def score_eclipse(eclipse: Dict, first_contact: Union[None, FirstContactTime], type: ExpectedEclipseType, phase_timing: Union[None, PhaseTiming], location: Union[None, EclipsePosition]) -> float: scores = [LunarEclipseQuery.eclipse_core_score(eclipse, type)] weights = [0.5] if location is not None: assert eclipse['angle'] is not None scores.append(AngularSeparationQuery.separation_score(location.target_angle, location.tolerance, location.target_position, eclipse['angle'], eclipse['position'])) weights.append(0.25) if first_contact is not None: if type == ExpectedEclipseType.UNKNOWN: # If the eclipse is a prediction then allow a higher time tolerance scores.append(LunarEclipseQuery.eclipse_time_of_day_score(eclipse, first_contact, HIGH_TIME_TOLERANCE)) else: scores.append(LunarEclipseQuery.eclipse_time_of_day_score(eclipse, first_contact, REGULAR_TIME_TOLERANCE)) weights.append(0.25) if phase_timing is not None: scores.append(LunarEclipseQuery.eclipse_phase_length_score(eclipse, phase_timing)) weights.append(0.25) score = np.average(scores, weights=weights) assert 0 <= score <= 1 return score
def plot_separation_score(angle: float, tolerance: float, dest: str): range = (angle + tolerance) * 1.5 xs = np.arange(0, range, 0.01) ys = list( map( lambda x: AngularSeparationQuery.separation_score( target_angle=angle, tolerance=tolerance, target_position=None, actual=x, actual_position=EclipticPosition.BEHIND.value, ), xs)) f, ax1 = plt.subplots() ax1.set_xlabel('Angular Separation°') ax1.set_ylabel('Score') ax1.plot(xs, ys) if angle != 0: ax1.axvline(x=angle, color='r', label="Target Angle") ax1.axvline(x=angle + tolerance, color='g', label="Upper Bound") if angle - tolerance > 0: ax1.axvline(x=angle - tolerance, color='b', label="Lower Bound") ax1.legend() plt.savefig(dest)