def test_keplerSTM_init(self):
        """
        Test method: initialize all possible constructors and sanity check generated objects
        """

        test_str = 'EXOSIMS.util.KeplerSTM_C.CyKeplerSTM'

        ps = keplerSTM.planSys(np.random.randn(6), np.random.rand(1))
        if test_str in sys.modules:
            self.assertTrue(ps.havec)
        else:
            self.assertFalse(ps.havec)
        self.assertEqual(ps.algOrder[0], ps.calcSTM)
        self.assertEqual(ps.nplanets, 1)

        ps2 = keplerSTM.planSys(np.random.randn(6),
                                np.random.rand(1),
                                noc=True,
                                prefVallado=True)
        self.assertFalse(ps2.havec)
        self.assertEqual(ps2.algOrder[1], ps2.calcSTM)
        self.assertEqual(ps2.nplanets, 1)

        ps3 = keplerSTM_indprop.planSys(np.random.randn(6), np.random.rand(1))
        if test_str in sys.modules:
            self.assertTrue(ps3.havec)
        else:
            self.assertFalse(ps3.havec)
        self.assertEqual(ps3.nplanets, 1)

        ps4 = keplerSTM_indprop.planSys(np.random.randn(6),
                                        np.random.rand(1),
                                        noc=True)
        self.assertFalse(ps4.havec)
        self.assertEqual(ps4.nplanets, 1)

        with self.assertRaises(Exception):
            ps0 = keplerSTM.planSys(np.random.randn(6), np.random.rand(2))

        with self.assertRaises(Exception):
            ps0 = keplerSTM.planSys(np.random.randn(9), np.random.rand(1))

        with self.assertRaises(Exception):
            ps0 = keplerSTM_indprop.planSys(np.random.randn(6),
                                            np.random.rand(2))

        with self.assertRaises(Exception):
            ps0 = keplerSTM_indprop.planSys(np.random.randn(9),
                                            np.random.rand(1))
Exemple #2
0
    def test_keplerSTM_init(self):
        """
        Test method: initialize all possible constructors and sanity check generated objects
        """

        test_str = 'EXOSIMS.util.KeplerSTM_C.CyKeplerSTM'

        ps = keplerSTM.planSys(np.random.randn(6),np.random.rand(1))
        if test_str in sys.modules:
            self.assertTrue(ps.havec)
        else:
            self.assertFalse(ps.havec)
        self.assertEqual(ps.algOrder[0],ps.calcSTM)
        self.assertEqual(ps.nplanets,1)

        ps2 = keplerSTM.planSys(np.random.randn(6),np.random.rand(1),noc=True,prefVallado=True)
        self.assertFalse(ps2.havec)
        self.assertEqual(ps2.algOrder[1],ps2.calcSTM)
        self.assertEqual(ps2.nplanets,1)

        ps3 = keplerSTM_indprop.planSys(np.random.randn(6),np.random.rand(1))
        if test_str in sys.modules:
            self.assertTrue(ps3.havec)
        else:
            self.assertFalse(ps3.havec)
        self.assertEqual(ps3.nplanets,1)


        ps4 = keplerSTM_indprop.planSys(np.random.randn(6),np.random.rand(1),noc=True)
        self.assertFalse(ps4.havec)
        self.assertEqual(ps4.nplanets,1)

        with self.assertRaises(Exception):
            ps0 = keplerSTM.planSys(np.random.randn(6),np.random.rand(2))

        with self.assertRaises(Exception):
            ps0 = keplerSTM.planSys(np.random.randn(9),np.random.rand(1))

        with self.assertRaises(Exception):
            ps0 = keplerSTM_indprop.planSys(np.random.randn(6),np.random.rand(2))

        with self.assertRaises(Exception):
            ps0 = keplerSTM_indprop.planSys(np.random.randn(9),np.random.rand(1))
    def propag_system(self, sInd, dt):
        """Propagates planet time-dependant parameters: position, velocity, 
        planet-star distance, apparent separation, phase function, surface brightness 
        of exo-zodiacal light, delta magnitude, and working angle.
        
        This method uses the Kepler state transition matrix to propagate a 
        planet's state (position and velocity vectors) forward in time using 
        the Kepler state transition matrix.
        
        Args:
            sInd (integer):
                Index of the target system of interest
            dt (astropy Quantity):
                Time increment in units of day, for planet position propagation
        
        """

        PPMod = self.PlanetPhysicalModel
        ZL = self.ZodiacalLight
        TL = self.TargetList

        assert np.isscalar(sInd), \
                "Can only propagate one system at a time, sInd must be scalar."
        # check for planets around this target
        pInds = np.where(self.plan2star == sInd)[0]
        if len(pInds) == 0:
            return
        # check for positive time increment
        assert dt >= 0, "Time increment (dt) to propagate a planet must be positive."
        if dt == 0:
            return

        # Calculate initial positions in AU and velocities in AU/day
        r0 = self.r[pInds].to('AU').value
        v0 = self.v[pInds].to('AU/day').value
        # stack dimensionless positions and velocities
        nPlans = pInds.size
        x0 = np.reshape(np.concatenate((r0, v0), axis=1), nPlans * 6)

        # Calculate vector of gravitational parameter in AU3/day2
        Ms = TL.MsTrue[[sInd]]
        Mp = self.Mp[pInds]
        mu = (const.G * (Mp + Ms)).to('AU3/day2').value

        # use keplerSTM.py to propagate the system
        prop = planSys(x0, mu, epsmult=10.)
        try:
            prop.takeStep(dt.to('day').value)
        except ValueError:
            #try again with larger epsmult and two steps to force convergence
            prop = planSys(x0, mu, epsmult=100.)
            try:
                prop.takeStep(dt.to('day').value / 2.)
                prop.takeStep(dt.to('day').value / 2.)
            except ValueError:
                raise ValueError('planSys error')

        # split off position and velocity vectors
        x1 = np.array(np.hsplit(prop.x0, 2 * nPlans))
        rind = np.array(range(0, len(x1), 2))  # even indices
        vind = np.array(range(1, len(x1), 2))  # odd indices

        # update planets' position, velocity, planet-star distance, apparent, separation,
        # phase function, exozodi surface brightness, delta magnitude and working angle
        self.r[pInds] = x1[rind] * u.AU
        self.v[pInds] = x1[vind] * u.AU / u.day
        # if sys.version_info[0] > 2:
        #     self.d[pInds] = np.linalg.norm(self.r[pInds], axis=1)
        #     self.s[pInds] = np.linalg.norm(self.r[pInds,0:2], axis=1)
        # else:
        #     self.d[pInds] = np.linalg.norm(self.r[pInds], axis=1)*self.r.unit
        #     self.s[pInds] = np.linalg.norm(self.r[pInds,0:2], axis=1)*self.r.unit

        try:
            self.d[pInds] = np.linalg.norm(self.r[pInds], axis=1)
            self.phi[pInds] = PPMod.calc_Phi(
                np.arccos(self.r[pInds, 2] / self.d[pInds]))
        except:
            self.d[pInds] = np.linalg.norm(self.r[pInds], axis=1) * self.r.unit
            self.phi[pInds] = PPMod.calc_Phi(
                np.arccos(self.r[pInds, 2] / self.d[pInds]))

        # self.fEZ[pInds] = ZL.fEZ(TL.MV[sInd], self.I[pInds], self.d[pInds])
        self.dMag[pInds] = deltaMag(self.p[pInds], self.Rp[pInds],
                                    self.d[pInds], self.phi[pInds])
        try:
            self.s[pInds] = np.linalg.norm(self.r[pInds, 0:2], axis=1)
            self.WA[pInds] = np.arctan(self.s[pInds] /
                                       TL.dist[sInd]).to('arcsec')
        except:
            self.s[pInds] = np.linalg.norm(self.r[pInds, 0:2],
                                           axis=1) * self.r.unit
            self.WA[pInds] = np.arctan(self.s[pInds] /
                                       TL.dist[sInd]).to('arcsec')
