OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l1_goci.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <stdio.h>
3 
4 #include "l1.h"
5 #include "hdf5.h"
6 #include "hdf5_hl.h"
7 #include <proj.h>
8 
9 #include "goci.h"
10 #include "l1_goci.h"
11 #include <libnav.h>
12 
13 static goci_l1b_t *goci_l1b = NULL;
14 
15 static int year, month, day, hour, minute, second, doy, base_msec;
16 static uint32_t *buf;
17 
18 int
19 openl1_goci(filehandle *file)
20 /*
21  * openl1_goci prepares for reading the GOCI L1B file
22  */ {
23  int status;
24  char tim_str[80];
25 
26  status = goci_l1b_open(file->name, &goci_l1b);
27  if (status) {
28  fprintf(stderr, "-E- %s line %d: unable to open %s\n",
29  __FILE__, __LINE__, file->name);
30  return 1;
31  }
32  if (want_verbose)
33  printf("GOCI Level-1B %s\n", file->name);
34 
35  file->npix = goci_l1b->npixels;
36  file->nscan = goci_l1b->nscans;
37  file->nbands = goci_l1b->nbands;
38  strcpy(file->spatialResolution, "500 m");
39 
40  // get time. If slot navigation is available, get the start time
41  // for future modification based on the slot. Else, use the center time
42 
43  if (goci_l1b->slot_nav_avail)
44  strcpy(tim_str, "Scene Start time");
45  else
46  strcpy(tim_str, "Scene center time");
47 
48  goci_l1b_get_date(goci_l1b, tim_str, &year, &month, &day);
49  goci_l1b_get_time(goci_l1b, tim_str, &hour, &minute, &second);
50 
51  ymdhms2ydmsec(year, month, day, hour, minute, second,
52  &year, &doy, &base_msec);
53 
54  if (want_verbose) {
55  printf("GOCI %s: %4d-%02d-%02d %03d %02d:%02d:%02d %d\n",
56  tim_str, year, month, day, doy, hour, minute, second, base_msec);
57  printf("GOCI file has %d bands, %d samples, %d lines\n",
58  file->nbands, file->npix, file->nscan);
59  }
60 
61  buf = (uint32_t *) malloc(file->npix * sizeof (uint32_t));
62  if (buf == NULL)
63  goto memory_error;
64 
65  if (goci_proj4_open(goci_l1b)) {
66  fprintf(stderr, "-E- %s line %d: unable to init proj4 geolocation for %s\n",
67  __FILE__, __LINE__, file->name);
68  goto memory_release;
69  }
70  if (want_verbose)
71  printf("GOCI using internal navigation\n");
72 
73  return 0;
74 
75 memory_error:
76  fprintf(stderr, "%s: %d - memory error\n", __FILE__, __LINE__);
77 memory_release:
78  if (buf) free(buf);
79 
80  return 1;
81 }
82 
83 int
84 readl1_goci(filehandle *file, int recnum, l1str *l1rec, int lonlat)
85 /*
86  * fill standard record with L1B line of data
87  */ {
88  int status, min_msec = 86401 * 1000, max_msec = -1;
89 
90  float rel_sec;
91 
92  int npix, nbands, ip, ib, ipb, msec;
93 
94  PJ_COORD c, c_out;
95 
96  npix = file->npix;
97  nbands = file->nbands;
98  msec = base_msec;
99 
100  // set information about data
101 
102  l1rec->npix = file->npix;
103  l1rec->scantime = yds2unix(year, doy, (double) (msec / 1.e3));
104 
105  // set default z and t
106  c.xyzt.z = 0.0;
107  c.xyzt.t = HUGE_VAL;
108 
109  for (ip = 0; ip < npix; ip++) {
110 
111  l1rec->pixnum[ip] = ip;
112 
113  // convert to lat lon
114  c.xy.x = ip * goci_l1b->deltaX + goci_l1b->startX;
115  c.xy.y = recnum * goci_l1b->deltaY + goci_l1b->startY;
116  c_out = proj_trans(goci_l1b->pj, PJ_FWD, c);
117  if(isfinite(c_out.xy.x) && isfinite(c_out.xy.y)) {
118  l1rec->lon[ip] = c_out.xy.x;
119  l1rec->lat[ip] = c_out.xy.y;
120  } else {
121  l1rec->lon[ip] = -999.0;
122  l1rec->lat[ip] = -999.0;
123  }
124 
125  if (l1rec->lon[ip] < -181.0 || l1rec->lon[ip] > 181.0 ||
126  l1rec->lat[ip] < -91.0 || l1rec->lat[ip] > 91.0)
127  l1rec->navfail[ip] = 1;
128 
129  if (!lonlat) {
130  // get the msec based on goci nav availability
131  if (goci_l1b->slot_nav_avail) {
132  unsigned char slot;
133  slot = goci_slot_time(ip, recnum, goci_l1b, &rel_sec);
134  l1rec->slot[ip] = slot + 1;
135  msec = base_msec + rel_sec * 1000;
136  if (msec > max_msec) max_msec = msec;
137  if (msec < min_msec) min_msec = msec;
138  } else
139  msec = base_msec;
140  float gmt = (float) msec / (1000.0 * 3600.0);
141  sunangs_(&year, &doy, &gmt, l1rec->lon + ip, l1rec->lat + ip,
142  l1rec->solz + ip, l1rec->sola + ip);
143  *(l1rec->sola + ip) = (*(l1rec->sola + ip) > 180.) ?
144  *(l1rec->sola + ip) - 360. : *(l1rec->sola + ip);
145 
146  get_zenaz(goci_l1b->sat_pos, l1rec->lon[ip], l1rec->lat[ip],
147  l1rec->senz + ip, l1rec->sena + ip);
148  *(l1rec->sena + ip) = (*(l1rec->sena + ip) > 180.) ?
149  *(l1rec->sena + ip) - 360. : *(l1rec->sena + ip);
150  }
151  if (goci_l1b->slot_nav_avail)
152  l1rec->scantime = yds2unix(year, doy, ((min_msec + max_msec) / 2.0) / 1e3);
153 
154  }
155 
156  if (lonlat) {
157  return (LIFE_IS_GOOD);
158  }
159 
160 
161  for (ib = 0; ib < nbands; ib++) {
162 
163  status = goci_l1b_get_band(goci_l1b, ib, recnum, buf);
164  if (status) {
165  fprintf(stderr, "-E- %s line %d: Failed to read Lt, band %d, recnum %d\n",
166  __FILE__, __LINE__, ib, recnum);
167  return 1;
168  }
169 
170  for (ip = 0; ip < npix; ip++) {
171  ipb = ip * nbands + ib;
172  if (buf[ip] == 0) {
173  l1rec->slot[ip] = 0;
174  }
175  l1rec->Lt[ipb] = buf[ip]*1.0E-07;
176  }
177  }
178 
179  return 0;
180 }
181 
182 int
183 closel1_goci(filehandle *file) {
184  if (buf) free(buf);
185  if (goci_l1b->slot_asg) free(goci_l1b->slot_asg);
186  if (goci_l1b) free(goci_l1b);
187  return 0;
188 }
int32_t slot_nav_avail
Definition: goci.h:32
int goci_l1b_get_time(goci_l1b_t *goci_l1b, char *tstr_name, int *hour, int *min, int *sec)
read a time of GOCI data
Definition: goci.c:452
double startY
Definition: goci.h:22
double deltaY
Definition: goci.h:24
void get_zenaz(float *pos, float lon, float lat, float *senz, float *sena)
Definition: get_zenaz.c:28
int32_t day
int status
Definition: l1_czcs_hdf.c:32
double yds2unix(int16_t year, int16_t day, double secs)
Definition: yds2unix.c:7
unsigned char goci_slot_time(int32_t ipix, int32_t ilin, goci_l1b_t *goci_l1b, float *rel_sec)
Definition: goci_slot.c:436
#define NULL
Definition: decode_rs.h:63
double deltaX
Definition: goci.h:23
read l1rec
int goci_l1b_get_band(goci_l1b_t *goci_l1b, int band, int line, uint32_t *buf)
read specified band and line from GOCI file.
Definition: goci.c:488
int32 * msec
Definition: l1_czcs_hdf.c:31
int closel1_goci(filehandle *file)
Definition: l1_goci.c:183
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 readl1_goci(filehandle *file, int recnum, l1str *l1rec, int lonlat)
Definition: l1_goci.c:84
void sunangs_(int *, int *, float *, float *, float *, float *, float *)
PJ * pj
Definition: goci.h:20
read recnum
subroutine lonlat(alon, alat, xlon, ylat)
Definition: lonlat.f:2
int goci_l1b_open(const char *src_path, goci_l1b_t **goci_l1b)
open GOCI bands
Definition: goci.c:226
int nscans
Definition: goci.h:17
int want_verbose
GOCI file format reader.
void ymdhms2ydmsec(int yy, int mm, int dd, int hh, int mn, int sc, int32_t *year, int32_t *day, int32_t *msec)
Definition: ydhms2ydmsec.c:3
int32_t nbands
double startX
Definition: goci.h:21
int goci_proj4_open(goci_l1b_t *l1b)
init proj4 for GOCI geolocation
Definition: goci.c:31
unsigned char * slot_asg
Definition: goci.h:34
int nbands
Definition: goci.h:18
int goci_l1b_get_date(goci_l1b_t *goci_l1b, char *tstr_name, int *year, int *month, int *day)
read a date of GOCI data
Definition: goci.c:415
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 as required for compatibility with version of the SDP toolkit Corrected test output file names to end in per delivery and then split off a new MYD_PR03 pcf file for Aqua Added AssociatedPlatformInstrumentSensor to the inventory metadata in MOD01 mcf and MOD03 mcf Created new versions named MYD01 mcf and MYD03 where AssociatedPlatformShortName is rather than Terra The program itself has been changed to read the Satellite Instrument validate it against the input L1A and LUT and to use it determine the correct files to retrieve the ephemeris and attitude data from Changed to produce a LocalGranuleID starting with MYD03 if run on Aqua data Added the Scan Type file attribute to the Geolocation copied from the L1A and attitude_angels to radians rather than degrees The accumulation of Cumulated gflags was moved from GEO_validate_earth_location c to GEO_locate_one_scan c
Definition: HISTORY.txt:464
float sat_pos[3]
Definition: goci.h:25
int npixels
Definition: goci.h:16
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int npix
Definition: get_cmp.c:27
int openl1_goci(filehandle *file)
Definition: l1_goci.c:19