-
Notifications
You must be signed in to change notification settings - Fork 1
/
GeomagnetismHeader.h
435 lines (326 loc) · 14.8 KB
/
GeomagnetismHeader.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
/* WMM Subroutine library was tested in the following environments
*
* 1. Red Hat Linux with GCC Compiler
* 2. MS Windows XP with CodeGear C++ compiler
* 3. Sun Solaris with GCC Compiler
*
*
* Revision Number: $Revision: 833 $
* Last changed by: $Author: awoods $
* Last changed on: $Date: 2012-04-16 14:01:51 -0600 (Mon, 16 Apr 2012) $
*
*
*/
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE
#endif
//#ifndef EPOCHRANGE
//#define EPOCHRANGE (int)5
//#endif
#define READONLYMODE "r"
#define MAXLINELENGTH (1024)
#define NOOFPARAMS (15)
#define NOOFCOEFFICIENTS (7)
#define _DEGREE_NOT_FOUND (-2)
#define CALCULATE_NUMTERMS(N) (N * ( N + 1 ) / 2 + N)
#ifndef WMMHEADER_H
#define WMMHEADER_H
#ifndef M_PI
#define M_PI ((2)*(acos(0.0)))
#endif
#define RAD2DEG(rad) ((rad)*(180.0L/M_PI))
#define DEG2RAD(deg) ((deg)*(M_PI/180.0L))
#define ATanH(x) (0.5 * log((1 + x) / (1 - x)))
#define TRUE ((int)1)
#define FALSE ((int)0)
#define MAG_PS_MIN_LAT_DEGREE -55 /* Minimum Latitude for Polar Stereographic projection in degrees */
#define MAG_PS_MAX_LAT_DEGREE 55 /* Maximum Latitude for Polar Stereographic projection in degrees */
#define MAG_UTM_MIN_LAT_DEGREE -80.5 /* Minimum Latitude for UTM projection in degrees */
#define MAG_UTM_MAX_LAT_DEGREE 84.5 /* Maximum Latitude for UTM projection in degrees */
#define MAG_GEO_POLE_TOLERANCE 1e-5
#define MAG_USE_GEOID 1 /* 1 Geoid - Ellipsoid difference should be corrected, 0 otherwise */
/*
Data types and prototype declaration for
World Magnetic Model (WMM) subroutines.
July 28, 2009
typedef struct {
double EditionDate;
double epoch; //Base time of Geomagnetic model epoch (yrs)
char ModelName[32];
double *Main_Field_Coeff_G; // C - Gauss coefficients of main geomagnetic model (nT)
double *Main_Field_Coeff_H; // C - Gauss coefficients of main geomagnetic model (nT)
double *Secular_Var_Coeff_G; // CD - Gauss coefficients of secular geomagnetic model (nT/yr)
double *Secular_Var_Coeff_H; // CD - Gauss coefficients of secular geomagnetic model (nT/yr)
int nMax; // Maximum degree of spherical harmonic model
int nMaxSecVar; //Maxumum degree of spherical harmonic secular model
int SecularVariationUsed; //Whether or not the magnetic secular variation vector will be needed by program
double CoefficientFileEndDate; //
} MAGtype_MagneticModel;
typedef struct {
double a; /*semi-major axis of the ellipsoid*/
double b; /*semi-minor axis of the ellipsoid*/
double fla; /* flattening */
double epssq; /*first eccentricity squared */
double eps; /* first eccentricity */
double re; /* mean radius of ellipsoid*/
} MAGtype_Ellipsoid;
typedef struct {
double lambda; // longitude
double phi; // geodetic latitude
double HeightAboveEllipsoid; // height above the ellipsoid (HaE)
double HeightAboveGeoid; /* (height above the EGM96 geoid model ) */
int UseGeoid;
} MAGtype_CoordGeodetic;
typedef struct {
double lambda; /* longitude*/
double phig; /* geocentric latitude*/
double r; /* distance from the center of the ellipsoid*/
} MAGtype_CoordSpherical;
typedef struct {
int Year;
int Month;
int Day;
double DecimalYear; /* decimal years */
} MAGtype_Date;
/*typedef struct {
int MAG_Mercator;
int MAG_LambertConformalConic;
int MAG_PolarStereographic;
int MAG_TransverseMercator;
} MAGtype_MapProjectionCode;
Deprecated, Will be removed in the next revision.*/
typedef struct {
double *Pcup; /* Legendre Function */
double *dPcup; /* Derivative of Legendre fcn */
} MAGtype_LegendreFunction;
typedef struct {
double Bx; /* North */
double By; /* East */
double Bz; /* Down */
} MAGtype_MagneticResults;
typedef struct {
double *RelativeRadiusPower; /* [earth_reference_radius_km / sph. radius ]^n */
double *cos_mlambda; /*cp(m) - cosine of (m*spherical coord. longitude)*/
double *sin_mlambda; /* sp(m) - sine of (m*spherical coord. longitude) */
} MAGtype_SphericalHarmonicVariables;
typedef struct {
double Decl; /* 1. Angle between the magnetic field vector and true north, positive east*/
double Incl; /*2. Angle between the magnetic field vector and the horizontal plane, positive down*/
double F; /*3. Magnetic Field Strength*/
double H; /*4. Horizontal Magnetic Field Strength*/
double X; /*5. Northern component of the magnetic field vector*/
double Y; /*6. Eastern component of the magnetic field vector*/
double Z; /*7. Downward component of the magnetic field vector*/
double GV; /*8. The Grid Variation*/
double Decldot; /*9. Yearly Rate of change in declination*/
double Incldot; /*10. Yearly Rate of change in inclination*/
double Fdot; /*11. Yearly rate of change in Magnetic field strength*/
double Hdot; /*12. Yearly rate of change in horizontal field strength*/
double Xdot; /*13. Yearly rate of change in the northern component*/
double Ydot; /*14. Yearly rate of change in the eastern component*/
double Zdot; /*15. Yearly rate of change in the downward component*/
double GVdot; /*16. Yearly rate of change in grid variation*/
} MAGtype_GeoMagneticElements;
typedef struct {
int NumbGeoidCols; /* 360 degrees of longitude at 15 minute spacing */
int NumbGeoidRows; /* 180 degrees of latitude at 15 minute spacing */
int NumbHeaderItems; /* min, max lat, min, max long, lat, long spacing*/
int ScaleFactor; /* 4 grid cells per degree at 15 minute spacing */
float *GeoidHeightBuffer;
int NumbGeoidElevs;
int Geoid_Initialized; /* indicates successful initialization */
int UseGeoid; /*Is the Geoid being used?*/
} MAGtype_Geoid;
typedef struct {
char Longitude[40];
char Latitude[40];
} MAGtype_CoordGeodeticStr;
typedef struct {
double Easting; /* (X) in meters*/
double Northing; /* (Y) in meters */
int Zone; /*UTM Zone*/
char HemiSphere;
double CentralMeridian;
double ConvergenceOfMeridians;
double PointScale;
} MAGtype_UTMParameters;
enum PARAMS {
SHDF,
MODELNAME,
PUBLISHER,
RELEASEDATE,
DATACUTOFF,
MODELSTARTYEAR,
MODELENDYEAR,
EPOCH,
INTSTATICDEG,
INTSECVARDEG,
EXTSTATICDEG,
EXTSECVARDEG,
GEOMAGREFRAD,
NORMALIZATION,
SPATBASFUNC
};
enum COEFFICIENTS {
IE,
N,
M,
GNM,
HNM,
DGNM,
DHNM
};
enum YYYYMMDD {
YEAR,
MONTH,
DAY
};
/*Prototypes */
/*Wrapper Functions*/
int MAG_Geomag(MAGtype_Ellipsoid Ellip,
MAGtype_CoordSpherical CoordSpherical,
MAGtype_CoordGeodetic CoordGeodetic,
MAGtype_MagneticModel *TimedMagneticModel,
MAGtype_GeoMagneticElements *GeoMagneticElements);
int MAG_Grid(MAGtype_CoordGeodetic minimum,
MAGtype_CoordGeodetic maximum,
double step_size,
double altitude_step_size,
double time_step,
MAGtype_MagneticModel *MagneticModel,
MAGtype_Geoid *geoid,
MAGtype_Ellipsoid Ellip,
MAGtype_Date StartDate,
MAGtype_Date EndDate,
int ElementOption,
int PrintOption,
char *OutputFile);
int MAG_robustReadMagneticModel_Large(char *filename, char* filenameSV, MAGtype_MagneticModel **MagneticModel, int array_size);
int MAG_robustReadMagModels(char *filename, MAGtype_MagneticModel *(*magneticmodels)[], int array_size);
int MAG_SetDefaults(MAGtype_Ellipsoid *Ellip, MAGtype_Geoid *Geoid);
/*User Interface*/
void MAG_Error(int control);
char MAG_GeomagIntroduction_WMM(MAGtype_MagneticModel *MagneticModel, char *VersionDate);
char MAG_GeomagIntroduction_EMM(MAGtype_MagneticModel *MagneticModel, char *VersionDate);
int MAG_GetUserGrid(MAGtype_CoordGeodetic *minimum,
MAGtype_CoordGeodetic *maximum,
double *step_size,
double *a_step_size,
double *step_time,
MAGtype_Date *StartDate,
MAGtype_Date *EndDate,
int *ElementOption,
int *PrintOption,
char *OutputFile,
MAGtype_Geoid *Geoid);
int MAG_GetUserInput(MAGtype_MagneticModel *MagneticModel,
MAGtype_Geoid *Geoid,
MAGtype_CoordGeodetic *CoordGeodetic,
MAGtype_Date *MagneticDate);
void MAG_PrintUserData(MAGtype_GeoMagneticElements GeomagElements,
MAGtype_CoordGeodetic SpaceInput,
MAGtype_Date TimeInput,
MAGtype_MagneticModel *MagneticModel,
MAGtype_Geoid *Geoid);
int MAG_ValidateDMSstringlat(char *input, char *Error);
int MAG_ValidateDMSstringlong(char *input, char *Error);
int MAG_Warnings(int control, double value, MAGtype_MagneticModel *MagneticModel);
/*Memory and File Processing*/
MAGtype_LegendreFunction *MAG_AllocateLegendreFunctionMemory(int NumTerms);
MAGtype_MagneticModel *MAG_AllocateModelMemory(int NumTerms);
MAGtype_SphericalHarmonicVariables *MAG_AllocateSphVarMemory(int nMax);
void MAG_AssignHeaderValues(MAGtype_MagneticModel *model, char values[][MAXLINELENGTH]);
void MAG_AssignMagneticModelCoeffs(MAGtype_MagneticModel *Assignee, MAGtype_MagneticModel *Source, int nMax, int nMaxSecVar);
int MAG_FreeMemory(MAGtype_MagneticModel *MagneticModel, MAGtype_MagneticModel *TimedMagneticModel, MAGtype_LegendreFunction *LegendreFunction);
int MAG_FreeLegendreMemory(MAGtype_LegendreFunction *LegendreFunction);
int MAG_FreeMagneticModelMemory(MAGtype_MagneticModel *MagneticModel);
int MAG_FreeSphVarMemory(MAGtype_SphericalHarmonicVariables *SphVar);
void MAG_PrintWMMFormat(char *filename, MAGtype_MagneticModel *MagneticModel);
void MAG_PrintEMMFormat(char *filename, char *filenameSV, MAGtype_MagneticModel *MagneticModel);
int MAG_readMagneticModel(char *filename, MAGtype_MagneticModel *MagneticModel);
int MAG_readMagneticModel_Large(char *filename, char *filenameSV, MAGtype_MagneticModel *MagneticModel);
int MAG_readMagneticModel_SHDF(char *filename, MAGtype_MagneticModel *(*magneticmodels)[], int array_size);
int MAG_swab_type();
char *MAG_Trim(char *str);
float MAG_FloatSwap(float f);
/*Conversions, Transformations, and other Calculations*/
int MAG_CalculateGeoMagneticElements(MAGtype_MagneticResults *MagneticResultsGeo, MAGtype_GeoMagneticElements *GeoMagneticElements);
int MAG_CalculateSecularVariationElements(MAGtype_MagneticResults MagneticVariation, MAGtype_GeoMagneticElements *MagneticElements);
int MAG_CalculateGridVariation(MAGtype_CoordGeodetic location, MAGtype_GeoMagneticElements *elements);
int MAG_DateToYear(MAGtype_Date *Calendar_Date, char *Error);
void MAG_DegreeToDMSstring(double DegreesOfArc, int UnitDepth, char *DMSstring);
void MAG_DMSstringToDegree(char *DMSstring, double *DegreesOfArc);
int MAG_GeodeticToSpherical(MAGtype_Ellipsoid Ellip, MAGtype_CoordGeodetic CoordGeodetic, MAGtype_CoordSpherical *CoordSpherical);
int MAG_GetTransverseMercator(MAGtype_CoordGeodetic CoordGeodetic, MAGtype_UTMParameters *UTMParameters);
int MAG_GetUTMParameters(double Latitude,
double Longitude,
int *Zone,
char *Hemisphere,
double *CentralMeridian);
int MAG_isNaN(double d);
int MAG_RotateMagneticVector(MAGtype_CoordSpherical,
MAGtype_CoordGeodetic CoordGeodetic,
MAGtype_MagneticResults MagneticResultsSph,
MAGtype_MagneticResults *MagneticResultsGeo);
void MAG_SphericalToCartesian(MAGtype_CoordSpherical CoordSpherical, double *x, double *y, double *z);
void MAG_TMfwd4(double Eps, double Epssq, double K0R4, double K0R4oa,
double Acoeff[], double Lam0, double K0, double falseE,
double falseN, int XYonly, double Lambda, double Phi,
double *X, double *Y, double *pscale, double *CoM); //Rewrite this?
int MAG_YearToDate(MAGtype_Date *Date);
/*Spherical Harmonics*/
int MAG_AssociatedLegendreFunction(MAGtype_CoordSpherical CoordSpherical, int nMax, MAGtype_LegendreFunction *LegendreFunction);
int MAG_CheckGeographicPole(MAGtype_CoordGeodetic *CoordGeodetic);
int MAG_ComputeSphericalHarmonicVariables(MAGtype_Ellipsoid Ellip,
MAGtype_CoordSpherical CoordSpherical,
int nMax,
MAGtype_SphericalHarmonicVariables * SphVariables);
int MAG_PcupHigh(double *Pcup, double *dPcup, double x, int nMax);
int MAG_PcupLow(double *Pcup, double *dPcup, double x, int nMax);
int MAG_SecVarSummation(MAGtype_LegendreFunction *LegendreFunction,
MAGtype_MagneticModel *MagneticModel,
MAGtype_SphericalHarmonicVariables SphVariables,
MAGtype_CoordSpherical CoordSpherical,
MAGtype_MagneticResults *MagneticResults);
int MAG_SecVarSummationSpecial(MAGtype_MagneticModel *MagneticModel,
MAGtype_SphericalHarmonicVariables SphVariables,
MAGtype_CoordSpherical CoordSpherical,
MAGtype_MagneticResults *MagneticResults);
int MAG_Summation(MAGtype_LegendreFunction *LegendreFunction,
MAGtype_MagneticModel *MagneticModel,
MAGtype_SphericalHarmonicVariables SphVariables,
MAGtype_CoordSpherical CoordSpherical,
MAGtype_MagneticResults *MagneticResults);
int MAG_SummationSpecial(MAGtype_MagneticModel *MagneticModel,
MAGtype_SphericalHarmonicVariables SphVariables,
MAGtype_CoordSpherical CoordSpherical,
MAGtype_MagneticResults *MagneticResults);
int MAG_TimelyModifyMagneticModel(MAGtype_Date UserDate, MAGtype_MagneticModel *MagneticModel, MAGtype_MagneticModel *TimedMagneticModel);
/*Geoid*/
int MAG_InitializeGeoid(MAGtype_Geoid *Geoid);
int MAG_ConvertGeoidToEllipsoidHeight(MAGtype_CoordGeodetic *CoordGeodetic, MAGtype_Geoid *Geoid);
/*
* The function Convert_Geoid_To_Ellipsoid_Height converts the specified WGS84
* geoid height at the specified geodetic coordinates to the equivalent
* ellipsoid height, using the EGM96 gravity model.
*
* Latitude : Geodetic latitude in radians (input)
* Longitude : Geodetic longitude in radians (input)
* Geoid_Height : Geoid height, in meters (input)
* Ellipsoid_Height : Ellipsoid height, in meters. (output)
*
*/
int MAG_GetGeoidHeight(double Latitude, double Longitude, double *DeltaHeight, MAGtype_Geoid *Geoid);
/*
* The private function Get_Geoid_Height returns the height of the
* WGS84 geiod above or below the WGS84 ellipsoid,
* at the specified geodetic coordinates,
* using a grid of height adjustments from the EGM96 gravity model.
*
* Latitude : Geodetic latitude in radians (input)
* Longitude : Geodetic longitude in radians (input)
* DeltaHeight : Height Adjustment, in meters. (output)
*
*/
#endif /*WMMHEADER_H*/