Skip to content

fix(Pythia6Generator): replace fscanf parsing with istringstream#1260

Open
olantwin wants to merge 1 commit into
masterfrom
fix/pythia6-fscanf
Open

fix(Pythia6Generator): replace fscanf parsing with istringstream#1260
olantwin wants to merge 1 commit into
masterfrom
fix/pythia6-fscanf

Conversation

@olantwin

@olantwin olantwin commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Summary

clang-tidy's bugprone-unchecked-string-to-number-conversion flagged both fscanf calls in Pythia6Generator::ReadEvent (the remaining 2 sites from that category after PR #1244 swept atoi/atof). fscanf silently produces zeros when an input field doesn't match the format — the value just stays at its prior contents — instead of surfacing the parse error to the caller.

Change

Rewrite with fgets + std::istringstream. Each line is read into a buffer, then >> extracts the typed fields one at a time. If any extraction fails, log the offending line and abort the event, matching the std::stoi/std::stod error model PR #1244 adopted.

Both the header line (eventID, ntracks) and the per-track line (15 fields) get explicit fail checks. End-of-file detection now naturally drops out of fgets returning nullptr.

Test plan

  • pixi run --locked build — clean (133/133, 0 warnings)
  • pixi run --locked test — 2/2 pass
  • CPP_FILES=shipgen/Pythia6Generator.cxx pixi run --locked ci-clang-tidy — 0 bugprone-unchecked-string-to-number-conversion findings
  • CI's ci-fixed-target job still passes (its Pythia6 input is well-formed, so behaviour is unchanged)

Risks

Malformed Pythia6 input lines that previously fell through with zero fields will now log an error and skip the event. If any existing input file relies on the zero-fallback, this will surface as a runtime failure with a clear message — preferred to silent corruption.

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced event and track input parsing with improved error detection and validation for malformed or incomplete data entries.

clang-tidy's bugprone-unchecked-string-to-number-conversion flagged
both fscanf calls in Pythia6Generator::ReadEvent — the format-string
based parser silently produces zeros when an input field doesn't
match, instead of surfacing the parse error to the caller.

Rewrite with fgets + std::istringstream. Each line is read into a
buffer, then >> extracts the typed fields one at a time. If any
extraction fails, log the offending line and abort the event, the
same way std::stoi/std::stod handle malformed input. The header
line and the per-track line both get explicit fail checks.

No functional change for well-formed input files; malformed input
that previously fell through with zero fields now fails closer to
the cause.
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Pythia6Generator::ReadEvent in shipgen/Pythia6Generator.cxx is rewritten to replace fscanf-based parsing with fgets + std::istringstream parsing. Explicit validation is added for EOF, malformed event headers, zero track counts, and malformed track lines, with error logging and early return via CloseInput()/kFALSE on failure.

Changes

Pythia6Generator ReadEvent Parsing Rewrite

Layer / File(s) Summary
fgets+istringstream parsing and validation
shipgen/Pythia6Generator.cxx
Adds <sstream> and <string> headers; removes ncols-based local variable; replaces all fscanf calls with fgets+std::istringstream parsing for both the event header and per-track lines; introduces explicit EOF detection and field-count validation with LOG(error) messages and early exit through CloseInput()/kFALSE. Verbose per-track printing and the nLev == 1 guard on primGen->AddTrack are preserved.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • matclim
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description comprehensively covers the issue, solution, test plan, and risks, but the required checklist items are not explicitly marked. Check the checkbox items in the description template (Changelog, Commit message, CI checks) and mark them as completed or explain why they're not applicable.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: replacing fscanf parsing with istringstream in Pythia6Generator.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pythia6-fscanf

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
Contributor

CI Plots

View all plots

fixed-target

pixi

PlaneHA20011 PlaneHA21011 PlaneHA22011 PlaneHA10011 PlaneHA11011 PlaneHA12011 PlaneHA20012 PlaneHA21012 PlaneHA22012 PlaneHA10012 PlaneHA11012 PlaneHA12012 PlaneHA20013 PlaneHA21013 PlaneHA22013 PlaneHA10013 PlaneHA11013 PlaneHA12013 PlaneHA20014 PlaneHA21014 PlaneHA22014 PlaneHA10014 PlaneHA11014 PlaneHA12014 PlaneHA20015 PlaneHA21015 PlaneHA22015 PlaneHA10015 PlaneHA11015 PlaneHA12015 PlaneHA20016 PlaneHA21016 PlaneHA22016 PlaneHA10016 PlaneHA11016 PlaneHA12016 PlaneHA20017 PlaneHA21017 PlaneHA22017 PlaneHA10017 PlaneHA11017 PlaneHA12017 PlaneHA10022 PlaneHA11022 PlaneHA12022 PlaneHA10111 PlaneHA11111 PlaneHA12111 PlaneHA10221 PlaneHA11221 PlaneHA12221 PlaneHA10223 PlaneHA11223 PlaneHA12223 PlaneHA10331 PlaneHA11331 PlaneHA12331

