corems.encapsulation.factory.processingSetting

   1__author__ = "Yuri E. Corilo"
   2__date__ = "Jul 02, 2019"
   3
   4import dataclasses
   5import os
   6from typing import List, Dict
   7
   8from corems.encapsulation.constant import Atoms, Labels
   9
  10# Field metadata: omit from JSON/TOML parameter export (in-memory back-compat only).
  11LEGACY_PARAMETER = "legacy"
  12
  13
  14def legacy_field(default, **kwargs):
  15    """``dataclasses.field`` that marks a setting as legacy (not exported).
  16
  17    Use for in-memory / back-compat aliases that must not appear in
  18    parameter JSON/TOML when settings are dumped. Export paths should use
  19    :func:`settings_to_export_dict` (or equivalent) so this metadata is honored.
  20    """
  21    metadata = dict(kwargs.pop("metadata", {}) or {})
  22    metadata[LEGACY_PARAMETER] = True
  23    return dataclasses.field(default=default, metadata=metadata, **kwargs)
  24
  25
  26def settings_to_export_dict(settings_obj) -> dict:
  27    """Serialize settings for parameter export; skip fields marked legacy.
  28
  29    Fields defined with :func:`legacy_field` (metadata
  30    ``LEGACY_PARAMETER=True``) are omitted. Used by LCMS parameter dump so
  31    old annotation knobs on ``LiquidChromatographSetting`` are not rewritten
  32    into TOML/JSON after migration to ``spectral_similarity_search``.
  33    """
  34    if not dataclasses.is_dataclass(settings_obj) or isinstance(settings_obj, type):
  35        return dict(getattr(settings_obj, "__dict__", {}))
  36    out = {}
  37    for f in dataclasses.fields(settings_obj):
  38        if f.metadata.get(LEGACY_PARAMETER, False):
  39            continue
  40        out[f.name] = getattr(settings_obj, f.name)
  41    return out
  42
  43
  44def validate_used_atoms_keys(used_atoms):
  45    """Validate that usedAtoms keys are element symbols, not rare isotopes.
  46
  47    Molecular formula search treats each usedAtoms key as a monoisotopic
  48    (most-abundant) element. Heavy isotopologues (e.g. 13C, 54Fe, 37Cl) are
  49    produced later by isotopologue expansion of mono formulas, not by listing
  50    rare-isotope labels in usedAtoms. Membership in ``Atoms.isotopes`` does
  51    not mean the element is ready to search: each key still needs a valence
  52    in ``used_atom_valences`` (typically copied from ``Atoms.atoms_covalence``),
  53    or DBE calculation can fail.
  54
  55    Parameters
  56    ----------
  57    used_atoms : dict
  58        Mapping of atom symbol to (min, max) count range.
  59
  60    Raises
  61    ------
  62    ValueError
  63        If any key is not a mono element symbol (key of Atoms.isotopes).
  64    TypeError
  65        If used_atoms is not a mapping.
  66    """
  67    if used_atoms is None:
  68        return
  69    if not hasattr(used_atoms, "keys"):
  70        raise TypeError(
  71            "usedAtoms must be a dict of element symbols to (min, max) ranges"
  72        )
  73    invalid = [k for k in used_atoms.keys() if k not in Atoms.isotopes]
  74    if invalid:
  75        raise ValueError(
  76            "usedAtoms keys must be element symbols (e.g. Fe, C, Cl), "
  77            "not specific isotope labels (e.g. 54Fe, 13C, 37Cl). "
  78            f"Invalid key(s): {invalid}. "
  79            "Heavy isotopologues are generated from mono formulas during search."
  80        )
  81
  82
  83@dataclasses.dataclass
  84class TransientSetting:
  85    """Transient processing settings class
  86
  87    Attributes
  88    ----------
  89    implemented_apodization_function : tuple
  90        Available apodization functions
  91    apodization_method : str
  92        Apodization function to use. Hanning is a good default for Fourier transform magnitude mode.
  93        For absorption mode processing, Half-Sine or Half-Kaiser may be more appropriate.
  94    number_of_truncations : int
  95        How many times to truncate the transient prior to Fourier transform
  96    number_of_zero_fills : int
  97        How many times to zero fille the transient prior to Fourier transform.
  98    next_power_of_two : bool
  99        If True, zero fill to the next power of two after the new length of len(transient)+(number_of_zero_fills*len(transient)).
 100    kaiser_beta : float
 101        Beta parameter for Kaiser or Half-Kaiser apodisation function. 0 is rectangular,  5 is similar to Hamming,
 102        6 is similar to hanning, and 8.6 is similar to Blackman (from numpy docs)
 103
 104    """
 105
 106    implemented_apodization_function: tuple = (
 107        "Hamming",
 108        "Hanning",
 109        "Blackman",
 110        "Full-Sine",
 111        "Half-Sine",
 112        "Kaiser",
 113        "Half-Kaiser",
 114        "Rectangle",
 115    )
 116    apodization_method: str = "Hanning"
 117    number_of_truncations: int = 0
 118    number_of_zero_fills: int = 1
 119    next_power_of_two: bool = False
 120    kaiser_beta: float = 8.6
 121
 122    def __post_init__(self):
 123        # enforce datatype
 124        for field in dataclasses.fields(self):
 125            value = getattr(self, field.name)
 126            if not isinstance(value, field.type):
 127                value = field.type(value)
 128                setattr(self, field.name, value)
 129
 130
 131@dataclasses.dataclass
 132class DataInputSetting:
 133    """Data input settings class
 134
 135    Attributes
 136    ----------
 137    header_translate : dict
 138        Dictionary with the header labels to be translated to the corems labels. For example, {'m/z':'m/z', 'Resolving Power':'Resolving Power', 'Abundance':'Abundance' , 'S/N':'S/N'}
 139    """
 140
 141    # add to this dict the VALUES to match your labels, THE ORDER WON"T MATTER
 142    # "column_translate" : {"m/z":"m/z", "Resolving Power":"Resolving Power", "Abundance":"Abundance" , "S/N":"S/N"}
 143    header_translate: dict = dataclasses.field(default_factory=dict)
 144
 145    def __post_init__(self):
 146        self.header_translate = {
 147            "m/z": Labels.mz,
 148            "mOz": Labels.mz,
 149            "Mass": Labels.mz,
 150            "Resolving Power": Labels.rp,
 151            "Res.": Labels.rp,
 152            "resolution": Labels.rp,
 153            "Intensity": Labels.abundance,
 154            "Peak Height": Labels.abundance,
 155            "I": Labels.abundance,
 156            "Abundance": Labels.abundance,
 157            "abs_abu": Labels.abundance,
 158            "Signal/Noise": Labels.s2n,
 159            "S/N": Labels.s2n,
 160            "sn": Labels.s2n,
 161        }
 162
 163    def add_mz_label(self, label):
 164        """Add a label to the header_translate dictionary to be translated to the corems label for mz."""
 165        self.header_translate[label] = Labels.mz
 166
 167    def add_peak_height_label(self, label):
 168        """Add a label to the header_translate dictionary to be translated to the corems label for peak height."""
 169
 170        self.header_translate[label] = Labels.abundance
 171
 172    def add_sn_label(self, label):
 173        """Add a label to the header_translate dictionary to be translated to the corems label for signal to noise."""
 174        self.header_translate[label] = Labels.s2n
 175
 176    def add_resolving_power_label(self, label):
 177        """Add a label to the header_translate dictionary to be translated to the corems label for resolving power."""
 178        self.header_translate[label] = Labels.rp
 179
 180
 181@dataclasses.dataclass
 182class LiquidChromatographSetting:
 183    """Liquid chromatograph processing settings class
 184
 185    Attributes
 186    ----------
 187    scans : list or tuple, optional
 188        List of select scan to average or a tuple containing the range to average.
 189        Default is (-1, -1).
 190    eic_tolerance_ppm : float, optional
 191        Mass tolerance in ppm for extracted ion chromatogram peak detection.
 192        Default is 5.
 193    correct_eic_baseline : bool, optional
 194        If True, correct the baseline of the extracted ion chromatogram.
 195        Default is True.
 196    smooth_window : int, optional
 197        Window size for smoothing the ion chromatogram (extracted or total).
 198        Default is 5.
 199    smooth_method : str, optional
 200        Smoothing method to use. See implemented_smooth_method for options.
 201        Default is 'savgol'.
 202    implemented_smooth_method : tuple, optional
 203        Smoothing methods that can be implemented.
 204        Default is ('savgol', 'hanning', 'blackman', 'bartlett', 'flat', 'boxcar').
 205    savgol_pol_order : int, optional
 206        Polynomial order for Savitzky-Golay smoothing.
 207        Default is 2.
 208    consecutive_scan_min : int, optional
 209        Minimum number of consecutive scans to consider for peak detection.
 210        Default is 0 for backwards compatibility, but a value of 3 is recommended.
 211    peak_height_max_percent : float, optional
 212        1-100 % used for baseline detection use 0.1 for second_derivative and 10 for other methods.
 213        Default is 10.
 214    peak_max_prominence_percent : float, optional
 215        1-100 % used for baseline detection.
 216        Default is 1.
 217    peak_derivative_threshold : float, optional
 218        Threshold for defining derivative crossing.
 219        Default is 0.0005.
 220    min_peak_datapoints : float, optional
 221        minimum data point to define a chromatografic peak.
 222        Default is 5.
 223    noise_threshold_method : str, optional
 224        Method for detecting noise threshold.
 225        Default is 'manual_relative_abundance'.
 226    noise_threshold_methods_implemented : tuple, optional
 227        Methods for detected noise threshold that can be implemented.
 228        Default is ('auto_relative_abundance', 'manual_relative_abundance', 'second_derivative').
 229    peak_height_min_percent : float, optional
 230        0-100 % used for peak detection.
 231        Default is 0.1.
 232    eic_signal_threshold : float, optional
 233        0-100 % used for extracted ion chromatogram peak detection.
 234        Default is 0.01.
 235    eic_buffer_time : float, optional
 236        Buffer time to add to the start and end of the plot of the extracted ion chromatogram, in minutes.
 237        Default is 1.5.
 238    dispersity_index_window : float, optional
 239        Dispersity index window size, in minutes.
 240        Default is 3.0.
 241    noise_window_factor : float, optional
 242        Factor to determine noise estimation window size relative to peak width.
 243        Larger values use wider windows for noise estimation.
 244        For example, a value of 2.0 uses a window size equal to twice the peak width
 245        (depending on it's start and end scans) on each side.
 246        Called within the LCMSMassFeature.calc_noise_score() method.
 247        Default is 2.0.
 248    remove_redundant_mass_features : bool, optional
 249        If True, remove redundant mass features that are likely contaminants based on
 250        their m/z values and scan frequency.
 251        Especially useful for HILIC data where signals do not return to baseline between peaks
 252        or for data with significant background noise.
 253        Called within the LC_Calculations.find_mass_features() method.
 254        Default is False.
 255    redundant_scan_frequency_min : float, optional
 256        Minimum fraction of scans that must contain the m/z to be considered a likely
 257        noise/contaminant when using remove_redundant_mass_features.
 258        Default is 0.1 (10% of scans).
 259    redundant_feature_retain_n : int, optional
 260        Number of features to retain in each group when using remove_redundant_mass_features.
 261        Default is 3.
 262    remove_mass_features_by_peak_metrics : bool, optional
 263        If True, remove mass features based on their peak metrics such as S/N, Gaussian similarity,
 264        dispersity index, and noise score.
 265        Called within the LC_Calculations.add_peak_metrics() method.
 266        Default is False.
 267    mass_feature_attribute_filter_dict : dict, optional
 268        Dictionary specifying filtering criteria for mass feature attributes.
 269        Each key is an attribute name, and each value is a dict with 'value' and 'operator' keys.
 270
 271        Structure: {attribute_name: {'value': threshold, 'operator': comparison}}
 272
 273        Available operators:
 274        - '>' or 'greater': Keep features where attribute > threshold
 275        - '<' or 'less': Keep features where attribute < threshold
 276        - '>=' or 'greater_equal': Keep features where attribute >= threshold
 277        - '<=' or 'less_equal': Keep features where attribute <= threshold
 278
 279        Examples:
 280        {
 281            'noise_score_max': {'value': 0.5, 'operator': '>'},  # Keep if noise_score_max > 0.5
 282            'dispersity_index': {'value': 0.1, 'operator': '<'},  # Keep if dispersity_index < 0.1
 283            'gaussian_similarity': {'value': 0.7, 'operator': '>='}  # Keep if gaussian_similarity >= 0.7
 284        }
 285
 286        Available attributes include: 'noise_score', 'noise_score_min', 'noise_score_max',
 287        'gaussian_similarity', 'tailing_factor', 'dispersity_index', 'half_height_width', 'intensity'.
 288        Default is {"noise_score_max": {"value": 0.8, "operator": ">="},"noise_score_min": {"value": 0.5, "operator": ">="}},
 289    peak_picking_method : str, optional
 290        Peak picking method to use. See implemented_peak_picking_methods for options.
 291        Default is 'by_format', which selects persistent homology when all scans
 292        at the requested MS level are profile and centroided persistent
 293        homology when all are centroid, then stores the concrete method on
 294        this setting so saved parameters record what was used.
 295    implemented_peak_picking_methods : tuple, optional
 296        Peak picking methods that can be implemented.
 297        Default is ('by_format', 'persistent homology', 'centroided_persistent_homology').
 298    ph_smooth_it : int, optional
 299        Number of iterations to use for smoothing prior to finding mass features.
 300        Used only for "persistent homology" peak picking method.
 301        Called within the PHCalculations.find_mass_features_ph() method.
 302        Default is 1.
 303    ph_smooth_radius_mz : int, optional
 304        Radius in m/z steps (not daltons) for smoothing prior to finding mass features.
 305        Used only for "persistent homology" peak picking method.
 306        Called within the PHCalculations.find_mass_features_ph() method.
 307        Default is 0.
 308    ph_smooth_radius_scan : int, optional
 309        Radius in scan steps for smoothing prior to finding mass features.
 310        Used only for "persistent homology" peak picking method.
 311        Called within the PHCalculations.find_mass_features_ph() method.
 312        Default is 1.
 313    ph_inten_min_rel : float, optional
 314        Relative minimum intensity to use for finding mass features for persistent homology.
 315        Used only for "persistent homology" peak picking method.
 316        Calculated as a fraction of the maximum intensity of the unprocessed profile data (mz, scan).
 317        Called within the PH_Calculations.find_mass_features() method.
 318        Default is 0.001.
 319    ph_persis_min_rel : float, optional
 320        Relative minimum persistence for retaining mass features.
 321        Used for both "persistent homology" and "centroided_persistent_homology" peak picking methods.
 322        Calculated as a fraction of the maximum intensity of the unprocessed profile data (mz, scan).
 323        Should be greater to or equal to ph_inten_min_rel.
 324        Called within the PH_Calculations.find_mass_features() method.
 325        Default is 0.001.
 326    ph_inten_min_abs : float, optional
 327        Absolute minimum intensity for points that enter persistent homology.
 328        Applied with ph_inten_min_rel on profile and centroided data.
 329        The relative floor is still a fraction of the unfiltered maximum.
 330        0 disables the absolute floor. Default is 0.0.
 331    mass_feature_cluster_mz_tolerance_rel : float, optional
 332        Relative m/z tolerance to use for clustering mass features.
 333        Used for both "persistent homology" and "centroided_persistent_homology"
 334        peak picking methods.
 335        Called with the PHCalculations.cluster_mass_features() and the
 336        LCCalculations.deconvolute_ms1_mass_features() methods.
 337        Default is 5e-6 (5 ppm).
 338    mass_feature_cluster_rt_tolerance : float, optional
 339        Retention time tolerance to use for clustering mass features, in minutes.
 340        Used for both "persistent homology" and "centroided_persistent_homology"
 341        peak picking methods.
 342        Called with the PHCalculations.cluster_mass_features() and the
 343        LCCalculations.deconvolute_ms1_mass_features() methods.
 344        Default is 0.3.
 345    ms1_scans_to_average : int, optional
 346        Number of MS1 scans to average for mass-feature associated m/zs.
 347        Called within the LCMSBase.add_associated_ms1() method.
 348        Default is 1.
 349    ms1_deconvolution_corr_min : float, optional
 350        Minimum correlation to use for deconvoluting MS1 mass features.
 351        Called within the LCCalculations.deconvolute_ms1_mass_features() method.
 352        Default is 0.8.
 353    ms2_dda_rt_tolerance : float, optional
 354        Retention time tolerance to use for associating MS2 spectra to mass features, in minutes.
 355        Called within the LCMSBase.add_associated_ms2_dda() method.
 356        Default is 0.15.
 357    ms2_dda_mz_tolerance : float, optional
 358        Mass tolerance to use for associating MS2 spectra to mass features.
 359        Called within the LCMSBase.add_associated_ms2_dda() method.
 360        Default is 0.05.
 361    ms2_min_fe_score : float, optional
 362        Minimum flash entropy for retaining MS2 annotations.
 363        Legacy; prefer ``mass_spectrum["ms2"].spectral_similarity_search.ms2_min_fe_score``.
 364        Default is 0.2.
 365    search_as_lipids : bool, optional
 366        Legacy lipid-search flag; prefer ``mass_spectrum["ms2"].spectral_similarity_search``.
 367        Default is False.
 368    include_fragment_types : bool, optional
 369        Legacy fragment-type flag; prefer ``mass_spectrum["ms2"].spectral_similarity_search``.
 370        Default is False.
 371    export_profile_spectra : bool, optional
 372        If True, export profile spectra data.
 373        Default is False.
 374    export_eics : bool, optional
 375        If True, export extracted ion chromatograms.
 376        Default is True.
 377    export_unprocessed_ms1 : bool, optional
 378        If True, export unprocessed MS1 data.
 379        Default is False.
 380    export_only_relevant_mass_spectra : bool, optional
 381        If True, export only mass spectra associated with detected mass features:
 382        specifically the apex MS1 scan for each mass feature and the best MS2 scan
 383        for each mass feature (if available). If False, export all mass spectra.
 384        This parameter reduces HDF5 file size by excluding non-feature spectra.
 385        Default is False (backwards compatible - exports all spectra).
 386    verbose_processing : bool, optional
 387        If True, print verbose processing information.
 388        Default is True.
 389    """
 390
 391    scans: list | tuple = (-1, -1)
 392
 393    # Parameters used for generating EICs and performing 1D peak picking and EIC/TIC smoothing
 394    eic_tolerance_ppm: float = 5
 395    correct_eic_baseline = True
 396    smooth_window: int = 5
 397    smooth_method: str = "savgol"
 398    implemented_smooth_method: tuple = (
 399        "savgol",
 400        "hanning",
 401        "blackman",
 402        "bartlett",
 403        "flat",
 404        "boxcar",
 405    )
 406    savgol_pol_order: int = 2
 407    consecutive_scan_min: int = 0
 408    peak_height_max_percent: float = 10
 409    peak_max_prominence_percent: float = 1
 410    peak_derivative_threshold: float = 0.0005
 411    min_peak_datapoints: float = 5
 412    noise_threshold_method: str = "manual_relative_abundance"
 413    noise_threshold_methods_implemented: tuple = (
 414        "auto_relative_abundance",
 415        "manual_relative_abundance",
 416        "second_derivative",
 417    )
 418    peak_height_min_percent: float = 0.1
 419    eic_signal_threshold: float = 0.01
 420    eic_buffer_time = 1.5
 421    dispersity_index_window: float = 3.0  # minutes
 422    noise_window_factor: float = 2.0  # times the peak width for detemining SN for EIC
 423
 424    # Parameters used for filtering mass features after peak picking
 425    remove_redundant_mass_features: bool = False
 426    redundant_scan_frequency_min: float = 0.1
 427    redundant_feature_retain_n: int = 3
 428    remove_mass_features_by_peak_metrics: bool = False
 429    # note that this is a dictionary of dictionaries and set in __post_init__ instead of here
 430    mass_feature_attribute_filter_dict: Dict = dataclasses.field(default_factory=dict)
 431
 432    # Parameters used for 2D peak picking
 433    peak_picking_method: str = "by_format"
 434    implemented_peak_picking_methods: tuple = (
 435        "by_format",
 436        "persistent homology",
 437        "centroided_persistent_homology",
 438    )
 439
 440    # Parameters used in persistent homology calculations
 441    ph_smooth_it = 1
 442    ph_smooth_radius_mz = 0
 443    ph_smooth_radius_scan = 1
 444    ph_inten_min_rel = 0.001
 445    ph_persis_min_rel = 0.001
 446    ph_inten_min_abs: float = 0.0
 447
 448    # Parameters used to cluster mass features
 449    mass_feature_cluster_mz_tolerance_rel: float = 5e-6
 450    mass_feature_cluster_rt_tolerance: float = 0.3
 451
 452    # Parameters used in associating MS1 and MS2 spectra to LCMS mass features and deconvoluting MS1 mass features
 453    ms1_scans_to_average: int = 1
 454    ms1_deconvolution_corr_min: float = 0.8
 455    ms2_dda_rt_tolerance: float = 0.15
 456    ms2_dda_mz_tolerance: float = 0.05
 457
 458    # Legacy MS2 spectral annotation aliases (not exported; prefer MSParameters.spectral_similarity_search)
 459    ms2_min_fe_score: float = legacy_field(0.2)
 460    search_as_lipids: bool = legacy_field(False)
 461    include_fragment_types: bool = legacy_field(False)
 462
 463    # Parameters used for saving the data
 464    export_profile_spectra: bool = False
 465    export_eics: bool = True
 466    export_unprocessed_ms1: bool = False
 467    export_only_relevant_mass_spectra: bool = False
 468
 469    # Parameters used for verbose processing
 470    verbose_processing: bool = True
 471
 472    def __post_init__(self):
 473        # Set default values for mass_feature_attribute_filter_dict if empty
 474        if not self.mass_feature_attribute_filter_dict:
 475            self.mass_feature_attribute_filter_dict = {
 476                "noise_score_max": {"value": 0.8, "operator": ">="},
 477                "noise_score_min": {"value": 0.5, "operator": ">="},
 478            }
 479
 480        # enforce datatype
 481        for field in dataclasses.fields(self):
 482            value = getattr(self, field.name)
 483            if not isinstance(value, field.type):
 484                value = field.type(value)
 485                setattr(self, field.name, value)
 486
 487
 488@dataclasses.dataclass
 489class SpectralSimilaritySearchSettings:
 490    """Parameters for using spectral similarity to search spectra against a library of reference spectra (including within molecular networking).
 491
 492    Lives on :class:`~corems.encapsulation.factory.parameters.MSParameters`
 493    as ``spectral_similarity_search`` (e.g. ``lcms.parameters.mass_spectrum["ms2"].spectral_similarity_search``).
 494
 495    Not used for MS2 *molecular formula* search
 496    (``mass_spectrum[key].molecular_search``).
 497    """
 498
 499    # --- FlashEntropy library build (intensity normalize always on) ---
 500    max_ms2_tolerance_in_da: float = 0.01
 501    max_indexed_mz: float = 3000.0
 502    precursor_ions_removal_da: float | None = None
 503    noise_threshold: float = 0.0
 504
 505    # --- Annotation ---
 506    ms2_min_fe_score: float = 0.2
 507    include_fragment_types: bool = False
 508    search_as_lipids: bool = False
 509    peak_sep_da: float | None = None
 510
 511    # --- Molecular networking ---
 512    search_type: str = "open"
 513    additional_similarities: list = dataclasses.field(
 514        default_factory=lambda: ["cosine"]
 515    )
 516    similarity_thresholds: dict = dataclasses.field(default_factory=dict)
 517    ms1_tolerance_da: float | None = None
 518    ms2_tolerance_da: float | None = None
 519    entropy_threshold_low: float | None = None
 520    library_similarity_threshold: float = 0.3
 521    hydrate_library_similarities: bool = False
 522
 523    def __post_init__(self):
 524        if self.additional_similarities is not None:
 525            self.additional_similarities = list(self.additional_similarities)
 526        if self.similarity_thresholds is not None:
 527            self.similarity_thresholds = dict(self.similarity_thresholds)
 528
 529    @property
 530    def min_ms2_difference_in_da(self) -> float:
 531        """Minimum peak separation (Da); always ``2 * max_ms2_tolerance_in_da``."""
 532        return 2.0 * float(self.max_ms2_tolerance_in_da)
 533
 534    def copy(self) -> "SpectralSimilaritySearchSettings":
 535        """Return a copy with mutable list/dict fields isolated."""
 536        return dataclasses.replace(
 537            self,
 538            additional_similarities=list(self.additional_similarities),
 539            similarity_thresholds=dict(self.similarity_thresholds),
 540        )
 541
 542    def as_fe_kwargs(self) -> dict:
 543        """FlashEntropy library-build kwargs (historical ``fe_kwargs`` shape)."""
 544        return {
 545            "min_ms2_difference_in_da": self.min_ms2_difference_in_da,
 546            "max_ms2_tolerance_in_da": self.max_ms2_tolerance_in_da,
 547            "max_indexed_mz": self.max_indexed_mz,
 548            "precursor_ions_removal_da": self.precursor_ions_removal_da,
 549            "noise_threshold": self.noise_threshold,
 550        }
 551
 552    @property
 553    def resolved_peak_sep_da(self) -> float:
 554        """Peak separation (Da) for annotation search."""
 555        if self.peak_sep_da is not None:
 556            return float(self.peak_sep_da)
 557        return float(self.min_ms2_difference_in_da)
 558
 559
 560@dataclasses.dataclass
 561class MassSpectrumSetting:
 562    """Mass spectrum processing settings class
 563
 564    Attributes
 565    ----------
 566    noise_threshold_method : str, optional
 567        Method for detecting noise threshold. Default is 'by_format', which
 568        selects 'log' for a profile spectrum and 'relative_abundance' for
 569        a centroid spectrum, then stores that concrete method on this
 570        setting so saved parameters record what was used.
 571    noise_threshold_methods_implemented : tuple, optional
 572        Methods for detected noise threshold that can be implemented. Default is ('by_format', 'minima', 'signal_noise', 'relative_abundance', 'absolute_abundance', 'log').
 573    noise_threshold_min_std : int, optional
 574        Minumum value for noise thresholding when using 'minima' noise threshold method. Default is 6.
 575    noise_threshold_min_s2n : float, optional
 576        Minimum value for noise thresholding when using 'signal_noise' noise threshold method. Default is 4.
 577    noise_threshold_min_relative_abundance : float, optional
 578        Minimum value for noise thresholding when using 'relative_abundance' noise threshold method. Note that this is a percentage value. Default is 6 (6%).
 579    noise_threshold_absolute_abundance : float, optional
 580        Minimum value for noise thresholding when using 'absolute_abundance' noise threshold method. Default is 1_000_000.
 581    noise_threshold_log_nsigma : int, optional
 582        Number of standard deviations to use when using 'log' noise threshold method. Default is 6.
 583    noise_threshold_log_nsigma_corr_factor : float, optional
 584        Correction factor for log noise threshold method. Default is 0.463.
 585    noise_threshold_log_nsigma_bins : int, optional
 586        Number of bins to use for histogram when using 'log' noise threshold method. Default is 500.
 587    noise_min_mz : float, optional
 588        Minimum m/z to use for noise thresholding. Default is 50.0.
 589    noise_max_mz : float, optional
 590        Maximum m/z to use for noise thresholding. Default is 1200.0.
 591    min_picking_mz : float, optional
 592        Minimum m/z to use for peak picking. Default is 50.0.
 593    max_picking_mz : float, optional
 594        Maximum m/z to use for peak picking. Default is 1200.0.
 595    picking_point_extrapolate : int, optional
 596        How many data points (in each direction) to extrapolate the mz axis and 0 pad the abundance axis. Default is 3.
 597        Recommend not changing this value unless necessary.
 598    calib_minimize_method : str, optional
 599        Minimization method to use for calibration. Default is 'Powell'.
 600    calib_pol_order : int, optional
 601        Polynomial order to use for calibration. Default is 2.
 602    max_calib_ppm_error : float, optional
 603        Maximum ppm error to use for calibration. Default is 1.0.
 604    min_calib_ppm_error : float, optional
 605        Minimum ppm error to use for calibration. Default is -1.0.
 606    calib_sn_threshold : float, optional
 607        Signal to noise threshold to use for calibration. Default is 2.0.
 608    calibration_ref_match_method: string, optional
 609        Method for matching reference masses with measured masses for recalibration. Default is 'legacy'.
 610    calibration_ref_match_tolerance: float, optional
 611        If using the new method for calibration reference mass matching, this tolerance is the initial matching tolerance. Default is 0.003
 612    do_calibration : bool, optional
 613        If True, perform calibration. Default is True.
 614    verbose_processing : bool, optional
 615        If True, print verbose processing information. Default is True.
 616    """
 617
 618    noise_threshold_method: str = "by_format"
 619
 620    noise_threshold_methods_implemented: tuple = (
 621        "by_format",
 622        "minima",
 623        "signal_noise",
 624        "relative_abundance",
 625        "absolute_abundance",
 626        "log",
 627    )
 628
 629    noise_threshold_min_std: int = 6  # when using 'minima' method
 630
 631    noise_threshold_min_s2n: float = 4  # when using 'signal_noise' method
 632
 633    noise_threshold_min_relative_abundance: float = (
 634        6  # from 0-100, when using 'relative_abundance' method
 635    )
 636
 637    noise_threshold_absolute_abundance: float = (
 638        1_000_000  # when using 'absolute_abundance' method
 639    )
 640
 641    noise_threshold_log_nsigma: int = 6  # when using 'log' method
 642    noise_threshold_log_nsigma_corr_factor: float = 0.463  # mFT is 0.463, aFT is 1.0
 643    noise_threshold_log_nsigma_bins: int = 500  # bins for the histogram for the noise
 644
 645    noise_min_mz: float = 50.0
 646    noise_max_mz: float = 1200.0
 647
 648    min_picking_mz: float = 50.0
 649    max_picking_mz: float = 1200.0
 650
 651    # How many data points (in each direction) to extrapolate the mz axis and 0 pad the abundance axis
 652    # This will fix peak picking at spectrum limit issues
 653    #  0 to keep normal behaviour, typical value 3 to fix
 654    picking_point_extrapolate: int = 3
 655
 656    calib_minimize_method: str = "Powell"
 657    calib_pol_order: int = 2
 658    max_calib_ppm_error: float = 1.0
 659    min_calib_ppm_error: float = -1.0
 660    calib_sn_threshold: float = 2.0
 661    calibration_ref_match_method: str = "merged"
 662    calibration_ref_match_method_implemented: tuple = ("legacy", "merged")
 663    calibration_ref_match_tolerance: float = 0.003
 664    calibration_ref_match_std_raw_error_limit: float = 1.5
 665    # calib_ref_mzs: list = [0]
 666
 667    do_calibration: bool = True
 668    verbose_processing: bool = True
 669
 670    def __post_init__(self):
 671        # enforce datatype
 672        for field in dataclasses.fields(self):
 673            value = getattr(self, field.name)
 674            if not isinstance(value, field.type):
 675                value = field.type(value)
 676                setattr(self, field.name, value)
 677
 678
 679@dataclasses.dataclass
 680class MassSpecPeakSetting:
 681    """Mass spectrum peak processing settings class
 682
 683    Attributes
 684    ----------
 685    kendrick_base : Dict, optional
 686        Dictionary specifying the elements and their counts in the Kendrick base.
 687        Defaults to {'C': 1, 'H': 2}.
 688    kendrick_rounding_method : str, optional
 689        Method for calculating the nominal Kendrick mass. Valid values are 'floor', 'ceil', or 'round'.
 690        Defaults to 'floor'.
 691    implemented_kendrick_rounding_methods : tuple
 692        Tuple of valid rounding methods for calculating the nominal Kendrick mass.
 693        Defaults to ('floor', 'ceil', 'round').
 694    peak_derivative_threshold : float, optional
 695        Threshold for defining derivative crossing. Should be a value between 0 and 1.
 696        Defaults to 0.0.
 697    peak_min_prominence_percent : float, optional
 698        Minimum prominence percentage used for peak detection. Should be a value between 1 and 100.
 699        Defaults to 0.1.
 700    min_peak_datapoints : float, optional
 701        Minimum number of data points used for peak detection. Should be a value between 0 and infinity.
 702        Defaults to 5.
 703    peak_max_prominence_percent : float, optional
 704        Maximum prominence percentage used for baseline detection. Should be a value between 1 and 100.
 705        Defaults to 0.1.
 706    peak_height_max_percent : float, optional
 707        Maximum height percentage used for baseline detection. Should be a value between 1 and 100.
 708        Defaults to 10.
 709    legacy_resolving_power : bool, optional
 710        Flag indicating whether to use the legacy (CoreMS v1) resolving power calculation.
 711        Defaults to True.
 712    legacy_centroid_polyfit : bool, optional
 713        Use legacy (numpy polyfit) to fit centroid
 714        Default false.
 715    """
 716
 717    kendrick_base: Dict = dataclasses.field(default_factory=dict)
 718
 719    kendrick_rounding_method: str = "floor"  # 'floor', 'ceil' or 'round' are valid methods for calculating nominal kendrick mass
 720
 721    implemented_kendrick_rounding_methods: tuple = ("floor", "ceil", "round")
 722
 723    peak_derivative_threshold: float = 0.0  # define derivative crossing threshould 0-1
 724
 725    peak_min_prominence_percent: float = 0.1  # 1-100 % used for peak detection
 726
 727    min_peak_datapoints: float = 5  # 0-inf used for peak detection
 728
 729    peak_max_prominence_percent: float = 0.1  # 1-100 % used for baseline detection
 730
 731    peak_height_max_percent: float = 10  # 1-100 % used for baseline detection
 732
 733    legacy_resolving_power: bool = (
 734        True  # Use the legacy (CoreMS v1) resolving power calculation (True)
 735    )
 736
 737    legacy_centroid_polyfit: bool = False
 738
 739    def __post_init__(self):
 740        # default to CH2
 741        if not self.kendrick_base:
 742            self.kendrick_base = {"C": 1, "H": 2}
 743        # enforce datatype
 744        for field in dataclasses.fields(self):
 745            value = getattr(self, field.name)
 746            if not isinstance(value, field.type):
 747                value = field.type(value)
 748                setattr(self, field.name, value)
 749
 750
 751@dataclasses.dataclass
 752class GasChromatographSetting:
 753    """Gas chromatograph processing settings class
 754
 755    Attributes
 756    ----------
 757    use_deconvolution : bool, optional
 758        If True, use deconvolution. Default is False.
 759    implemented_smooth_method : tuple, optional
 760        Smoothing methods that can be implemented. Default is ('savgol', 'hanning', 'blackman', 'bartlett', 'flat', 'boxcar').
 761    smooth_window : int, optional
 762        Window size for smoothing the ion chromatogram. Default is 5.
 763    smooth_method : str, optional
 764        Smoothing method to use. Default is 'savgol'. Other options are 'hanning', 'blackman', 'bartlett', 'flat', 'boxcar'.
 765    savgol_pol_order : int, optional
 766        Polynomial order for Savitzky-Golay smoothing. Default is 2.
 767    peak_derivative_threshold : float, optional
 768        Threshold for defining derivative crossing. Should be a value between 0 and 1.
 769        Defaults to 0.0005.
 770    peak_height_max_percent : float, optional
 771        Maximum height percentage used for baseline detection. Should be a value between 1 and 100.
 772        Defaults to 10.
 773    peak_max_prominence_percent : float, optional
 774        Maximum prominence percentage used for baseline detection. Should be a value between 1 and 100.
 775        Defaults to 1.
 776    min_peak_datapoints : float, optional
 777        Minimum number of data points used for peak detection. Should be a value between 0 and infinity.
 778        Defaults to 5.
 779    max_peak_width : float, optional
 780        Maximum peak width used for peak detection. Should be a value between 0 and infinity.
 781        Defaults to 0.1.
 782    noise_threshold_method : str, optional
 783        Method for detecting noise threshold. Default is 'manual_relative_abundance'.
 784    noise_threshold_methods_implemented : tuple, optional
 785        Methods for detected noise threshold that can be implemented. Default is ('auto_relative_abundance', 'manual_relative_abundance', 'second_derivative').
 786    std_noise_threshold : int, optional
 787        Default is 3.
 788    peak_height_min_percent : float, optional
 789        0-100 % used for peak detection. Default is 0.1.
 790    peak_min_prominence_percent : float, optional
 791        0-100 % used for peak detection. Default is 0.1.
 792    eic_signal_threshold : float, optional
 793        0-100 % used for extracted ion chromatogram peak detection. Default is 0.01.
 794    max_rt_distance : float, optional
 795        Maximum distance allowance for hierarchical cluster, in minutes. Default is 0.025.
 796    verbose_processing : bool, optional
 797        If True, print verbose processing information. Default is True.
 798    """
 799
 800    use_deconvolution: bool = False
 801
 802    implemented_smooth_method: tuple = (
 803        "savgol",
 804        "hanning",
 805        "blackman",
 806        "bartlett",
 807        "flat",
 808        "boxcar",
 809    )
 810
 811    smooth_window: int = 5
 812
 813    smooth_method: str = "savgol"
 814
 815    savgol_pol_order: int = 2
 816
 817    peak_derivative_threshold: float = 0.0005
 818
 819    peak_height_max_percent: float = 10  # 1-100 % used for baseline detection use 0.1 for second_derivative and 10 for other methods
 820
 821    peak_max_prominence_percent: float = 1  # 1-100 % used for baseline detection
 822
 823    min_peak_datapoints: float = 5
 824
 825    max_peak_width: float = 0.1
 826
 827    noise_threshold_method: str = "manual_relative_abundance"
 828
 829    noise_threshold_methods_implemented: tuple = (
 830        "auto_relative_abundance",
 831        "manual_relative_abundance",
 832        "second_derivative",
 833    )
 834
 835    std_noise_threshold: int = 3
 836
 837    peak_height_min_percent: float = 0.1  # 0-100 % used for peak detection
 838
 839    peak_min_prominence_percent: float = 0.1  # 0-100 % used for peak detection
 840
 841    eic_signal_threshold: float = (
 842        0.01  # 0-100 % used for extracted ion chromatogram peak detection
 843    )
 844
 845    max_rt_distance: float = (
 846        0.025  # minutes, max distance allowance hierarchical clutter
 847    )
 848
 849    verbose_processing: bool = True
 850
 851    def __post_init__(self):
 852        # enforce datatype
 853        for field in dataclasses.fields(self):
 854            value = getattr(self, field.name)
 855            if not isinstance(value, field.type):
 856                value = field.type(value)
 857                setattr(self, field.name, value)
 858
 859
 860@dataclasses.dataclass
 861class CompoundSearchSettings:
 862    """Settings for compound search
 863
 864    Attributes
 865    ----------
 866    url_database : str, optional
 867        URL for the database. Default is 'sqlite:///db/pnnl_lowres_gcms_compounds.sqlite'.
 868    ri_search_range : float, optional
 869        Retention index search range. Default is 35.
 870    rt_search_range : float, optional
 871        Retention time search range, in minutes. Default is 1.0.
 872    correlation_threshold : float, optional
 873        Threshold for correlation for spectral similarity. Default is 0.5.
 874    score_threshold : float, optional
 875        Threshold for compsite score. Default is 0.0.
 876    ri_spacing : float, optional
 877        Retention index spacing. Default is 200.
 878    ri_std : float, optional
 879        Retention index standard deviation. Default is 3.
 880    ri_calibration_compound_names : list, optional
 881        List of compound names to use for retention index calibration. Default is ['Methyl Caprylate', 'Methyl Caprate', 'Methyl Pelargonate', 'Methyl Laurate', 'Methyl Myristate', 'Methyl Palmitate', 'Methyl Stearate', 'Methyl Eicosanoate', 'Methyl Docosanoate', 'Methyl Linocerate', 'Methyl Hexacosanoate', 'Methyl Octacosanoate', 'Methyl Triacontanoate'].
 882
 883    """
 884
 885    url_database: str = "postgresql+psycopg://coremsappdb:coremsapppnnl@localhost:5432/lowres"  # 'postgresql+psycopg://postgres:labthomson0102@172.22.113.27:5432/GCMS' # 'sqlite:///db/pnnl_lowres_gcms_compounds.sqlite'
 886
 887    ri_search_range: float = 35
 888
 889    rt_search_range: float = 1.0  # used for retention index calibration
 890
 891    correlation_threshold: float = 0.5  # used for calibration, spectral similarity
 892
 893    score_threshold: float = 0.0
 894
 895    ri_spacing: float = 200
 896
 897    ri_std: float = 3  # in standard deviation
 898
 899    ri_calibration_compound_names: List = dataclasses.field(default_factory=list)
 900
 901    # calculates and export all spectral similarity methods
 902    exploratory_mode: bool = False
 903
 904    score_methods: tuple = ("highest_sim_score", "highest_ss")
 905
 906    output_score_method: str = "All"
 907
 908    def __post_init__(self):
 909        # enforce datatype
 910        self.url_database = os.getenv(
 911            "SPECTRAL_GCMS_DATABASE_URL",
 912            "sqlite:///db/pnnl_lowres_gcms_compounds.sqlite",
 913        )
 914
 915        for field in dataclasses.fields(self):
 916            value = getattr(self, field.name)
 917            if not isinstance(value, field.type):
 918                value = field.type(value)
 919                setattr(self, field.name, value)
 920
 921        self.ri_calibration_compound_names = [
 922            "Methyl Caprylate",
 923            "Methyl Caprate",
 924            "Methyl Pelargonate",
 925            "Methyl Laurate",
 926            "Methyl Myristate",
 927            "Methyl Palmitate",
 928            "Methyl Stearate",
 929            "Methyl Eicosanoate",
 930            "Methyl Docosanoate",
 931            "Methyl Linocerate",
 932            "Methyl Hexacosanoate",
 933            "Methyl Octacosanoate",
 934            "Methyl Triacontanoate",
 935        ]
 936
 937
 938class MolecularLookupDictSettings:
 939    """Settings for molecular searching
 940
 941    These are used to generate the database entries, do not change.
 942
 943    Attributes
 944    ----------
 945    usedAtoms : dict, optional
 946        Dictionary of **element symbols** (most-abundant mono codes) to
 947        (min, max) count ranges. Keys must be element symbols present in
 948        ``Atoms.isotopes`` (e.g. ``C``, ``Fe``, ``Cl``), **not** specific
 949        isotope labels (e.g. ``13C``, ``54Fe``, ``37Cl``). Rare isotopes are
 950        produced by isotopologue expansion of mono formulas after assignment.
 951        Each key also needs a valence in ``used_atom_valences``.
 952        Default is {'C': (1, 90), 'H': (4, 200), 'O': (0, 12), 'N': (0, 0),
 953        'S': (0, 0), 'P': (0, 0), 'Cl': (0, 0)}.
 954    min_mz : float, optional
 955        Minimum m/z to use for searching. Default is 50.0.
 956    max_mz : float, optional
 957        Maximum m/z to use for searching. Default is 1200.0.
 958    min_dbe : float, optional
 959        Minimum double bond equivalent to use for searching. Default is 0.
 960    max_dbe : float, optional
 961        Maximum double bond equivalent to use for searching. Default is 50.
 962    use_pah_line_rule : bool, optional
 963        If True, use the PAH line rule. Default is False.
 964    isRadical : bool, optional
 965        If True, search for radical ions. Default is True.
 966    isProtonated : bool, optional
 967        If True, search for protonated ions. Default is True.
 968    url_database : str, optional
 969        URL for the database. Default is None.
 970    db_jobs : int, optional
 971        Number of jobs to use for database queries. Default is 1.
 972    used_atom_valences : dict, optional
 973        Dictionary of atoms and valences. Default is {'C': 4, '13C': 4, 'H': 1, 'O': 2, '18O': 2, 'N': 3, 'S': 2, '34S': 2, 'P': 3, 'Cl': 1, '37Cl': 1, 'Br': 1, 'Na': 1, 'F': 1, 'K': 0}.
 974
 975    """
 976
 977    ### DO NOT CHANGE IT! These are used to generate the database entries
 978
 979    ### DO change when creating a new application database
 980
 981    ### FOR search settings runtime and database query check use the MolecularFormulaSearchSettings class below
 982
 983    ### C, H, N, O, S and P atoms are ALWAYS needed at usedAtoms
 984    ### if you don't want to include one of those atoms set the max and min at 0
 985    ### Keys must be element symbols (Atoms.isotopes), not rare-isotope labels
 986    ### you can include any mono element in Atoms.isotopes
 987    ### make sure to include the selected covalence at the used_atoms_valences when adding new atoms
 988    ### NOTE : Adducts atoms have zero covalence
 989    ### NOTE : Not using static variable because this class is distributed using multiprocessing
 990    def __init__(self):
 991        self.usedAtoms = {
 992            "C": (1, 90),
 993            "H": (4, 200),
 994            "O": (0, 12),
 995            "N": (0, 0),
 996            "S": (0, 0),
 997            "P": (0, 0),
 998            "Cl": (0, 0),
 999        }
