103using std::ostringstream;
105using namespace genie;
109#ifdef __GENIE_GEOM_DRIVERS_ENABLED__
110#define __CAN_USE_ROOT_GEOM__
111#include <TGeoVolume.h>
112#include <TGeoManager.h>
113#include <TGeoShape.h>
128#ifdef __CAN_USE_ROOT_GEOM__
129void InitBoundingBox (
void);
162#ifdef __CAN_USE_ROOT_GEOM__
163TGeoManager * gOptRootGeoManager = 0;
164TGeoVolume * gOptRootGeoVolume = 0;
194int main(
int argc,
char ** argv)
197 gErrorIgnoreLevel = kWarning;
215 const Decayer * hnlgen =
dynamic_cast< const Decayer *
>( algHNLGen );
218 bool geom_is_accessible = ! (gSystem->AccessPathName(
gOptRootGeom.c_str()));
219 if (!geom_is_accessible) {
221 <<
"The specified ROOT geometry doesn't exist! Initialization failed!";
226 if( !gOptRootGeoManager ) gOptRootGeoManager = TGeoManager::Import(
gOptRootGeom.c_str());
228 TGeoVolume * top_volume = gOptRootGeoManager->GetTopVolume();
229 assert( top_volume );
230 __attribute__((unused)) TGeoShape * ts = top_volume->GetShape();
247 while( stIntChannels.size() > 0 ){
250 std::string tmpSt = stIntChannels.substr( stIntChannels.size()-1, stIntChannels.size() );
251 if( std::strcmp( tmpSt.c_str(),
"1" ) == 0 )
254 stIntChannels.erase( stIntChannels.end()-1, stIntChannels.end() );
265 <<
"Initialised Ntuple Writer";
300 <<
"Initialised MC job monitor";
305#ifdef __CAN_USE_ROOT_GEOM__
318 <<
"\nPlease check ${GENIE}/config/CommonHNL.xml sections \"ParamSpace\" and \"ParticleGun\"";
329 if( ievent % (
gOptNev / 1000 ) == 0 ){
330 int irat = ievent / (
gOptNev / 1000 );
331 std::cerr << 0.1 * irat <<
" % " <<
" ( " << ievent
332 <<
" / " <<
gOptNev <<
" ) \r" << std::flush;
335 if( ievent % (
gOptNev / 10 ) == 0 ){
336 int irat = ievent / (
gOptNev / 10 );
337 std::cerr << 10.0 * irat <<
" % " <<
" ( " << ievent
338 <<
" / " <<
gOptNev <<
" ) \r" << std::flush;
345 <<
" *** Generating event............ " << ievent;
362 <<
"No decay mode specified - sampling from all available modes.";
370 event->AttachSummary(interaction);
378 event->AddParticle( ptHNL );
390 NTP_FS0_E = ((
event->Particle(1))->P4())->E();
391 NTP_FS0_PX = ((
event->Particle(1))->P4())->Px();
392 NTP_FS0_PY = ((
event->Particle(1))->P4())->Py();
393 NTP_FS0_PZ = ((
event->Particle(1))->P4())->Pz();
395 NTP_FS1_E = ((
event->Particle(2))->P4())->E();
396 NTP_FS1_PX = ((
event->Particle(2))->P4())->Px();
397 NTP_FS1_PY = ((
event->Particle(2))->P4())->Py();
398 NTP_FS1_PZ = ((
event->Particle(2))->P4())->Pz();
399 if( event->Particle(3) ){
401 NTP_FS2_E = ((
event->Particle(3))->P4())->E();
402 NTP_FS2_PX = ((
event->Particle(3))->P4())->Px();
403 NTP_FS2_PY = ((
event->Particle(3))->P4())->Py();
404 NTP_FS2_PZ = ((
event->Particle(3))->P4())->Pz();
423 <<
"Generated event: " << *event;
427 mcjmonitor.
Update(ievent,event);
442#ifdef __CAN_USE_ROOT_GEOM__
443void InitBoundingBox(
void)
448 <<
"Initialising geometry bounding box.";
459 bool geom_is_accessible = ! (gSystem->AccessPathName(
gOptRootGeom.c_str()));
460 if (!geom_is_accessible) {
462 <<
"The specified ROOT geometry doesn't exist! Initialization failed!";
466 if( !gOptRootGeoManager ) gOptRootGeoManager = TGeoManager::Import(
gOptRootGeom.c_str());
468 TGeoVolume * top_volume = gOptRootGeoManager->GetTopVolume();
469 assert( top_volume );
470 TGeoShape * ts = top_volume->GetShape();
472 TGeoBBox * box = (TGeoBBox *)ts;
482 fox = (box->GetOrigin())[0];
483 foy = (box->GetOrigin())[1];
484 foz = (box->GetOrigin())[2];
487 <<
"Before conversion the bounding box has:"
488 <<
"\nOrigin = ( " <<
fox <<
" , " <<
foy <<
" , " <<
foz <<
" )"
489 <<
"\nDimensions = " <<
fdx <<
" x " <<
fdy <<
" x " <<
fdz
490 <<
"\n1cm = 1.0 unit";
501 <<
"Initialised bounding box successfully.";
511 double pMag = std::sqrt( E*E - M*M );
514 const Decayer * hnlgen =
dynamic_cast< const Decayer *
>( algHNLGen );
523 double cx = PGDirection.at(0), cy = PGDirection.at(1), cz = PGDirection.at(2);
524 double c2 = std::sqrt( cx*cx + cy*cy + cz*cz );
527 cx *= 1.0 / c2; cy *= 1.0 / c2; cz *= 1.0 / c2;
529 double theta = TMath::ACos( cz / c2 );
530 double phi = ( TMath::Sin( theta ) != 0.0 ) ? TMath::ACos( cx / ( c2 * TMath::Sin( theta ) ) ) : 0.0;
538 double dthetaDeg = PGunDeviation.at(0), dphiDeg = PGunDeviation.at(1);
543 double dTheta = rng->
RndGen().Uniform( -dThetaMax, dThetaMax );
544 double dPhi = rng->
RndGen().Uniform( -dPhiMax, dPhiMax );
546 std::ostringstream asts;
548 <<
"Output details for the momentum:"
549 <<
"\nDirectional cosines: ( " << cx <<
", " << cy <<
", " << cz <<
" )"
551 <<
", " << phi * 180.0 /
constants::kPi <<
" ) [deg] on unit sphere"
552 <<
"\nApplied deviation: dTheta = " << dTheta * 180.0 /
constants::kPi
556 theta += dTheta; phi += dPhi;
557 TLorentzVector * p4HNL =
new TLorentzVector();
558 p4HNL->SetPxPyPzE( pMag * TMath::Sin( theta ) * TMath::Cos( phi ),
559 pMag * TMath::Sin( theta ) * TMath::Sin( phi ),
560 pMag * TMath::Cos( theta ), E );
567 LOG(
"gevgen_pghnl",
pDEBUG ) << asts.str();
576 const Decayer * hnlgen =
dynamic_cast< const Decayer *
>( algHNLGen );
585 double ox = PGOrigin.at(0), oy = PGOrigin.at(1), oz = PGOrigin.at(2);
594 double Dxmax = PGDOrigin.at(0), Dymax = PGDOrigin.at(1), Dzmax = PGDOrigin.at(2);
597 double dx = rng->
RndGen().Uniform( -Dxmax, Dxmax );
598 double dy = rng->
RndGen().Uniform( -Dymax, Dymax );
599 double dz = rng->
RndGen().Uniform( -Dzmax, Dzmax );
602 ox += dx; oy += dy; oz += dz;
603 TLorentzVector * x4HNL =
new TLorentzVector();
604 x4HNL->SetXYZT( ox, oy, oz, 0.0 );
606 event->SetVertex( *x4HNL );
620 TLorentzVector x4 = *(
event->Vertex());
625 TRandom3 & rnd_geo = rnd->
RndGeom();
627 double rndx = 2 * (rnd_geo.Rndm() - 0.5);
628 double rndy = 2 * (rnd_geo.Rndm() - 0.5);
629 double rndz = 2 * (rnd_geo.Rndm() - 0.5);
632 double x_gen =
fox + rndx *
fdx;
633 double y_gen =
foy + rndy *
fdy;
634 double z_gen =
foz + rndz *
fdz;
636 TLorentzVector pos(x_gen, y_gen, z_gen, t_gen);
640 return TLorentzVector( 0, 0, 0, 0);
650 <<
"Instantiating HNL generator.";
659 LOG(
"gevgen_pghnl",
pFATAL) <<
"Couldn't instantiate the HNL generator";
665 <<
"HNL generator instantiated successfully.";
678 <<
"Rest frame CoMLifetime = " <<
CoMLifetime <<
" [GeV^{-1}]";
681 for( std::vector< HNLDecayMode_t >::iterator it = intChannels->begin(); it != intChannels->end(); ++it ){
683 auto mapG = gammaMap.find( mode );
684 double theGamma = mapG->second;
689 std::map< HNLDecayMode_t, double > intMap =
695 std::map< HNLDecayMode_t, double > PMap =
700 double ranThrow = rnd->
RndGen().Uniform( 0., 1. );
705 int decay = ( int ) selectedDecayChan;
711 LOG(
"gevgen_pghnl",
pINFO) <<
"Parsing command line arguments";
726 char * expargv[ argc + 2 ];
727 bool didFindUserInputTune =
false;
731 didFindUserInputTune =
true;
734 <<
"Using input HNL tune " << parser.
ArgAsString(
"tune");
740 for(
int iArg = 0; iArg < argc; iArg++ ){
741 expargv[iArg] = argv[iArg];
743 if( !didFindUserInputTune ){
744 char * chBit =
const_cast< char *
>( stExtraTuneBit.c_str() );
745 std::string stune(
"--tune");
char * tBit =
const_cast< char *
>( stune.c_str() );
746 expargv[argc] = tBit;
747 expargv[argc+1] = chBit;
751 int expargc = ( didFindUserInputTune ) ? argc : argc+2;
752 std::string stnull(
"");
char * nBit =
const_cast< char *
>( stnull.c_str() );
753 expargv[expargc] = nBit;
759 LOG(
"gevgen_pghnl",
pDEBUG) <<
"Reading MC run number";
762 LOG(
"gevgen_pghnl",
pDEBUG) <<
"Unspecified run number - Using default";
769 <<
"Reading number of events to generate";
773 <<
"You need to specify the number of events";
780 const Decayer * hnlgen =
dynamic_cast< const Decayer *
>( algHNLGen );
787 <<
"Reading HNL decay mode";
791 <<
"No decay mode specified - will sample from allowed decay modes";
798 <<
"Specified decay is not allowed kinematically for the given HNL mass";
809#ifdef __CAN_USE_ROOT_GEOM__
812 LOG(
"gevgen_pghnl",
pDEBUG) <<
"Getting input geometry";
816 bool accessible_geom_file =
817 ! (gSystem->AccessPathName(
geom.c_str()));
818 if (accessible_geom_file) {
823 <<
"Geometry option is not a ROOT file. Please use ROOT geom.";
840 <<
"Checking for input geometry length units";
843 LOG(
"gevgen_pghnl",
pDEBUG) <<
"Using default geometry length units";
863 LOG(
"gevgen_pghnl",
pDEBUG) <<
"Reading the event filename prefix";
867 <<
"Will set the default event filename prefix";
873 LOG(
"gevgen_pghnl",
pINFO) <<
"Reading random number seed";
876 LOG(
"gevgen_pghnl",
pINFO) <<
"Unspecified random number seed - Using default";
884 ostringstream gminfo;
886 gminfo <<
"Using ROOT geometry - file: " <<
gOptRootGeom
889 <<
", length units: " <<
lunits;
901 <<
"\n @@ Geometry : " << gminfo.str()
902 <<
"\n @@ Statistics : " <<
gOptNev <<
" events";
909 <<
"\n gevgen_pghnl [-h] "
911 <<
"\n -n n_of_events"
912 <<
"\n [-m decay_mode]"
913 <<
"\n [-g geometry (ROOT file)]"
914 <<
"\n [-L length_units_at_geom]"
915 <<
"\n [-o output_event_file_prefix]"
916 <<
"\n [--seed random_number_seed]"
917 <<
"\n [--message-thresholds xml_file]"
918 <<
"\n [--event-record-print-level level]"
919 <<
"\n [--mc-job-status-refresh-rate rate]"
921 <<
" Please also read the detailed documentation at http://www.genie-mc.org"
922 <<
" or look at the source code: $GENIE/src/Apps/gBeamHNLParticleGun.cxx"
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils.
The GENIE Algorithm Factory.
const Algorithm * GetAlgorithm(const AlgId &algid)
static AlgFactory * Instance()
Algorithm abstract base class.
Command line argument parser.
string ArgAsString(char opt)
bool OptionExists(char opt)
was option set?
Defines the EventRecordVisitorI interface. Concrete implementations of this interface use the 'Visito...
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
STDHEP-like event record entry that can fit a particle or a nucleus.
GENIE's GHEP MC event record.
static void SetPrintLevel(int print_level)
virtual void SetProbability(double prob)
Simple class to create & update MC job status files and env. vars. This is used to be able to keep tr...
void Update(int iev, const EventRecord *event)
void SetRefreshRate(int rate)
void SetProbeP4(const TLorentzVector &P4)
Summary information for an interaction.
InitialState * InitStatePtr(void) const
static Interaction * HNL(int probe, double E=0, int decayed_mode=-1)
A utility class to facilitate creating the GENIE MC Ntuple from the output GENIE GHEP event records.
void Initialize(void)
add event
void Save(void)
get the even tree
void AddEventRecord(int ievent, const EventRecord *ev_rec)
save the event tree
void CustomizeFilenamePrefix(string prefix)
A singleton holding random number generator classes. All random number generation in GENIE should tak...
TRandom3 & RndGeom(void) const
rnd number generator used by geometry drivers
static RandomGen * Instance()
Access instance.
TRandom3 & RndGen(void) const
rnd number generator for generic usage
void ReadFromCommandLine(int argc, char **argv)
static RunOpt * Instance(void)
Heavy Neutral Lepton final-state product generator.
std::vector< double > GetPGunDirection() const
std::vector< double > GetPGunDeviation() const
std::string GetHNLInterestingChannels() const
double GetHNLMass() const
void ProcessEventRecord(GHepRecord *event) const
double GetHNLLifetime() const
bool IsHNLMajorana() const
double GetPGunEnergy() const
std::vector< double > GetPGunDOrigin() const
std::vector< double > GetPGunOrigin() const
std::vector< double > GetHNLCouplings() const
void SetInterestingChannels(const std::map< genie::hnl::HNLDecayMode_t, double > gammaMap)
std::map< genie::hnl::HNLDecayMode_t, double > GetValidChannels()
Heavy Neutral Lepton decay vertex generator given production vertex and momentum ***.
void SetGeomFile(std::string geomfile) const
void ProcessEventRecord(GHepRecord *event_rec) const
string kDefOptEvFilePrefix
NtpMCFormat_t kDefOptNtpFormat
string gOptRootGeomTopVol
HNLDecayMode_t gOptDecayMode
std::vector< HNLDecayMode_t > gOptIntChannels
TLorentzVector GeneratePosition(GHepRecord *event)
TLorentzVector * GenerateOriginPosition(GHepRecord *event)
const EventRecordVisitorI * HNLGenerator(void)
int SelectDecayMode(std::vector< HNLDecayMode_t > *intChannels, SimpleHNL sh)
void GetCommandLineArgs(int argc, char **argv)
TLorentzVector * GenerateOriginMomentum(GHepRecord *event)
genie::hnl::HNLDecayMode_t SelectChannelInclusive(std::map< genie::hnl::HNLDecayMode_t, double > Pmap, double ranThrow)
std::map< genie::hnl::HNLDecayMode_t, double > SetInterestingChannels(std::vector< genie::hnl::HNLDecayMode_t > intChannels, std::map< genie::hnl::HNLDecayMode_t, double > gammaMap)
std::map< genie::hnl::HNLDecayMode_t, double > GetProbabilities(std::map< genie::hnl::HNLDecayMode_t, double > gammaMap)
enum genie::hnl::EHNLDecayMode HNLDecayMode_t
void RandGen(long int seed)
void MesgThresholds(string inpfile)
string AsString(genie::hnl::HNLDecayMode_t hnldm)
bool IsKinematicallyAllowed(genie::hnl::HNLDecayMode_t hnldm, double Mhnl)
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f=' *')
string P4AsString(const TLorentzVector *p)
double UnitFromString(string u)
THE MAIN GENIE PROJECT NAMESPACE
enum genie::ENtpMCFormat NtpMCFormat_t