petitRADTRANS.physics
=====================

.. py:module:: petitRADTRANS.physics

.. autoapi-nested-parse::

   Stores useful physical functions.



Functions
---------

.. autoapisummary::

   petitRADTRANS.physics.compute_dist
   petitRADTRANS.physics.compute_effective_temperature
   petitRADTRANS.physics.power_law_temperature_profile
   petitRADTRANS.physics.cubic_spline_profile
   petitRADTRANS.physics.doppler_shift
   petitRADTRANS.physics.flux_cm2flux_hz
   petitRADTRANS.physics.flux_hz2flux_cm
   petitRADTRANS.physics.flux2irradiance
   petitRADTRANS.physics.frequency2wavelength
   petitRADTRANS.physics.hz2um
   petitRADTRANS.physics.linear_spline_profile
   petitRADTRANS.physics.make_press_temp
   petitRADTRANS.physics.make_press_temp_iso
   petitRADTRANS.physics.madhu_seager_2009
   petitRADTRANS.physics.planck_function_cm
   petitRADTRANS.physics.planck_function_hz
   petitRADTRANS.physics.planck_function_hz_temperature_derivative
   petitRADTRANS.physics.rebin_spectrum
   petitRADTRANS.physics.rebin_spectrum_bin
   petitRADTRANS.physics.temperature_profile_function_guillot
   petitRADTRANS.physics.temperature_profile_function_guillot_dayside
   petitRADTRANS.physics.temperature_profile_function_guillot_global
   petitRADTRANS.physics.temperature_profile_function_guillot_global_ret
   petitRADTRANS.physics.temperature_profile_function_guillot_metallic
   petitRADTRANS.physics.temperature_profile_function_guillot_modif
   petitRADTRANS.physics.temperature_profile_function_isothermal
   petitRADTRANS.physics.temperature_profile_function_ret_model
   petitRADTRANS.physics.temperature_curvature_prior
   petitRADTRANS.physics.dtdp_temperature_profile
   petitRADTRANS.physics.um2hz
   petitRADTRANS.physics.wavelength2frequency


Module Contents
---------------

.. py:function:: compute_dist(t_irr, dist, t_star, r_star, mode, mode_what)

.. py:function:: compute_effective_temperature(wavelengths: numpy.typing.NDArray, flux: numpy.typing.NDArray, orbit_semi_major_axis: float = 1.0, planet_radius: float = 1.0, use_si_units: bool = False) -> float

   Calculates the effective temperature by integrating the model and using the stefan boltzmann law.

   Args:
       wavelengths : numpy.ndarray
           Wavelength grid
       flux : numpy.ndarray
           Flux density grid
       orbit_semi_major_axis : Optional(float)
           Distance to the object. Must have same units as planet_radius
       planet_radius : Optional(float)
           Object radius. Must have same units as orbit_semi_major_axis
       use_si_units : Optional(bool)
           If the flux is in W/m2/micron, this should be true


.. py:function:: power_law_temperature_profile(press: numpy.typing.NDArray, alpha: float, T0: float) -> numpy.typing.NDArray

   Compute a power law profile for temperature; log(T) = a*log(P) + b.

   This function computes a cubic spline profile for temperature using
   pressure and temperature data points, along with a curvature prior.

   Args:
       press (array-like): An array or list of pressure data points.
       alpha (float): power law exponent (how steep is the profile)
       T0 (float): multiplicative factor (offsets the profile)

   Returns:
       temperatures (array): temperature values for each pressure value


.. py:function:: cubic_spline_profile(press: numpy.typing.NDArray, temperature_points: numpy.typing.NDArray, gamma: float, nnodes: int = 0) -> tuple[numpy.typing.NDArray, float]

   Compute a cubic spline profile for temperature based on pressure points.

   This function computes a cubic spline profile for temperature using
   pressure and temperature data points, along with a curvature prior.

   Args:
       press (array-like): An array or list of pressure data points.
       temperature_points (array-like): An array or list of temperature data points.
       gamma (float): A parameter controlling the curvature of the spline.
       nnodes (int, optional): Number of nodes to use in the spline interpolation.
           Defaults to 0, which means automatic determination of nodes.

   Returns:
       tuple: A tuple containing two elements:
           - interpolated_temps (array-like): Interpolated temperature values
             based on the cubic spline.
           - prior (array-like): Curvature prior values calculated for the spline.


.. py:function:: doppler_shift(wavelength_0: numpy.typing.NDArray | float, velocity: numpy.typing.NDArray | float) -> numpy.typing.NDArray | float

   Calculate the Doppler-shifted wavelength for electromagnetic waves.

   A negative velocity means that the source is going toward the observer. A positive velocity means the source is
   going away from the observer.

   Args:
       wavelength_0: (cm) wavelength of the wave in the referential of the source
       velocity: (cm.s-1) velocity of the source relative to the observer

   Returns:
       (cm) the wavelength of the source as measured by the observer


.. py:function:: flux_cm2flux_hz(flux_cm: numpy.typing.NDArray | float, wavelength: numpy.typing.NDArray | float) -> numpy.typing.NDArray | float

   Convert a flux from [flux units]/cm to [flux units]/Hz at a given wavelength.
   Flux units can be, e.g., erg.s-1.cm-2.

   Steps:
       [cm] = c[cm.s-1] / [Hz]
       => d[cm]/d[Hz] = d(c / [Hz])/d[Hz]
       => d[cm]/d[Hz] = c / [Hz]**2
       integral of flux must be conserved: flux_cm * d[cm] = flux_hz * d[Hz]
       flux_hz = flux_cm * d[cm]/d[Hz]
       => flux_hz = flux_cm * wavelength**2 / c

   Args:
       flux_cm: ([flux units]/cm)
       wavelength: (cm)

   Returns:
       ([flux units]/Hz) the radiosity in converted units


.. py:function:: flux_hz2flux_cm(flux_hz: numpy.typing.NDArray | float, frequency: numpy.typing.NDArray | float) -> numpy.typing.NDArray | float

   Convert a flux from [flux units]/Hz to [flux units]/cm at a given frequency.
   Flux units can be, e.g., erg.s-1.cm-2.

   Steps:
       [cm] = c[cm.s-1] / [Hz]
       => d[cm]/d[Hz] = d(c / [Hz])/d[Hz]
       => d[cm]/d[Hz] = c / [Hz]**2
       => d[Hz]/d[cm] = [Hz]**2 / c
       integral of flux must be conserved: flux_cm * d[cm] = flux_hz * d[Hz]
       flux_cm = flux_hz * d[Hz]/d[cm]
       => flux_cm = flux_hz * frequency**2 / c

   Args:
       flux_hz: (erg.s-1.cm-2.sr-1/Hz)
       frequency: (Hz)

   Returns:
       (erg.s-1.cm-2.sr-1/cm) the radiosity in converted units


.. py:function:: flux2irradiance(flux: numpy.typing.NDArray | float, source_radius: float, target_distance: float) -> numpy.typing.NDArray | float

   Calculate the spectral irradiance of a spherical source on a target from its flux (spectral radiosity).

   Args:
       flux: (M.L-1.T-3) flux of the source
       source_radius: (L) radius of the spherical source
       target_distance: (L) distance from the source to the target

   Returns:
       The irradiance of the source on the target (M.L-1.T-3).


.. py:function:: frequency2wavelength(frequency: numpy.typing.NDArray | float) -> numpy.typing.NDArray | float

   Convert frequencies into wavelength in centimeter.

   Args:
       frequency: frequency: (Hz) the frequency to convert

   Returns:
       (cm) the corresponding wavelengths


.. py:function:: hz2um(frequency: numpy.typing.NDArray | float) -> numpy.typing.NDArray | float

   Convert frequencies into wavelengths in micrometer.

   Args:
       frequency: (Hz) the frequency to convert

   Returns:
       (um) the corresponding wavelengths


.. py:function:: linear_spline_profile(press: numpy.typing.NDArray, temperature_points: numpy.typing.NDArray, gamma: float, nnodes: int = 0) -> tuple[numpy.typing.NDArray, float]

   Compute a linear spline profile for temperature based on pressure points.

   This function computes a linear spline profile for temperature using
   pressure and temperature data points, along with a curvature prior.

   Args:
       press (array-like): An array or list of pressure data points.
       temperature_points (array-like): An array or list of temperature data points.
       gamma (float): A parameter controlling the curvature of the spline.
       nnodes (int, optional): Number of nodes to use in the spline interpolation.
           Defaults to 0, which means automatic determination of nodes.

   Returns:
       tuple: A tuple containing two elements:
           - interpolated_temps (array-like): Interpolated temperature values
             based on the linear spline.
           - prior (array-like): Curvature prior values calculated for the spline.


