Source code for hgrs.auxdata

import os

import numpy as np
import pandas as pd
import xarray as xr
import rioxarray as rio

import h5py
import netCDF4 as nc
import scipy.interpolate
import scipy.integrate

import matplotlib.pyplot as plt
import cartopy.crs as crs
import cartopy.feature as cf

import datetime

from pkg_resources import resource_filename

opj = os.path.join

# ******************************************************************************************************
dir, filename = os.path.split(__file__)

thuillier_file = resource_filename(__package__, 'data/aux/ref_atlas_thuillier3.nc')
gueymard_file = resource_filename(__package__, 'data/aux/NewGuey2003.dat')
kurucz_file = resource_filename(__package__, 'data/aux/kurucz_0.1nm.dat')
tsis_file = resource_filename(__package__,
                              'data/aux/hybrid_reference_spectrum_p1nm_resolution_c2022-11-30_with_unc.nc')

sunglint_eps_file = resource_filename(__package__, 'data/aux/mean_rglint_small_angles_vza_le_12_sza_le_60.txt')
rayleigh_file = resource_filename(__package__, 'data/aux/rayleigh_bodhaine.txt')


[docs] class AuxData(): def __init__(self, wl=None): # load data from raw files self.solar_irr = SolarIrradiance() self.sunglint_eps = pd.read_csv(sunglint_eps_file, sep=r'\s+', index_col=0).to_xarray() self.rayleigh() self.pressure_rot_ref = 1013.25 # reproject onto desired wavelengths if wl is not None: self.solar_irr = self.solar_irr.interp(wl=wl) self.sunglint_eps = self.sunglint_eps['mean'].interp(wl=wl) self.rot = self.rot.interp(wl=wl)
[docs] def rayleigh(self): ''' Rayleigh Optical Thickness for P=1013.25mb, T=288.15K, CO2=360ppm from Bodhaine, B.A., Wood, N.B, Dutton, E.G., Slusser, J.R. (1999). On Rayleigh Optical Depth Calculations, J. Atmos. Ocean Tech., 16, 1854-1861. ''' data = pd.read_csv(rayleigh_file, skiprows=16, sep=' ', header=None) data.columns = ('wl', 'rot', 'dpol') self.rot = data.set_index('wl').to_xarray().rot
[docs] class SolarIrradiance(): def __init__(self, wl=None): # load data from raw files self.wl_min = 300 self.wl_max = 2600 self.gueymard = self.read_gueymard() self.kurucz = self.read_kurucz() self.thuillier = self.read_thuillier() self.tsis = self.read_tsis()
[docs] def read_tsis(self): ''' Open TSIS data and convert them into xarray in mW/m2/nm :return: ''' tsis = xr.open_dataset(tsis_file) tsis = tsis.set_index(wavelength='Vacuum Wavelength').rename( {'wavelength': 'wl'}) # set_coords('Vacuum Wavelength') # convert tsis['SSI'] = tsis.SSI * 1000 # .plot(lw=0.5) tsis.SSI.attrs['units'] = 'mW m-2 nm-1' tsis.SSI.attrs['long_name'] = 'Solar Spectral Irradiance Reference Spectrum (mW m-2 nm-1)' tsis.SSI.attrs['reference'] = 'Coddington, O. M., Richard, E. C., Harber, D., et al. (2021).' + \ 'The TSIS-1 Hybrid Solar Reference Spectrum. Geophysical Research Letters,' + \ '48(12), e2020GL091709. https://doi.org/10.1029/2020GL091709' return tsis.SSI.sel(wl=slice(self.wl_min,self.wl_max))
[docs] def read_thuillier(self): ''' Open Thuillier data and convert them into xarray in mW/m2/nm :return: ''' solar_irr = xr.open_dataset(thuillier_file).squeeze().data.drop('time') * 1e3 solar_irr = solar_irr.rename({'wavelength': 'wl'}) # keep spectral range of interest UV-SWIR solar_irr = solar_irr[(solar_irr.wl <= self.wl_max) & (solar_irr.wl >= self.wl_min)] solar_irr.attrs['units'] = 'mW/m2/nm' return solar_irr
[docs] def read_gueymard(self): ''' Open Thuillier data and convert them into xarray in mW/m2/nm :return: ''' solar_irr = pd.read_csv(gueymard_file, sep=r'\s+', skiprows=30, header=None) solar_irr.columns = ['wl', 'data'] solar_irr = solar_irr.set_index('wl').data.to_xarray() # keep spectral range of interest UV-SWIR solar_irr = solar_irr[(solar_irr.wl <= self.wl_max) & (solar_irr.wl >= self.wl_min)] solar_irr.attrs['units'] = 'mW/m2/nm' solar_irr.attrs['reference'] = 'Gueymard, C. A., Solar Energy, Volume 76, Issue 4,2004, ISSN 0038-092X' return solar_irr
[docs] def read_kurucz(self): ''' Open Kurucz data and convert them into xarray in mW/m2/nm :return: ''' solar_irr = pd.read_csv(kurucz_file, sep=r'\s+', skiprows=11, header=None) solar_irr.columns = ['wl', 'data'] solar_irr = solar_irr.set_index('wl').data.to_xarray() # keep spectral range of interest UV-SWIR solar_irr = solar_irr[(solar_irr.wl <= self.wl_max) & (solar_irr.wl >= self.wl_min)] solar_irr.attrs['units'] = 'mW/m2/nm' solar_irr.attrs['reference'] = 'Kurucz, R.L., Synthetic infrared spectra, in Infrared Solar Physics, ' + \ 'IAU Symp. 154, edited by D.M. Rabin and J.T. Jefferies, Kluwer, Acad., ' + \ 'Norwell, MA, 1992.' return solar_irr
[docs] def interp(self, wl=[440, 550, 660, 770, 880]): ''' Interpolation on new wavelengths :param wl: wavelength in nm :return: update variables of the class ''' self.thuillier = self.thuillier.interp(wl=wl) self.gueymard = self.gueymard.interp(wl=wl)
[docs] @staticmethod def Gamma2sigma(Gamma): '''Function to convert FWHM (Gamma) to standard deviation (sigma)''' return Gamma * np.sqrt(2.) / (np.sqrt(2. * np.log(2.)) * 2.)
@staticmethod def gaussian(x, mu, sigma): return 1 / (sigma * np.sqrt(2 * np.pi)) * np.exp(-(x - mu) ** 2 / (2 * sigma ** 2))
[docs] def convolve(self, F0, fwhm, info={}): ''' Convolve with spectral response of sensor based on full width at half maximum of each band :param F0: xarray solar irradiance to convolve, coord=wl :param fwhm: xarray with data=fwhm containing full width at half maximum in nm, and coords=wl :param info: optional parameter to feed the attributes of the output xarray :return: ''' wl_ref = F0.wl F0_int = [] for fwhm_ in fwhm: sig = self.Gamma2sigma(fwhm_.values) rsr = self.gaussian(wl_ref, fwhm_.wl.values, sig) F0_ = (F0 * rsr).integrate('wl') / np.trapz(rsr, wl_ref) F0_int.append(F0_.values) return xr.DataArray(F0_int, name='F0', coords={'wl': fwhm.wl.values}, attrs=info)