CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/FastSimulation/CaloRecHitsProducer/src/EcalEndcapRecHitsMaker.cc

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   // If the noise is set to 0. No need to simulate it. 
00080   noisified_ = (noise_==0.);
00081 
00082   size=theFiredTTs_.size();
00083 
00084   for(unsigned itt=0;itt<size;++itt)
00085     {
00086       //      std::cout << " TT " << theFiredTTs_[itt] << " " << TTTEnergy_[theFiredTTs_[itt]] << std::endl;
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 //  for(unsigned ic=0;ic<TTTEnergy_.size();++ic)
00102 //    if(TTTEnergy_[ic]!=0.) std::cout << " TT " << ic << " not cleaned " << std::endl;
00103 //  for(unsigned ic=0;ic<SCHighInterest_.size();++ic)
00104 //    if(SCHighInterest_[ic]!=0) std::cout << " SCHighInterest " << ic << SCHighInterest_[ic] << " not cleaned " << std::endl;
00105 //  for(unsigned ic=0;ic<treatedSC_.size();++ic)
00106 //    if(treatedSC_[ic]) std::cout << " treatedSC " << ic << treatedSC_[ic] << " not cleaned " << std::endl;
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            // myDataFrame.setSize(1); // now useless - by construction fixed at 1 frame - FIXME
00129            //  The real work is in the following line
00130            geVtoGainAdc(theCalorimeterHits_[icell],gain,adc);
00131            myDataFrame.setSample(0,EcalMGPASample(adc,gain));
00132            //ecalDigis.push_back(myDataFrame);
00133         }
00134 
00135       // If the energy+noise is below the threshold, a hit is nevertheless created, otherwise, there is a risk that a "noisy" hit 
00136       // is afterwards put in this cell which would not be correct. 
00137       float energy=theCalorimeterHits_[icell];
00138       
00139       // the threshold is in amplitude, so the intercalibration constant should be injected 
00140       if ( energy<threshold_*((*ICMC_)[icell]) && !isHighInterest(myDetId) && applyZSCells_[icell]) 
00141         {
00142           theCalorimeterHits_[icell]=0.;
00143           //      int TThashedindex=towerOf_[icell];
00144           //      std::cout << " SR " << TTTEnergy_[TThashedindex] << " Cell energy " << energy << " 0 "<< std::endl;
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   //  std::cout << " loadPCaloHits " << std::endl;
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       // Check if the hit already exists
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       // the famous 1/0.97 calibration factor is applied here ! 
00187       // the miscalibration is applied here:
00188 
00189       // cficalo->energy can be 0 (a 7x7 grid is always built), in this case, one should not kill the cell (for later noise injection), but it should
00190       // be added only once.  This is a dirty trick. 
00191       float energy=(cficalo->energy()==0.) ? 0.000001 : cficalo->energy() ;
00192       energy*=calib;
00193       theCalorimeterHits_[hashedindex]+=energy;   
00194 
00195       // Now deal with the TTs
00196       int TThashedindex=towerOf_[hashedindex];
00197 
00198       if(TTTEnergy_[TThashedindex]==0.)
00199         {
00200           theFiredTTs_.push_back(TThashedindex);
00201         }
00202       // the same dirty trick as before. sinTheta is stored only for one endcap
00203       TTTEnergy_[TThashedindex]+=energy*sinTheta_[(hashedindex<EEDetId::kEEhalf)? hashedindex : hashedindex-EEDetId::kEEhalf];
00204 
00205     }
00206   //  std::cout << " Noisifying the TT " << std::endl;
00207   noisifyTriggerTowers();
00208   randomNoisifier();
00209 }
00210 
00211 void EcalEndcapRecHitsMaker::noisifyTriggerTowers()
00212 {
00213   if(noise_==0.) return;
00214 
00215   // noise should be injected in all the Super-crystals contained in each trigger tower 
00216   unsigned nTT=theFiredTTs_.size();
00217   for(unsigned itt=0;itt<nTT;++itt)
00218     {      
00219       // shoot noise in the trigger tower 
00220       //      std::cout << " Treating " << theFiredTTs_[itt] << " " << theTTDetIds_[theFiredTTs_[itt]] << " " << TTTEnergy_[theFiredTTs_[itt]] << std::endl;       
00221         noisifySuperCrystals(theFiredTTs_[itt]);
00222     }
00223 }
00224 
00225 // inject noise in all the supercrystals of a given trigger tower
00226 void EcalEndcapRecHitsMaker::noisifySuperCrystals(int tthi)
00227 {
00228   unsigned size=SCofTT_[tthi].size();
00229   // get the list of Supercrytals
00230   for(unsigned isc=0;isc<size;++isc)
00231     {
00232       //      std::cout << " Looking at SC " << isc << " " << SCofTT_[tthi][isc] << std::endl;
00233       // should not do it twice
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 //      if (nxtals!=25)
00240 //      {
00241 //        std::cout << " This SC has " << nxtals << " crystals " << std::endl;
00242 //      }
00243       for(unsigned ix=0;ix<nxtals;++ix)
00244         {
00245           unsigned hashedindex=xtals[ix];
00246           // check if the crystal has already something or not 
00247           //      std::cout << " Looking at crystal " << EEDetId(endcapRawId_[hashedindex]) << std::endl;
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               // the corresponding trigger tower should be updated 
00256               int newtthi=towerOf_[hashedindex];
00257               //              std::cout << " Updatung TT " << newtthi << std::endl;
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       //      std::cout << "SC " << SCofTT_[tthi][isc] << " done ; injected " << count << std::endl;
00268     }
00269 }
00270 
00271 // injects high noise fluctuations cells. It is assumed that these cells cannot 
00272 // make of the tower a high interest one. 
00273 // Two different cases:
00274 // 1) noise flat in energy -> use a GaussianTail generator
00275 // 2) noise from database (~flat in pT) -> inject noise everywhere
00276 void EcalEndcapRecHitsMaker::randomNoisifier()
00277 {
00278   // first of cells where some noise will be injected
00279   double mean = (double)(EEDetId::kSizeForDenseIndexing-theFiredCells_.size())*EEHotFraction_;
00280   unsigned ncells= random_->poissonShoot(mean);
00281 
00282   // for debugging
00283   //  std::vector<int> listofNewTowers;
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           // if noise_>0 the following is really an energy, if -1. it is a transverse energy
00297           double energy=0.;
00298           if(noise_>0.) 
00299             energy=myGaussianTailGenerator_->shoot();
00300           if(noise_==-1.) 
00301             {
00302               // in this case the generated noise might be below the threshold but it 
00303               // does not matter, the threshold will be applied anyway
00304               //              energy/=sinTheta_[(cellindex<EEDetId::kEEhalf)?cellindex : cellindex-EEDetId::kEEhalf];    
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               // in the case of high noise fluctuation, the ZS should not be applied later 
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           // now get the TT       
00318           int TThashedindex=towerOf_[cellindex];
00319           //      std::cout << " myDetIds " << myDetId << " "TTHI " << TThashedindex<< std::endl;
00320           if(TTTEnergy_[TThashedindex]==0.)
00321             {
00322               theFiredTTs_.push_back(TThashedindex);
00323               TTTEnergy_[TThashedindex]+=energy*sinTheta_[(cellindex<EEDetId::kEEhalf)?cellindex : cellindex-EEDetId::kEEhalf];  
00324               //              listofNewTowers.push_back(TThashedindex);
00325             }
00326 //        else
00327 //          {
00328 //            std::vector<int>::const_iterator itcheck=std::find(listofNewTowers.begin(),listofNewTowers.end(),
00329 //                                                               TThashedindex);
00330 //            if(itcheck==listofNewTowers.end())
00331 //              {
00332 //                const std::vector<int> & scxtals=SCofTT_[TThashedindex];
00333 //                for(unsigned isc=0;isc<scxtals.size();++isc)
00334 //                  {
00335 //                    const std::vector<int> & xtals(CrystalsinSC_[SCofTT_[TThashedindex][isc]]);
00336 //                    for(unsigned ic=0;ic<xtals.size();++ic)
00337 //                      std::cout << isc << " " << EEDetId::unhashIndex(xtals[ic]) << " " << theCalorimeterHits_[xtals[ic]] << std::endl;
00338 //                  }
00339 //              }
00340 //          }
00341           if(noise_>0.)
00342             ++icell;
00343         }
00344       if(noise_==-1.)
00345         ++icell;
00346     }
00347   //  std::cout << " Injected random noise in " << ncells << " cells " << std::endl;
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() ; // ~0.06 
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       // trick to save a bit of memory. sin Theta is identical in EE+/-
00393       if (cellhashedindex< EEDetId::kEEhalf)
00394         {
00395           float sintheta=std::sin(myEcalEndcapGeometry->getGeometry(myDetId)->getPosition().theta());
00396           sinTheta_[cellhashedindex]=sintheta;
00397         }
00398       // a bit of trigger tower and SuperCrystals algebra
00399       // first get the trigger tower 
00400       EcalTrigTowerDetId towid1= eTTmap_->towerOf(vec[ic]);
00401       int tthashedindex=TThashedIndexforEE(towid1);
00402       towerOf_[cellhashedindex]=tthashedindex;
00403 
00404       // get the SC of the cell
00405       int schi=SChashedIndex(EEDetId(vec[ic]));
00406       if(schi<0) 
00407         {
00408           //      std::cout << " OOps " << schi << std::endl;
00409           EEDetId myID(vec[ic]);
00410           //      std::cout << " DetId " << myID << " " << myID.isc() << " " <<  myID.zside() <<  " " << myID.isc()+(myID.zside()+1)*158 << std::endl;
00411         }
00412       
00413       theTTDetIds_[tthashedindex]=towid1;
00414 
00415       // check if this SC is already in the list of the corresponding TT
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       // check if this crystal is already in the list of crystals per sc
00423       itcheck=find(CrystalsinSC_[schi].begin(),CrystalsinSC_[schi].end(),cellhashedindex);
00424       if(itcheck==CrystalsinSC_[schi].end())
00425         CrystalsinSC_[schi].push_back(cellhashedindex);
00426 
00427       // check if the TT is already in the list of sc
00428       //      std::cout << " SCHI " << schi << " " << TTofSC_.size() << std::endl;
00429       //      std::cout << TTofSC_[schi].size() << std::endl;
00430       itcheck=find(TTofSC_[schi].begin(),TTofSC_[schi].end(),tthashedindex);
00431       if(itcheck==TTofSC_[schi].end())
00432         TTofSC_[schi].push_back(tthashedindex);
00433     }
00434   //  std::cout << " Made the array " << std::endl;
00435   // Stores the miscalibration constants
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       // Intercalib constants IC_MC_i
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       // should be saved, used by the zero suppression
00452       ICMC_ = &ICMC;
00453 
00454       // Intercalib constants IC_i 
00455       // IC = IC_MC * (1+delta)
00456       // where delta is the miscalib
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           // the miscalibration factor is 
00468           float factor = IC[ic]/ICMC[ic];
00469           // Apply Refactor & refactor_mean
00470           if(doMisCalib_) theCalibConstants_[ic] = refactor_mean_+(factor-1.)*refactor_;          
00471           rms+=(factor-1.)*(factor-1.);
00472           mean+=(factor-1.);
00473 
00474           // the miscalibration on the noise will be applied later one; so it is really ICMC here
00475           if(noise_==-1.)
00476             { 
00477               // the calibfactor will be applied later on 
00478               noisesigma_[ic]=noiseADC_*adcToGeV_*ICMC[ic]/calibfactor_;
00479               meanNoiseSigmaEt_ += noisesigma_[ic] * sinTheta_[(ic<EEDetId::kEEhalf)? ic : ic-EEDetId::kEEhalf];
00480               //              EEDetId myDetId(EEDetId::unhashIndex(ic));
00481               //              std::cout << " DDD " <<  myDetId << " " << myDetId.ix() << " " << myDetId.iy() <<  " " << ic << " " << noiseADC_ << " " << agc->getEEValue() << " " << ICMC[ic] << " " << noisesigma_[ic] << std::endl;
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       //      std::cout << "Found  " << ncells << " cells in the endcap calibration map. RMS is " << rms << std::endl;
00495     }  
00496   
00497   // Initialize the Gaussian tail generator
00498   // Two options : noise is set by the user (to a positive value). In this case, this value is taken
00499   // or the user chose to use the noise from DB. In this case, the noise is flat in pT and not in energy
00500   // but the threshold is in energy and not in pT. 
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       // computes the hot fraction from the threshold applied on the online amplitude reconstruction
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; // x1 
00524       //      std::cout << " E " << e << std::endl;
00525       adc = minAdc_ + (unsigned)(e*geVToAdc1_);
00526       //      std::cout << " e*geVtoAdc1_ " << e*geVToAdc1_ << " " <<(unsigned)(e*geVToAdc1_) << std::endl;
00527     } 
00528   else if (e<t2_)
00529     {
00530       gain = 2; // x6
00531       adc = minAdc_ + (unsigned)(e*geVToAdc2_);
00532     }
00533   else 
00534     {
00535       gain = 3; // x12
00536       adc = std::min(minAdc_+(unsigned)(e*geVToAdc3_),maxAdc_);
00537     }
00538 }
00539 
00540 bool EcalEndcapRecHitsMaker::isHighInterest(const EEDetId& detid)
00541 {
00542   //  std::cout << " is HI " ;
00543   int schi=SChashedIndex(detid);
00544   //  std::cout <<  detid << "  " << schi << " ";
00545   // check if it has already been treated or not
00546   // 0 <=> not treated
00547   // 1 <=> high interest
00548   // -1 <=> low interest
00549   //  std::cout << SCHighInterest_[schi] << std::endl;
00550   if(SCHighInterest_[schi]!=0) return (SCHighInterest_[schi]>0);
00551   
00552   // now look if a TT contributing is of high interest
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       //      std::cout << " Checking TT " << tts[itt] << std::endl;
00559       if(TTTEnergy_[tts[itt]]>SRThreshold_) result=true;
00560     }
00561   SCHighInterest_[schi]=(result)? 1:-1;
00562   theFiredSC_.push_back(schi);
00563   return result;
00564 }