Skip to content

Commit 9b7aed4

Browse files
authored
Merge branch 'develop' into feature/bearc_supera
2 parents 9a1af2f + 9472f66 commit 9b7aed4

File tree

10 files changed

+431
-77
lines changed

10 files changed

+431
-77
lines changed

sbncode/CAFMaker/FillTrue.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,6 +1363,7 @@ caf::g4_process_ caf::GetG4ProcessID(const std::string &process_name) {
13631363
MATCH_PROCESS(Transportation)
13641364
MATCH_PROCESS(msc)
13651365
MATCH_PROCESS(StepLimiter)
1366+
MATCH_PROCESS(RadioactiveDecayBase)
13661367
std::cerr << "Error: Process name with no match (" << process_name << ")\n";
13671368
assert(false);
13681369
return caf::kG4UNKNOWN; // unreachable in debug mode

sbncode/EventGenerator/MeVPrtl/Tools/HNL/AnisotropicThreeBodyDecay.cpp

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#include "AnisotropicThreeBodyDecay.h"
2-
#include "sbncode/EventGenerator/MeVPrtl/Tools/Constants.h"
32

4-
#include "TLorentzVector.h"
5-
#include "TRandom3.h"
3+
double evgen::ldm::AnThreeBD::GetRandom(CLHEP::HepRandomEngine* fEngine) {
4+
return CLHEP::RandFlat::shoot(fEngine);
5+
}
6+
7+
68

79
/*Implementation of HNL Three Body Decays Anisotropies
810
Valid as long as the HNL is decaying into a neutrino and identical final-state charged leptons
@@ -178,7 +180,7 @@ double evgen::ldm::AnThreeBD::MSqDM(double (&C)[6], double z2_num, double z2_ll,
178180
Currently optimized for electrons and muons for m_HNl<388 MeV
179181
This function returns values of the maximum previously calculated using multiple iterations of MSqDM function, as the maximum is not trivial to estimate, mainly because the allowed Dalitz region restricts the use of some algorithms.
180182
*/
181-
double evgen::ldm::AnThreeBD::MaxMSqDM(double m_HNL, int LeptonPDG, double Ue4, double Umu4, double Ut4, double m_p, double m_m, double Pol, double (&C)[6], bool Majorana)
183+
double evgen::ldm::AnThreeBD::MaxMSqDM(double m_HNL, int LeptonPDG, double Ue4, double Umu4, double Ut4, double m_p, double m_m, double Pol, double (&C)[6], bool Majorana, CLHEP::HepRandomEngine* fEngine)
182184
{
183185
double Ce4 = 0;
184186
double Cmu4 = 0;
@@ -293,15 +295,14 @@ in the rejection sampling method used in AnisotropicThreeBodyDist. If the theor
293295
//Use 10e6 as a good aproximation of the maximum, if more precision is required the number can be increased
294296
int N_iter = pow(10,6);
295297
double MSqMax = 0;
296-
TRandom3 *rand = new TRandom3(0);
297298
for (int i=0;i<N_iter;i++) {
298299
double MSq = 0;
299-
do {
300-
//Generate a position in the Dalitz Plot randomly
301-
double r1 = rand->Rndm();
302-
double r2 = rand->Rndm();
303-
double r3 = rand->Rndm();
304-
double r4 = rand->Rndm();
300+
do {
301+
//Generate a position in the Dalitz Plot randomly
302+
double r1 = evgen::ldm::AnThreeBD::GetRandom(fEngine);
303+
double r2 = evgen::ldm::AnThreeBD::GetRandom(fEngine);
304+
double r3 = evgen::ldm::AnThreeBD::GetRandom(fEngine);
305+
double r4 = evgen::ldm::AnThreeBD::GetRandom(fEngine);
305306

306307
z2_ll = ((m_HNL * m_HNL - (m_m + m_p) * (m_m + m_p)) * r1 + (m_m + m_p) * (m_m + m_p)) / (m_HNL * m_HNL);
307308
z2_num = (((m_HNL - m_p) * (m_HNL - m_p) - m_m * m_m) * r2 + m_m * m_m) / (m_HNL * m_HNL);
@@ -331,15 +332,14 @@ in the rejection sampling method used in AnisotropicThreeBodyDist. If the theor
331332
ctll: cosine of the angle between the charged-lepton-pair (sum of the four-vectors) and the z-axis
332333
gamll: rotation angle about the direction of the charged-lepton pair
333334
masses: [mN, mm, mp] the HNL and daughter charged-lepton masses (mm: negatively-charged, mp: positively-charged) */
334-
void evgen::ldm::AnThreeBD::RF4vecs(TLorentzVector &pnu, TLorentzVector &pm, TLorentzVector &pp, double z2_num, double z2_ll, double ct_ll, double gam_ll, double m_HNL, double m_p, double m_m)
335+
void evgen::ldm::AnThreeBD::RF4vecs(TLorentzVector &pnu, TLorentzVector &pm, TLorentzVector &pp, double z2_num, double z2_ll, double ct_ll, double gam_ll, double m_HNL, double m_p, double m_m, CLHEP::HepRandomEngine* fEngine)
335336
{
336337
double PnuRF[4], PmRF[4], PpRF[4];
337338

338339
double m2_ll = z2_ll * m_HNL * m_HNL;
339340
double m2_num = z2_num * m_HNL * m_HNL;
340341

341-
TRandom3 *rand1 = new TRandom3(0);
342-
double r1 = rand1->Rndm();
342+
double r1 = evgen::ldm::AnThreeBD::GetRandom(fEngine);
343343

344344
//Calculate some useful kinematical cuantities
345345
double E_m = (m2_ll + m2_num - m_p * m_p) / (2.0 * m_HNL);
@@ -352,7 +352,6 @@ void evgen::ldm::AnThreeBD::RF4vecs(TLorentzVector &pnu, TLorentzVector &pm, TLo
352352

353353
//Select the phi angle randomly as it doesnt affect the anisotropies
354354
double phi = r1 * 2.0 * TMath::Pi();
355-
phi = 1;
356355

357356
PnuRF[0] = E_nu;
358357
PnuRF[1] = -E_nu * st_ll * sin(phi);
@@ -385,14 +384,12 @@ void evgen::ldm::AnThreeBD::RF4vecs(TLorentzVector &pnu, TLorentzVector &pm, TLo
385384
AntiHNL: Wether the HNL is a AntiHNL or a HNL (Only relevant in Dirac case)
386385
Pol: Polarization of the HNL
387386
See arXiv:2104.05719 for more details */
388-
void evgen::ldm::AnThreeBD::AnisotropicThreeBodyDist(TLorentzVector &pnu, TLorentzVector &pm, TLorentzVector& pp, double m_HNL, double Ue4, double Umu4, double Ut4, int LeptonPDG, bool Majorana, bool AntiHNL, double Pol)
387+
void evgen::ldm::AnThreeBD::AnisotropicThreeBodyDist(TLorentzVector pHNL, TLorentzVector &pnu, TLorentzVector &pm, TLorentzVector& pp, double m_HNL, double Ue4, double Umu4, double Ut4, int LeptonPDG, bool Majorana, bool AntiHNL, double Pol, CLHEP::HepRandomEngine* fEngine)
389388
{
390389
//By default select the electron as the lepton pair
391390
double m_p = evgen::ldm::Constants::Instance().elec_mass;
392391
double m_m = evgen::ldm::Constants::Instance().elec_mass;
393392

394-
TRandom3 *rand = new TRandom3(0);
395-
396393
//Select wether the final leptons are electrons or muons
397394
if(LeptonPDG == 13) {
398395
m_p = evgen::ldm::Constants::Instance().muon_mass;
@@ -418,7 +415,7 @@ void evgen::ldm::AnThreeBD::AnisotropicThreeBodyDist(TLorentzVector &pnu, TLoren
418415
double gam_ll = 0;
419416

420417
//Get the Maximum of the Matrix-element squared and use rejection sampling to get the anisotropic final states distribution
421-
double MSqMax = evgen::ldm::AnThreeBD::MaxMSqDM(m_HNL, LeptonPDG, Ue4, Umu4, Ut4, m_p, m_m, Pol, C, Majorana);
418+
double MSqMax = evgen::ldm::AnThreeBD::MaxMSqDM(m_HNL, LeptonPDG, Ue4, Umu4, Ut4, m_p, m_m, Pol, C, Majorana,fEngine);
422419

423420
double MSq = 0;
424421
bool IsW = false;
@@ -430,23 +427,68 @@ void evgen::ldm::AnThreeBD::AnisotropicThreeBodyDist(TLorentzVector &pnu, TLoren
430427
ctll: cosine of the angle between the charged-lepton-pair (sum of the four-vectors) and the z-axis
431428
gamll: rotation angle about the direction of the charged-lepton pair
432429
*/
433-
double r1 = rand->Rndm();
434-
double r2 = rand->Rndm();
435-
double r3 = rand->Rndm();
436-
double r4 = rand->Rndm();
430+
double r1 = evgen::ldm::AnThreeBD::GetRandom(fEngine);
431+
double r2 = evgen::ldm::AnThreeBD::GetRandom(fEngine);
432+
double r3 = evgen::ldm::AnThreeBD::GetRandom(fEngine);
433+
double r4 = evgen::ldm::AnThreeBD::GetRandom(fEngine);
437434

438435
z2_ll = ((m_HNL * m_HNL - (m_m + m_p) * (m_m + m_p)) * r1 + (m_m + m_p) * (m_m + m_p))/(m_HNL * m_HNL);
439436
z2_num = (((m_HNL - m_p) * (m_HNL - m_p) - m_m * m_m) * r2 + m_m * m_m) / (m_HNL * m_HNL);
440437
ct_ll = r3 * 2 - 1;
441438
gam_ll = 2 * TMath::Pi() * r4;
442439
MSq = evgen::ldm::AnThreeBD::MSqDM(C, z2_num, z2_ll, ct_ll, gam_ll, m_HNL, m_p, m_m, Pol);
443440
}while(MSq==0);//Check if the randomly selected kinematical quantities where allowed in the Dalitz
444-
double r5 = rand->Rndm();
441+
double r5 = evgen::ldm::AnThreeBD::GetRandom(fEngine);
445442
if(r5 < MSq/MSqMax) IsW = true;
446443
}while(!IsW); //Use rejection-sampling to select each final state given its probability to happen
447444

448445
//Change from the generated kinematical quantities to 4 Vectors that can be used by the generator
449-
evgen::ldm::AnThreeBD::RF4vecs(pnu, pm, pp, z2_num, z2_ll, ct_ll, gam_ll, m_HNL, m_p, m_m);
450-
446+
evgen::ldm::AnThreeBD::RF4vecs(pnu, pm, pp, z2_num, z2_ll, ct_ll, gam_ll, m_HNL, m_p, m_m, fEngine);
447+
evgen::ldm::AnThreeBD::RotateToHNLPolFrame(pHNL, pnu, pm, pp);
448+
451449
return;
452450
}
451+
452+
/*
453+
Function to apply a rotation to the calculated vector to match the HNL Pol direction.
454+
Formulas in arXiv:2104.05719 are defined with an HNL with the spin in the z direction.
455+
A rotation must be applied to the decay products to change the z direction to the beam direction (or HNL direction)
456+
in order for the results to be consistent, as per the reference arXiv:2104.05719
457+
p_HNL: HNL momentum vector
458+
pnu: neutrino momentum vector
459+
pl: positive charge momentum vector
460+
pm: negative charge lepton momentum vector (3D)
461+
*/
462+
void evgen::ldm::AnThreeBD::RotateToHNLPolFrame(TLorentzVector pHNL, TLorentzVector &pnu, TLorentzVector &pm, TLorentzVector &pp) {
463+
//Define the HNL direction
464+
TVector3 HNL_dir = TVector3(pHNL.X(), pHNL.Y(), pHNL.Z()).Unit();
465+
466+
//Define the direction of the polarized HNL in which formulas are calculated (In this case z)
467+
TVector3 z(0, 0, 1);
468+
469+
// Calculate the axis of rotation (cross product of z and hnl direction)
470+
TVector3 rotation_axis = z.Cross(HNL_dir);
471+
472+
// Calculate the angle of rotation
473+
double angle = z.Angle(HNL_dir);
474+
475+
TVector3 pnu3D = TVector3(pnu.X(), pnu.Y(), pnu.Z());
476+
TVector3 pm3D = TVector3(pm.X(), pm.Y(), pm.Z());
477+
TVector3 pp3D = TVector3(pp.X(), pp.Y(), pp.Z());
478+
479+
//Apply the rotation
480+
if (rotation_axis.Mag() != 0) {
481+
pnu3D.Rotate(angle, rotation_axis);
482+
pm3D.Rotate(angle, rotation_axis);
483+
pp3D.Rotate(angle, rotation_axis);
484+
} else if(angle == M_PI) {
485+
pnu3D = -pnu3D;
486+
pm3D = -pm3D;
487+
pp3D = -pp3D;
488+
}
489+
pnu.SetXYZT(pnu3D.X(), pnu3D.Y(), pnu3D.Z(), pnu.T());
490+
pm.SetXYZT(pm3D.X(), pm3D.Y(), pm3D.Z(), pm.T());
491+
pp.SetXYZT(pp3D.X(), pp3D.Y(), pp3D.Z(), pp.T());
492+
493+
return;
494+
}

sbncode/EventGenerator/MeVPrtl/Tools/HNL/AnisotropicThreeBodyDecay.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
#define AnisotropicThreeBodyDecay_h
33

44
#include "TLorentzVector.h"
5-
5+
#include "sbncode/EventGenerator/MeVPrtl/Tools/Constants.h"
6+
#include "CLHEP/Random/RandomEngine.h"
7+
#include "CLHEP/Random/JamesRandom.h"
8+
#include "CLHEP/Random/RandFlat.h"
9+
#include "sbncode/EventGenerator/MeVPrtl/Tools/IMeVPrtlStage.h"
610

711
//Implementation of HNL Three Body Decays Anisotropies
812
//Valid as long as the HNL is decaying into a neutrino and identical final-state charged leptons
@@ -21,10 +25,13 @@ namespace AnThreeBD {
2125
void KinDep(double (&K)[6], double Pol, double z_num, double z_ll, double ct_ll, double gam_ll, double m_HNL, double m_p, double m_m);
2226
bool IsDalitzAllowed(double z_ll, double s, double d, double z_num);
2327
double MSqDM(double (&C)[6], double z_num, double z_ll, double ct_ll, double gam_ll, double m_HNL, double m_p, double m_m, double Pol);
24-
double MaxMSqDM(double m_HNL, int LeptonPDG, double Ue4, double Umu4, double Ut4, double m_p, double m_m, double Pol, double (&C)[6], bool Majorana);
25-
void RF4vecs(TLorentzVector &pnu, TLorentzVector &pm, TLorentzVector &pp, double z_num, double z_ll, double ct_ll, double gam_ll, double m_HNL, double m_p, double m_m);
26-
void AnisotropicThreeBodyDist(TLorentzVector &pnu, TLorentzVector &pm, TLorentzVector &pp, double m_HNL, double Ue4, double Umu4, double Ut4, int LeptonPDG, bool Majorana, bool AntiHNL, double Pol);
27-
28+
double MaxMSqDM(double m_HNL, int LeptonPDG, double Ue4, double Umu4, double Ut4, double m_p, double m_m, double Pol, double (&C)[6], bool Majorana, CLHEP::HepRandomEngine* fEngine);
29+
void RF4vecs(TLorentzVector &pnu, TLorentzVector &pm, TLorentzVector &pp, double z_num, double z_ll, double ct_ll, double gam_ll, double m_HNL, double m_p, double m_m, CLHEP::HepRandomEngine* fEngine);
30+
void AnisotropicThreeBodyDist(TLorentzVector pHNL,TLorentzVector &pnu, TLorentzVector &pm, TLorentzVector &pp, double m_HNL, double Ue4, double Umu4, double Ut4, int LeptonPDG, bool Majorana, bool AntiHNL, double Pol, CLHEP::HepRandomEngine* fEngine);
31+
void RotateToHNLPolFrame(TLorentzVector pHNL, TLorentzVector &pnu, TLorentzVector &pm, TLorentzVector &pp);
32+
33+
double GetRandom(CLHEP::HepRandomEngine* fEngine);
34+
2835
} // namespace AnThreeBD
2936
} // namespace ldm
3037
} // namespace evgen

0 commit comments

Comments
 (0)