StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StMcEEmcTreeMaker.cxx
1 /*
2  * Created by S. Gliske, May 2012
3  *
4  * Description: see header
5  *
6  */
7 
8 //#define DEBUG
9 
10 #include <Rtypes.h>
11 #include <TChain.h>
12 #include <TTree.h>
13 #include <TFile.h>
14 
15 #include "StMcEEmcTreeMaker.h"
16 
17 #include "StMuDSTMaker/COMMON/StMuDst.h"
18 #include "StMuDSTMaker/COMMON/StMuEvent.h"
19 #include "StEvent/StTriggerIdCollection.h"
20 #include "StEvent/StTriggerId.h"
21 
22 #include "StarClassLibrary/StThreeVectorF.hh"
23 #include "StEEmcUtil/EEmcGeom/EEmcGeomDefs.h"
24 
25 #include "StMcEvent/StMcTrack.hh"
26 #include "StMcEvent/StMcCalorimeterHit.hh"
27 #include "StMcEvent/StMcEmcModuleHitCollection.hh"
28 #include "StMcEvent/StMcEmcHitCollection.hh"
29 #include "StMcEvent/StMcContainers.hh"
30 #include "StMcEvent/StMcEvent.hh"
31 #include "StMcEvent/StMcVertex.hh"
32 
33 #include "St_DataSet.h"
34 #include "St_DataSetIter.h"
35 #include "tables/St_g2t_event_Table.h"
36 #include "tables/St_particle_Table.h"
37 #include "tables/St_g2t_pythia_Table.h"
38 
39 #include "StRoot/StEEmcPool/./EEmcTreeContainers/EEmcEnergy.h"
40 #include "StRoot/StEEmcPool/./EEmcTreeContainers/McParticle.h"
41 #include "StRoot/StEEmcPool/StEEmcPointMap/StEEmcPointMap.h"
42 
43 StMcEEmcTreeMaker_t::StMcEEmcTreeMaker_t( const Char_t *myName ) : StMaker( myName ), mIOStat( UNSET ), mFile(0), mTree(0), mChain(0),
44  mNumEvents(0), mMaxNumEvents(-1), mTowEnergyThres( 0.01 ), mBjX1(0), mBjX2(0) {
45  mEEmcEnergyArr = new TClonesArray("EEmcEnergy_t", 5);
46  mAncestorParticleArr = new TClonesArray("McParticle_t", 10);
47  mIncidentParticleArr = new TClonesArray("McParticle_t", 5);
48  mVertexArr = new TClonesArray("TVector3", 5);
49 };
50 
53  delete mEEmcEnergyArr;
54  delete mAncestorParticleArr;
55  delete mIncidentParticleArr;
56  delete mVertexArr;
57 
58  if( mChain )
59  delete mChain;
60 
61  if( mFile )
62  delete mFile;
63 
64  // no need to delete the TTree after deleting the TFile
65 };
66 
69  Int_t ierr = kStOk;
70 
71  if( mIOStat == UNSET || mFilename.empty() ){
72  LOG_ERROR << "Must set IO status to READ or WRITE and provide a filename" << endm;
73  ierr = kStFatal;
74  };
75 
76  // check trigger set
77  if( mTriggerSet.empty() && mIOStat == WRITE ){
78  LOG_FATAL << "ERROR: trigger set is empty." << endm;
79  LOG_FATAL << "If you really want to process all triggers, enter a single trigger ID of -999." << endm;
80  ierr = kStFatal;
81  } else if (mTriggerSet.size() == 1 && mTriggerSet.count( -999 ) ) {
82  // user has flagged to process all triggers
83  mTriggerSet.clear();
84  };
85 
86  if( !ierr ){
87  LOG_INFO << GetName() << ": Set to "
88  << ( mIOStat == READ ? "READ" : "WRITE" )
89  << " the file '" << mFilename
90  << endm;
91 
92  if( mIOStat == READ ){
93  mChain = new TChain("tree");
94  Int_t nFiles = mChain->Add( mFilename.data(), 1 );
95 
96  if( nFiles ){
97  LOG_INFO << "Opened " << nFiles << " based on '" << mFilename << endm;
98  } else {
99  LOG_ERROR << "Opened " << nFiles << " based on '" << mFilename << endm;
100  ierr = kStFatal;
101  };
102  mTree = mChain;
103 
104  if( !ierr ){
105  // set the branch addresses of the branches that must be there
106  mTree->SetBranchAddress( "eemcEnergyArr", &mEEmcEnergyArr );
107  mTree->SetBranchAddress( "incidentParticleArr", &mIncidentParticleArr );
108  mTree->SetBranchAddress( "ancestorParticleArr", &mAncestorParticleArr );
109  mTree->SetBranchAddress( "vertexArr", &mVertexArr );
110  mTree->SetBranchAddress( "xBj1", &mBjX1 );
111  mTree->SetBranchAddress( "xBj2", &mBjX2 );
112  };
113 
114  } else if( mIOStat == WRITE ){
115  mFile = new TFile( mFilename.data(), "RECREATE" );
116  if( mFile->IsOpen() ){
117  LOG_INFO << "Opened file '" << mFilename << "' for writing" << endm;
118  } else {
119  LOG_FATAL << "Error opening file '" << mFilename << "'" << endm;
120  ierr = kStFatal;
121  };
122 
123  if( !ierr ){
124  mTree = new TTree( "tree", "McEEmcTree" );
125  mTree->Branch( "eemcEnergyArr", &mEEmcEnergyArr );
126  mTree->Branch( "incidentParticleArr", &mIncidentParticleArr );
127  mTree->Branch( "ancestorParticleArr", &mAncestorParticleArr );
128  mTree->Branch( "vertexArr", &mVertexArr );
129  mTree->Branch( "xBj1", &mBjX1 );
130  mTree->Branch( "xBj2", &mBjX2 );
131  };
132  };
133  };
134 
135  Int_t treeMax = -1111;
136  if( mIOStat == READ && mChain->GetEntries() > treeMax )
137  treeMax = mChain->GetEntries();
138 
139  if( mMaxNumEvents < 0 || mMaxNumEvents > treeMax )
140  mMaxNumEvents = treeMax;
141 
142  return ierr;
143 };
144 
145 
148  Int_t ierr = kStOk;
149 
150  if( mIOStat == READ && mNumEvents >= mMaxNumEvents )
151  ierr = kStEOF;
152 
153  if( !ierr && ( mNumEvents < mMaxNumEvents || mMaxNumEvents < 0 ) ){
154  if( mIOStat == READ ){
155  mChain->GetEntry( mNumEvents );
156  } else {
157  Bool_t accept = 1;
158  // check if event passes trigger
159  if( !mTriggerSet.empty() ){
160  accept = 0;
161 
162  const StMuDst* muDst = (const StMuDst*)GetInputDS( "MuDst" );
163  if( muDst ){
164  StMuEvent *event = muDst->event();
165 
166  if( event ){
167  const StTriggerId& l1trig = event->triggerIdCollection().l1();
168 
169  std::set< Int_t >::iterator iter = mTriggerSet.begin();
170  for( ; iter != mTriggerSet.end() && !accept; ++iter )
171  accept = l1trig.isTrigger( (*iter) );
172  };
173  };
174  };
175 
176  if( accept )
177  ierr = fill();
178  };
179  };
180 
181  ++mNumEvents;
182  return ierr;
183 };
184 
185 //
186 Int_t StMcEEmcTreeMaker_t::fill(){
187  Int_t ierr = kStOk;
188 
189  // get the McEvent
190  StMcEvent* mcEventPtr = 0;
191  mcEventPtr = static_cast< StMcEvent* >( StMaker::GetChain()->GetDataSet("StMcEvent") );
192  if( !mcEventPtr ){
193  LOG_FATAL << "ERROR finding StMcEvent" << endm;
194  ierr = kStFatal;
195  };
196 
197  // for bjorken-x from Pythia
198  {
199  //GET GEANT EVENT
200  TDataSet *Event = GetDataSet("geant"); //Event->ls(3);
201 
202  //GET PYTHIA RECORD from particleTable
203  TDataSetIter geantDstI(Event);
204 
205  //CHECK IF EXISTS PARTICLE TABLE
206  if( geantDstI("particle") ){
207  St_g2t_pythia *Pg2t_pythia = (St_g2t_pythia*)geantDstI("g2t_pythia");
208  g2t_pythia_st *g2t_pythia1 = Pg2t_pythia->GetTable();
209 
210  mBjX1 = g2t_pythia1->bjor_1;
211  mBjX2 = g2t_pythia1->bjor_2;
212  };
213  };
214 
215  // index in mIncidentParticleArr
216  Int_t incPartIdx = -1;
217 
218  if( !ierr ){
219 
220  // prepare to iterate over the tracks and gather those indicident on the endcap.
221  const StSPtrVecMcTrack& tracks = mcEventPtr->tracks();
222  StSPtrVecMcTrack::const_iterator trackIter;
223 
224  // in the following, hit is defined as the energy response of a
225  // given element (tower, strip, etc.) of the EEmc, to be
226  // consistent with definitions in StEvent.
227  StSPtrVecMcCalorimeterHit::const_iterator hitIter;
228 
229  for( trackIter = tracks.begin(); trackIter != tracks.end(); ++trackIter ){
230  const StPtrVecMcCalorimeterHit& etowHits = (*trackIter)->eemcHits();
231 
232  Bool_t pass = !etowHits.empty();
233 
234  if( pass ){
235  const StMcVertex *stop = (*trackIter)->stopVertex();
236  pass = ( !stop || stop->position().z() > kEEmcZPRE1 );
237 
238  };
239 
240  // fill tower energy and determine if above thres
241  Float_t eTowEnergy = 0;
242  EEmcEnergy_t *eemcEnergy = 0;
243  if( pass ){
244  // determine the total energy deposited in the towers from this particle
245  for( hitIter = etowHits.begin(); hitIter != etowHits.end(); ++hitIter )
246  eTowEnergy += (*hitIter)->dE();
247 
248  pass &= ( eTowEnergy > mTowEnergyThres );
249  };
250 
251  if( pass ){
252  // increment the counter
253  ++incPartIdx;
254 
255  // add new object to the array
256  eemcEnergy = static_cast< EEmcEnergy_t* >( new( (*mEEmcEnergyArr)[ incPartIdx ] ) EEmcEnergy_t() );
257 
258  // fill towers
259  Float_t ePre1 = 0, ePre2 = 0, ePost = 0, eTow = 0;
260  for( hitIter = etowHits.begin(); hitIter != etowHits.end(); ++hitIter ){
261  Int_t sec = (*hitIter)->module() - 1;
262  Int_t sub = (*hitIter)->sub() - 1;
263  Int_t eta = (*hitIter)->eta() - 1;
264 
265  eemcEnergy->eTow.getByBin( sec, sub, eta ).energy = (*hitIter)->dE();
266  ++(eemcEnergy->nTowers);
267  eTow += (*hitIter)->dE();
268  };
269 
270  // now fill pre and post shower layers
271  {
272  const StPtrVecMcCalorimeterHit& eprsHits = (*trackIter)->eprsHits();
273  for( hitIter = eprsHits.begin(); hitIter != eprsHits.end(); ++hitIter ){
274  Int_t sec = (*hitIter)->module() - 1;
275  Int_t sub = ((*hitIter)->sub() - 1)%5;
276  Int_t eta = (*hitIter)->eta() - 1;
277  Int_t offset = ((*hitIter)->sub() - 1)/5;
278 
279  ( offset ? ( offset == 2 ? eemcEnergy->ePost : eemcEnergy->ePre2 ) : eemcEnergy->ePre1 ).getByBin( sec, sub, eta ).energy = (*hitIter)->dE();
280  ( offset ? ( offset == 2 ? ePost : ePre2 ) : ePre1 ) += (*hitIter)->dE();
281  };
282  };
283 
284  // now fill smd layers
285  std::vector< Double_t > meanU(kEEmcNumSectors,0), eU(kEEmcNumSectors,0), meanV(kEEmcNumSectors,0), eV(kEEmcNumSectors,0);
286 
287  {
288  const StPtrVecMcCalorimeterHit& esmduHits = (*trackIter)->esmduHits();
289  for( hitIter = esmduHits.begin(); hitIter != esmduHits.end(); ++hitIter ){
290  Int_t sec = (*hitIter)->module() - 1;
291  Int_t strip = (*hitIter)->eta() - 1;
292  eemcEnergy->eSmd.sec[sec].layer[0].strip[strip].energy = (*hitIter)->dE();
293  meanU[sec] += strip*(*hitIter)->dE();
294  eU[sec] += (*hitIter)->dE();
295  ++(eemcEnergy->nStrips);
296  };
297  };
298  {
299  const StPtrVecMcCalorimeterHit& esmdvHits = (*trackIter)->esmdvHits();
300  for( hitIter = esmdvHits.begin(); hitIter != esmdvHits.end(); ++hitIter ){
301  Int_t sec = (*hitIter)->module() - 1;
302  Int_t strip = (*hitIter)->eta() - 1;
303  eemcEnergy->eSmd.sec[sec].layer[1].strip[strip].energy = (*hitIter)->dE();
304  meanV[sec] += strip*(*hitIter)->dE();
305  eV[sec] += (*hitIter)->dE();
306  ++(eemcEnergy->nStrips);
307  };
308  };
309 
310  Float_t uPos = -1, vPos = -1;
311  Float_t maxE = 0, maxEu = 0, maxEv = 0;
312  Short_t sector = 0;
313  for( Int_t i=0; i<kEEmcNumSectors; ++i ){
314  Float_t smdSum = eU[i]+eV[i];
315  if( maxE < smdSum && eU[i] && eV[i] ){
316  maxE = smdSum;
317  maxEu = eU[i];
318  maxEv = eV[i];
319  uPos = static_cast< Float_t >( meanU[i] / eU[i] );
320  vPos = static_cast< Float_t >( meanV[i] / eV[i] );
321  sector = i;
322  };
323  };
324 
325 
326  // Note: uPos and vPos are the energy weighted average
327  // positions in the SMD in the sector with the most energy
328  // deposited in the SMD. Next, convert uPos, vPos to an x,y
329  // position
330  Float_t xPos = 0, yPos = 0;
331  if( uPos > 0 && vPos > 0 )
332  StEEmcPointMap_t::convertStripUVtoXY( sector, uPos, vPos, xPos, yPos );
333 
334  // Add McParticle_t to the TClonesArray
335  new( (*mIncidentParticleArr)[ incPartIdx ] ) McParticle_t( getAncestorIdx( (*trackIter)->parent() ),
336  getVertexIdx( (*trackIter)->startVertex() ),
337  getVertexIdx( (*trackIter)->stopVertex() ),
338  (*trackIter)->geantId(),
339  (*trackIter)->pdgId(),
340  (*trackIter)->energy(),
341  TVector3( (*trackIter)->momentum().xyz() ),
342  sector, uPos, vPos,
343  maxEu, maxEv,
344  TVector3( xPos, yPos, kEEmcZSMD ),
345  eTow, ePre1, ePre2, ePost );
346  } else {
347  // It didn't pass as an incident particle. However, if it
348  // was still aimed somewhat towards the EEMC, add it to the list of
349  // ancestors.
350 
351  // copy the momentum
352  TVector3 mom( (*trackIter)->momentum().xyz() );
353  Double_t eta = mom.Eta();
354 
355  // give a wide physics eta range
356  if( eta > 0.5 && eta < 2.5 )
357  getAncestorIdx( *trackIter ); // adds to the map if it is not there
358  };
359  };
360  };
361 
362  if( !ierr && incPartIdx > -1 ){
363  // first make a copy of the map
364  std::map< const StMcTrack*, Int_t > ancestorMapCopy( mAncestorMap );
365 
366  // an iterator
367  std::map< const StMcTrack*, Int_t >::iterator ancestorMapIter;
368 
369  // next, gather all the ancestors into the main map
370  for( ancestorMapIter = ancestorMapCopy.begin(); ancestorMapIter != ancestorMapCopy.end(); ++ancestorMapIter ){
371  UInt_t mapSize = mAncestorMap.size();
372  const StMcTrack *parent = ancestorMapIter->first->parent();
373 
374  // keep adding parents of parents, until connecting with an
375  // existing line or until there are no more parents.
376  if( parent ){
377  do {
378  mapSize = mAncestorMap.size(); // size before possible increase
379  getAncestorIdx( parent ); // adds to the map if it is not there
380  parent = parent->parent(); // update the pointer for the (possible) next loop
381  } while( parent && mapSize != mAncestorMap.size() );
382  };
383  };
384 
385  // now that the ancestors are gathered, lets fill the TClonesArray
386  for( ancestorMapIter = mAncestorMap.begin(); ancestorMapIter != mAncestorMap.end(); ++ancestorMapIter ){
387  Int_t idx = ancestorMapIter->second;
388  const StMcTrack *track = ancestorMapIter->first;
389 
390  if( idx > -1 && track )
391  new( (*mAncestorParticleArr)[ idx ] ) McParticle_t( getAncestorIdx( track->parent() ),
392  getVertexIdx( track->startVertex() ),
393  getVertexIdx( track->stopVertex() ),
394  track->geantId(),
395  track->pdgId(),
396  track->energy(),
397  TVector3( track->momentum().xyz() ),
398  0, 0, 0, 0, 0, TVector3(),
399  0, 0, 0, 0 );
400  };
401 
402  // lastly, we fill the TClonesArray of vertices
403  for( mVertexMapIter = mVertexMap.begin(); mVertexMapIter != mVertexMap.end(); ++mVertexMapIter ){
404  Int_t idx = mVertexMapIter->second;
405  const StMcVertex *vertex = mVertexMapIter->first;
406 
407  if( idx > -1 && vertex )
408  new( (*mVertexArr)[ idx ] ) TVector3( vertex->position().xyz() );
409  };
410 
411 // cout << "Event " << GetEventNumber() << " arrays of size "
412 // << mEEmcEnergyArr->GetEntriesFast() << ' '
413 // << mIncidentParticleArr->GetEntriesFast() << ' '
414 // << mAncestorParticleArr->GetEntriesFast() << ' '
415 // << mVertexArr->GetEntriesFast() << endl;
416  };
417 
418  // fill in any case, so that the entry number corresponds, even if
419  // errors earlier
420  mTree->Fill();
421 
422  return ierr;
423 };
424 
426 void StMcEEmcTreeMaker_t::Clear(Option_t *opts ){
427  mEEmcEnergyArr->Clear("C");
428  mAncestorParticleArr->Clear("C");
429  mIncidentParticleArr->Clear("C");
430  mVertexArr->Clear("C");
431 
432  mAncestorMap.clear();
433  mVertexMap.clear();
434 };
435 
438  if( mIOStat == WRITE ){
439  mFile->Write();
440  mFile->Close();
441  };
442 
443  return kStOk;
444 };
445 
447 void StMcEEmcTreeMaker_t::setTreeStatus( iostatus_t iostatus, const Char_t* fileName ){
448  mIOStat = iostatus;
449  mFilename = fileName;
450 };
451 
452 void StMcEEmcTreeMaker_t::setMaxNumEvents( Int_t maxNum ){
453  mMaxNumEvents = maxNum;
454 };
455 
456 // particles leaving less energy than this value in the ETOW are ignored.
457 void StMcEEmcTreeMaker_t::setEnergyThreshold( Float_t val ){
458  mTowEnergyThres = val;
459 };
460 
461 
462 Int_t StMcEEmcTreeMaker_t::getVertexIdx( const StMcVertex* vertex ){
463  Int_t idx = -1;
464 
465  if( vertex && vertex->position().z() > -900 ){
466  mVertexMapIter = mVertexMap.find( vertex );
467  if( mVertexMapIter != mVertexMap.end() ) {
468  idx = mVertexMapIter->second;
469  } else {
470  idx = mVertexMap.size();
471  mVertexMap[ vertex ] = idx;
472  };
473  };
474 
475  return idx;
476 };
477 
478 Int_t StMcEEmcTreeMaker_t::getAncestorIdx( const StMcTrack* track ){
479  Int_t idx = -1;
480 
481  if( track ){
482  mAncestorMapIter = mAncestorMap.find( track );
483  if( mAncestorMapIter != mAncestorMap.end() ) {
484  idx = mAncestorMapIter->second;
485  } else {
486  idx = mAncestorMap.size();
487  mAncestorMap[ track ] = idx;
488  };
489  };
490 
491  return idx;
492 };
493 
494 ClassImp( StMcEEmcTreeMaker_t );
495 
496 /*
497  * $Id: StMcEEmcTreeMaker.cxx,v 1.2 2013/03/19 18:49:08 sgliske Exp $
498  * $Log: StMcEEmcTreeMaker.cxx,v $
499  * Revision 1.2 2013/03/19 18:49:08 sgliske
500  * added Bjorken x1 and x2
501  *
502  * Revision 1.1 2012/11/26 19:06:10 sgliske
503  * moved from offline/users/sgliske/StRoot/StEEmcPool/StEEmcTreeMaker to StRoot/StEEmcPool/StEEmcTreeMaker
504  *
505  *
506  */
virtual ~StMcEEmcTreeMaker_t()
deconstructor
Int_t Init()
Initialize.
iostatus_t mIOStat
filenames
Monte Carlo Track class All information on a simulated track is stored in this class: kinematics...
Definition: StMcTrack.hh:144
void setTreeStatus(iostatus_t iostatus, const Char_t *fileName)
modifiers
StMcEEmcTreeMaker_t(const Char_t *myName)
constructor
Int_t Make()
Build an event.
TChain * mChain
TChains for reading.
Definition: Stypes.h:43
Int_t Finish()
Write everything to file.
void Clear(Option_t *opts="")
Clear for next event.
static StMuEvent * event()
returns pointer to current StMuEvent (class holding the event wise information, e.g. event number, run number)
Definition: StMuDst.h:320
Int_t mMaxNumEvents
max number of events
virtual const char * GetName() const
special overload
Definition: StMaker.cxx:237
TClonesArray * mEEmcEnergyArr
The data.
Definition: AgUStep.h:26
Int_t mNumEvents
number of events processed / written outt
Event data structure to hold all information from a Monte Carlo simulation. This class is the interfa...
Definition: StMcEvent.hh:169
TFile * mFile
TFiles/TTrees for writing.
Definition: Stypes.h:41