pygmi 2.2.7__zip
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.
- pygmi-2.2.7/LICENSE.txt +623 -0
- pygmi-2.2.7/MANIFEST.in +7 -0
- pygmi-2.2.7/PKG-INFO +47 -0
- pygmi-2.2.7/README.md +55 -0
- pygmi-2.2.7/README.rst +20 -0
- pygmi-2.2.7/log.txt +242 -0
- pygmi-2.2.7/pygmi/__init__.py +22 -0
- pygmi-2.2.7/pygmi/clust/__init__.py +4 -0
- pygmi-2.2.7/pygmi/clust/crisp_clust.py +708 -0
- pygmi-2.2.7/pygmi/clust/datatypes.py +65 -0
- pygmi-2.2.7/pygmi/clust/fuzzy_clust.py +906 -0
- pygmi-2.2.7/pygmi/clust/graphs.py +421 -0
- pygmi-2.2.7/pygmi/clust/graphtool.py +667 -0
- pygmi-2.2.7/pygmi/clust/menu.py +139 -0
- pygmi-2.2.7/pygmi/clust/var_ratio.py +92 -0
- pygmi-2.2.7/pygmi/clust/xie_beni.py +93 -0
- pygmi-2.2.7/pygmi/helpdocs/linepointer.png +0 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.main.html +31 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.ddisp.html +15 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.iodefs.exportkmz.html +13 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.iodefs.importpicture.html +16 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.layer.html +17 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.mext.html +44 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.misc.rangedcopy.html +16 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.param.html +37 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.prof.html +32 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.pview.html +26 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.gradients.html +14 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.tilt.html +14 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.visibility.html +14 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datagrid.html +13 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datamerge.html +11 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datareproj.html +11 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.rtp.html +14 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.ginterp.html +31 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.igrf.html +20 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.normalisation.html +14 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.smooth.html +22 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.tiltdepth.html +20 -0
- pygmi-2.2.7/pygmi/images/Help.png +0 -0
- pygmi-2.2.7/pygmi/images/bringtofront.png +0 -0
- pygmi-2.2.7/pygmi/images/cgs2.emf +0 -0
- pygmi-2.2.7/pygmi/images/delete.png +0 -0
- pygmi-2.2.7/pygmi/images/linepointer.png +0 -0
- pygmi-2.2.7/pygmi/images/logo256.ico +0 -0
- pygmi-2.2.7/pygmi/images/logo256.png +0 -0
- pygmi-2.2.7/pygmi/images/pointer.png +0 -0
- pygmi-2.2.7/pygmi/images/pygmi.png +0 -0
- pygmi-2.2.7/pygmi/images/sendtoback.png +0 -0
- pygmi-2.2.7/pygmi/main.py +1037 -0
- pygmi-2.2.7/pygmi/menu_default.py +327 -0
- pygmi-2.2.7/pygmi/misc.py +147 -0
- pygmi-2.2.7/pygmi/pfmod/__init__.py +6 -0
- pygmi-2.2.7/pygmi/pfmod/cubes.py +1488 -0
- pygmi-2.2.7/pygmi/pfmod/datatypes.py +292 -0
- pygmi-2.2.7/pygmi/pfmod/grvmag3d.py +1265 -0
- pygmi-2.2.7/pygmi/pfmod/iodefs.py +1001 -0
- pygmi-2.2.7/pygmi/pfmod/menu.py +107 -0
- pygmi-2.2.7/pygmi/pfmod/misc.py +301 -0
- pygmi-2.2.7/pygmi/pfmod/pfmod.py +248 -0
- pygmi-2.2.7/pygmi/pfmod/tab_ddisp.py +425 -0
- pygmi-2.2.7/pygmi/pfmod/tab_layer.py +490 -0
- pygmi-2.2.7/pygmi/pfmod/tab_mext.py +544 -0
- pygmi-2.2.7/pygmi/pfmod/tab_param.py +548 -0
- pygmi-2.2.7/pygmi/pfmod/tab_prof.py +946 -0
- pygmi-2.2.7/pygmi/pfmod/tab_pview.py +740 -0
- pygmi-2.2.7/pygmi/raster/IGRF11.COF +1635 -0
- pygmi-2.2.7/pygmi/raster/__init__.py +14 -0
- pygmi-2.2.7/pygmi/raster/cooper.py +718 -0
- pygmi-2.2.7/pygmi/raster/dataprep.py +1640 -0
- pygmi-2.2.7/pygmi/raster/datatypes.py +123 -0
- pygmi-2.2.7/pygmi/raster/equation_editor.py +256 -0
- pygmi-2.2.7/pygmi/raster/ginterp.py +1901 -0
- pygmi-2.2.7/pygmi/raster/graphs.py +531 -0
- pygmi-2.2.7/pygmi/raster/igrf.py +860 -0
- pygmi-2.2.7/pygmi/raster/iodefs.py +813 -0
- pygmi-2.2.7/pygmi/raster/menu.py +307 -0
- pygmi-2.2.7/pygmi/raster/normalisation.py +187 -0
- pygmi-2.2.7/pygmi/raster/show_table.py +245 -0
- pygmi-2.2.7/pygmi/raster/smooth.py +406 -0
- pygmi-2.2.7/pygmi/raster/tiltdepth.py +590 -0
- pygmi-2.2.7/pygmi/seis/__init__.py +0 -0
- pygmi-2.2.7/pygmi/seis/beachball.py +751 -0
- pygmi-2.2.7/pygmi/seis/datatypes.py +605 -0
- pygmi-2.2.7/pygmi/seis/del_rec.py +410 -0
- pygmi-2.2.7/pygmi/seis/iodefs.py +1261 -0
- pygmi-2.2.7/pygmi/seis/menu.py +136 -0
- pygmi-2.2.7/pygmi/seis/scan_imp.py +795 -0
- pygmi-2.2.7/pygmi/test/__init__.py +6 -0
- pygmi-2.2.7/pygmi/test/pfmod.py +212 -0
- pygmi-2.2.7/pygmi/test/tests.py +39 -0
- pygmi-2.2.7/pygmi/vector/__init__.py +7 -0
- pygmi-2.2.7/pygmi/vector/datatypes.py +74 -0
- pygmi-2.2.7/pygmi/vector/graphs.py +443 -0
- pygmi-2.2.7/pygmi/vector/iodefs.py +345 -0
- pygmi-2.2.7/pygmi/vector/menu.py +127 -0
- pygmi-2.2.7/pygmi.egg-info/PKG-INFO +47 -0
- pygmi-2.2.7/pygmi.egg-info/SOURCES.txt +105 -0
- pygmi-2.2.7/pygmi.egg-info/dependency_links.txt +1 -0
- pygmi-2.2.7/pygmi.egg-info/entry_points.txt +3 -0
- pygmi-2.2.7/pygmi.egg-info/not-zip-safe +1 -0
- pygmi-2.2.7/pygmi.egg-info/requires.txt +7 -0
- pygmi-2.2.7/pygmi.egg-info/top_level.txt +1 -0
- pygmi-2.2.7/quickstart.py +35 -0
- pygmi-2.2.7/setup.cfg +8 -0
- pygmi-2.2.7/setup.py +80 -0
|
@@ -0,0 +1,860 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Name: igrf.py (part of PyGMI)
|
|
3
|
+
#
|
|
4
|
+
# Author: Patrick Cole
|
|
5
|
+
# E-Mail: pcole@geoscience.org.za
|
|
6
|
+
#
|
|
7
|
+
# Copyright: (c) 2013 Council for Geoscience
|
|
8
|
+
# Licence: GPL-3.0
|
|
9
|
+
#
|
|
10
|
+
# This file is part of PyGMI
|
|
11
|
+
#
|
|
12
|
+
# PyGMI is free software: you can redistribute it and/or modify
|
|
13
|
+
# it under the terms of the GNU General Public License as published by
|
|
14
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
15
|
+
# (at your option) any later version.
|
|
16
|
+
#
|
|
17
|
+
# PyGMI is distributed in the hope that it will be useful,
|
|
18
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20
|
+
# GNU General Public License for more details.
|
|
21
|
+
#
|
|
22
|
+
# You should have received a copy of the GNU General Public License
|
|
23
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
24
|
+
# -----------------------------------------------------------------------------
|
|
25
|
+
"""
|
|
26
|
+
This code is based on the Geomag software, with information given below. It was
|
|
27
|
+
translated into Python from the Geomag code.
|
|
28
|
+
|
|
29
|
+
| This program, originally written in FORTRAN, was developed using subroutines
|
|
30
|
+
| written by : A. Zunde
|
|
31
|
+
| USGS, MS 964, Box 25046 Federal Center, Denver, Co. 80225
|
|
32
|
+
| and
|
|
33
|
+
| S.R.C. Malin & D.R. Barraclough
|
|
34
|
+
| Institute of Geological Sciences, United Kingdom.
|
|
35
|
+
|
|
36
|
+
| Translated
|
|
37
|
+
| into C by : Craig H. Shaffer
|
|
38
|
+
| 29 July, 1988
|
|
39
|
+
|
|
40
|
+
| Rewritten by : David Owens
|
|
41
|
+
| For Susan McLean
|
|
42
|
+
|
|
43
|
+
| Maintained by: Stefan Maus
|
|
44
|
+
| Contact : stefan.maus@noaa.gov
|
|
45
|
+
| National Geophysical Data Center
|
|
46
|
+
| World Data Center-A for Solid Earth Geophysics
|
|
47
|
+
| NOAA, E/GC1, 325 Broadway,
|
|
48
|
+
| Boulder, CO 80303
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
from PyQt4 import QtGui, QtCore
|
|
52
|
+
import numpy as np
|
|
53
|
+
from math import sin
|
|
54
|
+
from math import cos
|
|
55
|
+
from math import sqrt
|
|
56
|
+
from math import atan2
|
|
57
|
+
from osgeo import osr
|
|
58
|
+
import copy
|
|
59
|
+
import pygmi.raster.dataprep as dp
|
|
60
|
+
import pygmi.menu_default as menu_default
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class IGRF(QtGui.QDialog):
|
|
64
|
+
"""
|
|
65
|
+
IGRF field calculation
|
|
66
|
+
|
|
67
|
+
This produces two datasets. The first is an IGRF dataset for the area of
|
|
68
|
+
interest, defined by some input magnetic dataset. The second is the IGRF
|
|
69
|
+
corrected form of that input magnetic dataset.
|
|
70
|
+
|
|
71
|
+
To do this, the input dataset must be reprojected from its local projection
|
|
72
|
+
to degrees, where the IGRF correction will take place. This is done within
|
|
73
|
+
this class.
|
|
74
|
+
|
|
75
|
+
Attributes
|
|
76
|
+
----------
|
|
77
|
+
parent : parent
|
|
78
|
+
reference to the parent routine
|
|
79
|
+
indata : dictionary
|
|
80
|
+
dictionary of input datasets
|
|
81
|
+
outdata : dictionary
|
|
82
|
+
dictionary of output datasets
|
|
83
|
+
|
|
84
|
+
Parameters
|
|
85
|
+
----------
|
|
86
|
+
altmin : Double
|
|
87
|
+
Minimum height of selected model.
|
|
88
|
+
altmax : Double array
|
|
89
|
+
array of MAXMOD Maximum height of model.
|
|
90
|
+
maxalt : Double
|
|
91
|
+
Maximum height of selected model.
|
|
92
|
+
d : float
|
|
93
|
+
Declination of the field from the geographic north (deg).
|
|
94
|
+
sdate : float
|
|
95
|
+
start date inputted
|
|
96
|
+
ddot : float
|
|
97
|
+
annual rate of change of decl. (arc-min/yr)
|
|
98
|
+
alt : float
|
|
99
|
+
altitude above WGS84 Ellipsoid
|
|
100
|
+
epoch : list
|
|
101
|
+
list of MAXMOD epoch of model.
|
|
102
|
+
latitude : float
|
|
103
|
+
Latitude.
|
|
104
|
+
longitude : float
|
|
105
|
+
Longitude.
|
|
106
|
+
gh : numpy array
|
|
107
|
+
Schmidt quasi-normal internal spherical harmonic coeff.
|
|
108
|
+
Schmidt quasi-normal internal spherical harmonic coeff.
|
|
109
|
+
Coefficients of resulting model.
|
|
110
|
+
Coefficients of rate of change model.
|
|
111
|
+
i : float
|
|
112
|
+
Inclination (deg).
|
|
113
|
+
idot : float
|
|
114
|
+
Rate of change of i (arc-min/yr).
|
|
115
|
+
igdgc : int
|
|
116
|
+
Flag for geodetic or geocentric coordinate choice.
|
|
117
|
+
irec_pos : int array
|
|
118
|
+
array of MAXMOD Record counter for header
|
|
119
|
+
fileline : int
|
|
120
|
+
Current line in file (for errors)
|
|
121
|
+
max1 : list, int
|
|
122
|
+
array of MAXMOD Main field coefficient.
|
|
123
|
+
max2 : list, int
|
|
124
|
+
array of MAXMOD Secular variation coefficient.
|
|
125
|
+
max3 : list, int
|
|
126
|
+
array of MAXMOD Acceleration coefficient.
|
|
127
|
+
minyr : float
|
|
128
|
+
Min year of all models
|
|
129
|
+
maxyr : float
|
|
130
|
+
Max year of all models
|
|
131
|
+
yrmax : list, float
|
|
132
|
+
array of MAXMOD Max year of model.
|
|
133
|
+
yrmin : list, float
|
|
134
|
+
array of MAXMOD Min year of model.
|
|
135
|
+
"""
|
|
136
|
+
def __init__(self, parent=None):
|
|
137
|
+
QtGui.QDialog.__init__(self, parent=None)
|
|
138
|
+
|
|
139
|
+
self.parent = parent
|
|
140
|
+
self.indata = {}
|
|
141
|
+
self.outdata = {}
|
|
142
|
+
self.reportback = self.parent.showprocesslog
|
|
143
|
+
self.pbar = self.parent.pbar
|
|
144
|
+
|
|
145
|
+
MAXDEG = 13
|
|
146
|
+
MAXCOEFF = (MAXDEG*(MAXDEG+2)+1)
|
|
147
|
+
|
|
148
|
+
self.gh = np.zeros([4, MAXCOEFF])
|
|
149
|
+
self.d = 0
|
|
150
|
+
self.f = 0
|
|
151
|
+
self.h = 0
|
|
152
|
+
self.i = 0
|
|
153
|
+
self.dtemp = 0
|
|
154
|
+
self.ftemp = 0
|
|
155
|
+
self.htemp = 0
|
|
156
|
+
self.itemp = 0
|
|
157
|
+
self.x = 0
|
|
158
|
+
self.y = 0
|
|
159
|
+
self.z = 0
|
|
160
|
+
self.xtemp = 0
|
|
161
|
+
self.ytemp = 0
|
|
162
|
+
self.ztemp = 0
|
|
163
|
+
self.xdot = 0
|
|
164
|
+
self.ydot = 0
|
|
165
|
+
self.zdot = 0
|
|
166
|
+
self.fdot = 0
|
|
167
|
+
self.hdot = 0
|
|
168
|
+
self.idot = 0
|
|
169
|
+
self.ddot = 0
|
|
170
|
+
|
|
171
|
+
self.dsb_alt = QtGui.QDoubleSpinBox()
|
|
172
|
+
self.dateedit = QtGui.QDateEdit()
|
|
173
|
+
self.combobox_dtm = QtGui.QComboBox()
|
|
174
|
+
self.combobox_mag = QtGui.QComboBox()
|
|
175
|
+
self.proj = dp.GroupProj('Input Projection')
|
|
176
|
+
|
|
177
|
+
self.setupui()
|
|
178
|
+
|
|
179
|
+
self.ctrans = None
|
|
180
|
+
|
|
181
|
+
def setupui(self):
|
|
182
|
+
""" Setup UI """
|
|
183
|
+
|
|
184
|
+
gridlayout = QtGui.QGridLayout(self)
|
|
185
|
+
buttonbox = QtGui.QDialogButtonBox()
|
|
186
|
+
helpdocs = menu_default.HelpButton('pygmi.raster.igrf')
|
|
187
|
+
|
|
188
|
+
label_0 = QtGui.QLabel()
|
|
189
|
+
label_1 = QtGui.QLabel()
|
|
190
|
+
label_2 = QtGui.QLabel()
|
|
191
|
+
label_3 = QtGui.QLabel()
|
|
192
|
+
|
|
193
|
+
buttonbox.setOrientation(QtCore.Qt.Horizontal)
|
|
194
|
+
buttonbox.setStandardButtons(buttonbox.Cancel | buttonbox.Ok)
|
|
195
|
+
|
|
196
|
+
self.dsb_alt.setMaximum(99999.9)
|
|
197
|
+
|
|
198
|
+
self.setWindowTitle("IGRF")
|
|
199
|
+
label_0.setText("Sensor clearance above ground")
|
|
200
|
+
label_1.setText("Date")
|
|
201
|
+
label_2.setText("Digital Elevation Model")
|
|
202
|
+
label_3.setText("Magnetic Data")
|
|
203
|
+
|
|
204
|
+
gridlayout.addWidget(self.proj, 0, 0, 1, 2)
|
|
205
|
+
gridlayout.addWidget(label_0, 2, 0, 1, 1)
|
|
206
|
+
gridlayout.addWidget(self.dsb_alt, 2, 1, 1, 1)
|
|
207
|
+
gridlayout.addWidget(label_1, 3, 0, 1, 1)
|
|
208
|
+
gridlayout.addWidget(self.dateedit, 3, 1, 1, 1)
|
|
209
|
+
gridlayout.addWidget(label_2, 4, 0, 1, 1)
|
|
210
|
+
gridlayout.addWidget(self.combobox_dtm, 4, 1, 1, 1)
|
|
211
|
+
gridlayout.addWidget(label_3, 5, 0, 1, 1)
|
|
212
|
+
gridlayout.addWidget(self.combobox_mag, 5, 1, 1, 1)
|
|
213
|
+
gridlayout.addWidget(buttonbox, 6, 1, 1, 1)
|
|
214
|
+
gridlayout.addWidget(helpdocs, 6, 0, 1, 1)
|
|
215
|
+
|
|
216
|
+
buttonbox.accepted.connect(self.accept)
|
|
217
|
+
buttonbox.rejected.connect(self.reject)
|
|
218
|
+
|
|
219
|
+
def acceptall(self):
|
|
220
|
+
""" Accept button"""
|
|
221
|
+
|
|
222
|
+
orig_wkt = self.proj.wkt
|
|
223
|
+
|
|
224
|
+
orig = osr.SpatialReference()
|
|
225
|
+
orig.ImportFromWkt(orig_wkt)
|
|
226
|
+
|
|
227
|
+
targ = osr.SpatialReference()
|
|
228
|
+
targ.SetWellKnownGeogCS('WGS84')
|
|
229
|
+
|
|
230
|
+
self.ctrans = osr.CoordinateTransformation(orig, targ)
|
|
231
|
+
|
|
232
|
+
# self.accept()
|
|
233
|
+
|
|
234
|
+
def settings(self):
|
|
235
|
+
"""
|
|
236
|
+
Settings Dialog. This is the main entrypoint into this routine. It also
|
|
237
|
+
contains the main IGRF code.
|
|
238
|
+
"""
|
|
239
|
+
# Variable declaration
|
|
240
|
+
# Control variables
|
|
241
|
+
self.proj.set_current(self.indata['Raster'][0].wkt)
|
|
242
|
+
|
|
243
|
+
data = dp.merge(self.indata['Raster'])
|
|
244
|
+
self.combobox_dtm.clear()
|
|
245
|
+
self.combobox_mag.clear()
|
|
246
|
+
for i in data:
|
|
247
|
+
self.combobox_dtm.addItem(i.dataid)
|
|
248
|
+
self.combobox_mag.addItem(i.dataid)
|
|
249
|
+
|
|
250
|
+
tmp = self.exec_()
|
|
251
|
+
|
|
252
|
+
if tmp == 1:
|
|
253
|
+
self.acceptall()
|
|
254
|
+
tmp = True
|
|
255
|
+
else:
|
|
256
|
+
return False
|
|
257
|
+
|
|
258
|
+
# again = 1
|
|
259
|
+
mdf = open(__file__.rpartition('\\')[0]+'\\IGRF11.cof')
|
|
260
|
+
modbuff = mdf.readlines()
|
|
261
|
+
fileline = -1 # First line will be 1
|
|
262
|
+
model = []
|
|
263
|
+
epoch = []
|
|
264
|
+
max1 = []
|
|
265
|
+
max2 = []
|
|
266
|
+
max3 = []
|
|
267
|
+
yrmin = []
|
|
268
|
+
yrmax = []
|
|
269
|
+
altmin = []
|
|
270
|
+
altmax = []
|
|
271
|
+
irec_pos = []
|
|
272
|
+
# First model will be 0
|
|
273
|
+
for i in modbuff:
|
|
274
|
+
fileline += 1 # On new line
|
|
275
|
+
if i[:3] == ' ':
|
|
276
|
+
i2 = i.split()
|
|
277
|
+
model.append(i2[0])
|
|
278
|
+
epoch.append(float(i2[1]))
|
|
279
|
+
max1.append(int(i2[2]))
|
|
280
|
+
max2.append(int(i2[3]))
|
|
281
|
+
max3.append(int(i2[4]))
|
|
282
|
+
yrmin.append(float(i2[5]))
|
|
283
|
+
yrmax.append(float(i2[6]))
|
|
284
|
+
altmin.append(float(i2[7]))
|
|
285
|
+
altmax.append(float(i2[8]))
|
|
286
|
+
irec_pos.append(fileline)
|
|
287
|
+
|
|
288
|
+
i = self.combobox_mag.currentIndex()
|
|
289
|
+
maggrid = data[i]
|
|
290
|
+
|
|
291
|
+
i = self.combobox_dtm.currentIndex()
|
|
292
|
+
data = data[i]
|
|
293
|
+
altgrid = data.data.flatten() * 0.001 # in km
|
|
294
|
+
|
|
295
|
+
maxyr = max(yrmax)
|
|
296
|
+
sdate = self.dateedit.date()
|
|
297
|
+
sdate = sdate.year()+sdate.dayOfYear()/sdate.daysInYear()
|
|
298
|
+
alt = self.dsb_alt.value()
|
|
299
|
+
xrange = data.tlx+data.xdim/2.+np.arange(data.cols)*data.xdim
|
|
300
|
+
yrange = data.tly-data.ydim/2.-np.arange(data.rows)*data.ydim
|
|
301
|
+
xdat, ydat = np.meshgrid(xrange, yrange)
|
|
302
|
+
xdat = xdat.flatten()
|
|
303
|
+
ydat = ydat.flatten()
|
|
304
|
+
|
|
305
|
+
igrf_F = altgrid * 0
|
|
306
|
+
# Pick model
|
|
307
|
+
yrmax = np.array(yrmax)
|
|
308
|
+
modelI = sum(yrmax < sdate)
|
|
309
|
+
igdgc = 1
|
|
310
|
+
|
|
311
|
+
if (sdate > maxyr) and (sdate < maxyr+1):
|
|
312
|
+
print("\nWarning: The date %4.2f is out of range,\n", sdate)
|
|
313
|
+
print("but still within one year of model expiration date.\n")
|
|
314
|
+
print("An updated model file is available before 1.1.%4.0f\n",
|
|
315
|
+
maxyr)
|
|
316
|
+
|
|
317
|
+
if max2[modelI] == 0:
|
|
318
|
+
self.getshc(modbuff, 1, irec_pos[modelI], max1[modelI], 0)
|
|
319
|
+
self.getshc(modbuff, 1, irec_pos[modelI+1], max1[modelI+1], 1)
|
|
320
|
+
nmax = self.interpsh(sdate, yrmin[modelI], max1[modelI],
|
|
321
|
+
yrmin[modelI+1], max1[modelI+1], 2)
|
|
322
|
+
nmax = self.interpsh(sdate+1, yrmin[modelI], max1[modelI],
|
|
323
|
+
yrmin[modelI+1], max1[modelI+1], 3)
|
|
324
|
+
else:
|
|
325
|
+
self.getshc(modbuff, 1, irec_pos[modelI], max1[modelI], 0)
|
|
326
|
+
self.getshc(modbuff, 0, irec_pos[modelI], max2[modelI], 1)
|
|
327
|
+
nmax = self.extrapsh(sdate, epoch[modelI], max1[modelI],
|
|
328
|
+
max2[modelI], 2)
|
|
329
|
+
nmax = self.extrapsh(sdate+1, epoch[modelI], max1[modelI],
|
|
330
|
+
max2[modelI], 3)
|
|
331
|
+
|
|
332
|
+
progress = 0
|
|
333
|
+
maxlen = xdat.size
|
|
334
|
+
|
|
335
|
+
for i in self.pbar.iter(range(maxlen)):
|
|
336
|
+
if igrf_F.mask[i] == True:
|
|
337
|
+
continue
|
|
338
|
+
|
|
339
|
+
tmp = int(i*100/maxlen)
|
|
340
|
+
if tmp > progress:
|
|
341
|
+
progress = tmp
|
|
342
|
+
# self.reportback('Calculation: ' + str(progress) + '%', True)
|
|
343
|
+
|
|
344
|
+
longitude, latitude, _ = self.ctrans.TransformPoint(xdat[i],
|
|
345
|
+
ydat[i])
|
|
346
|
+
alt = altgrid[i]
|
|
347
|
+
|
|
348
|
+
# Do the first calculations
|
|
349
|
+
self.shval3(igdgc, latitude, longitude, alt, nmax, 3)
|
|
350
|
+
self.dihf(3)
|
|
351
|
+
# self.shval3(igdgc, latitude, longitude, alt, nmax, 4)
|
|
352
|
+
# self.dihf(4)
|
|
353
|
+
#
|
|
354
|
+
# RAD2DEG = (180.0/np.pi)
|
|
355
|
+
#
|
|
356
|
+
# self.ddot = ((self.dtemp - self.d)*RAD2DEG)
|
|
357
|
+
# if self.ddot > 180.0:
|
|
358
|
+
# self.ddot -= 360.0
|
|
359
|
+
# if self.ddot <= -180.0:
|
|
360
|
+
# self.ddot += 360.0
|
|
361
|
+
# self.ddot *= 60.0
|
|
362
|
+
#
|
|
363
|
+
# self.idot = ((self.itemp - self.i)*RAD2DEG)*60
|
|
364
|
+
# self.d = self.d*(RAD2DEG)
|
|
365
|
+
# self.i = self.i*(RAD2DEG)
|
|
366
|
+
# self.hdot = self.htemp - self.h
|
|
367
|
+
# self.xdot = self.xtemp - self.x
|
|
368
|
+
# self.ydot = self.ytemp - self.y
|
|
369
|
+
# self.zdot = self.ztemp - self.z
|
|
370
|
+
# self.fdot = self.ftemp - self.f
|
|
371
|
+
#
|
|
372
|
+
# # deal with geographic and magnetic poles
|
|
373
|
+
#
|
|
374
|
+
# if self.h < 100.0: # at magnetic poles
|
|
375
|
+
# self.d = np.nan
|
|
376
|
+
# self.ddot = np.nan
|
|
377
|
+
# # while rest is ok
|
|
378
|
+
#
|
|
379
|
+
# if 90.0-abs(latitude) <= 0.001: # at geographic poles
|
|
380
|
+
# self.x = np.nan
|
|
381
|
+
# self.y = np.nan
|
|
382
|
+
# self.d = np.nan
|
|
383
|
+
# self.xdot = np.nan
|
|
384
|
+
# self.ydot = np.nan
|
|
385
|
+
# self.ddot = np.nan
|
|
386
|
+
|
|
387
|
+
# print('Test Data')
|
|
388
|
+
# print('==========')
|
|
389
|
+
#
|
|
390
|
+
# print('# Date 2014.5', sdate)
|
|
391
|
+
# print('# Coord-System D')
|
|
392
|
+
# print('# Altitude K100', alt)
|
|
393
|
+
# print('# Latitude 70.3', latitude)
|
|
394
|
+
# print('# Longitude 30.8', longitude)
|
|
395
|
+
# print('# D_deg 13d', int(self.d))
|
|
396
|
+
# print('# D_min 51m ', int((self.d-int(self.d))*60))
|
|
397
|
+
# print('# I_deg 78d', int(self.i))
|
|
398
|
+
# print('# I_min 55m', int((self.i-int(self.i))*60))
|
|
399
|
+
# print('# H_nT 9987.9 {0:.1f}'.format(self.h))
|
|
400
|
+
# print('# X_nT 9697.4 {0:.1f}'.format(self.x))
|
|
401
|
+
# print('# Y_nT 2391.4 {0:.1f}'.format(self.y))
|
|
402
|
+
# print('# Z_nT 51022.3 {0:.1f}'.format(self.z))
|
|
403
|
+
# print('# F_nT 51990.7 {0:.1f}'.format(self.f))
|
|
404
|
+
# print('# dD_min 10.9 {0:.1f}'.format(self.ddot))
|
|
405
|
+
# print('# dI_min 1.0 {0:.1f}'.format(self.idot))
|
|
406
|
+
# print('# dH_nT -10.4 {0:.1f}'.format(self.hdot))
|
|
407
|
+
# print('# dX_nT -17.7 {0:.1f}'.format(self.xdot))
|
|
408
|
+
# print('# dY_nT 28.1 {0:.1f}'.format(self.ydot))
|
|
409
|
+
# print('# dZ_nT 29.0 {0:.1f}'.format(self.zdot))
|
|
410
|
+
# print('# dF_nT 26.5 {0:.1f}'.format(self.fdot))
|
|
411
|
+
igrf_F[i] = self.f
|
|
412
|
+
|
|
413
|
+
self.outdata['Raster'] = copy.deepcopy(self.indata['Raster'])
|
|
414
|
+
igrf_F = np.ma.array(igrf_F)
|
|
415
|
+
igrf_F.shape = data.data.shape
|
|
416
|
+
igrf_F.mask = data.data.mask
|
|
417
|
+
self.outdata['Raster'].append(copy.deepcopy(data))
|
|
418
|
+
self.outdata['Raster'][-1].data = igrf_F
|
|
419
|
+
self.outdata['Raster'][-1].dataid = 'IGRF'
|
|
420
|
+
self.outdata['Raster'].append(copy.deepcopy(maggrid))
|
|
421
|
+
self.outdata['Raster'][-1].data -= igrf_F
|
|
422
|
+
self.outdata['Raster'][-1].dataid = 'Magnetic Data: IGRF Corrected'
|
|
423
|
+
|
|
424
|
+
self.reportback('Calculation: Completed', True)
|
|
425
|
+
|
|
426
|
+
return True
|
|
427
|
+
|
|
428
|
+
def getshc(self, file, iflag, strec, nmax_of_gh, gh):
|
|
429
|
+
"""
|
|
430
|
+
Reads spherical harmonic coefficients from the specified model into an
|
|
431
|
+
array.
|
|
432
|
+
|
|
433
|
+
| FORTRAN: Bill Flanagan, NOAA CORPS, DESDIS, NGDC, 325 Broadway,
|
|
434
|
+
| Boulder CO. 80301
|
|
435
|
+
| C: C. H. Shaffer, Lockheed Missiles and Space Company, Sunnyvale CA
|
|
436
|
+
|
|
437
|
+
Parameters
|
|
438
|
+
----------
|
|
439
|
+
file : file
|
|
440
|
+
reference to a file object
|
|
441
|
+
iflag :
|
|
442
|
+
Flag for SV equal to 1 or not equal to 1 for designated read
|
|
443
|
+
statements
|
|
444
|
+
strec : int
|
|
445
|
+
Starting record number to read from model
|
|
446
|
+
nmax_of_gh : int
|
|
447
|
+
Maximum degree and order of model
|
|
448
|
+
|
|
449
|
+
Returns
|
|
450
|
+
-------
|
|
451
|
+
gh : list
|
|
452
|
+
Schmidt quasi-normal internal spherical harmonic coefficients
|
|
453
|
+
"""
|
|
454
|
+
ii = -1
|
|
455
|
+
cnt = 0
|
|
456
|
+
|
|
457
|
+
for nn in range(1, nmax_of_gh+1):
|
|
458
|
+
for _ in range(nn+1):
|
|
459
|
+
cnt += 1
|
|
460
|
+
tmp = file[strec+cnt]
|
|
461
|
+
tmp = tmp.split()
|
|
462
|
+
# n = int(tmp[0])
|
|
463
|
+
m = int(tmp[1])
|
|
464
|
+
|
|
465
|
+
if iflag == 1:
|
|
466
|
+
g = float(tmp[2])
|
|
467
|
+
hh = float(tmp[3])
|
|
468
|
+
else:
|
|
469
|
+
g = float(tmp[4])
|
|
470
|
+
hh = float(tmp[5])
|
|
471
|
+
|
|
472
|
+
ii = ii + 1
|
|
473
|
+
self.gh[gh][ii] = g
|
|
474
|
+
|
|
475
|
+
if m != 0:
|
|
476
|
+
ii = ii + 1
|
|
477
|
+
self.gh[gh][ii] = hh
|
|
478
|
+
|
|
479
|
+
return
|
|
480
|
+
|
|
481
|
+
def extrapsh(self, date, dte1, nmax1, nmax2, gh):
|
|
482
|
+
"""
|
|
483
|
+
Extrapolates linearly a spherical harmonic model with a
|
|
484
|
+
rate-of-change model.
|
|
485
|
+
|
|
486
|
+
| FORTRAN : A. Zunde, USGS, MS 964, box 25046 Federal Center, Denver,
|
|
487
|
+
| CO. 80225
|
|
488
|
+
| C : C. H. Shaffer, Lockheed Missiles and Space Company, Sunnyvale CA
|
|
489
|
+
|
|
490
|
+
Parameters
|
|
491
|
+
----------
|
|
492
|
+
date : float
|
|
493
|
+
date of resulting model (in decimal year)
|
|
494
|
+
dte1 : float
|
|
495
|
+
date of base model
|
|
496
|
+
nmax1 : int
|
|
497
|
+
maximum degree and order of base model
|
|
498
|
+
gh : numpy array
|
|
499
|
+
Schmidt quasi-normal internal spherical harmonic coefficients of
|
|
500
|
+
base model and rate-of-change model
|
|
501
|
+
nmax2 : int
|
|
502
|
+
maximum degree and order of rate-of-change model
|
|
503
|
+
|
|
504
|
+
Returns
|
|
505
|
+
-------
|
|
506
|
+
gh : numpy array
|
|
507
|
+
Schmidt quasi-normal internal spherical harmonic coefficients
|
|
508
|
+
nmax : int
|
|
509
|
+
maximum degree and order of resulting model
|
|
510
|
+
"""
|
|
511
|
+
factor = date - dte1
|
|
512
|
+
if nmax1 == nmax2:
|
|
513
|
+
k = nmax1 * (nmax1 + 2)
|
|
514
|
+
nmax = nmax1
|
|
515
|
+
else:
|
|
516
|
+
if nmax1 > nmax2:
|
|
517
|
+
k = nmax2 * (nmax2 + 2)
|
|
518
|
+
l = nmax1 * (nmax1 + 2)
|
|
519
|
+
for ii in range(k, l):
|
|
520
|
+
self.gh[gh][ii] = self.gh[0][ii]
|
|
521
|
+
|
|
522
|
+
nmax = nmax1
|
|
523
|
+
else:
|
|
524
|
+
k = nmax1 * (nmax1 + 2)
|
|
525
|
+
l = nmax2 * (nmax2 + 2)
|
|
526
|
+
for ii in range(k, l):
|
|
527
|
+
self.gh[gh][ii] = factor * self.gh[1][ii]
|
|
528
|
+
|
|
529
|
+
nmax = nmax2
|
|
530
|
+
|
|
531
|
+
for ii in range(k):
|
|
532
|
+
self.gh[gh][ii] = self.gh[0][ii] + factor * self.gh[1][ii]
|
|
533
|
+
|
|
534
|
+
return nmax
|
|
535
|
+
|
|
536
|
+
def interpsh(self, date, dte1, nmax1, dte2, nmax2, gh):
|
|
537
|
+
"""
|
|
538
|
+
Interpolates linearly, in time, between two spherical harmonic
|
|
539
|
+
models.
|
|
540
|
+
|
|
541
|
+
| FORTRAN : A. Zunde, USGS, MS 964, box 25046 Federal Center, Denver,
|
|
542
|
+
| CO. 80225
|
|
543
|
+
| C : C. H. Shaffer, Lockheed Missiles and Space Company, Sunnyvale CA
|
|
544
|
+
|
|
545
|
+
Parameters
|
|
546
|
+
----------
|
|
547
|
+
date : float
|
|
548
|
+
date of resulting model (in decimal year)
|
|
549
|
+
dte1 : float
|
|
550
|
+
date of earlier model
|
|
551
|
+
nmax1 : int
|
|
552
|
+
maximum degree and order of earlier model
|
|
553
|
+
gh : numpy array
|
|
554
|
+
Schmidt quasi-normal internal spherical harmonic coefficients of
|
|
555
|
+
earlier model and internal model
|
|
556
|
+
dte2 : float
|
|
557
|
+
date of later model
|
|
558
|
+
nmax2 : int
|
|
559
|
+
maximum degree and order of later model
|
|
560
|
+
|
|
561
|
+
Returns
|
|
562
|
+
-------
|
|
563
|
+
gh : numpy array
|
|
564
|
+
coefficients of resulting model
|
|
565
|
+
nmax : int
|
|
566
|
+
maximum degree and order of resulting model
|
|
567
|
+
"""
|
|
568
|
+
factor = (date - dte1) / (dte2 - dte1)
|
|
569
|
+
if nmax1 == nmax2:
|
|
570
|
+
k = nmax1 * (nmax1 + 2)
|
|
571
|
+
nmax = nmax1
|
|
572
|
+
else:
|
|
573
|
+
if nmax1 > nmax2:
|
|
574
|
+
k = nmax2 * (nmax2 + 2)
|
|
575
|
+
l = nmax1 * (nmax1 + 2)
|
|
576
|
+
for ii in range(k, l):
|
|
577
|
+
self.gh[gh][ii] = self.gh[0][ii] + factor*(-self.gh[0][ii])
|
|
578
|
+
nmax = nmax1
|
|
579
|
+
else:
|
|
580
|
+
k = nmax1 * (nmax1 + 2)
|
|
581
|
+
l = nmax2 * (nmax2 + 2)
|
|
582
|
+
for ii in range(k, l):
|
|
583
|
+
self.gh[gh][ii] = factor * self.gh[1][ii]
|
|
584
|
+
|
|
585
|
+
nmax = nmax2
|
|
586
|
+
|
|
587
|
+
for ii in range(k):
|
|
588
|
+
self.gh[gh][ii] = self.gh[0][ii] + factor*(self.gh[1][ii] -
|
|
589
|
+
self.gh[0][ii])
|
|
590
|
+
|
|
591
|
+
return nmax
|
|
592
|
+
|
|
593
|
+
def shval3(self, igdgc, flat, flon, elev, nmax, gh):
|
|
594
|
+
"""
|
|
595
|
+
Calculates field components from spherical harmonic (sh) models.
|
|
596
|
+
|
|
597
|
+
Based on subroutine 'igrf' by D. R. Barraclough and S. R. C. Malin,
|
|
598
|
+
report no. 71/1, institute of geological sciences, U.K.
|
|
599
|
+
|
|
600
|
+
| FORTRAN : Norman W. Peddie, USGS, MS 964, box 25046 Federal Center,
|
|
601
|
+
| Denver, CO. 80225
|
|
602
|
+
| C : C. H. Shaffer, Lockheed Missiles and Space Company, Sunnyvale CA
|
|
603
|
+
|
|
604
|
+
Parameters
|
|
605
|
+
----------
|
|
606
|
+
igdgc : int
|
|
607
|
+
indicates coordinate system used set equal to 1 if geodetic, 2 if
|
|
608
|
+
geocentric
|
|
609
|
+
latitude : float
|
|
610
|
+
north latitude, in degrees
|
|
611
|
+
longitude : float
|
|
612
|
+
east longitude, in degrees
|
|
613
|
+
elev : float
|
|
614
|
+
WGS84 altitude above ellipsoid (igdgc=1), or radial distance from
|
|
615
|
+
earth's center (igdgc=2)
|
|
616
|
+
a2,b2 : float
|
|
617
|
+
squares of semi-major and semi-minor axes of the reference spheroid
|
|
618
|
+
used for transforming between geodetic and geocentric coordinates
|
|
619
|
+
or components
|
|
620
|
+
nmax : int
|
|
621
|
+
maximum degree and order of coefficients
|
|
622
|
+
|
|
623
|
+
Returns
|
|
624
|
+
-------
|
|
625
|
+
x : float
|
|
626
|
+
northward component
|
|
627
|
+
y : float
|
|
628
|
+
eastward component
|
|
629
|
+
z : float
|
|
630
|
+
vertically-downward component
|
|
631
|
+
"""
|
|
632
|
+
|
|
633
|
+
sl = np.zeros(14)
|
|
634
|
+
cl = np.zeros(14)
|
|
635
|
+
p = np.zeros(119)
|
|
636
|
+
q = np.zeros(119)
|
|
637
|
+
earths_radius = 6371.2
|
|
638
|
+
dtr = np.pi/180.0
|
|
639
|
+
a2 = 40680631.59 # WGS84
|
|
640
|
+
b2 = 40408299.98 # WGS84
|
|
641
|
+
r = elev
|
|
642
|
+
argument = flat * dtr
|
|
643
|
+
slat = sin(argument)
|
|
644
|
+
if (90.0 - flat) < 0.001:
|
|
645
|
+
aa = 89.999 # 300 ft. from North pole
|
|
646
|
+
elif (90.0 + flat) < 0.001:
|
|
647
|
+
aa = -89.999 # 300 ft. from South pole
|
|
648
|
+
else:
|
|
649
|
+
aa = flat
|
|
650
|
+
|
|
651
|
+
argument = aa * dtr
|
|
652
|
+
clat = cos(argument)
|
|
653
|
+
argument = flon * dtr
|
|
654
|
+
sl[1] = sin(argument)
|
|
655
|
+
cl[1] = cos(argument)
|
|
656
|
+
|
|
657
|
+
if gh == 3:
|
|
658
|
+
self.x = 0
|
|
659
|
+
self.y = 0
|
|
660
|
+
self.z = 0
|
|
661
|
+
elif gh == 4:
|
|
662
|
+
self.xtemp = 0
|
|
663
|
+
self.ytemp = 0
|
|
664
|
+
self.ztemp = 0
|
|
665
|
+
|
|
666
|
+
sd = 0.0
|
|
667
|
+
cd = 1.0
|
|
668
|
+
l = 0
|
|
669
|
+
n = 0
|
|
670
|
+
m = 1
|
|
671
|
+
npq = int((nmax * (nmax + 3)) / 2)
|
|
672
|
+
if igdgc == 1:
|
|
673
|
+
aa = a2 * clat * clat
|
|
674
|
+
bb = b2 * slat * slat
|
|
675
|
+
cc = aa + bb
|
|
676
|
+
argument = cc
|
|
677
|
+
dd = sqrt(argument)
|
|
678
|
+
argument = elev * (elev + 2.0 * dd) + (a2 * aa + b2 * bb) / cc
|
|
679
|
+
r = sqrt(argument)
|
|
680
|
+
cd = (elev + dd) / r
|
|
681
|
+
sd = (a2 - b2) / dd * slat * clat / r
|
|
682
|
+
aa = slat
|
|
683
|
+
slat = slat * cd - clat * sd
|
|
684
|
+
clat = clat * cd + aa * sd
|
|
685
|
+
|
|
686
|
+
ratio = earths_radius / r
|
|
687
|
+
argument = 3.0
|
|
688
|
+
aa = sqrt(argument)
|
|
689
|
+
p[1] = 2.0 * slat
|
|
690
|
+
p[2] = 2.0 * clat
|
|
691
|
+
p[3] = 4.5 * slat * slat - 1.5
|
|
692
|
+
p[4] = 3.0 * aa * clat * slat
|
|
693
|
+
q[1] = -clat
|
|
694
|
+
q[2] = slat
|
|
695
|
+
q[3] = -3.0 * clat * slat
|
|
696
|
+
q[4] = aa * (slat * slat - clat * clat)
|
|
697
|
+
for k in range(1, npq+1):
|
|
698
|
+
if n < m:
|
|
699
|
+
m = 0
|
|
700
|
+
n = n + 1
|
|
701
|
+
argument = ratio
|
|
702
|
+
power = n + 2
|
|
703
|
+
rr = pow(argument, power)
|
|
704
|
+
fn = n
|
|
705
|
+
|
|
706
|
+
fm = m
|
|
707
|
+
if k >= 5:
|
|
708
|
+
if m == n:
|
|
709
|
+
argument = (1.0 - 0.5/fm)
|
|
710
|
+
aa = sqrt(argument)
|
|
711
|
+
j = k - n - 1
|
|
712
|
+
p[k] = (1.0 + 1.0/fm) * aa * clat * p[j]
|
|
713
|
+
q[k] = aa * (clat * q[j] + slat/fm * p[j])
|
|
714
|
+
sl[m] = sl[m-1] * cl[1] + cl[m-1] * sl[1]
|
|
715
|
+
cl[m] = cl[m-1] * cl[1] - sl[m-1] * sl[1]
|
|
716
|
+
else:
|
|
717
|
+
argument = fn*fn - fm*fm
|
|
718
|
+
aa = sqrt(argument)
|
|
719
|
+
argument = ((fn - 1.0)*(fn-1.0)) - (fm * fm)
|
|
720
|
+
bb = sqrt(argument)/aa
|
|
721
|
+
cc = (2.0 * fn - 1.0)/aa
|
|
722
|
+
ii = k - n
|
|
723
|
+
j = k - 2 * n + 1
|
|
724
|
+
p[k] = (fn + 1.0) * (cc * slat/fn * p[ii] - bb/(fn - 1.0)
|
|
725
|
+
* p[j])
|
|
726
|
+
q[k] = cc * (slat * q[ii] - clat/fn * p[ii]) - bb * q[j]
|
|
727
|
+
|
|
728
|
+
if gh == 3:
|
|
729
|
+
aa = rr * self.gh[2][l]
|
|
730
|
+
elif gh == 4:
|
|
731
|
+
aa = rr * self.gh[3][l]
|
|
732
|
+
|
|
733
|
+
if m == 0:
|
|
734
|
+
if gh == 3:
|
|
735
|
+
self.x = self.x + aa * q[k]
|
|
736
|
+
self.z = self.z - aa * p[k]
|
|
737
|
+
elif gh == 4:
|
|
738
|
+
self.xtemp = self.xtemp + aa * q[k]
|
|
739
|
+
self.ztemp = self.ztemp - aa * p[k]
|
|
740
|
+
else:
|
|
741
|
+
print("\nError in subroutine shval3")
|
|
742
|
+
|
|
743
|
+
l = l + 1
|
|
744
|
+
else:
|
|
745
|
+
if gh == 3:
|
|
746
|
+
bb = rr * self.gh[2][l+1]
|
|
747
|
+
cc = aa * cl[m] + bb * sl[m]
|
|
748
|
+
self.x = self.x + cc * q[k]
|
|
749
|
+
self.z = self.z - cc * p[k]
|
|
750
|
+
if clat > 0:
|
|
751
|
+
self.y = (self.y + (aa*sl[m] - bb*cl[m])*fm *
|
|
752
|
+
p[k]/((fn + 1.0)*clat))
|
|
753
|
+
else:
|
|
754
|
+
self.y = self.y + (aa*sl[m] - bb*cl[m])*q[k]*slat
|
|
755
|
+
l = l + 2
|
|
756
|
+
elif gh == 4:
|
|
757
|
+
bb = rr * self.gh[3][l+1]
|
|
758
|
+
cc = aa * cl[m] + bb * sl[m]
|
|
759
|
+
self.xtemp = self.xtemp + cc * q[k]
|
|
760
|
+
self.ztemp = self.ztemp - cc * p[k]
|
|
761
|
+
if clat > 0:
|
|
762
|
+
self.ytemp = (self.ytemp + (aa*sl[m] - bb*cl[m])*fm *
|
|
763
|
+
p[k]/((fn + 1.0) * clat))
|
|
764
|
+
else:
|
|
765
|
+
self.ytemp = (self.ytemp + (aa*sl[m] - bb*cl[m]) *
|
|
766
|
+
q[k]*slat)
|
|
767
|
+
l = l + 2
|
|
768
|
+
|
|
769
|
+
m = m + 1
|
|
770
|
+
|
|
771
|
+
if gh == 3:
|
|
772
|
+
aa = self.x
|
|
773
|
+
self.x = self.x * cd + self.z * sd
|
|
774
|
+
self.z = self.z * cd - aa * sd
|
|
775
|
+
elif gh == 4:
|
|
776
|
+
aa = self.xtemp
|
|
777
|
+
self.xtemp = self.xtemp * cd + self.ztemp * sd
|
|
778
|
+
self.ztemp = self.ztemp * cd - aa * sd
|
|
779
|
+
|
|
780
|
+
def dihf(self, gh):
|
|
781
|
+
"""
|
|
782
|
+
Computes the geomagnetic d, i, h, and f from x, y, and z.
|
|
783
|
+
|
|
784
|
+
| FORTRAN : A. Zunde, USGS, MS 964, box 25046 Federal Center, Denver,
|
|
785
|
+
| CO. 80225
|
|
786
|
+
| C : C. H. Shaffer, Lockheed Missiles and Space Company, Sunnyvale CA
|
|
787
|
+
|
|
788
|
+
Parameters
|
|
789
|
+
----------
|
|
790
|
+
x : float
|
|
791
|
+
northward component
|
|
792
|
+
y : float
|
|
793
|
+
eastward component
|
|
794
|
+
z : float
|
|
795
|
+
vertically-downward component
|
|
796
|
+
|
|
797
|
+
Returns
|
|
798
|
+
-------
|
|
799
|
+
d : float
|
|
800
|
+
declination
|
|
801
|
+
i : float
|
|
802
|
+
inclination
|
|
803
|
+
h : float
|
|
804
|
+
horizontal intensity
|
|
805
|
+
f : float
|
|
806
|
+
total intensity
|
|
807
|
+
"""
|
|
808
|
+
sn = 0.0001
|
|
809
|
+
|
|
810
|
+
if gh == 3:
|
|
811
|
+
x = self.x
|
|
812
|
+
y = self.y
|
|
813
|
+
z = self.z
|
|
814
|
+
h = self.h
|
|
815
|
+
f = self.f
|
|
816
|
+
i = self.i
|
|
817
|
+
d = self.d
|
|
818
|
+
else:
|
|
819
|
+
x = self.xtemp
|
|
820
|
+
y = self.ytemp
|
|
821
|
+
z = self.ztemp
|
|
822
|
+
h = self.htemp
|
|
823
|
+
f = self.ftemp
|
|
824
|
+
i = self.itemp
|
|
825
|
+
d = self.dtemp
|
|
826
|
+
|
|
827
|
+
for _ in range(2):
|
|
828
|
+
h2 = x*x + y*y
|
|
829
|
+
argument = h2
|
|
830
|
+
h = sqrt(argument) # calculate horizontal intensity
|
|
831
|
+
argument = h2 + z*z
|
|
832
|
+
f = sqrt(argument) # calculate total intensity
|
|
833
|
+
if f < sn:
|
|
834
|
+
d = np.nan # If d and i cannot be determined,
|
|
835
|
+
i = np.nan # set equal to NaN
|
|
836
|
+
else:
|
|
837
|
+
argument = z
|
|
838
|
+
argument2 = h
|
|
839
|
+
i = atan2(argument, argument2)
|
|
840
|
+
if h < sn:
|
|
841
|
+
d = np.nan
|
|
842
|
+
else:
|
|
843
|
+
hpx = h + x
|
|
844
|
+
if hpx < sn:
|
|
845
|
+
d = np.pi
|
|
846
|
+
else:
|
|
847
|
+
argument = y
|
|
848
|
+
argument2 = hpx
|
|
849
|
+
d = 2.0 * atan2(argument, argument2)
|
|
850
|
+
|
|
851
|
+
if gh == 3:
|
|
852
|
+
self.h = h
|
|
853
|
+
self.f = f
|
|
854
|
+
self.i = i
|
|
855
|
+
self.d = d
|
|
856
|
+
else:
|
|
857
|
+
self.htemp = h
|
|
858
|
+
self.ftemp = f
|
|
859
|
+
self.itemp = i
|
|
860
|
+
self.dtemp = d
|