Beispiel #1
0
    def test_interpolated_g(self):
        """checks that the interpolation of g(n,e) is not producing
        any large errors"""
        # create random binaries
        np.random.seed(42)
        n_values = 50
        m_1 = np.random.uniform(0, 10, n_values) * u.Msun
        m_2 = np.random.uniform(0, 10, n_values) * u.Msun
        dist = np.random.uniform(0, 30, n_values) * u.kpc
        f_orb = 10**(np.random.uniform(-5, -3, n_values)) * u.Hz
        ecc = np.random.uniform(0.0, 0.9, n_values)

        # compare snr calculated directly with through Source
        sources_interp = source.Source(m_1=m_1,
                                       m_2=m_2,
                                       f_orb=f_orb,
                                       ecc=ecc,
                                       dist=dist,
                                       interpolate_g=True)

        sources = source.Source(m_1=m_1,
                                m_2=m_2,
                                f_orb=f_orb,
                                ecc=ecc,
                                dist=dist,
                                interpolate_g=False)

        interp_snr = sources_interp.get_snr(verbose=True)
        snr = sources.get_snr(verbose=True)

        self.assertTrue(np.allclose(interp_snr, snr, atol=1e-1, rtol=1e-1))
Beispiel #2
0
    def test_source_snr_multi(self):
        """check that source calculates snr in correct way"""

        # create random (circular/stationary) binaries
        n_values = 500
        m_1 = np.random.uniform(0, 10, n_values) * u.Msun
        m_2 = np.random.uniform(0, 10, n_values) * u.Msun
        dist = np.random.uniform(0, 30, n_values) * u.kpc
        f_orb = 10**(np.random.uniform(-3, -2, n_values)) * u.Hz
        ecc = np.random.uniform(0.1, 0.2, n_values)
        n_proc = 2
        sources = source.Source(m_1=m_1,
                                m_2=m_2,
                                f_orb=f_orb,
                                ecc=ecc,
                                dist=dist,
                                n_proc=n_proc)

        sources_1 = source.Source(m_1=m_1,
                                  m_2=m_2,
                                  f_orb=f_orb,
                                  ecc=ecc,
                                  dist=dist,
                                  n_proc=1)

        # compare using 1 or 2 processors
        snr_2 = sources.get_snr(verbose=True)
        snr_1 = sources_1.get_snr(verbose=True)

        self.assertTrue(np.allclose(snr_2, snr_1))
Beispiel #3
0
    def test_updating_sc_params(self):
        """ ensuring that updating the sc params always works """
        original_sc_params = {
            "instrument": "LISA",
            "custom_psd": None,
            "t_obs": "auto",
            "L": "auto",
            "approximate_R": False,
            "confusion_noise": "auto"
        }

        sources = source.Source(m_1=1 * u.Msun,
                                m_2=1 * u.Msun,
                                f_orb=1e-3 * u.Hz,
                                ecc=0.2,
                                dist=10 * u.kpc,
                                sc_params=original_sc_params)

        sources.update_sc_params({"instrument": "TianQin"})

        correct_final_sc_params = {
            "instrument": "TianQin",
            "t_obs": "auto",
            "L": "auto",
            "approximate_R": False,
            "confusion_noise": "auto",
            "custom_psd": None,
        }
        self.assertTrue(correct_final_sc_params == sources._sc_params)
Beispiel #4
0
    def test_interpolated_sc(self):
        """checks that interpolated of LISA SC is not producing any large
        errors"""
        # create random binaries
        n_values = 50
        m_1 = np.random.uniform(0, 10, n_values) * u.Msun
        m_2 = np.random.uniform(0, 10, n_values) * u.Msun
        dist = np.random.uniform(0, 30, n_values) * u.kpc
        f_orb = 10**(np.random.uniform(-5, -1, n_values)) * u.Hz
        ecc = np.random.uniform(0.0, 0.4, n_values)

        # compare snr calculated directly with through Source
        sources = source.Source(m_1=m_1,
                                m_2=m_2,
                                f_orb=f_orb,
                                ecc=ecc,
                                dist=dist)
        interp_snr = sources.get_snr(verbose=True)

        # erase interpolation
        sources.interpolate_sc = False
        sources.update_sc_params(None)

        snr = sources.get_snr(verbose=True)

        self.assertTrue(np.allclose(interp_snr, snr, atol=1e-1, rtol=1e-1))
