# File with defaults for ease of use import re import typing as t from pathlib import PosixPath import h5py def exparams_from_meta( meta: t.Union[dict, PosixPath, str], extras: t.Collection[str] = ["ph"] ): """ Obtain parameters from metadata of hdf5 file. It compares a list of candidate channels using case-inspecific REGEX to identify valid channels. """ meta = meta if isinstance(meta, dict) else load_attributes(meta) base = { "tree": {"general": {"None": ["area", "volume", "eccentricity"]}}, "multichannel_ops": {}, } candidate_channels = { "Citrine", "GFP", "GFPFast", "mCherry", "pHluorin405", "pHluorin488", "Flavin", "Cy5", "mKO2", } default_reductions = {"max"} default_metrics = { "mean", "median", "std", "imBackground", "max5px", # "nuc_est_conv", } # Defined ratiometric combinations that can be used as ratio # key is numerator and value is denominator; add more to support additional channel names ratiometric_combinations = {"phluorin405": ("phluorin488", "gfpfast")} default_reduction_metrics = { r: default_metrics for r in default_reductions } # default_rm["None"] = ["nuc_conv_3d"] # Uncomment this to add nuc_conv_3d (slow) from aliby.tile.tiler import find_channel_name extant_fluorescence_ch = [] for av_channel in candidate_channels: # Find channels in metadata whose names match found_channel = find_channel_name(meta["channels"], av_channel) if found_channel is not None: extant_fluorescence_ch.append(found_channel) for ch in extant_fluorescence_ch: base["tree"][ch] = default_reduction_metrics base["sub_bg"] = extant_fluorescence_ch # Additional extraction defaults when channels available if "ph" in extras: # SWAINLAB-specific names # find first valid combination of ratiometric fluorescence channels numerator_channel, denominator_channel = (None, None) for ch1, chs2 in ratiometric_combinations.items(): found_channel1 = find_channel_name(extant_fluorescence_ch, ch1) if found_channel1 is not None: numerator_channel = found_channel1 for ch2 in chs2: found_channel2 = find_channel_name( extant_fluorescence_ch, ch2 ) if found_channel2: denominator_channel = found_channel2 break # If two compatible ratiometric channels are available if numerator_channel is not None and denominator_channel is not None: sets = { b + a: (x, y) for a, x in zip( ["", "_bgsub"], ( [numerator_channel, denominator_channel], [ f"{numerator_channel}_bgsub", f"{denominator_channel}_bgsub", ], ), ) for b, y in zip(["em_ratio", "gsum"], ["div0", "add"]) } for i, v in sets.items(): base["multichannel_ops"][i] = [ *v, default_reduction_metrics, ] return base def load_attributes(file: t.Union[str, PosixPath], group="/"): with h5py.File(file, "r") as f: meta = dict(f[group].attrs.items()) return meta