CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/FastSimulation/ShowerDevelopment/src/HDRShower.cc

Go to the documentation of this file.
00001 //FastSimulation Headers
00002 #include "FastSimulation/ShowerDevelopment/interface/HDRShower.h"
00003 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00004 #include "FastSimulation/CaloHitMakers/interface/EcalHitMaker.h"
00005 #include "FastSimulation/CaloHitMakers/interface/HcalHitMaker.h"
00006 
00007 //CMSSW headers
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 
00010 using namespace edm;
00011 
00013 // What's this? Doesn't seem to be needed. Maybe Geometry/CaloGeometry/interface/CaloCellGeometry.h?
00014 //#include "Calorimetry/CaloDetector/interface/CellGeometry.h"
00015 
00016 // number attempts for transverse distribution if exit on a spec. condition
00017 #define infinity 5000
00018 // debugging flag ( 0, 1, 2, 3)
00019 #define debug 0
00020 
00021 using namespace std;
00022 
00023 HDRShower::HDRShower(const RandomEngine* engine,
00024                      HDShowerParametrization* myParam, 
00025                      EcalHitMaker* myGrid,
00026                      HcalHitMaker* myHcalHitMaker,
00027                      int onECAL,
00028                      double epart)
00029   : theParam(myParam),
00030     theGrid(myGrid),
00031     theHcalHitMaker(myHcalHitMaker),
00032     onEcal(onECAL),
00033     e(epart),
00034     random(engine)
00035 { 
00036 
00037   eHDspot = 0.2;
00038   EsCut = 0.050;
00039   EcalShift = 0.12;
00040   nthetaStep = 10;
00041   thetaStep = 0.5*M_PI/nthetaStep;
00042 
00043   if(e < 0) e = 0.;
00044   setFuncParam(); 
00045 }
00046 
00047 bool HDRShower::computeShower() 
00048 {  
00049   if(onEcal) {
00050     depthECAL = theGrid->ecalTotalL0();         // ECAL depth segment
00051     depthGAP  = theGrid->ecalHcalGapTotalL0();  // GAP  depth segment
00052   }
00053   else depthECAL = depthGAP  = 0;
00054 
00055   float depthHCAL = theGrid->hcalTotalL0();    // HCAL depth segment
00056 
00057   //  maxDepth   = depthECAL + depthGAP + depthHCAL - 1.0;
00058   maxDepth   = depthECAL + depthHCAL - 0.5;
00059   depthStart = log(1./random->flatShoot()); // starting point lambda unts
00060 
00061   if( depthStart > maxDepth ) { 
00062     depthStart = maxDepth *  random->flatShoot();
00063     if( depthStart < 0.) depthStart = 0.;
00064   }
00065   
00066   if( depthStart < EcalShift) depthStart = EcalShift;
00067 
00068   decal = (depthECAL + depthStart)*0.5;
00069   qstatus = false;
00070   if(decal < depthECAL) {
00071     qstatus = theGrid->getPads(decal);
00072 //    if(!qstatus)
00073 //      cout<<" depth rejected by getQuads(decal="<<decal<<") status="<<qstatus
00074 //        <<" depthECAL="<<depthECAL<<endl;
00075 
00076   }
00077 
00078   thetaFunction(nthetaStep);
00079   int maxLoops = 10000;
00080   float esum = e;
00081   for(int itheta = 0; itheta < nthetaStep; itheta++) {
00082     float theta, es;
00083     for(int i=0; i<=thetaSpots[itheta]; i++) {
00084       if(i == thetaSpots[itheta]) es = elastspot[itheta];
00085       else es = eHDspot;
00086       float loops = 0;
00087       for(int j=0; j<maxLoops; j++) {
00088         theta = (itheta+random->flatShoot())*thetaStep;
00089         if( setHit(es, theta) ) break;
00090         loops++;
00091       }
00092       esum -= es;  // to check only
00093     }
00094   }
00095   return(true);
00096 }
00097 
00098 bool HDRShower::setHit(float espot, float theta) {
00099 
00100   float phi = 2.*M_PI*random->flatShoot(); // temporary: 1st approximation
00101   float rshower = getR();     // temporary: 1st approximation
00102 
00103   float d = depthStart + rshower*cos(theta);
00104   if(d + depthGAP > maxDepth) return(false);
00105 
00106   // Commented (F.B) to remove a warning. Not used anywhere ? 
00107   //  bool inHcal = !onEcal || d>depthECAL || !qstatus;
00108   bool result = 0;
00109   if( !onEcal || d>depthECAL || !qstatus) { // in HCAL (HF or HB, HE)
00110     d += depthGAP;
00111     bool setHDdepth = theHcalHitMaker->setDepth(d);
00112     if( setHDdepth) {
00113     theHcalHitMaker->setSpotEnergy(espot);
00114     result = theHcalHitMaker->addHit(rshower*sin(theta),phi,0);
00115     }
00116     else LogWarning("FastCalorimetry") <<" setHit in HCAL failed d="<<d
00117              <<" maxDepth="<<maxDepth<<" onEcal'"<<onEcal<<endl;
00118   }
00119   else {
00120     //    bool status = theGrid->getQuads(d);
00121     theGrid->setSpotEnergy(espot);
00122     result = theGrid->addHit(rshower*sin(theta),phi,0);
00123   }
00124   return(result);
00125 }
00126 
00127 float HDRShower::getR() {
00128   float p = random->flatShoot();
00129   unsigned int i = 1; while( rpdf[i]<p && i<R_range-1) { i++; }
00130   float r;
00131   float dr = rpdf[i] - rpdf[i-1];
00132   if(dr != 0.0)
00133     r=(float(i) + (p - rpdf[i-1])/dr)/lambdaHD;
00134   else r = float(i)/lambdaHD;
00135   return(r);
00136 }
00137 
00138 void HDRShower::thetaFunction(int nthetaStep)
00139 {
00140   unsigned int i = 0; while( EgridTable[i]<e && i<NEnergyScan-1) { i++; }
00141 
00142   float amean, asig, lambda1, lambda1sig,lam21,lam21sig; 
00143   amean = Theta1amp[i]; asig = Theta1ampSig[i];
00144   lambda1 = Theta1Lambda[i]; lambda1sig = Theta1LambdaSig[i]; 
00145   lam21 = ThetaLam21[i]; lam21sig = ThetaLam21Sig[i];
00146   if(i==0) i=1;  //extrapolation to the left
00147   float c = (e-EgridTable[i-1])/(EgridTable[i]-EgridTable[i-1]);
00148 
00149   amean += (Theta1amp[i]-Theta1amp[i-1]) * c;
00150   asig += (Theta1ampSig[i]-Theta1ampSig[i-1]) * c;
00151   lambda1 +=(Theta1Lambda[i]-Theta1Lambda[i-1])  * c;
00152   lambda1sig += (Theta1LambdaSig[i]-Theta1LambdaSig[i-1]) * c;
00153   lam21 += (ThetaLam21[i]-ThetaLam21[i-1]) * c;
00154   lam21sig += (ThetaLam21Sig[i]-ThetaLam21Sig[i-1]) * c;
00155 
00156   float a = exp(amean + asig*random->gaussShoot());
00157   float L1 = lambda1 + lambda1sig*random->gaussShoot();
00158   if(L1 < 0.02) L1 = 0.02;
00159   float L2 = L1*(lam21 + lam21sig*random->gaussShoot());
00160 
00161   vector<double> pdf;
00162   pdf.erase(pdf.begin(),pdf.end());
00163   thetaSpots.erase(thetaSpots.begin(),thetaSpots.end());
00164   elastspot.erase(elastspot.begin(),elastspot.end());
00165   double sum = 0;
00166   for(int it=0; it<nthetaStep; it++) {
00167     float theta = it*thetaStep;
00168     float p = a*exp(L1*theta) + exp(L2*theta);
00169     sum += p;
00170     pdf.push_back(p);
00171   }
00172   float ntot = e/eHDspot;
00173   float esum=0;
00174   for(int it=0; it<nthetaStep; it++) {
00175     float fn = ntot*pdf[it]/sum;
00176     thetaSpots.push_back(int(fn));
00177     elastspot.push_back((fn - int(fn))*eHDspot);
00178   }
00179 
00180   for(int it=0; it<nthetaStep; it++)
00181     if(elastspot[it] <EsCut) {
00182       esum += elastspot[it]; elastspot[it] = 0; }
00183 
00184   float en = esum/EsCut; int n = int(en); 
00185   en = esum - n*EsCut;
00186 
00187   for(int ie=0; ie<=n; ie++) {
00188     int k = int(nthetaStep*random->flatShoot());
00189     if(k<0 || k>nthetaStep-1) k = k%nthetaStep;
00190     if(ie == n) elastspot[k] += en;
00191     else elastspot[k] += EsCut;
00192   }
00193 }
00194 
00195 void HDRShower::setFuncParam()
00196 {
00197   lambdaHD = theParam->hcalProperties()->interactionLength();
00198   x0HD     = theParam->hcalProperties()->radLenIncm();
00199   if(onEcal)
00200     lambdaEM = theParam->ecalProperties()->interactionLength();
00201   else lambdaEM = lambdaHD;
00202 
00203   if(debug)
00204     LogDebug("FastCalorimetry") <<"setFuncParam-> lambdaEM="<<lambdaEM<<" lambdaHD="<<lambdaHD<<endl; 
00205 
00206   float _EgridTable[NEnergyScan] = { 10, 20, 30, 50, 100, 300, 500 };
00207   float _Theta1amp[NEnergyScan] = { 1.57, 2.05, 2.27, 2.52, 2.66, 2.76, 2.76};
00208   float _Theta1ampSig[NEnergyScan]={2.40, 1.50, 1.25, 1.0,  0.8,  0.52, 0.52};
00209  
00210   float _Theta1Lambda[NEnergyScan] = { 
00211    0.086, 0.092, 0.88, 0.80, 0.0713, 0.0536, 0.0536 };
00212   float _Theta1LambdaSig[NEnergyScan] = { 
00213     0.038, 0.037, 0.027,0.03, 0.023,  0.018, 0.018 };
00214 
00215   float _ThetaLam21[NEnergyScan] =  { 2.8, 2.44, 2.6, 2.77, 3.16, 3.56, 3.56 };
00216   float _ThetaLam21Sig[NEnergyScan]={ 1.8, 0.97, 0.87, 0.77, 0.7, 0.49, 0.49 };
00217 
00218   for(int i=0; i<NEnergyScan; i++) {
00219     EgridTable[i]   = _EgridTable[i];
00220     Theta1amp[i]    = _Theta1amp[i];
00221     Theta1ampSig[i] = _Theta1ampSig[i];
00222     Theta1Lambda[i] = _Theta1Lambda[i];
00223     Theta1LambdaSig[i] = _Theta1LambdaSig[i];
00224     ThetaLam21[i]   = _ThetaLam21[i];
00225     ThetaLam21Sig[i]= _ThetaLam21Sig[i];
00226   }
00227 
00228 #define lambdafit 15.05
00229   float R_alfa = -0.0993 + 0.1114*log(e);
00230   float R_p = 0.589191 + 0.0463392 *log(e);
00231   float R_beta_lam=(0.54134 -0.00011148*e)/4.0*lambdafit;//was fitted in 4cmbin
00232   float LamOverX0 = lambdaHD/x0HD; // 10.52
00233   //  int R_range = 100; // 7 lambda
00234   //  rpdf.erase(rpdf.begin(),rpdf.end());
00235 
00236   rpdf[0] = 0.;  
00237   for(int i=1; i<R_range; i++) {
00238     float x = (float(i))/lambdaHD;
00239     float r = pow(x,R_alfa)*
00240       (R_p*exp(-R_beta_lam*x) + (1-R_p)*exp(-LamOverX0*R_beta_lam*x));
00241     rpdf[i] = r;
00242     //    rpdf.push_back(r);
00243   }
00244 
00245   for(int i=1; i<R_range; i++) rpdf[i] += rpdf[i-1];
00246   for(int i=0; i<R_range; i++) rpdf[i] /= rpdf[R_range -1];
00247 }