Esempio n. 1
0
    def _extract_sample(self, particle_class, sequence_number, file_time,
                        regex, raw_data, timestamp):
        """
        Override method to pass sequence number and file time to particle. Also need to
        handle a particle without timestamp detected in _build_parsed_values() which
        raises a RecoverableSampleException and returns a particle with no values

        Extract sample from data if present and publish parsed particle

        @param particle_class The class to instantiate for this specific
            data particle. Parameterizing this allows for simple, standard
            behavior from this routine
        @param regex The regular expression that matches a data sample if regex
                     is none then process every line
        @param raw_data data to input into this particle.
        @retval return a raw particle if a sample was found, else None
        """
        particle = None
        particle_dict = {}

        try:
            if regex is None or regex.match(raw_data):
                particle = particle_class(
                    raw_data,
                    sequence_number,
                    file_time,
                    internal_timestamp=timestamp,
                    preferred_timestamp=DataParticleKey.INTERNAL_TIMESTAMP)

                # need to actually parse the particle fields to find out if there are errors
                particle_dict = particle.generate_dict()
                log.trace('Parsed particle: %s\n\n' % particle_dict)
                encoding_errors = particle.get_encoding_errors()
                if encoding_errors:
                    log.warn("Failed to encode: %s", encoding_errors)
                    raise SampleEncodingException("Failed to encode: %s" %
                                                  encoding_errors)

        # Also catch any possible exceptions thrown from unpacking data
        except (RecoverableSampleException, SampleEncodingException,
                struct.error) as e:
            log.error("Sample exception detected: %s raw data: %s", e,
                      raw_data)
            if self._exception_callback:
                self._exception_callback(e)
            else:
                raise e

        # Do not return a particle if there are no values within
        if not particle_dict or not particle_dict.get(DataParticleKey.VALUES):
            return None

        return particle
Esempio n. 2
0
    def _extract_sample(self,
                        particle_class,
                        regex,
                        raw_data,
                        port_timestamp=None,
                        internal_timestamp=None,
                        preferred_ts=DataParticleKey.INTERNAL_TIMESTAMP):
        """
        Extract sample from a response line if present and publish
        parsed particle

        @param particle_class The class to instantiate for this specific
            data particle. Parameterizing this allows for simple, standard
            behavior from this routine
        @param regex The regular expression that matches a data sample if regex
                     is none then process every line
        @param raw_data data to input into this particle.
        @param port_timestamp the port_timestamp (default: None)
        @param internal_timestamp the internal_timestamp (default: None)
        @param preferred_ts the preferred timestamp (default: INTERNAL_TIMESTAMP)
        @retval return a raw particle if a sample was found, else None
        """

        particle = None

        try:
            if regex is None or regex.match(raw_data):
                particle = particle_class(
                    raw_data,
                    port_timestamp=port_timestamp,
                    internal_timestamp=internal_timestamp,
                    preferred_timestamp=preferred_ts)

                # need to actually parse the particle fields to find out of there are errors
                particle.generate_dict()
                encoding_errors = particle.get_encoding_errors()
                if encoding_errors:
                    log.warn("Failed to encode: %s", encoding_errors)
                    raise SampleEncodingException("Failed to encode: %s" %
                                                  encoding_errors)

        except (RecoverableSampleException, SampleEncodingException) as e:
            log.error("Sample exception detected: %s raw data: %s", e,
                      raw_data)
            if self._exception_callback:
                self._exception_callback(e)
            else:
                raise e

        return particle
Esempio n. 3
0
    def _string_to_ddegrees(pos_str):
        """
        Converts the given string from this data stream into a more
        standard latitude/longitude value in decimal degrees.
        @param pos_str The position (latitude or longitude) string in the
           format "DDMM.MMMM" for latitude and "DDDMM.MMMM" for longitude. A
           positive or negative sign to the string indicates northern/southern
           or eastern/western hemispheres, respectively.
        @retval The position in decimal degrees
        """
        # As a stop gap fix add a .0 to integers that don't contain a decimal.  This
        # should only affect the engineering stream as the science data streams shouldn't
        # contain lat lon
        if not "." in pos_str:
            pos_str += ".0"

        # if there are not enough numbers to fill in DDMM, prepend zeros
        str_words = pos_str.split('.')
        adj_zeros = 4 - len(str_words[0])
        if adj_zeros > 0:
            for i in range(0, adj_zeros):
                pos_str = '0' + pos_str

        regex = r'([-+]?\d{2,3})(\d{2}\.\d+)'
        regex_matcher = re.compile(regex)
        latlon_match = regex_matcher.match(pos_str)

        if latlon_match is None:
            msg = "Failed to parse lat/lon value: '%s'" % pos_str
            log.error(msg)
            raise SampleEncodingException(msg)

        degrees = float(latlon_match.group(1))
        minutes = float(latlon_match.group(2))
        ddegrees = copysign((abs(degrees) + minutes / 60.), degrees)

        return ddegrees