corems.chroma_peak.calc.ChromaPeakCalc

  1import numpy as np
  2from bisect import bisect_left
  3
  4__author__ = "Yuri E. Corilo"
  5__date__ = "March 11, 2020"
  6
  7
  8class GCPeakCalculation(object):
  9    """
 10    Class for performing peak calculations in GC chromatography.
 11
 12    Methods
 13    -------
 14    * `calc_area(self, tic: List[float], dx: float) -> None`: Calculate the area under the curve of the chromatogram.
 15    * `linear_ri(self, right_ri: float, left_ri: float, left_rt: float, right_rt: float) -> float`: Calculate the retention index using linear interpolation.
 16    * `calc_ri(self, rt_ri_pairs: List[Tuple[float, float]]) -> int`: Calculate the retention index based on the given retention time - retention index pairs.
 17    """
 18
 19    def calc_area(self, tic: list[float], dx: float) -> None:
 20        """
 21        Calculate the area under the curve of the chromatogram.
 22
 23        Parameters
 24        ----------
 25        tic : List[float]
 26            The total ion current (TIC) values.
 27        dx : float
 28            The spacing between data points.
 29        """
 30        yy = tic[self.start_scan : self.final_scan]
 31        self._area = np.trapz(yy, dx=dx)
 32
 33    def linear_ri(
 34        self, right_ri: float, left_ri: float, left_rt: float, right_rt: float
 35    ) -> float:
 36        """
 37        Calculate the retention index using linear interpolation.
 38
 39        Parameters
 40        ----------
 41        right_ri : float
 42            The retention index at the right reference point.
 43        left_ri : float
 44            The retention index at the left reference point.
 45        left_rt : float
 46            The retention time at the left reference point.
 47        right_rt : float
 48            The retention time at the right reference point.
 49
 50        Returns
 51        -------
 52        float
 53            The calculated retention index.
 54        """
 55        return left_ri + (
 56            (right_ri - left_ri)
 57            * (self.retention_time - left_rt)
 58            / (right_rt - left_rt)
 59        )
 60
 61    def calc_ri(self, rt_ri_pairs: list[tuple[float, float]]) -> None:
 62        """
 63        Calculate the retention index based on the given retention time - retention index pairs.
 64
 65        Parameters
 66        ----------
 67        rt_ri_pairs : List[Tuple[float, float]]
 68            The list of retention time - retention index pairs.
 69
 70        """
 71        current_rt = self.retention_time
 72
 73        rts = [rt_ri[0] for rt_ri in rt_ri_pairs]
 74        index = bisect_left(rts, current_rt)
 75
 76        if index >= len(rt_ri_pairs):
 77            index -= 1
 78
 79        current_ref = rt_ri_pairs[index]
 80
 81        if current_rt == current_ref[0]:
 82            self._ri = current_ref[1]
 83
 84        else:
 85            if index == 0:
 86                index += 1
 87
 88            left_rt = rt_ri_pairs[index - 1][0]
 89            left_ri = rt_ri_pairs[index - 1][1]
 90
 91            right_rt = rt_ri_pairs[index][0]
 92            right_ri = rt_ri_pairs[index][1]
 93
 94            self._ri = self.linear_ri(right_ri, left_ri, left_rt, right_rt)
 95
 96
 97class LCMSMassFeatureCalculation:
 98    """Class for performing peak calculations in LC-MS mass spectrometry.
 99
100    This class is intended to be used as a mixin class for the LCMSMassFeature class.
101    """
102
103    def calc_dispersity_index(self):
104        """
105        Calculate the dispersity index of the mass feature.
106
107        This function calculates the dispersity index of the mass feature and
108        stores the result in the `_dispersity_index` attribute. The dispersity index is calculated as the standard
109        deviation of the retention times that account for 50% of the cummulative intensity, starting from the most
110        intense point, as described in [1].
111
112        Returns
113        -------
114        None, stores the result in the `_dispersity_index` attribute of the class.
115
116        Raises
117        ------
118        ValueError
119            If the EIC data are not available.
120
121        References
122        ----------
123        1) Boiteau, Rene M., et al. "Relating Molecular Properties to the Persistence of Marine Dissolved
124        Organic Matter with Liquid Chromatography–Ultrahigh-Resolution Mass Spectrometry."
125        Environmental Science & Technology 58.7 (2024): 3267-3277.
126        """
127        # Check if the EIC data is available
128        if self.eic_list is None:
129            raise ValueError(
130                "EIC data are not available. Please add the EIC data first."
131            )
132
133        # Sort the EIC data and RT data by descending intensity
134        eic_in = self.eic_list.argsort()
135        sorted_eic = self.eic_list[eic_in[::-1]]
136        sorted_rt = self.eic_rt_list[eic_in[::-1]]
137
138        # Calculate the dispersity index
139        cum_sum = np.cumsum(sorted_eic) / np.sum(sorted_eic)
140        rt_summ = sorted_rt[np.where(cum_sum < 0.5)]
141        if len(rt_summ) > 1:
142            d = np.std(rt_summ)
143            self._dispersity_index = d
144        elif len(rt_summ) == 1:
145            self._dispersity_index = 0
146
147    def calc_fraction_height_width(self, fraction: float):
148        """
149        Calculate the height width of the mass feature at a specfic fraction of the maximum intensity.
150
151        This function returns a tuple with the minimum and maximum half-height width based on scan resolution.
152
153        Parameters
154        ----------
155        fraction : float
156            The fraction of the maximum intensity to calculate the height width.
157            For example, 0.5 will calculate the half-height width.
158
159        Returns
160        -------
161        Tuple[float, float, bool]
162            The minimum and maximum half-height width based on scan resolution (in minutes), and a boolean indicating if the width was estimated.
163        """
164
165        # Pull out the EIC data
166        eic = self._eic_data.eic_smoothed
167
168        # Find the indices of the maximum intensity on either side
169        max_index = np.where(self._eic_data.scans == self.apex_scan)[0][0]
170        left_index = max_index
171        right_index = max_index
172        while eic[left_index] > eic[max_index] * fraction and left_index > 0:
173            left_index -= 1
174        while (
175            eic[right_index] > eic[max_index] * fraction and right_index < len(eic) - 1
176        ):
177            right_index += 1
178
179        # Get the retention times of the indexes just below the half height
180        left_rt = self._eic_data.time[left_index]
181        right_rt = self._eic_data.time[right_index]
182
183        # If left_rt and right_rt are outside the bounds of the integration, set them to the bounds and set estimated to True
184        estimated = False
185        if left_rt < self.eic_rt_list[0]:
186            left_rt = self.eic_rt_list[0]
187            left_index = np.where(self._eic_data.scans == self._eic_data.apexes[0][0])[
188                0
189            ][0]
190            estimated = True
191        if right_rt > self.eic_rt_list[-1]:
192            right_rt = self.eic_rt_list[-1]
193            right_index = np.where(
194                self._eic_data.scans == self._eic_data.apexes[0][-1]
195            )[0][0]
196            estimated = True
197        half_height_width_max = right_rt - left_rt
198
199        # Get the retention times of the indexes just above the half height
200        left_rt = self._eic_data.time[left_index + 1]
201        right_rt = self._eic_data.time[right_index - 1]
202        half_height_width_min = right_rt - left_rt
203
204        return half_height_width_min, half_height_width_max, estimated
205
206    def calc_half_height_width(self, accept_estimated: bool = False):
207        """
208        Calculate the half-height width of the mass feature.
209
210        This function calculates the half-height width of the mass feature and
211        stores the result in the `_half_height_width` attribute
212
213        Returns
214        -------
215        None, stores the result in the `_half_height_width` attribute of the class.
216        """
217        min_, max_, estimated = self.calc_fraction_height_width(0.5)
218        if not estimated or accept_estimated:
219            self._half_height_width = np.array([min_, max_])
220
221    def calc_tailing_factor(self, accept_estimated: bool = False):
222        """
223        Calculate the peak asymmetry of the mass feature.
224
225        This function calculates the peak asymmetry of the mass feature and
226        stores the result in the `_tailing_factor` attribute.
227        Calculations completed at 5% of the peak height in accordance with the USP tailing factor calculation.
228
229        Returns
230        -------
231        None, stores the result in the `_tailing_factor` attribute of the class.
232
233        References
234        ----------
235        1) JIS K0124:2011 General rules for high performance liquid chromatography
236        2) JIS K0214:2013 Technical terms for analytical chemistry
237        """
238        # First calculate the width of the peak at 5% of the peak height
239        width_min, width_max, estimated = self.calc_fraction_height_width(0.05)
240
241        if not estimated or accept_estimated:
242            # Next calculate the width of the peak at 95% of the peak height
243            eic = self._eic_data.eic_smoothed
244            max_index = np.where(self._eic_data.scans == self.apex_scan)[0][0]
245            left_index = max_index
246            while eic[left_index] > eic[max_index] * 0.05 and left_index > 0:
247                left_index -= 1
248
249            left_half_time_min = (
250                self._eic_data.time[max_index] - self._eic_data.time[left_index]
251            )
252            left_half_time_max = (
253                self._eic_data.time[max_index] - self._eic_data.time[left_index + 1]
254            )
255
256            tailing_factor = np.mean([width_min, width_max]) / (
257                2 * np.mean([left_half_time_min, left_half_time_max])
258            )
259
260            self._tailing_factor = tailing_factor
class GCPeakCalculation:
 9class GCPeakCalculation(object):
