22 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,6) 23 #include <TMCParticle.h> 25 #include <TMCParticle6.h> 50 using namespace genie;
54 extern "C" void py1ent_(
int *,
int *,
double *,
double *,
double *);
55 extern "C" void py2ent_(
int *,
int *,
int *,
double *);
93 TClonesArray * particle_list = this->
Hadronize(interaction);
95 if(! particle_list ) {
96 LOG(
"CharmHadronization",
pWARN) <<
"Got an empty particle list. Hadronizer failed!";
97 LOG(
"CharmHadronization",
pWARN) <<
"Quitting the current event generation thread";
102 exception.
SetReason(
"Could not simulate the hadronic system");
109 int mom =
event->FinalStateHadronicSystemPosition();
119 const TLorentzVector * had_syst =
event -> Particle(mom) -> P4() ;
120 TVector3 beta( 0., 0., had_syst ->
P()/ had_syst -> Energy() ) ;
123 TVector3 unitvq = had_syst -> Vect().Unit();
126 const TLorentzVector & vtx = *(neutrino->
X4());
129 TIter particle_iter(particle_list);
130 while ((particle = (
GHepParticle *) particle_iter.Next())) {
132 int pdgc = particle -> Pdg() ;
135 particle -> P4() -> Boost( beta ) ;
136 particle -> P4() -> RotateUz( unitvq ) ;
149 particle -> SetStatus( ist ) ;
151 int im = mom + 1 + particle -> FirstMother() ;
152 int ifc = ( particle -> FirstDaughter() == -1) ? -1 : mom + 1 + particle -> FirstDaughter();
153 int ilc = ( particle -> LastDaughter() == -1) ? -1 : mom + 1 + particle -> LastDaughter();
155 particle -> SetFirstMother( im ) ;
157 particle -> SetFirstDaughter( ifc ) ;
158 particle -> SetLastDaughter( ilc ) ;
162 particle -> SetPosition( vtx ) ;
164 event->AddParticle(*particle);
167 particle_list -> Delete() ;
168 delete particle_list ;
178 LOG(
"CharmHad",
pNOTICE) <<
"** Running CHARM hadronizer";
186 const InitialState & init_state = interaction -> InitState();
187 const Kinematics & kinematics = interaction -> Kine();
190 const TLorentzVector & p4Had = kinematics.
HadSystP4();
193 double W = kinematics.
W(
true);
195 TVector3 beta = -1 * p4Had.BoostVector();
196 TLorentzVector p4H(0,0,0,W);
198 double Eh = p4Had.Energy();
200 LOG(
"CharmHad",
pNOTICE) <<
"Ehad (LAB) = " << Eh <<
", W = " <<
W;
216 TLorentzVector p4C(0,0,0,0);
219 bool got_charmed_hadron =
false;
226 double mc = pdglib->
Find(pdg)->Mass();
229 <<
"Trying charm hadron = " << pdg <<
"(m = " << mc <<
")";
237 double mc2 = TMath::Power(mc,2);
238 double Ec2 = TMath::Power(Ec,2);
239 double pc2 = Ec2-mc2;
242 <<
"Trying charm hadron z = " << z <<
", E = " << Ec;
249 double plc2 = Ec2 - ptc2 - mc2;
251 <<
"Trying charm hadron pT^2 (tranv to pHad) = " << ptc2;
255 double ptc = TMath::Sqrt(ptc2);
256 double plc = TMath::Sqrt(plc2);
258 double pxc = ptc * TMath::Cos(phi);
259 double pyc = ptc * TMath::Sin(phi);
262 p4C.SetPxPyPzE(pxc,pyc,pzc,Ec);
275 TLorentzVector p4 = p4H - p4C;
278 <<
"Invariant mass of remnant hadronic system= " << wr;
280 LOG(
"CharmHad",
pINFO) <<
"Too small hadronic remnant mass!";
285 got_charmed_hadron =
true;
288 <<
"Generated charm hadron = " << pdg <<
"(m = " << mc <<
")";
290 <<
"Generated charm hadron z = " << z <<
", E = " << Ec;
301 bool used_lowW_strategy =
false;
302 int fs_nucleon_pdg = -1;
303 if(ch_pdg==-1 && W < 3.){
305 <<
"Had difficulty generating charm hadronic system near W threshold";
307 <<
"Trying an alternative strategy";
309 double qfsl = interaction->
FSPrimLepton()->Charge() / 3.;
310 double qinit = pdglib->
Find(nuc_pdg)->Charge() / 3.;
311 int qhad = (
int) (qinit - qfsl);
320 }
else if(qhad == 1) {
326 }
else if(qhad == 0) {
328 }
else if(qhad == -1) {
332 double mc = pdglib->
Find(chrm_pdg)->Mass();
333 double mn = pdglib->
Find(remn_pdg)->Mass();
337 double mass[2] = {mc, mn};
343 for(
int i=0; i<200; i++) {
345 wmax = TMath::Max(wmax,w);
352 bool accept_decay=
false;
353 unsigned int idecay_try=0;
360 <<
"Couldn't generate an unweighted phase space decay after " 361 << idecay_try <<
" attempts";
366 <<
"Decay weight = " << w <<
" > max decay weight = " << wmax;
368 double gw = wmax * rnd->
RndHadro().Rndm();
369 accept_decay = (gw<=
w);
372 used_lowW_strategy =
true;
376 fs_nucleon_pdg = remn_pdg;
390 <<
"Couldn't generate charm hadron for: " << *
interaction;
394 TLorentzVector p4R = p4H - p4C;
398 LOG(
"CharmHad",
pNOTICE) <<
"Remnant hadronic system mass = " << WR;
406 TClonesArray * particle_list =
new TClonesArray(
"genie::GHepParticle", 2);
407 particle_list->SetOwner(
true);
411 -1,-1,-1,-1, p4C.Px(),p4C.Py(),p4C.Pz(),p4C.E(), 0,0,0,0);
413 -1,-1,-1,-1, p4R.Px(),p4R.Py(),p4R.Pz(),p4R.E(), 0,0,0,0);
415 return particle_list;
423 if(used_lowW_strategy) {
425 TClonesArray * particle_list =
new TClonesArray(
"genie::GHepParticle", 3);
426 particle_list->SetOwner(
true);
430 -1,-1,-1,-1, p4C.Px(),p4C.Py(),p4C.Pz(),p4C.E(), 0,0,0,0);
432 -1,-1,2,2, p4R.Px(),p4R.Py(),p4R.Pz(),p4R.E(), 0,0,0,0);
434 1,1,-1,-1, p4R.Px(),p4R.Py(),p4R.Pz(),p4R.E(), 0,0,0,0);
436 return particle_list;
449 TClonesArray * particle_list =
new TClonesArray(
"genie::GHepParticle");
450 particle_list->SetOwner(
true);
453 -1,-1,-1,-1, p4C.Px(),p4C.Py(),p4C.Pz(),p4C.E(), 0,0,0,0);
455 -1,-1,2,3, p4R.Px(),p4R.Py(),p4R.Pz(),p4R.E(), 0,0,0,0);
457 unsigned int rpos =2;
459 bool use_pythia = (WR>1.5);
567 if(qrkSyst1 == 0 && qrkSyst2 == 0) {
569 <<
"Couldn't generate quark systems for PYTHIA in: " << *
interaction;
585 py2ent_(&ip, &qrkSyst1, &qrkSyst2, &WR);
590 TClonesArray * pythia_remnants = 0;
592 pythia_remnants =
dynamic_cast<TClonesArray *
>(
fPythia->ImportParticles(
"All"));
593 if(!pythia_remnants) {
594 LOG(
"CharmHad",
pWARN) <<
"Couldn't hadronize (non-charm) remnants!";
598 int np = pythia_remnants->GetEntries();
606 TVector3 rmnbeta = +1 * p4R.BoostVector();
608 TMCParticle * pythia_remn = 0;
610 TIter remn_iter(pythia_remnants);
611 while( (pythia_remn = (TMCParticle *) remn_iter.Next()) ) {
614 bremn =
new ((*particle_list)[rpos++])
GHepParticle ( pythia_remn->GetKF(),
616 pythia_remn->GetParent(),
618 pythia_remn->GetFirstChild(),
619 pythia_remn->GetLastChild(),
620 pythia_remn -> GetPx(),
621 pythia_remn -> GetPy(),
622 pythia_remn -> GetPz(),
623 pythia_remn -> GetEnergy(),
624 pythia_remn->GetVx(),
625 pythia_remn->GetVy(),
626 pythia_remn->GetVz(),
627 pythia_remn->GetTime()
631 bremn -> P4() -> Boost( rmnbeta ) ;
638 bremn -> SetFirstMother( (jp == 0 ? 1 : jp +1) );
639 bremn -> SetFirstDaughter ( (ifc == 0 ? -1 : ifc+1) );
640 bremn -> SetLastDaughter ( (ilc == 0 ? -1 : ilc+1) );
660 double qfsl = interaction->
FSPrimLepton()->Charge() / 3.;
661 double qinit = pdglib->
Find(nuc_pdg)->Charge() / 3.;
662 double qch = pdglib->
Find(ch_pdg)->Charge() / 3.;
663 int Q = (
int) (qinit - qfsl - qch);
685 pdglib->
Find(pd[0])->Mass(), pdglib->
Find(pd[1])->Mass()
691 LOG(
"CharmHad",
pERROR) <<
" *** Phase space decay is not permitted";
696 for(
int i=0; i<200; i++) {
698 wmax = TMath::Max(wmax,w);
701 LOG(
"CharmHad",
pERROR) <<
" *** Non-positive maximum weight";
702 LOG(
"CharmHad",
pERROR) <<
" *** Can not generate an unweighted phase space decay";
707 <<
"Max phase space gen. weight @ current hadronic system: " << wmax;
711 bool accept_decay=
false;
712 unsigned int idectry=0;
719 <<
"Couldn't generate an unweighted phase space decay after " 720 << itry <<
" attempts";
726 <<
"Decay weight = " << w <<
" > max decay weight = " << wmax;
728 double gw = wmax * rnd->
RndHadro().Rndm();
729 accept_decay = (gw<=
w);
731 <<
"Decay weight = " << w <<
" / R = " << gw <<
" - accepted: " << accept_decay;
733 for(
unsigned int i=0; i<2; i++) {
737 pdgc,
kIStStableFinalState,1,1,-1,-1,p4d->Px(),p4d->Py(),p4d->Pz(),p4d->Energy(),
744 return particle_list;
767 LOG(
"CharmHad",
pERROR) <<
"Could not generate a charm hadron!";
792 bool hadronize_remnants ;
793 GetParamDef(
"HadronizeRemnants", hadronize_remnants,
true ) ;
799 this->
SubAlg(
"FragmentationFunc"));
803 this ->
GetParam(
"PTFunction", pt_function ) ;
805 fCharmPT2pdf =
new TF1(
"fCharmPT2pdf", pt_function.c_str(),0,0.6);
811 std::vector<double> ec, d0frac, dpfrac, dsfrac ;
814 std::vector<std::string> bits ;
816 bool invalid_configuration = false ;
819 this ->
GetParam(
"CharmFrac-E", raw ) ;
824 "Failed to decode CharmFrac-E string: ";
825 LOG(
"CharmHadronization",
pFATAL) <<
"string: "<< raw ;
826 invalid_configuration = true ;
830 this ->
GetParam(
"CharmFrac-D0", raw ) ;
835 "Failed to decode CharmFrac-D0 string: ";
836 LOG(
"CharmHadronization",
pFATAL) <<
"string: "<< raw ;
837 invalid_configuration = true ;
841 if ( d0frac.size() != ec.size() ) {
842 LOG(
"CharmHadronization",
pFATAL) <<
"E entries don't match D0 fraction entries";
843 LOG(
"CharmHadronization",
pFATAL) <<
"E: " << ec.size() ;
844 LOG(
"CharmHadronization",
pFATAL) <<
"D0: " << d0frac.size() ;
845 invalid_configuration = true ;
849 this ->
GetParam(
"CharmFrac-D+", raw ) ;
854 "Failed to decode CharmFrac-D+ string: ";
855 LOG(
"CharmHadronization",
pFATAL) <<
"string: "<< raw ;
856 invalid_configuration = true ;
860 if ( dpfrac.size() != ec.size() ) {
861 LOG(
"CharmHadronization",
pFATAL) <<
"E entries don't match D+ fraction entries";
862 LOG(
"CharmHadronization",
pFATAL) <<
"E: " << ec.size() ;
863 LOG(
"CharmHadronization",
pFATAL) <<
"D+: " << dpfrac.size() ;
864 invalid_configuration = true ;
868 this ->
GetParam(
"CharmFrac-Ds", raw ) ;
873 "Failed to decode CharmFrac-Ds string: ";
874 LOG(
"CharmHadronization",
pFATAL) <<
"string: "<< raw ;
875 invalid_configuration = true ;
879 if ( dsfrac.size() != ec.size() ) {
880 LOG(
"CharmHadronization",
pFATAL) <<
"E entries don't match Ds fraction entries";
881 LOG(
"CharmHadronization",
pFATAL) <<
"E: " << ec.size() ;
882 LOG(
"CharmHadronization",
pFATAL) <<
"Ds: " << dsfrac.size() ;
883 invalid_configuration = true ;
895 if ( invalid_configuration ) {
898 <<
"Invalid configuration: Exiting" ;
const int kPdgP33m1232_DeltaPP
const int kPdgUUDiquarkS1
double W(bool selected=false) const
double fDmFrac
nubar D- charm fraction
TPythia6 * fPythia
remnant (non-charm) hadronizer
bool IsNeutrino(int pdgc)
THE MAIN GENIE PROJECT NAMESPACE
Spline * fDpFracSpl
nu charm fraction vs Ev: D+
static const double kNucleonMass
static RandomGen * Instance()
Access instance.
int HitNucPdg(void) const
Defines the EventRecordVisitorI interface. Concrete implementations of this interface use the 'Visito...
virtual double GenerateZ(void) const =0
int FirstDaughter(void) const
const int kPdgHadronicBlob
virtual ~CharmHadronization()
enum genie::EGHepStatus GHepStatus_t
A numeric analysis tool class for interpolating 1-D functions.
bool IsNucleus(void) const
void Initialize(void) const
void py1ent_(int *, int *, double *, double *, double *)
Generated/set kinematical variables for an event.
string P4AsString(const TLorentzVector *p)
static const unsigned int kMaxUnweightDecayIterations
bool IsDarkMatter(int pdgc)
bool IsChargedLepton(int pdgc)
virtual double Weight(void) const
const TLorentzVector & HadSystP4(void) const
double Evaluate(double x) const
A singleton holding random number generator classes. All random number generation in GENIE should tak...
void py2ent_(int *, int *, int *, double *)
const int kPdgP33m1232_DeltaP
const int kPdgP33m1232_DeltaM
TClonesArray * Hadronize(const Interaction *) const
int FirstMother(void) const
Summary information for an interaction.
int LastDaughter(void) const
An exception thrown by EventRecordVisitorI when the normal processing sequence has to be disrupted (f...
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
const int kPdgUDDiquarkS1
bool IsAntiNeutrino(int pdgc)
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
const FragmentationFunctionI * fFragmFunc
charm hadron fragmentation func
virtual void Configure(const Registry &config)
double fD0BarFrac
nubar {D0} charm fraction
void Configure(const Registry &config)
static const double kASmallNum
const int kPdgUDDiquarkS0
Misc GENIE control constants.
const int kPdgP33m1232_Delta0
bool Convert(const vector< std::string > &input, std::vector< T > &v)
bool fCharmOnly
don't hadronize non-charm blob
TParticlePDG * FSPrimLepton(void) const
final state primary lepton
Pure abstract base class. Defines the FragmentationFunctionI interface to be implemented by any algor...
bool IsNeutralLepton(int pdgc)
TRandom3 & RndHadro(void) const
rnd number generator used by hadronization models
void SwitchOnFastForward(void)
void ProcessEventRecord(GHepRecord *event) const
static PDGLibrary * Instance(void)
void SetReason(string reason)
vector< string > Split(string input, string delim)
static const double kPionMass
Singleton class to load & serve a TDatabasePDG.
const TLorentzVector * X4(void) const
int GenerateCharmHadron(int nupdg, double EvLab) const
A registry. Provides the container for algorithm configuration parameters.
TParticlePDG * Find(int pdgc)
double Weight(void) const
Spline * fDsFracSpl
nu charm fraction vs Ev: Ds+
const InitialState & InitState(void) const
bool GetParamDef(const RgKey &name, T &p, const T &def) const
bool GetParam(const RgKey &name, T &p, bool is_top_call=true) const
const Target & Tgt(void) const
static const unsigned int kRjMaxIterations
double ProbeE(RefFrame_t rf) const
GENIE's GHEP MC event record.
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
STDHEP-like event record entry that can fit a particle or a nucleus.
Spline * fD0FracSpl
nu charm fraction vs Ev: D0
cet::coded_exception< error, detail::translate > exception
TF1 * fCharmPT2pdf
charm hadron pT^2 pdf
void push_back(int pdg_code)
Event finding and building.
TGenPhaseSpace fPhaseSpaceGenerator
a phase space generator
Initial State information.
const int kPdgDDDiquarkS1
const Algorithm * SubAlg(const RgKey ®istry_key) const