예제 #1
0
 def test_readBytesIO(self):
     """
     Tests reading from BytesIO instances.
     """
     # 1
     file = os.path.join(self.path, 'example.y_first_trace')
     with open(file, 'rb') as f:
         data = f.read()
     st = readSEGY(io.BytesIO(data))
     self.assertEqual(len(st.traces[0].data), 500)
     # 2
     file = os.path.join(self.path, 'ld0042_file_00018.sgy_first_trace')
     with open(file, 'rb') as f:
         data = f.read()
     st = readSEGY(io.BytesIO(data))
     self.assertEqual(len(st.traces[0].data), 2050)
     # 3
     file = os.path.join(self.path, '1.sgy_first_trace')
     with open(file, 'rb') as f:
         data = f.read()
     st = readSEGY(io.BytesIO(data))
     self.assertEqual(len(st.traces[0].data), 8000)
     # 4
     file = os.path.join(self.path, '00001034.sgy_first_trace')
     with open(file, 'rb') as f:
         data = f.read()
     st = readSEGY(io.BytesIO(data))
     self.assertEqual(len(st.traces[0].data), 2001)
     # 5
     file = os.path.join(self.path, 'planes.segy_first_trace')
     with open(file, 'rb') as f:
         data = f.read()
     st = readSEGY(io.BytesIO(data))
     self.assertEqual(len(st.traces[0].data), 512)
예제 #2
0
def main():
    from obspy.segy.segy import readSEGY
    filename = '/Users/Uqer/Dropbox/SEGY/dr01.sgy'
    st = readSEGY(filename)
    tr = st.traces[0].data
    picker = merpicker(tr, 512, 0.25, 20, 600, "True")
    print(picker)
예제 #3
0
 def readData(self):
     temp = readSEGY(self.fileName,headonly=True)
     #print dir(temp)
     #print dir(temp.traces[0])
     #print temp.binary_file_header
     
     self.ntraces = len(temp.traces)
     self.ntimes = len(temp.traces[0].data)
     
     # temporary for testing only
     self.ntraces = 1000
     # Put the traces in a numpy array 
     self.data = np.empty([self.ntimes,self.ntraces])
     for i in range(0,self.ntraces):
         self.data[:,i] = temp.traces[i].data
     
     del temp # just making sure
예제 #4
0
    def readData(self):
        temp = readSEGY(self.fileName, headonly=True)
        #print dir(temp)
        #print dir(temp.traces[0])
        #print temp.binary_file_header

        self.ntraces = len(temp.traces)
        self.ntimes = len(temp.traces[0].data)

        # temporary for testing only
        self.ntraces = 1000
        # Put the traces in a numpy array
        self.data = np.empty([self.ntimes, self.ntraces])
        for i in range(0, self.ntraces):
            self.data[:, i] = temp.traces[i].data

        del temp  # just making sure
예제 #5
0
 def test_unpackBinaryFileHeader(self):
     """
     Compares some values of the binary header with values read with
     SeisView 2 by the DMNG.
     """
     file = os.path.join(self.path, '1.sgy_first_trace')
     segy = readSEGY(file)
     header = segy.binary_file_header
     # Compare the values.
     self.assertEqual(header.job_identification_number, 0)
     self.assertEqual(header.line_number, 0)
     self.assertEqual(header.reel_number, 0)
     self.assertEqual(header.number_of_data_traces_per_ensemble, 24)
     self.assertEqual(header.number_of_auxiliary_traces_per_ensemble, 0)
     self.assertEqual(header.sample_interval_in_microseconds, 250)
     self.assertEqual(
         header.sample_interval_in_microseconds_of_original_field_recording,
         250)
     self.assertEqual(header.number_of_samples_per_data_trace, 8000)
     self.assertEqual(
         header.
         number_of_samples_per_data_trace_for_original_field_recording,
         8000)
     self.assertEqual(header.data_sample_format_code, 2)
     self.assertEqual(header.ensemble_fold, 0)
     self.assertEqual(header.trace_sorting_code, 1)
     self.assertEqual(header.vertical_sum_code, 0)
     self.assertEqual(header.sweep_frequency_at_start, 0)
     self.assertEqual(header.sweep_frequency_at_end, 0)
     self.assertEqual(header.sweep_length, 0)
     self.assertEqual(header.sweep_type_code, 0)
     self.assertEqual(header.trace_number_of_sweep_channel, 0)
     self.assertEqual(header.sweep_trace_taper_length_in_ms_at_start, 0)
     self.assertEqual(header.sweep_trace_taper_length_in_ms_at_end, 0)
     self.assertEqual(header.taper_type, 0)
     self.assertEqual(header.correlated_data_traces, 0)
     self.assertEqual(header.binary_gain_recovered, 0)
     self.assertEqual(header.amplitude_recovery_method, 0)
     self.assertEqual(header.measurement_system, 0)
     self.assertEqual(header.impulse_signal_polarity, 0)
     self.assertEqual(header.vibratory_polarity_code, 0)
     self.assertEqual(
         header.number_of_3200_byte_ext_file_header_records_following,
         0)
