@@ -486,169 +486,121 @@ def get_stage_coords(source, filenames):
486486 source : str
487487 Path to the images.
488488 filenames : list of str
489- List of images filenames.
489+ List of image filenames.
490490
491491 Returns
492492 -------
493- dict
494-
495- {
496- dimensions : int, # number of dimensions (2D or 3D)
497- stage_coordinates_x : list, # absolute stage x-coordinated
498- stage_coordinates_y : list, # absolute stage y-coordinated
499- stage_coordinates_z : list, # absolute stage z-coordinated
500- relative_coordinates_x : list, # relative stage x-coordinates in px
501- relative_coordinates_y : list, # relative stage y-coordinates in px
502- relative_coordinates_z : list, # relative stage z-coordinates in px
503- image_calibration : list, # x,y,z image calibration in unit/px
504- calibration_unit : str, # image calibration unit
505- image_dimensions_czt : list, # number of images in dimensions c,z,t
506- series_names : list of str, # names of all series in the files
507- max_size : list of int, # max size (x/y/z) across all files
508- }
493+ StageMetadata
494+ An object containing extracted stage metadata.
509495 """
510-
511- # open an array to store the abosolute stage coordinates from metadata
496+ # Initialize lists to store stage coordinates and series names
512497 stage_coordinates_x = []
513498 stage_coordinates_y = []
514499 stage_coordinates_z = []
515500 series_names = []
516501
502+ # Intiialize default values
503+ dimensions = 2
504+ image_calibration = []
505+ calibration_unit = "unknown"
506+ image_dimensions_czt = []
507+ max_size = []
508+
509+ # Initialize max_size variables to track the maximums
510+ max_phys_size_x = 0.0
511+ max_phys_size_y = 0.0
512+ max_phys_size_z = 0.0
513+
517514 for counter , image in enumerate (filenames ):
518- # parse metadata
519515 reader = ImageReader ()
520516 reader .setFlattenedResolutions (False )
521- omeMeta = MetadataTools .createOMEXMLMetadata ()
522- reader .setMetadataStore (omeMeta )
517+ ome_meta = MetadataTools .createOMEXMLMetadata ()
518+ reader .setMetadataStore (ome_meta )
523519 reader .setId (source + str (image ))
524520 series_count = reader .getSeriesCount ()
525521
526- # get hyperstack dimensions from the first image
522+ # Process only the first image to get values not dependent on series
527523 if counter == 0 :
528524 frame_size_x = reader .getSizeX ()
529525 frame_size_y = reader .getSizeY ()
530526 frame_size_z = reader .getSizeZ ()
531527 frame_size_c = reader .getSizeC ()
532528 frame_size_t = reader .getSizeT ()
533529
534- # note the dimensions
535- if frame_size_z == 1 :
536- dimensions = 2
537- if frame_size_z > 1 :
538- dimensions = 3
539-
540- # get the physical calibration for the first image series
541- physSizeX = omeMeta .getPixelsPhysicalSizeX (0 )
542- physSizeY = omeMeta .getPixelsPhysicalSizeY (0 )
543- physSizeZ = omeMeta .getPixelsPhysicalSizeZ (0 )
544-
545- # workaround to get the z-interval if physSizeZ.value() returns None.
546- z_interval = 1
547- if physSizeZ is not None :
548- z_interval = physSizeZ .value ()
549-
550- if frame_size_z > 1 and physSizeZ is None :
551- log .debug ("no z calibration found, trying to recover" )
552- first_plane = omeMeta .getPlanePositionZ (0 , 0 )
553- next_plane_imagenumber = frame_size_c + frame_size_t - 1
554- second_plane = omeMeta .getPlanePositionZ (0 , next_plane_imagenumber )
555- z_interval = abs (abs (first_plane .value ()) - abs (second_plane .value ()))
556- log .debug ("z-interval seems to be: " + str (z_interval ))
557-
558- # create an image calibration
559- image_calibration = [
560- physSizeX .value (),
561- physSizeY .value (),
562- z_interval ,
563- ]
564- calibration_unit = physSizeX .unit ().getSymbol ()
565- image_dimensions_czt = [
566- frame_size_c ,
567- frame_size_z ,
568- frame_size_t ,
569- ]
530+ dimensions = 2 if frame_size_z == 1 else 3
531+
532+ # Retrieve physical size coordinates safely
533+ phys_size_x = getattr (ome_meta .getPixelsPhysicalSizeX (0 ), "value" , lambda : 1.0 )()
534+ phys_size_y = getattr (ome_meta .getPixelsPhysicalSizeY (0 ), "value" , lambda : 1.0 )()
535+ phys_size_z = getattr (ome_meta .getPixelsPhysicalSizeZ (0 ), "value" , lambda : None )()
536+
537+ z_interval = phys_size_z if phys_size_z is not None else 1.0
538+
539+ # Handle missing Z calibration
540+ if phys_size_z is None and frame_size_z > 1 :
541+ first_plane = getattr (ome_meta .getPlanePositionZ (0 , 0 ), "value" , lambda : 0 )()
542+ next_plane_index = frame_size_c + frame_size_t - 1
543+ second_plane = getattr (ome_meta .getPlanePositionZ (0 , next_plane_index ), "value" , lambda : 0 )()
544+ z_interval = abs (first_plane - second_plane )
545+
546+ image_calibration = [phys_size_x , phys_size_y , z_interval ]
547+ calibration_unit = (
548+ getattr (ome_meta .getPixelsPhysicalSizeX (0 ).unit (), "getSymbol" , lambda : "unknown" )()
549+ if phys_size_x
550+ else "unknown"
551+ )
552+ image_dimensions_czt = [frame_size_c , frame_size_z , frame_size_t ]
570553
571554 reader .close ()
572555
573556 for series in range (series_count ):
574- if omeMeta .getImageName (series ) == "macro image" :
557+ if ome_meta .getImageName (series ) == "macro image" :
575558 continue
576559
577560 if series_count > 1 and not str (image ).endswith (".vsi" ):
578- series_names .append (omeMeta .getImageName (series ))
561+ series_names .append (ome_meta .getImageName (series ))
579562 else :
580563 series_names .append (str (image ))
581- # get the plane position in calibrated units
582- current_position_x = omeMeta .getPlanePositionX (series , 0 )
583- current_position_y = omeMeta .getPlanePositionY (series , 0 )
584- current_position_z = omeMeta .getPlanePositionZ (series , 0 )
585-
586- physSizeX_max = (
587- physSizeX .value ()
588- if physSizeX .value () >= omeMeta .getPixelsPhysicalSizeX (series ).value ()
589- else omeMeta .getPixelsPhysicalSizeX (series ).value ()
590- )
591- physSizeY_max = (
592- physSizeY .value ()
593- if physSizeY .value () >= omeMeta .getPixelsPhysicalSizeY (series ).value ()
594- else omeMeta .getPixelsPhysicalSizeY (series ).value ()
595- )
596- if omeMeta .getPixelsPhysicalSizeZ (series ):
597- physSizeZ_max = (
598- physSizeZ .value ()
599- if physSizeZ .value ()
600- >= omeMeta .getPixelsPhysicalSizeZ (series ).value ()
601- else omeMeta .getPixelsPhysicalSizeZ (series ).value ()
602- )
603-
604- else :
605- physSizeZ_max = 1.0
606564
607- # get the absolute stage positions and store them
608- pos_x = current_position_x .value ()
609- pos_y = current_position_y .value ()
610-
611- if current_position_z is None :
612- log .debug ("the z-position is missing in the ome-xml metadata." )
613- pos_z = 1.0
614- else :
615- pos_z = current_position_z .value ()
616-
617- stage_coordinates_x .append (pos_x )
618- stage_coordinates_y .append (pos_y )
619- stage_coordinates_z .append (pos_z )
620-
621- max_size = [physSizeX_max , physSizeY_max , physSizeZ_max ]
622-
623- # calculate the store the relative stage movements in px (for the grid/collection stitcher)
624- relative_coordinates_x_px = []
625- relative_coordinates_y_px = []
626- relative_coordinates_z_px = []
627-
628- for i in range (len (stage_coordinates_x )):
629- rel_pos_x = (
630- stage_coordinates_x [i ] - stage_coordinates_x [0 ]
631- ) / physSizeX .value ()
632- rel_pos_y = (
633- stage_coordinates_y [i ] - stage_coordinates_y [0 ]
634- ) / physSizeY .value ()
635- rel_pos_z = (stage_coordinates_z [i ] - stage_coordinates_z [0 ]) / z_interval
636-
637- relative_coordinates_x_px .append (rel_pos_x )
638- relative_coordinates_y_px .append (rel_pos_y )
639- relative_coordinates_z_px .append (rel_pos_z )
640-
641- return {
642- "dimensions" : dimensions ,
643- "stage_coordinates_x" : stage_coordinates_x ,
644- "stage_coordinates_y" : stage_coordinates_y ,
645- "stage_coordinates_z" : stage_coordinates_z ,
646- "relative_coordinates_x" : relative_coordinates_x_px ,
647- "relative_coordinates_y" : relative_coordinates_y_px ,
648- "relative_coordinates_z" : relative_coordinates_z_px ,
649- "image_calibration" : image_calibration ,
650- "calibration_unit" : calibration_unit ,
651- "image_dimensions_czt" : image_dimensions_czt ,
652- "series_names" : series_names ,
653- "max_size" : max_size ,
654- }
565+ current_position_x = getattr (ome_meta .getPlanePositionX (series , 0 ), "value" , lambda : 0 )()
566+ current_position_y = getattr (ome_meta .getPlanePositionY (series , 0 ), "value" , lambda : 0 )()
567+ current_position_z = getattr (ome_meta .getPlanePositionZ (series , 0 ), "value" , lambda : 1.0 )()
568+
569+ max_phys_size_x = max (max_phys_size_x , ome_meta .getPixelsPhysicalSizeX (series ).value ())
570+ max_phys_size_y = max (max_phys_size_y , ome_meta .getPixelsPhysicalSizeY (series ).value ())
571+ max_phys_size_z = max (max_phys_size_z , ome_meta .getPixelsPhysicalSizeZ (series ).value ()
572+ if phys_size_z else z_interval )
573+
574+ stage_coordinates_x .append (current_position_x )
575+ stage_coordinates_y .append (current_position_y )
576+ stage_coordinates_z .append (current_position_z )
577+
578+ max_size = [max_phys_size_x , max_phys_size_y , max_phys_size_z ]
579+
580+ relative_coordinates_x_px = [
581+ (stage_coordinates_x [i ] - stage_coordinates_x [0 ]) / (phys_size_x or 1.0 )
582+ for i in range (len (stage_coordinates_x ))
583+ ]
584+ relative_coordinates_y_px = [
585+ (stage_coordinates_y [i ] - stage_coordinates_y [0 ]) / (phys_size_y or 1.0 )
586+ for i in range (len (stage_coordinates_y ))
587+ ]
588+ relative_coordinates_z_px = [
589+ (stage_coordinates_z [i ] - stage_coordinates_z [0 ]) / (z_interval or 1.0 )
590+ for i in range (len (stage_coordinates_z ))
591+ ]
592+
593+ return StageMetadata (
594+ dimensions = dimensions ,
595+ stage_coordinates_x = stage_coordinates_x ,
596+ stage_coordinates_y = stage_coordinates_y ,
597+ stage_coordinates_z = stage_coordinates_z ,
598+ relative_coordinates_x = relative_coordinates_x_px ,
599+ relative_coordinates_y = relative_coordinates_y_px ,
600+ relative_coordinates_z = relative_coordinates_z_px ,
601+ image_calibration = image_calibration ,
602+ calibration_unit = calibration_unit ,
603+ image_dimensions_czt = image_dimensions_czt ,
604+ series_names = series_names ,
605+ max_size = max_size ,
606+ )
0 commit comments