def process_light_curve(all_time, all_flux):
    """Removes low-frequency variability from a light curve.

  Args:
    all_time: A list of numpy arrays; the time values of the raw light curve.
    all_flux: A list of numpy arrays corresponding to the time arrays in
      all_time.

  Returns:
    time: 1D NumPy array; the time values of the light curve.
    flux: 1D NumPy array; the normalized flux values of the light curve.
  """
    # Split on gaps.
    all_time, all_flux = util.split(all_time, all_flux, gap_width=0.75)

    # Fit a piecewise-cubic spline with default arguments.
    spline = kepler_spline.fit_kepler_spline(all_time, all_flux,
                                             verbose=False)[0]

    # Concatenate the piecewise light curve and spline.
    time = np.concatenate(all_time)
    flux = np.concatenate(all_flux)
    spline = np.concatenate(spline)

    # In rare cases the piecewise spline contains NaNs in places the spline could
    # not be fit. We can't normalize those points if the spline isn't defined
    # there. Instead we just remove them.
    finite_i = np.isfinite(spline)
    if not np.all(finite_i):
        time = time[finite_i]
        flux = flux[finite_i]
        spline = spline[finite_i]

    # "Flatten" the light curve (remove low-frequency variability) by dividing by
    # the spline.
    flux /= spline

    return time, flux
Example #2
0
def process_light_curve(all_time, all_flux):
  """Removes low-frequency variability from a light curve.

  Args:
    all_time: A list of numpy arrays; the time values of the raw light curve.
    all_flux: A list of numpy arrays corresponding to the time arrays in
      all_time.

  Returns:
    time: 1D NumPy array; the time values of the light curve.
    flux: 1D NumPy array; the normalized flux values of the light curve.
  """
  # Split on gaps.
  all_time, all_flux = util.split(all_time, all_flux, gap_width=0.75)

  # Fit a piecewise-cubic spline with default arguments.
  spline = kepler_spline.fit_kepler_spline(all_time, all_flux, verbose=False)[0]

  # Concatenate the piecewise light curve and spline.
  time = np.concatenate(all_time)
  flux = np.concatenate(all_flux)
  spline = np.concatenate(spline)

  # In rare cases the piecewise spline contains NaNs in places the spline could
  # not be fit. We can't normalize those points if the spline isn't defined
  # there. Instead we just remove them.
  finite_i = np.isfinite(spline)
  if not np.all(finite_i):
    time = time[finite_i]
    flux = flux[finite_i]
    spline = spline[finite_i]

  # "Flatten" the light curve (remove low-frequency variability) by dividing by
  # the spline.
  flux /= spline

  return time, flux
Example #3
0
    def process(self, inputs):
        """Processes a single light curve."""
        raw_lc = inputs["raw_light_curve"]
        all_time = [
            np.array(s.time, dtype=np.float64) for s in raw_lc.segments
        ]
        all_flux = [
            np.array(s.flux, dtype=np.float64) for s in raw_lc.segments
        ]
        length_raw = sum([len(t) for t in all_time])

        # Remove events.
        events_to_remove = inputs.pop("events_to_remove", [])
        if events_to_remove:
            all_time, all_flux = util.remove_events(
                all_time,
                all_flux,
                events_to_remove,
                width_factor=self.remove_events_width_factor,
                include_empty_segments=False)

        if not all_time:
            return  # Removed entire light curve.

        # Split on gaps.
        all_time, all_flux = util.split(all_time,
                                        all_flux,
                                        gap_width=self.gap_width)

        # Mask events.
        events_to_mask = inputs.pop("events_to_mask_for_spline", [])
        if events_to_mask:
            all_masked_time, all_masked_flux = util.remove_events(
                all_time,
                all_flux,
                events=events_to_mask,
                width_factor=self.remove_events_width_factor)
        else:
            all_masked_time = all_time
            all_masked_flux = all_flux

        # Fit normalization curve.
        if self.normalize_method == "spline":
            all_spline, metadata = kepler_spline.fit_kepler_spline(
                all_masked_time, all_masked_flux, **self.normalize_args)
        else:
            raise ValueError("Unrecognized normalize_method: {}".format(
                self.normalize_method))

        # Interpolate the spline between the events removed.
        if events_to_mask:
            all_spline = util.interpolate_masked_spline(
                all_time, all_masked_time, all_spline)

        # Concatenate the results.
        time = np.concatenate(all_time)
        flux = np.concatenate(all_flux)
        norm_curve = np.concatenate(all_spline)

        # Initialize the output.
        light_curve = light_curve_pb2.LightCurve(
            length_raw=length_raw,
            spline_metadata=light_curve_pb2.SplineMetadata(
                bkspace=metadata.bkspace,
                bad_bkspaces=metadata.bad_bkspaces,
                likelihood_term=metadata.likelihood_term,
                penalty_term=metadata.penalty_term,
                bic=metadata.bic,
                masked_events=events_to_mask,
                **self.normalize_args),
            removed_events=events_to_remove)

        # If the normalization curve contains NaNs, we can't normalize those places.
        is_finite = np.isfinite(norm_curve)
        is_not_finite = np.logical_not(is_finite)
        if np.any(is_not_finite):
            light_curve.norm_curve_failures.time[:] = time[is_not_finite]
            light_curve.norm_curve_failures.flux[:] = flux[is_not_finite]
            time = time[is_finite]
            flux = flux[is_finite]
            norm_curve = norm_curve[is_finite]

        # Possibly remove outliers.
        if self.upward_outlier_sigma_cut or self.downward_outlier_sigma_cut:
            norm_flux = flux / norm_curve  # We compute outliers on normalized flux.
            deviation = norm_flux - np.median(norm_flux)

            if self.upward_outlier_sigma_cut:
                is_upward_outlier = np.logical_not(
                    robust_mean.robust_mean(
                        deviation, cut=self.upward_outlier_sigma_cut)[2])
                np.logical_and(is_upward_outlier,
                               deviation > 0,
                               out=is_upward_outlier)
            else:
                is_upward_outlier = np.zeros_like(deviation, dtype=np.bool)

            if self.downward_outlier_sigma_cut:
                is_downward_outlier = np.logical_not(
                    robust_mean.robust_mean(
                        deviation, cut=self.downward_outlier_sigma_cut)[2])
                np.logical_and(is_downward_outlier,
                               deviation < 0,
                               out=is_downward_outlier)
            else:
                is_downward_outlier = np.zeros_like(deviation, dtype=np.bool)

            is_outlier = np.logical_or(is_upward_outlier, is_downward_outlier)
            is_not_outlier = np.logical_not(is_outlier)
            if np.any(is_outlier):
                light_curve.outliers_removed.time[:] = time[is_outlier]
                light_curve.outliers_removed.flux[:] = flux[is_outlier]
                light_curve.outliers_removed.norm_curve[:] = norm_curve[
                    is_outlier]
                time = time[is_not_outlier]
                flux = flux[is_not_outlier]
                norm_curve = norm_curve[is_not_outlier]

        # Fill the output.
        light_curve.light_curve.time[:] = time
        light_curve.light_curve.flux[:] = flux
        light_curve.light_curve.norm_curve[:] = norm_curve
        inputs[self.output_name] = light_curve

        yield inputs