Exemple #1
0
    def read_parfile(self, parfilename: str = None) -> None:
        """
        Read a parameter file and create sub-dictionaries for saving parameters between sessions.

        Args:
            parfilename: Name of parameter file
        """

        if parfilename is None:
            parfilename = self.par_file
            if parfilename is None:
                azcam.AzcamWarning("Parameter file is not defined")
                return

        self.par_file = parfilename

        if not os.path.exists(parfilename):
            azcam.AzcamWarning(f"Parameter file not found: {parfilename}")
            return

        cp = configparser.ConfigParser()
        cp.read(parfilename)

        sections = cp.sections()

        # sectionname & value case sensitive, name is not
        for sectionname in sections:

            self.par_dict[sectionname] = {}

            for name, value in cp.items(sectionname):
                name = name.lower()
                self.par_dict[sectionname][name] = value

        return
Exemple #2
0
def show_menu(configs: dict) -> str:
    """
    Interative: Show a menu and wait for selection.
    "blank" may be used to display an empty line.
    print() is allowed here as this is for interactive use only.

    Args:
        configs: Dictionary of strings which are menu items
    Returns:
        string associated with item selected or empty string.
    """

    if len(configs) == 1:
        choice = configs[list(configs.keys())[0]]
        return choice

    CONFIRMED = 0
    choice = ""
    while not CONFIRMED:
        print("Select configuration number from list below:\n")
        i = 0
        for c in configs:
            if c == "blank":
                print("")
            else:
                i += 1
                print("%1d.....%s" % (i, c))
        print("")
        print("Enter configuration number: ", end="")
        choiceindex = input()
        if choiceindex == "q":
            azcam.AzcamWarning("Quit detected")
            return
        try:
            choiceindex = int(choiceindex)
        except ValueError:
            print("Bad keyboard input...try again\n")
            continue

        choiceindex = int(choiceindex)
        choiceindex = choiceindex - 1  # zero based

        # remove blanks
        for x in configs:
            if x == "blank":
                configs.remove("blank")

        if choiceindex < 0 or choiceindex > len(configs) - 1:
            print("invalid selection - %d\n" % (choiceindex + 1))
            continue

        # get choice
        configlist = list(configs.keys())  # is order OK?
        choice = configs[configlist[choiceindex]]

        CONFIRMED = 1

    print("")

    return choice
    def read_header(self):
        """
        Returns telescope header info.
        returns [Header[]]: Each element Header[i] contains the sublist (keyword, value, comment, and type).
        Example: Header[2][1] is the value of keyword 2 and Header[2][3] is its type.
        Type is one of str, int, or float.
        """

        if not self.enabled:
            azcam.AzcamWarning("telescope not enabled")
            return

        header = []

        data = self.Tserver.azcam_all()
        keywords = list(data.keys())
        keywords.sort()
        list1 = []

        for key in list(self.Tserver.keywords):
            try:
                t = self.header.typestrings[key]
                v = data[self.Tserver.keywords[key]]
                c = self.header.comments[key]
                list1 = [key, v, c, t]
                header.append(list1)
            except Exception as message:
                azcam.log("ERROR", key, message)
                continue

            # store value in Header
            self.header.set_keyword(list1[0], list1[1], list1[2], list1[3])

        return header
    def get_keyword(self, keyword):
        """
        Reads an telescope keyword value.
        Keyword is the name of the keyword to be read.
        This command will read hardware to obtain the keyword value.
        """

        if not self.enabled:
            azcam.AzcamWarning(f"{self.description} is not enabled")
            return

        data = self.Tserver.azcam_all()

        keyword = keyword.lower()
        reply = data[keyword]

        # parse RA and DEC specially
        if keyword == "RA":
            reply = "%s:%s:%s" % (reply[0:2], reply[2:4], reply[4:])
        elif keyword == "DEC":
            reply = "%s:%s:%s" % (reply[0:3], reply[3:5], reply[5:])
        else:
            pass

        # store value in Header
        self.set_keyword(keyword, reply)

        reply, t = self.header.convert_type(reply,
                                            self.header.typestrings[keyword])

        return [reply, self.comments[keyword], t]
    def wait_for_move(self):
        """
        Wait for telescope to stop moving.
        """

        if not self.enabled:
            azcam.AzcamWarning("telescope not enabled")
            return

        # loop for up to ~20 seconds
        for i in range(200):
            reply = self.get_keyword("MOTION")
            try:
                motion = int(reply[0])
            except:
                raise azcam.AzcamError("bad MOTION status keyword: %s" %
                                       reply[1])

            if not motion:
                return

            time.sleep(0.1)

        # stop the telescope
        command = "CANCEL"
        reply = self.Tserver.command(command)

        raise azcam.AzcamError("stopped motion flag not detected")
