OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l1c_str.cpp
Go to the documentation of this file.
1 //
2 // l1c_str.cpp
3 //
4 //
5 // Created by Martin Montes on 7/17/2021
6 #include "l1c_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 //static float *Fobar; // reflectance to radiance conversion factors
27 //static int extract_pixel_start = 0;
28 
29 static short *tmpShort;
30 
31 // whole file stuff
32 static size_t expected_num_blue_bands = 60; //120;
33 static size_t expected_num_red_bands = 60; //120;
34 static size_t expected_num_SWIR_bands = 9;
35 
36 static size_t nviews;
37 //static size_t nbands;
38 static size_t num_scans, num_pixels;
39 static size_t num_blue_bands, num_red_bands, num_SWIR_bands;
40 //static size_t tot_num_bands = 123; //238;
41 static int ncid_L1B;
42 
43 // scan line attributes
44 static double *scan_time; // seconds of day
45 static int32_t scan_time_year, scan_time_month, scan_time_day;
46 //static int32_t scan_time_hour,scan_time_min;
47 //static double scan_time_secs;
48 
49 //static uint_8 *scan_quality;
50 
51 // geolocation data
52 static int geolocationGrp;
53 static int lonId, latId, senzId, senaId, solzId, solaId;
54 static float latFillValue = -999.0;
55 static float lonFillValue = -999.0;
56 static short senzFillValue = -32768;
57 static float senzScale = 0.01;
58 static float senzOffset = 0.0;
59 static short senaFillValue = -32768;
60 static float senaScale = 0.01;
61 static float senaOffset = 0.0;
62 static short solzFillValue = -32768;
63 static float solzScale = 0.01;
64 static float solzOffset = 0.0;
65 static short solaFillValue = -32768;
66 static float solaScale = 0.01;
67 static float solaOffset = 0.0;
68 
69 // Observation data
70 static int observationGrp;
71 static int Lt_blueId, Lt_redId, Lt_SWIRId;
72 //static float **Lt_blue; //[num_blue_bands][num_pixels], This scan
73 //static float **Lt_red; //[num_red_bands][num_pixels], This scan
74 //static float **Lt_SWIR; //[num_SWIR_bands][num_pixels], This scan
75 
76 //static float ****Lt_all;
77 
78 static float Lt_blueFillValue = -999.0;
79 static float Lt_redFillValue = -999.0;
80 static float Lt_SWIRFillValue = -999.0;
81 
82 
83 //Navigation data
84 //static int navGrp;
85 //static int ovId,opId,attID;
86 //static float *orbv;//for each scan we have xpixels dim
87 //static float *orbp;
88 //static float *attang;
89 //static double *timeArr;
90 
91 static int status,dimid;
92 
93 using namespace std;
94 
95 
96 
97 
98 
99 
100 
101 
102 
103 
104 namespace l1c {
105 
106  l1c_str::l1c_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} {
107 
108  //init constructor
109  //global attributes
110  npix=-1;
111  iscan=0;
112  nscan=-1;
113  //scan line attributes--
114  ev_mid_time=nullptr;
115  scan_quality_flag=nullptr;
116  spix=-1;
117  epix=-1;
118  dpix=-1;
119 
120  // structure--pointers to data arrays
121  Lt=nullptr; //dim depends between sensors--OCI is bands x pixels --
122  Lt_blue=nullptr; //[num_views][num_pol][num_blue_bands][num_pixels]
123  Lt_red=nullptr;
124  Lt_SWIR=nullptr;
125 
126  //sensor/sun geometry
127  senz=nullptr;
128  sena=nullptr;
129  solz=nullptr;
130  sola=nullptr;
131  delphi=nullptr;
132  scattang=nullptr;
133 
134  //geolocation--
135  senazpix=nullptr;
136  latpix=nullptr;
137  lonpix=nullptr;
138  latpix2=nullptr;
139  lonpix2=nullptr;
140  latnad=nullptr;
141  lonnad=nullptr;
142  lonershift=nullptr;
143  terr_height=nullptr;
144  cloud_height=nullptr;
145 
146 
147  l1cfile=nullptr;
148 
149  //ancill info?
150 }
151 
152 
154 }
155 
156 int32_t l1c_str::openl1b_ocis_l1c(l1c_str *l1cstr,l1c_filehandle *l1cfile,int16_t *file_id){
157 
159  const char *ptstr;
160 
161  // Open the netcdf4 input file
162  str=l1cfile->l1b_name;
163  ptstr=str.c_str();
164  printf("Opening OCIS L1B file\n");
165  cout<<str<<endl;
166 
167  status = nc_open(ptstr, NC_NOWRITE, &ncid_L1B);
168  if (status != NC_NOERR) {
169  fprintf(stderr, "-E- %s line %d: nc_open(%s) failed.\n",
170  __FILE__, __LINE__, ptstr);
171  return (1);
172  }
173 
174  // num_scans
175  status = nc_inq_dimid(ncid_L1B, "number_of_scans", &dimid);
176  if (status != NC_NOERR) {
177  fprintf(stderr, "-E- Error reading number_of_scans.\n");
178  exit(EXIT_FAILURE);
179  }
180  nc_inq_dimlen(ncid_L1B, dimid, &num_scans);
181  l1cstr->nscan=num_scans;
182 
183  // num_pixels
184  status = nc_inq_dimid(ncid_L1B, "ccd_pixels", &dimid);
185  if (status != NC_NOERR) {
186  fprintf(stderr, "-E- Error reading num_pixels.\n");
187  exit(EXIT_FAILURE);
188  }
189  nc_inq_dimlen(ncid_L1B, dimid, &num_pixels);
190  l1cstr->npix=num_pixels;
191 
192  // num_blue_bands
193  status = nc_inq_dimid(ncid_L1B, "blue_bands", &dimid);
194  if (status != NC_NOERR) {
195  fprintf(stderr, "-E- Error reading num_blue_bands.\n");
196  exit(EXIT_FAILURE);
197  }
198  nc_inq_dimlen(ncid_L1B, dimid, &num_blue_bands);
199  if(num_blue_bands < expected_num_blue_bands) {
200  fprintf(stderr, "-E- Not enough blue bands, expecting %d, found %d.\n",
201  (int)expected_num_blue_bands, (int)num_blue_bands);
202  exit(EXIT_FAILURE);
203  }
204 
205  // num_red_bands
206  status = nc_inq_dimid(ncid_L1B, "red_bands", &dimid);
207  if (status != NC_NOERR) {
208  fprintf(stderr, "-E- Error reading num_red_bands.\n");
209  exit(EXIT_FAILURE);
210  };
211  nc_inq_dimlen(ncid_L1B, dimid, &num_red_bands);
212  if(num_red_bands < expected_num_red_bands) {
213  fprintf(stderr, "-E- Not enough red bands, expecting %d, found %d.\n",
214  (int)expected_num_red_bands, (int)num_red_bands);
215  exit(EXIT_FAILURE);
216  }
217 
218  // num_SWIR_bands
219  status = nc_inq_dimid(ncid_L1B, "SWIR_bands", &dimid);
220  if (status != NC_NOERR) {
221  fprintf(stderr, "-E- Error reading num_SWIR_bands.\n");
222  exit(EXIT_FAILURE);
223  };
224  nc_inq_dimlen(ncid_L1B, dimid, &num_SWIR_bands);
225  if(num_SWIR_bands < expected_num_SWIR_bands) {
226  fprintf(stderr, "-E- Not enough SWIR bands, expecting %d, found %d.\n",
227  (int)expected_num_SWIR_bands, (int)num_SWIR_bands);
228  exit(EXIT_FAILURE);
229  }
230 
231 // if (want_verbose) {
232  printf("OCI L1B Npix :%d Nlines:%d\n", (int)num_pixels, (int)num_scans);
233 // } // want_verbose
234 
235 
236 // allocate all of the data
237  tmpShort = (short*) calloc(num_pixels, sizeof(short));
238  scan_time = (double*) calloc(num_scans, sizeof(double));
239 
240  l1cstr->senazpix=(float*)calloc(num_pixels,sizeof(float));
241  l1cstr->latpix=(float*)calloc(num_pixels,sizeof(float));
242  l1cstr->lonpix=(float*)calloc(num_pixels,sizeof(float));
243  l1cstr->latpix2=(float*)calloc(num_pixels,sizeof(float));
244  l1cstr->lonpix2=(float*)calloc(num_pixels,sizeof(float));
245 
246 
247  l1cstr->Lt_blue = allocate2d_float(num_blue_bands, num_pixels);
248  l1cstr->Lt_red = allocate2d_float(num_red_bands, num_pixels);
249  l1cstr->Lt_SWIR = allocate2d_float(num_SWIR_bands, num_pixels);
250 
251  // Get group id from L1B file for GROUP scan_line_attributes.
252  int groupid;
253  if ((nc_inq_grp_ncid(ncid_L1B, "scan_line_attributes", &groupid)) == NC_NOERR) {
254  } else {
255  fprintf(stderr, "-E- Error finding scan_line_attributes.\n");
256  exit(EXIT_FAILURE);
257  }
258  int varid;
259  double scan_timeFillValue = -999.9;
260  status = nc_inq_varid(groupid, "time", &varid);
261  if(status == NC_NOERR) {
262  status = nc_inq_var_fill(groupid, varid, NULL, &scan_timeFillValue);
263  check_err(status, __LINE__, __FILE__);
264  status = nc_get_var_double(groupid, varid, scan_time);
265  check_err(status, __LINE__, __FILE__);
266  status = nc_get_att_int(groupid, varid, "year", &scan_time_year);
267  check_err(status, __LINE__, __FILE__);
268  status = nc_get_att_int(groupid, varid, "month", &scan_time_month);
269  check_err(status, __LINE__, __FILE__);
270  status = nc_get_att_int(groupid, varid, "day", &scan_time_day);
271  check_err(status, __LINE__, __FILE__);
272  } else {
273  status = nc_inq_varid(groupid, "ev_mid_time", &varid);
274  check_err(status, __LINE__, __FILE__);
275  status = nc_inq_var_fill(groupid, varid, NULL, &scan_timeFillValue);
276  check_err(status, __LINE__, __FILE__);
277  status = nc_get_var_double(groupid, varid, scan_time);
278  check_err(status, __LINE__, __FILE__);
279 
280  // get start time
281  size_t att_len;
282  status = nc_inq_attlen(ncid_L1B, NC_GLOBAL, "time_coverage_start", &att_len);
283  check_err(status, __LINE__, __FILE__);
284 
285  // allocate required space before retrieving values
286  char* time_str = (char *) malloc(att_len + 1); // + 1 for trailing null
287 
288  // get attribute values
289  status = nc_get_att_text(ncid_L1B, NC_GLOBAL, "time_coverage_start", time_str);
290  check_err(status, __LINE__, __FILE__);
291  time_str[att_len] = '\0';
292 
293  double start_time = isodate2unix(time_str);
294  int16_t syear, smon, sday;
295  double secs;
296  unix2ymds(start_time, &syear, &smon, &sday, &secs);
297  scan_time_year = syear;
298  scan_time_month = smon;
299  scan_time_day = sday;
300 
301  }
302 
303  for(size_t i=0; i<num_scans; i++) {
304  if(scan_time[i] == scan_timeFillValue)
305  scan_time[i] = BAD_FLT;
306  }
307 
308  // read the orbit#
309  int orbit_number;
310  status = nc_get_att_int(ncid_L1B, NC_GLOBAL, "orbit_number", &orbit_number);
311  check_err(status, __LINE__, __FILE__);
312 
313  // Setup geofile pointers
314  status = nc_inq_grp_ncid(ncid_L1B, "geolocation_data", &geolocationGrp);
315  check_err(status, __LINE__, __FILE__);
316  status = nc_inq_varid(geolocationGrp, "longitude", &lonId);
317  check_err(status, __LINE__, __FILE__);
318 
319  status = nc_inq_var_fill(geolocationGrp, lonId, NULL, &lonFillValue);
320  check_err(status, __LINE__, __FILE__);
321  status = nc_inq_varid(geolocationGrp, "latitude", &latId);
322  check_err(status, __LINE__, __FILE__);
323  status = nc_inq_var_fill(geolocationGrp, latId, NULL, &latFillValue);
324  check_err(status, __LINE__, __FILE__);
325 
326  status = nc_inq_varid(geolocationGrp, "sensor_zenith", &senzId);
327  check_err(status, __LINE__, __FILE__);
328  status = nc_inq_var_fill(geolocationGrp, senzId, NULL, &senzFillValue);
329  check_err(status, __LINE__, __FILE__);
330  status = nc_get_att_float(geolocationGrp, senzId, "scale_factor", &senzScale);
331  check_err(status, __LINE__, __FILE__);
332  status = nc_get_att_float(geolocationGrp, senzId, "add_offset", &senzOffset);
333  check_err(status, __LINE__, __FILE__);
334 
335  status = nc_inq_varid(geolocationGrp, "sensor_azimuth", &senaId);
336  check_err(status, __LINE__, __FILE__);
337  status = nc_inq_var_fill(geolocationGrp, senaId, NULL, &senaFillValue);
338  check_err(status, __LINE__, __FILE__);
339  status = nc_get_att_float(geolocationGrp, senaId, "scale_factor", &senaScale);
340  check_err(status, __LINE__, __FILE__);
341  status = nc_get_att_float(geolocationGrp, senaId, "add_offset", &senaOffset);
342  check_err(status, __LINE__, __FILE__);
343 
344  status = nc_inq_varid(geolocationGrp, "solar_zenith", &solzId);
345  check_err(status, __LINE__, __FILE__);
346  status = nc_inq_var_fill(geolocationGrp, solzId, NULL, &solzFillValue);
347  check_err(status, __LINE__, __FILE__);
348  status = nc_get_att_float(geolocationGrp, solzId, "scale_factor", &solzScale);
349  check_err(status, __LINE__, __FILE__);
350  status = nc_get_att_float(geolocationGrp, solzId, "add_offset", &solzOffset);
351  check_err(status, __LINE__, __FILE__);
352 
353  status = nc_inq_varid(geolocationGrp, "solar_azimuth", &solaId);
354  check_err(status, __LINE__, __FILE__);
355  status = nc_inq_var_fill(geolocationGrp, solaId, NULL, &solaFillValue);
356  check_err(status, __LINE__, __FILE__);
357  status = nc_get_att_float(geolocationGrp, solaId, "scale_factor", &solaScale);
358  check_err(status, __LINE__, __FILE__);
359  status = nc_get_att_float(geolocationGrp, solaId, "add_offset", &solaOffset);
360  check_err(status, __LINE__, __FILE__);
361 
362 
363  // get IDs for the observations
364  status = nc_inq_grp_ncid(ncid_L1B, "observation_data", &observationGrp);
365  check_err(status, __LINE__, __FILE__);
366 
367  // Get varids for each of the Lt_*
368  status = nc_inq_varid(observationGrp, "Lt_blue", &Lt_blueId);
369  check_err(status, __LINE__, __FILE__);
370  status = nc_inq_var_fill(observationGrp, Lt_blueId, NULL, &Lt_blueFillValue);
371  check_err(status, __LINE__, __FILE__);
372 
373  status = nc_inq_varid(observationGrp, "Lt_red", &Lt_redId);
374  check_err(status, __LINE__, __FILE__);
375  status = nc_inq_var_fill(observationGrp, Lt_redId, NULL, &Lt_redFillValue);
376  check_err(status, __LINE__, __FILE__);
377 
378  status = nc_inq_varid(observationGrp, "Lt_SWIR", &Lt_SWIRId);
379  check_err(status, __LINE__, __FILE__);
380  status = nc_inq_var_fill(observationGrp, Lt_SWIRId, NULL, &Lt_SWIRFillValue);
381  check_err(status, __LINE__, __FILE__);
382 
383 
384  l1cfile->sd_id = ncid_L1B;
385  l1cfile->nband_blue=num_blue_bands;
386  l1cfile->nband_red=num_red_bands;
387  l1cfile->nband_swir=num_SWIR_bands;
388  l1cfile->nbands=num_blue_bands+num_red_bands+num_SWIR_bands;
389  nviews=2;
390  l1cfile->n_views=nviews;
391 
392  cout<<"file->nbands_b ="<<l1cfile->nband_blue<<endl;
393  cout<<"file->nbands_r = "<<l1cfile->nband_red<<endl;
394  cout<<"file->nbands_swir = "<<l1cfile->nband_swir<<endl;
395 
396  l1cfile->npix = num_pixels;
397  l1cfile->nadpix=(num_pixels-1)/2;//nadir pixel index
398  l1cfile->nscan = num_scans;
399  l1cfile->ndets = 1;
400  l1cfile->terrain_corrected = 1; // presumed.
401  l1cfile->orbit_number = orbit_number;
402 
403 // rdsensorinfo(l1cfile->sensorID, input->evalmask,
404 // "Fobar", (void **) &Fobar);
405 
406 // if (want_verbose)
407 // printf("file->nbands = %d\n", (int) file->nbands);
408 
409 return 0;
410 }
411 
412 
413 int32_t l1c_str::readl1b_ocis_l1c(l1c_str *l1cstr,l1c_filehandle *l1cfile, int16_t *file_id,int32_t sline){
414  size_t oneline;
415  size_t start[] = {0,0},start2[]={0,0},start3[] = {0,0,0};
416  size_t count[] = {1,1},count2[] = {1,1,1};
417  string str;
418 
419 
421 
422  printf("Reading OCIS L1B file\n");
423  cout<<str<<endl;
424 
425  //assigning mem for Lt of different bands **********************
426 
427 //GEOLOCATION
428  l1cstr->iscan=sline;
429 
430  start[0] = sline;
431  start[1] = 0;
432  count[0] = 1;
433  count[1] = num_pixels; // 1 line at a time
434 
435  status = nc_get_vara_float(geolocationGrp, senaId, start, count, l1cstr->senazpix);//sensor azimuth -1800 to 1800 degrees, so must be divdied by 100
436  status = nc_get_vara_float(geolocationGrp, latId, start, count, l1cstr->latpix);
437  check_err(status, __LINE__, __FILE__);
438  status = nc_get_vara_float(geolocationGrp, lonId, start, count, l1cstr->lonpix);
439  check_err(status, __LINE__, __FILE__);
440 
441 
442  oneline=sline;
443 
444  if(oneline<num_scans-1)
445  start2[0] = sline+1;
446  else
447  start2[0] = sline;
448 
449  start2[1] = 0;
450 
451 
452  status = nc_get_vara_float(geolocationGrp, latId, start2, count, l1cstr->latpix2);
453  check_err(status, __LINE__, __FILE__);
454  status = nc_get_vara_float(geolocationGrp, lonId, start2, count, l1cstr->lonpix2);
455  check_err(status, __LINE__, __FILE__);
456 
457 
458 //RADIANCES
459  start3[0] = 0;
460  start3[1] = sline;
461  start3[2] = 0;
462  count2[0] = num_blue_bands;
463  count2[1] = 1; // 1 line at a time
464  count2[2] = num_pixels;
465 
466  status = nc_get_vara_float(observationGrp, Lt_blueId, start3, count2, l1cstr->Lt_blue[0]);//these are 2-D arrays------------ #bands x #pixels
467  check_err(status, __LINE__, __FILE__);
468 
469  count2[0] = num_red_bands;
470  status = nc_get_vara_float(observationGrp, Lt_redId, start3, count2, l1cstr->Lt_red[0]);
471  check_err(status, __LINE__, __FILE__);
472 
473  count2[0] = num_SWIR_bands;
474  status = nc_get_vara_float(observationGrp, Lt_SWIRId, start3, count2, l1cstr->Lt_SWIR[0]);
475  check_err(status, __LINE__, __FILE__);
476 
477 return 0;
478 }
479 
480 
482  string str;
483 
485  printf("Closing ocis l1b file\n");
486  cout<<str<<endl;
487  status = nc_close(l1cfile->sd_id);
488  check_err(status, __LINE__, __FILE__);
489 
490 
491  // Free memory
492  // From openl1b_ocis
493  if (l1cstr->senazpix != nullptr)
494  delete [] (l1cstr->senazpix);
495  if (l1cstr->latpix != nullptr)
496  delete [] (l1cstr->latpix);
497  if (l1cstr->lonpix != nullptr)
498  delete [] (l1cstr->lonpix);
499  if (l1cstr->latpix2 != nullptr)
500  delete [] (l1cstr->latpix2);
501  if (l1cstr->lonpix2 != nullptr)
502  delete [] (l1cstr->lonpix2);
503 
504  if (tmpShort) free(tmpShort);
505  if (scan_time) free(scan_time);
506  if (l1cstr->Lt_blue) free2d_float(l1cstr->Lt_blue);
507  if (l1cstr->Lt_red) free2d_float(l1cstr->Lt_red);
508  if (l1cstr->Lt_SWIR) free2d_float(l1cstr->Lt_SWIR);
509 
510  l1cstr->latpix=nullptr;
511  l1cstr->latpix2=nullptr;
512  l1cstr->lonpix=nullptr;
513  l1cstr->lonpix2=nullptr;
514 
515  l1cstr->Lt_blue=nullptr;
516  l1cstr->Lt_red=nullptr;
517  l1cstr->Lt_SWIR=nullptr;
518 
519 return 0;
520 }
521 
522 
523 } // namespace l1c
virtual int32_t readl1b_ocis_l1c(l1c_str *l1cstr, l1c_filehandle *l1cfile, int16_t *file_id, int32_t recnum)
Definition: l1c_str.cpp:413
float ** Lt_blue
Definition: l1c_str.h:50
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
l1c_filehandle * l1cfile
Definition: l1c_str.h:81
float ** Lt_SWIR
Definition: l1c_str.h:52
std::string l1b_name
#define NULL
Definition: decode_rs.h:63
float * lonpix2
Definition: l1c_str.h:72
void unix2ymds(double usec, int16_t *year, int16_t *mon, int16_t *day, double *secs)
Definition: unix2ymds.c:8
float * latpix
Definition: l1c_str.h:69
float * senazpix
Definition: l1c_str.h:68
int syear
Definition: l1_czcs_hdf.c:15
int32 nscan
Definition: l1_czcs_hdf.c:19
float * latpix2
Definition: l1c_str.h:71
@ string
float * lonpix
Definition: l1c_str.h:70
int sday
Definition: l1_czcs_hdf.c:15
int time_str(short, short, int, char *)
Definition: time_str.c:3
virtual int32_t openl1b_ocis_l1c(l1c_str *l1cstr, l1c_filehandle *l1cfile, int16_t *file_id)
Definition: l1c_str.cpp:156
size_t iscan
Definition: l1c_str.h:39
Utility functions for allocating and freeing four-dimensional arrays of various types.
void free2d_float(float **p)
Free a two-dimensional array created by allocate2d_float.
Definition: allocate2d.c:142
virtual ~l1c_str()
Definition: l1c_str.cpp:153
size_t nscan
Definition: l1c_str.h:40
Definition: l1c.cpp:76
virtual int32_t closel1b_ocis_l1c(l1c_str *l1cstr, l1c_filehandle *l1cfile)
Definition: l1c_str.cpp:481
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
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
int i
Definition: decode_rs.h:71
size_t npix
Definition: l1c_str.h:38
int npix
Definition: get_cmp.c:27
double isodate2unix(const char *isodate)
Definition: unix2isodate.c:61
float ** Lt_red
Definition: l1c_str.h:51
int count
Definition: decode_rs.h:79