epicure.appose_epyseg
1import appose 2import numpy as np 3import logging 4from importlib import resources 5import platform 6 7def share_as_ndarray(img: np.ndarray) -> appose.NDArray: 8 """Copies a NumPy array into a same-sized newly allocated block of shared memory.""" 9 shared = appose.NDArray(str(img.dtype), img.shape) 10 shared.ndarray()[:] = img 11 return shared 12 13def go_epyseg( image, parameters, progress_bar=None, logger=None ): 14 """ Install env with napari_epyseg if necessary with appose and run epyseg on the image """ 15 _logger = logger or logging.getLogger(__name__) 16 try: 17 pixi_file = resources.files("epicure.resources").joinpath("pixi.toml") 18 _logger.info("Build/Load napari_epyseg environement") 19 env = appose.pixi( pixi_file ).log_debug() 20 env = env.subscribe_output( lambda line: print("OUT:", line, end="") ) 21 env = env.subscribe_error( lambda line: print("DBG:", line, end="") ) 22 ## get cuda installation if Linux or Windows (tensorflow with cuda) 23 is_gpu_platform = platform.system() in ("Linux", "Windows") 24 env_name = "cuda" if is_gpu_platform else "default" 25 env = env.environment(env_name).build() 26 _logger.info(f"Environment built at: {env.base()}") 27 _logger.info( "Initiate environment to run epyseg" ) 28 python = env.python().init("import numpy as np; import napari_epyseg; from napari_epyseg.call_epyseg import run_epyseg") 29 30 epyseg_script = ''' 31### Script to run epyseg in another python environement, created with appose and launched as a task 32data = image.ndarray() 33#task.update(f'Start segmentation with epyseg') 34import logging 35class ApposeLogHandler(logging.Handler): 36 def emit(self, record): 37 msg = self.format(record) 38 task.update(message=msg) 39 40def setup_logger( name="epyseg_worker" ): 41 logger = logging.getLogger(name) 42 handler = ApposeLogHandler() 43 formatter = logging.Formatter('[Napari-epyseg] - %(message)s') 44 handler.setFormatter( formatter ) 45 logger.addHandler(handler) 46 logger.setLevel( extras["logger_level"] ) 47 return logger 48 49logger = setup_logger() 50segres = run_epyseg( data, parameters, progress_bar=extras["progress_bar"], logger=logger ) 51if segres is not None: 52 ## Write the results on the shared memory object 53 image.ndarray()[:] = segres 54logger.info( "Segmentation finished" ) 55''' 56 def log_listener(event): 57 """ Transfer appose task message to the main logger """ 58 if event.message: 59 _logger.info(f"[task] {event.message}") 60 61 try: 62 with share_as_ndarray(image) as shared_image: 63 task = python.task(epyseg_script) 64 task.listen( log_listener ) 65 task.inputs["image"] = shared_image 66 task.inputs["parameters"] = parameters 67 ## other convenient tools to print msg, show progress.. 68 task.inputs["extras"] = { "logger_name":_logger.name, "logger_level":_logger.level, "progress_bar": progress_bar } 69 _logger.info( "Start segmentation in appose service task.." ) 70 task.wait_for() 71 result = shared_image.ndarray() 72 return result 73 except Exception as e: 74 raise RuntimeError("Running epyseg in separated environement failed") from e 75 finally: 76 python.close() 77 except Exception as e: 78 raise RuntimeError("Epyseg in separated environement failed") from e
def
go_epyseg(image, parameters, progress_bar=None, logger=None):
14def go_epyseg( image, parameters, progress_bar=None, logger=None ): 15 """ Install env with napari_epyseg if necessary with appose and run epyseg on the image """ 16 _logger = logger or logging.getLogger(__name__) 17 try: 18 pixi_file = resources.files("epicure.resources").joinpath("pixi.toml") 19 _logger.info("Build/Load napari_epyseg environement") 20 env = appose.pixi( pixi_file ).log_debug() 21 env = env.subscribe_output( lambda line: print("OUT:", line, end="") ) 22 env = env.subscribe_error( lambda line: print("DBG:", line, end="") ) 23 ## get cuda installation if Linux or Windows (tensorflow with cuda) 24 is_gpu_platform = platform.system() in ("Linux", "Windows") 25 env_name = "cuda" if is_gpu_platform else "default" 26 env = env.environment(env_name).build() 27 _logger.info(f"Environment built at: {env.base()}") 28 _logger.info( "Initiate environment to run epyseg" ) 29 python = env.python().init("import numpy as np; import napari_epyseg; from napari_epyseg.call_epyseg import run_epyseg") 30 31 epyseg_script = ''' 32### Script to run epyseg in another python environement, created with appose and launched as a task 33data = image.ndarray() 34#task.update(f'Start segmentation with epyseg') 35import logging 36class ApposeLogHandler(logging.Handler): 37 def emit(self, record): 38 msg = self.format(record) 39 task.update(message=msg) 40 41def setup_logger( name="epyseg_worker" ): 42 logger = logging.getLogger(name) 43 handler = ApposeLogHandler() 44 formatter = logging.Formatter('[Napari-epyseg] - %(message)s') 45 handler.setFormatter( formatter ) 46 logger.addHandler(handler) 47 logger.setLevel( extras["logger_level"] ) 48 return logger 49 50logger = setup_logger() 51segres = run_epyseg( data, parameters, progress_bar=extras["progress_bar"], logger=logger ) 52if segres is not None: 53 ## Write the results on the shared memory object 54 image.ndarray()[:] = segres 55logger.info( "Segmentation finished" ) 56''' 57 def log_listener(event): 58 """ Transfer appose task message to the main logger """ 59 if event.message: 60 _logger.info(f"[task] {event.message}") 61 62 try: 63 with share_as_ndarray(image) as shared_image: 64 task = python.task(epyseg_script) 65 task.listen( log_listener ) 66 task.inputs["image"] = shared_image 67 task.inputs["parameters"] = parameters 68 ## other convenient tools to print msg, show progress.. 69 task.inputs["extras"] = { "logger_name":_logger.name, "logger_level":_logger.level, "progress_bar": progress_bar } 70 _logger.info( "Start segmentation in appose service task.." ) 71 task.wait_for() 72 result = shared_image.ndarray() 73 return result 74 except Exception as e: 75 raise RuntimeError("Running epyseg in separated environement failed") from e 76 finally: 77 python.close() 78 except Exception as e: 79 raise RuntimeError("Epyseg in separated environement failed") from e
Install env with napari_epyseg if necessary with appose and run epyseg on the image