Beispiel #1
0
    def split_by_gti(self):
        """
        Split the current :class:`Lightcurve` object into a list of :class:`Lightcurve` objects, one
        for each continuous GTI segment as defined in the ``gti`` attribute.

        Returns
        -------
        list_of_lcs : list
            A list of :class:`Lightcurve` objects, one for each GTI segment
        """
        list_of_lcs = []

        start_bins, stop_bins = gti_border_bins(self.gti, self.time, self.dt)
        for i in range(len(start_bins)):
            start = start_bins[i]
            stop = stop_bins[i]
            # Note: GTIs are consistent with default in this case!
            new_lc = Lightcurve(self.time[start:stop],
                                self.counts[start:stop],
                                err=self.counts_err[start:stop],
                                mjdref=self.mjdref,
                                gti=[self.gti[i]],
                                dt=self.dt,
                                err_dist=self.err_dist)
            list_of_lcs.append(new_lc)

        return list_of_lcs
Beispiel #2
0
    def split_by_gti(self):
        """Splits the `LightCurve` into a list of `LightCurve`s , using GTIs."""
        list_of_lcs = []

        start_bins, stop_bins = gti_border_bins(self.gti, self.time)
        for i in range(len(start_bins)):
            start = start_bins[i]
            stop = stop_bins[i]
            # Note: GTIs are consistent with default in this case!
            new_lc = Lightcurve(self.time[start:stop], self.counts[start:stop])
            list_of_lcs.append(new_lc)

        return list_of_lcs
Beispiel #3
0
    def split_by_gti(self):
        """
        Splits the `LightCurve` into a list of `LightCurve`s , using GTIs.
        """
        list_of_lcs = []

        start_bins, stop_bins = gti_border_bins(self.gti, self.time)
        for i in range(len(start_bins)):
            start = start_bins[i]
            stop = stop_bins[i]
            # Note: GTIs are consistent with default in this case!
            new_lc = Lightcurve(self.time[start:stop], self.counts[start:stop])
            list_of_lcs.append(new_lc)

        return list_of_lcs
Beispiel #4
0
    def split_by_gti(self):
        """
        Split the current :class:`Lightcurve` object into a list of :class:`Lightcurve` objects, one
        for each continuous GTI segment as defined in the ``gti`` attribute.

        Returns
        -------
        list_of_lcs : list
            A list of :class:`Lightcurve` objects, one for each GTI segment
        """
        list_of_lcs = []

        start_bins, stop_bins = gti_border_bins(self.gti, self.time, self.dt)
        for i in range(len(start_bins)):
            start = start_bins[i]
            stop = stop_bins[i]
            # Note: GTIs are consistent with default in this case!
            new_lc = Lightcurve(self.time[start:stop], self.counts[start:stop],
                                err=self.counts_err[start:stop],
                                mjdref=self.mjdref, gti=[self.gti[i]],
                                dt=self.dt, err_dist=self.err_dist)
            list_of_lcs.append(new_lc)

        return list_of_lcs
Beispiel #5
0
    def test_gti_border_bins_many_bins(self):
        times = np.arange(0, 2, 0.0001) + 0.00005

        start_bins, stop_bins = gti_border_bins([[0, 2]], times)
        assert start_bins == [0]
        assert stop_bins == [len(times)]
Beispiel #6
0
    def test_gti_border_bins(self):
        times = np.arange(0.5, 2.5)

        start_bins, stop_bins = gti_border_bins([[0, 2]], times)
        assert start_bins == [0]
        assert stop_bins == [2]
