def plot_PPSD(trace, sta, start_time, interval=7200, filebase=None, show=True): """ Plot a Probabilistic Power Spectral Desnsity for the trace trace = obspy Trace objet sta = obspy Inventory/Station object corresponding to the trace start_time = time at which to start spectra interval=offset between PSDs (seconds, minimum=3600) """ now_time = trace.start_time first_read = True while now_time < trace.end_time - interval: if first_read: if trace.stats.component[1] == 'D': ppsd = PPSD(trace.stats, metadata=sta, special_handling='hydrophone') else: ppsd = PPSD(trace.stats, metadata=sta) first_read = False ppsd.add(trace) now_time += interval ppsd.save_npz(f'{filebase}_PPSD.npz') if filebase: description = '{}.{}.{}.{}'.format(trace.stats.network, trace.stats.station, trace.stats.location, trace.stats.channel) ppsd.plot(filebase + '_' + description + '_PPSD.png') if show: plt.plot() # ppsd.plot_temporal([0.1,1,10]) # ppsd.plot_spectrogram() return 0
def ppsd(self, fmin=1., fmax=100., special_handling=None, filename=None, save=False): """ Function that calculates the probabilistic power spectral density of a given station-channel combination. :type fmin: float :param fmin: Minimum frequency to show in PPSD plot :type fmax: float :param fmax: Maximum frequency to show in PPSD plot """ # read list of files files = np.genfromtxt(self.filist, dtype=str) n = files.size # if no paz information is given, divide by 1.0 if self.metadata == None: self.metadata = {"sensitivity": 1.0} # loop over files for i in range(n): st = read(self.path + files[i]) st.merge() #st.decimate(self.dec_fact) if len(st) > 1: warnings.warn("more than one trace in st") tr = st.select(station=self.stn, channel=self.chn)[0] # at first run, initialize PPSD instance if i == 0: # "is_rotational_data" is set in order not to differentiate that data inst = PPSD(tr.stats, metadata=self.metadata, special_handling=special_handling, ppsd_length=1800.) # add trace print("add trace %s ..." % tr) inst.add(tr) print("number of psd segments:", len(inst.current_times_used)) inst.plot(show_noise_models=True, xaxis_frequency=True, period_lim=(fmin, fmax), filename=filename) if save: inst.save_npz("ppsd_%s_%s.npz" % (self.stn, self.chn))
def ppsd(self, fmin=1., fmax=100., special_handling=None, filename=None, save=False): """ Function that calculates the probabilistic power spectral density of a given station-channel combination. :type fmin: float :param fmin: Minimum frequency to show in PPSD plot :type fmax: float :param fmax: Maximum frequency to show in PPSD plot """ # read list of files files = np.genfromtxt(self.filist, dtype=str) n = files.size # if no paz information is given, divide by 1.0 if self.metadata == None: self.metadata = {"sensitivity": 1.0} # loop over files for i in range(n): st = read(files[i]) st.merge() st.decimate(self.dec_fact) if len(st) > 1: warnings.warn("more than one trace in st") tr = st.select(station=self.stn, channel=self.chn)[0] # at first run, initialize PPSD instance if i == 0: # "is_rotational_data" is set in order not to differentiate that data inst = PPSD(tr.stats, metadata=self.metadata, special_handling=special_handling) # add trace print("add trace %s ..." % tr) inst.add(tr) print("number of psd segments:", len(inst.current_times_used)) inst.plot(show_noise_models=True, xaxis_frequency=True, period_lim=(fmin, fmax), filename=filename) if save: inst.save_npz("ppsd_%s_%s.npz" % (self.stn, self.chn))
def _get_ppsd(self, st_info): #Devuelve la ppsd del stream st dado en el parametro de la función try: st = st_info[0] ppsd_dir = st_info[2] print("HOLA ", ppsd_dir) tr = st[0] ppsd = PPSD(tr.stats, metadata=self.parser, skip_on_gaps=True, overlapping=0.5) ppsd.add(st) ppsd.save_npz(ppsd_dir) return [ppsd, ppsd_dir] except Exception as e: msg = ( f"Error getting ppsd from: {st_info[1]} for the next reason:\n" "%s: %s\n" "Skipping this stream.") msg = msg % (e.__class__.__name__, str(e)) warnings.warn(msg) pass
def get_ppsd(my_storage, client, inv, ppsd_restrictions, single_cha_contents, starttime, endtime, plot_trace=False): """ Calculates the ppsd object according to starttime, endtime and ppsd_restrictions parameters. It will be save in my_storage/{network}.{station}.{location}.{channel}/ppsd Parameters: ----------- my_storage: str Path to save all ppsd analyses client: Client object from obspy To use get_waveforms method inv: Inventory object from obspy To recognize the filtered stations that you want to calculate the ppsd ppsd_restrictions: PPSDRestrictions Information about the PPSD parameters single_cha_contents: 'str' network.station.location.channel starttime: UTCDateTime Start time that will be used to calculate the ppsd. endtime: UTCDateTime End time that will be used to calculate the ppsd. plot_trace: Boolean Plot the stream (It consumes a little bit time) """ network, station, location, channel = single_cha_contents.split('.') try: st = client.get_waveforms(network=network, station=station, location=location, channel=channel, starttime=starttime, endtime=endtime) except: strftime = "%Y%m%dT%H%M%SZ" st_warn = (f"{network}." f"{station}." f"{location}." f"{channel}" f"__{starttime.strftime(strftime)}" f"__{endtime.strftime(strftime)}") st = None now = dt.datetime.now().strftime("%Y/%m/%d %H:%M:%S") if st == None: print_logs(job='load_trace', content=single_cha_contents, status='no', path=st_warn) return None if plot_trace == True: plotst_path = get_path(my_storage, PLOT_TRACE_DIRNAME, single_cha_contents, starttime, endtime, extension_file='jpg') filename = os.path.basename(plotst_path) if os.path.isfile(plotst_path) == True: print_logs(job='save_trace', content=single_cha_contents, status='exist', path=filename) else: plotst_dir = os.path.dirname(plotst_path) if os.path.isdir(plotst_dir) == False: os.makedirs(plotst_dir) st.plot(outfile=plotst_path) print_logs(job='save_trace', content=single_cha_contents, status='ok', path=filename) now = dt.datetime.now().strftime("%Y/%m/%d %H:%M:%S") try: ppsd_path = get_path(my_storage, PPSD_DIRNAME, single_cha_contents, starttime, endtime, extension_file='npz') filename = os.path.basename(ppsd_path) if os.path.isfile(ppsd_path) == True: print_logs(job='save_ppsd', content=single_cha_contents, status='exist', path=filename) else: ppsd_dir = os.path.dirname(ppsd_path) if os.path.isdir(ppsd_dir) == False: os.makedirs(ppsd_dir) tr = st[0] ppsd = PPSD(tr.stats, metadata=inv, **ppsd_restrictions.__dict__) ppsd.add(st) if ppsd_restrictions.time_of_weekday != None: ppsd.calculate_histogram( time_of_weekday=ppsd_restrictions.time_of_weekday) ppsd.save_npz(ppsd_path) print_logs(job='save_ppsd', content=single_cha_contents, status='ok', path=filename) except: print_logs(job='save_ppsd', content=single_cha_contents, status='exist', path=filename)
'gain': 60077000.0, 'poles': [ -0.037004 + 0.037016j, -0.037004 - 0.037016j, -251.33 + 0j, -131.04 - 467.29j, -131.04 + 467.29j ], 'sensitivity': 2516778400.0, 'zeros': [0j, 0j] } ppsd = PPSD(tr.stats, paz) print(ppsd.id) print(ppsd.times_processed) ppsd.add(st) print(ppsd.times_processed) ppsd.plot() ppsd.save_npz("myfile.npz") ppsd = PPSD.load_npz("myfile.npz") #%% Try getting the NHNM and NLNM nhnm = spec.get_nhnm() plt.semilogx(nhnm[0], nhnm[1]) nlnm = spec.get_nlnm() plt.semilogx(nlnm[0], nlnm[1])
def main(loglevel="INFO", njobs_per_worker=9999): logger = logbook.Logger("msnoise") # Reconfigure logger to show the pid number in log records logger = get_logger('msnoise.compute_psd_child', loglevel, with_pid=True) logger.info('*** Starting: Compute PPSD ***') db = connect() logger.debug('Preloading all instrument response') responses = preload_instrument_responses(db, return_format="inventory") params = get_params(db) ppsd_components = params.qc_components ppsd_length = params.qc_ppsd_length ppsd_overlap = params.qc_ppsd_overlap ppsd_period_smoothing_width_octaves = params.qc_ppsd_period_smoothing_width_octaves ppsd_period_step_octaves = params.qc_ppsd_period_step_octaves ppsd_period_limits = params.qc_ppsd_period_limits ppsd_db_bins = params.qc_ppsd_db_bins while is_next_job(db, jobtype='PSD'): logger.info("Getting the next job") jobs = get_next_job(db, jobtype='PSD', limit=njobs_per_worker) logger.debug("I will process %i jobs" % len(jobs)) if len(jobs) == 0: # edge case, should only occur when is_next returns true, but # get_next receives no jobs (heavily parallelised code) continue for job in jobs: net, sta, loc = job.pair.split('.') print("Processing %s" % job.pair) gd = UTCDateTime(job.day).datetime files = get_data_availability( db, net=net, sta=sta, loc=loc, starttime=(UTCDateTime(job.day) - 1.5 * ppsd_length).datetime, endtime=gd) if len(files) == 0: print("No files found for %s" % job.day) continue for comp in ppsd_components: toprocess = [] for file in files: if file.chan[-1] != comp: continue tmp = os.path.join(file.path, file.file) toprocess.append(tmp) if len(toprocess) == 0: continue st = Stream() for tmp in np.unique(toprocess): logger.debug("Reading %s" % tmp) try: st += read( tmp, starttime=UTCDateTime(gd) - 1.5 * ppsd_length, endtime=UTCDateTime(gd + datetime.timedelta(days=1)) - 0.001) except: logger.debug("Problem loading %s" % tmp) if not len(st): continue try: st.merge() except: logger.info("Failed merging streams:") traceback.print_exc() continue st = st.split() for tr in st: tr.stats.network = tr.stats.network.upper() tr.stats.station = tr.stats.station.upper() tr.stats.channel = tr.stats.channel.upper() tr = st.select(component=comp)[0] out = to_sds(tr.stats, gd.year, int(gd.strftime('%j'))) npzdout = os.path.join("PSD", "NPZ", out) logger.debug("ppsd will be output to: %s" % npzdout) ppsd = PPSD(tr.stats, metadata=responses, ppsd_length=ppsd_length, overlap=ppsd_overlap, period_smoothing_width_octaves= ppsd_period_smoothing_width_octaves, period_step_octaves=ppsd_period_step_octaves, period_limits=ppsd_period_limits, db_bins=ppsd_db_bins) # TODO handle when the response for this trace is not in the inv ppsd.add(st) out = to_sds(tr.stats, gd.year, int(gd.strftime('%j'))) pngout = os.path.join("PSD", "PNG", out) if not os.path.isdir(os.path.split(npzdout)[0]): os.makedirs(os.path.split(npzdout)[0]) os.makedirs(os.path.split(pngout)[0]) ppsd.save_npz(npzdout + ".npz") update_job(db, job.day, job.pair, 'PSD', 'D', ref=job.ref) if not params.hpc: for job in jobs: update_job(db, job.day, job.pair, 'PSD2HDF', 'T') try: ppsd.plot(pngout + ".png") except: logger.debug("Error saving PNG image") traceback.print_exc() del ppsd logger.debug('Day (job) "D"one')
fn_in = "{}/{}_{}.mseed".format(rawdatadir, datestr, nslc) pbar.set_description("PPSD %s" % fn_in) if not os.path.isfile(fn_in): continue stall = read(fn_in, headonly=True) for mseedid in list(set([tr.id for tr in stall])): npzdatadir = "{}/npz/{}/{}/{}".format(DATADIR, YYYY, MM, DD) pathlib.Path(npzdatadir).mkdir(parents=True, exist_ok=True) #fn_out = "{}/npz/{}_{}.npz".format(DATADIR,datestr, nslc) fn_out = "{}/{}_{}.npz".format(npzdatadir, datestr, nslc) if os.path.isfile(fn_out) and not force_reprocess: continue st = read(fn_in, sourcename=mseedid) trace = st[0] print("ppsd...") ppsd = PPSD(trace.stats, inv, ppsd_length=600, overlap=0.5, period_smoothing_width_octaves=0.025, period_step_octaves=0.0125, period_limits=(freqmin, freqmax), db_bins=(-200, 20, 0.25)) #period_limits=(0.008, 50), print("add traces ...") ppsd.add(st) ppsd.save_npz(fn_out[:-4]) del st, ppsd del stall
#Did you find some new data? updated_ppsd = True #process the traces to zero out gaps e = analysis.prepare_for_ppsd(e) n = analysis.prepare_for_ppsd(n) z = analysis.prepare_for_ppsd(z) Eppsd.add(e) Nppsd.add(n) Zppsd.add(z) #Done with that site, save the god danged ppsd if updated_ppsd == True: print('Updating PPSd for station ' + site) Eppsd.save_npz(Eppsd_file) Nppsd.save_npz(Nppsd_file) Zppsd.save_npz(Zppsd_file) else: print('PPSD for station ' + site + ' was unchanged') # Now plot each one if plot_ppsd: #Reset any stray figures plt.close("all") #get station information stations = genfromtxt(site_list, usecols=0, dtype='U') for ksta in range(len(stations)):