# Path: orb/utils/astrometry.py
# class Gaussian(PSF):
#     """Class implementing the gaussian profile
# 
#     .. note:: The Gaussian profile used here is:
#       :math:`f(x,y) = H + A \\times \exp(\\frac{-r^2}{2 W^2})`
# 
#       and,
#       :math:`r = (x - dx)^2 + (y - dy)^2`
#       
#       The total flux F under the 2D profile is:
#       :math:`F = 2 \\pi A W^2`
#     
#     """
# 
# 
#     input_params = list(['height', 'amplitude', 'x', 'y', 'fwhm'])
#     """Keys of the input parameters"""
#     
#     params = dict()
#     """dictionary containing the parameters of the profile"""
#     
#     width = None # Width = FWHM / abs(2.*sqrt(2. * log(2.)))
# 
# 
#     def __init__(self, params):
#         """Init Gaussian profile parameters
# 
#         :param params: Input parameters of the Gaussian profile. Input
#           parameters can be given as a dictionary providing {'height',
#           'amplitude', 'x', 'y', 'fwhm'} or an array of 5
#           elements stored in this order: ['height', 'amplitude', 'x',
#           'y', 'fwhm']
#         """
#         
#         self.params = dict()
#         if isinstance(params, dict):
#             if (set([key for key in params.keys()])
#                 & set(self.input_params) == set(self.input_params)):
#                 self.params['height'] = float(params['height'])
#                 self.params['amplitude'] = float(params['amplitude'])
#                 self.params['x'] = float(params['x'])
#                 self.params['y'] = float(params['y'])
#                 self.params['fwhm'] = abs(float(params['fwhm']))
#             else:
#                 raise ValueError("Input dictionary is not valid. You must provide a dictionary containing all those keys : %s"%str(self.input_params))
# 
#         elif (np.size(params) == np.size(self.input_params)):
#             self.params['height'] = float(params[0])
#             self.params['amplitude'] = float(params[1])
#             self.params['x'] = float(params[2])
#             self.params['y'] = float(params[3])
#             self.params['fwhm'] =  abs(float(params[4]))
# 
#         else:
#             raise ValueError('Invalid input parameters')
# 
# 
#         self.width = self.params['fwhm'] / abs(2.*math.sqrt(2. * math.log(2.)))
#         self.params['flux'] = self.flux()
# 
# 
#         # 1-D PSF function
#         self.psf = lambda r: (
#             self.params['height'] + self.params['amplitude']
#             * np.exp(-(r)**2./(2.*self.width**2.)))
#         
#         # 2-D PSF function
#         self.psf2d = lambda x, y: (
#             self.psf(np.sqrt((x-self.params['x'])**2.
#                              +(y-self.params['y'])**2.)))
#         
# 
#     def flux(self):
#         """Return the total flux under the 2D profile.
#         
#         The total flux F under a 2D profile is :
#         :math:`F = 2 \\pi A W^2`
#         
#         .. note:: Under a 1d profile the flux is :math:`F = \\sqrt{2\\pi}A W`
#         """
#         return 2. * self.params['amplitude'] * (self.width)**2 * math.pi
# 
#     def flux_error(self, amplitude_err, width_err):
#         """Return flux error.
#         
#         :param amplitude_err: estimation of the amplitude error
#         
#         :param width_err: estimation of the width error
#         """
#         return self.flux() * math.sqrt(
#             (amplitude_err / self.params['amplitude'])**2.
#             + 2. * (width_err / self.width)**2.)
#     
#     def array2d(self, nx, ny):
#         """Return a 2D profile given the size of the returned
#         array.
#         
#         :param nx: Length of the returned array along x axis
#         :param ny: Length of the returned array along y axis
#         """
#         return np.array(orb.cutils.gaussian_array2d(float(self.params['height']),
#                                                 float(self.params['amplitude']),
#                                                 float(self.params['x']),
#                                                 float(self.params['y']),
#                                                 float(self.params['fwhm']),
#                                                 int(nx), int(ny)))


import logging
import math
import numpy as np
import warnings
import orb.constants
import scipy.interpolate
import scipy.optimize
import orb.utils.spectrum
from orb.utils.astrometry import Gaussian

def compute_photon_energy(nm_axis):
    """Return the photon energy (in erg) computed for all the wavelength along
    a given wavelength axis.

    :param nm_axis: Wavelength axis in nm
    """
    return (orb.constants.PLANCK
            * orb.constants.LIGHT_VEL_KMS * 1e12
            / nm_axis)

def compute_equivalent_bandwidth(nm_axis, filter_transmission):
    """Return the equivalent bandwidth of a given filter.

    :param nm_axis: Filter transmission axis in nm.
    :param filter_transmission: Filter transmission curve
    """
    return np.nansum(np.diff(nm_axis) * filter_transmission[:-1]
                     / np.nanmax(filter_transmission))


def compute_star_central_pixel_value(seeing, plate_scale):
    """Return the relative value of the pixel containing the greatest
    proportion of the flux (central pixel) of Gaussian star.

    :param seeing: Star FWHM in arcsec
    :param plate_scale: Size of the pixels in arcsec.
    """
    N = 100
    fwhm_pix = seeing / plate_scale

