Esempio n. 1
0
    def _obj_to_create(self, filename):
        """
        open file, read a few lines to determine if it is an ossm file
        or a shio file
        """
        # mode 'U' means universal newline support
        fh = open(filename, 'rU')

        lines = [fh.readline() for i in range(4)]

        if len(lines[1]) == 0:
            # look for \r for lines instead of \n
            lines = string.split(lines[0], '\r', 4)

        if len(lines[1]) == 0:
            # if this is still 0, then throw an error!
            raise ValueError('This does not appear to be a valid file format '
                             'that can be read by OSSM or Shio to get '
                             'tide information')

        # look for following keywords to determine if it is a Shio or OSSM file
        shio_file = ['[StationInfo]', 'Type=', 'Name=', 'Latitude=']

        if all([shio_file[i] == (lines[i])[:len(shio_file[i])]
                for i in range(4)]):
            return CyShioTime(filename)
        elif len(string.split(lines[3], ',')) == 7:
            # maybe log / display a warning that v=0 for tide file and will be
            # ignored
            # if float( string.split(lines[3],',')[-1]) != 0.0:
            return CyOSSMTime(filename, file_contains=tsformat('uv'))
        else:
            raise ValueError('This does not appear to be a valid file format '
                             'that can be read by OSSM or Shio to get '
                             'tide information')
Esempio n. 2
0
    def _obj_to_create(self, filename):
        """
        open file, read a few lines to determine if it is an ossm file
        or a shio file
        """
        # mode 'U' means universal newline support
        fh = open(filename, 'rU')

        lines = [fh.readline() for i in range(4)]

        if len(lines[1]) == 0:
            # look for \r for lines instead of \n
            lines = string.split(lines[0], '\r', 4)

        if len(lines[1]) == 0:
            # if this is still 0, then throw an error!
            raise ValueError('This does not appear to be a valid file format '
                             'that can be read by OSSM or Shio to get '
                             'tide information')

        # look for following keywords to determine if it is a Shio or OSSM file
        shio_file = ['[StationInfo]', 'Type=', 'Name=', 'Latitude=']

        if all([shio_file[i] == (lines[i])[:len(shio_file[i])]
                for i in range(4)]):
            return CyShioTime(filename)
        elif len(string.split(lines[3], ',')) == 7:
            # maybe log / display a warning that v=0 for tide file and will be
            # ignored
            # if float( string.split(lines[3],',')[-1]) != 0.0:
            return CyTimeseries(filename, file_format=tsformat('uv'))
        else:
            raise ValueError('This does not appear to be a valid file format '
                             'that can be read by OSSM or Shio to get '
                             'tide information')
