Example #1
0
    def __init__(self,
                 filename=None,
                 tide=None,
                 uncertain_duration=48,
                 **kwargs):
        """
        Uses super to invoke base class __init__ method.

        :param filename: file containing currents patterns for Cats

        Optional parameters (kwargs).
        Defaults are defined by CyCatsMover object.

        :param tide: a gnome.environment.Tide object to be attached to
                     CatsMover
        :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.

        :param uncertain_duration: how often does a given uncertain element
                                   gets reset
        :param uncertain_time_delay: when does the uncertainly kick in.
        :param up_cur_uncertain: Scale for uncertainty along the flow
        :param down_cur_uncertain: Scale for uncertainty along the flow
        :param right_cur_uncertain: Scale for uncertainty across the flow
        :param left_cur_uncertain: Scale for uncertainty across the flow
        :param uncertain_eddy_diffusion: Diffusion coefficient for
                                         eddy diffusion. Default is 0.
        :param uncertain_eddy_v0: Default is .1 (Check that this is still used)
        Remaining kwargs are passed onto Mover's __init__ using super.
        See Mover documentation for remaining valid kwargs.
        """

        if not os.path.exists(filename):
            raise ValueError(
                'Path for Cats filename does not exist: {0}'.format(filename))

        self._filename = filename

        # check if this is stored with cy_cats_mover?
        self.mover = CyCatsMover()
        self.mover.text_read(filename)
        if 'name' not in kwargs:
            kwargs['name'] = os.path.split(filename)[1]
        super(CatsMover, self).__init__(uncertain_duration=uncertain_duration,
                                        **kwargs)

        self._tide = None
        if tide is not None:
            self.tide = tide

        self.scale = kwargs.pop('scale', self.mover.scale_type)
        self.scale_value = kwargs.get('scale_value', self.mover.scale_value)

        self.up_cur_uncertain = kwargs.pop('up_cur_uncertain', .3)
        self.down_cur_uncertain = kwargs.pop('down_cur_uncertain', -.3)
        self.right_cur_uncertain = kwargs.pop('right_cur_uncertain', .1)
        self.left_cur_uncertain = kwargs.pop('left_cur_uncertain', -.1)
        self.uncertain_eddy_diffusion = kwargs.pop('uncertain_eddy_diffusion',
                                                   0)
        self.uncertain_eddy_v0 = kwargs.pop('uncertain_eddy_v0', .1)
        # TODO: no need to check for None since properties that are None
        # are not persisted

        if 'scale_refpoint' in kwargs:
            self.scale_refpoint = kwargs.pop('scale_refpoint')
            self.mover.compute_velocity_scale()

        if (self.scale and self.scale_value != 0.0
                and self.scale_refpoint is None):
            raise TypeError("Provide a reference point in 'scale_refpoint'.")
Example #2
0
class CatsMover(CurrentMoversBase):

    _schema = CatsMoverSchema

    def __init__(self,
                 filename=None,
                 tide=None,
                 uncertain_duration=48,
                 **kwargs):
        """
        Uses super to invoke base class __init__ method.

        :param filename: file containing currents patterns for Cats

        Optional parameters (kwargs).
        Defaults are defined by CyCatsMover object.

        :param tide: a gnome.environment.Tide object to be attached to
                     CatsMover
        :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.

        :param uncertain_duration: how often does a given uncertain element
                                   gets reset
        :param uncertain_time_delay: when does the uncertainly kick in.
        :param up_cur_uncertain: Scale for uncertainty along the flow
        :param down_cur_uncertain: Scale for uncertainty along the flow
        :param right_cur_uncertain: Scale for uncertainty across the flow
        :param left_cur_uncertain: Scale for uncertainty across the flow
        :param uncertain_eddy_diffusion: Diffusion coefficient for
                                         eddy diffusion. Default is 0.
        :param uncertain_eddy_v0: Default is .1 (Check that this is still used)
        Remaining kwargs are passed onto Mover's __init__ using super.
        See Mover documentation for remaining valid kwargs.
        """

        if not os.path.exists(filename):
            raise ValueError(
                'Path for Cats filename does not exist: {0}'.format(filename))

        self._filename = filename

        # check if this is stored with cy_cats_mover?
        self.mover = CyCatsMover()
        self.mover.text_read(filename)
        if 'name' not in kwargs:
            kwargs['name'] = os.path.split(filename)[1]
        super(CatsMover, self).__init__(uncertain_duration=uncertain_duration,
                                        **kwargs)

        self._tide = None
        if tide is not None:
            self.tide = tide

        self.scale = kwargs.pop('scale', self.mover.scale_type)
        self.scale_value = kwargs.get('scale_value', self.mover.scale_value)

        self.up_cur_uncertain = kwargs.pop('up_cur_uncertain', .3)
        self.down_cur_uncertain = kwargs.pop('down_cur_uncertain', -.3)
        self.right_cur_uncertain = kwargs.pop('right_cur_uncertain', .1)
        self.left_cur_uncertain = kwargs.pop('left_cur_uncertain', -.1)
        self.uncertain_eddy_diffusion = kwargs.pop('uncertain_eddy_diffusion',
                                                   0)
        self.uncertain_eddy_v0 = kwargs.pop('uncertain_eddy_v0', .1)
        # TODO: no need to check for None since properties that are None
        # are not persisted

        if 'scale_refpoint' in kwargs:
            self.scale_refpoint = kwargs.pop('scale_refpoint')
            self.mover.compute_velocity_scale()

        if (self.scale and self.scale_value != 0.0
                and self.scale_refpoint is None):
            raise TypeError("Provide a reference point in 'scale_refpoint'.")

    def __repr__(self):
        return 'CatsMover(filename={0})'.format(self.filename)

    # Properties
    filename = property(lambda self: self._filename,
                        lambda self, val: setattr(self, '_filename', val))

    scale = property(
        lambda self: bool(self.mover.scale_type),
        lambda self, val: setattr(self.mover, 'scale_type', int(val)))

    scale_value = property(
        lambda self: self.mover.scale_value,
        lambda self, val: setattr(self.mover, 'scale_value', val))

    up_cur_uncertain = property(
        lambda self: self.mover.up_cur_uncertain,
        lambda self, val: setattr(self.mover, 'up_cur_uncertain', val))

    down_cur_uncertain = property(
        lambda self: self.mover.down_cur_uncertain,
        lambda self, val: setattr(self.mover, 'down_cur_uncertain', val))

    right_cur_uncertain = property(
        lambda self: self.mover.right_cur_uncertain,
        lambda self, val: setattr(self.mover, 'right_cur_uncertain', val))

    left_cur_uncertain = property(
        lambda self: self.mover.left_cur_uncertain,
        lambda self, val: setattr(self.mover, 'left_cur_uncertain', val))

    uncertain_eddy_diffusion = property(
        lambda self: self.mover.uncertain_eddy_diffusion,
        lambda self, val: setattr(self.mover, 'uncertain_eddy_diffusion', val))

    uncertain_eddy_v0 = property(
        lambda self: self.mover.uncertain_eddy_v0,
        lambda self, val: setattr(self.mover, 'uncertain_eddy_v0', val))

    @property
    def ref_scale(self):
        return self.mover.ref_scale

    @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 tide(self):
        return self._tide

    @tide.setter
    def tide(self, tide_obj):
        if tide_obj is None:
            self._tide = tide_obj
            return
        if not isinstance(tide_obj, Tide):
            raise TypeError('tide must be of type environment.Tide')

        if isinstance(tide_obj.cy_obj, CyShioTime):
            self.mover.set_shio(tide_obj.cy_obj)
        elif isinstance(tide_obj.cy_obj, CyOSSMTime):
            self.mover.set_ossm(tide_obj.cy_obj)
        else:
            raise TypeError('Tide.cy_obj attribute must be either '
                            'CyOSSMTime or CyShioTime type for CatsMover.')

        self._tide = tide_obj

    @property
    def data_start(self):
        if self.tide is not None:
            return self.tide.data_start
        else:
            return MinusInfTime()

    @property
    def data_stop(self):
        if self.tide is not None:
            return self.tide.data_stop
        else:
            return InfTime()

    def get_grid_data(self):
        """
            Invokes the GetToplogyHdl method of TriGridVel_c object
        """
        # we are assuming cats are always triangle grids,
        # but may want to extend
        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)
        """
        velocities = self.mover._get_velocity_handle()
        ref_scale = self.ref_scale  # this needs to be computed, needs a time

        if self._tide is not None:
            time_value, _err = self._tide.cy_obj.get_time_value(model_time)
            tide = time_value[0][0]
        else:
            tide = 1

        velocities['u'] *= ref_scale * tide
        velocities['v'] *= ref_scale * tide

        return velocities
Example #3
0
class CatsMover(CurrentMoversBase):

    _schema = CatsMoverSchema

    def __init__(self,
                 filename=None,
                 tide=None,
                 uncertain_duration=48,
                 **kwargs):
        """
        Uses super to invoke base class __init__ method.

        :param filename: file containing currents patterns for Cats

        Optional parameters (kwargs).
        Defaults are defined by CyCatsMover object.

        :param tide: a gnome.environment.Tide object to be attached to
                     CatsMover
        :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.

        :param uncertain_duration: how often does a given uncertain element
                                   gets reset
        :param uncertain_time_delay: when does the uncertainly kick in.
        :param up_cur_uncertain: Scale for uncertainty along the flow
        :param down_cur_uncertain: Scale for uncertainty along the flow
        :param right_cur_uncertain: Scale for uncertainty across the flow
        :param left_cur_uncertain: Scale for uncertainty across the flow
        :param uncertain_eddy_diffusion: Diffusion coefficient for
                                         eddy diffusion. Default is 0.
        :param uncertain_eddy_v0: Default is .1 (Check that this is still used)
        Remaining kwargs are passed onto Mover's __init__ using super.
        See Mover documentation for remaining valid kwargs.
        """

        if not os.path.exists(filename):
            raise ValueError('Path for Cats filename does not exist: {0}'
                             .format(filename))

        self._filename = filename

        # check if this is stored with cy_cats_mover?
        self.mover = CyCatsMover()
        self.mover.text_read(filename)
        if 'name' not in kwargs:
            kwargs['name'] = os.path.split(filename)[1]
        super(CatsMover, self).__init__(uncertain_duration=uncertain_duration,
                                        **kwargs)

        self._tide = None
        if tide is not None:
            self.tide = tide

        self.scale = kwargs.pop('scale', self.mover.scale_type)
        self.scale_value = kwargs.get('scale_value',
                                      self.mover.scale_value)

        self.up_cur_uncertain = kwargs.pop('up_cur_uncertain', .3)
        self.down_cur_uncertain = kwargs.pop('down_cur_uncertain', -.3)
        self.right_cur_uncertain = kwargs.pop('right_cur_uncertain', .1)
        self.left_cur_uncertain = kwargs.pop('left_cur_uncertain', -.1)
        self.uncertain_eddy_diffusion = kwargs.pop('uncertain_eddy_diffusion',
                                                   0)
        self.uncertain_eddy_v0 = kwargs.pop('uncertain_eddy_v0', .1)
        # TODO: no need to check for None since properties that are None
        # are not persisted

        if 'scale_refpoint' in kwargs:
            self.scale_refpoint = kwargs.pop('scale_refpoint')
            self.mover.compute_velocity_scale()

        if (self.scale and
            self.scale_value != 0.0 and
                self.scale_refpoint is None):
            raise TypeError("Provide a reference point in 'scale_refpoint'.")

    def __repr__(self):
        return 'CatsMover(filename={0})'.format(self.filename)

    # Properties
    filename = property(lambda self: self._filename,
                        lambda self, val: setattr(self, '_filename', val))

    scale = property(lambda self: bool(self.mover.scale_type),
                     lambda self, val: setattr(self.mover,
                                               'scale_type',
                                               int(val)))

    scale_value = property(lambda self: self.mover.scale_value,
                           lambda self, val: setattr(self.mover,
                                                     'scale_value',
                                                     val))

    up_cur_uncertain = property(lambda self: self.mover.up_cur_uncertain,
                                lambda self, val: setattr(self.mover,
                                                          'up_cur_uncertain',
                                                          val))

    down_cur_uncertain = property(lambda self: self.mover.down_cur_uncertain,
                                  lambda self, val:
                                  setattr(self.mover, 'down_cur_uncertain',
                                          val))

    right_cur_uncertain = property(lambda self: self.mover.right_cur_uncertain,
                                   lambda self, val:
                                   setattr(self.mover, 'right_cur_uncertain',
                                           val))

    left_cur_uncertain = property(lambda self: self.mover.left_cur_uncertain,
                                  lambda self, val:
                                  setattr(self.mover, 'left_cur_uncertain',
                                          val))

    uncertain_eddy_diffusion = property(lambda self:
                                        self.mover.uncertain_eddy_diffusion,
                                        lambda self, val:
                                        setattr(self.mover,
                                                'uncertain_eddy_diffusion',
                                                val))

    uncertain_eddy_v0 = property(lambda self: self.mover.uncertain_eddy_v0,
                                 lambda self, val: setattr(self.mover,
                                                           'uncertain_eddy_v0',
                                                           val))

    @property
    def ref_scale(self):
        return self.mover.ref_scale

    @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 tide(self):
        return self._tide

    @tide.setter
    def tide(self, tide_obj):
        if tide_obj is None:
            self._tide = tide_obj
            return
        if not isinstance(tide_obj, Tide):
            raise TypeError('tide must be of type environment.Tide')

        if isinstance(tide_obj.cy_obj, CyShioTime):
            self.mover.set_shio(tide_obj.cy_obj)
        elif isinstance(tide_obj.cy_obj, CyOSSMTime):
            self.mover.set_ossm(tide_obj.cy_obj)
        else:
            raise TypeError('Tide.cy_obj attribute must be either '
                            'CyOSSMTime or CyShioTime type for CatsMover.')

        self._tide = tide_obj

    @property
    def data_start(self):
        if self.tide is not None:
            return self.tide.data_start
        else:
            return MinusInfTime()

    @property
    def data_stop(self):
        if self.tide is not None:
            return self.tide.data_stop
        else:
            return InfTime()

    def get_grid_data(self):
        """
            Invokes the GetToplogyHdl method of TriGridVel_c object
        """
        # we are assuming cats are always triangle grids,
        # but may want to extend
        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)
        """
        velocities = self.mover._get_velocity_handle()
        ref_scale = self.ref_scale  # this needs to be computed, needs a time

        if self._tide is not None:
            time_value, _err = self._tide.cy_obj.get_time_value(model_time)
            tide = time_value[0][0]
        else:
            tide = 1

        velocities['u'] *= ref_scale * tide
        velocities['v'] *= ref_scale * tide

        return velocities
Example #4
0
    def __init__(self,
                 filename=None,
                 tide=None,
                 uncertain_duration=48,
                 **kwargs):
        """
        Uses super to invoke base class __init__ method.

        :param filename: file containing currents patterns for Cats

        Optional parameters (kwargs).
        Defaults are defined by CyCatsMover object.

        :param tide: a gnome.environment.Tide object to be attached to
                     CatsMover
        :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.

        :param uncertain_duration: how often does a given uncertain element
                                   gets reset
        :param uncertain_time_delay: when does the uncertainly kick in.
        :param up_cur_uncertain: Scale for uncertainty along the flow
        :param down_cur_uncertain: Scale for uncertainty along the flow
        :param right_cur_uncertain: Scale for uncertainty across the flow
        :param left_cur_uncertain: Scale for uncertainty across the flow
        :param uncertain_eddy_diffusion: Diffusion coefficient for
                                         eddy diffusion. Default is 0.
        :param uncertain_eddy_v0: Default is .1 (Check that this is still used)
        Remaining kwargs are passed onto Mover's __init__ using super.
        See Mover documentation for remaining valid kwargs.
        """

        if not os.path.exists(filename):
            raise ValueError('Path for Cats filename does not exist: {0}'
                             .format(filename))

        self._filename = filename

        # check if this is stored with cy_cats_mover?
        self.mover = CyCatsMover()
        self.mover.text_read(filename)
        if 'name' not in kwargs:
            kwargs['name'] = os.path.split(filename)[1]
        super(CatsMover, self).__init__(uncertain_duration=uncertain_duration,
                                        **kwargs)

        self._tide = None
        if tide is not None:
            self.tide = tide

        self.scale = kwargs.pop('scale', self.mover.scale_type)
        self.scale_value = kwargs.get('scale_value',
                                      self.mover.scale_value)

        self.up_cur_uncertain = kwargs.pop('up_cur_uncertain', .3)
        self.down_cur_uncertain = kwargs.pop('down_cur_uncertain', -.3)
        self.right_cur_uncertain = kwargs.pop('right_cur_uncertain', .1)
        self.left_cur_uncertain = kwargs.pop('left_cur_uncertain', -.1)
        self.uncertain_eddy_diffusion = kwargs.pop('uncertain_eddy_diffusion',
                                                   0)
        self.uncertain_eddy_v0 = kwargs.pop('uncertain_eddy_v0', .1)
        # TODO: no need to check for None since properties that are None
        # are not persisted

        if 'scale_refpoint' in kwargs:
            self.scale_refpoint = kwargs.pop('scale_refpoint')
            self.mover.compute_velocity_scale()

        if (self.scale and
            self.scale_value != 0.0 and
                self.scale_refpoint is None):
            raise TypeError("Provide a reference point in 'scale_refpoint'.")