10    """
11    Class for performing peak calculations in GC chromatography.
12
13    Methods
14    -------
15    * `calc_area(self, tic: List[float], dx: float) -> None`: Calculate the area under the curve of the chromatogram.
16    * `linear_ri(self, right_ri: float, left_ri: float, left_rt: float, right_rt: float) -> float`: Calculate the retention index using linear interpolation.
17    * `calc_ri(self, rt_ri_pairs: List[Tuple[float, float]]) -> int`: Calculate the retention index based on the given retention time - retention index pairs.
18    """
19
20    def calc_area(self, tic: list[float], dx: float) -> None:
21        """
22        Calculate the area under the curve of the chromatogram.
23
24        Parameters
25        ----------
26        tic : List[float]
27            The total ion current (TIC) values.
28        dx : float
29            The spacing between data points.
30        """
31        yy = tic[self.start_scan : self.final_scan]
32        self._area = np.trapz(yy, dx=dx)
33
34    def linear_ri(
35        self, right_ri: float, left_ri: float, left_rt: float, right_rt: float
36    ) -> float:
37        """
38        Calculate the retention index using linear interpolation.
39
40        Parameters
41        ----------
42        right_ri : float
43            The retention index at the right reference point.
44        left_ri : float
45            The retention index at the left reference point.
46        left_rt : float
47            The retention time at the left reference point.
48        right_rt : float
49            The retention time at the right reference point.
50
51        Returns
52        -------
53        float
54            The calculated retention index.
55        """
56        return left_ri + (
57            (right_ri - left_ri)
58            * (self.retention_time - left_rt)
59            / (right_rt - left_rt)
60        )
61
62    def calc_ri(self, rt_ri_pairs: list[tuple[float, float]]) -> None:
63        """
64        Calculate the retention index based on the given retention time - retention index pairs.
65
66        Parameters
67        ----------
68        rt_ri_pairs : List[Tuple[float, float]]
69            The list of retention time - retention index pairs.
70
71        """
72        current_rt = self.retention_time
73
74        rts = [rt_ri[0] for rt_ri in rt_ri_pairs]
75        index = bisect_left(rts, current_rt)
76
77        if index >= len(rt_ri_pairs):
78            index -= 1
79
80        current_ref = rt_ri_pairs[index]
81
82        if current_rt == current_ref[0]:
83            self._ri = current_ref[1]
84
85        else:
86            if index == 0:
87                index += 1
88
89            left_rt = rt_ri_pairs[index - 1][0]
90            left_ri = rt_ri_pairs[index - 1][1]
91
92            right_rt = rt_ri_pairs[index][0]
93            right_ri = rt_ri_pairs[index][1]
94
95            self._ri = self.linear_ri(right_ri, left_ri, left_rt, right_rt)

