corems.mass_spectra.factory.GC_Class

  1__author__ = "Yuri E. Corilo"
  2__date__ = "Feb 13, 2020"
  3
  4
  5from pathlib import Path
  6import json
  7
  8from numpy import array
  9
 10
 11from corems.mass_spectra.calc.GC_Calc import GC_Calculations
 12from corems.mass_spectra.calc.GC_Deconvolution import MassDeconvolution
 13from corems.mass_spectra.calc import SignalProcessing as sp
 14
 15from corems.chroma_peak.factory.chroma_peak_classes import GCPeak
 16from corems.mass_spectra.output.export import LowResGCMSExport
 17from corems.encapsulation.factory.parameters import GCMSParameters
 18
 19
 20class GCMSBase(GC_Calculations, MassDeconvolution):
 21    """Base class for GC-MS data processing.
 22
 23    Parameters
 24    ----
 25    file_location : str, pathlib.Path, or s3path.S3Path
 26        Path object containing the file location.
 27    analyzer : str, optional
 28        Name of the analyzer. Defaults to 'Unknown'.
 29    instrument_label : str, optional
 30        Label of the instrument. Defaults to 'Unknown'.
 31    sample_name : str, optional
 32        Name of the sample. If not provided, it is derived from the file location.
 33
 34    Attributes
 35    ------------
 36    file_location : pathlib.Path
 37        Path object containing the file location.
 38    sample_name : str
 39        Name of the sample.
 40    analyzer : str
 41        Name of the analyzer.
 42    instrument_label : str
 43        Label of the instrument.
 44    gcpeaks : list
 45        List of GCPeak objects.
 46    ri_pairs_ref : None
 47        Reference retention index pairs.
 48    cal_file_path : None
 49        Calibration file path.
 50    _parameters : GCMSParameters
 51        GC-MS parameters.
 52    _retention_time_list : list
 53        List of retention times.
 54    _scans_number_list : list
 55        List of scan numbers.
 56    _tic_list : list
 57        List of total ion chromatogram values.
 58    _ms : dict
 59        Dictionary containing all mass spectra.
 60    _processed_tic : list
 61        List of processed total ion chromatogram values.
 62
 63    Methods
 64    -------
 65    * process_chromatogram(plot_res=False). Process the chromatogram.
 66    * plot_gc_peaks(ax=None, color='red'). Plot the GC peaks.
 67    """
 68
 69    def __init__(
 70        self,
 71        file_location,
 72        analyzer="Unknown",
 73        instrument_label="Unknown",
 74        sample_name=None,
 75    ):
 76        if isinstance(file_location, str):
 77            # if obj is a string it defaults to create a Path obj, pass the S3Path if needed
 78            file_location = Path(file_location)
 79
 80        if not file_location.exists():
 81            raise FileExistsError("File does not exist: " + str(file_location))
 82
 83        self.file_location = file_location
 84
 85        if sample_name:
 86            self.sample_name = sample_name
 87        else:
 88            self.sample_name = file_location.stem
 89
 90        self.analyzer = analyzer
 91        self.instrument_label = instrument_label
 92        self._init_settings()
 93
 94        self._retention_time_list = []
 95        self._scans_number_list = []
 96        self._tic_list = []
 97
 98        # all scans
 99        self._ms = {}
