Beispiel #1
0
    def test_floating_point_types_are_indempotent(self):
        """
        Applying the constructor multiple times should not change the values.
        """
        f = FloatWithUncertainties(1.0,
                                   lower_uncertainty=0.5,
                                   upper_uncertainty=1.5)
        assert f == 1.0
        assert f.lower_uncertainty == 0.5
        assert f.upper_uncertainty == 1.5
        f = FloatWithUncertainties(f)
        assert f == 1.0
        assert f.lower_uncertainty == 0.5
        assert f.upper_uncertainty == 1.5

        f = FloatWithUncertaintiesAndUnit(1.0,
                                          lower_uncertainty=0.5,
                                          upper_uncertainty=1.5,
                                          unit="AB")
        assert f == 1.0
        assert f.lower_uncertainty == 0.5
        assert f.upper_uncertainty == 1.5
        assert f.unit == "AB"
        f = FloatWithUncertaintiesAndUnit(f)
        assert f == 1.0
        assert f.lower_uncertainty == 0.5
        assert f.upper_uncertainty == 1.5
        assert f.unit == "AB"
Beispiel #2
0
    def test_floating_point_types_are_indempotent(self):
        """
        Applying the constructor multiple times should not change the values.
        """
        f = FloatWithUncertainties(1.0,
                                   lower_uncertainty=0.5,
                                   upper_uncertainty=1.5)
        self.assertEqual(f, 1.0)
        self.assertEqual(f.lower_uncertainty, 0.5)
        self.assertEqual(f.upper_uncertainty, 1.5)
        f = FloatWithUncertainties(f)
        self.assertEqual(f, 1.0)
        self.assertEqual(f.lower_uncertainty, 0.5)
        self.assertEqual(f.upper_uncertainty, 1.5)

        f = FloatWithUncertaintiesAndUnit(1.0,
                                          lower_uncertainty=0.5,
                                          upper_uncertainty=1.5,
                                          unit="AB")
        self.assertEqual(f, 1.0)
        self.assertEqual(f.lower_uncertainty, 0.5)
        self.assertEqual(f.upper_uncertainty, 1.5)
        self.assertEqual(f.unit, "AB")
        f = FloatWithUncertaintiesAndUnit(f)
        self.assertEqual(f, 1.0)
        self.assertEqual(f.lower_uncertainty, 0.5)
        self.assertEqual(f.upper_uncertainty, 1.5)
        self.assertEqual(f.unit, "AB")
Beispiel #3
0
def extract_unique_sensors_responses(inv):
    resultSensors = defaultdict(list)
    resultResponses = defaultdict(list)
    for net in inv.networks:
        for sta in net.stations:
            for cha in sta.channels:
                assert cha.code != 0
                try:
                    if (cha.code not in resultResponses.keys()):
                        if (cha.response and cha.response.get_paz()):

                            good = True
                            for rs in cha.response.response_stages:
                                if rs.decimation_delay is None:
                                    rs.decimation_delay = FloatWithUncertaintiesAndUnit(
                                        0)
                                if rs.decimation_correction is None:
                                    rs.decimation_correction = FloatWithUncertaintiesAndUnit(
                                        0)

                            if (
                                    good
                            ):  # CONFUSED: why don't we index dict by network and station code as well, since cha.code is not unique
                                resultSensors[cha.code] = cha.sensor
                                resultResponses[cha.code] = cha.response
                except:
                    pass
    return resultSensors, resultResponses
