Repository: StingraySoftware/stingray (python)

Issue:
Unhandled exception thrown in AveragedCrossspectrum constructor
If we create two lightcurves and then create an `AveragedCrossspectrum` without specifying the segment size. The following exception gets thrown: TypeError: unsupported operand type(s) for /: 'NoneType' and 'float'.

The full traceback:
```Traceback (most recent call last):
  File "\<stdin\>", line 1, in <module>
  File "\~/stingray/crossspectrum.py", line 541, in __init__
    Crossspectrum.__init__(self, lc1, lc2, norm, gti=gti)
  File "\~/stingray/crossspectrum.py", line 137, in __init__
    self._make_crossspectrum(lc1, lc2)
  File "\~/stingray/crossspectrum.py", line 606, in _make_crossspectrum
    self._make_segment_spectrum(lc1, lc2, self.segment_size)
  File "\~/stingray/crossspectrum.py", line 573, in _make_segment_spectrum
    dt=lc1.dt)
  File "\~/stingray/gti.py", line 597, in bin_intervals_from_gtis
    nbin = np.long(chunk_length / dt)
TypeError: unsupported operand type(s) for /: 'NoneType' and 'float' 
```



Pull request description:
Specifying segment_size is now compulsory
Closes #209 

Patch:
diff --git a/stingray/crossspectrum.py b/stingray/crossspectrum.py
index 0f41724a..cf64f9ff 100644
--- a/stingray/crossspectrum.py
+++ b/stingray/crossspectrum.py
@@ -565,9 +565,10 @@ class AveragedCrossspectrum(Crossspectrum):
         """
         self.type = "crossspectrum"
 
-        if segment_size is not None:
-            if not np.isfinite(segment_size):
-                raise ValueError("segment_size must be finite")
+        if segment_size is None and lc1 is not None:
+            raise ValueError("segment_size must be specified")
+        if segment_size is not None and not np.isfinite(segment_size):
+            raise ValueError("segment_size must be finite!")
 
         self.segment_size = segment_size
 
diff --git a/stingray/powerspectrum.py b/stingray/powerspectrum.py
index 0cd61a5d..a0c20950 100755
--- a/stingray/powerspectrum.py
+++ b/stingray/powerspectrum.py
@@ -379,9 +379,10 @@ class AveragedPowerspectrum(AveragedCrossspectrum, Powerspectrum):
 
         self.type = "powerspectrum"
 
-        if segment_size is not None:
-            if not np.isfinite(segment_size):
-                raise ValueError("segment_size must be finite!")
+        if segment_size is None and lc is not None:
+            raise ValueError("segment_size must be specified")
+        if segment_size is not None and not np.isfinite(segment_size):
+            raise ValueError("segment_size must be finite!")
 
         self.segment_size = segment_size
 


Test patch:
diff --git a/stingray/tests/test_crossspectrum.py b/stingray/tests/test_crossspectrum.py
index 897adf56..d95e02bd 100644
--- a/stingray/tests/test_crossspectrum.py
+++ b/stingray/tests/test_crossspectrum.py
@@ -232,6 +232,21 @@ class TestAveragedCrossspectrum(object):
 
         self.cs = AveragedCrossspectrum(self.lc1, self.lc2, segment_size=1)
 
+    def test_make_empty_crossspectrum(self):
+        cs = AveragedCrossspectrum()
+        assert cs.freq is None
+        assert cs.power is None
+        assert cs.df is None
+        assert cs.nphots1 is None
+        assert cs.nphots2 is None
+        assert cs.m == 1
+        assert cs.n is None
+        assert cs.power_err is None
+
+    def test_no_segment_size(self):
+        with pytest.raises(ValueError):
+            cs = AveragedCrossspectrum(self.lc1, self.lc2)
+
     def test_invalid_type_attribute(self):
         with pytest.raises(ValueError):
             cs_test = AveragedCrossspectrum(self.lc1, self.lc2, segment_size=1)
diff --git a/stingray/tests/test_powerspectrum.py b/stingray/tests/test_powerspectrum.py
index 87b488be..bf204198 100644
--- a/stingray/tests/test_powerspectrum.py
+++ b/stingray/tests/test_powerspectrum.py
@@ -121,12 +121,11 @@ class TestPowerspectrum(object):
         assert np.isclose(rms_ps, rms_lc, atol=0.01)
 
     def test_leahy_norm_correct(self):
-        time = np.linspace(0, 10.0, 1e6)
+        time = np.linspace(0, 10.0, 1e5)
         counts = np.random.poisson(1000, size=time.shape[0])
 
         lc = Lightcurve(time, counts)
         ps = Powerspectrum(lc, norm="leahy")
-        print(np.mean(ps.power[1:]))
 
         assert np.isclose(np.mean(ps.power[1:]), 2.0, atol=0.01, rtol=0.01)
 
@@ -280,10 +279,20 @@ class TestAveragedPowerspectrum(object):
 
     def test_one_segment(self):
         segment_size = self.lc.tseg
-        print(segment_size, self.lc.tseg, self.lc.gti)
+
         ps = AveragedPowerspectrum(self.lc, segment_size)
         assert np.isclose(ps.segment_size, segment_size)
 
+    def test_make_empty_periodogram(self):
+        ps = AveragedPowerspectrum()
+        assert ps.norm == "frac"
+        assert ps.freq is None
+        assert ps.power is None
+        assert ps.power_err is None
+        assert ps.df is None
+        assert ps.m == 1
+        assert ps.n is None
+
     @pytest.mark.parametrize('nseg', [1, 2, 3, 5, 10, 20, 100])
     def test_n_segments(self, nseg):
         segment_size = self.lc.tseg/nseg
@@ -297,7 +306,7 @@ class TestAveragedPowerspectrum(object):
         assert ps.m == 2
 
     def test_init_without_segment(self):
-        with pytest.raises(TypeError):
+        with pytest.raises(ValueError):
             assert AveragedPowerspectrum(self.lc)
 
     def test_init_with_nonsense_segment(self):
@@ -307,7 +316,7 @@ class TestAveragedPowerspectrum(object):
 
     def test_init_with_none_segment(self):
         segment_size = None
-        with pytest.raises(TypeError):
+        with pytest.raises(ValueError):
             assert AveragedPowerspectrum(self.lc, segment_size)
 
     def test_init_with_inf_segment(self):
@@ -359,7 +368,7 @@ class TestAveragedPowerspectrum(object):
                           (aps.freq[0]-aps.df*0.5+bin_aps.df*0.5),
                           atol=1e-4, rtol=1e-4)
 
-    @pytest.mark.parametrize('f', [2, 3, 5, 1.5, 1, 85])
+    @pytest.mark.parametrize('f', [20, 30, 50, 15, 1, 850])
     def test_rebin_factor(self, f):
         """
         TODO: Not sure how to write tests for the rebin method!
@@ -420,14 +429,14 @@ class TestAveragedPowerspectrum(object):
         n = 100
         lc_all = []
         for i in range(n):
-            time = np.arange(0.0, 10.0, 10. / 100000)
+            time = np.arange(0.0, 10.0, 10. / 10000)
             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.mean(ps.power), 2.0, atol=1e-2, rtol=1e-2)
         assert np.isclose(np.std(ps.power), 2.0 / np.sqrt(n), atol=0.1, rtol=0.1)