Passed
Push — master ( 608fec...81ba06 )
by Stefan
01:20
created

eppaurora.electrons   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 355
Duplicated Lines 61.13 %

Importance

Changes 0
Metric Value
wmc 9
eloc 95
dl 217
loc 355
rs 10
c 0
b 0
f 0

9 Functions

Rating   Name   Duplication   Size   Complexity  
A fang2010_spec_int() 33 37 1
A maxwell_pflux() 0 22 1
A fang2010_mono() 35 35 1
A rr1987() 42 42 1
A maxwell_general() 0 20 1
A fang2008() 35 35 1
A fang2010_maxw_int() 17 37 1
A _fang_f_y() 10 10 1
A rr1987_mod() 45 45 1

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
# Copyright (c) 2020 Stefan Bender
3
#
4
# This file is part of pyeppaurora.
5
# pyeppaurora is free software: you can redistribute it or modify
6
# it under the terms of the GNU General Public License as published
7
# by the Free Software Foundation, version 2.
8
# See accompanying LICENSE file or http://www.gnu.org/licenses/gpl-2.0.html.
9
"""Atmospheric ionization rate parametrizations
10
11
Includes the atmospheric ionization rate parametrizations for auroral
12
and medium-energy electron precipitation, 100 eV--1 MeV [1]_, [2]_, and [3]_.
13
14
.. [1] Roble and Ridley, Ann. Geophys., 5A(6), 369--382, 1987
15
.. [2] Fang et al., J. Geophys. Res., 113, A09311, 2008
16
.. [3] Fang et al., Geophys. Res. Lett., 37, L22106, 2010
17
"""
18
19
import numpy as np
20
from numpy.polynomial.polynomial import polyval
21
22
__all__ = [
23
	"rr1987",
24
	"rr1987_mod",
25
	"fang2008",
26
	"fang2010_mono",
27
	"fang2010_spec_int",
28
	"fang2010_maxw_int",
29
	"maxwell_general",
30
	"maxwell_pflux",
31
]
32
33
POLY_F2008 = [
34
	[ 3.49979e-1, -6.18200e-2, -4.08124e-2,  1.65414e-2],
35
	[ 5.85425e-1, -5.00793e-2,  5.69309e-2, -4.02491e-3],
36
	[ 1.69692e-1, -2.58981e-2,  1.96822e-2,  1.20505e-3],
37
	[-1.22271e-1, -1.15532e-2,  5.37951e-6,  1.20189e-3],
38
	[ 1.57018,     2.87896e-1, -4.14857e-1,  5.18158e-2],
39
	[ 8.83195e-1,  4.31402e-2, -8.33599e-2,  1.02515e-2],
40
	[ 1.90953,    -4.74704e-2, -1.80200e-1,  2.46652e-2],
41
	[-1.29566,    -2.10952e-1,  2.73106e-1, -2.92752e-2]
42
]
43
44
POLY_F2010 = [
45
	[ 1.24616E+0,  1.45903E+0, -2.42269E-1,  5.95459E-2],
46
	[ 2.23976E+0, -4.22918E-7,  1.36458E-2,  2.53332E-3],
47
	[ 1.41754E+0,  1.44597E-1,  1.70433E-2,  6.39717E-4],
48
	[ 2.48775E-1, -1.50890E-1,  6.30894E-9,  1.23707E-3],
49
	[-4.65119E-1, -1.05081E-1, -8.95701E-2,  1.22450E-2],
50
	[ 3.86019E-1,  1.75430E-3, -7.42960E-4,  4.60881E-4],
51
	[-6.45454E-1,  8.49555E-4, -4.28581E-2, -2.99302E-3],
52
	[ 9.48930E-1,  1.97385E-1, -2.50660E-3, -2.06938E-3]
53
]
54
55
56 View Code Duplication
def rr1987(energy, flux, scale_height, rho):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
57
	"""Atmospheric electron energy dissipation Roble and Ridley, 1987 [#]_
58
59
	Equations (typo corrected) taken from Fang et al., 2008.
60
61
	Parameters
62
	----------
63
	energy: array_like (M,...)
64
		Characteristic energy E_0 [keV] of the Maxwellian distribution.
65
	flux: array_like (M,...)
66
		Integrated energy flux Q_0 [keV / cm² / s¹]
67
	scale_height: array_like (N,...)
68
		The atmospheric scale heights [cm].
69
	rho: array_like (N,...)
70
		The atmospheric mass density [g / cm³]
71
72
	Returns
73
	-------
74
	en_diss: array_like (M,N)
75
		The dissipated energy profiles [keV].
76
77
	References
78
	----------
79
80
	.. [#] Roble and Ridley, Ann. Geophys., 5A(6), 369--382, 1987
81
	"""
