home.py 9.11 KB
from math import fmod
import doctest
from .mechanics import Mechanics
from .angles import Angle

# ========================================================
# ========================================================
# === HOME
# ========================================================
# ========================================================

class Home(Mechanics):
    """ Class to describe a home
    """
# ========================================================
# === attributs
# ========================================================

    # Longitudes East increasing (0 to 360) E=[0-180] W=[180:360]
    _iau_longitude = 0 ; # rad. 
    _iau_latitude = 0 ; # rad
    _altitude_m = 0 ; # (m)
    _computed_rho = 0
    _rhocosphip = 1 
    _rhosinphip = 0
    
# ========================================================
# === internal methods : Generals
# ========================================================

    def _init_home(self, *args):
        """ Object initialization        
        """
        self._iau_longitude = 0 ; # rad
        self._iau_latitude = 0 ; # rad
        self._altitude_m = 0.0
        self._computed_rho = 0
        if (len(args)==0):
            self._home_decode("MPC 1.4625  0.72520  +0.68627")
        else:
            self._home_decode(*args)
        
    
# ========================================================
# === internal methods : 
# ========================================================
        
    def _home_decode(self, *args):
        if (len(args)==1):
            s = str(args[0]).upper()
            #print("s={}".format(s))
            s = s.split()
            if (s[0]=="GPS"):
                if (len(s)<5):
                    raise Exception
                    return ""
                self._set_longitude(s[1]) ; # [0]='GPS'
                longi = self._get_longitude()
                sense = str(s[2]).upper()
                if (sense[0]=='W'):
                    if (longi<180):
                        longi = 360 - longi
                else:
                    if (longi>180):
                        longi = 360 - longi
                self._iau_longitude = longi*self._DR
                self._set_latitude(s[3])
                self._set_altitude(s[4])
                self._computed_rho = 0
            elif (s[0]=="MPC"):
                if (len(s)<4):
                    raise Exception
                    return ""
                self._set_longitude(s[1]) ; # [0]='MPC'
                self._rhocosphip = float(s[2])
                self._rhosinphip = float(s[3])
                latitude, altitude = self._mc_rhophi2latalt(self._rhosinphip,self._rhocosphip)
                self._set_latitude(latitude)
                self._set_altitude(altitude)
                self._computed_rho = 1
            else:
                raise Exception
                return ""
        elif (len(args)==3):
            self._set_longitude(args[0])
            self._set_latitude(args[1])
            self._set_altitude(args[2])
        else:
            raise Exception
            return ""
        
# ========================================================
# === Home methods
# ========================================================

    def home(self,*args):
        """ Object initialization        
        
        {GPS long_deg sense lati_deg altitude_m}
        {MPC IAU_long_deg rhocosphi rhosinphi }
        """
        self._home_decode(*args)
        return args

# ========================================================
# === get/set methods
# ========================================================

    def _get_lrr(self):
        if (self._computed_rho == 0):
            latitude = self._iau_latitude / self._DR
            self._rhocosphip, self._rhosinphip = self._mc_latalt2rhophi(latitude,self._altitude_m)
            self._computed_rho = 1
        return self._iau_longitude/self._DR, self._rhocosphip, self._rhosinphip

    def _set_lrr(self, *args):
        self._home_gps_decode(*args)

    def _get_lla(self):
        longi = self._get_longitude()
        lati = self._get_latitude()
        alti= self._get_altitude()
        return longi, lati, alti
        
    def _set_lla(self, *args):
        self._home_gps_decode(*args)

    def _get_gps(self):
        longi = self._get_longitude()
        if (longi>180):
            sense = 'W'
            longi = 360-longi
        else:
            sense = 'E'
        lati = self._get_latitude()
        alti= self._get_altitude()
        s = "GPS {:.5f} {} {:+.5f} {:.2f}".format(longi,sense,lati,alti)
        return s
        
    def _set_gps(self, *args):
        self._home_gps_decode(*args)
    
    def _set_mpc(self, *args):
        self._home_gps_decode(*args)
    
    def _get_mpc(self):
        if (self._computed_rho == 0):
            latitude = self._iau_latitude / self._DR
            self._rhocosphip, self._rhosinphip = self._mc_latalt2rhophi(latitude,self._altitude_m)
            self._computed_rho = 1
        s = "MPC {:.5f} {:.6f} {:+.6f}".format(self._iau_longitude/self._DR,self._rhocosphip, self._rhosinphip)
        return s

    def _get_longitude(self):
        return self._iau_longitude/self._DR

    # Longitudes East increasing (0 to 360) E=[0-180] W=[180:360]
    def _set_longitude(self, longitude):
        if isinstance(longitude, (int, float, str, Angle)) == False:
            raise TypeError
            return ""
        if isinstance(longitude, str) == True:
            longitude = Angle(longitude)
        if isinstance(longitude, Angle) == True:
            longitude = longitude.deg()            
        longitude = fmod(longitude,360)
        if (longitude<0):
            longitude+=360
        self._iau_longitude = longitude*self._DR
        self._computed_rho = 0
        
    def _get_latitude(self):
        return self._iau_latitude/self._DR

    def _set_latitude(self, latitude):
        if isinstance(latitude, (int, float, str, Angle)) == False:
            raise TypeError
            return ""
        if isinstance(latitude, str) == True:
            latitude = Angle(latitude)
        if isinstance(latitude, Angle) == True:
            latitude = latitude.deg()            
        latitude = fmod(latitude,360)
        if (latitude>360):
            latitude-=360
        if (latitude<-90):
            latitude=-90
        if (latitude>90):
            latitude=90
        self._iau_latitude = latitude*self._DR
        self._computed_rho = 0
        
    def _get_altitude(self):
        return self._altitude_m

    def _set_altitude(self, altitude):
        if isinstance(altitude, (int, float, str)) == False:
            raise TypeError
            return ""
        if isinstance(altitude, str) == True:
            altitude = float(altitude)
        if (altitude<-450):
            altitude = -450
        self._altitude_m = altitude
        self._computed_rho = 0

    longitude = property(_get_longitude, _set_longitude)
    latitude = property(_get_latitude, _set_latitude)
    altitude = property(_get_altitude, _set_altitude)
    gps = property(_get_gps, _set_gps)
    mpc = property(_get_mpc, _set_mpc)
    lla = property(_get_lla, _set_lla)
    lrr = property(_get_lrr, _set_lrr)
    
# ========================================================
# === debug methods
# ========================================================
    
    def infos(self, action) -> None:
        """ To get informations about this class
        
        :param action: A command to run a debug action (see examples).
        :type action: string
        
        :Example:
            
        Home().infos("doctest")
        Home().infos("doc_methods")
        Home().infos("internal_attributes")
        Home().infos("public_methods")        
        """
        if (action == "doc_methods"):
            publics = [x for x in dir(self) if x[0]!="_"]
            for public in publics:
                varname = "{}".format(public)
                if (callable(getattr(self,varname))==True):
                    print("\n{:=^40}".format(" method "+varname+" "))
                    t = "Home()."+varname+".__doc__"
                    tt =eval(t)
                    print(tt)
        if (action == "doctest"):
            if __name__ == "__main__":
                print("\n{:~^40}".format("doctest"))
                doctest.testmod(verbose=False)
        if (action == "internal_attributes"):
            internals = [x for x in dir(self) if x[0]=="_" and x[1]!="_"]
            for internal in internals:
                varname = "{}".format(internal)
                #if (hasattr(self,varname)==True):
                if (callable(getattr(self,varname))==False):
                    print(varname + "=" + str(getattr(self,varname)))
        if (action == "public_methods"):
            publics = [x for x in dir(self) if x[0]!="_"]
            for public in publics:
                varname = "{}".format(public)
                if (callable(getattr(self,varname))==True):
                    print(varname)

# ========================================================
# === special methods
# ========================================================
        
    def __init__(self, *args):
        """ Object initialization
        """
        self._init_home(*args)
		  # super().__init__()