corems.mass_spectrum.factory.MassSpectrumClasses
1from pathlib import Path 2 3import numpy as np 4from lmfit.models import GaussianModel 5 6# from matplotlib import rcParamsDefault, rcParams 7from numpy import argmax, array, asarray, float64, histogram, searchsorted, where 8 9try: 10 from numpy import trapezoid 11except ImportError: # numpy < 2.0 12 from numpy import trapz as trapezoid 13from pandas import DataFrame 14 15from corems.encapsulation.constant import Labels 16from corems.encapsulation.factory.parameters import MSParameters 17from corems.encapsulation.input.parameter_from_json import ( 18 load_and_set_parameters_ms, 19 load_and_set_toml_parameters_ms, 20) 21from corems.mass_spectrum.calc.KendrickGroup import KendrickGrouping 22from corems.mass_spectrum.calc.MassSpectrumCalc import MassSpecCalc 23from corems.mass_spectrum.calc.MeanResolvingPowerFilter import MeanResolvingPowerFilter 24from corems.ms_peak.factory.MSPeakClasses import ICRMassPeak as MSPeak 25 26__author__ = "Yuri E. Corilo" 27__date__ = "Jun 12, 2019" 28 29 30def overrides(interface_class): 31 """Checks if the method overrides a method from an interface class.""" 32 33 def overrider(method): 34 assert method.__name__ in dir(interface_class) 35 return method 36 37 return overrider 38 39 40def _nearest_index_either_order(profile, value): 41 """Index into ``profile`` nearest ``value``; ``profile`` may run either 42 ascending or descending (e.g. a frequency-derived spectrum's m/z = A/f 43 runs high to low). 44 45 Clipped to ``[1, len(profile) - 2]`` so the result is always safe to 46 pass to ``find_minima()``, which looks at the neighbor on each side. 47 """ 48 n = len(profile) 49 if profile[0] <= profile[-1]: 50 idx = int(searchsorted(profile, value)) 51 else: 52 idx = n - 1 - int(searchsorted(profile[::-1], value)) 53 return min(max(idx, 1), n - 2) 54 55 56class MassSpecBase(MassSpecCalc, KendrickGrouping): 57 """A mass spectrum base class, stores the profile data and instrument settings. 58 59 Iteration over a list of MSPeaks classes stored at the _mspeaks attributes. 60 _mspeaks is populated under the hood by calling process_mass_spec method. 61 Iteration is null if _mspeaks is empty. 62 63 Parameters 64 ---------- 65 mz_exp : array_like 66 The m/z values of the mass spectrum. 67 abundance : array_like 68 The abundance values of the mass spectrum. 69 d_params : dict 70 A dictionary of parameters for the mass spectrum. 71 **kwargs 72 Additional keyword arguments. 73 74 Attributes 75 ---------- 76 77 mspeaks : list 78 A list of mass peaks. 79 is_calibrated : bool 80 Whether the mass spectrum is calibrated. 81 is_centroid : bool 82 Whether the mass spectrum is centroided. 83 has_frequency : bool 84 Whether the mass spectrum has a frequency domain. 85 calibration_order : None or int 86 The order of the mass spectrum's calibration. 87 calibration_points : None or ndarray 88 The calibration points of the mass spectrum. 89 calibration_ref_mzs: None or ndarray 90 The reference m/z values of the mass spectrum's calibration. 91 calibration_meas_mzs : None or ndarray 92 The measured m/z values of the mass spectrum's calibration. 93 calibration_RMS : None or float 94 The root mean square of the mass spectrum's calibration. 95 calibration_segment : None or CalibrationSegment 96 The calibration segment of the mass spectrum. 97 _abundance : ndarray 98 The abundance values of the mass spectrum. 99 _mz_exp : ndarray 100 The m/z values of the mass spectrum. 101 _mspeaks : list 102 A list of mass peaks. 103 _dict_nominal_masses_indexes : dict 104 A dictionary of nominal masses and their indexes. 105 _baseline_noise : float 106 The baseline noise of the mass spectrum. 107 _baseline_noise_std : float 108 The standard deviation of the baseline noise of the mass spectrum. 109 _dynamic_range : float or None 110 The dynamic range of the mass spectrum. 111 _transient_settings : None or TransientSettings 112 The transient settings of the mass spectrum. 113 _frequency_domain : None or FrequencyDomain 114 The frequency domain of the mass spectrum. 115 _mz_cal_profile : None or MzCalibrationProfile 116 The m/z calibration profile of the mass spectrum. 117 118 Methods 119 ------- 120 * process_mass_spec(). Main function to process the mass spectrum, 121 including calculating the noise threshold, peak picking, and resetting the MSpeak indexes. 122 123 See also: MassSpecCentroid(), MassSpecfromFreq(), MassSpecProfile() 124 """ 125 126 def __init__(self, mz_exp, abundance, d_params, **kwargs): 127 self._abundance = array(abundance, dtype=float64) 128 self._mz_exp = array(mz_exp, dtype=float64) 129 130 # objects created after process_mass_spec() function 131 self._mspeaks = list() 132 self.mspeaks = list() 133 self._dict_nominal_masses_indexes = dict() 134 self._baseline_noise = 0.001 135 self._baseline_noise_std = 0.001 136 self._dynamic_range = None 137 # set to None: initialization occurs inside subclass MassSpecfromFreq 138 self._transient_settings = None 139 self._frequency_domain = None 140 self._mz_cal_profile = None 141 self.is_calibrated = False 142 143 self._set_parameters_objects(d_params) 144 self._init_settings() 145 146 self.is_centroid = False 147 self.has_frequency = False 148 149 self.calibration_order = None 150 self.calibration_points = None 151 self.calibration_ref_mzs = None 152 self.calibration_meas_mzs = None 153 self.calibration_RMS = None 154 self.calibration_segment = None 155 self.calibration_raw_error_median = None 156 self.calibration_raw_error_stdev = None 157 158 def _init_settings(self): 159 """Initializes the settings for the mass spectrum.""" 160 self._parameters = MSParameters() 161 162 def __len__(self): 163 return len(self.mspeaks) 164 165 def __getitem__(self, position) -> MSPeak: 166 return self.mspeaks[position] 167 168 def set_indexes(self, list_indexes): 169 """Set the mass spectrum to iterate over only the selected MSpeaks indexes. 170 171 Parameters 172 ---------- 173 list_indexes : list of int 174 A list of integers representing the indexes of the MSpeaks to iterate over. 175 176 """ 177 self.mspeaks = [self._mspeaks[i] for i in list_indexes] 178 179 for i, mspeak in enumerate(self.mspeaks): 180 mspeak.index = i 181 182 self._set_nominal_masses_start_final_indexes() 183 184 def reset_indexes(self): 185 """Reset the mass spectrum to iterate over all MSpeaks objects. 186 187 This method resets the mass spectrum to its original state, allowing iteration over all MSpeaks objects. 188 It also sets the index of each MSpeak object to its corresponding position in the mass spectrum. 189 190 """ 191 self.mspeaks = self._mspeaks 192 193 for i, mspeak in enumerate(self.mspeaks): 194 mspeak.index = i 195 196 self._set_nominal_masses_start_final_indexes() 197 198 def add_mspeak( 199 self, 200 polarity, 201 mz_exp, 202 abundance, 203 resolving_power, 204 signal_to_noise, 205 massspec_indexes, 206 exp_freq=None, 207 ms_parent=None, 208 **kwargs, 209 ): 210 """Add a new MSPeak object to the MassSpectrum object. 211 212 Parameters 213 ---------- 214 polarity : int 215 Acquisition polarity of the MSPeak (``+1`` or ``-1``). 216 Do **not** pass ``ion_charge``; peaks store polarity only. 217 Assignment charge lives on ``MolecularFormula.ion_charge``. 218 mz_exp : float 219 The experimental m/z value of the MSPeak. 220 abundance : float 221 The abundance of the MSPeak. 222 resolving_power : float 223 The resolving power of the MSPeak. 224 signal_to_noise : float 225 The signal-to-noise ratio of the MSPeak. 226 massspec_indexes : list 227 A list of indexes of the MSPeak in the MassSpectrum object. 228 exp_freq : float, optional 229 The experimental frequency of the MSPeak. Defaults to None. 230 ms_parent : MSParent, optional 231 The MSParent object associated with the MSPeak. Defaults to None. 232 233 Raises 234 ------ 235 TypeError 236 If ``ion_charge`` is passed (removed; use ``polarity``), or if any 237 other unexpected keyword argument is given. 238 """ 239 if "ion_charge" in kwargs: 240 raise TypeError( 241 "add_mspeak() no longer accepts ion_charge=...; pass polarity " 242 "(±1) instead. Peaks store acquisition polarity only. Assignment " 243 "charge belongs on MolecularFormula.ion_charge after formula matching." 244 ) 245 if kwargs: 246 unexpected = ", ".join(sorted(kwargs)) 247 raise TypeError( 248 f"add_mspeak() got unexpected keyword argument(s): {unexpected}" 249 ) 250 251 mspeak = MSPeak( 252 polarity, 253 mz_exp, 254 abundance, 255 resolving_power, 256 signal_to_noise, 257 massspec_indexes, 258 len(self._mspeaks), 259 exp_freq=exp_freq, 260 ms_parent=ms_parent, 261 ) 262 263 self._mspeaks.append(mspeak) 264 265 def _set_parameters_objects(self, d_params): 266 """Set the parameters of the MassSpectrum object. 267 268 Parameters 269 ---------- 270 d_params : dict 271 A dictionary containing the parameters to set. 272 273 Notes 274 ----- 275 This method sets the following parameters of the MassSpectrum object: 276 - _calibration_terms 277 - label 278 - analyzer 279 - acquisition_time 280 - instrument_label 281 - polarity 282 - scan_number 283 - retention_time 284 - mobility_rt 285 - mobility_scan 286 - _filename 287 - _dir_location 288 - _baseline_noise 289 - _baseline_noise_std 290 - sample_name 291 """ 292 self._calibration_terms = ( 293 d_params.get("Aterm"), 294 d_params.get("Bterm"), 295 d_params.get("Cterm"), 296 ) 297 298 self.label = d_params.get(Labels.label) 299 300 self.analyzer = d_params.get("analyzer") 301 302 self.acquisition_time = d_params.get("acquisition_time") 303 304 self.instrument_label = d_params.get("instrument_label") 305 306 self.polarity = int(d_params.get("polarity")) 307 308 self.scan_number = d_params.get("scan_number") 309 310 self.retention_time = d_params.get("rt") 311 312 self.mobility_rt = d_params.get("mobility_rt") 313 314 self.mobility_scan = d_params.get("mobility_scan") 315 316 self._filename = d_params.get("filename_path") 317 318 self._dir_location = d_params.get("dir_location") 319 320 self._baseline_noise = d_params.get("baseline_noise") 321 322 self._baseline_noise_std = d_params.get("baseline_noise_std") 323 324 if d_params.get("sample_name") != "Unknown": 325 self.sample_name = d_params.get("sample_name") 326 if not self.sample_name: 327 self.sample_name = self.filename.stem 328 else: 329 self.sample_name = self.filename.stem 330 331 def reset_cal_therms(self, Aterm, Bterm, C, fas=0): 332 """Reset calibration terms and recalculate the mass-to-charge ratio and abundance. 333 334 Parameters 335 ---------- 336 Aterm : float 337 The A-term calibration coefficient. 338 Bterm : float 339 The B-term calibration coefficient. 340 C : float 341 The C-term calibration coefficient. 342 fas : float, optional 343 The frequency amplitude scaling factor. Default is 0. 344 """ 345 self._calibration_terms = (Aterm, Bterm, C) 346 347 self._mz_exp = self._f_to_mz() 348 self._abundance = self._abundance 349 self.find_peaks() 350 self.reset_indexes() 351 352 def clear_molecular_formulas(self): 353 """Clear the molecular formulas for all mspeaks in the MassSpectrum. 354 355 Returns 356 ------- 357 numpy.ndarray 358 An array of the cleared molecular formulas for each mspeak in the MassSpectrum. 359 """ 360 self.check_mspeaks() 361 return array([mspeak.clear_molecular_formulas() for mspeak in self.mspeaks]) 362 363 def process_mass_spec(self, keep_profile=True): 364 """Process the mass spectrum. 365 366 Parameters 367 ---------- 368 keep_profile : bool, optional 369 Whether to keep the profile data after processing. Defaults to True. 370 371 Notes 372 ----- 373 This method does the following: 374 - calculates the noise threshold 375 - does peak picking (creates mspeak_objs) 376 - resets the mspeak_obj indexes 377 """ 378 379 # if runned mannually make sure to rerun filter_by_noise_threshold 380 # calculates noise threshold 381 # do peak picking( create mspeak_objs) 382 # reset mspeak_obj the indexes 383 384 self.cal_noise_threshold() 385 386 self.find_peaks() 387 self.reset_indexes() 388 389 if self.mspeaks: 390 self._dynamic_range = self.max_abundance / self.min_abundance 391 else: 392 self._dynamic_range = 0 393 if not keep_profile: 394 self._abundance *= 0 395 self._mz_exp *= 0 396 397 def _resolve_noise_threshold_method(self): 398 """Resolve ``by_format`` and store the concrete noise-threshold method. 399 400 Profile spectra use ``log``. Centroid spectra use 401 ``relative_abundance``. An explicit method is left unchanged. 402 ``by_format`` is replaced on this spectrum's settings so saved 403 parameters record what was used. 404 405 Returns 406 ------- 407 str 408 Concrete noise-threshold method. 409 """ 410 method = self.settings.noise_threshold_method 411 if method != "by_format": 412 return method 413 resolved = "relative_abundance" if self.is_centroid else "log" 414 self.settings.noise_threshold_method = resolved 415 return resolved 416 417 def cal_noise_threshold(self): 418 """Calculate the noise threshold of the mass spectrum.""" 419 420 self._resolve_noise_threshold_method() 421 422 if self.label == Labels.simulated_profile: 423 self._baseline_noise, self._baseline_noise_std = 0.1, 1 424 425 if self.settings.noise_threshold_method == "log": 426 self._baseline_noise, self._baseline_noise_std = ( 427 self.run_log_noise_threshold_calc() 428 ) 429 430 else: 431 self._baseline_noise, self._baseline_noise_std = ( 432 self.run_noise_threshold_calc() 433 ) 434 435 @property 436 def parameters(self): 437 """Return the parameters of the mass spectrum.""" 438 return self._parameters 439 440 @parameters.setter 441 def parameters(self, instance_MSParameters): 442 self._parameters = instance_MSParameters 443 444 def set_parameter_from_json(self, parameters_path): 445 """Set the parameters of the mass spectrum from a JSON file. 446 447 Parameters 448 ---------- 449 parameters_path : str 450 The path to the JSON file containing the parameters. 451 """ 452 load_and_set_parameters_ms(self, parameters_path=parameters_path) 453 454 def set_parameter_from_toml(self, parameters_path): 455 load_and_set_toml_parameters_ms(self, parameters_path=parameters_path) 456 457 @property 458 def mspeaks_settings(self): 459 """Return the MS peak settings of the mass spectrum.""" 460 return self.parameters.ms_peak 461 462 @mspeaks_settings.setter 463 def mspeaks_settings(self, instance_MassSpecPeakSetting): 464 self.parameters.ms_peak = instance_MassSpecPeakSetting 465 466 @property 467 def settings(self): 468 """Return the settings of the mass spectrum.""" 469 return self.parameters.mass_spectrum 470 471 @settings.setter 472 def settings(self, instance_MassSpectrumSetting): 473 self.parameters.mass_spectrum = instance_MassSpectrumSetting 474 475 @property 476 def molecular_search_settings(self): 477 """Return the molecular search settings of the mass spectrum.""" 478 return self.parameters.molecular_search 479 480 @molecular_search_settings.setter 481 def molecular_search_settings(self, instance_MolecularFormulaSearchSettings): 482 self.parameters.molecular_search = instance_MolecularFormulaSearchSettings 483 484 @property 485 def mz_cal_profile(self): 486 """Return the calibrated m/z profile of the mass spectrum.""" 487 return self._mz_cal_profile 488 489 @mz_cal_profile.setter 490 def mz_cal_profile(self, mz_cal_list): 491 if len(mz_cal_list) == len(self._mz_exp): 492 self._mz_cal_profile = mz_cal_list 493 else: 494 raise Exception( 495 "calibrated array (%i) is not of the same size of the data (%i)" 496 % (len(mz_cal_list), len(self.mz_exp_profile)) 497 ) 498 499 @property 500 def mz_cal(self): 501 """Return the calibrated m/z values of the mass spectrum.""" 502 return array([mspeak.mz_cal for mspeak in self.mspeaks]) 503 504 @mz_cal.setter 505 def mz_cal(self, mz_cal_list): 506 if len(mz_cal_list) == len(self.mspeaks): 507 self.is_calibrated = True 508 for index, mz_cal in enumerate(mz_cal_list): 509 self.mspeaks[index].mz_cal = mz_cal 510 else: 511 raise Exception( 512 "calibrated array (%i) is not of the same size of the data (%i)" 513 % (len(mz_cal_list), len(self._mspeaks)) 514 ) 515 516 @property 517 def mz_exp(self): 518 """Return the experimental m/z values of the mass spectrum.""" 519 self.check_mspeaks() 520 521 if self.is_calibrated: 522 return array([mspeak.mz_cal for mspeak in self.mspeaks]) 523 524 else: 525 return array([mspeak.mz_exp for mspeak in self.mspeaks]) 526 527 @property 528 def freq_exp_profile(self): 529 """Return the experimental frequency profile of the mass spectrum.""" 530 return self._frequency_domain 531 532 @freq_exp_profile.setter 533 def freq_exp_profile(self, new_data): 534 self._frequency_domain = array(new_data) 535 536 @property 537 def freq_exp_pp(self): 538 """Return the experimental frequency values of the mass spectrum that are used for peak picking.""" 539 _, _, freq = self.prepare_peak_picking_data() 540 return freq 541 542 @property 543 def mz_exp_profile(self): 544 """Return the experimental m/z profile of the mass spectrum.""" 545 if self.is_calibrated: 546 return self.mz_cal_profile 547 else: 548 return self._mz_exp 549 550 @mz_exp_profile.setter 551 def mz_exp_profile(self, new_data): 552 self._mz_exp = array(new_data) 553 554 @property 555 def mz_exp_pp(self): 556 """Return the experimental m/z values of the mass spectrum that are used for peak picking.""" 557 mz, _, _ = self.prepare_peak_picking_data() 558 return mz 559 560 @property 561 def abundance_profile(self): 562 """Return the abundance profile of the mass spectrum.""" 563 return self._abundance 564 565 @abundance_profile.setter 566 def abundance_profile(self, new_data): 567 self._abundance = array(new_data) 568 569 @property 570 def abundance_profile_pp(self): 571 """Return the abundance profile of the mass spectrum that is used for peak picking.""" 572 _, abundance, _ = self.prepare_peak_picking_data() 573 return abundance 574 575 @property 576 def abundance(self): 577 """Return the abundance values of the mass spectrum.""" 578 self.check_mspeaks() 579 return array([mspeak.abundance for mspeak in self.mspeaks]) 580 581 def freq_exp(self): 582 """Return the experimental frequency values of the mass spectrum.""" 583 self.check_mspeaks() 584 return array([mspeak.freq_exp for mspeak in self.mspeaks]) 585 586 @property 587 def resolving_power(self): 588 """Return the resolving power values of the mass spectrum.""" 589 self.check_mspeaks() 590 return array([mspeak.resolving_power for mspeak in self.mspeaks]) 591 592 @property 593 def signal_to_noise(self): 594 self.check_mspeaks() 595 return array([mspeak.signal_to_noise for mspeak in self.mspeaks]) 596 597 @property 598 def nominal_mz(self): 599 """Return the nominal m/z values of the mass spectrum.""" 600 if self._dict_nominal_masses_indexes: 601 return sorted(list(self._dict_nominal_masses_indexes.keys())) 602 else: 603 raise ValueError("Nominal indexes not yet set") 604 605 def get_mz_and_abundance_peaks_tuples(self): 606 """Return a list of tuples containing the m/z and abundance values of the mass spectrum.""" 607 self.check_mspeaks() 608 return [(mspeak.mz_exp, mspeak.abundance) for mspeak in self.mspeaks] 609 610 @property 611 def kmd(self): 612 """Return the Kendrick mass defect values of the mass spectrum.""" 613 self.check_mspeaks() 614 return array([mspeak.kmd for mspeak in self.mspeaks]) 615 616 @property 617 def kendrick_mass(self): 618 """Return the Kendrick mass values of the mass spectrum.""" 619 self.check_mspeaks() 620 return array([mspeak.kendrick_mass for mspeak in self.mspeaks]) 621 622 @property 623 def max_mz_exp(self): 624 """Return the maximum experimental m/z value of the mass spectrum.""" 625 return max([mspeak.mz_exp for mspeak in self.mspeaks]) 626 627 @property 628 def min_mz_exp(self): 629 """Return the minimum experimental m/z value of the mass spectrum.""" 630 return min([mspeak.mz_exp for mspeak in self.mspeaks]) 631 632 @property 633 def max_abundance(self): 634 """Return the maximum abundance value of the mass spectrum.""" 635 return max([mspeak.abundance for mspeak in self.mspeaks]) 636 637 @property 638 def max_signal_to_noise(self): 639 """Return the maximum signal-to-noise ratio of the mass spectrum.""" 640 return max([mspeak.signal_to_noise for mspeak in self.mspeaks]) 641 642 @property 643 def most_abundant_mspeak(self): 644 """Return the most abundant MSpeak object of the mass spectrum.""" 645 return max(self.mspeaks, key=lambda m: m.abundance) 646 647 @property 648 def min_abundance(self): 649 """Return the minimum abundance value of the mass spectrum.""" 650 return min([mspeak.abundance for mspeak in self.mspeaks]) 651 652 # takes too much cpu time 653 @property 654 def dynamic_range(self): 655 """Return the dynamic range of the mass spectrum.""" 656 return self._dynamic_range 657 658 @property 659 def baseline_noise(self): 660 """Return the baseline noise of the mass spectrum.""" 661 if self._baseline_noise: 662 return self._baseline_noise 663 else: 664 return None 665 666 @property 667 def baseline_noise_std(self): 668 """Return the standard deviation of the baseline noise of the mass spectrum.""" 669 if self._baseline_noise_std == 0: 670 return self._baseline_noise_std 671 if self._baseline_noise_std: 672 return self._baseline_noise_std 673 else: 674 return None 675 676 @property 677 def Aterm(self): 678 """Return the A-term calibration coefficient of the mass spectrum.""" 679 return self._calibration_terms[0] 680 681 @property 682 def Bterm(self): 683 """Return the B-term calibration coefficient of the mass spectrum.""" 684 return self._calibration_terms[1] 685 686 @property 687 def Cterm(self): 688 """Return the C-term calibration coefficient of the mass spectrum.""" 689 return self._calibration_terms[2] 690 691 @property 692 def filename(self): 693 """Return the filename of the mass spectrum.""" 694 return Path(self._filename) 695 696 @property 697 def dir_location(self): 698 """Return the directory location of the mass spectrum.""" 699 return self._dir_location 700 701 def sort_by_mz(self): 702 """Sort the mass spectrum by m/z values.""" 703 return sorted(self, key=lambda m: m.mz_exp) 704 705 def sort_by_abundance(self, reverse=False): 706 """Sort the mass spectrum by abundance values.""" 707 return sorted(self, key=lambda m: m.abundance, reverse=reverse) 708 709 @property 710 def tic(self): 711 """Return the total ion current of the mass spectrum.""" 712 return trapezoid(self.abundance_profile, self.mz_exp_profile) 713 714 def check_mspeaks_warning(self): 715 """Check if the mass spectrum has MSpeaks objects. 716 717 Raises 718 ------ 719 Warning 720 If the mass spectrum has no MSpeaks objects. 721 """ 722 import warnings 723 724 if self.mspeaks: 725 pass 726 else: 727 warnings.warn("mspeaks list is empty, continuing without filtering data") 728 729 def check_mspeaks(self): 730 """Check if the mass spectrum has MSpeaks objects. 731 732 Raises 733 ------ 734 Exception 735 If the mass spectrum has no MSpeaks objects. 736 """ 737 if self.mspeaks: 738 pass 739 else: 740 raise Exception( 741 "mspeaks list is empty, please run process_mass_spec() first" 742 ) 743 744 def remove_assignment_by_index(self, indexes): 745 """Remove the molecular formula assignment of the MSpeaks objects at the specified indexes. 746 747 Parameters 748 ---------- 749 indexes : list of int 750 A list of indexes of the MSpeaks objects to remove the molecular formula assignment from. 751 """ 752 for i in indexes: 753 self.mspeaks[i].clear_molecular_formulas() 754 755 def filter_by_index(self, list_indexes): 756 """Filter the mass spectrum by the specified indexes. 757 758 Parameters 759 ---------- 760 list_indexes : list of int 761 A list of indexes of the MSpeaks objects to drop. 762 763 """ 764 765 self.mspeaks = [ 766 self.mspeaks[i] for i in range(len(self.mspeaks)) if i not in list_indexes 767 ] 768 769 for i, mspeak in enumerate(self.mspeaks): 770 mspeak.index = i 771 772 self._set_nominal_masses_start_final_indexes() 773 774 def filter_by_mz(self, min_mz, max_mz): 775 """Filter the mass spectrum by the specified m/z range. 776 777 Parameters 778 ---------- 779 min_mz : float 780 The minimum m/z value to keep. 781 max_mz : float 782 The maximum m/z value to keep. 783 784 """ 785 self.check_mspeaks_warning() 786 indexes = [ 787 index 788 for index, mspeak in enumerate(self.mspeaks) 789 if not min_mz <= mspeak.mz_exp <= max_mz 790 ] 791 self.filter_by_index(indexes) 792 793 def filter_by_s2n(self, min_s2n, max_s2n=False): 794 """Filter the mass spectrum by the specified signal-to-noise ratio range. 795 796 Parameters 797 ---------- 798 min_s2n : float 799 The minimum signal-to-noise ratio to keep. 800 max_s2n : float, optional 801 The maximum signal-to-noise ratio to keep. Defaults to False (no maximum). 802 803 """ 804 self.check_mspeaks_warning() 805 if max_s2n: 806 indexes = [ 807 index 808 for index, mspeak in enumerate(self.mspeaks) 809 if not min_s2n <= mspeak.signal_to_noise <= max_s2n 810 ] 811 else: 812 indexes = [ 813 index 814 for index, mspeak in enumerate(self.mspeaks) 815 if mspeak.signal_to_noise <= min_s2n 816 ] 817 self.filter_by_index(indexes) 818 819 def filter_by_abundance(self, min_abund, max_abund=False): 820 """Filter the mass spectrum by the specified abundance range. 821 822 Parameters 823 ---------- 824 min_abund : float 825 The minimum abundance to keep. 826 max_abund : float, optional 827 The maximum abundance to keep. Defaults to False (no maximum). 828 829 """ 830 self.check_mspeaks_warning() 831 if max_abund: 832 indexes = [ 833 index 834 for index, mspeak in enumerate(self.mspeaks) 835 if not min_abund <= mspeak.abundance <= max_abund 836 ] 837 else: 838 indexes = [ 839 index 840 for index, mspeak in enumerate(self.mspeaks) 841 if mspeak.abundance <= min_abund 842 ] 843 self.filter_by_index(indexes) 844 845 def filter_by_max_resolving_power(self, B, T): 846 """Filter the mass spectrum by the specified maximum resolving power. 847 848 Parameters 849 ---------- 850 B : float 851 T : float 852 853 """ 854 855 rpe = lambda m, z: (1.274e7 * z * B * T) / (m * z) 856 857 self.check_mspeaks_warning() 858 859 indexes_to_remove = [ 860 index 861 for index, mspeak in enumerate(self.mspeaks) 862 if mspeak.resolving_power >= rpe(mspeak.mz_exp, mspeak.polarity) 863 ] 864 self.filter_by_index(indexes_to_remove) 865 866 def filter_by_mean_resolving_power( 867 self, ndeviations=3, plot=False, guess_pars=False 868 ): 869 """Filter the mass spectrum by the specified mean resolving power. 870 871 Parameters 872 ---------- 873 ndeviations : float, optional 874 The number of standard deviations to use for filtering. Defaults to 3. 875 plot : bool, optional 876 Whether to plot the resolving power distribution. Defaults to False. 877 guess_pars : bool, optional 878 Whether to guess the parameters for the Gaussian model. Defaults to False. 879 880 """ 881 self.check_mspeaks_warning() 882 indexes_to_remove = MeanResolvingPowerFilter( 883 self, ndeviations, plot, guess_pars 884 ).main() 885 self.filter_by_index(indexes_to_remove) 886 887 def filter_by_min_resolving_power( 888 self, B, T, apodization_method: str = None, tolerance: float = 0 889 ): 890 """Filter the mass spectrum by the calculated minimum theoretical resolving power. 891 892 This is currently designed only for FTICR data, and accounts only for magnitude mode data 893 Accurate results require passing the apodisaion method used to calculate the resolving power. 894 see the ICRMassPeak function `resolving_power_calc` for more details. 895 896 Parameters 897 ---------- 898 B : Magnetic field strength in Tesla, float 899 T : transient length in seconds, float 900 apodization_method : str, optional 901 The apodization method to use for calculating the resolving power. Defaults to None. 902 tolerance : float, optional 903 The tolerance for the threshold. Defaults to 0, i.e. no tolerance 904 905 """ 906 if self.analyzer != "ICR": 907 raise Exception("This method is only applicable to ICR mass spectra. ") 908 909 self.check_mspeaks_warning() 910 911 indexes_to_remove = [ 912 index 913 for index, mspeak in enumerate(self.mspeaks) 914 if mspeak.resolving_power 915 < (1 - tolerance) 916 * mspeak.resolving_power_calc(B, T, apodization_method=apodization_method) 917 ] 918 self.filter_by_index(indexes_to_remove) 919 920 def filter_by_noise_threshold(self): 921 """Filter the mass spectrum by the noise threshold.""" 922 923 threshold = self.get_noise_threshold()[1][0] 924 925 self.check_mspeaks_warning() 926 927 indexes_to_remove = [ 928 index 929 for index, mspeak in enumerate(self.mspeaks) 930 if mspeak.abundance <= threshold 931 ] 932 self.filter_by_index(indexes_to_remove) 933 934 def find_peaks(self): 935 """Find the peaks of the mass spectrum.""" 936 # needs to clear previous results from peak_picking 937 self._mspeaks = list() 938 939 # then do peak picking 940 self.do_peak_picking() 941 # print("A total of %i peaks were found" % len(self._mspeaks)) 942 943 def change_kendrick_base_all_mspeaks(self, kendrick_dict_base): 944 """Change the Kendrick base of all MSpeaks objects. 945 946 Parameters 947 ---------- 948 kendrick_dict_base : dict 949 A dictionary of the Kendrick base to change to. 950 951 Notes 952 ----- 953 Example of kendrick_dict_base parameter: kendrick_dict_base = {"C": 1, "H": 2} or {"C": 1, "H": 1, "O":1} etc 954 """ 955 self.parameters.ms_peak.kendrick_base = kendrick_dict_base 956 957 for mspeak in self.mspeaks: 958 mspeak.change_kendrick_base(kendrick_dict_base) 959 960 def get_nominal_mz_first_last_indexes(self, nominal_mass): 961 """Return the first and last indexes of the MSpeaks objects with the specified nominal mass. 962 963 Parameters 964 ---------- 965 nominal_mass : int 966 The nominal mass to get the indexes for. 967 968 Returns 969 ------- 970 tuple 971 A tuple containing the first and last indexes of the MSpeaks objects with the specified nominal mass. 972 """ 973 if self._dict_nominal_masses_indexes: 974 if nominal_mass in self._dict_nominal_masses_indexes.keys(): 975 return ( 976 self._dict_nominal_masses_indexes.get(nominal_mass)[0], 977 self._dict_nominal_masses_indexes.get(nominal_mass)[1] + 1, 978 ) 979 980 else: 981 # import warnings 982 # uncomment warn to distribution 983 # warnings.warn("Nominal mass not found in _dict_nominal_masses_indexes, returning (0, 0) for nominal mass %i"%nominal_mass) 984 return (0, 0) 985 else: 986 raise Exception( 987 "run process_mass_spec() function before trying to access the data" 988 ) 989 990 def get_masses_count_by_nominal_mass(self): 991 """Return a dictionary of the nominal masses and their counts.""" 992 993 dict_nominal_masses_count = {} 994 995 all_nominal_masses = list(set([i.nominal_mz_exp for i in self.mspeaks])) 996 997 for nominal_mass in all_nominal_masses: 998 if nominal_mass not in dict_nominal_masses_count: 999 dict_nominal_masses_count[nominal_mass] = len( 1000 list(self.get_nominal_mass_indexes(nominal_mass)) 1001 ) 1002 1003 return dict_nominal_masses_count 1004 1005 def datapoints_count_by_nominal_mz(self, mz_overlay=0.1): 1006 """Return a dictionary of the nominal masses and their counts. 1007 1008 Parameters 1009 ---------- 1010 mz_overlay : float, optional 1011 The m/z overlay to use for counting. Defaults to 0.1. 1012 1013 Returns 1014 ------- 1015 dict 1016 A dictionary of the nominal masses and their counts. 1017 """ 1018 dict_nominal_masses_count = {} 1019 1020 all_nominal_masses = list(set([i.nominal_mz_exp for i in self.mspeaks])) 1021 1022 for nominal_mass in all_nominal_masses: 1023 if nominal_mass not in dict_nominal_masses_count: 1024 min_mz = nominal_mass - mz_overlay 1025 1026 max_mz = nominal_mass + 1 + mz_overlay 1027 1028 indexes = indexes = where( 1029 (self.mz_exp_profile > min_mz) & (self.mz_exp_profile < max_mz) 1030 ) 1031 1032 dict_nominal_masses_count[nominal_mass] = indexes[0].size 1033 1034 return dict_nominal_masses_count 1035 1036 def get_nominal_mass_indexes(self, nominal_mass, overlay=0.1): 1037 """Return the indexes of the MSpeaks objects with the specified nominal mass. 1038 1039 Parameters 1040 ---------- 1041 nominal_mass : int 1042 The nominal mass to get the indexes for. 1043 overlay : float, optional 1044 The m/z overlay to use for counting. Defaults to 0.1. 1045 1046 Returns 1047 ------- 1048 generator 1049 A generator of the indexes of the MSpeaks objects with the specified nominal mass. 1050 """ 1051 min_mz_to_look = nominal_mass - overlay 1052 max_mz_to_look = nominal_mass + 1 + overlay 1053 1054 return ( 1055 i 1056 for i in range(len(self.mspeaks)) 1057 if min_mz_to_look <= self.mspeaks[i].mz_exp <= max_mz_to_look 1058 ) 1059 1060 # indexes = (i for i in range(len(self.mspeaks)) if min_mz_to_look <= self.mspeaks[i].mz_exp <= max_mz_to_look) 1061 # return indexes 1062 1063 def _set_nominal_masses_start_final_indexes(self): 1064 """Set the start and final indexes of the MSpeaks objects for all nominal masses.""" 1065 dict_nominal_masses_indexes = {} 1066 1067 all_nominal_masses = set(i.nominal_mz_exp for i in self.mspeaks) 1068 1069 for nominal_mass in all_nominal_masses: 1070 # indexes = self.get_nominal_mass_indexes(nominal_mass) 1071 # Convert the iterator to a list to avoid multiple calls 1072 indexes = list(self.get_nominal_mass_indexes(nominal_mass)) 1073 1074 # If the list is not empty, find the first and last; otherwise, set None 1075 if indexes: 1076 first, last = indexes[0], indexes[-1] 1077 else: 1078 first = last = None 1079 # defaultvalue = None 1080 # first = last = next(indexes, defaultvalue) 1081 # for last in indexes: 1082 # pass 1083 1084 dict_nominal_masses_indexes[nominal_mass] = (first, last) 1085 1086 self._dict_nominal_masses_indexes = dict_nominal_masses_indexes 1087 1088 def plot_centroid(self, ax=None, c="g"): 1089 """Plot the centroid data of the mass spectrum. 1090 1091 Parameters 1092 ---------- 1093 ax : matplotlib.axes.Axes, optional 1094 The matplotlib axes to plot on. Defaults to None. 1095 c : str, optional 1096 The color to use for the plot. Defaults to 'g' (green). 1097 1098 Returns 1099 ------- 1100 matplotlib.axes.Axes 1101 The matplotlib axes containing the plot. 1102 1103 Raises 1104 ------ 1105 Exception 1106 If no centroid data is found. 1107 """ 1108 1109 import matplotlib.pyplot as plt 1110 1111 if self._mspeaks: 1112 if ax is None: 1113 ax = plt.gca() 1114 1115 markerline_a, stemlines_a, baseline_a = ax.stem( 1116 self.mz_exp, self.abundance, linefmt="-", markerfmt=" " 1117 ) 1118 1119 plt.setp(markerline_a, "color", c, "linewidth", 2) 1120 plt.setp(stemlines_a, "color", c, "linewidth", 2) 1121 plt.setp(baseline_a, "color", c, "linewidth", 2) 1122 1123 ax.set_xlabel("$\t{m/z}$", fontsize=12) 1124 ax.set_ylabel("Abundance", fontsize=12) 1125 ax.tick_params(axis="both", which="major", labelsize=12) 1126 1127 ax.axes.spines["top"].set_visible(False) 1128 ax.axes.spines["right"].set_visible(False) 1129 1130 ax.get_yaxis().set_visible(False) 1131 ax.spines["left"].set_visible(False) 1132 1133 else: 1134 raise Exception("No centroid data found, please run process_mass_spec") 1135 1136 return ax 1137 1138 def plot_profile_and_noise_threshold(self, ax=None, legend=False): 1139 """Plot the profile data and noise threshold of the mass spectrum. 1140 1141 Parameters 1142 ---------- 1143 ax : matplotlib.axes.Axes, optional 1144 The matplotlib axes to plot on. Defaults to None. 1145 legend : bool, optional 1146 Whether to show the legend. Defaults to False. 1147 1148 Returns 1149 ------- 1150 matplotlib.axes.Axes 1151 The matplotlib axes containing the plot. 1152 1153 Raises 1154 ------ 1155 Exception 1156 If no noise threshold is found. 1157 """ 1158 import matplotlib.pyplot as plt 1159 1160 if self.baseline_noise_std and self.baseline_noise_std: 1161 # x = (self.mz_exp_profile.min(), self.mz_exp_profile.max()) 1162 baseline = (self.baseline_noise, self.baseline_noise) 1163 1164 # std = self.parameters.mass_spectrum.noise_threshold_min_std 1165 # threshold = self.baseline_noise_std + (std * self.baseline_noise_std) 1166 x, y = self.get_noise_threshold() 1167 1168 if ax is None: 1169 ax = plt.gca() 1170 1171 ax.plot( 1172 self.mz_exp_profile, 1173 self.abundance_profile, 1174 color="green", 1175 label="Spectrum", 1176 ) 1177 ax.plot(x, (baseline, baseline), color="yellow", label="Baseline Noise") 1178 ax.plot(x, y, color="red", label="Noise Threshold") 1179 1180 ax.set_xlabel("$\t{m/z}$", fontsize=12) 1181 ax.set_ylabel("Abundance", fontsize=12) 1182 ax.tick_params(axis="both", which="major", labelsize=12) 1183 1184 ax.axes.spines["top"].set_visible(False) 1185 ax.axes.spines["right"].set_visible(False) 1186 1187 ax.get_yaxis().set_visible(False) 1188 ax.spines["left"].set_visible(False) 1189 if legend: 1190 ax.legend() 1191 1192 else: 1193 raise Exception("Calculate noise threshold first") 1194 1195 return ax 1196 1197 def plot_mz_domain_profile(self, color="green", ax=None): 1198 """Plot the m/z domain profile of the mass spectrum. 1199 1200 Parameters 1201 ---------- 1202 color : str, optional 1203 The color to use for the plot. Defaults to 'green'. 1204 ax : matplotlib.axes.Axes, optional 1205 The matplotlib axes to plot on. Defaults to None. 1206 1207 Returns 1208 ------- 1209 matplotlib.axes.Axes 1210 The matplotlib axes containing the plot. 1211 """ 1212 1213 import matplotlib.pyplot as plt 1214 1215 if ax is None: 1216 ax = plt.gca() 1217 ax.plot(self.mz_exp_profile, self.abundance_profile, color=color) 1218 ax.set(xlabel="m/z", ylabel="abundance") 1219 1220 return ax 1221 1222 def to_excel(self, out_file_path, write_metadata=True): 1223 """Export the mass spectrum to an Excel file. 1224 1225 Parameters 1226 ---------- 1227 out_file_path : str 1228 The path to the Excel file to export to. 1229 write_metadata : bool, optional 1230 Whether to write the metadata to the Excel file. Defaults to True. 1231 1232 Returns 1233 ------- 1234 None 1235 """ 1236 from corems.mass_spectrum.output.export import HighResMassSpecExport 1237 1238 exportMS = HighResMassSpecExport(out_file_path, self) 1239 exportMS.to_excel(write_metadata=write_metadata) 1240 1241 def to_hdf(self, out_file_path): 1242 """Export the mass spectrum to an HDF file. 1243 1244 Parameters 1245 ---------- 1246 out_file_path : str 1247 The path to the HDF file to export to. 1248 1249 Returns 1250 ------- 1251 None 1252 """ 1253 from corems.mass_spectrum.output.export import HighResMassSpecExport 1254 1255 exportMS = HighResMassSpecExport(out_file_path, self) 1256 exportMS.to_hdf() 1257 1258 def to_csv(self, out_file_path, write_metadata=True): 1259 """Export the mass spectrum to a CSV file. 1260 1261 Parameters 1262 ---------- 1263 out_file_path : str 1264 The path to the CSV file to export to. 1265 write_metadata : bool, optional 1266 Whether to write the metadata to the CSV file. Defaults to True. 1267 1268 """ 1269 from corems.mass_spectrum.output.export import HighResMassSpecExport 1270 1271 exportMS = HighResMassSpecExport(out_file_path, self) 1272 exportMS.to_csv(write_metadata=write_metadata) 1273 1274 def to_pandas(self, out_file_path, write_metadata=True): 1275 """Export the mass spectrum to a Pandas dataframe with pkl extension. 1276 1277 Parameters 1278 ---------- 1279 out_file_path : str 1280 The path to the CSV file to export to. 1281 write_metadata : bool, optional 1282 Whether to write the metadata to the CSV file. Defaults to True. 1283 1284 """ 1285 from corems.mass_spectrum.output.export import HighResMassSpecExport 1286 1287 exportMS = HighResMassSpecExport(out_file_path, self) 1288 exportMS.to_pandas(write_metadata=write_metadata) 1289 1290 def to_parquet(self, out_file_path, write_metadata=True): 1291 """Export the mass spectrum to a Parquet file. 1292 1293 Parameters 1294 ---------- 1295 out_file_path : str 1296 The path to the Parquet file to export to. 1297 write_metadata : bool, optional 1298 Whether to write the metadata to a JSON file. Defaults to True. 1299 1300 Notes 1301 ----- 1302 Requires ``pyarrow`` (or ``fastparquet``) for pandas Parquet I/O. 1303 """ 1304 from corems.mass_spectrum.output.export import HighResMassSpecExport 1305 1306 exportMS = HighResMassSpecExport(out_file_path, self) 1307 exportMS.to_parquet(write_metadata=write_metadata) 1308 1309 def to_dataframe(self, additional_columns=None): 1310 """Return the mass spectrum as a Pandas dataframe. 1311 1312 Parameters 1313 ---------- 1314 additional_columns : list, optional 1315 A list of additional columns to include in the dataframe. Defaults to None. 1316 Suitable columns are: "Aromaticity Index", "Aromaticity Index (modified)", and "NOSC" 1317 1318 Returns 1319 ------- 1320 pandas.DataFrame 1321 The mass spectrum as a Pandas dataframe. 1322 """ 1323 from corems.mass_spectrum.output.export import HighResMassSpecExport 1324 1325 exportMS = HighResMassSpecExport(self.filename, self) 1326 return exportMS.get_pandas_df(additional_columns=additional_columns) 1327 1328 def to_json(self): 1329 """Return the mass spectrum as a JSON file.""" 1330 from corems.mass_spectrum.output.export import HighResMassSpecExport 1331 1332 exportMS = HighResMassSpecExport(self.filename, self) 1333 return exportMS.to_json() 1334 1335 def parameters_json(self): 1336 """Return the parameters of the mass spectrum as a JSON string.""" 1337 from corems.mass_spectrum.output.export import HighResMassSpecExport 1338 1339 exportMS = HighResMassSpecExport(self.filename, self) 1340 return exportMS.parameters_to_json() 1341 1342 def parameters_toml(self): 1343 """Return the parameters of the mass spectrum as a TOML string.""" 1344 from corems.mass_spectrum.output.export import HighResMassSpecExport 1345 1346 exportMS = HighResMassSpecExport(self.filename, self) 1347 return exportMS.parameters_to_toml() 1348 1349 1350class MassSpecProfile(MassSpecBase): 1351 """A mass spectrum class when the entry point is on profile format 1352 1353 Notes 1354 ----- 1355 Stores the profile data and instrument settings. 1356 Iteration over a list of MSPeaks classes stored at the _mspeaks attributes. 1357 _mspeaks is populated under the hood by calling process_mass_spec method. 1358 Iteration is null if _mspeaks is empty. Many more attributes and methods inherited from MassSpecBase(). 1359 1360 Parameters 1361 ---------- 1362 data_dict : dict 1363 A dictionary containing the profile data. 1364 d_params : dict{'str': float, int or str} 1365 contains the instrument settings and processing settings 1366 auto_process : bool, optional 1367 Whether to automatically process the mass spectrum. Defaults to True. 1368 1369 1370 Attributes 1371 ---------- 1372 _abundance : ndarray 1373 The abundance values of the mass spectrum. 1374 _mz_exp : ndarray 1375 The m/z values of the mass spectrum. 1376 _mspeaks : list 1377 A list of mass peaks. 1378 1379 Methods 1380 ---------- 1381 * process_mass_spec(). Process the mass spectrum. 1382 1383 see also: MassSpecBase(), MassSpecfromFreq(), MassSpecCentroid() 1384 """ 1385 1386 def __init__(self, data_dict, d_params, auto_process=True): 1387 # print(data_dict.keys()) 1388 super().__init__( 1389 data_dict.get(Labels.mz), data_dict.get(Labels.abundance), d_params 1390 ) 1391 1392 if auto_process: 1393 self.process_mass_spec() 1394 1395 1396class MassSpecfromFreq(MassSpecBase): 1397 """A mass spectrum class when data entry is on frequency domain 1398 1399 Notes 1400 ----- 1401 - Transform to m/z based on the settings stored at d_params 1402 - Stores the profile data and instrument settings 1403 - Iteration over a list of MSPeaks classes stored at the _mspeaks attributes 1404 - _mspeaks is populated under the hood by calling process_mass_spec method 1405 - iteration is null if _mspeaks is empty 1406 1407 Parameters 1408 ---------- 1409 frequency_domain : list(float) 1410 all datapoints in frequency domain in Hz 1411 magnitude : frequency_domain : list(float) 1412 all datapoints in for magnitude of each frequency datapoint 1413 d_params : dict{'str': float, int or str} 1414 contains the instrument settings and processing settings 1415 auto_process : bool, optional 1416 Whether to automatically process the mass spectrum. Defaults to True. 1417 keep_profile : bool, optional 1418 Whether to keep the profile data. Defaults to True. 1419 1420 Attributes 1421 ---------- 1422 has_frequency : bool 1423 Whether the mass spectrum has frequency data. 1424 _frequency_domain : list(float) 1425 Frequency domain in Hz 1426 label : str 1427 store label (Bruker, Midas Transient, see Labels class ). It across distinct processing points 1428 _abundance : ndarray 1429 The abundance values of the mass spectrum. 1430 _mz_exp : ndarray 1431 The m/z values of the mass spectrum. 1432 _mspeaks : list 1433 A list of mass peaks. 1434 See Also: all the attributes of MassSpecBase class 1435 1436 Methods 1437 ---------- 1438 * _set_mz_domain(). 1439 calculates the m_z based on the setting of d_params 1440 * process_mass_spec(). Process the mass spectrum. 1441 1442 see also: MassSpecBase(), MassSpecProfile(), MassSpecCentroid() 1443 """ 1444 1445 def __init__( 1446 self, 1447 frequency_domain, 1448 magnitude, 1449 d_params, 1450 auto_process=True, 1451 keep_profile=True, 1452 ): 1453 super().__init__(None, magnitude, d_params) 1454 1455 self._frequency_domain = frequency_domain 1456 self.has_frequency = True 1457 self._set_mz_domain() 1458 self._sort_mz_domain() 1459 1460 self.magnetron_frequency = None 1461 self.magnetron_frequency_sigma = None 1462 1463 # use this call to automatically process data as the object is created, Setting need to be changed before initiating the class to be in effect 1464 1465 if auto_process: 1466 self.process_mass_spec(keep_profile=keep_profile) 1467 1468 def _sort_mz_domain(self): 1469 """Sort the mass spectrum by m/z values.""" 1470 1471 if self._mz_exp[0] > self._mz_exp[-1]: 1472 self._mz_exp = self._mz_exp[::-1] 1473 self._abundance = self._abundance[::-1] 1474 self._frequency_domain = self._frequency_domain[::-1] 1475 1476 def _set_mz_domain(self): 1477 """Set the m/z domain of the mass spectrum based on the settings of d_params.""" 1478 if self.label == Labels.bruker_frequency: 1479 self._mz_exp = self._f_to_mz_bruker() 1480 1481 else: 1482 self._mz_exp = self._f_to_mz() 1483 1484 @property 1485 def transient_settings(self): 1486 """Return the transient settings of the mass spectrum.""" 1487 return self.parameters.transient 1488 1489 @transient_settings.setter 1490 def transient_settings(self, instance_TransientSetting): 1491 self.parameters.transient = instance_TransientSetting 1492 1493 def calc_magnetron_freq(self, max_magnetron_freq=50, magnetron_freq_bins=300): 1494 """Calculates the magnetron frequency of the mass spectrum. 1495 1496 Parameters 1497 ---------- 1498 max_magnetron_freq : float, optional 1499 The maximum magnetron frequency. Defaults to 50. 1500 magnetron_freq_bins : int, optional 1501 The number of bins to use for the histogram. Defaults to 300. 1502 1503 Returns 1504 ------- 1505 None 1506 1507 Notes 1508 ----- 1509 Calculates the magnetron frequency by examining all the picked peaks and the distances between them in the frequency domain. 1510 A histogram of those values below the threshold 'max_magnetron_freq' with the 'magnetron_freq_bins' number of bins is calculated. 1511 A gaussian model is fit to this histogram - the center value of this (statistically probably) the magnetron frequency. 1512 This appears to work well or nOmega datasets, but may not work well for 1x datasets or those with very low magnetron peaks. 1513 """ 1514 ms_df = DataFrame(self.freq_exp(), columns=["Freq"]) 1515 ms_df["FreqDelta"] = ms_df["Freq"].diff() 1516 1517 freq_hist = histogram( 1518 ms_df[ms_df["FreqDelta"] < max_magnetron_freq]["FreqDelta"], 1519 bins=magnetron_freq_bins, 1520 ) 1521 1522 mod = GaussianModel() 1523 pars = mod.guess(freq_hist[0], x=freq_hist[1][:-1]) 1524 out = mod.fit(freq_hist[0], pars, x=freq_hist[1][:-1]) 1525 self.magnetron_frequency = out.best_values["center"] 1526 self.magnetron_frequency_sigma = out.best_values["sigma"] 1527 1528 1529class MassSpecCentroid(MassSpecBase): 1530 """A mass spectrum class when the entry point is on centroid format 1531 1532 Notes 1533 ----- 1534 - Stores the centroid data and instrument settings 1535 - Simulate profile data based on Gaussian or Lorentzian peak shape 1536 - Iteration over a list of MSPeaks classes stored at the _mspeaks attributes 1537 - _mspeaks is populated under the hood by calling process_mass_spec method 1538 - iteration is null if _mspeaks is empty 1539 1540 Parameters 1541 ---------- 1542 data_dict : dict {string: numpy array float64 ) 1543 contains keys [m/z, Abundance, Resolving Power, S/N] 1544 d_params : dict{'str': float, int or str} 1545 contains the instrument settings and processing settings 1546 auto_process : bool, optional 1547 Whether to automatically process the mass spectrum. Defaults to True. 1548 1549 Attributes 1550 ---------- 1551 label : str 1552 store label (Bruker, Midas Transient, see Labels class) 1553 _baseline_noise : float 1554 store baseline noise 1555 _baseline_noise_std : float 1556 store baseline noise std 1557 _abundance : ndarray 1558 The abundance values of the mass spectrum. 1559 _mz_exp : ndarray 1560 The m/z values of the mass spectrum. 1561 _mspeaks : list 1562 A list of mass peaks. 1563 1564 1565 Methods 1566 ---------- 1567 * process_mass_spec(). 1568 Process the mass spectrum. Overriden from MassSpecBase. Populates the _mspeaks list with MSpeaks class using the centroid data. 1569 * __simulate_profile__data__(). 1570 Simulate profile data based on Gaussian or Lorentzian peak shape. Needs theoretical resolving power calculation and define peak shape, intended for plotting and inspection purposes only. 1571 1572 see also: MassSpecBase(), MassSpecfromFreq(), MassSpecProfile() 1573 """ 1574 1575 def __init__(self, data_dict, d_params, auto_process=True): 1576 super().__init__([], [], d_params) 1577 1578 self._set_parameters_objects(d_params) 1579 1580 if self.label == Labels.thermo_centroid: 1581 self._baseline_noise = d_params.get("baseline_noise") 1582 self._baseline_noise_std = d_params.get("baseline_noise_std") 1583 1584 self.is_centroid = True 1585 self.data_dict = data_dict 1586 self._mz_exp = data_dict[Labels.mz] 1587 self._abundance = data_dict[Labels.abundance] 1588 1589 if auto_process: 1590 self.process_mass_spec() 1591 1592 def __simulate_profile__data__(self, exp_mz_centroid, magnitude_centroid): 1593 """Simulate profile data based on Gaussian or Lorentzian peak shape 1594 1595 Notes 1596 ----- 1597 Needs theoretical resolving power calculation and define peak shape. 1598 This is a quick fix to trick a line plot be able to plot as sticks for plotting and inspection purposes only. 1599 1600 Parameters 1601 ---------- 1602 exp_mz_centroid : list(float) 1603 list of m/z values 1604 magnitude_centroid : list(float) 1605 list of abundance values 1606 1607 1608 Returns 1609 ------- 1610 x : list(float) 1611 list of m/z values 1612 y : list(float) 1613 list of abundance values 1614 """ 1615 1616 x, y = [], [] 1617 for i in range(len(exp_mz_centroid)): 1618 x.append(exp_mz_centroid[i] - 0.0000001) 1619 x.append(exp_mz_centroid[i]) 1620 x.append(exp_mz_centroid[i] + 0.0000001) 1621 y.append(0) 1622 y.append(magnitude_centroid[i]) 1623 y.append(0) 1624 return x, y 1625 1626 @property 1627 def mz_exp_profile(self): 1628 """Return the m/z profile of the mass spectrum.""" 1629 mz_list = [] 1630 for mz in self.mz_exp: 1631 mz_list.append(mz - 0.0000001) 1632 mz_list.append(mz) 1633 mz_list.append(mz + 0.0000001) 1634 return mz_list 1635 1636 @mz_exp_profile.setter 1637 def mz_exp_profile(self, _mz_exp): 1638 self._mz_exp = _mz_exp 1639 1640 @property 1641 def abundance_profile(self): 1642 """Return the abundance profile of the mass spectrum.""" 1643 ab_list = [] 1644 for ab in self.abundance: 1645 ab_list.append(0) 1646 ab_list.append(ab) 1647 ab_list.append(0) 1648 return ab_list 1649 1650 @abundance_profile.setter 1651 def abundance_profile(self, abundance): 1652 self._abundance = abundance 1653 1654 @property 1655 def tic(self): 1656 """Return the total ion current of the mass spectrum.""" 1657 return sum(self.abundance) 1658 1659 def process_mass_spec(self): 1660 """Process the mass spectrum.""" 1661 1662 # overwrite process_mass_spec 1663 # mspeak objs are usually added inside the PeaKPicking class 1664 # for profile and freq based data 1665 data_dict = self.data_dict 1666 # Peak polarity only (±1); formula assignment charge is separate. 1667 peak_polarity = self.polarity 1668 1669 # Check if resolving power is present 1670 rp_present = True 1671 if not data_dict.get(Labels.rp): 1672 rp_present = False 1673 if rp_present and list(data_dict.get(Labels.rp)) == [None] * len( 1674 data_dict.get(Labels.rp) 1675 ): 1676 rp_present = False 1677 1678 # Check if s2n is present 1679 s2n_present = True 1680 if not data_dict.get(Labels.s2n): 1681 s2n_present = False 1682 if s2n_present and list(data_dict.get(Labels.s2n)) == [None] * len( 1683 data_dict.get(Labels.s2n) 1684 ): 1685 s2n_present = False 1686 1687 # Warning if no s2n data but noise thresholding is set to signal_noise 1688 if ( 1689 not s2n_present 1690 and self.parameters.mass_spectrum.noise_threshold_method == "signal_noise" 1691 ): 1692 raise Exception("Signal to Noise data is missing for noise thresholding") 1693 1694 # Pull out abundance data 1695 abun = array(data_dict.get(Labels.abundance)).astype(float) 1696 1697 # Get the threshold for filtering if using minima, relative, or absolute abundance thresholding 1698 abundance_threshold, factor = self.get_threshold(abun) 1699 1700 # Set rp_i and s2n_i to None which will be overwritten if present 1701 rp_i, s2n_i = np.nan, np.nan 1702 for index, mz in enumerate(data_dict.get(Labels.mz)): 1703 if rp_present: 1704 if not data_dict.get(Labels.rp)[index]: 1705 rp_i = np.nan 1706 else: 1707 rp_i = float(data_dict.get(Labels.rp)[index]) 1708 if s2n_present: 1709 if not data_dict.get(Labels.s2n)[index]: 1710 s2n_i = np.nan 1711 else: 1712 s2n_i = float(data_dict.get(Labels.s2n)[index]) 1713 1714 # centroid peak does not have start and end peak index pos 1715 massspec_indexes = (index, index, index) 1716 1717 # Add peaks based on the noise thresholding method 1718 if ( 1719 self.parameters.mass_spectrum.noise_threshold_method 1720 in ["minima", "relative_abundance", "absolute_abundance"] 1721 and abun[index] / factor >= abundance_threshold 1722 ): 1723 self.add_mspeak( 1724 peak_polarity, 1725 mz, 1726 abun[index], 1727 rp_i, 1728 s2n_i, 1729 massspec_indexes, 1730 ms_parent=self, 1731 ) 1732 if ( 1733 self.parameters.mass_spectrum.noise_threshold_method == "signal_noise" 1734 and s2n_i >= self.parameters.mass_spectrum.noise_threshold_min_s2n 1735 ): 1736 self.add_mspeak( 1737 peak_polarity, 1738 mz, 1739 abun[index], 1740 rp_i, 1741 s2n_i, 1742 massspec_indexes, 1743 ms_parent=self, 1744 ) 1745 1746 self.mspeaks = self._mspeaks 1747 self._dynamic_range = self.max_abundance / self.min_abundance 1748 self._set_nominal_masses_start_final_indexes() 1749 1750 if self.label != Labels.thermo_centroid: 1751 if self.settings.noise_threshold_method == "log": 1752 raise Exception("log noise Not tested for centroid data") 1753 # self._baseline_noise, self._baseline_noise_std = self.run_log_noise_threshold_calc() 1754 1755 else: 1756 self._baseline_noise, self._baseline_noise_std = ( 1757 self.run_noise_threshold_calc() 1758 ) 1759 1760 del self.data_dict 1761 1762 def to_profile( 1763 self, 1764 mz_profile, 1765 abundance_profile, 1766 mz_cal_profile=None, 1767 peak_profile_indices=None, 1768 is_calibrated=False, 1769 ): 1770 """Return a :class:`MassSpecProfile` sharing this spectrum's peaks. 1771 1772 Reuses the already-picked peaks (and any molecular formula 1773 assignments on them) instead of re-picking from the profile data, and 1774 re-points each peak's parent reference to the returned object. This 1775 transfers ownership of the peaks: ``self.mspeaks``/``self._mspeaks`` 1776 are cleared once the new object holds them, so this spectrum and the 1777 returned one never end up sharing (and independently mutating) the 1778 same peak list. Used to rehydrate a profile mass spectrum from a 1779 CoreMS HDF5 file that stored both a profile and a peak table, 1780 without re-running peak picking. 1781 1782 Parameters 1783 ---------- 1784 mz_profile : array_like 1785 Experimental (uncalibrated) m/z profile. 1786 abundance_profile : array_like 1787 Abundance profile, same length as ``mz_profile``. 1788 mz_cal_profile : array_like, optional 1789 Calibrated m/z profile, same length as ``mz_profile``. Applied 1790 whenever given, independently of ``is_calibrated``. Default is 1791 None. 1792 peak_profile_indices : array_like of shape (n_peaks, 3), optional 1793 Per-peak ``(left, apex, right)`` indices into 1794 ``mz_profile``/``abundance_profile``, in the same order as 1795 ``self.mspeaks``. Ignored entirely if its length doesn't match 1796 ``self.mspeaks``. Otherwise checked per peak -- a stored triple 1797 is only trusted when ``0 <= left <= apex <= right < len(mz_profile)`` 1798 -- since a file can carry indices from before a later 1799 reprocessing changed the profile length (the writer skips 1800 storing new ones when that happens, but an older file may still 1801 have a stale set from before this check existed). When omitted, 1802 or for any one peak whose stored triple fails that check, that 1803 peak's bounds are estimated instead: the apex starts at the 1804 nearest profile index to the peak's own m/z (its calibrated m/z 1805 against ``mz_cal_profile`` if the peak is calibrated, else its 1806 experimental m/z against ``mz_profile`` -- either array may run 1807 ascending or descending), the left/right bounds are then the 1808 neighboring local minima from that starting point, and the apex 1809 is finally set to the actual local maximum between those two 1810 bounds -- not the initial nearest-index estimate, which can be 1811 off by a few points from the quadratic-fit interpolation the 1812 original picking used. 1813 is_calibrated : bool, optional 1814 Whether the stored m/z is calibrated. Sets ``is_calibrated`` on 1815 the returned spectrum directly; ``mz_cal_profile`` is applied 1816 independently of this flag whenever it is given. Default is 1817 False. 1818 1819 Returns 1820 ------- 1821 MassSpecProfile 1822 """ 1823 d_params = { 1824 "Aterm": self.Aterm, 1825 "Bterm": self.Bterm, 1826 "Cterm": self.Cterm, 1827 Labels.label: self.label, 1828 "analyzer": self.analyzer, 1829 "acquisition_time": self.acquisition_time, 1830 "instrument_label": self.instrument_label, 1831 "polarity": self.polarity, 1832 "scan_number": self.scan_number, 1833 "rt": self.retention_time, 1834 "mobility_rt": self.mobility_rt, 1835 "mobility_scan": self.mobility_scan, 1836 "filename_path": self._filename, 1837 "dir_location": self._dir_location, 1838 "baseline_noise": self._baseline_noise, 1839 "baseline_noise_std": self._baseline_noise_std, 1840 "sample_name": self.sample_name, 1841 } 1842 1843 new_obj = MassSpecProfile( 1844 {Labels.mz: mz_profile, Labels.abundance: abundance_profile}, 1845 d_params, 1846 auto_process=False, 1847 ) 1848 1849 new_obj._mspeaks = self._mspeaks 1850 new_obj.mspeaks = self.mspeaks 1851 new_obj._dict_nominal_masses_indexes = self._dict_nominal_masses_indexes 1852 new_obj._dynamic_range = self._dynamic_range 1853 # MassSpecBase.__init__ gave new_obj a fresh, default MSParameters; 1854 # replace it with this spectrum's (e.g. settings restored by a 1855 # reader's load_settings()) so processing settings survive the 1856 # conversion. 1857 new_obj.parameters = self.parameters 1858 1859 # Transfer ownership: this spectrum no longer holds these peaks. 1860 self._mspeaks = [] 1861 self.mspeaks = [] 1862 1863 if is_calibrated: 1864 new_obj.is_calibrated = True 1865 if mz_cal_profile is not None: 1866 new_obj.mz_cal_profile = mz_cal_profile 1867 1868 abundance_arr = asarray(new_obj.abundance_profile) 1869 mz_arr = asarray(mz_profile) 1870 mz_cal_arr = asarray(mz_cal_profile) if mz_cal_profile is not None else None 1871 n = len(abundance_arr) 1872 1873 if peak_profile_indices is not None and len(peak_profile_indices) != len( 1874 new_obj.mspeaks 1875 ): 1876 peak_profile_indices = None 1877 1878 for i, mspeak in enumerate(new_obj.mspeaks): 1879 mspeak._ms_parent = new_obj 1880 1881 stored = None 1882 if peak_profile_indices is not None: 1883 left, apex, right = (int(v) for v in peak_profile_indices[i]) 1884 # Stored indices can predate a later reprocessing with a 1885 # different-length profile (the writer skips storing them 1886 # when that happens, but an older file may still have a 1887 # stale set); only trust them if they're a sane bound into 1888 # *this* profile, else fall back to the search below. 1889 if 0 <= left <= apex <= right < n: 1890 stored = (left, apex, right) 1891 1892 if stored is not None: 1893 left, apex, right = stored 1894 else: 1895 if mspeak.mz_cal is not None and mz_cal_arr is not None: 1896 search_profile, search_value = mz_cal_arr, mspeak.mz_cal 1897 else: 1898 search_profile, search_value = mz_arr, mspeak._mz_exp 1899 1900 apex = _nearest_index_either_order(search_profile, search_value) 1901 right = new_obj.find_minima(apex, abundance_arr, n, right=True) 1902 left = new_obj.find_minima(apex, abundance_arr, n, right=False) 1903 # Re-anchor the apex to the tallest sample within the now-known 1904 # bounds, rather than trusting the nearest-index estimate above. 1905 apex = left + int(argmax(abundance_arr[left : right + 1])) 1906 mspeak.peak_left_index = left 1907 mspeak.peak_apex_index = apex 1908 mspeak.peak_right_index = right 1909 1910 return new_obj 1911 1912 1913class MassSpecCentroidLowRes(MassSpecCentroid): 1914 """A mass spectrum class when the entry point is on low resolution centroid format 1915 1916 Notes 1917 ----- 1918 Does not store MSPeak Objs, will iterate over mz, abundance pairs instead 1919 1920 Parameters 1921 ---------- 1922 data_dict : dict {string: numpy array float64 ) 1923 contains keys [m/z, Abundance, Resolving Power, S/N] 1924 d_params : dict{'str': float, int or str} 1925 contains the instrument settings and processing settings 1926 1927 Attributes 1928 ---------- 1929 _processed_tic : float 1930 store processed total ion current 1931 _abundance : ndarray 1932 The abundance values of the mass spectrum. 1933 _mz_exp : ndarray 1934 The m/z values of the mass spectrum. 1935 """ 1936 1937 def __init__(self, data_dict, d_params): 1938 self._set_parameters_objects(d_params) 1939 self._mz_exp = array(data_dict.get(Labels.mz)) 1940 self._abundance = array(data_dict.get(Labels.abundance)) 1941 self._processed_tic = None 1942 1943 def __len__(self): 1944 return len(self.mz_exp) 1945 1946 def __getitem__(self, position): 1947 return (self.mz_exp[position], self.abundance[position]) 1948 1949 @property 1950 def mz_exp(self): 1951 """Return the m/z values of the mass spectrum.""" 1952 return self._mz_exp 1953 1954 @property 1955 def abundance(self): 1956 """Return the abundance values of the mass spectrum.""" 1957 return self._abundance 1958 1959 @property 1960 def processed_tic(self): 1961 """Return the processed total ion current of the mass spectrum.""" 1962 return sum(self._processed_tic) 1963 1964 @property 1965 def tic(self): 1966 """Return the total ion current of the mass spectrum.""" 1967 if self._processed_tic: 1968 return self._processed_tic 1969 else: 1970 return sum(self.abundance) 1971 1972 @property 1973 def mz_abun_tuples(self): 1974 """Return the m/z and abundance values of the mass spectrum as a list of tuples.""" 1975 r = lambda x: int(round(x[0], 0), int(round(x[1], 0))) 1976 1977 return [r(i) for i in self] 1978 1979 @property 1980 def mz_abun_dict(self): 1981 """Return the m/z and abundance values of the mass spectrum as a dictionary.""" 1982 r = lambda x: int(round(x, 0)) 1983 1984 return {r(i[0]): r(i[1]) for i in self}
31def overrides(interface_class): 32 """Checks if the method overrides a method from an interface class.""" 33 34 def overrider(method): 35 assert method.__name__ in dir(interface_class) 36 return method 37 38 return overrider
Checks if the method overrides a method from an interface class.
57class MassSpecBase(MassSpecCalc, KendrickGrouping): 58 """A mass spectrum base class, stores the profile data and instrument settings. 59 60 Iteration over a list of MSPeaks classes stored at the _mspeaks attributes. 61 _mspeaks is populated under the hood by calling process_mass_spec method. 62 Iteration is null if _mspeaks is empty. 63 64 Parameters 65 ---------- 66 mz_exp : array_like 67 The m/z values of the mass spectrum. 68 abundance : array_like 69 The abundance values of the mass spectrum. 70 d_params : dict 71 A dictionary of parameters for the mass spectrum. 72 **kwargs 73 Additional keyword arguments. 74 75 Attributes 76 ---------- 77 78 mspeaks : list 79 A list of mass peaks. 80 is_calibrated : bool 81 Whether the mass spectrum is calibrated. 82 is_centroid : bool 83 Whether the mass spectrum is centroided. 84 has_frequency : bool 85 Whether the mass spectrum has a frequency domain. 86 calibration_order : None or int 87 The order of the mass spectrum's calibration. 88 calibration_points : None or ndarray 89 The calibration points of the mass spectrum. 90 calibration_ref_mzs: None or ndarray 91 The reference m/z values of the mass spectrum's calibration. 92 calibration_meas_mzs : None or ndarray 93 The measured m/z values of the mass spectrum's calibration. 94 calibration_RMS : None or float 95 The root mean square of the mass spectrum's calibration. 96 calibration_segment : None or CalibrationSegment 97 The calibration segment of the mass spectrum. 98 _abundance : ndarray 99 The abundance values of the mass spectrum. 100 _mz_exp : ndarray 101 The m/z values of the mass spectrum. 102 _mspeaks : list 103 A list of mass peaks. 104 _dict_nominal_masses_indexes : dict 105 A dictionary of nominal masses and their indexes. 106 _baseline_noise : float 107 The baseline noise of the mass spectrum. 108 _baseline_noise_std : float 109 The standard deviation of the baseline noise of the mass spectrum. 110 _dynamic_range : float or None 111 The dynamic range of the mass spectrum. 112 _transient_settings : None or TransientSettings 113 The transient settings of the mass spectrum. 114 _frequency_domain : None or FrequencyDomain 115 The frequency domain of the mass spectrum. 116 _mz_cal_profile : None or MzCalibrationProfile 117 The m/z calibration profile of the mass spectrum. 118 119 Methods 120 ------- 121 * process_mass_spec(). Main function to process the mass spectrum, 122 including calculating the noise threshold, peak picking, and resetting the MSpeak indexes. 123 124 See also: MassSpecCentroid(), MassSpecfromFreq(), MassSpecProfile() 125 """ 126 127 def __init__(self, mz_exp, abundance, d_params, **kwargs): 128 self._abundance = array(abundance, dtype=float64) 129 self._mz_exp = array(mz_exp, dtype=float64) 130 131 # objects created after process_mass_spec() function 132 self._mspeaks = list() 133 self.mspeaks = list() 134 self._dict_nominal_masses_indexes = dict() 135 self._baseline_noise = 0.001 136 self._baseline_noise_std = 0.001 137 self._dynamic_range = None 138 # set to None: initialization occurs inside subclass MassSpecfromFreq 139 self._transient_settings = None 140 self._frequency_domain = None 141 self._mz_cal_profile = None 142 self.is_calibrated = False 143 144 self._set_parameters_objects(d_params) 145 self._init_settings() 146 147 self.is_centroid = False 148 self.has_frequency = False 149 150 self.calibration_order = None 151 self.calibration_points = None 152 self.calibration_ref_mzs = None 153 self.calibration_meas_mzs = None 154 self.calibration_RMS = None 155 self.calibration_segment = None 156 self.calibration_raw_error_median = None 157 self.calibration_raw_error_stdev = None 158 159 def _init_settings(self): 160 """Initializes the settings for the mass spectrum.""" 161 self._parameters = MSParameters() 162 163 def __len__(self): 164 return len(self.mspeaks) 165 166 def __getitem__(self, position) -> MSPeak: 167 return self.mspeaks[position] 168 169 def set_indexes(self, list_indexes): 170 """Set the mass spectrum to iterate over only the selected MSpeaks indexes. 171 172 Parameters 173 ---------- 174 list_indexes : list of int 175 A list of integers representing the indexes of the MSpeaks to iterate over. 176 177 """ 178 self.mspeaks = [self._mspeaks[i] for i in list_indexes] 179 180 for i, mspeak in enumerate(self.mspeaks): 181 mspeak.index = i 182 183 self._set_nominal_masses_start_final_indexes() 184 185 def reset_indexes(self): 186 """Reset the mass spectrum to iterate over all MSpeaks objects. 187 188 This method resets the mass spectrum to its original state, allowing iteration over all MSpeaks objects. 189 It also sets the index of each MSpeak object to its corresponding position in the mass spectrum. 190 191 """ 192 self.mspeaks = self._mspeaks 193 194 for i, mspeak in enumerate(self.mspeaks): 195 mspeak.index = i 196 197 self._set_nominal_masses_start_final_indexes() 198 199 def add_mspeak( 200 self, 201 polarity, 202 mz_exp, 203 abundance, 204 resolving_power, 205 signal_to_noise, 206 massspec_indexes, 207 exp_freq=None, 208 ms_parent=None, 209 **kwargs, 210 ): 211 """Add a new MSPeak object to the MassSpectrum object. 212 213 Parameters 214 ---------- 215 polarity : int 216 Acquisition polarity of the MSPeak (``+1`` or ``-1``). 217 Do **not** pass ``ion_charge``; peaks store polarity only. 218 Assignment charge lives on ``MolecularFormula.ion_charge``. 219 mz_exp : float 220 The experimental m/z value of the MSPeak. 221 abundance : float 222 The abundance of the MSPeak. 223 resolving_power : float 224 The resolving power of the MSPeak. 225 signal_to_noise : float 226 The signal-to-noise ratio of the MSPeak. 227 massspec_indexes : list 228 A list of indexes of the MSPeak in the MassSpectrum object. 229 exp_freq : float, optional 230 The experimental frequency of the MSPeak. Defaults to None. 231 ms_parent : MSParent, optional 232 The MSParent object associated with the MSPeak. Defaults to None. 233 234 Raises 235 ------ 236 TypeError 237 If ``ion_charge`` is passed (removed; use ``polarity``), or if any 238 other unexpected keyword argument is given. 239 """ 240 if "ion_charge" in kwargs: 241 raise TypeError( 242 "add_mspeak() no longer accepts ion_charge=...; pass polarity " 243 "(±1) instead. Peaks store acquisition polarity only. Assignment " 244 "charge belongs on MolecularFormula.ion_charge after formula matching." 245 ) 246 if kwargs: 247 unexpected = ", ".join(sorted(kwargs)) 248 raise TypeError( 249 f"add_mspeak() got unexpected keyword argument(s): {unexpected}" 250 ) 251 252 mspeak = MSPeak( 253 polarity, 254 mz_exp, 255 abundance, 256 resolving_power, 257 signal_to_noise, 258 massspec_indexes, 259 len(self._mspeaks), 260 exp_freq=exp_freq, 261 ms_parent=ms_parent, 262 ) 263 264 self._mspeaks.append(mspeak) 265 266 def _set_parameters_objects(self, d_params): 267 """Set the parameters of the MassSpectrum object. 268 269 Parameters 270 ---------- 271 d_params : dict 272 A dictionary containing the parameters to set. 273 274 Notes 275 ----- 276 This method sets the following parameters of the MassSpectrum object: 277 - _calibration_terms 278 - label 279 - analyzer 280 - acquisition_time 281 - instrument_label 282 - polarity 283 - scan_number 284 - retention_time 285 - mobility_rt 286 - mobility_scan 287 - _filename 288 - _dir_location 289 - _baseline_noise 290 - _baseline_noise_std 291 - sample_name 292 """ 293 self._calibration_terms = ( 294 d_params.get("Aterm"), 295 d_params.get("Bterm"), 296 d_params.get("Cterm"), 297 ) 298 299 self.label = d_params.get(Labels.label) 300 301 self.analyzer = d_params.get("analyzer") 302 303 self.acquisition_time = d_params.get("acquisition_time") 304 305 self.instrument_label = d_params.get("instrument_label") 306 307 self.polarity = int(d_params.get("polarity")) 308 309 self.scan_number = d_params.get("scan_number") 310 311 self.retention_time = d_params.get("rt") 312 313 self.mobility_rt = d_params.get("mobility_rt") 314 315 self.mobility_scan = d_params.get("mobility_scan") 316 317 self._filename = d_params.get("filename_path") 318 319 self._dir_location = d_params.get("dir_location") 320 321 self._baseline_noise = d_params.get("baseline_noise") 322 323 self._baseline_noise_std = d_params.get("baseline_noise_std") 324 325 if d_params.get("sample_name") != "Unknown": 326 self.sample_name = d_params.get("sample_name") 327 if not self.sample_name: 328 self.sample_name = self.filename.stem 329 else: 330 self.sample_name = self.filename.stem 331 332 def reset_cal_therms(self, Aterm, Bterm, C, fas=0): 333 """Reset calibration terms and recalculate the mass-to-charge ratio and abundance. 334 335 Parameters 336 ---------- 337 Aterm : float 338 The A-term calibration coefficient. 339 Bterm : float 340 The B-term calibration coefficient. 341 C : float 342 The C-term calibration coefficient. 343 fas : float, optional 344 The frequency amplitude scaling factor. Default is 0. 345 """ 346 self._calibration_terms = (Aterm, Bterm, C) 347 348 self._mz_exp = self._f_to_mz() 349 self._abundance = self._abundance 350 self.find_peaks() 351 self.reset_indexes() 352 353 def clear_molecular_formulas(self): 354 """Clear the molecular formulas for all mspeaks in the MassSpectrum. 355 356 Returns 357 ------- 358 numpy.ndarray 359 An array of the cleared molecular formulas for each mspeak in the MassSpectrum. 360 """ 361 self.check_mspeaks() 362 return array([mspeak.clear_molecular_formulas() for mspeak in self.mspeaks]) 363 364 def process_mass_spec(self, keep_profile=True): 365 """Process the mass spectrum. 366 367 Parameters 368 ---------- 369 keep_profile : bool, optional 370 Whether to keep the profile data after processing. Defaults to True. 371 372 Notes 373 ----- 374 This method does the following: 375 - calculates the noise threshold 376 - does peak picking (creates mspeak_objs) 377 - resets the mspeak_obj indexes 378 """ 379 380 # if runned mannually make sure to rerun filter_by_noise_threshold 381 # calculates noise threshold 382 # do peak picking( create mspeak_objs) 383 # reset mspeak_obj the indexes 384 385 self.cal_noise_threshold() 386 387 self.find_peaks() 388 self.reset_indexes() 389 390 if self.mspeaks: 391 self._dynamic_range = self.max_abundance / self.min_abundance 392 else: 393 self._dynamic_range = 0 394 if not keep_profile: 395 self._abundance *= 0 396 self._mz_exp *= 0 397 398 def _resolve_noise_threshold_method(self): 399 """Resolve ``by_format`` and store the concrete noise-threshold method. 400 401 Profile spectra use ``log``. Centroid spectra use 402 ``relative_abundance``. An explicit method is left unchanged. 403 ``by_format`` is replaced on this spectrum's settings so saved 404 parameters record what was used. 405 406 Returns 407 ------- 408 str 409 Concrete noise-threshold method. 410 """ 411 method = self.settings.noise_threshold_method 412 if method != "by_format": 413 return method 414 resolved = "relative_abundance" if self.is_centroid else "log" 415 self.settings.noise_threshold_method = resolved 416 return resolved 417 418 def cal_noise_threshold(self): 419 """Calculate the noise threshold of the mass spectrum.""" 420 421 self._resolve_noise_threshold_method() 422 423 if self.label == Labels.simulated_profile: 424 self._baseline_noise, self._baseline_noise_std = 0.1, 1 425 426 if self.settings.noise_threshold_method == "log": 427 self._baseline_noise, self._baseline_noise_std = ( 428 self.run_log_noise_threshold_calc() 429 ) 430 431 else: 432 self._baseline_noise, self._baseline_noise_std = ( 433 self.run_noise_threshold_calc() 434 ) 435 436 @property 437 def parameters(self): 438 """Return the parameters of the mass spectrum.""" 439 return self._parameters 440 441 @parameters.setter 442 def parameters(self, instance_MSParameters): 443 self._parameters = instance_MSParameters 444 445 def set_parameter_from_json(self, parameters_path): 446 """Set the parameters of the mass spectrum from a JSON file. 447 448 Parameters 449 ---------- 450 parameters_path : str 451 The path to the JSON file containing the parameters. 452 """ 453 load_and_set_parameters_ms(self, parameters_path=parameters_path) 454 455 def set_parameter_from_toml(self, parameters_path): 456 load_and_set_toml_parameters_ms(self, parameters_path=parameters_path) 457 458 @property 459 def mspeaks_settings(self): 460 """Return the MS peak settings of the mass spectrum.""" 461 return self.parameters.ms_peak 462 463 @mspeaks_settings.setter 464 def mspeaks_settings(self, instance_MassSpecPeakSetting): 465 self.parameters.ms_peak = instance_MassSpecPeakSetting 466 467 @property 468 def settings(self): 469 """Return the settings of the mass spectrum.""" 470 return self.parameters.mass_spectrum 471 472 @settings.setter 473 def settings(self, instance_MassSpectrumSetting): 474 self.parameters.mass_spectrum = instance_MassSpectrumSetting 475 476 @property 477 def molecular_search_settings(self): 478 """Return the molecular search settings of the mass spectrum.""" 479 return self.parameters.molecular_search 480 481 @molecular_search_settings.setter 482 def molecular_search_settings(self, instance_MolecularFormulaSearchSettings): 483 self.parameters.molecular_search = instance_MolecularFormulaSearchSettings 484 485 @property 486 def mz_cal_profile(self): 487 """Return the calibrated m/z profile of the mass spectrum.""" 488 return self._mz_cal_profile 489 490 @mz_cal_profile.setter 491 def mz_cal_profile(self, mz_cal_list): 492 if len(mz_cal_list) == len(self._mz_exp): 493 self._mz_cal_profile = mz_cal_list 494 else: 495 raise Exception( 496 "calibrated array (%i) is not of the same size of the data (%i)" 497 % (len(mz_cal_list), len(self.mz_exp_profile)) 498 ) 499 500 @property 501 def mz_cal(self): 502 """Return the calibrated m/z values of the mass spectrum.""" 503 return array([mspeak.mz_cal for mspeak in self.mspeaks]) 504 505 @mz_cal.setter 506 def mz_cal(self, mz_cal_list): 507 if len(mz_cal_list) == len(self.mspeaks): 508 self.is_calibrated = True 509 for index, mz_cal in enumerate(mz_cal_list): 510 self.mspeaks[index].mz_cal = mz_cal 511 else: 512 raise Exception( 513 "calibrated array (%i) is not of the same size of the data (%i)" 514 % (len(mz_cal_list), len(self._mspeaks)) 515 ) 516 517 @property 518 def mz_exp(self): 519 """Return the experimental m/z values of the mass spectrum.""" 520 self.check_mspeaks() 521 522 if self.is_calibrated: 523 return array([mspeak.mz_cal for mspeak in self.mspeaks]) 524 525 else: 526 return array([mspeak.mz_exp for mspeak in self.mspeaks]) 527 528 @property 529 def freq_exp_profile(self): 530 """Return the experimental frequency profile of the mass spectrum.""" 531 return self._frequency_domain 532 533 @freq_exp_profile.setter 534 def freq_exp_profile(self, new_data): 535 self._frequency_domain = array(new_data) 536 537 @property 538 def freq_exp_pp(self): 539 """Return the experimental frequency values of the mass spectrum that are used for peak picking.""" 540 _, _, freq = self.prepare_peak_picking_data() 541 return freq 542 543 @property 544 def mz_exp_profile(self): 545 """Return the experimental m/z profile of the mass spectrum.""" 546 if self.is_calibrated: 547 return self.mz_cal_profile 548 else: 549 return self._mz_exp 550 551 @mz_exp_profile.setter 552 def mz_exp_profile(self, new_data): 553 self._mz_exp = array(new_data) 554 555 @property 556 def mz_exp_pp(self): 557 """Return the experimental m/z values of the mass spectrum that are used for peak picking.""" 558 mz, _, _ = self.prepare_peak_picking_data() 559 return mz 560 561 @property 562 def abundance_profile(self): 563 """Return the abundance profile of the mass spectrum.""" 564 return self._abundance 565 566 @abundance_profile.setter 567 def abundance_profile(self, new_data): 568 self._abundance = array(new_data) 569 570 @property 571 def abundance_profile_pp(self): 572 """Return the abundance profile of the mass spectrum that is used for peak picking.""" 573 _, abundance, _ = self.prepare_peak_picking_data() 574 return abundance 575 576 @property 577 def abundance(self): 578 """Return the abundance values of the mass spectrum.""" 579 self.check_mspeaks() 580 return array([mspeak.abundance for mspeak in self.mspeaks]) 581 582 def freq_exp(self): 583 """Return the experimental frequency values of the mass spectrum.""" 584 self.check_mspeaks() 585 return array([mspeak.freq_exp for mspeak in self.mspeaks]) 586 587 @property 588 def resolving_power(self): 589 """Return the resolving power values of the mass spectrum.""" 590 self.check_mspeaks() 591 return array([mspeak.resolving_power for mspeak in self.mspeaks]) 592 593 @property 594 def signal_to_noise(self): 595 self.check_mspeaks() 596 return array([mspeak.signal_to_noise for mspeak in self.mspeaks]) 597 598 @property 599 def nominal_mz(self): 600 """Return the nominal m/z values of the mass spectrum.""" 601 if self._dict_nominal_masses_indexes: 602 return sorted(list(self._dict_nominal_masses_indexes.keys())) 603 else: 604 raise ValueError("Nominal indexes not yet set") 605 606 def get_mz_and_abundance_peaks_tuples(self): 607 """Return a list of tuples containing the m/z and abundance values of the mass spectrum.""" 608 self.check_mspeaks() 609 return [(mspeak.mz_exp, mspeak.abundance) for mspeak in self.mspeaks] 610 611 @property 612 def kmd(self): 613 """Return the Kendrick mass defect values of the mass spectrum.""" 614 self.check_mspeaks() 615 return array([mspeak.kmd for mspeak in self.mspeaks]) 616 617 @property 618 def kendrick_mass(self): 619 """Return the Kendrick mass values of the mass spectrum.""" 620 self.check_mspeaks() 621 return array([mspeak.kendrick_mass for mspeak in self.mspeaks]) 622 623 @property 624 def max_mz_exp(self): 625 """Return the maximum experimental m/z value of the mass spectrum.""" 626 return max([mspeak.mz_exp for mspeak in self.mspeaks]) 627 628 @property 629 def min_mz_exp(self): 630 """Return the minimum experimental m/z value of the mass spectrum.""" 631 return min([mspeak.mz_exp for mspeak in self.mspeaks]) 632 633 @property 634 def max_abundance(self): 635 """Return the maximum abundance value of the mass spectrum.""" 636 return max([mspeak.abundance for mspeak in self.mspeaks]) 637 638 @property 639 def max_signal_to_noise(self): 640 """Return the maximum signal-to-noise ratio of the mass spectrum.""" 641 return max([mspeak.signal_to_noise for mspeak in self.mspeaks]) 642 643 @property 644 def most_abundant_mspeak(self): 645 """Return the most abundant MSpeak object of the mass spectrum.""" 646 return max(self.mspeaks, key=lambda m: m.abundance) 647 648 @property 649 def min_abundance(self): 650 """Return the minimum abundance value of the mass spectrum.""" 651 return min([mspeak.abundance for mspeak in self.mspeaks]) 652 653 # takes too much cpu time 654 @property 655 def dynamic_range(self): 656 """Return the dynamic range of the mass spectrum.""" 657 return self._dynamic_range 658 659 @property 660 def baseline_noise(self): 661 """Return the baseline noise of the mass spectrum.""" 662 if self._baseline_noise: 663 return self._baseline_noise 664 else: 665 return None 666 667 @property 668 def baseline_noise_std(self): 669 """Return the standard deviation of the baseline noise of the mass spectrum.""" 670 if self._baseline_noise_std == 0: 671 return self._baseline_noise_std 672 if self._baseline_noise_std: 673 return self._baseline_noise_std 674 else: 675 return None 676 677 @property 678 def Aterm(self): 679 """Return the A-term calibration coefficient of the mass spectrum.""" 680 return self._calibration_terms[0] 681 682 @property 683 def Bterm(self): 684 """Return the B-term calibration coefficient of the mass spectrum.""" 685 return self._calibration_terms[1] 686 687 @property 688 def Cterm(self): 689 """Return the C-term calibration coefficient of the mass spectrum.""" 690 return self._calibration_terms[2] 691 692 @property 693 def filename(self): 694 """Return the filename of the mass spectrum.""" 695 return Path(self._filename) 696 697 @property 698 def dir_location(self): 699 """Return the directory location of the mass spectrum.""" 700 return self._dir_location 701 702 def sort_by_mz(self): 703 """Sort the mass spectrum by m/z values.""" 704 return sorted(self, key=lambda m: m.mz_exp) 705 706 def sort_by_abundance(self, reverse=False): 707 """Sort the mass spectrum by abundance values.""" 708 return sorted(self, key=lambda m: m.abundance, reverse=reverse) 709 710 @property 711 def tic(self): 712 """Return the total ion current of the mass spectrum.""" 713 return trapezoid(self.abundance_profile, self.mz_exp_profile) 714 715 def check_mspeaks_warning(self): 716 """Check if the mass spectrum has MSpeaks objects. 717 718 Raises 719 ------ 720 Warning 721 If the mass spectrum has no MSpeaks objects. 722 """ 723 import warnings 724 725 if self.mspeaks: 726 pass 727 else: 728 warnings.warn("mspeaks list is empty, continuing without filtering data") 729 730 def check_mspeaks(self): 731 """Check if the mass spectrum has MSpeaks objects. 732 733 Raises 734 ------ 735 Exception 736 If the mass spectrum has no MSpeaks objects. 737 """ 738 if self.mspeaks: 739 pass 740 else: 741 raise Exception( 742 "mspeaks list is empty, please run process_mass_spec() first" 743 ) 744 745 def remove_assignment_by_index(self, indexes): 746 """Remove the molecular formula assignment of the MSpeaks objects at the specified indexes. 747 748 Parameters 749 ---------- 750 indexes : list of int 751 A list of indexes of the MSpeaks objects to remove the molecular formula assignment from. 752 """ 753 for i in indexes: 754 self.mspeaks[i].clear_molecular_formulas() 755 756 def filter_by_index(self, list_indexes): 757 """Filter the mass spectrum by the specified indexes. 758 759 Parameters 760 ---------- 761 list_indexes : list of int 762 A list of indexes of the MSpeaks objects to drop. 763 764 """ 765 766 self.mspeaks = [ 767 self.mspeaks[i] for i in range(len(self.mspeaks)) if i not in list_indexes 768 ] 769 770 for i, mspeak in enumerate(self.mspeaks): 771 mspeak.index = i 772 773 self._set_nominal_masses_start_final_indexes() 774 775 def filter_by_mz(self, min_mz, max_mz): 776 """Filter the mass spectrum by the specified m/z range. 777 778 Parameters 779 ---------- 780 min_mz : float 781 The minimum m/z value to keep. 782 max_mz : float 783 The maximum m/z value to keep. 784 785 """ 786 self.check_mspeaks_warning() 787 indexes = [ 788 index 789 for index, mspeak in enumerate(self.mspeaks) 790 if not min_mz <= mspeak.mz_exp <= max_mz 791 ] 792 self.filter_by_index(indexes) 793 794 def filter_by_s2n(self, min_s2n, max_s2n=False): 795 """Filter the mass spectrum by the specified signal-to-noise ratio range. 796 797 Parameters 798 ---------- 799 min_s2n : float 800 The minimum signal-to-noise ratio to keep. 801 max_s2n : float, optional 802 The maximum signal-to-noise ratio to keep. Defaults to False (no maximum). 803 804 """ 805 self.check_mspeaks_warning() 806 if max_s2n: 807 indexes = [ 808 index 809 for index, mspeak in enumerate(self.mspeaks) 810 if not min_s2n <= mspeak.signal_to_noise <= max_s2n 811 ] 812 else: 813 indexes = [ 814 index 815 for index, mspeak in enumerate(self.mspeaks) 816 if mspeak.signal_to_noise <= min_s2n 817 ] 818 self.filter_by_index(indexes) 819 820 def filter_by_abundance(self, min_abund, max_abund=False): 821 """Filter the mass spectrum by the specified abundance range. 822 823 Parameters 824 ---------- 825 min_abund : float 826 The minimum abundance to keep. 827 max_abund : float, optional 828 The maximum abundance to keep. Defaults to False (no maximum). 829 830 """ 831 self.check_mspeaks_warning() 832 if max_abund: 833 indexes = [ 834 index 835 for index, mspeak in enumerate(self.mspeaks) 836 if not min_abund <= mspeak.abundance <= max_abund 837 ] 838 else: 839 indexes = [ 840 index 841 for index, mspeak in enumerate(self.mspeaks) 842 if mspeak.abundance <= min_abund 843 ] 844 self.filter_by_index(indexes) 845 846 def filter_by_max_resolving_power(self, B, T): 847 """Filter the mass spectrum by the specified maximum resolving power. 848 849 Parameters 850 ---------- 851 B : float 852 T : float 853 854 """ 855 856 rpe = lambda m, z: (1.274e7 * z * B * T) / (m * z) 857 858 self.check_mspeaks_warning() 859 860 indexes_to_remove = [ 861 index 862 for index, mspeak in enumerate(self.mspeaks) 863 if mspeak.resolving_power >= rpe(mspeak.mz_exp, mspeak.polarity) 864 ] 865 self.filter_by_index(indexes_to_remove) 866 867 def filter_by_mean_resolving_power( 868 self, ndeviations=3, plot=False, guess_pars=False 869 ): 870 """Filter the mass spectrum by the specified mean resolving power. 871 872 Parameters 873 ---------- 874 ndeviations : float, optional 875 The number of standard deviations to use for filtering. Defaults to 3. 876 plot : bool, optional 877 Whether to plot the resolving power distribution. Defaults to False. 878 guess_pars : bool, optional 879 Whether to guess the parameters for the Gaussian model. Defaults to False. 880 881 """ 882 self.check_mspeaks_warning() 883 indexes_to_remove = MeanResolvingPowerFilter( 884 self, ndeviations, plot, guess_pars 885 ).main() 886 self.filter_by_index(indexes_to_remove) 887 888 def filter_by_min_resolving_power( 889 self, B, T, apodization_method: str = None, tolerance: float = 0 890 ): 891 """Filter the mass spectrum by the calculated minimum theoretical resolving power. 892 893 This is currently designed only for FTICR data, and accounts only for magnitude mode data 894 Accurate results require passing the apodisaion method used to calculate the resolving power. 895 see the ICRMassPeak function `resolving_power_calc` for more details. 896 897 Parameters 898 ---------- 899 B : Magnetic field strength in Tesla, float 900 T : transient length in seconds, float 901 apodization_method : str, optional 902 The apodization method to use for calculating the resolving power. Defaults to None. 903 tolerance : float, optional 904 The tolerance for the threshold. Defaults to 0, i.e. no tolerance 905 906 """ 907 if self.analyzer != "ICR": 908 raise Exception("This method is only applicable to ICR mass spectra. ") 909 910 self.check_mspeaks_warning() 911 912 indexes_to_remove = [ 913 index 914 for index, mspeak in enumerate(self.mspeaks) 915 if mspeak.resolving_power 916 < (1 - tolerance) 917 * mspeak.resolving_power_calc(B, T, apodization_method=apodization_method) 918 ] 919 self.filter_by_index(indexes_to_remove) 920 921 def filter_by_noise_threshold(self): 922 """Filter the mass spectrum by the noise threshold.""" 923 924 threshold = self.get_noise_threshold()[1][0] 925 926 self.check_mspeaks_warning() 927 928 indexes_to_remove = [ 929 index 930 for index, mspeak in enumerate(self.mspeaks) 931 if mspeak.abundance <= threshold 932 ] 933 self.filter_by_index(indexes_to_remove) 934 935 def find_peaks(self): 936 """Find the peaks of the mass spectrum.""" 937 # needs to clear previous results from peak_picking 938 self._mspeaks = list() 939 940 # then do peak picking 941 self.do_peak_picking() 942 # print("A total of %i peaks were found" % len(self._mspeaks)) 943 944 def change_kendrick_base_all_mspeaks(self, kendrick_dict_base): 945 """Change the Kendrick base of all MSpeaks objects. 946 947 Parameters 948 ---------- 949 kendrick_dict_base : dict 950 A dictionary of the Kendrick base to change to. 951 952 Notes 953 ----- 954 Example of kendrick_dict_base parameter: kendrick_dict_base = {"C": 1, "H": 2} or {"C": 1, "H": 1, "O":1} etc 955 """ 956 self.parameters.ms_peak.kendrick_base = kendrick_dict_base 957 958 for mspeak in self.mspeaks: 959 mspeak.change_kendrick_base(kendrick_dict_base) 960 961 def get_nominal_mz_first_last_indexes(self, nominal_mass): 962 """Return the first and last indexes of the MSpeaks objects with the specified nominal mass. 963 964 Parameters 965 ---------- 966 nominal_mass : int 967 The nominal mass to get the indexes for. 968 969 Returns 970 ------- 971 tuple 972 A tuple containing the first and last indexes of the MSpeaks objects with the specified nominal mass. 973 """ 974 if self._dict_nominal_masses_indexes: 975 if nominal_mass in self._dict_nominal_masses_indexes.keys(): 976 return ( 977 self._dict_nominal_masses_indexes.get(nominal_mass)[0], 978 self._dict_nominal_masses_indexes.get(nominal_mass)[1] + 1, 979 ) 980 981 else: 982 # import warnings 983 # uncomment warn to distribution 984 # warnings.warn("Nominal mass not found in _dict_nominal_masses_indexes, returning (0, 0) for nominal mass %i"%nominal_mass) 985 return (0, 0) 986 else: 987 raise Exception( 988 "run process_mass_spec() function before trying to access the data" 989 ) 990 991 def get_masses_count_by_nominal_mass(self): 992 """Return a dictionary of the nominal masses and their counts.""" 993 994 dict_nominal_masses_count = {} 995 996 all_nominal_masses = list(set([i.nominal_mz_exp for i in self.mspeaks])) 997 998 for nominal_mass in all_nominal_masses: 999 if nominal_mass not in dict_nominal_masses_count: 1000 dict_nominal_masses_count[nominal_mass] = len( 1001 list(self.get_nominal_mass_indexes(nominal_mass)) 1002 ) 1003 1004 return dict_nominal_masses_count 1005 1006 def datapoints_count_by_nominal_mz(self, mz_overlay=0.1): 1007 """Return a dictionary of the nominal masses and their counts. 1008 1009 Parameters 1010 ---------- 1011 mz_overlay : float, optional 1012 The m/z overlay to use for counting. Defaults to 0.1. 1013 1014 Returns 1015 ------- 1016 dict 1017 A dictionary of the nominal masses and their counts. 1018 """ 1019 dict_nominal_masses_count = {} 1020 1021 all_nominal_masses = list(set([i.nominal_mz_exp for i in self.mspeaks])) 1022 1023 for nominal_mass in all_nominal_masses: 1024 if nominal_mass not in dict_nominal_masses_count: 1025 min_mz = nominal_mass - mz_overlay 1026 1027 max_mz = nominal_mass + 1 + mz_overlay 1028 1029 indexes = indexes = where( 1030 (self.mz_exp_profile > min_mz) & (self.mz_exp_profile < max_mz) 1031 ) 1032 1033 dict_nominal_masses_count[nominal_mass] = indexes[0].size 1034 1035 return dict_nominal_masses_count 1036 1037 def get_nominal_mass_indexes(self, nominal_mass, overlay=0.1): 1038 """Return the indexes of the MSpeaks objects with the specified nominal mass. 1039 1040 Parameters 1041 ---------- 1042 nominal_mass : int 1043 The nominal mass to get the indexes for. 1044 overlay : float, optional 1045 The m/z overlay to use for counting. Defaults to 0.1. 1046 1047 Returns 1048 ------- 1049 generator 1050 A generator of the indexes of the MSpeaks objects with the specified nominal mass. 1051 """ 1052 min_mz_to_look = nominal_mass - overlay 1053 max_mz_to_look = nominal_mass + 1 + overlay 1054 1055 return ( 1056 i 1057 for i in range(len(self.mspeaks)) 1058 if min_mz_to_look <= self.mspeaks[i].mz_exp <= max_mz_to_look 1059 ) 1060 1061 # indexes = (i for i in range(len(self.mspeaks)) if min_mz_to_look <= self.mspeaks[i].mz_exp <= max_mz_to_look) 1062 # return indexes 1063 1064 def _set_nominal_masses_start_final_indexes(self): 1065 """Set the start and final indexes of the MSpeaks objects for all nominal masses.""" 1066 dict_nominal_masses_indexes = {} 1067 1068 all_nominal_masses = set(i.nominal_mz_exp for i in self.mspeaks) 1069 1070 for nominal_mass in all_nominal_masses: 1071 # indexes = self.get_nominal_mass_indexes(nominal_mass) 1072 # Convert the iterator to a list to avoid multiple calls 1073 indexes = list(self.get_nominal_mass_indexes(nominal_mass)) 1074 1075 # If the list is not empty, find the first and last; otherwise, set None 1076 if indexes: 1077 first, last = indexes[0], indexes[-1] 1078 else: 1079 first = last = None 1080 # defaultvalue = None 1081 # first = last = next(indexes, defaultvalue) 1082 # for last in indexes: 1083 # pass 1084 1085 dict_nominal_masses_indexes[nominal_mass] = (first, last) 1086 1087 self._dict_nominal_masses_indexes = dict_nominal_masses_indexes 1088 1089 def plot_centroid(self, ax=None, c="g"): 1090 """Plot the centroid data of the mass spectrum. 1091 1092 Parameters 1093 ---------- 1094 ax : matplotlib.axes.Axes, optional 1095 The matplotlib axes to plot on. Defaults to None. 1096 c : str, optional 1097 The color to use for the plot. Defaults to 'g' (green). 1098 1099 Returns 1100 ------- 1101 matplotlib.axes.Axes 1102 The matplotlib axes containing the plot. 1103 1104 Raises 1105 ------ 1106 Exception 1107 If no centroid data is found. 1108 """ 1109 1110 import matplotlib.pyplot as plt 1111 1112 if self._mspeaks: 1113 if ax is None: 1114 ax = plt.gca() 1115 1116 markerline_a, stemlines_a, baseline_a = ax.stem( 1117 self.mz_exp, self.abundance, linefmt="-", markerfmt=" " 1118 ) 1119 1120 plt.setp(markerline_a, "color", c, "linewidth", 2) 1121 plt.setp(stemlines_a, "color", c, "linewidth", 2) 1122 plt.setp(baseline_a, "color", c, "linewidth", 2) 1123 1124 ax.set_xlabel("$\t{m/z}$", fontsize=12) 1125 ax.set_ylabel("Abundance", fontsize=12) 1126 ax.tick_params(axis="both", which="major", labelsize=12) 1127 1128 ax.axes.spines["top"].set_visible(False) 1129 ax.axes.spines["right"].set_visible(False) 1130 1131 ax.get_yaxis().set_visible(False) 1132 ax.spines["left"].set_visible(False) 1133 1134 else: 1135 raise Exception("No centroid data found, please run process_mass_spec") 1136 1137 return ax 1138 1139 def plot_profile_and_noise_threshold(self, ax=None, legend=False): 1140 """Plot the profile data and noise threshold of the mass spectrum. 1141 1142 Parameters 1143 ---------- 1144 ax : matplotlib.axes.Axes, optional 1145 The matplotlib axes to plot on. Defaults to None. 1146 legend : bool, optional 1147 Whether to show the legend. Defaults to False. 1148 1149 Returns 1150 ------- 1151 matplotlib.axes.Axes 1152 The matplotlib axes containing the plot. 1153 1154 Raises 1155 ------ 1156 Exception 1157 If no noise threshold is found. 1158 """ 1159 import matplotlib.pyplot as plt 1160 1161 if self.baseline_noise_std and self.baseline_noise_std: 1162 # x = (self.mz_exp_profile.min(), self.mz_exp_profile.max()) 1163 baseline = (self.baseline_noise, self.baseline_noise) 1164 1165 # std = self.parameters.mass_spectrum.noise_threshold_min_std 1166 # threshold = self.baseline_noise_std + (std * self.baseline_noise_std) 1167 x, y = self.get_noise_threshold() 1168 1169 if ax is None: 1170 ax = plt.gca() 1171 1172 ax.plot( 1173 self.mz_exp_profile, 1174 self.abundance_profile, 1175 color="green", 1176 label="Spectrum", 1177 ) 1178 ax.plot(x, (baseline, baseline), color="yellow", label="Baseline Noise") 1179 ax.plot(x, y, color="red", label="Noise Threshold") 1180 1181 ax.set_xlabel("$\t{m/z}$", fontsize=12) 1182 ax.set_ylabel("Abundance", fontsize=12) 1183 ax.tick_params(axis="both", which="major", labelsize=12) 1184 1185 ax.axes.spines["top"].set_visible(False) 1186 ax.axes.spines["right"].set_visible(False) 1187 1188 ax.get_yaxis().set_visible(False) 1189 ax.spines["left"].set_visible(False) 1190 if legend: 1191 ax.legend() 1192 1193 else: 1194 raise Exception("Calculate noise threshold first") 1195 1196 return ax 1197 1198 def plot_mz_domain_profile(self, color="green", ax=None): 1199 """Plot the m/z domain profile of the mass spectrum. 1200 1201 Parameters 1202 ---------- 1203 color : str, optional 1204 The color to use for the plot. Defaults to 'green'. 1205 ax : matplotlib.axes.Axes, optional 1206 The matplotlib axes to plot on. Defaults to None. 1207 1208 Returns 1209 ------- 1210 matplotlib.axes.Axes 1211 The matplotlib axes containing the plot. 1212 """ 1213 1214 import matplotlib.pyplot as plt 1215 1216 if ax is None: 1217 ax = plt.gca() 1218 ax.plot(self.mz_exp_profile, self.abundance_profile, color=color) 1219 ax.set(xlabel="m/z", ylabel="abundance") 1220 1221 return ax 1222 1223 def to_excel(self, out_file_path, write_metadata=True): 1224 """Export the mass spectrum to an Excel file. 1225 1226 Parameters 1227 ---------- 1228 out_file_path : str 1229 The path to the Excel file to export to. 1230 write_metadata : bool, optional 1231 Whether to write the metadata to the Excel file. Defaults to True. 1232 1233 Returns 1234 ------- 1235 None 1236 """ 1237 from corems.mass_spectrum.output.export import HighResMassSpecExport 1238 1239 exportMS = HighResMassSpecExport(out_file_path, self) 1240 exportMS.to_excel(write_metadata=write_metadata) 1241 1242 def to_hdf(self, out_file_path): 1243 """Export the mass spectrum to an HDF file. 1244 1245 Parameters 1246 ---------- 1247 out_file_path : str 1248 The path to the HDF file to export to. 1249 1250 Returns 1251 ------- 1252 None 1253 """ 1254 from corems.mass_spectrum.output.export import HighResMassSpecExport 1255 1256 exportMS = HighResMassSpecExport(out_file_path, self) 1257 exportMS.to_hdf() 1258 1259 def to_csv(self, out_file_path, write_metadata=True): 1260 """Export the mass spectrum to a CSV file. 1261 1262 Parameters 1263 ---------- 1264 out_file_path : str 1265 The path to the CSV file to export to. 1266 write_metadata : bool, optional 1267 Whether to write the metadata to the CSV file. Defaults to True. 1268 1269 """ 1270 from corems.mass_spectrum.output.export import HighResMassSpecExport 1271 1272 exportMS = HighResMassSpecExport(out_file_path, self) 1273 exportMS.to_csv(write_metadata=write_metadata) 1274 1275 def to_pandas(self, out_file_path, write_metadata=True): 1276 """Export the mass spectrum to a Pandas dataframe with pkl extension. 1277 1278 Parameters 1279 ---------- 1280 out_file_path : str 1281 The path to the CSV file to export to. 1282 write_metadata : bool, optional 1283 Whether to write the metadata to the CSV file. Defaults to True. 1284 1285 """ 1286 from corems.mass_spectrum.output.export import HighResMassSpecExport 1287 1288 exportMS = HighResMassSpecExport(out_file_path, self) 1289 exportMS.to_pandas(write_metadata=write_metadata) 1290 1291 def to_parquet(self, out_file_path, write_metadata=True): 1292 """Export the mass spectrum to a Parquet file. 1293 1294 Parameters 1295 ---------- 1296 out_file_path : str 1297 The path to the Parquet file to export to. 1298 write_metadata : bool, optional 1299 Whether to write the metadata to a JSON file. Defaults to True. 1300 1301 Notes 1302 ----- 1303 Requires ``pyarrow`` (or ``fastparquet``) for pandas Parquet I/O. 1304 """ 1305 from corems.mass_spectrum.output.export import HighResMassSpecExport 1306 1307 exportMS = HighResMassSpecExport(out_file_path, self) 1308 exportMS.to_parquet(write_metadata=write_metadata) 1309 1310 def to_dataframe(self, additional_columns=None): 1311 """Return the mass spectrum as a Pandas dataframe. 1312 1313 Parameters 1314 ---------- 1315 additional_columns : list, optional 1316 A list of additional columns to include in the dataframe. Defaults to None. 1317 Suitable columns are: "Aromaticity Index", "Aromaticity Index (modified)", and "NOSC" 1318 1319 Returns 1320 ------- 1321 pandas.DataFrame 1322 The mass spectrum as a Pandas dataframe. 1323 """ 1324 from corems.mass_spectrum.output.export import HighResMassSpecExport 1325 1326 exportMS = HighResMassSpecExport(self.filename, self) 1327 return exportMS.get_pandas_df(additional_columns=additional_columns) 1328 1329 def to_json(self): 1330 """Return the mass spectrum as a JSON file.""" 1331 from corems.mass_spectrum.output.export import HighResMassSpecExport 1332 1333 exportMS = HighResMassSpecExport(self.filename, self) 1334 return exportMS.to_json() 1335 1336 def parameters_json(self): 1337 """Return the parameters of the mass spectrum as a JSON string.""" 1338 from corems.mass_spectrum.output.export import HighResMassSpecExport 1339 1340 exportMS = HighResMassSpecExport(self.filename, self) 1341 return exportMS.parameters_to_json() 1342 1343 def parameters_toml(self): 1344 """Return the parameters of the mass spectrum as a TOML string.""" 1345 from corems.mass_spectrum.output.export import HighResMassSpecExport 1346 1347 exportMS = HighResMassSpecExport(self.filename, self) 1348 return exportMS.parameters_to_toml()
A mass spectrum base class, stores the profile data and instrument settings.
Iteration over a list of MSPeaks classes stored at the _mspeaks attributes. _mspeaks is populated under the hood by calling process_mass_spec method. Iteration is null if _mspeaks is empty.
Parameters
- mz_exp (array_like): The m/z values of the mass spectrum.
- abundance (array_like): The abundance values of the mass spectrum.
- d_params (dict): A dictionary of parameters for the mass spectrum.
- **kwargs: Additional keyword arguments.
Attributes
- mspeaks (list): A list of mass peaks.
- is_calibrated (bool): Whether the mass spectrum is calibrated.
- is_centroid (bool): Whether the mass spectrum is centroided.
- has_frequency (bool): Whether the mass spectrum has a frequency domain.
- calibration_order (None or int): The order of the mass spectrum's calibration.
- calibration_points (None or ndarray): The calibration points of the mass spectrum.
- calibration_ref_mzs (None or ndarray): The reference m/z values of the mass spectrum's calibration.
- calibration_meas_mzs (None or ndarray): The measured m/z values of the mass spectrum's calibration.
- calibration_RMS (None or float): The root mean square of the mass spectrum's calibration.
- calibration_segment (None or CalibrationSegment): The calibration segment of the mass spectrum.
- _abundance (ndarray): The abundance values of the mass spectrum.
- _mz_exp (ndarray): The m/z values of the mass spectrum.
- _mspeaks (list): A list of mass peaks.
- _dict_nominal_masses_indexes (dict): A dictionary of nominal masses and their indexes.
- _baseline_noise (float): The baseline noise of the mass spectrum.
- _baseline_noise_std (float): The standard deviation of the baseline noise of the mass spectrum.
- _dynamic_range (float or None): The dynamic range of the mass spectrum.
- _transient_settings (None or TransientSettings): The transient settings of the mass spectrum.
- _frequency_domain (None or FrequencyDomain): The frequency domain of the mass spectrum.
- _mz_cal_profile (None or MzCalibrationProfile): The m/z calibration profile of the mass spectrum.
Methods
- process_mass_spec(). Main function to process the mass spectrum, including calculating the noise threshold, peak picking, and resetting the MSpeak indexes.
See also: MassSpecCentroid(), MassSpecfromFreq(), MassSpecProfile()
127 def __init__(self, mz_exp, abundance, d_params, **kwargs): 128 self._abundance = array(abundance, dtype=float64) 129 self._mz_exp = array(mz_exp, dtype=float64) 130 131 # objects created after process_mass_spec() function 132 self._mspeaks = list() 133 self.mspeaks = list() 134 self._dict_nominal_masses_indexes = dict() 135 self._baseline_noise = 0.001 136 self._baseline_noise_std = 0.001 137 self._dynamic_range = None 138 # set to None: initialization occurs inside subclass MassSpecfromFreq 139 self._transient_settings = None 140 self._frequency_domain = None 141 self._mz_cal_profile = None 142 self.is_calibrated = False 143 144 self._set_parameters_objects(d_params) 145 self._init_settings() 146 147 self.is_centroid = False 148 self.has_frequency = False 149 150 self.calibration_order = None 151 self.calibration_points = None 152 self.calibration_ref_mzs = None 153 self.calibration_meas_mzs = None 154 self.calibration_RMS = None 155 self.calibration_segment = None 156 self.calibration_raw_error_median = None 157 self.calibration_raw_error_stdev = None
169 def set_indexes(self, list_indexes): 170 """Set the mass spectrum to iterate over only the selected MSpeaks indexes. 171 172 Parameters 173 ---------- 174 list_indexes : list of int 175 A list of integers representing the indexes of the MSpeaks to iterate over. 176 177 """ 178 self.mspeaks = [self._mspeaks[i] for i in list_indexes] 179 180 for i, mspeak in enumerate(self.mspeaks): 181 mspeak.index = i 182 183 self._set_nominal_masses_start_final_indexes()
Set the mass spectrum to iterate over only the selected MSpeaks indexes.
Parameters
- list_indexes (list of int): A list of integers representing the indexes of the MSpeaks to iterate over.
185 def reset_indexes(self): 186 """Reset the mass spectrum to iterate over all MSpeaks objects. 187 188 This method resets the mass spectrum to its original state, allowing iteration over all MSpeaks objects. 189 It also sets the index of each MSpeak object to its corresponding position in the mass spectrum. 190 191 """ 192 self.mspeaks = self._mspeaks 193 194 for i, mspeak in enumerate(self.mspeaks): 195 mspeak.index = i 196 197 self._set_nominal_masses_start_final_indexes()
Reset the mass spectrum to iterate over all MSpeaks objects.
This method resets the mass spectrum to its original state, allowing iteration over all MSpeaks objects. It also sets the index of each MSpeak object to its corresponding position in the mass spectrum.
199 def add_mspeak( 200 self, 201 polarity, 202 mz_exp, 203 abundance, 204 resolving_power, 205 signal_to_noise, 206 massspec_indexes, 207 exp_freq=None, 208 ms_parent=None, 209 **kwargs, 210 ): 211 """Add a new MSPeak object to the MassSpectrum object. 212 213 Parameters 214 ---------- 215 polarity : int 216 Acquisition polarity of the MSPeak (``+1`` or ``-1``). 217 Do **not** pass ``ion_charge``; peaks store polarity only. 218 Assignment charge lives on ``MolecularFormula.ion_charge``. 219 mz_exp : float 220 The experimental m/z value of the MSPeak. 221 abundance : float 222 The abundance of the MSPeak. 223 resolving_power : float 224 The resolving power of the MSPeak. 225 signal_to_noise : float 226 The signal-to-noise ratio of the MSPeak. 227 massspec_indexes : list 228 A list of indexes of the MSPeak in the MassSpectrum object. 229 exp_freq : float, optional 230 The experimental frequency of the MSPeak. Defaults to None. 231 ms_parent : MSParent, optional 232 The MSParent object associated with the MSPeak. Defaults to None. 233 234 Raises 235 ------ 236 TypeError 237 If ``ion_charge`` is passed (removed; use ``polarity``), or if any 238 other unexpected keyword argument is given. 239 """ 240 if "ion_charge" in kwargs: 241 raise TypeError( 242 "add_mspeak() no longer accepts ion_charge=...; pass polarity " 243 "(±1) instead. Peaks store acquisition polarity only. Assignment " 244 "charge belongs on MolecularFormula.ion_charge after formula matching." 245 ) 246 if kwargs: 247 unexpected = ", ".join(sorted(kwargs)) 248 raise TypeError( 249 f"add_mspeak() got unexpected keyword argument(s): {unexpected}" 250 ) 251 252 mspeak = MSPeak( 253 polarity, 254 mz_exp, 255 abundance, 256 resolving_power, 257 signal_to_noise, 258 massspec_indexes, 259 len(self._mspeaks), 260 exp_freq=exp_freq, 261 ms_parent=ms_parent, 262 ) 263 264 self._mspeaks.append(mspeak)
Add a new MSPeak object to the MassSpectrum object.
Parameters
- polarity (int):
Acquisition polarity of the MSPeak (
+1or-1). Do not passion_charge; peaks store polarity only. Assignment charge lives onMolecularFormula.ion_charge. - mz_exp (float): The experimental m/z value of the MSPeak.
- abundance (float): The abundance of the MSPeak.
- resolving_power (float): The resolving power of the MSPeak.
- signal_to_noise (float): The signal-to-noise ratio of the MSPeak.
- massspec_indexes (list): A list of indexes of the MSPeak in the MassSpectrum object.
- exp_freq (float, optional): The experimental frequency of the MSPeak. Defaults to None.
- ms_parent (MSParent, optional): The MSParent object associated with the MSPeak. Defaults to None.
Raises
- TypeError: If
ion_chargeis passed (removed; usepolarity), or if any other unexpected keyword argument is given.
332 def reset_cal_therms(self, Aterm, Bterm, C, fas=0): 333 """Reset calibration terms and recalculate the mass-to-charge ratio and abundance. 334 335 Parameters 336 ---------- 337 Aterm : float 338 The A-term calibration coefficient. 339 Bterm : float 340 The B-term calibration coefficient. 341 C : float 342 The C-term calibration coefficient. 343 fas : float, optional 344 The frequency amplitude scaling factor. Default is 0. 345 """ 346 self._calibration_terms = (Aterm, Bterm, C) 347 348 self._mz_exp = self._f_to_mz() 349 self._abundance = self._abundance 350 self.find_peaks() 351 self.reset_indexes()
Reset calibration terms and recalculate the mass-to-charge ratio and abundance.
Parameters
- Aterm (float): The A-term calibration coefficient.
- Bterm (float): The B-term calibration coefficient.
- C (float): The C-term calibration coefficient.
- fas (float, optional): The frequency amplitude scaling factor. Default is 0.
353 def clear_molecular_formulas(self): 354 """Clear the molecular formulas for all mspeaks in the MassSpectrum. 355 356 Returns 357 ------- 358 numpy.ndarray 359 An array of the cleared molecular formulas for each mspeak in the MassSpectrum. 360 """ 361 self.check_mspeaks() 362 return array([mspeak.clear_molecular_formulas() for mspeak in self.mspeaks])
Clear the molecular formulas for all mspeaks in the MassSpectrum.
Returns
- numpy.ndarray: An array of the cleared molecular formulas for each mspeak in the MassSpectrum.
364 def process_mass_spec(self, keep_profile=True): 365 """Process the mass spectrum. 366 367 Parameters 368 ---------- 369 keep_profile : bool, optional 370 Whether to keep the profile data after processing. Defaults to True. 371 372 Notes 373 ----- 374 This method does the following: 375 - calculates the noise threshold 376 - does peak picking (creates mspeak_objs) 377 - resets the mspeak_obj indexes 378 """ 379 380 # if runned mannually make sure to rerun filter_by_noise_threshold 381 # calculates noise threshold 382 # do peak picking( create mspeak_objs) 383 # reset mspeak_obj the indexes 384 385 self.cal_noise_threshold() 386 387 self.find_peaks() 388 self.reset_indexes() 389 390 if self.mspeaks: 391 self._dynamic_range = self.max_abundance / self.min_abundance 392 else: 393 self._dynamic_range = 0 394 if not keep_profile: 395 self._abundance *= 0 396 self._mz_exp *= 0
Process the mass spectrum.
Parameters
- keep_profile (bool, optional): Whether to keep the profile data after processing. Defaults to True.
Notes
This method does the following:
- calculates the noise threshold
- does peak picking (creates mspeak_objs)
- resets the mspeak_obj indexes
418 def cal_noise_threshold(self): 419 """Calculate the noise threshold of the mass spectrum.""" 420 421 self._resolve_noise_threshold_method() 422 423 if self.label == Labels.simulated_profile: 424 self._baseline_noise, self._baseline_noise_std = 0.1, 1 425 426 if self.settings.noise_threshold_method == "log": 427 self._baseline_noise, self._baseline_noise_std = ( 428 self.run_log_noise_threshold_calc() 429 ) 430 431 else: 432 self._baseline_noise, self._baseline_noise_std = ( 433 self.run_noise_threshold_calc() 434 )
Calculate the noise threshold of the mass spectrum.
436 @property 437 def parameters(self): 438 """Return the parameters of the mass spectrum.""" 439 return self._parameters
Return the parameters of the mass spectrum.
445 def set_parameter_from_json(self, parameters_path): 446 """Set the parameters of the mass spectrum from a JSON file. 447 448 Parameters 449 ---------- 450 parameters_path : str 451 The path to the JSON file containing the parameters. 452 """ 453 load_and_set_parameters_ms(self, parameters_path=parameters_path)
Set the parameters of the mass spectrum from a JSON file.
Parameters
- parameters_path (str): The path to the JSON file containing the parameters.
458 @property 459 def mspeaks_settings(self): 460 """Return the MS peak settings of the mass spectrum.""" 461 return self.parameters.ms_peak
Return the MS peak settings of the mass spectrum.
467 @property 468 def settings(self): 469 """Return the settings of the mass spectrum.""" 470 return self.parameters.mass_spectrum
Return the settings of the mass spectrum.
476 @property 477 def molecular_search_settings(self): 478 """Return the molecular search settings of the mass spectrum.""" 479 return self.parameters.molecular_search
Return the molecular search settings of the mass spectrum.
485 @property 486 def mz_cal_profile(self): 487 """Return the calibrated m/z profile of the mass spectrum.""" 488 return self._mz_cal_profile
Return the calibrated m/z profile of the mass spectrum.
500 @property 501 def mz_cal(self): 502 """Return the calibrated m/z values of the mass spectrum.""" 503 return array([mspeak.mz_cal for mspeak in self.mspeaks])
Return the calibrated m/z values of the mass spectrum.
517 @property 518 def mz_exp(self): 519 """Return the experimental m/z values of the mass spectrum.""" 520 self.check_mspeaks() 521 522 if self.is_calibrated: 523 return array([mspeak.mz_cal for mspeak in self.mspeaks]) 524 525 else: 526 return array([mspeak.mz_exp for mspeak in self.mspeaks])
Return the experimental m/z values of the mass spectrum.
528 @property 529 def freq_exp_profile(self): 530 """Return the experimental frequency profile of the mass spectrum.""" 531 return self._frequency_domain
Return the experimental frequency profile of the mass spectrum.
537 @property 538 def freq_exp_pp(self): 539 """Return the experimental frequency values of the mass spectrum that are used for peak picking.""" 540 _, _, freq = self.prepare_peak_picking_data() 541 return freq
Return the experimental frequency values of the mass spectrum that are used for peak picking.
543 @property 544 def mz_exp_profile(self): 545 """Return the experimental m/z profile of the mass spectrum.""" 546 if self.is_calibrated: 547 return self.mz_cal_profile 548 else: 549 return self._mz_exp
Return the experimental m/z profile of the mass spectrum.
555 @property 556 def mz_exp_pp(self): 557 """Return the experimental m/z values of the mass spectrum that are used for peak picking.""" 558 mz, _, _ = self.prepare_peak_picking_data() 559 return mz
Return the experimental m/z values of the mass spectrum that are used for peak picking.
561 @property 562 def abundance_profile(self): 563 """Return the abundance profile of the mass spectrum.""" 564 return self._abundance
Return the abundance profile of the mass spectrum.
570 @property 571 def abundance_profile_pp(self): 572 """Return the abundance profile of the mass spectrum that is used for peak picking.""" 573 _, abundance, _ = self.prepare_peak_picking_data() 574 return abundance
Return the abundance profile of the mass spectrum that is used for peak picking.
576 @property 577 def abundance(self): 578 """Return the abundance values of the mass spectrum.""" 579 self.check_mspeaks() 580 return array([mspeak.abundance for mspeak in self.mspeaks])
Return the abundance values of the mass spectrum.
582 def freq_exp(self): 583 """Return the experimental frequency values of the mass spectrum.""" 584 self.check_mspeaks() 585 return array([mspeak.freq_exp for mspeak in self.mspeaks])
Return the experimental frequency values of the mass spectrum.
587 @property 588 def resolving_power(self): 589 """Return the resolving power values of the mass spectrum.""" 590 self.check_mspeaks() 591 return array([mspeak.resolving_power for mspeak in self.mspeaks])
Return the resolving power values of the mass spectrum.
598 @property 599 def nominal_mz(self): 600 """Return the nominal m/z values of the mass spectrum.""" 601 if self._dict_nominal_masses_indexes: 602 return sorted(list(self._dict_nominal_masses_indexes.keys())) 603 else: 604 raise ValueError("Nominal indexes not yet set")
Return the nominal m/z values of the mass spectrum.
606 def get_mz_and_abundance_peaks_tuples(self): 607 """Return a list of tuples containing the m/z and abundance values of the mass spectrum.""" 608 self.check_mspeaks() 609 return [(mspeak.mz_exp, mspeak.abundance) for mspeak in self.mspeaks]
Return a list of tuples containing the m/z and abundance values of the mass spectrum.
611 @property 612 def kmd(self): 613 """Return the Kendrick mass defect values of the mass spectrum.""" 614 self.check_mspeaks() 615 return array([mspeak.kmd for mspeak in self.mspeaks])
Return the Kendrick mass defect values of the mass spectrum.
617 @property 618 def kendrick_mass(self): 619 """Return the Kendrick mass values of the mass spectrum.""" 620 self.check_mspeaks() 621 return array([mspeak.kendrick_mass for mspeak in self.mspeaks])
Return the Kendrick mass values of the mass spectrum.
623 @property 624 def max_mz_exp(self): 625 """Return the maximum experimental m/z value of the mass spectrum.""" 626 return max([mspeak.mz_exp for mspeak in self.mspeaks])
Return the maximum experimental m/z value of the mass spectrum.
628 @property 629 def min_mz_exp(self): 630 """Return the minimum experimental m/z value of the mass spectrum.""" 631 return min([mspeak.mz_exp for mspeak in self.mspeaks])
Return the minimum experimental m/z value of the mass spectrum.
633 @property 634 def max_abundance(self): 635 """Return the maximum abundance value of the mass spectrum.""" 636 return max([mspeak.abundance for mspeak in self.mspeaks])
Return the maximum abundance value of the mass spectrum.
638 @property 639 def max_signal_to_noise(self): 640 """Return the maximum signal-to-noise ratio of the mass spectrum.""" 641 return max([mspeak.signal_to_noise for mspeak in self.mspeaks])
Return the maximum signal-to-noise ratio of the mass spectrum.
643 @property 644 def most_abundant_mspeak(self): 645 """Return the most abundant MSpeak object of the mass spectrum.""" 646 return max(self.mspeaks, key=lambda m: m.abundance)
Return the most abundant MSpeak object of the mass spectrum.
648 @property 649 def min_abundance(self): 650 """Return the minimum abundance value of the mass spectrum.""" 651 return min([mspeak.abundance for mspeak in self.mspeaks])
Return the minimum abundance value of the mass spectrum.
654 @property 655 def dynamic_range(self): 656 """Return the dynamic range of the mass spectrum.""" 657 return self._dynamic_range
Return the dynamic range of the mass spectrum.
659 @property 660 def baseline_noise(self): 661 """Return the baseline noise of the mass spectrum.""" 662 if self._baseline_noise: 663 return self._baseline_noise 664 else: 665 return None
Return the baseline noise of the mass spectrum.
667 @property 668 def baseline_noise_std(self): 669 """Return the standard deviation of the baseline noise of the mass spectrum.""" 670 if self._baseline_noise_std == 0: 671 return self._baseline_noise_std 672 if self._baseline_noise_std: 673 return self._baseline_noise_std 674 else: 675 return None
Return the standard deviation of the baseline noise of the mass spectrum.
677 @property 678 def Aterm(self): 679 """Return the A-term calibration coefficient of the mass spectrum.""" 680 return self._calibration_terms[0]
Return the A-term calibration coefficient of the mass spectrum.
682 @property 683 def Bterm(self): 684 """Return the B-term calibration coefficient of the mass spectrum.""" 685 return self._calibration_terms[1]
Return the B-term calibration coefficient of the mass spectrum.
687 @property 688 def Cterm(self): 689 """Return the C-term calibration coefficient of the mass spectrum.""" 690 return self._calibration_terms[2]
Return the C-term calibration coefficient of the mass spectrum.
692 @property 693 def filename(self): 694 """Return the filename of the mass spectrum.""" 695 return Path(self._filename)
Return the filename of the mass spectrum.
697 @property 698 def dir_location(self): 699 """Return the directory location of the mass spectrum.""" 700 return self._dir_location
Return the directory location of the mass spectrum.
702 def sort_by_mz(self): 703 """Sort the mass spectrum by m/z values.""" 704 return sorted(self, key=lambda m: m.mz_exp)
Sort the mass spectrum by m/z values.
706 def sort_by_abundance(self, reverse=False): 707 """Sort the mass spectrum by abundance values.""" 708 return sorted(self, key=lambda m: m.abundance, reverse=reverse)
Sort the mass spectrum by abundance values.
710 @property 711 def tic(self): 712 """Return the total ion current of the mass spectrum.""" 713 return trapezoid(self.abundance_profile, self.mz_exp_profile)
Return the total ion current of the mass spectrum.
715 def check_mspeaks_warning(self): 716 """Check if the mass spectrum has MSpeaks objects. 717 718 Raises 719 ------ 720 Warning 721 If the mass spectrum has no MSpeaks objects. 722 """ 723 import warnings 724 725 if self.mspeaks: 726 pass 727 else: 728 warnings.warn("mspeaks list is empty, continuing without filtering data")
Check if the mass spectrum has MSpeaks objects.
Raises
- Warning: If the mass spectrum has no MSpeaks objects.
730 def check_mspeaks(self): 731 """Check if the mass spectrum has MSpeaks objects. 732 733 Raises 734 ------ 735 Exception 736 If the mass spectrum has no MSpeaks objects. 737 """ 738 if self.mspeaks: 739 pass 740 else: 741 raise Exception( 742 "mspeaks list is empty, please run process_mass_spec() first" 743 )
Check if the mass spectrum has MSpeaks objects.
Raises
- Exception: If the mass spectrum has no MSpeaks objects.
745 def remove_assignment_by_index(self, indexes): 746 """Remove the molecular formula assignment of the MSpeaks objects at the specified indexes. 747 748 Parameters 749 ---------- 750 indexes : list of int 751 A list of indexes of the MSpeaks objects to remove the molecular formula assignment from. 752 """ 753 for i in indexes: 754 self.mspeaks[i].clear_molecular_formulas()
Remove the molecular formula assignment of the MSpeaks objects at the specified indexes.
Parameters
- indexes (list of int): A list of indexes of the MSpeaks objects to remove the molecular formula assignment from.
756 def filter_by_index(self, list_indexes): 757 """Filter the mass spectrum by the specified indexes. 758 759 Parameters 760 ---------- 761 list_indexes : list of int 762 A list of indexes of the MSpeaks objects to drop. 763 764 """ 765 766 self.mspeaks = [ 767 self.mspeaks[i] for i in range(len(self.mspeaks)) if i not in list_indexes 768 ] 769 770 for i, mspeak in enumerate(self.mspeaks): 771 mspeak.index = i 772 773 self._set_nominal_masses_start_final_indexes()
Filter the mass spectrum by the specified indexes.
Parameters
- list_indexes (list of int): A list of indexes of the MSpeaks objects to drop.
775 def filter_by_mz(self, min_mz, max_mz): 776 """Filter the mass spectrum by the specified m/z range. 777 778 Parameters 779 ---------- 780 min_mz : float 781 The minimum m/z value to keep. 782 max_mz : float 783 The maximum m/z value to keep. 784 785 """ 786 self.check_mspeaks_warning() 787 indexes = [ 788 index 789 for index, mspeak in enumerate(self.mspeaks) 790 if not min_mz <= mspeak.mz_exp <= max_mz 791 ] 792 self.filter_by_index(indexes)
Filter the mass spectrum by the specified m/z range.
Parameters
- min_mz (float): The minimum m/z value to keep.
- max_mz (float): The maximum m/z value to keep.
794 def filter_by_s2n(self, min_s2n, max_s2n=False): 795 """Filter the mass spectrum by the specified signal-to-noise ratio range. 796 797 Parameters 798 ---------- 799 min_s2n : float 800 The minimum signal-to-noise ratio to keep. 801 max_s2n : float, optional 802 The maximum signal-to-noise ratio to keep. Defaults to False (no maximum). 803 804 """ 805 self.check_mspeaks_warning() 806 if max_s2n: 807 indexes = [ 808 index 809 for index, mspeak in enumerate(self.mspeaks) 810 if not min_s2n <= mspeak.signal_to_noise <= max_s2n 811 ] 812 else: 813 indexes = [ 814 index 815 for index, mspeak in enumerate(self.mspeaks) 816 if mspeak.signal_to_noise <= min_s2n 817 ] 818 self.filter_by_index(indexes)
Filter the mass spectrum by the specified signal-to-noise ratio range.
Parameters
- min_s2n (float): The minimum signal-to-noise ratio to keep.
- max_s2n (float, optional): The maximum signal-to-noise ratio to keep. Defaults to False (no maximum).
820 def filter_by_abundance(self, min_abund, max_abund=False): 821 """Filter the mass spectrum by the specified abundance range. 822 823 Parameters 824 ---------- 825 min_abund : float 826 The minimum abundance to keep. 827 max_abund : float, optional 828 The maximum abundance to keep. Defaults to False (no maximum). 829 830 """ 831 self.check_mspeaks_warning() 832 if max_abund: 833 indexes = [ 834 index 835 for index, mspeak in enumerate(self.mspeaks) 836 if not min_abund <= mspeak.abundance <= max_abund 837 ] 838 else: 839 indexes = [ 840 index 841 for index, mspeak in enumerate(self.mspeaks) 842 if mspeak.abundance <= min_abund 843 ] 844 self.filter_by_index(indexes)
Filter the mass spectrum by the specified abundance range.
Parameters
- min_abund (float): The minimum abundance to keep.
- max_abund (float, optional): The maximum abundance to keep. Defaults to False (no maximum).
846 def filter_by_max_resolving_power(self, B, T): 847 """Filter the mass spectrum by the specified maximum resolving power. 848 849 Parameters 850 ---------- 851 B : float 852 T : float 853 854 """ 855 856 rpe = lambda m, z: (1.274e7 * z * B * T) / (m * z) 857 858 self.check_mspeaks_warning() 859 860 indexes_to_remove = [ 861 index 862 for index, mspeak in enumerate(self.mspeaks) 863 if mspeak.resolving_power >= rpe(mspeak.mz_exp, mspeak.polarity) 864 ] 865 self.filter_by_index(indexes_to_remove)
Filter the mass spectrum by the specified maximum resolving power.
Parameters
B (float):
T (float):
867 def filter_by_mean_resolving_power( 868 self, ndeviations=3, plot=False, guess_pars=False 869 ): 870 """Filter the mass spectrum by the specified mean resolving power. 871 872 Parameters 873 ---------- 874 ndeviations : float, optional 875 The number of standard deviations to use for filtering. Defaults to 3. 876 plot : bool, optional 877 Whether to plot the resolving power distribution. Defaults to False. 878 guess_pars : bool, optional 879 Whether to guess the parameters for the Gaussian model. Defaults to False. 880 881 """ 882 self.check_mspeaks_warning() 883 indexes_to_remove = MeanResolvingPowerFilter( 884 self, ndeviations, plot, guess_pars 885 ).main() 886 self.filter_by_index(indexes_to_remove)
Filter the mass spectrum by the specified mean resolving power.
Parameters
- ndeviations (float, optional): The number of standard deviations to use for filtering. Defaults to 3.
- plot (bool, optional): Whether to plot the resolving power distribution. Defaults to False.
- guess_pars (bool, optional): Whether to guess the parameters for the Gaussian model. Defaults to False.
888 def filter_by_min_resolving_power( 889 self, B, T, apodization_method: str = None, tolerance: float = 0 890 ): 891 """Filter the mass spectrum by the calculated minimum theoretical resolving power. 892 893 This is currently designed only for FTICR data, and accounts only for magnitude mode data 894 Accurate results require passing the apodisaion method used to calculate the resolving power. 895 see the ICRMassPeak function `resolving_power_calc` for more details. 896 897 Parameters 898 ---------- 899 B : Magnetic field strength in Tesla, float 900 T : transient length in seconds, float 901 apodization_method : str, optional 902 The apodization method to use for calculating the resolving power. Defaults to None. 903 tolerance : float, optional 904 The tolerance for the threshold. Defaults to 0, i.e. no tolerance 905 906 """ 907 if self.analyzer != "ICR": 908 raise Exception("This method is only applicable to ICR mass spectra. ") 909 910 self.check_mspeaks_warning() 911 912 indexes_to_remove = [ 913 index 914 for index, mspeak in enumerate(self.mspeaks) 915 if mspeak.resolving_power 916 < (1 - tolerance) 917 * mspeak.resolving_power_calc(B, T, apodization_method=apodization_method) 918 ] 919 self.filter_by_index(indexes_to_remove)
Filter the mass spectrum by the calculated minimum theoretical resolving power.
This is currently designed only for FTICR data, and accounts only for magnitude mode data
Accurate results require passing the apodisaion method used to calculate the resolving power.
see the ICRMassPeak function resolving_power_calc for more details.
Parameters
B (Magnetic field strength in Tesla, float):
T (transient length in seconds, float):
apodization_method (str, optional): The apodization method to use for calculating the resolving power. Defaults to None.
- tolerance (float, optional): The tolerance for the threshold. Defaults to 0, i.e. no tolerance
921 def filter_by_noise_threshold(self): 922 """Filter the mass spectrum by the noise threshold.""" 923 924 threshold = self.get_noise_threshold()[1][0] 925 926 self.check_mspeaks_warning() 927 928 indexes_to_remove = [ 929 index 930 for index, mspeak in enumerate(self.mspeaks) 931 if mspeak.abundance <= threshold 932 ] 933 self.filter_by_index(indexes_to_remove)
Filter the mass spectrum by the noise threshold.
935 def find_peaks(self): 936 """Find the peaks of the mass spectrum.""" 937 # needs to clear previous results from peak_picking 938 self._mspeaks = list() 939 940 # then do peak picking 941 self.do_peak_picking() 942 # print("A total of %i peaks were found" % len(self._mspeaks))
Find the peaks of the mass spectrum.
944 def change_kendrick_base_all_mspeaks(self, kendrick_dict_base): 945 """Change the Kendrick base of all MSpeaks objects. 946 947 Parameters 948 ---------- 949 kendrick_dict_base : dict 950 A dictionary of the Kendrick base to change to. 951 952 Notes 953 ----- 954 Example of kendrick_dict_base parameter: kendrick_dict_base = {"C": 1, "H": 2} or {"C": 1, "H": 1, "O":1} etc 955 """ 956 self.parameters.ms_peak.kendrick_base = kendrick_dict_base 957 958 for mspeak in self.mspeaks: 959 mspeak.change_kendrick_base(kendrick_dict_base)
Change the Kendrick base of all MSpeaks objects.
Parameters
- kendrick_dict_base (dict): A dictionary of the Kendrick base to change to.
Notes
Example of kendrick_dict_base parameter: kendrick_dict_base = {"C": 1, "H": 2} or {"C": 1, "H": 1, "O":1} etc
961 def get_nominal_mz_first_last_indexes(self, nominal_mass): 962 """Return the first and last indexes of the MSpeaks objects with the specified nominal mass. 963 964 Parameters 965 ---------- 966 nominal_mass : int 967 The nominal mass to get the indexes for. 968 969 Returns 970 ------- 971 tuple 972 A tuple containing the first and last indexes of the MSpeaks objects with the specified nominal mass. 973 """ 974 if self._dict_nominal_masses_indexes: 975 if nominal_mass in self._dict_nominal_masses_indexes.keys(): 976 return ( 977 self._dict_nominal_masses_indexes.get(nominal_mass)[0], 978 self._dict_nominal_masses_indexes.get(nominal_mass)[1] + 1, 979 ) 980 981 else: 982 # import warnings 983 # uncomment warn to distribution 984 # warnings.warn("Nominal mass not found in _dict_nominal_masses_indexes, returning (0, 0) for nominal mass %i"%nominal_mass) 985 return (0, 0) 986 else: 987 raise Exception( 988 "run process_mass_spec() function before trying to access the data" 989 )
Return the first and last indexes of the MSpeaks objects with the specified nominal mass.
Parameters
- nominal_mass (int): The nominal mass to get the indexes for.
Returns
- tuple: A tuple containing the first and last indexes of the MSpeaks objects with the specified nominal mass.
991 def get_masses_count_by_nominal_mass(self): 992 """Return a dictionary of the nominal masses and their counts.""" 993 994 dict_nominal_masses_count = {} 995 996 all_nominal_masses = list(set([i.nominal_mz_exp for i in self.mspeaks])) 997 998 for nominal_mass in all_nominal_masses: 999 if nominal_mass not in dict_nominal_masses_count: 1000 dict_nominal_masses_count[nominal_mass] = len( 1001 list(self.get_nominal_mass_indexes(nominal_mass)) 1002 ) 1003 1004 return dict_nominal_masses_count
Return a dictionary of the nominal masses and their counts.
1006 def datapoints_count_by_nominal_mz(self, mz_overlay=0.1): 1007 """Return a dictionary of the nominal masses and their counts. 1008 1009 Parameters 1010 ---------- 1011 mz_overlay : float, optional 1012 The m/z overlay to use for counting. Defaults to 0.1. 1013 1014 Returns 1015 ------- 1016 dict 1017 A dictionary of the nominal masses and their counts. 1018 """ 1019 dict_nominal_masses_count = {} 1020 1021 all_nominal_masses = list(set([i.nominal_mz_exp for i in self.mspeaks])) 1022 1023 for nominal_mass in all_nominal_masses: 1024 if nominal_mass not in dict_nominal_masses_count: 1025 min_mz = nominal_mass - mz_overlay 1026 1027 max_mz = nominal_mass + 1 + mz_overlay 1028 1029 indexes = indexes = where( 1030 (self.mz_exp_profile > min_mz) & (self.mz_exp_profile < max_mz) 1031 ) 1032 1033 dict_nominal_masses_count[nominal_mass] = indexes[0].size 1034 1035 return dict_nominal_masses_count
Return a dictionary of the nominal masses and their counts.
Parameters
- mz_overlay (float, optional): The m/z overlay to use for counting. Defaults to 0.1.
Returns
- dict: A dictionary of the nominal masses and their counts.
1037 def get_nominal_mass_indexes(self, nominal_mass, overlay=0.1): 1038 """Return the indexes of the MSpeaks objects with the specified nominal mass. 1039 1040 Parameters 1041 ---------- 1042 nominal_mass : int 1043 The nominal mass to get the indexes for. 1044 overlay : float, optional 1045 The m/z overlay to use for counting. Defaults to 0.1. 1046 1047 Returns 1048 ------- 1049 generator 1050 A generator of the indexes of the MSpeaks objects with the specified nominal mass. 1051 """ 1052 min_mz_to_look = nominal_mass - overlay 1053 max_mz_to_look = nominal_mass + 1 + overlay 1054 1055 return ( 1056 i 1057 for i in range(len(self.mspeaks)) 1058 if min_mz_to_look <= self.mspeaks[i].mz_exp <= max_mz_to_look 1059 ) 1060 1061 # indexes = (i for i in range(len(self.mspeaks)) if min_mz_to_look <= self.mspeaks[i].mz_exp <= max_mz_to_look) 1062 # return indexes
Return the indexes of the MSpeaks objects with the specified nominal mass.
Parameters
- nominal_mass (int): The nominal mass to get the indexes for.
- overlay (float, optional): The m/z overlay to use for counting. Defaults to 0.1.
Returns
- generator: A generator of the indexes of the MSpeaks objects with the specified nominal mass.
1089 def plot_centroid(self, ax=None, c="g"): 1090 """Plot the centroid data of the mass spectrum. 1091 1092 Parameters 1093 ---------- 1094 ax : matplotlib.axes.Axes, optional 1095 The matplotlib axes to plot on. Defaults to None. 1096 c : str, optional 1097 The color to use for the plot. Defaults to 'g' (green). 1098 1099 Returns 1100 ------- 1101 matplotlib.axes.Axes 1102 The matplotlib axes containing the plot. 1103 1104 Raises 1105 ------ 1106 Exception 1107 If no centroid data is found. 1108 """ 1109 1110 import matplotlib.pyplot as plt 1111 1112 if self._mspeaks: 1113 if ax is None: 1114 ax = plt.gca() 1115 1116 markerline_a, stemlines_a, baseline_a = ax.stem( 1117 self.mz_exp, self.abundance, linefmt="-", markerfmt=" " 1118 ) 1119 1120 plt.setp(markerline_a, "color", c, "linewidth", 2) 1121 plt.setp(stemlines_a, "color", c, "linewidth", 2) 1122 plt.setp(baseline_a, "color", c, "linewidth", 2) 1123 1124 ax.set_xlabel("$\t{m/z}$", fontsize=12) 1125 ax.set_ylabel("Abundance", fontsize=12) 1126 ax.tick_params(axis="both", which="major", labelsize=12) 1127 1128 ax.axes.spines["top"].set_visible(False) 1129 ax.axes.spines["right"].set_visible(False) 1130 1131 ax.get_yaxis().set_visible(False) 1132 ax.spines["left"].set_visible(False) 1133 1134 else: 1135 raise Exception("No centroid data found, please run process_mass_spec") 1136 1137 return ax
Plot the centroid data of the mass spectrum.
Parameters
- ax (matplotlib.axes.Axes, optional): The matplotlib axes to plot on. Defaults to None.
- c (str, optional): The color to use for the plot. Defaults to 'g' (green).
Returns
- matplotlib.axes.Axes: The matplotlib axes containing the plot.
Raises
- Exception: If no centroid data is found.
1139 def plot_profile_and_noise_threshold(self, ax=None, legend=False): 1140 """Plot the profile data and noise threshold of the mass spectrum. 1141 1142 Parameters 1143 ---------- 1144 ax : matplotlib.axes.Axes, optional 1145 The matplotlib axes to plot on. Defaults to None. 1146 legend : bool, optional 1147 Whether to show the legend. Defaults to False. 1148 1149 Returns 1150 ------- 1151 matplotlib.axes.Axes 1152 The matplotlib axes containing the plot. 1153 1154 Raises 1155 ------ 1156 Exception 1157 If no noise threshold is found. 1158 """ 1159 import matplotlib.pyplot as plt 1160 1161 if self.baseline_noise_std and self.baseline_noise_std: 1162 # x = (self.mz_exp_profile.min(), self.mz_exp_profile.max()) 1163 baseline = (self.baseline_noise, self.baseline_noise) 1164 1165 # std = self.parameters.mass_spectrum.noise_threshold_min_std 1166 # threshold = self.baseline_noise_std + (std * self.baseline_noise_std) 1167 x, y = self.get_noise_threshold() 1168 1169 if ax is None: 1170 ax = plt.gca() 1171 1172 ax.plot( 1173 self.mz_exp_profile, 1174 self.abundance_profile, 1175 color="green", 1176 label="Spectrum", 1177 ) 1178 ax.plot(x, (baseline, baseline), color="yellow", label="Baseline Noise") 1179 ax.plot(x, y, color="red", label="Noise Threshold") 1180 1181 ax.set_xlabel("$\t{m/z}$", fontsize=12) 1182 ax.set_ylabel("Abundance", fontsize=12) 1183 ax.tick_params(axis="both", which="major", labelsize=12) 1184 1185 ax.axes.spines["top"].set_visible(False) 1186 ax.axes.spines["right"].set_visible(False) 1187 1188 ax.get_yaxis().set_visible(False) 1189 ax.spines["left"].set_visible(False) 1190 if legend: 1191 ax.legend() 1192 1193 else: 1194 raise Exception("Calculate noise threshold first") 1195 1196 return ax
Plot the profile data and noise threshold of the mass spectrum.
Parameters
- ax (matplotlib.axes.Axes, optional): The matplotlib axes to plot on. Defaults to None.
- legend (bool, optional): Whether to show the legend. Defaults to False.
Returns
- matplotlib.axes.Axes: The matplotlib axes containing the plot.
Raises
- Exception: If no noise threshold is found.
1198 def plot_mz_domain_profile(self, color="green", ax=None): 1199 """Plot the m/z domain profile of the mass spectrum. 1200 1201 Parameters 1202 ---------- 1203 color : str, optional 1204 The color to use for the plot. Defaults to 'green'. 1205 ax : matplotlib.axes.Axes, optional 1206 The matplotlib axes to plot on. Defaults to None. 1207 1208 Returns 1209 ------- 1210 matplotlib.axes.Axes 1211 The matplotlib axes containing the plot. 1212 """ 1213 1214 import matplotlib.pyplot as plt 1215 1216 if ax is None: 1217 ax = plt.gca() 1218 ax.plot(self.mz_exp_profile, self.abundance_profile, color=color) 1219 ax.set(xlabel="m/z", ylabel="abundance") 1220 1221 return ax
Plot the m/z domain profile of the mass spectrum.
Parameters
- color (str, optional): The color to use for the plot. Defaults to 'green'.
- ax (matplotlib.axes.Axes, optional): The matplotlib axes to plot on. Defaults to None.
Returns
- matplotlib.axes.Axes: The matplotlib axes containing the plot.
1223 def to_excel(self, out_file_path, write_metadata=True): 1224 """Export the mass spectrum to an Excel file. 1225 1226 Parameters 1227 ---------- 1228 out_file_path : str 1229 The path to the Excel file to export to. 1230 write_metadata : bool, optional 1231 Whether to write the metadata to the Excel file. Defaults to True. 1232 1233 Returns 1234 ------- 1235 None 1236 """ 1237 from corems.mass_spectrum.output.export import HighResMassSpecExport 1238 1239 exportMS = HighResMassSpecExport(out_file_path, self) 1240 exportMS.to_excel(write_metadata=write_metadata)
Export the mass spectrum to an Excel file.
Parameters
- out_file_path (str): The path to the Excel file to export to.
- write_metadata (bool, optional): Whether to write the metadata to the Excel file. Defaults to True.
Returns
- None
1242 def to_hdf(self, out_file_path): 1243 """Export the mass spectrum to an HDF file. 1244 1245 Parameters 1246 ---------- 1247 out_file_path : str 1248 The path to the HDF file to export to. 1249 1250 Returns 1251 ------- 1252 None 1253 """ 1254 from corems.mass_spectrum.output.export import HighResMassSpecExport 1255 1256 exportMS = HighResMassSpecExport(out_file_path, self) 1257 exportMS.to_hdf()
Export the mass spectrum to an HDF file.
Parameters
- out_file_path (str): The path to the HDF file to export to.
Returns
- None
1259 def to_csv(self, out_file_path, write_metadata=True): 1260 """Export the mass spectrum to a CSV file. 1261 1262 Parameters 1263 ---------- 1264 out_file_path : str 1265 The path to the CSV file to export to. 1266 write_metadata : bool, optional 1267 Whether to write the metadata to the CSV file. Defaults to True. 1268 1269 """ 1270 from corems.mass_spectrum.output.export import HighResMassSpecExport 1271 1272 exportMS = HighResMassSpecExport(out_file_path, self) 1273 exportMS.to_csv(write_metadata=write_metadata)
Export the mass spectrum to a CSV file.
Parameters
- out_file_path (str): The path to the CSV file to export to.
- write_metadata (bool, optional): Whether to write the metadata to the CSV file. Defaults to True.
1275 def to_pandas(self, out_file_path, write_metadata=True): 1276 """Export the mass spectrum to a Pandas dataframe with pkl extension. 1277 1278 Parameters 1279 ---------- 1280 out_file_path : str 1281 The path to the CSV file to export to. 1282 write_metadata : bool, optional 1283 Whether to write the metadata to the CSV file. Defaults to True. 1284 1285 """ 1286 from corems.mass_spectrum.output.export import HighResMassSpecExport 1287 1288 exportMS = HighResMassSpecExport(out_file_path, self) 1289 exportMS.to_pandas(write_metadata=write_metadata)
Export the mass spectrum to a Pandas dataframe with pkl extension.
Parameters
- out_file_path (str): The path to the CSV file to export to.
- write_metadata (bool, optional): Whether to write the metadata to the CSV file. Defaults to True.
1291 def to_parquet(self, out_file_path, write_metadata=True): 1292 """Export the mass spectrum to a Parquet file. 1293 1294 Parameters 1295 ---------- 1296 out_file_path : str 1297 The path to the Parquet file to export to. 1298 write_metadata : bool, optional 1299 Whether to write the metadata to a JSON file. Defaults to True. 1300 1301 Notes 1302 ----- 1303 Requires ``pyarrow`` (or ``fastparquet``) for pandas Parquet I/O. 1304 """ 1305 from corems.mass_spectrum.output.export import HighResMassSpecExport 1306 1307 exportMS = HighResMassSpecExport(out_file_path, self) 1308 exportMS.to_parquet(write_metadata=write_metadata)
Export the mass spectrum to a Parquet file.
Parameters
- out_file_path (str): The path to the Parquet file to export to.
- write_metadata (bool, optional): Whether to write the metadata to a JSON file. Defaults to True.
Notes
Requires pyarrow (or fastparquet) for pandas Parquet I/O.
1310 def to_dataframe(self, additional_columns=None): 1311 """Return the mass spectrum as a Pandas dataframe. 1312 1313 Parameters 1314 ---------- 1315 additional_columns : list, optional 1316 A list of additional columns to include in the dataframe. Defaults to None. 1317 Suitable columns are: "Aromaticity Index", "Aromaticity Index (modified)", and "NOSC" 1318 1319 Returns 1320 ------- 1321 pandas.DataFrame 1322 The mass spectrum as a Pandas dataframe. 1323 """ 1324 from corems.mass_spectrum.output.export import HighResMassSpecExport 1325 1326 exportMS = HighResMassSpecExport(self.filename, self) 1327 return exportMS.get_pandas_df(additional_columns=additional_columns)
Return the mass spectrum as a Pandas dataframe.
Parameters
- additional_columns (list, optional): A list of additional columns to include in the dataframe. Defaults to None. Suitable columns are: "Aromaticity Index", "Aromaticity Index (modified)", and "NOSC"
Returns
- pandas.DataFrame: The mass spectrum as a Pandas dataframe.
1329 def to_json(self): 1330 """Return the mass spectrum as a JSON file.""" 1331 from corems.mass_spectrum.output.export import HighResMassSpecExport 1332 1333 exportMS = HighResMassSpecExport(self.filename, self) 1334 return exportMS.to_json()
Return the mass spectrum as a JSON file.
1336 def parameters_json(self): 1337 """Return the parameters of the mass spectrum as a JSON string.""" 1338 from corems.mass_spectrum.output.export import HighResMassSpecExport 1339 1340 exportMS = HighResMassSpecExport(self.filename, self) 1341 return exportMS.parameters_to_json()
Return the parameters of the mass spectrum as a JSON string.
1343 def parameters_toml(self): 1344 """Return the parameters of the mass spectrum as a TOML string.""" 1345 from corems.mass_spectrum.output.export import HighResMassSpecExport 1346 1347 exportMS = HighResMassSpecExport(self.filename, self) 1348 return exportMS.parameters_to_toml()
Return the parameters of the mass spectrum as a TOML string.
Inherited Members
- corems.mass_spectrum.calc.MassSpectrumCalc.MassSpecCalc
- percentage_assigned
- percentile_assigned
- resolving_power_calc
- number_average_molecular_weight
- weight_average_molecular_weight
- corems.mass_spectrum.calc.PeakPicking.PeakPicking
- prepare_peak_picking_data
- cut_mz_domain_peak_picking
- legacy_cut_mz_domain_peak_picking
- extrapolate_axis
- extrapolate_axes_for_pp
- do_peak_picking
- find_minima
- linear_fit_calc
- calculate_resolving_power
- cal_minima
- calc_centroid
- get_threshold
- algebraic_quadratic
- find_apex_fit_quadratic
- check_prominence
- use_the_max
- calc_centroid_legacy
1351class MassSpecProfile(MassSpecBase): 1352 """A mass spectrum class when the entry point is on profile format 1353 1354 Notes 1355 ----- 1356 Stores the profile data and instrument settings. 1357 Iteration over a list of MSPeaks classes stored at the _mspeaks attributes. 1358 _mspeaks is populated under the hood by calling process_mass_spec method. 1359 Iteration is null if _mspeaks is empty. Many more attributes and methods inherited from MassSpecBase(). 1360 1361 Parameters 1362 ---------- 1363 data_dict : dict 1364 A dictionary containing the profile data. 1365 d_params : dict{'str': float, int or str} 1366 contains the instrument settings and processing settings 1367 auto_process : bool, optional 1368 Whether to automatically process the mass spectrum. Defaults to True. 1369 1370 1371 Attributes 1372 ---------- 1373 _abundance : ndarray 1374 The abundance values of the mass spectrum. 1375 _mz_exp : ndarray 1376 The m/z values of the mass spectrum. 1377 _mspeaks : list 1378 A list of mass peaks. 1379 1380 Methods 1381 ---------- 1382 * process_mass_spec(). Process the mass spectrum. 1383 1384 see also: MassSpecBase(), MassSpecfromFreq(), MassSpecCentroid() 1385 """ 1386 1387 def __init__(self, data_dict, d_params, auto_process=True): 1388 # print(data_dict.keys()) 1389 super().__init__( 1390 data_dict.get(Labels.mz), data_dict.get(Labels.abundance), d_params 1391 ) 1392 1393 if auto_process: 1394 self.process_mass_spec()
A mass spectrum class when the entry point is on profile format
Notes
Stores the profile data and instrument settings. Iteration over a list of MSPeaks classes stored at the _mspeaks attributes. _mspeaks is populated under the hood by calling process_mass_spec method. Iteration is null if _mspeaks is empty. Many more attributes and methods inherited from MassSpecBase().
Parameters
- data_dict (dict): A dictionary containing the profile data.
- d_params : dict{'str' (float, int or str}): contains the instrument settings and processing settings
- auto_process (bool, optional): Whether to automatically process the mass spectrum. Defaults to True.
Attributes
- _abundance (ndarray): The abundance values of the mass spectrum.
- _mz_exp (ndarray): The m/z values of the mass spectrum.
- _mspeaks (list): A list of mass peaks.
Methods
- process_mass_spec(). Process the mass spectrum.
see also: MassSpecBase(), MassSpecfromFreq(), MassSpecCentroid()
Inherited Members
- MassSpecBase
- mspeaks
- is_calibrated
- is_centroid
- has_frequency
- calibration_order
- calibration_points
- calibration_ref_mzs
- calibration_meas_mzs
- calibration_RMS
- calibration_segment
- calibration_raw_error_median
- calibration_raw_error_stdev
- set_indexes
- reset_indexes
- add_mspeak
- reset_cal_therms
- clear_molecular_formulas
- process_mass_spec
- cal_noise_threshold
- parameters
- set_parameter_from_json
- set_parameter_from_toml
- mspeaks_settings
- settings
- molecular_search_settings
- mz_cal_profile
- mz_cal
- mz_exp
- freq_exp_profile
- freq_exp_pp
- mz_exp_profile
- mz_exp_pp
- abundance_profile
- abundance_profile_pp
- abundance
- freq_exp
- resolving_power
- signal_to_noise
- nominal_mz
- get_mz_and_abundance_peaks_tuples
- kmd
- kendrick_mass
- max_mz_exp
- min_mz_exp
- max_abundance
- max_signal_to_noise
- most_abundant_mspeak
- min_abundance
- dynamic_range
- baseline_noise
- baseline_noise_std
- Aterm
- Bterm
- Cterm
- filename
- dir_location
- sort_by_mz
- sort_by_abundance
- tic
- check_mspeaks_warning
- check_mspeaks
- remove_assignment_by_index
- filter_by_index
- filter_by_mz
- filter_by_s2n
- filter_by_abundance
- filter_by_max_resolving_power
- filter_by_mean_resolving_power
- filter_by_min_resolving_power
- filter_by_noise_threshold
- find_peaks
- change_kendrick_base_all_mspeaks
- get_nominal_mz_first_last_indexes
- get_masses_count_by_nominal_mass
- datapoints_count_by_nominal_mz
- get_nominal_mass_indexes
- plot_centroid
- plot_profile_and_noise_threshold
- plot_mz_domain_profile
- to_excel
- to_hdf
- to_csv
- to_pandas
- to_parquet
- to_dataframe
- to_json
- parameters_json
- parameters_toml
- corems.mass_spectrum.calc.MassSpectrumCalc.MassSpecCalc
- percentage_assigned
- percentile_assigned
- resolving_power_calc
- number_average_molecular_weight
- weight_average_molecular_weight
- corems.mass_spectrum.calc.PeakPicking.PeakPicking
- prepare_peak_picking_data
- cut_mz_domain_peak_picking
- legacy_cut_mz_domain_peak_picking
- extrapolate_axis
- extrapolate_axes_for_pp
- do_peak_picking
- find_minima
- linear_fit_calc
- calculate_resolving_power
- cal_minima
- calc_centroid
- get_threshold
- algebraic_quadratic
- find_apex_fit_quadratic
- check_prominence
- use_the_max
- calc_centroid_legacy
1397class MassSpecfromFreq(MassSpecBase): 1398 """A mass spectrum class when data entry is on frequency domain 1399 1400 Notes 1401 ----- 1402 - Transform to m/z based on the settings stored at d_params 1403 - Stores the profile data and instrument settings 1404 - Iteration over a list of MSPeaks classes stored at the _mspeaks attributes 1405 - _mspeaks is populated under the hood by calling process_mass_spec method 1406 - iteration is null if _mspeaks is empty 1407 1408 Parameters 1409 ---------- 1410 frequency_domain : list(float) 1411 all datapoints in frequency domain in Hz 1412 magnitude : frequency_domain : list(float) 1413 all datapoints in for magnitude of each frequency datapoint 1414 d_params : dict{'str': float, int or str} 1415 contains the instrument settings and processing settings 1416 auto_process : bool, optional 1417 Whether to automatically process the mass spectrum. Defaults to True. 1418 keep_profile : bool, optional 1419 Whether to keep the profile data. Defaults to True. 1420 1421 Attributes 1422 ---------- 1423 has_frequency : bool 1424 Whether the mass spectrum has frequency data. 1425 _frequency_domain : list(float) 1426 Frequency domain in Hz 1427 label : str 1428 store label (Bruker, Midas Transient, see Labels class ). It across distinct processing points 1429 _abundance : ndarray 1430 The abundance values of the mass spectrum. 1431 _mz_exp : ndarray 1432 The m/z values of the mass spectrum. 1433 _mspeaks : list 1434 A list of mass peaks. 1435 See Also: all the attributes of MassSpecBase class 1436 1437 Methods 1438 ---------- 1439 * _set_mz_domain(). 1440 calculates the m_z based on the setting of d_params 1441 * process_mass_spec(). Process the mass spectrum. 1442 1443 see also: MassSpecBase(), MassSpecProfile(), MassSpecCentroid() 1444 """ 1445 1446 def __init__( 1447 self, 1448 frequency_domain, 1449 magnitude, 1450 d_params, 1451 auto_process=True, 1452 keep_profile=True, 1453 ): 1454 super().__init__(None, magnitude, d_params) 1455 1456 self._frequency_domain = frequency_domain 1457 self.has_frequency = True 1458 self._set_mz_domain() 1459 self._sort_mz_domain() 1460 1461 self.magnetron_frequency = None 1462 self.magnetron_frequency_sigma = None 1463 1464 # use this call to automatically process data as the object is created, Setting need to be changed before initiating the class to be in effect 1465 1466 if auto_process: 1467 self.process_mass_spec(keep_profile=keep_profile) 1468 1469 def _sort_mz_domain(self): 1470 """Sort the mass spectrum by m/z values.""" 1471 1472 if self._mz_exp[0] > self._mz_exp[-1]: 1473 self._mz_exp = self._mz_exp[::-1] 1474 self._abundance = self._abundance[::-1] 1475 self._frequency_domain = self._frequency_domain[::-1] 1476 1477 def _set_mz_domain(self): 1478 """Set the m/z domain of the mass spectrum based on the settings of d_params.""" 1479 if self.label == Labels.bruker_frequency: 1480 self._mz_exp = self._f_to_mz_bruker() 1481 1482 else: 1483 self._mz_exp = self._f_to_mz() 1484 1485 @property 1486 def transient_settings(self): 1487 """Return the transient settings of the mass spectrum.""" 1488 return self.parameters.transient 1489 1490 @transient_settings.setter 1491 def transient_settings(self, instance_TransientSetting): 1492 self.parameters.transient = instance_TransientSetting 1493 1494 def calc_magnetron_freq(self, max_magnetron_freq=50, magnetron_freq_bins=300): 1495 """Calculates the magnetron frequency of the mass spectrum. 1496 1497 Parameters 1498 ---------- 1499 max_magnetron_freq : float, optional 1500 The maximum magnetron frequency. Defaults to 50. 1501 magnetron_freq_bins : int, optional 1502 The number of bins to use for the histogram. Defaults to 300. 1503 1504 Returns 1505 ------- 1506 None 1507 1508 Notes 1509 ----- 1510 Calculates the magnetron frequency by examining all the picked peaks and the distances between them in the frequency domain. 1511 A histogram of those values below the threshold 'max_magnetron_freq' with the 'magnetron_freq_bins' number of bins is calculated. 1512 A gaussian model is fit to this histogram - the center value of this (statistically probably) the magnetron frequency. 1513 This appears to work well or nOmega datasets, but may not work well for 1x datasets or those with very low magnetron peaks. 1514 """ 1515 ms_df = DataFrame(self.freq_exp(), columns=["Freq"]) 1516 ms_df["FreqDelta"] = ms_df["Freq"].diff() 1517 1518 freq_hist = histogram( 1519 ms_df[ms_df["FreqDelta"] < max_magnetron_freq]["FreqDelta"], 1520 bins=magnetron_freq_bins, 1521 ) 1522 1523 mod = GaussianModel() 1524 pars = mod.guess(freq_hist[0], x=freq_hist[1][:-1]) 1525 out = mod.fit(freq_hist[0], pars, x=freq_hist[1][:-1]) 1526 self.magnetron_frequency = out.best_values["center"] 1527 self.magnetron_frequency_sigma = out.best_values["sigma"]
A mass spectrum class when data entry is on frequency domain
Notes
- Transform to m/z based on the settings stored at d_params
- Stores the profile data and instrument settings
- Iteration over a list of MSPeaks classes stored at the _mspeaks attributes
- _mspeaks is populated under the hood by calling process_mass_spec method
- iteration is null if _mspeaks is empty
Parameters
- frequency_domain (list(float)): all datapoints in frequency domain in Hz
- magnitude : frequency_domain (list(float)): all datapoints in for magnitude of each frequency datapoint
- d_params : dict{'str' (float, int or str}): contains the instrument settings and processing settings
- auto_process (bool, optional): Whether to automatically process the mass spectrum. Defaults to True.
- keep_profile (bool, optional): Whether to keep the profile data. Defaults to True.
Attributes
- has_frequency (bool): Whether the mass spectrum has frequency data.
- _frequency_domain (list(float)): Frequency domain in Hz
- label (str): store label (Bruker, Midas Transient, see Labels class ). It across distinct processing points
- _abundance (ndarray): The abundance values of the mass spectrum.
- _mz_exp (ndarray): The m/z values of the mass spectrum.
- _mspeaks (list): A list of mass peaks.
- See Also (all the attributes of MassSpecBase class):
Methods
- _set_mz_domain(). calculates the m_z based on the setting of d_params
- process_mass_spec(). Process the mass spectrum.
see also: MassSpecBase(), MassSpecProfile(), MassSpecCentroid()
1446 def __init__( 1447 self, 1448 frequency_domain, 1449 magnitude, 1450 d_params, 1451 auto_process=True, 1452 keep_profile=True, 1453 ): 1454 super().__init__(None, magnitude, d_params) 1455 1456 self._frequency_domain = frequency_domain 1457 self.has_frequency = True 1458 self._set_mz_domain() 1459 self._sort_mz_domain() 1460 1461 self.magnetron_frequency = None 1462 self.magnetron_frequency_sigma = None 1463 1464 # use this call to automatically process data as the object is created, Setting need to be changed before initiating the class to be in effect 1465 1466 if auto_process: 1467 self.process_mass_spec(keep_profile=keep_profile)
1485 @property 1486 def transient_settings(self): 1487 """Return the transient settings of the mass spectrum.""" 1488 return self.parameters.transient
Return the transient settings of the mass spectrum.
1494 def calc_magnetron_freq(self, max_magnetron_freq=50, magnetron_freq_bins=300): 1495 """Calculates the magnetron frequency of the mass spectrum. 1496 1497 Parameters 1498 ---------- 1499 max_magnetron_freq : float, optional 1500 The maximum magnetron frequency. Defaults to 50. 1501 magnetron_freq_bins : int, optional 1502 The number of bins to use for the histogram. Defaults to 300. 1503 1504 Returns 1505 ------- 1506 None 1507 1508 Notes 1509 ----- 1510 Calculates the magnetron frequency by examining all the picked peaks and the distances between them in the frequency domain. 1511 A histogram of those values below the threshold 'max_magnetron_freq' with the 'magnetron_freq_bins' number of bins is calculated. 1512 A gaussian model is fit to this histogram - the center value of this (statistically probably) the magnetron frequency. 1513 This appears to work well or nOmega datasets, but may not work well for 1x datasets or those with very low magnetron peaks. 1514 """ 1515 ms_df = DataFrame(self.freq_exp(), columns=["Freq"]) 1516 ms_df["FreqDelta"] = ms_df["Freq"].diff() 1517 1518 freq_hist = histogram( 1519 ms_df[ms_df["FreqDelta"] < max_magnetron_freq]["FreqDelta"], 1520 bins=magnetron_freq_bins, 1521 ) 1522 1523 mod = GaussianModel() 1524 pars = mod.guess(freq_hist[0], x=freq_hist[1][:-1]) 1525 out = mod.fit(freq_hist[0], pars, x=freq_hist[1][:-1]) 1526 self.magnetron_frequency = out.best_values["center"] 1527 self.magnetron_frequency_sigma = out.best_values["sigma"]
Calculates the magnetron frequency of the mass spectrum.
Parameters
- max_magnetron_freq (float, optional): The maximum magnetron frequency. Defaults to 50.
- magnetron_freq_bins (int, optional): The number of bins to use for the histogram. Defaults to 300.
Returns
- None
Notes
Calculates the magnetron frequency by examining all the picked peaks and the distances between them in the frequency domain. A histogram of those values below the threshold 'max_magnetron_freq' with the 'magnetron_freq_bins' number of bins is calculated. A gaussian model is fit to this histogram - the center value of this (statistically probably) the magnetron frequency. This appears to work well or nOmega datasets, but may not work well for 1x datasets or those with very low magnetron peaks.
Inherited Members
- MassSpecBase
- mspeaks
- is_calibrated
- is_centroid
- calibration_order
- calibration_points
- calibration_ref_mzs
- calibration_meas_mzs
- calibration_RMS
- calibration_segment
- calibration_raw_error_median
- calibration_raw_error_stdev
- set_indexes
- reset_indexes
- add_mspeak
- reset_cal_therms
- clear_molecular_formulas
- process_mass_spec
- cal_noise_threshold
- parameters
- set_parameter_from_json
- set_parameter_from_toml
- mspeaks_settings
- settings
- molecular_search_settings
- mz_cal_profile
- mz_cal
- mz_exp
- freq_exp_profile
- freq_exp_pp
- mz_exp_profile
- mz_exp_pp
- abundance_profile
- abundance_profile_pp
- abundance
- freq_exp
- resolving_power
- signal_to_noise
- nominal_mz
- get_mz_and_abundance_peaks_tuples
- kmd
- kendrick_mass
- max_mz_exp
- min_mz_exp
- max_abundance
- max_signal_to_noise
- most_abundant_mspeak
- min_abundance
- dynamic_range
- baseline_noise
- baseline_noise_std
- Aterm
- Bterm
- Cterm
- filename
- dir_location
- sort_by_mz
- sort_by_abundance
- tic
- check_mspeaks_warning
- check_mspeaks
- remove_assignment_by_index
- filter_by_index
- filter_by_mz
- filter_by_s2n
- filter_by_abundance
- filter_by_max_resolving_power
- filter_by_mean_resolving_power
- filter_by_min_resolving_power
- filter_by_noise_threshold
- find_peaks
- change_kendrick_base_all_mspeaks
- get_nominal_mz_first_last_indexes
- get_masses_count_by_nominal_mass
- datapoints_count_by_nominal_mz
- get_nominal_mass_indexes
- plot_centroid
- plot_profile_and_noise_threshold
- plot_mz_domain_profile
- to_excel
- to_hdf
- to_csv
- to_pandas
- to_parquet
- to_dataframe
- to_json
- parameters_json
- parameters_toml
- corems.mass_spectrum.calc.MassSpectrumCalc.MassSpecCalc
- percentage_assigned
- percentile_assigned
- resolving_power_calc
- number_average_molecular_weight
- weight_average_molecular_weight
- corems.mass_spectrum.calc.PeakPicking.PeakPicking
- prepare_peak_picking_data
- cut_mz_domain_peak_picking
- legacy_cut_mz_domain_peak_picking
- extrapolate_axis
- extrapolate_axes_for_pp
- do_peak_picking
- find_minima
- linear_fit_calc
- calculate_resolving_power
- cal_minima
- calc_centroid
- get_threshold
- algebraic_quadratic
- find_apex_fit_quadratic
- check_prominence
- use_the_max
- calc_centroid_legacy
1530class MassSpecCentroid(MassSpecBase): 1531 """A mass spectrum class when the entry point is on centroid format 1532 1533 Notes 1534 ----- 1535 - Stores the centroid data and instrument settings 1536 - Simulate profile data based on Gaussian or Lorentzian peak shape 1537 - Iteration over a list of MSPeaks classes stored at the _mspeaks attributes 1538 - _mspeaks is populated under the hood by calling process_mass_spec method 1539 - iteration is null if _mspeaks is empty 1540 1541 Parameters 1542 ---------- 1543 data_dict : dict {string: numpy array float64 ) 1544 contains keys [m/z, Abundance, Resolving Power, S/N] 1545 d_params : dict{'str': float, int or str} 1546 contains the instrument settings and processing settings 1547 auto_process : bool, optional 1548 Whether to automatically process the mass spectrum. Defaults to True. 1549 1550 Attributes 1551 ---------- 1552 label : str 1553 store label (Bruker, Midas Transient, see Labels class) 1554 _baseline_noise : float 1555 store baseline noise 1556 _baseline_noise_std : float 1557 store baseline noise std 1558 _abundance : ndarray 1559 The abundance values of the mass spectrum. 1560 _mz_exp : ndarray 1561 The m/z values of the mass spectrum. 1562 _mspeaks : list 1563 A list of mass peaks. 1564 1565 1566 Methods 1567 ---------- 1568 * process_mass_spec(). 1569 Process the mass spectrum. Overriden from MassSpecBase. Populates the _mspeaks list with MSpeaks class using the centroid data. 1570 * __simulate_profile__data__(). 1571 Simulate profile data based on Gaussian or Lorentzian peak shape. Needs theoretical resolving power calculation and define peak shape, intended for plotting and inspection purposes only. 1572 1573 see also: MassSpecBase(), MassSpecfromFreq(), MassSpecProfile() 1574 """ 1575 1576 def __init__(self, data_dict, d_params, auto_process=True): 1577 super().__init__([], [], d_params) 1578 1579 self._set_parameters_objects(d_params) 1580 1581 if self.label == Labels.thermo_centroid: 1582 self._baseline_noise = d_params.get("baseline_noise") 1583 self._baseline_noise_std = d_params.get("baseline_noise_std") 1584 1585 self.is_centroid = True 1586 self.data_dict = data_dict 1587 self._mz_exp = data_dict[Labels.mz] 1588 self._abundance = data_dict[Labels.abundance] 1589 1590 if auto_process: 1591 self.process_mass_spec() 1592 1593 def __simulate_profile__data__(self, exp_mz_centroid, magnitude_centroid): 1594 """Simulate profile data based on Gaussian or Lorentzian peak shape 1595 1596 Notes 1597 ----- 1598 Needs theoretical resolving power calculation and define peak shape. 1599 This is a quick fix to trick a line plot be able to plot as sticks for plotting and inspection purposes only. 1600 1601 Parameters 1602 ---------- 1603 exp_mz_centroid : list(float) 1604 list of m/z values 1605 magnitude_centroid : list(float) 1606 list of abundance values 1607 1608 1609 Returns 1610 ------- 1611 x : list(float) 1612 list of m/z values 1613 y : list(float) 1614 list of abundance values 1615 """ 1616 1617 x, y = [], [] 1618 for i in range(len(exp_mz_centroid)): 1619 x.append(exp_mz_centroid[i] - 0.0000001) 1620 x.append(exp_mz_centroid[i]) 1621 x.append(exp_mz_centroid[i] + 0.0000001) 1622 y.append(0) 1623 y.append(magnitude_centroid[i]) 1624 y.append(0) 1625 return x, y 1626 1627 @property 1628 def mz_exp_profile(self): 1629 """Return the m/z profile of the mass spectrum.""" 1630 mz_list = [] 1631 for mz in self.mz_exp: 1632 mz_list.append(mz - 0.0000001) 1633 mz_list.append(mz) 1634 mz_list.append(mz + 0.0000001) 1635 return mz_list 1636 1637 @mz_exp_profile.setter 1638 def mz_exp_profile(self, _mz_exp): 1639 self._mz_exp = _mz_exp 1640 1641 @property 1642 def abundance_profile(self): 1643 """Return the abundance profile of the mass spectrum.""" 1644 ab_list = [] 1645 for ab in self.abundance: 1646 ab_list.append(0) 1647 ab_list.append(ab) 1648 ab_list.append(0) 1649 return ab_list 1650 1651 @abundance_profile.setter 1652 def abundance_profile(self, abundance): 1653 self._abundance = abundance 1654 1655 @property 1656 def tic(self): 1657 """Return the total ion current of the mass spectrum.""" 1658 return sum(self.abundance) 1659 1660 def process_mass_spec(self): 1661 """Process the mass spectrum.""" 1662 1663 # overwrite process_mass_spec 1664 # mspeak objs are usually added inside the PeaKPicking class 1665 # for profile and freq based data 1666 data_dict = self.data_dict 1667 # Peak polarity only (±1); formula assignment charge is separate. 1668 peak_polarity = self.polarity 1669 1670 # Check if resolving power is present 1671 rp_present = True 1672 if not data_dict.get(Labels.rp): 1673 rp_present = False 1674 if rp_present and list(data_dict.get(Labels.rp)) == [None] * len( 1675 data_dict.get(Labels.rp) 1676 ): 1677 rp_present = False 1678 1679 # Check if s2n is present 1680 s2n_present = True 1681 if not data_dict.get(Labels.s2n): 1682 s2n_present = False 1683 if s2n_present and list(data_dict.get(Labels.s2n)) == [None] * len( 1684 data_dict.get(Labels.s2n) 1685 ): 1686 s2n_present = False 1687 1688 # Warning if no s2n data but noise thresholding is set to signal_noise 1689 if ( 1690 not s2n_present 1691 and self.parameters.mass_spectrum.noise_threshold_method == "signal_noise" 1692 ): 1693 raise Exception("Signal to Noise data is missing for noise thresholding") 1694 1695 # Pull out abundance data 1696 abun = array(data_dict.get(Labels.abundance)).astype(float) 1697 1698 # Get the threshold for filtering if using minima, relative, or absolute abundance thresholding 1699 abundance_threshold, factor = self.get_threshold(abun) 1700 1701 # Set rp_i and s2n_i to None which will be overwritten if present 1702 rp_i, s2n_i = np.nan, np.nan 1703 for index, mz in enumerate(data_dict.get(Labels.mz)): 1704 if rp_present: 1705 if not data_dict.get(Labels.rp)[index]: 1706 rp_i = np.nan 1707 else: 1708 rp_i = float(data_dict.get(Labels.rp)[index]) 1709 if s2n_present: 1710 if not data_dict.get(Labels.s2n)[index]: 1711 s2n_i = np.nan 1712 else: 1713 s2n_i = float(data_dict.get(Labels.s2n)[index]) 1714 1715 # centroid peak does not have start and end peak index pos 1716 massspec_indexes = (index, index, index) 1717 1718 # Add peaks based on the noise thresholding method 1719 if ( 1720 self.parameters.mass_spectrum.noise_threshold_method 1721 in ["minima", "relative_abundance", "absolute_abundance"] 1722 and abun[index] / factor >= abundance_threshold 1723 ): 1724 self.add_mspeak( 1725 peak_polarity, 1726 mz, 1727 abun[index], 1728 rp_i, 1729 s2n_i, 1730 massspec_indexes, 1731 ms_parent=self, 1732 ) 1733 if ( 1734 self.parameters.mass_spectrum.noise_threshold_method == "signal_noise" 1735 and s2n_i >= self.parameters.mass_spectrum.noise_threshold_min_s2n 1736 ): 1737 self.add_mspeak( 1738 peak_polarity, 1739 mz, 1740 abun[index], 1741 rp_i, 1742 s2n_i, 1743 massspec_indexes, 1744 ms_parent=self, 1745 ) 1746 1747 self.mspeaks = self._mspeaks 1748 self._dynamic_range = self.max_abundance / self.min_abundance 1749 self._set_nominal_masses_start_final_indexes() 1750 1751 if self.label != Labels.thermo_centroid: 1752 if self.settings.noise_threshold_method == "log": 1753 raise Exception("log noise Not tested for centroid data") 1754 # self._baseline_noise, self._baseline_noise_std = self.run_log_noise_threshold_calc() 1755 1756 else: 1757 self._baseline_noise, self._baseline_noise_std = ( 1758 self.run_noise_threshold_calc() 1759 ) 1760 1761 del self.data_dict 1762 1763 def to_profile( 1764 self, 1765 mz_profile, 1766 abundance_profile, 1767 mz_cal_profile=None, 1768 peak_profile_indices=None, 1769 is_calibrated=False, 1770 ): 1771 """Return a :class:`MassSpecProfile` sharing this spectrum's peaks. 1772 1773 Reuses the already-picked peaks (and any molecular formula 1774 assignments on them) instead of re-picking from the profile data, and 1775 re-points each peak's parent reference to the returned object. This 1776 transfers ownership of the peaks: ``self.mspeaks``/``self._mspeaks`` 1777 are cleared once the new object holds them, so this spectrum and the 1778 returned one never end up sharing (and independently mutating) the 1779 same peak list. Used to rehydrate a profile mass spectrum from a 1780 CoreMS HDF5 file that stored both a profile and a peak table, 1781 without re-running peak picking. 1782 1783 Parameters 1784 ---------- 1785 mz_profile : array_like 1786 Experimental (uncalibrated) m/z profile. 1787 abundance_profile : array_like 1788 Abundance profile, same length as ``mz_profile``. 1789 mz_cal_profile : array_like, optional 1790 Calibrated m/z profile, same length as ``mz_profile``. Applied 1791 whenever given, independently of ``is_calibrated``. Default is 1792 None. 1793 peak_profile_indices : array_like of shape (n_peaks, 3), optional 1794 Per-peak ``(left, apex, right)`` indices into 1795 ``mz_profile``/``abundance_profile``, in the same order as 1796 ``self.mspeaks``. Ignored entirely if its length doesn't match 1797 ``self.mspeaks``. Otherwise checked per peak -- a stored triple 1798 is only trusted when ``0 <= left <= apex <= right < len(mz_profile)`` 1799 -- since a file can carry indices from before a later 1800 reprocessing changed the profile length (the writer skips 1801 storing new ones when that happens, but an older file may still 1802 have a stale set from before this check existed). When omitted, 1803 or for any one peak whose stored triple fails that check, that 1804 peak's bounds are estimated instead: the apex starts at the 1805 nearest profile index to the peak's own m/z (its calibrated m/z 1806 against ``mz_cal_profile`` if the peak is calibrated, else its 1807 experimental m/z against ``mz_profile`` -- either array may run 1808 ascending or descending), the left/right bounds are then the 1809 neighboring local minima from that starting point, and the apex 1810 is finally set to the actual local maximum between those two 1811 bounds -- not the initial nearest-index estimate, which can be 1812 off by a few points from the quadratic-fit interpolation the 1813 original picking used. 1814 is_calibrated : bool, optional 1815 Whether the stored m/z is calibrated. Sets ``is_calibrated`` on 1816 the returned spectrum directly; ``mz_cal_profile`` is applied 1817 independently of this flag whenever it is given. Default is 1818 False. 1819 1820 Returns 1821 ------- 1822 MassSpecProfile 1823 """ 1824 d_params = { 1825 "Aterm": self.Aterm, 1826 "Bterm": self.Bterm, 1827 "Cterm": self.Cterm, 1828 Labels.label: self.label, 1829 "analyzer": self.analyzer, 1830 "acquisition_time": self.acquisition_time, 1831 "instrument_label": self.instrument_label, 1832 "polarity": self.polarity, 1833 "scan_number": self.scan_number, 1834 "rt": self.retention_time, 1835 "mobility_rt": self.mobility_rt, 1836 "mobility_scan": self.mobility_scan, 1837 "filename_path": self._filename, 1838 "dir_location": self._dir_location, 1839 "baseline_noise": self._baseline_noise, 1840 "baseline_noise_std": self._baseline_noise_std, 1841 "sample_name": self.sample_name, 1842 } 1843 1844 new_obj = MassSpecProfile( 1845 {Labels.mz: mz_profile, Labels.abundance: abundance_profile}, 1846 d_params, 1847 auto_process=False, 1848 ) 1849 1850 new_obj._mspeaks = self._mspeaks 1851 new_obj.mspeaks = self.mspeaks 1852 new_obj._dict_nominal_masses_indexes = self._dict_nominal_masses_indexes 1853 new_obj._dynamic_range = self._dynamic_range 1854 # MassSpecBase.__init__ gave new_obj a fresh, default MSParameters; 1855 # replace it with this spectrum's (e.g. settings restored by a 1856 # reader's load_settings()) so processing settings survive the 1857 # conversion. 1858 new_obj.parameters = self.parameters 1859 1860 # Transfer ownership: this spectrum no longer holds these peaks. 1861 self._mspeaks = [] 1862 self.mspeaks = [] 1863 1864 if is_calibrated: 1865 new_obj.is_calibrated = True 1866 if mz_cal_profile is not None: 1867 new_obj.mz_cal_profile = mz_cal_profile 1868 1869 abundance_arr = asarray(new_obj.abundance_profile) 1870 mz_arr = asarray(mz_profile) 1871 mz_cal_arr = asarray(mz_cal_profile) if mz_cal_profile is not None else None 1872 n = len(abundance_arr) 1873 1874 if peak_profile_indices is not None and len(peak_profile_indices) != len( 1875 new_obj.mspeaks 1876 ): 1877 peak_profile_indices = None 1878 1879 for i, mspeak in enumerate(new_obj.mspeaks): 1880 mspeak._ms_parent = new_obj 1881 1882 stored = None 1883 if peak_profile_indices is not None: 1884 left, apex, right = (int(v) for v in peak_profile_indices[i]) 1885 # Stored indices can predate a later reprocessing with a 1886 # different-length profile (the writer skips storing them 1887 # when that happens, but an older file may still have a 1888 # stale set); only trust them if they're a sane bound into 1889 # *this* profile, else fall back to the search below. 1890 if 0 <= left <= apex <= right < n: 1891 stored = (left, apex, right) 1892 1893 if stored is not None: 1894 left, apex, right = stored 1895 else: 1896 if mspeak.mz_cal is not None and mz_cal_arr is not None: 1897 search_profile, search_value = mz_cal_arr, mspeak.mz_cal 1898 else: 1899 search_profile, search_value = mz_arr, mspeak._mz_exp 1900 1901 apex = _nearest_index_either_order(search_profile, search_value) 1902 right = new_obj.find_minima(apex, abundance_arr, n, right=True) 1903 left = new_obj.find_minima(apex, abundance_arr, n, right=False) 1904 # Re-anchor the apex to the tallest sample within the now-known 1905 # bounds, rather than trusting the nearest-index estimate above. 1906 apex = left + int(argmax(abundance_arr[left : right + 1])) 1907 mspeak.peak_left_index = left 1908 mspeak.peak_apex_index = apex 1909 mspeak.peak_right_index = right 1910 1911 return new_obj
A mass spectrum class when the entry point is on centroid format
Notes
- Stores the centroid data and instrument settings
- Simulate profile data based on Gaussian or Lorentzian peak shape
- Iteration over a list of MSPeaks classes stored at the _mspeaks attributes
- _mspeaks is populated under the hood by calling process_mass_spec method
- iteration is null if _mspeaks is empty
Parameters
- data_dict : dict {string (numpy array float64 )): contains keys [m/z, Abundance, Resolving Power, S/N]
- d_params : dict{'str' (float, int or str}): contains the instrument settings and processing settings
- auto_process (bool, optional): Whether to automatically process the mass spectrum. Defaults to True.
Attributes
- label (str): store label (Bruker, Midas Transient, see Labels class)
- _baseline_noise (float): store baseline noise
- _baseline_noise_std (float): store baseline noise std
- _abundance (ndarray): The abundance values of the mass spectrum.
- _mz_exp (ndarray): The m/z values of the mass spectrum.
- _mspeaks (list): A list of mass peaks.
Methods
- process_mass_spec(). Process the mass spectrum. Overriden from MassSpecBase. Populates the _mspeaks list with MSpeaks class using the centroid data.
- __simulate_profile__data__(). Simulate profile data based on Gaussian or Lorentzian peak shape. Needs theoretical resolving power calculation and define peak shape, intended for plotting and inspection purposes only.
see also: MassSpecBase(), MassSpecfromFreq(), MassSpecProfile()
1576 def __init__(self, data_dict, d_params, auto_process=True): 1577 super().__init__([], [], d_params) 1578 1579 self._set_parameters_objects(d_params) 1580 1581 if self.label == Labels.thermo_centroid: 1582 self._baseline_noise = d_params.get("baseline_noise") 1583 self._baseline_noise_std = d_params.get("baseline_noise_std") 1584 1585 self.is_centroid = True 1586 self.data_dict = data_dict 1587 self._mz_exp = data_dict[Labels.mz] 1588 self._abundance = data_dict[Labels.abundance] 1589 1590 if auto_process: 1591 self.process_mass_spec()
1627 @property 1628 def mz_exp_profile(self): 1629 """Return the m/z profile of the mass spectrum.""" 1630 mz_list = [] 1631 for mz in self.mz_exp: 1632 mz_list.append(mz - 0.0000001) 1633 mz_list.append(mz) 1634 mz_list.append(mz + 0.0000001) 1635 return mz_list
Return the m/z profile of the mass spectrum.
1641 @property 1642 def abundance_profile(self): 1643 """Return the abundance profile of the mass spectrum.""" 1644 ab_list = [] 1645 for ab in self.abundance: 1646 ab_list.append(0) 1647 ab_list.append(ab) 1648 ab_list.append(0) 1649 return ab_list
Return the abundance profile of the mass spectrum.
1655 @property 1656 def tic(self): 1657 """Return the total ion current of the mass spectrum.""" 1658 return sum(self.abundance)
Return the total ion current of the mass spectrum.
1660 def process_mass_spec(self): 1661 """Process the mass spectrum.""" 1662 1663 # overwrite process_mass_spec 1664 # mspeak objs are usually added inside the PeaKPicking class 1665 # for profile and freq based data 1666 data_dict = self.data_dict 1667 # Peak polarity only (±1); formula assignment charge is separate. 1668 peak_polarity = self.polarity 1669 1670 # Check if resolving power is present 1671 rp_present = True 1672 if not data_dict.get(Labels.rp): 1673 rp_present = False 1674 if rp_present and list(data_dict.get(Labels.rp)) == [None] * len( 1675 data_dict.get(Labels.rp) 1676 ): 1677 rp_present = False 1678 1679 # Check if s2n is present 1680 s2n_present = True 1681 if not data_dict.get(Labels.s2n): 1682 s2n_present = False 1683 if s2n_present and list(data_dict.get(Labels.s2n)) == [None] * len( 1684 data_dict.get(Labels.s2n) 1685 ): 1686 s2n_present = False 1687 1688 # Warning if no s2n data but noise thresholding is set to signal_noise 1689 if ( 1690 not s2n_present 1691 and self.parameters.mass_spectrum.noise_threshold_method == "signal_noise" 1692 ): 1693 raise Exception("Signal to Noise data is missing for noise thresholding") 1694 1695 # Pull out abundance data 1696 abun = array(data_dict.get(Labels.abundance)).astype(float) 1697 1698 # Get the threshold for filtering if using minima, relative, or absolute abundance thresholding 1699 abundance_threshold, factor = self.get_threshold(abun) 1700 1701 # Set rp_i and s2n_i to None which will be overwritten if present 1702 rp_i, s2n_i = np.nan, np.nan 1703 for index, mz in enumerate(data_dict.get(Labels.mz)): 1704 if rp_present: 1705 if not data_dict.get(Labels.rp)[index]: 1706 rp_i = np.nan 1707 else: 1708 rp_i = float(data_dict.get(Labels.rp)[index]) 1709 if s2n_present: 1710 if not data_dict.get(Labels.s2n)[index]: 1711 s2n_i = np.nan 1712 else: 1713 s2n_i = float(data_dict.get(Labels.s2n)[index]) 1714 1715 # centroid peak does not have start and end peak index pos 1716 massspec_indexes = (index, index, index) 1717 1718 # Add peaks based on the noise thresholding method 1719 if ( 1720 self.parameters.mass_spectrum.noise_threshold_method 1721 in ["minima", "relative_abundance", "absolute_abundance"] 1722 and abun[index] / factor >= abundance_threshold 1723 ): 1724 self.add_mspeak( 1725 peak_polarity, 1726 mz, 1727 abun[index], 1728 rp_i, 1729 s2n_i, 1730 massspec_indexes, 1731 ms_parent=self, 1732 ) 1733 if ( 1734 self.parameters.mass_spectrum.noise_threshold_method == "signal_noise" 1735 and s2n_i >= self.parameters.mass_spectrum.noise_threshold_min_s2n 1736 ): 1737 self.add_mspeak( 1738 peak_polarity, 1739 mz, 1740 abun[index], 1741 rp_i, 1742 s2n_i, 1743 massspec_indexes, 1744 ms_parent=self, 1745 ) 1746 1747 self.mspeaks = self._mspeaks 1748 self._dynamic_range = self.max_abundance / self.min_abundance 1749 self._set_nominal_masses_start_final_indexes() 1750 1751 if self.label != Labels.thermo_centroid: 1752 if self.settings.noise_threshold_method == "log": 1753 raise Exception("log noise Not tested for centroid data") 1754 # self._baseline_noise, self._baseline_noise_std = self.run_log_noise_threshold_calc() 1755 1756 else: 1757 self._baseline_noise, self._baseline_noise_std = ( 1758 self.run_noise_threshold_calc() 1759 ) 1760 1761 del self.data_dict
Process the mass spectrum.
1763 def to_profile( 1764 self, 1765 mz_profile, 1766 abundance_profile, 1767 mz_cal_profile=None, 1768 peak_profile_indices=None, 1769 is_calibrated=False, 1770 ): 1771 """Return a :class:`MassSpecProfile` sharing this spectrum's peaks. 1772 1773 Reuses the already-picked peaks (and any molecular formula 1774 assignments on them) instead of re-picking from the profile data, and 1775 re-points each peak's parent reference to the returned object. This 1776 transfers ownership of the peaks: ``self.mspeaks``/``self._mspeaks`` 1777 are cleared once the new object holds them, so this spectrum and the 1778 returned one never end up sharing (and independently mutating) the 1779 same peak list. Used to rehydrate a profile mass spectrum from a 1780 CoreMS HDF5 file that stored both a profile and a peak table, 1781 without re-running peak picking. 1782 1783 Parameters 1784 ---------- 1785 mz_profile : array_like 1786 Experimental (uncalibrated) m/z profile. 1787 abundance_profile : array_like 1788 Abundance profile, same length as ``mz_profile``. 1789 mz_cal_profile : array_like, optional 1790 Calibrated m/z profile, same length as ``mz_profile``. Applied 1791 whenever given, independently of ``is_calibrated``. Default is 1792 None. 1793 peak_profile_indices : array_like of shape (n_peaks, 3), optional 1794 Per-peak ``(left, apex, right)`` indices into 1795 ``mz_profile``/``abundance_profile``, in the same order as 1796 ``self.mspeaks``. Ignored entirely if its length doesn't match 1797 ``self.mspeaks``. Otherwise checked per peak -- a stored triple 1798 is only trusted when ``0 <= left <= apex <= right < len(mz_profile)`` 1799 -- since a file can carry indices from before a later 1800 reprocessing changed the profile length (the writer skips 1801 storing new ones when that happens, but an older file may still 1802 have a stale set from before this check existed). When omitted, 1803 or for any one peak whose stored triple fails that check, that 1804 peak's bounds are estimated instead: the apex starts at the 1805 nearest profile index to the peak's own m/z (its calibrated m/z 1806 against ``mz_cal_profile`` if the peak is calibrated, else its 1807 experimental m/z against ``mz_profile`` -- either array may run 1808 ascending or descending), the left/right bounds are then the 1809 neighboring local minima from that starting point, and the apex 1810 is finally set to the actual local maximum between those two 1811 bounds -- not the initial nearest-index estimate, which can be 1812 off by a few points from the quadratic-fit interpolation the 1813 original picking used. 1814 is_calibrated : bool, optional 1815 Whether the stored m/z is calibrated. Sets ``is_calibrated`` on 1816 the returned spectrum directly; ``mz_cal_profile`` is applied 1817 independently of this flag whenever it is given. Default is 1818 False. 1819 1820 Returns 1821 ------- 1822 MassSpecProfile 1823 """ 1824 d_params = { 1825 "Aterm": self.Aterm, 1826 "Bterm": self.Bterm, 1827 "Cterm": self.Cterm, 1828 Labels.label: self.label, 1829 "analyzer": self.analyzer, 1830 "acquisition_time": self.acquisition_time, 1831 "instrument_label": self.instrument_label, 1832 "polarity": self.polarity, 1833 "scan_number": self.scan_number, 1834 "rt": self.retention_time, 1835 "mobility_rt": self.mobility_rt, 1836 "mobility_scan": self.mobility_scan, 1837 "filename_path": self._filename, 1838 "dir_location": self._dir_location, 1839 "baseline_noise": self._baseline_noise, 1840 "baseline_noise_std": self._baseline_noise_std, 1841 "sample_name": self.sample_name, 1842 } 1843 1844 new_obj = MassSpecProfile( 1845 {Labels.mz: mz_profile, Labels.abundance: abundance_profile}, 1846 d_params, 1847 auto_process=False, 1848 ) 1849 1850 new_obj._mspeaks = self._mspeaks 1851 new_obj.mspeaks = self.mspeaks 1852 new_obj._dict_nominal_masses_indexes = self._dict_nominal_masses_indexes 1853 new_obj._dynamic_range = self._dynamic_range 1854 # MassSpecBase.__init__ gave new_obj a fresh, default MSParameters; 1855 # replace it with this spectrum's (e.g. settings restored by a 1856 # reader's load_settings()) so processing settings survive the 1857 # conversion. 1858 new_obj.parameters = self.parameters 1859 1860 # Transfer ownership: this spectrum no longer holds these peaks. 1861 self._mspeaks = [] 1862 self.mspeaks = [] 1863 1864 if is_calibrated: 1865 new_obj.is_calibrated = True 1866 if mz_cal_profile is not None: 1867 new_obj.mz_cal_profile = mz_cal_profile 1868 1869 abundance_arr = asarray(new_obj.abundance_profile) 1870 mz_arr = asarray(mz_profile) 1871 mz_cal_arr = asarray(mz_cal_profile) if mz_cal_profile is not None else None 1872 n = len(abundance_arr) 1873 1874 if peak_profile_indices is not None and len(peak_profile_indices) != len( 1875 new_obj.mspeaks 1876 ): 1877 peak_profile_indices = None 1878 1879 for i, mspeak in enumerate(new_obj.mspeaks): 1880 mspeak._ms_parent = new_obj 1881 1882 stored = None 1883 if peak_profile_indices is not None: 1884 left, apex, right = (int(v) for v in peak_profile_indices[i]) 1885 # Stored indices can predate a later reprocessing with a 1886 # different-length profile (the writer skips storing them 1887 # when that happens, but an older file may still have a 1888 # stale set); only trust them if they're a sane bound into 1889 # *this* profile, else fall back to the search below. 1890 if 0 <= left <= apex <= right < n: 1891 stored = (left, apex, right) 1892 1893 if stored is not None: 1894 left, apex, right = stored 1895 else: 1896 if mspeak.mz_cal is not None and mz_cal_arr is not None: 1897 search_profile, search_value = mz_cal_arr, mspeak.mz_cal 1898 else: 1899 search_profile, search_value = mz_arr, mspeak._mz_exp 1900 1901 apex = _nearest_index_either_order(search_profile, search_value) 1902 right = new_obj.find_minima(apex, abundance_arr, n, right=True) 1903 left = new_obj.find_minima(apex, abundance_arr, n, right=False) 1904 # Re-anchor the apex to the tallest sample within the now-known 1905 # bounds, rather than trusting the nearest-index estimate above. 1906 apex = left + int(argmax(abundance_arr[left : right + 1])) 1907 mspeak.peak_left_index = left 1908 mspeak.peak_apex_index = apex 1909 mspeak.peak_right_index = right 1910 1911 return new_obj
Return a MassSpecProfile sharing this spectrum's peaks.
Reuses the already-picked peaks (and any molecular formula
assignments on them) instead of re-picking from the profile data, and
re-points each peak's parent reference to the returned object. This
transfers ownership of the peaks: self.mspeaks/self._mspeaks
are cleared once the new object holds them, so this spectrum and the
returned one never end up sharing (and independently mutating) the
same peak list. Used to rehydrate a profile mass spectrum from a
CoreMS HDF5 file that stored both a profile and a peak table,
without re-running peak picking.
Parameters
- mz_profile (array_like): Experimental (uncalibrated) m/z profile.
- abundance_profile (array_like):
Abundance profile, same length as
mz_profile. - mz_cal_profile (array_like, optional):
Calibrated m/z profile, same length as
mz_profile. Applied whenever given, independently ofis_calibrated. Default is None. - peak_profile_indices (array_like of shape (n_peaks, 3), optional):
Per-peak
(left, apex, right)indices intomz_profile/abundance_profile, in the same order asself.mspeaks. Ignored entirely if its length doesn't matchself.mspeaks. Otherwise checked per peak -- a stored triple is only trusted when0 <= left <= apex <= right < len(mz_profile)-- since a file can carry indices from before a later reprocessing changed the profile length (the writer skips storing new ones when that happens, but an older file may still have a stale set from before this check existed). When omitted, or for any one peak whose stored triple fails that check, that peak's bounds are estimated instead: the apex starts at the nearest profile index to the peak's own m/z (its calibrated m/z againstmz_cal_profileif the peak is calibrated, else its experimental m/z againstmz_profile-- either array may run ascending or descending), the left/right bounds are then the neighboring local minima from that starting point, and the apex is finally set to the actual local maximum between those two bounds -- not the initial nearest-index estimate, which can be off by a few points from the quadratic-fit interpolation the original picking used. - is_calibrated (bool, optional):
Whether the stored m/z is calibrated. Sets
is_calibratedon the returned spectrum directly;mz_cal_profileis applied independently of this flag whenever it is given. Default is False.
Returns
- MassSpecProfile
Inherited Members
- MassSpecBase
- mspeaks
- is_calibrated
- has_frequency
- calibration_order
- calibration_points
- calibration_ref_mzs
- calibration_meas_mzs
- calibration_RMS
- calibration_segment
- calibration_raw_error_median
- calibration_raw_error_stdev
- set_indexes
- reset_indexes
- add_mspeak
- reset_cal_therms
- clear_molecular_formulas
- cal_noise_threshold
- parameters
- set_parameter_from_json
- set_parameter_from_toml
- mspeaks_settings
- settings
- molecular_search_settings
- mz_cal_profile
- mz_cal
- mz_exp
- freq_exp_profile
- freq_exp_pp
- mz_exp_pp
- abundance_profile_pp
- abundance
- freq_exp
- resolving_power
- signal_to_noise
- nominal_mz
- get_mz_and_abundance_peaks_tuples
- kmd
- kendrick_mass
- max_mz_exp
- min_mz_exp
- max_abundance
- max_signal_to_noise
- most_abundant_mspeak
- min_abundance
- dynamic_range
- baseline_noise
- baseline_noise_std
- Aterm
- Bterm
- Cterm
- filename
- dir_location
- sort_by_mz
- sort_by_abundance
- check_mspeaks_warning
- check_mspeaks
- remove_assignment_by_index
- filter_by_index
- filter_by_mz
- filter_by_s2n
- filter_by_abundance
- filter_by_max_resolving_power
- filter_by_mean_resolving_power
- filter_by_min_resolving_power
- filter_by_noise_threshold
- find_peaks
- change_kendrick_base_all_mspeaks
- get_nominal_mz_first_last_indexes
- get_masses_count_by_nominal_mass
- datapoints_count_by_nominal_mz
- get_nominal_mass_indexes
- plot_centroid
- plot_profile_and_noise_threshold
- plot_mz_domain_profile
- to_excel
- to_hdf
- to_csv
- to_pandas
- to_parquet
- to_dataframe
- to_json
- parameters_json
- parameters_toml
- corems.mass_spectrum.calc.MassSpectrumCalc.MassSpecCalc
- percentage_assigned
- percentile_assigned
- resolving_power_calc
- number_average_molecular_weight
- weight_average_molecular_weight
- corems.mass_spectrum.calc.PeakPicking.PeakPicking
- prepare_peak_picking_data
- cut_mz_domain_peak_picking
- legacy_cut_mz_domain_peak_picking
- extrapolate_axis
- extrapolate_axes_for_pp
- do_peak_picking
- find_minima
- linear_fit_calc
- calculate_resolving_power
- cal_minima
- calc_centroid
- get_threshold
- algebraic_quadratic
- find_apex_fit_quadratic
- check_prominence
- use_the_max
- calc_centroid_legacy
1914class MassSpecCentroidLowRes(MassSpecCentroid): 1915 """A mass spectrum class when the entry point is on low resolution centroid format 1916 1917 Notes 1918 ----- 1919 Does not store MSPeak Objs, will iterate over mz, abundance pairs instead 1920 1921 Parameters 1922 ---------- 1923 data_dict : dict {string: numpy array float64 ) 1924 contains keys [m/z, Abundance, Resolving Power, S/N] 1925 d_params : dict{'str': float, int or str} 1926 contains the instrument settings and processing settings 1927 1928 Attributes 1929 ---------- 1930 _processed_tic : float 1931 store processed total ion current 1932 _abundance : ndarray 1933 The abundance values of the mass spectrum. 1934 _mz_exp : ndarray 1935 The m/z values of the mass spectrum. 1936 """ 1937 1938 def __init__(self, data_dict, d_params): 1939 self._set_parameters_objects(d_params) 1940 self._mz_exp = array(data_dict.get(Labels.mz)) 1941 self._abundance = array(data_dict.get(Labels.abundance)) 1942 self._processed_tic = None 1943 1944 def __len__(self): 1945 return len(self.mz_exp) 1946 1947 def __getitem__(self, position): 1948 return (self.mz_exp[position], self.abundance[position]) 1949 1950 @property 1951 def mz_exp(self): 1952 """Return the m/z values of the mass spectrum.""" 1953 return self._mz_exp 1954 1955 @property 1956 def abundance(self): 1957 """Return the abundance values of the mass spectrum.""" 1958 return self._abundance 1959 1960 @property 1961 def processed_tic(self): 1962 """Return the processed total ion current of the mass spectrum.""" 1963 return sum(self._processed_tic) 1964 1965 @property 1966 def tic(self): 1967 """Return the total ion current of the mass spectrum.""" 1968 if self._processed_tic: 1969 return self._processed_tic 1970 else: 1971 return sum(self.abundance) 1972 1973 @property 1974 def mz_abun_tuples(self): 1975 """Return the m/z and abundance values of the mass spectrum as a list of tuples.""" 1976 r = lambda x: int(round(x[0], 0), int(round(x[1], 0))) 1977 1978 return [r(i) for i in self] 1979 1980 @property 1981 def mz_abun_dict(self): 1982 """Return the m/z and abundance values of the mass spectrum as a dictionary.""" 1983 r = lambda x: int(round(x, 0)) 1984 1985 return {r(i[0]): r(i[1]) for i in self}
A mass spectrum class when the entry point is on low resolution centroid format
Notes
Does not store MSPeak Objs, will iterate over mz, abundance pairs instead
Parameters
- data_dict : dict {string (numpy array float64 )): contains keys [m/z, Abundance, Resolving Power, S/N]
- d_params : dict{'str' (float, int or str}): contains the instrument settings and processing settings
Attributes
- _processed_tic (float): store processed total ion current
- _abundance (ndarray): The abundance values of the mass spectrum.
- _mz_exp (ndarray): The m/z values of the mass spectrum.
1950 @property 1951 def mz_exp(self): 1952 """Return the m/z values of the mass spectrum.""" 1953 return self._mz_exp
Return the m/z values of the mass spectrum.
1955 @property 1956 def abundance(self): 1957 """Return the abundance values of the mass spectrum.""" 1958 return self._abundance
Return the abundance values of the mass spectrum.
1960 @property 1961 def processed_tic(self): 1962 """Return the processed total ion current of the mass spectrum.""" 1963 return sum(self._processed_tic)
Return the processed total ion current of the mass spectrum.
1965 @property 1966 def tic(self): 1967 """Return the total ion current of the mass spectrum.""" 1968 if self._processed_tic: 1969 return self._processed_tic 1970 else: 1971 return sum(self.abundance)
Return the total ion current of the mass spectrum.
1973 @property 1974 def mz_abun_tuples(self): 1975 """Return the m/z and abundance values of the mass spectrum as a list of tuples.""" 1976 r = lambda x: int(round(x[0], 0), int(round(x[1], 0))) 1977 1978 return [r(i) for i in self]
Return the m/z and abundance values of the mass spectrum as a list of tuples.
1980 @property 1981 def mz_abun_dict(self): 1982 """Return the m/z and abundance values of the mass spectrum as a dictionary.""" 1983 r = lambda x: int(round(x, 0)) 1984 1985 return {r(i[0]): r(i[1]) for i in self}
Return the m/z and abundance values of the mass spectrum as a dictionary.
Inherited Members
- MassSpecCentroid
- is_centroid
- data_dict
- mz_exp_profile
- abundance_profile
- process_mass_spec
- to_profile
- MassSpecBase
- mspeaks
- is_calibrated
- has_frequency
- calibration_order
- calibration_points
- calibration_ref_mzs
- calibration_meas_mzs
- calibration_RMS
- calibration_segment
- calibration_raw_error_median
- calibration_raw_error_stdev
- set_indexes
- reset_indexes
- add_mspeak
- reset_cal_therms
- clear_molecular_formulas
- cal_noise_threshold
- parameters
- set_parameter_from_json
- set_parameter_from_toml
- mspeaks_settings
- settings
- molecular_search_settings
- mz_cal_profile
- mz_cal
- freq_exp_profile
- freq_exp_pp
- mz_exp_pp
- abundance_profile_pp
- freq_exp
- resolving_power
- signal_to_noise
- nominal_mz
- get_mz_and_abundance_peaks_tuples
- kmd
- kendrick_mass
- max_mz_exp
- min_mz_exp
- max_abundance
- max_signal_to_noise
- most_abundant_mspeak
- min_abundance
- dynamic_range
- baseline_noise
- baseline_noise_std
- Aterm
- Bterm
- Cterm
- filename
- dir_location
- sort_by_mz
- sort_by_abundance
- check_mspeaks_warning
- check_mspeaks
- remove_assignment_by_index
- filter_by_index
- filter_by_mz
- filter_by_s2n
- filter_by_abundance
- filter_by_max_resolving_power
- filter_by_mean_resolving_power
- filter_by_min_resolving_power
- filter_by_noise_threshold
- find_peaks
- change_kendrick_base_all_mspeaks
- get_nominal_mz_first_last_indexes
- get_masses_count_by_nominal_mass
- datapoints_count_by_nominal_mz
- get_nominal_mass_indexes
- plot_centroid
- plot_profile_and_noise_threshold
- plot_mz_domain_profile
- to_excel
- to_hdf
- to_csv
- to_pandas
- to_parquet
- to_dataframe
- to_json
- parameters_json
- parameters_toml
- corems.mass_spectrum.calc.MassSpectrumCalc.MassSpecCalc
- percentage_assigned
- percentile_assigned
- resolving_power_calc
- number_average_molecular_weight
- weight_average_molecular_weight
- corems.mass_spectrum.calc.PeakPicking.PeakPicking
- prepare_peak_picking_data
- cut_mz_domain_peak_picking
- legacy_cut_mz_domain_peak_picking
- extrapolate_axis
- extrapolate_axes_for_pp
- do_peak_picking
- find_minima
- linear_fit_calc
- calculate_resolving_power
- cal_minima
- calc_centroid
- get_threshold
- algebraic_quadratic
- find_apex_fit_quadratic
- check_prominence
- use_the_max
- calc_centroid_legacy