def setup(self, path, extensions=None, ignore_prefixes=None, multi_image=None): self.path = os.path.normpath(path) self.extensions = self.EXTENSIONS if extensions is None \ else extensions self.ignore_prefixes = self.IGNORE_PREFIXES if ignore_prefixes is None \ else ignore_prefixes self.multi_image = self.MULTIIMAGE_USE_ZSLICE if multi_image is None \ else multi_image self.has_multi_images = False self.timestamps_from_file = None self.use_frame_indices = False self.dimension_lookup = {} self.meta_data = MetaData()
def setup(self, path, extensions=None, ignore_prefixes=None, multi_image=None): self.path = os.path.normpath(path) self.extensions = self.EXTENSIONS if extensions is None else extensions self.ignore_prefixes = self.IGNORE_PREFIXES if ignore_prefixes is None else ignore_prefixes self.multi_image = self.MULTIIMAGE_USE_ZSLICE if multi_image is None else multi_image self.has_multi_images = False self.timestamps_from_file = None self.use_frame_indices = False self.dimension_lookup = {} self.meta_data = MetaData()
class AbstractImporter(XmlSerializer): EXTENSIONS = [".tif", ".png", ".png"] IGNORE_PREFIXES = ["."] MULTIIMAGE_IGNORE = "ignore" MULTIIMAGE_USE_ZSLICE = "zslice" def __init__(self): super(AbstractImporter, self).__init__() def setup(self, path, extensions=None, ignore_prefixes=None, multi_image=None): self.path = os.path.normpath(path) self.extensions = self.EXTENSIONS if extensions is None else extensions self.ignore_prefixes = self.IGNORE_PREFIXES if ignore_prefixes is None else ignore_prefixes self.multi_image = self.MULTIIMAGE_USE_ZSLICE if multi_image is None else multi_image self.has_multi_images = False self.timestamps_from_file = None self.use_frame_indices = False self.dimension_lookup = {} self.meta_data = MetaData() def __setstate__(self, state): for k, v in state.iteritems(): self.__dict__[k] = v def scan(self): self.dimension_lookup = self._build_dimension_lookup() self.meta_data.setup() @property def is_valid(self): """ Return the import success. For now only the number of identified files is checked. """ return self.meta_data.image_files > 0 def get_image(self, coordinate): index = 0 zslice = coordinate.zslice if self.has_multi_images and self.multi_image == self.MULTIIMAGE_USE_ZSLICE: index = zslice - 1 zslice = None filename_rel = self.dimension_lookup[coordinate.position][coordinate.time][coordinate.channel][zslice] filename_abs = os.path.join(self.path, filename_rel) # make sure no back-slashes are left in the path filename_abs = filename_abs.replace("\\", "/") if self.meta_data.pixel_type == PixelType.name(PixelType.Uint8): image = ccore.readImage(filename_abs, index) elif self.meta_data.pixel_type == PixelType.name(PixelType.Uint16): image = ccore.readImageUInt16(filename_abs, index) else: image = ccore.readImageUInt16(filename_abs, index) return image def _build_dimension_lookup(self): s = StopWatch(start=True) lookup = {} has_xy = False positions = [] times = [] channels = [] zslices = [] dimension_items = self._get_dimension_items() print("Get dimensions: %s" % s.interim()) s.reset(start=True) # if use_frame_indices is set in the ini file, # we make a first scan of the items and determine for each position # the list of timepoints. # Then, we can assign to each position a dictionary that assigns to each timepoint # its index (after ordering). if self.use_frame_indices: # all_times = list(set([int(item[Dimensions.Time]) if Dimensions.Time in item else 0 # for item in dimension_items])) # all_times.sort() first_pass = {} for item in dimension_items: position = item[Dimensions.Position] if not position in first_pass: first_pass[position] = [] if Dimensions.Time in item: time_val = int(item[Dimensions.Time]) else: time_val = 0 first_pass[position].append(time_val) time_index_correspondence = {} for pos in first_pass.keys(): first_pass[position].sort() time_index_correspondence[pos] = dict(zip(first_pass[position], range(len(first_pass[position])))) for item in dimension_items: # import image info only once if not has_xy: has_xy = True info = ccore.ImageImportInfo(os.path.join(self.path, item["filename"])) self.meta_data.set_image_info(info) self.has_multi_images = False # info.images > 1 # position position = item[Dimensions.Position] if not position in lookup: lookup[position] = {} # time if Dimensions.Time in item: time_from_filename = int(item[Dimensions.Time]) else: time_from_filename = 0 item[Dimensions.Time] = str(time_from_filename) if self.use_frame_indices: time = time_index_correspondence[position][time_from_filename] else: time = time_from_filename if not time in lookup[position]: lookup[position][time] = {} # channels if Dimensions.Channel in item: channel = item[Dimensions.Channel] else: channel = "1" item[Dimensions.Channel] = channel if not channel in lookup[position][time]: lookup[position][time][channel] = {} # leave zslice optional. # in case of multi-images it must not be defined if Dimensions.ZSlice in item: zslice = item[Dimensions.ZSlice] else: zslice = 0 item[Dimensions.ZSlice] = zslice if zslice == "": zslice = None if not zslice is None: zslice = int(zslice) if not zslice in lookup[position][time][channel]: lookup[position][time][channel][zslice] = item["filename"] # allow to read timestamps from file if not present if MetaInfo.Timestamp in item: timestamp = float(item[MetaInfo.Timestamp]) self.meta_data.append_absolute_time(position, time, timestamp) elif self.timestamps_from_file in ["mtime", "ctime"]: filename_full = os.path.join(self.path, item["filename"]) if self.timestamps_from_file == "mtime": timestamp = os.path.getmtime(filename_full) else: timestamp = os.path.getctime(filename_full) item[MetaInfo.Timestamp] = timestamp self.meta_data.append_absolute_time(position, time, timestamp) if MetaInfo.Well in item: well = item[MetaInfo.Well] subwell = item.get(MetaInfo.Subwell, None) self.meta_data.append_well_subwell_info(position, well, subwell) if self.has_multi_images and self.multi_image == self.MULTIIMAGE_USE_ZSLICE: if not zslice is None: raise ValueError("Multi-image assigned for zslice conflicts" " with zslice token in filename!") zslices.extend(range(1, info.images + 1)) else: zslices.append(zslice) positions.append(position) times.append(time) channels.append(channel) self.meta_data.positions = tuple(sorted(set(positions))) # assure that all items of one dimension are of same length times = set(times) channels = set(channels) zslices = set(zslices) # find overall valid number of frames for p in lookup: times = times.intersection(lookup[p].keys()) # find overall valid channels/zslices based on overall valid frames for p in lookup: for t in times: channels = channels.intersection(lookup[p][t].keys()) for c in channels: zslices = zslices.intersection(lookup[p][t][c].keys()) self.meta_data.times = sorted(times) self.meta_data.channels = sorted(channels) self.meta_data.zslices = sorted(zslices) self.meta_data.image_files = len(dimension_items) print("Build time: %s" % s.stop()) return lookup def _get_dimension_items(self): raise NotImplementedError()
class AbstractImporter(XmlSerializer): EXTENSIONS = ['.tif', '.png', '.png'] IGNORE_PREFIXES = ['.'] MULTIIMAGE_IGNORE = 'ignore' MULTIIMAGE_USE_ZSLICE = 'zslice' def __init__(self): super(AbstractImporter, self).__init__() def setup(self, path, extensions=None, ignore_prefixes=None, multi_image=None): self.path = os.path.normpath(path) self.extensions = self.EXTENSIONS if extensions is None \ else extensions self.ignore_prefixes = self.IGNORE_PREFIXES if ignore_prefixes is None \ else ignore_prefixes self.multi_image = self.MULTIIMAGE_USE_ZSLICE if multi_image is None \ else multi_image self.has_multi_images = False self.timestamps_from_file = None self.use_frame_indices = False self.dimension_lookup = {} self.meta_data = MetaData() def __setstate__(self, state): for k, v in state.iteritems(): self.__dict__[k] = v def scan(self): self.dimension_lookup = self._build_dimension_lookup() self.meta_data.setup() @property def is_valid(self): """ Return the import success. For now only the number of identified files is checked. """ return self.meta_data.image_files > 0 def get_image(self, coordinate): index = 0 zslice = coordinate.zslice if (self.has_multi_images and self.multi_image == self.MULTIIMAGE_USE_ZSLICE): index = zslice - 1 zslice = None filename_rel = self.dimension_lookup[coordinate.position] \ [coordinate.time] \ [coordinate.channel] \ [zslice] filename_abs = os.path.join(self.path, filename_rel) # make sure no back-slashes are left in the path filename_abs = filename_abs.replace('\\', '/') if self.meta_data.pixel_type == PixelType.name(PixelType.Uint8): image = ccore.readImage(filename_abs, index) elif self.meta_data.pixel_type == PixelType.name(PixelType.Uint16): image = ccore.readImageUInt16(filename_abs, index) else: image = ccore.readImageUInt16(filename_abs, index) return image def _build_dimension_lookup(self): s = StopWatch(start=True) lookup = {} has_xy = False positions = [] times = [] channels = [] zslices = [] dimension_items = self._get_dimension_items() print("Get dimensions: %s" % s.interim()) s.reset(start=True) # if use_frame_indices is set in the ini file, # we make a first scan of the items and determine for each position # the list of timepoints. # Then, we can assign to each position a dictionary that assigns to each timepoint # its index (after ordering). if self.use_frame_indices: #all_times = list(set([int(item[Dimensions.Time]) if Dimensions.Time in item else 0 # for item in dimension_items])) #all_times.sort() first_pass = {} for item in dimension_items: position = item[Dimensions.Position] if not position in first_pass: first_pass[position] = [] if Dimensions.Time in item: time_val = int(item[Dimensions.Time]) else: time_val = 0 first_pass[position].append(time_val) time_index_correspondence = {} for pos in first_pass.keys(): first_pass[position].sort() time_index_correspondence[pos] = dict( zip(first_pass[position], range(len(first_pass[position])))) for item in dimension_items: # import image info only once if not has_xy: has_xy = True info = ccore.ImageImportInfo( os.path.join(self.path, item['filename'])) self.meta_data.set_image_info(info) self.has_multi_images = False #info.images > 1 # position position = item[Dimensions.Position] if not position in lookup: lookup[position] = {} # time if Dimensions.Time in item: time_from_filename = int(item[Dimensions.Time]) else: time_from_filename = 0 item[Dimensions.Time] = str(time_from_filename) if self.use_frame_indices: time = time_index_correspondence[position][time_from_filename] else: time = time_from_filename if not time in lookup[position]: lookup[position][time] = {} # channels if Dimensions.Channel in item: channel = item[Dimensions.Channel] else: channel = '1' item[Dimensions.Channel] = channel if not channel in lookup[position][time]: lookup[position][time][channel] = {} # leave zslice optional. # in case of multi-images it must not be defined if Dimensions.ZSlice in item: zslice = item[Dimensions.ZSlice] else: zslice = 0 item[Dimensions.ZSlice] = zslice if zslice == '': zslice = None if not zslice is None: zslice = int(zslice) if not zslice in lookup[position][time][channel]: lookup[position][time][channel][zslice] = item['filename'] # allow to read timestamps from file if not present if MetaInfo.Timestamp in item: timestamp = float(item[MetaInfo.Timestamp]) self.meta_data.append_absolute_time(position, time, timestamp) elif self.timestamps_from_file in ['mtime', 'ctime']: filename_full = os.path.join(self.path, item['filename']) if self.timestamps_from_file == 'mtime': timestamp = os.path.getmtime(filename_full) else: timestamp = os.path.getctime(filename_full) item[MetaInfo.Timestamp] = timestamp self.meta_data.append_absolute_time(position, time, timestamp) if MetaInfo.Well in item: well = item[MetaInfo.Well] subwell = item.get(MetaInfo.Subwell, None) self.meta_data.append_well_subwell_info( position, well, subwell) if (self.has_multi_images and self.multi_image == self.MULTIIMAGE_USE_ZSLICE): if not zslice is None: raise ValueError( 'Multi-image assigned for zslice conflicts' ' with zslice token in filename!') zslices.extend(range(1, info.images + 1)) else: zslices.append(zslice) positions.append(position) times.append(time) channels.append(channel) self.meta_data.positions = tuple(sorted(set(positions))) # assure that all items of one dimension are of same length times = set(times) channels = set(channels) zslices = set(zslices) # find overall valid number of frames for p in lookup: times = times.intersection(lookup[p].keys()) # find overall valid channels/zslices based on overall valid frames for p in lookup: for t in times: channels = channels.intersection(lookup[p][t].keys()) for c in channels: zslices = zslices.intersection(lookup[p][t][c].keys()) self.meta_data.times = sorted(times) self.meta_data.channels = sorted(channels) self.meta_data.zslices = sorted(zslices) self.meta_data.image_files = len(dimension_items) print('Build time: %s' % s.stop()) return lookup def _get_dimension_items(self): raise NotImplementedError()