1000        validate_used_atoms_keys(self.usedAtoms)
1001
1002        self.min_mz = 50
1003
1004        self.max_mz = 1200
1005
1006        self.min_dbe = 0
1007
1008        self.max_dbe = 50
1009
1010        # overwrites the dbe limits above to DBE = (C + heteroatoms) * 0.9
1011        self.use_pah_line_rule = False
1012
1013        self.isRadical = True
1014
1015        self.isProtonated = True
1016
1017        self.url_database = None
1018
1019        self.db_jobs = 1
1020
1021        self.used_atom_valences = {
1022            "C": 4,
1023            "13C": 4,
1024            "H": 1,
1025            "O": 2,
1026            "18O": 2,
1027            "N": 3,
1028            "S": 2,
1029            "34S": 2,
1030            "P": 3,
1031            "Cl": 1,
1032            "37Cl": 1,
1033            "Br": 1,
1034            "Na": 1,
1035            "F": 1,
1036            "K": 0,
1037        }
1038
1039
1040@dataclasses.dataclass
1041class MolecularFormulaSearchSettings:
1042    """Settings for molecular searching
1043
1044    Attributes
1045    ----------
1046    use_isotopologue_filter : bool, optional
1047        If True, use isotopologue filter. Default is False.
1048    isotopologue_filter_threshold : float, optional
1049        Threshold for isotopologue filter. Default is 33.
1050    isotopologue_filter_atoms : tuple, optional
1051        Tuple of atoms to use for isotopologue filter. Default is ('Cl', 'Br').
1052    use_runtime_kendrick_filter : bool, optional
1053        If True, use runtime Kendrick filter. Default is False.
1054    use_min_peaks_filter : bool, optional
1055        If True, use minimum peaks filter. Default is True.
1056    min_peaks_per_class : int, optional
1057        Minimum number of peaks per class. Default is 15.
1058    url_database : str, optional
1059        URL for the database. Default is 'postgresql+psycopg://coremsappdb:coremsapppnnl@localhost:5432/coremsapp'.
1060    db_jobs : int, optional
1061        Number of jobs to use for database queries. Default is 1. Can increase to 3 when python environment supports it.
1062    db_chunk_size : int, optional
1063        Chunk size to use for database queries. Default is 300.
1064    ion_charge : int, optional
1065        **Legacy / unused for formula search.** Kept so older YAML/JSON/TOML
1066        and ``MolecularFormulaSearchSettings(ion_charge=...)`` keep loading
1067        without error. Default is -1. Search polarity comes from the mass
1068        spectrum or LCMS object (DI often -1 from data; LC has no default).
1069        Absolute multi-charge range uses ``min_ion_charge`` / ``max_ion_charge``
1070        only. Do not use this field for new workflows.
1071    min_ion_charge : int, optional
1072        Minimum **absolute** ion charge for molecular formula search. Default is 1.
1073        With ``max_ion_charge``, defines the inclusive absolute charge range searched
1074        at polarity-signed values (e.g. positive polarity and max 2 → z = +1, +2).
1075        No 13C-based charge determination is performed; every selected peak is
1076        searched at each charge and candidates are ranked by existing formula
1077        scores (isotopologue similarity, confidence). Peak ``polarity`` remains
1078        ±1 (legacy alias ``peak.ion_charge``); assignment charge lives on
1079        ``MolecularFormula.ion_charge``.
1080    max_ion_charge : int, optional
1081        Maximum **absolute** ion charge for molecular formula search. Default is 1
1082        (legacy single-charge behavior). Must be >= ``min_ion_charge``.
1083        Incompatible with ``isAdduct=True`` when greater than 1 (adduct search is
1084        single-charge only; multi-charge adducts are not modeled).
1085    min_hc_filter : float, optional
1086        Minimum hydrogen to carbon ratio. Default is 0.3.
1087    max_hc_filter : float, optional
1088        Maximum hydrogen to carbon ratio. Default is 3.
1089    min_oc_filter : float, optional
1090        Minimum oxygen to carbon ratio. Default is 0.0.
1091    max_oc_filter : float, optional
1092        Maximum oxygen to carbon ratio. Default is 1.2.
1093    min_op_filter : float, optional
1094        Minimum oxygen to phosphorous ratio. Default is 2.
1095    use_pah_line_rule : bool, optional
1096        If True, use the PAH line rule. Default is False.
1097    min_dbe : float, optional
1098        Minimum double bond equivalent to use for searching. Default is 0.
1099    max_dbe : float, optional
1100        Maximum double bond equivalent to use for searching. Default is 40.
1101    mz_error_score_weight : float, optional
1102        Weight ``w_err`` for the formula-level mass-error term
1103        (``MolecularFormula.average_mz_error_score``) in the composite
1104        ``confidence_score``. Default is 0.6. See the
1105        ``corems.molecular_formula`` package documentation.
1106    isotopologue_score_weight : float, optional
1107        Weight ``w_iso`` for the isotopologue similarity term
1108        (``MolecularFormula.isotopologue_similarity``) in the composite
1109        ``confidence_score``. Default is 0.4. Some literature examples use
1110        equal weights (0.5 / 0.5).
1111    adduct_atoms_neg : tuple, optional
1112        Tuple of atoms to use in negative polarity. Default is ('Cl', 'Br').
1113    adduct_atoms_pos : tuple, optional
1114        Tuple of atoms to use in positive polarity. Default is ('Na', 'K').
1115    score_methods : tuple, optional
1116        Tuple of score method that can be implemented.
1117        Default is ('S_P_lowest_error', 'N_S_P_lowest_error', 'lowest_error', 'prob_score', 'air_filter_error', 'water_filter_error', 'earth_filter_error').
1118    score_method : str, optional
1119        Score method to use. Default is 'prob_score'. Options are 'S_P_lowest_error', 'N_S_P_lowest_error', 'lowest_error', 'prob_score', 'air_filter_error', 'water_filter_error', 'earth_filter_error'.
1120    output_min_score : float, optional
1121        Minimum score for output. Default is 0.1.
1122    output_score_method : str, optional
1123        Score method to use for output. Default is 'All Candidates'.
1124    isRadical : bool, optional
1125        If True, search for radical ions. Default is False.
1126    isProtonated : bool, optional
1127        If True, search for protonated ions. Default is True.
1128    isAdduct : bool, optional
1129        If True, search for adduct ions. Default is False.
1130        Requires ``max_ion_charge == 1`` (and typically ``min_ion_charge == 1``);
1131        multi-charge formula search does not include adduct ion types.
1132    usedAtoms : dict, optional
1133        Dictionary of **element symbols** (most-abundant mono codes) to
1134        (min, max) count ranges for molecular formula search. Keys must be
1135        element symbols present in ``Atoms.isotopes`` (e.g. ``C``, ``Fe``,
1136        ``Cl``), **not** specific isotope labels (e.g. ``13C``, ``54Fe``,
1137        ``37Cl``). Rare / heavy isotopes are generated by isotopologue
1138        expansion of mono formulas after assignment (when
1139        ``find_isotopologues`` is enabled), not by listing them here.
1140        Invalid keys raise ``ValueError`` at settings construction, assignment,
1141        or search entry. Each key also needs a valence in
1142        ``used_atom_valences`` (usually from ``Atoms.atoms_covalence``).
1143        Default empty dict is filled with C and H ranges in
1144        ``__post_init__``.
1145    ion_types_excluded : list, optional
1146        List of ion types to exclude from molecular id search, commonly ['[M+CH3COO]-]'] or ['[M+COOH]-'] depending on mobile phase content. Default is [].
1147    ionization_type : str, optional
1148        Ionization type. Default is 'ESI'.
1149    min_ppm_error : float, optional
1150        Minimum ppm error. Default is -10.0.
1151    max_ppm_error : float, optional
1152        Maximum ppm error. Default is 10.0.
1153    min_abun_error : float, optional
1154        Minimum abundance error for isotolopologue search. Default is -100.0.
1155    max_abun_error : float, optional
1156        Maximum abundance error for isotolopologue search. Default is 100.0.
1157    mz_error_range : float, optional
1158        m/z error range. Default is 1.5.
1159    error_method : str, optional
1160        Error method. Default is 'None'. Options are 'distance', 'lowest', 'symmetrical','average' 'None'.
1161    mz_error_average : float, optional
1162        m/z error average. Default is 0.0.
1163    used_atom_valences : dict, optional
1164        Dictionary of atoms and valences. Default is {'C': 4, '13C': 4, 'H': 1, 'O': 2, '18O': 2, 'N': 3, 'S': 2, '34S': 2, 'P': 3, 'Cl': 1, '37Cl': 1, 'Br': 1, 'Na': 1, 'F': 1, 'K': 0}.
1165    verbose_processing: bool, optional
1166        If True, print verbose processing information. Default is True.
1167    """
1168
1169    verbose_processing: bool = True
1170
1171    use_isotopologue_filter: bool = False
1172
1173    isotopologue_filter_threshold: float = 33
1174
1175    isotopologue_filter_atoms: tuple = ("Cl", "Br")
1176
1177    use_runtime_kendrick_filter: bool = False
1178
1179    use_min_peaks_filter: bool = True
1180
1181    min_peaks_per_class: int = 15
1182
1183    url_database: str = (
1184        "postgresql+psycopg://coremsappdb:coremsapppnnl@localhost:5432/coremsapp"
1185    )
1186
1187    db_jobs: int = 1
1188
1189    db_chunk_size: int = 300
1190
1191    # query setting========
1192    # Legacy BC only (parameter files / constructor). Not used for search.
1193    # Polarity: spectrum/LCMS data. Multi-z absolute range: min/max_ion_charge.
1194    ion_charge: int = -1
1195
1196    # Absolute charge range for formula search (polarity supplies sign).
1197    # Defaults 1..1 preserve single-charge behavior.
1198    min_ion_charge: int = 1
1199    max_ion_charge: int = 1
1200
1201    min_hc_filter: float = 0.3
1202
1203    max_hc_filter: float = 3
1204
1205    min_oc_filter: float = 0.0
1206
1207    max_oc_filter: float = 1.2
1208
1209    min_op_filter: float = 2
1210
1211    use_pah_line_rule: bool = False
1212
1213    min_dbe: float = 0
1214
1215    max_dbe: float = 40
1216
1217    mz_error_score_weight: float = 0.6
1218
1219    isotopologue_score_weight: float = 0.4
1220
1221    # look for close shell ions [M + Adduct]+ only considers metal set in the list adduct_atoms
1222    adduct_atoms_neg: tuple = ("Cl", "Br")
1223
1224    adduct_atoms_pos: tuple = ("Na", "K")
1225
1226    score_methods: tuple = (
1227        "S_P_lowest_error",
1228        "N_S_P_lowest_error",
1229        "lowest_error",
1230        "prob_score",
1231        "air_filter_error",
1232        "water_filter_error",
1233        "earth_filter_error",
1234    )
1235
1236    score_method: str = "prob_score"
1237
1238    output_min_score: float = 0.1
1239
1240    output_score_method: str = "All Candidates"
1241
1242    # depending on the polarity mode it looks for [M].+ , [M].-
1243    # query and automatically compile add entry if it doesn't exist
1244
1245    isRadical: bool = False
1246
1247    # depending on the polarity mode it looks for [M + H]+ , [M - H]+
1248    # query and automatically compile and push options if it doesn't exist
1249    isProtonated: bool = True
1250
1251    isAdduct: bool = False
1252
1253    usedAtoms: dict = dataclasses.field(default_factory=dict)
1254    ion_types_excluded: list = dataclasses.field(default_factory=list)
1255
1256    # search setting ========
1257
1258    ionization_type: str = "ESI"
1259
1260    # empirically set / needs optimization
1261    min_ppm_error: float = -10.0  # ppm
1262
1263    # empirically set / needs optimization
1264    max_ppm_error: float = 10.0  # ppm
1265
1266    # empirically set / needs optimization set for isotopologue search
1267    min_abun_error: float = -100.0  # percentage
1268
1269    # empirically set / needs optimization set for isotopologue search
1270    max_abun_error: float = 100.0  # percentage
1271
1272    # empirically set / needs optimization
1273    mz_error_range: float = 1.5
1274
1275    # 'distance', 'lowest', 'symmetrical','average' 'None'
1276    error_method: str = "None"
1277
1278    mz_error_average: float = 0.0
1279
1280    # used_atom_valences: {'C': 4, 'H':1, etc} = dataclasses.field(default_factory=dict)
1281    used_atom_valences: dict = dataclasses.field(default_factory=dict)
1282
1283    def __setattr__(self, name, value):
1284        # Catch full reassignment of usedAtoms after construction (common API).
1285        # In-place mutation (usedAtoms[key] = ...) is validated at search entry.
1286        if name == "usedAtoms" and value is not None:
1287            validate_used_atoms_keys(value)
1288        super().__setattr__(name, value)
1289
1290    def __post_init__(self):
1291        if not self.url_database or self.url_database == "":
1292            self.url_database = os.getenv(
1293                "COREMS_DATABASE_URL", "sqlite:///db/molformula.db"
1294            )
1295        # enforce datatype
1296        for field in dataclasses.fields(self):
1297            value = getattr(self, field.name)
1298            if not isinstance(value, field.type):
1299                value = field.type(value)
1300                setattr(self, field.name, value)
1301
1302        # enforce C and H if either do not exists
1303        if "C" not in self.usedAtoms.keys():
1304            self.usedAtoms["C"] = (1, 100)
1305        if "H" not in self.usedAtoms.keys():
1306            self.usedAtoms["H"] = (1, 200)
1307
1308        validate_used_atoms_keys(self.usedAtoms)
1309
1310        # add cummon values
1311        current_used_atoms = self.used_atom_valences.keys()
1312
1313        for atom in Atoms.atoms_covalence.keys():
1314            if atom not in current_used_atoms:
1315                covalence = Atoms.atoms_covalence.get(atom)
1316
1317                if isinstance(covalence, int):
1318                    self.used_atom_valences[atom] = covalence
1319
1320                else:
1321                    # will get the first number of all possible covalances, which should be the most commum
1322                    self.used_atom_valences[atom] = covalence[0]
1323
1324        self.validate_ion_charge_settings()
1325
1326    def validate_ion_charge_settings(self):
1327        """Validate absolute charge range and adduct compatibility.
1328
1329        Raises
1330        ------
1331        ValueError
1332            If ``min_ion_charge`` / ``max_ion_charge`` are invalid, or if
1333            ``isAdduct`` is enabled with multi-charge search
1334            (``max_ion_charge > 1``).
1335        """
1336        min_z = int(self.min_ion_charge)
1337        max_z = int(self.max_ion_charge)
1338        if min_z < 1:
1339            raise ValueError("min_ion_charge must be >= 1")
1340        if max_z < min_z:
1341            raise ValueError("max_ion_charge must be >= min_ion_charge")
1342        # Multi-charge adducts ([M+Na+H]2+, [M+2Na]2+, etc.) are not modeled;
1343        # adduct search is single-charge only.
1344        if self.isAdduct and max_z > 1:
1345            raise ValueError(
1346                "isAdduct=True is incompatible with multi-charge formula search "
1347                f"(max_ion_charge={max_z}). Set max_ion_charge=1 for adduct "
1348                "search, or disable isAdduct for multi-charge protonated/radical "
1349                "search."
1350            )
1351
1352
1353@dataclasses.dataclass
1354class LCMSCollectionSettings:
1355    """Settings for LCMS collection class
1356
1357    Attributes
1358    ----------
1359    cores : int, optional
1360        Number of cores to use for processing. Default is 1.
1361    drop_isotopologues : bool, optional
1362        If True, drop isotopologues from all analyses.
1363        Note that this will keep mass features identified as monoisotopes and any largest ion in deconvoluted mass spectrum.
1364        It will also keep mass features not identified as isotopologues or monoisotopes.
1365        Default is True.
1366    mass_feature_anchor_technique: list, optional
1367        List of mass feature anchor techniques for retention time alignment.
1368        Default is ['absolute_intensity'].
1369    mass_feature_anchor_techniques_available: tuple, optional
1370        Tuple of available mass feature anchor techniques for retention time alignment.
1371        Default is ('deconvoluted_mass_spectra', 'absolute_intensity', 'relative_intensity').
1372    mass_feature_anchor_absolute_intensity_threshold: int, optional
1373        Absolute intensity threshold for mass feature anchor for retention time alignment.
1374        Used when mass_feature_anchor_technique includes 'relative_intensity'.
1375        Default is 10000.
1376    mass_feature_anchor_relative_intensity_threshold: float, optional
1377        Relative intensity threshold (0-1) for mass feature anchor for retention time alignment.
1378        Removes the lower fraction of mass features by intensity from consideration.
1379        For example, 0.6 removes the lower 60% of intensity features.
1380        Used when mass_feature_anchor_technique includes 'relative_intensity'.
1381        Default is 0.6.
1382    alignment_minimum_matches: int, optional
1383        Minimum number of matched features required to attempt retention time alignment.
1384        If fewer matches are found between samples, alignment will be skipped for that sample.
1385        This is particularly useful when aligning blank samples or samples with very few features.
1386        Default is 5.
1387    alignment_hold_out_fraction: float, optional
1388        Hold out fraction for testing retention time alignment.
1389        Default is 0.3.
1390    alignment_acceptance_technique: list, optional
1391        List of alignment acceptance techniques for retention time alignment.
1392        Default is ['fraction_improved', 'mean_squared_error_improved'].
1393    alignment_acceptance_techniques_available: tuple, optional
1394        Tuple of available alignment acceptance techniques for retention time alignment.
1395        Default is ('fraction_improved', 'mean_squared_error_improved').
1396    alignment_acceptance_fraction_improved_threshold: float, optional
1397        Threshold for the improved fraction of the hold out mass features for accepting retention time alignment.
1398        Default is 0.5.
1399    alignment_mz_tol_ppm: int, optional
1400        m/z tolerance in ppm for retention time alignment and for consensus feature
1401        grouping isotope (and later adduct) mass deltas. Default is 5.
1402    alignment_rt_tol: float, optional
1403        Retention time tolerance in minutes for retention time alignment and for
1404        consensus feature grouping coelution windows. Default is 0.3.
1405    consensus_mz_tol_ppm: int, optional
1406        m/z tolerance in ppm for consensus mass feature alignment. Default is 5.
1407        The recommendation is that this value should be the same as alignment_mz_tol_ppm.
1408    consensus_rt_tol: float, optional
1409        Retention time tolerance for consensus mass feature alignment, in minutes. Default is 0.2.
1410    consensus_partition_size: int, optional
1411        Partition size for consensus mass feature alignment. Default is 5000.
1412    consensus_min_sample_fraction : float, optional
1413        Minimum fraction of samples (0-1) that must contain a cluster.
1414        Used for filtering consensus features and for gap-filling threshold.
1415        Default is 0.5 (50%). Higher values focus on more prevalent features.
1416    gap_fill_expand_on_miss : bool, optional
1417        If True, expands the search window when no peak is found inside the
1418        cluster bounds. m/z widens by consensus_mz_tol_ppm. Retention time
1419        widens by consensus_rt_tol minutes. Default is True.
1420    consensus_representative_metric : str, optional
1421        Metric used to determine the most representative sample for a consensus mass feature.
1422        Options:
1423        - 'intensity': Selects the mass feature with the highest intensity value
1424        - 'intensity_prefer_ms2': Selects the mass feature with the highest intensity among
1425          those that have MS2 scan numbers assigned. If no features have MS2 scans, falls
1426          back to selecting the highest intensity feature overall.
1427        Default is 'intensity_prefer_ms2'.
1428    consensus_representative_metrics_available : tuple, optional
1429        Tuple of available metrics for determining the most representative sample.
1430        Default is ('intensity', 'intensity_prefer_ms2').
1431    feature_group_isotope_atoms : tuple of str, optional
1432        Mono elements for natural-abundance isotope Δm edges via ``Atoms``
1433        (e.g. ``("C",)``). Default ``("C",)``. Not for tracer labeling.
1434    feature_group_min_isotope_abundance : float, optional
1435        Min natural abundance (0–1) for rare forms in isotope spacing.
1436        Default 0.01.
1437    feature_group_max_isotope_offset : int, optional
1438        Max M+n roll-up depth for one rare form (e.g. ¹³Cₙ). Default 4.
1439    feature_group_corr_threshold : float, optional
1440        Min Pearson correlation of apex ``intensity`` vectors for an edge
1441        (pairwise-complete; zeros dropped). Default 0.80.
1442    feature_group_min_shared_sample_fraction : float, optional
1443        Min fraction of samples with both heights > 0 before correlation
1444        is trusted (``ceil(fraction * n_samples)``). Default 0.15.
1445    feature_group_ion_types : tuple of str, optional
1446        Allow-list of ``ION_TYPE_DICT`` keys for adduct linking (``|z| = 1``).
1447        Empty/one type → isotopes only. Default is a curated common set
1448        (``DEFAULT_ION_TYPES``); narrow further to reduce false adduct links.
1449        Filtered by collection polarity at ``group_consensus_features()``.
1450    feature_group_constrain_annotation : bool, optional
1451        If True and labels exist, skip consensus isotopes in collection
1452        MS1/MS2/annotation and keep IDs only if ion type is in
1453        ``possible_ion_types``. Default True.
1454    feature_group_partition_size : int, optional
1455        Reserved RT-partition size for future multicore grouping.
1456        Default 5000.
1457    """
1458
1459    # Settings for general processing
1460    cores: int = 1
1461    drop_isotopologues: bool = False
1462
1463    # Settings for doing mass feature alignment
1464    _mass_feature_anchor_technique: list = dataclasses.field(
1465        default_factory=lambda: ["relative_intensity"]
1466    )
1467    mass_feature_anchor_techniques_available: tuple = (
1468        "deconvoluted_mass_spectra",
1469        "absolute_intensity",
1470        "relative_intensity",
1471    )
1472    mass_feature_anchor_absolute_intensity_threshold: int = 10000
1473    mass_feature_anchor_relative_intensity_threshold: float = 0.6
1474    alignment_minimum_matches: int = 5
1475    alignment_hold_out_fraction: float = 0.3
1476    _alignment_acceptance_technique: list = dataclasses.field(
1477        default_factory=lambda: ["fraction_improved", "mean_squared_error_improved"]
1478    )
1479    alignment_acceptance_techniques_available: tuple = (
1480        "fraction_improved",
1481        "mean_squared_error_improved",
1482    )
1483    alignment_acceptance_fraction_improved_threshold: float = 0.5
1484    alignment_mz_tol_ppm: int = 5
1485    alignment_rt_tol: float = 0.4
1486
1487    # Consensus mass feature settings
1488    consensus_mz_tol_ppm: int = alignment_mz_tol_ppm
1489    consensus_rt_tol: float = 0.3
1490    consensus_partition_size: int = 10000
1491    filter_consensus_mass_features: bool = True
1492    consensus_min_sample_fraction: float = 0.5
1493
1494    # Gap-filling settings
1495    gap_fill_expand_on_miss: bool = True
1496
1497    # Consensus mass feature visualization parameters
1498    consensus_representative_metric: str = "intensity_prefer_ms2"
1499    consensus_representative_metrics_available: tuple = (
1500        "intensity",
1501        "intensity_prefer_ms2",
1502    )
1503
1504    # Feature grouping (isotopes + z=1 adducts); RT/m/z use alignment_* tols
1505    feature_group_isotope_atoms: tuple = ("C",)
1506    feature_group_min_isotope_abundance: float = 0.01
1507    feature_group_max_isotope_offset: int = 4
1508    feature_group_corr_threshold: float = 0.80
1509    feature_group_min_shared_sample_fraction: float = 0.15
1510    feature_group_ion_types: tuple = dataclasses.field(
1511        default_factory=lambda: (
1512            __import__(
1513                "corems.mass_spectra.calc.feature_grouping",
1514                fromlist=["DEFAULT_ION_TYPES"],
1515            ).DEFAULT_ION_TYPES
1516        )
1517    )
1518    feature_group_constrain_annotation: bool = True
1519    feature_group_partition_size: int = 5000
1520
1521    def __post_init__(self):
1522        self.consensus_mz_tol_ppm = self.alignment_mz_tol_ppm
1523        self._validate_alignment_acceptance_technique(
1524            self.alignment_acceptance_technique
1525        )
1526        self._validate_mass_feature_anchor_technique(self.mass_feature_anchor_technique)
1527
1528    def _validate_alignment_acceptance_technique(self, techniques):
1529        for technique in techniques:
1530            if technique not in self.alignment_acceptance_techniques_available:
1531                raise ValueError(
1532                    f"Alignment acceptance technique '{technique}' is not available. Alignment acceptance technique must be passed as a list. Available techniques: {self.alignment_acceptance_techniques_available}"
1533                )
1534
1535    def _validate_mass_feature_anchor_technique(self, techniques):
1536        for technique in techniques:
1537            if technique not in self.mass_feature_anchor_techniques_available:
1538                raise ValueError(
1539                    f"Mass feature anchor technique '{technique}' is not available. Alignment acceptance technique must be passed as a list. Available techniques: {self.mass_feature_anchor_techniques_available}"
1540                )
1541
1542    @property
1543    def alignment_acceptance_technique(self):
1544        return self._alignment_acceptance_technique
1545
1546    @alignment_acceptance_technique.setter
1547    def alignment_acceptance_technique(self, value):
1548        self._validate_alignment_acceptance_technique(value)
1549        self._alignment_acceptance_technique = value
1550
1551    @property
1552    def mass_feature_anchor_technique(self):
1553        return self._mass_feature_anchor_technique
1554
1555    @mass_feature_anchor_technique.setter
1556    def mass_feature_anchor_technique(self, value):
1557        self._validate_mass_feature_anchor_technique(value)
1558        self._mass_feature_anchor_technique = value
LEGACY_PARAMETER = 'legacy'
def legacy_field(default, **kwargs):
15def legacy_field(default, **kwargs):
16    """``dataclasses.field`` that marks a setting as legacy (not exported).
17
18    Use for in-memory / back-compat aliases that must not appear in
19    parameter JSON/TOML when settings are dumped. Export paths should use
20    :func:`settings_to_export_dict` (or equivalent) so this metadata is honored.
21    """
22    metadata = dict(kwargs.pop("metadata", {}) or {})
23    metadata[LEGACY_PARAMETER] = True
24    return dataclasses.field(default=default, metadata=metadata, **kwargs)