82
	_c1 = 2.11685
83
	_c2 = 2.97035
84
	_c3 = 2.09710
85
	_c4 = 0.74054
86
	_c5 = 0.58795
87
	_c6 = 1.72746
88
	_c7 = 1.37459
89
	_c8 = 0.93296
90
91
	beta = (rho * scale_height / (4 * 1e-6))**(1 / 1.65)  # RR 1987, p. 371
92
	y = beta / energy  # Corrected in Fang et al. 2008 (4)
93
	f_y = (_c1 * (y**_c2) * np.exp(-_c3 * (y**_c4)) +
94
		_c5 * (y**_c6) * np.exp(-_c7 * (y**_c8)))
95
	# Corrected in Fang et al. 2008 (2)
96
	en_diss = 0.5 * flux / scale_height * f_y
97
	return en_diss
98
99
100 View Code Duplication
def rr1987_mod(energy, flux, scale_height, rho):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
101
	"""Atmospheric electron energy dissipation Roble and Ridley, 1987 [#]_
102
103
	Equations (typo corrected) taken from Fang et al., 2008.
104
	Modified polynomial values to get closer to Fang et al., 2008,
105
	origin unknown.
106
107
	Parameters
108
	----------
109
	energy: array_like (M,...)
110
		Characteristic energy E_0 [keV] of the Maxwellian distribution.
111
	flux: array_like (M,...)
112
		Integrated energy flux Q_0 [keV / cm² / s¹]
113
	scale_height: array_like (N,...)
114
		The atmospheric scale heights [cm].
115
	rho: array_like (N,...)
116
		The atmospheric mass density [g / cm³]
117
118
	Returns
119
	-------
120
	en_diss: array_like (M,N)
121
		The dissipated energy profiles [keV].
122
123
	References
124
	----------
125
126
	.. [#] Roble and Ridley, Ann. Geophys., 5A(6), 369--382, 1987
127
	"""
128
	# Modified polynomial, origin unknown
129
	_c1 = 3.233
130
	_c2 = 2.56588
131
	_c3 = 2.2541
132
	_c4 = 0.7297198
133
	_c5 = 1.106907
134
	_c6 = 1.71349
135
	_c7 = 1.8835444
136
	_c8 = 0.86472135
137
138
	# Fang et al., 2008, Eq. (4)
139
	y = (rho * scale_height / (4.6 * 1e-6))**(1 / 1.65) / energy
140
	f_y = (_c1 * (y**_c2) * np.exp(-_c3 * (y**_c4)) +
141
		_c5 * (y**_c6) * np.exp(-_c7 * (y**_c8)))
142
	# energy dissipated [keV]
143
	en_diss = 0.5 * flux / scale_height * f_y
144
	return en_diss
145
146
147 View Code Duplication
def _fang_f_y(_c, _y):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
148
	"""Polynomial evaluation helper
149
150
	Fang et al., 2008, Eq. (6), Fang et al., 2010 Eq. (4)
151
	"""
152
	ret = (
153
		_c[0] * (_y**_c[1]) * np.exp(-_c[2] * (_y**_c[3])) +
154
		_c[4] * (_y**_c[5]) * np.exp(-_c[6] * (_y**_c[7]))
155
	)
