Passed
Branch master (9c78f3)
by Stefan
06:59
created

sciapy.regress._options   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 277
Duplicated Lines 8.3 %

Test Coverage

Coverage 98.95%

Importance

Changes 0
Metric Value
eloc 188
dl 23
loc 277
ccs 94
cts 95
cp 0.9895
rs 10
c 0
b 0
f 0
wmc 5

4 Methods

Rating   Name   Duplication   Size   Complexity  
A Range.__eq__() 2 2 1
A Range.__repr__() 2 2 1
A Range.__init__() 3 3 1
A Range.__getitem__() 5 5 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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