dataclasses.field that marks a setting as legacy (not exported).

Use for in-memory / back-compat aliases that must not appear in parameter JSON/TOML when settings are dumped. Export paths should use settings_to_export_dict() (or equivalent) so this metadata is honored.

def settings_to_export_dict(settings_obj) -> dict:
27def settings_to_export_dict(settings_obj) -> dict:
28    """Serialize settings for parameter export; skip fields marked legacy.
29
30    Fields defined with :func:`legacy_field` (metadata
31    ``LEGACY_PARAMETER=True``) are omitted. Used by LCMS parameter dump so
32    old annotation knobs on ``LiquidChromatographSetting`` are not rewritten
33    into TOML/JSON after migration to ``spectral_similarity_search``.
34    """
35    if not dataclasses.is_dataclass(settings_obj) or isinstance(settings_obj, type):
36        return dict(getattr(settings_obj, "__dict__", {}))
37    out = {}
38    for f in dataclasses.fields(settings_obj):
39        if f.metadata.get(LEGACY_PARAMETER, False):
40            continue
41        out[f.name] = getattr(settings_obj, f.name)
42    return out

Serialize settings for parameter export; skip fields marked legacy.

Fields defined with legacy_field() (metadata LEGACY_PARAMETER=True) are omitted. Used by LCMS parameter dump so old annotation knobs on LiquidChromatographSetting are not rewritten into TOML/JSON after migration to spectral_similarity_search.