Esempio n. 3
0
    def __init__(self, timeseries=None, filename=None, format='uv'):
        """
        Initializes a timeseries object from either a timeseries or datafile
        containing the timeseries. If both timeseries and file are given,
        it will read data from the file

        If neither are given, timeseries gets initialized as:

            timeseries = np.zeros((1,), dtype=basic_types.datetime_value_2d)

        If user provides timeseries, the default format is 'uv'. The C++
        stores the data in 'uv' format - transformations are done in this
        Python code (set_timeseries(), get_timeseries()).

        C++ code only transforms the data from 'r-theta' to 'uv' format if
        data is read from file. And this happens during initialization because
        C++ stores data in 'uv' format internally.

        Units option are not included - let derived classes manage units since
        the units for CyTimeseries (OSSMTimeValue_c) are limited. No unit
        conversion is performed when get_timeseries, set_timeseries is invoked.
        It does, however convert between 'uv' and 'r-theta' depending on format
        specified. Choose format='uv' if no transformation is desired.

        .. note:: For the Wind datafiles, the units will get read from the
        file. These are stored in ossm.user_units. It would be ideal to remove
        units and unit conversion from here, but can't completely do away with
        it since C++ file reading uses/sets it. But, managing units is
        responsibility of derived objects.

        All other keywords are optional

        :param timeseries: numpy array containing time_value_pair
        :type timeseries: numpy.ndarray containing
            basic_types.datetime_value_2d or basic_types.datetime_value_1d. It
            gets converted to an array containging basic_types.time_value_pair
            datatype since that's what the C++ code expects
        :param filename: path to a timeseries file from which to read data.
            Datafile must contain either a 3 line or a 5 line header with
            following info:

            1. Station Name: name of the station as a string
            2. (long, lat, z): station location as tuple containing floats
            3. units: for wind this is knots, meteres per second
            or miles per hour. For datafile containing something other than
            velocity, this should be 'undefined'

        Optional parameters (kwargs):

        :param format: (Optional) default timeseries format is
            magnitude direction: 'r-theta'
        :type format: string 'r-theta' or 'uv'. Default is 'r-theta'.
            Converts string to integer defined by
            gnome.basic_types.ts_format.*
            TODO: 'format' is a python builtin keyword.  We should
            not use it as an argument name
        """
        if (timeseries is None and filename is None):
            timeseries = np.array([(sec_to_date(zero_time()), [0.0, 0.0])],
                                  dtype=basic_types.datetime_value_2d)

        self._filename = filename

        if filename is None:
            # will raise an Exception if it fails
            self._check_timeseries(timeseries)

            datetime_value_2d = self._xform_input_timeseries(timeseries)
            time_value_pair = to_time_value_pair(datetime_value_2d, format)

            self.ossm = CyTimeseries(timeseries=time_value_pair)
        else:
            ts_format = tsformat(format)
            self.ossm = CyTimeseries(filename=self._filename,
                                     file_format=ts_format)
Esempio n. 4
0
    def __init__(self, timeseries=None, filename=None, format='uv'):
        """
        Initializes a timeseries object from either a timeseries or datafile
        containing the timeseries. If both timeseries and file are given,
        it will read data from the file

        If neither are given, timeseries gets initialized as:

            timeseries = np.zeros((1,), dtype=basic_types.datetime_value_2d)

        If user provides timeseries, the default format is 'uv'. The C++
        stores the data in 'uv' format - transformations are done in this
        Python code (set_timeseries(), get_timeseries()).

        C++ code only transforms the data from 'r-theta' to 'uv' format if
        data is read from file. And this happens during initialization because
        C++ stores data in 'uv' format internally.

        Units option are not included - let derived classes manage units since
        the units for CyTimeseries (OSSMTimeValue_c) are limited. No unit
        conversion is performed when get_timeseries, set_timeseries is invoked.
        It does, however convert between 'uv' and 'r-theta' depending on format
        specified. Choose format='uv' if no transformation is desired.

        .. note:: For the Wind datafiles, the units will get read from the
        file. These are stored in ossm.user_units. It would be ideal to remove
        units and unit conversion from here, but can't completely do away with
        it since C++ file reading uses/sets it. But, managing units is
        responsibility of derived objects.

        All other keywords are optional

        :param timeseries: numpy array containing time_value_pair
        :type timeseries: numpy.ndarray containing
            basic_types.datetime_value_2d or basic_types.datetime_value_1d. It
            gets converted to an array containging basic_types.time_value_pair
            datatype since that's what the C++ code expects
        :param filename: path to a timeseries file from which to read data.
            Datafile must contain either a 3 line or a 5 line header with
            following info:

            1. Station Name: name of the station as a string
            2. (long, lat, z): station location as tuple containing floats
            3. units: for wind this is knots, meteres per second
            or miles per hour. For datafile containing something other than
            velocity, this should be 'undefined'

        Optional parameters (kwargs):

        :param format: (Optional) default timeseries format is
            magnitude direction: 'r-theta'
        :type format: string 'r-theta' or 'uv'. Default is 'r-theta'.
            Converts string to integer defined by
            gnome.basic_types.ts_format.*
            TODO: 'format' is a python builtin keyword.  We should
            not use it as an argument name
        """
        if (timeseries is None and filename is None):
            timeseries = np.array([(sec_to_date(zero_time()), [0.0, 0.0])],
                                  dtype=basic_types.datetime_value_2d)

        self._filename = filename

        if filename is None:
            if self._check_timeseries(timeseries):
                datetime_value_2d = self._xform_input_timeseries(timeseries)

                time_value_pair = to_time_value_pair(datetime_value_2d, format)
                self.ossm = CyTimeseries(timeseries=time_value_pair)
            else:
                raise ValueError('Bad timeseries as input')
        else:
            ts_format = tsformat(format)
            self.ossm = CyTimeseries(filename=self._filename,
                                     file_format=ts_format)
