Example #1
0
class GridCurrentMover(CurrentMoversBase):

    _schema = GridCurrentMoverSchema

    def __init__(self, filename,
                 topology_file=None,
                 extrapolate=False,
                 time_offset=0,
                 current_scale=1,
                 uncertain_along=0.5,
                 uncertain_across=0.25,
                 num_method='Euler',
                 **kwargs):
        """
        Initialize a GridCurrentMover

        :param filename: absolute or relative path to the data file:
                         could be netcdf or filelist
        :param topology_file=None: absolute or relative path to topology file.
                                   If not given, the GridCurrentMover will
                                   compute the topology from the data file.

        :param active_range: Range of datetimes for when the mover should be
                             active
        :type active_range: 2-tuple of datetimes

        :param current_scale: Value to scale current data
        :param uncertain_duration: how often does a given uncertain element
                                   get reset
        :param uncertain_time_delay: when does the uncertainly kick in.
        :param uncertain_cross: Scale for uncertainty perpendicular to the flow
        :param uncertain_along: Scale for uncertainty parallel to the flow
        :param extrapolate: Allow current data to be extrapolated
                            before and after file data
        :param time_offset: Time zone shift if data is in GMT
        :param num_method: Numerical method for calculating movement delta.
                           Default Euler
                           option: Runga-Kutta 4 (RK4)

        uses super, super(GridCurrentMover,self).__init__(\*\*kwargs)
        """
        # if child is calling, the self.mover is set by child - do not reset
        if type(self) == GridCurrentMover:
            self.mover = CyGridCurrentMover()

        if not os.path.exists(filename):
            raise ValueError('Path for current 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))

        super(GridCurrentMover, self).__init__(**kwargs)

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

        # check if this is stored with cy_gridcurrent_mover?
        self.topology_file = topology_file
        self.current_scale = current_scale
        self.uncertain_along = uncertain_along
        self.uncertain_across = uncertain_across

        self.mover.text_read(filename, topology_file)
        self.mover.extrapolate_in_time(extrapolate)
        self.mover.offset_time(time_offset * 3600.)

        self.num_method = num_method

        if self.topology_file is None:
            # this causes an error saving for currents that don't have topology
            #self.topology_file = filename + '.dat'
            #self.export_topology(self.topology_file)
            temp_topology_file = filename + '.dat'
            self.export_topology(temp_topology_file)
            if os.path.exists(temp_topology_file):
                self.topology_file = temp_topology_file

    def __repr__(self):
        return ('GridCurrentMover('
                'uncertain_duration={0.uncertain_duration},'
                'uncertain_time_delay={0.uncertain_time_delay}, '
                'uncertain_cross={0.uncertain_cross}, '
                'uncertain_along={0.uncertain_along}, '
                'active_range={1.active_range}, '
                'on={1.on})'
                .format(self.mover, self))

    def __str__(self):
        return ('GridCurrentMover - current _state.\n'
                '  uncertain_duration={0.uncertain_duration}\n'
                '  uncertain_time_delay={0.uncertain_time_delay}\n'
                '  uncertain_cross={0.uncertain_cross}\n'
                '  uncertain_along={0.uncertain_along}\n'
                '  active_range time={1.active_range}\n'
                '  current on/off status={1.on}'
                .format(self.mover, self))

    # Define properties using lambda functions: uses lambda function, which are
    # accessible via fget/fset as follows:
    uncertain_cross = property(lambda self: self.mover.uncertain_cross,
                               lambda self, val: setattr(self.mover,
                                                         'uncertain_cross',
                                                         val))

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

    current_scale = property(lambda self: self.mover.current_scale,
                             lambda self, val: setattr(self.mover,
                                                       'current_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.))

    @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())

    @property
    def num_method(self):
        return self._num_method

    @num_method.setter
    def num_method(self, val):
        self.mover.num_method = val
        self._num_method = val

    @property
    def is_data_on_cells(self):
        return self.mover._is_data_on_cells()

    def get_grid_data(self):
        """
            The main function for getting grid data from the mover
        """
        if self.mover._is_triangle_grid():
            return self.get_triangles()
        else:
            return self.get_cells()

    def get_center_points(self):
        if self.mover._is_triangle_grid():
            if self.mover._is_data_on_cells():
                return self.get_triangle_center_points()
            else:
                return self.get_points()
        else:
            return self.get_cell_center_points()

    def get_scaled_velocities(self, time):
        """
        :param model_time=0:
        """
        num_tri = self.mover.get_num_triangles()

        # will need to update this for regular grids
        if self.mover._is_triangle_grid():
            if self.mover._is_data_on_cells():
                num_cells = num_tri
            else:
                num_vertices = self.mover.get_num_points()
                num_cells = num_vertices
        elif self.mover._is_regular_grid():
            num_cells = self.mover.get_num_points()
        else:
            num_cells = num_tri / 2

        vels = np.zeros(num_cells, dtype=basic_types.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.)

    def get_offset_time(self):
        """
        :param offset_time=0: allow data to be in GMT with a time zone offset
                              (hours).
        """
        return self.mover.get_offset_time() / 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()

    def get_num_method(self):
        return self.mover.num_method
Example #2
0
class GridCurrentMover(CurrentMoversBase):

    _schema = GridCurrentMoverSchema

    def __init__(self,
                 filename,
                 topology_file=None,
                 extrapolate=False,
                 time_offset=0,
                 current_scale=1,
                 uncertain_along=0.5,
                 uncertain_across=0.25,
                 num_method='Euler',
                 **kwargs):
        """
        Initialize a GridCurrentMover

        :param filename: absolute or relative path to the data file:
                         could be netcdf or filelist
        :param topology_file=None: absolute or relative path to topology file.
                                   If not given, the GridCurrentMover will
                                   compute the topology from the data file.

        :param active_range: Range of datetimes for when the mover should be
                             active
        :type active_range: 2-tuple of datetimes

        :param current_scale: Value to scale current data
        :param uncertain_duration: how often does a given uncertain element
                                   get reset
        :param uncertain_time_delay: when does the uncertainly kick in.
        :param uncertain_cross: Scale for uncertainty perpendicular to the flow
        :param uncertain_along: Scale for uncertainty parallel to the flow
        :param extrapolate: Allow current data to be extrapolated
                            before and after file data
        :param time_offset: Time zone shift if data is in GMT
        :param num_method: Numerical method for calculating movement delta.
                           Default Euler
                           option: Runga-Kutta 4 (RK4)

        uses super, super(GridCurrentMover,self).__init__(\*\*kwargs)
        """
        # if child is calling, the self.mover is set by child - do not reset
        if type(self) == GridCurrentMover:
            self.mover = CyGridCurrentMover()

        if not os.path.exists(filename):
            raise ValueError(
                'Path for current 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))

        super(GridCurrentMover, self).__init__(**kwargs)

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

        # check if this is stored with cy_gridcurrent_mover?
        self.topology_file = topology_file
        self.current_scale = current_scale
        self.uncertain_along = uncertain_along
        self.uncertain_across = uncertain_across

        self.mover.text_read(filename, topology_file)
        self.mover.extrapolate_in_time(extrapolate)
        self.mover.offset_time(time_offset * 3600.)

        self.num_method = num_method

        if self.topology_file is None:
            # this causes an error saving for currents that don't have topology
            #self.topology_file = filename + '.dat'
            #self.export_topology(self.topology_file)
            temp_topology_file = filename + '.dat'
            self.export_topology(temp_topology_file)
            if os.path.exists(temp_topology_file):
                self.topology_file = temp_topology_file

    def __repr__(self):
        return ('GridCurrentMover('
                'uncertain_duration={0.uncertain_duration},'
                'uncertain_time_delay={0.uncertain_time_delay}, '
                'uncertain_cross={0.uncertain_cross}, '
                'uncertain_along={0.uncertain_along}, '
                'active_range={1.active_range}, '
                'on={1.on})'.format(self.mover, self))

    def __str__(self):
        return ('GridCurrentMover - current _state.\n'
                '  uncertain_duration={0.uncertain_duration}\n'
                '  uncertain_time_delay={0.uncertain_time_delay}\n'
                '  uncertain_cross={0.uncertain_cross}\n'
                '  uncertain_along={0.uncertain_along}\n'
                '  active_range time={1.active_range}\n'
                '  current on/off status={1.on}'.format(self.mover, self))

    # Define properties using lambda functions: uses lambda function, which are
    # accessible via fget/fset as follows:
    uncertain_cross = property(
        lambda self: self.mover.uncertain_cross,
        lambda self, val: setattr(self.mover, 'uncertain_cross', val))

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

    current_scale = property(
        lambda self: self.mover.current_scale,
        lambda self, val: setattr(self.mover, 'current_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.))

    @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())

    @property
    def num_method(self):
        return self._num_method

    @num_method.setter
    def num_method(self, val):
        self.mover.num_method = val
        self._num_method = val

    @property
    def is_data_on_cells(self):
        return self.mover._is_data_on_cells()

    def get_grid_data(self):
        """
            The main function for getting grid data from the mover
        """
        if self.mover._is_triangle_grid():
            return self.get_triangles()
        else:
            return self.get_cells()

    def get_center_points(self):
        if self.mover._is_triangle_grid():
            if self.mover._is_data_on_cells():
                return self.get_triangle_center_points()
            else:
                return self.get_points()
        else:
            return self.get_cell_center_points()

    def get_scaled_velocities(self, time):
        """
        :param model_time=0:
        """
        num_tri = self.mover.get_num_triangles()

        # will need to update this for regular grids
        if self.mover._is_triangle_grid():
            if self.mover._is_data_on_cells():
                num_cells = num_tri
            else:
                num_vertices = self.mover.get_num_points()
                num_cells = num_vertices
        elif self.mover._is_regular_grid():
            num_cells = self.mover.get_num_points()
        else:
            num_cells = num_tri / 2

        vels = np.zeros(num_cells, dtype=basic_types.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.)

    def get_offset_time(self):
        """
        :param offset_time=0: allow data to be in GMT with a time zone offset
                              (hours).
        """
        return self.mover.get_offset_time() / 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()

    def get_num_method(self):
        return self.mover.num_method
class GridCurrentMover(CurrentMoversBase, serializable.Serializable):

    _update = ['uncertain_cross', 'uncertain_along', 'current_scale']
    _save = ['uncertain_cross', 'uncertain_along', 'current_scale']
    _state = copy.deepcopy(CurrentMoversBase._state)

    _state.add(update=_update, save=_save)
    _state.add_field([serializable.Field('filename',
                                         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 = GridCurrentMoverSchema

    def __init__(self, filename,
                 topology_file=None,
                 extrapolate=False,
                 time_offset=0,
                 current_scale=1,
                 uncertain_along=0.5,
                 uncertain_across=0.25,
                 **kwargs):
        """
        Initialize a GridCurrentMover

        :param filename: absolute or relative path to the data file:
                         could be netcdf or filelist
        :param topology_file=None: absolute or relative path to topology file.
                                   If not given, the GridCurrentMover will
                                   compute the topology from the data file.
        :param active_start: datetime when the mover should be active
        :param active_stop: datetime after which the mover should be inactive
        :param current_scale: Value to scale current data
        :param uncertain_duration: how often does a given uncertain element
                                   get reset
        :param uncertain_time_delay: when does the uncertainly kick in.
        :param uncertain_cross: Scale for uncertainty perpendicular to the flow
        :param uncertain_along: Scale for uncertainty parallel to the flow
        :param extrapolate: Allow current data to be extrapolated
                            before and after file data
        :param time_offset: Time zone shift if data is in GMT

        uses super, super(GridCurrentMover,self).__init__(\*\*kwargs)
        """

        # if child is calling, the self.mover is set by child - do not reset
        if type(self) == GridCurrentMover:
            self.mover = CyGridCurrentMover()

        if not os.path.exists(filename):
            raise ValueError('Path for current 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))

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

        # check if this is stored with cy_gridcurrent_mover?
        self.topology_file = topology_file
        self.current_scale = current_scale
        self.uncertain_along = uncertain_along
        self.uncertain_across = uncertain_across
        self.mover.text_read(filename, topology_file)
        self.mover.extrapolate_in_time(extrapolate)
        self.mover.offset_time(time_offset * 3600.)

        super(GridCurrentMover, self).__init__(**kwargs)

    def __repr__(self):
        return ('GridCurrentMover('
                'uncertain_duration={0.uncertain_duration},'
                'uncertain_time_delay={0.uncertain_time_delay}, '
                'uncertain_cross={0.uncertain_cross}, '
                'uncertain_along={0.uncertain_along}, '
                'active_start={1.active_start}, '
                'active_stop={1.active_stop}, '
                'on={1.on})'.format(self.mover, self))

    def __str__(self):
        return ('GridCurrentMover - current _state.\n'
                '  uncertain_duration={0.uncertain_duration}\n'
                '  uncertain_time_delay={0.uncertain_time_delay}\n'
                '  uncertain_cross={0.uncertain_cross}\n'
                '  uncertain_along={0.uncertain_along}\n'
                '  active_start time={1.active_start}\n'
                '  active_stop time={1.active_stop}\n'
                '  current on/off status={1.on}'
                .format(self.mover, self))

    # Define properties using lambda functions: uses lambda function, which are
    # accessible via fget/fset as follows:
    uncertain_cross = property(lambda self: self.mover.uncertain_cross,
                               lambda self, val: setattr(self.mover,
                                                         'uncertain_cross',
                                                         val))

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

    current_scale = property(lambda self: self.mover.current_scale,
                             lambda self, val: setattr(self.mover,
                                                       'current_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):
        """
            The main function for getting grid data from the mover
        """
        if self.mover._is_triangle_grid():
            return self.get_triangles()
        else:
            return self.get_cells()

    def get_center_points(self):
        if self.mover._is_triangle_grid():
            return self.get_triangle_center_points()
        else:
            return self.get_cell_center_points()

    def get_scaled_velocities(self, time):
        """
        :param model_time=0:
        """
        num_tri = self.mover.get_num_triangles()
        vels = np.zeros(num_tri, dtype=basic_types.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.)

    def get_offset_time(self):
        """
        :param offset_time=0: allow data to be in GMT with a time zone offset
                              (hours).
        """
        return (self.mover.get_offset_time()) / 3600.