Skip to content
Snippets Groups Projects
Commit 28e3889c authored by Jorrit Schaap's avatar Jorrit Schaap
Browse files

TMSS-2877: implemented min_distance constraint for both the calibrator and target

parent 3b5b8f47
No related branches found
No related tags found
1 merge request!1270TMSS-2877
...@@ -1275,66 +1275,76 @@ def evaluate_sky_min_distance_constraint(scheduling_unit: models.SchedulingUnitB ...@@ -1275,66 +1275,76 @@ def evaluate_sky_min_distance_constraint(scheduling_unit: models.SchedulingUnitB
""" Evaluate the sky min_distance constraint: is it met? and what are the score, optimal- and earliest_possible_start_time? """ Evaluate the sky min_distance constraint: is it met? and what are the score, optimal- and earliest_possible_start_time?
""" """
result = ConstraintResult(scheduling_unit, 'sky.min_distance', proposed_start_time) result = ConstraintResult(scheduling_unit, 'sky.min_distance', proposed_start_time)
constraints = scheduling_unit.scheduling_constraints_doc constraints_doc = scheduling_unit.scheduling_constraints_doc
if 'sky' not in constraints or 'min_distance' not in constraints['sky']: if 'sky' not in constraints_doc or 'min_distance' not in constraints_doc['sky']:
return result return result
# disect the constraints in a 'target' and 'calibrator' part which works for all versions
# In TMSS-2877, constraints template version 9 was created with two sections for 'target' and 'calibrator'.
# before version 9, we only had one section which was for the target only.
target_constraints = constraints_doc['sky']['min_distance'].get('target', constraints_doc['sky']['min_distance'])
calibrator_constraints = constraints_doc['sky']['min_distance'].get('calibrator', {})
# keep track of the smallest actual distance to compute the score # keep track of the smallest actual distance to compute the score
smallest_actual_distance = 3.1415 # bodies can be at most half a great circle away, which is Pi radians. smallest_actual_distance = 3.1415 # bodies can be at most half a great circle away, which is Pi radians.
# min_distance constraints are only computed for target observations
target_obs_tasks = [t for t in scheduling_unit.observation_tasks if t.is_target_observation] target_obs_tasks = [t for t in scheduling_unit.observation_tasks if t.is_target_observation]
for target_obs_task in target_obs_tasks: calibrator_obs_tasks = [t for t in scheduling_unit.observation_tasks if t.is_calibrator_observation]
sap_pointings = get_target_sap_pointings(target_obs_task)
if not sap_pointings: for constraints, obs_tasks in ((target_constraints, target_obs_tasks),
logger.warning("SUB id=%s task id=%s could not determine pointing(s) to evaluate sky constraints", scheduling_unit.id, target_obs_task.id) (calibrator_constraints, calibrator_obs_tasks)):
return result # min_distance constraints are only computed for target observations
for obs_task in obs_tasks:
# since the constraint only applies to the middle of the obs, only consider the proposed_center_time sap_pointings = get_target_sap_pointings(obs_task) if obs_task.is_target_observation else get_calibrator_sap_pointings(obs_task)
# take along the relative_start_time of this task compared to the scheduling unit's start_time if not sap_pointings:
task_proposed_start_time = proposed_start_time + target_obs_task.relative_start_time logger.warning("SUB id=%s task id=%s could not determine pointing(s) to evaluate sky constraints", scheduling_unit.id, target_obs_task.id)
task_proposed_center_time = task_proposed_start_time + target_obs_task.specified_duration / 2 return result
task_proposed_end_time = task_proposed_start_time + target_obs_task.specified_duration
gridded_timestamps = (gridder.grid_time(task_proposed_start_time), # since the constraint only applies to the middle of the obs, only consider the proposed_center_time
gridder.grid_time(task_proposed_center_time), # take along the relative_start_time of this task compared to the scheduling unit's start_time
gridder.grid_time(task_proposed_end_time)) task_proposed_start_time = proposed_start_time + obs_task.relative_start_time
task_proposed_center_time = task_proposed_start_time + obs_task.specified_duration / 2
# currently we only check at bounds and center, we probably want to add some more samples in between later on task_proposed_end_time = task_proposed_start_time + obs_task.specified_duration
# loop over all bodies and their respective min_distance constraints gridded_timestamps = (gridder.grid_time(task_proposed_start_time),
for pointing in sap_pointings: gridder.grid_time(task_proposed_center_time),
for body, min_distance in constraints['sky']['min_distance'].items(): gridder.grid_time(task_proposed_end_time))
for gridded_timestamp in gridded_timestamps:
distances = coordinates_and_timestamps_to_separation_from_bodies(pointing=pointing, # currently we only check at bounds and center, we probably want to add some more samples in between later on
timestamps=(gridded_timestamp,), # loop over all bodies and their respective min_distance constraints
bodies=[body]) for pointing in sap_pointings:
actual_distances = distances[body] for body, min_distance in constraints.items():
assert (len(actual_distances) == 1) for gridded_timestamp in gridded_timestamps:
actual_distance = actual_distances[gridded_timestamp] distances = coordinates_and_timestamps_to_separation_from_bodies(pointing=pointing,
# logger.debug("min_distance: SUB id=%s task_id=%s task_name='%s' pointing='%s' distance=%.3f[deg] to body=%s %s min_distance=%.3f[deg] at '%s'", timestamps=(gridded_timestamp,),
# scheduling_unit.id, target_obs_task.id, target_obs_task.name, pointing, actual_distance.degree, body, bodies=[body])
# '<' if actual_distance.rad < min_distance else '>=', actual_distances = distances[body]
# Angle(min_distance, astropy.units.rad).degree, assert (len(actual_distances) == 1)
# gridded_timestamp) actual_distance = actual_distances[gridded_timestamp]
# logger.debug("min_distance: SUB id=%s task_id=%s task_name='%s' pointing='%s' distance=%.3f[deg] to body=%s %s min_distance=%.3f[deg] at '%s'",
# keep track of the smallest actual distance to compute the score # scheduling_unit.id, target_obs_task.id, target_obs_task.name, pointing, actual_distance.degree, body,
smallest_actual_distance = min(smallest_actual_distance, actual_distance.rad) # '<' if actual_distance.rad < min_distance else '>=',
# Angle(min_distance, astropy.units.rad).degree,
if actual_distance.rad < min_distance: # gridded_timestamp)
# constraint not met. update result, and do early exit.
result.score = 0 # keep track of the smallest actual distance to compute the score
result.earliest_possible_start_time = None smallest_actual_distance = min(smallest_actual_distance, actual_distance.rad)
result.optimal_start_time = None
result.message = "%s distance=%.3f[deg] to body=%s %s min_distance=%.3f[deg] at '%s'" % (pointing, if actual_distance.rad < min_distance:
actual_distance.degree, # constraint not met. update result, and do early exit.
body, result.score = 0
'<' if actual_distance.rad < min_distance else '>=', result.earliest_possible_start_time = None
Angle(min_distance, astropy.units.rad).degree, result.optimal_start_time = None
gridded_timestamp) result.message = "%s distance=%.3f[deg] to body=%s %s min_distance=%.3f[deg] at '%s'" % (pointing,
logger.debug(result) actual_distance.degree,
return result body,
# no early exit, so constraint is met for this station and timestamp '<' if actual_distance.rad < min_distance else '>=',
# continue with rest of stations & timestamps Angle(min_distance, astropy.units.rad).degree,
gridded_timestamp)
logger.debug(result)
return result
# no early exit, so constraint is met for this station and timestamp
# continue with rest of stations & timestamps
# no early exit, so constraint is met for all stations and timestamps # no early exit, so constraint is met for all stations and timestamps
result.earliest_possible_start_time = proposed_start_time result.earliest_possible_start_time = proposed_start_time
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment