Build accelerometer response from values in m/s2

I am trying to build the response for a piezoelectric accelerometer for which I have a csv file with 8192 values given as “total response for the instrument at 2ms, including sensor and high pass filter at 0.5Hz” - I believe these values are in m/s2 - and also the following information: “the frequency and phase response of the sensor is flat between 1-125Hz, sensitivity is 3.6V/g”.

How can I build the instrument response from this information ?

I have tried something like this:

response = Response(
    instrument_sensitivity=instrument_sensitivity,
    response_stages=[stage]
)

with:

instrument_sensitivity = InstrumentSensitivity(
    value=sensitivity,  # unsure about what to input here... 
    frequency=1.0,
    input_units='M/S**2',
    output_units='COUNTS',
    input_units_description='Acceleration in m/s²',
    output_units_description='Digital counts from 24-bit ADC',
    frequency_range_start=1.0,
    frequency_range_end=125.0,
    frequency_range_db_variation=0.0
)

and:

stage = FIRResponseStage(  # unsure if this should be used or CoefficientsTypeResponseStage ?
    stage_sequence_number=1,
    stage_gain=1.0,
    stage_gain_frequency=1.0,  # unsure about this
    input_units='M/S**2',
    output_units='COUNTS',
    symmetry='NONE', # generic FIR, no symmetry
    coefficients=coefficients,  # values straight from the csv file ?
    decimation_input_sample_rate=500.0,
    decimation_factor=1,
    decimation_offset=0,
    decimation_delay=0,
    decimation_correction=0
)

Any help would be greatly appreciated.

I wouldn’t dare derive anything from this piece of information, to be honest. Personally, I would get in touch with the person recording the data or the manufacturer of the instrument.

Thank you for the feedback, this data actually comes from the manufacturer along with the comments, so at this stage, this is what I have to work with…

This is what I ended up doing and the plot from the resulting Response object looks close enough to the official manufacturer’s specifications:

sampling = 0.002
N = len(resp)  # resp is a list of all samples from the csv file
# Amplitude and Phase
comp = np.fft.rfft(resp)
freqs = np.fft.rfftfreq(N, sampling)
amplitude = abs(comp)
phase_deg = np.arctan(comp.imag / comp.real) * 180 / np.pi
# build list of ResponseListElement
rl = [
    ResponseListElement(f, A, p)
        for f, A, p in zip(freqs, amplitude, phase_deg)
]

# one digital stage, blockette 55
stage = ResponseListResponseStage(
    stage_sequence_number=1,
    stage_gain=1.0,
    stage_gain_frequency=1.0,
    input_units='M/S**2',
    output_units='V',
    response_list_elements=rl
)
# sensitivity
sens = InstrumentSensitivity(
    value=0.367,
    frequency=1.0,
    input_units='M/S**2',
    output_units='V',
    frequency_range_start=1.0,
    frequency_range_end=125.0,
    frequency_range_db_variation=0.
)

response = Response(
    instrument_sensitivity=sens,
    response_stages=[stage]
)

does this make any sense ?

Hard to say without seeing what the csv file you mentioned looks like, but it seems more plausible to me now with a f-a-p Response List as opposed to a list of FIR Filter coefficients like indicated in first post. I would be concerned whether the frequencies your response is sampled at are correct though. Seems dangerous to calculate them yourself, if it’s a f-a-p response info in that csv, I’d absolutely expect the frequencies being specified there alongside the complex response values. I would totally contact the manufacturer about it again.

For phase you can simply use np.angle().

Also, in terms of ResponseListResponseStage, you want the stage gain to be the actual value at the normalization frequency and then all the individual elements should be divided by that value (so that they are relative values compared to that stage gain).