1 #include "Framework/Conventions/GBuild.h" 2 #ifdef __GENIE_INCL_ENABLED__ 14 #include "G4INCLConfig.hh" 15 #include "G4INCLCascade.hh" 16 #include "G4INCLConfigEnums.hh" 17 #include "G4INCLParticle.hh" 19 #include "G4INCLSignalHandling.hh" 22 #include "G4INCLIDeExcitation.hh" 25 #ifdef INCL_DEEXCITATION_ABLAXX 26 #include "G4INCLAblaInterface.hh" 30 #ifdef INCL_DEEXCITATION_ABLA07 31 #include "G4INCLAbla07Interface.hh" 35 #ifdef INCL_DEEXCITATION_SMM 36 #include "G4INCLSMMInterface.hh" 40 #ifdef INCL_DEEXCITATION_GEMINIXX 41 #include "G4INCLGEMINIXXInterface.hh" 49 #ifdef HAS_BOOST_TIMER 50 #include <boost/timer/timer.hpp> 51 namespace bt = boost::timer;
70 using namespace genie;
72 using namespace G4INCL;
73 using std::ostringstream;
76 HINCLCascadeIntranuke::HINCLCascadeIntranuke() :
78 theINCLConfig(0), theINCLModel(0), theDeExcitation(0)
85 HINCLCascadeIntranuke::HINCLCascadeIntranuke(
string config) :
87 theINCLConfig(0), theINCLModel(0), theDeExcitation(0)
90 <<
"ctor from config " <<
config;
94 HINCLCascadeIntranuke::~HINCLCascadeIntranuke()
98 if ( theINCLConfig ) { theINCLConfig=0; }
99 if ( theINCLModel ) {
delete theINCLModel; theINCLModel=0; }
100 if ( theDeExcitation ) {
delete theDeExcitation; theDeExcitation=0; }
105 void HINCLCascadeIntranuke::LoadConfig(
void)
107 LOG(
"HINCLCascadeIntranuke",
pINFO) <<
"Settings for INCL++ mode: " ;
109 #ifdef INCL_SIGNAL_HANDLING 110 enableSignalHandling();
114 if ( theINCLConfig ) { theINCLConfig=0; }
115 if ( theINCLModel ) {
delete theINCLModel; theINCLModel=0; }
116 if ( theDeExcitation ) {
delete theDeExcitation; theDeExcitation=0; }
118 INCLConfigParser theParser;
120 size_t maxFlags = 200;
122 char * flags[maxFlags];
126 flags[nflags] = strdup(infile.c_str()); ++nflags;
130 flags[nflags] = strdup(pflag.c_str()); ++nflags;
134 flags[nflags] = strdup(tflag.c_str()); ++nflags;
138 flags[nflags] = strdup(Nflag.c_str()); ++nflags;
142 flags[nflags] = strdup(Eflag.c_str()); ++nflags;
146 flags[nflags] = strdup(dflag.c_str()); ++nflags;
152 for (
size_t j=0; j < extraTokens.size(); ++j) {
156 flags[nflags] = strdup(token.c_str()); ++nflags;
161 <<
"LoadConfig() create theINCLConfig";
162 theINCLConfig = theParser.parse(nflags,flags);
167 bool updateNeeded = AddDataPathFlags(nflags,flags);
169 delete theINCLConfig;
170 theINCLConfig = theParser.parse(nflags,flags);
174 <<
"doCascade new G4INCL::INCL";
175 theINCLModel =
new G4INCL::INCL(theINCLConfig);
179 switch(theINCLConfig->getDeExcitationType()) {
180 #ifdef INCL_DEEXCITATION_ABLAXX 181 case G4INCL::DeExcitationABLAv3p:
182 theDeExcitation =
new G4INCLAblaInterface(theINCLConfig);
184 <<
"using ABLAv3p for DeExcitation";
187 #ifdef INCL_DEEXCITATION_ABLA07 188 case G4INCL::DeExcitationABLA07:
189 theDeExcitation =
new ABLA07CXX::Abla07Interface(theINCLConfig);
191 <<
"using ABLA07CXX for DeExcitation";
194 #ifdef INCL_DEEXCITATION_SMM 195 case G4INCL::DeExcitationSMM:
196 theDeExcitation =
new SMMCXX::SMMInterface(theINCLConfig);
198 <<
"using SMMCXX for DeExcitation";
201 #ifdef INCL_DEEXCITATION_GEMINIXX 202 case G4INCL::DeExcitationGEMINIXX:
203 theDeExcitation =
new G4INCLGEMINIXXInterface(theINCLConfig);
205 <<
"using GEMINIXX for DeExcitation";
209 std::stringstream ss;
210 ss <<
"########################################################\n" 211 <<
"### WARNING WARNING WARNING ###\n" 213 <<
"### You are running the code without any coupling to ###\n" 214 <<
"### a de-excitation model! ###\n" 215 <<
"### Results will be INCOMPLETE and UNPHYSICAL! ###\n" 216 <<
"### Are you sure this is what you want to do? ###\n" 217 <<
"########################################################\n";
226 for (
size_t i=0; i < nflags; ++i) {
235 bool HINCLCascadeIntranuke::AddDataPathFlags(
size_t& nflags,
char** flags) {
238 bool needed_update =
false;
239 size_t nflags_in = nflags;
242 std::vector<std::string> datapaths;
245 <<
"check for data location of INCL";
248 datapaths.push_back(theINCLConfig->getINCLXXDataFilePath());
249 datapaths.push_back(
"!INCL-incl-data-alt1");
250 datapaths.push_back(
"!INCL-incl-data-alt2");
252 LookForAndAddValidPath(datapaths,0,
"--inclxx-datafile-path",nflags,flags);
254 switch(theINCLConfig->getDeExcitationType()) {
255 #ifdef INCL_DEEXCITATION_ABLAXX 256 case G4INCL::DeExcitationABLAv3p:
258 <<
"using ABLAv3p for DeExcitation -- check for data location";
260 datapaths.push_back(theINCLConfig->getABLAv3pCxxDataFilePath());
261 datapaths.push_back(
"!INCL-ablav3p-data-alt1");
262 datapaths.push_back(
"!INCL-ablav3p-data-alt2");
264 LookForAndAddValidPath(datapaths,0,
"--ablav3p-cxx-datafile-path",nflags,flags);
267 #ifdef INCL_DEEXCITATION_ABLA07 268 case G4INCL::DeExcitationABLA07:
270 <<
"using ABLA07 for DeExcitation -- check for data location";
272 datapaths.push_back(theINCLConfig->getABLA07DataFilePath());
273 datapaths.push_back(
"!INCL-abla07-data-alt1");
274 datapaths.push_back(
"!INCL-abla07-data-alt2");
276 LookForAndAddValidPath(datapaths,0,
"--abla07-datafile-path",nflags,flags);
279 #ifdef INCL_DEEXCITATION_SMM 280 case G4INCL::DeExcitationSMM:
282 <<
"using SMMCXX for DeExcitation -- no data files to check for";
285 #ifdef INCL_DEEXCITATION_GEMINIXX 286 case G4INCL::DeExcitationGEMINIXX:
288 <<
"using GEMINIXX for DeExcitation -- check for data location";
290 datapaths.push_back(theINCLConfig->getGEMINIXXDataFilePath());
291 datapaths.push_back(
"!INCL-gemini-data-alt1");
292 datapaths.push_back(
"!INCL-gemini-data-alt2");
294 LookForAndAddValidPath(datapaths,0,
"--geminixx-datafile-path",nflags,flags);
299 <<
"using no DeExcitation -- no data files to check for";
304 std::stringstream ss;
305 for (
size_t i=0; i < nflags; ++i) {
306 if ( i == nflags_in ) ss <<
"---- list prior to AddDataPathFlags()\n";
307 ss <<
"[" <<
setw(3) << i <<
"] " << flags[i] <<
'\n';
310 <<
"Flags passed to INCLConfigParser" 313 return needed_update;
317 bool HINCLCascadeIntranuke::LookForAndAddValidPath(std::vector<std::string>& datapaths,
319 const char* optString,
320 size_t& nflags,
char** flags) {
332 bool needed_update =
false;
335 <<
"looking for a valid path for " << optString
336 <<
" (default [" << defaultIndx <<
"]";
338 size_t foundIndx = SIZE_MAX;
339 size_t npaths = datapaths.size();
340 for (
size_t ipath = 0; ipath < npaths; ++ipath) {
343 <<
"looking at " << apath;
344 if ( apath.at(0) ==
'!' ) {
352 <<
"fetch param "<<
"[" << ipath <<
"] "<< apath <<
" got " << newpath;
355 const char* expandedPath = gSystem->ExpandPathName(apath.c_str());
356 if ( ! expandedPath ) {
358 <<
"expandedPath was NULL";
363 <<
"expandedPath " << expandedPath <<
" " 364 << ((valid)?
"valid":
"doesn't exist");
371 if ( foundIndx == defaultIndx ) {
373 }
else if ( foundIndx > npaths-1 ) {
375 std::stringstream ss;
376 for (
size_t ipath = 0; ipath < npaths; ++ipath) {
378 ss <<
"[" << ipath <<
"] " << apath <<
"\n";
381 <<
"no valid path found for " << optString
382 <<
", tried: \n" << ss.str();
385 flags[nflags] = strdup(optString); ++nflags;
386 flags[nflags] = strdup(datapaths[foundIndx].c_str()); ++nflags;
387 needed_update =
true;
390 return needed_update;
394 int HINCLCascadeIntranuke::doCascade(
GHepRecord * evrec)
const {
396 if ( ! theINCLConfig || ! theINCLModel )
return 0;
402 const ParticleType theType = toINCLparticletype(pprobe->
Pdg());
404 double E = (pprobe->
E())*1000;
405 double massp = G4INCL::ParticleTable::getRealMass(theType);
406 double EKin = E - massp;
408 G4INCL::ParticleSpecies theSpecies;
409 theSpecies.theType = theType;
410 theSpecies.theA = pdgcpiontoA(pprobe->
Pdg());
411 theSpecies.theZ = pdgcpiontoZ(pprobe->
Pdg());
415 int pdg_codeProbe = 0;
416 pdg_codeProbe = INCLpartycleSpecietoPDGCODE(theSpecies);
419 result = theINCLModel->processEvent(theSpecies,EKin,target->
A(),target->
Z());
421 double m_target = ParticleTable::getTableMass(result.At, result.Zt);
424 TLorentzVector p4h (0.,0.,fsProbe->
Pz(),fsProbe->
E());
425 TLorentzVector x4null(0.,0.,0.,0.);
426 TLorentzVector p4tgt (0.,0.,0.,m_target/1000);
429 if ( result.transparent ) {
430 evrec->
AddParticle(pdg_codeProbe, ist1, 0,-1,-1,-1, p4h,x4null);
432 INCL_DEBUG(
"Transparent event" <<
std::endl);
434 INCL_DEBUG(
"Number of produced particles: " << result.nParticles <<
"\n");
435 if ( theDeExcitation != 0 ) {
436 theDeExcitation->deExcite(&result);
439 for (
int nP = 0; nP < result.nParticles; nP++){
440 if ( nP == result.nParticles-1 ) {
457 void HINCLCascadeIntranuke::ProcessEventRecord(
GHepRecord * evrec)
const {
460 <<
"************ Running HINCLCascadeIntranuke MODE INTRANUKE ************";
465 HINCLCascadeIntranuke::doCascade(evrec);
467 HINCLCascadeIntranuke::TransportHadrons(evrec);
470 LOG(
"HINCLCascadeIntranuke",
pINFO) <<
"Done with this event";
473 bool HINCLCascadeIntranuke::CanRescatter(
const GHepParticle *
p)
const {
486 void HINCLCascadeIntranuke::TransportHadrons(
GHepRecord * evrec)
const {
501 <<
"Propagating hadrons within nucleus found in position = " << inucl;
507 <<
"No nucleus found in position = " << inucl;
514 int A_f(0), Z_f(0), Aft(0), A_i(target->
A()),Z_i(target->
Z());
517 <<
"Nucleus (A,Z) = (" <<
fRemnA <<
", " <<
fRemnZ <<
")";
519 const TLorentzVector & p4nucl = *(nucl->
P4());
520 TLorentzVector x4null(0.,0.,0.,0.);
523 TObjArrayIter piter(evrec);
530 TLorentzVector * p_4 = nucl->
P4();
532 double pxRemn = p_4->Px();
533 double pyRemn = p_4->Py();
534 double pzRemn = p_4->Pz();
536 TLorentzVector p4tgf(p_4->Px(),p_4->Py(),p_4->Pz(),0.0);
539 std::vector<G4INCL::EventInfo>ListeOfINCLresult;
540 std::vector<int> Postion_evrec;
542 double ExcitaionE(0), the_pxRemn(0), the_pyRemn(0), the_pzRemn(0);
543 int Zl(0), Aresult(0), Zresult(0), Aexception(0), Zexception(0),
544 Pos(0), theA_Remn(0), theZ_Remn(0);
546 if ( fsl->
Charge() == 0. ) Zl = 0;
547 if ( fsl->
Charge() < 0. ) Zl = -1;
548 if ( fsl->
Charge() > 0. ) Zl = 1;
549 bool has_remnant =
false;
566 <<
"... Current version can't rescatter a " << sp->
Name();
574 TLorentzVector *v4= sp->
GetX4();
578 thePosition.setX(v4->X());
579 thePosition.setY(v4->Y());
580 thePosition.setZ(v4->Z());
581 TLorentzVector * p4 = sp->
P4();
587 int pdgc = sp->
Pdg();
589 const ParticleType theType = toINCLparticletype(pdgc);
591 if ( theType == G4INCL::UnknownParticle) {
600 double E = (p4->Energy())*1000;
601 double massp = G4INCL::ParticleTable::getRealMass(theType);
603 double EKin = E - massp;
605 G4INCL::ParticleSpecies theSpecies;
606 theSpecies.theType=theType;
607 theSpecies.theA=pdgcpiontoA(sp->
Pdg());
608 theSpecies.theZ=pdgcpiontoZ(sp->
Pdg());
610 G4INCL::Particle *pincl =
611 new G4INCL::Particle( theType , E ,
momentum, thePosition);
614 G4INCL::Random::getSeeds();
616 G4INCL::Random::saveSeeds();
619 result=theINCLModel->processEvent(theSpecies,pincl,EKin,
fRemnA,fRemnZ,
"FSI");
622 Aresult += (
fRemnA + pdgcpiontoA(sp->
Pdg())- result.ARem[0]);
623 Zresult += (fRemnZ + pdgcpiontoZ(sp->
Pdg())- result.ZRem[0]);
624 Aexception = A_i - Aresult;
625 Zexception = Z_i - Zresult;
626 bool AZexception(
false);
627 if ( Zexception <= 0 || Aexception <= 0 || Aexception<=Zexception) {
629 Zl+=pdgcpiontoZ(sp->
Pdg());
630 Aft+=pdgcpiontoA(sp->
Pdg());
635 for (
size_t it=0; it<ListeOfINCLresult.size();it++){
636 Pos = Postion_evrec.at(it);
638 theA_Remn+= (
fRemnA + pdgcpiontoA(pinthenucleus->
Pdg())- ListeOfINCLresult.at(it).ARem[0]);
639 theZ_Remn+= (fRemnZ + pdgcpiontoZ(pinthenucleus->
Pdg())- ListeOfINCLresult.at(it).ZRem[0]);
640 if ( (A_i-theA_Remn-Aft) < (Z_i-theZ_Remn-Zl) ) {
641 theA_Remn-= (
fRemnA + pdgcpiontoA(pinthenucleus->
Pdg())- ListeOfINCLresult.at(it).ARem[0]);
642 theZ_Remn-= (fRemnZ + pdgcpiontoZ(pinthenucleus->
Pdg())- ListeOfINCLresult.at(it).ZRem[0]);
643 Zl+=pdgcpiontoZ(pinthenucleus->
Pdg());
644 Aft+=pdgcpiontoA(pinthenucleus->
Pdg());
650 the_pxRemn+=ListeOfINCLresult.at(it).pxRem[0];
651 the_pyRemn+=ListeOfINCLresult.at(it).pyRem[0];
652 the_pzRemn+=ListeOfINCLresult.at(it).pzRem[0];
653 ExcitaionE+=ListeOfINCLresult.at(it).EStarRem[0];
656 if ( AZexception ) ListeOfINCLresult.pop_back();
657 for (
size_t it=0; it<ListeOfINCLresult.size();it++){
659 if ( it < ListeOfINCLresult.size()-1 ) {
660 for (
int nP=0; nP < ListeOfINCLresult.at(it).nParticles; nP++ ) {
661 GHepParticle *p_outD = INCLtoGenieParticle(ListeOfINCLresult.at(it),
667 ListeOfINCLresult.at(it).ARem[0]=A_i-theA_Remn- Aft;
668 ListeOfINCLresult.at(it).ZRem[0]=Z_i-theZ_Remn- Zl;
670 ListeOfINCLresult.at(it).pxRem[0]= the_pxRemn + (pxRemn*1000);
671 ListeOfINCLresult.at(it).pyRem[0]= the_pyRemn + (pyRemn*1000);
672 ListeOfINCLresult.at(it).pzRem[0]= the_pzRemn + (1000*pzRemn);
673 ListeOfINCLresult.at(it).EStarRem[0]=ExcitaionE;
674 theDeExcitation->deExcite(&ListeOfINCLresult.at(it));
675 for (
int nP=0;nP<ListeOfINCLresult.at(it).nParticles;nP++ ) {
676 GHepParticle *p_outFinal = INCLtoGenieParticle(ListeOfINCLresult.at(it),
684 ListeOfINCLresult.clear();
688 if ( result.transparent ) {
689 Zl+=pdgcpiontoZ(sp->
Pdg());
690 Aft+=pdgcpiontoA(sp->
Pdg());
696 Postion_evrec.push_back(icurr);
697 ListeOfINCLresult.push_back(result);
705 if ( ListeOfINCLresult.size() != 0 ) {
706 bool AZexception(
false);
707 for (
size_t it=0; it<ListeOfINCLresult.size();it++){
708 Pos = Postion_evrec.at(it);
710 theA_Remn+= (
fRemnA + pdgcpiontoA(pinthenucleus->
Pdg())- ListeOfINCLresult.at(it).ARem[0]);
711 theZ_Remn+= (fRemnZ + pdgcpiontoZ(pinthenucleus->
Pdg())- ListeOfINCLresult.at(it).ZRem[0]);
712 if ( (A_i-theA_Remn-Aft) < (Z_i-theZ_Remn-Zl) ) {
713 theA_Remn-= (
fRemnA + pdgcpiontoA(pinthenucleus->
Pdg())- ListeOfINCLresult.at(it).ARem[0]);
714 theZ_Remn-= (fRemnZ + pdgcpiontoZ(pinthenucleus->
Pdg())- ListeOfINCLresult.at(it).ZRem[0]);
715 Zl+=pdgcpiontoZ(pinthenucleus->
Pdg());
716 Aft+=pdgcpiontoA(pinthenucleus->
Pdg());
722 the_pxRemn+=ListeOfINCLresult.at(it).pxRem[0];
723 the_pyRemn+=ListeOfINCLresult.at(it).pyRem[0];
724 the_pzRemn+=ListeOfINCLresult.at(it).pzRem[0];
725 ExcitaionE+=ListeOfINCLresult.at(it).EStarRem[0];
728 if (AZexception) ListeOfINCLresult.pop_back();
729 for (
size_t it=0; it < ListeOfINCLresult.size(); it++) {
732 ListeOfINCLresult.at(it).pxRem[0] += pxRemn*1000;
733 ListeOfINCLresult.at(it).pyRem[0] += pyRemn*1000;
734 ListeOfINCLresult.at(it).pzRem[0] += 1000*pzRemn;
735 if ( theDeExcitation != 0 ) theDeExcitation->deExcite(&ListeOfINCLresult.at(it));
736 for (
int nP=0; nP < ListeOfINCLresult.at(it).nParticles; nP++ ) {
737 GHepParticle *p_out = INCLtoGenieParticle(ListeOfINCLresult.at(it),
743 if ( it < ListeOfINCLresult.size()-1 ) {
744 for (
int nP=0; nP < ListeOfINCLresult.at(it).nParticles; nP++ ) {
745 A_f+=ListeOfINCLresult.at(it).A[nP];
746 Z_f+=ListeOfINCLresult.at(it).Z[nP];
753 ListeOfINCLresult.at(it).ARem[0]=A_i-theA_Remn-Aft;
754 ListeOfINCLresult.at(it).ZRem[0]=Z_i-theZ_Remn-Zl;
755 ListeOfINCLresult.at(it).pxRem[0]= the_pxRemn + (pxRemn*1000);
756 ListeOfINCLresult.at(it).pyRem[0]= the_pyRemn + (pyRemn*1000);
757 ListeOfINCLresult.at(it).pzRem[0]= the_pzRemn + (1000*pzRemn);
758 ListeOfINCLresult.at(it).EStarRem[0]=ExcitaionE;
759 if ( theDeExcitation != 0 ) theDeExcitation->deExcite(&ListeOfINCLresult.at(it));
760 for (
int nP=0; nP < ListeOfINCLresult.at(it).nParticles; nP++ ) {
761 A_f+=ListeOfINCLresult.at(it).A[nP];
762 Z_f+=ListeOfINCLresult.at(it).Z[nP];
763 GHepParticle *p_outR = INCLtoGenieParticle(ListeOfINCLresult.at(it),
773 if ( ListeOfINCLresult.size() == 0 && !has_remnant) {
781 int HINCLCascadeIntranuke::pdgcpiontoA(
int pdgc)
const {
783 if ( pdgc == 2212 || pdgc == 2112 )
return 1;
784 else if ( pdgc == 211 || pdgc == -211 || pdgc == 111 )
return 0;
790 int HINCLCascadeIntranuke::pdgcpiontoZ(
int pdgc)
const {
792 if ( pdgc == 2212 || pdgc == 211 )
return 1;
793 else if ( pdgc == 2112 || pdgc == 111 )
return 0;
794 else if ( pdgc == -211 )
return -1;
800 bool HINCLCascadeIntranuke::NeedsRescattering(
const GHepParticle * p)
const {
813 <<
"Configure from Registry: '" << config.
Name() <<
"'\n" 825 <<
"Configure from param_set name: " << param_set;
832 #endif // __GENIE_INCL_ENABLED__
void SetFirstMother(int m)
virtual GHepParticle * Particle(int position) const
TLorentzVector * GetX4(void) const
THE MAIN GENIE PROJECT NAMESPACE
double E(void) const
Get energy.
virtual Interaction * Summary(void) const
const TLorentzVector * P4(void) const
Defines the EventRecordVisitorI interface. Concrete implementations of this interface use the 'Visito...
virtual int RemnantNucleusPosition(void) const
bool IsQuasiElastic(void) const
int fRemnA
remnant nucleus A
bool CanRescatter(const GHepParticle *p) const
double Pz(void) const
Get Pz.
GHepStatus_t Status(void) const
GEvGenMode_t fGMode
event generation mode (lepton+A, hadron+A, ...)
virtual GHepParticle * Probe(void) const
string Name(void) const
get the registry name
string Name(void) const
Name that corresponds to the PDG code.
std::vector< art::Ptr< recob::Seed > > SeedVector
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
virtual GHepParticle * FinalStatePrimaryLepton(void) const
virtual void Configure(const Registry &config)
GEvGenMode_t EventGenerationMode(void) const
bool NeedsRescattering(const GHepParticle *p) const
double Charge(void) const
Chrg that corresponds to the PDG code.
Q_EXPORT QTSManip setw(int w)
vector< string > Split(string input, string delim)
bool DirectoryExists(const char *path)
void SetStatus(GHepStatus_t s)
A registry. Provides the container for algorithm configuration parameters.
void Configure(string mesg)
int IonPdgCode(int A, int Z)
virtual void AddParticle(const GHepParticle &p)
const ProcessInfo & ProcInfo(void) const
std::string nucl(const std::string &A, const std::string &elem)
bool GetParamDef(const RgKey &name, T &p, const T &def) const
def momentum(x1, x2, x3, scale=1.)
GENIE's GHEP MC event record.
STDHEP-like event record entry that can fit a particle or a nucleus.
virtual int TargetNucleusPosition(void) const
Root of GENIE utility namespaces.
QTextStream & endl(QTextStream &s)
enum genie::EGHepStatus GHepStatus_t
int fRemnZ
remnant nucleus Z
TLorentzVector fRemnP4
P4 of remnant system.