NASA Logo
Ocean Color Science Software

ocssw V2022
l1_l1c.c
Go to the documentation of this file.
1 /* ============================================================================ */
2 /* module l1_l1c.c - functions to read L1C for l2gen (l1info really) */
3 /* Written By: Don Shea */
4 /* */
5 /* ============================================================================ */
6 
7 #include <netcdf.h>
8 #include "l1_l1c.h"
9 
10 #include <nc4utils.h>
11 #include "libnav.h"
12 #include <stdio.h>
13 #include <math.h>
14 
15 
16 static short *tmpShort;
17 
18 static size_t num_scans, num_pixels;
19 static size_t num_bands;
20 static int ncid_L1C;
21 
22 // time
23 static double *scan_time;
24 static double file_start_day;
25 
26 // geolocation data
27 static int geolocationGrp;
28 static int lonId, latId;
29 static float latFillValue = BAD_FLT;
30 static float lonFillValue = BAD_FLT;
31 
44 int openl1_l1c(filehandle * file) {
45  int dimid, status;
46 
47  // Open the netcdf4 input file
48  printf("Opening L1C file\n");
49  status = nc_open(file->name, NC_NOWRITE, &ncid_L1C);
50  if (status != NC_NOERR) {
51  fprintf(stderr, "-E- %s line %d: nc_open(%s) failed.\n",
52  __FILE__, __LINE__, file->name);
53  return (1);
54  }
55 
56  // num_scans
57  status = nc_inq_dimid(ncid_L1C, "bins_along_track", &dimid);
58  if (status != NC_NOERR) {
59  fprintf(stderr, "-E- Error reading bins_along_track.\n");
60  exit(EXIT_FAILURE);
61  }
62  nc_inq_dimlen(ncid_L1C, dimid, &num_scans);
63 
64  // num_pixels
65  status = nc_inq_dimid(ncid_L1C, "bins_across_track", &dimid);
66  if (status != NC_NOERR) {
67  fprintf(stderr, "-E- Error reading bins_across_track.\n");
68  exit(EXIT_FAILURE);
69  }
70  nc_inq_dimlen(ncid_L1C, dimid, &num_pixels);
71 
72  // num_bands
73  status = nc_inq_dimid(ncid_L1C, "intensity_bands_per_view", &dimid);
74  if (status != NC_NOERR) {
75  fprintf(stderr, "-E- Error reading intensity_bands_per_view.\n");
76  exit(EXIT_FAILURE);
77  }
78  nc_inq_dimlen(ncid_L1C, dimid, &num_bands);
79 
80  if (want_verbose) {
81  printf("L1C Npix :%d Nlines:%d\n", (int)num_pixels, (int)num_scans);
82  } // want_verbose
83 
84  // allocate all of the data
85  tmpShort = (short*) malloc(num_pixels * sizeof(short));
86  scan_time = (double*) malloc(num_scans * sizeof(double));
87 
88  // Get group id from L1B file for GROUP bin_attributes.
89  int groupid;
90  if ((nc_inq_grp_ncid(ncid_L1C, "bin_attributes", &groupid)) == NC_NOERR) {
91  } else {
92  fprintf(stderr, "-E- Error finding bin_attributes.\n");
93  exit(EXIT_FAILURE);
94  }
95  int varid;
96  double scan_timeFillValue = BAD_FLT;
97  status = nc_inq_varid(groupid, "nadir_view_time", &varid);
98  if(status != NC_NOERR) {
99  fprintf(stderr, "-E- Error finding nadir_view_time.\n");
100  exit(EXIT_FAILURE);
101  }
102  status = nc_inq_var_fill(groupid, varid, NULL, &scan_timeFillValue);
103  check_err(status, __LINE__, __FILE__);
104  status = nc_get_var_double(groupid, varid, scan_time);
105  check_err(status, __LINE__, __FILE__);
106 
107  // get start time
108  size_t att_len;
109  status = nc_inq_attlen(ncid_L1C, NC_GLOBAL, "time_coverage_start", &att_len);
110  check_err(status, __LINE__, __FILE__);
111 
112  // allocate required space before retrieving values
113  char* time_str = (char *) malloc(att_len + 1); // + 1 for trailing null
114 
115  // get attribute values
116  status = nc_get_att_text(ncid_L1C, NC_GLOBAL, "time_coverage_start", time_str);
117  check_err(status, __LINE__, __FILE__);
118  time_str[att_len] = '\0';
119 
120  double start_time = isodate2unix(time_str);
121  int16_t syear, smon, sday;
122  double secs;
123  unix2ymds(start_time, &syear, &smon, &sday, &secs);
124  file_start_day = ymds2unix(syear, smon, sday, 0.0);
125 
126  free(time_str);
127 
128  for(int i=0; i<num_scans; i++) {
129  if(scan_time[i] == scan_timeFillValue)
130  scan_time[i] = BAD_FLT;
131  }
132 
133  // Setup geofile pointers
134  status = nc_inq_grp_ncid(ncid_L1C, "geolocation_data", &geolocationGrp);
135  check_err(status, __LINE__, __FILE__);
136  status = nc_inq_varid(geolocationGrp, "longitude", &lonId);
137  check_err(status, __LINE__, __FILE__);
138  status = nc_inq_var_fill(geolocationGrp, lonId, NULL, &lonFillValue);
139  check_err(status, __LINE__, __FILE__);
140  status = nc_inq_varid(geolocationGrp, "latitude", &latId);
141  check_err(status, __LINE__, __FILE__);
142  status = nc_inq_var_fill(geolocationGrp, latId, NULL, &latFillValue);
143  check_err(status, __LINE__, __FILE__);
144 
145  file->sd_id = ncid_L1C;
146  file->nbands = num_bands;
147  file->npix = num_pixels;
148  file->nscan = num_scans;
149  file->ndets = 1;
150  file->terrain_corrected = 1; // presumed.
151  strcpy(file->spatialResolution, "5.2km");
152 
153  if (want_verbose)
154  printf("file->nbands = %d\n", (int) file->nbands);
155 
156  return (LIFE_IS_GOOD);
157 }
158 
159 
172 int readl1_l1c(filehandle *file, int32_t line, l1str *l1rec) {
173 
174  int status;
175  size_t start[] = { 0, 0, 0 };
176  size_t count[] = { 1, 1, 1 };
177 
178  for (int ip = 0; ip < num_pixels; ip++) {
179  l1rec->pixnum[ip] = ip;
180  }
181 
182  l1rec->npix = file->npix;
183  if(scan_time[line] == BAD_FLT) {
184  l1rec->scantime = BAD_FLT;
185  l1rec->fsol = BAD_FLT;
186  } else {
187  l1rec->scantime = file_start_day + scan_time[line];
188 
189  int16_t syear, sday;
190  double secs;
191  unix2yds(l1rec->scantime, &syear, &sday, &secs);
192 
193  int32_t yr = syear;
194  int32_t dy = sday;
195  int32_t msec = (int32_t) (secs * 1000.0);
196  double esdist = esdist_(&yr, &dy, &msec);
197 
198  l1rec->fsol = pow(1.0 / esdist, 2);
199  }
200 
201  start[0] = line;
202  start[1] = 0;
203  start[2] = 0;
204  count[0] = 1;
205  count[1] = num_pixels; // 1 line at a time
206  count[2] = 1;
207  status = nc_get_vara_float(geolocationGrp, latId, start, count, l1rec->lat);
208  check_err(status, __LINE__, __FILE__);
209  status = nc_get_vara_float(geolocationGrp, lonId, start, count, l1rec->lon);
210  check_err(status, __LINE__, __FILE__);
211 
212  for(int i=0; i<num_pixels; i++) {
213  if(l1rec->lat[i] == latFillValue)
214  l1rec->lat[i] = BAD_FLT;
215  if(l1rec->lon[i] == lonFillValue)
216  l1rec->lon[i] = BAD_FLT;
217 
218  // set solz to 0 so all pixels are daytime
219  l1rec->solz[i] = 0.0;
220 
221  }
222 
223  return (LIFE_IS_GOOD);
224 }
225 
226 
232 int closel1_l1c(filehandle *file) {
233  int status;
234 
235  printf("Closing L1C file\n");
236  status = nc_close(file->sd_id);
237  check_err(status, __LINE__, __FILE__);
238 
239  // Free memory
240  // From openl1_oci
241  if (tmpShort) free(tmpShort);
242  if (scan_time) free(scan_time);
243 
244  return (LIFE_IS_GOOD);
245 }
246 
247 
248 
249 
250 
int status
Definition: l1_czcs_hdf.c:32
void check_err(const int stat, const int line, const char *file)
Definition: nc4utils.c:35
#define NULL
Definition: decode_rs.h:63
int readl1_l1c(filehandle *file, int32_t line, l1str *l1rec)
Definition: l1_l1c.c:172
read l1rec
void unix2ymds(double usec, int16_t *year, int16_t *mon, int16_t *day, double *secs)
Definition: unix2ymds.c:8
int32 * msec
Definition: l1_czcs_hdf.c:31
double esdist_(int32_t *year, int32_t *day, int32_t *msec)
int syear
Definition: l1_czcs_hdf.c:15
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed file
Definition: HISTORY.txt:413
#define LIFE_IS_GOOD
Definition: passthebuck.h:4
int sday
Definition: l1_czcs_hdf.c:15
int time_str(short, short, int, char *)
Definition: time_str.c:3
int want_verbose
void unix2yds(double usec, short *year, short *day, double *secs)
#define BAD_FLT
Definition: jplaeriallib.h:19
int openl1_l1c(filehandle *file)
Definition: l1_l1c.c:44
real *8 function esdist(iyr, iday, msec)
Definition: esdist.f:3
double ymds2unix(short year, short month, short day, double secs)
int i
Definition: decode_rs.h:71
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int closel1_l1c(filehandle *file)
Definition: l1_l1c.c:232
double isodate2unix(const char *isodate)
Definition: unix2isodate.c:61
int count
Definition: decode_rs.h:79