Exemple #1
0
    def setup_class(cls):
        tstart = 0.0
        tend = 1.0
        dt = 0.0001

        time = np.arange(tstart + 0.5 * dt, tend + 0.5 * dt, dt)

        mean_count_rate = 100.0
        mean_counts = mean_count_rate * dt

        poisson_counts = np.random.poisson(mean_counts, size=time.shape[0])

        cls.lc = Lightcurve(time,
                            counts=poisson_counts,
                            dt=dt,
                            gti=[[tstart, tend]])
    def test_leahy_correct_for_multiple(self):

        n = 100
        lc_all = []
        for i in range(n):
            time = np.arange(0.0, 10.0, 10. / 100000)
            counts = np.random.poisson(1000, size=time.shape[0])
            lc = Lightcurve(time, counts)
            lc_all.append(lc)

        ps = AveragedPowerspectrum(lc_all, 10.0, norm="leahy")

        assert np.isclose(np.mean(ps.power), 2.0, atol=1e-3, rtol=1e-3)
        assert np.isclose(np.std(ps.power),
                          2.0 / np.sqrt(n),
                          atol=0.1,
                          rtol=0.1)
    def test_io_with_hdf5(self):
        lc = Lightcurve(self.times, self.counts)
        lc.write('lc.hdf5', format_='hdf5')

        if _H5PY_INSTALLED:
            data = lc.read('lc.hdf5', format_='hdf5')
            assert np.all(data['time'] == self.times)
            assert np.all(data['counts'] == self.counts)
            assert np.all(data['gti'] == self.gti)
            os.remove('lc.hdf5')

        else:
            lc.read('lc.pickle', format_='pickle')
            assert np.all(lc.time == self.times)
            assert np.all(lc.counts == self.counts)
            assert np.all(lc.gti == self.gti)
            os.remove('lc.pickle')
Exemple #4
0
def correct_lightcurve(lc_file, uf_file, outname=None, expo_limit=1e-7):
    """Apply exposure correction to light curve.

    Parameters
    ----------
    lc_file : str
        The light curve file, in HENDRICS format
    uf_file : str
        The unfiltered event file, in FITS format

    Returns
    -------
    outdata : str
        Output data structure

    Other Parameters
    ----------------
    outname : str
        Output file name
    """
    outname = _assign_value_if_none(
        outname, hen_root(lc_file) + "_lccorr" + HEN_FILE_EXTENSION)

    ftype, contents = get_file_type(lc_file)

    time = contents.time
    lc = contents.counts
    dt = contents.dt
    gti = contents.gti

    expo = get_exposure_from_uf(time, uf_file, dt=dt, gti=gti)

    newlc = np.array(lc / expo * dt, dtype=np.float64)
    newlc[expo < expo_limit] = 0

    newlc_err = np.array(contents.counts_err / expo * dt, dtype=np.float64)
    newlc_err[expo < expo_limit] = 0

    lcurve = Lightcurve(time, newlc, err=newlc_err,
                        gti=gti, err_dist ='gauss',
                        mjdref=contents.mjdref)

    lcurve.expo = expo

    save_lcurve(lcurve, outname)
    return outname
