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)