Generating a test cloud field
The following snippet generates a netcdf cloud field with xarray so that it can be handled by libRadtran 3D
def create_librad_netcdf_cldfile(fname, lwc, reff, hhl, dx, dy, reff_min=2.51, reff_max=55):
"""
Creates a netcdf cloud file for libRadtran calculations
Provide:
lwc and reff arrays with dimensions (Nx, Ny, Nz)
hhl with dimension(Nz+1)
dx, dy, hhl in units of [km]
lwc in [g/kg]
reff in [micrometer]
"""
import xarray as xr
import os
import numpy as np
#pylint: disable = invalid-name
""" create lwc file """
if (lwc is None) or (reff is None):
print('lwc or reff is None, not writing a cld file...')
return
print('shape of input:', np.shape(lwc,), ':', np.shape(reff), ':', np.shape(hhl))
print('assembling data for: ', fname, ' :: min {} max {}'.format(np.min(lwc), np.max(lwc)), ' :: reff {} {}'.format(np.min(reff), np.max(reff)))
if lwc.shape[2]+1 != len(hhl):
raise IndexError('vertical shape of lwc should match height lvls')
Nx, Ny, Nz = lwc.shape
lwc = np.round(lwc, decimals=3)
reff= np.round(reff,decimals=3)
reff = np.minimum(np.maximum(reff, reff_min),reff_max)
dlwc = xr.DataArray(np.swapaxes(lwc , 0, 1), dims=('ny','nx','nz'))
dreff = xr.DataArray(np.swapaxes(reff, 0, 1), dims=('ny','nx','nz'))
D = xr.Dataset({
'lwc' : xr.DataArray(np.swapaxes(lwc , 0, 1), dims=('ny','nx','nz')),
'reff': xr.DataArray(np.swapaxes(reff, 0, 1), dims=('ny','nx','nz')),
'z' : xr.DataArray(hhl, dims=('nz_lev')), },
attrs={
'cldproperties': 3,
'dx': dx,
'dy': dy,
})
try:
os.mkdir(os.path.dirname(fname))
except OSError:
pass
print('... writing to file: ... ', fname)
D.to_netcdf(fname)
from pylab import *
Nx, Ny, Nz = 10, 10, 5
hhl = np.linspace(0,2,Nz+1)
lwc = np.zeros((Nx, Ny, Nz))
reff = np.zeros((Nx, Ny, Nz))
lwc[Nx//2, Ny//2, Nz//2] = 1
reff[lwc>0] = 10
dx = dy = .5
create_librad_netcdf_cldfile('test_cloud.nc', lwc, reff, hhl, dx, dy)
Generate LibRadtran input file
#!/bin/python3
import sys
import os
import shutil
import subprocess
import tempfile
from jinja2 import Template
help_str = """
Generate a LibRadtran input with a template and run it.
Input file is a Temporary file and
Output is saved in a temporary folder
"""
homedir = os.environ['HOME']
libRadtran = os.path.join(homedir, 'libRadtran')
datadict = {
'data_files_path': os.path.join(libRadtran, 'data'),
'atmosphere_file': os.path.join(libRadtran, 'data', 'atmmod', 'afglus.dat'),
'source_solar': os.path.join(libRadtran, 'data', 'atlas_plus_modtran'),
'mol_abs_param': 'kato2',
'wavelength_index': '1 32',
'albedo': 0.15,
'sza': 60,
'phi0': 0, # 0 is South
'rte_solver': 'montecarlo',
'mc_ipa': True,
#'mc_tenstream': 'solver_3_10',
#'rte_solver': 'twostrebe',
#'ipa_3d': True,
'mc_sample_grid': '10 10 .5 .5',
'wc_file_3D': 'test_cloud.nc',
}
inp_template = Template(
"""
data_files_path {{data_files_path}}
atmosphere_file {{atmosphere_file}}
source solar {{source_solar}} per_nm
{% if output_process %}
output_process {{output_process}}
{% else %}
output_process sum
{% endif %}
mol_abs_param {{mol_abs_param}}
wavelength_index {{wavelength_index}}
albedo {{albedo}}
sza {{sza}}
phi0 {{phi0}}
{% if mc_forward_output %}
mc_forward_output {{mc_forward_output}}
{% else %}
mc_forward_output absorption K_per_day
{% endif %}
{% if zout %}
zout {{zout}}
{% else %}
zout all_levels
{% endif %}
rte_solver {{rte_solver}}
{% if ipa_3d %}
ipa_3d
{% endif %}
{% if mc_tenstream %}
mc_tenstream {{mc_tenstream}}
{% endif %}
{% if mc_ipa %}
mc_ipa
{% endif %}
{% if mc_photons %}
mc_photons {{mc_photons}}
{% endif %}
mc_sample_grid {{mc_sample_grid}}
{% if wc_file_3D %}
wc_file 3D {{wc_file_3D}}
wc_properties hu interpolate
{% endif %}
{% if ic_file_3D %}
ic_file 3D {{ic_file_3D}}
ic_properties yang interpolate
{% endif %}
{% if outdir %}
mc_basename {{outdir}}/mc
{% endif %}
#quiet
verbose
""")
tempfile.NamedTemporaryFile
with tempfile.NamedTemporaryFile('w') as fh:
outdir = tempfile.mkdtemp()
datadict['outdir'] = outdir
fh.write(inp_template.render(**datadict))
fh.flush()
sp = subprocess.call([os.path.join(libRadtran, 'bin', 'uvspec'), '-f', fh.name])
shutil.rmtree(outdir)