Exemple #5
0
    def test_sort(self):
        _times = [1, 2, 3, 4]
        _counts = [40, 10, 20, 5]
        lc = Lightcurve(_times, _counts, mjdref=57000)
        mjdref = lc.mjdref

        lc.sort()

        assert np.all(lc.counts == np.array([5, 10, 20, 40]))
        assert np.all(lc.time == np.array([4, 2, 3, 1]))
        assert lc.mjdref == mjdref

        lc.sort(reverse=True)

        assert np.all(lc.counts == np.array([40, 20, 10, 5]))
        assert np.all(lc.time == np.array([1, 3, 2, 4]))
        assert lc.mjdref == mjdref
    def test_sort_counts(self):
        _times = [1, 2, 3, 4]
        _counts = [40, 10, 20, 5]
        lc = Lightcurve(_times, _counts, mjdref=57000)
        mjdref = lc.mjdref

        lc_new = lc.sort_counts()

        assert np.allclose(lc_new.counts, np.array([5, 10, 20, 40]))
        assert np.allclose(lc_new.time, np.array([4, 2, 3, 1]))
        assert lc_new.mjdref == mjdref

        lc_new = lc.sort_counts(reverse=True)

        assert np.allclose(lc_new.counts, np.array([40, 20, 10, 5]))
        assert np.allclose(lc_new.time, np.array([1, 3, 2, 4]))
        assert lc_new.mjdref == mjdref
    def test_fractional_rms_in_frac_norm_is_consistent_averaged(self):
        time = np.arange(0, 400, 1) + 0.5

        poisson_counts = np.random.poisson(100.0, size=time.shape[0])

        lc = Lightcurve(time, counts=poisson_counts, dt=1, gti=[[0, 400]])
        ps = AveragedPowerspectrum(lc=lc, norm="leahy", segment_size=100)
        rms_ps_l, rms_err_l = ps.compute_rms(min_freq=ps.freq[1],
                                             max_freq=ps.freq[-1],
                                             white_noise_offset=0)

        ps = AveragedPowerspectrum(lc=lc, norm="frac", segment_size=100)
        rms_ps, rms_err = ps.compute_rms(min_freq=ps.freq[1],
                                         max_freq=ps.freq[-1],
                                         white_noise_offset=0)
        assert np.allclose(rms_ps, rms_ps_l, atol=0.01)
        assert np.allclose(rms_err, rms_err_l, atol=0.01)
    def test_timeseries_roundtrip(self):
        """Test that io methods raise Key Error when
        wrong format is provided.
        """
        N = len(self.times)
        lc = Lightcurve(self.times,
                        self.counts,
                        mission="BUBU",
                        instr="BABA",
                        mjdref=53467.)

        ts = lc.to_astropy_timeseries()
        new_lc = lc.from_astropy_timeseries(ts)
        for attr in ['time', 'gti', 'counts']:
            assert np.allclose(getattr(lc, attr), getattr(new_lc, attr))
        for attr in ['mission', 'instr', 'mjdref']:
            assert getattr(lc, attr) == getattr(new_lc, attr)
    def _make_reference_bands_from_lightcurves(self, bounds=None):
        '''
        Helper class to construct reference bands for all light curves in ``band_interest``, assuming the
        data is given to the class :class:`Covariancespectrum` as a (set of) lightcurve(s). Generally
        sums up all other light curves within ``bounds`` that are *not* the band of interest.

        Parameters
        ----------
        bounds : iterable
            The energy bounds to use for the reference band. Must be of type ``(elow, ehigh)``.

        Returns
        -------
        lc_all: list of :class:`stingray.Lightcurve` objects.
            The list of :class:`stingray.Lightcurve` objects containing all reference bands,
            between the values given in ``bounds``.

        '''

        if not bounds:
            bounds_idx = [0, len(self.band_interest)]

        else:
            low_bound = self.band_interest.searchsorted(bounds[0])
            high_bound = self.band_interest.searchsorted(bounds[1])

            bounds_idx = [low_bound, high_bound]

        lc_all = []
        for i, b in enumerate(self.band_interest):

            # initialize empty counts array
            counts = np.zeros_like(self.lcs[0].counts)
            for j in range(bounds_idx[0], bounds_idx[1], 1):
                if i == j:
                    continue
                else:
                    counts += self.lcs[j].counts

            # make a combined light curve
            lc = Lightcurve(self.lcs[0].time, counts, skip_checks=True)

            # add to list of reference light curves
            lc_all.append(lc)

        return lc_all
