Skip to content

Commit

Permalink
Refined user guide. Bugfix in date routines. Obsolete keyword eng in …
Browse files Browse the repository at this point in the history
…date routines: use en instead.
  • Loading branch information
mcuntz committed Jul 6, 2020
1 parent bd58d3c commit 0c0f7af
Show file tree
Hide file tree
Showing 14 changed files with 297 additions and 285 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- PYTHON=python
- PIP=pip
before_install:
- choco install python --version 3.8.0
- choco install python --version 3.8.2
- export PATH="/c/Python38:/c/Python38/Scripts:$PATH"

env:
Expand Down
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

All notable changes after its initial release in May 2020 (v2.0) are documented in this file.

### v2.1 (May 2020)
### v2.1 (Jul 2020)
- Refined documentation.
- Use python3 for *nix and python for Windows on TravisCI.
- Use en instead of eng in date routines.
- Bugfix for Excel dates in date routines.

### v2.0.2 (May 2020)
- Finished setup in repositories with all dependencies, TWINE password, etc.
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ of the ICOS ecosystem site FR-Hes.

The package uses several functions of the JAMS Python package
https://github.com/mcuntz/jams_python
The JAMS package and *hesseflux* are synchronised irregularily.
The JAMS package and *hesseflux* are synchronised irregularly.

*hesseflux* includes a Python port of Logtools, the Logger Tools
Software of Olaf Kolle, MPI-BGC Jena, (c) 2012.
Expand Down Expand Up @@ -94,7 +94,8 @@ The project structure is based on a
## Contributing to hesseflux

Users are welcome to submit bug reports, feature requests, and code
contributions to this project through GitHub.
contributions to this project through GitHub.

More information is available in the
[Contributing](http://hesseflux.readthedocs.org/en/latest/contributing.html)
guidelines.
20 changes: 10 additions & 10 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,15 +248,15 @@ def setup(app):

# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
"Python 3.9": ("https://docs.python.org/3.9", None),
"Python 3.6": ("https://docs.python.org/3.6", None),
"Python": ("https://docs.python.org/", None),
"NumPy": ("http://docs.scipy.org/doc/numpy/", None),
"SciPy": ("http://docs.scipy.org/doc/scipy/reference/", None),
"matplotlib": ("http://matplotlib.org/", None),
"Pandas": ("https://pandas.pydata.org/docs/", None),
"Sphinx": ("https://sphinx.readthedocs.io/en/latest/", None),
"Python": ("https://docs.python.org/3/", None),
"NumPy": ("https://numpy.org/doc/stable/", None),
"SciPy": ("https://docs.scipy.org/doc/scipy/reference/", None),
"matplotlib": ("https://matplotlib.org/", None),
"cython": ("https://cython.readthedocs.io/en/latest/", None),
"Sphinx": ("https://www.sphinx-doc.org/en/master/", None),
"Pandas": ("https://pandas.pydata.org/docs/", None),
"schwimmbad": ("https://schwimmbad.readthedocs.io/en/latest/", None),
"mpi4py": ("https://mpi4py.readthedocs.io/en/latest/", None),
"emcee": ("https://emcee.readthedocs.io/en/latest/", None),
"mpi4py": ("https://mpi4py.readthedocs.io/en/latest/", None),
"emcee": ("https://emcee.readthedocs.io/en/latest/", None),
"pyeee": ("https://pyeee.readthedocs.io/en/latest/", None),
}
319 changes: 145 additions & 174 deletions docs/source/userguide.rst

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion hesseflux/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
The package uses several functions of the JAMS Python package
https://github.com/mcuntz/jams_python
The JAMS package and hesseflux are synchronised irregularily.
The JAMS package and hesseflux are synchronised irregularly.
hesseflux includes a Python port of Logtools, the Logger Tools
Software of Olaf Kolle, MPI-BGC Jena, (c) 2012.
Expand Down
4 changes: 2 additions & 2 deletions hesseflux/ascii2ascii.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
'ascii2en', 'ascii2fr', 'ascii2us', 'ascii2eng',
'en2ascii', 'fr2ascii', 'us2ascii', 'eng2ascii']


