示例#1
0
def read_data_header(fn_raw):
    """
    Deprecated!!!
    USE 
              read_ts_header

    INSTEAD


        Read the header line of MTpy TS data files.

    input
    -----
    MTpy TS data file name

    output
    -------
    list of header elements:
    stationname, channel, sampling rate, starttime first sample, 
    starttime last sample, unit, lat, lon, elevation

    """

    fn = op.abspath(op.realpath(fn_raw))

    if not op.isfile(fn):
        raise MTex.MTpyError_inputarguments('Not a file:%s' % fn)
    try:
        F = open(fn, 'r')
    except:
        raise MTex.MTpyError_inputarguments('File not readable:%s' % fn)

    firstline = F.readline().strip().split()
    if not firstline[0][0] == '#':
        raise MTex.MTpyError_ts_data('Time series data file does '
                                     'not have a proper header:%s' % fn)

    F.close()

    header_list = []

    idx_header = 0

    if len(firstline[0]) > 1:
        header_list.append(firstline[0][1:].upper())
    else:
        header_list.append(firstline[1].upper())
        idx_header += 1

    header_list.append(firstline[idx_header + 1].lower())
    header_list.append(float(firstline[idx_header + 2]))
    header_list.append(float(firstline[idx_header + 3]))
    header_list.append(int(float(firstline[idx_header + 4])))
    header_list.append(firstline[idx_header + 5].lower())
    header_list.append(float(firstline[idx_header + 6]))
    header_list.append(float(firstline[idx_header + 7]))
    header_list.append(float(firstline[idx_header + 8]))

    return header_list
示例#2
0
def read_ts_header(tsfile):
    """ Read in the header line from MTpy timeseries data files.
        
        Return header as dictionary. Return empty dict, 
        if no header line was found.
    """

    header_dict = {}

    tsfile = op.abspath(tsfile)
    
    if not op.isfile(tsfile):
        raise MTex.MTpyError_inputarguments('Error - '
            'input file not existing: {0}'.format(tsfile))

    try:
        with open(tsfile,'r') as F:
            firstline =''
            #ignoring empty lines or lines with just the '#' character in it
            while len(firstline) == 0:
                firstline = F.readline().strip()
                if firstline == '#':
                    firstline = ''
        if firstline[0] != '#':
            raise
    except:
        raise MTex.MTpyError_ts_data('No header line found -'
            ' check file: {0}'.format(tsfile))
        

    firstline = firstline.replace('#','')
    headerlist = firstline.split()


    for i in range(len(headerlist)):
        header_dict[lo_headerelements[i]] = headerlist[i]
        #old header had tmax instead of n_samples:
        if ((i == 4) and float(headerlist[4])%1 != 0 
            and float(headerlist[i]) > float(headerlist[i-1])):
            header_dict[lo_headerelements[i]] = int(
                    (float(headerlist[i]) - float(headerlist[i-1])
                    )*float(headerlist[i-2]) )+1

    headerlements = ['samplingrate','t_min','nsamples','lat','lon','elev']

    for h in headerlements:                   
        try: 
            header_dict[h] = float(header_dict[h])
        except:
            pass
        try:
            if header_dict[h]%1==0:
                header_dict[h] = int(header_dict[h])
        except:
            pass

    return header_dict
示例#3
0
def _data_instrument_consistency_check(data, field, dipole_length, instrument, 
                                        amplification, logger, gain):
    """
    Check, if the input values given  for the calibration make any sense at all.

    """

    if len(data) == 0 :
        raise MTex.MTpyError_ts_data( 'no data provided for calibration' )

    if not field.lower() in ['e','b']:
        raise MTex.MTpyError_inputarguments( 'Field must be E or B' )

#    if float(dipole_length) <= 0:
#        raise MTpyError_inputarguments( 'Dipole length must be positive' )

    if float(amplification) <= 0:
        raise MTex.MTpyError_inputarguments('Amplification factor must be positive')

    if float(gain) <= 0:
        raise MTex.MTpyError_inputarguments('Instrument gain must be positive')

    try:
        if not logger.lower() in list_of_loggers:
            raise
    except:
        raise MTex.MTpyError_inputarguments( 'wrong choice of logger')

    try:
        if not instrument.lower() in list_of_instruments:
            raise
    except:
        raise MTex.MTpyError_inputarguments( 'wrong choice of instrument')

    if field.lower == 'b':
        if logger.lower() == 'elogger':
            raise MTex.MTpyError_inputarguments( 'wrong choice of logger')
        if instrument.lower() == 'electrodes':
            raise MTex.MTpyError_inputarguments( 'wrong choice of instrument')
        if not float(dipole_length) == 1:
            raise MTex.MTpyError_inputarguments( 'Dipole length must be "1" for'
                                                ' B-field calibration')
           

    if field.lower == 'e':
        if not instrument.lower() == 'electrodes':
            raise MTex.MTpyError_inputarguments( 'wrong choice of instrument')
