CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/FastSimulation/CaloRecHitsProducer/src/EcalBarrelRecHitsMaker.cc

Go to the documentation of this file.
00001 #include "FastSimulation/CaloRecHitsProducer/interface/EcalBarrelRecHitsMaker.h"
00002 #include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h"
00003 #include "DataFormats/EcalDetId/interface/EBDetId.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 "FWCore/Framework/interface/ESHandle.h"
00011 #include "FWCore/Framework/interface/EventSetup.h"
00012 #include "FWCore/Framework/interface/Event.h"
00013 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00014 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00015 #include "Geometry/EcalAlgo/interface/EcalBarrelGeometry.h"
00016 #include "CondFormats/EcalObjects/interface/EcalIntercalibConstants.h"
00017 #include "CondFormats/DataRecord/interface/EcalIntercalibConstantsRcd.h"
00018 #include "CondFormats/EcalObjects/interface/EcalADCToGeVConstant.h"
00019 #include "CondFormats/DataRecord/interface/EcalADCToGeVConstantRcd.h"
00020 #include "CondFormats/EcalObjects/interface/EcalIntercalibConstantsMC.h"
00021 #include "CondFormats/DataRecord/interface/EcalIntercalibConstantsMCRcd.h"
00022 #include "Geometry/CaloTopology/interface/EcalTrigTowerConstituentsMap.h"
00023 #include "Geometry/CaloEventSetup/interface/CaloTopologyRecord.h"
00024 #include "Geometry/CaloTopology/interface/CaloTopology.h"
00025 #include "DataFormats/CaloTowers/interface/CaloTowerDetId.h"
00026 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00027 
00028 #include "CLHEP/GenericFunctions/Erf.hh"
00029 //#include <algorithm>
00030 
00031 EcalBarrelRecHitsMaker::EcalBarrelRecHitsMaker(edm::ParameterSet const & p,
00032                                                const RandomEngine* myrandom)
00033   : random_(myrandom)
00034 {
00035   edm::ParameterSet RecHitsParameters=p.getParameter<edm::ParameterSet>("ECALBarrel");
00036   inputCol_=RecHitsParameters.getParameter<edm::InputTag>("MixedSimHits");
00037   noise_ = RecHitsParameters.getParameter<double>("Noise");
00038   threshold_ = RecHitsParameters.getParameter<double>("Threshold");
00039   refactor_ = RecHitsParameters.getParameter<double> ("Refactor");
00040   refactor_mean_ = RecHitsParameters.getParameter<double> ("Refactor_mean");
00041   noiseADC_ = RecHitsParameters.getParameter<double>("NoiseADC");
00042   highNoiseParameters_ = RecHitsParameters.getParameter<std::vector<double> > ("HighNoiseParameters");
00043   SRThreshold_ = RecHitsParameters.getParameter<double> ("SRThreshold");
00044   SREtaSize_ = RecHitsParameters.getUntrackedParameter<int> ("SREtaSize",1);
00045   SRPhiSize_ = RecHitsParameters.getUntrackedParameter<int> ("SRPhiSize",1);
00046   applyZSCells_.resize(EBDetId::kSizeForDenseIndexing,true);
00047   theCalorimeterHits_.resize(EBDetId::kSizeForDenseIndexing,0.);
00048   crystalsinTT_.resize(2448);
00049   TTTEnergy_.resize(2448,0.);
00050   TTHighInterest_.resize(2448,0);
00051   treatedTTs_.resize(2448,false);
00052   theTTDetIds_.resize(2448);
00053   neighboringTTs_.resize(2448);
00054   sinTheta_.resize(86,0.); 
00055   doCustomHighNoise_=false;
00056   // Initialize the Gaussian tail generator
00057   // Two options : noise is set by the user (to a positive value). In this case, this value is taken
00058   // or the user chose to use the noise from DB. In this case, the noise is flat in pT and not in energy
00059   // but the threshold is in energy and not in pT.
00060   doCustomHighNoise_=highNoiseParameters_.size()>=3;
00061   Genfun::Erf myErf; 
00062   if(  noise_>0. ) {
00063     EBHotFraction_ = 0.5-0.5*myErf(threshold_/noise_/sqrt(2.));
00064     myGaussianTailGenerator_ = new GaussianTail(random_, noise_, threshold_);
00065     edm::LogInfo("CaloRecHitsProducer") <<"Uniform noise simulation selected in the barrel";
00066   } else if (noise_==-1 && doCustomHighNoise_)
00067     {
00068       if(highNoiseParameters_.size()==4)
00069         EBHotFraction_ = 0.5-0.5*myErf(highNoiseParameters_[3]/highNoiseParameters_[2]/sqrt(2.));
00070       if(highNoiseParameters_.size()==3)
00071         EBHotFraction_ = highNoiseParameters_[2] ;
00072       edm::LogInfo("CaloRecHitsProducer")<< " The gaussian model for high noise fluctuation cells after ZS is selected (best model), hot fraction " << EBHotFraction_  << std::endl;
00073     }
00074   
00075   noisified_ = (noise_==0.);
00076   edm::ParameterSet CalibParameters = RecHitsParameters.getParameter<edm::ParameterSet>("ContFact"); 
00077   double c1=CalibParameters.getParameter<double>("EBs25notContainment"); 
00078   calibfactor_=1./c1;
00079 
00080 
00081 }
00082 
00083 EcalBarrelRecHitsMaker::~EcalBarrelRecHitsMaker()
00084 {;
00085 }
00086 
00087 
00088 void EcalBarrelRecHitsMaker::clean()
00089 {
00090   //  std::cout << " clean " << std::endl;
00091   unsigned size=theFiredCells_.size();
00092   for(unsigned ic=0;ic<size;++ic)
00093     {
00094       theCalorimeterHits_[theFiredCells_[ic]] = 0.;
00095       applyZSCells_[theFiredCells_[ic]] = true;
00096     }
00097   theFiredCells_.clear();
00098   // If the noise is set to 0. No need to simulate it. 
00099   noisified_ = (noise_==0.);
00100   //  std::cout << " Finished to clean "  << std::endl;
00101   
00102   size=theFiredTTs_.size();
00103   //  std::cout << " Number of barrel TT " << size << std::endl;
00104   for(unsigned itt=0;itt<size;++itt)
00105     {
00106       //      std::cout << " TT " << theFiredTTs_[itt] << " " << TTTEnergy_[theFiredTTs_[itt]] << std::endl;
00107       TTTEnergy_[theFiredTTs_[itt]]=0.;
00108       treatedTTs_[theFiredTTs_[itt]]=false;
00109     }  
00110   theFiredTTs_.clear();
00111   
00112   size=theTTofHighInterest_.size();
00113   for(unsigned itt=0;itt<size;++itt)
00114     TTHighInterest_[theTTofHighInterest_[itt]]=0;
00115   theTTofHighInterest_.clear();
00116 
00117 //  std::cout << " Check cleaning " << std::endl;
00118 //  for(unsigned ic=0;ic<TTTEnergy_.size();++ic)
00119 //    if(TTTEnergy_[ic]!=0.) std::cout << " TT " << ic << " not cleaned " << std::endl;
00120 //  for(unsigned ic=0;ic<TTHighInterest_.size();++ic)
00121 //    if(TTHighInterest_[ic]!=0) std::cout << " TTHighInterest " << ic << TTHighInterest_[ic] << " not cleaned " << std::endl;
00122 //  for(unsigned ic=0;ic<treatedTTs_.size();++ic)
00123 //    if(treatedTTs_[ic]) std::cout << " treatedTT " << ic << treatedTTs_[ic] << " not cleaned " << std::endl;
00124   
00125 }
00126 
00127 void EcalBarrelRecHitsMaker::loadEcalBarrelRecHits(edm::Event &iEvent,EBRecHitCollection & ecalHits,EBDigiCollection & ecalDigis)
00128 {
00129 
00130   clean();
00131   loadPCaloHits(iEvent);
00132   
00133   unsigned nhit=theFiredCells_.size();
00134   //  std::cout << " loadEcalBarrelRecHits " << nhit << std::endl;
00135   unsigned gain, adc;
00136   ecalDigis.reserve(nhit);
00137   ecalHits.reserve(nhit);
00138   for(unsigned ihit=0;ihit<nhit;++ihit)
00139     {      
00140       unsigned icell = theFiredCells_[ihit];
00141 
00142       EBDetId myDetId(barrelRawId_[icell]);
00143       EcalTrigTowerDetId towid= eTTmap_->towerOf(myDetId);
00144       int TThashedindex=towid.hashedIndex();      
00145 
00146       if(doDigis_)
00147         {
00148           ecalDigis.push_back( myDetId );
00149           EBDataFrame myDataFrame( ecalDigis.back() );
00150           // myDataFrame.setSize(1);  // now useless - by construction fixed at 1 frame - FIXME
00151           //  The real work is in the following line
00152           geVtoGainAdc(theCalorimeterHits_[icell],gain,adc);
00153           myDataFrame.setSample(0,EcalMGPASample(adc,gain));
00154           
00155           //      std::cout << "myDataFrame" << myDataFrame.sample(0).raw() << std::endl;
00156           //ecalDigis.push_back(myDataFrame);
00157         }
00158       
00159       // If the energy+noise is below the threshold, a hit is nevertheless created, otherwise, there is a risk that a "noisy" hit 
00160       // is afterwards put in this cell which would not be correct. 
00161       float energy=theCalorimeterHits_[icell];
00162       //      std::cout << myDetId << " Energy " << theCalorimeterHits_[icell] << " " << TTTEnergy_[TThashedindex] << " " << isHighInterest(TThashedindex) << std::endl;
00163       if ( SRThreshold_ && energy < threshold_  && !isHighInterest(TThashedindex) && applyZSCells_[icell])
00164         {
00165           //      std::cout << " Killed " << std::endl;
00166           theCalorimeterHits_[icell]=0.;
00167           energy=0.;
00168         } 
00169       //      else
00170         //      std::cout << " SR " <<  TTTEnergy_[TThashedindex] << " Cell energy " << energy << " 1" << std::endl;
00171 //      if( TTTEnergy_[TThashedindex] < SRThreshold_ && energy > threshold_)
00172 //      std::cout << " SR " << TTTEnergy_[TThashedindex] << " Cell energy " << energy << std::endl;
00173       if (energy > sat_)
00174         {
00175           theCalorimeterHits_[icell]=sat_;
00176           energy=sat_;
00177         }
00178 //      std::cout << " Threshold ok " << std::endl;
00179 //      std::cout << " Raw Id " << barrelRawId_[icell] << std::endl;
00180 //      std::cout << " Adding " << icell << " " << barrelRawId_[icell] << " " << energy << std::endl;
00181       if(energy!=0.)
00182         ecalHits.push_back(EcalRecHit(myDetId,energy,0.));
00183       //      std::cout << " Hit stored " << std::endl;
00184     }
00185   //  std::cout << " Done " << std::endl;
00186 
00187 }
00188 
00189 void EcalBarrelRecHitsMaker::loadPCaloHits(const edm::Event & iEvent)
00190 {
00191 
00192   edm::Handle<CrossingFrame<PCaloHit> > cf;
00193   iEvent.getByLabel(inputCol_,cf);
00194   std::auto_ptr<MixCollection<PCaloHit> > colcalo(new MixCollection<PCaloHit>(cf.product(),std::pair<int,int>(0,0) ));
00195 
00196 
00197   theFiredCells_.reserve(colcalo->size());
00198 
00199   MixCollection<PCaloHit>::iterator cficalo;
00200   MixCollection<PCaloHit>::iterator cficaloend=colcalo->end();
00201 
00202   for (cficalo=colcalo->begin(); cficalo!=cficaloend;cficalo++) 
00203     {
00204       unsigned hashedindex = EBDetId(cficalo->id()).hashedIndex();      
00205       // the famous 1/0.97 calibration factor is applied here ! 
00206       // the miscalibration is applied here:
00207       float calib = (doMisCalib_) ? calibfactor_*theCalibConstants_[hashedindex]:calibfactor_;
00208       // Check if the hit already exists
00209       if(theCalorimeterHits_[hashedindex]==0.)
00210         {
00211           theFiredCells_.push_back(hashedindex);
00212           float noise=(noise_==-1.) ? noisesigma_[hashedindex] : noise_ ;
00213           if (!noisified_ )  theCalorimeterHits_[hashedindex] += random_->gaussShoot(0.,noise*calib); 
00214         }
00215 
00216 
00217       // cficalo->energy can be 0 (a 7x7 grid is always built) if there is no noise simulated, in this case the cells should
00218       // not be added several times. 
00219       float energy=(cficalo->energy()==0.) ? 0.000001 : cficalo->energy() ;
00220       energy*=calib;
00221       theCalorimeterHits_[hashedindex]+=energy;         
00222 
00223       // Now deal with the TTs. 
00224       EBDetId myDetId(EBDetId(cficalo->id()));
00225       EcalTrigTowerDetId towid= eTTmap_->towerOf(myDetId);
00226 //      std::cout << " Added " << energy << " in " << EBDetId(cficalo->id()) << std::endl;
00227       int TThashedindex=towid.hashedIndex();
00228       if(TTTEnergy_[TThashedindex]==0.)
00229         {
00230           theFiredTTs_.push_back(TThashedindex);           
00231 //        std::cout << " Creating " ;
00232         }
00233       //      std::cout << " Updating " << TThashedindex << " " << energy << " " << sinTheta_[myDetId.ietaAbs()] <<std::endl;
00234        TTTEnergy_[TThashedindex]+=energy*sinTheta_[myDetId.ietaAbs()];
00235        //       std::cout << " TT " << TThashedindex  << " updated, now contains " << TTTEnergy_[TThashedindex] << std::endl;
00236     }
00237   noisifyTriggerTowers();  
00238   noisified_ = true;
00239 }
00240 
00241 void EcalBarrelRecHitsMaker::noisifyTriggerTowers()
00242 {
00243   if(noise_==0.) return;
00244 //  std::cout << " List of TT before" << std::endl;
00245 //  for(unsigned itt=0;itt<theFiredTTs_.size();++itt)
00246 //    std::cout << " TT " << theFiredTTs_[itt] << " " << TTTEnergy_[theFiredTTs_[itt]] << std::endl;
00247 
00248   //  std::cout << " Starting to noisify the trigger towers " << std::endl;
00249   unsigned nTT=theFiredTTs_.size();
00250   for(unsigned itt=0;itt<nTT;++itt)
00251     {      
00252       //      std::cout << "Treating " << theFiredTTs_[itt] << " " << theTTDetIds_[theFiredTTs_[itt]].ieta() << " " <<  theTTDetIds_[theFiredTTs_[itt]].iphi() << " " << TTTEnergy_[theFiredTTs_[itt]] << std::endl;
00253       // shoot noise in the trigger tower 
00254       noisifyTriggerTower(theFiredTTs_[itt]);
00255       // get the neighboring TTs
00256       const std::vector<int>& neighbors=neighboringTTs_[theFiredTTs_[itt]];
00257       unsigned nneighbors=neighbors.size();
00258       // inject noise in those towers only if they have not been looked at yet
00259       //      std::cout << " Now looking at the neighbours " << std::endl;
00260       for(unsigned in=0;in<nneighbors;++in)
00261         {
00262           //      std::cout << " TT " << neighbors[in] << " " << theTTDetIds_[neighbors[in]] << " has been treated " << treatedTTs_[neighbors[in]] << std::endl;
00263           if(!treatedTTs_[neighbors[in]])
00264             {
00265               noisifyTriggerTower(neighbors[in]);
00266               if(TTTEnergy_[neighbors[in]]==0.)
00267                 theFiredTTs_.push_back(neighbors[in]);
00268               //              std::cout << " Added " << neighbors[in] << " in theFiredTTs_ " << std::endl;;
00269             }
00270         }
00271     }
00272 //  std::cout << " List of TT after" << std::endl;
00273 //  for(unsigned itt=0;itt<theFiredTTs_.size();++itt)
00274 //    {
00275 //      std::cout << " TT " << theFiredTTs_[itt] << " " << TTTEnergy_[theFiredTTs_[itt]] << std::endl;
00276 //      const std::vector<int> & xtals=crystalsinTT_[theFiredTTs_[itt]];
00277 //      for(unsigned ic=0;ic<xtals.size();++ic)
00278 //      std::cout << EBDetId::unhashIndex(xtals[ic]) << " " << theCalorimeterHits_[xtals[ic]] << std::endl;
00279 //    }
00280 
00281   randomNoisifier();
00282 }
00283 
00284 bool EcalBarrelRecHitsMaker::noisifyTriggerTower(unsigned tthi)
00285 {
00286   // check if the TT has already been treated or not
00287   if(treatedTTs_[tthi]) return false;
00288   // get the crystals in the TT (this info might need to be cached)
00289   //  const std::vector<DetId> & xtals=eTTmap_->constituentsOf(theTTDetIds_[tthi]);
00290   const std::vector<int> & xtals(crystalsinTT_[tthi]);
00291   unsigned nxtals=xtals.size();
00292   unsigned counter =0 ; 
00293   float energy=0.;
00294   for(unsigned ic=0;ic<nxtals;++ic)
00295     {
00296       unsigned hashedindex=xtals[ic];
00297       // check if the crystal has been already hit
00298 //      std::cout << " Checking " << EBDetId(barrelRawId_[xtals[ic]]) << " " << theCalorimeterHits_[hashedindex] << std::endl;
00299       if(theCalorimeterHits_[hashedindex]==0)
00300         {
00301           float calib = (doMisCalib_) ? calibfactor_*theCalibConstants_[hashedindex]:calibfactor_;
00302           float noise = (noise_==-1.) ? noisesigma_[hashedindex]:noise_;
00303           float energy = calib*random_->gaussShoot(0.,noise);
00304           theCalorimeterHits_[hashedindex]=energy;
00305           //      std::cout << " Updating with noise " << tthi << " " << energy << " " << sinTheta_[EBDetId(barrelRawId_[hashedindex]).ietaAbs()] << std::endl;
00306           if(TTTEnergy_[tthi]==0.)
00307             theFiredTTs_.push_back(tthi);
00308           TTTEnergy_[tthi]+=energy*sinTheta_[EBDetId(barrelRawId_[hashedindex]).ietaAbs()];
00309           
00310           theFiredCells_.push_back(hashedindex);
00311           ++counter;
00312         }
00313       else
00314         energy+=theCalorimeterHits_[hashedindex];
00315     }
00316 //  std::cout << " Energy " << energy  << " Added noise in " << counter << " cells" << std::endl;
00317   treatedTTs_[tthi]=true;
00318   return true;
00319 }
00320 
00321 
00322 // injects high noise fluctuations cells. It is assumed that these cells cannot 
00323 // make of the tower a high interest one
00324 void EcalBarrelRecHitsMaker::randomNoisifier()
00325 {
00326   // first number of cells where some noise will be injected
00327   double mean = (double)(EBDetId::kSizeForDenseIndexing-theFiredCells_.size())*EBHotFraction_;
00328   unsigned ncells= random_->poissonShoot(mean);
00329 
00330  // if hot fraction is high (for example, no ZS, inject everywhere)
00331   bool fullInjection=(noise_==-1. && !doCustomHighNoise_);
00332 
00333   if(fullInjection)
00334     ncells = EBDetId::kSizeForDenseIndexing;
00335   // for debugging
00336   //  std::vector<int> listofNewTowers;
00337 
00338   unsigned icell=0;
00339   while(icell < ncells)
00340     {
00341       unsigned cellindex= (!fullInjection) ? 
00342         (unsigned)(floor(random_->flatShoot()*EBDetId::kSizeForDenseIndexing)): icell ;
00343 
00344       if(theCalorimeterHits_[cellindex]==0.)
00345         {
00346           float energy=0.;
00347           if(noise_>0.) 
00348             energy=myGaussianTailGenerator_->shoot();
00349           if(noise_==-1.) 
00350             {
00351               // in this case the generated noise might be below the threshold but it 
00352               // does not matter, the threshold will be applied anyway
00353               //              energy/=sinTheta_[(cellindex<EEDetId::kEEhalf)?cellindex : cellindex-EEDetId::kEEhalf];    
00354               float noisemean  = (doCustomHighNoise_)? highNoiseParameters_[0]*(*ICMC_)[cellindex]*adcToGeV_: 0.;
00355               float noisesigma = (doCustomHighNoise_)? highNoiseParameters_[1]*(*ICMC_)[cellindex]*adcToGeV_ : noisesigma_[cellindex]; 
00356               energy=random_->gaussShoot(noisemean,noisesigma); 
00357               
00358               // in the case of high noise fluctuation, the ZS should not be applied later 
00359               if(doCustomHighNoise_) applyZSCells_[cellindex]=false;
00360             }
00361           float calib = (doMisCalib_) ? calibfactor_*theCalibConstants_[cellindex]:calibfactor_;
00362           energy *= calib;
00363           theCalorimeterHits_[cellindex]=energy;
00364           theFiredCells_.push_back(cellindex);
00365           EBDetId myDetId(EBDetId::unhashIndex(cellindex));
00366           // now get the TT       
00367           int TThashedindex=(eTTmap_->towerOf(myDetId)).hashedIndex();
00368           //      std::cout << " myDetIds " << myDetId << " "TTHI " << TThashedindex<< std::endl;
00369           if(TTTEnergy_[TThashedindex]==0.)
00370             {
00371               theFiredTTs_.push_back(TThashedindex);
00372               TTTEnergy_[TThashedindex]+=energy*sinTheta_[myDetId.ietaAbs()];         
00373               //              listofNewTowers.push_back(TThashedindex);
00374             }
00375 //        else
00376 //          {
00377 //            std::vector<int>::const_iterator itcheck=std::find(listofNewTowers.begin(),listofNewTowers.end(),
00378 //                                                             TThashedindex);
00379 //            if(itcheck==listofNewTowers.end())
00380 //              {
00381 //                std::cout << " EcalBarrelRecHitsMaker : this tower has already been treated " << TTTEnergy_[TThashedindex] << std::endl;
00382 //                const std::vector<int> & xtals=crystalsinTT_[TThashedindex];
00383 //                for(unsigned ic=0;ic<xtals.size();++ic)
00384 //                  std::cout << EBDetId::unhashIndex(xtals[ic]) << " " << theCalorimeterHits_[xtals[ic]] << std::endl;
00385 //              }
00386 //          }
00387           if(noise_>0.)
00388             ++icell;
00389         }
00390       if(noise_==-1.)
00391         ++icell;
00392     }
00393   //  std::cout << " Injected random noise in " << ncells << " cells " << std::endl;
00394 }
00395 
00396 void EcalBarrelRecHitsMaker::init(const edm::EventSetup &es,bool doDigis,bool doMiscalib)
00397 {
00398   //  std::cout << " Initializing EcalBarrelRecHitsMaker " << std::endl;
00399   doDigis_=doDigis;
00400   doMisCalib_=doMiscalib;
00401 
00402   edm::ESHandle<EcalADCToGeVConstant> agc;
00403   es.get<EcalADCToGeVConstantRcd>().get(agc);
00404 
00405   adcToGeV_= agc->getEBValue();// 0.035 ;
00406   minAdc_ = 200;
00407   maxAdc_ = 4085;
00408 
00409   geVToAdc1_ = 1./adcToGeV_;
00410   geVToAdc2_ = geVToAdc1_/2.;
00411   geVToAdc3_ = geVToAdc1_/12.;
00412   
00413   t1_ = ((int)maxAdc_-(int)minAdc_)*adcToGeV_;
00414   t2_ = 2.* t1_ ; 
00415 
00416   // Saturation value. Not needed in the digitization
00417   sat_ = 12.*t1_*calibfactor_;
00418 
00419   barrelRawId_.resize(EBDetId::kSizeForDenseIndexing);
00420   if (doMisCalib_ || noise_==-1.) theCalibConstants_.resize(EBDetId::kSizeForDenseIndexing);
00421   edm::ESHandle<CaloGeometry> pG;
00422   es.get<CaloGeometryRecord>().get(pG);   
00423 
00424 //  edm::ESHandle<CaloTopology> theCaloTopology;
00425 //  es.get<CaloTopologyRecord>().get(theCaloTopology);     
00426 
00427   edm::ESHandle<EcalTrigTowerConstituentsMap> hetm;
00428   es.get<IdealGeometryRecord>().get(hetm);
00429   eTTmap_ = &(*hetm);
00430   
00431   const EcalBarrelGeometry * myEcalBarrelGeometry = dynamic_cast<const EcalBarrelGeometry*>(pG->getSubdetectorGeometry(DetId::Ecal,EcalBarrel));
00432   //  std::cout << " Got the geometry " << myEcalBarrelGeometry << std::endl;
00433   const std::vector<DetId>& vec(myEcalBarrelGeometry->getValidDetIds(DetId::Ecal,EcalBarrel));
00434   unsigned size=vec.size();    
00435   for(unsigned ic=0; ic<size; ++ic) 
00436     {
00437       EBDetId myDetId(vec[ic]);
00438       int crystalHashedIndex=myDetId.hashedIndex();
00439       barrelRawId_[crystalHashedIndex]=vec[ic].rawId();
00440       // save the Trigger tower DetIds
00441       EcalTrigTowerDetId towid= eTTmap_->towerOf(EBDetId(vec[ic]));
00442       int TThashedindex=towid.hashedIndex();      
00443       theTTDetIds_[TThashedindex]=towid;                  
00444       crystalsinTT_[TThashedindex].push_back(crystalHashedIndex);
00445       int ietaAbs=myDetId.ietaAbs();
00446       if(sinTheta_[ietaAbs]==0.)
00447         {
00448           sinTheta_[ietaAbs]=std::sin(myEcalBarrelGeometry->getGeometry(myDetId)->getPosition().theta());
00449           //      std::cout << " Ieta abs " << ietaAbs << " " << sinTheta_[ietaAbs] << std::endl;
00450         }
00451     }
00452 
00453 
00454   unsigned nTTs=theTTDetIds_.size();
00455 
00456 //  EBDetId myDetId(-58,203);
00458 //  EcalTrigTowerDetId towid= eTTmap_->towerOf(myDetId);
00461 //  const std::vector<int> & xtals(crystalsinTT_[towid.hashedIndex()]);
00462 //  unsigned Size=xtals.size();
00463 //  for(unsigned i=0;i<Size;++i)
00464 //    {
00465 //      std::cout << EBDetId(barrelRawId_[xtals[i]]) << std::endl;
00466 //    }
00467 
00468   // now loop on each TT and save its neighbors. 
00469   for(unsigned iTT=0;iTT<nTTs;++iTT)
00470     {
00471       int ietaPivot=theTTDetIds_[iTT].ieta();
00472       int iphiPivot=theTTDetIds_[iTT].iphi();
00473       int TThashedIndex=theTTDetIds_[iTT].hashedIndex();
00474       //      std::cout << " TT Pivot " << TThashedIndex << " " << ietaPivot << " " << iphiPivot << " iz " << theTTDetIds_[iTT].zside() << std::endl;
00475       int ietamin=std::max(ietaPivot-SREtaSize_,-17);
00476       if(ietamin==0) ietamin=-1;
00477       int ietamax=std::min(ietaPivot+SREtaSize_,17);
00478       if(ietamax==0) ietamax=1;
00479       int iphimin=iphiPivot-SRPhiSize_;
00480       int iphimax=iphiPivot+SRPhiSize_;
00481       for(int ieta=ietamin;ieta<=ietamax;)
00482         {
00483           int iz=(ieta>0)? 1 : -1; 
00484           for(int iphi=iphimin;iphi<=iphimax;)
00485             {
00486               int riphi=iphi;
00487               if(riphi<1) riphi+=72;
00488               else if(riphi>72) riphi-=72;
00489               EcalTrigTowerDetId neighborTTDetId(iz,EcalBarrel,abs(ieta),riphi);
00490               //      std::cout << " Voisin " << ieta << " " << riphi << " " <<neighborTTDetId.hashedIndex()<< " " << neighborTTDetId.ieta() << " " << neighborTTDetId.iphi() << std::endl;
00491               if(ieta!=ietaPivot||riphi!=iphiPivot)
00492                 {
00493                   neighboringTTs_[TThashedIndex].push_back(neighborTTDetId.hashedIndex());
00494                 }
00495               ++iphi;
00496 
00497             }
00498           ++ieta;
00499           if(ieta==0) ieta=1;
00500         }
00501     }
00502 
00503   //  std::cout << " Made the array " << std::endl;
00504 
00505   // Stores the miscalibration constants
00506   if(doMisCalib_ || noise_==-1.)
00507     {
00508       double rms=0.;
00509       double mean=0.;
00510       unsigned ncells=0;
00511 
00512       if(noise_==-1.)
00513         noisesigma_.resize(EBDetId::kSizeForDenseIndexing);
00514 
00515       // Intercalib MC constants IC_MC_i
00516       edm::ESHandle<EcalIntercalibConstantsMC> pJcal;
00517       es.get<EcalIntercalibConstantsMCRcd>().get(pJcal); 
00518       const EcalIntercalibConstantsMC* jcal = pJcal.product(); 
00519       const std::vector<float>& ICMC = jcal->barrelItems();
00520 
00521        // should be saved, used by the zero suppression
00522       ICMC_ = &ICMC;
00523 
00524       // Intercalib constants IC_i 
00525       // IC = IC_MC * (1+delta)
00526       // where delta is the miscalib
00527       edm::ESHandle<EcalIntercalibConstants> pIcal;
00528       es.get<EcalIntercalibConstantsRcd>().get(pIcal);
00529       const EcalIntercalibConstants* ical = pIcal.product();
00530       const std::vector<float> & IC = ical->barrelItems();
00531       
00532       float meanIC=0.;
00533       unsigned nic = IC.size();
00534       for ( unsigned ic=0; ic <nic ; ++ic ) {
00535         // the miscalibration factor is 
00536         float factor = IC[ic]/ICMC[ic];
00537         meanIC+=(IC[ic]-1.);
00538         // Apply Refactor & refactor_mean
00539         theCalibConstants_[ic] = refactor_mean_+(factor-1.)*refactor_;
00540         
00541         rms+=(factor-1.)*(factor-1.);
00542         mean+=(factor-1.);
00543         ++ncells;       
00544         if(noise_==-1.)
00545           { 
00546             // the calibfactor will be applied later on 
00547             noisesigma_[ic]=noiseADC_*adcToGeV_*ICMC[ic]/calibfactor_;
00548           }
00549 
00550       }
00551 
00552       mean/=(float)ncells;
00553       rms/=(float)ncells;
00554 
00555       rms=sqrt(rms-mean*mean);
00556       meanIC = 1.+ meanIC/ncells;
00557       // The following should be on LogInfo
00558       //      float NoiseSigma = 1.26 * meanIC * adcToGeV_ ;
00559       //      std::cout << " Found " << ncells << 
00560       edm::LogInfo("CaloRecHitsProducer") << "Found  " << ncells << " cells in the barrel calibration map. RMS is " << rms << std::endl;
00561       //      std::cout << "Found  " << ncells << " cells in the barrel calibration map. RMS is " << rms << std::endl;
00562     }  
00563 }
00564 
00565 void EcalBarrelRecHitsMaker::geVtoGainAdc(float e,unsigned & gain, unsigned &adc) const
00566 {
00567   if(e<t1_)
00568     {
00569       gain = 1; // x1 
00570       //      std::cout << " E " << e << std::endl;
00571       adc = minAdc_ + (unsigned)(e*geVToAdc1_);
00572       //      std::cout << " e*geVtoAdc1_ " << e*geVToAdc1_ << " " <<(unsigned)(e*geVToAdc1_) << std::endl;
00573     } 
00574   else if (e<t2_)
00575     {
00576       gain = 2; 
00577       adc = minAdc_ + (unsigned)(e*geVToAdc2_);
00578     }
00579   else 
00580     {
00581       gain = 3; 
00582       adc = std::min(minAdc_+(unsigned)(e*geVToAdc3_),maxAdc_);
00583     }
00584 }
00585 
00586 bool EcalBarrelRecHitsMaker::isHighInterest(int tthi)
00587 {
00588 
00589   if(TTHighInterest_[tthi]!=0) return (TTHighInterest_[tthi]>0);
00590 
00591   TTHighInterest_[tthi]=(TTTEnergy_[tthi] > SRThreshold_) ? 1:-1;
00592   // if high interest, can leave ; otherwise look at the neighbours)
00593   if( TTHighInterest_[tthi]==1) 
00594     {
00595       theTTofHighInterest_.push_back(tthi);
00596       return true;
00597     }
00598 
00599   // now look if a neighboring TT is of high interest
00600   const std::vector<int> & tts(neighboringTTs_[tthi]);
00601   // a tower is of high interest if it or one of its neighbour is above the SR threshold
00602   unsigned size=tts.size();
00603   bool result=false;
00604   for(unsigned itt=0;itt<size&&!result;++itt)
00605     {
00606       if(TTTEnergy_[tts[itt]] > SRThreshold_) result=true;
00607     }
00608   TTHighInterest_[tthi]=(result)? 1:-1;
00609   theTTofHighInterest_.push_back(tthi);
00610   return result;
00611 }