segmenter: add process_id
This commit is contained in:
parent
5d0c067eb6
commit
ec43f11f98
|
@ -98,6 +98,7 @@ class SegmenterProcess(multiprocessing.Process):
|
||||||
# combination of self.__debug_objects_root and actual sample folder name
|
# combination of self.__debug_objects_root and actual sample folder name
|
||||||
self.__working_debug_path = ""
|
self.__working_debug_path = ""
|
||||||
self.__archive_fn = ""
|
self.__archive_fn = ""
|
||||||
|
self.__process_id = ""
|
||||||
self.__flat = None
|
self.__flat = None
|
||||||
self.__mask_array = None
|
self.__mask_array = None
|
||||||
self.__mask_to_remove = None
|
self.__mask_to_remove = None
|
||||||
|
@ -565,7 +566,13 @@ class SegmenterProcess(multiprocessing.Process):
|
||||||
|
|
||||||
logger.debug(f"Images found are {images_list}")
|
logger.debug(f"Images found are {images_list}")
|
||||||
images_count = len(images_list)
|
images_count = len(images_list)
|
||||||
logger.debug(f"We found {images_count} images, good luck!")
|
if images_count == 0:
|
||||||
|
logger.error(
|
||||||
|
"There is no image to run the segmentation on. Please check your selection."
|
||||||
|
)
|
||||||
|
raise FileNotFoundError
|
||||||
|
else:
|
||||||
|
logger.debug(f"We found {images_count} images, good luck!")
|
||||||
|
|
||||||
first_start = time.monotonic()
|
first_start = time.monotonic()
|
||||||
self.__mask_to_remove = None
|
self.__mask_to_remove = None
|
||||||
|
@ -665,7 +672,9 @@ class SegmenterProcess(multiprocessing.Process):
|
||||||
objects_count, _ = self._slice_image(img, name, mask, total_objects)
|
objects_count, _ = self._slice_image(img, name, mask, total_objects)
|
||||||
total_objects += objects_count
|
total_objects += objects_count
|
||||||
# Simple heuristic to detect a movement of the flow cell and a change in the resulting flat
|
# Simple heuristic to detect a movement of the flow cell and a change in the resulting flat
|
||||||
|
# TODO: this heuristic should be improved or removed if deemed unnecessary
|
||||||
if average_objects != 0 and objects_count > average_objects + 20:
|
if average_objects != 0 and objects_count > average_objects + 20:
|
||||||
|
# FIXME: this should force a new slice of the current image
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"We need to recalculate a flat since we have {objects_count} new objects instead of the average of {average_objects}"
|
f"We need to recalculate a flat since we have {objects_count} new objects instead of the average of {average_objects}"
|
||||||
)
|
)
|
||||||
|
@ -735,14 +744,29 @@ class SegmenterProcess(multiprocessing.Process):
|
||||||
"""
|
"""
|
||||||
logger.info(f"The pipeline will be run in {len(path_list)} directories")
|
logger.info(f"The pipeline will be run in {len(path_list)} directories")
|
||||||
logger.debug(f"Those are {path_list}")
|
logger.debug(f"Those are {path_list}")
|
||||||
|
|
||||||
|
self.__process_uuid = planktoscope.uuidName.uuidMachine(
|
||||||
|
machine=planktoscope.uuidName.getSerial()
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.__process_id == "":
|
||||||
|
self.__process_id = self.__process_uuid
|
||||||
|
|
||||||
|
logger.info(f"The process_uuid of this run is {self.__process_uuid}")
|
||||||
|
logger.info(f"The process_id of this run is {self.__process_id}")
|
||||||
|
exception = None
|
||||||
|
|
||||||
for path in path_list:
|
for path in path_list:
|
||||||
logger.debug(f"{path}: Checking for the presence of metadata.json")
|
logger.debug(f"{path}: Checking for the presence of metadata.json")
|
||||||
if os.path.exists(os.path.join(path, "metadata.json")):
|
if os.path.exists(os.path.join(path, "metadata.json")):
|
||||||
# The file exists, let's check if we force or not
|
# The file exists, let's check if we force or not
|
||||||
if force:
|
if force:
|
||||||
# forcing, let's gooooo
|
# forcing, let's gooooo
|
||||||
if not self.segment_path(path, ecotaxa_export):
|
try:
|
||||||
logger.error(f"There was en error while segmenting {path}")
|
self.segment_path(path, ecotaxa_export)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"There was an error while segmenting {path}")
|
||||||
|
exception = e
|
||||||
else:
|
else:
|
||||||
# we need to check for the presence of done.txt in each folder
|
# we need to check for the presence of done.txt in each folder
|
||||||
logger.debug(f"{path}: Checking for the presence of done.txt")
|
logger.debug(f"{path}: Checking for the presence of done.txt")
|
||||||
|
@ -751,12 +775,25 @@ class SegmenterProcess(multiprocessing.Process):
|
||||||
f"Moving to the next folder, {path} has already been segmented"
|
f"Moving to the next folder, {path} has already been segmented"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if not self.segment_path(path, ecotaxa_export):
|
try:
|
||||||
logger.error(f"There was en error while segmenting {path}")
|
self.segment_path(path, ecotaxa_export)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"There was an error while segmenting {path}")
|
||||||
|
exception = e
|
||||||
else:
|
else:
|
||||||
logger.debug(f"Moving to the next folder, {path} has no metadata.json")
|
logger.debug(f"Moving to the next folder, {path} has no metadata.json")
|
||||||
# Publish the status "Done" to via MQTT to Node-RED
|
if exception is None:
|
||||||
self.segmenter_client.client.publish("status/segmenter", '{"status":"Done"}')
|
# Publish the status "Done" to via MQTT to Node-RED
|
||||||
|
self.segmenter_client.client.publish(
|
||||||
|
"status/segmenter", '{"status":"Done"}'
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.segmenter_client.client.publish(
|
||||||
|
"status/segmenter",
|
||||||
|
f'{{"status":"An exception was raised during the segmentation: {e}."}}',
|
||||||
|
)
|
||||||
|
# Reset process_id
|
||||||
|
self.__process_id = ""
|
||||||
|
|
||||||
def segment_path(self, path, ecotaxa_export):
|
def segment_path(self, path, ecotaxa_export):
|
||||||
"""Starts the segmentation in the given path
|
"""Starts the segmentation in the given path
|
||||||
|
@ -778,8 +815,12 @@ class SegmenterProcess(multiprocessing.Process):
|
||||||
)
|
)
|
||||||
|
|
||||||
project = self.__global_metadata["sample_project"].replace(" ", "_")
|
project = self.__global_metadata["sample_project"].replace(" ", "_")
|
||||||
date = datetime.datetime.utcnow().isoformat()
|
|
||||||
sample = self.__global_metadata["sample_id"].replace(" ", "_")
|
sample = self.__global_metadata["sample_id"].replace(" ", "_")
|
||||||
|
date = datetime.datetime.utcnow().isoformat()
|
||||||
|
|
||||||
|
self.__global_metadata["process_datetime"] = date
|
||||||
|
self.__global_metadata["process_uuid"] = self.__process_uuid
|
||||||
|
self.__global_metadata["process_id"] = f"{project}_{sample}_{self.__process_id}"
|
||||||
|
|
||||||
# TODO Make this dynamic: if we change operations order and/or parameters, we need to make this evolve.
|
# TODO Make this dynamic: if we change operations order and/or parameters, we need to make this evolve.
|
||||||
self.__global_metadata["process_1st_operation"] = {
|
self.__global_metadata["process_1st_operation"] = {
|
||||||
|
@ -851,12 +892,13 @@ class SegmenterProcess(multiprocessing.Process):
|
||||||
self._pipe(ecotaxa_export)
|
self._pipe(ecotaxa_export)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(f"There was an error in the pipeline {e}")
|
logger.exception(f"There was an error in the pipeline {e}")
|
||||||
return False
|
raise e
|
||||||
|
|
||||||
# Add file 'done' to path to mark the folder as already segmented
|
# Add file 'done' to path to mark the folder as already segmented
|
||||||
with open(os.path.join(self.__working_path, "done.txt"), "w") as done_file:
|
with open(os.path.join(self.__working_path, "done.txt"), "w") as done_file:
|
||||||
done_file.writelines(datetime.datetime.utcnow().isoformat())
|
done_file.writelines(datetime.datetime.utcnow().isoformat())
|
||||||
logger.info(f"Pipeline has been run for {path}")
|
logger.info(f"Pipeline has been run for {path}")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@logger.catch
|
@logger.catch
|
||||||
|
@ -871,28 +913,39 @@ class SegmenterProcess(multiprocessing.Process):
|
||||||
if "action" in last_message:
|
if "action" in last_message:
|
||||||
# If the command is "segment"
|
# If the command is "segment"
|
||||||
if last_message["action"] == "segment":
|
if last_message["action"] == "segment":
|
||||||
path = None
|
|
||||||
recursive = True
|
|
||||||
force = False
|
|
||||||
ecotaxa_export = True
|
|
||||||
# {"action":"segment"}
|
# {"action":"segment"}
|
||||||
if "settings" in last_message:
|
if "settings" in last_message:
|
||||||
if "force" in last_message["settings"]:
|
# force rework of already done folder
|
||||||
# force rework of already done folder
|
force = (
|
||||||
force = last_message["settings"]["force"]
|
last_message["settings"]["force"]
|
||||||
if "recursive" in last_message["settings"]:
|
if "force" in last_message
|
||||||
# parse folders recursively starting from the given parameter
|
else False
|
||||||
recursive = last_message["settings"]["recursive"]
|
)
|
||||||
if "ecotaxa" in last_message["settings"]:
|
|
||||||
# generate ecotaxa output archive
|
# parse folders recursively starting from the given parameter
|
||||||
ecotaxa_export = last_message["settings"]["ecotaxa"]
|
recursive = (
|
||||||
|
last_message["settings"]["recursive"]
|
||||||
|
if "recursive" in last_message
|
||||||
|
else True
|
||||||
|
)
|
||||||
|
|
||||||
|
# generate ecotaxa output archive
|
||||||
|
ecotaxa_export = (
|
||||||
|
last_message["settings"]["ecotaxa"]
|
||||||
|
if "ecotaxa" in last_message
|
||||||
|
else True
|
||||||
|
)
|
||||||
|
|
||||||
if "keep" in last_message["settings"]:
|
if "keep" in last_message["settings"]:
|
||||||
# keep debug images
|
# keep debug images
|
||||||
self.__save_debug_img = last_message["settings"]["keep"]
|
self.__save_debug_img = last_message["settings"]["keep"]
|
||||||
|
|
||||||
|
if "process_id" in last_message["settings"]:
|
||||||
|
# keep debug images
|
||||||
|
self.__process_id = last_message["settings"]["process_id"]
|
||||||
# TODO eventually add customisation to segmenter parameters here
|
# TODO eventually add customisation to segmenter parameters here
|
||||||
|
|
||||||
if "path" in last_message:
|
path = last_message["path"] if "path" in last_message else None
|
||||||
path = last_message["path"]
|
|
||||||
|
|
||||||
# Publish the status "Started" to via MQTT to Node-RED
|
# Publish the status "Started" to via MQTT to Node-RED
|
||||||
self.segmenter_client.client.publish(
|
self.segmenter_client.client.publish(
|
||||||
|
|
Loading…
Reference in a new issue