コード例 #1
0
def geophone_response(resonance_frequency,
                      gain,
                      damping=0.707,
                      output_resistance=np.inf,
                      cable_length=np.inf,
                      cable_capacitance=np.inf,
                      sensitivity=1,
                      stage_sequence_number=1):
    paz = corn_freq_2_paz(resonance_frequency, damp=damping)

    l = cable_length
    R = output_resistance
    C = cable_capacitance

    if ((R * l * C) != np.inf) and ((R * l * C) != 0):
        pole_cable = -1 / (R * l * C)
        paz['poles'].append(pole_cable)

    i_s = InstrumentSensitivity(sensitivity,
                                resonance_frequency,
                                input_units='M/S',
                                output_units='M/S',
                                input_units_description='velocity',
                                output_units_description='velocity')

    pzr = PolesZerosResponseStage(stage_sequence_number, gain,
                                  resonance_frequency, 'M/S', 'M/S',
                                  'LAPLACE (RADIANT/SECOND)',
                                  resonance_frequency, paz['zeros'],
                                  paz['poles'])

    return Response(instrument_sensitivity=i_s, response_stages=[pzr])
コード例 #2
0
def accelerometer_response(resonance_frequency,
                           gain,
                           sensitivity=1,
                           stage_sequence_number=1,
                           damping=0.707):
    i_s = InstrumentSensitivity(sensitivity,
                                resonance_frequency,
                                input_units='M/S/S',
                                output_units='M/S/S',
                                input_units_description='acceleration',
                                output_units_description='acceleration')

    paz = corn_freq_2_paz(resonance_frequency, damp=damping)

    paz['zeros'] = []

    pzr = PolesZerosResponseStage(1, 1, 14, 'M/S/S', 'M/S',
                                  'LAPLACE (RADIANT/SECOND)', 1, [],
                                  paz['poles'])

    return Response(instrument_sensitivity=i_s, response_stages=[pzr])
