GENIEGenerator
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
124  std::string infile;
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,kIStStableFinalState,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 
439  for (int nP = 0; nP < result.nParticles; nP++){
440  if ( nP == result.nParticles-1 ) {
441  int pdgRem=INCLtopdgcode(result.A[nP],result.Z[nP]);
442  TParticlePDG * pdgRemn=PDGLibrary::Instance()->Find(pdgRem,false);
443  if(!pdgRemn)
444  {
445  LOG("HINCLCascadeIntranuke", pINFO)
446  << "NO Particle with pdg = " << pdgRem << " in PDGLibrary!";
447  // Add the particle with status id=15 and change it to HadroBlob
448  TVector3 p3M(result.px[nP]/1000,result.py[nP]/1000,result.pz[nP]/1000);
449 
450  double MassRem=0.5*((result.px[nP])*(result.px[nP]) +
451  (result.py[nP])*(result.py[nP]) +
452  (result.pz[nP])*(result.pz[nP]) -
453  result.EKin[nP]*result.EKin[nP]) / (result.EKin[nP]);
454  float ERem=result.EKin[nP]+MassRem;
455  TLorentzVector p4tgtf(p3M,ERem/1000);
457  1,-1,-1,-1, p4tgtf, x4null);;
458  evrec->AddParticle(p_outR);
459  }
460  else
461  {
462  GHepParticle *p_outR =
463  INCLtoGenieParticle(result,nP,kIStStableFinalState,1,-1);
464  evrec->AddParticle(*p_outR);
465  delete p_outR;
466  }
467  } else {
468  GHepParticle *p_outR =
469  INCLtoGenieParticle(result,nP,kIStStableFinalState,0,-1);
470  evrec->AddParticle(*p_outR);
471  delete p_outR;
472  }
473 
474  }
475  }
476  return 0;
477 }
478 
479 void HINCLCascadeIntranuke::ProcessEventRecord(GHepRecord * evrec) const {
480 
481  LOG("HINCLCascadeIntranuke", pNOTICE)
482  << "************ Running HINCLCascadeIntranuke MODE INTRANUKE ************";
483 
484  fGMode = evrec->EventGenerationMode();
485  if ( fGMode == kGMdHadronNucleus ||
486  fGMode == kGMdPhotonNucleus ) {
487  HINCLCascadeIntranuke::doCascade(evrec);
488 } else if ( fGMode == kGMdLeptonNucleus ) {
489  HINCLCascadeIntranuke::TransportHadrons(evrec);
490 }
491 
492 LOG("HINCLCascadeIntranuke", pINFO) << "Done with this event";
493 }
494 
495 bool HINCLCascadeIntranuke::CanRescatter(const GHepParticle * p) const {
496 
497  // checks whether a particle that needs to be rescattered, can in fact be
498  // rescattered by this cascade MC
499  assert(p);
500  return ( p->Pdg() == kPdgPiP ||
501  p->Pdg() == kPdgPiM ||
502  p->Pdg() == kPdgPi0 ||
503  p->Pdg() == kPdgProton ||
504  p->Pdg() == kPdgNeutron
505  );
506 }
507 
508 void HINCLCascadeIntranuke::TransportHadrons(GHepRecord * evrec) const {
509 
510  int inucl = -1;
511  if ( fGMode == kGMdHadronNucleus ||
512  fGMode == kGMdPhotonNucleus ) {
513  inucl = evrec->TargetNucleusPosition();
514 } else {
515  if ( fGMode == kGMdLeptonNucleus ||
516  fGMode == kGMdNucleonDecay ||
517  fGMode == kGMdNeutronOsc ) {
518  inucl = evrec->RemnantNucleusPosition();
519 }
520 }
521 
522 LOG("HINCLCascadeIntranuke", pNOTICE)
523 << "Propagating hadrons within nucleus found in position = " << inucl;
524 int tpos = evrec->TargetNucleusPosition();
525 GHepParticle * target = evrec->Particle(tpos);
526 GHepParticle * nucl = evrec->Particle(inucl);
527 if ( ! nucl ) {
528  LOG("HINCLCascadeIntranuke", pERROR)
529  << "No nucleus found in position = " << inucl;
530  LOG("HINCLCascadeIntranuke", pERROR)
531  << *evrec;
532  return;
533 }
534 fRemnA = nucl->A();
535 fRemnZ = nucl->Z();
536 GHepParticle * Incident_particle = evrec->Particle(0);
537 
538 int A_f(0), Z_f(0), Aft(0), A_i(target->A()),Z_i(0), Charge_probe(Incident_particle->Charge());
539 if(Charge_probe==0) Z_i=target->Z();
540 else if(Charge_probe<0) Z_i=target->Z()-1;
541 else if(Charge_probe>0)Z_i=target->Z()+1;
542 
543 
544 LOG("HINCLCascadeIntranuke", pNOTICE)
545 << "Nucleus (A,Z) = (" << fRemnA << ", " << fRemnZ << ")";
546 
547 const TLorentzVector & p4nucl = *(nucl->P4());
548 TLorentzVector x4null(0.,0.,0.,0.);
549 fRemnP4 = p4nucl;
550 
551 TObjArrayIter piter(evrec);
552 GHepParticle * p = 0;
553 
554 int icurr = -1;
555 
556 bool is_QE = evrec->Summary()->ProcInfo().IsQuasiElastic();
557 
558 TLorentzVector * p_4 = nucl->P4();
559  // momentum of the remnant nucleus.
560 double pxRemn = p_4->Px();
561 double pyRemn = p_4->Py();
562 double pzRemn = p_4->Pz();
563 int pdg_codeTargetRemn= genie::pdg::IonPdgCode(nucl->A(),nucl->Z());
564 TLorentzVector p4tgf(p_4->Px(),p_4->Py(),p_4->Pz(),0.0);
565 
566  // Loop over GHEP and run intranuclear rescattering on handled particles
567 std::vector<G4INCL::EventInfo>ListeOfINCLresult;
568 std::vector<int> Postion_evrec,num_of_AZexception;
569  GHepParticle * fsl = evrec->FinalStatePrimaryLepton(); // primary Lepton
570  double ExcitaionE(0), the_pxRemn(0), the_pyRemn(0), the_pzRemn(0);
571  int Zl(0), Aresult(0), Zresult(0), Aexception(0), Zexception(0),Pos(0),
572  mother1(0),mother2(0),theA_Remn(0), theZ_Remn(0);
573 
574  if ( fsl->Charge() == 0. ) Zl = 0;
575  else if ( fsl->Charge() < 0. ) Zl = -1;
576  else if ( fsl->Charge() > 0. ) Zl = 1;
577  bool has_remnant = false;
578  while ( (p = (GHepParticle *) piter.Next() ) ) {
579 
580  icurr++;
581 
582  // Check whether the particle needs rescattering, otherwise skip it
583  if( ! this->NeedsRescattering(p) ) continue;
584  GHepParticle * sp = new GHepParticle(*p);
585 
586  // Set clone's mom to be the hadron that was cloned
587  sp->SetFirstMother(icurr);
588 
589  // Check whether the particle can be rescattered
590  if ( ! this->CanRescatter(sp) ) {
591 
592  // if I can't rescatter it, I will just take it out of the nucleus
593  LOG("HINCLCascadeIntranuke", pNOTICE)
594  << "... Current version can't rescatter a " << sp->Name();
595  sp->SetFirstMother(icurr);
597  if ( sp->Charge() == 0. ) {
598  Zl+=0;
599  Aft+=1;
600  }
601  else if ( sp->Charge() < 0. ) {
602  Zl-=1;
603  Aft+=1;
604  }
605  else if ( sp->Charge() > 0. ) {
606  Zl+=1;
607  Aft+=1;
608  }
609 
610  evrec->AddParticle(*sp);
611  evrec->Particle(sp->FirstMother())->SetRescatterCode(1);
612  delete sp;
613  continue; // <-- skip to next GHEP entry
614  }
615 
616  TLorentzVector *v4= sp->GetX4();
617 
618  ThreeVector thePosition(0.,0.,0.);
619  ThreeVector momentum (0.,0.,0.);
620  thePosition.setX(v4->X());
621  thePosition.setY(v4->Y());
622  thePosition.setZ(v4->Z());
623  TLorentzVector * p4 = sp->P4();
624 
625  momentum.setX(p4->Px()*1000);
626  momentum.setY(p4->Py()*1000);
627  momentum.setZ(p4->Pz()*1000);
628 
629  int pdgc = sp->Pdg();
630 
631  const ParticleType theType = toINCLparticletype(pdgc);
632 
633  if ( theType == G4INCL::UnknownParticle) {
634  // INCL++ can't handle the particle
635  sp->SetFirstMother(icurr);
637  evrec->AddParticle(*sp);
638  evrec->Particle(sp->FirstMother())->SetRescatterCode(1);
639  delete sp;
640  continue;
641  }
642 
643  double E = (p4->Energy())*1000;
644  double massp = G4INCL::ParticleTable::getRealMass(theType);
645 
646  double EKin = E - massp;
647 
648  G4INCL::ParticleSpecies theSpecies;
649  theSpecies.theType=theType;
650  theSpecies.theA=pdgcpiontoA(sp->Pdg());
651  theSpecies.theZ=pdgcpiontoZ(sp->Pdg());
652 
653  G4INCL::Particle *pincl =
654  new G4INCL::Particle( theType , E , momentum, thePosition);
655 
656  G4INCL::Random::SeedVector const theInitialSeeds =
657  G4INCL::Random::getSeeds();
658 
659  G4INCL::Random::saveSeeds();
660  G4INCL::EventInfo result;
661 
662 
663  result=theINCLModel->processEvent(theSpecies,pincl,EKin,fRemnA,fRemnZ,"FSI");
664 
665  // Exception get remnant with Z and A <0
666  Aresult += (fRemnA + pdgcpiontoA(sp->Pdg())- result.ARem[0]); // Aresult & Zresult are particles from cascade
667  Zresult += (fRemnZ + pdgcpiontoZ(sp->Pdg())- result.ZRem[0]);
668  Aexception = A_i - Aresult; // remaining particles in the nucleus
669  Zexception = Z_i - Zresult;
670  bool AZexception(false);
671  if ( Zexception <= 0 || Aexception <= 0 || Aexception<=Zexception) {
672  // Make sure that ARemn and Zremn >0
673  Zl+=pdgcpiontoZ(sp->Pdg());
674  Aft+=pdgcpiontoA(sp->Pdg());
675  sp->SetFirstMother(icurr);
677  evrec->AddParticle(*sp);
678  evrec->Particle(sp->FirstMother())->SetRescatterCode(1);
679  delete sp;
680  for (size_t it=0; it<ListeOfINCLresult.size();it++){
681  Pos=Postion_evrec.at(it);// Position of the mother in evrec
682 
683  GHepParticle * pinthenucleus = evrec->Particle(Pos);
684  theA_Remn+= (fRemnA + pdgcpiontoA(pinthenucleus->Pdg())- ListeOfINCLresult.at(it).ARem[0]);
685  theZ_Remn+= (fRemnZ + pdgcpiontoZ(pinthenucleus->Pdg())- ListeOfINCLresult.at(it).ZRem[0]);
686  if ( (A_i-theA_Remn-Aft) < (Z_i-theZ_Remn-Zl) ) {
687  theA_Remn-= (fRemnA + pdgcpiontoA(pinthenucleus->Pdg())- ListeOfINCLresult.at(it).ARem[0]);
688  theZ_Remn-= (fRemnZ + pdgcpiontoZ(pinthenucleus->Pdg())- ListeOfINCLresult.at(it).ZRem[0]);
689  Zl+=pdgcpiontoZ(pinthenucleus->Pdg());
690  Aft+=pdgcpiontoA(pinthenucleus->Pdg());
691 
692  pinthenucleus->SetFirstMother(Pos);
693  pinthenucleus->SetStatus(kIStStableFinalState);
694  evrec->AddParticle(*pinthenucleus);
695  evrec->Particle(pinthenucleus->FirstMother())->SetRescatterCode(1);
696  AZexception=true;
697  num_of_AZexception.push_back(it);
698  } else {
699  the_pxRemn+=ListeOfINCLresult.at(it).pxRem[0];
700  the_pyRemn+=ListeOfINCLresult.at(it).pyRem[0];
701  the_pzRemn+=ListeOfINCLresult.at(it).pzRem[0];
702  ExcitaionE+=ListeOfINCLresult.at(it).EStarRem[0];
703  }
704  }
705  if (AZexception) {
706  for (size_t it=0;it<num_of_AZexception.size();it++) {
707  ListeOfINCLresult.pop_back();
708  }}
709 
710  if(ListeOfINCLresult.size() != 0) {
711  int Number_of_Sec=ListeOfINCLresult.size();
712  int mom2(0),mom1(0);
713  mom1=Postion_evrec.at(0);
714  if(Number_of_Sec==1) mom2=-1;
715  if(Number_of_Sec>1) mom2=Postion_evrec.at(Number_of_Sec-1);
716 
717  for (size_t it=0; it<ListeOfINCLresult.size();it++){
718 
719  if ( it < ListeOfINCLresult.size()-1 ) {
720  for (int nP=0; nP < ListeOfINCLresult.at(it).nParticles; nP++ ) {
721  GHepParticle *p_outD = INCLtoGenieParticle(ListeOfINCLresult.at(it),
722  nP,kIStStableFinalState,mom1,mom2);
723  evrec->AddParticle(*p_outD);
724  delete p_outD;
725  } //Add result without the remnant nucleus
726  } else {
727  ListeOfINCLresult.at(it).ARem[0]=A_i-theA_Remn- Aft;
728  ListeOfINCLresult.at(it).ZRem[0]=Z_i-theZ_Remn- Zl;
729 
730  ListeOfINCLresult.at(it).pxRem[0]= the_pxRemn + (pxRemn*1000);
731  ListeOfINCLresult.at(it).pyRem[0]= the_pyRemn + (pyRemn*1000);
732  ListeOfINCLresult.at(it).pzRem[0]= the_pzRemn + (1000*pzRemn);
733  ListeOfINCLresult.at(it).EStarRem[0]=ExcitaionE;
734  theDeExcitation->deExcite(&ListeOfINCLresult.at(it));
735  for (int nP=0;nP<ListeOfINCLresult.at(it).nParticles;nP++ ) {
736  int rem_index=FindlargestFragment(ListeOfINCLresult.at(it));
737  if(nP==rem_index||ListeOfINCLresult.at(it).A[nP]>1) {
738  mom1=inucl;
739  mom2=-1;
740  }
741  else{
742  mom1=Postion_evrec.at(0);
743  if(Number_of_Sec==1) mom2=-1;
744  if(Number_of_Sec>1) mom2=Postion_evrec.at(Number_of_Sec-1);
745  }
746  GHepParticle *p_outFinal = INCLtoGenieParticle(ListeOfINCLresult.at(it),
747  nP,kIStStableFinalState,mom1,mom2);
748  evrec->AddParticle(*p_outFinal);
749  delete p_outFinal;
750  has_remnant=true;
751  }//Add all the result with the correct remnant nucleus
752  }
753  }
754  ListeOfINCLresult.clear();
755  num_of_AZexception.clear();
756  }//
757  } else {
758  //if result give a transparent event FSI=1
759  // Store *sp
760  if ( result.transparent ) {
761  Zl+=pdgcpiontoZ(sp->Pdg());
762  Aft+=pdgcpiontoA(sp->Pdg());
763  //sp->SetFirstMother(icurr);
765  evrec->AddParticle(*sp);
766  evrec->Particle(sp->FirstMother())->SetRescatterCode(1);
767  delete sp;
768  } else {
769  Postion_evrec.push_back(icurr);
770  ListeOfINCLresult.push_back(result);
771  delete sp;
772  }
773 
774  }
775 
776  } //Ghep-entry
777 
778  if ( ListeOfINCLresult.size() != 0 ) {
779  bool AZexception=false;
780  for (size_t it=0; it<ListeOfINCLresult.size();it++){
781  Pos = Postion_evrec.at(it); // Position of the mother in evrec
782 
783 
784  GHepParticle * pinthenucleus = evrec->Particle(Pos);
785  theA_Remn+= (fRemnA + pdgcpiontoA(pinthenucleus->Pdg())- ListeOfINCLresult.at(it).ARem[0]);
786  theZ_Remn+= (fRemnZ + pdgcpiontoZ(pinthenucleus->Pdg())- ListeOfINCLresult.at(it).ZRem[0]);
787  if ( (A_i-theA_Remn-Aft) < (Z_i-theZ_Remn-Zl) ) {
788  theA_Remn-= (fRemnA + pdgcpiontoA(pinthenucleus->Pdg())- ListeOfINCLresult.at(it).ARem[0]);
789  theZ_Remn-= (fRemnZ + pdgcpiontoZ(pinthenucleus->Pdg())- ListeOfINCLresult.at(it).ZRem[0]);
790  Zl+=pdgcpiontoZ(pinthenucleus->Pdg());
791  Aft+=pdgcpiontoA(pinthenucleus->Pdg());
792 
793  pinthenucleus->SetFirstMother(Pos);
794  pinthenucleus->SetStatus(kIStStableFinalState);
795  evrec->AddParticle(*pinthenucleus);
796  AZexception=true;
797  num_of_AZexception.push_back(it);
798  } else {
799  the_pxRemn+=ListeOfINCLresult.at(it).pxRem[0];
800  the_pyRemn+=ListeOfINCLresult.at(it).pyRem[0];
801  the_pzRemn+=ListeOfINCLresult.at(it).pzRem[0];
802  ExcitaionE+=ListeOfINCLresult.at(it).EStarRem[0];
803  }
804  }
805  if (AZexception) {
806  for (size_t it=0;it<num_of_AZexception.size();it++) {
807  ListeOfINCLresult.pop_back();
808  }}
809  for (size_t it=0; it < ListeOfINCLresult.size(); it++) {
810  if ( is_QE) {
811  // QE - event
812  ListeOfINCLresult.at(it).pxRem[0] += pxRemn*1000;
813  ListeOfINCLresult.at(it).pyRem[0] += pyRemn*1000;
814  ListeOfINCLresult.at(it).pzRem[0] += 1000*pzRemn;
815  if ( theDeExcitation != 0 ) theDeExcitation->deExcite(&ListeOfINCLresult.at(it));
816  int rem_index=FindlargestFragment(ListeOfINCLresult.at(it));
817 
818  for (int nP=0; nP < ListeOfINCLresult.at(it).nParticles; nP++ ) {
819  // if(nP==ListeOfINCLresult.at(it).nParticles-1) Pos=inucl;
820  if(nP==rem_index) Pos=inucl;
821  else if(nP!=rem_index) Pos=Postion_evrec.at(it);
822  GHepParticle *p_out = INCLtoGenieParticle(ListeOfINCLresult.at(it),
823  nP,kIStStableFinalState,Pos,-1);
824  evrec->AddParticle(*p_out);
825  delete p_out;
826  }// Add to evrec the result
827  } else {
828  if ( it < ListeOfINCLresult.size()-1 ) {
829  for (int nP=0; nP < ListeOfINCLresult.at(it).nParticles; nP++ ) {
830  A_f+=ListeOfINCLresult.at(it).A[nP];
831  Z_f+=ListeOfINCLresult.at(it).Z[nP];
832  if(ListeOfINCLresult.at(it).A[nP]>1) { // if the event emits cluster during cascade
833  mother1=inucl;
834  mother2=-1;
835  }
836  else{
837  mother1=Postion_evrec.at(0);
838  if(ListeOfINCLresult.size()==1) mother2=-1;
839  else if(ListeOfINCLresult.size()>1){
840  mother2=Postion_evrec.at(ListeOfINCLresult.size()-1);
841  }
842  }
843  GHepParticle *p_outD =
844  INCLtoGenieParticle(ListeOfINCLresult.at(it),nP,kIStStableFinalState,mother1,mother2);
845  evrec->AddParticle(*p_outD);
846  delete p_outD;
847  } //Add result without the remnant nucleus
848  } else {
849  ListeOfINCLresult.at(it).ARem[0]=A_i-theA_Remn-Aft;
850  ListeOfINCLresult.at(it).ZRem[0]=Z_i-theZ_Remn-Zl;
851  ListeOfINCLresult.at(it).pxRem[0]= the_pxRemn + (pxRemn*1000);
852  ListeOfINCLresult.at(it).pyRem[0]= the_pyRemn + (pyRemn*1000);
853  ListeOfINCLresult.at(it).pzRem[0]= the_pzRemn + (1000*pzRemn);
854  ListeOfINCLresult.at(it).EStarRem[0]=ExcitaionE;
855  if ( theDeExcitation != 0 ) theDeExcitation->deExcite(&ListeOfINCLresult.at(it));
856  int rem_index=FindlargestFragment(ListeOfINCLresult.at(it));
857  for (int nP=0; nP < ListeOfINCLresult.at(it).nParticles; nP++ ) {
858  A_f+=ListeOfINCLresult.at(it).A[nP];
859  Z_f+=ListeOfINCLresult.at(it).Z[nP];
860  if(nP==rem_index||ListeOfINCLresult.at(it).A[nP]>1) {
861  mother1=inucl;
862  mother2=-1;
863  }
864  else{
865  mother1=Postion_evrec.at(0);
866  if(ListeOfINCLresult.size()==1) mother2=-1;
867  else if(ListeOfINCLresult.size()>1){
868  mother2=Postion_evrec.at(ListeOfINCLresult.size()-1);
869  }
870  }
871  GHepParticle *p_outR = INCLtoGenieParticle(ListeOfINCLresult.at(it),
872  nP,kIStStableFinalState,mother1,mother2);
873  evrec->AddParticle(*p_outR);
874  has_remnant=true;
875  delete p_outR;
876  } //Add all the result with the correct remnant nucleus
877  }
878  }
879  }// Loop over all the result from INCLCascade
880  }
881 
882  if ( ListeOfINCLresult.size() == 0 && !has_remnant) {
883  TParticlePDG * pdgRemn=PDGLibrary::Instance()->Find(pdg_codeTargetRemn,false);
884  if(!pdgRemn)
885  {
886  LOG("HINCLCascadeIntranuke", pINFO)
887  << "NO Particle with pdg = " << pdg_codeTargetRemn << " in PDGLibrary!";
888  GHepParticle remnant(kPdgHadronicBlob, kIStFinalStateNuclearRemnant, inucl,-1,-1,-1, fRemnP4, x4null);
889  evrec->AddParticle(remnant);
890  }else{
891  GHepParticle remnant(pdg_codeTargetRemn, kIStStableFinalState, inucl,-1,-1,-1, fRemnP4, x4null);
892  evrec->AddParticle(remnant);
893  }
894 }
896 
897 
898 int dau1(0), dau2(0),Nsec=ListeOfINCLresult.size();
899 if(Nsec>1){
900  GHepParticle * pinN = evrec->Particle(Postion_evrec.at(0));
901  dau1=pinN->FirstDaughter();
902  dau2=pinN->LastDaughter();
903  for(int ii=1;ii<Nsec;ii++){
904  evrec->Particle(Postion_evrec.at(ii))->SetFirstDaughter(dau1);
905  evrec->Particle(Postion_evrec.at(ii))->SetLastDaughter(dau2);
906  }
907 }
908 }
909 
910 //______________________________________________________________________________
911 int HINCLCascadeIntranuke::pdgcpiontoA(int pdgc) const {
912 
913  if ( pdgc == 2212 || pdgc == 2112 ) return 1;
914  else if ( pdgc == 211 || pdgc == -211 || pdgc == 111 ) return 0;
915  return 0; // return something
916 
917 }
918 
919 //______________________________________________________________________________
920 int HINCLCascadeIntranuke::pdgcpiontoZ(int pdgc) const {
921 
922  if ( pdgc == 2212 || pdgc == 211 ) return 1;
923  else if ( pdgc == 2112 || pdgc == 111 ) return 0;
924  else if ( pdgc == -211 ) return -1;
925  return 0; // return something
926 
927 }
928 
929 //______________________________________________________________________________
930 bool HINCLCascadeIntranuke::NeedsRescattering(const GHepParticle * p) const {
931 
932  // checks whether the particle should be rescattered
933  assert(p);
934  // attempt to rescatter anything marked as 'hadron in the nucleus'
935  return ( p->Status() == kIStHadronInTheNucleus );
936 
937 }
938 
939 //______________________________________________________________________________
940 void HINCLCascadeIntranuke::Configure(const Registry & config) {
941 
942  LOG("HINCLCascadeIntranuke", pDEBUG)
943  << "Configure from Registry: '" << config.Name() << "'\n"
944  << config;
945 
946  Algorithm::Configure(config);
947  this->LoadConfig();
948 
949 }
950 
951 //___________________________________________________________________________
952 void HINCLCascadeIntranuke::Configure(string param_set) {
953 
954  LOG("HINCLCascadeIntranuke", pDEBUG)
955  << "Configure from param_set name: " << param_set;
956 
957  Algorithm::Configure(param_set);
958  this->LoadConfig();
959 
960 }
961 
962 #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
#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...
int FirstDaughter(void) const
Definition: GHepParticle.h:68
const int kPdgHadronicBlob
Definition: PDGCodes.h:211
virtual int RemnantNucleusPosition(void) const
Definition: GHepRecord.cxx:397
bool IsQuasiElastic(void) const
Definition: ProcessInfo.cxx:69
double Pz(void) const
Get Pz.
Definition: GHepParticle.h:90
GHepStatus_t Status(void) const
Definition: GHepParticle.h:64
virtual GHepParticle * Probe(void) const
Definition: GHepRecord.cxx:284
int Pdg(void) const
Definition: GHepParticle.h:63
int FirstMother(void) const
Definition: GHepParticle.h:66
string Name(void) const
get the registry name
Definition: Registry.cxx:597
string Name(void) const
Name that corresponds to the PDG code.
int LastDaughter(void) const
Definition: GHepParticle.h:69
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
string infile
virtual GHepParticle * FinalStatePrimaryLepton(void) const
Definition: GHepRecord.cxx:333
virtual void Configure(const Registry &config)
Definition: Algorithm.cxx:62
GEvGenMode_t EventGenerationMode(void) const
Definition: GHepRecord.cxx:209
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
static PDGLibrary * Instance(void)
Definition: PDGLibrary.cxx:68
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:71
const int kPdgPiM
Definition: PDGCodes.h:159
virtual void AddParticle(const GHepParticle &p)
Definition: GHepRecord.cxx:499
const ProcessInfo & ProcInfo(void) const
Definition: Interaction.h:70
const int kPdgProton
Definition: PDGCodes.h:81
TParticlePDG * Find(int pdgc, bool must_exist=true)
Definition: PDGLibrary.cxx:86
int A(void) const
#define pNOTICE
Definition: Messenger.h:61
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:370
enum genie::EGHepStatus GHepStatus_t
#define pDEBUG
Definition: Messenger.h:63