100
101        # after peak detection
102        self._processed_tic = []
103        self.gcpeaks = []
104
105        self.ri_pairs_ref = None
106        self.cal_file_path = None
107
108    def _init_settings(self):
109        """Initialize the settings for GC_Class.
110
111        This method initializes the settings for the GC_Class object using the GCMSParameters class.
112        """
113        self._parameters = GCMSParameters()
114
115    def __len__(self):
116        """Return the number of GC peaks in the GC_Class object."""
117        return len(self.gcpeaks)
118
119    def __getitem__(self, scan_number) -> GCPeak:
120        """Return the GCPeak with the given scan number."""
121        return self.gcpeaks[scan_number]
122
123    # def __iter__(self):
124
125    #     return iter(self.gcpeaks.values())
126
127    def process_chromatogram(self, plot_res=False):
128        """Process the chromatogram.
129
130        This method processes the chromatogram.
131
132        Parameters
133        ----------
134        plot_res : bool, optional
135            If True, plot the results. Defaults to False.
136        """
137
138        # tic = self.tic - self.baseline_detector(self.tic)
139
140        self._processed_tic = self.smooth_tic(self.tic)
141
142        for index, tic in enumerate(self._processed_tic):
143            self._ms[index]._processed_tic = tic
144
145        # self.second_derivative_threshold(self._processed_tic)
146
147        if self.chromatogram_settings.use_deconvolution:
148            self.run_deconvolution(plot_res=False)
149
150        else:
151            peaks_index = self.centroid_detector(
152                self._processed_tic, self.retention_time
153            )
154
155            for i in peaks_index:
156                apex_index = i[1]
157
158                gc_peak = GCPeak(self, self._ms[apex_index], i)
159
160                gc_peak.calc_area(self._processed_tic, 1)
161
162                self.gcpeaks.append(gc_peak)
163
164                # self.gcpeaks[self.scans_number[apex_index]] = gc_peak
165
166    def add_mass_spectrum(self, mass_spec):
167        """Add a mass spectrum to the GC-MS object.
168
169        This method adds a mass spectrum to the GC-MS object.
170
171        Parameters
172        ----------
173        mass_spec : MassSpectrum
174            Mass spectrum to be added.
175        """
176
177        self._ms[mass_spec.scan_number] = mass_spec
178
179    def set_tic_list_from_data(self):
180        """Set the total ion chromatogram list from the mass spectra data within the GC-MS data object."""
181
182        self.tic = [self._ms.get(i).tic for i in self.scans_number]
183
184        # self.set_tic_list([self._ms.get(i).get_sumed_signal_to_noise() for i in self.get_scans_number()])
185
186    def set_retention_time_from_data(self):
187        """Set the retention time list from the mass spectra data within the GC-MS data object."""
188
189        retention_time_list = []
190
191        for key_ms in sorted(self._ms.keys()):
192            retention_time_list.append(self._ms.get(key_ms).retention_time)
193
194        self.retention_time = retention_time_list
195
196        # self.set_retention_time_list(sorted(self._ms.keys()))
197
198    def set_scans_number_from_data(self):
199        """Set the scan number list from the mass spectra data within the GC-MS data object."""
200
201        self.scans_number = sorted(self._ms.keys())
202
203    @property
204    def parameters(self):
205        """GCMS Parameters"""
206        return self._parameters
207
208    @parameters.setter
209    def parameters(self, gcms_parameters_instance):
210        self._parameters = gcms_parameters_instance
211
212    # Note: maintaining `parameter` for backwards compatibility,
213    # but proper usage would reference `parameters` to conform
214    # to other classes.
215    @property
216    def parameter(self):
217        """GCMS Parameters"""
218        return self._parameters
219
220    @parameter.setter
221    def parameter(self, gcms_parameters_instance):
222        self._parameters = gcms_parameters_instance
223
224    @property
225    def molecular_search_settings(self):
226        """Molecular Search Settings"""
227        return self.parameters.molecular_search
228
229    @molecular_search_settings.setter
230    def molecular_search_settings(self, settings_class_instance):
231        self.parameters.molecular_search = settings_class_instance
232
233    @property
234    def chromatogram_settings(self):
235        """Chromatogram Settings"""
236        return self.parameters.gc_ms
237
238    @chromatogram_settings.setter
239    def chromatogram_settings(self, settings_class_instance):
240        self.parameters.gc_ms = settings_class_instance
241
242    @property
243    def scans_number(self):
244        """Scans Number"""
245        return self._scans_number_list
246
247    @property
248    def retention_time(self):
249        """Retention Time"""
250        return self._retention_time_list
251
252    @property
253    def processed_tic(self):
254        """Processed Total Ion Current"""
255        return self._processed_tic
256
257    @property
258    def tic(self):
259        """Total Ion Current"""
260        return self._tic_list
261
262    @property
263    def max_tic(self):
264        """Maximum Total Ion Current"""
265        return max([gc_peak.tic for gc_peak in self])
266
267    @property
268    def min_tic(self):
269        """Minimum Total Ion Current"""
270        return min([gc_peak.tic for gc_peak in self])
271
272    @property
273    def dynamic_range(self):
274        """Dynamic Range of the Total Ion Current"""
275        return self.max_tic / self.min_tic
276
277    @property
278    def matched_peaks(self):
279        """Matched Peaks"""
280        return [gc_peak for gc_peak in self if gc_peak]
281
282    @property
283    def sorted_gcpeaks(self):
284        """Sorted GC Peaks, by retention time"""
285        return sorted(self, key=lambda g: g.retention_time)
286
287    @property
288    def unique_metabolites(self):
289        """Unique Metabolites"""
290        metabolites = set()
291        for gc_peak in self:
292            if gc_peak:
293                for compound_obj in gc_peak:
294                    metabolites.add(compound_obj.name)
295
296        return metabolites
297
298    @property
299    def metabolites_data(self):
300        """Metabolites Data"""
301        metabolites = {}
302        for gc_peak in self:
303            if gc_peak:
304                for compound_obj in gc_peak:
305                    if compound_obj.name in metabolites.keys():
306                        current_score = metabolites[compound_obj.name][
307                            "highest_similarity_score"
308                        ]
309                        compound_score = compound_obj.spectral_similarity_score
310                        metabolites[compound_obj.name]["highest_similarity_score"] = (
311                            compound_score
312                            if compound_score > current_score
313                            else current_score
314                        )
315
316                    else:
317                        if compound_obj.metadata:
318                            metabolites[compound_obj.name] = {
319                                "name": compound_obj.name,
320                                "highest_similarity_score": compound_obj.spectral_similarity_score,
321                                "casno": compound_obj.metadata.cas,
322                                "kegg": compound_obj.metadata.kegg,
323                                "inchi": compound_obj.metadata.inchi,
324                                "inchi_key": compound_obj.metadata.inchikey,
325                                "chebi": compound_obj.metadata.chebi,
326                                "smiles": compound_obj.metadata.smiles,
327                            }
328                        else:
329                            metabolites[compound_obj.name] = {
330                                "name": compound_obj.name,
331                                "highest_similarity_score": compound_obj.spectral_similarity_score,
332                                "casno": "",
333                                "kegg": "",
334                                "inchi": "",
335                                "inchikey": "",
336                                "chebi": "",
337                                "smiles": "",
338                            }
339
340        return list(metabolites.values())
341
342    @property
343    def no_matched_peaks(self):
344        """Peaks with no Matched Metabolites"""
345        return [peak for peak in self if not peak]
346
347    @retention_time.setter
348    def retention_time(self, alist):
349        # self._retention_time_list = linspace(0, 80, num=len(self._scans_number_list))
350        self._retention_time_list = alist
351
352    @scans_number.setter
353    def scans_number(self, alist):
354        self._scans_number_list = alist
355
356    @tic.setter
357    def tic(self, alist):
358        self._tic_list = array(alist)
359
360    def plot_gc_peaks(self, ax=None, color="red"):  # pragma: no cover
361        """Plot the GC peaks.
362
363        This method plots the GC peaks.
364
365        Parameters
366        ----------
367        ax : matplotlib.axes.Axes, optional
368            Axes object to plot the GC peaks. Defaults to None.
369        color : str, optional
370            Color of the GC peaks. Defaults to 'red'.
371        """
372
373        import matplotlib.pyplot as plt
374
375        fig = plt.gcf()
376        if ax is None:
377            ax = plt.gca()
378
379        max_rts = [gc_peak.mass_spectrum.retention_time for gc_peak in self]
380        max_tics = [gc_peak.mass_spectrum.tic for gc_peak in self]
381
382        # min_rts = [self._ms[gc_peak.start_index].retention_time for gc_peak in self] + [self._ms[gc_peak.final_index].retention_time for gc_peak in self]
383        # min_tics = [self._ms[gc_peak.start_index].tic for gc_peak in self] + [self._ms[gc_peak.final_index].tic for gc_peak in self]
384        # sc = ax.scatter(min_rts, min_tics, color='yellow', linewidth=0, marker='v')
385
386        sc = ax.scatter(max_rts, max_tics, color=color, marker="v")
387
388        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
389
390        annot = ax.annotate(
391            "",
392            xy=(0, 0),
393            xytext=(20, 20),
394            textcoords="offset points",
395            bbox=dict(boxstyle="round", fc="w"),
396            arrowprops=dict(arrowstyle="->"),
397        )
398        annot.set_visible(False)
399        annot.get_bbox_patch().set_facecolor(("lightblue"))
400        annot.get_bbox_patch().set_alpha(0.8)
401
402        def update_annot(ind):
403            pos = sc.get_offsets()[ind["ind"][0]]
404            annot.xy = pos
405
406            text = "RT: {}\nRT Ref: {}\nRI: {}\nRI Ref: {}\nSimilarity Score: {}\nName: {}".format(
407                " ".join([str(round(self[n].retention_time, 2)) for n in ind["ind"]]),
408                " ".join(
409                    [
410                        str(
411                            round(self[n].highest_score_compound.retention_time, 2)
412                            if self[n].highest_score_compound
413                            else None
414                        )
415                        for n in ind["ind"]
416                    ]
417                ),
418                " ".join(
419                    [
420                        str(round(self[n].ri, 2) if self[n].ri else None)
421                        for n in ind["ind"]
422                    ]
423                ),
424                " ".join(
425                    [
426                        str(
427                            round(self[n].highest_score_compound.ri, 2)
428                            if self[n].highest_score_compound
429                            else None
430                        )
431                        for n in ind["ind"]
432                    ]
433                ),
434                " ".join(
435                    [
436                        str(
437                            round(self[n].highest_score_compound.similarity_score, 4)
438                            if self[n].highest_score_compound
439                            else None
440                        )
441                        for n in ind["ind"]
442                    ]
443                ),
444                " ".join(
445                    [
446                        str(
447                            self[n].highest_score_compound.name
448                            if self[n].highest_score_compound
449                            else None
450                        )
451                        for n in ind["ind"]
452                    ]
453                ),
454            )
455            annot.set_text(text)
456
457        def hover(event):
458            vis = annot.get_visible()
459            if event.inaxes == ax:
460                cont, ind = sc.contains(event)
461                if cont:
462                    update_annot(ind)
463                    annot.set_visible(True)
464                    fig.canvas.draw_idle()
465                else:
466                    if vis:
467                        annot.set_visible(False)
468                        fig.canvas.draw_idle()
469
470        fig.canvas.mpl_connect("motion_notify_event", hover)
471
472        return ax
473
474    def to_excel(
475        self, out_file_path, write_mode="ab", write_metadata=True, id_label="corems:"
476    ):
477        """Export the GC-MS data to an Excel file.
478
479        This method exports the GC-MS data to an Excel file.
480
481        Parameters
482        ----------
483        out_file_path : str, pathlib.Path, or s3path.S3Path
484            Path object containing the file location.
485        write_mode : str, optional
486            Write mode. Defaults to 'ab'.
487        write_metadata : bool, optional
488            If True, write the metadata. Defaults to True.
489        id_label : str, optional
490            Label of the ID. Defaults to 'corems:'.
491
492        """
493
494        if isinstance(out_file_path, str):
495            out_file_path = Path(out_file_path)
496
497        exportMS = LowResGCMSExport(out_file_path, self)
498        exportMS.to_excel(
499            id_label=id_label, write_mode=write_mode, write_metadata=write_metadata
500        )
501
502        return out_file_path.with_suffix(".xlsx")
503
504    def to_csv(
505        self,
506        out_file_path,
507        separate_output=False,
508        write_metadata=True,
509        id_label="corems:",
510    ):
511        """Export the GC-MS data to a CSV file.
512
513        Parameters
514        ----------
515        out_file_path : str, pathlib.Path, or s3path.S3Path
516            Path object containing the file location.
517        separate_output : bool, optional
518            If True, separate the output. Defaults to False.
519        write_metadata : bool, optional
520            If True, write the metadata. Defaults to True.
521
522        """
523
524        if isinstance(out_file_path, str):
525            out_file_path = Path(out_file_path)
526
527        exportMS = LowResGCMSExport(out_file_path, self)
528        exportMS.to_csv(
529            id_label=id_label,
530            separate_output=separate_output,
531            write_metadata=write_metadata,
532        )
533
534        return out_file_path.with_suffix(".csv")
535
536    def to_pandas(self, out_file_path, write_metadata=True, id_label="corems:"):
537        """Export the GC-MS data to a Pandas dataframe.
538
539        Parameters
540        ----------
541        out_file_path : str, pathlib.Path, or s3path.S3Path
542            Path object containing the file location.
543        write_metadata : bool, optional
544            If True, write the metadata. Defaults to True.
545        id_label : str, optional
546            Label of the ID. Defaults to 'corems:'.
547
548        """
549
550        if isinstance(out_file_path, str):
551            out_file_path = Path(out_file_path)
552        # pickle dataframe (pkl extension)
553        exportMS = LowResGCMSExport(out_file_path, self)
554        exportMS.to_pandas(id_label=id_label, write_metadata=write_metadata)
555
556        return out_file_path.with_suffix(".pkl")
557
558    def to_parquet(self, out_file_path, write_metadata=True, id_label="corems:"):
559        """Export the GC-MS data to a Parquet file.
560
561        Parameters
562        ----------
563        out_file_path : str, pathlib.Path, or s3path.S3Path
564            Path object containing the file location.
565        write_metadata : bool, optional
566            If True, write the metadata. Defaults to True.
567        id_label : str, optional
568            Label of the ID. Defaults to 'corems:'.
569
570        Notes
571        -----
572        Requires ``pyarrow`` (or ``fastparquet``) for pandas Parquet I/O.
573        """
574
575        if isinstance(out_file_path, str):
576            out_file_path = Path(out_file_path)
577
578        exportMS = LowResGCMSExport(out_file_path, self)
579        exportMS.to_parquet(id_label=id_label, write_metadata=write_metadata)
580
581        return out_file_path.with_suffix(".parquet")
582
583    def to_dataframe(self, id_label="corems:"):
584        """Export the GC-MS data to a Pandas dataframe.
585
586        Parameters
587        ----------
588        id_label : str, optional
589            Label of the ID. Defaults to 'corems:'.
590
591        """
592
593        # returns pandas dataframe
594        exportMS = LowResGCMSExport(self.sample_name, self)
595        return exportMS.get_pandas_df(id_label=id_label)
596
597    def processing_stats(self):
598        """Return the processing statistics."""
599
600        # returns json string
601        exportMS = LowResGCMSExport(self.sample_name, self)
602        return exportMS.get_data_stats(self)
603
604    def parameters_json(self, id_label="corems:", output_path=" "):
605        """Return the parameters in JSON format.
606
607        Parameters
608        ----------
609        id_label : str, optional
610            Label of the ID. Defaults to 'corems:'.
611        output_path : str, optional
612            Path object containing the file location. Defaults to " ".
613        """
614
615        # returns json string
616        exportMS = LowResGCMSExport(self.sample_name, self)
617        return exportMS.get_parameters_json(self, id_label, output_path)
618
619    def to_json(self, id_label="corems:"):
620        """Export the GC-MS data to a JSON file.
621
622        Parameters
623        ----------
624        id_label : str, optional
625            Label of the ID. Defaults to 'corems:'.
626
627        """
628
629        # returns pandas dataframe
630        exportMS = LowResGCMSExport(self.sample_name, self)
631        return exportMS.get_json(id_label=id_label)
632
633    def to_hdf(self, id_label="corems:"):
634        """Export the GC-MS data to a HDF file.
635
636        Parameters
637        ----------
638        id_label : str, optional
639            Label of the ID. Defaults to 'corems:'.
640
641        """
642
643        # returns pandas dataframe
644        exportMS = LowResGCMSExport(self.sample_name, self)
645        return exportMS.to_hdf(id_label=id_label)
646
647    def plot_chromatogram(self, ax=None, color="blue"):  # pragma: no cover
648        """Plot the chromatogram.
649
650        Parameters
651        ----------
652        ax : matplotlib.axes.Axes, optional
653            Axes object to plot the chromatogram. Defaults to None.
654        color : str, optional
655            Color of the chromatogram. Defaults to 'blue'.
656
657        """
658
659        import matplotlib.pyplot as plt
660
661        if ax is None:
662            ax = plt.gca()
663
664        ax.plot(self.retention_time, self.tic, color=color)
665        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
666
667        return ax
668
669    def plot_smoothed_chromatogram(self, ax=None, color="green"):  # pragma: no cover
670        """Plot the smoothed chromatogram.
671
672        Parameters
673        ----------
674        ax : matplotlib.axes.Axes, optional
675            Axes object to plot the smoothed chromatogram. Defaults to None.
676        color : str, optional
677            Color of the smoothed chromatogram. Defaults to 'green'.
678
679        """
680
681        import matplotlib.pyplot as plt
682
683        if ax is None:
684            ax = plt.gca()
685
686        ax.plot(self.retention_time, self.smooth_tic(self.tic), color=color)
687
688        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
689
690        return ax
691
692    def plot_detected_baseline(self, ax=None, color="blue"):  # pragma: no cover
693        """Plot the detected baseline.
694
695        Parameters
696        ----------
697        ax : matplotlib.axes.Axes, optional
698            Axes object to plot the detected baseline. Defaults to None.
699        color : str, optional
700            Color of the detected baseline. Defaults to 'blue'.
701
702        """
703
704        import matplotlib.pyplot as plt
705
706        if ax is None:
707            ax = plt.gca()
708
709        max_height = self.chromatogram_settings.peak_height_max_percent
710        max_prominence = self.chromatogram_settings.peak_max_prominence_percent
711
712        baseline = sp.baseline_detector(
713            self.tic, self.retention_time, max_height, max_prominence
714        )
715        ax.plot(self.retention_time, color=color)
716        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
717
718        return ax
719
720    def plot_baseline_subtraction(self, ax=None, color="black"):  # pragma: no cover
721        """Plot the baseline subtraction.
722
723        Parameters
724        ----------
725        ax : matplotlib.axes.Axes, optional
726            Axes object to plot the baseline subtraction. Defaults to None.
727        color : str, optional
728            Color of the baseline subtraction. Defaults to 'black'.
729
730        """
731
732        import matplotlib.pyplot as plt
733
734        if ax is None:
735            ax = plt.gca()
736
737        max_height = self.chromatogram_settings.peak_height_max_percent
738
739        max_prominence = self.chromatogram_settings.peak_max_prominence_percent
740
741        x = self.tic + sp.baseline_detector(
742            self.tic, self.retention_time, max_height, max_prominence
743        )
744
745        ax.plot(self.retention_time, x, color=color)
746
747        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
748
749        return ax
750
751    def peaks_rt_tic(self, json_string=False):
752        """Return the peaks, retention time, and total ion chromatogram.
753
754        Parameters
755        ----------
756        json_string : bool, optional
757            If True, return the peaks, retention time, and total ion chromatogram in JSON format. Defaults to False.
758
759        """
760
761        peaks_list = dict()
762
763        all_candidates_data = {}
764
765        all_peaks_data = {}
766
767        for gcms_peak in self.sorted_gcpeaks:
768            dict_data = {
769                "rt": gcms_peak.rt_list,
770                "tic": gcms_peak.tic_list,
771                "mz": gcms_peak.mass_spectrum.mz_exp.tolist(),
772                "abundance": gcms_peak.mass_spectrum.abundance.tolist(),
773                "candidate_names": gcms_peak.compound_names,
774            }
775
776            peaks_list[gcms_peak.retention_time] = dict_data
777
778            for compound in gcms_peak:
779                if compound.name not in all_candidates_data.keys():
780                    mz = array(compound.mz).tolist()
781                    abundance = array(compound.abundance).tolist()
782                    data = {"mz": mz, "abundance": abundance}
783                    all_candidates_data[compound.name] = data
784
785        all_peaks_data["peak_data"] = peaks_list
786        all_peaks_data["ref_data"] = all_candidates_data
787
788        if json_string:
789            return json.dumps(all_peaks_data)
790
791        else:
792            return all_peaks_data
793
794    def plot_processed_chromatogram(self, ax=None, color="black"):
795        """Plot the processed chromatogram.
796
797        Parameters
798        ----------
799        ax : matplotlib.axes.Axes, optional
800            Axes object to plot the processed chromatogram. Defaults to None.
801        color : str, optional
802            Color of the processed chromatogram. Defaults to 'black'.
803
804        """
805
806        import matplotlib.pyplot as plt
807
808        if ax is None:
809            ax = plt.gca()
810
811        ax.plot(self.retention_time, self.processed_tic, color=color)
812
813        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
814
815        return ax
 21class GCMSBase(GC_Calculations, MassDeconvolution):
 22    """Base class for GC-MS data processing.
 23
 24    Parameters
 25    ----
 26    file_location : str, pathlib.Path, or s3path.S3Path
 27        Path object containing the file location.
 28    analyzer : str, optional
 29        Name of the analyzer. Defaults to 'Unknown'.
 30    instrument_label : str, optional
 31        Label of the instrument. Defaults to 'Unknown'.
 32    sample_name : str, optional
 33        Name of the sample. If not provided, it is derived from the file location.
 34
 35    Attributes
 36    ------------
 37    file_location : pathlib.Path
 38        Path object containing the file location.
 39    sample_name : str
 40        Name of the sample.
 41    analyzer : str
 42        Name of the analyzer.
 43    instrument_label : str
 44        Label of the instrument.
 45    gcpeaks : list
 46        List of GCPeak objects.
 47    ri_pairs_ref : None
 48        Reference retention index pairs.
 49    cal_file_path : None
 50        Calibration file path.
 51    _parameters : GCMSParameters
 52        GC-MS parameters.
 53    _retention_time_list : list
 54        List of retention times.
 55    _scans_number_list : list
 56        List of scan numbers.
 57    _tic_list : list
 58        List of total ion chromatogram values.
 59    _ms : dict
 60        Dictionary containing all mass spectra.
 61    _processed_tic : list
 62        List of processed total ion chromatogram values.
 63
 64    Methods
 65    -------
 66    * process_chromatogram(plot_res=False). Process the chromatogram.
 67    * plot_gc_peaks(ax=None, color='red'). Plot the GC peaks.
 68    """
 69
 70    def __init__(
 71        self,
 72        file_location,
 73        analyzer="Unknown",
 74        instrument_label="Unknown",
 75        sample_name=None,
 76    ):
 77        if isinstance(file_location, str):
 78            # if obj is a string it defaults to create a Path obj, pass the S3Path if needed
 79            file_location = Path(file_location)
 80
 81        if not file_location.exists():
 82            raise FileExistsError("File does not exist: " + str(file_location))
 83
 84        self.file_location = file_location
 85
 86        if sample_name:
 87            self.sample_name = sample_name
 88        else:
 89            self.sample_name = file_location.stem
 90
 91        self.analyzer = analyzer
 92        self.instrument_label = instrument_label
 93        self._init_settings()
 94
 95        self._retention_time_list = []
 96        self._scans_number_list = []
 97        self._tic_list = []
 98
 99        # all scans
100        self._ms = {}
101
102        # after peak detection
103        self._processed_tic = []
104        self.gcpeaks = []
105
106        self.ri_pairs_ref = None
107        self.cal_file_path = None
108
109    def _init_settings(self):
110        """Initialize the settings for GC_Class.
111
112        This method initializes the settings for the GC_Class object using the GCMSParameters class.
113        """
114        self._parameters = GCMSParameters()
115
116    def __len__(self):
117        """Return the number of GC peaks in the GC_Class object."""
118        return len(self.gcpeaks)
119
120    def __getitem__(self, scan_number) -> GCPeak:
121        """Return the GCPeak with the given scan number."""
122        return self.gcpeaks[scan_number]
123
124    # def __iter__(self):
125
126    #     return iter(self.gcpeaks.values())
127
128    def process_chromatogram(self, plot_res=False):
129        """Process the chromatogram.
130
131        This method processes the chromatogram.
132
133        Parameters
134        ----------
135        plot_res : bool, optional
136            If True, plot the results. Defaults to False.
137        """
138
139        # tic = self.tic - self.baseline_detector(self.tic)
140
141        self._processed_tic = self.smooth_tic(self.tic)
142
143        for index, tic in enumerate(self._processed_tic):
144            self._ms[index]._processed_tic = tic
145
146        # self.second_derivative_threshold(self._processed_tic)
147
148        if self.chromatogram_settings.use_deconvolution:
149            self.run_deconvolution(plot_res=False)
150
151        else:
152            peaks_index = self.centroid_detector(
153                self._processed_tic, self.retention_time
154            )
155
156            for i in peaks_index:
157                apex_index = i[1]
158
159                gc_peak = GCPeak(self, self._ms[apex_index], i)
160
161                gc_peak.calc_area(self._processed_tic, 1)
162
163                self.gcpeaks.append(gc_peak)
164
165                # self.gcpeaks[self.scans_number[apex_index]] = gc_peak
166
167    def add_mass_spectrum(self, mass_spec):
168        """Add a mass spectrum to the GC-MS object.
169
170        This method adds a mass spectrum to the GC-MS object.
171
172        Parameters
173        ----------
174        mass_spec : MassSpectrum
175            Mass spectrum to be added.
176        """
177
178        self._ms[mass_spec.scan_number] = mass_spec
179
180    def set_tic_list_from_data(self):
181        """Set the total ion chromatogram list from the mass spectra data within the GC-MS data object."""
182
183        self.tic = [self._ms.get(i).tic for i in self.scans_number]
184
185        # self.set_tic_list([self._ms.get(i).get_sumed_signal_to_noise() for i in self.get_scans_number()])
186
187    def set_retention_time_from_data(self):
188        """Set the retention time list from the mass spectra data within the GC-MS data object."""
189
190        retention_time_list = []
191
192        for key_ms in sorted(self._ms.keys()):
193            retention_time_list.append(self._ms.get(key_ms).retention_time)
194
195        self.retention_time = retention_time_list
196
197        # self.set_retention_time_list(sorted(self._ms.keys()))
198
199    def set_scans_number_from_data(self):
200        """Set the scan number list from the mass spectra data within the GC-MS data object."""
201
202        self.scans_number = sorted(self._ms.keys())
203
204    @property
205    def parameters(self):
206        """GCMS Parameters"""
207        return self._parameters
208
209    @parameters.setter
210    def parameters(self, gcms_parameters_instance):
211        self._parameters = gcms_parameters_instance
212
213    # Note: maintaining `parameter` for backwards compatibility,
214    # but proper usage would reference `parameters` to conform
215    # to other classes.
216    @property
217    def parameter(self):
218        """GCMS Parameters"""
219        return self._parameters
220
221    @parameter.setter
222    def parameter(self, gcms_parameters_instance):
223        self._parameters = gcms_parameters_instance
224
225    @property
226    def molecular_search_settings(self):
227        """Molecular Search Settings"""
228        return self.parameters.molecular_search
229
230    @molecular_search_settings.setter
231    def molecular_search_settings(self, settings_class_instance):
232        self.parameters.molecular_search = settings_class_instance
233
234    @property
235    def chromatogram_settings(self):
236        """Chromatogram Settings"""
237        return self.parameters.gc_ms
238
239    @chromatogram_settings.setter
240    def chromatogram_settings(self, settings_class_instance):
241        self.parameters.gc_ms = settings_class_instance
242
243    @property
244    def scans_number(self):
245        """Scans Number"""
246        return self._scans_number_list
247
248    @property
249    def retention_time(self):
250        """Retention Time"""
251        return self._retention_time_list
252
253    @property
254    def processed_tic(self):
255        """Processed Total Ion Current"""
256        return self._processed_tic
257
258    @property
259    def tic(self):
260        """Total Ion Current"""
261        return self._tic_list
262
263    @property
264    def max_tic(self):
265        """Maximum Total Ion Current"""
266        return max([gc_peak.tic for gc_peak in self])
267
268    @property
269    def min_tic(self):
270        """Minimum Total Ion Current"""
271        return min([gc_peak.tic for gc_peak in self])
272
273    @property
274    def dynamic_range(self):
275        """Dynamic Range of the Total Ion Current"""
276        return self.max_tic / self.min_tic
277
278    @property
279    def matched_peaks(self):
280        """Matched Peaks"""
281        return [gc_peak for gc_peak in self if gc_peak]
282
283    @property
284    def sorted_gcpeaks(self):
285        """Sorted GC Peaks, by retention time"""
286        return sorted(self, key=lambda g: g.retention_time)
287
288    @property
289    def unique_metabolites(self):
290        """Unique Metabolites"""
291        metabolites = set()
292        for gc_peak in self:
293            if gc_peak:
294                for compound_obj in gc_peak:
295                    metabolites.add(compound_obj.name)
296
297        return metabolites
298
299    @property
300    def metabolites_data(self):
301        """Metabolites Data"""
302        metabolites = {}
303        for gc_peak in self:
304            if gc_peak:
305                for compound_obj in gc_peak:
306                    if compound_obj.name in metabolites.keys():
307                        current_score = metabolites[compound_obj.name][
308                            "highest_similarity_score"
309                        ]
310                        compound_score = compound_obj.spectral_similarity_score
311                        metabolites[compound_obj.name]["highest_similarity_score"] = (
312                            compound_score
313                            if compound_score > current_score
314                            else current_score
315                        )
316
317                    else:
318                        if compound_obj.metadata:
319                            metabolites[compound_obj.name] = {
320                                "name": compound_obj.name,
321                                "highest_similarity_score": compound_obj.spectral_similarity_score,
322                                "casno": compound_obj.metadata.cas,
323                                "kegg": compound_obj.metadata.kegg,
324                                "inchi": compound_obj.metadata.inchi,
325                                "inchi_key": compound_obj.metadata.inchikey,
326                                "chebi": compound_obj.metadata.chebi,
327                                "smiles": compound_obj.metadata.smiles,
328                            }
329                        else:
330                            metabolites[compound_obj.name] = {
331                                "name": compound_obj.name,
332                                "highest_similarity_score": compound_obj.spectral_similarity_score,
333                                "casno": "",
334                                "kegg": "",
335                                "inchi": "",
336                                "inchikey": "",
337                                "chebi": "",
338                                "smiles": "",
339                            }
340
341        return list(metabolites.values())
342
343    @property
344    def no_matched_peaks(self):
345        """Peaks with no Matched Metabolites"""
346        return [peak for peak in self if not peak]
347
348    @retention_time.setter
349    def retention_time(self, alist):
350        # self._retention_time_list = linspace(0, 80, num=len(self._scans_number_list))
351        self._retention_time_list = alist
352
353    @scans_number.setter
354    def scans_number(self, alist):
355        self._scans_number_list = alist
356
357    @tic.setter
358    def tic(self, alist):
359        self._tic_list = array(alist)
360
361    def plot_gc_peaks(self, ax=None, color="red"):  # pragma: no cover
362        """Plot the GC peaks.
363
364        This method plots the GC peaks.
365
366        Parameters
367        ----------
368        ax : matplotlib.axes.Axes, optional
369            Axes object to plot the GC peaks. Defaults to None.
370        color : str, optional
371            Color of the GC peaks. Defaults to 'red'.
372        """
373
374        import matplotlib.pyplot as plt
375
376        fig = plt.gcf()
377        if ax is None:
378            ax = plt.gca()
379
380        max_rts = [gc_peak.mass_spectrum.retention_time for gc_peak in self]
381        max_tics = [gc_peak.mass_spectrum.tic for gc_peak in self]
382
383        # min_rts = [self._ms[gc_peak.start_index].retention_time for gc_peak in self] + [self._ms[gc_peak.final_index].retention_time for gc_peak in self]
384        # min_tics = [self._ms[gc_peak.start_index].tic for gc_peak in self] + [self._ms[gc_peak.final_index].tic for gc_peak in self]
385        # sc = ax.scatter(min_rts, min_tics, color='yellow', linewidth=0, marker='v')
386
387        sc = ax.scatter(max_rts, max_tics, color=color, marker="v")
388
389        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
390
391        annot = ax.annotate(
392            "",
393            xy=(0, 0),
394            xytext=(20, 20),
395            textcoords="offset points",
396            bbox=dict(boxstyle="round", fc="w"),
397            arrowprops=dict(arrowstyle="->"),
398        )
399        annot.set_visible(False)
400        annot.get_bbox_patch().set_facecolor(("lightblue"))
401        annot.get_bbox_patch().set_alpha(0.8)
402
403        def update_annot(ind):
404            pos = sc.get_offsets()[ind["ind"][0]]
405            annot.xy = pos
406
407            text = "RT: {}\nRT Ref: {}\nRI: {}\nRI Ref: {}\nSimilarity Score: {}\nName: {}".format(
408                " ".join([str(round(self[n].retention_time, 2)) for n in ind["ind"]]),
409                " ".join(
410                    [
411                        str(
412                            round(self[n].highest_score_compound.retention_time, 2)
413                            if self[n].highest_score_compound
414                            else None
415                        )
416                        for n in ind["ind"]
417                    ]
418                ),
419                " ".join(
420                    [
421                        str(round(self[n].ri, 2) if self[n].ri else None)
422                        for n in ind["ind"]
423                    ]
424                ),
425                " ".join(
426                    [
427                        str(
428                            round(self[n].highest_score_compound.ri, 2)
429                            if self[n].highest_score_compound
430                            else None
431                        )
432                        for n in ind["ind"]
433                    ]
434                ),
435                " ".join(
436                    [
437                        str(
438                            round(self[n].highest_score_compound.similarity_score, 4)
439                            if self[n].highest_score_compound
440                            else None
441                        )
442                        for n in ind["ind"]
443                    ]
444                ),
445                " ".join(
446                    [
447                        str(
448                            self[n].highest_score_compound.name
449                            if self[n].highest_score_compound
450                            else None
451                        )
452                        for n in ind["ind"]
453                    ]
454                ),
455            )
456            annot.set_text(text)
457
458        def hover(event):
459            vis = annot.get_visible()
460            if event.inaxes == ax:
461                cont, ind = sc.contains(event)
462                if cont:
463                    update_annot(ind)
464                    annot.set_visible(True)
465                    fig.canvas.draw_idle()
466                else:
467                    if vis:
468                        annot.set_visible(False)
469                        fig.canvas.draw_idle()
470
471        fig.canvas.mpl_connect("motion_notify_event", hover)
472
473        return ax
474
475    def to_excel(
476        self, out_file_path, write_mode="ab", write_metadata=True, id_label="corems:"
477    ):
478        """Export the GC-MS data to an Excel file.
479
480        This method exports the GC-MS data to an Excel file.
481
482        Parameters
483        ----------
484        out_file_path : str, pathlib.Path, or s3path.S3Path
485            Path object containing the file location.
486        write_mode : str, optional
487            Write mode. Defaults to 'ab'.
488        write_metadata : bool, optional
489            If True, write the metadata. Defaults to True.
490        id_label : str, optional
491            Label of the ID. Defaults to 'corems:'.
492
493        """
494
495        if isinstance(out_file_path, str):
496            out_file_path = Path(out_file_path)
497
498        exportMS = LowResGCMSExport(out_file_path, self)
499        exportMS.to_excel(
500            id_label=id_label, write_mode=write_mode, write_metadata=write_metadata
501        )
502
503        return out_file_path.with_suffix(".xlsx")
504
505    def to_csv(
506        self,
507        out_file_path,
508        separate_output=False,
509        write_metadata=True,
510        id_label="corems:",
511    ):
512        """Export the GC-MS data to a CSV file.
513
514        Parameters
515        ----------
516        out_file_path : str, pathlib.Path, or s3path.S3Path
517            Path object containing the file location.
518        separate_output : bool, optional
519            If True, separate the output. Defaults to False.
520        write_metadata : bool, optional
521            If True, write the metadata. Defaults to True.
522
523        """
524
525        if isinstance(out_file_path, str):
526            out_file_path = Path(out_file_path)
527
528        exportMS = LowResGCMSExport(out_file_path, self)
529        exportMS.to_csv(
530            id_label=id_label,
531            separate_output=separate_output,
532            write_metadata=write_metadata,
533        )
534
535        return out_file_path.with_suffix(".csv")
536
537    def to_pandas(self, out_file_path, write_metadata=True, id_label="corems:"):
538        """Export the GC-MS data to a Pandas dataframe.
539
540        Parameters
541        ----------
542        out_file_path : str, pathlib.Path, or s3path.S3Path
543            Path object containing the file location.
544        write_metadata : bool, optional
545            If True, write the metadata. Defaults to True.
546        id_label : str, optional
547            Label of the ID. Defaults to 'corems:'.
548
549        """
550
551        if isinstance(out_file_path, str):
552            out_file_path = Path(out_file_path)
553        # pickle dataframe (pkl extension)
554        exportMS = LowResGCMSExport(out_file_path, self)
555        exportMS.to_pandas(id_label=id_label, write_metadata=write_metadata)
556
557        return out_file_path.with_suffix(".pkl")
558
559    def to_parquet(self, out_file_path, write_metadata=True, id_label="corems:"):
560        """Export the GC-MS data to a Parquet file.
561
562        Parameters
563        ----------
564        out_file_path : str, pathlib.Path, or s3path.S3Path
565            Path object containing the file location.
566        write_metadata : bool, optional
567            If True, write the metadata. Defaults to True.
568        id_label : str, optional
569            Label of the ID. Defaults to 'corems:'.
570
571        Notes
572        -----
573        Requires ``pyarrow`` (or ``fastparquet``) for pandas Parquet I/O.
574        """
575
576        if isinstance(out_file_path, str):
577            out_file_path = Path(out_file_path)
578
579        exportMS = LowResGCMSExport(out_file_path, self)
580        exportMS.to_parquet(id_label=id_label, write_metadata=write_metadata)
581
582        return out_file_path.with_suffix(".parquet")
583
584    def to_dataframe(self, id_label="corems:"):
585        """Export the GC-MS data to a Pandas dataframe.
586
587        Parameters
588        ----------
589        id_label : str, optional
590            Label of the ID. Defaults to 'corems:'.
591
592        """
593
594        # returns pandas dataframe
595        exportMS = LowResGCMSExport(self.sample_name, self)
596        return exportMS.get_pandas_df(id_label=id_label)
597
598    def processing_stats(self):
599        """Return the processing statistics."""
600
601        # returns json string
602        exportMS = LowResGCMSExport(self.sample_name, self)
603        return exportMS.get_data_stats(self)
604
605    def parameters_json(self, id_label="corems:", output_path=" "):
606        """Return the parameters in JSON format.
607
608        Parameters
609        ----------
610        id_label : str, optional
611            Label of the ID. Defaults to 'corems:'.
612        output_path : str, optional
613            Path object containing the file location. Defaults to " ".
614        """
615
616        # returns json string
617        exportMS = LowResGCMSExport(self.sample_name, self)
618        return exportMS.get_parameters_json(self, id_label, output_path)
619
620    def to_json(self, id_label="corems:"):
621        """Export the GC-MS data to a JSON file.
622
623        Parameters
624        ----------
625        id_label : str, optional
626            Label of the ID. Defaults to 'corems:'.
627
628        """
629
630        # returns pandas dataframe
631        exportMS = LowResGCMSExport(self.sample_name, self)
632        return exportMS.get_json(id_label=id_label)
633
634    def to_hdf(self, id_label="corems:"):
635        """Export the GC-MS data to a HDF file.
636
637        Parameters
638        ----------
639        id_label : str, optional
640            Label of the ID. Defaults to 'corems:'.
641
642        """
643
644        # returns pandas dataframe
645        exportMS = LowResGCMSExport(self.sample_name, self)
646        return exportMS.to_hdf(id_label=id_label)
647
648    def plot_chromatogram(self, ax=None, color="blue"):  # pragma: no cover
649        """Plot the chromatogram.
650
651        Parameters
652        ----------
653        ax : matplotlib.axes.Axes, optional
654            Axes object to plot the chromatogram. Defaults to None.
655        color : str, optional
656            Color of the chromatogram. Defaults to 'blue'.
657
658        """
659
660        import matplotlib.pyplot as plt
661
662        if ax is None:
663            ax = plt.gca()
664
665        ax.plot(self.retention_time, self.tic, color=color)
666        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
667
668        return ax
669
670    def plot_smoothed_chromatogram(self, ax=None, color="green"):  # pragma: no cover
671        """Plot the smoothed chromatogram.
672
673        Parameters
674        ----------
675        ax : matplotlib.axes.Axes, optional
676            Axes object to plot the smoothed chromatogram. Defaults to None.
677        color : str, optional
678            Color of the smoothed chromatogram. Defaults to 'green'.
679
680        """
681
682        import matplotlib.pyplot as plt
683
684        if ax is None:
685            ax = plt.gca()
686
687        ax.plot(self.retention_time, self.smooth_tic(self.tic), color=color)
688
689        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
690
691        return ax
692
693    def plot_detected_baseline(self, ax=None, color="blue"):  # pragma: no cover
694        """Plot the detected baseline.
695
696        Parameters
697        ----------
698        ax : matplotlib.axes.Axes, optional
699            Axes object to plot the detected baseline. Defaults to None.
700        color : str, optional
701            Color of the detected baseline. Defaults to 'blue'.
702
703        """
704
705        import matplotlib.pyplot as plt
706
707        if ax is None:
708            ax = plt.gca()
709
710        max_height = self.chromatogram_settings.peak_height_max_percent
711        max_prominence = self.chromatogram_settings.peak_max_prominence_percent
712
713        baseline = sp.baseline_detector(
714            self.tic, self.retention_time, max_height, max_prominence
715        )
716        ax.plot(self.retention_time, color=color)
717        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
718
719        return ax
720
721    def plot_baseline_subtraction(self, ax=None, color="black"):  # pragma: no cover
722        """Plot the baseline subtraction.
723
724        Parameters
725        ----------
726        ax : matplotlib.axes.Axes, optional
727            Axes object to plot the baseline subtraction. Defaults to None.
728        color : str, optional
729            Color of the baseline subtraction. Defaults to 'black'.
730
731        """
732
733        import matplotlib.pyplot as plt
734
735        if ax is None:
736            ax = plt.gca()
737
738        max_height = self.chromatogram_settings.peak_height_max_percent
739
740        max_prominence = self.chromatogram_settings.peak_max_prominence_percent
741
742        x = self.tic + sp.baseline_detector(
743            self.tic, self.retention_time, max_height, max_prominence
744        )
745
746        ax.plot(self.retention_time, x, color=color)
747
748        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
749
750        return ax
751
752    def peaks_rt_tic(self, json_string=False):
753        """Return the peaks, retention time, and total ion chromatogram.
754
755        Parameters
756        ----------
757        json_string : bool, optional
758            If True, return the peaks, retention time, and total ion chromatogram in JSON format. Defaults to False.
759
760        """
761
762        peaks_list = dict()
763
764        all_candidates_data = {}
765
766        all_peaks_data = {}
767
768        for gcms_peak in self.sorted_gcpeaks:
769            dict_data = {
770                "rt": gcms_peak.rt_list,
771                "tic": gcms_peak.tic_list,
772                "mz": gcms_peak.mass_spectrum.mz_exp.tolist(),
773                "abundance": gcms_peak.mass_spectrum.abundance.tolist(),
774                "candidate_names": gcms_peak.compound_names,
775            }
776
777            peaks_list[gcms_peak.retention_time] = dict_data
778
779            for compound in gcms_peak:
780                if compound.name not in all_candidates_data.keys():
781                    mz = array(compound.mz).tolist()
782                    abundance = array(compound.abundance).tolist()
783                    data = {"mz": mz, "abundance": abundance}
784                    all_candidates_data[compound.name] = data
785
786        all_peaks_data["peak_data"] = peaks_list
787        all_peaks_data["ref_data"] = all_candidates_data
788
789        if json_string:
790            return json.dumps(all_peaks_data)
791
792        else:
793            return all_peaks_data
794
795    def plot_processed_chromatogram(self, ax=None, color="black"):
796        """Plot the processed chromatogram.
797
798        Parameters
799        ----------
800        ax : matplotlib.axes.Axes, optional
801            Axes object to plot the processed chromatogram. Defaults to None.
802        color : str, optional
803            Color of the processed chromatogram. Defaults to 'black'.
804
805        """
806
807        import matplotlib.pyplot as plt
808
809        if ax is None:
810            ax = plt.gca()
811
812        ax.plot(self.retention_time, self.processed_tic, color=color)
813
814        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
815
816        return ax

