def get_im_shape_and_dtype(self, files): im0 = tifffile.memmap(files[0], mode='r') im_shape = im0.shape im_shapes = [tifffile.memmap(ff, mode='r').shape for ff in files[1:]] if any(sh != im_shape for sh in im_shapes): raise ValueError("Incompatible shapes for Image Stack") return im_shape, im0.dtype
def supports_memmap(image_path): if tifffile is None: return False ext = os.path.splitext(image_path)[1] if ext.lower() not in TIF_EXTS: return False try: tifffile.memmap(image_path, mode='r') except ValueError: return False return True
def threeDImageArrays(path): once = 0 dimension1 = 0 dimension2 = 0 channels_dict = defaultdict(int) for filename in os.listdir(path): try: if(once == 0): rememmap = tif.memmap( path + "/" + filename) dimension1 = rememmap.shape[0] dimension2 = rememmap.shape[1] once += 1 channel_num = int(filename[10:12]) channels_dict[channel_num] += 1 except ValueError: pass main_dict = dict() for ch, Zs in channels_dict.items(): main_dict[ch] = np.random.randint(0, 5, (int(Zs/4), dimension1 * 2, dimension2 * 2), 'uint16') i = 0 for filename in os.listdir(path): try: x = int(filename[0:3][0]) y = int(filename[0:3][-1]) Z = int(filename[5:8]) channel_num = int(filename[10:12]) rememmap = tif.memmap( path + "/" + filename) if(x == 0 and y == 0): main_dict[channel_num][Z,0:dimension1,0:dimension2] = rememmap elif(x == 0 and y == 1): main_dict[channel_num][Z,0:dimension1*2,dimension2:dimension2*2] = rememmap elif(x == 1 and y == 0): main_dict[channel_num][Z,dimension1:dimension1*2,0:dimension2] = rememmap elif(x == 1 and y == 1): main_dict[channel_num][Z,dimension1:dimension1*2,dimension2:dimension2*2] = rememmap except ValueError: pass for i,array in main_dict.items(): new_file_name = "channel" + str(i) + ".tif" tif.imwrite(new_file_name, array, photometric='minisblack') #tif.imwrite(new_file_name, array, photometric='rgb') return tuple(main_dict.values())
def is_tif_stack(path): if tifffile is None: return False ext = os.path.splitext(path)[1] if ext.lower() not in TifStackDataset.tif_exts: return False try: tifffile.memmap(path) except ValueError: return False return True
def fillHoles(oldCollagenFile, newCollagenFile): if (os.path.isfile(newCollagenFile)): print(newCollagenFile + " already exists.") return oldCollagen = memmap(oldCollagenFile, dtype='uint8') newCollagen = memmap(newCollagenFile, shape=oldCollagen.shape, dtype='uint8') kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (20, 20)) newCollagen[:,:] = cv2.morphologyEx(oldCollagen, cv2.MORPH_CLOSE, kernel) newCollagen[newCollagen == 1] = 255 del oldCollagen del newCollagen
def check_input(path): files = glob(os.path.join(path, '*.tif')) files.sort() im_shape = memmap(files[0], mode='r').shape for ff in files[1:]: this_shape = memmap(ff, mode='r').shape if im_shape != this_shape: print("Shapes don't match for", ff) print(im_shape, this_shape) assert False shape = (len(files),) + im_shape print(shape)
def is_tif_slices(files): if tifffile is None: return False f0 = files[0] ext = os.path.splitext(f0)[1] if ext.lower() not in TifStackDataset.tif_exts: return False try: tifffile.memmap(f0) except ValueError: return False return True
def removeSmallCollagenBlops(oldFile, newFile, threshold): assert(os.path.isfile(oldFile)), oldFile + " does not exist" if (os.path.isfile(newFile)): print(newFile + " already exists") return oldCollagen = memmap(oldFile, dtype='uint8') newCollagen = memmap(newFile, shape = oldCollagen.shape, dtype='uint8') for x in range(0, oldCollagen.shape[0] - (s-1), s/2): for y in range(0, oldCollagen.shape[1] - (s-1), s/2): patch = numpy.array(oldCollagen[x:x+s, y:y+s]) current = numpy.array(newCollagen[x:x+s, y:y+s]) newCollagen[x:x+s, y:y+s] = current | removeBlops(patch, threshold) del oldCollagen del newCollagen
def load_band(self, band, compute_toa_flag=True, sun_elevation_correction=True, slice_=None): """ https://www.usgs.gov/land-resources/nli/landsat/using-usgs-landsat-level-1-data-product Lλ = MLQcal + AL Lλ = TOA spectral radiance (Watts/( m2 * srad * μm)) ML = Band-specific multiplicative rescaling factor from the metadata (RADIANCE_MULT_BAND_x, where x is the band number) AL = Band-specific additive rescaling factor from the metadata (RADIANCE_ADD_BAND_x, where x is the band number) Qcal = Quantized and calibrated standard product pixel values (DN) :param band: :param compute_toa_flag: :param sun_elevation_correction: :param slice_: slice to read :return: """ band_name = str(band) fileband_name = os.path.join(self.folder_tiffs, self.name + "_B" + band_name + ".TIF") img = tifffile.memmap(fileband_name) if slice_ is None: slice_ = (slice(None), slice(None)) img = img[slice_].astype(np.float32) if compute_toa_flag: return compute_toa_single( img, band, self.metadata, sun_elevation_correction=sun_elevation_correction) return img
def czi2tif(czifile, tiffile=None, squeeze=True, verbose=True, **kwargs): """Convert CZI file to memory-mappable TIFF file. To read the image data from the created TIFF file: Read the 'StripOffsets' and 'ImageDescription' tags from the first TIFF page. Get the 'dtype' and 'shape' attributes from the ImageDescription string using a JSON decoder. Memory-map 'product(shape) * sizeof(dtype)' bytes in the file starting at StripOffsets[0]. Cast the mapped bytes to an array of 'dtype' and 'shape'. """ verbose = print_ if verbose else lambda *a, **b: None if tiffile is None: tiffile = czifile + '.tif' elif tiffile.lower() == 'none': tiffile = None verbose("\nOpening CZI file... ", end='', flush=True) start_time = time.time() with CziFile(czifile) as czi: if squeeze: shape, axes = squeeze_axes(czi.shape, czi.axes, '') else: shape = czi.shape axes = czi.axes dtype = str(czi.dtype) size = product(shape) * czi.dtype.itemsize verbose("%.3f s" % (time.time() - start_time)) verbose("Image\n axes: %s\n shape: %s\n dtype: %s\n size: %s" % (axes, shape, dtype, format_size(size)), flush=True) if not tiffile: verbose("Copying image from CZI file to RAM... ", end='', flush=True) start_time = time.time() czi.asarray(order=0) else: verbose("Creating empty TIF file... ", end='', flush=True) start_time = time.time() if 'software' not in kwargs: kwargs['software'] = 'czi2tif' metadata = kwargs.pop('metadata', {}) metadata.update(axes=axes, dtype=dtype) data = memmap(tiffile, shape=shape, dtype=dtype, metadata=metadata, **kwargs) data = data.reshape(czi.shape) verbose("%.3f s" % (time.time() - start_time)) verbose("Copying image from CZI to TIF file... ", end='', flush=True) start_time = time.time() czi.asarray(order=0, out=data) verbose("%.3f s" % (time.time() - start_time), flush=True)
def _load_fixemask(self, slice_=None): if slice_ is None: slice_ = (slice(None), slice(None)) img = tifffile.memmap(self.gt_file) return img[slice_]
def load_bqa(self, slice_=None): if slice_ is None: slice_ = (slice(None), slice(None)) bqa = tifffile.memmap( os.path.join(self.folder_tiffs, self.name + "_BQA.TIF")) return bqa[slice_]
def test_3d_uint8(self): background = tif.memmap('./input/testdata_uint8_3d_auto.tif') equal = test(self.im_filter, './input/testdata_uint8_3d_signal.tif', './filters/backgroundsubtraction/regular_output/out_uint8_3d_signal.tif', **{'background': background} ) self.assertTrue(equal)
def write_tiles(self): """ If the region cropped has a size in pixels above 4096 in any dimension the *.ome.tiff will be written as tiled data using a numpy memmap. Writing of the *.ome.tiff is done using tifffile. :returns number of tiles written """ tw = self.tile_width th = self.tile_height size_x = self.size_x size_y = self.size_y size_c = self.size_c # initialise the numpy memmap fp = memmap( self.outputpath, dtype='uint8', mode='r+', shape=(size_c, size_y, size_x), description=self.xml, photometric='MINISBLACK' ) tile_count = 0 for c in range(0, self.size_c): channel = self.channels[c] for tile_offset_y in range(0, floor((size_y + th - 1) / th)): for tile_offset_x in range(0, floor((size_x + tw - 1) / tw)): x = tile_offset_x * tw y = tile_offset_y * tw w = tw if (w + x > size_x): w = size_x - x h = th if (h + y > size_y): h = size_y - y # get the pixel data out of the SlideImage chunk = self._get_pixels(channel, x, y, w, h) print(chunk.shape) if (w != chunk.shape[-1]) or (h != chunk.shape[-2]): w = chunk.shape[-1] h = chunk.shape[-2] # add the data to the memmap # TODO: apply rotation fp[c, y: y + h, x: x + w] = chunk[:, :] fp.flush() del fp return tile_count
def test(im_filter, input_path, correct_output_path, **extra_kwargs): input_path = Path(input_path) copy_path = Path(input_path.stem + '_copy').with_suffix('.tif') shutil.copy(input_path, copy_path) data = tif.imread(str(copy_path)) im_filter.set_inputs({**{'input': data}, **extra_kwargs}) generated_output = im_filter.run() correct_output = tif.memmap(correct_output_path) equal = np.all(generated_output == correct_output) os.remove(copy_path) return equal
def _open_probability_map_file(self, image_nr, label_value, multichannel=False): """Minor change in the file and path definition.""" # memmap is slow, so we must cache it to be fast! fname = self.filenames[image_nr].img if multichannel: fname = Path('{}.tif'.format(fname)) n_classes = multichannel C = n_classes else: fname = Path('{}_class_{}.tif'.format(fname, label_value)) C = 1 # channel in output probmap path = self.savepath / fname if not path.exists(): # created "empty" tif of shape _, Z, X, Y = self.image_dimensions(image_nr) return memmap(path, shape=(Z, Y, X, C), dtype='float32') return memmap(path)
def read_tif( path: str, img5d: Image5d = None) -> Tuple[Image5d, Dict[config.MetaKeys, Any]]: """Read TIF files with Tifffile with lazy access through memory mapping. Args: path: Path to file. img5d: Image5d storage class; defaults to None. Returns: Image5d storage instance and dictionary of extracted metadata. """ if img5d is None: # set up a new storage instance img5d = Image5d() # extract metadata tif = tifffile.TiffFile(path) md = dict.fromkeys(config.MetaKeys) axes = tif.series[0].axes if tif.ome_metadata: # read OME-XML metadata names, sizes, md = importer.parse_ome_raw(tif.ome_metadata) res = np.array(md[config.MetaKeys.RESOLUTIONS]) print(tif.ome_metadata) else: # parse resolutions res = np.ones((1, 3)) if tif.imagej_metadata and "spacing" in tif.imagej_metadata: # ImageJ format holds z-resolution as spacing res[0, 0] = tif.imagej_metadata["spacing"] for i, name in enumerate(("YResolution", "XResolution")): # parse x/y-resolution from standard TIF metadata axis_res = tif.pages[0].tags[name].value if axis_res and len(axis_res) > 1 and axis_res[0]: res[0, i + 1] = axis_res[1] / axis_res[0] md[config.MetaKeys.RESOLUTIONS] = res # load TIFF by memory mapping tif_memmap = tifffile.memmap(path) ndim = len(tif_memmap.shape) if ndim < 4 or ndim == 4 and "c" in axes.lower(): # add a time dimension for 3D or 3D+C images to ensure TZYX(C) axes tif_memmap = np.expand_dims(tif_memmap, axis=0) # add image to Image5d instance img5d.img = tif_memmap img5d.path_img = path img5d.img_io = config.LoadIO.TIFFFILE return img5d, md
def read_image(self, image_filename): # read image self.image = memmap( os.path.join(self.output_dir, 'memmap', os.path.split(image_filename)[1])) self.image_size = self.image.shape[::-1] # (width, height) # downscale image self.image = self.image[::self.dsr, ::self.dsr] # adjust intensity to 2% and 98% percentile p2, p98 = np.percentile(self.image, (2, 98)) self.image = rescale_intensity(self.image, in_range=(p2, p98))
def get_focus_index_croped(self, imgpath): print("Reading: " + imgpath) self.basepath, self.imgname = os.path.split(imgpath) # Calculate focus index as in Xu et al. 2017 # Images are too big. Calculate in central portion self.img = tifffile.memmap(imgpath) # memory map self.xc = int(self.img.shape[0] / 4) self.yc = int(self.img.shape[1] / 4) self.img_croped = self.img[self.xc:2 * self.xc, self.yc:2 * self.yc] self.smooth_short = gaussian(self.img_croped, sigma=2) self.smooth_long = gaussian(self.img_croped, sigma=4) self.pixwise_dif = self.smooth_short - self.smooth_long self.focus_index = np.sum(np.sqrt(np.square( self.pixwise_dif))) / self.img_croped.size # If FI is less than min: call person on duty self.nav_ref = self.controller.get_frame("navbar") self.min_fi = self.nav_ref.inp.get() if self.focus_index < float(self.min_fi): account_sid = os.environ['TWILIO_ACCOUNT_SID'] auth_token = os.environ['TWILIO_AUTH_TOKEN'] client = Client(account_sid, auth_token) call = client.calls.create( twiml= '<Response><Say>FIBdeSEMAna has a problem!!</Say></Response>', to='+34667878228', from_='+19843004811') print(call.sid) # Keep copy of 100 focus idxs for detection # if len(app.main.focus_idxs) < 100: # app.main.focus_idxs.append((self.imgname, self.focus_index)) # else: # app.main.focus_idxs.clear() # app.main.focus_idxs.append((self.imgname, self.focus_index)) # print(app.main.focus_idxs[-5:]) # Write FI to a file and update the plot self.f = open(os.path.join(self.basepath, "focus_idxs.csv"), "a+") self.f.write(self.imgname + "," + str(self.focus_index) + "\n") self.f.flush() self.f.seek(0) # Update the plot self.refresh_plot(self.f) self.f.close()
def computeRawCollagenMask(slide, rawCollagenFile, model): if (os.path.isfile(rawCollagenFile)): print(rawCollagenFile + " already exists.") return rawCollagen = memmap(rawCollagenFile, shape=slide.dimensions, dtype='uint8') for x in range(0, slide.dimensions[0] - (s-1), s/2): for y in range(0, slide.dimensions[1] - (s-1), s/2): patch = slide.read_region(location = (x, y), size = (s, s), level = 0) patch = numpy.array(patch)[:,:,:3] current = numpy.array(rawCollagen[x:x+s, y:y+s]) # openslide uses (width, height) dimensions, tifffile.memmap (height, width). # Thus, I am transposing the extracted collagen. rawCollagen[x:x+s, y:y+s] = current | numpy.transpose(extractCollagen(patch, model)) del rawCollagen
def _open_label_file(self, image_nr): # memmap is slow, so we must cache it to be fast! path = self.img_path / self.filenames[image_nr].img label_filename = self.filenames[image_nr].lbl if label_filename is None: logger.warning('no label matrix file found for image file %s', str(image_nr)) return None path = self.label_path / label_filename logger.debug('Trying to load labelmat %s', path) lbl_data = memmap(path) return self.fix_dims(lbl_data, path) # shape order: z, y, x, c
def test_put_probmap_data_2(self): img_path = os.path.abspath( os.path.join( base_path, '../test_data/tiffconnector_1/im/6width4height3slices_rgb.tif') ) label_path = os.path.join(base_path, '/path/to/nowhere') c = TiffConnector(img_path, label_path, savepath=self.tmpdir) d = Dataset(c) size = (1, 2, 2) batch_size = 1 p = PredictionBatch(d, batch_size, size) pixel_val = 0 for mb in p: pixel_val += 10 data = np.ones((1, 2, 1, 2, 2)) * pixel_val mb.put_probmap_data(data) pixelmap = memmap( os.path.join(self.tmpdir, '6width4height3slices_rgb_class_1.tif')) # zslice 0 val_0 = np.array([[10., 10., 30., 30., 50., 50.], [10., 10., 30., 30., 50., 50.], [20., 20., 40., 40., 60., 60.], [20., 20., 40., 40., 60., 60.]]) assert_array_almost_equal(pixelmap[0, :, :, 0], val_0) # zslice 1 val_1 = np.array([[70., 70., 90., 90., 110., 110.], [70., 70., 90., 90., 110., 110.], [80., 80., 100., 100., 120., 120.], [80., 80., 100., 100., 120., 120.]]) assert_array_almost_equal(pixelmap[1, :, :, 0], val_1) # zslice 2 val_2 = np.array([[130., 130., 150., 150., 170., 170.], [130., 130., 150., 150., 170., 170.], [140., 140., 160., 160., 180., 180.], [140., 140., 160., 160., 180., 180.]]) assert_array_almost_equal(pixelmap[2, :, :, 0], val_2)
def create(location=None, shape=None, dtype=None, mode=None, as_source=True, **kwargs): """Create a memory map. Arguments --------- location : str The filename of the memory mapped array. shape : tuple or None The shape of the memory map to create. dtype : dtype The data type of the memory map. mode : 'r', 'w', 'w+', None The mode to open the memory map. as_source : bool If True, return as Source class. Returns ------- memmap : np.memmap The memory map. Note ---- By default memmaps are initialized as fortran contiguous if order is None. """ if shape is None: raise ValueError('Shape for new tif file must be given!') shape = shape_to_tif(shape) mode = 'r+' if mode == 'w+' or mode is None else mode dtype = 'float64' if dtype is None else dtype memmap = tif.memmap(filename=location, shape=shape, dtype=dtype, mode=mode) if as_source: return Source(location) else: return memmap
def __init__( self, file_path: PathType, sampling_frequency: FloatType, channel_names: ArrayType = None, ): assert HAVE_TIFF, self.installation_mesg ImagingExtractor.__init__(self) self.file_path = Path(file_path) self._sampling_frequency = sampling_frequency self._channel_names = channel_names assert self.file_path.suffix in [".tiff", ".tif", ".TIFF", ".TIF"] with tifffile.TiffFile(self.file_path) as tif: self._num_channels = len(tif.series) # deal with multiple channels self._video = tifffile.memmap(self.file_path, mode="r") ( self._num_channels, self._num_frames, self._size_x, self._size_y, ) = get_video_shape(self._video) if len(self._video.shape) == 3: # check if this converts to np.ndarray self._video = self._video[np.newaxis, :] if self._channel_names is not None: assert len(self._channel_names) == self._num_channels, ( "'channel_names' length is different than number " "of channels" ) else: self._channel_names = [f"channel_{ch}" for ch in range(self._num_channels)] self._kwargs = { "file_path": str(Path(file_path).absolute()), "sampling_frequency": sampling_frequency, "channel_names": channel_names, }
def write_memmap(image_filenames, output_dir, dtype='uint8'): if not os.path.exists(os.path.join(output_dir, 'memmap')): os.makedirs(os.path.join(output_dir, 'memmap')) output_dir = os.path.join(output_dir, 'memmap') for file in image_filenames: image = imread(file) if dtype == 'uint8': image = img_as_ubyte(image) new_file = os.path.join(output_dir, os.path.split(file)[1]) memmap_image = memmap(new_file, shape=image.shape, dtype=image.dtype, bigtiff=True) memmap_image[:] = image[:] memmap_image.flush() del memmap_image
def import_videos(self, video_paths): # add the new video paths to the currently loaded video paths self.video_paths += video_paths # assign a group number to the new videos if len(self.video_groups) > 0: group_num = np.amax(np.unique(self.video_groups)) + 1 else: group_num = 0 # store video lengths and group numbers for video_path in video_paths: video = tifffile.memmap(video_path) self.video_lengths.append(video.shape[0]) self.video_groups.append(group_num) self.tail_angles.append(None) if len(video.shape) > 3: num_z = video.shape[1] else: num_z = 1 self.mask_points[group_num] = [ [] for z in range(num_z) ]
def __init__(self, file_path: PathType, sampling_frequency, channel_names=None): assert HAVE_TIFF, self.installation_mesg ImagingExtractor.__init__(self) self.file_path = Path(file_path) self._sampling_frequency = sampling_frequency self._channel_names = channel_names assert self.file_path.suffix in ['.tiff', '.tif', '.TIFF', '.TIF'] with tifffile.TiffFile(self.file_path) as tif: self._num_channels = len(tif.series) # deal with multiple channels self._video = tifffile.memmap(self.file_path) self._num_channels, self._num_frames, self._size_x, self._size_y = get_video_shape( self._video) if len(self._video.shape) == 3: # check if this converts to np.ndarray self._video = self._video[np.newaxis, :] if self._channel_names is not None: assert len(self._channel_names) == self._num_channels, "'channel_names' length is different than number " \ "of channels" else: self._channel_names = [ f'channel_{ch}' for ch in range(self._num_channels) ] self._kwargs = { 'file_path': str(Path(file_path).absolute()), 'sampling_frequency': sampling_frequency, 'channel_names': channel_names }
def _read_volume(self): return tifffile.memmap(self.files)
def _read_image(self, index): return tifffile.memmap(self.files[index])
def load_rois(self, load_path, group_num=None, video_path=None): # load the saved ROIs roi_data = np.load(load_path) # extract the dictionary roi_data = roi_data[()] if group_num is None: # set ROI variables self.roi_spatial_footprints = roi_data['roi_spatial_footprints'] self.roi_temporal_footprints = roi_data['roi_temporal_footprints'] self.roi_temporal_residuals = roi_data['roi_temporal_residuals'] self.bg_spatial_footprints = roi_data['bg_spatial_footprints'] self.bg_temporal_footprints = roi_data['bg_temporal_footprints'] self.filtered_out_rois = roi_data['filtered_out_rois'] self.discarded_rois = roi_data['discarded_rois'] self.removed_rois = roi_data['removed_rois'] self.locked_rois = roi_data['locked_rois'] if 'masks' in roi_data.keys(): self.mask_points = roi_data['masks'] else: self.mask_points = {} if len(self.video_paths) > 0: # get number of z planes video = tifffile.memmap(self.video_paths[0]) if len(video.shape) > 3: num_z = video.shape[1] else: num_z = 1 for group_num in np.unique(self.video_groups): self.mask_points[group_num] = [ [] for z in range(num_z) ] else: roi_spatial_footprints = roi_data['roi_spatial_footprints'] roi_temporal_footprints = roi_data['roi_temporal_footprints'] roi_temporal_residuals = roi_data['roi_temporal_residuals'] bg_spatial_footprints = roi_data['bg_spatial_footprints'] bg_temporal_footprints = roi_data['bg_temporal_footprints'] filtered_out_rois = roi_data['filtered_out_rois'] discarded_rois = roi_data['discarded_rois'] removed_rois = roi_data['removed_rois'] locked_rois = roi_data['locked_rois'] if 'masks' in roi_data.keys(): masks = roi_data['masks'] else: if len(self.video_paths) > 0: # get number of z planes video = tifffile.memmap(self.video_paths[0]) if len(video.shape) > 3: num_z = video.shape[1] else: num_z = 1 masks = [ [] for z in range(num_z) ] self.roi_spatial_footprints[group_num] = roi_spatial_footprints self.bg_spatial_footprints[group_num] = bg_spatial_footprints self.filtered_out_rois[group_num] = filtered_out_rois self.discarded_rois[group_num] = discarded_rois self.removed_rois[group_num] = removed_rois self.locked_rois[group_num] = locked_rois self.mask_points[group_num] = masks group_indices = [ i for i in range(len(self.video_paths)) if self.video_groups[i] == group_num ] group_lengths = [ self.video_lengths[i] for i in group_indices ] group_paths = [ self.video_paths[i] for i in group_indices ] index = group_paths.index(video_path) if group_num not in self.roi_temporal_footprints.keys(): self.roi_temporal_footprints[group_num] = [ np.zeros((self.roi_spatial_footprints[group_num][z].shape[1], np.sum(group_lengths))) for z in range(len(roi_spatial_footprints)) ] self.roi_temporal_residuals[group_num] = [ np.zeros((self.roi_spatial_footprints[group_num][z].shape[1], np.sum(group_lengths))) for z in range(len(roi_spatial_footprints)) ] self.bg_temporal_footprints[group_num] = [ np.zeros((self.bg_spatial_footprints[group_num][z].shape[1], np.sum(group_lengths))) for z in range(len(roi_spatial_footprints)) ] if index == 0: for z in range(len(roi_spatial_footprints)): self.roi_temporal_footprints[group_num][z][:, :group_lengths[0]] = roi_temporal_footprints[z] self.roi_temporal_residuals[group_num][z][:, :group_lengths[0]] = roi_temporal_residuals[z] self.bg_temporal_footprints[group_num][z][:, :group_lengths[0]] = bg_temporal_footprints[z] else: for z in range(len(roi_spatial_footprints)): self.roi_temporal_footprints[group_num][z][:, np.sum(group_lengths[:index]):np.sum(group_lengths[:index+1])] = roi_temporal_footprints[z] self.roi_temporal_residuals[group_num][z][:, np.sum(group_lengths[:index]):np.sum(group_lengths[:index+1])] = roi_temporal_residuals[z] self.bg_temporal_footprints[group_num][z][:, np.sum(group_lengths[:index]):np.sum(group_lengths[:index+1])] = bg_temporal_footprints[z] self.find_new_rois = False