Skip to content

Report generation fails with "IndexError: single positional indexer is out-of-bounds" #231

@malteboettcher

Description

@malteboettcher

Hi,

I'm encountering an error when running MS²Rescore with the following config:

{
  "$schema": "./config_schema.json",
  "ms2rescore": {
    "feature_generators": {
      "basic": {},
      "ms2pip": {
        "model": "HCD",
        "ms2_tolerance": 0.02
      },
      "deeplc": {
        "calibration_set_size": 0.4
      }
    },
    "rescoring_engine": {
      "percolator": {}
    },
    "psm_file": null,
    "psm_file_type": "xtandem",
    "psm_reader_kwargs": {},
    "spectrum_path": null,
    "output_path": null,
    "log_level": "info",
    "id_decoy_pattern": "decoy_",
    "psm_id_pattern": "([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})",
    "spectrum_id_pattern": "([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})",
    "lower_score_is_better": false,
    "modification_mapping": {
      "+57.022": "U:Carbamidomethyl",
      "+15.994": "U:Oxidation",
      "+39.9954": "U:Pyro-carbamidomethyl",
      "+42.0106": "U:Acetyl",
      "-17.0266": "U:Gln->pyro-Glu",
      "-18.0106": "U:Glu->pyro-Glu"
    },
    "fixed_modifications": {},
    "processes": -1,
    "rename_to_usi": false,
    "fasta_file": null,
    "write_report": true
  }
} 

Everything seems to work fine up to the rescoring step, but when generating the final report, the process fails with the following error:

2025-07-14 15:21:49 INFO     ms2rescore.feature_generators.deeplc // Adding
                             DeepLC-derived features to PSMs.
                    INFO     ms2rescore.feature_generators.deeplc // Running
                             DeepLC for PSMs from run (1/1): spectra...
2025-07-14 15:22:11 INFO     ms2rescore.rescoring_engines.percolator //
                             Percolator output:
                             Protein decoy-prefix used is decoy_
                             All files have been read
                             Percolator version 3.06.1, Build Date Jun 15 2023
                             14:55:20
                             Copyright (c) 2006-9 University of Washington. All
                             rights reserved.
                             Written by Lukas Käll ([email protected]) in
                             the
                             Department of Genome Sciences at the University of
                             Washington.
                             Issued command:
                             percolator --results-psms
                             /xtandemserver/download/output2.ms2rescore.percolat
                             or.psms.pout --decoy-results-psms
                             /xtandemserver/download/output2.ms2rescore.percolat
                             or.decoy.psms.pout --results-peptides
                             /xtandemserver/download/output2.ms2rescore.percolat
                             or.peptides.pout --decoy-results-peptides
                             /xtandemserver/download/output2.ms2rescore.percolat
                             or.decoy.peptides.pout --results-proteins
                             /xtandemserver/download/output2.ms2rescore.percolat
                             or.proteins.pout --decoy-results-proteins
                             /xtandemserver/download/output2.ms2rescore.percolat
                             or.decoy.proteins.pout --weights
                             /xtandemserver/download/output2.ms2rescore.percolat
                             or.weights.tsv --verbose 1 --num-threads 8
                             --post-processing-tdc
                             /xtandemserver/download/output2.ms2rescore.pin
                             Started Mon Jul 14 15:21:57 2025
                              on xtandem-6b9f78b46b-l5nxm
                             Hyperparameters: selectionFdr=0.01, Cpos=0, Cneg=0,
                             maxNiter=10
                             Concatenated search input detected and
                             --post-processing-tdc flag set. Applying
                             target-decoy competition on Percolator scores.
                             Selecting Cpos by cross-validation.
                             Selecting Cneg by cross-validation.
                             Found 0 test set positives with q<0.01 in initial
                             direction
                             ---Training with Cpos selected by cross validation,
                             Cneg selected by cross validation,
                             initial_fdr=0.01, fdr=0.01
                             Found 0 test set PSMs with q<0.01.
                             No targets found with q<0.01
                             Resetting score vector, using default vector. Use
                             --override flag to prevent this.
                             Selected best-scoring PSM per scan+expMass
                             (target-decoy competition): 3650 target PSMs and
                             3526 decoy PSMs.
                             Tossing out "redundant" PSMs keeping only the best
                             scoring PSM for each unique peptide.
                             Calculating q values.
                             Final list yields 0 target peptides with q<0.01.
                             Calculating posterior error probabilities (PEPs).

                    INFO     ms2rescore.core // Identified -28 (-100.00%) less
                             PSMs at 1% FDR after rescoring.
                    INFO     ms2rescore.core // Writing output to
                             /xtandemserver/download/output2.ms2rescore.psms.tsv
                             ...
2025-07-14 15:22:12 INFO     ms2rescore.report.generate // Collecting files...
                    INFO     ms2rescore.report.generate // ✅ Found PSMs:
                             '/xtandemserver/download/output2.ms2rescore.psms.ts
                             v'
                    INFO     ms2rescore.report.generate // ✅ Found
                             configuration:
                             '/xtandemserver/download/output2.ms2rescore.full-co
                             nfig.json'
                    INFO     ms2rescore.report.generate // ✅ Found feature
                             names:
                             '/xtandemserver/download/output2.ms2rescore.feature
                             _names.tsv'
                    WARNING  ms2rescore.report.generate // ❌ feature weights:
                             '/xtandemserver/download/output2.ms2rescore.mokapot
                             .weights.tsv'
                    INFO     ms2rescore.report.generate // ✅ Found log:
                             '/xtandemserver/download/output2.ms2rescore.log.txt
                             '
                    INFO     ms2rescore.report.generate // Recalculating
                             confidence estimates...
                    INFO     mokapot.dataset // Using 1 features:
                    INFO     mokapot.dataset //   (1)        before
                    INFO     mokapot.dataset // Found 7176 PSMs.
                    INFO     mokapot.dataset //   - 3650 target PSMs and 3526
                             decoy PSMs detected.
