17 #include <initializer_list> 32 #include "cetlib_except/exception.h" 37 #include "nurandom/RandomUtils/NuRandomService.h" 50 #include "TDatabasePDG.h" 55 #include "CLHEP/Random/RandFlat.h" 56 #include "CLHEP/Random/RandGaussQ.h" 70 Name(
"ParticleSelectionMode"),
75 Name(
"PadOutVectors"),
76 Comment(
"if true, all per-PDG-ID quantities must contain only one value, which is then used for all PDG IDs")
81 Comment(
"PDG ID of the particles to be generated; this is the key for the other options marked as \"per PDG ID\"")
92 Comment(
"central momentum (GeV/c) to generate"),
98 Comment(
"variation in momenta (GeV/c)"),
104 Comment(
"central x position (cm) in world coordinates [per PDG ID]")
109 Comment(
"central y position (cm) in world coordinates [per PDG ID]")
114 Comment(
"central z position (cm) in world coordinates [per PDG ID]")
119 Comment(
"central time (s) [per PDG ID]")
124 Comment(
"variation (radius or RMS) in x position (cm) [per PDG ID]")
129 Comment(
"variation (radius or RMS) in y position (cm) [per PDG ID]")
134 Comment(
"variation (radius or RMS) in z position (cm) [per PDG ID]")
139 Comment(
"variation (semi-interval or RMS) in time (s) [per PDG ID]")
153 Name(
"SingleVertex"),
154 Comment(
"if true, all particles are produced at the same location"),
160 Comment(
"angle from Z axis on world X-Z plane (degrees)")
165 Comment(
"angle from Z axis on world Y-Z plane (degrees)")
169 Name(
"SigmaThetaXZ"),
170 Comment(
"variation in angle in X-Z plane (degrees)")
174 Name(
"SigmaThetaYZ"),
175 Comment(
"variation in angle in Y-Z plane (degrees)")
185 Name(
"HistogramFile"),
186 Comment(
"ROOT file containing the required distributions for the generation"),
192 Comment(
"name of the histograms of momentum distributions"),
204 Name(
"ThetaXzYzHist"),
205 Comment(
"name of the histograms of angular (X-Z and Y-Z) distribution"),
211 Comment(
"override the random number generator seed")
242 void printVecs(std::vector<std::string>
const& list);
243 bool PadVector(std::vector<double> &vec);
293 std::vector<std::unique_ptr<TH1>>
hPHist ;
338 template <
typename OptionList>
340 (
std::string Option, OptionList
const& allowedOptions) -> decltype(
auto);
355 template <
typename OptionList>
357 OptionList
const& allowedOptions,
bool printKey,
358 std::initializer_list<typename OptionList::value_type::first_type> exclude
361 template <
typename OptionList>
363 (OptionList
const& allowedOptions,
bool printKey =
true)
368 template <
typename OptionList>
370 typename OptionList::value_type::first_type optionKey,
371 OptionList
const& allowedOptions,
381 std::map<int, std::string>
names;
388 std::map<int, std::string>
names;
401 template <
typename OptionList>
403 (
std::string Option, OptionList
const& allowedOptions) -> decltype(
auto)
405 using key_type =
typename OptionList::value_type::first_type;
406 using tolower_type =
int(*)(
int);
407 auto toLower = [](
auto const&
S)
411 std::transform(
S.cbegin(),
S.cend(), std::back_inserter(s),
412 (tolower_type) &std::tolower);
415 auto option = toLower(Option);
416 for (
auto const& candidate: allowedOptions) {
417 if (toLower(candidate.second) == option)
return candidate.first;
421 key_type
num = std::stoi(Option, &end);
422 if (allowedOptions.count(num) && (end == Option.length()))
return num;
424 catch (std::invalid_argument
const&) {}
425 throw std::runtime_error(
"Option '" + Option +
"' not supported.");
429 template <
typename OptionList>
431 OptionList
const& allowedOptions,
bool printKey ,
432 std::initializer_list<typename OptionList::value_type::first_type> exclude
437 for (
auto const& option: allowedOptions) {
438 auto const&
key = option.first;
439 if (std::find(exclude.begin(), exclude.end(),
key) != exclude.end())
441 if (n++ > 0) msg +=
", ";
450 template <
typename OptionList>
452 typename OptionList::value_type::first_type optionKey,
453 OptionList
const& allowedOptions,
456 auto iOption = allowedOptions.find(optionKey);
457 return (iOption != allowedOptions.end())? iOption->second: defName;
497 rndm::NuRandomService::seed_t seed;
498 if (
config().Seed(seed)) {
502 produces< std::vector<simb::MCTruth> >();
503 produces< sumdata::RunData, art::InRun >();
522 std::vector<std::string> vlist(15);
532 vlist[9] =
"Theta0XZ";
533 vlist[10] =
"Theta0YZ";
534 vlist[11] =
"SigmaThetaXZ";
535 vlist[12] =
"SigmaThetaYZ";
537 vlist[14] =
"SigmaT";
546 if( !this->
PadVector(
fP0 ) ){ list.append(vlist[1].append(
", \n")); }
549 if( !this->
PadVector(
fX0 ) ){ list.append(vlist[3].append(
", \n")); }
550 if( !this->
PadVector(
fY0 ) ){ list.append(vlist[4].append(
", \n")); }
551 if( !this->
PadVector(
fZ0 ) ){ list.append(vlist[5].append(
", \n")); }
559 if( !this->
PadVector(
fT0 ) ){ list.append(vlist[13].append(
", \n")); }
566 <<
"\n vector(s) defined in the fhicl files has/have " 567 <<
"a different size than the PDG vector " 568 <<
"\n and it has (they have) more than one value, " 569 <<
"\n disallowing sensible padding " 570 <<
" and/or you have set fPadOutVectors to false. \n";
575 TFile* histFile =
nullptr;
581 if (!histFile || histFile->IsZombie() || !histFile->IsOpen()) {
596 histFile =
new TFile(relative_filename.c_str());
597 if (!histFile || histFile->IsZombie() || !histFile->IsOpen()) {
600 throw art::Exception(
art::errors::NotFound) <<
"Cannot open ROOT file found using relative path and originally specified in parameter HistogramFile: \"" << relative_filename <<
'"';
610 histFile =
new TFile(found_filename.c_str());
611 if (!histFile || histFile->IsZombie() || !histFile->IsOpen()) {
614 throw art::Exception(
art::errors::NotFound) <<
"Cannot open ROOT file found on FW_SEARCH_PATH and originally specified in parameter HistogramFile: \"" << found_filename <<
'"';
627 <<
"Position distribution of type '" 639 <<
"Time distribution of type '" 651 <<
fPHist.size() <<
" momentum histograms to describe " <<
fPDG.size() <<
" particle types...";
654 for (
auto const& histName:
fPHist) {
655 TH1* pHist =
dynamic_cast<TH1*
>(histFile->Get(histName.c_str()));
658 <<
"Failed to read momentum histogram '" << histName <<
"' from '" << histFile->GetPath() <<
"\'";
660 pHist->SetDirectory(
nullptr);
661 hPHist.emplace_back(pHist);
672 <<
fThetaXzYzHist.size() <<
" direction histograms to describe " <<
fPDG.size() <<
" particle types...";
676 TH2* pHist =
dynamic_cast<TH2*
>(histFile->Get(histName.c_str()));
679 <<
"Failed to read direction histogram '" << histName <<
"' from '" << histFile->GetPath() <<
"\'";
681 pHist->SetDirectory(
nullptr);
696 if( vec.size() !=
fPDG.size() ){
708 if(vec.size() != 1)
return false;
711 vec.resize(
fPDG.size(), vec[0]);
724 std::unique_ptr< std::vector<simb::MCTruth> > truthcol(
new std::vector<simb::MCTruth>);
732 truthcol->push_back(truth);
757 p =
fP0[i] +
fSigmaP[i]*(2.0*flat.fire()-1.0);
761 static TDatabasePDG pdgt;
762 TParticlePDG* pdgp = pdgt.GetParticle(
fPDG[i]);
763 if (pdgp) m = pdgp->Mass();
773 x[0] =
fX0[i] +
fSigmaX[i]*(2.0*flat.fire()-1.0);
774 x[1] =
fY0[i] +
fSigmaY[i]*(2.0*flat.fire()-1.0);
775 x[2] =
fZ0[i] +
fSigmaZ[i]*(2.0*flat.fire()-1.0);
783 t =
fT0[i] +
fSigmaT[i]*(2.0*flat.fire()-1.0);
786 TLorentzVector
pos(x[0], x[1], x[2], t);
793 double thyzradsplussigma = 0;
794 double thyzradsminussigma = 0;
804 thxz = (180./
M_PI)*thetaxz;
805 thyz = (180./
M_PI)*thetayz;
821 double sinthyzmin = std::sin(thyzradsminussigma);
822 double sinthyzmax = std::sin(thyzradsplussigma);
823 double sinthyz = sinthyzmin + flat.fire() * (sinthyzmax - sinthyzmin);
824 thyz = (180. /
M_PI) * std::asin(sinthyz);
827 double thxzrad=thxz*
M_PI/180.0;
828 double thyzrad=thyz*
M_PI/180.0;
830 TLorentzVector pvec(p*std::cos(thyzrad)*std::sin(thxzrad),
832 p*std::cos(thxzrad)*std::cos(thyzrad),
836 int trackid = -1*(i+1);
866 x[0] =
fX0[0] +
fSigmaX[0]*(2.0*flat.fire()-1.0);
867 x[1] =
fY0[0] +
fSigmaY[0]*(2.0*flat.fire()-1.0);
868 x[2] =
fZ0[0] +
fSigmaZ[0]*(2.0*flat.fire()-1.0);
876 t =
fT0[0] +
fSigmaT[0]*(2.0*flat.fire()-1.0);
879 TLorentzVector
pos(x[0], x[1], x[2], t);
882 for (
unsigned int i(0); i<
fPDG.size(); ++i){
893 p =
fP0[i] +
fSigmaP[i]*(2.0*flat.fire()-1.0);
896 static TDatabasePDG pdgt;
897 TParticlePDG* pdgp = pdgt.GetParticle(
fPDG[i]);
898 if (pdgp) m = pdgp->Mass();
906 double thyzradsplussigma = 0;
907 double thyzradsminussigma = 0;
917 thxz = (180./
M_PI)*thetaxz;
918 thyz = (180./
M_PI)*thetayz;
934 double sinthyzmin = std::sin(thyzradsminussigma);
935 double sinthyzmax = std::sin(thyzradsplussigma);
936 double sinthyz = sinthyzmin + flat.fire() * (sinthyzmax - sinthyzmin);
937 thyz = (180. /
M_PI) * std::asin(sinthyz);
940 double thxzrad=thxz*
M_PI/180.0;
941 double thyzrad=thyz*
M_PI/180.0;
943 TLorentzVector pvec(p*std::cos(thyzrad)*std::sin(thxzrad),
945 p*std::cos(thxzrad)*std::cos(thyzrad),
949 int trackid = -1*(i+1);
974 for (
unsigned int i=0; i<
fPDG.size(); ++i) {
984 unsigned int i=flat.fireInt(
fPDG.size());
989 mf::LogWarning(
"UnrecognizeOption") <<
"SingleGen does not recognize ParticleSelectionMode " 1001 mf::LogInfo(
"SingleGen") <<
" You are using vector values for SingleGen configuration.\n " 1002 <<
" Some of the configuration vectors may have been padded out ," 1003 <<
" because they (weren't) as long as the pdg vector" 1004 <<
" in your configuration. \n" 1005 <<
" The new input particle configuration is:\n" ;
1008 for(
size_t i = 0; i <=1; ++i){
1010 values.append(list[i]);
1011 values.append(
": [ ");
1013 for(
size_t e = 0;
e <
fPDG.size(); ++
e){
1014 std::stringstream buf;
1016 if(i == 0 ) buf <<
fPDG[
e] <<
", ";
1018 if(i == 1 ) buf <<
fP0[
e] <<
", ";
1019 if(i == 2 ) buf <<
fSigmaP[
e] <<
", ";
1020 if(i == 3 ) buf <<
fX0[
e] <<
", ";
1021 if(i == 4 ) buf <<
fY0[
e] <<
", ";
1022 if(i == 5 ) buf <<
fZ0[
e] <<
", ";
1023 if(i == 6 ) buf <<
fSigmaX[
e] <<
", ";
1024 if(i == 7 ) buf <<
fSigmaY[
e] <<
", ";
1025 if(i == 8 ) buf <<
fSigmaZ[
e] <<
", ";
1030 if(i == 13) buf <<
fT0[
e] <<
", ";
1031 if(i == 14) buf <<
fSigmaT[
e] <<
", ";
1032 values.append(buf.str());
1035 values.erase(values.find_last_of(
","));
1036 values.append(
" ] \n");
1051 double throw_value = h.Integral() * flat.fire();
1052 double cum_value(0);
1053 for (
int i(0); i < h.GetNbinsX()+1; ++i){
1054 cum_value += h.GetBinContent(i);
1055 if (throw_value < cum_value){
1056 return flat.fire()*h.GetBinWidth(i) + h.GetBinLowEdge(i);
1066 double throw_value = h.Integral() * flat.fire();
1067 double cum_value(0);
1068 for (
int i(0); i < h.GetNbinsX()+1; ++i){
1069 for (
int j(0); j < h.GetNbinsY()+1; ++j){
1070 cum_value += h.GetBinContent(i, j);
1071 if (throw_value < cum_value){
1072 x = flat.fire()*h.GetXaxis()->GetBinWidth(i) + h.GetXaxis()->GetBinLowEdge(i);
1073 y = flat.fire()*h.GetYaxis()->GetBinWidth(j) + h.GetYaxis()->GetBinLowEdge(j);
int fPDist
How to distribute momenta (gaus or uniform)
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
static const std::map< int, std::string > DistributionNames
Names of all distribution modes.
base_engine_t & createEngine(seed_t seed)
int fTDist
How to distribute t (gaus, or uniform)
module to produce single or multiple specified particles in the detector
bool PadVector(std::vector< double > &vec)
static std::string presentOptions(OptionList const &allowedOptions, bool printKey, std::initializer_list< typename OptionList::value_type::first_type > exclude)
Returns a string describing all options in the list.
void AddTrajectoryPoint(TLorentzVector const &position, TLorentzVector const &momentum)
fhicl::Sequence< double > SigmaT
void msg(const char *fmt,...)
static std::map< int, std::string > makeParticleSelectionModeNames()
Returns a vector with the name of particle selection mode keywords.
static std::map< int, std::string > makeDistributionNames()
Returns a vector with the name of distribution keywords.
void SetOrigin(simb::Origin_t origin)
fhicl::Sequence< double > SigmaP
std::vector< std::unique_ptr< TH2 > > hThetaXzYzHist
actual TH1 for momentum distributions
std::vector< double > fSigmaT
Variation in t position (s)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
fhicl::Sequence< double > SigmaThetaXZ
EDProducer(fhicl::ParameterSet const &pset)
std::vector< std::unique_ptr< TH1 > > hPHist
ChannelGroupService::Name Name
fhicl::OptionalAtom< rndm::NuRandomService::seed_t > Seed
std::vector< std::string > fThetaXzYzHist
name of histogram for thetaxz/thetayz distribution
fhicl::Sequence< double > Y0
void SampleOne(unsigned int i, simb::MCTruth &mct)
bool fSingleVertex
if true - all particles produced at the same location
fhicl::Sequence< double > SigmaThetaYZ
fhicl::Sequence< double > SigmaZ
fhicl::Sequence< std::string > ThetaXzYzHist
int fPosDist
How to distribute xyz (gaus, or uniform)
void printVecs(std::vector< std::string > const &list)
fhicl::Sequence< double > P0
art framework interface to geometry description
fhicl::Sequence< double > SigmaY
std::vector< double > fSigmaZ
Variation in z position (cm)
fhicl::Sequence< double > X0
static constexpr int kSelectOneRandPart
fhicl::Sequence< double > Theta0YZ
fhicl::Sequence< double > T0
fhicl::Atom< std::string > HistogramFile
std::vector< double > fT0
Central t position (s) in world coordinates.
fhicl::Atom< std::string > AngleDist
void produce(art::Event &evt) override
#define DEFINE_ART_MODULE(klass)
std::string DetectorName() const
Returns a string with the name of the detector, as configured.
std::vector< double > fP0
Central momentum (GeV/c) to generate.
std::vector< double > fTheta0YZ
Angle in YZ plane (degrees)
single particles thrown at the detector
fhicl::Atom< bool > SingleVertex
fhicl::Sequence< double > SigmaX
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
fhicl::Atom< std::string > ParticleSelectionMode
static constexpr int kSelectAllParts
One particle per entry is generated.
double SelectFromHist(const TH1 &h)
void Sample(simb::MCTruth &mct)
fhicl::Sequence< int > PDG
Description of geometry of one entire detector.
static auto selectOption(std::string Option, OptionList const &allowedOptions) -> decltype(auto)
Parses an option string and returns the corresponding option number.
fhicl::Sequence< double > Theta0XZ
fhicl::Sequence< double > Z0
std::vector< double > fY0
Central y position (cm) in world coordinates.
std::vector< int > fPDG
PDG code of particles to generate.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
std::vector< double > fSigmaThetaYZ
Variation in angle in YZ plane.
std::vector< double > fSigmaP
Variation in momenta (GeV/c)
void Add(simb::MCParticle const &part)
fhicl::Sequence< std::string > PHist
std::vector< double > fZ0
Central z position (cm) in world coordinates.
std::vector< std::string > fPHist
name of histogram of momenta
std::vector< double > fSigmaX
Variation in x position (cm)
fhicl::Atom< std::string > PosDist
static constexpr int kGAUS
Gaussian distribution.
bool fromHistogram(std::string const &key) const
Returns whether the specified mode is an histogram distribution.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::vector< double > fX0
Central x position (cm) in world coordinates.
static std::string optionName(typename OptionList::value_type::first_type optionKey, OptionList const &allowedOptions, std::string defName="<unknown>")
Returns the name of the specified option key, or defName if not known.
Access the description of detector geometry.
static const std::map< int, std::string > ParticleSelectionModeNames
Names of all particle selection modes.
bool file_exists(std::string const &qualified_filename)
std::string fHistFileName
Filename containing histogram of momenta.
int fAngleDist
How to distribute angles (gaus, uniform)
SingleGen(Parameters const &config)
static constexpr int kUNIF
Uniform distribution.
std::vector< double > fTheta0XZ
Angle in XZ plane (degrees)
Event generator information.
void beginRun(art::Run &run) override
Act on begin of run: write "RunData" information (sumdata::RunData).
static std::vector< std::string > const names
static constexpr int kHIST
void setup()
Performs checks and initialization based on the current configuration.
fhicl::Atom< std::string > PDist
Event Generation using GENIE, cosmics or single particles.
fhicl::Atom< bool > PadOutVectors
std::string to_string(ModuleType const mt)
std::vector< double > fSigmaThetaXZ
Variation in angle in XZ plane.
void SampleMany(simb::MCTruth &mct)
cet::coded_exception< error, detail::translate > exception
fhicl::Atom< std::string > TDist
CLHEP::HepRandomEngine & fEngine
actual TH2 for angle distributions - Xz on x axis .
std::vector< double > fSigmaY
Variation in y position (cm)