def _is_gwpy_data_good(start_time, end_time, det): """Check if start-end time is a period when the IFO has quality data. Check passes if the IFO has quality data during the time period provided. Note: we are using the DMT-SCIENCE channel to check the quality. https://labcit.ligo.caltech.edu/~jzweizig/talks/LSC-2009-06-03/DMT-DQ_Stat-2009-06-03.pdf This method is slow as it queries GWpy. Parameters ---------- start_time, end_time: float GPS start and end time of required data. det: str The string key that represents the detector ("H1", "L1", etc) Returns ------- True: if data is good (IFO has quality data during entire duration). False: if data is bad (IFO does not have quality data during entire duration). None: if the data quality check failed """ # Create data quality flag channel_num = 1 quality_flag = f"{det}:DMT-SCIENCE:{channel_num}" logger.info( f"Checking data quality {quality_flag} {start_time}-{end_time}") try: flag = gwpy.segments.DataQualityFlag.query( quality_flag, gwpy.time.to_gps(start_time), gwpy.time.to_gps(end_time)) # compare active duration from quality flag and total duration total_duration = end_time - start_time active_duration = float(flag.livetime) inactive_duration = total_duration - active_duration # data is not good if there is any period when the IFO is inactive if inactive_duration > 0: data_is_good = False logger.warning( "Data quality check: FAILED. \n" "{det} does not have quality data for " "{inactive_duration}s out of {total_duration}s".format( det=det, inactive_duration=inactive_duration, total_duration=total_duration, )) else: data_is_good = True logger.info("Data quality check: PASSED.") except Exception as e: logger.warning(f"Error in Data Quality Check: {e}.") data_is_good = None return data_is_good
def psd_start_time(self, psd_start_time): if psd_start_time is None: self._psd_start_time = None else: self._psd_start_time = psd_start_time logger.info( "PSD start-time set to {} relative to segment start time". format(self._psd_start_time))
def __get_psd_data(self, det): # psd_start_time is given relative to the segment start time # so here we calculate the actual start time actual_psd_start_time = self.start_time + self.psd_start_time actual_psd_end_time = actual_psd_start_time + self.psd_duration logger.info(f"Getting psd-segment data for {det}") psd_data = self._get_data(det, self.get_channel_type(det), actual_psd_start_time, actual_psd_end_time) return psd_data
def main(): """ Data generation main logic """ args, unknown_args = parse_args(sys.argv[1:], create_generation_parser()) log_version_information() data = DataGenerationInput(args, unknown_args) if args.likelihood_type == "ROQGravitationalWaveTransient": data.save_roq_weights() data.save_data_dump() logger.info("Completed data generation")
def print_detector_information(interferometers): for ifo in interferometers: logger.info( "{}: sampling-frequency={}, segment-start-time={}, duration={}".format( ifo.name, ifo.strain_data.sampling_frequency, ifo.strain_data.start_time, ifo.strain_data.duration, ) )
def save_roq_weights(self): logger.info( "Using ROQ likelihood with roq-folder={} and roq-scale-factor={}". format(self.roq_folder, self.roq_scale_factor)) params = np.genfromtxt(self.roq_folder + "/params.dat", names=True) freq_nodes_linear = np.load(self.roq_folder + "/fnodes_linear.npy") freq_nodes_quadratic = np.load(self.roq_folder + "/fnodes_quadratic.npy") freq_nodes_linear *= self.roq_scale_factor freq_nodes_quadratic *= self.roq_scale_factor basis_matrix_linear = np.load(self.roq_folder + "/B_linear.npy").T basis_matrix_quadratic = np.load(self.roq_folder + "/B_quadratic.npy").T waveform_arguments = self.get_default_waveform_arguments() waveform_arguments["frequency_nodes_linear"] = freq_nodes_linear waveform_arguments["frequency_nodes_quadratic"] = freq_nodes_quadratic waveform_generator = self.waveform_generator_class( sampling_frequency=self.interferometers.sampling_frequency, duration=self.interferometers.duration, frequency_domain_source_model=self. bilby_roq_frequency_domain_source_model, parameter_conversion=self.parameter_conversion, start_time=self.interferometers.start_time, waveform_arguments=waveform_arguments, ) likelihood = bilby.gw.likelihood.ROQGravitationalWaveTransient( interferometers=self.interferometers, priors=self.priors, roq_params=params, roq_scale_factor=self.roq_scale_factor, waveform_generator=waveform_generator, linear_matrix=basis_matrix_linear, quadratic_matrix=basis_matrix_quadratic, reference_frame=self.reference_frame, time_reference=self.time_reference, weights=self.roq_weights, ) del basis_matrix_linear, basis_matrix_quadratic if self.injection_parameters is not None: likelihood.parameters.update(self.injection_parameters) logger.info("ROQ likelihood at injection values = " "{}".format(likelihood.log_likelihood_ratio())) weight_file = os.path.join(self.data_directory, self.label + "_roq_weights.npz") self.meta_data["weight_file"] = weight_file likelihood.save_weights(weight_file)
def __plot_ifo_data(self, det, strain_data, psd_strain_data=None): """Method to plot an IFO's data. Parameters ---------- det: str The detector name corresponding to the key in data-dict strain_data, psd_strain_data: gwpy.TimeSeries The timeseries strain data of a detector. Returns ------- None File by the name `<outdir>/data/<det>_<Label>_D{duration}_data.png` is saved """ if psd_strain_data is None: logger.info("Unable to plot the IFO data without the PSD data") return else: plot_psd = True plot_kwargs = dict( det=det, data_directory=self.data_directory, trigger_time=self.trigger_time, duration=self.duration, post_trigger_duration=self.post_trigger_duration, label=self.label, ) time = [ strain_data.t0.value, strain_data.t0.value + strain_data.duration.value ] psd_time = [ psd_strain_data.t0.value, psd_strain_data.t0.value + psd_strain_data.duration.value, ] # plot PSD if plot_psd: strain_spectogram_plot( data=psd_strain_data, extra_label=f"D{int(psd_time[1] - psd_time[0])}", **plot_kwargs, ) # plot psd_strain_data+strain_data and zoom into strain_data segment data_with_psd = psd_strain_data.append(strain_data, inplace=False) strain_spectogram_plot(data=data_with_psd, extra_label=f"D{int(time[1] - time[0])}", **plot_kwargs)
def sampling_seed(self, sampling_seed): if sampling_seed is None: sampling_seed = np.random.randint(1, 1e6) self._samplng_seed = sampling_seed np.random.seed(sampling_seed) logger.info(f"Sampling seed set to {sampling_seed}") if self.sampler == "cpnest": self.sampler_kwargs["seed"] = self.sampler_kwargs.get( "seed", self._samplng_seed )
def psd_start_time(self): """ The PSD start time relative to segment start time """ if self._psd_start_time is not None: return self._psd_start_time elif self.trigger_time is not None: psd_start_time = -self.psd_duration logger.info( f"Using default PSD start time {psd_start_time} relative to start time" ) return psd_start_time else: raise BilbyPipeError("PSD start time not set")
def interferometers(self): try: return self._interferometers except AttributeError: ifos = self.data_dump.interferometers names = [ifo.name for ifo in ifos] logger.info(f"Found data for detectors = {names}") ifos_to_use = [ifo for ifo in ifos if ifo.name in self.detectors] names_to_use = [ifo.name for ifo in ifos_to_use] logger.info(f"Using data for detectors = {names_to_use}") self._interferometers = bilby.gw.detector.InterferometerList(ifos_to_use) self.print_detector_information(self._interferometers) return self._interferometers
def __generate_psd(self, psd_data, roll_off): """Create the psd from strain data.""" psd_alpha = 2 * roll_off / self.duration overlap = self.psd_fractional_overlap * self.duration logger.info("PSD settings: window=Tukey, Tukey-alpha={} roll-off={}," " overlap={}, method={}".format(psd_alpha, roll_off, overlap, self.psd_method)) psd = psd_data.psd( fftlength=self.duration, overlap=overlap, window=("tukey", psd_alpha), method=self.psd_method, ) return psd
def psd_duration(self, psd_duration): MAXIMUM = self.psd_maximum_duration if psd_duration <= MAXIMUM: self._psd_duration = psd_duration logger.info("PSD duration set to {}s, {}x the duration {}s".format( psd_duration, self.psd_length, self.duration)) else: self._psd_duration = MAXIMUM logger.info( "Requested PSD duration {}={}x{} exceeds allowed maximum {}" ". Setting psd_duration = {}".format( psd_duration, self.psd_length, self.duration, MAXIMUM, self.psd_duration, ))
def _set_interferometers_from_data(self): """ Method to generate the interferometers data from data This sets the PSD before the analysis data so that the SNR of injected signals is correct. """ end_time = self.start_time + self.duration roll_off = self.tukey_roll_off if 2 * roll_off > self.duration: raise ValueError( "2 * tukey-roll-off is longer than segment duration.") ifo_list = [] for det in self.detectors: ifo = bilby.gw.detector.get_empty_interferometer(det) ifo.strain_data.roll_off = roll_off if self.psd_dict is not None and det in self.psd_dict: psd_data = None self._set_psd_from_file(ifo) else: logger.info(f"Setting PSD for {det} from data") psd_data = self.__get_psd_data(det) psd = self.__generate_psd(psd_data, roll_off) ifo.power_spectral_density = PowerSpectralDensity( frequency_array=psd.frequencies.value, psd_array=psd.value) logger.info(f"Getting analysis-segment data for {det}") data = self._get_data(det, self.get_channel_type(det), self.start_time, end_time) if self.injection: data = self.inject_signal_into_time_domain_data(data, ifo) ifo.strain_data.set_from_gwpy_timeseries(data) if self.create_plots: self.__plot_ifo_data(det, strain_data=data, psd_strain_data=psd_data) ifo_list.append(ifo) self.interferometers = bilby.gw.detector.InterferometerList(ifo_list)
def _set_interferometers_from_injection_in_gaussian_noise(self): """ Method to generate the interferometers data from an injection in Gaussian noise """ self.injection_parameters = self.injection_df.iloc[self.idx].to_dict() logger.info("Injecting waveform with ") for prop in [ "minimum_frequency", "maximum_frequency", "trigger_time", "start_time", "duration", ]: logger.info(f"{prop} = {getattr(self, prop)}") self._set_interferometers_from_gaussian_noise() waveform_arguments = self.get_injection_waveform_arguments() logger.info(f"Using waveform arguments: {waveform_arguments}") waveform_generator = self.waveform_generator_class( duration=self.duration, start_time=self.start_time, sampling_frequency=self.sampling_frequency, frequency_domain_source_model=self. bilby_frequency_domain_source_model, parameter_conversion=self.parameter_conversion, waveform_arguments=waveform_arguments, ) self.interferometers.inject_signal( waveform_generator=waveform_generator, parameters=self.injection_parameters)
def _gwpy_get(self, channel, start_time, end_time, dtype="float64"): """Wrapper function to gwpy.timeseries.TimeSeries.get() Parameters ---------- channel: str The name of the channel to read, e.g. 'L1:GDS-CALIB_STRAIN' start_time, end_time: float GPS start and end time of required data dtype: str or np.dtype Data type requested Returns ------- data: TimeSeries If successful, the data, otherwise None is returned """ logger.debug("Attempt to locate data") logger.info( "Calling TimeSeries.get('{}', start={}, end={}, dtype='{}')". format(channel, start_time, end_time, dtype)) if self.data_format: kwargs = dict(format=self.data_format) logger.info(f"Extra kwargs passed to get(): {kwargs}") else: kwargs = dict() try: data = gwpy.timeseries.TimeSeries.get(channel, start_time, end_time, verbose=False, dtype=dtype, **kwargs) return data except RuntimeError as e: logger.info(f"Unable to read data for channel {channel}") logger.debug(f"Error message {e}") except ImportError: logger.info("Unable to read data as NDS2 is not installed") except TypeError: logger.debug("Problem reading data try again without kwargs") data = gwpy.timeseries.TimeSeries.get(channel, start_time, end_time, verbose=False, dtype=dtype) return data
def generation_seed(self, generation_seed): """Sets the generation seed. If no generation seed has been provided, a random seed between 1 and 1e6 is selected. If a seed is provided, it is used as the base seed and all generation jobs will have their seeds set as {generation_seed = base_seed + job_idx}. NOTE: self.idx must not be None Parameters ---------- generation_seed: int or None """ if generation_seed is None: generation_seed = np.random.randint(1, 1e6) else: assert self.idx is not None generation_seed = generation_seed + self.idx self._generation_seed = generation_seed np.random.seed(generation_seed) logger.info(f"Generation seed set to {generation_seed}")
def _gwpy_fetch_open_data(self, det, start_time, end_time): """Wrapper function to gwpy.timeseries.TimeSeries.fetch_open_data() Parameters ---------- det: str The detector name, e.g 'H1' start_time, end_time: float GPS start and end time of required data Returns ------- data: TimeSeries If successful, the data, otherwise None is returned """ logger.info("Attempting to download data from GWOSC") logger.info( "Calling TimeSeries.fetch_open_data('{}', start={}, end={})". format(det, start_time, end_time)) data = gwpy.timeseries.TimeSeries.fetch_open_data( det, start_time, end_time) return data
def sighandler(signum, frame): logger.info("Performing periodic eviction") sys.exit(CHECKPOINT_EXIT_CODE)
def inject_signal_into_time_domain_data(self, data, ifo): """Method to inject a signal into time-domain interferometer data Parameters of the injection are obtained from the `injection_parameters` or the injection file (if injection_parameters has not been set). The geocent_time of the injection is set to be trigger_time +/- deltaT/2 if the geocent_time is not provided in the injection parameters. Parameters ---------- data: gwpy.timeseries.TimeSeries The data into which to inject the signal ifo: bilby.gw.detector.Interferometer The interferometer for which the data relates to Returns ------- data_and_signal: gwpy.timeseries.TimeSeries The data with the signal added """ # Get the injection parameters if self.injection_parameters is not None: parameters = self.injection_parameters else: parameters = self.injection_df.iloc[self.idx].to_dict() self.injection_parameters = parameters # Set the geocent time if none is provided if "geocent_time" not in parameters: parameters["geocent_time"] = get_geocent_time_with_uncertainty( geocent_time=self.trigger_time, uncertainty=self.deltaT / 2.0) waveform_arguments = self.get_injection_waveform_arguments() waveform_generator = self.waveform_generator_class( duration=self.duration, sampling_frequency=self.sampling_frequency, frequency_domain_source_model=self. bilby_frequency_domain_source_model, parameter_conversion=self.parameter_conversion, waveform_arguments=waveform_arguments, ) if self.create_plots: outdir = self.data_directory label = self.label else: outdir = None label = None logger.info(f"Injecting with {self.injection_waveform_approximant}") ( signal_and_data, meta_data, ) = bilby.gw.detector.inject_signal_into_gwpy_timeseries( data=data, waveform_generator=waveform_generator, parameters=parameters, det=ifo.name, outdir=outdir, label=label, ) ifo.meta_data = meta_data if self.create_plots: # Plots of before and after injection saved plot_kwargs = dict( det=ifo.name, data_directory=self.data_directory, trigger_time=self.trigger_time, duration=self.duration, post_trigger_duration=self.post_trigger_duration, label=self.label, ) strain_spectogram_plot(data=data, extra_label="before_injection", **plot_kwargs) strain_spectogram_plot(data=signal_and_data, extra_label="with_injection", **plot_kwargs) return signal_and_data
def _gwpy_read(self, det, channel, start_time, end_time, dtype="float64"): """Wrapper function to gwpy.timeseries.TimeSeries.read() Parameters ---------- det: str The detector name corresponding to the key in data-dict channel: str The name of the channel to read, e.g. 'L1:GDS-CALIB_STRAIN' start_time, end_time: float GPS start and end time of required data dtype: str or np.dtype Data type requested Returns ------- data: TimeSeries If successful, the data, otherwise None is returned """ logger.debug("data-dict provided, attempt read of data") if det not in self.data_dict: logger.info(f"Detector {det} not found in data-dict") return None else: source = self.data_dict[det] format_ext = os.path.splitext(source)[1] # If the source contains a glob-path, e.g. *gwf, glob it first if "*" in source: logger.info(f"Globbing {source}") source = glob.glob(source) logger.info(f"Setting source={source}") if "gwf" in format_ext: kwargs = dict(source=source, channel=channel, dtype=dtype, format="gwf.lalframe") elif "hdf5" in format_ext: kwargs = dict(source=source, start=start_time, end=end_time, format="hdf5") elif "txt" in format_ext: data = kwargs = dict(source=source) else: # Generic best try kwargs = dict(source=source, channel=channel, start=start_time, end=end_time) if self.data_format is not None: kwargs["format"] = self.data_format try: kwargs_string = "" for key, val in kwargs.items(): if isinstance(val, str): val = f"'{val}'" kwargs_string += f"{key}={val}, " logger.info( f"Running: gwpy.timeseries.TimeSeries.read({kwargs_string})") data = gwpy.timeseries.TimeSeries.read(**kwargs) data = data.crop(start=start_time, end=end_time) if data.duration.value < end_time - start_time: logger.warning( "Unable to read in requested {}s duration of data from {}" " only {}s available: returning None".format( end_time - start_time, source, data.duration.value)) data = None elif data.duration.value > end_time - start_time: logger.info( "Read in {}s of data from {}, but {}s requested, truncating" .format(data.duration.value, source, end_time - start_time)) data = data[data.times.value >= start_time] data = data[data.times.value < end_time] return data except ValueError as e: logger.info(f"Reading of data failed with error {e}") return None
def __init__(self, args, unknown_args, test=False): logger.info(f"Command line arguments: {args}") # Generic initialisation self.meta_data = dict() self.result = None # Admin arguments self.ini = args.ini self.scheduler = args.scheduler self.periodic_restart_time = args.periodic_restart_time self.request_cpus = args.request_cpus # Naming arguments self.outdir = args.outdir self.label = args.label # Data dump file to run on self.data_dump_file = args.data_dump_file # Choices for running self.detectors = args.detectors self.sampler = args.sampler self.sampler_kwargs = args.sampler_kwargs self.sampling_seed = args.sampling_seed # Frequencies self.sampling_frequency = args.sampling_frequency self.minimum_frequency = args.minimum_frequency self.maximum_frequency = args.maximum_frequency self.reference_frequency = args.reference_frequency # Waveform, source model and likelihood self.waveform_generator_class = args.waveform_generator self.waveform_approximant = args.waveform_approximant self.catch_waveform_errors = args.catch_waveform_errors self.pn_spin_order = args.pn_spin_order self.pn_tidal_order = args.pn_tidal_order self.pn_phase_order = args.pn_phase_order self.pn_amplitude_order = args.pn_amplitude_order self.mode_array = args.mode_array self.waveform_arguments_dict = args.waveform_arguments_dict self.numerical_relativity_file = args.numerical_relativity_file self.frequency_domain_source_model = args.frequency_domain_source_model self.likelihood_type = args.likelihood_type self.reference_frame = args.reference_frame self.time_reference = args.time_reference self.extra_likelihood_kwargs = args.extra_likelihood_kwargs # ROQ self.roq_folder = args.roq_folder self.roq_scale_factor = args.roq_scale_factor # Calibration self.calibration_model = args.calibration_model self.spline_calibration_nodes = args.spline_calibration_nodes self.spline_calibration_envelope_dict = args.spline_calibration_envelope_dict # Marginalization self.distance_marginalization = args.distance_marginalization self.distance_marginalization_lookup_table = None self.phase_marginalization = args.phase_marginalization self.time_marginalization = args.time_marginalization self.jitter_time = args.jitter_time # Prior conversions self.convert_to_flat_in_component_mass = args.convert_to_flat_in_component_mass if test is False: self._load_data_dump()
def _get_data(self, det, channel_type, start_time, end_time, resample=True): """Read in data using gwpy If the channel_type is "GWOSC", open data is obtained. Otherwise, we try to read in the data first using "read" if a data_dict exists and then using "get". Parameters ---------- channel_type: str The full channel name is formed from <det>:<channel_type>, see bilby_pipe --help for more information. start_time, end_time: float GPS start and end time of segment Returns ------- data: gwpy.timeseries.TimeSeries The loaded data Raises ------ BilbyPipeError: If there is an issue obtaining the data or with the data itself """ timeslide_val = None if hasattr(self, "timeslide_dict"): timeslide_val = self.timeslide_dict[det] start_time = start_time + timeslide_val end_time = end_time + timeslide_val logger.info( "Applying timeshift of {}. Time range {} - {} => {} - {}". format( timeslide_val, start_time - timeslide_val, end_time - timeslide_val, start_time, end_time, )) if self.ignore_gwpy_data_quality_check is False: data_is_good = self._is_gwpy_data_good(start_time, end_time, det) if not data_is_good: raise BilbyPipeError("Data quality is not good.") data = None if data is None and channel_type == "GWOSC": data = self._gwpy_fetch_open_data(det, start_time, end_time) channel = f"{det}:{channel_type}" if data is None and self.data_dict is not None: data = self._gwpy_read(det, channel, start_time, end_time) if data is None: data = self._gwpy_get(channel, start_time, end_time) if data is None: raise BilbyPipeError("Failed to obtain data") if np.all(data.value == 0): raise BilbyPipeError("Obtained data is all zeros") if resample and data.sample_rate.value == self.sampling_frequency: logger.info("Sample rate matches data no resampling") elif resample: message = "Resampling data to sampling_frequency {} using {}" if self.resampling_method == "gwpy": logger.info( message.format(self.sampling_frequency, self.resampling_method)) data = data.resample(self.sampling_frequency) elif self.resampling_method == "lal": logger.info( message.format(self.sampling_frequency, self.resampling_method)) try: lal_timeseries = data.to_lal() lal.ResampleREAL8TimeSeries( lal_timeseries, float(1 / self.sampling_frequency)) except Exception as e: raise BilbyPipeError( "The lal resampling method has failed with exception {} " "You may wish to try a different resampling method". format(e)) data = gwpy.timeseries.TimeSeries( lal_timeseries.data.data, epoch=lal_timeseries.epoch, dt=lal_timeseries.deltaT, ) else: logger.warning( "Resampling method {} not understood, should be " "'gwpy' or 'lal'.".format(self.resampling_method)) else: logger.info("No data resampling requested") if timeslide_val: # to match up the time axis for the interferometer network data.shift(-timeslide_val) return data
def _set_psd_from_file(self, ifo): psd_file = self.psd_dict[ifo.name] logger.info(f"Setting {ifo.name} PSD from file {psd_file}") ifo.power_spectral_density = ( PowerSpectralDensity.from_power_spectral_density_file( psd_file=psd_file))
def __init__(self, args, unknown_args, create_data=True): logger.info(f"Command line arguments: {args}") logger.info(f"Unknown command line arguments: {unknown_args}") # Generic initialisation self.meta_data = dict( command_line_args=args.__dict__, unknown_command_line_args=unknown_args, injection_parameters=None, bilby_version=bilby.__version__, bilby_pipe_version=get_version_information(), ) self.injection_parameters = None # Admin arguments self.ini = args.ini # Run index arguments self.idx = args.idx self.generation_seed = args.generation_seed self.trigger_time = args.trigger_time # Naming arguments self.outdir = args.outdir self.label = args.label # Prior arguments self.reference_frame = args.reference_frame self.time_reference = args.time_reference self.prior_file = args.prior_file self.prior_dict = args.prior_dict self.deltaT = args.deltaT self.default_prior = args.default_prior # Data arguments self.ignore_gwpy_data_quality_check = args.ignore_gwpy_data_quality_check self.detectors = args.detectors self.channel_dict = args.channel_dict self.data_dict = args.data_dict self.data_format = args.data_format self.tukey_roll_off = args.tukey_roll_off self.zero_noise = args.zero_noise self.resampling_method = args.resampling_method if args.timeslide_dict is not None: self.timeslide_dict = convert_string_to_dict(args.timeslide_dict) logger.info( f"Read-in timeslide dict directly: {self.timeslide_dict}") elif args.timeslide_file is not None: self.gps_file = args.gps_file self.timeslide_file = args.timeslide_file self.timeslide_dict = self.get_timeslide_dict(self.idx) # Data duration arguments self.duration = args.duration self.post_trigger_duration = args.post_trigger_duration # Frequencies self.sampling_frequency = args.sampling_frequency self.minimum_frequency = args.minimum_frequency self.maximum_frequency = args.maximum_frequency self.reference_frequency = args.reference_frequency # Waveform, source model and likelihood self.waveform_generator_class = args.waveform_generator self.waveform_approximant = args.waveform_approximant self.catch_waveform_errors = args.catch_waveform_errors self.pn_spin_order = args.pn_spin_order self.pn_tidal_order = args.pn_tidal_order self.pn_phase_order = args.pn_phase_order self.pn_amplitude_order = args.pn_amplitude_order self.mode_array = args.mode_array self.waveform_arguments_dict = args.waveform_arguments_dict self.numerical_relativity_file = args.numerical_relativity_file self.injection_waveform_approximant = args.injection_waveform_approximant self.frequency_domain_source_model = args.frequency_domain_source_model self.likelihood_type = args.likelihood_type self.extra_likelihood_kwargs = args.extra_likelihood_kwargs # PSD self.psd_maximum_duration = args.psd_maximum_duration self.psd_dict = args.psd_dict if self.psd_dict is None: self.psd_length = args.psd_length self.psd_fractional_overlap = args.psd_fractional_overlap self.psd_start_time = args.psd_start_time self.psd_method = args.psd_method # ROQ self.roq_folder = args.roq_folder self.roq_weights = args.roq_weights self.roq_scale_factor = args.roq_scale_factor # Calibration self.calibration_model = args.calibration_model self.spline_calibration_envelope_dict = args.spline_calibration_envelope_dict self.spline_calibration_amplitude_uncertainty_dict = ( args.spline_calibration_amplitude_uncertainty_dict) self.spline_calibration_phase_uncertainty_dict = ( args.spline_calibration_phase_uncertainty_dict) self.spline_calibration_nodes = args.spline_calibration_nodes # Marginalization self.distance_marginalization = args.distance_marginalization self.distance_marginalization_lookup_table = ( args.distance_marginalization_lookup_table) self.phase_marginalization = args.phase_marginalization self.time_marginalization = args.time_marginalization self.jitter_time = args.jitter_time # Plotting self.create_plots = args.create_plots if create_data: self.create_data(args)