Beispiel #4
0
def obtain_nominal_instrument_response(netcode, statcode, chcode, req):
    """
    For given network, station and channel code, find suitable response(s) in IRIS database and
    return as dict of obspy instrument responses.

    :param netcode: Network code (may include wildcards)
    :type netcode: str
    :param statcode: Station code (may include wildcards)
    :type statcode: str
    :param chcode: Channel code (may include wildcards)
    :type chcode: str
    :param req: Request object to use for URI query
    :type req: Object conforming to interface of 'requests' library
    :return: Dictionary of instrument responses from IRIS for given network(s), station(s) and channel(s).
    :rtype: dict of {str, Instrument(obspy.core.inventory.util.Equipment, obspy.core.inventory.response.Response)}
    """
    from obspy.core.util.obspy_types import FloatWithUncertaintiesAndUnit

    query_url = form_response_request_url(netcode, statcode, chcode)
    tries = 10
    while tries > 0:
        try:
            tries -= 1
            response_xml = req.get(query_url)
            first_line = sio.StringIO(response_xml.text).readline().rstrip()
            assert 'Error 404' not in first_line
            break
        except req.exceptions.RequestException as e:  # pylint: disable=unused-variable
            time.sleep(1)
    assert tries > 0
    set_text_encoding(response_xml, quiet=True)
    # This line decodes when .text attribute is extracted, then encodes to utf-8
    obspy_input = bio.BytesIO(response_xml.text.encode('utf-8'))
    try:
        channel_data = read_inventory(obspy_input)
        responses = {
            cha.code: Instrument(cha.sensor, cha.response)
            for net in channel_data.networks for sta in net.stations
            for cha in sta.channels
            if cha.code is not None and cha.response is not None
        }
        # Make responses valid for Seiscomp3
        for inst in responses.values():
            assert inst.response
            for rs in inst.response.response_stages:
                if rs.decimation_delay is None:
                    rs.decimation_delay = FloatWithUncertaintiesAndUnit(0)
                if rs.decimation_correction is None:
                    rs.decimation_correction = FloatWithUncertaintiesAndUnit(0)
    except ValueError:
        responses = {}
    return responses
Beispiel #5
0
 def water_level(self, value):
     if value is None:
         self._water_level = None
     elif isinstance(value, FloatWithUncertaintiesAndUnit):
         self._water_level = value
     else:
         self._water_level = FloatWithUncertaintiesAndUnit(value)
Beispiel #6
0
def genArrWithUncertainty(vals, errs):
    outArr = [
        FloatWithUncertaintiesAndUnit(val,
                                      lower_uncertainty=err,
                                      upper_uncertainty=err)
        for val, err in zip(vals, errs)
    ]
    return outArr
