Skip to content

WIP: UBT straws#1169

Open
mesmith75 wants to merge 85 commits into
ShipSoft:masterfrom
mesmith75:ubt_straws
Open

WIP: UBT straws#1169
mesmith75 wants to merge 85 commits into
ShipSoft:masterfrom
mesmith75:ubt_straws

Conversation

@mesmith75

@mesmith75 mesmith75 commented May 1, 2026

Copy link
Copy Markdown
Contributor

Checklist

Summary by CodeRabbit

Release Notes

  • New Features

    • UpstreamTagger now supports parametric geometry setup via new configuration setters (aperture, straw/wire parameters, stereo/layer offsets, frame material), plus a new YAML configuration file for streamlined detector setup.
    • Added a lightweight geometry “z-position” helper module and expanded configuration utilities for placing the UpstreamTagger within the overall detector.
  • Bug Fixes

    • Improved hit information by accumulating energy loss consistently and deriving the sub-detector ID for created hits.
  • Chores

    • Added new wire and gas mixture materials; adjusted simulation logging/verbosity and error-suppression behavior during runs.

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@mesmith75, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 53 minutes and 29 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 027e2ea9-df42-4e30-b401-2598d89c3c4d

📥 Commits

Reviewing files that changed from the base of the PR and between 845c154 and b140986.

📒 Files selected for processing (3)
  • UpstreamTagger/UpstreamTaggerHit.cxx
  • python/geometry_config.py
  • python/shipDet_conf.py
📝 Walkthrough

Walkthrough

This PR replaces the UpstreamTagger detector's fixed-box geometry with a full parametric straw detector implementation. The detector now reads configuration from YAML, accumulates energy loss across multiple steps in ProcessHits, derives subdetector IDs from volume names via compile-time hashing, and constructs a detailed multi-layer stereo straw geometry with configurable aperture, pitch, angles, and materials.

Changes

UpstreamTagger Parametric Straw Detector Implementation

Layer / File(s) Summary
Header API contracts
UpstreamTagger/UpstreamTagger.h, UpstreamTagger/UpstreamTaggerHit.h
UpstreamTagger adds constructor UpstreamTagger(std::string medium), nine setter methods for geometry parameters (z-position, aperture, straw diameter/pitch, layer/view z-offsets, stereo angle, wire thickness, frame material), and static utilities StrawDecode() and StrawEndPoints(). Replaces fixed box dimensions with detailed parameters (f_aperture_width/height, f_station_length, f_straw_pitch, f_view_angle, f_offset_layer, f_inner/outer_straw_diameter, f_wire_thickness, f_delta_z_layer, f_delta_z_view, f_frame_material, fMedium). UpstreamTaggerHit adds private member fSubDetID for layer identification.
Materials and geometry definitions
geometry/media.geo, geometry/ubt_config.yaml
New materials: WReWire (tungsten–rhenium 75/25 wire) and UBTMixture (argon–ethane 50/50 gas). YAML configuration defines aperture width/height, straw outer diameter, wall thickness, straw pitch, layer y-offset, stereo view z-offsets, view angle, and station length in cm.
Python geometry scaffold
python/ShipGeo.py, python/geometry_config.py
ShipGeo class stores detector z-positions with zPositions() helper for inspection. Defines TrackStation1-4 and UBTStation1-4 at specified z-coordinates. Computes magnetic field region, decay volume, muon shield (passive/active design selectable), hadron absorber, target, and tracking straw geometries with derived lengths and z-offsets. geometry_config.py sets UBTStation1.z at decayVolume.z0 - 50 cm and reduces UpstreamTagger BoxZ to 2.0 cm.
Core detector implementation
UpstreamTagger/UpstreamTagger.cxx
Adds compile-time hashing (hash template, operator"" _hash) and detPieces() function to map volume-name strings to detector piece IDs. New constructor UpstreamTagger(std::string medium) initializes fMedium. Nine setter methods populate geometry parameters. ProcessHits() accumulates energy loss via fELoss += gMC->Edep() and derives subDetID from current volume name using detPieces(volName). Replaces ConstructGeometry() with full parametric build: initializes TGeoMedium objects (air, mylar, UBTMixture, WReWire, frame material, detector medium), constructs station frames and composite geometry, creates stereo views with computed pitch/offset/growth, instantiates gas-sensitive volumes alongside straw and wire layers, places all volumes with nested loops using computed translations and rotations.
Hit processing
UpstreamTagger/UpstreamTaggerHit.cxx
Adds commented-out code path to assign fSubDetID = p->GetLayerID() from hit point data, establishing infrastructure for future layer-ID tracking in smeared hits.
Detector configuration and orchestration
python/shipDet_conf.py
New configure_upstreamTagger(yaml_file, ship_geo) function reads UBT configuration from YAML into ship_geo.ubt_geo, sets medium from ship_geo.DecayVolumeMedium, constructs ROOT.UpstreamTagger(medium), calls all nine setter methods with parameters from config and UBTStation1.z, and appends to detectorList. In configure(run, ship_geo), replaces inlined detector setup with call to configure_upstreamTagger(). Updates exclusion list to skip "TargetStation".
Diagnostics and logging
macro/run_simScript.py
Configures FairLogger file severity to "fatal" and verbosity to "verylow". Adds console output about to run: N before run.Run() and all sorted after completion. Sets ROOT.gErrorIgnoreLevel = ROOT.kFatal before geometry overlap checking to suppress non-fatal ROOT warnings.