Example #5
0
class CatsMover(CurrentMoversBase, serializable.Serializable):

    _state = copy.deepcopy(CurrentMoversBase._state)

    _update = [
        "scale",
        "scale_refpoint",
        "scale_value",
        "up_cur_uncertain",
        "down_cur_uncertain",
        "right_cur_uncertain",
        "left_cur_uncertain",
        "uncertain_eddy_diffusion",
        "uncertain_eddy_v0",
    ]
    _create = []
    _create.extend(_update)
    _state.add(update=_update, save=_create)
    _state.add_field(
        [
            serializable.Field("filename", save=True, read=True, isdatafile=True, test_for_eq=False),
            serializable.Field("tide", save=True, update=True, save_reference=True),
        ]
    )
    _schema = CatsMoverSchema

    def __init__(self, filename, tide=None, uncertain_duration=48, **kwargs):
        """
        Uses super to invoke base class __init__ method.

        :param filename: file containing currents patterns for Cats

        Optional parameters (kwargs).
        Defaults are defined by CyCatsMover object.

        :param tide: a gnome.environment.Tide object to be attached to
                     CatsMover
        :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.

        :param uncertain_duration: how often does a given uncertain element
                                   gets reset
        :param uncertain_time_delay: when does the uncertainly kick in.
        :param up_cur_uncertain: Scale for uncertainty along the flow
        :param down_cur_uncertain: Scale for uncertainty along the flow
        :param right_cur_uncertain: Scale for uncertainty across the flow
        :param left_cur_uncertain: Scale for uncertainty across the flow
        :param uncertain_eddy_diffusion: Diffusion coefficient for
                                         eddy diffusion. Default is 0.
        :param uncertain_eddy_v0: Default is .1 (Check that this is still used)
        Remaining kwargs are passed onto Mover's __init__ using super.
        See Mover documentation for remaining valid kwargs.
        """
        if not os.path.exists(filename):
            raise ValueError("Path for Cats filename does not exist: {0}".format(filename))

        self._filename = filename

        # check if this is stored with cy_cats_mover?
        self.mover = CyCatsMover()
        self.mover.text_read(filename)
        self.name = os.path.split(filename)[1]

        self._tide = None
        if tide is not None:
            self.tide = tide

        self.scale = kwargs.pop("scale", self.mover.scale_type)
        self.scale_value = kwargs.get("scale_value", self.mover.scale_value)

        self.up_cur_uncertain = kwargs.pop("up_cur_uncertain", 0.3)
        self.down_cur_uncertain = kwargs.pop("down_cur_uncertain", -0.3)
        self.right_cur_uncertain = kwargs.pop("right_cur_uncertain", 0.1)
        self.left_cur_uncertain = kwargs.pop("left_cur_uncertain", -0.1)
        self.uncertain_eddy_diffusion = kwargs.pop("uncertain_eddy_diffusion", 0)
        self.uncertain_eddy_v0 = kwargs.pop("uncertain_eddy_v0", 0.1)
        # TODO: no need to check for None since properties that are None
        # are not persisted

        if "scale_refpoint" in kwargs:
            self.scale_refpoint = kwargs.pop("scale_refpoint")
            self.mover.compute_velocity_scale()

        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(CatsMover, self).__init__(uncertain_duration, **kwargs)

    def __repr__(self):
        return "CatsMover(filename={0})".format(self.filename)

    # Properties
    filename = property(lambda self: basename(self._filename), lambda self, val: setattr(self, "_filename", val))

    scale = property(
        lambda self: bool(self.mover.scale_type), lambda self, val: setattr(self.mover, "scale_type", int(val))
    )

    scale_value = property(
        lambda self: self.mover.scale_value, lambda self, val: setattr(self.mover, "scale_value", val)
    )

    up_cur_uncertain = property(
        lambda self: self.mover.up_cur_uncertain, lambda self, val: setattr(self.mover, "up_cur_uncertain", val)
    )

    down_cur_uncertain = property(
        lambda self: self.mover.down_cur_uncertain, lambda self, val: setattr(self.mover, "down_cur_uncertain", val)
    )

    right_cur_uncertain = property(
        lambda self: self.mover.right_cur_uncertain, lambda self, val: setattr(self.mover, "right_cur_uncertain", val)
    )

    left_cur_uncertain = property(
        lambda self: self.mover.left_cur_uncertain, lambda self, val: setattr(self.mover, "left_cur_uncertain", val)
    )

    uncertain_eddy_diffusion = property(
        lambda self: self.mover.uncertain_eddy_diffusion,
        lambda self, val: setattr(self.mover, "uncertain_eddy_diffusion", val),
    )

    uncertain_eddy_v0 = property(
        lambda self: self.mover.uncertain_eddy_v0, lambda self, val: setattr(self.mover, "uncertain_eddy_v0", val)
    )

    @property
    def ref_scale(self):
        return self.mover.ref_scale

    @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.0)
        else:
            self.mover.ref_point = val

        self.mover.compute_velocity_scale()

    @property
    def tide(self):
        return self._tide

    @tide.setter
    def tide(self, tide_obj):
        if not isinstance(tide_obj, environment.Tide):
            raise TypeError("tide must be of type environment.Tide")

        if isinstance(tide_obj.cy_obj, CyShioTime):
            self.mover.set_shio(tide_obj.cy_obj)
        elif isinstance(tide_obj.cy_obj, CyOSSMTime):
            self.mover.set_ossm(tide_obj.cy_obj)
        else:
            raise TypeError("Tide.cy_obj attribute must be either " "CyOSSMTime or CyShioTime type for CatsMover.")

        self._tide = tide_obj

    def get_grid_data(self):
        """
            Invokes the GetToplogyHdl method of TriGridVel_c object
        """
        # we are assuming cats are always triangle grids,
        # but may want to extend
        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)
        """
        velocities = self.mover._get_velocity_handle()
        ref_scale = self.ref_scale  # this needs to be computed, needs a time

        if self._tide is not None:
            time_value = self._tide.cy_obj.get_time_value(model_time)
            tide = time_value[0][0]
        else:
            tide = 1

        velocities["u"] *= ref_scale * tide
        velocities["v"] *= ref_scale * tide

        return velocities

    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
        """
        toserial = self.to_serialize(json_)
        schema = self.__class__._schema()

        if json_ == "save":
            toserial["filename"] = self._filename

        if "tide" in toserial:
            schema.add(environment.TideSchema(name="tide"))

        return schema.serialize(toserial)

    @classmethod
    def deserialize(cls, json_):
        """
        append correct schema for wind object
        """
        if not cls.is_sparse(json_):
            schema = cls._schema()

            if "tide" in json_:
                schema.add(environment.TideSchema())

            return schema.deserialize(json_)
        else:
            return json_