Source code for eureka.S5_lightcurve_fitting.models.SinusoidPhaseCurve

import numpy as np
try:
    import batman
except ImportError:
    print("Could not import batman. Functionality may be limited.")

from .Model import Model
from ...lib.readEPF import Parameters


[docs]class SinusoidPhaseCurveModel(Model): """A sinusoidal phase curve model""" def __init__(self, transit_model=None, eclipse_model=None, **kwargs): """Initialize the phase curve model. Parameters ---------- transit_model : eureka.S5_lightcurve_fitting.models.Model; optional The transit model to use for this phase curve model. Defaults to None. eclipse_model : eureka.S5_lightcurve_fitting.models.Model; optional The eclipse model to use for this phase curve model. Defaults to None. **kwargs : dict Additional parameters to pass to eureka.S5_lightcurve_fitting.models.Model.__init__(). Can pass in the parameters, longparamlist, nchan, and paramtitles arguments here. """ # Inherit from Model calss super().__init__(**kwargs) # Define model type (physical, systematic, other) self.modeltype = 'physical' # Check for Parameters instance self.parameters = kwargs.get('parameters') # Generate parameters from kwargs if necessary if self.parameters is None: self.parameters = Parameters(**kwargs) # Set parameters for multi-channel fits self.longparamlist = kwargs.get('longparamlist') self.nchan = kwargs.get('nchan') self.paramtitles = kwargs.get('paramtitles') self.components = None self.transit_model = transit_model self.eclipse_model = eclipse_model if transit_model is not None: self.components = [self.transit_model, ] if eclipse_model is not None: if self.components is None: self.components = [self.eclipse_model, ] else: self.components.append(self.eclipse_model) @property def time(self): """A getter for the time.""" return self._time @time.setter def time(self, time_array): """A setter for the time.""" self._time = time_array if self.transit_model is not None: self.transit_model.time = time_array if self.eclipse_model is not None: self.eclipse_model.time = time_array
[docs] def update(self, newparams, names, **kwargs): """Update the model with new parameter values. Parameters ---------- newparams : ndarray New parameter values. names : list Parameter names. **kwargs : dict Additional parameters to pass to eureka.S5_lightcurve_fitting.models.Model.update(). """ super().update(newparams, names, **kwargs) if self.transit_model is not None: self.transit_model.update(newparams, names, **kwargs) if self.eclipse_model is not None: self.eclipse_model.update(newparams, names, **kwargs)
[docs] def eval(self, **kwargs): """Evaluate the function with the given values. Parameters ---------- **kwargs : dict Must pass in the time array here if not already set. Returns ------- lcfinal : ndarray The value of the model at the times self.time. """ # Get the time if self.time is None: self.time = kwargs.get('time') # Initialize model bm_params = batman.TransitParams() pc_params = {'AmpCos1': 0., 'AmpSin1': 0., 'AmpCos2': 0., 'AmpSin2': 0.} # Set all parameters lcfinal = np.array([]) for c in np.arange(self.nchan): # Set all parameters for index, item in enumerate(self.longparamlist[c]): if np.any([key in item for key in pc_params.keys()]): pc_params[self.paramtitles[index]] = \ self.parameters.dict[item][0] else: setattr(bm_params, self.paramtitles[index], self.parameters.dict[item][0]) bm_params.limb_dark = 'uniform' bm_params.u = [] m_transit = None if not np.any(['t_secondary' in key for key in self.longparamlist[c]]): # If not explicitly fitting for the time of eclipse, get the # time of eclipse from the time of transit, period, # eccentricity, and argument of periastron m_transit = batman.TransitModel(bm_params, self.time, transittype='primary') t_secondary = m_transit.get_t_secondary(bm_params) else: t_secondary = self.parameters.dict['t_secondary'][0] if self.parameters.dict['ecc'][0] == 0.: # the planet is on a circular orbit t = self.time - t_secondary freq = 2.*np.pi/self.parameters.dict['per'][0] phi = (freq*t) else: if m_transit is None: # Avoid overhead of making a new transit model if avoidable m_transit = batman.TransitModel(bm_params, self.time, transittype='primary') anom = m_transit.get_true_anomaly() w = self.parameters.dict['w'][0] # the planet is on an eccentric orbit phi = anom + w*np.pi/180. + np.pi/2. # calculate the phase variations if pc_params['AmpCos2'] == 0. and pc_params['AmpSin2'] == 0.: # Skip multiplying by a bunch of zeros to speed up fitting phaseVars = (1. + pc_params['AmpCos1']*(np.cos(phi)-1.) + pc_params['AmpSin1']*np.sin(phi)) else: phaseVars = (1. + pc_params['AmpCos1']*(np.cos(phi)-1.) + pc_params['AmpSin1']*np.sin(phi) + pc_params['AmpCos2']*(np.cos(2.*phi)-1.) + pc_params['AmpSin2']*np.sin(2.*phi)) lcfinal = np.append(lcfinal, phaseVars) transit = self.transit_model.eval() eclipse = self.eclipse_model.eval() return transit + lcfinal*(eclipse-1)