OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
DDAlgorithm.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  *
3  * NAME: DDAlgorithm.cpp
4  *
5  * DESCRIPTION: Base class for all algorithms.
6  *
7  * Created on: October 19, 2020
8  * Author: Sam Anderson
9  *
10  *******************************************************************************/
11 
12 #include <boost/math/interpolators/barycentric_rational.hpp>
13 #include <boost/timer/timer.hpp>
14 #include <algorithm>
15 #include <netcdf>
16 
17 #include <DDataset.hpp>
18 #include <DDOptions.h>
19 #include <DDAlgorithm.h>
20 
21 using namespace std;
22 using namespace netCDF;
23 using namespace netCDF::exceptions;
24 
25 /**************************************************************************
26  * NAME: DDAlgorithm()
27  *
28  * DESCRIPTION: Constructor
29  *
30  *************************************************************************/
31 
33 {
34  lines_ = 0;
35  pixels_ = 0;
36  for (size_t i=0; i< NTWL; i++) {
37  rfl_[i] = 0.0;
38  gasc_[i] = 0.0;
39  for (size_t j=0; j<3; j++) {
40  for (size_t k=0; k<3; k++) {
41  rfla_[i][j][k] = 0.0;
42  }
43  }
44  }
45  lat_ = 0.0;
46  lon_ = 0.0;
47  solz_ = 0.0;
48  senz_ = 0.0;
49  raa_ = 0.0;
50  height_ = 0.0;
51  scatt_ = 0.0;
52  ws_ = 0.0;
53  pwv_ = 0.0;
54  oz_ = 0.0;
55  ps_ = 0.0;
56  month_ = 0;
57  bgascorrect_ = false;
58  bglintmask_ = false;
59  bcloudmask_ = false;
60  btest_ = false ;
61  cloud_mask_ = DFILL_UBYTE;
62  l2_flags_ = 0;
63  qual_flag_ = 0;
64  aerosol_type_ = 0;
65  error_flag_ = 0;
66  scatter_ang_ = 0.0;
67  glint_ang_ = 0.0;
68  sse_ = 0.0;
69  fmf_ = 0.0;
70  aot_550_ = 0.0;
71  ae1_ = 0.0;
72  ae2_ = 0.0;
73  ndv_ = 0.0;
74  chlor_ = 0.0;
75  for (size_t i=0; i< NOWL+1; i++) {
76  aot_[i] = 0.0;
77  }
78  for (size_t i=0; i< NLWL+1; i++) {
79  ssa_[i] = 0.0;
80  sr_[i] = 0.0;
81  }
82 };
83 
85 {
86 };
87 
88 /**************************************************************************
89  * NAME: read_inputs()
90  *
91  * DESCRIPTION: Read inputs from map
92  *
93  *************************************************************************/
94 
95 int DDAlgorithm::get_inputs( vector<size_t> start, vector<size_t> count,
96  map<string, ddata*> imap )
97 {
98  int status = DTDB_SUCCESS;
99  size_t sy = start[0];
100  size_t sx = start[1];
101  lon_ = static_cast<ddma<float,2>*>(imap["longitude"])->pts[sy][sx];
102  lon_ = (lon_ > 180.0) ? lon_ - 360.0 : lon_;
103  lon_ = (lon_ < -180.0) ? lon_ + 360.0 : lon_;
104  lat_ = static_cast<ddma<float,2>*>(imap["latitude"])->pts[sy][sx];
105  lat_ = (lat_ > 90.0) ? lat_ - 180.0 : lat_;
106  lat_ = (lat_ < -90.0) ? lat_ + 180.0 : lat_;
107  solz_ = static_cast<ddma<float,2>*>(imap["solar_zenith"])->pts[sy][sx];
108  senz_ = static_cast<ddma<float,2>*>(imap["sensor_zenith"])->pts[sy][sx];
109  height_ = static_cast<ddma<float,2>*>(imap["elevation"])->pts[sy][sx]/1000.0;
110 
111  float sola = static_cast<ddma<float,2>*>(imap["solar_azimuth"])->pts[sy][sx];
112  sola = (sola > 180.0) ? sola - 360.0 : sola;
113  sola = (sola < -180.0) ? sola + 360.0 : sola;
114  float sena = static_cast<ddma<float,2>*>(imap["sensor_azimuth"])->pts[sy][sx];
115  sena = (sena > 180.0) ? sena - 360.0 : sena;
116  sena = (sena < -180.0) ? sena + 360.0 : sena;
117  raa_ = fabs(sola - sena - 180.0);
118  raa_ = (raa_ > 360.0) ? fmod(raa_,360) : raa_;
119  raa_ = (raa_ > 180.0) ? 360.0 - raa_ : raa_;
120  if((solz_ > 0.0) && (senz_ > 0.0) && (raa_ > 0.0)) {
121  scatt_ = -cos (solz_*DEGtoRAD)*cos(senz_*DEGtoRAD)
122  + sin(solz_*DEGtoRAD)*sin(senz_*DEGtoRAD)
123  * cos (raa_*DEGtoRAD);
124  scatt_ = acos (scatt_)*RADtoDEG;
125  }
126  ws_ = static_cast<ddma<float,2>*>(imap["wind_speed"])->pts[sy][sx];
127  pwv_ = static_cast<ddma<float,2>*>(imap["water_vapor"])->pts[sy][sx];
128  oz_ = static_cast<ddma<float,2>*>(imap["ozone"])->pts[sy][sx];
129  ps_ = static_cast<ddma<float,2>*>(imap["surface_pressure"])->pts[sy][sx]/100.0; // in units hPa
130  cloud_mask_ = static_cast<ddma<unsigned char,2>*>(imap["cloud_mask"])->pts[sy][sx];
131 
132  size_t ilmin = (sy==0) ? 1 : 0;
133  size_t ilmax = (sy==count[0]-1) ? 1 : 2;
134  size_t ipmin = (sx==0) ? 1 : 0;
135  size_t ipmax = (sx==count[1]-1) ? 1 : 2;
136  for (auto &it : DDProcess::rhot_band_names) {
137  string name = (string) it.first;
138  rfl_[(size_t) it.second] = DFILL_FLOAT;
139  for (size_t il=0; il<3; il++) {
140  for (size_t ip=0; ip<3; ip++) {
141  rfla_[(size_t)it.second][il][ip] = DFILL_FLOAT;
142  }
143  }
144  rfl_[(size_t) it.second] = (static_cast<ddma<float,2>*>(imap[name]))->pts[sy][sx];
145  for (size_t il=ilmin; il<=ilmax; il++) {
146  for (size_t ip=ipmin; ip<=ipmax; ip++) {
147  rfla_[(size_t)it.second][il][ip] =
148  (static_cast<ddma<float,2>*>(imap[name]))->pts[sy-1+il][sx-1+ip];
149  }
150  }
151  }
152  l2_flags_ = 0;
153 
154  return status;
155 }
156 
157 /**************************************************************************
158  * NAME: set_outputs()
159  *
160  * DESCRIPTION: Set outputs
161  *
162  *************************************************************************/
163 
164 map<string, ddata*> DDAlgorithm::set_outputs()
165 {
166  map<string, ddata*> omap;
167  int status = DTDB_SUCCESS;
168  ddval<int>* pstat = new ddval<int>(dtype::INT, status);
169  omap.insert({"status", pstat});
170 
171  omap.insert({"status", pstat});
173  (unsigned char) cloud_mask_);
174  omap.insert({"cloud_mask", puc});
175  ddval<short>* psh = new ddval<short>(dtype::SHORT, aerosol_type_);
176  omap.insert({"aerosol_type", psh});
177  ddval<float>* pfl = new ddval<float>(dtype::FLOAT, ae1_);
178  omap.insert({"angstrom", pfl});
179 // pfl = new ddval<float>(dtype::FLOAT, aot_550_);
180 // if (!bcloudmask_ && (pfl->val > 0)) {
181 // pfl->val = log10(pfl->val);
182 // }
183 // omap.insert({"aot_550", pfl});
184  pfl = new ddval<float>(dtype::FLOAT, ndv_);
185  omap.insert({"ndvi", pfl});
186  pfl = new ddval<float>(dtype::FLOAT, sse_);
187  omap.insert({"residual_error", pfl});
188  short qual = 0;
189  if (pfl->val > 0) {
190  qual = (short) ceil(-log10(pfl->val));
191  }
192  qual = (qual>3) ? 3 : (qual<0) ? 0 : qual;
193  psh = new ddval<short>(dtype::SHORT, qual);
194  omap.insert({"quality_flag", psh});
195 
196  pfl = new ddval<float>(dtype::FLOAT, fmf_);
197  omap.insert({"fmf_550", pfl});
198  pfl = new ddval<float>(dtype::FLOAT, chlor_);
199  omap.insert({"chlorophyll", pfl});
200  pfl = new ddval<float>(dtype::FLOAT, glint_ang_);
201  omap.insert({"glint_angle", pfl});
202  pfl = new ddval<float>(dtype::FLOAT, scatter_ang_);
203  omap.insert({"scattering_angle", pfl});
204 
205  for (auto &it : DDProcess::rhot_band_names) {
206  string name = (string) it.first;
207  pfl = new ddval<float>(dtype::FLOAT, rfl_[(size_t)it.second]);
208  omap.insert({name, pfl});
209  }
210  for (auto &it : DDProcess::aot_band_names) {
211  string name = (string) it.first;
212  pfl = new ddval<float>(dtype::FLOAT, aot_[(size_t)it.second]);
213  if (!bcloudmask_ && (pfl->val > 0)) {
214  pfl->val = log10(pfl->val);
215  }
216  omap.insert({name, pfl});
217  }
218  for (auto &it : DDProcess::srf_band_names) {
219  string name = (string) it.first;
220  pfl = new ddval<float>(dtype::FLOAT, sr_[(size_t)it.second]);
221  omap.insert({name, pfl});
222  pfl = new ddval<float>(dtype::FLOAT, ssa_[(size_t)it.second]);
223  string oname = "ssa" + name.substr(7);
224  omap.insert({oname, pfl});
225  }
226 
227 // for special aot_380
228 // Interpolation of ocean spectral optical depth to wavelength 380
229 // This is a placeholder for a planned UV model
230  vector<float> tba = {490.0,550.0,670.0,865.0,1240.0,1610.0,2250.0};
231  vector<float> yba(begin(aot_)+1, end(aot_));
232  using boost::math::barycentric_rational;
233  barycentric_rational<float> interp(move(tba), move(yba));
234  float uv = interp(380.0);
235  pfl = new ddval<float>(dtype::FLOAT, uv);
236  omap.insert({"aot_380", pfl});
237 
238  if (qual == 0 && qual_flag_!= DFILL_SHORT) l2_flags_ += (unsigned int) flags::PRODFAIL;
239  if (qual == 1 && qual_flag_!= DFILL_SHORT) l2_flags_ += (unsigned int) flags::PRODWARN;
240  if (cloud_mask_ == 1) l2_flags_ += (unsigned int) flags::CLDICE;
241 
242  ddval<int>* pflags = new ddval<int>(dtype::INT, l2_flags_);
243  omap.insert({"l2_flags", pflags});
244 
245  return omap;
246 }
247 
248 map<string, ddata*> DDAlgorithm::set_fills()
249 {
250  l2_flags_ += (unsigned int) flags::PRODFAIL;
251  qual_flag_ = DFILL_SHORT;
252  aerosol_type_ = DFILL_SHORT;
253  scatter_ang_ = DFILL_FLOAT;
254  glint_ang_ = DFILL_FLOAT;
255  sse_ = DFILL_FLOAT;
256  fmf_ = DFILL_FLOAT;
257  aot_550_ = DFILL_FLOAT;
258  ae1_ = DFILL_FLOAT;
259  ae2_ = DFILL_FLOAT;
260  ndv_ = DFILL_FLOAT;
261  chlor_ = DFILL_FLOAT;
262  for (size_t i=0; i< NOWL+1; i++) {
263  aot_[i] = DFILL_FLOAT;
264  }
265  for (size_t i=0; i< NLWL+1; i++) {
266  ssa_[i] = DFILL_FLOAT;
267  sr_[i] = DFILL_FLOAT;
268  }
269  return set_outputs();
270 };
271 
272 
273 
void interp(double *ephemPtr, int startLoc, double *inTime, int numCoefs, int numCom, int numSets, int velFlag, double *posvel)
@ SHORT
signed 2 byte integer
int j
Definition: decode_rs.h:73
int status
Definition: l1_czcs_hdf.c:32
constexpr unsigned char DFILL_UBYTE
Definition: DDataset.hpp:28
@ UBYTE
unsigned 1 byte int
int16_t * qual
Definition: l2bin.cpp:86
@ FLOAT
single precision floating point number
@ PRODWARN
@ string
int get_inputs(vector< size_t > start, vector< size_t > count, map< string, ddata * > imap)
Definition: DDAlgorithm.cpp:95
static const map< string, srf_band > srf_band_names
Definition: DDProcess.h:158
map< string, ddata * > set_outputs()
map< string, ddata * > set_fills()
static const map< string, aot_band > aot_band_names
Definition: DDProcess.h:157
constexpr float DFILL_FLOAT
Definition: DDataset.hpp:25
#define fabs(a)
Definition: misc.h:93
virtual ~DDAlgorithm()
Definition: DDAlgorithm.cpp:84
@ INT
signed 4 byte integer
def set_outputs(output_keys)
Definition: utils.py:164
@ PRODFAIL
int i
Definition: decode_rs.h:71
static const map< string, rhot_band > rhot_band_names
Definition: DDProcess.h:156
int k
Definition: decode_rs.h:73
constexpr short DFILL_SHORT
Definition: DDataset.hpp:27
int count
Definition: decode_rs.h:79