Skip to content

Commit

Permalink
Add startTime and endTime data arrays in mpas_xarray
Browse files Browse the repository at this point in the history
If the time coordinate is defined based on the average of a
start time and and end time (e.g xtime_start and xtime_end),
also store the start and end time for later use in accurately
performing time averages (e.g. computing climatologies).
  • Loading branch information
xylar committed Mar 29, 2017
1 parent 64abea5 commit ab92fff
Showing 1 changed file with 51 additions and 48 deletions.
99 changes: 51 additions & 48 deletions mpas_analysis/shared/mpas_xarray/mpas_xarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,59 +471,62 @@ def _parse_dataset_time(ds, inTimeVariableName, calendar,
ends = dsEnd[outTimeVariableName].values

# replace the time in starts with the mean of starts and ends
dsStart[outTimeVariableName] = [starts[i] +
(ends[i] - starts[i])/2
for i in range(len(starts))]

return dsStart

# The remainder of the function is for cases when there is just one time
# variable (either because we're recursively calling the function or
# because we're not averaging). The contents of the time variable is
# expected to be either a string (|S64) or a float (meaning days since
# start of the simulation).

timeVar = ds[inTimeVariableName]

if timeVar.dtype == '|S64':
# this is an array of date strings like 'xtime'
# convert to string
timeStrings = [''.join(xtime).strip() for xtime in timeVar.values]
days = string_to_days_since_date(dateString=timeStrings,
referenceDate=referenceDate,
calendar=calendar)
dsOut = dsStart.copy()

elif timeVar.dtype == 'float64':
# this array contains floating-point days like 'daysSinceStartOfSim'
dsOut['startTime'] = starts
dsOut['endTime'] = ends

if simulationStartTime is None:
raise ValueError('MPAS time variable {} appears to be a number of '
'days since start of sim but '
'simulationStartTime was not '
'supplied.'.format(inTimeVariableName))
dsOut[outTimeVariableName] = [starts[i] +
(ends[i] - starts[i])/2
for i in range(len(starts))]

if (string_to_datetime(referenceDate) ==
string_to_datetime(simulationStartTime)):
days = timeVar.values
else:
# a conversion may be required
dates = days_to_datetime(days=timeVar.values,
referenceDate=simulationStartTime,
calendar=calendar)
days = datetime_to_days(dates=dates,
referenceDate=referenceDate,
calendar=calendar)

elif timeVar.dtype == 'timedelta64[ns]':
raise TypeError("timeVar of unsupported type {}. This is likely "
"because xarray.open_dataset was called with "
"decode_times=True.".format(timeVar.dtype))
else:
raise TypeError("timeVar of unsupported type {}".format(
timeVar.dtype))

dsOut = ds.copy()
dsOut.coords[outTimeVariableName] = (outTimeVariableName, days)
# there is just one time variable (either because we're recursively
# calling the function or because we're not averaging).

# The contents of the time variable is expected to be either a string
# (|S64) or a float (meaning days since start of the simulation).

timeVar = ds[inTimeVariableName]

if timeVar.dtype == '|S64':
# this is an array of date strings like 'xtime'
# convert to string
timeStrings = [''.join(xtime).strip() for xtime in timeVar.values]
days = string_to_days_since_date(dateString=timeStrings,
referenceDate=referenceDate,
calendar=calendar)

elif timeVar.dtype == 'float64':
# this array contains floating-point days like
# 'daysSinceStartOfSim'

if simulationStartTime is None:
raise ValueError('MPAS time variable {} appears to be a number of days since start \n'
'of sim but simulationStartTime was not supplied.'.format(inTimeVariableName))

if (string_to_datetime(referenceDate) ==
string_to_datetime(simulationStartTime)):
days = timeVar.values
else:
# a conversion may be required
dates = days_to_datetime(days=timeVar.values,
referenceDate=simulationStartTime,
calendar=calendar)
days = datetime_to_days(dates=dates,
referenceDate=referenceDate,
calendar=calendar)

elif timeVar.dtype == 'timedelta64[ns]':
raise TypeError('timeVar of unsupported type {}. This is likely because xarray.open_dataset \n'
'was called with decode_times=True, which can mangle MPAS times.'.format(timeVar.dtype))
else:
raise TypeError("timeVar of unsupported type {}".format(
timeVar.dtype))

dsOut = ds.copy()
dsOut.coords[outTimeVariableName] = (outTimeVariableName, days)

return dsOut # }}}

Expand Down

0 comments on commit ab92fff

Please sign in to comment.