Base class for GC-MS data processing.

Parameters
  • file_location (str, pathlib.Path, or s3path.S3Path): Path object containing the file location.
  • analyzer (str, optional): Name of the analyzer. Defaults to 'Unknown'.
  • instrument_label (str, optional): Label of the instrument. Defaults to 'Unknown'.
  • sample_name (str, optional): Name of the sample. If not provided, it is derived from the file location.
Attributes
  • file_location (pathlib.Path): Path object containing the file location.
  • sample_name (str): Name of the sample.
  • analyzer (str): Name of the analyzer.
  • instrument_label (str): Label of the instrument.
  • gcpeaks (list): List of GCPeak objects.
  • ri_pairs_ref (None): Reference retention index pairs.
  • cal_file_path (None): Calibration file path.
  • _parameters (GCMSParameters): GC-MS parameters.
  • _retention_time_list (list): List of retention times.
  • _scans_number_list (list): List of scan numbers.
  • _tic_list (list): List of total ion chromatogram values.
  • _ms (dict): Dictionary containing all mass spectra.
  • _processed_tic (list): List of processed total ion chromatogram values.
Methods
  • process_chromatogram(plot_res=False). Process the chromatogram.
  • plot_gc_peaks(ax=None, color='red'). Plot the GC peaks.
GCMSBase( file_location, analyzer='Unknown', instrument_label='Unknown', sample_name=None)
 70    def __init__(
 71        self,
 72        file_location,
 73        analyzer="Unknown",
 74        instrument_label="Unknown",
 75        sample_name=None,
 76    ):
 77        if isinstance(file_location, str):
 78            # if obj is a string it defaults to create a Path obj, pass the S3Path if needed
 79            file_location = Path(file_location)
 80
 81        if not file_location.exists():
 82            raise FileExistsError("File does not exist: " + str(file_location))
 83
 84        self.file_location = file_location
 85
 86        if sample_name:
 87            self.sample_name = sample_name
 88        else:
 89            self.sample_name = file_location.stem
 90
 91        self.analyzer = analyzer
 92        self.instrument_label = instrument_label
 93        self._init_settings()
 94
 95        self._retention_time_list = []
 96        self._scans_number_list = []
 97        self._tic_list = []
 98
 99        # all scans