156
	return ret
157
158
159 View Code Duplication
def fang2008(energy, flux, scale_height, rho, pij=POLY_F2008):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
160
	"""Atmospheric electron energy dissipation from Fang et al., 2008
161
162
	Ionization profile parametrization as derived in Fang et al., 2008 [#]_.
163
164
	Parameters
165
	----------
166
	energy: array_like (M,...)
167
		Characteristic energy E_0 [keV] of the Maxwellian distribution.
168
	flux: array_like (M,...)
169
		Integrated energy flux Q_0 [keV / cm² / s¹]
170
	scale_height: array_like (N,...)
171
		The atmospheric scale height(s) [cm].
172
	rho: array_like (N,...)
173
		The atmospheric densities [g / cm³], corresponding to the scale heights.
174
175
	Returns
176
	-------
177
	en_diss: array_like (M,N)
178
		The dissipated energy profiles [keV].
179
180
	References
181
	----------
182
183
	.. [#] Fang et al., J. Geophys. Res., 113, A09311, 2008, doi: 10.1029/2008JA013384
184
	"""
185
	pij = np.asarray(pij)
186
	# Fang et al., 2008, Eq. (7)
187
	_cs = np.exp(polyval(np.log(energy), pij.T))
188
	# Fang et al., 2008, Eq. (4)
189
	y = (rho * scale_height / (4e-6))**(1 / 1.65) / energy
190
	f_y = _fang_f_y(_cs, y)
191
	# Fang et al., 2008, Eq. (2)
192
	en_diss = 0.5 * f_y * flux / scale_height
193
	return en_diss
194
195
196 View Code Duplication
def fang2010_mono(energy, flux, scale_height, rho, pij=POLY_F2010):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
197
	r"""Atmospheric electron energy dissipation from Fang et al., 2010
198
199
	Parametrization for mono-energetic electrons [#]_.
200
201
	Parameters
202
	----------
203
	energy: array_like (M,...)
204
		Energy E_0 of the mono-energetic electron beam [keV].
205
	flux: array_like (M,...)
206
		Energy flux Q_0 of the mono-energetic electron beam [keV / cm² / s¹].
207
	scale_height: array_like (N,...)
208
		The atmospheric scale heights [cm].
209
	rho: array_like (N,...)
210
		The atmospheric mass densities [g / cm³], corresponding to the scale heights.
211
212
	Returns
213
	-------
214
	en_diss: array_like (M,N)
215
		The dissipated energy profiles [keV].
216
217
	References
218
	----------
219
220
	.. [#] Fang et al., Geophys. Res. Lett., 37, L22106, 2010, doi: 10.1029/2010GL045406
221
	"""
222
	pij = np.asarray(pij)
223
	# Fang et al., 2010, Eq. (5)
224
	_cs = np.exp(polyval(np.log(energy), pij.T))
225
	# Fang et al., 2010, Eq. (1)
226
	y = 2. / energy * (rho * scale_height / (6e-6))**(0.7)
227
	f_y = _fang_f_y(_cs, y)
228
	# Fang et al., 2008, Eq. (2)
229
	en_diss = f_y * flux / scale_height
230
	return en_diss
231
232
233 View Code Duplication
def fang2010_spec_int(ens, dfluxes, scale_height, rho, pij=POLY_F2010, axis=-1):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
234
	r"""Integrate over a given energy spectrum
235
236
	Integrates over the mono-energetic parametrization `q` from Fang et al., 2010
237
	using the given differential particle spectrum `phi`:
238
239
	:math:`\int_\text{spec} \phi(E) q(E, Q) E \text{d}E`
240
241
	Parameters
242
	----------
243
	ens: array_like (M,...)
244
		Central (bin) energies of the spectrum
245
	dfluxes: array_like (M,...)
246
		Differential particle fluxes in the given bins
247
	scale_height: array_like (N,...)
248
		The atmospheric scale heights
249
	rho: array_like (N,...)
250
		The atmospheric densities, corresponding to the
251
		scale heights.
252
253
	Returns
254
	-------
255
	en_diss: array_like (N)
256
		The dissipated energy profiles [keV].
257
258
	See Also
259
	--------
260
	fang2010_mono
261
	"""
