GENIEGenerator
Loading...
Searching...
No Matches
GHepRecord.cxx
Go to the documentation of this file.
1//____________________________________________________________________________
2/*
3 Copyright (c) 2003-2025, The GENIE Collaboration
4 For the full text of the license visit http://copyright.genie-mc.org
5
6 Costas Andreopoulos <c.andreopoulos \at cern.ch>
7 University of Liverpool
8*/
9//____________________________________________________________________________
10
11#include <cassert>
12#include <algorithm>
13#include <iomanip>
14
15#include <TLorentzVector.h>
16#include <TVector3.h>
17#include <TSystem.h>
18#include <TRootIOCtor.h>
19
20#include "Framework/Conventions/GBuild.h"
31
32using std::endl;
33using std::setw;
34using std::setprecision;
35using std::setfill;
36using std::ios;
37
38using namespace genie;
39
41
43
44//___________________________________________________________________________
45namespace genie {
46 ostream & operator << (ostream & stream, const GHepRecord & rec)
47 {
48 rec.Print(stream);
49 return stream;
50 }
51}
52//___________________________________________________________________________
54TClonesArray("genie::GHepParticle")
55{
56 this->InitRecord();
57}
58//___________________________________________________________________________
60TClonesArray("genie::GHepParticle", size)
61{
62 this->InitRecord();
63}
64//___________________________________________________________________________
66TClonesArray("genie::GHepParticle", record.GetEntries())
67{
68 this->InitRecord();
69 this->Copy(record);
70}
71//___________________________________________________________________________
73TClonesArray("genie::GHepParticle"),
75fVtx(0),
77fEventMask(0),
78fWeight(0.),
79fProb(0.),
80fXSec(0.),
81fDiffXSec(0.)
82{
83
84}
85//___________________________________________________________________________
90//___________________________________________________________________________
92{
93 if(!fInteraction) {
94 LOG("GHEP", pWARN) << "Returning NULL interaction";
95 }
96 return fInteraction;
97}
98//___________________________________________________________________________
100{
101 fInteraction = interaction;
102}
103//___________________________________________________________________________
105{
106// Returns the GHepParticle from the specified position of the event record.
107
108 if( position >=0 && position < this->GetEntries() ) {
109 GHepParticle * particle = (GHepParticle *) (*this)[position];
110 if(particle) return particle;
111 }
112 LOG("GHEP", pINFO)
113 << "No particle found with: (pos = " << position << ")";
114
115 return 0;
116}
117//___________________________________________________________________________
119 int pdg, GHepStatus_t status, int start) const
120{
121// Returns the first GHepParticle with the input pdg-code and status
122// starting from the specified position of the event record.
123
124 int nentries = this->GetEntries();
125 for(int i = start; i < nentries; i++) {
126 GHepParticle * p = (GHepParticle *) (*this)[i];
127 if(p->Status() == status && p->Pdg() == pdg) return p;
128 }
129
130 LOG("GHEP", pINFO)
131 << "No particle found with: (pos >= " << start
132 << ", pdg = " << pdg << ", ist = " << status << ")";
133
134 return 0;
135}
136//___________________________________________________________________________
138 int pdg, GHepStatus_t status, int start) const
139{
140// Returns the position of the first GHepParticle with the input pdg-code
141// and status starting from the specified position of the event record.
142
143 int nentries = this->GetEntries();
144 for(int i = start; i < nentries; i++) {
145 GHepParticle * p = (GHepParticle *) (*this)[i];
146 if(p->Status() == status && p->Pdg() == pdg) return i;
148
149 LOG("GHEP", pINFO)
150 << "No particle found with: (pos >= " << start
151 << ", pdg = " << pdg << ", ist = " << status << ")";
152
153 return -1;
154}
155//___________________________________________________________________________
156int GHepRecord::ParticlePosition(GHepParticle * particle, int start) const
157{
158// Returns the position of the first match with the specified GHepParticle
159// starting from the specified position of the event record.
160
161 int nentries = this->GetEntries();
162 for(int i = start; i < nentries; i++) {
163 GHepParticle * p = (GHepParticle *) (*this)[i];
164 if( p->Compare(particle) ) return i;
165 }
166
167 LOG("GHEP", pINFO)
168 << "No particle found with pos >= " << start
169 << " matching particle: " << *particle;
170
171 return -1;
172}
173//___________________________________________________________________________
174vector<int> * GHepRecord::GetStableDescendants(int position) const
175{
176// Returns a list of all stable descendants of the GHEP entry in the input
177// slot. The user adopts the output vector.
178
179 // return null if particle index is out of range
180 int nentries = this->GetEntries();
181 if(position<0 || position>=nentries) return 0;
182
183 vector<int> * descendants = new vector<int>;
184
185 // return itself if it is a stable final state particle
186 if(this->Particle(position)->Status() == kIStStableFinalState) {
187 descendants->push_back(position);
188 return descendants;
189 }
190
191 for(int i = 0; i < nentries; i++) {
192 if(i==position) continue;
193 GHepParticle * p = (GHepParticle *) (*this)[i];
194 if(p->Status() != kIStStableFinalState) continue;
195 bool is_descendant=false;
196 int mom = p->FirstMother();
197 while(mom>-1) {
198 if(mom==position) is_descendant=true;
199 if(is_descendant) {
200 descendants->push_back(i);
201 break;
202 }
203 mom = this->Particle(mom)->FirstMother();
204 }
205 }
206 return descendants;
207}
208//___________________________________________________________________________
210{
211 GHepParticle * p0 = this->Particle(0);
212 if(!p0) return kGMdUnknown;
213 GHepParticle * p1 = this->Particle(1);
214 if(!p1) return kGMdUnknown;
215
216 int p0pdg = p0->Pdg();
217 GHepStatus_t p0st = p0->Status();
218 int p1pdg = p1->Pdg();
219 GHepStatus_t p1st = p1->Status();
220
221 // In lepton+nucleon/nucleus mode, the 1st entry in the event record
222 // is a charged or neutral lepton with status code = kIStInitialState
223 if( pdg::IsLepton(p0pdg) && p0st == kIStInitialState )
224 {
225 return kGMdLeptonNucleus;
226 }
227
228 // In dark matter mode, the 1st entry in the event record is a dark
229 // matter particle
230 if( (pdg::IsDarkMatter(p0pdg) || pdg::IsAntiDarkMatter(p0pdg)) && p0st == kIStInitialState )
231 {
233 }
234
235 // In hadron+nucleon/nucleus mode, the 1st entry in the event record
236 // is a hadron with status code = kIStInitialState and the 2nd entry
237 // is a nucleon or nucleus with status code = kIStInitialState
238 if( pdg::IsHadron(p0pdg) && p0st == kIStInitialState )
239 {
240 if( (pdg::IsIon(p1pdg) || pdg::IsNucleon(p1pdg)) && p1st == kIStInitialState)
241 {
242 return kGMdHadronNucleus;
243 }
244 }
245
246 // As above, with a photon as a probe
247 if( p0pdg == kPdgGamma && p0st == kIStInitialState )
248 {
249 if( (pdg::IsIon(p1pdg) || pdg::IsNucleon(p1pdg)) && p1st == kIStInitialState)
250 {
251 return kGMdPhotonNucleus;
252 }
253 }
254
255 // In nucleon decay mode,
256 // - [if the decayed nucleon was a bound one] the 1st entry in the event
257 // record is a nucleus with status code = kIStInitialState and the
258 // 2nd entry is a nucleon with code = kIStDecayedState
259 // - [if the decayed nucleon was a free one] the first entry in the event
260 // record is a nucleon with status code = kIStInitialState and it has a
261 // single daughter which is a nucleon with status code = kIStDecayedState.
262
263 if( pdg::IsIon(p0pdg) && p0st == kIStInitialState &&
264 pdg::IsNucleon(p1pdg) && p1st == kIStDecayedState)
265 {
266 return kGMdNucleonDecay;
267 }
268 if( pdg::IsNucleon(p0pdg) && p0st == kIStInitialState &&
269 pdg::IsNucleon(p1pdg) && p1st == kIStDecayedState)
270 {
271 return kGMdNucleonDecay;
272 }
273
274 // In HNL decay mode, the first entry is a HNL.
275
276 if( pdg::IsHNL(p0pdg) && p0st == kIStInitialState )
277 {
278 return kGMdHNLDecay;
279 }
280
281 return kGMdUnknown;
282}
283//___________________________________________________________________________
285{
286// Returns the GHepParticle representing the probe (neutrino, e,...).
287
288 int ipos = this->ProbePosition();
289 if(ipos>-1) return this->Particle(ipos);
290 return 0;
291}
292//___________________________________________________________________________
294{
295// Returns the GHepParticle representing the target / initial state nucleus,
296// or 0 if it does not exist.
297
298 int ipos = this->TargetNucleusPosition();
299 if(ipos>-1) return this->Particle(ipos);
300 return 0;
301}
302//___________________________________________________________________________
304{
305// Returns the GHepParticle representing the remnant nucleus,
306// or 0 if it does not exist.
307
308 int ipos = this->RemnantNucleusPosition();
309 if(ipos>-1) return this->Particle(ipos);
310 return 0;
311}
312//___________________________________________________________________________
314{
315// Returns the GHepParticle representing the struck nucleon, or 0 if it does
316// not exist.
317
318 int ipos = this->HitNucleonPosition();
319 if(ipos>-1) return this->Particle(ipos);
320 return 0;
321}
322//___________________________________________________________________________
324{
325// Returns the GHepParticle representing the struck electron, or 0 if it does
326// not exist.
327
328 int ipos = this->HitElectronPosition();
329 if(ipos>-1) return this->Particle(ipos);
330 return 0;
331}
332//___________________________________________________________________________
334{
335// Returns the GHepParticle representing the final state primary lepton.
336
337 int ipos = this->FinalStatePrimaryLeptonPosition();
338 if(ipos>-1) return this->Particle(ipos);
339 return 0;
340}
341//___________________________________________________________________________
343{
344// Returns the GHepParticle representing the sum of the DIS pre-fragm f/s
345// hadronic system, or 0 if it does not exist.
346
347 int ipos = this->FinalStateHadronicSystemPosition();
348 if(ipos>-1) return this->Particle(ipos);
349 return 0;
350}
351//___________________________________________________________________________
353{
354// Returns the GHEP position of the GHepParticle representing the probe
355// (neutrino, e,...).
356
357 // The probe is *always* at slot 0.
358 GEvGenMode_t mode = this->EventGenerationMode();
359 if(mode == kGMdLeptonNucleus ||
360 mode == kGMdDarkMatterNucleus ||
361 mode == kGMdHadronNucleus ||
362 mode == kGMdPhotonNucleus ||
363 mode == kGMdHNLDecay)
364 {
365 return 0;
366 }
367 return -1;
368}
369//___________________________________________________________________________
371{
372// Returns the GHEP position of the GHepParticle representing the target
373// nucleus - or -1 if the interaction takes place at a free nucleon.
374
375 GEvGenMode_t mode = this->EventGenerationMode();
376
377 if(mode == kGMdLeptonNucleus ||
378 mode == kGMdDarkMatterNucleus ||
379 mode == kGMdHadronNucleus ||
380 mode == kGMdPhotonNucleus)
381 {
382 GHepParticle * p = this->Particle(1); // If exists, it will be at slot 1
383 if(!p) return -1;
384 int pdgc = p->Pdg();
385 if(pdg::IsIon(pdgc) && p->Status()==kIStInitialState) return 1;
386 }
387 if(mode == kGMdNucleonDecay) {
388 GHepParticle * p = this->Particle(0); // If exists, it will be at slot 0
389 if(!p) return -1;
390 int pdgc = p->Pdg();
391 if(pdg::IsIon(pdgc) && p->Status()==kIStInitialState) return 0;
392 }
393
394 return -1;
395}
396//___________________________________________________________________________
398{
399// Returns the GHEP position of the GHepParticle representing the remnant
400// nucleus - or -1 if the interaction takes place at a free nucleon.
401
402 GHepParticle * p = this->TargetNucleus();
403 if(!p) return -1;
404
405 int dau1 = p->FirstDaughter();
406 int dau2 = p->LastDaughter();
407
408 if(dau1==-1 && dau2==-1) return -1;
409
410 for(int i=dau1; i<=dau2; i++) {
411 GHepParticle * dp = this->Particle(i);
412 int dpdgc = dp->Pdg();
413 if(pdg::IsIon(dpdgc) && dp->Status()==kIStStableFinalState) return i;
414 }
415 return -1;
416}
417//___________________________________________________________________________
419{
420// Returns the GHEP position of the GHepParticle representing the hit nucleon.
421// If a struck nucleon is set it will be at slot 2 (for scattering off nuclear
422// targets) or at slot 1 (for free nucleon scattering).
423// If the struck nucleon is not set (eg coherent scattering, ve- scattering)
424// it returns 0.
425
426 GHepParticle * nucleus = this->TargetNucleus();
427
428 int ipos = (nucleus) ? 2 : 1;
430
431 GHepParticle * p = this->Particle(ipos);
432 if(!p) return -1;
433
434// bool isN = pdg::IsNeutronOrProton(p->Pdg());
435 bool isN = pdg::IsNucleon(p->Pdg()) || pdg::Is2NucleonCluster(p->Pdg());
436 if(isN && p->Status()==ist) return ipos;
437
438 return -1;
439}
440//___________________________________________________________________________
442{
443// Returns the GHEP position of the GHepParticle representing a hit electron.
444// Same as above..
445
446 GHepParticle * nucleus = this->TargetNucleus();
447
448 int ipos = (nucleus) ? 2 : 1;
449
450 GHepParticle * p = this->Particle(ipos);
451 if(!p) return -1;
452
453 bool ise = pdg::IsElectron(p->Pdg());
454 if(ise && p->Status()==kIStInitialState) return ipos;
455
456 return -1;
457}
458//___________________________________________________________________________
460{
461// Returns the GHEP position GHepParticle representing the final state
462// primary lepton.
463
464 GHepParticle * probe = this->Probe();
465 if(!probe) return -1;
466
467 int ifsl = probe->FirstDaughter();
468 return ifsl;
469}
470//___________________________________________________________________________
476//___________________________________________________________________________
477unsigned int GHepRecord::NEntries(int pdg, GHepStatus_t ist, int start) const
478{
479 unsigned int nentries = 0;
480
481 for(int i = start; i < this->GetEntries(); i++) {
482 GHepParticle * p = (GHepParticle *) (*this)[i];
483 if(p->Pdg()==pdg && p->Status()==ist) nentries++;
484 }
485 return nentries;
486}
487//___________________________________________________________________________
488unsigned int GHepRecord::NEntries(int pdg, int start) const
489{
490 unsigned int nentries = 0;
491
492 for(int i = start; i < this->GetEntries(); i++) {
493 GHepParticle * p = (GHepParticle *) (*this)[i];
494 if(p->Pdg()==pdg) nentries++;
495 }
496 return nentries;
497}
498//___________________________________________________________________________
500{
501// Provides a simplified method for inserting entries in the TClonesArray
502
503 unsigned int pos = this->GetEntries();
504
505#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
506 LOG("GHEP", pINFO)
507 << "Adding particle with pdgc = " << p.Pdg() << " at slot = " << pos;
508#endif
509 new ((*this)[pos]) GHepParticle(p);
510
511 // Update the mother's daughter list. If the newly inserted particle broke
512 // compactification, then run CompactifyDaughterLists()
513 this->UpdateDaughterLists();
514}
515//___________________________________________________________________________
517 int pdg, GHepStatus_t status, int mom1, int mom2, int dau1, int dau2,
518 const TLorentzVector & p, const TLorentzVector & v)
519{
520// Provides a 'simplified' method for inserting entries in the TClonesArray
521
522 unsigned int pos = this->GetEntries();
523
524#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
525 LOG("GHEP", pINFO)
526 << "Adding particle with pdgc = " << pdg << " at slot = " << pos;
527#endif
528 new ((*this)[pos]) GHepParticle(pdg,status, mom1,mom2,dau1,dau2, p, v);
529
530 // Update the mother's daughter list. If the newly inserted particle broke
531 // compactification, then run CompactifyDaughterLists()
532 this->UpdateDaughterLists();
533}
534//___________________________________________________________________________
536 int pdg, GHepStatus_t status, int mom1, int mom2, int dau1, int dau2,
537 double px, double py, double pz, double E,
538 double x, double y, double z, double t)
539{
540// Provides a 'simplified' method for inserting entries in the TClonesArray
541
542 unsigned int pos = this->GetEntries();
543
544#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
545 LOG("GHEP", pINFO)
546 << "Adding particle with pdgc = " << pdg << " at slot = " << pos;
547#endif
548 new ( (*this)[pos] ) GHepParticle (
549 pdg, status, mom1, mom2, dau1, dau2, px, py, pz, E, x, y, z, t);
550
551 // Update the mother's daughter list. If the newly inserted particle broke
552 // compactification, then run CompactifyDaughterLists()
553 this->UpdateDaughterLists();
554}
555//___________________________________________________________________________
557{
558 int pos = this->GetEntries() - 1; // position of last entry
559
560#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
561 LOG("GHEP", pINFO)
562 << "Updating the daughter-list for the mother of particle at: " << pos;
563#endif
564
565 GHepParticle * p = this->Particle(pos);
566 assert(p);
567
568 int mom_pos = p->FirstMother();
569#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
570 LOG("GHEP", pINFO) << "Mother particle is at slot: " << mom_pos;
571#endif
572 if(mom_pos==-1) return; // may not have mom (eg init state)
573 GHepParticle * mom = this->Particle(mom_pos);
574 if(!mom) return; // may not have mom (eg init state)
575
576 int dau1 = mom->FirstDaughter();
577 int dau2 = mom->LastDaughter();
578
579 // handles the case where the daughter list was initially empty
580 if(dau1 == -1) {
581 mom->SetFirstDaughter(pos);
582 mom->SetLastDaughter(pos);
583 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
584 LOG("GHEP", pINFO)
585 << "Done! Daughter-list is compact: [" << pos << ", " << pos << "]";
586 #endif
587 return;
588 }
589 // handles the case where the new daughter is added at the slot just before
590 // an already compact daughter list
591 if(pos == dau1-1) {
592 mom->SetFirstDaughter(pos);
593 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
594 LOG("GHEP", pINFO)
595 << "Done! Daughter-list is compact: [" << pos << ", " << dau2 << "]";
596 #endif
597 return;
598 }
599 // handles the case where the new daughter is added at the slot just after
600 // an already compact daughter list
601 if(pos == dau2+1) {
602 mom->SetLastDaughter(pos);
603 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
604 LOG("GHEP", pINFO)
605 << "Done! Daughter-list is compact: [" << dau1 << ", " << pos << "]";
606 #endif
607 return;
608 }
609
610 // If you are here, then the last particle insertion broke the daughter
611 // list compactification - Run the compactifier
612 LOG("GHEP", pNOTICE)
613 << "Daughter-list is not compact - Running compactifier";
615}
616//___________________________________________________________________________
618{
619 LOG("GHEP", pNOTICE) << "Removing all intermediate particles from GHEP";
620 this->Compress();
621
622 int i=0;
623 GHepParticle * p = 0;
624
625 TIter iter(this);
626 while( (p = (GHepParticle *)iter.Next()) ) {
627
628 if(!p) continue;
629 GHepStatus_t ist = p->Status();
630
631 bool keep = (ist==kIStInitialState) ||
633 if(keep) {
634 p->SetFirstDaughter(-1);
635 p->SetLastDaughter(-1);
636 p->SetFirstMother(-1);
637 p->SetLastMother(-1);
638 } else {
639 LOG("GHEP", pNOTICE)
640 << "Removing: " << p->Name() << " from slot: " << i;
641 this->RemoveAt(i);
642 }
643 i++;
644 }
645#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
646 LOG("GHEP", pDEBUG) << "Compressing GHEP record to remove empty slots";
647#endif
648 this->Compress();
649}
650//___________________________________________________________________________
652{
653 int n = this->GetEntries();
654 if(n<1) return;
655
656 int i = this->Particle(n-1)->FirstMother();
657 if(i<0) return;
658
659 // for(int i=0; i<n; i++) {
660 bool compact = this->HasCompactDaughterList(i);
661
662#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
663 LOG("GHEP", pNOTICE)
664 << "Particle's " << i << " daughter list is "
665 << ((compact) ? "compact" : "__not__ compact");
666#endif
667
668 if(!compact) {
669 GHepParticle * p = this->Particle(i);
670
671 int dau1 = p->FirstDaughter();
672 int dau2 = p->LastDaughter();
673 int ndau = dau2-dau1+1;
674 int ndp = dau2+1;
675 if(dau1==-1) {ndau=0;}
676
677 int curr_pos = n-1;
678 while (curr_pos > ndp) {
679 this->SwapParticles(curr_pos,curr_pos-1);
680 curr_pos--;
681 }
682 if(ndau>0) {
683 this->Particle(i)->SetFirstDaughter(dau1);
684 this->Particle(i)->SetLastDaughter(dau2+1);
685 } else {
686 this->Particle(i)->SetFirstDaughter(-1);
687 this->Particle(i)->SetLastDaughter(-1);
688 }
689 this->FinalizeDaughterLists();
690
691 } //!compact
692
693#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
694 LOG("GHEP", pINFO)
695 << "Done ompactifying daughter-list for particle at slot: " << i;
696#endif
697 // }
698}
699//___________________________________________________________________________
701{
702#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
703 LOG("GHEP", pDEBUG) << "Examining daughter-list of particle at: " << pos;
704#endif
705 vector<int> daughters;
706 GHepParticle * p = 0;
707 TIter iter(this);
708 int i=0;
709 while( (p = (GHepParticle *)iter.Next()) ) {
710 if(p->FirstMother() == pos) {
711
712#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
713 LOG("GHEP", pDEBUG) << "Particle at: " << i << " is a daughter";
714#endif
715 daughters.push_back(i);
716 }
717 i++;
718 }
719
720 bool is_compact = true;
721 if(daughters.size()>1) {
722 sort(daughters.begin(), daughters.end());
723 vector<int>::iterator diter = daughters.begin();
724 int prev = *diter;
725 for(; diter != daughters.end(); ++diter) {
726 int curr = *diter;
727 is_compact = is_compact && (TMath::Abs(prev-curr)<=1);
728 prev = curr;
729 }
730 }
731#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
732 LOG("GHEP", pINFO)
733 << "Daughter-list of particle at: " << pos << " is "
734 << (is_compact ? "" : "not") << " compact";
735#endif
736 return is_compact;
737}
738//___________________________________________________________________________
740{
741 GHepParticle * p = 0;
742 TIter iter(this);
743 int pos = 0;
744 while( (p = (GHepParticle *)iter.Next()) ) {
745 int ist = p->Status();
746 if(ist != kIStInitialState && ist != kIStNucleonTarget) return pos;
747 pos++;
748 }
749 return pos;
750}
751//___________________________________________________________________________
753{
754#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
755 LOG("GHEP", pINFO) << "Swapping GHepParticles : " << i << " <--> " << j;
756#endif
757 int n = this->GetEntries();
758 assert(i>=0 && j>=0 && i<n && j<n);
759
760 if(i==j) return;
761
762 GHepParticle * pi = this->Particle(i);
763 GHepParticle * pj = this->Particle(j);
764 GHepParticle * tmp = new GHepParticle(*pi);
765
766 pi->Copy(*pj);
767 pj->Copy(*tmp);
768
769 delete tmp;
770
771 // tell their daughters
772 if(pi->HasDaughters()) {
773#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
774 LOG("GHEP", pINFO)
775 << pi->Name() << "(previously at pos: " << j
776 << ") is now at pos: " << i << " -> Notify daughters";
777#endif
778 for(int k=0; k<n; k++) {
779 if(this->Particle(k)->FirstMother()==j) {
780 this->Particle(k)->SetFirstMother(i);
781 }
782 }
783 }
784
785 if(pj->HasDaughters()) {
786#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
787 LOG("GHEP", pINFO)
788 << pj->Name() << "(previously at pos: " << i
789 << ") is now at pos: " << j << " -> Notify daughters";
790#endif
791 for(int k=0; k<n; k++) {
792 if(this->Particle(k)->FirstMother()==i) {
793 this->Particle(k)->SetFirstMother(j);
794 }
795 }
796 }
797}
798//___________________________________________________________________________
800{
801// Update all daughter-lists based on particle 'first mother' field.
802// To work correctly, the daughter-lists must have been compactified first.
803
804 GHepParticle * p1 = 0;
805 TIter iter1(this);
806 int i1=0;
807 while( (p1 = (GHepParticle *)iter1.Next()) ) {
808 int dau1 = -1;
809 int dau2 = -1;
810 GHepParticle * p2 = 0;
811 TIter iter2(this);
812 int i2=0;
813 while( (p2 = (GHepParticle *)iter2.Next()) ) {
814
815 if(p2->FirstMother() == i1) {
816 dau1 = (dau1<0) ? i2 : TMath::Min(dau1,i2);
817 dau2 = (dau2<0) ? i2 : TMath::Max(dau2,i2);
818 }
819 i2++;
820 }
821 i1++;
822 p1 -> SetFirstDaughter (dau1);
823 p1 -> SetLastDaughter (dau2);
824 }
825}
826//___________________________________________________________________________
827void GHepRecord::SetVertex(double x, double y, double z, double t)
828{
829 fVtx->SetXYZT(x,y,z,t);
830}
831//___________________________________________________________________________
832void GHepRecord::SetVertex(const TLorentzVector & vtx)
833{
834 fVtx->SetXYZT(vtx.X(),vtx.Y(),vtx.Z(),vtx.T());
835}
836//___________________________________________________________________________
838{
839#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
840 LOG("GHEP", pDEBUG) << "Initializing GHepRecord";
841#endif
842 fInteraction = 0;
843 fWeight = 1.;
844 fProb = 1.;
845 fXSec = 0.;
846 fDiffXSec = 0.;
848 fVtx = new TLorentzVector(0,0,0,0);
849
850 fEventFlags = new TBits(GHepFlags::NFlags());
851 fEventFlags -> ResetAllBits(false);
852
853 fEventMask = new TBits(GHepFlags::NFlags());
854//fEventMask -> ResetAllBits(true);
855 for(unsigned int i = 0; i < GHepFlags::NFlags(); i++) {
856 fEventMask->SetBitNumber(i, true);
857 }
858
859 LOG("GHEP", pINFO)
860 << "Initialised unphysical event mask (bits: " << GHepFlags::NFlags() - 1
861 << " -> 0) : " << *fEventMask;
862
863 this->SetOwner(true);
864}
865//___________________________________________________________________________
867{
868#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
869 LOG("GHEP", pDEBUG) << "Cleaning up GHepRecord";
870#endif
871 this->Clear("C");
872}
873//___________________________________________________________________________
875{
876#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
877 LOG("GHEP", pDEBUG) << "Reseting GHepRecord";
878#endif
879 this->CleanRecord();
880 this->InitRecord();
881}
882//___________________________________________________________________________
883void GHepRecord::Clear(Option_t * opt)
884{
885 if (fInteraction) delete fInteraction;
886 fInteraction=0;
887
888 if (fVtx) delete fVtx;
889 fVtx=0;
890
891 if(fEventFlags) delete fEventFlags;
892 fEventFlags=0;
893
894 if(fEventMask) delete fEventMask;
895 fEventMask=0;
896
897 TClonesArray::Clear(opt);
898
899// if (fInteraction) delete fInteraction;
900// delete fVtx;
901//
902// delete fEventFlags;
903//
904// TClonesArray::Clear(opt);
905}
906//___________________________________________________________________________
907void GHepRecord::Copy(const GHepRecord & record)
908{
909 // clean up
910 this->ResetRecord();
911
912 // copy event record entries
913 unsigned int ientry = 0;
914 GHepParticle * p = 0;
915 TIter ghepiter(&record);
916 while ( (p = (GHepParticle *) ghepiter.Next()) )
917 new ( (*this)[ientry++] ) GHepParticle(*p);
918
919 // copy summary
920 fInteraction = new Interaction( *record.fInteraction );
921
922 // copy flags & mask
923 *fEventFlags = *(record.EventFlags());
924 *fEventMask = *(record.EventMask());
925
926 // copy vtx position
927 TLorentzVector * v = record.Vertex();
928 fVtx->SetXYZT(v->X(),v->Y(),v->Z(),v->T());
929
930 // copy weights & xsecs
931 fWeight = record.fWeight;
932 fProb = record.fProb;
933 fXSec = record.fXSec;
934 fDiffXSec = record.fDiffXSec;
936}
937//___________________________________________________________________________
938void GHepRecord::SetUnphysEventMask(const TBits & mask)
939{
940 *fEventMask = mask;
941
942 LOG("GHEP", pINFO)
943 << "Setting unphysical event mask (bits: " << GHepFlags::NFlags() - 1
944 << " -> 0) : " << *fEventMask;
945}
946//___________________________________________________________________________
947bool GHepRecord::Accept(void) const
948{
949 TBits flags = *fEventFlags;
950 TBits mask = *fEventMask;
951 TBits bitwiseand = flags & mask;
952 bool accept = (bitwiseand.CountBits() == 0);
953 return accept;
954}
955//___________________________________________________________________________
956void GHepRecord::SetPrintLevel(int print_level)
957{
958 fPrintLevel = print_level;
959}
961{
962 return fPrintLevel;
963}
964//___________________________________________________________________________
965void GHepRecord::Print(ostream & stream) const
966{
967 // Print levels:
968 // 0 -> prints particle list
969 // 1 -> prints particle list + event flags
970 // 2 -> prints particle list + event flags + wght/xsec
971 // 3 -> prints particle list + event flags + wght/xsec + summary
972 // 10 -> as in level 0 but showing particle positions too
973 // 11 -> as in level 1 but showing particle positions too
974 // 12 -> as in level 2 but showing particle positions too
975 // 13 -> as in level 3 but showing particle positions too
976
977 bool accept_input_print_level =
978 (fPrintLevel >= 0 && fPrintLevel <= 3) ||
979 (fPrintLevel >=10 && fPrintLevel <=13);
980
981 int printlevel = (accept_input_print_level) ? fPrintLevel : 3;
982 int printlevel_orig = printlevel;
983
984 bool showpos = false;
985 if(printlevel >= 10) {
986 printlevel-=10;
987 showpos=true;
988 }
989
990 stream << "\n\n|";
991 stream << setfill('-') << setw(115) << "|";
992
993 stream << "\n|GENIE GHEP Event Record [print level: "
994 << setfill(' ') << setw(3) << printlevel_orig << "]"
995 << setfill(' ') << setw(73) << "|";
996
997 stream << "\n|";
998 stream << setfill('-') << setw(115) << "|";
999
1000 stream << "\n| ";
1001 stream << setfill(' ') << setw(6) << "Idx | "
1002 << setfill(' ') << setw(16) << "Name | "
1003 << setfill(' ') << setw(6) << "Ist | "
1004 << setfill(' ') << setw(13) << "PDG | "
1005 << setfill(' ') << setw(12) << "Mother | "
1006 << setfill(' ') << setw(12) << "Daughter | "
1007 << setfill(' ') << setw(10) << ((showpos) ? "Px(x) |" : "Px | ")
1008 << setfill(' ') << setw(10) << ((showpos) ? "Py(y) |" : "Py | ")
1009 << setfill(' ') << setw(10) << ((showpos) ? "Pz(z) |" : "Pz | ")
1010 << setfill(' ') << setw(10) << ((showpos) ? "E(t) |" : "E | ")
1011 << setfill(' ') << setw(10) << "m | ";
1012
1013 stream << "\n|";
1014 stream << setfill('-') << setw(115) << "|";
1015
1016 GHepParticle * p = 0;
1017 TObjArrayIter piter(this);
1018 TVector3 polarization(0,0,0);
1019
1020 unsigned int idx = 0;
1021
1022 double sum_E = 0;
1023 double sum_px = 0;
1024 double sum_py = 0;
1025 double sum_pz = 0;
1026
1027 while( (p = (GHepParticle *) piter.Next()) ) {
1028
1029 stream << "\n| ";
1030 stream << setfill(' ') << setw(3) << idx++ << " | ";
1031 stream << setfill(' ') << setw(13) << p->Name() << " | ";
1032 stream << setfill(' ') << setw(3) << p->Status() << " | ";
1033 stream << setfill(' ') << setw(10) << p->Pdg() << " | ";
1034 stream << setfill(' ') << setw(3) << p->FirstMother() << " | ";
1035 stream << setfill(' ') << setw(3) << p->LastMother() << " | ";
1036 stream << setfill(' ') << setw(3) << p->FirstDaughter() << " | ";
1037 stream << setfill(' ') << setw(3) << p->LastDaughter() << " | ";
1038 stream << std::fixed << setprecision(3);
1039 stream << setfill(' ') << setw(7) << p->Px() << " | ";
1040 stream << setfill(' ') << setw(7) << p->Py() << " | ";
1041 stream << setfill(' ') << setw(7) << p->Pz() << " | ";
1042 stream << setfill(' ') << setw(7) << p->E() << " | ";
1043
1044 if (p->IsOnMassShell())
1045 stream << setfill(' ') << setw(7) << p->Mass() << " | ";
1046 else
1047 stream << setfill('*') << setw(7) << p->Mass() << " | M = "
1048 << p->P4()->M() << " ";
1049
1050 if (p->PolzIsSet()) {
1051 p->GetPolarization(polarization);
1052 stream << "P = (" << polarization.x() << "," << polarization.y()
1053 << "," << polarization.z() << ")";
1054 }
1055
1056 if (p->RescatterCode() != -1) {
1057 stream << "FSI = " << p->RescatterCode();
1058 }
1059
1060 // plot particle position if requested
1061 if(showpos) {
1062 stream << "\n| ";
1063 stream << setfill(' ') << setw(6) << " | ";
1064 stream << setfill(' ') << setw(16) << " | ";
1065 stream << setfill(' ') << setw(6) << " | ";
1066 stream << setfill(' ') << setw(13) << " | ";
1067 stream << setfill(' ') << setw(6) << " | ";
1068 stream << setfill(' ') << setw(6) << " | ";
1069 stream << setfill(' ') << setw(6) << " | ";
1070 stream << setfill(' ') << setw(6) << " | ";
1071 stream << std::fixed << setprecision(3);
1072 stream << setfill(' ') << setw(7) << p->Vx() << " | ";
1073 stream << setfill(' ') << setw(7) << p->Vy() << " | ";
1074 stream << setfill(' ') << setw(7) << p->Vz() << " | ";
1075 stream << setfill(' ') << setw(7) << p->Vt() << " | ";
1076 stream << setfill(' ') << setw(10) << " | ";
1077 }
1078
1079 // compute P4_{final} - P4_{nitial}
1080
1081 if(p->Status() == kIStStableFinalState ||
1083
1084 sum_E += p->E();
1085 sum_px += p->Px();
1086 sum_py += p->Py();
1087 sum_pz += p->Pz();
1088 } else
1089 if(p->Status() == kIStInitialState) {
1090 /*
1091 if(p->Status() == kIStInitialState || p->Status() == kIStNucleonTarget) {
1092 */
1093 sum_E -= p->E();
1094 sum_px -= p->Px();
1095 sum_py -= p->Py();
1096 sum_pz -= p->Pz();
1097 }
1098
1099 } // loop over particles
1100
1101 stream << "\n|";
1102 stream << setfill('-') << setw(115) << "|";
1103
1104 // Print SUMS
1105 stream << "\n| ";
1106 stream << setfill(' ') << setw(17) << "Fin-Init: "
1107 << setfill(' ') << setw(6) << " "
1108 << setfill(' ') << setw(18) << " "
1109 << setfill(' ') << setw(12) << " "
1110 << setfill(' ') << setw(12) << " | ";
1111 stream << std::fixed << setprecision(3);
1112 stream << setfill(' ') << setw(7) << sum_px << " | ";
1113 stream << setfill(' ') << setw(7) << sum_py << " | ";
1114 stream << setfill(' ') << setw(7) << sum_pz << " | ";
1115 stream << setfill(' ') << setw(7) << sum_E << " | ";
1116 stream << setfill(' ') << setw(10) << " | ";
1117
1118 stream << "\n|";
1119 stream << setfill('-') << setw(115) << "|";
1120
1121 // Print vertex
1122
1123 GHepParticle * probe = this->Probe();
1124 if(probe){
1125 stream << "\n| ";
1126 stream << setfill(' ') << setw(17) << "Vertex: ";
1127 stream << setfill(' ') << setw(11)
1128 << ((probe) ? probe->Name() : "unknown probe") << " @ (";
1129
1130 stream << std::fixed << setprecision(5);
1131 stream << "x = " << setfill(' ') << setw(11) << this->Vertex()->X() << " m, ";
1132 stream << "y = " << setfill(' ') << setw(11) << this->Vertex()->Y() << " m, ";
1133 stream << "z = " << setfill(' ') << setw(11) << this->Vertex()->Z() << " m, ";
1134 stream << std::scientific << setprecision(6);
1135 stream << "t = " << setfill(' ') << setw(15) << this->Vertex()->T() << " s) ";
1136 stream << std::fixed << setprecision(3);
1137 stream << setfill(' ') << setw(2) << "|";
1138
1139 stream << "\n|";
1140 stream << setfill('-') << setw(115) << "|";
1141 }
1142
1143 // Print FLAGS
1144
1145 if(printlevel>=1) {
1146 stream << "\n| ";
1147 stream << "Err flag [bits:" << fEventFlags->GetNbits()-1 << "->0] : "
1148 << *fEventFlags << " | "
1149 << "1st set: " << setfill(' ') << setw(56)
1150 << ( this->IsUnphysical() ?
1151 GHepFlags::Describe(GHepFlag_t(fEventFlags->FirstSetBit())) :
1152 "none") << " | ";
1153 stream << "\n| ";
1154 stream << "Err mask [bits:" << fEventMask->GetNbits()-1 << "->0] : "
1155 << *fEventMask << " | "
1156 << "Is unphysical: " << setfill(' ') << setw(5)
1157 << utils::print::BoolAsYNString(this->IsUnphysical()) << " | "
1158 << "Accepted: " << setfill(' ') << setw(5)
1160 << " |";
1161 stream << "\n|";
1162 stream << setfill('-') << setw(115) << "|";
1163 }
1164
1165 if(printlevel>=2) {
1166 stream << "\n| ";
1167 stream << std::scientific << setprecision(5);
1168
1169 stream << "sig(Ev) = "
1170 << setfill(' ') << setw(17) << fXSec/units::cm2
1171 << " cm^2 |";
1172
1173 switch(fDiffXSecPhSp) {
1174 case ( kPSyfE ) :
1175 stream << " dsig(y;E)/dy = " << setfill(' ') << setw(13) << fDiffXSec/units::cm2 << " cm^2 |";
1176 break;
1177 case ( kPSxyfE ) :
1178 stream << " d2sig(x,y;E)/dxdy = " << setfill(' ') << setw(13) << fDiffXSec/units::cm2 << " cm^2 |";
1179 break;
1180 case ( kPSxytfE ) :
1181 stream << " d3sig(x,y,t;E)/dxdydt = " << setfill(' ') << setw(13) << fDiffXSec/units::cm2 << " cm^2/GeV^2 |";
1182 break;
1183 case ( kPSQ2fE ) :
1184 stream << " dsig(Q2;E)/dQ2 = " << setfill(' ') << setw(13) << fDiffXSec/units::cm2 << " cm^2/GeV^2 |";
1185 break;
1186 case ( kPSQ2vpfE ) :
1187 stream << " dsig(Q2,v,p;E)/dQ2dvdp =" << setfill(' ') << setw(13) << fDiffXSec/units::cm2 << " cm^2/GeV^4 |";
1188 break;
1189 case ( kPSWQ2fE ) :
1190 stream << " d2sig(W,Q2;E)/dWdQ2 = " << setfill(' ') << setw(13) << fDiffXSec/units::cm2 << " cm^2/GeV^3 |";
1191 break;
1192 case ( kPSWQ2ctpphipfE ) :
1193 stream << " d4sig(W,Q2,cos(theta),phi;E)/dWdQ2dOmega = " << setfill(' ') << setw(13) << fDiffXSec/units::cm2 << " cm^2/GeV^3 |";
1194 break;
1195 default :
1196 stream << " dsig(Ev;{K_s})/dK = " << setfill(' ') << setw(13) << fDiffXSec/units::cm2 << " cm^2/{K} |";
1197 }
1198 stream << " Weight = "
1199 << setfill(' ') << setw(16)
1200 << std::fixed << setprecision(5)
1201 << fWeight
1202 << " |";
1203
1204 stream << "\n|";
1205 stream << setfill('-') << setw(115) << "|";
1206 }
1207
1208 stream << "\n";
1209 stream << setfill(' ');
1210
1211 if(printlevel==3) {
1212 if(fInteraction) stream << *fInteraction;
1213 else stream << "NULL Interaction!" << endl;
1214 }
1215 stream << "\n";
1216}
1217//___________________________________________________________________________
ClassImp(EventRecord) namespace genie
#define pNOTICE
Definition Messenger.h:61
#define pINFO
Definition Messenger.h:62
#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
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils.
static const char * Describe(GHepFlag_t flag)
Definition GHepFlags.h:42
static unsigned int NFlags(void)
Definition GHepFlags.h:76
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)
int Pdg(void) const
void Copy(const GHepParticle &particle)
void SetFirstMother(int m)
void SetLastMother(int m)
double Vy(void) const
Get production y.
const TLorentzVector * P4(void) const
double Mass(void) const
Mass that corresponds to the PDG code.
int LastMother(void) const
int LastDaughter(void) const
bool IsOnMassShell(void) const
bool HasDaughters(void) const
double Px(void) const
Get Px.
double E(void) const
Get energy.
double Pz(void) const
Get Pz.
double Py(void) const
Get Py.
double Vz(void) const
Get production z.
bool PolzIsSet(void) const
int RescatterCode(void) const
void SetFirstDaughter(int d)
GHepStatus_t Status(void) const
double Vx(void) const
Get production x.
double Vt(void) const
Get production time.
void GetPolarization(TVector3 &polz)
int FirstDaughter(void) const
bool Compare(const GHepParticle *p) const
GENIE's GHEP MC event record.
Definition GHepRecord.h:45
virtual bool HasCompactDaughterList(int pos)
double fProb
event probability (for given flux neutrino and density-weighted path-length for target element)
Definition GHepRecord.h:179
TLorentzVector * fVtx
vertex in the detector coordinate system
Definition GHepRecord.h:171
virtual void SwapParticles(int i, int j)
void Print(ostream &stream) const
virtual int ParticlePosition(int pdg, GHepStatus_t i, int start=0) const
virtual int FinalStateHadronicSystemPosition(void) const
virtual int ProbePosition(void) const
virtual GHepParticle * Probe(void) const
KinePhaseSpace_t fDiffXSecPhSp
specifies which differential cross-section (dsig/dQ2, dsig/dQ2dW, dsig/dxdy,...)
Definition GHepRecord.h:182
virtual int HitElectronPosition(void) const
static int fPrintLevel
Definition GHepRecord.h:196
virtual void AttachSummary(Interaction *interaction)
double fDiffXSec
differential cross section for selected event kinematics
Definition GHepRecord.h:181
virtual void ResetRecord(void)
void InitRecord(void)
virtual GHepParticle * FindParticle(int pdg, GHepStatus_t ist, int start) const
virtual bool Accept(void) const
void SetUnphysEventMask(const TBits &mask)
virtual void UpdateDaughterLists(void)
virtual GHepParticle * HitElectron(void) const
virtual GHepParticle * TargetNucleus(void) const
virtual int FinalStatePrimaryLeptonPosition(void) const
virtual Interaction * Summary(void) const
virtual void CompactifyDaughterLists(void)
Interaction * fInteraction
attached summary information
Definition GHepRecord.h:168
virtual unsigned int NEntries(int pdg, GHepStatus_t ist, int start=0) const
TBits * fEventFlags
event flags indicating various pathologies or an unphysical event
Definition GHepRecord.h:174
virtual TBits * EventFlags(void) const
Definition GHepRecord.h:117
virtual TBits * EventMask(void) const
Definition GHepRecord.h:118
GEvGenMode_t EventGenerationMode(void) const
virtual void FinalizeDaughterLists(void)
virtual void RemoveIntermediateParticles(void)
virtual GHepParticle * RemnantNucleus(void) const
static int GetPrintLevel()
double fWeight
event weight
Definition GHepRecord.h:178
virtual void AddParticle(const GHepParticle &p)
TBits * fEventMask
an input bit-field mask allowing one to ignore bits set in fEventFlags
Definition GHepRecord.h:175
virtual void Clear(Option_t *opt="")
virtual void Copy(const GHepRecord &record)
virtual GHepParticle * FinalStateHadronicSystem(void) const
virtual int TargetNucleusPosition(void) const
virtual TLorentzVector * Vertex(void) const
Definition GHepRecord.h:140
void CleanRecord(void)
virtual int RemnantNucleusPosition(void) const
virtual void SetVertex(double x, double y, double z, double t)
virtual vector< int > * GetStableDescendants(int position) const
virtual GHepParticle * Particle(int position) const
static void SetPrintLevel(int print_level)
virtual ~GHepRecord()
virtual GHepParticle * FinalStatePrimaryLepton(void) const
virtual int FirstNonInitStateEntry(void)
virtual int HitNucleonPosition(void) const
double fXSec
cross section for selected event
Definition GHepRecord.h:180
virtual GHepParticle * HitNucleon(void) const
virtual bool IsUnphysical(void) const
Definition GHepRecord.h:119
Summary information for an interaction.
Definition Interaction.h:56
Utilities for improving the code readability when using PDG codes.
bool Is2NucleonCluster(int pdgc)
Definition PDGUtils.cxx:402
bool IsLepton(int pdgc)
Definition PDGUtils.cxx:86
bool IsIon(int pdgc)
Definition PDGUtils.cxx:42
bool IsHNL(int pdgc)
Definition PDGUtils.cxx:419
bool IsElectron(int pdgc)
Definition PDGUtils.cxx:188
bool IsNucleon(int pdgc)
Definition PDGUtils.cxx:346
bool IsAntiDarkMatter(int pdgc)
Definition PDGUtils.cxx:133
bool IsDarkMatter(int pdgc)
Definition PDGUtils.cxx:127
bool IsHadron(int pdgc)
Definition PDGUtils.cxx:392
static constexpr double cm2
Definition Units.h:69
string BoolAsYNString(bool b)
THE MAIN GENIE PROJECT NAMESPACE
Definition AlgCmp.h:25
@ kIStFinalStateNuclearRemnant
Definition GHepStatus.h:38
@ kIStDISPreFragmHadronicState
Definition GHepStatus.h:35
@ kIStStableFinalState
Definition GHepStatus.h:30
@ kIStDecayedState
Definition GHepStatus.h:32
@ kIStInitialState
Definition GHepStatus.h:29
@ kIStNucleonTarget
Definition GHepStatus.h:34
enum genie::EGHepFlag GHepFlag_t
@ kPSWQ2ctpphipfE
const int kPdgHadronicSyst
Definition PDGCodes.h:210
enum genie::EGHepStatus GHepStatus_t
@ kGMdNucleonDecay
Definition GMode.h:30
@ kGMdDarkMatterNucleus
Definition GMode.h:29
@ kGMdLeptonNucleus
Definition GMode.h:26
@ kGMdHadronNucleus
Definition GMode.h:27
@ kGMdPhotonNucleus
Definition GMode.h:28
@ kGMdUnknown
Definition GMode.h:25
@ kGMdHNLDecay
Definition GMode.h:32
ostream & operator<<(ostream &stream, const AlgConfigPool &config_pool)
enum genie::EGEvGenMode GEvGenMode_t
const int kPdgGamma
Definition PDGCodes.h:189