Beispiel #5
0
    def test_source_strain(self):
        """check that source calculate strain correctly"""
        n_values = 500
        m_1 = np.random.uniform(0, 10, n_values) * u.Msun
        m_2 = np.random.uniform(0, 10, n_values) * u.Msun
        m_c = utils.chirp_mass(m_1, m_2)
        dist = np.random.uniform(0, 30, n_values) * u.kpc
        f_orb = 10**(np.random.uniform(-5, -4, n_values)) * u.Hz
        ecc = np.repeat(0.0, n_values)

        sources = source.Source(m_1=m_1,
                                m_2=m_2,
                                f_orb=f_orb,
                                ecc=ecc,
                                dist=dist,
                                interpolate_g=False)

        source_strain = sources.get_h_0_n([1, 2, 3])
        true_strain = strain.h_0_n(m_c=m_c,
                                   f_orb=f_orb,
                                   ecc=ecc,
                                   n=[1, 2, 3],
                                   dist=dist)[:, 0, :]

        self.assertTrue(np.all(source_strain == true_strain))

        source_char_strain = sources.get_h_c_n([1, 2, 3])
        true_char_strain = strain.h_c_n(m_c=m_c,
                                        f_orb=f_orb,
                                        ecc=ecc,
                                        n=[1, 2, 3],
                                        dist=dist)[:, 0, :]

        self.assertTrue(np.all(source_char_strain == true_char_strain))
Beispiel #6
0
    def test_source_snr(self):
        """check that source calculates snr in correct way"""

        # create random (circular/stationary) binaries
        n_values = 500
        t_obs = 4 * u.yr
        m_1 = np.random.uniform(0, 10, n_values) * u.Msun
        m_2 = np.random.uniform(0, 10, n_values) * u.Msun
        m_c = utils.chirp_mass(m_1, m_2)
        dist = np.random.uniform(0, 30, n_values) * u.kpc
        f_orb = 10**(np.random.uniform(-5, -4, n_values)) * u.Hz
        ecc = np.repeat(0.0, n_values)
        sources = source.Source(m_1=m_1,
                                m_2=m_2,
                                f_orb=f_orb,
                                ecc=ecc,
                                dist=dist)

        # compare snr calculated directly with through Source
        snr_direct = snr.snr_circ_stationary(m_c=m_c,
                                             f_orb=f_orb,
                                             dist=dist,
                                             t_obs=t_obs)
        snr_source = sources.get_snr(verbose=True)

        self.assertTrue(np.allclose(snr_direct, snr_source))

        # repeat the same test for eccentric systems
        ecc = np.random.uniform(sources.ecc_tol, 0.1, n_values)
        sources.ecc = ecc

        snr_direct = snr.snr_ecc_stationary(m_c=m_c,
                                            f_orb=f_orb,
                                            ecc=ecc,
                                            dist=dist,
                                            t_obs=t_obs,
                                            harmonics_required=10)
        snr_source = sources.get_snr(verbose=True)

        self.assertTrue(np.allclose(snr_direct, snr_source))
Beispiel #7
0
    def test_amplitude_modulation_h_c_n(self):
        """Make sure that the amplitude modulated strains are correct.
        Note that this is very redundant with the utils modulation tests"""
        n_values = 500
        m_1 = np.random.uniform(0, 10, n_values) * u.Msun
        m_2 = np.random.uniform(0, 10, n_values) * u.Msun
        m_c = utils.chirp_mass(m_1, m_2)
        dist = np.random.uniform(0, 30, n_values) * u.kpc
        f_orb = 10**(np.random.uniform(-5, -4, n_values)) * u.Hz
        ecc = np.repeat(0.0, n_values)
        incs = np.arccos(np.random.uniform(-1, 1, n_values)) * u.rad
        thetas = np.arcsin(np.random.uniform(-1, 1, n_values)) * u.rad
        phis = np.random.uniform(0, 2 * np.pi, n_values) * u.rad
        psis = np.random.uniform(0, 2 * np.pi, n_values) * u.rad

        positions = SkyCoord(phis,
                             thetas,
                             distance=dist,
                             frame='heliocentrictrueecliptic')

        sources = source.Source(m_1=m_1,
                                m_2=m_2,
                                f_orb=f_orb,
                                ecc=ecc,
                                dist=dist,
                                position=positions,
                                inclination=incs,
                                polarisation=psis,
                                interpolate_g=False)
        source_strains = sources.get_h_c_n([1, 2, 3])
        true_strain = strain.h_c_n(m_c=m_c,
                                   f_orb=f_orb,
                                   ecc=ecc,
                                   dist=dist,
                                   position=positions,
                                   inclination=incs,
                                   polarisation=psis,
                                   n=[1, 2, 3])[:, 0, :]
        self.assertTrue(np.all(source_strains == true_strain))