예제 #6
0
 def test_readAndWriteSEGY(self, headonly=False):
     """
     Reading and writing again should not change a file.
     """
     for file, attribs in self.files.items():
         file = os.path.join(self.path, file)
         non_normalized_samples = attribs['non_normalized_samples']
         # Read the file.
         with open(file, 'rb') as f:
             org_data = f.read()
         segy_file = readSEGY(file, headonly=headonly)
         with NamedTemporaryFile() as tf:
             out_file = tf.name
             segy_file.write(out_file)
             # Read the new file again.
             with open(out_file, 'rb') as f:
                 new_data = f.read()
         # The two files should have the same length.
         self.assertEqual(len(org_data), len(new_data))
         # Replace the not normalized samples. The not normalized
         # samples are already tested in test_packSEGYData and therefore not
         # tested again here.
         if len(non_normalized_samples) != 0:
             # Convert to 4 byte integers. Any 4 byte numbers work.
             org_data = np.fromstring(org_data, np.int32)
             new_data = np.fromstring(new_data, np.int32)
             # Skip the header (4*960 bytes) and replace the non normalized
             # data samples.
             org_data[960:][non_normalized_samples] = \
                 new_data[960:][non_normalized_samples]
             # Create strings again.
             org_data = org_data.tostring()
             new_data = new_data.tostring()
         # Always write the SEGY File revision number!
         # org_data[3500:3502] = new_data[3500:3502]
         # Test the identity without the SEGY revision number
         self.assertEqual(org_data[:3500], new_data[:3500])
         self.assertEqual(org_data[3502:], new_data[3502:])
