11# -*- coding: utf-8 -*-
2- # Copyright (c) 2004-2014 Alterra, Wageningen-UR
3- # Allard de Wit ([email protected] ), April 2014 2+ # Copyright (c) 2004-2016 Alterra, Wageningen-UR
3+ # Allard de Wit ([email protected] ), October 2016 44"""Miscellaneous utilities for PCSE
55"""
66import os , sys
99from math import log10 , cos , sin , asin , sqrt , exp
1010from collections import namedtuple
1111from bisect import bisect_left
12- try :
13- # support both python2 and python3
14- from collections import MutableMapping
15- except ImportError :
16- from UserDict import DictMixin as MutableMapping
1712import textwrap
1813import sqlite3
19- import pdb
20-
21-
22- import numpy as np
2314
2415from . import exceptions as exc
2516
2617Celsius2Kelvin = lambda x : x + 273.16
2718hPa2kPa = lambda x : x / 10.
19+
2820# Saturated Vapour pressure [kPa] at temperature temp [C]
2921SatVapourPressure = lambda temp : 0.6108 * exp ((17.27 * temp ) / (237.3 + temp ))
3022
@@ -300,7 +292,7 @@ def penman_monteith(DAY, LAT, ELEV, TMIN, TMAX, AVRAD, VAP, WIND2):
300292
301293 return ET0
302294
303- #-------------------------------------------------------------------------------
295+
304296def check_angstromAB (xA , xB ):
305297 """Routine checks validity of Angstrom coefficients.
306298
@@ -388,16 +380,12 @@ def doy(day):
388380 """Converts a date or datetime object to day-of-year (Jan 1st = doy 1)
389381 """
390382 # Check if day is a date or datetime object
391- if isinstance (day , datetime .date ):
392- pass
393- elif isinstance (day , datetime .datetime ):
394- day = day .date ()
383+ if isinstance (day , (datetime .date , datetime .datetime )):
384+ return day .timetuple ().tm_yday
395385 else :
396386 msg = "Parameter day is not a date or datetime object."
397387 raise RuntimeError (msg )
398388
399- return (day - datetime .date (day .year ,1 ,1 )).days + 1
400-
401389
402390def limit (min , max , v ):
403391 """limits the range of v between min and max
@@ -603,7 +591,7 @@ def astro(day, latitude, radiation, _cache={}):
603591
604592 return retvalue
605593
606- #-------------------------------------------------------------------------------
594+
607595class Afgen (object ):
608596 """Emulates the AFGEN function in WOFOST.
609597
@@ -693,104 +681,6 @@ def __call__(self, x):
693681
694682 return v
695683
696- #-------------------------------------------------------------------------------
697- class Afgen2 (object ):
698- """Emulates the AFGEN function in TTUTIL with Numpy.interp
699-
700- :param tbl_xy: List or array of XY value pairs describing the function
701- the X values should be mononically increasing.
702- :param unit: The interpolated values is returned with given
703- `unit <http://pypi.python.org/pypi/Unum/4.1.0>`_ assigned.
704-
705- Returns the interpolated value provided with the
706- absicca value at which the interpolation should take place.
707-
708- example::
709-
710- >>> tbl_xy = [0,0,1,1,5,10]
711- >>> f = Afgen(tbl_xy)
712- >>> f(0.5)
713- 0.5
714- >>> f(1.5)
715- 2.125
716- >>> f(5)
717- 10.0
718- >>> f(6)
719- 10.0
720- >>> f(-1)
721- 0.0
722- """
723-
724- def __init__ (self , tbl_xy , unit = None ):
725-
726- x = tbl_xy [0 ::2 ]
727- y = tbl_xy [1 ::2 ]
728-
729- # Determine if there are empty pairs in tbl_xy by searching
730- # for the point where x stops monotonically increasing
731- xpos = np .arange (1 , len (x ))
732- ibreak = False
733- for i in xpos :
734- if x [i ] <= x [i - 1 ]:
735- ibreak = True
736- break
737-
738- if ibreak is True :
739- x = x [0 :i ]
740- y = y [0 :i ]
741-
742- self .x = x
743- self .y = y
744- self .unit = unit
745-
746- def __call__ (self , p ):
747-
748- v = np .interp (p , self .x , self .y )
749-
750- # if a unum unit is defined, multiply with a unit
751- if self .unit is not None :
752- v *= self .unit
753- return float (v )
754-
755- def __str__ (self ):
756- msg = "AFGEN interpolation over (X,Y) pairs:\n "
757- for (x ,y ) in zip (self .x , self .y ):
758- msg += ("(%f,%f)\n " % (x ,y ))
759- msg += "\n "
760- if self .unit is not None :
761- msg += "Return value as unit: %s" % self .unit
762- return msg
763-
764- #-------------------------------------------------------------------------------
765- class Chainmap (MutableMapping ):
766- """Combine multiple mappings for sequential lookup.
767-
768- For example, to emulate Python's normal lookup sequence:
769-
770- import __builtin__
771- pylookup = Chainmap(locals(), globals(), vars(__builtin__))
772-
773- recipe taken from http://code.activestate.com/recipes/305268/
774- Available natively in the connections module in python 3.3
775- """
776-
777- def __init__ (self , * maps ):
778- self ._maps = maps
779-
780- def __getitem__ (self , key ):
781- for mapping in self ._maps :
782- try :
783- return mapping [key ]
784- except KeyError :
785- pass
786- raise KeyError (key )
787-
788- def keys (self ):
789- k = []
790- for mapping in self ._maps :
791- return k .extend (mapping .keys )
792- return k
793-
794684
795685def merge_dict (d1 , d2 , overwrite = False ):
796686 """Merge contents of d1 and d2 and return the merged dictionary
@@ -909,9 +799,9 @@ def is_a_month(day):
909799 if (day == datetime .date (day .year , day .month + 1 , 1 ) - \
910800 datetime .timedelta (days = 1 )):
911801 return True
912-
913802 return False
914803
804+
915805def is_a_week (day , weekday = 0 ):
916806 """Default weekday is Monday. Monday is 0 and Sunday is 6"""
917807 if day .weekday () == weekday :
@@ -938,9 +828,9 @@ def is_a_dekad(day):
938828 elif (day == datetime .date (day .year , day .month + 1 , 1 ) -
939829 datetime .timedelta (days = 1 )):
940830 return True
941-
942831 return False
943832
833+
944834def load_SQLite_dump_file (dump_file_name , SQLite_db_name ):
945835 """Build an SQLite database <SQLite_db_name> from dump file <dump_file_name>.
946836 """
@@ -952,6 +842,7 @@ def load_SQLite_dump_file(dump_file_name, SQLite_db_name):
952842 con .executescript (str_sql_dump )
953843 con .close ()
954844
845+
955846def safe_float (x ):
956847 """Returns the value of x converted to float, if fails return None.
957848 """
@@ -960,6 +851,7 @@ def safe_float(x):
960851 except (ValueError , TypeError ):
961852 return None
962853
854+
963855def check_date (indate ):
964856 """Check representations of date and try to force into a datetime.date
965857
0 commit comments