Class for performing peak calculations in GC chromatography.

Methods
  • calc_area(self, tic: List[float], dx: float) -> None: Calculate the area under the curve of the chromatogram.
  • linear_ri(self, right_ri: float, left_ri: float, left_rt: float, right_rt: float) -> float: Calculate the retention index using linear interpolation.
  • calc_ri(self, rt_ri_pairs: List[Tuple[float, float]]) -> int: Calculate the retention index based on the given retention time - retention index pairs.
def calc_area(self, tic: list[float], dx: float) -> None:
20    def calc_area(self, tic: list[float], dx: float) -> None:
21        """
22        Calculate the area under the curve of the chromatogram.
23
24        Parameters
25        ----------
26        tic : List[float]
27            The total ion current (TIC) values.
28        dx : float
29            The spacing between data points.
30        """
31        yy = tic[self.start_scan : self.final_scan]
32        self._area = np.trapz(yy, dx=dx)

Calculate the area under the curve of the chromatogram.

Parameters
  • tic (List[float]): The total ion current (TIC) values.
  • dx (float): The spacing between data points.
def linear_ri( self, right_ri: float, left_ri: float, left_rt: float, right_rt: float) -> float:
34    def linear_ri(
35        self, right_ri: float, left_ri: float, left_rt: float, right_rt: float
36    ) -> float:
37        """
38        Calculate the retention index using linear interpolation.
39
40        Parameters
41        ----------
42        right_ri : float
43            The retention index at the right reference point.
44        left_ri : float
45            The retention index at the left reference point.
46        left_rt : float
47            The retention time at the left reference point.
48        right_rt : float
49            The retention time at the right reference point.
50
51        Returns
52        -------
53        float
54            The calculated retention index.
55        """
56        return left_ri + (
57            (right_ri - left_ri)
58            * (self.retention_time - left_rt)
59            / (right_rt - left_rt)
60        )

