GENIEGenerator
Loading...
Searching...
No Matches
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
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>
51namespace 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
70using namespace genie;
71using namespace genie::utils;
72using namespace G4INCL;
73using std::ostringstream;
74using namespace std;
75
76HINCLCascadeIntranuke::HINCLCascadeIntranuke() :
77EventRecordVisitorI("genie::HINCLCascadeIntranuke"),
78theINCLConfig(0), theINCLModel(0), theDeExcitation(0)
79{
80 LOG("HINCLCascadeIntranuke", pDEBUG)
81 << "default ctor";
82}
83
84//______________________________________________________________________________
85HINCLCascadeIntranuke::HINCLCascadeIntranuke(string config) :
86EventRecordVisitorI("genie::HINCLCascadeIntranuke", config),
87theINCLConfig(0), theINCLModel(0), theDeExcitation(0)
88{
89 LOG("HINCLCascadeIntranuke", pDEBUG)
90 << "ctor from config " << config;
91}
92
93//______________________________________________________________________________
94HINCLCascadeIntranuke::~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//______________________________________________________________________________
105void 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//______________________________________________________________________________
235bool 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//______________________________________________________________________________
317bool 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//______________________________________________________________________________
394int 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
479void 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
492LOG("HINCLCascadeIntranuke", pINFO) << "Done with this event";
493}
494
495bool 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
508void 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
522LOG("HINCLCascadeIntranuke", pNOTICE)
523<< "Propagating hadrons within nucleus found in position = " << inucl;
524int tpos = evrec->TargetNucleusPosition();
525GHepParticle * target = evrec->Particle(tpos);
526GHepParticle * nucl = evrec->Particle(inucl);
527if ( ! nucl ) {
528 LOG("HINCLCascadeIntranuke", pERROR)
529 << "No nucleus found in position = " << inucl;
530 LOG("HINCLCascadeIntranuke", pERROR)
531 << *evrec;
532 return;
533}
534fRemnA = nucl->A();
535fRemnZ = nucl->Z();
536GHepParticle * Incident_particle = evrec->Particle(0);
537
538int A_f(0), Z_f(0), Aft(0), A_i(target->A()),Z_i(0), Charge_probe(Incident_particle->Charge());
539if(Charge_probe==0) Z_i=target->Z();
540else if(Charge_probe<0) Z_i=target->Z()-1;
541else if(Charge_probe>0)Z_i=target->Z()+1;
542
543
544LOG("HINCLCascadeIntranuke", pNOTICE)
545<< "Nucleus (A,Z) = (" << fRemnA << ", " << fRemnZ << ")";
546
547const TLorentzVector & p4nucl = *(nucl->P4());
548TLorentzVector x4null(0.,0.,0.,0.);
549fRemnP4 = p4nucl;
550
551TObjArrayIter piter(evrec);
552GHepParticle * p = 0;
553
554int icurr = -1;
555
556bool is_QE = evrec->Summary()->ProcInfo().IsQuasiElastic();
557
558TLorentzVector * p_4 = nucl->P4();
559 // momentum of the remnant nucleus.
560double pxRemn = p_4->Px();
561double pyRemn = p_4->Py();
562double pzRemn = p_4->Pz();
563int pdg_codeTargetRemn= genie::pdg::IonPdgCode(nucl->A(),nucl->Z());
564TLorentzVector p4tgf(p_4->Px(),p_4->Py(),p_4->Pz(),0.0);
565
566 // Loop over GHEP and run intranuclear rescattering on handled particles
567std::vector<G4INCL::EventInfo>ListeOfINCLresult;
568std::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
898int dau1(0), dau2(0),Nsec=ListeOfINCLresult.size();
899if(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//______________________________________________________________________________
911int 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//______________________________________________________________________________
920int 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//______________________________________________________________________________
930bool 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//______________________________________________________________________________
940void HINCLCascadeIntranuke::Configure(const Registry & config) {
941
942 LOG("HINCLCascadeIntranuke", pDEBUG)
943 << "Configure from Registry: '" << config.Name() << "'\n"
944 << config;
945
947 this->LoadConfig();
948
949}
950
951//___________________________________________________________________________
952void 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__
string infile
#define pNOTICE
Definition Messenger.h:61
#define pINFO
Definition Messenger.h:62
#define pERROR
Definition Messenger.h:59
#define pDEBUG
Definition Messenger.h:63
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
Definition Messenger.h:96
#define pWARN
Definition Messenger.h:60
virtual void Configure(const Registry &config)
Definition Algorithm.cxx:62
Defines the EventRecordVisitorI interface. Concrete implementations of this interface use the 'Visito...
STDHEP-like event record entry that can fit a particle or a nucleus.
string Name(void) const
Name that corresponds to the PDG code.
int FirstMother(void) const
void SetLastDaughter(int d)
void SetRescatterCode(int code)
int Pdg(void) const
void SetFirstMother(int m)
const TLorentzVector * P4(void) const
double Charge(void) const
Chrg that corresponds to the PDG code.
int LastDaughter(void) const
TLorentzVector * GetX4(void) const
void SetStatus(GHepStatus_t s)
int Z(void) const
double E(void) const
Get energy.
double Pz(void) const
Get Pz.
int A(void) const
void SetFirstDaughter(int d)
GHepStatus_t Status(void) const
int FirstDaughter(void) const
GENIE's GHEP MC event record.
Definition GHepRecord.h:45
virtual GHepParticle * Probe(void) const
virtual Interaction * Summary(void) const
GEvGenMode_t EventGenerationMode(void) const
virtual void AddParticle(const GHepParticle &p)
virtual int TargetNucleusPosition(void) const
virtual int RemnantNucleusPosition(void) const
virtual GHepParticle * Particle(int position) const
virtual GHepParticle * FinalStatePrimaryLepton(void) const
const ProcessInfo & ProcInfo(void) const
Definition Interaction.h:70
static PDGLibrary * Instance(void)
bool IsQuasiElastic(void) const
A registry. Provides the container for algorithm configuration parameters.
Definition Registry.h:65
int IonPdgCode(int A, int Z)
Definition PDGUtils.cxx:71
Simple functions for loading and reading nucleus dependent keys from config files.
vector< string > Split(string input, string delim)
bool DirectoryExists(const char *path)
Root of GENIE utility namespaces.
THE MAIN GENIE PROJECT NAMESPACE
Definition AlgCmp.h:25
const int kPdgPiM
Definition PDGCodes.h:159
@ kIStIntermediateState
Definition GHepStatus.h:31
@ kIStHadronInTheNucleus
Definition GHepStatus.h:37
@ kIStFinalStateNuclearRemnant
Definition GHepStatus.h:38
@ kIStStableFinalState
Definition GHepStatus.h:30
const int kPdgProton
Definition PDGCodes.h:81
const int kPdgPi0
Definition PDGCodes.h:160
const int kPdgNeutron
Definition PDGCodes.h:83
enum genie::EGHepStatus GHepStatus_t
@ kGMdNucleonDecay
Definition GMode.h:30
@ kGMdLeptonNucleus
Definition GMode.h:26
@ kGMdHadronNucleus
Definition GMode.h:27
@ kGMdPhotonNucleus
Definition GMode.h:28
@ kGMdNeutronOsc
Definition GMode.h:31
const int kPdgHadronicBlob
Definition PDGCodes.h:211
const int kPdgPiP
Definition PDGCodes.h:158