Beispiel #7
0
def getStation(stationBlock, units, transFuncs):
    ## Should probably do a check up here to see that the order given in block is consistent ##
    for entry in stationBlock:
        if entry.name == 'Station Identifier':
            #            print 'NewStation!',entry.station_call_letters
            staDict = {
                'code': entry.station_call_letters,
                'latitude': entry.latitude,
                'longitude': entry.longitude,
                'elevation': entry.elevation,
                'channels': [],
                'site': Site(entry.site_name),
                'creation_date':
                UTCDateTime(entry.start_effective_date),  # Allows for save
                'start_date': UTCDateTime(entry.start_effective_date),
                'end_date': UTCDateTime(entry.end_effective_date)
            }
            staNetCode = entry.network_code
        # If found a new channel, reset the stages
        elif entry.name == 'Channel Identifier':
            #            print 'NewChannel!',entry.channel_identifier
            stages = []
            chaDict = {
                'code': entry.channel_identifier,
                'location_code': entry.location_identifier,
                'latitude': entry.latitude,
                'longitude': entry.longitude,
                'elevation': entry.elevation,
                'depth': entry.local_depth,
                'sample_rate': entry.sample_rate,
                'start_date': UTCDateTime(entry.start_date),
                'end_date': UTCDateTime(entry.end_date),
                'azimuth': entry.azimuth,
                'dip': entry.dip
            }
        #code, location_code, latitude, longitude, elevation, depth
        # If on a new stage, set up the dictionary again
        # ...paz stage
        elif entry.name == 'Response Poles and Zeros':
            # Get units
            stageReqs = {}
            #            print entry.name,entry.stage_sequence_number
            #            print entry
            #            quit()
            stageReqs['input_units'] = units[entry.stage_signal_input_units]
            stageReqs['output_units'] = units[entry.stage_signal_output_units]
            # Collect the poles and zeros
            lastType = 'paz'
            if entry.number_of_complex_zeros == 0:
                zeros = np.array([], dtype=float)
            else:
                zeros = np.array(entry.real_zero, dtype=float) + np.array(
                    entry.imaginary_zero, dtype=float) * 1j
            if entry.number_of_complex_poles == 0:
                poles = np.array([], dtype=float)
            else:
                poles = np.array(entry.real_pole, dtype=float) + np.array(
                    entry.imaginary_pole, dtype=float) * 1j
            # Form the paz response dictionary (also ensure arrays are 1D)
            pazDict = {
                'pz_transfer_function_type':
                transFuncs[entry.transfer_function_types],
                'normalization_factor':
                entry.A0_normalization_factor,
                'normalization_frequency':
                entry.normalization_frequency,
                'zeros':
                setArrDim(zeros),
                'poles':
                setArrDim(poles)
            }
        # ...coeff stage
        elif entry.name == 'Response Coefficients':
            # Get units
            stageReqs = {}
            #            print entry.name,entry.stage_sequence_number
            stageReqs['input_units'] = units[entry.signal_input_units]
            stageReqs['output_units'] = units[entry.signal_output_units]
            # Collect the coefficients
            lastType = 'coef'
            if entry.number_of_denominators == 0:
                denom = np.array([], dtype=float)
                denomErr = np.array([], dtype=float)
            else:
                denom = np.array(entry.denominator_coefficient, dtype=float)
                denomErr = np.array(entry.denominator_error, dtype=float)
            if entry.number_of_numerators == 0:
                numer = np.array([], dtype=float)
                numerErr = np.array([], dtype=float)
            else:
                numer = np.array(entry.numerator_coefficient, dtype=float)
                numerErr = np.array(entry.numerator_error, dtype=float)
            # Convert these arrays into lists of numbers which have uncertainty (also ensure arrays are 1D)
            denomArr = genArrWithUncertainty(setArrDim(denom),
                                             setArrDim(denomErr))
            numerArr = genArrWithUncertainty(setArrDim(numer),
                                             setArrDim(numerErr))
            # Form the coeefficient response dictionary
            coefDict = {
                'cf_transfer_function_type': transFuncs[entry.response_type],
                'numerator': numerArr,
                'denominator': denomArr
            }
        # Get the decimation sampling info
        elif entry.name == 'Decimation':
            #            print entry.name,entry.stage_sequence_number
            stageReqs['decimation_input_sample_rate'] = Frequency(
                entry.input_sample_rate)
            stageReqs['decimation_factor'] = entry.decimation_factor
            stageReqs['decimation_offset'] = entry.decimation_offset
            stageReqs['decimation_delay'] = FloatWithUncertaintiesAndUnit(
                entry.estimated_delay)
            stageReqs['decimation_correction'] = FloatWithUncertaintiesAndUnit(
                entry.correction_applied)
        # Get the stage sensitivity
        elif entry.name == 'Channel Sensitivity Gain':
            #            print entry.name,entry.stage_sequence_number
            if entry.stage_sequence_number != 0:
                stageReqs[
                    'stage_sequence_number'] = entry.stage_sequence_number
                stageReqs['stage_gain'] = entry.sensitivity_gain
                stageReqs['stage_gain_frequency'] = entry.frequency
                # See what type of stage this was
                if lastType == 'paz':
                    pazDict.update(stageReqs)
                    stages.append(PolesZerosResponseStage(**pazDict))
                else:
                    coefDict.update(stageReqs)
                    stages.append(CoefficientsTypeResponseStage(**coefDict))
            # If on the last stage, send off the collected stage info
            else:
                if len(stages) > 0:
                    instrSens = InstrumentSensitivity(entry.sensitivity_gain,
                                                      entry.frequency,
                                                      stages[0].input_units,
                                                      stages[-1].output_units)
                    # Finalize the channel dictionary, and append this channel to the station dictionary
                    chaResp = Response(response_stages=stages,
                                       instrument_sensitivity=instrSens)
                    chaDict['response'] = chaResp
                staDict['channels'].append(Channel(**chaDict))
    # Return the stations to the list of stations (also track the network code)
    return Station(**staDict), staNetCode