Example #1
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))
    def __init__(self, manager, host=None, port=None):

        Pyro.core.initServer(banner=False)

        try:
            Pyro.core.Daemon.__init__(
                self, host=host or MANAGER_DEFAULT_HOST, port=port or MANAGER_DEFAULT_PORT, norange=0
            )
        except Pyro.errors.DaemonError, e:
            log.error("Couldn't start Chimera server. Check errors below.")
            raise
Example #3
0
    def __init__(self, manager, host=None, port=None):

        Pyro.core.initServer(banner=False)

        try:
            Pyro.core.Daemon.__init__(self,
                                      host=host or MANAGER_DEFAULT_HOST,
                                      port=port or MANAGER_DEFAULT_PORT,
                                      norange=0)
        except Pyro.errors.DaemonError, e:
            log.error("Couldn't start Chimera server. Check errors below.")
            raise
Example #4
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 #5
0
    def _injectInstrument(self, handler):
        if not issubclass(handler, ActionHandler):
            return

        if not hasattr(handler.process, "__requires__"):
            return
        
        for instrument in handler.process.__requires__:
            try:
                setattr(handler, instrument,
                        self.controller.getManager().getProxy(self.controller[instrument]))
            except ObjectNotFoundException, e:
                log.error("No instrument to inject on %s handler" % handler)
Example #6
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 #7
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 #8
0
    def solveField(fullfilename, findstarmethod="astrometry.net"):
        """
        @param: fullfilename entire path to image
        @type: str

        @param: findstarmethod (astrometry.net, sex) 
        @type: str

        Does astrometry to image=fullfilename
        Uses either astrometry.net or sex(tractor) as its star finder

        """

        pathname, filename = os.path.split(fullfilename)
        pathname = pathname + "/"
        basefilename,file_xtn = os.path.splitext(filename)
        # *** enforce .fits extension
        if (file_xtn != ".fits"):
            raise ValueError("File extension must be .fits it was = %s\n" %file_xtn)

        # *** check whether the file exists or not
        if ( os.path.exists(fullfilename) == False ):
            raise IOError("You selected image %s  It does not exist\n" %fullfilename)

        # version 0.23 changed behavior of --overwrite
        # I need to specify an output filename with -o
        outfilename = basefilename + "-out"

        image = Image.fromFile(fullfilename)
        try:
            ra = image["CRVAL1"]    # expects to see this in image
        except:
            raise AstrometryNetException("Need CRVAL1 and CRVAL2 and CD1_1 on header")
        try:
            dec = image["CRVAL2"]
        except:
            raise AstrometryNetException("Need CRVAL1 and CRVAL2 and CD1_1 on header")
        width = image["NAXIS1"]
        height = image["NAXIS2"] 
        radius = 5.0 * abs(image["CD1_1"]) * width
        
        if findstarmethod == "astrometry.net":
            line = "solve-field %s -d 10,20,30,40,50,60,70,80,90,100 --overwrite -o %s --ra %f --dec %f --radius %f"  %(fullfilename, outfilename, ra, dec, radius)
        elif findstarmethod == "sex":
            sexoutfilename = pathname + outfilename + ".xyls"
            line = "solve-field %s  -d 10,20,30,40,50,60,70,80,90,100 --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d --ra %f --dec %f --radius %f"  %(sexoutfilename, outfilename, width, height, ra, dec, radius)
            # line = "solve-field %s --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d"  %(sexoutfilename, outfilename,width, height)
            # could use --guess-scale for unreliable mounts:
            # line = "solve-field %s --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d --guess-scale"  %(sexoutfilename, outfilename, width, height)

            sex = SExtractor()
            sex.config['BACK_TYPE']   = "AUTO"
            sex.config['DETECT_THRESH'] = 3.0
            sex.config['DETECT_MINAREA'] = 18.0
            sex.config['VERBOSE_TYPE'] = "QUIET"
            sex.config['CATALOG_TYPE'] = "FITS_1.0"
            #sex.config['CATALOG_TYPE'] = "ASCII"
            sex.config['CATALOG_NAME'] = sexoutfilename
            sex.config['PARAMETERS_LIST'] = ["X_IMAGE","Y_IMAGE","MAG_ISO"]
            sex.run(fullfilename)

        else:
            log.error("Unknown option used in astrometry.net")

        # when there is a solution astrometry.net creates a file with .solved
        # added as extension.  
        is_solved = pathname + outfilename + ".solved"
        # if it is already there, make sure to delete it 
        if ( os.path.exists(is_solved)):
            os.remove(is_solved)
	print "SOLVE"  , line
        # *** it would be nice to add a test here to check 
        # whether astrometrynet is running OK, if not raise a new exception 
        # like AstrometryNetInstallProblem
        solve = Popen(line.split()) # ,env=os.environ)
        solve.wait()
        # if solution failed, there will be no file .solved
        if ( os.path.exists(is_solved) == False ):
            raise NoSolutionAstrometryNetException("Astrometry.net could not find a solution for image: %s %s" %(fullfilename, is_solved))

        # wcs_imgname will be the old fits file with the new header
        # wcs_solution is the solve-field solution file
        wcs_imgname = pathname + outfilename + "-wcs" + ".fits"
        wcs_solution = pathname + outfilename + ".wcs"
        shutil.copyfile(wcs_solution,wcs_solution+".fits")
        if ( os.path.exists(wcs_imgname) == True ):
            iraf.imdelete(wcs_imgname)

        # create a separate image with new header
        iraf.artdata()
        iraf.imcopy(fullfilename,wcs_imgname)
        iraf.hedit(wcs_imgname,"CD1_1,CD1_2,CD2_1,CD2_2,CRPIX1,CRPIX2,CRVAL1,CRVAL2,RA,DEC,ALT,AZ",
                   add="no",addonly="no",delete="yes",
                   verify="no",show="no",update="yes")
        iraf.mkheader(images=wcs_imgname,headers=wcs_solution+".fits",
                      append="yes",verbose="no",mode="al")
        return(wcs_imgname)
