@@ -80,6 +80,7 @@ def __init__(self, observed, synthetic, config, event=None, station=None):
8080
8181 self .ttimes = []
8282 self .windows = []
83+ self .rejects = {}
8384
8485 self .taupy_model = TauPyModel (model = self .config .earth_model )
8586
@@ -446,7 +447,9 @@ def filter_window_noise(win):
446447 else :
447448 raise NotImplementedError
448449
449- self .windows = list (filter (filter_window_noise , self .windows ))
450+ windows = list (filter (filter_window_noise , self .windows ))
451+ self .separate_rejects (windows , "s2n" )
452+
450453 logger .info ("SN amplitude ratio window rejection retained %i windows" %
451454 len (self .windows ))
452455
@@ -524,10 +527,11 @@ def reject_on_traveltimes(self):
524527
525528 min_time = self .ttimes [0 ]["time" ] - self .config .min_period + offset
526529 max_time = dist_in_km / self .config .min_surface_wave_velocity + offset
530+ windows = [win for win in self .windows
531+ if (win .relative_endtime >= min_time ) and
532+ (win .relative_starttime <= max_time )]
527533
528- self .windows = [win for win in self .windows
529- if (win .relative_endtime >= min_time ) and
530- (win .relative_starttime <= max_time )]
534+ self .separate_rejects (windows , "traveltimes" )
531535 logger .info ("Rejection based on travel times retained %i windows." %
532536 len (self .windows ))
533537
@@ -559,6 +563,38 @@ def initial_window_selection(self):
559563 logger .info ("Initial window selection yielded %i possible windows." %
560564 len (self .windows ))
561565
566+
567+ def separate_rejects (self , windows , key ):
568+ """
569+ Separate a new batch of selected windows from the rejected windows.
570+
571+ Similar to remove_duplicates(), checks left and right bounds to
572+ determine which windows have been rejected by a given function,
573+ reassigns internal windows attribute, and adds rejected windows to
574+ rejects attribute with a given tag specified by calling function
575+
576+ :type windows: list
577+ :param windows: list of Window objects that have been outputted by
578+ a rejection function
579+ :type tag: str
580+ :param tag: tag based on the function that rejected the windows
581+ """
582+ # Determine unique tags for the new set of windows
583+ new_windows = [(win .left , win .right ) for win in windows ]
584+
585+ # Scroll through current windows and sort by accept/reject
586+ accepted_windows , rejected_windows = [], []
587+ for window in self .windows :
588+ tag = (window .left , window .right )
589+ if tag in new_windows :
590+ accepted_windows .append (window )
591+ else :
592+ rejected_windows .append (window )
593+
594+ self .windows = accepted_windows
595+ if rejected_windows :
596+ self .rejects [key ] = rejected_windows
597+
562598 def remove_duplicates (self ):
563599 """
564600 Filter to remove duplicate windows based on left and right bounds.
@@ -583,8 +619,10 @@ def schedule_weighted_intervals(self):
583619 """
584620 Run the weighted interval scheduling.
585621 """
586- self .windows = schedule_weighted_intervals (self .windows )
587- logger .info ("Weighted interval schedule optimzation retained %i "
622+ windows = schedule_weighted_intervals (self .windows )
623+ self .separate_rejects (windows , "schedule" )
624+
625+ logger .info ("Weighted interval schedule optimization retained %i "
588626 "windows." % len (self .windows ))
589627
590628 def reject_on_minima_water_level (self ):
@@ -600,7 +638,9 @@ def filter_window_minima(win):
600638 return not np .any (self .stalta [internal_minima ] <=
601639 waterlevel_midpoint )
602640
603- self .windows = list (filter (filter_window_minima , self .windows ))
641+ windows = list (filter (filter_window_minima , self .windows ))
642+ self .separate_rejects (windows , "water_level" )
643+
604644 logger .info ("Water level rejection retained %i windows" %
605645 len (self .windows ))
606646
@@ -631,8 +671,10 @@ def filter_windows_maximum_prominence(win):
631671 return False
632672 return True
633673
634- self . windows = list (filter (filter_windows_maximum_prominence ,
674+ windows = list (filter (filter_windows_maximum_prominence ,
635675 self .windows ))
676+ self .separate_rejects (windows , "prominence" )
677+
636678 logger .info ("Prominence of central peak rejection retained "
637679 "%i windows." % len (self .windows ))
638680
@@ -675,8 +717,8 @@ def filter_phase_rejection(win):
675717 return True
676718 return False
677719
678- self . windows = list (filter (
679- filter_phase_rejection , self .windows ) )
720+ windows = list (filter (filter_phase_rejection , self . windows ))
721+ self .separate_rejects ( windows , "phase_sep" )
680722 logger .info ("Single phase group rejection retained %i windows" %
681723 len (self .windows ))
682724
@@ -711,7 +753,9 @@ def curtail_window_length(win):
711753 win .right = int (i_right + time_decay_right )
712754 return win
713755
714- self .windows = [curtail_window_length (i ) for i in self .windows ]
756+ windows = [curtail_window_length (i ) for i in self .windows ]
757+ self .separate_rejects (windows , "curtail" )
758+
715759
716760 @property
717761 def minimum_window_length (self ):
@@ -725,9 +769,10 @@ def reject_windows_based_on_minimum_length(self):
725769 """
726770 Reject windows smaller than the minimal window length.
727771 """
728- self . windows = list (filter (
772+ windows = list (filter (
729773 lambda x : (x .right - x .left ) >= self .minimum_window_length ,
730774 self .windows ))
775+ self .separate_rejects (windows , "min_length" )
731776 logger .info ("Rejection based on minimum window length retained %i "
732777 "windows." % len (self .windows ))
733778
@@ -764,7 +809,9 @@ def reject_based_on_criteria(win):
764809 return False
765810 return True
766811
767- self .windows = list (filter (reject_based_on_criteria , self .windows ))
812+ windows = list (filter (reject_based_on_criteria , self .windows ))
813+ self .separate_rejects (windows , "data_fit" )
814+
768815 logger .info ("Rejection based on data fit criteria retained %i windows."
769816 % len (self .windows ))
770817
0 commit comments