OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l2_str.cpp
Go to the documentation of this file.
1 //
2 // l2_str.cpp
3 //
4 //
5 // Created by Martin Montes on 2/11/2022
6 #include "l2_str.h"
7 #include <iostream>
8 #include <string>
9 #include "l1c_filehandle.h"
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <math.h>
13 #include <stdbool.h>
14 #include <stdint.h>
15 #include <netcdf.h>
16 #include <nc4utils.h>
17 #include "libnav.h"
18 #include <timeutils.h>
19 #include <genutils.h>
20 
21 
22 #include "allocate4d.h"
23 #include <allocate3d.h>
24 #include <allocate2d.h>
25 
26 #include <boost/foreach.hpp>
27 #include <boost/algorithm/string.hpp>
28 
29 static short *tmpShort;
30 
31 // whole file stuff
32 static size_t expected_number_of_bands = 239;//OCIS
33 static size_t nviews;
34 static size_t num_scans, num_pixels,number_of_bands;
35 static int ncid_L1B;
36 
37 // scan line attributes
38 static double *scan_time; // seconds of day
39 static int32_t scan_time_year, scan_time_month, scan_time_day;
40 
41 
42 //static uint_8 *scan_quality;
43 
44 // geolocation data
45 static int geolocationGrp;
46 static int tiltId,lonId, latId,prodims[345];//#345 of potential L2 products is from product.h
47 static float latFillValue = -999.0;
48 static float lonFillValue = -999.0;
49 
50 static float tiltmin = 0.0,tiltmax=0.0;
51 static float tiltFillValue = -999.0;
52 
53 // Observation data
54 static int observationGrp;
55 
56 
57 //Navigation data
58 static int status,dimid;
59 
60 using namespace std;
61 
62 
63 namespace l1c {
64 
65  l2_str::l2_str() : att_ang{-999.0,-999.0,-999.0}, orb_pos{-999.0,-999.0,-999.0}, orb_vel{-999.0,-999.0,-999.0} {
66 
67  //init constructor
68  //global attributes
69  npix=-1;
70  iscan=0;
71  nscan=-1;
72  //scan line attributes--
73  ev_mid_time=nullptr;
74  scan_quality_flag=nullptr;
75  spix=-1;
76  epix=-1;
77  dpix=-1;
78 
79  // structure--pointers to data arrays
80  Lt=nullptr; //dim depends between sensors--OCI is bands x pixels --
81  Lt_blue=nullptr; //[num_views][num_pol][num_blue_bands][num_pixels]
82  Lt_red=nullptr;
83  Lt_SWIR=nullptr;
84 
85  l2prod=nullptr;
86  nl2prod=-1;
87  slopeprod=nullptr;
88  offsetprod=nullptr;
89  tilt=nullptr;
90 
91  //sensor/sun geometry
92  senz=nullptr;
93  sena=nullptr;
94  solz=nullptr;
95  sola=nullptr;
96  delphi=nullptr;
97  scattang=nullptr;
98 
99  //geolocation--
100  senazpix=nullptr;
101  latpix=nullptr;
102  lonpix=nullptr;
103  latpix2=nullptr;
104  lonpix2=nullptr;
105 
106  l1cfile=nullptr;
107 
108  //ancill info?
109 }
110 
111 
113 }
114 
115 int32_t l2_str::openl2_ocis_l1c(L1C_input *l1cinput,l2_str *l2str,l1c_filehandle *l1cfile,int16_t *file_id){
116 
118  const char *ptstr;
119 
120  string delim1 = ":, "; // product delimiters
121  string l2prod_str = l1cinput->l2prod;
122  boost::trim_if(l2prod_str, boost::is_any_of(delim1));
123  vector<string> prodparam;
124  boost::algorithm::split(prodparam, l2prod_str,
125  boost::is_any_of(delim1));
126  cout<<"number of L2 products to be processed...................#:..."<<prodparam.size()<<endl;
127  for(size_t iprod=0;iprod<prodparam.size();iprod++){
128  cout<<"selected L2 ----------- prodparam...."<<prodparam[iprod]<<endl;
129  }
130 
131  //nl2prod member of l2_str
132  nl2prod=prodparam.size();//number of selected l2 products
133 
135  ptstr=str.c_str();
136  printf("Opening OCIS L2 file\n");
137  cout<<str<<endl;
138 
139  status = nc_open(ptstr, NC_NOWRITE, &ncid_L1B);
140  if (status != NC_NOERR) {
141  fprintf(stderr, "-E- %s line %d: nc_open(%s) failed.\n",
142  __FILE__, __LINE__, ptstr);
143  return (1);
144  }
145 
146  // num_scans
147  status = nc_inq_dimid(ncid_L1B, "number_of_lines", &dimid);
148  if (status != NC_NOERR) {
149  fprintf(stderr, "-E- Error reading number_of_scans.\n");
150  exit(EXIT_FAILURE);
151  }
152  nc_inq_dimlen(ncid_L1B, dimid, &num_scans);
153  l2str->nscan=num_scans;
154 
155  // num_pixels
156  status = nc_inq_dimid(ncid_L1B, "pixels_per_line", &dimid);
157  if (status != NC_NOERR) {
158  fprintf(stderr, "-E- Error reading num_pixels.\n");
159  exit(EXIT_FAILURE);
160  }
161  nc_inq_dimlen(ncid_L1B, dimid, &num_pixels);
162  l2str->npix=num_pixels;
163 
164  // number of bands
165  status = nc_inq_dimid(ncid_L1B, "number_of_bands", &dimid);
166  if (status != NC_NOERR) {
167  fprintf(stderr, "-E- Error reading number of_bands.\n");
168  exit(EXIT_FAILURE);
169  }
170  nc_inq_dimlen(ncid_L1B, dimid, &number_of_bands);
171  if(number_of_bands < expected_number_of_bands) {
172  fprintf(stderr, "-E- Not enough bands, expecting %d, found %d.\n",
173  (int)expected_number_of_bands, (int)number_of_bands);
174  exit(EXIT_FAILURE);
175  }
176 
177 // if (want_verbose) {
178  printf("OCI L2 Npix :%d Nlines:%d\n", (int)num_pixels, (int)num_scans);
179 // } // want_verbose
180 
181 
182 // allocate all of the data
183  tmpShort = (short*) calloc(num_pixels, sizeof(short));
184  scan_time = (double*) calloc(num_scans, sizeof(double));
185  l2str->tilt=(float*)calloc(num_scans,sizeof(float));
186  l2str->latpix=(float*)calloc(num_pixels,sizeof(float));
187  l2str->lonpix=(float*)calloc(num_pixels,sizeof(float));
188  l2str->l2prod = allocate2d_float(nl2prod, num_pixels);
189 
190 
191 
192  // Get group id from L1B file for GROUP scan_line_attributes.
193  int groupid;
194  if ((nc_inq_grp_ncid(ncid_L1B, "scan_line_attributes", &groupid)) == NC_NOERR) {
195  } else {
196  fprintf(stderr, "-E- Error finding scan_line_attributes.\n");
197  exit(EXIT_FAILURE);
198  }
199  int varid;
200  double scan_timeFillValue = -999.9;
201  status = nc_inq_varid(groupid, "time", &varid);
202  if(status == NC_NOERR) {
203  status = nc_inq_var_fill(groupid, varid, NULL, &scan_timeFillValue);
204  check_err(status, __LINE__, __FILE__);
205  status = nc_get_var_double(groupid, varid, scan_time);
206  check_err(status, __LINE__, __FILE__);
207  status = nc_get_att_int(groupid, varid, "year", &scan_time_year);
208  check_err(status, __LINE__, __FILE__);
209  status = nc_get_att_int(groupid, varid, "month", &scan_time_month);
210  check_err(status, __LINE__, __FILE__);
211  status = nc_get_att_int(groupid, varid, "day", &scan_time_day);
212  check_err(status, __LINE__, __FILE__);
213  } else {
214  status = nc_inq_varid(groupid, "msec", &varid);
215  check_err(status, __LINE__, __FILE__);
216  status = nc_inq_var_fill(groupid, varid, NULL, &scan_timeFillValue);
217  check_err(status, __LINE__, __FILE__);
218  status = nc_get_var_double(groupid, varid, scan_time);
219  check_err(status, __LINE__, __FILE__);
220 
221  // get start time
222  size_t att_len;
223  status = nc_inq_attlen(ncid_L1B, NC_GLOBAL, "time_coverage_start", &att_len);
224  check_err(status, __LINE__, __FILE__);
225 
226  // allocate required space before retrieving values
227  char* time_str = (char *) malloc(att_len + 1); // + 1 for trailing null
228 
229  // get attribute values
230  status = nc_get_att_text(ncid_L1B, NC_GLOBAL, "time_coverage_start", time_str);
231  check_err(status, __LINE__, __FILE__);
232  time_str[att_len] = '\0';
233 
234  double start_time = isodate2unix(time_str);
235  int16_t syear, smon, sday;
236  double secs;
237  unix2ymds(start_time, &syear, &smon, &sday, &secs);
238  scan_time_year = syear;
239  scan_time_month = smon;
240  scan_time_day = sday;
241 
242  }
243 
244  for(size_t i=0; i<num_scans; i++) {
245  if(scan_time[i] == scan_timeFillValue)
246  scan_time[i] = BAD_FLT;
247  }
248 
249  // read the orbit#
250  int orbit_number;
251  status = nc_get_att_int(ncid_L1B, NC_GLOBAL, "orbit_number", &orbit_number);
252  check_err(status, __LINE__, __FILE__);
253 
254  // Setup geofile pointers
255  status = nc_inq_grp_ncid(ncid_L1B, "navigation_data", &geolocationGrp);
256  check_err(status, __LINE__, __FILE__);
257  status = nc_inq_varid(geolocationGrp, "longitude", &lonId);
258  check_err(status, __LINE__, __FILE__);
259 
260  status = nc_inq_var_fill(geolocationGrp, lonId, NULL, &lonFillValue);
261  check_err(status, __LINE__, __FILE__);
262  status = nc_inq_varid(geolocationGrp, "latitude", &latId);
263  check_err(status, __LINE__, __FILE__);
264  status = nc_inq_var_fill(geolocationGrp, latId, NULL, &latFillValue);
265  check_err(status, __LINE__, __FILE__);
266 
267  status = nc_inq_varid(geolocationGrp, "tilt", &tiltId);//number of lines
268  check_err(status, __LINE__, __FILE__);
269  status = nc_inq_var_fill(geolocationGrp, tiltId, NULL, &tiltFillValue);
270  check_err(status, __LINE__, __FILE__);
271  status = nc_get_att_float(geolocationGrp, tiltId, "valid_min", &tiltmin);
272  check_err(status, __LINE__, __FILE__);
273  status = nc_get_att_float(geolocationGrp, tiltId, "valid_max", &tiltmax);
274  check_err(status, __LINE__, __FILE__);
275 
276 
277 
278  // get IDs for the observations
279  status = nc_inq_grp_ncid(ncid_L1B, "geophysical_data", &observationGrp);
280  check_err(status, __LINE__, __FILE__);
281 
282  for (size_t iprod = 0;iprod <nl2prod;iprod++) {
283  cout<<"getting sds id for product.."<<prodparam[iprod].c_str()<<endl;
284  status = nc_inq_varid(observationGrp, prodparam[iprod].c_str(), &prodims[iprod]);
285  check_err(status, __LINE__, __FILE__);
286  }
287 
288 
289 //slope offset of products
290  l2str->slopeprod = (float*) calloc(nl2prod, sizeof(float));
291  l2str->offsetprod = (float*) calloc(nl2prod, sizeof(float));
292 
293  string ATT_NAME1="scale_factor",ATT_NAME2="add_offset";
294  for (size_t iprod = 0;iprod <nl2prod;iprod++) {
295  if (nc_get_att_float(observationGrp, prodims[iprod], ATT_NAME1.c_str(), &l2str->slopeprod[iprod]))
296  check_err(status, __LINE__, __FILE__);
297  if (nc_get_att_float(observationGrp, prodims[iprod], ATT_NAME2.c_str() , &l2str->offsetprod[iprod]))
298  check_err(status, __LINE__, __FILE__);
299  }
300 
301 
302 
303 //tilt
304  status = nc_get_var_float(geolocationGrp,tiltId,l2str->tilt);
305  check_err(status, __LINE__, __FILE__);
306 
307 
308 
309 
310 
311 //l1cfile class---
312  l1cfile->sd_id = ncid_L1B;
313  l1cfile->nbands=number_of_bands;
314  nviews=2;
315  l1cfile->n_views=nviews;
316 
317 
318  cout<<"number of bands ="<<l1cfile->nbands<<endl;
319 
320  l1cfile->npix = num_pixels;
321  l1cfile->nadpix=(num_pixels-1)/2;//nadir pixel index
322  l1cfile->nscan = num_scans;
323  l1cfile->ndets = 1;
324  l1cfile->terrain_corrected = 1; // presumed.
325  l1cfile->orbit_number = orbit_number;
326 
327 
328 
329 return 0;
330 }
331 
332 
333 int32_t l2_str::readl2_ocis_l1c(l2_str *l2str,l1c_filehandle *l1cfile, int16_t *file_id,int32_t sline){
334 
335  size_t start[] = {0,0};
336  size_t count[] = {1,1};
337 
338  string str;
340  printf("Reading OCIS L2 file\n");
341  cout<<str<<endl;
342 
343 
344  //assigning mem for Lt of different bands **********************
345 
346 //GEOLOCATION
347  l2str->iscan=sline;
348  start[0] = sline;
349  start[1] = 0;
350  count[0] = 1;
351  count[1] = num_pixels; // 1 line at a time
352 
353 
354  status = nc_get_vara_float(geolocationGrp, latId, start, count, l2str->latpix);
355  check_err(status, __LINE__, __FILE__);
356  status = nc_get_vara_float(geolocationGrp, lonId, start, count, l2str->lonpix);
357  check_err(status, __LINE__, __FILE__);
358 
359 //L2 products
360  for (size_t iprod = 0;iprod <nl2prod;iprod++) {
361  status = nc_get_vara_float(observationGrp,prodims[iprod],start, count, l2str->l2prod[iprod]);
362  check_err(status, __LINE__, __FILE__);
363  }
364 
365 
366 return 0;
367 }
368 
369 
370 
372  string str;
374 
375  printf("Closing ocis L2 file\n");
376  cout<<str<<endl;
377  status = nc_close(l1cfile->sd_id);
378  check_err(status, __LINE__, __FILE__);
379  // Free memory
380 
381  if (l2str->latpix != nullptr)
382  delete [] (l2str->latpix);
383  if (l2str->lonpix != nullptr)
384  delete [] (l2str->lonpix);
385  if (l2str->slopeprod != nullptr)
386  delete [] (l2str->slopeprod);
387  if (l2str->offsetprod != nullptr)
388  delete [] (l2str->offsetprod);
389  if (l2str->tilt != nullptr)
390  delete [] (l2str->tilt);
391  if (l2str->l2prod != nullptr)
392  delete [] (l2str->l2prod);
393 
394  if (tmpShort) free(tmpShort);
395  if (scan_time) free(scan_time);
396 
397  l2str->latpix=nullptr;
398  l2str->slopeprod=nullptr;
399  l2str->lonpix=nullptr;
400  l2str->offsetprod=nullptr;
401  l2str->tilt=nullptr;
402 return 0;
403 }
404 
405 
406 
407 
408 
409 } // namespace l1c
410 
411 
412 
float * offsetprod
Definition: l2_str.h:58
Utility functions for allocating and freeing three-dimensional arrays of various types.
int status
Definition: l1_czcs_hdf.c:32
void check_err(const int stat, const int line, const char *file)
Definition: nc4utils.c:35
float ** l2prod
Definition: l2_str.h:55
char l2prod[2048]
Definition: l1c_input.h:42
std::string l1b_name
size_t nl2prod
Definition: l2_str.h:56
#define NULL
Definition: decode_rs.h:63
size_t nscan
Definition: l2_str.h:40
float * tilt
Definition: l2_str.h:59
void unix2ymds(double usec, int16_t *year, int16_t *mon, int16_t *day, double *secs)
Definition: unix2ymds.c:8
float * slopeprod
Definition: l2_str.h:57
virtual int32_t closel2_ocis_l1c(l2_str *l2str, l1c_filehandle *l1cfile)
Definition: l2_str.cpp:371
int syear
Definition: l1_czcs_hdf.c:15
l1c_filehandle * l1cfile
Definition: l2_str.h:82
int32 nscan
Definition: l1_czcs_hdf.c:19
@ string
int sday
Definition: l1_czcs_hdf.c:15
int time_str(short, short, int, char *)
Definition: time_str.c:3
virtual ~l2_str()
Definition: l2_str.cpp:112
virtual int32_t openl2_ocis_l1c(L1C_input *l1cinput, l2_str *l2str, l1c_filehandle *l1cfile, int16_t *file_id)
Definition: l2_str.cpp:115
size_t npix
Definition: l2_str.h:38
Utility functions for allocating and freeing four-dimensional arrays of various types.
virtual int32_t readl2_ocis_l1c(l2_str *l2str, l1c_filehandle *l1cfile, int16_t *file_id, int32_t recnum)
Definition: l2_str.cpp:333
float * lonpix
Definition: l2_str.h:77
Definition: l1c.cpp:76
Utility functions for allocating and freeing two-dimensional arrays of various types.
const char * str
Definition: l1c_msi.cpp:35
#define BAD_FLT
Definition: jplaeriallib.h:19
float * latpix
Definition: l2_str.h:76
size_t iscan
Definition: l2_str.h:39
int32 dpix
Definition: l1_czcs_hdf.c:22
int32 spix
Definition: l1_czcs_hdf.c:21
int32_t iscan
int32 epix
Definition: l1_czcs_hdf.c:23
float ** allocate2d_float(size_t h, size_t w)
Allocate a two-dimensional array of type float of a given size.
Definition: allocate2d.c:125
float32 * att_ang
Definition: l1_czcs_hdf.c:34
int16_t * tilt
Definition: l2bin.cpp:86
int i
Definition: decode_rs.h:71
int npix
Definition: get_cmp.c:27
double isodate2unix(const char *isodate)
Definition: unix2isodate.c:61
int count
Definition: decode_rs.h:79