def tosegmentxml(file, segs): """ Write the glue.segments.segmentlist object segs to file object file in xml format with appropriate tables. """ # generate empty document xmldoc = ligolw.Document() xmldoc.appendChild(ligolw.LIGO_LW()) xmldoc.childNodes[-1].appendChild(lsctables.New(lsctables.ProcessTable)) xmldoc.childNodes[-1].appendChild( lsctables.New(lsctables.ProcessParamsTable)) # append process to table process = ligolw_process.append_process(xmldoc,\ program='pylal.dq.dqSegmentUtils',\ version=__version__,\ cvs_repository='lscsoft',\ cvs_entry_time=__date__) gpssegs = segments.segmentlist() for seg in segs: gpssegs.append( segments.segment(LIGOTimeGPS(seg[0]), LIGOTimeGPS(seg[1]))) # append segs and seg definer segments_tables = ligolw_segments.LigolwSegments(xmldoc) segments_tables.add(ligolw_segments.LigolwSegmentList(active=gpssegs)) # finalise segments_tables.coalesce() segments_tables.optimize() segments_tables.finalize(process) ligolw_process.set_process_end_time(process) # write file with utils.SignalsTrap(): utils.write_fileobj(xmldoc, file, gz=False)
epoch = sngl_inspiral.end - (len(snr) - 1) / sample_rate snr = np.concatenate((snr[:0:-1].conj(), snr)) snr *= sngl_inspiral.snr * np.exp(1j * sngl_inspiral.coa_phase) snr_series = lal.CreateCOMPLEX16TimeSeries('snr', epoch, 0, dt, lal.StrainUnit, len(snr)) snr_series.data.data[:] = snr elem = lal.series.build_COMPLEX16TimeSeries(snr_series) elem.appendChild( ligolw_param.Param.from_pyvalue(u'event_id', sngl_inspiral.event_id)) out_xmldoc.childNodes[0].appendChild(elem) # Add CoincMap entry. coinc_map = lsctables.CoincMap() coinc_map.coinc_event_id = coinc.coinc_event_id coinc_map.table_name = sngl_inspiral_table.tableName coinc_map.event_id = sngl_inspiral.event_id coinc_map_table.append(coinc_map) # Record process end time. progress.update(-1, 'writing ' + opts.output.name) ligolw_process.set_process_end_time(process) # Write output file. with ligolw_utils.SignalsTrap(): ligolw_utils.write_fileobj(out_xmldoc, opts.output, gz=(os.path.splitext( opts.output.name)[-1] == ".gz"))
def main(args=None): p = parser() opts = p.parse_args(args) # LIGO-LW XML imports. from glue.ligolw import ligolw from glue.ligolw.param import Param from glue.ligolw.utils import process as ligolw_process from glue.ligolw.utils.search_summary import append_search_summary from glue.ligolw import utils as ligolw_utils from glue.ligolw.lsctables import ( New, CoincDefTable, CoincID, CoincInspiralTable, CoincMapTable, CoincTable, ProcessParamsTable, ProcessTable, SimInspiralTable, SnglInspiralTable, TimeSlideTable) # glue, LAL and pylal imports. from ligo import segments import glue.lal import lal.series import lalsimulation from lalinspiral.inspinjfind import InspiralSCExactCoincDef from lalinspiral.thinca import InspiralCoincDef from tqdm import tqdm # FIXME: disable progress bar monitor thread. # # I was getting error messages that look like this: # # Traceback (most recent call last): # File "/tqdm/_tqdm.py", line 885, in __del__ # self.close() # File "/tqdm/_tqdm.py", line 1090, in close # self._decr_instances(self) # File "/tqdm/_tqdm.py", line 454, in _decr_instances # cls.monitor.exit() # File "/tqdm/_monitor.py", line 52, in exit # self.join() # File "/usr/lib64/python3.6/threading.py", line 1053, in join # raise RuntimeError("cannot join current thread") # RuntimeError: cannot join current thread # # I don't know what causes this... maybe a race condition in tqdm's cleanup # code. Anyway, this should disable the tqdm monitor thread entirely. tqdm.monitor_interval = 0 # BAYESTAR imports. from ..io.events.ligolw import ContentHandler from ..bayestar import filter # Read PSDs. xmldoc, _ = ligolw_utils.load_fileobj( opts.reference_psd, contenthandler=lal.series.PSDContentHandler) psds = lal.series.read_psd_xmldoc(xmldoc, root_name=None) psds = { key: filter.InterpolatedPSD(filter.abscissa(psd), psd.data.data) for key, psd in psds.items() if psd is not None} psds = [psds[ifo] for ifo in opts.detector] # Extract simulation table from injection file. inj_xmldoc, _ = ligolw_utils.load_fileobj( opts.input, contenthandler=ContentHandler) orig_sim_inspiral_table = SimInspiralTable.get_table(inj_xmldoc) # Prune injections that are outside distance limits. orig_sim_inspiral_table[:] = [ row for row in orig_sim_inspiral_table if opts.min_distance <= row.distance <= opts.max_distance] # Open output file. xmldoc = ligolw.Document() xmlroot = xmldoc.appendChild(ligolw.LIGO_LW()) # Create tables. Process and ProcessParams tables are copied from the # injection file. coinc_def_table = xmlroot.appendChild(New(CoincDefTable)) coinc_inspiral_table = xmlroot.appendChild(New(CoincInspiralTable)) coinc_map_table = xmlroot.appendChild(New(CoincMapTable)) coinc_table = xmlroot.appendChild(New(CoincTable)) xmlroot.appendChild(ProcessParamsTable.get_table(inj_xmldoc)) xmlroot.appendChild(ProcessTable.get_table(inj_xmldoc)) sim_inspiral_table = xmlroot.appendChild(New(SimInspiralTable)) sngl_inspiral_table = xmlroot.appendChild(New(SnglInspiralTable)) time_slide_table = xmlroot.appendChild(New(TimeSlideTable)) # Write process metadata to output file. process = register_to_xmldoc( xmldoc, p, opts, ifos=opts.detector, comment="Simulated coincidences") # Add search summary to output file. all_time = segments.segment( [glue.lal.LIGOTimeGPS(0), glue.lal.LIGOTimeGPS(2e9)]) append_search_summary(xmldoc, process, inseg=all_time, outseg=all_time) # Create a time slide entry. Needed for coinc_event rows. time_slide_id = time_slide_table.get_time_slide_id( {ifo: 0 for ifo in opts.detector}, create_new=process) # Populate CoincDef table. inspiral_coinc_def = copy.copy(InspiralCoincDef) inspiral_coinc_def.coinc_def_id = coinc_def_table.get_next_id() coinc_def_table.append(inspiral_coinc_def) found_coinc_def = copy.copy(InspiralSCExactCoincDef) found_coinc_def.coinc_def_id = coinc_def_table.get_next_id() coinc_def_table.append(found_coinc_def) # Precompute values that are common to all simulations. detectors = [lalsimulation.DetectorPrefixToLALDetector(ifo) for ifo in opts.detector] responses = [det.response for det in detectors] locations = [det.location for det in detectors] if opts.jobs == 1: pool_map = map else: from .. import omp from multiprocessing import Pool omp.num_threads = 1 # disable OpenMP parallelism pool_map = Pool(opts.jobs).imap func = functools.partial(simulate, psds=psds, responses=responses, locations=locations, measurement_error=opts.measurement_error, f_low=opts.f_low, waveform=opts.waveform) # Make sure that each thread gets a different random number state. # We start by drawing a random integer s in the main thread, and # then the i'th subprocess will seed itself with the integer i + s. # # The seed must be an unsigned 32-bit integer, so if there are n # threads, then s must be drawn from the interval [0, 2**32 - n). # # Note that *we* are thread 0, so there are a total of # n=1+len(sim_inspiral_table) threads. seed = np.random.randint(0, 2 ** 32 - len(sim_inspiral_table) - 1) np.random.seed(seed) count_coincs = 0 with tqdm(total=len(orig_sim_inspiral_table)) as progress: for sim_inspiral, simulation in zip( orig_sim_inspiral_table, pool_map(func, zip(np.arange(len(orig_sim_inspiral_table)) + seed + 1, orig_sim_inspiral_table))): progress.update() sngl_inspirals = [] used_snr_series = [] net_snr = 0.0 count_triggers = 0 # Loop over individual detectors and create SnglInspiral entries. for ifo, (horizon, abs_snr, arg_snr, toa, series) \ in zip(opts.detector, simulation): if np.random.uniform() > opts.duty_cycle: continue elif abs_snr >= opts.snr_threshold: # If SNR < threshold, then the injection is not found. # Skip it. count_triggers += 1 net_snr += np.square(abs_snr) elif not opts.keep_subthreshold: continue # Create SnglInspiral entry. used_snr_series.append(series) sngl_inspirals.append( sngl_inspiral_table.RowType(**dict( dict.fromkeys(sngl_inspiral_table.validcolumns, None), process_id=process.process_id, ifo=ifo, mass1=sim_inspiral.mass1, mass2=sim_inspiral.mass2, spin1x=sim_inspiral.spin1x, spin1y=sim_inspiral.spin1y, spin1z=sim_inspiral.spin1z, spin2x=sim_inspiral.spin2x, spin2y=sim_inspiral.spin2y, spin2z=sim_inspiral.spin2z, end=toa, snr=abs_snr, coa_phase=arg_snr, eff_distance=horizon / abs_snr))) net_snr = np.sqrt(net_snr) # If too few triggers were found, then skip this event. if count_triggers < opts.min_triggers: continue # If network SNR < threshold, then the injection is not found. # Skip it. if net_snr < opts.net_snr_threshold: continue # Add Coinc table entry. coinc = coinc_table.appendRow( coinc_event_id=coinc_table.get_next_id(), process_id=process.process_id, coinc_def_id=inspiral_coinc_def.coinc_def_id, time_slide_id=time_slide_id, insts=opts.detector, nevents=len(opts.detector), likelihood=None) # Add CoincInspiral table entry. coinc_inspiral_table.appendRow( coinc_event_id=coinc.coinc_event_id, instruments=[ sngl_inspiral.ifo for sngl_inspiral in sngl_inspirals], end=lal.LIGOTimeGPS(1e-9 * np.mean([ sngl_inspiral.end.ns() for sngl_inspiral in sngl_inspirals if sngl_inspiral.end is not None])), mass=sim_inspiral.mass1 + sim_inspiral.mass2, mchirp=sim_inspiral.mchirp, combined_far=0.0, # Not provided false_alarm_rate=0.0, # Not provided minimum_duration=None, # Not provided snr=net_snr) # Record all sngl_inspiral records and associate them with coincs. for sngl_inspiral, series in zip(sngl_inspirals, used_snr_series): # Give this sngl_inspiral record an id and add it to the table. sngl_inspiral.event_id = sngl_inspiral_table.get_next_id() sngl_inspiral_table.append(sngl_inspiral) if opts.enable_snr_series: elem = lal.series.build_COMPLEX8TimeSeries(series) elem.appendChild( Param.from_pyvalue(u'event_id', sngl_inspiral.event_id)) xmlroot.appendChild(elem) # Add CoincMap entry. coinc_map_table.appendRow( coinc_event_id=coinc.coinc_event_id, table_name=sngl_inspiral_table.tableName, event_id=sngl_inspiral.event_id) # Record injection if not opts.preserve_ids: sim_inspiral.simulation_id = sim_inspiral_table.get_next_id() sim_inspiral_table.append(sim_inspiral) count_coincs += 1 progress.set_postfix(saved=count_coincs) # Record coincidence associating injections with events. for i, sim_inspiral in enumerate(sim_inspiral_table): coinc = coinc_table.appendRow( coinc_event_id=coinc_table.get_next_id(), process_id=process.process_id, coinc_def_id=found_coinc_def.coinc_def_id, time_slide_id=time_slide_id, instruments=None, nevents=None, likelihood=None) coinc_map_table.appendRow( coinc_event_id=coinc.coinc_event_id, table_name=sim_inspiral_table.tableName, event_id=sim_inspiral.simulation_id) coinc_map_table.appendRow( coinc_event_id=coinc.coinc_event_id, table_name=coinc_table.tableName, event_id=CoincID(i)) # Record process end time. ligolw_process.set_process_end_time(process) # Write output file. with ligolw_utils.SignalsTrap(): ligolw_utils.write_fileobj( xmldoc, opts.output, gz=(os.path.splitext(opts.output.name)[-1] == ".gz"))