100        self._ms = {}
101
102        # after peak detection
103        self._processed_tic = []
104        self.gcpeaks = []
105
106        self.ri_pairs_ref = None
107        self.cal_file_path = None
file_location
analyzer
instrument_label
gcpeaks
ri_pairs_ref
cal_file_path
def process_chromatogram(self, plot_res=False):
128    def process_chromatogram(self, plot_res=False):
129        """Process the chromatogram.
130
131        This method processes the chromatogram.
132
133        Parameters
134        ----------
135        plot_res : bool, optional
136            If True, plot the results. Defaults to False.
137        """
138
139        # tic = self.tic - self.baseline_detector(self.tic)
140
141        self._processed_tic = self.smooth_tic(self.tic)
142
143        for index, tic in enumerate(self._processed_tic):
144            self._ms[index]._processed_tic = tic
145
146        # self.second_derivative_threshold(self._processed_tic)
147
148        if self.chromatogram_settings.use_deconvolution:
149            self.run_deconvolution(plot_res=False)
150
151        else:
152            peaks_index = self.centroid_detector(
153                self._processed_tic, self.retention_time
154            )
155
156            for i in peaks_index:
157                apex_index = i[1]
158
159                gc_peak = GCPeak(self, self._ms[apex_index], i)
160
161                gc_peak.calc_area(self._processed_tic, 1)
162
163                self.gcpeaks.append(gc_peak)
164
165                # self.gcpeaks[self.scans_number[apex_index]] = gc_peak