Exemple #4
0
 def propag_system(self, sInd, currentTimeNorm):
     """Propagates planet time-dependant parameters: position, velocity, 
     planet-star distance, apparent separation, phase function, surface brightness 
     of exo-zodiacal light, delta magnitude, working angle, and the planet 
     current time array.
     
     This method uses the Kepler state transition matrix to propagate a 
     planet's state (position and velocity vectors) forward in time using 
     the Kepler state transition matrix.
     
     Args:
         sInd (integer):
             Index of the target system of interest
         currentTimeNorm (astropy Quantity):
             Current mission time normalized to zero at mission start in units of day
     
     """
     
     PPMod = self.PlanetPhysicalModel
     ZL = self.ZodiacalLight
     TL = self.TargetList
     
     assert np.isscalar(sInd), "Can only propagate one system at a time, \
             sInd must be scalar."
     # check for planets around this target
     pInds = np.where(self.plan2star == sInd)[0]
     if not np.any(pInds):
         return
     # check for positive time increment
     dt = currentTimeNorm - self.planTime[pInds][0]
     assert dt >= 0, "Time increment (dt) to propagate a planet must be positive."
     if dt == 0:
         return
     
     # Initial positions in AU and velocities in AU/day
     rold = self.r[pInds].to('AU').value
     vold = self.v[pInds].to('AU/day').value
     # stack dimensionless positions and velocities
     x0 = np.array([])
     for i in xrange(len(rold)):
         x0 = np.hstack((x0, rold[i], vold[i]))
     
     # calculate system's distance and masses
     sDist = TL.dist[[sInd]]
     Ms = TL.MsTrue[[sInd]]*const.M_sun
     Mp = self.Mp[pInds]
     # calculate vector of gravitational parameter
     mu = (const.G*(Mp + Ms)).to('AU3/day2').value
     
     # use keplerSTM.py to propagate the system
     prop = planSys(x0, mu, epsmult=10.)
     try:
         prop.takeStep(dt.to('day').value)
     except ValueError:
         #try again with larger epsmult and two steps to force convergence 
         prop = planSys(x0, mu, epsmult=100.)
         try:
             prop.takeStep(dt.to('day').value/2.)
             prop.takeStep(dt.to('day').value/2.)
         except ValueError:
             raise ValueError('planSys error')
     
     # split off position and velocity vectors
     x1 = np.array(np.hsplit(prop.x0, 2*len(rold)))
     rind = np.array(range(0,len(x1),2)) # even indices
     vind = np.array(range(1,len(x1),2)) # odd indices
     
     # update planets' position, velocity, planet-star distance, apparent 
     # separation, phase function, exozodi surface brightness, delta magnitude, 
     # working angle, and current time
     self.r[pInds] = x1[rind]*u.AU
     self.v[pInds] = x1[vind]*u.AU/u.day
     self.d[pInds] = np.sqrt(np.sum(self.r[pInds]**2, axis=1))
     self.s[pInds] = np.sqrt(np.sum(self.r[pInds,0:2]**2, axis=1))
     self.phi[pInds] = PPMod.calc_Phi(np.arcsin(self.s[pInds]/self.d[pInds]))
     self.fEZ[pInds] = ZL.fEZ(TL, sInd, self.I[pInds],self.d[pInds])
     self.dMag[pInds] = deltaMag(self.p[pInds],self.Rp[pInds],self.d[pInds],self.phi[pInds])
     self.WA[pInds] = np.arctan(self.s[pInds]/sDist).to('mas')
     self.planTime[pInds] = currentTimeNorm
 def propag_system(self, sInd, dt):
     """Propagates planet time-dependant parameters: position, velocity, 
     planet-star distance, apparent separation, phase function, surface brightness 
     of exo-zodiacal light, delta magnitude, and working angle.
     
     This method uses the Kepler state transition matrix to propagate a 
     planet's state (position and velocity vectors) forward in time using 
     the Kepler state transition matrix.
     
     Args:
         sInd (integer):
             Index of the target system of interest
         dt (astropy Quantity):
             Time increment in units of day, for planet position propagation
     
     """
     
     PPMod = self.PlanetPhysicalModel
     ZL = self.ZodiacalLight
     TL = self.TargetList
     
     assert np.isscalar(sInd), \
             "Can only propagate one system at a time, sInd must be scalar."
     # check for planets around this target
     pInds = np.where(self.plan2star == sInd)[0]
     if len(pInds) == 0:
         return
     # check for positive time increment
     assert dt >= 0, "Time increment (dt) to propagate a planet must be positive."
     if dt == 0:
         return
     
     # Calculate initial positions in AU and velocities in AU/day
     r0 = self.r[pInds].to('AU').value
     v0 = self.v[pInds].to('AU/day').value
     # stack dimensionless positions and velocities
     nPlans = pInds.size
     x0 = np.reshape(np.concatenate((r0, v0), axis=1), nPlans*6)
     
     # Calculate vector of gravitational parameter in AU3/day2
     Ms = TL.MsTrue[[sInd]]
     Mp = self.Mp[pInds]
     mu = (const.G*(Mp + Ms)).to('AU3/day2').value
     
     # use keplerSTM.py to propagate the system
     prop = planSys(x0, mu, epsmult=10.)
     try:
         prop.takeStep(dt.to('day').value)
     except ValueError:
         #try again with larger epsmult and two steps to force convergence 
         prop = planSys(x0, mu, epsmult=100.)
         try:
             prop.takeStep(dt.to('day').value/2.)
             prop.takeStep(dt.to('day').value/2.)
         except ValueError:
             raise ValueError('planSys error')
     
     # split off position and velocity vectors
     x1 = np.array(np.hsplit(prop.x0, 2*nPlans))
     rind = np.array(range(0, len(x1), 2)) # even indices
     vind = np.array(range(1, len(x1), 2)) # odd indices
     
     # update planets' position, velocity, planet-star distance, apparent, separation,
     # phase function, exozodi surface brightness, delta magnitude and working angle
     self.r[pInds] = x1[rind]*u.AU
     self.v[pInds] = x1[vind]*u.AU/u.day
     self.d[pInds] = np.linalg.norm(self.r[pInds], axis=1)*self.r.unit
     self.s[pInds] = np.linalg.norm(self.r[pInds,0:2], axis=1)*self.r.unit
     self.phi[pInds] = PPMod.calc_Phi(np.arccos(self.r[pInds,2]/self.d[pInds]))
     self.fEZ[pInds] = ZL.fEZ(TL.MV[sInd], self.I[pInds], self.d[pInds])
     self.dMag[pInds] = deltaMag(self.p[pInds], self.Rp[pInds], self.d[pInds],
             self.phi[pInds])
     self.WA[pInds] = np.arctan(self.s[pInds]/TL.dist[sInd]).to('arcsec')