Calculate the retention index using linear interpolation.

Parameters
  • right_ri (float): The retention index at the right reference point.
  • left_ri (float): The retention index at the left reference point.
  • left_rt (float): The retention time at the left reference point.
  • right_rt (float): The retention time at the right reference point.
Returns
  • float: The calculated retention index.
def calc_ri(self, rt_ri_pairs: list[tuple[float, float]]) -> None:
62    def calc_ri(self, rt_ri_pairs: list[tuple[float, float]]) -> None:
63        """
64        Calculate the retention index based on the given retention time - retention index pairs.
65
66        Parameters
67        ----------
68        rt_ri_pairs : List[Tuple[float, float]]
69            The list of retention time - retention index pairs.
70
71        """
72        current_rt = self.retention_time
73
74        rts = [rt_ri[0] for rt_ri in rt_ri_pairs]
75        index = bisect_left(rts, current_rt)
76
77        if index >= len(rt_ri_pairs):
78            index -= 1
79
80        current_ref = rt_ri_pairs[index]
81
82        if current_rt == current_ref[0]:
83            self._ri = current_ref[1]
84
85        else:
86            if index == 0:
87                index += 1
88
89            left_rt = rt_ri_pairs[index - 1][0]
90            left_ri = rt_ri_pairs[index - 1][1]
91
92            right_rt = rt_ri_pairs[index][0]
93            right_ri = rt_ri_pairs[index][1]
94
95            self._ri = self.linear_ri(right_ri, left_ri, left_rt, right_rt)

Calculate the retention index based on the given retention time - retention index pairs.

Parameters
  • rt_ri_pairs (List[Tuple[float, float]]): The list of retention time - retention index pairs.
class LCMSMassFeatureCalculation:
 98class LCMSMassFeatureCalculation:
 99    """Class for performing peak calculations in LC-MS mass spectrometry.
100
101    This class is intended to be used as a mixin class for the LCMSMassFeature class.
102    """
103
104    def calc_dispersity_index(self):
105        """
106        Calculate the dispersity index of the mass feature.
107
108        This function calculates the dispersity index of the mass feature and
109        stores the result in the `_dispersity_index` attribute. The dispersity index is calculated as the standard
110        deviation of the retention times that account for 50% of the cummulative intensity, starting from the most
111        intense point, as described in [1].
112
113        Returns
114        -------
115        None, stores the result in the `_dispersity_index` attribute of the class.
116
117        Raises
118        ------
119        ValueError
120            If the EIC data are not available.
121
122        References
123        ----------
124        1) Boiteau, Rene M., et al. "Relating Molecular Properties to the Persistence of Marine Dissolved
125        Organic Matter with Liquid Chromatography–Ultrahigh-Resolution Mass Spectrometry."
126        Environmental Science & Technology 58.7 (2024): 3267-3277.
127        """
128        # Check if the EIC data is available
129        if self.eic_list is None:
130            raise ValueError(
131                "EIC data are not available. Please add the EIC data first."
132            )
133
134        # Sort the EIC data and RT data by descending intensity
135        eic_in = self.eic_list.argsort()
136        sorted_eic = self.eic_list[eic_in[::-1]]
137        sorted_rt = self.eic_rt_list[eic_in[::-1]]
138
139        # Calculate the dispersity index
140        cum_sum = np.cumsum(sorted_eic) / np.sum(sorted_eic)
141        rt_summ = sorted_rt[np.where(cum_sum < 0.5)]
142        if len(rt_summ) > 1:
143            d = np.std(rt_summ)
144            self._dispersity_index = d
145        elif len(rt_summ) == 1:
146            self._dispersity_index = 0
147
148    def calc_fraction_height_width(self, fraction: float):
149        """
150        Calculate the height width of the mass feature at a specfic fraction of the maximum intensity.
151
152        This function returns a tuple with the minimum and maximum half-height width based on scan resolution.
153
154        Parameters
155        ----------
156        fraction : float
157            The fraction of the maximum intensity to calculate the height width.
158            For example, 0.5 will calculate the half-height width.
159
160        Returns
161        -------
162        Tuple[float, float, bool]
163            The minimum and maximum half-height width based on scan resolution (in minutes), and a boolean indicating if the width was estimated.
164        """
165
166        # Pull out the EIC data
167        eic = self._eic_data.eic_smoothed
168
169        # Find the indices of the maximum intensity on either side
170        max_index = np.where(self._eic_data.scans == self.apex_scan)[0][0]
171        left_index = max_index
172        right_index = max_index
173        while eic[left_index] > eic[max_index] * fraction and left_index > 0:
174            left_index -= 1
175        while (
176            eic[right_index] > eic[max_index] * fraction and right_index < len(eic) - 1
177        ):
178            right_index += 1
179
180        # Get the retention times of the indexes just below the half height
181        left_rt = self._eic_data.time[left_index]
182        right_rt = self._eic_data.time[right_index]
183
184        # If left_rt and right_rt are outside the bounds of the integration, set them to the bounds and set estimated to True
185        estimated = False
186        if left_rt < self.eic_rt_list[0]:
187            left_rt = self.eic_rt_list[0]
188            left_index = np.where(self._eic_data.scans == self._eic_data.apexes[0][0])[
189                0
190            ][0]
191            estimated = True
192        if right_rt > self.eic_rt_list[-1]:
193            right_rt = self.eic_rt_list[-1]
194            right_index = np.where(
195                self._eic_data.scans == self._eic_data.apexes[0][-1]
196            )[0][0]
197            estimated = True
198        half_height_width_max = right_rt - left_rt
199
200        # Get the retention times of the indexes just above the half height
201        left_rt = self._eic_data.time[left_index + 1]
202        right_rt = self._eic_data.time[right_index - 1]
203        half_height_width_min = right_rt - left_rt
204
205        return half_height_width_min, half_height_width_max, estimated
206
207    def calc_half_height_width(self, accept_estimated: bool = False):
208        """
209        Calculate the half-height width of the mass feature.
210
211        This function calculates the half-height width of the mass feature and
212        stores the result in the `_half_height_width` attribute
213
214        Returns
215        -------
216        None, stores the result in the `_half_height_width` attribute of the class.
217        """
218        min_, max_, estimated = self.calc_fraction_height_width(0.5)
219        if not estimated or accept_estimated:
220            self._half_height_width = np.array([min_, max_])
221
222    def calc_tailing_factor(self, accept_estimated: bool = False):
223        """
224        Calculate the peak asymmetry of the mass feature.
225
226        This function calculates the peak asymmetry of the mass feature and
227        stores the result in the `_tailing_factor` attribute.
228        Calculations completed at 5% of the peak height in accordance with the USP tailing factor calculation.
229
230        Returns
231        -------
232        None, stores the result in the `_tailing_factor` attribute of the class.
233
234        References
235        ----------
236        1) JIS K0124:2011 General rules for high performance liquid chromatography
237        2) JIS K0214:2013 Technical terms for analytical chemistry
238        """
239        # First calculate the width of the peak at 5% of the peak height
240        width_min, width_max, estimated = self.calc_fraction_height_width(0.05)
241
242        if not estimated or accept_estimated:
243            # Next calculate the width of the peak at 95% of the peak height
244            eic = self._eic_data.eic_smoothed
245            max_index = np.where(self._eic_data.scans == self.apex_scan)[0][0]
246            left_index = max_index
247            while eic[left_index] > eic[max_index] * 0.05 and left_index > 0:
248                left_index -= 1
249
250            left_half_time_min = (
251                self._eic_data.time[max_index] - self._eic_data.time[left_index]
252            )
253            left_half_time_max = (
254                self._eic_data.time[max_index] - self._eic_data.time[left_index + 1]
255            )
256
257            tailing_factor = np.mean([width_min, width_max]) / (
258                2 * np.mean([left_half_time_min, left_half_time_max])
259            )
260
261            self._tailing_factor = tailing_factor

