В этом коде происходит утечка памяти? или нет - PullRequest
0 голосов
/ 17 марта 2020

Я написал ниже python код для создания фигуры. Это выглядит хорошо, когда я работаю с меньшими данными. Но когда я запускаю этот код с большими данными, возникает проблема, которая выглядит как «стек памяти». Память неуклонно растет с бегом. Поскольку этот код является простой итерацией, поэтому я не думаю, что этот код использует слишком много памяти (используется от 1 до 2% до 90 ~ 95% при использовании). Я думаю, что использованная память не уничтожается, а накапливается, когда итерация заканчивается. Тем не менее, я не знаю, как исправить и подтвердить использование памяти в этом коде. Не могли бы вы помочь мне, пожалуйста,

#!/usr/bin/env python3

from obspy.core import read
from obspy.signal.trigger import recursive_sta_lta as stalta
from obspy.signal.trigger import plot_trigger
from obspy.signal.trigger import trigger_onset
from obspy.core import UTCDateTime as ut
import matplotlib.pyplot as plt
import numpy as np
from collections import deque
import os
import datetime

def plot_st(base_path, save_path):
    f_starttime = ut.now()
    st_time = ut(2018,11,10)
    end_time = ut(2019,10,31)
    day_count = int((end_time - st_time) / 86400)

    for date in range(day_count):
        time = st_time + date * 86400
        y = str(time.year)
        m = str(time.month)
        d = str(time.day)
        if time.month < 10:
            m = '0'+m
        else:
            m = m
        if time.day < 10:
            d = '0'+d
        else:
            d = d

        ymd = '%s' %(y[2:4]+m+d)
        print(ymd)
        # Set base_path => detection result directory
    #    base_path = './test/all_st'
        try:
            dir_count = len(next(os.walk('%s/%s' %(base_path, ymd)))[1])
        except:
            print("No data in %s" %(y+m+d))
            continue
#        print(dir_count)
        for count in range(0, dir_count):
            if count < 10:
                dir_loc = '000%s' %count
            elif count > 9 and count < 100:
                dir_loc = '00%s' %count
            elif count > 99 and count < 1000:
                dir_loc = '0%s' %count
            else:
                dir_loc = '%s' %count
            st = read('%s/%s/%s/*.sac' %(base_path, ymd, dir_loc), format = 'sac')
            print('The number of stream ... %s' %len(st))
            plt.rcParams["figure.figsize"] = (24,20)
            plt.rcParams["lines.linewidth"] = 2
            plt.rcParams["lines.color"] = 'k'
            plt.rcParams["axes.grid"] = True
            plt.rc('font', size = 14)
            # plt.rc('xtick', labelsize = )
            # plt.rc('ytick', labelsize = )
            plt.rc('legend', fontsize = 14)

            #st = read('./test/all_st/181230/0001/*.sac',format = 'sac')
            tr = st[0]
            sttime = ut(tr.stats.starttime)
            hour = sttime.hour
            minute = sttime.minute
            second = sttime.second
            print('Making %s\n%s/%s/%s,%s:%s:%s' %(tr, y, m, d, hour, minute, second))
            st.filter('bandpass',freqmin=5,freqmax=10,corners=2,zerophase=True)
            st.taper(0.05)
            st.detrend()
            df = tr.stats.sampling_rate
            npts = tr.stats.npts

            # Cut trace time due to primary data point fluctuation because of slicing
            # You can use np.delete instead of below
            t = np.arange(npts-1000, dtype = np.float32)/df

            fig = plt.figure()

            # Set axis and title
            ax2 = plt.subplot(len(st),1,1)
            ax2.axis('off')
            ax2.set_title('%s_%s' %(ymd, dir_loc), fontweight = 'bold', fontsize = 20)
    #         t = np.delete(t, range(0,1000), None)

            for j in range(0,len(st)):
                tr = st[j]
            #   tr.filter('bandpass', freqmin = 5, freqmax = 10, corners = 2, zerophase = True)
                cft = stalta(tr, int(0.5*df), int(10*df))
            #   tr.detrend()
            #   tr.taper(0.05)

            # Cut trace due to primary data point fluctuation because of slicing
                t1 = tr.stats.starttime + 10
                t2 = tr.stats.endtime
                tr = tr.slice(t1,t2)
                cft = stalta(tr, int(0.5 * df), int(5 * df))
                on_off = np.array(trigger_onset(cft, 4, 3))
            #   ax1 = plt.subplot(12,1,1)
                ax1 = fig.add_subplot(len(st),1,j+1, sharex=ax2)
                plt.plot(t, tr.data, 'k', label = "Station: %s" %tr.stats.station)
                i, j  = ax1.get_ylim()
                ax1.legend(loc = 'upper right')
                # Make sta/lta trigger on/off vertical line
                try:
                    ax1.vlines(on_off[:,0]/df, i, j, color='r', lw=2, label="Trigger On", alpha = 0.5)
            #       ax1.vlines(on_off[:,1]/df, i, j, color='b', lw=2, label="Trigger Off")
                    ax1.legend(loc = 'upper right')
                except IndexError:
                    pass

            # Set x-label as trace start time
            ax1.set_xlabel('Start time: %s' %tr.stats.starttime, fontsize = 20)

            # Set no space within traces graph (all traces per one graph)
            plt.subplots_adjust(hspace=0)

            di = os.path.isdir('%s/%s' %(save_path, y+m))
            if di == False:
                os.mkdir('%s/%s' %(save_path,y+m))
            save = '%s/%s' %(save_path, y+m)
            # Set save directory of figure that has name of
            # year, month, day and the number of detected events
            fig.savefig('./%s/%s_%s.png' %(save,ymd,dir_loc), format = 'png')
            print('Figure is saved')
    f_endtime = ut.now()
    print('Total time: %ss' %(f_endtime - f_starttime))

base_path = './test/all_st'
save_path = './detection_figure/all_st'

plot_st(base_path, save_path)
...