StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StEEmcDataDrivenMcMaker.cxx
1 //
2 // Hal Spinka <hms@anl.gov>
3 // Argonne National Laboratory
4 //
5 // Pibero Djawotho <pibero@indiana.edu>
6 // Indiana University Cyclotron Facility
7 //
8 // Ilya Selyuzhenkov <ilya.selyuzhenkov@gmail.com>
9 // Indiana University Cyclotron Facility
10 //
11 
12 // ROOT
13 #include "TFile.h"
14 #include "TTree.h"
15 #include "TRandom.h"
16 #include "TClonesArray.h"
17 #include "TH1.h"
18 #include "TH2.h"
19 #include "TChain.h"
20 
21 // STAR
22 #include "StEventTypes.h"
23 #include "StMuDSTMaker/COMMON/StMuTypes.hh"
24 #include "StMcEvent/StMcEventTypes.hh"
25 #include "StEEmcUtil/database/EEmcDbItem.h"
26 #include "StEEmcUtil/database/StEEmcDb.h"
27 #include "StEEmcUtil/EEmcGeom/EEmcGeomSimple.h"
28 #include "StEEmcUtil/StEEmcSmd/EEmcSmdGeom.h"
29 #include "StEEmcSimulatorMaker/StEEmcFastMaker.h"
30 #include "StEEmcPool/StEEmcA2EMaker/StEEmcA2EMaker.h"
31 
32 // Local
33 #include "StEEmcPool/StEEmcDataDrivenMcEventInfo/StEEmcDataDrivenMcEventInfo.h"
34 #include "StEEmcShowerShape.h"
35 #include "StEEmcDataDrivenMcMaker.h"
36 
37 ClassImp(StEEmcDataDrivenMcMaker);
38 
39 StEEmcDataDrivenMcMaker::StEEmcDataDrivenMcMaker(const char* name) : StMaker(name)
40 {
41  mUsePed = true;
42  mEEmcDb = 0;
43 }
44 
45 void StEEmcDataDrivenMcMaker::Clear(Option_t* option)
46 {
47  memset(mStrips, 0, sizeof(mStrips));
48  mDataDrivenMcEventInfo->Clear(option);
49  StMaker::Clear(option);
50 }
51 
52 int StEEmcDataDrivenMcMaker::Init()
53 {
54  // Initialize pointer to Monte Carlo event
55  mMcEvent = 0;
56 
57  //mNumberOfStripsReplaced = 12; // default number of strips replaced
58  //mShowerShapeScalingMethod = 1; // default scaling method
59  // Load shower shape library
60  TFile* file = new TFile(mLibraryFile);
61  LOG_INFO << "Shower Shape Library = " << mLibraryFile << endm;
62  assert(file && !file->IsZombie());
63  TTree* tree = (TTree*)file->Get("etas");
64  assert(tree);
65  StEEmcShowerShape* showerShape = 0;
66  tree->SetBranchAddress("StEEmcSmdResponse", &showerShape);
67 
68  for (int i = 0; i < NUMBER_OF_ENERGY_BINS; ++i) {
69  for (int j = 0; j < NUMBER_OF_PRESHOWER_BINS; ++j) {
70  mShowerShapes[i][j] = new TClonesArray("StEEmcShowerShape");
71  }
72  }
73 
74  for (int iEntry = 0; tree->GetEntry(iEntry) > 0; ++iEntry) {
75  int uid = showerShape->highUstripId();
76  int vid = showerShape->highVstripId();
77  // Drop shapes that are at the edges of the SMD
78 // if (uid < 12 || uid > 275 || vid < 12 || vid > 275) continue;
79  if (uid < mNumberOfStripsReplaced || uid > 288 - mNumberOfStripsReplaced-1 || vid < mNumberOfStripsReplaced || vid > 288-mNumberOfStripsReplaced-1) continue; // Added by Ilya Selyuzhenkov
80  assert(0 <= showerShape->sector() && showerShape->sector() < 12);
81  int i = getEnergyBin(showerShape);
82  int j = getPreshowerBin(showerShape);
83  assert(i >= 0 && i < NUMBER_OF_ENERGY_BINS);
84  assert(j >= 0 && j < NUMBER_OF_PRESHOWER_BINS);
85  TClonesArray& tca = *mShowerShapes[i][j];
86  mLibraryMap[new (tca[tca.GetEntriesFast()]) StEEmcShowerShape(*showerShape)] = iEntry;
87  }
88 
89  LOG_INFO << "Number of shower shapes in library = " << tree->GetEntriesFast() << endm;
90 
91  for (int i = 0; i < NUMBER_OF_ENERGY_BINS; ++i) {
92  for (int j = 0; j < NUMBER_OF_PRESHOWER_BINS; ++j) {
93  LOG_INFO << "Energy bin =" << i
94  << ", preshower bin=" << j
95  << ", number of shower shapes=" << mShowerShapes[i][j]->GetEntriesFast()
96  << endm;
97  } // for-loop
98  } // for-loop
99 
100  file->Close();
101 
102  // MuDst utility to translate between StMuEmcHit id and sector, subsector, and strip id
103  mMuEmcUtil = new StMuEmcUtil;
104 
105  // Initialize log file to 0
106  mLogFile = 0;
107 
108  if (mLogFileName != "") {
109  mLogFile = TFile::Open(mLogFileName, "recreate");
110  assert(mLogFile);
111  }
112 
113  // Data-driven MC event info
114  mDataDrivenMcEventInfo = new StEEmcDataDrivenMcEventInfo;
115 
116  // Create tree
117  mTree = new TTree("DataDrivenMcEventInfo", "Data-driven Monte Carlo event info");
118  mTree->Branch("DataDrivenMcEventInfo", &mDataDrivenMcEventInfo);
119 
120  // Get Energy to ADC maker
121  mA2E = (StEEmcA2EMaker*)GetMakerInheritsFrom("StEEmcA2EMaker");
122  assert(mA2E);
123 
124  // Load pedestals from database
125  mEEmcDb = (StEEmcDb*)this->GetDataSet("StEEmcDb");
126  assert(mEEmcDb);
127 
128  // Clear ped & gain arrays
129  memset(mPed, 0, sizeof(mPed));
130  memset(mGain, 0, sizeof(mGain));
131 
132  return StMaker::Init();
133 }
134 
135 int StEEmcDataDrivenMcMaker::InitRun(int runNumber)
136 {
137  for (int sector = 0; sector < 12; ++sector) {
138  for (int plane = 0; plane < 2; ++plane) {
139  char uv = plane+'U';
140  for (int strip = 0; strip < 288; ++strip) {
141  //Database ranges: sector=1-12, plane=U-V, strip=1-288
142  const EEmcDbItem* x = mEEmcDb->getByStrip(sector+1, uv, strip+1);
143  assert(x);
144  mPed[sector][plane][strip] = mUsePed ? x->ped : 0;
145  mGain[sector][plane][strip] = mUsePed ? x->gain : StEEmcFastMaker::getSmdGain();
146  }
147  }
148  }
149 
150  return StMaker::InitRun(runNumber);
151 }
152 
154 {
155  // Get MuDst
156  if (!GetDataSet("MuDst")) {
157  LOG_WARN << "No MuDst" << endm;
158  return kStWarn;
159  }
160 
161  // Get MuDst EMC collection
163  if (!emc) {
164  LOG_WARN << "No MuDst EMC collection" << endm;
165  return kStWarn;
166  }
167 
168  // Load SMDU hits from MuDst
169  for (int plane = 1; plane <= 2; ++plane) {
170  char uv = 'U' + plane - 1;
171  for (int i = 0; i < emc->getNEndcapSmdHits(uv); ++i) {
172  int sector, strip;
173  StMuEmcHit* hit = emc->getEndcapSmdHit(uv, i, sector, strip);
174  hit->setAdc(int(hit->getAdc() + mPed[sector-1][plane-1][strip-1]));
175  mStrips[sector-1][plane-1][strip-1] = hit;
176  }
177  }
178 
179  // Get StMcEvent
180  mMcEvent = (StMcEvent*)GetDataSet("StMcEvent");
181 
182  if (!mMcEvent) {
183  LOG_WARN << "No StMcEvent" << endm;
184  return kStWarn;
185  }
186 
187  // Fill MC event info
188  mDataDrivenMcEventInfo->SetRunId(mMcEvent->runNumber());
189  mDataDrivenMcEventInfo->SetEventId(mMcEvent->eventNumber());
190 
191  // Get MuDst file name
192  if (StMuDstMaker* mudst = dynamic_cast<StMuDstMaker*>(GetMakerInheritsFrom("StMuDstMaker"))) {
193  mDataDrivenMcEventInfo->SetFileName(mudst->chain()->GetFile()->GetName());
194  }
195 
196  // Start with primary particles and look for final states
197  // photons recursively.
198  processVertex(mMcEvent->primaryVertex());
199 
200  // Fill tree
201  if (mDataDrivenMcEventInfo->NumberOfReplacements()) mTree->Fill();
202 
203  return kStOk;
204 }
205 
206 void StEEmcDataDrivenMcMaker::processVertex(StMcVertex* mcVertex)
207 {
208  for (unsigned int i = 0; i < mcVertex->numberOfDaughters(); ++i)
209  processTrack(mcVertex->daughter(i));
210 }
211 
212 void StEEmcDataDrivenMcMaker::processTrack(StMcTrack* mcTrack)
213 {
214  if (mcTrack->stopVertex()) {
215  // The particle decays; check its daughters.
216  processVertex(mcTrack->stopVertex());
217  }
218  else {
219  // This is a final state particle, i.e. it doesn't decay.
220  // Is it a photon, electron or positron?
221  if (mcTrack->geantId() < 1 || mcTrack->geantId() > 3) return;
222 
223  // We must have hits in both SMD planes
224  if (mcTrack->esmduHits().empty() && mcTrack->esmdvHits().empty()) return;
225 
226  // SMD hits must be contained in a single sector
227  if (multiSector(mcTrack->esmduHits()) || multiSector(mcTrack->esmdvHits())) return;
228 
229  // Get photon momentum and polar/zenith angle
230  TVector3 momentum(mcTrack->momentum().xyz());
231  float cosTheta = momentum.CosTheta();
232  if (!cosTheta) return;
233 
234  // Get z-position of SMD plane
235  float zSMD = EEmcGeomSimple::Instance().getZSMD();
236 
237  // Get z-position of collision vertex
238  TVector3 vertex(mcTrack->startVertex()->position().xyz());
239 
240  // Project photon into the SMD plane.
241  // First, we take the momentum vector and stretch it out
242  // to the SMD plane. Second, we add the collision vertex
243  // to get the position of the photon in the SMD plane
244  // starting at the origin of the STAR coordinate system.
245  TVector3 position = momentum;
246  float magnitude = (zSMD - vertex.z()) / cosTheta;
247  position.SetMag(magnitude);
248  position += vertex;
249 
250  // Photon must extrapolate to a valid tower
251  int sector = -1;
252  int subsector = -1;
253  int etabin = -1;
254  if (!EEmcGeomSimple::Instance().getTower(position, sector, subsector, etabin)) return;
255 
256  // Save replace information
257  StEEmcDataDrivenMcReplaceInfo* replaceInfo = mDataDrivenMcEventInfo->newReplaceInfo();
258 
259  int sectors[2];
260  int strips[2];
261 
262  for (int plane = 0; plane < 2; ++plane) {
263  // Get U and V strips closest to the extrapolated position of the photon in
264  // the SMD plane.
265  float dca;
266  const StructEEmcStrip* eemcStrip = EEmcSmdGeom::instance()->getDca2Strip(plane, position, &dca);
267  sectors[plane] = eemcStrip->stripStructId.sectorId - 1; // sector=0-11
268  strips [plane] = eemcStrip->stripStructId. stripId - 1; // strip=0-287
269 
270  // Get MC shower max hits
271  StPtrVecMcCalorimeterHit& hits = (plane == 0) ? mcTrack->esmduHits() : mcTrack->esmdvHits();
272 
273  // Loop over hits and determine max hit
274  StMcCalorimeterHit* maxHit = 0;
275 
276  for (size_t k = 0; k < hits.size(); ++k) {
277  StMcCalorimeterHit* hit = hits[k];
278  if (plane == 0)
279  replaceInfo->addMcHitEsmdU(hit);
280  else
281  replaceInfo->addMcHitEsmdV(hit);
282  if (!maxHit || hit->dE() > maxHit->dE()) maxHit = hit;
283  } // End hit loop
284 
285  if (maxHit) {
286  int maxId = maxHit->eta() - 1; // 0-287
287  if (plane == 0) {
288  replaceInfo->highStripShiftU = maxId - strips[plane];
289  }
290  else {
291  replaceInfo->highStripShiftV = maxId - strips[plane];
292  }
293  }
294  } // End plane loop
295 
296  getEnergies(mcTrack, replaceInfo);
297 
298  // Pick a random shower shape from the library. The shower shape and the Monte Carlo
299  // photon must be in the same sector configuration, same energy bin, and same preshower bin.
300  int iEnergyBin = !(mcTrack->energy() < 8);
301 
302  // Check range
303  assert(iEnergyBin >= 0 && iEnergyBin < NUMBER_OF_ENERGY_BINS);
304 
305  // Get preshower hit from MuDst
306  float pre1 = 0;
307  float pre2 = 0;
308  float post = 0;
309 
310  // Preshower hits loop
311  for (int i = 0; i < StMuDst::muEmcCollection()->getNEndcapPrsHits(); ++i) {
312  int sec; // 1-12
313  int sub; // 1-5
314  int eta; // 1-12
315  int layer; // 1-3 (1=pre1, 2=pre2, 3=post)
316  StMuEmcHit* hit = StMuDst::muEmcCollection()->getEndcapPrsHit(i, sec, sub, eta, layer);
317  if (sector+1 == sec && subsector+1 == sub && etabin+1 == eta) {
318  switch (layer) {
319  case 1: pre1 += hit->getEnergy(); break;
320  case 2: pre2 += hit->getEnergy(); break;
321  case 3: post += hit->getEnergy(); break;
322  default: break;
323  }
324  }
325  } // Preshower hits loop
326 
327  int iPreshowerBin = -1;
328 
329  if (pre1 == 0 && pre2 == 0)
330  iPreshowerBin = 0;
331  else if (pre1 == 0 && pre2 > 0)
332  iPreshowerBin = 1;
333  else if (pre1 > 0 && pre1 < 4e-3)
334  iPreshowerBin = 2;
335  else if (pre1 >= 4e-3)
336  iPreshowerBin = 3;
337  else {
338  LOG_ERROR << "Could not determine preshower bin" << endm;
339  exit(1);
340  }
341 
342  // Check range
343  assert(iPreshowerBin >= 0 && iPreshowerBin < NUMBER_OF_PRESHOWER_BINS);
344 
345  int iEntry = gRandom->Integer(mShowerShapes[iEnergyBin][iPreshowerBin]->GetEntriesFast());
346  StEEmcShowerShape* showerShape = (StEEmcShowerShape*)mShowerShapes[iEnergyBin][iPreshowerBin]->At(iEntry);
347  assert(showerShape);
348 
349  // Save replacement info
350  replaceInfo->pid = mcTrack->geantId();
351  replaceInfo->parentPid = mcTrack->parent()->geantId();
352  replaceInfo->libraryShapeId = mLibraryMap[showerShape];
353  replaceInfo->libraryBinId = iEnergyBin * NUMBER_OF_PRESHOWER_BINS + iPreshowerBin;
354  replaceInfo->energy = mcTrack->energy();
355  replaceInfo->momentum = mcTrack->momentum().xyz();
356 
357  // Determine the first hadron PID from the Pythia record
358  // (PDG code of grand parent for now)
359  if (mcTrack->parent()->parent())
360  replaceInfo->firstHadronPid = mcTrack->parent()->parent()->pdgId();
361 
362  // Match the Monte Carlo energy of the photon to the energy
363  // of the shower shape from the library computed by the
364  // cluster finder.
365  assert(showerShape->energy());
366 // float scale = mcTrack->energy() / showerShape->energy();
367 
368  // Replace simulation strips with strips from the shower shape
369  // in the library out to +mNumberOfStripsReplaced/-mNumberOfStripsReplaced
370  // strips of the max strip.
371  for (int plane = 0; plane < 2; ++plane) {
372  int& sector = sectors[plane];
373  int& strip = strips [plane];
374 
375  float scale = GetShowerShapeScale(mcTrack, showerShape, sector, plane, strip);
376  if (plane == 0){ replaceInfo->energyScaleU = scale; }else{ replaceInfo->energyScaleV = scale; }
377 
378  for (int dx = -mNumberOfStripsReplaced; dx <= mNumberOfStripsReplaced; ++dx) {
379  int id = strip + dx;
380  if (id < 0 || id >= 288) continue;
381  int highStrip = (plane == 0) ? showerShape->highUstripId() : showerShape->highVstripId();
382  int id2 = highStrip + dx;
383  assert(0 <= id2 && id2 < 288);
384  StMuEmcHit* hit2 = (plane == 0) ? showerShape->uStrip(id2) : showerShape->vStrip(id2);
385  StMuEmcHit* hit = mStrips[sector][plane][id]; // Can be 0 for simulation!
386  if (!hit) {
387  // There was no Monte Carlo hit for that strip.
388  // Create an empty hit in the MuDst and set
389  // its id using SMuEmcUtil.
390  int det = (plane == 0) ? esmdu : esmdv;
391  StMuDst::muEmcCollection()->addSmdHit(det);
392  int n = StMuDst::muEmcCollection()->getNSmdHits(det);
393  hit = StMuDst::muEmcCollection()->getSmdHit(n - 1, det);
394 
395  // int StMuEmcUtil::getEndcapId(int detector, int module, int eta, int sub, int& id);
396  // Parameters:
397  // detector=(bemc=1, bprs=2, bsmde=3, bsmdp=4, eemc=5, eprs=6, esmdu=7, esmdv=8)
398  // module=sector (1-12)
399  // eta=strip (1-288)
400  // sub=not used (always set to 1)
401  // id=hit id
402  // Return value:
403  // 0=okay
404  // 1=error
405  // Description:
406  // The id is encoded as 300*(module-1)+eta for ESMDU and ESMDV.
407  int id3;
408  assert(mMuEmcUtil->getEndcapId(det, sector+1, id+1, 1, id3) == 0);
409  hit->setId(id3);
410  hit->setAdc((int)mPed[sector][plane][id]);
411  hit->setEnergy(0);
412 
413  // Insert the newly created hit into
414  // the local strip table.
415  mStrips[sector][plane][id] = hit;
416  }
417 
418  // Find the corresponing Monte Carlo hit (identified by sector & strip id)
419  // and subtract its energy contribution to the SMD strip in the MuDst.
420  // If it is the only hit that deposited energy into that SMD strip, then
421  // the MC energy and MuDst energy are identical.
422  float dE = 0;
423  StPtrVecMcCalorimeterHit& mcHits = (plane == 0) ? mcTrack->esmduHits() : mcTrack->esmdvHits();
424  for (size_t i = 0; i < mcHits.size(); ++i) {
425  StMcCalorimeterHit* mcHit = mcHits[i];
426  if (mcHit->module() == sector+1 && mcHit->eta() == id+1) {
427  dE = mcHit->dE();
428  break;
429  }
430  }
431 
432  hit->setEnergy(hit->getEnergy() - dE);
433 
434  // Replace the energy contribution of the Monte Carlo hit with the
435  // corresponding hit from the shower shape library, appropriately
436  // scaled and translated, by adding the energy of the hit from the
437  // library to the strip in the MuDst.
438  hit->setEnergy(hit->getEnergy() + scale * hit2->getEnergy());
439 
440  // Set the ADC. Below is probably the correct way to do it,
441  // however the ADC were not saved for hits in the shower shape
442  // library!
443  //hit->setAdc(int(hit->getAdc() + scale * hit2->getAdc()));
444 
445  int adc = int(hit->getEnergy() * mGain[sector][plane][id] + mPed[sector][plane][id]);
446 // cout <<"sec " << sector<< " plane " << plane << " strip " << id << " gain " << mGain[sector][plane][strip] << " ped " << mPed[sector][plane][strip]<< endl;
447  if (adc < 0) adc = 0;
448  if (adc > StEEmcFastMaker::getMaxAdc()) adc = StEEmcFastMaker::getMaxAdc();
449  hit->setAdc(adc);
450  } // Loop over strips
451  } // Loop over planes
452  }
453 }
454 
456 {
457  if (mLogFile) {
458  mLogFile->Write();
459  mLogFile->Close();
460  }
461 
462  return kStOk;
463 }
464 
465 bool StEEmcDataDrivenMcMaker::multiSector(const vector<StMcCalorimeterHit*>& hits) const
466 {
467  for (size_t i = 0; i < hits.size(); ++i)
468  if (hits[i]->module() != hits[0]->module())
469  return true;
470  return false;
471 }
472 
473 int StEEmcDataDrivenMcMaker::getEnergyBin(StEEmcShowerShape* showerShape) const
474 {
475  return !(showerShape->energy() < 8);
476 }
477 
478 int StEEmcDataDrivenMcMaker::getPreshowerBin(StEEmcShowerShape* showerShape) const
479 {
480  float pre1 = showerShape->preshower1();
481  float pre2 = showerShape->preshower2();
482 
483  if (pre1 == 0 && pre2 == 0) return 0;
484  if (pre1 == 0 && pre2 > 0) return 1;
485  if (pre1 > 0 && pre1 < 4e-3) return 2;
486  if (pre1 >= 4e-3) return 3;
487 
488  return -1;
489 }
490 
491 void StEEmcDataDrivenMcMaker::getEnergies(StMcTrack *mcTrack, StEEmcDataDrivenMcReplaceInfo *replaceInfo)
492 {
493  // Loop over towers
494  const int NUMBER_OF_EEMC_LAYERS = 6;
495 
496  StPtrVecMcCalorimeterHit* hits[NUMBER_OF_EEMC_LAYERS];
497  StMcEmcHitCollection* emc[NUMBER_OF_EEMC_LAYERS];
498 
499  hits[0] = &mcTrack->eemcHits();
500  hits[1] = &mcTrack->eprsHits();
501  hits[4] = &mcTrack->esmduHits();
502  hits[5] = &mcTrack->esmdvHits();
503 
504  emc[0] = mMcEvent->eemcHitCollection();
505  emc[1] = mMcEvent->eprsHitCollection();
506  emc[4] = mMcEvent->esmduHitCollection();
507  emc[5] = mMcEvent->esmdvHitCollection();
508 
509  for (int layer = 0; layer < NUMBER_OF_EEMC_LAYERS; ++layer) {
510  if (layer == 2 || layer == 3) continue; // not implemented in StMcEvent
511  replaceInfo->nTowerFired[layer] = hits[layer]->size();
512 
513  vector<int> ids;
514 
515  replaceInfo->dEnergy[layer] = 0;
516  replaceInfo->totalEnergyScaled[layer] = 0;
517 
518  for (size_t i = 0; i < hits[layer]->size(); ++i) {
519  StMcCalorimeterHit* hit = hits[layer]->at(i);
520  replaceInfo->dEnergy[layer] += hit->dE();
521  int id = hit->sub() + 100 * hit->module() + 100000 * hit->eta();
522  ids.push_back(id);
523 
524  if (layer < 4) {
525  StEEmcTower tower = mA2E->tower(hit->module()-1, hit->sub()-1, hit->eta()-1);
526  replaceInfo->totalEnergyScaled[layer] += tower.energy();
527  }
528  else {
529  StEEmcStrip strip = mA2E->strip(hit->module()-1, hit->sub()-1, hit->eta()-1);
530  replaceInfo->totalEnergyScaled[layer] += strip.energy();
531  }
532  }
533 
534  replaceInfo->totalEnergy[layer] = 0;
535 
536  for (size_t m = 1; m <= emc[layer]->numberOfModules(); ++m) {
537  for (size_t k = 0; k < emc[layer]->module(m)->numberOfHits(); ++k) {
538  StMcCalorimeterHit* hit = emc[layer]->module(m)->hits().at(k);
539  int id = hit->sub() + 100 * hit->module() + 100000 * hit->eta();
540  if (find(ids.begin(), ids.end(), id) != ids.end()) {
541  replaceInfo->totalEnergy[layer] += hit->dE();
542  }
543  }
544  }
545  }
546 }
547 
548 float StEEmcDataDrivenMcMaker::GetShowerShapeScale
549 (
550  StMcTrack *mcTrack,
551  StEEmcShowerShape* showerShape,
552  int sector,
553  int plane,
554  int geantPhotonCentralStrip
555 )
556 {
557  float scale = 0;
558  switch (mShowerShapeScalingMethod)
559  {
560  case 1: // method 1: scale = E_smd^geant / E_smd^library
561  {
562  float smdEnergyGeant = 0; // SMD energy sum from Geant photon from +/- mNumberOfStripsReplaced strips
563  float smdEnergyLibrary = 0; // SMD energy sum from data-driven library photon in +/- mNumberOfStripsReplaced strips
564  for (int dx = -mNumberOfStripsReplaced; dx <= mNumberOfStripsReplaced; ++dx)
565  {
566  int id = geantPhotonCentralStrip + dx;
567  if (id < 0 || id >= 288) continue;
568  int highStrip = (plane == 0) ? showerShape->highUstripId() : showerShape->highVstripId();
569  int id2 = highStrip + dx;
570  assert(0 <= id2 && id2 < 288);
571  StMuEmcHit* hit2 = (plane == 0) ? showerShape->uStrip(id2) : showerShape->vStrip(id2);
572 
573  StPtrVecMcCalorimeterHit& mcHits = (plane == 0) ? mcTrack->esmduHits() : mcTrack->esmdvHits();
574  for (size_t i = 0; i < mcHits.size(); ++i)
575  {
576  StMcCalorimeterHit* mcHit = mcHits[i];
577  if (mcHit->module() == sector+1 && mcHit->eta() == id+1)
578  {
579  smdEnergyGeant += mcHit->dE();
580  break;
581  }
582  }
583  smdEnergyLibrary += hit2->getEnergy();
584  }
585  scale = smdEnergyGeant/smdEnergyLibrary;
586  break;
587  }
588  case 2: // method 2: scale = E_gamma^geant / E_gamma^library
589  {
590  scale = mcTrack->energy() / showerShape->energy();
591  break;
592  }
593  default: break;
594  }
595  return scale;
596 }
597 
EEmc ADC –&gt; energy maker.
static EEmcGeomSimple & Instance()
returns a reference to a static instance of EEmcGeomSimple
float getEnergy() const
Return Hit energy.
Definition: StMuEmcHit.h:21
StEEmcStrip & strip(Int_t sector, Int_t plane, Int_t strip)
virtual void Clear(Option_t *option="")
User defined functions.
Definition: StMaker.cxx:634
Monte Carlo Track class All information on a simulated track is stored in this class: kinematics...
Definition: StMcTrack.hh:144
int getAdc() const
Return ADC value.
Definition: StMuEmcHit.h:19
static Float_t getSmdGain()
(adc=g*de ) fixed gain for SMD
Base class for representing tower, preshower and postshower elements.
Definition: StEEmcTower.h:11
Float_t getZSMD() const
gets z-depth of the SMD layer in EEMC
static StMuEmcCollection * muEmcCollection()
returns pointer to current StMuEmcCollection
Definition: StMuDst.h:389
Definition: Stypes.h:42
StEEmcTower & tower(Int_t index, Int_t layer=0)
void Clear(Option_t *option="")
User defined functions.
void energy(Float_t e)
Set the energy (adc-ped+0.5)/gain for this element.
Definition: StEEmcElement.h:21
Event data structure to hold all information from a Monte Carlo simulation. This class is the interfa...
Definition: StMcEvent.hh:169
Base class for describing an endcap SMD strip.
Definition: StEEmcStrip.h:8
const StructEEmcStrip * getDca2Strip(const Int_t iUV, const TVector3 &point, Float_t *dca) const
Definition: Stypes.h:41