00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "TFile.h"
00014 #include "TTree.h"
00015 #include "TRandom.h"
00016 #include "TClonesArray.h"
00017 #include "TH1.h"
00018 #include "TH2.h"
00019 #include "TChain.h"
00020
00021
00022 #include "StEventTypes.h"
00023 #include "StMuDSTMaker/COMMON/StMuTypes.hh"
00024 #include "StMcEvent/StMcEventTypes.hh"
00025 #include "StEEmcUtil/database/EEmcDbItem.h"
00026 #include "StEEmcUtil/database/StEEmcDb.h"
00027 #include "StEEmcUtil/EEmcGeom/EEmcGeomSimple.h"
00028 #include "StEEmcUtil/StEEmcSmd/EEmcSmdGeom.h"
00029 #include "StEEmcSimulatorMaker/StEEmcFastMaker.h"
00030 #include "StEEmcPool/StEEmcA2EMaker/StEEmcA2EMaker.h"
00031
00032
00033 #include "StEEmcPool/StEEmcDataDrivenMcEventInfo/StEEmcDataDrivenMcEventInfo.h"
00034 #include "StEEmcShowerShape.h"
00035 #include "StEEmcDataDrivenMcMaker.h"
00036
00037 ClassImp(StEEmcDataDrivenMcMaker);
00038
00039 StEEmcDataDrivenMcMaker::StEEmcDataDrivenMcMaker(const char* name) : StMaker(name)
00040 {
00041 mUsePed = true;
00042 mEEmcDb = 0;
00043 }
00044
00045 void StEEmcDataDrivenMcMaker::Clear(Option_t* option)
00046 {
00047 memset(mStrips, 0, sizeof(mStrips));
00048 mDataDrivenMcEventInfo->Clear(option);
00049 StMaker::Clear(option);
00050 }
00051
00052 int StEEmcDataDrivenMcMaker::Init()
00053 {
00054
00055 mMcEvent = 0;
00056
00057
00058
00059
00060 TFile* file = new TFile(mLibraryFile);
00061 LOG_INFO << "Shower Shape Library = " << mLibraryFile << endm;
00062 assert(file && !file->IsZombie());
00063 TTree* tree = (TTree*)file->Get("etas");
00064 assert(tree);
00065 StEEmcShowerShape* showerShape = 0;
00066 tree->SetBranchAddress("StEEmcSmdResponse", &showerShape);
00067
00068 for (int i = 0; i < NUMBER_OF_ENERGY_BINS; ++i) {
00069 for (int j = 0; j < NUMBER_OF_PRESHOWER_BINS; ++j) {
00070 mShowerShapes[i][j] = new TClonesArray("StEEmcShowerShape");
00071 }
00072 }
00073
00074 for (int iEntry = 0; tree->GetEntry(iEntry) > 0; ++iEntry) {
00075 int uid = showerShape->highUstripId();
00076 int vid = showerShape->highVstripId();
00077
00078
00079 if (uid < mNumberOfStripsReplaced || uid > 288 - mNumberOfStripsReplaced-1 || vid < mNumberOfStripsReplaced || vid > 288-mNumberOfStripsReplaced-1) continue;
00080 assert(0 <= showerShape->sector() && showerShape->sector() < 12);
00081 int i = getEnergyBin(showerShape);
00082 int j = getPreshowerBin(showerShape);
00083 assert(i >= 0 && i < NUMBER_OF_ENERGY_BINS);
00084 assert(j >= 0 && j < NUMBER_OF_PRESHOWER_BINS);
00085 TClonesArray& tca = *mShowerShapes[i][j];
00086 mLibraryMap[new (tca[tca.GetEntriesFast()]) StEEmcShowerShape(*showerShape)] = iEntry;
00087 }
00088
00089 LOG_INFO << "Number of shower shapes in library = " << tree->GetEntriesFast() << endm;
00090
00091 for (int i = 0; i < NUMBER_OF_ENERGY_BINS; ++i) {
00092 for (int j = 0; j < NUMBER_OF_PRESHOWER_BINS; ++j) {
00093 LOG_INFO << "Energy bin =" << i
00094 << ", preshower bin=" << j
00095 << ", number of shower shapes=" << mShowerShapes[i][j]->GetEntriesFast()
00096 << endm;
00097 }
00098 }
00099
00100 file->Close();
00101
00102
00103 mMuEmcUtil = new StMuEmcUtil;
00104
00105
00106 mLogFile = 0;
00107
00108 if (mLogFileName != "") {
00109 mLogFile = TFile::Open(mLogFileName, "recreate");
00110 assert(mLogFile);
00111 }
00112
00113
00114 mDataDrivenMcEventInfo = new StEEmcDataDrivenMcEventInfo;
00115
00116
00117 mTree = new TTree("DataDrivenMcEventInfo", "Data-driven Monte Carlo event info");
00118 mTree->Branch("DataDrivenMcEventInfo", &mDataDrivenMcEventInfo);
00119
00120
00121 mA2E = (StEEmcA2EMaker*)GetMakerInheritsFrom("StEEmcA2EMaker");
00122 assert(mA2E);
00123
00124
00125 mEEmcDb = (StEEmcDb*)this->GetDataSet("StEEmcDb");
00126 assert(mEEmcDb);
00127
00128
00129 memset(mPed, 0, sizeof(mPed));
00130 memset(mGain, 0, sizeof(mGain));
00131
00132 return StMaker::Init();
00133 }
00134
00135 int StEEmcDataDrivenMcMaker::InitRun(int runNumber)
00136 {
00137 for (int sector = 0; sector < 12; ++sector) {
00138 for (int plane = 0; plane < 2; ++plane) {
00139 char uv = plane+'U';
00140 for (int strip = 0; strip < 288; ++strip) {
00141
00142 const EEmcDbItem* x = mEEmcDb->getByStrip(sector+1, uv, strip+1);
00143 assert(x);
00144 mPed[sector][plane][strip] = mUsePed ? x->ped : 0;
00145 mGain[sector][plane][strip] = mUsePed ? x->gain : StEEmcFastMaker::getSmdGain();
00146 }
00147 }
00148 }
00149
00150 return StMaker::InitRun(runNumber);
00151 }
00152
00153 int StEEmcDataDrivenMcMaker::Make()
00154 {
00155
00156 if (!GetDataSet("MuDst")) {
00157 LOG_WARN << "No MuDst" << endm;
00158 return kStWarn;
00159 }
00160
00161
00162 StMuEmcCollection* emc = StMuDst::muEmcCollection();
00163 if (!emc) {
00164 LOG_WARN << "No MuDst EMC collection" << endm;
00165 return kStWarn;
00166 }
00167
00168
00169 for (int plane = 1; plane <= 2; ++plane) {
00170 char uv = 'U' + plane - 1;
00171 for (int i = 0; i < emc->getNEndcapSmdHits(uv); ++i) {
00172 int sector, strip;
00173 StMuEmcHit* hit = emc->getEndcapSmdHit(uv, i, sector, strip);
00174 hit->setAdc(int(hit->getAdc() + mPed[sector-1][plane-1][strip-1]));
00175 mStrips[sector-1][plane-1][strip-1] = hit;
00176 }
00177 }
00178
00179
00180 mMcEvent = (StMcEvent*)GetDataSet("StMcEvent");
00181
00182 if (!mMcEvent) {
00183 LOG_WARN << "No StMcEvent" << endm;
00184 return kStWarn;
00185 }
00186
00187
00188 mDataDrivenMcEventInfo->SetRunId(mMcEvent->runNumber());
00189 mDataDrivenMcEventInfo->SetEventId(mMcEvent->eventNumber());
00190
00191
00192 if (StMuDstMaker* mudst = dynamic_cast<StMuDstMaker*>(GetMakerInheritsFrom("StMuDstMaker"))) {
00193 mDataDrivenMcEventInfo->SetFileName(mudst->chain()->GetFile()->GetName());
00194 }
00195
00196
00197
00198 processVertex(mMcEvent->primaryVertex());
00199
00200
00201 if (mDataDrivenMcEventInfo->NumberOfReplacements()) mTree->Fill();
00202
00203 return kStOk;
00204 }
00205
00206 void StEEmcDataDrivenMcMaker::processVertex(StMcVertex* mcVertex)
00207 {
00208 for (unsigned int i = 0; i < mcVertex->numberOfDaughters(); ++i)
00209 processTrack(mcVertex->daughter(i));
00210 }
00211
00212 void StEEmcDataDrivenMcMaker::processTrack(StMcTrack* mcTrack)
00213 {
00214 if (mcTrack->stopVertex()) {
00215
00216 processVertex(mcTrack->stopVertex());
00217 }
00218 else {
00219
00220
00221 if (mcTrack->geantId() < 1 || mcTrack->geantId() > 3) return;
00222
00223
00224 if (mcTrack->esmduHits().empty() && mcTrack->esmdvHits().empty()) return;
00225
00226
00227 if (multiSector(mcTrack->esmduHits()) || multiSector(mcTrack->esmdvHits())) return;
00228
00229
00230 TVector3 momentum(mcTrack->momentum().xyz());
00231 float cosTheta = momentum.CosTheta();
00232 if (!cosTheta) return;
00233
00234
00235 float zSMD = EEmcGeomSimple::Instance().getZSMD();
00236
00237
00238 TVector3 vertex(mcTrack->startVertex()->position().xyz());
00239
00240
00241
00242
00243
00244
00245 TVector3 position = momentum;
00246 float magnitude = (zSMD - vertex.z()) / cosTheta;
00247 position.SetMag(magnitude);
00248 position += vertex;
00249
00250
00251 int sector = -1;
00252 int subsector = -1;
00253 int etabin = -1;
00254 if (!EEmcGeomSimple::Instance().getTower(position, sector, subsector, etabin)) return;
00255
00256
00257 StEEmcDataDrivenMcReplaceInfo* replaceInfo = mDataDrivenMcEventInfo->newReplaceInfo();
00258
00259 int sectors[2];
00260 int strips[2];
00261 StMcCalorimeterHit* maxHits[2];
00262
00263 for (int plane = 0; plane < 2; ++plane) {
00264
00265
00266 float dca;
00267 const StructEEmcStrip* eemcStrip = EEmcSmdGeom::instance()->getDca2Strip(plane, position, &dca);
00268 sectors[plane] = eemcStrip->stripStructId.sectorId - 1;
00269 strips [plane] = eemcStrip->stripStructId. stripId - 1;
00270
00271
00272 StPtrVecMcCalorimeterHit& hits = (plane == 0) ? mcTrack->esmduHits() : mcTrack->esmdvHits();
00273
00274
00275 StMcCalorimeterHit* maxHit = 0;
00276
00277 for (size_t k = 0; k < hits.size(); ++k) {
00278 StMcCalorimeterHit* hit = hits[k];
00279 if (plane == 0)
00280 replaceInfo->addMcHitEsmdU(hit);
00281 else
00282 replaceInfo->addMcHitEsmdV(hit);
00283 if (!maxHit || hit->dE() > maxHit->dE()) maxHit = hit;
00284 }
00285
00286
00287 maxHits[plane] = maxHit;
00288
00289 if (maxHit) {
00290 int maxId = maxHit->eta() - 1;
00291 if (plane == 0) {
00292 replaceInfo->highStripShiftU = maxId - strips[plane];
00293 }
00294 else {
00295 replaceInfo->highStripShiftV = maxId - strips[plane];
00296 }
00297 }
00298 }
00299
00300 getEnergies(mcTrack, replaceInfo);
00301
00302
00303
00304 int iEnergyBin = !(mcTrack->energy() < 8);
00305
00306
00307 assert(iEnergyBin >= 0 && iEnergyBin < NUMBER_OF_ENERGY_BINS);
00308
00309
00310 float pre1 = 0;
00311 float pre2 = 0;
00312 float post = 0;
00313
00314
00315 for (int i = 0; i < StMuDst::muEmcCollection()->getNEndcapPrsHits(); ++i) {
00316 int sec;
00317 int sub;
00318 int eta;
00319 int layer;
00320 StMuEmcHit* hit = StMuDst::muEmcCollection()->getEndcapPrsHit(i, sec, sub, eta, layer);
00321 if (sector+1 == sec && subsector+1 == sub && etabin+1 == eta) {
00322 switch (layer) {
00323 case 1: pre1 += hit->getEnergy(); break;
00324 case 2: pre2 += hit->getEnergy(); break;
00325 case 3: post += hit->getEnergy(); break;
00326 default: break;
00327 }
00328 }
00329 }
00330
00331 int iPreshowerBin = -1;
00332
00333 if (pre1 == 0 && pre2 == 0)
00334 iPreshowerBin = 0;
00335 else if (pre1 == 0 && pre2 > 0)
00336 iPreshowerBin = 1;
00337 else if (pre1 > 0 && pre1 < 4e-3)
00338 iPreshowerBin = 2;
00339 else if (pre1 >= 4e-3)
00340 iPreshowerBin = 3;
00341 else {
00342 LOG_ERROR << "Could not determine preshower bin" << endm;
00343 exit(1);
00344 }
00345
00346
00347 assert(iPreshowerBin >= 0 && iPreshowerBin < NUMBER_OF_PRESHOWER_BINS);
00348
00349 int iEntry = gRandom->Integer(mShowerShapes[iEnergyBin][iPreshowerBin]->GetEntriesFast());
00350 StEEmcShowerShape* showerShape = (StEEmcShowerShape*)mShowerShapes[iEnergyBin][iPreshowerBin]->At(iEntry);
00351 assert(showerShape);
00352
00353
00354 replaceInfo->pid = mcTrack->geantId();
00355 replaceInfo->parentPid = mcTrack->parent()->geantId();
00356 replaceInfo->libraryShapeId = mLibraryMap[showerShape];
00357 replaceInfo->libraryBinId = iEnergyBin * NUMBER_OF_PRESHOWER_BINS + iPreshowerBin;
00358 replaceInfo->energy = mcTrack->energy();
00359 replaceInfo->momentum = mcTrack->momentum().xyz();
00360
00361
00362
00363 if (mcTrack->parent()->parent())
00364 replaceInfo->firstHadronPid = mcTrack->parent()->parent()->pdgId();
00365
00366
00367
00368
00369 assert(showerShape->energy());
00370
00371
00372
00373
00374
00375 for (int plane = 0; plane < 2; ++plane) {
00376 int& sector = sectors[plane];
00377 int& strip = strips [plane];
00378
00379 float scale = GetShowerShapeScale(mcTrack, showerShape, sector, plane, strip);
00380 if (plane == 0){ replaceInfo->energyScaleU = scale; }else{ replaceInfo->energyScaleV = scale; }
00381
00382 for (int dx = -mNumberOfStripsReplaced; dx <= mNumberOfStripsReplaced; ++dx) {
00383 int id = strip + dx;
00384 if (id < 0 || id >= 288) continue;
00385 int highStrip = (plane == 0) ? showerShape->highUstripId() : showerShape->highVstripId();
00386 int id2 = highStrip + dx;
00387 assert(0 <= id2 && id2 < 288);
00388 StMuEmcHit* hit2 = (plane == 0) ? showerShape->uStrip(id2) : showerShape->vStrip(id2);
00389 StMuEmcHit* hit = mStrips[sector][plane][id];
00390 if (!hit) {
00391
00392
00393
00394 int det = (plane == 0) ? esmdu : esmdv;
00395 StMuDst::muEmcCollection()->addSmdHit(det);
00396 int n = StMuDst::muEmcCollection()->getNSmdHits(det);
00397 hit = StMuDst::muEmcCollection()->getSmdHit(n - 1, det);
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 int id3;
00412 assert(mMuEmcUtil->getEndcapId(det, sector+1, id+1, 1, id3) == 0);
00413 hit->setId(id3);
00414 hit->setAdc((int)mPed[sector][plane][id]);
00415 hit->setEnergy(0);
00416
00417
00418
00419 mStrips[sector][plane][id] = hit;
00420 }
00421
00422
00423
00424
00425
00426 float dE = 0;
00427 StPtrVecMcCalorimeterHit& mcHits = (plane == 0) ? mcTrack->esmduHits() : mcTrack->esmdvHits();
00428 for (size_t i = 0; i < mcHits.size(); ++i) {
00429 StMcCalorimeterHit* mcHit = mcHits[i];
00430 if (mcHit->module() == sector+1 && mcHit->eta() == id+1) {
00431 dE = mcHit->dE();
00432 break;
00433 }
00434 }
00435
00436 hit->setEnergy(hit->getEnergy() - dE);
00437
00438
00439
00440
00441
00442 hit->setEnergy(hit->getEnergy() + scale * hit2->getEnergy());
00443
00444
00445
00446
00447
00448
00449 int adc = int(hit->getEnergy() * mGain[sector][plane][id] + mPed[sector][plane][id]);
00450
00451 if (adc < 0) adc = 0;
00452 if (adc > StEEmcFastMaker::getMaxAdc()) adc = StEEmcFastMaker::getMaxAdc();
00453 hit->setAdc(adc);
00454 }
00455 }
00456 }
00457 }
00458
00459 int StEEmcDataDrivenMcMaker::Finish()
00460 {
00461 if (mLogFile) {
00462 mLogFile->Write();
00463 mLogFile->Close();
00464 }
00465
00466 return kStOk;
00467 }
00468
00469 bool StEEmcDataDrivenMcMaker::multiSector(const vector<StMcCalorimeterHit*>& hits) const
00470 {
00471 for (size_t i = 0; i < hits.size(); ++i)
00472 if (hits[i]->module() != hits[0]->module())
00473 return true;
00474 return false;
00475 }
00476
00477 int StEEmcDataDrivenMcMaker::getEnergyBin(StEEmcShowerShape* showerShape) const
00478 {
00479 return !(showerShape->energy() < 8);
00480 }
00481
00482 int StEEmcDataDrivenMcMaker::getPreshowerBin(StEEmcShowerShape* showerShape) const
00483 {
00484 float pre1 = showerShape->preshower1();
00485 float pre2 = showerShape->preshower2();
00486
00487 if (pre1 == 0 && pre2 == 0) return 0;
00488 if (pre1 == 0 && pre2 > 0) return 1;
00489 if (pre1 > 0 && pre1 < 4e-3) return 2;
00490 if (pre1 >= 4e-3) return 3;
00491
00492 return -1;
00493 }
00494
00495 void StEEmcDataDrivenMcMaker::getEnergies(StMcTrack *mcTrack, StEEmcDataDrivenMcReplaceInfo *replaceInfo)
00496 {
00497
00498 const int NUMBER_OF_EEMC_LAYERS = 6;
00499
00500 StPtrVecMcCalorimeterHit* hits[NUMBER_OF_EEMC_LAYERS];
00501 StMcEmcHitCollection* emc[NUMBER_OF_EEMC_LAYERS];
00502
00503 hits[0] = &mcTrack->eemcHits();
00504 hits[1] = &mcTrack->eprsHits();
00505 hits[4] = &mcTrack->esmduHits();
00506 hits[5] = &mcTrack->esmdvHits();
00507
00508 emc[0] = mMcEvent->eemcHitCollection();
00509 emc[1] = mMcEvent->eprsHitCollection();
00510 emc[4] = mMcEvent->esmduHitCollection();
00511 emc[5] = mMcEvent->esmdvHitCollection();
00512
00513 for (int layer = 0; layer < NUMBER_OF_EEMC_LAYERS; ++layer) {
00514 if (layer == 2 || layer == 3) continue;
00515 replaceInfo->nTowerFired[layer] = hits[layer]->size();
00516
00517 vector<int> ids;
00518
00519 replaceInfo->dEnergy[layer] = 0;
00520 replaceInfo->totalEnergyScaled[layer] = 0;
00521
00522 for (size_t i = 0; i < hits[layer]->size(); ++i) {
00523 StMcCalorimeterHit* hit = hits[layer]->at(i);
00524 replaceInfo->dEnergy[layer] += hit->dE();
00525 int id = hit->sub() + 100 * hit->module() + 100000 * hit->eta();
00526 ids.push_back(id);
00527
00528 if (layer < 4) {
00529 StEEmcTower tower = mA2E->tower(hit->module()-1, hit->sub()-1, hit->eta()-1);
00530 replaceInfo->totalEnergyScaled[layer] += tower.energy();
00531 }
00532 else {
00533 StEEmcStrip strip = mA2E->strip(hit->module()-1, hit->sub()-1, hit->eta()-1);
00534 replaceInfo->totalEnergyScaled[layer] += strip.energy();
00535 }
00536 }
00537
00538 replaceInfo->totalEnergy[layer] = 0;
00539
00540 for (size_t m = 1; m <= emc[layer]->numberOfModules(); ++m) {
00541 for (size_t k = 0; k < emc[layer]->module(m)->numberOfHits(); ++k) {
00542 StMcCalorimeterHit* hit = emc[layer]->module(m)->hits().at(k);
00543 int id = hit->sub() + 100 * hit->module() + 100000 * hit->eta();
00544 if (find(ids.begin(), ids.end(), id) != ids.end()) {
00545 replaceInfo->totalEnergy[layer] += hit->dE();
00546 }
00547 }
00548 }
00549 }
00550 }
00551
00552 float StEEmcDataDrivenMcMaker::GetShowerShapeScale
00553 (
00554 StMcTrack *mcTrack,
00555 StEEmcShowerShape* showerShape,
00556 int sector,
00557 int plane,
00558 int geantPhotonCentralStrip
00559 )
00560 {
00561 float scale = 0;
00562 switch (mShowerShapeScalingMethod)
00563 {
00564 case 1:
00565 {
00566 float smdEnergyGeant = 0;
00567 float smdEnergyLibrary = 0;
00568 for (int dx = -mNumberOfStripsReplaced; dx <= mNumberOfStripsReplaced; ++dx)
00569 {
00570 int id = geantPhotonCentralStrip + dx;
00571 if (id < 0 || id >= 288) continue;
00572 int highStrip = (plane == 0) ? showerShape->highUstripId() : showerShape->highVstripId();
00573 int id2 = highStrip + dx;
00574 assert(0 <= id2 && id2 < 288);
00575 StMuEmcHit* hit2 = (plane == 0) ? showerShape->uStrip(id2) : showerShape->vStrip(id2);
00576
00577 StPtrVecMcCalorimeterHit& mcHits = (plane == 0) ? mcTrack->esmduHits() : mcTrack->esmdvHits();
00578 for (size_t i = 0; i < mcHits.size(); ++i)
00579 {
00580 StMcCalorimeterHit* mcHit = mcHits[i];
00581 if (mcHit->module() == sector+1 && mcHit->eta() == id+1)
00582 {
00583 smdEnergyGeant += mcHit->dE();
00584 break;
00585 }
00586 }
00587 smdEnergyLibrary += hit2->getEnergy();
00588 }
00589 scale = smdEnergyGeant/smdEnergyLibrary;
00590 break;
00591 }
00592 case 2:
00593 {
00594 scale = mcTrack->energy() / showerShape->energy();
00595 break;
00596 }
00597 default: break;
00598 }
00599 return scale;
00600 }
00601