/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
FastSimulation/MaterialEffects/src/MuonBremsstrahlungSimulator.cc
168 строк
7 KB
Kevin Pedro
fix potential memory leaks
06 дек 2025, 00:42
06 дек 2025, 00:42
e22405e
Код
Авторство
О чём код?
/////////////////////////////////////////////// //MuonBremsstrahlungSimulator // Description: Implementation of Muon bremsstrahlung using the Petrukhin model //Authors :Sandro Fonseca de Souza and Andre Sznajder (UERJ/Brazil) // Date: 23-Nov-2010 ////////////////////////////////////////////////////////// #include "FastSimulation/MaterialEffects/interface/MuonBremsstrahlungSimulator.h" #include "FastSimulation/Utilities/interface/RandomEngineAndDistribution.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FastSimulation/MaterialEffects/interface/PetrukhinModel.h" #include "FastSimulation/Particle/interface/makeParticle.h" #include <cmath> #include <string> #include <iostream> ////////////////////////////////////////////////////////////////////////////////////// MuonBremsstrahlungSimulator::MuonBremsstrahlungSimulator( double A, double Z, double density, double radLen, double photonEnergyCut, double photonFractECut) : MaterialEffectsSimulator(A, Z, density, radLen) { // Set the minimal photon energy for a Brem from mu+/- photonEnergy = photonEnergyCut; photonFractE = photonFractECut; d = 0.; //distance LogDebug("MuonBremsstrahlungSimulator") << "Starting the MuonBremsstrahlungSimulator" << std::endl; } /////////////////////////////////////////////////////////////////// void MuonBremsstrahlungSimulator::compute(ParticlePropagator& Particle, RandomEngineAndDistribution const* random) { double NA = 6.022e+23; //Avogadro's number if (radLengths > 4.) { Particle.particle().setMomentum(0., 0., 0., 0.); deltaPMuon.SetXYZT(0., 0., 0., 0.); brem_photon.SetXYZT(0., 0., 0., 0.); } // Hard brem probability with a photon Energy above photonEnergy. double EMuon = Particle.particle().e(); //Muon Energy if (EMuon < photonEnergy) return; xmin = std::max(photonEnergy / EMuon, photonFractE); //fraction of muon's energy transferred to the photon // xmax = photonEnergy/Particle.particle().e(); if (xmin >= 1. || xmin <= 0.) return; xmax = 1.; npar = 3; //Number of parameters // create TF1 using a free C function f1 = std::make_unique<TF1>("f1", PetrukhinFunc, xmin, xmax, npar); //Setting parameters f1->SetParameters(EMuon, A, Z); ///////////////////////////////////////////////////////////////////////// //d = distance for several materials //X0 = radLen //d = radLengths * X0(for tracker,yoke,ECAL and HCAL) d = radLengths * radLen; //Integration bremProba = density * d * (NA / A) * (f1->Integral(0., 1.)); // Number of photons to be radiated. unsigned int nPhotons = random->poissonShoot(bremProba); _theUpdatedState.reserve(nPhotons); if (!nPhotons) return; //Rotate to the lab frame double chi = Particle.particle().theta(); double psi = Particle.particle().phi(); RawParticle::RotationZ rotZ(psi); RawParticle::RotationY rotY(chi); // Energy of these photons for (unsigned int i = 0; i < nPhotons; ++i) { // Check that there is enough energy left. if (Particle.particle().e() < photonEnergy) break; LogDebug("MuonBremsstrahlungSimulator") << "MuonBremsstrahlungSimulator parameters:" << std::endl; LogDebug("MuonBremsstrahlungSimulator") << "xmin-> " << xmin << std::endl; LogDebug("MuonBremsstrahlungSimulator") << "Atomic Weight-> " << A << std::endl; LogDebug("MuonBremsstrahlungSimulator") << "Density-> " << density << std::endl; LogDebug("MuonBremsstrahlungSimulator") << "Distance-> " << d << std::endl; LogDebug("MuonBremsstrahlungSimulator") << "bremProba->" << bremProba << std::endl; LogDebug("MuonBremsstrahlungSimulator") << "nPhotons->" << nPhotons << std::endl; LogDebug("MuonBremsstrahlungSimulator") << " Muon_Energy-> " << EMuon << std::endl; LogDebug("MuonBremsstrahlungSimulator") << "X0-> " << radLen << std::endl; LogDebug("MuonBremsstrahlungSimulator") << " radLengths-> " << radLengths << std::endl; // Add a photon RawParticle thePhoton = makeParticle(Particle.particleDataTable(), 22, brem(Particle, random)); if (thePhoton.E() > 0.) { thePhoton.rotate(rotY); thePhoton.rotate(rotZ); _theUpdatedState.push_back(thePhoton); // Update the original mu +/- deltaPMuon = Particle.particle().momentum() -= thePhoton.momentum(); // Information of brem photon brem_photon.SetXYZT(thePhoton.Px(), thePhoton.Py(), thePhoton.Pz(), thePhoton.E()); LogDebug("MuonBremsstrahlungSimulator") << " Muon Bremsstrahlung: photon_energy-> " << thePhoton.E() << std::endl; LogDebug("MuonBremsstrahlungSimulator") << "photon_px->" << thePhoton.Px() << std::endl; LogDebug("MuonBremsstrahlungSimulator") << "photon_py->" << thePhoton.Py() << std::endl; LogDebug("MuonBremsstrahlungSimulator") << "photon_pz->" << thePhoton.Pz() << std::endl; } } } /////////////////////////////////////////////////////////////////////////////////////////// XYZTLorentzVector MuonBremsstrahlungSimulator::brem(ParticlePropagator& pp, RandomEngineAndDistribution const* random) const { // This is a simple version of a Muon Brem using Petrukhin model . //Ref: http://pdg.lbl.gov/2008/AtomicNuclearProperties/adndt.pdf double mumass = 0.105658367; //mu mass (GeV/c^2) // RANDOM_NUMBER_ERROR // Random number should be generated by the engines from the // RandomNumberGeneratorService. This appears to use the global // engine in ROOT. This is not thread safe unless the module using // it is a one module and declares a shared resource and all // other modules using it also declare the same shared resource. // This also breaks replay. // It might be that this is never used because of the std::cout // statement 2 lines below. I've never seen or heard complaints // about that vebosity .... double xp = f1->GetRandom(); LogDebug("MuonBremsstrahlungSimulator") << "MuonBremsstrahlungSimulator: xp->" << xp << std::endl; std::cout << "MuonBremsstrahlungSimulator: xp->" << xp << std::endl; // Have photon energy. Now generate angles with respect to the z axis // defined by the incoming particle's momentum. // Isotropic in phi const double phi = random->flatShoot() * 2 * M_PI; // theta from universal distribution const double theta = gbteth(pp.particle().e(), mumass, xp, random) * mumass / pp.particle().e(); // Make momentum components double stheta = std::sin(theta); double ctheta = std::cos(theta); double sphi = std::sin(phi); double cphi = std::cos(phi); return xp * pp.particle().e() * XYZTLorentzVector(stheta * cphi, stheta * sphi, ctheta, 1.); } ////////////////////////////////////////////////////////////////////////////////////////////// double MuonBremsstrahlungSimulator::gbteth(const double ener, const double partm, const double efrac, RandomEngineAndDistribution const* random) const { const double alfa = 0.625; const double d = 0.13 * (0.8 + 1.3 / theZ()) * (100.0 + (1.0 / ener)) * (1.0 + efrac); const double w1 = 9.0 / (9.0 + d); const double umax = ener * M_PI / partm; double u; do { double beta = (random->flatShoot() <= w1) ? alfa : 3.0 * alfa; u = -std::log(random->flatShoot() * random->flatShoot()) / beta; } while (u >= umax); return u; }