12 #ifndef EVGEN_RADIOLOGICAL 13 #define EVGEN_RADIOLOGICAL 31 #include "art_root_io/TFileService.h" 32 #include "art_root_io/TFileDirectory.h" 36 #include "cetlib_except/exception.h" 44 #include "nugen/EventGeneratorBase/evgenbase.h" 45 #include "nurandom/RandomUtils/NuRandomService.h" 50 #include "CoreUtils/ServiceUtil.h" 54 #include "TLorentzVector.h" 56 #include "TGenPhaseSpace.h" 63 #include "CLHEP/Random/RandFlat.h" 64 #include "CLHEP/Random/RandPoisson.h" 66 namespace simb {
class MCTruth; }
87 void SampleOne(
unsigned int i,
91 void samplespectrum(
std::string nuclide,
int &itype,
double &
t,
double &
m,
double &p);
94 double samplefromth1d(TH1D *
hist);
119 const double m_e = 0.000510998928;
120 const double m_alpha = 3.727379240;
144 produces< std::vector<simb::MCTruth> >();
145 produces< sumdata::RunData, ::art::InRun >();
160 fNuclide = p.
get< std::vector<std::string>>(
"Nuclide");
161 fBq = p.
get< std::vector<double> >(
"BqPercc");
162 fT0 = p.
get< std::vector<double> >(
"T0");
163 fT1 = p.
get< std::vector<double> >(
"T1");
164 fX0 = p.
get< std::vector<double> >(
"X0");
165 fY0 = p.
get< std::vector<double> >(
"Y0");
166 fZ0 = p.
get< std::vector<double> >(
"Z0");
167 fX1 = p.
get< std::vector<double> >(
"X1");
168 fY1 = p.
get< std::vector<double> >(
"Y1");
169 fZ1 = p.
get< std::vector<double> >(
"Z1");
172 unsigned int nsize =
fNuclide.size();
173 if ( fBq.size() != nsize )
throw cet::exception(
"RadioGen") <<
"Different size Bq vector and Nuclide vector\n";
174 if ( fT0.size() != nsize )
throw cet::exception(
"RadioGen") <<
"Different size T0 vector and Nuclide vector\n";
175 if ( fT1.size() != nsize )
throw cet::exception(
"RadioGen") <<
"Different size T1 vector and Nuclide vector\n";
176 if ( fX0.size() != nsize )
throw cet::exception(
"RadioGen") <<
"Different size X0 vector and Nuclide vector\n";
177 if ( fY0.size() != nsize )
throw cet::exception(
"RadioGen") <<
"Different size Y0 vector and Nuclide vector\n";
178 if ( fZ0.size() != nsize )
throw cet::exception(
"RadioGen") <<
"Different size Z0 vector and Nuclide vector\n";
179 if ( fX1.size() != nsize )
throw cet::exception(
"RadioGen") <<
"Different size X1 vector and Nuclide vector\n";
180 if ( fY1.size() != nsize )
throw cet::exception(
"RadioGen") <<
"Different size Y1 vector and Nuclide vector\n";
181 if ( fZ1.size() != nsize )
throw cet::exception(
"RadioGen") <<
"Different size Z1 vector and Nuclide vector\n";
186 readfile(
"40K",
"Potassium_40.root");
187 readfile(
"232Th",
"Thorium_232.root");
188 readfile(
"238U",
"Uranium_238.root");
199 auto geo = gar::providerFrom<geo::GeometryGAr>();
211 std::unique_ptr< std::vector<simb::MCTruth> > truthcol(
new std::vector<simb::MCTruth>);
217 for (
unsigned int i=0; i<
fNuclide.size(); ++i) {
222 truthcol->push_back(truth);
234 CLHEP::RandPoisson poisson(
fEngine);
239 long ndecays = poisson.shoot(rate);
241 for (
unsigned int idecay=0; idecay<ndecays; idecay++)
258 double p2 = energy*energy - m*
m;
259 if (p2 > 0) p = TMath::Sqrt(p2);
267 TLorentzVector
pos(
fX0[i] + flat.fire()*(
fX1[i] -
fX0[i]),
270 fT0[i] + flat.fire()*(
fT1[i] -
fT0[i]) );
274 double costheta = (2.0*flat.fire() - 1.0);
275 if (costheta < -1.0) costheta = -1.0;
276 if (costheta > 1.0) costheta = 1.0;
277 double sintheta = sqrt(1.0-costheta*costheta);
278 double phi = 2.0*
M_PI*flat.fire();
280 TLorentzVector pvec(p*sintheta*std::cos(phi),
281 p*sintheta*std::sin(phi),
291 if (pdgid == 1000020040)
312 for (
size_t i=0; i<
fNuclide.size(); i++)
320 if (ifound == 0)
return;
322 Bool_t addStatus = TH1::AddDirectoryStatus();
323 TH1::AddDirectory(kFALSE);
335 if (fullname.empty() ||
stat(fullname.c_str(), &sb)!=0)
338 <<
" not found in FW_SEARCH_PATH!\n";
340 TFile
f(fullname.c_str(),
"READ");
341 TGraph *alphagraph = (TGraph*)
f.Get(
"Alphas");
342 TGraph *betagraph = (TGraph*)
f.Get(
"Betas");
343 TGraph *gammagraph = (TGraph*)
f.Get(
"Gammas");
347 int np = alphagraph->GetN();
348 double *
y = alphagraph->GetY();
353 TH1D *alphahist = (TH1D*)
new TH1D(name.c_str(),
"Alpha Spectrum",np,0,np-1);
354 for (
int i=0; i<np; i++)
356 alphahist->SetBinContent(i+1,y[i]);
357 alphahist->SetBinError(i+1,0);
371 int np = betagraph->GetN();
373 double *
y = betagraph->GetY();
378 TH1D *betahist = (TH1D*)
new TH1D(name.c_str(),
"Beta Spectrum",np,0,np-1);
380 for (
int i=0; i<np; i++)
382 betahist->SetBinContent(i+1,y[i]);
383 betahist->SetBinError(i+1,0);
396 int np = gammagraph->GetN();
397 double *
y = gammagraph->GetY();
402 TH1D *gammahist = (TH1D*)
new TH1D(name.c_str(),
"Gamma Spectrum",np,0,np-1);
403 for (
int i=0; i<np; i++)
405 gammahist->SetBinContent(i+1,y[i]);
406 gammahist->SetBinError(i+1,0);
418 TH1::AddDirectory(addStatus);
448 throw cet::exception(
"RadioGen") <<
"Ununderstood nuclide: " << nuclide <<
"\n";
451 double rtype = flat.fire();
456 for (
int itry=0;itry<10;itry++)
476 if (itype >= 0)
break;
480 throw cet::exception(
"RadioGen") <<
"Normalization problem with nuclide: " << nuclide <<
"\n";
485 { p = TMath::Sqrt(p); }
497 int nbinsx = hist->GetNbinsX();
498 std::vector<double> partialsum;
499 partialsum.resize(nbinsx+1);
502 for (
int i=1;i<=
nbinsx;i++)
504 double hc = hist->GetBinContent(i);
505 if ( hc < 0)
throw cet::exception(
"RadioGen") <<
"Negative bin: " << i <<
" " << hist->GetName() <<
"\n";
506 partialsum[i] = partialsum[i-1] + hc;
509 if (integral == 0)
return 0;
511 for (
int i=1;i<=
nbinsx;i++) partialsum[i] /= integral;
513 double r1 = flat.fire();
514 int ibin = TMath::BinarySearch(nbinsx,&(partialsum[0]),r1);
515 Double_t
x = hist->GetBinLowEdge(ibin+1);
516 if (r1 > partialsum[ibin]) x +=
517 hist->GetBinWidth(ibin+1)*(r1-partialsum[ibin])/(partialsum[ibin+1] - partialsum[ibin]);
base_engine_t & createEngine(seed_t seed)
std::vector< double > fX0
Bottom corner x position (cm) in world coordinates.
std::vector< TH1D * > gammaspectrum
void readfile(std::string nuclide, std::string filename)
std::vector< double > fY1
Top corner y position (cm) in world coordinates.
std::vector< double > fT1
End of time window to simulate in ns.
void SampleOne(unsigned int i, simb::MCTruth &mct)
void AddTrajectoryPoint(TLorentzVector const &position, TLorentzVector const &momentum)
void SetOrigin(simb::Origin_t origin)
std::vector< double > fZ1
Top corner z position (cm) in world coordinates.
std::vector< double > alphaintegral
std::vector< double > fT0
Beginning of time window to simulate in ns.
std::vector< double > fX1
Top corner x position (cm) in world coordinates.
std::vector< std::string > fNuclide
List of nuclides to simulate. Example: "39Ar".
std::vector< double > fBq
Radioactivity in Becquerels (decay per sec) per cubic cm.
#define DEFINE_ART_MODULE(klass)
virtual void reconfigure(fhicl::ParameterSet const &pset)
single particles thrown at the detector
T get(std::string const &key) const
std::vector< TH1D * > alphaspectrum
std::vector< double > fY0
Bottom corner y position (cm) in world coordinates.
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
double samplefromth1d(TH1D *hist)
std::vector< double > fZ0
Bottom corner z position (cm) in world coordinates.
std::vector< double > gammaintegral
Base utilities and modules for event generation and detector simulation.
void reconfigure(fhicl::ParameterSet const &p)
CLHEP::HepRandomEngine & fEngine
void beginRun(::art::Run &run)
General GArSoft Utilities.
void Add(simb::MCParticle const &part)
void samplespectrum(std::string nuclide, int &itype, double &t, double &m, double &p)
std::vector< TH1D * > betaspectrum
std::string find_file(std::string const &filename) const
std::vector< std::string > spectrumname
Event generator information.
std::vector< double > betaintegral
int trackidcounter
Serial number for the MC track ID.
LArSoft geometry interface.
art framework interface to geometry description
Event Generation using GENIE, cosmics or single particles.
nbinsx
New: trying to make a variation.
cet::coded_exception< error, detail::translate > exception
void produce(::art::Event &evt)