GENIEGenerator
Loading...
Searching...
No Matches
HNLDecaySelector.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 Author: John Plows <komninos-john.plows \at physics.ox.ac.uk>
7 University of Oxford
8*/
9//____________________________________________________________________________
10
12
14
15using namespace genie::hnl;
16
17// Takes parameter space, outputs all available channels + widths
18std::map< HNLDecayMode_t, double > selector::GetValidChannelWidths( const double M, const double /* Ue42 */, const double /* Umu42 */, const double /* Ut42 */, const bool IsMajorana ){
19
20 // construct an BRCalculator * object to handle the scalings.
21 const Algorithm * algBRCalc = AlgFactory::Instance()->GetAlgorithm("genie::hnl::BRCalculator", "Default");
22 const BRCalculator * BRCalc = dynamic_cast< const BRCalculator * >( algBRCalc );
23
24 std::map< HNLDecayMode_t, double > allChannels;
25
26 // invisible decay is always possible
27 double GINV = 0.0;
28 if( fDecayGammas[0] < 0.0 ){
29 GINV = BRCalc->DecayWidth( kHNLDcyNuNuNu );
30 if( IsMajorana ) GINV *= 2.0;
31 fDecayGammas[0] = GINV;
32 LOG("HNL", pDEBUG)
33 << " Invisible decay gamma = " << fDecayGammas[0];
34 } else GINV = fDecayGammas[0];
35 allChannels.insert( allChannels.begin(), std::pair< HNLDecayMode_t, double >( kHNLDcyNuNuNu, GINV ) );
36
37 assert( GINV >= 0.0 );
38
39 // nu-e-e is next lightest
40 if( M < 2.0 * genie::constants::kElectronMass ) return allChannels;
41
42 double GNEE = 0.0;
43 if( fDecayGammas[1] < 0.0 ){
44 GNEE = BRCalc->DecayWidth( kHNLDcyNuEE );
45 if( IsMajorana ) GNEE *= 2.0;
46 fDecayGammas[1] = GNEE;
47 LOG("HNL", pDEBUG)
48 << " Nu-e-e gamma = " << fDecayGammas[1];
49 } else GNEE = fDecayGammas[1];
50 allChannels.insert( allChannels.begin(), std::pair< HNLDecayMode_t, double >( kHNLDcyNuEE, GNEE ) );
51
52 assert( GNEE >= 0.0 );
53
54 // nu-e-mu is next lightest
56
57 double GNEM = 0.0;
58 if( fDecayGammas[2] < 0.0 ){
59 GNEM = BRCalc->DecayWidth( kHNLDcyNuMuE );
60 if( IsMajorana ) GNEM *= 2.0;
61 fDecayGammas[2] = GNEM;
62 LOG("HNL", pDEBUG)
63 << " Nu-e-mu gamma = " << fDecayGammas[2];
64 } else GNEM = fDecayGammas[2];
65 allChannels.insert( allChannels.begin(), std::pair< HNLDecayMode_t, double >( kHNLDcyNuMuE, GNEM ) );
66
67 assert( GNEM >= 0.0 );
68
69 // pi0-nu is next lightest
70 if( M < genie::constants::kPi0Mass ) return allChannels;
71
72 double GP0N = 0.0;
73 if( fDecayGammas[3] < 0.0 ){
74 GP0N = BRCalc->DecayWidth( kHNLDcyPi0Nu );
75 if( IsMajorana ) GP0N *= 2.0;
76 fDecayGammas[3] = GP0N;
77 LOG("HNL", pDEBUG)
78 << " Pi0-nu gamma = " << fDecayGammas[3];
79 } else GP0N = fDecayGammas[3];
80 allChannels.insert( allChannels.begin(), std::pair< HNLDecayMode_t, double >( kHNLDcyPi0Nu, GP0N ) );
81
82 assert( GP0N >= 0.0 );
83
84 // pi-e is next lightest
86
87 double GPIE = 0.0;
88 if( fDecayGammas[4] < 0.0 ){
89 GPIE = BRCalc->DecayWidth( kHNLDcyPiE );
90 if( IsMajorana ) GPIE *= 2.0;
91 fDecayGammas[4] = GPIE;
92 LOG("HNL", pDEBUG)
93 << " Pi-e gamma = " << fDecayGammas[4];
94 } else GPIE = fDecayGammas[4];
95 allChannels.insert( allChannels.begin(), std::pair< HNLDecayMode_t, double >( kHNLDcyPiE, GPIE) );
96
97 assert( GPIE >= 0.0 );
98
99 // nu-mu-mu is next lightest
100 if( M < 2.0 * genie::constants::kMuonMass ) return allChannels;
101
102 double GNMM = 0.0;
103 if( fDecayGammas[5] < 0.0 ){
104 GNMM = BRCalc->DecayWidth( kHNLDcyNuMuMu );
105 if( IsMajorana ) GNMM *= 2.0;
106 fDecayGammas[5] = GNMM;
107 LOG("HNL", pDEBUG)
108 << " Nu-mu-mu gamma = " << fDecayGammas[5];
109 } else GNMM = fDecayGammas[5];
110 allChannels.insert( allChannels.begin(), std::pair< HNLDecayMode_t, double >( kHNLDcyNuMuMu, GNMM ) );
111
112 assert( GNMM >= 0.0 );
113
114 // pi-mu is next lightest
115 if( M < genie::constants::kPionMass + genie::constants::kMuonMass ) return allChannels;
116
117 double GPIM = 0.0;
118 if( fDecayGammas[6] < 0.0 ){
119 GPIM = BRCalc->DecayWidth( kHNLDcyPiMu );
120 if( IsMajorana ) GPIM *= 2.0;
121 fDecayGammas[6] = GPIM;
122 LOG("HNL", pDEBUG)
123 << " Pi-mu gamma = " << fDecayGammas[6];
124 } else GPIM = fDecayGammas[6];
125 allChannels.insert( allChannels.begin(), std::pair< HNLDecayMode_t, double >( kHNLDcyPiMu, GPIM ) );
126
127 assert( GPIM >= 0.0 );
128
129 // pi0-pi0-nu is next lightest
130 if( M < 2.0 * genie::constants::kPi0Mass ) return allChannels;
131
132 double GP02 = 0.0;
133 if( fDecayGammas[7] < 0.0 ){
134 GP02 = BRCalc->DecayWidth( kHNLDcyPi0Pi0Nu );
135 if( IsMajorana ) GP02 *= 2.0;
136 fDecayGammas[7] = GP02;
137 LOG("HNL", pDEBUG)
138 << " Pi0-pi0-nu gamma = " << fDecayGammas[7];
139 } else fDecayGammas[7] = GP02;
140 allChannels.insert( allChannels.begin(), std::pair< HNLDecayMode_t, double >( kHNLDcyPi0Pi0Nu, GP02 ) );
141
142 assert( GP02 >= 0.0 );
143
144 // pi-pi0-e is next lightest
146
147 double GP0E = 0.0;
148 if( fDecayGammas[8] < 0.0 ){
149 GP0E = BRCalc->DecayWidth( kHNLDcyPiPi0E );
150 if( IsMajorana ) GP0E *= 2.0;
151 fDecayGammas[8] = GP0E;
152 LOG("HNL", pDEBUG)
153 << " Pi-pi0-e gamma = " << fDecayGammas[8];
154 } else GP0E = fDecayGammas[8];
155 allChannels.insert( allChannels.begin(), std::pair< HNLDecayMode_t, double >( kHNLDcyPiPi0E, GP0E ) );
156
157 assert( GP0E >= 0.0 );
158
159 // pi-pi0-mu is next lightest
161
162 double GP0M = 0.0;
163 if( fDecayGammas[9] < 0.0 ){
164 GP0M = BRCalc->DecayWidth( kHNLDcyPiPi0Mu );
165 if( IsMajorana ) GP0M *= 2.0;
166 fDecayGammas[9] = GP0M;
167 LOG("HNL", pDEBUG)
168 << " Pi-pi0-mu gamma = " << fDecayGammas[9];
169 } else GP0M = fDecayGammas[9];
170 allChannels.insert( allChannels.begin(), std::pair< HNLDecayMode_t, double >( kHNLDcyPiPi0Mu, GP0M ) );
171
172 assert( GP0M >= 0.0 );
173
174 //all done! Return
175 return allChannels;
176}
177
178// Calculates the *total* decay width from all the valid channels
179double selector::GetTotalDecayWidth( std::map< HNLDecayMode_t, double > gammaMap ) {
180
181 double totGamma = 0.0;
182
183 for( std::map< HNLDecayMode_t, double >::iterator it = gammaMap.begin(); it != gammaMap.end(); ++it ){ totGamma += (*it).second; }
184
185 LOG("HNL", pDEBUG)
186 << " Total gamma from N_channels = " << gammaMap.size()
187 << " is = " << totGamma << " [GeV]"
188 << " or = " << totGamma * genie::units::GeV * genie::units::ns << " [ns^{-1}]";
189
190 return totGamma;
191}
192
193// Returns lifetime of particle with mass and couplings
194double selector::CalcCoMLifetime( const double M, const double Ue42, const double Umu42, const double Ut42, const bool IsMajorana ){
195
196 std::map< HNLDecayMode_t, double > allChannels = selector::GetValidChannelWidths( M, Ue42, Umu42, Ut42, IsMajorana );
197 double totGamma = selector::GetTotalDecayWidth( allChannels );
198 return 1.0 / totGamma; // GeV^{-1}
199}
200
201// let's pick the interesting channels
202std::map< HNLDecayMode_t, double > selector::SetInterestingChannels( std::vector< HNLDecayMode_t > intChannels, std::map< HNLDecayMode_t, double > gammaMap ){
203
204 std::map< HNLDecayMode_t, double > interestingMap;
205
206 for( std::vector< HNLDecayMode_t >::iterator it = intChannels.begin(); it != intChannels.end(); ++it ){
207 HNLDecayMode_t decType = (*it);
208 double gamma = gammaMap.find( (*it) )->second;
209 interestingMap.insert( std::pair< HNLDecayMode_t, double >( decType, gamma ) );
210 }
211 return interestingMap;
212} // this is now a reduced map with only the channels we want to decay HNL to
213
214// and transform decay widths to branching ratios (probabilities)
215std::map< HNLDecayMode_t, double > selector::GetProbabilities( std::map< HNLDecayMode_t, double > gammaMap ){
216
217 double totGamma = GetTotalDecayWidth( gammaMap );
218 std::map< HNLDecayMode_t, double > Pmap;
219
220 // P = Gamma(channel)/Gamma(tot)
221 for( std::map< HNLDecayMode_t, double >::iterator it = gammaMap.begin(); it != gammaMap.end(); ++it ){
222 Pmap.insert( std::pair< HNLDecayMode_t, double >( (*it).first, (*it).second / totGamma ) );
223 }
224 return Pmap;
225}
226
227// choose a particular channel to decay to
228HNLDecayMode_t selector::SelectChannelInclusive( std::map< HNLDecayMode_t, double > Pmap, double ranThrow ){
229
230 // in inclusive method, decay is factorised in three parts:
231 // a) Decay vertex placement
232 // b) Decay product selection: construct
233 // c) Decay product kinematics
234 // This method does only b)
235
236 // first get P(all interesting channels)
237 double PInt = 0.0, all_before = 0.0;
238 HNLDecayMode_t selectedChannel = kHNLDcyNull;
239
240 for( std::map< HNLDecayMode_t, double >::iterator it = Pmap.begin(); it != Pmap.end(); ++it ){ PInt += (*it).second; }
241
242 // compare ranThrow to P(channel)/PInt + all_before
243 // if all_before + P(channel)/PInt >= ranThrow then select this channel
244 // don't break, check if scores add up to 1!
245 for( std::map< HNLDecayMode_t, double >::iterator it = Pmap.begin(); it != Pmap.end(); ++it ){
246 double modP = (*it).second / PInt;
247 if( all_before < ranThrow &&
248 all_before + modP >= ranThrow ) selectedChannel = (*it).first;
249 all_before += modP;
250 }
251
252 return selectedChannel;
253}
#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
static AlgFactory * Instance()
Algorithm abstract base class.
Definition Algorithm.h:54
Manages HNL BR (prod and decay)
double DecayWidth(genie::hnl::HNLDecayMode_t hnldm) const
std::map< genie::hnl::HNLDecayMode_t, double > GetValidChannelWidths(const double M, const double Ue42, const double Umu42, const double Ut42, const bool IsMajorana=false)
genie::hnl::HNLDecayMode_t SelectChannelInclusive(std::map< genie::hnl::HNLDecayMode_t, double > Pmap, double ranThrow)
std::map< genie::hnl::HNLDecayMode_t, double > SetInterestingChannels(std::vector< genie::hnl::HNLDecayMode_t > intChannels, std::map< genie::hnl::HNLDecayMode_t, double > gammaMap)
double GetTotalDecayWidth(std::map< genie::hnl::HNLDecayMode_t, double > gammaMap)
double CalcCoMLifetime(const double M, const double Ue42, const double Umu42, const double Ut42, const bool IsMajorana=false)
std::map< genie::hnl::HNLDecayMode_t, double > GetProbabilities(std::map< genie::hnl::HNLDecayMode_t, double > gammaMap)
enum genie::hnl::EHNLDecayMode HNLDecayMode_t
static constexpr double ns
Definition Units.h:98
static constexpr double GeV
Definition Units.h:28