diff --git a/demo/python/astronomy.py b/demo/python/astronomy.py index e42b4cea..995a0368 100644 --- a/demo/python/astronomy.py +++ b/demo/python/astronomy.py @@ -265,6 +265,28 @@ class StateVector: self.vx, self.vy, self.vz, repr(self.t)) + def __add__(self, other): + return StateVector( + self.x + other.x, + self.y + other.y, + self.z + other.z, + self.vx + other.vx, + self.vy + other.vy, + self.vz + other.vz, + self.t + ) + + def __sub__(self, other): + return StateVector( + self.x - other.x, + self.y - other.y, + self.z - other.z, + self.vx - other.vx, + self.vy - other.vy, + self.vz - other.vz, + self.t + ) + @enum.unique class Body(enum.Enum): """The celestial bodies supported by Astronomy Engine calculations. @@ -3978,15 +4000,28 @@ class JupiterMoonsInfo: Attributes ---------- - moon : StateVector[4] - An array of state vectors, one for each of the four major moons - of Jupiter, in the following order: 0=Io, 1=Europa, 2=Ganymede, 3=Callisto. + io : StateVector + The position and velocity of Jupiter's moon Io. + europa : StateVector + The position and velocity of Jupiter's moon Europa. + ganymede : StateVector + The position and velocity of Jupiter's moon Ganymede. + callisto : StateVector + The position and velocity of Jupiter's moon Callisto. """ def __init__(self, moon): - self.moon = moon + self.io = moon[0] + self.europa = moon[1] + self.ganymede = moon[2] + self.callisto = moon[3] def __repr__(self): - return 'JupiterMoonsInfo({})'.format(repr(self.moon)) + return 'JupiterMoonsInfo(io={}, europa={}, ganymede={}, callisto={})'.format( + repr(self.io), + repr(self.europa), + repr(self.ganymede), + repr(self.callisto) + ) def _JupiterMoon_elem2pv(time, mu, A, AL, K, H, Q, P): diff --git a/demo/python/jupiter_moons.py b/demo/python/jupiter_moons.py index b390593b..4cb9da33 100755 --- a/demo/python/jupiter_moons.py +++ b/demo/python/jupiter_moons.py @@ -52,11 +52,18 @@ if __name__ == '__main__': jm = JupiterMoons(backdate) + # Tricky: I'm "cheating" a little bit below by adding Vector `jv` + # to StateVector `jm.`, to result in a Vector position for each moon. + # This works because StateVector has all the fields that Vector has, + # plus the velocity components (vx, vy, vz). + # This is alarming to type purists, but just another normal day of + # "duck typing" for Pythonistas. + PrintBody('Jupiter', jv) - PrintBody('Io', jv + jm.moon[0]) - PrintBody('Europa', jv + jm.moon[1]) - PrintBody('Ganymede', jv + jm.moon[2]) - PrintBody('Callisto', jv + jm.moon[3]) + PrintBody('Io', jv + jm.io) + PrintBody('Europa', jv + jm.europa) + PrintBody('Ganymede', jv + jm.ganymede) + PrintBody('Callisto', jv + jm.callisto) print() sys.exit(0) diff --git a/generate/template/astronomy.py b/generate/template/astronomy.py index 82794623..437bc919 100644 --- a/generate/template/astronomy.py +++ b/generate/template/astronomy.py @@ -265,6 +265,28 @@ class StateVector: self.vx, self.vy, self.vz, repr(self.t)) + def __add__(self, other): + return StateVector( + self.x + other.x, + self.y + other.y, + self.z + other.z, + self.vx + other.vx, + self.vy + other.vy, + self.vz + other.vz, + self.t + ) + + def __sub__(self, other): + return StateVector( + self.x - other.x, + self.y - other.y, + self.z - other.z, + self.vx - other.vx, + self.vy - other.vy, + self.vz - other.vz, + self.t + ) + @enum.unique class Body(enum.Enum): """The celestial bodies supported by Astronomy Engine calculations. @@ -1936,15 +1958,28 @@ class JupiterMoonsInfo: Attributes ---------- - moon : StateVector[4] - An array of state vectors, one for each of the four major moons - of Jupiter, in the following order: 0=Io, 1=Europa, 2=Ganymede, 3=Callisto. + io : StateVector + The position and velocity of Jupiter's moon Io. + europa : StateVector + The position and velocity of Jupiter's moon Europa. + ganymede : StateVector + The position and velocity of Jupiter's moon Ganymede. + callisto : StateVector + The position and velocity of Jupiter's moon Callisto. """ def __init__(self, moon): - self.moon = moon + self.io = moon[0] + self.europa = moon[1] + self.ganymede = moon[2] + self.callisto = moon[3] def __repr__(self): - return 'JupiterMoonsInfo({})'.format(repr(self.moon)) + return 'JupiterMoonsInfo(io={}, europa={}, ganymede={}, callisto={})'.format( + repr(self.io), + repr(self.europa), + repr(self.ganymede), + repr(self.callisto) + ) def _JupiterMoon_elem2pv(time, mu, A, AL, K, H, Q, P): diff --git a/generate/test.py b/generate/test.py index 331b83b3..9ec33213 100755 --- a/generate/test.py +++ b/generate/test.py @@ -109,6 +109,9 @@ def GeoMoon(): #----------------------------------------------------------------------------------------------------------- +def SelectJupiterMoon(jm, mindex): + return [jm.io, jm.europa, jm.ganymede, jm.callisto][mindex] + def AstroCheck(printflag): time = astronomy.Time.Make(1700, 1, 1, 0, 0, 0) stop = astronomy.Time.Make(2200, 1, 1, 0, 0, 0) @@ -147,7 +150,7 @@ def AstroCheck(printflag): jm = astronomy.JupiterMoons(time) if printflag: for mindex in range(4): - moon = jm.moon[mindex] + moon = SelectJupiterMoon(jm, mindex) print('j {:d} {:0.18e} {:0.18e} {:0.18e} {:0.18e} {:0.18e} {:0.18e} {:0.18e} {:0.18e}'.format(mindex, time.tt, time.ut, moon.x, moon.y, moon.z, moon.vx, moon.vy, moon.vz)) time = time.AddDays(dt) return 0 @@ -1813,19 +1816,20 @@ def JupiterMoons_CheckJpl(mindex, tt, pos, vel): vel_tolerance = 9.0e-4 time = astronomy.Time.FromTerrestrialTime(tt) jm = astronomy.JupiterMoons(time) + moon = SelectJupiterMoon(jm, mindex) - dx = v(pos[0] - jm.moon[mindex].x) - dy = v(pos[1] - jm.moon[mindex].y) - dz = v(pos[2] - jm.moon[mindex].z) + dx = v(pos[0] - moon.x) + dy = v(pos[1] - moon.y) + dz = v(pos[2] - moon.z) mag = sqrt(pos[0]*pos[0] + pos[1]*pos[1] + pos[2]*pos[2]) pos_diff = sqrt(dx*dx + dy*dy + dz*dz) / mag if pos_diff > pos_tolerance: print('PY JupiterMoons_CheckJpl(mindex={}, tt={}): excessive position error {}'.format(mindex, tt, pos_diff)) return 1 - dx = v(vel[0] - jm.moon[mindex].vx) - dy = v(vel[1] - jm.moon[mindex].vy) - dz = v(vel[2] - jm.moon[mindex].vz) + dx = v(vel[0] - moon.vx) + dy = v(vel[1] - moon.vy) + dz = v(vel[2] - moon.vz) mag = sqrt(vel[0]*vel[0] + vel[1]*vel[1] + vel[2]*vel[2]) vel_diff = sqrt(dx*dx + dy*dy + dz*dz) / mag if vel_diff > vel_tolerance: diff --git a/source/python/README.md b/source/python/README.md index 5f589eba..27dd7173 100644 --- a/source/python/README.md +++ b/source/python/README.md @@ -507,7 +507,10 @@ and the velocities in AU/day. | Type | Attribute | Description | | --- | --- | --- | -| [`StateVector[4]`](#StateVector[4]) | `moon` | An array of state vectors, one for each of the four major moons of Jupiter, in the following order: 0=Io, 1=Europa, 2=Ganymede, 3=Callisto. | +| [`StateVector`](#StateVector) | `io` | The position and velocity of Jupiter's moon Io. | +| [`StateVector`](#StateVector) | `europa` | The position and velocity of Jupiter's moon Europa. | +| [`StateVector`](#StateVector) | `ganymede` | The position and velocity of Jupiter's moon Ganymede. | +| [`StateVector`](#StateVector) | `callisto` | The position and velocity of Jupiter's moon Callisto. | --- diff --git a/source/python/astronomy/astronomy.py b/source/python/astronomy/astronomy.py index e42b4cea..995a0368 100644 --- a/source/python/astronomy/astronomy.py +++ b/source/python/astronomy/astronomy.py @@ -265,6 +265,28 @@ class StateVector: self.vx, self.vy, self.vz, repr(self.t)) + def __add__(self, other): + return StateVector( + self.x + other.x, + self.y + other.y, + self.z + other.z, + self.vx + other.vx, + self.vy + other.vy, + self.vz + other.vz, + self.t + ) + + def __sub__(self, other): + return StateVector( + self.x - other.x, + self.y - other.y, + self.z - other.z, + self.vx - other.vx, + self.vy - other.vy, + self.vz - other.vz, + self.t + ) + @enum.unique class Body(enum.Enum): """The celestial bodies supported by Astronomy Engine calculations. @@ -3978,15 +4000,28 @@ class JupiterMoonsInfo: Attributes ---------- - moon : StateVector[4] - An array of state vectors, one for each of the four major moons - of Jupiter, in the following order: 0=Io, 1=Europa, 2=Ganymede, 3=Callisto. + io : StateVector + The position and velocity of Jupiter's moon Io. + europa : StateVector + The position and velocity of Jupiter's moon Europa. + ganymede : StateVector + The position and velocity of Jupiter's moon Ganymede. + callisto : StateVector + The position and velocity of Jupiter's moon Callisto. """ def __init__(self, moon): - self.moon = moon + self.io = moon[0] + self.europa = moon[1] + self.ganymede = moon[2] + self.callisto = moon[3] def __repr__(self): - return 'JupiterMoonsInfo({})'.format(repr(self.moon)) + return 'JupiterMoonsInfo(io={}, europa={}, ganymede={}, callisto={})'.format( + repr(self.io), + repr(self.europa), + repr(self.ganymede), + repr(self.callisto) + ) def _JupiterMoon_elem2pv(time, mu, A, AL, K, H, Q, P):