Revision: 7707
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7707&view=rev
Author:   jswhit
Date:     2009-09-08 12:06:35 +0000 (Tue, 08 Sep 2009)

Log Message:
-----------
update to latest version from netcdf4-python

Modified Paths:
--------------
    trunk/toolkits/basemap/lib/mpl_toolkits/basemap/netcdftime.py

Modified: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/netcdftime.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/netcdftime.py       
2009-09-08 01:53:12 UTC (rev 7706)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/netcdftime.py       
2009-09-08 12:06:35 UTC (rev 7707)
@@ -934,18 +934,38 @@
     cdftime = utime(units,calendar=calendar)
     return cdftime.num2date(times)
 
-
 def _check_index(indices, dates, nctime, calendar):
-    """Assert that the time indices given correspond to the given dates."""
-    t = numpy.empty(len(indices), nctime.dtype)
-    for n,i in enumerate(indices):
-        t[n] = nctime[i]
-    assert numpy.all( num2date(t, nctime.units, calendar) == dates)
+    """Return True if the time indices given correspond to the given dates, 
+    False otherwise.
+    
+    Parameters: 
 
+    indices : sequence of integers
+    Positive integers indexing the time variable.
 
-def date2index(dates, nctime, calendar=None):
+    dates : sequence of datetime objects
+    Reference dates.
+
+    nctime : netCDF Variable object
+    NetCDF time object.
+
+    calendar : string
+    Calendar of nctime.
+     """
+    if  (indices <0).any():
+       return False
+       
+    if (indices >= nctime.shape[0]).any():
+        return False
+        
+    t = nctime[indices] 
+    return numpy.all( num2date(t, nctime.units, calendar) == dates)
+
+
+
+def date2index(dates, nctime, calendar=None, select='exact'):
     """
-    date2index(dates, nctime, calendar=None)
+    date2index(dates, nctime, calendar=None, select='exact')
     
     Return indices of a netCDF time variable corresponding to the given dates.
     
@@ -953,7 +973,8 @@
     The datetime objects should not include a time-zone offset.
     
     @param nctime: A netCDF time variable object. The nctime object must have a
-    C{units} attribute.
+    C{units} attribute. The entries are assumed to be stored in increasing 
+    order.
     
     @param calendar: Describes the calendar used in the time calculation.
     Valid calendars C{'standard', 'gregorian', 'proleptic_gregorian'
@@ -961,32 +982,54 @@
     Default is C{'standard'}, which is a mixed Julian/Gregorian calendar
     If C{calendar} is None, its value is given by C{nctime.calendar} or
     C{standard} if no such attribute exists.
+    
+    @param select: C{'exact', 'before', 'after', 'nearest'}
+      The index selection method. C{exact} will return the indices perfectly 
+      matching the dates given. C{before} and C{after} will return the indices 
+      corresponding to the dates just before or just after the given dates if 
+      an exact match cannot be found. C{nearest} will return the indices that 
+      correpond to the closest dates. 
     """
     # Setting the calendar.
     if calendar is None:
         calendar = getattr(nctime, 'calendar', 'standard')
 
     num = numpy.atleast_1d(date2num(dates, nctime.units, calendar))
-
-    index = numpy.empty(numpy.alen(dates), int)
-
+    
     # Trying to infer the correct index from the starting time and the stride.
-    try:
-        t0, t1 = nctime[:2]
-        dt = t1 - t0
-        index[:] = (num-t0)/dt
+    # This assumes that the times are increasing uniformly. 
+    t0, t1 = nctime[:2]
+    dt = t1 - t0
+    index = numpy.array((num-t0)/dt, int)
 
-        # Checking that the index really corresponds to the given date.
-        _check_index(index, dates, nctime, calendar)
-
-    except AssertionError:
-
-        # If check fails, use brute force method.
-        index[:] = numpy.digitize(num, nctime[:]) - 1
-
-        # Perform check again.
-        _check_index(index, dates, nctime, calendar)
-
+    # Checking that the index really corresponds to the given date.
+    # If the times do not correspond, then it means that the times
+    # are not increasing uniformly and we try the bisection method.
+    if not _check_index(index, dates, nctime, calendar):
+    
+        # Use the bisection method. Assumes the dates are ordered.
+        import bisect
+        
+        index = numpy.array([bisect.bisect_left(nctime, n) for n in num], int)
+        
+        nomatch = num2date(nctime[index], nctime.units) != dates
+        
+        if select == 'exact':
+            if not (num2date(nctime[index], nctime.units) == dates).all():
+                raise ValueError, 'Dates not found.'
+    
+        elif select == 'before':
+            index[nomatch] -= 1
+        
+        elif select == 'after':
+            pass
+        
+        elif select == 'nearest':
+            index[nomatch] = index[nomatch] - 1 * ( num[nomatch] < 
(nctime[index[nomatch]-1] + nctime[index[nomatch]]) / 2. )
+        
+        else:
+            raise ValueError, select
+    
     # convert numpy scalars or single element arrays to python ints.
     index = _toscalar(index)
 


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to