Process the chromatogram.

This method processes the chromatogram.

Parameters
  • plot_res (bool, optional): If True, plot the results. Defaults to False.
def add_mass_spectrum(self, mass_spec):
167    def add_mass_spectrum(self, mass_spec):
168        """Add a mass spectrum to the GC-MS object.
169
170        This method adds a mass spectrum to the GC-MS object.
171
172        Parameters
173        ----------
174        mass_spec : MassSpectrum
175            Mass spectrum to be added.
176        """
177
178        self._ms[mass_spec.scan_number] = mass_spec

Add a mass spectrum to the GC-MS object.

This method adds a mass spectrum to the GC-MS object.

Parameters
  • mass_spec (MassSpectrum): Mass spectrum to be added.
def set_tic_list_from_data(self):
180    def set_tic_list_from_data(self):
181        """Set the total ion chromatogram list from the mass spectra data within the GC-MS data object."""
182
183        self.tic = [self._ms.get(i).tic for i in self.scans_number]
184
185        # self.set_tic_list([self._ms.get(i).get_sumed_signal_to_noise() for i in self.get_scans_number()])

Set the total ion chromatogram list from the mass spectra data within the GC-MS data object.

def set_retention_time_from_data(self):
187    def set_retention_time_from_data(self):
188        """Set the retention time list from the mass spectra data within the GC-MS data object."""
189
190        retention_time_list = []
191
192        for key_ms in sorted(self._ms.keys()):
193            retention_time_list.append(self._ms.get(key_ms).retention_time)
194
195        self.retention_time = retention_time_list
196
197        # self.set_retention_time_list(sorted(self._ms.keys()))

Set the retention time list from the mass spectra data within the GC-MS data object.

def set_scans_number_from_data(self):
199    def set_scans_number_from_data(self):
200        """Set the scan number list from the mass spectra data within the GC-MS data object."""
201
202        self.scans_number = sorted(self._ms.keys())

Set the scan number list from the mass spectra data within the GC-MS data object.

parameters
204    @property
205    def parameters(self):
206        """GCMS Parameters"""
207        return self._parameters

GCMS Parameters

parameter
216    @property
217    def parameter(self):
218        """GCMS Parameters"""
219        return self._parameters

GCMS Parameters

molecular_search_settings
225    @property
226    def molecular_search_settings(self):
227        """Molecular Search Settings"""
228        return self.parameters.molecular_search

Molecular Search Settings

chromatogram_settings
234    @property
235    def chromatogram_settings(self):
236        """Chromatogram Settings"""
237        return self.parameters.gc_ms

Chromatogram Settings

scans_number
243    @property
244    def scans_number(self):
245        """Scans Number"""
246        return self._scans_number_list

Scans Number

retention_time
248    @property
249    def retention_time(self):
250        """Retention Time"""
251        return self._retention_time_list

Retention Time

processed_tic
253    @property
254    def processed_tic(self):
255        """Processed Total Ion Current"""
256        return self._processed_tic

Processed Total Ion Current

tic
258    @property
259    def tic(self):
260        """Total Ion Current"""
261        return self._tic_list

Total Ion Current

max_tic
263    @property
264    def max_tic(self):
265        """Maximum Total Ion Current"""
266        return max([gc_peak.tic for gc_peak in self])

Maximum Total Ion Current

min_tic
268    @property
269    def min_tic(self):
270        """Minimum Total Ion Current"""
271        return min([gc_peak.tic for gc_peak in self])

Minimum Total Ion Current

dynamic_range
273    @property
274    def dynamic_range(self):
275        """Dynamic Range of the Total Ion Current"""
276        return self.max_tic / self.min_tic

Dynamic Range of the Total Ion Current

matched_peaks
278    @property
279    def matched_peaks(self):
280        """Matched Peaks"""
281        return [gc_peak for gc_peak in self if gc_peak]

Matched Peaks

sorted_gcpeaks
283    @property
284    def sorted_gcpeaks(self):
285        """Sorted GC Peaks, by retention time"""
286        return sorted(self, key=lambda g: g.retention_time)

Sorted GC Peaks, by retention time

unique_metabolites
288    @property
289    def unique_metabolites(self):
290        """Unique Metabolites"""
291        metabolites = set()
292        for gc_peak in self:
293            if gc_peak:
294                for compound_obj in gc_peak:
295                    metabolites.add(compound_obj.name)
296
297        return metabolites

Unique Metabolites

metabolites_data
299    @property
300    def metabolites_data(self):
301        """Metabolites Data"""
302        metabolites = {}
303        for gc_peak in self:
304            if gc_peak:
305                for compound_obj in gc_peak:
306                    if compound_obj.name in metabolites.keys():
307                        current_score = metabolites[compound_obj.name][
308                            "highest_similarity_score"
309                        ]
310                        compound_score = compound_obj.spectral_similarity_score
311                        metabolites[compound_obj.name]["highest_similarity_score"] = (
312                            compound_score
313                            if compound_score > current_score
314                            else current_score
315                        )
316
317                    else:
318                        if compound_obj.metadata:
319                            metabolites[compound_obj.name] = {
320                                "name": compound_obj.name,
321                                "highest_similarity_score": compound_obj.spectral_similarity_score,
322                                "casno": compound_obj.metadata.cas,
323                                "kegg": compound_obj.metadata.kegg,
324                                "inchi": compound_obj.metadata.inchi,
325                                "inchi_key": compound_obj.metadata.inchikey,
326                                "chebi": compound_obj.metadata.chebi,
327                                "smiles": compound_obj.metadata.smiles,
328                            }
329                        else:
330                            metabolites[compound_obj.name] = {
331                                "name": compound_obj.name,
332                                "highest_similarity_score": compound_obj.spectral_similarity_score,
333                                "casno": "",
334                                "kegg": "",
335                                "inchi": "",
336                                "inchikey": "",
337                                "chebi": "",
338                                "smiles": "",
339                            }
340
341        return list(metabolites.values())

