lipase/tests/test0001.py

142 lines
7.6 KiB
Python

"""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
#@ String raw_images_root_path
#@ String tests_output_data_path
import unittest # unittest2 doesn't exist in fiji
import sys
from lipase.imageengine import IImageEngine, PixelType, Aabb, NullDebugger, FileBasedDebugger
from lipase.imagej.ijimageengine import IJImageEngine, IJImage
from lipase.telemos import WhiteEstimator, correct_non_uniform_lighting
from lipase.maxima_finder import MaximaFinder
from lipase.template_matcher import TemplateMatcher
from lipase.traps_detector import TrapsDetector
from lipase.catalog import ImageCatalog, Sequence
from lipase.lipase import Lipase, ImageLogger
from lipase.lipase import GlobulesAreaEstimator, EmptyFrameBackgroundEstimator
from lipase.circsymdetector import CircularSymmetryDetector
from lipase.imagej.hdf5serializer import save_hdf5_file
class TestLipase(unittest.TestCase):
RAW_IMAGES_ROOT_PATH = raw_images_root_path # eg '/Users/graffy/ownCloud/ipr/lipase/raw-images' pylint: disable=undefined-variable
TESTS_OUTPUT_DATA_PATH = tests_output_data_path # eg '/tmp/lipase/tests-output-data' pylint: disable=undefined-variable
# we need to know if the test succeeded or not https://stackoverflow.com/questions/4414234/getting-pythons-unittest-results-in-a-teardown-method
# CURRENT_RESULT = None # holds last result object passed to run method
def setUp(self):
print("initializing TestLipase instance")
IImageEngine.set_instance(IJImageEngine(debugger=FileBasedDebugger('%s/debug-images' % self.TESTS_OUTPUT_DATA_PATH)))
self.catalog = ImageCatalog(self.RAW_IMAGES_ROOT_PATH)
def tearDown(self):
print("uninitializing TestLipase instance")
self.catalog = None
def test_estimate_white(self):
sequence = self.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'])
# find_white_reference_image(white_estimate, sequence.get_white())
print(white_estimate)
IImageEngine.get_instance().debugger.on_image(white_estimate, 'white_estimate')
# assert False, "hellooooo"
print('end of test_estimate_white')
def test_uniform_lighting_correction(self):
non_uniform_sequence = self.catalog.sequences['res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos0']
uniform_sequence = correct_non_uniform_lighting(non_uniform_sequence, 'DM300_nofilter_vis', white_estimator=WhiteEstimator(open_size=75, close_size=75, average_size=75)) # pylint: disable=unused-variable
def test_template_matcher(self):
sequence = self.catalog.sequences['res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos0']
stack = sequence.as_hyperstack(['DM300_nofilter_vis'], selected_frames=[0])
first_image = stack.get_image(frame_index=0)
x_min = 423
x_max = 553
y_min = 419
y_max = 533
template_trap_aabb = Aabb(x_min, y_min, x_max, y_max)
template_trap_image = first_image.get_subimage(template_trap_aabb)
for image in [first_image, template_trap_image]:
print(image.get_pixel_type(), image.get_width(), image.get_height())
# the typical value of peaks is -2.e10 and the value between peaks is below -8.0e10
threshold = -3.0e10
tolerance = 1.0e10
maxima_finder = MaximaFinder(threshold, tolerance)
template_matcher = TemplateMatcher(maxima_finder)
matches = template_matcher.match_template(first_image, template_trap_image)
num_traps = len(matches)
print("number of traps found : %d" % num_traps)
num_expected_traps = 13 # 13 traps are completely visible in the first image
self.assertAlmostEqual(len(matches), num_expected_traps, delta=1.0)
def test_traps_detector(self):
# the typical value of peaks is -500 and the value between peaks is below -2500
threshold = -1500.0
tolerance = 1500
maxima_finder = MaximaFinder(threshold, tolerance)
template_matcher = TemplateMatcher(maxima_finder)
traps_detector = TrapsDetector(template_matcher)
sequence = self.catalog.sequences['res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos0']
x_min = 423
x_max = 553
y_min = 419
y_max = 533
trap_aabb = Aabb(x_min, y_min, x_max, y_max)
traps_mask = traps_detector.compute_traps_mask(sequence, 'DM300_nofilter_vis', trap_aabb)
measured_mean_value = traps_mask.get_mean_value()
expected_traps_coverage = 0.07909
traps_pixel_value = 255.0
expected_mean_value = expected_traps_coverage * traps_pixel_value
print("expected_mean_value: %f" % expected_mean_value)
print("measured_mean_value: %f" % measured_mean_value)
self.assertAlmostEqual(measured_mean_value, expected_mean_value, delta=0.01)
def test_visible_traps_sequence_processing(self):
traps_sequence = self.catalog.sequences['res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos0']
visible_traps_sequence = traps_sequence.as_hyperstack(['DM300_nofilter_vis'])
background_estimator = EmptyFrameBackgroundEstimator(empty_frame_index=39)
processor = GlobulesAreaEstimator(background_estimator=background_estimator, particle_threshold=2000.0)
results = processor.detect_particles(visible_traps_sequence)
save_hdf5_file('%s/results.h5' % self.TESTS_OUTPUT_DATA_PATH, results)
# results file could be checked with "h5dump --xml ./lipase.git/results.h5"
first_frame_measured_ratio = results['globules_area_ratio'][(0,)]
first_frame_expected_ratio = 0.008
self.assertAlmostEqual(first_frame_measured_ratio, first_frame_expected_ratio, delta=0.01)
def test_circle_detector(self):
traps_sequence = self.catalog.sequences['res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos0']
visible_traps_sequence = traps_sequence.as_hyperstack(['DM300_nofilter_vis'])
src_image = visible_traps_sequence.get_image(frame_index=0)
# ie = IImageEngine.get_instance()
detector = CircularSymmetryDetector(max_radius=32.0, num_angular_sectors=4, num_radial_sectors=8)
radial_profiles, angular_variance_avg_image = detector.compute_radial_profiles(src_image) # pylint: disable=unused-variable
# def test_lipase_process(self):
# lipase = Lipase(self.catalog, debugger=NullDebugger())
def run_script():
# unittest.main() # this would result in : ImportError: No module named __main__
# solution from : https://discourse.mcneel.com/t/using-unittest-in-rhino-python-not-possible/15364
suite = unittest.TestLoader().loadTestsFromTestCase(TestLipase)
stream = sys.stdout # by default it's sys.stderr, which doesn't appear in imagej's output
test_result = unittest.TextTestRunner(stream=stream, verbosity=2).run(suite)
print('test_result : %s' % test_result)
# store summary of the result in a file so that the caller of imagej can detect that this python script failed (imagej seems to always return error code 0, regardless the error returned by the python script it executes : even sys.exit(1) doesn't change this)
with open('/tmp/test_result.txt', 'w') as f:
f.write('%d' % {True: 0, False: 1}[test_result.wasSuccessful()])
print('end of run_script')
# note : when launched from fiji, __name__ doesn't have the value "__main__", as when launched from python
run_script()