def _run_benchmark( resources_dir: Path, extensions: List[str], non_aics_reader: List[Callable], iterations: int = 3, ): # Collect files matching the extensions provided files = [] for ext in extensions: files += list(resources_dir.glob(ext)) files += list(Path("/Users/jamies/Data").glob(ext)) # Run reads for each file and store details in results aics_czi_reader = lambda file: (aics.CziFile(file).read_image(S=0)) results = [] for file in files: print(file) yx_planes = np.prod( aics.CziFile(file).size[:-2]) #info_read.size("STCZ")) for reader in [aics_czi_reader, non_aics_reader]: reader_path = f"{reader.__module__}.{reader.__name__}" for i in tqdm(range(iterations), desc=f"{reader_path}: {file.name}"): reader(str(file)) # warmup run start = time.perf_counter() reader(str(file)) results.append({ "file_name": file.name, "file_size_gb": file.stat().st_size / 10e8, "reader": ("other" if "czifile" in reader_path else "aics"), "yx_planes": int(yx_planes), "read_duration": time.perf_counter() - start, }) return results
def extract_aicspylibczi(self,max_projection=True): ''' Use aicspylibczi to extract images from czi file. Assumes time and series dimensions = 1. Params max_projection : bool : Make minimal projection of z_stack ''' if VERBOSE: print("Reading file: " + self.raw_path + "\t and extracting to folder: " + self.extracted_folder) czi = aicspylibczi.CziFile(pathlib.Path(self.raw_path)) dims = czi.dims_shape()[0] channels = list(range(dims['C'][1])) z_indexes = list(range(dims['Z'][1])) for c in channels: img_projection = None for z in z_indexes: img = czi.read_mosaic(C=c,Z=z,scale_factor=1) img = np.squeeze(img) if not max_projection: out_path = out_path.join(self.extracted_folder,self.file_id + "_INFO_0_0_"+str(z)+"_"+str(c)+self.file_ending) if VERBOSE: print("\tChannel: "+str(c)+"/"+str(max(channels))+"\tZ_index: "+str(z)+"/"+str(max(z))+"\tWriting: "+out_path) if not cv2.imwrite(out_path,img): raise ValueError("Could not save image to: "+out_path) else: if img_projection is None: img_projection = img else: img_projection = np.maximum(img_projection,img) if max_projection: out_path = os.path.join(self.extracted_folder,self.file_id + "_INFO_0_0_0_"+str(c)+self.file_ending) if VERBOSE: print("\tChannel: "+str(c)+"/"+str(max(channels))+"\tWriting: "+out_path) if not cv2.imwrite(out_path,img_projection): raise ValueError("Could not save image to: "+out_path) self.meta_xml_to_file(czi,os.path.join(self.extracted_folder,"meta_data.txt"),os.path.join(self.extracted_folder,"meta_data_all.txt")) img_paths = [] for path in os.listdir(self.extracted_folder): if path.endswith(".tiff"): img_paths.append(os.path.join(self.extracted_folder,path)) with open(self.extracted_images_info_file,'w') as f: for path in img_paths: f.write(path+"\n")
def writeMozaicImages(filePath="", channel_nr=None, z_stack_nr=None, czi_image=None, output_dir=""): # Checking if args were filledi n correctly if not filePath and czi_image is None: print( "No filepath or czi image was supplied, so the function cannot perform anything." ) return if filePath and czi_image is not None: print("Filepath and czi image cannot both be supplied as arguments.") return if filePath: czi = aicspylibczi.CziFile(filePath) if not czi.is_mosaic(): print("Given file is not a mosaic file.") return if z_stack_nr is not None and channel_nr is not None: mosaic_data = czi.read_mosaic(C=channel_nr, Z=z_stack_nr, scale_factor=1) else: if not czi_image.is_mosaic(): print("Given file is not a mosaic file.") return if z_stack_nr is not None and channel_nr is not None: channel_index = channel_nr - 1 z_stack_index = z_stack_nr - 1 mosaic_data = czi_image.read_mosaic(C=channel_index, Z=z_stack_index, scale_factor=1) mosaic_data = mosaic_data[0, 0, :, :].astype(np.uint16) img = Image.fromarray(mosaic_data) if not os.path.isdir(output_dir): os.makedirs(output_dir) output_filename = os.path.join( output_dir, f"channel{channel_nr}_z-stack{z_stack_nr}.tif") img.save(output_filename) print( f"Extracted channel {channel_nr}: z-stack {z_stack_nr} from original image to {output_filename}." ) elif channel_nr is not None: # Here we want maxIP of a certain channel channel_index = channel_nr - 1 # Indexing in czi api is 0 based, but user will be thinking in 1 based indexing. z_stack_min, z_stack_max = czi_image.dims_shape()[0][ 'Z'] #unpack the necessary image_list = [] for i in range(z_stack_min, z_stack_max): mosaic_data = czi_image.read_mosaic(C=channel_index, Z=i, scale_factor=1) mosaic_data = mosaic_data[0, 0, :, :].astype(np.uint16) image_list.append(mosaic_data) maxIP = maxIPstack(image_list) if not os.path.isdir(output_dir): os.makedirs(output_dir) output_filename = os.path.join(output_dir, f"channel_{channel_nr}_maxIP.tif") io.imsave(output_filename, maxIP, check_contrast=False) print( f"Wrote z-stack-maxIP of channel {channel_nr} to {output_filename}" )
image_list = [] for i in range(z_stack_min, z_stack_max): mosaic_data = czi_image.read_mosaic(C=channel_index, Z=i, scale_factor=1) mosaic_data = mosaic_data[0, 0, :, :].astype(np.uint16) image_list.append(mosaic_data) maxIP = maxIPstack(image_list) if not os.path.isdir(output_dir): os.makedirs(output_dir) output_filename = os.path.join(output_dir, f"channel_{channel_nr}_maxIP.tif") io.imsave(output_filename, maxIP, check_contrast=False) print( f"Wrote z-stack-maxIP of channel {channel_nr} to {output_filename}" ) for index, round_img in enumerate(mosaic_file_list): czi = aicspylibczi.CziFile(round_img) c_stack_min, c_stack_max = czi.dims_shape()[0]['C'] for i in range(c_stack_min + 1, c_stack_max + 1): # I want them named starting at 1, not at 0 writeMozaicImages( czi_image=czi, channel_nr=i, output_dir= f"/media/tool/gabriele_data/161230_161220_3_1/maxIP-seperate-channels/Round{index+1}/" )
def get_czi_planetable(czifile): # get the czi object using pylibczi czi = aicspylibczi.CziFile(czifile) # get the czi metadata md, add = imf.get_metadata(czifile) # initialize the plane table df_czi = define_czi_planetable() # define subblock counter sbcount = -1 # create progressbar # total = md['SizeS'] * md['SizeM'] * md['SizeT'] * md['SizeZ'] * md['SizeC'] # pbar = tqdm(total=total) # pbar = progressbar.ProgressBar(max_value=total) # in case the CZI has the M-Dimension if md['czi_isMosaic']: for s, m, t, z, c in product(range(md['SizeS']), range(md['SizeM']), range(md['SizeT']), range(md['SizeZ']), range(md['SizeC'])): sbcount += 1 # print(s, m, t, z, c) info = czi.read_subblock_rect(S=s, M=m, T=t, Z=z, C=c) # read information from subblock sb = czi.read_subblock_metadata(unified_xml=True, B=0, S=s, M=m, T=t, Z=z, C=c) try: time = sb.xpath('//AcquisitionTime')[0].text timestamp = dt.parse(time).timestamp() except IndexError as e: timestamp = 0.0 try: xpos = np.double(sb.xpath('//StageXPosition')[0].text) except IndexError as e: xpos = 0.0 try: ypos = np.double(sb.xpath('//StageYPosition')[0].text) except IndexError as e: ypos = 0.0 try: zpos = np.double(sb.xpath('//FocusPosition')[0].text) except IndexError as e: zpos = 0.0 df_czi = df_czi.append({'Subblock': sbcount, 'Scene': s, 'Tile': m, 'T': t, 'Z': z, 'C': c, 'X[micron]': xpos, 'Y[micron]': ypos, 'Z[micron]': zpos, 'Time[s]': timestamp, 'xstart': info[0], 'ystart': info[1], 'xwidth': info[2], 'ywidth': info[3]}, ignore_index=True) if not md['czi_isMosaic']: """ for s, t, z, c in it.product(range(md['SizeS']), range(md['SizeT']), range(md['SizeZ']), range(md['SizeC'])): """ for s, t, z, c in product(range(md['SizeS']), range(md['SizeT']), range(md['SizeZ']), range(md['SizeC'])): sbcount += 1 info = czi.read_subblock_rect(S=s, T=t, Z=z, C=c) # read information from subblocks sb = czi.read_subblock_metadata(unified_xml=True, B=0, S=s, T=t, Z=z, C=c) try: time = sb.xpath('//AcquisitionTime')[0].text timestamp = dt.parse(time).timestamp() except IndexError as e: timestamp = 0.0 try: xpos = np.double(sb.xpath('//StageXPosition')[0].text) except IndexError as e: xpos = 0.0 try: ypos = np.double(sb.xpath('//StageYPosition')[0].text) except IndexError as e: ypos = 0.0 try: zpos = np.double(sb.xpath('//FocusPosition')[0].text) except IndexError as e: zpos = 0.0 df_czi = df_czi.append({'Subblock': sbcount, 'Scene': s, 'Tile': 0, 'T': t, 'Z': z, 'C': c, 'X[micron]': xpos, 'Y[micron]': ypos, 'Z[micron]': zpos, 'Time[s]': timestamp, 'xstart': info[0], 'ystart': info[1], 'xwidth': info[2], 'ywidth': info[3]}, ignore_index=True) # normalize timestamps df_czi = imf.norm_columns(df_czi, colname='Time[s]', mode='min') # cast data types df_czi = df_czi.astype({'Subblock': 'int32', 'Scene': 'int32', 'Tile': 'int32', 'T': 'int32', 'Z': 'int32', 'C': 'int16', 'xstart': 'int32', 'xstart': 'int32', 'ystart': 'int32', 'xwidth': 'int32', 'ywidth': 'int32'}, copy=False, errors='ignore') return df_czi
maxIP = np.maximum.reduce(parsed_list) return maxIP def writeMozaicImages(czi_image, channel_nr, output_prefix=""): channel_index = channel_nr - 1 # Indexing in czi api is 0 based, but user will be thinking in 1 based indexing. z_stack_min, z_stack_max = czi_image.dims_shape()[0][ 'Z'] #unpack the necessary image_list = [] for i in range(z_stack_min, z_stack_max): mosaic_data = czi_image.read_mosaic(C=channel_index, Z=i, scale_factor=1) mosaic_data = mosaic_data[0, 0, :, :].astype(np.uint16) image_list.append(mosaic_data) maxIP = maxIPstack(image_list) output_filename = f"{ output_prefix }_c{channel_nr}.tif" io.imsave(output_filename, maxIP) filepath = sys.argv[1] prefix = os.path.splitext(filepath)[0] # if a third argument is inputted, it should be teh dir where the user want the files stored, otherwise the code will assume this is part of an entire workflow and just write to cwd. czi = aicspylibczi.CziFile(filepath) c_stack_min, c_stack_max = czi.dims_shape()[0]['C'] for i in range(c_stack_min + 1, c_stack_max + 1): # I want them named starting at 1, not at 0 writeMozaicImages(czi_image=czi, channel_nr=i, output_prefix=prefix)
output = r"W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Tests\export_test\quicknii_output" step = 3 prepare_stack_for_quicknii(path, output, step) #%% Trying to open multiscene mosaic CZI files def norm_by(x, min_, max_): norms = np.percentile(x, [min_, max_]) i2 = np.clip((x - norms[0]) / (norms[1] - norms[0]), 0, 1) return i2 path = r"W:\Neurophysiology-Storage1\Wahl\Hendrik\PhD\Data\Batch3\histology\Batch3_quant\images\M41_01.czi" czi = aicspylibczi.CziFile(path) mosaic_data = czi.read_mosaic(C=2, scale_factor=0.1) normed_mosaic_data = norm_by(mosaic_data[0, :, :], 5, 98) * 255 plt.imshow(normed_mosaic_data) czi.read_subblock_rect(S=1, M=100) #%% Open OME TIFF path = r"W:\Neurophysiology-Storage1\Wahl\Victor\M11_1.czi - Scene #0.ome.tif" # path = r"Z:\data\h.heiser\slidescanner_transfer_20210209_0901\M41_01_DAPI_8bit.ome.tiff" ome = tiff.imread(path) plt.imshow(ome[0]) #%% Try to read .flat file from QuickNII to get atlas identifier data