Beispiel #7
0
def simulate_times_from_count_array(time, counts, gti, dt, use_spline=False):
    """Simulate an event list, by using the inverse CDF method.

    + Assume that the light curve is a probability density (must be positive
      definite)

    + Calculate the CDF from the cumulative sum, and normalize it from 0 to 1

    + Extract N random probability values from 0 to 1

    + Find the CDF values corresponding to these N values

    + Find the times corresponding to these N CDF values

    Parameters
    ----------
    time: array-like
    counts: array-like
    gti: [[gti00, gti01], ..., [gtin0, gtin1]]
    dt: float

    Other Parameters
    ----------------
    use_spline : bool
        Approximate the light curve with a spline to avoid binning effects

    Returns
    -------
    times : array-like
        Simulated photon arrival times

    Examples
    --------
    >>> t = [0.5, 1.5, 2.5, 3.5, 5.5]
    >>> c = [100] * 5
    >>> gti = [[0, 4], [5, 6]]
    >>> times = simulate_times_from_count_array(t, c, gti, 1, use_spline=True)
    >>> np.all(np.diff(times) > 0)  # Output array is sorted
    True
    >>> np.all(times >= 0.)  # All times inside GTIs
    True
    >>> np.all(times <= 6.)
    True
    >>> np.any(times > 5.)
    True
    >>> np.any(times < 4.)
    True
    >>> np.any((times > 4.) & (times < 5.))  # No times outside GTIs
    False
    >>> c[0] = -3.
    >>> simulate_times_from_count_array(t, c, gti, 1)  # Test with one negative value in the lc
    Traceback (most recent call last):
        ...
    ValueError: simulate_times can only work with...
    """
    time = np.asarray(time)
    counts = np.asarray(counts)
    gti = np.asarray(gti)
    kind = "linear"
    if use_spline and time.size > 2:
        kind = "cubic"

    if np.any(counts < 0):
        raise ValueError(
            "simulate_times can only work with positive-definite light curves"
        )

    if len(gti) > 1:  # Work GTI by GTI, to avoid the spillover of events
        all_events = []
        start_bins, stop_bins = gti_border_bins(gti, time, dt=dt)
        for i, (start, stop) in enumerate(zip(start_bins, stop_bins)):
            new_events = simulate_times_from_count_array(
                time[start:stop],
                counts[start:stop],
                [gti[i]],
                dt,
                use_spline=use_spline)
            all_events.append(new_events)
        return np.concatenate(all_events)

    if len(counts) == 1:  # Corner case: a single light curve bin
        dt = dt
        t0 = time[0] - dt / 2
        t1 = time[0] + dt / 2
        N = counts[0]
        return np.sort(np.random.uniform(t0, t1, N))

    tmin = gti[0, 0]
    tmax = gti[-1, 1]
    duration = (tmax - tmin)
    phase_bins = np.copy(time)
    phase_bins -= tmin
    phase_bins /= duration
    dph = dt / duration

    counts = np.concatenate(([0], counts))
    phase_bins = np.concatenate(
        ([0], phase_bins + dph / 2))
    n_events_predict = np.random.poisson(np.sum(counts))

    cdf = np.cumsum(counts, dtype=float)
    cdf -= cdf[0]
    cdf /= cdf[-1]

    inv_cdf_func = sci.interp1d(
        cdf,
        phase_bins,
        kind=kind)

    cdf_vals = np.sort(np.random.uniform(0, 1, n_events_predict))
    times = inv_cdf_func(cdf_vals)
    times *= duration
    times += tmin

    return times
Beispiel #8
0
def simulate_times_from_count_array(time, counts, gti, dt, use_spline=False):
    """Simulate an event list, by using the inverse CDF method.

    + Assume that the light curve is a probability density (must be positive
      definite)

    + Calculate the CDF from the cumulative sum, and normalize it from 0 to 1

    + Extract N random probability values from 0 to 1

    + Find the CDF values corresponding to these N values

    + Find the times corresponding to these N CDF values

    Parameters
    ----------
    time: array-like
    counts: array-like
    gti: [[gti00, gti01], ..., [gtin0, gtin1]]
    dt: float

    Other Parameters
    ----------------
    use_spline : bool
        Approximate the light curve with a spline to avoid binning effects

    Returns
    -------
    times : array-like
        Simulated photon arrival times

    Examples
    --------
    >>> t = [0., 1., 2., 3., 5.]
    >>> c = [100] * 5
    >>> gti = [[-0.5, 3.5], [4.5, 5.5]]
    >>> times = simulate_times_from_count_array(t, c, gti, 1, use_spline=True)
    >>> np.all(np.diff(times) > 0)  # Output array is sorted
    True
    >>> np.all(times >= -0.5)  # All times inside GTIs
    True
    >>> np.all(times <= 5.5)
    True
    >>> np.any(times > 4.5)
    True
    >>> np.any(times < 3.5)
    True
    >>> np.any((times > 3.5) & (times < 4.5))  # No times outside GTIs
    False
    >>> # test that it works with integer times (former bug)
    >>> times = simulate_times_from_count_array([0, 1, 2, 3, 5], c, gti, 1, use_spline=True)
    >>> c[0] = -3.
    >>> simulate_times_from_count_array(t, c, gti, 1)  # Test with one negative value in the lc
    Traceback (most recent call last):
        ...
    ValueError: simulate_times can only work with...
    """
    time = np.asarray(time)
    counts = np.asarray(counts).astype(float)
    gti = np.asarray(gti)
    kind = "linear"
    if use_spline and time.size > 2:
        kind = "cubic"

    if np.any(counts < 0):
        raise ValueError(
            "simulate_times can only work with positive-definite light curves"
        )

    if len(gti) > 1:  # Work GTI by GTI, to avoid the spillover of events
        all_events = []
        start_bins, stop_bins = gti_border_bins(gti, time, dt=dt)
        for i, (start, stop) in enumerate(zip(start_bins, stop_bins)):
            new_events = simulate_times_from_count_array(
                time[start:stop],
                counts[start:stop],
                [gti[i]],
                dt,
                use_spline=use_spline)
            all_events.append(new_events)
        return np.concatenate(all_events)

    n_events_predict = np.random.poisson(np.sum(counts))
    tmin = gti[0, 0]
    tmax = gti[-1, 1]
    times = simulate_with_inverse_cdf(
        counts, n_events_predict, sorted=True, x_range=[tmin, tmax],
        interp_kind=kind)

    return times