Metabolites Data

no_matched_peaks
343    @property
344    def no_matched_peaks(self):
345        """Peaks with no Matched Metabolites"""
346        return [peak for peak in self if not peak]

Peaks with no Matched Metabolites

def plot_gc_peaks(self, ax=None, color='red'):
361    def plot_gc_peaks(self, ax=None, color="red"):  # pragma: no cover
362        """Plot the GC peaks.
363
364        This method plots the GC peaks.
365
366        Parameters
367        ----------
368        ax : matplotlib.axes.Axes, optional
369            Axes object to plot the GC peaks. Defaults to None.
370        color : str, optional
371            Color of the GC peaks. Defaults to 'red'.
372        """
373
374        import matplotlib.pyplot as plt
375
376        fig = plt.gcf()
377        if ax is None:
378            ax = plt.gca()
379
380        max_rts = [gc_peak.mass_spectrum.retention_time for gc_peak in self]
381        max_tics = [gc_peak.mass_spectrum.tic for gc_peak in self]
382
383        # min_rts = [self._ms[gc_peak.start_index].retention_time for gc_peak in self] + [self._ms[gc_peak.final_index].retention_time for gc_peak in self]
384        # min_tics = [self._ms[gc_peak.start_index].tic for gc_peak in self] + [self._ms[gc_peak.final_index].tic for gc_peak in self]
385        # sc = ax.scatter(min_rts, min_tics, color='yellow', linewidth=0, marker='v')
386
387        sc = ax.scatter(max_rts, max_tics, color=color, marker="v")
388
389        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
390
391        annot = ax.annotate(
392            "",
393            xy=(0, 0),
394            xytext=(20, 20),
395            textcoords="offset points",
396            bbox=dict(boxstyle="round", fc="w"),
397            arrowprops=dict(arrowstyle="->"),
398        )
399        annot.set_visible(False)
400        annot.get_bbox_patch().set_facecolor(("lightblue"))
401        annot.get_bbox_patch().set_alpha(0.8)
402
403        def update_annot(ind):
404            pos = sc.get_offsets()[ind["ind"][0]]
405            annot.xy = pos
406
407            text = "RT: {}\nRT Ref: {}\nRI: {}\nRI Ref: {}\nSimilarity Score: {}\nName: {}".format(
408                " ".join([str(round(self[n].retention_time, 2)) for n in ind["ind"]]),
409                " ".join(
410                    [
411                        str(
412                            round(self[n].highest_score_compound.retention_time, 2)
413                            if self[n].highest_score_compound
414                            else None
415                        )
416                        for n in ind["ind"]
417                    ]
418                ),
419                " ".join(
420                    [
421                        str(round(self[n].ri, 2) if self[n].ri else None)
422                        for n in ind["ind"]
423                    ]
424                ),
425                " ".join(
426                    [
427                        str(
428                            round(self[n].highest_score_compound.ri, 2)
429                            if self[n].highest_score_compound
430                            else None
431                        )
432                        for n in ind["ind"]
433                    ]
434                ),
435                " ".join(
436                    [
437                        str(
438                            round(self[n].highest_score_compound.similarity_score, 4)
439                            if self[n].highest_score_compound
440                            else None
441                        )
442                        for n in ind["ind"]
443                    ]
444                ),
445                " ".join(
446                    [
447                        str(
448                            self[n].highest_score_compound.name
449                            if self[n].highest_score_compound
450                            else None
451                        )
452                        for n in ind["ind"]
453                    ]
454                ),
455            )
456            annot.set_text(text)
457
458        def hover(event):
459            vis = annot.get_visible()
460            if event.inaxes == ax:
461                cont, ind = sc.contains(event)
462                if cont:
463                    update_annot(ind)
464                    annot.set_visible(True)
465                    fig.canvas.draw_idle()
466                else:
467                    if vis:
468                        annot.set_visible(False)
469                        fig.canvas.draw_idle()
470
471        fig.canvas.mpl_connect("motion_notify_event", hover)
472
473        return ax

Plot the GC peaks.

This method plots the GC peaks.

Parameters
  • ax (matplotlib.axes.Axes, optional): Axes object to plot the GC peaks. Defaults to None.
  • color (str, optional): Color of the GC peaks. Defaults to 'red'.
def to_excel( self, out_file_path, write_mode='ab', write_metadata=True, id_label='corems:'):
475    def to_excel(
476        self, out_file_path, write_mode="ab", write_metadata=True, id_label="corems:"
477    ):
478        """Export the GC-MS data to an Excel file.
479
480        This method exports the GC-MS data to an Excel file.
481
482        Parameters
483        ----------
484        out_file_path : str, pathlib.Path, or s3path.S3Path
485            Path object containing the file location.
486        write_mode : str, optional
487            Write mode. Defaults to 'ab'.
488        write_metadata : bool, optional
489            If True, write the metadata. Defaults to True.
490        id_label : str, optional
491            Label of the ID. Defaults to 'corems:'.
492
493        """
494
495        if isinstance(out_file_path, str):
496            out_file_path = Path(out_file_path)
497
498        exportMS = LowResGCMSExport(out_file_path, self)
499        exportMS.to_excel(
500            id_label=id_label, write_mode=write_mode, write_metadata=write_metadata
501        )
502
503        return out_file_path.with_suffix(".xlsx")

Export the GC-MS data to an Excel file.

This method exports the GC-MS data to an Excel file.

Parameters
  • out_file_path (str, pathlib.Path, or s3path.S3Path): Path object containing the file location.
  • write_mode (str, optional): Write mode. Defaults to 'ab'.
  • write_metadata (bool, optional): If True, write the metadata. Defaults to True.
  • id_label (str, optional): Label of the ID. Defaults to 'corems:'.
def to_csv( self, out_file_path, separate_output=False, write_metadata=True, id_label='corems:'):
505    def to_csv(
506        self,
507        out_file_path,
508        separate_output=False,
509        write_metadata=True,
510        id_label="corems:",
511    ):
512        """Export the GC-MS data to a CSV file.
513
514        Parameters
515        ----------
516        out_file_path : str, pathlib.Path, or s3path.S3Path
517            Path object containing the file location.
518        separate_output : bool, optional
519            If True, separate the output. Defaults to False.
520        write_metadata : bool, optional
521            If True, write the metadata. Defaults to True.
522
523        """
524
525        if isinstance(out_file_path, str):
526            out_file_path = Path(out_file_path)
527
528        exportMS = LowResGCMSExport(out_file_path, self)
529        exportMS.to_csv(
530            id_label=id_label,
531            separate_output=separate_output,
532            write_metadata=write_metadata,
533        )
534
535        return out_file_path.with_suffix(".csv")

Export the GC-MS data to a CSV file.

Parameters
  • out_file_path (str, pathlib.Path, or s3path.S3Path): Path object containing the file location.
  • separate_output (bool, optional): If True, separate the output. Defaults to False.
  • write_metadata (bool, optional): If True, write the metadata. Defaults to True.
def to_pandas(self, out_file_path, write_metadata=True, id_label='corems:'):
537    def to_pandas(self, out_file_path, write_metadata=True, id_label="corems:"):
538        """Export the GC-MS data to a Pandas dataframe.
539
540        Parameters
541        ----------
542        out_file_path : str, pathlib.Path, or s3path.S3Path
543            Path object containing the file location.
544        write_metadata : bool, optional
545            If True, write the metadata. Defaults to True.
546        id_label : str, optional
547            Label of the ID. Defaults to 'corems:'.
548
549        """
550
551        if isinstance(out_file_path, str):
552            out_file_path = Path(out_file_path)
553        # pickle dataframe (pkl extension)
554        exportMS = LowResGCMSExport(out_file_path, self)
555        exportMS.to_pandas(id_label=id_label, write_metadata=write_metadata)
556
557        return out_file_path.with_suffix(".pkl")

Export the GC-MS data to a Pandas dataframe.

Parameters
  • out_file_path (str, pathlib.Path, or s3path.S3Path): Path object containing the file location.
  • write_metadata (bool, optional): If True, write the metadata. Defaults to True.
  • id_label (str, optional): Label of the ID. Defaults to 'corems:'.
def to_parquet(self, out_file_path, write_metadata=True, id_label='corems:'):
559    def to_parquet(self, out_file_path, write_metadata=True, id_label="corems:"):
560        """Export the GC-MS data to a Parquet file.
561
562        Parameters
563        ----------
564        out_file_path : str, pathlib.Path, or s3path.S3Path
565            Path object containing the file location.
566        write_metadata : bool, optional
567            If True, write the metadata. Defaults to True.
568        id_label : str, optional
569            Label of the ID. Defaults to 'corems:'.
570
571        Notes
572        -----
573        Requires ``pyarrow`` (or ``fastparquet``) for pandas Parquet I/O.
574        """
575
576        if isinstance(out_file_path, str):
577            out_file_path = Path(out_file_path)
578
579        exportMS = LowResGCMSExport(out_file_path, self)
580        exportMS.to_parquet(id_label=id_label, write_metadata=write_metadata)
581
582        return out_file_path.with_suffix(".parquet")

Export the GC-MS data to a Parquet file.

