1 !****************************************************************************
5 ! An interface for the scale dependent nuclear modifications
6 ! R_f^A(x,Q) = f_A(x,Q)/f_p(x,Q)
7 ! where f_A is the distribution of the parton flavour f for a PROTON in a
8 ! nucleus A, and f_p is the corresponding parton distribution in the
11 ! When using this interface, please refer to:
13 ! K.J. Eskola, H. Paukkunen and C.A. Salgado,
14 ! "EPS09 - a New Generation of NLO and LO Nuclear Parton Distribution Functions,"
15 ! Published as JHEP04(2009) 065.
16 ! Eprint: arXiv:0902.4154 [hep-ph].
18 ! Questions & comments to:
19 ! hannu.paukkunen@phys.jyu.fi
20 ! kari.eskola@phys.jyu.fi
21 ! carlos.salgado@usc.es
23 ! ***************************************************************************
26 ! For given input values of
28 ! order: 1=LO, 2=NLO ; integer
29 ! pset : 1...31 ; integer
31 ! 2,3 = error sets S{+1}, S{-1}
32 ! 4,5 = error sets S{+2}, S{-2}
34 ! 30,31 = error sets {S+15}, {S-15}
35 ! A : atomic number ; integer
36 ! x : Bjorken-x ; double precision
37 ! Q : scale in GeV ; double precision
41 ! Call EPS09(order, pset, A, x, Q, ruv, rdv, ru, rd, rs, rc, rb, rg)
43 ! returns the bound proton nuclear corrections R_f^A(x,Q)
44 ! (in double precision) for
55 ! The nuclear corrections for bound neutrons can be obtained
56 ! by the isospin symmetry, e.g. the total up quark distribution
57 ! per nucleon in a nucleus A with Z protons is
59 ! u_A(x,Q) = Z/A * [ruv*uV_p(x,Q) + ru*uSea_p(x,Q)] +
60 ! (A-Z)/A * [rdv*dV_p(x,Q) + rd*dSea_p(x,Q)]
62 ! Note that the parametrization should only be applied at the
66 ! 1.3 <= Q <= 1000 GeV.
68 ! No warning message is displayed if these limits are
69 ! exceeded, and outside these boundaries the modifications
70 ! are frozen to the boundary values, i.e
72 ! for Q > 1000, the modifications at Q=1000 are returned,
73 ! for Q < 1.3, the modifications at Q=1.3 are returned,
74 ! for x > 1, the modifications at x=1 are returned
75 ! for x < 1e-6, the modifications at x=1e-6 are returned,
77 ! The data used by the program for required order
78 ! and atomic number A, are stored in separate files
83 ! which must be located in the working directory.
85 ! The error bands for absolute cross-sections and for
86 ! their nuclear ratios should be computed as explained
87 ! in Secs. 2.5 and 4 of arXiv:0902.4154 [hep-ph]. For
88 ! the absolute cross sections, both the errors in the
89 ! free-proton PDFs f_p(x,Q) and the errors in
90 ! the modifications R_f^A(x,Q) should be accounted for.
91 ! For the nuclear ratios, it is sufficient to account only
92 ! for the errors in the modifications R_f^A(x,Q).
94 ! *********************************************************
95 ! *********************************************************
99 Subroutine EPS09(order, pset, AAA, xxx, QQQ,ruv, rdv, ru, rd, rs, rc, rb, rg)
102 Double precision :: ruv, rdv, ru, rd, rs, rc, rb, rg, QQQ, xxx
103 Double precision :: LSTEP, x, Q, Q2, allvalues(1:31,1:8,0:50,0:50)
104 Double precision :: x_i=0.000001, arg(4), fu(4), res, fg(3)
105 Double precision :: result(9), dummy
106 Double precision :: realQ, Q2min=1.69, Q2max=1000000.0, Qsteps=50.0
107 Double precision :: n_x, zero=0.0
109 Character (Len=50) filenimi
111 Integer :: xlinsteps=25, xlogsteps=25, startline, lineno
112 Integer :: k, p, t, Qpoint, xpoint, pset, iovar
113 Integer :: setnumber,j, A, openchannel, order, AAA
114 Integer :: psetlast = -10, Alast = -10, orderlast = -10
116 character*512 dirpath,setpath
123 ! *********************************************
124 ! Stop if the set specifications are wrong ones
125 ! *********************************************
127 If (order .NE. 1 .and. order .NE. 2) then
128 Write(*,*) 'Wrong order!'
129 Write(*,*) 'LO : order = 1'
130 Write(*,*) 'NLO: order = 2'
134 If (pset .LT. 1 .or. pset .GT. 31) then
135 Write(*,*) 'Wrong set!'
136 Write(*,*) 'Central set: pset = 1'
137 Write(*,*) 'Error sets : pset = 2...31'
141 ! ********************************
142 ! Make sure not to change any
143 ! specifications given by the user
144 ! ********************************
151 ! *******************************
152 ! Freeze x if it's < 10E-6 or > 1
153 ! *******************************
162 ! ************************************
163 ! Freeze Q^2 if it's < 1.69 or > 10E+6
164 ! ************************************
166 If (Q2 .LT. Q2min) Then
169 If (Q2 .GT. Q2max) Then
173 ! If the set specifications have been changed, read the tables again
175 If (A .NE. Alast .or. order .NE. orderlast) Then
177 ! Write(*,*) 'Set changed!'
181 If (order .EQ. 1) then
184 Write(filenimi,'("EPS09LOR_", I1)'), A
185 Else If (A < 100) Then
186 Write(filenimi,'("EPS09LOR_", I2)'), A
187 Else If (A < 1000) Then
188 Write(filenimi,'("EPS09LOR_", I3)'), A
194 Write(filenimi,'("EPS09NLOR_", I1)'), A
195 Else If (A < 100) Then
196 Write(filenimi,'("EPS09NLOR_", I2)'), A
197 Else If (A < 1000) Then
198 Write(filenimi,'("EPS09NLOR_", I3)'), A
203 call getdirpath(dirpath)
204 setpath=dirpath(:LEN_TRIM(dirpath))//"/"//filenimi(:LEN_TRIM(filenimi))//".LHgrid"
205 print *,setpath(:LEN_TRIM(setpath))
206 OPEN (11, file = setpath(:LEN_TRIM(setpath)), status='OLD', IOSTAT=iovar)
208 If (iovar .NE. 0) Then
209 Write(*,*) 'Missing file: ',filenimi
221 Read(11,*) (allvalues(setnumber,p,k,t), p=1,8)
236 ! Find out the position in the loglog Q^2-grid
238 realQ = Qsteps * (log(log(Q2)/log(Q2min)))/(log(log(Q2max)/log(Q2min)))
241 If (Qpoint .LE. 0) Then
244 If (Qpoint .GE. Anint(Qsteps)-1) Then
245 Qpoint = Anint(Qsteps)-1
248 LSTEP = (1.0/(xlogsteps)) * LOG(0.1/x_i)
250 ! *********************
251 ! Interpolate the grids
252 ! *********************
256 ! Find the position in the x-grid
259 n_x = ((1.0/LSTEP) * Log(x/x_i))
262 n_x = ((x-0.1)*xlinsteps/(1.0-0.1) + xlogsteps)
266 If (xpoint .LE. 0) Then
270 If (t .EQ. 1 .or. t .EQ. 2) Then
271 If (xpoint .GE. (xlinsteps+xlogsteps)-4) Then
272 xpoint = (xlinsteps+xlogsteps)-4
276 If (t .EQ. 3 .or. t .EQ. 4 .or. t .EQ. 5 .or. t .EQ. 6 .or. t .EQ. 7) Then
277 If (xpoint .GE. (xlinsteps+xlogsteps)-7) Then
278 xpoint = (xlinsteps+xlogsteps)-7
283 If (xpoint .GE. (xlinsteps+xlogsteps)-4) Then
284 xpoint = (xlinsteps+xlogsteps)-4
289 If (xpoint-2+k .LT. xlogsteps) Then
290 arg(k) = (x_i) * exp(LSTEP * (xpoint-2+k))
292 arg(k) = 0.1 + (xpoint-2+k-xlogsteps) * (1-0.1)/xlinsteps
298 fu(1) = allvalues(pset,t,Qpoint-2+j,xpoint-1)
299 fu(2) = allvalues(pset,t,Qpoint-2+j,xpoint)
300 fu(3) = allvalues(pset,t,Qpoint-2+j,xpoint+1)
301 fu(4) = allvalues(pset,t,Qpoint-2+j,xpoint+2)
302 Call luovi(fu,arg,4,x,res)
305 ! *****************************************
306 ! *****************************************
314 Call luovi(fg,arg,3,realQ,res)
320 ruv = max(result(1),zero)
321 rdv = max(result(2),zero)
322 ru = max(result(3),zero)
323 rd = max(result(4),zero)
324 rs = max(result(5),zero)
325 rc = max(result(6),zero)
326 rb = max(result(7),zero)
327 rg = max(result(8),zero)
333 ! ********************************
334 ! Modified version of Cern Library
335 ! interpolation routine E100
336 ! ********************************
338 SUBROUTINE luovi(F,ARG,MMM,Z,SUM)
342 Double precision :: F(MMM), ARG(MMM), COF(MMM), SUM, Z
343 INTEGER :: M, MM, I, J, JNDEX, INDEX
354 COF(INDEX) = (COF(INDEX)-COF(INDEX-1))/(ARG(INDEX)-ARG(JNDEX))
360 SUM = (Z-ARG(INDEX))*SUM + COF(INDEX)