File indexing completed on 2025-05-23 23:48:32
0001
0002
0003 #include "FastSimulation/ShowerDevelopment/interface/HDShower.h"
0004 #include "FastSimulation/Utilities/interface/RandomEngineAndDistribution.h"
0005
0006 #include "FastSimulation/CaloHitMakers/interface/EcalHitMaker.h"
0007 #include "FastSimulation/CaloHitMakers/interface/HcalHitMaker.h"
0008
0009
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011
0012 #include <cmath>
0013
0014
0015 #define infinity 10000
0016
0017 #define debug 0
0018
0019 using namespace edm;
0020
0021 HDShower::HDShower(const RandomEngineAndDistribution* engine,
0022 HDShowerParametrization* myParam,
0023 EcalHitMaker* myGrid,
0024 HcalHitMaker* myHcalHitMaker,
0025 int onECAL,
0026 double epart,
0027 double pmip)
0028 : theParam(myParam),
0029 theGrid(myGrid),
0030 theHcalHitMaker(myHcalHitMaker),
0031 onEcal(onECAL),
0032 e(epart),
0033
0034 random(engine) {
0035 init(engine, myParam, myGrid, myHcalHitMaker, onECAL, epart, pmip);
0036 }
0037
0038 void HDShower::init(const RandomEngineAndDistribution* engine,
0039 HDShowerParametrization* myParam,
0040 EcalHitMaker* myGrid,
0041 HcalHitMaker* myHcalHitMaker,
0042 int onECAL,
0043 double epart,
0044 double pmip) {
0045
0046
0047
0048
0049 lossesOpt = myParam->hsParameters()->getHDlossesOpt();
0050 nDepthSteps = myParam->hsParameters()->getHDnDepthSteps();
0051 nTRsteps = myParam->hsParameters()->getHDnTRsteps();
0052 transParam = myParam->hsParameters()->getHDtransParam();
0053 eSpotSize = myParam->hsParameters()->getHDeSpotSize();
0054 depthStep = myParam->hsParameters()->getHDdepthStep();
0055 criticalEnergy = myParam->hsParameters()->getHDcriticalEnergy();
0056 maxTRfactor = myParam->hsParameters()->getHDmaxTRfactor();
0057 balanceEH = myParam->hsParameters()->getHDbalanceEH();
0058 hcalDepthFactor = myParam->hsParameters()->getHDhcalDepthFactor();
0059
0060
0061 transParam *= (1. + random->flatShoot());
0062
0063
0064 hcalDepthFactor += 0.05 * (2. * random->flatShoot() - 1.);
0065
0066 transFactor = 1.;
0067
0068
0069
0070
0071 if (e < 0)
0072 e = 0.;
0073
0074
0075
0076
0077
0078 theECALproperties = theParam->ecalProperties();
0079 theHCALproperties = theParam->hcalProperties();
0080
0081 double emax = theParam->emax();
0082 double emid = theParam->emid();
0083 double emin = theParam->emin();
0084 double effective = e;
0085
0086 if (e < emid) {
0087 theParam->setCase(1);
0088
0089 if (e < emin)
0090 effective = emin;
0091 } else
0092 theParam->setCase(2);
0093
0094
0095 if (effective > 0.5 * emax) {
0096 eSpotSize *= 2.5;
0097 if (effective > emax) {
0098 effective = emax;
0099 eSpotSize *= 4.;
0100 depthStep *= 2.;
0101 if (effective > 1000.)
0102 eSpotSize *= 2.;
0103 }
0104 }
0105
0106 if (debug == 2)
0107 LogInfo("FastCalorimetry") << " HDShower : " << std::endl
0108 << " Energy " << e << std::endl
0109 << " lossesOpt " << lossesOpt << std::endl
0110 << " nDepthSteps " << nDepthSteps << std::endl
0111 << " nTRsteps " << nTRsteps << std::endl
0112 << " transParam " << transParam << std::endl
0113 << " eSpotSize " << eSpotSize << std::endl
0114 << " criticalEnergy " << criticalEnergy << std::endl
0115 << " maxTRfactor " << maxTRfactor << std::endl
0116 << " balanceEH " << balanceEH << std::endl
0117 << "hcalDepthFactor " << hcalDepthFactor << std::endl;
0118
0119 double alpEM1 = theParam->alpe1();
0120 double alpEM2 = theParam->alpe2();
0121
0122 double betEM1 = theParam->bete1();
0123 double betEM2 = theParam->bete2();
0124
0125 double alpHD1 = theParam->alph1();
0126 double alpHD2 = theParam->alph2();
0127
0128 double betHD1 = theParam->beth1();
0129 double betHD2 = theParam->beth2();
0130
0131 double part1 = theParam->part1();
0132 double part2 = theParam->part2();
0133
0134 aloge = std::log(effective);
0135
0136 double edpar = (theParam->e1() + aloge * theParam->e2()) * effective;
0137 double aedep = std::log(edpar);
0138
0139 if (debug == 2)
0140 LogInfo("FastCalorimetry") << " HDShower : " << std::endl
0141 << " edpar " << edpar << " aedep " << aedep << std::endl
0142 << " alpEM1 " << alpEM1 << std::endl
0143 << " alpEM2 " << alpEM2 << std::endl
0144 << " betEM1 " << betEM1 << std::endl
0145 << " betEM2 " << betEM2 << std::endl
0146 << " alpHD1 " << alpHD1 << std::endl
0147 << " alpHD2 " << alpHD2 << std::endl
0148 << " betHD1 " << betHD1 << std::endl
0149 << " betHD2 " << betHD2 << std::endl
0150 << " part1 " << part1 << std::endl
0151 << " part2 " << part2 << std::endl;
0152
0153
0154 theR1 = theParam->r1();
0155 theR2 = theParam->r2();
0156 theR3 = theParam->r3();
0157
0158 alpEM = alpEM1 + alpEM2 * aedep;
0159 tgamEM = tgamma(alpEM);
0160 betEM = betEM1 - betEM2 * aedep;
0161 alpHD = alpHD1 + alpHD2 * aedep;
0162 tgamHD = tgamma(alpHD);
0163 betHD = betHD1 - betHD2 * aedep;
0164 part = part1 - part2 * aedep;
0165 if (part > 1.)
0166 part = 1.;
0167
0168 if (debug == 2)
0169 LogInfo("FastCalorimetry") << " HDShower : " << std::endl
0170 << " alpEM " << alpEM << std::endl
0171 << " tgamEM " << tgamEM << std::endl
0172 << " betEM " << betEM << std::endl
0173 << " alpHD " << alpHD << std::endl
0174 << " tgamHD " << tgamHD << std::endl
0175 << " betHD " << betHD << std::endl
0176 << " part " << part << std::endl;
0177
0178 if (onECAL) {
0179 lambdaEM = theParam->ecalProperties()->interactionLength();
0180 x0EM = theParam->ecalProperties()->radLenIncm();
0181 } else {
0182 lambdaEM = 0.;
0183 x0EM = 0.;
0184 }
0185 lambdaHD = theParam->hcalProperties()->interactionLength();
0186 x0HD = theParam->hcalProperties()->radLenIncm();
0187
0188 if (debug == 2)
0189 LogInfo("FastCalorimetry") << " HDShower e " << e << std::endl
0190 << " x0EM = " << x0EM << std::endl
0191 << " x0HD = " << x0HD << std::endl
0192 << " lamEM = " << lambdaEM << std::endl
0193 << " lamHD = " << lambdaHD << std::endl;
0194
0195
0196
0197
0198 double sum1 = 0.;
0199 double sum2 = 0.;
0200 double sum3 = 0.;
0201 int nsteps = 0;
0202
0203 int nmoresteps;
0204
0205
0206 mip = 1;
0207
0208 if (e < criticalEnergy)
0209 nmoresteps = 1;
0210 else
0211 nmoresteps = nDepthSteps;
0212
0213 depthECAL = 0.;
0214 depthGAP = 0.;
0215 depthGAPx0 = 0.;
0216 if (onECAL) {
0217 depthECAL = theGrid->ecalTotalL0();
0218
0219 depthGAP = theGrid->ecalHcalGapTotalL0();
0220 depthGAPx0 = theGrid->ecalHcalGapTotalX0();
0221 }
0222
0223 depthHCAL = theGrid->hcalTotalL0();
0224 depthToHCAL = depthECAL + depthGAP;
0225
0226
0227
0228
0229
0230 double maxDepth = depthToHCAL + depthHCAL - 1.1 * depthStep;
0231 double depthStart = std::log(1. / random->flatShoot());
0232
0233 if (pmip == 1) {
0234 depthStart = depthToHCAL;
0235 } else {
0236 depthStart = depthStart * 0.9 * depthECAL / std::log(1. / pmip);
0237 }
0238
0239
0240 if (e < emin) {
0241 if (debug)
0242 LogInfo("FastCalorimetry") << " FamosHDShower : e <emin -> depthStart = 0" << std::endl;
0243 depthStart = 0.;
0244 }
0245
0246 if (depthStart > maxDepth) {
0247 if (debug)
0248 LogInfo("FastCalorimetry") << " FamosHDShower : depthStart too big ... = " << depthStart << std::endl;
0249 depthStart = maxDepth * random->flatShoot();
0250 if (depthStart < 0.)
0251 depthStart = 0.;
0252 if (debug)
0253 LogInfo("FastCalorimetry") << " FamosHDShower : depthStart re-calculated = " << depthStart << std::endl;
0254 }
0255
0256 if (onECAL && e < emid) {
0257 if (depthECAL > depthStep && (depthECAL - depthStart) / depthECAL > 0.2) {
0258 depthStart = 0.5 * depthECAL * random->flatShoot();
0259 if (debug)
0260 LogInfo("FastCalorimetry") << " FamosHDShower : small energy, "
0261 << " depthStart reduced to = " << depthStart << std::endl;
0262 }
0263 }
0264
0265 if (depthHCAL < depthStep) {
0266 if (debug)
0267 LogInfo("FastCalorimetry") << " FamosHDShower : depthHCAL too small ... = " << depthHCAL
0268 << " depthStart -> forced to 0 !!!" << std::endl;
0269 depthStart = 0.;
0270 nmoresteps = 0;
0271
0272 if (depthECAL < depthStep) {
0273 nsteps = -1;
0274 LogInfo("FastCalorimetry") << " FamosHDShower : too small ECAL and HCAL depths - "
0275 << " particle is lost !!! " << std::endl;
0276 }
0277 }
0278
0279 if (debug)
0280 LogInfo("FastCalorimetry") << " FamosHDShower depths(lam) - " << std::endl
0281 << " ECAL = " << depthECAL << std::endl
0282 << " GAP = " << depthGAP << std::endl
0283 << " HCAL = " << depthHCAL << std::endl
0284 << " starting point = " << depthStart << std::endl;
0285
0286 if (onEcal) {
0287 if (debug)
0288 LogInfo("FastCalorimetry") << " FamosHDShower : onECAL" << std::endl;
0289 if (depthStart < depthECAL) {
0290 if (debug)
0291 LogInfo("FastCalorimetry") << " FamosHDShower : depthStart < depthECAL" << std::endl;
0292 if (depthECAL > depthStep && (depthECAL - depthStart) / depthECAL > 0.1) {
0293 if (debug)
0294 LogInfo("FastCalorimetry") << " FamosHDShower : enough space to make ECAL step" << std::endl;
0295
0296
0297 nsteps++;
0298 sum1 += depthECAL;
0299 sum2 += depthECAL - depthStart;
0300 sum3 += sum2 * lambdaEM / x0EM;
0301 lamtotal.push_back(sum1);
0302 lamdepth.push_back(sum2);
0303 lamcurr.push_back(lambdaEM);
0304 lamstep.push_back(depthECAL - depthStart);
0305 x0depth.push_back(sum3);
0306 x0curr.push_back(x0EM);
0307 detector.push_back(1);
0308 mip = 0;
0309
0310 if (debug)
0311 LogInfo("FastCalorimetry") << " FamosHDShower : "
0312 << " in ECAL sum1, sum2 " << sum1 << " " << sum2 << std::endl;
0313
0314
0315
0316 sum1 += depthGAP;
0317 sum2 += depthGAP;
0318 sum3 += depthGAPx0;
0319 } else {
0320
0321 if (debug)
0322 LogInfo("FastCalorimetry") << " FamosHDShower : goto HCAL" << std::endl;
0323
0324 depthStart = depthToHCAL;
0325 sum1 += depthStart;
0326 }
0327 } else {
0328 if (depthStart >= depthECAL && depthStart < depthToHCAL) {
0329 depthStart = depthToHCAL;
0330 }
0331 sum1 += depthStart;
0332 if (debug)
0333 LogInfo("FastCalorimetry") << " FamosHDShower : goto HCAL" << std::endl;
0334 }
0335 } else {
0336 if (debug)
0337 LogInfo("FastCalorimetry") << " FamosHDShower : forward" << std::endl;
0338 sum1 += depthStart;
0339 transFactor = 0.5;
0340 }
0341
0342 for (int i = 0; i < nmoresteps; i++) {
0343 sum1 += depthStep;
0344 if (sum1 > (depthECAL + depthGAP + depthHCAL))
0345 break;
0346 sum2 += depthStep;
0347 sum3 += sum2 * lambdaHD / x0HD;
0348 lamtotal.push_back(sum1);
0349 lamdepth.push_back(sum2);
0350 lamcurr.push_back(lambdaHD);
0351 lamstep.push_back(depthStep);
0352 x0depth.push_back(sum3);
0353 x0curr.push_back(x0HD);
0354 detector.push_back(3);
0355 nsteps++;
0356 }
0357
0358
0359
0360 if (nsteps > 0) {
0361 makeSteps(nsteps);
0362 }
0363 }
0364
0365 void HDShower::makeSteps(int nsteps) {
0366 double sumes = 0.;
0367 double sum = 0.;
0368 std::vector<double> temp;
0369
0370 if (debug)
0371 LogInfo("FastCalorimetry") << " FamosHDShower::makeSteps - "
0372 << " nsteps required : " << nsteps << std::endl;
0373
0374 int count = 0;
0375 for (int i = 0; i < nsteps; i++) {
0376 double deplam = lamdepth[i] - 0.5 * lamstep[i];
0377 double depx0 = x0depth[i] - 0.5 * lamstep[i] / x0curr[i];
0378 double x = betEM * depx0;
0379 double y = betHD * deplam;
0380
0381 if (debug == 2)
0382 LogInfo("FastCalorimetry") << " FamosHDShower::makeSteps "
0383 << " - step " << i << " depx0, x = " << depx0 << ", " << x
0384 << " deplam, y = " << deplam << ", " << y << std::endl;
0385
0386 double est = (part * betEM * gam(x, alpEM) * lamcurr[i] / (x0curr[i] * tgamEM) +
0387 (1. - part) * betHD * gam(y, alpHD) / tgamHD) *
0388 lamstep[i];
0389
0390
0391 if (est < 0.) {
0392 LogInfo("FastCalorimetry") << "*** FamosHDShower::makeSteps "
0393 << " - negative step energy !!!" << std::endl;
0394 break;
0395 }
0396
0397
0398 sum += est;
0399 int nPest = (int)(est * e / sum / eSpotSize);
0400
0401 if (debug == 2)
0402 LogInfo("FastCalorimetry") << " FamosHDShower::makeSteps - nPoints estimate = " << nPest << std::endl;
0403
0404 if (nPest <= 1 && count != 0)
0405 break;
0406
0407
0408
0409 temp.push_back(est);
0410 sumes += est;
0411
0412 rlamStep.push_back(transParam * (theR1 + (theR2 - theR3 * aloge)) * deplam * transFactor);
0413 count++;
0414 }
0415
0416
0417 if (detector[0] == 1 && count > 1) {
0418 double oldECALenergy = temp[0];
0419 double oldHCALenergy = sumes - oldECALenergy;
0420 double newECALenergy = 2. * sumes;
0421 for (int i = 0; newECALenergy > sumes && i < infinity; i++)
0422 newECALenergy = 2. * balanceEH * random->flatShoot() * oldECALenergy;
0423
0424 if (debug == 2)
0425 LogInfo("FastCalorimetry") << "*** FamosHDShower::makeSteps "
0426 << " ECAL fraction : old/new - " << oldECALenergy / sumes << "/"
0427 << newECALenergy / sumes << std::endl;
0428
0429 temp[0] = newECALenergy;
0430 double newHCALenergy = sumes - newECALenergy;
0431 double newHCALreweight = newHCALenergy / oldHCALenergy;
0432
0433 for (int i = 1; i < count; i++) {
0434 temp[i] *= newHCALreweight;
0435 }
0436 }
0437
0438
0439 for (int i = 0; i < count; i++) {
0440 eStep.push_back(temp[i] * e / sumes);
0441 nspots.push_back((int)(eStep[i] / eSpotSize) + 1);
0442
0443 if (debug)
0444 LogInfo("FastCalorimetry") << " step " << i << " det: " << detector[i]
0445 << " xO and lamdepth at the end of step = " << x0depth[i] << " " << lamdepth[i]
0446 << " Estep func = " << eStep[i] << " Rstep = " << rlamStep[i]
0447 << " Nspots = " << nspots[i] << " espot = " << eStep[i] / (double)nspots[i]
0448 << std::endl;
0449 }
0450
0451
0452 if (count == 1 and detector[0] == 1)
0453 rlamStep[0] *= 2.;
0454
0455 if (debug) {
0456 if (eStep[0] > 0.95 * e && detector[0] == 1)
0457 LogInfo("FastCalorimetry") << " FamosHDShower::makeSteps - "
0458 << "ECAL energy = " << eStep[0] << " out of total = " << e << std::endl;
0459 }
0460 }
0461
0462 bool HDShower::compute() {
0463
0464
0465 bool status = false;
0466 int numLongit = eStep.size();
0467 if (debug)
0468 LogInfo("FastCalorimetry") << " FamosHDShower::compute - "
0469 << " N_long.steps required : " << numLongit << std::endl;
0470
0471 if (numLongit > 0) {
0472 status = true;
0473
0474 std::vector<double> Fhist;
0475 std::vector<double> rhist;
0476 for (int j = 0; j < nTRsteps + 1; j++) {
0477 rhist.push_back(maxTRfactor * j / nTRsteps);
0478 Fhist.push_back(transProb(maxTRfactor, 1., rhist[j]));
0479 if (debug == 3)
0480 LogInfo("FastCalorimetry") << "indexFinder - i, Fhist[i] = " << j << " " << Fhist[j] << std::endl;
0481 }
0482
0483
0484 for (int i = 0; i < numLongit; i++) {
0485 double currentDepthL0 = lamtotal[i] - 0.5 * lamstep[i];
0486
0487 if (detector[i] != 1)
0488 currentDepthL0 *= hcalDepthFactor;
0489 if (debug)
0490 LogInfo("FastCalorimetry") << " FamosHDShower::compute - detector = " << detector[i]
0491 << " currentDepthL0 = " << currentDepthL0 << std::endl;
0492
0493 double maxTRsize = maxTRfactor * rlamStep[i];
0494 double rbinsize = maxTRsize / nTRsteps;
0495 double espot = eStep[i] / (double)nspots[i];
0496
0497 if (espot > 2. || espot < 0.)
0498 LogInfo("FastCalorimetry") << " FamosHDShower::compute - unphysical espot = " << espot << std::endl;
0499
0500 int ecal = 0;
0501 if (detector[i] != 1) {
0502 bool setHDdepth = theHcalHitMaker->setDepth(currentDepthL0);
0503
0504 if (debug)
0505 LogInfo("FastCalorimetry") << " FamosHDShower::compute - status of "
0506 << " theHcalHitMaker->setDepth(currentDepthL0) is " << setHDdepth << std::endl;
0507
0508 if (!setHDdepth) {
0509 currentDepthL0 -= lamstep[i];
0510 setHDdepth = theHcalHitMaker->setDepth(currentDepthL0);
0511 }
0512
0513 if (!setHDdepth)
0514 continue;
0515
0516 theHcalHitMaker->setSpotEnergy(espot);
0517
0518
0519 } else {
0520 ecal = 1;
0521 bool status = theGrid->getPads(currentDepthL0);
0522
0523 if (debug)
0524 LogInfo("FastCalorimetry") << " FamosHDShower::compute - status of Grid = " << status << std::endl;
0525
0526 if (!status)
0527 continue;
0528
0529 int ntry = nspots[i] * 10;
0530 if (ntry >= infinity) {
0531 nspots[i] = 0.5 * infinity;
0532 espot *= 0.1 * (double)ntry / double(nspots[i]);
0533 } else {
0534 espot *= 0.1;
0535
0536 nspots[i] = ntry;
0537 }
0538
0539 theGrid->setSpotEnergy(espot);
0540
0541
0542 }
0543
0544
0545 int nok = 0;
0546 int count = 0;
0547 int inf = infinity;
0548 if (lossesOpt)
0549 inf = nspots[i];
0550
0551 if (nspots[i] > inf)
0552 std::cout << " FamosHDShower::compute - at long.step " << i << " too many spots required : " << nspots[i]
0553 << " !!! " << std::endl;
0554
0555 for (int j = 0; j < inf; j++) {
0556 if (nok == nspots[i])
0557 break;
0558 count++;
0559
0560 double prob = random->flatShoot();
0561 int index = indexFinder(prob, Fhist);
0562 double radius = rlamStep[i] * rhist[index] + random->flatShoot() * rbinsize;
0563 double phi = 2. * M_PI * random->flatShoot();
0564
0565 if (debug == 2)
0566 LogInfo("FastCalorimetry") << std::endl
0567 << " FamosHDShower::compute "
0568 << " r = " << radius << " phi = " << phi << std::endl;
0569
0570 bool result;
0571 if (ecal) {
0572 result = theGrid->addHit(radius, phi, 0);
0573
0574 if (debug == 2)
0575 LogInfo("FastCalorimetry") << " FamosHDShower::compute - "
0576 << " theGrid->addHit result = " << result << std::endl;
0577
0578
0579 } else {
0580 result = theHcalHitMaker->addHit(radius, phi, 0);
0581
0582 if (debug == 2)
0583 LogInfo("FastCalorimetry") << " FamosHDShower::compute - "
0584 << " theHcalHitMaker->addHit result = " << result << std::endl;
0585
0586
0587 }
0588
0589 if (result)
0590 nok++;
0591
0592 }
0593
0594 if (count == infinity) {
0595 if (debug)
0596 LogInfo("FastCalorimetry") << " FamosHDShower::compute "
0597 << " maximum number of"
0598 << " transverse points " << count << " is used !!!" << std::endl;
0599 }
0600
0601 if (debug)
0602 LogInfo("FastCalorimetry") << " FamosHDShower::compute "
0603 << " long.step No." << i << " Ntry, Nok = " << count << " " << nok << std::endl;
0604 }
0605 }
0606
0607 return status;
0608 }
0609
0610 int HDShower::indexFinder(double x, const std::vector<double>& Fhist) {
0611
0612 int size = Fhist.size();
0613
0614 int curr = size / 2;
0615 int step = size / 4;
0616 int iter;
0617 int prevdir = 0;
0618 int actudir = 0;
0619
0620 for (iter = 0; iter < size; iter++) {
0621 if (curr >= size || curr < 1)
0622 LogWarning("FastCalorimetry") << " FamosHDShower::indexFinder - wrong current index = " << curr << " !!!"
0623 << std::endl;
0624
0625 if ((x <= Fhist[curr]) && (x > Fhist[curr - 1]))
0626 break;
0627 prevdir = actudir;
0628 if (x > Fhist[curr]) {
0629 actudir = 1;
0630 } else {
0631 actudir = -1;
0632 }
0633 if (prevdir * actudir < 0) {
0634 if (step > 1)
0635 step /= 2;
0636 }
0637 curr += actudir * step;
0638 if (curr > size)
0639 curr = size;
0640 else {
0641 if (curr < 1) {
0642 curr = 1;
0643 }
0644 }
0645
0646 if (debug == 3)
0647 LogInfo("FastCalorimetry") << " indexFinder - end of iter." << iter << " curr, F[curr-1], F[curr] = " << curr
0648 << " " << Fhist[curr - 1] << " " << Fhist[curr] << std::endl;
0649 }
0650
0651 if (debug == 3)
0652 LogInfo("FastCalorimetry") << " indexFinder x = " << x << " found index = " << curr - 1 << std::endl;
0653
0654 return curr - 1;
0655 }