class ComponentMover(CurrentMoversBase): _schema = ComponentMoverSchema def __init__(self, filename1=None, filename2=None, scale_refpoint=None, pat1_angle=0, pat1_speed=10, pat1_speed_units=2, pat1_scale_to_value=0.1, pat2_angle=90, pat2_scale_to_value=0.1, pat2_speed=10, pat2_speed_units=2, scale_by=0, wind=None, **kwargs): """ Uses super to invoke base class __init__ method. :param filename: file containing currents for first Cats pattern Optional parameters (kwargs). Defaults are defined by CyCatsMover object. :param filename: file containing currents for second Cats pattern :param wind: A gnome.environment.Wind object to be used to drive the CatsMovers. Will want a warning that mover will not be active without a wind :param scale: A boolean to indicate whether to scale value at reference point or not :param scale_value: Value used for scaling at reference point :param scale_refpoint: Reference location (long, lat, z). The scaling applied to all data is determined by scaling the raw value at this location. Remaining kwargs are passed onto Mover's __init__ using super. See Mover documentation for remaining valid kwargs. """ if filename1 and not os.path.exists(filename1): raise ValueError( 'Path for Cats filename1 does not exist: {0}'.format( filename1)) if filename2 is not None: if not os.path.exists(filename2): raise ValueError( 'Path for Cats filename2 does not exist: {0}'.format( filename2)) self.filename1 = filename1 self.filename2 = filename2 self.mover = CyComponentMover() self.mover.text_read(filename1, filename2) super(ComponentMover, self).__init__(**kwargs) self._wind = None if wind is not None: self.wind = wind self.scale_by = scale_by self.scale_refpoint = scale_refpoint self.pat1_angle = pat1_angle self.pat1_speed = pat1_speed self.pat1_speed_units = pat1_speed_units self.pat1_scale_to_value = pat1_scale_to_value self.pat2_angle = pat2_angle self.pat2_scale_to_value = pat2_scale_to_value self.pat2_speed = pat2_speed self.pat2_speed_units = pat2_speed_units def __repr__(self): """ unambiguous representation of object """ return 'ComponentMover(filename={0})'.format(self.filename1) # Properties pat1_angle = property( lambda self: self.mover.pat1_angle, lambda self, val: setattr(self.mover, 'pat1_angle', val)) pat1_speed = property( lambda self: self.mover.pat1_speed, lambda self, val: setattr(self.mover, 'pat1_speed', val)) pat1_speed_units = property( lambda self: self.mover.pat1_speed_units, lambda self, val: setattr(self.mover, 'pat1_speed_units', val)) pat1_scale_to_value = property( lambda self: self.mover.pat1_scale_to_value, lambda self, val: setattr(self.mover, 'pat1_scale_to_value', val)) pat2_angle = property( lambda self: self.mover.pat2_angle, lambda self, val: setattr(self.mover, 'pat2_angle', val)) pat2_speed = property( lambda self: self.mover.pat2_speed, lambda self, val: setattr(self.mover, 'pat2_speed', val)) pat2_speed_units = property( lambda self: self.mover.pat2_speed_units, lambda self, val: setattr(self.mover, 'pat2_speed_units', val)) pat2_scale_to_value = property( lambda self: self.mover.pat2_scale_to_value, lambda self, val: setattr(self.mover, 'pat2_scale_to_value', val)) scale_by = property(lambda self: self.mover.scale_by, lambda self, val: setattr(self.mover, 'scale_by', val)) extrapolate = property( lambda self: self.mover.extrapolate, lambda self, val: setattr(self.mover, 'extrapolate', val)) use_averaged_winds = property( lambda self: self.mover.use_averaged_winds, lambda self, val: setattr(self.mover, 'use_averaged_winds', val)) wind_power_factor = property( lambda self: self.mover.wind_power_factor, lambda self, val: setattr(self.mover, 'wind_power_factor', val)) past_hours_to_average = property( lambda self: (self.mover.past_hours_to_average), lambda self, val: setattr(self.mover, 'past_hours_to_average', val)) scale_factor_averaged_winds = property( lambda self: self.mover.scale_factor_averaged_winds, lambda self, val: setattr(self.mover, 'scale_factor_averaged_winds', val)) use_original_scale_factor = property( lambda self: self.mover.use_original_scale_factor, lambda self, val: setattr(self.mover, 'use_original_scale_factor', val)) @property def data_start(self): if self.wind is not None: return self.wind.data_start else: return MinusInfTime() @property def data_stop(self): if self.wind is not None: return self.wind.data_stop else: return InfTime() @property def scale_refpoint(self): return self.mover.ref_point @scale_refpoint.setter def scale_refpoint(self, val): ''' Must be a tuple of length 2 or 3: (long, lat, z). If only (long, lat) is given, the set z = 0 ''' if val is None: return if len(val) == 2: self.mover.ref_point = (val[0], val[1], 0.) else: self.mover.ref_point = val @property def wind(self): return self._wind @wind.setter def wind(self, wind_obj): if not isinstance(wind_obj, Wind): self._wind = None return self.mover.set_ossm(wind_obj.ossm) self._wind = wind_obj def get_grid_data(self): """ Invokes the GetToplogyHdl method of TriGridVel_c object """ return self.get_triangles() def get_center_points(self): return self.get_triangle_center_points() def get_optimize_values(self, model_time): optimize_pat1 = self.mover.get_optimize_value(model_time, 1) optimize_pat2 = self.mover.get_optimize_value(model_time, 2) return optimize_pat1, optimize_pat2 def get_scaled_velocities(self, model_time): """ Get file values scaled to optimized check if pat2 exists """ pat = 1 vels_pat1 = self.mover._get_velocity_handle(pat) pat = 2 vels_pat2 = self.mover._get_velocity_handle(pat) optimize_pat1, optimize_pat2 = self.get_optimize_values(model_time) vels_pat1['u'] = vels_pat1['u'] * optimize_pat1 vels_pat1['v'] = vels_pat1['v'] * optimize_pat1 if vels_pat2 != 0 and optimize_pat2 != 0: vels_pat1['u'] = vels_pat1['u'] + vels_pat2['u'] * optimize_pat2 vels_pat1['v'] = vels_pat1['v'] + vels_pat2['v'] * optimize_pat2 return vels_pat1
class ComponentMover(CurrentMoversBase): _schema = ComponentMoverSchema def __init__(self, filename1=None, filename2=None, scale_refpoint=None, pat1_angle=0, pat1_speed=10, pat1_speed_units=2, pat1_scale_to_value=0.1, pat2_angle=90, pat2_scale_to_value=0.1, pat2_speed=10, pat2_speed_units=2, scale_by=0, wind=None, **kwargs): """ Uses super to invoke base class __init__ method. :param filename: file containing currents for first Cats pattern Optional parameters (kwargs). Defaults are defined by CyCatsMover object. :param filename: file containing currents for second Cats pattern :param wind: A gnome.environment.Wind object to be used to drive the CatsMovers. Will want a warning that mover will not be active without a wind :param scale: A boolean to indicate whether to scale value at reference point or not :param scale_value: Value used for scaling at reference point :param scale_refpoint: Reference location (long, lat, z). The scaling applied to all data is determined by scaling the raw value at this location. Remaining kwargs are passed onto Mover's __init__ using super. See Mover documentation for remaining valid kwargs. """ if filename1 and not os.path.exists(filename1): raise ValueError('Path for Cats filename1 does not exist: {0}' .format(filename1)) if filename2 is not None: if not os.path.exists(filename2): raise ValueError('Path for Cats filename2 does not exist: {0}' .format(filename2)) self.filename1 = filename1 self.filename2 = filename2 self.mover = CyComponentMover() self.mover.text_read(filename1, filename2) super(ComponentMover, self).__init__(**kwargs) self._wind = None if wind is not None: self.wind = wind self.scale_by = scale_by self.scale_refpoint = scale_refpoint self.pat1_angle = pat1_angle self.pat1_speed = pat1_speed self.pat1_speed_units = pat1_speed_units self.pat1_scale_to_value = pat1_scale_to_value self.pat2_angle = pat2_angle self.pat2_scale_to_value = pat2_scale_to_value self.pat2_speed = pat2_speed self.pat2_speed_units = pat2_speed_units def __repr__(self): """ unambiguous representation of object """ return 'ComponentMover(filename={0})'.format(self.filename1) # Properties pat1_angle = property(lambda self: self.mover.pat1_angle, lambda self, val: setattr(self.mover, 'pat1_angle', val)) pat1_speed = property(lambda self: self.mover.pat1_speed, lambda self, val: setattr(self.mover, 'pat1_speed', val)) pat1_speed_units = property(lambda self: self.mover.pat1_speed_units, lambda self, val: setattr(self.mover, 'pat1_speed_units', val)) pat1_scale_to_value = property(lambda self: self.mover.pat1_scale_to_value, lambda self, val: setattr(self.mover, 'pat1_scale_to_value', val)) pat2_angle = property(lambda self: self.mover.pat2_angle, lambda self, val: setattr(self.mover, 'pat2_angle', val)) pat2_speed = property(lambda self: self.mover.pat2_speed, lambda self, val: setattr(self.mover, 'pat2_speed', val)) pat2_speed_units = property(lambda self: self.mover.pat2_speed_units, lambda self, val: setattr(self.mover, 'pat2_speed_units', val)) pat2_scale_to_value = property(lambda self: self.mover.pat2_scale_to_value, lambda self, val: setattr(self.mover, 'pat2_scale_to_value', val)) scale_by = property(lambda self: self.mover.scale_by, lambda self, val: setattr(self.mover, 'scale_by', val)) extrapolate = property(lambda self: self.mover.extrapolate, lambda self, val: setattr(self.mover, 'extrapolate', val)) use_averaged_winds = property(lambda self: self.mover.use_averaged_winds, lambda self, val: setattr(self.mover, 'use_averaged_winds', val)) wind_power_factor = property(lambda self: self.mover.wind_power_factor, lambda self, val: setattr(self.mover, 'wind_power_factor', val)) past_hours_to_average = property(lambda self: (self.mover .past_hours_to_average), lambda self, val: setattr(self.mover, 'past_hours_to_average', val)) scale_factor_averaged_winds = property(lambda self: self.mover.scale_factor_averaged_winds, lambda self, val: setattr(self.mover, 'scale_factor_averaged_winds', val)) use_original_scale_factor = property(lambda self: self.mover.use_original_scale_factor, lambda self, val: setattr(self.mover, 'use_original_scale_factor', val)) @property def data_start(self): if self.wind is not None: return self.wind.data_start else: return MinusInfTime() @property def data_stop(self): if self.wind is not None: return self.wind.data_stop else: return InfTime() @property def scale_refpoint(self): return self.mover.ref_point @scale_refpoint.setter def scale_refpoint(self, val): ''' Must be a tuple of length 2 or 3: (long, lat, z). If only (long, lat) is given, the set z = 0 ''' if val is None: return if len(val) == 2: self.mover.ref_point = (val[0], val[1], 0.) else: self.mover.ref_point = val @property def wind(self): return self._wind @wind.setter def wind(self, wind_obj): if not isinstance(wind_obj, Wind): self._wind = None return self.mover.set_ossm(wind_obj.ossm) self._wind = wind_obj def get_grid_data(self): """ Invokes the GetToplogyHdl method of TriGridVel_c object """ return self.get_triangles() def get_center_points(self): return self.get_triangle_center_points() def get_optimize_values(self, model_time): optimize_pat1 = self.mover.get_optimize_value(model_time, 1) optimize_pat2 = self.mover.get_optimize_value(model_time, 2) return optimize_pat1, optimize_pat2 def get_scaled_velocities(self, model_time): """ Get file values scaled to optimized check if pat2 exists """ pat = 1 vels_pat1 = self.mover._get_velocity_handle(pat) pat = 2 vels_pat2 = self.mover._get_velocity_handle(pat) optimize_pat1, optimize_pat2 = self.get_optimize_values(model_time) vels_pat1['u'] = vels_pat1['u'] * optimize_pat1 vels_pat1['v'] = vels_pat1['v'] * optimize_pat1 if vels_pat2 != 0 and optimize_pat2 != 0: vels_pat1['u'] = vels_pat1['u'] + vels_pat2['u'] * optimize_pat2 vels_pat1['v'] = vels_pat1['v'] + vels_pat2['v'] * optimize_pat2 return vels_pat1
class ComponentMover(CurrentMoversBase, Serializable): # _state = copy.deepcopy(CyMover._state) _state = copy.deepcopy(CurrentMoversBase._state) _update = ['scale_refpoint', 'pat1_angle', 'pat1_speed', 'pat1_speed_units', 'pat1_scale_to_value', 'pat2_angle', 'pat2_speed', 'pat2_speed_units', 'pat2_scale_to_value', 'scale_by'] _create = [] _create.extend(_update) _state.add(update=_update, save=_create) _state.add_field([Field('filename1', save=True, read=True, isdatafile=True, test_for_eq=False), Field('filename2', save=True, read=True, isdatafile=True, test_for_eq=False), Field('wind', save=True, update=True, save_reference=True)]) _schema = ComponentMoverSchema def __init__(self, filename1, filename2=None, wind=None, **kwargs): """ Uses super to invoke base class __init__ method. :param filename: file containing currents for first Cats pattern Optional parameters (kwargs). Defaults are defined by CyCatsMover object. :param filename: file containing currents for second Cats pattern :param wind: A gnome.environment.Wind object to be used to drive the CatsMovers. Will want a warning that mover will not be active without a wind :param scale: A boolean to indicate whether to scale value at reference point or not :param scale_value: Value used for scaling at reference point :param scale_refpoint: Reference location (long, lat, z). The scaling applied to all data is determined by scaling the raw value at this location. Remaining kwargs are passed onto Mover's __init__ using super. See Mover documentation for remaining valid kwargs. """ if not os.path.exists(filename1): raise ValueError('Path for Cats filename1 does not exist: {0}' .format(filename1)) if filename2 is not None: if not os.path.exists(filename2): raise ValueError('Path for Cats filename2 does not exist: {0}' .format(filename2)) self.filename1 = filename1 self.filename2 = filename2 self.mover = CyComponentMover() self.mover.text_read(filename1, filename2) self._wind = None if wind is not None: self.wind = wind # TODO: no need to check for None since properties that are None # are not persisted # I think this is required... if 'scale_refpoint' in kwargs: self.scale_refpoint = kwargs.pop('scale_refpoint') super(ComponentMover, self).__init__(**kwargs) def __repr__(self): """ unambiguous representation of object """ return 'ComponentMover(filename={0})'.format(self.filename1) # Properties pat1_angle = property(lambda self: self.mover.pat1_angle, lambda self, val: setattr(self.mover, 'pat1_angle', val)) pat1_speed = property(lambda self: self.mover.pat1_speed, lambda self, val: setattr(self.mover, 'pat1_speed', val)) pat1_speed_units = property(lambda self: self.mover.pat1_speed_units, lambda self, val: setattr(self.mover, 'pat1_speed_units', val)) pat1_scale_to_value = property(lambda self: self.mover.pat1_scale_to_value, lambda self, val: setattr(self.mover, 'pat1_scale_to_value', val)) pat2_angle = property(lambda self: self.mover.pat2_angle, lambda self, val: setattr(self.mover, 'pat2_angle', val)) pat2_speed = property(lambda self: self.mover.pat2_speed, lambda self, val: setattr(self.mover, 'pat2_speed', val)) pat2_speed_units = property(lambda self: self.mover.pat2_speed_units, lambda self, val: setattr(self.mover, 'pat2_speed_units', val)) pat2_scale_to_value = property(lambda self: self.mover.pat2_scale_to_value, lambda self, val: setattr(self.mover, 'pat2_scale_to_value', val)) scale_by = property(lambda self: self.mover.scale_by, lambda self, val: setattr(self.mover, 'scale_by', val)) extrapolate = property(lambda self: self.mover.extrapolate, lambda self, val: setattr(self.mover, 'extrapolate', val)) use_averaged_winds = property(lambda self: self.mover.use_averaged_winds, lambda self, val: setattr(self.mover, 'use_averaged_winds', val)) wind_power_factor = property(lambda self: self.mover.wind_power_factor, lambda self, val: setattr(self.mover, 'wind_power_factor', val)) past_hours_to_average = property(lambda self: (self.mover .past_hours_to_average), lambda self, val: setattr(self.mover, 'past_hours_to_average', val)) scale_factor_averaged_winds = property(lambda self: self.mover.scale_factor_averaged_winds, lambda self, val: setattr(self.mover, 'scale_factor_averaged_winds', val)) use_original_scale_factor = property(lambda self: self.mover.use_original_scale_factor, lambda self, val: setattr(self.mover, 'use_original_scale_factor', val)) @property def scale_refpoint(self): return self.mover.ref_point @scale_refpoint.setter def scale_refpoint(self, val): ''' Must be a tuple of length 2 or 3: (long, lat, z). If only (long, lat) is given, the set z = 0 ''' if len(val) == 2: self.mover.ref_point = (val[0], val[1], 0.) else: self.mover.ref_point = val @property def wind(self): return self._wind @wind.setter def wind(self, wind_obj): if not isinstance(wind_obj, Wind): raise TypeError('wind must be of type environment.Wind') self.mover.set_ossm(wind_obj.ossm) self._wind = wind_obj def get_grid_data(self): """ Invokes the GetToplogyHdl method of TriGridVel_c object """ return self.get_triangles() def get_center_points(self): return self.get_triangle_center_points() def get_scaled_velocities(self, model_time): """ Get file values scaled to ref pt value, with tide applied (if any) """ return self.mover._get_velocity_handle() def serialize(self, json_='webapi'): """ Since 'wind' property is saved as a reference when used in save file and 'save' option, need to add appropriate node to WindMover schema """ dict_ = self.to_serialize(json_) schema = self.__class__._schema() if json_ == 'webapi' and 'wind' in dict_: schema.add(WindSchema(name='wind')) return schema.serialize(dict_) @classmethod def deserialize(cls, json_): """ append correct schema for wind object """ schema = cls._schema() if 'wind' in json_: # for 'webapi', there will be nested Wind structure # for 'save' option, there should be no nested 'wind'. It is # removed, loaded and added back after deserialization schema.add(WindSchema()) return schema.deserialize(json_)
class ComponentMover(CyMover, serializable.Serializable): _state = copy.deepcopy(CyMover._state) _update = ['scale_refpoint', 'pat1_angle', 'pat1_speed', 'pat1_speed_units', 'pat1_scale_to_value', 'pat2_angle', 'pat2_speed', 'pat2_speed_units', 'pat2_scale_to_value', 'scale_by'] _create = [] _create.extend(_update) _state.add(update=_update, save=_create) _state.add_field([serializable.Field('filename1', save=True, read=True, isdatafile=True, test_for_eq=False), serializable.Field('filename2', save=True, read=True, isdatafile=True, test_for_eq=False), serializable.Field('wind', save=True, update=True, save_reference=True)]) _schema = ComponentMoverSchema def __init__(self, filename1, filename2=None, wind=None, **kwargs): """ Uses super to invoke base class __init__ method. :param filename: file containing currents for first Cats pattern Optional parameters (kwargs). Defaults are defined by CyCatsMover object. :param filename: file containing currents for second Cats pattern :param wind: A gnome.environment.Wind object to be used to drive the CatsMovers. Will want a warning that mover will not be active without a wind :param scale: A boolean to indicate whether to scale value at reference point or not :param scale_value: Value used for scaling at reference point :param scale_refpoint: Reference location (long, lat, z). The scaling applied to all data is determined by scaling the raw value at this location. Remaining kwargs are passed onto Mover's __init__ using super. See Mover documentation for remaining valid kwargs. """ if not os.path.exists(filename1): raise ValueError('Path for Cats filename1 does not exist: {0}' .format(filename1)) if filename2 is not None: if not os.path.exists(filename2): raise ValueError('Path for Cats filename2 does not exist: {0}' .format(filename2)) self.filename1 = filename1 self.filename2 = filename2 self.mover = CyComponentMover() self.mover.text_read(filename1, filename2) self._wind = None if wind is not None: self.wind = wind # self.scale = kwargs.pop('scale', self.mover.scale_type) # self.scale_value = kwargs.get('scale_value', # self.mover.scale_value) # TODO: no need to check for None since properties that are None # are not persisted # I think this is required... if 'scale_refpoint' in kwargs: self.scale_refpoint = kwargs.pop('scale_refpoint') # if self.scale and self.scale_value != 0.0 \ # and self.scale_refpoint is None: # raise TypeError("Provide a reference point in 'scale_refpoint'." # ) super(ComponentMover, self).__init__(**kwargs) def __repr__(self): """ unambiguous representation of object """ return 'ComponentMover(filename={0})'.format(self.filename1) # Properties # scale_type = property(lambda self: bool(self.mover.scale_type), # lambda self, val: setattr(self.mover, 'scale_type', # int(val))) # scale_by = property(lambda self: bool(self.mover.scale_by), # lambda self, val: setattr(self.mover, 'scale_by', # int(val))) pat1_angle = property(lambda self: self.mover.pat1_angle, lambda self, val: setattr(self.mover, 'pat1_angle', val)) pat1_speed = property(lambda self: self.mover.pat1_speed, lambda self, val: setattr(self.mover, 'pat1_speed', val)) pat1_speed_units = property(lambda self: self.mover.pat1_speed_units, lambda self, val: setattr(self.mover, 'pat1_speed_units', val)) pat1_scale_to_value = property(lambda self: self.mover.pat1_scale_to_value, lambda self, val: setattr(self.mover, 'pat1_scale_to_value', val)) pat2_angle = property(lambda self: self.mover.pat2_angle, lambda self, val: setattr(self.mover, 'pat2_angle', val)) pat2_speed = property(lambda self: self.mover.pat2_speed, lambda self, val: setattr(self.mover, 'pat2_speed', val)) pat2_speed_units = property(lambda self: self.mover.pat2_speed_units, lambda self, val: setattr(self.mover, 'pat2_speed_units', val)) pat2_scale_to_value = property(lambda self: self.mover.pat2_scale_to_value, lambda self, val: setattr(self.mover, 'pat2_scale_to_value', val)) scale_by = property(lambda self: self.mover.scale_by, lambda self, val: setattr(self.mover, 'scale_by', val)) @property def scale_refpoint(self): return self.mover.ref_point @scale_refpoint.setter def scale_refpoint(self, val): ''' Must be a tuple of length 2 or 3: (long, lat, z). If only (long, lat) is given, the set z = 0 ''' if len(val) == 2: self.mover.ref_point = (val[0], val[1], 0.) else: self.mover.ref_point = val @property def wind(self): return self._wind @wind.setter def wind(self, wind_obj): if not isinstance(wind_obj, environment.Wind): raise TypeError('wind must be of type environment.Wind') self.mover.set_ossm(wind_obj.ossm) self._wind = wind_obj def serialize(self, json_='webapi'): """ Since 'wind' property is saved as a reference when used in save file and 'save' option, need to add appropriate node to WindMover schema """ dict_ = self.to_serialize(json_) schema = self.__class__._schema() if json_ == 'webapi' and 'wind' in dict_: schema.add(environment.WindSchema(name='wind')) return schema.serialize(dict_) @classmethod def deserialize(cls, json_): """ append correct schema for wind object """ schema = cls._schema() if 'wind' in json_: # for 'webapi', there will be nested Wind structure # for 'save' option, there should be no nested 'wind'. It is # removed, loaded and added back after deserialization schema.add(environment.WindSchema()) _to_dict = schema.deserialize(json_) return _to_dict