from __future__ import absolute_import from celery.task import Task from django.conf import settings from common.models import * from utils.Logger import setupLogger from analyzer.tasks import Analysis from utils.JDManipulator import * from devices.Telescope import TelescopeController from devices.CameraNIR import NIRCameraController from devices.CameraVIS import VISCameraController import time import subprocess import os ''' Super class for execute_plan_vis / _nir ''' class execute_plan(Task): def setTelescope(self): self.tel = TelescopeController() return 0 def start(self) -> int: self.setTelescope() self.logger = setupLogger("Observation"+self.type, "Observation"+self.type) self.image_count = 0 # JB TODO REMOVE : is it still useful ? # TaskId.objects.filter(task_id=self.request.id).delete() if self.countdown > 0: time.sleep(self.countdown) try: self.plan = Plan.objects.get(id=self.plan_id) self.duration = julianSecondsToSeconds(self.plan.duration) except: self.logDB(message="Plan with id %d not found" % (self.plan_id)) return 1 self.plan_dir = self.plan.name + "_" + str(self.plan_id) self.dir_name = settings.OUTPUT_FOLDER + os.sep + self.plan_dir if self.createDirs(): self.log("Could not create dirs") self.logDB(message="Could not create directory " + self.dir_name + " for image storage") return 1 self.launchAnalysis() self.log("Starting execution " + self.type) return self.logDB('Start plan %s observation from camera %s'%(self.plan.name, str(self.type))) def createDirs(self): try: if not os.path.isdir(settings.OUTPUT_FOLDER): os.makedirs(settings.OUTPUT_FOLDER) if not os.path.isdir(self.dir_name): os.makedirs(self.dir_name) except: return 1 return 0 def log(self, message: str) -> int: self.logger.info(self.type + ' -> '+ message) return 0 def logDB(self, message: str) -> int: Log.objects.create(agent='Observation manager', message=message) return 0 def launchAnalysis(self): Analysis.apply_async((self.plan_id, settings.OUTPUT_FOLDER)) return 0 def launchCalibration(self) -> int: create_calibrations.apply_async((self.plan_id, settings.OUTPUT_FOLDER, self.image_count)) return 0 def end(self) -> int: self.log("Finished plan observation") return self.logDB('Finished plan observation ' + self.plan.name + ' from camera ' + str(self.type)) def run(self, plan_id: int, countdown: float, type: str) -> int: self.plan_id = plan_id self.countdown = countdown self.type = type if self.start(): self.log("fail exec task -> leaving") return 1 self.execute() return self.end() def execute(self) -> int: time = julianSecondsToSeconds(self.plan.duration) self.log("Sleeping for " + str(int(self.duration))) time.sleep(int(self.duration)) return 0 ''' Gives the orders to the instruments to retrieve the image(s) of a plan VIS. Send the images to the calibrator ''' class execute_plan_vis(execute_plan): def setCamera(self): self.vis_camera = VISCameraController() return 0 def run(self, plan_id: int, countdown: float) -> int: self.setCamera() super().run(plan_id, countdown, "VIS") return 0 def execute(self) -> int: # TODO All the comunication protocol with the device self.tel.do("GOTO " + str(self.plan.position)) self.vis_camera.do("CAPTURE "+self.dir_name+" "+str(self.plan.nb_images)+" "+str(self.plan.duration)) self.log("Sleeping for " + str(int(self.duration))) #TODO: faire un boucle infinie de recup image + lancement calib pour chaque image des que disponible time.sleep(int(self.duration)) self.launchCalibration() return 0 ''' Gives the orders to the instruments to retrieve the image(s) of a plan NIR. Send the images to the calibrator ''' class execute_plan_nir(execute_plan): def setCamera(self): self.nir_camera = NIRCameraController() return 0 def run(self, plan_id: int, countdown: float) -> int: self.setCamera() super().run(plan_id, countdown, "NIR") return 0 def execute(self) -> int: # TODO All the comunication protocol with the device self.tel.do("GOTO " + str(self.plan.position)) self.nir_camera.do("CAPTURE "+self.dir_name+" "+str(self.plan.nb_images)+" "+str(self.plan.duration)) self.log("Sleeping for " + str(int(self.duration))) #TODO: faire un boucle infinie de recup image + lancement calib pour chaque image des que disponible time.sleep(int(self.duration)) self.launchCalibration() return 0 ''' Call a process with a folder and an image number as parameter who will create the calibration for an image ''' class create_calibrations(Task): logger = setupLogger("calibrations", "calibrations") def log(self, message: str) -> int: self.logger.info(message) return 0 def logDB(self, message: str) -> int: Log.objects.create(agent='Observation manager', message=message) return 0 def execProcess(self, command: str) -> int: self.process = subprocess.Popen(command, shell=True) return 0 def start(self, plan_id: int, folder: str, image_number: int) -> int: self.plan_id = plan_id self.folder = folder self.image_number = image_number self.path_dir_file = os.path.dirname(os.path.realpath(__file__)) try: self.plan = Plan.objects.get(id=self.plan_id) self.plan_folder = self.plan.name + "_" + str(self.plan_id) except: self.log("not found calibrations") self.logDB(message="Plan with id %d not found"%(self.plan_id)) return 1 self.dir_name = self.folder + os.sep + self.plan.name + "_" + str(self.plan_id) + os.sep + "calibrations" if self.createDirectory(): self.log("err dir calibrations") self.logDB(message="Could not create folder for calibrations") return 1 self.log("start calibrations") return self.logDB("Starting calibration for image " + str(self.image_number)) def createDirectory(self): try: if not os.path.isdir(self.dir_name): os.makedirs(self.dir_name) except: return 1 return 0 def changeDirectory(self, path: str): os.chdir(path) return 0 def execute(self) -> int: self.changeDirectory(self.path_dir_file) return self.execProcess("./calibrator '"+str(self.folder)+"' '"+self.plan_folder+"' '"+str(self.image_number) + "'") def end(self) -> int: self.process.wait() if self.process.returncode == 0: self.log("executed calibrations") self.logDB(message="Calibration executed successfully for image " + str(self.image_number)) else: self.log("failed calibrations") self.logDB(message="Could not calibrate image " + str(self.image_number)) return self.process.returncode def run(self, plan_id: int, folder: str, image_number: int) -> int: if self.start(plan_id, folder, image_number): return 1 self.execute() return self.end() class night_calibrations(Task): def run(self): return 0