Example #1
0
    def run(self):
        log.info("Starting scheduler machine")
        self.state(State.OFF)

        # inject instruments on handlers
        self.executor.__start__()

        while self.state() != State.SHUTDOWN:

            if self.state() == State.OFF:
                log.debug("[off] will just sleep..")
                self.sleep()

            if self.state() == State.START:
                log.debug("[start] database changed, rescheduling...")
                self.scheduler.reschedule(self)
                self.state(State.IDLE)

            if self.state() == State.IDLE:

                log.debug("[idle] looking for something to do...")

                # find something to do
                program = self.scheduler.next()

                if program:
                    log.debug("[idle] there is something to do, processing...")
                    log.debug("[idle] program slew start %s",program.slewAt)
                    log.debug("[idle] program exposure start %s",program.exposeAt)
                    self.state(State.BUSY)
                    self.currentProgram = program
                    self._process(program)
                    continue

                # should'nt get here if any task was executed
                log.debug("[idle] there is nothing to do, going offline...")
                self.currentProgram = None
                self.state(State.OFF)

            elif self.state() == State.BUSY:
                log.debug("[busy] waiting tasks to finish..")
                self.sleep()

            elif self.state() == State.STOP:
                log.debug("[stop] trying to stop current program")
                self.executor.stop()
                self.state(State.OFF)

            elif self.state() == State.SHUTDOWN:
                log.debug("[shutdown] trying to stop current program")
                self.executor.stop()
                log.debug("[shutdown] should die soon.")
                break

        log.debug('[shutdown] thread ending...')
Example #2
0
    def start(self, location):
        """
        Start the object pointed by 'location'.

        @param location: The object to start.
        @type location: Location or str

        @raises ObjectNotFoundException: When te request object or the Manager was not found.
        @raises ChimeraObjectException: Internal error on managed (user) object.
        
        @return: retuns True if sucessfull. False otherwise.
        @rtype: bool
        """

        if location not in self.resources:
            raise ObjectNotFoundException("Location %s was not found." %
                                          location)

        log.info("Starting %s." % location)

        resource = self.resources.get(location)

        if resource.instance.getState() == State.RUNNING:
            return True

        try:
            resource.instance.__start__()
        except Exception:
            log.exception("Error running %s __start__ method." % location)
            raise ChimeraObjectException("Error running %s __start__ method." %
                                         location)

        try:
            # FIXME: thread exception handling
            # ok, now schedule object main in a new thread
            log.info("Running %s. __main___." % location)

            loop = threading.Thread(target=resource.instance.__main__)
            loop.setName(str(resource.location) + ".__main__")
            loop.setDaemon(True)
            loop.start()

            resource.instance.__setstate__(State.RUNNING)
            resource.created = time.time()
            resource.loop = loop

            return True

        except Exception, e:
            log.exception("Error running %s __main__ method." % location)
            resource.instance.__setstate__(State.STOPPED)
            raise ChimeraObjectException("Error running %s __main__ method." %
                                         location)
Example #3
0
    def beginExposure (self, manager):

        self._fetchPreHeaders(manager)

        if self["wait_dome"]:
            try:
                dome = manager.getProxy("/Dome/0")
                dome.syncWithTel()
                log.debug("Dome slit position synchronized with telescope position.")
                
            except ObjectNotFoundException:
                log.info("No dome present, taking exposure without dome sync.")
Example #4
0
    def beginExposure(self, manager):

        self._fetchPreHeaders(manager)

        if self["wait_dome"]:
            try:
                dome = manager.getProxy("/Dome/0")
                dome.syncWithTel()
                log.debug(
                    "Dome slit position synchronized with telescope position.")

            except ObjectNotFoundException:
                log.info("No dome present, taking exposure without dome sync.")
Example #5
0
    def startup(self):

        if self.options.daemon:
            # detach
            log.info("FIXME: Daemon...")
            
        # system config
        try:
            self.config = SystemConfig.fromFile(self.options.config_file)
        except (InvalidLocationException, IOError), e:
            log.exception(e)
            log.error("There was a problem reading your configuration file. (%s)" % e)
            sys.exit(1)
Example #6
0
    def selectScienceTargets(self):
        '''
		Based on configuration parameters select a good set of targets to run scheduler on a specified Julian Day.
		'''

        session = Session()

        # [To be done] Reject objects that are close to the moon

        for tbin, time in enumerate(self.obsTimeBins):

            if self.obsTimeMask[tbin] < 1.0:
                # Select objects from database that where not observed and where not scheduled yet
                # In the future may include targets that where observed a number of nights ago.
                # This is still incomplete. We should also consider the distance from the previous pointing to the next!
                # Since a target can have a higher airmass but be farther away from a neaby target that will take less time
                # to point.
                # one way of selecting targets that are close together and have good airmass is to select regions that are close
                # to the current location. it can start as searching an area with r1 ~ 10 x the FoV and, if there are no regions
                # to to x2 that and then x4 that. If still there are no targets, than search for the higher in the sky.
                targets = session.query(Targets).filter(
                    Targets.observed == False).filter(
                        Targets.scheduled == False).filter(
                            Targets.type == self.sciFlag)

                lst = _skysub.lst(time, self.sitelong)  #*360./24.
                alt = np.array([
                    _skysub.altit(target.targetDec, lst - target.targetRa,
                                  self.sitelat)[0] for target in targets
                ])
                stg = alt.argmax()

                log.info('Selecting %s' % (targets[stg]))

                # Marking target as schedule
                tst = session.query(Targets).filter(
                    Targets.id == targets[stg].id)

                for t in tst:
                    t.scheduled = True
                    session.commit()
                    self.addObservation(t, time)

                self.obsTimeMask[tbin] = 1.0
            else:
                log.debug(
                    'Bin %3i @mjd=%.3f already filled up with observations. Skipping...'
                    % (tbin, time - 2400000.5))

        #print i
        return 0  #targets
Example #7
0
    def start (self, location):
        """
        Start the object pointed by 'location'.

        @param location: The object to start.
        @type location: Location or str

        @raises ObjectNotFoundException: When te request object or the Manager was not found.
        @raises ChimeraObjectException: Internal error on managed (user) object.
        
        @return: retuns True if sucessfull. False otherwise.
        @rtype: bool
        """

        if location not in self.resources:
            raise ObjectNotFoundException ("Location %s was not found." % location)
            
        log.info("Starting %s." % location)            

        resource = self.resources.get(location)

        if resource.instance.getState() == State.RUNNING:
            return True

        try:
            resource.instance.__start__()
        except Exception:
            log.exception ("Error running %s __start__ method." % location)
            raise ChimeraObjectException("Error running %s __start__ method." % location)

        try:
            # FIXME: thread exception handling
            # ok, now schedule object main in a new thread
            log.info("Running %s. __main___." % location)                        

            loop = threading.Thread(target=resource.instance.__main__)
            loop.setName(str(resource.location) + ".__main__")
            loop.setDaemon(True)
            loop.start()

            resource.instance.__setstate__(State.RUNNING)
            resource.created = time.time()
            resource.loop = loop

            return True

        except Exception, e:
            log.exception("Error running %s __main__ method." % location)
            resource.instance.__setstate__(State.STOPPED)
            raise ChimeraObjectException("Error running %s __main__ method." % location)
