![]() |
![]() |
00001 #include "SimCalorimetry/HcalSimAlgos/interface/HcalHitCorrection.h" 00002 #include "SimCalorimetry/CaloSimAlgos/interface/CaloSimParameters.h" 00003 #include "SimCalorimetry/HcalSimAlgos/interface/HcalSimParameters.h" 00004 #include "CalibCalorimetry/HcalAlgos/interface/HcalTimeSlew.h" 00005 #include "DataFormats/DetId/interface/DetId.h" 00006 #include "DataFormats/HcalDetId/interface/HcalDetId.h" 00007 #include "DataFormats/HcalDetId/interface/HcalZDCDetId.h" 00008 #include "FWCore/Utilities/interface/Exception.h" 00009 #include "FWCore/MessageLogger/interface/MessageLogger.h" 00010 00011 HcalHitCorrection::HcalHitCorrection(const CaloVSimParameterMap * parameterMap) 00012 : theParameterMap(parameterMap),theRandGaussQ(0) 00013 { 00014 } 00015 00016 00017 void HcalHitCorrection::fillChargeSums(MixCollection<PCaloHit> & hits) 00018 { 00019 for(MixCollection<PCaloHit>::MixItr hitItr = hits.begin(); 00020 hitItr != hits.end(); ++hitItr) 00021 { 00022 LogDebug("HcalHitCorrection") << "HcalHitCorrection::Hit 0x" << std::hex 00023 << hitItr->id() << std::dec; 00024 int tbin = timeBin(*hitItr); 00025 LogDebug("HcalHitCorrection") << "HcalHitCorrection::Hit tbin" << tbin; 00026 if(tbin >= 0 && tbin < 10) 00027 { 00028 theChargeSumsForTimeBin[tbin][DetId(hitItr->id())] += charge(*hitItr); 00029 } 00030 } 00031 } 00032 00033 00034 void HcalHitCorrection::clear() 00035 { 00036 for(int i = 0; i < 10; ++i) 00037 { 00038 theChargeSumsForTimeBin[i].clear(); 00039 } 00040 } 00041 00042 double HcalHitCorrection::charge(const PCaloHit & hit) const 00043 { 00044 HcalDetId detId(hit.id()); 00045 const CaloSimParameters & parameters = theParameterMap->simParameters(detId); 00046 double simHitToCharge = parameters.simHitToPhotoelectrons(detId) 00047 * parameters.photoelectronsToAnalog(detId); 00048 return hit.energy() * simHitToCharge; 00049 } 00050 00051 00052 double HcalHitCorrection::delay(const PCaloHit & hit) const 00053 { 00054 // HO goes slow, HF shouldn't be used at all 00055 //ZDC not used for the moment 00056 00057 DetId detId(hit.id()); 00058 if(detId.det()==DetId::Calo && detId.subdetId()==HcalZDCDetId::SubdetectorId) return 0; 00059 HcalDetId hcalDetId(hit.id()); 00060 double delay = 0.; 00061 00062 if(hcalDetId.subdet() == HcalBarrel || hcalDetId.subdet() == HcalEndcap || hcalDetId.subdet() == HcalOuter ) { 00063 00064 HcalTimeSlew::BiasSetting biasSetting = (hcalDetId.subdet() == HcalOuter) ? 00065 HcalTimeSlew::Slow : 00066 HcalTimeSlew::Medium; 00067 00068 int tbin = timeBin(hit); 00069 double totalCharge=0; 00070 if(tbin >= 0 && tbin < 10) 00071 { 00072 ChargeSumsByChannel::const_iterator totalChargeItr = theChargeSumsForTimeBin[tbin].find(detId); 00073 if(totalChargeItr == theChargeSumsForTimeBin[tbin].end()) 00074 { 00075 throw cms::Exception("HcalHitCorrection") << "Cannot find HCAL charge sum for hit " << hit; 00076 } 00077 totalCharge = totalChargeItr->second; 00078 delay = HcalTimeSlew::delay(totalCharge, biasSetting); 00079 LogDebug("HcalHitCorrection") << "TIMESLEWcharge " << charge(hit) 00080 << " totalcharge " << totalCharge 00081 << " olddelay " << HcalTimeSlew::delay(charge(hit), biasSetting) 00082 << " newdelay " << delay; 00083 } 00084 // now, the smearing 00085 const HcalSimParameters& params=static_cast<const HcalSimParameters&>(theParameterMap->simParameters(detId)); 00086 if (params.doTimeSmear() && theRandGaussQ!=0) { 00087 double rms=params.timeSmearRMS(charge(hit)); 00088 00089 double smearns=theRandGaussQ->fire()*rms; 00090 00091 LogDebug("HcalHitCorrection") << "TimeSmear charge " << charge(hit) << " rms " << rms << " delay " << delay << " smearns " << smearns; 00092 delay+=smearns; 00093 } 00094 } 00095 00096 return delay; 00097 } 00098 00099 00100 void HcalHitCorrection::correct(PCaloHit & hit) const { 00101 // replace the hit with a new one, with a time delay 00102 hit = PCaloHit(hit.id(), hit.energyEM(), hit.energyHad(), hit.time()+delay(hit), hit.geantTrackId()); 00103 } 00104 00105 00106 int HcalHitCorrection::timeBin(const PCaloHit & hit) const 00107 { 00108 const CaloSimParameters & parameters = theParameterMap->simParameters(DetId(hit.id())); 00109 double t = hit.time() - timeOfFlight(DetId(hit.id())) + parameters.timePhase(); 00110 return static_cast<int> (t / 25) + parameters.binOfMaximum() - 1; 00111 } 00112 00113 00114 double HcalHitCorrection::timeOfFlight(const DetId & detId) const 00115 { 00116 if(detId.det()==DetId::Calo && detId.subdetId()==HcalZDCDetId::SubdetectorId) 00117 return 37.666; 00118 switch(detId.subdetId()) 00119 { 00120 case HcalBarrel: 00121 return 8.4; 00122 break; 00123 case HcalEndcap: 00124 return 13.; 00125 break; 00126 case HcalOuter: 00127 return 18.7; 00128 break; 00129 case HcalForward: 00130 return 37.; 00131 break; 00132 default: 00133 throw cms::Exception("HcalHitCorrection") << "Bad Hcal subdetector " << detId.subdetId(); 00134 break; 00135 } 00136 } 00137 00138 00139 00140 void HcalHitCorrection::setRandomEngine(CLHEP::HepRandomEngine & engine) { 00141 if (theRandGaussQ==0) { 00142 theRandGaussQ=new CLHEP::RandGaussQ(engine); 00143 } 00144 }