def save(self, tile_indices, output_dir, data, compress=6): region_index, tile_index, tx, ty = tile_indices img_label, stats = data # Save label volumes if present (use compression as these are often highly redundant) label_tile_path = None if img_label is not None: label_tile_path = cytokit_io.get_cytometry_image_path( region_index, tx, ty) cytokit_io.save_tile(osp.join(output_dir, label_tile_path), img_label, config=self.config, compress=compress) # Save statistics if present stats_path = None if stats is not None: # Append useful metadata to cytometry stats (align these names to those used in config.TileDims) # and export as csv stats.insert(0, 'tile_y', ty) stats.insert(0, 'tile_x', tx) stats.insert(0, 'tile_index', tile_index) stats.insert(0, 'region_index', region_index) stats_path = cytokit_io.get_cytometry_stats_path( region_index, tx, ty) cytokit_io.save_csv(osp.join(output_dir, stats_path), stats, index=False) return label_tile_path, stats_path
def aggregate_cytometry_statistics(output_dir, config, mode='all', export_csv=True, export_fcs=True, variant=None): from cytokit.function import data as function_data # Aggregate all cytometry csv data (across tiles) res = function_data.get_cytometry_data(output_dir, config, mode=mode) # Get file extension, possibly with user-defined "variant" name to be included in all # resulting file names def ext(file_ext): return file_ext if variant is None else '{}.{}'.format( variant, file_ext) # Export result as csv csv_path, fcs_path = None, None if export_csv: csv_path = osp.join(output_dir, cytokit_io.get_cytometry_agg_path(ext('csv'))) cytokit_io.save_csv(csv_path, res, index=False) logger.info( 'Saved cytometry aggregation results to csv at "{}"'.format( csv_path)) if export_fcs: import re import fcswrite nonalnum = '[^0-9a-zA-Z]+' fcs_path = osp.join(output_dir, cytokit_io.get_cytometry_agg_path(ext('fcs'))) if len(res) > 0: # For FCS exports, save only integer and floating point values and replace any non-alphanumeric # column name characters with underscores res_fcs = res.select_dtypes( ['int', 'float']).rename(columns=lambda c: re.sub(nonalnum, '_', c)) if not osp.exists(osp.dirname(fcs_path)): os.makedirs(osp.dirname(fcs_path), exist_ok=True) fcswrite.write_fcs(filename=fcs_path, chn_names=res_fcs.columns.tolist(), data=res_fcs.values) logger.info( 'Saved cytometry aggregation results to fcs at "{}"'.format( fcs_path)) else: # fcswrite fails on writing empty datasets so log a warning instead logger.warning( 'Skipping FCS export because no objects were detected') return csv_path, fcs_path