Class for performing peak calculations in LC-MS mass spectrometry.

This class is intended to be used as a mixin class for the LCMSMassFeature class.

def calc_dispersity_index(self):
104    def calc_dispersity_index(self):
105        """
106        Calculate the dispersity index of the mass feature.
107
108        This function calculates the dispersity index of the mass feature and
109        stores the result in the `_dispersity_index` attribute. The dispersity index is calculated as the standard
110        deviation of the retention times that account for 50% of the cummulative intensity, starting from the most
111        intense point, as described in [1].
112
113        Returns
114        -------
115        None, stores the result in the `_dispersity_index` attribute of the class.
116
117        Raises
118        ------
119        ValueError
120            If the EIC data are not available.
121
122        References
123        ----------
124        1) Boiteau, Rene M., et al. "Relating Molecular Properties to the Persistence of Marine Dissolved
125        Organic Matter with Liquid Chromatography–Ultrahigh-Resolution Mass Spectrometry."
126        Environmental Science & Technology 58.7 (2024): 3267-3277.
127        """
128        # Check if the EIC data is available
129        if self.eic_list is None:
130            raise ValueError(
131                "EIC data are not available. Please add the EIC data first."
132            )
133
134        # Sort the EIC data and RT data by descending intensity
135        eic_in = self.eic_list.argsort()
136        sorted_eic = self.eic_list[eic_in[::-1]]
137        sorted_rt = self.eic_rt_list[eic_in[::-1]]
138
139        # Calculate the dispersity index
140        cum_sum = np.cumsum(sorted_eic) / np.sum(sorted_eic)
141        rt_summ = sorted_rt[np.where(cum_sum < 0.5)]
142        if len(rt_summ) > 1:
143            d = np.std(rt_summ)
144            self._dispersity_index = d
145        elif len(rt_summ) == 1:
146            self._dispersity_index = 0

Calculate the dispersity index of the mass feature.

This function calculates the dispersity index of the mass feature and stores the result in the _dispersity_index attribute. The dispersity index is calculated as the standard deviation of the retention times that account for 50% of the cummulative intensity, starting from the most intense point, as described in [1].

Returns
  • None, stores the result in the _dispersity_index attribute of the class.
Raises
  • ValueError: If the EIC data are not available.
References

1) Boiteau, Rene M., et al. "Relating Molecular Properties to the Persistence of Marine Dissolved Organic Matter with Liquid Chromatography–Ultrahigh-Resolution Mass Spectrometry." Environmental Science & Technology 58.7 (2024): 3267-3277.

def calc_fraction_height_width(self, fraction: float):
148    def calc_fraction_height_width(self, fraction: float):
149        """
150        Calculate the height width of the mass feature at a specfic fraction of the maximum intensity.
151
152        This function returns a tuple with the minimum and maximum half-height width based on scan resolution.
153
154        Parameters
155        ----------
156        fraction : float
157            The fraction of the maximum intensity to calculate the height width.
158            For example, 0.5 will calculate the half-height width.
159
160        Returns
161        -------
162        Tuple[float, float, bool]
163            The minimum and maximum half-height width based on scan resolution (in minutes), and a boolean indicating if the width was estimated.
164        """
165
166        # Pull out the EIC data
167        eic = self._eic_data.eic_smoothed
168
169        # Find the indices of the maximum intensity on either side
170        max_index = np.where(self._eic_data.scans == self.apex_scan)[0][0]
171        left_index = max_index
172        right_index = max_index
173        while eic[left_index] > eic[max_index] * fraction and left_index > 0:
174            left_index -= 1
175        while (
176            eic[right_index] > eic[max_index] * fraction and right_index < len(eic) - 1
177        ):
178            right_index += 1
179
180        # Get the retention times of the indexes just below the half height
181        left_rt = self._eic_data.time[left_index]
182        right_rt = self._eic_data.time[right_index]
183
184        # If left_rt and right_rt are outside the bounds of the integration, set them to the bounds and set estimated to True
185        estimated = False
186        if left_rt < self.eic_rt_list[0]:
187            left_rt = self.eic_rt_list[0]
188            left_index = np.where(self._eic_data.scans == self._eic_data.apexes[0][0])[
189                0
190            ][0]
191            estimated = True
192        if right_rt > self.eic_rt_list[-1]:
193            right_rt = self.eic_rt_list[-1]
194            right_index = np.where(
195                self._eic_data.scans == self._eic_data.apexes[0][-1]
196            )[0][0]
197            estimated = True
198        half_height_width_max = right_rt - left_rt
199
200        # Get the retention times of the indexes just above the half height
201        left_rt = self._eic_data.time[left_index + 1]
202        right_rt = self._eic_data.time[right_index - 1]
203        half_height_width_min = right_rt - left_rt
204
205        return half_height_width_min, half_height_width_max, estimated

