GENIEGenerator
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SppChannel.h
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*!
3 
4 \class genie::SppChannel
5 
6 \brief Enumeration of single pion production channels
7 
8 \authors Costas Andreopoulos <c.andreopoulos \at cern.ch>
9  University of Liverpool \n
10  Igor Kakorin <kakorin@jinr.ru> Joint Institute for Nuclear Research \n
11 
12 \created December 16, 2004
13 
14 \update November 12, 2019
15  Added extra functions for MK model. \n
16  Branching ratios are looked in particle database now.
17 
18 \cpright Copyright (c) 2003-2024, The GENIE Collaboration
19  For the full text of the license visit http://copyright.genie-mc.org
20 */
21 //____________________________________________________________________________
22 
23 #ifndef _SPP_CHANNEL_H_
24 #define _SPP_CHANNEL_H_
25 
26 #include <string>
27 
28 #include <TDecayChannel.h>
29 
38 
39 using std::string;
40 using namespace genie::constants;
41 
42 namespace genie {
43 
44 typedef enum ESppChannel {
45 
46  kSppNull = 0,
47 
48  // [p,n,pi+,pi0,pi-]
49 
50  kSpp_vp_cc_10100, /* neutrino CC */
53 
54  kSpp_vp_nc_10010, /* neutrino NC */
58 
59  kSpp_vbn_cc_01001, /* anti-neutrino CC */
62 
63  kSpp_vbp_nc_10010, /* anti-neutrino NC */
67 
68 } SppChannel_t;
69 
70 
72 {
73 public:
74 
75  //__________________________________________________________________________
76  static string AsString(SppChannel_t channel)
77  {
78  switch (channel) {
79 
80  case (kSpp_vp_cc_10100) : return "v p -> l- p pi+"; break;
81  case (kSpp_vn_cc_10010) : return "v n -> l- p pi0"; break;
82  case (kSpp_vn_cc_01100) : return "v n -> l- n pi+"; break;
83 
84  case (kSpp_vp_nc_10010) : return "v p -> v p pi0"; break;
85  case (kSpp_vp_nc_01100) : return "v p -> v n pi+"; break;
86  case (kSpp_vn_nc_01010) : return "v n -> v n pi0"; break;
87  case (kSpp_vn_nc_10001) : return "v n -> v p pi-"; break;
88 
89  case (kSpp_vbn_cc_01001): return "vb n -> l+ n pi-"; break;
90  case (kSpp_vbp_cc_01010): return "vb p -> l+ n pi0"; break;
91  case (kSpp_vbp_cc_10001): return "vb p -> l+ p pi-"; break;
92 
93  case (kSpp_vbp_nc_10010): return "vb p -> vb p pi0"; break;
94  case (kSpp_vbp_nc_01100): return "vb p -> vb n pi+"; break;
95  case (kSpp_vbn_nc_01010): return "vb n -> vb n pi0"; break;
96  case (kSpp_vbn_nc_10001): return "vb n -> vb p pi-"; break;
97 
98  default : return "Unknown"; break;
99  }
100  return "Unknown";
101  }
102  //__________________________________________________________________________
103  static int InitStateNucleon(SppChannel_t channel)
104  {
105  switch (channel) {
106 
107  case (kSpp_vp_cc_10100) : return kPdgProton; break;
108  case (kSpp_vn_cc_10010) : return kPdgNeutron; break;
109  case (kSpp_vn_cc_01100) : return kPdgNeutron; break;
110 
111  case (kSpp_vp_nc_10010) : return kPdgProton; break;
112  case (kSpp_vp_nc_01100) : return kPdgProton; break;
113  case (kSpp_vn_nc_01010) : return kPdgNeutron; break;
114  case (kSpp_vn_nc_10001) : return kPdgNeutron; break;
115 
116  case (kSpp_vbn_cc_01001): return kPdgNeutron; break;
117  case (kSpp_vbp_cc_01010): return kPdgProton; break;
118  case (kSpp_vbp_cc_10001): return kPdgProton; break;
119 
120  case (kSpp_vbp_nc_10010): return kPdgProton; break;
121  case (kSpp_vbp_nc_01100): return kPdgProton; break;
122  case (kSpp_vbn_nc_01010): return kPdgNeutron; break;
123  case (kSpp_vbn_nc_10001): return kPdgNeutron; break;
124 
125  default : return 0; break;
126  }
127  return 0;
128  }
129  //__________________________________________________________________________
130  static int FinStateNucleon(SppChannel_t channel)
131  {
132  switch (channel) {
133 
134  case (kSpp_vp_cc_10100) : return kPdgProton; break;
135  case (kSpp_vn_cc_10010) : return kPdgProton; break;
136  case (kSpp_vn_cc_01100) : return kPdgNeutron; break;
137 
138  case (kSpp_vp_nc_10010) : return kPdgProton; break;
139  case (kSpp_vp_nc_01100) : return kPdgNeutron; break;
140  case (kSpp_vn_nc_01010) : return kPdgNeutron; break;
141  case (kSpp_vn_nc_10001) : return kPdgProton; break;
142 
143  case (kSpp_vbn_cc_01001): return kPdgNeutron; break;
144  case (kSpp_vbp_cc_01010): return kPdgNeutron; break;
145  case (kSpp_vbp_cc_10001): return kPdgProton; break;
146 
147  case (kSpp_vbp_nc_10010): return kPdgProton; break;
148  case (kSpp_vbp_nc_01100): return kPdgNeutron; break;
149  case (kSpp_vbn_nc_01010): return kPdgNeutron; break;
150  case (kSpp_vbn_nc_10001): return kPdgProton; break;
151 
152  default : return 0; break;
153  }
154  return 0;
155  }
156  //__________________________________________________________________________
157  static int FinStatePion(SppChannel_t channel)
158  {
159  switch (channel) {
160 
161  case (kSpp_vp_cc_10100) : return kPdgPiP; break;
162  case (kSpp_vn_cc_10010) : return kPdgPi0; break;
163  case (kSpp_vn_cc_01100) : return kPdgPiP; break;
164 
165  case (kSpp_vp_nc_10010) : return kPdgPi0; break;
166  case (kSpp_vp_nc_01100) : return kPdgPiP; break;
167  case (kSpp_vn_nc_01010) : return kPdgPi0; break;
168  case (kSpp_vn_nc_10001) : return kPdgPiM; break;
169 
170  case (kSpp_vbn_cc_01001): return kPdgPiM; break;
171  case (kSpp_vbp_cc_01010): return kPdgPi0; break;
172  case (kSpp_vbp_cc_10001): return kPdgPiM; break;
173 
174  case (kSpp_vbp_nc_10010): return kPdgPi0; break;
175  case (kSpp_vbp_nc_01100): return kPdgPiP; break;
176  case (kSpp_vbn_nc_01010): return kPdgPi0; break;
177  case (kSpp_vbn_nc_10001): return kPdgPiM; break;
178 
179  default : return 0; break;
180  }
181  return 0;
182  }
183  //__________________________________________________________________________
184  static int ResonanceCharge(SppChannel_t channel)
185  {
186  switch (channel) {
187 
188  case (kSpp_vp_cc_10100) : return 2; break;
189  case (kSpp_vn_cc_10010) : return 1; break;
190  case (kSpp_vn_cc_01100) : return 1; break;
191 
192  case (kSpp_vp_nc_10010) : return 1; break;
193  case (kSpp_vp_nc_01100) : return 1; break;
194  case (kSpp_vn_nc_01010) : return 0; break;
195  case (kSpp_vn_nc_10001) : return 0; break;
196 
197  case (kSpp_vbn_cc_01001): return -1; break;
198  case (kSpp_vbp_cc_01010): return 0; break;
199  case (kSpp_vbp_cc_10001): return 0; break;
200 
201  case (kSpp_vbp_nc_10010): return 1; break;
202  case (kSpp_vbp_nc_01100): return 1; break;
203  case (kSpp_vbn_nc_01010): return 0; break;
204  case (kSpp_vbn_nc_10001): return 0; break;
205 
206  default : return 0; break;
207  }
208  return 0;
209  }
210  //__________________________________________________________________________
211  static int FinStateIsospin(SppChannel_t channel)
212  {
213  switch (channel) {
214 
215  case (kSpp_vp_cc_10100) : return 3; break;
216  case (kSpp_vn_cc_10010) : return 1; break;
217  case (kSpp_vn_cc_01100) : return 1; break;
218 
219  case (kSpp_vp_nc_10010) : return 1; break;
220  case (kSpp_vp_nc_01100) : return 1; break;
221  case (kSpp_vn_nc_01010) : return 1; break;
222  case (kSpp_vn_nc_10001) : return 1; break;
223 
224  case (kSpp_vbn_cc_01001): return 3; break;
225  case (kSpp_vbp_cc_01010): return 1; break;
226  case (kSpp_vbp_cc_10001): return 1; break;
227 
228  case (kSpp_vbp_nc_10010): return 1; break;
229  case (kSpp_vbp_nc_01100): return 1; break;
230  case (kSpp_vbn_nc_01010): return 1; break;
231  case (kSpp_vbn_nc_10001): return 1; break;
232 
233  default : return 0; break;
234  }
235  return 0;
236  }
237  //__________________________________________________________________________
238  static double IsospinWeight(SppChannel_t channel, Resonance_t res)
239  {
240  // return the square of isospin Glebsch Gordon coefficient for the input resonance
241  // contribution to the input exclusive channel
242 
243  bool is_delta = utils::res::IsDelta(res);
244 
245  double iw_1_3 = 1./3;
246  double iw_2_3 = 2./3;
247 
248  switch (channel) {
249 
250  //-- v CC
251  case (kSpp_vp_cc_10100) : return (is_delta) ? (1.0) : (0.0); break;
252  case (kSpp_vn_cc_10010) : return (is_delta) ? (iw_2_3) : (iw_1_3); break;
253  case (kSpp_vn_cc_01100) : return (is_delta) ? (iw_1_3) : (iw_2_3); break;
254 
255  //-- v NC
256  case (kSpp_vp_nc_10010) : return (is_delta) ? (iw_2_3) : (iw_1_3); break;
257  case (kSpp_vp_nc_01100) : return (is_delta) ? (iw_1_3) : (iw_2_3); break;
258  case (kSpp_vn_nc_01010) : return (is_delta) ? (iw_2_3) : (iw_1_3); break;
259  case (kSpp_vn_nc_10001) : return (is_delta) ? (iw_1_3) : (iw_2_3); break;
260 
261  //-- same as for neutrinos (? - check)
262 
263  //-- vbar CC
264  case (kSpp_vbn_cc_01001): return (is_delta) ? (1.0) : (0.0); break;
265  case (kSpp_vbp_cc_01010): return (is_delta) ? (iw_2_3) : (iw_1_3); break;
266  case (kSpp_vbp_cc_10001): return (is_delta) ? (iw_1_3) : (iw_2_3); break;
267 
268  //-- vbar NC
269  case (kSpp_vbp_nc_10010): return (is_delta) ? (iw_2_3) : (iw_1_3); break;
270  case (kSpp_vbp_nc_01100): return (is_delta) ? (iw_1_3) : (iw_2_3); break;
271  case (kSpp_vbn_nc_01010): return (is_delta) ? (iw_2_3) : (iw_1_3); break;
272  case (kSpp_vbn_nc_10001): return (is_delta) ? (iw_1_3) : (iw_2_3); break;
273 
274  default : return 0; break;
275  }
276 
277  return 0;
278  }
279  //__________________________________________________________________________
280  static double Isospin3Coefficients(SppChannel_t channel)
281  {
282  // return the isospin coefficients for the channel
283  // with final state isospin = 3/2
284 
285  // [p,n,pi+,pi0,pi-]
286  switch (channel) {
287 
288  //-- v CC
289  case (kSpp_vp_cc_10100) : return kSqrt3;
290  case (kSpp_vn_cc_10010) : return -kSqrt2_3;
291  case (kSpp_vn_cc_01100) : return k1_Sqrt3;
292 
293  //-- v NC
294  case (kSpp_vp_nc_10010) : return kSqrt2_3;
295  case (kSpp_vp_nc_01100) : return -k1_Sqrt3;
296  case (kSpp_vn_nc_01010) : return kSqrt2_3;
297  case (kSpp_vn_nc_10001) : return k1_Sqrt3;
298 
299 
300 
301  //-- vbar CC
302  case (kSpp_vbn_cc_01001): return kSqrt3;
303  case (kSpp_vbp_cc_01010): return -kSqrt2_3;
304  case (kSpp_vbp_cc_10001): return k1_Sqrt3;
305 
306  //-- vbar NC
307  case (kSpp_vbp_nc_10010): return kSqrt2_3;
308  case (kSpp_vbp_nc_01100): return -k1_Sqrt3;
309  case (kSpp_vbn_nc_01010): return kSqrt2_3;
310  case (kSpp_vbn_nc_10001): return k1_Sqrt3;
311 
312  default : return 0;
313  }
314 
315  }
316  //__________________________________________________________________________
317  static double Isospin1Coefficients(SppChannel_t channel)
318  {
319  // return the isospin coefficients for the channel
320  // with final state isospin = 1/2
321 
322  // [p,n,pi+,pi0,pi-]
323  switch (channel) {
324 
325  //-- v CC
326  case (kSpp_vp_cc_10100) : return 0.;
327  case (kSpp_vn_cc_10010) : return k1_Sqrt3;
328  case (kSpp_vn_cc_01100) : return kSqrt2_3;
329 
330  //-- v NC
331  case (kSpp_vp_nc_10010) : return -k1_Sqrt3;
332  case (kSpp_vp_nc_01100) : return -kSqrt2_3;
333  case (kSpp_vn_nc_01010) : return k1_Sqrt3;
334  case (kSpp_vn_nc_10001) : return -kSqrt2_3;
335 
336 
337 
338  //-- vbar CC
339  case (kSpp_vbn_cc_01001): return 0.;
340  case (kSpp_vbp_cc_01010): return k1_Sqrt3;
341  case (kSpp_vbp_cc_10001): return kSqrt2_3;
342 
343  //-- vbar NC
344  case (kSpp_vbp_nc_10010): return -k1_Sqrt3;
345  case (kSpp_vbp_nc_01100): return -kSqrt2_3;
346  case (kSpp_vbn_nc_01010): return k1_Sqrt3;
347  case (kSpp_vbn_nc_10001): return -kSqrt2_3;
348 
349  default : return 0;
350  }
351 
352  }
353  //__________________________________________________________________________
354  // The values of resonance mass and width is taken from
355  // M. Tanabashi et al. (Particle Data Group) Phys. Rev. D 98, 030001
356  // Hardcoded data are removed, now they are taken from PDG table via TDatabasePDG and cached
357  static double BranchingRatio(Resonance_t res)
358  {
359  // return the BR for the decay of the input resonance to the final state: nucleon + pion.
360  // get list of TDecayChannels, match one with the input channel and get
361  // the branching ratio.
362  static std::map<Resonance_t, double> cache ;
363 
364  auto it = cache.find( res ) ;
365  if ( it != cache.end() ) {
366  return it -> second ;
367  }
368 
369  double BR = 0. ;
370 
371  PDGLibrary * pdglib = PDGLibrary::Instance();
372  // the charge of resonance does not matter
373  int pdg = genie::utils::res::PdgCode(res, 0);
374  TParticlePDG * res_pdg = pdglib->Find( pdg );
375  if (res_pdg != 0)
376  {
377  for (int nch = 0; nch < res_pdg->NDecayChannels(); nch++)
378  {
379  TDecayChannel * ch = res_pdg->DecayChannel(nch);
380  if (ch->NDaughters() == 2)
381  {
382  int first_daughter_pdg = ch->DaughterPdgCode (0);
383  int second_daughter_pdg = ch->DaughterPdgCode (1);
384  if ((genie::pdg::IsNucleon(first_daughter_pdg ) && genie::pdg::IsPion(second_daughter_pdg)) ||
385  (genie::pdg::IsNucleon(second_daughter_pdg) && genie::pdg::IsPion(first_daughter_pdg )))
386  {
387  BR += ch->BranchingRatio();
388  }
389  }
390  }
391  cache[res] = BR;
392  return BR;
393  }
394 
395  // should not be here - meaningless to return anything
396  gAbortingInErr = true;
397  LOG("SppChannel", pFATAL) << "Unknown resonance " << res;
398  exit(1);
399 
400  }
401  //__________________________________________________________________________
402  static SppChannel_t FromInteraction(const Interaction * interaction)
403  {
404  const InitialState & init_state = interaction->InitState();
405  const ProcessInfo & proc_info = interaction->ProcInfo();
406  if ( !proc_info.IsSinglePion() ) return kSppNull;
407 
408  const XclsTag & xcls_tag = interaction->ExclTag();
409  if( xcls_tag.NPions() != 1 ) return kSppNull;
410  if( xcls_tag.NNucleons() != 1 ) return kSppNull;
411 
412  // get struck nucleon
413  int hit_nucl_pdgc = init_state.Tgt().HitNucPdg();
414  if( ! pdg::IsNeutronOrProton(hit_nucl_pdgc) ) return kSppNull;
415  bool hit_p = pdg::IsProton(hit_nucl_pdgc);
416  bool hit_n = !hit_p;
417 
418  // the final state hadronic sytem has 1 pi and 1 nucleon
419  bool fs_pi_plus = ( xcls_tag.NPiPlus() == 1 );
420  bool fs_pi_minus = ( xcls_tag.NPiMinus() == 1 );
421  bool fs_pi_0 = ( xcls_tag.NPi0() == 1 );
422  bool fs_p = ( xcls_tag.NProtons() == 1 );
423  bool fs_n = ( xcls_tag.NNeutrons() == 1 );
424 
425  // get probe
426  int probe = init_state.ProbePdg();
427 
428  // figure out spp channel
429  if( pdg::IsNeutrino(probe) ) {
430 
431  if ( proc_info.IsWeakCC() ) {
432  if (hit_p && fs_p && fs_pi_plus ) return kSpp_vp_cc_10100;
433  else if (hit_n && fs_p && fs_pi_0 ) return kSpp_vn_cc_10010;
434  else if (hit_n && fs_n && fs_pi_plus ) return kSpp_vn_cc_01100;
435  else return kSppNull;
436  } else if ( proc_info.IsWeakNC() ) {
437  if (hit_p && fs_p && fs_pi_0 ) return kSpp_vp_nc_10010;
438  else if (hit_p && fs_n && fs_pi_plus ) return kSpp_vp_nc_01100;
439  else if (hit_n && fs_n && fs_pi_0 ) return kSpp_vn_nc_01010;
440  else if (hit_n && fs_p && fs_pi_minus) return kSpp_vn_nc_10001;
441  else return kSppNull;
442  } else return kSppNull;
443 
444  } else if( pdg::IsAntiNeutrino(probe) ) {
445 
446  if ( proc_info.IsWeakCC() ) {
447  if (hit_n && fs_n && fs_pi_minus) return kSpp_vbn_cc_01001;
448  else if (hit_p && fs_n && fs_pi_0 ) return kSpp_vbp_cc_01010;
449  else if (hit_p && fs_p && fs_pi_minus) return kSpp_vbp_cc_10001;
450  else return kSppNull;
451  } else if ( proc_info.IsWeakNC() ) {
452  if (hit_p && fs_p && fs_pi_0 ) return kSpp_vbp_nc_10010;
453  else if (hit_p && fs_n && fs_pi_plus ) return kSpp_vbp_nc_01100;
454  else if (hit_n && fs_n && fs_pi_0 ) return kSpp_vbn_nc_01010;
455  else if (hit_n && fs_p && fs_pi_minus) return kSpp_vbn_nc_10001;
456  else return kSppNull;
457  } else return kSppNull;
458  }
459 
460  return kSppNull;
461  }
462  //__________________________________________________________________________
463 };
464 
465 } // genie namespace
466 
467 #endif // _SPP_CHANNEL_H_
bool IsDelta(Resonance_t res)
is it a Delta resonance?
static SppChannel_t FromInteraction(const Interaction *interaction)
Definition: SppChannel.h:402
bool IsPion(int pdgc)
Definition: PDGUtils.cxx:326
bool IsWeakCC(void) const
bool IsNeutrino(int pdgc)
Definition: PDGUtils.cxx:110
int HitNucPdg(void) const
Definition: Target.cxx:304
bool IsNucleon(int pdgc)
Definition: PDGUtils.cxx:346
int NPions(void) const
Definition: XclsTag.h:62
Enumeration of single pion production channels.
Definition: SppChannel.h:71
#define pFATAL
Definition: Messenger.h:56
int NNeutrons(void) const
Definition: XclsTag.h:57
static double Isospin1Coefficients(SppChannel_t channel)
Definition: SppChannel.h:317
int NPiMinus(void) const
Definition: XclsTag.h:60
static int FinStateNucleon(SppChannel_t channel)
Definition: SppChannel.h:130
static double IsospinWeight(SppChannel_t channel, Resonance_t res)
Definition: SppChannel.h:238
enum genie::EResonance Resonance_t
Contains minimal information for tagging exclusive processes.
Definition: XclsTag.h:39
enum genie::ESppChannel SppChannel_t
static string AsString(SppChannel_t channel)
Definition: SppChannel.h:76
Summary information for an interaction.
Definition: Interaction.h:56
static constexpr double second
Definition: Units.h:37
bool IsProton(int pdgc)
Definition: PDGUtils.cxx:336
bool IsWeakNC(void) const
int PdgCode(Resonance_t res, int Q)
(resonance id, charge) -&gt; PDG code
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
static int ResonanceCharge(SppChannel_t channel)
Definition: SppChannel.h:184
static int InitStateNucleon(SppChannel_t channel)
Definition: SppChannel.h:103
A class encapsulating an enumeration of interaction types (EM, Weak-CC, Weak-NC) and scattering types...
Definition: ProcessInfo.h:46
ESppChannel
Definition: SppChannel.h:44
bool IsAntiNeutrino(int pdgc)
Definition: PDGUtils.cxx:118
int ProbePdg(void) const
Definition: InitialState.h:64
int NPiPlus(void) const
Definition: XclsTag.h:59
const int kPdgPiP
Definition: PDGCodes.h:158
const int kPdgPi0
Definition: PDGCodes.h:160
int NNucleons(void) const
Definition: XclsTag.h:61
int NPi0(void) const
Definition: XclsTag.h:58
static int FinStatePion(SppChannel_t channel)
Definition: SppChannel.h:157
static double Isospin3Coefficients(SppChannel_t channel)
Definition: SppChannel.h:280
static PDGLibrary * Instance(void)
Definition: PDGLibrary.cxx:68
Singleton class to load &amp; serve a TDatabasePDG.
Definition: PDGLibrary.h:35
const XclsTag & ExclTag(void) const
Definition: Interaction.h:72
bool IsNeutronOrProton(int pdgc)
Definition: PDGUtils.cxx:351
const int kPdgPiM
Definition: PDGCodes.h:159
const InitialState & InitState(void) const
Definition: Interaction.h:69
const ProcessInfo & ProcInfo(void) const
Definition: Interaction.h:70
const int kPdgProton
Definition: PDGCodes.h:81
TParticlePDG * Find(int pdgc, bool must_exist=true)
Definition: PDGLibrary.cxx:86
const Target & Tgt(void) const
Definition: InitialState.h:66
bool IsSinglePion(void) const
Definition: ProcessInfo.cxx:79
static double BranchingRatio(Resonance_t res)
Definition: SppChannel.h:357
static int FinStateIsospin(SppChannel_t channel)
Definition: SppChannel.h:211
bool gAbortingInErr
Definition: Messenger.cxx:34
const int kPdgNeutron
Definition: PDGCodes.h:83
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
Initial State information.
Definition: InitialState.h:48
int NProtons(void) const
Definition: XclsTag.h:56