Пример #1
0
    def init_target_with_bad_json(self):

        missingfilter = (
            '{"targetid": 3, "fieldid": 2573, "ra_rad": 5.24504477561707, '
            '"dec_rad": -0.030036505561584215, "ang_rad": 0.7853981633974483, '
            '"num_exp": 2, "exp_times": [15.0, 15.0], "_exp_time": null, '
            '"time": 0.0, "airmass": 0.0, "sky_brightness": 0.0, "cloud": 0.0, '
            '"seeing": 0.0, "propid": 0, "need": 0.0, "bonus": 0.0, "value": 0.0, '
            '"goal": 0, "visits": 0, "progress": 0.0, '
            '"sequenceid": 0, "subsequencename": "", "groupid": 0, "groupix": 0, '
            '"is_deep_drilling": false, "is_dd_firstvisit": false, "remaining_dd_visits": 0, '
            '"dd_exposures": 0, "dd_filterchanges": 0, "dd_exptime": 0.0, '
            '"alt_rad": 0.7853981633974483, "az_rad": 3.9269908169872414, '
            '"rot_rad": 0.5235987755982988, "telalt_rad": 0.7853981633974483, '
            '"telaz_rad": 3.9269908169872414, "telrot_rad": 0.5235987755982988, "propboost": 1.0, '
            '"slewtime": 0.0, "cost": 0.0, "rank": 0.0, "num_props": 0, "propid_list": [], '
            '"need_list": [], "bonus_list": [], "value_list": [], "propboost_list": [], '
            '"sequenceid_list": [], "subsequencename_list": [], "groupid_list": [], '
            '"groupix_list": [], "is_deep_drilling_list": [], '
            '"is_dd_firstvisit_list": [], "remaining_dd_visits_list": [], '
            '"dd_exposures_list": [], "dd_filterchanges_list": [], "dd_exptime_list": [], '
            '"last_visit_time": 0.0, "note": ""}'
        )
        t = Target()
        t.from_json(missingfilter)
Пример #2
0
 def test_driver_state_copy(self):
     target2 = Target()
     target2.copy_driver_state(self.target)
     self.assertEqual(target2.alt_rad, self.alt_rad)
     self.assertEqual(target2.az_rad, self.az_rad)
     self.assertEqual(target2.ang_rad, self.ang_rad)
     self.assertEqual(target2.rot_rad, self.rot_rad)
     self.assertEqual(target2.telalt_rad, self.telalt_rad)
     self.assertEqual(target2.telaz_rad, self.telaz_rad)
     self.assertEqual(target2.telrot_rad, self.telrot_rad)
Пример #3
0
    def read_script(self):

        scriptfilepath = self.script_file
        lines = file(scriptfilepath).readlines()
        targetid = 0
        self.targetsList = []
        for line in lines:
            line = line.strip()
            if not line:			# skip blank line
                continue
            if line[0] == '#': 		# skip comment line
                continue
            targetid += 1
            values = line.split()
            target = Target()
            target.fieldid = eval(values[0])
            target.filter = values[1]
            target.ra_rad = math.radians(eval(values[2]))
            target.dec_rad = math.radians(eval(values[3]))
            target.ang_rad = math.radians(eval(values[4]))
            target.num_exp = eval(values[5])
            target.exp_times = [int(x) for x in values[6].split(',')]

            self.targetsList.append(target)
        self.log.info("%d targets" % len(self.targetsList))
Пример #4
0
 def test_json_serialization(self):
     jsondump = self.target.to_json()
     target2 = Target()
     target2.from_json(jsondump)
     self.assertEqual(self.target.targetid, target2.targetid)
     self.assertEqual(self.target.fieldid, target2.fieldid)
     self.assertEqual(self.target.filter, target2.filter)
     self.assertEqual(self.target.ra_rad, target2.ra_rad)
     self.assertEqual(self.target.dec_rad, target2.dec_rad)
     self.assertEqual(self.target.num_exp, target2.num_exp)
     self.assertListEqual(self.target.exp_times, target2.exp_times)
Пример #5
0
    def __init__(self):

        self.log = logging.getLogger("schedulerDriver")

        self.params = DriverParameters()
        self.location = ObservatoryLocation()

        self.observatoryModel = ObservatoryModel(self.location, WORDY)
        self.observatoryModel2 = ObservatoryModel(self.location, WORDY)
        self.observatoryState = ObservatoryState()

        self.sky = AstronomicalSkyModel(self.location)

        self.db = FieldsDatabase()

        self.build_fields_dict()

        self.propid_counter = 0
        self.science_proposal_list = []

        self.start_time = 0.0
        self.time = 0.0
        self.targetid = 0
        self.survey_started = False
        self.isnight = False
        self.sunset_timestamp = 0.0
        self.sunrise_timestamp = 0.0
        self.survey_duration_DAYS = 0.0
        self.survey_duration_SECS = self.survey_duration_DAYS * 24 * 60 * 60.0
        self.darktime = False
        self.mounted_filter = ""
        self.unmounted_filter = ""
        self.midnight_moonphase = 0.0

        self.nulltarget = Target()
        self.nulltarget.targetid = -1
        self.nulltarget.num_exp = 1
        self.nulltarget.exp_times = [0.0]
        self.nulltarget.num_props = 1
        self.nulltarget.propid_list = [0]
        self.nulltarget.need_list = [0.0]
        self.nulltarget.bonus_list = [0.0]
        self.nulltarget.value_list = [0.0]
        self.nulltarget.propboost_list = [1.0]
        self.last_winner_target = self.nulltarget.get_copy()
        self.deep_drilling_target = None

        self.need_filter_swap = False
        self.filter_to_unmount = ""
        self.filter_to_mount = ""

        self.cloud = 0.0
        self.seeing = 0.0
Пример #6
0
 def test_creation_from_topic(self):
     topic = collections.namedtuple(
         "topic",
         [
             "targetId",
             "fieldId",
             "filter",
             "ra",
             "decl",
             "skyAngle",
             "numExposures",
             "exposureTimes",
         ],
     )
     topic.targetId = 1
     topic.fieldId = -1
     topic.filter = "z"
     topic.ra = 274.279376
     topic.decl = -14.441534
     topic.skyAngle = 45.0
     topic.numExposures = 3
     topic.exposureTimes = [5.0, 10.0, 5.0]
     target = Target.from_topic(topic)
     self.assertEqual(target.targetid, topic.targetId)
     self.assertEqual(target.fieldid, topic.fieldId)
     self.assertEqual(target.filter, topic.filter)
     self.assertEqual(target.ra, topic.ra)
     self.assertAlmostEqual(target.dec, topic.decl, delta=1e-7)
     self.assertEqual(target.num_exp, topic.numExposures)
     self.assertListEqual(target.exp_times, topic.exposureTimes)
Пример #7
0
    def test_get_deep_drilling_time(self):
        target = Target()
        target.is_deep_drilling = True
        target.is_dd_firstvisit = True
        target.remaining_dd_visits = 96
        target.dd_exposures = 2 * 96
        target.dd_filterchanges = 3
        target.dd_exptime = 96 * 2 * 15.0

        ddtime = self.model.get_deep_drilling_time(target)
        self.assertEqual(ddtime, 3808.0)
Пример #8
0
    def setUp(self):
        self.targetId = 3
        self.fieldId = 2573
        self.band_filter = "r"
        self.ra = 300.518929
        self.dec = -1.720965
        self.ang = 45.0
        self.num_exposures = 2
        self.exposure_times = [15.0, 15.0]

        self.alt = 45.0
        self.az = 225.0
        self.rot = 30.0
        self.telalt = 45.0
        self.telaz = 225.0
        self.telrot = 30.0

        self.ra_rad = math.radians(self.ra)
        self.dec_rad = math.radians(self.dec)
        self.ang_rad = math.radians(self.ang)
        self.alt_rad = math.radians(self.alt)
        self.az_rad = math.radians(self.az)
        self.rot_rad = math.radians(self.rot)
        self.telalt_rad = math.radians(self.telalt)
        self.telaz_rad = math.radians(self.telaz)
        self.telrot_rad = math.radians(self.telrot)

        self.target = Target(
            self.targetId,
            self.fieldId,
            self.band_filter,
            self.ra_rad,
            self.dec_rad,
            self.ang_rad,
            self.num_exposures,
            self.exposure_times,
        )
        self.target.alt_rad = self.alt_rad
        self.target.az_rad = self.az_rad
        self.target.rot_rad = self.rot_rad
        self.target.telalt_rad = self.telalt_rad
        self.target.telaz_rad = self.telaz_rad
        self.target.telrot_rad = self.telrot_rad
