Source code for pyLIMA.event

# -*- coding: utf-8 -*-
"""
Created on Thu Aug 27 16:39:32 2015

@author: ebachelet
"""

from __future__ import division

import sys
import numpy as np

from pyLIMA import microlfits


[docs]class EventException(Exception): pass
[docs]class Event(object): """ ######## Event module ######## This module create an event object with the informations (attributes) needed for the fits. Attributes : kind : type of event. In general, should be 'Microlensing' (default) name : name of the event. Should be a string. Default is 'Sagittarius A*' ra : right ascension of the event (J2000). Should be a float in degree between 0.0 and 360.0. Default is ra of Sagittarius A, :math:`\\alpha` = 266.416792 from Baker & Sramek 1999ApJ...524..805B dec : declination of the event (J2000). Should be a float in degree between -90 and 90. Default is dec of Sagittarius A, :math:`\\delta` = -29.007806 from Baker & Sramek 1999ApJ...524..805B Teff : effective temperature of the star in Kelvin. Should be a float. Default is 5000.0 K log_g : surface gravity in log10 cgs unit. Should be a float. Default is 4.5 telescopes : list of telescopes names (strings). Default is an empty list. Have to be fill with some telescopes class instances. survey : the reference telescope. Has to be a string, default is 'None'. fits : list of microlfits objects. """ def __init__(self): """ Initialization of the attributes described above. """ self.kind = 'Microlensing' self.name = 'Sagittarius A*' self.ra = 266.416792 self.dec = -29.007806 self.Teff = 5000 # Kelvins self.log_g = 4.5 self.telescopes = [] self.survey = 'None' self.fits = []
[docs] def fit(self, model, method, DE_population_size=10, flux_estimation_MCMC='MCMC', fix_parameters_dictionnary=None, grid_resolution=10, computational_pool=None, binary_regime=None): """Function to fit the event with a model and a method. :param model: the model you want to fit. More details in the microlfits module :param method: the fitting method you want to use. Has to be a string in the available_methods parameter: 'LM' : Levenberg-Marquardt algorithm 'DE' : Differential Evolution algorithm 'MCMC' : Monte-Carlo Markov Chain algorithm More details in the microlfits module A microlfits object is added in the event.fits list. For example, if you request two fits, you will obtain : event.fits=[fit1,fit2] More details in the microlfits module. """ available_kind = ['Microlensing'] available_methods = ['LM', 'DE', 'MCMC', 'GRIDS', 'TRF'] if self.kind not in available_kind: print('ERROR : No possible fit yet for a non microlensing event, sorry :(') raise EventException('Can not fit this event kind') if method not in available_methods: print('ERROR : Wrong method request, has to be a string selected between ' + \ ' or '.join(available_methods) + '') raise EventException('Wrong fit method request') fit = microlfits.MLFits(self) fit.mlfit(model, method, DE_population_size=DE_population_size, flux_estimation_MCMC=flux_estimation_MCMC, fix_parameters_dictionnary=fix_parameters_dictionnary, grid_resolution=grid_resolution, computational_pool=computational_pool, binary_regime=binary_regime) self.fits.append(fit)
[docs] def telescopes_names(self): """Print the the telescope's names contain in the event. """ print([self.telescopes[i].name for i in range(len(self.telescopes))])
[docs] def check_event(self): """Function to check if everything is correctly set before the fit. An ERROR is returned if the check is not successful Should be used before any event_fit function calls First check if the event name is a string. Then check if the right ascension (event.ra) is between 0 and 360 degrees. Then check if the declination (event.dec) is between -90 and 90 degrees. Then check if you have any telescopes ingested. Finally check if your telescopes have a lightcurve attributes different from None. """ if not isinstance(self.name, str): raise EventException('ERROR : The event name (' + str( self.name) + ') is not correct, it has to be a string') if (self.ra > 360) or (self.ra < 0): raise EventException('ERROR : The event ra (' + str( self.ra) + ') is not correct, it has to be a float between 0 and 360 degrees') if (self.dec > 90) or (self.dec < -90): raise EventException('ERROR : The event dec (' + str( self.dec) + ') is not correct, it has to be between -90 and 90 degrees') if len(self.telescopes) == 0: raise EventException('There is no telescope associated to your event, no fit possible!') else: for telescope in self.telescopes: if (len(telescope.lightcurve_magnitude) == 0) & \ (len(telescope.lightcurve_flux) == 0): print('ERROR : There is no associated lightcurve in magnitude or flux with ' \ 'this telescopes : ' \ + telescope.name + ', add one with telescope.lightcurve = your_data') raise EventException('There is no lightcurve associated to the telescope ' + str( telescope.name) + ', no fit possible!') print(sys._getframe().f_code.co_name, ' : Everything looks fine, this event can be fitted')
[docs] def find_survey(self, choice=None): """Function to find the survey telescope in the telescopes list, and put it on the first place (useful for some fits functions). :param choice: the name of the telescope choosing as the survey. Has to be a string. Default is the first telescope. """ self.survey = choice or self.telescopes[0].name names = [telescope.name for telescope in self.telescopes] if any(self.survey in name for name in names): index = np.where(self.survey == np.array(names))[0] sorting = np.arange(0, len(self.telescopes)) sorting = np.delete(sorting, index) sorting = np.insert(sorting, 0, index) self.telescopes = [self.telescopes[i] for i in sorting] else: print('ERROR : There is no telescope names containing ' + self.survey) return
[docs] def lightcurves_in_flux(self, choice='Yes'): """ Transform all telescopes magnitude lightcurves in flux units. :param choice: to clean your lightcurve or not. Has to be a string 'Yes' or 'No'. Defaul is 'Yes'. More details in the telescope module """ for telescope in self.telescopes: telescope.lightcurve_flux = telescope.lightcurve_in_flux(choice)
[docs] def compute_parallax_all_telescopes(self, parallax_model): """ Compute the parallax displacement for all the telescopes, if this is desired in the second order parameter. """ for telescope in self.telescopes: if len(telescope.deltas_positions) == 0: telescope.compute_parallax(self, parallax_model)
[docs] def total_number_of_data_points(self): """ Compute the parallax displacement for all the telescopes, if this is desired in the second order parameter. :return: n_data, the total number of points :rtype: float """ n_data = 0.0 for telescope in self.telescopes: n_data = n_data + telescope.n_data('flux') return n_data