예제 #7
0
 def test_unpackTraceHeader(self):
     """
     Compares some values of the first trace header with values read with
     SeisView 2 by the DMNG.
     """
     file = os.path.join(self.path, '1.sgy_first_trace')
     segy = readSEGY(file)
     header = segy.traces[0].header
     # Compare the values.
     self.assertEqual(header.trace_sequence_number_within_line, 0)
     self.assertEqual(header.trace_sequence_number_within_segy_file, 0)
     self.assertEqual(header.original_field_record_number, 1)
     self.assertEqual(header.trace_number_within_the_original_field_record,
                      1)
     self.assertEqual(header.energy_source_point_number, 0)
     self.assertEqual(header.ensemble_number, 0)
     self.assertEqual(header.trace_number_within_the_ensemble, 0)
     self.assertEqual(header.trace_identification_code, 1)
     self.assertEqual(
         header.number_of_vertically_summed_traces_yielding_this_trace,
         5)
     self.assertEqual(
         header.number_of_horizontally_stacked_traces_yielding_this_trace,
         0)
     self.assertEqual(header.data_use, 0)
     self.assertEqual(getattr(
         header, 'distance_from_center_of_the_' +
         'source_point_to_the_center_of_the_receiver_group'), 0)
     self.assertEqual(header.receiver_group_elevation, 0)
     self.assertEqual(header.surface_elevation_at_source, 0)
     self.assertEqual(header.source_depth_below_surface, 0)
     self.assertEqual(header.datum_elevation_at_receiver_group, 0)
     self.assertEqual(header.datum_elevation_at_source, 0)
     self.assertEqual(header.water_depth_at_source, 0)
     self.assertEqual(header.water_depth_at_group, 0)
     self.assertEqual(
         header.scalar_to_be_applied_to_all_elevations_and_depths, -100)
     self.assertEqual(header.scalar_to_be_applied_to_all_coordinates, -100)
     self.assertEqual(header.source_coordinate_x, 0)
     self.assertEqual(header.source_coordinate_y, 0)
     self.assertEqual(header.group_coordinate_x, 300)
     self.assertEqual(header.group_coordinate_y, 0)
     self.assertEqual(header.coordinate_units, 0)
     self.assertEqual(header.weathering_velocity, 0)
     self.assertEqual(header.subweathering_velocity, 0)
     self.assertEqual(header.uphole_time_at_source_in_ms, 0)
     self.assertEqual(header.uphole_time_at_group_in_ms, 0)
     self.assertEqual(header.source_static_correction_in_ms, 0)
     self.assertEqual(header.group_static_correction_in_ms, 0)
     self.assertEqual(header.total_static_applied_in_ms, 0)
     self.assertEqual(header.lag_time_A, 0)
     self.assertEqual(header.lag_time_B, 0)
     self.assertEqual(header.delay_recording_time, -100)
     self.assertEqual(header.mute_time_start_time_in_ms, 0)
     self.assertEqual(header.mute_time_end_time_in_ms, 0)
     self.assertEqual(header.number_of_samples_in_this_trace, 8000)
     self.assertEqual(header.sample_interval_in_ms_for_this_trace, 250)
     self.assertEqual(header.gain_type_of_field_instruments, 0)
     self.assertEqual(header.instrument_gain_constant, 24)
     self.assertEqual(header.instrument_early_or_initial_gain, 0)
     self.assertEqual(header.correlated, 0)
     self.assertEqual(header.sweep_frequency_at_start, 0)
     self.assertEqual(header.sweep_frequency_at_end, 0)
     self.assertEqual(header.sweep_length_in_ms, 0)
     self.assertEqual(header.sweep_type, 0)
     self.assertEqual(header.sweep_trace_taper_length_at_start_in_ms, 0)
     self.assertEqual(header.sweep_trace_taper_length_at_end_in_ms, 0)
     self.assertEqual(header.taper_type, 0)
     self.assertEqual(header.alias_filter_frequency, 1666)
     self.assertEqual(header.alias_filter_slope, 0)
     self.assertEqual(header.notch_filter_frequency, 0)
     self.assertEqual(header.notch_filter_slope, 0)
     self.assertEqual(header.low_cut_frequency, 0)
     self.assertEqual(header.high_cut_frequency, 0)
     self.assertEqual(header.low_cut_slope, 0)
     self.assertEqual(header.high_cut_slope, 0)
     self.assertEqual(header.year_data_recorded, 2005)
     self.assertEqual(header.day_of_year, 353)
     self.assertEqual(header.hour_of_day, 15)
     self.assertEqual(header.minute_of_hour, 7)
     self.assertEqual(header.second_of_minute, 54)
     self.assertEqual(header.time_basis_code, 0)
     self.assertEqual(header.trace_weighting_factor, 0)
     self.assertEqual(
         header.geophone_group_number_of_roll_switch_position_one, 2)
     self.assertEqual(header.geophone_group_number_of_trace_number_one, 2)
     self.assertEqual(header.geophone_group_number_of_last_trace, 0)
     self.assertEqual(header.gap_size, 0)
     self.assertEqual(header.over_travel_associated_with_taper, 0)
     self.assertEqual(
         header.x_coordinate_of_ensemble_position_of_this_trace, 0)
     self.assertEqual(
         header.y_coordinate_of_ensemble_position_of_this_trace, 0)
     self.assertEqual(
         header.for_3d_poststack_data_this_field_is_for_in_line_number, 0)
     self.assertEqual(
         header.for_3d_poststack_data_this_field_is_for_cross_line_number,
         0)
     self.assertEqual(header.shotpoint_number, 0)
     self.assertEqual(
         header.scalar_to_be_applied_to_the_shotpoint_number, 0)
     self.assertEqual(header.trace_value_measurement_unit, 0)
     self.assertEqual(header.transduction_constant_mantissa, 0)
     self.assertEqual(header.transduction_constant_exponent, 0)
     self.assertEqual(header.transduction_units, 0)
     self.assertEqual(header.device_trace_identifier, 0)
     self.assertEqual(header.scalar_to_be_applied_to_times, 0)
     self.assertEqual(header.source_type_orientation, 0)
     self.assertEqual(header.source_energy_direction_mantissa, 0)
     self.assertEqual(header.source_energy_direction_exponent, 0)
     self.assertEqual(header.source_measurement_mantissa, 0)
     self.assertEqual(header.source_measurement_exponent, 0)
     self.assertEqual(header.source_measurement_unit, 0)
