Go to the documentation of this file.00001 #include "FastSimulation/CaloRecHitsProducer/interface/EcalEndcapRecHitsMaker.h"
00002 #include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h"
00003 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00004 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00005 #include "FastSimulation/Utilities/interface/GaussianTail.h"
00006
00007 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"
00008 #include "SimDataFormats/CrossingFrame/interface/MixCollection.h"
00009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00010 #include "DataFormats/Common/interface/Handle.h"
00011 #include "FWCore/Framework/interface/ESHandle.h"
00012 #include "FWCore/Framework/interface/Event.h"
00013 #include "FWCore/Framework/interface/EventSetup.h"
00014 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00015 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00016 #include "Geometry/EcalAlgo/interface/EcalEndcapGeometry.h"
00017 #include "CondFormats/EcalObjects/interface/EcalIntercalibConstants.h"
00018 #include "CondFormats/DataRecord/interface/EcalIntercalibConstantsRcd.h"
00019 #include "CondFormats/EcalObjects/interface/EcalIntercalibConstantsMC.h"
00020 #include "CondFormats/DataRecord/interface/EcalIntercalibConstantsMCRcd.h"
00021 #include "CondFormats/EcalObjects/interface/EcalADCToGeVConstant.h"
00022 #include "CondFormats/DataRecord/interface/EcalADCToGeVConstantRcd.h"
00023
00024 #include "Geometry/CaloTopology/interface/EcalTrigTowerConstituentsMap.h"
00025
00026 #include "CLHEP/GenericFunctions/Erf.hh"
00027
00028 #include <algorithm>
00029
00030 EcalEndcapRecHitsMaker::EcalEndcapRecHitsMaker(edm::ParameterSet const & p,
00031
00032 const RandomEngine * myrandom)
00033 : random_(myrandom)
00034 {
00035 edm::ParameterSet RecHitsParameters=p.getParameter<edm::ParameterSet>("ECALEndcap");
00036 inputCol_=RecHitsParameters.getParameter<edm::InputTag>("MixedSimHits");
00037 noise_ = RecHitsParameters.getParameter<double>("Noise");
00038 threshold_ = RecHitsParameters.getParameter<double>("Threshold");
00039 SRThreshold_ = RecHitsParameters.getParameter<double> ("SRThreshold");
00040 refactor_ = RecHitsParameters.getParameter<double> ("Refactor");
00041 refactor_mean_ = RecHitsParameters.getParameter<double> ("Refactor_mean");
00042 noiseADC_ = RecHitsParameters.getParameter<double>("NoiseADC");
00043 highNoiseParameters_ = RecHitsParameters.getParameter<std::vector<double> > ("HighNoiseParameters");
00044
00045 theCalorimeterHits_.resize(EEDetId::kSizeForDenseIndexing,0.);
00046 applyZSCells_.resize(EEDetId::kSizeForDenseIndexing,true);
00047 towerOf_.resize(EEDetId::kSizeForDenseIndexing);
00048 theTTDetIds_.resize(1440);
00049 SCofTT_.resize(1440);
00050 SCHighInterest_.resize(633,0);
00051 treatedSC_.resize(633,false);
00052 TTofSC_.resize(633);
00053 TTTEnergy_.resize(1440,0.);
00054 CrystalsinSC_.resize(633);
00055 sinTheta_.resize(EEDetId::kEEhalf,0.);
00056 doCustomHighNoise_=false;
00057
00058 noisified_ = (noise_==0.);
00059 edm::ParameterSet CalibParameters=RecHitsParameters.getParameter<edm::ParameterSet>("ContFact");
00060 double c1 = CalibParameters.getParameter<double>("EEs25notContainment");
00061 calibfactor_= 1./c1;
00062 }
00063
00064
00065 EcalEndcapRecHitsMaker::~EcalEndcapRecHitsMaker()
00066 {;
00067 }
00068
00069 void EcalEndcapRecHitsMaker::clean()
00070 {
00071
00072 unsigned size=theFiredCells_.size();
00073 for(unsigned ic=0;ic<size;++ic)
00074 {
00075 theCalorimeterHits_[theFiredCells_[ic]] = 0.;
00076 applyZSCells_[theFiredCells_[ic]] = false;
00077 }
00078 theFiredCells_.clear();
00079
00080 noisified_ = (noise_==0.);
00081
00082 size=theFiredTTs_.size();
00083
00084 for(unsigned itt=0;itt<size;++itt)
00085 {
00086
00087 TTTEnergy_[theFiredTTs_[itt]]=0.;
00088 }
00089 theFiredTTs_.clear();
00090
00091 size=theFiredSC_.size();
00092 for(unsigned isc=0;isc<size;++isc)
00093 {
00094 SCHighInterest_[theFiredSC_[isc]]=0;
00095 treatedSC_[theFiredSC_[isc]]=false;
00096 }
00097 theFiredSC_.clear();
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 }
00108
00109
00110 void EcalEndcapRecHitsMaker::loadEcalEndcapRecHits(edm::Event &iEvent,EERecHitCollection & ecalHits,EEDigiCollection & ecalDigis)
00111 {
00112 clean();
00113 loadPCaloHits(iEvent);
00114
00115 unsigned nhit=theFiredCells_.size();
00116 unsigned gain, adc;
00117 ecalDigis.reserve(nhit);
00118 ecalHits.reserve(nhit);
00119 for(unsigned ihit=0;ihit<nhit;++ihit)
00120 {
00121 unsigned icell = theFiredCells_[ihit];
00122
00123 EEDetId myDetId(endcapRawId_[icell]);
00124 if(doDigis_)
00125 {
00126 ecalDigis.push_back( myDetId );
00127 EEDataFrame myDataFrame( ecalDigis.back() );
00128
00129
00130 geVtoGainAdc(theCalorimeterHits_[icell],gain,adc);
00131 myDataFrame.setSample(0,EcalMGPASample(adc,gain));
00132
00133 }
00134
00135
00136
00137 float energy=theCalorimeterHits_[icell];
00138
00139
00140 if ( energy<threshold_*((*ICMC_)[icell]) && !isHighInterest(myDetId) && applyZSCells_[icell])
00141 {
00142 theCalorimeterHits_[icell]=0.;
00143
00144
00145 energy=0.;
00146 }
00147 else
00148 if( energy > sat_)
00149 {
00150 energy=sat_;
00151 theCalorimeterHits_[icell]=sat_;
00152 }
00153 if(energy!=0.)
00154 {
00155 ecalHits.push_back(EcalRecHit(myDetId,energy,0.));
00156 }
00157 }
00158 noisified_ = true;
00159
00160 }
00161
00162 void EcalEndcapRecHitsMaker::loadPCaloHits(const edm::Event & iEvent)
00163 {
00164
00165 edm::Handle<CrossingFrame<PCaloHit> > cf;
00166 iEvent.getByLabel(inputCol_,cf);
00167 std::auto_ptr<MixCollection<PCaloHit> > colcalo(new MixCollection<PCaloHit>(cf.product(),std::pair<int,int>(0,0) ));
00168
00169 theFiredCells_.reserve(colcalo->size());
00170 MixCollection<PCaloHit>::iterator cficalo;
00171 MixCollection<PCaloHit>::iterator cficaloend=colcalo->end();
00172 for (cficalo=colcalo->begin(); cficalo!=cficaloend;cficalo++)
00173 {
00174
00175 unsigned hashedindex = EEDetId(cficalo->id()).hashedIndex();
00176
00177 float calib=(doMisCalib_) ? calibfactor_*theCalibConstants_[hashedindex]:calibfactor_;
00178 if(theCalorimeterHits_[hashedindex]==0.)
00179 {
00180 theFiredCells_.push_back(hashedindex);
00181 float noise=(noise_==-1.) ? noisesigma_[hashedindex] : noise_ ;
00182 if (!noisified_ ) {
00183 theCalorimeterHits_[hashedindex] += random_->gaussShoot(0.,noise*calib);
00184 }
00185 }
00186
00187
00188
00189
00190
00191 float energy=(cficalo->energy()==0.) ? 0.000001 : cficalo->energy() ;
00192 energy*=calib;
00193 theCalorimeterHits_[hashedindex]+=energy;
00194
00195
00196 int TThashedindex=towerOf_[hashedindex];
00197
00198 if(TTTEnergy_[TThashedindex]==0.)
00199 {
00200 theFiredTTs_.push_back(TThashedindex);
00201 }
00202
00203 TTTEnergy_[TThashedindex]+=energy*sinTheta_[(hashedindex<EEDetId::kEEhalf)? hashedindex : hashedindex-EEDetId::kEEhalf];
00204
00205 }
00206
00207 noisifyTriggerTowers();
00208 randomNoisifier();
00209 }
00210
00211 void EcalEndcapRecHitsMaker::noisifyTriggerTowers()
00212 {
00213 if(noise_==0.) return;
00214
00215
00216 unsigned nTT=theFiredTTs_.size();
00217 for(unsigned itt=0;itt<nTT;++itt)
00218 {
00219
00220
00221 noisifySuperCrystals(theFiredTTs_[itt]);
00222 }
00223 }
00224
00225
00226 void EcalEndcapRecHitsMaker::noisifySuperCrystals(int tthi)
00227 {
00228 unsigned size=SCofTT_[tthi].size();
00229
00230 for(unsigned isc=0;isc<size;++isc)
00231 {
00232
00233
00234 if(treatedSC_[SCofTT_[tthi][isc]]) continue;
00235
00236 const std::vector<int> & xtals(CrystalsinSC_[SCofTT_[tthi][isc]]);
00237 unsigned nxtals=xtals.size();
00238 unsigned count=0;
00239
00240
00241
00242
00243 for(unsigned ix=0;ix<nxtals;++ix)
00244 {
00245 unsigned hashedindex=xtals[ix];
00246
00247
00248 if(theCalorimeterHits_[hashedindex]==0.)
00249 {
00250 float calib = (doMisCalib_) ? calibfactor_*theCalibConstants_[hashedindex]:calibfactor_;
00251 float noise = (noise_==-1.) ? noisesigma_[hashedindex]:noise_;
00252 float energy = calib*random_->gaussShoot(0.,noise);
00253 theCalorimeterHits_[hashedindex]=energy;
00254 theFiredCells_.push_back(hashedindex);
00255
00256 int newtthi=towerOf_[hashedindex];
00257
00258 if(TTTEnergy_[newtthi]==0.)
00259 {
00260 theFiredTTs_.push_back(newtthi);
00261 }
00262 TTTEnergy_[newtthi]+=energy*sinTheta_[(hashedindex<EEDetId::kEEhalf)? hashedindex : hashedindex-EEDetId::kEEhalf];
00263 ++count;
00264 }
00265 }
00266 treatedSC_[SCofTT_[tthi][isc]]=true;
00267
00268 }
00269 }
00270
00271
00272
00273
00274
00275
00276 void EcalEndcapRecHitsMaker::randomNoisifier()
00277 {
00278
00279 double mean = (double)(EEDetId::kSizeForDenseIndexing-theFiredCells_.size())*EEHotFraction_;
00280 unsigned ncells= random_->poissonShoot(mean);
00281
00282
00283
00284
00285 if(noise_==-1. && !doCustomHighNoise_)
00286 ncells=EEDetId::kSizeForDenseIndexing;
00287
00288 unsigned icell=0;
00289 while(icell < ncells)
00290 {
00291 unsigned cellindex= (noise_!=-1. || doCustomHighNoise_) ?
00292 (unsigned)(floor(random_->flatShoot()*EEDetId::kSizeForDenseIndexing)): icell ;
00293
00294 if(theCalorimeterHits_[cellindex]==0.)
00295 {
00296
00297 double energy=0.;
00298 if(noise_>0.)
00299 energy=myGaussianTailGenerator_->shoot();
00300 if(noise_==-1.)
00301 {
00302
00303
00304
00305 float noisemean = (doCustomHighNoise_)? highNoiseParameters_[0]*(*ICMC_)[cellindex]*adcToGeV_: 0.;
00306 float noisesigma = (doCustomHighNoise_)? highNoiseParameters_[1]*(*ICMC_)[cellindex]*adcToGeV_ : noisesigma_[cellindex];
00307 energy=random_->gaussShoot(noisemean,noisesigma);
00308
00309
00310 if(doCustomHighNoise_) applyZSCells_[cellindex]=false;
00311 }
00312 float calib = (doMisCalib_) ? calibfactor_*theCalibConstants_[cellindex]:calibfactor_;
00313 energy *= calib;
00314 theCalorimeterHits_[cellindex]=energy;
00315 theFiredCells_.push_back(cellindex);
00316 EEDetId myDetId(EEDetId::unhashIndex(cellindex));
00317
00318 int TThashedindex=towerOf_[cellindex];
00319
00320 if(TTTEnergy_[TThashedindex]==0.)
00321 {
00322 theFiredTTs_.push_back(TThashedindex);
00323 TTTEnergy_[TThashedindex]+=energy*sinTheta_[(cellindex<EEDetId::kEEhalf)?cellindex : cellindex-EEDetId::kEEhalf];
00324
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 if(noise_>0.)
00342 ++icell;
00343 }
00344 if(noise_==-1.)
00345 ++icell;
00346 }
00347
00348 }
00349
00350
00351 void EcalEndcapRecHitsMaker::init(const edm::EventSetup &es,bool doDigis,bool domiscalib)
00352 {
00353 doDigis_=doDigis;
00354 doMisCalib_=domiscalib;
00355
00356
00357 edm::ESHandle<EcalADCToGeVConstant> agc;
00358 es.get<EcalADCToGeVConstantRcd>().get(agc);
00359
00360 adcToGeV_= agc->getEEValue() ;
00361 minAdc_ = 200;
00362 maxAdc_ = 4085;
00363
00364 geVToAdc1_ = 1./adcToGeV_;
00365 geVToAdc2_ = geVToAdc1_/2.;
00366 geVToAdc3_ = geVToAdc1_/12.;
00367
00368 t1_ = ((int)maxAdc_-(int)minAdc_)*adcToGeV_;
00369 t2_ = 2.* t1_ ;
00370
00371 sat_ = 12.*t1_*calibfactor_;
00372
00373 endcapRawId_.resize(EEDetId::kSizeForDenseIndexing);
00374
00375 if (doMisCalib_) theCalibConstants_.resize(EEDetId::kSizeForDenseIndexing);
00376
00377 edm::ESHandle<CaloGeometry> pG;
00378 es.get<CaloGeometryRecord>().get(pG);
00379
00380 edm::ESHandle<EcalTrigTowerConstituentsMap> hetm;
00381 es.get<IdealGeometryRecord>().get(hetm);
00382 eTTmap_ = &(*hetm);
00383
00384 const EcalEndcapGeometry * myEcalEndcapGeometry = dynamic_cast<const EcalEndcapGeometry*>(pG->getSubdetectorGeometry(DetId::Ecal,EcalEndcap));
00385 const std::vector<DetId>& vec(myEcalEndcapGeometry->getValidDetIds(DetId::Ecal,EcalEndcap));
00386 unsigned size=vec.size();
00387 for(unsigned ic=0; ic<size; ++ic)
00388 {
00389 EEDetId myDetId(vec[ic]);
00390 int cellhashedindex=myDetId.hashedIndex();
00391 endcapRawId_[cellhashedindex]=vec[ic].rawId();
00392
00393 if (cellhashedindex< EEDetId::kEEhalf)
00394 {
00395 float sintheta=std::sin(myEcalEndcapGeometry->getGeometry(myDetId)->getPosition().theta());
00396 sinTheta_[cellhashedindex]=sintheta;
00397 }
00398
00399
00400 EcalTrigTowerDetId towid1= eTTmap_->towerOf(vec[ic]);
00401 int tthashedindex=TThashedIndexforEE(towid1);
00402 towerOf_[cellhashedindex]=tthashedindex;
00403
00404
00405 int schi=SChashedIndex(EEDetId(vec[ic]));
00406 if(schi<0)
00407 {
00408
00409 EEDetId myID(vec[ic]);
00410
00411 }
00412
00413 theTTDetIds_[tthashedindex]=towid1;
00414
00415
00416 std::vector<int>::const_iterator itcheck=find(SCofTT_[tthashedindex].begin(),
00417 SCofTT_[tthashedindex].end(),
00418 schi);
00419 if(itcheck==SCofTT_[tthashedindex].end())
00420 SCofTT_[tthashedindex].push_back(schi);
00421
00422
00423 itcheck=find(CrystalsinSC_[schi].begin(),CrystalsinSC_[schi].end(),cellhashedindex);
00424 if(itcheck==CrystalsinSC_[schi].end())
00425 CrystalsinSC_[schi].push_back(cellhashedindex);
00426
00427
00428
00429
00430 itcheck=find(TTofSC_[schi].begin(),TTofSC_[schi].end(),tthashedindex);
00431 if(itcheck==TTofSC_[schi].end())
00432 TTofSC_[schi].push_back(tthashedindex);
00433 }
00434
00435
00436 if(doMisCalib_||noise_==-1.)
00437 {
00438 double rms=0.;
00439 double mean=0.;
00440 unsigned ncells=0;
00441
00442 if(noise_==-1.)
00443 noisesigma_.resize(EEDetId::kSizeForDenseIndexing);
00444
00445
00446 edm::ESHandle<EcalIntercalibConstantsMC> pJcal;
00447 es.get<EcalIntercalibConstantsMCRcd>().get(pJcal);
00448 const EcalIntercalibConstantsMC* jcal = pJcal.product();
00449 const std::vector<float>& ICMC = jcal->endcapItems();
00450
00451
00452 ICMC_ = &ICMC;
00453
00454
00455
00456
00457 edm::ESHandle<EcalIntercalibConstants> pIcal;
00458 es.get<EcalIntercalibConstantsRcd>().get(pIcal);
00459 const EcalIntercalibConstants* ical = pIcal.product();
00460 const std::vector<float>& IC = ical->endcapItems();
00461
00462
00463 unsigned nic = IC.size();
00464 meanNoiseSigmaEt_ = 0.;
00465 for(unsigned ic=0;ic<nic;++ic)
00466 {
00467
00468 float factor = IC[ic]/ICMC[ic];
00469
00470 if(doMisCalib_) theCalibConstants_[ic] = refactor_mean_+(factor-1.)*refactor_;
00471 rms+=(factor-1.)*(factor-1.);
00472 mean+=(factor-1.);
00473
00474
00475 if(noise_==-1.)
00476 {
00477
00478 noisesigma_[ic]=noiseADC_*adcToGeV_*ICMC[ic]/calibfactor_;
00479 meanNoiseSigmaEt_ += noisesigma_[ic] * sinTheta_[(ic<EEDetId::kEEhalf)? ic : ic-EEDetId::kEEhalf];
00480
00481
00482 }
00483 ++ncells;
00484 }
00485
00486 mean/=(float)ncells;
00487 rms/=(float)ncells;
00488
00489 rms=sqrt(rms-mean*mean);
00490
00491 meanNoiseSigmaEt_ /=(float)ncells;
00492
00493 edm::LogInfo("CaloRecHitsProducer") << "Found " << ncells << " cells in the endcap calibration map. RMS is " << rms << std::endl;
00494
00495 }
00496
00497
00498
00499
00500
00501
00502 doCustomHighNoise_=highNoiseParameters_.size()==4;
00503 Genfun::Erf myErf;
00504 if( noise_>0. ) {
00505 EEHotFraction_ = 0.5-0.5*myErf(threshold_/noise_/sqrt(2.));
00506 myGaussianTailGenerator_ = new GaussianTail(random_, noise_, threshold_);
00507 edm::LogInfo("CaloRecHitsProducer") <<"Uniform noise simulation selected";
00508 }
00509 else if( noise_==-1 && doCustomHighNoise_)
00510 {
00511
00512
00513 EEHotFraction_ = 0.5-0.5*myErf(highNoiseParameters_[3]/highNoiseParameters_[2]/sqrt(2.));
00514 edm::LogInfo("CaloRecHitsProducer")<< " The gaussian model for high noise fluctuation cells after ZS is selected (best model), hot fraction " << EEHotFraction_ << std::endl;
00515 }
00516 }
00517
00518
00519 void EcalEndcapRecHitsMaker::geVtoGainAdc(float e,unsigned & gain, unsigned &adc) const
00520 {
00521 if(e<t1_)
00522 {
00523 gain = 1;
00524
00525 adc = minAdc_ + (unsigned)(e*geVToAdc1_);
00526
00527 }
00528 else if (e<t2_)
00529 {
00530 gain = 2;
00531 adc = minAdc_ + (unsigned)(e*geVToAdc2_);
00532 }
00533 else
00534 {
00535 gain = 3;
00536 adc = std::min(minAdc_+(unsigned)(e*geVToAdc3_),maxAdc_);
00537 }
00538 }
00539
00540 bool EcalEndcapRecHitsMaker::isHighInterest(const EEDetId& detid)
00541 {
00542
00543 int schi=SChashedIndex(detid);
00544
00545
00546
00547
00548
00549
00550 if(SCHighInterest_[schi]!=0) return (SCHighInterest_[schi]>0);
00551
00552
00553 const std::vector<int> & tts(TTofSC_[schi]);
00554 unsigned size=tts.size();
00555 bool result=false;
00556 for(unsigned itt=0;itt<size&&!result;++itt)
00557 {
00558
00559 if(TTTEnergy_[tts[itt]]>SRThreshold_) result=true;
00560 }
00561 SCHighInterest_[schi]=(result)? 1:-1;
00562 theFiredSC_.push_back(schi);
00563 return result;
00564 }