CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/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   if(fullInjection)
00333     ncells = EBDetId::kSizeForDenseIndexing;
00334   // for debugging
00335   //  std::vector<int> listofNewTowers;
00336 
00337   unsigned icell=0;
00338   while(icell < ncells)
00339     {
00340       unsigned cellindex= (unsigned)(floor(random_->flatShoot()*EBDetId::kSizeForDenseIndexing));
00341       if(theCalorimeterHits_[cellindex]==0.)
00342         {
00343           float energy=0.;
00344           if(noise_>0.) 
00345             energy=myGaussianTailGenerator_->shoot();
00346           if(noise_==-1.) 
00347             {
00348               // in this case the generated noise might be below the threshold but it 
00349               // does not matter, the threshold will be applied anyway
00350               //              energy/=sinTheta_[(cellindex<EEDetId::kEEhalf)?cellindex : cellindex-EEDetId::kEEhalf];    
00351               float noisemean  = (doCustomHighNoise_)? highNoiseParameters_[0]*(*ICMC_)[cellindex]*adcToGeV_: 0.;
00352               float noisesigma = (doCustomHighNoise_)? highNoiseParameters_[1]*(*ICMC_)[cellindex]*adcToGeV_ : noisesigma_[cellindex]; 
00353               energy=random_->gaussShoot(noisemean,noisesigma); 
00354               
00355               // in the case of high noise fluctuation, the ZS should not be applied later 
00356               if(doCustomHighNoise_) applyZSCells_[cellindex]=false;
00357             }
00358           float calib = (doMisCalib_) ? calibfactor_*theCalibConstants_[cellindex]:calibfactor_;
00359           energy *= calib;
00360           theCalorimeterHits_[cellindex]=energy;
00361           theFiredCells_.push_back(cellindex);
00362           EBDetId myDetId(EBDetId::unhashIndex(cellindex));
00363           // now get the TT       
00364           int TThashedindex=(eTTmap_->towerOf(myDetId)).hashedIndex();
00365           //      std::cout << " myDetIds " << myDetId << " "TTHI " << TThashedindex<< std::endl;
00366           if(TTTEnergy_[TThashedindex]==0.)
00367             {
00368               theFiredTTs_.push_back(TThashedindex);
00369               TTTEnergy_[TThashedindex]+=energy*sinTheta_[myDetId.ietaAbs()];         
00370               //              listofNewTowers.push_back(TThashedindex);
00371             }
00372 //        else
00373 //          {
00374 //            std::vector<int>::const_iterator itcheck=std::find(listofNewTowers.begin(),listofNewTowers.end(),
00375 //                                                             TThashedindex);
00376 //            if(itcheck==listofNewTowers.end())
00377 //              {
00378 //                std::cout << " EcalBarrelRecHitsMaker : this tower has already been treated " << TTTEnergy_[TThashedindex] << std::endl;
00379 //                const std::vector<int> & xtals=crystalsinTT_[TThashedindex];
00380 //                for(unsigned ic=0;ic<xtals.size();++ic)
00381 //                  std::cout << EBDetId::unhashIndex(xtals[ic]) << " " << theCalorimeterHits_[xtals[ic]] << std::endl;
00382 //              }
00383 //          }
00384           ++icell;
00385         }
00386     }
00387   //  std::cout << " Injected random noise in " << ncells << " cells " << std::endl;
00388 }
00389 
00390 void EcalBarrelRecHitsMaker::init(const edm::EventSetup &es,bool doDigis,bool doMiscalib)
00391 {
00392   //  std::cout << " Initializing EcalBarrelRecHitsMaker " << std::endl;
00393   doDigis_=doDigis;
00394   doMisCalib_=doMiscalib;
00395 
00396   edm::ESHandle<EcalADCToGeVConstant> agc;
00397   es.get<EcalADCToGeVConstantRcd>().get(agc);
00398 
00399   adcToGeV_= agc->getEBValue();// 0.035 ;
00400   minAdc_ = 200;
00401   maxAdc_ = 4085;
00402 
00403   geVToAdc1_ = 1./adcToGeV_;
00404   geVToAdc2_ = geVToAdc1_/2.;
00405   geVToAdc3_ = geVToAdc1_/12.;
00406   
00407   t1_ = ((int)maxAdc_-(int)minAdc_)*adcToGeV_;
00408   t2_ = 2.* t1_ ; 
00409 
00410   // Saturation value. Not needed in the digitization
00411   sat_ = 12.*t1_*calibfactor_;
00412 
00413   barrelRawId_.resize(EBDetId::kSizeForDenseIndexing);
00414   if (doMisCalib_ || noise_==-1.) theCalibConstants_.resize(EBDetId::kSizeForDenseIndexing);
00415   edm::ESHandle<CaloGeometry> pG;
00416   es.get<CaloGeometryRecord>().get(pG);   
00417 
00418 //  edm::ESHandle<CaloTopology> theCaloTopology;
00419 //  es.get<CaloTopologyRecord>().get(theCaloTopology);     
00420 
00421   edm::ESHandle<EcalTrigTowerConstituentsMap> hetm;
00422   es.get<IdealGeometryRecord>().get(hetm);
00423   eTTmap_ = &(*hetm);
00424   
00425   const EcalBarrelGeometry * myEcalBarrelGeometry = dynamic_cast<const EcalBarrelGeometry*>(pG->getSubdetectorGeometry(DetId::Ecal,EcalBarrel));
00426   //  std::cout << " Got the geometry " << myEcalBarrelGeometry << std::endl;
00427   const std::vector<DetId>& vec(myEcalBarrelGeometry->getValidDetIds(DetId::Ecal,EcalBarrel));
00428   unsigned size=vec.size();    
00429   for(unsigned ic=0; ic<size; ++ic) 
00430     {
00431       EBDetId myDetId(vec[ic]);
00432       int crystalHashedIndex=myDetId.hashedIndex();
00433       barrelRawId_[crystalHashedIndex]=vec[ic].rawId();
00434       // save the Trigger tower DetIds
00435       EcalTrigTowerDetId towid= eTTmap_->towerOf(EBDetId(vec[ic]));
00436       int TThashedindex=towid.hashedIndex();      
00437       theTTDetIds_[TThashedindex]=towid;                  
00438       crystalsinTT_[TThashedindex].push_back(crystalHashedIndex);
00439       int ietaAbs=myDetId.ietaAbs();
00440       if(sinTheta_[ietaAbs]==0.)
00441         {
00442           sinTheta_[ietaAbs]=std::sin(myEcalBarrelGeometry->getGeometry(myDetId)->getPosition().theta());
00443           //      std::cout << " Ieta abs " << ietaAbs << " " << sinTheta_[ietaAbs] << std::endl;
00444         }
00445     }
00446 
00447 
00448   unsigned nTTs=theTTDetIds_.size();
00449 
00450 //  EBDetId myDetId(-58,203);
00452 //  EcalTrigTowerDetId towid= eTTmap_->towerOf(myDetId);
00455 //  const std::vector<int> & xtals(crystalsinTT_[towid.hashedIndex()]);
00456 //  unsigned Size=xtals.size();
00457 //  for(unsigned i=0;i<Size;++i)
00458 //    {
00459 //      std::cout << EBDetId(barrelRawId_[xtals[i]]) << std::endl;
00460 //    }
00461 
00462   // now loop on each TT and save its neighbors. 
00463   for(unsigned iTT=0;iTT<nTTs;++iTT)
00464     {
00465       int ietaPivot=theTTDetIds_[iTT].ieta();
00466       int iphiPivot=theTTDetIds_[iTT].iphi();
00467       int TThashedIndex=theTTDetIds_[iTT].hashedIndex();
00468       //      std::cout << " TT Pivot " << TThashedIndex << " " << ietaPivot << " " << iphiPivot << " iz " << theTTDetIds_[iTT].zside() << std::endl;
00469       int ietamin=std::max(ietaPivot-SREtaSize_,-17);
00470       if(ietamin==0) ietamin=-1;
00471       int ietamax=std::min(ietaPivot+SREtaSize_,17);
00472       if(ietamax==0) ietamax=1;
00473       int iphimin=iphiPivot-SRPhiSize_;
00474       int iphimax=iphiPivot+SRPhiSize_;
00475       for(int ieta=ietamin;ieta<=ietamax;)
00476         {
00477           int iz=(ieta>0)? 1 : -1; 
00478           for(int iphi=iphimin;iphi<=iphimax;)
00479             {
00480               int riphi=iphi;
00481               if(riphi<1) riphi+=72;
00482               else if(riphi>72) riphi-=72;
00483               EcalTrigTowerDetId neighborTTDetId(iz,EcalBarrel,abs(ieta),riphi);
00484               //      std::cout << " Voisin " << ieta << " " << riphi << " " <<neighborTTDetId.hashedIndex()<< " " << neighborTTDetId.ieta() << " " << neighborTTDetId.iphi() << std::endl;
00485               if(ieta!=ietaPivot||riphi!=iphiPivot)
00486                 {
00487                   neighboringTTs_[TThashedIndex].push_back(neighborTTDetId.hashedIndex());
00488                 }
00489               ++iphi;
00490 
00491             }
00492           ++ieta;
00493           if(ieta==0) ieta=1;
00494         }
00495     }
00496 
00497   //  std::cout << " Made the array " << std::endl;
00498 
00499   // Stores the miscalibration constants
00500   if(doMisCalib_ || noise_==-1.)
00501     {
00502       double rms=0.;
00503       double mean=0.;
00504       unsigned ncells=0;
00505 
00506       if(noise_==-1.)
00507         noisesigma_.resize(EBDetId::kSizeForDenseIndexing);
00508 
00509       // Intercalib MC constants IC_MC_i
00510       edm::ESHandle<EcalIntercalibConstantsMC> pJcal;
00511       es.get<EcalIntercalibConstantsMCRcd>().get(pJcal); 
00512       const EcalIntercalibConstantsMC* jcal = pJcal.product(); 
00513       const std::vector<float>& ICMC = jcal->barrelItems();
00514 
00515        // should be saved, used by the zero suppression
00516       ICMC_ = &ICMC;
00517 
00518       // Intercalib constants IC_i 
00519       // IC = IC_MC * (1+delta)
00520       // where delta is the miscalib
00521       edm::ESHandle<EcalIntercalibConstants> pIcal;
00522       es.get<EcalIntercalibConstantsRcd>().get(pIcal);
00523       const EcalIntercalibConstants* ical = pIcal.product();
00524       const std::vector<float> & IC = ical->barrelItems();
00525       
00526       float meanIC=0.;
00527       unsigned nic = IC.size();
00528       for ( unsigned ic=0; ic <nic ; ++ic ) {
00529         // the miscalibration factor is 
00530         float factor = IC[ic]/ICMC[ic];
00531         meanIC+=(IC[ic]-1.);
00532         // Apply Refactor & refactor_mean
00533         theCalibConstants_[ic] = refactor_mean_+(factor-1.)*refactor_;
00534         
00535         rms+=(factor-1.)*(factor-1.);
00536         mean+=(factor-1.);
00537         ++ncells;       
00538         if(noise_==-1.)
00539           { 
00540             // the calibfactor will be applied later on 
00541             noisesigma_[ic]=noiseADC_*adcToGeV_*ICMC[ic]/calibfactor_;
00542           }
00543 
00544       }
00545 
00546       mean/=(float)ncells;
00547       rms/=(float)ncells;
00548 
00549       rms=sqrt(rms-mean*mean);
00550       meanIC = 1.+ meanIC/ncells;
00551       // The following should be on LogInfo
00552       //      float NoiseSigma = 1.26 * meanIC * adcToGeV_ ;
00553       //      std::cout << " Found " << ncells << 
00554       edm::LogInfo("CaloRecHitsProducer") << "Found  " << ncells << " cells in the barrel calibration map. RMS is " << rms << std::endl;
00555       //      std::cout << "Found  " << ncells << " cells in the barrel calibration map. RMS is " << rms << std::endl;
00556     }  
00557 }
00558 
00559 void EcalBarrelRecHitsMaker::geVtoGainAdc(float e,unsigned & gain, unsigned &adc) const
00560 {
00561   if(e<t1_)
00562     {
00563       gain = 1; // x1 
00564       //      std::cout << " E " << e << std::endl;
00565       adc = minAdc_ + (unsigned)(e*geVToAdc1_);
00566       //      std::cout << " e*geVtoAdc1_ " << e*geVToAdc1_ << " " <<(unsigned)(e*geVToAdc1_) << std::endl;
00567     } 
00568   else if (e<t2_)
00569     {
00570       gain = 2; 
00571       adc = minAdc_ + (unsigned)(e*geVToAdc2_);
00572     }
00573   else 
00574     {
00575       gain = 3; 
00576       adc = std::min(minAdc_+(unsigned)(e*geVToAdc3_),maxAdc_);
00577     }
00578 }
00579 
00580 bool EcalBarrelRecHitsMaker::isHighInterest(int tthi)
00581 {
00582 
00583   if(TTHighInterest_[tthi]!=0) return (TTHighInterest_[tthi]>0);
00584 
00585   TTHighInterest_[tthi]=(TTTEnergy_[tthi] > SRThreshold_) ? 1:-1;
00586   // if high interest, can leave ; otherwise look at the neighbours)
00587   if( TTHighInterest_[tthi]==1) 
00588     {
00589       theTTofHighInterest_.push_back(tthi);
00590       return true;
00591     }
00592 
00593   // now look if a neighboring TT is of high interest
00594   const std::vector<int> & tts(neighboringTTs_[tthi]);
00595   // a tower is of high interest if it or one of its neighbour is above the SR threshold
00596   unsigned size=tts.size();
00597   bool result=false;
00598   for(unsigned itt=0;itt<size&&!result;++itt)
00599     {
00600       if(TTTEnergy_[tts[itt]] > SRThreshold_) result=true;
00601     }
00602   TTHighInterest_[tthi]=(result)? 1:-1;
00603   theTTofHighInterest_.push_back(tthi);
00604   return result;
00605 }