Ejemplo n.º 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
Ejemplo n.º 2
0
def expand_cadence_request(request_dict):
    '''
    Takes in a valid cadence request (valid request with cadence block), and expands the request into a list of requests
    with their windows determined by the cadence parameters. Only valid requests that pass rise-set are returned, with
    failing requests silently left out of the returned list.
    :param request_dict: a valid request dictionary with cadence information.
    :return: Expanded list of requests with valid windows within the cadence.
    '''
    cadence = request_dict['cadence']
    # now expand the request into a list of requests with the proper windows from the cadence block
    cadence_requests = []
    half_jitter = timedelta(hours=cadence['jitter'] / 2.0)
    request_duration = get_request_duration(request_dict)
    request_window_start = cadence['start']

    while request_window_start < cadence['end']:
        window_start = max(request_window_start - half_jitter,
                           cadence['start'])
        window_end = min(request_window_start + half_jitter, cadence['end'])

        # test the rise_set of this window
        request_dict['windows'] = [{'start': window_start, 'end': window_end}]
        intervals = get_rise_set_intervals(request_dict)
        largest_interval = get_largest_interval(intervals)
        if largest_interval.total_seconds(
        ) >= request_duration and window_end > timezone.now():
            # this cadence window passes rise_set and is in the future so add it to the list
            request_copy = request_dict.copy()
            del request_copy['cadence']
            cadence_requests.append(request_copy)

        request_window_start += timedelta(hours=cadence['period'])
    return cadence_requests
Ejemplo n.º 3
0
 def duration(self):
     cached_duration = cache.get('request_duration_{}'.format(self.id))
     if not cached_duration:
         duration = get_request_duration(
             {'molecules': [m.as_dict for m in self.molecules.all()]})
         cache.set('request_duration_{}'.format(self.id), duration,
                   86400 * 30 * 6)
         return duration
     else:
         return cached_duration
Ejemplo n.º 4
0
 def duration(self):
     return get_request_duration(self.as_dict)