示例#1
0
 def test_can_convert_column_to_relative_scale_with_nans(self):
     light_curve = LightCurve()
     light_curve.data_frame = pd.DataFrame({'a': [1, 2, 3, np.nan]})
     light_curve.convert_column_to_relative_scale('a')
     light_curve_values = light_curve.data_frame['a'].values
     expected_values = np.array([0.5, 1, 1.5, np.nan])
     assert np.allclose(light_curve_values, expected_values, equal_nan=True)
示例#2
0
 def test_setting_fluxes_sets_existing_named_flux_column_if_one_exists(
         self):
     light_curve = LightCurve()
     light_curve.flux_column_names = ['flux_column']
     light_curve.fluxes = [0, 1]
     assert np.array_equal(light_curve.data_frame['flux_column'].values,
                           [0, 1])
示例#3
0
    def inject_signal_into_light_curve(self, light_curve_fluxes: np.ndarray, light_curve_times: np.ndarray,
                                       signal_magnifications: np.ndarray, signal_times: np.ndarray,
                                       wandb_loggable_injection: Optional[WandbLoggableInjection] = None) -> np.ndarray:
        """
        Injects a synthetic magnification signal into real light curve fluxes.

        :param light_curve_fluxes: The fluxes of the light curve to be injected into.
        :param light_curve_times: The times of the flux observations of the light curve.
        :param signal_magnifications: The synthetic magnifications to inject.
        :param signal_times: The times of the synthetic magnifications.
        :param wandb_loggable_injection: The object to log the injection process.
        :return: The fluxes with the injected signal.
        """
        minimum_light_curve_time = np.min(light_curve_times)
        relative_light_curve_times = light_curve_times - minimum_light_curve_time
        relative_signal_times = signal_times - np.min(signal_times)
        signal_time_length = np.max(relative_signal_times)
        light_curve_time_length = np.max(relative_light_curve_times)
        time_length_difference = light_curve_time_length - signal_time_length
        signal_start_offset = (np.random.random() * time_length_difference) + minimum_light_curve_time
        offset_signal_times = relative_signal_times + signal_start_offset
        if self.baseline_flux_estimation_method == BaselineFluxEstimationMethod.MEDIAN_ABSOLUTE_DEVIATION:
            baseline_flux = scipy.stats.median_abs_deviation(light_curve_fluxes)
            baseline_to_median_absolute_deviation_ratio = 10  # Arbitrarily chosen to give a reasonable scale.
            baseline_flux *= baseline_to_median_absolute_deviation_ratio
        else:
            baseline_flux = np.median(light_curve_fluxes)
        signal_fluxes = (signal_magnifications * baseline_flux) - baseline_flux
        if self.out_of_bounds_injection_handling is OutOfBoundsInjectionHandlingMethod.RANDOM_INJECTION_LOCATION:
            signal_flux_interpolator = interp1d(offset_signal_times, signal_fluxes, bounds_error=False, fill_value=0)
        elif (self.out_of_bounds_injection_handling is OutOfBoundsInjectionHandlingMethod.REPEAT_SIGNAL and
              time_length_difference > 0):
            before_signal_gap = signal_start_offset - minimum_light_curve_time
            after_signal_gap = time_length_difference - before_signal_gap
            minimum_signal_time_step = np.min(np.diff(offset_signal_times))
            before_repeats_needed = math.ceil(before_signal_gap / (signal_time_length + minimum_signal_time_step))
            after_repeats_needed = math.ceil(after_signal_gap / (signal_time_length + minimum_signal_time_step))
            repeated_signal_fluxes = np.tile(signal_fluxes, before_repeats_needed + 1 + after_repeats_needed)
            repeated_signal_times = None
            for repeat_index in range(-before_repeats_needed, after_repeats_needed + 1):
                repeat_signal_start_offset = (signal_time_length + minimum_signal_time_step) * repeat_index
                if repeated_signal_times is None:
                    repeated_signal_times = offset_signal_times + repeat_signal_start_offset
                else:
                    repeat_index_signal_times = offset_signal_times + repeat_signal_start_offset
                    repeated_signal_times = np.concatenate([repeated_signal_times, repeat_index_signal_times])
            signal_flux_interpolator = interp1d(repeated_signal_times, repeated_signal_fluxes, bounds_error=True)
        else:
            signal_flux_interpolator = interp1d(offset_signal_times, signal_fluxes, bounds_error=True)
        interpolated_signal_fluxes = signal_flux_interpolator(light_curve_times)
        fluxes_with_injected_signal = light_curve_fluxes + interpolated_signal_fluxes
        if wandb_loggable_injection is not None:
            wandb_loggable_injection.aligned_injectee_light_curve = LightCurve.from_times_and_fluxes(
                light_curve_times, light_curve_fluxes)
            wandb_loggable_injection.aligned_injectable_light_curve = LightCurve.from_times_and_fluxes(
                offset_signal_times, signal_fluxes)
            wandb_loggable_injection.aligned_injected_light_curve = LightCurve.from_times_and_fluxes(
                light_curve_times, fluxes_with_injected_signal)
        return fluxes_with_injected_signal
示例#4
0
 def test_can_convert_columns_to_relative_scale(self):
     light_curve = LightCurve()
     light_curve.data_frame = pd.DataFrame({
         'a': [1, 2, 3],
         'b': [-1, -2, -3],
         'c': [1, 2, 3]
     })
     light_curve.convert_columns_to_relative_scale(['a', 'b'])
     assert np.array_equal(light_curve.data_frame['a'].values,
                           [0.5, 1, 1.5])
     assert np.array_equal(light_curve.data_frame['b'].values,
                           [0.5, 1, 1.5])
     assert np.array_equal(light_curve.data_frame['c'].values, [1, 2, 3])