Exemple #10
0
    def _simulate_model_string(self, model_str, params):
        """
        For generating a light curve from a pre-defined model

        Parameters
        ----------
        model_str : string
            name of the pre-defined model
        params : list or dictionary
            parameters of the pre-defined model

        Returns
        -------
        lightCurve : `LightCurve` object
        """

        # Frequencies at which the PSD is to be computed
        # (only positive frequencies, since the signal is real)
        nbins = self.red_noise * self.N
        simfreq = np.fft.rfftfreq(nbins, d=self.dt)[1:]

        if model_str in dir(models):
            if isinstance(params, dict):
                model = eval('models.' + model_str + '(**params)')
                # Compute PSD from model
                simpsd = model(simfreq)
            elif isinstance(params, list):
                simpsd = eval('models.' + model_str + '(simfreq, params)')
            else:
                raise ValueError('Params should be list or dictionary!')

            fac = np.sqrt(simpsd)
            pos_real = self.random_state.normal(size=nbins // 2) * fac
            pos_imag = self.random_state.normal(size=nbins // 2) * fac

            long_lc = self._find_inverse(pos_real, pos_imag)

            lc = Lightcurve(self.time,
                            self._extract_and_scale(long_lc),
                            err=np.zeros_like(self.time) + np.sqrt(self.mean),
                            err_dist='gauss',
                            dt=self.dt)
            return lc
        else:
            raise ValueError('Model is not defined!')
Exemple #11
0
    def test_timelag(self):
        dt = 0.1
        simulator = Simulator(dt, 10000, rms=0.2, mean=1000)
        test_lc1 = simulator.simulate(2)
        test_lc2 = Lightcurve(test_lc1.time,
                              np.array(np.roll(test_lc1.counts, 2)),
                              err_dist=test_lc1.err_dist,
                              dt=dt)

        with warnings.catch_warnings(record=True) as w:
            cs = AveragedCrossspectrum(test_lc1,
                                       test_lc2,
                                       segment_size=5,
                                       norm="none")

            time_lag, time_lag_err = cs.time_lag()

        assert np.all(np.abs(time_lag[:6] - 0.1) < 3 * time_lag_err[:6])
Exemple #12
0
    def test_timelag(self):
        from ..simulator.simulator import Simulator
        dt = 0.1
        simulator = Simulator(dt, 10000, rms=0.8, mean=1000)
        test_lc1 = simulator.simulate(2)
        test_lc2 = Lightcurve(test_lc1.time,
                              np.array(np.roll(test_lc1.counts, 2)),
                              err_dist=test_lc1.err_dist,
                              dt=dt)

        cs = AveragedCrossspectrum(test_lc1,
                                   test_lc2,
                                   segment_size=5,
                                   norm="none")

        time_lag, time_lag_err = cs.time_lag()

        assert np.all(np.abs(time_lag[:6] - 0.1) < 3 * time_lag_err[:6])
Exemple #13
0
    def _simulate_model(self, model):
        """
        For generating a light curve from a pre-defined model

        Parameters
        ----------
        model : astropy.modeling.Model derived function
            the pre-defined model
            (library-based, available in astropy.modeling.models or
            custom-defined)

        Returns
        -------
        lightCurve : :class:`stingray.lightcurve.LightCurve` object
        """
        # Frequencies at which the PSD is to be computed
        # (only positive frequencies, since the signal is real)
        nbins = self.red_noise * self.N
        simfreq = np.fft.rfftfreq(nbins, d=self.dt)[1:]

        # Compute PSD from model
        simpsd = model(simfreq)

        if self.nphot == 0:
            nphot = 1.0
        else:
            nphot = self.nphot
        self.std = np.sqrt(
            (nphot / (self.N**2.)) * (np.sum(simpsd[:-1]) + 0.5 * simpsd[-1]))

        fac = np.sqrt(simpsd) * nphot / 4.0
        pos_real = self.random_state.normal(size=nbins // 2) * fac
        pos_imag = self.random_state.normal(size=nbins // 2) * fac

        long_lc = self._find_inverse(pos_real, pos_imag)

        lc = Lightcurve(self.time,
                        self._extract_and_scale(long_lc),
                        err=np.zeros_like(self.time) + np.sqrt(self.mean),
                        err_dist='gauss',
                        dt=self.dt,
                        skip_checks=True)
        return lc
Exemple #14
0
    def _simulate_power_law(self, B):
        """
        Generate LightCurve from a power law spectrum.

        Parameters
        ----------
        B : int
            Defines the shape of power law spectrum.

        Returns
        -------
        lightCurve : array-like
        """
        # Define frequencies at which to compute PSD
        w = np.fft.rfftfreq(self.red_noise * self.N, d=self.dt)[1:]

        # Draw two set of 'N' guassian distributed numbers
        a1 = self.random_state.normal(size=len(w))
        a2 = self.random_state.normal(size=len(w))

        psd = np.power((1 / w), B)

        if self.nphot == 0:
            nphot = 1.0
        else:
            nphot = self.nphot
        self.std = np.sqrt(
            (nphot / (self.N**2.)) * (np.sum(psd[:-1]) + 0.5 * psd[-1]))

        # Multiply by (1/w)^B to get real and imaginary parts
        real = a1 * np.sqrt(psd * nphot / 4)
        imaginary = a2 * np.sqrt(psd * nphot / 4)

        # Obtain time series
        long_lc = self._find_inverse(real, imaginary)
        lc = Lightcurve(self.time,
                        self._extract_and_scale(long_lc),
                        err=np.zeros_like(self.time) + np.sqrt(self.mean),
                        err_dist='gauss',
                        dt=self.dt,
                        skip_checks=True)

        return lc
Exemple #15
0
    def test_sort(self):
        _times = [2, 1, 3, 4]
        _counts = [40, 10, 20, 5]
        _counts_err = [4, 1, 2, 0.5]

        lc = Lightcurve(_times, _counts, err=_counts_err, mjdref=57000)
        mjdref = lc.mjdref

        lc_new = lc.sort()

        assert np.all(lc_new.counts_err == np.array([1, 4, 2, 0.5]))
        assert np.all(lc_new.counts == np.array([10, 40, 20, 5]))
        assert np.all(lc_new.time == np.array([1, 2, 3, 4]))
        assert lc_new.mjdref == mjdref

        lc_new = lc.sort(reverse=True)

        assert np.all(lc_new.counts == np.array([5, 20, 40, 10]))
        assert np.all(lc_new.time == np.array([4, 3, 2, 1]))
        assert lc_new.mjdref == mjdref
Exemple #16
0
    def _simulate_power_spectrum(self, s):
        """
        Generate a light curve from user-provided spectrum.

        Parameters
        ----------
        s : array-like
            power spectrum

        Returns
        -------
        lightCurve : `LightCurve` object
        """
        # Cast spectrum as numpy array
        s = np.array(s)

        if self.nphot == 0:
            nphot = 1.0
        else:
            nphot = self.nphot
        self.std = np.sqrt(
            (nphot / (self.N**2.)) * (np.sum(s[:-1]) + 0.5 * s[-1]))

        self.red_noise = 1

        # Draw two set of 'N' guassian distributed numbers
        a1 = self.random_state.normal(size=len(s))
        a2 = self.random_state.normal(size=len(s))

        real = a1 * nphot * np.sqrt(s) / 4.0
        imaginary = a2 * nphot * np.sqrt(s) / 4.0

        lc = self._find_inverse(real, imaginary)
        lc = Lightcurve(self.time,
                        self._extract_and_scale(lc),
                        err=np.zeros_like(self.time) + np.sqrt(self.mean),
                        err_dist='gauss',
                        dt=self.dt,
                        skip_checks=True)

        return lc
Exemple #17
0
    def _simulate_impulse_response(self, s, h, mode='same'):
        """
        Generate LightCurve from impulse response. To get
        accurate results, binning intervals (dt) of variability
        signal 's' and impulse response 'h' must be equal.

        Parameters
        ----------
        s : array-like
            Underlying variability signal
        h : array-like
            Impulse response
        mode : str
            mode can be 'same', 'filtered, or 'full'.
            'same' indicates that the length of output light
            curve is same as that of input signal.
            'filtered' means that length of output light curve
            is len(s) - lag_delay
            'full' indicates that the length of output light
            curve is len(s) + len(h) -1

        Returns
        -------
        lightCurve : :class:`stingray.lightcurve.LightCurve` object
        """
        lc = signal.fftconvolve(s, h)

        if mode == 'same':
            lc = lc[:-(len(h) - 1)]

        elif mode == 'filtered':
            lc = lc[(len(h) - 1):-(len(h) - 1)]

        time = self.dt * np.arange(0.5, len(lc)) + self.tstart
        err = np.zeros_like(time)
        return Lightcurve(time,
                          lc,
                          err_dist='gauss',
                          dt=self.dt,
                          err=err,
                          skip_checks=True)
    def test_list_of_light_curves(self):
        n_lcs = 10

        tstart = 0.0
        tend = 1.0
        dt = 0.0001

        time = np.linspace(tstart, tend, int((tend - tstart) / dt))

        mean_count_rate = 1000.0
        mean_counts = mean_count_rate * dt

        lc_all = []
        for n in range(n_lcs):
            poisson_counts = np.random.poisson(mean_counts, size=len(time))

            lc = Lightcurve(time, counts=poisson_counts)
            lc_all.append(lc)

        segment_size = 0.5
        assert AveragedPowerspectrum(lc_all, segment_size)
Exemple #19
0
    def _simulate_model(self, model):
        """
        For generating a light curve from a pre-defined model

        Parameters
        ----------
        model: astropy.modeling.Model derived function
            the pre-defined model
            (library-based, available in astropy.modeling.models or custom-defined)

        Returns
        -------
        lightCurve: `LightCurve` object
        """

        # Frequencies at which the PSD is to be computed
        # (only positive frequencies, since the signal is real)
        nbins = self.red_noise * self.N
        simfreq = np.fft.rfftfreq(nbins, d=self.dt)[1:]

        # Compute PSD from model
        simpsd = model(simfreq)

        fac = np.sqrt(simpsd / 2.)
        pos_real = self.random_state.normal(size=nbins // 2) * fac
        pos_imag = self.random_state.normal(size=nbins // 2) * fac

        pos_freq_transform = pos_real + 1j * pos_imag

        # Simulate light curve from its Fourier transform
        arg = np.concatenate(([self.mean], pos_freq_transform))

        # Inverse Fourier transform
        long_lc = np.fft.irfft(arg)

        lc = Lightcurve(self.time,
                        self._extract_and_scale(long_lc),
                        err_dist='gauss',
                        dt=self.dt)
        return lc
    def test_fractional_rms_in_frac_norm_is_consistent(self):
        """
        Copied from test_powerspectrum.py
        """
        time = np.arange(0, 100, 1) + 0.5

        poisson_counts = np.random.poisson(100.0,
                                           size=time.shape[0])

        lc = Lightcurve(time, counts=poisson_counts, dt=1,
                        gti=[[0, 100]])
        mtp = Multitaper(lc, norm="leahy")
        rms_mtp_l, rms_err_l = mtp.compute_rms(min_freq=mtp.freq[1],
                                               max_freq=mtp.freq[-1],
                                               white_noise_offset=0)

        mtp = Multitaper(lc, norm="frac")
        rms_mtp, rms_err = mtp.compute_rms(min_freq=mtp.freq[1],
                                           max_freq=mtp.freq[-1],
                                           white_noise_offset=0)
        assert np.allclose(rms_mtp, rms_mtp_l, atol=0.01)
        assert np.allclose(rms_err, rms_err_l, atol=0.01)
Exemple #21
0
    def test_analyze_lc_chunks_fvar_fracstep(self):
        dt = 0.1
        tstart = 0
        tstop = 100
        times = np.arange(tstart, tstop, dt)
        gti = np.array([[tstart - dt / 2, tstop - dt / 2]])
        # Simulate something *clearly* non-constant
        counts = np.random.poisson(10000 + 2000 * np.sin(2 * np.pi * times))

        lc = Lightcurve(times, counts, gti=gti)

        def excvar(lc):
            from stingray.utils import excess_variance
            return excess_variance(lc, normalization='fvar')

        start, stop, res = lc.analyze_lc_chunks(20, excvar, fraction_step=0.5)
        # excess_variance returns fvar and fvar_err
        res, res_err = res

        assert np.allclose(start[0], gti[0, 0])
        assert np.all(res > 0)
        # This must be a clear measurement of fvar
        assert np.all(res > res_err)
Exemple #22
0
    def test_list_with_nonsense_component(self):
        n_lcs = 10

        tstart = 0.0
        tend = 1.0
        dt = 0.0001

        time = np.linspace(tstart, tend, int((tend - tstart) / dt))

        mean_count_rate = 1000.0
        mean_counts = mean_count_rate * dt

        lc_all = []
        for n in range(n_lcs):
            poisson_counts = np.random.poisson(mean_counts, size=len(time))

            lc = Lightcurve(time, counts=poisson_counts)
            lc_all.append(lc)

        lc_all.append(1.0)
        segment_size = 0.5

        with pytest.raises(TypeError):
            assert AveragedPowerspectrum(lc_all, segment_size)
    def test_timeseries_roundtrip_ctrate(self):
        """Test that io methods raise Key Error when
        wrong format is provided.
        """
        N = len(self.times)
        dt = 0.5
        mean_counts = 2.0
        times = np.arange(0 + dt / 2, 5 - dt / 2, dt)
        countrate = np.zeros_like(times) + mean_counts

        lc = Lightcurve(times,
                        countrate,
                        mission="BUBU",
                        instr="BABA",
                        mjdref=53467.,
                        input_counts=False)

        ts = lc.to_astropy_timeseries()
        new_lc = lc.from_astropy_timeseries(ts)
        for attr in ['time', 'gti', 'countrate']:
            assert np.allclose(getattr(lc, attr), getattr(new_lc, attr))
        assert np.allclose(new_lc.counts, lc.countrate * lc.dt)
        for attr in ['mission', 'instr', 'mjdref']:
            assert getattr(lc, attr) == getattr(new_lc, attr)
    def test_multitaper_lombscargle(self):
        rng = np.random.default_rng()
        N = 1000

        white_noise_irregular = rng.normal(loc=0.0, scale=7, size=N)
        start = 0.0
        end = 9.0

        # Generating uneven sampling times by adding white noise. Do tell a better way
        time_irregular = np.linspace(start, end, N) + rng.normal(loc=0.0,
                                                                 scale=(end-start)/(3*N), size=N)
        time_irregular = np.sort(time_irregular)

        with pytest.warns(UserWarning) as record:
            lc_nonuni = Lightcurve(time=time_irregular,
                                   counts=white_noise_irregular, err_dist="gauss",
                                   err=np.ones_like(time_irregular) + np.sqrt(0.))  # Zero mean
        assert np.any(["aren't equal" in r.message.args[0]
                       for r in record])

        mtls_white = Multitaper(lc_nonuni, lombscargle=True, low_bias=True, NW=4)
        assert mtls_white.norm == "frac"
        assert mtls_white.fullspec is False
        assert mtls_white.meancounts == lc_nonuni.meancounts
        assert mtls_white.nphots == np.float64(np.sum(lc_nonuni.counts))
        assert mtls_white.err_dist == lc_nonuni.err_dist
        assert mtls_white.dt == lc_nonuni.dt
        assert mtls_white.n == lc_nonuni.time.shape[0]
        assert mtls_white.df == 1.0 / lc_nonuni.tseg
        assert mtls_white.m == 1
        assert mtls_white.freq is not None
        assert mtls_white.multitaper_norm_power is not None
        assert mtls_white.power is not None
        assert mtls_white.power_err is not None
        assert mtls_white.jk_var_deg_freedom is None  # Not supported yet
        assert len(mtls_white.eigvals) > 0
Exemple #25
0
    def _simulate_model(self, mod, p):
        """
        For generating a light curve from pre-defined model

        Parameters
        ----------
        mod: str
            name of the pre-defined model

        p: list iterable
            model parameters. For details, see model definitions
            in model.py

        Returns
        -------
        lightCurve: `LightCurve` object
        """

        # Define frequencies at which to compute PSD
        w = np.fft.rfftfreq(self.red_noise * self.N, d=self.dt)[1:]

        if mod in dir(models):
            mod = 'models.' + mod
            s = eval(mod + '(w, p)')

            # Draw two set of 'N' guassian distributed numbers
            a1 = np.random.normal(size=len(s))
            a2 = np.random.normal(size=len(s))

            long_lc = self._find_inverse(a1 * s, a2 * s)
            lc = Lightcurve(self.time, self._extract_and_scale(long_lc))

            return lc

        else:
            raise ValueError('Model is not defined!')
 def test_n(self):
     lc = Lightcurve(self.times, self.counts)
     assert lc.n == 4
 def test_io_with_ascii(self):
     lc = Lightcurve(self.times, self.counts)
     lc.write('ascii_lc.txt', format_='ascii')
     lc.read('ascii_lc.txt', format_='ascii')
     os.remove('ascii_lc.txt')
 def test_plot_title(self):
     lc = Lightcurve(self.times, self.counts)
     lc.plot(title="Test Lightcurve")
     assert plt.fignum_exists(1)
 def test_plot_axis(self):
     lc = Lightcurve(self.times, self.counts)
     lc.plot(axis=[0, 1, 0, 100])
     assert plt.fignum_exists(1)
 def test_plot_custom_filename(self):
     lc = Lightcurve(self.times, self.counts)
     lc.plot(save=True, filename='lc.png')
     assert os.path.isfile('lc.png')
     os.unlink('lc.png')