def build_bank(bank_url, psd_file, sample_rate, f_low, f_high=None, autocorrelation_length=None, verbose=False): """Return an instance of a Bank class.""" bank_xmldoc = ligolw_utils.load_url(bank_url, contenthandler=ContentHandler, verbose=verbose) psd = lal.series.read_psd_xmldoc( ligolw_utils.load_url(psd_file, contenthandler=lal.series.PSDContentHandler)) assert numpy.log2( sample_rate).is_integer(), "sample_rate can only be power of two." bank = Bank(bank_xmldoc, psd[lsctables.SnglInspiralTable.get_table(bank_xmldoc)[0].ifo], sample_rate, f_low, f_high, autocorrelation_length=autocorrelation_length, verbose=verbose) bank.template_bank_filename = bank_url #FIXME: dummy bank_id bank.bank_id = 0 return bank
def marginalize_pdf_urls(urls, which, ignore_missing_files=False, verbose=False): """ Implements marginalization of PDFs in ranking statistic data files. The marginalization is over the degree of freedom represented by the file collection. One or both of the candidate parameter PDFs and ranking statistic PDFs can be processed, with errors thrown if one or more files is missing the required component. """ name = u"gstlal_inspiral_likelihood" data = None for n, url in enumerate(urls, start=1): # # load input document # if verbose: print("%d/%d:" % (n, len(urls)), file=sys.stderr) try: xmldoc = ligolw_utils.load_url( url, verbose=verbose, contenthandler=RankingStat.LIGOLWContentHandler) except IOError: # IOError is raised when an on-disk file is # missing. urllib2.URLError is raised when a URL # cannot be loaded, but this is subclassed from # IOError so IOError will catch those, too. if not ignore_missing_files: raise if verbose: print("Could not load \"%s\" ... skipping as requested" % url, file=sys.stderr) continue # # extract PDF objects compute weighted sum of ranking data # PDFs # if which == "RankingStat": if data is None: data = RankingStat.from_xml(xmldoc, name) else: data += RankingStat.from_xml(xmldoc, name) elif which == "RankingStatPDF": if data is None: data = RankingStatPDF.from_xml(xmldoc, name) else: data += RankingStatPDF.from_xml(xmldoc, name) else: raise ValueError("invalid which (%s)" % which) xmldoc.unlink() return data
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 from_url(cls, url, verbose=False): xmldoc = ligolw_utils.load_url(url, contenthandler=ContentHandler, verbose=verbose) banks = [] for root in ( elem for elem in xmldoc.getElementsByTagName(ligolw.LIGO_LW.tagName) if elem.hasAttribute("Name") and elem.Name == "gstlal_template_bank"): bank = cls.__new__(cls) bank.bank_id = ligolw_param.get_pyvalue(root, "bank_id") bank.sample_rate = ligolw_param.get_pyvalue(root, "sample_rate") bank.processed_psd = None bank.sngl_inspiral_table = lsctables.SnglInspiralTable.get_table( root) bank.template_bank_filename = ligolw_param.get_pyvalue( root, "template_bank_filename") bank.sigmasq = ligolw_array.get_array(root, "sigmasq").array bank.templates = ligolw_array.get_array(root, "templates").array bank.autocorrelation_bank = ligolw_array.get_array( root, "autocorrelation_bank").array bank.autocorrelation_mask = ligolw_array.get_array( root, "autocorrelation_mask").array bank.horizon_factors = dict( (row.template_id, sigmasq**.5) for row, sigmasq in zip( bank.sngl_inspiral_table, bank.sigmasq)) banks.append(bank) min_template_id, horizon_distance_func = svd_bank.horizon_distance_func( banks) horizon_norm, = (bank.horizon_factors[row.template_id] for row in bank.sngl_inspiral_table for bank in banks if row.template_id == min_template_id) for bank in banks: bank.horizon_distance_func = horizon_distance_func bank.horizon_factors = dict( (tid, f / horizon_norm) for (tid, f) in bank.horizon_factors.items()) return banks
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 read_banks(filename, contenthandler, verbose=False): """Read SVD banks from a LIGO_LW xml file.""" # Load document xmldoc = ligolw_utils.load_url(filename, contenthandler=contenthandler, verbose=verbose) banks = [] # FIXME in principle this could be different for each bank included in # this file, but we only put one in the file for now # FIXME, right now there is only one instrument so we just pull out the # only psd there is try: raw_psd = list(lal.series.read_psd_xmldoc(xmldoc).values())[0] except ValueError: # the bank file does not contain psd ligolw element. raw_psd = None for root in ( elem for elem in xmldoc.getElementsByTagName(ligolw.LIGO_LW.tagName) if elem.hasAttribute(u"Name") and elem.Name == "gstlal_svd_bank_Bank"): # Create new SVD bank object bank = Bank.__new__(Bank) # Read sngl inspiral table bank.sngl_inspiral_table = lsctables.SnglInspiralTable.get_table(root) bank.sngl_inspiral_table.parentNode.removeChild( bank.sngl_inspiral_table) # Read root-level scalar parameters bank.filter_length = ligolw_param.get_pyvalue(root, 'filter_length') bank.gate_threshold = ligolw_param.get_pyvalue(root, 'gate_threshold') bank.logname = ligolw_param.get_pyvalue(root, 'logname') or None bank.snr_threshold = ligolw_param.get_pyvalue(root, 'snr_threshold') bank.template_bank_filename = ligolw_param.get_pyvalue( root, 'template_bank_filename') bank.bank_id = ligolw_param.get_pyvalue(root, 'bank_id') try: bank.newdeltaF = ligolw_param.get_pyvalue(root, 'new_deltaf') bank.working_f_low = ligolw_param.get_pyvalue( root, 'working_f_low') bank.f_low = ligolw_param.get_pyvalue(root, 'f_low') bank.sample_rate_max = ligolw_param.get_pyvalue( root, 'sample_rate_max') except ValueError: pass # Read root-level arrays bank.autocorrelation_bank = ligolw_array.get_array( root, 'autocorrelation_bank_real').array + 1j * ligolw_array.get_array( root, 'autocorrelation_bank_imag').array bank.autocorrelation_mask = ligolw_array.get_array( root, 'autocorrelation_mask').array bank.sigmasq = ligolw_array.get_array(root, 'sigmasq').array # prepare the horizon distance factors bank.horizon_factors = dict( (row.template_id, sigmasq**.5) for row, sigmasq in zip(bank.sngl_inspiral_table, bank.sigmasq)) if raw_psd is not None: # reproduce the whitening psd and attach a reference to the psd bank.processed_psd = cbc_template_fir.condition_psd( raw_psd, bank.newdeltaF, minfs=(bank.working_f_low, bank.f_low), maxfs=(bank.sample_rate_max / 2.0 * 0.90, bank.sample_rate_max / 2.0)) # Read bank fragments bank.bank_fragments = [] for el in (node for node in root.childNodes if node.tagName == ligolw.LIGO_LW.tagName): frag = BankFragment(rate=ligolw_param.get_pyvalue(el, 'rate'), start=ligolw_param.get_pyvalue(el, 'start'), end=ligolw_param.get_pyvalue(el, 'end')) # Read arrays frag.chifacs = ligolw_array.get_array(el, 'chifacs').array try: frag.mix_matrix = ligolw_array.get_array(el, 'mix_matrix').array except ValueError: frag.mix_matrix = None frag.orthogonal_template_bank = ligolw_array.get_array( el, 'orthogonal_template_bank').array try: frag.singular_values = ligolw_array.get_array( el, 'singular_values').array except ValueError: frag.singular_values = None try: frag.sum_of_squares_weights = ligolw_array.get_array( el, 'sum_of_squares_weights').array except ValueError: frag.sum_of_squares_weights = None bank.bank_fragments.append(frag) banks.append(bank) template_id, func = horizon_distance_func(banks) horizon_norm = None for bank in banks: if template_id in bank.horizon_factors: assert horizon_norm is None horizon_norm = bank.horizon_factors[template_id] for bank in banks: bank.horizon_distance_func = func bank.horizon_factors = dict( (tid, f / horizon_norm) for (tid, f) in bank.horizon_factors.items()) xmldoc.unlink() return banks
def build_bank(template_bank_url, psd, flow, ortho_gate_fap, snr_threshold, svd_tolerance, padding=1.5, identity_transform=False, verbose=False, autocorrelation_length=201, samples_min=1024, samples_max_256=1024, samples_max_64=2048, samples_max=4096, bank_id=None, contenthandler=None, sample_rate=None, instrument_override=None): """! Return an instance of a Bank class. @param template_bank_url The template bank filename or url containing a subbank of templates to decompose in a single inpsiral table. @param psd A class instance of a psd. @param flow The lower frequency cutoff. @param ortho_gate_fap The FAP threshold for the sum of squares threshold, see http://arxiv.org/abs/1101.0584 @param snr_threshold The SNR threshold for the search @param svd_tolerance The target SNR loss of the SVD, see http://arxiv.org/abs/1005.0012 @param padding The padding from Nyquist for any template time slice, e.g., if a time slice has a Nyquist of 256 Hz and the padding is set to 2, only allow the template frequency to extend to 128 Hz. @param identity_transform Don't do the SVD, just do time slices and keep the raw waveforms @param verbose Be verbose @param autocorrelation_length The number of autocorrelation samples to use in the chisquared test. Must be odd @param samples_min The minimum number of samples to use in any time slice @param samples_max_256 The maximum number of samples to have in any time slice greater than or equal to 256 Hz @param samples_max_64 The maximum number of samples to have in any time slice greater than or equal to 64 Hz @param samples_max The maximum number of samples in any time slice below 64 Hz @param bank_id The id of the bank in question @param contenthandler The ligolw content handler for file I/O """ # Open template bank file bank_xmldoc = ligolw_utils.load_url(template_bank_url, contenthandler=contenthandler, verbose=verbose) # Get sngl inspiral table bank_sngl_table = lsctables.SnglInspiralTable.get_table(bank_xmldoc) # override instrument if needed (this is useful if a generic instrument independent bank file is provided if instrument_override is not None: for row in bank_sngl_table: row.ifo = instrument_override # Choose how to break up templates in time time_freq_bounds = templates.time_slices( bank_sngl_table, fhigh=check_ffinal_and_find_max_ffinal(bank_xmldoc), flow=flow, padding=padding, samples_min=samples_min, samples_max_256=samples_max_256, samples_max_64=samples_max_64, samples_max=samples_max, sample_rate=sample_rate, verbose=verbose) if sample_rate is not None: fhigh = check_ffinal_and_find_max_ffinal(bank_xmldoc) else: fhigh = None # Generate templates, perform SVD, get orthogonal basis # and store as Bank object bank = Bank( bank_xmldoc, psd[bank_sngl_table[0].ifo], time_freq_bounds, gate_fap=ortho_gate_fap, snr_threshold=snr_threshold, tolerance=svd_tolerance, flow=flow, autocorrelation_length=autocorrelation_length, # samples identity_transform=identity_transform, verbose=verbose, bank_id=bank_id, fhigh=fhigh) # FIXME: remove this when no longer needed # by trigger generator element. bank.set_template_bank_filename( ligolw_utils.local_path_from_url(template_bank_url)) return bank
def read_url(filename, contenthandler=SNRContentHandler, verbose=False): return ligolw_utils.load_url(filename, verbose=verbose, contenthandler=contenthandler)