def generate_release_timeseries(self, num_ts, max_release, ts): ''' Release timeseries describe release behavior as a function of time. _release_ts describes the number of LEs that should exist at time T _pos_ts describes the spill position at time T All use TimeseriesData objects. ''' t = None if num_ts == 1: #This is a special case, when the release is short enough a single #timestep encompasses the whole thing. if self.release_duration == 0: t = Time([ self.release_time, self.end_release_time + timedelta(seconds=1) ]) else: t = Time([self.release_time, self.end_release_time]) else: t = Time([ self.release_time + timedelta(seconds=ts * step) for step in range(0, num_ts + 1) ]) t.data[-1] = self.end_release_time if self.release_duration == 0: self._release_ts = TimeseriesData(name=self.name + '_release_ts', time=t, data=np.full( t.data.shape, max_release).astype(int)) else: self._release_ts = TimeseriesData(name=self.name + '_release_ts', time=t, data=np.linspace( 0, max_release, num_ts + 1).astype(int)) lon_ts = TimeseriesData(name=self.name + '_lon_ts', time=t, data=np.linspace(self.start_position[0], self.end_position[0], num_ts + 1)) lat_ts = TimeseriesData(name=self.name + '_lat_ts', time=t, data=np.linspace(self.start_position[1], self.end_position[1], num_ts + 1)) z_ts = TimeseriesData(name=self.name + '_z_ts', time=t, data=np.linspace(self.start_position[2], self.end_position[2], num_ts + 1)) self._pos_ts = TimeseriesVector(name=self.name + '_pos_ts', time=t, variables=[lon_ts, lat_ts, z_ts])
def get_tsv_instance(self, dates, series_data, series_data2): _t = Time(dates) return TimeseriesVector(variables=[ TimeseriesData(name='u', time=_t, data=series_data), TimeseriesData(name='v', time=_t, data=series_data2) ], units='m/s')
def build_test_instance(self, dates, series_data, series_data2): times = Time(dates) return TimeseriesVector(variables=[ TimeseriesData(name='u', time=times, data=series_data), TimeseriesData(name='v', time=times, data=series_data2) ], units='m/s')
def demo(cls): _t = Time(dates()) tsv = TimeseriesVector(variables=[ TimeseriesData(name='u', time=_t, data=series_data()), TimeseriesData(name='v', time=_t, data=series_data2()) ], units='m/s') return DemoObj(variable=tsv, variables=[tsv, tsv.variables[0]])
def test_save_load(self, dates): t = Time(dates) saveloc = tempfile.mkdtemp() saveloc = os.path.join(saveloc, 'test.zip') _references = t.save(saveloc) new_instance = self.test_class.load(saveloc) assert t == new_instance
def time(self, t): if self.data is not None and len(t) != len(self.data): warnings.warn("Data/time interval mismatch, doing nothing") return if isinstance(t, Time): self._time = t elif isinstance(t, collections.Iterable): self._time = Time(t) else: raise ValueError('Object being assigned must be an iterable ' 'or a Time object')
def test_save_load(self, dates, series_data, series_data2): times = Time(dates) tsv = TimeseriesVector(variables=[ TimeseriesData(name='u', time=times, data=series_data), TimeseriesData(name='v', time=times, data=series_data2) ], units='m/s') inst = DemoObj(filename=None, variable=tsv, variables=[tsv, tsv.variables[0]]) saveloc = tempfile.mkdtemp() _json_, zipfile_, _refs = inst.save(saveloc=saveloc) loaded = DemoObj.load(zipfile_) assert inst == loaded
def test_construction(self, dates): t = Time(dates) assert t.min_time == t.data[0] == dt.datetime(2000, 1, 1, 0) assert t.max_time == t.data[-1] == dt.datetime(2000, 1, 1, 8) dates = [ dt.datetime(2000, 1, 1, 0), dt.datetime(2000, 1, 1, 2), dt.datetime(2000, 1, 1, 4), dt.datetime(2000, 1, 1, 6), dt.datetime(2000, 1, 1, 8) ] t2 = self.test_class(dates) assert t == t2
def test_serialization(self, dates, series_data, series_data2): filename = 'foo.nc' times = Time(dates) tsv = TimeseriesVector(variables=[ TimeseriesData(name='u', time=times, data=series_data), TimeseriesData(name='v', time=times, data=series_data2) ], units='m/s') inst = DemoObj(filename=filename, variable=tsv, variables=[tsv, tsv.variables[0]]) serial = inst.serialize() deser = DemoObj.deserialize(serial) assert deser.variable == inst.variable assert deser.variables == inst.variables assert deser.filename == 'foo.nc'
def new_set_timeseries(self, value, coord_sys): if self._check_timeseries(value): units = self.units wind_data = self._xform_input_timeseries(value) self._timeseries = wind_data.copy() wind_data['value'] = self._convert_units(wind_data['value'], coord_sys, units, 'meter per second') datetime_value_2d = self._xform_input_timeseries(wind_data) timeval = to_time_value_pair(wind_data, coord_sys) self.ossm.timeseries = timeval if not hasattr(self, '_time') or self._time is None: self._time = Time() self.time.data = self._timeseries['time'].astype(datetime.datetime) else: raise ValueError('Bad timeseries as input')
def test_index_of(self, dates): t = Time(dates) before = t.min_time - dt.timedelta(hours=1) after = t.max_time + dt.timedelta(hours=1) assert t.index_of(before, True) == 0 assert t.index_of(after, True) == 5 assert t.index_of(t.data[-1], True) == 4 assert t.index_of(t.data[0], True) == 0 with pytest.raises(ValueError): t.index_of(before, False) with pytest.raises(ValueError): t.index_of(after, False) assert t.index_of(t.max_time, True) == 4 assert t.index_of(t.min_time, True) == 0
def test_serialization_options(self, dates, series_data, series_data2): times = Time(dates) tsv = TimeseriesVector(variables=[ TimeseriesData(name='u', time=times, data=series_data), TimeseriesData(name='v', time=times, data=series_data2) ], units='m/s') # kludge for platform differences # It should work for the platform the test is running on: if os.name == 'posix': filename = 'some/random/path/foo.nc' else: # if not posix, should be windows filename = os.path.normpath('C:\\foo.nc') inst = DemoObj(filename=filename, variable=tsv, variables=[tsv, tsv.variables[0]]) serial = inst.serialize(options={'raw_paths': False}) assert serial['filename'] == 'foo.nc'
def __init__(self, variables=None, time=None, units=None, *args, **kwargs): ''' A class that represents a vector natural phenomenon and provides an interface to get the value of the phenomenon at a position in space and time. :param name: Name of the Property :type name: string :param units: Unit of the underlying data :type units: string :param time: Time axis of the data :type time: [] of datetime.datetime, netCDF4.Variable, or Time object :param variables: component data arrays :type variables: [] of TimeseriesData or numpy.array (Max len=2) ''' self._units = self._time = self._variables = None if all([isinstance(v, TimeseriesData) for v in variables]): if time is not None and not isinstance(time, Time): time = Time(time) units = variables[0].units if units is None else units time = variables[0].time if time is None else time if variables is None or len(variables) < 2: raise ValueError('variables must be an array-like of 2 or more ' 'TimeseriesData objects') self.variables = variables self.units = units self.time = time super(TimeseriesVector, self).__init__(*args, **kwargs)
def __init__(self, timeseries=None, units=None, filename=None, coord_sys='r-theta', latitude=None, longitude=None, speed_uncertainty_scale=0.0, extrapolation_is_allowed=False, **kwargs): """ todo: update docstrings! """ self.updated_at = kwargs.pop('updated_at', None) self.source_id = kwargs.pop('source_id', 'undefined') self.longitude = longitude self.latitude = latitude self.description = kwargs.pop('description', 'Wind Object') self.speed_uncertainty_scale = speed_uncertainty_scale # TODO: the way we are doing this, super() is not being used # effectively. We should tailor kwargs in a way that we can # just pass it into the base __init__() function. # As it is, we are losing arguments that we then need to # explicitly handle. if filename is not None: self.source_type = kwargs.pop('source_type', 'file') super(Wind, self).__init__(filename=filename, coord_sys=coord_sys, **kwargs) self.name = kwargs.pop('name', os.path.split(self.filename)[1]) # set _user_units attribute to match user_units read from file. self._user_units = self.ossm.user_units if units is not None: self.units = units else: if kwargs.get('source_type') in wind_datasources._attr: self.source_type = kwargs.pop('source_type') else: self.source_type = 'undefined' # either timeseries is given or nothing is given # create an empty default object super(Wind, self).__init__(coord_sys=coord_sys, **kwargs) self.units = 'mps' # units for default object if timeseries is not None: if units is None: raise TypeError('Units must be provided with timeseries') self.set_wind_data(timeseries, units, coord_sys) self.extrapolation_is_allowed = extrapolation_is_allowed self.time = kwargs.pop('time', None) self._time = Time( data=self.timeseries['time'].astype(datetime.datetime))
def get_tsd_instance(self, dates, series_data): return TimeseriesData(time=Time(dates), data=series_data, units='m')
def test_serialize(self, dates): t = Time(dates) web_ser = t.serialize() t2 = self.test_class.deserialize(web_ser) assert t == t2
def test_interp_alpha(self, dates): t = Time(dates) test_time = dt.datetime(2000, 1, 1, 1) assert np.isclose(t.interp_alpha(test_time), 0.5)