示例#5
0
 def flat(cls, value: float = 1) -> LightCurve:
     """
     Creates a flat light curve.
     """
     length = 100
     fluxes = np.full(shape=[length], fill_value=value, dtype=np.float32)
     times = np.arange(length, dtype=np.float32)
     return LightCurve.from_times_and_fluxes(times=times, fluxes=fluxes)
示例#6
0
 def sine_wave(cls, period=50) -> LightCurve:
     """
     Creates a sine wave light curve.
     """
     length = 100
     periods_to_produce = length / period
     fluxes = (np.sin(
         np.linspace(
             0, np.pi * periods_to_produce, num=length, endpoint=False)) /
               2) + 1
     times = np.arange(length)
     return LightCurve.from_times_and_fluxes(times=times, fluxes=fluxes)
示例#7
0
    def preprocess_standard_light_curve(
            self,
            load_times_fluxes_and_flux_errors_from_path_function: Callable[
                [Path], Tuple[np.ndarray, np.ndarray, Union[np.ndarray, None]]],
            load_auxiliary_information_for_path_function: Callable[[Path], np.ndarray],
            load_label_from_path_function: Callable[[Path], Union[float, np.ndarray]],
            light_curve_path_tensor: tf.Tensor, evaluation_mode: bool = False,
            request_queue: Optional[Queue] = None,
            example_queue: Optional[Queue] = None
    ) -> (np.ndarray, np.ndarray):
        """
        Preprocesses a individual standard light curve from a light curve path tensor, using a passed function defining
        how to load the values from the light curve file and the label value to use. Designed to be used with `partial`
        to prepare a function which will just require the light curve path tensor, and can then be mapped to a dataset.

        :param load_times_fluxes_and_flux_errors_from_path_function: The function to load the light curve times and
                                                                     fluxes from a file.
        :param load_label_from_path_function: The function to load the label to assign to the light curve.
        :param light_curve_path_tensor: The tensor containing the path to the light curve file.
        :param evaluation_mode: Whether or not the preprocessing should occur in evaluation mode (for repeatability).
        :param request_queue: The logging request queue.
        :param example_queue: The logging example queue.
        :return: The example and label arrays shaped for use as single example for the network.
        """
        light_curve_path = Path(light_curve_path_tensor.numpy().decode('utf-8'))
        times, fluxes, flux_errors = load_times_fluxes_and_flux_errors_from_path_function(light_curve_path)
        if self.logger is not None and self.logger.should_produce_example(request_queue):
            light_curve = LightCurve.from_times_and_fluxes(times, fluxes)
            loggable_light_curve = WandbLoggableLightCurve(light_curve_name=light_curve_path.name,
                                                           light_curve=light_curve)
            self.logger.submit_loggable(example_queue, loggable_light_curve)
        light_curve = self.build_light_curve_array(fluxes=fluxes, times=times, flux_errors=flux_errors)
        example = self.preprocess_light_curve(light_curve, evaluation_mode=evaluation_mode)
        label = load_label_from_path_function(light_curve_path)
        label = self.expand_label_to_training_dimensions(label)
        if self.number_of_auxiliary_values > 0:
            auxiliary_information = load_auxiliary_information_for_path_function(light_curve_path)
            return example, auxiliary_information, label
        else:
            return example, label
示例#8
0
 def test_times_are_drawn_from_light_curve_data_frame_when_column_name_is_set(
         self):
     light_curve = LightCurve()
     light_curve.data_frame = pd.DataFrame({'time_column': [0, 1]})
     light_curve.time_column_name = 'time_column'
     assert np.array_equal(light_curve.times, [0, 1])
示例#9
0
 def test_can_convert_column_to_relative_scale(self):
     light_curve = LightCurve()
     light_curve.data_frame = pd.DataFrame({'a': [1, 2, 3]})
     light_curve.convert_column_to_relative_scale('a')
     assert np.array_equal(light_curve.data_frame['a'].values,
                           [0.5, 1, 1.5])
示例#10
0
 def test_flux_column_name_is_set_when_times_are_manually_set(self):
     light_curve = LightCurve()
     assert len(light_curve.flux_column_names) == 0
     light_curve.fluxes = [0, 1]
     assert len(light_curve.flux_column_names) == 1
示例#11
0
 def test_time_column_name_is_set_when_times_are_manually_set(self):
     light_curve = LightCurve()
     assert light_curve.time_column_name is None
     light_curve.times = [0, 1]
     assert light_curve.time_column_name is not None
示例#12
0
 def test_fluxes_error_when_column_name_is_not_set(self):
     light_curve = LightCurve()
     light_curve.data_frame = pd.DataFrame({'flux_column': [0, 1]})
     with pytest.raises(IndexError):
         _ = light_curve.fluxes
示例#13
0
 def test_times_error_when_column_name_is_not_set(self):
     light_curve = LightCurve()
     light_curve.data_frame = pd.DataFrame({'time_column': [0, 1]})
     with pytest.raises(KeyError):
         _ = light_curve.times
示例#14
0
 def test_fluxes_are_drawn_from_light_curve_data_frame_when_column_names_is_set(
         self):
     light_curve = LightCurve()
     light_curve.data_frame = pd.DataFrame({'flux_column': [0, 1]})
     light_curve.flux_column_names = ['flux_column']
     assert np.array_equal(light_curve.fluxes, [0, 1])