GENIEGenerator
Loading...
Searching...
No Matches
HEDISStrucFunc.cxx
Go to the documentation of this file.
1//____________________________________________________________________________
2/*
3 Copyright (c) 2003-2025, The GENIE Collaboration
4 For the full text of the license visit http://copyright.genie-mc.org
5 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
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__
32LHAPDF::PDF* pdf;
33#endif
34
35using namespace genie;
36using namespace genie::constants;
37
38// values from LHAPDF set
39double xPDFmin; // Minimum values of x in grid from LHPADF set
40double Q2PDFmin; // Minimum values of Q2 in grid from LHPADF set
41double Q2PDFmax; // Maximum values of Q2 in grid from LHPADF set
42std::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//_________________________________________________________________________
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//____________________________________________________________________________
358void 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//____________________________________________________________________________
504void 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//____________________________________________________________________________
611SF_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//____________________________________________________________________________
621SF_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//____________________________________________________________________________
631SF_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
double Q2PDFmin
double xPDFmin
std::map< int, double > mPDFQrk
double Q2PDFmax
#define pINFO
Definition Messenger.h:62
#define pERROR
Definition Messenger.h:59
#define pFATAL
Definition Messenger.h:56
#define pDEBUG
Definition Messenger.h:63
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
Definition Messenger.h:96
#define pWARN
Definition Messenger.h:60
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils.
Concrete implementations of the InteractionListGeneratorI interface. Generate a list of all the Inter...
InteractionList * CreateHEDISlist(vector< InitialState > vinit, vector< InteractionType_t > vinttype) const
void CreateNucSF(const Interaction *in, string sfFile)
SF_xQ2 EvalNucSFLO(const Interaction *in, double x, double Q2)
enum genie::HEDISStrucFunc::StrucFuncType HEDISStrucFuncType_t
int NucSFCode(const Interaction *in)
SF_xQ2 EvalQrkSFLO(const Interaction *in, double x, double Q2)
string QrkSFName(const Interaction *in)
SF_xQ2 EvalNucSFNLO(const Interaction *in, double x, double Q2)
vector< double > sf_q2_array
map< int, HEDISStrucFuncTable > fQrkSFLOTables
string NucSFName(const Interaction *in)
static HEDISStrucFunc * Instance(SF_info sfinfo)
static HEDISStrucFunc * fgInstance
vector< double > sf_x_array
void CreateQrkSF(const Interaction *in, string sfFile)
map< int, HEDISStrucFuncTable > fNucSFLOTables
int QrkSFCode(const Interaction *in)
HEDISStrucFunc(SF_info sfinfo)
map< int, HEDISStrucFuncTable > fNucSFNLOTables
Initial State information.
const Target & Tgt(void) const
int ProbePdg(void) const
A vector of Interaction objects.
Summary information for an interaction.
Definition Interaction.h:56
const XclsTag & ExclTag(void) const
Definition Interaction.h:72
const ProcessInfo & ProcInfo(void) const
Definition Interaction.h:70
const InitialState & InitState(void) const
Definition Interaction.h:69
bool IsWeakCC(void) const
TuneId * Tune(void) const
Definition RunOpt.h:46
static RunOpt * Instance(void)
Definition RunOpt.cxx:54
int HitNucPdg(void) const
Definition Target.cxx:304
int HitQrkPdg(void) const
Definition Target.cxx:242
bool HitSeaQrk(void) const
Definition Target.cxx:299
double HitNucMass(void) const
Definition Target.cxx:233
string Name(void) const
Definition TuneId.h:46
int FinalQuarkPdg(void) const
Definition XclsTag.h:72
const double e
Basic constants.
bool IsNeutrino(int pdgc)
Definition PDGUtils.cxx:110
bool IsProton(int pdgc)
Definition PDGUtils.cxx:336
THE MAIN GENIE PROJECT NAMESPACE
Definition AlgCmp.h:25
const int kPdgAntiNuE
Definition PDGCodes.h:29
const int kPdgNuE
Definition PDGCodes.h:28