mounttools.py 15.1 KB
# -*- coding: utf-8 -*-
import math
import os
import sys
import serial.tools.list_ports
import requests

path = os.path.join(os.path.dirname(__file__), '..')
if path not in sys.path:
    sys.path.append(path)    
# --- celme imports
modulename = 'celme'
if modulename in dir():
    del celme
if modulename not in dir():    
    import celme

# #####################################################################
# #####################################################################
# #####################################################################
# Class Mounttools
# #####################################################################
# #####################################################################
# This class included various tools
# decode_kwargs
# #####################################################################

class Mounttools:

    _pi = math.pi
    _d2r = _pi/180.0    
    _r2d = 180.0/_pi
    
    def decode_kwargs(self, params_optional:dict, params_mandatory:dict, **kwargs)->dict:
        """ Conversion of the kwargs into params
        
        Conversion of the dictionary kwargs to another dictionary called params
        according the prescriptions of keys and defauts values defined in the
        two dictionaries params_optional and params_mandatory.
        """
        # ========= change keys into upper strings
        dics = dict()
        for k,v in kwargs.items():
            ku = str(k).upper()
            if (type(v) is str):
                v = v.strip()
            dic = { ku : v }
            dics.update(dic)
        selected_parameters = dics
        #print("dics={}".format(dics))
        # ========= decode **kwargs
        dico_param = {}
        # ---
        params = params_mandatory
        for param_key in params:
            if param_key in selected_parameters:
                raw_value = selected_parameters[param_key]
                type_conv = params[param_key][0]
                if type_conv==float:
                    value = float(raw_value)
                elif type_conv==int:
                    value = int(raw_value)
                else:
                    value = raw_value
                dico_param[param_key] = value
            else:
                msg = "{} not found amongst mandatory parameters ({})".format(param_key,params.keys())
                raise Exception(msg)
        # ---
        params = params_optional
        for param_key in params:
            if param_key in selected_parameters:
                raw_value = selected_parameters[param_key]
                type_conv = params[param_key][0]
            else:
                raw_value = params[param_key][1]
                type_conv = params[param_key][0]
            if type_conv==float:
                value = float(raw_value)
            elif type_conv==int:
                value = int(raw_value)
            else:
                value = raw_value
            dico_param[param_key] = value
        return dico_param

    def decode_args_kwargs(self, arg_index:int, params_args:dict, params_optional:dict, *args, **kwargs)->dict:
        """ Conversion of the args and kwargs into params
        
        Conversion of the parameters args and dictionary kwargs to another dictionary called params
        according the prescriptions of keys and defauts values defined in the
        two dictionaries params_optional and params_mandatory.
        """        
        #print("arg_index={}".format(arg_index))
        #print("params_args={}".format(params_args))
        #print("params_optional={}".format(params_optional))
        #print("*args={}".format(args))
        #print("**kwargs={}".format(kwargs))
        # ========= valid *args
        argc = len(args)
        valid = 1
        if (argc==0):
            valid = 0
            msg = "No key specified ({})".format(params_args.keys())
        else:
            # --- Identify the selected motion type
            selected_arg = args[arg_index].upper()
            if selected_arg in params_args:
                parameters = params_args[selected_arg]
            else:
                valid = 0
                msg = "{} not found amongst args ({})".format(selected_arg,params_args.keys())
        if valid==0:
            raise Exception(msg)
        # ========= valid **kwargs
        valid = 0
        #if (kwargc==0):
        #    raise Exception(res)
        #print("3.*args={}".format(args))
        #print("3.**kwargs={}".format(kwargs))
        # ========= change keys into upper strings
        dics = dict()
        for k,v in kwargs.items():
            ku = str(k).upper()
            if (type(v) is str):
                v = v.strip()
            dic = { ku : v }
            dics.update(dic)
        selected_parameters = dics
        #print("dics={}".format(dics))
        # ========= decode **kwargs
        valid = 0
        dico_param = {}
        dico_param["SELECTED_ARG"] = selected_arg
        # --- input values of mandatory parameters
        params = parameters["MANDATORY"]
        #print(">>> params={}".format(params))
        #print("*** selected_parameters={}".format(selected_parameters))
        for param_key in params:
            #print("** param_key={}".format(param_key))
            if param_key in selected_parameters:
                raw_value = selected_parameters[param_key]
                type_conv = params[param_key][0]
                #print("* type_conv={}".format(type_conv))
                if type_conv==float:
                    value = float(raw_value)
                elif type_conv==int:
                    value = int(raw_value)
                else:
                    value = raw_value
                dico_param[param_key] = value
            else:
                print("- TOTO")
                msg = "{} not found amongst mandatory parameters ({})".format(param_key,params.keys())
                raise Exception(msg)
        # --- input or default values of optional parameters
        params = params_optional
        for parameter_key in parameters["OPTIONAL"]:
            params[parameter_key] = parameters["OPTIONAL"][parameter_key]            
        for param_key in params:
            if param_key in selected_parameters:
                raw_value = selected_parameters[param_key]
                type_conv = params[param_key][0]
            else:
                raw_value = params[param_key][1]
                type_conv = params[param_key][0]
            if type_conv==float:
                value = float(raw_value)
            elif type_conv==int:
                value = int(raw_value)
            else:
                value = raw_value
            dico_param[param_key] = value
        return dico_param

    def name2coord(self, *args):
        found = 0
        ra = 0
        dec = 0
        # ========= valid *args
        argc = len(args)
        name0 = ""
        if (argc==0):
            return found, ra, dec
        else:
            name0 = args[0].lower()
        cwd = os.getcwd()
        # --- star names
        if found==0:
            name0 = args[0].lower()
            filename = cwd + "/catalogues/catagoto/etoiles_brillantes.txt"
            #print("filename={}".format(filename))
            with open(filename, 'r', errors='surrogateescape', newline='') as fid:
                lignes = fid.read()
            lignes = lignes.split("\n")        
            for ligne in lignes:
                #print("{}".format(ligne))
                name = ligne[0:21].strip().lower()            
                if name0==name:
                    found = 1
                if found==0:
                    name = ligne[21:36].strip().lower()            
                    if name0==name:
                        found = 1
                if found==1:
                    #print("name0={} name={}".format(name0,name))
                    #print("ligne={}".format(ligne))
                    ra = ligne[36:38]+"h"+ligne[39:41]+"m"+ligne[42:47]+"s"         
                    dec = ligne[52:55]+"d"+ligne[56:58]+"m"+ligne[59:63]+"s"
                    break
        # --- Messier
        if found==0:
            name0 = args[0].upper()
            filename = cwd + "/catalogues/catagoto/cat_messier.txt"
            #print("filename={}".format(filename))
            with open(filename, 'r', errors='surrogateescape', newline='') as fid:
                lignes = fid.read()
            lignes = lignes.split("\n")        
            for ligne in lignes:
                #print("{}".format(ligne))
                lligne = ligne.split()
                if len(lligne)==0:
                    continue
                name = lligne[0].strip().upper() 
                if name0==name:
                    found = 1
                    ra = lligne[1]+"h"+lligne[2]+"m"         
                    dec = lligne[3]+"d"+lligne[4]+"m"
                    break
        # --- NGC
        if found==0:
            name0 = args[0].upper()
            filename = cwd + "/catalogues/catagoto/cat_ngc.txt"
            #print("filename={}".format(filename))
            with open(filename, 'r', errors='surrogateescape', newline='') as fid:
                lignes = fid.read()
            lignes = lignes.split("\n")        
            for ligne in lignes:
                #print("{}".format(ligne))
                lligne = ligne.split()
                if len(lligne)==0:
                    continue
                name = lligne[0].strip().upper() 
                if name0==name:
                    found = 1
                    ra = lligne[1]+"h"+lligne[2]+"m"         
                    dec = lligne[3]+"d"+lligne[4]+"m"
                    break
        # --- IC
        if found==0:
            name0 = args[0].upper()
            filename = cwd + "/catalogues/catagoto/cat_ic.txt"
            #print("filename={}".format(filename))
            with open(filename, 'r', errors='surrogateescape', newline='') as fid:
                lignes = fid.read()
            lignes = lignes.split("\n")        
            for ligne in lignes:
                #print("{}".format(ligne))
                lligne = ligne.split()
                name = lligne[0].strip().upper() 
                if len(lligne)==0:
                    continue
                if name0==name:
                    found = 1
                    ra = lligne[1]+"h"+lligne[2]+"m"         
                    dec = lligne[3]+"d"+lligne[4]+"m"
                    break
        return found, ra, dec

    def get_available_serial_ports(self):
        """
        Return a list of available serial ports of the local computer
        """
        # --
        prefix_myserial_ports = ""
        if sys.platform.startswith('win'):
            prefix_myserial_ports = "//./"
        elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
            prefix_myserial_ports = ""
        elif sys.platform.startswith('darwin'):
            prefix_myserial_ports = ""
        # --
        serial_ports = serial.tools.list_ports.comports(include_links=False)
        # --
        available_serial_ports = []
        for serial_port in serial_ports:
            available_serial_port = prefix_myserial_ports + serial_port.device 
            available_serial_ports.append(available_serial_port)
        return available_serial_ports

    def vo_simbad(self, ident):
        """
        Return ra,dec,J2000 according an object name using SImbad server
        """
        found = 0
        ident = ident.replace(" ","+")
        url = "http://simbad.u-strasbg.fr/simbad/sim-basic?Ident={}&submit=SIMBAD+search".format(ident)
        res = requests.get(url, timeout = 10)
        if res.ok==False:
            return {}
        texte = res.text
        k1 = texte.find("ICRS")
        texte = texte[k1:]
        ltexte = texte.split("\n")
        if len(ltexte)>11:
            radec = ltexte[11]
            radecs = radec.split()
            ra = radecs[0]+"h"+radecs[1]+"m"+"{:.3f}".format(float(radecs[2]))+"s"
            dec = radecs[3]+"d"+radecs[4]+"m"+"{:.2f}".format(float(radecs[5]))+"s"
            #cra = celme.Angle(ra).deg()
            #cdec = celme.Angle(dec).deg()
            found = 1
        else:
            ra = 0
            dec = 0            
        return found, ra, dec