Parameters
  • out_file_path (str, pathlib.Path, or s3path.S3Path): Path object containing the file location.
  • write_metadata (bool, optional): If True, write the metadata. Defaults to True.
  • id_label (str, optional): Label of the ID. Defaults to 'corems:'.
Notes

Requires pyarrow (or fastparquet) for pandas Parquet I/O.

def to_dataframe(self, id_label='corems:'):
584    def to_dataframe(self, id_label="corems:"):
585        """Export the GC-MS data to a Pandas dataframe.
586
587        Parameters
588        ----------
589        id_label : str, optional
590            Label of the ID. Defaults to 'corems:'.
591
592        """
593
594        # returns pandas dataframe
595        exportMS = LowResGCMSExport(self.sample_name, self)
596        return exportMS.get_pandas_df(id_label=id_label)

Export the GC-MS data to a Pandas dataframe.

Parameters
  • id_label (str, optional): Label of the ID. Defaults to 'corems:'.
def processing_stats(self):
598    def processing_stats(self):
599        """Return the processing statistics."""
600
601        # returns json string
602        exportMS = LowResGCMSExport(self.sample_name, self)
603        return exportMS.get_data_stats(self)

Return the processing statistics.

def parameters_json(self, id_label='corems:', output_path=' '):
605    def parameters_json(self, id_label="corems:", output_path=" "):
606        """Return the parameters in JSON format.
607
608        Parameters
609        ----------
610        id_label : str, optional
611            Label of the ID. Defaults to 'corems:'.
612        output_path : str, optional
613            Path object containing the file location. Defaults to " ".
614        """
615
616        # returns json string
617        exportMS = LowResGCMSExport(self.sample_name, self)
618        return exportMS.get_parameters_json(self, id_label, output_path)

Return the parameters in JSON format.

Parameters
  • id_label (str, optional): Label of the ID. Defaults to 'corems:'.
  • output_path (str, optional): Path object containing the file location. Defaults to " ".
def to_json(self, id_label='corems:'):
620    def to_json(self, id_label="corems:"):
621        """Export the GC-MS data to a JSON file.
622
623        Parameters
624        ----------
625        id_label : str, optional
626            Label of the ID. Defaults to 'corems:'.
627
628        """
629
630        # returns pandas dataframe
631        exportMS = LowResGCMSExport(self.sample_name, self)
632        return exportMS.get_json(id_label=id_label)

Export the GC-MS data to a JSON file.

Parameters
  • id_label (str, optional): Label of the ID. Defaults to 'corems:'.
def to_hdf(self, id_label='corems:'):
634    def to_hdf(self, id_label="corems:"):
635        """Export the GC-MS data to a HDF file.
636
637        Parameters
638        ----------
639        id_label : str, optional
640            Label of the ID. Defaults to 'corems:'.
641
642        """
643
644        # returns pandas dataframe
645        exportMS = LowResGCMSExport(self.sample_name, self)
646        return exportMS.to_hdf(id_label=id_label)

Export the GC-MS data to a HDF file.

Parameters
  • id_label (str, optional): Label of the ID. Defaults to 'corems:'.
def plot_chromatogram(self, ax=None, color='blue'):
648    def plot_chromatogram(self, ax=None, color="blue"):  # pragma: no cover
649        """Plot the chromatogram.
650
651        Parameters
652        ----------
653        ax : matplotlib.axes.Axes, optional
654            Axes object to plot the chromatogram. Defaults to None.
655        color : str, optional
656            Color of the chromatogram. Defaults to 'blue'.
657
658        """
659
660        import matplotlib.pyplot as plt
661
662        if ax is None:
663            ax = plt.gca()
664
665        ax.plot(self.retention_time, self.tic, color=color)
666        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
667
668        return ax

Plot the chromatogram.

Parameters
  • ax (matplotlib.axes.Axes, optional): Axes object to plot the chromatogram. Defaults to None.
  • color (str, optional): Color of the chromatogram. Defaults to 'blue'.
def plot_smoothed_chromatogram(self, ax=None, color='green'):
670    def plot_smoothed_chromatogram(self, ax=None, color="green"):  # pragma: no cover
671        """Plot the smoothed chromatogram.
672
673        Parameters
674        ----------
675        ax : matplotlib.axes.Axes, optional
676            Axes object to plot the smoothed chromatogram. Defaults to None.
677        color : str, optional
678            Color of the smoothed chromatogram. Defaults to 'green'.
679
680        """
681
682        import matplotlib.pyplot as plt
683
684        if ax is None:
685            ax = plt.gca()
686
687        ax.plot(self.retention_time, self.smooth_tic(self.tic), color=color)
688
689        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
690
691        return ax

Plot the smoothed chromatogram.

Parameters
  • ax (matplotlib.axes.Axes, optional): Axes object to plot the smoothed chromatogram. Defaults to None.
  • color (str, optional): Color of the smoothed chromatogram. Defaults to 'green'.
def plot_detected_baseline(self, ax=None, color='blue'):
693    def plot_detected_baseline(self, ax=None, color="blue"):  # pragma: no cover
694        """Plot the detected baseline.
695
696        Parameters
697        ----------
698        ax : matplotlib.axes.Axes, optional
699            Axes object to plot the detected baseline. Defaults to None.
700        color : str, optional
701            Color of the detected baseline. Defaults to 'blue'.
702
703        """
704
705        import matplotlib.pyplot as plt
706
707        if ax is None:
708            ax = plt.gca()
709
710        max_height = self.chromatogram_settings.peak_height_max_percent
711        max_prominence = self.chromatogram_settings.peak_max_prominence_percent
712
713        baseline = sp.baseline_detector(
714            self.tic, self.retention_time, max_height, max_prominence
715        )
716        ax.plot(self.retention_time, color=color)
717        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
718
719        return ax

Plot the detected baseline.

Parameters
  • ax (matplotlib.axes.Axes, optional): Axes object to plot the detected baseline. Defaults to None.
  • color (str, optional): Color of the detected baseline. Defaults to 'blue'.
def plot_baseline_subtraction(self, ax=None, color='black'):
721    def plot_baseline_subtraction(self, ax=None, color="black"):  # pragma: no cover
722        """Plot the baseline subtraction.
723
724        Parameters
725        ----------
726        ax : matplotlib.axes.Axes, optional
727            Axes object to plot the baseline subtraction. Defaults to None.
728        color : str, optional
729            Color of the baseline subtraction. Defaults to 'black'.
730
731        """
732
733        import matplotlib.pyplot as plt
734
735        if ax is None:
736            ax = plt.gca()
737
738        max_height = self.chromatogram_settings.peak_height_max_percent
739
740        max_prominence = self.chromatogram_settings.peak_max_prominence_percent
741
742        x = self.tic + sp.baseline_detector(
743            self.tic, self.retention_time, max_height, max_prominence
744        )
745
746        ax.plot(self.retention_time, x, color=color)
747
748        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
749
750        return ax

Plot the baseline subtraction.

Parameters
  • ax (matplotlib.axes.Axes, optional): Axes object to plot the baseline subtraction. Defaults to None.
  • color (str, optional): Color of the baseline subtraction. Defaults to 'black'.
def peaks_rt_tic(self, json_string=False):
752    def peaks_rt_tic(self, json_string=False):
753        """Return the peaks, retention time, and total ion chromatogram.
754
755        Parameters
756        ----------
757        json_string : bool, optional
758            If True, return the peaks, retention time, and total ion chromatogram in JSON format. Defaults to False.
759
760        """
761
762        peaks_list = dict()
763
764        all_candidates_data = {}
765
766        all_peaks_data = {}
767
768        for gcms_peak in self.sorted_gcpeaks:
769            dict_data = {
770                "rt": gcms_peak.rt_list,
771                "tic": gcms_peak.tic_list,
772                "mz": gcms_peak.mass_spectrum.mz_exp.tolist(),
773                "abundance": gcms_peak.mass_spectrum.abundance.tolist(),
774                "candidate_names": gcms_peak.compound_names,
775            }
776
777            peaks_list[gcms_peak.retention_time] = dict_data
778
779            for compound in gcms_peak:
780                if compound.name not in all_candidates_data.keys():
781                    mz = array(compound.mz).tolist()
782                    abundance = array(compound.abundance).tolist()
783                    data = {"mz": mz, "abundance": abundance}
784                    all_candidates_data[compound.name] = data
785
786        all_peaks_data["peak_data"] = peaks_list
787        all_peaks_data["ref_data"] = all_candidates_data
788
789        if json_string:
790            return json.dumps(all_peaks_data)
791
792        else:
793            return all_peaks_data

Return the peaks, retention time, and total ion chromatogram.

Parameters
  • json_string (bool, optional): If True, return the peaks, retention time, and total ion chromatogram in JSON format. Defaults to False.
def plot_processed_chromatogram(self, ax=None, color='black'):
795    def plot_processed_chromatogram(self, ax=None, color="black"):
796        """Plot the processed chromatogram.
797
798        Parameters
799        ----------
800        ax : matplotlib.axes.Axes, optional
801            Axes object to plot the processed chromatogram. Defaults to None.
802        color : str, optional
803            Color of the processed chromatogram. Defaults to 'black'.
804
805        """
806
807        import matplotlib.pyplot as plt
808
809        if ax is None:
810            ax = plt.gca()
811
812        ax.plot(self.retention_time, self.processed_tic, color=color)
813
814        ax.set(xlabel="Retention Time (s)", ylabel="Total Ion Chromatogram")
815
816        return ax

Plot the processed chromatogram.

Parameters
  • ax (matplotlib.axes.Axes, optional): Axes object to plot the processed chromatogram. Defaults to None.
  • color (str, optional): Color of the processed chromatogram. Defaults to 'black'.