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