# #####################################################################
# #####################################################################
# #####################################################################
# Main
# #####################################################################
# #####################################################################
# #####################################################################

if __name__ == "__main__":

    example = 5
    print("Example       = {}".format(example))
            
    if example == 1:
        def decode_test(**kwargs):
            tools = Mounttools()
            # --- Dicos of optional and mandatory parameters
            params_optional = {}
            params_optional["OUT_UNIT"] = (str,'m')
            params_mandatory = {} 
            params_mandatory["VALUE"] = (float,1.0)
            params_mandatory["INP_UNIT"] = (str,'m')
            # --- Decode kwarg parameters
            params = tools.decode_kwargs(params_optional, params_mandatory, **kwargs)
            return params
        # -- Now we call the function with default optional keys
        params = decode_test(value=3.6, inp_unit="cm")
        print("(1) params={}".format(params))
        # -- Now we call the function with personal optional keys
        params = decode_test(value=3.6, inp_unit="cm", out_unit="km")
        print("(2) params={}".format(params))
        
    if example == 2:
        def decode_test(*args, **kwargs):
            tools = Mounttools()
            # --- Dicos of optional and mandatory parameters
            #kwargc = len(kwargs)
            #print("2.*args={} argc={}".format(args,argc))
            #print("2.**kwargs={} kwargc={}".format(kwargs,kwargc))
            # ========= Definition of motion_types
            # --- Dico of motion types and their parameters
            motion_types = {}
            motion_types["OFFSET"]   = {"MANDATORY" : {"OFFSET":[float,1.0], "VELOCITY":[float,1.0]}, "OPTIONAL" : {"DRIFT":[float,0.0]} }
            motion_types["ABSOLUTE"] = {"MANDATORY" : {"POSITION":[float,0.0], "VELOCITY":[float,1.0]}, "OPTIONAL" : {"DRIFT":[float,0.0]} }
            motion_types["CONTINUOUS"]   = {"MANDATORY" : {"DRIFT":[float,0.0]}, "OPTIONAL" : {} }
            # --- Dico of optional parameters for all motion types
            params_optional = {"FRAME":(str,'inc')}
            # --- Decode args and kwargs parameters
            params = tools.decode_args_kwargs(0, motion_types, params_optional, *args, **kwargs)
            return params
        # -- Now we call the function with default optional keys
        params = decode_test("absolute", position=130, velocity=-1.4)
        print("(1) params={}".format(params))
        
    if example == 3:
        tools = Mounttools()
        res = tools.name2coord("vega")
        print("res={}".format(res))

    if example == 4:
        tools = Mounttools()
        res = tools.get_available_serial_ports()
        print("Available serial ports are {}".format(res))

    if example == 5:
        tools = Mounttools()
        res = tools.vo_simbad("Messier 12")
        print("res={}".format(res))