CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/SimCalorimetry/HcalSimAlgos/src/HcalSiPMHitResponse.cc

Go to the documentation of this file.
00001 #include "SimCalorimetry/HcalSimAlgos/interface/HcalSiPMHitResponse.h"
00002 #include "SimCalorimetry/HcalSimAlgos/interface/HcalSiPM.h"
00003 #include "SimCalorimetry/HcalSimAlgos/interface/HcalSimParameters.h"
00004 #include "SimCalorimetry/HcalSimAlgos/interface/HcalShapes.h"
00005 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVHitFilter.h"
00008 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVSimParameterMap.h"
00009 #include "SimCalorimetry/CaloSimAlgos/interface/CaloSimParameters.h"
00010 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVHitCorrection.h"
00011 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVShape.h"
00012 #include "FWCore/Utilities/interface/isFinite.h"
00013 
00014 #include <math.h>
00015 
00016 HcalSiPMHitResponse::HcalSiPMHitResponse(const CaloVSimParameterMap * parameterMap,
00017                                          const CaloShapes * shapes) :
00018   CaloHitResponse(parameterMap, shapes), theSiPM(), theRecoveryTime(250.), 
00019   TIMEMULT(1), Y11RANGE(80.), Y11MAX(0.04), Y11TIMETORISE(16.65), 
00020   theRndFlat(0) {
00021   theSiPM = new HcalSiPM(2500);
00022 }
00023 
00024 HcalSiPMHitResponse::~HcalSiPMHitResponse() {
00025   if (theSiPM)
00026     delete theSiPM;
00027   delete theRndFlat;
00028 }
00029 
00030 void HcalSiPMHitResponse::initializeHits() {
00031   LogDebug("HcalSiPMHitResponse") << "HcalSiPMHitResponse::initalizeHits()";
00032   precisionTimedPhotons.clear();
00033   LogDebug("HcalSiPMHitResponse") << " precisionTimedPhotons size: " << precisionTimedPhotons.size()
00034             << std::endl;
00035 }
00036 
00037 void HcalSiPMHitResponse::finalizeHits() {
00038 
00039   photonTimeMap::iterator channelPhotons;
00040   for (channelPhotons = precisionTimedPhotons.begin();
00041        channelPhotons != precisionTimedPhotons.end();
00042        ++channelPhotons) {
00043     CaloSamples signal(makeSiPMSignal(channelPhotons->first, 
00044                                       channelPhotons->second));
00045     bool keep( keepBlank() );
00046     if (!keep) {
00047       const unsigned int size ( signal.size() ) ;
00048       if( 0 != size ) {
00049         for( unsigned int i ( 0 ) ; i != size ; ++i ) {
00050           keep = keep || signal[i] > 1.e-7 ;
00051         }
00052       }
00053     }
00054     // LogDebug("HcalSiPMHitResponse") << signal;
00055 
00056     LogDebug("HcalSiPMHitResponse") << HcalDetId(signal.id()) << ' ' << signal;
00057     if (keep) add(signal);
00058   }
00059 }
00060 
00061 void HcalSiPMHitResponse::add(const CaloSamples& signal) {
00062   DetId id(signal.id());
00063   CaloSamples * oldSignal = findSignal(id);
00064   if (oldSignal == 0) {
00065     theAnalogSignalMap[id] = signal;
00066   } else {
00067     (*oldSignal) += signal;
00068   }
00069 }
00070 
00071 void HcalSiPMHitResponse::add(const PCaloHit& hit) {
00072     if (!edm::isNotFinite(hit.time()) &&
00073         ((theHitFilter == 0) || (theHitFilter->accepts(hit)))) {
00074       HcalDetId id(hit.id());
00075       const HcalSimParameters& pars = dynamic_cast<const HcalSimParameters&>(theParameterMap->simParameters(id));
00076       if (precisionTimedPhotons.find(id)==precisionTimedPhotons.end()) {
00077         precisionTimedPhotons.insert(std::pair<DetId, photonTimeHist >(id, photonTimeHist(theTDCParams.nbins()*TIMEMULT*pars.readoutFrameSize(), 0)));
00078       }
00079       double signal(analogSignalAmplitude(id, hit.energy(), pars));
00080       unsigned int photons(signal + 0.5);
00081       double time( hit.time() );
00082 
00083       LogDebug("HcalSiPMHitResponse") << id;
00084       LogDebug("HcalSiPMHitResponse") << " fCtoGeV: " << pars.fCtoGeV(id)
00085                 << " samplingFactor: " << pars.samplingFactor(id)
00086                 << " photoelectronsToAnalog: " << pars.photoelectronsToAnalog(id)
00087                 << " simHitToPhotoelectrons: " << pars.simHitToPhotoelectrons(id);
00088       LogDebug("HcalSiPMHitResponse") << " energy: " << hit.energy()
00089                 << " photons: " << photons 
00090                 << " time: " << time;
00091       if (theHitCorrection != 0)
00092         time += theHitCorrection->delay(hit);
00093       LogDebug("HcalSiPMHitResponse") << " corrected time: " << time;
00094       LogDebug("HcalSiPMHitResponse") << " timePhase: " << pars.timePhase()
00095                 << " tof: " << timeOfFlight(id)
00096                 << " binOfMaximum: " << pars.binOfMaximum()
00097                 << " phaseShift: " << thePhaseShift_;
00098       double tzero(Y11TIMETORISE + pars.timePhase() - 
00099                    (hit.time() - timeOfFlight(id)) - 
00100                    BUNCHSPACE*( pars.binOfMaximum() - thePhaseShift_));
00101       LogDebug("HcalSiPMHitResponse") << " tzero: " << tzero;
00102       tzero += BUNCHSPACE*pars.binOfMaximum() + 72.31;
00103       LogDebug("HcalSiPMHitResponse") << " corrected tzero: " << tzero << '\n';
00104       double t_pe(0.);
00105       int t_bin(0);
00106       for (unsigned int pe(0); pe<photons; ++pe) {
00107         t_pe = generatePhotonTime();
00108         t_bin = int((t_pe + tzero)/(theTDCParams.deltaT()/TIMEMULT) + 0.5);
00109         LogDebug("HcalSiPMHitResponse") << "t_pe: " << t_pe << " t_pe + tzero: " << (t_pe+tzero)
00110                   << " t_bin: " << t_bin << '\n';
00111         if ((t_bin >= 0) && 
00112             (static_cast<unsigned int>(t_bin) < precisionTimedPhotons[id].size()))
00113             precisionTimedPhotons[id][t_bin] += 1;
00114       }
00115     }
00116 }
00117 
00118 void HcalSiPMHitResponse::run(MixCollection<PCaloHit> & hits) {
00119   typedef std::multiset <const PCaloHit *, PCaloHitCompareTimes> SortedHitSet;
00120 
00121   std::map< DetId, SortedHitSet > sortedhits;
00122   for (MixCollection<PCaloHit>::MixItr hitItr = hits.begin();
00123        hitItr != hits.end(); ++hitItr) {
00124     if (!((hitItr.bunch() < theMinBunch) || (hitItr.bunch() > theMaxBunch)) &&
00125         !(edm::isNotFinite(hitItr->time())) &&
00126         ((theHitFilter == 0) || (theHitFilter->accepts(*hitItr)))) {
00127       DetId id(hitItr->id());
00128       if (sortedhits.find(id)==sortedhits.end())
00129         sortedhits.insert(std::pair<DetId, SortedHitSet>(id, SortedHitSet()));
00130       sortedhits[id].insert(&(*hitItr));
00131     }
00132   }
00133   int pixelIntegral, oldIntegral;
00134   HcalSiPMRecovery pixelHistory(theRecoveryTime);
00135   for (std::map<DetId, SortedHitSet>::iterator i = sortedhits.begin(); 
00136        i!=sortedhits.end(); ++i) {
00137     pixelHistory.clearHistory();
00138     for (SortedHitSet::iterator itr = i->second.begin(); 
00139          itr != i->second.end(); ++itr) {
00140       const PCaloHit& hit = **itr;
00141       pixelIntegral = pixelHistory.getIntegral(hit.time());
00142       oldIntegral = pixelIntegral;
00143       CaloSamples signal(makeSiPMSignal(i->first, hit, pixelIntegral));
00144       pixelHistory.addToHistory(hit.time(), pixelIntegral-oldIntegral);
00145       add(signal);
00146     }
00147   }
00148 }
00149 
00150 
00151 void HcalSiPMHitResponse::setRandomEngine(CLHEP::HepRandomEngine & engine)
00152 {
00153   theSiPM->initRandomEngine(engine);
00154   CaloHitResponse::setRandomEngine(engine);
00155   theRndFlat = new CLHEP::RandFlat(engine);
00156 }
00157 
00158 CaloSamples HcalSiPMHitResponse::makeBlankSignal(const DetId& detId) const {
00159   const CaloSimParameters & parameters = theParameterMap->simParameters(detId);
00160   int preciseSize(parameters.readoutFrameSize()*theTDCParams.nbins());
00161   CaloSamples result(detId, parameters.readoutFrameSize(), preciseSize);
00162   result.setPresamples(parameters.binOfMaximum()-1);
00163   result.setPrecise(result.presamples()*theTDCParams.nbins(), 
00164                     theTDCParams.deltaT());
00165   return result;
00166 }
00167 
00168 CaloSamples HcalSiPMHitResponse::makeSiPMSignal(const DetId & id,
00169                                                 const PCaloHit & inHit, 
00170                                                 int & integral ) const {
00171   
00172   PCaloHit hit = inHit;
00173   if (theHitCorrection != 0) {
00174     hit.setTime(hit.time() + theHitCorrection->delay(hit));
00175   }
00176 
00177   const HcalSimParameters& pars = dynamic_cast<const HcalSimParameters&>(theParameterMap->simParameters(id));
00178   theSiPM->setNCells(pars.pixels());
00179 
00180   double signal = analogSignalAmplitude(id, hit.energy(), pars);
00181   int photons = static_cast<int>(signal + 0.5);
00182   int pixels = theSiPM->hitCells(photons, integral);
00183   integral += pixels;
00184   signal = double(pixels);
00185 
00186   CaloSamples result(makeBlankSignal(id));
00187 
00188   if(pixels > 0)
00189   {
00190     const CaloVShape * shape = theShapes->shape(id);
00191     double jitter = hit.time() - timeOfFlight(id);
00192 
00193     const double tzero = pars.timePhase() - jitter -
00194       BUNCHSPACE*(pars.binOfMaximum() - thePhaseShift_);
00195     double binTime = tzero;
00196 
00197     for (int bin = 0; bin < result.size(); bin++) {
00198       result[bin] += (*shape)(binTime)*signal;
00199       binTime += BUNCHSPACE;
00200     }
00201   }
00202 
00203   return result;
00204 }
00205 
00206 CaloSamples HcalSiPMHitResponse::makeSiPMSignal(DetId const& id, 
00207                                                 photonTimeHist const& photons) const {
00208   const HcalSimParameters& pars = dynamic_cast<const HcalSimParameters&>(theParameterMap->simParameters(id));  
00209   theSiPM->setNCells(pars.pixels());
00210   theSiPM->setTau(5.);
00211   //use to make signal
00212   CaloSamples signal( makeBlankSignal(id) );
00213   double dt(theTDCParams.deltaT()/TIMEMULT);
00214   int sampleBin(0), preciseBin(0);
00215   signal.resetPrecise();
00216   unsigned int pe(0);
00217   double hitPixels(0.);
00218   double elapsedTime(0.);
00219   unsigned int sumPE(0);
00220   double sumHits(0.);
00221   LogDebug("HcalSiPMHitResponse") << HcalDetId(id) << '\n';
00222   for (unsigned int pt(0); pt < photons.size(); ++pt) {
00223     pe = photons[pt];
00224     sumPE += pe;
00225     preciseBin = pt/TIMEMULT;
00226     sampleBin = preciseBin/theTDCParams.nbins();
00227     if (pe > 0) {
00228       hitPixels = theSiPM->hitCells(pe, 0., elapsedTime);
00229       signal[sampleBin] += hitPixels;
00230       signal.preciseAtMod(preciseBin) += hitPixels;
00231       sumHits += hitPixels;
00232       LogDebug("HcalSiPMHitResponse") << " elapsedTime: " << dt << " sampleBin: " << sampleBin
00233                 << " preciseBin: " << preciseBin
00234                 << " pe: " << pe << " hitPixels: " << hitPixels << '\n';
00235     }
00236     elapsedTime += dt;
00237   }
00238   LogDebug("HcalSiPMHitResponse") << "sum pe: " << sumPE << " sum sipm pixels: " << sumHits
00239             << std::endl;
00240 
00241   return signal;
00242 }
00243 
00244 double HcalSiPMHitResponse::generatePhotonTime() const {
00245   double result(0.);
00246   while (true) {
00247     result = theRndFlat->fire(Y11RANGE);
00248     if (theRndFlat->fire(Y11MAX) < Y11TimePDF(result))
00249       return result;
00250   }
00251 }
00252 
00253 double HcalSiPMHitResponse::Y11TimePDF(double t) {
00254   return exp(-0.0635-0.1518*t)*pow(t, 2.528)/2485.9;
00255 }