pythontypesobspy

Need more precision to save to SEG-Y with ObsPy


I am trying to save data in SEG-Y format using Python's ObsPy. I am having trouble with the data types. I need higher precision than float32, because I have a very high sampling rate (10 MSamples/sec), so a time interval of only 0.1 microseconds. Likewise, my high_cut_frequency is 20MHz, which is beyond the capacity of float32 (20000000). When I write the header information, these values are overwritten with default values (1.0 or 0.0). This is with both the SEG-Y header and the generic ObsPy header. Is it possible to save in float64? Or, is there another trick to get the precision I need with SEG-Y? From what I gather, the data encoding only allows float32.

Below is the basic code, with comments on lines that generate error:

    import numpy as np
    from numpy import matrix
    import sys
    import getopt
    import time        
    from obspy import read, Trace, Stream, UTCDateTime
    from obspy.core.trace import Stats
    from obspy.core import AttribDict
    from obspy.segy.segy import SEGYTraceHeader, SEGYBinaryFileHeader
    from obspy.segy.core import readSEGY

    dataStream=Stream()
    averages = np.random.rand(10)
    data = np.require(averages, dtype='float32')

    trace = Trace(data=data)
    stats = Stats()

    trace.stats.starttime = UTCDateTime()

    if not hasattr(trace.stats, 'segy.trace_header'):
        trace.stats.segy = {}

    trace.stats.segy.trace_header =  SEGYTraceHeader()

    trace.stats.segy.trace_header.lag_time_B = 154
    trace.stats.segy.trace_header.scalar_to_be_applied_to_times = -4
    trace.stats.segy.trace_header.sample_interval_in_ms_for_this_trace = 10 #100 microseconds *10-4 = 0.01 us:  shows up as 1.0 when I read the file.
    trace.stats.segy.trace_header.high_cut_frequency = 20000000 #error: number to large with 20MHz
    trace.stats.segy.trace_header.number_of_samples_in_this_trace = len(trace)

    trace.stats.delta = 0.1*10**-6 # this will work for 1 us, but not 0.1 us!!

    dataStream.stats = AttribDict()
    dataStream.stats.binary_file_header = SEGYBinaryFileHeader()
    dataStream.stats.binary_file_header.number_of_data_traces_per_ensemble = 1
    dataStream.stats.binary_file_header.number_of_samples_per_data_trace = len(trace)

    dataStream.write('Test.sgy', format='SEGY', data_encoding=1, byteorder=sys.byteorder)

Solution

  • In the SEG-Y standard, the sample interval must be specified as an integer in microseconds. If you are going below 1 microsecond, you will be outside the scope of the SEG-Y format.

    What are you going to do with the data? There may be better options (DZT format for example).