QPMDMDISPXSec.cxx
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*
3  Copyright (c) 2003-2020, The GENIE Collaboration
4  For the full text of the license visit http://copyright.genie-mc.org
5 
6 
7  Author: Joshua Berger <jberger \at physics.wisc.edu>
8  University of Wisconsin-Madison
9 
10  Costas Andreopoulos <constantinos.andreopoulos \at cern.ch>
11  University of Liverpool & STFC Rutherford Appleton Laboratory
12 */
13 //____________________________________________________________________________
14 
15 #include <sstream>
16 
17 #include <TMath.h>
18 #include <TH1D.h>
19 
24 #include "Framework/Conventions/GBuild.h"
34 #include "Framework/Utils/RunOpt.h"
37 #include "Framework/Utils/Range1.h"
39 #include "Framework/Utils/Cache.h"
41 
42 using std::ostringstream;
43 
44 using namespace genie;
45 using namespace genie::constants;
46 //using namespace genie::units;
47 
48 //____________________________________________________________________________
50 XSecAlgorithmI("genie::QPMDMDISPXSec")
51 {
52  fInInitPhase = true;
53 }
54 //____________________________________________________________________________
56 XSecAlgorithmI("genie::QPMDMDISPXSec", config)
57 {
58  fInInitPhase = true;
59 }
60 //____________________________________________________________________________
62 {
63 
64 }
65 //____________________________________________________________________________
67  const Interaction * interaction, KinePhaseSpace_t kps) const
68 {
69  if(! this -> ValidProcess (interaction) ) return 0.;
70  if(! this -> ValidKinematics (interaction) ) return 0.;
71 
72  // Get kinematical & init-state parameters
73  const Kinematics & kinematics = interaction -> Kine();
74  const InitialState & init_state = interaction -> InitState();
75  const ProcessInfo & proc_info = interaction -> ProcInfo(); // comment-out unused variable to eliminate warnings
76 
77  LOG("DMDISPXSec", pDEBUG) << "Using v^" << fVelMode << " dependence";
78 
79  double E = init_state.ProbeE(kRfHitNucRest);
80  double ml = interaction->FSPrimLepton()->Mass();
81  double Mnuc = init_state.Tgt().HitNucMass();
82  double x = kinematics.x();
83  double y = kinematics.y();
84 
85  double E2 = E * E;
86  double ml2 = ml * ml;
87  // double ml4 = ml2 * ml2; // comment-out unused variable to eliminate warnings
88  // double Mnuc2 = Mnuc * Mnuc; // comment-out unused variable to eliminate warnings
89 
90 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
91  LOG("DMDISPXSec", pDEBUG)
92  << "Computing d2xsec/dxdy @ E = " << E << ", x = " << x << ", y = " << y;
93 #endif
94 
95  // One of the xsec terms changes sign for antineutrinos @ DMDIS/CC
96 
97  // bool is_nubar_cc = pdg::IsAntiNeutrino(init_state.ProbePdg()) &&
98  // proc_info.IsWeakCC(); // // comment-out unused variable to eliminate warnings
99  // int sign = (is_nubar_cc) ? -1 : 1; // comment-out unused variable to eliminate warnings
100  int sign = 1;
101  if ( pdg::IsAntiDarkMatter(init_state.ProbePdg()) ) sign = -1;
102 
103  // Calculate the DMDIS structure functions
104  fDISSF.Calculate(interaction);
105 
106 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
107  LOG("DMDISPXSec", pDEBUG) << fDISSF;
108 #endif
109 
110  //
111  // Compute the differential cross section
112  //
113 
114  // For EM interaction replace G_{Fermi} with :
115  // a_{em} * pi / ( sqrt(2) * sin^2(theta_weinberg) * Mass_{W}^2 }
116  // See C.Quigg, Gauge Theories of the Strong, Weak and E/M Interactions,
117  // ISBN 0-8053-6021-2, p.112 (6.3.57)
118  // Also, take int account that the photon propagator is 1/p^2 but the
119  // W propagator is 1/(p^2-Mass_{W}^2), so weight the EM case with
120  // Mass_{W}^4 / q^4
121  // So, overall:
122  // G_{Fermi}^2 --> a_{em}^2 * pi^2 / (2 * sin^4(theta_weinberg) * q^{4})
123  //
124  double Q2 = utils::kinematics::XYtoQ2(E,Mnuc,x,y);
125  // double Q4 = Q2*Q2; // comment-out unused variable to eliminate warnings
126  // temp: set the Z' mass to MZ and g' = 1 for now
127  LOG("DMDISPXSec", pDEBUG)
128  << "Using a mediator mass " << fMedMass;
129  double Mzp2 = TMath::Power(fMedMass,2);
130  // double gzp = RunOpt::Instance()->ZpCoupling();
131  double gzp = fgzp;
132  double gzp4 = TMath::Power(gzp,4);
133  double g2 = gzp4 / TMath::Power((Q2 + Mzp2), 2);
134  double p2 = TMath::Max(E2 - ml2,0.);
135  double front_factor = (g2*Mnuc*E) / (64.0 * kPi) * (E2 / p2);
136 
137  // Build all dxsec/dxdy terms
138  double term1 = 0.;
139  double term2 = 0.;
140  double term3 = 0.;
141  double term4 = 0.;
142  double term5 = 0.;
143  // The cross-check of these expressions is that they should
144  // give the elastic cross-section in the limit x -> 1, PDF -> 1,
145  // and absent nuclear effects
146  if (fVelMode == 0) {
147  // Second lines contain longitudinal Z' coupling
148  // If the mediator is relatively light, these terms are important
149  // and can't be neglected like they are in the SM
150  double QchiV2 = TMath::Power(0.5*(fQchiL + fQchiR),2);
151  double QchiA2 = TMath::Power(0.5*(fQchiL - fQchiR),2);
152  double QchiVA = TMath::Power(0.5*fQchiL,2) - TMath::Power(0.5*fQchiR,2);
153  double LongF = TMath::Power(1.0 + 2.0 * x * y * Mnuc * E / Mzp2,2);
154  term1 = 8.0 * y * ((QchiV2 + QchiA2) * x * y - (QchiV2 - (2.0 + LongF) * QchiA2) * ml2 / (E * Mnuc));
155  term2 = 4.0 * (2.0 * (QchiV2 + QchiA2) * (1.0 - y - 0.5 * Mnuc / E * x * y) - QchiA2 * ml2 / E * (2.0 / E + y / x / Mnuc * (1.0 - LongF)));
156  term3 = sign * 8.0 * (2.0 - y) * x * y * QchiVA;
157  term4 = 16.0 * QchiA2 * LongF * ml2 * x * y / (E * Mnuc);
158  term5 = -8.0 * QchiA2 * LongF * ml2 * y / (E * Mnuc);
159  }
160  else if (fVelMode == 2) {
161  // Scalar case has no longitudinal Z' coupling
162  double QchiS2 = TMath::Power(fQchiS, 2);
163  term1 = - 4.0 * QchiS2 * y * (x * y + 2.0 * ml2/(E*Mnuc));
164  term2 = 2.0 * QchiS2 * TMath::Power(y - 2.0,2);
165  }
166 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
167  LOG("DMDISPXSec", pDEBUG)
168  << "\nd2xsec/dxdy ~ (" << term1 << ")*F1+(" << term2 << ")*F2+("
169  << term3 << ")*F3+(" << term4 << ")*F4+(" << term5 << ")*F5";
170 #endif
171 
172  term1 *= fDISSF.F1();
173  term2 *= fDISSF.F2();
174  term3 *= fDISSF.F3();
175  term4 *= fDISSF.F4();
176  term5 *= fDISSF.F5();
177 
178  LOG("DMDISPXSec", pDEBUG)
179  << "\nd2xsec/dxdy ~ (" << term1 << ")+(" << term2 << ")+("
180  << term3 << ")+(" << term4 << ")+(" << term5 << ")";
181 
182 
183  double xsec = front_factor * (term1 + term2 + term3 + term4 + term5);
184  xsec = TMath::Max(xsec,0.);
185 
186 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
187  LOG("DMDISPXSec", pINFO)
188  << "d2xsec/dxdy[FreeN] (E= " << E
189  << ", x= " << x << ", y= " << y << ") = " << xsec;
190 #endif
191 
192  // The algorithm computes d^2xsec/dxdy
193  // Check whether variable tranformation is needed
194  if(kps!=kPSxyfE) {
195  double J = utils::kinematics::Jacobian(interaction,kPSxyfE,kps);
196  xsec *= J;
197  }
198 
199  // If requested return the free nucleon xsec even for input nuclear tgt
200  if( interaction->TestBit(kIAssumeFreeNucleon) ) return xsec;
201 
202  // Compute nuclear cross section (simple scaling here, corrections must
203  // have been included in the structure functions)
204  const Target & target = init_state.Tgt();
205  int nucpdgc = target.HitNucPdg();
206  int NNucl = (pdg::IsProton(nucpdgc)) ? target.Z() : target.N();
207  xsec *= NNucl;
208 
209  // Apply scaling / if required to reach well known asymmptotic value
210  xsec *= fScale;
211 
212  // Subtract the inclusive charm production cross section
213  interaction->ExclTagPtr()->SetCharm();
214  double xsec_charm = fCharmProdModel->XSec(interaction,kps);
215  interaction->ExclTagPtr()->UnsetCharm();
216 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
217  LOG("DMDISPXSec", pINFO)
218  << "Subtracting charm piece: " << xsec_charm << " / out of " << xsec;
219 #endif
220  xsec = TMath::Max(0., xsec-xsec_charm);
221  return xsec;
222 }
223 //____________________________________________________________________________
225 {
226  double xsec = fXSecIntegrator->Integrate(this,interaction);
227  return xsec;
228 }
229 //____________________________________________________________________________
231 {
232  if(interaction->TestBit(kISkipProcessChk)) return true;
233 
234  const ProcessInfo & proc_info = interaction->ProcInfo();
235  if(!proc_info.IsDarkMatterDeepInelastic()) return false;
236 
237  const InitialState & init_state = interaction -> InitState();
238  int probe_pdg = init_state.ProbePdg();
239  if(!pdg::IsDarkMatter(probe_pdg) && !pdg::IsAntiDarkMatter(probe_pdg)) return false;
240 
241  if(! init_state.Tgt().HitNucIsSet()) return false;
242 
243  int hitnuc_pdg = init_state.Tgt().HitNucPdg();
244  if(!pdg::IsNeutronOrProton(hitnuc_pdg)) return false;
245 
246  return true;
247 }
248 //____________________________________________________________________________
250 {
251  Algorithm::Configure(config);
252  this->LoadConfig();
253 }
254 //____________________________________________________________________________
256 {
257  Algorithm::Configure(config);
258 
259  Registry r( "QPMDMDISPXSec_specific", false ) ;
260 
261  RgKey xdefkey = "XSecModel@genie::EventGenerator/DIS-CC-CHARM";
262  RgKey local_key = "CharmXSec" ;
263  r.Set( local_key, AlgConfigPool::Instance() -> GlobalParameterList() -> GetAlg(xdefkey) ) ;
264 
266 
267  this->LoadConfig();
268 }
269 //____________________________________________________________________________
271 {
272  // Access global defaults to use in case of missing parameters
273 
274  fDISSFModel = 0;
275  fDISSFModel =
276  dynamic_cast<const DISStructureFuncModelI *> (this->SubAlg("SFAlg"));
277  assert(fDISSFModel);
278 
279  fDISSF.SetModel(fDISSFModel); // <-- attach algorithm
280 
281  // Cross section scaling factor
282  this->GetParam( "DIS-XSecScale", fScale ) ;
283 
284  // sin^4(theta_weinberg)
285  double thw ;
286  this->GetParam( "WeinbergAngle", thw ) ;
287  fSin48w = TMath::Power( TMath::Sin(thw), 4 );
288 
289  // Caching the reduction factors used in the DMDIS/RES joing scheme?
290  // In normal event generation (1 config -> many calls) it is worth caching
291  // these suppression factors.
292  // Depending on the way this algorithm is used during event reweighting,
293  // precomputing (for all W's) & caching these factors might not be efficient.
294  // Here we provide the option to turn the caching off at run-time (default: on)
295 
296  bool cache_enabled = RunOpt::Instance()->BareXSecPreCalc();
297 
298  this->GetParamDef( "UseCache", fUseCache, true ) ;
299  fUseCache = fUseCache && cache_enabled;
300 
301  // Since this method would be called every time the current algorithm is
302  // reconfigured at run-time, remove all the data cached by this algorithm
303  // since they depend on the previous configuration
304 
305  if(!fInInitPhase) {
306  Cache * cache = Cache::Instance();
307  string keysubstr = this->Id().Key() + "/DMDIS-RES-Join";
308  cache->RmMatchedCacheBranches(keysubstr);
309  }
310  fInInitPhase = false;
311 
312  // velocity dependence of the interaction
313  this->GetParamDef("velocity-mode", fVelMode, 0);
314 
315  // mediator coupling
316  this->GetParam("ZpCoupling", fgzp);
317  this->GetParam("DarkLeftCharge", fQchiL);
318  this->GetParam("DarkRightCharge", fQchiR);
319  this->GetParam("DarkScalarCharge", fQchiS);
320 
321  // mediator mass ratio and mediator mass
323 
324  //-- load the differential cross section integrator
326  dynamic_cast<const XSecIntegratorI *> (this->SubAlg("XSec-Integrator"));
327  assert(fXSecIntegrator);
328 
329  RgKey local_key = "CharmXSec" ;
330  RgAlg xalg ;
331  GetParam( local_key, xalg) ;
332  LOG("DMDISXSec", pDEBUG)
333  << "Loading the cross section model: " << xalg;
334  fCharmProdModel = dynamic_cast<const XSecAlgorithmI *> ( this -> SubAlg(local_key) ) ;
335  assert(fCharmProdModel);
336 }
337 //____________________________________________________________________________
338 
void SetModel(const DISStructureFuncModelI *model)
Attach an algorithm.
Cross Section Calculation Interface.
Pure Abstract Base Class. Defines the DISStructureFuncModelI interface to be implemented by any algor...
Basic constants.
double fgzp
Coupling to the mediator Zprime.
Definition: QPMDMDISPXSec.h:74
double F2(void) const
Get the computed structure function F2.
double J(double q0, double q3, double Enu, double ml)
Definition: MECUtils.cxx:147
THE MAIN GENIE PROJECT NAMESPACE
Definition: AlgCmp.h:25
Cross Section Integrator Interface.
double Q2(const Interaction *const i)
Definition: KineUtils.cxx:1064
int HitNucPdg(void) const
Definition: Target.cxx:304
const int kPdgMediator
Definition: PDGCodes.h:220
virtual double XSec(const Interaction *i, KinePhaseSpace_t k=kPSfE) const =0
Compute the cross section for the input interaction.
double HitNucMass(void) const
Definition: Target.cxx:233
double fSin48w
sin^4(Weingberg angle)
Definition: QPMDMDISPXSec.h:71
Generated/set kinematical variables for an event.
Definition: Kinematics.h:39
bool IsDarkMatter(int pdgc)
Definition: PDGUtils.cxx:124
double x(bool selected=false) const
Definition: Kinematics.cxx:99
int fVelMode
velcoity dependence for xsec
Definition: QPMDMDISPXSec.h:72
double Integral(const Interaction *i) const
enum genie::EKinePhaseSpace KinePhaseSpace_t
const XSecAlgorithmI * fCharmProdModel
Definition: QPMDMDISPXSec.h:65
bool ValidProcess(const Interaction *i) const
Can this cross section algorithm handle the input process?
void SetCharm(int charm_pdgc=0)
Definition: XclsTag.cxx:59
double y(bool selected=false) const
Definition: Kinematics.cxx:112
double F4(void) const
Get the computed structure function F4.
double fQchiS
Scalar DM charge.
Definition: QPMDMDISPXSec.h:77
Summary information for an interaction.
Definition: Interaction.h:56
double F1(void) const
Get the computed structure function F1.
virtual bool ValidKinematics(const Interaction *i) const
Is the input kinematical point a physically allowed one?
bool IsProton(int pdgc)
Definition: PDGUtils.cxx:333
bool BareXSecPreCalc(void) const
Definition: RunOpt.h:51
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
bool IsAntiDarkMatter(int pdgc)
Definition: PDGUtils.cxx:130
static Config * config
Definition: config.cpp:1054
double fQchiR
Right-handed DM charge.
Definition: QPMDMDISPXSec.h:76
A class encapsulating an enumeration of interaction types (EM, Weak-CC, Weak-NC) and scattering types...
Definition: ProcessInfo.h:46
const DISStructureFuncModelI * fDISSFModel
SF model.
Definition: QPMDMDISPXSec.h:61
double XYtoQ2(double Ev, double M, double x, double y)
Definition: KineUtils.cxx:1195
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
Definition: Target.h:40
virtual void Configure(const Registry &config)
Definition: Algorithm.cxx:62
double fMedMass
Mediator mass.
Definition: QPMDMDISPXSec.h:73
int ProbePdg(void) const
Definition: InitialState.h:64
DISStructureFunc fDISSF
Definition: QPMDMDISPXSec.h:58
int Z(void) const
Definition: Target.h:68
#define pINFO
Definition: Messenger.h:62
bool fUseCache
cache reduction factors used in joining scheme
Definition: QPMDMDISPXSec.h:68
double fQchiL
Left-handed DM charge.
Definition: QPMDMDISPXSec.h:75
double fScale
cross section scaling factor
Definition: QPMDMDISPXSec.h:70
TParticlePDG * FSPrimLepton(void) const
final state primary lepton
const XSecIntegratorI * fXSecIntegrator
diff. xsec integrator
Definition: QPMDMDISPXSec.h:63
double F5(void) const
Get the computed structure function F5.
GENIE Cache Memory.
Definition: Cache.h:38
XclsTag * ExclTagPtr(void) const
Definition: Interaction.h:77
int sign(double val)
Definition: UtilFunc.cxx:104
double F3(void) const
Get the computed structure function F3.
virtual const AlgId & Id(void) const
Get algorithm ID.
Definition: Algorithm.h:97
int N(void) const
Definition: Target.h:69
static PDGLibrary * Instance(void)
Definition: PDGLibrary.cxx:57
static RunOpt * Instance(void)
Definition: RunOpt.cxx:54
bool HitNucIsSet(void) const
Definition: Target.cxx:283
string RgKey
void Configure(const Registry &config)
A registry. Provides the container for algorithm configuration parameters.
Definition: Registry.h:65
const UInt_t kIAssumeFreeNucleon
Definition: Interaction.h:49
E
Definition: 018_def.c:13
bool IsNeutronOrProton(int pdgc)
Definition: PDGUtils.cxx:348
Definition: 018_def.c:13
virtual double Integrate(const XSecAlgorithmI *model, const Interaction *interaction) const =0
void UnsetCharm(void)
Definition: XclsTag.cxx:65
double Jacobian(const Interaction *const i, KinePhaseSpace_t f, KinePhaseSpace_t t)
Definition: KineUtils.cxx:130
const ProcessInfo & ProcInfo(void) const
Definition: Interaction.h:70
list x
Definition: train.py:276
void Calculate(const Interaction *interaction)
Calculate the S/F&#39;s for the input interaction using the attached algorithm.
void RmMatchedCacheBranches(string key_substring)
Definition: Cache.cxx:127
TParticlePDG * Find(int pdgc, bool must_exist=true)
Definition: PDGLibrary.cxx:75
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
Definition: InitialState.h:66
double XSec(const Interaction *i, KinePhaseSpace_t k) const
Compute the cross section for the input interaction.
static Cache * Instance(void)
Definition: Cache.cxx:67
bool IsDarkMatterDeepInelastic(void) const
Definition: ProcessInfo.cxx:89
void Set(RgIMapPair entry)
Definition: Registry.cxx:267
double ProbeE(RefFrame_t rf) const
static const double kPi
Definition: Constants.h:37
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
string Key(void) const
Definition: AlgId.h:46
const UInt_t kISkipProcessChk
if set, skip process validity checks
Definition: Interaction.h:47
static AlgConfigPool * Instance()
Initial State information.
Definition: InitialState.h:48
#define pDEBUG
Definition: Messenger.h:63
const Algorithm * SubAlg(const RgKey &registry_key) const
Definition: Algorithm.cxx:345