示例#1
0
 def _location_available(location_info, location_constraints):
     for constraint in [
             'telescope_class', 'site', 'enclosure', 'telescope'
     ]:
         if (constraint in location_constraints
                 and not case_insensitive_equals(
                     location_info[constraint],
                     location_constraints[constraint])):
             return False
     return True
示例#2
0
    def get_specific_instrument(self, instrument_type_code, site, enclosure,
                                telescope):
        """Get the specific instrument name.

        Parameters:
            instrument_type: Instrument type
            site: 3-letter site code
            enclosure: 4-letter enclosure code
            telescope: 4-letter telescope code
        Returns:
            The matching specific instrument name
        Raises:
            ConfigDBError: If the specific instrument name is not found
        """
        fallback_instrument = ''
        for instrument in self.active_instruments:
            if instrument['state'] != ['DISABLED']:
                temp_instrument_type = instrument['instrument_type']['code']
                if case_insensitive_equals(instrument_type_code,
                                           temp_instrument_type):
                    split_string = instrument['__str__'].lower().split('.')
                    temp_site, temp_observatory, temp_telescope, _ = split_string
                    if (case_insensitive_equals(site, temp_site)
                            and case_insensitive_equals(
                                enclosure, temp_observatory)
                            and case_insensitive_equals(
                                telescope, temp_telescope)):
                        if instrument['state'] == 'SCHEDULABLE':
                            return instrument['code']
                        else:
                            fallback_instrument = instrument['code']

        if fallback_instrument:
            return fallback_instrument

        raise ConfigDBError(
            'get_specific_instrument failed: unable to find instrument type {} at location {}'
            .format(instrument_type_code,
                    '.'.join([site, enclosure, telescope])))
示例#3
0
    def _elements_available(elements_by_type, available_element_groups):
        # Assume that the elements_by_type have only valid element types.
        for element_type in elements_by_type:
            available_element_group_types = [
                eg['type'].lower() for eg in available_element_groups
            ]
            if element_type.lower() not in available_element_group_types:
                return False

            lowercase_elements_of_type = set(
                [e.lower() for e in elements_by_type[element_type]])
            for element_group in available_element_groups:
                if case_insensitive_equals(element_type,
                                           element_group['type']):
                    codes = {
                        oe['code'].lower()
                        for oe in element_group['optical_elements']
                        if oe['schedulable']
                    }
                    if not lowercase_elements_of_type.issubset(codes):
                        return False
                    break
        return True
示例#4
0
    def get_autoguider_for_instrument(self, instrument_name, self_guide):
        """Get the autoguider instrument name.

        Parameters:
            instrument_name: Science camera instrument name
            self_guide: Boolean indicating whether to self-guide
        Returns:
             Instrument name to be used for autoguiding
        Raises:
            ConfigDBError: If unable to determine a suitable autoguider
        """
        fallback_instrument = ''
        for instrument in self.active_instruments:
            if instrument['state'] != ['DISABLED']:
                if case_insensitive_equals(instrument_name,
                                           instrument['code']):
                    if instrument['state'] == 'SCHEDULABLE':
                        if not self_guide:
                            return instrument['autoguider_camera']['code']
                        elif instrument['instrument_type'][
                                'allow_self_guiding']:
                            return instrument['code']
                    else:
                        if not self_guide:
                            fallback_instrument = instrument[
                                'autoguider_camera']['code']
                        elif instrument['instrument_type'][
                                'allow_self_guiding']:
                            fallback_instrument = instrument['code']

        if fallback_instrument:
            return fallback_instrument

        raise ConfigDBError(
            'get_autoguider_for_instrument failed: unable to find autoguider for instrument {} where self_guide={}'
            .format(instrument_name, self_guide))
示例#5
0
    def get_telescopes_for_instruments(self,
                                       instrument_types_to_requirements,
                                       location,
                                       is_staff=False):
        """Get the set of telescopes on which a request can be observed.

        The main dictionary passed in contains instrument requirements by instrument type. The requirements include
        the science and guide camera optical elements needed, and whether the observation is planning to self-guide.
        The optical elements sub-structures can contain any number of lists of different elements, keyed by element type

        Parameters:
            instrument_types_to_requirements: dict of Instrument type to corresponding sets of science_optical_elements,
                guiding_optical_elements, and self_guide fields
            location: Dictionary with any location restrictions
        Returns:
            Set of available telescopes
        """
        loc_is_set = self._location_fully_set(location)
        telescope_sets = defaultdict(set)
        for instrument in self.active_instruments:
            if instrument['state'] == 'SCHEDULABLE' or (
                    instrument['state'] != 'DISABLED' and is_staff
                    and loc_is_set):
                instrument_location = self._parse_instrument_string(
                    instrument['__str__'])
                for instrument_type, instrument_requirements in instrument_types_to_requirements.items(
                ):
                    if (case_insensitive_equals(
                            instrument_type,
                            instrument['instrument_type']['code'])
                            and self._location_available(
                                instrument_location, location)):
                        # This instrument is a candidate, now the optical elements just need to match
                        self_guide = instrument_requirements['self_guide']
                        these_imager_element_groups = []
                        for science_camera in instrument['science_cameras']:
                            these_imager_element_groups.extend(
                                science_camera['optical_element_groups'])

                        if self_guide and instrument['instrument_type'][
                                'allow_self_guiding']:
                            these_guider_element_groups = these_imager_element_groups
                        elif not self_guide:
                            these_guider_element_groups = instrument[
                                'autoguider_camera']['optical_element_groups']
                        else:
                            # There is no available guider on this telescope
                            continue

                        if (self._elements_available(
                                instrument_requirements[
                                    'science_optical_elements'],
                                these_imager_element_groups)
                                and self._elements_available(
                                    instrument_requirements[
                                        'guiding_optical_elements'],
                                    these_guider_element_groups)):
                            telescope_sets[instrument_type].add(
                                instrument_location['telescope_location'])

        telescope_sets = list(telescope_sets.values())
        if len(telescope_sets) > 1:
            return telescope_sets[0].intersection(*telescope_sets[1:])
        else:
            return telescope_sets[0] if telescope_sets else set()