Пример #9
0
    def slew(self, target):
        """Perform the slewing operation for the observatory to the given target.

        Parameters
        ----------
        target : SALPY_scheduler.targetC
            The Scheduler topic instance holding the target information.

        Returns
        -------
        float
            The time to slew the telescope from its current position to the target position.
        """
        self.slew_count += 1
        self.log.log(LoggingLevel.TRACE.value,
                     "Slew count: {}".format(self.slew_count))
        initial_slew_state = copy.deepcopy(self.model.current_state)
        self.log.log(LoggingLevel.TRACE.value,
                     "Initial slew state: {}".format(initial_slew_state))
        self.slew_initial_state = self.get_slew_state(initial_slew_state)

        sched_target = Target.from_topic(target)
        self.model.slew(sched_target)

        final_slew_state = copy.deepcopy(self.model.current_state)
        self.log.log(LoggingLevel.TRACE.value,
                     "Final slew state: {}".format(final_slew_state))
        self.slew_final_state = self.get_slew_state(final_slew_state)

        slew_time = (final_slew_state.time - initial_slew_state.time,
                     "seconds")

        slew_distance = palpy.dsep(final_slew_state.ra_rad,
                                   final_slew_state.dec_rad,
                                   initial_slew_state.ra_rad,
                                   initial_slew_state.dec_rad)

        self.slew_history = SlewHistory(self.slew_count,
                                        initial_slew_state.time,
                                        final_slew_state.time, slew_time[0],
                                        math.degrees(slew_distance),
                                        self.observations_made)

        self.get_slew_activities()

        self.slew_maxspeeds = SlewMaxSpeeds(self.slew_count,
                                            final_slew_state.domalt_peakspeed,
                                            final_slew_state.domaz_peakspeed,
                                            final_slew_state.telalt_peakspeed,
                                            final_slew_state.telaz_peakspeed,
                                            final_slew_state.telrot_peakspeed,
                                            self.slew_count)

        return slew_time
Пример #10
0
    def test_park(self):
        self.model.update_state(0)
        self.model.params.rotator_followsky = False
        self.model.params.rotator_resume_angle = False
        # Start at park, slew to target.
        # Use default configuration (dome crawl, CL updates, etc.)
        target = Target()
        target.ra_rad = math.radians(60)
        target.dec_rad = math.radians(-20)
        target.ang_rad = math.radians(0)
        target.filter = "z"

        self.model.slew(target)
        expected_state = "t=156.0 ra=60.000 dec=-20.000 ang=243.495 filter=z track=True " \
                         "alt=61.191 az=76.196 pa=243.224 rot=359.729 telaz=76.196 telrot=-0.271 " \
                         "mounted=['g', 'r', 'i', 'z', 'y'] unmounted=['u']"
        self.assertEqual(str(self.model.current_state), expected_state)
        self.check_delay_and_state(
            self.model,
            self.make_slewact_dict((8.387, 11.966, 0.0, 7.387, 36.0, 18.775,
                                    48.507, 1.0, 120.0, 2.0)),
            ['telopticsclosedloop', 'filter'], (-3.50, 7.00, 0.0, -1.75, 1.50))

        self.model.park()
        expected_state = "t=241.1 ra=30.487 dec=-26.744 ang=180.000 filter=z track=False " \
                         "alt=86.500 az=0.000 pa=180.000 rot=0.000 telaz=0.000 telrot=0.000 " \
                         "mounted=['g', 'r', 'i', 'z', 'y'] unmounted=['u']"
        self.assertEqual(str(self.model.current_state), expected_state)
        self.check_delay_and_state(
            self.model,
            self.make_slewact_dict(
                (8.231, 11.885, 1.041, 7.231, 36.0, 18.462, 48.130, 1.0, 0.0,
                 2.0)), ['telopticsclosedloop', 'domazsettle', 'domaz'],
            (3.50, -7.00, 0.520, 1.75, -1.50))
Пример #11
0
    def __init__(self):
        self.log = logging.getLogger("schedulerDriver")

        self.params = DriverParameters()
        self.location = ObservatoryLocation()

        self.observatoryModel = ObservatoryModel(self.location, WORDY)
        self.observatoryModel2 = ObservatoryModel(self.location, WORDY)
        self.observatoryState = ObservatoryState()

        self.sky = AstronomicalSkyModel(self.location)

        self.propid_counter = 0
        self.night = 0
        self.start_time = 0.0
        self.time = 0.0
        self.targetid = 0
        self.survey_started = False
        self.isnight = False
        self.sunset_timestamp = 0.0
        self.sunrise_timestamp = 0.0
        self.survey_duration_DAYS = 0.0
        self.survey_duration_SECS = self.survey_duration_DAYS * 24 * 60 * 60.0
        self.darktime = False
        self.mounted_filter = ""
        self.unmounted_filter = ""
        self.midnight_moonphase = 0.0

        self.nulltarget = Target()
        self.nulltarget.targetid = -1
        self.nulltarget.num_exp = 1
        self.nulltarget.exp_times = [0.0]
        self.nulltarget.num_props = 1
        self.nulltarget.propid_list = [0]
        self.nulltarget.need_list = [0.0]
        self.nulltarget.bonus_list = [0.0]
        self.nulltarget.value_list = [0.0]
        self.nulltarget.propboost_list = [1.0]

        self.last_winner_target = self.nulltarget.get_copy()
        self.deep_drilling_target = None

        self.need_filter_swap = False
        self.filter_to_unmount = ""
        self.filter_to_mount = ""

        self.cloud = 0.0
        self.seeing = 0.0
Пример #12
0
 def test_creation_from_topic(self):
     topic = collections.namedtuple('topic', ['targetId', 'fieldId',
                                              'filter', 'ra', 'decl',
                                              'skyAngle',
                                              'numExposures',
                                              'exposureTimes'])
     topic.targetId = 1
     topic.fieldId = -1
     topic.filter = 'z'
     topic.ra = 274.279376
     topic.decl = -14.441534
     topic.skyAngle = 45.0
     topic.numExposures = 3
     topic.exposureTimes = [5.0, 10.0, 5.0]
     target = Target.from_topic(topic)
     self.assertEqual(target.targetid, topic.targetId)
     self.assertEqual(target.fieldid, topic.fieldId)
     self.assertEqual(target.filter, topic.filter)
     self.assertEqual(target.ra, topic.ra)
     self.assertAlmostEqual(target.dec, topic.decl, delta=1e-7)
     self.assertEqual(target.num_exp, topic.numExposures)
     self.assertListEqual(target.exp_times, topic.exposureTimes)
Пример #13
0
    def test_domecrawl(self):
        self.model.update_state(0)
        self.assertEqual(
            str(self.model.current_state),
            "t=0.0 ra=29.480 dec=-26.744 ang=180.000 "
            "filter=r track=False alt=86.500 az=0.000 pa=180.000 rot=0.000 "
            "telaz=0.000 telrot=0.000 "
            "mounted=['g', 'r', 'i', 'z', 'y'] unmounted=['u']")

        target = Target()
        target.ra_rad = math.radians(35)
        target.dec_rad = math.radians(-27)
        target.ang_rad = math.radians(0)
        target.filter = "r"

        # Just test whether dome crawl is faster or not.
        # If we test the final slew state, this is including other aspects of slew model (such as CLoptics).
        self.model.params.domaz_free_range = 0
        delay_nocrawl = self.model.get_slew_delay(target)
        self.model.params.domaz_free_range = np.radians(4.0)
        delay_crawl = self.model.get_slew_delay(target)
        self.assertTrue(delay_crawl < delay_nocrawl)
Пример #14
0
    def test_slewdata(self):
        self.model.update_state(0)
        # Use old values, to avoid updating final states.
        self.model.params.domaz_free_range = 0
        self.model.params.optics_cl_delay = [0, 20.0]
        self.model.params.rotator_followsky = True

        target = Target()
        target.ra_rad = math.radians(60)
        target.dec_rad = math.radians(-20)
        target.ang_rad = math.radians(0)
        target.filter = "r"

        self.model.slew(target)
        self.assertEqual(
            str(self.model.current_state),
            "t=74.2 ra=60.000 dec=-20.000 ang=180.000 "
            "filter=r track=True alt=60.904 az=76.495 pa=243.368 rot=63.368 "
            "telaz=76.495 telrot=63.368 "
            "mounted=['g', 'r', 'i', 'z', 'y'] unmounted=['u']")
        self.check_delay_and_state(
            self.model,
            self.make_slewact_dict(
                (8.387, 11.966, 21.641, 7.387, 20.0, 18.775, 53.174, 1.0, 0.0,
                 2.0)), ['telopticsclosedloop', 'domazsettle', 'domaz'],
            (-3.50, 7.00, 3.50, -1.75, 1.50))

        target = Target()
        target.ra_rad = math.radians(60)
        target.dec_rad = math.radians(-20)
        target.ang_rad = math.radians(0)
        target.filter = "i"

        self.model.slew(target)
        self.assertEqual(
            str(self.model.current_state),
            "t=194.2 ra=60.000 dec=-20.000 ang=180.000 "
            "filter=i track=True alt=61.324 az=76.056 pa=243.156 rot=63.156 "
            "telaz=76.056 telrot=63.156 "
            "mounted=['g', 'r', 'i', 'z', 'y'] unmounted=['u']")
        self.check_delay_and_state(
            self.model,
            self.make_slewact_dict(
                (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 120.0, 2.0)),
            ['filter'], (0, 0, 0, 0, 0))

        target = Target()
        target.ra_rad = math.radians(61)
        target.dec_rad = math.radians(-21)
        target.ang_rad = math.radians(1)
        target.filter = "i"

        self.model.slew(target)
        self.assertEqual(
            str(self.model.current_state),
            "t=199.0 ra=61.000 dec=-21.000 ang=181.000 "
            "filter=i track=True alt=60.931 az=78.751 pa=245.172 rot=64.172 "
            "telaz=78.751 telrot=64.172 "
            "mounted=['g', 'r', 'i', 'z', 'y'] unmounted=['u']")
        self.check_delay_and_state(
            self.model,
            self.make_slewact_dict((0.683, 1.244, 2.022, 0.117, 0.0, 1.365,
                                    3.801, 1.0, 0.000, 2.000)),
            ['domazsettle', 'domaz'], (-1.194, 4.354, 1.011, -0.598, 1.425))