Sequence Diagram(s)

sequenceDiagram
  participant SimSetup as Sim Setup
  participant ShipGeo as ShipGeo Module
  participant GeometryConfig as geometry_config.py
  participant ShipDetConf as shipDet_conf.py
  participant UpstreamTagger as ROOT.UpstreamTagger
  participant MC as MC Engine
  
  SimSetup->>ShipGeo: Define z-positions
  ShipGeo-->>SimSetup: TrackStation, UBTStation1-4
  SimSetup->>GeometryConfig: Create config with z-positions
  GeometryConfig-->>SimSetup: c.UpstreamTagger, c.UBTStation1
  SimSetup->>ShipDetConf: configure(run, ship_geo)
  ShipDetConf->>ShipDetConf: configure_upstreamTagger(yaml, ship_geo)
  ShipDetConf->>UpstreamTagger: UpstreamTagger(medium)
  UpstreamTagger->>UpstreamTagger: Initialize fMedium
  ShipDetConf->>UpstreamTagger: SetzPositions(UBTStation1.z)
  ShipDetConf->>UpstreamTagger: SetApertureArea(w, h, l)
  ShipDetConf->>UpstreamTagger: SetStrawDiameter(outer, wall)
  ShipDetConf->>UpstreamTagger: SetStrawPitch(pitch, offset)
  ShipDetConf->>UpstreamTagger: SetDeltazLayer(delta_z)
  ShipDetConf->>UpstreamTagger: SetDeltazView(delta_z_view)
  ShipDetConf->>UpstreamTagger: SetStereoAngle(angle)
  ShipDetConf->>UpstreamTagger: SetWireThickness(thickness)
  ShipDetConf->>UpstreamTagger: SetFrameMaterial(material)
  UpstreamTagger->>UpstreamTagger: ConstructGeometry()
  UpstreamTagger-->>ShipDetConf: Detector ready
  MC->>UpstreamTagger: ProcessHits(vol) for each step
  UpstreamTagger->>UpstreamTagger: fELoss += gMC->Edep()
  UpstreamTagger->>UpstreamTagger: volName = gMC->CurrentVolName()
  UpstreamTagger->>UpstreamTagger: subDetID = detPieces(volName)
  UpstreamTagger-->>MC: Hit created with subDetID
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • matclim
  • wcmartylee
🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description contains only the uncompleted checklist template with no substantive explanation of the changes, objectives, or rationale for the implementation. Add detailed description of the changes: explain the refactored geometry system, new constructor signature, public setter methods, material definitions added, and the purpose of these modifications.
Docstring Coverage ⚠️ Warning Docstring coverage is 18.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'WIP: UBT straws' is vague and generic, lacking meaningful detail about the substantial changes made to the UpstreamTagger detector geometry, constructor, and public API. Replace with a more descriptive title that summarizes the main changes, such as 'Refactor UpstreamTagger geometry with parametric straw configuration and new public API.'
✅ Passed checks (2 passed)
Check name Status Explanation
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 unit tests (beta)
  • Create PR with unit tests

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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.

