Skip to content

Commit

Permalink
Merge 38106c2 into b9d5b28
Browse files Browse the repository at this point in the history
  • Loading branch information
jnation3406 committed Jun 26, 2019
2 parents b9d5b28 + 38106c2 commit aac6797
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 24 deletions.
8 changes: 7 additions & 1 deletion observation_portal/blocks/conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,13 @@ def convert_observation_to_pond_block(observation):
events = []
if configuration.get('summary'):
events.append(copy.deepcopy(configuration['summary']))
completed_exposures = events[0].get('time_completed', 0) // first_instrument_config.get('exposure_time', 1)
if configuration['state'] == 'COMPLETED':
completed_exposures = first_instrument_config['exposure_count']
elif first_instrument_config.get('exposure_time', 1) > 0:
completed_exposures = events[0].get('time_completed', 0) // first_instrument_config.get('exposure_time',
1)
else:
completed_exposures = 0
events[0]['completed_exposures'] = completed_exposures
del events[0]['time_completed']
del events[0]['events']
Expand Down
5 changes: 2 additions & 3 deletions observation_portal/blocks/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class PondBlockFilter(django_filters.FilterSet):
site = django_filters.MultipleChoiceFilter(choices=configdb.get_site_tuples())
observatory = django_filters.MultipleChoiceFilter(choices=configdb.get_enclosure_tuples())
observatory = django_filters.MultipleChoiceFilter(choices=configdb.get_enclosure_tuples(), field_name='enclosure')
telescope = django_filters.MultipleChoiceFilter(choices=configdb.get_telescope_tuples())
start_after = django_filters.CharFilter(field_name='start', method='filter_start_after', label='Start after',
widget=forms.TextInput(attrs={'class': 'input', 'type': 'date'}))
Expand All @@ -24,8 +24,7 @@ class PondBlockFilter(django_filters.FilterSet):
proposal = django_filters.CharFilter(field_name='request__request_group__proposal__id', distinct=True, lookup_expr='exact')
instrument_class = django_filters.ChoiceFilter(choices=configdb.get_instrument_type_tuples(),
field_name='configuration_statuses__configuration__instrument_type')
canceled = django_filters.TypedChoiceFilter(choices=(('false', 'False'), ('true', 'True')),
method='filter_canceled', coerce=strtobool)
canceled = django_filters.BooleanFilter(method='filter_canceled')
order = django_filters.OrderingFilter(fields=('start', 'modified'))
time_span = django_filters.DateRangeFilter(field_name='start')

