00001
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
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009
00010 using namespace edm;
00011
00013
00014
00015
00016
00017 #define infinity 5000
00018
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();
00051 depthGAP = theGrid->ecalHcalGapTotalL0();
00052 }
00053 else depthECAL = depthGAP = 0;
00054
00055 float depthHCAL = theGrid->hcalTotalL0();
00056
00057
00058 maxDepth = depthECAL + depthHCAL - 0.5;
00059 depthStart = log(1./random->flatShoot());
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
00073
00074
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;
00093 }
00094 }
00095 return(true);
00096 }
00097
00098 bool HDRShower::setHit(float espot, float theta) {
00099
00100 float phi = 2.*M_PI*random->flatShoot();
00101 float rshower = getR();
00102
00103 float d = depthStart + rshower*cos(theta);
00104 if(d + depthGAP > maxDepth) return(false);
00105
00106
00107
00108 bool result = 0;
00109 if( !onEcal || d>depthECAL || !qstatus) {
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
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;
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;
00232 float LamOverX0 = lambdaHD/x0HD;
00233
00234
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
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 }