Beispiel #8
0
    def test_evolving_subclass(self):
        # create random (circular/evolving) binaries
        n_values = 500
        m_1 = np.random.uniform(5, 10, n_values) * u.Msun
        m_2 = np.random.uniform(5, 10, n_values) * u.Msun
        dist = np.random.uniform(0, 30, n_values) * u.kpc
        f_orb = 10**(np.random.uniform(-1.2, -0.5, n_values)) * u.Hz
        ecc = np.repeat(0.0, n_values)

        # compare snr calculated directly with through Source
        sources = source.Source(m_1=m_1,
                                m_2=m_2,
                                f_orb=f_orb,
                                ecc=ecc,
                                dist=dist)
        evolving_sources = source.Evolving(m_1=m_1,
                                           m_2=m_2,
                                           f_orb=f_orb,
                                           ecc=ecc,
                                           dist=dist)
        self.assertTrue(
            np.allclose(sources.get_snr(verbose=True),
                        evolving_sources.get_snr(verbose=True)))
Beispiel #9
0
    def test_evolution_functions(self):
        """Test that evolving sources works as expected"""
        n_values = 50
        m_1 = np.random.uniform(0, 10, n_values) * u.Msun
        m_2 = np.random.uniform(0, 10, n_values) * u.Msun
        dist = np.random.uniform(0, 30, n_values) * u.kpc
        f_orb = 10**(np.random.uniform(-5, -1, n_values)) * u.Hz
        ecc = np.linspace(0.0, 0.4, n_values)

        # compare snr calculated directly with through Source
        sources = source.Source(m_1=m_1,
                                m_2=m_2,
                                f_orb=f_orb,
                                ecc=ecc,
                                dist=dist,
                                interpolate_g=False,
                                interpolate_sc=False)

        # calculate the merger times
        t_merge = sources.get_merger_time(save_in_class=False)

        # create a new class after evolving every source for 10 years
        evolved_sources = sources.evolve_sources(10 * u.yr,
                                                 create_new_class=True)

        # evolve one of the evolved sources for a little more time
        t_evol = np.zeros(n_values) * u.yr
        t_evol[0] = 1 * u.yr
        evolved_sources.evolve_sources(t_evol)

        # ensure that merger times have been updated correctly
        final_merger_times = t_merge - (10 * u.yr)
        final_merger_times[0] -= 1 * u.yr
        final_merger_times[final_merger_times < 0 * u.yr] = 0 * u.yr
        self.assertTrue(
            np.allclose(final_merger_times, evolved_sources.t_merge))
Beispiel #10
0
    def test_bad_input(self):
        """checks that Source handles bad input well"""

        n_values = 10
        m_1 = np.random.uniform(0, 10, n_values) * u.Msun
        m_2 = np.random.uniform(0, 10, n_values) * u.Msun
        ecc = np.random.uniform(0.0, 0.95, n_values)
        dist = np.random.uniform(0, 10, n_values) * u.kpc
        f_orb = 10**(np.random.uniform(-5, -1, n_values)) * u.Hz
        position = SkyCoord(lat=np.random.uniform(0.0, 90, n_values) * u.deg,
                            lon=np.random.uniform(0, 360, n_values) * u.deg,
                            distance=dist,
                            frame="heliocentrictrueecliptic")
        inclination = np.arcsin(np.random.uniform(-1, 1, n_values)) * u.rad
        polarisation = np.random.uniform(0, 2 * np.pi, n_values) * u.rad

        # try creating sources with no f_orb or a
        no_worries = True
        try:
            source.Source(m_1=m_1, m_2=m_2, ecc=ecc, dist=dist)
        except ValueError:
            no_worries = False
        self.assertFalse(no_worries)

        # try creating sources with no units
        no_worries = True
        try:
            source.Source(m_1=m_1,
                          m_2=m_2,
                          ecc=ecc,
                          dist=dist.value,
                          f_orb=f_orb)
        except AssertionError:
            no_worries = False
        self.assertFalse(no_worries)

        # try creating sources with only single source (should be fine)
        no_worries = True
        source.Source(m_1=1 * u.Msun,
                      m_2=1 * u.Msun,
                      ecc=0.1,
                      dist=8 * u.kpc,
                      f_orb=3e-4 * u.Hz)
        self.assertTrue(no_worries)

        # try creating sources with only single source with some in arrays
        no_worries = True
        source.Source(m_1=1 * u.Msun,
                      m_2=1 * u.Msun,
                      ecc=[0.1],
                      dist=8 * u.kpc,
                      f_orb=3e-4 * u.Hz)
        self.assertTrue(no_worries)

        # try creating a source with inclination but not position
        no_worries = True
        try:
            source.Source(m_1=m_1,
                          m_2=m_2,
                          ecc=ecc,
                          dist=dist,
                          f_orb=f_orb,
                          inclination=inclination)
        except ValueError:
            no_worries = False
        self.assertFalse(no_worries)

        # try creating a source with polarisation but not position
        no_worries = True
        try:
            source.Source(m_1=m_1,
                          m_2=m_2,
                          ecc=ecc,
                          dist=dist,
                          f_orb=f_orb,
                          polarisation=polarisation)
        except ValueError:
            no_worries = False
        self.assertFalse(no_worries)

        # create a source with position but not inclination or polarisation with eccentric sources
        no_worries = True
        try:
            source.Source(m_1=m_1,
                          m_2=m_2,
                          ecc=ecc,
                          dist=dist,
                          f_orb=f_orb,
                          position=position)
        except ValueError:
            no_worries = False
        self.assertFalse(no_worries)

        # create a source with position but not inclination or polarisation with circular sources
        ecc = np.zeros_like(ecc)
        no_worries = True
        try:
            source.Source(m_1=m_1,
                          m_2=m_2,
                          ecc=ecc,
                          dist=dist,
                          f_orb=f_orb,
                          position=position)
        except ValueError:
            no_worries = False
        self.assertTrue(no_worries)

        # try creating sources with different length arrays
        no_worries = True
        dist = np.append(dist, 8 * u.kpc)
        try:
            source.Source(m_1=m_1, m_2=m_2, ecc=ecc, dist=dist, f_orb=f_orb)
        except ValueError:
            no_worries = False
        self.assertFalse(no_worries)
