def __init__(self, relevantAxes="xyz"): self.ke = KeplerEllipse(1.0, 1.0) fuf.OneDFit.__init__(self, ["a", "per", "e", "tau", "Omega", "w", "i"]) self["a"] = 1.0 self["per"] = 1.0 # Which axes to consider? # x=0, y=1, z=2 self.axes = () for i, axis in enumerate("xyz"): if axis in relevantAxes: self.axes += (i, )
def __init__(self, relevantAxes="xyz", mode="pos"): self.ke = KeplerEllipse(1.0, 1.0) fuf.OneDFit.__init__(self, ["a", "per", "e", "tau", "Omega", "w", "i"]) self["a"] = 1.0 self["per"] = 1.0 # Which axes to consider? # x=0, y=1, z=2 self.axes = () for i, axis in enumerate("xyz"): if axis in relevantAxes: self.axes += (i, ) # Save the mode if not mode in ["pos", "vel"]: raise(PE.PyAValError("Unknown mode: " + str(mode), \ where="KeplerEllipseModel", \ solution="Choose either 'pos' or 'vel'.")) self._mode = mode
def __init__(self, relevantAxes="xyz"): self.ke = KeplerEllipse(1.0, 1.0) fuf.OneDFit.__init__(self, ["a", "per", "e", "tau", "Omega", "w", "i"]) self["a"] = 1.0 self["per"] = 1.0 # Which axes to consider? # x=0, y=1, z=2 self.axes = () for i, axis in enumerate("xyz"): if axis in relevantAxes: self.axes += (i,)
def __init__(self, relevantAxes="xyz", mode="pos"): self.ke = KeplerEllipse(1.0, 1.0) fuf.OneDFit.__init__(self, ["a", "per", "e", "tau", "Omega", "w", "i"]) self["a"] = 1.0 self["per"] = 1.0 # Which axes to consider? # x=0, y=1, z=2 self.axes = () for i, axis in enumerate("xyz"): if axis in relevantAxes: self.axes += (i,) # Save the mode if not mode in ["pos", "vel"]: raise(PE.PyAValError("Unknown mode: " + str(mode), \ where="KeplerEllipseModel", \ solution="Choose either 'pos' or 'vel'.")) self._mode = mode
def plot_keplerian_orbit(a, per, ecc=0, t_p=0, OMEGA=180, omega=90, inc=90, R_main=1, R_sec=1, fig=None, show=True): """Plot a keplerian orbit. Show the orbit in the plan of the three planes: xy (plane of the sky), xz and yzselfself. Also show a zoom on the transit and eclipse regions. :param float a: Semi-major axis [astropy Quantity/au] :param float per: Orbital period [astropy Quantity/day] :param float ecc: Orbital eccentricity (0-1) :param float t_p: Time of periapsis passage [day] :param float OMEGA: Longitude of the ascending node [astropy Quantity/deg] :param float omega: Argument of periapsis [astropy Quantity/deg] Note that the longitude if periapsis is given by OMEGA + omega. :param float inc: Orbit inclination [astropy Quantity/deg]. :param float R_main: Radius of the main object (for ex. the star) [astropy Quantity/R_sun] :param float R_sec: Radius of the secondary object (for ex. the planet) [astropy Quantity/R_jup] :param Figure fig: Figure :param bool show: If True show the figure before exiting the function """ # Check parameters units d_par = {"a": a, "per": per, "ecc": ecc, "t_p": t_p, "OMEGA": OMEGA, "omega": omega, "inc": inc, "R_main": R_main, "R_sec": R_sec} for param, unit in zip(["a", "per", "t_p", "OMEGA", "omega", "inc", "R_main", "R_sec"], [unt.au, unt.d, unt.d, unt.deg, unt.deg, unt.deg, unt.R_sun, unt.R_jup]): if isinstance(d_par[param], unt.Quantity): d_par[param] = d_par[param].to(unit).value # Main radius in AU R_main_au = d_par["R_main"] * unt.R_sun.to(unt.au) # Initialise the axes and figure if fig is None: # Create figure and axes fig, axes = pl.subplots(nrows=2, ncols=2) # Put labels and titles axes[1, 0].set_title("Plan of Sky - full xy") axes[1, 0].set_xlabel("x - East ->") axes[1, 0].set_ylabel("y - North ->") axes[0, 0].set_title("Plan xz") axes[1, 1].set_title("Plan zy") axes[0, 1].set_title("Plan of Sky - Eclipses Zoom") axes[0, 1].set_xlabel("x - East ->") axes[0, 1].set_ylabel("y - North ->") # Ensure equal scale axis for ax in axes.flat: ax.axis("equal") else: axes = array(fig.get_axes()).reshape((2, 2)) # Create the Keplerian elliptical orbit # ke = KeplerEllipse(1, 10, e=0.0, Omega=180., i=90.0, w=90.0) ke = KeplerEllipse(d_par["a"], d_par["per"], e=d_par["ecc"], tau=d_par["t_p"], Omega=d_par["OMEGA"], i=d_par["inc"], w=d_par["omega"]) # Create a time vector to sample the full period time = linspace(t_p, t_p + per, 200) # Compute the position xyz for the time vector pos = ke.xyzPos(time) # Find the nodes of the orbit (Observer at -z) ascn, descn = ke.xyzNodes_LOSZ() # Plot the Main object for ax in axes.flat: star = pl.Circle((0, 0), radius=R_main_au, facecolor="C8", edgecolor="black") ax.add_artist(star) # Plot orbit in xy plans axes[1, 0].plot(pos[::, 0], pos[::, 1]) # Plot orbit in xy plans Eclipses zoom axes[0, 1].plot(pos[::, 0], pos[::, 1]) # Do the Zoom axes[0, 1].set_xlim((-R_main_au * 1.5, R_main_au * 1.5)) axes[0, 1].set_ylim((-R_main_au * 1.5, R_main_au * 1.5)) # Plot orbit in xz plan axes[0, 0].plot(pos[::, 0], pos[::, 2]) # Plot orbit in zy plan axes[1, 1].plot(pos[::, 2], pos[::, 1]) if show: pl.show() return fig
class KeplerEllipseModel(fuf.OneDFit): """ A model of a Keplerian orbit. This class uses the *KeplerEllipse* from the PyA's pyasl to calculate a Keplerian orbit. It may be used to fit complete 3d information on the orbit. Projections using only one or two dimensions are also possible. The constructor allows to specify *relevant axes*, which are those axes considered in the calculation. The actual model is, however, only one-dimensional. The values returned by evaluate have the order a1, b1, c1, a2, b2, c3, ... . Where a, b, and c stand for the first, second, and third axis and the number specifies the data point. Note that in this case, the resulting model has not the same number of points as the time axis. *Fit parameters* - `a` - The semi-major axis (same units as the data) - `per` - The period (same time units as data) - `e` - The eccentricity - `tau` - Time of periapsis passage (same time units as data) - `Omega` - Longitude of the ascending node [deg] - `w` - Argument of periapsis [deg] - `i` - Inclination angle [deg] Parameters ---------- relevantAxes : string A string containing any combination of x, y, and z. The string specifies the axes (and their order) to be considered in the calculations. """ def __init__(self, relevantAxes="xyz"): self.ke = KeplerEllipse(1.0, 1.0) fuf.OneDFit.__init__(self, ["a", "per", "e", "tau", "Omega", "w", "i"]) self["a"] = 1.0 self["per"] = 1.0 # Which axes to consider? # x=0, y=1, z=2 self.axes = () for i, axis in enumerate("xyz"): if axis in relevantAxes: self.axes += (i,) def evaluate(self, t): """ Calculates and returns model according to the current parameter values. Although more than one axis may be relevant the output will be one dimensional. If, e.g., the relevant axes are x and y, the order of the output will be x0, y0, x1, y1, ... . Parameters ---------- t : array Times at which to evaluate the model. """ self.ke.i = self["i"] self.ke.w = self["w"] self.ke.Omega = self["Omega"] self.ke.e = abs(self["e"]) self.ke.a = self["a"] self.ke.per = self["per"] self.ke.tau = self["tau"] self.ke.n = 2.0*pi/self["per"] # Get the data pertaining to the relevant axes pos = self.ke.xyzPos(t)[::,self.axes] # Reshape to 1d form # If the relevant axes are x and y, the order # of the output will be x0, y0, x1, y1, x2, y2, ... pos = pos.reshape(pos.size) return pos
class KeplerEllipseModel(fuf.OneDFit): """ A model of a Keplerian orbit. This class uses the *KeplerEllipse* from the PyA's pyasl to calculate a Keplerian orbit. It may be used to fit complete 3d position or velocity information on the orbit; any individual axes may also be selected. The constructor allows to specify *relevant axes*, which are those axes considered in the calculation. The actual (technical) model is, however, only one-dimensional. The values returned by evaluate have the order a1, b1, c1, a2, b2, c3, ... . Where a, b, and c represent the first, second, and third axis and the number specifies the data point. Note that in this case, the resulting model has not the same number of points as the time axis. *Fit parameters* - `a` - The semi-major axis (same units as the data) - `per` - The period (same time units as data) - `e` - The eccentricity - `tau` - Time of periapsis passage (same time units as data) - `Omega` - Longitude of the ascending node [deg] - `w` - Argument of periapsis [deg] - `i` - Inclination angle [deg] Parameters ---------- relevantAxes : string A string containing any combination of x, y, and z. The string specifies the axes (and their order) to be considered in the calculations. mode : string, {"pos", "vel"} Determines whether the output is positions or velocities. In this case, the units are determined by the units of major axis and time (e.g., AU per day). """ def __init__(self, relevantAxes="xyz", mode="pos"): self.ke = KeplerEllipse(1.0, 1.0) fuf.OneDFit.__init__(self, ["a", "per", "e", "tau", "Omega", "w", "i"]) self["a"] = 1.0 self["per"] = 1.0 # Which axes to consider? # x=0, y=1, z=2 self.axes = () for i, axis in enumerate("xyz"): if axis in relevantAxes: self.axes += (i, ) # Save the mode if not mode in ["pos", "vel"]: raise(PE.PyAValError("Unknown mode: " + str(mode), \ where="KeplerEllipseModel", \ solution="Choose either 'pos' or 'vel'.")) self._mode = mode def evaluate(self, t): """ Calculates and returns model according to the current parameter values. Although more than one axis may be relevant the output will be one dimensional. If, e.g., the relevant axes are x and y, the order of the output will be x0, y0, x1, y1, ... . Parameters ---------- t : array Times at which to evaluate the model. """ self.ke.i = self["i"] self.ke.w = self["w"] self.ke.Omega = self["Omega"] self.ke.e = abs(self["e"]) self.ke.a = self["a"] self.ke.per = self["per"] self.ke.tau = self["tau"] self.ke.n = 2.0 * pi / self["per"] # Get the data pertaining to the relevant axes if self._mode == "pos": result = self.ke.xyzPos(t)[::, self.axes] else: result = self.ke.xyzVel(t)[::, self.axes] # Reshape to 1d form # If the relevant axes are x and y, the order # of the output will be x0, y0, x1, y1, x2, y2, ... result = result.reshape(result.size) return result
class KeplerEllipseModel(fuf.OneDFit): """ A model of a Keplerian orbit. This class uses the *KeplerEllipse* from the PyA's pyasl to calculate a Keplerian orbit. It may be used to fit complete 3d information on the orbit. Projections using only one or two dimensions are also possible. The constructor allows to specify *relevant axes*, which are those axes considered in the calculation. The actual model is, however, only one-dimensional. The values returned by evaluate have the order a1, b1, c1, a2, b2, c3, ... . Where a, b, and c stand for the first, second, and third axis and the number specifies the data point. Note that in this case, the resulting model has not the same number of points as the time axis. *Fit parameters* - `a` - The semi-major axis (same units as the data) - `per` - The period (same time units as data) - `e` - The eccentricity - `tau` - Time of periapsis passage (same time units as data) - `Omega` - Longitude of the ascending node [deg] - `w` - Argument of periapsis [deg] - `i` - Inclination angle [deg] Parameters ---------- relevantAxes : string A string containing any combination of x, y, and z. The string specifies the axes (and their order) to be considered in the calculations. """ def __init__(self, relevantAxes="xyz"): self.ke = KeplerEllipse(1.0, 1.0) fuf.OneDFit.__init__(self, ["a", "per", "e", "tau", "Omega", "w", "i"]) self["a"] = 1.0 self["per"] = 1.0 # Which axes to consider? # x=0, y=1, z=2 self.axes = () for i, axis in enumerate("xyz"): if axis in relevantAxes: self.axes += (i, ) def evaluate(self, t): """ Calculates and returns model according to the current parameter values. Although more than one axis may be relevant the output will be one dimensional. If, e.g., the relevant axes are x and y, the order of the output will be x0, y0, x1, y1, ... . Parameters ---------- t : array Times at which to evaluate the model. """ self.ke.i = self["i"] self.ke.w = self["w"] self.ke.Omega = self["Omega"] self.ke.e = abs(self["e"]) self.ke.a = self["a"] self.ke.per = self["per"] self.ke.tau = self["tau"] self.ke.n = 2.0 * pi / self["per"] # Get the data pertaining to the relevant axes pos = self.ke.xyzPos(t)[::, self.axes] # Reshape to 1d form # If the relevant axes are x and y, the order # of the output will be x0, y0, x1, y1, x2, y2, ... pos = pos.reshape(pos.size) return pos
class KeplerEllipseModel(fuf.OneDFit): """ A model of a Keplerian orbit. This class uses the *KeplerEllipse* from the PyA's pyasl to calculate a Keplerian orbit. It may be used to fit complete 3d position or velocity information on the orbit; any individual axes may also be selected. The constructor allows to specify *relevant axes*, which are those axes considered in the calculation. The actual (technical) model is, however, only one-dimensional. The values returned by evaluate have the order a1, b1, c1, a2, b2, c3, ... . Where a, b, and c represent the first, second, and third axis and the number specifies the data point. Note that in this case, the resulting model has not the same number of points as the time axis. *Fit parameters* - `a` - The semi-major axis (same units as the data) - `per` - The period (same time units as data) - `e` - The eccentricity - `tau` - Time of periapsis passage (same time units as data) - `Omega` - Longitude of the ascending node [deg] - `w` - Argument of periapsis [deg] - `i` - Inclination angle [deg] Parameters ---------- relevantAxes : string A string containing any combination of x, y, and z. The string specifies the axes (and their order) to be considered in the calculations. mode : string, {"pos", "vel"} Determines whether the output is positions or velocities. In this case, the units are determined by the units of major axis and time (e.g., AU per day). """ def __init__(self, relevantAxes="xyz", mode="pos"): self.ke = KeplerEllipse(1.0, 1.0) fuf.OneDFit.__init__(self, ["a", "per", "e", "tau", "Omega", "w", "i"]) self["a"] = 1.0 self["per"] = 1.0 # Which axes to consider? # x=0, y=1, z=2 self.axes = () for i, axis in enumerate("xyz"): if axis in relevantAxes: self.axes += (i,) # Save the mode if not mode in ["pos", "vel"]: raise(PE.PyAValError("Unknown mode: " + str(mode), \ where="KeplerEllipseModel", \ solution="Choose either 'pos' or 'vel'.")) self._mode = mode def evaluate(self, t): """ Calculates and returns model according to the current parameter values. Although more than one axis may be relevant the output will be one dimensional. If, e.g., the relevant axes are x and y, the order of the output will be x0, y0, x1, y1, ... . Parameters ---------- t : array Times at which to evaluate the model. """ self.ke.i = self["i"] self.ke.w = self["w"] self.ke.Omega = self["Omega"] self.ke.e = abs(self["e"]) self.ke.a = self["a"] self.ke.per = self["per"] self.ke.tau = self["tau"] self.ke.n = 2.0 * pi / self["per"] # Get the data pertaining to the relevant axes if self._mode == "pos": result = self.ke.xyzPos(t)[::, self.axes] else: result = self.ke.xyzVel(t)[::, self.axes] # Reshape to 1d form # If the relevant axes are x and y, the order # of the output will be x0, y0, x1, y1, x2, y2, ... result = result.reshape(result.size) return result