def test_parse_xml(self): expected_fovs = [ { 'run': 'run', 'folder': os.path.join('Point1', 'RowNumber0', 'Chemical_Image0'), 'dwell': 4.0, 'coordinates': (100, 200), 'point_name': 'Point', 'date': '2016-03-21T15:03:27', 'scans': 1, }, { 'run': 'run', 'folder': os.path.join('Point2', 'RowNumber0', 'Depth_Profile0'), 'dwell': 0.2, 'coordinates': (-100, -200), 'point_name': 'Custom', 'date': '2016-03-21T15:03:27', 'scans': 2, }, ] expected_calibration = { 'RasterStyle': None, 'TimeResolution': 0.5, 'MassGain': 1.0, 'MassOffset': 0.0, 'MassRange': 200.0, 'XSize': 2.0, 'YSize': 2.0 } fovs, calibration = runs.parse_xml(self.xml) self.assertEqual(fovs, expected_fovs) self.assertEqual(calibration, expected_calibration)
def create_mibitiffs(input_folder, run_path, point, panel_path, slide, size, run_label=None, instrument=None, tissue=None, aperture=None, out=None): """Combines single-channel TIFFs into a MIBItiff. The input TIFFs are not assumed to have any MIBI metadata. If they do, it is suggested to use the simpler :meth:`~merge_mibitiffs` instead. Args: input_folder: Path to a folder containing single-channel TIFFs. run_path: Path to a run xml. point: Point name of the image, e.g. Point1 or Point2. This should match the name of folder generated for the raw data as it is listed in the run xml file. panel_path: Path to a panel CSV. slide: The slide ID. size: The size of the FOV in microns, i.e. 500. run_label: Optional custom run label for the combined TIFF. If uploading the output to MIBItracker, the run label set here must match the label of the MIBItracker run. Defaults to the name of the run xml. instrument: Optionally, the instrument ID. tissue: Optionally, the name of tissue. aperture: Optionally, the name of the aperture or imaging preset. out: Optionally, a path to a location for saving the combined TIFF. If not specified, defaults to 'combined.tiff' inside the input folder. run_label: Optionally, a custom run label for the `run` property of the image. """ panel_df = panels.read_csv(panel_path) panel_name, _ = os.path.splitext(os.path.basename(panel_path)) tiff_files = os.listdir(input_folder) fovs, calibration = runs.parse_xml(run_path) point_number = int(point[5:]) try: fov = fovs[point_number - 1] # point number is 1-based, not 0-based except IndexError: raise IndexError('{} not found in run xml.'.format(point)) if fov['date']: run_date = datetime.datetime.strptime(fov['date'], '%Y-%m-%dT%H:%M:%S').date() else: run_date = datetime.datetime.now().date() image_data = [] for i in panel_df.index: tiff_path = os.path.join( input_folder, _match_target_filename(tiff_files, panel_df['Target'][i])) data = _load_single_channel(tiff_path) image_data.append(data) image_data = np.stack(image_data, axis=2) image = mi.MibiImage(image_data, list(zip(panel_df['Mass'], panel_df['Target']))) image.size = int(size) image.coordinates = (fov['coordinates']) image.filename = fov['run'] image.run = run_label if run_label else fov['run'] image.version = tiff.SOFTWARE_VERSION image.instrument = instrument image.slide = slide image.dwell = fov['dwell'] image.scans = fov['scans'] image.aperture = aperture image.point_name = fov['point_name'] image.folder = fov['folder'] image.tissue = tissue image.panel = panel_name image.date = run_date image.mass_offset = calibration['MassOffset'] image.mass_gain = calibration['MassGain'] image.time_resolution = calibration['TimeResolution'] if out is None: out = os.path.join(input_folder, 'combined.tiff') tiff.write(out, image, multichannel=True)