def __getitem__(self, coinc_event_id): newxmldoc = ligolw.Document() ligolw_elem = newxmldoc.appendChild(ligolw.LIGO_LW()) # when making these, we can't use .copy() method of Table # instances because we need to ensure we have a Table # subclass, not a DBTable subclass new_process_table = ligolw_elem.appendChild(lsctables.New(lsctables.ProcessTable, self.process_table.columnnamesreal)) new_process_params_table = ligolw_elem.appendChild(lsctables.New(lsctables.ProcessParamsTable, self.process_params_table.columnnamesreal)) new_sngl_inspiral_table = ligolw_elem.appendChild(lsctables.New(lsctables.SnglInspiralTable, self.sngl_inspiral_table.columnnamesreal)) new_coinc_def_table = ligolw_elem.appendChild(lsctables.New(lsctables.CoincDefTable, self.coinc_def_table.columnnamesreal)) new_coinc_event_table = ligolw_elem.appendChild(lsctables.New(lsctables.CoincTable, self.coinc_event_table.columnnamesreal)) new_coinc_inspiral_table = ligolw_elem.appendChild(lsctables.New(lsctables.CoincInspiralTable, self.coinc_inspiral_table.columnnamesreal)) new_coinc_event_map_table = ligolw_elem.appendChild(lsctables.New(lsctables.CoincMapTable, self.coinc_event_map_table.columnnamesreal)) new_time_slide_table = ligolw_elem.appendChild(lsctables.New(lsctables.TimeSlideTable, self.time_slide_table.columnnamesreal)) new_coinc_def_table.append(self.coinc_def) coincevent = self.coinc_event_index[coinc_event_id] new_time_slide_table.extend(self.time_slide_index[coincevent.time_slide_id]) new_sngl_inspiral_table.extend(self.sngl_inspiral_index[coinc_event_id]) new_coinc_event_table.append(coincevent) new_coinc_event_map_table.extend(self.coinc_event_maps_index[coinc_event_id]) new_coinc_inspiral_table.append(self.coinc_inspiral_index[coinc_event_id]) for process_id in set(new_sngl_inspiral_table.getColumnByName("process_id")) | set(new_coinc_event_table.getColumnByName("process_id")) | set(new_time_slide_table.getColumnByName("process_id")): # process row is required new_process_table.append(self.process_index[process_id]) try: new_process_params_table.extend(self.process_params_index[process_id]) except KeyError: # process_params rows are optional pass return newxmldoc
def load_injections(inj_file, vetoes, sim_table=False, label=None): """Loads injections from PyGRB output file""" if label is None: logging.info("Loading injections...") else: logging.info("Loading %s...", label) insp_table = glsctables.MultiInspiralTable if sim_table: insp_table = glsctables.SimInspiralTable # Load injections in injection file inj_table = load_xml_table(inj_file, insp_table.tableName) # Extract injections in time-slid non-vetoed data injs = lsctables.New(insp_table, columns=insp_table.loadcolumns) injs.extend(inj for inj in inj_table if inj.get_end() not in vetoes) if label is None: logging.info("%d injections found.", len(injs)) else: logging.info("%d %s found.", len(injs), label) return injs
def table_to_ligolw(table, tablename): """Convert a `astropy.table.Table` to a :class:`ligo.lw.table.Table` """ from ligo.lw import lsctables # create new LIGO_LW table columns = table.columns.keys() cls = lsctables.TableByName[tablename] llwcolumns = list(columns) for col, llwcols in _get_property_columns(cls, columns).items(): idx = llwcolumns.index(col) llwcolumns.pop(idx) for name in llwcols[::-1]: llwcolumns.insert(idx, name) llwtable = lsctables.New(cls, columns=llwcolumns) # map rows across for row in table: llwrow = llwtable.RowType() for name in columns: setattr(llwrow, name, to_ligolw_table_type(row[name], llwtable, name)) llwtable.append(llwrow) return llwtable
def load_triggers(trig_file, vetoes, ifos): """"Loads triggers from PyGRB output file""" logging.info("Loading triggers...") # Extract time-slides multis, slide_dict, _ = \ MultiInspiralUtils.ReadMultiInspiralTimeSlidesFromFiles([trig_file]) num_slides = len(slide_dict) lsctables.MultiInspiralTable.loadcolumns =\ [slot for slot in multis[0].__slots__ if hasattr(multis[0], slot)] # Extract triggers trigs = lsctables.New(lsctables.MultiInspiralTable, columns=lsctables.MultiInspiralTable.loadcolumns) logging.info("%d triggers found.", len(trigs)) # Time-slid vetoes for slide_id in range(num_slides): slid_vetoes = copy.deepcopy(vetoes) for ifo in ifos: slid_vetoes[ifo].shift(-slide_dict[slide_id][ifo]) # Add time-slid triggers vets = slid_vetoes.union(slid_vetoes.keys()) trigs.extend(t for t in multis.veto(vets) if int(t.time_slide_id) == slide_id) logging.info("%d triggers found when including timeslides.", len(trigs)) return trigs
def __init__(self, xmldoc): super(ExcessPowerCoincTables, self).__init__(xmldoc) # find the multi_burst table or create one if not found try: self.multibursttable = lsctables.MultiBurstTable.get_table(xmldoc) except ValueError: self.multibursttable = lsctables.New( lsctables.MultiBurstTable, ("process_id", "duration", "central_freq", "bandwidth", "snr", "confidence", "amplitude", "coinc_event_id")) xmldoc.childNodes[0].appendChild(self.multibursttable)
def new_table(tablename, data=None, **new_kw): from ligo.lw import lsctables from ligo.lw.table import Table table = lsctables.New(lsctables.TableByName[Table.TableName(tablename)], **new_kw) for dat in data or list(): row = table.RowType() for key, val in dat.items(): setattr(row, key, val) table.append(row) return table
def __init__(self, xmldoc, coinc_definer_row): super(InspiralCoincTables, self).__init__(xmldoc, coinc_definer_row) # # find the coinc_inspiral table or create one if not found # try: self.coinc_inspiral_table = lsctables.CoincInspiralTable.get_table(xmldoc) except ValueError: self.coinc_inspiral_table = lsctables.New(lsctables.CoincInspiralTable) xmldoc.childNodes[0].appendChild(self.coinc_inspiral_table)
def new_doc(comment=None, **kwargs): doc = ligolw.Document() doc.appendChild(ligolw.LIGO_LW()) process = ligolw_process.register_to_xmldoc( doc, program=u"lalapps_gen_timeslides", paramdict=kwargs, version=__version__, cvs_repository=u"lscsoft", cvs_entry_time=__date__, comment=comment) doc.childNodes[0].appendChild(lsctables.New(lsctables.TimeSlideTable)) return doc, process
def table_to_ligolw(table, tablename): """Convert a `astropy.table.Table` to a :class:`ligo.lw.table.Table` """ from ligo.lw import lsctables # -- work out columns for LIGO_LW table # this is overly complicated because of the way that we magically # map properties of ligo.lw.table.Table objects to real columns in # astropy.table.Table objects, but also because ligo.lw internally # combines table names and column names for some columns # (e.g. process:process_id) columns = table.columns.keys() cls = lsctables.TableByName[tablename] inst = lsctables.New(cls) try: columnnamesreal = dict(zip(inst.columnnames, inst.columnnamesreal)) except AttributeError: # glue doesn't have these attributes columnnamesreal = {} llwcolumns = [columnnamesreal.get(n, n) for n in columns] for col, llwcols in _get_property_columns(cls, columns).items(): idx = llwcolumns.index(col) llwcolumns.pop(idx) for name in llwcols[::-1]: llwcolumns.insert(idx, name) # create new LIGO_LW table llwtable = lsctables.New(cls, columns=llwcolumns) # map rows across for row in table: llwrow = llwtable.RowType() for name in columns: setattr(llwrow, name, to_ligolw_table_type(row[name], llwtable, name)) llwtable.append(llwrow) return llwtable
def setUp(self): available_detectors = get_available_detectors() available_detectors = [a[0] for a in available_detectors] self.assertTrue('H1' in available_detectors) self.assertTrue('L1' in available_detectors) self.assertTrue('V1' in available_detectors) self.detectors = [Detector(d) for d in ['H1', 'L1', 'V1']] self.sample_rate = 4096. self.earth_time = lal.REARTH_SI / lal.C_SI # create a few random injections self.injections = [] start_time = float(lal.GPSTimeNow()) taper_choices = ('TAPER_NONE', 'TAPER_START', 'TAPER_END', 'TAPER_STARTEND') for i, taper in zip(range(20), itertools.cycle(taper_choices)): inj = MyInjection() inj.end_time = start_time + 40000 * i + \ numpy.random.normal(scale=3600) random = numpy.random.uniform inj.mass1 = random(low=1., high=20.) inj.mass2 = random(low=1., high=20.) inj.distance = random(low=0.9, high=1.1) * 1e6 * lal.PC_SI inj.latitude = numpy.arccos(random(low=-1, high=1)) inj.longitude = random(low=0, high=2 * lal.PI) inj.inclination = numpy.arccos(random(low=-1, high=1)) inj.polarization = random(low=0, high=2 * lal.PI) inj.taper = taper self.injections.append(inj) # create LIGOLW document xmldoc = ligolw.Document() xmldoc.appendChild(ligolw.LIGO_LW()) # create sim inspiral table, link it to document and fill it sim_table = lsctables.New(lsctables.SimInspiralTable) xmldoc.childNodes[-1].appendChild(sim_table) for i in range(len(self.injections)): row = sim_table.RowType() self.injections[i].fill_sim_inspiral_row(row) row.process_id = 0 row.simulation_id = i sim_table.append(row) # write document to temp file self.inj_file = tempfile.NamedTemporaryFile(suffix='.xml') ligolw_utils.write_fileobj(xmldoc, self.inj_file)
def load_injections(inj_file, vetoes): """"Loads injections from PyGRB output file""" logging.info("Loading injections...") # Load injection file xml_doc = load_xml_file(inj_file) multis = lsctables.MultiInspiralTable.get_table(xml_doc) # Extract injections injs = lsctables.New(lsctables.MultiInspiralTable, columns=lsctables.MultiInspiralTable.loadcolumns) # Injections in time-slid non-vetoed data injs.extend(t for t in multis if t.get_end() not in vetoes) logging.info("%d injections found.", len(injs)) return injs
def write(filename, samples, write_params=None, static_args=None): """Writes the injection samples to the given xml. Parameters ---------- filename : str The name of the file to write to. samples : io.FieldArray FieldArray of parameters. write_params : list, optional Only write the given parameter names. All given names must be keys in ``samples``. Default is to write all parameters in ``samples``. static_args : dict, optional Dictionary mapping static parameter names to values. These are written to the ``attrs``. """ xmldoc = ligolw.Document() xmldoc.appendChild(ligolw.LIGO_LW()) simtable = lsctables.New(lsctables.SimInspiralTable) xmldoc.childNodes[0].appendChild(simtable) if static_args is None: static_args = {} if write_params is None: write_params = samples.fieldnames for ii in range(samples.size): sim = lsctables.SimInspiral() # initialize all elements to None for col in sim.__slots__: setattr(sim, col, None) for field in write_params: data = samples[ii][field] set_sim_data(sim, field, data) # set any static args for (field, value) in static_args.items(): set_sim_data(sim, field, value) simtable.append(sim) ligolw_utils.write_filename(xmldoc, filename, gz=filename.endswith('gz'))
def convert_to_sngl_inspiral_table(params, proc_id): ''' Convert a list of m1,m2,spin1z,spin2z values into a basic sngl_inspiral table with mass and spin parameters populated and event IDs assigned Parameters ----------- params : iterable Each entry in the params iterable should be a sequence of [mass1, mass2, spin1z, spin2z] in that order proc_id : int Process ID to add to each row of the sngl_inspiral table Returns ---------- SnglInspiralTable Bank of templates in SnglInspiralTable format ''' sngl_inspiral_table = lsctables.New(lsctables.SnglInspiralTable) col_names = ['mass1','mass2','spin1z','spin2z'] for values in params: tmplt = return_empty_sngl() tmplt.process_id = proc_id for colname, value in zip(col_names, values): setattr(tmplt, colname, value) tmplt.mtotal, tmplt.eta = pnutils.mass1_mass2_to_mtotal_eta( tmplt.mass1, tmplt.mass2) tmplt.mchirp, _ = pnutils.mass1_mass2_to_mchirp_eta( tmplt.mass1, tmplt.mass2) tmplt.template_duration = 0 # FIXME tmplt.event_id = sngl_inspiral_table.get_next_id() sngl_inspiral_table.append(tmplt) return sngl_inspiral_table
injections['coa_phase'] = samples['phi_orb'] injections['polarization'] = samples['polarization'] injections['spin1x'] = s1x injections['spin1y'] = s1y injections['spin1z'] = s1z injections['spin2x'] = s2x injections['spin2y'] = s2y injections['spin2z'] = s2z injections['amp_order'] = [opts.amporder for i in range(N)] injections['numrel_data'] = ["" for _ in range(N)] # Create a new XML document xmldoc = ligolw.Document() xmldoc.appendChild(ligolw.LIGO_LW()) proc = ligo.lw.utils.process.register_to_xmldoc(doc, sys.argv[0], {}) sim_table = lsctables.New(lsctables.SimInspiralTable) xmldoc.childNodes[0].appendChild(sim_table) # Add empty rows to the sim_inspiral table for inj in range(N): row = sim_table.RowType() for slot in row.__slots__: setattr(row, slot, 0) sim_table.append(row) # Fill in IDs for i, row in enumerate(sim_table): row.process_id = proc.process_id row.simulation_id = sim_table.get_next_id() # Fill rows
def output_sngl_inspiral_table(outputFile, tempBank, metricParams, ethincaParams, programName="", optDict = None, outdoc=None): """ Function that converts the information produced by the various PyCBC bank generation codes into a valid LIGOLW XML file containing a sngl_inspiral table and outputs to file. Parameters ----------- outputFile : string Name of the file that the bank will be written to tempBank : iterable Each entry in the tempBank iterable should be a sequence of [mass1,mass2,spin1z,spin2z] in that order. metricParams : metricParameters instance Structure holding all the options for construction of the metric and the eigenvalues, eigenvectors and covariance matrix needed to manipulate the space. ethincaParams: {ethincaParameters instance, None} Structure holding options relevant to the ethinca metric computation including the upper frequency cutoff to be used for filtering. NOTE: The computation is currently only valid for non-spinning systems and uses the TaylorF2 approximant. programName (key-word-argument) : string Name of the executable that has been run optDict (key-word argument) : dictionary Dictionary of the command line arguments passed to the program outdoc (key-word argument) : ligolw xml document If given add template bank to this representation of a xml document and write to disk. If not given create a new document. """ if optDict is None: optDict = {} if outdoc is None: outdoc = ligolw.Document() outdoc.appendChild(ligolw.LIGO_LW()) # get IFO to put in search summary table ifos = [] if 'channel_name' in optDict.keys(): if optDict['channel_name'] is not None: ifos = [optDict['channel_name'][0:2]] proc = create_process_table( outdoc, program_name=programName, detectors=ifos, options=optDict ) proc_id = proc.process_id sngl_inspiral_table = convert_to_sngl_inspiral_table(tempBank, proc_id) # Calculate Gamma components if needed if ethincaParams is not None: if ethincaParams.doEthinca: for sngl in sngl_inspiral_table: # Set tau_0 and tau_3 values needed for the calculation of # ethinca metric distances (sngl.tau0,sngl.tau3) = pnutils.mass1_mass2_to_tau0_tau3( sngl.mass1, sngl.mass2, metricParams.f0) fMax_theor, GammaVals = calculate_ethinca_metric_comps( metricParams, ethincaParams, sngl.mass1, sngl.mass2, spin1z=sngl.spin1z, spin2z=sngl.spin2z, full_ethinca=ethincaParams.full_ethinca) # assign the upper frequency cutoff and Gamma0-5 values sngl.f_final = fMax_theor for i in range(len(GammaVals)): setattr(sngl, "Gamma"+str(i), GammaVals[i]) # If Gamma metric components are not wanted, assign f_final from an # upper frequency cutoff specified in ethincaParams elif ethincaParams.cutoff is not None: for sngl in sngl_inspiral_table: sngl.f_final = pnutils.frequency_cutoff_from_name( ethincaParams.cutoff, sngl.mass1, sngl.mass2, sngl.spin1z, sngl.spin2z) # set per-template low-frequency cutoff if 'f_low_column' in optDict and 'f_low' in optDict and \ optDict['f_low_column'] is not None: for sngl in sngl_inspiral_table: setattr(sngl, optDict['f_low_column'], optDict['f_low']) outdoc.childNodes[0].appendChild(sngl_inspiral_table) # get times to put in search summary table start_time = 0 end_time = 0 if 'gps_start_time' in optDict.keys() and 'gps_end_time' in optDict.keys(): start_time = optDict['gps_start_time'] end_time = optDict['gps_end_time'] # make search summary table search_summary_table = lsctables.New(lsctables.SearchSummaryTable) search_summary = return_search_summary( start_time, end_time, len(sngl_inspiral_table), ifos ) search_summary_table.append(search_summary) outdoc.childNodes[0].appendChild(search_summary_table) # write the xml doc to disk ligolw_utils.write_filename(outdoc, outputFile)
def main(args=None): from ligo.lw import lsctables from ligo.lw import utils as ligolw_utils from ligo.lw import ligolw import lal.series from scipy import stats p = parser() args = p.parse_args(args) xmldoc = ligolw.Document() xmlroot = xmldoc.appendChild(ligolw.LIGO_LW()) process = register_to_xmldoc(xmldoc, p, args) gwcosmo = GWCosmo( cosmology.default_cosmology.get_cosmology_from_string(args.cosmology)) ns_mass_min = 1.0 ns_mass_max = 2.0 bh_mass_min = 5.0 bh_mass_max = 50.0 ns_astro_spin_min = -0.05 ns_astro_spin_max = +0.05 ns_astro_mass_dist = stats.norm(1.33, 0.09) ns_astro_spin_dist = stats.uniform(ns_astro_spin_min, ns_astro_spin_max - ns_astro_spin_min) ns_broad_spin_min = -0.4 ns_broad_spin_max = +0.4 ns_broad_mass_dist = stats.uniform(ns_mass_min, ns_mass_max - ns_mass_min) ns_broad_spin_dist = stats.uniform(ns_broad_spin_min, ns_broad_spin_max - ns_broad_spin_min) bh_astro_spin_min = -0.99 bh_astro_spin_max = +0.99 bh_astro_mass_dist = stats.pareto(b=1.3) bh_astro_spin_dist = stats.uniform(bh_astro_spin_min, bh_astro_spin_max - bh_astro_spin_min) bh_broad_spin_min = -0.99 bh_broad_spin_max = +0.99 bh_broad_mass_dist = stats.reciprocal(bh_mass_min, bh_mass_max) bh_broad_spin_dist = stats.uniform(bh_broad_spin_min, bh_broad_spin_max - bh_broad_spin_min) if args.distribution.startswith('bns_'): m1_min = m2_min = ns_mass_min m1_max = m2_max = ns_mass_max if args.distribution.endswith('_astro'): x1_min = x2_min = ns_astro_spin_min x1_max = x2_max = ns_astro_spin_max m1_dist = m2_dist = ns_astro_mass_dist x1_dist = x2_dist = ns_astro_spin_dist elif args.distribution.endswith('_broad'): x1_min = x2_min = ns_broad_spin_min x1_max = x2_max = ns_broad_spin_max m1_dist = m2_dist = ns_broad_mass_dist x1_dist = x2_dist = ns_broad_spin_dist else: # pragma: no cover assert_not_reached() elif args.distribution.startswith('nsbh_'): m1_min = bh_mass_min m1_max = bh_mass_max m2_min = ns_mass_min m2_max = ns_mass_max if args.distribution.endswith('_astro'): x1_min = bh_astro_spin_min x1_max = bh_astro_spin_max x2_min = ns_astro_spin_min x2_max = ns_astro_spin_max m1_dist = bh_astro_mass_dist m2_dist = ns_astro_mass_dist x1_dist = bh_astro_spin_dist x2_dist = ns_astro_spin_dist elif args.distribution.endswith('_broad'): x1_min = bh_broad_spin_min x1_max = bh_broad_spin_max x2_min = ns_broad_spin_min x2_max = ns_broad_spin_max m1_dist = bh_broad_mass_dist m2_dist = ns_broad_mass_dist x1_dist = bh_broad_spin_dist x2_dist = ns_broad_spin_dist else: # pragma: no cover assert_not_reached() elif args.distribution.startswith('bbh_'): m1_min = m2_min = bh_mass_min m1_max = m2_max = bh_mass_max if args.distribution.endswith('_astro'): x1_min = x2_min = bh_astro_spin_min x1_max = x2_max = bh_astro_spin_max m1_dist = m2_dist = bh_astro_mass_dist x1_dist = x2_dist = bh_astro_spin_dist elif args.distribution.endswith('_broad'): x1_min = x2_min = bh_broad_spin_min x1_max = x2_max = bh_broad_spin_max m1_dist = m2_dist = bh_broad_mass_dist x1_dist = x2_dist = bh_broad_spin_dist else: # pragma: no cover assert_not_reached() else: # pragma: no cover assert_not_reached() dists = (m1_dist, m2_dist, x1_dist, x2_dist) # Read PSDs psds = list( lal.series.read_psd_xmldoc( ligolw_utils.load_fileobj( args.reference_psd, contenthandler=lal.series.PSDContentHandler)).values()) # Construct mass1, mass2, spin1z, spin2z grid. m1 = np.geomspace(m1_min, m1_max, 10) m2 = np.geomspace(m2_min, m2_max, 10) x1 = np.linspace(x1_min, x1_max, 10) x2 = np.linspace(x2_min, x2_max, 10) params = m1, m2, x1, x2 # Calculate the maximum distance on the grid. max_z = gwcosmo.get_max_z(psds, args.waveform, args.f_low, args.min_snr, m1, m2, x1, x2, jobs=args.jobs) if args.max_distance is not None: new_max_z = cosmology.z_at_value(gwcosmo.cosmo.luminosity_distance, args.max_distance * units.Mpc) max_z[max_z > new_max_z] = new_max_z max_distance = gwcosmo.sensitive_distance(max_z).to_value(units.Mpc) # Find piecewise constant approximate upper bound on distance. max_distance = cell_max(max_distance) # Calculate V * T in each grid cell cdfs = [dist.cdf(param) for param, dist in zip(params, dists)] cdf_los = [cdf[:-1] for cdf in cdfs] cdfs = [np.diff(cdf) for cdf in cdfs] probs = np.prod(np.meshgrid(*cdfs, indexing='ij'), axis=0) probs /= probs.sum() probs *= 4 / 3 * np.pi * max_distance**3 volume = probs.sum() probs /= volume probs = probs.ravel() volumetric_rate = args.nsamples / volume * units.year**-1 * units.Mpc**-3 # Draw random grid cells dist = stats.rv_discrete(values=(np.arange(len(probs)), probs)) indices = np.unravel_index(dist.rvs(size=args.nsamples), max_distance.shape) # Draw random intrinsic params from each cell cols = {} cols['mass1'], cols['mass2'], cols['spin1z'], cols['spin2z'] = [ dist.ppf(stats.uniform(cdf_lo[i], cdf[i]).rvs(size=args.nsamples)) for i, dist, cdf_lo, cdf in zip(indices, dists, cdf_los, cdfs) ] # Swap binary components as needed to ensure that mass1 >= mass2. # Note that the .copy() is important. # See https://github.com/numpy/numpy/issues/14428 swap = cols['mass1'] < cols['mass2'] cols['mass1'][swap], cols['mass2'][swap] = \ cols['mass2'][swap].copy(), cols['mass1'][swap].copy() cols['spin1z'][swap], cols['spin2z'][swap] = \ cols['spin2z'][swap].copy(), cols['spin1z'][swap].copy() # Draw random extrinsic parameters cols['distance'] = stats.powerlaw( a=3, scale=max_distance[indices]).rvs(size=args.nsamples) cols['longitude'] = stats.uniform(0, 2 * np.pi).rvs(size=args.nsamples) cols['latitude'] = np.arcsin(stats.uniform(-1, 2).rvs(size=args.nsamples)) cols['inclination'] = np.arccos( stats.uniform(-1, 2).rvs(size=args.nsamples)) cols['polarization'] = stats.uniform(0, 2 * np.pi).rvs(size=args.nsamples) cols['coa_phase'] = stats.uniform(-np.pi, 2 * np.pi).rvs(size=args.nsamples) cols['time_geocent'] = stats.uniform(1e9, units.year.to( units.second)).rvs(size=args.nsamples) # Convert from sensitive distance to redshift and comoving distance. # FIXME: Replace this brute-force lookup table with a solver. z = np.linspace(0, max_z.max(), 10000) ds = gwcosmo.sensitive_distance(z).to_value(units.Mpc) dc = gwcosmo.cosmo.comoving_distance(z).to_value(units.Mpc) z_for_ds = interp1d(ds, z, kind='cubic', assume_sorted=True) dc_for_ds = interp1d(ds, dc, kind='cubic', assume_sorted=True) zp1 = 1 + z_for_ds(cols['distance']) cols['distance'] = dc_for_ds(cols['distance']) # Apply redshift factor to convert from comoving distance and source frame # masses to luminosity distance and observer frame masses. for key in ['distance', 'mass1', 'mass2']: cols[key] *= zp1 # Populate sim_inspiral table sims = xmlroot.appendChild(lsctables.New(lsctables.SimInspiralTable)) for row in zip(*cols.values()): sims.appendRow(**dict(dict.fromkeys(sims.validcolumns, None), process_id=process.process_id, simulation_id=sims.get_next_id(), waveform=args.waveform, f_lower=args.f_low, **dict(zip(cols.keys(), row)))) # Record process end time. process.comment = str(volumetric_rate) process.set_end_time_now() # Write output file. write_fileobj(xmldoc, args.output)
def __init__(self, xmldoc, b_b_def, sb_b_def, si_b_def, sb_c_e_def, sb_c_n_def, si_c_e_def, si_c_n_def, process, livetime_program): # # store the process row # self.process = process # # locate the sngl_burst, time_slide and injection tables # self.snglbursttable = lsctables.SnglBurstTable.get_table(xmldoc) try: self.simbursttable = lsctables.SimBurstTable.get_table(xmldoc) except ValueError: self.simbursttable = None try: self.siminspiraltable = lsctables.SimInspiralTable.get_table( xmldoc) except ValueError: self.siminspiraltable = None try: timeslidetable = lsctables.TimeSlideTable.get_table(xmldoc) except ValueError: timeslidetable = None if timeslidetable is not None: self.offsetvectors = timeslidetable.as_dict() else: self.offsetvectors = {} # # store the longest duration of a burst event # if self.snglbursttable: self.longestduration = max( self.snglbursttable.getColumnByName("duration")) else: self.longestduration = 0.0 # # get a segmentlistdict indicating the times when the jobs # that produced burst events could have produced output # self.seglists = ligolw_search_summary.segmentlistdict_fromsearchsummary( xmldoc, livetime_program).coalesce() # # FIXME: in the future, the sim_inspiral table should # indicate time slide at which the injection was done, like # the sim_burst table does. for now, fake it by giving # each one a time_slide_id attribute. this is the only # reason why a place-holder class is required for the # SimInspiral row type; that class can be deleted when # this is no longer needed # if self.siminspiraltable is not None: time_slide_id = ligolw_time_slide.get_time_slide_id( xmldoc, {}.fromkeys(self.seglists, 0.0), create_new=process, superset_ok=True, nonunique_ok=False) for sim in self.siminspiraltable: sim.time_slide_id = time_slide_id # # get coinc_definer rows for sim_* <--> sngl_burst coincs # for whichever sim_* tables are present; this creates a # coinc_definer table if the document doesn't have one # if self.simbursttable is not None: self.sb_b_coinc_def_id = ligolw_coincs.get_coinc_def_id( xmldoc, sb_b_def.search, sb_b_def.search_coinc_type, create_new=True, description=sb_b_def.description) else: self.sb_b_coinc_def_id = None if self.siminspiraltable is not None: self.si_b_coinc_def_id = ligolw_coincs.get_coinc_def_id( xmldoc, si_b_def.search, si_b_def.search_coinc_type, create_new=True, description=si_b_def.description) else: self.si_b_coinc_def_id = None # # get coinc_def_id's for sngl_burst <--> sngl_burst, and # both kinds of sim_* <--> coinc_event coincs. set all to # None if this document does not contain any sngl_burst # <--> sngl_burst coincs. # try: b_b_coinc_def_id = ligolw_coincs.get_coinc_def_id( xmldoc, b_b_def.search, b_b_def.search_coinc_type, create_new=False) except KeyError: b_b_coinc_def_id = None self.sb_c_e_coinc_def_id = None self.sb_c_n_coinc_def_id = None self.si_c_e_coinc_def_id = None self.si_c_n_coinc_def_id = None else: if self.simbursttable is not None: self.sb_c_e_coinc_def_id = ligolw_coincs.get_coinc_def_id( xmldoc, sb_c_e_def.search, sb_c_e_def.search_coinc_type, create_new=True, description=sb_c_e_def.description) self.sb_c_n_coinc_def_id = ligolw_coincs.get_coinc_def_id( xmldoc, sb_c_n_def.search, sb_c_n_def.search_coinc_type, create_new=True, description=sb_c_n_def.description) else: self.sb_c_e_coinc_def_id = None self.sb_c_n_coinc_def_id = None if self.siminspiraltable is not None: self.si_c_e_coinc_def_id = ligolw_coincs.get_coinc_def_id( xmldoc, si_c_e_def.search, si_c_e_def.search_coinc_type, create_new=True, description=si_c_e_def.description) self.si_c_n_coinc_def_id = ligolw_coincs.get_coinc_def_id( xmldoc, si_c_n_def.search, si_c_n_def.search_coinc_type, create_new=True, description=si_c_n_def.description) else: self.si_c_e_coinc_def_id = None self.si_c_n_coinc_def_id = None # # get coinc table, create one if needed # try: self.coinctable = lsctables.CoincTable.get_table(xmldoc) except ValueError: self.coinctable = lsctables.New(lsctables.CoincTable) xmldoc.childNodes[0].appendChild(self.coinctable) self.coinctable.sync_next_id() # # get coinc_map table, create one if needed # try: self.coincmaptable = lsctables.CoincMapTable.get_table(xmldoc) except ValueError: self.coincmaptable = lsctables.New(lsctables.CoincMapTable) xmldoc.childNodes[0].appendChild(self.coincmaptable) # # index the document # # index sngl_burst table index = dict((row.event_id, row) for row in self.snglbursttable) # find IDs of burst<-->burst coincs self.coincs = dict((row.coinc_event_id, []) for row in self.coinctable if row.coinc_def_id == b_b_coinc_def_id) # construct event list for each burst<-->burst coinc for row in self.coincmaptable: try: self.coincs[row.coinc_event_id].append(index[row.event_id]) except KeyError: pass del index # sort the event list for each coin by peak time and # convert to tuples for speed for coinc_event_id, events in self.coincs.items(): events.sort(key=lambda event: event.peak) self.coincs[coinc_event_id] = tuple(events) # convert dictionary to a list of (coinc_event_id, events) # tuples and create a coinc_event_id to offset vector # look-up table self.coincs = self.coincs.items() self.coincoffsets = dict( (row.coinc_event_id, self.offsetvectors[row.time_slide_id]) for row in self.coinctable if row.coinc_def_id == b_b_coinc_def_id) # # represent the sngl_burst table as a dictionary indexed by # instrument whose values are the event lists for those # instruments sorted by peak time. sort the coincs list by # the peak time of the first (earliest) event in each coinc # (recall that the event tuple for each coinc has been # time-ordered) # self.snglbursttable = dict( (instrument, sorted((event for event in self.snglbursttable if event.ifo == instrument), key=lambda event: event.peak)) for instrument in set(self.snglbursttable.getColumnByName("ifo"))) self.coincs.sort( key=lambda coinc_id_events: coinc_id_events[1][0].peak)
def create_bank_xml(flow, fhigh, band, duration, level=0, ndof=1, frequency_overlap=0, detector=None, units=utils.EXCESSPOWER_UNIT_SCALE['Hz']): """ Create a bank of sngl_burst XML entries. This file is then used by the trigger generator to do trigger generation. Takes in the frequency parameters and filter duration and returns an ligolw entity with a sngl_burst Table which can be saved to a file. """ xmldoc = ligolw.Document() xmldoc.appendChild(ligolw.LIGO_LW()) bank = lsctables.New(lsctables.SnglBurstTable, [ "peak_time_ns", "start_time_ns", "stop_time_ns", "process_id", "ifo", "peak_time", "start_time", "stop_time", "duration", "time_lag", "peak_frequency", "search", "central_freq", "channel", "amplitude", "snr", "confidence", "chisq", "chisq_dof", "flow", "fhigh", "bandwidth", "tfvolume", "hrss", "event_id" ]) bank.sync_next_id() # The first frequency band actually begins at flow, so we offset the # central frequency accordingly if level == 0: # Hann windows edge = band / 2 cfreq = flow + band else: # Tukey windows edge = band / 2**(level + 1) # The sin^2 tapering comes from the Hann windows, so we need to know # how far they extend to account for the overlap at the ends cfreq = flow + edge + (band / 2) while cfreq + edge + band / 2 <= fhigh: row = bank.RowType() row.search = u"gstlal_excesspower" row.duration = duration * ndof row.bandwidth = band row.peak_frequency = cfreq row.central_freq = cfreq # This actually marks the 50 % overlap point row.flow = cfreq - band / 2.0 # This actually marks the 50 % overlap point row.fhigh = cfreq + band / 2.0 row.ifo = detector row.chisq_dof = 2 * band * row.duration row.duration *= units # Stuff that doesn't matter, yet row.peak_time_ns = 0 row.peak_time = 0 row.start_time_ns = 0 row.start_time = 0 row.stop_time_ns = 0 row.stop_time = 0 row.tfvolume = 0 row.time_lag = 0 row.amplitude = 0 row.hrss = 0 row.snr = 0 row.chisq = 0 row.confidence = 0 row.event_id = bank.get_next_id() row.channel = "awesome full of GW channel" row.process_id = ilwd.ilwdchar(u"process:process_id:0") bank.append(row) #cfreq += band #band is half the full width of the window, so this is 50% overlap cfreq += band * (1 - frequency_overlap) xmldoc.childNodes[0].appendChild(bank) return xmldoc
injections['q'] = q try: injections['hrss'] = samples['hrss'] except: injections['hrss'] = np.exp(samples['loghrss']) injections['ra'] = samples['ra'] injections['dec'] = samples['dec'] injections['psi'] = samples['psi'] # Create a new XML document xmldoc = ligolw.Document() xmldoc.appendChild(ligolw.LIGO_LW()) proc = ligo.lw.utils.process.register_to_xmldoc(doc, sys.argv[0], {}) #create timeslide table and set offsets to 0 timeslide_table = lsctables.New(lsctables.TimeSlideTable) timeslide_id = timeslide_table.append_offsetvector( { 'H1': 0, 'V1': 0, 'L1': 0, 'H2': 0 }, proc) sim_table = lsctables.New(lsctables.SimBurstTable) xmldoc.childNodes[0].appendChild(timeslide_table) xmldoc.childNodes[0].appendChild(sim_table) # Add empty rows to the sim_inspiral table for inj in range(N): row = sim_table.RowType()
def __init__(self, xmldoc, bbdef, sbdef, scedef, scndef, process, end_time_bisect_window): # # store the process row # self.process = process # # locate the sngl_inspiral and sim_inspiral tables # self.snglinspiraltable = lsctables.SnglInspiralTable.get_table(xmldoc) self.siminspiraltable = lsctables.SimInspiralTable.get_table(xmldoc) # # get the offset vectors from the document # self.offsetvectors = lsctables.TimeSlideTable.get_table(xmldoc).as_dict() # # construct the zero-lag time slide needed to cover the # instruments listed in all the triggers, then determine # its ID (or create it if needed) # # FIXME: in the future, the sim_inspiral table should # indicate time slide at which the injection was done # self.tisi_id = ligolw_time_slide.get_time_slide_id(xmldoc, {}.fromkeys(self.snglinspiraltable.getColumnByName("ifo"), 0.0), create_new = process, superset_ok = True, nonunique_ok = True) # # get coinc_definer row for sim_inspiral <--> sngl_inspiral # coincs; this creates a coinc_definer table if the # document doesn't have one # self.sb_coinc_def_id = ligolw_coincs.get_coinc_def_id(xmldoc, sbdef.search, sbdef.search_coinc_type, create_new = True, description = sbdef.description) # # get coinc_def_id's for sngl_inspiral <--> sngl_inspiral, and # both kinds of sim_inspiral <--> coinc_event coincs. set all # to None if this document does not contain any sngl_inspiral # <--> sngl_inspiral coincs. # try: ii_coinc_def_id = ligolw_coincs.get_coinc_def_id(xmldoc, bbdef.search, bbdef.search_coinc_type, create_new = False) except KeyError: ii_coinc_def_id = None self.sce_coinc_def_id = None self.scn_coinc_def_id = None else: self.sce_coinc_def_id = ligolw_coincs.get_coinc_def_id(xmldoc, scedef.search, scedef.search_coinc_type, create_new = True, description = scedef.description) self.scn_coinc_def_id = ligolw_coincs.get_coinc_def_id(xmldoc, scndef.search, scndef.search_coinc_type, create_new = True, description = scndef.description) # # get coinc table, create one if needed # try: self.coinctable = lsctables.CoincTable.get_table(xmldoc) except ValueError: self.coinctable = lsctables.New(lsctables.CoincTable) xmldoc.childNodes[0].appendChild(self.coinctable) self.coinctable.sync_next_id() # # get coinc_map table, create one if needed # try: self.coincmaptable = lsctables.CoincMapTable.get_table(xmldoc) except ValueError: self.coincmaptable = lsctables.New(lsctables.CoincMapTable) xmldoc.childNodes[0].appendChild(self.coincmaptable) # # index the document # # FIXME: inspiral<-->inspiral coincs should be organized by time # slide ID, but since injections are only done at zero lag # for now this is ignored. # # index the sngl_inspiral table index = dict((row.event_id, row) for row in self.snglinspiraltable) # find IDs of inspiral<-->inspiral coincs self.sngls = dict((row.coinc_event_id, []) for row in self.coinctable if row.coinc_def_id == ii_coinc_def_id) # construct event list for each inspiral<-->inspiral coinc for row in self.coincmaptable: try: self.sngls[row.coinc_event_id].append(index[row.event_id]) except KeyError: pass del index # construct a sngl-->coincs look-up table self.coincs = dict((event.event_id, set()) for events in self.sngls.values() for event in events) for row in self.coincmaptable: if row.event_id in self.coincs and row.coinc_event_id in self.sngls: self.coincs[row.event_id].add(row.coinc_event_id) # create a coinc_event_id to offset vector look-up table self.coincoffsets = dict((row.coinc_event_id, self.offsetvectors[row.time_slide_id]) for row in self.coinctable if row.coinc_def_id == ii_coinc_def_id) # # sort sngl_inspiral table by end time # self.snglinspiraltable.sort(key = lambda row: row.end) # # set the window for inspirals_near_endtime(). this window # is the amount of time such that if an injection's end # time and a inspiral event's end time differ by more than # this it is *impossible* for them to match one another. # self.end_time_bisect_window = lsctables.LIGOTimeGPS(end_time_bisect_window)
# try: lsctables.SimBurstTable.get_table(xmldoc) except ValueError: # no sim_burst table in document pass else: raise ValueError( "%s contains a sim_burst table. this program isn't smart enough to deal with that." % options.time_slide_xml) sim_burst_tbl = xmldoc.childNodes[-1].appendChild( lsctables.New(lsctables.SimBurstTable, [ "process:process_id", "simulation_id", "time_slide:time_slide_id", "waveform", "waveform_number", "ra", "dec", "psi", "time_geocent_gps", "time_geocent_gps_ns", "duration", "frequency", "bandwidth", "egw_over_rsquared", "pol_ellipse_angle", "pol_ellipse_e" ])) # # populate the sim_burst table with pixels # if options.verbose: print("time-frequency tiles have %g degrees of freedom" % (2. * options.delta_t * options.delta_f), file=sys.stderr) for n, filename in enumerate(filenames, 1): if options.verbose: print("%d/%d: loading %s ..." % (n, len(filenames), filename),
def make_exttrig_file(cp, ifos, sci_seg, out_dir): ''' Make an ExtTrig xml file containing information on the external trigger Parameters ---------- cp : pycbc.workflow.configuration.WorkflowConfigParser object The parsed configuration options of a pycbc.workflow.core.Workflow. ifos : str String containing the analysis interferometer IDs. sci_seg : ligo.segments.segment The science segment for the analysis run. out_dir : str The output directory, destination for xml file. Returns ------- xml_file : pycbc.workflow.File object The xml file with external trigger information. ''' # Initialise objects xmldoc = ligolw.Document() xmldoc.appendChild(ligolw.LIGO_LW()) tbl = lsctables.New(lsctables.ExtTriggersTable) cols = tbl.validcolumns xmldoc.childNodes[-1].appendChild(tbl) row = tbl.appendRow() # Add known attributes for this GRB setattr(row, "event_ra", float(cp.get("workflow", "ra"))) setattr(row, "event_dec", float(cp.get("workflow", "dec"))) setattr(row, "start_time", int(cp.get("workflow", "trigger-time"))) setattr(row, "event_number_grb", str(cp.get("workflow", "trigger-name"))) # Fill in all empty rows for entry in cols.keys(): if hasattr(row, entry): continue if cols[entry] in ['real_4', 'real_8']: setattr(row, entry, 0.) elif cols[entry] in ['int_4s', 'int_8s']: setattr(row, entry, 0) elif cols[entry] == 'lstring': setattr(row, entry, '') elif entry == 'process_id': row.process_id = 0 elif entry == 'event_id': row.event_id = 0 else: raise ValueError("Column %s not recognized" % entry) # Save file xml_file_name = "triggerGRB%s.xml" % str(cp.get("workflow", "trigger-name")) xml_file_path = os.path.join(out_dir, xml_file_name) utils.write_filename(xmldoc, xml_file_path) xml_file_url = urljoin("file:", pathname2url(xml_file_path)) xml_file = File(ifos, xml_file_name, sci_seg, file_url=xml_file_url) xml_file.add_pfn(xml_file_url, site="local") return xml_file
def __init__(self, ifos, coinc_results, **kwargs): """Initialize a ligolw xml representation of a zerolag trigger for upload from pycbc live to gracedb. Parameters ---------- ifos: list of strs A list of the ifos participating in this trigger. coinc_results: dict of values A dictionary of values. The format is defined in pycbc/events/coinc.py and matches the on disk representation in the hdf file for this time. psds: dict of FrequencySeries Dictionary providing PSD estimates for all involved detectors. low_frequency_cutoff: float Minimum valid frequency for the PSD estimates. high_frequency_cutoff: float, optional Maximum frequency considered for the PSD estimates. Default None. followup_data: dict of dicts, optional Dictionary providing SNR time series for each detector, to be used in sky localization with BAYESTAR. The format should be `followup_data['H1']['snr_series']`. More detectors can be present than given in `ifos`. If so, the extra detectors will only be used for sky localization. channel_names: dict of strings, optional Strain channel names for each detector. Will be recorded in the sngl_inspiral table. mc_area_args: dict of dicts, optional Dictionary providing arguments to be used in source probability estimation with pycbc/mchirp_area.py """ self.template_id = coinc_results['foreground/%s/template_id' % ifos[0]] self.coinc_results = coinc_results self.ifos = ifos # remember if this should be marked as HWINJ self.is_hardware_injection = ('HWINJ' in coinc_results and coinc_results['HWINJ']) # Check if we need to apply a time offset (this may be permerger) self.time_offset = 0 rtoff = 'foreground/{}/time_offset'.format(ifos[0]) if rtoff in coinc_results: self.time_offset = coinc_results[rtoff] if 'followup_data' in kwargs: fud = kwargs['followup_data'] assert len({fud[ifo]['snr_series'].delta_t for ifo in fud}) == 1, \ "delta_t for all ifos do not match" self.snr_series = {ifo: fud[ifo]['snr_series'] for ifo in fud} usable_ifos = fud.keys() followup_ifos = list(set(usable_ifos) - set(ifos)) for ifo in self.snr_series: self.snr_series[ifo].start_time += self.time_offset else: self.snr_series = None usable_ifos = ifos followup_ifos = [] # Set up the bare structure of the xml document outdoc = ligolw.Document() outdoc.appendChild(ligolw.LIGO_LW()) # FIXME is it safe (in terms of downstream operations) to let # `program_name` default to the actual script name? proc_id = create_process_table(outdoc, program_name='pycbc', detectors=usable_ifos).process_id # Set up coinc_definer table coinc_def_table = lsctables.New(lsctables.CoincDefTable) coinc_def_id = lsctables.CoincDefID(0) coinc_def_row = lsctables.CoincDef() coinc_def_row.search = "inspiral" coinc_def_row.description = "sngl_inspiral<-->sngl_inspiral coincs" coinc_def_row.coinc_def_id = coinc_def_id coinc_def_row.search_coinc_type = 0 coinc_def_table.append(coinc_def_row) outdoc.childNodes[0].appendChild(coinc_def_table) # Set up coinc inspiral and coinc event tables coinc_id = lsctables.CoincID(0) coinc_event_table = lsctables.New(lsctables.CoincTable) coinc_event_row = lsctables.Coinc() coinc_event_row.coinc_def_id = coinc_def_id coinc_event_row.nevents = len(usable_ifos) coinc_event_row.instruments = ','.join(usable_ifos) coinc_event_row.time_slide_id = lsctables.TimeSlideID(0) coinc_event_row.process_id = proc_id coinc_event_row.coinc_event_id = coinc_id coinc_event_row.likelihood = 0. coinc_event_table.append(coinc_event_row) outdoc.childNodes[0].appendChild(coinc_event_table) # Set up sngls sngl_inspiral_table = lsctables.New(lsctables.SnglInspiralTable) coinc_event_map_table = lsctables.New(lsctables.CoincMapTable) sngl_populated = None network_snrsq = 0 for sngl_id, ifo in enumerate(usable_ifos): sngl = return_empty_sngl(nones=True) sngl.event_id = lsctables.SnglInspiralID(sngl_id) sngl.process_id = proc_id sngl.ifo = ifo names = [ n.split('/')[-1] for n in coinc_results if 'foreground/%s' % ifo in n ] for name in names: val = coinc_results['foreground/%s/%s' % (ifo, name)] if name == 'end_time': val += self.time_offset sngl.end = lal.LIGOTimeGPS(val) else: try: setattr(sngl, name, val) except AttributeError: pass if sngl.mass1 and sngl.mass2: sngl.mtotal, sngl.eta = pnutils.mass1_mass2_to_mtotal_eta( sngl.mass1, sngl.mass2) sngl.mchirp, _ = pnutils.mass1_mass2_to_mchirp_eta( sngl.mass1, sngl.mass2) sngl_populated = sngl if sngl.snr: sngl.eff_distance = (sngl.sigmasq)**0.5 / sngl.snr network_snrsq += sngl.snr**2.0 if 'channel_names' in kwargs and ifo in kwargs['channel_names']: sngl.channel = kwargs['channel_names'][ifo] sngl_inspiral_table.append(sngl) # Set up coinc_map entry coinc_map_row = lsctables.CoincMap() coinc_map_row.table_name = 'sngl_inspiral' coinc_map_row.coinc_event_id = coinc_id coinc_map_row.event_id = sngl.event_id coinc_event_map_table.append(coinc_map_row) if self.snr_series is not None: snr_series_to_xml(self.snr_series[ifo], outdoc, sngl.event_id) # set merger time to the average of the ifo peaks self.merger_time = numpy.mean([ coinc_results['foreground/{}/end_time'.format(ifo)] for ifo in ifos ]) + self.time_offset # for subthreshold detectors, respect BAYESTAR's assumptions and checks bayestar_check_fields = ('mass1 mass2 mtotal mchirp eta spin1x ' 'spin1y spin1z spin2x spin2y spin2z').split() for sngl in sngl_inspiral_table: if sngl.ifo in followup_ifos: for bcf in bayestar_check_fields: setattr(sngl, bcf, getattr(sngl_populated, bcf)) sngl.end = lal.LIGOTimeGPS(self.merger_time) outdoc.childNodes[0].appendChild(coinc_event_map_table) outdoc.childNodes[0].appendChild(sngl_inspiral_table) # Set up the coinc inspiral table coinc_inspiral_table = lsctables.New(lsctables.CoincInspiralTable) coinc_inspiral_row = lsctables.CoincInspiral() # This seems to be used as FAP, which should not be in gracedb coinc_inspiral_row.false_alarm_rate = 0 coinc_inspiral_row.minimum_duration = 0. coinc_inspiral_row.instruments = tuple(usable_ifos) coinc_inspiral_row.coinc_event_id = coinc_id coinc_inspiral_row.mchirp = sngl_populated.mchirp coinc_inspiral_row.mass = sngl_populated.mtotal coinc_inspiral_row.end_time = sngl_populated.end_time coinc_inspiral_row.end_time_ns = sngl_populated.end_time_ns coinc_inspiral_row.snr = network_snrsq**0.5 far = 1.0 / (lal.YRJUL_SI * coinc_results['foreground/ifar']) coinc_inspiral_row.combined_far = far coinc_inspiral_table.append(coinc_inspiral_row) outdoc.childNodes[0].appendChild(coinc_inspiral_table) # append the PSDs self.psds = kwargs['psds'] psds_lal = {} for ifo in self.psds: psd = self.psds[ifo] kmin = int(kwargs['low_frequency_cutoff'] / psd.delta_f) fseries = lal.CreateREAL8FrequencySeries( "psd", psd.epoch, kwargs['low_frequency_cutoff'], psd.delta_f, lal.StrainUnit**2 / lal.HertzUnit, len(psd) - kmin) fseries.data.data = psd.numpy()[kmin:] / pycbc.DYN_RANGE_FAC**2.0 psds_lal[ifo] = fseries make_psd_xmldoc(psds_lal, outdoc) # source probabilities estimation if 'mc_area_args' in kwargs: eff_distances = [sngl.eff_distance for sngl in sngl_inspiral_table] probabilities = calc_probabilities(coinc_inspiral_row.mchirp, coinc_inspiral_row.snr, min(eff_distances), kwargs['mc_area_args']) self.probabilities = probabilities else: self.probabilities = None self.outdoc = outdoc self.time = sngl_populated.end
def write_simplified_sngl_inspiral_table(m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, instrument, approximant, filename=None): """Writing a simplified sngl_inspiral_table containing only one template. Args: m1 (float): mass1. m2 (float): mass2. s1x (float): spin 1 x-axis. s1y (float): spin 1 y-axis. s1z (float): spin 1 z-axis. s2x (float): spin 2 x-axis. s2y (float): spin 2 y-axis. s2z (float): spin 2 z-axis. instrument (str): The instrument for the template. approximant (str): The approximant used to simulate the waveform. filename (str, default=None): The output filename. Return: The file object representing the xmldoc. """ # Check if it is valid approximant templates.gstlal_valid_approximant(approximant) xmldoc = ligolw.Document() root = xmldoc.appendChild(ligolw.LIGO_LW()) table = lsctables.New(lsctables.SnglInspiralTable) rows = table.RowType() # set all slots to impossible/dummy value for t, c in zip(table.columntypes, table.columnnames): if t == u"real_4" or t == u"real_8": rows.__setattr__(c, 0) elif t == u"int_4s" or t == u"int_8s": rows.__setattr__(c, 0) elif t == u"lstring": rows.__setattr__(c, "") else: rows.__setattr__(c, None) rows.mass1 = m1 rows.mass2 = m2 rows.mtotal = m1 + m2 rows.mchirp = (m1 * m2)**0.6 / (m1 + m2)**0.2 rows.spin1x = s1x rows.spin1y = s1y rows.spin1z = s1z rows.spin2x = s2x rows.spin2y = s2y rows.spin2z = s2z rows.ifo = instrument table.append(rows) root.appendChild(table) #FIXME: do something better than this root.appendChild( ligolw_param.Param.from_pyvalue("approximant", approximant)) if filename is not None: ligolw_utils.write_filename(xmldoc, filename, gz=filename.endswith("gz")) return xmldoc