11 #include "cetlib_except/exception.h" 23 #include "TLorentzVector.h" 25 #include "CLHEP/Random/RandFlat.h" 26 #include "CLHEP/Random/RandPoisson.h" 37 : fNumberOfLevels ( 73 )
38 , fNumberOfStartLevels ( 21 )
39 , fBranchingRatios (fNumberOfLevels )
40 , fDecayTo (fNumberOfLevels )
41 , fMonoenergeticNeutrinos
42 (parameterSet.
get<
bool >(
"MonoenergeticNeutrinos"))
44 (parameterSet.
get< double >(
"NeutrinoEnergy" ))
45 , fEnergySpectrumFileName
46 (parameterSet.
get<
std::
string >(
"EnergySpectrumFileName"))
47 , fUsePoissonDistribution
48 (parameterSet.
get<
bool >(
"UsePoissonDistribution"))
50 (parameterSet.
get<
bool >(
"AllowZeroNeutrinos" ))
52 (parameterSet.
get<
int >(
"NumberOfNeutrinos" ))
54 (parameterSet.
get< double >(
"NeutrinoTimeBegin" ))
56 (parameterSet.
get< double >(
"NeutrinoTimeEnd" ))
60 (parameterSet.
get< std::vector< double > >(
"ActiveVolume0"));
62 (parameterSet.
get< std::vector< double > >(
"ActiveVolume1"));
75 std::vector<simb::MCTruth> truths;
78 for(
int i = 0; i < NumberOfNu; ++i) {
88 truths.push_back(truth);
99 (CLHEP::HepRandomEngine& engine)
const 102 CLHEP::RandFlat randFlat(engine);
104 std::vector< double > isotropicDirection;
106 double phi = 2*TMath::Pi()*randFlat.fire();
107 double cosTheta = 2*randFlat.fire() - 1;
108 double theta = TMath::ACos(cosTheta);
111 isotropicDirection.push_back(cos(phi)*sin(theta));
112 isotropicDirection.push_back(sin(phi)*sin(theta));
113 isotropicDirection.push_back(cosTheta);
115 return isotropicDirection;
122 (CLHEP::HepRandomEngine& engine)
const 125 CLHEP::RandFlat randFlat(engine);
129 position.push_back(randFlat.
131 position.push_back(randFlat.
133 position.push_back(randFlat.
143 (CLHEP::HepRandomEngine& engine)
const 148 CLHEP::RandPoisson randPoisson(engine);
161 (CLHEP::HepRandomEngine& engine)
const 164 CLHEP::RandFlat randFlat(engine);
174 (CLHEP::HepRandomEngine& engine)
const 179 CLHEP::RandFlat randFlat(engine);
181 double neutrinoEnergy = 0.0;
183 double randomNumber = randFlat.fire();
186 std::pair< double, double > previousPair;
192 if (randomNumber < energyProbability->
second)
196 neutrinoEnergy = energyProbability->first -
197 (energyProbability->second - randomNumber)*
198 (energyProbability->first - previousPair.first)/
199 (energyProbability->second - previousPair.second);
204 neutrinoEnergy = energyProbability->first;
208 previousPair = *energyProbability;
211 return neutrinoEnergy;
221 std::string directoryName =
"SupernovaNeutrinos/" +
225 searchPath.
find_file(directoryName, fullName);
227 if (fullName.empty())
229 <<
"Cannot find file with neutrino energy spectrum " 232 TFile energySpectrumFile(fullName.c_str(),
"READ");
234 std::string energySpectrumGraphName =
"NueSpectrum";
235 TGraph *energySpectrumGraph =
236 dynamic_cast< TGraph*
>(energySpectrumFile.Get
237 (energySpectrumGraphName.c_str()));
240 int numberOfPoints = energySpectrumGraph->GetN();
241 double *energyValues = energySpectrumGraph->GetX();
242 double *fluxValues = energySpectrumGraph->GetY();
243 for (
int point = 0; point < numberOfPoints; ++point)
244 integral += fluxValues[point];
246 double probability = 0.0;
247 for (
int point = 0; point < numberOfPoints; ++point)
249 probability += fluxValues[point]/
integral;
802 double startEnergyLevels[] = { 2.281, 2.752, 2.937,
803 3.143, 3.334, 3.569, 3.652, 3.786, 3.861, 4.067, 4.111, 4.267,
804 4.364, 4.522, 4.655, 4.825, 5.017, 5.080, 5.223, 5.696, 6.006 };
809 double b[] = { 0.9, 1.5, 0.11, 0.06, 0.04, 0.01,
810 0.16, 0.26, 0.01, 0.05, 0.11, 0.29,
811 3.84, 0.31, 0.38, 0.47, 0.36, 0.23,
816 double energyLevels[] = { 7.4724, 6.2270, 5.06347,
817 4.99294, 4.8756, 4.87255, 4.78865, 4.744093, 4.53706,
818 4.47299, 4.41936, 4.39588, 4.3840, 4.3656, 4.28052,
819 4.25362, 4.21307, 4.18003, 4.14901, 4.11084, 4.10446,
820 4.02035, 3.92390, 3.88792, 3.86866, 3.840228, 3.82143,
821 3.79757, 3.76779, 3.73848, 3.663739, 3.62995, 3.59924,
822 3.55697, 3.48621, 3.439144, 3.41434, 3.39363, 3.36803,
823 3.22867, 3.15381, 3.14644, 3.12836, 3.109721, 3.1002,
824 3.02795, 2.98587, 2.9508, 2.87901, 2.80788, 2.7874,
825 2.786644, 2.75672, 2.74691, 2.730372, 2.625990, 2.57593,
826 2.558, 2.54277, 2.419171, 2.397165, 2.290493, 2.289871,
827 2.26040, 2.103668, 2.069809, 2.047354, 1.959068, 1.643639,
828 0.891398, 0.8001427, 0.0298299, 0.0 };
841 CLHEP::HepRandomEngine& engine)
const 844 bool success =
false;
857 double neutrinoEnergy,
double neutrinoTime,
858 CLHEP::HepRandomEngine& engine)
const 861 CLHEP::RandFlat randFlat(engine);
863 int highestLevel = 0;
864 std::vector< double > levelCrossSections =
867 double totalCrossSection = 0;
870 levelCrossSections.begin();
871 crossSection != levelCrossSections.end(); ++crossSection)
872 totalCrossSection += *crossSection;
874 if (totalCrossSection == 0)
877 std::vector< double > startLevelProbabilities;
880 levelCrossSections.begin();
881 crossSection != levelCrossSections.end(); ++crossSection)
882 startLevelProbabilities.push_back((*crossSection)/totalCrossSection);
884 double randomNumber = randFlat.fire();
886 int chosenStartLevel = -1;
890 if (randomNumber < (startLevelProbabilities.at(
level) + tprob))
892 chosenStartLevel =
level;
895 tprob += startLevelProbabilities.at(
level);
903 std::vector< double > levelDelay;
908 int highestHigher = 0;
930 lastLevel = lowestLower;
943 lastLevel = highestHigher;
944 level = highestHigher;
963 int neutrinoTrackID = -1*(truth.
NParticles() + 1);
967 double neutrinoP = neutrinoEnergy/1000.0;
968 double neutrinoPx = neutrinoDirection.at(0)*neutrinoP;
969 double neutrinoPy = neutrinoDirection.at(1)*neutrinoP;
970 double neutrinoPz = neutrinoDirection.at(2)*neutrinoP;
980 TLorentzVector neutrinoPosition(vertex.at(0), vertex.at(1),
981 vertex.at(2), neutrinoTime);
982 TLorentzVector neutrinoMomentum(neutrinoPx, neutrinoPy,
983 neutrinoPz, neutrinoEnergy/1000.0);
995 double electronEnergy = neutrinoEnergy -
997 double electronEnergyGeV = electronEnergy/1000.0;
999 double electronM = 0.000511;
1000 double electronP = std::sqrt(
std::pow(electronEnergyGeV,2)
1005 double electronPx = electronDirection.at(0)*electronP;
1006 double electronPy = electronDirection.at(1)*electronP;
1007 double electronPz = electronDirection.at(2)*electronP;
1014 TLorentzVector electronPosition(vertex.at(0), vertex.at(1),
1015 vertex.at(2), neutrinoTime);
1016 TLorentzVector electronMomentum(electronPx, electronPy,
1017 electronPz, electronEnergyGeV);
1020 truth.
Add(electron);
1022 double ttime = neutrinoTime;
1023 int noMoreDecay = 0;
1026 int groundLevel = fNumberOfLevels - 1;
1027 while (level != groundLevel)
1030 double rl = randFlat.fire();
1037 for (
unsigned int iLevel = 0;
1046 level =
fDecayTo.at(level).at(decayNum);
1051 double gammaEnergyGeV = gammaEnergy/1000;
1054 double gammaPx = gammaDirection.at(0)*gammaEnergyGeV;
1055 double gammaPy = gammaDirection.at(1)*gammaEnergyGeV;
1056 double gammaPz = gammaDirection.at(2)*gammaEnergyGeV;
1060 double gammaTime = (-TMath::Log(randFlat.fire())/
1061 (1/(levelDelay.at(lastLevel)))) + ttime;
1070 TLorentzVector gammaPosition(vertex.at(0), vertex.at(1),
1071 vertex.at(2), neutrinoTime);
1072 TLorentzVector gammaMomentum(gammaPx, gammaPy,
1073 gammaPz, gammaEnergyGeV);
1086 std::cout <<
"(tprob + *iLevel) > 1" <<
std::endl;
1096 if (noMoreDecay == 1)
break;
1102 std::cout <<
"level != 72" <<
std::endl;
1103 std::cout <<
"level = " << level <<
std::endl;
1129 (
double neutrinoEnergy,
int& highestLevel)
const 1133 std::vector< double > levelCrossSections;
1151 double p = std::sqrt(
pow(w, 2) -
pow(511.0, 2));
1153 double f = std::sqrt(3.0634 + (0.6814/(w - 1)));
1155 sigma += 1.6e-8*(p*w*f*
fB.at(
n));
1158 levelCrossSections.push_back(sigma);
1161 return levelCrossSections;
std::vector< double > fStartEnergyLevels
void AddTrajectoryPoint(TLorentzVector const &position, TLorentzVector const &momentum)
bool ProcessOneNeutrino(simb::MCTruth &truth, double neutrinoEnergy, double neutrinoTime, CLHEP::HepRandomEngine &engine) const
void SetOrigin(simb::Origin_t origin)
double fNeutrinoTimeBegin
std::vector< double > GetUniformPosition(CLHEP::HepRandomEngine &engine) const
std::vector< double > fEnergyLevels
void CreateKinematicsVector(simb::MCTruth &truth, CLHEP::HepRandomEngine &engine) const
void SetNeutrino(int CCNC, int mode, int interactionType, int target, int nucleon, int quark, double w, double x, double y, double qsqr)
charged current quasi-elastic
std::vector< std::vector< double > > fBranchingRatios
std::vector< double > GetIsotropicDirection(CLHEP::HepRandomEngine &engine) const
bool fUsePoissonDistribution
bool fMonoenergeticNeutrinos
double GetNeutrinoTime(CLHEP::HepRandomEngine &engine) const
std::vector< double > CalculateCrossSections(double neutrinoEnergy, int &highestLevel) const
int GetNumberOfNeutrinos(CLHEP::HepRandomEngine &engine) const
NueAr40CCGenerator(fhicl::ParameterSet const ¶meterSet)
T get(std::string const &key) const
std::map< double, double > fEnergyProbabilityMap
double gamma(double KE, const simb::MCParticle *part)
double GetNeutrinoEnergy(CLHEP::HepRandomEngine &engine) const
void Add(simb::MCParticle const &part)
std::string fEnergySpectrumFileName
std::string find_file(std::string const &filename) const
std::vector< simb::MCTruth > Generate(CLHEP::HepRandomEngine &engine)
Event generator information.
auto const & get(AssnsNode< L, R, D > const &r)
std::vector< std::vector< double > > fActiveVolume
second_as<> second
Type of time stored in seconds, in double precision.
std::vector< std::vector< int > > fDecayTo
Event Generation using GENIE, cosmics or single particles.
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
void ReadNeutrinoSpectrum()