BmnRoot
Loading...
Searching...
No Matches
BmnSsdMC.cxx
Go to the documentation of this file.
1
9#include "BmnSsdMC.h"
10
11#include "TGeoBBox.h"
12#include "TGeoManager.h"
13#include "TGeoPhysicalNode.h"
14#include "TParticle.h"
15#include "TVirtualMC.h"
16#include "TVector3.h"
17#include "TKey.h"
18#include "TFile.h"
19
20#include "FairLogger.h"
21
22#include "CbmStack.h"
23#include "BmnSsdElement.h"
24#include "BmnSsdPoint.h"
25#include "BmnSsdSetup.h"
26
27using std::pair;
28using std::map;
29
30// ----- Constructor ---------------------------------------------------
31BmnSsdMC::BmnSsdMC(Bool_t active, const char* name)
32 : FairDetector(name, active, kSSD),
33 fStatusIn(),
34 fStatusOut(),
35 fEloss(0.),
36 fAddressMap(),
37 fSsdPoints(NULL),
38 fSetup(NULL),
39 fCombiTrans(NULL),
40 fProcessNeutrals(kFALSE)
41{
42}
43// -------------------------------------------------------------------------
44
45
46
47// ----- Destructor ----------------------------------------------------
49 if (fSsdPoints) {
50 fSsdPoints->Delete();
51 delete fSsdPoints;
52 }
53 if (fCombiTrans) {
54 delete fCombiTrans;
55 }
56
57}
58// -------------------------------------------------------------------------
59
60
61
62// ----- ConstructGeometry -----------------------------------------------
64
65 TString fileName = GetGeometryFileName();
66
67 // --- Only ROOT geometries are supported
68 if ( ! fileName.EndsWith(".root") ) {
69 LOG(fatal) << GetName() << ": Geometry format of file "
70 << fileName.Data() << " not supported.";
71 }
72
73 LOG(info) << "Constructing " << GetName() << " geometry from ROOT file "
74 << fileName.Data();
76}
77// -------------------------------------------------------------------------
78
79
80
81// ----- End of event action -------------------------------------------
83 Print(); // Status output
84 Reset(); // Reset the track status parameters
85}
86// -------------------------------------------------------------------------
87
88
89
90// ----- Initialise ----------------------------------------------------
92
93 // --- Instantiate the output array
94 fSsdPoints = new TClonesArray("BmnSsdPoint");
95
96 // --- Get the BmnSsdSetup instance and construct a map from full path
97 // --- to address for each sensor. This is needed to store the unique x
98 // --- address of the activated sensor in the BmnSsdPoint class.
99 // --- Unfortunately, the full geometry path (string) is the only way
100 // --- to unambiguously identify the current active node during the
101 // --- transport. It may seem that looking up a string in a map is not
102 // --- efficient. I checked however, that the performance penalty is very
103 // --- small.
104 fAddressMap.clear();
105 fSetup = BmnSsdSetup::Instance();
106 fSetup->Init();
107 Int_t nUnits = fSetup->GetNofDaughters();
108 for (Int_t iUnit = 0; iUnit < nUnits; iUnit++) {
109 BmnSsdElement* unit = fSetup->GetDaughter(iUnit);
110 Int_t nLadd = unit->GetNofDaughters();
111 for (Int_t iLadd = 0; iLadd < nLadd; iLadd++) {
112 BmnSsdElement* ladd = unit->GetDaughter(iLadd);
113 Int_t nHlad = ladd->GetNofDaughters();
114 for (Int_t iHlad = 0; iHlad < nHlad; iHlad++) {
115 BmnSsdElement* hlad = ladd->GetDaughter(iHlad);
116 Int_t nModu = hlad->GetNofDaughters();
117 for (Int_t iModu = 0; iModu < nModu; iModu++) {
118 BmnSsdElement* modu = hlad->GetDaughter(iModu);
119 Int_t nSens = modu->GetNofDaughters();
120 for (Int_t iSens = 0; iSens < nSens; iSens++) {
121 BmnSsdElement* sensor = modu->GetDaughter(iSens);
122 TString path = sensor->GetPnode()->GetName();
123 if ( ! path.BeginsWith("/") ) path.Prepend("/");
124 pair<TString, Int_t> a(path, sensor->GetAddress());
125 fAddressMap.insert(a);
126 TString test = sensor->GetPnode()->GetName();
127 }
128 }
129 }
130 }
131 }
132 LOG(info) << fName << ": Address map initialised with "
133 << Int_t(fAddressMap.size()) << " sensors. "
134 ;
135
136 // --- Call the Initialise method of the mother class
137 FairDetector::Initialize();
138}
139// -------------------------------------------------------------------------
140
141
142
143// ----- ProcessHits ----------------------------------------------------
144Bool_t BmnSsdMC::ProcessHits(FairVolume* /*vol*/) {
145
146 // --- If this is the first step for the track in the sensor:
147 // Reset energy loss and store track parameters
148 if ( gMC->IsTrackEntering() ) {
149 fEloss = 0.;
150 fStatusIn.Reset();
151 fStatusOut.Reset();
152 SetStatus(fStatusIn);
153 }
154
155 // --- For all steps within active volume: sum up differential energy loss
156 fEloss += gMC->Edep();
157
158
159 // --- If track is leaving: get track parameters and create BmnSsdPoint
160 if ( gMC->IsTrackExiting() ||
161 gMC->IsTrackStop() ||
162 gMC->IsTrackDisappeared() ) {
163
164 SetStatus(fStatusOut);
165
166 // --- No action if no energy loss (neutral particles)
167 if (fEloss == 0. && ( ! fProcessNeutrals ) ) return kFALSE;
168
169 // --- Add a SsdPoint to the output array. Increment stack counter.
170 CreatePoint();
171
172 // --- Increment number of SsdPoints for this track
173 CbmStack* stack = (CbmStack*) gMC->GetStack();
174 stack->AddPoint(kSSD);
175
176 } //? track is exiting or stopped
177
178
179 return kTRUE;
180}
181// -------------------------------------------------------------------------
182
183
184
185// ----- Reset output array and track status ---------------------------
187 fSsdPoints->Delete();
188 fStatusIn.Reset();
189 fStatusOut.Reset();
190 fEloss = 0.;
191}
192// -------------------------------------------------------------------------
193
194
195
196// ----- Screen log ----------------------------------------------------
197void BmnSsdMC::Print(Option_t* /*opt*/) const {
198 //Int_t nHits = fSsdPoints->GetEntriesFast();
199 LOG(info) << fName << ": " << fSsdPoints->GetEntriesFast()
200 << " points registered in this event.";
201}
202// -------------------------------------------------------------------------
203
204
205
206// =========================================================================
207// Private methods
208// =========================================================================
209
210
211// ----- Create SSD point ----------------------------------------------
212BmnSsdPoint* BmnSsdMC::CreatePoint() {
213
214 // --- Check detector address
215 if ( fStatusIn.fAddress != fStatusOut.fAddress ) {
216 LOG(error) << GetName() << ": inconsistent detector addresses "
217 << fStatusIn.fAddress << " " << fStatusOut.fAddress
218 ;
219 return NULL;
220 }
221
222 // --- Check track Id
223 if ( fStatusIn.fTrackId != fStatusOut.fTrackId ) {
224 LOG(error) << GetName() << ": inconsistent track Id "
225 << fStatusIn.fTrackId << " " << fStatusOut.fTrackId
226 ;
227 return NULL;
228 }
229
230 // --- Check track PID
231 if ( fStatusIn.fPid != fStatusOut.fPid ) {
232 LOG(error) << GetName() << ": inconsistent track PID "
233 << fStatusIn.fPid << " " << fStatusOut.fPid
234 ;
235 return NULL;
236 }
237
238 // --- Entry position and momentum
239 TVector3 posIn(fStatusIn.fX, fStatusIn.fY, fStatusIn.fZ);
240 TVector3 momIn(fStatusIn.fPx, fStatusIn.fPy, fStatusIn.fPz);
241
242 // --- Exit position and momentum
243 TVector3 posOut(fStatusOut.fX, fStatusOut.fY, fStatusOut.fZ);
244 TVector3 momOut(fStatusOut.fPx, fStatusOut.fPy, fStatusOut.fPz);
245
246 // --- Time and track length (average between in and out)
247 Double_t time = 0.5 * ( fStatusIn.fTime + fStatusOut.fTime );
248 Double_t length = 0.5 * ( fStatusIn.fLength + fStatusOut.fLength);
249
250 // --- Flag for entry/exit
251 Int_t flag = 0;
252 if ( fStatusIn.fFlag ) flag += 1; // first coordinate is entry step
253 if ( fStatusOut.fFlag ) flag += 2; // second coordinate is exit step
254
255 // --- Debug output
256 LOG(debug2) << GetName() << ": Creating point from track "
257 << fStatusIn.fTrackId << " in sensor "
258 << fStatusIn.fAddress << ", position (" << posIn.X()
259 << ", " << posIn.Y() << ", " << posIn.Z()
260 << "), energy loss " << fEloss;
261
262 // --- Add new point to output array
263 Int_t newIndex = fSsdPoints->GetEntriesFast();
264 return new ( (*fSsdPoints)[fSsdPoints->GetEntriesFast()] )
265 BmnSsdPoint(fStatusIn.fTrackId, fStatusIn.fAddress, posIn, posOut,
266 momIn, momOut, time, length, fEloss, fStatusIn.fPid, 0,
267 newIndex, flag);
268
269}
270// -------------------------------------------------------------------------
271
272
273
274// ----- Set the current track status ----------------------------------
275void BmnSsdMC::SetStatus(BmnSsdTrackStatus& status) {
276
277 // --- Check for TVirtualMC and TGeomanager
278 if ( ! (gMC && gGeoManager) ) {
279 LOG(error) << fName << ": No TVirtualMC or TGeoManager instance!"
280 ;
281 return;
282 }
283
284 // --- Address of current sensor
285 // --- Use the geometry path from TVirtualMC; cannot rely on
286 // --- TGeoManager here.
287 TString path = gMC->CurrentVolPath();
288
289 auto it = fAddressMap.find(path);
290 if ( it == fAddressMap.end() ) {
291 LOG(fatal) << fName << ": Path not found in address map! "
292 << gGeoManager->GetPath();
293 status.fAddress = 0;
294 }
295 else status.fAddress = it->second;
296
297 // --- Index and PID of current track
298 status.fTrackId = gMC->GetStack()->GetCurrentTrackNumber();
299 status.fPid = gMC->GetStack()->GetCurrentTrack()->GetPdgCode();
300
301 // --- Position
302 gMC->TrackPosition(status.fX, status.fY, status.fZ);
303
304 // --- Momentum
305 Double_t dummy;
306 gMC->TrackMomentum(status.fPx, status.fPy, status.fPz, dummy);
307
308 // --- Time and track length
309 status.fTime = gMC->TrackTime() * 1.e9; // conversion into ns
310 status.fLength = gMC->TrackLength();
311
312 // --- Status flag (entry/exit or new/stopped/disappeared)
313 if ( gMC->IsTrackEntering() ) {
314 if ( gMC->IsNewTrack() ) status.fFlag = kFALSE; // Track created in sensor
315 else status.fFlag = kTRUE; // Track entering
316 }
317 else { // exiting or stopped or disappeared
318 if ( gMC->IsTrackDisappeared() || gMC->IsTrackStop() )
319 status.fFlag = kFALSE; // Track stopped or disappeared in sensor
320 else
321 status.fFlag = kTRUE; // Track exiting
322 }
323}
324// -------------------------------------------------------------------------
325
326//__________________________________________________________________________
328{
329 if( IsNewGeometryFile(fgeoName) ) {
330 TGeoVolume *module1 = TGeoVolume::Import(fgeoName);
331
332 gGeoManager->GetTopVolume()->AddNode(module1, 0, fCombiTrans);
333 TGeoNode* node = module1->GetNode(0);
334 ExpandSsdNodes(node);
335// ExpandNode(node); // Destroys something in the geometry. TODO: find the reason
336 } else {
337 FairModule::ConstructRootGeometry();
338 }
339}
340
341void BmnSsdMC::ExpandSsdNodes(TGeoNode* fN)
342{
343/*
344 TGeoMatrix* Matrix =fN->GetMatrix();
345 if(gGeoManager->GetListOfMatrices()->FindObject(Matrix)) { gGeoManager->GetListOfMatrices()->Remove(Matrix); }
346*/
347 TGeoVolume* v1=fN->GetVolume();
348 TObjArray* NodeList=v1->GetNodes();
349 for (Int_t Nod=0; Nod<NodeList->GetEntriesFast(); Nod++) {
350 TGeoNode* fNode =(TGeoNode*)NodeList->At(Nod);
351// TGeoMatrix* M =fNode->GetMatrix();
352 //M->SetDefaultName();
353// SetDefaultMatrixName(M);
354
355 if(fNode->GetNdaughters()>0) { ExpandSsdNodes(fNode); }
356 TGeoVolume* v= fNode->GetVolume();
357// AssignMediumAtImport(v);
358// if (!gGeoManager->FindVolumeFast(v->GetName())) {
359// LOG(debug2)<<"Register Volume " << v->GetName();
360// v->RegisterYourself();
361// }
362 if ( (this->InheritsFrom("FairDetector")) && CheckIfSensitive(v->GetName())) {
363 // LOG(info)<<"Sensitive Volume "<< v->GetName();
364 AddSensitiveVolume(v);
365 }
366 }
367
368}
369
370Bool_t BmnSsdMC::IsNewGeometryFile(TString /*filename*/)
371{
372
373 TFile* f=new TFile(fgeoName);
374 TList* l = f->GetListOfKeys();
375 Int_t numKeys = l->GetSize();
376 if ( 2 != numKeys) {
377 LOG(info) << "Not exactly two keys in the file. File is not of new type."
378 ;
379 return kFALSE;
380 }
381 TKey* key;
382 TIter next( l);
383 Bool_t foundGeoVolume = kFALSE;
384 Bool_t foundGeoMatrix = kFALSE;
385 TGeoTranslation* trans = NULL;
386 TGeoRotation* rot = NULL;
387 while ((key = (TKey*)next())) {
388 if (strcmp(key->GetClassName(),"TGeoVolume") == 0) {
389 LOG(debug) << "Found TGeoVolume in geometry file.";
390 foundGeoVolume = kTRUE;
391 continue;
392 }
393 if (strcmp(key->GetClassName(),"TGeoTranslation") == 0) {
394 LOG(debug) << "Found TGeoTranslation in geometry file.";
395 foundGeoMatrix = kTRUE;
396 trans = static_cast<TGeoTranslation*>(key->ReadObj());
397 rot = new TGeoRotation();
398 fCombiTrans = new TGeoCombiTrans(*trans, *rot);
399 continue;
400 }
401 if (strcmp(key->GetClassName(),"TGeoRotation") == 0) {
402 LOG(debug) << "Found TGeoRotation in geometry file.";
403 foundGeoMatrix = kTRUE;
404 trans = new TGeoTranslation();
405 rot = static_cast<TGeoRotation*>(key->ReadObj());
406 fCombiTrans = new TGeoCombiTrans(*trans, *rot);
407 continue;
408 }
409 if (strcmp(key->GetClassName(),"TGeoCombiTrans") == 0) {
410 LOG(debug) << "Found TGeoCombiTrans in geometry file.";
411 foundGeoMatrix = kTRUE;
412 fCombiTrans = static_cast<TGeoCombiTrans*>(key->ReadObj());
413 continue;
414 }
415 }
416 if ( foundGeoVolume && foundGeoMatrix ) {
417 return kTRUE;
418 } else {
419 if ( !foundGeoVolume) {
420 LOG(info) << "No TGeoVolume found in geometry file. File is not of new type.";
421 }
422 if ( !foundGeoMatrix) {
423 LOG(info) << "Not TGeoMatrix derived object found in geometry file. File is not of new type.";
424 }
425 return kFALSE;
426 }
427}
__m128 v
Definition P4_F32vec4.h:1
float f
Definition P4_F32vec4.h:21
@ kSSD
Class representing an element of the SSD setup.
Int_t GetAddress() const
Int_t GetNofDaughters() const
BmnSsdElement * GetDaughter(Int_t index) const
TGeoPhysicalNode * GetPnode() const
virtual ~BmnSsdMC()
Definition BmnSsdMC.cxx:48
virtual void EndOfEvent()
Action at end of event.
Definition BmnSsdMC.cxx:82
void ExpandSsdNodes(TGeoNode *fN)
Definition BmnSsdMC.cxx:341
virtual Bool_t ProcessHits(FairVolume *vol=0)
Action for a track step in a sensitive node of the SSD.
Definition BmnSsdMC.cxx:144
virtual void ConstructGeometry()
Construct the SSD geometry in the TGeoManager.
Definition BmnSsdMC.cxx:63
virtual Bool_t CheckIfSensitive(std::string name)
Check whether a volume is sensitive.
Definition BmnSsdMC.h:58
virtual void Print(Option_t *opt="") const
Screen log Prints current number of SsdPoints in array. Virtual from TObject.
Definition BmnSsdMC.cxx:197
virtual void Reset()
Clear output array and reset current track status.
Definition BmnSsdMC.cxx:186
virtual void Initialize()
Initialisation.
Definition BmnSsdMC.cxx:91
virtual void ConstructRootGeometry()
Definition BmnSsdMC.cxx:327
BmnSsdMC(Bool_t active=kTRUE, const char *name="SSDMC")
Definition BmnSsdMC.cxx:31
static BmnSsdSetup * Instance()
Bool_t Init(const char *geometryFile=nullptr, const char *sensorParameterFile=nullptr)
Initialise the setup.
Stores status of track during transport. Auxiliary for BmnSsd.
Double_t fPy
Momentum x component [GeV].
Double_t fX
x position [cm]
Int_t fAddress
Unique address.
Double_t fY
x position [cm]
Double_t fPz
Momentum x component [GeV].
Bool_t fFlag
Status flag. TRUE if normal entry/exit, else FALSE.
Int_t fPid
MCTrack PID [PDG code].
Double_t fZ
x position [cm]
Double_t fLength
Length since track creation [cm].
Int_t fTrackId
MCTrack index.
Double_t fTime
Time since track creation [ns].
Double_t fPx
Momentum x component [GeV].
void AddPoint(DetectorId iDet)
Definition CbmStack.cxx:351