ReFRACtor
radiant_driver.cc
Go to the documentation of this file.
1 #include "radiant_driver.h"
2 #include "linear_algebra.h"
3 #include "fp_exception.h"
4 #include "old_constant.h"
5 #include "wgs84_constant.h"
7 
8 extern "C"
9 {
10  // arrays tau,zlev,refrac_lay_grid,tlev,get_atmos_jacobian,l_tau
11  // l_user_radiance_direct
12  // l_radiance_direct,user_layer,user_tau,l_user_tau,user_radiance_direct
13 
14  // in: numlay,fsun,mu0,tau,dim_reset,use_pseudo_spherical new_scene_geo
15  // planet_radius,zlev.use_refraction,refrac_ind_par,refrac_lay_grid
16  // plev,tlev,linearize_atmos_par,get_atmos_jacobian,numpar,l_tau,l_dim_reset
17  // get_user_rad, n_user_rad,user_layer,l_user_tau
18  // user_tau
19 
20  // out: radiance_direct,l_radiance_direct,user_radiance_direct,
21  // l_user_radiance_direct
22  void rad_direct(
23  int *numlay,
24  double *fsun,
25  double *mu0,
26  double *tau,
27  double *radiance_direct,
28  bool *dim_reset,
29  bool *use_pseudo_spherical,
30  bool *new_scene_geo,
31  double *planet_radius,
32  double *zlev,
33  bool*use_refraction,
34  double *refrac_ind_par,
35  int *refrac_lay_grid,
36  double *plev,
37  double *tlev,
38  bool *linearize_atmos_par,
39  bool *get_atmos_jacobian,
40  int *numpar,
41  double *l_tau,
42  bool *l_dim_reset,
43  double *l_radiance_direct,
44  bool *get_user_rad,
45  int *n_user_rad,
46  int *user_layer,
47  double *user_tau,
48  double *l_user_tau,
49  double *user_radiance_direct,
50  double *l_user_radiance_direct);
51 
52  void rad_init(double **tau_in_c,double **l_tau_ind, int *maxlay,int *maxatm);
53  void rad_cleanup(double *tau_in_c,double *l_tau_ind,int *numpar, int *numlay );
54 
55 }
56 
57 
58 //-----------------------------------------------------------------------
61 //\param Atm. An atmospsher object.
62 // \param Sza Solar zenith angle. This is in degrees, and should be
65 
66 RadiantDriver::RadiantDriver(const boost::shared_ptr<RtAtmosphere>& Atm,
67  const blitz::Array<double, 1>& Sza)
68  : sza(Sza.copy())
69 
70 {
71  atm = Atm;
72  Array<double, 2> stokes_coef_v(sza.rows(), number_stokes());
73  stokes_coef_v = 0;
74  stokes_coef_v(Range::all(), 0) = 1.0;
75  stokes_coef.reset(new StokesCoefficientConstant(stokes_coef_v));
76 
77  for(int i = 0; i < number_spectrometer(); ++i) {
78  range_check(sza(i), 0.0, 90.0);
79  }
80 
81  // Allocates space for radiant arrays
82  int maxlay, maxatm;
83  double *tau_ind, *l_tau_ind;
84 
85  rad_init(&tau_ind,&l_tau_ind,&maxlay,&maxatm);
86  tau_in.reference(Array<double, 1>(tau_ind, shape(maxlay), neverDeleteData,
87  ColumnMajorArray<1>()));
88 
89  l_tau_in.reference(Array<double, 2>(l_tau_ind, shape(maxatm, maxlay),
90  neverDeleteData,
91  ColumnMajorArray<2>()));
92  atm->add_observer(*this);
93 }
94 
95 //-----------------------------------------------------------------------
97 //-----------------------------------------------------------------------
98 
100 {
101  int numpar = l_tau_in.extent(firstDim);
102  int numlay = l_tau_in.extent(secondDim);
103  rad_cleanup(tau_in.dataFirst(), l_tau_in.dataFirst(), &numpar, &numlay);
104 }
105 
106 Array<double, 1> RadiantDriver::stokes_single_wn
107 (double Wn, int Spec_index, const ArrayAd<double, 2>& Iv) const {
108  return stokes_and_maybe_jacobian(Wn, Spec_index, Iv).value();
109 }
110 
112 (double Wn, int Spec_index, const ArrayAd<double, 2>& Iv) const
113 {
114  return stokes_and_maybe_jacobian(Wn, Spec_index, Iv);
115 }
116 
117 ArrayAd<double, 1> RadiantDriver::stokes_and_maybe_jacobian
118 (double Wn, int Spec_index, const ArrayAd<double, 2>& Iv) const
119 {
120  firstIndex i1; secondIndex i2; thirdIndex i3;
121  Range rlay(0, atm->number_layer() - 1);
122  Range ra(Range::all());
123  ArrayAd<double, 1> od, ssa;
124  Array<double, 3> jac_iv(0,0,0);
125 
126  if(Iv.rows() != 0) {
127  od.reference(atm->optical_depth_wrt_iv(Wn, Spec_index, Iv));
128  if(!Iv.is_constant())
129  jac_iv.reference(Iv.jacobian());
130  } else {
131  od.reference(atm->optical_depth_wrt_iv(Wn, Spec_index));
132  ArrayAd<double, 2> t(atm->intermediate_variable(Wn, Spec_index));
133  if(!t.is_constant())
134  jac_iv.reference(t.jacobian());
135  }
136 
137  Array<double, 1> jac(jac_iv.depth());
138  ArrayAd<double,1> res(number_stokes(), jac.rows());
139 
140  tau_in(rlay) = od.value();
141 
142  int natm_jac = od.number_variable();
143  Range rjac(0, natm_jac - 1);
144  l_tau_in(rlay, rjac) = where(od.value()(i1) != 0,
145  od.jacobian() / od.value()(i1), 0.0);
146 
147  int numlay = atm->number_layer();
148  double fsun = 1.0;
149  double mu0 = cos((sza(0)/180.0*OldConstant::pi));
150 
151  double radiance_direct = 0; // output
152 
153  bool dim_reset = true; // this will cause reallocation of memory
154  bool use_pseudo_spherical = true;
155  bool new_scene_geo = true;
156  double planet_radius = OldConstant::wgs84_a.convert(units::km).value;
157 
158  ArrayAd<double, 1> temp_zlev = atm->altitude(Spec_index).convert(units::km).value;
159  blitz::Array<double, 1> zlev = temp_zlev.value();
160  bool use_refraction = false; // always false for radiant
161 
162  // matches value from chapman boa currently, if refraction
163  // ever enabled
164  double refrac_ind_par = 0.000288;
165 
166  // hardcoded in old code
167  blitz::Array<int, 1> refrac_lay_grid(numlay);
168  refrac_lay_grid = 10; //hardcoded in old code
169 
170  // the following 2 are not used because use_refraction is false for radiant
171  blitz::Array<double, 1> plev(numlay+1); // not used w/o refraction
172  blitz::Array<double, 1> tlev(numlay+1); // not used w/o refraction
173  int numpar = natm_jac; //number of rows in jacobian??
174 
175  bool linearize_atmos_par = numpar > 0; // true if creating jacobians
176  blitz::Array<bool, 2> get_atmos_jacobian(numpar,numlay);
177  get_atmos_jacobian = linearize_atmos_par; // true if we need jacobians, i.e. doing retrievals
178  bool l_dim_reset = true; //causes reallocation
179  blitz::Array<double, 2> l_radiance_direct(numpar,numlay, blitz::ColumnMajorArray<2>());
180 
181  bool get_user_rad = false; //for radiant
182  int n_user_rad = 10; //??
183 
184  blitz::Array<int, 1> user_layer(n_user_rad);
185  blitz::Array<double, 1> user_tau(n_user_rad);
186  blitz::Array<double, 2> l_user_tau(numpar,n_user_rad);
187  blitz::Array<double, 1> user_radiance_direct(n_user_rad);
188  blitz::Array<double, 3> l_user_radiance_direct(numpar,numlay,n_user_rad);
189  rad_direct(&numlay, // n_active_levels -1, from pressure file, might be modified by conner
190  // sounding info pressure file
191  &fsun, //always 1 for radiant
192  &mu0, // layer 1, new_scene_geo
193  tau_in.dataFirst(), //optical depths taug + taur + taua
194  &radiance_direct, //ouput BEER'S LAW COMPUTATION FOR DIRECT RADIANCE
195  &dim_reset, //I'm setting to always true to simplify dome logic
196  &use_pseudo_spherical, //true for radiant
197  &new_scene_geo, //I'm setting to always true to simplify dome logic
198  &planet_radius, //constant from constants module
199  zlev.dataFirst(), //altitudes
200  &use_refraction, //always false for radiant
201  &refrac_ind_par, //hardcoded in old code
202  refrac_lay_grid.dataFirst(), //hardcoded in old code
203  plev.dataFirst(), //not used because no refraction
204  tlev.dataFirst(), // not used because no refraction
205  &linearize_atmos_par,
206  get_atmos_jacobian.data(),
207  &numpar,
208  l_tau_in.dataFirst(),
209  &l_dim_reset,
210  l_radiance_direct.dataFirst(),
211  &get_user_rad,
212  &n_user_rad,
213  user_layer.dataFirst(),
214  user_tau.dataFirst(),
215  l_user_tau.dataFirst(),
216  user_radiance_direct.dataFirst(),
217  l_user_radiance_direct.dataFirst());
218 
219  radiance_direct *= SOLID_ANGLE;
220  l_radiance_direct = l_radiance_direct * SOLID_ANGLE;
221  for(int i = 0; i < jac.rows(); ++i) {
222  double val = 0;
223  for(int m = 0; m < jac_iv.rows(); ++m)
224  for(int n = 0; n < jac_iv.cols(); ++n) {
225  //note the transposition
226  val += l_radiance_direct(n,m) * jac_iv(m, n, i); //this is atmoswf
227  }
228  jac(i) = val;
229  }
230 
231  res = 0;
232  res(0) = AutoDerivative<double>(radiance_direct,jac);
233 
234  return res;
235 }
236 
237 
238 //-----------------------------------------------------------------------
240 //-----------------------------------------------------------------------
241 
242 void RadiantDriver::print(std::ostream& Os) const
243 {
244  Os << "RadiantDriver";
245 }
246 
#define range_check(V, Min, Max)
Range check.
Definition: fp_exception.h:140
void rad_cleanup(double *tau_in_c, double *l_tau_ind, int *numpar, int *numlay)
virtual ArrayAd< double, 1 > stokes_and_jacobian_single_wn(double Wn, int Spec_index, const ArrayAd< double, 2 > &Iv) const
Calculate stokes vector and Jacobian for the given wavenumber.
bool is_constant() const
Definition: array_ad.h:371
virtual int number_spectrometer() const
Number of spectrometer we have.
void rad_init(double **tau_in_c, double **l_tau_ind, int *maxlay, int *maxatm)
This class maintains the stokes coefficient portion of the state.
void rad_direct(int *numlay, double *fsun, double *mu0, double *tau, double *radiance_direct, bool *dim_reset, bool *use_pseudo_spherical, bool *new_scene_geo, double *planet_radius, double *zlev, bool *use_refraction, double *refrac_ind_par, int *refrac_lay_grid, double *plev, double *tlev, bool *linearize_atmos_par, bool *get_atmos_jacobian, int *numpar, double *l_tau, bool *l_dim_reset, double *l_radiance_direct, bool *get_user_rad, int *n_user_rad, int *user_layer, double *user_tau, double *l_user_tau, double *user_radiance_direct, double *l_user_radiance_direct)
const DoubleWithUnit wgs84_a(6378137.0000, units::m)
Equatorial radius.
const blitz::Array< T, D+1 > jacobian() const
Definition: array_ad.h:307
virtual blitz::Array< double, 1 > stokes_single_wn(double Wn, int Spec_index, const ArrayAd< double, 2 > &Iv) const
Calculate stokes vector for the given wavenumber.
const blitz::Array< T, D > & value() const
Definition: array_ad.h:306
virtual void print(std::ostream &Os) const
Print to a stream.
const Unit m("m", 1.0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
int number_variable() const
Definition: array_ad.h:376
DoubleWithUnit convert(const Unit &R) const
Convert to the given units.
void reference(const ArrayAd< T, D > &V)
Definition: array_ad.h:372
virtual ~RadiantDriver()
Destructor.
boost::shared_ptr< StokesCoefficient > stokes_coef
Object to go from stokes vector to reflectance.
const Unit km("km", 1e3 *m)
int rows() const
Definition: array_ad.h:368

Copyright © 2017, California Institute of Technology.
ALL RIGHTS RESERVED.
U.S. Government Sponsorship acknowledged.
Generated Fri Aug 24 2018 15:44:10