2025-07-14 15:22:13 INFO     mokapot.dataset // Using 1 features:
                    INFO     mokapot.dataset //   (1)        after
                    INFO     mokapot.dataset // Found 7176 PSMs.
                    INFO     mokapot.dataset //   - 3650 target PSMs and 3526
                             decoy PSMs detected.
                    ERROR    ms2rescore._main_ // single positional indexer is
                             out-of-bounds
                             ╭─────── Traceback (most recent call last) ───────╮
                             │ /usr/local/lib/python3.10/dist-packages/ms2resc │
                             │ ore/_main_.py:178 in main                     │
                             │                                                 │
                             │   175 │                                         │
                             │   176 │   # Run MS²Rescore                      │
                             │   177 │   try:                                  │
                             │ ❱ 178 │   │   rescore(configuration=config)     │
                             │   179 │   except Exception as e:                │
                             │   180 │   │   LOGGER.exception(e)               │
                             │   181 │   │   sys.exit(1)                       │
                             │                                                 │
                             │ /usr/local/lib/python3.10/dist-packages/ms2resc │
                             │ ore/core.py:156 in rescore                      │
                             │                                                 │
                             │   153 │   # Write report                        │
                             │   154 │   if config["write_report"]:            │
                             │   155 │   │   try:                              │
                             │ ❱ 156 │   │   │   generate.generate_report(     │
                             │   157 │   │   │   │   output_file_root, psm_lis │
                             │       use_txt_log=True                          │
                             │   158 │   │   │   )                             │
                             │   159 │   │   except exceptions.ReportGeneratio │
                             │                                                 │
                             │ /usr/local/lib/python3.10/dist-packages/ms2resc │
                             │ ore/report/generate.py:90 in generate_report    │
                             │                                                 │
                             │    87 │   confidence_before, confidence_after = │
                             │    88 │                                         │
                             │    89 │   overview_context = _get_overview_cont │
                             │ ❱  90 │   target_decoy_context = _get_target_de │
                             │    91 │   features_context = _get_features_cont │
                             │       feature_names=feature_names)              │
                             │    92 │   config_context = _get_config_context( │
                             │    93 │   log_context = _get_log_context(files) │
                             │                                                 │
                             │ /usr/local/lib/python3.10/dist-packages/ms2resc │
                             │ ore/report/generate.py:238 in                   │
                             │ _get_target_decoy_context                       │
                             │                                                 │
                             │   235 │   │   │   {                             │
                             │   236 │   │   │   │   "title": TEXTS["charts"][ │
                             │   237 │   │   │   │   "description": TEXTS["cha │
                             │ ❱ 238 │   │   │   │   "chart": charts.score_his │
                             │   239 │   │   │   },                            │
                             │   240 │   │   │   {                             │
                             │   241 │   │   │   │   "title": TEXTS["charts"][ │
                             │                                                 │
                             │ /usr/local/lib/python3.10/dist-packages/ms2resc │
                             │ ore/report/charts.py:85 in score_histogram      │
                             │                                                 │
                             │    82 │   # Get score thresholds                │
                             │    83 │   if all(psm_df["qvalue"]):             │
                             │    84 │   │   score_threshold = (               │
                             │ ❱  85 │   │   │   psm_df[psm_df["qvalue"] <= 0. │
                             │    86 │   │   │   .sort_values("qvalue", ascend │
                             │    87 │   │   │   .iloc[0]                      │
                             │    88 │   │   )                                 │
                             │                                                 │
                             │ /usr/local/lib/python3.10/dist-packages/pandas/ │
                             │ core/indexing.py:1073 in _getitem_            │
                             │                                                 │
                             │   1070 │   │   │   axis = self.axis or 0        │
                             │   1071 │   │   │                                │
                             │   1072 │   │   │   maybe_callable = com.apply_i │
                             │ ❱ 1073 │   │   │   return self._getitem_axis(ma │
                             │   1074 │                                        │
                             │   1075 │   def _is_scalar_access(self, key: tup │
                             │   1076 │   │   raise NotImplementedError()      │
                             │                                                 │
                             │ /usr/local/lib/python3.10/dist-packages/pandas/ │
                             │ core/indexing.py:1625 in _getitem_axis          │
                             │                                                 │
                             │   1622 │   │   │   │   raise TypeError("Cannot  │
                             │   1623 │   │   │                                │
                             │   1624 │   │   │   # validate the location      │
                             │ ❱ 1625 │   │   │   self._validate_integer(key,  │
                             │   1626 │   │   │                                │
                             │   1627 │   │   │   return self.obj._ixs(key, ax │
                             │   1628                                          │
                             │                                                 │
                             │ /usr/local/lib/python3.10/dist-packages/pandas/ │
                             │ core/indexing.py:1557 in _validate_integer      │
                             │                                                 │
                             │   1554 │   │   """                              │
                             │   1555 │   │   len_axis = len(self.obj._get_axi │
                             │   1556 │   │   if key >= len_axis or key < -len │
                             │ ❱ 1557 │   │   │   raise IndexError("single pos │
                             │   1558 │                                        │
                             │   1559 │   # ---------------------------------- │
                             │   1560                                          │
                             ╰─────────────────────────────────────────────────╯
                             IndexError: single positional indexer is
                             out-of-bounds

This happens during the call to score_histogram in report/charts.py. It seems like psm_df[psm_df["qvalue"] <= 0.01] might be empty, possibly because no target PSMs were identified at 1% FDR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions