Beispiel #1
0
    def validate(self, data):
        # Target special validation
        if configdb.is_spectrograph(data['molecules'][0]['instrument_name']
                                    ) and 'rot_mode' not in data['target']:
            data['target']['rot_mode'] = 'VFLOAT'

        # check if the instrument specified is allowed
        valid_instruments = configdb.get_active_instrument_types(
            data['location'])
        for molecule in data['molecules']:
            if molecule['instrument_name'] not in valid_instruments:
                msg = _(
                    "Invalid instrument name '{}' at site={}, obs={}, tel={}. \n"
                ).format(molecule['instrument_name'],
                         data['location'].get('site', 'Any'),
                         data['location'].get('observatory', 'Any'),
                         data['location'].get('telescope', 'Any'))
                msg += _("Valid instruments include: ")
                for inst_name in valid_instruments:
                    msg += inst_name + ', '
                raise serializers.ValidationError(msg)

        # check that the requests window has enough rise_set visible time to accomodate the requests duration
        if data.get('windows'):
            duration = get_request_duration(data)
            rise_set_intervals = get_rise_set_intervals(data)
            largest_interval = timedelta(seconds=0)
            for interval in rise_set_intervals:
                largest_interval = max((interval[1] - interval[0]),
                                       largest_interval)

            for molecule in data['molecules']:
                if molecule.get('fill_window'):
                    molecule_duration = get_molecule_duration(
                        molecule_dict=molecule)
                    num_exposures = get_num_exposures(
                        molecule, largest_interval -
                        timedelta(seconds=duration - molecule_duration))
                    molecule['exposure_count'] = num_exposures
                    duration = get_request_duration(data)
                # delete the fill window attribute, it is only used for this validation
                try:
                    del molecule['fill_window']
                except KeyError:
                    pass
            if largest_interval.total_seconds() <= 0:
                raise serializers.ValidationError(
                    _('According to the constraints of the request, the target is never visible within the time '
                      'window. Check that the target is in the nighttime sky. Consider modifying the time '
                      'window or loosening the airmass or lunar separation constraints. If the target is '
                      'non sidereal, double check that the provided elements are correct.'
                      ))
            if largest_interval.total_seconds() <= duration:
                raise serializers.ValidationError((
                    'According to the constraints of the request, the target is visible for a maximum of {0:.2f} '
                    'hours within the time window. This is less than the duration of your request {1:.2f} hours. Consider '
                    'expanding the time window or loosening the airmass or lunar separation constraints.'
                ).format(largest_interval.total_seconds() / 3600.0,
                         duration / 3600.0))
        return data
Beispiel #2
0
def get_request_duration(request_dict):
    # calculate the total time needed by the request, based on its instrument and exposures
    request_overheads = configdb.get_request_overheads(
        request_dict['molecules'][0]['instrument_name'])
    duration = sum(
        [get_molecule_duration(m) for m in request_dict['molecules']])
    if configdb.is_spectrograph(
            request_dict['molecules'][0]['instrument_name']):
        duration += get_num_mol_changes(
            request_dict['molecules']
        ) * request_overheads['config_change_time']

        for molecule in request_dict['molecules']:
            if molecule['acquire_mode'].upper() != 'OFF' and molecule[
                    'type'].upper() in ['SPECTRUM', 'NRES_SPECTRUM']:
                duration += request_overheads[
                    'acquire_exposure_time'] + request_overheads[
                        'acquire_processing_time']
    else:
        duration += get_num_filter_changes(
            request_dict['molecules']
        ) * request_overheads['filter_change_time']

    duration += request_overheads['front_padding']
    duration = ceil(duration)

    return duration
Beispiel #3
0
 def get(self, request):
     info = {}
     for instrument_type in configdb.get_active_instrument_types({}):
         filters = configdb.get_filters(instrument_type)
         filter_map = configdb.get_filter_map()
         info[instrument_type] = {
             'type': 'SPECTRA' if configdb.is_spectrograph(instrument_type) else 'IMAGE',
             'class': instrument_type[0:3],
             'name': configdb.get_instrument_name(instrument_type),
             'filters': {filter: filter_map[filter] for filter in filters},
             'binnings': configdb.get_binnings(instrument_type),
             'default_binning': configdb.get_default_binning(instrument_type),
         }
     return Response(info)