Exemple #6
0
    def initialize(self) -> None:
        """
        Initialize the tool.
        """

        if self.initialized:
            return

        if not self.enabled:
            azcam.AzcamWarning(f"{self.description} is not enabled")
            return

        self.initialized = 1

        return
Exemple #7
0
    def initialize(self):
        """
        Initialize display.
        """

        if self.initialized:
            return

        if not self.enabled:
            azcam.AzcamWarning("Display is not enabled")
            return

        self.set_display(self.default_display)

        return
    def offset(self, RA, Dec):
        """
        Offsets telescope in arcsecs.
        """

        if not self.enabled:
            azcam.AzcamWarning("telescope not enabled")
            return

        reply = self.Tserver.comSTEPRA(RA)
        reply = self.Tserver.comSTEPDEC(Dec)

        # wait for motion to stop
        reply = self.wait_for_move()

        return
Exemple #9
0
    def expose(self, exposure_time=-1, imagetype="", title=""):
        """
        Make a complete exposure.
        exposure_time is the exposure time in seconds
        imagetype is the type of exposure ('zero', 'object', 'flat', ...)
        title is the image title.
        """

        # allow custom operations
        self.start()

        azcam.log("Exposure started")

        # if last exposure was aborted, warn before clearing flag
        if self.exposure_flag == self.exposureflags["ABORT"]:
            azcam.AzcamWarning("Previous exposure was aborted")

        # begin
        if self.exposure_flag != self.exposureflags["ABORT"]:
            self.begin(exposure_time, imagetype, title)

        # integrate
        if self.exposure_flag != self.exposureflags["ABORT"]:
            self.integrate()

        # readout
        if (self.exposure_flag != self.exposureflags["ABORT"]
                and self.exposure_flag == self.exposureflags["READ"]):
            try:
                self.readout()
            except azcam.AzcamError:
                pass
        # end
        if self.exposure_flag != self.exposureflags["ABORT"]:
            self.end()

        self.exposure_flag = self.exposureflags["NONE"]
        self.completed = 1
        azcam.log("Exposure finished")

        # allow custom operations
        self.finish()

        return
Exemple #10
0
    def read_file(self, filename=""):
        """
        Read a header file and import the data into the header.
        """

        # if no file specified, just skip
        if filename == "":
            return

        if not os.path.exists(filename):
            azcam.AzcamWarning("Header file not found:%s" % filename)
            return

        with open(filename, "r") as f1:
            for line in f1.readlines():
                line = line.rstrip()
                line = line.lstrip()
                if line.startswith("#"):
                    break
                if len(line) == 0:
                    break
                tokens = line.split(" ", 1)
                keyword = tokens[0]

                if keyword == "COMMENT" and len(tokens) == 1:
                    value = ""
                    comment = ""
                else:
                    nslash = tokens[1].find("/")
                    if nslash == -1:
                        value = tokens[1].strip()
                        comment = ""
                    else:
                        comment = tokens[1][nslash + 1 :].strip()
                        value = tokens[1][:nslash].strip()

                typ, val = azcam.utils.get_datatype(value)
                self.set_keyword(keyword, val, comment, typ)

        self.filename = filename

        return
    def initialize(self):
        """
        Initializes the telescope interface.
        """

        if self.initialized:
            return

        if not self.enabled:
            azcam.AzcamWarning(f"{self.description} is not enabled")
            return

        self.Tserver = TelescopeNG()

        # add keywords
        self.define_keywords()

        self.initialized = 1

        return
Exemple #12
0
    def initialize(self):
        """
        Initialize Ds9.

        :return None:
        """

        if self.initialized:
            return

        if os.name == "posix":
            self.xpaset_app = "xpaset"
            self.xpaget_app = "xpaget"
            self.xpaaccess_app = "xpaaccess"
            self.xpans = "xpans"
        else:
            self.ds9_app = os.path.join(self.root, "ds9.exe")
            self.ds9_app = os.path.abspath(self.ds9_app)
            self.xpaset_app = os.path.join(self.root, "xpaset.exe")
            self.xpaset_app = os.path.abspath(self.xpaset_app)
            self.xpaget_app = os.path.join(self.root, "xpaget.exe")
            self.xpaget_app = os.path.abspath(self.xpaget_app)
            self.xpaaccess_app = os.path.join(self.root, "xpaaccess.exe")
            self.xpaaccess_app = os.path.abspath(self.xpaaccess_app)
            self.xpans = os.path.join(self.root, "xpans.exe")
            self.xpans = os.path.abspath(self.xpans)

        if not self.enabled:
            azcam.AzcamWarning("Display is not enabled")
            return

        self.set_display(self.default_display)

        self.initialized = 1

        return
