Added 2 menu plugins that allow the user to interactively use lipase

The 2 available plugins are:
- Define Raw Images Root: this plugin allows the user to tell lipase where the raw images are stored
- Estimate White: this plugin allows the user to trigger the computation of a white image estimate for the given sequence and the given channel (the sequence id an the channel ids are currently hardcoded but it is of course planned to make it user selectable)

These changes involved quite a lot of work:
- added the support of a lipase user settings file to store user dependent things such as the location of the lipase raw images (to allow the user to use lipase plugins without having to specify the raw images locations again an again)
- investigations on how to make different lipase plugins use a common lipase library: the library is packagesd into a jar file placed in Fiji/jars/lib, while the plugins (menu items) are placed into Fiji/plugins directory
- investigations on fiji script parameters (for plugins input output)
This commit is contained in:
Guillaume Raffy 2019-09-26 10:25:02 +02:00
parent 228ae4ab54
commit e6217b38a3
12 changed files with 359 additions and 1 deletions

View File

@ -0,0 +1,226 @@
#!/bin/bash
FIJI_ROOT_PATH='/Applications/Fiji.app'
function ensure_maven_in_installed()
{
sudo port install maven32
sudo port select --set maven maven32
}
function accept_maven_scijava_org_certificate()
{
# fixes (using the nice description in https://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art032) the following error when executing "mvn -Dimagej.app.directory=/Applications/Fiji.app"
# [INFO] ------------------------------------------------------------------------
# [ERROR] Failed to execute goal on project example-script-collection: Could not resolve dependencies for project org.scijava:example-script-collection:jar:0.1.0-SNAPSHOT: Failed to collect dependencies at net.imagej:imagej:jar:2.0.0-rc-71: Failed to read artifact descriptor for net.imagej:imagej:jar:2.0.0-rc-71: Could not transfer artifact net.imagej:imagej:pom:2.0.0-rc-71 from/to scijava.public (https://maven.scijava.org/content/groups/public): sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target -> [Help 1]
# [ERROR]
# [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
local java_home=$(/usr/libexec/java_home)
#[1]graffy@pr079234:~/toto/example-script-collection[15:43:02]>/usr/libexec/java_home
#/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home
local jre_home="$java_home/jre"
keytool -list -keystore $jre_home/lib/security/cacerts
# just press enter on the password prompt
# [1]graffy@pr079234:~/toto/example-script-collection[15:44:43]>keytool -list -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/security/cacerts
# Enter keystore password:
# ***************** WARNING WARNING WARNING *****************
# * The integrity of the information stored in your keystore *
# * has NOT been verified! In order to verify its integrity, *
# * you must provide your keystore password. *
# ***************** WARNING WARNING WARNING *****************
# Keystore type: JKS
# Keystore provider: SUN
# Your keystore contains 93 entries
# digicertassuredidrootca, Apr 16, 2008, trustedCertEntry,
# Certificate fingerprint (SHA1): 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43
# ...
# godaddyrootg2ca, Jul 19, 2014, trustedCertEntry,
# Certificate fingerprint (SHA1): 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B
keytool -printcert -rfc -sslserver maven.scijava.org
# [1]graffy@pr079234:~/toto/example-script-collection[16:06:05]>keytool -printcert -rfc -sslserver maven.scijava.org
# -----BEGIN CERTIFICATE-----
# MIIFWDCCBECgAwIBAgISA7zwf4Rs4UhVp5fLyHh58bjtMA0GCSqGSIb3DQEBCwUAMEoxCzAJBgNV
# ...
# Ob5k02cDAcqlcJqIzqhxANh7UDoLw7h36hBnyIHDMbMMkfrtgMv5WSa0DZ2mZf63P6iYGUmr5dtz
# ciAu0w==
# -----END CERTIFICATE-----
# -----BEGIN CERTIFICATE-----
# MIIFWDCCBECgAwIBAgISA7zwf4Rs4UhVp5fLyHh58bjtMA0GCSqGSIb3DQEBCwUAMEoxCzAJBgNV
# ...
# Ob5k02cDAcqlcJqIzqhxANh7UDoLw7h36hBnyIHDMbMMkfrtgMv5WSa0DZ2mZf63P6iYGUmr5dtz
# ciAu0w==
# -----END CERTIFICATE-----
# -----BEGIN CERTIFICATE-----
# MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/MSQwIgYDVQQK
# ...
# TZ+sOPAveyxindmjkW8lGy+QsRlGPfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M
# +X+Q7UNKEkROb3N6KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
# -----END CERTIFICATE-----
# split output into:
# - /tmp/cert1.pem
# - /tmp/cert2.pem
# - /tmp/cert3.pem
keytool -importcert -file /tmp/cert1.pem -keystore $jre_home/lib/security/cacerts
# password : changeit
# [1]graffy@pr079234:~/toto/example-script-collection[17:12:30]>sudo keytool -importcert -file /tmp/cert1.pem -keystore $jre_home/lib/security/cacerts
# Password:
# Sorry, try again.
# Password:
# Enter keystore password:
# Owner: CN=maven.imagej.net
# Issuer: CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
# Serial number: 3bcf07f846ce14855a797cbc87879f1b8ed
# Valid from: Sat Aug 17 07:39:53 CEST 2019 until: Fri Nov 15 06:39:53 CET 2019
# Certificate fingerprints:
# MD5: 05:B4:5A:31:AE:1F:36:71:0E:24:FB:0F:72:AE:BD:BD
# SHA1: E5:3E:B0:CC:8E:D0:C6:A3:EF:2F:42:93:45:60:82:C2:1B:A3:BD:F3
# SHA256: 74:3C:C7:2C:E6:C5:FE:9F:79:F5:F7:9D:7E:2A:4F:C9:BA:51:A0:88:95:1C:FC:15:8D:DC:EC:B0:99:BD:0E:61
# Signature algorithm name: SHA256withRSA
# Version: 3
# Extensions:
# #1: ObjectId: 1.3.6.1.4.1.11129.2.4.2 Criticality=false
# 0000: 04 81 F2 00 F0 00 76 00 74 7E DA 83 31 AD 33 10 ......v.t...1.3.
# 0010: 91 21 9C CE 25 4F 42 70 C2 BF FD 5E 42 20 08 C6 .!..%OBp...^B ..
# 0020: 37 35 79 E6 10 7B CC 56 00 00 01 6C 9E 4D C8 C6 75y....V...l.M..
# 0030: 00 00 04 03 00 47 30 45 02 20 1C DB D8 F3 9D 77 .....G0E. .....w
# 0040: 48 BB B3 D7 0E 50 C4 0F C0 DF 65 94 A7 C4 23 E2 H....P....e...#.
# 0050: 19 C3 88 4D 8D 6D D9 82 D3 BA 02 21 00 AC CC 93 ...M.m.....!....
# 0060: BE 28 59 5C 2E BC A0 8E 36 4D 23 FB 1D 4B 0F FE .(Y\....6M#..K..
# 0070: F4 38 9F C6 D1 13 53 91 62 25 0F C9 71 00 76 00 .8....S.b%..q.v.
# 0080: 29 3C 51 96 54 C8 39 65 BA AA 50 FC 58 07 D4 B7 )<Q.T.9e..P.X...
# 0090: 6F BF 58 7A 29 72 DC A4 C3 0C F4 E5 45 47 F4 78 o.Xz)r......EG.x
# 00A0: 00 00 01 6C 9E 4D CA AD 00 00 04 03 00 47 30 45 ...l.M.......G0E
# 00B0: 02 20 5B D4 50 BC 32 89 32 C4 33 EB 5B 30 3F 25 . [.P.2.2.3.[0?%
# 00C0: F0 7C A6 D4 8A F7 8B AB 55 3A 54 6D F9 2E C9 DE ........U:Tm....
# 00D0: D3 4B 02 21 00 8C A8 8B D3 38 20 38 A1 BB 37 B3 .K.!.....8 8..7.
# 00E0: EE 3A 38 17 82 16 D3 1C E0 30 95 C4 E7 F7 8A 26 .:8......0.....&
# 00F0: 62 B7 BC AF DF b....
# #2: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
# AuthorityInfoAccess [
# [
# accessMethod: ocsp
# accessLocation: URIName: http://ocsp.int-x3.letsencrypt.org
# ,
# accessMethod: caIssuers
# accessLocation: URIName: http://cert.int-x3.letsencrypt.org/
# ]
# ]
# #3: ObjectId: 2.5.29.35 Criticality=false
# AuthorityKeyIdentifier [
# KeyIdentifier [
# 0000: A8 4A 6A 63 04 7D DD BA E6 D1 39 B7 A6 45 65 EF .Jjc......9..Ee.
# 0010: F3 A8 EC A1 ....
# ]
# ]
# #4: ObjectId: 2.5.29.19 Criticality=true
# BasicConstraints:[
# CA:false
# PathLen: undefined
# ]
# #5: ObjectId: 2.5.29.32 Criticality=false
# CertificatePolicies [
# [CertificatePolicyId: [2.23.140.1.2.1]
# [] ]
# [CertificatePolicyId: [1.3.6.1.4.1.44947.1.1.1]
# [PolicyQualifierInfo: [
# qualifierID: 1.3.6.1.5.5.7.2.1
# qualifier: 0000: 16 1A 68 74 74 70 3A 2F 2F 63 70 73 2E 6C 65 74 ..http://cps.let
# 0010: 73 65 6E 63 72 79 70 74 2E 6F 72 67 sencrypt.org
# ]] ]
# ]
# #6: ObjectId: 2.5.29.37 Criticality=false
# ExtendedKeyUsages [
# serverAuth
# clientAuth
# ]
# #7: ObjectId: 2.5.29.15 Criticality=true
# KeyUsage [
# DigitalSignature
# Key_Encipherment
# ]
# #8: ObjectId: 2.5.29.17 Criticality=false
# SubjectAlternativeName [
# DNSName: maven.imagej.net
# ]
# #9: ObjectId: 2.5.29.14 Criticality=false
# SubjectKeyIdentifier [
# KeyIdentifier [
# 0000: 63 09 5F EA C5 C8 7D 24 DD 2B 11 71 BB FB F6 F9 c._....$.+.q....
# 0010: 6F 7C BD 0A o...
# ]
# ]
# Trust this certificate? [no]: yes
# Certificate was added to keystore
#> mykey, Sep 20, 2019, trustedCertEntry,
#> Certificate fingerprint (SHA1): E5:3E:B0:CC:8E:D0:C6:A3:EF:2F:42:93:45:60:82:C2:1B:A3:BD:F3
#export MAVEN_OPTS="-Xmx512m -Djavax.net.ssl.trustStore=trust.jks \
# -Djavax.net.ssl.trustStorePassword= \
# -Djavax.net.ssl.keyStore=/tmp/cert1.pem \
# -Djavax.net.ssl.keyStoreType=pem
}
function create_test_jar()
{
git clone https://github.com/imagej/example-script-collection.git
pushd example-script-collection
rm -R src/test/java
ensure_maven_in_installed
accept_maven_scijava_org_certificate
mvn -Dimagej.app.directory=/Applications/Fiji.app
popd
}
function install_lipase_libs_in_fiji()
{
# https://imagej.net/Jython_Scripting
mkdir -p "$FIJI_ROOT_PATH/jars/Lib"
# cp -R ./src/* "$FIJI_ROOT_PATH/jars/Lib"
pushd src
find ./lipase -name "*.py" > /tmp/files.txt
jar cvf $FIJI_ROOT_PATH/jars/Lib/fr.univ-rennes1.ip.lipase.lib.jar @/tmp/files.txt
popd
}
function install_lipase_in_fiji()
{
install_lipase_libs_in_fiji
mkdir -p $FIJI_ROOT_PATH/plugins/Ipr
rsync -a ./src/ij-plugins/Ipr/ $FIJI_ROOT_PATH/plugins/Ipr/
}
install_lipase_in_fiji