@mesmith75 mesmith75 changed the title WIP: Ubt straws WIP: UBT straws May 1, 2026
@olantwin

olantwin commented May 4, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 4, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

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: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
UpstreamTagger/UpstreamTagger.cxx (1)

117-140: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

subDetID is computed and then discarded.

Line 119 derives the Y/U/V/plastic ID, but AddHit() still only receives uniqueId. As a result, the new UpstreamTaggerHit::fSubDetID path never gets populated, so downstream code cannot distinguish which UBT subdetector produced the hit.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@UpstreamTagger/UpstreamTagger.cxx` around lines 117 - 140, The code computes
subDetID via detPieces(volName) but never uses it, so
UpstreamTaggerHit::fSubDetID remains unset; modify the hit-creation path to pass
subDetID into the hit (either extend AddHit to accept a subDetID parameter or
set the hit's fSubDetID after creation), updating the call site in
UpstreamTagger.cxx where AddHit(fEventID, fTrackID, uniqueId, ...) is invoked
and any related constructors/factories that produce UpstreamTaggerHit so the
hit's fSubDetID is populated with the computed subDetID.
🧹 Nitpick comments (1)
python/geometry_config.py (1)

425-431: ⚡ Quick win

Remove the checked-in merge markers.

These commented <<<<<<<, =======, >>>>>>> lines make the selected UBT geometry harder to trust during later edits.

Cleanup
-    # <<<<<<< HEAD
     c.UpstreamTagger.BoxZ = 2.0 * u.cm  # Z dimension (thickness)
     c.UpstreamTagger.Z_Position = -25.400 * u.m + c.decayVolume.z  # Relative position of UBT to decay vessel centre
-    # =======
-    #    c.UpstreamTagger.BoxZ = 16.0 * u.cm  # Z dimension (thickness)
-    #    c.UpstreamTagger.Z_Position = -25.400 * u.m + c.decayVolume.z  # Relative position of UBT to decay vessel centre
-    # >>>>>>> mymaster
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@python/geometry_config.py` around lines 425 - 431, Remove the leftover merge
conflict markers and the alternate commented block so the UpstreamTagger
settings are unambiguous: delete the lines containing "<<<<<<<", "=======",
">>>>>>>" and the commented-out alternative BoxZ/Z_Position entries, leaving
only the intended assignments for c.UpstreamTagger.BoxZ and
c.UpstreamTagger.Z_Position (e.g., BoxZ = 2.0 * u.cm and Z_Position = -25.400 *
u.m + c.decayVolume.z).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@geometry/media.geo`:
- Around line 2205-2208: The material definition for WReWire claims
"Tunsten-Rhenium 75/25" but uses fractions 0.97 0.03; update the definition so
the actual composition matches the label (or vice versa). Locate the WReWire
block and either change the composition numbers from "0.97 0.03" to "0.75 0.25"
to reflect 75% W / 25% Re, or change the comment/label to the correct ratio that
matches the existing fractions; ensure any dependent documentation or variable
names that reference WReWire remain consistent.

In `@geometry/ubt_config.yaml`:
- Around line 2-13: The UBT config is missing the frame_material key required by
UpstreamTagger::ConstructGeometry() which calls
ShipGeo::InitMedium(f_frame_material); add a "frame_material" entry inside the
UBT block (e.g., frame_material: <validMediumName>) so f_frame_material is
non-empty and matches an existing medium name known to ShipGeo::InitMedium;
ensure the value exactly matches the material identifier used elsewhere in the
project.

In `@macro/run_simScript.py`:
- Around line 349-350: The file log severity is currently forced to fatal via
ROOT.gInterpreter.ProcessLine('fair::Logger::SetFileSeverity("fatal");'), which
hides non-fatal diagnostics needed for postmortem; change the code to set
fair::Logger::SetFileSeverity("debug") (or a less restrictive level) when
running in debug mode (e.g., when --debug is enabled) and keep the more
restrictive level otherwise, and ensure this conditional mirrors any
console-only verbosity settings like fair::Logger::SetVerbosity so file and
console logging reflect the chosen debug flag.
- Around line 758-761: ROOT.gErrorIgnoreLevel is being changed globally before
the overlap check and never restored; scope the suppression to only the
overlap-checking block by saving the current level, setting
ROOT.gErrorIgnoreLevel = ROOT.kFatal only while options.check_overlaps and the
overlap code (the block under the if options.check_overlaps) runs, then restore
the saved value immediately after that block so subsequent operations (file
filtering, muon discrimination, tree/event processing) use the original error
level.

In `@python/shipDet_conf.py`:
- Around line 464-472: Remove the leftover merge-conflict markers and
commented-out alternate implementation in the upstream tagger block: delete the
conflict markers (<<<<<<< HEAD, =======, >>>>>>> mymaster) and the redundant
commented lines referencing upstreamTagger, UpstreamTagger.SetZposition, and
SetBoxDimensions, leaving the single intended call
configure_upstreamTagger(os.path.join(os.environ["FAIRSHIP"], "geometry",
"ubt_config.yaml"), ship_geo) intact so only the active configure_upstreamTagger
usage remains.
- Line 502: The file currently sets exclusionList = ["TargetStation"] which
forces skipping TargetStation during run.AddModule(...) and can alter
physics/geometry; change this so TargetStation is not unconditionally
excluded—either initialize exclusionList to an empty list or make adding
"TargetStation" conditional (e.g., based on a config flag or environment
variable) and update any code paths that reference exclusionList and
run.AddModule to respect that conditional logic (look for the exclusionList
variable and the run.AddModule(...) call sites to apply the change).

In `@python/ShipGeo.py`:
- Around line 15-20: zPositions() is broken: it references sys without import,
treats ShipGeo as iterable and uses eval for attribute access; fix by importing
sys at top, retrieving the main module via sys.modules["__main__"], locating the
ShipGeo class/object on that module (e.g., getattr(main, "ShipGeo")), iterating
its attributes via dir() or vars(ShipGeo).items(), and replacing
eval("ShipGeo."+x+".z") with safe attribute access using
getattr(getattr(ShipGeo, x) or attribute object, "z", None) (use hasattr/getattr
checks) so you only print entries that actually have a numeric z attribute in
the ShipGeo namespace.

In `@UpstreamTagger/UpstreamTagger.cxx`:
- Around line 288-291: The geometry placement currently ignores the stored
det_zPos/SetZposition and uses T_station_z directly; change the node creation in
the UpstreamTagger constructor (where TGeoVolume* vol is created and
top->AddNode is called) to use the detector's stored Z position (det_zPos or the
value set by SetZposition, and/or the config value c.UpstreamTagger.Z_Position
from python/geometry_config.py) instead of the raw T_station_z; ensure any code
that updates SetZposition also updates the translation used for AddNode (or
recompute T_station_z from det_zPos before adding the node) so callers that only
set det_zPos get the correct placement.

---

Outside diff comments:
In `@UpstreamTagger/UpstreamTagger.cxx`:
- Around line 117-140: The code computes subDetID via detPieces(volName) but
never uses it, so UpstreamTaggerHit::fSubDetID remains unset; modify the
hit-creation path to pass subDetID into the hit (either extend AddHit to accept
a subDetID parameter or set the hit's fSubDetID after creation), updating the
call site in UpstreamTagger.cxx where AddHit(fEventID, fTrackID, uniqueId, ...)
is invoked and any related constructors/factories that produce UpstreamTaggerHit
so the hit's fSubDetID is populated with the computed subDetID.

---

Nitpick comments:
In `@python/geometry_config.py`:
- Around line 425-431: Remove the leftover merge conflict markers and the
alternate commented block so the UpstreamTagger settings are unambiguous: delete
the lines containing "<<<<<<<", "=======", ">>>>>>>" and the commented-out
alternative BoxZ/Z_Position entries, leaving only the intended assignments for
c.UpstreamTagger.BoxZ and c.UpstreamTagger.Z_Position (e.g., BoxZ = 2.0 * u.cm
and Z_Position = -25.400 * u.m + c.decayVolume.z).
🪄 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: c7a8b28a-3c79-4435-a6e3-6471dd9ff1c2

📥 Commits

Reviewing files that changed from the base of the PR and between f8d3703 and c0032aa.

📒 Files selected for processing (10)
  • UpstreamTagger/UpstreamTagger.cxx
  • UpstreamTagger/UpstreamTagger.h
  • UpstreamTagger/UpstreamTaggerHit.cxx
  • UpstreamTagger/UpstreamTaggerHit.h
  • geometry/media.geo
  • geometry/ubt_config.yaml
  • macro/run_simScript.py
  • python/ShipGeo.py
  • python/geometry_config.py
  • python/shipDet_conf.py

Comment thread geometry/media.geo
Comment on lines +2205 to +2208
// Tunsten-Rhenium 75/25 wire
WReWire 2 183.84 186.207 74. 75. 19.3 0.97 0.03
0 1 20. 0.001
0

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 | 🟠 Major | ⚡ Quick win

WReWire does not match its stated composition.

The comment says this is a 75/25 tungsten-rhenium wire, but the mixture is defined with 0.97 0.03 fractions. That is a very different material budget, so either the label or the numbers need to be corrected before this is used in simulation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@geometry/media.geo` around lines 2205 - 2208, The material definition for
WReWire claims "Tunsten-Rhenium 75/25" but uses fractions 0.97 0.03; update the
definition so the actual composition matches the label (or vice versa). Locate
the WReWire block and either change the composition numbers from "0.97 0.03" to
"0.75 0.25" to reflect 75% W / 25% Re, or change the comment/label to the
correct ratio that matches the existing fractions; ensure any dependent
documentation or variable names that reference WReWire remain consistent.