def validate_used_atoms_keys(used_atoms):
45def validate_used_atoms_keys(used_atoms):
46    """Validate that usedAtoms keys are element symbols, not rare isotopes.
47
48    Molecular formula search treats each usedAtoms key as a monoisotopic
49    (most-abundant) element. Heavy isotopologues (e.g. 13C, 54Fe, 37Cl) are
50    produced later by isotopologue expansion of mono formulas, not by listing
51    rare-isotope labels in usedAtoms. Membership in ``Atoms.isotopes`` does
52    not mean the element is ready to search: each key still needs a valence
53    in ``used_atom_valences`` (typically copied from ``Atoms.atoms_covalence``),
54    or DBE calculation can fail.
55
56    Parameters
57    ----------
58    used_atoms : dict
59        Mapping of atom symbol to (min, max) count range.
60
61    Raises
62    ------
63    ValueError
64        If any key is not a mono element symbol (key of Atoms.isotopes).
65    TypeError
66        If used_atoms is not a mapping.
67    """
68    if used_atoms is None:
69        return
70    if not hasattr(used_atoms, "keys"):
71        raise TypeError(
72            "usedAtoms must be a dict of element symbols to (min, max) ranges"
73        )
74    invalid = [k for k in used_atoms.keys() if k not in Atoms.isotopes]
75    if invalid:
76        raise ValueError(
77            "usedAtoms keys must be element symbols (e.g. Fe, C, Cl), "
78            "not specific isotope labels (e.g. 54Fe, 13C, 37Cl). "
79            f"Invalid key(s): {invalid}. "
80            "Heavy isotopologues are generated from mono formulas during search."
81        )

Validate that usedAtoms keys are element symbols, not rare isotopes.

Molecular formula search treats each usedAtoms key as a monoisotopic (most-abundant) element. Heavy isotopologues (e.g. 13C, 54Fe, 37Cl) are produced later by isotopologue expansion of mono formulas, not by listing rare-isotope labels in usedAtoms. Membership in Atoms.isotopes does not mean the element is ready to search: each key still needs a valence in used_atom_valences (typically copied from Atoms.atoms_covalence), or DBE calculation can fail.

Parameters
  • used_atoms (dict): Mapping of atom symbol to (min, max) count range.
Raises
  • ValueError: If any key is not a mono element symbol (key of Atoms.isotopes).
  • TypeError: If used_atoms is not a mapping.
@dataclasses.dataclass
class TransientSetting:
 84@dataclasses.dataclass
 85class TransientSetting:
 86    """Transient processing settings class
 87
 88    Attributes
 89    ----------
 90    implemented_apodization_function : tuple
 91        Available apodization functions
 92    apodization_method : str
 93        Apodization function to use. Hanning is a good default for Fourier transform magnitude mode.
 94        For absorption mode processing, Half-Sine or Half-Kaiser may be more appropriate.
 95    number_of_truncations : int
 96        How many times to truncate the transient prior to Fourier transform
 97    number_of_zero_fills : int
 98        How many times to zero fille the transient prior to Fourier transform.
 99    next_power_of_two : bool
100        If True, zero fill to the next power of two after the new length of len(transient)+(number_of_zero_fills*len(transient)).
101    kaiser_beta : float
102        Beta parameter for Kaiser or Half-Kaiser apodisation function. 0 is rectangular,  5 is similar to Hamming,
103        6 is similar to hanning, and 8.6 is similar to Blackman (from numpy docs)
104
105    """
106
107    implemented_apodization_function: tuple = (
108        "Hamming",
109        "Hanning",
110        "Blackman",
111        "Full-Sine",
112        "Half-Sine",
113        "Kaiser",
114        "Half-Kaiser",
115        "Rectangle",
116    )
117    apodization_method: str = "Hanning"
118    number_of_truncations: int = 0
119    number_of_zero_fills: int = 1
120    next_power_of_two: bool = False
121    kaiser_beta: float = 8.6
122
123    def __post_init__(self):
124        # enforce datatype
125        for field in dataclasses.fields(self):
126            value = getattr(self, field.name)
127            if not isinstance(value, field.type):
128                value = field.type(value)
129                setattr(self, field.name, value)

Transient processing settings class

Attributes
  • implemented_apodization_function (tuple): Available apodization functions
  • apodization_method (str): Apodization function to use. Hanning is a good default for Fourier transform magnitude mode. For absorption mode processing, Half-Sine or Half-Kaiser may be more appropriate.
  • number_of_truncations (int): How many times to truncate the transient prior to Fourier transform
  • number_of_zero_fills (int): How many times to zero fille the transient prior to Fourier transform.
  • next_power_of_two (bool): If True, zero fill to the next power of two after the new length of len(transient)+(number_of_zero_fills*len(transient)).
  • kaiser_beta (float): Beta parameter for Kaiser or Half-Kaiser apodisation function. 0 is rectangular, 5 is similar to Hamming, 6 is similar to hanning, and 8.6 is similar to Blackman (from numpy docs)
TransientSetting( implemented_apodization_function: tuple = ('Hamming', 'Hanning', 'Blackman', 'Full-Sine', 'Half-Sine', 'Kaiser', 'Half-Kaiser', 'Rectangle'), apodization_method: str = 'Hanning', number_of_truncations: int = 0, number_of_zero_fills: int = 1, next_power_of_two: bool = False, kaiser_beta: float = 8.6)
implemented_apodization_function: tuple = ('Hamming', 'Hanning', 'Blackman', 'Full-Sine', 'Half-Sine', 'Kaiser', 'Half-Kaiser', 'Rectangle')
apodization_method: str = 'Hanning'
number_of_truncations: int = 0
number_of_zero_fills: int = 1
next_power_of_two: bool = False
kaiser_beta: float = 8.6
@dataclasses.dataclass
class DataInputSetting:
132@dataclasses.dataclass
133class DataInputSetting:
134    """Data input settings class
135
136    Attributes
137    ----------
138    header_translate : dict
139        Dictionary with the header labels to be translated to the corems labels. For example, {'m/z':'m/z', 'Resolving Power':'Resolving Power', 'Abundance':'Abundance' , 'S/N':'S/N'}
140    """
141
142    # add to this dict the VALUES to match your labels, THE ORDER WON"T MATTER
143    # "column_translate" : {"m/z":"m/z", "Resolving Power":"Resolving Power", "Abundance":"Abundance" , "S/N":"S/N"}
144    header_translate: dict = dataclasses.field(default_factory=dict)
145
146    def __post_init__(self):
147        self.header_translate = {
148            "m/z": Labels.mz,
149            "mOz": Labels.mz,
150            "Mass": Labels.mz,
151            "Resolving Power": Labels.rp,
152            "Res.": Labels.rp,
153            "resolution": Labels.rp,
154            "Intensity": Labels.abundance,
155            "Peak Height": Labels.abundance,
156            "I": Labels.abundance,
157            "Abundance": Labels.abundance,
158            "abs_abu": Labels.abundance,
159            "Signal/Noise": Labels.s2n,
160            "S/N": Labels.s2n,
161            "sn": Labels.s2n,
162        }
163
164    def add_mz_label(self, label):
165        """Add a label to the header_translate dictionary to be translated to the corems label for mz."""
166        self.header_translate[label] = Labels.mz
167
168    def add_peak_height_label(self, label):
169        """Add a label to the header_translate dictionary to be translated to the corems label for peak height."""
170
171        self.header_translate[label] = Labels.abundance
172
173    def add_sn_label(self, label):
174        """Add a label to the header_translate dictionary to be translated to the corems label for signal to noise."""
175        self.header_translate[label] = Labels.s2n
176
177    def add_resolving_power_label(self, label):
178        """Add a label to the header_translate dictionary to be translated to the corems label for resolving power."""
179        self.header_translate[label] = Labels.rp

Data input settings class

Attributes
  • header_translate (dict): Dictionary with the header labels to be translated to the corems labels. For example, {'m/z':'m/z', 'Resolving Power':'Resolving Power', 'Abundance':'Abundance' , 'S/N':'S/N'}
DataInputSetting(header_translate: dict = <factory>)
header_translate: dict
def add_mz_label(self, label):
164    def add_mz_label(self, label):
165        """Add a label to the header_translate dictionary to be translated to the corems label for mz."""
166        self.header_translate[label] = Labels.mz

Add a label to the header_translate dictionary to be translated to the corems label for mz.

def add_peak_height_label(self, label):
168    def add_peak_height_label(self, label):
169        """Add a label to the header_translate dictionary to be translated to the corems label for peak height."""
170
171        self.header_translate[label] = Labels.abundance

Add a label to the header_translate dictionary to be translated to the corems label for peak height.

def add_sn_label(self, label):
173    def add_sn_label(self, label):
174        """Add a label to the header_translate dictionary to be translated to the corems label for signal to noise."""
175        self.header_translate[label] = Labels.s2n

Add a label to the header_translate dictionary to be translated to the corems label for signal to noise.

def add_resolving_power_label(self, label):
177    def add_resolving_power_label(self, label):
178        """Add a label to the header_translate dictionary to be translated to the corems label for resolving power."""
179        self.header_translate[label] = Labels.rp

Add a label to the header_translate dictionary to be translated to the corems label for resolving power.

@dataclasses.dataclass
class LiquidChromatographSetting:
182@dataclasses.dataclass
183class LiquidChromatographSetting:
184    """Liquid chromatograph processing settings class
185
186    Attributes
187    ----------
188    scans : list or tuple, optional
189        List of select scan to average or a tuple containing the range to average.
190        Default is (-1, -1).
191    eic_tolerance_ppm : float, optional
192        Mass tolerance in ppm for extracted ion chromatogram peak detection.
193        Default is 5.
194    correct_eic_baseline : bool, optional
195        If True, correct the baseline of the extracted ion chromatogram.
196        Default is True.
197    smooth_window : int, optional
198        Window size for smoothing the ion chromatogram (extracted or total).
199        Default is 5.
200    smooth_method : str, optional
201        Smoothing method to use. See implemented_smooth_method for options.
202        Default is 'savgol'.
203    implemented_smooth_method : tuple, optional
204        Smoothing methods that can be implemented.
205        Default is ('savgol', 'hanning', 'blackman', 'bartlett', 'flat', 'boxcar').
206    savgol_pol_order : int, optional
207        Polynomial order for Savitzky-Golay smoothing.
208        Default is 2.
209    consecutive_scan_min : int, optional
210        Minimum number of consecutive scans to consider for peak detection.
211        Default is 0 for backwards compatibility, but a value of 3 is recommended.
212    peak_height_max_percent : float, optional
213        1-100 % used for baseline detection use 0.1 for second_derivative and 10 for other methods.
214        Default is 10.
215    peak_max_prominence_percent : float, optional
216        1-100 % used for baseline detection.
217        Default is 1.
218    peak_derivative_threshold : float, optional
219        Threshold for defining derivative crossing.
220        Default is 0.0005.
221    min_peak_datapoints : float, optional
222        minimum data point to define a chromatografic peak.
223        Default is 5.
224    noise_threshold_method : str, optional
225        Method for detecting noise threshold.
226        Default is 'manual_relative_abundance'.
227    noise_threshold_methods_implemented : tuple, optional
228        Methods for detected noise threshold that can be implemented.
229        Default is ('auto_relative_abundance', 'manual_relative_abundance', 'second_derivative').
230    peak_height_min_percent : float, optional
231        0-100 % used for peak detection.
232        Default is 0.1.
233    eic_signal_threshold : float, optional
234        0-100 % used for extracted ion chromatogram peak detection.
235        Default is 0.01.
236    eic_buffer_time : float, optional
237        Buffer time to add to the start and end of the plot of the extracted ion chromatogram, in minutes.
238        Default is 1.5.
239    dispersity_index_window : float, optional
240        Dispersity index window size, in minutes.
241        Default is 3.0.
242    noise_window_factor : float, optional
243        Factor to determine noise estimation window size relative to peak width.
244        Larger values use wider windows for noise estimation.
245        For example, a value of 2.0 uses a window size equal to twice the peak width
246        (depending on it's start and end scans) on each side.
247        Called within the LCMSMassFeature.calc_noise_score() method.
248        Default is 2.0.
249    remove_redundant_mass_features : bool, optional
250        If True, remove redundant mass features that are likely contaminants based on
251        their m/z values and scan frequency.
252        Especially useful for HILIC data where signals do not return to baseline between peaks
253        or for data with significant background noise.
254        Called within the LC_Calculations.find_mass_features() method.
255        Default is False.
256    redundant_scan_frequency_min : float, optional
257        Minimum fraction of scans that must contain the m/z to be considered a likely
258        noise/contaminant when using remove_redundant_mass_features.
259        Default is 0.1 (10% of scans).
260    redundant_feature_retain_n : int, optional
261        Number of features to retain in each group when using remove_redundant_mass_features.
262        Default is 3.
263    remove_mass_features_by_peak_metrics : bool, optional
264        If True, remove mass features based on their peak metrics such as S/N, Gaussian similarity,
265        dispersity index, and noise score.
266        Called within the LC_Calculations.add_peak_metrics() method.
267        Default is False.
268    mass_feature_attribute_filter_dict : dict, optional
269        Dictionary specifying filtering criteria for mass feature attributes.
270        Each key is an attribute name, and each value is a dict with 'value' and 'operator' keys.
271
272        Structure: {attribute_name: {'value': threshold, 'operator': comparison}}
273
274        Available operators:
275        - '>' or 'greater': Keep features where attribute > threshold
276        - '<' or 'less': Keep features where attribute < threshold
277        - '>=' or 'greater_equal': Keep features where attribute >= threshold
278        - '<=' or 'less_equal': Keep features where attribute <= threshold
279
280        Examples:
281        {
282            'noise_score_max': {'value': 0.5, 'operator': '>'},  # Keep if noise_score_max > 0.5
283            'dispersity_index': {'value': 0.1, 'operator': '<'},  # Keep if dispersity_index < 0.1
284            'gaussian_similarity': {'value': 0.7, 'operator': '>='}  # Keep if gaussian_similarity >= 0.7
285        }
286
287        Available attributes include: 'noise_score', 'noise_score_min', 'noise_score_max',
288        'gaussian_similarity', 'tailing_factor', 'dispersity_index', 'half_height_width', 'intensity'.
289        Default is {"noise_score_max": {"value": 0.8, "operator": ">="},"noise_score_min": {"value": 0.5, "operator": ">="}},
290    peak_picking_method : str, optional
291        Peak picking method to use. See implemented_peak_picking_methods for options.
292        Default is 'by_format', which selects persistent homology when all scans
293        at the requested MS level are profile and centroided persistent
294        homology when all are centroid, then stores the concrete method on
295        this setting so saved parameters record what was used.
296    implemented_peak_picking_methods : tuple, optional
297        Peak picking methods that can be implemented.
298        Default is ('by_format', 'persistent homology', 'centroided_persistent_homology').
299    ph_smooth_it : int, optional
300        Number of iterations to use for smoothing prior to finding mass features.
301        Used only for "persistent homology" peak picking method.
302        Called within the PHCalculations.find_mass_features_ph() method.
303        Default is 1.
304    ph_smooth_radius_mz : int, optional
305        Radius in m/z steps (not daltons) for smoothing prior to finding mass features.
306        Used only for "persistent homology" peak picking method.
307        Called within the PHCalculations.find_mass_features_ph() method.
308        Default is 0.
309    ph_smooth_radius_scan : int, optional
310        Radius in scan steps for smoothing prior to finding mass features.
311        Used only for "persistent homology" peak picking method.
312        Called within the PHCalculations.find_mass_features_ph() method.
313        Default is 1.
314    ph_inten_min_rel : float, optional
315        Relative minimum intensity to use for finding mass features for persistent homology.
316        Used only for "persistent homology" peak picking method.
317        Calculated as a fraction of the maximum intensity of the unprocessed profile data (mz, scan).
318        Called within the PH_Calculations.find_mass_features() method.
319        Default is 0.001.
320    ph_persis_min_rel : float, optional
321        Relative minimum persistence for retaining mass features.
322        Used for both "persistent homology" and "centroided_persistent_homology" peak picking methods.
323        Calculated as a fraction of the maximum intensity of the unprocessed profile data (mz, scan).
324        Should be greater to or equal to ph_inten_min_rel.
325        Called within the PH_Calculations.find_mass_features() method.
326        Default is 0.001.
327    ph_inten_min_abs : float, optional
328        Absolute minimum intensity for points that enter persistent homology.
329        Applied with ph_inten_min_rel on profile and centroided data.
330        The relative floor is still a fraction of the unfiltered maximum.
331        0 disables the absolute floor. Default is 0.0.
332    mass_feature_cluster_mz_tolerance_rel : float, optional
333        Relative m/z tolerance to use for clustering mass features.
334        Used for both "persistent homology" and "centroided_persistent_homology"
335        peak picking methods.
336        Called with the PHCalculations.cluster_mass_features() and the
337        LCCalculations.deconvolute_ms1_mass_features() methods.
338        Default is 5e-6 (5 ppm).
339    mass_feature_cluster_rt_tolerance : float, optional
340        Retention time tolerance to use for clustering mass features, in minutes.
341        Used for both "persistent homology" and "centroided_persistent_homology"
342        peak picking methods.
343        Called with the PHCalculations.cluster_mass_features() and the
344        LCCalculations.deconvolute_ms1_mass_features() methods.
345        Default is 0.3.
346    ms1_scans_to_average : int, optional
347        Number of MS1 scans to average for mass-feature associated m/zs.
348        Called within the LCMSBase.add_associated_ms1() method.
349        Default is 1.
350    ms1_deconvolution_corr_min : float, optional
351        Minimum correlation to use for deconvoluting MS1 mass features.
352        Called within the LCCalculations.deconvolute_ms1_mass_features() method.
353        Default is 0.8.
354    ms2_dda_rt_tolerance : float, optional
355        Retention time tolerance to use for associating MS2 spectra to mass features, in minutes.
356        Called within the LCMSBase.add_associated_ms2_dda() method.
357        Default is 0.15.
358    ms2_dda_mz_tolerance : float, optional
359        Mass tolerance to use for associating MS2 spectra to mass features.
360        Called within the LCMSBase.add_associated_ms2_dda() method.
361        Default is 0.05.
362    ms2_min_fe_score : float, optional
363        Minimum flash entropy for retaining MS2 annotations.
364        Legacy; prefer ``mass_spectrum["ms2"].spectral_similarity_search.ms2_min_fe_score``.
365        Default is 0.2.
366    search_as_lipids : bool, optional
367        Legacy lipid-search flag; prefer ``mass_spectrum["ms2"].spectral_similarity_search``.
368        Default is False.
369    include_fragment_types : bool, optional
370        Legacy fragment-type flag; prefer ``mass_spectrum["ms2"].spectral_similarity_search``.
371        Default is False.
372    export_profile_spectra : bool, optional
373        If True, export profile spectra data.
374        Default is False.
375    export_eics : bool, optional
376        If True, export extracted ion chromatograms.
377        Default is True.
378    export_unprocessed_ms1 : bool, optional
379        If True, export unprocessed MS1 data.
380        Default is False.
381    export_only_relevant_mass_spectra : bool, optional
382        If True, export only mass spectra associated with detected mass features:
383        specifically the apex MS1 scan for each mass feature and the best MS2 scan
384        for each mass feature (if available). If False, export all mass spectra.
385        This parameter reduces HDF5 file size by excluding non-feature spectra.
386        Default is False (backwards compatible - exports all spectra).
387    verbose_processing : bool, optional
388        If True, print verbose processing information.
389        Default is True.
390    """
391
392    scans: list | tuple = (-1, -1)
393
394    # Parameters used for generating EICs and performing 1D peak picking and EIC/TIC smoothing
395    eic_tolerance_ppm: float = 5
396    correct_eic_baseline = True
397    smooth_window: int = 5
398    smooth_method: str = "savgol"
399    implemented_smooth_method: tuple = (
400        "savgol",
401        "hanning",
402        "blackman",
403        "bartlett",
404        "flat",
405        "boxcar",
406    )
407    savgol_pol_order: int = 2
408    consecutive_scan_min: int = 0
409    peak_height_max_percent: float = 10
410    peak_max_prominence_percent: float = 1
411    peak_derivative_threshold: float = 0.0005
412    min_peak_datapoints: float = 5
413    noise_threshold_method: str = "manual_relative_abundance"
414    noise_threshold_methods_implemented: tuple = (
415        "auto_relative_abundance",
416        "manual_relative_abundance",
417        "second_derivative",
418    )
419    peak_height_min_percent: float = 0.1
420    eic_signal_threshold: float = 0.01
421    eic_buffer_time = 1.5
422    dispersity_index_window: float = 3.0  # minutes
423    noise_window_factor: float = 2.0  # times the peak width for detemining SN for EIC
424
425    # Parameters used for filtering mass features after peak picking
426    remove_redundant_mass_features: bool = False
427    redundant_scan_frequency_min: float = 0.1
428    redundant_feature_retain_n: int = 3
429    remove_mass_features_by_peak_metrics: bool = False
430    # note that this is a dictionary of dictionaries and set in __post_init__ instead of here
431    mass_feature_attribute_filter_dict: Dict = dataclasses.field(default_factory=dict)
432
433    # Parameters used for 2D peak picking
434    peak_picking_method: str = "by_format"
435    implemented_peak_picking_methods: tuple = (
436        "by_format",
437        "persistent homology",
438        "centroided_persistent_homology",
439    )
440
441    # Parameters used in persistent homology calculations
442    ph_smooth_it = 1
443    ph_smooth_radius_mz = 0
444    ph_smooth_radius_scan = 1
445    ph_inten_min_rel = 0.001
446    ph_persis_min_rel = 0.001
447    ph_inten_min_abs: float = 0.0
448
449    # Parameters used to cluster mass features
450    mass_feature_cluster_mz_tolerance_rel: float = 5e-6
451    mass_feature_cluster_rt_tolerance: float = 0.3
452
453    # Parameters used in associating MS1 and MS2 spectra to LCMS mass features and deconvoluting MS1 mass features
454    ms1_scans_to_average: int = 1
455    ms1_deconvolution_corr_min: float = 0.8
456    ms2_dda_rt_tolerance: float = 0.15
457    ms2_dda_mz_tolerance: float = 0.05
458
459    # Legacy MS2 spectral annotation aliases (not exported; prefer MSParameters.spectral_similarity_search)
460    ms2_min_fe_score: float = legacy_field(0.2)
461    search_as_lipids: bool = legacy_field(False)
462    include_fragment_types: bool = legacy_field(False)
463
464    # Parameters used for saving the data
465    export_profile_spectra: bool = False
466    export_eics: bool = True
467    export_unprocessed_ms1: bool = False
468    export_only_relevant_mass_spectra: bool = False
469
470    # Parameters used for verbose processing
471    verbose_processing: bool = True
472
473    def __post_init__(self):
474        # Set default values for mass_feature_attribute_filter_dict if empty
475        if not self.mass_feature_attribute_filter_dict:
476            self.mass_feature_attribute_filter_dict = {
477                "noise_score_max": {"value": 0.8, "operator": ">="},
478                "noise_score_min": {"value": 0.5, "operator": ">="},
479            }
480
481        # enforce datatype
482        for field in dataclasses.fields(self):
483            value = getattr(self, field.name)
484            if not isinstance(value, field.type):
485                value = field.type(value)
486                setattr(self, field.name, value)

Liquid chromatograph processing settings class

