Exemplo n.º 1
0
    def scale_planets(cls,
                      scale_data: dict = None,
                      do_moons: bool = True,
                      debug: bool = False):
        """
        Scales all defined planets to scales specified by scale_data 

        Parameters
        ----------

        scale_data: dict 
            A dictionary 
        do_moons: bool 
            scale moons aroundPlanet
        moon_scales: dict 
            provide a dictionary of args for the Moon.scale_moon() function
        debug (bool): 
            enables debug messages
        """
        scale_data = cls._default_scale_data if scale_data == None else utilz.merge_attributes(
            cls._default_scale_data, scale_data)
        [
            i.scale_planet(scale_data=scale_data, debug=debug)
            for i in cls._instances
        ]
        if do_moons:
            [
                i.scale_moon(scale_data=scale_data, debug=debug)
                for i in Moon._instances
            ]
Exemplo n.º 2
0
    def scale_distance(self,
                       scale_data: dict = None,
                       debug: bool = False) -> Planet:
        """
        Returns a planet object with scaled distance values (semimajorAxis, semiminorAxis)
        standard scaling is performed by the function f(x) = x/(10**scaleExponent)

        Parameters
        ----------

        scale_data: dict 
            dictionary of overrides for default scale_data
        debug: bool
            output informational messages (default: False)
        """
        scale_data = self.default_scale_data if scale_data == None else utilz.merge_attributes(
            self.default_scale_data, scale_data)
        print(
            f"INFO: {self.englishName} raw values [semimajorAxis -> {self.semimajorAxis}] [semiminorAxis -> ({self.semiminorAxis}]"
        ) if debug else None
        self.scaleDistExp = scale_data['planet']['scale_dist']
        self.semimajorAxis = float(self.semimajorAxis /
                                   (10**self.scaleDistExp))
        self.semiminorAxis = float(self.semiminorAxis /
                                   (10**self.scaleDistExp))
        print(
            f"INFO: {self.englishName} scaled with [values/(10**{self.scaleDistExp})] [semimajorAxis -> {self.semimajorAxis}] [semiminorAxis -> {self.semiminorAxis}]"
        ) if debug else None
        return self
Exemplo n.º 3
0
    def scale_mass(self,
                   scale_data: dict = None,
                   debug: bool = False) -> Planet:
        """
        Returns a planet object with scaled calculated mass value (massRawKG)
        standard scaling is performed by the function f(x) = x/(10**scaleExponent)

        Parameters
        ----------

        scale_data: dict 
            (dictionary of overrides for default scale_data)
        debug: bool
            output informational messages (default: False)
        """
        scale_data = self.default_scale_data if scale_data == None else utilz.merge_attributes(
            self.default_scale_data, scale_data)
        print(f"INFO: {self.englishName} raw values [mass -> {self.massRawKG}]"
              ) if debug else None
        self.scaleMassExp = scale_data['planet']['scale_mass']
        self.massExponent = self.massExponent - (self.scaleMassExp)
        self.massRawKG = float(
            f"{float(self.massValue*(10**self.scaleMassExp)):f}")
        print(
            f"INFO: {self.englishName} scaled with [values/(10**{self.scaleMassExp})] [mass ->{self.massRawKG}]"
        ) if debug else None
        return self
Exemplo n.º 4
0
    def scale_planet(self,
                     scale_data: dict = None,
                     do_moons: bool = False,
                     debug: bool = False) -> Planet:
        """
        Returns a planet object with scaled distance, size, calculated mass & volume values (equaRadius, meanRadius, massRawKG, volumeRawKG, semimajorAxis, semiminorAxis)
        standard scaling is performed by the function f(x) = x/(10**scaleExponent)

        Parameters
        ----------

        scale_data: dict (dictionary of overrides for default scale_data)
        output informational messages (default: False)
        """
        scale_data = self.default_scale_data if scale_data == None else utilz.merge_attributes(
            self.default_scale_data, scale_data)
        self.meanRadius = self.meanRadius
        self.equaRadius = self.equaRadius
        self.englishName = self.englishName
        print(
            f"INFO: {self.englishName} raw values [meanRadius -> {self.meanRadius}] [equaRadius -> {self.equaRadius}] [semimajorAxis -> {self.semimajorAxis}] [semiminorAxis -> {self.semiminorAxis}]  [volValueRawKG -> {self.volumeRawKG}] [massRawKG -> {self.massRawKG}]"
        ) if debug else None
        self.scaleDistExp = scale_data['planet']['scale_dist']
        self.scaleMassExp = scale_data['planet']['scale_mass']
        self.scaleSizeExp = scale_data['planet']['scale_size']
        self.scaleVolExp = scale_data['planet']['scale_vol']
        self.semimajorAxis = self.semimajorAxis / (10**self.scaleDistExp)
        self.semiminorAxis = self.semiminorAxis / (10**self.scaleDistExp)
        self.volExponent = self.volExponent - (self.scaleVolExp)
        self.massExponent = self.massExponent - (self.scaleMassExp)
        self.massRawKG = float(
            f"{float(self.massValue*(10**self.scaleMassExp)):f}")
        self.volumeRawKG = float(
            f"{float(self.volValue*(10**self.scaleVolExp)):f}")

        self.meanRadius = self.meanRadius / (10**(self.scaleSizeExp))
        self.equaRadius = self.equaRadius / (10**(self.scaleSizeExp))
        #self.distanceFromSunInAU = self.distanceFromSunInAU / (10**(scale_dist))
        # NOTE: you should scale moons with the planet accordingly
        # scale_size: float = 0.5,scale_mass: float = 8.5, scale_vol: float = 8.5, scale_dist: float = 4.2, debug: bool = False
        if do_moons:
            [
                i.scale_moon(scale_data=scale_data, debug=debug)
                for i in self.moonData
            ]

        print(
            f"INFO: {self.englishName} scaled values [meanRadius -> {self.meanRadius}] [equaRadius -> {self.equaRadius}] [semimajorAxis -> {self.semimajorAxis}] [semiminorAxis -> {self.semiminorAxis}]  [volValueRawKG -> {self.volumeRawKG}] [massRawKG -> {self.massRawKG}]"
        ) if debug else None
        return self