Comment thread geometry/ubt_config.yaml
Comment on lines +2 to +13
UBT:
width: 50 # Aperture width (x) in cm (half length)
height: 150 # Aperture height (y) in cm (half length)
wire_thickness: 0.0025 # Sense wire thickness in cm
wall_thickness: 0.0015 # Straw wall thickness in cm
outer_straw_diameter: 0.5 # in cm
straw_pitch: 0.6 # Distance (y) between straws in a layer in cm
y_layer_offset: 0.25 # Offset (y) of straws between layers in cm
delta_z_layer: 0.433 # Distance (z = sqrt(3)/2 * D) between layers in cm
delta_z_view: 6 # Distance (z) between stereo views in cm
view_angle: 15 # Stereo angle in degree
station_length: 32 # (z = outer_straw_diameter + delta_z_layer + delta_z_view + space for plastic) in cm (half length)

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 | 🟠 Major | ⚡ Quick win

This config is missing the frame material required by ConstructGeometry().

UpstreamTagger::ConstructGeometry() unconditionally calls ShipGeo::InitMedium(f_frame_material) and builds the frame with that medium. Without a frame_material entry here, the medium name stays empty and the new geometry path is reachable failure in this PR.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@geometry/ubt_config.yaml` around lines 2 - 13, The UBT config is missing the
frame_material key required by UpstreamTagger::ConstructGeometry() which calls
ShipGeo::InitMedium(f_frame_material); add a "frame_material" entry inside the
UBT block (e.g., frame_material: <validMediumName>) so f_frame_material is
non-empty and matches an existing medium name known to ShipGeo::InitMedium;
ensure the value exactly matches the material identifier used elsewhere in the
project.

Comment thread macro/run_simScript.py Outdated
Comment on lines +349 to +350
ROOT.gInterpreter.ProcessLine('fair::Logger::SetFileSeverity("fatal");')
ROOT.gInterpreter.ProcessLine('fair::Logger::SetVerbosity("verylow");')

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 | 🟠 Major

🧩 Analysis chain

🌐 Web query:

`In the current FairRoot/FairLogger version used by this project, what is the exact behavior of:

  • fair::Logger::SetFileSeverity(...)
  • fair::Logger::SetConsoleSeverity(...)
  • fair::Logger::SetVerbosity(...)
    Does SetFileSeverity("fatal") suppress all non-fatal messages written to file even when console severity is set to debug/debug1/debug2?`

💡 Result:

In the current FairRoot/FairLogger (FairLogger v2.3.2 as of 2026-03-17), fair::Logger::SetFileSeverity(severity) sets the minimum severity threshold for the file sink independently of other sinks. Similarly, fair::Logger::SetConsoleSeverity(severity) sets the threshold for the console sink. fair::Logger::SetVerbosity(verbosity) sets the verbosity level, which controls the detail/format of output (e.g., high/medium/low, affecting timestamps, file/line info) but does not alter severity thresholds. SetFileSeverity("fatal") sets the file sink to only log FATAL messages and higher (typically the highest severity; lower severities like debug/info are suppressed for file output). This suppression is independent of console settings. Thus, even if console severity is "debug" (or debug1/debug2 equivalents), non-fatal messages (e.g., debug, info) will not be written to the file—only fatal ones will. "fatal" logs the chosen severity and above; lower severities are filtered per sink. FairLogger wrapper (FairRoot's FairLogger.h) calls these methods and uses IsLogNeeded(fair::Severity) to check before logging, respecting per-sink thresholds.

Citations:


File logging suppresses non-fatal messages needed for crash triage.

Line 349 sets file severity to fatal, which suppresses all non-fatal messages (debug, info, warning) in file output according to FairLogger's independent per-sink severity behavior. This means even when --debug is passed (which only affects console output), the file log remains silent except for fatal events—losing context needed to debug failures like the CI Geant4 abort.

Adjust the file severity based on debug mode (e.g., SetFileSeverity("debug") when debug is enabled) to preserve non-fatal diagnostics for postmortem analysis.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@macro/run_simScript.py` around lines 349 - 350, The file log severity is
currently forced to fatal via
ROOT.gInterpreter.ProcessLine('fair::Logger::SetFileSeverity("fatal");'), which
hides non-fatal diagnostics needed for postmortem; change the code to set
fair::Logger::SetFileSeverity("debug") (or a less restrictive level) when
running in debug mode (e.g., when --debug is enabled) and keep the more
restrictive level otherwise, and ensure this conditional mirrors any
console-only verbosity settings like fair::Logger::SetVerbosity so file and
console logging reflect the chosen debug flag.

