Skip to content

Planet

Planet

A planet (which may have rings)

Parameters:

Name Type Description Default
P float

Orbital period [day]

required
a float

Semi-major axis [stellar radius]

required
Rp float

Planet radius [stellar radius]

required
Mp float

Planet mass [Earth mass]

None
e float

Eccentricity of the orbit. Default is 0

0.0
w float

Argument of periastron [degree]. w=0 means periastron is on the yz plane, w=90 means it is in front of the observer. Default is 90

90.0
ip float

Inclination of the orbital plane [degree]. Default is 90

90.0
lbda float

Projected spin-orbit misalignment angle [degree]. Default is 0

0.0
t0 float

Time of periastron passage [day]. Default is 0

0.0
Source code in SOAP/classes.py
class Planet:
    """A planet (which may have rings)

    Args:
        P (float):
            Orbital period [day]
        a (float):
            Semi-major axis [stellar radius]
        Rp (float):
            Planet radius [stellar radius]
        Mp (float, optional):
            Planet mass [Earth mass]
        e (float, optional):
            Eccentricity of the orbit. Default is 0
        w (float, optional):
            Argument of periastron [degree]. w=0 means periastron is on the yz
            plane, w=90 means it is in front of the observer. Default is 90
        ip (float, optional):
            Inclination of the orbital plane [degree]. Default is 90
        lbda (float):
            Projected spin-orbit misalignment angle [degree]. Default is 0
        t0 (float):
            Time of periastron passage [day]. Default is 0
    """

    @maybe_quantity_input(
        P=U.day,
        a=U.solRad,
        Rp=U.solRad,
        Mp=U.earthMass,
        w=U.deg,
        ip=U.deg,
        lbda=U.deg,
        t0=U.day,
    )
    def __init__(self, P, a, Rp, Mp=None, e=0.0, w=90.0, ip=90.0, lbda=0.0, t0=0.0):
        self.P = P
        self.t0 = t0
        self.e = e
        self.w = w
        self.ip = ip
        self.lbda = lbda
        self.a = a << U.solRad
        self.Rp = Rp
        self.Mp = Mp

        self.ring = None

    def add_ring(self, fi=1.0, fe=1.0, ir=0.0, theta=0.0):
        """
        Add a ring to this planet.

        Args:
            fi (float, optional [default: 1.0]):
                Ring inner radius
            fe (float, optional [default: 1.0]):
                Ring outer radius
            ir (float, optional [default: 0.0]):
                Projected inclination of ring wrt to the skyplane [degrees].
                90 for an edge-on ring, 0 for face on
            theta (float, optional [default: 0.0]):
                Projected ring tilt [degrees]. 90 means that the image of the ring in
                perpendicular to the orbit in the plane of the sky.
        """

        self.ring = Ring(fi, fe, ir, theta)

    def remove_ring(self):
        self.ring = None

    @property
    def has_ring(self):
        if self.ring is not None:
            if self.ring.fe > self.ring.fi and self.ring.fe > 1.0:
                return True
        return False

    @maybe_quantity_input(stellar_mass=U.M_sun)
    def semi_amplitude(self, stellar_mass=1.0, unit=kms):
        if self.Mp is None:
            raise ValueError("no planet mass defined")
        from astropy.constants import G

        f = (2 * np.pi * G / self.P) ** (1 / 3)
        Mratio = self.Mp / (self.Mp + stellar_mass) ** (2 / 3)
        self.K = f * Mratio / np.sqrt((1 - self.e**2))
        self.K <<= unit
        return self.K

    @maybe_quantity_input(stellar_mass=U.M_sun)
    def rv_curve(self, time, stellar_mass=1.0, unit=kms):
        if self.Mp is None:
            raise ValueError("no planet mass defined")

        from .keplerian import keplerian

        # calculate semi-amplitude
        self.semi_amplitude(stellar_mass)

        rv_kep = keplerian(
            time,
            self.P.value,
            self.K.value,
            self.e,
            np.deg2rad(self.w.value),
            self.t0.value,
            0.0,
        )
        return rv_kep * unit

    def __repr__(self):
        if self.Rp == 0:
            return "no planet (to enable, set planet.Rp > 0)"

        pars = (
            f"P={self.P}; t0={self.t0}; e={self.e}; w={self.w}; "
            f"ip={self.ip}; lbda={self.lbda}; a={self.a}, Rp={self.Rp}"
        )

        if self.ring:  # and self.ring.fi != self.ring.fe:
            ring_pars = f"fi={self.ring.fi}, fe={self.ring.fe}, ir={self.ring.ir}, theta={self.ring.theta}"
            return f"SOAP.Planet({pars})\n\t\tring({ring_pars})"
        else:
            return f"SOAP.Planet({pars})"

    def __setattr__(self, name, value):
        try:
            old = getattr(self, name)
            if has_unit(old):
                super().__setattr__(name, value << old.unit)
            else:
                super().__setattr__(name, value)
        except AttributeError:
            super().__setattr__(name, value)

    def set(self, **kwargs):
        set_object_attributes(self, kwargs)

add_ring(fi=1.0, fe=1.0, ir=0.0, theta=0.0)

Add a ring to this planet.

Parameters:

Name Type Description Default
fi (float, optional [default

1.0]): Ring inner radius

required
fe (float, optional [default

1.0]): Ring outer radius

required
ir (float, optional [default

0.0]): Projected inclination of ring wrt to the skyplane [degrees]. 90 for an edge-on ring, 0 for face on

required
theta (float, optional [default

0.0]): Projected ring tilt [degrees]. 90 means that the image of the ring in perpendicular to the orbit in the plane of the sky.

required
Source code in SOAP/classes.py
def add_ring(self, fi=1.0, fe=1.0, ir=0.0, theta=0.0):
    """
    Add a ring to this planet.

    Args:
        fi (float, optional [default: 1.0]):
            Ring inner radius
        fe (float, optional [default: 1.0]):
            Ring outer radius
        ir (float, optional [default: 0.0]):
            Projected inclination of ring wrt to the skyplane [degrees].
            90 for an edge-on ring, 0 for face on
        theta (float, optional [default: 0.0]):
            Projected ring tilt [degrees]. 90 means that the image of the ring in
            perpendicular to the orbit in the plane of the sky.
    """

    self.ring = Ring(fi, fe, ir, theta)