Skip to content

feat(apps): build individual subsystems from build_geometry - #52

Open
matclim wants to merge 8 commits into
ShipSoft:mainfrom
matclim:self-registration
Open

feat(apps): build individual subsystems from build_geometry#52
matclim wants to merge 8 commits into
ShipSoft:mainfrom
matclim:self-registration

Conversation

@matclim

@matclim matclim commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

feat(apps): build individual subsystems from build_geometry

build_geometry now accepts a subsystem name and builds that subsystem on
its own (local frame), alongside the default full-detector build:

build_geometry # full detector -> ship_geometry.db
build_geometry Calorimeter # single subsystem -> Calorimeter.db
build_geometry --list # list subsystem names

A token ending in .db is treated as the output file; any other token names
a subsystem, as spelled by --list. The standalone build_subsystem
executable is removed and its behaviour folded into build_geometry.

Update the README build, factory-pattern, structure, and "adding a
subsystem" sections to match.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Added token-based build_geometry support to list subsystem names, build the full detector by default, or build a single named subsystem with configurable .db output.
    • Introduced a subsystem registry with automatic factory self-registration and deterministic assembly/placement.
  • Bug Fixes

    • Improved runtime validation for unknown subsystem requests and missing/invalid world volume, with clearer failure behavior.
  • Documentation

    • Updated the README to describe the new registry workflow, single-subsystem build path, and gmex viewing steps.
  • Chores

    • Adjusted build/link options to prevent self-registered subsystems from being dropped in common configurations.

It is now possible to build (and visualise, although the proper visualisation will be the subject of another PR) single or incomplete sets of detectors, for example the target and the Magnet:

image

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds registry-based subsystem assembly, self-registering factories, selectable full or subsystem geometry builds, linker retention for registration initializers, and updated README guidance.

Changes

Subsystem Registry Refactor

