/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
FastSimulation/ShowerDevelopment/src/EMShower.cc
675 строк
22 KB
Shahzad Malik Muzaffar
[FASTSIM] [CLANG] Fixed unused-but-set-variable warnings
22 дек 2022, 13:25
22 дек 2022, 13:25
73735fe
Код
Авторство
О чём код?
//FAMOS Headers #include "FastSimulation/ShowerDevelopment/interface/EMShower.h" #include "FastSimulation/CaloHitMakers/interface/EcalHitMaker.h" #include "FastSimulation/CaloHitMakers/interface/PreshowerHitMaker.h" #include "FastSimulation/CaloHitMakers/interface/HcalHitMaker.h" #include "FastSimulation/Utilities/interface/RandomEngineAndDistribution.h" #include "FastSimulation/Utilities/interface/GammaFunctionGenerator.h" #include <cmath> //#include "FastSimulation/Utilities/interface/Histos.h" using std::vector; EMShower::EMShower(const RandomEngineAndDistribution* engine, GammaFunctionGenerator* gamma, EMECALShowerParametrization* const myParam, vector<const RawParticle*>* const myPart, EcalHitMaker* const myGrid, PreshowerHitMaker* const myPresh, bool bFixedLength) : theParam(myParam), thePart(myPart), theGrid(myGrid), thePreshower(myPresh), random(engine), myGammaGenerator(gamma), bFixedLength_(bFixedLength) { // Get the Famos Histos pointer // myHistos = Histos::instance(); // myGammaGenerator = GammaFunctionGenerator::instance(); stepsCalculated = false; hasPreshower = myPresh != nullptr; theECAL = myParam->ecalProperties(); theHCAL = myParam->hcalProperties(); theLayer1 = myParam->layer1Properties(); theLayer2 = myParam->layer2Properties(); double fotos = theECAL->photoStatistics() * theECAL->lightCollectionEfficiency(); nPart = thePart->size(); totalEnergy = 0.; globalMaximum = 0.; //double meanDepth = 0.; // Initialize the shower parameters for each particle for (unsigned int i = 0; i < nPart; ++i) { // std::cout << " AAA " << *(*thePart)[i] << std::endl; // The particle and the shower energy Etot.push_back(0.); E.push_back(((*thePart)[i])->e()); totalEnergy += E[i]; double lny = std::log(E[i] / theECAL->criticalEnergy()); // Average and Sigma for T and alpha double theMeanT = myParam->meanT(lny); double theMeanAlpha = myParam->meanAlpha(lny); double theMeanLnT = myParam->meanLnT(lny); double theMeanLnAlpha = myParam->meanLnAlpha(lny); double theSigmaLnT = myParam->sigmaLnT(lny); double theSigmaLnAlpha = myParam->sigmaLnAlpha(lny); // The correlation matrix double theCorrelation = myParam->correlationAlphaT(lny); double rhop = std::sqrt((1. + theCorrelation) / 2.); double rhom = std::sqrt((1. - theCorrelation) / 2.); // The number of spots in ECAL / HCAL theNumberOfSpots.push_back(myParam->nSpots(E[i])); // theNumberOfSpots.push_back(myParam->nSpots(E[i])*spotFraction); //theNumberOfSpots = random->poissonShoot(myParam->nSpots(myPart->e())); // Photo-statistics photos.push_back(E[i] * fotos); // The longitudinal shower development parameters // Fluctuations of alpha, T and beta double z1 = 0.; double z2 = 0.; double aa = 0.; // Protect against too large fluctuations (a < 1) for small energies while (aa <= 1.) { z1 = random->gaussShoot(0., 1.); z2 = random->gaussShoot(0., 1.); aa = std::exp(theMeanLnAlpha + theSigmaLnAlpha * (z1 * rhop - z2 * rhom)); } a.push_back(aa); T.push_back(std::exp(theMeanLnT + theSigmaLnT * (z1 * rhop + z2 * rhom))); b.push_back((a[i] - 1.) / T[i]); maximumOfShower.push_back((a[i] - 1.) / b[i]); globalMaximum += maximumOfShower[i] * E[i]; //meanDepth += a[i] / b[i] * E[i]; // std::cout << " Adding max " << maximumOfShower[i] << " " << E[i] << " " <<maximumOfShower[i]*E[i] << std::endl; // std::cout << std::setw(8) << std::setprecision(5) << " a /b " << a[i] << " " << b[i] << std::endl; Ti.push_back(a[i] / b[i] * (std::exp(theMeanLnAlpha) - 1.) / std::exp(theMeanLnAlpha)); // The parameters for the number of energy spots TSpot.push_back(theParam->meanTSpot(theMeanT)); aSpot.push_back(theParam->meanAlphaSpot(theMeanAlpha)); bSpot.push_back((aSpot[i] - 1.) / TSpot[i]); // myHistos->fill("h7000",a[i]); // myHistos->fill("h7002",E[i],a[i]); } // std::cout << " PS1 : " << myGrid->ps1TotalX0() // << " PS2 : " << myGrid->ps2TotalX0() // << " ECAL : " << myGrid->ecalTotalX0() // << " HCAL : " << myGrid->hcalTotalX0() // << " Offset : " << myGrid->x0DepthOffset() // << std::endl; globalMaximum /= totalEnergy; //meanDepth /= totalEnergy; // std::cout << " Total Energy " << totalEnergy << " Global max " << globalMaximum << std::endl; } void EMShower::prepareSteps() { // TimeMe theT("EMShower::compute"); // Determine the longitudinal intervals // std::cout << " EMShower compute" << std::endl; double dt; double radlen; int stps; int first_Ecal_step = 0; int last_Ecal_step = 0; // The maximum is in principe 8 (with 5X0 steps in the ECAL) steps.reserve(24); /* std::cout << " PS1 : " << theGrid->ps1TotalX0() << " PS2 : " << theGrid->ps2TotalX0() << " PS2 and ECAL : " << theGrid->ps2eeTotalX0() << " ECAL : " << theGrid->ecalTotalX0() << " HCAL : " << theGrid->hcalTotalX0() << " Offset : " << theGrid->x0DepthOffset() << std::endl; */ radlen = -theGrid->x0DepthOffset(); // Preshower Layer 1 radlen += theGrid->ps1TotalX0(); if (radlen > 0.) { steps.push_back(Step(0, radlen)); radlen = 0.; } // Preshower Layer 2 radlen += theGrid->ps2TotalX0(); if (radlen > 0.) { steps.push_back(Step(1, radlen)); radlen = 0.; } // add a step between preshower and ee radlen += theGrid->ps2eeTotalX0(); if (radlen > 0.) { steps.push_back(Step(5, radlen)); radlen = 0.; } // ECAL radlen += theGrid->ecalTotalX0(); // std::cout << "theGrid->ecalTotalX0() = " << theGrid->ecalTotalX0() << std::endl; if (radlen > 0.) { if (!bFixedLength_) { stps = (int)((radlen + 2.5) / 5.); // stps=(int)((radlen+.5)/1.); if (stps == 0) stps = 1; dt = radlen / (double)stps; Step step(2, dt); first_Ecal_step = steps.size(); for (int ist = 0; ist < stps; ++ist) steps.push_back(step); last_Ecal_step = steps.size() - 1; radlen = 0.; } else { dt = 1.0; stps = static_cast<int>(radlen); if (stps == 0) stps = 1; Step step(2, dt); first_Ecal_step = steps.size(); for (int ist = 0; ist < stps; ++ist) steps.push_back(step); dt = radlen - stps; if (dt > 0) { Step stepLast(2, dt); steps.push_back(stepLast); } last_Ecal_step = steps.size() - 1; // std::cout << "radlen = " << radlen << " stps = " << stps << " dt = " << dt << std::endl; radlen = 0.; } } // I should had a gap here ! // HCAL radlen += theGrid->hcalTotalX0(); if (radlen > 0.) { double dtFrontHcal = theGrid->totalX0() - theGrid->hcalTotalX0(); // One single step for the full HCAL if (dtFrontHcal < 30.) { dt = 30. - dtFrontHcal; Step step(3, dt); steps.push_back(step); } } nSteps = steps.size(); if (nSteps == 0) return; double ESliceTot = 0.; double MeanDepth = 0.; depositedEnergy.resize(nSteps); meanDepth.resize(nSteps); double t = 0.; int offset = 0; for (unsigned iStep = 0; iStep < nSteps; ++iStep) { ESliceTot = 0.; MeanDepth = 0.; double realTotalEnergy = 0; dt = steps[iStep].second; t += dt; for (unsigned int i = 0; i < nPart; ++i) { depositedEnergy[iStep].push_back(deposit(t, a[i], b[i], dt)); ESliceTot += depositedEnergy[iStep][i]; MeanDepth += deposit(t, a[i] + 1., b[i], dt) / b[i] * a[i]; realTotalEnergy += depositedEnergy[iStep][i] * E[i]; } if (ESliceTot > 0.) // can happen for the shower tails; this depth will be skipped anyway MeanDepth /= ESliceTot; else MeanDepth = t - dt; meanDepth[iStep] = MeanDepth; if (realTotalEnergy < 0.001) { offset -= 1; } } innerDepth = meanDepth[first_Ecal_step]; if (last_Ecal_step + offset >= 0) outerDepth = meanDepth[last_Ecal_step + offset]; else outerDepth = innerDepth; stepsCalculated = true; } void EMShower::compute() { double t = 0.; double dt = 0.; if (!stepsCalculated) prepareSteps(); // Prepare the grids in EcalHitMaker // theGrid->setInnerAndOuterDepth(innerDepth,outerDepth); //float pstot = 0.; //float ps2tot = 0.; //float ps1tot = 0.; bool status = false; // double E1 = 0.; // Energy layer 1 // double E2 = 0.; // Energy layer 2 // double n1 = 0.; // #mips layer 1 // double n2 = 0.; // #mips layer 2 // double E9 = 0.; // Energy ECAL // Loop over all segments for the longitudinal development //double totECalc = 0; for (unsigned iStep = 0; iStep < nSteps; ++iStep) { // The length of the shower in this segment dt = steps[iStep].second; // std::cout << " Detector " << steps[iStep].first << " t " << t << " " << dt << std::endl; // The elapsed length t += dt; // In what detector are we ? unsigned detector = steps[iStep].first; bool presh1 = detector == 0; bool presh2 = detector == 1; bool ecal = detector == 2; bool hcal = detector == 3; bool vfcal = detector == 4; bool gap = detector == 5; // Temporary. Will be removed if (theHCAL == nullptr) hcal = false; // Keep only ECAL for now if (vfcal) continue; // Nothing to do in the gap if (gap) continue; // cout << " t = " << t << endl; // Build the grid of crystals at this ECAL depth // Actually, it might be useful to check if this grid is empty or not. // If it is empty (because no crystal at this depth), it is of no use // (and time consuming) to generate the spots // middle of the step double tt = t - 0.5 * dt; double realTotalEnergy = 0.; for (unsigned int i = 0; i < nPart; ++i) { realTotalEnergy += depositedEnergy[iStep][i] * E[i]; } // std::cout << " Step " << tt << std::endl; // std::cout << "ecal " << ecal << " hcal " << hcal <<std::endl; // If the amount of energy is greater than 1 MeV, make a new grid // otherwise put in the previous one. bool usePreviousGrid = (realTotalEnergy < 0.001); // If the amount of energy is greater than 1 MeV, make a new grid // otherwise put in the previous one. // If less than 1 kEV. Just skip if (iStep > 2 && realTotalEnergy < 0.000001) continue; if (ecal && !usePreviousGrid) { status = theGrid->getPads(meanDepth[iStep]); } if (hcal) { status = theHcalHitMaker->setDepth(tt); } if ((ecal || hcal) && !status) continue; bool detailedShowerTail = false; // check if a detailed treatment of the rear leakage should be applied if (ecal && !usePreviousGrid) { detailedShowerTail = (t - dt > theGrid->getX0back()); } // The particles of the shower are processed in parallel for (unsigned int i = 0; i < nPart; ++i) { // double Edepo=deposit(t,a[i],b[i],dt); // integration of the shower profile between t-dt and t double dE = (!hcal) ? depositedEnergy[iStep][i] : 1. - deposit(a[i], b[i], t - dt); // no need to do the full machinery if there is ~nothing to distribute) if (dE * E[i] < 0.000001) continue; if (ecal && !theECAL->isHom()) { double mean = dE * E[i]; double sigma = theECAL->resE() * sqrt(mean); /* double meanLn = log(mean); double kLn = sigma/mean+1; double sigmaLn = log(kLn); */ double dE0 = dE; // std::cout << "dE before shoot = " << dE << std::endl; dE = random->gaussShoot(mean, sigma) / E[i]; // myGammaGenerator->setParameters(aSam,bSam,0); // dE = myGammaGenerator->shoot()/E[i]; // std::cout << "dE shooted = " << dE << " E[i] = " << E[i] << std::endl; if (dE * E[i] < 0.000001) continue; photos[i] = photos[i] * dE / dE0; } /* if (ecal && !theParam->ecalProperties()->isHom()){ double cSquare = TMath::Power(theParam->ecalProperties()->resE(),2); double aSam = dE/cSquare; double bSam = 1./cSquare; // dE = dE*gam(bSam*dE, aSam)/tgamma(aSam); } */ //totECalc += dE; // The number of energy spots (or mips) double nS = 0; // ECAL case : Account for photostatistics and long'al non-uniformity if (ecal) { // double aSam = E[i]*dE*one_over_resoSquare; // double bSam = one_over_resoSquare; dE = random->poissonShoot(dE * photos[i]) / photos[i]; double z0 = random->gaussShoot(0., 1.); dE *= 1. + z0 * theECAL->lightCollectionUniformity(); // Expected spot number nS = (theNumberOfSpots[i] * gam(bSpot[i] * tt, aSpot[i]) * bSpot[i] * dt / tgamma(aSpot[i])); // Preshower : Expected number of mips + fluctuation } else if (hcal) { nS = (theNumberOfSpots[i] * gam(bSpot[i] * tt, aSpot[i]) * bSpot[i] * dt / tgamma(aSpot[i])) * theHCAL->spotFraction(); double nSo = nS; nS = random->poissonShoot(nS); // 'Quick and dirty' fix (but this line should be better removed): if (nSo > 0. && nS / nSo < 10.) dE *= nS / nSo; // if(true) // { // std::cout << " theHCAL->spotFraction = " <<theHCAL->spotFraction() <<std::endl; // std::cout << " nSpot Ecal : " << nSo/theHCAL->spotFraction() << " Final " << nS << std::endl; // } } else if (presh1) { nS = random->poissonShoot(dE * E[i] * theLayer1->mipsPerGeV()); // std::cout << " dE *E[i] (1)" << dE*E[i] << " " << dE*E[i]*theLayer1->mipsPerGeV() << " "<< nS << std::endl; //pstot += dE * E[i]; //ps1tot += dE * E[i]; dE = nS / (E[i] * theLayer1->mipsPerGeV()); // E1 += dE*E[i]; // n1 += nS; // if (presh2) { E2 += SpotEnergy; ++n2; } } else if (presh2) { nS = random->poissonShoot(dE * E[i] * theLayer2->mipsPerGeV()); // std::cout << " dE *E[i] (2) " << dE*E[i] << " " << dE*E[i]*theLayer2->mipsPerGeV() << " "<< nS << std::endl; //pstot += dE * E[i]; //ps2tot += dE * E[i]; dE = nS / (E[i] * theLayer2->mipsPerGeV()); // E2 += dE*E[i]; // n2 += nS; } if (detailedShowerTail) myGammaGenerator->setParameters(floor(a[i] + 0.5), b[i], t - dt); // myHistos->fill("h100",t,dE); // The lateral development parameters // Energy of the spots double eSpot = (nS > 0.) ? dE / nS : 0.; double SpotEnergy = eSpot * E[i]; if (hasPreshower && (presh1 || presh2)) thePreshower->setSpotEnergy(0.00009); if (hcal) { SpotEnergy *= theHCAL->hOverPi(); theHcalHitMaker->setSpotEnergy(SpotEnergy); } // Poissonian fluctuations for the number of spots // int nSpot = random->poissonShoot(nS); int nSpot = (int)(nS + 0.5); // Fig. 11 (right) *** Does not match. // myHistos->fill("h101",t,(double)nSpot/theNumberOfSpots); //double taui = t/T; double taui = tt / Ti[i]; double proba = theParam->p(taui, E[i]); double theRC = theParam->rC(taui, E[i]); double theRT = theParam->rT(taui, E[i]); // Fig. 10 // myHistos->fill("h300",taui,theRC); // myHistos->fill("h301",taui,theRT); // myHistos->fill("h302",taui,proba); double dSpotsCore = random->gaussShoot(proba * nSpot, std::sqrt(proba * (1. - proba) * nSpot)); if (dSpotsCore < 0) dSpotsCore = 0; unsigned nSpots_core = (unsigned)(dSpotsCore + 0.5); unsigned nSpots_tail = ((unsigned)nSpot > nSpots_core) ? nSpot - nSpots_core : 0; for (unsigned icomp = 0; icomp < 2; ++icomp) { double theR = (icomp == 0) ? theRC : theRT; unsigned ncompspots = (icomp == 0) ? nSpots_core : nSpots_tail; RadialInterval radInterval(theR, ncompspots, SpotEnergy, random); if (ecal) { if (icomp == 0) { setIntervals(icomp, radInterval); } else { setIntervals(icomp, radInterval); } } else { radInterval.addInterval(100., 1.); // 100% of the spots } radInterval.compute(); // irad = 0 : central circle; irad=1 : outside unsigned nrad = radInterval.nIntervals(); for (unsigned irad = 0; irad < nrad; ++irad) { double spote = radInterval.getSpotEnergy(irad); if (ecal) theGrid->setSpotEnergy(spote); if (hcal) theHcalHitMaker->setSpotEnergy(spote); unsigned nradspots = radInterval.getNumberOfSpots(irad); double umin = radInterval.getUmin(irad); double umax = radInterval.getUmax(irad); // Go for the lateral development // std::cout << "Couche " << iStep << " irad = " << irad << " Ene = " << E[i] << " eSpot = " << eSpot << " spote = " << spote << " nSpot = " << nS << std::endl; for (unsigned ispot = 0; ispot < nradspots; ++ispot) { double z3 = random->flatShoot(umin, umax); double ri = theR * std::sqrt(z3 / (1. - z3)); // Generate phi double phi = 2. * M_PI * random->flatShoot(); // Add the hit in the crystal // if( ecal ) theGrid->addHit(ri*theECAL->moliereRadius(),phi); // Now the *moliereRadius is done in EcalHitMaker if (ecal) { if (detailedShowerTail) { // std::cout << "About to call addHitDepth " << std::endl; double depth; do { depth = myGammaGenerator->shoot(random); } while (depth > t); theGrid->addHitDepth(ri, phi, depth); // std::cout << " Done " << std::endl; } else theGrid->addHit(ri, phi); } else if (hasPreshower && presh1) thePreshower->addHit(ri, phi, 1); else if (hasPreshower && presh2) thePreshower->addHit(ri, phi, 2); else if (hcal) { // std::cout << " About to add a spot in the HCAL" << status << std::endl; theHcalHitMaker->addHit(ri, phi); // std::cout << " Added a spot in the HCAL" << status << std::endl; } // if (ecal) E9 += SpotEnergy; // if (presh1) { E1 += SpotEnergy; ++n1; } // if (presh2) { E2 += SpotEnergy; ++n2; } Etot[i] += spote; } } } // std::cout << " Done with the step " << std::endl; // The shower! //myHistos->fill("h500",theSpot.z(),theSpot.perp()); } // std::cout << " nPart " << nPart << std::endl; } // std::cout << " Finshed the step loop " << std::endl; // myHistos->fill("h500",E1+0.7*E2,E9); // myHistos->fill("h501",n1+0.7*n2,E9); // myHistos->fill("h400",n1); // myHistos->fill("h401",n2); // myHistos->fill("h402",E9+E1+0.7*E2); // if(!standalone)theGrid->printGrid(); /* double Etotal = 0.; for (unsigned i = 0; i < nPart; ++i) { // myHistos->fill("h10",Etot[i]); Etotal += Etot[i]; } */ // std::cout << "Etotal = " << Etotal << " nPart = "<< nPart << std::endl; // std::cout << "totECalc = " << totECalc << std::endl; // myHistos->fill("h20",Etotal); // if(thePreshower) // std::cout << " PS " << thePreshower->layer1Calibrated() << " " << thePreshower->layer2Calibrated() << " " << thePreshower->totalCalibrated() << " " << ps1tot << " " <<ps2tot << " " << pstot << std::endl; } double EMShower::gam(double x, double a) const { // A stupid gamma function return std::pow(x, a - 1.) * std::exp(-x); } //double //EMShower::deposit(double t, double a, double b, double dt) { // // // The number of integration steps (about 1 / X0) // int numberOfSteps = (int)dt+1; // // // The size if the integration step // double integrationstep = dt/(double)numberOfSteps; // // // Half this size // double halfis = 0.5*integrationstep; // // double dE = 0.; // // for(double tt=t-dt+halfis;tt<t;tt+=integrationstep) { // // // Simpson integration over each of these steps // dE += gam(b*(tt-halfis),a) // + 4.*gam(b* tt ,a) // + gam(b*(tt+halfis),a); // // } // // // Normalization // dE *= b*integrationstep/tgamma(a)/6.; // // // There we go. // return dE; //} double EMShower::deposit(double t, double a, double b, double dt) { myIncompleteGamma.a().setValue(a); double b1 = b * (t - dt); double b2 = b * t; double result = 0.; double rb1 = (b1 != 0.) ? myIncompleteGamma(b1) : 0.; double rb2 = (b2 != 0.) ? myIncompleteGamma(b2) : 0.; result = (rb2 - rb1); return result; } void EMShower::setIntervals(unsigned icomp, RadialInterval& rad) { // std::cout << " Got the pointer " << std::endl; const std::vector<double>& myValues((icomp) ? theParam->getTailIntervals() : theParam->getCoreIntervals()); // std::cout << " Got the vector " << myValues.size () << std::endl; unsigned nvals = myValues.size() / 2; for (unsigned iv = 0; iv < nvals; ++iv) { // std::cout << myValues[2*iv] << " " << myValues[2*iv+1] <<std::endl; rad.addInterval(myValues[2 * iv], myValues[2 * iv + 1]); } } void EMShower::setPreshower(PreshowerHitMaker* const myPresh) { if (myPresh != nullptr) { thePreshower = myPresh; hasPreshower = true; } } void EMShower::setHcal(HcalHitMaker* const myHcal) { theHcalHitMaker = myHcal; } double EMShower::deposit(double a, double b, double t) { // std::cout << " Deposit " << std::endl; myIncompleteGamma.a().setValue(a); double b2 = b * t; double result = 0.; if (fabs(b2) < 1.e-9) b2 = 1.e-9; result = myIncompleteGamma(b2); // std::cout << " deposit t = " << t << " " << result <<std::endl; return result; }