Esempio n. 5
0
    def __init__(self, timeseries=None, units=None,
                 filename=None, format='r-theta',
                 latitude=None, longitude=None,
                 **kwargs):
        """
        Initializes a wind object from timeseries or datafile
        If both are given, it will read data from the file

        If neither are given, timeseries gets initialized as:

            timeseries = np.zeros((1,), dtype=basic_types.datetime_value_2d)
            units = 'mps'

        If user provides timeseries, they *must* also provide units

        All other keywords are optional. Optional parameters (kwargs):

        :param timeseries: numpy array containing time_value_pair
        :type timeseries: numpy.ndarray[basic_types.time_value_pair, ndim=1]
        :param filename: path to a long wind file from which to read wind data
        :param units: units associated with the timeseries data. If 'filename'
            is given, then units are read in from the file.
            get_timeseries() will use these as default units to
            output data, unless user specifies otherwise.
            These units must be valid as defined in the hazpy
            unit_conversion module:
            unit_conversion.GetUnitNames('Velocity')
        :type units:  string, for example: 'knot', 'meter per second',
            'mile per hour' etc.
            Default units for input/output timeseries data
        :param format: (Optional) default timeseries format is
            magnitude direction: 'r-theta'
        :type format: string 'r-theta' or 'uv'. Default is 'r-theta'.
            Converts string to integer defined by
            gnome.basic_types.ts_format.*
            TODO: 'format' is a python builtin keyword.  We should
            not use it as an argument name
        :param name: (Optional) human readable string for wind object name.
            Default is filename if data is from file or "Wind Object"
        :param source_type: (Optional) Default is undefined, but can be one of
            the following: ['buoy', 'manual', 'undefined', 'file', 'nws']
            If data is read from file, then it is 'file'
        :param latitude: (Optional) latitude of station or location where
            wind data is obtained from NWS
        :param longitude: (Optional) longitude of station or location where
            wind data is obtained from NWS

        """
        if (timeseries is None and filename is None):
            timeseries = np.zeros((1,), dtype=basic_types.datetime_value_2d)
            units = 'mps'

        self._filename = None

        if not filename:
            time_value_pair = self._convert_to_time_value_pair(timeseries,
                units, format)

            # this has same scope as CyWindMover object
            #
            # TODO: move this as a class attribute if we can.
            #       I can see that we are instantiating the class,
            #       but maybe we can find a way to not have to
            #       pickle this attribute when we pickle a Wind instance
            #
            self.ossm = CyOSSMTime(timeseries=time_value_pair)
            self._user_units = units
            self.source_type = (kwargs.pop('source_type')
                                if kwargs.get('source_type')
                                in basic_types.wind_datasource._attr
                                else 'undefined')
            self.name = kwargs.pop('name', self.__class__.__name__)
        else:
            ts_format = tsformat(format)
            self._filename = filename
            self.ossm = CyOSSMTime(filename=self._filename,
                                   file_contains=ts_format)
            self._user_units = self.ossm.user_units

            self.source_type = 'file'  # this must be file
            self.name = kwargs.pop('name', os.path.split(self.filename)[1])

        self.updated_at = kwargs.pop('updated_at', None)
        self.source_id = kwargs.pop('source_id', 'undefined')
        self.longitude = longitude
        self.latitude = latitude
        self.description = kwargs.pop('description', 'Wind Object')
        super(Wind, self).__init__(**kwargs)
