@@ -59,6 +59,40 @@ void Detector::InitializeO2Detector()
5959{
6060 // register the sensitive volumes with FairRoot
6161 defineSensitiveVolumes ();
62+ buildVolumeIdTables ();
63+ }
64+
65+ void Detector::buildVolumeIdTables ()
66+ {
67+ auto * vmc = TVirtualMC::GetMC ();
68+ const int nVols = vmc->NofVolumes () + 1 ;
69+ mRegionByVolId .assign (nVols, kNotSensitive );
70+ mChamberByVolId .assign (nVols, -1 );
71+ mSectorByVolId .assign (nVols, -1 );
72+
73+ auto record = [nVols](std::vector<int8_t >& table, int vid, int8_t value, const char * what) {
74+ if (vid <= 0 || vid >= nVols) {
75+ LOG (fatal) << " TRD volume " << what << " has no usable volume id (" << vid << " )" ;
76+ }
77+ table[vid] = value;
78+ };
79+
80+ // The drift and amplification gas volumes, distinguished by the second character of
81+ // their name exactly as Geometry::createVolume selects them as sensitive.
82+ for (const auto & name : mGeom ->getSensitiveTRDVolumes ()) {
83+ record (mRegionByVolId , vmc->VolId (name.c_str ()), name[1 ] == ' J' ? kDrift : kAmplification , name.c_str ());
84+ }
85+
86+ // The readout-chamber assemblies and the supermodule mother volumes
87+ char volName[16 ];
88+ for (int idet = 0 ; idet < NLAYER * NSTACK ; ++idet) {
89+ snprintf (volName, sizeof (volName), " UT%02d" , idet);
90+ record (mChamberByVolId , vmc->VolId (volName), idet, volName);
91+ }
92+ for (int sector = 0 ; sector < NSECTOR ; ++sector) {
93+ snprintf (volName, sizeof (volName), " BTRD%d" , sector);
94+ record (mSectorByVolId , vmc->VolId (volName), sector, volName);
95+ }
6296}
6397
6498void Detector::InitializeParams ()
@@ -89,35 +123,46 @@ bool Detector::ProcessHits(FairVolume* v)
89123 fMC ->SetMaxStep (mMaxMCStepDef ); // Should we optimize this value?
90124
91125 // Inside sensitive volume ?
92- bool drRegion = false ;
93- bool amRegion = false ;
94- char idRegion;
95- int cIdChamber;
96- int r1 = std::sscanf (fMC ->CurrentVolName (), " U%c%d" , &idRegion, &cIdChamber);
97- if (r1 != 2 ) {
98- LOG (fatal) << " Something went wrong with the geometry volume name " << fMC ->CurrentVolName ();
99- }
100- if (idRegion == ' J' ) {
101- drRegion = true ;
102- } else if (idRegion == ' K' ) {
103- amRegion = true ;
104- } else {
126+ int copy = 0 ;
127+ const int vid = fMC ->CurrentVolID (copy);
128+ const int8_t region = (vid > 0 && vid < (int )mRegionByVolId .size ()) ? mRegionByVolId [vid] : kNotSensitive ;
129+ if (region == kNotSensitive ) {
105130 return false ;
106131 }
107-
108- const int idChamber = mGeom ->getDetectorSec (cIdChamber);
109- if (idChamber < 0 || idChamber > 29 ) {
110- LOG (fatal) << " Chamber ID out of bounds" ;
132+ const bool drRegion = (region == kDrift );
133+ const bool amRegion = (region == kAmplification );
134+
135+ // Find how far up the chamber and the supermodule sit, once, by walking up until the
136+ // ancestor's volume id is one we know. Hard-coding the depth breaks silently whenever a
137+ // level is added, removed, or flattened away by the transport engine's own conversion.
138+ if (mSectorOffset < 0 ) {
139+ for (int off = 0 ; off < 16 ; ++off) {
140+ const int oid = fMC ->CurrentVolOffID (off, copy);
141+ if (oid <= 0 || oid >= (int )mChamberByVolId .size ()) {
142+ continue ;
143+ }
144+ if (mChamberOffset < 0 && mChamberByVolId [oid] >= 0 ) {
145+ mChamberOffset = off;
146+ }
147+ if (mSectorByVolId [oid] >= 0 ) {
148+ mSectorOffset = off;
149+ break ;
150+ }
151+ }
152+ if (mChamberOffset < 0 || mSectorOffset < 0 ) {
153+ LOG (fatal) << " No TRD chamber/supermodule ancestor above sensitive volume " << fMC ->CurrentVolName ();
154+ }
155+ LOG (info) << " TRD: chamber at mother offset " << mChamberOffset << " , supermodule at " << mSectorOffset ;
111156 }
112157
113- int sector;
114- int r2 = std::sscanf (fMC ->CurrentVolOffName (7 ), " BTRD%d" , §or);
115- if (r2 != 1 ) {
116- LOG (fatal) << " Something went wrong with the geometry volume name " << fMC ->CurrentVolOffName (7 );
117- }
118- if (sector < 0 || sector >= NSECTOR ) {
119- LOG (fatal) << " Sector out of bounds" ;
158+ const int chamberVol = fMC ->CurrentVolOffID (mChamberOffset , copy);
159+ const int sectorVol = fMC ->CurrentVolOffID (mSectorOffset , copy);
160+ const int idChamber = (chamberVol > 0 && chamberVol < (int )mChamberByVolId .size ()) ? mChamberByVolId [chamberVol] : -1 ;
161+ const int sector = (sectorVol > 0 && sectorVol < (int )mSectorByVolId .size ()) ? mSectorByVolId [sectorVol] : -1 ;
162+ if (idChamber < 0 || sector < 0 ) {
163+ LOG (fatal) << " Cannot resolve TRD chamber/supermodule from volume " << fMC ->CurrentVolName ();
120164 }
165+
121166 // The detector number (0 - 539)
122167 int det = mGeom ->getDetector (mGeom ->getLayer (idChamber), mGeom ->getStack (idChamber), sector);
123168 if (det < 0 || det >= MAXCHAMBER ) {
0 commit comments