def evaluate(self, time): """ Calculate a light curve according to the analytical models given by Pal 2008. Parameters ---------- time : array An array of time points at which the light curve shall be calculated. .. note:: time = 0 -> Planet is exactly in the line of sight (phase = 0). Returns ------- Model : array The analytical light curve is stored in the property `lightcurve`. """ # Translate the given parameters into an orbit and, finally, # into a projected, normalized distance (z-parameter) self._calcZList(time - self["T0"]) # 'W' parameters corresponding to notation in Pal '08 w = 6. - 2. * self["linLimb"] - self["quadLimb"] w0 = (6. - 6. * self["linLimb"] - 12. * self["quadLimb"]) / w w1 = (6. * self["linLimb"] + 12. * self["quadLimb"]) / w w2 = 6. * self["quadLimb"] / w # Initialize flux decrease array df = numpy.zeros(len(time)) # Get a list of 'cases' (according to Pal '08). Depends on radius ratio and 'z'-parameter along the orbit ca = self._selectCases() # Loop through z-list, and calculate the light curve at each point in z (->time) for i in self._intrans: # Calculate the coefficients to be substituted into the Pal '08 equation c = self._returnCoeff(ca[i].step, self._zlist[i]) # Substitute the coefficients and get 'flux decrease' if ca[i].step != 12: # Calculate flux decrease only if there is an occultation if not self.useBoost: df[i] = w0 * c[0] + w2 * c[5] + w1 * (c[1] + c[2] * mpmath.ellipk( c[6]**2) + c[3] * mpmath.ellipe(c[6]**2) + c[4] * mpmath.ellippi(c[7], c[6]**2)) else: df[i] = w0 * c[0] + w2 * c[5] + w1 * (c[1] + c[2] * self.ell.ell1( c[6]) + c[3] * self.ell.ell2(c[6]) + c[4] * self.ell.ell3(c[7], c[6])) self.lightcurve = (1. - df) * 1. / \ (1. + self["b"]) + self["b"] / (1.0 + self["b"]) return self.lightcurve
def force_due_to_shell(self, r, z): force = 0; for e1 in [-1, 1]: for e2 in [-1, 1]: m1 = z - 0.5*e1*self.m.l_m - 0.5*e2*self.c.l_c; m2 = ((self.m.r_m - r) / float(m1))**2 + 1; m3 = np.sqrt((self.m.r_m + r)**2 + m1**2); m4 = 4*self.m.r_m*r / float(m3**2); # Different from paper. fs = ( special.ellipk(m4) - 1.0/m2*special.ellipe(m4) + (m1**2 / float(m3**2) - 1) * mpmath.ellippi(m4/float(1-m2), m4)); force += e1*e2*m1*m2*m3*fs; J1 = self.m.B_r; J2 = MU_0*self.c.N_z*self.c.I/float(self.c.l_c); return (J1*J2)/float(2*MU_0) * force;
def OmegaPix(Fnum_x, Fnum_y=None): ''' Calculate the solid angle subtended by an elliptical aperture on-axis. Algorithm from "John T. Conway. Nuclear Instruments and Methods in Physics Research Section A: Accelerators, Spectrometers, Detectors and Associated Equipment, 614(1):17 ? 27, 2010. https://doi.org/10.1016/j.nima.2009.11.075 Equation n. 56 Parameters ---------- Fnum_x : scalar Input F-number along dispersion direction Fnum_y : scalar Optional, input F-number along cross-dispersion direction Returns ------- Omega : scalar The solid angle subtanded by an elliptical aperture in units u.sr ''' if not Fnum_y: Fnum_y = Fnum_x if Fnum_x > Fnum_y: a = 1.0 / (2 * Fnum_y) b = 1.0 / (2 * Fnum_x) else: a = 1.0 / (2 * Fnum_x) b = 1.0 / (2 * Fnum_y) h = 1.0 A = 4.0 * h * b / (a * np.sqrt(h**2 + a**2)) k = np.sqrt((a**2 - b**2) / (h**2 + a**2)) alpha = np.sqrt(1 - (b / a)**2) Omega = 2.0 * np.pi - A * mpmath.ellippi(alpha**2, k**2) return Omega * u.sr