Comment thread macro/run_simScript.py Outdated
Comment thread python/shipDet_conf.py Outdated
Comment thread python/shipDet_conf.py Outdated
Comment thread python/ShipGeo.py
Comment on lines +15 to +20
def zPositions():
main = sys.modules["__main__"]
if hasattr(main, "ShipGeo"):
for x in ShipGeo:
if hasattr(eval("ShipGeo." + x), "z"):
print(x, "z=", eval("ShipGeo." + x + ".z"))

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 | 🟠 Major | ⚡ Quick win

zPositions() is currently broken.

It uses sys without importing it, iterates over ShipGeo even though the class is not iterable, and relies on eval() for plain attribute access.

Proposed fix
+import sys
+
 def zPositions():
     main = sys.modules["__main__"]
-    if hasattr(main, "ShipGeo"):
-        for x in ShipGeo:
-            if hasattr(eval("ShipGeo." + x), "z"):
-                print(x, "z=", eval("ShipGeo." + x + ".z"))
+    for name, value in vars(main).items():
+        if isinstance(value, ShipGeo) and hasattr(value, "z"):
+            print(name, "z=", value.z)
🧰 Tools
🪛 GitHub Check: static-analysis

[failure] 18-18: Pyrefly not-iterable
Type type[ShipGeo] is not iterable


