from copy import deepcopy
from typing import List, Tuple
from enum import Enum
[docs]class MatchType(Enum):
shifted = 1
unshifted = 2
[docs]class Match:
"""
Class for Match
Attributes
----------
first_peak_mz : int
mz of the peak in the first spectrum
second_peak_mz : int
mz of the peak in the second spectrum
match_type : MatchType
Type of the match
"""
[docs] def __init__(self, first_peak_mz:int, second_peak_mz:int, match_type: MatchType):
"""
Initialize the Match object.
Parameters
----------
first_peak_mz : int
m/z of the first peak
second_peak_mz : int
m/z of the second peak
match_type : MatchType
Type of the match
Notes
-----
if you need matches with more information, create a new class and inherit from this class.
"""
self.first_peak_mz = first_peak_mz
self.second_peak_mz = second_peak_mz
self.match_type = match_type
def __repr__(self):
return f"Match({self.first_peak_mz}, {self.second_peak_mz}, {self.match_type})"
[docs] def copy(self):
"""
Create a copy of the Match object
"""
return Match(self.first_peak_mz, self.second_peak_mz, self.match_type)
[docs]class EdgeDetail:
"""
Class for Edge Details
Arguments
---------
number_of_modifications : int
Number of modifications, -1 for unknown
match_score : float
Match score, how well the two spectra match
matches : List[Match]
List of matches, each match is a tuple of two peak m/z values and the match type. It is
important to note that match has directionality. The first peak m/z is from the first
node of the edge and the second peak m/z is from the second node of the edge.
"""
[docs] def __init__(self, number_of_modifications: int = -1, match_score: float = 0, matches: List[Match] = None, start_spectrum_id: str = None, end_spectrum_id: str = None, start_compound_id: str = None, end_compound_id: str = None):
"""
Initialize the EdgeDetail object.
Parameters
----------
number_of_modifications : int
Number of modifications, -1 for unknown
match_score : float
Match score, how well the two spectra match
matches : List[Match]
List of matches, each match is a tuple of two peak m/z values and the match type. It is
important to note that match has directionality. The first peak m/z is from the first
node of the edge and the second peak m/z is from the second node of the edge.
"""
self.start_spectrum_id = start_spectrum_id
self.end_spectrum_id = end_spectrum_id
self.start_compound_id = start_compound_id
self.end_compound_id = end_compound_id
self.number_of_modifications = number_of_modifications
self.match_score = match_score
self.matches = matches if matches else []
def __str__(self):
return f"EdgeDetail({self.number_of_modifications}, {self.match_score}, {self.matches})"
[docs] def reverse_edge(self):
"""
Reverse an edge details in the network.
This is useful when the reversed matches are needed from the edge in the network.
first_peak_mz and second_peak_mz are swapped in the matches, and start and end spectrum and compound ids are also swapped.
"""
new_obj = deepcopy(self)
for match in new_obj.matches:
match.first_peak_mz, match.second_peak_mz = match.second_peak_mz, match.first_peak_mz
new_obj.start_spectrum_id, new_obj.end_spectrum_id = new_obj.end_spectrum_id, new_obj.start_spectrum_id
new_obj.start_compound_id, new_obj.end_compound_id = new_obj.end_compound_id, new_obj.start_compound_id
return new_obj
[docs] def copy(self):
"""
Create a copy of the EdgeDetail object
Returns
-------
EdgeDetail
A copy of the EdgeDetail object
"""
return EdgeDetail(
self.number_of_modifications,
self.match_score,
deepcopy(self.matches),
self.start_spectrum_id,
self.end_spectrum_id,
self.start_compound_id,
self.end_compound_id
)
[docs] def get_matches_pairs(self) -> List[Tuple[int, int]]:
"""
Get the matches as a list of tuples
Returns
-------
List[Tuple[int, int]]
List of tuples of peak m/z values
"""
return [(match.first_peak_mz, match.second_peak_mz) for match in self.matches]
[docs] def get_single_type_matches(self, match_type: MatchType) -> List[Tuple[int, int]]:
"""
Get the matches of a specific type
Parameters
----------
match_type : MatchType
Type of the match
Returns
-------
List[Tuple[int, int]]
List of tuples of peak m/z values [(first_peak_mz, second_peak_mz), ...] of the specified match type
"""
return [(match.first_peak_mz, match.second_peak_mz) for match in self.matches if match.match_type == match_type]