Example #8
0
    def startup(self):

        if self.options.daemon:
            # detach
            log.info("FIXME: Daemon...")

        # system config
        try:
            self.config = SystemConfig.fromFile(self.options.config_file)
        except (InvalidLocationException, IOError), e:
            log.exception(e)
            log.error(
                "There was a problem reading your configuration file. (%s)" %
                e)
            sys.exit(1)
Example #9
0
    def __init__(self, host=None, port=None, local=False):
        RemoteObject.__init__(self)

        log.info("Starting manager.")

        self.resources = ResourcesManager()
        self.classLoader = ClassLoader()

        # identity
        self.setGUID(MANAGER_LOCATION)

        # shutdown event
        self.died = threading.Event()

        if not local:
            try:
                ManagerLocator.locate()
                raise ChimeraException("Chimera is already running"
                                       " on this system. Use chimera-admin"
                                       " to manage it.")
            except ManagerNotFoundException:
                # ok, we are alone.
                pass

        # our daemon server
        self.adapter = ManagerAdapter(self, host, port)
        self.adapterThread = threading.Thread(target=self.adapter.requestLoop)
        self.adapterThread.setDaemon(True)
        self.adapterThread.start()

        # finder beacon
        if not local:
            self.beacon = ManagerBeacon(self)
            self.beaconThread = threading.Thread(target=self.beacon.run)
            self.beaconThread.setDaemon(True)
            self.beaconThread.start()
        else:
            self.beacon = None

        # register ourself
        self.resources.add(MANAGER_LOCATION, self,
                           getManagerURI(self.getHostname(), self.getPort()))

        # signals
        signal.signal(signal.SIGTERM, self._sighandler)
        signal.signal(signal.SIGINT, self._sighandler)
        atexit.register(self._sighandler)
Example #10
0
    def stop(self, location):
        """
        Stop the object pointed by 'location'.

        @param location: The object to stop.
        @type location: Location or str

        @raises ObjectNotFoundException: When the requested object or the Manager was not found.
        @raises ChimeraObjectException: Internal error on managed (user) object.

        @return: retuns True if sucessfull. False otherwise.
        @rtype: bool
        """

        if location not in self.resources:
            raise ObjectNotFoundException("Location %s was not found." %
                                          location)

        log.info("Stopping %s." % location)

        resource = self.resources.get(location)

        try:

            # stop control loop
            if resource.loop and resource.loop.isAlive():
                resource.instance.__abort_loop__()
                try:
                    resource.loop.join()
                except KeyboardInterrupt:
                    # ignore Ctrl+C on shutdown
                    pass

            if resource.instance.getState() != State.STOPPED:
                resource.instance.__stop__()
                resource.instance.__setstate__(State.STOPPED)

            return True

        except Exception, e:
            log.exception(
                "Error running %s __stop__ method. Exception follows..." %
                location)
            raise ChimeraObjectException("Error running %s __stop__ method." %
                                         location)
Example #11
0
    def shutdown(self):
        """
        Ask the system to shutdown. Closing all sockets and stopping
        all threads.

        @return: Nothing
        @rtype: None
        """

        # die, but only if we are alive ;)
        if not self.died.isSet():

            log.info("Shuting down manager.")

            # stop objects
            # damm 2.4, on 2.5 try/except/finally works
            try:
                try:

                    elderly_first = sorted(
                        list(self.resources.values()),
                        cmp=lambda x, y: cmp(x.created, y.created),
                        reverse=True)

                    for resource in elderly_first:

                        # except Manager
                        if resource.location == MANAGER_LOCATION: continue

                        # stop object
                        self.stop(resource.location)

                except ChimeraException:
                    pass
            finally:
                # kill our adapter
                self.adapter.shutdown(disconnect=True)
                if self.beacon:
                    self.beacon.shutdown()
                    self.beaconThread.join()

                # die!
                self.died.set()
                log.info("Manager finished.")
Example #12
0
    def run(self):
        log.info("Starting scheduler machine")
        self.state(State.DIRTY)

        while self.state() != State.SHUTDOWN:

            if self.state() == State.OFF:
                log.debug("[off] will just sleep..")
                pass

            if self.state() == State.DIRTY:
                log.debug("[dirty] database changed, rescheduling...")
                self.scheduler.reschedule(self)
                self.state(State.IDLE)
                continue

            if self.state() == State.IDLE:

                log.debug("[idle] looking for something to do...")

                # find something to do
                exposure = self.scheduler.next()

                if exposure:
                    log.debug("[idle] there is something to do, processing...")
                    self.state(State.BUSY)
                    self._process(exposure)
                    continue

                # should'nt get here if any task was executed
                log.debug("[idle] there is nothing to do, sleeping...")

            elif self.state() == State.BUSY:
                log.debug("[busy] waiting tasks to finish..")
                pass

            elif self.state() == State.SHUTDOWN:
                log.debug("[shutdown] should die soon.")
                break

            # Rest In Pieces/Let Sleeping Dogs Lie
            self.sleep()

        log.debug('[shutdown] thread ending...')
Example #13
0
	def selectScienceTargets(self):
		'''
		Based on configuration parameters select a good set of targets to run scheduler on a specified Julian Day.
		'''
		
		session = Session()
		
		# [To be done] Reject objects that are close to the moon

		for tbin,time in enumerate(self.obsTimeBins):

			if self.obsTimeMask[tbin] < 1.0:
				# Select objects from database that where not observed and where not scheduled yet
				# In the future may include targets that where observed a number of nights ago.
				# This is still incomplete. We should also consider the distance from the previous pointing to the next!
				# Since a target can have a higher airmass but be farther away from a neaby target that will take less time
				# to point.
				# one way of selecting targets that are close together and have good airmass is to select regions that are close
				# to the current location. it can start as searching an area with r1 ~ 10 x the FoV and, if there are no regions
				# to to x2 that and then x4 that. If still there are no targets, than search for the higher in the sky.
				targets = session.query(Targets).filter(Targets.observed == False).filter(Targets.scheduled == False).filter(Targets.type == self.sciFlag)
			
				lst = _skysub.lst(time,self.sitelong) #*360./24.
				alt = np.array([_skysub.altit(target.targetDec,lst - target.targetRa,self.sitelat)[0] for target in targets])
				stg = alt.argmax()

				log.info('Selecting %s'%(targets[stg]))
				
				# Marking target as schedule
				tst = session.query(Targets).filter(Targets.id == targets[stg].id)

				for t in tst:
					t.scheduled = True
					session.commit()
					self.addObservation(t,time)
				
				self.obsTimeMask[tbin] = 1.0
			else:
				log.debug('Bin %3i @mjd=%.3f already filled up with observations. Skipping...'%(tbin,time-2400000.5))
				
		#print i
		return 0 #targets
Example #14
0
    def stop (self, location):
        """
        Stop the object pointed by 'location'.

        @param location: The object to stop.
        @type location: Location or str

        @raises ObjectNotFoundException: When the requested object or the Manager was not found.
        @raises ChimeraObjectException: Internal error on managed (user) object.

        @return: retuns True if sucessfull. False otherwise.
        @rtype: bool
        """
    
        if location not in self.resources:
            raise ObjectNotFoundException ("Location %s was not found." % location)

        log.info("Stopping %s." % location)
            
        resource = self.resources.get(location)

        try:

            # stop control loop
            if resource.loop and resource.loop.isAlive():
                resource.instance.__abort_loop__()
                try:
                    resource.loop.join()
                except KeyboardInterrupt:
                    # ignore Ctrl+C on shutdown
                    pass

            if resource.instance.getState() != State.STOPPED:
                resource.instance.__stop__ ()
                resource.instance.__setstate__(State.STOPPED)

            return True

        except Exception, e:
            log.exception("Error running %s __stop__ method. Exception follows..." % location)
            raise ChimeraObjectException("Error running %s __stop__ method." % location)
    def shutdown(self):
        """
        Ask the system to shutdown. Closing all sockets and stopping
        all threads.

        @return: Nothing
        @rtype: None
        """

        # die, but only if we are alive ;)
        if not self.died.isSet():

            log.info("Shuting down manager.")

            # stop objects
            # damm 2.4, on 2.5 try/except/finally works
            try:
                try:

                    elderly_first = sorted(
                        list(self.resources.values()), cmp=lambda x, y: cmp(x.created, y.created), reverse=True
                    )

                    for resource in elderly_first:

                        # except Manager
                        if resource.location == MANAGER_LOCATION:
                            continue

                        # stop object
                        self.stop(resource.location)

                except ChimeraException:
                    pass
            finally:
                # kill our adapter
                self.adapter.shutdown(disconnect=True)

                # die!
                self.died.set()
                log.info("Manager finished.")
Example #16
0
    def __init__(self, host = None, port = None):
        RemoteObject.__init__ (self)
        
        log.info("Starting manager.")

        self.resources = ResourcesManager()
        self.classLoader = ClassLoader()

        # identity
        self.setGUID(MANAGER_LOCATION)

        # shutdown event
        self.died = threading.Event()

        # our daemon server
        self.adapter = ManagerAdapter (self, host, port)
        self.adapterThread = threading.Thread(target=self.adapter.requestLoop)
        self.adapterThread.setDaemon(True)
        self.adapterThread.start()

        # register ourselves
        self.resources.add(MANAGER_LOCATION, self, getManagerURI(self.getHostname(), self.getPort()))
Example #17
0
    def __init__(self, host=None, port=None):
        RemoteObject.__init__(self)

        log.info("Starting manager.")

        self.resources = ResourcesManager()
        self.classLoader = ClassLoader()

        # identity
        self.setGUID(MANAGER_LOCATION)

        # shutdown event
        self.died = threading.Event()

        # our daemon server
        self.adapter = ManagerAdapter(self, host, port)
        self.adapterThread = threading.Thread(target=self.adapter.requestLoop)
        self.adapterThread.setDaemon(True)
        self.adapterThread.start()

        # register ourself
        self.resources.add(MANAGER_LOCATION, self,
                           getManagerURI(self.getHostname(), self.getPort()))
Example #18
0
                self.manager = Manager(**self.config.chimera)
            except ChimeraException, e:
                log.error("Chimera is already running on this machine. Use chimera-admin to manage it.")
                sys.exit(1)

            log.info("Chimera: running on "+ self.manager.getHostname() + ":" + str(self.manager.getPort()))
            log.info("Chimera: reading configuration from %s" % os.path.realpath(self.options.config_file))

        # add site object
        if not self.options.dry:
            
            for site in self.config.sites:
                self.manager.addClass(Site, site.name, site.config, True)
            
        # search paths
        log.info("Setting objects include path from command line parameters...")
        for _dir in self.options.inst_dir:
            self.paths["instruments"].append(_dir)
    
        for _dir in self.options.ctrl_dir:
            self.paths["controllers"].append(_dir)
        
        # init from config
        log.info("Trying to start instruments...")
        for inst in self.config.instruments + self.options.instruments:
            
            if self.options.dry:
                print inst
            else:
                self._add(inst, path=self.paths["instruments"], start=True)
Example #19
0
	def addObservation(self,target,obstime):
	
		session = Session()
		
		lineRe = re.compile('(?P<coord>(?P<ra>[\d:-]+)\s+(?P<dec>\+?[\d:-]+)\s+(?P<epoch>[\dnowNOWJjBb\.]+)\s+)?(?P<imagetype>[\w]+)'
                            '\s+(?P<objname>\'([^\\n\'\\\\]|\\\\.)*\'|"([^\\n"\\\\]|\\\\.)*"|([^ \\n"\\\\]|\\\\.)*)\s+(?P<exposures>[\w\d\s:\*\(\),]*)')
		programs = []
		
		entryFormat = '%(ra)s %(dec)s %(epoch)s %(obstype)s %(name)s %(exposures)s'
		
		p = Position.fromRaDec(target.targetRa,target.targetDec)
		ra = p.ra.HMS
		dec = p.dec.DMS
		
		filterExpt = self.sciExpTime
		if target.type == self.stdFlag:
			filterExpt = self.stdExpTime

		exposures = '1*('

		for i in range(self.nfilters):
			exposures = exposures+'%s:%.0f, '%(self.filters[i],filterExpt[i])

		exposures = exposures[:-2]
		exposures += ')'
		
		infos = {	'ra' : '%02.0f:%02.0f:%02.0f'%(ra[1],ra[2],ra[3]),
					'dec': '%+03.0f:%02.0f:%02.0f'%(dec[0]*dec[1],dec[2],dec[3]),
					'epoch' : 'J%.0f'%target.targetEpoch,
					'obstype' : 'OBJECT',
					'name' :target.name,
					'exposures' : exposures
					}

		i = 0
		line = entryFormat%infos
		
		matchs = lineRe.search(line)
		params = matchs.groupdict()
		
		position = None
		objname  = None

		if params.get("coord", None):
			position  = Position.fromRaDec(str(params['ra']), str(params['dec']), params['epoch'])

		imagetype = params['imagetype'].upper()
		objname   = params['objname'].replace("\"", "")

		multiplier, exps = params['exposures'].split("*")
		try:
			multiplier = int(multiplier)
		except ValueError:
			multiplier = 1

		exps = exps.replace("(", "").replace(")", "").strip().split(",")

		mjd = obstime - 2400000.5
		for i in range(multiplier):

			program = Program(tid = target.id ,name="%s-%03d" % (objname.replace(" ", ""), i),
                              slewAt=mjd,exposeAt=mjd+1./60./24.)

			log.info("# program: %s" % program.name)

			if imagetype == "OBJECT":
				if position:
					program.actions.append(Point(targetRaDec=position))
				else:
					program.actions.append(Point(targetName=objname))

			if imagetype == "FLAT":
				site = self._remoteManager.getProxy("/Site/0")
				flatPosition = Position.fromAltAz(site['flat_alt'], site['flat_az'])
				program.actions.append(Point(targetAltAz=flatPosition))

			#if i == 0:
			#    program.actions.append(AutoFocus(start=1500, end=3000, step=250, filter="R", exptime=10))
			#    program.actions.append(PointVerify(here=True))

			for exp in exps:
				if exp.count(":") > 1:
					filter, exptime, frames = exp.strip().split(":")
				else:
					filter, exptime = exp.strip().split(":")
					frames = 1

				if imagetype in ("OBJECT", "FLAT"):
					shutter = "OPEN"
				else:
					shutter = "CLOSE"

				if imagetype == "BIAS":
					exptime = 0

				if imagetype in ("BIAS", "DARK"):
					filter = None

				log.info("%s %s %s filter=%s exptime=%s frames=%s" % (imagetype, objname, str(position), filter, exptime, frames))

				program.actions.append(Expose(shutter=shutter,
											  filename="%s-$DATE-$TIME" % objname.replace(" ", ""),
											  filter=filter,
											  frames=frames,
											  exptime=exptime,
											  imageType=imagetype,
											  objectName=objname))
			log.info("")
			programs.append(program)

		session.add_all(programs)
		session.commit()
Example #20
0
                )
                sys.exit(1)

            log.info("Chimera: running on " + self.manager.getHostname() +
                     ":" + str(self.manager.getPort()))
            log.info("Chimera: reading configuration from %s" %
                     os.path.realpath(self.options.config_file))

        # add site object
        if not self.options.dry:

            for site in self.config.sites:
                self.manager.addClass(Site, site.name, site.config, True)

        # search paths
        log.info(
            "Setting objects include path from command line parameters...")
        for _dir in self.options.inst_dir:
            self.paths["instruments"].append(_dir)

        for _dir in self.options.ctrl_dir:
            self.paths["controllers"].append(_dir)

        # init from config
        log.info("Trying to start instruments...")
        for inst in self.config.instruments + self.options.instruments:

            if self.options.dry:
                print inst
            else:
                self._add(inst, path=self.paths["instruments"], start=True)
Example #21
0
    def startup(self):

        if self.options.daemon:
            # detach
            log.info("FIXME: Daemon...")

        # system config
        try:
            self.config = SystemConfig.fromFile(self.options.config_file)
        except (InvalidLocationException, IOError) as e:
            log.exception(e)
            log.error(
                "There was a problem reading your configuration file. (%s)" %
                e)
            sys.exit(1)

        # manager
        if not self.options.dry:
            log.info("Starting system.")
            log.info("Chimera: %s" % _chimera_version_)
            log.info("Chimera prefix: %s" % ChimeraPath().root())
            log.info("Python: %s" % platform.python_version())
            log.info("System: %s" % ' '.join(platform.uname()))

            try:
                self.manager = Manager(**self.config.chimera)
            except ChimeraException as e:
                log.error(
                    "Chimera is already running on this machine. Use chimera-admin to manage it."
                )
                sys.exit(1)

            log.info("Chimera: running on " + self.manager.getHostname() +
                     ":" + str(self.manager.getPort()))
            log.info("Chimera: reading configuration from %s" %
                     os.path.realpath(self.options.config_file))

        # add site object
        if not self.options.dry:

            for site in self.config.sites:
                self.manager.addClass(Site, site.name, site.config, True)

        # search paths
        log.info(
            "Setting objects include path from command line parameters...")
        for _dir in self.options.inst_dir:
            self.paths["instruments"].append(_dir)

        for _dir in self.options.ctrl_dir:
            self.paths["controllers"].append(_dir)

        # init from config
        log.info("Trying to start instruments...")
        for inst in self.config.instruments + self.options.instruments:

            if self.options.dry:
                print(inst)
            else:
                self._add(inst, path=self.paths["instruments"], start=True)

        log.info("Trying to start controllers...")
        for ctrl in self.config.controllers + self.options.controllers:

            if self.options.dry:
                print(ctrl)
            else:
                self._add(ctrl, path=self.paths["controllers"], start=True)

        log.info("System up and running.")

        # ok, let's wait manager work
        if self.wait and not self.options.dry:
            self.manager.wait()
Example #22
0
 def shutdown(self):
     log.info("Shutting down system.")
     self.manager.shutdown()
Example #23
0
    def selectStandardTargets(self, nstars=3, nairmass=3):
        '''
		Based on configuration parameters, select 'nstars' standard stars to run scheduler on a specified Julian Day. Ideally you 
		will select standard stars before your science targets so not to have a full queue. Usually standard stars are observed 
		more than once a night at different airmasses. The user can control this parameter with nairmass and the script will try
		to take care of the rest. 
		'''

        session = Session()

        # First of all, standard stars can be obsered multiple times in sucessive nights. I will mark all
        # stars an unscheduled.
        targets = session.query(Targets).filter(
            Targets.scheduled == True).filter(Targets.type == self.stdFlag)
        for target in targets:
            target.scheduled = False
            session.commit()

        # [To be done] Reject objects that are close to the moon

        # Selecting standard stars is not only searching for the higher in that time but select stars than can be observed at 3
        # or more (nairmass) different airmasses. It is also important to select stars with different colors (but this will be
        # taken care in the future).

        if nairmass * nstars > len(self.obsTimeBins):
            log.warning(
                'Requesting more stars/observations than it will be possible to schedule. Decreasing number of requests to fit in the night.'
            )
            nstars = len(self.obsTimeBins) / nairmass

        obsStandars = np.zeros(len(
            self.obsTimeBins)) - 1  # first selection of observable standards

        for tbin, time in enumerate(self.obsTimeBins):

            if self.obsTimeMask[tbin] < 1.0:
                # 1 - Select objects from database that where not scheduled yet (standard stars may be repited)
                #     that fits our observing night
                targets = session.query(Targets).filter(
                    Targets.scheduled == 0).filter(
                        Targets.type == self.stdFlag)

                lst = _skysub.lst(time, self.sitelong)  #*360./24.
                alt = np.array([
                    _skysub.altit(target.targetDec, lst - target.targetRa,
                                  self.sitelat)[0] for target in targets
                ])
                stg = alt.argmax()

                log.info('Selecting %s' % (targets[stg]))

                # Marking target as schedule
                tst = session.query(Targets).filter(
                    Targets.id == targets[stg].id)

                for t in tst:
                    t.scheduled = True
                    session.commit()
                    obsStandars[tbin] = t.id

            else:
                log.info(
                    'Bin already filled up with observations. Skipping...')

        if len(obsStandars[obsStandars >= 0]) < nstars:
            log.warning(
                'Could not find %i suitable standard stars in catalog. Only %i where found.'
                % (nstars, len(obsStandars[obsStandars >= 0])))
        #
        # Unmarking potential targets as scheduled
        #
        for id in obsStandars[obsStandars >= 0]:
            target = session.query(Targets).filter(Targets.id == id)
            for t in target:
                t.scheduled = False
                session.commit()

            tbin += 1
        #
        # Preparing a grid of altitudes for each target for each observing window
        #
        amGrid = np.zeros(len(obsStandars) * len(obsStandars)).reshape(
            len(obsStandars), len(obsStandars))

        for i in np.arange(len(obsStandars))[obsStandars >= 0]:
            target = session.query(Targets).filter(
                Targets.id == obsStandars[i])[0]
            for j in range(len(obsStandars)):
                lst = _skysub.lst(self.obsTimeBins[j], self.sitelong)
                amGrid[i][j] = _skysub.true_airmass(
                    _skysub.secant_z(
                        _skysub.altit(target.targetDec, lst - target.targetRa,
                                      self.sitelat)[0]))
                if amGrid[i][j] < 0:
                    amGrid[i][j] = 99.
        #
        # Build a grid mask that specifies the position in time each target should be observed. This means that, when
        # selecting a single target we ocuppy more than one, non consecutive, position in the night. This grid shows where are these
        # positions.
        #
        obsMask = np.zeros(len(obsStandars) * len(obsStandars),
                           dtype=np.bool).reshape(len(obsStandars),
                                                  len(obsStandars))

        for i in np.arange(len(obsStandars))[obsStandars >= 0]:
            amObs = np.linspace(amGrid[i].min(), self.stdMaxAirmass,
                                nairmass)  # requested aimasses
            dam = np.mean(
                np.abs(amGrid[i][amGrid[i] < self.stdMaxAirmass][1:] -
                       amGrid[i][amGrid[i] < self.stdMaxAirmass][:-1])
            )  # how much airmass changes in average
            for j, am in enumerate(amObs):
                # Mark positions where target is at	specified airmass
                if j == 0:
                    obsMask[i] = np.bitwise_or(obsMask[i], amGrid[i] == am)
                else:
                    obsMask[i] = np.bitwise_or(
                        obsMask[i],
                        np.bitwise_and(amGrid[i] > am - dam,
                                       amGrid[i] < am + dam))

            #print amGrid[i][np.where(obsMask[i])]
        #
        # Now it is time to actually select the targets. It will start with the first target and then try the others
        # until it find enough standard stars, as specified by the user.
        #
        # Para cada bin em tempo, varro o bin em massa de ar por coisas observaveis. Se acho um, vejo se posso agendar
        # os outros bins. Se sim, marco o alvo para observacao, se nao, passo para o proximo. Repito ate completar a
        # lista de alvos
        #

        obsMaskTimeGrid = np.zeros(len(obsStandars), dtype=np.bool)
        nrequests = 0
        reqId = np.zeros(nstars, dtype=np.int) - 1
        for tbin, time in enumerate(self.obsTimeBins[:-1]):
            # Evaluates if time slots are all available. If yes, mark orbservation and ocuppy slots.
            if ((not obsMaskTimeGrid[obsMask[tbin]].any())
                    and (len(amGrid[tbin][obsMask[tbin]]) >= nairmass)):
                obsMaskTimeGrid = np.bitwise_or(obsMaskTimeGrid, obsMask[tbin])
                reqId[nrequests] = tbin
                nrequests += 1
            if nrequests >= nstars:
                break

        # Finally, requesting observations

        for id in reqId[reqId >= 0]:
            target = session.query(Targets).filter(
                Targets.id == obsStandars[id])[0]
            secz = amGrid[id][obsMask[id]]
            seczreq = np.zeros(nairmass, dtype=np.bool)
            amObs = np.linspace(amGrid[id].min(), self.stdMaxAirmass,
                                nairmass)  # requested aimasses
            for i, obstime in enumerate(self.obsTimeBins[obsMask[id]]):
                sindex = np.abs(amObs - secz[i]).argmin()
                if not seczreq[sindex]:
                    log.info(
                        'Requesting observations of %s @airmass=%4.2f @mjd=%.3f...'
                        % (target.name, secz[i], obstime - 2400000.5))
                    seczreq[sindex] = True
                    target.scheduled = True
                    session.commit()
                    self.addObservation(target, obstime)
                    self.obsTimeMask[obsMask[id]] = 1.0
            #print self.obsTimeBins[obsMask[id]]
            #print

        #print i
        return 0  #targets
Example #24
0
 def shutdown(self):
     log.info("Shutting down system.")
     self.manager.shutdown()
Example #25
0
	def selectStandardTargets(self,nstars=3,nairmass=3):
		'''
		Based on configuration parameters, select 'nstars' standard stars to run scheduler on a specified Julian Day. Ideally you 
		will select standard stars before your science targets so not to have a full queue. Usually standard stars are observed 
		more than once a night at different airmasses. The user can control this parameter with nairmass and the script will try
		to take care of the rest. 
		'''

		session = Session()
		
		# First of all, standard stars can be obsered multiple times in sucessive nights. I will mark all
		# stars an unscheduled.
		targets = session.query(Targets).filter(Targets.scheduled == True).filter(Targets.type == self.stdFlag)
		for target in targets:
			target.scheduled = False
			session.commit()
		
		# [To be done] Reject objects that are close to the moon

		# Selecting standard stars is not only searching for the higher in that time but select stars than can be observed at 3
		# or more (nairmass) different airmasses. It is also important to select stars with different colors (but this will be
		# taken care in the future).

		if nairmass*nstars > len(self.obsTimeBins):
			log.warning('Requesting more stars/observations than it will be possible to schedule. Decreasing number of requests to fit in the night.')
			nstars = len(self.obsTimeBins)/nairmass

		obsStandars = np.zeros(len(self.obsTimeBins))-1 # first selection of observable standards

		for tbin,time in enumerate(self.obsTimeBins):

			if self.obsTimeMask[tbin] < 1.0:
				# 1 - Select objects from database that where not scheduled yet (standard stars may be repited)
				#     that fits our observing night
				targets = session.query(Targets).filter(Targets.scheduled == 0).filter(Targets.type == self.stdFlag)
			
				lst = _skysub.lst(time,self.sitelong) #*360./24.
				alt = np.array([_skysub.altit(target.targetDec,lst - target.targetRa,self.sitelat)[0] for target in targets])
				stg = alt.argmax()

				log.info('Selecting %s'%(targets[stg]))
				
				# Marking target as schedule
				tst = session.query(Targets).filter(Targets.id == targets[stg].id)

				for t in tst:
					t.scheduled = True
					session.commit()
					obsStandars[tbin] = t.id
				
			else:
				log.info('Bin already filled up with observations. Skipping...')

		if len(obsStandars[obsStandars >= 0]) < nstars:
			log.warning('Could not find %i suitable standard stars in catalog. Only %i where found.'%(nstars,len(obsStandars[obsStandars >= 0])))
		#
		# Unmarking potential targets as scheduled
		#
		for id in obsStandars[obsStandars >= 0]:
			target = session.query(Targets).filter(Targets.id == id)
			for t in target:
				t.scheduled = False
				session.commit()
				
			tbin+=1
		#
		# Preparing a grid of altitudes for each target for each observing window
		#
		amGrid = np.zeros(len(obsStandars)*len(obsStandars)).reshape(len(obsStandars),len(obsStandars))

		for i in np.arange(len(obsStandars))[obsStandars >= 0]:
			target = session.query(Targets).filter(Targets.id == obsStandars[i])[0]
			for j in range(len(obsStandars)):
				lst = _skysub.lst(self.obsTimeBins[j],self.sitelong)
				amGrid[i][j] = _skysub.true_airmass(_skysub.secant_z(_skysub.altit(target.targetDec,lst - target.targetRa,self.sitelat)[0]))
				if amGrid[i][j] < 0:
					amGrid [i][j] = 99.
		#
		# Build a grid mask that specifies the position in time each target should be observed. This means that, when
		# selecting a single target we ocuppy more than one, non consecutive, position in the night. This grid shows where are these
		# positions.
		#
		obsMask = np.zeros(len(obsStandars)*len(obsStandars),dtype=np.bool).reshape(len(obsStandars),len(obsStandars))

		for i in np.arange(len(obsStandars))[obsStandars >= 0]:
			amObs = np.linspace(amGrid[i].min(),self.stdMaxAirmass,nairmass) # requested aimasses
			dam = np.mean(np.abs(amGrid[i][amGrid[i]<self.stdMaxAirmass][1:] - amGrid[i][amGrid[i]<self.stdMaxAirmass][:-1])) # how much airmass changes in average
			for j,am in enumerate(amObs):
				# Mark positions where target is at	specified airmass
				if j == 0:
					obsMask[i] = np.bitwise_or(obsMask[i],amGrid[i] == am)
				else:
					obsMask[i] = np.bitwise_or(obsMask[i],np.bitwise_and(amGrid[i]>am-dam,amGrid[i]<am+dam))

			#print amGrid[i][np.where(obsMask[i])]
		#
		# Now it is time to actually select the targets. It will start with the first target and then try the others
		# until it find enough standard stars, as specified by the user.
		#
		# Para cada bin em tempo, varro o bin em massa de ar por coisas observaveis. Se acho um, vejo se posso agendar
		# os outros bins. Se sim, marco o alvo para observacao, se nao, passo para o proximo. Repito ate completar a
		# lista de alvos
		#

		obsMaskTimeGrid = np.zeros(len(obsStandars),dtype=np.bool)
		nrequests = 0
		reqId = np.zeros(nstars,dtype=np.int)-1
		for tbin,time in enumerate(self.obsTimeBins[:-1]):
			# Evaluates if time slots are all available. If yes, mark orbservation and ocuppy slots.
			if ( (not obsMaskTimeGrid[obsMask[tbin]].any()) and (len(amGrid[tbin][obsMask[tbin]])>=nairmass) ):
				obsMaskTimeGrid = np.bitwise_or(obsMaskTimeGrid,obsMask[tbin])
				reqId[nrequests] = tbin
				nrequests += 1
			if nrequests >= nstars:
				break

		# Finally, requesting observations

		for id in reqId[reqId >= 0]:
			target = session.query(Targets).filter(Targets.id == obsStandars[id])[0]
			secz = amGrid[id][obsMask[id]]
			seczreq = np.zeros(nairmass,dtype=np.bool)
			amObs = np.linspace(amGrid[id].min(),self.stdMaxAirmass,nairmass) # requested aimasses
			for i,obstime in enumerate(self.obsTimeBins[obsMask[id]]):
				sindex = np.abs(amObs-secz[i]).argmin()
				if not seczreq[sindex]:
					log.info('Requesting observations of %s @airmass=%4.2f @mjd=%.3f...'%(target.name,secz[i],obstime-2400000.5))
					seczreq[sindex] = True
					target.scheduled = True
					session.commit()
					self.addObservation(target,obstime)
					self.obsTimeMask[obsMask[id]] = 1.0
			#print self.obsTimeBins[obsMask[id]]
			#print

		#print i
		return 0 #targets
