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 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')
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')