Beispiel #4
0
    def validate(self, data):
        # set special defaults if it is a spectrograph
        if configdb.is_spectrograph(data['instrument_name']):
            if 'ag_mode' not in data:
                data['ag_mode'] = 'ON'
            if 'acquire_mode' not in data:
                data['acquire_mode'] = 'WCS'

            if data['acquire_mode'] == 'BRIGHTEST' and not data.get(
                    'acquire_radius_arcsec'):
                raise serializers.ValidationError({
                    'acquire_radius_arcsec':
                    'Acquire radius must be positive.'
                })

        types_that_require_filter = [
            'expose', 'auto_focus', 'zero_pointing', 'standard', 'sky_flat'
        ]
        types_that_require_slit = ['spectrum', 'arc', 'lamp_flat']
        types_that_require_ag_mode_on = [
            'spectrum', 'nres_spectrum', 'nres_test', 'nres_expose'
        ]

        # Spectrum and NRES_SPECTRUM obs must have ag_mode 'ON'
        if data['type'].lower() in types_that_require_ag_mode_on:
            if data['ag_mode'] is not 'ON':
                raise serializers.ValidationError({
                    'ag_mode':
                    _('Autoguiding must be on for {} observations.'.format(
                        data['type']))
                })

        # check that the filter is available in the instrument type specified
        available_filters = configdb.get_filters(data['instrument_name'])
        if configdb.is_spectrograph(data['instrument_name']):
            if (data['type'].lower() in types_that_require_slit and data.get(
                    'spectra_slit', '').lower() not in available_filters):
                raise serializers.ValidationError({
                    'spectra_slit':
                    _("Invalid spectra slit {} for instrument {}. Valid slits are: {}"
                      ).format(data.get('spectra_slit',
                                        ''), data['instrument_name'],
                               ", ".join(available_filters))
                })
        elif data['type'].lower() in types_that_require_filter:
            if not data.get('filter'):
                raise serializers.ValidationError({
                    'filter':
                    _("You must specify a filter for {} exposures.").format(
                        MOLECULE_TYPE_DISPLAY[data['type']])
                })
            elif data['filter'].lower() not in available_filters:
                raise serializers.ValidationError({
                    'filter':
                    _("Invalid filter {} for instrument {}. Valid filters are: {}"
                      ).format(data['filter'], data['instrument_name'],
                               ", ".join(available_filters))
                })

        # check that the binning is available for the instrument type specified
        if 'bin_x' not in data and 'bin_y' not in data:
            data['bin_x'] = configdb.get_default_binning(
                data['instrument_name'])
            data['bin_y'] = data['bin_x']
        elif 'bin_x' in data and 'bin_y' in data:
            available_binnings = configdb.get_binnings(data['instrument_name'])
            if data['bin_x'] not in available_binnings:
                msg = _(
                    "Invalid binning of {} for instrument {}. Valid binnings are: {}"
                ).format(data['bin_x'], data['instrument_name'].upper(),
                         ", ".join([str(b) for b in available_binnings]))
                raise serializers.ValidationError(msg)
        else:
            raise serializers.ValidationError(
                _("Missing one of bin_x or bin_y. Specify both or neither."))

        # check that the molecule type matches the instruemnt
        imager_only_types = ['EXPOSE', 'SKY_FLAT', 'AUTO_FOCUS']
        spec_only_types = ['SPECTRUM', 'ARC', 'LAMP_FLAT']
        if configdb.is_spectrograph(
                data['instrument_name']) and data['type'] in imager_only_types:
            raise serializers.ValidationError(
                _('Invalid type {0} for a spectrograph.'.format(data['type'])))
        if not configdb.is_spectrograph(
                data['instrument_name']) and data['type'] in spec_only_types:
            raise serializers.ValidationError(
                _('Invalid type {0} for an imager.'.format(data['type'])))

        return data