Shah5105
Shah5105

Reputation: 57

loop to read multiple files

I am using Obspy _read_segy function to read a segy file using following line of code:

line_1=_read_segy('st1.segy')

However I have a large number of files in a folder as follow:

st1.segy
st2.segy
st3.segy
.
.
st700.segy

I want to use a for loop to read the data but I am new so can any one help me in this regard. Currently i am using repeated lines to read data as follow:

line_2=_read_segy('st1.segy')
line_2=_read_segy('st2.segy')

The next step is to display the segy data using matplotlib and again i am using following line of code on individual lines which makes it way to much repeated work. Can someone help me with creating a loop to display the data and save the figures .

data=np.stack(t.data for t in line_1.traces)
vm=np.percentile(data,99)
plt.figure(figsize=(60,30))
plt.imshow(data.T, cmap='seismic',vmin=-vm, vmax=vm, aspect='auto')
plt.title('Line_1')
plt.savefig('Line_1.png')
plt.show()

Your kind suggestions will help me a lot as I am a beginner in python programming. Thank you

Upvotes: 1

Views: 1192

Answers (3)

rbatt
rbatt

Reputation: 4797

I'll focus on addressing the file looping, as you said you're new and I'm assuming simple loops are something you'd like to learn about (the first example is sufficient for this).

If you'd like an answer to your second question, it might be worth providing some example data, the output result (graph) of your current attempt, and a description of your desired output. If you provide that reproducible example and clear description of the problem you're having it'd be easier to answer.

Create a list (or other iterable) to hold the file names to read, and another container (maybe a dict) to hold the result of your read_segy.

files = ['st1.segy', 'st2.segy']
lines = {} # creates an empty dictionary; dictionaries consist of key: value pairs
for f in files: # f will first be 'st1.segy', then 'st2.segy'
    lines[f] = read_segy(f)

As stated in the comment by @Guimoute, if you want to dynamically generate the file names, you can create the files list by pasting integers to the base file name.

lines = {} # creates an empty dictionary; dictionaries have key: value pairs
missing_files = []
for i in range(1, 701):
    f = f"st{str(i)}.segy" # would give "st1.segy" for i = 1
    try: # in case one of the files is missing or can’t be read
        lines[f] = read_segy(f)
    except:
        missing_files.append(f) # store names of missing or unreadable files

Upvotes: 1

Kris
Kris

Reputation: 8868

If you want to reduce code duplication, you use something called functions. And If you want to repeatedly do something, you can use loops. So you can call a function in a loop, if you want to do this for all files.

Now, for reading the files in folder, you can use glob package of python. Something like below:

import glob, os
def save_fig(in_file_name, out_file_name):
    line_1 = _read_segy(in_file_name)
    data = np.stack(t.data for t in line_1.traces)
    vm = np.percentile(data, 99)
    plt.figure(figsize=(60, 30))
    plt.imshow(data.T, cmap='seismic', vmin=-vm, vmax=vm, aspect='auto')
    plt.title(out_file_name)
    plt.savefig(out_file_name)



segy_files = list(glob.glob(segy_files_path+"/*.segy"))
for index, file in enumerate(segy_files):
    save_fig(file, "Line_{}.png".format(index + 1))

I have not added other imports here, which you know to add!. segy_files_path is the folder where your files reside.

Upvotes: 1

Guimoute
Guimoute

Reputation: 4629

You just need to dynamically open the files in a loop. Fortunately they all follow the same naming pattern.

N = 700
for n in range(N):
    line_n =_read_segy(f"st{n}.segy") # Dynamic name. 
    data = np.stack(t.data for t in line_n.traces)
    vm = np.percentile(data, 99)
    plt.figure(figsize=(60, 30))
    plt.imshow(data.T, cmap="seismic", vmin=-vm, vmax=vm, aspect="auto")
    plt.title(f"Line_{n}")
    plt.show()    
    plt.savefig(f"Line_{n}.png")
    plt.close() # Needed if you don't want to keep 700 figures open. 

Upvotes: 1

Related Questions