-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add link_test_orbit #109
Add link_test_orbit #109
Conversation
A couple of post-vacation interface thoughts: What do you think about decoupling observations = ObservationSource.get_observations(mjd_min=None, mjd_max=None, obscodes=None) The job of how observations are gathered relative to a test orbit feels like something that should be delegated to the test orbit class (even more so with covariance matrices which we might create as a function of the state vector and covariances that get propagated with the state vector). Here we could add a function to the test orbit class: gathered_observations = test_orbit.gather_observations(observations, method="cell") gathered_observations = test_orbit.gather_observations(observations, method="covariance") |
I suppose one could get real fancy and abstract the method: class PhaseSpaceMapping(ABC):
def filter_observations(self):
pass class CovarianceMapping(PhaseSpaceMapping):
def __init__(self, matrix = np.random.random((6, 6)):
pass class CellMapping(PhaseSpaceMapping):
def __init__(self, radius = 1):
pass Whats tricky here is that the CovarianceMapping will be time-dependent (it might shrink or grow with the test orbit) so maybe this level of abstract over complicates things. |
I think the current structure is preferable. In the current scheme, non-test-orbit-based filtering is pretty simple. See, for example, the "StaticObservationSource" implementation, which always yields the same values. We're also free to write chains of ObservationSources: one that filters by time, a second that filters to only observations that have not been linked in previous THOR runs, a third that filters to objects within the covariance region of a test orbit. If these filters were applied as a method on a test orbit, those would be much harder to express. Maybe we should rename that abstraction to "ObservationFilter" to express this concept a bit better. The root source is something like AIMS or Parquet or whatever, and that's a fairly different thing. And indeed the current implementations expect a pile of observations as input in order to be constructed! |
I guess what isn't fully obvious to me is how we use the current structure for propagated covariance matrices assumed with each test orbit? The way I'm thinking about is that two identical state vectors with different covariance matrices are in fact different test orbits (different volumes of phase space), so they should be coupled together somehow. Maybe we add a |
Ah actually, I see how we would do it. We generate ephemerides inside This definitely points towards us needing to cache or store some of these propagations / ephemerides since it will get expensive otherwise with the number of recomputations. |
Yes, that's exactly how I'd think of it - an additional |
Agreed on naming them |
f22ae8d
to
a864165
Compare
@spenczar Just FYI, I've rebased this branch to main and set the base to main. I'm now working on an integration test and will commit it here. |
a29394f
to
ff0eb7e
Compare
ff0eb7e
to
7a9a859
Compare
7a9a859
to
848800b
Compare
@spenczar and @akoumjian, I've made some pretty substantial updates to some of the underlying functions to get this running. Here is the current high-level interface (using adam_core's test data): Load some test data: from adam_core.utils.helpers import make_observations
from adam_core.utils.helpers import make_real_orbits
exposures, detections, associations = make_observations()
orbits = make_real_orbits() Lets link with a single test orbit (note this function is just going to return the transformed detections): from thor.observations import Observations
from thor.observations.filters import TestOrbitRadiusObservationFilter
from thor import TestOrbit, link_test_orbit
observations = Observations.from_detections_and_exposures(detections, exposures)
test_orbit = TestOrbit.from_orbits(orbits[10])
transformed_observations = link_test_orbit(
test_orbit,
observations,
filters=[
TestOrbitRadiusObservationFilter(radius=50)
]
) Plot the resulting transformed detections: import matplotlib.pyplot as plt
df = transformed_observations.to_dataframe()
fig, ax = plt.subplots(1, 1, dpi=200)
ax.set_aspect("equal")
ax.scatter(df["coordinates.theta_x"], df["coordinates.theta_y"], s=0.1)
ax.set_xlabel(r"$\theta_X$ [deg]")
ax.set_ylabel(r"$\theta_Y$ [deg]") What is coincidentally really cool here is that this dataset has simulated ephemerides from two distinct observatories and spans a total of 60 days. We have some nearly linear motion over that time span! A bunch of things were changed:
To get this working the following PRs in adam_core need to be merged: |
I still need to define an integration test but the adam_core stuff needs to be merged / reviewed first. Early reviews from both of you would be super welcome here. |
…des and checks for freshness
…Orbit.generate_ephemeris_from_observations
b2fdc7d
to
a4a5a79
Compare
…Observations.from_detections_and_exposures
…Observations.get_observers
a4a5a79
to
3272afb
Compare
No description provided.