diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 62e266ac..c50a12bf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,7 +5,11 @@ name: pytest with flake8 -on: [push, pull_request] +on: + pull_request: + push: + schedule: + - cron: "0 3 * * 1" # Runs 03:00 UT on Mondays jobs: build: @@ -48,8 +52,8 @@ jobs: if: ${{ matrix.os == 'macos-latest' }} run: | brew reinstall gcc - python -m build . - pip install . + CC=/usr/local/bin/gcc-12 python -m build . + CC=/usr/local/bin/gcc-12 pip install . - name: Install on Windows if: ${{ matrix.os == 'windows-latest' }} diff --git a/.zenodo.json b/.zenodo.json index 4a648c9b..bd50446d 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -34,6 +34,10 @@ "affiliation": "Naval Research Laboratory", "name": "Burrell, Angeline G." }, + { + "orcid": "0000-0001-7098-0524", + "name": "Lamarche, Leslie L." + }, { "orcid": "0000-0002-3487-3630", "name": "Starr, Gregory" @@ -46,10 +50,6 @@ "orcid": "0000-0001-7955-4441", "affiliation": "GFZ German Research Centre for Geosciences", "name": "Morschhauser, Achim" - }, - { - "orcid": "0000-0001-7098-0524", - "name": "Lamarche, Leslie L." } ] } diff --git a/AUTHORS.rst b/AUTHORS.rst index a2cf4adb..ff49fa7a 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -7,10 +7,10 @@ This python wrapper is made by: * Karl M. Laundal * Christer van der Meeren * Angeline G. Burrell (maintainer) +* Leslie Lamarche * Gregory Starr * Ashton Reimer * Achim Morschhauser -* Leslie Lamarche Fortran code by Emmert et al. [2010] [1]_. Quasi-dipole and modified apex coordinates are defined by Richmond [1995] [2]_. The code uses @@ -19,7 +19,7 @@ IGRF-12 with coefficients valid through 2020 [Thébault et al., 2015] [3]_. .. [1] Emmert, J. T., A. D. Richmond, and D. P. Drob (2010), A computationally compact representation of Magnetic-Apex and Quasi-Dipole coordinates with smooth base vectors, - J. Geophys. Res., 115(A8), A08322, :doi:`10.1029/2010JA015326`. + J. Geophys. Res., 115(A8), A08322, doi:10.1029/2010JA015326. .. [2] Richmond, A. D. (1995), Ionospheric Electrodynamics Using Magnetic Apex Coordinates, Journal of geomagnetism and diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1eb1b91f..e2a961c4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,15 @@ Changelog ========= +2.0.1 (2023-04-11) +------------------ +* Expanded installation instructions in the documenation +* Added unit tests for todays date, ensuring that `apex.dat` is current +* Added cron unit test to GitHub Actions CI +* Added a logo +* Correct indexing bug in Fortran source that was causing array overflow and + memory errors for extrapolated years beyond the latest formal IGRF fit + 2.0.0 (2022-12-09) ------------------ * Update Fortran source code to Fortran 90 standards diff --git a/README.rst b/README.rst index bbc4d78b..b79a961d 100644 --- a/README.rst +++ b/README.rst @@ -1,3 +1,5 @@ +|logo| + ======== Overview ======== @@ -71,8 +73,7 @@ References .. [1] Emmert, J. T., A. D. Richmond, and D. P. Drob (2010), A computationally compact representation of Magnetic-Apex and Quasi-Dipole coordinates with smooth base vectors, - J. Geophys. Res., 115(A8), A08322, - `doi:10.1029/2010JA015326 `_. + J. Geophys. Res., 115(A8), A08322, doi:10.1029/2010JA015326. .. [2] Richmond, A. D. (1995), Ionospheric Electrodynamics Using Magnetic Apex Coordinates, Journal of geomagnetism and @@ -121,19 +122,19 @@ Badges .. |downloads| image:: https://img.shields.io/pypi/dm/apexpy.svg?style=flat :alt: PyPI Package monthly downloads - :target: https://pypi.python.org/pypi/apexpy + :target: https://pypi.org/project/apexpy .. |wheel| image:: https://img.shields.io/pypi/wheel/apexpy.svg?style=flat :alt: PyPI Wheel - :target: https://pypi.python.org/pypi/apexpy + :target: https://pypi.org/project/apexpy .. |supported-versions| image:: https://img.shields.io/pypi/pyversions/apexpy.svg?style=flat :alt: Supported versions - :target: https://pypi.python.org/pypi/apexpy + :target: https://pypi.org/project/apexpy .. |supported-implementations| image:: https://img.shields.io/pypi/implementation/apexpy.svg?style=flat :alt: Supported implementations - :target: https://pypi.python.org/pypi/apexpy + :target: https://pypi.org/project/apexpy .. |scrutinizer| image:: https://img.shields.io/scrutinizer/quality/g/aburrell/apexpy/main.svg?style=flat :alt: Scrutinizer Status @@ -141,3 +142,6 @@ Badges .. |doi| image:: https://www.zenodo.org/badge/doi/10.5281/zenodo.4585641.svg :target: https://doi.org/10.5281/zenodo.1214206 + +.. |logo| image:: docs/apexpy.png + :alt: ApexPy logo: yellow magnetic field lines surrounding the Earth's surface, which is blue diff --git a/apexpy/__init__.py b/apexpy/__init__.py index ecb54589..1895213f 100644 --- a/apexpy/__init__.py +++ b/apexpy/__init__.py @@ -12,5 +12,5 @@ from apexpy import helpers # noqa F401 # Define the global variables -__version__ = "2.0.0" +__version__ = "2.0.1" __all__ = ['Apex', 'fortranapex', 'helpers', 'ApexHeightError'] diff --git a/apexpy/apex.py b/apexpy/apex.py index 99245563..0c0d06be 100644 --- a/apexpy/apex.py +++ b/apexpy/apex.py @@ -980,7 +980,7 @@ def basevectors_qd(self, lat, lon, height, coords='geo', precision=1e-10): .. [3] Emmert, J. T., A. D. Richmond, and D. P. Drob (2010), A computationally compact representation of Magnetic-Apex and Quasi-Dipole coordinates with smooth base vectors, - J. Geophys. Res., 115(A8), A08322, :doi:`10.1029/2010JA015326`. + J. Geophys. Res., 115(A8), A08322, doi:10.1029/2010JA015326. """ # Convert from current coordinates to geodetic coordinates @@ -1079,7 +1079,7 @@ def basevectors_apex(self, lat, lon, height, coords='geo', precision=1e-10): .. [5] Emmert, J. T., A. D. Richmond, and D. P. Drob (2010), A computationally compact representation of Magnetic-Apex and Quasi-Dipole coordinates with smooth base vectors, - J. Geophys. Res., 115(A8), A08322, :doi:`10.1029/2010JA015326`. + J. Geophys. Res., 115(A8), A08322, doi:10.1029/2010JA015326. """ # Convert to geodetic coordinates from current coordinate system diff --git a/apexpy/apexsh.dat b/apexpy/apexsh.dat index a862b742..36e86fb0 100644 Binary files a/apexpy/apexsh.dat and b/apexpy/apexsh.dat differ diff --git a/apexpy/tests/test_Apex.py b/apexpy/tests/test_Apex.py index cff2775e..2fd3f0dc 100644 --- a/apexpy/tests/test_Apex.py +++ b/apexpy/tests/test_Apex.py @@ -108,6 +108,13 @@ def test_init_defaults(self): self.eval_refh() return + def test_init_today(self): + """Test Apex class initialization with today's date.""" + self.apex_out = apexpy.Apex(date=self.test_date) + self.eval_date() + self.eval_refh() + return + @pytest.mark.parametrize("in_date", [2015, 2015.5, dt.date(2015, 1, 1), dt.datetime(2015, 6, 1, 18, 23, 45)]) @@ -313,6 +320,13 @@ def get_input_args(self, method_name, precision=0.0): return in_args + def test_apex_conversion_today(self): + """Test Apex class conversion with today's date.""" + self.apex_out = apexpy.Apex(date=dt.datetime.utcnow(), refh=300) + assert not np.isnan(self.apex_out.geo2apex(self.in_lat, self.in_lon, + self.in_alt)).any() + return + @pytest.mark.parametrize("apex_method,fortran_method,fslice", [("_geo2qd", "apxg2q", slice(0, 2, 1)), ("_geo2apex", "apxg2all", slice(2, 4, 1)), @@ -1758,3 +1772,75 @@ def test_get_height_along_fieldline(self, lat, height): assert abs(height - fheight) < 1.0e-7, \ "bad height calculation: {:.7f} != {:.7f}".format(height, fheight) return + + +class TestApexMethodExtrapolateIGRF(object): + """Test the Apex methods on a year when IGRF must be extrapolated. + + Notes + ----- + Extrapolation should be done using a year within 5 years of the latest IGRF + model epoch. + + """ + + def setup_method(self): + """Initialize all tests.""" + self.apex_out = apexpy.Apex(date=2025, refh=300) + self.in_lat = 60 + self.in_lon = 15 + self.in_alt = 100 + self.in_time = dt.datetime(2024, 2, 3, 4, 5, 6) + return + + def teardown_method(self): + """Clean up after each test.""" + del self.apex_out, self.in_lat, self.in_lon, self.in_alt + return + + @pytest.mark.parametrize("method_name, out_comp", + [("geo2apex", + (56.25343704223633, 92.04932403564453)), + ("apex2geo", + (53.84184265136719, -66.93045806884766, + 3.6222547805664362e-06)), + ("geo2qd", + (56.82968521118164, 92.04932403564453)), + ("apex2qd", (60.498401178276744, 15.0)), + ("qd2apex", (59.49138097045895, 15.0))]) + def test_method_scalar_input(self, method_name, out_comp): + """Test the user method against set values with scalars. + + Parameters + ---------- + method_name : str + Apex class method to be tested + out_comp : tuple of floats + Expected output values + + """ + # Get the desired methods + user_method = getattr(self.apex_out, method_name) + + # Get the user output + user_out = user_method(self.in_lat, self.in_lon, self.in_alt) + + # Evaluate the user output + np.testing.assert_allclose(user_out, out_comp, rtol=1e-5, atol=1e-5) + + for out_val in user_out: + assert np.asarray(out_val).shape == (), "output is not a scalar" + return + + def test_convert_to_mlt(self): + """Test conversion from mlon to mlt with scalars.""" + + # Get user output + user_out = self.apex_out.mlon2mlt(self.in_lon, self.in_time) + + # Set comparison values + out_comp = 23.955474853515625 + + # Evaluate user output + np.testing.assert_allclose(user_out, out_comp, rtol=1e-5, atol=1e-5) + return diff --git a/apexpy/tests/test_cmd.py b/apexpy/tests/test_cmd.py index 0bf8f6a1..d01c518d 100644 --- a/apexpy/tests/test_cmd.py +++ b/apexpy/tests/test_cmd.py @@ -61,19 +61,19 @@ def execute_command_line(self, command, command_kwargs=None, or the requested output from the pipe command. """ - if command_kwargs is None: - command_kwargs = {} - - pipe = subprocess.Popen(command, **command_kwargs) - out = pipe.communicate() - pipe.wait() + data = None if pipe_out: - data = out - elif os.path.isfile(self.outfile): - data = np.loadtxt(self.outfile) + if command_kwargs is None: + command_kwargs = {} + + pipe = subprocess.Popen(command, **command_kwargs) + data = pipe.communicate() + pipe.wait() else: - data = None + os.system(" ".join(command)) + if os.path.isfile(self.outfile): + data = np.loadtxt(self.outfile) return data diff --git a/docs/apexpy.png b/docs/apexpy.png new file mode 100644 index 00000000..08cb6775 Binary files /dev/null and b/docs/apexpy.png differ diff --git a/docs/api.rst b/docs/api.rst index c808f2b8..3fc8568e 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -63,4 +63,4 @@ You can get help on the command by running ``apexpy -h``. .. [1] Emmert, J. T., A. D. Richmond, and D. P. Drob (2010), A computationally compact representation of Magnetic-Apex and Quasi-Dipole coordinates with smooth base vectors, - J. Geophys. Res., 115(A8), A08322, :doi:`10.1029/2010JA015326`. + J. Geophys. Res., 115(A8), A08322, doi:10.1029/2010JA015326. diff --git a/docs/conf.py b/docs/conf.py index f39f2385..2994989d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import json +import os import re extensions = ['sphinx.ext.autodoc', @@ -35,6 +36,9 @@ autoapi_keep_files = True autoapi_root = 'autoapi/generated' +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = os.path.join(os.path.abspath('.'), 'apexpy.png') # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. @@ -54,4 +58,4 @@ napoleon_use_rtype = False napoleon_use_param = False -extlinks = {'doi': ('http://dx.doi.org/%s', 'doi:')} +extlinks = {'doi': ('http://dx.doi.org/%s', 'doi:%s')} diff --git a/docs/examples/index.rst b/docs/ex_index.rst similarity index 59% rename from docs/examples/index.rst rename to docs/ex_index.rst index c87f20b1..f3a4a723 100644 --- a/docs/examples/index.rst +++ b/docs/ex_index.rst @@ -6,7 +6,7 @@ and support functions. .. toctree:: - ex_init.rst - ex_cli.rst - ex_apexh.rst - ex_gc.rst + examples/ex_init.rst + examples/ex_cli.rst + examples/ex_apexh.rst + examples/ex_gc.rst diff --git a/docs/index.rst b/docs/index.rst index 9922153f..7357dcb7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -7,7 +7,7 @@ Contents readme installation - examples/index + ex_index api contributing maintenance diff --git a/docs/installation.rst b/docs/installation.rst index 64f35906..9e08194b 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -42,7 +42,9 @@ The code behind this package is written in Fortran. Because of this, you the following steps. `Gfortran `_ is a free compiler that can be installed, if one is not already available on your system. If you are installing this or MinGW in Windows, make sure you install it -**after** installing the Windows Microsoft C++ Build tools. The :py:mod:`apexpy` +**after** installing the Windows Microsoft C++ Build tools. You must also make +sure that the compilers and Python that are installed both use the same +processing standard (either 32-bit or 64-bit). The :py:mod:`apexpy` installation has been tested successfully with gfortran 7 and some more recent versions. Earlier versions of gfortran may not work and are not recommended. @@ -125,10 +127,12 @@ To download an artifact: download location. Alternatively (or if this doesn't work) you can use `wget` to retrieve the archive. 4. Copy the zip archive into the ``apexpy/dist`` directory and unzip. -5. Check the archive for the expected matrix of *.whl objects +5. Check the archive for the expected matrix of ``*.whl`` objects To install, use ``pip install .`` +.. _installation-build: + Build from Source ^^^^^^^^^^^^^^^^^ @@ -215,6 +219,20 @@ encountered when using clang for ``CC`` alongside gfortran. This resulted in a seemly successful installation with :py:mod:`apexpy` reporting that fortranapex cannot be imported. +Some users have reported unusual behavior when using Anaconda on Apple Silicon +systems. Anaconda will attempt to build and install the Intel versions of +wheels instead of the M1 versions and run everything through Rosetta. This +configuration has not been fully evaluated, but it results in a seemly +successful installation with :py:mod:`apexpy` reporting that fortranapex +cannot be imported. Users should confirm that wheels created by conda (both for +apexpy and other packages) end in ``arm64.whl`` not ``osx-64.whl``. If the +later is true, users should consider uninstalling anaconda completely, and +instead installing miniconda following +`these instructions `_, +which has been confirmed to work. **WARNING:** This will remove any environments +you have set up and likely undo all IDE settings, so be cautious and consider +backing up your work first! + Windows systems are known to have issues with Fortran-based codes. The Windows testing we do uses miniconda, so we recommend using the Anaconda environment. diff --git a/docs/maintenance.rst b/docs/maintenance.rst index 964ae677..beba5c1b 100644 --- a/docs/maintenance.rst +++ b/docs/maintenance.rst @@ -16,74 +16,48 @@ Updating IGRF The `International Geomagnetic Reference Field `_ is regularly updated to reflect the most recent changes to the Terrestrial magnetic field. apexpy currently uses IRGF-13 coefficients, which are provided -in the ``apexpy/src/apexpy/igrf13coeff.txt`` file. To change or update the -magnetic field coefficients used by apexpy, you need to update the python code. -Assuming your new coefficient file has the same format, the process is simple: - -1. Clone the repository or your fork of the repository (see :ref:`contributing`) -2. Update ``apexpy/src/apexpy/apex.py`` variable ``igrf_fn`` by setting - it equal to the new target filename -3. Install the python package from the command line - (see :ref:`installation-cmd`) - -Updating ``apexsh.dat`` ------------------------ +in the ``apexpy/apexpy/igrf13coeff.txt`` file. To change or update the +magnetic field coefficients used by apexpy, you need to update the python code, +then rerun the fortran program that builds ``apexpy/apexpy/apexsh.dat``. This +is what makes apexpy performant. For more details, see Emmert et al. [2010] [1]_. -After updating the IGRF coefficients file the ``apexsh.dat`` file needs to be -rebuilt. This file is what makes apexpy performant. For more details, see -Emmert et al. [2010] [1]_. - -Updating ``apexsh.dat`` is done by modifying and building the fortran source -code in the ``apexpy/src/fortranapex`` directory. Working in that directory: +Assuming your new coefficient file has the same format, the process is simple: -1. Make sure a copy of the latest IGRF coefficient file is present in the - selfsame directory. -2. Modify the ``igrffilein`` in ``checkapexsh.f90`` to the name of the IGRF - coefficient file (``igrf13coeff.txt``, for example). -3. Modify ``checkapexsh.f90`` by adding the next 5 year epoch to the +1. Clone the repository or your fork of the repository (see :ref:`contributing`). +2. Update ``apexpy/apexpy/apex.py`` variable ``igrf_fn`` by setting + it equal to the new IGRF coefficient filename (``igrf13coeff.txt``, for example). +3. In ``apexpy/fortranapex/checkapexsh.f90``, update the variable ``igrffilein`` + to the new IGRF coefficent filename. Relative paths are allowed. +4. Modify ``checkapexsh.f90`` by adding the next 5 year epoch to the ``epochgrid`` variable and updating the ``nepochgrid`` variable as necessary. For example, if the newest IGRF coefficients are good up to 2025 and ``epochgrid`` only has up to the year 2020, then add 2025 to ``epochgrid`` and then increment ``nepochgrid`` by 1. -4. Build the ``apextest`` binary by running the ``make`` command. -5. Copy the IGRF coefficient file (``cp ../apexpy/igrf13coeff.txt``) into the - current directory. -6. Execute the ``apextest`` binary to generate the new ``apexsh.dat`` file. -7. Copy the new ``apexsh.dat`` file to the ``apexpy/src/apexpy`` directory. - -After updating the ``apexsh.dat`` file, some of the unit tests and the -documentation examples in the README and ``apexpy/docs/examples`` directory -will need to be updated as well. +5. Execute the ``apextest`` binary to generate the new ``apexsh.dat`` file. +6. Update the unit tests in the class ``TestApexMethodExtrapolateIGRF`` in + ``apexpy/apexpy/tests/test_Apex.py`` so that they check the methods are working + correctly with dates after the latest IGRF epoch (i.e., if the latest epoch is + 2020, set the test to initialize with the year 2025). You will have to update + the hard-coded confirmation values used by these tests. +7. Commit all changes and create a pull request on GitHub to integrate your + branch with updated IGRF into the main repository. Modifying Fortran Source ------------------------ When modifying the fortran source code, it can be helpful to run a preliminary -validation of the fortran output independent of the python wrapper. +validation of the fortran output independent of the python wrapper. This should +be done within the ``apexpy/fortranapex`` directory. 1. Remove any existing binaries by running the ``make clean`` command. 2. Build the ``apextest`` binary by running the ``make`` command. -3. Copy the IGRF coefficient file (``cp ../apexpy/igrf13coeff.txt``) into the - current directory. -4. Execute the ``apextext`` binary. -5. Confirm the output printed to the screen matches the test output shown in - the comment blot at the bottom of ``checkapexsh.f90``. - -The output may not match the test output exactly due to floating point errors -and improvements in the precision of the calculation. - -After updating the fortran source code, the signature file must be recreated so -the python wrapper works correctly. It is also a good idea to update -``apexsh.dat`` following the instructions above. Use `f2py `_ -to create a new signature file from the ``apexpy/src/fortranapex`` directory. -:: - - f2py -m fortranapex apexsh.f90 igrf.f90 apex.f90 magfld.f90 makeapexsh.f90 -h fortranapex.pyf --overwrite-signature - - -This will create the file ``fortranapex.pyf``. Then reinstall the package with -``pip`` from the root directory. If the modifications involved adding or -removing fortran source files, modify the list of extension sources in -``setup.py``. +3. Execute the ``apextext`` binary. +4. Confirm the output printed to the screen matches the test output shown in + the comment block at the bottom of ``checkapexsh.f90``. The output may not match + the test output exactly due to floating point errors and improvements in the + precision of the calculation. +5. If the modifications involved adding or removing fortran source files, modify the + list of extension sources in ``setup.cfg``. +6. Rebuild and install apexpy following the instructions in :ref:`installation-build`. Updating tests and style standards ----------------------------------- @@ -99,4 +73,4 @@ the current maintainer to ensure a minimal duplication of effort. .. [1] Emmert, J. T., A. D. Richmond, and D. P. Drob (2010), A computationally compact representation of Magnetic-Apex and Quasi-Dipole coordinates with smooth base vectors, - J. Geophys. Res., 115(A8), A08322, :doi:`10.1029/2010JA015326`. + J. Geophys. Res., 115(A8), A08322, doi:10.1029/2010JA015326. diff --git a/fortranapex/Makefile b/fortranapex/Makefile index d4904e77..a6428965 100644 --- a/fortranapex/Makefile +++ b/fortranapex/Makefile @@ -6,7 +6,7 @@ FC = gfortran # mpif90, ifort LD = $(FC) LDFLAGS = #-ipo -FFLAGS = -Wall -O3 -fPIC #-ipo -check bounds -check pointer -check uninit +FFLAGS = -Wall -O3 -fPIC -fcheck=all -fbounds-check -pedantic -Wextra #-ipo -check bounds -check pointer -check uninit SFLAGS = -static #-libgfortran -static-libgcc (AGB, static should work?) STATIC = 0 diff --git a/fortranapex/checkapexsh.f90 b/fortranapex/checkapexsh.f90 index e21b4164..a590bc30 100644 --- a/fortranapex/checkapexsh.f90 +++ b/fortranapex/checkapexsh.f90 @@ -27,8 +27,8 @@ program checkapexsh integer(4), parameter :: nepochgrid=26 ! integer(4), parameter :: nepochgrid=3 ! For testing/debugging integer(4) :: lmax=3, nmmax=6 - character(1000) :: apexshfile='apexsh.dat' - character(len=1000) :: igrffilein='igrf13coeffs.txt' + character(1000) :: apexshfile='../apexpy/apexsh.dat' + character(len=1000) :: igrffilein='../apexpy/igrf13coeffs.txt' real(8) :: epochgrid(0:nepochgrid - 1) real(8) :: epoch real(8) :: glat, glon, alt, hr, prec, error diff --git a/fortranapex/igrf.f90 b/fortranapex/igrf.f90 index 102ce27e..c3e46d10 100644 --- a/fortranapex/igrf.f90 +++ b/fortranapex/igrf.f90 @@ -48,16 +48,19 @@ subroutine read_igrf(filename_in) end do ! Read epochs - num_epochs = count([(s(i:i + 3), i = 1, len_trim(s))]== 'IGRF') - num_epochs = count([(s(i:i + 3), i = 1, len_trim(s))]== 'DGRF') + num_epochs + num_epochs = 0 + do i=1, len_trim(s) + if ((s(i:i+3) == 'IGRF').or.(s(i:i+3) == 'DGRF')) then + num_epochs = num_epochs + 1 + end if + end do allocate(epoch(1:num_epochs)) allocate(nmxe(1:num_epochs)) ! Read epochs - read(100,*, iostat = state) s - do i = 1, num_epochs - epoch(i) = 1900.0 + real(i - 1) * 5.0d0 - end do + read(unit = 100, fmt = '(A)', iostat = state) s + read(s(8:), *) epoch + ! Number of coefficients do i = 1, num_epochs @@ -89,7 +92,7 @@ subroutine read_igrf(filename_in) call fseek(100, offset, 0, state) ! Assign the variables for Gauss coefficients - allocate(g(1:num_sh, 1:num_epochs)) + allocate(g(1:num_sh, 1:num_epochs+1)) allocate(nm(1:num_sh, 2)) ! Read coefficients diff --git a/fortranapex/magfld.f90 b/fortranapex/magfld.f90 index 665b82c4..02ba761c 100644 --- a/fortranapex/magfld.f90 +++ b/fortranapex/magfld.f90 @@ -172,11 +172,11 @@ subroutine cofrm(date, filename) call exit(1) end if - ! Set the date and time - iy = 1 - do while (date > epoch(iy)) - iy = iy + 1 + ! Set the date and time index + do iy = 1, nepo + if (date < epoch(iy)) exit end do + iy = iy - 1 ngh = nght * nepo nmax1 = int(nmxe(iy)) diff --git a/meson.build b/meson.build index 1b2a19a9..e7f1556d 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project( 'apexpy', 'c', # Note that the git commit hash cannot be added dynamically here - version: '2.0.0', + version: '2.0.1', license: 'MIT', meson_version: '>= 0.63.0', default_options: [ diff --git a/setup.cfg b/setup.cfg index 730aae80..32900af3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = apexpy -version = 2.0.0 +version = 2.0.1 license = MIT description = "A Python wrapper for Apex coordinates" long_description = file: README.rst, CHANGELOG.rst