HINCLCascadeIntranuke.cxx
Go to the documentation of this file.
1 #include "Framework/Conventions/GBuild.h"
2 #ifdef __GENIE_INCL_ENABLED__
3 
4 //---------------------
5 #include <iostream>
6 #include <iomanip>
7 #include <string>
8 #include <sstream>
9 
10 // GENIE
11 #include "HINCLCascadeIntranuke.h"
12 
13 // INCL++
14 #include "G4INCLConfig.hh"
15 #include "G4INCLCascade.hh"
16 #include "G4INCLConfigEnums.hh"
17 #include "G4INCLParticle.hh"
18 // signal handler (for Linux and GCC)
19 #include "G4INCLSignalHandling.hh"
20 
21 // Generic de-excitation interface
22 #include "G4INCLIDeExcitation.hh"
23 
24 // ABLA v3p de-excitation
25 #ifdef INCL_DEEXCITATION_ABLAXX
26 #include "G4INCLAblaInterface.hh"
27 #endif
28 
29 // ABLA07 de-excitation
30 #ifdef INCL_DEEXCITATION_ABLA07
31 #include "G4INCLAbla07Interface.hh"
32 #endif
33 
34 // SMM de-excitation
35 #ifdef INCL_DEEXCITATION_SMM
36 #include "G4INCLSMMInterface.hh"
37 #endif
38 
39 // GEMINIXX de-excitation
40 #ifdef INCL_DEEXCITATION_GEMINIXX
41 #include "G4INCLGEMINIXXInterface.hh"
42 #endif
43 
44 //#ifdef HAS_BOOST_DATE_TIME
45 //#include <boost/date_time/posix_time/posix_time.hpp>
46 //namespace bpt = boost::posix_time;
47 //#endif
48 
49 #ifdef HAS_BOOST_TIMER
50 #include <boost/timer/timer.hpp>
51 namespace bt = boost::timer;
52 #endif
53 
54 
55 // --------------------------------------Include for GENIE---------------------
56 // GENIE
57 #include "INCLConvertParticle.hh"
58 #include "INCLConfigParser.h"
59 // INCL++
60 //#include "ConfigParser.hh"
61 
66 
67 // ROOT
68 #include "TSystem.h"
69 
70 using namespace genie;
71 using namespace genie::utils;
72 using namespace G4INCL;
73 using std::ostringstream;
74 using namespace std;
75 
76 HINCLCascadeIntranuke::HINCLCascadeIntranuke() :
77  EventRecordVisitorI("genie::HINCLCascadeIntranuke"),
78  theINCLConfig(0), theINCLModel(0), theDeExcitation(0)
79 {
80  LOG("HINCLCascadeIntranuke", pDEBUG)
81  << "default ctor";
82 }
83 
84 //______________________________________________________________________________
85 HINCLCascadeIntranuke::HINCLCascadeIntranuke(string config) :
86  EventRecordVisitorI("genie::HINCLCascadeIntranuke", config),
87  theINCLConfig(0), theINCLModel(0), theDeExcitation(0)
88 {
89  LOG("HINCLCascadeIntranuke", pDEBUG)
90  << "ctor from config " << config;
91 }
92 
93 //______________________________________________________________________________
94 HINCLCascadeIntranuke::~HINCLCascadeIntranuke()
95 {
96 
97  // Config is owned by model once handed over
98  if ( theINCLConfig ) { theINCLConfig=0; }
99  if ( theINCLModel ) { delete theINCLModel; theINCLModel=0; }
100  if ( theDeExcitation ) { delete theDeExcitation; theDeExcitation=0; }
101 
102 }
103 
104 //______________________________________________________________________________
105 void HINCLCascadeIntranuke::LoadConfig(void)
106 {
107  LOG("HINCLCascadeIntranuke", pINFO) << "Settings for INCL++ mode: " ;
108 
109 #ifdef INCL_SIGNAL_HANDLING
110  enableSignalHandling();
111 #endif
112 
113  // Config is owned by model once handed over
114  if ( theINCLConfig ) { theINCLConfig=0; }
115  if ( theINCLModel ) { delete theINCLModel; theINCLModel=0; }
116  if ( theDeExcitation ) { delete theDeExcitation; theDeExcitation=0; }
117 
118  INCLConfigParser theParser;
119 
120  size_t maxFlags = 200;
121  size_t nflags = 0;
122  char * flags[maxFlags]; // note non-const'ness desired by ConfigParser
123 
125  GetParamDef( "INCL-infile", infile, std::string("NULL"));
126  flags[nflags] = strdup(infile.c_str()); ++nflags;
127 
128  std::string pflag;
129  GetParamDef( "INCL-pflag", pflag, std::string("-pp"));
130  flags[nflags] = strdup(pflag.c_str()); ++nflags;
131 
132  std::string tflag;
133  GetParamDef( "INCL-tflag", tflag, std::string("-tFe56"));
134  flags[nflags] = strdup(tflag.c_str()); ++nflags;
135 
136  std::string Nflag;
137  GetParamDef( "INCL-Nflag", Nflag, std::string("-N1"));
138  flags[nflags] = strdup(Nflag.c_str()); ++nflags;
139 
140  std::string Eflag;
141  GetParamDef( "INCL-Eflag", Eflag, std::string("-E1"));
142  flags[nflags] = strdup(Eflag.c_str()); ++nflags;
143 
144  std::string dflag;
145  GetParamDef( "INCL-dflag", dflag, std::string("-dABLA07"));
146  flags[nflags] = strdup(dflag.c_str()); ++nflags;
147 
148  // arbitary extra flags, need to be tokenized
149  std::string extra_incl_flags;
150  GetParamDef( "INCL-extra-flags", extra_incl_flags, std::string(""));
151  std::vector<std::string> extraTokens = genie::utils::str::Split(extra_incl_flags," \t\n");
152  for (size_t j=0; j < extraTokens.size(); ++j) {
153  std::string& token = extraTokens[j];
154  if ( token != "" ) {
155  // don't add empty strings
156  flags[nflags] = strdup(token.c_str()); ++nflags;
157  }
158  }
159 
160  LOG("HINCLCascadeIntranuke", pDEBUG)
161  << "LoadConfig() create theINCLConfig";
162  theINCLConfig = theParser.parse(nflags,flags);
163 
164  // there's currently no way to update *all* of the data paths in the Config
165  // after it's been generated, so check whether default file paths "work",
166  // add to the flags if necessary, and then regenerate
167  bool updateNeeded = AddDataPathFlags(nflags,flags);
168  if (updateNeeded) {
169  delete theINCLConfig;
170  theINCLConfig = theParser.parse(nflags,flags);
171  }
172 
173  LOG("HINCLCascadeIntranuke", pDEBUG)
174  << "doCascade new G4INCL::INCL";
175  theINCLModel = new G4INCL::INCL(theINCLConfig);
176 
177  // code copied fomr INCL's main/src/INCLCascade.cc
178  // with additions for GENIE messenger system
179  switch(theINCLConfig->getDeExcitationType()) {
180 #ifdef INCL_DEEXCITATION_ABLAXX
181  case G4INCL::DeExcitationABLAv3p:
182  theDeExcitation = new G4INCLAblaInterface(theINCLConfig);
183  LOG("HINCLCascadeIntranuke", pINFO)
184  << "using ABLAv3p for DeExcitation";
185  break;
186 #endif
187 #ifdef INCL_DEEXCITATION_ABLA07
188  case G4INCL::DeExcitationABLA07:
189  theDeExcitation = new ABLA07CXX::Abla07Interface(theINCLConfig);
190  LOG("HINCLCascadeIntranuke", pINFO)
191  << "using ABLA07CXX for DeExcitation";
192  break;
193 #endif
194 #ifdef INCL_DEEXCITATION_SMM
195  case G4INCL::DeExcitationSMM:
196  theDeExcitation = new SMMCXX::SMMInterface(theINCLConfig);
197  LOG("HINCLCascadeIntranuke", pINFO)
198  << "using SMMCXX for DeExcitation";
199  break;
200 #endif
201 #ifdef INCL_DEEXCITATION_GEMINIXX
202  case G4INCL::DeExcitationGEMINIXX:
203  theDeExcitation = new G4INCLGEMINIXXInterface(theINCLConfig);
204  LOG("HINCLCascadeIntranuke", pINFO)
205  << "using GEMINIXX for DeExcitation";
206  break;
207 #endif
208  default:
209  std::stringstream ss;
210  ss << "########################################################\n"
211  << "### WARNING WARNING WARNING ###\n"
212  << "### ###\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";
218  INCL_INFO(ss.str());
219  LOG("HINCLCascadeIntranuke", pWARN)
220  << '\n' << ss.str();
221  //std::cout << ss.str();
222  break;
223  }
224 
225  // try not to leak strings
226  for (size_t i=0; i < nflags; ++i) {
227  char * p = flags[i];
228  free(p);
229  flags[i] = 0;
230  }
231 
232 }
233 
234 //______________________________________________________________________________
235 bool HINCLCascadeIntranuke::AddDataPathFlags(size_t& nflags, char** flags) {
236 
237  // check if the default INCL path works
238  bool needed_update = false;
239  size_t nflags_in = nflags;
240 
241  std::string validpath;
242  std::vector<std::string> datapaths;
243 
244  LOG("HINCLCascadeIntranuke", pINFO)
245  << "check for data location of INCL";
246 
247  datapaths.clear();
248  datapaths.push_back(theINCLConfig->getINCLXXDataFilePath());
249  datapaths.push_back("!INCL-incl-data-alt1");
250  datapaths.push_back("!INCL-incl-data-alt2");
251  needed_update |=
252  LookForAndAddValidPath(datapaths,0,"--inclxx-datafile-path",nflags,flags);
253 
254  switch(theINCLConfig->getDeExcitationType()) {
255 #ifdef INCL_DEEXCITATION_ABLAXX
256  case G4INCL::DeExcitationABLAv3p:
257  LOG("HINCLCascadeIntranuke", pINFO)
258  << "using ABLAv3p for DeExcitation -- check for data location";
259  datapaths.clear();
260  datapaths.push_back(theINCLConfig->getABLAv3pCxxDataFilePath());
261  datapaths.push_back("!INCL-ablav3p-data-alt1");
262  datapaths.push_back("!INCL-ablav3p-data-alt2");
263  needed_update |=
264  LookForAndAddValidPath(datapaths,0,"--ablav3p-cxx-datafile-path",nflags,flags);
265  break;
266 #endif
267 #ifdef INCL_DEEXCITATION_ABLA07
268  case G4INCL::DeExcitationABLA07:
269  LOG("HINCLCascadeIntranuke", pINFO)
270  << "using ABLA07 for DeExcitation -- check for data location";
271  datapaths.clear();
272  datapaths.push_back(theINCLConfig->getABLA07DataFilePath());
273  datapaths.push_back("!INCL-abla07-data-alt1");
274  datapaths.push_back("!INCL-abla07-data-alt2");
275  needed_update |=
276  LookForAndAddValidPath(datapaths,0,"--abla07-datafile-path",nflags,flags);
277  break;
278 #endif
279 #ifdef INCL_DEEXCITATION_SMM
280  case G4INCL::DeExcitationSMM:
281  LOG("HINCLCascadeIntranuke", pINFO)
282  << "using SMMCXX for DeExcitation -- no data files to check for";
283  break;
284 #endif
285 #ifdef INCL_DEEXCITATION_GEMINIXX
286  case G4INCL::DeExcitationGEMINIXX:
287  LOG("HINCLCascadeIntranuke", pINFO)
288  << "using GEMINIXX for DeExcitation -- check for data location";
289  datapaths.clear();
290  datapaths.push_back(theINCLConfig->getGEMINIXXDataFilePath());
291  datapaths.push_back("!INCL-gemini-data-alt1");
292  datapaths.push_back("!INCL-gemini-data-alt2");
293  needed_update |=
294  LookForAndAddValidPath(datapaths,0,"--geminixx-datafile-path",nflags,flags);
295  break;
296 #endif
297  default:
298  LOG("HINCLCascadeIntranuke", pINFO)
299  << "using no DeExcitation -- no data files to check for";
300  break;
301  }
302 
303  // print info
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';
308  }
309  LOG("HINCLCascadeIntranuke", pNOTICE)
310  << "Flags passed to INCLConfigParser"
311  << '\n' << ss.str();
312 
313  return needed_update;
314 }
315 
316 //______________________________________________________________________________
317 bool HINCLCascadeIntranuke::LookForAndAddValidPath(std::vector<std::string>& datapaths,
318  size_t defaultIndx,
319  const char* optString,
320  size_t& nflags, char** flags) {
321 
322  // okay, we have a series of paths _OR_ parameter names ("!" as first char)
323  // loop over possibilities
324  // convert parameter names to their actual values
325  // expand string to evaluate ${} env variables
326  // check if the path exists
327  // first instance that exists is our choice
328  // if it isn't the defaultIndx entry, then we must add to the
329  // flags passed to ConfigParser
330  // add the optString, then the path
331 
332  bool needed_update = false;
333 
334  LOG("HINCLCascadeIntranuke", pINFO)
335  << "looking for a valid path for " << optString
336  << " (default [" << defaultIndx << "]";
337 
338  size_t foundIndx = SIZE_MAX; // flag as unfound
339  size_t npaths = datapaths.size();
340  for (size_t ipath = 0; ipath < npaths; ++ipath) {
341  std::string& apath = datapaths[ipath];
342  LOG("HINCLCascadeIntranuke", pINFO)
343  << "looking at " << apath;
344  if ( apath.at(0) == '!' ) {
345  apath.erase(0,1); // remove the "!"
346  // parameter name, returned value, default value
347  // default if not found is parameter name, just to make clear what failed
348  std::string newpath = "";
349  std::string notfoundvalue = std::string("no-such-param-") + apath;
350  GetParamDef(apath,newpath,notfoundvalue);
351  LOG("HINCLCascadeIntranuke", pINFO)
352  << "fetch param "<< "[" << ipath << "] "<< apath << " got " << newpath;
353  apath = newpath;
354  }
355  const char* expandedPath = gSystem->ExpandPathName(apath.c_str());
356  if ( ! expandedPath ) {
357  LOG("HINCLCascadeIntranuke", pINFO)
358  << "expandedPath was NULL";
359  continue;
360  }
361  bool valid = utils::system::DirectoryExists(expandedPath);
362  LOG("HINCLCascadeIntranuke", pINFO)
363  << "expandedPath " << expandedPath << " "
364  << ((valid)?"valid":"doesn't exist");
365  if ( valid ) {
366  apath = std::string(expandedPath);
367  foundIndx = ipath;
368  break;
369  }
370  }
371  if ( foundIndx == defaultIndx ) {
372  // nothing to do ... the default works
373  } else if ( foundIndx > npaths-1 ) {
374  // nothing valid found // yikes
375  std::stringstream ss;
376  for (size_t ipath = 0; ipath < npaths; ++ipath) {
377  std::string& apath = datapaths[ipath];
378  ss << "[" << ipath << "] " << apath << "\n";
379  }
380  LOG("HINCLCascadeIntranuke", pWARN)
381  << "no valid path found for " << optString
382  << ", tried: \n" << ss.str();
383  } else {
384  // add the flag with the valid path
385  flags[nflags] = strdup(optString); ++nflags;
386  flags[nflags] = strdup(datapaths[foundIndx].c_str()); ++nflags;
387  needed_update = true;
388  }
389 
390  return needed_update;
391 }
392 
393 //______________________________________________________________________________
394 int HINCLCascadeIntranuke::doCascade(GHepRecord * evrec) const {
395 
396  if ( ! theINCLConfig || ! theINCLModel ) return 0;
397 
398  int tpos = evrec->TargetNucleusPosition();
399  GHepParticle * target = evrec->Particle(tpos);
400  GHepParticle * pprobe = evrec->Probe();
401 
402  const ParticleType theType = toINCLparticletype(pprobe->Pdg());
403 
404  double E = (pprobe->E())*1000;
405  double massp = G4INCL::ParticleTable::getRealMass(theType);
406  double EKin = E - massp;
407 
408  G4INCL::ParticleSpecies theSpecies;
409  theSpecies.theType = theType;
410  theSpecies.theA = pdgcpiontoA(pprobe->Pdg());
411  theSpecies.theZ = pdgcpiontoZ(pprobe->Pdg());
412 
413  G4INCL::Random::SeedVector const theInitialSeeds = G4INCL::Random::getSeeds();
415  int pdg_codeProbe = 0;
416  pdg_codeProbe = INCLpartycleSpecietoPDGCODE(theSpecies);
417 
418  G4INCL::EventInfo result;
419  result = theINCLModel->processEvent(theSpecies,EKin,target->A(),target->Z());
420 
421  double m_target = ParticleTable::getTableMass(result.At, result.Zt);
422  GHepParticle * fsProbe = evrec->Probe();
423 
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);
427  int pdg_codeTarget= genie::pdg::IonPdgCode(target->A(), target->Z());
428 
429  if ( result.transparent ) {
430  evrec->AddParticle(pdg_codeProbe, ist1, 0,-1,-1,-1, p4h,x4null);
431  evrec->AddParticle(pdg_codeTarget,kIStFinalStateNuclearRemnant,1,-1,-1,-1,p4tgt,x4null);
432  INCL_DEBUG("Transparent event" << std::endl);
433  } else {
434  INCL_DEBUG("Number of produced particles: " << result.nParticles << "\n");
435  if ( theDeExcitation != 0 ) {
436  theDeExcitation->deExcite(&result);
437  }
438  int mom = 1;
439  for (int nP = 0; nP < result.nParticles; nP++){
440  if ( nP == result.nParticles-1 ) {
441  GHepParticle *p_outR =
442  INCLtoGenieParticle(result,nP,kIStFinalStateNuclearRemnant,mom,-1);
443  evrec->AddParticle(*p_outR);
444  delete p_outR;
445  } else {
446  GHepParticle *p_outR =
447  INCLtoGenieParticle(result,nP,kIStStableFinalState,0,-1);
448  evrec->AddParticle(*p_outR);
449  delete p_outR;
450  }
451 
452  }
453  }
454  return 0;
455 }
456 
457 void HINCLCascadeIntranuke::ProcessEventRecord(GHepRecord * evrec) const {
458 
459  LOG("HINCLCascadeIntranuke", pNOTICE)
460  << "************ Running HINCLCascadeIntranuke MODE INTRANUKE ************";
461 
462  fGMode = evrec->EventGenerationMode();
463  if ( fGMode == kGMdHadronNucleus ||
465  HINCLCascadeIntranuke::doCascade(evrec);
466  } else if ( fGMode == kGMdLeptonNucleus ) {
467  HINCLCascadeIntranuke::TransportHadrons(evrec);
468  }
469 
470  LOG("HINCLCascadeIntranuke", pINFO) << "Done with this event";
471 }
472 
473 bool HINCLCascadeIntranuke::CanRescatter(const GHepParticle * p) const {
474 
475  // checks whether a particle that needs to be rescattered, can in fact be
476  // rescattered by this cascade MC
477  assert(p);
478  return ( p->Pdg() == kPdgPiP ||
479  p->Pdg() == kPdgPiM ||
480  p->Pdg() == kPdgPi0 ||
481  p->Pdg() == kPdgProton ||
482  p->Pdg() == kPdgNeutron
483  );
484 }
485 
486 void HINCLCascadeIntranuke::TransportHadrons(GHepRecord * evrec) const {
487 
488  int inucl = -1;
489  if ( fGMode == kGMdHadronNucleus ||
491  inucl = evrec->TargetNucleusPosition();
492  } else {
493  if ( fGMode == kGMdLeptonNucleus ||
495  fGMode == kGMdNeutronOsc ) {
496  inucl = evrec->RemnantNucleusPosition();
497  }
498  }
499 
500  LOG("HINCLCascadeIntranuke", pNOTICE)
501  << "Propagating hadrons within nucleus found in position = " << inucl;
502  int tpos = evrec->TargetNucleusPosition();
503  GHepParticle * target = evrec->Particle(tpos);
504  GHepParticle * nucl = evrec->Particle(inucl);
505  if ( ! nucl ) {
506  LOG("HINCLCascadeIntranuke", pERROR)
507  << "No nucleus found in position = " << inucl;
508  LOG("HINCLCascadeIntranuke", pERROR)
509  << *evrec;
510  return;
511  }
512  fRemnA = nucl->A();
513  fRemnZ = nucl->Z();
514  int A_f(0), Z_f(0), Aft(0), A_i(target->A()),Z_i(target->Z());
515 
516  LOG("HINCLCascadeIntranuke", pNOTICE)
517  << "Nucleus (A,Z) = (" << fRemnA << ", " << fRemnZ << ")";
518 
519  const TLorentzVector & p4nucl = *(nucl->P4());
520  TLorentzVector x4null(0.,0.,0.,0.);
521  fRemnP4 = p4nucl;
522 
523  TObjArrayIter piter(evrec);
524  GHepParticle * p = 0;
525 
526  int icurr = -1;
527 
528  bool is_QE = evrec->Summary()->ProcInfo().IsQuasiElastic();
529 
530  TLorentzVector * p_4 = nucl->P4();
531  // momentum of the remnant nucleus.
532  double pxRemn = p_4->Px();
533  double pyRemn = p_4->Py();
534  double pzRemn = p_4->Pz();
535  int pdg_codeTargetRemn= genie::pdg::IonPdgCode(nucl->A(),nucl->Z());
536  TLorentzVector p4tgf(p_4->Px(),p_4->Py(),p_4->Pz(),0.0);
537 
538  // Loop over GHEP and run intranuclear rescattering on handled particles
539  std::vector<G4INCL::EventInfo>ListeOfINCLresult;
540  std::vector<int> Postion_evrec;
541  GHepParticle * fsl = evrec->FinalStatePrimaryLepton(); // primary Lepton
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);
545 
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;
550  while ( (p = (GHepParticle *) piter.Next() ) ) {
551 
552  icurr++;
553 
554  // Check whether the particle needs rescattering, otherwise skip it
555  if( ! this->NeedsRescattering(p) ) continue;
556  GHepParticle * sp = new GHepParticle(*p);
557 
558  // Set clone's mom to be the hadron that was cloned
559  sp->SetFirstMother(icurr);
560 
561  // Check whether the particle can be rescattered
562  if ( ! this->CanRescatter(sp) ) {
563 
564  // if I can't rescatter it, I will just take it out of the nucleus
565  LOG("HINCLCascadeIntranuke", pNOTICE)
566  << "... Current version can't rescatter a " << sp->Name();
567  sp->SetFirstMother(icurr);
569  evrec->AddParticle(*sp);
570  delete sp;
571  continue; // <-- skip to next GHEP entry
572  }
573 
574  TLorentzVector *v4= sp->GetX4();
575 
576  ThreeVector thePosition(0.,0.,0.);
577  ThreeVector momentum (0.,0.,0.);
578  thePosition.setX(v4->X());
579  thePosition.setY(v4->Y());
580  thePosition.setZ(v4->Z());
581  TLorentzVector * p4 = sp->P4();
582 
583  momentum.setX(p4->Px()*1000);
584  momentum.setY(p4->Py()*1000);
585  momentum.setZ(p4->Pz()*1000);
586 
587  int pdgc = sp->Pdg();
588 
589  const ParticleType theType = toINCLparticletype(pdgc);
590 
591  if ( theType == G4INCL::UnknownParticle) {
592  // INCL++ can't handle the particle
593  sp->SetFirstMother(icurr);
595  evrec->AddParticle(*sp);
596  delete sp;
597  continue;
598  }
599 
600  double E = (p4->Energy())*1000;
601  double massp = G4INCL::ParticleTable::getRealMass(theType);
602 
603  double EKin = E - massp;
604 
605  G4INCL::ParticleSpecies theSpecies;
606  theSpecies.theType=theType;
607  theSpecies.theA=pdgcpiontoA(sp->Pdg());
608  theSpecies.theZ=pdgcpiontoZ(sp->Pdg());
609 
610  G4INCL::Particle *pincl =
611  new G4INCL::Particle( theType , E , momentum, thePosition);
612 
613  G4INCL::Random::SeedVector const theInitialSeeds =
614  G4INCL::Random::getSeeds();
615 
616  G4INCL::Random::saveSeeds();
617  G4INCL::EventInfo result;
618 
619  result=theINCLModel->processEvent(theSpecies,pincl,EKin,fRemnA,fRemnZ,"FSI");
620 
621  // Exception get remnant with Z and A <0
622  Aresult += (fRemnA + pdgcpiontoA(sp->Pdg())- result.ARem[0]); // Aresult & Zresult are particles from cascade
623  Zresult += (fRemnZ + pdgcpiontoZ(sp->Pdg())- result.ZRem[0]);
624  Aexception = A_i - Aresult; // remaining particles in the nucleus
625  Zexception = Z_i - Zresult;
626  bool AZexception(false);
627  if ( Zexception <= 0 || Aexception <= 0 || Aexception<=Zexception) {
628  // Make sure that ARemn and Zremn >0
629  Zl+=pdgcpiontoZ(sp->Pdg());
630  Aft+=pdgcpiontoA(sp->Pdg());
631  sp->SetFirstMother(icurr);
633  evrec->AddParticle(*sp);
634  delete sp;
635  for (size_t it=0; it<ListeOfINCLresult.size();it++){
636  Pos = Postion_evrec.at(it); // Position of the mother in evrec
637  GHepParticle * pinthenucleus = evrec->Particle(Pos);
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());
645  pinthenucleus->SetFirstMother(Pos);
646  pinthenucleus->SetStatus(kIStStableFinalState);
647  evrec->AddParticle(*pinthenucleus);
648  AZexception=true;
649  } else {
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];
654  }
655  }
656  if ( AZexception ) ListeOfINCLresult.pop_back();
657  for (size_t it=0; it<ListeOfINCLresult.size();it++){
658 
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),
662  nP,kIStStableFinalState,Pos,inucl);
663  evrec->AddParticle(*p_outD);
664  delete p_outD;
665  } //Add result without the remnant nucleus
666  } else {
667  ListeOfINCLresult.at(it).ARem[0]=A_i-theA_Remn- Aft;
668  ListeOfINCLresult.at(it).ZRem[0]=Z_i-theZ_Remn- Zl;
669 
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),
677  nP,kIStStableFinalState,Pos,inucl);
678  evrec->AddParticle(*p_outFinal);
679  delete p_outFinal;
680  has_remnant=true;
681  }//Add all the result with the correct remnant nucleus
682  }
683  }
684  ListeOfINCLresult.clear();
685  } else {
686  //if result give a transparent event FSI=1
687  // Store *sp
688  if ( result.transparent ) {
689  Zl+=pdgcpiontoZ(sp->Pdg());
690  Aft+=pdgcpiontoA(sp->Pdg());
691  sp->SetFirstMother(icurr);
693  evrec->AddParticle(*sp);
694  delete sp;
695  } else {
696  Postion_evrec.push_back(icurr);
697  ListeOfINCLresult.push_back(result);
698  delete sp;
699  }
700 
701  }
702 
703  } //Ghep-entry
704 
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); // Position of the mother in evrec
709  GHepParticle * pinthenucleus = evrec->Particle(Pos);
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());
717  pinthenucleus->SetFirstMother(Pos);
718  pinthenucleus->SetStatus(kIStStableFinalState);
719  evrec->AddParticle(*pinthenucleus);
720  AZexception=true;
721  } else {
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];
726  }
727  }
728  if (AZexception) ListeOfINCLresult.pop_back();
729  for (size_t it=0; it < ListeOfINCLresult.size(); it++) {
730  if ( is_QE) {
731  // QE - event
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),
738  nP,kIStStableFinalState,Pos,inucl);
739  evrec->AddParticle(*p_out);
740  delete p_out;
741  }// Add to evrec the result
742  } else {
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];
747  GHepParticle *p_outD =
748  INCLtoGenieParticle(ListeOfINCLresult.at(it),nP,kIStStableFinalState,Pos,inucl);
749  evrec->AddParticle(*p_outD);
750  delete p_outD;
751  } //Add result without the remnant nucleus
752  } else {
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),
764  nP,kIStStableFinalState,Pos,inucl);
765  evrec->AddParticle(*p_outR);
766  delete p_outR;
767  } //Add all the result with the correct remnant nucleus
768  }
769  }
770  }// Loop over all the result from INCLCascade
771  }
772 
773  if ( ListeOfINCLresult.size() == 0 && !has_remnant) {
774  GHepParticle remnant(pdg_codeTargetRemn, kIStFinalStateNuclearRemnant, inucl,-1,-1,-1, fRemnP4, x4null);
775  evrec->AddParticle(remnant);
776  }
777  evrec->Particle(inucl)->SetStatus(kIStIntermediateState);
778 }
779 
780 //______________________________________________________________________________
781 int HINCLCascadeIntranuke::pdgcpiontoA(int pdgc) const {
782 
783  if ( pdgc == 2212 || pdgc == 2112 ) return 1;
784  else if ( pdgc == 211 || pdgc == -211 || pdgc == 111 ) return 0;
785  return 0; // return something
786 
787 }
788 
789 //______________________________________________________________________________
790 int HINCLCascadeIntranuke::pdgcpiontoZ(int pdgc) const {
791 
792  if ( pdgc == 2212 || pdgc == 211 ) return 1;
793  else if ( pdgc == 2112 || pdgc == 111 ) return 0;
794  else if ( pdgc == -211 ) return -1;
795  return 0; // return something
796 
797 }
798 
799 //______________________________________________________________________________
800 bool HINCLCascadeIntranuke::NeedsRescattering(const GHepParticle * p) const {
801 
802  // checks whether the particle should be rescattered
803  assert(p);
804  // attempt to rescatter anything marked as 'hadron in the nucleus'
805  return ( p->Status() == kIStHadronInTheNucleus );
806 
807 }
808 
809 //______________________________________________________________________________
811 
812  LOG("HINCLCascadeIntranuke", pDEBUG)
813  << "Configure from Registry: '" << config.Name() << "'\n"
814  << config;
815 
816  Algorithm::Configure(config);
817  this->LoadConfig();
818 
819 }
820 
821 //___________________________________________________________________________
822 void HINCLCascadeIntranuke::Configure(string param_set) {
823 
824  LOG("HINCLCascadeIntranuke", pDEBUG)
825  << "Configure from param_set name: " << param_set;
826 
827  Algorithm::Configure(param_set);
828  this->LoadConfig();
829 
830 }
831 
832 #endif // __GENIE_INCL_ENABLED__
int Z(void) const
void SetFirstMother(int m)
Definition: GHepParticle.h:132
virtual GHepParticle * Particle(int position) const
Definition: GHepRecord.cxx:104
TLorentzVector * GetX4(void) const
THE MAIN GENIE PROJECT NAMESPACE
Definition: AlgCmp.h:25
static QCString result
#define pERROR
Definition: Messenger.h:59
double E(void) const
Get energy.
Definition: GHepParticle.h:91
virtual Interaction * Summary(void) const
Definition: GHepRecord.cxx:91
const TLorentzVector * P4(void) const
Definition: GHepParticle.h:78
Defines the EventRecordVisitorI interface. Concrete implementations of this interface use the &#39;Visito...
std::string string
Definition: nybbler.cc:12
virtual int RemnantNucleusPosition(void) const
Definition: GHepRecord.cxx:389
bool IsQuasiElastic(void) const
Definition: ProcessInfo.cxx:69
int fRemnA
remnant nucleus A
STL namespace.
bool CanRescatter(const GHepParticle *p) const
double Pz(void) const
Get Pz.
Definition: GHepParticle.h:90
GHepStatus_t Status(void) const
Definition: GHepParticle.h:64
GEvGenMode_t fGMode
event generation mode (lepton+A, hadron+A, ...)
virtual GHepParticle * Probe(void) const
Definition: GHepRecord.cxx:277
int Pdg(void) const
Definition: GHepParticle.h:63
string Name(void) const
get the registry name
Definition: Registry.cxx:597
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...
Definition: Messenger.h:96
string infile
bt
Definition: tracks.py:83
static Config * config
Definition: config.cpp:1054
virtual GHepParticle * FinalStatePrimaryLepton(void) const
Definition: GHepRecord.cxx:326
virtual void Configure(const Registry &config)
Definition: Algorithm.cxx:62
GEvGenMode_t EventGenerationMode(void) const
Definition: GHepRecord.cxx:209
bool NeedsRescattering(const GHepParticle *p) const
p
Definition: test.py:223
const int kPdgPiP
Definition: PDGCodes.h:158
const int kPdgPi0
Definition: PDGCodes.h:160
double Charge(void) const
Chrg that corresponds to the PDG code.
#define pINFO
Definition: Messenger.h:62
#define pWARN
Definition: Messenger.h:60
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
vector< string > Split(string input, string delim)
Definition: StringUtils.cxx:36
bool DirectoryExists(const char *path)
Definition: SystemUtils.cxx:92
void SetStatus(GHepStatus_t s)
Definition: GHepParticle.h:126
A registry. Provides the container for algorithm configuration parameters.
Definition: Registry.h:65
void Configure(string mesg)
Definition: gEvServ.cxx:196
int IonPdgCode(int A, int Z)
Definition: PDGUtils.cxx:68
const int kPdgPiM
Definition: PDGCodes.h:159
virtual void AddParticle(const GHepParticle &p)
Definition: GHepRecord.cxx:491
const ProcessInfo & ProcInfo(void) const
Definition: Interaction.h:70
std::string nucl(const std::string &A, const std::string &elem)
Definition: TruthText.cxx:114
const int kPdgProton
Definition: PDGCodes.h:81
int A(void) const
#define pNOTICE
Definition: Messenger.h:61
bool GetParamDef(const RgKey &name, T &p, const T &def) const
def momentum(x1, x2, x3, scale=1.)
const int kPdgNeutron
Definition: PDGCodes.h:83
GENIE&#39;s GHEP MC event record.
Definition: GHepRecord.h:45
STDHEP-like event record entry that can fit a particle or a nucleus.
Definition: GHepParticle.h:39
virtual int TargetNucleusPosition(void) const
Definition: GHepRecord.cxx:362
Root of GENIE utility namespaces.
QTextStream & endl(QTextStream &s)
enum genie::EGHepStatus GHepStatus_t
int fRemnZ
remnant nucleus Z
#define pDEBUG
Definition: Messenger.h:63
TLorentzVector fRemnP4
P4 of remnant system.