View File

@ -0,0 +1,27 @@
#@ File (label="Select the root directory of root images", style="directory") RAW_IMAGES_ROOT_PATH
# https://imagej.net/Script_Parameters
# @ output String INFO
# @File(label = "Image File", persist=True) FILENAME
"""This script is supposed to be launched from fiji's jython interpreter
"""
# # note: fiji's jython doesn't support encoding keyword
# https://imagej.net/Scripting_Headless
from lipase.settings import UserSettings
# print("RAW_IMAGES_ROOT_PATH=%s", RAW_IMAGES_ROOT_PATH)
# it is necassary to add lipase's root path to the path if run from fiji as script otherwise jython fails to find lipase's modules such as catalog
# sys.path.append(lipase_src_root_path) # pylint: disable=undefined-variable
def run_script():
settings = UserSettings()
settings.raw_images_root_path = str(RAW_IMAGES_ROOT_PATH)
settings.save()
# global INFO
# INFO = "the root directory containing raw images (%s) has been stored in your settings file %s" % (str(RAW_IMAGES_ROOT_PATH), settings.get_settings_file_path())
# note : when launched from fiji, __name__ doesn't have the value "__main__", as when launched from python
run_script()

View File

@ -0,0 +1,43 @@
#@output ImagePlus WHITE_ESTIMATE
"""This script is supposed to be launched from fiji's jython interpreter
"""
#from ij import IJ # pylint: disable=import-error
#WHITE_ESTIMATE = IJ.openImage('/Users/graffy/ownCloud/ipr/lipase/lipase.git/white_estimate.tiff')
# # note: fiji's jython doesn't support encoding keyword
# https://imagej.net/Scripting_Headless
# String lipase_src_root_path
# String(label="Please enter your name",description="Name field") name
# OUTPUT String greeting
import sys
print('python version %s' % sys.version) # prints python version
from lipase.settings import UserSettings
# it is necassary to add lipase's root path to the path if run from fiji as script otherwise jython fails to find lipase's modules such as catalog
# sys.path.append(lipase_src_root_path) # pylint: disable=undefined-variable
# from lipase import Lipase, ImageLogger
from lipase.preprocessing import test_preprocessing # noqa: E402 pylint: disable=import-error,wrong-import-position
from lipase.imageengine import IImageEngine
from lipase.imagej.ijimageengine import IJImageEngine
from lipase.preprocessing import WhiteEstimator
from lipase.catalog import ImageCatalog
def run_script():
user_settings = UserSettings()
IImageEngine.set_instance(IJImageEngine())
catalog = ImageCatalog(user_settings.raw_images_root_path)
sequence = catalog.sequences['res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos2']
white_estimator = WhiteEstimator(open_size=75, close_size=75, average_size=75)
white_estimate = white_estimator.estimate_white([sequence], ['DM300_327-353_fluo'])
print(type(white_estimate))
global WHITE_ESTIMATE
WHITE_ESTIMATE = white_estimate.ij_image
# note : when launched from fiji, __name__ doesn't have the value "__main__", as when launched from python
run_script()