Example #26
0
class SiteController(object):
    def __init__(self, args=[], wait=True):

        self.wait = wait

        self.options, self.args = self.parseArgs(args)

        if self.options.verbose == 1:
            chimera.core.log.setConsoleLevel(logging.INFO)

        if self.options.verbose > 1:
            chimera.core.log.setConsoleLevel(logging.DEBUG)

        self.manager = None

        self.paths = {"instruments": [], "controllers": [], "drivers": []}

        # add system path
        self.paths["instruments"].append(ChimeraPath.instruments())
        self.paths["controllers"].append(ChimeraPath.controllers())
        self.paths["drivers"].append(ChimeraPath.drivers())

    def parseArgs(self, args):
        def check_location(option, opt_str, value, parser):
            try:
                l = Location(value)
            except InvalidLocationException:
                raise optparse.OptionValueError("%s isnt't a valid location." %
                                                value)

            eval('parser.values.%s.append ("%s")' % (option.dest, value))

        def check_includepath(option, opt_str, value, parser):

            if not value or not os.path.isdir(os.path.abspath(value)):
                raise optparse.OptionValueError(
                    "Couldn't found %s include path." % value)

            eval('parser.values.%s.append ("%s")' % (option.dest, value))

        parser = optparse.OptionParser(
            prog="chimera",
            version=find_dev_version() or _chimera_version_,
            description=_chimera_description_,
            usage="chimera --help for more information")

        manag_group = optparse.OptionGroup(parser, "Basic options")
        manag_group.add_option(
            "-H",
            "--host",
            action="store",
            dest="pyro_host",
            type="string",
            help="Host name/IP address to run as; [default=%default]",
            metavar="HOST")

        manag_group.add_option(
            "-P",
            "--port",
            action="store",
            dest="pyro_port",
            type="string",
            help="Port on which to listen for requests; [default=%default]",
            metavar="PORT")

        config_group = optparse.OptionGroup(parser, "Configuration")

        config_group.add_option(
            "--config",
            dest="config_file",
            help="Start Chimera using configuration from FILE.",
            metavar="FILE")

        config_group.add_option("--skip-global",
                                action="store_false",
                                dest="use_global",
                                help="Don't use global coniguration file.")

        config_group.add_option(
            "--daemon",
            action="store_true",
            dest='daemon',
            help=
            "Run Chimera in Daemon mode (will detach from current terminal).")

        misc_group = optparse.OptionGroup(parser, "General")

        misc_group.add_option(
            "--dry-run",
            action="store_true",
            dest="dry",
            help=
            "Only list all configured objects (from command line and configuration files) without starting the system."
        )

        misc_group.add_option(
            "-v",
            "--verbose",
            action="count",
            dest='verbose',
            help="Increase log level (multiple v's to increase even more).")

        inst_group = optparse.OptionGroup(
            parser, "Instruments, Controllers and Drivers Management")

        inst_group.add_option(
            "-i",
            "--instrument",
            action="callback",
            callback=check_location,
            dest="instruments",
            type="string",
            help="Load the instrument defined by LOCATION."
            "This option could be setted many times to load multiple instruments.",
            metavar="LOCATION")

        inst_group.add_option(
            "-c",
            "--controller",
            action="callback",
            callback=check_location,
            dest="controllers",
            type="string",
            help="Load the controller defined by LOCATION."
            "This option could be setted many times to load multiple controllers.",
            metavar="LOCATION")

        inst_group.add_option(
            "-d",
            "--driver",
            action="callback",
            callback=check_location,
            dest="drivers",
            type="string",
            help="Load the driver defined by LOCATION."
            "This option could be setted many times to load multiple drivers.",
            metavar="LOCATION")

        inst_group.add_option("-I",
                              "--instruments-dir",
                              action="callback",
                              callback=check_includepath,
                              dest="inst_dir",
                              type="string",
                              help="Append PATH to instruments load path.",
                              metavar="PATH")

        inst_group.add_option("-C",
                              "--controllers-dir",
                              action="callback",
                              callback=check_includepath,
                              dest="ctrl_dir",
                              type="string",
                              help="Append PATH to controllers load path.",
                              metavar="PATH")

        inst_group.add_option("-D",
                              "--drivers-dir",
                              action="callback",
                              callback=check_includepath,
                              dest="drv_dir",
                              type="string",
                              help="Append PATH to drivers load path.",
                              metavar="PATH")

        parser.add_option_group(manag_group)
        parser.add_option_group(config_group)
        parser.add_option_group(misc_group)
        parser.add_option_group(inst_group)

        parser.set_defaults(instruments=[],
                            controllers=[],
                            drivers=[],
                            config_file=SYSTEM_CONFIG_DEFAULT_FILENAME,
                            inst_dir=[],
                            ctrl_dir=[],
                            drv_dir=[],
                            dry=False,
                            use_global=True,
                            verbose=0,
                            daemon=False,
                            pyro_host=MANAGER_DEFAULT_HOST,
                            pyro_port=MANAGER_DEFAULT_PORT)

        return parser.parse_args(args)

    def startup(self):

        if self.options.daemon:
            # detach
            log.info("FIXME: Daemon...")

        # system config
        self.config = SystemConfig.fromFile(self.options.config_file,
                                            self.options.use_global)

        # manager
        if not self.options.dry:
            log.info("Starting system.")
            log.info("Chimera version: %s" % find_dev_version()
                     or _chimera_version_)
            log.info("Chimera prefix: %s" % ChimeraPath.root())

            try:
                self.manager = Manager(**self.config.chimera)
            except ChimeraException, e:
                log.error(
                    "Chimera is already running on this machine. Use chimera-admin to manage it."
                )
                sys.exit(1)

            log.info("Chimera: running on " + self.manager.getHostname() +
                     ":" + str(self.manager.getPort()))
            if self.options.use_global:
                log.info("Chimera: reading configuration from %s" %
                         SYSTEM_CONFIG_DEFAULT_GLOBAL)
            log.info("Chimera: reading configuration from %s" %
                     os.path.realpath(self.options.config_file))

        # add site object
        if not self.options.dry:

            for site in self.config.sites:
                self.manager.addClass(Site, site.name, site.config, True)

        # search paths
        log.info(
            "Setting objects include path from command line parameters...")
        for _dir in self.options.inst_dir:
            self.paths["instruments"].append(_dir)

        for _dir in self.options.ctrl_dir:
            self.paths["controllers"].append(_dir)

        for _dir in self.options.drv_dir:
            self.paths["drivers"].append(_dir)

        # init from config
        log.info("Trying to start drivers...")
        for drv in self.config.drivers + self.options.drivers:

            if self.options.dry:
                print drv
            else:
                self._add(drv, path=self.paths["drivers"], start=True)

        log.info("Trying to start instruments...")
        for inst in self.config.instruments + self.options.instruments:

            if self.options.dry:
                print inst
            else:
                self._add(inst, path=self.paths["instruments"], start=True)

        log.info("Trying to start controllers...")
        for ctrl in self.config.controllers + self.options.controllers:

            if self.options.dry:
                print ctrl
            else:
                self._add(ctrl, path=self.paths["controllers"], start=True)

        log.info("System up and running.")

        # ok, let's wait manager work
        if self.wait and not self.options.dry:
            self.manager.wait()
Example #27
0
    def startup(self):

        if self.options.daemon:
            # detach
            log.info("FIXME: Daemon...")

        # system config
        self.config = SystemConfig.fromFile(self.options.config_file,
                                            self.options.use_global)

        # manager
        if not self.options.dry:
            log.info("Starting system.")
            log.info("Chimera version: %s" % find_dev_version()
                     or _chimera_version_)
            log.info("Chimera prefix: %s" % ChimeraPath.root())

            try:
                self.manager = Manager(**self.config.chimera)
            except ChimeraException, e:
                log.error(
                    "Chimera is already running on this machine. Use chimera-admin to manage it."
                )
                sys.exit(1)

            log.info("Chimera: running on " + self.manager.getHostname() +
                     ":" + str(self.manager.getPort()))
            if self.options.use_global:
                log.info("Chimera: reading configuration from %s" %
                         SYSTEM_CONFIG_DEFAULT_GLOBAL)
            log.info("Chimera: reading configuration from %s" %
                     os.path.realpath(self.options.config_file))
