def __init__( self, wind_file, topology_file=None, **kwargs ): """ :param wind_file: file containing wind data on a grid :param topology_file: Default is None. When exporting topology, it is stored in this file Pass optional arguments to base class uses super: super(GridWindMover,self).__init__(**kwargs) """ if not os.path.exists(wind_file): raise ValueError('Path for wind file does not exist: {0}' .format(wind_file)) if topology_file is not None: if not os.path.exists(topology_file): raise ValueError('Path for Topology file does not exist: {0}' .format(topology_file)) # is wind_file and topology_file is stored with cy_gridwind_mover? self.wind_file = wind_file self.topology_file = topology_file self.mover = CyGridWindMover() super(GridWindMover, self).__init__(**kwargs) self.mover.text_read(wind_file, topology_file)
def __init__(self, wind_file, topology_file=None, extrapolate=False, time_offset=0, **kwargs): """ :param wind_file: file containing wind data on a grid :param topology_file: Default is None. When exporting topology, it is stored in this file :param wind_scale: Value to scale wind data :param extrapolate: Allow current data to be extrapolated before and after file data :param time_offset: Time zone shift if data is in GMT Pass optional arguments to base class uses super: super(GridWindMover,self).__init__(\*\*kwargs) """ if not os.path.exists(wind_file): raise ValueError('Path for wind file does not exist: {0}' .format(wind_file)) if topology_file is not None: if not os.path.exists(topology_file): raise ValueError('Path for Topology file does not exist: {0}' .format(topology_file)) # is wind_file and topology_file is stored with cy_gridwind_mover? self.wind_file = wind_file self.topology_file = topology_file self.mover = CyGridWindMover(wind_scale=kwargs.pop('wind_scale', 1)) self.name = os.path.split(wind_file)[1] super(GridWindMover, self).__init__(**kwargs) self.mover.text_read(wind_file, topology_file) self.mover.extrapolate_in_time(extrapolate) self.mover.offset_time(time_offset * 3600.)
def __init__(self, filename, topology_file=None, extrapolate=False, time_offset=0, **kwargs): """ :param wind_file: file containing wind data on a grid :param filename: file containing wind data on a grid :param topology_file: Default is None. When exporting topology, it is stored in this file :param wind_scale: Value to scale wind data :param extrapolate: Allow current data to be extrapolated before and after file data :param time_offset: Time zone shift if data is in GMT Pass optional arguments to base class uses super: super(GridWindMover,self).__init__(\*\*kwargs) """ if not os.path.exists(filename): raise ValueError( 'Path for wind file does not exist: {0}'.format(filename)) if topology_file is not None: if not os.path.exists(topology_file): raise ValueError( 'Path for Topology file does not exist: {0}'.format( topology_file)) # is wind_file and topology_file is stored with cy_gridwind_mover? self.filename = filename self.topology_file = topology_file self.mover = CyGridWindMover(wind_scale=kwargs.pop('wind_scale', 1)) self.name = os.path.split(filename)[1] super(GridWindMover, self).__init__(**kwargs) self.mover.text_read(filename, topology_file) self.real_data_start = sec_to_datetime(self.mover.get_start_time()) self.real_data_stop = sec_to_datetime(self.mover.get_end_time()) self.mover.extrapolate_in_time(extrapolate) self.mover.offset_time(time_offset * 3600.)
def __init__(self, filename=None, topology_file=None, extrapolate=False, time_offset=0, **kwargs): """ :param wind_file: file containing wind data on a grid :param filename: file containing wind data on a grid :param topology_file: Default is None. When exporting topology, it is stored in this file :param wind_scale: Value to scale wind data :param extrapolate: Allow current data to be extrapolated before and after file data :param time_offset: Time zone shift if data is in GMT Pass optional arguments to base class uses super: super(GridWindMover,self).__init__(\*\*kwargs) """ if not os.path.exists(filename): raise ValueError( 'Path for wind file does not exist: {0}'.format(filename)) if topology_file is not None: if not os.path.exists(topology_file): raise ValueError( 'Path for Topology file does not exist: {0}'.format( topology_file)) self.mover = CyGridWindMover(wind_scale=kwargs.pop('wind_scale', 1)) self.mover.text_read(filename, topology_file) # Ideally, we would be able to run the base class initialization first # because we designed the Movers well. As it is, we inherit from the # CyMover, and the CyMover needs to have a self.mover attribute. super(GridWindMover, self).__init__(**kwargs) # is wind_file and topology_file is stored with cy_gridwind_mover? self.name = os.path.split(filename)[1] self.filename = filename self.topology_file = topology_file self.mover.extrapolate_in_time(extrapolate) self.mover.offset_time(time_offset * 3600.)
def __init__(self, filename=None, topology_file=None, extrapolate=False, time_offset=0, **kwargs): """ :param wind_file: file containing wind data on a grid :param filename: file containing wind data on a grid :param topology_file: Default is None. When exporting topology, it is stored in this file :param wind_scale: Value to scale wind data :param extrapolate: Allow current data to be extrapolated before and after file data :param time_offset: Time zone shift if data is in GMT Pass optional arguments to base class uses super: super(GridWindMover,self).__init__(\*\*kwargs) """ if not os.path.exists(filename): raise ValueError('Path for wind file does not exist: {0}' .format(filename)) if topology_file is not None: if not os.path.exists(topology_file): raise ValueError('Path for Topology file does not exist: {0}' .format(topology_file)) self.mover = CyGridWindMover(wind_scale=kwargs.pop('wind_scale', 1)) self.mover.text_read(filename, topology_file) # Ideally, we would be able to run the base class initialization first # because we designed the Movers well. As it is, we inherit from the # CyMover, and the CyMover needs to have a self.mover attribute. super(GridWindMover, self).__init__(**kwargs) # is wind_file and topology_file is stored with cy_gridwind_mover? self.name = os.path.split(filename)[1] self.filename = filename self.topology_file = topology_file self.mover.extrapolate_in_time(extrapolate) self.mover.offset_time(time_offset * 3600.)
class GridWindMover(WindMoversBase): _schema = GridWindMoverSchema def __init__(self, filename=None, topology_file=None, extrapolate=False, time_offset=0, **kwargs): """ :param wind_file: file containing wind data on a grid :param filename: file containing wind data on a grid :param topology_file: Default is None. When exporting topology, it is stored in this file :param wind_scale: Value to scale wind data :param extrapolate: Allow current data to be extrapolated before and after file data :param time_offset: Time zone shift if data is in GMT Pass optional arguments to base class uses super: super(GridWindMover,self).__init__(\*\*kwargs) """ if not os.path.exists(filename): raise ValueError( 'Path for wind file does not exist: {0}'.format(filename)) if topology_file is not None: if not os.path.exists(topology_file): raise ValueError( 'Path for Topology file does not exist: {0}'.format( topology_file)) self.mover = CyGridWindMover(wind_scale=kwargs.pop('wind_scale', 1)) self.mover.text_read(filename, topology_file) # Ideally, we would be able to run the base class initialization first # because we designed the Movers well. As it is, we inherit from the # CyMover, and the CyMover needs to have a self.mover attribute. super(GridWindMover, self).__init__(**kwargs) # is wind_file and topology_file is stored with cy_gridwind_mover? self.name = os.path.split(filename)[1] self.filename = filename self.topology_file = topology_file self.mover.extrapolate_in_time(extrapolate) self.mover.offset_time(time_offset * 3600.) @property def data_start(self): return sec_to_datetime(self.mover.get_start_time()) @property def data_stop(self): return sec_to_datetime(self.mover.get_end_time()) def __repr__(self): """ .. todo:: We probably want to include more information. """ return 'GridWindMover(\n{0})'.format(self._state_as_str()) def __str__(self): return ('GridWindMover - current _state.\n{0}'.format( self._state_as_str())) wind_scale = property( lambda self: self.mover.wind_scale, lambda self, val: setattr(self.mover, 'wind_scale', val)) extrapolate = property( lambda self: self.mover.extrapolate, lambda self, val: setattr(self.mover, 'extrapolate', val)) time_offset = property( lambda self: self.mover.time_offset / 3600., lambda self, val: setattr(self.mover, 'time_offset', val * 3600.)) def get_grid_data(self): return self.get_cells() def get_cells(self): """ Invokes the GetCellDataHdl method of TimeGridWind_c object. Cross-references point data to get cell coordinates. """ cell_data = self.mover._get_cell_data() points = self.get_points() dtype = cell_data[0].dtype.descr unstructured_type = dtype[0][1] unstructured = (cell_data.view(dtype=unstructured_type).reshape( -1, len(dtype))[:, 1:]) return points[unstructured] def get_points(self): points = (self.mover._get_points().astype([('long', '<f8'), ('lat', '<f8')])) points['long'] /= 10**6 points['lat'] /= 10**6 return points def get_cell_center_points(self): ''' Right now the cython mover only gets the triangular center points, so we need to calculate centers based on the cells themselves. Cells will have the format (tl, tr, bl, br) We need to get the rectangular centers Center will be: (tl + ((br - tl) / 2.)) ''' return (self.mover._get_center_points().view(dtype='<f8').reshape( -1, 2)) def get_center_points(self): return self.get_cell_center_points() def get_scaled_velocities(self, time): """ :param model_time=0: """ # regular and curvilinear grids only if self.mover._is_regular_grid(): num_cells = self.mover.get_num_points() else: num_tri = self.mover.get_num_triangles() num_cells = num_tri / 2 # will need to update this for regular grids vels = np.zeros(num_cells, dtype=velocity_rec) self.mover.get_scaled_velocities(time, vels) return vels def export_topology(self, topology_file): """ :param topology_file=None: absolute or relative path where topology file will be written. """ if topology_file is None: raise ValueError( 'Topology file path required: {0}'.format(topology_file)) self.mover.export_topology(topology_file) def extrapolate_in_time(self, extrapolate): """ :param extrapolate=false: Allow current data to be extrapolated before and after file data. """ self.mover.extrapolate_in_time(extrapolate) def offset_time(self, time_offset): """ :param offset_time=0: Allow data to be in GMT with a time zone offset (hours). """ self.mover.offset_time(time_offset * 3600.)
class GridWindMover(WindMoversBase, serializable.Serializable): _state = copy.deepcopy(WindMoversBase._state) _state.add(update=['wind_scale', 'extrapolate'], save=['wind_scale', 'extrapolate']) _state.add_field([ serializable.Field('wind_file', save=True, read=True, isdatafile=True, test_for_eq=False), serializable.Field('topology_file', save=True, read=True, isdatafile=True, test_for_eq=False) ]) _schema = GridWindMoverSchema def __init__(self, wind_file, topology_file=None, extrapolate=False, time_offset=0, **kwargs): """ :param wind_file: file containing wind data on a grid :param topology_file: Default is None. When exporting topology, it is stored in this file :param wind_scale: Value to scale wind data :param extrapolate: Allow current data to be extrapolated before and after file data :param time_offset: Time zone shift if data is in GMT Pass optional arguments to base class uses super: super(GridWindMover,self).__init__(\*\*kwargs) """ if not os.path.exists(wind_file): raise ValueError( 'Path for wind file does not exist: {0}'.format(wind_file)) if topology_file is not None: if not os.path.exists(topology_file): raise ValueError( 'Path for Topology file does not exist: {0}'.format( topology_file)) # is wind_file and topology_file is stored with cy_gridwind_mover? self.wind_file = wind_file self.topology_file = topology_file self.mover = CyGridWindMover(wind_scale=kwargs.pop('wind_scale', 1)) self.name = os.path.split(wind_file)[1] super(GridWindMover, self).__init__(**kwargs) self.mover.text_read(wind_file, topology_file) self.real_data_start = time_utils.sec_to_datetime( self.mover.get_start_time()) self.real_data_stop = time_utils.sec_to_datetime( self.mover.get_end_time()) self.mover.extrapolate_in_time(extrapolate) self.mover.offset_time(time_offset * 3600.) def __repr__(self): """ .. todo:: We probably want to include more information. """ info = 'GridWindMover(\n{0})'.format(self._state_as_str()) return info def __str__(self): info = ('GridWindMover - current _state.\n' '{0}'.format(self._state_as_str())) return info wind_scale = property( lambda self: self.mover.wind_scale, lambda self, val: setattr(self.mover, 'wind_scale', val)) extrapolate = property( lambda self: self.mover.extrapolate, lambda self, val: setattr(self.mover, 'extrapolate', val)) time_offset = property( lambda self: self.mover.time_offset / 3600., lambda self, val: setattr(self.mover, 'time_offset', val * 3600.)) def export_topology(self, topology_file): """ :param topology_file=None: absolute or relative path where topology file will be written. """ if topology_file is None: raise ValueError( 'Topology file path required: {0}'.format(topology_file)) self.mover.export_topology(topology_file) def extrapolate_in_time(self, extrapolate): """ :param extrapolate=false: Allow current data to be extrapolated before and after file data. """ self.mover.extrapolate_in_time(extrapolate) def offset_time(self, time_offset): """ :param offset_time=0: Allow data to be in GMT with a time zone offset (hours). """ self.mover.offset_time(time_offset * 3600.) def get_start_time(self): """ :this will be the real_data_start time (seconds). """ return (self.mover.get_start_time()) def get_end_time(self): """ :this will be the real_data_stop time (seconds). """ return (self.mover.get_end_time())
class GridWindMover(WindMoversBase, serializable.Serializable): _state = copy.deepcopy(WindMoversBase._state) _state.add(update=['wind_scale', 'extrapolate'], save=['wind_scale', 'extrapolate']) _state.add_field([serializable.Field('wind_file', save=True, read=True, isdatafile=True, test_for_eq=False), serializable.Field('topology_file', save=True, read=True, isdatafile=True, test_for_eq=False)]) _schema = GridWindMoverSchema def __init__(self, wind_file, topology_file=None, extrapolate=False, time_offset=0, **kwargs): """ :param wind_file: file containing wind data on a grid :param topology_file: Default is None. When exporting topology, it is stored in this file :param wind_scale: Value to scale wind data :param extrapolate: Allow current data to be extrapolated before and after file data :param time_offset: Time zone shift if data is in GMT Pass optional arguments to base class uses super: super(GridWindMover,self).__init__(\*\*kwargs) """ if not os.path.exists(wind_file): raise ValueError('Path for wind file does not exist: {0}' .format(wind_file)) if topology_file is not None: if not os.path.exists(topology_file): raise ValueError('Path for Topology file does not exist: {0}' .format(topology_file)) # is wind_file and topology_file is stored with cy_gridwind_mover? self.wind_file = wind_file self.topology_file = topology_file self.mover = CyGridWindMover(wind_scale=kwargs.pop('wind_scale', 1)) self.name = os.path.split(wind_file)[1] super(GridWindMover, self).__init__(**kwargs) self.mover.text_read(wind_file, topology_file) self.real_data_start = time_utils.sec_to_datetime(self.mover.get_start_time()) self.real_data_stop = time_utils.sec_to_datetime(self.mover.get_end_time()) self.mover.extrapolate_in_time(extrapolate) self.mover.offset_time(time_offset * 3600.) def __repr__(self): """ .. todo:: We probably want to include more information. """ info = 'GridWindMover(\n{0})'.format(self._state_as_str()) return info def __str__(self): info = ('GridWindMover - current _state.\n' '{0}'.format(self._state_as_str())) return info wind_scale = property(lambda self: self.mover.wind_scale, lambda self, val: setattr(self.mover, 'wind_scale', val)) extrapolate = property(lambda self: self.mover.extrapolate, lambda self, val: setattr(self.mover, 'extrapolate', val)) time_offset = property(lambda self: self.mover.time_offset / 3600., lambda self, val: setattr(self.mover, 'time_offset', val * 3600.)) def export_topology(self, topology_file): """ :param topology_file=None: absolute or relative path where topology file will be written. """ if topology_file is None: raise ValueError('Topology file path required: {0}'. format(topology_file)) self.mover.export_topology(topology_file) def extrapolate_in_time(self, extrapolate): """ :param extrapolate=false: Allow current data to be extrapolated before and after file data. """ self.mover.extrapolate_in_time(extrapolate) def offset_time(self, time_offset): """ :param offset_time=0: Allow data to be in GMT with a time zone offset (hours). """ self.mover.offset_time(time_offset * 3600.) def get_start_time(self): """ :this will be the real_data_start time (seconds). """ return (self.mover.get_start_time()) def get_end_time(self): """ :this will be the real_data_stop time (seconds). """ return (self.mover.get_end_time())
class TestGridWindMover: cm = Common() gcm = CyGridWindMover() # delta = np.zeros((cm.num_le,), dtype=basic_types.world_point) def move(self): self.gcm.prepare_for_model_run() print "Certain move" self.gcm.prepare_for_model_step(self.cm.model_time, self.cm.time_step) self.gcm.get_move( self.cm.model_time, self.cm.time_step, self.cm.ref, self.cm.delta, self.cm.wind, self.cm.status, spill_type.forecast, ) def move_uncertain(self): self.gcm.prepare_for_model_run() spill_size = np.zeros( (1, ), dtype=np.int32 ) # number of LEs in 1 uncertainty spill - simple test spill_size[0] = self.cm.num_le # for uncertainty spills start_pos = (-122.934656, 38.27594, 0) print "Uncertain move" self.gcm.prepare_for_model_step(self.cm.model_time, self.cm.time_step, 1, spill_size) self.gcm.get_move( self.cm.model_time, self.cm.time_step, self.cm.ref, self.cm.delta_uncertainty, self.cm.wind, self.cm.status, spill_type.uncertainty, ) def check_move(self): self.move() print self.cm.delta assert np.all(self.cm.delta['lat'] != 0) assert np.all(self.cm.delta['long'] != 0) def check_move_uncertain(self): self.move_uncertain() print self.cm.delta_uncertainty assert np.all(self.cm.delta_uncertainty['lat'] != 0) assert np.all(self.cm.delta_uncertainty['long'] != 0) def check_move_certain_uncertain(self, uncertain_time_delay=0): self.check_move() self.check_move_uncertain() tol = 1e-5 msg = r"{0} move is not within a tolerance of {1}" if uncertain_time_delay == 0: assert np.all( self.cm.delta_uncertainty['lat'] != self.cm.delta['lat']) assert np.all( self.cm.delta_uncertainty['long'] != self.cm.delta['long']) if uncertain_time_delay > 0: np.testing.assert_allclose( self.cm.delta['lat'], self.cm.delta_uncertainty['lat'], tol, tol, msg.format('grid_wind.nc', tol), 0, ) np.testing.assert_allclose( self.cm.delta['long'], self.cm.delta_uncertainty['long'], tol, tol, msg.format('grid_wind.nc', tol), 0, ) def test_move_reg(self): """ test move for a regular grid (first time in file) """ time = datetime.datetime(1999, 11, 29, 21) self.cm.model_time = date_to_sec(time) time_grid_file = testdata['GridWindMover']['wind_rect'] self.gcm.text_read(time_grid_file) self.cm.ref[:]['long'] = 3.104588 # for simple example self.cm.ref[:]['lat'] = 52.016468 self.check_move() actual = np.empty((self.cm.num_le, ), dtype=world_point) actual[:]['lat'] = .00010063832857459063 actual[:]['long'] = 3.0168548769686512e-05 actual[:]['z'] = 0. tol = 1e-5 msg = '{0} move is not within a tolerance of {1}' np.testing.assert_allclose( self.cm.delta['lat'], actual['lat'], tol, tol, msg.format('test_wind.cdf', tol), 0, ) np.testing.assert_allclose( self.cm.delta['long'], actual['long'], tol, tol, msg.format('test_wind.cdf', tol), 0, ) def test_move_reg_extrapolate(self): """ test move for a regular grid (first time in file) """ time = datetime.datetime(1999, 11, 29, 20) # before first time in file self.cm.model_time = date_to_sec(time) time_grid_file = testdata['GridWindMover']['wind_rect'] self.gcm.text_read(time_grid_file) self.gcm.extrapolate_in_time(True) self.cm.ref[:]['long'] = 3.104588 # for simple example self.cm.ref[:]['lat'] = 52.016468 self.check_move() actual = np.empty((self.cm.num_le, ), dtype=world_point) actual[:]['lat'] = .00010063832857459063 actual[:]['long'] = 3.0168548769686512e-05 actual[:]['z'] = 0. tol = 1e-5 msg = '{0} move is not within a tolerance of {1}' np.testing.assert_allclose( self.cm.delta['lat'], actual['lat'], tol, tol, msg.format('test_wind.cdf', tol), 0, ) np.testing.assert_allclose( self.cm.delta['long'], actual['long'], tol, tol, msg.format('test_wind.cdf', tol), 0, ) def test_move_curv(self): """ test move for a curvilinear grid (first time in file) """ time = datetime.datetime(2006, 3, 31, 21) self.cm.model_time = date_to_sec(time) self.cm.uncertain = True self.gcm.text_read(testdata['GridWindMover']['wind_curv'], testdata['GridWindMover']['top_curv']) self.cm.ref[:]['long'] = -122.934656 # for NWS off CA self.cm.ref[:]['lat'] = 38.27594 #self.check_move() self.check_move_certain_uncertain(self.gcm.uncertain_time_delay) actual = np.empty((self.cm.num_le, ), dtype=world_point) actual[:]['lat'] = 0.0009890068148185598 actual[:]['long'] = 0.0012165959734995123 actual[:]['z'] = 0. tol = 1e-5 msg = '{0} move is not within a tolerance of {1}' np.testing.assert_allclose( self.cm.delta['lat'], actual['lat'], tol, tol, msg.format('WindSpeedDirSubset.nc', tol), 0, ) np.testing.assert_allclose( self.cm.delta['long'], actual['long'], tol, tol, msg.format('WindSpeedDirSubset.nc', tol), 0, ) #check that certain and uncertain are the same if uncertainty is time delayed #self.gcm.uncertain_time_delay = 3 self.gcm.uncertain_time_delay = 10800 # cython expects time_delay in seconds self.check_move_certain_uncertain(self.gcm.uncertain_time_delay) # np.testing.assert_equal(self.cm.delta, actual, # "test_move_curv() failed", 0) np.all(self.cm.delta['z'] == 0) def test_move_curv_no_top(self): """ test move for a curvilinear grid (first time in file) """ time = datetime.datetime(2006, 3, 31, 21) self.cm.model_time = date_to_sec(time) time_grid_file = testdata['GridWindMover']['wind_curv'] self.gcm.text_read(time_grid_file) topology_file2 = os.path.join( os.path.split(time_grid_file)[0], 'WindSpeedDirSubsetTopNew.dat') self.gcm.export_topology(topology_file2) self.cm.ref[:]['long'] = -122.934656 # for NWS off CA self.cm.ref[:]['lat'] = 38.27594 self.check_move() actual = np.empty((self.cm.num_le, ), dtype=world_point) actual[:]['lat'] = 0.0009890068148185598 actual[:]['long'] = 0.0012165959734995123 actual[:]['z'] = 0. tol = 1e-5 msg = '{0} move is not within a tolerance of {1}' np.testing.assert_allclose( self.cm.delta['lat'], actual['lat'], tol, tol, msg.format('WindSpeedDirSubset.nc', tol), 0, ) np.testing.assert_allclose( self.cm.delta['long'], actual['long'], tol, tol, msg.format('WindSpeedDirSubset.nc', tol), 0, ) # np.testing.assert_equal(self.cm.delta, actual, # "test_move_curv() failed", 0) np.all(self.cm.delta['z'] == 0) # def test_move_curv_series(self): # """ # Test a curvilinear file series # - time in first file # - time in second file # """ # time = datetime.datetime(2009, 8, 9, 0) #second file # self.cm.model_time = time_utils.date_to_sec(time) # # time_grid_file = os.path.join(winds_dir, 'file_series', 'flist2.txt') # topology_file = os.path.join(cur_file, 'file_series', # 'HiROMSTopology.dat') # # self.gcm.text_read(time_grid_file,topology_file) # self.cm.ref[:]['long'] = (-157.795728) #for HiROMS # self.cm.ref[:]['lat'] = (21.069288) # self.check_move() # # actual = np.empty((self.cm.num_le,), dtype=basic_types.world_point) # actual[:]['lat'] = (-.003850193) #file 2 # actual[:]['long'] = (.000152012) # tol = 1e-5 # # msg = "{0} move is not within a tolerance of {1}" # np.testing.assert_allclose(self.cm.delta['lat'], actual['lat'], # tol, tol, # msg.format("HiROMS", tol), 0) # np.testing.assert_allclose(self.cm.delta['long'], actual['long'], # tol, tol, # msg.format("HiROMS", tol), 0) def test_move_gridwindtime(self): """ test move for a grid wind timeseries file (first time in file) """ # time = datetime.datetime(2002, 11, 19, 1) time = datetime.datetime(2002, 1, 30, 1) self.cm.model_time = date_to_sec(time) time_grid_file = testdata['GridWindMover']['grid_ts'] self.gcm.text_read(time_grid_file) self.cm.ref[:]['long'] = -119.861328 # for gridWind test self.cm.ref[:]['lat'] = 34.130412 self.check_move() actual = np.empty((self.cm.num_le, ), dtype=world_point) actual[:]['lat'] = -0.0001765253714478036 actual[:]['long'] = 0.00010508690731670587 actual[:]['z'] = 0. tol = 1e-5 msg = '{0} move is not within a tolerance of {1}' np.testing.assert_allclose( self.cm.delta['lat'], actual['lat'], tol, tol, msg.format('gridwindtime', tol), 0, ) np.testing.assert_allclose( self.cm.delta['long'], actual['long'], tol, tol, msg.format('gridwindtime', tol), 0, )
class GridWindMover(WindMoversBase): _schema = GridWindMoverSchema def __init__(self, filename=None, topology_file=None, extrapolate=False, time_offset=0, **kwargs): """ :param wind_file: file containing wind data on a grid :param filename: file containing wind data on a grid :param topology_file: Default is None. When exporting topology, it is stored in this file :param wind_scale: Value to scale wind data :param extrapolate: Allow current data to be extrapolated before and after file data :param time_offset: Time zone shift if data is in GMT Pass optional arguments to base class uses super: super(GridWindMover,self).__init__(\*\*kwargs) """ if not os.path.exists(filename): raise ValueError('Path for wind file does not exist: {0}' .format(filename)) if topology_file is not None: if not os.path.exists(topology_file): raise ValueError('Path for Topology file does not exist: {0}' .format(topology_file)) self.mover = CyGridWindMover(wind_scale=kwargs.pop('wind_scale', 1)) self.mover.text_read(filename, topology_file) # Ideally, we would be able to run the base class initialization first # because we designed the Movers well. As it is, we inherit from the # CyMover, and the CyMover needs to have a self.mover attribute. super(GridWindMover, self).__init__(**kwargs) # is wind_file and topology_file is stored with cy_gridwind_mover? self.name = os.path.split(filename)[1] self.filename = filename self.topology_file = topology_file self.mover.extrapolate_in_time(extrapolate) self.mover.offset_time(time_offset * 3600.) @property def data_start(self): return sec_to_datetime(self.mover.get_start_time()) @property def data_stop(self): return sec_to_datetime(self.mover.get_end_time()) def __repr__(self): """ .. todo:: We probably want to include more information. """ return 'GridWindMover(\n{0})'.format(self._state_as_str()) def __str__(self): return ('GridWindMover - current _state.\n{0}' .format(self._state_as_str())) wind_scale = property(lambda self: self.mover.wind_scale, lambda self, val: setattr(self.mover, 'wind_scale', val)) extrapolate = property(lambda self: self.mover.extrapolate, lambda self, val: setattr(self.mover, 'extrapolate', val)) time_offset = property(lambda self: self.mover.time_offset / 3600., lambda self, val: setattr(self.mover, 'time_offset', val * 3600.)) def get_grid_data(self): return self.get_cells() def get_cells(self): """ Invokes the GetCellDataHdl method of TimeGridWind_c object. Cross-references point data to get cell coordinates. """ cell_data = self.mover._get_cell_data() points = self.get_points() dtype = cell_data[0].dtype.descr unstructured_type = dtype[0][1] unstructured = (cell_data.view(dtype=unstructured_type) .reshape(-1, len(dtype))[:, 1:]) return points[unstructured] def get_points(self): points = (self.mover._get_points() .astype([('long', '<f8'), ('lat', '<f8')])) points['long'] /= 10 ** 6 points['lat'] /= 10 ** 6 return points def get_cell_center_points(self): ''' Right now the cython mover only gets the triangular center points, so we need to calculate centers based on the cells themselves. Cells will have the format (tl, tr, bl, br) We need to get the rectangular centers Center will be: (tl + ((br - tl) / 2.)) ''' return (self.mover._get_center_points() .view(dtype='<f8').reshape(-1, 2)) def get_center_points(self): return self.get_cell_center_points() def get_scaled_velocities(self, time): """ :param model_time=0: """ # regular and curvilinear grids only if self.mover._is_regular_grid(): num_cells = self.mover.get_num_points() else: num_tri = self.mover.get_num_triangles() num_cells = num_tri / 2 # will need to update this for regular grids vels = np.zeros(num_cells, dtype=velocity_rec) self.mover.get_scaled_velocities(time, vels) return vels def export_topology(self, topology_file): """ :param topology_file=None: absolute or relative path where topology file will be written. """ if topology_file is None: raise ValueError('Topology file path required: {0}'. format(topology_file)) self.mover.export_topology(topology_file) def extrapolate_in_time(self, extrapolate): """ :param extrapolate=false: Allow current data to be extrapolated before and after file data. """ self.mover.extrapolate_in_time(extrapolate) def offset_time(self, time_offset): """ :param offset_time=0: Allow data to be in GMT with a time zone offset (hours). """ self.mover.offset_time(time_offset * 3600.)
class GridWindMover(WindMoversBase, serializable.Serializable): _state = copy.deepcopy(WindMoversBase._state) _state.add(update=["wind_scale"], create=["wind_scale"]) _state.add_field( [ serializable.Field("wind_file", create=True, read=True, isdatafile=True, test_for_eq=False), serializable.Field("topology_file", create=True, read=True, isdatafile=True, test_for_eq=False), ] ) def __init__(self, wind_file, topology_file=None, extrapolate=False, time_offset=0, **kwargs): """ :param wind_file: file containing wind data on a grid :param topology_file: Default is None. When exporting topology, it is stored in this file :param wind_scale: Value to scale wind data :param extrapolate: Allow current data to be extrapolated before and after file data :param time_offset: Time zone shift if data is in GMT Pass optional arguments to base class uses super: super(GridWindMover,self).__init__(**kwargs) """ if not os.path.exists(wind_file): raise ValueError("Path for wind file does not exist: {0}".format(wind_file)) if topology_file is not None: if not os.path.exists(topology_file): raise ValueError("Path for Topology file does not exist: {0}".format(topology_file)) # is wind_file and topology_file is stored with cy_gridwind_mover? self.wind_file = wind_file self.topology_file = topology_file self.mover = CyGridWindMover(wind_scale=kwargs.pop("wind_scale", 1)) super(GridWindMover, self).__init__(**kwargs) self.mover.text_read(wind_file, topology_file) self.mover.extrapolate_in_time(extrapolate) self.mover.offset_time(time_offset * 3600.0) def __repr__(self): """ .. todo:: We probably want to include more information. """ info = "GridWindMover(\n{0})".format(self._state_as_str()) return info def __str__(self): info = "GridWindMover - current _state.\n" "{0}".format(self._state_as_str()) return info wind_scale = property(lambda self: self.mover.wind_scale, lambda self, val: setattr(self.mover, "wind_scale", val)) extrapolate = property( lambda self: self.mover.extrapolate, lambda self, val: setattr(self.mover, "extrapolate", val) ) time_offset = property( lambda self: self.mover.time_offset / 3600.0, lambda self, val: setattr(self.mover, "time_offset", val * 3600.0) ) def export_topology(self, topology_file): """ :param topology_file=None: absolute or relative path where topology file will be written. """ if topology_file is None: raise ValueError("Topology file path required: {0}".format(topology_file)) self.mover.export_topology(topology_file) def extrapolate_in_time(self, extrapolate): """ :param extrapolate=false: Allow current data to be extrapolated before and after file data. """ self.mover.extrapolate_in_time(extrapolate) def offset_time(self, time_offset): """ :param offset_time=0: Allow data to be in GMT with a time zone offset (hours). """ self.mover.offset_time(time_offset * 3600.0)
class GridWindMover(WindMoversBase, serializable.Serializable): state = copy.deepcopy(WindMoversBase.state) state.add_field([serializable.Field('wind_file', create=True, read=True, isdatafile=True), serializable.Field('topology_file', create=True, read=True, isdatafile=True)]) def __init__( self, wind_file, topology_file=None, **kwargs ): """ :param wind_file: file containing wind data on a grid :param topology_file: Default is None. When exporting topology, it is stored in this file Pass optional arguments to base class uses super: super(GridWindMover,self).__init__(**kwargs) """ if not os.path.exists(wind_file): raise ValueError('Path for wind file does not exist: {0}' .format(wind_file)) if topology_file is not None: if not os.path.exists(topology_file): raise ValueError('Path for Topology file does not exist: {0}' .format(topology_file)) # is wind_file and topology_file is stored with cy_gridwind_mover? self.wind_file = wind_file self.topology_file = topology_file self.mover = CyGridWindMover() super(GridWindMover, self).__init__(**kwargs) self.mover.text_read(wind_file, topology_file) def __repr__(self): """ .. todo:: We probably want to include more information. """ info = 'GridWindMover(\n{0})'.format(self._state_as_str()) return info def __str__(self): info = 'GridWindMover - current state.\n' \ + "{0}".format(self._state_as_str()) return info def export_topology(self, topology_file): """ :param topology_file=None: absolute or relative path where topology file will be written. """ if topology_file is None: raise ValueError('Topology file path required: {0}'. format(topology_file)) self.mover.export_topology(topology_file)