00001
00002
00003 #include "StEmcSimulatorMaker.h"
00004
00005 #include <assert.h>
00006 #include <set>
00007
00008 #include "StMcEvent/StMcCalorimeterHit.hh"
00009 #include "StMcEvent/StMcEmcModuleHitCollection.hh"
00010 #include "StMcEvent/StMcEmcHitCollection.hh"
00011 #include "StMcEvent/StMcEvent.hh"
00012 #include "StMcEvent/StMcTrack.hh"
00013
00014 #include "StEvent/StEmcRawHit.h"
00015 #include "StEvent/StEmcDetector.h"
00016 #include "StEvent/StEmcCollection.h"
00017 #include "StEvent/StEvent.h"
00018
00019 #include "StMuDSTMaker/COMMON/StMuDst.h"
00020
00021 #include "StEmcUtil/database/StBemcTables.h"
00022 #include "StEmcUtil/geometry/StEmcGeom.h"
00023 #include "StEmcUtil/projection/StEmcPosition.h"
00024
00025 #include "StEmcSimpleSimulator.h"
00026 #include "StEmcPmtSimulator.h"
00027
00028 ClassImp(StEmcSimulatorMaker)
00029
00030 StEmcSimulatorMaker::StEmcSimulatorMaker(const char *name):StMaker(name) {
00031
00032 mEmbeddingMode = (GetMaker("emcRaw") || GetMaker("Eread"));
00033 LOG_INFO <<"StEmcSimulatorMaker EMBEDDING mode = "<< (Int_t)mEmbeddingMode <<endm;
00034
00035
00036 for(int i=0; i<MAXDETBARREL; i++) {
00037 mMakeFullDetector[i] = false;
00038 mCheckStatus[i] = true;
00039 mDoZeroSuppression[i] = (mEmbeddingMode) ? false:true;
00040 mPedestalCut[i] = 1.5;
00041 mCalibOffset[i] = 0.0;
00042 mCalibSpread[i] = 0.0;
00043 mMaxAdcSpread[i] = 0.0;
00044 mCrossTalk[i] = 0.0;
00045 }
00046
00047 mMaxAdc[0] = 4095;
00048 mMaxAdc[1] = 1023;
00049 mMaxAdc[2] = 1023;
00050 mMaxAdc[3] = 1023;
00051
00052
00053 mDoZeroSuppression[0] = false;
00054
00055
00056 mMakeFullDetector[0] = true;
00057
00058 mMcEvent = NULL;
00059 mEmcCollection = NULL;
00060
00061 for(int i=0; i<MAXDETBARREL; i++) {
00062 mEmcMcHits[i] = NULL;
00063 mGeom[i] = StEmcGeom::instance(i+1);
00064 if(!mGeom[i]) {
00065 LOG_FATAL << "Geometry for detector "<<i+1<<" undefined" << endm;
00066 assert(0);
00067 }
00068 }
00069
00070 mTables = new StBemcTables(kTRUE, kTRUE);
00071 mPosition = new StEmcPosition();
00072
00073
00074 mSimulatorMode[BTOW-1] = StEmcVirtualSimulator::kPrimarySecondaryFullMode;
00075 mSimulatorMode[BPRS-1] = StEmcVirtualSimulator::kPrimarySecondaryFullMode;
00076 mSimulatorMode[BSMDE-1] = StEmcVirtualSimulator::kSimpleMode;
00077 mSimulatorMode[BSMDP-1] = StEmcVirtualSimulator::kSimpleMode;
00078
00079 mIsBFC = GetParentChain()->InheritsFrom("StBFChain");
00080 LOG_INFO << "Is StEmcSimulatorMaker in BFC? " << mIsBFC << endm;
00081 }
00082
00083 StEmcSimulatorMaker::~StEmcSimulatorMaker() {
00084 delete mSimulator[BTOW-1];
00085 delete mSimulator[BPRS-1];
00086 delete mSimulator[BSMDE-1];
00087 delete mSimulator[BSMDP-1];
00088
00089 delete mTables;
00090 delete mPosition;
00091 }
00092
00093 Int_t StEmcSimulatorMaker::Init() {
00094 mSimulator[BTOW-1] = new StEmcPmtSimulator(kBarrelEmcTowerId, mSimulatorMode[BTOW-1]);
00095 mSimulator[BPRS-1] = new StEmcPmtSimulator(kBarrelEmcPreShowerId, mSimulatorMode[BPRS-1]);
00096 mSimulator[BSMDE-1] = new StEmcSimpleSimulator(kBarrelSmdEtaStripId, mSimulatorMode[BSMDE-1]);
00097 mSimulator[BSMDP-1] = new StEmcSimpleSimulator(kBarrelSmdPhiStripId, mSimulatorMode[BSMDP-1]);
00098
00099 for(int det=BTOW; det<=BSMDP; det++) {
00100 mSimulator[det-1]->setEmbeddingMode(mEmbeddingMode);
00101 mSimulator[det-1]->setTables(mTables);
00102 mSimulator[det-1]->setCalibScale(1.0 + mCalibOffset[det-1]);
00103 mSimulator[det-1]->setCalibSpread(mCalibSpread[det-1]);
00104 mSimulator[det-1]->setMaximumAdc(mMaxAdc[det-1]);
00105 mSimulator[det-1]->setMaximumAdcSpread(mMaxAdcSpread[det-1]);
00106 }
00107
00108 return kStOk;
00109 }
00110
00111 void StEmcSimulatorMaker::Clear(const char*) {
00112 mMcEvent = NULL;
00113 }
00114
00115 Int_t StEmcSimulatorMaker::Make() {
00116 mMcEvent = dynamic_cast<StMcEvent*>(GetDataSet("StMcEvent"));
00117 if(!mMcEvent) {
00118 LOG_ERROR << "couldn't find StMcEvent for this event" << endm;
00119 return kStErr;
00120 }
00121
00122 mEmcMcHits[0] = mMcEvent->bemcHitCollection();
00123 mEmcMcHits[1] = mMcEvent->bprsHitCollection();
00124 mEmcMcHits[2] = mMcEvent->bsmdeHitCollection();
00125 mEmcMcHits[3] = mMcEvent->bsmdpHitCollection();
00126
00127
00128 vector<StMcTrack*> McTracks = mMcEvent->tracks();
00129 for(unsigned int i = 0; i < McTracks.size(); ++i) {
00130 StMcTrack *track = McTracks.at(i);
00131 if(track->stopVertex()) continue;
00132 makeCrossTalk(track);
00133 }
00134
00135
00136 int maxChannels[4] = {4800, 4800, 18000, 18000};
00137 std::vector<int> hasHit;
00138 std::vector<int>::const_iterator iter;
00139
00140 int softId, module, eta, sub;
00141 for(int det=BTOW; det<=BSMDP; det++) {
00142 if(mMakeFullDetector[det-1] == 0) continue;
00143
00144
00145 for(unsigned int mod=1; mod<=mEmcMcHits[det-1]->numberOfModules(); mod++) {
00146 const StMcEmcModuleHitCollection* module = mEmcMcHits[det-1]->module(mod);
00147 const vector<StMcCalorimeterHit*> hits = module->detectorHits();
00148 for(unsigned long i=0; i<hits.size(); i++) {
00149 mGeom[det-1]->getId(hits[i]->module(), hits[i]->eta(), hits[i]->sub(), softId);
00150 hasHit.push_back(softId);
00151 }
00152 }
00153
00154
00155 std::sort(hasHit.begin(), hasHit.end());
00156 iter = hasHit.begin();
00157 int nextHitId = 0;
00158 if(hasHit.size()) nextHitId = *iter;
00159
00160 StMcCalorimeterHit *mcHit = new StMcCalorimeterHit();
00161
00162
00163 for(int softId=1; softId<=maxChannels[det-1]; softId++) {
00164 if( softId != nextHitId ) {
00165 mGeom[det-1]->getBin(softId,module,eta,sub);
00166 mcHit->setModule(module);
00167 mcHit->setEta(eta);
00168 mcHit->setSub(sub);
00169 mcHit->setdE(0.0);
00170 mcHit->setParentTrack(NULL);
00171
00172
00173 mEmcMcHits[det-1]->module(module)->detectorHits().push_back(mcHit);
00174 mcHit = new StMcCalorimeterHit();
00175 }
00176 else {
00177 iter++;
00178 if(iter != hasHit.end()) nextHitId = *iter;
00179 }
00180 }
00181
00182 delete mcHit;
00183 hasHit.clear();
00184 }
00185
00186
00187 for(int det=BTOW; det<=BSMDP; det++) {
00188 LOG_DEBUG << *(mEmcMcHits[det-1]) << endm;
00189 for(unsigned int mod=1; mod<=mEmcMcHits[det-1]->numberOfModules(); mod++) {
00190 const StMcEmcModuleHitCollection *module = mEmcMcHits[det-1]->module(mod);
00191 const vector<StMcCalorimeterHit*> hits = module->detectorHits();
00192 for(unsigned long i=0; i<hits.size(); i++) {
00193 int softId; mGeom[det-1]->getId(hits[i]->module(), hits[i]->eta(), hits[i]->sub(), softId);
00194 LOG_DEBUG << "softId:" << softId << " mod:" << hits[i]->module() << " eta:" << hits[i]->eta() << " sub:" << hits[i]->sub() << " dE:" << hits[i]->dE() << endm;
00195 }
00196 }
00197 }
00198
00199
00200 makeRawHits();
00201
00202 return StMaker::Make();
00203 }
00204
00205
00206 void StEmcSimulatorMaker::makeRawHits() {
00207 mTables->loadTables(this);
00208
00209
00210 if (mEmbeddingMode) {
00211 mEmcCollection = new StEmcCollection();
00212 } else {
00213 StEvent* event = (StEvent*)GetInputDS("StEvent");
00214 if (!event) {
00215 event = new StEvent();
00216 AddData(event);
00217 }
00218 mEmcCollection = event->emcCollection();
00219 if (!mEmcCollection) {
00220 mEmcCollection = new StEmcCollection();
00221 event->setEmcCollection(mEmcCollection);
00222 }
00223 StMuDst* mudst = (StMuDst*)GetInputDS("MuDst");
00224 if (mudst) {
00225 mudst->setEmcCollection(mEmcCollection);
00226 }
00227 }
00228
00229 for (int det = BTOW;det <= BSMDP;det++) {
00230 StDetectorId detectorId = kUnknownId;
00231 switch(det) {
00232 case BTOW: detectorId = kBarrelEmcTowerId; break;
00233 case BPRS: detectorId = kBarrelEmcPreShowerId; break;
00234 case BSMDE: detectorId = kBarrelSmdEtaStripId; break;
00235 case BSMDP: detectorId = kBarrelSmdPhiStripId; break;
00236 }
00237 StEmcDetector *detector = new StEmcDetector(detectorId, 120);
00238 mEmcCollection->setDetector(detector);
00239
00240 for (unsigned int mod = 1;mod <= mEmcMcHits[det-1]->numberOfModules();mod++) {
00241 const StMcEmcModuleHitCollection* module = mEmcMcHits[det-1]->module(mod);
00242 const vector<StMcCalorimeterHit*> hits = module->detectorHits();
00243 for (unsigned long i = 0;i < hits.size();i++) {
00244 int softId;
00245 mGeom[det-1]->getId(hits[i]->module(), hits[i]->eta(), hits[i]->sub(), softId);
00246 LOG_DEBUG << "-----------------------------------------------------------------------------------------------" << endm;
00247
00248 if (mCheckStatus[det-1]) {
00249 if (mTables->status(det, softId) != 1) {
00250 LOG_DEBUG << Form("det=%2d softId=%5d -- removing hit b/c DB status!=1", detectorId, softId) << endm;
00251 continue;
00252 }
00253 }
00254
00255 StEmcRawHit *rawHit = mSimulator[det-1]->makeRawHit(hits[i]);
00256 rawHit->setCalibrationType(0);
00257
00258
00259 if (mDoZeroSuppression[det-1]) {
00260 float pedMean = mTables->pedestal(det, softId);
00261 float pedRMS = mTables->pedestalRMS(det, softId);
00262 if ((rawHit->adc() - pedMean) < (mPedestalCut[det-1] * pedRMS)) {
00263 LOG_DEBUG << "removing hit b/c it failed pedestal cut" << endm;
00264 delete rawHit;
00265 continue;
00266 }
00267 }
00268
00269
00270 if (mIsBFC && !mEmbeddingMode) {
00271 rawHit->setEnergy(hits[i]->dE());
00272 }
00273
00274 detector->addHit(rawHit);
00275 }
00276 }
00277 }
00278 }
00279
00281
00282
00284 void StEmcSimulatorMaker::makeCrossTalk(StMcTrack *track)
00285 {
00286
00287 for (int det = BSMDE;det <= BSMDP;++det) {
00288
00289 if(det == BSMDP) continue;
00290
00291 vector<StMcCalorimeterHit*> trackHits;
00292 switch(det) {
00293 case BSMDE: trackHits = track->bsmdeHits(); break;
00294 case BSMDP: trackHits = track->bsmdpHits(); break;
00295 }
00296 LOG_DEBUG << " this track has BSMD of size = " << trackHits.size() << endm;
00297
00299
00301 double highEnergy = -1;
00302 int highElement = -1;
00303 for (unsigned long j = 0;j < trackHits.size();++j) {
00304 double energy = trackHits.at(j)->dE();
00305 if ((energy > highEnergy) || (highEnergy < 0)) {
00306 highEnergy = energy;
00307 highElement = j;
00308 }
00309 }
00310 if (highElement != -1) {
00312
00314 StMcCalorimeterHit* highHit = trackHits.at(highElement);
00315
00316 const Int_t numCross = 5;
00317 int softIds[2 * numCross + 1] = {0};
00318
00319
00320 StMcCalorimeterHit *detectorNextHits[2 * numCross + 1] = {0};
00321
00322 switch (det) {
00323
00324 case BSMDE:
00325 case BSMDP:
00326 for (Int_t i = 0;i < (2*numCross + 1);i++) {
00327 softIds[i] = mPosition->getNextId(det, highHit->module(), highHit->eta(), highHit->sub(), (det == BSMDE) ? (i - numCross) : 0, (det == BSMDP) ? (i - numCross) : 0);
00328 }
00329 break;
00330 }
00331
00332 int modHigh = 0;
00333 float etaHigh = 0;
00334 mGeom[det - 1]->getId(highHit->module(), highHit->eta(), highHit->sub(), softIds[numCross]);
00335 modHigh = highHit->module();
00336 mGeom[det - 1]->getEta(softIds[numCross], etaHigh);
00337
00339
00341 double totalenergyb = 0;
00342 double totalenergya = 0;
00343 for (unsigned int mod = 1;mod <= mEmcMcHits[det- 1]->numberOfModules();++mod) {
00344 const StMcEmcModuleHitCollection* module = mEmcMcHits[det - 1]->module(mod);
00345 const vector<StMcCalorimeterHit*> &detectorHits = module->detectorHits();
00346 for (unsigned long k = 0;k < detectorHits.size();++k) {
00347 int softTemp;
00348 mGeom[det - 1]->getId(detectorHits[k]->module(), detectorHits[k]->eta(), detectorHits[k]->sub(), softTemp);
00349
00350 for (Int_t i = 0;i < (2*numCross + 1);i++) {
00351 if (softTemp == softIds[i]) {
00352 detectorNextHits[i] = detectorHits[k];
00353 totalenergyb += detectorHits[k]->dE();
00354 }
00355 }
00356 }
00357 }
00358
00359
00360 const float crossTalk = mCrossTalk[det - 1] * (1 - fabs(etaHigh) );
00361
00362 double leakE1 = 0, leakE2 = 0;
00363 StMcCalorimeterHit *tempHit = new StMcCalorimeterHit();
00364 for (int i = 0;i <= numCross;i++) {
00365 double energy1 = detectorNextHits[numCross + i] ? detectorNextHits[numCross + i]->dE() : 0;
00366 double energy2 = detectorNextHits[numCross - i] ? detectorNextHits[numCross - i]->dE() : 0;
00367 {LOG_DEBUG << "In: softId1 = " << softIds[numCross + i] << ", softId2 = " << softIds[numCross - i] << endm;}
00368 {LOG_DEBUG << "In: energy1 = " << energy1 << ", energy2 = " << energy2 << endm;}
00369 {LOG_DEBUG << "In: leakE1 = " << leakE1 << ", leakE2 = " << leakE2 << endm;}
00370
00371 energy1 += leakE1;
00372 energy2 += leakE2;
00373
00374
00375
00376
00377
00378 if ((i < numCross) && softIds[numCross + i] && softIds[numCross + (i + 1)]) {
00379
00380 const double energyNext1 = detectorNextHits[numCross + (i + 1)] ? detectorNextHits[numCross + (i + 1)]->dE() : 0;
00381
00382 leakE1 = crossTalk * (energy1 - energyNext1);
00383 } else {
00384 leakE1 = 0;
00385 }
00386
00387 if ((i < numCross) && softIds[numCross - i] && softIds[numCross - (i + 1)]) {
00388
00389 const double energyNext2 = detectorNextHits[numCross - (i + 1)] ? detectorNextHits[numCross - (i + 1)]->dE() : 0;
00390
00391 leakE2 = crossTalk * (energy2 - energyNext2);
00392 } else {
00393 leakE2 = 0;
00394 }
00395
00396 energy1 -= leakE1;
00397 if (i == 0) {
00398 energy1 -= leakE2;
00399 } else {
00400 energy2 -= leakE2;
00401 }
00402 {LOG_DEBUG << "Out: energy1 = " << energy1 << ", energy2 = " << energy2 << endm;}
00403 {LOG_DEBUG << "Out: leakE1 = " << leakE1 << ", leakE2 = " << leakE2 << endm;}
00404
00405 int module, eta, sub;
00406 if (detectorNextHits[numCross + i]) {
00407 detectorNextHits[numCross + i]->setdE(energy1);
00408 } else {
00409 if (softIds[numCross + i]) {
00411
00412
00414 mGeom[det - 1]->getBin(softIds[numCross + i], module, eta, sub);
00415 tempHit->setModule(module);
00416 tempHit->setEta(eta);
00417 tempHit->setSub(sub);
00418 tempHit->setParentTrack(NULL);
00419 tempHit->setdE(energy1);
00420 detectorNextHits[numCross + i] = tempHit;
00421 StMcEmcHitCollection::EAddHit returnCode = mEmcMcHits[det - 1]->addHit(tempHit);
00422 if (returnCode == StMcEmcHitCollection::kNew) {
00423 tempHit = new StMcCalorimeterHit();
00424 }
00425 }
00426 }
00427 if (i != 0) {
00428 if (detectorNextHits[numCross - i]) {
00429 detectorNextHits[numCross - i]->setdE(energy2);
00430 } else {
00431 if (softIds[numCross - i]) {
00432 mGeom[det - 1]->getBin(softIds[numCross - i], module, eta, sub);
00433 tempHit->setModule(module);
00434 tempHit->setEta(eta);
00435 tempHit->setSub(sub);
00436 tempHit->setParentTrack(NULL);
00437 tempHit->setdE(energy2);
00438 detectorNextHits[numCross - i] = tempHit;
00439 StMcEmcHitCollection::EAddHit returnCode = mEmcMcHits[det - 1]->addHit(tempHit);
00440 if (returnCode == StMcEmcHitCollection::kNew) {
00441 tempHit = new StMcCalorimeterHit();
00442 }
00443 }
00444 }
00445 }
00446 totalenergya += detectorNextHits[numCross + i] ? detectorNextHits[numCross + i]->dE() : 0;
00447 if (i != 0) totalenergya += detectorNextHits[numCross - i] ? detectorNextHits[numCross - i]->dE() : 0;
00448 }
00449 {LOG_DEBUG << "total energy before is " << totalenergyb << " and total energy after immediately, is " << totalenergya << endm;}
00450 delete tempHit;
00451 }
00452 }
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643