Inital steps for moving to LightTransition (WIP)#8544
Conversation
📝 WalkthroughWalkthroughAdds a memory‑efficient "Light" data path: LightTargetedExperiment I/O (streaming TSV/PQP readers & writers), extended LightTransition/LightCompound/LightProtein fields and accessors, Light variants of MRMAssay and MRMDecoy algorithms (annotation, restriction, detecting, IPF/UIS, decoy generation), TOPP light‑path integration, and tests. Duplicate implementations present in MRMAssay.cpp. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor TOPP
participant Reader as TSV/PQP Reader
participant LightExp as LightTargetedExperiment
participant MRMA as MRMAssay (light)
participant Decoy as MRMDecoy (light)
participant Writer as TSV/PQP Writer
Note over Reader,LightExp: streaming, deduplication, incremental population
TOPP->>Reader: stream input -> LightTargetedExperiment
Reader-->>LightExp: append transitions/compounds/proteins
TOPP->>MRMA: reannotate/restrict/detecting (light)
MRMA-->>LightExp: update annotations / mark detecting
alt UIS/IPF generation
TOPP->>MRMA: uisTransitionsLight(...)
MRMA-->>LightExp: add identifying transitions / peptidoforms
end
alt decoy generation
TOPP->>Decoy: generateDecoysLight(...)
Decoy-->>LightExp: append decoy transitions/compounds/proteins
end
TOPP->>Writer: convertLightTargetedExperimentToTSV/ToPQP(LightExp)
Writer-->>TOPP: file written
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (2)**/*📄 CodeRabbit inference engine (AGENTS.md)
Files:
src/tests/topp/CMakeLists.txt📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (12)📓 Common learnings📚 Learning: 2025-12-20T17:04:02.774ZApplied to files:
📚 Learning: 2025-09-03T12:58:20.032ZApplied to files:
📚 Learning: 2025-12-20T17:04:02.774ZApplied to files:
📚 Learning: 2025-12-20T17:04:02.774ZApplied to files:
📚 Learning: 2025-12-20T17:04:02.774ZApplied to files:
📚 Learning: 2025-08-05T12:43:11.681ZApplied to files:
📚 Learning: 2025-12-20T17:04:02.774ZApplied to files:
📚 Learning: 2025-12-20T17:04:02.774ZApplied to files:
📚 Learning: 2025-12-20T17:04:02.774ZApplied to files:
📚 Learning: 2025-08-05T12:43:11.681ZApplied to files:
📚 Learning: 2025-08-05T12:43:11.681ZApplied to files:
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
🔇 Additional comments (3)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (5)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (1)
944-958: Fragment annotation parsing is functional but basic.The parsing logic extracts the fragment type (first character) and ordinal number correctly for standard annotations like "y7" or "b3". However, this may not handle more complex annotations (e.g., "y7-H2O" or "b3^2"). If such annotations are expected, consider using a more robust parsing approach.
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp (1)
739-1156: Complex method acknowledged; consider future refactoring.The static analysis flagged this method as complex (lines 739-1157). While the complexity is understandable given the need to mirror the heavy-path
writePQPOutput_function, consider extracting common SQL schema creation, index map building, and insert logic into shared helper methods in a future refactor to reduce duplication between the two paths.src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h (1)
233-245: Minor Doxygen inconsistency:@param[out]formin_transitions.Line 239 uses
@param[out]formin_transitions, but this is an input parameter. This inconsistency also exists in the originaldetectingTransitionsdocumentation at line 112. Consider changing to@param[in]for consistency.🔎 Suggested fix
@param[in] exp the input, unfiltered transitions - @param[out] min_transitions the minimum number of transitions required per assay + @param[in] min_transitions the minimum number of transitions required per assay @param[in] max_transitions the maximum number of transitions required per assaysrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp (1)
1441-1446: Dead code:compound_mapis built but never used.The
compound_mapis constructed at lines 1442-1446 but is not referenced anywhere in the remaining code. This appears to be leftover from development or copy-paste.🔎 Proposed fix to remove unused code
- // Build compound map - std::map<std::string, const OpenSwath::LightCompound*> compound_map; - for (const auto& compound : exp.compounds) - { - compound_map[compound.id] = &compound; - } - for (const auto& compound : exp.compounds)src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (1)
1557-1720: Well-structured TSV export with comprehensive field handling.The implementation correctly:
- Builds efficient lookup maps for compounds and proteins
- Handles both peptide and non-peptide compounds with appropriate field selection
- Falls back to transition-level
precursor_imwhen compounddrift_timeis unavailable (lines 1673-1676)- Documents the CE=-1 placeholder limitation (line 1706)
One minor suggestion: consider checking if the output file stream opened successfully before writing.
🔎 Optional: Add file open check
std::ofstream os(filename); + if (!os.is_open()) + { + throw Exception::FileNotWritable(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename); + } os.precision(writtenDigits(double()));
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
-
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h(2 hunks) -
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h(2 hunks) -
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.h(1 hunks) -
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.h(1 hunks) -
src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp(1 hunks) -
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp(1 hunks) -
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp(2 hunks) -
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp(3 hunks) -
src/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.h(3 hunks) -
src/pyOpenMS/pxds/LightTargetedExperiment.pxd(2 hunks) -
src/topp/OpenSwathAssayGenerator.cpp(1 hunks) -
src/topp/OpenSwathDecoyGenerator.cpp(1 hunks) -
src/topp/TargetedFileConverter.cpp(1 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cppsrc/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.hsrc/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
src/openms/include/OpenMS/**/*.h
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Add Doxygen comments for new public methods and classes
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.hsrc/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cppsrc/topp/OpenSwathDecoyGenerator.cppsrc/topp/TargetedFileConverter.cppsrc/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cppsrc/topp/OpenSwathAssayGenerator.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.hsrc/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
**/*.h
📄 CodeRabbit inference engine (AGENTS.md)
**/*.h: Use _impl.h only when needed; .h files must not include _impl.h
Do not use 'using namespace' or 'using std::...' in headers; allowed only in .cpp files
Prefer forward declarations in headers; include only base class headers, non-pointer members, and templates
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.hsrc/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.hsrc/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cppsrc/topp/OpenSwathDecoyGenerator.cppsrc/topp/TargetedFileConverter.cppsrc/pyOpenMS/pxds/LightTargetedExperiment.pxdsrc/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cppsrc/topp/OpenSwathAssayGenerator.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.hsrc/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
src/topp/*.cpp
📄 CodeRabbit inference engine (AGENTS.md)
src/topp/*.cpp: Use ProgressLogger in tools for progress reporting
Add new C++ class source in src/topp/.cpp and register in src/topp/executables.cmake
Define TOPP tool parameters in registerOptionsAndFlags_(); read with getStringOption_ and related helpers
Files:
src/topp/OpenSwathDecoyGenerator.cppsrc/topp/TargetedFileConverter.cppsrc/topp/OpenSwathAssayGenerator.cpp
src/pyOpenMS/pxds/*.pxd
📄 CodeRabbit inference engine (AGENTS.md)
src/pyOpenMS/pxds/*.pxd: Keep .pxd signatures in sync with C++ APIs; update or remove wrap-ignore when wrapping changes
Always declare default and copy constructors in .pxd files; use cimport, not Python import
For non-inheriting classes use 'cdef cppclass ClassName:' with no base in .pxd
Use wrap-ignore, wrap-as, wrap-iter-begin/end, wrap-instances, wrap-attach, wrap-upper-limit, wrap-inherits hints in .pxd comments
Avoid custom init in .pxd unless required; it overrides autowrap dispatchers
Do not add Python-only methods to .pxd files; use addons or _dataframes.py wrappers
Files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
src/pyOpenMS/**/*.{pxd,pyx,py}
📄 CodeRabbit inference engine (AGENTS.md)
Use snake_case for Python-facing names and DataFrame columns in pyOpenMS
Files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
src/pyOpenMS/**/*.pxd
📄 CodeRabbit inference engine (AGENTS.md)
Autowrap gotcha: autowrap returns Python strings; do not .decode(). Avoid cdef for autowrap string returns. Avoid cdef typed variables for autowrap return values inside def methods; use Python type checks. Keep addons minimal; avoid redundant aliases.
Files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: PR checklist: update AUTHORS and CHANGELOG, run/extend tests, update pyOpenMS bindings when needed
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cppsrc/topp/OpenSwathDecoyGenerator.cppsrc/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cppsrc/topp/OpenSwathAssayGenerator.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
📚 Learning: 2025-07-29T10:05:48.015Z
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
Applied to files:
src/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.hsrc/pyOpenMS/pxds/LightTargetedExperiment.pxdsrc/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/include/OpenMS/**/*.h : Add Doxygen comments for new public methods and classes
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
📚 Learning: 2025-08-14T10:19:54.371Z
Learnt from: jpfeuffer
Repo: OpenMS/OpenMS PR: 8167
File: src/topp/Digestor.cpp:200-226
Timestamp: 2025-08-14T10:19:54.371Z
Learning: In OpenMS (C++ bioinformatics framework), use boost random libraries instead of std library random distributions for cross-platform reproducible random number generation, as std library distributions are not reproducible across platforms.
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Utilize OpenMS logging mechanisms
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/topp/*.cpp : Use ProgressLogger in tools for progress reporting
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use appropriate OpenMS containers and algorithms
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/tests/class_tests/openms/**/*.cpp : Write unit tests for new functionality
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Be mindful of memory usage when processing large datasets
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Consider algorithmic complexity for data processing operations
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to **/*.{h,cpp,cxx,cc,hpp} : Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to **/*.{h,cpp,cxx,cc,hpp} : Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/pyOpenMS/pxds/*.pxd : Keep .pxd signatures in sync with C++ APIs; update or remove wrap-ignore when wrapping changes
Applied to files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
📚 Learning: 2025-06-16T15:49:26.504Z
Learnt from: FreezB11
Repo: OpenMS/OpenMS PR: 7969
File: src/pyOpenMS/pxds/TMTThirtyTwoPlexQuantitationMethod.pxd:1-3
Timestamp: 2025-06-16T15:49:26.504Z
Learning: In OpenMS Python bindings (.pxd files), derived quantitation method classes like TMTThirtyTwoPlexQuantitationMethod only need to declare their constructors. All other public methods (getName, getChannelInformation, getNumberOfChannels, getIsotopeCorrectionMatrix, getReferenceChannel) are inherited from the base IsobaricQuantitationMethod class and don't need to be redeclared explicitly.
Applied to files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/pyOpenMS/**/*.h : Add Doxygen comments for new public methods and classes in pyOpenMS bindings
Applied to files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/pyOpenMS/pxds/*.pxd : Do not add Python-only methods to .pxd files; use addons or _dataframes.py wrappers
Applied to files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/pyOpenMS/**/*.pxd : Autowrap gotcha: autowrap returns Python strings; do not .decode(). Avoid cdef for autowrap string returns. Avoid cdef typed variables for autowrap return values inside def methods; use Python type checks. Keep addons minimal; avoid redundant aliases.
Applied to files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
📚 Learning: 2025-10-15T07:49:09.293Z
Learnt from: timosachsenberg
Repo: OpenMS/OpenMS PR: 8177
File: src/openms/include/OpenMS/PROCESSING/CENTROIDING/PeakPickerIM.h:11-14
Timestamp: 2025-10-15T07:49:09.293Z
Learning: In OpenMS, DefaultParamHandler.h is located under OpenMS/DATASTRUCTURES/, not OpenMS/CONCEPT/. The correct include is: `#include <OpenMS/DATASTRUCTURES/DefaultParamHandler.h>`
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
🧬 Code graph analysis (7)
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.h (1)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (2)
convertLightTargetedExperimentToTSV(1557-1720)convertLightTargetedExperimentToTSV(1557-1557)
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp (6)
reannotateTransitionsLight(1198-1334)reannotateTransitionsLight(1198-1205)restrictTransitionsLight(1336-1380)restrictTransitionsLight(1336-1339)detectingTransitionsLight(1382-1477)detectingTransitionsLight(1382-1384)
src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp (2)
src/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.h (1)
precursor_mz(25-25)src/openms/include/OpenMS/MATH/MathFunctions.h (1)
roundDecimal(168-173)
src/topp/OpenSwathDecoyGenerator.cpp (3)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (3)
switchKR(309-337)switchKR(309-309)MRMDecoy(27-41)src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (2)
TransitionTSVFile(87-100)TransitionTSVFile(102-102)src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp (2)
TransitionPQPFile(26-29)TransitionPQPFile(31-31)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (2)
src/openms/source/CONCEPT/Exception.cpp (1)
IllegalArgument(247-250)src/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.h (1)
fragment_charge(27-27)
src/topp/OpenSwathAssayGenerator.cpp (3)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (2)
TransitionTSVFile(87-100)TransitionTSVFile(102-102)src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp (2)
TransitionPQPFile(26-29)TransitionPQPFile(31-31)src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp (2)
MRMAssay(22-22)MRMAssay(24-24)
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (4)
generateDecoysLight(639-1005)generateDecoysLight(639-654)switchKR(309-337)switchKR(309-309)
🪛 GitHub Check: CodeFactor
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
[notice] 639-1006: src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp#L639-L1006
Complex Method
src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp
[notice] 1198-1335: src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp#L1198-L1335
Complex Method
[notice] 1382-1478: src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp#L1382-L1478
Complex Method
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
[notice] 739-1157: src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp#L739-L1157
Complex Method
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: build-win
- GitHub Check: build-lnx
- GitHub Check: build-macos-arm
- GitHub Check: build-lnx-arm
- GitHub Check: build-and-test (ubuntu-24.04, clang++, 17)
- GitHub Check: build-and-test (macos-14, xcode, 15.4)
- GitHub Check: build-and-test (windows-2025, cl.exe, 14.44)
- GitHub Check: build-and-test (ubuntu-24.04, g++, 13)
- GitHub Check: build-and-test (ubuntu-24.04-arm, g++, 13)
🔇 Additional comments (33)
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.h (1)
229-236: LGTM!The new
convertLightTargetedExperimentToPQPmethod is well-documented with Doxygen comments and follows the established pattern of the existingconvertTargetedExperimentToPQPmethod. The use ofconstreference for the input parameter is appropriate for the light-path design.src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.h (1)
325-332: LGTM!The new
convertLightTargetedExperimentToTSVmethod declaration follows the same pattern as its PQP counterpart and the existing heavy-pathconvertTargetedExperimentToTSV. Doxygen comments are properly included per coding guidelines.src/topp/TargetedFileConverter.cpp (2)
127-165: Light-path routing and memory-efficient conversion look well-structured.The logic correctly routes TSV/MRM/PQP → TSV/PQP conversions through the memory-efficient
LightTargetedExperimentpath.One note on Line 151: The light path always uses
legacy_traml_id=trueregardless of the user's--legacy_traml_idflag, while the heavy path (Line 187) respects the user's choice. The inline comment explains this is to "preserve original string identifiers," but this creates an inconsistency where the flag is effectively ignored for light-path PQP inputs.Please verify this is the intended behavior. If users expect the
--legacy_traml_idflag to affect PQP → TSV conversions, this should be documented or the flag should be applied:- // Light path uses TRAML_ID (legacy_traml_id=true) to preserve original string identifiers - pqp_reader.convertPQPToTargetedExperiment(in.c_str(), light_exp, true); + // Light path respects legacy_traml_id flag for PQP reading + pqp_reader.convertPQPToTargetedExperiment(in.c_str(), light_exp, legacy_traml_id);
167-211: LGTM!The heavy path correctly maintains full metadata for TraML conversions, calls validation after reading TSV/PQP inputs, and properly handles all three output formats (TSV, PQP, TraML).
src/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.h (3)
29-37: LGTM!The default values for
detecting_transitionandquantifying_transitionnow match the semantics inTSVTransition. The new roundtrip I/O fields (fragment_nr,fragment_type,annotation,peptidoforms) are properly typed and documented with Doxygen comments.
155-158: LGTM!The new
LightCompoundfields (label_type,smiles,adducts) support metabolomics roundtrip I/O and are properly documented.
193-195: LGTM!The new
uniprot_idfield inLightProteincompletes the roundtrip I/O support for protein-level data.src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (2)
639-667: The newgenerateDecoysLightfunction provides a memory-efficient decoy generation path.The implementation correctly mirrors the heavy-path
generateDecoyslogic while operating onLightTargetedExperimentstructures. The approach of using temporary heavyTargetedExperiment::Peptideobjects for the actual decoy generation methods is pragmatic for code reuse.
1002-1005: LGTM!The final assignment using
std::moveis appropriate for the output vectors, ensuring efficient transfer of ownership.src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h (2)
15-15: LGTM!The new include for
TransitionExperiment.his necessary to support theOpenSwath::LightTargetedExperimenttype used in the newgenerateDecoysLightmethod declaration.
106-145: Well-documented light-path API addition.The Doxygen documentation is complete with
@briefand all@paramtags. The method signature correctly mirrorsgenerateDecoys()while operating onLightTargetedExperimentstructures. Theconstqualifier is consistent with the existing API.As per coding guidelines, the Doxygen documentation for this new public method is properly provided.
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp (4)
41-42: LGTM!The added comments clarify the
legacy_traml_idbehavior, improving code readability.
892-897: Unusedcompound_lookupvariable.The
compound_lookupmap is built here but is only used much later (line 1100) for compound inserts. This is fine, but note that all compounds are iterated twice - once to build the lookup and once to process precursors. This is consistent with the heavy-path implementation.
954-967: Batch insertion condition differs from heavy-path.The condition
i % 50000 == 0 && i > 0differs from the heavy-path version at line 467 which usesi % 50000 == 0. This means the light path won't commit a transaction at iteration 0, which is actually correct behavior (avoiding an empty transaction commit), so this is an improvement over the heavy path.
1081-1094: Good exception handling for invalid sequences.The try-catch around
AASequence::fromStringproperly handles sequences that can't be parsed (e.g., non-peptide compounds or invalid modification syntax), falling back to using the raw string as both unmodified and modified sequence.src/topp/OpenSwathDecoyGenerator.cpp (3)
196-199: LGTM!The light-path condition correctly enables memory-efficient processing when input is TSV/MRM/PQP and output is TSV/PQP, which are the appropriate cases for this optimization.
250-266: LGTM!The merge logic correctly handles the
separateflag, usingstd::movefor efficiency and properly appending decoy collections to the merged experiment when not separating.
268-279: LGTM!The light-path output correctly uses the new
convertLightTargetedExperimentToTSVandconvertLightTargetedExperimentToPQPmethods based on output type.src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h (4)
15-15: LGTM!The include for
TransitionExperiment.his necessary to support theOpenSwath::LightTargetedExperimenttype in the new light-path method declarations.
189-191: LGTM!The section comment clearly delineates the new light (memory-efficient) API additions from the existing heavy-path methods.
193-215: Well-documented light-path method.The Doxygen documentation for
reannotateTransitionsLightis complete and correctly describes the method as a light version ofreannotateTransitions(). As per coding guidelines, Doxygen comments are properly provided for this new public method.
217-231: Well-documented light-path method.The Doxygen documentation for
restrictTransitionsLightis complete and correctly describes the method as a light version ofrestrictTransitions().src/topp/OpenSwathAssayGenerator.cpp (3)
247-251: LGTM!The light-path condition correctly enables memory-efficient processing when IPF is disabled and input/output are TSV/MRM/PQP formats. This is appropriate since IPF requires the full
TargetedExperimentstructures for UIS transition generation.
252-299: LGTM!The light-path implementation correctly:
- Loads transitions into
LightTargetedExperiment- Uses the new
*Lightmethods for annotation, restriction, and detection- Writes output using the new light-path converters
The workflow mirrors the heavy path while operating on memory-efficient structures.
301-340: LGTM!The heavy-path loading and annotation logic is correctly preserved for TraML inputs or when IPF is enabled. The validation step (
validateTargetedExperiment) is appropriately called for TSV/MRM/PQP inputs.src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp (3)
1194-1196: Clear section header for Light methods.The comment block clearly delineates the new memory-efficient Light versions. The naming convention (
*Light) is consistent and self-documenting.
1198-1334: Light reannotation logic is correctly implemented with proper error handling.The method correctly mirrors the behavior of
reannotateTransitions()while operating onLightTargetedExperiment. The exception handling for invalid sequences (lines 1246-1259) gracefully continues processing. The compound map lookup (O(1)) is efficient.One observation: The fragment annotation parsing (lines 1304-1326) assumes single-character fragment type prefixes (e.g., "y", "b"). This works for standard ion types but may not handle extended annotations like "MS2_Precursor_i0" correctly—though this is consistent with how the non-Light version behaves.
1336-1380: Missing unannotated transition check compared to non-Light version.The non-Light
restrictTransitions()(lines 817-827) checks for unannotated interpretations viagetInterpretationList()and skips transitions withNonIdentifiedion types. This Light version omits that check.If this is intentional (because
LightTransitiondoesn't store full interpretation data), consider adding a comment explaining the difference. Otherwise, you may want to filter based ontr.annotationortr.fragment_typebeing empty/invalid.src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (3)
678-683: LGTM!The additional transition fields (
fragment_nr,fragment_type,annotation,peptidoforms) are correctly populated from the TSV input, enabling roundtrip I/O support.
701-740: Robust modification parsing with appropriate exception handling.The modification extraction logic correctly handles:
- N-terminal modifications (location = -1)
- C-terminal modifications (location = sequence size)
- Per-residue modifications
The
try-catchblock aroundAASequence::fromString()gracefully handles unparseable sequences without crashing the entire import process.
764-768: LGTM!The bounds check at line 765 correctly handles cases where
uniprot_idandProteinNamevectors may have different sizes, preventing potential out-of-bounds access.src/pyOpenMS/pxds/LightTargetedExperiment.pxd (2)
55-82: LightCompound bindings correctly extended.The new fields (
gene_name,label_type,smiles,adducts) align with the roundtrip I/O support added toTransitionTSVFile.cpp. The method declarations follow the existing pattern.
84-91: LightProtein bindings correctly extended withuniprot_id.The addition of
uniprot_idenables roundtrip preservation of UniProt accession numbers through the light-path processing pipeline.
IDFilter.h: - Add IsNotIdentificationVector concept to disambiguate template overloads - Add removeEmptyIdentifications(PeptideIdentificationList&) overload - Fixes autowrap-generated binding compilation with C++20 concepts setup.py: - Use numpy.get_include() for numpy 2.x compatibility - Update C++ standard from C++17 to C++20 (required for OpenMS concepts) - Change Qt5 to Qt6 on Linux (matches OpenMS build) - Change libomp to gomp (GNU OpenMP runtime for GCC builds) - Fix libraries.extend() bug: was iterating string characters instead of append 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
-
src/openms/include/OpenMS/PROCESSING/ID/IDFilter.h(3 hunks) -
src/pyOpenMS/setup.py(5 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/pyOpenMS/setup.pysrc/openms/include/OpenMS/PROCESSING/ID/IDFilter.h
src/pyOpenMS/**/*.{pxd,pyx,py}
📄 CodeRabbit inference engine (AGENTS.md)
Use snake_case for Python-facing names and DataFrame columns in pyOpenMS
Files:
src/pyOpenMS/setup.py
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/include/OpenMS/PROCESSING/ID/IDFilter.h
src/openms/include/OpenMS/**/*.h
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Add Doxygen comments for new public methods and classes
Files:
src/openms/include/OpenMS/PROCESSING/ID/IDFilter.h
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/openms/include/OpenMS/PROCESSING/ID/IDFilter.h
**/*.h
📄 CodeRabbit inference engine (AGENTS.md)
**/*.h: Use _impl.h only when needed; .h files must not include _impl.h
Do not use 'using namespace' or 'using std::...' in headers; allowed only in .cpp files
Prefer forward declarations in headers; include only base class headers, non-pointer members, and templates
Files:
src/openms/include/OpenMS/PROCESSING/ID/IDFilter.h
🧠 Learnings (4)
📓 Common learnings
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: PR checklist: update AUTHORS and CHANGELOG, run/extend tests, update pyOpenMS bindings when needed
Applied to files:
src/pyOpenMS/setup.py
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/pyOpenMS/pxds/*.pxd : Keep .pxd signatures in sync with C++ APIs; update or remove wrap-ignore when wrapping changes
Applied to files:
src/pyOpenMS/setup.py
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/openms/include/OpenMS/PROCESSING/ID/IDFilter.h
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: build-lnx-arm
- GitHub Check: build-macos-arm
- GitHub Check: build-lnx
- GitHub Check: build-win
- GitHub Check: build-and-test (windows-2025, cl.exe, 14.44)
- GitHub Check: build-and-test (ubuntu-24.04, g++, 13)
- GitHub Check: build-and-test (ubuntu-24.04-arm, g++, 13)
- GitHub Check: build-and-test (ubuntu-24.04, clang++, 17)
- GitHub Check: build-and-test (macos-14, xcode, 15.4)
- GitHub Check: cppcheck-test
🔇 Additional comments (8)
src/openms/include/OpenMS/PROCESSING/ID/IDFilter.h (4)
40-41: LGTM!Cosmetic reformatting aligns with the new concept style below.
43-48: LGTM!The concept correctly excludes the three identification vector types (
std::vector<PeptideIdentification>,std::vector<ProteinIdentification>, andPeptideIdentificationList) that have their own dedicated overloads, ensuring unambiguous template resolution.
684-689: LGTM!The overload follows the established pattern for
PeptideIdentificationListmethods in this file, correctly delegating to thestd::vector<PeptideIdentification>overload viagetData().
1286-1291: LGTM!The
IsNotIdentificationVectorconstraint correctly disambiguates this template from the dedicated overloads forstd::vector<PeptideIdentification>,std::vector<ProteinIdentification>, andPeptideIdentificationList, ensuring this version is only instantiated forFeatureMap/ConsensusMap-like types.src/pyOpenMS/setup.py (4)
125-125: Good use of the official NumPy API.Switching from
numpy.core.__path__[0]tonumpy.get_include()is the correct approach, as it uses the documented NumPy API rather than accessing internal implementation details.
91-91: The Qt6 migration on Linux is correct and properly aligned with the OpenMS build configuration. CMake configuration explicitly requires Qt6 (find_package(Qt6 COMPONENTS Core Network REQUIRED)insrc/pyOpenMS/CMakeLists.txt), and the entire OpenMS library links against Qt6 core components. The platform-specific difference (Windows: Qt5, Linux: Qt6) reflects different platform build configurations, not an inconsistency.
226-227: Consider whether simplifiedboost_regexnaming will work with your target Boost configurations.Boost library names include threading tags (indicating multithreading support), and libraries built without multithreading support can be identified by the absence of -mt. CMake's FindBoost module handles architecture-specific library suffixes like -x64.
The code appends generic
"boost_regex"after CMake processing. This works when OpenMS contrib builds Boost with--layout=tagged, which produces predictable names without compiler-specific suffixes. However, static Boost libraries on some systems like Ubuntu are compiled with different settings and may require names likeboost_regex-mt.The approach was deliberately chosen: the CMakeLists.txt shows boost_regex handling via CMake was attempted but abandoned, with the note that "the logic for static vs dynamic is in setup.py." This acknowledges the CMake limitation but leaves setup.py without fallback logic for non-standard Boost configurations. While the simplified name works for OpenMS contrib builds, it may fail for system Boost installations with non-standard layouts.
178-178: Verify OpenMP runtime library matches the compiler on Linux.The hardcoded use of
gompon Linux assumes GCC is the compiler. However, mixing OpenMP runtimes in the same program can easily cause fatal breakage. SinceOPEN_MS_COMPILERis available at runtime and the codebase's CI matrix includes Clang testing, this should be made compiler-dependent:
- libgomp is the GNU Offloading and Multi Processing Runtime Library for the GNU implementation of OpenMP
- Clang on Linux uses the LLVM OpenMP runtime (
omp/libomp), notgompThe fix should check the compiler before linking:
if OMP: if "clang" in OPEN_MS_COMPILER.lower(): libraries.append("omp") else: # GCC or compatible libraries.append("gomp") libraries.append("pthread")This matches the macOS pattern already in place (line 183) where Clang uses
omp.
- MRMDecoy.cpp: Fix shuffle check to use decoy_temp_peptide instead of temp_peptide - LightTargetedExperiment.pxd: Add missing isPrecursorImSet() and getPrecursorIM() methods - OpenSwathAssayGenerator.cpp: Fix if/else-if chain for output file type handling - OpenSwathDecoyGenerator.cpp: Add division by zero protection and fix if/else-if chain 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (3)
669-693: Consider documenting or refactoring seeding strategy.The current implementation uses
srand(time(nullptr))(line 669) for random selection, which mirrors the existinggenerateDecoysfunction (line 394). However, the DecoyDatabase.cpp context shows more sophisticated per-repeat seeding patterns. While this is consistent with the existing heavy-path behavior, consider:
- Documenting the seeding strategy in a comment
- Future refactoring to support deterministic repeat seeds for reproducibility (as done in DecoyDatabase.cpp)
This applies to both the light and heavy paths.
794-810: Validate decoy method parameter.The shuffle branch correctly checks modifications on the shuffled result (
decoy_temp_peptide), addressing the past review concern. However, theelsebranch (lines 807-810) silently copies the original peptide when an unknown method is provided.Consider validating the
methodparameter earlier in the function (similar to how the heavy-pathgenerateDecoysexpects specific method strings) to fail fast on invalid input.
639-1005: Consider future refactoring to reduce complexity.Static analysis flags this 367-line function as complex. While it correctly mirrors the existing
generateDecoysimplementation, both the light and heavy paths would benefit from extracting helper methods for:
- Peptide selection and filtering logic
- Decoy sequence generation per method
- Transition annotation and filtering
- Protein/compound cleanup
This is inherited technical debt from the original design rather than a new issue, but documenting it helps future maintenance.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
-
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp(1 hunks) -
src/pyOpenMS/pxds/LightTargetedExperiment.pxd(2 hunks) -
src/topp/OpenSwathAssayGenerator.cpp(1 hunks) -
src/topp/OpenSwathDecoyGenerator.cpp(1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/topp/OpenSwathDecoyGenerator.cppsrc/topp/OpenSwathAssayGenerator.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/topp/OpenSwathDecoyGenerator.cppsrc/topp/OpenSwathAssayGenerator.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/pyOpenMS/pxds/LightTargetedExperiment.pxd
src/topp/*.cpp
📄 CodeRabbit inference engine (AGENTS.md)
src/topp/*.cpp: Use ProgressLogger in tools for progress reporting
Add new C++ class source in src/topp/.cpp and register in src/topp/executables.cmake
Define TOPP tool parameters in registerOptionsAndFlags_(); read with getStringOption_ and related helpers
Files:
src/topp/OpenSwathDecoyGenerator.cppsrc/topp/OpenSwathAssayGenerator.cpp
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
src/pyOpenMS/pxds/*.pxd
📄 CodeRabbit inference engine (AGENTS.md)
src/pyOpenMS/pxds/*.pxd: Keep .pxd signatures in sync with C++ APIs; update or remove wrap-ignore when wrapping changes
Always declare default and copy constructors in .pxd files; use cimport, not Python import
For non-inheriting classes use 'cdef cppclass ClassName:' with no base in .pxd
Use wrap-ignore, wrap-as, wrap-iter-begin/end, wrap-instances, wrap-attach, wrap-upper-limit, wrap-inherits hints in .pxd comments
Avoid custom init in .pxd unless required; it overrides autowrap dispatchers
Do not add Python-only methods to .pxd files; use addons or _dataframes.py wrappers
Files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
src/pyOpenMS/**/*.{pxd,pyx,py}
📄 CodeRabbit inference engine (AGENTS.md)
Use snake_case for Python-facing names and DataFrame columns in pyOpenMS
Files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
src/pyOpenMS/**/*.pxd
📄 CodeRabbit inference engine (AGENTS.md)
Autowrap gotcha: autowrap returns Python strings; do not .decode(). Avoid cdef for autowrap string returns. Avoid cdef typed variables for autowrap return values inside def methods; use Python type checks. Keep addons minimal; avoid redundant aliases.
Files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
🧠 Learnings (12)
📓 Common learnings
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/topp/OpenSwathAssayGenerator.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-09-03T12:58:20.032Z
Learnt from: timosachsenberg
Repo: OpenMS/OpenMS PR: 8177
File: src/tests/topp/CMakeLists.txt:1857-1865
Timestamp: 2025-09-03T12:58:20.032Z
Learning: OpenMS tests: When adding new TOPP tests in src/tests/topp/CMakeLists.txt that compare outputs via FuzzyDiff, always add set_tests_properties("<tool>_<n>_out<m>" PROPERTIES DEPENDS "<tool>_<n>") to avoid flakiness under parallel CTest runs.
Applied to files:
src/topp/OpenSwathAssayGenerator.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/include/OpenMS/**/*.h : Add Doxygen comments for new public methods and classes
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/pyOpenMS/pxds/*.pxd : Keep .pxd signatures in sync with C++ APIs; update or remove wrap-ignore when wrapping changes
Applied to files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/pyOpenMS/pxds/*.pxd : Do not add Python-only methods to .pxd files; use addons or _dataframes.py wrappers
Applied to files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/pyOpenMS/**/*.h : Add Doxygen comments for new public methods and classes in pyOpenMS bindings
Applied to files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
📚 Learning: 2025-07-29T10:05:48.015Z
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
Applied to files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/pyOpenMS/**/*.pxd : Autowrap gotcha: autowrap returns Python strings; do not .decode(). Avoid cdef for autowrap string returns. Avoid cdef typed variables for autowrap return values inside def methods; use Python type checks. Keep addons minimal; avoid redundant aliases.
Applied to files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: PR checklist: update AUTHORS and CHANGELOG, run/extend tests, update pyOpenMS bindings when needed
Applied to files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
📚 Learning: 2025-06-16T15:49:26.504Z
Learnt from: FreezB11
Repo: OpenMS/OpenMS PR: 7969
File: src/pyOpenMS/pxds/TMTThirtyTwoPlexQuantitationMethod.pxd:1-3
Timestamp: 2025-06-16T15:49:26.504Z
Learning: In OpenMS Python bindings (.pxd files), derived quantitation method classes like TMTThirtyTwoPlexQuantitationMethod only need to declare their constructors. All other public methods (getName, getChannelInformation, getNumberOfChannels, getIsotopeCorrectionMatrix, getReferenceChannel) are inherited from the base IsobaricQuantitationMethod class and don't need to be redeclared explicitly.
Applied to files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/pyOpenMS/pxds/*.pxd : Always declare default and copy constructors in .pxd files; use cimport, not Python import
Applied to files:
src/pyOpenMS/pxds/LightTargetedExperiment.pxd
🧬 Code graph analysis (3)
src/topp/OpenSwathDecoyGenerator.cpp (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (3)
switchKR(309-337)switchKR(309-309)MRMDecoy(27-41)
src/topp/OpenSwathAssayGenerator.cpp (3)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (2)
TransitionTSVFile(87-100)TransitionTSVFile(102-102)src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp (2)
TransitionPQPFile(26-29)TransitionPQPFile(31-31)src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp (2)
MRMAssay(22-22)MRMAssay(24-24)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (1)
src/topp/DecoyDatabase.cpp (1)
protein(151-502)
🪛 GitHub Check: CodeFactor
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
[notice] 639-1006: src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp#L639-L1006
Complex Method
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: build-and-test (ubuntu-24.04, g++, 13)
- GitHub Check: build-and-test (windows-2025, cl.exe, 14.44)
- GitHub Check: build-and-test (macos-14, xcode, 15.4)
- GitHub Check: build-and-test (ubuntu-24.04-arm, g++, 13)
- GitHub Check: build-and-test (ubuntu-24.04, clang++, 17)
- GitHub Check: build-macos-arm
- GitHub Check: build-win
- GitHub Check: build-lnx
- GitHub Check: build-lnx-arm
- GitHub Check: cppcheck-test
🔇 Additional comments (17)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (3)
639-654: LGTM: Function signature matches the heavy-path pattern.The new
generateDecoysLightfunction signature correctly mirrors the existinggenerateDecoysfunction, usingLightTargetedExperimenttypes for memory efficiency while maintaining the same parameter set and semantics.
746-757: LGTM: Proper error handling for invalid sequences.The try-catch block correctly handles unparseable sequences by logging and excluding them, ensuring the function degrades gracefully rather than crashing on invalid input.
878-890: LGTM: Appropriate handling of metabolite transitions.The code correctly identifies non-peptide compounds and handles them by copying transitions with the decoy tag, bypassing peptide-specific decoy generation logic. This is the appropriate behavior for metabolites.
src/topp/OpenSwathDecoyGenerator.cpp (5)
196-198: LGTM: Light path detection logic is correct.The condition correctly identifies when memory-efficient processing can be used: TSV/MRM/PQP inputs to TSV/PQP outputs. TraML requires the heavy path, which is appropriate given its richer data model.
243-254: LGTM: Division by zero check properly implemented.The check at lines 243-247 ensures non-empty compounds and proteins before division, addressing the past review concern. The error message is clear and helpful.
264-272: LGTM: Efficient merge implementation using move semantics.The merge logic correctly uses
std::movefor the base experiment and then appends decoys using vector insert. This is memory-efficient and avoids unnecessary copies.
274-285: LGTM: Correct if/else-if chain for output type handling.The conditional chain correctly uses
else iffor mutually exclusive output types (TSV vs PQP), addressing the past review concern.
359-376: LGTM: Complete output type handling for heavy path.The heavy path correctly handles all supported output formats (TSV, PQP, TraML) with proper if/else-if chaining, ensuring mutually exclusive execution.
src/topp/OpenSwathAssayGenerator.cpp (4)
247-250: LGTM: Light path detection correctly excludes IPF workflows.The condition properly routes to the light path only when IPF is disabled and formats are TSV/MRM/PQP → TSV/PQP. This is necessary because IPF (Identification Precursor Filtering) requires the richer
TargetedExperimentdata model for UIS (Unique Ion Signature) generation.
278-285: LGTM: Correct usage of Light-path MRMAssay methods.The code correctly calls the new Light variants (
reannotateTransitionsLight,restrictTransitionsLight,detectingTransitionsLight) introduced in MRMAssay for memory-efficient processing ofLightTargetedExperiment.
288-299: LGTM: Proper if/else-if chain for light path output.The output handling correctly uses
else iffor mutually exclusive TSV and PQP output types, addressing the past review concern.
366-383: LGTM: Complete output handling for heavy path with correct chaining.The heavy path output correctly handles all three supported formats (TSV, PQP, TraML) with proper if/else-if chaining throughout.
src/pyOpenMS/pxds/LightTargetedExperiment.pxd (5)
8-9: LGTM: Constructors properly declared.All classes correctly declare both default and copy constructors with proper
except + nogilannotations, following the pyOpenMS binding guidelines.Also applies to: 58-59, 87-88
15-15: LGTM: New LightTransition fields properly typed.The new fields use appropriate Cython types and are correctly documented as supporting roundtrip TSV/PQP I/O, aligning with the PR's memory-efficient data handling goals.
Also applies to: 23-27
37-38: LGTM: Accessor methods added per past review.The
isPrecursorImSet()andgetPrecursorIM()methods have been added with correct signatures, addressing the past review concern about missing precursor IM accessors.
67-67: LGTM: New LightCompound fields properly declared.The additional compound metadata fields (
gene_name,label_type,smiles,adducts) use appropriate Cython types and support the enhanced I/O functionality for TSV/PQP formats.Also applies to: 72-75
92-93: LGTM: LightProtein uniprot_id field added.The
uniprot_idfield is properly typed and documented, supporting enhanced protein metadata in the Light data model.
Add test 6 (light path) and test 7 (heavy path) for OpenSwathDecoyGenerator to verify both code paths produce correct output: - Test 6: TSV -> TSV using LightTargetedExperiment (memory-efficient path) - Test 7: TSV -> TraML using TargetedExperiment (full feature path) Both tests use the same input (OpenSwathDecoyGenerator_input_4.tsv) and parameters to verify that the light and heavy paths generate equivalent decoy sequences. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Recent ChangesCodeRabbit Fixes (53de5fe)Addressed all valid issues from the CodeRabbit review:
New Tests (5ff3c8a)Added tests to verify both light and heavy decoy generation paths produce correct output:
Both tests use the same input (
All 14 OpenSwathDecoyGenerator tests pass. |
Add OPENMS_LOG_DEBUG statement when transitions are skipped due to unparseable sequences, improving debuggability. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (1)
812-819: Use OpenMS::String consistently (duplicate key construction).Line 813 uses
std::stringandstd::to_stringfor the duplicate key, matching the issue at line 702. This should also use OpenMSStringfor consistency.🔎 Proposed fix
// Check for duplicates - std::string decoy_key = std::string(decoy_temp_peptide.sequence) + std::to_string(decoy_compound.charge); + String decoy_key = String(decoy_temp_peptide.sequence) + String(decoy_compound.charge); if (allPeptideSequences.find(decoy_key) != allPeptideSequences.end())
🧹 Nitpick comments (5)
src/tests/topp/CMakeLists.txt (1)
1329-1341: OpenSwathDecoyGenerator light/heavy tests are well-wired; consider PQP coverage or clarifying the commentThe new tests correctly exercise the TSV light path (LightTargetedExperiment) and the TraML heavy path, with consistent parameters, use of
${DIFF}, and properset_tests_properties(... DEPENDS ...)to avoid parallel CTest races. As a small improvement, either:
- add an analogous PQP-based light-path test (e.g., TSV→PQP or PQP→PQP) to cover the PQP branch mentioned in the comment, or
- narrow the comment to TSV-only if PQP is validated elsewhere.
Based on learnings, the DEPENDS usage is spot on.
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (4)
674-678: Inconsistent exception message with heavy variant.The error message differs from the heavy
generateDecoysversion (line 401), which says "values larger than one currently not supported". Consider aligning the messages for consistency.🔎 Proposed alignment
- throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, - "Decoy fraction needs to be less than one"); + throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, + "Decoy fraction needs to be less than one (values larger than one currently not supported).");
695-706: Use OpenMS::String consistently instead of std::string.Lines 702 and 706 use
std::stringandstd::to_string, but the heavy variant (lines 426, 429) uses OpenMSString. The coding guidelines prefer OpenMS::String for numeric formatting and parsing.As per coding guidelines, OpenMS::String should be used for consistency and precision.
🔎 Proposed fix
// Create map of all peptide sequences to detect duplicates - std::unordered_map<std::string, std::string> allPeptideSequences; + std::unordered_map<String, String> allPeptideSequences; for (const auto& idx : selection_list) { const auto& compound = exp.compounds[idx]; if (compound.isPeptide()) { - allPeptideSequences[compound.sequence + std::to_string(compound.charge)] = compound.id; + allPeptideSequences[compound.sequence + String(compound.charge)] = compound.id; } } - std::unordered_set<std::string> exclusion_peptides; + std::unordered_set<String> exclusion_peptides;
807-810: Consider logging or validating unknown decoy methods.The
elsebranch silently falls back to using the original peptide sequence when the method doesn't match known values. The heavy variant doesn't have this explicit fallback. Consider adding a warning log or validation to catch configuration errors.🔎 Proposed defensive check
else { + OPENMS_LOG_WARN << "[peptide] Unknown decoy method '" << method << "' for " << decoy_compound.id << ", using original sequence" << std::endl; decoy_temp_peptide = temp_peptide; }
639-1006: Consider extracting helper methods to reduce complexity.Static analysis flagged this 367-line method as complex. While the implementation is functionally correct and mirrors the existing heavy variant, extracting helper methods for compound selection, peptide decoy generation, and transition processing would improve maintainability and testability.
Potential extractions:
- Selection logic (lines 669-693) →
selectCompoundsForDecoys- Peptide decoy generation (lines 746-834) →
generatePeptideDecoy- Transition generation (lines 878-966) →
generateDecoyTransitions- Filtering logic (lines 970-1001) →
filterExcludedEntitiesThis refactoring can be deferred to a follow-up PR if preferred.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
-
src/tests/topp/OpenSwathDecoyGenerator_output_6_light.tsvis excluded by!**/*.tsv
📒 Files selected for processing (3)
-
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp(1 hunks) -
src/tests/topp/CMakeLists.txt(1 hunks) -
src/tests/topp/OpenSwathDecoyGenerator_output_7_heavy.TraML(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/tests/topp/OpenSwathDecoyGenerator_output_7_heavy.TraMLsrc/tests/topp/CMakeLists.txtsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
src/tests/topp/CMakeLists.txt
📄 CodeRabbit inference engine (AGENTS.md)
src/tests/topp/CMakeLists.txt: Add TOPP tests in src/tests/topp/CMakeLists.txt
Use FuzzyDiff for numeric comparisons in tests; keep test data small; use whitelist for unstable lines
Files:
src/tests/topp/CMakeLists.txt
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
🧠 Learnings (15)
📓 Common learnings
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/topp/CMakeLists.txt : Add TOPP tests in src/tests/topp/CMakeLists.txt
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-09-03T12:58:20.032Z
Learnt from: timosachsenberg
Repo: OpenMS/OpenMS PR: 8177
File: src/tests/topp/CMakeLists.txt:1857-1865
Timestamp: 2025-09-03T12:58:20.032Z
Learning: OpenMS tests: When adding new TOPP tests in src/tests/topp/CMakeLists.txt that compare outputs via FuzzyDiff, always add set_tests_properties("<tool>_<n>_out<m>" PROPERTIES DEPENDS "<tool>_<n>") to avoid flakiness under parallel CTest runs.
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/topp/CMakeLists.txt : Use FuzzyDiff for numeric comparisons in tests; keep test data small; use whitelist for unstable lines
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/class_tests/**/*.cpp : Use NEW_TMP_FILE macro for each output file in tests; avoid side effects in comparison macros
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/topp/*.cpp : Add new C++ class source in src/topp/<Tool>.cpp and register in src/topp/executables.cmake
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/class_tests/**/*.cpp : Add unit/class test source in src/tests/class_tests/<lib>/source/ and register in executables.cmake
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/tests/class_tests/openms/**/*.cpp : Write unit tests for new functionality
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to doc/doxygen/public/TOPP.doxygen : Document TOPP tool and add to doc/doxygen/public/TOPP.doxygen where applicable
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: PR checklist: update AUTHORS and CHANGELOG, run/extend tests, update pyOpenMS bindings when needed
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/tests/class_tests/openms/*Test.cpp : Follow naming convention: `ClassNameTest.cpp` for `ClassName`
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/include/OpenMS/**/*.h : Add Doxygen comments for new public methods and classes
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Follow the established error handling patterns
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Utilize OpenMS logging mechanisms
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
🧬 Code graph analysis (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (1)
src/openms/source/CONCEPT/Exception.cpp (1)
IllegalArgument(247-250)
🪛 GitHub Check: CodeFactor
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
[notice] 639-1006: src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp#L639-L1006
Complex Method
🔇 Additional comments (2)
src/tests/topp/OpenSwathDecoyGenerator_output_7_heavy.TraML (1)
1-123: LGTM!This TraML test file is well-structured and follows the TraML 1.0.0 specification correctly. Key validations:
- The
.TraMLextension adheres to the coding guidelines (ML is an allowed exception to lowercase).- The decoy sequence
AATAATTAATTPATAAAAPAAAAAAAAACmatches the expected output per PR objectives.- All five transitions properly reference the decoy peptide, include correct b-ion annotations (ordinals 5-9), and are appropriately flagged with
MS:1002008(decoy SRM transition).- CV references use standard PSI-MS ontology terms.
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (1)
892-902: Excellent error handling for sequence parsing.The debug logging for unparseable sequences addresses the past review feedback and provides good debuggability for unexpected sequence formats.
singjc
left a comment
There was a problem hiding this comment.
From a quick scan of the code, things look fine. I will run a local test and take another deeper look a little later today.
There was a problem hiding this comment.
Not sure why this file was touched / included in this PR? I didn't think this was used / relevant for OpenSwaths Assay/Decoy Generator or TargetedFilteConverter?
| // Create a temporary heavy Peptide for decoy generation | ||
| OpenMS::TargetedExperiment::Peptide temp_peptide; |
There was a problem hiding this comment.
Why do we need to use a heavy Peptide structure for decoy generation
| bool detecting_transition{true}; | ||
| bool quantifying_transition{true}; |
There was a problem hiding this comment.
I'm not sure if we want these to be set to true by default? Not sure if there is existing logic in identification transition generation to explicitly set detecting and quantifying to false. Will need to check.
| add_test("TOPP_OpenSwathDecoyGenerator_test_5_out1" ${DIFF} -in1 OpenSwathDecoyGenerator_5.tmp.TraML -in2 ${DATA_DIR_TOPP}/OpenSwathDecoyGenerator_output_5.TraML) | ||
| set_tests_properties("TOPP_OpenSwathDecoyGenerator_test_5_out1" PROPERTIES DEPENDS "TOPP_OpenSwathDecoyGenerator_test_5") | ||
|
|
||
| # Test 6: Light path (TSV -> TSV) - tests the memory-efficient LightTargetedExperiment path |
There was a problem hiding this comment.
Seems like we didn't have existing PQP output tests? Maybe we should add?
There was a problem hiding this comment.
I think it is hard to verify the output of the .pqp file and that is why they are not there. I guess we could do a test which is pqp decoy generator then convert to tsv and compare output?
|
|
||
| TargetedExperiment targeted_exp; | ||
| // Use memory-efficient Light path for TSV/PQP → TSV/PQP when IPF is disabled | ||
| bool use_light_path = !enable_ipf |
There was a problem hiding this comment.
This is fine for the first iteration, but we will want to get the light data structures working for when IPF is enabled as well.
Addressed Review FeedbackI've implemented the changes based on @singjc's review comments: High Priority - Implemented ✅Pure light-path decoy generation (addresses comment on MRMDecoy.cpp:760) Added 5 new light-only methods to avoid temporary
Updated Medium Priority - Implemented ✅Documentation for detecting/quantifying defaults (addresses comment on TransitionExperiment.h:30) Added inline documentation explaining the default values and their usage in IPF workflows. PQP output tests (addresses comment on CMakeLists.txt:1329) Added roundtrip tests for PQP output in the light path. Low Priority - Deferred with TODO ✅IPF support for light path (addresses comment on OpenSwathAssayGenerator.cpp:248) Added TODO comment for future implementation. This requires additional work (MRMIonSeries light methods, transition type handling). Removed from PR ✅IDFilter.h changes (addresses comment on IDFilter.h) Reverted the unrelated C++20 build fix - should be in a separate PR. Testing
|
Address PR review feedback from singjc regarding memory efficiency: - Add reversePeptideLight() for light peptide sequence reversal - Add shufflePeptideLight() for light peptide shuffling with mods - Add pseudoreversePeptideLight_() for pseudo-reverse (keep C-term) - Add switchKRLight() for terminal K/R switching - Add hasCNterminalModsLight_() for terminal mod detection - Update generateDecoysLight() to use pure light methods These methods operate directly on std::string and LightModification vectors, avoiding temporary TargetedExperiment::Peptide allocations for improved memory efficiency with large spectral libraries. Also includes: - Documentation for detecting/quantifying transition defaults - PQP output tests for light path - TODO comment for future IPF light path support - Comprehensive unit tests comparing light vs heavy methods 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/pyOpenMS/setup.py (1)
195-196: C++20 update is correct, but Windows still uses C++17.The C++20 standard for Linux/macOS builds is appropriate, but as noted in the previous review comment, Windows remains on C++17 (lines 172-173), creating an ABI mismatch with the C++20-compiled OpenMS library. Please update Windows to C++20 as well.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.hsrc/pyOpenMS/setup.pysrc/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/topp/CMakeLists.txtsrc/topp/OpenSwathAssayGenerator.cpp
🧰 Additional context used
📓 Path-based instructions (10)
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/pyOpenMS/setup.pysrc/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/topp/CMakeLists.txtsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/topp/OpenSwathAssayGenerator.cppsrc/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
src/pyOpenMS/**/*.{pxd,pyx,py}
📄 CodeRabbit inference engine (AGENTS.md)
Use snake_case for Python-facing names and DataFrame columns in pyOpenMS
Files:
src/pyOpenMS/setup.py
src/tests/class_tests/openms/**/*.cpp
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Write unit tests for new functionality
Files:
src/tests/class_tests/openms/source/MRMDecoy_test.cpp
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/topp/OpenSwathAssayGenerator.cppsrc/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
src/tests/class_tests/**/*.cpp
📄 CodeRabbit inference engine (AGENTS.md)
src/tests/class_tests/**/*.cpp: Add unit/class test source in src/tests/class_tests//source/ and register in executables.cmake
Use NEW_TMP_FILE macro for each output file in tests; avoid side effects in comparison macros
Wrap template methods with 2+ arguments in parentheses when using START_SECTION macro
Files:
src/tests/class_tests/openms/source/MRMDecoy_test.cpp
src/tests/topp/CMakeLists.txt
📄 CodeRabbit inference engine (AGENTS.md)
src/tests/topp/CMakeLists.txt: Add TOPP tests in src/tests/topp/CMakeLists.txt
Use FuzzyDiff for numeric comparisons in tests; keep test data small; use whitelist for unstable lines
Files:
src/tests/topp/CMakeLists.txt
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
src/topp/*.cpp
📄 CodeRabbit inference engine (AGENTS.md)
src/topp/*.cpp: Use ProgressLogger in tools for progress reporting
Add new C++ class source in src/topp/.cpp and register in src/topp/executables.cmake
Define TOPP tool parameters in registerOptionsAndFlags_(); read with getStringOption_ and related helpers
Files:
src/topp/OpenSwathAssayGenerator.cpp
**/*.h
📄 CodeRabbit inference engine (AGENTS.md)
**/*.h: Use _impl.h only when needed; .h files must not include _impl.h
Do not use 'using namespace' or 'using std::...' in headers; allowed only in .cpp files
Prefer forward declarations in headers; include only base class headers, non-pointer members, and templates
Files:
src/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
src/openms/include/OpenMS/**/*.h
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Add Doxygen comments for new public methods and classes
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
🧠 Learnings (26)
📓 Common learnings
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: PR checklist: update AUTHORS and CHANGELOG, run/extend tests, update pyOpenMS bindings when needed
Applied to files:
src/pyOpenMS/setup.pysrc/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/topp/CMakeLists.txt
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/pyOpenMS/pxds/*.pxd : Keep .pxd signatures in sync with C++ APIs; update or remove wrap-ignore when wrapping changes
Applied to files:
src/pyOpenMS/setup.py
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/pyOpenMS/**/*.h : Add Doxygen comments for new public methods and classes in pyOpenMS bindings
Applied to files:
src/pyOpenMS/setup.py
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Regenerate pyOpenMS after addon changes by removing OpenMS-build/pyOpenMS/.cpp_extension_generated and rebuilding target pyopenms
Applied to files:
src/pyOpenMS/setup.py
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/pyOpenMS/**/*.pxd : Autowrap gotcha: autowrap returns Python strings; do not .decode(). Avoid cdef for autowrap string returns. Avoid cdef typed variables for autowrap return values inside def methods; use Python type checks. Keep addons minimal; avoid redundant aliases.
Applied to files:
src/pyOpenMS/setup.py
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/tests/class_tests/openms/**/*.cpp : Write unit tests for new functionality
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/topp/CMakeLists.txt
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/tests/class_tests/openms/*Test.cpp : Follow naming convention: `ClassNameTest.cpp` for `ClassName`
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/topp/CMakeLists.txt
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/topp/OpenSwathAssayGenerator.cppsrc/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/include/OpenMS/**/*.h : Add Doxygen comments for new public methods and classes
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
📚 Learning: 2025-09-03T12:58:20.032Z
Learnt from: timosachsenberg
Repo: OpenMS/OpenMS PR: 8177
File: src/tests/topp/CMakeLists.txt:1857-1865
Timestamp: 2025-09-03T12:58:20.032Z
Learning: OpenMS tests: When adding new TOPP tests in src/tests/topp/CMakeLists.txt that compare outputs via FuzzyDiff, always add set_tests_properties("<tool>_<n>_out<m>" PROPERTIES DEPENDS "<tool>_<n>") to avoid flakiness under parallel CTest runs.
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/topp/CMakeLists.txtsrc/topp/OpenSwathAssayGenerator.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/class_tests/**/*.cpp : Use NEW_TMP_FILE macro for each output file in tests; avoid side effects in comparison macros
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/topp/CMakeLists.txt
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/topp/CMakeLists.txt : Use FuzzyDiff for numeric comparisons in tests; keep test data small; use whitelist for unstable lines
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/topp/CMakeLists.txt
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/class_tests/**/*.cpp : Add unit/class test source in src/tests/class_tests/<lib>/source/ and register in executables.cmake
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/topp/CMakeLists.txt
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/topp/CMakeLists.txt : Add TOPP tests in src/tests/topp/CMakeLists.txt
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/topp/CMakeLists.txt
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use appropriate OpenMS containers and algorithms
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to **/*.{h,cpp,cxx,cc,hpp} : Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Be mindful of memory usage when processing large datasets
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/topp/*.cpp : Add new C++ class source in src/topp/<Tool>.cpp and register in src/topp/executables.cmake
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to doc/doxygen/public/TOPP.doxygen : Document TOPP tool and add to doc/doxygen/public/TOPP.doxygen where applicable
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Ensure existing tests pass before suggesting changes
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Follow the established error handling patterns
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Utilize OpenMS logging mechanisms
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
📚 Learning: 2025-07-29T10:05:48.015Z
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
Applied to files:
src/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.h
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/topp/*.cpp : Use ProgressLogger in tools for progress reporting
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
📚 Learning: 2025-10-15T07:49:09.293Z
Learnt from: timosachsenberg
Repo: OpenMS/OpenMS PR: 8177
File: src/openms/include/OpenMS/PROCESSING/CENTROIDING/PeakPickerIM.h:11-14
Timestamp: 2025-10-15T07:49:09.293Z
Learning: In OpenMS, DefaultParamHandler.h is located under OpenMS/DATASTRUCTURES/, not OpenMS/CONCEPT/. The correct include is: `#include <OpenMS/DATASTRUCTURES/DefaultParamHandler.h>`
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h
🧬 Code graph analysis (2)
src/tests/class_tests/openms/source/MRMDecoy_test.cpp (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (8)
pseudoreversePeptideLight_(441-447)pseudoreversePeptideLight_(441-443)hasCNterminalModsLight_(481-505)hasCNterminalModsLight_(481-484)reversePeptide(245-295)reversePeptide(245-247)reversePeptideLight(381-439)reversePeptideLight(381-386)
src/topp/OpenSwathAssayGenerator.cpp (4)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (2)
TransitionTSVFile(87-100)TransitionTSVFile(102-102)src/topp/TargetedFileConverter.cpp (1)
TransitionTSVFile(81-84)src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp (2)
TransitionPQPFile(26-29)TransitionPQPFile(31-31)src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp (2)
MRMAssay(22-22)MRMAssay(24-24)
🪛 GitHub Check: CodeFactor
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
[notice] 507-640: src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp#L507-L640
Complex Method
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: build-and-test (ubuntu-24.04, clang++, 17)
- GitHub Check: build-and-test (windows-2025, cl.exe, 14.44)
- GitHub Check: build-and-test (macos-14, xcode, 15.4)
- GitHub Check: build-and-test (ubuntu-24.04-arm, g++, 13)
- GitHub Check: build-and-test (ubuntu-24.04, g++, 13)
- GitHub Check: build-win
- GitHub Check: build-macos-arm
- GitHub Check: build-lnx
- GitHub Check: build-lnx-arm
- GitHub Check: cppcheck-test
🔇 Additional comments (27)
src/pyOpenMS/setup.py (4)
125-125: LGTM: Correct numpy include path API.Using
numpy.get_include()is the official, documented method. The previousnumpy.core.__path__[0]approach relied on internal implementation details and has been deprecated in recent numpy versions.
226-227: LGTM: Simplified boost_regex linkage.Using the generic
boost_regexlibrary name simplifies the configuration and should work with standard Boost installations. The warning comment appropriately notes that naming may vary by platform, which is helpful for troubleshooting.
91-91: No action required — the Qt6 migration for Linux is correctly implemented.The setup.py file correctly specifies Qt6 (Qt6Core and Qt6Network) for Linux builds on line 91, aligning with OpenMS's requirement for Qt 6 (>= 6.2). The change properly addresses the migration from Qt5 to Qt6 and will work correctly with OpenMS libraries compiled with Qt6 support.
178-178: Verify OpenMP runtime compatibility is correct.The Linux OpenMP runtime change to
gomp(GNU) is the correct choice when building with GCC, which is the standard compiler on Linux for OpenMS. GCC uses "-fopenmp" compiler flag, which links to libgomp by default. The code now properly matches the OpenMP runtime used in the OpenMS C++ library build rather than causing a mismatch. Ensure OpenMS CI/packaging on Linux builds with GCC rather than Clang.src/tests/class_tests/openms/source/MRMDecoy_test.cpp (5)
46-62: LGTM! Well-structured test helpers for light-path methods.The helper methods properly expose the protected
pseudoreversePeptideLight_and statichasCNterminalModsLight_for unit testing. The static helper correctly delegates to the static protected method.
550-676: Comprehensive parity tests for reversePeptideLight.Good coverage of:
- Single modification case
- Multiple modifications with keepN/keepC flags
- Full reverse (keepN=false, keepC=false)
- const_pattern parameter
- Empty modifications edge case
The tests validate that light and heavy implementations produce identical results.
746-889: Thorough shuffle parity testing.Tests cover multiple scenarios including modifications, terminal K/R preservation, and K/R/P pattern handling. Same seed usage ensures reproducible comparisons between light and heavy implementations.
891-932: Good coverage for switchKRLight.Tests K→R, R→K switching, and non-K/R terminal randomization. The test correctly accounts for the fact that randomization may differ between implementations while still validating the expected behavior.
934-1017: Complete terminal modification detection tests.All edge cases are covered: N-terminal, C-terminal, C-terminal AA position, internal modifications, empty modifications, and combined N+C terminal modifications.
src/openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/TransitionExperiment.h (3)
29-38: Good documentation for default values.The inline comments clearly explain why
detecting_transitionandquantifying_transitiondefault totrueand that loaders/converters explicitly set values from source data. This addresses the previous review concern about these defaults.
40-44: LGTM! New annotation fields for roundtrip I/O.The added fields (
fragment_nr,fragment_type,annotation,peptidoforms) support complete roundtrip TSV/PQP I/O. Default values are appropriate (-1for unset fragment number, empty strings).
162-165: LGTM! Extended LightCompound and LightProtein for complete roundtrip support.New fields for metabolomics (
smiles,adducts) and protein metadata (uniprot_id) enable full data preservation in light-path workflows.Also applies to: 200-202
src/topp/OpenSwathAssayGenerator.cpp (3)
247-254: Clear routing logic with documented TODO.The condition correctly routes to the light path when IPF is disabled and input/output formats are compatible (TSV/MRM/PQP). The TODO adequately documents the deferred work for IPF support in the light path.
370-387: Correct if/else-if chain for output handling.The output type handling now properly uses
if/else if/else iffor mutually exclusive branches (TSV → PQP → TraML), addressing the previous review feedback.
256-304: Light path skips validation by design; document the intentional data integrity trade-off.The light path intentionally does not perform input validation after loading, unlike the heavy path which calls
validateTargetedExperiment()(lines 319, 329). This is by design:validateTargetedExperiment()only acceptsTargetedExperiment, not the memory-efficientLightTargetedExperimentused in the light path. While this trade-off makes sense for the memory-efficient pathway, it means invalid data (duplicate/invalid references) could silently pass through without detection. Consider either: (1) documenting this intentional gap in code comments, or (2) implementing equivalent validation forLightTargetedExperimentif data integrity is critical.src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (7)
375-439: LGTM! reversePeptideLight correctly mirrors heavy version.The implementation follows the same algorithm as
reversePeptide(): finding fixed residues, building index, erasing fixed positions, reversing, re-inserting, and relocating modifications. The terminal modification handling (positions -1 and sequence.size()) is correctly preserved.
449-479: LGTM! switchKRLight implementation.Correctly handles empty sequence edge case (line 462) and mirrors the heavy version's logic for K↔R switching and randomization.
481-505: LGTM! hasCNterminalModsLight_ implementation.Clean static implementation that checks all three terminal modification cases: N-terminal (-1), C-terminal (sequence_length), and optionally C-terminal AA (sequence_length - 1).
507-639: Complexity is acceptable for parity with heavy version.The static analysis flagged this as complex, but the complexity is necessary to maintain exact parity with
shufflePeptide(). The implementation correctly:
- Uses the same Fisher-Yates shuffle algorithm
- Matches RNG call order (critical for reproducibility)
- Applies mutations every 10 attempts with correct ordering
- Persists mutations for subsequent iterations
The complexity is inherent to the algorithm and matches the heavy version.
1057-1071: Correct terminal modification check on shuffled result.The shuffle branch now correctly checks
hasCNterminalModsLight_ondecoy_mods/decoy_sequence(the shuffled result) rather than the original, addressing the previous review feedback.
1167-1177: Good error logging for sequence parsing failures.The catch block now logs a debug message when transition sequences cannot be parsed, improving debuggability as requested in previous feedback.
904-1281: Comprehensive light-path decoy generation.The implementation correctly:
- Handles proteins, compounds, and transitions
- Applies the same decoy methods (pseudo-reverse, reverse, shuffle)
- Manages duplicate detection and exclusion
- Builds proper UniMod notation for modified sequences
- Annotates fragment ions using MRMIonSeries
- Filters excluded peptides from final output
The structure mirrors
generateDecoys()while operating on light data structures.src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h (3)
106-144: Well-documented public API for light-path decoy generation.Complete Doxygen documentation with parameter descriptions. The signature mirrors
generateDecoys()while operating onOpenSwath::LightTargetedExperiment, maintaining API consistency.
204-252: Good public API design for light-path utilities.The public methods are:
reversePeptideLight- static, appropriate since it doesn't need instance stateshufflePeptideLight- const member, needs instance forfindFixedAndTermResidues_switchKRLight- static, stateless operationDocumentation is complete with parameter descriptions and return value documentation.
261-287: Appropriate protected helper methods.
hasCNterminalModsLight_is correctly marked static as it doesn't need instance state.pseudoreversePeptideLight_is const and delegates to the publicreversePeptideLight.src/tests/topp/CMakeLists.txt (2)
1329-1354: OpenSwathDecoyGenerator light/heavy/PQP tests are consistent and robustThe new tests cleanly cover the light TSV path (test 6), the heavy TraML path with identical parameters (test 7), and the light PQP→TSV roundtrip (test 8). Using the same input/parameters and a shared expected TSV makes the light vs heavy comparison meaningful, and the DEPENDS chains on the *_out1 checks correctly guard against parallel CTest flakiness. No issues from my side here.
1435-1441: TargetedFileConverter light-path TSV↔PQP roundtrip test matches existing patternsThe light-path TSV→PQP→TSV roundtrip test reuses the existing ConvertTSVToTraML_1_input.tsv, mirrors the structure of earlier PQP tests, and wires DEPENDS correctly. This should give good coverage for the new LightTargetedExperiment-based converter path without adding complexity.
Reduces code duplication by having heavy methods call their light counterparts with conversion helpers: - Add detail::toLightMods() to convert heavy Peptide::Modification to LightModification format - Add detail::applyLocationUpdates() to apply location changes back - shufflePeptide() now delegates to shufflePeptideLight() - reversePeptide() now delegates to reversePeptideLight() - switchKR() now delegates to switchKRLight() - hasCNterminalMods_() now delegates to hasCNterminalModsLight_() Also fixes identity comparison in shufflePeptideLight to compare against the working copy (peptide_seq) rather than original sequence, matching the original heavy method behavior where the peptide object gets updated during mutation phases. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add -sort flag to FuzzyDiff that sorts data lines before comparison (preserves header as first line) - Update PQP roundtrip test to use -sort flag since PQP reader returns transitions ordered by ID, not by original insertion order - Update light-path roundtrip test to use -sort flag - Add expected output files for roundtrip tests with correct TSV format (UniprotId is empty in PQP roundtrip since PQP format doesn't store it) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Latest UpdatesCommits added:
Test Results
Technical Notes
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
src/tests/topp/CMakeLists.txt (2)
1329-1356: OpenSwathDecoyGenerator light-path + PQP roundtrip tests look correct and well‑isolated
- Test 6 exercises TSV→TSV light path, Test 7 mirrors parameters on heavy TraML, and Test 8 adds a PQP→TSV roundtrip with
-sortto handle row ordering.- All
*_out1checks useFuzzyDiffvia${DIFF}and correctly declareDEPENDSon their generating tests, which should avoid parallel CTest races.No issues from my side; this is a solid coverage addition for the new light decoy/I/O paths.
If PQP→TSV ordering ever becomes more complex, consider documenting in a short comment near the
-sortflag what the stable sort key is intended to be (e.g. transition ID vs m/z) for future maintainers. Based on learnings, dependencies for FuzzyDiff tests are set up as recommended.
1437-1443: TargetedFileConverter light-path TSV↔PQP roundtrip test is consistent and dependency-safe
- The prepare and roundtrip steps are split into separate tests with
DEPENDSset, matching the existing TOPP testing pattern.FuzzyDiffis invoked with-sort, which is appropriate given PQP’s potentially different row ordering.Looks good and aligns with the light-path design and TOPP test conventions.
Minor: if you later add more light-path tests, grouping their comments under a short “LightTargetedExperiment roundtrips” header could make this block easier to scan. Based on learnings, FuzzyDiff and dependency usage follow the project guidelines.
src/topp/FuzzyDiff.cpp (1)
143-182: Optional: Consider memory usage for large files.The
sortFilelambda loads the entire file into memory (line 152-162). While acceptable for test files, this could be problematic for very large comparison files. Consider documenting this limitation or implementing an external sort if large-file support is needed in the future.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
-
src/tests/topp/OpenSwathDecoyGenerator_output_8_pqp_roundtrip.tsvis excluded by!**/*.tsv -
src/tests/topp/TargetedFileConverter_light_path_output.tsvis excluded by!**/*.tsv
📒 Files selected for processing (3)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/tests/topp/CMakeLists.txtsrc/topp/FuzzyDiff.cpp
🧰 Additional context used
📓 Path-based instructions (5)
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/tests/topp/CMakeLists.txtsrc/topp/FuzzyDiff.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
src/tests/topp/CMakeLists.txt
📄 CodeRabbit inference engine (AGENTS.md)
src/tests/topp/CMakeLists.txt: Add TOPP tests in src/tests/topp/CMakeLists.txt
Use FuzzyDiff for numeric comparisons in tests; keep test data small; use whitelist for unstable lines
Files:
src/tests/topp/CMakeLists.txt
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/topp/FuzzyDiff.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
src/topp/*.cpp
📄 CodeRabbit inference engine (AGENTS.md)
src/topp/*.cpp: Use ProgressLogger in tools for progress reporting
Add new C++ class source in src/topp/.cpp and register in src/topp/executables.cmake
Define TOPP tool parameters in registerOptionsAndFlags_(); read with getStringOption_ and related helpers
Files:
src/topp/FuzzyDiff.cpp
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
🧠 Learnings (21)
📓 Common learnings
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/topp/CMakeLists.txt : Add TOPP tests in src/tests/topp/CMakeLists.txt
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-09-03T12:58:20.032Z
Learnt from: timosachsenberg
Repo: OpenMS/OpenMS PR: 8177
File: src/tests/topp/CMakeLists.txt:1857-1865
Timestamp: 2025-09-03T12:58:20.032Z
Learning: OpenMS tests: When adding new TOPP tests in src/tests/topp/CMakeLists.txt that compare outputs via FuzzyDiff, always add set_tests_properties("<tool>_<n>_out<m>" PROPERTIES DEPENDS "<tool>_<n>") to avoid flakiness under parallel CTest runs.
Applied to files:
src/tests/topp/CMakeLists.txtsrc/topp/FuzzyDiff.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/topp/CMakeLists.txt : Use FuzzyDiff for numeric comparisons in tests; keep test data small; use whitelist for unstable lines
Applied to files:
src/tests/topp/CMakeLists.txtsrc/topp/FuzzyDiff.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/topp/*.cpp : Add new C++ class source in src/topp/<Tool>.cpp and register in src/topp/executables.cmake
Applied to files:
src/tests/topp/CMakeLists.txtsrc/topp/FuzzyDiff.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/class_tests/**/*.cpp : Use NEW_TMP_FILE macro for each output file in tests; avoid side effects in comparison macros
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/tests/class_tests/openms/**/*.cpp : Write unit tests for new functionality
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/class_tests/**/*.cpp : Add unit/class test source in src/tests/class_tests/<lib>/source/ and register in executables.cmake
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to doc/doxygen/public/TOPP.doxygen : Document TOPP tool and add to doc/doxygen/public/TOPP.doxygen where applicable
Applied to files:
src/tests/topp/CMakeLists.txtsrc/topp/FuzzyDiff.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: PR checklist: update AUTHORS and CHANGELOG, run/extend tests, update pyOpenMS bindings when needed
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/tests/class_tests/openms/*Test.cpp : Follow naming convention: `ClassNameTest.cpp` for `ClassName`
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Ensure existing tests pass before suggesting changes
Applied to files:
src/tests/topp/CMakeLists.txt
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use appropriate OpenMS containers and algorithms
Applied to files:
src/topp/FuzzyDiff.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/topp/*.cpp : Define TOPP tool parameters in registerOptionsAndFlags_(); read with getStringOption_ and related helpers
Applied to files:
src/topp/FuzzyDiff.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to **/*.{h,cpp,cxx,cc,hpp} : Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Applied to files:
src/topp/FuzzyDiff.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/topp/FuzzyDiff.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Be mindful of memory usage when processing large datasets
Applied to files:
src/topp/FuzzyDiff.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Consider algorithmic complexity for data processing operations
Applied to files:
src/topp/FuzzyDiff.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/include/OpenMS/**/*.h : Add Doxygen comments for new public methods and classes
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Follow the established error handling patterns
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Utilize OpenMS logging mechanisms
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
🧬 Code graph analysis (1)
src/topp/FuzzyDiff.cpp (1)
src/openms/source/CONCEPT/Exception.cpp (2)
FileNotFound(166-170)UnableToCreateFile(235-239)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: build-and-test (windows-2025, cl.exe, 14.44)
- GitHub Check: build-and-test (ubuntu-24.04-arm, g++, 13)
- GitHub Check: build-and-test (ubuntu-24.04, clang++, 17)
- GitHub Check: build-and-test (ubuntu-24.04, g++, 13)
- GitHub Check: build-and-test (macos-14, xcode, 15.4)
- GitHub Check: build-win
- GitHub Check: build-macos-arm
- GitHub Check: build-lnx
- GitHub Check: build-lnx-arm
- GitHub Check: cppcheck-test
🔇 Additional comments (12)
src/topp/FuzzyDiff.cpp (3)
13-16: LGTM! Necessary includes for sorting feature.The added headers support temporary file handling (File.h), sorting (algorithm), and file I/O (fstream).
84-85: LGTM! Clear flag documentation.The flag description appropriately documents the header-preservation behavior.
104-104: LGTM! Standard flag reading.src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (9)
102-134: LGTM! Clean delegation helpers.The conversion functions correctly extract minimal data (location + unimod_id) for the light path and apply location updates back to heavy structures. The size precondition in
applyLocationUpdatesprovides good safety.
136-160: LGTM! Proper delegation to light implementation.The refactored
shufflePeptidecorrectly delegates to the light implementation while preserving the original interface. The conversion and location update pattern is consistent.
162-201: LGTM! Consistent delegation pattern across methods.All heavy-path methods correctly delegate to their light counterparts with proper conversion. The pattern is consistent and preserves the original interfaces.
228-286: LGTM! Correct light-path reverse implementation.The algorithm correctly handles fixed residues and terminal modifications. The index mapping logic properly relocates modifications while preserving terminal mod positions.
288-294: LGTM! Correct pseudo-reverse delegation.The method correctly delegates to
reversePeptideLightwith parameters matching the heavy-path behavior.
296-326: LGTM! Correct K/R switching logic.The light implementation correctly handles K↔R switching and randomization. The static RNG ensures deterministic behavior across calls.
328-352: LGTM! Correct terminal modification detection.The function correctly identifies N-terminal (-1), C-terminal (sequence_length), and optionally the C-terminal AA modifications.
354-487: LGTM! Comprehensive shuffle implementation.The Fisher-Yates shuffle, modification relocation, and mutation logic (every 10 attempts) are correctly implemented. The RNG call order (pick AA first, then position) matches the heavy version, ensuring deterministic behavior. The identity threshold check and mutation persistence are properly handled.
752-1129: LGTM! Comprehensive light-path decoy generation.The implementation correctly mirrors the heavy-path logic while operating on
LightTargetedExperimentstructures. Key strengths:
- Proper handling of selection fractions, duplicate detection, and exclusion filtering
- Correct application of decoy methods (pseudo-reverse, reverse, shuffle) with terminal modification checks
- Safe charge handling (defaults to 1 when ≤ 0, preventing division by zero)
- Appropriate error handling with debug logging for unparseable sequences
- Efficient use of maps/sets and move semantics
The shuffle method correctly checks terminal mods on the shuffled result (line 910), consistent with the fix in commit 53de5fe.
Add memory-efficient light version of uisTransitions() to enable IPF (Identification Peptide Fragment) workflows for large-scale spectral libraries without loading full TargetedExperiment objects. Key implementations: - generateTargetInSilicoMapLight_(): Generate theoretical peptidoforms - generateDecoyInSilicoMapLight_(): Generate decoy peptidoforms - generateTargetAssaysLight_(): Create UIS transitions with peptidoforms - generateDecoyAssaysLight_(): Create decoy UIS transitions (filtered) - uisTransitionsLight(): Main orchestrator following 4-step pipeline Critical bug fixes applied during review: - Use target peptide's SWATH index for decoy generation (not decoy's) - Use target compound id as DecoyPeptideMap key (matching heavy version) - Remove incorrect DECOY_ prefix stripping in decoy assay generation Update OpenSwathAssayGenerator to use light path with -enable_ipf when input/output formats support it (PQP, TSV, MRM). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix getAASequenceFromLightCompound() to handle both PQP input (full modified sequence) and TraML input (unmodified + modifications vector) - Fix generateDecoyAssaysLight_() to use target_precursor_swath for DecoyIonMap lookup (matching heavy path behavior) - Add UIS SWATH window generation and post-IPF restriction to light path - Add command-line parameters for IPF decoy seed and disable flag - Add class tests for uisTransitionsLight() with light/heavy equivalence - Add TOPP test for PQP input with IPF enabled (test_4) - Remove duplicate include in MRMDecoy_test.cpp 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/topp/OpenSwathAssayGenerator.cpp (1)
191-415: Align light-path IPF SWATH window generation with heavy pathThe light-path IPF block (lines 290–315) deviates from the heavy implementation in two ways:
Window count calculation: Light path uses
static_cast<size_t>((precursor_upper_mz_limit - precursor_lower_mz_limit) / precursor_mz_threshold)which truncates the result, whereas the heavy path usesMath::round()to round to the nearest integer. This can yield different window counts due to floating-point rounding, causing subtle behavioral divergence.Missing flag check: Light path ignores the
enable_swath_specifityflag entirely and always synthesizes UIS windows whenswathes.empty(), while the heavy path checksif (!enable_swath_specifity)before synthesis. This breaks parameter consistency and contradicts the comment "same logic as heavy path."To keep IPF behavior consistent and respect the configuration flag, mirror the heavy logic in the light path using
Math::round()and theenable_swath_specifityguard.
🧹 Nitpick comments (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp (1)
1194-2077: Light MRMAssay implementation appears behaviorally aligned with heavy pathThe new Light variants (reannotate/restrict/detecting/UIS IPF helpers and uisTransitionsLight) follow the structure and data flow of the existing heavy implementations:
- AASequence reconstruction from LightCompound correctly distinguishes PQP-style “sequence contains mods” from TraML-style “sequence + modifications[]” and avoids double-applying modifications.
- Target/decoy in‑silico maps and assay generation reuse the same SequenceMapT / IonMapT / PeptideMapT concepts, keyed by unmodified sequences and SWATH index, and keep the target/decoy ID wiring consistent with the heavy code.
- detectingTransitionsLight mirrors the heavy selection logic (intensity ranking, min/max transitions, decoy exclusion) while operating on LightTransition and LightCompound/LightProtein, which matches the unified-compounds design.
- uisTransitionsLight appends new identifying and decoy transitions to the existing experiment, just like the heavy version does via copy‑modify‑set.
The only nit is the small unused
compound_mapin restrictTransitionsLight, which could be removed in a follow-up cleanup, but it doesn’t affect behavior. Overall, the light-path implementation looks sound and in sync with the established MRMAssay behavior.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cppsrc/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/topp/CMakeLists.txtsrc/tests/topp/OpenSwathAssayGenerator_input_4.pqpsrc/tests/topp/OpenSwathAssayGenerator_output_4.pqpsrc/topp/OpenSwathAssayGenerator.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
- src/tests/topp/CMakeLists.txt
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/topp/OpenSwathAssayGenerator.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/topp/OpenSwathAssayGenerator.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp
src/topp/*.cpp
📄 CodeRabbit inference engine (AGENTS.md)
src/topp/*.cpp: Use ProgressLogger in tools for progress reporting
Add new C++ class source in src/topp/.cpp and register in src/topp/executables.cmake
Define TOPP tool parameters in registerOptionsAndFlags_(); read with getStringOption_ and related helpers
Files:
src/topp/OpenSwathAssayGenerator.cpp
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp
src/openms/include/OpenMS/**/*.h
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Add Doxygen comments for new public methods and classes
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h
**/*.h
📄 CodeRabbit inference engine (AGENTS.md)
**/*.h: Use _impl.h only when needed; .h files must not include _impl.h
Do not use 'using namespace' or 'using std::...' in headers; allowed only in .cpp files
Prefer forward declarations in headers; include only base class headers, non-pointer members, and templates
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h
src/tests/class_tests/openms/**/*.cpp
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Write unit tests for new functionality
Files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cpp
src/tests/class_tests/**/*.cpp
📄 CodeRabbit inference engine (AGENTS.md)
src/tests/class_tests/**/*.cpp: Add unit/class test source in src/tests/class_tests//source/ and register in executables.cmake
Use NEW_TMP_FILE macro for each output file in tests; avoid side effects in comparison macros
Wrap template methods with 2+ arguments in parentheses when using START_SECTION macro
Files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cpp
🧠 Learnings (22)
📓 Common learnings
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/topp/OpenSwathAssayGenerator.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Utilize OpenMS logging mechanisms
Applied to files:
src/topp/OpenSwathAssayGenerator.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h
📚 Learning: 2025-09-03T12:58:20.032Z
Learnt from: timosachsenberg
Repo: OpenMS/OpenMS PR: 8177
File: src/tests/topp/CMakeLists.txt:1857-1865
Timestamp: 2025-09-03T12:58:20.032Z
Learning: OpenMS tests: When adding new TOPP tests in src/tests/topp/CMakeLists.txt that compare outputs via FuzzyDiff, always add set_tests_properties("<tool>_<n>_out<m>" PROPERTIES DEPENDS "<tool>_<n>") to avoid flakiness under parallel CTest runs.
Applied to files:
src/topp/OpenSwathAssayGenerator.cppsrc/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/topp/*.cpp : Define TOPP tool parameters in registerOptionsAndFlags_(); read with getStringOption_ and related helpers
Applied to files:
src/topp/OpenSwathAssayGenerator.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/include/OpenMS/**/*.h : Add Doxygen comments for new public methods and classes
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp
📚 Learning: 2025-08-14T10:19:54.371Z
Learnt from: jpfeuffer
Repo: OpenMS/OpenMS PR: 8167
File: src/topp/Digestor.cpp:200-226
Timestamp: 2025-08-14T10:19:54.371Z
Learning: In OpenMS (C++ bioinformatics framework), use boost random libraries instead of std library random distributions for cross-platform reproducible random number generation, as std library distributions are not reproducible across platforms.
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/topp/*.cpp : Use ProgressLogger in tools for progress reporting
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use appropriate OpenMS containers and algorithms
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/tests/class_tests/openms/**/*.cpp : Write unit tests for new functionality
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Be mindful of memory usage when processing large datasets
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Consider algorithmic complexity for data processing operations
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to **/*.{h,cpp,cxx,cc,hpp} : Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.hsrc/tests/class_tests/openms/source/MRMDecoy_test.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to **/*.{h,cpp,cxx,cc,hpp} : Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Applied to files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/tests/class_tests/openms/*Test.cpp : Follow naming convention: `ClassNameTest.cpp` for `ClassName`
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/class_tests/**/*.cpp : Use NEW_TMP_FILE macro for each output file in tests; avoid side effects in comparison macros
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: PR checklist: update AUTHORS and CHANGELOG, run/extend tests, update pyOpenMS bindings when needed
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/topp/CMakeLists.txt : Use FuzzyDiff for numeric comparisons in tests; keep test data small; use whitelist for unstable lines
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/topp/CMakeLists.txt : Add TOPP tests in src/tests/topp/CMakeLists.txt
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cpp
📚 Learning: 2025-12-20T17:04:02.760Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.760Z
Learning: Applies to src/tests/class_tests/**/*.cpp : Add unit/class test source in src/tests/class_tests/<lib>/source/ and register in executables.cmake
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cppsrc/tests/class_tests/openms/source/MRMAssay_test.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Follow the established error handling patterns
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cpp
📚 Learning: 2025-10-15T07:49:09.293Z
Learnt from: timosachsenberg
Repo: OpenMS/OpenMS PR: 8177
File: src/openms/include/OpenMS/PROCESSING/CENTROIDING/PeakPickerIM.h:11-14
Timestamp: 2025-10-15T07:49:09.293Z
Learning: In OpenMS, DefaultParamHandler.h is located under OpenMS/DATASTRUCTURES/, not OpenMS/CONCEPT/. The correct include is: `#include <OpenMS/DATASTRUCTURES/DefaultParamHandler.h>`
Applied to files:
src/tests/class_tests/openms/source/MRMDecoy_test.cpp
🧬 Code graph analysis (3)
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp (16)
reannotateTransitionsLight(1198-1334)reannotateTransitionsLight(1198-1205)restrictTransitionsLight(1336-1380)restrictTransitionsLight(1336-1339)detectingTransitionsLight(1382-1477)detectingTransitionsLight(1382-1384)uisTransitionsLight(2021-2077)uisTransitionsLight(2021-2032)generateTargetInSilicoMapLight_(1559-1643)generateTargetInSilicoMapLight_(1559-1570)generateDecoyInSilicoMapLight_(1645-1748)generateDecoyInSilicoMapLight_(1645-1657)generateTargetAssaysLight_(1750-1865)generateTargetAssaysLight_(1750-1756)generateDecoyAssaysLight_(1867-2019)generateDecoyAssaysLight_(1867-1875)
src/tests/class_tests/openms/source/MRMDecoy_test.cpp (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (10)
pseudoreversePeptideLight_(288-294)pseudoreversePeptideLight_(288-290)hasCNterminalModsLight_(328-352)hasCNterminalModsLight_(328-331)reversePeptide(162-175)reversePeptide(162-164)reversePeptideLight(228-286)reversePeptideLight(228-233)switchKRLight(296-326)switchKRLight(296-296)
src/tests/class_tests/openms/source/MRMAssay_test.cpp (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp (4)
uisTransitionsLight(2021-2077)uisTransitionsLight(2021-2032)uisTransitions(975-1021)uisTransitions(975-986)
🪛 GitHub Check: CodeFactor
src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp
[notice] 1198-1335: src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp#L1198-L1335
Complex Method
[notice] 1382-1478: src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp#L1382-L1478
Complex Method
[notice] 1867-2020: src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp#L1867-L2020
Complex Method
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: build-and-test (ubuntu-24.04, clang++, 17)
- GitHub Check: build-and-test (windows-2025, cl.exe, 14.44)
- GitHub Check: build-and-test (ubuntu-24.04, g++, 13)
- GitHub Check: build-and-test (ubuntu-24.04-arm, g++, 13)
- GitHub Check: build-and-test (macos-14, xcode, 15.4)
- GitHub Check: build-lnx
- GitHub Check: build-win
- GitHub Check: build-lnx-arm
- GitHub Check: build-macos-arm
- GitHub Check: cppcheck-test
🔇 Additional comments (3)
src/tests/class_tests/openms/source/MRMAssay_test.cpp (1)
14-1002: Light-path UIS tests look correct and provide good parity coverageThe new uisTransitionsLight section and the [EXTRA] equivalence test correctly mirror the heavy-path configuration (same input TraML, SWATH windows, fragment settings, and shuffle seed), and validate both the presence of identifying target/decoy transitions and count parity between heavy and light paths. This is a solid functional regression guard for the new light implementation, and I don’t see issues in the test logic.
src/tests/class_tests/openms/source/MRMDecoy_test.cpp (1)
18-1016: Heavy–light decoy/peptide parity tests are well structuredThe additional helper methods and [EXTRA] sections exercise the new light implementations (reverse/pseudoreverse, shuffle, KR-switch, terminal-mod detection) against the existing heavy ones with shared seeds and mod locations. This gives very strong behavioral parity coverage for the new light-path code in MRMDecoy without introducing questionable assumptions. No issues from the test side.
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMAssay.h (1)
15-565: Light MRMAssay API surface and documentation look consistentThe added LightTargetedExperiment-based methods and IPF helpers mirror the existing heavy APIs in both signature and documented semantics, and the TransitionExperiment.h include cleanly introduces the required OpenSwath light types without polluting the header (no
using namespace). This is in line with the design where LightTargetedExperiment unifies peptide-like entities incompounds, and the public documentation is sufficient for callers.
(Based on learnings, Light* entities are expected to live in a unified compounds collection.)
|
Initial testing with the 2014 panhuman library (with IM appended) with TargetedFileConverter shows that we are getting improvements in memory consumption. Before After Before worrying about reducing memory further though, I did notice that the outputs vary slightly currently. Some fields that were previously encoded as NA are now just blank. Before After: Although this likely does not have practical implications it would be good to have consistent behaviour with the old code. Some columns that were previously NA and now blank include: PeptideGroupLabel and GeneName |
|
Thanks for testing! and totally agree that output should be the same. I want to get this perfect first and then continue looking into improvements. |
jcharkow
left a comment
There was a problem hiding this comment.
For an exploratory investigation everything looks good however it seems that it could probably reuse code from the heavy methods a lot more.
General Comments:
Would it be better to overload the methods instead of creating new methods? It seems that a lot of code is duplicated from the heavy methods that do not need to be.
| // | ||
| // Helper functions for converting between heavy and light modification formats | ||
| // | ||
| namespace detail |
There was a problem hiding this comment.
I've never seen namespace detail used in the codebase? Is that standard?
| // Open database | ||
| SqliteConnector conn(filename); | ||
|
|
||
| // Create SQL structure (same as heavy version) |
There was a problem hiding this comment.
This could be a shared method with the heavy version
There was a problem hiding this comment.
the SQL initialisation step
| extra_link_args.append("-std=c++20") | ||
| extra_compile_args.append("-std=c++20") |
There was a problem hiding this comment.
This should probably not be changed either here?
There was a problem hiding this comment.
We should not need separate outputs for light and heavy since outputs should be the same?
| assays.restrictTransitionsLight(light_exp, product_lower_mz_limit, product_upper_mz_limit, swathes); | ||
| assays.detectingTransitionsLight(light_exp, min_transitions, max_transitions); | ||
|
|
||
| if (!enable_swath_specifity) |
There was a problem hiding this comment.
seems that this is just removed?
Sounds good that makes sense. I hope that we can get further improvements though or else the dynamic CVTermList initiation might be a better path forward. It seems that CVTermList is already inheriting from MetaInfoInterface which is lightweight however CVTermList itself is not lightweight since it is always initiating cv_terms_ perhaps, we should also try just switching this functionality to be a null pointer if there are no cv terms? From claude Haiku Previously when I saw the memory improvements I removed the inheritance but just replacing with pointers there is less of an improvement. EDIT: I played around with the above suggestions and it does not seem that it has a huge impact on memory usage. Thus it is probably best to just stick with the light format. I suspect that my biggest memory improvements in my previous implementation is the replacement of the Basically previously the interpretation list was replaced with just the ordinal and ion type which I believe is what the light implementation does. TLDR: Probably best to switch with the light format rather than optimising TargetedExperiment For more info on my previous implementation see branch: https://github.com/jcharkow/OpenMS/tree/refactorTargetedExp |
- Default empty GeneName and PeptideGroupLabel fields to "NA" - Change CollisionEnergy format from "-1" to "-1.0" for consistency - Update expected test output files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp (3)
243-571: Significant code duplication withreadPQPInput_for SQL query construction.Lines 272-393 (SQL query building logic) are nearly identical to the corresponding section in
readPQPInput_(lines 62-183). Consider extracting the SQL query construction into a shared private helper method to reduce duplication and improve maintainability.💡 Suggested refactoring approach
Extract a helper method that returns the constructed SQL query string:
std::string buildPQPSelectQuery_(bool legacy_traml_id, bool drift_time_exists, bool gene_exists, bool annotation_exists, bool adducts_exists) const;This would eliminate ~120 lines of duplication between
readPQPInput_andstreamPQPToLightTargetedExperiment_.
1077-1168: Consider extracting CREATE TABLE SQL to shared constant.The CREATE TABLE SQL statements (lines 1077-1168) are identical to those in
writePQPOutput_(lines 582-678). This ~90-line duplication could be eliminated by extracting to a shared constant or helper method.This addresses reviewer jcharkow's comment about "shared method with the heavy version" for "the SQL initialisation step."
💡 Suggested approach
Extract to a file-level or class-level constant:
namespace { const char* PQP_CREATE_TABLES_SQL = "CREATE TABLE VERSION(" \ "ID INT NOT NULL);" \ // ... rest of CREATE TABLE statements ; }Then both methods can reference this shared constant.
1312-1371: Consider refactoring: Precursor insertion logic could be simplified.The nested if-else block for peptide vs. compound precursors (lines 1317-1370) spans ~55 lines and contains substantial duplication in the INSERT statement construction. Consider extracting to a helper method or restructuring for improved readability.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.hsrc/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
🧰 Additional context used
📓 Path-based instructions (5)
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.hsrc/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
src/openms/include/OpenMS/**/*.h
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Add Doxygen comments for new public methods and classes
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.h
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.hsrc/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
**/*.h
📄 CodeRabbit inference engine (AGENTS.md)
**/*.h: Use _impl.h only when needed; .h files must not include _impl.h
Do not use 'using namespace' or 'using std::...' in headers; allowed only in .cpp files
Prefer forward declarations in headers; include only base class headers, non-pointer members, and templates
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.h
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.hsrc/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
🧠 Learnings (3)
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
📚 Learning: 2025-12-20T17:04:02.774Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.774Z
Learning: Applies to **/*.{h,cpp,cxx,cc,hpp} : Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Utilize OpenMS logging mechanisms
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
🧬 Code graph analysis (2)
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.h (1)
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp (4)
streamPQPToLightTargetedExperiment_(243-571)streamPQPToLightTargetedExperiment_(243-243)convertLightTargetedExperimentToPQP(1069-1487)convertLightTargetedExperimentToPQP(1069-1069)
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp (1)
src/openms/include/OpenMS/FORMAT/SqliteConnector.h (1)
columnExists(90-93)
🪛 GitHub Check: CodeFactor
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
[notice] 243-572: src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp#L243-L572
Complex Method
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: build-and-test (macos-14, xcode, 15.4)
- GitHub Check: build-win
- GitHub Check: build-lnx-arm
- GitHub Check: build-and-test (ubuntu-24.04, clang++, 17)
🔇 Additional comments (6)
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.h (2)
204-215: LGTM! Well-documented streaming method.The Doxygen comment is clear and informative, and the performance claim aligns with the PR objectives. The private method signature is appropriate for this internal optimization.
242-248: LGTM! Public API addition is well-documented.The method signature mirrors the existing heavy-path API, providing consistency. Documentation is adequate for a writer method.
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp (4)
13-13: LGTM! Proper logging include.The LogStream include is appropriate for the OPENMS_LOG_DEBUG usage in the streaming function (line 532).
Based on learnings: Use OpenMS logging mechanisms.
42-43: LGTM! Improved comment clarity.The expanded comments clearly explain the legacy_traml_id toggle behavior, making the code more maintainable.
502-533: Good defensive programming with AASequence parsing.The try-catch block around AASequence parsing with appropriate debug logging is a solid approach to handle potentially invalid sequences gracefully.
Based on learnings: Use OpenMS logging mechanisms.
1065-1067: LGTM! Clean delegation to streaming parser.The switch to the streaming parser achieves the memory-efficiency goals mentioned in the PR objectives.
|
Update after streaming, max memory only 966Mb! |
…ula, SMILES Remove NA handling for these 4 fields to match heavy-path output format. Only Adducts remains as NA when not set. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (3)
670-670: Consider validating fragment_charge before casting to int8_t.The cast from
int(returned bytoInt()) toint8_tcould theoretically overflow if the charge value is outside the range [-128, 127]. While fragment charges are typically small in practice, adding a validation check or documenting the assumption would improve robustness.🔎 Proposed validation
- transition.fragment_charge = static_cast<int8_t>(tr_it->fragment_charge.toInt()); + int charge = tr_it->fragment_charge.toInt(); + if (charge < -128 || charge > 127) + { + throw Exception::InvalidValue(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, + "Fragment charge out of range for int8_t", String(charge)); + } + transition.fragment_charge = static_cast<int8_t>(charge);
707-739: Extract duplicated modification parsing logic to a helper method.The code for parsing N-terminal, C-terminal, and residue modifications from
AASequence(lines 707-739 and 1098-1129) is duplicated. Extracting this to a helper method would improve maintainability and reduce code duplication.🔎 Proposed helper method
// Add to private section of TransitionTSVFile class void parseModificationsToLight_(const String& sequence, std::vector<OpenSwath::LightModification>& modifications) const;Then implement:
void TransitionTSVFile::parseModificationsToLight_( const String& sequence, std::vector<OpenSwath::LightModification>& modifications) const { try { AASequence aa_sequence = AASequence::fromString(sequence); if (aa_sequence.hasNTerminalModification()) { OpenSwath::LightModification mod; mod.location = -1; mod.unimod_id = aa_sequence.getNTerminalModification()->getUniModRecordId(); modifications.push_back(mod); } if (aa_sequence.hasCTerminalModification()) { OpenSwath::LightModification mod; mod.location = static_cast<int>(aa_sequence.size()); mod.unimod_id = aa_sequence.getCTerminalModification()->getUniModRecordId(); modifications.push_back(mod); } for (Size i = 0; i != aa_sequence.size(); i++) { if (aa_sequence[i].isModified()) { OpenSwath::LightModification mod; mod.location = static_cast<int>(i); mod.unimod_id = aa_sequence.getResidue(i).getModification()->getUniModRecordId(); modifications.push_back(mod); } } } catch (Exception::InvalidValue&) { OPENMS_LOG_DEBUG << "Could not parse modifications from sequence: " << sequence << std::endl; } }Replace both occurrences with:
parseModificationsToLight_(sequence, compound.modifications);Also applies to: 1098-1129
781-1166: High complexity is acceptable given memory-efficiency goals, but consider future refactoring.This 385-line streaming method is flagged by static analysis for complexity. The design achieves ~5× memory reduction (per comment on line 1929) by processing line-by-line without buffering all transitions. While this duplicates logic from
readUnstructuredTSVInput_, the performance benefits align with the PR's memory-efficiency objectives.For future maintainability, consider whether helper methods could extract repeated logic (header parsing, field extraction, compound/protein creation) without sacrificing the streaming benefits.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
-
src/tests/topp/OpenSwathDecoyGenerator_output_6_light.tsvis excluded by!**/*.tsv -
src/tests/topp/OpenSwathDecoyGenerator_output_8_pqp_roundtrip.tsvis excluded by!**/*.tsv -
src/tests/topp/TargetedFileConverter_light_path_output.tsvis excluded by!**/*.tsv
📒 Files selected for processing (1)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
🧰 Additional context used
📓 Path-based instructions (3)
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.774Z
Learning: PR checklist: update AUTHORS and CHANGELOG, run/extend tests, update pyOpenMS bindings when needed
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
📚 Learning: 2025-07-29T10:05:48.015Z
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
🧬 Code graph analysis (1)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (1)
src/openms/include/OpenMS/CONCEPT/Types.h (1)
writtenDigits(264-267)
🪛 GitHub Check: CodeFactor
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
[notice] 781-1166: src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp#L781-L1166
Complex Method
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: build-and-test (windows-2025, cl.exe, 14.44)
- GitHub Check: build-and-test (ubuntu-24.04, g++, 13)
- GitHub Check: build-and-test (macos-14, xcode, 15.4)
- GitHub Check: build-and-test (ubuntu-24.04, clang++, 17)
- GitHub Check: build-and-test (ubuntu-24.04-arm, g++, 13)
- GitHub Check: build-lnx
- GitHub Check: build-win
- GitHub Check: build-lnx-arm
- GitHub Check: build-macos-arm
- GitHub Check: cppcheck-test
🔇 Additional comments (3)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (3)
1024-1050: Inline mixed-sequence-group detection is correctly adapted for streaming.The inline detection logic (lines 1024-1050) replicates the behavior of
resolveMixedSequenceGroups_but operates on each transition as it's parsed. This duplication is necessary for the streaming approach, since you cannot perform a separate resolution pass without buffering all transitions. The logic correctly respectsoverride_group_label_check_and emits appropriate warnings.
1927-1931: Memory-efficient streaming parser successfully integrated.The switch to
streamTSVToLightTargetedExperiment_achieves the stated ~5× reduction in peak memory usage by eliminating the intermediate transition list buffer. This aligns with the PR's memory-efficiency objectives for large targeted experiments.
2069-2095: "NA" field handling is intentional and documented.The selective "NA" substitution (lines 2069-2091) is intentional per commit 695d657 and PR comments. As documented in the comment on lines 2078-2079,
label_type,compound_name,sum_formula, andsmilesare left empty (not "NA") for consistency with heavy-path output, while other fields likepeptide_group_label,gene_name,adducts, protein names, and uniprot IDs use "NA" when empty.This resolves the inconsistency flagged in the previous review.
- Remove unused TSVToTargetedExperiment_ overload for LightTargetedExperiment (now handled by streaming parser) - Extract duplicated SQL query building into buildPQPSelectQuery_() helper - Add PQPSqlQueryInfo struct to hold query and column availability flags - Net reduction of ~240 lines of code 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp (1)
1149-1161: SQL injection vulnerability: unescaped string values in INSERT statement.The
tr.transition_name(line 1152) andtr.getAnnotation()(line 1156) are inserted directly into the SQL statement without escaping. If these contain single quotes, the SQL will break or potentially allow injection. This was previously flagged in the heavy-path code.🔎 Recommended fix: Add SQL escaping helper
+ // Helper lambda to escape single quotes for SQL + auto escape_sql = [](const std::string& s) { + std::string result; + result.reserve(s.size()); + for (char c : s) { + if (c == '\'') result += "''"; + else result += c; + } + return result; + }; + // Insert transition data insert_transition_sql << "INSERT INTO TRANSITION (ID, TRAML_ID, PRODUCT_MZ, CHARGE, TYPE, ANNOTATION, ORDINAL, " << "DETECTING, IDENTIFYING, QUANTIFYING, LIBRARY_INTENSITY, DECOY) VALUES (" << i << ",'" << - tr.transition_name << "'," << + escape_sql(tr.transition_name) << "'," << tr.product_mz << "," << transition_charge << ",'" << fragment_type_char << "','" << - tr.getAnnotation() << "'," << + escape_sql(tr.getAnnotation()) << "'," <<
🧹 Nitpick comments (6)
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp (3)
248-449: Well-structured streaming implementation for memory efficiency.The streaming path directly populates
LightTargetedExperimentwithout intermediateTSVTransitionstorage, achieving the claimed ~5x memory reduction. The compound and protein deduplication maps are appropriately sized for the use case.Minor observation: Line 410 uses
std::endlwhich flushes the stream. Per coding guidelines, prefer\nfor performance.🔎 Suggested fix
- OPENMS_LOG_DEBUG << "Could not parse modifications from sequence: " << sequence << std::endl; + OPENMS_LOG_DEBUG << "Could not parse modifications from sequence: " << sequence << "\n";
956-1043: Consider extracting shared PQP schema creation.The
create_sqlstring defining the PQP schema (lines 956-1043) is duplicated fromwritePQPOutput_(lines 460-556). As noted in past review comments, this could be a shared constant or method.🔎 Suggested approach
Extract the schema creation SQL to a private static constant or helper method that both
writePQPOutput_andconvertLightTargetedExperimentToPQPcan use:// In class header or as static member static const char* getPQPSchemaSQL_();This would reduce ~90 lines of duplication and ensure schema consistency between heavy and light paths.
1163-1176: Batch transaction boundary differs from heavy path.The light path commits transactions when
i % 50000 == 0 && i > 0(line 1163), while the heavy path usesi % 50000 == 0(line 676). This means the light path won't commit at iteration 0, which is correct behavior but inconsistent with the heavy path that would commit an empty transaction at i=0.Consider aligning the behavior for consistency:
- if (i % 50000 == 0) - // if (i % 2 == 0) // for testing + if (i % 50000 == 0 && i > 0)src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (3)
649-705: Line counting for progress requires reading file twice.The implementation counts lines by reading the entire file first (lines 697-703), then seeks back to parse again. For very large files, this doubles I/O time.
Consider using an indeterminate progress indicator or estimating based on file size, though this may be an acceptable trade-off for user feedback.
🔎 Alternative approach
// Option 1: Use file size estimation std::ifstream::pos_type file_size = data.tellg(); data.seekg(0, std::ios::end); file_size = data.tellg() - file_size; data.seekg(0, std::ios::beg); Size estimated_lines = file_size / 200; // Estimate ~200 bytes per line // Option 2: Update progress periodically without total startProgress(0, 0, "streaming TSV to LightTargetedExperiment"); // ... in loop: if (cnt % 10000 == 0) { OPENMS_LOG_INFO << "Processed " << cnt << " transitions...\n"; }
668-890: Significant code duplication with readUnstructuredTSVInput_.The parsing logic (header handling, column extraction, SpectraST annotation, group ID generation) in
streamTSVToLightTargetedExperiment_(lines 668-890) duplicates most ofreadUnstructuredTSVInput_(lines 192-466). This increases maintenance burden and risks divergence.Consider extracting the TSV line parsing into a shared helper that both methods can use, returning a
TSVTransitionobject. The streaming method would then convert it immediately rather than collecting into a vector.
966-997: Exception handling for modification parsing is appropriate.The try-catch block gracefully handles invalid sequences by logging a debug message rather than failing. This matches the behavior in
streamPQPToLightTargetedExperiment_in TransitionPQPFile.cpp.Note: Line 996 uses
std::endl. Per coding guidelines, prefer\nfor performance.🔎 Suggested fix
- OPENMS_LOG_DEBUG << "Could not parse modifications from sequence: " << sequence << std::endl; + OPENMS_LOG_DEBUG << "Could not parse modifications from sequence: " << sequence << "\n";
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.hsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.hsrc/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cppsrc/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
- src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionPQPFile.h
🧰 Additional context used
📓 Path-based instructions (5)
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.hsrc/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.hsrc/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.hsrc/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
src/openms/include/OpenMS/**/*.h
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Add Doxygen comments for new public methods and classes
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.h
**/*.h
📄 CodeRabbit inference engine (AGENTS.md)
**/*.h: Use _impl.h only when needed; .h files must not include _impl.h
Do not use 'using namespace' or 'using std::...' in headers; allowed only in .cpp files
Prefer forward declarations in headers; include only base class headers, non-pointer members, and templates
Files:
src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.h
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.774Z
Learning: PR checklist: update AUTHORS and CHANGELOG, run/extend tests, update pyOpenMS bindings when needed
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cppsrc/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.hsrc/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
📚 Learning: 2025-12-20T17:04:02.774Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.774Z
Learning: Applies to **/*.{h,cpp,cxx,cc,hpp} : Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Utilize OpenMS logging mechanisms
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp
🧬 Code graph analysis (1)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (2)
src/openms/source/CONCEPT/Exception.cpp (1)
IllegalArgument(247-250)src/openms/include/OpenMS/CONCEPT/Types.h (1)
writtenDigits(264-267)
🔇 Additional comments (6)
src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp (1)
34-168: Good refactor: SQL query building extracted to shared helper.The extraction of
buildPQPSelectQuery_centralizes the SQL query construction logic, making it reusable betweenreadPQPInput_andstreamPQPToLightTargetedExperiment_. This reduces code duplication and ensures consistent behavior.src/openms/include/OpenMS/ANALYSIS/OPENSWATH/TransitionTSVFile.h (2)
244-258: Good documentation for the new streaming method.The Doxygen comment clearly explains the purpose, memory benefits (~5x reduction), and inline mixed sequence group detection behavior. The method signature appropriately takes
FileTypes::Typeto handle different input formats.
331-337: API addition for light-to-TSV conversion.The new public method
convertLightTargetedExperimentToTSVcomplements the existing heavy-pathconvertTargetedExperimentToTSV, providing a symmetric API for the light data structures.src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (3)
892-917: Inline mixed sequence group detection is a good optimization.Detecting mixed sequence groups inline during streaming avoids a second pass over the data. The logic correctly matches the batch version in
resolveMixedSequenceGroups_and respects theoverride_group_label_check_parameter.
1937-1963: NA field handling aligns with past review feedback.The code now explicitly sets several fields to "NA" when empty (peptide_group_label, gene_name, adducts, peptide_sequence, full_peptide_name) and handles empty protein_names/uniprot_ids vectors (lines 1962-1963). This addresses the inconsistency flagged in the past review about differing output between light and heavy paths.
1987-1988: CE and drift_time handling differs from heavy path.The light path writes a hardcoded
-1.0for CE (line 1987) since it's not stored in the light structure, which is correct. However,drift_timecould be negative (line 1988) if neither compound nor transition has it set, resulting in-1in the output. The heavy path has similar behavior, so this is consistent.
Change IonSeries typedef from std::unordered_map to std::map to ensure deterministic iteration order across all platforms. This fixes potential ARM64 portability issues where hash table iteration order differs from x86_64, causing different ion annotation results when tie-breaking in annotateIon(). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace static RNG with FNV-1a hash of peptide sequence for selecting replacement amino acids. This ensures: - Same peptide always gets the same replacement AA (reproducible) - Results are independent of processing order (portable across platforms) - Fixes ARM64 portability issue where hash table iteration order differs Updated test expected outputs to reflect the new deterministic behavior. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (1)
298-302: Consider extracting the duplicated amino acid array.The same static
aaarray andaa_sizeconstant appear in bothswitchKRLight(lines 298-303) andshufflePeptideLight(lines 380-385). Extracting this to thedetailnamespace would improve maintainability and follow the DRY principle.🔎 Suggested refactor
In the
detailnamespace (after line 134), add:// Amino acids for K/R replacement (excludes K, R, P) static constexpr const char* kReplacementAminoAcids[] = { "A", "N", "D", "C", "E", "Q", "G", "H", "I", "L", "M", "F", "S", "T", "W", "Y", "V" }; static constexpr int kReplacementAminoAcidsSize = 17;Then update both methods to use
detail::kReplacementAminoAcidsanddetail::kReplacementAminoAcidsSize.Also applies to: 380-385
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
-
src/tests/topp/OpenSwathDecoyGenerator_output_6_light.tsvis excluded by!**/*.tsv -
src/tests/topp/OpenSwathDecoyGenerator_output_8_pqp_roundtrip.tsvis excluded by!**/*.tsv
📒 Files selected for processing (3)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cppsrc/tests/topp/OpenSwathDecoyGenerator_output_4.TraMLsrc/tests/topp/OpenSwathDecoyGenerator_output_7_heavy.TraML
🚧 Files skipped from review as they are similar to previous changes (1)
- src/tests/topp/OpenSwathDecoyGenerator_output_7_heavy.TraML
🧰 Additional context used
📓 Path-based instructions (3)
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/tests/topp/OpenSwathDecoyGenerator_output_4.TraMLsrc/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
🧠 Learnings (9)
📚 Learning: 2025-07-29T10:06:14.860Z
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/tests/class_tests/openms/data/MRMAssay_uisTransitions_output_4_boost58.TraML:30-30
Timestamp: 2025-07-29T10:06:14.860Z
Learning: MS:1000893 in PSI-MS controlled vocabulary refers to "peptide group label", not "peptidoform group label". There is no official PSI-MS CV term for "peptidoform group label" with accession MS:1003050 as I incorrectly claimed.
Applied to files:
src/tests/topp/OpenSwathDecoyGenerator_output_4.TraML
📚 Learning: 2025-07-29T10:06:14.860Z
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/tests/class_tests/openms/data/MRMAssay_uisTransitions_output_4_boost58.TraML:30-30
Timestamp: 2025-07-29T10:06:14.860Z
Learning: The user corrected me that my claim about MS:1003050 being the accession for "peptidoform group label" was inaccurate. I should verify PSI-MS CV terms before making such claims.
Applied to files:
src/tests/topp/OpenSwathDecoyGenerator_output_4.TraML
📚 Learning: 2025-12-04T16:25:07.026Z
Learnt from: timosachsenberg
Repo: OpenMS/OpenMS PR: 8177
File: src/openms/source/FORMAT/HANDLERS/MzMLHandler.cpp:5069-5074
Timestamp: 2025-12-04T16:25:07.026Z
Learning: In OpenMS mzML writing, PSI-MS term MS:1003441 "ion mobility centroid frame" is a spectrum-level cvParam. It should be written at spectrum level (not scan level).
Applied to files:
src/tests/topp/OpenSwathDecoyGenerator_output_4.TraML
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/include/OpenMS/**/*.h : Add Doxygen comments for new public methods and classes
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-12-20T17:04:02.774Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.774Z
Learning: Applies to src/pyOpenMS/pxds/*.pxd : Keep .pxd signatures in sync with C++ APIs; update or remove wrap-ignore when wrapping changes
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/pyOpenMS/**/*.h : Add Doxygen comments for new public methods and classes in pyOpenMS bindings
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Follow the established error handling patterns
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Utilize OpenMS logging mechanisms
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
🧬 Code graph analysis (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (2)
src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp (1)
pseudoRNG(408-408)src/topp/DecoyDatabase.cpp (1)
shuffler(372-372)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: build-and-test (windows-2025, cl.exe, 14.44)
- GitHub Check: build-and-test (macos-14, xcode, 15.4)
- GitHub Check: build-and-test (ubuntu-24.04-arm, g++, 13)
- GitHub Check: build-and-test (ubuntu-24.04, clang++, 17)
- GitHub Check: build-and-test (ubuntu-24.04, g++, 13)
- GitHub Check: build-lnx
- GitHub Check: build-macos-arm
- GitHub Check: build-lnx-arm
- GitHub Check: build-win
- GitHub Check: cppcheck-test
🔇 Additional comments (7)
src/tests/topp/OpenSwathDecoyGenerator_output_4.TraML (1)
14-14: LGTM! Test expectation correctly updated for deterministic decoy generation.The changes reflect the switch from static RNG to FNV-1a hash in
switchKRLight(), ensuring reproducible decoy sequences across platforms. The sequence change (C→N at position 29) correctly propagates to the precursor m/z (1172.084 → 1177.601), with the mass difference (~5.52 m/z for charge state 2) consistent with the residue substitution. All five transitions are consistently updated.Also applies to: 29-29, 48-48, 67-67, 86-86, 105-105
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (6)
102-134: LGTM: Clean conversion helpers between heavy and light formats.The
detailnamespace provides clear, efficient conversion utilities. Good use ofreserve()and precondition checks.
136-200: LGTM: Effective delegation pattern to light implementations.The heavy methods now cleanly delegate to their light counterparts using the conversion helpers, maintaining functional parity while enabling memory-efficient code paths.
228-294: LGTM: Correct light-path reversal implementation.The reversal logic properly handles fixed residues and modification relocation, including terminal modifications at positions -1 and
sequence.size().
296-356: LGTM: Deterministic and portable implementations.
switchKRLightuses FNV-1a hashing to ensure reproducible AA replacement across platforms.hasCNterminalModsLight_correctly identifies terminal modifications.
358-491: LGTM: Correct shuffle implementation matching heavy-path behavior.The Fisher-Yates shuffle correctly handles fixed residues, modification relocation, and mutation timing. The RNG call order matches the heavy version, ensuring reproducible results.
756-1146: LGTM: Comprehensive light-path decoy generation.The implementation correctly mirrors the heavy-path logic while operating on light structures for memory efficiency. Key strengths:
- Proper duplicate detection using
allPeptideSequencesmap- Correct terminal modification checks on shuffled results (lines 914-918)
- Good error handling with debug logging for unparseable sequences
- Fragment annotation extraction handles all cases correctly
The srand(time(nullptr)) calls seeded C's rand() function, but portable_random_shuffle() uses boost::mt19937_64 which is independent. These calls had no effect on program behavior. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (1)
1070-1097: Fragment annotation parsing assumes specific format.The parsing logic expects annotations in format "b4^1" or "y10^2" (letter + number + optional "^charge"). This is coupled to
MRMIonSeries::annotateIonoutput format. While functional, extracting this to a helper method would improve testability and allow reuse.Consider extracting annotation parsing to a helper function
// In a suitable location (e.g., MRMIonSeries or utility header) struct FragmentAnnotation { std::string type; int number = 0; int charge = 1; }; FragmentAnnotation parseFragmentAnnotation(const std::string& annotation);This would centralize the format assumption and make it easier to adjust if the annotation format changes.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
🧰 Additional context used
📓 Path-based instructions (3)
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.774Z
Learning: PR checklist: update AUTHORS and CHANGELOG, run/extend tests, update pyOpenMS bindings when needed
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/include/OpenMS/**/*.h : Add Doxygen comments for new public methods and classes
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-12-20T17:04:02.774Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.774Z
Learning: Applies to src/pyOpenMS/pxds/*.pxd : Keep .pxd signatures in sync with C++ APIs; update or remove wrap-ignore when wrapping changes
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Follow the established error handling patterns
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Utilize OpenMS logging mechanisms
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp
🧬 Code graph analysis (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (1)
src/openms/source/ANALYSIS/OPENSWATH/MRMAssay.cpp (1)
pseudoRNG(408-408)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: build-and-test (ubuntu-24.04, clang++, 17)
- GitHub Check: build-and-test (windows-2025, cl.exe, 14.44)
- GitHub Check: build-and-test (ubuntu-24.04, g++, 13)
- GitHub Check: build-and-test (ubuntu-24.04-arm, g++, 13)
- GitHub Check: build-and-test (macos-14, xcode, 15.4)
- GitHub Check: build-lnx-arm
- GitHub Check: build-win
- GitHub Check: build-lnx
- GitHub Check: build-macos-arm
- GitHub Check: cppcheck-test
🔇 Additional comments (11)
src/openms/source/ANALYSIS/OPENSWATH/MRMDecoy.cpp (11)
102-134: Delegation helpers are well-designed.The
detailnamespace is a standard C++ idiom for internal implementation details. The conversion helpers properly handle the heavy↔light modification translation with appropriate precondition checks. Theinlinespecifier is appropriate for these small, frequently-called functions.
136-200: Clean delegation pattern with proper separation of concerns.The heavy methods correctly delegate to light implementations and apply modifications back. The use of C++17 structured bindings (
auto [new_sequence, new_mods] = ...) improves readability. This design ensures single-source-of-truth for the decoy generation logic while maintaining backward compatibility with the heavy API.
202-221: LGTM.The modified sequence string builder correctly handles both terminal (positions -1 and sequence.size()) and residue modifications with proper UniMod notation.
228-286: Partial reversal logic is correctly implemented.The method properly:
- Preserves fixed residues (K/P/R and optionally termini)
- Reverses only the movable portion of the sequence
- Correctly relocates modifications based on the index mapping
- Preserves terminal modifications at positions -1 and sequence.size()
296-330: Deterministic amino acid replacement ensures reproducibility.The FNV-1a hash implementation provides platform-independent deterministic selection, which is crucial for reproducible decoy generation across different architectures (as noted in PR objectives). The empty sequence guard at line 305 prevents edge case issues.
332-356: LGTM.Terminal modification detection correctly identifies N-terminal (position -1), C-terminal (position sequence_length), and optionally the C-terminal AA position.
358-491: Shuffle implementation is functionally correct.The shuffling logic correctly:
- Preserves fixed residues and termini
- Uses Fisher-Yates shuffle variant
- Attempts mutations every 10 iterations to aid convergence
- Maintains RNG call order matching heavy version for reproducibility
Minor observation: empty sequences are implicitly handled because
AASequenceIdentityreturns NaN for empty strings, causing the while loop to exit immediately. This is safe but could be made explicit with an early return for clarity.
755-783: LGTM - Decoy protein generation mirrors heavy path.The protein decoy generation correctly prefixes IDs with the decoy tag.
862-872: Good error handling for sequence parsing.The try-catch block properly handles unparseable sequences by logging a debug message and adding to the exclusion set, consistent with the pattern in the heavy path.
1017-1027: Error logging for transition sequence parsing has been addressed.Based on past review feedback, this now logs a debug message when sequence parsing fails for transitions, matching the pattern used for peptide parsing errors.
1108-1143: Efficient filtering and cleanup.The use of
std::remove_ifwitheraseandstd::movefor the final assignments is idiomatic and memory-efficient. The filtering logic correctly removes excluded peptides, orphaned transitions, and orphaned proteins.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (1)
1826-1827: File stream error handling still not addressed.The output file stream is opened without checking for success. This was flagged in a previous review but remains unaddressed. If the file cannot be created (permissions, disk full, invalid path, etc.), subsequent writes will silently fail.
As per coding guidelines and Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION.
🔎 Suggested fix
std::ofstream os(filename); + if (!os.is_open()) + { + throw Exception::FileNotWritable(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename); + } os.precision(writtenDigits(double()));
🧹 Nitpick comments (2)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (2)
696-703: Line counting undermines streaming benefits.The entire file is read once just to count lines for progress tracking. For large files, this doubles I/O overhead and delays the start of actual processing, undermining the memory efficiency benefits of streaming (~5x reduction noted in PR objectives).
💡 Suggested alternatives
Option 1: Remove progress tracking entirely (simplest):
- // Count lines for progress (seek back after) - Size total_lines = 0; - { - std::ifstream count_stream(filename); - std::string count_line; - while (TextFile::getLine(count_stream, count_line)) { ++total_lines; } - if (total_lines > 0) --total_lines; // subtract header - } - startProgress(0, total_lines, "streaming TSV to LightTargetedExperiment"); + // Progress tracking not available for streaming modeOption 2: Use indeterminate progress or file-size estimation:
- // Count lines for progress (seek back after) - Size total_lines = 0; - { - std::ifstream count_stream(filename); - std::string count_line; - while (TextFile::getLine(count_stream, count_line)) { ++total_lines; } - if (total_lines > 0) --total_lines; // subtract header - } - startProgress(0, total_lines, "streaming TSV to LightTargetedExperiment"); + // Use indeterminate progress for streaming + nextProgress(); // or similar OpenMS pattern for unknown total
709-918: Consider refactoring to reduce duplication.The parsing logic (lines 709-891) and mixed sequence group detection (lines 892-918) substantially duplicate logic from
readUnstructuredTSVInput_(lines 231-459) andresolveMixedSequenceGroups_(lines 1035-1081). While the inline streaming approach is beneficial for memory efficiency, the duplication creates maintenance burden—bug fixes or enhancements need to be applied in both paths.Potential approaches:
- Extract common parsing logic into shared helper functions
- Template the parsing to work with different output targets
- Document the intentional duplication and establish a policy to keep both implementations synchronized
Given the PR focus on memory optimization and the different architectural constraints (streaming vs batch), this duplication may be acceptable, but it should be tracked for future refactoring.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
-
src/tests/topp/OpenSwathDecoyGenerator_output_6_light.tsvis excluded by!**/*.tsv -
src/tests/topp/OpenSwathDecoyGenerator_output_8_pqp_roundtrip.tsvis excluded by!**/*.tsv
📒 Files selected for processing (1)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
🧰 Additional context used
📓 Path-based instructions (3)
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.774Z
Learning: PR checklist: update AUTHORS and CHANGELOG, run/extend tests, update pyOpenMS bindings when needed
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Follow the established error handling patterns
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
📚 Learning: 2025-12-20T17:04:02.774Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.774Z
Learning: Applies to **/*.{h,cpp,cxx,cc,hpp} : Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
🧬 Code graph analysis (1)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (2)
src/openms/source/CONCEPT/Exception.cpp (1)
IllegalArgument(247-250)src/openms/include/OpenMS/CONCEPT/Types.h (1)
writtenDigits(264-267)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: build-lnx
- GitHub Check: build-lnx-arm
- GitHub Check: build-and-test (ubuntu-24.04, clang++, 17)
- GitHub Check: build-win
- GitHub Check: build-and-test (windows-2025, cl.exe, 14.44)
- GitHub Check: build-and-test (ubuntu-24.04, g++, 13)
- GitHub Check: build-and-test (ubuntu-24.04-arm, g++, 13)
- GitHub Check: cppcheck-test
| // Map for detecting mixed sequence groups inline (peptide_group_label -> first sequence seen) | ||
| std::map<String, String> label_to_sequence; | ||
|
|
||
| std::ifstream data(filename); |
There was a problem hiding this comment.
Add input file stream error handling.
The input file stream is opened without checking for success. If the file cannot be opened (permissions, does not exist, etc.), subsequent reads will fail silently or cause undefined behavior.
As per coding guidelines, follow established error handling patterns.
🔎 Suggested fix
std::ifstream data(filename);
+ if (!data.is_open())
+ {
+ throw Exception::FileNotReadable(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename);
+ }
std::string line;🤖 Prompt for AI Agents
In src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp around line 658,
the std::ifstream is opened but not checked; add a check immediately after
opening the stream and handle failure by using the project’s established
error/exception mechanism (e.g. detect if the stream is not open/valid,
construct a clear error message containing the filename and errno/strerror if
available, and throw the appropriate OpenMS exception or error helper) so that
file-open failures fail fast and provide actionable diagnostics.
For consistency with heavy-path output, leave Adducts and UniprotId columns empty instead of "NA" when not set. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5bb37b5 to
da6086b
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (2)
658-658: Add input file stream error handling.The input file stream is opened without checking for success. If the file cannot be opened (permissions, does not exist, etc.), subsequent reads will fail silently or cause undefined behavior.
As per coding guidelines, follow established error handling patterns.
🔎 Suggested fix
std::ifstream data(filename); + if (!data.is_open()) + { + throw Exception::FileNotReadable(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename); + } std::string line;
1826-1827: Verify file stream error handling.The output file stream is opened but there's no check for successful opening. If the file cannot be created (permissions, disk full, etc.), subsequent writes will silently fail.
🔎 Suggested fix
std::ofstream os(filename); + if (!os.is_open()) + { + throw Exception::FileNotWritable(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename); + } os.precision(writtenDigits(double()));
🧹 Nitpick comments (3)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (3)
699-703: Consider adding error handling for line counting stream.The secondary stream opened for line counting lacks an error check. While this is only used for progress tracking and won't affect data processing, it would be more robust to verify the stream opened successfully.
1983-1983: Consider outputting empty or "NA" for missing CE values.Currently, CE is hardcoded to
-1.0sinceLightTransitiondoesn't store collision energy. However, the heavy-path uses-1as a sentinel value internally but may output differently. Consider using an empty string or "NA" for consistency with how missing values are typically represented in TSV output.
1994-1996: Consider checking stream state after closing.Buffered write errors may only manifest when the stream is flushed at close. For robustness, consider checking the stream state after closing to ensure all data was written successfully.
🔎 Suggested enhancement
os << line << std::endl; } endProgress(); os.close(); + if (os.fail()) + { + throw Exception::FileNotWritable(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, + String("Error writing to file: ") + filename); + } }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
-
src/tests/topp/OpenSwathDecoyGenerator_output_6_light.tsvis excluded by!**/*.tsv -
src/tests/topp/OpenSwathDecoyGenerator_output_8_pqp_roundtrip.tsvis excluded by!**/*.tsv -
src/tests/topp/TargetedFileConverter_light_path_output.tsvis excluded by!**/*.tsv
📒 Files selected for processing (1)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
🧰 Additional context used
📓 Path-based instructions (3)
src/openms/**/*.{cpp,h,hpp,cc,cxx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/openms/**/*.{cpp,h,hpp,cc,cxx}: Follow the existing C++ coding conventions in the codebase
Use the established naming patterns for classes, methods, and variables
Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Follow the established error handling patterns
Utilize OpenMS logging mechanisms
Be mindful of memory usage when processing large datasets
Consider algorithmic complexity for data processing operations
Use appropriate OpenMS containers and algorithms
Files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
**/*.{h,cpp,cxx,cc,hpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{h,cpp,cxx,cc,hpp}: Use 2 spaces for indentation; no tabs; Unix line endings
Add space after keywords (if, for) and around binary operators
Use opening/closing braces that align; use braces even for single-line blocks (trivial one-liners may stay single-line)
Class names must match file names; one class per file; always pair .h with .cpp
Use PascalCase for classes, types, and namespaces; lowerCamel for methods; snake_case for variables
Use uppercase with underscores for enums and macros; prefer enum class over preprocessor macros
Private and protected members must end with underscore (_)
Use lower_case with underscores for parameters; document ranges and units
Use OpenMS primitive types from OpenMS/CONCEPT/Types.h
Follow Rule-of-0 or Rule-of-6 for constructors and destructors
Provide get/set accessor pairs for protected and private members; no reference getters for primitive types
Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Document exceptions with @brief and details in Doxygen comments; include assignee name in @todo tags
Use // style comments (not /* */); write comments describing the next few lines in plain English; aim for at least ~5% code comments
Each C++ file preamble must contain the$Maintainer:$ marker
Use ./.clang-format configuration for code formatting in supporting IDEs
Add OPENMS_DLLAPI to all non-template exported classes, structs, functions, and variables; not on templates; include in friend operator declarations
Use OpenMS logging macros and OpenMS::LogStream; avoid std::cout and std::err directly
Avoid std::endl for performance; prefer \n
Prefer OpenMS::String for numeric formatting and parsing (precision and speed)
Use Size/SignedSize for STL .size() values
Avoid pointers; prefer references
Files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use lowercase file extensions, except ML, XML, and mzData
Files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
🧠 Learnings (5)
📓 Common learnings
Learnt from: poshul
Repo: OpenMS/OpenMS PR: 8133
File: src/openms/source/ANALYSIS/OPENSWATH/OpenSwathHelper.cpp:0-0
Timestamp: 2025-07-29T10:05:48.015Z
Learning: In LightTargetedExperiment, all entity types (peptides, nucleotides, compounds, oligos) are intentionally stored in a unified collection called `compounds` (later renamed to `peptideNuctideCompounds`). This means that when processing oligos, the code correctly accesses `targeted_exp.compounds[i].oligo_refs` rather than a separate oligo-specific collection, as the design uses a unified data structure approach.
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Use OpenMS data structures (e.g., MSExperiment, FeatureMap, PeptideIdentification)
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Be mindful of memory usage when processing large datasets
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
📚 Learning: 2025-08-05T12:43:11.681Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-05T12:43:11.681Z
Learning: Applies to src/openms/**/*.{cpp,h,hpp,cc,cxx} : Follow the established error handling patterns
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
📚 Learning: 2025-12-20T17:04:02.774Z
Learnt from: CR
Repo: OpenMS/OpenMS PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-20T17:04:02.774Z
Learning: Applies to **/*.{h,cpp,cxx,cc,hpp} : Exception classes must derive from Exception::Base; throw with file, line, and OPENMS_PRETTY_FUNCTION; catch by reference
Applied to files:
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp
🧬 Code graph analysis (1)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (2)
src/openms/source/CONCEPT/Exception.cpp (1)
IllegalArgument(247-250)src/openms/include/OpenMS/CONCEPT/Types.h (1)
writtenDigits(264-267)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: build-and-test (windows-2025, cl.exe, 14.44)
- GitHub Check: build-and-test (ubuntu-24.04-arm, g++, 13)
- GitHub Check: build-and-test (ubuntu-24.04, clang++, 17)
- GitHub Check: build-lnx
- GitHub Check: build-win
- GitHub Check: cppcheck-test
🔇 Additional comments (5)
src/openms/source/ANALYSIS/OPENSWATH/TransitionTSVFile.cpp (5)
960-998: Modification parsing handles errors gracefully.The try-catch around
AASequence::fromStringproperly handles invalid modification strings by logging at debug level and continuing without modifications. This is appropriate behavior for a streaming parser.
892-918: Inline mixed sequence group detection is correctly implemented.The streaming implementation properly replicates the batch-mode
resolveMixedSequenceGroups_logic, maintaining a map to detect conflicting sequences within the same peptide group label. Theoverride_group_label_check_parameter is correctly respected.
1795-1799: Clean delegation to streaming parser.The method now correctly delegates to the memory-efficient streaming implementation for
LightTargetedExperiment.
1937-1959: NA handling aligns with discussed conventions.The implementation correctly sets "NA" for
peptide_group_label,gene_name,peptide_sequence,full_peptide_name, andprotein_nameswhen empty. Other fields (label_type,compound_name,sum_formula,smiles,adducts,uniprot_ids) are intentionally left empty to match heavy-path behavior as discussed in PR comments.
649-1033: Well-structured streaming implementation for memory efficiency.The
streamTSVToLightTargetedExperiment_method properly implements a streaming approach that:
- Reuses a single
TSVTransitionbuffer per line (line 729)- Uses maps for deduplication of compounds and proteins
- Implements inline mixed sequence group detection to avoid post-processing
- Directly constructs
LightTransition,LightCompound, andLightProteinobjectsThis aligns with the PR's goal of reducing peak memory usage for large targeted experiments. Based on coding guidelines, the approach is mindful of memory usage when processing large datasets.
PQP files (SQLite binary format) have platform-dependent internal layout, causing byte-by-byte comparison to fail on macOS ARM64. Changed test to use TSV roundtrip comparison with -sort flag for portable testing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* [FEATURE] Add FAIMS support to ProteomicsLFQ (#8478)
- Annotate peptide IDs with FAIMS_CV from spectrum data before feature
detection, enabling proper per-CV filtering in FeatureFinderIdentificationAlgorithm
- Add documentation describing FAIMS support: automatic detection,
per-CV processing, feature merging, and downstream alignment/linking
FAIMS data is now automatically handled:
1. FFI splits data by compensation voltage and processes each CV group
2. Features from different CVs representing the same analyte are merged
3. Merged features are aligned and linked based on RT and m/z
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Add append() and extend() methods to pyOpenMS map classes with __len__ support (#8510)
Implements feature request #8124 by adding Pythonic methods to:
- ConsensusMap: __len__, append, extend
- FeatureMap: __len__, append, extend
- PeptideIdentificationList: append, extend (already had __len__)
These methods provide a more Pythonic interface:
- __len__() enables use of built-in len() function
- append() adds single items (equivalent to push_back())
- extend() adds multiple items from iterables or other map objects
Includes comprehensive unit tests for all new methods.
Co-authored-by: Claude <noreply@anthropic.com>
* Store PeptideIndexer settings as metavalues in SearchParameters (#8489)
* Initial plan
* Add PeptideIndexer settings as metavalues in ProteinIdentification
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Extract metavalue keys as constants to improve maintainability
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Remove trailing whitespace from PeptideIndexing.h
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Use !empty() instead of size() > 0 for better readability
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Store PeptideIndexer settings in SearchParameters instead of ProteinIdentification
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Remove unnecessary static constants for metavalue keys
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Fix PeptideIndexing test and update test output files
- Fix unit test to provide ProteinIdentification before running
(the test was creating an empty prot_ids vector but expecting
metavalues to be set - the code only updates existing
ProteinIdentifications)
- Update all PeptideIndexer TOPP test expected output files to
include the new metavalues in SearchParameters
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add PeptideIndexer settings to TOPP test expected output files (#8509)
Update expected output files to include PeptideIndexer settings that are
now written to SearchParameters. This includes decoy_string, enzyme,
enzyme_specificity, and related parameters.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Add PeptideIndexer params to SageAdapter test output (#8518)
Update the SageAdapter_1_out.idXML test file to include the
PeptideIndexer metavalues that were missing from the PR #8509
update which added these to other adapter test files.
Co-authored-by: Claude <noreply@anthropic.com>
* Check the return value of configure so that we stop on configure errors (#8515)
* Check the return value of configure so that we stop on configure errors
* make sure nsis is in path.
* Simplify notarization step in CI workflow
Removed redundant notarization parameters from CI workflow.
* fix cat-on-keyboard error
Updated the workflow to use a structured THIRDPARTY directory.
* Simplify CI workflow by removing deb dependency check
Removed conditional dependency installation for deb packages in CI workflow.
* Use external libraries from Debian repos to prevent deb package conflicts (#8496)
* Initial plan
* Use external SQLite3, SQLiteCpp, nlohmann-json, and SIMDe from Debian repos
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Fix debian package dependencies - SQLiteCpp is static library
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Add documentation for USE_EXTERNAL_* CMake options
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
Co-authored-by: Samuel Wein <sam@samwein.com>
* Use unsigned channel identifiers in peptide quantification (#8516)
* Remove non-schema CMakeLists.txt from OPENSWATH directory (#8513)
* Initial plan
* Remove non-standard CMakeLists.txt from OPENSWATH directory
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* explicitly add timestamping to notarization process (#8527)
* Hide Eigen from OpenMS public API (Issue #8456) (#8511)
* Hide Eigen from OpenMS public API (Issue #8456)
This implements Option D from issue #8456: use Eigen::Map only without PIMPL.
Changes:
- Move Eigen3::Eigen from PUBLIC to PRIVATE linking in CMakeLists.txt
- Rewrite Matrix<T> to use std::vector<T> storage (column-major)
- Add internal MatrixEigen.h with eigenView() for zero-copy Eigen access
- Refactor TraceFitter/LevMarqFitter1D GenericFunctor to use raw double*
instead of Eigen types in public interface
- Update all internal code to use eigenView() where Eigen operations needed
- Add missing includes (<cmath>, <Eigen/LU>, <Eigen/QR>) where needed
- Update tests to link against Eigen when using eigenView() directly
The Matrix class now provides:
- std::vector storage with data() pointer access
- getValue/setValue methods for element access
- eigenView() (internal) for full Eigen matrix operations
Downstream users no longer need Eigen headers when using OpenMS.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add pyOpenMS test for Matrix column-major ordering
Add testMatrixDoubleColumnMajorOrdering() to verify that the Matrix class
correctly preserves row/column ordering when passing data between numpy
and C++. This test catches potential column-major vs row-major issues that
could cause data transposition.
The test verifies:
- Shape preservation (3x4 matrix stays 3x4, not transposed to 4x3)
- Element-by-element verification via getValue matches numpy indexing
- Round-trip preservation (numpy -> C++ -> numpy)
- View indexing matches getValue for all elements
- Modifications through numpy view are reflected in C++ object
- Highly non-square matrices (2x5) work correctly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix Doxygen for solveNNLS_ to document in-place matrix modification
Update the documentation for the non-const solveNNLS_ overload to correctly
indicate that correction_matrix is modified in-place by the NNLS solver.
Changed @param[in] to @param[in,out] and added a @note explaining that
this overload mutates the matrix for efficiency, with a reference to the
const-preserving overload for cases where the original must be preserved.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix Doxygen for computeStats_ to correctly document parameters
- Change @param[out] x_naive to @param[in] (it's const reference input)
- Change @param[in] stats to @param[in,out] (it's modified by function)
- Clarify that x_naive is LU-decomposition solution, not "uncorrected"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix Doxygen param annotations for NonNegativeLeastSquaresSolver
Add proper @param[in], @param[out], @param[in,out] annotations based on
actual implementation behavior:
- const Matrix& overload: A and b are [in] (copies made internally)
- raw pointer overload: A and b are [in,out] (modified by NNLS solver)
- Matrix& overload: A and b are [in,out] (passed to raw pointer version)
Also clarify in @brief that const overload preserves originals while
non-const overloads modify inputs in-place for efficiency.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix misleading comments about Matrix template instantiations
Remove contradictory comment that said "No explicit template instantiations
needed" when explicit instantiations are present. Clarify that these are
explicit instantiations to compile template code into libOpenMS.so, not
"default instances for backwards compatibility".
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Remove Eigen dependency from NonNegativeLeastSquaresSolver_test
Remove include of internal MatrixEigen.h header and replace Eigen::Index
with Size. This aligns with the PR goal of hiding Eigen from the public API.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add unit tests for internal MatrixEigen utilities
Test coverage for the internal Eigen-based utilities in MatrixEigen.h:
- eigenView() for mutable and const Matrix
- eigenVectorView() for std::vector and raw pointers
- eigenMatrixView() for raw pointers
- Zero-copy verification (modifications through view affect original)
- Eigen operations work correctly on views
- Matrix/view consistency with column-major storage
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add pointer-safety documentation for NNLS raw-pointer overload
Document memory requirements, ownership semantics, and lifetime constraints
for the double* A parameter:
- Must be non-null, pointing to A_rows * A_cols contiguous doubles
- Column-major storage order required
- Caller retains ownership and must ensure validity during call
- Contents modified in-place and undefined after call
- nullptr or undersized buffer is undefined behavior
Also add note recommending Matrix& overload for safety and mention
std::span as potential future improvement.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Link MRMScoring_test to Eigen3::Eigen
MRMScoring_test.cpp includes MatrixEigen.h which requires Eigen headers.
Since Eigen is a PRIVATE dependency of OpenMS, tests that directly include
internal Eigen-dependent headers must explicitly link to Eigen3::Eigen.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Remove Eigen dependency from ImageCreator
- Add maxValue() and minValue() methods to Matrix class using std::max_element/std::min_element
- Update ImageCreator.cpp to use Matrix::maxValue() instead of eigenView().maxCoeff()
- Remove MatrixEigen.h include from ImageCreator.cpp
This fixes the build error where ImageCreator failed to compile because
it included MatrixEigen.h but TOPP tools don't link against Eigen3::Eigen.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Replace Eigen::Index with Size in test files
Part of hiding Eigen from the public API. Tests should not use
Eigen types directly since Eigen is an internal implementation detail.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add missing <atomic> include to MzMLHandler.cpp
Fix build failure caused by missing std::atomic include. This was
previously provided transitively through Eigen headers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix Doxygen documentation warnings in Matrix.h (#8529)
* Initial plan
* Fix Doxygen warnings in Matrix.h getValue/setValue documentation
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
* Wrap Math::getPPM template functions for Python bindings (#8525)
* Initial plan
* Add Math.pxd wrapper and unit tests for Math::getPPM functions
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Update Math.pxd to properly handle template functions with concrete double type
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Remove unnecessary wrap-as directives from Math.pxd
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Improve documentation for Math class wrapper with usage examples
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Add wrap-doc documentation at function level for all Math functions
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Update Math class documentation to be more general and extensible
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
* Add precursor m/z range filter to PeakFileOptions (#8526)
* Initial plan
* Add precursor m/z range filter support to PeakFileOptions
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Implement precursor m/z range filtering in MzML, MzXML, and MzData handlers
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Fix MzXMLHandler to properly skip filtered spectra by removing from spectrum_data_
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
* Initial plan
* Changes before error encountered
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Remove MS level check from precursor m/z range filter
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* [DOC] Add AGENTS.md guidance (#8537)
* [DOC] Add AGENTS.md guidance
* [DOC] Update TOPP tool documentation paths
* Implement to_df directly in Cython files (#8520)
* Move get_df() methods directly into Cython .pyx addon files
Instead of using Python wrapper classes in _dataframes.py to add DataFrame
export functionality, implement get_df() directly in the Cython addon files
alongside get_data_dict(). This simplifies the architecture by:
- Removing the "duck typing hack" of wrapper classes that override Cython classes
- Putting all DataFrame logic in one place (the Cython addon files)
- Making the code flow more straightforward
Changes:
- MSSpectrum.pyx: Added get_df()
- MSChromatogram.pyx: Added get_df()
- Mobilogram.pyx: Added get_df()
- MSExperiment.pyx: Added get_df_columns(), get_df(), get_ion_df(), get_massql_df()
- ConsensusMap.pyx: Added get_df_columns(), get_intensity_df(), get_metadata_df(), get_df()
- FeatureMap.pyx: Added get_df_columns(), get_df(), get_assigned_peptide_identifications()
- MRMTransitionGroupCP.pyx: New addon with get_chromatogram_df(), get_feature_df() methods
- _dataframes.py: Simplified to only export standalone functions
- README.md: Updated documentation to reflect new pattern
* Add get_df() to PeptideIdentificationList and comprehensive tests
- Add get_df() and update_scores_from_df() methods to PeptideIdentificationList.pyx
following the same pattern as other data structures
- Update _dataframes.py to use backwards-compatible wrapper functions that call the
new methods (peptide_identifications_to_df → peps.get_df(), update_scores_from_df → peps.update_scores_from_df())
- Simplify _dataframes.py by removing duplicate implementation code
- Add comprehensive tests for:
- PeptideIdentificationList.get_df() with various parameters
- PeptideIdentificationList.update_scores_from_df()
- Mobilogram.get_df() column selection
- Backwards-compatible wrapper functions
* Fix Cython compilation errors in get_df() addon methods
- Use lazy pandas imports inside methods to avoid module-level import issues
- Replace bool() calls with len() > 0 to avoid Cython type conflicts
- Replace {bool: ...} dict keys with {type(True): ...} for same reason
- Rename 'long' parameter to 'long_format' to avoid Cython keyword conflict
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add to_arrow() methods for Apache Arrow Table export
Add to_arrow() methods to pyOpenMS classes following the Polars naming convention:
- MSSpectrum.to_arrow() - reuses get_data_dict() for efficient numpy-to-Arrow conversion
- MSChromatogram.to_arrow() - reuses get_data_dict()
- Mobilogram.to_arrow() - reuses get_data_dict()
- MSExperiment.to_arrow() - supports long_format parameter like get_df()
- ConsensusMap.to_arrow() - wraps get_df() with pa.Table.from_pandas()
- FeatureMap.to_arrow() - wraps get_df() with pa.Table.from_pandas()
- MRMTransitionGroupCP.chromatograms_to_arrow(), features_to_arrow()
- PeptideIdentificationList.to_arrow()
All methods use lazy imports for pyarrow to keep it as an optional dependency.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix UnboundLocalError in PeptideIdentificationList.get_df()
When a PeptideHit doesn't have a particular metavalue, the code would
reference an undefined 'val' variable. Fix by using the precomputed
dmv[idx] array which already contains the correct default missing value
for each metavalue's type.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix bugs and add tests for DataFrame/Arrow export
Bug fixes:
- ConsensusMap.get_intensity_df(): Fix np.fromiter count truncation
by computing actual row count (one row per file per feature)
- MSExperiment.get_massql_df(): Fix division by zero in intensity
normalization for empty spectra or all-zero intensities
- _dataframes.py: Fix 'any' to 'Any' type hint import
Tests added:
- TestToArrowMethods: 7 tests for to_arrow() across all classes
- TestBugFixes: 3 tests for the bug fixes above
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix FeatureMap.get_df() missing spectrum_native_id check
Add existence check for 'spectrum_native_id' meta value before calling
getMetaValue() in extract_meta_data(). This follows the same pattern
used in get_assigned_peptide_identifications().
Without this check, calling get_df() on a FeatureMap where some features
lack the 'spectrum_native_id' meta value could fail unexpectedly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix test parameter name mismatch in MSExperiment.get_df() test (#8523)
* Initial plan
* Fix test parameter name: change long= to long_format= in MSExperiment test
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Potential fix for pull request finding 'Unused import'
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* Apply suggestions from code review
Co-authored-by: Justin Sing <32938975+singjc@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Make pandas and pyarrow optional dependencies with Sphinx docstrings (#8535)
* Initial plan
* Remove pandas from required dependencies and fix docstrings
- Removed pandas from install_requires in setup.py (now optional)
- Added ImportError with helpful message when pandas is not installed
- Fixed all docstrings to use Sphinx reStructuredText format (:param, :type, :return, :rtype, :raises)
- Updated docstrings in 8 addon files (ConsensusMap, FeatureMap, MRMTransitionGroupCP, MSChromatogram, MSExperiment, MSSpectrum, Mobilogram, PeptideIdentificationList)
- Also added ImportError handling for pyarrow imports (optional dependency)
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Fix remaining to_arrow() docstrings to use Sphinx format
- Updated all to_arrow() method docstrings to use Sphinx reStructuredText format
- Fixed docstrings in ConsensusMap, FeatureMap, MRMTransitionGroupCP, MSChromatogram, MSExperiment, MSSpectrum, Mobilogram, PeptideIdentificationList
- All DataFrame and Arrow export methods now have consistent Sphinx-style documentation
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Install pandas and pyarrow for CI test job (#8539)
* Initial plan
* Install pandas and pyarrow in test job for optional dependency tests
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* some review comments (#8540)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Justin Sing <32938975+singjc@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Add security patterns to .gitignore to prevent credential leaks (#8545)
* Add security patterns to .gitignore to prevent credential leaks
Add comprehensive gitignore rules for common credential and secret files:
- Environment files (.env, .env.*)
- Private keys and certificates (.pem, .key, .p12, .pfx, .crt)
- Credential files (credentials.json, secrets.yaml, etc.)
- Cloud provider credentials (AWS, SSH keys)
- API tokens and keys (.npmrc, .pypirc, .netrc, *.token)
- Docker and Kubernetes secrets
- Database files that may contain credentials
- OAuth tokens and client secrets
- GPG keys
- Terraform and Ansible vault files
- IDE credential storage
- Shell history files
- Local config files that may contain secrets
- Jupyter notebook checkpoints
- GitHub and AI service tokens
* Remove database extensions from gitignore
OpenMS uses SQLite databases (via SQLiteCpp library, MzMLSqliteHandler,
SqliteConnector, etc.) so *.sqlite, *.sqlite3, and *.db should not be ignored.
---------
Co-authored-by: Claude <noreply@anthropic.com>
* MetaboliteSpectralMatcher fixes from playing with Nucleosides (#8163)
* Update src/openms/source/ANALYSIS/ID/MetaboliteSpectralMatching.cpp
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Update src/openms/source/ANALYSIS/ID/MetaboliteSpectralMatching.cpp
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Apply suggestions from code review
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Update MetaboliteSpectralMatching.cpp
* fix
* add test with GNPS MGF
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
* propagate extern libs settings to package (#8556)
* fix macos pkg logo (#8554)
* Inital steps for moving to LightTransition (WIP) (#8544)
* inital commit
* Fix pyOpenMS build for C++20 and modern dependencies
IDFilter.h:
- Add IsNotIdentificationVector concept to disambiguate template overloads
- Add removeEmptyIdentifications(PeptideIdentificationList&) overload
- Fixes autowrap-generated binding compilation with C++20 concepts
setup.py:
- Use numpy.get_include() for numpy 2.x compatibility
- Update C++ standard from C++17 to C++20 (required for OpenMS concepts)
- Change Qt5 to Qt6 on Linux (matches OpenMS build)
- Change libomp to gomp (GNU OpenMP runtime for GCC builds)
- Fix libraries.extend() bug: was iterating string characters instead of append
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix issues from CodeRabbit PR review
- MRMDecoy.cpp: Fix shuffle check to use decoy_temp_peptide instead of temp_peptide
- LightTargetedExperiment.pxd: Add missing isPrecursorImSet() and getPrecursorIM() methods
- OpenSwathAssayGenerator.cpp: Fix if/else-if chain for output file type handling
- OpenSwathDecoyGenerator.cpp: Add division by zero protection and fix if/else-if chain
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add tests for light and heavy decoy generation paths
Add test 6 (light path) and test 7 (heavy path) for OpenSwathDecoyGenerator
to verify both code paths produce correct output:
- Test 6: TSV -> TSV using LightTargetedExperiment (memory-efficient path)
- Test 7: TSV -> TraML using TargetedExperiment (full feature path)
Both tests use the same input (OpenSwathDecoyGenerator_input_4.tsv) and
parameters to verify that the light and heavy paths generate equivalent
decoy sequences.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add debug logging for transition sequence parsing failures
Add OPENMS_LOG_DEBUG statement when transitions are skipped due to
unparseable sequences, improving debuggability.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Implement pure light-path decoy generation methods
Address PR review feedback from singjc regarding memory efficiency:
- Add reversePeptideLight() for light peptide sequence reversal
- Add shufflePeptideLight() for light peptide shuffling with mods
- Add pseudoreversePeptideLight_() for pseudo-reverse (keep C-term)
- Add switchKRLight() for terminal K/R switching
- Add hasCNterminalModsLight_() for terminal mod detection
- Update generateDecoysLight() to use pure light methods
These methods operate directly on std::string and LightModification
vectors, avoiding temporary TargetedExperiment::Peptide allocations
for improved memory efficiency with large spectral libraries.
Also includes:
- Documentation for detecting/quantifying transition defaults
- PQP output tests for light path
- TODO comment for future IPF light path support
- Comprehensive unit tests comparing light vs heavy methods
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Refactor MRMDecoy heavy methods to delegate to light implementations
Reduces code duplication by having heavy methods call their light
counterparts with conversion helpers:
- Add detail::toLightMods() to convert heavy Peptide::Modification to
LightModification format
- Add detail::applyLocationUpdates() to apply location changes back
- shufflePeptide() now delegates to shufflePeptideLight()
- reversePeptide() now delegates to reversePeptideLight()
- switchKR() now delegates to switchKRLight()
- hasCNterminalMods_() now delegates to hasCNterminalModsLight_()
Also fixes identity comparison in shufflePeptideLight to compare against
the working copy (peptide_seq) rather than original sequence, matching
the original heavy method behavior where the peptide object gets updated
during mutation phases.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add FuzzyDiff -sort flag for order-independent file comparison
- Add -sort flag to FuzzyDiff that sorts data lines before comparison
(preserves header as first line)
- Update PQP roundtrip test to use -sort flag since PQP reader returns
transitions ordered by ID, not by original insertion order
- Update light-path roundtrip test to use -sort flag
- Add expected output files for roundtrip tests with correct TSV format
(UniprotId is empty in PQP roundtrip since PQP format doesn't store it)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Implement light-path IPF support for uisTransitionsLight()
Add memory-efficient light version of uisTransitions() to enable IPF
(Identification Peptide Fragment) workflows for large-scale spectral
libraries without loading full TargetedExperiment objects.
Key implementations:
- generateTargetInSilicoMapLight_(): Generate theoretical peptidoforms
- generateDecoyInSilicoMapLight_(): Generate decoy peptidoforms
- generateTargetAssaysLight_(): Create UIS transitions with peptidoforms
- generateDecoyAssaysLight_(): Create decoy UIS transitions (filtered)
- uisTransitionsLight(): Main orchestrator following 4-step pipeline
Critical bug fixes applied during review:
- Use target peptide's SWATH index for decoy generation (not decoy's)
- Use target compound id as DecoyPeptideMap key (matching heavy version)
- Remove incorrect DECOY_ prefix stripping in decoy assay generation
Update OpenSwathAssayGenerator to use light path with -enable_ipf when
input/output formats support it (PQP, TSV, MRM).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add IPF light path tests and fix sequence reconstruction bug
- Fix getAASequenceFromLightCompound() to handle both PQP input (full
modified sequence) and TraML input (unmodified + modifications vector)
- Fix generateDecoyAssaysLight_() to use target_precursor_swath for
DecoyIonMap lookup (matching heavy path behavior)
- Add UIS SWATH window generation and post-IPF restriction to light path
- Add command-line parameters for IPF decoy seed and disable flag
- Add class tests for uisTransitionsLight() with light/heavy equivalence
- Add TOPP test for PQP input with IPF enabled (test_4)
- Remove duplicate include in MRMDecoy_test.cpp
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix light-path TSV output to match heavy-path format
- Default empty GeneName and PeptideGroupLabel fields to "NA"
- Change CollisionEnergy format from "-1" to "-1.0" for consistency
- Update expected test output files
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix test mode to disable decoy transitions for reproducibility
The refactoring that added command-line flags for IPF decoy parameters
accidentally removed the automatic disabling of decoy transitions in
test mode. This caused TOPP_OpenSwathAssayGenerator tests to fail by
generating extra UISDECOY transitions not present in expected outputs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix light-path IPF UIS window generation to respect enable_swath_specifity
The light-path IPF code only checked swathes.empty(), causing divergence
from the heavy path which respects the enable_swath_specifity flag. Changed
the condition to (!enable_swath_specifity || swathes.empty()) to match the
heavy path behavior. Also fixed the loop calculation to use Math::round()
instead of truncation for consistent window count computation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Optimize LightTransition memory layout with compact types
Memory optimizations for LightTransition struct:
- Add FragmentIonType enum (1 byte vs 32+ bytes for std::string)
- Add TransitionFlags bitfield for packed bools (1 byte vs 4+ bytes)
- Change fragment_charge from int to int8_t (4 bytes → 1 byte)
- Change fragment_nr from int to int16_t (4 bytes → 2 bytes)
Estimated savings: ~39+ bytes per transition (~19 MB for 500K transitions)
Updated all consumers to use new getter/setter API:
- TransitionPQPFile.cpp, TransitionTSVFile.cpp (I/O)
- MRMAssay.cpp, MRMDecoy.cpp (assay/decoy generation)
- DataAccessHelper.cpp, OpenSwathHelper.cpp (utilities)
- MRMFeatureFinderScoring.cpp (feature finding)
- pyOpenMS bindings (LightTargetedExperiment.pxd)
All 2383 relevant tests pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Eliminate annotation string field from LightTransition
Replace stored annotation string with getAnnotation() method that
reconstructs annotations from existing fields (fragment_type, fragment_nr,
fragment_charge). This saves ~32 bytes per transition.
Key changes:
- Add getAnnotation() method to LightTransition that builds annotation
strings like "b4^1", "y10^2", "prec" from fragment metadata
- Update MRMAssay.cpp to extract charge from annotation strings when
parsing (format: type + ordinal + "^" + charge)
- Update MRMDecoy.cpp similarly for decoy transition generation
- Update TransitionTSVFile.cpp and TransitionPQPFile.cpp to use
getAnnotation() instead of direct field access
- Update pyOpenMS bindings to expose getAnnotation() method
The annotation format matches MRMIonSeries.cpp which generates
annotations as: type + ordinal + "^" + charge (e.g., "b4^1")
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix decoy compound ID bug in light-path IPF generation
The light-path decoy generation was incorrectly setting decoy_compound.id
to "DECOY_" + compound.id, causing decoy transitions to reference
non-existent compound IDs. This differed from the heavy-path behavior
where decoy peptide IDs are kept identical to target peptide IDs.
Fixed by removing the "DECOY_" prefix, matching the heavy-path approach
where decoy transitions reference target compounds (which exist) and are
distinguished by their decoy flag instead of a different compound ID.
Also updated test reference file to reflect correct annotation
reconstruction from structured fields (FragmentType + FragmentSeriesNumber
+ FragmentCharge).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix heavy-path UIS swath window generation when swathes is empty
The heavy-path IPF code only checked !enable_swath_specifity to decide
whether to generate default UIS swath windows, while the light-path
correctly checks (!enable_swath_specifity || swathes.empty()).
This caused the heavy-path to use empty swathes when enable_swath_specifity
was true but no swathes were provided, resulting in no swath windows being
generated for UIS transitions.
Fixed by adding || swathes.empty() to match the light-path logic.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix duplicate conditions in stringToFragmentIonType
Remove redundant duplicate OR operands in z-prime and z-dot ion checks.
The conditions (s == "z'" || s == "z'") and (s == "z." || s == "z.")
were copy-paste mistakes with identical strings on both sides.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix ambiguous operator+ between String and std::string
Explicitly wrap tr.getFragmentType() in String() to avoid ambiguous
overload resolution between String::operator+ and std::string::operator+
on some compilers/platforms.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Light-path TSV output: use NA for empty fields and fix pyOpenMS bindings
- Add NA handling for empty fields in light-path TSV output:
label_type, compound_name, sum_formula, smiles, adducts,
peptide_sequence, full_peptide_name, protein_names, uniprot_ids
- Fix pyOpenMS LightTargetedExperiment.pxd: use int instead of
signed char/short for fragment_charge and fragment_nr to avoid
Cython treating int8_t as bytes type
- Update test reference files to reflect new NA values
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add light/heavy path equivalence tests for TransitionTSVFile
Add comprehensive unit tests verifying equivalence between light and
heavy paths for transition library I/O:
- Light path TSV roundtrip test
- Light vs Heavy path equivalence via PQP roundtrip
- Light path preserves transition flags (detecting/quantifying/identifying)
- Light path preserves fragment annotation
Tests use field normalization to handle expected empty/"NA" differences
between paths while catching real bugs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add streaming TSV parser for ~5x memory reduction
Implement streamTSVToLightTargetedExperiment_() which reads TSV files
directly into LightTargetedExperiment without creating an intermediate
vector<TSVTransition>. This eliminates the memory duplication where
data was stored twice during parsing.
Memory improvement for 1M transitions:
- Old: ~630MB peak (500MB TSVTransition vector + 130MB LightExperiment)
- New: ~130MB peak (only LightTargetedExperiment + small tracking maps)
Key implementation details:
- Single TSVTransition buffer reused for each line
- Inline mixed sequence group detection during streaming
- Immediate conversion to LightTransition/LightCompound/LightProtein
- Progress tracking with line count pre-scan
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add streaming PQP reader for ~5x memory reduction
Implement streamPQPToLightTargetedExperiment_() which reads PQP files
directly into LightTargetedExperiment without creating an intermediate
vector<TSVTransition>. This eliminates memory duplication during parsing.
Memory improvement for 1M transitions:
- Old: ~630MB peak (500MB TSVTransition vector + 130MB LightExperiment)
- New: ~130MB peak (only LightTargetedExperiment + small tracking maps)
Key implementation details:
- Direct SQL row to LightTransition conversion
- Compound/protein deduplication inline during streaming
- Same SQL queries as original for compatibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Light-path TSV: use empty fields for LabelType, CompoundName, SumFormula, SMILES
Remove NA handling for these 4 fields to match heavy-path output format.
Only Adducts remains as NA when not set.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Cleanup: remove dead code and refactor PQP SQL query building
- Remove unused TSVToTargetedExperiment_ overload for LightTargetedExperiment
(now handled by streaming parser)
- Extract duplicated SQL query building into buildPQPSelectQuery_() helper
- Add PQPSqlQueryInfo struct to hold query and column availability flags
- Net reduction of ~240 lines of code
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Use std::map for MRMIonSeries::IonSeries for ARM64 portability
Change IonSeries typedef from std::unordered_map to std::map to ensure
deterministic iteration order across all platforms. This fixes potential
ARM64 portability issues where hash table iteration order differs from
x86_64, causing different ion annotation results when tie-breaking in
annotateIon().
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix switchKRLight() to use portable deterministic hash
Replace static RNG with FNV-1a hash of peptide sequence for selecting
replacement amino acids. This ensures:
- Same peptide always gets the same replacement AA (reproducible)
- Results are independent of processing order (portable across platforms)
- Fixes ARM64 portability issue where hash table iteration order differs
Updated test expected outputs to reflect the new deterministic behavior.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Remove dead srand() calls in MRMDecoy
The srand(time(nullptr)) calls seeded C's rand() function, but
portable_random_shuffle() uses boost::mt19937_64 which is independent.
These calls had no effect on program behavior.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Light-path TSV: use empty fields for Adducts and UniprotId
For consistency with heavy-path output, leave Adducts and UniprotId
columns empty instead of "NA" when not set.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix OpenSwathAssayGenerator test_4 for cross-platform portability
PQP files (SQLite binary format) have platform-dependent internal
layout, causing byte-by-byte comparison to fail on macOS ARM64.
Changed test to use TSV roundtrip comparison with -sort flag for
portable testing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* [DOC] Improve AGENTS.md based on best practices research (#8560)
Restructure AGENTS.md following the AGENTS.md standard best practices:
- Add Critical Constraints section upfront (what NOT to do)
- Add Quick Commands section with copy-paste ready commands
- Add code examples for naming conventions and file structure
- Add testing pattern examples with actual code
- Add verification commands section
- Create concise change impact checklist table
- Consolidate external links to essential resources only
- Improve overall structure for agent consumption
Based on research from GitHub's analysis of 2,500+ repositories
and the official AGENTS.md specification.
Co-authored-by: Claude <noreply@anthropic.com>
* Remove outdated template files and update test creation documentation (#8548)
* Initial plan
* Remove outdated templates and update documentation references
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
* [DOC] Improve AGENTS.md based on best practices research (#8563)
* [DOC] Improve AGENTS.md based on best practices research
Enhance AGENTS.md following the AGENTS.md standard best practices while
preserving all original content:
Added:
- Critical Constraints section upfront (explicit "NEVER do" list)
- Quick Commands section with copy-paste ready bash commands
- Visual directory tree for repo layout
- Code examples for naming conventions, file structure, and tests
- Commit message example
- Debugging command examples
Preserved:
- All original build/install instructions
- All testing guidelines and details
- All coding conventions
- All pyOpenMS wrapping details
- All external documentation links
- All CI/packaging information
Based on research from GitHub's analysis of 2,500+ repositories
and the official AGENTS.md specification.
* [DOC] Add Doxygen style guide and OS-specific build gotchas to AGENTS.md
Expand AGENTS.md with detailed information researched from the codebase:
Doxygen Documentation Style:
- File header format with $Maintainer$ and $Authors$ markers
- Class documentation with @brief, @ingroup, @htmlinclude
- Method documentation with @param[in/out], @return, @throws
- Constructor/destructor grouping with @name and //@{
- Inline documentation with /// comments
- Common Doxygen tags reference table
Platform-Specific Build Gotchas:
- Windows: MSVC requirements, MinGW not supported, Release/Debug mixing
- macOS: AppleClang linker flag, Qt PrintSupport, code signing
- Linux: PIC flags, STL debug mode, headless GUI testing
- Qt6: version requirements, component dependencies, WebEngine
- Boost: Homebrew static linking issues and workarounds
- CMake: CMAKE_SIZEOF_VOID_P bug, Eigen3 version detection
Also added:
- Required and optional dependency lists
- CMake minimum version (3.21) and C++20 standard requirement
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Cleanup TOPP tests, clean gitignore (#8555)
* Fix some race conditions in topp tests
* remove files that shouldn''t be tracked
* start moving temporary topp files into separate directory
* second batch of topp tests fixed.
* third batch
* fourth pass
* ixed the hardcoded CSV output path to use the input file's directory instead of the test execution directory, and corrected all 8 instances of "ambigious" → "ambiguous" spelling
* re-add idripper idxmls
* re-organize .gitignore
* more .gitignore cleanup
* create proper temp files for tests
* gitignore cleanup
* remove dupes from merge
* address coderabbit comments
* Fix temp file location
* use QDir for constructing paths in OpenNuXL
* Remove overbroad test file exclusions from gitignore
* Address code comments.
* Document ProteomicsLFQ automatic median normalization behavior (#8438)
* Initial plan
* Document ProteomicsLFQ normalization behavior
- Add detailed normalization documentation to Doxygen header
- Clarify automatic median normalization for feature intensity quantification
- Document when normalization is disabled (MSstats/Triqler output)
- Explain relationship between consensus feature normalization and ProteinQuantification:consensus:normalize
- Add inline code comments for better code clarity
- Update PeptideAndProteinQuant parameter description
- Provide workaround for using alternative normalization methods
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Fix hyphenation in documentation
Use proper compound adjective form "feature-intensity-based" instead of "feature intensity-based"
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Apply suggestions from code review
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
* Enhance DataValue conversion error messages with type and value context (#8572)
* Initial plan
* Improve DataValue error messages to include type and value information
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Add tests to verify improved DataValue error messages
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Document wrapping classes with deleted/private constructors in pyOpenMS (#8561)
* Initial plan
* Document how to wrap classes with deleted/private constructors in pyOpenMS
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Fix spacing in wrap-ignore comment for consistency
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Add namespace context to XMLHandler example for accuracy
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Add clarifying notes about singleton getInstance() overloads
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Improve documentation for wrap-manual-memory and fix Pattern 4 example
- Add wrap-manual-memory directive to "Hints to autowrap" section
- Document autowrap naming convention for wrap-ignore'd functions
- Fix misleading wrap-manual-dealloc reference (not a real directive)
- Update Pattern 4 example to match actual ConsensusIDAlgorithm.pxd
- Use PeptideIdentificationList instead of outdated libcpp_vector type
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Add precursor m/z range filter option to PeakFileOptions
Adds setPrecursorMZRange(), hasPrecursorMZRange(), and getPrecursorMZRange()
methods to filter spectra based on their precursor m/z values. Updates
hasFilters() to include this new filter type.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
Co-authored-by: Samuel Wein <sam@samwein.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Justin Sing <32938975+singjc@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Add PeakFileOptions support to OnDiscMSExperiment
This enables users to set filtering options (m/z range, intensity range,
RT range, MS levels, etc.) for OnDiscMSExperiment, similar to how it works
for in-memory MSExperiment loading via FileHandler.
Changes:
- Added PeakFileOptions member and getOptions/setOptions methods
- Options are applied when loading metadata (RT range, MS levels filter)
- Options are applied when retrieving spectra (m/z, intensity filters)
- Options are applied when retrieving chromatograms (RT, intensity filters)
- Updated copy constructor to copy options
- Added pyOpenMS bindings for new methods
- Added comprehensive tests for the new functionality
* Optimize OnDiscMSExperiment to skip I/O for filtered spectra
When RT range or MS level filters are set, check metadata BEFORE loading
peak data. If a spectrum doesn't pass these filters, return it with
metadata but skip the expensive I/O operation to load peaks.
This allows efficient iteration over large files where only a subset
of spectra are needed based on RT or MS level criteria.
* Fix metadata loading to maintain index correspondence
Changed loadMetaData_() to always load ALL metadata without RT/MS level
filters. This ensures index correspondence between indexed_mzml_file_ and
meta_ms_experiment_ is maintained.
Filtering behavior for OnDiscMSExperiment:
- RT range and MS level filters are checked at retrieval time (skips I/O)
- Filtered spectra return with metadata but no peaks
- All indices are preserved (unlike in-memory loading where filtered
spectra are removed from the container)
Also added comprehensive documentation explaining this behavior.
* feature: Add PeakFileOptions support to OnDiscMSExperiment (#8534)
* [FEATURE] Add FAIMS support to ProteomicsLFQ (#8478)
- Annotate peptide IDs with FAIMS_CV from spectrum data before feature
detection, enabling proper per-CV filtering in FeatureFinderIdentificationAlgorithm
- Add documentation describing FAIMS support: automatic detection,
per-CV processing, feature merging, and downstream alignment/linking
FAIMS data is now automatically handled:
1. FFI splits data by compensation voltage and processes each CV group
2. Features from different CVs representing the same analyte are merged
3. Merged features are aligned and linked based on RT and m/z
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Add append() and extend() methods to pyOpenMS map classes with __len__ support (#8510)
Implements feature request #8124 by adding Pythonic methods to:
- ConsensusMap: __len__, append, extend
- FeatureMap: __len__, append, extend
- PeptideIdentificationList: append, extend (already had __len__)
These methods provide a more Pythonic interface:
- __len__() enables use of built-in len() function
- append() adds single items (equivalent to push_back())
- extend() adds multiple items from iterables or other map objects
Includes comprehensive unit tests for all new methods.
Co-authored-by: Claude <noreply@anthropic.com>
* Store PeptideIndexer settings as metavalues in SearchParameters (#8489)
* Initial plan
* Add PeptideIndexer settings as metavalues in ProteinIdentification
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Extract metavalue keys as constants to improve maintainability
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Remove trailing whitespace from PeptideIndexing.h
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Use !empty() instead of size() > 0 for better readability
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Store PeptideIndexer settings in SearchParameters instead of ProteinIdentification
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Remove unnecessary static constants for metavalue keys
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Fix PeptideIndexing test and update test output files
- Fix unit test to provide ProteinIdentification before running
(the test was creating an empty prot_ids vector but expecting
metavalues to be set - the code only updates existing
ProteinIdentifications)
- Update all PeptideIndexer TOPP test expected output files to
include the new metavalues in SearchParameters
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add PeptideIndexer settings to TOPP test expected output files (#8509)
Update expected output files to include PeptideIndexer settings that are
now written to SearchParameters. This includes decoy_string, enzyme,
enzyme_specificity, and related parameters.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Add PeptideIndexer params to SageAdapter test output (#8518)
Update the SageAdapter_1_out.idXML test file to include the
PeptideIndexer metavalues that were missing from the PR #8509
update which added these to other adapter test files.
Co-authored-by: Claude <noreply@anthropic.com>
* Check the return value of configure so that we stop on configure errors (#8515)
* Check the return value of configure so that we stop on configure errors
* make sure nsis is in path.
* Simplify notarization step in CI workflow
Removed redundant notarization parameters from CI workflow.
* fix cat-on-keyboard error
Updated the workflow to use a structured THIRDPARTY directory.
* Simplify CI workflow by removing deb dependency check
Removed conditional dependency installation for deb packages in CI workflow.
* Use external libraries from Debian repos to prevent deb package conflicts (#8496)
* Initial plan
* Use external SQLite3, SQLiteCpp, nlohmann-json, and SIMDe from Debian repos
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Fix debian package dependencies - SQLiteCpp is static library
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* Add documentation for USE_EXTERNAL_* CMake options
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
Co-authored-by: Samuel Wein <sam@samwein.com>
* Use unsigned channel identifiers in peptide quantification (#8516)
* Remove non-schema CMakeLists.txt from OPENSWATH directory (#8513)
* Initial plan
* Remove non-standard CMakeLists.txt from OPENSWATH directory
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
* explicitly add timestamping to notarization process (#8527)
* Hide Eigen from OpenMS public API (Issue #8456) (#8511)
* Hide Eigen from OpenMS public API (Issue #8456)
This implements Option D from issue #8456: use Eigen::Map only without PIMPL.
Changes:
- Move Eigen3::Eigen from PUBLIC to PRIVATE linking in CMakeLists.txt
- Rewrite Matrix<T> to use std::vector<T> storage (column-major)
- Add internal MatrixEigen.h with eigenView() for zero-copy Eigen access
- Refactor TraceFitter/LevMarqFitter1D GenericFunctor to use raw double*
instead of Eigen types in public interface
- Update all internal code to use eigenView() where Eigen operations needed
- Add missing includes (<cmath>, <Eigen/LU>, <Eigen/QR>) where needed
- Update tests to link against Eigen when using eigenView() directly
The Matrix class now provides:
- std::vector storage with data() pointer access
- getValue/setValue methods for element access
- eigenView() (internal) for full Eigen matrix operations
Downstream users no longer need Eigen headers when using OpenMS.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add pyOpenMS test for Matrix column-major ordering
Add testMatrixDoubleColumnMajorOrdering() to verify that the Matrix class
correctly preserves row/column ordering when passing data between numpy
and C++. This test catches potential column-major vs row-major issues that
could cause data transposition.
The test verifies:
- Shape preservation (3x4 matrix stays 3x4, not transposed to 4x3)
- Element-by-element verification via getValue matches numpy indexing
- Round-trip preservation (numpy -> C++ -> numpy)
- View indexing matches getValue for all elements
- Modifications through numpy view are reflected in C++ object
- Highly non-square matrices (2x5) work correctly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix Doxygen for solveNNLS_ to document in-place matrix modification
Update the documentation for the non-const solveNNLS_ overload to correctly
indicate that correction_matrix is modified in-place by the NNLS solver.
Changed @param[in] to @param[in,out] and added a @note explaining that
this overload mutates the matrix for efficiency, with a reference to the
const-preserving overload for cases where the original must be preserved.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix Doxygen for computeStats_ to correctly document parameters
- Change @param[out] x_naive to @param[in] (it's const reference input)
- Change @param[in] stats to @param[in,out] (it's modified by function)
- Clarify that x_naive is LU-decomposition solution, not "uncorrected"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix Doxygen param annotations for NonNegativeLeastSquaresSolver
Add proper @param[in], @param[out], @param[in,out] annotations based on
actual implementation behavior:
- const Matrix& overload: A and b are [in] (copies made internally)
- raw pointer overload: A and b are [in,out] (modified by NNLS solver)
- Matrix& overload: A and b are [in,out] (passed to raw pointer version)
Also clarify in @brief that const overload preserves originals while
non-const overloads modify inputs in-place for efficiency.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix misleading comments about Matrix template instantiations
Remove contradictory comment that said "No explicit template instantiations
needed" when explicit instantiations are present. Clarify that these are
explicit instantiations to compile template code into libOpenMS.so, not
"default instances for backwards compatibility".
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Remove Eigen dependency from NonNegativeLeastSquaresSolver_test
Remove include of internal MatrixEigen.h header and replace Eigen::Index
with Size. This aligns with the PR goal of hiding Eigen from the public API.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add unit tests for internal MatrixEigen utilities
Test coverage for the internal Eigen-based utilities in MatrixEigen.h:
- eigenView() for mutable and const Matrix
- eigenVectorView() for std::vector and raw pointers
- eigenMatrixView() for raw pointers
- Zero-copy verification (modifications through view affect original)
- Eigen operations work correctly on views
- Matrix/view consistency with column-major storage
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add pointer-safety documentation for NNLS raw-pointer overload
Document memory requirements, ownership semantics, and lifetime constraints
for the double* A parameter:
- Must be non-null, pointing to A_rows * A_cols contiguous doubles
- Column-major storage order required
- Caller retains ownership and must ensure validity during call
- Contents modified in-place and undefined after call
- nullptr or undersized buffer is undefined behavior
Also add note recommending Matrix& overload for safety and mention
std::span as potential future improvement.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Link MRMScoring_test to Eigen3::Eigen
MRMScoring_test.cpp includes MatrixEigen.h which requires Eigen headers.
Since Eigen is a PRIVATE dependency of OpenMS, tests that directly include
internal Eigen-dependent headers must explicitly link to Eigen3::Eigen.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Remove Eigen dependency from ImageCreator
- Add maxValue() and minValue() methods to Matrix class using std::max_element/std::min_element
- Update ImageCreator.cpp to use Matrix::maxValue() instead of eigenView().maxCoeff()
- Remove MatrixEigen.h include from ImageCreator.cpp
This fixes the build error where ImageCreator failed to compile because
it included MatrixEigen.h but TOPP tools don't link against Eigen3::Eigen.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Replace Eigen::Index with Size in test files
Part of hiding Eigen from the public API. Tests should not use
Eigen types directly since Eigen is an internal implementation detail.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add missing <atomic> include to MzMLHandler.cpp
Fix build failure caused by missing std::atomic include. This was
previously provided transitively through Eigen headers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix Doxygen documentation warnings in Matrix.h (#8529)
* Initial plan
* Fix Doxygen warnings in Matrix.h getValue/setValue documentation
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
* Wrap Math::getPPM template functions for Python bindings (#8525)
* Initial plan
* Add Math.pxd wrapper and unit tests for Math::getPPM functions
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Update Math.pxd to properly handle template functions with concrete double type
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Remove unnecessary wrap-as directives from Math.pxd
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Improve documentation for Math class wrapper with usage examples
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Add wrap-doc documentation at function level for all Math functions
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Update Math class documentation to be more general and extensible
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
* Add precursor m/z range filter to PeakFileOptions (#8526)
* Initial plan
* Add precursor m/z range filter support to PeakFileOptions
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Implement precursor m/z range filtering in MzML, MzXML, and MzData handlers
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Fix MzXMLHandler to properly skip filtered spectra by removing from spectrum_data_
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
* Initial plan
* Changes before error encountered
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Remove MS level check from precursor m/z range filter
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* [DOC] Add AGENTS.md guidance (#8537)
* [DOC] Add AGENTS.md guidance
* [DOC] Update TOPP tool documentation paths
* Implement to_df directly in Cython files (#8520)
* Move get_df() methods directly into Cython .pyx addon files
Instead of using Python wrapper classes in _dataframes.py to add DataFrame
export functionality, implement get_df() directly in the Cython addon files
alongside get_data_dict(). This simplifies the architecture by:
- Removing the "duck typing hack" of wrapper classes that override Cython classes
- Putting all DataFrame logic in one place (the Cython addon files)
- Making the code flow more straightforward
Changes:
- MSSpectrum.pyx: Added get_df()
- MSChromatogram.pyx: Added get_df()
- Mobilogram.pyx: Added get_df()
- MSExperiment.pyx: Added get_df_columns(), get_df(), get_ion_df(), get_massql_df()
- ConsensusMap.pyx: Added get_df_columns(), get_intensity_df(), get_metadata_df(), get_df()
- FeatureMap.pyx: Added get_df_columns(), get_df(), get_assigned_peptide_identifications()
- MRMTransitionGroupCP.pyx: New addon with get_chromatogram_df(), get_feature_df() methods
- _dataframes.py: Simplified to only export standalone functions
- README.md: Updated documentation to reflect new pattern
* Add get_df() to PeptideIdentificationList and comprehensive tests
- Add get_df() and update_scores_from_df() methods to PeptideIdentificationList.pyx
following the same pattern as other data structures
- Update _dataframes.py to use backwards-compatible wrapper functions that call the
new methods (peptide_identifications_to_df → peps.get_df(), update_scores_from_df → peps.update_scores_from_df())
- Simplify _dataframes.py by removing duplicate implementation code
- Add comprehensive tests for:
- PeptideIdentificationList.get_df() with various parameters
- PeptideIdentificationList.update_scores_from_df()
- Mobilogram.get_df() column selection
- Backwards-compatible wrapper functions
* Fix Cython compilation errors in get_df() addon methods
- Use lazy pandas imports inside methods to avoid module-level import issues
- Replace bool() calls with len() > 0 to avoid Cython type conflicts
- Replace {bool: ...} dict keys with {type(True): ...} for same reason
- Rename 'long' parameter to 'long_format' to avoid Cython keyword conflict
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add to_arrow() methods for Apache Arrow Table export
Add to_arrow() methods to pyOpenMS classes following the Polars naming convention:
- MSSpectrum.to_arrow() - reuses get_data_dict() for efficient numpy-to-Arrow conversion
- MSChromatogram.to_arrow() - reuses get_data_dict()
- Mobilogram.to_arrow() - reuses get_data_dict()
- MSExperiment.to_arrow() - supports long_format parameter like get_df()
- ConsensusMap.to_arrow() - wraps get_df() with pa.Table.from_pandas()
- FeatureMap.to_arrow() - wraps get_df() with pa.Table.from_pandas()
- MRMTransitionGroupCP.chromatograms_to_arrow(), features_to_arrow()
- PeptideIdentificationList.to_arrow()
All methods use lazy imports for pyarrow to keep it as an optional dependency.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix UnboundLocalError in PeptideIdentificationList.get_df()
When a PeptideHit doesn't have a particular metavalue, the code would
reference an undefined 'val' variable. Fix by using the precomputed
dmv[idx] array which already contains the correct default missing value
for each metavalue's type.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix bugs and add tests for DataFrame/Arrow export
Bug fixes:
- ConsensusMap.get_intensity_df(): Fix np.fromiter count truncation
by computing actual row count (one row per file per feature)
- MSExperiment.get_massql_df(): Fix division by zero in intensity
normalization for empty spectra or all-zero intensities
- _dataframes.py: Fix 'any' to 'Any' type hint import
Tests added:
- TestToArrowMethods: 7 tests for to_arrow() across all classes
- TestBugFixes: 3 tests for the bug fixes above
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix FeatureMap.get_df() missing spectrum_native_id check
Add existence check for 'spectrum_native_id' meta value before calling
getMetaValue() in extract_meta_data(). This follows the same pattern
used in get_assigned_peptide_identifications().
Without this check, calling get_df() on a FeatureMap where some features
lack the 'spectrum_native_id' meta value could fail unexpectedly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix test parameter name mismatch in MSExperiment.get_df() test (#8523)
* Initial plan
* Fix test parameter name: change long= to long_format= in MSExperiment test
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Potential fix for pull request finding 'Unused import'
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* Apply suggestions from code review
Co-authored-by: Justin Sing <32938975+singjc@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Make pandas and pyarrow optional dependencies with Sphinx docstrings (#8535)
* Initial plan
* Remove pandas from required dependencies and fix docstrings
- Removed pandas from install_requires in setup.py (now optional)
- Added ImportError with helpful message when pandas is not installed
- Fixed all docstrings to use Sphinx reStructuredText format (:param, :type, :return, :rtype, :raises)
- Updated docstrings in 8 addon files (ConsensusMap, FeatureMap, MRMTransitionGroupCP, MSChromatogram, MSExperiment, MSSpectrum, Mobilogram, PeptideIdentificationList)
- Also added ImportError handling for pyarrow imports (optional dependency)
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Fix remaining to_arrow() docstrings to use Sphinx format
- Updated all to_arrow() method docstrings to use Sphinx reStructuredText format
- Fixed docstrings in ConsensusMap, FeatureMap, MRMTransitionGroupCP, MSChromatogram, MSExperiment, MSSpectrum, Mobilogram, PeptideIdentificationList
- All DataFrame and Arrow export methods now have consistent Sphinx-style documentation
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Install pandas and pyarrow for CI test job (#8539)
* Initial plan
* Install pandas and pyarrow in test job for optional dependency tests
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* some review comments (#8540)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Justin Sing <32938975+singjc@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Add security patterns to .gitignore to prevent credential leaks (#8545)
* Add security patterns to .gitignore to prevent credential leaks
Add comprehensive gitignore rules for common credential and secret files:
- Environment files (.env, .env.*)
- Private keys and certificates (.pem, .key, .p12, .pfx, .crt)
- Credential files (credentials.json, secrets.yaml, etc.)
- Cloud provider credentials (AWS, SSH keys)
- API tokens and keys (.npmrc, .pypirc, .netrc, *.token)
- Docker and Kubernetes secrets
- Database files that may contain credentials
- OAuth tokens and client secrets
- GPG keys
- Terraform and Ansible vault files
- IDE credential storage
- Shell history files
- Local config files that may contain secrets
- Jupyter notebook checkpoints
- GitHub and AI service tokens
* Remove database extensions from gitignore
OpenMS uses SQLite databases (via SQLiteCpp library, MzMLSqliteHandler,
SqliteConnector, etc.) so *.sqlite, *.sqlite3, and *.db should not be ignored.
---------
Co-authored-by: Claude <noreply@anthropic.com>
* MetaboliteSpectralMatcher fixes from playing with Nucleosides (#8163)
* Update src/openms/source/ANALYSIS/ID/MetaboliteSpectralMatching.cpp
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Update src/openms/source/ANALYSIS/ID/MetaboliteSpectralMatching.cpp
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Apply suggestions from code review
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Update MetaboliteSpectralMatching.cpp
* fix
* add test with GNPS MGF
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
* propagate extern libs settings to package (#8556)
* fix macos pkg logo (#8554)
* Inital steps for moving to LightTransition (WIP) (#8544)
* inital commit
* Fix pyOpenMS build for C++20 and modern dependencies
IDFilter.h:
- Add IsNotIdentificationVector concept to disambiguate template overloads
- Add removeEmptyIdentifications(PeptideIdentificationList&) overload
- Fixes autowrap-generated binding compilation with C++20 concepts
setup.py:
- Use numpy.get_include() for numpy 2.x compatibility
- Update C++ standard from C++17 to C++20 (required for OpenMS concepts)
- Change Qt5 to Qt6 on Linux (matches OpenMS build)
- Change libomp to gomp (GNU OpenMP runtime for GCC builds)
- Fix libraries.extend() bug: was iterating string characters instead of append
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix issues from CodeRabbit PR review
- MRMDecoy.cpp: Fix shuffle check to use decoy_temp_peptide instead of temp_peptide
- LightTargetedExperiment.pxd: Add missing isPrecursorImSet() and getPrecursorIM() methods
- OpenSwathAssayGenerator.cpp: Fix if/else-if chain for output file type handling
- OpenSwathDecoyGenerator.cpp: Add division by zero protection and fix if/else-if chain
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add tests for light and heavy decoy generation paths
Add test 6 (light path) and test 7 (heavy path) for OpenSwathDecoyGenerator
to verify both code paths produce correct output:
- Test 6: TSV -> TSV using LightTargetedExperiment (memory-efficient path)
- Test 7: TSV -> TraML using TargetedExperiment (full feature path)
Both tests use the same input (OpenSwathDecoyGenerator_input_4.tsv) and
parameters to verify that the light and heavy paths generate equivalent
decoy sequences.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add debug logging for transition sequence parsing failures
Add OPENMS_LOG_DEBUG statement when transitions are skipped due to
unparseable sequences, improving debuggability.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Implement pure light-path decoy generation methods
Address PR review feedback from singjc regarding memory efficiency:
- Add reversePeptideLight() for light peptide sequence reversal
- Add shufflePeptideLight() for light peptide shuffling with mods
- Add pseudoreversePeptideLight_() for pseudo-reverse (keep C-term)
- Add switchKRLight() for terminal K/R switching
- Add hasCNterminalModsLight_() for terminal mod detection
- Update generateDecoysLight() to use pure light methods
These methods operate directly on std::string and LightModification
vectors, avoiding temporary TargetedExperiment::Peptide allocations
for improved memory efficiency with large spectral libraries.
Also includes:
- Documentation for detecting/quantifying transition defaults
- PQP output tests for light path
- TODO comment for future IPF light path support
- Comprehensive unit tests comparing light vs heavy methods
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Refactor MRMDecoy heavy methods to delegate to light implementations
Reduces code duplication by having heavy methods call their light
counterparts with conversion helpers:
- Add detail::toLightMods() to convert heavy Peptide::Modification to
LightModification format
- Add detail::applyLocationUpdates() to apply location changes back
- shufflePeptide() now delegates to shufflePeptideLight()
- reversePeptide() now delegates to reversePeptideLight()
- switchKR() now delegates to switchKRLight()
- hasCNterminalMods_() now delegates to hasCNterminalModsLight_()
Also fixes identity comparison in shufflePeptideLight to compare against
the working copy (peptide_seq) rather than original sequence, matching
the original heavy method behavior where the peptide object gets updated
during mutation phases.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add FuzzyDiff -sort flag for order-independent file comparison
- Add -sort flag to FuzzyDiff that sorts data lines before comparison
(preserves header as first line)
- Update PQP roundtrip test to use -sort flag since PQP reader returns
transitions ordered by ID, not by original insertion order
- Update light-path roundtrip test to use -sort flag
- Add expected output files for roundtrip tests with correct TSV format
(UniprotId is empty in PQP roundtrip since PQP format doesn't store it)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Implement light-path IPF support for uisTransitionsLight()
Add memory-efficient light version of uisTransitions() to enable IPF
(Identification Peptide Fragment) workflows for large-scale spectral
libraries without loading full TargetedExperiment objects.
Key implementations:
- generateTargetInSilicoMapLight_(): Generate theoretical peptidoforms
- generateDecoyInSilicoMapLight_(): Generate decoy peptidoforms
- generateTargetAssaysLight_(): Create UIS transitions with peptidoforms
- generateDecoyAssaysLight_(): Create decoy UIS transitions (filtered)
- uisTransitionsLight(): Main orchestrator following 4-step pipeline
Critical bug fixes applied during review:
- Use target peptide's SWATH index for decoy generation (not decoy's)
- Use target compound id as DecoyPeptideMap key (matching heavy version)
- Remove incorrect DECOY_ prefix stripping in decoy assay generation
Update OpenSwathAssayGenerator to use light path with -enable_ipf when
input/output formats support it (PQP, TSV, MRM).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add IPF light path tests and fix sequence reconstruction bug
- Fix getAASequenceFromLightCompound() to handle both PQP input (full
modified sequence) and TraML input (unmodified + modifications vector)
- Fix generateDecoyAssaysLight_() to use target_precursor_swath for
DecoyIonMap lookup (matching heavy path behavior)
- Add UIS SWATH window generation and post-IPF restriction to light path
- Add command-line parameters for IPF decoy seed and disable flag
- Add class tests for uisTransitionsLight() with light/heavy equivalence
- Add TOPP test for PQP input with IPF enabled (test_4)
- Remove duplicate include in MRMDecoy_test.cpp
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix light-path TSV output to match heavy-path format
- Default empty GeneName and PeptideGroupLabel fields to "NA"
- Change CollisionEnergy format from "-1" to "-1.0" for consistency
- Update expected test output files
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix test mode to disable decoy transitions for reproducibility
The refactoring that added command-line flags for IPF decoy parameters
accidentally removed the automatic disabling of decoy transitions in
test mode. This caused TOPP_OpenSwathAssayGenerator tests to fail by
generating extra UISDECOY transitions not present in expected outputs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix light-path IPF UIS window generation to respect enable_swath_specifity
The light-path IPF code only checked swathes.empty(), causing divergence
from the heavy path which respects the enable_swath_specifity flag. Changed
the condition to (!enable_swath_specifity || swathes.empty()) to match the
heavy path behavior. Also fixed the loop calculation to use Math::round()
instead of truncation for consistent window count computation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Optimize LightTransition memory layout with compact types
Memory optimizations for LightTransition struct:
- Add FragmentIonType enum (1 byte vs 32+ bytes for std::string)
- Add TransitionFlags bitfield for packed bools (1 byte vs 4+ bytes)
- Change fragment_charge from int to int8_t (4 bytes → 1 byte)
- Change fragment_nr from int to int16_t (4 bytes → 2 bytes)
Estimated savings: ~39+ bytes per transition (~19 MB for 500K transitions)
Updated all consumers to use new getter/setter API:
- TransitionPQPFile.cpp, TransitionTSVFile.cpp (I/O)
- MRMAssay.cpp, MRMDecoy.cpp (assay/decoy generation)
- DataAccessHelper.cpp, OpenSwathHelper.cpp (utilities)
- MRMFeatureFinderScoring.cpp (feature finding)
- pyOpenMS bindings (LightTargetedExperiment.pxd)
All 2383 relevant tests pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Eliminate annotation string field from LightTransition
Replace stored annotation string with getAnnotation() method that
reconstructs annotations from existing fields (fragment_type, fragment_nr,
fragment_charge). This saves ~32 bytes per transition.
Key changes:
- Add getAnnotation() method to LightTransition that builds annotation
strings like "b4^1", "y10^2", "prec" from fragment metadata
- Update MRMAssay.cpp to extract charge from annotation strings when
parsing (format: type + ordinal + "^" + charge)
- Update MRMDecoy.cpp similarly for decoy transition generation
- Update TransitionTSVFile.cpp and TransitionPQPFile.cpp to use
getAnnotation() instead of direct field access
- Update pyOpenMS bindings to expose getAnnotation() method
The annotation format matches MRMIonSeries.cpp which generates
annotations as: type + ordinal + "^" + charge (e.g., "b4^1")
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix decoy compound ID bug in light-path IPF generation
The light-path decoy generation was incorrectly setting decoy_compound.id
to "DECOY_" + compound.id, causing decoy transitions to reference
non-existent compound IDs. This differed from the heavy-path behavior
where decoy peptide IDs are kept identical to target peptide IDs.
Fixed by removing the "DECOY_" prefix, matching the heavy-path approach
where decoy transitions reference target compounds (which exist) and are
distinguished by their decoy flag instead of a different compound ID.
Also updated test reference file to reflect correct annotation
reconstruction from structured fields (FragmentType + FragmentSeriesNumber
+ FragmentCharge).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix heavy-path UIS swath window generation when swathes is empty
The heavy-path IPF code only checked !enable_swath_specifity to decide
whether to generate default UIS swath windows, while the light-path
correctly checks (!enable_swath_specifity || swathes.empty()).
This caused the heavy-path to use empty swathes when enable_swath_specifity
was true but no swathes were provided, resulting in no swath windows being
generated for UIS transitions.
Fixed by adding || swathes.empty() to match the light-path logic.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix duplicate conditions in stringToFragmentIonType
Remove redundant duplicate OR operands in z-prime and z-dot ion checks.
The conditions (s == "z'" || s == "z'") and (s == "z." || s == "z.")
were copy-paste mistakes with identical strings on both sides.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix ambiguous operator+ between String and std::string
Explicitly wrap tr.getFragmentType() in String() to avoid ambiguous
overload resolution between String::operator+ and std::string::operator+
on some compilers/platforms.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Light-path TSV output: use NA for empty fields and fix pyOpenMS bindings
- Add NA handling for empty fields in light-path TSV output:
label_type, compound_name, sum_formula, smiles, adducts,
peptide_sequence, full_peptide_name, protein_names, uniprot_ids
- Fix pyOpenMS LightTargetedExperiment.pxd: use int instead of
signed char/short for fragment_charge and fragment_nr to avoid
Cython treating int8_t as bytes type
- Update test reference files to reflect new NA values
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add light/heavy path equivalence tests for TransitionTSVFile
Add comprehensive unit tests verifying equivalence between light and
heavy paths for transition library I/O:
- Light path TSV roundtrip test
- Light vs Heavy path equivalence via PQP roundtrip
- Light path preserves transition flags (detecting/quantifying/identifying)
- Light path preserves fragment annotation
Tests use field normalization to handle expected empty/"NA" differences
between paths while catching real bugs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add streaming TSV parser for ~5x memory reduction
Implement streamTSVToLightTargetedExperiment_() which reads TSV files
directly into LightTargetedExperiment without creating an intermediate
vector<TSVTransition>. This eliminates the memory duplication where
data was stored twice during parsing.
Memory improvement for 1M transitions:
- Old: ~630MB peak (500MB TSVTransition vector + 130MB LightExperiment)
- New: ~130MB peak (only LightTargetedExperiment + small tracking maps)
Key implementation details:
- Single TSVTransition buffer reused for each line
- Inline mixed sequence group detection during streaming
- Immediate conversion to LightTransition/LightCompound/LightProtein
- Progress tracking with line count pre-scan
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add streaming PQP reader for ~5x memory reduction
Implement streamPQPToLightTargetedExperiment_() which reads PQP files
directly into LightTargetedExperiment without creating an intermediate
vector<TSVTransition>. This eliminates memory duplication during parsing.
Memory improvement for 1M transitions:
- Old: ~630MB peak (500MB TSVTransition vector + 130MB LightExperiment)
- New: ~130MB peak (only LightTargetedExperiment + small tracking maps)
Key implementation details:
- Direct SQL row to LightTransition conversion
- Compound/protein deduplication inline during streaming
- Same SQL queries as original for compatibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Light-path TSV: use empty fields for LabelType, CompoundName, SumFormula, SMILES
Remove NA handling for these 4 fields to match heavy-path output format.
Only Adducts remains as NA when not set.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Cleanup: remove dead code and refactor PQP SQL query building
- Remove unused TSVToTargetedExperiment_ overload for LightTargetedExperiment
(now handled by streaming parser)
- Extract duplicated SQL query building into buildPQPSelectQuery_() helper
- Add PQPSqlQueryInfo struct to hold query and column availability flags
- Net reduction of ~240 lines of code
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Use std::map for MRMIonSeries::IonSeries for ARM64 portability
Change IonSeries typedef from std::unordered_map to std::map to ensure
deterministic iteration order across all platforms. This fixes potential
ARM64 portability issues where hash table iteration order differs from
x86_64, causing different ion annotation results when tie-breaking in
annotateIon().
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix switchKRLight() to use portable deterministic hash
Replace static RNG with FNV-1a hash of peptide sequence for selecting
replacement amino acids. This ensures:
- Same peptide always gets the same replacement AA (reproducible)
- Results are independent of processing order (portable across platforms)
- Fixes ARM64 portability issue where hash table iteration order differs
Updated test expected outputs to reflect the new deterministic behavior.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Remove dead srand() calls in MRMDecoy
The srand(time(nullptr)) calls seeded C's rand() function, but
portable_random_shuffle() uses boost::mt19937_64 which is independent.
These calls had no effect on program behavior.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Light-path TSV: use empty fields for Adducts and UniprotId
For consistency with heavy-path output, leave Adducts and UniprotId
columns empty instead of "NA" when not set.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix OpenSwathAssayGenerator test_4 for cross-platform portability
PQP files (SQLite binary format) have platform-dependent internal
layout, causing byte-by-byte comparison to fail on macOS ARM64.
Changed test to use TSV roundtrip comparison with -sort flag for
portable testing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* [DOC] Improve AGENTS.md based on best practices research (#8560)
Restructure AGENTS.md following the AGENTS.md standard best practices:
- Add Critical Constraints section upfront (what NOT to do)
- Add Quick Commands section with copy-paste ready commands
- Add code examples for naming conventions and file structure
- Add testing pattern examples with actual code
- Add verification commands section
- Create concise change impact checklist table
- Consolidate external links to essential resources only
- Improve overall structure for agent consumption
Based on research from GitHub's analysis of 2,500+ repositories
and the official AGENTS.md specification.
Co-authored-by: Claude <noreply@anthropic.com>
* Remove outdated template files and update test creation documentation (#8548)
* Initial plan
* Remove outdated templates and update documentation references
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
* [DOC] Improve AGENTS.md based on best practices research (#8563)
* [DOC] Improve AGENTS.md based on best practices research
Enhance AGENTS.md following the AGENTS.md standard best practices while
preserving all original content:
Added:
- Critical Constraints section upfront (explicit "NEVER do" list)
- Quick Commands section with copy-paste ready bash commands
- Visual directory tree for repo layout
- Code examples for naming conventions, file structure, and tests
- Commit message example
- Debugging command examples
Preserved:
- All original build/install instructions
- All testing guidelines and details
- All coding conventions
- All pyOpenMS wrapping details
- All external documentation links
- All CI/packaging information
Based on research from GitHub's analysis of 2,500+ repositories
and the official AGENTS.md specification.
* [DOC] Add Doxygen style guide and OS-specific build gotchas to AGENTS.md
Expand AGENTS.md with detailed information researched from the codebase:
Doxygen Documentation Style:
- File header format with $Maintainer$ and $Authors$ markers
- Class documentation with @brief, @ingroup, @htmlinclude
- Method documentation with @param[in/out], @return, @throws
- Constructor/destructor grouping with @name and //@{
- Inline documentation with /// comments
- Common Doxygen tags reference table
Platform-Specific Build Gotchas:
- Windows: MSVC requirements, MinGW not supported, Release/Debug mixing
- macOS: AppleClang linker flag, Qt PrintSupport, code signing
- Linux: PIC flags, STL debug mode, headless GUI testing
- Qt6: version requirements, component dependencies, WebEngine
- Boost: Homebrew static linking issues and workarounds
- CMake: CMAKE_SIZEOF_VOID_P bug, Eigen3 version detection
Also added:
- Required and optional dependency lists
- CMake minimum version (3.21) and C++20 standard requirement
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Cleanup TOPP tests, clean gitignore (#8555)
* Fix some race conditions in topp tests
* remove files that shouldn''t be tracked
* start moving temporary topp files into separate directory
* second batch of topp tests fixed.
* third batch
* fourth pass
* ixed the hardcoded CSV output path to use the input file's directory instead of the test execution directory, and corrected all 8 instances of "ambigious" → "ambiguous" spelling
* re-add idripper idxmls
* re-organize .gitignore
* more .gitignore cleanup
* create proper temp files for tests
* gitignore cleanup
* remove dupes from merge
* address coderabbit comments
* Fix temp file location
* use QDir for constructing paths in OpenNuXL
* Remove overbroad test file exclusions from gitignore
* Address code comments.
* Document ProteomicsLFQ automatic median normalization behavior (#8438)
* Initial plan
* Document ProteomicsLFQ normalization behavior
- Add detailed normalization documentation to Doxygen header
- Clarify automatic median normalization for feature intensity quantification
- Document when normalization is disabled (MSstats/Triqler output)
- Explain relationship between consensus feature normalization and ProteinQuantification:consensus:normalize
- Add inline code comments for better code clarity
- Update PeptideAndProteinQuant parameter description
- Provide workaround for using alternative normalization methods
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Fix hyphenation in documentation
Use proper compound adjective form "feature-intensity-based" instead of "feature intensity-based"
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Apply suggestions from code review
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
* Enhance DataValue conversion error messages with type and value context (#8572)
* Initial plan
* Improve DataValue error messages to include type and value information
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Add tests to verify improved DataValue error messages
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Document wrapping classes with deleted/private constructors in pyOpenMS (#8561)
* Initial plan
* Document how to wrap classes with deleted/private constructors in pyOpenMS
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Fix spacing in wrap-ignore comment for consistency
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Add namespace context to XMLHandler example for accuracy
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Add clarifying notes about singleton getInstance() overloads
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
* Improve documentation for wrap-manual-memory and fix Pattern 4 example
- Add wrap-manual-memory directive to "Hints to autowrap" section
- Document autowrap naming convention for wrap-ignore'd functions
- Fix misleading wrap-manual-dealloc reference (not a real directive)
- Update Pattern 4 example to match actual ConsensusIDAlgorithm.pxd
- Use PeptideIdentificationList instead of outdated libcpp_vector type
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Add precursor m/z range filter option to PeakFileOptions
Adds setPrecursorMZRange(), hasPrecursorMZRange(), and getPrecursorMZRange()
methods to filter spectra based on their precursor m/z values. Updates
hasFilters() to include this new filter type.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Timo Sachsenberg <timo.sachsenberg@uni-tuebingen.de>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
Co-authored-by: Samuel Wein <sam@samwein.com>
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Justin Sing <32938975+singjc@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Fix corrupted byte offsets in MzMLFile_4_indexed.mzML test file
The indexed mzML test file had incorrect byte offsets in the index section,
causing parse failures on ARM Linux and Mac platforms. Regenerated the file
with FileConverter to fix the spectrum offsets.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jpfeuffer <8102638+jpfeuffer@users.noreply.github.com>
Co-authored-by: Samuel Wein <sam@samwein.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Justin Sing <32938975+singjc@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Description
This pull request introduces memory-efficient ("Light") versions of several key methods in the OpenSWATH library to improve processing of large targeted experiments. The main focus is on enabling operations directly on the lightweight
LightTargetedExperimentstructure, reducing memory usage and improving scalability for large datasets. Additionally, support for reading and writing these light experiments in standard file formats (TSV, PQP) is added.Lightweight processing and I/O enhancements:
MRMAssayfor memory-efficient handling of large libraries:reannotateTransitionsLight,restrictTransitionsLight, anddetectingTransitionsLightnow operate directly onOpenSwath::LightTargetedExperimentobjects. [1] [2]generateDecoysLightinMRMDecoy, enabling memory-efficient decoy generation for large experiments using the light structure.LightTargetedExperimentstructures to TSV and PQP file formats:convertLightTargetedExperimentToTSVandconvertLightTargetedExperimentToPQP. [1] [2]Dependency updates:
TransitionExperiment.hin relevant files to support the new light experiment structures and methods. [1] [2]Checklist
How can I get additional information on failed tests during CI
Click to expand
If your PR is failing you can check outIf you click in the column that lists the failed tests you will get detailed error messages.
Advanced commands (admins / reviewer only)
Click to expand
/reformat(experimental) applies the clang-format style changes as additional commit. Note: your branch must have a different name (e.g., yourrepo:feature/XYZ) than the receiving branch (e.g., OpenMS:develop). Otherwise, reformat fails to push.rebuild jenkinswill retrigger Jenkins-based CI buildsSummary by CodeRabbit
New Features
Data / I/O
Options
API / Bindings
Tests
Tools
✏️ Tip: You can customize this high-level summary in your review settings.