Example #28
0
class SiteController(object):
    def __init__(self, args=[], wait=True):

        self.wait = wait

        self.options, self.args = self.parseArgs(args)

        if self.options.verbose == 1:
            chimera.core.log.setConsoleLevel(logging.INFO)
            #log.setConsoleLevel(logging.INFO)

        if self.options.verbose > 1:
            chimera.core.log.setConsoleLevel(logging.DEBUG)
            #log.setConsoleLevel(logging.DEBUG)

        self.manager = None

        self.paths = {"instruments": [], "controllers": []}

        # add system and plugins paths
        Path = ChimeraPath()
        self.paths["instruments"].extend(Path.instruments)
        self.paths["controllers"].extend(Path.controllers)

    def parseArgs(self, args):
        def check_location(option, opt_str, value, parser):
            try:
                l = Location(value)
            except InvalidLocationException:
                raise optparse.OptionValueError("%s isnt't a valid location." %
                                                value)

            eval('parser.values.%s.append ("%s")' % (option.dest, value))

        def check_includepath(option, opt_str, value, parser):

            if not value or not os.path.isdir(os.path.abspath(value)):
                raise optparse.OptionValueError(
                    "Couldn't found %s include path." % value)

            eval('parser.values.%s.append ("%s")' % (option.dest, value))

        parser = optparse.OptionParser(
            prog="chimera",
            version=_chimera_version_,
            description=_chimera_description_,
            usage="chimera --help for more information")

        manag_group = optparse.OptionGroup(parser, "Basic options")
        manag_group.add_option(
            "-H",
            "--host",
            action="store",
            dest="pyro_host",
            type="string",
            help="Host name/IP address to run as; [default=%default]",
            metavar="HOST")

        manag_group.add_option(
            "-P",
            "--port",
            action="store",
            dest="pyro_port",
            type="string",
            help="Port on which to listen for requests; [default=%default]",
            metavar="PORT")

        config_group = optparse.OptionGroup(parser, "Configuration")

        config_group.add_option(
            "--config",
            dest="config_file",
            help="Start Chimera using configuration from FILE.",
            metavar="FILE")

        config_group.add_option(
            "--daemon",
            action="store_true",
            dest='daemon',
            help=
            "Run Chimera in Daemon mode (will detach from current terminal).")

        misc_group = optparse.OptionGroup(parser, "General")

        misc_group.add_option(
            "--dry-run",
            action="store_true",
            dest="dry",
            help=
            "Only list all configured objects (from command line and configuration files) without starting the system."
        )

        misc_group.add_option(
            "-v",
            "--verbose",
            action="count",
            dest='verbose',
            help="Increase log level (multiple v's to increase even more).")

        inst_group = optparse.OptionGroup(
            parser, "Instruments and Controllers Management")

        inst_group.add_option(
            "-i",
            "--instrument",
            action="callback",
            callback=check_location,
            dest="instruments",
            type="string",
            help="Load the instrument defined by LOCATION."
            "This option could be set many times to load multiple instruments.",
            metavar="LOCATION")

        inst_group.add_option(
            "-c",
            "--controller",
            action="callback",
            callback=check_location,
            dest="controllers",
            type="string",
            help="Load the controller defined by LOCATION."
            "This option could be set many times to load multiple controllers.",
            metavar="LOCATION")

        inst_group.add_option("-I",
                              "--instruments-dir",
                              action="callback",
                              callback=check_includepath,
                              dest="inst_dir",
                              type="string",
                              help="Append PATH to instruments load path.",
                              metavar="PATH")

        inst_group.add_option("-C",
                              "--controllers-dir",
                              action="callback",
                              callback=check_includepath,
                              dest="ctrl_dir",
                              type="string",
                              help="Append PATH to controllers load path.",
                              metavar="PATH")

        parser.add_option_group(manag_group)
        parser.add_option_group(config_group)
        parser.add_option_group(misc_group)
        parser.add_option_group(inst_group)

        parser.set_defaults(instruments=[],
                            controllers=[],
                            config_file=SYSTEM_CONFIG_DEFAULT_FILENAME,
                            inst_dir=[],
                            ctrl_dir=[],
                            drv_dir=[],
                            dry=False,
                            verbose=0,
                            daemon=False,
                            pyro_host=MANAGER_DEFAULT_HOST,
                            pyro_port=MANAGER_DEFAULT_PORT)

        return parser.parse_args(args)

    def startup(self):

        if self.options.daemon:
            # detach
            log.info("FIXME: Daemon...")

        # system config
        try:
            self.config = SystemConfig.fromFile(self.options.config_file)
        except (InvalidLocationException, IOError), e:
            log.exception(e)
            log.error(
                "There was a problem reading your configuration file. (%s)" %
                e)
            sys.exit(1)

        # manager
        if not self.options.dry:
            log.info("Starting system.")
            log.info("Chimera: %s" % _chimera_version_)
            log.info("Chimera prefix: %s" % ChimeraPath().root())
            log.info("Python: %s" % platform.python_version())
            log.info("System: %s" % ' '.join(platform.uname()))

            try:
                self.manager = Manager(**self.config.chimera)
            except ChimeraException, e:
                log.error(
                    "Chimera is already running on this machine. Use chimera-admin to manage it."
                )
                sys.exit(1)

            log.info("Chimera: running on " + self.manager.getHostname() +
                     ":" + str(self.manager.getPort()))
            log.info("Chimera: reading configuration from %s" %
                     os.path.realpath(self.options.config_file))
Example #29
0
    def addObservation(self, target, obstime):

        session = Session()

        lineRe = re.compile(
            '(?P<coord>(?P<ra>[\d:-]+)\s+(?P<dec>\+?[\d:-]+)\s+(?P<epoch>[\dnowNOWJjBb\.]+)\s+)?(?P<imagetype>[\w]+)'
            '\s+(?P<objname>\'([^\\n\'\\\\]|\\\\.)*\'|"([^\\n"\\\\]|\\\\.)*"|([^ \\n"\\\\]|\\\\.)*)\s+(?P<exposures>[\w\d\s:\*\(\),]*)'
        )
        programs = []

        entryFormat = '%(ra)s %(dec)s %(epoch)s %(obstype)s %(name)s %(exposures)s'

        p = Position.fromRaDec(target.targetRa, target.targetDec)
        ra = p.ra.HMS
        dec = p.dec.DMS

        filterExpt = self.sciExpTime
        if target.type == self.stdFlag:
            filterExpt = self.stdExpTime

        exposures = '1*('

        for i in range(self.nfilters):
            exposures = exposures + '%s:%.0f, ' % (self.filters[i],
                                                   filterExpt[i])

        exposures = exposures[:-2]
        exposures += ')'

        infos = {
            'ra': '%02.0f:%02.0f:%02.0f' % (ra[1], ra[2], ra[3]),
            'dec': '%+03.0f:%02.0f:%02.0f' % (dec[0] * dec[1], dec[2], dec[3]),
            'epoch': 'J%.0f' % target.targetEpoch,
            'obstype': 'OBJECT',
            'name': target.name,
            'exposures': exposures
        }

        i = 0
        line = entryFormat % infos

        matchs = lineRe.search(line)
        params = matchs.groupdict()

        position = None
        objname = None

        if params.get("coord", None):
            position = Position.fromRaDec(str(params['ra']),
                                          str(params['dec']), params['epoch'])

        imagetype = params['imagetype'].upper()
        objname = params['objname'].replace("\"", "")

        multiplier, exps = params['exposures'].split("*")
        try:
            multiplier = int(multiplier)
        except ValueError:
            multiplier = 1

        exps = exps.replace("(", "").replace(")", "").strip().split(",")

        mjd = obstime - 2400000.5
        for i in range(multiplier):

            program = Program(tid=target.id,
                              name="%s-%03d" % (objname.replace(" ", ""), i),
                              slewAt=mjd,
                              exposeAt=mjd + 1. / 60. / 24.)

            log.info("# program: %s" % program.name)

            if imagetype == "OBJECT":
                if position:
                    program.actions.append(Point(targetRaDec=position))
                else:
                    program.actions.append(Point(targetName=objname))

            if imagetype == "FLAT":
                site = self._remoteManager.getProxy("/Site/0")
                flatPosition = Position.fromAltAz(site['flat_alt'],
                                                  site['flat_az'])
                program.actions.append(Point(targetAltAz=flatPosition))

            #if i == 0:
            #    program.actions.append(AutoFocus(start=1500, end=3000, step=250, filter="R", exptime=10))
            #    program.actions.append(PointVerify(here=True))

            for exp in exps:
                if exp.count(":") > 1:
                    filter, exptime, frames = exp.strip().split(":")
                else:
                    filter, exptime = exp.strip().split(":")
                    frames = 1

                if imagetype in ("OBJECT", "FLAT"):
                    shutter = "OPEN"
                else:
                    shutter = "CLOSE"

                if imagetype == "BIAS":
                    exptime = 0

                if imagetype in ("BIAS", "DARK"):
                    filter = None

                log.info("%s %s %s filter=%s exptime=%s frames=%s" %
                         (imagetype, objname, str(position), filter, exptime,
                          frames))

                program.actions.append(
                    Expose(shutter=shutter,
                           filename="%s-$DATE-$TIME" %
                           objname.replace(" ", ""),
                           filter=filter,
                           frames=frames,
                           exptime=exptime,
                           imageType=imagetype,
                           objectName=objname))
            log.info("")
            programs.append(program)

        session.add_all(programs)
        session.commit()