Calculate the height width of the mass feature at a specfic fraction of the maximum intensity.

This function returns a tuple with the minimum and maximum half-height width based on scan resolution.

Parameters
  • fraction (float): The fraction of the maximum intensity to calculate the height width. For example, 0.5 will calculate the half-height width.
Returns
  • Tuple[float, float, bool]: The minimum and maximum half-height width based on scan resolution (in minutes), and a boolean indicating if the width was estimated.
def calc_half_height_width(self, accept_estimated: bool = False):
207    def calc_half_height_width(self, accept_estimated: bool = False):
208        """
209        Calculate the half-height width of the mass feature.
210
211        This function calculates the half-height width of the mass feature and
212        stores the result in the `_half_height_width` attribute
213
214        Returns
215        -------
216        None, stores the result in the `_half_height_width` attribute of the class.
217        """
218        min_, max_, estimated = self.calc_fraction_height_width(0.5)
219        if not estimated or accept_estimated:
220            self._half_height_width = np.array([min_, max_])

Calculate the half-height width of the mass feature.

This function calculates the half-height width of the mass feature and stores the result in the _half_height_width attribute

Returns
  • None, stores the result in the _half_height_width attribute of the class.
def calc_tailing_factor(self, accept_estimated: bool = False):
222    def calc_tailing_factor(self, accept_estimated: bool = False):
223        """
224        Calculate the peak asymmetry of the mass feature.
225
226        This function calculates the peak asymmetry of the mass feature and
227        stores the result in the `_tailing_factor` attribute.
228        Calculations completed at 5% of the peak height in accordance with the USP tailing factor calculation.
229
230        Returns
231        -------
232        None, stores the result in the `_tailing_factor` attribute of the class.
233
234        References
235        ----------
236        1) JIS K0124:2011 General rules for high performance liquid chromatography
237        2) JIS K0214:2013 Technical terms for analytical chemistry
238        """
239        # First calculate the width of the peak at 5% of the peak height
240        width_min, width_max, estimated = self.calc_fraction_height_width(0.05)
241
242        if not estimated or accept_estimated:
243            # Next calculate the width of the peak at 95% of the peak height
244            eic = self._eic_data.eic_smoothed
245            max_index = np.where(self._eic_data.scans == self.apex_scan)[0][0]
246            left_index = max_index
247            while eic[left_index] > eic[max_index] * 0.05 and left_index > 0:
248                left_index -= 1
249
250            left_half_time_min = (
251                self._eic_data.time[max_index] - self._eic_data.time[left_index]
252            )
253            left_half_time_max = (
254                self._eic_data.time[max_index] - self._eic_data.time[left_index + 1]
255            )
256
257            tailing_factor = np.mean([width_min, width_max]) / (
258                2 * np.mean([left_half_time_min, left_half_time_max])
259            )
260
261            self._tailing_factor = tailing_factor

Calculate the peak asymmetry of the mass feature.

This function calculates the peak asymmetry of the mass feature and stores the result in the _tailing_factor attribute. Calculations completed at 5% of the peak height in accordance with the USP tailing factor calculation.

Returns
  • None, stores the result in the _tailing_factor attribute of the class.
References

1) JIS K0124:2011 General rules for high performance liquid chromatography 2) JIS K0214:2013 Technical terms for analytical chemistry