CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/CalibCalorimetry/HcalAlgos/src/HcalPulseShapes.cc

Go to the documentation of this file.
00001 #include "CalibCalorimetry/HcalAlgos/interface/HcalPulseShapes.h"
00002 #include "CondFormats/HcalObjects/interface/HcalMCParam.h"
00003 #include "CondFormats/HcalObjects/interface/HcalMCParams.h"
00004 #include "CondFormats/DataRecord/interface/HcalMCParamsRcd.h"
00005 #include "CondFormats/HcalObjects/interface/HcalRecoParam.h"
00006 #include "CondFormats/HcalObjects/interface/HcalRecoParams.h"
00007 #include "CondFormats/DataRecord/interface/HcalRecoParamsRcd.h"
00008 #include "FWCore/Utilities/interface/Exception.h"
00009 #include "FWCore/Framework/interface/ESHandle.h"
00010 #include "FWCore/Framework/interface/EventSetup.h"
00011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00012 #include "Geometry/CaloTopology/interface/HcalTopology.h"
00013 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00014 
00015 // #include "CalibCalorimetry/HcalAlgos/interface/HcalDbASCIIIO.h"
00016 #include <cmath>
00017 
00018 #include <iostream>
00019 #include <fstream>
00020 
00021 HcalPulseShapes::HcalPulseShapes() 
00022 : theMCParams(0),
00023   theTopology(0),
00024   theRecoParams(0),
00025   theShapes()
00026 {
00027 /*
00028 
00029 Reco  MC
00030 --------------------------------------------------------------------------------------
00031 000                                                   not used (reserved)
00032 101   101      hpdShape_                              HPD (original version)
00033 102   102      =101                                   HPD BV 30 volts in HBP iphi54
00034 103   123      hpdShape_v2, hpdShapeMC_v2             HPD (2011. oct version)
00035 104   124      hpdBV30Shape_v2, hpdBV30ShapeMC_v2     HPD bv30 in HBP iph54
00036 105   125      hpdShape_v2, hpdShapeMC_v2             HPD (2011.11.12 version)
00037 201   201      siPMShape_                             SiPMs Zecotec shape   (HO)
00038 202   202      =201,                                  SiPMs Hamamatsu shape (HO)
00039 301   301      hfShape_                               regular HF PMT shape
00040 401   401                                             regular ZDC shape
00041 --------------------------------------------------------------------------------------
00042 
00043 */
00044 
00045  
00046   float ts1, ts2, ts3, thpd, tpre, wd1, wd2, wd3;
00047 
00048   //  HPD Shape  Version 1 (used before CMSSW5, until Oct 2011)
00049   ts1=8. ; ts2=10. ; ts3=29.3; thpd=4.0; tpre=9.0; wd1=2.0; wd2=0.7; wd3=1.0;  
00050   computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdShape_);
00051   theShapes[101] = &hpdShape_;
00052   theShapes[102] = theShapes[101];
00053 
00054   //  HPD Shape  Version 2 for CMSSW 5. Nov 2011  (RECO and MC separately)
00055   ts1=8. ; ts2=10. ; ts3=25.0; thpd=4.0; tpre=9.0; wd1=2.0; wd2=0.7; wd3=1.0;
00056   computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdShape_v2);
00057   theShapes[103] = &hpdShape_v2;
00058 
00059   ts1=8. ; ts2=10. ; ts3=29.3; thpd=4.0; tpre=7.0; wd1=2.0; wd2=0.7; wd3=1.0;
00060   computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdShapeMC_v2);
00061   theShapes[123] = &hpdShapeMC_v2;
00062 
00063   //  HPD Shape  Version 3 for CMSSW 5. Nov 2011  (RECO and MC separately)
00064   ts1=8. ; ts2=19. ; ts3=29.3; thpd=4.0; tpre=9.0; wd1=2.0; wd2=0.7; wd3=0.32;
00065   computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdShape_v3);
00066   theShapes[105] = &hpdShape_v3;
00067 
00068   ts1=8. ; ts2=10. ; ts3=22.3; thpd=4.0; tpre=7.0; wd1=2.0; wd2=0.7; wd3=1.0;
00069   computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdShapeMC_v3);
00070   theShapes[125] = &hpdShapeMC_v3;
00071 
00072   // HPD with Bias Voltage 30 volts, wider pulse.  (HBPlus iphi54)
00073 
00074   ts1=8. ; ts2=12. ; ts3=31.7; thpd=9.0; tpre=9.0; wd1=2.0; wd2=0.7; wd3=1.0;
00075   computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdBV30Shape_v2);
00076   theShapes[104] = &hpdBV30Shape_v2;
00077 
00078   ts1=8. ; ts2=12. ; ts3=31.7; thpd=9.0; tpre=9.0; wd1=2.0; wd2=0.7; wd3=1.0;
00079   computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdBV30ShapeMC_v2);
00080   theShapes[124] = &hpdBV30ShapeMC_v2;
00081 
00082   // HF and SiPM
00083 
00084   computeHFShape();
00085   computeSiPMShape();
00086 
00087   theShapes[201] = &siPMShape_;
00088   theShapes[202] = theShapes[201];
00089   theShapes[301] = &hfShape_;
00090   //theShapes[401] = new CaloCachedShapeIntegrator(&theZDCShape);
00091 
00092   /*
00093   // backward-compatibility with old scheme
00094   theShapes[0] = theShapes[101];
00095   //FIXME "special" HB
00096   theShapes[1] = theShapes[101];
00097   theShapes[2] = theShapes[201];
00098   theShapes[3] = theShapes[301];
00099   //theShapes[4] = theShapes[401];
00100   */
00101 }
00102 
00103 
00104 HcalPulseShapes::~HcalPulseShapes() {
00105   if (theMCParams) delete theMCParams;
00106   if (theRecoParams) delete theRecoParams;
00107   if (theTopology) delete theTopology;
00108 }
00109 
00110 
00111 void HcalPulseShapes::beginRun(edm::EventSetup const & es)
00112 {
00113   edm::ESHandle<HcalMCParams> p;
00114   es.get<HcalMCParamsRcd>().get(p);
00115   theMCParams = new HcalMCParams(*p.product());
00116 
00117   edm::ESHandle<HcalTopology> htopo;
00118   es.get<IdealGeometryRecord>().get(htopo);
00119   theTopology=new HcalTopology(*htopo);
00120   theMCParams->setTopo(theTopology);
00121 
00122   edm::ESHandle<HcalRecoParams> q;
00123   es.get<HcalRecoParamsRcd>().get(q);
00124   theRecoParams = new HcalRecoParams(*q.product());
00125   theRecoParams->setTopo(theTopology);
00126 
00127 //      std::cout<<" skdump in HcalPulseShapes::beginRun   dupm MCParams "<<std::endl;
00128 //      std::ofstream skfile("skdumpMCParamsNewFormat.txt");
00129 //      HcalDbASCIIIO::dumpObject(skfile, (*theMCParams) );
00130 }
00131 
00132 
00133 void HcalPulseShapes::endRun()
00134 {
00135   if (theMCParams) delete theMCParams;
00136   if (theRecoParams) delete theRecoParams;
00137   if (theTopology) delete theTopology;
00138 
00139 
00140   theMCParams = 0;
00141   theRecoParams = 0;
00142   theTopology = 0;
00143 }
00144 
00145 
00146 //void HcalPulseShapes::computeHPDShape()
00147 void HcalPulseShapes::computeHPDShape(float ts1, float ts2, float ts3, float thpd, float tpre,
00148                                 float wd1, float wd2, float wd3, Shape &tmphpdShape_)
00149 {
00150 
00151   /*
00152   std::cout << "o HcalPulseShapes::computeHPDShape  " 
00153             << " ts1, ts2, ts3, thpd, tpre, w1, w2, w3 =" 
00154             <<  ts1 << ", " << ts2 << ", " << ts3 << ", " 
00155             << thpd << ", " << tpre << ", " << wd1 << ", " <<  wd2 
00156             << ", "  << wd3 << std::endl;
00157   */
00158 
00159 // pulse shape time constants in ns
00160 /*
00161   const float ts1  = 8.;          // scintillation time constants : 1,2,3
00162   const float ts2  = 10.;           
00163   const float ts3  = 29.3;         
00164   const float thpd = 4.;          // HPD current collection drift time
00165   const float tpre = 9.;          // preamp time constant (refit on TB04 data)
00166   
00167   const float wd1 = 2.;           // relative weights of decay exponents 
00168   const float wd2 = 0.7;
00169   const float wd3 = 1.;
00170 */  
00171   // pulse shape componnts over a range of time 0 ns to 255 ns in 1 ns steps
00172   unsigned int nbin = 256;
00173   tmphpdShape_.setNBin(nbin);
00174   std::vector<float> ntmp(nbin,0.0);  // zeroing output pulse shape
00175   std::vector<float> nth(nbin,0.0);   // zeroing HPD drift shape
00176   std::vector<float> ntp(nbin,0.0);   // zeroing Binkley preamp shape
00177   std::vector<float> ntd(nbin,0.0);   // zeroing Scintillator decay shape
00178 
00179   unsigned int i,j,k;
00180   float norm;
00181 
00182   // HPD starts at I and rises to 2I in thpd of time
00183   norm=0.0;
00184   for(j=0;j<thpd && j<nbin;j++){
00185     nth[j] = 1.0 + ((float)j)/thpd;
00186     norm += nth[j];
00187   }
00188   // normalize integrated current to 1.0
00189   for(j=0;j<thpd && j<nbin;j++){
00190     nth[j] /= norm;
00191   }
00192   
00193   // Binkley shape over 6 time constants
00194   norm=0.0;
00195   for(j=0;j<6*tpre && j<nbin;j++){
00196     ntp[j] = ((float)j)*exp(-((float)(j*j))/(tpre*tpre));
00197     norm += ntp[j];
00198   }
00199   // normalize pulse area to 1.0
00200   for(j=0;j<6*tpre && j<nbin;j++){
00201     ntp[j] /= norm;
00202   }
00203 
00204 // ignore stochastic variation of photoelectron emission
00205 // <...>
00206 
00207 // effective tile plus wave-length shifter decay time over 4 time constants
00208   unsigned int tmax = 6 * (int)ts3;
00209  
00210   norm=0.0;
00211   for(j=0;j<tmax && j<nbin;j++){
00212     ntd[j] = wd1 * exp(-((float)j)/ts1) + 
00213       wd2 * exp(-((float)j)/ts2) + 
00214       wd3 * exp(-((float)j)/ts3) ; 
00215     norm += ntd[j];
00216   }
00217   // normalize pulse area to 1.0
00218   for(j=0;j<tmax && j<nbin;j++){
00219     ntd[j] /= norm;
00220   }
00221   
00222   unsigned int t1,t2,t3,t4;
00223   for(i=0;i<tmax && i<nbin;i++){
00224     t1 = i;
00225     //    t2 = t1 + top*rand;
00226     // ignoring jitter from optical path length
00227     t2 = t1;
00228     for(j=0;j<thpd && j<nbin;j++){
00229       t3 = t2 + j;
00230       for(k=0;k<4*tpre && k<nbin;k++){       // here "4" is set deliberately,
00231         t4 = t3 + k;                         // as in test fortran toy MC ...
00232         if(t4<nbin){                         
00233           unsigned int ntb=t4;                        
00234           ntmp[ntb] += ntd[i]*nth[j]*ntp[k];
00235         }
00236       }
00237     }
00238   }
00239   
00240   // normalize for 1 GeV pulse height
00241   norm = 0.;
00242   for(i=0;i<nbin;i++){
00243     norm += ntmp[i];
00244   }
00245 
00246   //cout << " Convoluted SHAPE ==============  " << endl;
00247   for(i=0; i<nbin; i++){
00248     ntmp[i] /= norm;
00249     //  cout << " shape " << i << " = " << ntmp[i] << endl;   
00250   }
00251 
00252   for(i=0; i<nbin; i++){
00253     tmphpdShape_.setShapeBin(i,ntmp[i]);
00254   }
00255 }
00256 
00257 void HcalPulseShapes::computeHFShape() {
00258   // first create pulse shape over a range of time 0 ns to 255 ns in 1 ns steps
00259   unsigned int nbin = 256;
00260   hfShape_.setNBin(nbin);
00261   std::vector<float> ntmp(nbin,0.0);  // 
00262 
00263   const float k0=0.7956; // shape parameters
00264   const float p2=1.355;
00265   const float p4=2.327;
00266   const float p1=4.3;    // position parameter
00267 
00268   float norm = 0.0;
00269 
00270   for(unsigned int j = 0; j < 25 && j < nbin; ++j){
00271 
00272     float r0 = j-p1;
00273     float sigma0 = (r0<0) ? p2 : p2*p4;
00274     r0 /= sigma0;
00275     if(r0 < k0) ntmp[j] = exp(-0.5*r0*r0);
00276     else ntmp[j] = exp(0.5*k0*k0-k0*r0);
00277     norm += ntmp[j];
00278   }
00279   // normalize pulse area to 1.0
00280   for(unsigned int j = 0; j < 25 && j < nbin; ++j){
00281     ntmp[j] /= norm;
00282     hfShape_.setShapeBin(j,ntmp[j]);
00283   }
00284 }
00285 
00286 
00287 void HcalPulseShapes::computeSiPMShape()
00288 {
00289   unsigned int nbin = 100; // to avoid big drop of integral for previous 512
00290                        // due to negative afterpulse (May 6, 2013. S.Abdullin) 
00291   siPMShape_.setNBin(nbin);
00292   std::vector<float> nt(nbin,0.0);  //
00293 
00294   double norm = 0.;
00295   for (unsigned int j = 0; j < nbin; ++j) {
00296     if (j <= 31.)
00297       nt[j] = 2.15*j;
00298     else if ((j > 31) && (j <= 96))
00299       nt[j] = 102.1 - 1.12*j;
00300     else
00301       nt[j] = 0.0076*j - 6.4;
00302     norm += (nt[j]>0) ? nt[j] : 0.;
00303   }
00304 
00305   for (unsigned int j = 0; j < nbin; ++j) {
00306     nt[j] /= norm;
00307     siPMShape_.setShapeBin(j,nt[j]);
00308   }
00309 }
00310 
00311 
00312 const HcalPulseShapes::Shape &
00313 HcalPulseShapes::getShape(int shapeType) const
00314 {
00315 
00316   //  std::cout << "- HcalPulseShapes::Shape for type "<< shapeType 
00317   //            << std::endl;
00318 
00319   ShapeMap::const_iterator shapeMapItr = theShapes.find(shapeType);
00320   if(shapeMapItr == theShapes.end()) {
00321    throw cms::Exception("HcalPulseShapes") << "unknown shapeType";
00322    return  hpdShape_;   // should not return this, but...
00323   } else {
00324     return *(shapeMapItr->second);
00325   }
00326 }
00327 
00328 
00329 const HcalPulseShapes::Shape &
00330 HcalPulseShapes::shape(const HcalDetId & detId) const
00331 {
00332   if(!theMCParams) {
00333     return defaultShape(detId);
00334   }
00335   int shapeType = theMCParams->getValues(detId)->signalShape();
00336 
00337   /*
00338           int sub     = detId.subdet();
00339           int depth   = detId.depth();
00340           int inteta  = detId.ieta();
00341           int intphi  = detId.iphi();
00342           
00343           std::cout << " HcalPulseShapes::shape cell:" 
00344                     << " sub, ieta, iphi, depth = " 
00345                     << sub << "  " << inteta << "  " << intphi 
00346                     << "  " << depth  << " => ShapeId "<<  shapeType 
00347                     << std::endl;
00348   */
00349 
00350   ShapeMap::const_iterator shapeMapItr = theShapes.find(shapeType);
00351   if(shapeMapItr == theShapes.end()) {
00352     return defaultShape(detId);
00353   } else {
00354     return *(shapeMapItr->second);
00355   }
00356 }
00357 
00358 const HcalPulseShapes::Shape &
00359 HcalPulseShapes::shapeForReco(const HcalDetId & detId) const
00360 {
00361   if(!theRecoParams) {
00362     return defaultShape(detId);
00363   }
00364   int shapeType = theRecoParams->getValues(detId.rawId())->pulseShapeID();
00365 
00366   /*
00367           int sub     = detId.subdet();
00368           int depth   = detId.depth();
00369           int inteta  = detId.ieta();
00370           int intphi  = detId.iphi();
00371           
00372           std::cout << ">> HcalPulseShapes::shapeForReco cell:" 
00373                     << " sub, ieta, iphi, depth = " 
00374                     << sub << "  " << inteta << "  " << intphi 
00375                     << "  " << depth  << " => ShapeId "<<  shapeType 
00376                     << std::endl;
00377   */
00378 
00379   ShapeMap::const_iterator shapeMapItr = theShapes.find(shapeType);
00380   if(shapeMapItr == theShapes.end()) {
00381     return defaultShape(detId);
00382   } else {
00383     return *(shapeMapItr->second);
00384   }
00385 }
00386 
00387 
00388 const HcalPulseShapes::Shape &
00389 HcalPulseShapes::defaultShape(const HcalDetId & detId) const
00390 {
00391   edm::LogWarning("HcalPulseShapes") << "Cannot find HCAL MC Params ";
00392   HcalSubdetector subdet = detId.subdet();
00393   switch(subdet) {
00394   case HcalBarrel:
00395     return hbShape();
00396   case HcalEndcap:
00397     return heShape();
00398   case HcalForward:
00399     return hfShape();
00400   case HcalOuter:
00401     //FIXME doesn't look for SiPMs
00402     return hoShape(false);
00403   default:
00404     throw cms::Exception("HcalPulseShapes") << "unknown detId";
00405     break;
00406   }
00407 }
00408