262
	ediss_f10 = fang2010_mono(
263
		ens[None, None, :],
264
		dfluxes,
265
		scale_height[..., None],
266
		rho[..., None],
267
		pij=pij,
268
	)
269
	return np.trapz(ediss_f10 * ens, ens, axis=axis)
270
271
272 View Code Duplication
def fang2010_maxw_int(energy, flux, scale_height, rho, bounds=(0.1, 300.), nstep=128, pij=POLY_F2010):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
273
	"""Integrate Fang et al., 2010 over a Maxwellian spectrum
274
275
	Integrates the mono-energetic parametrization from Fang et al., 2010 [#]_
276
	over a Maxwellian spectrum with characteristic energy `energy` and
277
	total energy flux `flux`.
278
279
	Parameters
280
	----------
281
	energy: array_like (M,...)
282
		Characteristic energy E_0 [keV] of the Maxwellian distribution.
283
	flux: array_like (M,...)
284
		Integrated energy flux Q_0 [keV / cm² / s¹]
285
	scale_height: array_like (N,...)
286
		The atmospheric scale heights [cm].
287
	rho: array_like (N,...)
288
		The atmospheric mass density [g / cm³]
289
	bounds: tuple, optional
290
		(min, max) [keV] of the integration range to integrate the Maxwellian.
291
		Make sure that this is appropriate to encompass the spectrum.
292
		Default: (0.1, 300.)
293
	nsteps: int, optional
294
		Number of integration steps, default: 128.
295
296
	Returns
297
	-------
298
	en_diss: array_like (M,N)
299
		The dissipated energy profiles [keV].
300
301
	See Also
302
	--------
303
	fang2010_mono, fang2010_spec_int, maxwell_pflux
304
	"""
305
	bounds_l10 = np.log10(bounds)
306
	ens = np.logspace(*bounds_l10, num=nstep)
307
	dflux = flux * maxwell_pflux(ens[:, None], energy)
308
	return fang2010_spec_int(ens, dflux.T, scale_height, rho, pij=pij, axis=-1)
309
310
311
def maxwell_general(en, en_0=10.):
312
	"""Maxwell number flux spectrum as in Fang2008 [1]
313
314
	Defined in Fang et al., JGR 2008, Eq. (1).
315
316
	Parameters
317
	----------
318
	en: float
319
		Energy in [keV]
320
	en_0: float, optional
321
		Characteristic energy in [keV], i.e. mode of the distribution.
322
		Default: 10 keV
323
324
	Returns
325
	-------
326
	phi: float
327
		Differential hemispherical number flux in [keV-1 cm-2 s-1]
328
		([keV] or scaled by 1 keV-2 cm-2 s-1, e.g. ).
329
	"""
330
	return en * np.exp(-en / en_0)
331
332
333
def maxwell_pflux(en, en_0=10.):
334
	"""Maxwell particle flux spectrum as in Fang2008 [1]
335
336
	Defined in Fang et al., JGR 2008, Eq. (1).
337
	The total precipitating energy flux is fixed to 1 keV cm-2 s-1,
338
	multiply by Q_0 [keV cm-2 s-1] to scale the particle flux.
339
340
	Parameters
341
	----------
342
	en: float
343
		Energy in [keV]
344
	en_0: float, optional
345
		Characteristic energy in [keV], i.e. mode of the distribution.
346
		Default: 10 keV.
347
348
	Returns
349
	-------
350
	phi: float
351
		Hemispherical differential particle flux in [keV-1 cm-2 s-1]
352
		([kev-2] scaled by unit energy flux).
353
	"""
354
	return 0.5 / en_0**3 * maxwell_general(en, en_0)
355