def check_coinc_results(): coinc_fail = False # gather coincident triggers coinc_trig_paths = sorted(glob.glob('output/coinc*.xml.gz')) n_coincs = len(coinc_trig_paths) if n_coincs == 0: log.error('No coincident triggers detected') coinc_fail = True elif n_coincs >= 10: log.error('Too many coincident triggers detected') coinc_fail = True else: log.info('%d coincident trigger(s) detected', n_coincs) injs = sorted(glob.glob('test_inj*.hdf')) n_injs = len(injs) inj_mass1 = np.empty(n_injs) inj_mass2 = np.empty(n_injs) inj_spin1z = np.empty(n_injs) inj_spin2z = np.empty(n_injs) inj_time = np.empty(n_injs) for idx, inj_path in enumerate(injs): with h5py.File(inj_path, 'r') as inj: inj_mass1[idx] = inj['mass1'][0] inj_mass2[idx] = inj['mass2'][0] inj_spin1z[idx] = inj['spin1z'][0] inj_spin2z[idx] = inj['spin2z'][0] inj_time[idx] = inj['tc'][0] if n_injs > n_coincs: log.error('More injections than coincident triggers') coinc_fail = True # create field array to store properties of triggers dtype = [('mass1', float), ('mass2', float), ('spin1z', float), ('spin2z', float), ('tc', float), ('net_snr', float)] trig_props = FieldArray(n_coincs, dtype=dtype) # store properties of coincident triggers for x, ctrigfp in enumerate(coinc_trig_paths): log.info('Checking trigger %s', ctrigfp) xmldoc = ligolw_utils.load_filename( ctrigfp, False, contenthandler=LIGOLWContentHandler) sngl_inspiral_table = lsctables.SnglInspiralTable.get_table(xmldoc) trig_props['tc'][x] = sngl_inspiral_table.get_column('end_time')[0] trig_props['mass1'][x] = sngl_inspiral_table.get_column('mass1')[0] trig_props['mass2'][x] = sngl_inspiral_table.get_column('mass2')[0] trig_props['spin1z'][x] = sngl_inspiral_table.get_column('spin1z')[0] trig_props['spin2z'][x] = sngl_inspiral_table.get_column('spin2z')[0] snr_list = sngl_inspiral_table.get_column('snr') trig_props['net_snr'][x] = sum(snr_list**2)**0.5 log.info('IFO SNRs: %s', snr_list) log.info('Network SNR: %f', trig_props['net_snr'][x]) log.info('IFO End Time: %f', trig_props['tc'][x]) log.info('Mass 1: %f', trig_props['mass1'][x]) log.info('Mass 2: %f', trig_props['mass2'][x]) log.info('Spin1z: %f', trig_props['spin1z'][x]) log.info('Spin2z: %f', trig_props['spin2z'][x]) # check if injections match trigger params for i in range(n_injs): has_match = False for j in range(n_coincs): if (close(inj_time[i], trig_props['tc'][j], 1.0) and close(inj_mass1[i], trig_props['mass1'][j], 5e-7) and close(inj_mass2[i], trig_props['mass2'][j], 5e-7) and close(inj_spin1z[i], trig_props['spin1z'][j], 5e-7) and close(inj_spin2z[i], trig_props['spin2z'][j], 5e-7) and close(15.0, trig_props['net_snr'][j], 1.0)): has_match = True break if not has_match: coinc_fail = True log.error('Injection %i has no match', i) if coinc_fail: log.error('Coincident Trigger Test Failed') return coinc_fail
def __init__( self, tcs, freqs, amps, taus, ras, decs, psis=0.0, phis=0.0, inclinations=np.pi / 2.0, detector=None, starttime=1000000000, duration=1.0, deltat=1 / 8192, psd=aLIGOZeroDetHighPower, asd=None, flow=20.0, ): # get the number of injections (use injection times, tcs) if isinstance(tcs, float): tcs = np.asarray([tcs]) self.ninj = len(tcs) # set up a FieldArray to contain required ring-down parameters self.__injections = FieldArray( self.ninj, dtype=[ ("approximant", "S20"), ("f_220", "<f8"), ("lmns", "S3"), ("tau_220", "<f8"), ("amp220", "<f8"), ("phi220", "<f8"), ("polarization", "<f8"), ("inclination", "<f8"), ("ra", "<f8"), ("dec", "<f8"), ("tc", "<f8"), ], ) pnames = [ "f_220", "tau_220", "amp220", "phi220", "ra", "dec", "inclination", "polarization", "tc", ] for param, pvalue in zip( pnames, [freqs, taus, amps, phis, ras, decs, inclinations, psis, tcs], ): if isinstance(pvalue, float): self.__injections[param] = np.full(self.ninj, pvalue) elif isinstance(pvalue, (list, np.ndarray)): if len(pvalue) != self.ninj: raise ValueError( "{} must have the same number of entries as 'tc'".format(param) ) self.__injections[param] = pvalue else: raise TypeError("Input must be a float or list") # the PyCBC "TdQNMfromFreqTau" approximant creates time-domain ring-down signals self.__injections["approximant"] = np.full(self.ninj, "TdQNMfromFreqTau") self.__injections["lmns"] = np.full( self.ninj, "221" ) # use 1 22 mode (the 220 mode) # create the injections self.create_injections() # create the simulated data if requested if detector is not None: self.create_data( detector, starttime, duration, deltat, psd, asd=asd, flow=flow ) # inject signal(s) into the data self.inject()
dtype = [('mass1', float), ('mass2', float), ('spin1z', float), ('spin2z', float), ('tc', float), ('distance', float), ('ra', float), ('dec', float), ('approximant', 'S32')] static_params = {'f_lower': 17., 'f_ref': 17., 'taper': 'start', 'inclination': 0., 'coa_phase': 0., 'polarization': 0.} samples = FieldArray(2, dtype=dtype) # masses and spins are intended to match the highest # and lowest mass templates in the template bank samples['mass1'] = [290.929321, 1.1331687] samples['mass2'] = [3.6755455, 1.010624] samples['spin1z'] = [0.9934847, 0.029544285] samples['spin2z'] = [0.92713535, 0.020993788] # distance and sky locations to have network SNRs ~15 samples['tc'] = [1272790100.1, 1272790260.1] samples['distance'] = [178., 79.] samples['ra'] = [np.deg2rad(45), np.deg2rad(10)] samples['dec'] = [np.deg2rad(45), np.deg2rad(-45)] samples['approximant'] = ['SEOBNRv4_opt', 'SpinTaylorT4']
def check_coinc_results(args): coinc_fail = False # read injections with h5py.File(args.injections, 'r') as injfile: inj_mass1 = injfile['mass1'][:] inj_mass2 = injfile['mass2'][:] inj_spin1z = injfile['spin1z'][:] inj_spin2z = injfile['spin2z'][:] inj_time = injfile['tc'][:] # gather coincident triggers coinc_trig_paths = sorted(glob.glob('output/coinc*.xml.gz')) n_coincs = len(coinc_trig_paths) if n_coincs == 0: log.error('No coincident triggers detected') coinc_fail = True elif n_coincs >= 10: log.error('Too many coincident triggers detected') coinc_fail = True else: log.info('%d coincident trigger(s) detected', n_coincs) # create field array to store properties of triggers dtype = [('mass1', float), ('mass2', float), ('spin1z', float), ('spin2z', float), ('tc', float), ('net_snr', float)] trig_props = FieldArray(n_coincs, dtype=dtype) # store properties of coincident triggers for x, ctrigfp in enumerate(coinc_trig_paths): log.info('Checking trigger %s', ctrigfp) xmldoc = load_xml_doc( ctrigfp, False, contenthandler=LIGOLWContentHandler) si_table = lsctables.SnglInspiralTable.get_table(xmldoc) trig_props['tc'][x] = si_table[0].end trig_props['mass1'][x] = si_table[0].mass1 trig_props['mass2'][x] = si_table[0].mass2 trig_props['spin1z'][x] = si_table[0].spin1z trig_props['spin2z'][x] = si_table[0].spin2z snr_list = si_table.getColumnByName('snr').asarray() trig_props['net_snr'][x] = sum(snr_list ** 2) ** 0.5 log.info('Single-detector SNRs: %s', snr_list) log.info('Network SNR: %f', trig_props['net_snr'][x]) log.info('Merger time: %f', trig_props['tc'][x]) log.info('Mass 1: %f', trig_props['mass1'][x]) log.info('Mass 2: %f', trig_props['mass2'][x]) log.info('Spin1z: %f', trig_props['spin1z'][x]) log.info('Spin2z: %f', trig_props['spin2z'][x]) # check if injections match trigger params for i in range(len(inj_mass1)): has_match = False for j in range(n_coincs): # FIXME should calculate the optimal SNRs of the injections # and use those for checking net_snr if (close(inj_time[i], trig_props['tc'][j], 1.0) and close(inj_mass1[i], trig_props['mass1'][j], 1e-5) and close(inj_mass2[i], trig_props['mass2'][j], 1e-5) and close(inj_spin1z[i], trig_props['spin1z'][j], 1e-5) and close(inj_spin2z[i], trig_props['spin2z'][j], 1e-5) and close(15.0, trig_props['net_snr'][j], 2.0)): has_match = True break if not has_match: coinc_fail = True log.error('Injection %i was missed', i) if coinc_fail: log.error('Coincident Trigger Test Failed') return coinc_fail