GENIEGenerator
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
HEDISStrucFunc.cxx
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*
3  Copyright (c) 2003-2024, The GENIE Collaboration
4  For the full text of the license visit http://copyright.genie-mc.org
5  or see $GENIE/LICENSE
6 
7  Author: Alfonso Garcia <alfonsog \at nikhef.nl>
8  NIKHEF
9 
10  For the class documentation see the corresponding header file.
11 
12 */
13 //____________________________________________________________________________
14 
19 #include "Framework/Utils/RunOpt.h"
23 
24 #include <TSystem.h>
25 #include <TMath.h>
26 
27 #ifdef __GENIE_APFEL_ENABLED__
28 #include "APFEL/APFEL.h"
29 #endif
30 #include "LHAPDF/LHAPDF.h"
31 #ifdef __GENIE_LHAPDF6_ENABLED__
32 LHAPDF::PDF* pdf;
33 #endif
34 
35 using namespace genie;
36 using namespace genie::constants;
37 
38 // values from LHAPDF set
39 double xPDFmin; // Minimum values of x in grid from LHPADF set
40 double Q2PDFmin; // Minimum values of Q2 in grid from LHPADF set
41 double Q2PDFmax; // Maximum values of Q2 in grid from LHPADF set
42 std::map<int, double> mPDFQrk; // Mass of the quark from LHAPDF set
43 
44 //_________________________________________________________________________
46 //_________________________________________________________________________
48 {
49 
50  fSF = sfinfo;
51 
52  string basedir = "";
53  if ( gSystem->Getenv("HEDIS_SF_DATA_PATH")==NULL ) basedir = string(gSystem->Getenv("GENIE")) + "/data/evgen/hedis-sf";
54  else basedir = string(gSystem->Getenv("HEDIS_SF_DATA_PATH"));
55  LOG("HEDISStrucFunc", pWARN) << "Base directory: " << basedir;
56 
57  if ( gSystem->AccessPathName( basedir.c_str(), kReadPermission ) ) {
58  LOG("HEDISStrucFunc", pFATAL) << "Base directory doesnt exist or you dont have read permission.";
59  LOG("HEDISStrucFunc", pFATAL) << "Remember!!!";
60  LOG("HEDISStrucFunc", pFATAL) << "Path to base directory is defined with the enviroment variable HEDIS_SF_DATA_PATH.";
61  LOG("HEDISStrucFunc", pFATAL) << "If not defined, default location is $GENIE/data/evgen/hedis-sf";
62  assert(0);
63  }
64 
65  // Name of the directory where SF tables are (or will be) saved.
66  string SFname = basedir + "/" + RunOpt::Instance()->Tune()->Name();
67 
68  // Check that the directory where SF tables are stored exists
69  LOG("HEDISStrucFunc", pWARN) << "SF are (or will be) in following directory: " << SFname;
70  if ( gSystem->AccessPathName( SFname.c_str(), kReadPermission ) ) {
71  LOG("HEDISStrucFunc", pWARN) << "Bad news! Directory doesnt exists.";
72  LOG("HEDISStrucFunc", pWARN) << "HEDIS package requires computation of SF";
73  LOG("HEDISStrucFunc", pWARN) << "This will be SLOW!!!!!";
74  if ( gSystem->mkdir(SFname.c_str())==0 ) {
75  LOG("HEDISStrucFunc", pINFO) << "Creating Metafile with input information";
76  std::ofstream meta_stream((SFname+"/Inputs.txt").c_str());
77  meta_stream << fSF;
78  meta_stream.close();
79  }
80  else {
81  LOG("HEDISStrucFunc", pFATAL) << "You dont have write permission in the following directory:";
82  LOG("HEDISStrucFunc", pFATAL) << SFname;
83  LOG("HEDISStrucFunc", pFATAL) << "Remember!!!";
84  LOG("HEDISStrucFunc", pFATAL) << "Path to base directory is defined with the enviroment variable HEDIS_SF_DATA_PATH.";
85  LOG("HEDISStrucFunc", pFATAL) << "If not defined, default location is $GENIE/data/evgen/hedis-sf";
86  assert(0);
87  }
88  }
89  else {
90  LOG("HEDISStrucFunc", pWARN) << "Good news! Directory already exists.";
91  LOG("HEDISStrucFunc", pWARN) << "Precomputed SF stored in that directory will be used";
92  LOG("HEDISStrucFunc", pINFO) << "Comparing info from Metafile and selected Tune (CommonParam.xml)";
93  SF_info cm;
94  std::ifstream meta_stream((SFname+"/Inputs.txt").c_str(), std::ios::in);
95  meta_stream >> cm;
96  meta_stream.close();
97  if (cm==fSF) {
98  LOG("HEDISStrucFunc", pINFO) << "Info from MetaFile and Tune match";
99  }
100  else {
101  LOG("HEDISStrucFunc", pFATAL) << "Info from MetaFile and Tune doesnt match";
102  LOG("HEDISStrucFunc", pFATAL) << "MetaFile Path : " << SFname << "/Inputs.txt";
103  LOG("HEDISStrucFunc", pFATAL) << "From Tune : ";
104  LOG("HEDISStrucFunc", pFATAL) << cm;
105  LOG("HEDISStrucFunc", pFATAL) << "From MetaFile : ";
106  LOG("HEDISStrucFunc", pFATAL) << fSF;
107  assert(0);
108  }
109  }
110 
111  fSF.Sin2ThW = fSF.Rho==0. ? fSF.Sin2ThW : 1.-fSF.MassW*fSF.MassW/fSF.MassZ/fSF.MassZ/(1+fSF.Rho);
112  LOG("HEDISStrucFunc", pINFO) << "Weingber angle computation:";
113  LOG("HEDISStrucFunc", pINFO) << "Rho = " << fSF.Rho;
114  LOG("HEDISStrucFunc", pINFO) << "Sin2ThW = " << fSF.Sin2ThW;
115 
116  // initialising lhapdf
117 #ifdef __GENIE_LHAPDF6_ENABLED__
118  LOG("HEDISStrucFunc", pINFO) << "Initialising LHAPDF6...";
119  pdf = LHAPDF::mkPDF(fSF.LHAPDFset, fSF.LHAPDFmember);
120  xPDFmin = pdf->xMin();
121  Q2PDFmin = pdf->q2Min();
122  Q2PDFmax = pdf->q2Max();
123  LOG("HEDISStrucFunc", pINFO) << "PDF info:";
124  LOG("HEDISStrucFunc", pINFO) << "OrderQCD = " << pdf->orderQCD();
125  LOG("HEDISStrucFunc", pINFO) << "FlavorScheme = " << pdf->info().get_entry("FlavorScheme");
126  LOG("HEDISStrucFunc", pINFO) << "NumFlavors = " << pdf->info().get_entry("NumFlavors");
127  LOG("HEDISStrucFunc", pINFO) << "Xmin = " << xPDFmin << " Xmax = " << pdf->xMax() << " Q2min = " << Q2PDFmin << " Q2max = " << Q2PDFmax;
128  LOG("HEDISStrucFunc", pINFO) << "MZ = " << pdf->info().get_entry("MZ");
129  for (int i=1; i<7; i++) {
130  mPDFQrk[i] = pdf->quarkMass(i);
131  LOG("HEDISStrucFunc", pINFO) << "M" << i << " = " << mPDFQrk[i];
132  }
133 #endif
134 #ifdef __GENIE_LHAPDF5_ENABLED__
135  LOG("HEDISStrucFunc", pINFO) << "Initialising LHAPDF5...";
136  LHAPDF::initPDFByName(fSF.LHAPDFset, LHAPDF::LHGRID, fSF.LHAPDFmember);
137  xPDFmin = LHAPDF::getXmin(0);
138  Q2PDFmin = LHAPDF::getQ2min(0);
139  Q2PDFmax = LHAPDF::getQ2max(0);
140  LOG("HEDISStrucFunc", pINFO) << "PDF info:";
141  LOG("HEDISStrucFunc", pINFO) << "Xmin = " << xPDFmin << " Xmax = " << LHAPDF::getXmax(0) << " Q2min = " << Q2PDFmin << " Q2max = " << Q2PDFmax;
142  for (int i=1; i<7; i++) {
143  mPDFQrk[i] = LHAPDF::getQMass(i);
144  LOG("HEDISStrucFunc", pINFO) << "M" << i << " = " << mPDFQrk[i];
145  }
146 #endif
147 
148  // checking if LHAPDF boundaries matches boundaries defined by user
149  if ( fSF.XGridMin < xPDFmin ) {
150  LOG("HEDISStrucFunc", pWARN) << "Lower boundary in X is smaller than input PDF";
151  LOG("HEDISStrucFunc", pWARN) << "xPDFmin = " << xPDFmin;
152  LOG("HEDISStrucFunc", pWARN) << "xGridMin = " << fSF.XGridMin;
153  LOG("HEDISStrucFunc", pWARN) << "DANGER: An extrapolation will be done!!!!!";
154  }
155  else if ( fSF.Q2GridMin < Q2PDFmin ) {
156  LOG("HEDISStrucFunc", pWARN) << "Lower boundary in Q2 is smaller than input PDF";
157  LOG("HEDISStrucFunc", pWARN) << "Q2PDFmin = " << Q2PDFmin;
158  LOG("HEDISStrucFunc", pWARN) << "Q2GridMin = " << fSF.Q2GridMin;
159  LOG("HEDISStrucFunc", pWARN) << "DANGER: An extrapolation will be done!!!!!";
160  }
161  else if ( fSF.Q2GridMax > Q2PDFmax ) {
162  LOG("HEDISStrucFunc", pWARN) << "Upper boundary in Q2 is bigger than input PDF";
163  LOG("HEDISStrucFunc", pWARN) << "Q2PDFmax = " << Q2PDFmax;
164  LOG("HEDISStrucFunc", pWARN) << "Q2GridMax = " << fSF.Q2GridMax;
165  LOG("HEDISStrucFunc", pWARN) << "DANGER: An extrapolation will be done!!!!!";
166  }
167 
168  // define arrays to fill from data files
169  double dlogq2 = TMath::Abs( TMath::Log10(fSF.Q2GridMin)-TMath::Log10(fSF.Q2GridMax) ) / fSF.NGridQ2;
170  double dlogx = TMath::Abs( TMath::Log10(fSF.XGridMin)-TMath::Log10(1.) ) / fSF.NGridX;
171  LOG("HEDISStrucFunc", pINFO) << "Grid x,Q2 :" << fSF.NGridX << " , " << fSF.NGridQ2;
172  for ( double logq2 = TMath::Log10(fSF.Q2GridMin); logq2<TMath::Log10(fSF.Q2GridMax); logq2+= dlogq2 ) {
173  double q2 = TMath::Power( 10, logq2 + 0.5*dlogq2 );
174  if (q2>fSF.Q2GridMax) continue;
175  sf_q2_array.push_back(q2);
176  LOG("HEDISStrucFunc", pDEBUG) << "q2: " << sf_q2_array.back();
177  }
178  for ( double logx = TMath::Log10(fSF.XGridMin); logx<TMath::Log10(1.); logx+= dlogx ) {
179  double x = TMath::Power( 10, logx + 0.5*dlogx );
180  if ( x>1. ) continue;
181  sf_x_array.push_back(x);
182  LOG("HEDISStrucFunc", pDEBUG) << "x: " << sf_x_array.back();
183  }
184 
185  // Change to variables that are suitable for BLI2DNonUnifGrid
186  int nx = sf_q2_array.size();
187  int ny = sf_x_array.size();
188  double x[nx];
189  double y[ny];
190  double z[nx*ny];
191  for (int i=0; i<nx; i++) x[i] = sf_q2_array[i];
192  for (int j=0; j<ny; j++) y[j] = sf_x_array[j];
193 
194  vector<InteractionType_t> inttype;
195  inttype.push_back(kIntWeakCC);
196  inttype.push_back(kIntWeakNC);
197  vector<InitialState> init_state;
198  init_state.push_back(InitialState(1, 2, kPdgNuE));
199  init_state.push_back(InitialState(1, 2, kPdgAntiNuE));
200 
202  InteractionList * ilist = helist->CreateHEDISlist(init_state,inttype);
203 
204  // Load structure functions for each quark at LO
205  for(InteractionList::iterator in=ilist->begin(); in!=ilist->end(); ++in) {
206 
207  string sfFile = SFname + "/QrkSF_LO_" + QrkSFName(*in) + ".dat";
208  // Make sure data files are available
209  LOG("HEDISStrucFunc", pINFO) << "Checking if file " << sfFile << " exists...";
210  if ( gSystem->AccessPathName( sfFile.c_str()) ) {
211  LOG("HEDISStrucFunc", pWARN) << "File doesnt exist. SF table will be computed.";
212  CreateQrkSF( *in, sfFile );
213  }
214  else if ( atoi(gSystem->GetFromPipe(("wc -w "+sfFile+" | awk '{print $1}'").c_str()))!=kSFT3*nx*ny ) {
215  LOG("HEDISStrucFunc", pWARN) << "File does not contain all the need points. SF table will be recomputed.";
216  gSystem->Exec(("rm "+sfFile).c_str());
217  CreateQrkSF( *in, sfFile );
218  }
219  std::ifstream sf_stream(sfFile.c_str(), std::ios::in);
220  // Loop over F1,F2,F3
221  for(int sf = 1; sf < kSFnumber; ++sf) {
222  // Loop over x/Q2 bins
223  for ( int ij=0; ij<nx*ny; ij++ ) sf_stream >> z[ij];
224  // Create SF tables with BLI2DNonUnifGrid using x,Q2 binning
225  fQrkSFLOTables[QrkSFCode(*in)].Table[(HEDISStrucFuncType_t)sf] = new genie::BLI2DNonUnifGrid( nx, ny, x, y, z );
226  }
227  }
228 
229  if (fSF.IsNLO) {
230 #ifdef __GENIE_APFEL_ENABLED__
231  // initialising APFEL framework
232  LOG("HEDISStrucFunc", pINFO) << "Initialising APFEL..." ;
233  APFEL::SetPDFSet(fSF.LHAPDFset);
234  APFEL::SetReplica(fSF.LHAPDFmember);
235  if (fSF.Scheme=="BGR") {
236  APFEL::SetMassScheme("FONLL-B");
237  APFEL::SetPoleMasses(mPDFQrk[4],mPDFQrk[5],mPDFQrk[6]);
238  }
239  else if (fSF.Scheme=="CSMS") {
240  APFEL::SetMassScheme("ZM-VFNS");
241  APFEL::SetPoleMasses(mPDFQrk[4],mPDFQrk[5],mPDFQrk[5]+0.1);
242  }
243  else if (fSF.Scheme=="GGHR") {
244  APFEL::SetMassScheme("FFNS5");
245  APFEL::SetPoleMasses(mPDFQrk[4],mPDFQrk[5],mPDFQrk[6]);
246  APFEL::SetMaxFlavourPDFs(5);
247  APFEL::SetMaxFlavourAlpha(5);
248  }
249  else {
250  LOG("HEDISStrucFunc", pERROR) << "Mass Scheme is not set properly";
251  assert(0);
252  }
253  APFEL::SetQLimits(TMath::Sqrt(fSF.Q2GridMin),TMath::Sqrt(fSF.Q2GridMax));
254  APFEL::SetMaxFlavourPDFs(6);
255  APFEL::SetMaxFlavourAlpha(6);
256  APFEL::SetNumberOfGrids(3);
257  APFEL::SetGridParameters(1,90,3,fSF.XGridMin);
258  APFEL::SetGridParameters(2,50,5,1e-1);
259  APFEL::SetGridParameters(3,40,5,8e-1);
260  APFEL::SetPerturbativeOrder(1);
261  APFEL::SetAlphaQCDRef(pdf->alphasQ(fSF.MassZ),fSF.MassZ);
262  APFEL::SetProtonMass(kProtonMass);
263  APFEL::SetWMass(fSF.MassW);
264  APFEL::SetZMass(fSF.MassZ);
265  APFEL::SetSin2ThetaW(fSF.Sin2ThW);
266  APFEL::SetCKM(fSF.Vud, fSF.Vus, fSF.Vub,
267  fSF.Vcd, fSF.Vcs, fSF.Vcb,
268  fSF.Vtd, fSF.Vts, fSF.Vtb);
269 #endif
270 
271  // Load structure functions for each quark at LO
272  int nch = -1;
273  for(InteractionList::iterator in=ilist->begin(); in!=ilist->end(); ++in) {
274 
275  if ( nch==NucSFCode(*in) ) continue;
276  nch = NucSFCode(*in);
277 
278  string sfFile = SFname + "/NucSF_NLO_" + NucSFName(*in) + ".dat";
279  // Make sure data files are available
280  LOG("HEDISStrucFunc", pINFO) << "Checking if file " << sfFile << " exists...";
281  if ( gSystem->AccessPathName( sfFile.c_str()) ) {
282 #ifdef __GENIE_APFEL_ENABLED__
283  LOG("HEDISStrucFunc", pWARN) << "File doesnt exist. SF table will be computed.";
284  CreateNucSF( *in, sfFile );
285 #else
286  LOG("HEDISStrucFunc", pERROR) << "File doesnt exist. APFEL is needed for NLO SF";
287  assert(0);
288 #endif
289  }
290  else if ( atoi(gSystem->GetFromPipe(("wc -w "+sfFile+" | awk '{print $1}'").c_str()))!=kSFT3*nx*ny ) {
291 #ifdef __GENIE_APFEL_ENABLED__
292  LOG("HEDISStrucFunc", pWARN) << "File does not contain all the need points. SF table will be recomputed.";
293  gSystem->Exec(("rm "+sfFile).c_str());
294  CreateNucSF( *in, sfFile );
295 #else
296  LOG("HEDISStrucFunc", pERROR) << "File does not contain all the need points. APFEL is needed for NLO SF";
297  assert(0);
298 #endif
299  }
300  std::ifstream sf_stream(sfFile.c_str(), std::ios::in);
301  // Loop over F1,F2,F3
302  for(int sf = 1; sf < kSFnumber; ++sf) {
303  // Loop over x/Q2 bins
304  for ( int ij=0; ij<nx*ny; ij++ ) sf_stream >> z[ij];
305  // Create SF tables with BLI2DNonUnifGrid using x,Q2 binning
306  fNucSFNLOTables[nch].Table[(HEDISStrucFuncType_t)sf] = new genie::BLI2DNonUnifGrid( nx, ny, x, y, z );
307  }
308 
309  //compute structure functions for each nucleon at LO using quark grids
310  LOG("HEDISStrucFunc", pDEBUG) << "Creating LO " << sfFile;
311  vector <int> qcodes;
312  for(InteractionList::iterator in2=ilist->begin(); in2!=ilist->end(); ++in2) {
313  if (NucSFCode(*in2)==nch) qcodes.push_back(QrkSFCode(*in2));
314  }
315  // Loop over F1,F2,F3
316  for(int sf = 1; sf < kSFnumber; ++sf) {
317  int ij = 0;
318  // Loop over Q2 bins
319  for (int i=0; i<nx; i++) {
320  // Loop over x bins
321  for (int j=0; j<ny; j++) {
322  double sum = 0.;
323  // NucSF = sum_qrks QrkSF
324  for(vector<int>::const_iterator iq=qcodes.begin(); iq!=qcodes.end(); ++iq)
325  sum += fQrkSFLOTables[*iq].Table[(HEDISStrucFuncType_t)sf]->Evaluate(x[i],y[j]);
326  z[ij] = sum;
327  ij++;
328  }
329  }
330  // Create SF tables with BLI2DNonUnifGrid using x,Q2 binning
331  fNucSFLOTables[nch].Table[(HEDISStrucFuncType_t)sf] = new genie::BLI2DNonUnifGrid( nx, ny, x, y, z );
332  }
333  }
334  }
335 
336  fgInstance = 0;
337 
338 }
339 //_________________________________________________________________________
341 {
342 
343 }
344 //_________________________________________________________________________
346 {
347  if(fgInstance == 0) {
348  LOG("HEDISStrucFunc", pINFO) << "Late initialization";
349  static HEDISStrucFunc::Cleaner cleaner;
351  fgInstance = new HEDISStrucFunc(sfinfo);
352  }
353  return fgInstance;
354 }
355 
356 
357 //____________________________________________________________________________
358 void HEDISStrucFunc::CreateQrkSF( const Interaction * in, string sfFile )
359 {
360 
361  // variables used to tag the SF for particular channel
362  bool iscc = in->ProcInfo().IsWeakCC();
363  bool isnu = pdg::IsNeutrino(in->InitState().ProbePdg());
364  bool ispr = pdg::IsProton(in->InitState().Tgt().HitNucPdg());
365  bool sea_iq = in->InitState().Tgt().HitSeaQrk();
366  int pdg_iq = in->InitState().Tgt().HitQrkPdg();
367  int pdg_fq = in->ExclTag().FinalQuarkPdg();
368  double mass_nucl = in->InitState().Tgt().HitNucMass();
369 
370  // up and down quark swicth depending on proton or neutron interaction
371  int qrkd = 0;
372  int qrku = 0;
373  if ( ispr ) { qrkd = 1 ; qrku = 2; }
374  else { qrkd = 2 ; qrku = 1; }
375 
376  // variables associated to the PDF and coupling of the quarks
377  int qpdf1 = -999; // number used to compute PDF
378  int qpdf2 = -999; // auxiliary number used to compute PDF for valence quarks
379  double Cp2 = -999; // couping for F1,F2
380  double Cp3 = -999; // couping for F3
381  double sign3 = isnu ? +1. : -1.; // sign change for nu/nubar in F3
382  if ( iscc ) {
383  if ( isnu ) {
384  if ( pdg_iq== 1 && !sea_iq && pdg_fq== 2 ) { qpdf1 = qrkd; qpdf2 = -qrkd; Cp2 = 2*fSF.Vud*fSF.Vud; Cp3 = 2*fSF.Vud*fSF.Vud; }
385  else if ( pdg_iq== 1 && !sea_iq && pdg_fq== 4 ) { qpdf1 = qrkd; qpdf2 = -qrkd; Cp2 = 2*fSF.Vcd*fSF.Vcd; Cp3 = 2*fSF.Vcd*fSF.Vcd; }
386  else if ( pdg_iq== 1 && !sea_iq && pdg_fq== 6 ) { qpdf1 = qrkd; qpdf2 = -qrkd; Cp2 = 2*fSF.Vtd*fSF.Vtd; Cp3 = 2*fSF.Vtd*fSF.Vtd; }
387  else if ( pdg_iq== 1 && sea_iq && pdg_fq== 2 ) { qpdf1 = -qrkd; Cp2 = 2*fSF.Vud*fSF.Vud; Cp3 = 2*fSF.Vud*fSF.Vud; }
388  else if ( pdg_iq== 1 && sea_iq && pdg_fq== 4 ) { qpdf1 = -qrkd; Cp2 = 2*fSF.Vcd*fSF.Vcd; Cp3 = 2*fSF.Vcd*fSF.Vcd; }
389  else if ( pdg_iq== 1 && sea_iq && pdg_fq== 6 ) { qpdf1 = -qrkd; Cp2 = 2*fSF.Vtd*fSF.Vtd; Cp3 = 2*fSF.Vtd*fSF.Vtd; }
390  else if ( pdg_iq== 3 && sea_iq && pdg_fq== 2 ) { qpdf1 = 3; Cp2 = 2*fSF.Vus*fSF.Vus; Cp3 = 2*fSF.Vus*fSF.Vus; }
391  else if ( pdg_iq== 3 && sea_iq && pdg_fq== 4 ) { qpdf1 = 3; Cp2 = 2*fSF.Vcs*fSF.Vcs; Cp3 = 2*fSF.Vcs*fSF.Vcs; }
392  else if ( pdg_iq== 3 && sea_iq && pdg_fq== 6 ) { qpdf1 = 3; Cp2 = 2*fSF.Vts*fSF.Vts; Cp3 = 2*fSF.Vts*fSF.Vts; }
393  else if ( pdg_iq== 5 && sea_iq && pdg_fq== 2 ) { qpdf1 = 5; Cp2 = 2*fSF.Vub*fSF.Vub; Cp3 = 2*fSF.Vub*fSF.Vub; }
394  else if ( pdg_iq== 5 && sea_iq && pdg_fq== 4 ) { qpdf1 = 5; Cp2 = 2*fSF.Vcb*fSF.Vcb; Cp3 = 2*fSF.Vcb*fSF.Vcb; }
395  else if ( pdg_iq== 5 && sea_iq && pdg_fq== 6 ) { qpdf1 = 5; Cp2 = 2*fSF.Vtb*fSF.Vtb; Cp3 = 2*fSF.Vtb*fSF.Vtb; }
396  else if ( pdg_iq==-2 && sea_iq && pdg_fq==-1 ) { qpdf1 = -qrku; Cp2 = 2*fSF.Vud*fSF.Vud; Cp3 = -2*fSF.Vud*fSF.Vud; }
397  else if ( pdg_iq==-2 && sea_iq && pdg_fq==-3 ) { qpdf1 = -qrku; Cp2 = 2*fSF.Vus*fSF.Vus; Cp3 = -2*fSF.Vus*fSF.Vus; }
398  else if ( pdg_iq==-2 && sea_iq && pdg_fq==-5 ) { qpdf1 = -qrku; Cp2 = 2*fSF.Vub*fSF.Vub; Cp3 = -2*fSF.Vub*fSF.Vub; }
399  else if ( pdg_iq==-4 && sea_iq && pdg_fq==-1 ) { qpdf1 = -4; Cp2 = 2*fSF.Vcd*fSF.Vcd; Cp3 = -2*fSF.Vcd*fSF.Vcd; }
400  else if ( pdg_iq==-4 && sea_iq && pdg_fq==-3 ) { qpdf1 = -4; Cp2 = 2*fSF.Vcs*fSF.Vcs; Cp3 = -2*fSF.Vcs*fSF.Vcs; }
401  else if ( pdg_iq==-4 && sea_iq && pdg_fq==-5 ) { qpdf1 = -4; Cp2 = 2*fSF.Vcb*fSF.Vcb; Cp3 = -2*fSF.Vcb*fSF.Vcb; }
402  }
403  else {
404  if ( pdg_iq== 2 && !sea_iq && pdg_fq== 1 ) { qpdf1 = qrku; qpdf2 = -qrku; Cp2 = 2*fSF.Vud*fSF.Vud; Cp3 = 2*fSF.Vud*fSF.Vud; }
405  else if ( pdg_iq== 2 && !sea_iq && pdg_fq== 3 ) { qpdf1 = qrku; qpdf2 = -qrku; Cp2 = 2*fSF.Vus*fSF.Vus; Cp3 = 2*fSF.Vus*fSF.Vus; }
406  else if ( pdg_iq== 2 && !sea_iq && pdg_fq== 5 ) { qpdf1 = qrku; qpdf2 = -qrku; Cp2 = 2*fSF.Vub*fSF.Vub; Cp3 = 2*fSF.Vub*fSF.Vub; }
407  else if ( pdg_iq== 2 && sea_iq && pdg_fq== 1 ) { qpdf1 = -qrku; Cp2 = 2*fSF.Vud*fSF.Vud; Cp3 = 2*fSF.Vud*fSF.Vud; }
408  else if ( pdg_iq== 2 && sea_iq && pdg_fq== 3 ) { qpdf1 = -qrku; Cp2 = 2*fSF.Vus*fSF.Vus; Cp3 = 2*fSF.Vus*fSF.Vus; }
409  else if ( pdg_iq== 2 && sea_iq && pdg_fq== 5 ) { qpdf1 = -qrku; Cp2 = 2*fSF.Vub*fSF.Vub; Cp3 = 2*fSF.Vub*fSF.Vub; }
410  else if ( pdg_iq== 4 && sea_iq && pdg_fq== 1 ) { qpdf1 = 4; Cp2 = 2*fSF.Vcd*fSF.Vcd; Cp3 = 2*fSF.Vcd*fSF.Vcd; }
411  else if ( pdg_iq== 4 && sea_iq && pdg_fq== 3 ) { qpdf1 = 4; Cp2 = 2*fSF.Vcs*fSF.Vcs; Cp3 = 2*fSF.Vcs*fSF.Vcs; }
412  else if ( pdg_iq== 4 && sea_iq && pdg_fq== 5 ) { qpdf1 = 4; Cp2 = 2*fSF.Vcb*fSF.Vcb; Cp3 = 2*fSF.Vcb*fSF.Vcb; }
413  else if ( pdg_iq==-1 && sea_iq && pdg_fq==-2 ) { qpdf1 = -qrkd; Cp2 = 2*fSF.Vud*fSF.Vud; Cp3 = -2*fSF.Vud*fSF.Vud; }
414  else if ( pdg_iq==-1 && sea_iq && pdg_fq==-4 ) { qpdf1 = -qrkd; Cp2 = 2*fSF.Vcd*fSF.Vcd; Cp3 = -2*fSF.Vcd*fSF.Vcd; }
415  else if ( pdg_iq==-1 && sea_iq && pdg_fq==-6 ) { qpdf1 = -qrkd; Cp2 = 2*fSF.Vtd*fSF.Vtd; Cp3 = -2*fSF.Vtd*fSF.Vtd; }
416  else if ( pdg_iq==-3 && sea_iq && pdg_fq==-2 ) { qpdf1 = -3; Cp2 = 2*fSF.Vus*fSF.Vus; Cp3 = -2*fSF.Vus*fSF.Vus; }
417  else if ( pdg_iq==-3 && sea_iq && pdg_fq==-4 ) { qpdf1 = -3; Cp2 = 2*fSF.Vcs*fSF.Vcs; Cp3 = -2*fSF.Vcs*fSF.Vcs; }
418  else if ( pdg_iq==-3 && sea_iq && pdg_fq==-6 ) { qpdf1 = -3; Cp2 = 2*fSF.Vts*fSF.Vts; Cp3 = -2*fSF.Vts*fSF.Vts; }
419  else if ( pdg_iq==-5 && sea_iq && pdg_fq==-2 ) { qpdf1 = -5; Cp2 = 2*fSF.Vub*fSF.Vub; Cp3 = -2*fSF.Vub*fSF.Vub; }
420  else if ( pdg_iq==-5 && sea_iq && pdg_fq==-4 ) { qpdf1 = -5; Cp2 = 2*fSF.Vcb*fSF.Vcb; Cp3 = -2*fSF.Vcb*fSF.Vcb; }
421  else if ( pdg_iq==-5 && sea_iq && pdg_fq==-6 ) { qpdf1 = -5; Cp2 = 2*fSF.Vtb*fSF.Vtb; Cp3 = -2*fSF.Vtb*fSF.Vtb; }
422  }
423  }
424  else {
425  double c2u = TMath::Power( 1./2. - 4./3.*fSF.Sin2ThW,2) + 1./4.;
426  double c2d = TMath::Power(-1./2. + 2./3.*fSF.Sin2ThW,2) + 1./4.;
427  double c3u = 1./2. - 4./3.*fSF.Sin2ThW;
428  double c3d = 1./2. - 2./3.*fSF.Sin2ThW;
429  if ( pdg_iq== 1 && !sea_iq && pdg_fq== 1 ) { qpdf1 = qrkd; qpdf2 = -qrkd; Cp2 = c2d; Cp3 = c3d; }
430  else if ( pdg_iq== 2 && !sea_iq && pdg_fq== 2 ) { qpdf1 = qrku; qpdf2 = -qrku; Cp2 = c2u; Cp3 = c3u; }
431  else if ( pdg_iq== 1 && sea_iq && pdg_fq== 1 ) { qpdf1 = -qrkd; Cp2 = c2d; Cp3 = c3d; }
432  else if ( pdg_iq== 2 && sea_iq && pdg_fq== 2 ) { qpdf1 = -qrku; Cp2 = c2u; Cp3 = c3u; }
433  else if ( pdg_iq== 3 && sea_iq && pdg_fq== 3 ) { qpdf1 = 3; Cp2 = c2d; Cp3 = c3d; }
434  else if ( pdg_iq== 4 && sea_iq && pdg_fq== 4 ) { qpdf1 = 4; Cp2 = c2u; Cp3 = c3u; }
435  else if ( pdg_iq== 5 && sea_iq && pdg_fq== 5 ) { qpdf1 = 5; Cp2 = c2d; Cp3 = c3d; }
436  else if ( pdg_iq==-1 && sea_iq && pdg_fq==-1 ) { qpdf1 = -qrkd; Cp2 = c2d; Cp3 = -c3d; }
437  else if ( pdg_iq==-2 && sea_iq && pdg_fq==-2 ) { qpdf1 = -qrku; Cp2 = c2u; Cp3 = -c3u; }
438  else if ( pdg_iq==-3 && sea_iq && pdg_fq==-3 ) { qpdf1 = -3; Cp2 = c2d; Cp3 = -c3d; }
439  else if ( pdg_iq==-4 && sea_iq && pdg_fq==-4 ) { qpdf1 = -4; Cp2 = c2u; Cp3 = -c3u; }
440  else if ( pdg_iq==-5 && sea_iq && pdg_fq==-5 ) { qpdf1 = -5; Cp2 = c2d; Cp3 = -c3d; }
441  }
442 
443  // open file in which SF will be stored
444  std::ofstream sf_stream(sfFile.c_str());
445 
446  // loop over 3 different SF: F1,F2,F3
447  for(int sf = 1; sf < 4; sf++) {
448  for ( unsigned int i=0; i<sf_q2_array.size(); i++ ) {
449  double Q2 = sf_q2_array[i];
450  for ( unsigned int j=0; j<sf_x_array.size(); j++ ) {
451  double x = sf_x_array[j];
452 
453  double z = x; // this variable is introduce in case you want to apply scaling
454 
455  // W threshold
456  if (fSF.QrkThrs==1) {
457  if ( Q2*(1/z-1)+mass_nucl*mass_nucl <= TMath::Power(mass_nucl+mPDFQrk[TMath::Abs(pdg_fq)],2) ) { sf_stream << 0. << " "; continue; }
458  }
459  // W threshold and slow rescaling
460  else if (fSF.QrkThrs==2) {
461  if ( Q2*(1/z-1)+mass_nucl*mass_nucl <= TMath::Power(mass_nucl+mPDFQrk[TMath::Abs(pdg_fq)],2) ) { sf_stream << 0. << " "; continue; }
462  z *= 1+mPDFQrk[TMath::Abs(pdg_fq)]*mPDFQrk[TMath::Abs(pdg_fq)]/Q2;
463  }
464  // Slow rescaling
465  else if (fSF.QrkThrs==3) {
466  z *= 1+mPDFQrk[TMath::Abs(pdg_fq)]*mPDFQrk[TMath::Abs(pdg_fq)]/Q2;
467  }
468 
469  // Fill x,Q2 used to extract PDF. If values outside boundaries then freeze them.
470  double xPDF = TMath::Max( z, xPDFmin );
471  double Q2PDF = TMath::Max( Q2, Q2PDFmin );
472  Q2PDF = TMath::Min( Q2PDF, Q2PDFmax );
473 
474  // Extract PDF requiring then to be higher than zero
475 #ifdef __GENIE_LHAPDF6_ENABLED__
476  double fPDF = fmax( pdf->xfxQ2(qpdf1, xPDF, Q2PDF)/z , 0.);
477  if (qpdf2!= -999) fPDF -= fmax( pdf->xfxQ2(qpdf2, xPDF, Q2PDF)/z , 0.);
478 #endif
479 #ifdef __GENIE_LHAPDF5_ENABLED__
480  double fPDF = fmax( LHAPDF::xfx(xPDF, TMath::Sqrt(Q2PDF), qpdf1)/z , 0.);
481  if (qpdf2!= -999) fPDF -= fmax( LHAPDF::xfx(xPDF, TMath::Sqrt(Q2PDF), qpdf2)/z , 0.);
482 #endif
483 
484  // Compute SF
485  double tmp = -999;
486  if ( sf==1 ) tmp = fPDF*Cp2/2;
487  else if ( sf==2 ) tmp = fPDF*Cp2*z;
488  else if ( sf==3 ) tmp = fPDF*Cp3*sign3;
489 
490  // Save SF for particular x and Q2 in file
491  LOG("HEDISStrucFunc", pDEBUG) << "QrkSFLO" << sf << "[x=" << x << "," << Q2 << "] = " << tmp;
492  sf_stream << tmp << " ";
493 
494  }
495  }
496  }
497 
498  // Close file in which SF are stored
499  sf_stream.close();
500 
501 }
502 #ifdef __GENIE_APFEL_ENABLED__
503 //____________________________________________________________________________
504 void HEDISStrucFunc::CreateNucSF( const Interaction * in, string sfFile )
505 {
506 
507  // variables used to tag the SF for particular channel
508  bool iscc = in->ProcInfo().IsWeakCC();
509  bool isnu = pdg::IsNeutrino(in->InitState().ProbePdg());
510  bool ispr = pdg::IsProton(in->InitState().Tgt().HitNucPdg());
511 
512  // Define the channel that is used in APFEL
513  if ( isnu ) APFEL::SetProjectileDIS("neutrino");
514  else APFEL::SetProjectileDIS("antineutrino");
515  if ( iscc ) APFEL::SetProcessDIS("CC");
516  else APFEL::SetProcessDIS("NC");
517  if ( ispr ) APFEL::SetTargetDIS("proton");
518  else APFEL::SetTargetDIS("neutron");
519 
520  APFEL::InitializeAPFEL_DIS();
521 
522  // Using APFEL format to store the SF grid
523  int nx = sf_x_array.size();
524  int nq2 = sf_q2_array.size();
525  double xlist[nx*nq2];
526  double q2list[nx*nq2];
527  double F2list[nx*nq2];
528  double FLlist[nx*nq2];
529  double xF3list[nx*nq2];
530 
531  int nlist = 0;
532  for ( unsigned int i=0; i<sf_q2_array.size(); i++ ) {
533  double Q2 = sf_q2_array[i];
534  double Q = TMath::Sqrt(Q2);
535  // SF from APFEL are multiplied by a prefactor in NC. We dont want that prefactor
536  double norm = iscc ? 1. : 2./TMath::Power( Q2/(Q2 + TMath::Power(APFEL::GetZMass(),2))/4/APFEL::GetSin2ThetaW()/(1-APFEL::GetSin2ThetaW()), 2 );
537  APFEL::SetAlphaQCDRef(pdf->alphasQ(Q),Q);
538  APFEL::ComputeStructureFunctionsAPFEL(Q,Q);
539  for ( unsigned int j=0; j<sf_x_array.size(); j++ ) {
540  double x = sf_x_array[j];
541  q2list[nlist] = Q2;
542  xlist[nlist] = x;
543  FLlist[nlist] = norm*APFEL::FLtotal(x);
544  F2list[nlist] = norm*APFEL::F2total(x);
545  xF3list[nlist] = norm*APFEL::F3total(x);
546  nlist++;
547  }
548  }
549 
550  // open file in which SF will be stored
551  std::ofstream sf_stream(sfFile.c_str());
552 
553  double sign3 = isnu ? +1. : -1.; // sign change for nu/nubar in F3
554  // loop over 3 different SF: F1,F2,F3
555  for(int sf = 1; sf < 4; sf++) {
556  for (int i=0; i<nx*nq2; i++) {
557  double tmp = 0;
558  if ( sf==1 ) tmp = (F2list[i]-FLlist[i])/2/xlist[i];
559  else if ( sf==2 ) tmp = F2list[i];
560  else if ( sf==3 ) tmp = sign3 * xF3list[i] / xlist[i];
561  // Save SF for particular x and Q2 in file
562  LOG("HEDISStrucFunc", pDEBUG) << "NucSFNLO" << sf << "[x=" << xlist[i] << "," << q2list[i] << "] = " << tmp;
563  sf_stream << tmp << " ";
564  }
565  }
566 
567  // Close file in which SF are stored
568  sf_stream.close();
569 
570 }
571 #endif
572 //____________________________________________________________________________
574 {
575  string sin = pdg::IsNeutrino(in->InitState().ProbePdg()) ? "nu_" : "nubar_";
576  sin += in->ProcInfo().IsWeakCC() ? "cc_" : "nc_";
577  sin += pdg::IsProton(in->InitState().Tgt().HitNucPdg()) ? "p_" : "n_";
578  sin += "iq"+to_string(in->InitState().Tgt().HitQrkPdg());
579  sin += in->InitState().Tgt().HitSeaQrk() ? "sea_" : "val_";
580  sin += "fq"+to_string(in->ExclTag().FinalQuarkPdg());
581  return sin;
582 }
583 //____________________________________________________________________________
585 {
586  string sin = pdg::IsNeutrino(in->InitState().ProbePdg()) ? "nu_" : "nubar_";
587  sin += in->ProcInfo().IsWeakCC() ? "cc_" : "nc_";
588  sin += pdg::IsProton(in->InitState().Tgt().HitNucPdg()) ? "p" : "n";
589  return sin;
590 }
591 //____________________________________________________________________________
593 {
594  int code = 10000000*pdg::IsNeutrino(in->InitState().ProbePdg());
595  code += 1000000*in->ProcInfo().IsWeakCC();
596  code += 100000*pdg::IsProton(in->InitState().Tgt().HitNucPdg());
597  code += 10000*in->InitState().Tgt().HitSeaQrk();
598  code += 100*(6+in->InitState().Tgt().HitQrkPdg());
599  code += 1*(6+in->ExclTag().FinalQuarkPdg());
600  return code;
601 }
602 //____________________________________________________________________________
604 {
605  int code = 100*pdg::IsNeutrino(in->InitState().ProbePdg());
606  code += 10*in->ProcInfo().IsWeakCC();
607  code += 1*pdg::IsProton(in->InitState().Tgt().HitNucPdg());
608  return code;
609 }
610 //____________________________________________________________________________
611 SF_xQ2 HEDISStrucFunc::EvalQrkSFLO( const Interaction * in, double x, double Q2 )
612 {
613  int code = QrkSFCode(in);
614  SF_xQ2 sf;
615  sf.F1 = fQrkSFLOTables[code].Table[kSFT1]->Evaluate(Q2,x);
616  sf.F2 = fQrkSFLOTables[code].Table[kSFT2]->Evaluate(Q2,x);
617  sf.F3 = fQrkSFLOTables[code].Table[kSFT3]->Evaluate(Q2,x);
618  return sf;
619 }
620 //____________________________________________________________________________
621 SF_xQ2 HEDISStrucFunc::EvalNucSFLO( const Interaction * in, double x, double Q2 )
622 {
623  int code = NucSFCode(in);
624  SF_xQ2 sf;
625  sf.F1 = fNucSFLOTables[code].Table[kSFT1]->Evaluate(Q2,x);
626  sf.F2 = fNucSFLOTables[code].Table[kSFT2]->Evaluate(Q2,x);
627  sf.F3 = fNucSFLOTables[code].Table[kSFT3]->Evaluate(Q2,x);
628  return sf;
629 }
630 //____________________________________________________________________________
631 SF_xQ2 HEDISStrucFunc::EvalNucSFNLO( const Interaction * in, double x, double Q2 )
632 {
633  int code = NucSFCode(in);
634  SF_xQ2 sf;
635  sf.F1 = fNucSFNLOTables[code].Table[kSFT1]->Evaluate(Q2,x);
636  sf.F2 = fNucSFNLOTables[code].Table[kSFT2]->Evaluate(Q2,x);
637  sf.F3 = fNucSFNLOTables[code].Table[kSFT3]->Evaluate(Q2,x);
638  return sf;
639 }
640 
static constexpr double cm
Definition: Units.h:68
double xPDFmin
TuneId * Tune(void) const
Definition: RunOpt.h:46
string Name(void) const
Definition: TuneId.h:46
bool HitSeaQrk(void) const
Definition: Target.cxx:299
bool IsWeakCC(void) const
const int kPdgNuE
Definition: PDGCodes.h:28
bool IsNeutrino(int pdgc)
Definition: PDGUtils.cxx:110
static HEDISStrucFunc * fgInstance
#define pERROR
Definition: Messenger.h:59
double Q2PDFmin
double Q2(const Interaction *const i)
Definition: KineUtils.cxx:1077
int HitNucPdg(void) const
Definition: Target.cxx:304
Concrete implementations of the InteractionListGeneratorI interface. Generate a list of all the Inter...
int HitQrkPdg(void) const
Definition: Target.cxx:242
const int kPdgAntiNuE
Definition: PDGCodes.h:29
double HitNucMass(void) const
Definition: Target.cxx:233
#define pFATAL
Definition: Messenger.h:56
SF_xQ2 EvalNucSFLO(const Interaction *in, double x, double Q2)
HEDISStrucFunc(SF_info sfinfo)
std::map< int, double > mPDFQrk
int NucSFCode(const Interaction *in)
int QrkSFCode(const Interaction *in)
string QrkSFName(const Interaction *in)
enum genie::HEDISStrucFunc::StrucFuncType HEDISStrucFuncType_t
static HEDISStrucFunc * Instance(SF_info sfinfo)
Summary information for an interaction.
Definition: Interaction.h:56
bool IsProton(int pdgc)
Definition: PDGUtils.cxx:336
const double e
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
void CreateNucSF(const Interaction *in, string sfFile)
int ProbePdg(void) const
Definition: InitialState.h:64
#define pINFO
Definition: Messenger.h:62
InteractionList * CreateHEDISlist(vector< InitialState > vinit, vector< InteractionType_t > vinttype) const
#define pWARN
Definition: Messenger.h:60
int FinalQuarkPdg(void) const
Definition: XclsTag.h:72
static RunOpt * Instance(void)
Definition: RunOpt.cxx:54
void CreateQrkSF(const Interaction *in, string sfFile)
const XclsTag & ExclTag(void) const
Definition: Interaction.h:72
string NucSFName(const Interaction *in)
A vector of Interaction objects.
const InitialState & InitState(void) const
Definition: Interaction.h:69
const ProcessInfo & ProcInfo(void) const
Definition: Interaction.h:70
SF_xQ2 EvalQrkSFLO(const Interaction *in, double x, double Q2)
const Target & Tgt(void) const
Definition: InitialState.h:66
double Q2PDFmax
SF_xQ2 EvalNucSFNLO(const Interaction *in, double x, double Q2)
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
#define pDEBUG
Definition: Messenger.h:63