[failure] 16-16: Pyrefly unknown-name
Could not find name sys

🪛 Ruff (0.15.12)

[error] 16-16: Undefined name sys

(F821)


[error] 19-19: Use of possibly insecure function; consider using ast.literal_eval

(S307)


[error] 20-20: Use of possibly insecure function; consider using ast.literal_eval

(S307)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@python/ShipGeo.py` around lines 15 - 20, zPositions() is broken: it
references sys without import, treats ShipGeo as iterable and uses eval for
attribute access; fix by importing sys at top, retrieving the main module via
sys.modules["__main__"], locating the ShipGeo class/object on that module (e.g.,
getattr(main, "ShipGeo")), iterating its attributes via dir() or
vars(ShipGeo).items(), and replacing eval("ShipGeo."+x+".z") with safe attribute
access using getattr(getattr(ShipGeo, x) or attribute object, "z", None) (use
hasattr/getattr checks) so you only print entries that actually have a numeric z
attribute in the ShipGeo namespace.

Comment on lines +288 to +291
TGeoVolume* vol = new TGeoVolume(nmstation, statbox, med);
// z-translate the station to its (absolute) position
top->AddNode(vol, statnb,
new TGeoTranslation(0, floor_offset / 2., T_station_z));

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 | 🟠 Major | ⚡ Quick win

SetZposition() no longer affects the built geometry.

The public API still stores det_zPos, and python/geometry_config.py still defines c.UpstreamTagger.Z_Position, but this placement uses T_station_z directly. Any caller that only sets the detector Z will now get a silently misplaced UBT.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@UpstreamTagger/UpstreamTagger.cxx` around lines 288 - 291, The geometry
placement currently ignores the stored det_zPos/SetZposition and uses
T_station_z directly; change the node creation in the UpstreamTagger constructor
(where TGeoVolume* vol is created and top->AddNode is called) to use the
detector's stored Z position (det_zPos or the value set by SetZposition, and/or
the config value c.UpstreamTagger.Z_Position from python/geometry_config.py)
instead of the raw T_station_z; ensure any code that updates SetZposition also
updates the translation used for AddNode (or recompute T_station_z from det_zPos
before adding the node) so callers that only set det_zPos get the correct
placement.

