Skip to content

Commit

Permalink
Merge pull request #40 from aburrell/develop
Browse files Browse the repository at this point in the history
Version 2.5.2 release which includes:
- FutureWarning on depreciated functions
- No logbook dependency
- Updated version support
- Warnings for very high altitudes
- Better environment variable setting logic
  • Loading branch information
aburrell authored Sep 19, 2019
2 parents 059710e + e4961ed commit 00b82e5
Show file tree
Hide file tree
Showing 30 changed files with 1,114 additions and 557 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 2.5.1
current_version = 2.5.2
commit = True
tag = True

Expand Down
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
language: python
python:
- "2.7"
- "3.4"
- "3.5"
- "3.6"
- "3.7"
sudo: false
env:
global:
Expand Down
5 changes: 5 additions & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ Authors
* Angeline G. Burrell - https://github.com/aburrell
* Christer van der Meeren
* Karl M. Laundal

Thanks
======
* Marina Shmidt - Testing and code review
* Bill Rideout - Testing
12 changes: 12 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@

Changelog
=========
2.5.2 (2019-08-27)
-----------------------------------------
* Added FutureWarning to deprecated functions
* Updated names in licenses
* Moved module structure routine tests to their own class
* Added high altitude limit to avoid while-loop hanging
* Changed version support to 2.7, 3.6, and 3.7
* Removed logbook dependency
* Added logic to avoid reseting environment variables if not necessary
* Added copyright and license disclaimer to module-specific program files


2.5.1 (2018-10-19)
-----------------------------------------
* Commented out debug statement in C code
Expand Down
5 changes: 5 additions & 0 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ Bug reports, feature suggestions and other contributions are greatly
appreciated! While I can't promise to implement everything, I will always try
to respond in a timely manner.

You can also contribute by testing pull request or performing code reviews. If
you help out in ways that don't involve hacking the code, please add your name
under the **Thanks** header in the ``AUTHORS.rst`` file. We appreciate the
time you have given to improve this project.

Short version
=============

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) [2018] Burrell, van der Meeren, Laundal
Copyright (c) [2019] Burrell, van der Meeren, Laundal

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ include CONTRIBUTING.rst
include LICENSE
include LICENSE-AstAlg.txt
include README.rst
include CODE_OF_CONDUCT.md

include tox.ini .travis.yml appveyor.yml .codeclimate.yml .landscape.yaml

Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Space Physics, 119, 7501–7521, doi:10.1002/2014JA020264.
Quick start
===========

Install (requires NumPy and logging)::
Install (requires NumPy)::

pip install aacgmv2

Expand All @@ -33,7 +33,7 @@ Convert between AACGM and geographic coordinates::
>>> np.array(aacgmv2.get_aacgm_coord(60, 15, 300, dtime))
array([57.4698, 93.6300, 1.4822])
>>> # AACGM to geo, mix arrays/numbers
>>> aacgmv2.convert_latlon_arr([90, -90], 0, 0, dtime, code="A2G")
>>> aacgmv2.convert_latlon_arr([90, -90], 0, 0, dtime, method_code="A2G")
(array([82.9666, -74.3385]), array([-84.6652, 125.8401]), array([14.1244, 12.8771]))

Convert between AACGM and MLT::
Expand Down
74 changes: 44 additions & 30 deletions aacgmv2/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Copyright (C) 2019 NRL
# Author: Angeline Burrell
# Disclaimer: This code is under the MIT license, whose details can be found at
# the root in the LICENSE file
#
# -*- coding: utf-8 -*-
"""aacgmv2
Expand All @@ -10,6 +15,9 @@
Parameters
---------------------------------------------------------------------------
logger
high_alt_coeff
high_alt_trace
AACGM_V2_DAT_PREFIX
IGRF_12_COEFFS
_aacgmv2.G2A
Expand All @@ -30,6 +38,8 @@
convert
convert_mlt
wrapper.set_coeff_path
wrapper.test_height
wrapper.test_time
deprecated.subsol
_aacgmv2.convert
_aacgmv2.set_datetime
Expand All @@ -39,11 +49,31 @@
_aacgmv2.inv_mlt_convert_yrsec
---------------------------------------------------------------------------
"""
# Imports
#---------------------------------------------------------------------

import logging
import os as _os
from sys import stderr
import logbook as logging

__version__ = "2.5.1"
from aacgmv2.wrapper import (convert_latlon, convert_mlt, get_aacgm_coord)
from aacgmv2.wrapper import (convert_latlon_arr, get_aacgm_coord_arr)
from aacgmv2.wrapper import (convert_bool_to_bit, convert_str_to_bit)
from aacgmv2 import (deprecated)
from aacgmv2.deprecated import (convert)
from aacgmv2 import (_aacgmv2)

# Define global variables
#---------------------------------------------------------------------

__version__ = "2.5.2"

# Define a logger object to allow easier log handling
logger = logging.getLogger('aacgmv2_logger')