.. py:function:: make_press_temp(rad_trans_params)

   Function to make temp


.. py:function:: make_press_temp_iso(rad_trans_params)

   Function to make temp


.. py:function:: madhu_seager_2009(pressures, log_pressure_points, T_set, alpha_points, beta_points)

   Calculate temperatures based on the Madhusudhan and Seager (2009) parameterization.

   This function computes temperatures using the Madhu and Seager (2009) parameterization
   for a given set of pressure values, pressure breakpoints, temperature breakpoints,
   alpha values, and beta values.

   Based off of the POSEIDON implementation:
   https://github.com/MartianColonist/POSEIDON/blob/main/POSEIDON/atmosphere.py

   Parameters:
       pressures : (numpy.ndarray)
           An array of pressure values (in bar) at which to calculate temperatures.
       log_pressure_points : (list)
           A list of log10 pressure breakpoints defining different temperature regimes.
           The zeroth element is the minimum pressure, should be log10(press[0]).
           The first element is the 1-2 boundary
           The second element is the level of the inversion
           The third element is the 2-3 boundary.
           The fourth element is the pressure at which the temperature is set (P_set).
       T_set : (float)
           A temperature at log_pressure_points[4] used to constrain the temperature profile.
       alpha_points : (list)
           A list of alpha values used in the parameterization for different regimes.
           Must have length 2.
       beta_points : (list)
           A list of beta values used in the parameterization for different regimes.
           By default, b[0] == b[1] == 0.5, unclear how well this will work if these aren't used!
           Must have length 2.

   Returns:
       temperatures : (numpy.ndarray)
           An array of calculated temperatures (in K) corresponding to the input pressure values.

   Reference:
   - Madhusudhan, N., & Seager, S. (2009). A Temperature and Abundance Retrieval Method for Exoplanet Atmospheres.
     The Astrophysical Journal, 707(1), 24-39. https://doi.org/10.1088/0004-637X/707/1/24


.. py:function:: planck_function_cm(temperature: float, wavelength: numpy.typing.NDArray | float) -> numpy.typing.NDArray | float

   Returns the Planck function :math:`B_{\lambda}(T)` in units of
   :math:`\rm erg/s/cm^2/cm/steradian`.

   Args:
       temperature (float):
           Temperature in K.
       wavelength:
           Array containing the wavelength in cm.


.. py:function:: planck_function_hz(temperature: float, frequency: numpy.typing.NDArray | float) -> numpy.typing.NDArray | float

   Returns the Planck function :math:`B_{\nu}(T)` in units of
   :math:`\rm erg/s/cm^2/Hz/steradian`.

   Args:
       temperature (float):
           Temperature in K.
       frequency:
           Array containing the frequency in Hz.


.. py:function:: planck_function_hz_temperature_derivative(temperature: float, frequency: numpy.typing.NDArray | float) -> numpy.typing.NDArray | float

   Returns the derivative of the Planck function with respect to the temperature in units of
   :math:`\rm erg/s/cm^2/Hz/steradian`.
   # TODO unused?

   Args:
       temperature:
           Temperature in K.
       frequency:
           Array containing the frequency in Hz.
   Returns:



.. py:function:: rebin_spectrum(input_wavelengths: numpy.typing.NDArray, input_spectrum: numpy.typing.NDArray, rebinned_wavelengths: numpy.typing.NDArray) -> numpy.typing.NDArray

   Re-bin the spectrum using the Fortran rebin_spectrum function, and catch errors occurring there.
   The fortran rebin function raises non-blocking errors. In that case, the function outputs an array of -1.

   Args:
       input_wavelengths: wavelengths of the input spectrum
       input_spectrum: spectrum to re-bin
       rebinned_wavelengths: wavelengths to re-bin the spectrum to. Must be contained within input_wavelengths

   Returns:
       The re-binned spectrum on the re-binned wavelengths


.. py:function:: rebin_spectrum_bin(input_wavelengths: numpy.typing.NDArray, input_spectrum: numpy.typing.NDArray, rebinned_wavelengths: numpy.typing.NDArray, bin_widths: numpy.typing.NDArray) -> numpy.typing.NDArray

   Re-bin the spectrum using the Fortran rebin_spectrum_bin function, and catch errors occurring there.
   The fortran rebin function raises non-blocking errors. In that case, the function outputs an array of -1.

   Args:
       input_wavelengths: wavelengths of the input spectrum
       input_spectrum: spectrum to re-bin
       rebinned_wavelengths: wavelengths to re-bin the spectrum to. Must be contained within input_wavelengths
       bin_widths: bin widths of the wavelengths to re-bin the spectrum to.

   Returns:
       The re-binned spectrum on the re-binned wavelengths


.. py:function:: temperature_profile_function_guillot(pressures: numpy.typing.NDArray, infrared_mean_opacity: float, gamma: float, gravities: numpy.typing.NDArray, intrinsic_temperature: float, equilibrium_temperature: float, redistribution_coefficient: float = 0.25) -> numpy.typing.NDArray

   Returns a temperature array, in units of K,
   of the same dimensions as the pressure P
   (in bar).

   For this the temperature model of Guillot (2010) is used (his Equation 29).
   Source: https://doi.org/10.1051/0004-6361/200913396

   Args:
       pressures:
           numpy array of floats, containing the input pressure in bars.
       infrared_mean_opacity:
           The infrared mean opacity in units of :math:`\rm cm^2/s`.
       gamma:
           The ratio between the visual and infrared mean opacities.
       gravities:
           The planetary gravity at the given pressures in units of :math:`\rm cm/s^2`.
       intrinsic_temperature:
           The planetary intrinsic temperature (in units of K).
       equilibrium_temperature:
           The planetary equilibrium temperature (in units of K).
       redistribution_coefficient:
           The redistribution coefficient of the irradiance. A value of 1 corresponds to the substellar point, 1/2 for
           the day-side average and 1/4 for the global average.


.. py:function:: temperature_profile_function_guillot_dayside(pressures: numpy.typing.NDArray, infrared_mean_opacity: float, gamma: float, gravities: numpy.typing.NDArray, intrinsic_temperature: float, equilibrium_temperature: float) -> numpy.typing.NDArray

   Returns a temperature array, in units of K,
   of the same dimensions as the pressure P
   (in bar). For this the temperature model of Guillot (2010)
   is used (his Equation 29), in the case of averaging the flux over the day side of the planet.

   Args:
       pressures:
           numpy array of floats, containing the input pressure in bars.
       infrared_mean_opacity (float):
           The infrared opacity in units of :math:`\rm cm^2/s`.
       gamma (float):
           The ratio between the visual and infrared opacity.
       gravities (float):
           The planetary surface gravity in units of :math:`\rm cm/s^2`.
       intrinsic_temperature (float):
           The planetary internal temperature (in units of K).
       equilibrium_temperature (float):
           The planetary equilibrium temperature (in units of K).


.. py:function:: temperature_profile_function_guillot_global(pressures: numpy.typing.NDArray, infrared_mean_opacity: float, gamma: float, gravities: numpy.typing.NDArray, intrinsic_temperature: float, equilibrium_temperature: float) -> numpy.typing.NDArray

   Returns a temperature array, in units of K,
   of the same dimensions as the pressure P
   (in bar). For this the temperature model of Guillot (2010)
   is used (his Equation 29), in the case of averaging the flux over the whole planetary surface.

   Args:
       pressures:
           numpy array of floats, containing the input pressure in bars.
       infrared_mean_opacity (float):
           The infrared opacity in units of :math:`\rm cm^2/s`.
       gamma (float):
           The ratio between the visual and infrared opacity.
       gravities (float):
           The planetary surface gravity in units of :math:`\rm cm/s^2`.
       intrinsic_temperature (float):
           The planetary internal temperature (in units of K).
       equilibrium_temperature (float):
           The planetary equilibrium temperature (in units of K).


.. py:function:: temperature_profile_function_guillot_global_ret(pressures: numpy.typing.NDArray, delta: float, gamma: float, intrinsic_temperature: float, equilibrium_temperature: float) -> numpy.typing.NDArray

   Global Guillot P-T formula with kappa/gravity replaced by delta.