Layer / File(s) Summary
Subsystem registry contract
include/SHiPGeometry/SubsystemDescriptor.h, include/SHiPGeometry/SubsystemRegistry.h
Defines subsystem descriptors, registry records, factory callbacks, registration helpers, assembly APIs, and the REGISTER_SUBSYSTEM macro.
Registry-driven assembler implementation
src/SHiPGeometry.cpp
Builds the world and selected subsystems from registry metadata, orders placements by (z, id), exposes single-subsystem and listing APIs, and delegates full builds through SHiPGeometryBuilder::build().
Factory descriptors and self-registration
subsystems/*/include/*Factory.h, subsystems/*/src/*Factory.cpp
Adds descriptor metadata and registry registration to subsystem factories; TimingDetector construction now delegates geometry generation to Gmx2Geo.
build_geometry CLI rework
apps/build_geometry.cpp
Adds --list, subsystem selection, .db output handling, validation, error reporting, geometry traversal, and database persistence.
Linker wiring and documentation
src/CMakeLists.txt, README.md
Retains linked subsystem registration initializers and documents CLI usage, registry assembly, factory registration, and subsystem integration requirements.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested reviewers: olantwin

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.89% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: build_geometry now builds individual subsystems.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@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: 6

🧹 Nitpick comments (1)
include/SHiPGeometry/SubsystemRegistry.h (1)

54-57: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Fail fast on duplicate subsystem names.

emplace() silently ignores a second registration with the same desc.name, but still returns true; a duplicated descriptor would make one subsystem disappear from --list/assembly without any diagnostic.

Proposed fix
+#include <stdexcept>
+
 inline bool registerSubsystem(const SubsystemDescriptor& desc,
                               std::function<GeoVPhysVol*(SHiPMaterials&)> build) {
-    registry().emplace(desc.name, SubsystemInfo{desc, std::move(build)});
+    auto [_, inserted] =
+        registry().emplace(desc.name, SubsystemInfo{desc, std::move(build)});
+    if (!inserted) {
+        throw std::runtime_error("Duplicate subsystem registration: '" +
+                                 std::string(desc.name) + "'");
+    }
     return true;
 }
🤖 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 `@include/SHiPGeometry/SubsystemRegistry.h` around lines 54 - 57, The
registerSubsystem function currently returns success even when a duplicate
desc.name is registered, because registry().emplace() silently ignores the
second entry. Update registerSubsystem in SubsystemRegistry.h to detect an
existing name before or after emplace, and fail fast by rejecting the duplicate
instead of returning true. Use the registerSubsystem and registry() symbols to
locate the check, and make sure duplicate subsystem descriptors cannot be added
without a clear diagnostic.
🤖 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 `@apps/build_geometry.cpp`:
- Around line 83-85: The output-file cleanup in build_geometry.cpp uses the
throwing std::filesystem::remove overload after a redundant exists() check,
which can crash on permission or lock failures. Update the logic around the
outputFile deletion to call the non-throwing remove variant and handle its
result (and any error_code) in build_geometry so missing files are treated as a
no-op while real filesystem errors are reported cleanly.
- Around line 55-76: The default full-build path in build_geometry.cpp lacks the
same exception handling used for SHiPGeometry::buildSubsystem, so
builder.build() can terminate on a thrown std::runtime_error. Wrap the
names.empty() branch in the same try/catch pattern used for the single-subsystem
path, catch std::exception, print a clear error plus available subsystems if
helpful, and return 1 so buildGeometry fails gracefully instead of aborting.

In `@include/SHiPGeometry/SubsystemRegistry.h`:
- Around line 8-11: The header is not self-contained because
`SubsystemRegistry.h` uses `std::move` without including the declaration it
comes from. Add the missing `<utility>` include alongside the existing includes
in `SubsystemRegistry.h` so any translation unit using `SubsystemRegistry`
compiles independently.

In `@README.md`:
- Line 170: The fenced code block in the README is missing a language
identifier, which triggers markdownlint MD040. Update that markdown fence to
include a language specifier, using the fenced block in the README around the
geometry/ snippet as the target so the block is properly annotated.

In `@src/SHiPGeometry.cpp`:
- Around line 50-59: The world assembly path currently assumes
entry.second.build(materials) always returns a valid geometry, but a factory may
return null and lead to a bad cast or later GeoModel failure. In the world
selection logic in SHiPGeometry::buildSubsystem, check the build result before
dynamic_cast<GeoPhysVol*> and throw a clear error if it is null; apply the same
validation anywhere build results are passed into place() so null subsystem
geometries are rejected at the assembly boundary instead of propagating deeper.

In `@subsystems/UpstreamTagger/src/UpstreamTaggerFactory.cpp`:
- Line 5: The UpstreamTagger registration path is losing the SHiPUBTManager
pointer, so build() never receives a valid manager and setContainerVolume() is
skipped. Update the REGISTER_SUBSYSTEM wiring in UpstreamTaggerFactory so the
registry callback preserves and forwards the SHiPUBTManager* (or otherwise
retrieves it) into build(), and ensure both buildSubsystem() and
assembleGeometry() use the same manager-aware path.

---

Nitpick comments:
In `@include/SHiPGeometry/SubsystemRegistry.h`:
- Around line 54-57: The registerSubsystem function currently returns success
even when a duplicate desc.name is registered, because registry().emplace()
silently ignores the second entry. Update registerSubsystem in
SubsystemRegistry.h to detect an existing name before or after emplace, and fail
fast by rejecting the duplicate instead of returning true. Use the
registerSubsystem and registry() symbols to locate the check, and make sure
duplicate subsystem descriptors cannot be added without a clear diagnostic.
🪄 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: 6f28d3d8-52fb-4061-8ca5-100ab3561b6c

📥 Commits

Reviewing files that changed from the base of the PR and between 203b9d2 and 40b4a66.

📒 Files selected for processing (25)
  • README.md
  • apps/build_geometry.cpp
  • include/SHiPGeometry/SubsystemRegistry.h
  • src/CMakeLists.txt
  • src/SHiPGeometry.cpp
  • subsystems/Calorimeter/include/Calorimeter/CalorimeterFactory.h
  • subsystems/Calorimeter/src/CalorimeterFactory.cpp
  • subsystems/Cavern/include/Cavern/CavernFactory.h
  • subsystems/Cavern/src/CavernFactory.cpp
  • subsystems/DecayVolume/include/DecayVolume/DecayVolumeFactory.h
  • subsystems/DecayVolume/src/DecayVolumeFactory.cpp
  • subsystems/Magnet/include/Magnet/MagnetFactory.h
  • subsystems/Magnet/src/MagnetFactory.cpp
  • subsystems/MuonShield/include/MuonShield/MuonShieldFactory.h
  • subsystems/MuonShield/src/MuonShieldFactory.cpp
  • subsystems/NeutrinoDetector/include/NeutrinoDetector/NeutrinoDetectorFactory.h
  • subsystems/NeutrinoDetector/src/NeutrinoDetectorFactory.cpp
  • subsystems/Target/include/Target/TargetFactory.h
  • subsystems/Target/src/TargetFactory.cpp
  • subsystems/TimingDetector/include/TimingDetector/TimingDetectorFactory.h
  • subsystems/TimingDetector/src/TimingDetectorFactory.cpp
  • subsystems/Trackers/include/Trackers/TrackersFactory.h
  • subsystems/Trackers/src/TrackersFactory.cpp
  • subsystems/UpstreamTagger/include/UpstreamTagger/UpstreamTaggerFactory.h
  • subsystems/UpstreamTagger/src/UpstreamTaggerFactory.cpp

Comment thread apps/build_geometry.cpp Outdated
Comment thread apps/build_geometry.cpp
Comment on lines 83 to 85
if (std::filesystem::exists(outputFile)) {
std::filesystem::remove(outputFile);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

std::filesystem::remove can throw uncaught on permission/lock errors.

The throwing overload is used; a locked or permission-denied output file would crash the tool instead of producing a clean error. The preceding exists() check is also redundant since remove() returns false harmlessly when the path doesn't exist.

🛡️ Proposed fix
-    if (std::filesystem::exists(outputFile)) {
-        std::filesystem::remove(outputFile);
-    }
+    std::error_code ec;
+    std::filesystem::remove(outputFile, ec);
+    if (ec) {
+        std::cerr << "Warning: could not remove existing " << outputFile << ": " << ec.message()
+                   << std::endl;
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (std::filesystem::exists(outputFile)) {
std::filesystem::remove(outputFile);
}
std::error_code ec;
std::filesystem::remove(outputFile, ec);
if (ec) {
std::cerr << "Warning: could not remove existing " << outputFile << ": " << ec.message()
<< std::endl;
}
🤖 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 `@apps/build_geometry.cpp` around lines 83 - 85, The output-file cleanup in
build_geometry.cpp uses the throwing std::filesystem::remove overload after a
redundant exists() check, which can crash on permission or lock failures. Update
the logic around the outputFile deletion to call the non-throwing remove variant
and handle its result (and any error_code) in build_geometry so missing files
are treated as a no-op while real filesystem errors are reported cleanly.

Comment thread include/SHiPGeometry/SubsystemRegistry.h
Comment thread README.md

## Structure

```

@coderabbitai coderabbitai Bot Jul 1, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a language identifier to the fenced code block.

markdownlint flags this block (MD040) since it has no language specified.

📝 Proposed fix
-```
+```text
 geometry/
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 170-170: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 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 `@README.md` at line 170, The fenced code block in the README is missing a
language identifier, which triggers markdownlint MD040. Update that markdown
fence to include a language specifier, using the fenced block in the README
around the geometry/ snippet as the target so the block is properly annotated.

Source: Linters/SAST tools

✅ Addressed in commits 40b4a66 to b7d33d4

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.

I think this is not actually resolved.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- README structure section ---'
nl -ba README.md | sed -n '160,195p'

printf '%s\n' '--- Markdown lint configuration files ---'
fd -HI '(^|/)(\.markdownlint.*|markdownlint.*)$' . -t f -x sh -c 'printf "\n--- %s ---\n" "$1"; cat "$1"' sh {} \; || true

printf '%s\n' '--- All unlabeled Markdown fences in README.md ---'
awk '
  /^```[[:space:]]*$/ { print "Line " NR ": " $0 }
' README.md

Length of output: 816


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- README structure section (numbered) ---'
awk 'NR >= 160 && NR <= 195 { printf "%d:%s\n", NR, $0 }' README.md

printf '%s\n' '--- Markdown lint configuration files ---'
find . -type f \( -name '.markdownlint*' -o -name 'markdownlint*' \) \
  -not -path './.git/*' \
  -print \
  -exec sh -c 'printf "\n--- %s ---\n" "$1"; cat "$1"' sh {} \;

printf '%s\n' '--- Unlabeled Markdown fences in README.md ---'
awk '/^```[[:space:]]*$/ { printf "Line %d: %s\n", NR, $0 }' README.md

Length of output: 2577


@olantwin, you’re right — it is not resolved. README.md still has an unlabeled opening fence at Line 180 for the geometry/ structure tree, so it still triggers MD040.

The minimal fix remains:

```text
geometry/
...

I’ll keep this finding unresolved.

Comment thread src/SHiPGeometry.cpp
// Copyright (C) CERN for the benefit of the SHiP Collaboration

#include "UpstreamTagger/UpstreamTaggerFactory.h"
#include "SHiPGeometry/SubsystemRegistry.h"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check how SHiPUBTManager is wired today, and whether anything besides this
# build() overload sets it, to confirm the registry path truly loses it.
rg -n "SHiPUBTManager" --type=cpp -C3
rg -n "buildSubsystem|assembleGeometry" --type=cpp -C3

Repository: ShipSoft/Geometry

Length of output: 155


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the relevant files and inspect the factory/registry wiring.
git ls-files | rg 'UpstreamTaggerFactory\.cpp|UpstreamTagger.*\.cpp|SHiPGeometry/SubsystemRegistry\.h|SubsystemRegistry\.h|REGISTER_SUBSYSTEM'

echo '--- UpstreamTaggerFactory.cpp ---'
cat -n subsystems/UpstreamTagger/src/UpstreamTaggerFactory.cpp | sed -n '1,220p'

echo '--- SubsystemRegistry.h (if present) ---'
for f in $(git ls-files | rg 'SubsystemRegistry\.h$'); do
  echo "### $f"
  cat -n "$f" | sed -n '1,260p'
done

echo '--- any REGISTER_SUBSYSTEM uses ---'
rg -n "REGISTER_SUBSYSTEM|build\(SHiPMaterials|SHiPUBTManager|setContainerVolume|containerPhys|GeoFullPhysVol" subsystems -C 3

Repository: ShipSoft/Geometry

Length of output: 45346


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect registry consumers to see whether they ever pass a manager or provide
# a post-build hook.
for f in $(git ls-files | rg 'SubsystemRegistry\.(cpp|cc|cxx|h)$|.*\.cpp$|.*\.h$'); do
  if rg -n "buildSubsystem\(|assembleGeometry\(|registerSubsystem\(|setContainerVolume\(" "$f" >/dev/null 2>&1; then
    echo "### $f"
    rg -n "buildSubsystem\(|assembleGeometry\(|registerSubsystem\(|setContainerVolume\(" "$f" -C 4
  fi
done

Repository: ShipSoft/Geometry

Length of output: 3955


REGISTER_SUBSYSTEM drops the SHiPUBTManager*, so the UpstreamTagger tree-top never gets registered through the registry path. The registry callback only forwards SHiPMaterials&, so build() always sees manager == nullptr and setContainerVolume() is skipped in both buildSubsystem() and assembleGeometry().

🤖 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 `@subsystems/UpstreamTagger/src/UpstreamTaggerFactory.cpp` at line 5, The
UpstreamTagger registration path is losing the SHiPUBTManager pointer, so
build() never receives a valid manager and setContainerVolume() is skipped.
Update the REGISTER_SUBSYSTEM wiring in UpstreamTaggerFactory so the registry
callback preserves and forwards the SHiPUBTManager* (or otherwise retrieves it)
into build(), and ensure both buildSubsystem() and assembleGeometry() use the
same manager-aware path.

@matclim
matclim requested a review from olantwin July 1, 2026 22:39
@matclim

matclim commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

This PR is in preparation for another PR which will include visualisation, both for all subsystems and for individual subsystems.

@matclim

matclim commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

@CodeRabbit full review

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@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

♻️ Duplicate comments (1)
src/SHiPGeometry.cpp (1)

49-59: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Unvalidated factory build results still propagate into cast/placement.

The world lookup at Line 53 casts the factory's return value without checking for nullptr/cast failure, and the placement loop at Line 79 passes info->build(materials) straight into place() without a null check. A misbehaving or mis-descriptored factory (e.g. isWorld=true on a non-GeoPhysVol, or a build path that legitimately returns nullptr) will either silently produce a null world or crash deep inside GeoModel with an unclear error.

Proposed fix
     GeoPhysVol* world = nullptr;
     for (auto& entry : reg) {
         if (entry.second.desc.isWorld) {
-            world = dynamic_cast<GeoPhysVol*>(entry.second.build(materials));
+            auto* builtWorld = entry.second.build(materials);
+            world = dynamic_cast<GeoPhysVol*>(builtWorld);
+            if (!world) {
+                throw std::runtime_error("World subsystem '" + entry.first +
+                                         "' did not return a GeoPhysVol");
+            }
             break;
         }
     }
@@
     for (const SubsystemInfo* info : placed) {
-        place(world, info->build(materials), info->desc);
+        auto* volume = info->build(materials);
+        if (!volume) {
+            throw std::runtime_error("Subsystem '" + std::string(info->desc.name) +
+                                     "' returned null geometry");
+        }
+        place(world, volume, info->desc);
     }

Also applies to: 78-80

🤖 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 `@src/SHiPGeometry.cpp` around lines 49 - 59, The world selection in
SHiPGeometry currently trusts factory build results without validation, so a bad
isWorld subsystem or a build that returns null can propagate into the GeoPhysVol
cast and later placement. In the world lookup logic, check the result of
entry.second.build(materials) before dynamic_cast and verify the cast succeeded
before assigning world; if either fails, throw a clear runtime error mentioning
the subsystem. In the placement loop, validate info->build(materials) before
calling place() and skip/throw on null so GeoModel never receives an invalid
object from SHiPGeometry.
🤖 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 `@README.md`:
- Around line 162-164: The CMake guidance in README.md is misleading because
src/CMakeLists.txt does not use a --whole-archive block for subsystem libraries;
update the instructions to reference the actual --no-as-needed / --as-needed
linker block and the existing inline comment about whole-archive being a no-op.
Make sure the step tells contributors to add the new subsystem target to that
real link section so REGISTER_SUBSYSTEM initialization is preserved.

---

Duplicate comments:
In `@src/SHiPGeometry.cpp`:
- Around line 49-59: The world selection in SHiPGeometry currently trusts
factory build results without validation, so a bad isWorld subsystem or a build
that returns null can propagate into the GeoPhysVol cast and later placement. In
the world lookup logic, check the result of entry.second.build(materials) before
dynamic_cast and verify the cast succeeded before assigning world; if either
fails, throw a clear runtime error mentioning the subsystem. In the placement
loop, validate info->build(materials) before calling place() and skip/throw on
null so GeoModel never receives an invalid object from SHiPGeometry.
🪄 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: f3f6c31d-2095-4c0a-a342-3d9cb4907ffe

📥 Commits

Reviewing files that changed from the base of the PR and between 203b9d2 and b7d33d4.

📒 Files selected for processing (25)
  • README.md
  • apps/build_geometry.cpp
  • include/SHiPGeometry/SubsystemRegistry.h
  • src/CMakeLists.txt
  • src/SHiPGeometry.cpp
  • subsystems/Calorimeter/include/Calorimeter/CalorimeterFactory.h
  • subsystems/Calorimeter/src/CalorimeterFactory.cpp
  • subsystems/Cavern/include/Cavern/CavernFactory.h
  • subsystems/Cavern/src/CavernFactory.cpp
  • subsystems/DecayVolume/include/DecayVolume/DecayVolumeFactory.h
  • subsystems/DecayVolume/src/DecayVolumeFactory.cpp
  • subsystems/Magnet/include/Magnet/MagnetFactory.h
  • subsystems/Magnet/src/MagnetFactory.cpp
  • subsystems/MuonShield/include/MuonShield/MuonShieldFactory.h
  • subsystems/MuonShield/src/MuonShieldFactory.cpp
  • subsystems/NeutrinoDetector/include/NeutrinoDetector/NeutrinoDetectorFactory.h
  • subsystems/NeutrinoDetector/src/NeutrinoDetectorFactory.cpp
  • subsystems/Target/include/Target/TargetFactory.h
  • subsystems/Target/src/TargetFactory.cpp
  • subsystems/TimingDetector/include/TimingDetector/TimingDetectorFactory.h
  • subsystems/TimingDetector/src/TimingDetectorFactory.cpp
  • subsystems/Trackers/include/Trackers/TrackersFactory.h
  • subsystems/Trackers/src/TrackersFactory.cpp
  • subsystems/UpstreamTagger/include/UpstreamTagger/UpstreamTaggerFactory.h
  • subsystems/UpstreamTagger/src/UpstreamTaggerFactory.cpp

Comment thread README.md Outdated
Comment on lines +162 to +164
4. **CMake**: add sources/headers to `subsystems/<Name>/CMakeLists.txt`, and
add the new library to the `--whole-archive` block in `src/CMakeLists.txt`
so its self-registration initializer is not dropped by the linker

@coderabbitai coderabbitai Bot Jul 2, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

"--whole-archive block" doesn't match the actual CMake mechanism.

src/CMakeLists.txt links subsystem targets using -Wl,--no-as-needed ... -Wl,--as-needed, with an inline comment explicitly noting whole-archive is a no-op for these shared libraries. A contributor following this step would search for a nonexistent --whole-archive block instead of the actual --no-as-needed block, risking a subsystem being left unlinked (its REGISTER_SUBSYSTEM initializer silently dropped).

📝 Proposed fix
-4. **CMake**: add sources/headers to `subsystems/<Name>/CMakeLists.txt`, and
-   add the new library to the `--whole-archive` block in `src/CMakeLists.txt`
-   so its self-registration initializer is not dropped by the linker
+4. **CMake**: add sources/headers to `subsystems/<Name>/CMakeLists.txt`, and
+   add the new library to the `--no-as-needed` linker block in
+   `src/CMakeLists.txt` so its self-registration initializer is not dropped
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
4. **CMake**: add sources/headers to `subsystems/<Name>/CMakeLists.txt`, and
add the new library to the `--whole-archive` block in `src/CMakeLists.txt`
so its self-registration initializer is not dropped by the linker
4. **CMake**: add sources/headers to `subsystems/<Name>/CMakeLists.txt`, and
add the new library to the `--no-as-needed` linker block in
`src/CMakeLists.txt` so its self-registration initializer is not dropped
🤖 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 `@README.md` around lines 162 - 164, The CMake guidance in README.md is
misleading because src/CMakeLists.txt does not use a --whole-archive block for
subsystem libraries; update the instructions to reference the actual
--no-as-needed / --as-needed linker block and the existing inline comment about
whole-archive being a no-op. Make sure the step tells contributors to add the
new subsystem target to that real link section so REGISTER_SUBSYSTEM
initialization is preserved.

✅ Addressed in commits 3d75f9c to 6bddf29

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 issue seems to still be present?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- README CMake guidance ---'
sed -n '155,172p' README.md

printf '%s\n' '--- src/CMakeLists.txt linker-related lines ---'
rg -n -C 8 -- '--whole-archive|--no-as-needed|--as-needed|target_link_libraries\s*\(' src/CMakeLists.txt

Length of output: 2637


@olantwin Yes — it is still present.

The README still refers to a nonexistent --whole-archive block. The actual mechanism in src/CMakeLists.txt is:

  • add the subsystem target to target_link_libraries(SHiPGeometry ...); and
  • retain it at consumer link time through target_link_options(SHiPGeometry INTERFACE "-Wl,--no-as-needed").

The documentation should be updated to reference that subsystem-target list and the --no-as-needed retention behavior. The earlier “addressed” status was incorrect.

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.

@matclim Please address this.

@matclim
matclim force-pushed the self-registration branch from b7d33d4 to 99a36d4 Compare July 11, 2026 20:23
Matei Climescu added 3 commits July 12, 2026 00:24
@matclim
matclim force-pushed the self-registration branch from 99a36d4 to 6bddf29 Compare July 11, 2026 23:07

@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

Caution

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

⚠️ Outside diff range comments (1)
README.md (1)

182-193: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Include NeutrinoDetector in the structure tree.

It is listed as an implemented subsystem above and participates in the registry, but is missing from this repository layout. This makes the documented subsystem structure incomplete.

🤖 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 `@README.md` around lines 182 - 193, Update the README repository structure
tree under subsystems to include the implemented NeutrinoDetector directory,
keeping it alongside the other detector subsystem entries and preserving the
documented layout.
♻️ Duplicate comments (1)
include/SHiPGeometry/SubsystemRegistry.h (1)

8-11: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Missing <utility> include for std::move (duplicate of prior review).

std::move is used on line 56 but <utility> is not included. The header is not self-contained. This was previously flagged and remains unresolved.

Proposed fix
 `#include` <functional>
 `#include` <map>
 `#include` <string>
+#include <utility>
 `#include` <vector>
🤖 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 `@include/SHiPGeometry/SubsystemRegistry.h` around lines 8 - 11, Update the
includes in SubsystemRegistry.h to add the standard <utility> header, ensuring
the std::move usage in the registry implementation is declared and the header
remains self-contained.
🧹 Nitpick comments (1)
src/CMakeLists.txt (1)

28-34: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider guarding --no-as-needed for non-GNU linkers.

-Wl,--no-as-needed is specific to GNU ld and gold. LLD supports it with GNU-compatible defaults, but Apple's ld does not. If the project only targets Linux with GNU ld this is fine; otherwise consider a linker check:

# Only apply on GNU-compatible linkers
if(CMAKE_LINKER_ID STREQUAL "GNU" OR CMAKE_LINKER_ID STREQUAL "Gold")
    target_link_options(SHiPGeometry INTERFACE "-Wl,--no-as-needed")
endif()

This is a minor portability note — skip if Linux/GNU-only is an established constraint.

🤖 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 `@src/CMakeLists.txt` around lines 28 - 34, Guard the --no-as-needed option on
target_link_options(SHiPGeometry) using a CMAKE_LINKER_ID check for
GNU-compatible linkers such as GNU or Gold, leaving the option unset for
unsupported linkers like Apple ld.
🤖 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 `@include/SHiPGeometry/SubsystemRegistry.h`:
- Around line 54-58: Update registerSubsystem to inspect the insertion result
from registry().emplace. When desc.name is already registered, emit a diagnostic
or throw instead of silently discarding the new factory; preserve the successful
registration and true return behavior for unique names.

---

Outside diff comments:
In `@README.md`:
- Around line 182-193: Update the README repository structure tree under
subsystems to include the implemented NeutrinoDetector directory, keeping it
alongside the other detector subsystem entries and preserving the documented
layout.

---

Duplicate comments:
In `@include/SHiPGeometry/SubsystemRegistry.h`:
- Around line 8-11: Update the includes in SubsystemRegistry.h to add the
standard <utility> header, ensuring the std::move usage in the registry
implementation is declared and the header remains self-contained.

---

Nitpick comments:
In `@src/CMakeLists.txt`:
- Around line 28-34: Guard the --no-as-needed option on
target_link_options(SHiPGeometry) using a CMAKE_LINKER_ID check for
GNU-compatible linkers such as GNU or Gold, leaving the option unset for
unsupported linkers like Apple ld.
🪄 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: f8c5f1e5-fedc-4a7e-9bc3-bf827e1168d9

📥 Commits

Reviewing files that changed from the base of the PR and between b7d33d4 and 6bddf29.

📒 Files selected for processing (26)
  • Geometry]:
  • README.md
  • apps/build_geometry.cpp
  • include/SHiPGeometry/SubsystemRegistry.h
  • src/CMakeLists.txt
  • src/SHiPGeometry.cpp
  • subsystems/Calorimeter/include/Calorimeter/CalorimeterFactory.h
  • subsystems/Calorimeter/src/CalorimeterFactory.cpp
  • subsystems/Cavern/include/Cavern/CavernFactory.h
  • subsystems/Cavern/src/CavernFactory.cpp
  • subsystems/DecayVolume/include/DecayVolume/DecayVolumeFactory.h
  • subsystems/DecayVolume/src/DecayVolumeFactory.cpp
  • subsystems/Magnet/include/Magnet/MagnetFactory.h
  • subsystems/Magnet/src/MagnetFactory.cpp
  • subsystems/MuonShield/include/MuonShield/MuonShieldFactory.h
  • subsystems/MuonShield/src/MuonShieldFactory.cpp
  • subsystems/NeutrinoDetector/include/NeutrinoDetector/NeutrinoDetectorFactory.h
  • subsystems/NeutrinoDetector/src/NeutrinoDetectorFactory.cpp
  • subsystems/Target/include/Target/TargetFactory.h
  • subsystems/Target/src/TargetFactory.cpp
  • subsystems/TimingDetector/include/TimingDetector/TimingDetectorFactory.h
  • subsystems/TimingDetector/src/TimingDetectorFactory.cpp
  • subsystems/Trackers/include/Trackers/TrackersFactory.h
  • subsystems/Trackers/src/TrackersFactory.cpp
  • subsystems/UpstreamTagger/include/UpstreamTagger/UpstreamTaggerFactory.h
  • subsystems/UpstreamTagger/src/UpstreamTaggerFactory.cpp
✅ Files skipped from review due to trivial changes (2)
  • subsystems/Trackers/src/TrackersFactory.cpp
  • subsystems/Cavern/src/CavernFactory.cpp
🚧 Files skipped from review as they are similar to previous changes (20)
  • subsystems/UpstreamTagger/include/UpstreamTagger/UpstreamTaggerFactory.h
  • subsystems/NeutrinoDetector/src/NeutrinoDetectorFactory.cpp
  • subsystems/Magnet/include/Magnet/MagnetFactory.h
  • subsystems/Calorimeter/src/CalorimeterFactory.cpp
  • subsystems/MuonShield/include/MuonShield/MuonShieldFactory.h
  • subsystems/TimingDetector/include/TimingDetector/TimingDetectorFactory.h
  • subsystems/Cavern/include/Cavern/CavernFactory.h
  • subsystems/Trackers/include/Trackers/TrackersFactory.h
  • subsystems/DecayVolume/src/DecayVolumeFactory.cpp
  • subsystems/Calorimeter/include/Calorimeter/CalorimeterFactory.h
  • subsystems/Target/include/Target/TargetFactory.h
  • subsystems/NeutrinoDetector/include/NeutrinoDetector/NeutrinoDetectorFactory.h
  • subsystems/UpstreamTagger/src/UpstreamTaggerFactory.cpp
  • subsystems/Magnet/src/MagnetFactory.cpp
  • subsystems/Target/src/TargetFactory.cpp
  • subsystems/MuonShield/src/MuonShieldFactory.cpp
  • subsystems/DecayVolume/include/DecayVolume/DecayVolumeFactory.h
  • apps/build_geometry.cpp
  • subsystems/TimingDetector/src/TimingDetectorFactory.cpp
  • src/SHiPGeometry.cpp

Comment thread include/SHiPGeometry/SubsystemRegistry.h
…tion

registerSubsystem inspected nothing from emplace(), so a second subsystem
declaring an already-registered descriptor name was silently discarded and
registration still reported success. Check the insertion result and abort
with a diagnostic naming the offending subsystem; registration runs at
static-init, so a throw would reach no handler.

Add <cstdio>, <cstdlib> and <utility> so the header is self-contained, and
correct the REGISTER_SUBSYSTEM note, which still described the subsystems as
static archives needing --whole-archive.

Restrict -Wl,--no-as-needed to non-Apple UNIX, and add NeutrinoDetector to
the README structure tree.
@matclim

matclim commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

@CodeRabbit full review

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.


Your plan includes PR reviews subject to rate limits. More reviews will be available in 36 minutes.

@matclim

matclim commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

@CodeRabbit full review

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@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: 3

🤖 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 `@src/CMakeLists.txt`:
- Around line 28-38: Remove the unconditional target_link_options call for
SHiPGeometry, leaving only the --no-as-needed option inside the existing
“if(UNIX AND NOT APPLE)” guard. Preserve the guarded platform-specific linker
behavior.

In `@subsystems/Magnet/include/Magnet/MagnetFactory.h`:
- Around line 31-34: Update MagnetFactory::descriptor so its placement envelope
no longer overlaps the TrackersFactory envelope when both are assembled as world
siblings; preserve the intentional shared z-center while adjusting the Magnet
envelope’s z extent or placement to fit outside the Trackers span. Verify the
resulting descriptor bounds are non-intersecting.

In `@subsystems/UpstreamTagger/src/UpstreamTaggerFactory.cpp`:
- Around line 145-146: Update the registry integration for UpstreamTaggerFactory
so the SHiPUBTManager* reaches build() when constructed through
REGISTER_SUBSYSTEM, allowing setContainerVolume() to execute. Modify the
relevant factory registration/build path rather than the unrelated
container-volume logic, and preserve direct construction behavior.
🪄 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: 26b0db48-46bf-4ac2-8c71-09f8ce040c1f

📥 Commits

Reviewing files that changed from the base of the PR and between 754fa69 and 135f739.

📒 Files selected for processing (26)
  • Geometry]:
  • README.md
  • apps/build_geometry.cpp
  • include/SHiPGeometry/SubsystemRegistry.h
  • src/CMakeLists.txt
  • src/SHiPGeometry.cpp
  • subsystems/Calorimeter/include/Calorimeter/CalorimeterFactory.h
  • subsystems/Calorimeter/src/CalorimeterFactory.cpp
  • subsystems/Cavern/include/Cavern/CavernFactory.h
  • subsystems/Cavern/src/CavernFactory.cpp
  • subsystems/DecayVolume/include/DecayVolume/DecayVolumeFactory.h
  • subsystems/DecayVolume/src/DecayVolumeFactory.cpp
  • subsystems/Magnet/include/Magnet/MagnetFactory.h
  • subsystems/Magnet/src/MagnetFactory.cpp
  • subsystems/MuonShield/include/MuonShield/MuonShieldFactory.h
  • subsystems/MuonShield/src/MuonShieldFactory.cpp
  • subsystems/NeutrinoDetector/include/NeutrinoDetector/NeutrinoDetectorFactory.h
  • subsystems/NeutrinoDetector/src/NeutrinoDetectorFactory.cpp
  • subsystems/Target/include/Target/TargetFactory.h
  • subsystems/Target/src/TargetFactory.cpp
  • subsystems/TimingDetector/include/TimingDetector/TimingDetectorFactory.h
  • subsystems/TimingDetector/src/TimingDetectorFactory.cpp
  • subsystems/Trackers/include/Trackers/TrackersFactory.h
  • subsystems/Trackers/src/TrackersFactory.cpp
  • subsystems/UpstreamTagger/include/UpstreamTagger/UpstreamTaggerFactory.h
  • subsystems/UpstreamTagger/src/UpstreamTaggerFactory.cpp

Comment thread src/CMakeLists.txt
Comment thread subsystems/Magnet/include/Magnet/MagnetFactory.h
Comment thread subsystems/UpstreamTagger/src/UpstreamTaggerFactory.cpp
@olantwin

Copy link
Copy Markdown
Contributor

One general comment: let's use spdlog for logging. I didn't catch it in the original commits.

@olantwin

Copy link
Copy Markdown
Contributor

Full review coming...

@olantwin

Copy link
Copy Markdown
Contributor

There are still quite a few open code rabbit comments and a merge conflict. What's your plan for this PR?

@matclim

matclim commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

I was waiting for your review, the main features are there, the coderabbit stuff may lead to refactors which should only be done once we agree about the way this should be merged.

@olantwin

Copy link
Copy Markdown
Contributor

Ok, then I'll review now.

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

A few questions and nitpicks.

Comment thread Geometry]: Outdated

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 file should be removed.
Please add only files (or better: lines/hunks) you intend to commit.

Comment thread src/CMakeLists.txt
# link line, which is where the entries were being dropped.
target_link_options(SHiPGeometry INTERFACE "-Wl,--no-as-needed")

if(UNIX AND NOT APPLE)

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 unguarded version probably needs to be removed.

Comment thread README.md Outdated
Comment on lines +162 to +164
4. **CMake**: add sources/headers to `subsystems/<Name>/CMakeLists.txt`, and
add the new library to the `--whole-archive` block in `src/CMakeLists.txt`
so its self-registration initializer is not dropped by the linker

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 issue seems to still be present?

Comment thread src/CMakeLists.txt Outdated
Comment on lines +29 to +33
# The subsystems are referenced only through their REGISTER_SUBSYSTEM static
# initialisers, so the toolchain's default --as-needed drops them from the
# DT_NEEDED of every executable that links SHiPGeometry, and their
# registrations never run. INTERFACE puts --no-as-needed on the *consumer's*
# link line, which is where the entries were being dropped.

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 probably only works for dynamically linked builds. Maybe we should disallow static builds or raise a warning if build statically.

Comment thread src/SHiPGeometry.cpp
#include "DecayVolume/DecayVolumeFactory.h"
#include "Magnet/MagnetFactory.h"
#include "MuonShield/MuonShieldFactory.h"
#include "SHiPGeometry/Placement.h"

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.

I don't think we use this header anywhere anymore. Maybe time to delete it entirely?

Comment thread apps/build_geometry.cpp Outdated
Comment on lines +28 to +33
namespace {
bool endsWith(const std::string& s, const std::string& suffix) {
return s.size() >= suffix.size() &&
s.compare(s.size() - suffix.size(), suffix.size(), suffix) == 0;
}
} // namespace

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 isn't needed, use std::string::ends_with()

Comment thread src/SHiPGeometry.cpp

} // namespace

GeoPhysVol* assembleGeometry(const std::vector<std::string>& only) {

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.

Is the selection parameter used anywhere (e.g. the CI)?

Comment thread src/SHiPGeometry.cpp
#include "Target/TargetFactory.h"
#include "TimingDetector/TimingDetectorFactory.h"
#include "Trackers/TrackersFactory.h"
#include "UpstreamTagger/SHiPUBTManager.h"

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.

I think SHiPUBTManager is also now useless.

Sidenote: Let's not add SHiP to our classnames... I know it's my fault for some as well. Probably something deserving of a sweeping cleanup.

@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 unaddressed coderabbit comments and some new comments from me.

Comment thread src/CMakeLists.txt Outdated
Comment on lines +37 to +47
elseif(NOT BUILD_SHARED_LIBS)
# Static build: --no-as-needed does not apply to archives. Subsystem
# self-registration would instead need --whole-archive (or equivalent),
# which is not configured here, so the registry may be empty at run time.
message(
WARNING
"Static build detected: subsystem self-registration relies on "
"-Wl,--no-as-needed for shared libraries and is not wired up for static "
"archives. build_geometry/tests may find an empty subsystem registry. "
"Prefer BUILD_SHARED_LIBS=ON."
)

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 check needs to come first and can't be exclusive with Linux (unix and not apple)

Comment thread README.md Outdated
Comment on lines +162 to +164
4. **CMake**: add sources/headers to `subsystems/<Name>/CMakeLists.txt`, and
add the new library to the `--whole-archive` block in `src/CMakeLists.txt`
so its self-registration initializer is not dropped by the linker

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.

@matclim Please address this.

Comment thread apps/build_geometry.cpp Outdated

/// This subsystem's self-description (name, node, id, placement).
static SubsystemDescriptor descriptor() {
return {"Trackers", "/SHiP/trackers", 5, 0.0, 0.0, 89570.0, false};

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 use s_containerCentreZ here instead of hardcoding the same number?

if (manager) {
manager->setContainerVolume(containerPhys);
}
manager->setContainerVolume(containerPhys);

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.

Maybe here the previous method was better, at least i don't see the advantage of adding a dummy manager over skipping the setting of the container volume.

#include "UpstreamTagger/UpstreamTaggerFactory.h"

#include "SHiPGeometry/SHiPMaterials.h"
#include "SHiPGeometry/SubsystemRegistry.h"

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.

Here (and elsewhere): this is a pretty heavy header. Most isn't needed in the factory headers. I suggest we split this so that a light-weight header is included in the factory headers and the rest in the factory implementations.

Comment thread src/SHiPGeometry.cpp Outdated
Comment on lines +30 to +34
for (auto& entry : reg) {
if (entry.second.desc.isWorld) {
world = dynamic_cast<GeoPhysVol*>(entry.second.build(materials));
break;
}

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.

  1. Using structured bindings would make this more readable
  2. Is the cast here reliable? I don't have the inheritance structure of GeoPhysVol in my head right now, but can this over/undermatch?

- build_geometry: assemble a selection of subsystems (>1 name) instead
  of rejecting it; reinstates assembleGeometry(only) with name validation
- geometry: split SubsystemDescriptor into a lightweight header so the
  factory headers no longer pull in the full registry (map, functional,
  GeoPhysVol); the registry machinery stays in SubsystemRegistry.h
- geometry: validate the world dynamic_cast and use structured bindings
  in the assembler, so a mis-typed world fails clearly
- upstream-tagger: revert the local-manager fallback and keep the
  manager guard (a local manager is destroyed at scope exit, so it did
  nothing); fixes an unconditional deref
- trackers: derive descriptor z from s_containerCentreZ instead of the
  hardcoded 89570
- cmake: check static builds first and independently of the Linux guard,
  warn that self-registration needs shared libs
- readme: fix the stale --whole-archive instruction, add NeutrinoDetector
@matclim

matclim commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 37 minutes.

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.

2 participants