Go to the documentation of this file.00001
00002 #include "FastSimulation/ShowerDevelopment/interface/HDShower.h"
00003
00004 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00005
00006
00008
00009
00010
00011 #include "FastSimulation/CaloHitMakers/interface/EcalHitMaker.h"
00012 #include "FastSimulation/CaloHitMakers/interface/HcalHitMaker.h"
00013
00014
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016
00018
00019
00020
00021 #include <cmath>
00022
00023
00024 #define infinity 10000
00025
00026 #define debug 0
00027
00028 using namespace edm;
00029
00030 HDShower::HDShower(const RandomEngine* engine,
00031 HDShowerParametrization* myParam,
00032 EcalHitMaker* myGrid,
00033 HcalHitMaker* myHcalHitMaker,
00034 int onECAL,
00035 double epart)
00036 : theParam(myParam),
00037 theGrid(myGrid),
00038 theHcalHitMaker(myHcalHitMaker),
00039 onEcal(onECAL),
00040 e(epart),
00041 random(engine)
00042 {
00043
00044
00045
00046
00047 lossesOpt = myParam->hsParameters()->getHDlossesOpt();
00048 nDepthSteps = myParam->hsParameters()->getHDnDepthSteps();
00049 nTRsteps = myParam->hsParameters()->getHDnTRsteps();
00050 transParam = myParam->hsParameters()->getHDtransParam();
00051 eSpotSize = myParam->hsParameters()->getHDeSpotSize();
00052 depthStep = myParam->hsParameters()->getHDdepthStep();
00053 criticalEnergy = myParam->hsParameters()->getHDcriticalEnergy();
00054 maxTRfactor = myParam->hsParameters()->getHDmaxTRfactor();
00055 balanceEH = myParam->hsParameters()->getHDbalanceEH();
00056 hcalDepthFactor = myParam->hsParameters()->getHDhcalDepthFactor();
00057
00058
00059 transParam *= (1. + random->flatShoot());
00060
00061
00062 hcalDepthFactor += 0.05 * (2.* random->flatShoot() - 1.);
00063
00064 transFactor = 1.;
00065
00066
00067
00068
00069 if(e < 0) e = 0.;
00070
00071
00072
00073
00074
00075 theECALproperties = theParam->ecalProperties();
00076 theHCALproperties = theParam->hcalProperties();
00077
00078 double emax = theParam->emax();
00079 double emid = theParam->emid();
00080 double emin = theParam->emin();
00081 double effective = e;
00082
00083
00084 if( e < emid ) {
00085 theParam->setCase(1);
00086
00087 if(e < emin) effective = emin;
00088 }
00089 else
00090 theParam->setCase(2);
00091
00092
00093 if(effective > 0.5 * emax) {
00094 eSpotSize *= 2.5;
00095 if(effective > emax) {
00096 effective = emax;
00097 eSpotSize *= 4.;
00098 depthStep *= 2.;
00099 if(effective > 1000.)
00100 eSpotSize *= 2.;
00101 }
00102 }
00103
00104
00105 if(debug == 2 )
00106 LogDebug("FastCalorimetry") << " HDShower : " << std::endl
00107 << " Energy " << e << std::endl
00108 << " lossesOpt " << lossesOpt << std::endl
00109 << " nDepthSteps " << nDepthSteps << std::endl
00110 << " nTRsteps " << nTRsteps << std::endl
00111 << " transParam " << transParam << std::endl
00112 << " eSpotSize " << eSpotSize << std::endl
00113 << " criticalEnergy " << criticalEnergy << std::endl
00114 << " maxTRfactor " << maxTRfactor << std::endl
00115 << " balanceEH " << balanceEH << std::endl
00116 << "hcalDepthFactor " << hcalDepthFactor << std::endl;
00117
00118
00119 double alpEM1 = theParam->alpe1();
00120 double alpEM2 = theParam->alpe2();
00121
00122 double betEM1 = theParam->bete1();
00123 double betEM2 = theParam->bete2();
00124
00125 double alpHD1 = theParam->alph1();
00126 double alpHD2 = theParam->alph2();
00127
00128 double betHD1 = theParam->beth1();
00129 double betHD2 = theParam->beth2();
00130
00131 double part1 = theParam->part1();
00132 double part2 = theParam->part2();
00133
00134 aloge = std::log(effective);
00135
00136 double edpar = (theParam->e1() + aloge * theParam->e2()) * effective;
00137 double aedep = std::log(edpar);
00138
00139 if(debug == 2)
00140 LogDebug("FastCalorimetry") << " HDShower : " << std::endl
00141 << " edpar " << edpar << " aedep " << aedep << std::endl
00142 << " alpEM1 " << alpEM1 << std::endl
00143 << " alpEM2 " << alpEM2 << std::endl
00144 << " betEM1 " << betEM1 << std::endl
00145 << " betEM2 " << betEM2 << std::endl
00146 << " alpHD1 " << alpHD1 << std::endl
00147 << " alpHD2 " << alpHD2 << std::endl
00148 << " betHD1 " << betHD1 << std::endl
00149 << " betHD2 " << betHD2 << std::endl
00150 << " part1 " << part1 << std::endl
00151 << " part2 " << part2 << std::endl;
00152
00153
00154 theR1 = theParam->r1();
00155 theR2 = theParam->r2();
00156 theR3 = theParam->r3();
00157
00158 alpEM = alpEM1 + alpEM2 * aedep;
00159 tgamEM = tgamma(alpEM);
00160 betEM = betEM1 - betEM2 * aedep;
00161 alpHD = alpHD1 + alpHD2 * aedep;
00162 tgamHD = tgamma(alpHD);
00163 betHD = betHD1 - betHD2 * aedep;
00164 part = part1 - part2 * aedep;
00165 if(part > 1.) part = 1.;
00166
00167 if(debug == 2 )
00168 LogDebug("FastCalorimetry") << " HDShower : " << std::endl
00169 << " alpEM " << alpEM << std::endl
00170 << " tgamEM " << tgamEM << std::endl
00171 << " betEM " << betEM << std::endl
00172 << " alpHD " << alpHD << std::endl
00173 << " tgamHD " << tgamHD << std::endl
00174 << " betHD " << betHD << std::endl
00175 << " part " << part << std::endl;
00176
00177
00178 if(onECAL){
00179 lambdaEM = theParam->ecalProperties()->interactionLength();
00180 x0EM = theParam->ecalProperties()->radLenIncm();
00181 }
00182 else {
00183 lambdaEM = 0.;
00184 x0EM = 0.;
00185 }
00186 lambdaHD = theParam->hcalProperties()->interactionLength();
00187 x0HD = theParam->hcalProperties()->radLenIncm();
00188
00189 if(debug == 2)
00190 LogDebug("FastCalorimetry") << " HDShower e " << e << std::endl
00191 << " x0EM = " << x0EM << std::endl
00192 << " x0HD = " << x0HD << std::endl
00193 << " lamEM = " << lambdaEM << std::endl
00194 << " lamHD = " << lambdaHD << std::endl;
00195
00196
00197
00198
00199
00200 double sum1 = 0.;
00201 double sum2 = 0.;
00202 double sum3 = 0.;
00203 int nsteps = 0;
00204
00205 int nmoresteps;
00206
00207
00208 mip = 1;
00209
00210 if(e < criticalEnergy ) nmoresteps = 1;
00211 else nmoresteps = nDepthSteps;
00212
00213 double depthECAL = 0.;
00214 double depthGAP = 0.;
00215 double depthGAPx0 = 0.;
00216 if(onECAL ) {
00217 depthECAL = theGrid->ecalTotalL0();
00218 depthGAP = theGrid->ecalHcalGapTotalL0();
00219 depthGAPx0 = theGrid->ecalHcalGapTotalX0();
00220 }
00221
00222 double depthHCAL = theGrid->hcalTotalL0();
00223 double depthToHCAL = depthECAL + depthGAP;
00224
00225
00226
00227
00228
00229 double maxDepth = depthToHCAL + depthHCAL - 1.1 * depthStep;
00230 double depthStart = std::log(1./random->flatShoot());
00231
00232 if(e < emin) {
00233 if(debug)
00234 LogDebug("FastCalorimetry") << " FamosHDShower : e <emin -> depthStart = 0" << std::endl;
00235 depthStart = 0.;
00236 }
00237
00238 if(depthStart > maxDepth) {
00239 if(debug) LogDebug("FastCalorimetry") << " FamosHDShower : depthStart too big ... = "
00240 << depthStart << std::endl;
00241
00242 depthStart = maxDepth * random->flatShoot();
00243 if( depthStart < 0.) depthStart = 0.;
00244 if(debug) LogDebug("FastCalorimetry") << " FamosHDShower : depthStart re-calculated = "
00245 << depthStart << std::endl;
00246 }
00247
00248 if( onECAL && e < emid ) {
00249 if(depthECAL > depthStep && (depthECAL - depthStart)/depthECAL > 0.2) {
00250
00251 depthStart = 0.5 * depthECAL * random->flatShoot();
00252 if(debug)
00253 LogDebug("FastCalorimetry") << " FamosHDShower : small energy, "
00254 << " depthStart reduced to = " << depthStart << std::endl;
00255
00256 }
00257 }
00258
00259 if( depthHCAL < depthStep) {
00260 if(debug) LogDebug("FastCalorimetry") << " FamosHDShower : depthHCAL too small ... = "
00261 << depthHCAL << " depthStart -> forced to 0 !!!"
00262 << std::endl;
00263 depthStart = 0.;
00264 nmoresteps = 0;
00265
00266 if(depthECAL < depthStep) {
00267 nsteps = -1;
00268 LogInfo("FastCalorimetry") << " FamosHDShower : too small ECAL and HCAL depths - "
00269 << " particle is lost !!! " << std::endl;
00270 }
00271 }
00272
00273
00274
00275 if(debug)
00276 LogDebug("FastCalorimetry") << " FamosHDShower depths(lam) - " << std::endl
00277 << " ECAL = " << depthECAL << std::endl
00278 << " GAP = " << depthGAP << std::endl
00279 << " HCAL = " << depthHCAL << std::endl
00280 << " starting point = " << depthStart << std::endl;
00281
00282 if( onEcal ) {
00283 if(debug) LogDebug("FastCalorimetry") << " FamosHDShower : onECAL" << std::endl;
00284 if(depthStart < depthECAL) {
00285 if(debug) LogDebug("FastCalorimetry") << " FamosHDShower : depthStart < depthECAL" << std::endl;
00286 if(depthECAL > depthStep && (depthECAL - depthStart)/depthECAL > 0.1) {
00287 if(debug) LogDebug("FastCalorimetry") << " FamosHDShower : enough space to make ECAL step"
00288 << std::endl;
00289
00290 nsteps++;
00291 sum1 += depthECAL;
00292 sum2 += depthECAL-depthStart;
00293 sum3 += sum2 * lambdaEM / x0EM;
00294 lamtotal.push_back(sum1);
00295 lamdepth.push_back(sum2);
00296 lamcurr.push_back(lambdaEM);
00297 lamstep.push_back(depthECAL-depthStart);
00298 x0depth.push_back(sum3);
00299 x0curr.push_back(x0EM);
00300 detector.push_back(1);
00301 mip = 0;
00302
00303 if(debug) LogDebug("FastCalorimetry") << " FamosHDShower : " << " in ECAL sum1, sum2 "
00304 << sum1 << " " << sum2 << std::endl;
00305
00306
00307
00308 sum1 += depthGAP;
00309 sum2 += depthGAP;
00310 sum3 += depthGAPx0;
00311 }
00312
00313 else {
00314
00315 if(debug) LogDebug("FastCalorimetry") << " FamosHDShower : goto HCAL" << std::endl;
00316
00317 depthStart = depthToHCAL;
00318 sum1 += depthStart;
00319 }
00320 }
00321 else {
00322
00323 if(depthStart >= depthECAL && depthStart < depthToHCAL ) {
00324 depthStart = depthToHCAL;
00325 }
00326 sum1 += depthStart;
00327
00328 if(debug) LogDebug("FastCalorimetry") << " FamosHDShower : goto HCAL" << std::endl;
00329 }
00330 }
00331 else {
00332 if(debug) LogDebug("FastCalorimetry") << " FamosHDShower : forward" << std::endl;
00333 sum1 += depthStart;
00334 transFactor = 0.5;
00335 }
00336
00337 for (int i = 0; i < nmoresteps ; i++) {
00338 sum1 += depthStep;
00339 if (sum1 > (depthECAL + depthGAP + depthHCAL)) break;
00340 sum2 += depthStep;
00341 sum3 += sum2 * lambdaHD / x0HD;
00342 lamtotal.push_back(sum1);
00343 lamdepth.push_back(sum2);
00344 lamcurr.push_back(lambdaHD);
00345 lamstep.push_back(depthStep);
00346 x0depth.push_back(sum3);
00347 x0curr.push_back(x0HD);
00348 detector.push_back(3);
00349 nsteps++;
00350 }
00351
00352
00353
00354
00355 if(nsteps > 0) { makeSteps(nsteps); }
00356
00357 }
00358
00359 void HDShower::makeSteps(int nsteps) {
00360
00361 double sumes = 0.;
00362 double sum = 0.;
00363 std::vector<double> temp;
00364
00365
00366 if(debug)
00367 LogDebug("FastCalorimetry") << " FamosHDShower::makeSteps - "
00368 << " nsteps required : " << nsteps << std::endl;
00369
00370 int count = 0;
00371 for (int i = 0; i < nsteps; i++) {
00372
00373 double deplam = lamdepth[i] - 0.5 * lamstep[i];
00374 double depx0 = x0depth[i] - 0.5 * lamstep[i] / x0curr[i];
00375 double x = betEM * depx0;
00376 double y = betHD * deplam;
00377
00378 if(debug == 2)
00379 LogDebug("FastCalorimetry") << " FamosHDShower::makeSteps "
00380 << " - step " << i
00381 << " depx0, x = " << depx0 << ", " << x
00382 << " deplam, y = " << deplam << ", "
00383 << y << std::endl;
00384
00385 double est = (part * betEM * gam(x,alpEM) * lamcurr[i] /
00386 (x0curr[i] * tgamEM) +
00387 (1.-part) * betHD * gam(y,alpHD) / tgamHD) * lamstep[i];
00388
00389
00390 if(est < 0.) {
00391 LogDebug("FastCalorimetry") << "*** FamosHDShower::makeSteps " << " - negative step energy !!!"
00392 << std::endl;
00393 est = 0.;
00394 break ;
00395 }
00396
00397
00398 sum += est;
00399 int nPest = (int) (est * e / sum / eSpotSize) ;
00400
00401 if(debug == 2)
00402 LogDebug("FastCalorimetry") << " FamosHDShower::makeSteps - nPoints estimate = "
00403 << nPest << std::endl;
00404
00405 if(nPest <= 1 && count !=0 ) break;
00406
00407
00408
00409 temp.push_back(est);
00410 sumes += est;
00411
00412 rlamStep.push_back(transParam * (theR1 + (theR2 - theR3 * aloge))
00413 * deplam * transFactor);
00414 count ++;
00415 }
00416
00417
00418 if(detector[0] == 1 && count > 1) {
00419 double oldECALenergy = temp[0];
00420 double oldHCALenergy = sumes - oldECALenergy ;
00421 double newECALenergy = 2. * sumes;
00422 for (int i = 0; newECALenergy > sumes && i < infinity; i++)
00423 newECALenergy = 2.* balanceEH * random->flatShoot() * oldECALenergy;
00424
00425 if(debug == 2)
00426 LogDebug("FastCalorimetry") << "*** FamosHDShower::makeSteps " << " ECAL fraction : old/new - "
00427 << oldECALenergy/sumes << "/" << newECALenergy/sumes << std::endl;
00428
00429 temp[0] = newECALenergy;
00430 double newHCALenergy = sumes - newECALenergy;
00431 double newHCALreweight = newHCALenergy / oldHCALenergy;
00432
00433 for (int i = 1; i < count; i++) {
00434 temp[i] *= newHCALreweight;
00435 }
00436
00437 }
00438
00439
00440
00441 for (int i = 0; i < count ; i++) {
00442 eStep.push_back(temp[i] * e / sumes );
00443 nspots.push_back((int)(eStep[i]/eSpotSize)+1);
00444
00445 if(debug)
00446 LogDebug("FastCalorimetry")
00447 << " step " << i
00448 << " det: " << detector[i]
00449 << " xO and lamdepth at the end of step = "
00450 << x0depth[i] << " "
00451 << lamdepth[i] << " Estep func = " << eStep[i]
00452 << " Rstep = " << rlamStep[i] << " Nspots = " << nspots[i]
00453 << " espot = " << eStep[i] / (double)nspots[i]
00454 << std::endl;
00455
00456 }
00457
00458
00459
00460 if(count == 1 and detector[0] == 1) rlamStep[0] *= 2.;
00461
00462
00463 if(debug) {
00464 if(eStep[0] > 0.95 * e && detector[0] == 1)
00465 LogDebug("FastCalorimetry") << " FamosHDShower::makeSteps - " << "ECAL energy = " << eStep[0]
00466 << " out of total = " << e << std::endl;
00467 }
00468
00469 }
00470
00471 bool HDShower::compute() {
00472
00473
00474
00475 bool status = false;
00476 int numLongit = eStep.size();
00477 if(debug)
00478 LogDebug("FastCalorimetry") << " FamosHDShower::compute - "
00479 << " N_long.steps required : " << numLongit << std::endl;
00480
00481 if(numLongit > 0) {
00482
00483 status = true;
00484
00485 std::vector<double> Fhist;
00486 std::vector<double> rhist;
00487 for (int j = 0; j < nTRsteps + 1; j++) {
00488 rhist.push_back(maxTRfactor * j / nTRsteps );
00489 Fhist.push_back(transProb(maxTRfactor,1.,rhist[j]));
00490 if(debug == 3)
00491 LogDebug("FastCalorimetry") << "indexFinder - i, Fhist[i] = " << j << " " << Fhist[j] << std::endl;
00492 }
00493
00494
00495 for (int i = 0; i < numLongit ; i++) {
00496
00497 double currentDepthL0 = lamtotal[i] - 0.5 * lamstep[i];
00498
00499 if(detector[i] != 1) currentDepthL0 *= hcalDepthFactor;
00500 if(debug)
00501 LogDebug("FastCalorimetry") << " FamosHDShower::compute - detector = "
00502 << detector[i]
00503 << " currentDepthL0 = "
00504 << currentDepthL0 << std::endl;
00505
00506 double maxTRsize = maxTRfactor * rlamStep[i];
00507 double rbinsize = maxTRsize / nTRsteps;
00508 double espot = eStep[i] / (double)nspots[i];
00509
00510 if(espot > 2. || espot < 0. )
00511 LogDebug("FastCalorimetry") << " FamosHDShower::compute - unphysical espot = "
00512 << espot << std::endl;
00513
00514 int ecal = 0;
00515 if(detector[i] != 1) {
00516 bool setHDdepth = theHcalHitMaker->setDepth(currentDepthL0);
00517
00518 if(debug)
00519 LogDebug("FastCalorimetry") << " FamosHDShower::compute - status of "
00520 << " theHcalHitMaker->setDepth(currentDepthL0) is "
00521 << setHDdepth << std::endl;
00522
00523 if(!setHDdepth)
00524 {
00525 currentDepthL0 -= lamstep[i];
00526 setHDdepth = theHcalHitMaker->setDepth(currentDepthL0);
00527 }
00528 if(!setHDdepth) continue;
00529
00530 theHcalHitMaker->setSpotEnergy(espot);
00531 }
00532 else {
00533 ecal = 1;
00534 bool status = theGrid->getPads(currentDepthL0);
00535
00536 if(debug)
00537 LogDebug("FastCalorimetry") << " FamosHDShower::compute - status of Grid = "
00538 << status << std::endl;
00539
00540 if(!status) continue;
00541
00542 int ntry = nspots[i] * 10;
00543 if( ntry >= infinity ) {
00544 nspots[i] = 0.5 * infinity;
00545 espot *= 0.1 * (double)ntry / double(nspots[i]);
00546 }
00547 else {
00548 espot *= 0.1;
00549
00550 nspots[i] = ntry;
00551 }
00552
00553
00554 theGrid->setSpotEnergy(espot);
00555 }
00556
00557
00558
00559 int nok = 0;
00560 int count = 0;
00561 int inf = infinity;
00562 if(lossesOpt) inf = nspots[i];
00563
00564 if(nspots[i] > inf ){
00565 std::cout << " FamosHDShower::compute - at long.step " << i
00566 << " too many spots required : " << nspots[i] << " !!! "
00567 << std::endl;
00568 }
00569
00570 for (int j = 0; j < inf; j++) {
00571 if(nok == nspots[i]) break;
00572 count ++;
00573
00574 double prob = random->flatShoot();
00575 int index = indexFinder(prob,Fhist);
00576 double radius = rlamStep[i] * rhist[index] +
00577 random->flatShoot() * rbinsize;
00578 double phi = 2.*M_PI*random->flatShoot();
00579
00580 if(debug == 2)
00581 LogDebug("FastCalorimetry") << std::endl << " FamosHDShower::compute " << " r = " << radius
00582 << " phi = " << phi << std::endl;
00583
00584 bool result;
00585 if(ecal) {
00586 result = theGrid->addHit(radius,phi,0);
00587
00588 if(debug == 2)
00589 LogDebug("FastCalorimetry") << " FamosHDShower::compute - "
00590 << " theGrid->addHit result = "
00591 << result << std::endl;
00592 }
00593 else {
00594 result = theHcalHitMaker->addHit(radius,phi,0);
00595
00596 if(debug == 2)
00597 LogDebug("FastCalorimetry") << " FamosHDShower::compute - "
00598 << " theHcalHitMaker->addHit result = "
00599 << result << std::endl;
00600 }
00601 if(result) nok ++;
00602
00603 }
00604 if(count == infinity) {
00605 if(debug)
00606 LogDebug("FastCalorimetry")
00607 << " FamosHDShower::compute " << " maximum number of"
00608 << " transverse points " << count << " is used !!!" << std::endl;
00609 }
00610
00611 if(debug)
00612 LogDebug("FastCalorimetry")
00613 << " FamosHDShower::compute " << " long.step No." << i
00614 << " Ntry, Nok = " << count
00615 << " " << nok << std::endl;
00616
00617 }
00618 }
00619
00620 return status;
00621
00622 }
00623
00624 int HDShower::indexFinder(double x, const std::vector<double> & Fhist) {
00625
00626 int size = Fhist.size();
00627
00628 int curr = size / 2;
00629 int step = size / 4;
00630 int iter;
00631 int prevdir = 0;
00632 int actudir = 0;
00633
00634 for (iter = 0; iter < size ; iter++) {
00635
00636 if( curr >= size || curr < 1 )
00637 LogWarning("FastCalorimetry") << " FamosHDShower::indexFinder - wrong current index = "
00638 << curr << " !!!" << std::endl;
00639
00640 if ((x <= Fhist[curr]) && (x > Fhist[curr-1])) break;
00641 prevdir = actudir;
00642 if(x > Fhist[curr]) {actudir = 1;}
00643 else {actudir = -1;}
00644 if(prevdir * actudir < 0) { if(step > 1) step /= 2;}
00645 curr += actudir * step;
00646 if(curr > size) curr = size;
00647 else { if(curr < 1) {curr = 1;}}
00648
00649 if(debug == 3)
00650 LogDebug("FastCalorimetry") << " indexFinder - end of iter." << iter
00651 << " curr, F[curr-1], F[curr] = "
00652 << curr << " " << Fhist[curr-1] << " " << Fhist[curr] << std::endl;
00653
00654 }
00655
00656 if(debug == 3)
00657 LogDebug("FastCalorimetry") << " indexFinder x = " << x << " found index = " << curr-1
00658 << std::endl;
00659
00660
00661 return curr-1;
00662 }