from typing import List, Iterable
from RIAssigner.data.Data import Data
from .ComputationMethod import ComputationMethod
[docs]
class Kovats(ComputationMethod):
"""Class to compute the Kovats retention index."""
[docs]
def compute(self, query: Data, reference: Data) -> List[Data.RetentionIndexType]:
"""Compute non-isothermal Kovats retention index.
For details see https://webbook.nist.gov/chemistry/gc-ri/.
Parameters
----------
query:
Dataset for which to compute retention indices.
reference:
Reference dataset with retention times and retention indices
Returns
-------
retention_indices: List[Data.RetentionIndexType]
List of computed retention indices
"""
self._check_data_args(query, reference)
index = 0
# Copy rts and ris and insert 0 in the beginning, so that interpolation always starts at 0,0 to the first reference compound.
reference_rts = [0.0] + list(reference.retention_times)
reference_ris = [0.0] + list(reference.retention_indices)
retention_indices = [self._compute_ri(target_rt, reference_rts, reference_ris, index) for target_rt in query.retention_times]
return retention_indices
[docs]
def _compute_ri(
self,
target_rt: Data.RetentionTimeType,
reference_rts: Iterable[Data.RetentionTimeType],
reference_ris: Iterable[Data.RetentionTimeType],
index: int,
) -> Data.RetentionIndexType:
"""Compute retention index for target retention time.
Args:
target_rt (Data.RetentionTimeType): Retention time for which to compute the index
reference_rts (Iterable[Data.RetentionTimeType]): Reference retention times
reference_ris (Iterable[Data.RetentionTimeType]): Reference retention indices
index (int): Current reference index
Returns:
Data.RetentionIndexType: Computed retention index
"""
ri = None
if Data.is_valid(target_rt):
index = _update_index(target_rt, reference_rts, index)
ri = _compute_kovats(target_rt, reference_rts, reference_ris, index)
return ri
[docs]
def _update_index(target_rt: float, reference_rts: Iterable[Data.RetentionTimeType], index: int):
"""Get the indices of previosly eluting and next eluting reference compounds.
Retention times in 'Data' objects are sorted in ascending order, so this method assumes
that 'reference_rt' is sorted in ascending order.
Parameters
----------
reference_rts
Retention times of reference compounds.
"""
if target_rt > max(reference_rts) or index >= len(reference_rts):
index = len(reference_rts) - 1
else:
while reference_rts[index] < target_rt:
index += 1
return index
[docs]
def _compute_kovats(
target_rt: float,
reference_rts: Iterable[Data.RetentionTimeType],
reference_ris: Iterable[Data.RetentionIndexType],
index: int,
) -> float:
"""Compute retention index according to Van den Dool (see https://webbook.nist.gov/chemistry/gc-ri/)
Args:
target_rt (float): Retention time for which to compute the RI
reference_rts (Iterable[Data.RetentionTimeType]): Reference data retention times
reference_ris (Iterable[Data.RetentionIndexType]): Reference data retention indices
index (int): Higher index of reference compound (n+1)
Returns:
Data.RetentionIndexType: Computed retention index
"""
term_a = target_rt - reference_rts[index - 1]
term_b = reference_rts[index] - reference_rts[index - 1]
factor = reference_ris[index] - reference_ris[index - 1]
ri = factor * term_a / term_b + reference_ris[index - 1]
return float(ri)