def ascii2ascii(edate, full=False, en=False, fr=False, us=False, eng=False, YY=False):
"""
Convert date notations between ascii DD.MM.YYYY hh:mm:ss, English YYYY-MM-DD hh:mm:ss,
Expand Down Expand Up @@ -455,7 +455,7 @@ def fr2ascii(edate, full=False, YY=False):
if YY:
import time as ptime
iyr2 = int(ptime.asctime()[-2:])
odate = [ d[0:6]+'19'+d[6:] if int(d[6:8]) > iyr2 else d[0:6]+'20'+d[6:] for d in odate ] # ascii -> ascii
odate = [ d[0:6]+'19'+d[6:] if int(d[6:8]) > iyr2 else d[0:6]+'20'+d[6:] for d in odate ] # ascii -> ascii

if full:
odate = [ (d+' 00:00:00')[:19] if len(d) < 11 else (d+':00:00')[:19] for d in odate ]
Expand Down
90 changes: 56 additions & 34 deletions hesseflux/date2dec.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
* mo for months always integer, Oct 2016, Matthias Cuntz
* 00, 01, etc. for integers not accepted by Python 3, removed from examples and code, Nov 2016, Matthias Cuntz
* Using numpy docstring format, May 2020, Matthias Cuntz
* Succeed eng by en keyword as in ascii2ascii and dec2date, Jul 2020, Matthias Cuntz
* proleptic_gregorian instead of gregorian calendar for Excel dates, Jul 2020, Matthias Cuntz
.. moduleauthor:: Matthias Cuntz, Arndt Piayda
Expand All @@ -45,7 +47,7 @@
def date2dec(calendar = 'standard', units=None,
excelerr = True, yr=1,
mo=1, dy=1, hr=0, mi=0, sc=0,
ascii=None, eng=None):
ascii=None, en=None, eng=None):
"""
Convert scalar and array_like with calendar dates into decimal
dates. Supported calendar formats are standard, gregorian, julian,
Expand Down Expand Up @@ -79,14 +81,16 @@ def date2dec(calendar = 'standard', units=None,
`ascii` overwrites all other keywords.
`ascii` and `eng` are mutually exclusive.
eng : array_like, optional
en : array_like, optional
strings of the format 'yyyy-mm-dd hh:mm:ss'.
Missing hour, minutes and/or seconds are set
to their default values (0).
`eng` overwrites all other keywords.
`en` overwrites all other keywords.
`eng` and `ascii` are mutually exclusive.
`en` and `ascii` are mutually exclusive.
eng : array_like, optional
Same as en: obsolete.
calendar : str, optional
Calendar of output dates (default: 'standard').
Expand Down Expand Up @@ -278,6 +282,14 @@ def date2dec(calendar = 'standard', units=None,
>>> print((date2dec(ascii='01.03.2003 00:00:00') - date2dec(ascii='01.03.2003')) == 0.)
True
# en
>>> decimal = date2dec(en='1992-01-26 02:00', calendar='decimal360')
>>> print('{:.7f}'.format(decimal))
1992.0696759
>>> decimal = date2dec(eng='1992-01-26 02:00', calendar='decimal360')
>>> print('{:.7f}'.format(decimal))
1992.0696759
History
-------
Written Arndt Piayda, Jun 2010
Expand All @@ -298,6 +310,8 @@ def date2dec(calendar = 'standard', units=None,
Matthias Cuntz, Oct 2016 - netcdftime provided even with netCDF4 > 1.0.0; make mo for months always integer
Matthias Cuntz, Nov 2016 - 00, 01, etc. for integers not accepted by Python3
Matthias Cuntz, May 2020 - numpy docstring format
Matthias Cuntz, Jul 2020 - en for eng
Matthias Cuntz, Jul 2020 - use proleptic_gregorian for Excel dates
"""
#
# Checks
Expand All @@ -322,17 +336,25 @@ def date2dec(calendar = 'standard', units=None,
if (calendar not in calendars):
raise ValueError("date2dec error: Wrong calendar!"
" Choose: "+''.join([i+' ' for i in calendars]))
# obsolete eng
if (eng is not None):
if (en is not None):
raise ValueError("date2dec error: 'eng' was succeeded by 'en'. Only one can be given.")
else:
en = eng
# if ascii input is given by user, other input will be neglected
# calculation of input size and shape
if (ascii is not None) and (eng is not None):
raise ValueError("date2dec error: 'ascii' and 'eng' mutually exclusive")
if ascii is not None:
if (ascii is not None) and (en is not None):
raise ValueError("date2dec error: 'ascii' and 'en' mutually exclusive")
if (ascii is not None):
islist = type(ascii) != type(np.array(ascii))
isarr = np.ndim(ascii)
if (islist & (isarr > 2)):
raise ValueError("date2dec error: ascii input is list > 2D; Use array input")
if isarr == 0: ascii = np.array([ascii])
else: ascii = np.array(ascii)
if isarr == 0:
ascii = np.array([ascii])
else:
ascii = np.array(ascii)
insize = ascii.size
outsize = insize
outshape = ascii.shape
Expand Down Expand Up @@ -371,22 +393,22 @@ def date2dec(calendar = 'standard', units=None,
timeobj[i] = nt.datetime(yr[i], 3, 1, hr[i], mi[i], sc[i])
else:
timeobj[i] = nt.datetime(yr[i], mo[i], dy[i], hr[i], mi[i], sc[i])
if eng is not None:
islist = type(eng) != type(np.array(eng))
isarr = np.ndim(eng)
if (en is not None):
islist = type(en) != type(np.array(en))
isarr = np.ndim(en)
if isarr == 0:
eng = np.array([eng])
en = np.array([en])
else:
eng = np.array(eng)
en = np.array(en)
if (islist & (isarr > 2)):
raise ValueError("date2dec error: eng input is list > 2D; Use array input")
eng = np.array(eng)
insize = eng.size
raise ValueError("date2dec error: en input is list > 2D; Use array input")
en = np.array(en)
insize = en.size
outsize = insize
outshape = eng.shape
engfl = eng.flatten()
outshape = en.shape
enfl = en.flatten()
timeobj = np.zeros(insize, dtype=object)
# slicing of eng strings to implement in datetime object. missing times
# slicing of en strings to implement in datetime object. missing times
# will be set to 0.
yr = np.zeros(insize, dtype=np.int)
mo = np.zeros(insize, dtype=np.int)
Expand All @@ -395,7 +417,7 @@ def date2dec(calendar = 'standard', units=None,
mi = np.zeros(insize, dtype=np.int)
sc = np.zeros(insize, dtype=np.int)
for i in range(insize):
ee = engfl[i].split('-')
ee = enfl[i].split('-')
yr[i] = int(ee[0])
mo[i] = int(ee[1])
tail = ee[2].split()
Expand All @@ -421,7 +443,7 @@ def date2dec(calendar = 'standard', units=None,
timeobj[i] = nt.datetime(yr[i], mo[i], dy[i], hr[i], mi[i], sc[i])
# if no ascii input, other inputs will be concidered
# calculation of input sizes, shapes and number of axis
if ((ascii is None) and (eng is None)):
if (ascii is None) and (en is None):
isnlist1 = type(yr) == type(np.array(yr))
isarr1 = np.ndim(yr)
if isarr1 == 0: yr = np.array([yr])
Expand Down Expand Up @@ -508,7 +530,7 @@ def date2dec(calendar = 'standard', units=None,
t1 = nt.datetime(1582, 10, 15, 0, 0, 0)
is121 = True if (min(timeobj)<t0) and (max(timeobj)>=t1) else False
if (calendar == 'standard') or (calendar == 'gregorian'):
if units is None:
if not units:
units = 'days since 0001-01-01 12:00:00'
dec0 = 1721424
else:
Expand All @@ -518,7 +540,7 @@ def date2dec(calendar = 'standard', units=None,
else:
output = nt.date2num(timeobj, units, calendar='gregorian')+dec0
elif calendar == 'julian':
if units is None:
if not units:
units = 'days since 0001-01-01 12:00:00'
dec0 = 1721424
else:
Expand All @@ -528,20 +550,20 @@ def date2dec(calendar = 'standard', units=None,
else:
output = nt.date2num(timeobj, units, calendar='julian')+dec0
elif calendar == 'proleptic_gregorian':
if units is None: units = 'days since 0001-01-01 00:00:00'
if not units: units = 'days since 0001-01-01 00:00:00'
if is121 and (nt.__version__ < '1.2.2'):
for ii, tt in enumerate(timeobj): output[ii] = nt.date2num(tt, units, calendar='proleptic_gregorian')
else:
output = nt.date2num(timeobj, units, calendar='proleptic_gregorian')
elif calendar == 'excel1900':
doerr = False
if units is None:
if not units:
units = 'days since 1899-12-31 00:00:00'
if excelerr: doerr = True
if is121 and (nt.__version__ < '1.2.2'):
for ii, tt in enumerate(timeobj): output[ii] = nt.date2num(tt, units, calendar='gregorian')
for ii, tt in enumerate(timeobj): output[ii] = nt.date2num(tt, units, calendar='proleptic_gregorian')
else:
output = nt.date2num(timeobj, units, calendar='gregorian')
output = nt.date2num(timeobj, units, calendar='proleptic_gregorian')
if doerr:
output = np.where(output >= 60., output+1., output)
# date2num treats 29.02.1900 as 01.03.1990, i.e. is the same decimal number
Expand All @@ -552,25 +574,25 @@ def date2dec(calendar = 'standard', units=None,
if (yr[i]==1900) & (mo[i]==2) & (dy[i]==29):
output[i] -= 1.
elif calendar == 'excel1904':
if units is None: units = 'days since 1903-12-31 00:00:00'
if not units: units = 'days since 1903-12-31 00:00:00'
if is121 and (nt.__version__ < '1.2.2'):
for ii, tt in enumerate(timeobj): output[ii] = nt.date2num(tt, units, calendar='gregorian')
for ii, tt in enumerate(timeobj): output[ii] = nt.date2num(tt, units, calendar='proleptic_gregorian')
else:
output = nt.date2num(timeobj, units, calendar='gregorian')
output = nt.date2num(timeobj, units, calendar='proleptic_gregorian')
elif (calendar == '365_day') or (calendar == 'noleap'):
if units is None: units = 'days since 0001-01-01 00:00:00'
if not units: units = 'days since 0001-01-01 00:00:00'
if is121 and (nt.__version__ < '1.2.2'):
for ii, tt in enumerate(timeobj): output[ii] = nt.date2num(tt, units, calendar='365_day')
else:
output = nt.date2num(timeobj, units, calendar='365_day')
elif (calendar == '366_day') or (calendar == 'all_leap'):
if units is None: units = 'days since 0001-01-01 00:00:00'
if not units: units = 'days since 0001-01-01 00:00:00'
if is121 and (nt.__version__ < '1.2.2'):
for ii, tt in enumerate(timeobj): output[ii] = nt.date2num(tt, units, calendar='366_day')
else:
output = nt.date2num(timeobj, units, calendar='366_day')
elif calendar == '360_day':
if units is None: units = 'days since 0001-01-01 00:00:00'
if not units: units = 'days since 0001-01-01 00:00:00'
if is121 and (nt.__version__ < '1.2.2'):
for ii, tt in enumerate(timeobj): output[ii] = nt.date2num(tt, units, calendar='360_day')
else:
Expand Down

0 comments on commit 0c0f7af

Please sign in to comment.