# Altitude constraints
high_alt_coeff = 2000.0 # Tested and published in Shepherd (2014)
high_alt_trace = 6378.0 # 1 RE, these are ionospheric coordinates

# path and filename prefix for the IGRF coefficients
AACGM_v2_DAT_PREFIX = _os.path.join(_os.path.realpath( \
Expand All @@ -53,39 +83,23 @@
'magmodel_1590-2015.txt')

# If not defined, set the IGRF and AACGM environment variables
reset_warn = False
__reset_warn__ = False
if 'IGRF_COEFFS' in _os.environ.keys():
stderr.write("resetting environment variable IGRF_COEFFS in python "
+ "script\n")
reset_warn = True
# Check and see if this environment variable is the same or different
if not _os.environ['IGRF_COEFFS'] == IGRF_COEFFS:
stderr.write("".join(["resetting environment variable IGRF_COEFFS in ",
"python script\n"]))
__reset_warn__ = True
_os.environ['IGRF_COEFFS'] = IGRF_COEFFS

if 'AACGM_v2_DAT_PREFIX' in _os.environ.keys():
stderr.write("resetting environment variable AACGM_v2_DAT_PREFIX in " +
"python script\n")
reset_warn = True
# Check and see if this environment variable is the same or different
if not _os.environ['AACGM_v2_DAT_PREFIX'] == AACGM_v2_DAT_PREFIX:
stderr.write("".join(["resetting environment variable ",
"AACGM_v2_DAT_PREFIX in python script\n"]))
__reset_warn__ = True
_os.environ['AACGM_v2_DAT_PREFIX'] = AACGM_v2_DAT_PREFIX

if reset_warn:
if __reset_warn__:
stderr.write("non-default coefficient files may be specified by running " +
"aacgmv2.wrapper.set_coeff_path before any other functions\n")
# Imports
#---------------------------------------------------------------------

try:
from aacgmv2.wrapper import (convert_latlon, convert_mlt, get_aacgm_coord)
from aacgmv2.wrapper import (convert_latlon_arr, get_aacgm_coord_arr)
from aacgmv2.wrapper import (convert_bool_to_bit, convert_str_to_bit)
except Exception as err:
logging.exception(__file__ + ' -> aacgmv2: ' + str(err))

try:
from aacgmv2 import (deprecated)
from aacgmv2.deprecated import (convert)
except Exception as err:
logging.exception(__file__ + ' -> aacgmv2: ' + str(err))

try:
from aacgmv2 import (_aacgmv2)
except Exception as err:
logging.exception(__file__ + ' -> aacgmv2: ' + str(err))
7 changes: 5 additions & 2 deletions aacgmv2/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Copyright (C) 2019 NRL
# Author: Angeline Burrell
# Disclaimer: This code is under the MIT license, whose details can be found at
# the root in the LICENSE file
#
# -*- coding: utf-8 -*-


"""Executed when aacgmv2 is invoked with python -m aacgmv2"""

from __future__ import division, print_function, absolute_import
Expand Down
5 changes: 5 additions & 0 deletions aacgmv2/aacgmv2module.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <stdio.h>

/*****************************************************************************
* Copyright (C) 2019 NRL
*
* Author: Angeline G. Burrell, UTDallas, April 2017
*
* Comments: python wrapper to AACGM functions based on test_aacgm.c
Expand All @@ -11,6 +13,9 @@
* coordinates: Definition and functional approximations, Journal
* of Geophysical Research: Space Physics, 119, p 7501-7521,
* doi:10.1002/2014JA020264
*
* Disclaimer: This code is under the MIT license, whose details can be found at
* the root in the LICENSE file
*****************************************************************************/

#include <Python.h>
Expand Down
39 changes: 32 additions & 7 deletions aacgmv2/deprecated.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Copyright (C) 2019 NRL
# Author: Angeline Burrell
# Disclaimer: This code is under the MIT license, whose details can be found at
# the root in the LICENSE file
#
# -*- coding: utf-8 -*-
"""Pythonic wrappers for AACGM-V2 C functions that were depricated in the
change from version 2.0.0 to version 2.0.2
Expand All @@ -15,11 +20,14 @@
Laundal, K. M. and A. D. Richmond (2016), Magnetic Coordinate Systems, Space
Sci. Rev., doi:10.1007/s11214-016-0275-y.
-------------------------------------------------------------------------------
"""

from __future__ import division, absolute_import, unicode_literals
import datetime as dt
import numpy as np
import logbook as logging
import warnings
import aacgmv2

def convert(lat, lon, alt, date=None, a2g=False, trace=False, allowtrace=False,
badidea=False, geocentric=False):
Expand Down Expand Up @@ -54,15 +62,17 @@ def convert(lat, lon, alt, date=None, a2g=False, trace=False, allowtrace=False,
lon_out : (float)
Output longitude in degrees E
"""
import aacgmv2

dstr = "Deprecated routine, will be removed in version 2.6. Recommend "
dstr += "using convert_latlon or convert_latlon_arr"
warnings.warn(dstr, category=FutureWarning)

if(np.array(alt).max() > 2000 and not trace and not allowtrace and
not badidea):
estr = 'coefficients are not valid for altitudes above 2000 km. You'
estr += ' must either use field-line tracing (trace=True '
estr += 'or allowtrace=True) or indicate you know this is a bad idea'
estr += ' (badidea=True)'
logging.error(estr)
raise ValueError(estr)

# construct a code from the boolian flags
Expand All @@ -73,7 +83,7 @@ def convert(lat, lon, alt, date=None, a2g=False, trace=False, allowtrace=False,

# convert location
lat_out, lon_out, _ = aacgmv2.convert_latlon_arr(lat, lon, alt, date,
code=bit_code)
method_code=bit_code)

return lat_out, lon_out

Expand Down Expand Up @@ -108,12 +118,19 @@ def subsol(year, doy, utime):
algorithm).
After Fortran code by A. D. Richmond, NCAR. Translated from IDL
by K. Laundal.
"""

dstr = "Deprecated routine, may be removed in future versions"
warnings.warn(dstr, category=FutureWarning)

# Convert from 4 digit year to 2 digit year
yr2 = year - 2000

if year >= 2101:
logging.error('subsol invalid after 2100. Input year is:', year)
aacgmv2.logger.error('subsol invalid after 2100. Input year is:', year)

# Determine if this year is a leap year
nleap = np.floor((year - 1601) / 4)
nleap = nleap - 99
if year <= 1900:
Expand All @@ -123,6 +140,8 @@ def subsol(year, doy, utime):
ncent = 3 - ncent
nleap = nleap + ncent

# Calculate some of the coefficients needed to deterimine the mean longitude
# of the sun and the mean anomaly
l_0 = -79.549 + (-0.238699 * (yr2 - 4 * nleap) + 3.08514e-2 * nleap)
g_0 = -2.472 + (-0.2558905 * (yr2 - 4 * nleap) - 3.79617e-2 * nleap)

Expand Down Expand Up @@ -177,6 +196,10 @@ def gc2gd_lat(gc_lat):
gd_lat : (same as input)
Geodetic latitude in degrees N
"""
dstr = "Deprecated routine, may be removed in future versions"
warnings.warn(dstr, category=FutureWarning)


wgs84_e2 = 0.006694379990141317 - 1.0
return np.rad2deg(-np.arctan(np.tan(np.deg2rad(gc_lat)) / wgs84_e2))

Expand All @@ -201,8 +224,10 @@ def igrf_dipole_axis(date):
work after IGRF updates. The dipole coefficients are interpolated to the
date, or extrapolated if date > latest IGRF model
"""
import datetime as dt
import aacgmv2

dstr = "Deprecated routine, may be removed in future versions"
warnings.warn(dstr, category=FutureWarning)


# get time in years, as float:
year = date.year
Expand Down
15 changes: 1 addition & 14 deletions aacgmv2/tests/test_c_aacgmv2.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import division, absolute_import, unicode_literals

import datetime as dt
import numpy as np
import pytest
import aacgmv2
Expand All @@ -23,18 +24,6 @@ def teardown(self):
del self.date_args, self.long_date, self.mlat, self.mlon, self.mlt
del self.lat_in, self.lon_in, self.alt_in

@classmethod
def test_module_structure(self):
"""Test module structure"""
assert aacgmv2
assert aacgmv2._aacgmv2
assert aacgmv2._aacgmv2.set_datetime
assert aacgmv2._aacgmv2.convert
assert aacgmv2._aacgmv2.inv_mlt_convert
assert aacgmv2._aacgmv2.inv_mlt_convert_yrsec
assert aacgmv2._aacgmv2.mlt_convert
assert aacgmv2._aacgmv2.mlt_convert_yrsec

def test_constants(self):
"""Test module constants"""
ans1 = aacgmv2._aacgmv2.G2A == 0
Expand Down Expand Up @@ -264,7 +253,6 @@ def test_inv_mlt_convert(self):

def test_inv_mlt_convert_yrsec(self):
"""Test MLT inversion with year and seconds of year"""
import datetime as dt
dtime = dt.datetime(*self.long_date)
soy = (int(dtime.strftime("%j"))-1) * 86400 + dtime.hour * 3600 + \
dtime.minute * 60 + dtime.second
Expand Down Expand Up @@ -303,7 +291,6 @@ def test_mlt_convert(self):

def test_mlt_convert_yrsec(self):
"""Test MLT calculation using year and seconds of year"""
import datetime as dt
dtime = dt.datetime(*self.long_date)
soy = (int(dtime.strftime("%j"))-1) * 86400 + dtime.hour * 3600 + \
dtime.minute * 60 + dtime.second
Expand Down
Loading

0 comments on commit 00b82e5

Please sign in to comment.