import os sys.dont_write_bytecode = True from minerva_library import control from minerva_library import utils import ipdb, datetime, time, socket import threading from minerva_library import mail if __name__ == '__main__': utils.killmain() base_directory = '/home/minerva/minerva-control' if socket.gethostname() == 'Kiwispec-PC': base_directory = 'C:/minerva-control' minerva = control.control('control_day.ini', base_directory) # stop at 2:30 pm local (so calibrations can finish before daily reboot at 3:30 pm) endtime = datetime.datetime(datetime.datetime.utcnow().year, datetime.datetime.utcnow().month, datetime.datetime.utcnow().day, 21, 30, 0) # home all telescopes (make sure they're pointing north) # ***not in danger of pointing at the Sun*** minerva.telescope_park() for telescope in minerva.telescopes: if not telescope.inPosition(alt=45.0, az=0.0, pointingTolerance=3600.0, tracking=False,
dest='red', action='store_true', default=False, help='run with MINERVA red configuration') parser.add_argument('--south', dest='south', action='store_true', default=False, help='run with MINERVA Australis configuration') opt = parser.parse_args() base_directory = '/home/minerva/minerva-control' utils.killmain(red=opt.red, south=opt.south) minerva = control.control('control.ini', base_directory, red=opt.red, south=opt.south) for dome in minerva.domes: sunfile = 'minerva_library/sunOverride.' + dome.id + '.request.txt' if os.path.exists(sunfile): os.remove(sunfile) # make sure the domes are closed # but not if it starts in the middle of the night # if datetime.datetime.utcnow().hour < 2 or datetime.datetime.utcnow( ).hour > 20: requestfile = 'minerva_library/' + dome.id + '.request.txt' if os.path.exists(requestfile): os.remove(requestfile) # if a file for kiwispec exists, use that. If not, observe with all four telescopes if os.path.exists(minerva.base_directory + '/schedule/' + minerva.site.night + '.kiwispec.txt'):
def observe(red=False, south=False): try: utils.killmain(red=red, south=south) except: pass base_directory = '/home/minerva/minerva-control' minerva = control.control('control.ini', base_directory, red=red, south=south) threads = [] for telescope in minerva.telescopes: # Prep for Night camera = utils.getCamera(minerva, telescope.id) #set up night's directory minerva.prepNight(telescope) scheduleFile = minerva.base_directory + '/schedule/' + minerva.site.night + '.' + telescope.id + '.txt' utils.scheduleIsValid(scheduleFile, email=True, logger=minerva.logger, directory=minerva.directory) # Setup tech thread thread = PropagatingThread(target=SetupTech, args=(minerva, telescope, camera)) thread.name = telescope.id thread.start() threads.append(thread) # End FOR loop # Wait until all threads are done because if this telescope's homing is not complete, # then the skyflats thread (which checks to see if the homing is complete) # will try to home the telescope if it sees that it is not done homing. # This makes 2 functions trying to home the telescope at the same time. for p in np.arange(len(threads)): minerva.logger.info("Waiting for " + threads[p].name + " to finish") threads[p].join() minerva.logger.info("All threads finished setting up") threads = [] # Spectroscopic Calibration # if before the end of twilight, do calibrations if datetime.datetime.utcnow() < minerva.site.NautTwilEnd(): if minerva.spectrograph != None: rv_control.backlight(minerva) # by default, checkiftime = True. This is just here as a reminder kwargs = {'checkiftime': True} if minerva.spectrograph != None: thread = PropagatingThread(target=minerva.specCalib_catch, args=(), kwargs=kwargs) if minerva.red: thread.name = 'MRED' else: thread.name = 'Kiwispec' thread.start() threads.append(thread) # photometric calibrations for telescope in minerva.telescopes: CalibInfo, CalibEndInfo = minerva.loadCalibInfo(telescope.id) if CalibInfo != None and CalibEndInfo != None: # Photometry Calibration thread if datetime.datetime.utcnow() < minerva.site.NautTwilEnd(): # by default, checkiftime = True. This is just here as a reminder kwargs = {'checkiftime': True} thread = PropagatingThread(target=PhotCalib, args=(minerva, CalibInfo, telescope.id), kwargs=kwargs) thread.name = telescope.id thread.start() threads.append(thread) for p in np.arange(len(threads)): threads[p].join() minerva.logger.info("Done with daytime calibrations") # Now do Domes and Skyflats threads = [] for telescope in minerva.telescopes: CalibInfo, CalibEndInfo = minerva.loadCalibInfo(telescope.id) # Prepare Domes before taking Sky flats dome = utils.getDome(minerva, telescope.id) sunfile = minerva.base_directory + '/minerva_library/sunOverride.' + dome.id + '.txt' if os.path.exists(sunfile): os.remove(sunfile) with open( minerva.base_directory + '/minerva_library/' + dome.id + '.request.txt', 'w') as fh: fh.write(str(datetime.datetime.utcnow())) if CalibInfo != None and CalibEndInfo != None: if datetime.datetime.utcnow() < minerva.site.NautTwilEnd(): # Skyflats thread thread = PropagatingThread(target=startSkyFlats, args=(minerva, telescope, dome, CalibInfo)) thread.name = telescope.id thread.start() threads.append(thread) # End FOR loop tel_p_targets = {} for telescope in minerva.telescopes: try: with open( minerva.base_directory + '/schedule/' + minerva.site.night + '.' + telescope.id + '.txt', 'r') as targetfile: next(targetfile) # skip both calibration headers next(targetfile) p_targets = [] for line in targetfile: target = minerva.parseTarget(line) if target <> -1: # only works for Python 2 # truncate the start and end times so it's observable: elevation (above ~20 degrees) and airmass (X < 3 or 2) target = utils.truncate_observable_window( minerva.site, target, logger=minerva.logger) # The target dictionary's start and end times should be in datetime.datetime format now if target['starttime'] < target['endtime']: p_targets.append(target) # starttime and endtime should only represent when the object is observable tel_p_targets[telescope.id] = p_targets except IOError: # there is no photometry target file # record the telescope so that when the night begins, the dynamic scheduler will know which telescope(s) are free tel_p_targets[telescope.id] = None # Even if there is a photometry schedule for a telescope, we may not want (or be able) to use that telescope so I don't include such a telescope in the dictionary # Calculate the duration times between photometry targets # Calculate the expected start and end times of the photometric observations for telescope in minerva.telescopes: # check for photometry targets in the telescope target [list] if tel_p_targets[telescope.id] != None: for ind_target in xrange(len(tel_p_targets[telescope.id])): p_target = tel_p_targets[telescope.id][ ind_target] # without copy.copy, this ind_target dictionary will change whenever the p_target variable changes. This only happens with one variable coupling at a time if ind_target == 0: minerva.logger.info('here 6') if p_target['starttime'] < minerva.site.NautTwilEnd( ): # staying safe, but should not be necessary p_target['exp_starttime'] = minerva.site.NautTwilEnd() else: p_target['exp_starttime'] = p_target['starttime'] # Add expected endtime by accounting for the number of exposures, exposure time, filters, and acquisition p_target['exp_endtime'] = p_target[ 'exp_starttime'] + Acq_Exp_RdO(120.0, p_target, 7.0) if p_target['exp_endtime'] > p_target['endtime']: p_target['exp_endtime'] = p_target['endtime'] if p_target['exp_endtime'] > minerva.site.NautTwilBegin( ): # if the exp_endtime is later than sunrise p_target['exp_endtime'] = minerva.site.NautTwilBegin() else: minerva.logger.info('here 7') # check previous expected endtime, if that overlaps with the current starttime then create expected starttime in target's dictionary if p_target['starttime'] <= tel_p_targets[telescope.id][ ind_target - 1]['exp_endtime']: p_target['exp_starttime'] = tel_p_targets[telescope.id][ ind_target - 1]['exp_endtime'] # It is okay to overlap because of the specified acquisition time, and the computer won't start acquiring the next target until the first one is finished--even if I tell it to do so. else: p_target['exp_starttime'] = p_target['starttime'] # After ascertaining expected starttime of this target, then determine expected endtime of this target p_target['exp_endtime'] = p_target[ 'exp_starttime'] + Acq_Exp_RdO(120.0, p_target, 7.0) if p_target['exp_endtime'] > p_target['endtime']: p_target['exp_endtime'] = p_target['endtime'] if p_target['exp_endtime'] > minerva.site.NautTwilBegin( ): # if the exp_endtime is later than sunrise p_target['exp_endtime'] = minerva.site.NautTwilBegin() #tel_p_targets[telescope.id][ind_target] = p_target # the updated dictionary is placed back in the list # This should be unnecessary because I did not use copy.copy # Get the states of change minerva.logger.info('here 8') chrono_states = get_States(minerva, tel_p_targets) minerva.logger.info('here 9') # Wait for the sky flats to finish for p in np.arange(len(threads)): threads[p].join() minerva.logger.info('here 10') omniObserve(minerva, chrono_states) minerva.logger.info('here 11') for tele in minerva.telescopes: minerva.endNight(tele, kiwispec=True)