コード例 #3
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
コード例 #4
0
ファイル: inventory.py プロジェクト: znamy/obspy
def _read_response_stage(stage, rate, stage_number, input_units, output_units):
    """
    Private function to read a response stage

    :param stage: response stage element
    :param rate: stage sample rate
    :param stage_number: response stage number
    :param input_units: input units of stage
    :param output_units output units of stage
    """
    elem_type = stage.tag.split("}")[1]

    stage_sequence_number = stage_number

    # Obtain the stage gain and frequency
    # Default to a gain of 0 and frequency of 0 if missing
    stage_gain = _attr2obj(stage, "gain", float) or 0
    stage_gain_frequency = _attr2obj(stage, "gainFrequency", float) or 0.0

    name = _attr2obj(stage, "name", str)
    resource_id = _attr2obj(stage, "publicID", str)

    # Determine the decimation parameters
    # This is dependent on the type of stage
    # Decimation delay/correction need to be normalized
    if elem_type == "responseFIR":
        decimation_factor = _attr2obj(stage, "decimationFactor", int)
        if rate != 0.0:
            temp = _attr2obj(stage, "delay", float) / rate
            decimation_delay = _read_float_var(temp,
                                               FloatWithUncertaintiesAndUnit,
                                               unit=True)
            temp = _attr2obj(stage, "correction", float) / rate
            decimation_corr = _read_float_var(temp,
                                              FloatWithUncertaintiesAndUnit,
                                              unit=True)
        else:
            decimation_delay = _read_float_var("inf",
                                               FloatWithUncertaintiesAndUnit,
                                               unit=True)
            decimation_corr = _read_float_var("inf",
                                              FloatWithUncertaintiesAndUnit,
                                              unit=True)
        decimation_input_sample_rate = \
            _read_float_var(rate, Frequency)
        decimation_offset = int(0)
    elif elem_type == "datalogger":
        decimation_factor = int(1)
        decimation_delay = _read_float_var(0.00,
                                           FloatWithUncertaintiesAndUnit,
                                           unit=True)
        decimation_corr = _read_float_var(0.00,
                                          FloatWithUncertaintiesAndUnit,
                                          unit=True)
        decimation_input_sample_rate = \
            _read_float_var(rate, Frequency)
        decimation_offset = int(0)
    elif elem_type == "responsePAZ" or elem_type == "responsePolynomial":
        decimation_factor = None
        decimation_delay = None
        decimation_corr = None
        decimation_input_sample_rate = None
        decimation_offset = None
    else:
        raise ValueError("Unknown type of response: " + str(elem_type))

    # set up list of for this stage arguments
    kwargs = {
        "stage_sequence_number": stage_sequence_number,
        "input_units": str(input_units),
        "output_units": str(output_units),
        "input_units_description": None,
        "output_units_description": None,
        "resource_id": None,
        "resource_id2": resource_id,
        "stage_gain": stage_gain,
        "stage_gain_frequency": stage_gain_frequency,
        "name": name,
        "description": None,
        "decimation_input_sample_rate": decimation_input_sample_rate,
        "decimation_factor": decimation_factor,
        "decimation_offset": decimation_offset,
        "decimation_delay": decimation_delay,
        "decimation_correction": decimation_corr
    }

    # Different processing for different types of responses
    # currently supported:
    # PAZ, COEFF, FIR, Polynomial response is not supported;
    # could not find example
    if elem_type == 'responsePAZ':

        # read normalization params
        normalization_freq = _attr2obj(stage, "normalizationFrequency",
                                       Frequency)
        normalization_factor = _attr2obj(stage, "normalizationFactor", float)

        # Parse the type of the transfer function
        # A: Laplace (rad)
        # B: Laplace (Hz)
        # D: digital (z-transform)
        pz_transfer_function_type = _attr2obj(stage, "type", str)
        if pz_transfer_function_type == 'A':
            pz_transfer_function_type = 'LAPLACE (RADIANS/SECOND)'
        elif pz_transfer_function_type == 'B':
            pz_transfer_function_type = 'LAPLACE (HERTZ)'
        elif pz_transfer_function_type == 'D':
            pz_transfer_function_type = 'DIGITAL (Z-TRANSFORM)'
        else:
            msg = ("Unknown transfer function code %s. Defaulting to Laplace"
                   "(rad)") % pz_transfer_function_type
            warnings.warn(msg)
            pz_transfer_function_type = 'LAPLACE (RADIANS/SECOND)'

        # Parse string of poles and zeros
        # paz are stored as a string in arclinkXML
        # e.g. (-0.01234,0.01234) (-0.01234,-0.01234)
        zeros_array = stage.find(_ns("zeros")).text
        poles_array = stage.find(_ns("poles")).text
        if zeros_array is not None:
            zeros_array = zeros_array.split(" ")
        else:
            zeros_array = []
        if poles_array is not None:
            poles_array = poles_array.split(" ")
        else:
            poles_array = []

        # Keep counter for pole/zero number
        cnt = 0
        poles = []
        zeros = []
        for el in poles_array:
            poles.append(_tag2pole_or_zero(el, cnt))
            cnt += 1
        for el in zeros_array:
            zeros.append(_tag2pole_or_zero(el, cnt))
            cnt += 1

        # Return the paz response
        return PolesZerosResponseStage(
            pz_transfer_function_type=pz_transfer_function_type,
            normalization_frequency=normalization_freq,
            normalization_factor=normalization_factor,
            zeros=zeros,
            poles=poles,
            **kwargs)

    elif elem_type == 'datalogger':
        cf_transfer_function_type = "DIGITAL"
        numerator = []
        denominator = []
        return CoefficientsTypeResponseStage(
            cf_transfer_function_type=cf_transfer_function_type,
            numerator=numerator,
            denominator=denominator,
            **kwargs)

    elif elem_type == 'responsePolynomial':
        raise NotImplementedError("responsePolynomial not"
                                  "implemented. Contact the ObsPy developers")
        # Polynomial response (UNTESTED)
        # Currently not implemented in ObsPy (20-11-2015)
        f_low = None
        f_high = None
        max_err = None
        appr_type = _attr2obj(stage, "approximationType", str)
        appr_low = _attr2obj(stage, "approximationLowerBound", float)
        appr_high = _attr2obj(stage, "approximationUpperBound", float)
        coeffs_str = _tag2obj(stage, _ns("coefficients"), str)
        if coeffs_str is not None:
            coeffs = coeffs_str.split(" ")
            coeffs_float = []
            i = 0
            # pass additional mapping of coefficient counter
            # so that a proper stationXML can be formatted
            for c in coeffs:
                temp = _read_float_var(c,
                                       FilterCoefficient,
                                       additional_mapping={str("number"): i})
                coeffs_float.append(temp)
                i += 1

        return PolynomialResponseStage(approximation_type=appr_type,
                                       frequency_lower_bound=f_low,
                                       frequency_upper_bound=f_high,
                                       approximation_lower_bound=appr_low,
                                       approximation_upper_bound=appr_high,
                                       maximum_error=max_err,
                                       coefficients=coeffs,
                                       **kwargs)

    elif elem_type == 'responseFIR':
        # For the responseFIR obtain the symmetry and
        # list of coefficients

        coeffs_str = _tag2obj(stage, _ns("coefficients"), str)
        coeffs_float = []
        if coeffs_str is not None and coeffs_str != 'None':
            coeffs = coeffs_str.split(" ")
            i = 0
            # pass additional mapping of coefficient counter
            # so that a proper stationXML can be formatted
            for c in coeffs:
                temp = _read_float_var(c,
                                       FilterCoefficient,
                                       additional_mapping={str("number"): i})
                coeffs_float.append(temp)
                i += 1

        # Write the FIR symmetry to what ObsPy expects
        # A = NONE, B = ODD, C = EVEN
        symmetry = _attr2obj(stage, "symmetry", str)
        if symmetry == 'A':
            symmetry = 'NONE'
        elif symmetry == 'B':
            symmetry = 'ODD'
        elif symmetry == 'C':
            symmetry = 'EVEN'
        else:
            raise ValueError('Unknown symmetry metric; expected A, B, or C')

        return FIRResponseStage(coefficients=coeffs_float,
                                symmetry=symmetry,
                                **kwargs)

    else:
        raise NotImplementedError