Expand Down
2 changes: 1 addition & 1 deletion observation_portal/common/configdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ def is_valid_guider_for_instrument_name(self, instrument_name, guide_camera_name
if instrument['code'].upper() == instrument_name.upper():
if instrument['autoguider_camera']['code'].lower() == guide_camera_name.lower():
return True
elif instrument['allow_self_guiding'] and guide_camera_name.lower() == instrument_name.lower():
elif instrument['science_camera']['camera_type']['allow_self_guiding'] and guide_camera_name.lower() == instrument_name.lower():
return True
return False

Expand Down
5 changes: 5 additions & 0 deletions observation_portal/common/rise_set_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ def filter_out_downtime_from_intervalsets(intervalsets_by_telescope: dict) -> di


def get_rise_set_target(target_dict):
if 'type' not in target_dict:
return make_hour_angle_target(
hour_angle=Angle(degrees=0),
dec=Angle(degrees=0),
)
if target_dict['type'] in ['ICRS', 'HOUR_ANGLE']:
pmra = (target_dict['proper_motion_ra'] / 1000.0 / cos(radians(target_dict['dec']))) / 3600.0
pmdec = (target_dict['proper_motion_dec'] / 1000.0) / 3600.0
Expand Down
35 changes: 21 additions & 14 deletions observation_portal/common/test_data/configdb.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,19 @@
{
"state": "SCHEDULABLE",
"code": "xx01",
"allow_self_guiding": true,
"autoguider_camera": {
"code": "ef01",
"camera_type": {
"code": "1M0-SCICAM-SBIG"
"code": "1M0-SCICAM-SBIG",
"allow_self_guiding": true
}
},
"science_camera": {
"code": "xx01",
"camera_type": {
"code": "1M0-SCICAM-SBIG",
"name": "1M0-SCICAM-SBIG",
"allow_self_guiding": true,
"default_mode": {
"binning": 2,
"readout": 14.5
Expand Down Expand Up @@ -148,18 +149,19 @@
{
"state": "DISABLED",
"code": "xx06",
"allow_self_guiding": true,
"autoguider_camera": {
"code": "xx07",
"camera_type": {
"code": "1M0-SCICAM-SBIG"
"code": "1M0-SCICAM-SBIG",
"allow_self_guiding": true
}
},
"science_camera": {
"code": "xx06",
"camera_type": {
"code": "1M0-SCICAM-SBIG",
"name": "1M0-SCICAM-SBIG",
"allow_self_guiding": true,
"default_mode": {
"binning": 2,
"readout": 14.5
Expand Down Expand Up @@ -271,18 +273,19 @@
{
"state": "ENABLED",
"code": "xx08",
"allow_self_guiding": true,
"autoguider_camera": {
"code": "xx09",
"camera_type": {
"code": "1M0-SCICAM-SBIG"
"code": "1M0-SCICAM-SBIG",
"allow_self_guiding": true
}
},
"science_camera": {
"code": "xx08",
"camera_type": {
"code": "1M0-SCICAM-SBIG",
"name": "1M0-SCICAM-SBIG",
"allow_self_guiding": true,
"default_mode": {
"binning": 2,
"readout": 14.5
Expand Down Expand Up @@ -408,18 +411,19 @@
{
"state": "SCHEDULABLE",
"code": "xx02",
"allow_self_guiding": false,
"autoguider_camera": {
"code": "ef02",
"camera_type": {
"code": "2M0-FLOYDS-AG"
"code": "2M0-FLOYDS-AG",
"allow_self_guiding": false
}
},
"science_camera": {
"code": "xx02",
"camera_type": {
"code": "2M0-FLOYDS-SCICAM",
"name": "2M0-FLOYDS-SCICAM",
"allow_self_guiding": false,
"config_change_time": 30,
"acquire_processing_time": 60,
"acquire_exposure_time": 30,
Expand Down Expand Up @@ -567,18 +571,19 @@
{
"state": "SCHEDULABLE",
"code": "xx03",
"allow_self_guiding": true,
"autoguider_camera": {
"code": "ef03",
"camera_type": {
"code": "1M0-SCICAM-AG"
"code": "1M0-SCICAM-AG",
"allow_self_guiding": true
}
},
"science_camera": {
"code": "xx03",
"camera_type": {
"code": "1M0-SCICAM-SBIG",
"name": "1M0-SCICAM-SBIG",
"allow_self_guiding": true,
"default_mode": {
"binning": 2,
"readout": 14.5
Expand Down Expand Up @@ -690,18 +695,19 @@
{
"state": "SCHEDULABLE",
"code": "nres02",
"allow_self_guiding": false,
"autoguider_camera": {
"code": "ak02",
"camera_type": {
"code": "1M0-NRES-AG"
"code": "1M0-NRES-AG",
"allow_self_guiding": false
}
},
"science_camera": {
"code": "nres02",
"camera_type": {
"code": "1M0-NRES-SCICAM",
"name": "1M0-NRES-SCICAM",
"allow_self_guiding": false,
"default_mode": {
"binning": 2,
"readout": 90.5
Expand Down Expand Up @@ -812,18 +818,19 @@
{
"state": "SCHEDULABLE",
"code": "xx04",
"allow_self_guiding": false,
"autoguider_camera": {
"code": "ef04",
"camera_type": {
"code": "2M0-FLOYDS-AG"
"code": "2M0-FLOYDS-AG",
"allow_self_guiding": false
}
},
"science_camera": {
"code": "xx04",
"camera_type": {
"code": "2M0-FLOYDS-SCICAM",
"name": "2M0-FLOYDS-SCICAM",
"allow_self_guiding": false,
"config_change_time": 30,
"acquire_processing_time": 60,
"acquire_exposure_time": 30,
Expand Down
8 changes: 4 additions & 4 deletions observation_portal/observations/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ def test_observation_not_in_a_request_window_but_overlaps_with_window_start_reje
observation['end'] = "2016-09-03T00:30:00Z"
response = self.client.post(reverse('api:observations-list'), data=observation)
self.assertEqual(response.status_code, 400)
self.assertIn('The start and end times do not fall within any window of the request', str(response.content))
self.assertIn('times do not fall within any window of the request', str(response.content))

def test_observation_not_in_a_request_window_but_overlaps_with_window_end_rejected(self):
observation = self._generate_observation_data(
Expand All @@ -628,7 +628,7 @@ def test_observation_not_in_a_request_window_but_overlaps_with_window_end_reject
observation['end'] = "2016-09-06T00:30:00Z"
response = self.client.post(reverse('api:observations-list'), data=observation)
self.assertEqual(response.status_code, 400)
self.assertIn('The start and end times do not fall within any window of the request', str(response.content))
self.assertIn('times do not fall within any window of the request', str(response.content))

def test_observation_starting_after_request_window_end_rejected(self):
observation = self._generate_observation_data(
Expand All @@ -638,7 +638,7 @@ def test_observation_starting_after_request_window_end_rejected(self):
observation['end'] = "2016-09-07T00:30:00Z"
response = self.client.post(reverse('api:observations-list'), data=observation)
self.assertEqual(response.status_code, 400)
self.assertIn('The start and end times do not fall within any window of the request', str(response.content))
self.assertIn('times do not fall within any window of the request', str(response.content))

def test_observation_ending_before_request_window_start_rejected(self):
observation = self._generate_observation_data(
Expand All @@ -648,7 +648,7 @@ def test_observation_ending_before_request_window_start_rejected(self):
observation['end'] = "2016-09-02T00:30:00Z"
response = self.client.post(reverse('api:observations-list'), data=observation)
self.assertEqual(response.status_code, 400)
self.assertIn('The start and end times do not fall within any window of the request', str(response.content))
self.assertIn('times do not fall within any window of the request', str(response.content))

def test_observation_does_not_match_request_location_site_rejected(self):
observation = self._generate_observation_data(
Expand Down
2 changes: 1 addition & 1 deletion observation_portal/requestgroups/duration_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def get_request_duration(request_dict):
if configuration['acquisition_config']['mode'] != 'OFF':
if configuration['acquisition_config']['mode'] in request_overheads['acquisition_overheads']:
duration += request_overheads['acquisition_overheads'][configuration['acquisition_config']['mode']]
if 'exposure_time' in configuration['acquisition_config']:
if 'exposure_time' in configuration['acquisition_config'] and configuration['acquisition_config']['exposure_time']:
duration += configuration['acquisition_config']['exposure_time']
else:
duration += request_overheads['default_acquisition_exposure_time']
Expand Down
7 changes: 7 additions & 0 deletions observation_portal/requestgroups/test/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1648,6 +1648,13 @@ def test_acquisition_config_exposure_time_limits(self):
self.assertEqual(ur['requests'][0]['configurations'][0]['acquisition_config']['exposure_time'], 20)
self.assertEqual(response.status_code, 201)

def test_acquisition_config_no_exposure_time_works(self):
good_data = self.generic_payload.copy()
good_data['requests'][0]['configurations'][0]['acquisition_config']['exposure_time'] = None
response = self.client.post(reverse('api:request_groups-validate'), data=good_data)
ur = response.json()
self.assertEqual(response.status_code, 200)

def test_more_than_max_rois_rejected(self):
roi_data = {'x1': 0, 'x2': 20, 'y1': 0, 'y2': 100}
bad_data = self.generic_payload.copy()
Expand Down
42 changes: 42 additions & 0 deletions observation_portal/requestgroups/test/test_request_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from mixer.backend.django import mixer
from datetime import datetime
from unittest.mock import patch
import copy

from observation_portal.requestgroups.request_utils import (get_airmasses_for_request_at_sites, get_telescope_states_for_request,
get_filtered_rise_set_intervals_by_site)
Expand Down Expand Up @@ -412,6 +413,47 @@ def test_telescope_states_calculation(self):

self.assertIn(domb_expected_available_state2, telescope_states[self.tk2])

def test_telescope_states_calculation_with_no_target(self):
request_dict = self.request.as_dict()
request_dict['configurations'][0]['target'] = {}

telescope_states = get_telescope_states_for_request(request_dict)
# Assert that telescope states were received for this request
self.assertIn(self.tk1, telescope_states)
self.assertIn(self.tk2, telescope_states)

expected_start_of_night_doma = datetime(2016, 10, 1, 18, 24, 58, tzinfo=timezone.utc)
expected_start_of_night_domb = datetime(2016, 10, 1, 18, 30, 0, tzinfo=timezone.utc)


# These are the same states tested for similar times in the telescope_states test class
doma_expected_available_state = {'telescope': 'tst.doma.1m0a',
'event_type': 'AVAILABLE',
'event_reason': 'Available for scheduling',
'start': expected_start_of_night_doma,
'end': datetime(2016, 10, 1, 20, 44, 58, tzinfo=timezone.utc)
}

self.assertIn(doma_expected_available_state, telescope_states[self.tk1])

domb_expected_available_state1 = {'telescope': 'tst.domb.1m0a',
'event_type': 'AVAILABLE',
'event_reason': 'Available for scheduling',
'start': expected_start_of_night_domb,
'end': datetime(2016, 10, 1, 19, 24, 59, tzinfo=timezone.utc)
}

self.assertIn(domb_expected_available_state1, telescope_states[self.tk2])

domb_expected_available_state2 = {'telescope': 'tst.domb.1m0a',
'event_type': 'AVAILABLE',
'event_reason': 'Available for scheduling',
'start': datetime(2016, 10, 1, 20, 24, 59, tzinfo=timezone.utc),
'end': datetime(2016, 10, 1, 20, 44, 58, tzinfo=timezone.utc)
}

self.assertIn(domb_expected_available_state2, telescope_states[self.tk2])

def test_telescope_states_empty(self):
self.location.site = 'cpt'
self.location.save()
Expand Down

0 comments on commit aac6797

Please sign in to comment.