Пример #15
0
    def test_slew(self):
        self.model.update_state(0)
        self.model.params.domaz_free_range = 0
        self.model.params.optics_cl_delay = [0, 20.0]
        self.model.params.rotator_followsky = True

        self.assertEqual(
            str(self.model.current_state),
            "t=0.0 ra=29.480 dec=-26.744 ang=180.000 "
            "filter=r track=False alt=86.500 az=0.000 pa=180.000 rot=0.000 "
            "telaz=0.000 telrot=0.000 "
            "mounted=['g', 'r', 'i', 'z', 'y'] unmounted=['u']")

        target = Target()
        target.ra_rad = math.radians(60)
        target.dec_rad = math.radians(-20)
        target.ang_rad = math.radians(0)
        target.filter = "r"

        self.model.slew(target)
        self.assertEqual(
            str(self.model.current_state),
            "t=74.2 ra=60.000 dec=-20.000 ang=180.000 "
            "filter=r track=True alt=60.904 az=76.495 pa=243.368 rot=63.368 "
            "telaz=76.495 telrot=63.368 "
            "mounted=['g', 'r', 'i', 'z', 'y'] unmounted=['u']")

        target = Target()
        target.ra_rad = math.radians(60)
        target.dec_rad = math.radians(-20)
        target.ang_rad = math.radians(0)
        target.filter = "i"

        self.model.slew(target)
        self.assertEqual(
            str(self.model.current_state),
            "t=194.2 ra=60.000 dec=-20.000 ang=180.000 "
            "filter=i track=True alt=61.324 az=76.056 pa=243.156 rot=63.156 "
            "telaz=76.056 telrot=63.156 "
            "mounted=['g', 'r', 'i', 'z', 'y'] unmounted=['u']")
Пример #16
0
    def test_get_slew_delay_followsky_false(self):
        # Test slew time without followsky option. Similar to test_get_slew_delay above.
        self.model.update_state(0)
        self.model.params.rotator_followsky = False
        expected_state = "t=0.0 ra=29.480 dec=-26.744 ang=180.000 " \
                         "filter=r track=False alt=86.500 az=0.000 pa=180.000 rot=0.000 " \
                         "telaz=0.000 telrot=0.000 " \
                         "mounted=['g', 'r', 'i', 'z', 'y'] unmounted=['u']"
        self.assertEqual(str(self.model.current_state), expected_state)

        target = Target()
        target.ra_rad = math.radians(60)
        target.dec_rad = math.radians(-20)
        target.ang_rad = math.radians(0)
        target.filter = "r"

        delay, status = self.model.get_slew_delay(target)
        self.assertAlmostEqual(delay, 85.507, delta=1e-3)

        self.model.slew(target)

        target = Target()
        target.ra_rad = math.radians(60)
        target.dec_rad = math.radians(-20)
        target.ang_rad = math.radians(0)
        target.filter = "g"

        delay, status = self.model.get_slew_delay(target)
        self.assertAlmostEqual(delay, 120, delta=1e-3)

        target = Target()
        target.ra_rad = math.radians(50)
        target.dec_rad = math.radians(-10)
        target.ang_rad = math.radians(10)
        target.filter = "r"

        delay, status = self.model.get_slew_delay(target)
        self.assertAlmostEqual(delay, 17.913, delta=1e-3)

        self.model.slew(target)
        delay, status = self.model.get_slew_delay(target)
        self.assertAlmostEqual(delay, 2.0, delta=1e-3)

        # Here is the difference when using followsky = False
        target.ang_rad = math.radians(15)
        delay, status = self.model.get_slew_delay(target)
        self.assertAlmostEqual(delay, 2.0, delta=1e-3)
Пример #17
0
    def test_get_slew_delay(self):
        self.model.update_state(0)
        # Use old values, to avoid updating final states.
        self.model.params.rotator_followsky = True

        self.assertEqual(
            str(self.model.current_state),
            "t=0.0 ra=29.480 dec=-26.744 ang=180.000 "
            "filter=r track=False alt=86.500 az=0.000 pa=180.000 rot=0.000 "
            "telaz=0.000 telrot=0.000 "
            "mounted=['g', 'r', 'i', 'z', 'y'] unmounted=['u']")
        # This slew will include a CL optics correction.
        target = Target()
        target.ra_rad = math.radians(60)
        target.dec_rad = math.radians(-20)
        target.ang_rad = math.radians(0)
        target.filter = "r"

        delay, status = self.model.get_slew_delay(target)
        self.assertAlmostEqual(delay, 85.507, delta=1e-3)

        self.model.slew(target)

        # This slew simply includes a filter change.
        target = Target()
        target.ra_rad = math.radians(60)
        target.dec_rad = math.radians(-20)
        target.ang_rad = math.radians(0)
        target.filter = "g"

        delay, status = self.model.get_slew_delay(target)
        self.assertAlmostEqual(delay, 120, delta=1e-3)

        # This slew does not include OL correction, but does involve dome crawl.
        target = Target()
        target.ra_rad = math.radians(50)
        target.dec_rad = math.radians(-10)
        target.ang_rad = math.radians(10)
        target.filter = "r"

        delay, status = self.model.get_slew_delay(target)
        self.assertAlmostEqual(delay, 17.913, delta=1e-3)

        # This slew is only readout.
        self.model.slew(target)
        delay, status = self.model.get_slew_delay(target)
        self.assertAlmostEqual(delay, 2.0, delta=1e-3)

        # This slew involves rotator.
        target.ang_rad = math.radians(15)
        delay, status = self.model.get_slew_delay(target)
        self.assertAlmostEqual(delay, 4.472, delta=1e-3)
Пример #18
0
class Driver(object):
    def __init__(self):

        self.log = logging.getLogger("schedulerDriver")

        self.params = DriverParameters()
        self.location = ObservatoryLocation()

        self.observatoryModel = ObservatoryModel(self.location, WORDY)
        self.observatoryModel2 = ObservatoryModel(self.location, WORDY)
        self.observatoryState = ObservatoryState()

        self.sky = AstronomicalSkyModel(self.location)

        self.db = FieldsDatabase()

        self.build_fields_dict()

        self.propid_counter = 0
        self.science_proposal_list = []

        self.start_time = 0.0
        self.time = 0.0
        self.targetid = 0
        self.survey_started = False
        self.isnight = False
        self.sunset_timestamp = 0.0
        self.sunrise_timestamp = 0.0
        self.survey_duration_DAYS = 0.0
        self.survey_duration_SECS = self.survey_duration_DAYS * 24 * 60 * 60.0
        self.darktime = False
        self.mounted_filter = ""
        self.unmounted_filter = ""
        self.midnight_moonphase = 0.0

        self.nulltarget = Target()
        self.nulltarget.targetid = -1
        self.nulltarget.num_exp = 1
        self.nulltarget.exp_times = [0.0]
        self.nulltarget.num_props = 1
        self.nulltarget.propid_list = [0]
        self.nulltarget.need_list = [0.0]
        self.nulltarget.bonus_list = [0.0]
        self.nulltarget.value_list = [0.0]
        self.nulltarget.propboost_list = [1.0]
        self.last_winner_target = self.nulltarget.get_copy()
        self.deep_drilling_target = None

        self.need_filter_swap = False
        self.filter_to_unmount = ""
        self.filter_to_mount = ""

        self.cloud = 0.0
        self.seeing = 0.0

    def configure_survey(self, survey_conf_file):

        prop_conf_path = os.path.dirname(survey_conf_file)
        confdict = read_conf_file(survey_conf_file)

        self.survey_duration_DAYS = confdict["survey"]["survey_duration"]
        self.survey_duration_SECS = self.survey_duration_DAYS * 24 * 60 * 60.0

        self.propid_counter = 0
        self.science_proposal_list = []

        if 'scripted_propconf' in confdict["proposals"]:
            scripted_propconflist = confdict["proposals"]["scripted_propconf"]
        else:
            scripted_propconflist = []
        if not isinstance(scripted_propconflist, list):
            # turn it into a list with one entry
            propconf = scripted_propconflist
            scripted_propconflist = []
            scripted_propconflist.append(propconf)
        self.log.info("configure_survey: scripted proposals %s" % (scripted_propconflist))
        for k in range(len(scripted_propconflist)):
            self.propid_counter += 1
            scripted_prop = ScriptedProposal(self.propid_counter,
                                             os.path.join(prop_conf_path,
                                                          "{}".format(scripted_propconflist[k])),
                                             self.sky)
            self.science_proposal_list.append(scripted_prop)

        if 'areadistribution_propconf' in confdict["proposals"]:
            areadistribution_propconflist = confdict["proposals"]["areadistribution_propconf"]
        else:
            areadistribution_propconflist = []
            self.log.info("areadistributionPropConf:%s default" % (areadistribution_propconflist))
        if not isinstance(areadistribution_propconflist, list):
            # turn it into a list with one entry
            propconf = areadistribution_propconflist
            areadistribution_propconflist = []
            areadistribution_propconflist.append(propconf)
        self.log.info("init: areadistribution proposals %s" % (areadistribution_propconflist))
        for k in range(len(areadistribution_propconflist)):
            self.propid_counter += 1
            configfilepath = os.path.join(prop_conf_path, "{}".format(areadistribution_propconflist[k]))
            (path, name_ext) = os.path.split(configfilepath)
            (name, ext) = os.path.splitext(name_ext)
            proposal_confdict = read_conf_file(configfilepath)
            self.create_area_proposal(self.propid_counter, name, proposal_confdict)

        for prop in self.science_proposal_list:
            prop.configure_constraints(self.params)

    def configure_duration(self, survey_duration):

        self.survey_duration_DAYS = survey_duration
        self.survey_duration_SECS = survey_duration * 24 * 60 * 60.0

    def configure(self, confdict):

        self.params.configure(confdict)
        self.log.log(WORDY,
                     "configure: coadd_values=%s" % (self.params.coadd_values))
        self.log.log(WORDY,
                     "configure: time_balancing=%s" % (self.params.time_balancing))
        self.log.log(WORDY,
                     "configure: timecost_dc=%.3f" % (self.params.timecost_dc))
        self.log.log(WORDY,
                     "configure: timecost_dt=%.3f" % (self.params.timecost_dt))
        self.log.log(WORDY,
                     "configure: timecost_k=%.3f" % (self.params.timecost_k))
        self.log.log(WORDY,
                     "configure: timecost_weight=%.3f" % (self.params.timecost_weight))
        self.log.log(WORDY,
                     "configure: night_boundary=%.1f" % (self.params.night_boundary))
        self.log.log(WORDY,
                     "configure: ignore_sky_brightness=%s" % (self.params.ignore_sky_brightness))
        self.log.log(WORDY,
                     "configure: ignore_airmass=%s" % (self.params.ignore_airmass))
        self.log.log(WORDY,
                     "configure: ignore_clouds=%s" % (self.params.ignore_clouds))
        self.log.log(WORDY,
                     "configure: ignore_seeing=%s" % (self.params.ignore_seeing))
        self.log.log(WORDY,
                     "configure: new_moon_phase_threshold=%.2f" % (self.params.new_moon_phase_threshold))

        for prop in self.science_proposal_list:
            prop.configure_constraints(self.params)

    def configure_location(self, confdict):

        self.location.configure(confdict)
        self.observatoryModel.location.configure(confdict)
        self.observatoryModel2.location.configure(confdict)
        self.sky.update_location(self.location)

    def configure_observatory(self, confdict):

        self.observatoryModel.configure(confdict)
        self.observatoryModel2.configure(confdict)

    def configure_telescope(self, confdict):

        self.observatoryModel.configure_telescope(confdict)
        self.observatoryModel2.configure_telescope(confdict)

    def configure_rotator(self, confdict):

        self.observatoryModel.configure_rotator(confdict)
        self.observatoryModel2.configure_rotator(confdict)

    def configure_dome(self, confdict):

        self.observatoryModel.configure_dome(confdict)
        self.observatoryModel2.configure_dome(confdict)

    def configure_optics(self, confdict):

        self.observatoryModel.configure_optics(confdict)
        self.observatoryModel2.configure_optics(confdict)

    def configure_camera(self, confdict):

        self.observatoryModel.configure_camera(confdict)
        self.observatoryModel2.configure_camera(confdict)

    def configure_slew(self, confdict):

        self.observatoryModel.configure_slew(confdict)
        self.observatoryModel2.configure_slew(confdict)

    def configure_park(self, confdict):

        self.observatoryModel.configure_park(confdict)
        self.observatoryModel2.configure_park(confdict)

    def create_area_proposal(self, propid, name, config_dict):

        self.propid_counter += 1
        area_prop = AreaDistributionProposal(propid, name, config_dict, self.sky)
        area_prop.configure_constraints(self.params)
        self.science_proposal_list.append(area_prop)

    def create_sequence_proposal(self, propid, name, config_dict):

        self.propid_counter += 1
        seq_prop = TimeDistributionProposal(propid, name, config_dict, self.sky)
        seq_prop.configure_constraints(self.params)
        self.science_proposal_list.append(seq_prop)

    def build_fields_dict(self):

        sql = "select * from Field"
        res = self.db.query(sql)

        self.fields_dict = {}
        for row in res:
            field = Field()
            fieldid = row[0]
            field.fieldid = fieldid
            field.fov_rad = math.radians(row[1])
            field.ra_rad = math.radians(row[2])
            field.dec_rad = math.radians(row[3])
            field.gl_rad = math.radians(row[4])
            field.gb_rad = math.radians(row[5])
            field.el_rad = math.radians(row[6])
            field.eb_rad = math.radians(row[7])
            self.fields_dict[fieldid] = field
            self.log.log(EXTENSIVE, "buildFieldsTable: %s" % (self.fields_dict[fieldid]))
        self.log.info("buildFieldsTable: %d fields" % (len(self.fields_dict)))

    def get_fields_dict(self):

        return self.fields_dict

    def start_survey(self, timestamp, night):

        self.start_time = timestamp
        self.log.info("start_survey t=%.6f" % timestamp)

        self.survey_started = True
        for prop in self.science_proposal_list:
            prop.start_survey()

        self.sky.update(timestamp)
        (sunset, sunrise) = self.sky.get_night_boundaries(self.params.night_boundary)
        self.log.debug("start_survey sunset=%.6f sunrise=%.6f" % (sunset, sunrise))
        # if round(sunset) <= round(timestamp) < round(sunrise):
        if sunset <= timestamp < sunrise:
            self.start_night(timestamp, night)

        self.sunset_timestamp = sunset
        self.sunrise_timestamp = sunrise

    def end_survey(self):

        self.log.info("end_survey")

        for prop in self.science_proposal_list:
            prop.end_survey()

    def start_night(self, timestamp, night):

        timeprogress = (timestamp - self.start_time) / self.survey_duration_SECS
        self.log.info("start_night t=%.6f, night=%d timeprogress=%.2f%%" %
                      (timestamp, night, 100 * timeprogress))

        self.isnight = True

        for prop in self.science_proposal_list:
            prop.start_night(timestamp, self.observatoryModel.current_state.mountedfilters, night)

    def end_night(self, timestamp, night):

        timeprogress = (timestamp - self.start_time) / self.survey_duration_SECS
        self.log.info("end_night t=%.6f, night=%d timeprogress=%.2f%%" %
                      (timestamp, night, 100 * timeprogress))

        self.isnight = False

        self.last_winner_target = self.nulltarget
        self.deep_drilling_target = None

        total_filter_visits_dict = {}
        total_filter_goal_dict = {}
        total_filter_progress_dict = {}
        for prop in self.science_proposal_list:
            prop.end_night(timestamp)
            filter_visits_dict = {}
            filter_goal_dict = {}
            filter_progress_dict = {}
            for filter in self.observatoryModel.filters:
                if filter not in total_filter_visits_dict:
                    total_filter_visits_dict[filter] = 0
                    total_filter_goal_dict[filter] = 0
                filter_visits_dict[filter] = prop.get_filter_visits(filter)
                filter_goal_dict[filter] = prop.get_filter_goal(filter)
                filter_progress_dict[filter] = prop.get_filter_progress(filter)
                total_filter_visits_dict[filter] += filter_visits_dict[filter]
                total_filter_goal_dict[filter] += filter_goal_dict[filter]
                self.log.debug("end_night propid=%d name=%s filter=%s progress=%.2f%%" %
                               (prop.propid, prop.name, filter, 100 * filter_progress_dict[filter]))
        for filter in self.observatoryModel.filters:
            if total_filter_goal_dict[filter] > 0:
                total_filter_progress_dict[filter] = \
                    float(total_filter_visits_dict[filter]) / total_filter_goal_dict[filter]
            else:
                total_filter_progress_dict[filter] = 0.0
            self.log.info("end_night filter=%s progress=%.2f%%" %
                          (filter, 100 * total_filter_progress_dict[filter]))

        previous_midnight_moonphase = self.midnight_moonphase
        self.sky.update(timestamp)
        (sunset, sunrise) = self.sky.get_night_boundaries(self.params.night_boundary)
        self.log.debug("end_night sunset=%.6f sunrise=%.6f" % (sunset, sunrise))

        self.sunset_timestamp = sunset
        self.sunrise_timestamp = sunrise
        next_midnight = (sunset + sunrise) / 2
        self.sky.update(next_midnight)
        info = self.sky.get_moon_sun_info(numpy.array([0.0]), numpy.array([0.0]))
        self.midnight_moonphase = info["moonPhase"]
        self.log.info("end_night next moonphase=%.2f%%" % (self.midnight_moonphase))

        self.need_filter_swap = False
        self.filter_to_mount = ""
        self.filter_to_unmount = ""
        if self.darktime:
            if self.midnight_moonphase > previous_midnight_moonphase:
                self.log.info("end_night dark time waxing")
                if self.midnight_moonphase > self.params.new_moon_phase_threshold:
                    self.need_filter_swap = True
                    self.filter_to_mount = self.unmounted_filter
                    self.filter_to_unmount = self.mounted_filter
                    self.darktime = False
            else:
                self.log.info("end_night dark time waning")
        else:
            if self.midnight_moonphase < previous_midnight_moonphase:
                self.log.info("end_night bright time waning")
                if self.midnight_moonphase < self.params.new_moon_phase_threshold:
                    self.need_filter_swap = True
                    self.filter_to_mount = self.observatoryModel.params.filter_darktime
                    max_progress = -1.0
                    for filter in self.observatoryModel.params.filter_removable_list:
                        if total_filter_progress_dict[filter] > max_progress:
                            self.filter_to_unmount = filter
                            max_progress = total_filter_progress_dict[filter]
                    self.darktime = True
            else:
                self.log.info("end_night bright time waxing")

        if self.need_filter_swap:
            self.log.debug("end_night filter swap %s=>cam=>%s" %
                           (self.filter_to_mount, self.filter_to_unmount))

    def swap_filter(self, filter_to_unmount, filter_to_mount):

        self.log.info("swap_filter swap %s=>cam=>%s" % (filter_to_mount, filter_to_unmount))

        self.observatoryModel.swap_filter(filter_to_unmount)

        self.unmounted_filter = filter_to_unmount
        self.mounted_filter = filter_to_mount

        return

    def update_time(self, timestamp, night):

        self.time = timestamp
        self.observatoryModel.update_state(self.time)
        if not self.survey_started:
            self.start_survey(timestamp, night)

        if self.isnight:
            # if round(timestamp) >= round(self.sunrise_timestamp):
            if timestamp >= self.sunrise_timestamp:
                self.end_night(timestamp, night)
        else:
            # if round(timestamp) >= round(self.sunset_timestamp):
            if timestamp >= self.sunset_timestamp:
                self.start_night(timestamp, night)

        return self.isnight

    def get_need_filter_swap(self):

        return (self.need_filter_swap, self.filter_to_unmount, self.filter_to_mount)

    def update_internal_conditions(self, observatory_state, night):

        if observatory_state.unmountedfilters != self.observatoryModel.current_state.unmountedfilters:
            unmount = observatory_state.unmountedfilters[0]
            mount = self.observatoryModel.current_state.unmountedfilters[0]
            self.swap_filter(unmount, mount)
            for prop in self.science_proposal_list:
                prop.start_night(observatory_state.time, observatory_state.mountedfilters, night)

        self.time = observatory_state.time
        self.observatoryModel.set_state(observatory_state)
        self.observatoryState.set(observatory_state)

    def update_external_conditions(self, cloud, seeing):

        self.cloud = cloud
        self.seeing = seeing

        return

    def select_next_target(self):

        if not self.isnight:
            return self.nulltarget

        targets_dict = {}
        ranked_targets_list = []
        propboost_dict = {}
        sumboost = 0.0

        timeprogress = (self.time - self.start_time) / self.survey_duration_SECS
        for prop in self.science_proposal_list:

            progress = prop.get_progress()
            if self.params.time_balancing:
                if progress > 0.0:
                    if timeprogress < 1.0:
                        needindex = (1.0 - progress) / (1.0 - timeprogress)
                    else:
                        needindex = 0.0
                    if timeprogress > 0.0:
                        progressindex = progress / timeprogress
                    else:
                        progressindex = 1.0
                    propboost_dict[prop.propid] = needindex / progressindex
                else:
                    propboost_dict[prop.propid] = 1.0
            else:
                propboost_dict[prop.propid] = 1.0
            sumboost += propboost_dict[prop.propid]

        if self.deep_drilling_target is not None:
            self.log.debug("select_next_target: in deep drilling %s" % str(self.deep_drilling_target))

        if self.observatoryModel.is_filter_change_allowed():
            constrained_filter = None
        else:
            constrained_filter = self.observatoryModel.current_state.filter
        num_filter_changes = self.observatoryModel.get_number_filter_changes()
        delta_burst = self.observatoryModel.get_delta_filter_burst()
        delta_avg = self.observatoryModel.get_delta_filter_avg()
        self.log.debug("select_next_target: filter changes num=%i tburst=%.1f tavg=%.1f constrained=%s" %
                       (num_filter_changes, delta_burst, delta_avg, constrained_filter))

        for prop in self.science_proposal_list:
            propboost_dict[prop.propid] = \
                (propboost_dict[prop.propid] * len(self.science_proposal_list) / sumboost) ** self.params.propboost_weight

            proptarget_list = prop.suggest_targets(self.time,
                                                   self.deep_drilling_target, constrained_filter,
                                                   self.cloud, self.seeing)
            self.log.log(EXTENSIVE, "select_next_target propid=%d name=%s "
                         "targets=%d progress=%.2f%% propboost=%.3f" %
                         (prop.propid, prop.name,
                          len(proptarget_list), 100 * progress, propboost_dict[prop.propid]))

            for target in proptarget_list:
                target.num_props = 1
                target.propboost = propboost_dict[prop.propid]
                target.propid_list = [prop.propid]
                target.need_list = [target.need]
                target.bonus_list = [target.bonus]
                target.value_list = [target.value]
                target.propboost_list = [target.propboost]
                target.sequenceid_list = [target.sequenceid]
                target.subsequencename_list = [target.subsequencename]
                target.groupid_list = [target.groupid]
                target.groupix_list = [target.groupix]
                target.is_deep_drilling_list = [target.is_deep_drilling]
                target.is_dd_firstvisit_list = [target.is_dd_firstvisit]
                target.remaining_dd_visits_list = [target.remaining_dd_visits]
                target.dd_exposures_list = [target.dd_exposures]
                target.dd_filterchanges_list = [target.dd_filterchanges]
                target.dd_exptime_list = [target.dd_exptime]

                fieldfilter = (target.fieldid, target.filter)
                if fieldfilter in targets_dict:
                    if self.params.coadd_values:
                        targets_dict[fieldfilter][0] = targets_dict[fieldfilter][0].get_copy()
                        targets_dict[fieldfilter][0].need += target.need
                        targets_dict[fieldfilter][0].bonus += target.bonus
                        targets_dict[fieldfilter][0].value += target.value
                        targets_dict[fieldfilter][0].propboost += target.propboost
                        if target.is_deep_drilling:
                            # overrides to make the coadded target a consistent deep drilling
                            targets_dict[fieldfilter][0].is_deep_drilling = target.is_deep_drilling
                            targets_dict[fieldfilter][0].is_dd_firstvisit = target.is_dd_firstvisit
                            targets_dict[fieldfilter][0].remaining_dd_visits = target.remaining_dd_visits
                            targets_dict[fieldfilter][0].dd_exposures = target.dd_exposures
                            targets_dict[fieldfilter][0].dd_filterchanges = target.dd_filterchanges
                            targets_dict[fieldfilter][0].dd_exptime = target.dd_exptime
                            targets_dict[fieldfilter][0].sequenceid = target.sequenceid
                            targets_dict[fieldfilter][0].subsequencename = target.subsequencename
                            targets_dict[fieldfilter][0].groupid = target.groupid
                            targets_dict[fieldfilter][0].groupix = target.groupix
                        else:
                            # new target to coadd is not deep drilling
                            if not targets_dict[fieldfilter][0].is_deep_drilling:
                                # coadded target is not deep drilling
                                # overrides with new sequence information
                                targets_dict[fieldfilter][0].sequenceid = target.sequenceid
                                targets_dict[fieldfilter][0].subsequencename = target.subsequencename
                                targets_dict[fieldfilter][0].groupid = target.groupid
                                targets_dict[fieldfilter][0].groupix = target.groupix
                            # if coadded target is already deep drilling, don't override
                        targets_dict[fieldfilter][0].num_props += 1
                        targets_dict[fieldfilter][0].propid_list.append(prop.propid)
                        targets_dict[fieldfilter][0].need_list.append(target.need)
                        targets_dict[fieldfilter][0].bonus_list.append(target.bonus)
                        targets_dict[fieldfilter][0].value_list.append(target.value)
                        targets_dict[fieldfilter][0].propboost_list.append(target.propboost)
                        targets_dict[fieldfilter][0].sequenceid_list.append(target.sequenceid)
                        targets_dict[fieldfilter][0].subsequencename_list.append(target.subsequencename)
                        targets_dict[fieldfilter][0].groupid_list.append(target.groupid)
                        targets_dict[fieldfilter][0].groupix_list.append(target.groupix)
                        targets_dict[fieldfilter][0].is_deep_drilling_list.append(target.is_deep_drilling)
                        targets_dict[fieldfilter][0].is_dd_firstvisit_list.append(target.is_dd_firstvisit)
                        targets_dict[fieldfilter][0].remaining_dd_visits_list.append(
                            target.remaining_dd_visits)
                        targets_dict[fieldfilter][0].dd_exposures_list.append(target.dd_exposures)
                        targets_dict[fieldfilter][0].dd_filterchanges_list.append(target.dd_filterchanges)
                        targets_dict[fieldfilter][0].dd_exptime_list.append(target.dd_exptime)
                    else:
                        targets_dict[fieldfilter].append(target)
                else:
                    targets_dict[fieldfilter] = [target]

        filtercost = self.compute_filterchange_cost() * self.params.filtercost_weight
        for fieldfilter in targets_dict:
            slewtime = self.observatoryModel.get_slew_delay(targets_dict[fieldfilter][0])
            if slewtime >= 0:
                timecost = self.compute_slewtime_cost(slewtime) * self.params.timecost_weight
                for target in targets_dict[fieldfilter]:
                    target.slewtime = slewtime
                    if target.filter != self.observatoryModel.current_state.filter:
                        target.cost = timecost + filtercost
                    else:
                        target.cost = timecost
                    target.rank = (target.value * target.propboost) - target.cost
                    ranked_targets_list.append((-target.rank, target))

        sorted_list = sorted(ranked_targets_list, key=itemgetter(0))

        winner_found = False
        while len(sorted_list) > 0 and not winner_found:
            winner_target = sorted_list.pop(0)[1]

            self.observatoryModel2.set_state(self.observatoryState)
            self.observatoryModel2.observe(winner_target)
            if winner_target.is_dd_firstvisit:
                ttime = self.observatoryModel2.get_deep_drilling_time(winner_target)
            else:
                ttime = 0.0
            ntime = self.observatoryModel2.current_state.time + ttime + 30.0
            if ntime < self.sunrise_timestamp:
                self.observatoryModel2.update_state(ntime)
                if self.observatoryModel2.current_state.tracking:
                    self.targetid += 1
                    winner_target.targetid = self.targetid
                    winner_target.time = self.time
                    winner_found = True
                else:
                    self.log.debug("select_next_target: target rejected ttime=%.1f %s" %
                                   (ttime, str(winner_target)))
                    self.log.debug("select_next_target: state rejected %s" %
                                   str(self.observatoryModel2.current_state))
            else:
                self.log.debug("select_next_target: target rejected ttime=%.1f %s" %
                               (ttime, str(winner_target)))
                self.log.debug("select_next_target: rejected due to end of night")
                if ttime == 0.0:
                    # ttime == 0 means it is a regular visit (not DD)
                    # if there is no time left for a single visit then quit
                    break

        if winner_found:
            if not self.params.coadd_values:
                first_target = targets_dict[(winner_target.fieldid, winner_target.filter)][0]
                if first_target.propid != winner_target.propid:
                    winner_target.copy_driver_state(first_target)
            self.last_winner_target = winner_target.get_copy()
        else:
            self.last_winner_target = self.nulltarget

        return self.last_winner_target

    def register_observation(self, observation):

        target_list = []
        if observation.targetid > 0:
            if self.observation_fulfills_target(observation, self.last_winner_target):
                observation = self.last_winner_target
            else:
                self.log.info("register_observation: unexpected observation %s" % str(observation))

            for prop in self.science_proposal_list:
                target = prop.register_observation(observation)
                if target is not None:
                    target_list.append(target)

        self.last_observation = observation.get_copy()
        if self.last_observation.is_deep_drilling and (self.last_observation.remaining_dd_visits > 1):
            self.deep_drilling_target = self.last_observation
        else:
            self.deep_drilling_target = None

        return target_list

    def compute_slewtime_cost(self, slewtime):

        cost = (self.params.timecost_k / (slewtime + self.params.timecost_dt) -
                self.params.timecost_dc - self.params.timecost_cref) / (1.0 - self.params.timecost_cref)
        #cost = self.params.timecost_k / (slewtime + self.params.timecost_dt) - self.params.timecost_dc

        return cost

    def compute_filterchange_cost(self):

        t = self.observatoryModel.get_delta_last_filterchange()
        T = self.observatoryModel.params.filter_max_changes_avg_interval
        if t < T:
            cost = 1.0 - t / T
        else:
            cost = 0.0

        return cost

    def observation_fulfills_target(self, observ, target):

        return (observ.fieldid == target.fieldid) and (observ.filter == target.filter)
Пример #19
0
    def observe(self, observation):
        """Try to make an observation

        Returns
        -------
        observation : observation object
            None if there was no observation taken. Completed observation with meta data filled in.
        new_night : bool
            Have we started a new night.
        """

        start_night = self.night.copy()

        # Make sure the kinematic model is set to the correct mjd
        t = Time(self.mjd, format='mjd')
        self.observatory.update_state(t.unix)

        if np.isnan(observation['rotSkyPos']):
            observation = self._update_rotSkyPos(observation)

        target = Target(band_filter=observation['filter'],
                        ra_rad=observation['RA'],
                        dec_rad=observation['dec'],
                        ang_rad=observation['rotSkyPos'],
                        num_exp=observation['nexp'],
                        exp_times=[observation['exptime']])
        start_ra = self.observatory.current_state.ra_rad
        start_dec = self.observatory.current_state.dec_rad
        slewtime, visittime = self.observatory.observe_times(target)

        # Check if the mjd after slewtime and visitime is fine:
        observation_worked, new_mjd = self.check_mjd(self.mjd +
                                                     (slewtime + visittime) /
                                                     24. / 3600.)
        if observation_worked:
            observation['visittime'] = visittime
            observation['slewtime'] = slewtime
            observation['slewdist'] = _angularSeparation(
                start_ra, start_dec, self.observatory.current_state.ra_rad,
                self.observatory.current_state.dec_rad)
            self.mjd = self.mjd + slewtime / 24. / 3600.
            # Reach into the observatory model to pull out the relevant data it has calculated
            # Note, this might be after the observation has been completed.
            observation['alt'] = self.observatory.current_state.alt_rad
            observation['az'] = self.observatory.current_state.az_rad
            observation['pa'] = self.observatory.current_state.pa_rad
            observation['rotTelPos'] = self.observatory.current_state.rot_rad
            observation['rotSkyPos'] = self.observatory.current_state.ang_rad

            # Metadata on observation is after slew and settle, so at start of exposure.
            result = self.observation_add_data(observation)
            self.mjd = self.mjd + visittime / 24. / 3600.
            new_night = False
        else:
            result = None
            self.observatory.park()
            # Skip to next legitimate mjd
            self.mjd = new_mjd
            now_night = self.night
            if now_night == start_night:
                new_night = False
            else:
                new_night = True

        return result, new_night
    def start_night(self, timestamp, filters_mounted_tonight_list, night):

        Proposal.start_night(self, timestamp, filters_mounted_tonight_list,
                             night)
        self.fieldsvisitedtonight = {}
        self.tonight_filters_list = []
        self.tonight_targets = 0
        self.tonight_targets_dict = {}
        for filter in filters_mounted_tonight_list:
            self.tonight_filters_list.append(filter)
        self.build_tonight_fields_list(timestamp, night)
        self.tonight_fields = len(self.tonight_fields_list)

        # compute at start night
        for field in self.tonight_fields_list:
            fieldid = field.fieldid

            # add new fields to fields dictionary
            if fieldid not in self.survey_fields_dict:
                self.survey_fields_dict[fieldid] = field.get_copy()
                self.survey_fields += 1

            # add new fields to targets dictionary
            if fieldid not in self.survey_targets_dict:
                self.survey_targets_dict[fieldid] = {}

            self.tonight_targets_dict[fieldid] = {}
            for filter in filters_mounted_tonight_list:
                if filter in self.params.filter_list:
                    if self.params.filter_goal_dict[filter] > 0:
                        if filter not in self.survey_targets_dict[fieldid]:
                            target = Target()
                            target.fieldid = fieldid
                            target.filter = filter
                            target.num_exp = self.params.filter_num_exp_dict[
                                filter]
                            target.exp_times = self.params.filter_exp_times_dict[
                                filter]
                            target.ra_rad = field.ra_rad
                            target.dec_rad = field.dec_rad
                            target.propid = self.propid
                            target.goal = self.params.filter_goal_dict[filter]
                            target.visits = 0
                            target.progress = 0.0
                            target.groupid = 1
                            target.groupix = 1
                            self.survey_targets_dict[fieldid][filter] = target

                            self.survey_targets += 1
                            self.survey_targets_goal += target.goal
                            self.survey_filters_goal_dict[
                                filter] += target.goal
                        target = self.survey_targets_dict[fieldid][filter]
                        if target.progress < 1.0:
                            self.tonight_targets_dict[fieldid][filter] = target
                            self.tonight_targets += 1

        for filter in self.params.filter_list:
            if self.survey_filters_goal_dict[filter] > 0:
                self.survey_filters_progress_dict[filter] = \
                    float(self.survey_filters_visits_dict[filter]) / self.survey_filters_goal_dict[filter]
            else:
                self.survey_filters_progress_dict[filter] = 0.0

        if self.survey_targets_goal > 0:
            self.survey_targets_progress = float(
                self.survey_targets_visits) / self.survey_targets_goal
        else:
            self.survey_targets_progress = 0.0

        self.log.debug("start_night tonight fields=%i targets=%i" %
                       (self.tonight_fields, self.tonight_targets))

        self.last_observation = None
        self.last_observation_was_for_this_proposal = False
Пример #21
0
class TargetTest(unittest.TestCase):

    def setUp(self):
        self.targetId = 3
        self.fieldId = 2573
        self.band_filter = 'r'
        self.ra = 300.518929
        self.dec = -1.720965
        self.ang = 45.0
        self.num_exposures = 2
        self.exposure_times = [15.0, 15.0]

        self.alt = 45.0
        self.az = 225.0
        self.rot = 30.0
        self.telalt = 45.0
        self.telaz = 225.0
        self.telrot = 30.0

        self.ra_rad = math.radians(self.ra)
        self.dec_rad = math.radians(self.dec)
        self.ang_rad = math.radians(self.ang)
        self.alt_rad = math.radians(self.alt)
        self.az_rad = math.radians(self.az)
        self.rot_rad = math.radians(self.rot)
        self.telalt_rad = math.radians(self.telalt)
        self.telaz_rad = math.radians(self.telaz)
        self.telrot_rad = math.radians(self.telrot)

        self.target = Target(self.targetId, self.fieldId, self.band_filter,
                             self.ra_rad, self.dec_rad, self.ang_rad,
                             self.num_exposures, self.exposure_times)
        self.target.alt_rad = self.alt_rad
        self.target.az_rad = self.az_rad
        self.target.rot_rad = self.rot_rad
        self.target.telalt_rad = self.telalt_rad
        self.target.telaz_rad = self.telaz_rad
        self.target.telrot_rad = self.telrot_rad

    def test_basic_information_after_creation(self):
        self.assertEqual(self.target.targetid, self.targetId)
        self.assertEqual(self.target.fieldid, self.fieldId)
        self.assertEqual(self.target.filter, self.band_filter)
        self.assertEqual(self.target.ra, self.ra)
        self.assertEqual(self.target.dec, self.dec)
        self.assertEqual(self.target.num_exp, self.num_exposures)
        self.assertListEqual(self.target.exp_times, self.exposure_times)
    
    def test_json_serialization(self):
        jsondump = self.target.to_json()
        target2 = Target()
        target2.from_json(jsondump)
        self.assertEqual(self.target.targetid, target2.targetid)
        self.assertEqual(self.target.fieldid, target2.fieldid)
        self.assertEqual(self.target.filter, target2.filter)
        self.assertEqual(self.target.ra_rad, target2.ra_rad)
        self.assertEqual(self.target.dec_rad, target2.dec_rad)
        self.assertEqual(self.target.num_exp, target2.num_exp)
        self.assertListEqual(self.target.exp_times, target2.exp_times)

    def test_json_ingest_has_required_params(self):
        self.assertRaises(KeyError, self.init_target_with_bad_json)

    def init_target_with_bad_json(self):
        missingfilter = '{"targetid": 3, "fieldid": 2573, "ra_rad": 5.24504477561707, "dec_rad": -0.030036505561584215, "ang_rad": 0.7853981633974483, "num_exp": 2, "exp_times": [15.0, 15.0], "_exp_time": null, "time": 0.0, "airmass": 0.0, "sky_brightness": 0.0, "cloud": 0.0, "seeing": 0.0, "propid": 0, "need": 0.0, "bonus": 0.0, "value": 0.0, "goal": 0, "visits": 0, "progress": 0.0, "sequenceid": 0, "subsequencename": "", "groupid": 0, "groupix": 0, "is_deep_drilling": false, "is_dd_firstvisit": false, "remaining_dd_visits": 0, "dd_exposures": 0, "dd_filterchanges": 0, "dd_exptime": 0.0, "alt_rad": 0.7853981633974483, "az_rad": 3.9269908169872414, "rot_rad": 0.5235987755982988, "telalt_rad": 0.7853981633974483, "telaz_rad": 3.9269908169872414, "telrot_rad": 0.5235987755982988, "propboost": 1.0, "slewtime": 0.0, "cost": 0.0, "rank": 0.0, "num_props": 0, "propid_list": [], "need_list": [], "bonus_list": [], "value_list": [], "propboost_list": [], "sequenceid_list": [], "subsequencename_list": [], "groupid_list": [], "groupix_list": [], "is_deep_drilling_list": [], "is_dd_firstvisit_list": [], "remaining_dd_visits_list": [], "dd_exposures_list": [], "dd_filterchanges_list": [], "dd_exptime_list": [], "last_visit_time": 0.0, "note": ""}'
        t = Target()
        t.from_json(missingfilter)

    def test_string_representation(self):
        truth_str = "targetid=3 field=2573 filter=r exp_times=[15.0, 15.0] "\
                    "ra=300.519 dec=-1.721 ang=45.000 alt=45.000 az=225.000 "\
                    "rot=30.000 telalt=45.000 telaz=225.000 telrot=30.000 "\
                    "time=0.0 airmass=0.000 brightness=0.000 "\
                    "cloud=0.00 seeing=0.00 visits=0 progress=0.00% "\
                    "seqid=0 ssname= groupid=0 groupix=0 "\
                    "firstdd=False ddvisits=0 "\
                    "need=0.000 bonus=0.000 value=0.000 propboost=1.000 "\
                    "propid=[] need=[] bonus=[] value=[] propboost=[] "\
                    "slewtime=0.000 cost=0.000 rank=0.000 note="
        self.assertEqual(str(self.target), truth_str)

    def test_driver_state_copy(self):
        target2 = Target()
        target2.copy_driver_state(self.target)
        self.assertEqual(target2.alt_rad, self.alt_rad)
        self.assertEqual(target2.az_rad, self.az_rad)
        self.assertEqual(target2.ang_rad, self.ang_rad)
        self.assertEqual(target2.rot_rad, self.rot_rad)
        self.assertEqual(target2.telalt_rad, self.telalt_rad)
        self.assertEqual(target2.telaz_rad, self.telaz_rad)
        self.assertEqual(target2.telrot_rad, self.telrot_rad)

    def test_copy_creation(self):
        target2 = self.target.get_copy()
        target2.targetid = 10
        target2.fieldid = 2142
        self.assertEqual(self.target.targetid, self.targetId)
        self.assertEqual(target2.targetid, 10)
        self.assertEqual(self.target.fieldid, self.fieldId)
        self.assertEqual(target2.fieldid, 2142)

    def test_creation_from_topic(self):
        topic = collections.namedtuple('topic', ['targetId', 'fieldId',
                                                 'filter', 'ra', 'decl',
                                                 'skyAngle',
                                                 'numExposures',
                                                 'exposureTimes'])
        topic.targetId = 1
        topic.fieldId = -1
        topic.filter = 'z'
        topic.ra = 274.279376
        topic.decl = -14.441534
        topic.skyAngle = 45.0
        topic.numExposures = 3
        topic.exposureTimes = [5.0, 10.0, 5.0]
        target = Target.from_topic(topic)
        self.assertEqual(target.targetid, topic.targetId)
        self.assertEqual(target.fieldid, topic.fieldId)
        self.assertEqual(target.filter, topic.filter)
        self.assertEqual(target.ra, topic.ra)
        self.assertAlmostEqual(target.dec, topic.decl, delta=1e-7)
        self.assertEqual(target.num_exp, topic.numExposures)
        self.assertListEqual(target.exp_times, topic.exposureTimes)
Пример #22
0
class Driver(object):
    def __init__(self):
        self.log = logging.getLogger("schedulerDriver")

        self.params = DriverParameters()
        self.location = ObservatoryLocation()

        self.observatoryModel = ObservatoryModel(self.location, WORDY)
        self.observatoryModel2 = ObservatoryModel(self.location, WORDY)
        self.observatoryState = ObservatoryState()

        self.sky = AstronomicalSkyModel(self.location)

        self.propid_counter = 0
        self.night = 0
        self.start_time = 0.0
        self.time = 0.0
        self.targetid = 0
        self.survey_started = False
        self.isnight = False
        self.sunset_timestamp = 0.0
        self.sunrise_timestamp = 0.0
        self.survey_duration_DAYS = 0.0
        self.survey_duration_SECS = self.survey_duration_DAYS * 24 * 60 * 60.0
        self.darktime = False
        self.mounted_filter = ""
        self.unmounted_filter = ""
        self.midnight_moonphase = 0.0

        self.nulltarget = Target()
        self.nulltarget.targetid = -1
        self.nulltarget.num_exp = 1
        self.nulltarget.exp_times = [0.0]
        self.nulltarget.num_props = 1
        self.nulltarget.propid_list = [0]
        self.nulltarget.need_list = [0.0]
        self.nulltarget.bonus_list = [0.0]
        self.nulltarget.value_list = [0.0]
        self.nulltarget.propboost_list = [1.0]

        self.last_winner_target = self.nulltarget.get_copy()
        self.deep_drilling_target = None

        self.need_filter_swap = False
        self.filter_to_unmount = ""
        self.filter_to_mount = ""

        self.cloud = 0.0
        self.seeing = 0.0

    def configure_scheduler(self, **kwargs):
        raise NotImplemented

    def configure_duration(self, survey_duration):

        self.survey_duration_DAYS = survey_duration
        self.survey_duration_SECS = survey_duration * 24 * 60 * 60.0

    def configure(self, confdict):
        self.params.configure(confdict)
        self.log.log(WORDY,
                     "configure: night_boundary=%.1f" % (self.params.night_boundary))

    def configure_location(self, confdict):

        self.location.configure(confdict)
        self.observatoryModel.location.configure(confdict)
        self.observatoryModel2.location.configure(confdict)
        self.sky.update_location(self.location)

    def configure_observatory(self, confdict):
        """This method calls the configure()method in ObservatoryModel class,
        which configures all its submodules. When initializing one can issue
        a call to this method with a complete set of parameters on confdict.

        Parameters
        ----------
        confdict : dict()

        Returns
        -------
        None
        """
        self.observatoryModel.configure(confdict)
        self.observatoryModel2.configure(confdict)

    def configure_telescope(self, confdict):

        self.observatoryModel.configure_telescope(confdict)
        self.observatoryModel2.configure_telescope(confdict)

    def configure_rotator(self, confdict):

        self.observatoryModel.configure_rotator(confdict)
        self.observatoryModel2.configure_rotator(confdict)

    def configure_dome(self, confdict):

        self.observatoryModel.configure_dome(confdict)
        self.observatoryModel2.configure_dome(confdict)

    def configure_optics(self, confdict):

        self.observatoryModel.configure_optics(confdict)
        self.observatoryModel2.configure_optics(confdict)

    def configure_camera(self, confdict):

        self.observatoryModel.configure_camera(confdict)
        self.observatoryModel2.configure_camera(confdict)

    def configure_slew(self, confdict):

        self.observatoryModel.configure_slew(confdict)
        self.observatoryModel2.configure_slew(confdict)

    def configure_park(self, confdict):

        self.observatoryModel.configure_park(confdict)
        self.observatoryModel2.configure_park(confdict)

    def start_survey(self, timestamp, night):
        """This method begins the survey.

        Parameters
        ----------
        timestamp : float
        night : int

        Returns
        -------
        None
        """
        self.start_time = timestamp

        self.log.info("start_survey t=%.6f" % timestamp)

        self.survey_started = True
        self.sky.update(timestamp)
        (sunset, sunrise) = self.sky.get_night_boundaries(self.params.night_boundary)
        self.log.debug("start_survey sunset=%.6f sunrise=%.6f" % (sunset, sunrise))
        # if round(sunset) <= round(timestamp) < round(sunrise):
        if sunset <= timestamp < sunrise:
            self.start_night(timestamp, night)

        self.sunset_timestamp = sunset
        self.sunrise_timestamp = sunrise

    def end_survey(self):
        """This method ends the survey.

        Parameters
        ----------
        None

        Returns
        -------
        None
        """
        self.log.info("end_survey")

    def start_night(self, timestamp, night):
        """This method is called once per night before observations begin.
        It is not called if the observatory is undergoing downtime.
        Parameters
        ----------
        timestamp : float
        night : int

        Returns
        -------
        None
        """
        timeprogress = (timestamp - self.start_time) / self.survey_duration_SECS
        self.log.info("start_night t=%.6f, night=%d timeprogress=%.2f%%" %
                      (timestamp, night, 100 * timeprogress))

        self.isnight = True

    def end_night(self, timestamp, night):
        """This method is called once per night after observing completes.

        Parameters
        ----------
        timestamp : float
        night : int

        Returns
        -------
        None
        """
        pass

    def swap_filter(self, filter_to_unmount, filter_to_mount):

        self.log.info("swap_filter swap %s=>cam=>%s" % (filter_to_mount, filter_to_unmount))

        self.observatoryModel.swap_filter(filter_to_unmount)

        self.unmounted_filter = filter_to_unmount
        self.mounted_filter = filter_to_mount

        return

    def update_time(self, timestamp, night):
            self.time = timestamp
            self.observatoryModel.update_state(self.time)
            if not self.survey_started:
                self.start_survey(timestamp, night)

            if self.isnight:
                # if round(timestamp) >= round(self.sunrise_timestamp):
                if timestamp >= self.sunrise_timestamp:
                    self.end_night(timestamp, night)
            else:
                # if round(timestamp) >= round(self.sunset_timestamp):
                if timestamp >= self.sunset_timestamp:
                    self.start_night(timestamp, night)
            return self.isnight

    def get_need_filter_swap(self):
        """When scheduler determines that a filter swap is needed,
        this shall return a tuple where the first element is a TRUE value,
        and the second and third elements are single-character strings identifying
        which filter to remove from the carousel, and which filter to add, respectively.

        Parameters
        ----------
        None

        Returns
        -------
        Tuple (bool, str, str)
        """
        return (self.need_filter_swap, self.filter_to_unmount, self.filter_to_mount)

    def update_internal_conditions(self, observatory_state, night):

        if observatory_state.unmountedfilters != self.observatoryModel.current_state.unmountedfilters:
            unmount = observatory_state.unmountedfilters[0]
            mount = self.observatoryModel.current_state.unmountedfilters[0]
            self.swap_filter(unmount, mount)
        self.time = observatory_state.time
        self.observatoryModel.set_state(observatory_state)
        self.observatoryState.set(observatory_state)

    def update_external_conditions(self, cloud, seeing):

        self.cloud = cloud
        self.seeing = seeing

        return

    def cold_start(self, observations):
        """Rebuilds the internal state of the scheduler from a list of observations.

        Parameters
        ----------
        observations : list of Observation objects

        Returns
        -------
        None
        """
        raise NotImplemented

    def select_next_target(self):
        """Picks a target and returns it as a target object.

        Parameters
        ----------
        None

        Returns
        -------
        Target
        """

        raise NotImplemented

    def register_observation(self, observation):
        """Validates observation and returns a list of successfully completed observations.

        Parameters
        ----------
        observation : Observation or a python list of Observations

        Returns
        -------
        Python list of one or more Observations
        """

        raise NotImplemented
Пример #23
0
    def generate_target(self, fb_observation, tag='generate'):
        '''Takes an observation array given by the feature based scheduler and generate an appropriate OpSim target.

        :param fb_observation: numpy.array
        :return: Target
        '''

        # self.log.debug('%s: %s' % (tag, fb_observation))
        self.targetid += 1
        filtername = fb_observation['filter']
        propid = fb_observation['survey_id']

        target = Target()
        target.targetid = self.targetid
        target.fieldid = fb_observation['field_id']
        target.filter = str(filtername)
        target.num_exp = fb_observation['nexp']
        target.exp_times = [
            fb_observation['exptime'] / fb_observation['nexp']
        ] * fb_observation['nexp']
        target.ra_rad = fb_observation['RA']
        target.dec_rad = fb_observation['dec']
        target.ang_rad = fb_observation['rotSkyPos']
        target.propid = propid
        target.goal = 100
        target.visits = 0
        target.progress = 0.0
        target.groupid = 1
        target.groupix = 0
        target.propid_list = [propid]
        target.need_list = [target.need]
        target.bonus_list = [target.bonus]
        target.value_list = [target.value]
        target.propboost_list = [target.propboost]
        target.sequenceid_list = [target.sequenceid]
        target.subsequencename_list = [target.subsequencename]
        target.groupid_list = [target.groupid]
        target.groupix_list = [target.groupix]
        target.is_deep_drilling_list = [target.is_deep_drilling]
        target.is_dd_firstvisit_list = [target.is_dd_firstvisit]
        target.remaining_dd_visits_list = [target.remaining_dd_visits]
        target.dd_exposures_list = [target.dd_exposures]
        target.dd_filterchanges_list = [target.dd_filterchanges]
        target.dd_exptime_list = [target.dd_exptime]

        return target
Пример #24
0
    def __init__(self, propid, field, name, params):

        self.propid = propid
        self.field = field
        self.name = name

        self.num_events = params.subsequence_num_events[name]
        self.num_max_missed = params.subsequence_num_max_missed[name]
        self.time_interval = params.subsequence_time_interval[name]
        self.time_window_start = params.subsequence_time_window_start[name]
        self.time_window_max = params.subsequence_time_window_max[name]
        self.time_window_end = params.subsequence_time_window_end[name]
        self.filter_list = params.subsequence_filter_list[name]
        self.visits_list = params.subsequence_visits_list[name]
        self.filter_num_exp_dict = dict(params.filter_num_exp_dict)
        self.filter_exp_times_dict = dict(params.filter_exp_times_dict)

        self.num_visits_per_event = 0
        self.filters_goal_dict = {}

        self.dd_exposures = 0
        self.dd_exptime = 0.0
        self.num_subevents = len(self.filter_list)
        for ix, filter in enumerate(self.filter_list):
            if filter not in self.filters_goal_dict:
                self.filters_goal_dict[filter] = 0
            self.filters_goal_dict[filter] += self.num_events * self.visits_list[ix]
            self.num_visits_per_event += self.visits_list[ix]
            self.dd_exposures += self.visits_list[ix] * self.filter_num_exp_dict[filter]
            self.dd_exptime += self.visits_list[ix] * sum(self.filter_exp_times_dict[filter])
        self.goal = self.num_events * self.num_visits_per_event

        if (len(self.visits_list) > 1) or (self.visits_list[0] > 1):
            self.is_deep_drilling = True
            self.dd_visits = self.num_visits_per_event
            self.dd_filterchanges = max(len(self.filter_list) - 1, 0)
        else:
            self.is_deep_drilling = False
            self.dd_visits = 0
            self.dd_filterchanges = 0

        self.subevent_index = 0
        self.subevent_num_visits_left = self.visits_list[0]
        self.event_visits_list = []
        self.all_events_list = []
        self.obs_events_list = []
        self.mis_events_list = []
        self.in_deep_drilling = False

        self.target = Target()
        self.target.fieldid = field.fieldid
        self.target.filter = self.filter_list[self.subevent_index]
        self.target.num_exp = self.filter_num_exp_dict[self.target.filter]
        self.target.exp_times = self.filter_exp_times_dict[self.target.filter]
        self.target.ra_rad = field.ra_rad
        self.target.dec_rad = field.dec_rad
        self.target.propid = self.propid
        self.target.goal = self.goal
        self.target.visits = 0
        self.target.progress = 0.0

        self.target.sequenceid = self.field.fieldid
        self.target.subsequencename = self.name
        self.target.groupid = 1
        self.target.groupix = 1
        self.target.is_deep_drilling = self.is_deep_drilling
        self.target.is_dd_firstvisit = self.is_deep_drilling
        self.target.remaining_dd_visits = self.dd_visits
        self.target.dd_exposures = self.dd_exposures
        self.target.dd_filterchanges = self.dd_filterchanges
        self.target.dd_exptime = self.dd_exptime

        self.update_state()