From 51dc87330ca409d8a25202ea71a2be2ff01ba9ac Mon Sep 17 00:00:00 2001 From: ankitkhushwaha <124484362+ankitkhushwaha@users.noreply.github.com> Date: Sun, 6 Apr 2025 09:33:35 +0530 Subject: [PATCH 1/7] Fixes issue with None in stingray.lighcurve --- stingray/lightcurve.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/stingray/lightcurve.py b/stingray/lightcurve.py index c6cff03b6..87b1cfc04 100644 --- a/stingray/lightcurve.py +++ b/stingray/lightcurve.py @@ -83,10 +83,13 @@ class Lightcurve(StingrayTimeseries): They will be used by other methods to have an indication of the "safe" time intervals to use during analysis. - err_dist: str, optional, default ``None`` + err_dist: str, optional, None, default ``poisson`` Statistical distribution used to calculate the uncertainties and other statistical values appropriately. Default makes no assumptions and keep errors equal to zero. + + At the moment Stingray only uses ``poisson`` err_dist. + All analysis in the light curve will assume Poisson errors. bg_counts: iterable,`:class:numpy.array` or `:class:List` of floats, optional, default ``None`` A list or array of background counts detected in the background extraction region @@ -275,7 +278,9 @@ def __init__( if not skip_checks: time, counts, err = self.initial_optional_checks(time, counts, err, gti=gti) - if err_dist.lower() not in valid_statistics: + if err_dist is None: + pass + elif isinstance(err_dist, str) or err_dist.lower() not in valid_statistics: # err_dist set can be increased with other statistics raise StingrayError( "Statistic not recognized." "Please select one of these: ", From ec8bd4a548c026f7796af1f2655cec5de5813caa Mon Sep 17 00:00:00 2001 From: ankitkhushwaha <124484362+ankitkhushwaha@users.noreply.github.com> Date: Sun, 6 Apr 2025 09:46:12 +0530 Subject: [PATCH 2/7] fixes test falling --- stingray/lightcurve.py | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/stingray/lightcurve.py b/stingray/lightcurve.py index 87b1cfc04..72ae26dd3 100644 --- a/stingray/lightcurve.py +++ b/stingray/lightcurve.py @@ -278,21 +278,20 @@ def __init__( if not skip_checks: time, counts, err = self.initial_optional_checks(time, counts, err, gti=gti) - if err_dist is None: - pass - elif isinstance(err_dist, str) or err_dist.lower() not in valid_statistics: - # err_dist set can be increased with other statistics - raise StingrayError( - "Statistic not recognized." "Please select one of these: ", - "{}".format(valid_statistics), - ) - elif not err_dist.lower() == "poisson": - simon( - "Stingray only uses poisson err_dist at the moment. " - "All analysis in the light curve will assume Poisson " - "errors. " - "Sorry for the inconvenience." - ) + if err_dist is not None: + if err_dist.lower() not in valid_statistics: + # err_dist set can be increased with other statistics + raise StingrayError( + "Statistic not recognized." "Please select one of these: ", + "{}".format(valid_statistics), + ) + elif not err_dist.lower() == "poisson": + simon( + "Stingray only uses poisson err_dist at the moment. " + "All analysis in the light curve will assume Poisson " + "errors. " + "Sorry for the inconvenience." + ) self._time = time From 44e5048330456c581a2ed7dbbe1dcfc14d98ddb6 Mon Sep 17 00:00:00 2001 From: ankitkhushwaha <124484362+ankitkhushwaha@users.noreply.github.com> Date: Sun, 6 Apr 2025 10:24:06 +0530 Subject: [PATCH 3/7] fix tstart in lightcurve.shift --- stingray/lightcurve.py | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/stingray/lightcurve.py b/stingray/lightcurve.py index 72ae26dd3..87b544e2a 100644 --- a/stingray/lightcurve.py +++ b/stingray/lightcurve.py @@ -8,6 +8,7 @@ import os import logging import warnings +import copy from collections.abc import Iterable import numpy as np @@ -87,7 +88,7 @@ class Lightcurve(StingrayTimeseries): Statistical distribution used to calculate the uncertainties and other statistical values appropriately. Default makes no assumptions and keep errors equal to zero. - + At the moment Stingray only uses ``poisson`` err_dist. All analysis in the light curve will assume Poisson errors. @@ -1163,6 +1164,45 @@ def truncate(self, start=0, stop=None, method="index"): return super().truncate(start=start, stop=stop, method=method) + def shift(self, time_shift: float, inplace=False): + """Shift the time and the GTIs by the same amount + + Parameters + ---------- + time_shift: float + The time interval by which the time series will be shifted (in + the same units as the time array in :class:`StingrayTimeseries` + + Other parameters + ---------------- + inplace : bool + If True, overwrite the current time series. Otherwise, return a new one. + + Returns + ------- + ts : ``StingrayTimeseries`` object + The new time series shifted by ``time_shift`` + + """ + if inplace: + ts = self + else: + ts = copy.deepcopy(self) + ts.time = ts._time = np.asanyarray(ts.time) + time_shift # type: ignore + + if isinstance(self.dt, Iterable): + ts.tstart = ts._time[0] - 0.5 * self.dt[0] + ts.tseg = ts._time[-1] - ts._time[0] + self.dt[-1] / 2 + self.dt[0] / 2 + else: + ts.tstart = ts._time[0] - 0.5 * self.dt + ts.tseg = ts._time[-1] - ts._time[0] + self.dt + # Pay attention here: if the GTIs are created dynamically while we + # access the property, + if ts._gti is not None: + ts._gti = np.asanyarray(ts._gti) + time_shift # type: ignore + + return ts + def split(self, min_gap, min_points=1): """ For data with gaps, it can sometimes be useful to be able to split From 514e5e34808dd70907e60ddcdcf4f7fa846f7388 Mon Sep 17 00:00:00 2001 From: ankitkhushwaha <124484362+ankitkhushwaha@users.noreply.github.com> Date: Sat, 12 Apr 2025 15:26:31 +0530 Subject: [PATCH 4/7] add tests for `lightcurve.shift` --- stingray/lightcurve.py | 37 +++++++++++++------------------ stingray/tests/test_lightcurve.py | 3 +++ 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/stingray/lightcurve.py b/stingray/lightcurve.py index 87b544e2a..a8fe5c456 100644 --- a/stingray/lightcurve.py +++ b/stingray/lightcurve.py @@ -84,14 +84,13 @@ class Lightcurve(StingrayTimeseries): They will be used by other methods to have an indication of the "safe" time intervals to use during analysis. - err_dist: str, optional, None, default ``poisson`` + err_dist: str, optional, default ``None`` Statistical distribution used to calculate the uncertainties and other statistical values appropriately. Default makes no assumptions and keep errors equal to zero. - At the moment Stingray only uses ``poisson`` err_dist. - All analysis in the light curve will assume Poisson errors. - + Stingray currently supports only Poisson error distribution. + All light curve analyses will assume Poisson errors. bg_counts: iterable,`:class:numpy.array` or `:class:List` of floats, optional, default ``None`` A list or array of background counts detected in the background extraction region in each bin corresponding to the bins defined in `time`. @@ -279,20 +278,19 @@ def __init__( if not skip_checks: time, counts, err = self.initial_optional_checks(time, counts, err, gti=gti) - if err_dist is not None: - if err_dist.lower() not in valid_statistics: - # err_dist set can be increased with other statistics - raise StingrayError( - "Statistic not recognized." "Please select one of these: ", - "{}".format(valid_statistics), - ) - elif not err_dist.lower() == "poisson": - simon( - "Stingray only uses poisson err_dist at the moment. " - "All analysis in the light curve will assume Poisson " - "errors. " - "Sorry for the inconvenience." - ) + if err_dist.lower() not in valid_statistics: + # err_dist set can be increased with other statistics + raise StingrayError( + "Statistic not recognized." "Please select one of these: ", + "{}".format(valid_statistics), + ) + elif not err_dist.lower() == "poisson": + simon( + "Stingray only uses poisson err_dist at the moment. " + "All analysis in the light curve will assume Poisson " + "errors. " + "Sorry for the inconvenience." + ) self._time = time @@ -311,7 +309,6 @@ def __init__( dt = 1.0 self.dt = dt - if isinstance(dt, Iterable): warnings.warn( "Some functionalities of Stingray Lightcurve will not work when `dt` is Iterable" @@ -1192,10 +1189,8 @@ def shift(self, time_shift: float, inplace=False): if isinstance(self.dt, Iterable): ts.tstart = ts._time[0] - 0.5 * self.dt[0] - ts.tseg = ts._time[-1] - ts._time[0] + self.dt[-1] / 2 + self.dt[0] / 2 else: ts.tstart = ts._time[0] - 0.5 * self.dt - ts.tseg = ts._time[-1] - ts._time[0] + self.dt # Pay attention here: if the GTIs are created dynamically while we # access the property, if ts._gti is not None: diff --git a/stingray/tests/test_lightcurve.py b/stingray/tests/test_lightcurve.py index 8dc528b2c..6e6bf34a1 100644 --- a/stingray/tests/test_lightcurve.py +++ b/stingray/tests/test_lightcurve.py @@ -1329,12 +1329,15 @@ def test_shift(self): lc = Lightcurve(times, counts, input_counts=True) lc2 = lc.shift(1) assert np.allclose(lc2.time - 1, times) + assert np.allclose(lc2.tstart - 1, lc.tstart) lc2 = lc.shift(-1) assert np.allclose(lc2.time + 1, times) + assert np.allclose(lc2.tstart + 1, lc.tstart) assert np.allclose(lc2.counts, lc.counts) assert np.allclose(lc2.countrate, lc.countrate) lc = Lightcurve(times, counts, input_counts=False) lc2 = lc.shift(1) + assert np.allclose(lc2.tstart - 1, lc.tstart) assert np.allclose(lc2.counts, lc.counts) assert np.allclose(lc2.countrate, lc.countrate) From bbed440855b7f42df26224f15dce1ba0132be04b Mon Sep 17 00:00:00 2001 From: ankitkhushwaha <124484362+ankitkhushwaha@users.noreply.github.com> Date: Sat, 12 Apr 2025 16:10:17 +0530 Subject: [PATCH 5/7] add more test to increase coverage --- stingray/tests/test_lightcurve.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/stingray/tests/test_lightcurve.py b/stingray/tests/test_lightcurve.py index 6e6bf34a1..8cff0fbd0 100644 --- a/stingray/tests/test_lightcurve.py +++ b/stingray/tests/test_lightcurve.py @@ -1330,6 +1330,20 @@ def test_shift(self): lc2 = lc.shift(1) assert np.allclose(lc2.time - 1, times) assert np.allclose(lc2.tstart - 1, lc.tstart) + + lc1 = Lightcurve(times, counts, input_counts=True) + with pytest.warns( + UserWarning, + match="Some functionalities of Stingray Lightcurve will not work when `dt` is Iterable", + ): + lc2 = Lightcurve(times, counts, input_counts=True, dt=[1.0] * len(times)) + lc1.shift(1, inplace=True) + lc2.shift(1, inplace=True) + assert np.allclose(lc1.time - 1, times) + assert np.allclose(lc1.tstart - 1, lc.tstart) + assert np.allclose(lc2.time - 1, times) + assert np.allclose(lc2.tstart - 1, lc.tstart) + lc2 = lc.shift(-1) assert np.allclose(lc2.time + 1, times) assert np.allclose(lc2.tstart + 1, lc.tstart) From 1e308660f6ca0a47d5b8043a0e987ef212a215d8 Mon Sep 17 00:00:00 2001 From: ankitkhushwaha <124484362+ankitkhushwaha@users.noreply.github.com> Date: Sat, 12 Apr 2025 16:15:19 +0530 Subject: [PATCH 6/7] add changelog --- docs/changes/912.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/changes/912.bugfix.rst diff --git a/docs/changes/912.bugfix.rst b/docs/changes/912.bugfix.rst new file mode 100644 index 000000000..b6da40447 --- /dev/null +++ b/docs/changes/912.bugfix.rst @@ -0,0 +1 @@ +Fixed the ``tstart`` attribute not updating correctly in the ``stingray.Lightcurve.shift`` method. From 03a0a6b2687ec95816c4f453229cee53773753c8 Mon Sep 17 00:00:00 2001 From: ankitkhushwaha <124484362+ankitkhushwaha@users.noreply.github.com> Date: Sat, 12 Apr 2025 16:24:25 +0530 Subject: [PATCH 7/7] fixes test failure due to uneven Bin sizes --- stingray/tests/test_lightcurve.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stingray/tests/test_lightcurve.py b/stingray/tests/test_lightcurve.py index 8cff0fbd0..f641eb60d 100644 --- a/stingray/tests/test_lightcurve.py +++ b/stingray/tests/test_lightcurve.py @@ -1336,7 +1336,9 @@ def test_shift(self): UserWarning, match="Some functionalities of Stingray Lightcurve will not work when `dt` is Iterable", ): - lc2 = Lightcurve(times, counts, input_counts=True, dt=[1.0] * len(times)) + lc2 = Lightcurve( + times, counts, input_counts=True, dt=[1.0] * len(times), skip_checks=True + ) lc1.shift(1, inplace=True) lc2.shift(1, inplace=True) assert np.allclose(lc1.time - 1, times)