def create_empty_sim_inspiral_row(): """ Create an empty sim_inspiral or sngl_inspiral row where the columns have default values of None for a float. Retuns ---------- row: SimInspiral An empty sim_inspiral row. """ # create sim_inspiral row row = lsctables.SimInspiral() cols = lsctables.SimInspiralTable.validcolumns # populate columns with default values for entry in cols.keys(): if cols[entry] in ['real_4', 'real_8']: setattr(row, entry, None) elif cols[entry] == 'int_4s': setattr(row, entry, None) elif cols[entry] == 'lstring': setattr(row, entry, "") elif entry == 'process_id': row.process_id = "process:process_id:0" elif entry == 'simulation_id': row.simulation_id = "sim_inspiral:simulation_id:0" return row
def create_empty_row(obj): """Create an empty sngl_inspiral row where the columns have default values of 0.0 for a float, 0 for an int, '' for a string. The ilwd columns have a default where the index is 0. """ # check if sim_inspiral or sngl_inspiral row = lsctables.SimInspiral() cols = lsctables.SimInspiralTable.validcolumns # populate columns with default values for entry in cols.keys(): if cols[entry] in ['real_4', 'real_8']: setattr(row, entry, 0.) elif cols[entry] == 'int_4s': setattr(row, entry, 0) elif cols[entry] == 'lstring': setattr(row, entry, '') elif entry == 'process_id': row.process_id = ilwd.ilwdchar("sim_inspiral:process_id:0") elif entry == 'simulation_id': row.simulation_id = ilwd.ilwdchar("sim_inspiral:simulation_id:0") else: raise ValueError("Column %s not recognized." % (entry)) return row
def get_new_sample_point(): """This function returns an instance of lsctables.SimInspiral, with elements corresponding to various physical parameters uniformly sampled within their respective ranges. """ p = lsctables.SimInspiral() # Masses p.mchirp = sample_mchirp() p.eta = sample_eta_uniform() while not accept_point(p.mchirp, p.eta): p.mchirp = sample_mchirp() p.eta = sample_eta_uniform() p.mass1, p.mass2 = mchirp_eta_to_mass1_mass2(p.mchirp, p.eta) # Spins p.spin1x = sample_sxyz() p.spin1y = sample_sxyz() p.spin1z = sample_sxyz() smag = np.sqrt(p.spin1x**2. + p.spin1y**2. + p.spin1z**2.) if smag > smag_max or smag < smag_min: newsmag = sample_smag() p.spin1x *= (newsmag / smag) p.spin1y *= (newsmag / smag) p.spin1z *= (newsmag / smag) p.spin2x = sample_sxyz() p.spin2y = sample_sxyz() p.spin2z = sample_sxyz() smag = np.sqrt(p.spin2x**2. + p.spin2y**2. + p.spin2z**2.) if smag > smag_max or smag < smag_min: newsmag = sample_smag() p.spin2x *= (newsmag / smag) p.spin2y *= (newsmag / smag) p.spin2z *= (newsmag / smag) # Orbital parameters p.alpha = sample_ecc() p.alpha1 = sample_mean_per_ano() p.alpha2 = sample_long_asc_nodes() p.coa_phase = sample_coa_phase() # Orientation and location p.inclination = sample_inc() p.distance = sample_dist() # Polarization p.polarization = sample_pol() # Sky angles p.latitude, p.longitude = sample_lat_lon() # Unique HASH p.simulation_id = get_sim_hash() # Process ID p.process_id = out_proc_id return p
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'))
print("Reading from %s" % input_catalog, file=sys.stderr) # for point in input_table: # Apply the mass-ratio threshold qth = options.upper_q_threshold if point.eta < (qth / (1. + qth)**2): if options.verbose: print(" -- Not including %s" % point.waveform, file=sys.stdout) sys.stdout.flush() continue # Check if the waveform location is specified. # if not os.path.exists(point.numrel_data): continue # if not (os.path.getsize(point.numrel_data) > 0): continue # If cehck passed, proceed to appending it to the final table npoint = lsctables.SimInspiral() # Initialize columns for nn in out_table.columnnames: if 'process_id' in nn: npoint.process_id = proc_id elif 'waveform' in nn: npoint.waveform = 'NR' else: npoint.__setattr__(nn, 0) # Copy over columns for nn in point.__slots__: if hasattr(point, nn): npoint.__setattr__(nn, point.__getattribute__(nn)) # out_table.append(npoint) #
print param_names if options.type == "sngl": sngl_inspiral_table = lsctables.New(lsctables.SnglInspiralTable, columns=col_names) elif options.type == "sim": sngl_inspiral_table = lsctables.New(lsctables.SimInspiralTable, columns=col_names) outdoc.childNodes[0].appendChild(sngl_inspiral_table) for values in params: if options.type == "sngl": tmplt = lsctables.SnglInspiral() elif options.type == "sim": tmplt = lsctables.SimInspiral() tmplt.process_id = proc_id index = 0 for value in values: if value is 'skip': continue setattr(tmplt, param_names[index], value) index += 1 sngl_inspiral_table.append(tmplt) # write the xml doc to disk proctable = table.get_table(outdoc, lsctables.ProcessTable.tableName) outname = 'table.xml' ligolw_utils.write_filename(outdoc, outname)
def calculate_faithfulness(m1, m2, s1x=0, s1y=0, s1z=0, s2x=0, s2y=0, s2z=0, tc=0, phic=0, ra=0, dec=0, polarization=0, signal_approx='IMRPhenomD', signal_file=None, tmplt_approx='IMRPhenomC', tmplt_file=None, aligned_spin_tmplt_only=True, non_spin_tmplt_only=False, f_lower=15.0, sample_rate=4096, signal_duration=256, psd_string='aLIGOZeroDetHighPower', verbose=True, debug=False): """ Calculates the match for a signal of given physical parameters, as modelled by a given signal approximant, against templates of another approximant. This function allows turning off x,y components of spin for templates. IN PROGRESS: Adding facility to use "FromDataFile" waveforms """ # {{{ # 0) OPTION CHECKING if aligned_spin_tmplt_only: print( "WARNING: Spin components parallel to L allowed, others set to 0 in templates.") # 1) GENERATE FILTERING META-PARAMETERS filter_N = signal_duration * sample_rate filter_n = filter_N / 2 + 1 delta_t = 1./sample_rate delta_f = 1./signal_duration # LIGO Noise PSD psd = from_string(psd_string, filter_n, delta_f, f_lower) # 2) GENERATE THE TARGET SIGNAL # Get the signal waveform first if signal_approx in pywf.fd_approximants(): generator = pywfg.FDomainDetFrameGenerator(pywfg.FDomainCBCGenerator, 0, variable_args=['mass1', 'mass2', 'spin1x', 'spin1y', 'spin1z', 'spin2x', 'spin2y', 'spin2z', 'coa_phase', 'tc', 'ra', 'dec', 'polarization'], detectors=['H1'], delta_f=delta_f, f_lower=f_lower, approximant=signal_approx) elif signal_approx in pywf.td_approximants(): generator = pywfg.TDomainDetFrameGenerator(pywfg.TDomainCBCGenerator, 0, variable_args=['mass1', 'mass2', 'spin1x', 'spin1y', 'spin1z', 'spin2x', 'spin2y', 'spin2z', 'coa_phase', 'tc', 'ra', 'dec', 'polarization'], detectors=['H1'], delta_t=delta_t, f_lower=f_lower, approximant=signal_approx) elif 'FromDataFile' in signal_approx: if os.path.getsize(signal_file) == 0: raise RuntimeError( " ERROR:...OOPS. Waveform file %s empty!!" % signal_file) try: _ = np.loadtxt(signal_file) except: raise RuntimeError( " WARNING: FAILURE READING DATA FROM %s.." % signal_file) waveform_params = lsctables.SimInspiral() waveform_params.latitude = 0 waveform_params.longitude = 0 waveform_params.polarization = 0 waveform_params.spin1x = 0 waveform_params.spin1y = 0 waveform_params.spin1z = 0 waveform_params.spin2x = 0 waveform_params.spin2y = 0 waveform_params.spin2z = 0 # try: if True: if verbose: print(".. generating signal waveform ") signal_htilde, _params = get_waveform(signal_approx, -1, -1, -1, waveform_params, f_lower, sample_rate, filter_N, datafile=signal_file) print(".. generated signal waveform ") m1, m2, w_value, _ = _params waveform_params.mass1 = m1 waveform_params.mass2 = m2 signal_h = make_frequency_series(signal_htilde) signal_h = extend_waveform_FrequencySeries(signal_h, filter_n) # except: raise IOError("Approximant %s not found.." % signal_approx) else: raise IOError("Signal Approximant %s not found.." % signal_approx) if verbose: print("..Generating signal with masses = %3f, %.3f, spin1 = (%.3f, %.3f, %.3f), and spin2 = (%.3f, %.3f, %.3f)" % (m1, m2, s1x, s1y, s1z, s2x, s2y, s2z)) sys.stdout.flush() if signal_approx in pywf.fd_approximants(): signal = generator.generate_from_args(m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, phic, tc, ra, dec, polarization) # NOTE: SEOBNRv4 has extra high frequency content, it seems.. if 'SEOBNRv4_ROM' in signal_approx or 'SEOBNRv2_ROM' in signal_approx: signal_h = extend_waveform_FrequencySeries( signal['H1'], filter_n, force_fit=True) else: signal_h = extend_waveform_FrequencySeries(signal['H1'], filter_n) elif signal_approx in pywf.td_approximants(): signal = generator.generate_from_args(m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, phic, tc, ra, dec, polarization) signal_h = make_frequency_series(signal['H1']) signal_h = extend_waveform_FrequencySeries(signal_h, filter_n) elif 'FromDataFile' in signal_approx: pass else: raise IOError("Signal Approximant %s not found.." % signal_approx) # 3) GENERATE THE TARGET TEMPLATE # Get the signal waveform first if tmplt_approx in pywf.fd_approximants(): generator = pywfg.FDomainDetFrameGenerator(pywfg.FDomainCBCGenerator, 0, variable_args=['mass1', 'mass2', 'spin1x', 'spin1y', 'spin1z', 'spin2x', 'spin2y', 'spin2z', 'coa_phase', 'tc', 'ra', 'dec', 'polarization'], detectors=['H1'], delta_f=delta_f, f_lower=f_lower, approximant=tmplt_approx) elif tmplt_approx in pywf.td_approximants(): generator = pywfg.TDomainDetFrameGenerator(pywfg.TDomainCBCGenerator, 0, variable_args=['mass1', 'mass2', 'spin1x', 'spin1y', 'spin1z', 'spin2x', 'spin2y', 'spin2z', 'coa_phase', 'tc', 'ra', 'dec', 'polarization'], detectors=['H1'], delta_t=delta_t, f_lower=f_lower, approximant=tmplt_approx) elif 'FromDataFile' in tmplt_approx: if os.path.getsize(tmplt_file) == 0: raise RuntimeError( " ERROR:...OOPS. Waveform file %s empty!!" % tmplt_file) try: _ = np.loadtxt(tmplt_file) except: raise RuntimeError( " WARNING: FAILURE READING DATA FROM %s.." % tmplt_file) waveform_params = lsctables.SimInspiral() waveform_params.latitude = 0 waveform_params.longitude = 0 waveform_params.polarization = 0 waveform_params.spin1x = 0 waveform_params.spin1y = 0 waveform_params.spin1z = 0 waveform_params.spin2x = 0 waveform_params.spin2y = 0 waveform_params.spin2z = 0 # try: if True: if verbose: print(".. generating signal waveform ") tmplt_htilde, _params = get_waveform(tmplt_approx, -1, -1, -1, waveform_params, f_lower, 1./delta_t, filter_N, datafile=tmplt_file) print(".. generated signal waveform ") m1, m2, w_value, _ = _params waveform_params.mass1 = m1 waveform_params.mass2 = m2 tmplt_h = make_frequency_series(tmplt_htilde) tmplt_h = extend_waveform_FrequencySeries(tmplt_h, filter_n) # except: raise IOError("Approximant %s not found.." % tmplt_approx) else: raise IOError("Template Approximant %s not found.." % tmplt_approx) # if aligned_spin_tmplt_only: _m1, _m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z = m1, m2, 0, 0, s1z, 0, 0, s2z elif non_spin_tmplt_only: _m1, _m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z = m1, m2, 0, 0, 0, 0, 0, 0 else: _m1, _m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z = m1, m2, s1x, s1y, s1z, s2x, s2y, s2z # # template = generator.generate_from_args(_m1, _m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z,\ # phic, tc, ra, dec, polarization) # if verbose: print( "..Generating template with masses = %3f, %.3f, spin1 = (%.3f, %.3f, %.3f), and spin2 = (%.3f, %.3f, %.3f)" % (_m1, _m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z)) sys.stdout.flush() if tmplt_approx in pywf.fd_approximants(): try: template = generator.generate_from_args(_m1, _m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z, phic, tc, ra, dec, polarization) except RuntimeError as rerr: print("""FAILED TO GENERATE %s waveform for masses = %.3f, %.3f spins = (%.3f, %.3f, %.3f), (%.3f, %.3f, %.3f) phic, tc, ra, dec, pol = (%.3f, %.3f, %.3f, %.3f, %.3f)""" % (tmplt_approx, _m1, _m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z, phic, tc, ra, dec, polarization)) raise RuntimeError(rerr) # NOTE: SEOBNRv4 has extra high frequency content, it seems.. if 'SEOBNRv4_ROM' in tmplt_approx or 'SEOBNRv2_ROM' in tmplt_approx: template_h = extend_waveform_FrequencySeries( template['H1'], filter_n, force_fit=True) else: template_h = extend_waveform_FrequencySeries( template['H1'], filter_n) elif tmplt_approx in pywf.td_approximants(): try: template = generator.generate_from_args(_m1, _m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z, phic, tc, ra, dec, polarization) except RuntimeError as rerr: print("""FAILED TO GENERATE %s waveform for masses = %.3f, %.3f spins = (%.3f, %.3f, %.3f), (%.3f, %.3f, %.3f) phic, tc, ra, dec, pol = (%.3f, %.3f, %.3f, %.3f, %.3f)""" % (tmplt_approx, _m1, _m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z, phic, tc, ra, dec, polarization)) raise RuntimeError(rerr) template_h = make_frequency_series(template['H1']) template_h = extend_waveform_FrequencySeries(template_h, filter_n) elif 'FromDataFile' in tmplt_approx: pass else: raise IOError("Template Approximant %s not found.." % tmplt_approx) # 4) COMPUTE MATCH m, idx = match(signal_h, template_h, psd=psd, low_frequency_cutoff=f_lower) if debug: print( "MATCH IS %.6f for parameters" % m, m1, m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z) sys.stderr.flush() # # 5) RETURN OPTIMIZED MATCH return m, idx
def frominjectionfile(file, type, ifo=None, start=None, end=None): """ Read generic injection file object file containing injections of the given type string. Returns an 'Sim' lsctable of the corresponding type. Arguments: file : file object type : [ "inspiral" | "burst" | "ringdown" ] Keyword arguments: ifo : [ "G1" | "H1" | "H2" | "L1" | "V1" ] """ # read type type = type.lower() # read injection xml xml = re.compile('(xml$|xml.gz$)') if re.search(xml,file.name): xmldoc,digest = utils.load_fileobj(file) injtable = table.get_table(xmldoc,'sim_%s:table' % (type)) # read injection txt else: cchar = re.compile('[#%<!()_\[\]{}:;\'\"]+') #== construct new Sim{Burst,Inspiral,Ringdown}Table injtable = lsctables.New(lsctables.__dict__['Sim%sTable' % (type.title())]) if type=='inspiral': columns = ['geocent_end_time.geocent_end_time_ns',\ 'h_end_time.h_end_time_ns',\ 'l_end_time.l_end_time_ns',\ 'v_end_time.v_end_time_ns',\ 'distance'] for line in file.readlines(): if re.match(cchar,line): continue # set up siminspiral object inj = lsctables.SimInspiral() # split data sep = re.compile('[\s,=]+') data = sep.split(line) # set attributes inj.geocent_end_time = int(data[0].split('.')[0]) inj.geocent_end_time_ns = int(data[0].split('.')[1]) inj.h_end_time = int(data[1].split('.')[0]) inj.h_end_time_ns = int(data[1].split('.')[1]) inj.l_end_time = int(data[2].split('.')[0]) inj.l_end_time_ns = int(data[2].split('.')[1]) inj.v_end_time = int(data[3].split('.')[0]) inj.v_end_time_ns = int(data[3].split('.')[1]) inj.distance = float(data[4]) injtable.append(inj) if type=='burst': if file.readlines()[0].startswith('filestart'): # if given parsed burst file file.seek(0) snrcol = { 'G1':23, 'H1':19, 'L1':21, 'V1':25 } for line in file.readlines(): inj = lsctables.SimBurst() # split data sep = re.compile('[\s,=]+') data = sep.split(line) # set attributes # gps time if 'burstgps' in data: idx = data.index('burstgps')+1 geocent = LIGOTimeGPS(data[idx]) inj.time_geocent_gps = geocent.seconds inj.time_geocent_gps_ns = geocent.nanoseconds else: continue #inj.waveform = data[4] #inj.waveform_number = int(data[5]) # frequency if 'freq' in data: idx = data.index('freq')+1 inj.frequency = float(data[idx]) else: continue # SNR a.k.a. amplitude if ifo and 'snr%s' % ifo in data: idx = data.index('snr%s' % ifo)+1 inj.amplitude = float(data[idx]) elif 'rmsSNR' in data: idx = data.index('rmsSNR')+1 inj.amplitude = float(data[idx]) else: continue if 'phi' in data: idx = data.index('phi' )+1 inj.ra = float(data[idx])*24/(2*math.pi) if 'theta' in data: idx = data.index('theta' )+1 inj.ra = 90-(float(data[idx])*180/math.pi) if ifo and 'hrss%s' % ifo in data: idx = data.index('hrss%s' % ifo)+1 inj.hrss = float(data[idx]) elif 'hrss' in data: idx = data.index('hrss')+1 inj.hrss = float(data[idx]) # extra columns to be added when I know how #inj.q = 0 #inj.q = float(data[11]) #h_delay = LIGOTimeGPS(data[41]) #inj.h_peak_time = inj.time_geocent_gps+h_delay.seconds #inj.h_peak_time_ns = inj.time_geocent_gps_ns+h_delay.nanoseconds #l_delay = LIGOTimeGPS(data[43]) #inj.l_peak_time = inj.time_geocent_gps+l_delay.seconds #inj.l_peak_time_ns = inj.time_geocent_gps_ns+l_delay.nanoseconds #v_delay = LIGOTimeGPS(data[43]) #inj.v_peak_time = inj.time_geocent_gps+v_delay.seconds #inj.v_peak_time_ns = inj.time_geocent_gps_ns+v_delay.nanoseconds injtable.append(inj) else: # if given parsed burst file file.seek(0) for line in file.readlines(): inj = lsctables.SimBurst() # split data sep = re.compile('[\s,]+') data = sep.split(line) # set attributes geocent = LIGOTimeGPS(data[0]) inj.time_geocent_gps = geocent.seconds inj.time_geocent_gps_ns = geocent.nanoseconds injtable.append(inj) injections = table.new_from_template(injtable) if not start: start = 0 if not end: end = 9999999999 span = segments.segmentlist([ segments.segment(start, end) ]) get_time = dqTriggerUtils.def_get_time(injections.tableName) injections.extend(inj for inj in injtable if get_time(inj) in span) return injections
def calculate_fitting_factor(m1, m2, s1x=0, s1y=0, s1z=0, s2x=0, s2y=0, s2z=0, tc=0, phic=0, ra=0, dec=0, polarization=0, signal_approx='IMRPhenomD', signal_file=None, tmplt_approx='IMRPhenomC', vary_masses_only=True, vary_masses_and_aligned_spin_only=False, chirp_mass_window=0.1, effective_spin_window=0.5, num_retries=4, f_lower=15.0, sample_rate=4096, signal_duration=256, psd_string='aLIGOZeroDetHighPower', pso_swarm_size=500, pso_omega=0.5, pso_phip=0.5, pso_phig=0.25, pso_minfunc=1e-8, verbose=True, debug=False): """ Calculates the fitting factor for a signal of given physical parameters, as modelled by a given signal approximant, against templates of another approximant. This function uses a particle swarm optimization to maximize the overlaps between signal and templates. Algorithm parameters are tunable, depending on how many dimensions we are optimizing over. IN PROGRESS: Adding facility to use "FromDataFile" waveforms """ # {{{ # 0) OPTION CHECKING if vary_masses_only: print("WARNING: Only component masses are allowed to be varied in templates. Setting the rest to signal values.") if vary_masses_and_aligned_spin_only: print("WARNING: Only component masses and spin components parallel to L allowed to be varied in templates. Setting the rest to signal values.") if vary_masses_only and vary_masses_and_aligned_spin_only: raise IOError( "Inconsistent options: vary_masses_only and vary_masses_and_aligned_spin_only") if (not vary_masses_only) and (not vary_masses_and_aligned_spin_only): print("WARNING: All mass and spin components varied in templates. Sky parameters still fixed to signal values.") # 1) GENERATE FILTERING META-PARAMETERS signal_duration = int(signal_duration) sample_rate = int(sample_rate) filter_N = signal_duration * sample_rate filter_n = filter_N / 2 + 1 delta_t = 1./sample_rate delta_f = 1./signal_duration if verbose: print("signal_duration = %d, sample_rate = %d, filter_N = %d, filter_n = %d" % ( signal_duration, sample_rate, filter_N, filter_n)) print("deltaT = %f, deltaF = %f" % (delta_t, delta_f)) # LIGO Noise PSD psd = from_string(psd_string, filter_n, delta_f, f_lower) # 2) GENERATE THE TARGET SIGNAL # PREPARATORY: Get the signal generator if signal_approx in pywf.fd_approximants(): generator = pywfg.FDomainDetFrameGenerator(pywfg.FDomainCBCGenerator, 0, variable_args=['mass1', 'mass2', 'spin1x', 'spin1y', 'spin1z', 'spin2x', 'spin2y', 'spin2z', 'coa_phase', 'tc', 'ra', 'dec', 'polarization'], detectors=['H1'], delta_f=delta_f, f_lower=f_lower, approximant=signal_approx) elif signal_approx in pywf.td_approximants(): generator = pywfg.TDomainDetFrameGenerator(pywfg.TDomainCBCGenerator, 0, variable_args=['mass1', 'mass2', 'spin1x', 'spin1y', 'spin1z', 'spin2x', 'spin2y', 'spin2z', 'coa_phase', 'tc', 'ra', 'dec', 'polarization'], detectors=['H1'], delta_t=delta_t, f_lower=f_lower, approximant=signal_approx) elif 'FromDataFile' in signal_approx: if os.path.getsize(signal_file) == 0: raise RuntimeError( " ERROR:...OOPS. Waveform file %s empty!!" % signal_file) try: _ = np.loadtxt(signal_file) except: raise RuntimeError( " WARNING: FAILURE READING DATA FROM %s.." % signal_file) waveform_params = lsctables.SimInspiral() waveform_params.latitude = 0 waveform_params.longitude = 0 waveform_params.polarization = 0 waveform_params.spin1x = 0 waveform_params.spin1y = 0 waveform_params.spin1z = 0 waveform_params.spin2x = 0 waveform_params.spin2y = 0 waveform_params.spin2z = 0 # try: if True: if verbose: print(".. generating signal waveform ") signal_htilde, _params = get_waveform(signal_approx, -1, -1, -1, waveform_params, f_lower, sample_rate, filter_N, datafile=signal_file) print(".. generated signal waveform ") m1, m2, w_value, _ = _params waveform_params.mass1 = m1 waveform_params.mass2 = m2 signal_h = make_frequency_series(signal_htilde) signal_h = extend_waveform_FrequencySeries(signal_h, filter_n) # except: raise IOError("Approximant %s not found.." % signal_approx) else: raise IOError("Approximant %s not found.." % signal_approx) if verbose: print( "\nGenerating signal with masses = %3f, %.3f, spin1 = (%.3f, %.3f, %.3f), and spin2 = (%.3f, %.3f, %.3f)" % (m1, m2, s1x, s1y, s1z, s2x, s2y, s2z)) sys.stdout.flush() # Actually GENERATE THE SIGNAL if signal_approx in pywf.fd_approximants(): signal = generator.generate_from_args(m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, phic, tc, ra, dec, polarization) signal_h = extend_waveform_FrequencySeries(signal['H1'], filter_n) elif signal_approx in pywf.td_approximants(): signal = generator.generate_from_args(m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, phic, tc, ra, dec, polarization) signal_h = make_frequency_series(signal['H1']) signal_h = extend_waveform_FrequencySeries(signal_h, filter_n) elif 'FromDataFile' in signal_approx: pass else: raise IOError("Approximant %s not found.." % signal_approx) ### # NOW : Set up PSO calculation of the optimal overlap parameter set, i.e. \theta(FF) ### # 3) INITIALIZE THE WAVEFORM GENERATOR FOR TEMPLATES # We allow all intrinsic parameters to vary, and fix them to the signal # values, in case only masses or only mass+aligned-spin components are # requested to be varied. This fixing is done inside the objective function. if tmplt_approx in pywf.fd_approximants(): generator_tmplt = pywfg.FDomainDetFrameGenerator(pywfg.FDomainCBCGenerator, 0, variable_args=['mass1', 'mass2', 'spin1x', 'spin1y', 'spin1z', 'spin2x', 'spin2y', 'spin2z' ], detectors=['H1'], coa_phase=phic, tc=tc, ra=ra, dec=dec, polarization=polarization, delta_f=delta_f, f_lower=f_lower, approximant=tmplt_approx) elif tmplt_approx in pywf.td_approximants(): raise IOError( "Time-domain templates not supported yet (TDomainDetFrameGenerator doesn't exist)") generator_tmplt = pywfg.TDomainDetFrameGenerator(pywfg.TDomainCBCGenerator, 0, variable_args=['mass1', 'mass2', 'spin1x', 'spin1y', 'spin1z', 'spin2x', 'spin2y', 'spin2z' ], detectors=['H1'], coa_phase=phic, tc=tc, ra=ra, dec=dec, polarization=polarization, delta_t=delta_t, f_lower=f_lower, approximant=tmplt_approx) elif 'FromDataFile' in tmplt_approx: raise RuntimeError( "Using **templates** from data files is not implemented yet") else: raise IOError("Approximant %s not found.." % tmplt_approx) # 4) DEFINE AN OBJECTIVE FUNCTION FOR PSO TO MINIMIZE def objective_function_fitting_factor(x, *args): """ This function is to be minimized if the fitting factor is to be found """ objective_function_fitting_factor.counter += 1 # 1) OBTAIN THE TEMPLATE PARAMETERS FROM X. ASSUME THAT ONLY # THOSE ARE PASSED THAT ARE NEEDED BY THE GENERATOR if len(x) == 2: m1, m2 = x if vary_masses_only: _s1x = _s1y = _s1z = _s2x = _s2y = _s2z = 0 else: _s1x, _s1y, _s1z = s1x, s1y, s1z _s2x, _s2y, _s2z = s2x, s2y, s2z elif len(x) == 4: m1, m2, _s1z, _s2z = x if vary_masses_and_aligned_spin_only: _s1x = _s1y = _s2x = _s2y = 0 else: _s1x, _s1y = s1x, s1y _s2x, _s2y = s2x, s2y elif len(x) == 8: m1, m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z = x else: raise IOError( "No of vars %d not supported (should be 2 or 4 or 8)" % len(x)) # 2) CHECK FOR CONSISTENCY if (_s1x**2 + _s1y**2 + _s1z**2) > s_max or (_s2x**2 + _s2y**2 + _s2z**2) > s_max: return 1e99 # 2) ASSUME THAT signal_h, tmplt_generator = args tmplt = tmplt_generator.generate_from_args( m1, m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z) tmplt_h = make_frequency_series(tmplt['H1']) if debug: print("IN FF Objective-> for parameters:", m1, m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z) if debug: print("IN FF Objective-> Length(tmplt) = %d, making it %d" % (len(tmplt['H1']), filter_n)) # NOTE: SEOBNRv4 has extra high frequency content, it seems.. if 'SEOBNRv4_ROM' in tmplt_approx or 'SEOBNRv2_ROM' in tmplt_approx: tmplt_h = extend_waveform_FrequencySeries( tmplt_h, filter_n, force_fit=True) else: tmplt_h = extend_waveform_FrequencySeries(tmplt_h, filter_n) # 3) COMPUTE MATCH m, _ = match(signal_h, tmplt_h, psd=psd, low_frequency_cutoff=f_lower) if debug: print("MATCH IS %.6f for parameters:" % m, m1, m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z) retval = np.log10(1. - m) # We do not want PSO to go berserk, so we stop when FF = 0.999999 if retval <= -6.0: retval = -6.0 return retval objective_function_fitting_factor.counter = 0 # 5) DEFINE A CONSTRAINT FUNCTION FOR PSO TO RESPECT def constraint_function_fitting_factor(x, *args): """ This function implements constraints on the optimization of fitting factors: 1) spin magnitudes on both holes should be <= 1 """ if len(x) == 2: m1, m2 = x s1x = s1y = s1z = s2x = s2y = s2z = 0 elif len(x) == 4: m1, m2, s1z, s2z = x s1x = s1y = s2x = s2y = 0 elif len(x) == 8: m1, m2, s1x, s1y, s1z, s2x, s2y, s2z = x # 1) Constraint on spin magnitudes s1_mag = (s1x**2 + s1y**2 + s1z**2)**0.5 s2_mag = (s2x**2 + s2y**2 + s2z**2)**0.5 ## if (s1_mag > s_max) or (s2_mag > s_max): return -1 # 2) Constraint on effective spin s_eff = (s1z * m1 + s2z * m2) / (m1 + m2) ## if (s_eff > s_eff_max) or (s_eff < s_eff_min): return -1 # FINALLY) DEFAULT return 1 # 6) FINALLY, CALL THE PSO TO COMPUTE THE FITTING FACTOR # 6a) FIRST CONSTRUCT THE FIXED ARGUMENTS FOR THE PSO's OBJECTIVE FUNCTION pso_args = (signal_h, generator_tmplt) # 6b) NOW SET THE RANGE OF PARAMETERS TO BE PROBED mt = m1 + m2 * 1.0 et = m1 * m2 / mt / mt mc = mt * et**0.6 mc_min = mc * (1.0 - chirp_mass_window) mc_max = mc * (1.0 + chirp_mass_window) et_max = 0.25 et_min = 10. / 121. # Lets say we trust waveform models up to q = 10 m1_max, _ = pnutils.mchirp_eta_to_mass1_mass2(mc_max, et_min) m1_min, _ = pnutils.mchirp_eta_to_mass1_mass2(mc_min, et_max) _, m2_max = pnutils.mchirp_eta_to_mass1_mass2(mc_max, et_max) _, m2_min = pnutils.mchirp_eta_to_mass1_mass2(mc_min, et_min) s_min = -0.99 s_max = +0.99 s_eff = (s1z * m1 + s2z * m2) / (m1 + m2) s_eff_min = s_eff - effective_spin_window s_eff_max = s_eff + effective_spin_window if verbose: print(m1, m2, mt, et, mc, mc_min, mc_max, et_min, et_max, m1_min, m1_max, m2_min, m2_max) if vary_masses_only: low_lim = [m1_min, m2_min] high_lim = [m1_max, m2_max] elif vary_masses_and_aligned_spin_only: low_lim = [m1_min, m2_min, s_min, s_min] high_lim = [m1_max, m2_max, s_max, s_max] else: low_lim = [m1_min, m2_min, s_min, s_min, s_min, s_min, s_min, s_min] high_lim = [m1_max, m2_max, s_max, s_max, s_max, s_max, s_max, s_max] # if verbose: print("\nSearching within limits:\n", low_lim, " and \n", high_lim) print("\nCalculating overlap now..") sys.stdout.flush() olap, idx = calculate_faithfulness(m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, tc=tc, phic=phic, ra=ra, dec=dec, polarization=polarization, signal_approx=signal_approx, signal_file=signal_file, tmplt_approx=tmplt_approx, tmplt_file=None, aligned_spin_tmplt_only=vary_masses_and_aligned_spin_only, non_spin_tmplt_only=vary_masses_only, f_lower=f_lower, sample_rate=sample_rate, signal_duration=signal_duration, verbose=verbose, debug=debug) # if verbose: print("Overlap with aligned_spin_tmplt_only = ", vary_masses_and_aligned_spin_only, " and non_spin_tmplt_only = ", vary_masses_only, ": ", olap, np.log10( 1. - olap)) sys.stdout.flush() # idx = 1 ff = 0.0 while ff < olap: if idx and idx % 2 == 0: pso_minfunc *= 0.1 pso_phig *= 1.1 if idx > num_retries: print( "WARNING: Failed to improve on overlap in %d iterations. Set ff = olap now" % num_retries) ff = olap break if verbose: print("\nTry %d to compute fitting factor" % idx) sys.stdout.flush() params, ff = pso(objective_function_fitting_factor, low_lim, high_lim, f_ieqcons=constraint_function_fitting_factor, args=pso_args, swarmsize=pso_swarm_size, omega=pso_omega, phip=pso_phip, phig=pso_phig, minfunc=pso_minfunc, maxiter=500, debug=verbose) # Restore fitting factor from 1-ff ff = 1.0 - 10**ff if verbose: print("\nLoop will continue till %.12f < %.12f" % (ff, olap)) sys.stdout.flush() idx += 1 if verbose: print("optimization took %d objective func evals" % objective_function_fitting_factor.counter) sys.stdout.flush() # # 7) RETURN OPTIMIZED PARAMETERS return [params, olap, ff]
# Prepare xml document xmldoc = ligolw.Document() xmldoc.appendChild(ligolw.LIGO_LW()) proc_id = ligolw_process.register_to_xmldoc\ (xmldoc, "nr_catalog", args.__dict__, comment="", version=lalapps.git_version.version, cvs_repository='lalsuite/' + lalapps.git_version.branch, cvs_entry_time=lalapps.git_version.date).process_id sim_table = lsctables.New(lsctables.SimInspiralTable) inj_list = args.inputs for count, inj in enumerate(inj_list): curr_sim = lsctables.SimInspiral() # Add the empty columns fill_missing_columns(curr_sim) # Set id columns curr_sim.process_id = proc_id curr_sim.simulation_id = ilwd.ilwdchar("sim_inspiral:simulation_id:%d"\ %(count)) curr_sim.numrel_data = inj f = h5py.File(inj, 'r') curr_sim.eta = f.attrs['eta'] if curr_sim.eta > 0.25 and curr_sim.eta < 0.2501: curr_sim.eta = 0.25 # Populate spins columns with spins in LAL frame! Need to be # transformed from NR frame curr_sim.f_lower = f.attrs['f_lower_at_1MSUN'] f.close()
def new_row(tabletype): if tabletype == lsctables.SnglInspiralTable: return lsctables.SnglInspiral() if tabletype == lsctables.SimInspiralTable: return lsctables.SimInspiral() raise IOError("Input table type neither Sim or Sngl Inspiral")
eta = q / (1. + q)**2 mchirp = mtotal * eta**0.6 m1, m2 = mchirp_eta_to_m1_m2(mchirp, eta) if (mtotal <= mtotal_max) and (mtotal >= mtotal_min) and ( eta >= eta_min) and (eta <= eta_max) and (m1 > mass1_min) and ( m2 > mass2_min) and (m1 < mass1_max) and (m2 < mass2_max): return True else: print("sample mtotal = %f, q = %f REJECTED!" % (mtotal, q)) return False for i in np.arange(npoints): if i % 1000 == 0 and options.verbose: print("Point %d" % i, file=sys.stderr) smplpt = lsctables.SimInspiral() smplpt.process_id = proc_id # Using the field alpha as the index associated with the point. This value # remains the same, even if these points get split up between jobs smplpt.bandpass = i smplpt.alpha = i smplpt.alpha1 = sample_range(ecc_min, ecc_max) smplpt.alpha2 = sample_range(anom_min, anom_max) # Get the masses if options.sample_m1_m2: if options.mass1 is not None: smplpt.mass1 = options.mass1
def get_new_sample_point(): """This function returns an instance of lsctables.SimInspiral, with elements corresponding to various physical parameters uniformly sampled within their respective ranges. """ p = lsctables.SimInspiral() p.alpha = -1 p.alpha1 = -1 p.alpha2 = -1 p.eta, chi = sample_eta_chi() p.spin1z = chi p.spin2z = chi # Get the allowed range of mchirp for this eta #q = (0.5/p.eta) * (1. + sqrt(1. - 4.*p.eta)) - 1. mtot_max = mtotal_max #mass_max * (1. + (1./q) ) mtot_min = 1.5581 * chi**2 + 11.438 * chi + 63.875 mtot = sample_bound(mtot_min, mtot_max) p.mchirp = mtot * p.eta**0.6 p.mass1, p.mass2 = mchirp_eta_to_mass1_mass2(p.mchirp, p.eta) #mchirp_max = (mtot_max) * p.eta**0.6 #mchirp_min = -63.5 * p.eta**2 + 65.9 * p.eta + 19.7 - 0.50 #p.mchirp = sample_bound(mchirp_min,mchirp_max) #tm1,tm2 = qm.mchirp_eta_to_m1_m2(p.mchirp,p.eta) # Just in case the values fall outside the bank's range #while (tm1 < mass_min) or (tm1 > mass_max) or (tm2 < mass_min) or (tm2 > mass_max): # p.eta = sample_eta() # p.mchirp = sample_bound(mchirp_min,mchirp_max) # tm1,tm2 = qm.mchirp_eta_to_m1_m2(p.mchirp,p.eta) #p.eta = eta #p.mass1 = m1 #p.mass2 = m2 #tm1 = sample_mass() #tm2 = sample_mass() #p.mass1 = max( tm1, tm2 ) #p.mass2 = min( tm1, tm2 ) #p.mchirp, p.eta = qm.m1_m2_to_mchirp_eta( p.mass1, p.mass2 ) #while not accept_point( p.mchirp, p.eta ): # tm1 = sample_mass() # tm2 = sample_mass() # p.mass1 = max( tm1, tm2 ) # p.mass2 = min( tm1, tm2 ) # p.mchirp, p.eta = qm.m1_m2_to_mchirp_eta( p.mass1, p.mass2 ) p.spin1x = 0. #sample_sxyz() p.spin1y = 0. #sample_sxyz() #p.spin1z = sample_sxyz() #smag = np.sqrt( p.spin1x**2. + p.spin1y**2. + p.spin1z**2. ) #if smag: # newsmag = sample_smag() # p.spin1x *= (newsmag/smag) # p.spin1y *= (newsmag/smag) # p.spin1z *= (newsmag/smag) p.spin2x = 0. #sample_sxyz() p.spin2y = 0. #sample_sxyz() #p.spin2z = sample_sxyz() #smag = np.sqrt( p.spin2x**2. + p.spin2y**2. + p.spin2z**2. ) #if smag: # newsmag = sample_smag() # p.spin2x *= (newsmag/smag) # p.spin2y *= (newsmag/smag) # p.spin2z *= (newsmag/smag) p.inclination = sample_inc() p.polarization = sample_pol() p.latitude = 0. p.longitude = 0. return p