def extractImagesMetadata(self, imagePath, imageIdentifiers): """Overrides extractImagesMetadata method making sure to store both series and channel indices in the channel code to be reused later to extract color information and other metadata. The channel code is in the form SERIES-(\d+)_CHANNEL-(\d+). Only metadata for the relevant series number is returned! @param imagePath Full path to the file to process @param imageIdentifiers Array of ImageIdentifier's @see constructor. """ # Initialize array of metadata entries metaData = [] # Iterate over all image identifiers for id in imageIdentifiers: # Extract the info from the image identifier ch = int(id.colorChannelIndex) plane = int(id.focalPlaneIndex) series = int(id.seriesIndex) timepoint = int(id.timeSeriesIndex) # Make sure to process only the relevant series if self._seriesNum != -1 and series != self._seriesNum: continue # Build the channel code channelCode = "SERIES-" + str(series) + "_CHANNEL-" + str(ch) # Initialize a new ImageMetadata object imageMetadata = ImageMetadata() # Fill in all information imageMetadata.imageIdentifier = id imageMetadata.seriesNumber = series imageMetadata.timepoint = timepoint imageMetadata.depth = plane imageMetadata.channelCode = channelCode imageMetadata.tileNumber = 1 # + self._seriesNum imageMetadata.well = "IGNORED" # Append metadata for current image metaData.append(imageMetadata) # Log image geometry information if self._DEBUG: self._logger.info( "MICROSCOPYSINGLEDATASETCONFIG::extractImagesMetadata(): " + "Current image: series = " + str(series) + " channel = " + str(ch) + " plane = " + str(plane) + " timepoint = " + str(timepoint) + " channel code = " + str(channelCode)) # Now return the metaData array return metaData
def extractImagesMetadata(self, imagePath, imageIdentifiers): """Overrides extractImagesMetadata method making sure to store both series and channel indices in the channel code to be reused later to extract color information and other metadata. The channel code is in the form SERIES-(\d+)_CHANNEL-(\d+). Only metadata for the relevant series number is returned! @param imagePath Full path to the file to process @param imageIdentifiers Array of ImageIdentifier's @see constructor. """ # Initialize array of metadata entries metaData = [] # Iterate over all image identifiers for id in imageIdentifiers: # Extract the info from the image identifier ch = int(id.colorChannelIndex) plane = int(id.focalPlaneIndex) series = int(id.seriesIndex) timepoint = int(id.timeSeriesIndex) # Make sure to process only the relevant series if self._seriesNum != -1 and series != self._seriesNum: continue # Build the channel code channelCode = "SERIES-" + str(series) + "_CHANNEL-" + str(ch) # Initialize a new ImageMetadata object imageMetadata = ImageMetadata(); # Fill in all information imageMetadata.imageIdentifier = id imageMetadata.seriesNumber = series imageMetadata.timepoint = timepoint imageMetadata.depth = plane imageMetadata.channelCode = channelCode imageMetadata.tileNumber = 1 # + self._seriesNum imageMetadata.well = "IGNORED" # Append metadata for current image metaData.append(imageMetadata) # Log image geometry information if self._DEBUG: self._logger.info("MICROSCOPYSINGLEDATASETCONFIG::extractImagesMetadata(): " + "Current image: series = " + str(series) + " channel = " + str(ch) + " plane = " + str(plane) + " timepoint = " + str(timepoint) + " channel code = " + str(channelCode)) # Now return the metaData array return metaData
def extractImagesMetadata(self, imagePath, imageIdentifiers): """Overrides extractImageMetadata method making sure to store both series and channel indices in the channel code to be reused later to extract color information and other metadata. The channel code is in the form SERIES-(\d+)_CHANNEL-(\d+). Only metadata for the relevant series number is returned! @param imagePath Full path to the file to process @param imageIdentifiers Array of ImageIdentifier's @see constructor. """ # Info self._logger.info("Processing file " + str(imagePath) + " with identifiers " + str(imageIdentifiers)) # Find the file in the csvTable hashmap row = self._csvTable[imagePath] self._logger.info("File " + imagePath + " was found in the CSV table.") self._logger.info("The corresponding row is " + str(row)) # Coordinates position = -1 tileX = -1 tileY = -1 planeNum = -1 timeNum = -1 well = "" # Get the well well = row[4] # Test position string self._logger.info("Position string is " + str(row[5])) # Get the positions from the Position column m_pos = self._pattern_pos.match(row[5]) if m_pos is not None: if m_pos.group("position") is not None: position = int(m_pos.group("position")) if m_pos.group("x") is not None: tileX = int(m_pos.group("x")) if m_pos.group("y") is not None: tileY = int(m_pos.group("y")) if m_pos.group("z") is not None: planeNum = int(m_pos.group("z")) # Try the fallback option m_pos_name_fb = self._pattern_pos_name_fb.match(row[6]) if m_pos_name_fb is not None: if m_pos_name_fb.group("pos") is not None: pos = m_pos_name_fb.group("pos") tileX = int(pos[0:2]) tileY = int(pos[2:4]) # Then, get time information m_time = self._pattern_time_name.match(row[6]) if m_time is not None: if m_time.group("time") is not None: timeNum = int(m_time.group("time")) else: # Try the fallback option m_time_fb = self._pattern_time_name_fb.match(row[6]) if m_time_fb is not None: if m_time_fb.group("time") is not None: timeNum = int(m_time_fb.group("time")) # Fallback if position == -1: position = 1 if tileX == -1: tileX = 1 if tileY == -1: tileY = 1 if planeNum == -1: planeNum = 1 if timeNum == -1: timeNum = 1 # Channel name channelName = self._buildChannelName(row) # Build series ID from row (if present, use path information to build a unique id) seriesID = "Well_" + well + "_Pos_" + str(position) + "_" + str(tileX) + "_" + str(tileY) + "_Path_" + \ self._pathInfoAsID(row[6]) # Find the series number that correspond to seriesID series = self._seriesNumFromSeriesID(seriesID) # Inform if series == -1: err = "Series with ID " + seriesID + " could not be found!" self._logger.error(err) raise (Exception(err)) else: self._logger.info("Series with ID " + seriesID + " corresponds to series number " + str(series)) # Make sure to process only the relevant series if series != self._seriesNum: return [] # Get channel index from channel name channel = self._getChannelNumber(self._allSeriesMetadata[series], channelName) # Build the channel code channelCode = "SERIES-" + str(series) + "_CHANNEL-" + str(channel) if self._DEBUG: msg = "Current file = " + imagePath + " has series = " + \ str(series) + " timepoint = " + str(timeNum) + " plane = " + \ str(planeNum) + " channel = " + str(channel) + " channelCode = " + \ str(channelCode) self._logger.info(msg) # Initialize Metadata array Metadata = [] # Initialize a new ImageMetadata object imageMetadata = ImageMetadata() # Build a tile number from tileX and tileY tileNum = 1000 * tileX + tileY if tileNum < 1: tileNum = 1 self._logger.info("Tile number is " + str(tileNum)) # Fill in all information imageMetadata.imageIdentifier = imageIdentifiers.get(0) imageMetadata.seriesNumber = series imageMetadata.timepoint = timeNum imageMetadata.depth = planeNum imageMetadata.channelCode = channelCode imageMetadata.tileNumber = tileNum imageMetadata.well = well # Now return the image metadata object in an array Metadata.append(imageMetadata) return Metadata
def extractImagesMetadata(self, imagePath, imageIdentifiers): """Overrides extractImageMetadata method making sure to store both series and channel indices in the channel code to be reused later to extract color information and other metadata. The channel code is in the form SERIES-(\d+)_CHANNEL-(\d+). Only metadata for the relevant series number is returned! @param imagePath Full path to the file to process @param imageIdentifiers Array of ImageIdentifier's @see constructor. """ # Info self._logger.info("Processing file " + str(imagePath) + " with identifiers " + str(imageIdentifiers)) # Extract the relevant information from the file name - the image # identifiers in this case do not carry any useful information. m = self._pattern.match(imagePath) if m is None: err = "VISITRONNDCOMPOSITEDATASETCONFIG::extractImageMetadata(): " + \ "unexpected file name " + str(imagePath) self._logger.error(err) raise Exception(err) # Get the extracted info fileinfo = m.groupdict() # Get and store the base name basename = fileinfo['basename'] # Extract the series number series = self._seriesNumFromFileName(imagePath) if series == -1: raise Exception("Could not find any series containing file " + imagePath + "!") if self._DEBUG: self._logger.info("Found file " + imagePath + " in series " + str(series)) # Make sure to process only the relevant series if series != self._seriesNum: return [] # Get current metadata currentMetaData = self._allSeriesMetadata[series] # Compare the basename extracted from the file name with # the one stored in the attributes if basename != currentMetaData["basename"]: self._logger.error("Basename mismatch: " + basename + "(from filename) vs. " + currentMetaData["basename"] + "(from attributes).") # Extract the channel number # The channel number in the file name is 1-based if fileinfo["channel"] is not None: channelNumberFromFile = int(fileinfo['channel']) - 1 if self._DEBUG: self._logger.info("Found channel number " + str(channelNumberFromFile) + " in file name.") else: self._logger.info( "Channel number not found: fall back to image identifiers.") channelNumberFromFile = -1 if fileinfo["channelname"] is not None: channelName = fileinfo['channelname'] if self._DEBUG: self._logger.info("Found channel name " + channelName + " in file name.") else: if channelNumberFromFile != -1: keyName = "channelName" + channelNumberFromFile if keyName in currentMetadata: channelName = currentMetadata[keyName] self._logger.info("Channel name from metadata: " + channelName) else: self._logger.info( "Channel name not found: falling back to ''.") channelName = "" self._logger.info("Channel name not found: falling back to ''.") channelName = "" # Extract the timepoint # The timepoint number in the file (if defined) is 1-based if fileinfo["timepoint"] is not None: timepointFromFile = int(fileinfo['timepoint']) - 1 if self._DEBUG: self._logger.info("Found timepoint " + str(timepointFromFile) + " in file name.") else: timepointFromFile = -1 # Inform if self._DEBUG: self._logger.info("Parsing of file " + str(imagePath) + " gives: " + \ "basename = " + str(basename) + "; " + \ "channelNumber = " + str(channelNumberFromFile) + "; " + \ "channelName = " + channelName + "; " + \ "seriesNum = " + str(series) + "; " + \ "timepoint = " + str(timepointFromFile)) # Initialize array of metadata entries metaData = [] # Now process the file indentifiers for this file # Iterate over all image identifiers for id in imageIdentifiers: # Extract the relevant info from the image identifier plane = id.focalPlaneIndex # Fallback if channelNumberFromFile == -1: channelNumber = int(id.colorChannelIndex) else: channelNumber = channelNumberFromFile if timepointFromFile == -1: timepoint = id.timeSeriesIndex else: timepoint = timepointFromFile if self._DEBUG: self._logger.info("Image identifiers for image " + str(imagePath) + ": " + str(id) + " map to " + "channel = " + str(id.colorChannelIndex) + "; plane = " + str(id.focalPlaneIndex) + "; series = " + str(id.seriesIndex) + "; timepoint = " + str(id.timeSeriesIndex)) self._logger.info( "Geometry after integrating image identifiers: " + "channel = " + str(channelNumber) + "; plane = " + str(plane) + "; series = " + str(series) + "; timepoint = " + str(timepoint)) # Build the channel code channelCode = "SERIES-" + str(series) + "_CHANNEL-" + str( channelNumber) if self._DEBUG: self._logger.info( "Adding image to channel with channel code " + channelCode) # Attempt to work around a geometry-parsing issue in imageIdentifiers expectedNumPlanes = int(currentMetaData["sizeZ"]) expectedNumTimepoints = int(currentMetaData["sizeT"]) if (timepoint > (expectedNumTimepoints - 1) and expectedNumPlanes > 1) or \ (plane > (expectedNumPlanes - 1) and expectedNumTimepoints > 1): self._logger.info("Swapping Z and T") timepoint, plane = plane, timepoint # Update the ImageIdentifier id = ImageIdentifier(series, timepoint, plane, channelNumber) # Initialize a new ImageMetadata object imageMetadata = ImageMetadata() # Fill in all information imageMetadata.imageIdentifier = id imageMetadata.seriesNumber = series imageMetadata.timepoint = timepoint imageMetadata.depth = plane imageMetadata.channelCode = channelCode imageMetadata.tileNumber = 1 # + self._seriesNum imageMetadata.well = "IGNORED" # Append metadata for current image metaData.append(imageMetadata) # Now return the image metadata object in an array return metaData
def extractImagesMetadata(self, imagePath, imageIdentifiers): """Overrides extractImageMetadata method making sure to store both series and channel indices in the channel code to be reused later to extract color information and other metadata. The channel code is in the form SERIES-(\d+)_CHANNEL-(\d+). Only metadata for the relevant series number is returned! @param imagePath Full path to the file to process @param imageIdentifiers Array of ImageIdentifier's @see constructor. """ # Info self._logger.info("Processing file " + str(imagePath) + " with identifiers " + str(imageIdentifiers)) # Extract the relevant information from the file name - the image # identifiers in this case do not carry any useful information. m = self._pattern.match(imagePath) if m is None: err = "VISITRONNDCOMPOSITEDATASETCONFIG::extractImageMetadata(): " + \ "unexpected file name " + str(imagePath) self._logger.error(err) raise Exception(err) # Get the extracted info fileinfo = m.groupdict() # Get and store the base name basename = fileinfo['basename'] # Extract the series number series = self._seriesNumFromFileName(imagePath) if series == -1: raise Exception("Could not find any series containing file " + imagePath + "!") if self._DEBUG: self._logger.info("Found file " + imagePath + " in series " + str(series)) # Make sure to process only the relevant series if series != self._seriesNum: return [] # Get current metadata currentMetaData = self._allSeriesMetadata[series] # Compare the basename extracted from the file name with # the one stored in the attributes if basename != currentMetaData["basename"]: self._logger.error("Basename mismatch: " + basename + "(from filename) vs. " + currentMetaData["basename"] + "(from attributes).") # Extract the channel number # The channel number in the file name is 1-based if fileinfo["channel"] is not None: channelNumberFromFile = int(fileinfo['channel']) - 1 if self._DEBUG: self._logger.info("Found channel number " + str(channelNumberFromFile) + " in file name.") else: self._logger.info("Channel number not found: fall back to image identifiers.") channelNumberFromFile = -1 if fileinfo["channelname"] is not None: channelName = fileinfo['channelname'] if self._DEBUG: self._logger.info("Found channel name " + channelName + " in file name.") else: if channelNumberFromFile != -1: keyName = "channelName" + channelNumberFromFile if keyName in currentMetadata: channelName = currentMetadata[keyName] self._logger.info("Channel name from metadata: " + channelName) else: self._logger.info("Channel name not found: falling back to ''.") channelName = "" self._logger.info("Channel name not found: falling back to ''.") channelName = "" # Extract the timepoint # The timepoint number in the file (if defined) is 1-based if fileinfo["timepoint"] is not None: timepointFromFile = int(fileinfo['timepoint']) - 1 if self._DEBUG: self._logger.info("Found timepoint " + str(timepointFromFile) + " in file name.") else: timepointFromFile = -1 # Inform if self._DEBUG: self._logger.info("Parsing of file " + str(imagePath) + " gives: " + \ "basename = " + str(basename) + "; " + \ "channelNumber = " + str(channelNumberFromFile) + "; " + \ "channelName = " + channelName + "; " + \ "seriesNum = " + str(series) + "; " + \ "timepoint = " + str(timepointFromFile)) # Initialize array of metadata entries metaData = [] # Now process the file indentifiers for this file # Iterate over all image identifiers for id in imageIdentifiers: # Extract the relevant info from the image identifier plane = id.focalPlaneIndex # Fallback if channelNumberFromFile == -1: channelNumber = int(id.colorChannelIndex) else: channelNumber = channelNumberFromFile if timepointFromFile == -1: timepoint = id.timeSeriesIndex else: timepoint = timepointFromFile if self._DEBUG: self._logger.info("Image identifiers for image " + str(imagePath) + ": " + str(id) + " map to " + "channel = " + str(id.colorChannelIndex) + "; plane = " + str(id.focalPlaneIndex) + "; series = " + str(id.seriesIndex) + "; timepoint = " + str(id.timeSeriesIndex)) self._logger.info("Geometry after integrating image identifiers: " + "channel = " + str(channelNumber) + "; plane = " + str(plane) + "; series = " + str(series) + "; timepoint = " + str(timepoint)) # Build the channel code channelCode = "SERIES-" + str(series) + "_CHANNEL-" + str(channelNumber) if self._DEBUG: self._logger.info("Adding image to channel with channel code " + channelCode) # Attempt to work around a geometry-parsing issue in imageIdentifiers expectedNumPlanes = int(currentMetaData["sizeZ"]) expectedNumTimepoints = int(currentMetaData["sizeT"]) if (timepoint > (expectedNumTimepoints - 1) and expectedNumPlanes > 1) or \ (plane > (expectedNumPlanes - 1) and expectedNumTimepoints > 1): self._logger.info("Swapping Z and T") timepoint, plane = plane, timepoint # Update the ImageIdentifier id = ImageIdentifier(series, timepoint, plane, channelNumber) # Initialize a new ImageMetadata object imageMetadata = ImageMetadata(); # Fill in all information imageMetadata.imageIdentifier = id imageMetadata.seriesNumber = series imageMetadata.timepoint = timepoint imageMetadata.depth = plane imageMetadata.channelCode = channelCode imageMetadata.tileNumber = 1 # + self._seriesNum imageMetadata.well = "IGNORED" # Append metadata for current image metaData.append(imageMetadata) # Now return the image metadata object in an array return metaData
def extractImagesMetadata(self, imagePath, imageIdentifiers): """Overrides extractImageMetadata method making sure to store both series and channel indices in the channel code to be reused later to extract color information and other metadata. The channel code is in the form SERIES-(\d+)_CHANNEL-(\d+). Only metadata for the relevant series number is returned! @param imagePath Full path to the file to process @param imageIdentifiers Array of ImageIdentifier's @see constructor. """ # Extract the relevant information from the file name - the image # identifiers in this case do not carry any useful information. m = self._pattern.match(imagePath) simple_m = self._pattern_simple.match(imagePath) # First we try the more complex regex if m is not None: # Get and store the base name basename = m.group("basename") if self._basename == "" or self._basename != basename: self._basename = basename # The series number is not always defined in the file name. if m.group("series") is None: series = 0 else: series = int(m.group("series")) # Make sure to process only the relevant series if series != self._seriesNum: return [] # The time index is also not always specified. if m.group("timepoint") is None: timepoint = 0 else: timepoint = int(m.group("timepoint")) # Plane number is always specified if m.group("plane") is None: plane = 0 else: plane = int(m.group("plane")) # Channel number is always specified if m.group("channel") is None: ch = 0 else: ch = int(m.group("channel")) else: # Try with the simpler regex if simple_m is None: err = "MICROSCOPYCOMPOSITEDATASETCONFIG::extractImageMetadata(): " + \ "unexpected file name " + str(imagePath) self._logger.error(err) raise Exception(err) # Get and store the base name basename = simple_m.group("basename") if self._basename == "" or self._basename != basename: self._basename = basename # Series number series = 0 # Make sure to process only the relevant series if series != self._seriesNum: return [] # Timepoint timepoint = 0 # Plane number is always specified if simple_m.group("plane") is None: plane = 0 else: plane = int(simple_m.group("plane")) # Channel number ch = 0 # Build the channel code channelCode = "SERIES-" + str(series) + "_CHANNEL-" + str(ch) if self._DEBUG: msg = "Current file = " + imagePath + " has series = " + \ str(series) + " timepoint = " + str(timepoint) + " plane = " + \ str(plane) + " channel = " + str(ch) + "; channelCode = " + \ str(channelCode) self._logger.info(msg) # Initialize Metadata array Metadata = [] # Initialize a new ImageMetadata object imageMetadata = ImageMetadata() # Fill in all information imageMetadata.imageIdentifier = imageIdentifiers.get(0) imageMetadata.seriesNumber = series imageMetadata.timepoint = timepoint imageMetadata.depth = plane imageMetadata.channelCode = channelCode imageMetadata.tileNumber = 1 # + self._seriesNum imageMetadata.well = "IGNORED" # Now return the image metadata object in an array Metadata.append(imageMetadata) return Metadata
def extractImagesMetadata(self, imagePath, imageIdentifiers): """Overrides extractImageMetadata method making sure to store both series and channel indices in the channel code to be reused later to extract color information and other metadata. The channel code is in the form SERIES-(\d+)_CHANNEL-(\d+). Only metadata for the relevant series number is returned! @param imagePath Full path to the file to process @param imageIdentifiers Array of ImageIdentifier's @see constructor. """ # Info self._logger.info("Processing file " + str(imagePath) + " with identifiers " + str(imageIdentifiers)) # Find the file in the csvTable hashmap row = self._csvTable[imagePath] self._logger.info("File " + imagePath + " was found in the CSV table.") self._logger.info("The corresponding row is " + str(row)) # Coordinates position = -1 tileX = -1 tileY = -1 planeNum = -1 timeNum = -1 well = "" # Get the well well = row[4] # Test position string self._logger.info("Position string is " + str(row[5])) # Get the positions from the Position column m_pos = self._pattern_pos.match(row[5]) if m_pos is not None: if m_pos.group("position") is not None: position = int(m_pos.group("position")) if m_pos.group("x") is not None: tileX = int(m_pos.group("x")) if m_pos.group("y") is not None: tileY = int(m_pos.group("y")) if m_pos.group("z") is not None: planeNum = int(m_pos.group("z")) # Try the fallback option m_pos_name_fb = self._pattern_pos_name_fb.match(row[6]) if m_pos_name_fb is not None: if m_pos_name_fb.group("pos") is not None: pos = m_pos_name_fb.group("pos") tileX = int(pos[0:2]) tileY = int(pos[2:4]) # Then, get time information m_time = self._pattern_time_name.match(row[6]) if m_time is not None: if m_time.group("time") is not None: timeNum = int(m_time.group("time")) else: # Try the fallback option m_time_fb = self._pattern_time_name_fb.match(row[6]) if m_time_fb is not None: if m_time_fb.group("time") is not None: timeNum = int(m_time_fb.group("time")) # Fallback if position == -1: position = 1 if tileX == -1: tileX = 1 if tileY == -1: tileY = 1 if planeNum == -1: planeNum = 1 if timeNum == -1: timeNum = 1 # Channel name channelName = self._buildChannelName(row) # Build series ID from row (if present, use path information to build a unique id) seriesID = "Well_" + well + "_Pos_" + str(position) + "_" + str(tileX) + "_" + str(tileY) + "_Path_" + \ self._pathInfoAsID(row[6]) # Find the series number that correspond to seriesID series = self._seriesNumFromSeriesID(seriesID) # Inform if series == -1: err = "Series with ID " + seriesID + " could not be found!" self._logger.error(err) raise(Exception(err)) else: self._logger.info("Series with ID " + seriesID + " corresponds to series number " + str(series)) # Make sure to process only the relevant series if series != self._seriesNum: return [] # Get channel index from channel name channel = self._getChannelNumber(self._allSeriesMetadata[series], channelName) # Build the channel code channelCode = "SERIES-" + str(series) + "_CHANNEL-" + str(channel) if self._DEBUG: msg = "Current file = " + imagePath + " has series = " + \ str(series) + " timepoint = " + str(timeNum) + " plane = " + \ str(planeNum) + " channel = " + str(channel) + " channelCode = " + \ str(channelCode) self._logger.info(msg) # Initialize Metadata array Metadata = [] # Initialize a new ImageMetadata object imageMetadata = ImageMetadata() # Build a tile number from tileX and tileY tileNum = 1000 * tileX + tileY if tileNum < 1: tileNum = 1 self._logger.info("Tile number is " + str(tileNum)) # Fill in all information imageMetadata.imageIdentifier = imageIdentifiers.get(0) imageMetadata.seriesNumber = series imageMetadata.timepoint = timeNum imageMetadata.depth = planeNum imageMetadata.channelCode = channelCode imageMetadata.tileNumber = tileNum imageMetadata.well = well # Now return the image metadata object in an array Metadata.append(imageMetadata) return Metadata
def extractImagesMetadata(self, imagePath, imageIdentifiers): """Overrides extractImageMetadata method making sure to store both series and channel indices in the channel code to be reused later to extract color information and other metadata. The channel code is in the form SERIES-(\d+)_CHANNEL-(\d+). Only metadata for the relevant series number is returned! @param imagePath Full path to the file to process @param imageIdentifiers Array of ImageIdentifier's @see constructor. """ # Extract the relevant information from the file name - the image # identifiers in this case do not carry any useful information. m = self._pattern.match(imagePath) simple_m = self._pattern_simple.match(imagePath) # First we try the more complex regex if m is not None: # Get and store the base name basename = m.group("basename") if self._basename == "" or self._basename != basename: self._basename = basename # The series number is not always defined in the file name. # In the regex, the group(2) optionally matches _s{digits}; # in case group(2) is not None, the actual series number is # stored in group(4). if m.group("series") is None: series = 0 else: series = int("series") # Make sure to process only the relevant series if series != self._seriesNum: return [] # The time index is also not always specified. if m.group("timepoint") is None: timepoint = 0 else: timepoint = int(m.group("timepoint")) # Plane number is always specified if m.group("plane") is None: plane = 0 else: plane = int(m.group("plane")) # Channel number is always specified if m.group("channel") is None: ch = 0 else: ch = int(m.group(8)) else: # Try with the simpler regex if simple_m is None: err = "MICROSCOPYCOMPOSITEDATASETCONFIG::extractImageMetadata(): " + \ "unexpected file name " + str(imagePath) self._logger.error(err) raise Exception(err) # Get and store the base name basename = simple_m.group("basename") if self._basename == "" or self._basename != basename: self._basename = basename # Series number series = 0 # Make sure to process only the relevant series if series != self._seriesNum: return [] # Timepoint timepoint = 0 # Plane number is always specified if simple_m.group("plane") is None: plane = 0 else: plane = int(simple_m.group("plane")) # Channel number ch = 0 # Build the channel code channelCode = "SERIES-" + str(series) + "_CHANNEL-" + str(ch) if self._DEBUG: msg = "Current file = " + imagePath + " has series = " + \ str(series) + " timepoint = " + str(timepoint) + " plane = " + \ str(plane) + " channel = " + str(ch) + "; channelCode = " + \ str(channelCode) self._logger.info(msg) # Initialize Metadata array Metadata = [] # Initialize a new ImageMetadata object imageMetadata = ImageMetadata(); # Fill in all information imageMetadata.imageIdentifier = imageIdentifiers.get(0) imageMetadata.seriesNumber = series imageMetadata.timepoint = timepoint imageMetadata.depth = plane imageMetadata.channelCode = channelCode imageMetadata.tileNumber = 1 # + self._seriesNum imageMetadata.well = "IGNORED" # Now return the image metadata object in an array Metadata.append(imageMetadata) return Metadata