29
29
from sklearn .cluster import dbscan
30
30
from scipy .interpolate import LSQUnivariateSpline
31
31
from pandas .plotting import register_matplotlib_converters , deregister_matplotlib_converters
32
+ from seismic .misc import print_exception
32
33
33
34
# import obspy
34
35
from netCDF4 import Dataset as NCDataset
37
38
from seismic .ASDFdatabase import FederatedASDFDataSet
38
39
from seismic .xcorqc .analytic_plot_utils import distance , timestamps_to_plottable_datetimes
39
40
40
-
41
41
class XcorrClockAnalyzer :
42
42
"""
43
43
Helper class for bundling of preprocessed cross-correlation data before plotting
@@ -189,8 +189,8 @@ def _preprocess(self):
189
189
xc_start_times = xcdata .variables ['IntervalStartTimes' ][:]
190
190
# xc_end_times = xcdata.variables['IntervalEndTimes'][:]
191
191
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 ' ][:]
194
194
xcdata .close ()
195
195
xcdata = None
196
196
@@ -389,12 +389,12 @@ def plot_resampled_clusters(self, ax, ids, resampled_corrections, stn_code=''):
389
389
# end class
390
390
391
391
392
- def station_codes (filename ):
392
+ def nsl_codes (filename ):
393
393
"""
394
394
Convert a netCDF4 .nc filename generated by correlator to the corresponding
395
395
station codes in the format ``NETWORK.STATION``
396
396
397
- Assumed format: ``NET1.STAT1.NET2.STA2.* .nc``
397
+ Assumed format: ``NET1.STAT1.LOC1.CHA1. NET2.STA2.LOC2.CHA2 .nc``
398
398
399
399
:param filename: The ``.nc`` filename from which to extract the station and network codes
400
400
:type filename: str
@@ -403,34 +403,35 @@ def station_codes(filename):
403
403
"""
404
404
_ , fname = os .path .split (filename )
405
405
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 )
409
409
410
410
411
- def station_distance (federated_ds , code1 , code2 ):
411
+ def station_distance (federated_ds , nsl1 , nsl2 ):
412
412
"""
413
413
Determine the distance in km between a pair of stations at a given time.
414
414
415
415
:param federated_ds: Federated dataset to query for station coordinates
416
416
: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
421
421
:return: Distance between stations in kilometers
422
422
:rtype: float
423
423
"""
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 ]
426
429
return distance (coords1 , coords2 )
427
430
428
431
429
432
def plot_xcorr_time_series (ax , x_lag , y_times , xcorr_data , use_formatter = False ):
430
-
431
433
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 )
434
435
435
436
if use_formatter :
436
437
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
515
516
if row_rcf_crosscorr is not None :
516
517
# Line plot laid over the top of RCF * CCF
517
518
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 )
519
519
plot_data = row_rcf_crosscorr
520
520
crange_floor = 0.7
521
521
plot_data [np .isnan (plot_data )] = crange_floor
522
522
plot_data [(plot_data < crange_floor )] = crange_floor
523
523
nan_mask = np .isnan (correction )
524
524
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 )
526
526
ax .set_ylim ((min (np_times ), max (np_times )))
527
527
xrange = 1.2 * np .nanmax (np .abs (correction ))
528
528
ax .set_xlim ((- xrange , xrange ))
@@ -561,15 +561,15 @@ def plot_xcorr_file_clock_analysis(src_file, asdf_dataset, time_window, snr_thre
561
561
rcf_corrected = xcorr_ca .rcf_corrected
562
562
row_rcf_crosscorr = xcorr_ca .row_rcf_crosscorr
563
563
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 )
566
566
567
567
# -----------------------------------------------------------------------
568
568
# Master layout and plotting code
569
569
570
570
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 )
573
573
574
574
ax1 = fig .add_axes ([0.1 , 0.075 , 0.5 , 0.725 ])
575
575
@@ -623,13 +623,9 @@ def setstr(name):
623
623
pdf_out = PdfPages (pdf_file )
624
624
pdf_out .savefig (plt .gcf (), dpi = 600 )
625
625
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 ))
628
626
629
627
if png_file is not None :
630
628
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 ))
633
629
634
630
if show :
635
631
plt .show ()
@@ -663,8 +659,8 @@ def read_correlator_config(nc_file):
663
659
folder , fname = os .path .split (nc_file )
664
660
base , _ = os .path .splitext (fname )
665
661
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 :])
668
664
config_filename = '.' .join (['correlator' , timestamp , 'cfg' ])
669
665
config_file = os .path .join (folder , config_filename )
670
666
if os .path .exists (config_file ):
@@ -732,6 +728,7 @@ def batch_process_xcorr(src_files, dataset, time_window, snr_threshold, pearson_
732
728
if save_plots :
733
729
basename , _ = os .path .splitext (src_file )
734
730
png_file = basename + ".png"
731
+ pdf_file = basename + ".pdf"
735
732
# If png file already exists and has later timestamp than src_file, then skip it.
736
733
if os .path .exists (png_file ):
737
734
src_file_time = os .path .getmtime (src_file )
@@ -745,7 +742,8 @@ def batch_process_xcorr(src_files, dataset, time_window, snr_threshold, pearson_
745
742
pbar .update ()
746
743
continue
747
744
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 ,
749
747
title_tag = title_tag , settings = settings )
750
748
else :
751
749
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_
755
753
pbar .update ()
756
754
757
755
except Exception as e :
756
+ print_exception (e )
758
757
tqdm .write ("ERROR processing file {}" .format (src_file ))
759
758
failed_files .append ((src_file , str (e )))
760
759
0 commit comments