Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions src/SHiPGeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,15 @@ GeoPhysVol* SHiPGeometryBuilder::build() {
GeoTrf::Translate3D(0.0, 0.0, 28.95 * m));

// Build and place UpstreamTagger (sensitive scintillator slab)
// Z: 32.52 to 32.92 m → centre: 32.72 m
// Integration layout 2026-0.1 (EDMS 3287817 v1.1): 0.4 m slot from 32.67
// to 33.07 m at the entrance of the decay volume. The 160 mm tile plane is
// placed inside that slot with its rear face flush with the decay-volume
// container (32.92 m), so it cannot sit exactly on the slot mid-plane.
SHiPUBTManager ubtManager;
UpstreamTaggerFactory upstreamTaggerFactory(materials);
GeoVPhysVol* upstreamTagger = upstreamTaggerFactory.build(&ubtManager);
placeChild(world, upstreamTagger, "/SHiP/upstream_tagger", 3,
GeoTrf::Translate3D(0.0, 0.0, 32.72 * m));
GeoTrf::Translate3D(0.0, 0.0, 32.84 * m));

// Build and place DecayVolume
// Z: 32.92 to 83.32 m → centre: 58.12 m
Expand All @@ -81,25 +84,27 @@ GeoPhysVol* SHiPGeometryBuilder::build() {

// Build and place Trackers (container with 4 stations).
// The factory already handles internal positioning; place the container at
// its centre Z (average of station 1 and 4 centres).
// its centre Z (average of station 1 and 4 centres, integration layout
// 2026-0.1: station mid-planes at 84.22, 86.22, 93.22 and 95.22 m).
TrackersFactory trackersFactory(materials);
GeoPhysVol* trackers = trackersFactory.build();
constexpr double trackersCentreZ = (84.07 + 95.07) / 2.0 * m;
constexpr double trackersCentreZ = (84.22 + 95.22) / 2.0 * m;
placeChild(world, trackers, "/SHiP/trackers", 5,
GeoTrf::Translate3D(0.0, 0.0, trackersCentreZ));

// Build and place Magnet
// Z: 87.07 to 92.07 m → centre: 89.57 m
// Integration layout 2026-0.1: 5 m slot with its mid-plane at 89.72 m.
MagnetFactory magnetFactory(materials);
GeoPhysVol* magnet = magnetFactory.build();
placeChild(world, magnet, "/SHiP/magnet", 6, GeoTrf::Translate3D(0.0, 0.0, 89.57 * m));
placeChild(world, magnet, "/SHiP/magnet", 6, GeoTrf::Translate3D(0.0, 0.0, 89.72 * m));

// Build and place TimingDetector
// Z: 95.902 m (from GDML reference)
// Integration layout 2026-0.1: 0.46 m slot from 96.14 to 96.60 m, placed
// at the slot centre.
TimingDetectorFactory timingDetectorFactory(materials);
GeoPhysVol* timingDetector = timingDetectorFactory.build();
placeChild(world, timingDetector, "/SHiP/timing_detector", 7,
GeoTrf::Translate3D(0.0, 0.0, 95.902 * m));
GeoTrf::Translate3D(0.0, 0.0, 96.37 * m));

// Build and place Calorimeter (ECAL + HCAL).
// The layer structure comes from CalorimeterConstants.h; the outer container
Expand Down
2 changes: 1 addition & 1 deletion subsystems/Magnet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ SHiPMagnet (Air, 6500×8600×5000 mm)
└─ CV_4 (Aluminium) at (-2600, 0, +1525)
```

Position in world: z = 89570 mm.
Position in world: z = 89720 mm (mid-plane of the 87.22–92.22 m slot in integration layout 2026-0.1, EDMS 3287817 v1.1).

## Materials

Expand Down
2 changes: 1 addition & 1 deletion subsystems/TimingDetector/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Timing_Detector (Air, 5500×6500×500 mm)
3 columns × 110 rows; z stagger = (row%2)·12 + (col%2)·90 mm
```

Position in world: z = 95902 mm.
Position in world: z = 96370 mm (centre of the 96.14–96.60 m slot in integration layout 2026-0.1, EDMS 3287817 v1.1).

## Materials

