Skip to content

Commit 08b0e48

Browse files
committed
some further plot updates
1 parent 3b349f0 commit 08b0e48

File tree

3 files changed

+375
-258
lines changed

3 files changed

+375
-258
lines changed

src/adam_impact_study/analysis/main.py

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import argparse
1+
22
import logging
33
import pathlib
44
from typing import Literal, Optional, Union
@@ -535,6 +535,60 @@ def compute_observation_cadence(
535535
)
536536

537537

538+
class MaximumImpactProbabilityPriorToImpact(qv.Table):
539+
orbit_id = qv.LargeStringColumn()
540+
maximum_impact_probability = qv.Float64Column(nullable=True)
541+
542+
543+
def compute_maximum_impact_probability_5_years_prior_to_impact(
544+
impactor_orbits: ImpactorOrbits,
545+
results: WindowResult,
546+
) -> MaximumImpactProbabilityPriorToImpact:
547+
"""
548+
Compute the maximum impact probability 5 years prior to impact for each object.
549+
"""
550+
maximum_impact_probability_prior_to_impact = (
551+
MaximumImpactProbabilityPriorToImpact.empty()
552+
)
553+
unique_orbits = impactor_orbits.orbit_id.unique()
554+
for orbit_id in unique_orbits:
555+
impactor_orbit = impactor_orbits.select("orbit_id", orbit_id)
556+
orbit_results = results.select("orbit_id", orbit_id)
557+
if len(orbit_results) == 0:
558+
maximum_impact_probability_prior_to_impact = qv.concatenate(
559+
[
560+
maximum_impact_probability_prior_to_impact,
561+
MaximumImpactProbabilityPriorToImpact.from_kwargs(
562+
orbit_id=[orbit_id], maximum_impact_probability=[None]
563+
),
564+
]
565+
)
566+
continue
567+
568+
# Filter windows to those five years prior to impact
569+
five_years_prior_to_impact = impactor_orbit.impact_time.add_days(365 * -5)
570+
windows_five_years_prior_to_impact = orbit_results.apply_mask(
571+
pc.greater_equal(
572+
orbit_results.observation_end.mjd(), five_years_prior_to_impact.mjd()[0]
573+
)
574+
)
575+
576+
maximum_impact_probability = pc.max(
577+
windows_five_years_prior_to_impact.impact_probability
578+
).as_py()
579+
maximum_impact_probability_prior_to_impact = qv.concatenate(
580+
[
581+
maximum_impact_probability_prior_to_impact,
582+
MaximumImpactProbabilityPriorToImpact.from_kwargs(
583+
orbit_id=[orbit_id],
584+
maximum_impact_probability=[maximum_impact_probability],
585+
),
586+
]
587+
)
588+
589+
return maximum_impact_probability_prior_to_impact
590+
591+
538592
class CompletenessByDiameter(qv.Table):
539593
diameter = qv.Float64Column()
540594
percentage_discovered = qv.Float64Column()
@@ -628,14 +682,18 @@ def _orbit_complete_status(
628682
# No observations means an IP of 0.
629683
if len(observations) == 0:
630684
return "complete"
631-
685+
632686
# If there are no windows, the object is complete
633687
# This can occur if the observations occur over less than 3 unique nights
634688
if len(window_results) == 0:
635689
return "complete"
636690

637-
assert len(observations.orbit_id.unique().to_pylist()) == 1, "Observations must be for a single orbit"
638-
assert len(window_results.orbit_id.unique().to_pylist()) == 1, "Window results must be for a single orbit"
691+
assert (
692+
len(observations.orbit_id.unique().to_pylist()) == 1
693+
), "Observations must be for a single orbit"
694+
assert (
695+
len(window_results.orbit_id.unique().to_pylist()) == 1
696+
), "Window results must be for a single orbit"
639697

640698
# If any windows are incomplete, the object is not complete
641699
if pc.any(pc.equal(window_results.status, "incomplete")).as_py():
@@ -651,7 +709,9 @@ def _orbit_complete_status(
651709
# If any windows has an error that don't match the two above substrings, then mark
652710
# as incomplete
653711
matches_find_orb_failed = pc.equal(window_results.error, find_orb_failed)
654-
matches_covariance_failed = pc.match_substring(window_results.error, covariance_failed)
712+
matches_covariance_failed = pc.match_substring(
713+
window_results.error, covariance_failed
714+
)
655715
combined_mask = pc.or_(matches_find_orb_failed, matches_covariance_failed)
656716
if pc.any(pc.invert(combined_mask)).as_py():
657717
return "incomplete"
@@ -715,6 +775,12 @@ def summarize_impact_study_object_results(
715775
orbit_id, orbit_window_results, orbit_discovery_dates
716776
)
717777

778+
maximum_impact_probability_prior_to_impact = (
779+
compute_maximum_impact_probability_5_years_prior_to_impact(
780+
impactor_orbit, completed_window_results
781+
)
782+
)
783+
718784
if len(orbit_observations) == 0:
719785
return ImpactorResultSummary.from_kwargs(
720786
orbit=impactor_orbit,
@@ -736,12 +802,12 @@ def summarize_impact_study_object_results(
736802
ip_threshold_90_percent=Timestamp.nulls(1, scale="utc"),
737803
ip_threshold_100_percent=Timestamp.nulls(1, scale="utc"),
738804
maximum_impact_probability=[0],
805+
maximum_impact_probability_5_years_prior=[0],
739806
results_timing=orbit_results_timing,
740807
error=[None],
741808
status=[orbit_complete],
742809
)
743810

744-
745811
# If the observations are not linked, we can return early
746812
if not pc.all(pc.equal(orbit_observations.linked, True)).as_py():
747813
return ImpactorResultSummary.from_kwargs(
@@ -766,6 +832,7 @@ def summarize_impact_study_object_results(
766832
maximum_impact_probability=[
767833
pc.max(orbit_window_results.impact_probability)
768834
],
835+
maximum_impact_probability_5_years_prior=maximum_impact_probability_prior_to_impact.maximum_impact_probability,
769836
results_timing=orbit_results_timing,
770837
status=[orbit_complete],
771838
)
@@ -791,6 +858,7 @@ def summarize_impact_study_object_results(
791858
ip_threshold_90_percent=ip_threshold_90_percent.date,
792859
ip_threshold_100_percent=ip_threshold_100_percent.date,
793860
maximum_impact_probability=[0],
861+
maximum_impact_probability_5_years_prior=[0],
794862
results_timing=orbit_results_timing,
795863
error=[None],
796864
status=[orbit_complete],
@@ -819,6 +887,7 @@ def summarize_impact_study_object_results(
819887
maximum_impact_probability=[
820888
pc.max(orbit_window_results.impact_probability)
821889
],
890+
maximum_impact_probability_5_years_prior=maximum_impact_probability_prior_to_impact.maximum_impact_probability,
822891
results_timing=orbit_results_timing,
823892
error=["Orbit has incomplete windows"],
824893
status=[orbit_complete],
@@ -850,6 +919,7 @@ def summarize_impact_study_object_results(
850919
ip_threshold_90_percent=ip_threshold_90_percent.date,
851920
ip_threshold_100_percent=ip_threshold_100_percent.date,
852921
maximum_impact_probability=[pc.max(orbit_window_results.impact_probability)],
922+
maximum_impact_probability_5_years_prior=maximum_impact_probability_prior_to_impact.maximum_impact_probability,
853923
results_timing=orbit_results_timing,
854924
status=[orbit_complete],
855925
)

0 commit comments

Comments
 (0)