@olantwin olantwin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some first comments, I'll review further later.

Comment thread macro/run_simScript.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we discuss changing the default log level and verbosity separately?

Comment thread python/geometry_config.py Outdated
Comment on lines +425 to +431
# <<<<<<< HEAD
c.UpstreamTagger.BoxZ = 2.0 * u.cm # Z dimension (thickness)
c.UpstreamTagger.Z_Position = -25.400 * u.m + c.decayVolume.z # Relative position of UBT to decay vessel centre
# =======
# c.UpstreamTagger.BoxZ = 16.0 * u.cm # Z dimension (thickness)
# c.UpstreamTagger.Z_Position = -25.400 * u.m + c.decayVolume.z # Relative position of UBT to decay vessel centre
# >>>>>>> mymaster

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There's an unresolved merge conflict here.

Comment thread python/shipDet_conf.py Outdated
Comment on lines +464 to +472
# <<<<<<< HEAD
configure_upstreamTagger(os.path.join(os.environ["FAIRSHIP"], "geometry", "ubt_config.yaml"), ship_geo)
# =======
# upstreamTagger = ROOT.UpstreamTagger("UpstreamTagger", ROOT.kTRUE)
# upstreamTagger.SetZposition(ship_geo.UpstreamTagger.Z_Position)
# upstreamTagger.SetBoxDimensions(
# ship_geo.UpstreamTagger.BoxX, ship_geo.UpstreamTagger.BoxY, ship_geo.UpstreamTagger.BoxZ
# >>>>>>> mymaster
# )

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Another unresolved merge conflict

Comment thread python/shipDet_conf.py Outdated
run.SetField(fMagField)

exclusionList = []
exclusionList = ["TargetStation"]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should not be excluded by default.

@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.

🧹 Nitpick comments (1)
python/shipDet_conf.py (1)

268-268: 💤 Low value

Add type hints for consistency with peer functions.

Other configure_* functions in this file have type annotations. Consider adding them here for consistency:

-def configure_upstreamTagger(yaml_file, ship_geo):
+def configure_upstreamTagger(yaml_file: str, ship_geo) -> None:
🤖 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 `@python/shipDet_conf.py` at line 268, Add type hints to the
configure_upstreamTagger function signature to match the pattern used by other
configure_* functions in the file. Add type annotations for the yaml_file
parameter and the ship_geo parameter, as well as specify the return type of the
function. Review the existing configure_* functions in the same file to
determine the appropriate types to use for consistency.
🤖 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.

Nitpick comments:
In `@python/shipDet_conf.py`:
- Line 268: Add type hints to the configure_upstreamTagger function signature to
match the pattern used by other configure_* functions in the file. Add type
annotations for the yaml_file parameter and the ship_geo parameter, as well as
specify the return type of the function. Review the existing configure_*
functions in the same file to determine the appropriate types to use for
consistency.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6feea647-0cb6-48b5-93cd-df61f02931ff

📥 Commits

Reviewing files that changed from the base of the PR and between c0032aa and 845c154.

📒 Files selected for processing (4)
  • UpstreamTagger/UpstreamTagger.h
  • macro/run_simScript.py
  • python/geometry_config.py
  • python/shipDet_conf.py
💤 Files with no reviewable changes (1)
  • UpstreamTagger/UpstreamTagger.h
🚧 Files skipped from review as they are similar to previous changes (2)
  • python/geometry_config.py
  • macro/run_simScript.py

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.

3 participants