def create_inj_WFs(filename, PSD, sample_rate, instrument, N_inj=None, plot_dir=None): #https://git.ligo.org/RatesAndPopulations/lvc-rates-and-pop/-/blob/master/bin/lvc_rates_injections class LIGOLWContentHandler(ligolw.LIGOLWContentHandler): pass lsctables.use_in(LIGOLWContentHandler) xmldoc = utils.load_filename(filename, verbose=True, contenthandler=LIGOLWContentHandler) sim_inspiral_table = lsctables.SimInspiralTable.get_table(xmldoc) WFs = [] #a list of tuples if N_inj is None: N_inj = len(sim_inspiral_table) for row in tqdm(sim_inspiral_table): WFs.append(get_WF_and_snr(row, PSD, sample_rate, instrument, plot_dir)) if len(WFs) >= N_inj: break return WFs
def read_ligolw(source, contenthandler=LIGOLWContentHandler, **kwargs): """Read one or more LIGO_LW format files Parameters ---------- source : `str`, `file` the open file or file path to read contenthandler : `~xml.sax.handler.ContentHandler`, optional content handler used to parse document verbose : `bool`, optional be verbose when reading files, default: `False` Returns ------- xmldoc : :class:`~ligo.lw.ligolw.Document` the document object as parsed from the file(s) """ from ligo.lw.ligolw import Document from ligo.lw import types from ligo.lw.lsctables import use_in from ligo.lw.utils import (load_url, ligolw_add) # mock ToPyType to link to numpy dtypes topytype = types.ToPyType.copy() for key in types.ToPyType: if key in types.ToNumPyType: types.ToPyType[key] = numpy.dtype(types.ToNumPyType[key]).type contenthandler = use_in(contenthandler) # read one or more files into a single Document source = file_list(source) try: if len(source) == 1: return load_url(source[0], contenthandler=contenthandler, **kwargs) return ligolw_add.ligolw_add(Document(), source, contenthandler=contenthandler, **kwargs) except LigolwElementError as exc: # failed to read with ligo.lw, # try again with glue.ligolw (ilwdchar_compat) if LIGO_LW_COMPAT_ERROR.search(str(exc)): try: return read_ligolw(source, contenthandler=contenthandler, ilwdchar_compat=True, **kwargs) except Exception: # if fails for any reason, use original error pass raise finally: # replace ToPyType types.ToPyType = topytype
def build_content_handler(parent, filter_func): """Build a `~xml.sax.handler.ContentHandler` with a given filter """ from ligo.lw.lsctables import use_in class _ContentHandler(parent): # pylint: disable=too-few-public-methods def __init__(self, document): super().__init__(document, filter_func) return use_in(_ContentHandler)
def build_content_handler(parent, filter_func): """Build a `~xml.sax.handler.ContentHandler` with a given filter """ from ligo.lw.lsctables import use_in class _ContentHandler(parent): # pylint: disable=too-few-public-methods def __init__(self, document): super(_ContentHandler, self).__init__(document, filter_func) return use_in(_ContentHandler)
def open_xmldoc(fobj, **kwargs): """Try and open an existing LIGO_LW-format file, or create a new Document Parameters ---------- fobj : `str`, `file` file path or open file object to read **kwargs other keyword arguments to pass to :func:`~ligo.lw.utils.load_filename`, or :func:`~ligo.lw.utils.load_fileobj` as appropriate Returns -------- xmldoc : :class:`~ligo.lw.ligolw.Document` either the `Document` as parsed from an existing file, or a new, empty `Document` """ from ligo.lw.ligolw import (Document, LIGOLWContentHandler) from ligo.lw.lsctables import use_in from ligo.lw.utils import (load_filename, load_fileobj) use_in(kwargs.setdefault('contenthandler', LIGOLWContentHandler)) try: # try and load existing file if isinstance(fobj, string_types): return load_filename(fobj, **kwargs) if isinstance(fobj, FILE_LIKE): return load_fileobj(fobj, **kwargs)[0] except (OSError, IOError): # or just create a new Document return Document() except LigolwElementError as exc: if LIGO_LW_COMPAT_ERROR.search(str(exc)): try: return open_xmldoc(fobj, ilwdchar_compat=True, **kwargs) except Exception: # for any reason, raise original pass raise
def open_xmldoc(fobj, **kwargs): """Try and open an existing LIGO_LW-format file, or create a new Document Parameters ---------- fobj : `str`, `file` file path or open file object to read **kwargs other keyword arguments to pass to :func:`~ligo.lw.utils.load_filename`, or :func:`~ligo.lw.utils.load_fileobj` as appropriate Returns -------- xmldoc : :class:`~ligo.lw.ligolw.Document` either the `Document` as parsed from an existing file, or a new, empty `Document` """ from ligo.lw.ligolw import (Document, LIGOLWContentHandler) from ligo.lw.lsctables import use_in from ligo.lw.utils import (load_filename, load_fileobj) use_in(kwargs.setdefault('contenthandler', LIGOLWContentHandler)) try: # try and load existing file if isinstance(fobj, str): return load_filename(fobj, **kwargs) if isinstance(fobj, FILE_LIKE): return load_fileobj(fobj, **kwargs)[0] except (OSError, IOError): # or just create a new Document return Document() except LigolwElementError as exc: if LIGO_LW_COMPAT_ERROR.search(str(exc)): try: return open_xmldoc(fobj, ilwdchar_compat=True, **kwargs) except Exception: # for any reason, raise original pass raise
def plotbank(in_filename, out_filename=None, column1='mchirp', column2='mtotal'): """Plot template bank parameters from a file generated by lalapps_tmpltbank.""" from ligo.lw import ligolw, utils, lsctables class LIGOLWContentHandler(ligolw.LIGOLWContentHandler): pass lsctables.use_in(LIGOLWContentHandler) table = lsctables.SnglInspiralTable.get_table( utils.load_filename(in_filename, contenthandler=LIGOLWContentHandler)) pylab.figure() pylab.title('%s: placement of %d templates' % (in_filename, len(table))) pylab.plot(table.get_column(column1), table.get_column(column2), ',') pylab.xlabel(labels[column1]) pylab.ylabel(labels[column2]) pylab.grid() if out_filename is None: pylab.show() else: pylab.savefig(out_filename) pylab.close()
def read_ligolw(source, contenthandler=LIGOLWContentHandler, **kwargs): """Read one or more LIGO_LW format files Parameters ---------- source : `str`, `file` the open file or file path to read contenthandler : `~xml.sax.handler.ContentHandler`, optional content handler used to parse document verbose : `bool`, optional be verbose when reading files, default: `False` Returns ------- xmldoc : :class:`~ligo.lw.ligolw.Document` the document object as parsed from the file(s) """ from ligo.lw.ligolw import Document from ligo.lw import types from ligo.lw.lsctables import use_in from ligo.lw.utils import (load_url, ligolw_add) # mock ToPyType to link to numpy dtypes topytype = types.ToPyType.copy() for key in types.ToPyType: if key in types.ToNumPyType: types.ToPyType[key] = numpy.dtype(types.ToNumPyType[key]).type contenthandler = use_in(contenthandler) # read one or more files into a single Document source = file_list(source) try: if len(source) == 1: return load_url( source[0], contenthandler=contenthandler, **kwargs ) return ligolw_add.ligolw_add( Document(), source, contenthandler=contenthandler, **kwargs ) except LigolwElementError as exc: # failed to read with ligo.lw, # try again with glue.ligolw (ilwdchar_compat) if LIGO_LW_COMPAT_ERROR.search(str(exc)): try: return read_ligolw( source, contenthandler=contenthandler, ilwdchar_compat=True, **kwargs ) except Exception: # if fails for any reason, use original error pass raise finally: # replace ToPyType types.ToPyType = topytype
# # Input # # ============================================================================= # # # Content handler # class ContentHandler(ligolw.LIGOLWContentHandler): pass lsctables.use_in(ContentHandler) # # Use interning row builder to save memory. # lsctables.table.TableStream.RowBuilder = lsctables.table.InterningRowBuilder # # ============================================================================= # # Preparation # # ============================================================================= #
def read_table(source, tablename=None, columns=None, contenthandler=None, **kwargs): """Read a :class:`~ligo.lw.table.Table` from one or more LIGO_LW files Parameters ---------- source : `Document`, `file`, `str`, `CacheEntry`, `list` object representing one or more files. One of - a LIGO_LW :class:`~ligo.lw.ligolw.Document` - an open `file` - a `str` pointing to a file path on disk - a formatted :class:`~lal.utils.CacheEntry` representing one file - a `list` of `str` file paths or :class:`~lal.utils.CacheEntry` tablename : `str` name of the table to read. columns : `list`, optional list of column name strings to read, default all. contenthandler : `~xml.sax.handler.ContentHandler`, optional SAX content handler for parsing LIGO_LW documents. **kwargs other keyword arguments are passed to `~gwpy.io.ligolw.read_ligolw` Returns ------- table : :class:`~ligo.lw.table.Table` `Table` of data """ from ligo.lw.ligolw import Document from ligo.lw import (table, lsctables) # get ilwdchar_compat to pass to read_ligolw() if Document.__module__.startswith("glue"): kwargs["ilwdchar_compat"] = True # get content handler to read only this table (if given) if tablename is not None: tableclass = lsctables.TableByName[table.Table.TableName(tablename)] if contenthandler is None: contenthandler = get_partial_contenthandler(tableclass) # overwrite loading column names to get just what was asked for _oldcols = tableclass.loadcolumns if columns is not None: tableclass.loadcolumns = columns # read document if isinstance(source, Document): xmldoc = source else: if contenthandler is None: contenthandler = lsctables.use_in(LIGOLWContentHandler) try: xmldoc = read_ligolw(source, contenthandler=contenthandler, **kwargs) finally: # reinstate original set of loading column names if tablename is not None: tableclass.loadcolumns = _oldcols # now find the right table if tablename is None: tables = list_tables(xmldoc) if not tables: raise ValueError("No tables found in LIGO_LW document(s)") if len(tables) > 1: tlist = "'{}'".format("', '".join(tables)) raise ValueError("Multiple tables found in LIGO_LW document(s), " "please specify the table to read via the " "``tablename=`` keyword argument. The following " "tables were found: {}".format(tlist)) tableclass = lsctables.TableByName[table.Table.TableName(tables[0])] # extract table return tableclass.get_table(xmldoc)
# ============================================================================= # # Input # # ============================================================================= # # # Content handler # class ContentHandler(ligolw.LIGOLWContentHandler): pass lsctables.use_in(ContentHandler) # # Use interning row builder to save memory. # lsctables.table.TableStream.RowBuilder = lsctables.table.InterningRowBuilder # # ============================================================================= # # Preparation #
# # ============================================================================= # # ligo.lw Content Handlers # # ============================================================================= # class ligolwcontenthandler(LIGOLWContentHandler): pass ligolw_array.use_in(ligolwcontenthandler) ligolw_param.use_in(ligolwcontenthandler) lsctables.use_in(ligolwcontenthandler) def parse_segments_xml(path): llwsegments = ligolw_segments.LigolwSegments( ligolw_utils.load_filename(path, contenthandler=ligolwcontenthandler)) seglistdicts = { #'frame gate': llwsegments.get_by_name(u'framesegments')} 'h(t) gate': llwsegments.get_by_name(u'whitehtsegments'), 'state vector': llwsegments.get_by_name(u'statevectorsegments'), 'trigger buffers': llwsegments.get_by_name(u'triggersegments') } # FIXME This needs to be generalized to more than two IFOs seglistdicts['joint segments'] = { 'H1L1': seglistdicts['state vector'].intersection(['H1', 'L1']) } return seglistdicts
from optparse import OptionParser import sys from ligo.lw import ligolw from ligo.lw import lsctables from ligo.lw import utils as ligolw_utils from ligo.lw.utils import process as ligolw_process from ligo.lw.utils import segments as ligolw_segments import lal from lalinspiral import thinca from ligo.segments import utils as segmentsUtils lsctables.use_in(ligolw.LIGOLWContentHandler) __author__ = "Kipp Cannon <*****@*****.**>" from lalapps.git_version import date as __date__ from lalapps.git_version import version as __version__ # # Must use coincidence code's custom sngl_inspiral table row type. # lsctables.SnglInspiralTable.RowType = lsctables.SnglInspiral = thinca.SnglInspiral
# # ============================================================================= # from optparse import OptionParser from lal.utils import CacheEntry from ligo.lw import ligolw from ligo.lw import lsctables from ligo.lw import utils as ligolw_utils from ligo.lw.utils import process as ligolw_process from lalburst import git_version from lalburst import bucluster lsctables.use_in(ligolw.LIGOLWContentHandler) __author__ = "Kipp Cannon <*****@*****.**>" __version__ = "git id %s" % git_version.id __date__ = git_version.date # # ============================================================================= # # Command Line # # ============================================================================= # def parse_command_line():
def setup_roq(cp): """ Generates cp objects with the different ROQs applied """ use_roq = False if cp.has_option('paths', 'roq_b_matrix_directory') or cp.has_option( 'paths', 'computeroqweights'): if not cp.has_option('analysis', 'roq'): print( "Warning: If you are attempting to enable ROQ by specifying roq_b_matrix_directory or computeroqweights,\n\ please use analysis.roq in your config file in future. Enabling ROQ." ) cp.set('analysis', 'roq', True) if not cp.getboolean('analysis', 'roq'): yield cp return path = cp.get('paths', 'roq_b_matrix_directory') if not os.path.isdir(path): print("The ROQ directory %s does not seem to exist\n" % path) sys.exit(1) use_roq = True roq_paths = os.listdir(path) roq_params = {} roq_force_flow = None if cp.has_option('lalinference', 'roq_force_flow'): roq_force_flow = cp.getfloat('lalinference', 'roq_force_flow') print("WARNING: Forcing the f_low to ", str(roq_force_flow), "Hz") print( "WARNING: Overwriting user choice of flow, srate, seglen, and (mc_min, mc_max and q-min) or (mass1_min, mass1_max, mass2_min, mass2_max)" ) def key(item): # to order the ROQ bases return float(item[1]['seglen']) coinc_xml_obj = None row = None # Get file object of coinc.xml if opts.gid is not None: from ligo.gracedb.rest import GraceDb gid = opts.gid cwd = os.getcwd() if cp.has_option('analysis', 'service-url'): client = GraceDb(cp.get('analysis', 'service-url')) else: client = GraceDb() coinc_xml_obj = ligolw_utils.load_fileobj( client.files(gid, "coinc.xml"), contenthandler=lsctables.use_in(ligolw.LIGOLWContentHandler))[0] elif cp.has_option('input', 'coinc-xml'): coinc_xml_obj = ligolw_utils.load_fileobj( open(cp.get('input', 'coinc-xml'), "rb"), contenthandler=lsctables.use_in(ligolw.LIGOLWContentHandler))[0] # Get sim_inspiral from injection file if cp.has_option('input', 'injection-file'): print( "Only 0-th event in the XML table will be considered while running with ROQ\n" ) row = lsctables.SimInspiralTable.get_table( ligolw_utils.load_filename(cp.get('input', 'injection-file'), contenthandler=lsctables.use_in( ligolw.LIGOLWContentHandler)))[0] roq_bounds = pipe_utils.Query_ROQ_Bounds_Type(path, roq_paths) if roq_bounds == 'chirp_mass_q': print('ROQ has bounds in chirp mass and mass-ratio') mc_priors, trigger_mchirp = pipe_utils.get_roq_mchirp_priors( path, roq_paths, roq_params, key, coinc_xml_obj=coinc_xml_obj, sim_inspiral=row) elif roq_bounds == 'component_mass': print('ROQ has bounds in component masses') # get component mass bounds, then compute the chirp mass that can be safely covered # further below we pass along the component mass bounds to the sampler, not the tighter chirp-mass, q bounds m1_priors, m2_priors, trigger_mchirp = pipe_utils.get_roq_component_mass_priors( path, roq_paths, roq_params, key, coinc_xml_obj=coinc_xml_obj, sim_inspiral=row) mc_priors = {} for (roq, m1_prior), (roq2, m2_prior) in zip(m1_priors.items(), m2_priors.items()): mc_priors[roq] = sorted([ pipe_utils.mchirp_from_components(m1_prior[1], m2_prior[0]), pipe_utils.mchirp_from_components(m1_prior[0], m2_prior[1]) ]) if cp.has_option('lalinference', 'trigger_mchirp'): trigger_mchirp = float(cp.get('lalinference', 'trigger_mchirp')) roq_mass_freq_scale_factor = pipe_utils.get_roq_mass_freq_scale_factor( mc_priors, trigger_mchirp, roq_force_flow) if roq_mass_freq_scale_factor != 1.: print( 'WARNING: Rescaling ROQ basis, please ensure it is allowed with the model used.' ) # If the true chirp mass is unknown, add variations over the mass bins if opts.gid is not None or (opts.injections is not None or cp.has_option( 'input', 'injection-file')) or cp.has_option( 'lalinference', 'trigger_mchirp') or cp.has_option( 'input', 'coinc-xml'): for mc_prior in mc_priors: mc_priors[mc_prior] = np.array(mc_priors[mc_prior]) # find mass bin containing the trigger candidate_roq_paths = \ [roq for roq in roq_paths if mc_priors[roq][0]*roq_mass_freq_scale_factor <= trigger_mchirp <= mc_priors[roq][1]*roq_mass_freq_scale_factor] if candidate_roq_paths: margins = np.array([ min( mc_priors[roq][1] * roq_mass_freq_scale_factor - trigger_mchirp, trigger_mchirp - mc_priors[roq][0] * roq_mass_freq_scale_factor) for roq in candidate_roq_paths ]) best_path = candidate_roq_paths[np.argmax(margins)] roq_paths = [best_path] print( 'Prior in Mchirp will be [{}, {}] to contain the trigger Mchirp {}.' .format(mc_priors[best_path][0] * roq_mass_freq_scale_factor, mc_priors[best_path][1] * roq_mass_freq_scale_factor, trigger_mchirp)) else: print("No roq mass bins containing the trigger") raise else: for mc_prior in mc_priors: mc_priors[mc_prior] = np.array( mc_priors[mc_prior]) * roq_mass_freq_scale_factor # write the master configparser cur_basedir = cp.get('paths', 'basedir') masterpath = os.path.join(cur_basedir, 'config.ini') with open(masterpath, 'w') as cpfile: cp.write(cpfile) for roq in roq_paths: this_cp = configparser.ConfigParser() this_cp.optionxform = str this_cp.read(masterpath) basedir = this_cp.get('paths', 'basedir') for dirs in 'basedir', 'daglogdir', 'webdir': val = this_cp.get('paths', dirs) newval = os.path.join(val, roq) mkdirs(newval) this_cp.set('paths', dirs, newval) this_cp.set( 'paths', 'roq_b_matrix_directory', os.path.join(cp.get('paths', 'roq_b_matrix_directory'), roq)) flow = roq_params[roq]['flow'] / roq_mass_freq_scale_factor srate = 2. * roq_params[roq]['fhigh'] / roq_mass_freq_scale_factor #if srate > 8192: # srate = 8192 seglen = roq_params[roq]['seglen'] * roq_mass_freq_scale_factor # params.dat uses the convention q>1 so our q_min is the inverse of their qmax this_cp.set('engine', 'srate', str(srate)) this_cp.set('engine', 'seglen', str(seglen)) if this_cp.has_option('lalinference', 'flow'): tmp = this_cp.get('lalinference', 'flow') tmp = eval(tmp) ifos = tmp.keys() else: tmp = {} ifos = eval(this_cp.get('analysis', 'ifos')) for i in ifos: tmp[i] = flow this_cp.set('lalinference', 'flow', str(tmp)) if roq_bounds == 'chirp_mass_q': mc_min = mc_priors[roq][0] * roq_mass_freq_scale_factor mc_max = mc_priors[roq][1] * roq_mass_freq_scale_factor # params.dat uses the convention q>1 so our q_min is the inverse of their qmax q_min = 1. / float(roq_params[roq]['qmax']) this_cp.set('engine', 'chirpmass-min', str(mc_min)) this_cp.set('engine', 'chirpmass-max', str(mc_max)) this_cp.set('engine', 'q-min', str(q_min)) this_cp.set( 'engine', 'comp-min', str( max( roq_params[roq]['compmin'] * roq_mass_freq_scale_factor, mc_min * pow(1 + q_min, 1. / 5.) * pow(q_min, 2. / 5.)))) this_cp.set( 'engine', 'comp-max', str(mc_max * pow(1 + q_min, 1. / 5.) * pow(q_min, -3. / 5.))) elif roq_bounds == 'component_mass': m1_min = m1_priors[roq][0] m1_max = m1_priors[roq][1] m2_min = m2_priors[roq][0] m2_max = m2_priors[roq][1] this_cp.set('engine', 'mass1-min', str(m1_min)) this_cp.set('engine', 'mass1-max', str(m1_max)) this_cp.set('engine', 'mass2-min', str(m2_min)) this_cp.set('engine', 'mass2-max', str(m2_max)) yield this_cp return
parser.add_option('--injXML', action='store', type='string', dest='injxml', help='sim_inspiral XML file for injections') parser.add_option('--outdir', action='store', type='string', help='output directory') parser.add_option('--postsamples', action='store', type='string', default='posterior_samples.dat', help='filename for posterior samples files') parser.add_option('--par', action='append', default=[], type='string', help='parameter names for the p-p plot') parser.add_option('--skyPPfolder', action='store',dest='skypp',type='string',default=None,help='Path to folder containing png/pdf with 2D skyarea PP plots') (options, args) = parser.parse_args() injs = lsctables.SimInspiralTable.get_table(utils.load_filename(options.injxml,contenthandler=lsctables.use_in(ligolw.LIGOLWContentHandler))) if options.par == []: parameters = ['m1', 'm2', 'mc', 'eta', 'q', 'theta_jn', 'a1', 'a2', 'tilt1', 'tilt2', 'phi12', 'phi_jl', 'ra', 'dec', 'distance', 'time', 'phi_orb', 'psi'] else: parameters = options.par try: os.mkdir(options.outdir) except: pass pvalues = { } posfiles=args Ninj=0 for index,posfile in enumerate(posfiles):
Attributes = ligolw.sax.xmlreader.AttributesImpl from gstlal import cbc_template_fir from gstlal import misc as gstlalmisc from gstlal import templates from gstlal import reference_psd class DefaultContentHandler(ligolw.LIGOLWContentHandler): pass ligolw_array.use_in(DefaultContentHandler) ligolw_param.use_in(DefaultContentHandler) lsctables.use_in(DefaultContentHandler) # # ============================================================================= # # Utilities # # ============================================================================= # # # Read approximant # def read_approximant(xmldoc, programs=("gstlal_bank_splitter", )):
def startElement(self, name, attrs): if attrs.has_key('Name') and table.Table.TableName( attrs['Name']) == self.tabname: self.tableElementName = name # Got the right table, let's see if it's the right event ligolw.LIGOLWContentHandler.startElement(self, name, attrs) self.intable = True elif self.intable: # We are in the correct table ligolw.LIGOLWContentHandler.startElement(self, name, attrs) def endElement(self, name): if self.intable: ligolw.LIGOLWContentHandler.endElement(self, name) if self.intable and name == self.tableElementName: self.intable = False lsctables.use_in(LIGOLWContentHandlerExtractSimBurstTable) posterior_name_to_sim_burst_extractor = { 'frequency': lambda sb: sb.frequency, 'duration': lambda sb: sb.duration, 'quality': lambda sb: sb.q, 'hrss': lambda sb: sb.hrss, 'psi': lambda sb: sb.psi, 'time': lambda sb: sb.time_geocent_gps + 1e-9 * sb.time_geocent_gps_ns, 'ra': lambda sb: sb.ra, 'dec': lambda sb: sb.dec, 'polar_angle': lambda sb: sb.pol_ellipse_angle, 'polar_eccentricity': lambda sb: sb.pol_ellipse_e, 'alpha': lambda sb: sb.pol_ellipse_angle }
def read_table(source, tablename=None, columns=None, contenthandler=None, **kwargs): """Read a :class:`~ligo.lw.table.Table` from one or more LIGO_LW files Parameters ---------- source : `Document`, `file`, `str`, `CacheEntry`, `list` object representing one or more files. One of - a LIGO_LW :class:`~ligo.lw.ligolw.Document` - an open `file` - a `str` pointing to a file path on disk - a formatted :class:`~lal.utils.CacheEntry` representing one file - a `list` of `str` file paths or :class:`~lal.utils.CacheEntry` tablename : `str` name of the table to read. columns : `list`, optional list of column name strings to read, default all. contenthandler : `~xml.sax.handler.ContentHandler`, optional SAX content handler for parsing LIGO_LW documents. **kwargs other keyword arguments are passed to `~gwpy.io.ligolw.read_ligolw` Returns ------- table : :class:`~ligo.lw.table.Table` `Table` of data """ from ligo.lw.ligolw import Document from ligo.lw import (table, lsctables) # get ilwdchar_compat to pass to read_ligolw() if Document.__module__.startswith("glue"): kwargs["ilwdchar_compat"] = True # get content handler to read only this table (if given) if tablename is not None: tableclass = lsctables.TableByName[ table.Table.TableName(tablename) ] if contenthandler is None: contenthandler = get_partial_contenthandler(tableclass) # overwrite loading column names to get just what was asked for _oldcols = tableclass.loadcolumns if columns is not None: tableclass.loadcolumns = columns # read document if isinstance(source, Document): xmldoc = source else: if contenthandler is None: contenthandler = lsctables.use_in(LIGOLWContentHandler) try: xmldoc = read_ligolw(source, contenthandler=contenthandler, **kwargs) finally: # reinstate original set of loading column names if tablename is not None: tableclass.loadcolumns = _oldcols # now find the right table if tablename is None: tables = list_tables(xmldoc) if not tables: raise ValueError("No tables found in LIGO_LW document(s)") if len(tables) > 1: tlist = "'{}'".format("', '".join(tables)) raise ValueError("Multiple tables found in LIGO_LW document(s), " "please specify the table to read via the " "``tablename=`` keyword argument. The following " "tables were found: {}".format(tlist)) tableclass = lsctables.TableByName[table.Table.TableName(tables[0])] # extract table return tableclass.get_table(xmldoc)