.. py:function:: temperature_profile_function_guillot_metallic(pressures: numpy.typing.NDArray, gamma: float, reference_gravity: numpy.typing.NDArray, intrinsic_temperature: float, equilibrium_temperature: float, infrared_mean_opacity_solar_metallicity: float, metallicity: float | None = None) -> numpy.typing.NDArray

   Get a Guillot temperature profile depending on metallicity.

   Args:
       pressures: (bar) pressures of the profile
       gamma: ratio between visual and infrared opacity
       reference_gravity: (cm.s-2) surface gravity
       intrinsic_temperature: (K) intrinsic temperature
       equilibrium_temperature: (K) equilibrium temperature
       infrared_mean_opacity_solar_metallicity:
           (cm2.s-1) infrared mean opacity for a solar metallicity (Z = 1) atmosphere
       metallicity: ratio of heavy elements abundance over H abundance with respect to the solar ratio

   Returns:
       temperatures: (K) the temperature at each pressures of the atmosphere


.. py:function:: temperature_profile_function_guillot_modif(pressures: numpy.typing.NDArray, delta: float, gamma: float, intrinsic_temperature: float, equilibrium_temperature: float, ptrans: float, alpha: float) -> numpy.typing.NDArray

   Modified Guillot P-T formula


.. py:function:: temperature_profile_function_isothermal(pressures: numpy.typing.NDArray, temperature: float) -> numpy.typing.NDArray

.. py:function:: temperature_profile_function_ret_model(rad_trans_params)

   Self-luminous retrieval P-T model.

   Args:
       t3 : np.array([t1, t2, t3])
           temperature points to be added on top
           radiative Eddington structure (above tau = 0.1).
           Use spline interpolation, t1 < t2 < t3 < tconnect as prior.
       delta : float
           proportionality factor in tau = delta * press_cgs**alpha
       alpha : float
           power law index in tau = delta * press_cgs**alpha
           For the tau model: use proximity to kappa_rosseland photosphere
           as prior.
       tint : float
           internal temperature of the Eddington model
       press : np.ndarray
           input pressure profile in bar
       conv : bool
           enforce convective adiabat yes/no
       co_ratio : float
           C/O for the nabla_ad interpolation
       metallicity : float
           metallicity for the nabla_ad interpolation
   Returns:
       Tret : np.ndarray
           The temperature as a function of atmospheric pressure.


.. py:function:: temperature_curvature_prior(press, temps, gamma)

   Compute a curvature prior for a temperature-pressure profile.

   This function calculates a curvature prior for a temperature-pressure profile,
   penalizing deviations from a smooth, low-curvature profile, based on Line 2015

   Args:
       press (array-like): An array or list of pressure data points.
       temps (array-like): An array or list of temperature data points.
       gamma (float): The curvature penalization factor.

   Returns:
       float: The curvature prior value.


.. py:function:: dtdp_temperature_profile(press, num_layer, layer_pt_slopes, t_bottom, top_of_atmosphere_pressure=-3, bottom_of_atmosphere_pressure=3)

   This function takes the temperature gradient at a set number of spline points and interpolates a temperature
   profile as a function of pressure.

   Args:
       press : array_like
           The pressure array.
       num_layer : int
           The number of layers. Default for covering 10^3 to 10^-3 bar as in Zhang 2023 is 6.
           To cover 10^3 to 10^-6 bar 10 is recommended.
       layer_pt_slopes : array_like
           The temperature gradient at the spline points.
       t_bottom : float
           The temperature at the bottom of the atmosphere.
       top_of_atmosphere_pressure : float
           Minimum atmospheric pressure in log bar. If the pressure array extends beyond this value, the
           temperature structure at lower pressures than this value will be isothermal.
       bottom_of_atmosphere_pressure : float
           Maximum atmospheric pressure in log bar.

   Returns:
       temperatures : array_like
           The temperature profile.


.. py:function:: um2hz(wavelength: numpy.typing.NDArray | float) -> numpy.typing.NDArray | float

   Convert wavelengths in micrometer into frequencies.

   Args:
       wavelength: (um) the wavelengths to convert

   Returns:
       (Hz) the corresponding frequencies


.. py:function:: wavelength2frequency(wavelength: numpy.typing.NDArray | float) -> numpy.typing.NDArray | float

   Convert wavelengths in centimeter to frequencies.

   Args:
       wavelength: (cm) the wavelengths to convert

   Returns:
       (Hz) the converted frequencies


