Use this file to discover all available pages before exploring further.
The Scattering and Neutrino Detector (SND) is positioned between the muon shield exit and the upstream entrance of the decay vessel. Its primary physics goals are to detect and measure neutrino interactions — especially from tau-neutrinos — and to search for hidden-particle scattering signatures that leave short tracks inside a dense target. SND comprises several complementary sub-systems, each addressing a different part of the physics programme. The sub-system configuration is selected by the --SND_design flag at simulation time, and the full set of geometry parameters is driven by YAML files read at runtime. This page describes all four sub-systems — NuTauTarget, nuTauTT, SiliconTarget, and MTC — together with their C++ classes, Python digitisers, and key geometry parameters.
# Enable SND with the default design (design 2: MTC + SiliconTarget)python macro/run_simScript.py --SND --SND_design 2# Enable SND with the emulsion-based designpython macro/run_simScript.py --SND --SND_design 1# Enable both designs in the same simulationpython macro/run_simScript.py --SND --SND_design all
In geometry_config.py, SND_design is always stored as a list so multiple designs can coexist:
def create_config(SND: bool = True, SND_design=None, ...): if SND_design is None: SND_design = [2] if not isinstance(SND_design, list): SND_design = [SND_design] c.SND_design = SND_design
The configure() function in python/shipDet_conf.py iterates over this list and calls the appropriate configuration function for each design number:
for design in ship_geo.SND_design: if design == 2: configure_snd_mtc(...) configure_snd_siliconTarget(...) elif design == 1: configure_snd_old(...) else: print(f"Warning: SND design {design} is not recognized.")
Design 1 implements the classic OPERA-style emulsion brick target interleaved with SciFi tracking planes. It is configured by configure_snd_old() in python/shipDet_conf.py, which reads geometry/snd_config_old.yaml.
Located in SND/EmulsionTarget/Target.h. The target is a wall of emulsion bricks, each brick consisting of alternating lead and emulsion film plates inside a protective plastic wrapping.
The MTC (MTCDetector, SND/MTC/MTCDetector.h) is a SciFi + scintillator spectrometer placed at the downstream end of the muon shield. It is designed to reconstruct the charge and momentum of muons from charm decays. Configuration is read from geometry/MTC_config.yaml.
mtc = ROOT.MTCDetector("MTC", ROOT.kTRUE)mtc.SetMTCParameters( ship_geo.mtc_geo.width, ship_geo.mtc_geo.height, ship_geo.mtc_geo.angle, # stereo angle of SciFi planes ship_geo.mtc_geo.ironThick, # iron absorber thickness per layer ship_geo.mtc_geo.sciFiThick, # SciFi plane thickness ship_geo.mtc_geo.num_of_agg_channels, ship_geo.mtc_geo.scint_cell_size, ship_geo.mtc_geo.scintThick, # scintillator plane thickness ship_geo.mtc_geo.nLayers, # total number of layers ship_geo.mtc_geo.zPosition, # z-centre of MTC ship_geo.mtc_geo.fieldY, # magnetic field Bfield in y)
When zPosition == "auto", the MTC is placed at the centre of the last muon-shield magnet:
python/detectors/MTCDetector.py inherits from BaseDetector. It reads MTCDetPoint MC hits, maps SiPM channels to SciFi fibres using SciFiMapping, and produces MTCDetHit objects. A fibre ID example:
fiberID = 123051820 → 1: MTC unique detector ID → 23: layer number → 0: station type (0 = +5°, 1 = −5°, 2 = scintillator plane) → 5: z-layer number (0–5) → 1820: fibre index within the layer
The MTC also notifies the muon shield that space must be reserved for it:
The SiliconTarget (SND/SiliconTarget/SiliconTarget.h) provides silicon strip tracking as an alternative to emulsion bricks for precision vertexing. It is placed slightly upstream of the MTC. Configuration is read from geometry/SiliconTarget_config.yaml.
The timing detector is closely associated with the SND readout for track-to-vertex association. The TimeDet class (TimeDet/TimeDet.h) builds two orthogonal scintillator bar layers. Its Python digitiser timeDetector (python/detectors/timeDetector.py) converts TimeDetPoint MC hits to TimeDetHit objects, selecting the earliest valid hit per bar cell:
# python/detectors/timeDetector.py (excerpt)class timeDetector(BaseDetector): def digitize(self) -> None: earliest_per_det_id = {} for index, point in enumerate(self.intree.TimeDetPoint): hit = ROOT.TimeDetHit(point, self.intree.t0) self.det.push_back(hit) if hit.isValid(): detector_id = hit.GetDetectorID() if detector_id in earliest_per_det_id: times = hit.GetMeasurements() earliest = earliest_per_det_id[detector_id] ref_times = self.det[earliest].GetMeasurements() if ref_times[0] > times[0] or ref_times[1] > times[1]: self.det[earliest].setInvalid() earliest_per_det_id[detector_id] = index else: self.det[index].setInvalid() else: earliest_per_det_id[detector_id] = index
TimeDet geometry parameters from geometry_config.py:
SND/├── EmulsionTarget/│ ├── Target.h / Target.cxx ← NuTauTarget geometry (design 1)│ ├── TargetTracker.h / .cxx ← nuTauTT SciFi tracker (design 1)│ ├── TargetPoint.h / .cxx ← MC hit point for target│ └── TTPoint.h / .cxx ← MC hit point for tracker├── MTC/│ ├── MTCDetector.h / MTCDetector.cxx ← MTC geometry (design 2)│ ├── MTCDetPoint.h / .cxx ← MC hit point│ └── MTCDetHit.h / .cxx ← digitised hit└── SiliconTarget/ ├── SiliconTarget.h / .cxx ← Si strip tracker (design 2) ├── SiliconTargetPoint.h / .cxx ← MC hit point └── SiliconTargetHit.h / .cxx ← digitised hit
The YAML configuration files for all SND sub-systems are stored under $FAIRSHIP/geometry/: snd_config_old.yaml (design 1), MTC_config.yaml (design 2 MTC), and SiliconTarget_config.yaml (design 2 silicon). These files must be present at runtime; the code opens them with open(yaml_file) and raises FileNotFoundError if they are missing.