SND@LHC Software
Loading...
Searching...
No Matches
ShipStack.cxx
Go to the documentation of this file.
1// -------------------------------------------------------------------------
2// ----- ShipStack source file -----
3// -------------------------------------------------------------------------
4#include "ShipStack.h"
5
6#include "FairDetector.h" // for FairDetector
7#include "FairLink.h" // for FairLink
8#include "FairMCPoint.h" // for FairMCPoint
9#include "ShipMCTrack.h" // for ShipMCTrack
10#include "FairRootManager.h" // for FairRootManager
11#include "FairLogger.h" // for FairLogger, MESSAGE_ORIGIN
12
13#include <iosfwd> // for ostream
14#include "TClonesArray.h" // for TClonesArray
15#include "TIterator.h" // for TIterator
16#include "TLorentzVector.h" // for TLorentzVector
17#include "TParticle.h" // for TParticle
18#include "TRefArray.h" // for TRefArray
19
20#include <stddef.h> // for NULL
21#include <iostream> // for operator<<, etc
22
23using std::cout;
24using std::endl;
25using std::pair;
26
27
28// ----- Default constructor -------------------------------------------
30 : FairGenericStack(),
31 fStack(),
32 fParticles(new TClonesArray("TParticle", size)),
33 fTracks(new TClonesArray("ShipMCTrack", size)),
34 fStoreMap(),
35 fStoreIter(),
36 fIndexMap(),
37 fIndexIter(),
38 fPointsMap(),
39 fCurrentTrack(-1),
40 fNPrimaries(0),
41 fNParticles(0),
42 fNTracks(0),
43 fIndex(0),
44 fStoreSecondaries(kTRUE),
45 fMinPoints(1),
46 fEnergyCut(0.),
47 fStoreMothers(kTRUE)
48{
49}
50
51// -------------------------------------------------------------------------
52
53
54
55// ----- Destructor ----------------------------------------------------
57{
58 if (fParticles) {
59 fParticles->Delete();
60 delete fParticles;
61 }
62 if (fTracks) {
63 fTracks->Delete();
64 delete fTracks;
65 }
66}
67// -------------------------------------------------------------------------
68
69void ShipStack::PushTrack(Int_t toBeDone, Int_t parentId, Int_t pdgCode,
70 Double_t px, Double_t py, Double_t pz,
71 Double_t e, Double_t vx, Double_t vy, Double_t vz,
72 Double_t time, Double_t polx, Double_t poly,
73 Double_t polz, TMCProcess proc, Int_t& ntr,
74 Double_t weight, Int_t is)
75{
76
77 PushTrack( toBeDone, parentId, pdgCode,
78 px, py, pz,
79 e, vx, vy, vz,
80 time, polx, poly,
81 polz, proc, ntr,
82 weight, is, -1);
83}
84
85
86
87// ----- Virtual public method PushTrack -------------------------------
88void ShipStack::PushTrack(Int_t toBeDone, Int_t parentId, Int_t pdgCode,
89 Double_t px, Double_t py, Double_t pz,
90 Double_t e, Double_t vx, Double_t vy, Double_t vz,
91 Double_t time, Double_t polx, Double_t poly,
92 Double_t polz, TMCProcess proc, Int_t& ntr,
93 Double_t weight, Int_t is, Int_t secondparentID)
94{
95 // cout << "ShipStack: " << fNParticles << " " << pdgCode << " " << parentId << " " << secondparentID<<" "<<proc<< endl;
96
97 // --> Get TParticle array
98 TClonesArray& partArray = *fParticles;
99
100 // --> Create new TParticle and add it to the TParticle array
101 Int_t trackId = fNParticles;
102 Int_t nPoints = 0;
103 Int_t daughter1Id = -1;
104 Int_t daughter2Id = -1;
105 TParticle* particle =
106 new(partArray[fNParticles++]) TParticle(pdgCode, trackId, parentId,nPoints,
107 daughter1Id, daughter2Id, px, py, pz, e, vx, vy, vz, time);
108// from root, how does this fit ? misuse of status and mother2 ??? status is used for trackID definetely
109// TParticle(Int_t pdg, Int_t status, Int_t mother1, Int_t mother2,
110// Int_t daughter1, Int_t daughter2, Double_t px, Double_t py, Double_t pz, Double_t etot, Double_t vx, Double_t vy, Double_t vz, Double_t time)
111 particle->SetPolarisation(polx, poly, polz);
112 particle->SetWeight(weight);
113 particle->SetUniqueID(proc);
114// TR August 2014, still trying to understand the logic of FairRoot, due to misuse of secondparentID, all is a big mess
115 if (parentId < 0){
116 particle->SetFirstMother(secondparentID);
117 particle->SetLastMother(secondparentID);
118 }
119 else {
120 particle->SetFirstMother(parentId);
121 particle->SetLastMother(parentId);
122 }
123 // --> Increment counter
124 if (parentId < 0) { fNPrimaries++; }
125
126 // --> Set argument variable
127 ntr = trackId;
128
129 // --> Push particle on the stack if toBeDone is set
130 if (toBeDone == 1) {
131 particle->SetBit(kDoneBit);
132 fStack.push(particle);
133 }
134
135}
136// -------------------------------------------------------------------------
137
138
139
140// ----- Virtual method PopNextTrack -----------------------------------
141TParticle* ShipStack::PopNextTrack(Int_t& iTrack)
142{
143
144 // If end of stack: Return empty pointer
145 if (fStack.empty()) {
146 iTrack = -1;
147 return NULL;
148 }
149
150 // If not, get next particle from stack
151 TParticle* thisParticle = fStack.top();
152 fStack.pop();
153
154 if ( !thisParticle) {
155 iTrack = 0;
156 return NULL;
157 }
158
159 fCurrentTrack = thisParticle->GetStatusCode();
160 iTrack = fCurrentTrack;
161
162 return thisParticle;
163
164}
165// -------------------------------------------------------------------------
166
167
168
169// ----- Virtual method PopPrimaryForTracking --------------------------
170TParticle* ShipStack::PopPrimaryForTracking(Int_t iPrim)
171{
172
173 // Get the iPrimth particle from the fStack TClonesArray. This
174 // should be a primary (if the index is correct).
175
176 // Test for index
177 if (iPrim < 0 || iPrim >= fNPrimaries) {
178 LOGF(fatal, "ShipStack: Primary index out of range! %i ", iPrim);
179 }
180
181 // Return the iPrim-th TParticle from the fParticle array. This should be
182 // a primary.
183 TParticle* part = (TParticle*)fParticles->At(iPrim);
184 /* do not understand the logic behind this !!! TR July 2014
185 if ( ! (part->GetMother(0) < 0) ) {
186 fLogger->Fatal(MESSAGE_ORIGIN, "ShipStack:: Not a primary track! %i ",iPrim);
187 Fatal("ShipStack::PopPrimaryForTracking", "Not a primary track");
188 }*/
189 if(!part->TestBit(kDoneBit)) return NULL;
190 else return part;
191
192}
193// -------------------------------------------------------------------------
194
195
196
197// ----- Virtual public method GetCurrentTrack -------------------------
199{
200 TParticle* currentPart = GetParticle(fCurrentTrack);
201 if ( ! currentPart) {
202 LOG(warn) << "ShipStack: Current track not found in stack!";
203 }
204 return currentPart;
205}
206// -------------------------------------------------------------------------
207
208
209
210// ----- Public method AddParticle -------------------------------------
211void ShipStack::AddParticle(TParticle* oldPart)
212{
213 TClonesArray& array = *fParticles;
214 TParticle* newPart = new(array[fIndex]) TParticle(*oldPart);
215 newPart->SetWeight(oldPart->GetWeight());
216 newPart->SetUniqueID(oldPart->GetUniqueID());
217 fIndex++;
218}
219// -------------------------------------------------------------------------
220
221
222
223// ----- Public method FillTrackArray ----------------------------------
225{
226
227 LOG(DEBUG) << "ShipStack: Filling MCTrack array...";
228
229 // --> Reset index map and number of output tracks
230 fIndexMap.clear();
231 fNTracks = 0;
232
233 // --> Check tracks for selection criteria
234 SelectTracks();
235
236 // --> Loop over fParticles array and copy selected tracks
237 for (Int_t iPart=0; iPart<fNParticles; iPart++) {
238
239 fStoreIter = fStoreMap.find(iPart);
240 if (fStoreIter == fStoreMap.end() ) {
241 LOGF(fatal, "ShipStack: Particle %i not found in storage map! ", iPart);
242 }
243 Bool_t store = (*fStoreIter).second;
244
245 if (store) {
246 ShipMCTrack* track =
247 new( (*fTracks)[fNTracks]) ShipMCTrack(GetParticle(iPart));
248 fIndexMap[iPart] = fNTracks;
249 // --> Set the number of points in the detectors for this track
250 for (Int_t iDet = kEmulsionDet; iDet < kEndOfList; iDet++) {
251 pair<Int_t, Int_t> a(iPart, iDet);
252 track->SetNPoints(iDet, fPointsMap[a]);
253 }
254 fNTracks++;
255 } else { fIndexMap[iPart] = -2; }
256
257 }
258
259 // --> Map index for primary mothers
260 fIndexMap[-1] = -1;
261
262 // --> Screen output
263 //Print(1);
264
265}
266// -------------------------------------------------------------------------
267
268
269
270// ----- Public method UpdateTrackIndex --------------------------------
271void ShipStack::UpdateTrackIndex(TRefArray* detList)
272{
273
274 LOG(DEBUG) << "ShipStack: Updating track indizes...";
275 Int_t nColl = 0;
276
277 // First update mother ID in MCTracks
278 for (Int_t i=0; i<fNTracks; i++) {
279 ShipMCTrack* track = (ShipMCTrack*)fTracks->At(i);
280 Int_t iMotherOld = track->GetMotherId();
281 fIndexIter = fIndexMap.find(iMotherOld);
282 if (fIndexIter == fIndexMap.end()) {
283 LOGF(fatal, "ShipStack: Particle index %i not found in dex map! ", iMotherOld);
284 }
285 track->SetMotherId( (*fIndexIter).second );
286 }
287
288
289 if(fDetList==0) {
290 // Now iterate through all active detectors
291 fDetIter = detList->MakeIterator();
292 fDetIter->Reset();
293 } else {
294 fDetIter->Reset();
295 }
296
297 FairDetector* det = NULL;
298 while( (det = (FairDetector*)fDetIter->Next() ) ) {
299
300
301 // --> Get hit collections from detector
302 Int_t iColl = 0;
303 TClonesArray* hitArray;
304 while ( (hitArray = det->GetCollection(iColl++)) ) {
305 nColl++;
306 Int_t nPoints = hitArray->GetEntriesFast();
307
308 // --> Update track index for all MCPoints in the collection
309 for (Int_t iPoint=0; iPoint<nPoints; iPoint++) {
310 FairMCPoint* point = (FairMCPoint*)hitArray->At(iPoint);
311 Int_t iTrack = point->GetTrackID();
312
313 fIndexIter = fIndexMap.find(iTrack);
314 if (fIndexIter == fIndexMap.end()) {
315 LOGF(fatal, "ShipStack: Particle index %i not found in index map! ", iTrack);
316 }
317 point->SetTrackID((*fIndexIter).second);
318 point->SetLink(FairLink("MCTrack", (*fIndexIter).second));
319 }
320
321 } // Collections of this detector
322 } // List of active detectors
323 LOGF(debug, "...stack and %i collections updated.", nColl);
324}
325// -------------------------------------------------------------------------
326
327
328
329// ----- Public method Reset -------------------------------------------
331{
332 fIndex = 0;
333 fCurrentTrack = -1;
335 while (! fStack.empty() ) { fStack.pop(); }
336 fParticles->Clear();
337 fTracks->Clear();
338 fPointsMap.clear();
339}
340// -------------------------------------------------------------------------
341
342
343
344// ----- Public method Register ----------------------------------------
346{
347 FairRootManager::Instance()->Register("MCTrack", "Stack", fTracks,kTRUE);
348}
349// -------------------------------------------------------------------------
350
351
352
353// ----- Public method Print --------------------------------------------
354void ShipStack::Print(Int_t iVerbose) const
355{
356 cout << "-I- ShipStack: Number of primaries = "
357 << fNPrimaries << endl;
358 cout << " Total number of particles = "
359 << fNParticles << endl;
360 cout << " Number of tracks in output = "
361 << fNTracks << endl;
362 if (iVerbose) {
363 for (Int_t iTrack=0; iTrack<fNTracks; iTrack++) {
364 ((ShipMCTrack*) fTracks->At(iTrack))->Print(iTrack);
365 }
366 }
367}
368// -------------------------------------------------------------------------
369
370
371
372// ----- Public method AddPoint (for current track) --------------------
374{
375 Int_t iDet = detId;
376// cout << "Add point for Detektor" << iDet << endl;
377 pair<Int_t, Int_t> a(fCurrentTrack, iDet);
378 if ( fPointsMap.find(a) == fPointsMap.end() ) { fPointsMap[a] = 1; }
379 else { fPointsMap[a]++; }
380}
381// -------------------------------------------------------------------------
382
383
384
385// ----- Public method AddPoint (for arbitrary track) -------------------
386void ShipStack::AddPoint(DetectorId detId, Int_t iTrack)
387{
388 if ( iTrack < 0 ) { return; }
389 Int_t iDet = detId;
390 pair<Int_t, Int_t> a(iTrack, iDet);
391 if ( fPointsMap.find(a) == fPointsMap.end() ) { fPointsMap[a] = 1; }
392 else { fPointsMap[a]++; }
393}
394// -------------------------------------------------------------------------
395
396
397
398
399// ----- Virtual method GetCurrentParentTrackNumber --------------------
401{
402 TParticle* currentPart = GetCurrentTrack();
403 if ( currentPart ) { return currentPart->GetFirstMother(); }
404 else { return -1; }
405}
406// -------------------------------------------------------------------------
407
408
409
410// ----- Public method GetParticle -------------------------------------
411TParticle* ShipStack::GetParticle(Int_t trackID) const
412{
413 if (trackID < 0 || trackID >= fNParticles) {
414 LOGF(fatal, "ShipStack: Particle index %i out of range. Max=%i", trackID, fNParticles);
415 }
416 return (TParticle*)fParticles->At(trackID);
417}
418// -------------------------------------------------------------------------
419
420
421
422// ----- Private method SelectTracks -----------------------------------
424{
425
426 // --> Clear storage map
427 fStoreMap.clear();
428
429 // --> Check particles in the fParticle array
430 for (Int_t i=0; i<fNParticles; i++) {
431
432 TParticle* thisPart = GetParticle(i);
433 Bool_t store = kTRUE;
434
435 // --> Get track parameters
436 Int_t iMother = thisPart->GetMother(0);
437 TLorentzVector p;
438 thisPart->Momentum(p);
439 Double_t energy = p.E();
440 Double_t mass = p.M();
441// Double_t mass = thisPart->GetMass();
442 Double_t eKin = energy - mass;
443
444 // --> Calculate number of points
445 Int_t nPoints = 0;
446 for (Int_t iDet = kEmulsionDet; iDet < kEndOfList; iDet++) {
447 pair<Int_t, Int_t> a(i, iDet);
448 if ( fPointsMap.find(a) != fPointsMap.end() ) {
449 nPoints += fPointsMap[a];
450 }
451 }
452
453 // --> Check for cuts (store primaries in any case)
454 if (iMother < 0) { store = kTRUE; }
455 else {
456 if (!fStoreSecondaries) { store = kFALSE; }
457 if (nPoints < fMinPoints) { store = kFALSE; }
458 if (eKin < fEnergyCut) { store = kFALSE; }
459 if ((nPoints >= fMinPoints && fMinPoints > 0) || (eKin >= fEnergyCut && fEnergyCut > 0)) {
460 store=kTRUE;
461 }
462 }
463 // --> Set storage flag
464 fStoreMap[i] = store;
465// special case for Ship generators, want to keep all original particles with their mother daughter relationship
466// independent if tracked or not. apply a dirty trick and use second mother to identify original generator particles.
467// doesn't work, always true: Int_t iMother2 = GetParticle(i)->GetMother(1); maybe should set Mother2 to -1 in the generator
468// if (iMother == iMother2) {fStoreMap[i] = kTRUE;}
469 }
470 // --> If flag is set, flag recursively mothers of selected tracks
471 if (fStoreMothers) {
472 for (Int_t i=0; i<fNParticles; i++) {
473 if (fStoreMap[i]) {
474 Int_t iMother = GetParticle(i)->GetMother(0);
475 {
476 while(iMother >= 0)
477 {
478 fStoreMap[iMother] = kTRUE;
479 iMother = GetParticle(iMother)->GetMother(0);
480 }
481 }
482 }
483 }
484 }
485
486}
487// -------------------------------------------------------------------------
488
489
490
DetectorId
@ kEmulsionDet
@ kEndOfList
@ kDoneBit
Definition ShipStack.h:44
Int_t fMinPoints
Definition ShipStack.h:238
virtual TParticle * PopNextTrack(Int_t &iTrack)
Bool_t fStoreMothers
Definition ShipStack.h:240
void AddPoint(DetectorId iDet)
std::map< std::pair< Int_t, Int_t >, Int_t > fPointsMap
Definition ShipStack.h:225
virtual void Reset()
Int_t fNTracks
Number of entries in fParticles.
Definition ShipStack.h:232
std::map< Int_t, Int_t > fIndexMap
Definition ShipStack.h:220
TParticle * GetParticle(Int_t trackId) const
Int_t fIndex
Number of entries in fTracks.
Definition ShipStack.h:233
virtual void PushTrack(Int_t toBeDone, Int_t parentID, Int_t pdgCode, Double_t px, Double_t py, Double_t pz, Double_t e, Double_t vx, Double_t vy, Double_t vz, Double_t time, Double_t polx, Double_t poly, Double_t polz, TMCProcess proc, Int_t &ntr, Double_t weight, Int_t is)
Definition ShipStack.cxx:69
virtual TParticle * GetCurrentTrack() const
virtual void Register()
virtual void Print(Int_t iVerbose=0) const
std::map< Int_t, Bool_t >::iterator fStoreIter
Definition ShipStack.h:216
Double32_t fEnergyCut
Definition ShipStack.h:239
TClonesArray * fTracks
Definition ShipStack.h:211
virtual void UpdateTrackIndex(TRefArray *detArray=0)
Bool_t fStoreSecondaries
Used for merging.
Definition ShipStack.h:237
virtual ~ShipStack()
Definition ShipStack.cxx:56
Int_t fNParticles
Number of primary particles.
Definition ShipStack.h:231
std::map< Int_t, Bool_t > fStoreMap
Definition ShipStack.h:215
virtual void FillTrackArray()
virtual Int_t GetCurrentParentTrackNumber() const
Int_t fNPrimaries
Index of current track.
Definition ShipStack.h:230
std::stack< TParticle * > fStack
Definition ShipStack.h:201
std::map< Int_t, Int_t >::iterator fIndexIter
Definition ShipStack.h:221
TClonesArray * fParticles
Definition ShipStack.h:207
void SelectTracks()
virtual TParticle * PopPrimaryForTracking(Int_t iPrim)
Int_t fCurrentTrack
Definition ShipStack.h:229
ShipStack(Int_t size=100)
Definition ShipStack.cxx:29
virtual void AddParticle(TParticle *part)
ClassImp(ecalContFact) ecalContFact