10 #include "cetlib/search_path.h" 11 #include "cetlib_except/exception.h" 20 #include "TLorentzVector.h" 22 #include "CLHEP/Random/RandFlat.h" 23 #include "CLHEP/Random/RandPoisson.h" 35 : fNumberOfLevels ( 73 )
36 , fNumberOfStartLevels ( 21 )
37 , fBranchingRatios (fNumberOfLevels )
38 , fDecayTo (fNumberOfLevels )
39 , fMonoenergeticNeutrinos
40 (parameterSet.get< bool >(
"MonoenergeticNeutrinos"))
42 (parameterSet.get< double >(
"NeutrinoEnergy" ))
43 , fEnergySpectrumFileName
44 (parameterSet.get<
std::string >(
"EnergySpectrumFileName"))
45 , fUsePoissonDistribution
46 (parameterSet.get< bool >(
"UsePoissonDistribution"))
48 (parameterSet.get< bool >(
"AllowZeroNeutrinos" ))
50 (parameterSet.get< int >(
"NumberOfNeutrinos" ))
52 (parameterSet.get< double >(
"NeutrinoTimeBegin" ))
54 (parameterSet.get< double >(
"NeutrinoTimeEnd" ))
58 (parameterSet.
get< std::vector< double > >(
"ActiveVolume0"));
60 (parameterSet.
get< std::vector< double > >(
"ActiveVolume1"));
73 std::vector<simb::MCTruth> truths;
76 for(
int i = 0; i < NumberOfNu; ++i) {
86 truths.push_back(truth);
97 (CLHEP::HepRandomEngine& engine)
const 100 CLHEP::RandFlat randFlat(engine);
102 std::vector< double > isotropicDirection;
104 double phi = 2*TMath::Pi()*randFlat.fire();
105 double cosTheta = 2*randFlat.fire() - 1;
106 double theta = TMath::ACos(cosTheta);
109 isotropicDirection.push_back(cos(phi)*sin(theta));
110 isotropicDirection.push_back(sin(phi)*sin(theta));
111 isotropicDirection.push_back(cosTheta);
113 return isotropicDirection;
120 (CLHEP::HepRandomEngine& engine)
const 123 CLHEP::RandFlat randFlat(engine);
125 std::vector< double > position;
127 position.push_back(randFlat.
129 position.push_back(randFlat.
131 position.push_back(randFlat.
141 (CLHEP::HepRandomEngine& engine)
const 146 CLHEP::RandPoisson randPoisson(engine);
159 (CLHEP::HepRandomEngine& engine)
const 162 CLHEP::RandFlat randFlat(engine);
172 (CLHEP::HepRandomEngine& engine)
const 177 CLHEP::RandFlat randFlat(engine);
179 double neutrinoEnergy = 0.0;
181 double randomNumber = randFlat.fire();
184 std::pair< double, double > previousPair;
190 if (randomNumber < energyProbability->second)
194 neutrinoEnergy = energyProbability->first -
195 (energyProbability->second - randomNumber)*
196 (energyProbability->first - previousPair.first)/
197 (energyProbability->second - previousPair.second);
202 neutrinoEnergy = energyProbability->first;
206 previousPair = *energyProbability;
209 return neutrinoEnergy;
218 cet::search_path searchPath(
"FW_SEARCH_PATH");
219 std::string directoryName =
"SupernovaNeutrinos/" +
222 std::string fullName;
223 searchPath.find_file(directoryName, fullName);
225 if (fullName.empty())
227 <<
"Cannot find file with neutrino energy spectrum " 230 TFile energySpectrumFile(fullName.c_str(),
"READ");
232 std::string energySpectrumGraphName =
"NueSpectrum";
233 TGraph *energySpectrumGraph =
234 dynamic_cast< TGraph*
>(energySpectrumFile.Get
235 (energySpectrumGraphName.c_str()));
237 double integral = 0.0;
238 int numberOfPoints = energySpectrumGraph->GetN();
239 double *energyValues = energySpectrumGraph->GetX();
240 double *fluxValues = energySpectrumGraph->GetY();
241 for (
int point = 0; point < numberOfPoints; ++point)
242 integral += fluxValues[point];
244 double probability = 0.0;
245 for (
int point = 0; point < numberOfPoints; ++point)
247 probability += fluxValues[point]/integral;
800 double startEnergyLevels[] = { 2.281, 2.752, 2.937,
801 3.143, 3.334, 3.569, 3.652, 3.786, 3.861, 4.067, 4.111, 4.267,
802 4.364, 4.522, 4.655, 4.825, 5.017, 5.080, 5.223, 5.696, 6.006 };
807 double b[] = { 0.9, 1.5, 0.11, 0.06, 0.04, 0.01,
808 0.16, 0.26, 0.01, 0.05, 0.11, 0.29,
809 3.84, 0.31, 0.38, 0.47, 0.36, 0.23,
814 double energyLevels[] = { 7.4724, 6.2270, 5.06347,
815 4.99294, 4.8756, 4.87255, 4.78865, 4.744093, 4.53706,
816 4.47299, 4.41936, 4.39588, 4.3840, 4.3656, 4.28052,
817 4.25362, 4.21307, 4.18003, 4.14901, 4.11084, 4.10446,
818 4.02035, 3.92390, 3.88792, 3.86866, 3.840228, 3.82143,
819 3.79757, 3.76779, 3.73848, 3.663739, 3.62995, 3.59924,
820 3.55697, 3.48621, 3.439144, 3.41434, 3.39363, 3.36803,
821 3.22867, 3.15381, 3.14644, 3.12836, 3.109721, 3.1002,
822 3.02795, 2.98587, 2.9508, 2.87901, 2.80788, 2.7874,
823 2.786644, 2.75672, 2.74691, 2.730372, 2.625990, 2.57593,
824 2.558, 2.54277, 2.419171, 2.397165, 2.290493, 2.289871,
825 2.26040, 2.103668, 2.069809, 2.047354, 1.959068, 1.643639,
826 0.891398, 0.8001427, 0.0298299, 0.0 };
839 CLHEP::HepRandomEngine& engine)
const 842 bool success =
false;
855 double neutrinoEnergy,
double neutrinoTime,
856 CLHEP::HepRandomEngine& engine)
const 859 CLHEP::RandFlat randFlat(engine);
861 int highestLevel = 0;
862 std::vector< double > levelCrossSections =
865 double totalCrossSection = 0;
868 levelCrossSections.begin();
869 crossSection != levelCrossSections.end(); ++crossSection)
870 totalCrossSection += *crossSection;
872 if (totalCrossSection == 0)
875 std::vector< double > startLevelProbabilities;
878 levelCrossSections.begin();
879 crossSection != levelCrossSections.end(); ++crossSection)
880 startLevelProbabilities.push_back((*crossSection)/totalCrossSection);
882 double randomNumber = randFlat.fire();
884 int chosenStartLevel = -1;
886 for (
int level = 0; level < highestLevel; ++level)
888 if (randomNumber < (startLevelProbabilities.at(level) + tprob))
890 chosenStartLevel = level;
893 tprob += startLevelProbabilities.at(level);
901 std::vector< double > levelDelay;
906 int highestHigher = 0;
928 lastLevel = lowestLower;
941 lastLevel = highestHigher;
942 level = highestHigher;
961 int neutrinoTrackID = -1*(truth.
NParticles() + 1);
962 std::string primary(
"primary");
965 double neutrinoP = neutrinoEnergy/1000.0;
966 double neutrinoPx = neutrinoDirection.at(0)*neutrinoP;
967 double neutrinoPy = neutrinoDirection.at(1)*neutrinoP;
968 double neutrinoPz = neutrinoDirection.at(2)*neutrinoP;
978 TLorentzVector neutrinoPosition(vertex.at(0), vertex.at(1),
979 vertex.at(2), neutrinoTime);
980 TLorentzVector neutrinoMomentum(neutrinoPx, neutrinoPy,
981 neutrinoPz, neutrinoEnergy/1000.0);
993 double electronEnergy = neutrinoEnergy -
995 double electronEnergyGeV = electronEnergy/1000.0;
997 double electronM = 0.000511;
998 double electronP = std::sqrt(std::pow(electronEnergyGeV,2)
999 - std::pow(electronM,2));
1003 double electronPx = electronDirection.at(0)*electronP;
1004 double electronPy = electronDirection.at(1)*electronP;
1005 double electronPz = electronDirection.at(2)*electronP;
1009 int electronPDG = 11;
1012 TLorentzVector electronPosition(vertex.at(0), vertex.at(1),
1013 vertex.at(2), neutrinoTime);
1014 TLorentzVector electronMomentum(electronPx, electronPy,
1015 electronPz, electronEnergyGeV);
1018 truth.
Add(electron);
1020 double ttime = neutrinoTime;
1021 int noMoreDecay = 0;
1024 int groundLevel = fNumberOfLevels - 1;
1025 while (level != groundLevel)
1028 double rl = randFlat.fire();
1035 for (
unsigned int iLevel = 0;
1044 level =
fDecayTo.at(level).at(decayNum);
1049 double gammaEnergyGeV = gammaEnergy/1000;
1052 double gammaPx = gammaDirection.at(0)*gammaEnergyGeV;
1053 double gammaPy = gammaDirection.at(1)*gammaEnergyGeV;
1054 double gammaPz = gammaDirection.at(2)*gammaEnergyGeV;
1058 double gammaTime = (-TMath::Log(randFlat.fire())/
1059 (1/(levelDelay.at(lastLevel)))) + ttime;
1068 TLorentzVector gammaPosition(vertex.at(0), vertex.at(1),
1069 vertex.at(2), neutrinoTime);
1070 TLorentzVector gammaMomentum(gammaPx, gammaPy,
1071 gammaPz, gammaEnergyGeV);
1084 std::cout <<
"(tprob + *iLevel) > 1" << std::endl;
1094 if (noMoreDecay == 1)
break;
1100 std::cout <<
"level != 72" << std::endl;
1101 std::cout <<
"level = " << level << std::endl;
1127 (
double neutrinoEnergy,
int& highestLevel)
const 1131 std::vector< double > levelCrossSections;
1144 for (
int n = 0;
n <= level; ++
n)
1149 double p = std::sqrt(pow(w, 2) - pow(511.0, 2));
1151 double f = std::sqrt(3.0634 + (0.6814/(w - 1)));
1153 sigma += 1.6e-8*(p*w*f*
fB.at(
n));
1156 levelCrossSections.push_back(sigma);
1159 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
void Add(simb::MCParticle &part)
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 GetNeutrinoEnergy(CLHEP::HepRandomEngine &engine) const
std::string fEnergySpectrumFileName
std::vector< simb::MCTruth > Generate(CLHEP::HepRandomEngine &engine)
Event generator information.
std::vector< std::vector< double > > fActiveVolume
std::vector< std::vector< int > > fDecayTo
Event Generation using GENIE, cosmics or single particles.
cet::coded_exception< error, detail::translate > exception
void ReadNeutrinoSpectrum()