示例#4
0
def correct_for_instrument_response(data, samplingrate, responsedata):
    """Correct input time series for instrument response.
        Instr.Resp. is given as 3 column array: frequency, real part, imaginary part

        The given section is demeaned, window tapered, zero padded, (potentially bandpassed with the extreme frequencies of the response frequency axis), FFT-ed, "deconvolved" (straight division by the array values or interpolated values inbetween - in frequency domain), re-transformed, mean-re-added and returned.

    """

    datamean = np.mean(data)
    data -= datamean

    freqmin = responsedata[0, 0]
    freqmax = responsedata[-1, 0]
    #print freqmin,freqmax

    N = len(data)
    if N < 1:
        raise MTex.MTpyError_ts_data(
            'Error - Length of TS to correct is zero!')

    #use double sided cosine taper function
    window = MTfi.tukey(N, 0.2)

    tapered_data = data * window

    #check, if length is directly equal to power of 2:
    if np.log2(N) % 1 == 0:
        next2power = int(np.log2(N))
    else:
        next2power = int(np.log2(N)) + 1

    #zero pad data for significantly faster fft - NO, Numpy does not do that automatically
    padded_data = np.zeros((2**next2power))
    padded_data[:len(tapered_data)] = tapered_data

    #bandpass data for excluding all frequencies that are not covered by the known instrument response
    bp_data = padded_data  #butter_bandpass_filter(padded_data, freqmin, freqmax, samplingrate)

    #get the spectrum of the data
    data_spectrum = np.fft.rfft(bp_data)
    data_freqs = np.fft.fftfreq(len(bp_data), 1. / samplingrate)

    #and the same for the instrument
    instr_spectrum = responsedata[:, 1] + np.complex(0, 1) * responsedata[:, 2]
    instr_freqs = responsedata[:, 0]

    lo_mags = []
    lo_freqs = []

    #return data_freqs,data_spectrum,instr_freqs,instr_spectrum

    #now correct for all frequencies on the data_freqs-axis:
    corrected_spectrum = np.zeros((len(data_spectrum)), 'complex')
    for i in range(len(data_spectrum)):
        freq = data_freqs[i]
        spec = data_spectrum[i]

        #this is effectively a boxcar window - maybe to be replaced by proper windowing function ?
        if not (freqmin <= np.abs(freq) <= freqmax):
            print 'no instrument response in this frequency range - spectrum set to zero here: ', freq
            corrected_spectrum[i] = 0  #spec
            #lo_mags.append([np.abs(spec),np.abs(corrected_spectrum[i]), 0 ])
            #lo_freqs.append([freq,0,0,0,0,0,0])
            continue

        #find the appropriate frequencies ( since the current freq-value is most likely inbetween two values on the instr_freqs-axis)
        #get the respective value by linear interpolation

        #find the value closest to the current freq, assume it's lower
        closest_lower = np.abs(freq - instr_freqs).argmin()

        #if it coincides with the highest frequency/last entry:
        if closest_lower == len(instr_freqs) - 1:
            factor = data_spectrum[closest_lower]
        # or the lowest
        elif closest_lower == 0:
            factor = data_spectrum[0]
        else:
            #in case the closest frequency value is not lower but higher, take the freq value below as lower bound for the interval:
            if instr_freqs[closest_lower] > freq:
                closest_lower -= 1

            #define the interval:
            instrfreq1 = instr_freqs[closest_lower]
            instrfreq2 = instr_freqs[closest_lower + 1]
            instrfactor1 = instr_spectrum[closest_lower]
            instrfactor2 = instr_spectrum[closest_lower + 1]
            intervallength = instrfreq2 - instrfreq1
            weight = (freq - instrfreq1) / intervallength

            factor = weight * instrfactor2 + (1 - weight) * instrfactor1
            #lo_freqs.append([freq,instrfreq1,instrfreq2,weight,instrfactor1,instrfactor2,factor])

        #finally correct the data for the instrument influence by dividing the complex data spectral value by the instrument response value:
        corrected_spectrum[i] = spec / factor
        #lo_mags.append([np.abs(spec),np.abs(corrected_spectrum[i]), factor ])
    #invert into time domain
    correctedTS = np.fft.irfft(corrected_spectrum)

    #cut the zero padding
    correctedTS = correctedTS[:N]

    #re-attach the mean
    correctedTS += datamean

    return correctedTS  #, lo_mags,lo_freqs