OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
rd_geo_init.c
Go to the documentation of this file.
1 #include "viirs_sim_sdr.h"
2 #include <stdio.h>
3 #include <string.h>
4 #include <time.h>
5 #include <stdlib.h>
6 #define jul_day_1958 2436205
7 #define sec_per_day 86400
8 
9 int rd_geo_init(ctl_struc *ctl, sdr_info_struc *sdr_info,
10  in_rec_struc *in_rec)
11 /*-----------------------------------------------------------------------------
12  Routine: rd_geo_init
13 
14  Description: prepare the geolocation data file for use
15  The attributes and small datasets are read and the file is set so
16  datasets can then be read
17 
18  Returns type: int - 0 if good
19 
20  Arguments:
21  Type Name I/O Description
22  ---- ---- --- -----------
23  ctl_struc * ctl I input controls, use geolocation file
24  name and ctrate time (optionally)
25  sdr_info_struc * sdr_info I/O general SDR information
26  in_rec_struc * in_rec I/O input file information
27 
28  Modification history:
29 
30  W. Robinson, SAIC 20 Nov 2008 Original development
31  W. Robinson, SAIC 02 Oct 2009 accomodate the sensor attitude,
32  position and velocity
33  W. Robinson, SAIC 10 Mar 2010 go to scan-oriented processing and use
34  more scan options (agregated, un-aggregated, margin)
35 
36 ----------------------------------------------------------------------------*/ {
37  int month, dom, jul_day, hour, min, sec, h5_stat;
38  int16_t lcl_margin[2];
39  time_t sec_time;
40  struct tm *lcltime, init_tim, *new_tim;
41  double st_sec;
42  long extra_sec;
43  /*
44  * Open the HDF 5 file
45  */
46  if (h5io_openr(ctl->in_geo_file, 0, &(in_rec->geo_fid)) != 0) {
47  printf("%s - could not open HDF 5 file: %s\n",
48  __FILE__, ctl->in_geo_file);
49  return 1;
50  }
51  /*
52  * attributes may exist for the other scan formats, if not, it is standard
53  */
54  if ((h5_stat = h5io_attr_exist(&(in_rec->geo_fid), "scn_fmt"))
55  == 0) {
56  printf("%s, %d - Geo file indicates detailed scan format information\n",
57  __FILE__, __LINE__);
58  if (h5io_rd_attr(&(in_rec->geo_fid), "scn_fmt", &(in_rec->scn_fmt))
59  != 0) {
60  printf("%s, %d - failed to read the scn_fmt attribute\n",
61  __FILE__, __LINE__);
62  return 1;
63  }
64  if ((in_rec->scn_fmt < 0) || (in_rec->scn_fmt > 2)) {
65  printf("%s, %d - scn_fmt attribute outside valid range\n",
66  __FILE__, __LINE__);
67  return 1;
68  }
69  if (h5io_rd_attr(&(in_rec->geo_fid), "ndet", &(in_rec->ndet_scan))
70  != 0) {
71  printf("%s, %d - failed to read the ndet attribute\n",
72  __FILE__, __LINE__);
73  printf(" (after reading scn_fmt attribute)\n");
74  return 1;
75  }
76  if (h5io_rd_attr(&(in_rec->geo_fid), "margin", lcl_margin) != 0) {
77  printf("%s, %d - failed to read the margin attribute\n",
78  __FILE__, __LINE__);
79  printf(" (after reading scn_fmt attribute)\n");
80  return 1;
81  }
82  in_rec->margin[0] = lcl_margin[0];
83  in_rec->margin[1] = lcl_margin[1];
84  } else {
85  in_rec->scn_fmt = 0;
86  in_rec->margin[0] = 0;
87  in_rec->margin[1] = 0;
88  in_rec->ndet_scan = NDET;
89  }
90  printf("%s, %d - scn_fmt = %d, ndet_scan: %d, margin = %d %d\n",
91  __FILE__, __LINE__, in_rec->scn_fmt, in_rec->ndet_scan, in_rec->margin[0],
92  in_rec->margin[1]);
93  /*
94  * read the normal attributes
95  */
96  if (h5io_rd_attr(&(in_rec->geo_fid), "year", &(sdr_info->year))
97  != 0) {
98  printf("%s - failed to read the year attribute\n", __FILE__);
99  return 1;
100  }
101  if (h5io_rd_attr(&(in_rec->geo_fid), "day", &(sdr_info->day))
102  != 0) {
103  printf("%s - failed to read the day attribute\n", __FILE__);
104  return 1;
105  }
106  if (h5io_rd_attr(&(in_rec->geo_fid), "start_sec",
107  &(sdr_info->start_sec)) != 0) {
108  printf("%s - failed to read the start_sec attribute\n", __FILE__);
109  return 1;
110  }
111  if (h5io_rd_attr(&(in_rec->geo_fid), "npix", &(in_rec->npix))
112  != 0) {
113  printf("%s - failed to read the npix attribute\n", __FILE__);
114  return 1;
115  }
116  if (h5io_rd_attr(&(in_rec->geo_fid), "nlin", &(in_rec->nlin))
117  != 0) {
118  printf("%s - failed to read the nlin attribute\n", __FILE__);
119  return 1;
120  }
121  if (h5io_rd_attr(&(in_rec->geo_fid), "nscan", &(in_rec->nscan))
122  != 0) {
123  printf("%s - failed to read the nscan attribute\n", __FILE__);
124  return 1;
125  }
126  /*
127  * read the small datasets: position, velocity, scan time, and sensor
128  * attitude The large, pixel-oriented datasets will be transfered a
129  * line at a time
130  */
131  if ((sdr_info->geo_pos = (float *) malloc(in_rec->nscan * 3 *
132  sizeof (float))) == NULL) {
133  printf("%s:%d - failed to allocate space for geo_pos dataset\n", __FILE__,
134  __LINE__);
135  return 1;
136  }
137  if (h5io_grab_ds(&(in_rec->geo_fid), "pos", (void *) sdr_info->geo_pos)
138  != 0) {
139  printf("%s:%d - failed to grab the geo_pos dataset\n", __FILE__,
140  __LINE__);
141  return 1;
142  }
143 
144  if ((sdr_info->geo_vel = (float *) malloc(in_rec->nscan * 3 *
145  sizeof (float))) == NULL) {
146  printf("%s:%d - failed to allocate space for geo_vel dataset\n", __FILE__,
147  __LINE__);
148  return 1;
149  }
150  if (h5io_grab_ds(&(in_rec->geo_fid), "vel", (void *) sdr_info->geo_vel)
151  != 0) {
152  printf("%s:%d - failed to grab the geo_vel dataset\n", __FILE__,
153  __LINE__);
154  return 1;
155  }
156 
157  if ((sdr_info->scan_time =
158  (double *) malloc(in_rec->nscan * sizeof (double)))
159  == NULL) {
160  printf("%s:%d - failed to allocate space for scan_time dataset\n",
161  __FILE__, __LINE__);
162  return 1;
163  }
164  if (h5io_grab_ds(&(in_rec->geo_fid), "scan_time",
165  (void *) sdr_info->scan_time) != 0) {
166  printf("%s:%d - failed to grab the scan_time dataset\n", __FILE__,
167  __LINE__);
168  return 1;
169  }
170 
171  if ((sdr_info->geo_att = (float *) malloc(in_rec->nscan * 3 *
172  sizeof (float))) == NULL) {
173  printf("%s:%d - failed to allocate space for geo_att dataset\n", __FILE__,
174  __LINE__);
175  return 1;
176  }
177  if (h5io_grab_ds(&(in_rec->geo_fid), "att_arr", (void *) sdr_info->geo_att)
178  != 0) {
179  printf("%s:%d - failed to grab the geo_att dataset\n", __FILE__,
180  __LINE__);
181  return 1;
182  }
183 
184  printf("%s: year, day, start_sec: %d %d %f\n", __FILE__, sdr_info->year,
185  sdr_info->day, sdr_info->start_sec);
186  printf("%s: npix, nlin, nscan: %d %d %d\n", __FILE__, in_rec->npix,
187  in_rec->nlin, in_rec->nscan);
188  /*
189  * create the start of the day in a VIIRS used unit - microseconds
190  * past 1/1/1958
191  */
192  day2mday(sdr_info->year, sdr_info->day, &month, &dom);
193  jul_day = jd_c(sdr_info->year, month, dom);
194  sdr_info->t58_day = 1.e6 * sec_per_day * ((int64) jul_day - jul_day_1958);
195  /*
196  * set the start and end in the 1958 reference too
197  */
198  sdr_info->st_58_t = sdr_info->t58_day + sdr_info->start_sec * 1.e6;
199  sdr_info->en_58_t = sdr_info->st_58_t + SEC_PER_SCAN * in_rec->nscan * 1.e6;
200  /*
201  * set up the create dates and times needed for filling the dataset here
202  * create date, time in formats YYYYMMDD, HHMMSS.SSSSSSZ
203  * start end, date, time can only be completely done after trading the geo
204  * time
205  */
206  if (strcmp(ctl->cre_time, "Unspecified") == 0) {
207  time(&sec_time);
208  lcltime = localtime(&sec_time);
209  sprintf(sdr_info->cre_date, "%4.4d%2.2d%2.2d", lcltime->tm_year + 1900,
210  lcltime->tm_mon + 1, lcltime->tm_mday);
211 
212  sprintf(sdr_info->cre_time, "%2.2d%2.2d%2.2d.000000Z",
213  lcltime->tm_hour, lcltime->tm_min, lcltime->tm_sec);
214  } else {
215  strncpy(sdr_info->cre_date, ctl->cre_time, 8);
216  sdr_info->cre_date[8] = 0;
217  strncpy(sdr_info->cre_time, ctl->cre_time + 9, 13);
218  sdr_info->cre_time[13] = 'Z';
219  sdr_info->cre_time[14] = 0;
220  }
221  /*
222  * For convenience in creating output file names, create a string
223  * with the start year, day, hour, min, sec
224  */
225  hour = (int) (sdr_info->start_sec / 3600.);
226  min = (int) (sdr_info->start_sec / 60.) % 60;
227  sec = (int) (sdr_info->start_sec) % 60;
228  sprintf(sdr_info->ofile_base, "%4.4d%3.3d%2.2d%2.2d%2.2d",
229  sdr_info->year, sdr_info->day, hour, min, sec);
230  /*
231  * set the start and end times
232  * to avoid daylight savings complications, set to GMT
233  */
234  if (putenv("TZ=GMT 0") != 0) {
235  printf("%s, %d: GMT time zone switch error\n", __FILE__, __LINE__);
236  return 1;
237  }
238  day2mday(sdr_info->year, sdr_info->day, &month, &dom);
239  sprintf(sdr_info->st_date, "%4.4d%2.2d%2.2d", sdr_info->year,
240  month, dom);
241  st_sec = sdr_info->start_sec;
242  init_tim.tm_year = sdr_info->year - 1900;
243  init_tim.tm_mday = sdr_info->day;
244  init_tim.tm_mon = 0;
245  init_tim.tm_hour = 0;
246  init_tim.tm_min = 0;
247  init_tim.tm_sec = (int) st_sec;
248  init_tim.tm_isdst = 0;
249  extra_sec = 1.e6 * (st_sec - init_tim.tm_sec);
250  sec_time = mktime(&init_tim);
251  new_tim = localtime(&sec_time);
252  sprintf(sdr_info->st_time, "%2.2d%2.2d%2.2d.%6.6ldZ", new_tim->tm_hour,
253  new_tim->tm_min, new_tim->tm_sec, extra_sec);
254 
255  init_tim.tm_hour = 0;
256  init_tim.tm_min = 0;
257  init_tim.tm_sec = (int) (st_sec + (in_rec->nscan - 1) * SEC_PER_SCAN);
258  /* the extra_sec is the fractional seconds that don't get in mktime et al */
259  extra_sec = 1.e6 * (st_sec + (in_rec->nscan - 1) * SEC_PER_SCAN
260  - init_tim.tm_sec);
261 
262  sec_time = mktime(&init_tim);
263  new_tim = localtime(&sec_time);
264 
265  if (unsetenv("TZ") != 0) {
266  printf("%s, %d: GMT time zone unset error\n", __FILE__, __LINE__);
267  return 1;
268  }
269 
270  sprintf(sdr_info->en_date, "%4.4d%2.2d%2.2d", new_tim->tm_year + 1900,
271  new_tim->tm_mon + 1, new_tim->tm_mday);
272  sprintf(sdr_info->en_time, "%2.2d%2.2d%2.2d.%6.6ldZ", new_tim->tm_hour,
273  new_tim->tm_min, new_tim->tm_sec, extra_sec);
274  /*
275  */
276  return 0;
277 }
int h5io_openr(char *file, int opt, h5io_str *id)
Definition: h5io.c:4
int h5io_attr_exist(h5io_str *id, char *attr_name)
Definition: h5io.c:1451
These are used to scale the SD before writing it to the HDF4 file The default is and which means the product is not scaled at all Since the product is usually stored as a float inside of this is a way to write the float out as a integer l2prod min
#define NULL
Definition: decode_rs.h:63
int jd_c(int y, int m, int d)
Definition: time_utl.c:97
float tm[MODELMAX]
long long int64
int h5io_rd_attr(h5io_str *id, char *attr_name, void *data)
Definition: h5io.c:412
int rd_geo_init(ctl_struc *ctl, sdr_info_struc *sdr_info, in_rec_struc *in_rec)
Definition: rd_geo_init.c:9
#define jul_day_1958
Definition: rd_geo_init.c:6
int day2mday(int year, int day_of_year, int *month, int *day_of_month)
Definition: day2mday.c:3
int h5io_grab_ds(h5io_str *id, char *path_name, void *data)
Definition: h5io.c:1347
this program makes no use of any feature of the SDP Toolkit that could generate such a then geolocation is calculated at that and then aggregated up to Resolved feature request Bug by adding three new int8 SDSs for each high resolution offsets between the high resolution geolocation and a bi linear interpolation extrapolation of the positions This can be used to reconstruct the high resolution geolocation Resolved Bug by delaying cumulation of gflags until after validation of derived products Resolved Bug by setting Latitude and Longitude to the correct fill resolving to support Near Real Time because they may be unnecessary if use of entrained ephemeris and attitude data is turned resolving bug report Corrected to filter out Aqua attitude records with missing status helping resolve bug MOD_PR03 will still correctly write scan and pixel data that does not depend upon the start time
Definition: HISTORY.txt:248
#define SEC_PER_SCAN
Definition: viirs_sim_sdr.h:37
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second and prod_ix set to PARAM_TYPE_INT name_prefix is compared with the beginning of the product name If name_suffix is not empty the it must match the end of the product name The characters right after the prefix are read as an integer and prod_ix is set to that number strncpy(l2prod->name_prefix, "myprod", UNITLEN)
#define NDET
Definition: polcor.c:13
#define sec_per_day
Definition: rd_geo_init.c:7