예제 #8
0
Uses ObsPy package for SEGY file reading
You can find instructions for installing Obspy at http://obspy.org/

"""
from fatiando.vis import mpl
from obspy.segy import segy
import urllib
import numpy as np

# fetch sample SEGY data, near-offset marmousi data
url = "http://dl.dropboxusercontent.com/" \
      "s/i287ci4ww3w7gdt/marmousi_nearoffset.segy"
urllib.urlretrieve(url, 'marmousi_nearoffset.segy')
# We'll use the ObsPy library to load the SEGY data"
segyfile = segy.readSEGY('marmousi_nearoffset.segy')
# turn ObsPy Stream in a matrix of traces
# first dimension time, second dimension traces
ntraces = len(segyfile.traces)
nsamples = len(segyfile.traces[0].data)
mtraces = np.zeros((nsamples, ntraces))
i = 0
for tr in segyfile.traces:
    mtraces[:, i] = tr.data[:]
    i += 1
# make plots
mpl.figure()
mpl.subplot(2, 1, 1)
mpl.ylabel('time (seconds)')
mpl.title("Seismic wiggle plot", fontsize=13, family='sans-serif',
          weight='bold')
예제 #9
0
def main(target, cfg):
    """
    Puts everything together.
    """
    t0 = time.time()

    # Read the file.
    section = readSEGY(target, unpack_headers=True)

    # Calculate some things.
    # NB Getting nsamples and dt from the first trace assumes that all
    # traces are the same length, which is not a safe assumption in SEGY v2.
    ninlines = section.traces[-1].header.trace_sequence_number_within_line
    last_tr = section.traces[-1].header.trace_sequence_number_within_segy_file
    nxlines = last_tr / ninlines

    nsamples = section.traces[0].header.number_of_samples_in_this_trace
    dt = section.traces[0].header.sample_interval_in_ms_for_this_trace
    ntraces = len(section.traces)
    tbase = 0.001 * np.arange(0, nsamples * dt, dt)
    tstart = 0
    tend = np.amax(tbase)

    # Make the data array.
    data = np.vstack([t.data for t in section.traces]).T

    threed = False
    if nxlines > 1:  # Then it's a 3D and `data` is an ensemble.
        threed = True
        cube = np.reshape(data.T, (ninlines, nxlines, nsamples))
        l = cfg['number']
        if cfg['direction'].lower()[0] == 'i':
            direction = 'inline'
            ntraces = nxlines
            l *= ninlines if (l < 1) else 1
            data = cube[l, :, :].T
        else:
            direction = 'xline'
            ntraces = ninlines
            l *= nxlines if (l < 1) else 1
            data = cube[:, l, :].T

    # Collect some other data. Use a for loop because there are several.
    elev, esp, ens, tsq = [], [], [], []
    for i, trace in enumerate(section.traces):
        elev.append(trace.header.receiver_group_elevation)
        esp.append(trace.header.energy_source_point_number)
        tsq.append(trace.header.trace_sequence_number_within_line)

        if threed:
            trs = []
            if direction == 'inline':
                cdp_label_text = 'Crossline number'
                trace_label_text = 'Trace number'
                ens.append(trace.header.for_3d_poststack_data_this_field_is_for_cross_line_number)
                trs.append(trace.header.for_3d_poststack_data_this_field_is_for_in_line_number)
            else:
                cdp_label_text = 'Inline number'
                trace_label_text = 'Trace number'
                ens.append(trace.header.for_3d_poststack_data_this_field_is_for_in_line_number)
                trs.append(trace.header.for_3d_poststack_data_this_field_is_for_cross_line_number)
            line_no = min(trs)
        else:
            cdp_label_text = 'CDP number'
            trace_label_text = 'Trace number'
            ens.append(trace.header.ensemble_number)
        min_tr, max_tr = 0, ntraces

    traces = (min_tr, max_tr)

    clip_val = np.percentile(data, cfg['percentile'])

    # Notify user of parameters
    Notice.info("n_traces   {}".format(ntraces))
    Notice.info("n_samples  {}".format(nsamples))
    Notice.info("dt         {}".format(dt))
    Notice.info("t_start    {}".format(tstart))
    Notice.info("t_end      {}".format(tend))
    Notice.info("max_val    {}".format(np.amax(data)))
    Notice.info("min_val    {}".format(np.amin(data)))
    Notice.info("clip_val   {}".format(clip_val))

    t1 = time.time()
    Notice.ok("Read data in {:.1f} s".format(t1-t0))

    #####################################################################
    #
    # MAKE PLOT
    #
    #####################################################################
    Notice.hr_header("Plotting")

    ##################################
    # Plot size parameters
    # Some constants
    fs = cfg['fontsize']
    wsl = 6  # Width of sidelabel, inches
    mih = 12  # Minimum plot height, inches
    fhh = 5  # File header box height, inches
    m = 0.5  # basic unit of margins, inches

    # Margins, CSS like: top, right, bottom, left.
    mt, mr, mb, ml = m,  2 * m, m, 2 * m
    mm = m  # padded margin between seismic and label

    # Width is determined by seismic width, plus sidelabel, plus margins.
    seismic_width = ntraces / cfg['tpi']
    w = ml + seismic_width + mm + wsl + mr  # inches

    # Height is given by ips, but with a minimum of mih inches
    seismic_height = cfg['ips'] * (tbase[-1] - tbase[0]) / 1000
    h_reqd = mb + seismic_height + mt  # inches
    h = max(mih, h_reqd)

    # Calculate where to start sidelabel and seismic data.
    # Depends on whether sidelabel is on the left or right.
    if cfg['sidelabel'] == 'right':
        ssl = (ml + seismic_width + mm) / w  # Start of side label (ratio)
        seismic_left = ml / w
    else:
        ssl = ml / w
        seismic_left = (ml + wsl + mm) / w

    adj = max(0, h - h_reqd) / 2
    seismic_bottom = (mb / h) + adj / h
    seismic_width_fraction = seismic_width / w
    seismic_height_fraction = seismic_height / h

    # Publish some notices so user knows plot size.
    Notice.info("Width of plot   {} in".format(w))
    Notice.info("Height of plot  {} in".format(h))

    ##################################
    # Make the figure.
    fig = plt.figure(figsize=(w, h), facecolor='w')

    # Add the main seismic axis.
    ax = fig.add_axes([seismic_left,
                       seismic_bottom,
                       seismic_width_fraction,
                       seismic_height_fraction
                       ])

    # make parasitic axes for labeling CDP number
    par1 = ax.twiny()
    par1.spines["top"].set_position(("axes", 1.0))
    tickfmt = mtick.FormatStrFormatter('%.0f')
    par1.plot(ens, np.zeros_like(ens))
    par1.set_xlabel(cdp_label_text, fontsize=fs-2)
    par1.set_xticklabels(par1.get_xticks(), fontsize=fs-2)
    par1.xaxis.set_major_formatter(tickfmt)

    # Plot title
    title_ax = fig.add_axes([ssl, 1-mt/h, wsl/w, mt/(h)])
    title_ax = plotter.plot_title(title_ax, target, fs=1.5*fs, cfg=cfg)
    if threed:
        title_ax.text(0.0, 0.0, '{} {}'.format(direction.title(), line_no))

    # Plot text header.
    s = section.textual_file_header.decode()
    start = (h - 1.5*mt - fhh) / h
    head_ax = fig.add_axes([ssl, start, wsl/w, fhh/h])
    head_ax = plotter.plot_header(head_ax, s, fs=fs-1, cfg=cfg)

    # Plot histogram.
    # Params for histogram plot
    pady = 0.75 / h  # 0.75 inch
    padx = 0.75 / w   # 0.75 inch
    cstrip = 0.3/h   # color_strip height = 0.3 in
    charth = 1.5/h   # height of charts = 1.5 in
    chartw = wsl/w - mr/w - padx  # or ml/w for left-hand sidelabel; same thing
    chartx = (ssl + padx)
    histy = 1.5 * mb/h + charth + pady
    # Plot colourbar under histogram
    clrbar_ax = fig.add_axes([chartx, histy - cstrip, chartw, cstrip])
    clrbar_ax = plotter.plot_colourbar(clrbar_ax, cmap=cfg['cmap'])
    # Plot histogram itself
    hist_ax = fig.add_axes([chartx, histy, chartw, charth])
    hist_ax = plotter.plot_histogram(hist_ax,
                                     data,
                                     tickfmt,
                                     percentile=cfg['percentile'],
                                     fs=fs)

    # Plot spectrum.
    specy = 1.5 * mb/h
    spec_ax = fig.add_axes([chartx, specy, chartw, charth])

    try:
        spec_ax = plotter.plot_spectrum(spec_ax,
                                        data,
                                        dt,
                                        tickfmt,
                                        ntraces=20,
                                        fontsize=fs)
    except:
        pass

    # Plot seismic data.
    if cfg['display'].lower() in ['vd', 'varden', 'variable']:
        _ = ax.imshow(data,
                      cmap=cfg['cmap'],
                      clim=[-clip_val, clip_val],
                      extent=[0, ntraces, tbase[-1], tbase[0]],
                      aspect='auto'
                      )

    elif cfg['display'].lower() == 'wiggle':
        ax = plotter.wiggle_plot(ax,
                                 data,
                                 tbase,
                                 ntraces,
                                 skip=cfg['skip'],
                                 gain=cfg['gain'],
                                 rgb=cfg['colour'],
                                 alpha=cfg['opacity'],
                                 lw=cfg['lineweight']
                                 )
        ax.set_ylim(ax.get_ylim()[::-1])

    elif cfg['display'].lower() == 'both':
        # variable density goes on first
        _ = ax.imshow(data,
                      cmap=cfg['cmap'],
                      clim=[-clip_val, clip_val],
                      extent=[0, ntraces, tbase[-1], tbase[0]],
                      aspect='auto'
                      )

        # wiggle plots go on top
        ax = plotter.wiggle_plot(ax,
                                 data,
                                 tbase,
                                 ntraces,
                                 skip=cfg['skip'],
                                 gain=cfg['gain'],
                                 rgb=cfg['colour'],
                                 alpha=cfg['opacity'],
                                 lw=cfg['lineweight']
                                 )
        # ax.set_ylim(ax.get_ylim()[::-1])

    else:
        Notice.fail("You need to specify the type of display: wiggle or vd")

    # Seismic axis annotations.
    ax = plotter.decorate_seismic(ax, traces, trace_label_text, tickfmt, cfg)

    # Watermark.
    if cfg['watermark_text']:
        Notice.info("Adding watermark")
        ax = plotter.watermark_seismic(ax, cfg)

    t2 = time.time()
    Notice.ok("Built plot in {:.1f} s".format(t2-t1))

    #####################################################################
    #
    # SAVE FILE
    #
    #####################################################################
    Notice.hr_header("Saving")

    if cfg['stain_paper'] or cfg['coffee_rings'] or cfg['distort'] or cfg['scribble']:
        stupid = True
    else:
        stupid = False

    s = "Saved image file {} in {:.1f} s"
    if cfg['outfile']:

        if os.path.isfile(cfg['outfile']):
            outfile = cfg['outfile']
        else:  # is directory
            stem, ext = os.path.splitext(os.path.split(target)[1])
            outfile = os.path.join(cfg['outfile'], stem + '.png')

        stem, _ = os.path.splitext(outfile)  # Needed for stupidity.
        fig.savefig(outfile)
        t3 = time.time()
        Notice.ok(s.format(outfile, t3-t2))
    else:  # Do the default: save a PNG in the same dir as the target.
        stem, _ = os.path.splitext(target)
        fig.savefig(stem)
        t3 = time.time()
        Notice.ok(s.format(stem+'.png', t3-t2))

    if stupid:
        fig.savefig(stem + ".stupid.png")
    else:
        return

    #####################################################################
    #
    # SAVE STUPID FILE
    #
    #####################################################################
    Notice.hr_header("Applying the stupidity")

    stupid_image = Image.open(stem + ".stupid.png")
    if cfg['stain_paper']:
        utils.stain_paper(stupid_image)
    utils.add_rings(stupid_image, cfg['coffee_rings'])
    if cfg['scribble']:
        utils.add_scribble(stupid_image)
    stupid_image.save(stem + ".stupid.png")

    s = "Saved stupid file stupid.png in {:.1f} s"
    t4 = time.time()
    Notice.ok(s.format(t4-t3))

    return
예제 #10
0
def main(target, cfg):
    """
    Puts everything together.
    """
    t0 = time.time()

    # Read the file.
    section = readSEGY(target, unpack_headers=True)

    # Calculate some things
    nsamples = section.traces[0].header.number_of_samples_in_this_trace
    dt = section.traces[0].header.sample_interval_in_ms_for_this_trace
    ntraces = len(section.traces)
    tbase = 0.001 * np.arange(0, nsamples * dt, dt)
    tstart = 0
    tend = np.amax(tbase)
    wsd = ntraces / cfg['tpi']

    # Build the data container
    elev, esp, ens, tsq = [], [], [], []  # energy source point number
    data = np.zeros((nsamples, ntraces))
    for i, trace in enumerate(section.traces):
        data[:, i] = trace.data
        elev.append(trace.header.receiver_group_elevation)
        esp.append(trace.header.energy_source_point_number)
        ens.append(trace.header.ensemble_number)
        tsq.append(trace.header.trace_sequence_number_within_line)

    clip_val = np.percentile(data, 99.0)

    # Notify user of parameters
    Notice.info("n_traces   {}".format(ntraces))
    Notice.info("n_samples  {}".format(nsamples))
    Notice.info("dt         {}".format(dt))
    Notice.info("t_start    {}".format(tstart))
    Notice.info("t_end      {}".format(tend))
    Notice.info("max_val    {}".format(np.amax(data)))
    Notice.info("min_val    {}".format(np.amin(data)))
    Notice.info("clip_val   {}".format(clip_val))

    t1 = time.time()
    Notice.ok("Read data successfully in {:.1f} s".format(t1-t0))

    #####################################################################
    #
    # MAKE PLOT
    #
    #####################################################################
    Notice.hr_header("Plotting")

    ##################################
    # Plot size parameters
    # Some constants
    wsl = 6  # Width of sidelabel
    mih = 10  # Minimum plot height
    fhh = 5  # File header height
    m = 0.5  # margin in inches

    # Margins, CSS like
    mt, mb, ml, mr = m, m, 2 * m, 2 * m
    mm = mr / 2  # padded margin between seismic and label

    # Width is determined by tpi, plus a constant for the sidelabel, plus 1 in
    w = ml + wsd + wsl + mr + mm

    # Height is given by ips, but with a minimum of 8 inches, plus 1 in
    h = max(mih, cfg['ips'] * (np.amax(tbase) - np.amin(tbase)) / 1000 + mt + mb)

    # More settings
    ssl = (ml + wsd + mm) / w  # Start of side label (ratio)
    fs = cfg['fontsize']

    Notice.info("Width of plot   {} in".format(w))
    Notice.info("Height of plot  {} in".format(h))

    ##################################
    # Make the figure.
    fig = plt.figure(figsize=(w, h), facecolor='w')
    ax = fig.add_axes([ml / w, mb / h, wsd / w, (h - mb - mt) / h])

    # make parasitic axes for labeling CDP number
    par1 = ax.twiny()
    par1.spines["top"].set_position(("axes", 1.0))
    tickfmt = mtick.FormatStrFormatter('%.0f')
    par1.plot(ens, np.zeros_like(ens))
    par1.set_xlabel("CDP number", fontsize=fs-2)
    par1.set_xticklabels(par1.get_xticks(), fontsize=fs-2)
    par1.xaxis.set_major_formatter(tickfmt)

    ax = wiggle_plot(ax,
                     data,
                     tbase,
                     ntraces,
                     skip=cfg['skip'],
                     gain=cfg['gain'],
                     rgb=cfg['colour'],
                     alpha=cfg['opacity'],
                     lw=cfg['lineweight']
                     )

    ax = decorate_seismic(ax, ntraces, tickfmt, fs)

    # Plot title
    title_ax = fig.add_axes([ssl, 1-mt/h, wsl/w, mt/(2*h)])
    title_ax = plot_title(title_ax, target, fs=fs)

    # Plot text header.
    s = str(section.textual_file_header)[2:-1]
    start = (h - mt - fhh) / h
    head_ax = fig.add_axes([ssl, start, wsl/w, fhh/h])
    head_ax = plot_header(head_ax, s, fs)

    # Plot histogram.
    pad = 0.05
    charty = 0.125  # height of chart
    xhist = (ssl + pad)
    whist = (1 - ssl - (ml/w)) - 2 * pad
    hist_ax = fig.add_axes([xhist, 1.5 * mb/h + charty + pad, whist, charty])
    hist_ax = plot_histogram(hist_ax, data, fs)

    # Plot spectrum.
    spec_ax = fig.add_axes([xhist, 1.5 * mb/h, whist, charty])
    spec_ax = plot_spectrum(spec_ax, data, dt, fs)

    t2 = time.time()
    Notice.ok("Built plot in {:.1f} s".format(t2-t1))

    #####################################################################
    #
    # SAVE FILE
    #
    #####################################################################
    Notice.hr_header("Saving")
    s = "Saved image file {} in {:.1f} s"
    if cfg['outfile']:
        fig.savefig(cfg['outfile'])
        t3 = time.time()
        Notice.ok(s.format(cfg['outfile'], t3-t2))
    else:
        stem, _ = os.path.splitext(target)
        fig.savefig(stem)
        t3 = time.time()
        Notice.ok(s.format(stem+'.png', t3-t2))

    return
예제 #11
0
# !/Users/Uqer/anaconda/bin/python

#Test codes
import numpy as np
from numpy import sqrt, square
from psmodules.pspicker import merpicker
from psmodules.pspdf import pdftp
from obspy.segy.segy import readSEGY
from psmodules.psarray import dharray

geonum = 12
gx, gy, gz = dharray(geonum, 0, 0, 3000, 25)

filename = '/Users/Uqer/Dropbox/SEGY/dr01.sgy'
st = readSEGY(filename)
tr = st.traces[0].data
# pick = merpicker(tr, 512, 0.25, 20, 600, "true" )

x1 = 500
x2 = 1000
z1 = 1000
z2 = 3000
vel = 3000

ns = 512
srate = 0.25
win = 20
threshold = 600
N = 12
to = 0