Example #9
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 #10
0
    def solveField(fullfilename, findstarmethod="astrometry.net"):
        """
        @param: fullfilename entire path to image
        @type: str

        @param: findstarmethod (astrometry.net, sex) 
        @type: str

        Does astrometry to image=fullfilename
        Uses either astrometry.net or sex(tractor) as its star finder

        """

        pathname, filename = os.path.split(fullfilename)
        pathname = pathname + "/"
        basefilename,file_xtn = os.path.splitext(filename)
        # *** enforce .fits extension
        if (file_xtn != ".fits"):
            raise ValueError("File extension must be .fits it was = %s\n" %file_xtn)

        # *** check whether the file exists or not
        if ( os.path.exists(fullfilename) == False ):
            raise IOError("You selected image %s  It does not exist\n" %fullfilename)

        # version 0.23 changed behavior of --overwrite
        # I need to specify an output filename with -o
        outfilename = basefilename + "-out"

        image = Image.fromFile(fullfilename)
        try:
            ra = image["CRVAL1"]    # expects to see this in image
        except:
            raise AstrometryNetException("Need CRVAL1 and CRVAL2 and CD1_1 on header")
        try:
            dec = image["CRVAL2"]
        except:
            raise AstrometryNetException("Need CRVAL1 and CRVAL2 and CD1_1 on header")
        width = image["NAXIS1"]
        height = image["NAXIS2"] 
        radius = 5.0 * abs(image["CD1_1"]) * width

        if findstarmethod == "astrometry.net":
            #line = "solve-field --guess-scale %s --overwrite -o %s" %(fullfilename, outfilename)
            line = "solve-field %s --overwrite -o %s --ra %f --dec %f --radius %f"  %(fullfilename, outfilename, ra, dec, radius)
            print line


        elif findstarmethod == "sex":
            sexoutfilename = pathname + outfilename + ".xyls"
            line = "solve-field %s --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d --ra %f --dec %f --radius %f"  %(sexoutfilename, outfilename, width, height, ra, dec, radius)
            print "Sextractor command line %s" %line
            # using --guess-scale
            # line = "solve-field %s --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d --guess-scale"  %(sexoutfilename, outfilename, width, height)

            sex = SExtractor()
            sex.config['BACK_TYPE']   = "AUTO"
            sex.config['DETECT_THRESH'] = 3.0
            sex.config['DETECT_MINAREA'] = 18.0
            sex.config['VERBOSE_TYPE'] = "QUIET"
            sex.config['CATALOG_TYPE'] = "FITS_1.0"
            #sex.config['CATALOG_TYPE'] = "ASCII"
            sex.config['CATALOG_NAME'] = sexoutfilename
            sex.config['PARAMETERS_LIST'] = ["X_IMAGE","Y_IMAGE","MAG_ISO"]
            sex.run(fullfilename)

        else:
            log.error("Unknown option used in astrometry.net")

        # when there is a solution astrometry.net creates a file with .solved
        # added as extension.  
        is_solved = pathname + outfilename + ".solved"
        # if it is already there, make sure to delete it 
        if ( os.path.exists(is_solved)):
            os.remove(is_solved)
        solve = Popen(line.split()) # ,env=os.environ)
        solve.wait()
        # if solution failed, there will be no file .solved
        if ( os.path.exists(is_solved) == False ):
            raise NoSolutionAstrometryNetException("Astrometry.net could not find a solution for image: %s %s" %(fullfilename, is_solved))

        # wcs_imgname will be the old fits file with the new header
        # wcs_solution is the solve-field solution file
        wcs_imgname = pathname + outfilename + "-wcs" + ".fits"
        wcs_solution = pathname + outfilename + ".wcs"
        shutil.copyfile(wcs_solution,wcs_solution+".fits")
        if ( os.path.exists(wcs_imgname) == True ):
            iraf.imdelete(wcs_imgname)

        # create a separate image with new header
        iraf.artdata()
        iraf.imcopy(fullfilename,wcs_imgname)
        iraf.mkheader(images=wcs_imgname,headers=wcs_solution+".fits",
                      append="no",verbose="no",mode="al")
        return(wcs_imgname)