From b3b6073d9127d675d2d1326b6bf5459dde76ccfc Mon Sep 17 00:00:00 2001 From: GarethCabournDavies Date: Fri, 24 Nov 2023 05:40:39 -0800 Subject: [PATCH] allow option to do a logical and on masks --- .../pycbc_plot_trigger_timeseries | 2 +- bin/minifollowups/pycbc_sngl_minifollowup | 9 ++--- bin/plotting/pycbc_plot_singles_vs_params | 2 +- pycbc/io/hdf.py | 36 +++++++++++++++++-- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/bin/minifollowups/pycbc_plot_trigger_timeseries b/bin/minifollowups/pycbc_plot_trigger_timeseries index 68cd473fa56..6cc5c575375 100644 --- a/bin/minifollowups/pycbc_plot_trigger_timeseries +++ b/bin/minifollowups/pycbc_plot_trigger_timeseries @@ -67,7 +67,7 @@ for ifo in args.single_trigger_files.keys(): group=ifo, indices_only=True ) - data_mask = np.zeros(data[ifo]['snr'].size, dtype=bool) + data_mask = numpy.zeros(data[ifo]['snr'].size, dtype=bool) data_mask[idx] = True if not len(idx): diff --git a/bin/minifollowups/pycbc_sngl_minifollowup b/bin/minifollowups/pycbc_sngl_minifollowup index 0a999f9cb0e..5515e87a930 100644 --- a/bin/minifollowups/pycbc_sngl_minifollowup +++ b/bin/minifollowups/pycbc_sngl_minifollowup @@ -65,8 +65,9 @@ parser.add_argument('--inspiral-data-read-name', parser.add_argument('--inspiral-data-analyzed-name', help="Name of inspiral segmentlist containing data " "analyzed by each analysis job.") -parser.add_argument('--min-snr', type=float, default=6.5, - help="Minimum SNR to consider for loudest triggers") +parser.add_argument('--min-sngl-ranking', type=float, default=6.5, + help="Minimum sngl-ranking to consider for loudest " + "triggers. Default=6.5.") parser.add_argument('--non-coinc-time-only', action='store_true', help="If given remove (veto) single-detector triggers " "that occur during a time when at least one other " @@ -136,8 +137,8 @@ trigs = hdf.SingleDetTriggers( bank_file=args.bank_file, veto_file=args.foreground_censor_file, segment_name=args.foreground_segment_name, - filter_ranking='snr', - filter_threshold=args.min_snr + filter_rank=args.sngl_ranking, + filter_threshold=args.min_sngl_ranking ) # Include gating vetoes diff --git a/bin/plotting/pycbc_plot_singles_vs_params b/bin/plotting/pycbc_plot_singles_vs_params index be70e065a27..c7569ae2671 100644 --- a/bin/plotting/pycbc_plot_singles_vs_params +++ b/bin/plotting/pycbc_plot_singles_vs_params @@ -107,7 +107,7 @@ if opts.z_var == 'density' or opts.min_z is None: filter_thresh = None else: # We can apply a/another filter on the z value - filter_rank = ranking.sngls_ranking_function_dict[opts.z_var] + filter_rank = opts.z_var filter_thresh = opts.min_z trigs = pycbc.io.SingleDetTriggers( diff --git a/pycbc/io/hdf.py b/pycbc/io/hdf.py index 0c7257c6b46..61f2182d793 100644 --- a/pycbc/io/hdf.py +++ b/pycbc/io/hdf.py @@ -537,7 +537,8 @@ def __init__(self, trig_file, detector, bank_file=None, veto_file=None, chunksize=chunksize, ) logging.info("%d triggers remain", idx.size) - self.apply_mask(idx) + # If self.mask already has values, need to take these into account: + self.and_masks(idx) if filter_func: # Apply a filter on the triggers which is _not_ a ranking statistic @@ -617,7 +618,12 @@ def get_param_names(cls): if type(m[1]) == property] def apply_mask(self, logic_mask): - """Apply a mask over the top of the current mask""" + """Apply a mask over the top of the current mask + + Parameters + ---------- + logic_mask : boolean array or numpy array of indices + """ if self.mask is None: self.mask = np.zeros(self.ntriggers, dtype=bool) self.mask[logic_mask] = True @@ -628,6 +634,32 @@ def apply_mask(self, logic_mask): else: self.mask = list(np.array(self.mask)[logic_mask]) + def and_masks(self, logic_mask): + """Apply a mask to be combined as a logical and with the current mask. + + Parameters + ---------- + logic_mask : boolean array or numpy array of indices + """ + if self.mask is None: + # No mask exists, just update to use the given mask + self.apply_mask(logic_mask) + return + + # Use intersection of the indices of True values in the masks + if hasattr(logic_mask, 'dtype') and (logic_mask.dtype == 'bool'): + new_indices = self.mask.nonzero()[0][logic_mask] + else: + new_indices = np.array(logic_mask) + + if hasattr(self.mask, 'dtype') and (self.mask.dtype == 'bool'): + orig_indices = self.mask.nonzero()[0][logic_mask] + else: + orig_indices = np.array(self.mask) + + self.mask[:] = False + self.mask[np.intersect1d(new_indices, orig_indices)] = True + def mask_to_n_loudest_clustered_events(self, rank_method, ranking_threshold=6, n_loudest=10,