Exemple #13
0
    def display(self, image, extension_number=-1):
        """
        Display a file in ds9, making a copy so locking does not occur.
        If specified for an MEF file, only extension_number is displayed.

        :param image: a filename or an image object
        :param int extension_number: FITS extension number of image, -1 for all
        :return None:
        """

        self.initialize()

        # test, could be slow but seems to work nicely
        self.set_display()

        ds9 = self.host + ":" + self.port

        if type(image) == str:
            filename1 = azcam.utils.make_image_filename(image)
        else:
            filename1 = image.filename

        ext = os.path.splitext(filename1)[-1]

        # copy image file so it is not locked by ds9
        filename = os.path.join(tempfile.gettempdir(), "tempdisplayfile" + ext)
        shutil.copyfile(filename1, filename)

        if ext == ".fits":
            im = pyfits.open(filename)
            ne = max(0, len(im) - 1)
            im.close()
            if ne in [0, 1]:
                # s = self.xpaset_app + " " + ds9 + "fits iraf < " + filename
                s = [self.xpaset_app, ds9, f"fits iraf < {filename}"]
            else:
                if extension_number == -1:
                    # s = self.xpaset_app + " " + ds9 + "fits mosaicimage iraf < " + filename
                    s = [
                        self.xpaset_app, ds9,
                        f"fits mosaicimage iraf < {filename}"
                    ]
                else:
                    s = [
                        self.xpaset_app,
                        ds9,
                        "fits",
                        f"[{extension_number}] < {filename}",
                    ]
        elif ext == ".bin":
            NumCols, NumRows = self.size_x, self.size_y
            s = [
                self.xpaset_app,
                ds9,
                "array",
                f"[xdim={NumCols},ydim={NumRows},bitpix=-16] < {filename}",
            ]
        else:
            azcam.AzcamWarning("invalid image extension")
            return

        # execute XPA command to display file
        s = " ".join(s)
        p = subprocess.Popen(
            s,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            shell=True,
        )
        stdout, stderr = p.communicate()
        stdout = stdout.decode("utf-8")

        return
Exemple #14
0
    def guide(self, number_exposures=1):
        """
        Make a complete guider exposure sequence.
        NumberExposures is the number of exposures to make, -1 loop forever
        """

        AbortFlag = 0

        number_exposures = int(number_exposures)

        # system must be reset once before an exposure can be made
        if not azcam.db.tools["controller"].is_reset:
            azcam.db.tools["controller"].reset()

        # parameters for faster operation
        flusharray = self.flush_array
        azcam.log("Guide started")

        # this loop continues even for errors since data is sent to a seperate client receiving images
        LoopCount = 0
        while True:

            if 0:
                self.begin(exposure_time=-1,
                           imagetype="object",
                           title="guide image")

                # integrate
                self.integrate()

                # readout
                if self.exposure_flag == self.exposureflags["READ"]:
                    try:
                        self.readout()
                        self.guide_status = 1  # image read OK
                        self.guide_image_copy = self.image
                    except Exception:
                        self.guide_status = 2  # image not read OK, but don't stop guide loop
                        self.image = self.guide_image_copy

                # image writing
                self.end()
                self.exposure_flag = self.exposureflags["NONE"]
            else:
                self.expose(-1, "object", "guide image")

            AbortFlag = azcam.db.abortflag
            if AbortFlag:
                break

            if number_exposures == -1:
                continue
            else:
                LoopCount += 1

            if LoopCount >= number_exposures:
                break

        # finish
        self.guide_status = 0
        self.flush_array = flusharray

        if AbortFlag:
            azcam.AzcamWarning("Guide aborted")
        else:
            azcam.log("Guide finished")

        return