Expand Down
10 changes: 5 additions & 5 deletions subsystems/Trackers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,18 @@ The spectrometer dipole between stations 2 and 3 is a separate subsystem
└─ /SHiP/trackers/tracker_magnet (Air, inert marker box)
```

Station Z positions (centres): 84070, 86070, 93070, 95070 mm.
Position in world: centred at z = 89570 mm (average of stations 1 and 4).
Station Z positions (centres): 84220, 86220, 93220, 95220 mm.
Position in world: centred at z = 89720 mm (average of stations 1 and 4).
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Stations 1-2 are upstream of the magnet, stations 3-4 downstream.

## Tracker magnet

`/SHiP/trackers/tracker_magnet` is an inert, air-filled marker volume for
the tracker magnet, centred at z = 86820 mm with a 460 mm Z extent.
the tracker magnet, centred at z = 86970 mm with a 460 mm Z extent.

It is **not** a physically-scaled dipole. The spectrometer dipole proper is
the separate `Magnet` subsystem (iron yoke + coils) occupying z = 87.07 to
92.07 m. The only space inside the trackers container that is clear of both
the separate `Magnet` subsystem (iron yoke + coils) occupying z = 87.22 to
92.22 m. The only space inside the trackers container that is clear of both
the straw stations and that yoke is the ~0.5 m gap between station 2 and the
yoke, so the marker is sized and placed to fit there without overlap.

Expand Down
21 changes: 11 additions & 10 deletions subsystems/Trackers/include/Trackers/TrackersFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ class SHiPMaterials;
*
* Builds 4 straw tracking stations for the SHiP spectrometer. Station
* envelopes and z-positions follow the GDML reference / subsystem_envelopes.csv:
* - Station 1: Z 83.57-84.57 m → centre 84.07 m
* - Station 2: Z 85.57-86.57 m → centre 86.07 m
* - Station 3: Z 92.57-93.57 m → centre 93.07 m
* - Station 4: Z 94.57-95.57 m → centre 95.07 m
* - Station 1: Z 83.72-84.72 m → centre 84.22 m
* - Station 2: Z 85.72-86.72 m → centre 86.22 m
* - Station 3: Z 92.72-93.72 m → centre 93.22 m
* - Station 4: Z 94.72-95.72 m → centre 95.22 m
* (integration layout 2026-0.1, EDMS 3287817 v1.1)
* Station envelope (GDML statbox): half 3000 × 3430 × 500 mm.
*
* Each station envelope is filled with 4 stereo views. A view is a material
Expand Down Expand Up @@ -78,12 +79,12 @@ class TrackersFactory {
//
// NOTE: this is NOT a physically-scaled dipole. The spectrometer dipole
// proper is the separate Magnet subsystem (iron yoke + coils) occupying
// z = 87.07-92.07 m. The only free space inside the trackers container
// z = 87.22-92.22 m. The only free space inside the trackers container
// and clear of that yoke is a ~0.5 m gap, so this marker is sized to fit
// there. It exists so the tracker magnet has a named placeholder in the
// geometry; simulation/field code can locate it by the name
// "/SHiP/trackers/tracker_magnet".
static constexpr double s_trackerMagnetZ = 86820.0 * mm; ///< centre
static constexpr double s_trackerMagnetZ = 86970.0 * mm; ///< centre
static constexpr double s_trackerMagnetHalfZ = 230.0 * mm; ///< half-depth

private:
Expand All @@ -98,10 +99,10 @@ class TrackersFactory {
static constexpr double s_halfZ = 500.0 * mm; // 50 cm

// Station Z positions (centres, from origin).
static constexpr double s_station1Z = 84070.0 * mm; // 84.07 m
static constexpr double s_station2Z = 86070.0 * mm; // 86.07 m
static constexpr double s_station3Z = 93070.0 * mm; // 93.07 m
static constexpr double s_station4Z = 95070.0 * mm; // 95.07 m
static constexpr double s_station1Z = 84220.0 * mm; // 84.22 m
static constexpr double s_station2Z = 86220.0 * mm; // 86.22 m
static constexpr double s_station3Z = 93220.0 * mm; // 93.22 m
static constexpr double s_station4Z = 95220.0 * mm; // 95.22 m

// Container dimensions (spans all stations).
static constexpr double s_containerHalfZ = (s_station4Z - s_station1Z) / 2.0 + s_halfZ;
Expand Down
8 changes: 4 additions & 4 deletions subsystems/Trackers/test_trackers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ TEST_CASE("TrackersHasTrackerMagnet", "[trackers]") {
REQUIRE(tm != nullptr);
auto* box = dynamic_cast<const GeoBox*>(tm->getLogVol()->getShape());
REQUIRE(box != nullptr);
// Span must stay clear of station 2 (ends 86570 mm) and the Magnet yoke
// (starts 87070 mm): 86570 <= centre ± halfZ <= 87070.
// Span must stay clear of station 2 (ends 86720 mm) and the Magnet slot
// (starts 87220 mm): 86720 <= centre ± halfZ <= 87220.
const double centre = TrackersFactory::s_trackerMagnetZ;
const double halfZ = box->getZHalfLength();
CHECK(centre - halfZ >= 86570.0);
CHECK(centre + halfZ <= 87070.0);
CHECK(centre - halfZ >= 86720.0);
CHECK(centre + halfZ <= 87220.0);
}
2 changes: 1 addition & 1 deletion subsystems/UpstreamTagger/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ registered with `SHiPUBTManager`.
Tile totals: fine 2 × 400 + 2 × 19 200 = 39 200; coarse 300 + 2 × 3 750 = 7 800;
**47 000 tiles** in total.

Position in world: z = 32 720 mm (centre of the 32.52–32.92 m envelope).
Position in world: z = 32 840 mm (inside the 32.67–33.07 m slot of integration layout 2026-0.1, EDMS 3287817 v1.1, with the rear face flush with the decay-volume container at 32.92 m).

## Materials

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ class SHiPUBTManager;
* "/SHiP/upstream_tagger/..." names, mirroring the calorimeter bar layers;
* sensitive-detector assignment is performed downstream by name pattern.
*
* The container envelope (half 2200 × 3200 × 80 mm, centre Z = 32 720 mm)
* is unchanged from the previous monolithic slab so the placement in
* SHiPGeometry and the subsystem-envelope consistency checks still hold.
* The container envelope (half 2200 × 3200 × 80 mm) has the same dimensions
* as the previous monolithic slab, so the subsystem-envelope consistency
* checks still hold. SHiPGeometry places it at centre Z = 32 840 mm.
*/
class UpstreamTaggerFactory {
public:
Expand Down
12 changes: 7 additions & 5 deletions tests/test_consistency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,16 +177,18 @@
double tolerance; // mm
};

// Centres as placed in SHiPGeometryBuilder::build()
// Centres as placed in SHiPGeometryBuilder::build(). The subsystems moved for
// integration layout 2026-0.1 use a 50 mm tolerance, below the smallest of
// those shifts (120 mm), so the old positions would fail the check.
std::vector<Expected> expected = {
{"/SHiP/target", 432.5, 500.0},
{"/SHiP/muon_shield", 16763.3, 500.0},
{"/SHiP/neutrino_detector", 28950.0, 500.0},
{"/SHiP/upstream_tagger", 32720.0, 500.0},
{"/SHiP/upstream_tagger", 32840.0, 50.0},

Check warning on line 187 in tests/test_consistency.cpp

View workflow job for this annotation

GitHub Actions / clang-tidy / clang-tidy

modernize-use-designated-initializers

use designated initializer list to initialize 'const value_type' (aka 'const Expected')
{"/SHiP/decay_volume", 58120.0, 500.0},
{"/SHiP/trackers", 89570.0, 500.0},
{"/SHiP/magnet", 89570.0, 500.0},
{"/SHiP/timing_detector", 95902.0, 500.0},
{"/SHiP/trackers", 89720.0, 50.0},

Check warning on line 189 in tests/test_consistency.cpp

View workflow job for this annotation

GitHub Actions / clang-tidy / clang-tidy

modernize-use-designated-initializers

use designated initializer list to initialize 'const value_type' (aka 'const Expected')
{"/SHiP/magnet", 89720.0, 50.0},

Check warning on line 190 in tests/test_consistency.cpp

View workflow job for this annotation

GitHub Actions / clang-tidy / clang-tidy

modernize-use-designated-initializers

use designated initializer list to initialize 'const value_type' (aka 'const Expected')
{"/SHiP/timing_detector", 96370.0, 50.0},

Check warning on line 191 in tests/test_consistency.cpp

View workflow job for this annotation

GitHub Actions / clang-tidy / clang-tidy

modernize-use-designated-initializers

use designated initializer list to initialize 'const value_type' (aka 'const Expected')
{"/SHiP/calorimeter", 98320.0, 500.0},
};

Expand Down
Loading