View File

View File

@ -15,7 +15,6 @@ from catalog import Sequence, ImageCatalog
import preprocessing
# greeting = "Hello, " + name + "!"
# image prefix :
# AF
# blé : coupes de blé
@ -42,6 +41,8 @@ import preprocessing
# - cond[5678] : condition non réalistes
class IImageProcessingDebugger(object):
def __init__(self):

61
src/lipase/settings.py Normal file
View File

@ -0,0 +1,61 @@
"""Lipase user settings."""
import json
from os.path import expanduser
class UserSettings(object):
"""User settings."""
attributes = {'raw_images_root_path': {'type': str}}
def __init__(self):
"""constructor."""
self.settings = {} # json dictionary
self.raw_images_root_path = 'bla'
try:
with open(self.get_settings_file_path(), 'r') as json_file:
self.settings = json.load(json_file)
except IOError as error:
print('Failed to read %s : %s' % (self.get_settings_file_path(), error))
def __getattr__(self, attr):
"""Override __getattr__ to check the validity of settings attributes names."""
print('getting %s' % (attr,))
if attr == 'settings':
return self.__dict__['settings']
else:
assert attr in UserSettings.attributes
return self.settings[attr]
def __setattr__(self, attr, value):
"""Override __setattr__ to check the validity of settings attributes names."""
print('setting %s to %s' % (attr, value))
if attr == 'settings':
self.__dict__['settings'] = value
else:
assert attr in UserSettings.attributes
assert type(value) == UserSettings.attributes[attr]['type'], "invalid type for attribute %s : %s instead of %s" % (attr, str(type(value)), str(UserSettings.attributes[attr]['type']))
self.settings[attr] = value
def get_settings_file_path(self):
"""Return the location of lipase user settings file."""
home = expanduser("~")
return '%s/.fr.univ-rennes1.ipr.lipase.json' % home
def save(self):
"""Save user settings."""
with open(self.get_settings_file_path(), 'w') as json_file:
json.dump(self.settings, json_file)
def test():
"""Unit test."""
settings = UserSettings()
print(settings.raw_images_root_path)
settings.raw_images_root_path = '/Users/graffy/ownCloud/ipr/lipase/raw-images'
# settings.toto = 'hello'
settings.save()
if __name__ == '__main__':
test()