libmagdev ========= libmagdev is is library for computing the magnetic deviation (aka magnetic declination) at any point on the earth's surface by means of the IGRF model. magdev is a simple command-line program that uses libmagdev. libmagdev's web page is http://chezphil.org/libmagdev/ (C) 2009 Philip Endecott. libmagdev is distributed under the terms of the Boost Software License, version 1.0, which can be found in the file LICENSE. Introduction ------------ Magnetic deviation is the angle between the direction that a compass needle points (magnetic North) and the direction of the North Pole (true North). It varies with location and with time. The International Geomagnetic Reference Field is a mathematic model of the earth's magnetic field that can be used to compute a prediction of the magnetic field and hence the deviation. For more information about the IGRF, see http://www.ngdc.noaa.gov/IAGA/vmod/igrf.html. Note that the result produced by this program is relative to true N. In some cases you may actually need the angle relative to grid N for some particular map. To determine this you'll need to know the grid-to-true angle for that map; that calculation is beyond the scope of this code. Verifying your results ---------------------- PLEASE verify your results by comparing them with some other source of data; there are various web-based calculators and also the Geomag program described below. My own tests tend to show small but not negligible differences from the other calculators; I probably have some mistake somewhere that's causing this. Please report any discrepencies that you find to the author. This code has seen very little testing. A major motivation for making this code open-source is the hope that others will find (and hopefully fix) the remaining bugs. Using magdev ------------ The command-line program magdev can be used to compute the current predicted magnetic deviation given longitude and latitude values. It is used as follows: $ magdev -103.25 +51.29 9.008933 The command line parameters are longitude and latitude (in that order) in decimal degrees with E and N positive. The output is the deviation in decimal degrees with positive values indicating that magnetic N is E of true N. Using libmagdev --------------- To use libmagdev, include its header file and call magdev() as follows: float dev = magdev(time(NULL), lng, lat, alt_km); The first parameter is the time for which the prediction should be made as a time_t, i.e. seconds since the epoch. You will normally want to pass the current time. The second and third parameters give the location and the final one is the altitude in kilometres above sea level, which can normally be 0. The returned value may be NAN if an error occurs, for example if the requested time is before the start of the available models. Getting the code ---------------- The code is available only using subversion: $ svn co http://svn.chezphil.org/libmagdev/trunk libmagdev Installation ------------ You should be able to compile the library and command-line program by running "make" in the top-level directory. "sudo make install" will attempt to install things in /usr/local. This code should be somewhat portable, but no doubt some gcc-isms or similar have slipped in. If you need to make changes so that it works on your system do let me know. Ancestry -------- libmagdev is based on the Geomag 6.1 program which is linked from the noaa.gov page mentioned above. Geomag is a translation from FORTRAN to C and is the second most revolting piece of code I have ever had to look at. It hurt my eyes. I have attempted to remove most of the uglyness but the result is still far from good code, mainly because I don't know exactly what most of it is doing so I can't add sensible variable names. If you would like to further beautify the code please don't hesitate to do so, especially if you think you understand more of the maths than I do. Geomag appears to be in the public domain, which seems reasonable considering that it comes from a US government agency. How it works ------------ See the NOAA web page or this Wikipedia page: http://en.wikipedia.org/wiki/International_Geomagnetic_Reference_Field_-_IGRF for some mathematical background. The IGRF is a mathemetical model constructed to fit observations of the earth's magnetic field. A new set of parameters is published every five years. For historical calculations (i.e. before the last set of parameters was published), interpolation is used to determine an estimate of the field. For dates after the last set of parameters was published, extrapolation is carried out. It is necessary to update to new sets of parameters when they are published; the next set should appear this year (2009) ready for use starting in 2010. The data goes back to 1900. If you only care about current and future data you could exclude all of the old data; this would save of the order of 10 kbytes from the size of the library. In libmagdev these model parameters are compiled-in to the library. The alternative would be to have a data file that is read at run-time (this is what Geomag does). The advantages of compiling in the model parameters include less complexity (i.e. it doesn't need to worry about paths to any data files) and better run-time performance. (It takes of the order of a milisecond to compute one deviation.) The main disadvantage is that the library needs to be recompiled when new model parameters are published (and unless you use dynamic linking, applications will need to be re-linked). The parameters come from the text file IGRF10.txt. This is the IGRF10.unx file from the Geomag source. An awk script converts this to a set of C source fragments, which are included into the library when it is compiled. Operation of the library is as follows: - An appropriate pair of models for interpolation, or a model for extrapolation, is chosen based on the required date. - The necessary interpolation or extrapolation is performed to provide a model for the required date. - The model is evaluated at the required location to determine the X, Y and Z components of the magnetic field. - Simple trigonometry is used to determine the deviation angle from the vector. If you wanted to use the vector field components, or to perform the interpolation only once to save time when computing many deviations for the same date, then the library could easily be modified to do this. Change Log ---------- 2009-04-09 - first version.