Beispiel #11
0
    def test_masks(self):
        """checks that the masks are being produced correctly"""
        n_values = 10000
        dist = np.random.uniform(0, 30, n_values) * u.kpc

        # all stationary and circular
        m_1 = np.random.uniform(0, 10, n_values) * u.Msun
        m_2 = np.random.uniform(0, 10, n_values) * u.Msun
        f_orb = 10**(np.random.uniform(-7, -5, n_values)) * u.Hz
        ecc = np.random.uniform(0.0, 0.0, n_values)

        sources = source.Source(m_1=m_1,
                                m_2=m_2,
                                ecc=ecc,
                                dist=dist,
                                f_orb=f_orb,
                                interpolate_g=False)
        self.assertTrue(
            sources.get_source_mask(circular=True, stationary=True).all())

        # all stationary and eccentric
        m_1 = np.random.uniform(0, 10, n_values) * u.Msun
        m_2 = np.random.uniform(0, 10, n_values) * u.Msun
        f_orb = 10**(np.random.uniform(-7, -5, n_values)) * u.Hz
        ecc = np.random.uniform(0.1, 0.2, n_values)

        sources = source.Source(m_1=m_1,
                                m_2=m_2,
                                ecc=ecc,
                                dist=dist,
                                f_orb=f_orb,
                                interpolate_g=False)
        self.assertTrue(
            sources.get_source_mask(circular=False, stationary=True).all())

        # all evolving and circular
        m_1 = np.random.uniform(5, 10, n_values) * u.Msun
        m_2 = np.random.uniform(5, 10, n_values) * u.Msun
        f_orb = 10**(np.random.uniform(-1, 0, n_values)) * u.Hz
        ecc = np.random.uniform(0.0, 0.0, n_values)

        sources = source.Source(m_1=m_1,
                                m_2=m_2,
                                ecc=ecc,
                                dist=dist,
                                f_orb=f_orb,
                                interpolate_g=False)
        self.assertTrue(
            sources.get_source_mask(circular=True, stationary=False).all())

        # all evolving and eccentric
        m_1 = np.random.uniform(5, 10, n_values) * u.Msun
        m_2 = np.random.uniform(5, 10, n_values) * u.Msun
        f_orb = 10**(np.random.uniform(-1, 0, n_values)) * u.Hz
        ecc = np.random.uniform(0.1, 0.9, n_values)

        sources = source.Source(m_1=m_1,
                                m_2=m_2,
                                ecc=ecc,
                                dist=dist,
                                f_orb=f_orb,
                                interpolate_g=False)
        self.assertTrue(
            sources.get_source_mask(circular=False, stationary=False).all())

        # check it works fine if you give Nones
        self.assertTrue(
            sources.get_source_mask(circular=None, stationary=None).all())

        # check it crashes if you give nonesense input
        no_worries = True
        try:
            sources.get_source_mask(circular="ridiculous input")
        except ValueError:
            no_worries = False
        self.assertFalse(no_worries)

        # check it crashes if you give nonesense input
        no_worries = True
        try:
            sources.get_source_mask(stationary="ridiculous input")
        except ValueError:
            no_worries = False
        self.assertFalse(no_worries)