CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/CalibCalorimetry/HcalAlgos/src/HcalPulseShapes.cc

Go to the documentation of this file.
00001 #include "CalibCalorimetry/HcalAlgos/interface/HcalPulseShapes.h"
00002 #include <cmath>
00003 
00004 HcalPulseShapes::HcalPulseShapes() {
00005   computeHPDShape(hpdShape_);
00006   computeHFShape(hfShape_);
00007 }
00008 
00009 
00010 void HcalPulseShapes::computeHPDShape(HcalPulseShapes::Shape& sh)
00011 {
00012 
00013   // pulse shape time constants in ns
00014   const float ts1  = 8.;          // scintillation time constants : 1,2,3
00015   const float ts2  = 10.;           
00016   const float ts3  = 29.3;         
00017   const float thpd = 4.;          // HPD current collection drift time
00018   const float tpre = 9.;          // preamp time constant (refit on TB04 data)
00019   
00020   const float wd1 = 2.;           // relative weights of decay exponents 
00021   const float wd2 = 0.7;
00022   const float wd3 = 1.;
00023   
00024   // pulse shape componnts over a range of time 0 ns to 255 ns in 1 ns steps
00025   int nbin = 256;
00026   sh.setNBin(nbin);
00027   std::vector<float> ntmp(nbin,0.0);  // zeroing output pulse shape
00028   std::vector<float> nth(nbin,0.0);   // zeroing HPD drift shape
00029   std::vector<float> ntp(nbin,0.0);   // zeroing Binkley preamp shape
00030   std::vector<float> ntd(nbin,0.0);   // zeroing Scintillator decay shape
00031 
00032   int i,j,k;
00033   float norm;
00034 
00035   // HPD starts at I and rises to 2I in thpd of time
00036   norm=0.0;
00037   for(j=0;j<thpd && j<nbin;j++){
00038     nth[j] = 1.0 + ((float)j)/thpd;
00039     norm += nth[j];
00040   }
00041   // normalize integrated current to 1.0
00042   for(j=0;j<thpd && j<nbin;j++){
00043     nth[j] /= norm;
00044   }
00045   
00046   // Binkley shape over 6 time constants
00047   norm=0.0;
00048   for(j=0;j<6*tpre && j<nbin;j++){
00049     ntp[j] = ((float)j)*exp(-((float)(j*j))/(tpre*tpre));
00050     norm += ntp[j];
00051   }
00052   // normalize pulse area to 1.0
00053   for(j=0;j<6*tpre && j<nbin;j++){
00054     ntp[j] /= norm;
00055   }
00056 
00057 // ignore stochastic variation of photoelectron emission
00058 // <...>
00059 
00060 // effective tile plus wave-length shifter decay time over 4 time constants
00061   int tmax = 6 * (int)ts3;
00062  
00063   norm=0.0;
00064   for(j=0;j<tmax && j<nbin;j++){
00065     ntd[j] = wd1 * exp(-((float)j)/ts1) + 
00066       wd2 * exp(-((float)j)/ts2) + 
00067       wd3 * exp(-((float)j)/ts3) ; 
00068     norm += ntd[j];
00069   }
00070   // normalize pulse area to 1.0
00071   for(j=0;j<tmax && j<nbin;j++){
00072     ntd[j] /= norm;
00073   }
00074   
00075   int t1,t2,t3,t4;
00076   for(i=0;i<tmax && i<nbin;i++){
00077     t1 = i;
00078     //    t2 = t1 + top*rand;
00079     // ignoring jitter from optical path length
00080     t2 = t1;
00081     for(j=0;j<thpd && j<nbin;j++){
00082       t3 = t2 + j;
00083       for(k=0;k<4*tpre && k<nbin;k++){       // here "4" is set deliberately,
00084  t4 = t3 + k;                         // as in test fortran toy MC ...
00085  if(t4<nbin){                         
00086    int ntb=t4;                        
00087    ntmp[ntb] += ntd[i]*nth[j]*ntp[k];
00088         }
00089       }
00090     }
00091   }
00092   
00093   // normalize for 1 GeV pulse height
00094   norm = 0.;
00095   for(i=0;i<nbin;i++){
00096     norm += ntmp[i];
00097   }
00098 
00099   //cout << " Convoluted SHAPE ==============  " << endl;
00100   for(i=0; i<nbin; i++){
00101     ntmp[i] /= norm;
00102     //  cout << " shape " << i << " = " << ntmp[i] << endl;   
00103   }
00104 
00105   for(i=0; i<nbin; i++){
00106     sh.setShapeBin(i,ntmp[i]);
00107   }
00108 }
00109 
00110 void HcalPulseShapes::computeHFShape(HcalPulseShapes::Shape& sh) {
00111 
00112   //  cout << endl << " ===== computeShapeHF  !!! " << endl << endl;
00113 
00114   const float ts = 3.0;           // time constant in   t * exp(-(t/ts)**2)
00115 
00116   // first create pulse shape over a range of time 0 ns to 255 ns in 1 ns steps
00117   int nbin = 256;
00118   sh.setNBin(nbin);
00119   std::vector<float> ntmp(nbin,0.0);  // 
00120 
00121   int j;
00122   float norm;
00123 
00124   // HF SHAPE
00125   norm = 0.0;
00126   for( j = 0; j < 3 * ts && j < nbin; j++){
00127     ntmp[j] = ((float)j)*exp(-((float)(j*j))/(ts*ts));
00128     norm += ntmp[j];
00129   }
00130   // normalize pulse area to 1.0
00131   for( j = 0; j < 3 * ts && j < nbin; j++){
00132     ntmp[j] /= norm;
00133 
00134     //    cout << " nt [" << j << "] = " <<  ntmp[j] << endl;
00135     sh.setShapeBin(j,ntmp[j]);
00136   }
00137 }
00138 
00139 HcalPulseShapes::Shape::Shape() {
00140   nbin_=0;
00141   tpeak_=0;
00142 }
00143 
00144 void HcalPulseShapes::Shape::setNBin(int n) {
00145   nbin_=n;
00146   shape_=std::vector<float>(n,0.0f);
00147 }
00148 
00149 void HcalPulseShapes::Shape::setShapeBin(int i, float f) {
00150   if (i>=0 && i<nbin_) shape_[i]=f;
00151 }
00152 
00153 float HcalPulseShapes::Shape::operator()(double t) const {
00154   // shape is in 1 ns steps
00155   int i=(int)(t+0.5);
00156   float rv=0;
00157   if (i>=0 && i<nbin_) rv=shape_[i];
00158   return rv;
00159 }
00160 
00161 float HcalPulseShapes::Shape::at(double t) const {
00162   // shape is in 1 ns steps
00163   int i=(int)(t+0.5);
00164   float rv=0;
00165   if (i>=0 && i<nbin_) rv=shape_[i];
00166   return rv;
00167 }
00168 
00169 float HcalPulseShapes::Shape::integrate(double t1, double t2) const {
00170   static const float int_delta_ns = 0.05f; 
00171   double intval = 0.0;
00172 
00173   for (double t = t1; t < t2; t+= int_delta_ns) {
00174     float loedge = at(t);
00175     float hiedge = at(t+int_delta_ns);
00176     intval += (loedge+hiedge)*int_delta_ns/2.0;
00177   }
00178 
00179   return (float)intval;
00180 }