Source code for sofia_redux.calibration.standard_model.thermast

# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""Generate a themeral model of an asteroid"""

import numpy as np
from scipy import integrate as si


[docs] def thermast(Gmag, pV, rsize, phang, dsun, dist, nw=500): """ Create a model of the thermal flux from an asteroid. Follow the process outlined in Delbo and Harris, 2002. Parameters ---------- Gmag : float Magnitude slope constant. pV : float Albedo of the asteroid in V band. rsize : float Radius of the asteroid in km. phang : float Phase angle of the asteroid in degrees. dsun : float Distance between the Sun and the asteroid in AU. dist : float Distance between the Earth and the asteroid in AU. nw : int, optional Number of wavelength data points to generate. Defaults to 2500. Returns ------- warr : numpy.array Array of length `nw` containing the wavelength data. flux : numpy.arry Array of length `nw` containing the flux emitted by the asteroid at each wavelength in `warr`. """ # Define constants c = 2.9979e14 # micros/sec stefan_boltzmann = 5.67051e-5 # erg/cm2/s/K^4 solar_constant = 0.1368e7 # erg/cm2/s au = 1.49598e8 # km / 1 AU W2Jy = 1.0e-26 # W/m2/Hz/Jy eta = 0.756 # beaming factor emissivity = 0.90 # emissivity correction = correction_factor(phase_angle=phang) # Convert distance from AU to km dist *= au # Create wavelength array wmin = 1.0 wmax = 300.0 warr = np.linspace(wmin, wmax, nw) qint = 0.290 + 0.684 * Gmag alb_bond = qint * pV subsolar_temp_max = ((1.0 - alb_bond) * solar_constant / (emissivity * stefan_boltzmann * eta * dsun ** 2)) ** 0.25 omin = 0. omax = np.pi / 2. # For each wavelength, integrate over angle to get the # total flux fnu = flux_at_w(warr, subsolar_temp_max, omin, omax) fnu *= 2. * np.pi * emissivity * correction * (rsize / dist) ** 2 fnu *= warr * warr / (c * W2Jy) return warr, fnu
[docs] def correction_factor(phase_angle): """ Calculate correction factor from asteroid's phase angle. Allows the STM to be used at non-zero solar phase angles, taken from Lebofsky et al. (1986). Parameters ---------- phase_angle : float Phase angle of the asteroid in degrees. Returns ------- correction : float Correction factor """ correction = 10.0 ** (-0.01 * np.abs(phase_angle) / 2.5) return correction
[docs] def flux_at_w(warr, subsolar_temperature, omin=0., omax=np.pi / 2.): r""" Calculate the thermal flux from a blackbody object. Parameters ---------- warr : numpy.array Wavelengths to calculate flux at, in microns. subsolar_temperature : float Maximum sub-solar temperature of the asteroid, as given by Equation 9 in Deblo & Harris (2002). omin : float, optional Lower omega limit of integration in radians. Defaults to 0. omax : float Upper omega limit of integration in radians. Defaults to $\pi$/2. Returns ------- flux : numpy.array Wavelength dependent component of the blackbody flux of the object. Notes ----- Implementation of the integral in Equation 10 from Delbo & Harris (2002). .. math:: F_{\lambda} \,=\, \int_{\Omega_{min}}^{\Omega{\max}} d\Omega """ if omin < 0: omin = 0 if omax > np.pi / 2: omax = np.pi / 2 flux = np.zeros_like(warr) for i, w in enumerate(warr): flux[i], _ = si.fixed_quad(bbflux, omin, omax, n=10, args=(subsolar_temperature, w)) return flux
[docs] def bbflux(omega, tss, w): """ Calculate the modified blackbody flux from the asteroid. Parameters ---------- omega : numpy.array Angular distance from the sub-solar point. tss : float Maximum sub-solar temperature of the asteroid in Kelvins. w : float Wavelength in microns. Returns ------- flux : numpy.array Thermal flux as a function of `omega`. Notes ----- This function computes the integrand of Equation 10 from Delbo & Harris (2002). """ temp = tss * np.cos(omega) ** 0.25 flux = planck_function(w, temp) * np.cos(omega) * np.sin(omega) return flux
[docs] def planck_function(w, temp): """ Evaluate the Planck function. Parameters ---------- w : float, numpy.array Wavelength in microns. temp : float, numpy.array Temperature of object in Kelvins. Returns ------- bb : float, numpy.array The blackbody flux from the object in W/m2/micron/str. """ # Constants h = 6.6261e-27 # ergs-s c = 2.9979e10 # cm/s k = 1.3897e-16 # erg/K # Conversions mu2cm = 1.0e-4 # cm/micron erg2w = 1.0e-7 # W/(erg/s) m2cm = 1.0e2 # cm/m # Convert wavelength to cm wcm = w * mu2cm term1 = 2.0 * h * c * c / (w * (wcm ** 4)) term1 = term1 * erg2w * m2cm * m2cm zterm = h * c / (wcm * k * temp) idx = zterm >= 150. term2 = np.exp(zterm) - 1. bb = term1 / term2 if isinstance(bb, np.ndarray): bb[bb < 0] = 0. bb[idx] = 0. return bb