# Path: orb/utils/astrometry.py
# class Gaussian(PSF):
#     """Class implementing the gaussian profile
# 
#     .. note:: The Gaussian profile used here is:
#       :math:`f(x,y) = H + A \\times \exp(\\frac{-r^2}{2 W^2})`
# 
#       and,
#       :math:`r = (x - dx)^2 + (y - dy)^2`
#       
#       The total flux F under the 2D profile is:
#       :math:`F = 2 \\pi A W^2`
#     
#     """
# 
# 
#     input_params = list(['height', 'amplitude', 'x', 'y', 'fwhm'])
#     """Keys of the input parameters"""
#     
#     params = dict()
#     """dictionary containing the parameters of the profile"""
#     
#     width = None # Width = FWHM / abs(2.*sqrt(2. * log(2.)))
# 
# 
#     def __init__(self, params):
#         """Init Gaussian profile parameters
# 
#         :param params: Input parameters of the Gaussian profile. Input
#           parameters can be given as a dictionary providing {'height',
#           'amplitude', 'x', 'y', 'fwhm'} or an array of 5
#           elements stored in this order: ['height', 'amplitude', 'x',
#           'y', 'fwhm']
#         """
#         
#         self.params = dict()
#         if isinstance(params, dict):
#             if (set([key for key in params.keys()])
#                 & set(self.input_params) == set(self.input_params)):
#                 self.params['height'] = float(params['height'])
#                 self.params['amplitude'] = float(params['amplitude'])
#                 self.params['x'] = float(params['x'])
#                 self.params['y'] = float(params['y'])
#                 self.params['fwhm'] = abs(float(params['fwhm']))
#             else:
#                 raise ValueError("Input dictionary is not valid. You must provide a dictionary containing all those keys : %s"%str(self.input_params))
# 
#         elif (np.size(params) == np.size(self.input_params)):
#             self.params['height'] = float(params[0])
#             self.params['amplitude'] = float(params[1])
#             self.params['x'] = float(params[2])
#             self.params['y'] = float(params[3])
#             self.params['fwhm'] =  abs(float(params[4]))
# 
#         else:
#             raise ValueError('Invalid input parameters')
# 
# 
#         self.width = self.params['fwhm'] / abs(2.*math.sqrt(2. * math.log(2.)))
#         self.params['flux'] = self.flux()
# 
# 
#         # 1-D PSF function
#         self.psf = lambda r: (
#             self.params['height'] + self.params['amplitude']
#             * np.exp(-(r)**2./(2.*self.width**2.)))
#         
#         # 2-D PSF function
#         self.psf2d = lambda x, y: (
#             self.psf(np.sqrt((x-self.params['x'])**2.
#                              +(y-self.params['y'])**2.)))
#         
# 
#     def flux(self):
#         """Return the total flux under the 2D profile.
#         
#         The total flux F under a 2D profile is :
#         :math:`F = 2 \\pi A W^2`
#         
#         .. note:: Under a 1d profile the flux is :math:`F = \\sqrt{2\\pi}A W`
#         """
#         return 2. * self.params['amplitude'] * (self.width)**2 * math.pi
# 
#     def flux_error(self, amplitude_err, width_err):
#         """Return flux error.
#         
#         :param amplitude_err: estimation of the amplitude error
#         
#         :param width_err: estimation of the width error
#         """
#         return self.flux() * math.sqrt(
#             (amplitude_err / self.params['amplitude'])**2.
#             + 2. * (width_err / self.width)**2.)
#     
#     def array2d(self, nx, ny):
#         """Return a 2D profile given the size of the returned
#         array.
#         
#         :param nx: Length of the returned array along x axis
#         :param ny: Length of the returned array along y axis
#         """
#         return np.array(orb.cutils.gaussian_array2d(float(self.params['height']),
#                                                 float(self.params['amplitude']),
#                                                 float(self.params['x']),
#                                                 float(self.params['y']),
#                                                 float(self.params['fwhm']),
#                                                 int(nx), int(ny)))


# Path: orb/utils/photometry.py
import logging
import math
import numpy as np
import warnings
import orb.constants
import scipy.interpolate
import scipy.optimize
import orb.utils.spectrum
from orb.utils.astrometry import Gaussian


def compute_photon_energy(nm_axis):
    """Return the photon energy (in erg) computed for all the wavelength along
    a given wavelength axis.

    :param nm_axis: Wavelength axis in nm
    """
    return (orb.constants.PLANCK
            * orb.constants.LIGHT_VEL_KMS * 1e12
            / nm_axis)

def compute_equivalent_bandwidth(nm_axis, filter_transmission):
    """Return the equivalent bandwidth of a given filter.

    :param nm_axis: Filter transmission axis in nm.
    :param filter_transmission: Filter transmission curve
    """
    return np.nansum(np.diff(nm_axis) * filter_transmission[:-1]
                     / np.nanmax(filter_transmission))


def compute_star_central_pixel_value(seeing, plate_scale):
    """Return the relative value of the pixel containing the greatest
    proportion of the flux (central pixel) of Gaussian star.

    :param seeing: Star FWHM in arcsec
    :param plate_scale: Size of the pixels in arcsec.
    """
    N = 100
    fwhm_pix = seeing / plate_scale

    star = Gaussian([0,1,N/2,N/2,fwhm_pix]).array2d(N,N)