From: <js...@us...> - 2009-09-10 11:36:24
|
Revision: 7731 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7731&view=rev Author: jswhit Date: 2009-09-10 11:36:16 +0000 (Thu, 10 Sep 2009) Log Message: ----------- fixes for date2index from David Huard 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-10 08:15:48 UTC (rev 7730) +++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/netcdftime.py 2009-09-10 11:36:16 UTC (rev 7731) @@ -966,42 +966,42 @@ return numpy.all( num2date(t, nctime.units, calendar) == dates) - def date2index(dates, nctime, calendar=None, select='exact'): """ date2index(dates, nctime, calendar=None, select='exact') - + Return indices of a netCDF time variable corresponding to the given dates. - + @param dates: A datetime object or a sequence of datetime objects. 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. The entries are assumed to be stored in increasing + 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' 'noleap', '365_day', '360_day', 'julian', 'all_leap', '366_day'}. 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. + 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: + + if calendar == None: calendar = getattr(nctime, 'calendar', 'standard') - + num = numpy.atleast_1d(date2num(dates, nctime.units, calendar)) - + # Trying to infer the correct index from the starting time and the stride. - # This assumes that the times are increasing uniformly. + # This assumes that the times are increasing uniformly. t0, t1 = nctime[:2] dt = t1 - t0 index = numpy.array((num-t0)/dt, int) @@ -1010,36 +1010,39 @@ # 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 - + + # Find the dates for which the match is not perfect. + # Use list comprehension instead of the simpler `nctime[index]` since + # not all time objects support numpy integer indexing (eg dap). + ncnum = numpy.squeeze([nctime[i] for i in index]) + mismatch = numpy.nonzero(ncnum != num)[0] + if select == 'exact': - if not (num2date(nctime[index], nctime.units) == dates).all(): - raise ValueError, 'Dates not found.' - + if len(mismatch) > 0: + raise ValueError, 'Some dates not found.' + elif select == 'before': - index[nomatch] -= 1 - + index[mismatch] -= 1 + elif select == 'after': pass - + elif select == 'nearest': - index[nomatch] = index[nomatch] - 1 * ( num[nomatch] < (nctime[index[nomatch]-1] + nctime[index[nomatch]]) / 2. ) - + nearest_to_left = num[mismatch] < numpy.array( [nctime[i-1] + nctime[i] for i in index[mismatch]]) / 2. + index[mismatch] = index[mismatch] - 1 * nearest_to_left + else: - raise ValueError, select - + raise ValueError("%s is not an option for the `select` argument."%select) + # convert numpy scalars or single element arrays to python ints. - index = _toscalar(index) + return _toscalar(index) - return index - def _toscalar(a): if a.shape in [(),(1,)]: return a.item() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |