1
|
|
|
# -*- coding: utf-8 -*- |
2
|
|
|
# vim:fileencoding=utf-8 |
3
|
|
|
# |
4
|
|
|
# Copyright (c) 2017-2018 Stefan Bender |
5
|
|
|
# |
6
|
|
|
# This module is part of sciapy. |
7
|
|
|
# sciapy is free software: you can redistribute it or modify |
8
|
|
|
# it under the terms of the GNU General Public License as published |
9
|
|
|
# by the Free Software Foundation, version 2. |
10
|
|
|
# See accompanying LICENSE file or http://www.gnu.org/licenses/gpl-2.0.html. |
11
|
1 |
|
"""SCIAMACHY regression tool command line options |
12
|
|
|
|
13
|
|
|
Command line options for the command line tool. |
14
|
|
|
""" |
15
|
|
|
|
16
|
1 |
|
import argparse |
17
|
1 |
|
from distutils.util import strtobool |
18
|
|
|
|
19
|
1 |
|
from ._gpkernels import george_kernels, celerite_terms |
20
|
|
|
|
21
|
1 |
|
__all__ = ["parser"] |
22
|
|
|
|
23
|
|
|
|
24
|
1 |
View Code Duplication |
class Range(object): |
|
|
|
|
25
|
|
|
"""Ranges for floats in command line arguments |
26
|
|
|
|
27
|
|
|
Helps to properly notify the user if the command line argument |
28
|
|
|
is out of range[1]. |
29
|
|
|
|
30
|
|
|
[1](https://stackoverflow.com/questions/12116685/) |
31
|
|
|
""" |
32
|
1 |
|
def __init__(self, start, end): |
33
|
1 |
|
self.start = start |
34
|
1 |
|
self.end = end |
35
|
|
|
|
36
|
1 |
|
def __eq__(self, other): |
37
|
|
|
return self.start <= other <= self.end |
38
|
|
|
|
39
|
1 |
|
def __getitem__(self, index): |
40
|
1 |
|
if index == 0: |
41
|
1 |
|
return self |
42
|
|
|
else: |
43
|
1 |
|
raise IndexError() |
44
|
|
|
|
45
|
1 |
|
def __repr__(self): |
46
|
1 |
|
return '{0}--{1}'.format(self.start, self.end) |
47
|
|
|
|
48
|
|
|
|
49
|
1 |
|
parser = argparse.ArgumentParser(description="SCIAMACHY data regression", |
50
|
|
|
prog="scia_regress") |
51
|
1 |
|
parser.add_argument("file", default="SCIA_NO.nc", |
52
|
|
|
help="The filename of the input netcdf file") |
53
|
1 |
|
parser.add_argument("-m", "--name_suffix", default="", |
54
|
|
|
help="The suffix for the figure plot files (default: \"\")") |
55
|
1 |
|
parser.add_argument("--proxies", metavar="NAME1:FILE1,NAME2:FILE2,...", |
56
|
|
|
default="Sol:~/Work/data/indices/lisird_lya3_1947-2017.dat," |
57
|
|
|
"GM:~/Work/data/indices/AE/AE_Kyoto_1980-2016_daily2_shift12h.dat", |
58
|
|
|
help="Comma separated list of (solar and geomagnetic or other) " |
59
|
|
|
"proxies as 'name:file' (default: %(default)s)") |
60
|
1 |
|
parser.add_argument("-T", "--fit_lags", default="", type=str, |
61
|
|
|
help="Fit the proxy lag time " |
62
|
|
|
"(comma separated proxy names, e.g. Sol,GM) " |
63
|
|
|
"(default: %(default)s)") |
64
|
1 |
|
parser.add_argument("-I", "--fit_lifetimes", default="", type=str, |
65
|
|
|
help="Fit the proxy life time " |
66
|
|
|
"(comma separated proxy names, e.g. Sol,GM), " |
67
|
|
|
"sets the proxy lag time to zero (default: %(default)s)") |
68
|
1 |
|
parser.add_argument("--fit_annlifetimes", default="", type=str, |
69
|
|
|
help="Fit the proxy annual life time variations " |
70
|
|
|
"(comma separated proxy names, e.g. Sol,GM) " |
71
|
|
|
"(default: %(default)s)") |
72
|
1 |
|
parser.add_argument("--fit_phase", action="store_true", default=False, |
73
|
|
|
help="Fit the phase of the harmonic terms directly " |
74
|
|
|
"instead of using separate cosine and sine terms " |
75
|
|
|
"(default: %(default)s)") |
76
|
1 |
|
parser.add_argument("--use_sza", action="store_true", default=False, |
77
|
|
|
help="Fit the proxy annual life time variations " |
78
|
|
|
"using the (cosine and sine of the) of the solar zenith angle " |
79
|
|
|
"instead of the time (default: %(default)s)") |
80
|
1 |
|
parser.add_argument("-t", "--lag_times", metavar="years", |
81
|
|
|
default="Sol:0,GM:0", type=str, |
82
|
|
|
help="Comma-separated list of name:value pairs of fixed proxy lags " |
83
|
|
|
"(in fractional years) (default: %(default)s)") |
84
|
1 |
|
parser.add_argument("--center_proxies", default="", type=str, |
85
|
|
|
help="Comma-separated list of proxies to center " |
86
|
|
|
"by subtracting the mean (default: %(default)s)") |
87
|
1 |
|
parser.add_argument("--log_proxies", default="", type=str, |
88
|
|
|
help="Comma-separated list of proxies to take the logarithm of " |
89
|
|
|
"for fitting (default: %(default)s)") |
90
|
1 |
|
parser.add_argument("--positive_proxies", default="", type=str, |
91
|
|
|
help="Comma-separated list of proxies with positive cofficients. " |
92
|
|
|
"Changes the parameter bounds for these proxies accordingly " |
93
|
|
|
"(default: %(default)s)") |
94
|
1 |
|
parser.add_argument("--norm_proxies_distSEsq", default="", type=str, |
95
|
|
|
help="Comma-separated list of proxies to be normalized by the " |
96
|
|
|
"Sun-Earth distance squared, for example the Lyman-alpha radiation " |
97
|
|
|
"(default: %(default)s)") |
98
|
1 |
|
parser.add_argument("--norm_proxies_SZA", default="", type=str, |
99
|
|
|
help="Comma-separated list of proxies to be normalized by the " |
100
|
|
|
"the solar zenith angle, for example to adjust the Lyman-alpha " |
101
|
|
|
"radiation for the seasonal effects at different latitudes " |
102
|
|
|
"(default: %(default)s)") |
103
|
1 |
|
parser.add_argument("--time_format", default="jyear", type=str, |
104
|
|
|
choices=['jyear', 'decimalyear', 'jd', 'mjd'], |
105
|
|
|
help="Treat the time units (proxy and data) according to the given " |
106
|
|
|
"astropy.time time format. (default: %(default)s)") |
107
|
1 |
|
parser.add_argument("-k", "--fit_offset", action="store_true", default=False, |
108
|
|
|
help="Fit an additional offset via regression (default: %(default)s)") |
109
|
1 |
|
parser.add_argument("-F", "--freqs", default="1, 2", type=str, |
110
|
|
|
help="Comma separated list of frequencies (in inverse years) to fit " |
111
|
|
|
"(default: %(default)s)") |
112
|
1 |
|
parser.add_argument("--lifetime_scan", default=0, type=int, |
113
|
|
|
help="Number of days to go back to estimate the lifetime. " |
114
|
|
|
"If set to zero or negative, the scan range will be set to " |
115
|
|
|
"three times the maximum lifetime, including the annual variation " |
116
|
|
|
"(default: %(default)s)") |
117
|
1 |
|
parser.add_argument("--lifetime_prior", default=None, type=str, |
118
|
|
|
choices=[None, 'flat', 'exp', 'normal'], |
119
|
|
|
help="The prior probability density for the lifetimes " |
120
|
|
|
"(default: %(default)s)") |
121
|
1 |
|
parser.add_argument("--lifetime_metric", default=1, type=float, |
122
|
|
|
help="The prior probability density metric for the lifetimes in days " |
123
|
|
|
"(default: %(default)s)") |
124
|
1 |
|
parser.add_argument("--center_data", action="store_true", default=False, |
125
|
|
|
help="Center the data by subtracting a global mean (default: %(default)s)") |
126
|
1 |
|
parser.add_argument("--initial", metavar="values", default=None, type=str, |
127
|
|
|
help="Comma separated list of initial parameter values " |
128
|
|
|
"(default: %(default)s)") |
129
|
1 |
|
parser.add_argument("-i", "--linearise", action="store_true", default=False, |
130
|
|
|
help="Use the linearised version of the model (default: %(default)s).") |
131
|
1 |
|
parser.add_argument("-A", "--altitude", metavar="km", |
132
|
|
|
type=float, default=72, |
133
|
|
|
help="Altitude bin [km] (default: %(default)s)") |
134
|
1 |
|
parser.add_argument("-L", "--latitude", metavar="degN", |
135
|
|
|
type=float, default=62.5, |
136
|
|
|
help="Latitude bin [°N] (default: %(default)s)") |
137
|
1 |
|
parser.add_argument("--season", default=None, |
138
|
|
|
choices=[None, 'summerNH', 'summerSH'], |
139
|
|
|
help="Select a particular season (default: %(default)s)") |
140
|
1 |
|
parser.add_argument("--exclude_spe", action="store_true", default=False, |
141
|
|
|
help="Exclude pre-defined SPE events (default: %(default)s)") |
142
|
1 |
|
parser.add_argument("--akd_threshold", default=0.002, type=float, |
143
|
|
|
help="Exclude data with an averaging kernel diagonal element " |
144
|
|
|
"smaller than the given threshold (default: %(default)s)") |
145
|
1 |
|
parser.add_argument("--cnt_threshold", default=0, type=int, |
146
|
|
|
help="Exclude data with less than the given number of measurement points " |
147
|
|
|
"in the averaged bin (default: %(default)s)") |
148
|
1 |
|
parser.add_argument("-s", "--scale", metavar="factor", |
149
|
|
|
type=float, default=1e-6, |
150
|
|
|
help="Scale the data by factor prior to fitting (default: %(default)s)") |
151
|
1 |
|
parser.add_argument("-r", "--random_subsample", metavar="factor", |
152
|
|
|
type=int, default=1, |
153
|
|
|
help="Randomly subsample the data by the given factor " |
154
|
|
|
"(default: 1, no subsampling)") |
155
|
1 |
|
parser.add_argument("--train_fraction", metavar="factor", |
156
|
|
|
type=float, default=1, choices=Range(0., 1.), |
157
|
|
|
help="Use the given fraction of the data points to train the model " |
158
|
|
|
"(default: 1, train on all points)") |
159
|
1 |
|
parser.add_argument("--test_fraction", metavar="factor", |
160
|
|
|
type=float, default=1, choices=Range(0., 1.), |
161
|
|
|
help="Use the given fraction of the data points to test the model " |
162
|
|
|
"(default: test on (1 - train_fraction) or all points)") |
163
|
1 |
|
parser.add_argument("--random_train_test", dest="random_train_test", |
164
|
|
|
action="store_true") |
165
|
1 |
|
parser.add_argument("--no-random_train_test", dest="random_train_test", |
166
|
|
|
action="store_false", |
167
|
|
|
help="Randomize the data before splitting into train and test sets " |
168
|
|
|
"(default: %(default)s).") |
169
|
1 |
|
parser.set_defaults(random_train_test=False) |
170
|
1 |
|
parser.add_argument("--scheduler_address", metavar="address:port", |
171
|
|
|
default=None, |
172
|
|
|
help="Connect to dask scheduler at address:port " |
173
|
|
|
"(default: %(default)s)") |
174
|
1 |
|
parser.add_argument("--scheduler_file", metavar="file", |
175
|
|
|
default=None, |
176
|
|
|
help="Connect to dask scheduler at using the scheduler file " |
177
|
|
|
"(default: %(default)s)") |
178
|
1 |
|
parser.add_argument("-O", "--optimize", metavar="m", type=int, default="1", |
179
|
|
|
help="Optimize the parameters before MCMC run with method no. m: " |
180
|
|
|
"0: no optimization, 1: Powell, " |
181
|
|
|
"2: differential evolution with latin hypercube initialization, " |
182
|
|
|
"3: basin hopping " |
183
|
|
|
"(default: %(default)s)") |
184
|
1 |
|
parser.add_argument("-N", "--openblas_threads", metavar="N", |
185
|
|
|
type=int, default=1, |
186
|
|
|
help="Use N OpenBlas threads (default: %(default)s)") |
187
|
1 |
|
parser.add_argument("-S", "--random_seed", metavar="NNNN", |
188
|
|
|
type=int, default=None, |
189
|
|
|
help="Use a particular random seed to obtain " |
190
|
|
|
"reproducible results (default: %(default)s)") |
191
|
1 |
|
group_mcmc = parser.add_argument_group(title="MCMC parameters", |
192
|
|
|
description="Fine-tuning of the (optional) MCMC run.") |
193
|
1 |
|
group_mcmc.add_argument("-M", "--mcmc", type=strtobool, default="true", |
194
|
|
|
help="Fit the parameters with MCMC (default: %(default)s)") |
195
|
1 |
|
group_mcmc.add_argument("-w", "--walkers", metavar="N", |
196
|
|
|
type=int, default=100, |
197
|
|
|
help="Use N MCMC walkers (default: %(default)s)") |
198
|
1 |
|
group_mcmc.add_argument("-b", "--burn_in", metavar="N", |
199
|
|
|
type=int, default=200, |
200
|
|
|
help="Use N MCMC burn-in samples " |
201
|
|
|
"(run twice if --optimize is False) (default: %(default)s)") |
202
|
1 |
|
group_mcmc.add_argument("-p", "--production", metavar="N", |
203
|
|
|
type=int, default=800, |
204
|
|
|
help="Use N MCMC production samples (default: %(default)s)") |
205
|
1 |
|
group_mcmc.add_argument("-n", "--threads", metavar="N", |
206
|
|
|
type=int, default=1, |
207
|
|
|
help="Use N MCMC threads (default: %(default)s)") |
208
|
1 |
|
group_mcmc.add_argument("-P", "--progress", action="store_true", default=False, |
209
|
|
|
help="Show MCMC sampler progress (default: %(default)s)") |
210
|
1 |
|
group_gp = parser.add_argument_group(title="GP parameters", |
211
|
|
|
description="Fine-tuning of the (optional) Gaussian Process parameters.") |
212
|
1 |
|
group_gp.add_argument("-g", "--george", action="store_true", default=False, |
213
|
|
|
help="Optimize a Gaussian Process model of the correlations " |
214
|
|
|
"using the `celerite` (not set) or `george` GP packages " |
215
|
|
|
"(default: %(default)s)") |
216
|
1 |
|
group_gp.add_argument("-K", "--kernels", default="", type=str, |
217
|
|
|
help="Comma separated list of Gaussian Process kernels to use. " |
218
|
|
|
"They will be combined linearly (default: %(default)s) " |
219
|
|
|
"Possible choices are: {0} for george (-g) and {1} for celerite" |
220
|
|
|
.format(sorted(map(str, george_kernels.keys())), |
221
|
|
|
sorted(map(str, celerite_terms.keys())))) |
222
|
1 |
|
group_gp.add_argument("-B", "--fit_bias", action="store_true", default=False, |
223
|
|
|
help="Fit bias using a constant kernel (default: %(default)s)") |
224
|
1 |
|
group_gp.add_argument("-W", "--fit_white", action="store_true", default=False, |
225
|
|
|
help="Fit additional white noise (default: %(default)s)") |
226
|
1 |
|
group_gp.add_argument("-H", "--HODLR_Solver", action="store_true", default=False, |
227
|
|
|
help="Use the HODLR solver for the GP fit (default: %(default)s)") |
228
|
1 |
|
group_save = parser.add_argument_group(title="Output options", |
229
|
|
|
description="Diagnostic output and figures.") |
230
|
1 |
|
group_save.add_argument("--save_model", dest="save_model", action="store_true") |
231
|
1 |
|
group_save.add_argument("--no-save_model", dest="save_model", action="store_false", |
232
|
|
|
help="Saves a pickled version of the Model (default: %(default)s).") |
233
|
1 |
|
group_save.add_argument("--save_samples", dest="save_samples", action="store_true") |
234
|
1 |
|
group_save.add_argument("--no-save_samples", dest="save_samples", action="store_false", |
235
|
|
|
help="Saves the MCMC samples to disk (see --sample_format) " |
236
|
|
|
"(default: %(default)s).") |
237
|
1 |
|
group_save.add_argument("--samples_format", default="netcdf4", |
238
|
|
|
choices=['npz', 'h5', 'hdf5', 'nc', 'netcdf4'], |
239
|
|
|
help="File format for the samples, compressed .npz or netcdf4 (hdf5) " |
240
|
|
|
"(h5 and hdf5 will also save to netcdf4 files but named \".h5\") " |
241
|
|
|
"(default: %(default)s).") |
242
|
1 |
|
group_save.add_argument("--plot_corner", dest="plot_corner", action="store_true") |
243
|
1 |
|
group_save.add_argument("--no-plot_corner", dest="plot_corner", action="store_false", |
244
|
|
|
help="Plot the fitted parameter distributions as a corner plot " |
245
|
|
|
"(default: %(default)s).") |
246
|
1 |
|
group_save.add_argument("--plot_samples", dest="plot_samples", action="store_true") |
247
|
1 |
|
group_save.add_argument("--no-plot_samples", dest="plot_samples", action="store_false", |
248
|
|
|
help="Plot sample predictions using the fitted parameters " |
249
|
|
|
"(default: %(default)s).") |
250
|
1 |
|
group_save.add_argument("--plot_median", dest="plot_median", action="store_true") |
251
|
1 |
|
group_save.add_argument("--no-plot_median", dest="plot_median", action="store_false", |
252
|
|
|
help="Plot median prediction and the residuals combined " |
253
|
|
|
"(default: %(default)s).") |
254
|
1 |
|
group_save.add_argument("--plot_residuals", dest="plot_residuals", action="store_true") |
255
|
1 |
|
group_save.add_argument("--no-plot_residuals", dest="plot_residuals", action="store_false", |
256
|
|
|
help="Plot standalone median prediction residuals " |
257
|
|
|
"(default: %(default)s).") |
258
|
1 |
|
group_save.add_argument("--plot_maxlnp", dest="plot_maxlnp", action="store_true") |
259
|
1 |
|
group_save.add_argument("--no-plot_maxlnp", dest="plot_maxlnp", action="store_false", |
260
|
|
|
help="Plot the maximum posterior prediction and the residuals combined " |
261
|
|
|
"(default: %(default)s).") |
262
|
1 |
|
group_save.add_argument("--plot_maxlnpres", dest="plot_maxlnpres", action="store_true") |
263
|
1 |
|
group_save.add_argument("--no-plot_maxlnpres", dest="plot_maxlnpres", action="store_false", |
264
|
|
|
help="Plot standalone maximum posterior prediction residuals " |
265
|
|
|
"(default: %(default)s).") |
266
|
1 |
|
group_save.set_defaults(save_model=False, save_samples="netcdf4", |
267
|
|
|
plot_corner=True, plot_samples=True, plot_median=False, |
268
|
|
|
plot_residuals=False, plot_maxlnp=True, plot_maxlnpres=False) |
269
|
1 |
|
loglevels = parser.add_mutually_exclusive_group() |
270
|
1 |
|
loglevels.add_argument("-q", "--quiet", action="store_true", default=False, |
271
|
|
|
help="less output, same as --loglevel=ERROR (default: %(default)s)") |
272
|
1 |
|
loglevels.add_argument("-v", "--verbose", action="store_true", default=False, |
273
|
|
|
help="verbose output, same as --loglevel=INFO (default: %(default)s)") |
274
|
1 |
|
loglevels.add_argument("-l", "--loglevel", default="WARNING", |
275
|
|
|
choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], |
276
|
|
|
help="change the loglevel (default: %(default)s)") |
277
|
|
|
|