ReFRACtor
merra_aerosol.cc
Go to the documentation of this file.
1 #include "merra_aerosol.h"
2 #include "aerosol_optical.h"
3 #include "aerosol_property_hdf.h"
6 #include "initial_guess_value.h"
7 
8 using namespace FullPhysics;
9 using namespace blitz;
10 
11 #ifdef HAVE_LUA
12 #include "register_lua.h"
13 // Luabind is restricted to 10 arguments in a function. The
14 // constructor for MerraAerosol takes too many. As an easy
15 // workaround, just stuff a number of the values into an array.
16 boost::shared_ptr<MerraAerosol> merra_aerosol_create(
17 const HdfFile& Merra_climatology,
18 const HdfFile& Aerosol_property,
19 DoubleWithUnit Latitude, DoubleWithUnit Longitude,
20 const boost::shared_ptr<Pressure> &Press,
22 const blitz::Array<double, 2>& Aerosol_cov,
23 const blitz::Array<double, 1>& val)
24 {
26  (new MerraAerosol(Merra_climatology, Aerosol_property,
27  Latitude, Longitude, Press, Rh, Aerosol_cov,
28  val(0), val(1), static_cast<int>(val(2)),
29  static_cast<int>(val(3)), val(4),
30  static_cast<int>(val(5)) == 1,
31  static_cast<int>(val(6)) == 1));
32 }
34 .def("aerosol", &MerraAerosol::aerosol)
35 .def("initial_guess", &MerraAerosol::initial_guess)
36 .def("add_aerosol", &MerraAerosol::add_aerosol)
37 .def("number_merra_particle", &MerraAerosol::number_merra_particle)
38 .scope
39 [
40  luabind::def("create", &merra_aerosol_create)
41 ]
43 #endif
44 
45 //-----------------------------------------------------------------------
68 //-----------------------------------------------------------------------
69 
71 (const HdfFile& Merra_climatology,
72  const HdfFile& Aerosol_property,
73  DoubleWithUnit Latitude, DoubleWithUnit Longitude,
74  const boost::shared_ptr< Pressure > &Press,
76  const blitz::Array<double, 2>& Aerosol_cov,
77  double Max_aod,
78  double Exp_aod,
79  int Min_types,
80  int Max_types,
81  bool Linear_aod,
82  bool Relative_humidity_aerosol,
83  double Max_residual,
84  double Reference_wn)
85 : linear_aod(Linear_aod),
86  rh_aerosol(Relative_humidity_aerosol),
87  press(Press),
88  rh(Rh),
89  ref_wn(Reference_wn),
90  merra_fname(Merra_climatology.file_name()),
91  prop_fname(Aerosol_property.file_name()),
92  lat(Latitude),
93  lon(Longitude)
94 {
95  int lat_ind = file_index(Merra_climatology, "Latitude", Latitude);
96  int lon_ind = file_index(Merra_climatology, "Longitude", Longitude, true);
97  TinyVector<int,3> shp = Merra_climatology.read_shape<3>("/AOD_Fraction");
98  Array<double, 3> aod_frac =
99  Merra_climatology.read_field<double, 3>("/AOD_Fraction",
100  shape(0,lat_ind,lon_ind),
101  shape(shp[0],1,1));
102  TinyVector<int,4> shp2 =
103  Merra_climatology.read_shape<4>("/COMPOSITE_AOD_GAUSSIAN");
104  Array<double, 4> aod_gauss =
105  Merra_climatology.read_field<double, 4>("/COMPOSITE_AOD_GAUSSIAN",
106  shape(0,0,lat_ind,lon_ind),
107  shape(shp2[0],shp2[1], 1,1));
108  shp = Merra_climatology.read_shape<3>("/COMPOSITE_AOD_SORT_Index");
109  Array<int, 3> aod_sort_index =
110  Merra_climatology.read_field<int, 3>("/COMPOSITE_AOD_SORT_Index",
111  shape(0,lat_ind,lon_ind),
112  shape(shp[0],1,1));
113  Array<std::string, 1> comp_name =
114  Merra_climatology.read_field<std::string, 1>("/COMPOSITE_NAME");
115  double total_aod = sum(aod_gauss(3, Range::all(), 0, 0));
116  ig.reset(new CompositeInitialGuess);
117  // Loop over composite types until thresholds are reached:
118  number_merra_particle_ = 0;
119  for(int counter = 0; counter < aod_sort_index.shape()[0]; ++counter) {
120  int i = aod_sort_index(counter);
121  bool select;
122  if(counter < Min_types)
123  select = true;
124  else if(aod_frac(counter, 0, 0) > Exp_aod ||
125  (1 - aod_frac(counter, 0, 0)) * total_aod < Max_residual ||
126  counter >= Max_types)
127  select = false;
128  else
129  select = true;
130  if(select) {
131  ++number_merra_particle_;
132  double aod = aod_gauss(3, i);
133  double peak_height = aod_gauss(1, i);
134  double peak_width = aod_gauss(2, i);
135  if(aod > Max_aod)
136  aod = Max_aod;
137  std::string aname = comp_name(i);
138  Array<bool, 1> flag(3);
139  Array<double, 1> coeff(3);
140  flag = true, true, true;
141  if(linear_aod)
142  coeff = aod, peak_height, peak_width;
143  else
144  coeff = log(aod), peak_height, peak_width;
145  aext.push_back
147  (new AerosolShapeGaussian(press, flag, coeff, aname, linear_aod)));
148  if(rh_aerosol)
149  aprop.push_back
151  (new AerosolPropertyRhHdf(Aerosol_property, aname + "/Properties",
152  press, rh)));
153  else
154  aprop.push_back
156  (new AerosolPropertyHdf(Aerosol_property, aname + "/Properties",
157  press)));
159  nig->apriori(coeff);
160  nig->apriori_covariance(Aerosol_cov);
161  ig->add_builder(nig);
162  }
163  }
164 }
165 
166 
167 //-----------------------------------------------------------------------
169 //-----------------------------------------------------------------------
170 
172 {
173  if(!aerosol_)
174  aerosol_.reset(new AerosolOptical(aext, aprop, press, rh, ref_wn));
175  return aerosol_;
176 }
177 
178 //-----------------------------------------------------------------------
181 //-----------------------------------------------------------------------
182 
187 {
188  aext.push_back(Aext);
189  aprop.push_back(Aprop);
190  ig->add_builder(Ig);
191 }
192 
193 //-----------------------------------------------------------------------
195 //-----------------------------------------------------------------------
196 
197 int MerraAerosol::file_index(const HdfFile& Merra_climatology,
198  const std::string& Field_name,
199  DoubleWithUnit& V, bool Wrap_around)
200 {
201  Array<double, 1> value_data =
202  Merra_climatology.read_field<double, 1>("/" + Field_name);
203  double value = V.convert(Unit("deg")).value;
204  // Special handling at the edges for longitude
205  if(Wrap_around &&
206  value < value_data(0) &&
207  value >= (value_data(value_data.rows() - 1) - 360)) {
208  if(fabs(value - value_data(0)) <
209  fabs(value - (value_data(value_data.rows() - 1) - 360)))
210  return 0;
211  else
212  return value_data.rows() - 1;
213  }
214  if(Wrap_around &&
215  value >= value_data(value_data.rows() - 1) &&
216  value < (value_data(0) + 360)) {
217  if(fabs(value - (value_data(0) + 360)) <
218  fabs(value - value_data(value_data.rows() - 1)))
219  return 0;
220  else
221  return value_data.rows() - 1;
222  }
223  if(value < value_data(0) || value >= value_data(value_data.rows() - 1)) {
224  Exception e;
225  e << Field_name << " " << V << " is out or the range covered by the\n"
226  << "Merra_climatology file " << Merra_climatology.file_name();
227  throw e;
228  }
229  if(value == value_data(0))
230  return 0;
231  double* f = std::lower_bound(value_data.data(),
232  value_data.data() + value_data.rows(),
233  value);
234  int i = f - value_data.data();
235  if(((value - value_data(i - 1)) / (value_data(i) - value_data(i - 1))) < 0.5)
236  return i - 1;
237  else
238  return i;
239 }
240 
241 //-----------------------------------------------------------------------
243 //-----------------------------------------------------------------------
244 
245 void MerraAerosol::print(std::ostream& Os) const
246 {
247  Os << "MerraAerosol: ("
248  << (linear_aod ? "Linear, " : "Logarithmic, ")
249  << (rh_aerosol ? "RH aerosol" : "Not RH aerosol")
250  << ")\n"
251  << " Coefficient:\n"
252  << " Merra file name: " << merra_fname << "\n"
253  << " Aerosol property file name: " << prop_fname << "\n"
254  << " Latitude: " << lat << "\n"
255  << " Longitude: " << lon << "\n";
256 }
blitz::TinyVector< int, D > read_shape(const std::string &Dataname) const
Reads the shape of a dataset.
Definition: hdf_file.h:553
boost::shared_ptr< InitialGuessBuilder > initial_guess() const
Return IntitialGuessBuilder for the Aerosol.
Definition: merra_aerosol.h:41
blitz::Array< T, D > read_field(const std::string &Dataname) const
Read a given field.
Definition: hdf_file.h:564
This class is used to create the Aerosol from a Merra climatology file.
Definition: merra_aerosol.h:15
void add_aerosol(const boost::shared_ptr< AerosolExtinction > &Aext, const boost::shared_ptr< AerosolProperty > &Aprop, const boost::shared_ptr< InitialGuessBuilder > &Ig)
Add in an aerosol that comes from some source other than Dijian&#39;s files (e.g., hardcoded aerosols to ...
This gives the Aerosol properties for an Aerosol.
This is the base of the exception hierarchy for Full Physics code.
Definition: fp_exception.h:16
A common way to create an initial guess is to have other classes responsible for portions of the stat...
This class reads and writes a HDF5 file.
Definition: hdf_file.h:39
#define REGISTER_LUA_CLASS(X)
Definition: register_lua.h:116
Apply value function to a blitz array.
MerraAerosol(const HdfFile &Merra_climatology, const HdfFile &Aerosol_property, DoubleWithUnit Latitude, DoubleWithUnit Longitude, const boost::shared_ptr< Pressure > &Press, const boost::shared_ptr< RelativeHumidity > &Rh, const blitz::Array< double, 2 > &Aerosol_cov, double Max_aod=0.2, double Exp_aod=0.8, int Min_types=2, int Max_types=4, bool Linear_aod=false, bool Relative_humidity_aerosol=false, double Max_residual=0.005, double Reference_wn=1e4/0.755)
Constructor.
boost::shared_ptr< Aerosol > aerosol() const
Return the aerosol setup generated from this class.
This is a simple implementation of InitialGuessBuilder that just has variables used to give the aprio...
This class maps the state vector to aerosol extinction defined by a Gaussian parameterization.
Implementation of Aerosol.
We frequently have a double with units associated with it.
const std::string & file_name() const
File name.
Definition: hdf_file.h:131
DoubleWithUnit convert(const Unit &R) const
Convert to the given units.
This gives the Aerosol properties for an Aerosol.
Libraries such as boost::units allow unit handling where we know the units at compile time...
Definition: unit.h:25
Contains classes to abstract away details in various Spurr Radiative Transfer software.
Definition: doxygen_python.h:1
#define REGISTER_LUA_END()
Definition: register_lua.h:134
virtual void print(std::ostream &Os) const
Print to stream.
def(luabind::constructor< int >()) .def("rows"
int number_merra_particle() const
Number of merra particles.
Definition: merra_aerosol.h:47
double value(const FullPhysics::AutoDerivative< double > &Ad)

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