Exemple #15
0
    def set_par(self, parameter: str, value: typing.Any = None) -> None:
        """
        Set the value of a parameter in the parameters dictionary.

        Args:
            parameter (str): name of the parameter
            value (Any): value of the parameter. Defaults to None.
        Returns:
            None
        """

        parameter = parameter.lower()

        if azcam.db.mode == "console":
            try:
                azcam.db.tools["server"].command(f"parameters.set_par {parameter} {value}")
            except azcam.AzcamError:
                return
            return None

        # special cases
        if parameter == "imagefilename":
            azcam.db.tools["exposure"].image.filename = value
            return None
        elif parameter == "imagetitle":
            if value is None or value == "" or value == "None":
                azcam.db.tools["exposure"].set_image_title("")
            else:
                azcam.db.tools["exposure"].set_image_title(f"{value}")
            return None
        elif parameter == "exposuretime":
            azcam.db.tools["exposure"].set_exposuretime(value)
            return None
        elif parameter == "logcommands":
            azcam.db.tools["cmdserver"].logcommands = int(value)
            return None

        # parameter must be in parameters
        try:
            attribute = azcam.db.pardict[parameter]
        except KeyError:
            azcam.AzcamWarning(f"Parameter {parameter} not available for set_par")
            return None

        # object must be a tool
        tokens = attribute.split(".")
        numtokens = len(tokens)
        if numtokens < 2:
            azcam.log("%s not valid for parameter %s" % (attribute, parameter))
            return None

        # first try to set value type
        _, value = azcam.utils.get_datatype(value)
        object1 = tokens[0]

        # run through tools
        try:
            obj = azcam.db.tools[object1]
            for i in range(1, numtokens - 1):
                obj = getattr(obj, tokens[i])
            # last time is actual object
            try:
                setattr(obj, tokens[-1], value)
            except AttributeError:
                pass
                # azcam.AzcamWarning(f"Could not set parameter: {parameter}")
        except KeyError:
            pass

        return None
Exemple #16
0
    def get_par(self, parameter: str) -> typing.Any:
        """
        Return the value of a parameter in the parameters dictionary.


        Args:
            parameter (str): name of the parameter

        Returns:
            value (Any): value of the parameter
        """

        parameter = parameter.lower()
        value = None

        if azcam.db.mode == "console":
            try:
                reply = azcam.db.tools["server"].command(f"parameters.get_par {parameter}")
            except azcam.AzcamError:
                return
            _, value = azcam.utils.get_datatype(reply)
            return value

        # special cases
        if parameter == "imagefilename":
            value = azcam.db.tools["exposure"].get_filename()
            return value
        elif parameter == "imagetitle":
            value = azcam.db.tools["exposure"].get_image_title()
            return value
        elif parameter == "exposuretime":
            value = azcam.db.tools["exposure"].get_exposuretime()
            return value
        elif parameter == "exposurecompleted":
            value = azcam.db.tools["exposure"].finished()
            return value
        elif parameter == "exposuretimeremaining":
            value = azcam.db.tools["exposure"].get_exposuretime_remaining()
            return value
        elif parameter == "pixelsremaining":
            value = azcam.db.tools["exposure"].get_pixels_remaining()
            return value
        elif parameter == "camtemp":
            value = azcam.db.tools["tempcon"].get_temperatures()[0]
            return value
        elif parameter == "dewtemp":
            value = azcam.db.tools["tempcon"].get_temperatures()[1]
            return value
        elif parameter == "temperatures":
            camtemp = azcam.db.tools["tempcon"].get_temperatures()[0]
            dewtemp = azcam.db.tools["tempcon"].get_temperatures()[1]
            return [camtemp, dewtemp]
        elif parameter == "logcommands":
            value = azcam.db.tools["cmdserver"].logcommands
            return value
        elif parameter == "wd":
            value = azcam.utils.curdir()
            return value
        elif parameter == "logdata":
            value = azcam.db.logger.get_logdata()
            return value

        # parameter must be in parameters
        try:
            attribute = azcam.db.pardict[parameter]
        except KeyError:
            azcam.AzcamWarning(f"Parameter {parameter} not available for get_par")
            return None

        tokens = attribute.split(".")
        numtokens = len(tokens)

        # a tool and attribute is required
        if numtokens == 1:
            return None

        object1 = tokens[0]

        # object1 must be a tool
        try:
            obj = azcam.db.tools[object1]
            for i in range(1, numtokens):
                try:
                    obj = getattr(obj, tokens[i])
                except AttributeError:
                    pass
            value = obj  # last time is value
        except KeyError:
            value = None

        return value