NASA Logo
Ocean Color Science Software

ocssw V2022
l1_l1c_anc.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_anc.h"
9 
10 #include <nc4utils.h>
11 #include "libnav.h"
12 #include <stdio.h>
13 #include <math.h>
14 
15 
16 static size_t num_scans, num_pixels;
17 static int ncid_L1C;
18 
19 // time
20 static double start_time;
21 static double end_time;
22 static double delta_time;
23 
24 // geolocation data
25 static int lonId, latId;
26 static float latFillValue = BAD_FLT;
27 static float lonFillValue = BAD_FLT;
28 
36 int openl1_l1c_anc(filehandle * file) {
37  int dimid, status;
38 
39  // Open the netcdf4 input file
40  printf("Opening L1C file\n");
41  status = nc_open(file->name, NC_NOWRITE, &ncid_L1C);
42  if (status != NC_NOERR) {
43  fprintf(stderr, "-E- %s line %d: nc_open(%s) failed.\n",
44  __FILE__, __LINE__, file->name);
45  return (1);
46  }
47 
48  // num_scans
49  status = nc_inq_dimid(ncid_L1C, "bins_along_track", &dimid);
50  if (status != NC_NOERR) {
51  fprintf(stderr, "-E- Error reading bins_along_track.\n");
52  exit(EXIT_FAILURE);
53  }
54  nc_inq_dimlen(ncid_L1C, dimid, &num_scans);
55 
56  // num_pixels
57  status = nc_inq_dimid(ncid_L1C, "bins_across_track", &dimid);
58  if (status != NC_NOERR) {
59  fprintf(stderr, "-E- Error reading bins_across_track.\n");
60  exit(EXIT_FAILURE);
61  }
62  nc_inq_dimlen(ncid_L1C, dimid, &num_pixels);
63 
64  if (want_verbose) {
65  printf("L1C Ancillary Npix :%d Nlines:%d\n", (int)num_pixels, (int)num_scans);
66  } // want_verbose
67 
68  // get start time
69  size_t att_len;
70  status = nc_inq_attlen(ncid_L1C, NC_GLOBAL, "time_coverage_start", &att_len);
71  check_err(status, __LINE__, __FILE__);
72 
73  // allocate required space before retrieving values
74  char* time_str = (char *) malloc(att_len + 1); // + 1 for trailing null
75 
76  // get attribute values
77  status = nc_get_att_text(ncid_L1C, NC_GLOBAL, "time_coverage_start", time_str);
78  check_err(status, __LINE__, __FILE__);
79  time_str[att_len] = '\0';
80  start_time = isodate2unix(time_str);
81  free(time_str);
82 
83  // get end time
84  status = nc_inq_attlen(ncid_L1C, NC_GLOBAL, "time_coverage_end", &att_len);
85  check_err(status, __LINE__, __FILE__);
86 
87  // allocate required space before retrieving values
88  time_str = (char *) malloc(att_len + 1); // + 1 for trailing null
89 
90  // get attribute values
91  status = nc_get_att_text(ncid_L1C, NC_GLOBAL, "time_coverage_end", time_str);
92  check_err(status, __LINE__, __FILE__);
93  time_str[att_len] = '\0';
94  end_time = isodate2unix(time_str);
95  free(time_str);
96 
97  delta_time = (end_time - start_time) / num_scans;
98 
99  // Setup geofile pointers
100  status = nc_inq_varid(ncid_L1C, "longitude", &lonId);
101  check_err(status, __LINE__, __FILE__);
102  status = nc_inq_var_fill(ncid_L1C, lonId, NULL, &lonFillValue);
103  check_err(status, __LINE__, __FILE__);
104  status = nc_inq_varid(ncid_L1C, "latitude", &latId);
105  check_err(status, __LINE__, __FILE__);
106  status = nc_inq_var_fill(ncid_L1C, latId, NULL, &latFillValue);
107  check_err(status, __LINE__, __FILE__);
108 
109  file->sd_id = ncid_L1C;
110  file->npix = num_pixels;
111  file->nscan = num_scans;
112  file->ndets = 1;
113  file->terrain_corrected = 1; // presumed.
114  strcpy(file->spatialResolution, "5.2km");
115 
116  return (LIFE_IS_GOOD);
117 }
118 
119 
132 int readl1_l1c_anc(filehandle *file, int32_t line, l1str *l1rec) {
133 
134  int status;
135  size_t start[] = { 0, 0, 0 };
136  size_t count[] = { 1, 1, 1 };
137 
138  for (int ip = 0; ip < num_pixels; ip++) {
139  l1rec->pixnum[ip] = ip;
140  }
141 
142  l1rec->npix = file->npix;
143  l1rec->scantime = start_time + (delta_time * line);
144 
145  int16_t syear, sday;
146  double secs;
147  unix2yds(l1rec->scantime, &syear, &sday, &secs);
148 
149  int32_t yr = syear;
150  int32_t dy = sday;
151  int32_t msec = (int32_t) (secs * 1000.0);
152  double esdist = esdist_(&yr, &dy, &msec);
153 
154  l1rec->fsol = pow(1.0 / esdist, 2);
155 
156  start[0] = line;
157  start[1] = 0;
158  start[2] = 0;
159  count[0] = 1;
160  count[1] = num_pixels; // 1 line at a time
161  count[2] = 1;
162  status = nc_get_vara_float(ncid_L1C, latId, start, count, l1rec->lat);
163  check_err(status, __LINE__, __FILE__);
164  status = nc_get_vara_float(ncid_L1C, lonId, start, count, l1rec->lon);
165  check_err(status, __LINE__, __FILE__);
166 
167  for(int i=0; i<num_pixels; i++) {
168  if(l1rec->lat[i] == latFillValue)
169  l1rec->lat[i] = BAD_FLT;
170  if(l1rec->lon[i] == lonFillValue)
171  l1rec->lon[i] = BAD_FLT;
172 
173  // set solz to 0 so all pixels are daytime
174  l1rec->solz[i] = 0.0;
175 
176  }
177 
178  return (LIFE_IS_GOOD);
179 }
180 
181 
187 int closel1_l1c_anc(filehandle *file) {
188  int status;
189 
190  printf("Closing L1C Ancillary file\n");
191  status = nc_close(file->sd_id);
192  check_err(status, __LINE__, __FILE__);
193 
194  return (LIFE_IS_GOOD);
195 }
196 
197 
198 
199 
200 
int readl1_l1c_anc(filehandle *file, int32_t line, l1str *l1rec)
Definition: l1_l1c_anc.c:132
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
read l1rec
int closel1_l1c_anc(filehandle *file)
Definition: l1_l1c_anc.c:187
int openl1_l1c_anc(filehandle *file)
Definition: l1_l1c_anc.c:36
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
real *8 function esdist(iyr, iday, msec)
Definition: esdist.f:3
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")
double isodate2unix(const char *isodate)
Definition: unix2isodate.c:61
int count
Definition: decode_rs.h:79