tparton 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
tparton-0.1.1/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ Copyright 2024 Congzhou M Sha (cms6712@psu.edu)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ Usage of these programs should cite the publication or preprint associated with this work.
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
tparton-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.3
2
+ Name: tparton
3
+ Version: 0.1.1
4
+ Summary: Evolution of the transversity parton distribution functions via two methods: (1) direct integration of the DGLAP equations along the energy scale and (2) fast Mellin inversion.
5
+ Author-email: Congzhou M Sha <cms6712@psu.edu>
6
+ License-File: LICENSE
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Programming Language :: Python :: 3
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+
13
+ # tParton
14
+
15
+ This is an evolution code for the transversity parton distribution functions encountered in hadronic physics.
@@ -0,0 +1,3 @@
1
+ # tParton
2
+
3
+ This is an evolution code for the transversity parton distribution functions encountered in hadronic physics.
@@ -0,0 +1,18 @@
1
+ [project]
2
+ name = "tparton"
3
+ version = "0.1.1"
4
+ authors = [
5
+ { name = "Congzhou M Sha", email="cms6712@psu.edu" }
6
+ ]
7
+ description = "Evolution of the transversity parton distribution functions via two methods: (1) direct integration of the DGLAP equations along the energy scale and (2) fast Mellin inversion."
8
+ readme = "README.md"
9
+ requires-python = ">=3.8"
10
+ classifiers = [
11
+ "Programming Language :: Python :: 3",
12
+ "License :: OSI Approved :: MIT License",
13
+ "Operating System :: OS Independent",
14
+ ]
15
+ [build-system]
16
+ requires = ["hatchling", "numpy>=2.0", "scipy>=1.13"]
17
+ build-backend = "hatchling.build"
18
+
@@ -0,0 +1,2 @@
1
+ from .t_evolution import evolve as t_evolve
2
+ from .m_evolution import evolve as m_evolve
@@ -0,0 +1,13 @@
1
+ import sys
2
+ method = 'm'
3
+ if len(sys.argv) == 2:
4
+ method = sys.argv[1]
5
+
6
+ if method == 'm':
7
+ print("Vogelsang's moment method")
8
+ from .m_evolution import main
9
+ main()
10
+ else:
11
+ print("Hirai's energy scale method")
12
+ from .t_evolution import main
13
+ main()
@@ -0,0 +1,235 @@
1
+ # Copyright Congzhou M Sha 2024
2
+ import mpmath as mp
3
+ import numpy as np
4
+ from scipy.interpolate import interp1d as interp
5
+ from mpmath import invertlaplace, mpc, pi, zeta, psi, euler as euler_gamma
6
+
7
+ mp.dp = 16
8
+ zeta2 = zeta(2)
9
+ zeta3 = zeta(3)
10
+
11
+ def constants(CG, Nf):
12
+ NC = CG
13
+ CF = (NC * NC - 1) / NC / 2
14
+ TR = 1/2
15
+ Tf= TR * Nf
16
+ beta0 = 11 / 3 * CG - 4 / 3 * TR * Nf
17
+ beta1 = 34 / 3 * CG ** 2 - 10 / 3 * CG * Nf - 2 * CF * Nf
18
+ return NC, CF, TR, Tf, beta0, beta1
19
+
20
+ psi0 = lambda s: psi(0,s)
21
+ psi_p = lambda s: psi(1,s)
22
+ psi_pp = lambda s: psi(2,s)
23
+
24
+ # Special functions which analytically continue the zeta function
25
+ S_1 = lambda n: euler_gamma + psi0(n+1)
26
+ S_2 = lambda n: zeta2 - psi_p(n+1)
27
+ S_3 = lambda n: zeta3 + 0.5 * psi_pp(n+1)
28
+
29
+ etaN = lambda n, eta: 1 if eta == 1 else mp.power(eta, n)
30
+
31
+ def S_p1(n, f):
32
+ return 0.5 * (
33
+ (1 + f) * S_1(n/2) + (1 - f) * S_1((n-1)/2))
34
+
35
+ def S_p2(n, f):
36
+ return 0.5 * (
37
+ (1 + f) * S_2(n/2) + (1 - f) * S_2((n-1)/2))
38
+
39
+ def S_p3(n, f):
40
+ return 0.5 * (
41
+ (1 + f) * S_3(n/2) + (1 - f) * S_3((n-1)/2))
42
+
43
+ G = lambda n: psi0((n+1)/2) - psi0(n/2)
44
+
45
+ def Stilde(n, f):
46
+ temp = -5/8 * zeta3
47
+ term = f
48
+ term *= S_1(n) / n / n - zeta2/2 * G(n) + \
49
+ mp.quad(lambda t: mp.power(t, n-1) * mp.polylog(2, t) / (1 + t), [0, 1])
50
+ return temp + term
51
+
52
+ def mellin(f, s):
53
+ return mp.quad(lambda t: mp.power(t, s-1) * f(t), [0, 1])
54
+
55
+ def inv_mellin(f, x):
56
+ res = invertlaplace(f, -mp.log(x), method='cohen', degree=3)
57
+ print(x, x*res)
58
+ return res
59
+
60
+ def evolve(
61
+ pdf,
62
+ Q0_2=0.16,
63
+ Q2=5.0,
64
+ l_QCD=0.25,
65
+ Nf=5,
66
+ CG=3,
67
+ morp='minus',
68
+ order=2,
69
+ n_x=200,
70
+ splittingMoments=False
71
+ ):
72
+ '''
73
+ Evolve the transversity PDF
74
+ ***************************
75
+ Parameters:
76
+ pdf: 1D or 2D array-like
77
+ the input first moment. If 1D, assumed to be at x
78
+ evenly distributed on [0, 1] inclusive.
79
+
80
+ Q0_2: float
81
+ initial Q^2
82
+
83
+ Q2: float
84
+ final evolved Q^2
85
+
86
+ l_QCD: float
87
+ QCD energy scale
88
+
89
+ n_f: int
90
+ number of flavors
91
+
92
+ n_t: int
93
+ number of time steps
94
+
95
+ n_z: int
96
+ the number of z steps to take in integral
97
+
98
+ morp: 'plus' or 'minus'
99
+ type of pdf (plus or minus type)
100
+
101
+ order: int
102
+ 1: first-order
103
+ 2: second-order
104
+
105
+ splittingMoments: bool
106
+ True: return splitting function moments
107
+ False: do not return splitting function moments
108
+ '''
109
+
110
+ # Calculate the color constants
111
+ if pdf.shape[-1] == 1:
112
+ xs = np.linspace(0, 1, len(pdf))
113
+ else:
114
+ xs, pdf = pdf[:, 0], pdf[:, 1]
115
+ pdf = pdf / (xs + 1e-100)
116
+ pdf[0] = 0
117
+ pdf[1] = 0
118
+ pdf_fun = interp(xs, pdf, fill_value=0, assume_sorted=True)
119
+ pdf = lambda x: mp.mpf(pdf_fun(float(x)).item())
120
+
121
+ eta = 1 if morp == 'plus' else -1
122
+
123
+ NC, CF, TR, Tf, beta0, beta1 = constants(CG, Nf)
124
+
125
+ # Corresponds to MDTP_qq_LO
126
+ LO_splitting_function_moment = lambda n: CF * (1.5 - 2 * S_1(n))
127
+ # Corresponds to MDTP_qq_NLO
128
+ def NLO_splitting_function_moment(n):
129
+ f = etaN(n, eta)
130
+ return \
131
+ CF * CF * (
132
+ 3 / 8
133
+ + (1-eta) / (n * (n + 1))
134
+ - 3 * S_2(n)
135
+ - 4 * S_1(n) * (S_2(n) - S_p2(n, f))
136
+ - 8 * Stilde(n, f)
137
+ + S_p3(n, f)
138
+ ) + \
139
+ 0.5 * CF * NC * (
140
+ 17 / 12
141
+ - (1 - eta) / (n * (n + 1))
142
+ - 134 / 9 * S_1(n)
143
+ + 22 / 3 * S_2(n)
144
+ + 4 * S_1(n) * (2 * S_2(n) - S_p2(n, f))
145
+ + 8 * Stilde(n, f)
146
+ - S_p3(n, f)
147
+ ) + \
148
+ 2 / 3 * CF * Tf * (
149
+ -1 / 4
150
+ + 10 / 3 * S_1(n)
151
+ - 2 * S_2(n)
152
+ )
153
+
154
+ def alpha_S(Q2):
155
+ ln_Q2_L_QCD = mp.log(Q2) - 2 * mp.log(l_QCD)
156
+ ln_ln_Q2_L_QCD = mp.log(ln_Q2_L_QCD)
157
+
158
+ alpha_S = 4 * pi / beta0 / ln_Q2_L_QCD
159
+ if order == 2:
160
+ alpha_S -= 4 * pi * beta1 / mp.power(beta0, 3) * ln_ln_Q2_L_QCD / ln_Q2_L_QCD / ln_Q2_L_QCD
161
+ return alpha_S
162
+
163
+ def evolveMoment(n, pdf_m):
164
+ total = 1
165
+ total += (alpha_S(Q0_2) - alpha_S(Q2)) / pi / beta0 * (NLO_splitting_function_moment(n) - beta1 / 2 / beta0 * LO_splitting_function_moment(n))
166
+ total *= mp.power(alpha_S(Q2) / alpha_S(Q0_2), -2 / beta0 * LO_splitting_function_moment(n)) * pdf_m
167
+ return total
168
+
169
+ if n_x > 0:
170
+ xs = np.linspace(0, 1, n_x+2)
171
+ xs = xs[1:-1]
172
+
173
+ # Perform Mellin transform
174
+ pdf_m = lambda s: mellin(pdf, s)
175
+ # Evolve moments
176
+ pdf_evolved_m = lambda s: mpc(evolveMoment(s, pdf_m(s)))
177
+ # Invert Mellin transform
178
+ pdf_evolved = np.array([inv_mellin(pdf_evolved_m, x).__complex__().real for x in xs])
179
+ pdf_evolved[0] = 0
180
+ pdf_evolved[-1] = 0
181
+ xs = np.pad(xs, 1)
182
+ xs[-1] = 1
183
+ pdf_evolved = np.pad(pdf_evolved, 1)
184
+ pdf_evolved = np.stack((xs, np.array(xs) * np.array(pdf_evolved)))
185
+ print('Done!')
186
+ return pdf_evolved
187
+
188
+ def main():
189
+ import argparse, sys
190
+ parser = argparse.ArgumentParser(description='Evolution of the nonsinglet transversity PDF, using Vogelsang\'s moment method.')
191
+ parser.add_argument('input', action='store', type=str,
192
+ help='The CSV file containing (x,x*PDF(x)) pairs on each line. If only a single number on each line, we assume a linear spacing for x between 0 and 1 inclusive')
193
+ parser.add_argument('Q0sq', action='store', type=float, help='The starting energy scale in units of GeV^2')
194
+ parser.add_argument('Qsq', action='store', type=float, help='The ending energy scale in units of GeV^2')
195
+ parser.add_argument('--morp', nargs='?', action='store', type=str, default='plus', help='The plus vs minus type PDF (default is \'plus\')')
196
+ parser.add_argument('-o', action='store', nargs='?', type=str, default='out.dat', help='Output file for the PDF, stored as (x,x*PDF(x)) pairs.')
197
+ parser.add_argument('-l', metavar='l_QCD', nargs='?', action='store', type=float, default=0.25, help='The QCD scale parameter (default 0.25 GeV^2)')
198
+ parser.add_argument('--nf', metavar='n_f', nargs='?', action='store', type=int, default=5, help='The number of flavors (default 5)')
199
+ parser.add_argument('--nc', metavar='n_c', nargs='?', action='store', type=int, default=3, help='The number of colors (default 3)')
200
+ parser.add_argument('--order', metavar='order', nargs='?', action='store', type=int, default=2, help='1: leading order, 2: NLO DGLAP (default 2)')
201
+ parser.add_argument('--nx', metavar='n_x', nargs='?', action='store', type=int, default=-1, help='The number of x values to sample the evolved PDF (default -1). If left at -1, will sample at input xs.')
202
+ parser.add_argument('--delim', nargs='?', action='store', type=str, default=' ', help='Delimiter for the output (default \' \'). If given without an argument, then the delimiter is whitespace (i.e. Mathematica output.)')
203
+
204
+
205
+ args = parser.parse_args()
206
+ f = args.input
207
+ if args.delim is None:
208
+ pdf = np.genfromtxt(f)
209
+ args.delim = ' '
210
+ else:
211
+ pdf = np.genfromtxt(f, delimiter=args.delim)
212
+ Q0sq = args.Q0sq
213
+ Qsq = args.Qsq
214
+ morp = args.morp
215
+ l = args.l
216
+ nf = args.nf
217
+ nc = args.nc
218
+ order = args.order
219
+ nx = args.nx
220
+
221
+ res = evolve(pdf,
222
+ Q0_2=Q0sq,
223
+ Q2=Qsq,
224
+ l_QCD=l,
225
+ Nf=nf,
226
+ CG=nc,
227
+ morp=morp,
228
+ order=order,
229
+ n_x=nx
230
+ )
231
+
232
+ np.savetxt(args.o, res.T, delimiter=args.delim)
233
+
234
+ if __name__ == '__main__':
235
+ main()
@@ -0,0 +1,231 @@
1
+ # Copyright Congzhou M Sha 2024
2
+ import numpy as np
3
+ from scipy.integrate import simpson
4
+ from numpy.core.multiarray import interp
5
+ from scipy.special import spence
6
+
7
+ def evolve(
8
+ pdf,
9
+ Q0_2=0.16,
10
+ Q2=5.0,
11
+ l_QCD=0.25,
12
+ n_f=3,
13
+ n_t=100,
14
+ n_z=500,
15
+ morp='plus',
16
+ order=2,
17
+ logScale=False
18
+ ):
19
+ '''
20
+ Evolve the transversity PDF
21
+ ***************************
22
+ Parameters:
23
+ pdf: array-like
24
+ the input first moment (assumed to be at x
25
+ evenly distributed on [0, 1] inclusive)
26
+
27
+ Q0_2: float
28
+ initial Q^2
29
+
30
+ Q2: float
31
+ final evolved Q^2
32
+
33
+ l_QCD: float
34
+ QCD energy scale
35
+
36
+ n_f: int
37
+ number of flavors
38
+
39
+ n_t: int
40
+ number of time steps
41
+
42
+ n_z: int
43
+ the number of z steps to take in integral
44
+
45
+ morp: 'plus' or 'minus'
46
+ type of pdf (plus or minus type)
47
+
48
+ order: int
49
+ 1: first-order
50
+ 2: second-order
51
+
52
+ logScale: bool
53
+ z is log scaled if True
54
+ '''
55
+ # Calculate the color constants
56
+ if pdf.shape[-1] == 1:
57
+ xs = np.linspace(0, 1, len(pdf))
58
+ else:
59
+ xs, pdf = pdf[:, 0], pdf[:, 1]
60
+ sign = 1 if morp == 'plus' else -1
61
+ lnlam = 2 * np.log(l_QCD)
62
+
63
+ pi = np.pi
64
+ CF = 4 / 3
65
+ CG = 3
66
+ TR = 1/2
67
+ beta0 = 11 / 3 * CG - 4 / 3 * TR * n_f
68
+ beta1 = 34 / 3 * CG ** 2 - 10 / 3 * CG * n_f - 2 * CF * n_f
69
+
70
+ def alp2pi(t):
71
+ dlnq2 = t - lnlam
72
+ alpha = 4 * pi / beta0 / dlnq2
73
+ alpha_factor = 1 if order == 1 else (1 - beta1 * np.log(dlnq2) / beta0**2 / dlnq2)
74
+ alpha_factor /= (2 * pi)
75
+ return alpha_factor * alpha
76
+
77
+ def splitting(z):
78
+ # Calculate the splitting functions
79
+ p0 = CF * 2 * z / (1 - z+1e-100)
80
+ p0pf = -CF * 2 / (1 - z+1e-100)
81
+
82
+ z1 = 1 / (1 + z)
83
+ z2 = z / (1 + z)
84
+ dln1 = np.log(z1)
85
+ dln2 = np.log(z2)
86
+ # SciPy convention for Spence (aka dilogarithm) differs from paper
87
+ s2 = -spence(z2) + spence(z1) - (dln1 ** 2 - dln2 ** 2) * 0.5
88
+
89
+ if order == 2:
90
+ omz = 1 - z
91
+ lnz = np.log(z)
92
+ lno = np.log(omz+1e-100)
93
+ dP0 = 2 * z / (omz+1e-100)
94
+ pp1 = 1 - z - (3 / 2 + 2 * lno) * lnz * dP0
95
+ pp2 = -omz + (67/9 + 11/3 * lnz + lnz**2 - pi**2 / 3) * dP0
96
+ pp3 = (-lnz - 5/3) * dP0
97
+ pp4 = -omz + 2 * s2 * 2 * -z / (1 + z)
98
+
99
+ # Eq. 43 in Vogelsang
100
+ dpqq = CF * CF * pp1 + CF * CG * 0.5 * pp2 + 2 / 3 * CF * TR * n_f * pp3
101
+
102
+ # Eq. 44 in Vogelsang
103
+ dpqqb = CF * (CF-CG / 2) * pp4
104
+ p1 = dpqq + sign * dpqqb
105
+ p1[0] = 0
106
+ else:
107
+ p1 = 0
108
+ omz = 1 - z
109
+
110
+ # The plus function contributions upon integration for the entire range of z in [x, 1]
111
+ # f(1) in Eq. A.8
112
+ # These terms correspond to -f(1)/(1-z) in Eq. A.8
113
+ p2plus = -(67/9-pi**2/3) * 2 / (omz+1e-100)
114
+ p3plus = 5 / 3 * 2 / (omz+1e-100)
115
+ p1pf = CF * CG / 2 * p2plus + 2 / 3 * CF * TR * n_f * p3plus
116
+
117
+ p0[-1] = 0
118
+ p0pf[-1] = 0
119
+ if order == 2:
120
+ p1[-1] = 0
121
+ p1pf[-1] = 0
122
+
123
+ # The zero order plus and delta function contributions to the integrals
124
+ plus0 = CF * 2
125
+ del0 = CF * 3/2
126
+
127
+ if order == 2:
128
+ zta = 1.2020569031595943
129
+ # The delta function contributions for the entire range of z in [x, 1]
130
+ del1 = CF * CF * (3 / 8 - pi**2 / 2 + 6 * zta) + \
131
+ CF * CG / 2 * (17 / 12 + 11 * pi**2 /9 - 6 * zta) - \
132
+ 2 / 3 * CF * TR * n_f * (1 / 4 + pi**2 / 3)
133
+ # p2pl, p3pl correspond to the f(1) in Eq. A.8
134
+ p2pl = (67 / 9 - pi**2/3) * 2
135
+ p3pl = -5 / 3 * 2
136
+ plus1 = CF * CG / 2 * p2pl + 2 / 3 * CF * TR * n_f * p3pl
137
+ else:
138
+ plus1 = 0
139
+ del1 = 0
140
+ return p0, p1, p0pf, p1pf, plus0, del0, plus1, del1
141
+
142
+ tmin = np.log(Q0_2)
143
+ tmax = np.log(Q2)
144
+ ts = np.linspace(tmin, tmax, n_t)
145
+
146
+ def integrate(pdf, i, z, alp):
147
+ p0, p1, p0pf, p1pf, plus0, del0, plus1, del1 = splitting(z)
148
+ p0[-1] = p0pf[-1] = 0
149
+ if order == 2:
150
+ p1[-1] = p1pf[-1] = 0
151
+
152
+ # Implement Eq. A.5 in Hirai
153
+ # The interp function interpolates pdf(x / z)
154
+ # In the FORTRAN code, the first part of this equation is not divided by z
155
+ func = ((p0 + (alp * p1 if order == 2 else 0)) * interp(xs[i] / z, xs, pdf)) + \
156
+ (p0pf + (alp * p1pf if order == 2 else 0)) * pdf[i]
157
+
158
+ lno = np.log(1 - xs[i])
159
+ estimate = simpson(func, x=z) + (plus0 * lno + del0) * pdf[i]
160
+ if order == 2:
161
+ estimate += alp * (plus1 * lno + del1) * pdf[i]
162
+
163
+ return estimate
164
+
165
+ dt = (tmax - tmin) / n_t
166
+ res = np.copy(pdf)
167
+ for i, t in enumerate(ts):
168
+ print(i+1, ' of ', len(ts), 'time steps')
169
+ alp = alp2pi(t)
170
+ inc = np.array([integrate(res, index, \
171
+ np.power(10, np.linspace(np.log10(xs[index]), 0, n_z + 1 - index)) if logScale else np.linspace(xs[index], 1, n_z + 1 - index), \
172
+ alp) for index in range(1, len(xs)-1)])
173
+ inc = np.pad(inc, 1)
174
+ res += dt * inc * alp
175
+ return np.stack((xs, res))
176
+
177
+
178
+ def main():
179
+ import argparse, sys
180
+ parser = argparse.ArgumentParser(description='Evolution of the nonsinglet transversity PDF, according to the DGLAP equation.')
181
+ parser.add_argument('input', action='store', type=str,
182
+ help='The CSV file containing (x,x*PDF(x)) pairs on each line. If only a single number on each line, we assume a linear spacing for x between 0 and 1 inclusive')
183
+ parser.add_argument('Q0sq', action='store', type=float, help='The starting energy scale in units of GeV^2')
184
+ parser.add_argument('Qsq', action='store', type=float, help='The ending energy scale in units of GeV^2')
185
+ parser.add_argument('--morp', action='store', nargs='?', type=str, default='plus', help='The plus vs minus type PDF (default \'plus\')')
186
+ parser.add_argument('-o', action='store', nargs='?', type=str, default='out.dat', help='Output file for the PDF, stored as (x,x*PDF(x)) pairs.')
187
+ parser.add_argument('-l', metavar='l_QCD', nargs='?', action='store', type=float, default=0.25, help='The QCD scale parameter (default 0.25 GeV^2)')
188
+ parser.add_argument('--nf', metavar='n_f', nargs='?', action='store', type=int, default=5, help='The number of flavors (default 5)')
189
+ parser.add_argument('--nc', metavar='n_c', nargs='?', action='store', type=int, default=3, help='The number of colors (default 3)')
190
+ parser.add_argument('--order', metavar='order', nargs='?', action='store', type=int, default=2, help='1: leading order, 2: NLO DGLAP (default 2)')
191
+ parser.add_argument('--nt', metavar='n_t', nargs='?', action='store', type=int, default=100, help='Number of steps to numerically integrate the DGLAP equations (default 100)')
192
+ parser.add_argument('--nz', metavar='n_z', nargs='?', action='store', type=int, default=1000, help='Number of steps for numerical integration (default 1000)')
193
+ parser.add_argument('--logScale', nargs='?', action='store', type=bool, default=True, help='True if integration should be done on a log scale (default True)')
194
+ parser.add_argument('--delim', nargs='?', action='store', type=str, default=' ', help='Delimiter for data file (default \' \'). If given without an argument, then the delimiter is whitespace (i.e. Mathematica output.)')
195
+
196
+
197
+ args = parser.parse_args()
198
+ args.delim = ' ' if args.delim is None else args.delim
199
+ f = args.input
200
+ if args.delim is None:
201
+ pdf = np.genfromtxt(f)
202
+ args.delim = ' '
203
+ else:
204
+ pdf = np.genfromtxt(f, delimiter=args.delim)
205
+ Q0sq = args.Q0sq
206
+ Qsq = args.Qsq
207
+ morp = args.morp
208
+ l = args.l
209
+ nf = args.nf
210
+ nc = args.nc
211
+ order = args.order
212
+ nt = args.nt
213
+ nz = args.nz
214
+ logScale = args.logScale
215
+
216
+ res = evolve(pdf,
217
+ Q0_2=Q0sq,
218
+ Q2=Qsq,
219
+ l_QCD=l,
220
+ n_f=nf,
221
+ n_t=nt,
222
+ n_z=nz,
223
+ morp=morp,
224
+ order=order,
225
+ logScale=logScale
226
+ )
227
+
228
+ np.savetxt(args.o, res.T, delimiter=args.delim)
229
+
230
+ if __name__ == '__main__':
231
+ main()