2929from sklearn .cluster import dbscan
3030from scipy .interpolate import LSQUnivariateSpline
3131from pandas .plotting import register_matplotlib_converters , deregister_matplotlib_converters
32+ from seismic .misc import print_exception
3233
3334# import obspy
3435from netCDF4 import Dataset as NCDataset
3738from seismic .ASDFdatabase import FederatedASDFDataSet
3839from seismic .xcorqc .analytic_plot_utils import distance , timestamps_to_plottable_datetimes
3940
40-
4141class XcorrClockAnalyzer :
4242 """
4343 Helper class for bundling of preprocessed cross-correlation data before plotting
@@ -189,8 +189,8 @@ def _preprocess(self):
189189 xc_start_times = xcdata .variables ['IntervalStartTimes' ][:]
190190 # xc_end_times = xcdata.variables['IntervalEndTimes'][:]
191191 xc_lag = xcdata .variables ['lag' ][:]
192- xc_xcorr = xcdata .variables ['xcorr ' ][:, :]
193- xc_num_stacked_windows = xcdata .variables ['NumStackedWindows ' ][:]
192+ xc_xcorr = xcdata .variables ['X ' ][:, :]
193+ xc_num_stacked_windows = xcdata .variables ['nX ' ][:]
194194 xcdata .close ()
195195 xcdata = None
196196
@@ -389,12 +389,12 @@ def plot_resampled_clusters(self, ax, ids, resampled_corrections, stn_code=''):
389389# end class
390390
391391
392- def station_codes (filename ):
392+ def nsl_codes (filename ):
393393 """
394394 Convert a netCDF4 .nc filename generated by correlator to the corresponding
395395 station codes in the format ``NETWORK.STATION``
396396
397- Assumed format: ``NET1.STAT1.NET2.STA2.* .nc``
397+ Assumed format: ``NET1.STAT1.LOC1.CHA1. NET2.STA2.LOC2.CHA2 .nc``
398398
399399 :param filename: The ``.nc`` filename from which to extract the station and network codes
400400 :type filename: str
@@ -403,34 +403,35 @@ def station_codes(filename):
403403 """
404404 _ , fname = os .path .split (filename )
405405 parts = fname .split ('.' )
406- sta1 = '.' .join (parts [0 :2 ])
407- sta2 = '.' .join (parts [2 : 4 ])
408- return (sta1 , sta2 )
406+ nsl1 = '.' .join (parts [0 :3 ])
407+ nsl2 = '.' .join (parts [4 : 7 ])
408+ return (nsl1 , nsl2 )
409409
410410
411- def station_distance (federated_ds , code1 , code2 ):
411+ def station_distance (federated_ds , nsl1 , nsl2 ):
412412 """
413413 Determine the distance in km between a pair of stations at a given time.
414414
415415 :param federated_ds: Federated dataset to query for station coordinates
416416 :type federated_ds: seismic.ASDFdatabase.FederatedASDFDataSet
417- :param code1: Station and network code in the format ``NETWORK.STATION`` for first station
418- :type code1 : str
419- :param code2: Station and network code in the format ``NETWORK.STATION`` for second station
420- :type code2 : str
417+ :param nsl1: ``NETWORK.STATION.LOCATION `` for first station
418+ :type nsl1 : str
419+ :param nsl2: ``NETWORK.STATION.LOCATION `` for second station
420+ :type nsl2 : str
421421 :return: Distance between stations in kilometers
422422 :rtype: float
423423 """
424- coords1 = federated_ds .unique_coordinates [code1 ]
425- coords2 = federated_ds .unique_coordinates [code2 ]
424+
425+ ns1 = '.' .join (nsl1 .split ('.' )[:2 ])
426+ ns2 = '.' .join (nsl2 .split ('.' )[:2 ])
427+ coords1 = federated_ds .unique_coordinates [ns1 ]
428+ coords2 = federated_ds .unique_coordinates [ns2 ]
426429 return distance (coords1 , coords2 )
427430
428431
429432def plot_xcorr_time_series (ax , x_lag , y_times , xcorr_data , use_formatter = False ):
430-
431433 np_times = np .array ([datetime .datetime .utcfromtimestamp (v ) for v in y_times ]).astype ('datetime64[s]' )
432- gx , gy = np .meshgrid (x_lag , np_times )
433- im = ax .pcolormesh (gx , gy , xcorr_data , cmap = 'RdYlBu_r' , vmin = 0 , vmax = 1 , rasterized = True )
434+ im = ax .pcolormesh (x_lag , np_times , xcorr_data , cmap = 'RdYlBu_r' , vmin = 0 , vmax = 1 , rasterized = True )
434435
435436 if use_formatter :
436437 date_formatter = matplotlib .dates .DateFormatter ("%Y-%m-%d" )
@@ -515,14 +516,13 @@ def plot_estimated_timeshift(ax, x_lag, y_times, correction, annotation=None, ro
515516 if row_rcf_crosscorr is not None :
516517 # Line plot laid over the top of RCF * CCF
517518 np_times = np .array ([datetime .datetime .utcfromtimestamp (v ) for v in y_times ]).astype ('datetime64[s]' )
518- gx , gy = np .meshgrid (x_lag , np_times )
519519 plot_data = row_rcf_crosscorr
520520 crange_floor = 0.7
521521 plot_data [np .isnan (plot_data )] = crange_floor
522522 plot_data [(plot_data < crange_floor )] = crange_floor
523523 nan_mask = np .isnan (correction )
524524 plot_data [nan_mask , :] = np .nan
525- ax .pcolormesh (gx , gy , plot_data , cmap = 'RdYlBu_r' , rasterized = True )
525+ ax .pcolormesh (x_lag , np_times , plot_data , cmap = 'RdYlBu_r' , rasterized = True )
526526 ax .set_ylim ((min (np_times ), max (np_times )))
527527 xrange = 1.2 * np .nanmax (np .abs (correction ))
528528 ax .set_xlim ((- xrange , xrange ))
@@ -561,15 +561,15 @@ def plot_xcorr_file_clock_analysis(src_file, asdf_dataset, time_window, snr_thre
561561 rcf_corrected = xcorr_ca .rcf_corrected
562562 row_rcf_crosscorr = xcorr_ca .row_rcf_crosscorr
563563
564- origin_code , dest_code = station_codes (src_file )
565- dist = station_distance (asdf_dataset , origin_code , dest_code )
564+ nsl1 , nsl2 = nsl_codes (src_file )
565+ dist = station_distance (asdf_dataset , nsl1 , nsl2 )
566566
567567 # -----------------------------------------------------------------------
568568 # Master layout and plotting code
569569
570570 fig = plt .figure (figsize = (11.69 , 16.53 ))
571- fig .suptitle ("Station: {}, Dist. to {} : {:3.2f} km{}" .format (
572- origin_code , dest_code , dist , '' if not title_tag else ' ' + title_tag ), fontsize = 16 , y = 1 )
571+ fig .suptitle ("Station-pair : {}-{}, Separation : {:3.2f} km{}" .format (
572+ nsl1 , nsl2 , dist , '' if not title_tag else ' ' + title_tag ), fontsize = 16 , y = 1 )
573573
574574 ax1 = fig .add_axes ([0.1 , 0.075 , 0.5 , 0.725 ])
575575
@@ -623,13 +623,9 @@ def setstr(name):
623623 pdf_out = PdfPages (pdf_file )
624624 pdf_out .savefig (plt .gcf (), dpi = 600 )
625625 pdf_out .close ()
626- # Change permissions so that others in same group can read and write over this file.
627- os .chmod (pdf_file , (stat .S_IRGRP | stat .S_IWGRP ))
628626
629627 if png_file is not None :
630628 plt .savefig (png_file , dpi = 150 )
631- # Change permissions so that others in same group can read and write over this file.
632- os .chmod (png_file , (stat .S_IRGRP | stat .S_IWGRP ))
633629
634630 if show :
635631 plt .show ()
@@ -663,8 +659,8 @@ def read_correlator_config(nc_file):
663659 folder , fname = os .path .split (nc_file )
664660 base , _ = os .path .splitext (fname )
665661 base_parts = base .split ('.' )
666- if len (base_parts ) > 4 :
667- timestamp = '.' .join (base_parts [4 :])
662+ if len (base_parts ) > 8 :
663+ timestamp = '.' .join (base_parts [8 :])
668664 config_filename = '.' .join (['correlator' , timestamp , 'cfg' ])
669665 config_file = os .path .join (folder , config_filename )
670666 if os .path .exists (config_file ):
@@ -732,6 +728,7 @@ def batch_process_xcorr(src_files, dataset, time_window, snr_threshold, pearson_
732728 if save_plots :
733729 basename , _ = os .path .splitext (src_file )
734730 png_file = basename + ".png"
731+ pdf_file = basename + ".pdf"
735732 # If png file already exists and has later timestamp than src_file, then skip it.
736733 if os .path .exists (png_file ):
737734 src_file_time = os .path .getmtime (src_file )
@@ -745,7 +742,8 @@ def batch_process_xcorr(src_files, dataset, time_window, snr_threshold, pearson_
745742 pbar .update ()
746743 continue
747744 plot_xcorr_file_clock_analysis (src_file , dataset , time_window , snr_threshold , pearson_cutoff_factor ,
748- png_file = png_file , show = False , underlay_rcf_xcorr = underlay_rcf_xcorr ,
745+ pdf_file = pdf_file , show = False ,
746+ underlay_rcf_xcorr = underlay_rcf_xcorr ,
749747 title_tag = title_tag , settings = settings )
750748 else :
751749 plot_xcorr_file_clock_analysis (src_file , dataset , time_window , snr_threshold , pearson_cutoff_factor ,
@@ -755,6 +753,7 @@ def batch_process_xcorr(src_files, dataset, time_window, snr_threshold, pearson_
755753 pbar .update ()
756754
757755 except Exception as e :
756+ print_exception (e )
758757 tqdm .write ("ERROR processing file {}" .format (src_file ))
759758 failed_files .append ((src_file , str (e )))
760759
0 commit comments