def test_read_bytes_io(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 = _read_segy(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 = _read_segy(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 = _read_segy(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 = _read_segy(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 = _read_segy(io.BytesIO(data)) self.assertEqual(len(st.traces[0].data), 512)
def load_SH_and_STH(filename, endian=None): """ Read and load headers from SEGY file. No data is loaded, saving time and memory. Usage ----- SH,STH = load_SH_and_STH(filename) """ # read file with obspy (headers only) seis = _read_segy(filename, endian=endian, headonly=True) traces = seis.traces ntraces = len(traces) # Load SEGY header SH = load_SEGY_header(seis) # additional headers for compatibility with older segy module SH['filename'] = filename SH["ntraces"] = ntraces SH["ns"] = SH['number_of_samples_per_data_trace'] SH["dt"] = SH['sample_interval_in_microseconds'] / 1000 # in milliseconds # Load all the Trace headers in arrays STH = load_SEGY_trace_header(traces) return SH, STH
def load_SEGY(filename, endian=None): """ Read and load data and headers from a SEGY file. Usage ----- data, SH, STH = load_SEGY(filename) """ # read file with obspy seis = _read_segy(filename, endian=endian) traces = seis.traces ntraces = len(traces) # Load SEGY header SH = load_SEGY_header(seis) # additional headers for compatibility with older segy module SH['filename'] = filename SH["ntraces"] = ntraces SH["ns"] = SH['number_of_samples_per_data_trace'] SH["dt"] = SH['sample_interval_in_microseconds'] / 1000 # in milliseconds # Load all the Trace headers in arrays STH = load_SEGY_trace_header(traces) # Load the data data = np.vstack([t.data for t in traces]).T return data, SH, STH
def dataload_segy(self, path_seis, size_vlm, idx0_vlm): ''' This function loads a segy file and quary a subvolume defined by size_vlm and idx0_vlm. ''' t0 = time() print('Start Loading Segy Data') file_segy = _read_segy(path_seis).traces traces = np.stack(t.data for t in file_segy) inlines = np.stack( t.header.for_3d_poststack_data_this_field_is_for_in_line_number for t in file_segy) xlines = np.stack( t.header.for_3d_poststack_data_this_field_is_for_cross_line_number for t in file_segy) idx_inline = inlines - np.min(inlines) idx_xline = xlines - np.min(xlines) num_traces = len(traces) num_inline = len(np.unique(inlines)) num_xline = len(np.unique(xlines)) num_sample = len(file_segy[0].data) seis_vlm = np.zeros([num_inline, num_xline, num_sample]) for i in range(num_traces): seis_vlm[idx_inline[i], idx_xline[i], :] = traces[i] t1 = time() print('\nCompleted Loading Segy Data') print('\nElapsed time: ' + "{:.2f}".format(t1 - t0) + ' sec') seis_vlm = seis_vlm[idx0_vlm[0]:idx0_vlm[0] + size_vlm[0], idx0_vlm[1]:idx0_vlm[1] + size_vlm[1], idx0_vlm[2]:idx0_vlm[2] + size_vlm[2]] self.seis_vlm = seis_vlm
def plot_segy(segy_input, png=False, cmap='bone_r', log10=False): ''' ''' import numpy as np import matplotlib.pyplot as plt from obspy.io.segy.segy import _read_segy stream = _read_segy(segy_input, headonly=True) data = np.stack(t.data for t in list(stream.traces)) fig = plt.subplots(figsize=(20,10)) if log10 == False: plt.imshow(data.T, cmap=cmap, aspect='auto') elif log10 == True: plt.imshow(np.log10(data).T, cmap=cmap, aspect='auto') plt.colorbar() plt.show() if png == True: plt.savefig('test_segy_plot.png', dpi=200, bbox_inches='tight') print('Saved Figure as ==> test_segy_plot.png') else: return fig
def __init__(self, filename, processor=None): from obspy.io.segy.segy import _read_segy self.stream = _read_segy(filename, unpack_headers=True) self.dt = self.stream.binary_file_header.sample_interval_in_microseconds / 1000000 self.nsamp = len(self.stream.traces[0].data) self.dt_synt = 0.004 self.dx_synt = 1 self.processor = processor
def __init__(self, segy_fn, pick_every=1): ''' Class for reading 2D segy files. This class assumes that the traces are CDP-ordered. :param segy_fn: segy file name :param pick_every: by default, every trace is read from the segy file, but pick_every>1 allows skipping traces. ''' self._sfn = segy_fn self._sf = segy._read_segy(self._sfn) self._pick_every = pick_every # Read traces self._mtraces = [] # trace samples self._xs = [] # x coordinates self._ys = [] # y coordinates self._ns = [] # num samples self._cdps = [] # ensemble number (cdps) self._si = [] # sample interval count = 0 for itr, tr in enumerate(self._sf.traces): if (itr % self._pick_every == 0): self._mtraces.append(tr.data) self._xs.append(tr.header.source_coordinate_x) self._ys.append(tr.header.source_coordinate_y) self._ns.append(tr.header.number_of_samples_in_this_trace) self._si.append( tr.header.sample_interval_in_ms_for_this_trace / 1e6) # convert from micro seconds to s self._cdps.append(tr.header.ensemble_number) count += 1 # end for self._ntraces = len(self._sf.traces) self._ns = numpy.array(self._ns) self._si = numpy.array(self._si) self._xs = numpy.array(self._xs) self._ys = numpy.array(self._ys) self._cdps = numpy.array(self._cdps) self._station_space = numpy.sqrt((self._xs[:-1] - self._xs[1:])**2 + (self._ys[:-1] - self._ys[1:])**2) self._dist = numpy.array([ numpy.sum(self._station_space[:i]) for i in range(len(self._station_space)) ]) # compute euclidean distance along profile self._ts = numpy.linspace(0, (numpy.max(self._ns) - 1) * numpy.max(self._si), numpy.max(self._ns)) self._mtraces = numpy.array(self._mtraces) self._mt, self._md = numpy.meshgrid( self._ts, self._dist) # mesh grid of distance and time self._mt, self._mc = numpy.meshgrid( self._ts, self._cdps) # mesh grid of cdp and time self._dist -= numpy.min( self._dist) # distance along profile starts from 0
def read_segy(self, name): """ Read a SEGY file and places returns the data in an array of dimension nt X nb traces :param name: Name of the segyfile :return: A numpy array containing the data """ segy = _read_segy(name) return np.transpose(np.array([trace.data for trace in segy.traces]))
def get_trace_header_stuff(target): # Copied verbatim from Seisplot # Read the file. section = segy._read_segy(target, unpack_headers=True) # Make the data array. data = np.vstack([t.data for t in section.traces]).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) ens.append(trace.header.ensemble_number) tsq.append(trace.header.trace_sequence_number_within_line) return elev, esp, ens, tsq
def test_unpack_binary_file_header(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 = _read_segy(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)
def load_img(self, img_path): """ reads and normalize a seismogram from the given segy file. :param img_path: a path to the segy file. :return: seismogram image as numpy array normalized between 0-1. """ segy = _read_segy(img_path) _traces = list() for trace in segy.traces: _traces.append(trace.data) x = np.asarray(_traces, dtype=np.float32) std = x.std() x -= x.mean() x /= std x *= 0.1 x += .5 x = np.clip(x, 0, 1) return x.T
def test_read_and_write_segy(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 = _read_segy(file, headonly=headonly) with NamedTemporaryFile() as tf: out_file = tf.name with warnings.catch_warnings(record=True): 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 = from_buffer(org_data, np.int32) new_data = from_buffer(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() # Just patch both headers - this tests something different. org_data = _patch_header(org_data) new_data = _patch_header(new_data) # 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:])
def load_awi_segy(self, segy_file='', coordinate_file='', dB=False, correct_gps=True): ''' ''' from obspy.io.segy.segy import _read_segy import numpy as np import pandas as pd segy_file = segy_file coordinate_file = coordinate_file stream = _read_segy(segy_file, headonly=True) data = pd.DataFrame(np.array([t.data for t in list(stream.traces)])) header = stream.binary_file_header.__dict__ frame = header['line_number'] sample_interval = header['sample_interval_in_microseconds'] sample_interval = sample_interval * 10e-13 number_of_samples = header['number_of_samples_per_data_trace'] # build time array time = np.repeat(sample_interval, number_of_samples) time[0] = 0 time = np.cumsum(time) self.Data = data.T self.Stream = stream self.Time = time self.Frame = str(frame) self.Domain = 'twt' coords = pd.read_csv(coordinate_file, delim_whitespace=True) self.Longitude = coords['GPSLon'].values self.Latitude = coords['GPSLat'].values self.Elevation = coords['GPSAlt'].values self.GPS_time = coords['Time'].values if correct_gps == True: try: self.Latitude = np.array( pd.DataFrame(self.Latitude).mask( pd.DataFrame(self.Latitude).duplicated(keep='first'), np.nan).interpolate()).T[0] self.Longitude = np.array( pd.DataFrame(self.Longitude).mask( pd.DataFrame(self.Longitude).duplicated(keep='first'), np.nan).interpolate()).T[0] except: print('... could not correct gps positions.') if dB == False: self.dB = False elif dB == True: self.dB = True else: print('==> dB True or False? Is set to False.') print('') print('==> Loaded {}'.format(self.Frame)) return self del stream, data, header, time, coords
"""Function to generate reflectivity for a wavelet with input accoustic velocity""" """ input: Nx1 array output: Nx1 array""" nsamples = len(trace_velocity) vfunct_imp = np.vectorize(get_impedance) imp = vfunct_imp(trace_velocity.reshape(nsamples,)) rc = (imp[1:] - imp[:-1])/(imp[1:] + imp[:-1]) rc = np.append(rc,rc[-1]) return rc xl = 676 il = 676 n_samples = 201 stream = _read_segy('../data/SEG_C3NA_Velocity.sgy', headonly=True) full_data = np.stack(t.data for t in stream.traces).reshape(xl*il*n_samples,) rc = np.apply_along_axis(get_reflectivity, 1, full_data.reshape(676*676,201)) w= bruges.filters.ricker(duration = 0.100, dt=0.001, f=120) rc_f = np.apply_along_axis(lambda t:np.convolve(t, w, mode='same'), axis=1, arr=rc) for i in range(676): np.savetxt(f"../data/img_{i:03}.csv", rc_f.reshape(676,676,201)[i,:,:], delimiter = ",", fmt='%.2f')
def FBTime(inputfile): """ Read the input SEG-Y files, 3D-VSP stacked file, sorted in SP, MD, Trace Number (output of stack) save it to a stream object, the seismic format from the Obspy library. Then create a total vector trace with X,Y and Z and pick the onset. Save all first breaks to a text file.""" tic = timeit.default_timer() print('The SEG-Y files is loading ... Please be patient') stream = _read_segy(inputfile, headonly=True) toc = timeit.default_timer() print('The loading took {0:.0f} seconds'.format(toc - tic)) # Create a series of variable to be able to save each component of each geophone # We will automatically figure out the following, number of geophone, number of shot points, number of components nbr_of_geophone = np.count_nonzero( np.unique( np.array([ t.header.datum_elevation_at_receiver_group for t in stream.traces ]))) nbr_of_SP = np.count_nonzero( np.unique( np.array( [t.header.energy_source_point_number for t in stream.traces]))) nbr_of_components = np.count_nonzero( np.unique( np.array([ t.header.trace_number_within_the_ensemble for t in stream.traces ]))) # We QC the variables by checking that the calculated number of traces is equal to the number of traces in the stream object (input SEG-Y file) nbr_of_traces = nbr_of_geophone * nbr_of_SP * nbr_of_components #nbr_of_samples_per_trace = stream.binary_file_header.number_of_samples_per_data_trace if nbr_of_traces == int(str(stream).split()[0]): print('All Shot Points, Components and Geophones accounted for.') else: print( 'Some traces are missing, please stop program and check SEG-Y file header' ) # running_mean is a function with calculates the average in a moving window def running_mean(x, N): cumsum = np.cumsum(np.insert(x, 0, 0)) return (cumsum[N:] - cumsum[:-N]) / N tic = timeit.default_timer( ) #to measure the time it takes to calculate the first break picking #set up a series of variable for the automatic first break picker first_arrival_time = np.empty( 0, dtype=np.int32) #empty array to store the first arrival time fore_window = 10 #10 samples in the fore window back_window = int(fore_window * 1.5) #15 samples in the back window #the first ratio measurement is done at the end of the back window, therefore we need to add 'back_window - 1' sample to the ratio array to get the correct time of the maximum ratio sample auto_pick_ratio_start = np.zeros(back_window - 1) #set up a time array equal to 4 samples time = np.linspace(0, 3, 4) - 2 #Start measuring first arrival time, source-receiver pair by source-receiver pair for i in range(nbr_of_SP * nbr_of_geophone): #create a total vector trace by summing the absolute values of all three components for all samples data_to_vectorise = np.sum([ np.absolute(stream.traces[i * nbr_of_components + j].data) for j in range(nbr_of_components) ], axis=0) #measure the average value in each window on the total vector trace mean_back_window = running_mean(data_to_vectorise, back_window)[:-fore_window] mean_fore_window = running_mean(data_to_vectorise, fore_window)[back_window:] #calculate the ratio between fore and back window auto_pick_ratio = mean_fore_window / mean_back_window #add to the ratio array the 'back_window' samples with couldn't not be measured to have an array with an index equal to the time sample in the data auto_pick_ratio = np.append(auto_pick_ratio_start, auto_pick_ratio) #extract the first arrival time precise to the nearest sample rough_first_arrival_time = auto_pick_ratio.argmax() # interpolate around the rough first arrival time and find a better first break time time_window = time + rough_first_arrival_time #time samples around the first arrival time -5/+4 samples start = int(time_window[0]) #first time sample end = int(time_window[-1]) #last time sample amplitude_window = data_to_vectorise[ start:end + 1] #extract the amplitude of the total vector trace at these time samples #set up the interpolation function to measure amplitude at any time with a cubic spline function f = interp1d(time_window, amplitude_window, kind='cubic') #interpolate every 0.1ms interpolated_amp = np.array([f(t) for t in np.arange(start, end, 0.1)]) #measure the average value in each window on the total vector trace mean_back_window = running_mean(interpolated_amp, back_window)[:-fore_window] mean_fore_window = running_mean(interpolated_amp, fore_window)[back_window:] #calculate the ratio between fore and back window auto_pick_ratio = mean_fore_window / mean_back_window ##### previous interpolation was running too slowly with 100 samples, went down to 40 samples, which now takes about 3ms (+5ms to read the data in the first place) #add the calculated first arrival time to the firt_arrival_time array n time (n = number of components) first_arrival_time = np.append( first_arrival_time, np.repeat(auto_pick_ratio.argmax() / 10 + start, nbr_of_components)) #every 2000 loops tell the users how much has been done of the calculation if i % 2000 == 0: print( 'The automatic first break picking has done {0:.1f}% of the work, almost there!' .format(i / (nbr_of_SP * nbr_of_geophone) * 100)) tac = timeit.default_timer() print('The automatic first break picking took {0:.1f} seconds'.format(tac - tic)) # Save the first arrival time to a text file to import it later on np.savetxt('FirstBreakTime.txt', first_arrival_time, fmt='%.2f')
plt.imshow(data, cmap=cmap, interpolation='bilinear', vmin=0, vmax=vm, aspect='auto') plt.colorbar(label="Amplitude", shrink=0.5) #plt.xlim(xmin=400, xmax=800) #plt.ylim(ymax=800,ymin=1200) #%% ########################### main process ############################## if __name__ == "__main__": '''return a SEGYFile object ''' segy = _read_segy('Data/CX_pst_3710_3720.sgy', headonly=True) '''read the header and trace''' #print(segy.binary_file_header) #print(segy.traces[492].header) segy_inf(segy) #print(segy.textual_file_header.decode(encoding='cp037')) x = np.array(list(segy.textual_file_header.decode(encoding='cp037'))) print('\n'.join(''.join(row) for row in x.reshape((40, 80)))) print(segy.binary_file_header) print(segy.traces[2].header) '''etract line and plot the line''' line3714 = extract_line(segy, 3714) #rows are traces plot_line_attribute(line3714, cmap="seismic", percent=99) #%%
try: max_amp = float(sys.argv[5]) except: print('Please enter a valid integer for the maximum amplitude:') print("Use the following command to run this script") print( "python SEGY_filter_panels_multi.py \"[filename]\" [initial trace] [number of traces] [min amp] [max amp]" ) max_amp = 1 # exit(0) #just reading the SEGY # #---------------------------------------------------------------------------------------- # stream = _read_su(filename,headonly=True) stream = _read_segy(filename, headonly=True) # stream = read(filename,format='segy') # print(stream.textual_file_header) # exit(0) #print(stream) print(stream.textual_file_header.decode()) #print(stream.binary_file_header) print("Trace Length=",stream.traces[0].npts, \ 'sampling interval=',stream.traces[0].header.sample_interval_in_ms_for_this_trace) # init_trace=0 # num_trace=20 tlen = stream.traces[0].npts dt = stream.traces[0].header.sample_interval_in_ms_for_this_trace
np.require(data, dtype=np.float32) trace = Trace(data=data) trace.stats.delta = 0.01 trace.stats.starttime = UTCDateTime(2011, 11, 11, 11, 11, 11) if not hasattr(trace.stats, 'segy.trace_header'): trace.stats.segy = {} trace.stats.segy.trace_header = SEGYTraceHeader() trace.stats.segy.trace_header = stream.traces[idx].header out.append(trace) inputfile = 'test.sgy' print('The SEG-Y files is loading ... Please be patient') tic = timeit.default_timer() stream = _read_segy(inputfile, headonly=True) toc = timeit.default_timer() print('The loading took {0:.0f} seconds'.format(toc - tic)) """ extract all source and receiver (geophone) coordinates """ source_x = np.array([t.header.source_coordinate_x for t in stream.traces])[::3] source_y = np.array([t.header.source_coordinate_y for t in stream.traces])[::3] geo_x = np.array([t.header.group_coordinate_x for t in stream.traces])[::3] geo_y = np.array([t.header.group_coordinate_x for t in stream.traces])[::3] """ measures the source to receiver azimuth """ azimuth = np.round([(360 + math.degrees( math.atan2((source_x[t] - geo_x[t]), (source_y[t] - geo_y[t])))) % 360 for t in range(source_x.size)], decimals=2) """ create a list of all the geophones' depth """ geophone_depths = (np.array( [t.header.datum_elevation_at_receiver_group
num_epochs = 1 batch_size = 56 patch_size = 64 num_channels = 1 num_classes = 9 all_examples = 158812 num_examples = 7500 sampler = list(range(all_examples)) running_loss = 0.0 loss_list = [] ########################## ### DATASET ########################## filename = 'data/Seismic_data.sgy' seismicdata = _read_segy(filename, headonly=True) # train data and lable###### labeled_data = np.load('patchdata.npy') labels = pd.read_csv('data/classification.ixz', delimiter=" ", names=["Inline", "Xline", "Time", "Class"]) labels["Xline"] -= 300 - 1 labels["Time"] = labels["Time"] // 4 # prediction data ######### inline_data = np.stack( t.data for t in seismicdata.traces if t.header.for_3d_poststack_data_this_field_is_for_in_line_number == 500).T train_data, test_data, train_samples, test_samples = train_test_split( labels, sampler, random_state=42) print(train_data.shape, test_data.shape)
def test_unpack_trace_header(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 = _read_segy(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)
plt.xlabel(u"Frequency(Hz)") plt.ylabel(u"Time(ms)") #plt.title(u"Time-frequency Spectrum") plt.colorbar() ax = plt.gca() ax.invert_yaxis() plt.tight_layout() plt.show() return cwtmatr, freqs ##################### Main processes ################################# if __name__ == "__main__": import read_segy as rsegy import resampling as rs segy = _read_segy('data/seis/CX_ZJ_ori.SGY', headonly=True) # time_start = 900.0 # time_stop = 1500.0 # time_step = 2.0 # ms # inline = 3662 # xline = 1938 trace = rsegy.extract_seismic(segy, line=3662, xline=1938, time_start = 810, time_stop= 1500, time_step=2, name='amp') trace_res = rs.resample(trace.time, trace.amp, time_start_re = 820, time_stop_re = 1400, time_step_re = 1, kind="quadratic", plot=False, logname='amp') cc,ff = spectrum_cwt(trace_res.time, trace_res.amp/10000, colorscale=1, widths=100, wavelet='morl', freqmax=100)
def get_nsamples(target): section = segy._read_segy(target, unpack_headers=True) return section.traces[0].header.number_of_samples_in_this_trace
def get_ntraces(target): section = segy._read_segy(target, unpack_headers=True) return len(section.traces)
def read_seismic(): try: t0 = time.time() data = segy_dir_path.get() #use obspy to read data stream = _read_segy(data, headonly=True) #create stream object num_trace = len(stream.traces) #get ns from binary header ns = stream.binary_file_header.number_of_samples_per_data_trace min_il = int(min_inline.get()) max_il = int(int(max_inline.get()) + 1) il_step = int(inline_step.get()) min_xl = int(min_xline.get()) max_xl = int(int(max_xline.get()) + 1) xl_step = int(xline_step.get()) inline_range = np.arange(min_il, max_il, il_step) xline_range = np.arange(min_xl, max_xl, xl_step) total_traces_calculated = (len(inline_range) * len(xline_range)) total_missing_traces = int(total_traces_calculated - num_trace) lines = [ "Total no of traces read : {}".format(num_trace), "Total number of calculated traces :{}".format( total_traces_calculated), "Total traces to pad: {}".format(total_missing_traces) ] tkinter.messagebox.showinfo("INFO", "\n".join(lines)) data = np.stack(t.data for t in stream.traces) #get z dim bounds, nt = data.shape data_t = data.T #Pad data with zero traces data_padded = np.pad(data_t, [(0, 0), (0, total_missing_traces)], mode='constant') data_padded = data_padded.T #Reshape data to a 3d cube shaped_data = np.reshape(data_padded, (inline_range.size, xline_range.size, nt)) #calculate the right colorbar scale vm = np.percentile(shaped_data, 99) #Define the mayavi data source source = mlab.pipeline.scalar_field(shaped_data) source.spacing = [il_step, xl_step, -4] for axis in ['x', 'y', 'z']: plane = mlab.pipeline.image_plane_widget( source, plane_orientation='{}_axes'.format(axis), colormap="gray", vmin=-vm, vmax=vm, slice_index=20) plane.module_manager.scalar_lut_manager.reverse_lut = True mlab.xlabel("XLINE") mlab.ylabel("INLINE") mlab.zlabel("TIME/DEPTH") #mlab.title("3D Seismic Cube : {}".format(str(segy_dir_path.get()))) #mlab.colorbar() mlab.show() except ValueError: tk.messagebox.showinfo("ERROR", "Please check your input bounds") close_window() except FileNotFoundError: tk.messagebox.showinfo("ERROR", "Please check your input File") close_window()
def get_tbase(target): # Read the file. section = segy._read_segy(target, unpack_headers=True) nsamples = section.traces[0].header.number_of_samples_in_this_trace dt = section.traces[0].header.sample_interval_in_ms_for_this_trace return 0.001 * np.arange(0, nsamples * dt, dt)
def segy2segy(inSEGY, outSEGY, s_srs=23029, t_srs=23030, s_coord='Source', t_coord='CDP', force_scaling=False, scaler=1.): ''' Transform coordinates in SEGY files. This function makes use of the GDAL library for processing coordinates and projections. Parameters ---------- inSEGY : Filename Input SEGY file. outSEGY : Filename Output SEGY file. s_srs : Integer Spatial reference system of the input (source) file. Must be defined as a EPSG code, i.e. 23029 for ED50 / UTM Zone 29N t_srs : Integer Spatial reference system of the output (target) file. Must be defined as a EPSG code, i.e. 23030 for ED50 / UTM Zone 30N s_coord : String Position of the coordinates in the input SEGY file. The field corresponds to a byte position in the binary file. t_coord : String Position of the coordinates in the output SEGY file. The field corresponds to a byte position in the binary file. force_scaling : Boolean If True, the program will use the number defined by the scaler argument to calculate the coordinates. Default is False and so the program will read the coordinate scaler from the SEGY file. It will use the same value for writing coordinates in the new SEGY file. scaler : Float Used in combination with force_scaling. The scaler is defined like for a SEGY file, for example -100 for dividing by 100 when reading. ''' # read coordinates from input XYarray, XYscale = segyXY(inSEGY, s_coord, force_scaling, scaler) # transform coordinates newXYarray = spatial.projectPoints(XYarray, s_srs, t_srs) # Apply scaling newXYarray = newXYarray / np.column_stack((XYscale, XYscale)) # load SEGY object (headers only) seis = _read_segy(inSEGY, headonly=True) traces = seis.traces # get key for coordinates position in output file Xcoord, Ycoord = coordKeys[t_coord.lower()] # insert new coordinates in SEGY object for i, trace in enumerate(traces): trace.header.__setattr__(Xcoord, np.round(newXYarray[i, 0])) trace.header.__setattr__(Ycoord, np.round(newXYarray[i, 1])) # write output SEGY with new coordinates seis.write(outSEGY)
def get_sample_rate_in_seconds(target): section = segy._read_segy(target, unpack_headers=True) return 1e-6 * section.traces[0].header.sample_interval_in_ms_for_this_trace