def apply(self, strain, detector_name, f_lower=None, distance_scale=1, simulation_ids=None, inj_filter_rejector=None): """Add injections (as seen by a particular detector) to a time series. Parameters ---------- strain : TimeSeries Time series to inject signals into, of type float32 or float64. detector_name : string Name of the detector used for projecting injections. f_lower : {None, float}, optional Low-frequency cutoff for injected signals. If None, use value provided by each injection. distance_scale: {1, float}, optional Factor to scale the distance of an injection with. The default is no scaling. simulation_ids: iterable, optional If given, only inject signals with the given simulation IDs. inj_filter_rejector: InjFilterRejector instance; optional, default=None If given send each injected waveform to the InjFilterRejector instance so that it can store a reduced representation of that injection if necessary. Returns ------- None Raises ------ TypeError For invalid types of `strain`. """ if strain.dtype not in (float32, float64): raise TypeError("Strain dtype must be float32 or float64, not " \ + str(strain.dtype)) lalstrain = strain.lal() earth_travel_time = lal.REARTH_SI / lal.C_SI t0 = float(strain.start_time) - earth_travel_time t1 = float(strain.end_time) + earth_travel_time # pick lalsimulation injection function add_injection = injection_func_map[strain.dtype] injections = self.table if simulation_ids: injections = [inj for inj in injections \ if inj.simulation_id in simulation_ids] injection_parameters = [] for inj in injections: if f_lower is None: f_l = inj.f_lower else: f_l = f_lower # roughly estimate if the injection may overlap with the segment # Add 2s to end_time to account for ringdown and light-travel delay end_time = inj.get_time_geocent() + 2 inj_length = sim.SimInspiralTaylorLength(strain.delta_t, inj.mass1 * lal.MSUN_SI, inj.mass2 * lal.MSUN_SI, f_l, 0) # Start time is taken as twice approx waveform length with a 1s # safety buffer start_time = inj.get_time_geocent() - 2 * (inj_length + 1) if end_time < t0 or start_time > t1: continue signal = self.make_strain_from_inj_object( inj, strain.delta_t, detector_name, f_lower=f_l, distance_scale=distance_scale) if float(signal.start_time) > t1: continue signal = signal.astype(strain.dtype) signal_lal = signal.lal() add_injection(lalstrain, signal_lal, None) injection_parameters.append(inj) if inj_filter_rejector is not None: sid = inj.simulation_id inj_filter_rejector.generate_short_inj_from_inj(signal, sid) strain.data[:] = lalstrain.data.data[:] injected = copy.copy(self) injected.table = lsctables.SimInspiralTable() injected.table += injection_parameters if inj_filter_rejector is not None: inj_filter_rejector.injection_params = injected return injected
# # Load injection file and sort by chirp mass. Sorting injections by # chirp mass helps avoid memory usage going off the rails when using # waveform caching # xmldoc2 = utils.load_filename(inj_file, contenthandler=ContentHandler) ligolw_copy_process(xmldoc2, fake_xmldoc) sims = sorted(lsctables.SimInspiralTable.get_table(xmldoc2), key=lambda s: s.mchirp) # # Sometimes inspinj doesn't give us everything we want, so we give the # user a little extra control here over the injections acutally used. # FIXME: preprocess inj file in future to avoid this step # newtbl = lsctables.SimInspiralTable() noinjs = 0 for s in sims: # short-circuit this potentially slow code path if possible if len(newtbl) == opts.injection_max - opts.injection_min: break # start adding to table once we reach min injection requested # by user if opts.injection_min <= noinjs: if 1. / opts.mratio_max <= s.mass1 / s.mass2 <= opts.mratio_max and opts.mtotal_min <= s.mass1 + s.mass2 <= opts.mtotal_max and ( opts.duration_min == 0 or lalsim.SimIMRSEOBNRv4ROMTimeOfFrequency( opts.flow, s.mass1 * MSUN_SI, s.mass2 * MSUN_SI, s.spin1z, s.spin2z) > opts.duration_min):