Esempio n. 6
0
    def __init__(self, **kwargs):
        """
        Initializes a wind object. It only takes keyword arguments as input,
        these are defined below.

        Invokes super(Wind,self).__init__(\*\*kwargs) for parent class
        initialization

        It requires one of the following to initialize:
              1. 'timeseries' along with 'units' or
              2. a 'filename' containing a header that defines units amongst
                 other meta data

        All other keywords are optional.
        Optional parameters (kwargs):

        :param timeseries: (Required) numpy array containing time_value_pair
        :type timeseries: numpy.ndarray[basic_types.time_value_pair, ndim=1]

        :param filename: path to a long wind file from which to read wind data
        :param units: units associated with the timeseries data. If 'filename'
                      is given, then units are read in from the file.
                      get_timeseries() will use these as default units to
                      output data, unless user specifies otherwise.
                      These units must be valid as defined in the hazpy
                      unit_conversion module:
                      unit_conversion.GetUnitNames('Velocity')
        :type units:  string, for example: 'knot', 'meter per second',
                      'mile per hour' etc.
                      Default units for input/output timeseries data

        :param format: (Optional) default timeseries format is
                       magnitude direction: 'r-theta'
        :type format: string 'r-theta' or 'uv'. Converts string to integer
                      defined by gnome.basic_types.ts_format.*
                      TODO: 'format' is a python builtin keyword
        :param name: (Optional) human readable string for wind object name.
                     Default is filename if data is from file or "Wind Object"
        :param source_type: (Optional) Default is undefined, but can be one of
                            the following:
                              ['buoy', 'manual', 'undefined', 'file', 'nws']
                            If data is read from file, then it is 'file'
        :param latitude: (Optional) latitude of station or location where
                         wind data is obtained from NWS
        :param longitude: (Optional) longitude of station or location where
                         wind data is obtained from NWS

        Remaining kwargs ('id' if present) are passed onto Environment's
                          __init__ using super.
        See base class documentation for remaining valid kwargs.
        """

        if 'timeseries' in kwargs and 'filename' in kwargs:
            raise TypeError('Cannot instantiate Wind object with both timeseries and file as input'
                            )

        if 'timeseries' not in kwargs and 'filename' not in kwargs:
            raise TypeError('Either provide a timeseries or a wind file with a header, containing wind data'
                            )

        # default lat/long - can these be set from reading data in the file?

        self.longitude = None
        self.latitude = None

        # format of data 'uv' or 'r-theta'. Default is 'r-theta'
        # TODO: 'format' is a python builtin keyword

        format = kwargs.pop('format', 'r-theta')
        self.description = kwargs.pop('description', 'Wind Object')
        if 'timeseries' in kwargs:
            if 'units' not in kwargs:
                raise TypeError("Provide 'units' argument with the 'timeseries' input"
                                )
            timeseries = kwargs.pop('timeseries')
            units = kwargs.pop('units')

            self._check_units(units)
            self._check_timeseries(timeseries, units)

            timeseries['value'] = self._convert_units(timeseries['value'
                    ], format, units, 'meter per second')

            # ts_format is checked during conversion

            time_value_pair = convert.to_time_value_pair(timeseries,
                    format)

            # this has same scope as CyWindMover object

            self.ossm = CyOSSMTime(timeseries=time_value_pair)

            # do not set ossm.user_units since that only has a subset of
            # possible units

            self._user_units = units

            self.name = kwargs.pop('name', 'Wind Object')
            self.source_type = (kwargs.pop('source_type'
                                ) if kwargs.get('source_type')
                                in basic_types.wind_datasource._attr else 'undefined'
                                )
        else:
            ts_format = convert.tsformat(format)
            self.ossm = CyOSSMTime(filename=kwargs.pop('filename'),
                                   file_contains=ts_format)
            self._user_units = self.ossm.user_units

            self.name = kwargs.pop('name',
                                   os.path.split(self.ossm.filename)[1])
            self.source_type = 'file'  # this must be file

        # For default: if read from file and filename exists,
        #                  then use last modified time of file
        #              else
        #                  default to datetime.datetime.now
        # not sure if this should be datetime or string

        self.updated_at = kwargs.pop('updated_at',
                (time_utils.sec_to_date(os.path.getmtime(self.ossm.filename)) if self.ossm.filename else datetime.datetime.now()))
        self.source_id = kwargs.pop('source_id', 'undefined')
        self.longitude = kwargs.pop('longitude', self.longitude)
        self.latitude = kwargs.pop('latitude', self.latitude)
        super(Wind, self).__init__(**kwargs)