Attributes
  • scans (list or tuple, optional): List of select scan to average or a tuple containing the range to average. Default is (-1, -1).
  • eic_tolerance_ppm (float, optional): Mass tolerance in ppm for extracted ion chromatogram peak detection. Default is 5.
  • correct_eic_baseline (bool, optional): If True, correct the baseline of the extracted ion chromatogram. Default is True.
  • smooth_window (int, optional): Window size for smoothing the ion chromatogram (extracted or total). Default is 5.
  • smooth_method (str, optional): Smoothing method to use. See implemented_smooth_method for options. Default is 'savgol'.
  • implemented_smooth_method (tuple, optional): Smoothing methods that can be implemented. Default is ('savgol', 'hanning', 'blackman', 'bartlett', 'flat', 'boxcar').
  • savgol_pol_order (int, optional): Polynomial order for Savitzky-Golay smoothing. Default is 2.
  • consecutive_scan_min (int, optional): Minimum number of consecutive scans to consider for peak detection. Default is 0 for backwards compatibility, but a value of 3 is recommended.
  • peak_height_max_percent (float, optional): 1-100 % used for baseline detection use 0.1 for second_derivative and 10 for other methods. Default is 10.
  • peak_max_prominence_percent (float, optional): 1-100 % used for baseline detection. Default is 1.
  • peak_derivative_threshold (float, optional): Threshold for defining derivative crossing. Default is 0.0005.
  • min_peak_datapoints (float, optional): minimum data point to define a chromatografic peak. Default is 5.
  • noise_threshold_method (str, optional): Method for detecting noise threshold. Default is 'manual_relative_abundance'.
  • noise_threshold_methods_implemented (tuple, optional): Methods for detected noise threshold that can be implemented. Default is ('auto_relative_abundance', 'manual_relative_abundance', 'second_derivative').
  • peak_height_min_percent (float, optional): 0-100 % used for peak detection. Default is 0.1.
  • eic_signal_threshold (float, optional): 0-100 % used for extracted ion chromatogram peak detection. Default is 0.01.
  • eic_buffer_time (float, optional): Buffer time to add to the start and end of the plot of the extracted ion chromatogram, in minutes. Default is 1.5.
  • dispersity_index_window (float, optional): Dispersity index window size, in minutes. Default is 3.0.
  • noise_window_factor (float, optional): Factor to determine noise estimation window size relative to peak width. Larger values use wider windows for noise estimation. For example, a value of 2.0 uses a window size equal to twice the peak width (depending on it's start and end scans) on each side. Called within the LCMSMassFeature.calc_noise_score() method. Default is 2.0.
  • remove_redundant_mass_features (bool, optional): If True, remove redundant mass features that are likely contaminants based on their m/z values and scan frequency. Especially useful for HILIC data where signals do not return to baseline between peaks or for data with significant background noise. Called within the LC_Calculations.find_mass_features() method. Default is False.
  • redundant_scan_frequency_min (float, optional): Minimum fraction of scans that must contain the m/z to be considered a likely noise/contaminant when using remove_redundant_mass_features. Default is 0.1 (10% of scans).
  • redundant_feature_retain_n (int, optional): Number of features to retain in each group when using remove_redundant_mass_features. Default is 3.
  • remove_mass_features_by_peak_metrics (bool, optional): If True, remove mass features based on their peak metrics such as S/N, Gaussian similarity, dispersity index, and noise score. Called within the LC_Calculations.add_peak_metrics() method. Default is False.
  • mass_feature_attribute_filter_dict (dict, optional): Dictionary specifying filtering criteria for mass feature attributes. Each key is an attribute name, and each value is a dict with 'value' and 'operator' keys.

    Structure: {attribute_name: {'value': threshold, 'operator': comparison}}

    Available operators:

    • '>' or 'greater': Keep features where attribute > threshold
    • '<' or 'less': Keep features where attribute < threshold
    • '>=' or 'greater_equal': Keep features where attribute >= threshold
    • '<=' or 'less_equal': Keep features where attribute <= threshold

    Examples: { 'noise_score_max': {'value': 0.5, 'operator': '>'}, # Keep if noise_score_max > 0.5 'dispersity_index': {'value': 0.1, 'operator': '<'}, # Keep if dispersity_index < 0.1 'gaussian_similarity': {'value': 0.7, 'operator': '>='} # Keep if gaussian_similarity >= 0.7 }

    Available attributes include: 'noise_score', 'noise_score_min', 'noise_score_max', 'gaussian_similarity', 'tailing_factor', 'dispersity_index', 'half_height_width', 'intensity'. Default is {"noise_score_max": {"value": 0.8, "operator": ">="},"noise_score_min": {"value": 0.5, "operator": ">="}},

  • peak_picking_method (str, optional): Peak picking method to use. See implemented_peak_picking_methods for options. Default is 'by_format', which selects persistent homology when all scans at the requested MS level are profile and centroided persistent homology when all are centroid, then stores the concrete method on this setting so saved parameters record what was used.
  • implemented_peak_picking_methods (tuple, optional): Peak picking methods that can be implemented. Default is ('by_format', 'persistent homology', 'centroided_persistent_homology').
  • ph_smooth_it (int, optional): Number of iterations to use for smoothing prior to finding mass features. Used only for "persistent homology" peak picking method. Called within the PHCalculations.find_mass_features_ph() method. Default is 1.
  • ph_smooth_radius_mz (int, optional): Radius in m/z steps (not daltons) for smoothing prior to finding mass features. Used only for "persistent homology" peak picking method. Called within the PHCalculations.find_mass_features_ph() method. Default is 0.
  • ph_smooth_radius_scan (int, optional): Radius in scan steps for smoothing prior to finding mass features. Used only for "persistent homology" peak picking method. Called within the PHCalculations.find_mass_features_ph() method. Default is 1.
  • ph_inten_min_rel (float, optional): Relative minimum intensity to use for finding mass features for persistent homology. Used only for "persistent homology" peak picking method. Calculated as a fraction of the maximum intensity of the unprocessed profile data (mz, scan). Called within the PH_Calculations.find_mass_features() method. Default is 0.001.
  • ph_persis_min_rel (float, optional): Relative minimum persistence for retaining mass features. Used for both "persistent homology" and "centroided_persistent_homology" peak picking methods. Calculated as a fraction of the maximum intensity of the unprocessed profile data (mz, scan). Should be greater to or equal to ph_inten_min_rel. Called within the PH_Calculations.find_mass_features() method. Default is 0.001.
  • ph_inten_min_abs (float, optional): Absolute minimum intensity for points that enter persistent homology. Applied with ph_inten_min_rel on profile and centroided data. The relative floor is still a fraction of the unfiltered maximum. 0 disables the absolute floor. Default is 0.0.
  • mass_feature_cluster_mz_tolerance_rel (float, optional): Relative m/z tolerance to use for clustering mass features. Used for both "persistent homology" and "centroided_persistent_homology" peak picking methods. Called with the PHCalculations.cluster_mass_features() and the LCCalculations.deconvolute_ms1_mass_features() methods. Default is 5e-6 (5 ppm).
  • mass_feature_cluster_rt_tolerance (float, optional): Retention time tolerance to use for clustering mass features, in minutes. Used for both "persistent homology" and "centroided_persistent_homology" peak picking methods. Called with the PHCalculations.cluster_mass_features() and the LCCalculations.deconvolute_ms1_mass_features() methods. Default is 0.3.
  • ms1_scans_to_average (int, optional): Number of MS1 scans to average for mass-feature associated m/zs. Called within the LCMSBase.add_associated_ms1() method. Default is 1.
  • ms1_deconvolution_corr_min (float, optional): Minimum correlation to use for deconvoluting MS1 mass features. Called within the LCCalculations.deconvolute_ms1_mass_features() method. Default is 0.8.
  • ms2_dda_rt_tolerance (float, optional): Retention time tolerance to use for associating MS2 spectra to mass features, in minutes. Called within the LCMSBase.add_associated_ms2_dda() method. Default is 0.15.
  • ms2_dda_mz_tolerance (float, optional): Mass tolerance to use for associating MS2 spectra to mass features. Called within the LCMSBase.add_associated_ms2_dda() method. Default is 0.05.
  • ms2_min_fe_score (float, optional): Minimum flash entropy for retaining MS2 annotations. Legacy; prefer mass_spectrum["ms2"].spectral_similarity_search.ms2_min_fe_score. Default is 0.2.
  • search_as_lipids (bool, optional): Legacy lipid-search flag; prefer mass_spectrum["ms2"].spectral_similarity_search. Default is False.
  • include_fragment_types (bool, optional): Legacy fragment-type flag; prefer mass_spectrum["ms2"].spectral_similarity_search. Default is False.
  • export_profile_spectra (bool, optional): If True, export profile spectra data. Default is False.
  • export_eics (bool, optional): If True, export extracted ion chromatograms. Default is True.
  • export_unprocessed_ms1 (bool, optional): If True, export unprocessed MS1 data. Default is False.
  • export_only_relevant_mass_spectra (bool, optional): If True, export only mass spectra associated with detected mass features: specifically the apex MS1 scan for each mass feature and the best MS2 scan for each mass feature (if available). If False, export all mass spectra. This parameter reduces HDF5 file size by excluding non-feature spectra. Default is False (backwards compatible - exports all spectra).
  • verbose_processing (bool, optional): If True, print verbose processing information. Default is True.
LiquidChromatographSetting( scans: list | tuple = (-1, -1), eic_tolerance_ppm: float = 5, smooth_window: int = 5, smooth_method: str = 'savgol', implemented_smooth_method: tuple = ('savgol', 'hanning', 'blackman', 'bartlett', 'flat', 'boxcar'), savgol_pol_order: int = 2, consecutive_scan_min: int = 0, peak_height_max_percent: float = 10, peak_max_prominence_percent: float = 1, peak_derivative_threshold: float = 0.0005, min_peak_datapoints: float = 5, noise_threshold_method: str = 'manual_relative_abundance', noise_threshold_methods_implemented: tuple = ('auto_relative_abundance', 'manual_relative_abundance', 'second_derivative'), peak_height_min_percent: float = 0.1, eic_signal_threshold: float = 0.01, dispersity_index_window: float = 3.0, noise_window_factor: float = 2.0, remove_redundant_mass_features: bool = False, redundant_scan_frequency_min: float = 0.1, redundant_feature_retain_n: int = 3, remove_mass_features_by_peak_metrics: bool = False, mass_feature_attribute_filter_dict: Dict = <factory>, peak_picking_method: str = 'by_format', implemented_peak_picking_methods: tuple = ('by_format', 'persistent homology', 'centroided_persistent_homology'), ph_inten_min_abs: float = 0.0, mass_feature_cluster_mz_tolerance_rel: float = 5e-06, mass_feature_cluster_rt_tolerance: float = 0.3, ms1_scans_to_average: int = 1, ms1_deconvolution_corr_min: float = 0.8, ms2_dda_rt_tolerance: float = 0.15, ms2_dda_mz_tolerance: float = 0.05, ms2_min_fe_score: float = 0.2, search_as_lipids: bool = False, include_fragment_types: bool = False, export_profile_spectra: bool = False, export_eics: bool = True, export_unprocessed_ms1: bool = False, export_only_relevant_mass_spectra: bool = False, verbose_processing: bool = True)
scans: list | tuple = (-1, -1)
eic_tolerance_ppm: float = 5
correct_eic_baseline = True
smooth_window: int = 5
smooth_method: str = 'savgol'
implemented_smooth_method: tuple = ('savgol', 'hanning', 'blackman', 'bartlett', 'flat', 'boxcar')
savgol_pol_order: int = 2
consecutive_scan_min: int = 0
peak_height_max_percent: float = 10
peak_max_prominence_percent: float = 1
peak_derivative_threshold: float = 0.0005
min_peak_datapoints: float = 5
noise_threshold_method: str = 'manual_relative_abundance'
noise_threshold_methods_implemented: tuple = ('auto_relative_abundance', 'manual_relative_abundance', 'second_derivative')
peak_height_min_percent: float = 0.1
eic_signal_threshold: float = 0.01
eic_buffer_time = 1.5
dispersity_index_window: float = 3.0
noise_window_factor: float = 2.0
remove_redundant_mass_features: bool = False
redundant_scan_frequency_min: float = 0.1
redundant_feature_retain_n: int = 3
remove_mass_features_by_peak_metrics: bool = False
mass_feature_attribute_filter_dict: Dict
peak_picking_method: str = 'by_format'
implemented_peak_picking_methods: tuple = ('by_format', 'persistent homology', 'centroided_persistent_homology')
ph_smooth_it = 1
ph_smooth_radius_mz = 0
ph_smooth_radius_scan = 1
ph_inten_min_rel = 0.001
ph_persis_min_rel = 0.001
ph_inten_min_abs: float = 0.0
mass_feature_cluster_mz_tolerance_rel: float = 5e-06
mass_feature_cluster_rt_tolerance: float = 0.3
ms1_scans_to_average: int = 1
ms1_deconvolution_corr_min: float = 0.8
ms2_dda_rt_tolerance: float = 0.15
ms2_dda_mz_tolerance: float = 0.05
ms2_min_fe_score: float = 0.2
search_as_lipids: bool = False
include_fragment_types: bool = False
export_profile_spectra: bool = False
export_eics: bool = True
export_unprocessed_ms1: bool = False
export_only_relevant_mass_spectra: bool = False
verbose_processing: bool = True
@dataclasses.dataclass
class SpectralSimilaritySearchSettings:
489@dataclasses.dataclass
490class SpectralSimilaritySearchSettings:
491    """Parameters for using spectral similarity to search spectra against a library of reference spectra (including within molecular networking).
492
493    Lives on :class:`~corems.encapsulation.factory.parameters.MSParameters`
494    as ``spectral_similarity_search`` (e.g. ``lcms.parameters.mass_spectrum["ms2"].spectral_similarity_search``).
495
496    Not used for MS2 *molecular formula* search
497    (``mass_spectrum[key].molecular_search``).
498    """
499
500    # --- FlashEntropy library build (intensity normalize always on) ---
501    max_ms2_tolerance_in_da: float = 0.01
502    max_indexed_mz: float = 3000.0
503    precursor_ions_removal_da: float | None = None
504    noise_threshold: float = 0.0
505
506    # --- Annotation ---
507    ms2_min_fe_score: float = 0.2
508    include_fragment_types: bool = False
509    search_as_lipids: bool = False
510    peak_sep_da: float | None = None
511
512    # --- Molecular networking ---
513    search_type: str = "open"
514    additional_similarities: list = dataclasses.field(
515        default_factory=lambda: ["cosine"]
516    )
517    similarity_thresholds: dict = dataclasses.field(default_factory=dict)
518    ms1_tolerance_da: float | None = None
519    ms2_tolerance_da: float | None = None
520    entropy_threshold_low: float | None = None
521    library_similarity_threshold: float = 0.3
522    hydrate_library_similarities: bool = False
523
524    def __post_init__(self):
525        if self.additional_similarities is not None:
526            self.additional_similarities = list(self.additional_similarities)
527        if self.similarity_thresholds is not None:
528            self.similarity_thresholds = dict(self.similarity_thresholds)
529
530    @property
531    def min_ms2_difference_in_da(self) -> float:
532        """Minimum peak separation (Da); always ``2 * max_ms2_tolerance_in_da``."""
533        return 2.0 * float(self.max_ms2_tolerance_in_da)
534
535    def copy(self) -> "SpectralSimilaritySearchSettings":
536        """Return a copy with mutable list/dict fields isolated."""
537        return dataclasses.replace(
538            self,
539            additional_similarities=list(self.additional_similarities),
540            similarity_thresholds=dict(self.similarity_thresholds),
541        )
542
543    def as_fe_kwargs(self) -> dict:
544        """FlashEntropy library-build kwargs (historical ``fe_kwargs`` shape)."""
545        return {
546            "min_ms2_difference_in_da": self.min_ms2_difference_in_da,
547            "max_ms2_tolerance_in_da": self.max_ms2_tolerance_in_da,
548            "max_indexed_mz": self.max_indexed_mz,
549            "precursor_ions_removal_da": self.precursor_ions_removal_da,
550            "noise_threshold": self.noise_threshold,
551        }
552
553    @property
554    def resolved_peak_sep_da(self) -> float:
555        """Peak separation (Da) for annotation search."""
556        if self.peak_sep_da is not None:
557            return float(self.peak_sep_da)
558        return float(self.min_ms2_difference_in_da)

Parameters for using spectral similarity to search spectra against a library of reference spectra (including within molecular networking).

Lives on ~corems.encapsulation.factory.parameters.MSParameters as spectral_similarity_search (e.g. lcms.parameters.mass_spectrum["ms2"].spectral_similarity_search).

Not used for MS2 molecular formula search (mass_spectrum[key].molecular_search).

SpectralSimilaritySearchSettings( max_ms2_tolerance_in_da: float = 0.01, max_indexed_mz: float = 3000.0, precursor_ions_removal_da: float | None = None, noise_threshold: float = 0.0, ms2_min_fe_score: float = 0.2, include_fragment_types: bool = False, search_as_lipids: bool = False, peak_sep_da: float | None = None, search_type: str = 'open', additional_similarities: list = <factory>, similarity_thresholds: dict = <factory>, ms1_tolerance_da: float | None = None, ms2_tolerance_da: float | None = None, entropy_threshold_low: float | None = None, library_similarity_threshold: float = 0.3, hydrate_library_similarities: bool = False)
max_ms2_tolerance_in_da: float = 0.01
max_indexed_mz: float = 3000.0
precursor_ions_removal_da: float | None = None
noise_threshold: float = 0.0
ms2_min_fe_score: float = 0.2
include_fragment_types: bool = False
search_as_lipids: bool = False
peak_sep_da: float | None = None
search_type: str = 'open'
additional_similarities: list
similarity_thresholds: dict
ms1_tolerance_da: float | None = None
ms2_tolerance_da: float | None = None
entropy_threshold_low: float | None = None
library_similarity_threshold: float = 0.3
hydrate_library_similarities: bool = False
min_ms2_difference_in_da: float
530    @property
531    def min_ms2_difference_in_da(self) -> float:
532        """Minimum peak separation (Da); always ``2 * max_ms2_tolerance_in_da``."""
533        return 2.0 * float(self.max_ms2_tolerance_in_da)

Minimum peak separation (Da); always 2 * max_ms2_tolerance_in_da.

def copy( self) -> SpectralSimilaritySearchSettings:
535    def copy(self) -> "SpectralSimilaritySearchSettings":
536        """Return a copy with mutable list/dict fields isolated."""
537        return dataclasses.replace(
538            self,
539            additional_similarities=list(self.additional_similarities),
540            similarity_thresholds=dict(self.similarity_thresholds),
541        )

Return a copy with mutable list/dict fields isolated.

def as_fe_kwargs(self) -> dict:
543    def as_fe_kwargs(self) -> dict:
544        """FlashEntropy library-build kwargs (historical ``fe_kwargs`` shape)."""
545        return {
546            "min_ms2_difference_in_da": self.min_ms2_difference_in_da,
547            "max_ms2_tolerance_in_da": self.max_ms2_tolerance_in_da,
548            "max_indexed_mz": self.max_indexed_mz,
549            "precursor_ions_removal_da": self.precursor_ions_removal_da,
550            "noise_threshold": self.noise_threshold,
551        }

FlashEntropy library-build kwargs (historical fe_kwargs shape).

resolved_peak_sep_da: float
553    @property
554    def resolved_peak_sep_da(self) -> float:
555        """Peak separation (Da) for annotation search."""
556        if self.peak_sep_da is not None:
557            return float(self.peak_sep_da)
558        return float(self.min_ms2_difference_in_da)

Peak separation (Da) for annotation search.

@dataclasses.dataclass
class MassSpectrumSetting:
561@dataclasses.dataclass
562class MassSpectrumSetting:
563    """Mass spectrum processing settings class
564
565    Attributes
566    ----------
567    noise_threshold_method : str, optional
568        Method for detecting noise threshold. Default is 'by_format', which
569        selects 'log' for a profile spectrum and 'relative_abundance' for
570        a centroid spectrum, then stores that concrete method on this
571        setting so saved parameters record what was used.
572    noise_threshold_methods_implemented : tuple, optional
573        Methods for detected noise threshold that can be implemented. Default is ('by_format', 'minima', 'signal_noise', 'relative_abundance', 'absolute_abundance', 'log').
574    noise_threshold_min_std : int, optional
575        Minumum value for noise thresholding when using 'minima' noise threshold method. Default is 6.
576    noise_threshold_min_s2n : float, optional
577        Minimum value for noise thresholding when using 'signal_noise' noise threshold method. Default is 4.
578    noise_threshold_min_relative_abundance : float, optional
579        Minimum value for noise thresholding when using 'relative_abundance' noise threshold method. Note that this is a percentage value. Default is 6 (6%).
580    noise_threshold_absolute_abundance : float, optional
581        Minimum value for noise thresholding when using 'absolute_abundance' noise threshold method. Default is 1_000_000.
582    noise_threshold_log_nsigma : int, optional
583        Number of standard deviations to use when using 'log' noise threshold method. Default is 6.
584    noise_threshold_log_nsigma_corr_factor : float, optional
585        Correction factor for log noise threshold method. Default is 0.463.
586    noise_threshold_log_nsigma_bins : int, optional
587        Number of bins to use for histogram when using 'log' noise threshold method. Default is 500.
588    noise_min_mz : float, optional
589        Minimum m/z to use for noise thresholding. Default is 50.0.
590    noise_max_mz : float, optional
591        Maximum m/z to use for noise thresholding. Default is 1200.0.
592    min_picking_mz : float, optional
593        Minimum m/z to use for peak picking. Default is 50.0.
594    max_picking_mz : float, optional
595        Maximum m/z to use for peak picking. Default is 1200.0.
596    picking_point_extrapolate : int, optional
597        How many data points (in each direction) to extrapolate the mz axis and 0 pad the abundance axis. Default is 3.
598        Recommend not changing this value unless necessary.
599    calib_minimize_method : str, optional
600        Minimization method to use for calibration. Default is 'Powell'.
601    calib_pol_order : int, optional
602        Polynomial order to use for calibration. Default is 2.
603    max_calib_ppm_error : float, optional
604        Maximum ppm error to use for calibration. Default is 1.0.
605    min_calib_ppm_error : float, optional
606        Minimum ppm error to use for calibration. Default is -1.0.
607    calib_sn_threshold : float, optional
608        Signal to noise threshold to use for calibration. Default is 2.0.
609    calibration_ref_match_method: string, optional
610        Method for matching reference masses with measured masses for recalibration. Default is 'legacy'.
611    calibration_ref_match_tolerance: float, optional
612        If using the new method for calibration reference mass matching, this tolerance is the initial matching tolerance. Default is 0.003
613    do_calibration : bool, optional
614        If True, perform calibration. Default is True.
615    verbose_processing : bool, optional
616        If True, print verbose processing information. Default is True.
617    """
618
619    noise_threshold_method: str = "by_format"
620
621    noise_threshold_methods_implemented: tuple = (
622        "by_format",
623        "minima",
624        "signal_noise",
625        "relative_abundance",
626        "absolute_abundance",
627        "log",
628    )
629
630    noise_threshold_min_std: int = 6  # when using 'minima' method
631
632    noise_threshold_min_s2n: float = 4  # when using 'signal_noise' method
633
634    noise_threshold_min_relative_abundance: float = (
635        6  # from 0-100, when using 'relative_abundance' method
636    )
637
638    noise_threshold_absolute_abundance: float = (
639        1_000_000  # when using 'absolute_abundance' method
640    )
641
642    noise_threshold_log_nsigma: int = 6  # when using 'log' method
643    noise_threshold_log_nsigma_corr_factor: float = 0.463  # mFT is 0.463, aFT is 1.0
644    noise_threshold_log_nsigma_bins: int = 500  # bins for the histogram for the noise
645
646    noise_min_mz: float = 50.0
647    noise_max_mz: float = 1200.0
648
649    min_picking_mz: float = 50.0
650    max_picking_mz: float = 1200.0
651
652    # How many data points (in each direction) to extrapolate the mz axis and 0 pad the abundance axis
653    # This will fix peak picking at spectrum limit issues
654    #  0 to keep normal behaviour, typical value 3 to fix
655    picking_point_extrapolate: int = 3
656
657    calib_minimize_method: str = "Powell"
658    calib_pol_order: int = 2
659    max_calib_ppm_error: float = 1.0
660    min_calib_ppm_error: float = -1.0
661    calib_sn_threshold: float = 2.0
662    calibration_ref_match_method: str = "merged"
663    calibration_ref_match_method_implemented: tuple = ("legacy", "merged")
664    calibration_ref_match_tolerance: float = 0.003
665    calibration_ref_match_std_raw_error_limit: float = 1.5
666    # calib_ref_mzs: list = [0]
667
668    do_calibration: bool = True
669    verbose_processing: bool = True
670
671    def __post_init__(self):
672        # enforce datatype
673        for field in dataclasses.fields(self):
674            value = getattr(self, field.name)
675            if not isinstance(value, field.type):
676                value = field.type(value)
677                setattr(self, field.name, value)

Mass spectrum processing settings class

Attributes
  • noise_threshold_method (str, optional): Method for detecting noise threshold. Default is 'by_format', which selects 'log' for a profile spectrum and 'relative_abundance' for a centroid spectrum, then stores that concrete method on this setting so saved parameters record what was used.
  • noise_threshold_methods_implemented (tuple, optional): Methods for detected noise threshold that can be implemented. Default is ('by_format', 'minima', 'signal_noise', 'relative_abundance', 'absolute_abundance', 'log').
  • noise_threshold_min_std (int, optional): Minumum value for noise thresholding when using 'minima' noise threshold method. Default is 6.
  • noise_threshold_min_s2n (float, optional): Minimum value for noise thresholding when using 'signal_noise' noise threshold method. Default is 4.
  • noise_threshold_min_relative_abundance (float, optional): Minimum value for noise thresholding when using 'relative_abundance' noise threshold method. Note that this is a percentage value. Default is 6 (6%).
  • noise_threshold_absolute_abundance (float, optional): Minimum value for noise thresholding when using 'absolute_abundance' noise threshold method. Default is 1_000_000.
  • noise_threshold_log_nsigma (int, optional): Number of standard deviations to use when using 'log' noise threshold method. Default is 6.
  • noise_threshold_log_nsigma_corr_factor (float, optional): Correction factor for log noise threshold method. Default is 0.463.
  • noise_threshold_log_nsigma_bins (int, optional): Number of bins to use for histogram when using 'log' noise threshold method. Default is 500.
  • noise_min_mz (float, optional): Minimum m/z to use for noise thresholding. Default is 50.0.
  • noise_max_mz (float, optional): Maximum m/z to use for noise thresholding. Default is 1200.0.
  • min_picking_mz (float, optional): Minimum m/z to use for peak picking. Default is 50.0.
  • max_picking_mz (float, optional): Maximum m/z to use for peak picking. Default is 1200.0.
  • picking_point_extrapolate (int, optional): How many data points (in each direction) to extrapolate the mz axis and 0 pad the abundance axis. Default is 3. Recommend not changing this value unless necessary.
  • calib_minimize_method (str, optional): Minimization method to use for calibration. Default is 'Powell'.
  • calib_pol_order (int, optional): Polynomial order to use for calibration. Default is 2.
  • max_calib_ppm_error (float, optional): Maximum ppm error to use for calibration. Default is 1.0.
  • min_calib_ppm_error (float, optional): Minimum ppm error to use for calibration. Default is -1.0.
  • calib_sn_threshold (float, optional): Signal to noise threshold to use for calibration. Default is 2.0.
  • calibration_ref_match_method (string, optional): Method for matching reference masses with measured masses for recalibration. Default is 'legacy'.
  • calibration_ref_match_tolerance (float, optional): If using the new method for calibration reference mass matching, this tolerance is the initial matching tolerance. Default is 0.003
  • do_calibration (bool, optional): If True, perform calibration. Default is True.
  • verbose_processing (bool, optional): If True, print verbose processing information. Default is True.
MassSpectrumSetting( noise_threshold_method: str = 'by_format', noise_threshold_methods_implemented: tuple = ('by_format', 'minima', 'signal_noise', 'relative_abundance', 'absolute_abundance', 'log'), noise_threshold_min_std: int = 6, noise_threshold_min_s2n: float = 4, noise_threshold_min_relative_abundance: float = 6, noise_threshold_absolute_abundance: float = 1000000, noise_threshold_log_nsigma: int = 6, noise_threshold_log_nsigma_corr_factor: float = 0.463, noise_threshold_log_nsigma_bins: int = 500, noise_min_mz: float = 50.0, noise_max_mz: float = 1200.0, min_picking_mz: float = 50.0, max_picking_mz: float = 1200.0, picking_point_extrapolate: int = 3, calib_minimize_method: str = 'Powell', calib_pol_order: int = 2, max_calib_ppm_error: float = 1.0, min_calib_ppm_error: float = -1.0, calib_sn_threshold: float = 2.0, calibration_ref_match_method: str = 'merged', calibration_ref_match_method_implemented: tuple = ('legacy', 'merged'), calibration_ref_match_tolerance: float = 0.003, calibration_ref_match_std_raw_error_limit: float = 1.5, do_calibration: bool = True, verbose_processing: bool = True)
noise_threshold_method: str = 'by_format'
noise_threshold_methods_implemented: tuple = ('by_format', 'minima', 'signal_noise', 'relative_abundance', 'absolute_abundance', 'log')
noise_threshold_min_std: int = 6
noise_threshold_min_s2n: float = 4
noise_threshold_min_relative_abundance: float = 6
noise_threshold_absolute_abundance: float = 1000000
noise_threshold_log_nsigma: int = 6
noise_threshold_log_nsigma_corr_factor: float = 0.463
noise_threshold_log_nsigma_bins: int = 500
noise_min_mz: float = 50.0
noise_max_mz: float = 1200.0
min_picking_mz: float = 50.0
max_picking_mz: float = 1200.0
picking_point_extrapolate: int = 3
calib_minimize_method: str = 'Powell'
calib_pol_order: int = 2
max_calib_ppm_error: float = 1.0
min_calib_ppm_error: float = -1.0
calib_sn_threshold: float = 2.0
calibration_ref_match_method: str = 'merged'
calibration_ref_match_method_implemented: tuple = ('legacy', 'merged')
calibration_ref_match_tolerance: float = 0.003
calibration_ref_match_std_raw_error_limit: float = 1.5
do_calibration: bool = True
verbose_processing: bool = True
@dataclasses.dataclass
class MassSpecPeakSetting:
680@dataclasses.dataclass
681class MassSpecPeakSetting:
682    """Mass spectrum peak processing settings class
683
684    Attributes
685    ----------
686    kendrick_base : Dict, optional
687        Dictionary specifying the elements and their counts in the Kendrick base.
688        Defaults to {'C': 1, 'H': 2}.
689    kendrick_rounding_method : str, optional
690        Method for calculating the nominal Kendrick mass. Valid values are 'floor', 'ceil', or 'round'.
691        Defaults to 'floor'.
692    implemented_kendrick_rounding_methods : tuple
693        Tuple of valid rounding methods for calculating the nominal Kendrick mass.
694        Defaults to ('floor', 'ceil', 'round').
695    peak_derivative_threshold : float, optional
696        Threshold for defining derivative crossing. Should be a value between 0 and 1.
697        Defaults to 0.0.
698    peak_min_prominence_percent : float, optional
699        Minimum prominence percentage used for peak detection. Should be a value between 1 and 100.
700        Defaults to 0.1.
701    min_peak_datapoints : float, optional
702        Minimum number of data points used for peak detection. Should be a value between 0 and infinity.
703        Defaults to 5.
704    peak_max_prominence_percent : float, optional
705        Maximum prominence percentage used for baseline detection. Should be a value between 1 and 100.
706        Defaults to 0.1.
707    peak_height_max_percent : float, optional
708        Maximum height percentage used for baseline detection. Should be a value between 1 and 100.
709        Defaults to 10.
710    legacy_resolving_power : bool, optional
711        Flag indicating whether to use the legacy (CoreMS v1) resolving power calculation.
712        Defaults to True.
713    legacy_centroid_polyfit : bool, optional
714        Use legacy (numpy polyfit) to fit centroid
715        Default false.
716    """
717
718    kendrick_base: Dict = dataclasses.field(default_factory=dict)
719
720    kendrick_rounding_method: str = "floor"  # 'floor', 'ceil' or 'round' are valid methods for calculating nominal kendrick mass
721
722    implemented_kendrick_rounding_methods: tuple = ("floor", "ceil", "round")
723
724    peak_derivative_threshold: float = 0.0  # define derivative crossing threshould 0-1
725
726    peak_min_prominence_percent: float = 0.1  # 1-100 % used for peak detection
727
728    min_peak_datapoints: float = 5  # 0-inf used for peak detection
729
730    peak_max_prominence_percent: float = 0.1  # 1-100 % used for baseline detection
731
732    peak_height_max_percent: float = 10  # 1-100 % used for baseline detection
733
734    legacy_resolving_power: bool = (
735        True  # Use the legacy (CoreMS v1) resolving power calculation (True)
736    )
737
738    legacy_centroid_polyfit: bool = False
739
740    def __post_init__(self):
741        # default to CH2
742        if not self.kendrick_base:
743            self.kendrick_base = {"C": 1, "H": 2}
744        # enforce datatype
745        for field in dataclasses.fields(self):
746            value = getattr(self, field.name)
747            if not isinstance(value, field.type):
748                value = field.type(value)
749                setattr(self, field.name, value)

Mass spectrum peak processing settings class

Attributes
  • kendrick_base (Dict, optional): Dictionary specifying the elements and their counts in the Kendrick base. Defaults to {'C': 1, 'H': 2}.
  • kendrick_rounding_method (str, optional): Method for calculating the nominal Kendrick mass. Valid values are 'floor', 'ceil', or 'round'. Defaults to 'floor'.
  • implemented_kendrick_rounding_methods (tuple): Tuple of valid rounding methods for calculating the nominal Kendrick mass. Defaults to ('floor', 'ceil', 'round').
  • peak_derivative_threshold (float, optional): Threshold for defining derivative crossing. Should be a value between 0 and 1. Defaults to 0.0.
  • peak_min_prominence_percent (float, optional): Minimum prominence percentage used for peak detection. Should be a value between 1 and 100. Defaults to 0.1.
  • min_peak_datapoints (float, optional): Minimum number of data points used for peak detection. Should be a value between 0 and infinity. Defaults to 5.
  • peak_max_prominence_percent (float, optional): Maximum prominence percentage used for baseline detection. Should be a value between 1 and 100. Defaults to 0.1.
  • peak_height_max_percent (float, optional): Maximum height percentage used for baseline detection. Should be a value between 1 and 100. Defaults to 10.
  • legacy_resolving_power (bool, optional): Flag indicating whether to use the legacy (CoreMS v1) resolving power calculation. Defaults to True.
  • legacy_centroid_polyfit (bool, optional): Use legacy (numpy polyfit) to fit centroid Default false.
MassSpecPeakSetting( kendrick_base: Dict = <factory>, kendrick_rounding_method: str = 'floor', implemented_kendrick_rounding_methods: tuple = ('floor', 'ceil', 'round'), peak_derivative_threshold: float = 0.0, peak_min_prominence_percent: float = 0.1, min_peak_datapoints: float = 5, peak_max_prominence_percent: float = 0.1, peak_height_max_percent: float = 10, legacy_resolving_power: bool = True, legacy_centroid_polyfit: bool = False)
kendrick_base: Dict
kendrick_rounding_method: str = 'floor'
implemented_kendrick_rounding_methods: tuple = ('floor', 'ceil', 'round')
peak_derivative_threshold: float = 0.0
peak_min_prominence_percent: float = 0.1
min_peak_datapoints: float = 5
peak_max_prominence_percent: float = 0.1
peak_height_max_percent: float = 10
legacy_resolving_power: bool = True
legacy_centroid_polyfit: bool = False
@dataclasses.dataclass
class GasChromatographSetting:
752@dataclasses.dataclass
753class GasChromatographSetting:
754    """Gas chromatograph processing settings class
755
756    Attributes
757    ----------
758    use_deconvolution : bool, optional
759        If True, use deconvolution. Default is False.
760    implemented_smooth_method : tuple, optional
761        Smoothing methods that can be implemented. Default is ('savgol', 'hanning', 'blackman', 'bartlett', 'flat', 'boxcar').
762    smooth_window : int, optional
763        Window size for smoothing the ion chromatogram. Default is 5.
764    smooth_method : str, optional
765        Smoothing method to use. Default is 'savgol'. Other options are 'hanning', 'blackman', 'bartlett', 'flat', 'boxcar'.
766    savgol_pol_order : int, optional
767        Polynomial order for Savitzky-Golay smoothing. Default is 2.
768    peak_derivative_threshold : float, optional
769        Threshold for defining derivative crossing. Should be a value between 0 and 1.
770        Defaults to 0.0005.
771    peak_height_max_percent : float, optional
772        Maximum height percentage used for baseline detection. Should be a value between 1 and 100.
773        Defaults to 10.
774    peak_max_prominence_percent : float, optional
775        Maximum prominence percentage used for baseline detection. Should be a value between 1 and 100.
776        Defaults to 1.
777    min_peak_datapoints : float, optional
778        Minimum number of data points used for peak detection. Should be a value between 0 and infinity.
779        Defaults to 5.
780    max_peak_width : float, optional
781        Maximum peak width used for peak detection. Should be a value between 0 and infinity.
782        Defaults to 0.1.
783    noise_threshold_method : str, optional
784        Method for detecting noise threshold. Default is 'manual_relative_abundance'.
785    noise_threshold_methods_implemented : tuple, optional
786        Methods for detected noise threshold that can be implemented. Default is ('auto_relative_abundance', 'manual_relative_abundance', 'second_derivative').
787    std_noise_threshold : int, optional
788        Default is 3.
789    peak_height_min_percent : float, optional
790        0-100 % used for peak detection. Default is 0.1.
791    peak_min_prominence_percent : float, optional
792        0-100 % used for peak detection. Default is 0.1.
793    eic_signal_threshold : float, optional
794        0-100 % used for extracted ion chromatogram peak detection. Default is 0.01.
795    max_rt_distance : float, optional
796        Maximum distance allowance for hierarchical cluster, in minutes. Default is 0.025.
797    verbose_processing : bool, optional
798        If True, print verbose processing information. Default is True.
799    """
800
801    use_deconvolution: bool = False
802
803    implemented_smooth_method: tuple = (
804        "savgol",
805        "hanning",
806        "blackman",
807        "bartlett",
808        "flat",
809        "boxcar",
810    )
811
812    smooth_window: int = 5
813
814    smooth_method: str = "savgol"
815
816    savgol_pol_order: int = 2
817
818    peak_derivative_threshold: float = 0.0005
819
820    peak_height_max_percent: float = 10  # 1-100 % used for baseline detection use 0.1 for second_derivative and 10 for other methods
821
822    peak_max_prominence_percent: float = 1  # 1-100 % used for baseline detection
823
824    min_peak_datapoints: float = 5
825
826    max_peak_width: float = 0.1
827
828    noise_threshold_method: str = "manual_relative_abundance"
829
830    noise_threshold_methods_implemented: tuple = (
831        "auto_relative_abundance",
832        "manual_relative_abundance",
833        "second_derivative",
834    )
835
836    std_noise_threshold: int = 3
837
838    peak_height_min_percent: float = 0.1  # 0-100 % used for peak detection
839
840    peak_min_prominence_percent: float = 0.1  # 0-100 % used for peak detection
841
842    eic_signal_threshold: float = (
843        0.01  # 0-100 % used for extracted ion chromatogram peak detection
844    )
845
846    max_rt_distance: float = (
847        0.025  # minutes, max distance allowance hierarchical clutter
848    )
849
850    verbose_processing: bool = True
851
852    def __post_init__(self):
853        # enforce datatype
854        for field in dataclasses.fields(self):
855            value = getattr(self, field.name)
856            if not isinstance(value, field.type):
857                value = field.type(value)
858                setattr(self, field.name, value)

Gas chromatograph processing settings class

Attributes
  • use_deconvolution (bool, optional): If True, use deconvolution. Default is False.
  • implemented_smooth_method (tuple, optional): Smoothing methods that can be implemented. Default is ('savgol', 'hanning', 'blackman', 'bartlett', 'flat', 'boxcar').
  • smooth_window (int, optional): Window size for smoothing the ion chromatogram. Default is 5.
  • smooth_method (str, optional): Smoothing method to use. Default is 'savgol'. Other options are 'hanning', 'blackman', 'bartlett', 'flat', 'boxcar'.
  • savgol_pol_order (int, optional): Polynomial order for Savitzky-Golay smoothing. Default is 2.
  • peak_derivative_threshold (float, optional): Threshold for defining derivative crossing. Should be a value between 0 and 1. Defaults to 0.0005.
  • peak_height_max_percent (float, optional): Maximum height percentage used for baseline detection. Should be a value between 1 and 100. Defaults to 10.
  • peak_max_prominence_percent (float, optional): Maximum prominence percentage used for baseline detection. Should be a value between 1 and 100. Defaults to 1.
  • min_peak_datapoints (float, optional): Minimum number of data points used for peak detection. Should be a value between 0 and infinity. Defaults to 5.
  • max_peak_width (float, optional): Maximum peak width used for peak detection. Should be a value between 0 and infinity. Defaults to 0.1.
  • noise_threshold_method (str, optional): Method for detecting noise threshold. Default is 'manual_relative_abundance'.
  • noise_threshold_methods_implemented (tuple, optional): Methods for detected noise threshold that can be implemented. Default is ('auto_relative_abundance', 'manual_relative_abundance', 'second_derivative').
  • std_noise_threshold (int, optional): Default is 3.
  • peak_height_min_percent (float, optional): 0-100 % used for peak detection. Default is 0.1.
  • peak_min_prominence_percent (float, optional): 0-100 % used for peak detection. Default is 0.1.
  • eic_signal_threshold (float, optional): 0-100 % used for extracted ion chromatogram peak detection. Default is 0.01.
  • max_rt_distance (float, optional): Maximum distance allowance for hierarchical cluster, in minutes. Default is 0.025.
  • verbose_processing (bool, optional): If True, print verbose processing information. Default is True.
GasChromatographSetting( use_deconvolution: bool = False, implemented_smooth_method: tuple = ('savgol', 'hanning', 'blackman', 'bartlett', 'flat', 'boxcar'), smooth_window: int = 5, smooth_method: str = 'savgol', savgol_pol_order: int = 2, peak_derivative_threshold: float = 0.0005, peak_height_max_percent: float = 10, peak_max_prominence_percent: float = 1, min_peak_datapoints: float = 5, max_peak_width: float = 0.1, noise_threshold_method: str = 'manual_relative_abundance', noise_threshold_methods_implemented: tuple = ('auto_relative_abundance', 'manual_relative_abundance', 'second_derivative'), std_noise_threshold: int = 3, peak_height_min_percent: float = 0.1, peak_min_prominence_percent: float = 0.1, eic_signal_threshold: float = 0.01, max_rt_distance: float = 0.025, verbose_processing: bool = True)
use_deconvolution: bool = False
implemented_smooth_method: tuple = ('savgol', 'hanning', 'blackman', 'bartlett', 'flat', 'boxcar')
smooth_window: int = 5
smooth_method: str = 'savgol'
savgol_pol_order: int = 2
peak_derivative_threshold: float = 0.0005
peak_height_max_percent: float = 10
peak_max_prominence_percent: float = 1
min_peak_datapoints: float = 5
max_peak_width: float = 0.1
noise_threshold_method: str = 'manual_relative_abundance'
noise_threshold_methods_implemented: tuple = ('auto_relative_abundance', 'manual_relative_abundance', 'second_derivative')
std_noise_threshold: int = 3
peak_height_min_percent: float = 0.1
peak_min_prominence_percent: float = 0.1
eic_signal_threshold: float = 0.01
max_rt_distance: float = 0.025
verbose_processing: bool = True
@dataclasses.dataclass
class CompoundSearchSettings:
861@dataclasses.dataclass
862class CompoundSearchSettings:
863    """Settings for compound search
864
865    Attributes
866    ----------
867    url_database : str, optional
868        URL for the database. Default is 'sqlite:///db/pnnl_lowres_gcms_compounds.sqlite'.
869    ri_search_range : float, optional
870        Retention index search range. Default is 35.
871    rt_search_range : float, optional
872        Retention time search range, in minutes. Default is 1.0.
873    correlation_threshold : float, optional
874        Threshold for correlation for spectral similarity. Default is 0.5.
875    score_threshold : float, optional
876        Threshold for compsite score. Default is 0.0.
877    ri_spacing : float, optional
878        Retention index spacing. Default is 200.
879    ri_std : float, optional
880        Retention index standard deviation. Default is 3.
881    ri_calibration_compound_names : list, optional
882        List of compound names to use for retention index calibration. Default is ['Methyl Caprylate', 'Methyl Caprate', 'Methyl Pelargonate', 'Methyl Laurate', 'Methyl Myristate', 'Methyl Palmitate', 'Methyl Stearate', 'Methyl Eicosanoate', 'Methyl Docosanoate', 'Methyl Linocerate', 'Methyl Hexacosanoate', 'Methyl Octacosanoate', 'Methyl Triacontanoate'].
883
884    """
885
886    url_database: str = "postgresql+psycopg://coremsappdb:coremsapppnnl@localhost:5432/lowres"  # 'postgresql+psycopg://postgres:labthomson0102@172.22.113.27:5432/GCMS' # 'sqlite:///db/pnnl_lowres_gcms_compounds.sqlite'
887
888    ri_search_range: float = 35
889
890    rt_search_range: float = 1.0  # used for retention index calibration
891
892    correlation_threshold: float = 0.5  # used for calibration, spectral similarity
893
894    score_threshold: float = 0.0
895
896    ri_spacing: float = 200
897
898    ri_std: float = 3  # in standard deviation
899
900    ri_calibration_compound_names: List = dataclasses.field(default_factory=list)
901
902    # calculates and export all spectral similarity methods
903    exploratory_mode: bool = False
904
905    score_methods: tuple = ("highest_sim_score", "highest_ss")
906
907    output_score_method: str = "All"
908
909    def __post_init__(self):
910        # enforce datatype
911        self.url_database = os.getenv(
912            "SPECTRAL_GCMS_DATABASE_URL",
913            "sqlite:///db/pnnl_lowres_gcms_compounds.sqlite",
914        )
915
916        for field in dataclasses.fields(self):
917            value = getattr(self, field.name)
918            if not isinstance(value, field.type):
919                value = field.type(value)
920                setattr(self, field.name, value)
921
922        self.ri_calibration_compound_names = [
923            "Methyl Caprylate",
924            "Methyl Caprate",
925            "Methyl Pelargonate",
926            "Methyl Laurate",
927            "Methyl Myristate",
928            "Methyl Palmitate",
929            "Methyl Stearate",
930            "Methyl Eicosanoate",
931            "Methyl Docosanoate",
932            "Methyl Linocerate",
933            "Methyl Hexacosanoate",
934            "Methyl Octacosanoate",
935            "Methyl Triacontanoate",
936        ]

Settings for compound search

Attributes
  • url_database (str, optional): URL for the database. Default is 'sqlite:///db/pnnl_lowres_gcms_compounds.sqlite'.
  • ri_search_range (float, optional): Retention index search range. Default is 35.
  • rt_search_range (float, optional): Retention time search range, in minutes. Default is 1.0.
  • correlation_threshold (float, optional): Threshold for correlation for spectral similarity. Default is 0.5.
  • score_threshold (float, optional): Threshold for compsite score. Default is 0.0.
  • ri_spacing (float, optional): Retention index spacing. Default is 200.
  • ri_std (float, optional): Retention index standard deviation. Default is 3.
  • ri_calibration_compound_names (list, optional): List of compound names to use for retention index calibration. Default is ['Methyl Caprylate', 'Methyl Caprate', 'Methyl Pelargonate', 'Methyl Laurate', 'Methyl Myristate', 'Methyl Palmitate', 'Methyl Stearate', 'Methyl Eicosanoate', 'Methyl Docosanoate', 'Methyl Linocerate', 'Methyl Hexacosanoate', 'Methyl Octacosanoate', 'Methyl Triacontanoate'].
CompoundSearchSettings( url_database: str = 'postgresql+psycopg://coremsappdb:coremsapppnnl@localhost:5432/lowres', ri_search_range: float = 35, rt_search_range: float = 1.0, correlation_threshold: float = 0.5, score_threshold: float = 0.0, ri_spacing: float = 200, ri_std: float = 3, ri_calibration_compound_names: List = <factory>, exploratory_mode: bool = False, score_methods: tuple = ('highest_sim_score', 'highest_ss'), output_score_method: str = 'All')
url_database: str = 'postgresql+psycopg://coremsappdb:coremsapppnnl@localhost:5432/lowres'
ri_search_range: float = 35
rt_search_range: float = 1.0
correlation_threshold: float = 0.5
score_threshold: float = 0.0
ri_spacing: float = 200
ri_std: float = 3
ri_calibration_compound_names: List
exploratory_mode: bool = False
score_methods: tuple = ('highest_sim_score', 'highest_ss')
output_score_method: str = 'All'
class MolecularLookupDictSettings:
 939class MolecularLookupDictSettings:
 940    """Settings for molecular searching
 941
 942    These are used to generate the database entries, do not change.
 943
 944    Attributes
 945    ----------
 946    usedAtoms : dict, optional
 947        Dictionary of **element symbols** (most-abundant mono codes) to
 948        (min, max) count ranges. Keys must be element symbols present in
 949        ``Atoms.isotopes`` (e.g. ``C``, ``Fe``, ``Cl``), **not** specific
 950        isotope labels (e.g. ``13C``, ``54Fe``, ``37Cl``). Rare isotopes are
 951        produced by isotopologue expansion of mono formulas after assignment.
 952        Each key also needs a valence in ``used_atom_valences``.
 953        Default is {'C': (1, 90), 'H': (4, 200), 'O': (0, 12), 'N': (0, 0),
 954        'S': (0, 0), 'P': (0, 0), 'Cl': (0, 0)}.
 955    min_mz : float, optional
 956        Minimum m/z to use for searching. Default is 50.0.
 957    max_mz : float, optional
 958        Maximum m/z to use for searching. Default is 1200.0.
 959    min_dbe : float, optional
 960        Minimum double bond equivalent to use for searching. Default is 0.
 961    max_dbe : float, optional
 962        Maximum double bond equivalent to use for searching. Default is 50.
 963    use_pah_line_rule : bool, optional
 964        If True, use the PAH line rule. Default is False.
 965    isRadical : bool, optional
 966        If True, search for radical ions. Default is True.
 967    isProtonated : bool, optional
 968        If True, search for protonated ions. Default is True.
 969    url_database : str, optional
 970        URL for the database. Default is None.
 971    db_jobs : int, optional
 972        Number of jobs to use for database queries. Default is 1.
 973    used_atom_valences : dict, optional
 974        Dictionary of atoms and valences. Default is {'C': 4, '13C': 4, 'H': 1, 'O': 2, '18O': 2, 'N': 3, 'S': 2, '34S': 2, 'P': 3, 'Cl': 1, '37Cl': 1, 'Br': 1, 'Na': 1, 'F': 1, 'K': 0}.
 975
 976    """
 977
 978    ### DO NOT CHANGE IT! These are used to generate the database entries
 979
 980    ### DO change when creating a new application database
 981
 982    ### FOR search settings runtime and database query check use the MolecularFormulaSearchSettings class below
 983
 984    ### C, H, N, O, S and P atoms are ALWAYS needed at usedAtoms
 985    ### if you don't want to include one of those atoms set the max and min at 0
 986    ### Keys must be element symbols (Atoms.isotopes), not rare-isotope labels
 987    ### you can include any mono element in Atoms.isotopes
 988    ### make sure to include the selected covalence at the used_atoms_valences when adding new atoms
 989    ### NOTE : Adducts atoms have zero covalence
 990    ### NOTE : Not using static variable because this class is distributed using multiprocessing
 991    def __init__(self):
 992        self.usedAtoms = {
 993            "C": (1, 90),
 994            "H": (4, 200),
 995            "O": (0, 12),
 996            "N": (0, 0),
 997            "S": (0, 0),
 998            "P": (0, 0),
 999            "Cl": (0, 0),
1000        }
1001        validate_used_atoms_keys(self.usedAtoms)
1002
1003        self.min_mz = 50
1004
1005        self.max_mz = 1200
1006
1007        self.min_dbe = 0
1008
1009        self.max_dbe = 50
1010
1011        # overwrites the dbe limits above to DBE = (C + heteroatoms) * 0.9
1012        self.use_pah_line_rule = False
1013
1014        self.isRadical = True
1015
1016        self.isProtonated = True
1017
1018        self.url_database = None
1019
1020        self.db_jobs = 1
1021
1022        self.used_atom_valences = {
1023            "C": 4,
1024            "13C": 4,
1025            "H": 1,
1026            "O": 2,
1027            "18O": 2,
1028            "N": 3,
1029            "S": 2,
1030            "34S": 2,
1031            "P": 3,
1032            "Cl": 1,
1033            "37Cl": 1,
1034            "Br": 1,
1035            "Na": 1,
1036            "F": 1,
1037            "K": 0,
1038        }

Settings for molecular searching

These are used to generate the database entries, do not change.

Attributes
  • usedAtoms (dict, optional): Dictionary of element symbols (most-abundant mono codes) to (min, max) count ranges. Keys must be element symbols present in Atoms.isotopes (e.g. C, Fe, Cl), not specific isotope labels (e.g. 13C, 54Fe, 37Cl). Rare isotopes are produced by isotopologue expansion of mono formulas after assignment. Each key also needs a valence in used_atom_valences. Default is {'C': (1, 90), 'H': (4, 200), 'O': (0, 12), 'N': (0, 0), 'S': (0, 0), 'P': (0, 0), 'Cl': (0, 0)}.
  • min_mz (float, optional): Minimum m/z to use for searching. Default is 50.0.
  • max_mz (float, optional): Maximum m/z to use for searching. Default is 1200.0.
  • min_dbe (float, optional): Minimum double bond equivalent to use for searching. Default is 0.
  • max_dbe (float, optional): Maximum double bond equivalent to use for searching. Default is 50.
  • use_pah_line_rule (bool, optional): If True, use the PAH line rule. Default is False.
  • isRadical (bool, optional): If True, search for radical ions. Default is True.
  • isProtonated (bool, optional): If True, search for protonated ions. Default is True.
  • url_database (str, optional): URL for the database. Default is None.
  • db_jobs (int, optional): Number of jobs to use for database queries. Default is 1.
  • used_atom_valences (dict, optional): Dictionary of atoms and valences. Default is {'C': 4, '13C': 4, 'H': 1, 'O': 2, '18O': 2, 'N': 3, 'S': 2, '34S': 2, 'P': 3, 'Cl': 1, '37Cl': 1, 'Br': 1, 'Na': 1, 'F': 1, 'K': 0}.
usedAtoms
min_mz
max_mz
min_dbe
max_dbe
use_pah_line_rule
isRadical
isProtonated
url_database
db_jobs
used_atom_valences
@dataclasses.dataclass
class MolecularFormulaSearchSettings:
1041@dataclasses.dataclass
1042class MolecularFormulaSearchSettings:
1043    """Settings for molecular searching
1044
1045    Attributes
1046    ----------
1047    use_isotopologue_filter : bool, optional
1048        If True, use isotopologue filter. Default is False.
1049    isotopologue_filter_threshold : float, optional
1050        Threshold for isotopologue filter. Default is 33.
1051    isotopologue_filter_atoms : tuple, optional
1052        Tuple of atoms to use for isotopologue filter. Default is ('Cl', 'Br').
1053    use_runtime_kendrick_filter : bool, optional
1054        If True, use runtime Kendrick filter. Default is False.
1055    use_min_peaks_filter : bool, optional
1056        If True, use minimum peaks filter. Default is True.
1057    min_peaks_per_class : int, optional
1058        Minimum number of peaks per class. Default is 15.
1059    url_database : str, optional
1060        URL for the database. Default is 'postgresql+psycopg://coremsappdb:coremsapppnnl@localhost:5432/coremsapp'.
1061    db_jobs : int, optional
1062        Number of jobs to use for database queries. Default is 1. Can increase to 3 when python environment supports it.
1063    db_chunk_size : int, optional
1064        Chunk size to use for database queries. Default is 300.
1065    ion_charge : int, optional
1066        **Legacy / unused for formula search.** Kept so older YAML/JSON/TOML
1067        and ``MolecularFormulaSearchSettings(ion_charge=...)`` keep loading
1068        without error. Default is -1. Search polarity comes from the mass
1069        spectrum or LCMS object (DI often -1 from data; LC has no default).
1070        Absolute multi-charge range uses ``min_ion_charge`` / ``max_ion_charge``
1071        only. Do not use this field for new workflows.
1072    min_ion_charge : int, optional
1073        Minimum **absolute** ion charge for molecular formula search. Default is 1.
1074        With ``max_ion_charge``, defines the inclusive absolute charge range searched
1075        at polarity-signed values (e.g. positive polarity and max 2 → z = +1, +2).
1076        No 13C-based charge determination is performed; every selected peak is
1077        searched at each charge and candidates are ranked by existing formula
1078        scores (isotopologue similarity, confidence). Peak ``polarity`` remains
1079        ±1 (legacy alias ``peak.ion_charge``); assignment charge lives on
1080        ``MolecularFormula.ion_charge``.
1081    max_ion_charge : int, optional
1082        Maximum **absolute** ion charge for molecular formula search. Default is 1
1083        (legacy single-charge behavior). Must be >= ``min_ion_charge``.
1084        Incompatible with ``isAdduct=True`` when greater than 1 (adduct search is
1085        single-charge only; multi-charge adducts are not modeled).
1086    min_hc_filter : float, optional
1087        Minimum hydrogen to carbon ratio. Default is 0.3.
1088    max_hc_filter : float, optional
1089        Maximum hydrogen to carbon ratio. Default is 3.
1090    min_oc_filter : float, optional
1091        Minimum oxygen to carbon ratio. Default is 0.0.
1092    max_oc_filter : float, optional
1093        Maximum oxygen to carbon ratio. Default is 1.2.
1094    min_op_filter : float, optional
1095        Minimum oxygen to phosphorous ratio. Default is 2.
1096    use_pah_line_rule : bool, optional
1097        If True, use the PAH line rule. Default is False.
1098    min_dbe : float, optional
1099        Minimum double bond equivalent to use for searching. Default is 0.
1100    max_dbe : float, optional
1101        Maximum double bond equivalent to use for searching. Default is 40.
1102    mz_error_score_weight : float, optional
1103        Weight ``w_err`` for the formula-level mass-error term
1104        (``MolecularFormula.average_mz_error_score``) in the composite
1105        ``confidence_score``. Default is 0.6. See the
1106        ``corems.molecular_formula`` package documentation.
1107    isotopologue_score_weight : float, optional
1108        Weight ``w_iso`` for the isotopologue similarity term
1109        (``MolecularFormula.isotopologue_similarity``) in the composite
1110        ``confidence_score``. Default is 0.4. Some literature examples use
1111        equal weights (0.5 / 0.5).
1112    adduct_atoms_neg : tuple, optional
1113        Tuple of atoms to use in negative polarity. Default is ('Cl', 'Br').
1114    adduct_atoms_pos : tuple, optional
1115        Tuple of atoms to use in positive polarity. Default is ('Na', 'K').
1116    score_methods : tuple, optional
1117        Tuple of score method that can be implemented.
1118        Default is ('S_P_lowest_error', 'N_S_P_lowest_error', 'lowest_error', 'prob_score', 'air_filter_error', 'water_filter_error', 'earth_filter_error').
1119    score_method : str, optional
1120        Score method to use. Default is 'prob_score'. Options are 'S_P_lowest_error', 'N_S_P_lowest_error', 'lowest_error', 'prob_score', 'air_filter_error', 'water_filter_error', 'earth_filter_error'.
1121    output_min_score : float, optional
1122        Minimum score for output. Default is 0.1.
1123    output_score_method : str, optional
1124        Score method to use for output. Default is 'All Candidates'.
1125    isRadical : bool, optional
1126        If True, search for radical ions. Default is False.
1127    isProtonated : bool, optional
1128        If True, search for protonated ions. Default is True.
1129    isAdduct : bool, optional
1130        If True, search for adduct ions. Default is False.
1131        Requires ``max_ion_charge == 1`` (and typically ``min_ion_charge == 1``);
1132        multi-charge formula search does not include adduct ion types.
1133    usedAtoms : dict, optional
1134        Dictionary of **element symbols** (most-abundant mono codes) to
1135        (min, max) count ranges for molecular formula search. Keys must be
1136        element symbols present in ``Atoms.isotopes`` (e.g. ``C``, ``Fe``,
1137        ``Cl``), **not** specific isotope labels (e.g. ``13C``, ``54Fe``,
1138        ``37Cl``). Rare / heavy isotopes are generated by isotopologue
1139        expansion of mono formulas after assignment (when
1140        ``find_isotopologues`` is enabled), not by listing them here.
1141        Invalid keys raise ``ValueError`` at settings construction, assignment,
1142        or search entry. Each key also needs a valence in
1143        ``used_atom_valences`` (usually from ``Atoms.atoms_covalence``).
1144        Default empty dict is filled with C and H ranges in
1145        ``__post_init__``.
1146    ion_types_excluded : list, optional
1147        List of ion types to exclude from molecular id search, commonly ['[M+CH3COO]-]'] or ['[M+COOH]-'] depending on mobile phase content. Default is [].
1148    ionization_type : str, optional
1149        Ionization type. Default is 'ESI'.
1150    min_ppm_error : float, optional
1151        Minimum ppm error. Default is -10.0.
1152    max_ppm_error : float, optional
1153        Maximum ppm error. Default is 10.0.
1154    min_abun_error : float, optional
1155        Minimum abundance error for isotolopologue search. Default is -100.0.
1156    max_abun_error : float, optional
1157        Maximum abundance error for isotolopologue search. Default is 100.0.
1158    mz_error_range : float, optional
1159        m/z error range. Default is 1.5.
1160    error_method : str, optional
1161        Error method. Default is 'None'. Options are 'distance', 'lowest', 'symmetrical','average' 'None'.
1162    mz_error_average : float, optional
1163        m/z error average. Default is 0.0.
1164    used_atom_valences : dict, optional
1165        Dictionary of atoms and valences. Default is {'C': 4, '13C': 4, 'H': 1, 'O': 2, '18O': 2, 'N': 3, 'S': 2, '34S': 2, 'P': 3, 'Cl': 1, '37Cl': 1, 'Br': 1, 'Na': 1, 'F': 1, 'K': 0}.
1166    verbose_processing: bool, optional
1167        If True, print verbose processing information. Default is True.
1168    """
1169
1170    verbose_processing: bool = True
1171
1172    use_isotopologue_filter: bool = False
1173
1174    isotopologue_filter_threshold: float = 33
1175
1176    isotopologue_filter_atoms: tuple = ("Cl", "Br")
1177
1178    use_runtime_kendrick_filter: bool = False
1179
1180    use_min_peaks_filter: bool = True
1181
1182    min_peaks_per_class: int = 15
1183
1184    url_database: str = (
1185        "postgresql+psycopg://coremsappdb:coremsapppnnl@localhost:5432/coremsapp"
1186    )
1187
1188    db_jobs: int = 1
1189
1190    db_chunk_size: int = 300
1191
1192    # query setting========
1193    # Legacy BC only (parameter files / constructor). Not used for search.
1194    # Polarity: spectrum/LCMS data. Multi-z absolute range: min/max_ion_charge.
1195    ion_charge: int = -1
1196
1197    # Absolute charge range for formula search (polarity supplies sign).
1198    # Defaults 1..1 preserve single-charge behavior.
1199    min_ion_charge: int = 1
1200    max_ion_charge: int = 1
1201
1202    min_hc_filter: float = 0.3
1203
1204    max_hc_filter: float = 3
1205
1206    min_oc_filter: float = 0.0
1207
1208    max_oc_filter: float = 1.2
1209
1210    min_op_filter: float = 2
1211
1212    use_pah_line_rule: bool = False
1213
1214    min_dbe: float = 0
1215
1216    max_dbe: float = 40
1217
1218    mz_error_score_weight: float = 0.6
1219
1220    isotopologue_score_weight: float = 0.4
1221
1222    # look for close shell ions [M + Adduct]+ only considers metal set in the list adduct_atoms
1223    adduct_atoms_neg: tuple = ("Cl", "Br")
1224
1225    adduct_atoms_pos: tuple = ("Na", "K")
1226
1227    score_methods: tuple = (
1228        "S_P_lowest_error",
1229        "N_S_P_lowest_error",
1230        "lowest_error",
1231        "prob_score",
1232        "air_filter_error",
1233        "water_filter_error",
1234        "earth_filter_error",
1235    )
1236
1237    score_method: str = "prob_score"
1238
1239    output_min_score: float = 0.1
1240
1241    output_score_method: str = "All Candidates"
1242
1243    # depending on the polarity mode it looks for [M].+ , [M].-
1244    # query and automatically compile add entry if it doesn't exist
1245
1246    isRadical: bool = False
1247
1248    # depending on the polarity mode it looks for [M + H]+ , [M - H]+
1249    # query and automatically compile and push options if it doesn't exist
1250    isProtonated: bool = True
1251
1252    isAdduct: bool = False
1253
1254    usedAtoms: dict = dataclasses.field(default_factory=dict)
1255    ion_types_excluded: list = dataclasses.field(default_factory=list)
1256
1257    # search setting ========
1258
1259    ionization_type: str = "ESI"
1260
1261    # empirically set / needs optimization
1262    min_ppm_error: float = -10.0  # ppm
1263
1264    # empirically set / needs optimization
1265    max_ppm_error: float = 10.0  # ppm
1266
1267    # empirically set / needs optimization set for isotopologue search
1268    min_abun_error: float = -100.0  # percentage
1269
1270    # empirically set / needs optimization set for isotopologue search
1271    max_abun_error: float = 100.0  # percentage
1272
1273    # empirically set / needs optimization
1274    mz_error_range: float = 1.5
1275
1276    # 'distance', 'lowest', 'symmetrical','average' 'None'
1277    error_method: str = "None"
1278
1279    mz_error_average: float = 0.0
1280
1281    # used_atom_valences: {'C': 4, 'H':1, etc} = dataclasses.field(default_factory=dict)
1282    used_atom_valences: dict = dataclasses.field(default_factory=dict)
1283
1284    def __setattr__(self, name, value):
1285        # Catch full reassignment of usedAtoms after construction (common API).
1286        # In-place mutation (usedAtoms[key] = ...) is validated at search entry.
1287        if name == "usedAtoms" and value is not None:
1288            validate_used_atoms_keys(value)
1289        super().__setattr__(name, value)
1290
1291    def __post_init__(self):
1292        if not self.url_database or self.url_database == "":
1293            self.url_database = os.getenv(
1294                "COREMS_DATABASE_URL", "sqlite:///db/molformula.db"
1295            )
1296        # enforce datatype
1297        for field in dataclasses.fields(self):
1298            value = getattr(self, field.name)
1299            if not isinstance(value, field.type):
1300                value = field.type(value)
1301                setattr(self, field.name, value)
1302
1303        # enforce C and H if either do not exists
1304        if "C" not in self.usedAtoms.keys():
1305            self.usedAtoms["C"] = (1, 100)
1306        if "H" not in self.usedAtoms.keys():
1307            self.usedAtoms["H"] = (1, 200)
1308
1309        validate_used_atoms_keys(self.usedAtoms)
1310
1311        # add cummon values
1312        current_used_atoms = self.used_atom_valences.keys()
1313
1314        for atom in Atoms.atoms_covalence.keys():
1315            if atom not in current_used_atoms:
1316                covalence = Atoms.atoms_covalence.get(atom)
1317
1318                if isinstance(covalence, int):
1319                    self.used_atom_valences[atom] = covalence
1320
1321                else:
1322                    # will get the first number of all possible covalances, which should be the most commum
1323                    self.used_atom_valences[atom] = covalence[0]
1324
1325        self.validate_ion_charge_settings()
1326
1327    def validate_ion_charge_settings(self):
1328        """Validate absolute charge range and adduct compatibility.
1329
1330        Raises
1331        ------
1332        ValueError
1333            If ``min_ion_charge`` / ``max_ion_charge`` are invalid, or if
1334            ``isAdduct`` is enabled with multi-charge search
1335            (``max_ion_charge > 1``).
1336        """
1337        min_z = int(self.min_ion_charge)
1338        max_z = int(self.max_ion_charge)
1339        if min_z < 1:
1340            raise ValueError("min_ion_charge must be >= 1")
1341        if max_z < min_z:
1342            raise ValueError("max_ion_charge must be >= min_ion_charge")
1343        # Multi-charge adducts ([M+Na+H]2+, [M+2Na]2+, etc.) are not modeled;
1344        # adduct search is single-charge only.
1345        if self.isAdduct and max_z > 1:
1346            raise ValueError(
1347                "isAdduct=True is incompatible with multi-charge formula search "
1348                f"(max_ion_charge={max_z}). Set max_ion_charge=1 for adduct "
1349                "search, or disable isAdduct for multi-charge protonated/radical "
1350                "search."
1351            )

Settings for molecular searching

Attributes
  • use_isotopologue_filter (bool, optional): If True, use isotopologue filter. Default is False.
  • isotopologue_filter_threshold (float, optional): Threshold for isotopologue filter. Default is 33.
  • isotopologue_filter_atoms (tuple, optional): Tuple of atoms to use for isotopologue filter. Default is ('Cl', 'Br').
  • use_runtime_kendrick_filter (bool, optional): If True, use runtime Kendrick filter. Default is False.
  • use_min_peaks_filter (bool, optional): If True, use minimum peaks filter. Default is True.
  • min_peaks_per_class (int, optional): Minimum number of peaks per class. Default is 15.
  • url_database (str, optional): URL for the database. Default is 'postgresql+psycopg://coremsappdb:coremsapppnnl@localhost:5432/coremsapp'.
  • db_jobs (int, optional): Number of jobs to use for database queries. Default is 1. Can increase to 3 when python environment supports it.
  • db_chunk_size (int, optional): Chunk size to use for database queries. Default is 300.
  • ion_charge (int, optional): Legacy / unused for formula search. Kept so older YAML/JSON/TOML and MolecularFormulaSearchSettings(ion_charge=...) keep loading without error. Default is -1. Search polarity comes from the mass spectrum or LCMS object (DI often -1 from data; LC has no default). Absolute multi-charge range uses min_ion_charge / max_ion_charge only. Do not use this field for new workflows.
  • min_ion_charge (int, optional): Minimum absolute ion charge for molecular formula search. Default is 1. With max_ion_charge, defines the inclusive absolute charge range searched at polarity-signed values (e.g. positive polarity and max 2 → z = +1, +2). No 13C-based charge determination is performed; every selected peak is searched at each charge and candidates are ranked by existing formula scores (isotopologue similarity, confidence). Peak polarity remains ±1 (legacy alias peak.ion_charge); assignment charge lives on MolecularFormula.ion_charge.
  • max_ion_charge (int, optional): Maximum absolute ion charge for molecular formula search. Default is 1 (legacy single-charge behavior). Must be >= min_ion_charge. Incompatible with isAdduct=True when greater than 1 (adduct search is single-charge only; multi-charge adducts are not modeled).
  • min_hc_filter (float, optional): Minimum hydrogen to carbon ratio. Default is 0.3.
  • max_hc_filter (float, optional): Maximum hydrogen to carbon ratio. Default is 3.
  • min_oc_filter (float, optional): Minimum oxygen to carbon ratio. Default is 0.0.
  • max_oc_filter (float, optional): Maximum oxygen to carbon ratio. Default is 1.2.
  • min_op_filter (float, optional): Minimum oxygen to phosphorous ratio. Default is 2.
  • use_pah_line_rule (bool, optional): If True, use the PAH line rule. Default is False.
  • min_dbe (float, optional): Minimum double bond equivalent to use for searching. Default is 0.
  • max_dbe (float, optional): Maximum double bond equivalent to use for searching. Default is 40.
  • mz_error_score_weight (float, optional): Weight w_err for the formula-level mass-error term (MolecularFormula.average_mz_error_score) in the composite confidence_score. Default is 0.6. See the corems.molecular_formula package documentation.
  • isotopologue_score_weight (float, optional): Weight w_iso for the isotopologue similarity term (MolecularFormula.isotopologue_similarity) in the composite confidence_score. Default is 0.4. Some literature examples use equal weights (0.5 / 0.5).
  • adduct_atoms_neg (tuple, optional): Tuple of atoms to use in negative polarity. Default is ('Cl', 'Br').
  • adduct_atoms_pos (tuple, optional): Tuple of atoms to use in positive polarity. Default is ('Na', 'K').
  • score_methods (tuple, optional): Tuple of score method that can be implemented. Default is ('S_P_lowest_error', 'N_S_P_lowest_error', 'lowest_error', 'prob_score', 'air_filter_error', 'water_filter_error', 'earth_filter_error').
  • score_method (str, optional): Score method to use. Default is 'prob_score'. Options are 'S_P_lowest_error', 'N_S_P_lowest_error', 'lowest_error', 'prob_score', 'air_filter_error', 'water_filter_error', 'earth_filter_error'.
  • output_min_score (float, optional): Minimum score for output. Default is 0.1.
  • output_score_method (str, optional): Score method to use for output. Default is 'All Candidates'.
  • isRadical (bool, optional): If True, search for radical ions. Default is False.
  • isProtonated (bool, optional): If True, search for protonated ions. Default is True.
  • isAdduct (bool, optional): If True, search for adduct ions. Default is False. Requires max_ion_charge == 1 (and typically min_ion_charge == 1); multi-charge formula search does not include adduct ion types.
  • usedAtoms (dict, optional): Dictionary of element symbols (most-abundant mono codes) to (min, max) count ranges for molecular formula search. Keys must be element symbols present in Atoms.isotopes (e.g. C, Fe, Cl), not specific isotope labels (e.g. 13C, 54Fe, 37Cl). Rare / heavy isotopes are generated by isotopologue expansion of mono formulas after assignment (when find_isotopologues is enabled), not by listing them here. Invalid keys raise ValueError at settings construction, assignment, or search entry. Each key also needs a valence in used_atom_valences (usually from Atoms.atoms_covalence). Default empty dict is filled with C and H ranges in __post_init__.
  • ion_types_excluded (list, optional): List of ion types to exclude from molecular id search, commonly ['[M+CH3COO]-]'] or ['[M+COOH]-'] depending on mobile phase content. Default is [].
  • ionization_type (str, optional): Ionization type. Default is 'ESI'.
  • min_ppm_error (float, optional): Minimum ppm error. Default is -10.0.
  • max_ppm_error (float, optional): Maximum ppm error. Default is 10.0.
  • min_abun_error (float, optional): Minimum abundance error for isotolopologue search. Default is -100.0.
  • max_abun_error (float, optional): Maximum abundance error for isotolopologue search. Default is 100.0.
  • mz_error_range (float, optional): m/z error range. Default is 1.5.
  • error_method (str, optional): Error method. Default is 'None'. Options are 'distance', 'lowest', 'symmetrical','average' 'None'.
  • mz_error_average (float, optional): m/z error average. Default is 0.0.
  • used_atom_valences (dict, optional): Dictionary of atoms and valences. Default is {'C': 4, '13C': 4, 'H': 1, 'O': 2, '18O': 2, 'N': 3, 'S': 2, '34S': 2, 'P': 3, 'Cl': 1, '37Cl': 1, 'Br': 1, 'Na': 1, 'F': 1, 'K': 0}.
  • verbose_processing (bool, optional): If True, print verbose processing information. Default is True.
MolecularFormulaSearchSettings( verbose_processing: bool = True, use_isotopologue_filter: bool = False, isotopologue_filter_threshold: float = 33, isotopologue_filter_atoms: tuple = ('Cl', 'Br'), use_runtime_kendrick_filter: bool = False, use_min_peaks_filter: bool = True, min_peaks_per_class: int = 15, url_database: str = 'postgresql+psycopg://coremsappdb:coremsapppnnl@localhost:5432/coremsapp', db_jobs: int = 1, db_chunk_size: int = 300, ion_charge: int = -1, min_ion_charge: int = 1, max_ion_charge: int = 1, min_hc_filter: float = 0.3, max_hc_filter: float = 3, min_oc_filter: float = 0.0, max_oc_filter: float = 1.2, min_op_filter: float = 2, use_pah_line_rule: bool = False, min_dbe: float = 0, max_dbe: float = 40, mz_error_score_weight: float = 0.6, isotopologue_score_weight: float = 0.4, adduct_atoms_neg: tuple = ('Cl', 'Br'), adduct_atoms_pos: tuple = ('Na', 'K'), score_methods: tuple = ('S_P_lowest_error', 'N_S_P_lowest_error', 'lowest_error', 'prob_score', 'air_filter_error', 'water_filter_error', 'earth_filter_error'), score_method: str = 'prob_score', output_min_score: float = 0.1, output_score_method: str = 'All Candidates', isRadical: bool = False, isProtonated: bool = True, isAdduct: bool = False, usedAtoms: dict = <factory>, ion_types_excluded: list = <factory>, ionization_type: str = 'ESI', min_ppm_error: float = -10.0, max_ppm_error: float = 10.0, min_abun_error: float = -100.0, max_abun_error: float = 100.0, mz_error_range: float = 1.5, error_method: str = 'None', mz_error_average: float = 0.0, used_atom_valences: dict = <factory>)
verbose_processing: bool = True
use_isotopologue_filter: bool = False
isotopologue_filter_threshold: float = 33
isotopologue_filter_atoms: tuple = ('Cl', 'Br')
use_runtime_kendrick_filter: bool = False
use_min_peaks_filter: bool = True
min_peaks_per_class: int = 15
url_database: str = 'postgresql+psycopg://coremsappdb:coremsapppnnl@localhost:5432/coremsapp'
db_jobs: int = 1
db_chunk_size: int = 300
ion_charge: int = -1
min_ion_charge: int = 1
max_ion_charge: int = 1
min_hc_filter: float = 0.3
max_hc_filter: float = 3
min_oc_filter: float = 0.0
max_oc_filter: float = 1.2
min_op_filter: float = 2
use_pah_line_rule: bool = False
min_dbe: float = 0
max_dbe: float = 40
mz_error_score_weight: float = 0.6
isotopologue_score_weight: float = 0.4
adduct_atoms_neg: tuple = ('Cl', 'Br')
adduct_atoms_pos: tuple = ('Na', 'K')
score_methods: tuple = ('S_P_lowest_error', 'N_S_P_lowest_error', 'lowest_error', 'prob_score', 'air_filter_error', 'water_filter_error', 'earth_filter_error')
score_method: str = 'prob_score'
output_min_score: float = 0.1
output_score_method: str = 'All Candidates'
isRadical: bool = False
isProtonated: bool = True
isAdduct: bool = False
usedAtoms: dict
ion_types_excluded: list
ionization_type: str = 'ESI'
min_ppm_error: float = -10.0
max_ppm_error: float = 10.0
min_abun_error: float = -100.0
max_abun_error: float = 100.0
mz_error_range: float = 1.5
error_method: str = 'None'
mz_error_average: float = 0.0
used_atom_valences: dict
def validate_ion_charge_settings(self):
1327    def validate_ion_charge_settings(self):
1328        """Validate absolute charge range and adduct compatibility.
1329
1330        Raises
1331        ------
1332        ValueError
1333            If ``min_ion_charge`` / ``max_ion_charge`` are invalid, or if
1334            ``isAdduct`` is enabled with multi-charge search
1335            (``max_ion_charge > 1``).
1336        """
1337        min_z = int(self.min_ion_charge)
1338        max_z = int(self.max_ion_charge)
1339        if min_z < 1:
1340            raise ValueError("min_ion_charge must be >= 1")
1341        if max_z < min_z:
1342            raise ValueError("max_ion_charge must be >= min_ion_charge")
1343        # Multi-charge adducts ([M+Na+H]2+, [M+2Na]2+, etc.) are not modeled;
1344        # adduct search is single-charge only.
1345        if self.isAdduct and max_z > 1:
1346            raise ValueError(
1347                "isAdduct=True is incompatible with multi-charge formula search "
1348                f"(max_ion_charge={max_z}). Set max_ion_charge=1 for adduct "
1349                "search, or disable isAdduct for multi-charge protonated/radical "
1350                "search."
1351            )

Validate absolute charge range and adduct compatibility.

Raises
@dataclasses.dataclass
class LCMSCollectionSettings:
1354@dataclasses.dataclass
1355class LCMSCollectionSettings:
1356    """Settings for LCMS collection class
1357
1358    Attributes
1359    ----------
1360    cores : int, optional
1361        Number of cores to use for processing. Default is 1.
1362    drop_isotopologues : bool, optional
1363        If True, drop isotopologues from all analyses.
1364        Note that this will keep mass features identified as monoisotopes and any largest ion in deconvoluted mass spectrum.
1365        It will also keep mass features not identified as isotopologues or monoisotopes.
1366        Default is True.
1367    mass_feature_anchor_technique: list, optional
1368        List of mass feature anchor techniques for retention time alignment.
1369        Default is ['absolute_intensity'].
1370    mass_feature_anchor_techniques_available: tuple, optional
1371        Tuple of available mass feature anchor techniques for retention time alignment.
1372        Default is ('deconvoluted_mass_spectra', 'absolute_intensity', 'relative_intensity').
1373    mass_feature_anchor_absolute_intensity_threshold: int, optional
1374        Absolute intensity threshold for mass feature anchor for retention time alignment.
1375        Used when mass_feature_anchor_technique includes 'relative_intensity'.
1376        Default is 10000.
1377    mass_feature_anchor_relative_intensity_threshold: float, optional
1378        Relative intensity threshold (0-1) for mass feature anchor for retention time alignment.
1379        Removes the lower fraction of mass features by intensity from consideration.
1380        For example, 0.6 removes the lower 60% of intensity features.
1381        Used when mass_feature_anchor_technique includes 'relative_intensity'.
1382        Default is 0.6.
1383    alignment_minimum_matches: int, optional
1384        Minimum number of matched features required to attempt retention time alignment.
1385        If fewer matches are found between samples, alignment will be skipped for that sample.
1386        This is particularly useful when aligning blank samples or samples with very few features.
1387        Default is 5.
1388    alignment_hold_out_fraction: float, optional
1389        Hold out fraction for testing retention time alignment.
1390        Default is 0.3.
1391    alignment_acceptance_technique: list, optional
1392        List of alignment acceptance techniques for retention time alignment.
1393        Default is ['fraction_improved', 'mean_squared_error_improved'].
1394    alignment_acceptance_techniques_available: tuple, optional
1395        Tuple of available alignment acceptance techniques for retention time alignment.
1396        Default is ('fraction_improved', 'mean_squared_error_improved').
1397    alignment_acceptance_fraction_improved_threshold: float, optional
1398        Threshold for the improved fraction of the hold out mass features for accepting retention time alignment.
1399        Default is 0.5.
1400    alignment_mz_tol_ppm: int, optional
1401        m/z tolerance in ppm for retention time alignment and for consensus feature
1402        grouping isotope (and later adduct) mass deltas. Default is 5.
1403    alignment_rt_tol: float, optional
1404        Retention time tolerance in minutes for retention time alignment and for
1405        consensus feature grouping coelution windows. Default is 0.3.
1406    consensus_mz_tol_ppm: int, optional
1407        m/z tolerance in ppm for consensus mass feature alignment. Default is 5.
1408        The recommendation is that this value should be the same as alignment_mz_tol_ppm.
1409    consensus_rt_tol: float, optional
1410        Retention time tolerance for consensus mass feature alignment, in minutes. Default is 0.2.
1411    consensus_partition_size: int, optional
1412        Partition size for consensus mass feature alignment. Default is 5000.
1413    consensus_min_sample_fraction : float, optional
1414        Minimum fraction of samples (0-1) that must contain a cluster.
1415        Used for filtering consensus features and for gap-filling threshold.
1416        Default is 0.5 (50%). Higher values focus on more prevalent features.
1417    gap_fill_expand_on_miss : bool, optional
1418        If True, expands the search window when no peak is found inside the
1419        cluster bounds. m/z widens by consensus_mz_tol_ppm. Retention time
1420        widens by consensus_rt_tol minutes. Default is True.
1421    consensus_representative_metric : str, optional
1422        Metric used to determine the most representative sample for a consensus mass feature.
1423        Options:
1424        - 'intensity': Selects the mass feature with the highest intensity value
1425        - 'intensity_prefer_ms2': Selects the mass feature with the highest intensity among
1426          those that have MS2 scan numbers assigned. If no features have MS2 scans, falls
1427          back to selecting the highest intensity feature overall.
1428        Default is 'intensity_prefer_ms2'.
1429    consensus_representative_metrics_available : tuple, optional
1430        Tuple of available metrics for determining the most representative sample.
1431        Default is ('intensity', 'intensity_prefer_ms2').
1432    feature_group_isotope_atoms : tuple of str, optional
1433        Mono elements for natural-abundance isotope Δm edges via ``Atoms``
1434        (e.g. ``("C",)``). Default ``("C",)``. Not for tracer labeling.
1435    feature_group_min_isotope_abundance : float, optional
1436        Min natural abundance (0–1) for rare forms in isotope spacing.
1437        Default 0.01.
1438    feature_group_max_isotope_offset : int, optional
1439        Max M+n roll-up depth for one rare form (e.g. ¹³Cₙ). Default 4.
1440    feature_group_corr_threshold : float, optional
1441        Min Pearson correlation of apex ``intensity`` vectors for an edge
1442        (pairwise-complete; zeros dropped). Default 0.80.
1443    feature_group_min_shared_sample_fraction : float, optional
1444        Min fraction of samples with both heights > 0 before correlation
1445        is trusted (``ceil(fraction * n_samples)``). Default 0.15.
1446    feature_group_ion_types : tuple of str, optional
1447        Allow-list of ``ION_TYPE_DICT`` keys for adduct linking (``|z| = 1``).
1448        Empty/one type → isotopes only. Default is a curated common set
1449        (``DEFAULT_ION_TYPES``); narrow further to reduce false adduct links.
1450        Filtered by collection polarity at ``group_consensus_features()``.
1451    feature_group_constrain_annotation : bool, optional
1452        If True and labels exist, skip consensus isotopes in collection
1453        MS1/MS2/annotation and keep IDs only if ion type is in
1454        ``possible_ion_types``. Default True.
1455    feature_group_partition_size : int, optional
1456        Reserved RT-partition size for future multicore grouping.
1457        Default 5000.
1458    """
1459
1460    # Settings for general processing
1461    cores: int = 1
1462    drop_isotopologues: bool = False
1463
1464    # Settings for doing mass feature alignment
1465    _mass_feature_anchor_technique: list = dataclasses.field(
1466        default_factory=lambda: ["relative_intensity"]
1467    )
1468    mass_feature_anchor_techniques_available: tuple = (
1469        "deconvoluted_mass_spectra",
1470        "absolute_intensity",
1471        "relative_intensity",
1472    )
1473    mass_feature_anchor_absolute_intensity_threshold: int = 10000
1474    mass_feature_anchor_relative_intensity_threshold: float = 0.6
1475    alignment_minimum_matches: int = 5
1476    alignment_hold_out_fraction: float = 0.3
1477    _alignment_acceptance_technique: list = dataclasses.field(
1478        default_factory=lambda: ["fraction_improved", "mean_squared_error_improved"]
1479    )
1480    alignment_acceptance_techniques_available: tuple = (
1481        "fraction_improved",
1482        "mean_squared_error_improved",
1483    )
1484    alignment_acceptance_fraction_improved_threshold: float = 0.5
1485    alignment_mz_tol_ppm: int = 5
1486    alignment_rt_tol: float = 0.4
1487
1488    # Consensus mass feature settings
1489    consensus_mz_tol_ppm: int = alignment_mz_tol_ppm
1490    consensus_rt_tol: float = 0.3
1491    consensus_partition_size: int = 10000
1492    filter_consensus_mass_features: bool = True
1493    consensus_min_sample_fraction: float = 0.5
1494
1495    # Gap-filling settings
1496    gap_fill_expand_on_miss: bool = True
1497
1498    # Consensus mass feature visualization parameters
1499    consensus_representative_metric: str = "intensity_prefer_ms2"
1500    consensus_representative_metrics_available: tuple = (
1501        "intensity",
1502        "intensity_prefer_ms2",
1503    )
1504
1505    # Feature grouping (isotopes + z=1 adducts); RT/m/z use alignment_* tols
1506    feature_group_isotope_atoms: tuple = ("C",)
1507    feature_group_min_isotope_abundance: float = 0.01
1508    feature_group_max_isotope_offset: int = 4
1509    feature_group_corr_threshold: float = 0.80
1510    feature_group_min_shared_sample_fraction: float = 0.15
1511    feature_group_ion_types: tuple = dataclasses.field(
1512        default_factory=lambda: (
1513            __import__(
1514                "corems.mass_spectra.calc.feature_grouping",
1515                fromlist=["DEFAULT_ION_TYPES"],
1516            ).DEFAULT_ION_TYPES
1517        )
1518    )
1519    feature_group_constrain_annotation: bool = True
1520    feature_group_partition_size: int = 5000
1521
1522    def __post_init__(self):
1523        self.consensus_mz_tol_ppm = self.alignment_mz_tol_ppm
1524        self._validate_alignment_acceptance_technique(
1525            self.alignment_acceptance_technique
1526        )
1527        self._validate_mass_feature_anchor_technique(self.mass_feature_anchor_technique)
1528
1529    def _validate_alignment_acceptance_technique(self, techniques):
1530        for technique in techniques:
1531            if technique not in self.alignment_acceptance_techniques_available:
1532                raise ValueError(
1533                    f"Alignment acceptance technique '{technique}' is not available. Alignment acceptance technique must be passed as a list. Available techniques: {self.alignment_acceptance_techniques_available}"
1534                )
1535
1536    def _validate_mass_feature_anchor_technique(self, techniques):
1537        for technique in techniques:
1538            if technique not in self.mass_feature_anchor_techniques_available:
1539                raise ValueError(
1540                    f"Mass feature anchor technique '{technique}' is not available. Alignment acceptance technique must be passed as a list. Available techniques: {self.mass_feature_anchor_techniques_available}"
1541                )
1542
1543    @property
1544    def alignment_acceptance_technique(self):
1545        return self._alignment_acceptance_technique
1546
1547    @alignment_acceptance_technique.setter
1548    def alignment_acceptance_technique(self, value):
1549        self._validate_alignment_acceptance_technique(value)
1550        self._alignment_acceptance_technique = value
1551
1552    @property
1553    def mass_feature_anchor_technique(self):
1554        return self._mass_feature_anchor_technique
1555
1556    @mass_feature_anchor_technique.setter
1557    def mass_feature_anchor_technique(self, value):
1558        self._validate_mass_feature_anchor_technique(value)
1559        self._mass_feature_anchor_technique = value

Settings for LCMS collection class

Attributes
  • cores (int, optional): Number of cores to use for processing. Default is 1.
  • drop_isotopologues (bool, optional): If True, drop isotopologues from all analyses. Note that this will keep mass features identified as monoisotopes and any largest ion in deconvoluted mass spectrum. It will also keep mass features not identified as isotopologues or monoisotopes. Default is True.
  • mass_feature_anchor_technique (list, optional): List of mass feature anchor techniques for retention time alignment. Default is ['absolute_intensity'].
  • mass_feature_anchor_techniques_available (tuple, optional): Tuple of available mass feature anchor techniques for retention time alignment. Default is ('deconvoluted_mass_spectra', 'absolute_intensity', 'relative_intensity').
  • mass_feature_anchor_absolute_intensity_threshold (int, optional): Absolute intensity threshold for mass feature anchor for retention time alignment. Used when mass_feature_anchor_technique includes 'relative_intensity'. Default is 10000.
  • mass_feature_anchor_relative_intensity_threshold (float, optional): Relative intensity threshold (0-1) for mass feature anchor for retention time alignment. Removes the lower fraction of mass features by intensity from consideration. For example, 0.6 removes the lower 60% of intensity features. Used when mass_feature_anchor_technique includes 'relative_intensity'. Default is 0.6.
  • alignment_minimum_matches (int, optional): Minimum number of matched features required to attempt retention time alignment. If fewer matches are found between samples, alignment will be skipped for that sample. This is particularly useful when aligning blank samples or samples with very few features. Default is 5.
  • alignment_hold_out_fraction (float, optional): Hold out fraction for testing retention time alignment. Default is 0.3.
  • alignment_acceptance_technique (list, optional): List of alignment acceptance techniques for retention time alignment. Default is ['fraction_improved', 'mean_squared_error_improved'].
  • alignment_acceptance_techniques_available (tuple, optional): Tuple of available alignment acceptance techniques for retention time alignment. Default is ('fraction_improved', 'mean_squared_error_improved').
  • alignment_acceptance_fraction_improved_threshold (float, optional): Threshold for the improved fraction of the hold out mass features for accepting retention time alignment. Default is 0.5.
  • alignment_mz_tol_ppm (int, optional): m/z tolerance in ppm for retention time alignment and for consensus feature grouping isotope (and later adduct) mass deltas. Default is 5.
  • alignment_rt_tol (float, optional): Retention time tolerance in minutes for retention time alignment and for consensus feature grouping coelution windows. Default is 0.3.
  • consensus_mz_tol_ppm (int, optional): m/z tolerance in ppm for consensus mass feature alignment. Default is 5. The recommendation is that this value should be the same as alignment_mz_tol_ppm.
  • consensus_rt_tol (float, optional): Retention time tolerance for consensus mass feature alignment, in minutes. Default is 0.2.
  • consensus_partition_size (int, optional): Partition size for consensus mass feature alignment. Default is 5000.
  • consensus_min_sample_fraction (float, optional): Minimum fraction of samples (0-1) that must contain a cluster. Used for filtering consensus features and for gap-filling threshold. Default is 0.5 (50%). Higher values focus on more prevalent features.
  • gap_fill_expand_on_miss (bool, optional): If True, expands the search window when no peak is found inside the cluster bounds. m/z widens by consensus_mz_tol_ppm. Retention time widens by consensus_rt_tol minutes. Default is True.
  • consensus_representative_metric (str, optional): Metric used to determine the most representative sample for a consensus mass feature. Options:
    • 'intensity': Selects the mass feature with the highest intensity value
    • 'intensity_prefer_ms2': Selects the mass feature with the highest intensity among those that have MS2 scan numbers assigned. If no features have MS2 scans, falls back to selecting the highest intensity feature overall. Default is 'intensity_prefer_ms2'.
  • consensus_representative_metrics_available (tuple, optional): Tuple of available metrics for determining the most representative sample. Default is ('intensity', 'intensity_prefer_ms2').
  • feature_group_isotope_atoms (tuple of str, optional): Mono elements for natural-abundance isotope Δm edges via Atoms (e.g. ("C",)). Default ("C",). Not for tracer labeling.
  • feature_group_min_isotope_abundance (float, optional): Min natural abundance (0–1) for rare forms in isotope spacing. Default 0.01.
  • feature_group_max_isotope_offset (int, optional): Max M+n roll-up depth for one rare form (e.g. ¹³Cₙ). Default 4.
  • feature_group_corr_threshold (float, optional): Min Pearson correlation of apex intensity vectors for an edge (pairwise-complete; zeros dropped). Default 0.80.
  • feature_group_min_shared_sample_fraction (float, optional): Min fraction of samples with both heights > 0 before correlation is trusted (ceil(fraction * n_samples)). Default 0.15.
  • feature_group_ion_types (tuple of str, optional): Allow-list of ION_TYPE_DICT keys for adduct linking (|z| = 1). Empty/one type → isotopes only. Default is a curated common set (DEFAULT_ION_TYPES); narrow further to reduce false adduct links. Filtered by collection polarity at group_consensus_features().
  • feature_group_constrain_annotation (bool, optional): If True and labels exist, skip consensus isotopes in collection MS1/MS2/annotation and keep IDs only if ion type is in possible_ion_types. Default True.
  • feature_group_partition_size (int, optional): Reserved RT-partition size for future multicore grouping. Default 5000.
LCMSCollectionSettings( cores: int = 1, drop_isotopologues: bool = False, _mass_feature_anchor_technique: list = <factory>, mass_feature_anchor_techniques_available: tuple = ('deconvoluted_mass_spectra', 'absolute_intensity', 'relative_intensity'), mass_feature_anchor_absolute_intensity_threshold: int = 10000, mass_feature_anchor_relative_intensity_threshold: float = 0.6, alignment_minimum_matches: int = 5, alignment_hold_out_fraction: float = 0.3, _alignment_acceptance_technique: list = <factory>, alignment_acceptance_techniques_available: tuple = ('fraction_improved', 'mean_squared_error_improved'), alignment_acceptance_fraction_improved_threshold: float = 0.5, alignment_mz_tol_ppm: int = 5, alignment_rt_tol: float = 0.4, consensus_mz_tol_ppm: int = 5, consensus_rt_tol: float = 0.3, consensus_partition_size: int = 10000, filter_consensus_mass_features: bool = True, consensus_min_sample_fraction: float = 0.5, gap_fill_expand_on_miss: bool = True, consensus_representative_metric: str = 'intensity_prefer_ms2', consensus_representative_metrics_available: tuple = ('intensity', 'intensity_prefer_ms2'), feature_group_isotope_atoms: tuple = ('C',), feature_group_min_isotope_abundance: float = 0.01, feature_group_max_isotope_offset: int = 4, feature_group_corr_threshold: float = 0.8, feature_group_min_shared_sample_fraction: float = 0.15, feature_group_ion_types: tuple = <factory>, feature_group_constrain_annotation: bool = True, feature_group_partition_size: int = 5000)
cores: int = 1
drop_isotopologues: bool = False
mass_feature_anchor_techniques_available: tuple = ('deconvoluted_mass_spectra', 'absolute_intensity', 'relative_intensity')
mass_feature_anchor_absolute_intensity_threshold: int = 10000
mass_feature_anchor_relative_intensity_threshold: float = 0.6
alignment_minimum_matches: int = 5
alignment_hold_out_fraction: float = 0.3
alignment_acceptance_techniques_available: tuple = ('fraction_improved', 'mean_squared_error_improved')
alignment_acceptance_fraction_improved_threshold: float = 0.5
alignment_mz_tol_ppm: int = 5
alignment_rt_tol: float = 0.4
consensus_mz_tol_ppm: int = 5
consensus_rt_tol: float = 0.3
consensus_partition_size: int = 10000
filter_consensus_mass_features: bool = True
consensus_min_sample_fraction: float = 0.5
gap_fill_expand_on_miss: bool = True
consensus_representative_metric: str = 'intensity_prefer_ms2'
consensus_representative_metrics_available: tuple = ('intensity', 'intensity_prefer_ms2')
feature_group_isotope_atoms: tuple = ('C',)
feature_group_min_isotope_abundance: float = 0.01
feature_group_max_isotope_offset: int = 4
feature_group_corr_threshold: float = 0.8
feature_group_min_shared_sample_fraction: float = 0.15
feature_group_ion_types: tuple
feature_group_constrain_annotation: bool = True
feature_group_partition_size: int = 5000
alignment_acceptance_technique
1543    @property
1544    def alignment_acceptance_technique(self):
1545        return self._alignment_acceptance_technique
mass_feature_anchor_technique
1552    @property
1553    def mass_feature_anchor_technique(self):
1554        return self._mass_feature_anchor_technique