StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StGammaFilterMaker.cxx
1 // STL
2 #include <vector>
3 
4 // ROOT Libraries
5 #include "TVector3.h"
6 #include "TFile.h"
7 #include "TTree.h"
8 
9 // StEvent Libraries
10 #include "StEvent.h"
11 
12 // StEvent Libraries
13 #include "StEventTypes.h"
14 
15 // StMcEvent Libraries
16 #include "StMcEvent/StMcCalorimeterHit.hh"
17 #include "StMcEvent/StMcEmcModuleHitCollection.hh"
18 #include "StMcEvent/StMcEmcHitCollection.hh"
19 #include "StMcEvent/StMcEvent.hh"
20 #include "StMcEvent/StMcVertex.hh"
21 
22 // StEmc Libraries
23 #include "StEmcClusterCollection.h"
24 #include "StEmcPoint.h"
25 #include "StEmcUtil/geometry/StEmcGeom.h"
26 #include "StEmcUtil/projection/StEmcPosition.h"
27 #include "StEmcUtil/others/emcDetectorName.h"
28 
29 // StMuDst Libraries
30 #include "StBFChain/StBFChain.h"
31 #include "StMuDSTMaker/COMMON/StMuDstMaker.h"
32 
33 // St_g2t Libraries
34 #include "tables/St_g2t_event_Table.h"
35 #include "tables/St_g2t_pythia_Table.h"
36 #include "tables/St_g2t_vertex_Table.h"
37 #include "tables/St_particle_Table.h"
38 #include "StSpinPool/StJetSkimEvent/StPythiaEvent.h"
39 
40 // Class Header
41 #include "StGammaFilterMaker.h"
42 
43 ClassImp(StGammaFilterMaker)
44 
45 // Constructor //
48 StGammaFilterMaker::StGammaFilterMaker(const char *name):
49 StMaker(name), mPythiaFile(0), mPythiaTree(0), mPythiaEvent(0)
50 {
51 
52  LOG_DEBUG << "StGammaFilterMaker()" << endm;
53 
54  mFirst = true;
55  mPythiaName = "pythia.root";
56 
57  // 2009 Defaults
58  mSeedEnergyThreshold = 5.0;
59  mClusterEtThreshold = 6.55;
60 
61  // Zero counters
62  mTotal = 0;
63  mAccepted = 0;
64 
65  // Calorimeter Geometries
66 
67  mMomentum = new TVector3();
68 
69  // BEMC Geometry
70  mBemcGeom = StEmcGeom::instance("bemc");
71  assert(mBemcGeom);
72 
73  mPosition = new StEmcPosition();
74  assert(mPosition);
75 
76  for ( int ii=0;ii< nBemcTowers+1;ii++ )
77  {
78  mBemcTowerHits[ii] = 0;
79  }
80 
81 
82 }
83 
85 // Destructor //
87 StGammaFilterMaker::~StGammaFilterMaker()
88 {
89  LOG_DEBUG << "~StGammaFilterMaker()" << endm;
90 
91  // Clean up
92  mMomentum->Delete();
93  delete mPosition;
94 
95 }
96 
98 // Maker Init //
100 Int_t StGammaFilterMaker::Init()
101 {
102 
103  LOG_DEBUG << "Init()" << endm;
104 
105  // Force the BFC to listen to the filter
106  SetAttr(".Privilege", 1);
107 
108  LOG_INFO << "Init() - Using gamma filter on the BEMC" << endm;
109 
110  LOG_INFO << "Init() : Seed energy threshold = " << mSeedEnergyThreshold << " GeV " << endm;
111  LOG_INFO << "Init() : Cluster eT threshold = " << mClusterEtThreshold << " GeV " << endm;
112 
113  // Create pythia output file
114  StBFChain *bfChain = dynamic_cast<StBFChain*>(GetMakerInheritsFrom("StBFChain"));
115  if(bfChain)
116  {
117  TString name(bfChain->GetFileOut());
118  name.ReplaceAll(".root",".pythia.root");
119  mPythiaName = name;
120  }
121 
122  LOG_INFO << "Init() : Storing pythia event information in " << mPythiaName << endm;
123  mPythiaEvent = new StPythiaEvent;
124  mPythiaFile = new TFile(mPythiaName, "recreate");
125  mPythiaTree = new TTree("pythiaTree", "Pythia Tree");
126  mPythiaTree->Branch("PythiaEvents", "StPythiaEvent", &mPythiaEvent);
127 
128  return kStOK;
129 
130 }
131 
133 // Maker Clear //
135 void StGammaFilterMaker::Clear(const Option_t*)
136 {
137  LOG_DEBUG << "Clear()" << endm;
138 
139  // Clear the StEmcRawHit arrays
140  StMcCalorimeterHit **point1 = mBemcTowerHits;
141  for(unsigned int i = 0; i < nBemcTowers + 1; ++i)
142  {
143  *point1 = NULL;
144  ++point1;
145  }
146 
147  mPythiaEvent->Clear();
148 
149 }
150 
152 // Set filter thresholds //
154 void StGammaFilterMaker::setThresholds(double seed, double cluster)
155 {
156 
157  LOG_DEBUG << "setThresholds()" << endm;
158 
159  if(seed > 0) mSeedEnergyThreshold = seed;
160  if(cluster > 0) mClusterEtThreshold = cluster;
161 
162 }
163 
165 // Calculate multiplier between energy deposited in the //
166 // BEMC sampling calorimeter and the true particle //
167 // energy, i.e. the inverse of the sampling fraction, //
168 // as a function of tower pseudorapidity //
169 // //
170 // LOW_EM compatible coeffiecients taken from //
171 // StEmcSimulatorMaker/StEmcSimpleSimulator.cxx v1.16 //
173 
174 double StGammaFilterMaker::BEMCSamplingMultiplier(double eta)
175 {
176 
177  double x = fabs(eta);
178  double c0 = 14.365;
179  double c1 = -0.512;
180  double c2 = 0.668;
181 
182  return c0 + c1 * x + c2 * x * x;
183 
184 }
186 // Apply filter //
189 {
190 
191  LOG_DEBUG << "Make()" << endm;
192 
193  // Acquire StEvent from the chain
194  StEvent *mEvent = dynamic_cast<StEvent*>(GetDataSet("StEvent"));
195  if(!mEvent)
196  {
197  LOG_WARN << "Make() - StEvent not found!" << endm;
198  return kStWarn;
199  }
200 
201  // Acquire StMcEvent from the chain
202  StMcEvent *mMcEvent = dynamic_cast<StMcEvent*>(GetDataSet("StMcEvent"));
203 
204  ++mTotal;
205 
206  // Store the pythia event record
207  fStorePythia();
208 
209  // Store the first event to ensure that a MuDst is created
210  // in the case of no events passing the filter
211  if(mFirst)
212  {
213 
214  LOG_INFO << "Make() : Storing first event without applying filter" << endm;
215 
216  ++mAccepted;
217  mFirst = false;
218 
219  return kStOK;
220  }
221 
222  // Check for functional StMcEvent
223  if(!mMcEvent)
224  {
225  LOG_WARN << "Make() - Bad StMcEvent!" << endm;
226  return kStWarn;
227  }
228 
229  // Acquire vertex information from the geant record
230  // and abort the event if the vertex is too extreme
231  double zVertex = mMcEvent->primaryVertex()->position().z();
232 
233  // Look for clusters in the chosen calorimeter
234  Int_t status = 0;
235 
236  // Pick up geant calorimeter depositions from StMcEvent
237  StMcEmcHitCollection *mcEmcCollection = mMcEvent->bemcHitCollection();
238  assert(mcEmcCollection);
239  status = makeBEMC(mcEmcCollection, zVertex);
240 
241  if(status == kStSKIP)
242  {
243  LOG_INFO << "Make() : Aborting Event " << mEvent->id() << " due to gamma filter rejection" << endm;
244  }
245 
246  if(status == kStOK)
247  {
248  ++mAccepted;
249  LOG_INFO << "Make() : Event " << mEvent->id() << " accepted!" << endm;
250  }
251 
252  return status;
253 
254 }
255 
257 // Construct crude BEMC clusters of 3x3 towers, //
258 // returning kStOK if a satisifactory cluster //
259 // is found and kStSKIP otherwise //
261 
262 Int_t StGammaFilterMaker::makeBEMC(StMcEmcHitCollection *mcEmcCollection, double zVertex)
263 {
264 
265  LOG_DEBUG << "makeBEMC()" << endm;
266 
268  // Instantiate variables //
270 
271  // Tower identification
272  int bemcId = 0;
273 
274  unsigned int m = 0;
275  unsigned int e = 0;
276  unsigned int s = 0;
277 
278  float eta = 0;
279 
280  // Tower position
281  float x = 0;
282  float y = 0;
283  float z = 0;
284  double r = 0;
285 
287  // Fill mBemcTowerHits //
288  // with hit data //
290  for(unsigned int m = 1; m < mcEmcCollection->numberOfModules() + 1; ++m)
291  {
292 
293  const StMcEmcModuleHitCollection *module = mcEmcCollection->module(m);
294  const vector<StMcCalorimeterHit*> hits = module->detectorHits();
295 
296  for(unsigned int l = 0; l < hits.size(); ++l)
297  {
298  mBemcGeom->getId(hits[l]->module(), hits[l]->eta(), hits[l]->sub(), bemcId);
299  mBemcTowerHits[bemcId] = hits[l];
300  }
301 
302  }
303 
305  // Search for clusters //
307  double seedEnergy = 0;
308  double clusterEnergy = 0;
309  double clusterEt = 0;
310  unsigned int neighborId = 0;
311  StMcCalorimeterHit *neighborHit = NULL;
312 
313  for(unsigned int n = 1; n < nBemcTowers + 1; ++n)
314  {
315 
316  StMcCalorimeterHit *hit = mBemcTowerHits[n];
317  if(!hit) continue;
318 
319  mBemcGeom->getEta(n, eta);
320 
321  seedEnergy = hit->dE() * BEMCSamplingMultiplier(eta);
322 
323  // Start with a seed tower...
324  if(seedEnergy > mSeedEnergyThreshold)
325  {
326 
327  clusterEnergy = seedEnergy;
328 
329  m = hit->module();
330  e = hit->eta();
331  s = hit->sub();
332 
333  // and accumulate energy from the neighboring towers
334  for(int i = -1; i < 2; ++i)
335  {
336  for(int j = -1; j < 2; ++j)
337  {
338 
339  if( !i && !j )
340  {
341  LOG_DEBUG << "\t\tTower " << n << ", E = " << seedEnergy << " (Seed)" << endm;
342  continue;
343  }
344 
345  neighborId = mPosition->getNextId(1, m, (int)e, s, i, j);
346  if(neighborId < 1) continue;
347  if(neighborId > 4800) continue;
348 
349  neighborHit = mBemcTowerHits[neighborId];
350 
351  if(!neighborHit) continue;
352  mBemcGeom->getEta(neighborId, eta);
353  LOG_DEBUG << "\t\tTower " << neighborId << ", E = " << neighborHit->dE() * BEMCSamplingMultiplier(eta) << endm;
354  clusterEnergy += neighborHit->dE() * BEMCSamplingMultiplier(eta);
355 
356  }
357 
358  }
359 
360  // Project cluster energy into transverse plane
361  mBemcGeom->getXYZ((int)n, x, y, z);
362  z -= zVertex;
363  r = sqrt(x * x + y * y + z * z);
364  x *= clusterEnergy / r;
365  y *= clusterEnergy / r;
366  z *= clusterEnergy / r;
367  mMomentum->SetXYZ(x, y, z);
368  clusterEt = mMomentum->Perp();
369 
370  LOG_DEBUG << "\tCluster Energy = " << clusterEnergy << " GeV" << endm;
371  LOG_DEBUG << "\tCluster eT (corrected for vertex) = " << clusterEt << " GeV" << endm;
372  LOG_DEBUG << "\tCluster eta (corrected for vertex) = " << mMomentum->Eta() << endm;
373  LOG_DEBUG << "\tCluster phi = " << mMomentum->Phi() << endm;
374  LOG_DEBUG << "" << endm;
375 
376  // Apply filter
377  if(clusterEt > mClusterEtThreshold)
378  {
379  return kStOk;
380  }
381 
382  } // Seed tower check
383 
384  } // Seed tower loop
385 
386  return kStSKIP;
387 
388 }
389 
391 // Display filter stats //
394 {
395 
396  LOG_DEBUG << "::Finish()" << endm;
397 
398  mPythiaFile->Write();
399  mPythiaFile->Close();
400 
401  LOG_INFO << "Finish() : " << GetName() << " finishing with " << endm;
402  LOG_INFO << "Finish() : \t" << mAccepted << " of " << mTotal << " events passing the filter" << endm;
403 
404  return kStOK;
405 
406 }
407 
409 // Store Pythia Event Record //
411 void StGammaFilterMaker::fStorePythia()
412 {
413 
414  TDataSet* geant = GetDataSet("geant");
415 
416  if(geant)
417  {
418 
419  TDataSetIter iter(geant);
420 
421  // Global event information
422  St_g2t_event* g2tEvent = (St_g2t_event*)iter("g2t_event");
423  if(g2tEvent)
424  {
425 
426  g2t_event_st* eventTable = (g2t_event_st*)g2tEvent->GetTable();
427  if(eventTable)
428  {
429  mPythiaEvent->setRunId(eventTable->n_run);
430  mPythiaEvent->setEventId(eventTable->n_event);
431  }
432 
433  }
434 
435  // Pythia event information
436  St_g2t_pythia* pythiaEvent = (St_g2t_pythia*)iter("g2t_pythia");
437  if(pythiaEvent)
438  {
439 
440  g2t_pythia_st* pythiaTable = (g2t_pythia_st*)pythiaEvent->GetTable();
441  if(pythiaTable)
442  {
443 
444  mPythiaEvent->setProcessId(pythiaTable->subprocess_id);
445  mPythiaEvent->setS(pythiaTable->mand_s);
446  mPythiaEvent->setT(pythiaTable->mand_t);
447  mPythiaEvent->setU(pythiaTable->mand_u);
448  mPythiaEvent->setPt(pythiaTable->hard_p);
449  mPythiaEvent->setCosTheta(pythiaTable->cos_th);
450  mPythiaEvent->setX1(pythiaTable->bjor_1);
451  mPythiaEvent->setX2(pythiaTable->bjor_2);
452 
453  }
454 
455  }
456 
457  // Vertex information
458  St_g2t_vertex* vertexEvent = (St_g2t_vertex*)iter("g2t_vertex");
459  if(vertexEvent)
460  {
461 
462  g2t_vertex_st* vertexTable = (g2t_vertex_st*)vertexEvent->GetTable();
463  if(vertexTable) mPythiaEvent->setVertex(TVector3(vertexTable[0].ge_x));
464  }
465 
466  // Pythia particle record
467  St_particle* particleEvent = (St_particle*)iter("particle");
468  if(particleEvent)
469  {
470 
471  particle_st* particleTable = (particle_st*)particleEvent->GetTable();
472  if(particleTable)
473  {
474 
475  for(int i = 0; i < particleEvent->GetNRows(); ++i)
476  {
477  mPythiaEvent->addParticle(TParticle(particleTable[i].idhep, // pdg
478  particleTable[i].isthep, // status
479  particleTable[i].jmohep[0], // mother1
480  particleTable[i].jmohep[1], // mother2
481  particleTable[i].jdahep[0], // daughter1
482  particleTable[i].jdahep[1], // daughter2
483  TLorentzVector(particleTable[i].phep), // momentum and energy
484  TLorentzVector(particleTable[i].vhep))); // production vertex and time
485  }
486 
487  }
488 
489  }
490 
491  }
492 
493  mPythiaTree->Fill();
494 
495  return;
496 
497 }
Definition: Stypes.h:48
Int_t getNextId(Int_t det, Int_t m, Int_t e, Int_t s, Int_t nEta, Int_t nPhi) const
Return neighbor id (works for all detectors 1=bemc, 2=bprs, 3=bsmde, 4=bsmdp)
virtual const char * GetName() const
special overload
Definition: StMaker.cxx:237
Definition: Stypes.h:42
Definition: Stypes.h:40
Event data structure to hold all information from a Monte Carlo simulation. This class is the interfa...
Definition: StMcEvent.hh:169
Definition: Stypes.h:41