Esempio n. 7
0
    def __init__(
        self,
        filename=None,
        timeseries=None,
        yeardata=os.path.join(os.path.dirname(gnome.__file__), 'data',
                              'yeardata'),
        **kwargs
        ):
        """
        Tide information can be obtained from a filename or set as a
        timeseries (timeseries is NOT TESTED YET)

        Invokes super(Tides,self).__init__(\*\*kwargs) for parent class
        initialization

        It requires one of the following to initialize:
              1. 'timeseries' assumed to be in 'uv' format
                 (NOT TESTED/IMPLEMENTED OR USED YET)
              2. a 'filename' containing a header that defines units amongst
                 other meta data

        :param timeseries: numpy array containing datetime_value_2d,
                           ts_format is always 'uv'
        :type timeseries: numpy.ndarray[basic_types.time_value_pair, ndim=1]
        :param units: units associated with the timeseries data. If 'filename'
                      is given, then units are read in from the filename.
                      unit_conversion - NOT IMPLEMENTED YET
        :type units:  (Optional) string, for example:
                        'knot', 'meter per second', 'mile per hour' etc
                      Default is None for now

        :param filename: path to a long wind filename from which to read
                         wind data

        :param yeardata: (Optional) path to yeardata used for Shio data
                         filenames. Default location is gnome/data/yeardata/

        Remaining kwargs ('id' if present) are passed onto Environment's
        __init__ using super.
        See base class documentation for remaining valid kwargs.
        """

        # define locally so it is available even for OSSM files,
        # though not used by OSSM files

        self._yeardata = None

        if timeseries is None and filename is None:
            raise ValueError('Either provide timeseries or a valid filename containing Tide data'
                             )

        if timeseries is not None:

#            if units is None:
#                raise ValueError("Provide valid units as string or unicode " \
#                                 "for timeseries")

            # will probably need to move this function out
            # self._check_timeseries(timeseries, units)

            # data_format is checked during conversion

            time_value_pair = convert.to_time_value_pair(timeseries,
                    convert.tsformat('uv'))

            # this has same scope as CyWindMover object

            self.cy_obj = CyOSSMTime(timeseries=time_value_pair)

            # not sure what these should be

            self._user_units = kwargs.pop('units', None)
        else:

            # self.filename = os.path.abspath( filename)

            self.cy_obj = self._obj_to_create(filename)

            # self.yeardata = os.path.abspath( yeardata ) # set yeardata

            self.yeardata = yeardata  # set yeardata

        super(Tide, self).__init__(**kwargs)
Esempio n. 8
0
def test_ts_format(format_):
    if format_ == 'uv':
        assert tsformat(format_) == ts_format.uv
    else:
        assert tsformat(format_) == ts_format.r_theta
Esempio n. 9
0
def test_ts_format(format_):
    if format_ == 'uv':
        assert tsformat(format_) == ts_format.uv
    else:
        assert tsformat(format_) == ts_format.r_theta