Skip to content

Commit 2710fe6

Browse files
committed
Fix robustness of PepXMLReader against missing params in file
1 parent 372355a commit 2710fe6

1 file changed

Lines changed: 28 additions & 18 deletions

File tree

psm_utils/io/pepxml.py

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
"mzFidelity",
2828
]
2929

30+
KNOWN_METADATA_KEYS = [
31+
"num_matched_ions",
32+
"tot_num_ions",
33+
"num_missed_cleavages",
34+
]
35+
3036

3137
class PepXMLReader(ReaderBase):
3238
"""Reader for pepXML PSM files."""
@@ -127,47 +133,51 @@ def _parse_peptidoform(
127133

128134
def _parse_psm(self, spectrum_query: dict[str, Any], search_hit: dict[str, Any]) -> PSM:
129135
"""Parse pepXML PSM to PSM."""
130-
metadata = {
131-
"num_matched_ions": str(search_hit["num_matched_ions"]),
132-
"tot_num_ions": str(search_hit["tot_num_ions"]),
133-
"num_missed_cleavages": str(search_hit["num_missed_cleavages"]),
134-
}
136+
# Build metadata from optional search hit fields
137+
metadata = {key: str(search_hit[key]) for key in KNOWN_METADATA_KEYS if key in search_hit}
138+
139+
# Add all search scores to metadata
135140
metadata.update(
136141
{
137-
f"search_score_{key.lower()}": str(search_hit["search_score"][key])
138-
for key in search_hit["search_score"]
142+
f"search_score_{key.lower()}": str(value)
143+
for key, value in search_hit["search_score"].items()
139144
}
140145
)
141146

147+
# Build provenance data from optional spectrum query fields
148+
provenance_data = {
149+
k: str(v)
150+
for k, v in {
151+
"pepxml_index": spectrum_query.get("index"),
152+
"start_scan": spectrum_query.get("start_scan"),
153+
"end_scan": spectrum_query.get("end_scan"),
154+
}.items()
155+
if v is not None
156+
}
157+
142158
return PSM(
143159
peptidoform=self._parse_peptidoform(
144160
search_hit["peptide"],
145161
search_hit["modifications"],
146162
spectrum_query["assumed_charge"],
147163
),
148-
spectrum_id=spectrum_query["spectrumNativeID"]
149-
if "spectrumNativeID" in spectrum_query
150-
else spectrum_query["spectrum"],
164+
spectrum_id=spectrum_query.get("spectrumNativeID", spectrum_query.get("spectrum")),
151165
run=None,
152166
collection=None,
153167
spectrum=None,
154168
is_decoy=None,
155-
score=search_hit["search_score"][self.score_key],
169+
score=search_hit["search_score"].get(self.score_key, None),
156170
qvalue=None,
157171
pep=None,
158172
precursor_mz=mass_to_mz(
159173
spectrum_query["precursor_neutral_mass"], spectrum_query["assumed_charge"]
160174
),
161175
retention_time=spectrum_query.get("retention_time_sec"),
162176
ion_mobility=spectrum_query.get("ion_mobility"),
163-
protein_list=[p["protein"] for p in search_hit["proteins"]],
164-
rank=search_hit["hit_rank"],
177+
protein_list=[p["protein"] for p in search_hit.get("proteins", [])],
178+
rank=search_hit.get("hit_rank", None),
165179
source=None,
166-
provenance_data={
167-
"pepxml_index": str(spectrum_query["index"]),
168-
"start_scan": str(spectrum_query["start_scan"]),
169-
"end_scan": str(spectrum_query["end_scan"]),
170-
},
180+
provenance_data=provenance_data,
171181
metadata=metadata,
172182
rescoring_features={},
173183
)

0 commit comments

Comments
 (0)