33 using namespace genie;
34 using namespace genie::hnl;
75 std::vector< double > * prodVtx = 0;
86 prodVtx =
new std::vector< double >();
87 prodVtx->emplace_back( event->
Vertex()->X() );
88 prodVtx->emplace_back( event->
Vertex()->Y() );
89 prodVtx->emplace_back( event->
Vertex()->Z() );
90 prodVtx->emplace_back( event->
Vertex()->T() );
94 double px = p3HNL->at(0);
95 double py = p3HNL->at(1);
96 double pz = p3HNL->at(2);
99 p4 = TLorentzVector( px, py, pz, E );
101 if( !event->
Vertex() || (
event->Vertex()->Vect()).Mag() == 0.0 )
104 prodVtx =
new std::vector< double >();
105 prodVtx->emplace_back( event->
Vertex()->X() );
106 prodVtx->emplace_back( event->
Vertex()->Y() );
107 prodVtx->emplace_back( event->
Vertex()->Z() );
108 prodVtx->emplace_back( event->
Vertex()->T() );
112 TLorentzVector v4( prodVtx->at(0), prodVtx->at(1), prodVtx->at(2), prodVtx->at(3) );
123 LOG(
"HNL",
pINFO) <<
"Generating decay...";
136 typeMod = (
event->Particle(0)->Pdg() >= 0 ) ? 1 : -1;
140 double rnd = Rng->
RndGen().Uniform(0.0, 1.0);
141 typeMod = ( rnd >= 0.5 ) ? 1.0 : -1.0;
144 for( std::vector<int>::iterator it = pdgv0.begin(); it != pdgv0.end(); ++it ){
150 assert ( pdgv.size() > 1);
163 std::ostringstream asts;
164 if( !doPol ) asts <<
"Performing a phase space decay...";
165 else asts <<
"Performing a polarised decay with polarisation vector:"
171 vector<int>::const_iterator pdg_iter;
173 double * mass =
new double[pdgv.size()];
175 for(pdg_iter = pdgv.begin(); pdg_iter != pdgv.end(); ++pdg_iter) {
176 int pdgc = *pdg_iter;
183 <<
"Decaying N = " << pdgv.size() <<
" particles / total mass = " << sum;
188 TLorentzVector * p4d = hnl->
GetP4(); TVector3 HNLBVec = p4d->BoostVector();
189 TLorentzVector * p4d_rest = (TLorentzVector *) p4d->Clone(); p4d_rest->Boost( -HNLBVec );
190 TLorentzVector * v4d = hnl->
GetX4();
197 TGenPhaseSpace fPhaseSpaceGenerator;
199 bool permitted = fPhaseSpaceGenerator.SetDecay(*p4d_rest, pdgv.size(), mass);
202 <<
" *** Phase space decay is not permitted \n"
203 <<
" Total particle mass = " << sum <<
"\n"
207 delete p4d;
delete p4d_rest;
211 exception.
SetReason(
"Decay not permitted kinematically");
219 for(
int idec=0; idec<200; idec++) {
220 double w = fPhaseSpaceGenerator.Generate();
221 wmax = TMath::Max(wmax,w);
227 <<
"Max phase space gen. weight @ current hadronic system: " << wmax;
230 bool decayFailed =
false;
236 LOG(
"HNL",
pDEBUG ) <<
"Doing a polarised decay...";
237 decayFailed = this->
PolarisedDecay( fPhaseSpaceGenerator, pdgv, wmax, vecPolDir );
242 <<
"Polarisation for invisible FS not implemented yet, defaulting to phase-space decay...";
245 LOG(
"HNL",
pDEBUG ) <<
"Doing a phase-space decay...";
255 exception.
SetReason(
"Couldn't select decay after N attempts");
261 TLorentzVector v4(*v4d);
262 int idp = 0;
int npip = 0, npi0 = 0, npim = 0;
263 for(pdg_iter = pdgv.begin(); pdg_iter != pdgv.end(); ++pdg_iter) {
264 int pdgc = *pdg_iter;
265 TLorentzVector * p4fin = fPhaseSpaceGenerator.GetDecay(idp);
267 p4fin->Boost( HNLBVec );
269 event->AddParticle(pdgc, ist, hnl_id,-1,-1,-1, *p4fin, v4);
282 double Elead = -1.0;
int ilead = -1;
283 std::vector< int > lpdgv = { 11, 13, 15 };
284 for( std::vector<int>::iterator lit = lpdgv.begin(); lit != lpdgv.end(); ++lit ) {
288 double tmpE = tmpPart->
E();
289 if( tmpE > Elead ){ Elead = tmpE; ilead =
event->ParticlePosition( tmpPart ); }
292 event->Particle( 0 )->SetFirstDaughter( ilead );
293 event->Particle( 0 )->SetFirstMother(-1);
294 event->Particle( 0 )->SetLastMother(-1);
296 assert( event->
Probe() );
299 <<
"No final state primary lepton for this event.";
306 int itmp = 1, ilast = 1;
309 event->Particle(itmp)->SetFirstMother(0);
310 event->Particle(itmp)->SetLastMother(-1);
311 if( itmp != ilead ) ilast = itmp;
314 event->Particle( 0 )->SetLastDaughter( ilast );
318 <<
"Finished with decay products. Clean up and exit!";
330 <<
"\nYou are seeing this message because the input dk2nu files did not give position information (for some reason)..."
331 <<
"\nDistributing the production vertex at some point in a 1m-side box. This is not good, and results will likely be unphysical.";
332 fProdVtxHist =
new TH3D(
"dummy",
"dummy", 100, -0.5, 0.5, 100, -0.5, 0.5, 100, -0.5, 0.5 );
336 double pvx = (rnd->
RndGen()).Uniform( -0.5, 0.5 );
337 double pvy = (rnd->
RndGen()).Uniform( -0.5, 0.5 );
338 double pvz = (rnd->
RndGen()).Uniform( -0.5, 0.5 );
339 std::vector< double > * prodVtx =
new std::vector< double >();
340 prodVtx->emplace_back( pvx ); prodVtx->emplace_back( pvy ); prodVtx->emplace_back( pvz );
342 <<
"Production vertex at: ( " << prodVtx->at(0) <<
", " << prodVtx->at(1) <<
", " << prodVtx->at(2) <<
") [cm]";
344 TLorentzVector v4( prodVtx->at(0), prodVtx->at(1), prodVtx->at(2), 0.0 );
356 double p = TMath::Sqrt(E*E-M*M);
359 double thetaDev = 0.0;
362 double theta = Rng->
RndGen().Gaus(0.0, thetaDev);
363 if( theta < 0.0 ) theta *= -1.0;
366 double px = p * std::sin(theta) * std::cos(phi);
367 double py = p * std::sin(theta) * std::sin(phi);
368 double pz = p * std::cos(theta);
370 std::vector< double > * p3HNL =
new std::vector< double >();
371 p3HNL->emplace_back(px);
372 p3HNL->emplace_back(py);
373 p3HNL->emplace_back(pz);
384 TLorentzVector * p4HNL =
event->Particle(0)->GetP4(); assert( p4HNL );
388 TLorentzVector * p4FSL = 0;
390 int iFSL =
event->Particle(0)->FirstDaughter();
392 p4FSL = (
event->Particle( iFSL ) )->GetP4();
394 TLorentzVector p4DIF( p4HNL->Px() - p4FSL->Px(),
395 p4HNL->Py() - p4FSL->Py(),
396 p4HNL->Pz() - p4FSL->Pz(),
397 p4HNL->E() - p4FSL->E() );
404 if(p4FSL)
delete p4FSL;
422 <<
"Loading configuration from file...";
425 std::vector< double > U4l2s;
458 assert( CoMLifetime > 0.0 );
490 fTx = -1.0 * translation.at(0);
491 fTy = -1.0 * translation.at(1);
492 fTz = -1.0 * translation.at(2);
494 fR1 = rotation.at(0);
495 fR2 = rotation.at(1);
496 fR3 = rotation.at(2);
513 TLorentzVector * pv4 =
new TLorentzVector();
514 pv4->SetXYZT( v4.X(), v4.Y(), v4.Z(), v4.T() );
530 TLorentzVector * vv =
event->Vertex();
531 TLorentzVector * tmpx4 =
event->Particle(0)->GetX4();
534 if( tmpx4->X() != vv->X() || tmpx4->Y() != vv->Y() || tmpx4->Z() != vv->Z() ){
535 fPolDir.emplace_back( tmpx4->X() );
536 fPolDir.emplace_back( tmpx4->Y() );
537 int tmpMod = (
event->XSec() > 0.0 ) ? 1 : -1;
538 fPolDir.emplace_back( tmpMod * std::sqrt( 1.0 -
539 ( tmpx4->X() * tmpx4->X() + tmpx4->Y() * tmpx4->Y() ) ) );
545 event->Particle(0)->SetPosition( vv->X(), vv->Y(), vv->Z(), vv->T() );
555 bool accept_decay=
false;
559 while(!accept_decay) {
565 <<
"Couldn't generate an unweighted phase space decay after "
566 << itry <<
" attempts";
570 double w = fPSG.Generate();
573 <<
"Decay weight = " << w <<
" > max decay weight = " << wm;
575 double gw = wm * rnd->
RndHadro().Rndm();
576 accept_decay = (gw<=w);
596 double polMod = -999.99;
599 unsigned int iUPD = 0;
600 double polWgt = -999.9;
603 bool isAccepted =
false;
608 bool isPi0Nu = ( pdgv.size() == 3 &&
609 std::abs( pdgv.at(1) ) ==
kPdgPi0 &&
610 std::abs( pdgv.at(2) ) ==
kPdgNuMu );
619 vector<int>::const_iterator pdg_iter;
620 int idc = 0;
double Elead = -1.0;
621 for(pdg_iter = pdgv.begin(); pdg_iter != pdgv.end(); ++pdg_iter) {
622 int pdgc = *pdg_iter; Elead = -1.0;
626 ( isPi0Nu && std::abs( pdgc ) ==
kPdgNuMu ) );
628 TLorentzVector * p4lep = fPSG.GetDecay(idc);
629 if( p4lep->E() > Elead ){
631 lepDir = p4lep->Vect();
633 if( std::abs(
fDecLepPdg) != std::abs(pdgc) || polMod < -1.0 ){
646 double theta = vPolDir.Angle( lepDir );
647 double ctheta = TMath::Cos( theta );
649 rwgt = rnd->
RndGen().Uniform(0.0, 2.0);
650 int typeMod = ( *(pdgv.begin()) > 0 ) ? 1 : -1;
651 polWgt = 1 + typeMod * polMod * ctheta;
653 isAccepted = ( rwgt >= polWgt );
661 <<
"Couldn't generate a polarised decay after "
662 << iUPD <<
" attempts";
674 double mPar = pdgl->
Find( std::abs( parPdg ) )->Mass();
675 double mLep = pdgl->
Find( std::abs( lepPdg ) )->Mass();
677 double num1 = mLep * mLep - M * M;
680 double den1 = mPar*mPar*( mLep*mLep + M*M );
681 double den2 = mLep*mLep - M*M;
684 double pMag = -1.0 * num1*num2 / ( den1 - den2*den2 );
691 double mLep = pdgl->
Find( std::abs( lepPdg ) )->Mass();
692 double mHad = pdgl->
Find( std::abs( hadPdg ) )->Mass();
694 double num1 = M*M - mLep*mLep;
696 double num3 = polMag;
698 double den1 = M*M - mLep*mLep;
699 double den2 = mHad*mHad*( M*M + mLep*mLep );
701 double pMod = num1*num2*num3 / ( den1*den1 - den2 );
717 std::vector<double> allCoups;
718 allCoups.emplace_back(
fUe42); allCoups.emplace_back(
fUm42); allCoups.emplace_back(
fUt42);
729 std::string chanInt =
"";
730 for(
int iCBits =
sizeof(
fChanBits ) /
sizeof(
fChanBits[0] ) - 1; iCBits >= 0 ; iCBits-- ){
731 chanInt.append( Form(
"%d",
fChanBits[iCBits]) );
738 std::vector< double > PGOrigin;
739 PGOrigin.emplace_back(
fPGOx ); PGOrigin.emplace_back(
fPGOy ); PGOrigin.emplace_back(
fPGOz );
745 std::vector< double > PGDOrigin;
746 PGDOrigin.emplace_back(
fPGDx ); PGDOrigin.emplace_back(
fPGDy ); PGDOrigin.emplace_back(
fPGDz );
757 std::vector< double > PGDirection;
758 PGDirection.emplace_back(
fPGCx ); PGDirection.emplace_back(
fPGCy ); PGDirection.emplace_back(
fPGCz );
764 std::vector< double > PGDeviation;
bool IsHNLMajorana() const
std::vector< double > fPolDir
void SetNPions(int npi_plus, int npi_0, int npi_minus)
virtual GHepParticle * Particle(int position) const
TLorentzVector * GetX4(void) const
void SetProbeP4(const TLorentzVector &P4)
double E(void) const
Get energy.
static RandomGen * Instance()
Access instance.
void SetQ2(double Q2, bool selected=false)
string AsString(genie::hnl::HNLDecayMode_t hnldm)
Kinematics * KinePtr(void) const
std::vector< double > * GenerateDecayPosition(GHepRecord *event) const
int GetParamVect(const std::string &comm_name, std::vector< T > &v, bool is_top_call=true) const
Handle to load vectors of parameters.
std::vector< double > fB2URotation
string P4AsString(const TLorentzVector *p)
static const unsigned int kMaxUnweightDecayIterations
bool UnpolarisedDecay(TGenPhaseSpace &fPSG, PDGCodeList pdgv, double wm) const
TParticlePDG * Probe(void) const
void Configure(const Registry &config)
std::vector< double > * GenerateMomentum(GHepRecord *event) const
A singleton holding random number generator classes. All random number generation in GENIE should tak...
genie::hnl::HNLDecayMode_t fCurrDecayMode
void UpdateEventRecord(GHepRecord *event) const
GHepStatus_t Status(void) const
void SetBeam2UserRotation(const double r1, const double r2, const double r3)
virtual TLorentzVector * Vertex(void) const
double GetHNLMass() const
double Kallen(double x, double y, double z)
virtual GHepParticle * Probe(void) const
Summary information for an interaction.
PDGCodeList DecayProductList(genie::hnl::HNLDecayMode_t hnldm)
double GetPGunEnergy() const
An exception thrown by EventRecordVisitorI when the normal processing sequence has to be disrupted (f...
bool PolarisedDecay(TGenPhaseSpace &fPSG, PDGCodeList pdgv, double wm, TVector3 vPolDir) const
void GenerateDecayProducts(GHepRecord *event) const
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
void SetProdVtxPosition(const TLorentzVector &v4) const
void SetInterestingChannelsVec(const std::vector< genie::hnl::HNLDecayMode_t > decVec)
std::vector< double > GetPGunDirection() const
double GetHNLLifetime() const
TLorentzVector * GetP4(void) const
void ReadCreationInfo(GHepRecord *event) const
virtual GHepParticle * FinalStatePrimaryLepton(void) const
virtual void Configure(const Registry &config)
void Sett(double t, bool selected=false)
genie::hnl::SimpleHNL GetHNLInstance() const
int DecayMode(void) const
enum genie::hnl::EHNLDecayMode HNLDecayMode_t
double CalcPolMod(double polMag, int lepPdg, int hadPdg, double M) const
std::vector< double > GetPGunOrigin() const
std::vector< double > GetPGunDeviation() const
void SetAngularDeviation(const double adev)
std::vector< double > GetPGunDOrigin() const
void SetType(const int type)
void AddInitialState(GHepRecord *event) const
std::vector< genie::hnl::HNLDecayMode_t > fIntChannels
std::string GetHNLInterestingChannels() const
XclsTag * ExclTagPtr(void) const
TRandom3 & RndHadro(void) const
rnd number generator used by hadronization models
void SetW(double W, bool selected=false)
void SwitchOnFastForward(void)
static PDGLibrary * Instance(void)
void SetHNLCouplings(double Ue42, double Um42, double Ut42) const
void SetReason(string reason)
Singleton class to load & serve a TDatabasePDG.
void SetBeam2UserTranslation(const double tx, const double ty, const double tz)
void SetBeam2User(std::vector< double > translation, std::vector< double > rotation) const
A registry. Provides the container for algorithm configuration parameters.
const XclsTag & ExclTag(void) const
TLorentzVector * fProdVtx
TRandom3 & RndGen(void) const
rnd number generator for generic usage
double CalcPolMag(int parPdg, int lepPdg, double M) const
std::vector< double > GetHNLCouplings() const
InitialState * InitStatePtr(void) const
virtual void AddParticle(const GHepParticle &p)
const InitialState & InitState(void) const
TParticlePDG * Find(int pdgc, bool must_exist=true)
bool GetParam(const RgKey &name, T &p, bool is_top_call=true) const
std::vector< double > fB2UTranslation
void ProcessEventRecord(GHepRecord *event) const
Expands the EventRecordVisitorI interface to include public interfaces for the HNL Decayer module...
double ProbeE(RefFrame_t rf) const
GENIE's GHEP MC event record.
static constexpr double m
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.
TLorentzVector * GetProbeP4(RefFrame_t rf=kRfHitNucRest) const
void push_back(int pdg_code)
enum genie::EGHepStatus GHepStatus_t
Initial State information.