Exemplo n.º 5
0
    def __init__(self,
                 name: str,
                 scale_data: dict = None,
                 debug: bool = False) -> Planet:
        """
        Returns an object of class planet.Planet 

        Parameters
        ----------

        name: str
            English name of a planet in the Solar System
        scale_data: dict
            A dict which overrides any default settings with user provided settings (default: see below for format..)
            {
                "planet": {
                    "scale_size": 0.5
                },
                "moon": {
                    "debug": True, 
                    "scale_mass": 8.5
                }
            }
        debug (bool): output useful debugging information
        """
        self.default_scale_data = {
            "planet": {
                "debug": False,
                "scale_mass": 8.5,
                "scale_vol": 8.5,
                "scale_dist": 3.2,
                "scale_size": 1.5
            },
            "moon": {
                "debug": False,
                "scale_mass": 8.5,
                "scale_vol": 8.5,
                "scale_dist": 4.2,
                "scale_size": 1.5
            }
        }
        self.user_scale_data = self.default_scale_data if scale_data == None else utilz.merge_attributes(
            self.default_scale_data, scale_data)
        _planet = data.get_planet_data(name)

        for k in _planet.keys():
            print(
                f"INFO: adding attribute for planet {_planet['englishName']} ({k}) with value ({_planet[k]}) to {_planet['englishName']}"
            ) if debug else None
            setattr(self, k, _planet[k])

        self.semiminorAxis = round(derive_semiminor_axis(self))
        self.semimajorAxis = float(self.semimajorAxis)
        # NOTE: hack to avoid IDE errors, key is dynamically set from returned `planet` JSON object
        self.moons = self.moons
        self.vol = self.vol
        self.mass = self.mass
        self.sideralOrbit = self.sideralOrbit
        if self.moons == None:
            self.moonData = []
        else:
            self.moonData = []

            for moon in self.moons:
                if moon == None:
                    print(
                        f"INFO: the moon {moon} is not parseable, it will be skipped in plotting"
                    ) if debug else None
                    continue
                moonobj = Moon(moon['rel'], debug=debug)
                if not hasattr(moonobj, 'id') or not hasattr(
                        moonobj, 'semimajorAxis') or not hasattr(
                            moonobj, 'semiminorAxis') or not hasattr(
                                moonobj, 'equaRadius') or not hasattr(
                                    moonobj, 'meanRadius') or not hasattr(
                                        moonobj, 'vol') or not hasattr(
                                            moonobj, 'mass'):
                    print(
                        f"INFO: the moon with relational URL {moon['rel']} is missing required attributes, it will be skipped in plotting"
                    ) if debug else None
                    continue
                # TODO: do filtering based on attribute limits, in blender module...
                print(f"INFO: adding moon with relational URL {moon['rel']}"
                      ) if debug else None
                self.moonData.append(moonobj)

        # scales are zeroed on initialization and updated when scale_planets, or scale_planet is called against the object
        self.scaleMassExp = 0.0
        self.scaleSizeExp = 0.0
        self.scaleDistExp = 0.0
        self.scaleVolExp = 0.0

        # mass and volume values
        self.volValue = self.vol['volValue']
        self.volExponent = self.vol['volExponent']
        self.massValue = self.mass['massValue']
        self.massExponent = self.mass['massExponent']
        self.volumeRawKG = float(
            f"{float(self.volValue*(10**self.volExponent)):f}")
        self.massRawKG = float(
            f"{float(self.massValue*(10**self.massExponent)):f}")
        ############################################################################################################
        # NOTE: calculate distance from sun in AU                                                                  #
        # NOTE: calculate harmonic frequency value                                                                 #
        # NOTE: AU value for orbital harmonies set during scale to properly capture scaled AU and harmonic values  #
        # SOURCE km->au: https://www.wolframalpha.com/input/?i=1+km+in+AU                                          #
        # SOURCE au->km: https://www.wolframalpha.com/input/?i=1+AU+in+km                                          #
        # 1.496*(10**(8-scale_exp)) -> 1 au in km (scaled)                                                         #
        # 6.685*(10**-(9-scale_exp)) -> 1 km in au (scaled)                                                        #
        ############################################################################################################
        self.distanceFromSunInAU = float(
            f"{float(self.semimajorAxis*( 6.685 * (10**-float(9) ) )):f}")
        self.harmonicFrequency = float(
            f"{float((self.distanceFromSunInAU**3)/(self.sideralOrbit**2)):f}")
        self.keys = list(_planet.keys()) + list(
            ('semiminorAxis', 'volValue', 'volExponent', 'massValue',
             'massExponent', 'volumeRawKG', 'massRawKG', 'distanceFromSunInAU',
             'harmonicFrequency', 'scaleMassExp', 'scaleSizeExp',
             'scaleDistExp', 'scaleVolExp'))
        self.__class__._instances.append(self)