sim-chain

helium-all-TRY_2025

distu distv disty nmeas chi2 delPOverP pullPOverPx pullPOverPy pullPOverPz delPOverP2 delPOverPz delPOverP2z chi2 prob IP Vzresol Vxresol Vyresol Vzpull Vxpull Vypull Doca IP0 HNL IP0_pi0 HNL_pi0 HNLw meas meas2 measVSchi2 distu distv disty meanhits extrapTimeDetX extrapTimeDetY oa nrtracks nrSBT pi0Mass delPOverPz_py delPOverP2z_py pullPOverPx_py pullPOverPy_py pullPOverPz_py

vacuums-all-TRY_2025

distu distv disty nmeas chi2 delPOverP pullPOverPx pullPOverPy pullPOverPz delPOverP2 delPOverPz delPOverP2z chi2 prob IP Vzresol Vxresol Vyresol Vzpull Vxpull Vypull Doca IP0 HNL IP0_pi0 HNL_pi0 HNLw meas meas2 measVSchi2 distu distv disty meanhits extrapTimeDetX extrapTimeDetY oa nrtracks nrSBT pi0Mass delPOverPz_py delPOverP2z_py pullPOverPx_py pullPOverPy_py pullPOverPz_py

tracking-benchmark

pixi

h_dp_over_p h_dp_vs_p h_dx h_dy h_dtx h_dty h_hit_residual h_hit_pull h_chi2ndf h_p_truth h_p_matched

@olantwin

Copy link
Copy Markdown
Contributor Author

@coderabbitai rate limit

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Your plan includes 1 PR review per hour. More reviews will be available in 16 minutes and 41 seconds.

@olantwin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@shipgen/Pythia6Generator.cxx`:
- Around line 72-76: The error message in the header parsing block incorrectly
reports "End of input file reached" for both malformed input (extraction
failures) and invalid semantics (ntracks <= 0). Separate the combined condition
check into two distinct checks: first test whether the extraction of eventID and
ntracks succeeded, and if that fails, log an error message indicating malformed
header with the raw line content; separately check if ntracks <= 0 and log a
different error message for invalid track count. This approach aligns with how
track parsing errors are handled at lines 93-94 (which log "malformed track
line" with raw content), ensuring consistent error reporting and improving
debuggability.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5087b95d-ce4c-49b7-8ea6-928566e1ea3d

📥 Commits

Reviewing files that changed from the base of the PR and between 7be7505 and c714048.

📒 Files selected for processing (1)
  • shipgen/Pythia6Generator.cxx

Comment on lines +72 to +76
if (!(headerStream >> eventID >> ntracks) || ntracks <= 0) {
cout << "-I Pythia6Generator: End of input file reached " << endl;
CloseInput();
return kFALSE;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Misleading error message for malformed event headers.

Lines 66–67 already handle EOF when fgets returns nullptr. If we reach line 72, we have a buffer containing a line. The combined condition !(headerStream >> eventID >> ntracks) || ntracks <= 0 fails when:

  • Extraction fails (malformed input, e.g., non-numeric tokens), or
  • Extraction succeeds but ntracks ≤ 0 (semantically invalid).

In both cases, the message "End of input file reached" is incorrect—the actual problem is malformed or invalid input, not EOF. For comparison, track parsing errors (lines 93–94) log "malformed track line" and include the raw line content. The header error should follow the same pattern for consistency and to aid debugging.

📝 Proposed fix: separate parse/validation checks and log the malformed line
  std::istringstream headerStream(headerBuf);
- if (!(headerStream >> eventID >> ntracks) || ntracks <= 0) {
-   cout << "-I Pythia6Generator: End of input file reached " << endl;
+ if (!(headerStream >> eventID >> ntracks)) {
+   LOG(error) << "Pythia6Generator: malformed event header: " << headerBuf;
+   CloseInput();
+   return kFALSE;
+ }
+ if (ntracks <= 0) {
+   LOG(error) << "Pythia6Generator: invalid track count " << ntracks
+              << " in event " << eventID;
    CloseInput();
    return kFALSE;
  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shipgen/Pythia6Generator.cxx` around lines 72 - 76, The error message in the
header parsing block incorrectly reports "End of input file reached" for both
malformed input (extraction failures) and invalid semantics (ntracks <= 0).
Separate the combined condition check into two distinct checks: first test
whether the extraction of eventID and ntracks succeeded, and if that fails, log
an error message indicating malformed header with the raw line content;
separately check if ntracks <= 0 and log a different error message for invalid
track count. This approach aligns with how track parsing errors are handled at
lines 93-94 (which log "malformed track line" with raw content), ensuring
consistent error reporting and improving debuggability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant