OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
scene_meta.c
Go to the documentation of this file.
1 #include "scene_meta.h"
2 
3 static scnstr meta;
4 
5 static int first = 1;
6 static int second = 1;
7 static int centerfound = 0;
8 static int start_node = UNKNOWNNODE;
9 static int end_node = UNKNOWNNODE;
10 static int ascdsc = UNKNOWNNODE;
11 static int daynight = UNKNOWNSCENE;
12 static float lastLat = -999;
13 static float lastLon0 = -999;
14 static float lastLonN = -999;
15 static int lastScan = -1;
16 static float northern_lat = -90.0;
17 static float southern_lat = +90.0;
18 static float eastern_lon = -180.0;
19 static float western_lon = +180.0;
20 
21 static float lat_rec[10] ={-999., -999., -999., -999., -999., -999., -999., -999., -999., -999,};
22 static int lat_rec_ptr = 0;
23 
24 static char *nodestr [3] = {"Ascending", "Descending", "Unknown"};
25 static char *daynightstr[4] = {"Day", "Night", "Mixed", "Unknown"};
26 
27 float westernmost(float lon1, float lon2) {
28  if (lon1 == -999.) lon1 = lon2;
29 
30  if (fabs(lon1 - lon2) < 190.0)
31  return ( MIN(lon1, lon2));
32  else
33  return ( MAX(lon1, lon2));
34 }
35 
36 float easternmost(float lon1, float lon2) {
37  if (lon1 == -999.) lon1 = lon2;
38 
39  if (fabs(lon1 - lon2) < 190.0)
40  return ( MAX(lon1, lon2));
41  else
42  return ( MIN(lon1, lon2));
43 }
44 
45 void scene_meta_init(void) {
46  strcpy(meta.daynight, daynightstr[UNKNOWNSCENE]);
47  strcpy(meta.start_node, nodestr[UNKNOWNNODE]);
48  strcpy(meta.end_node, nodestr[UNKNOWNNODE]);
49  meta.start_time = 0;
50  meta.center_time = 0;
51  meta.end_time = 0;
52 
53  meta.start_year = 0;
54  meta.start_day = 0;
55  meta.start_msec = 0;
56 
57  meta.end_year = 0;
58  meta.end_day = 0;
59  meta.end_msec = 0;
60 
61  meta.northern_lat = 90.0;
62  meta.southern_lat = -90.0;
63  meta.eastern_lon = 180.0;
64  meta.western_lon = -180.0;
65 
66  meta.start_center_lon = 0.0;
67  meta.start_center_lat = 0.0;
68  meta.end_center_lon = 0.0;
69  meta.end_center_lat = 0.0;
70 }
71 
72 void scene_meta_put(l1str *l1rec) {
73  static int firstCall = 1;
74  static int32_t cscan;
75  int16_t year, day;
76  double msec;
77 
78  int32_t cpix = l1rec->npix / 2;
79  int32_t npix = l1rec->npix;
80  int32_t epix = -1;
81  int32_t spix = -1;
82  int32_t ip;
83 
84  if (firstCall) {
85  firstCall = 0;
87  if (l1_input->eline < 1)
88  cscan = ((l1rec->l1file->nscan - 1) - MAX(l1_input->sline - 1, 0)) / 2;
89  else
90  cscan = ((l1_input->eline - 1) - MAX(l1_input->sline - 1, 0)) / 2;
91  }
92 
93  /* ignore buffering scans */
94  if (l1rec->iscan == lastScan) return;
95  if (l1rec->iscan < MAX(l1_input->sline - 1, 0)) return;
96  if (l1_input->eline < 1) {
97  if (l1rec->iscan > (l1rec->l1file->nscan - 1))
98  return;
99  } else {
100  if (l1rec->iscan > (l1_input->eline - 1))
101  return;
102  }
103 
104  for (ip = 0; ip < cpix; ip++) {
105  if ((l1rec->flags[ip] & NAVFAIL) == 0) {
106  spix = ip;
107  break;
108  }
109  }
110  for (ip = l1rec->npix - 1; ip > cpix; ip--) {
111  if ((l1rec->flags[ip] & NAVFAIL) == 0) {
112  epix = ip;
113  break;
114  }
115  }
116 
117  if (spix != -1 &&
118  epix != -1 &&
119  (l1rec->flags[cpix] & NAVFAIL) == 0) {
120 
121  if (first) {
122 
123  first = 0;
124  daynight = UNKNOWNSCENE;
125 
126  meta.upperleft_lon = l1rec->lon[0];
127  meta.upperright_lon = l1rec->lon[npix - 1];
128  meta.upperleft_lat = l1rec->lat[0];
129  meta.upperright_lat = l1rec->lat[npix - 1];
130  meta.start_center_lon = l1rec->lon[cpix];
131  meta.start_center_lat = l1rec->lat[cpix];
132  unix2yds(l1rec->scantime, &year, &day, &msec);
133  meta.start_year = (int32_t) year;
134  meta.start_day = (int32_t) day;
135  meta.start_msec = (int32_t) (msec * 1.e3);
136  meta.start_time = l1rec->scantime;
137 
138  } else if (second) {
139 
140  second = 0;
141  if (l1rec->lat[cpix] > lastLat)
142  ascdsc = 0; /* Ascending */
143  else
144  ascdsc = 1; /* Descending */
145  start_node = ascdsc;
146  end_node = ascdsc;
147 
148  ascdsc = (l1rec->l1file->sensorID == CZCS) ? 1 - ascdsc : ascdsc;
149  if (ascdsc == 1) { /* Descending */
150  western_lon = westernmost(lastLon0, l1rec->lon[spix]);
151  eastern_lon = easternmost(lastLonN, l1rec->lon[epix]);
152  } else { /* Ascending */
153  western_lon = westernmost(lastLonN, l1rec->lon[epix]);
154  eastern_lon = easternmost(lastLon0, l1rec->lon[spix]);
155  }
156 
157  } else {
158 
159  if (l1rec->lat[cpix] > lastLat)
160  ascdsc = 0; /* Ascending */
161  else
162  ascdsc = 1; /* Descending */
163  end_node = ascdsc;
164 
165  ascdsc = (l1rec->l1file->sensorID == CZCS) ? 1 - ascdsc : ascdsc;
166  if (ascdsc == 1) { /* Descending */
167  western_lon = westernmost(western_lon, l1rec->lon[spix]);
168  eastern_lon = easternmost(eastern_lon, l1rec->lon[epix]);
169  } else { /*Ascending */
170  western_lon = westernmost(western_lon, l1rec->lon[epix]);
171  eastern_lon = easternmost(eastern_lon, l1rec->lon[spix]);
172  }
173 
174  meta.lowerleft_lon = l1rec->lon[0];
175  meta.lowerright_lon = l1rec->lon[npix - 1];
176  meta.lowerleft_lat = l1rec->lat[0];
177  meta.lowerright_lat = l1rec->lat[npix - 1];
178  meta.end_center_lon = l1rec->lon[cpix];
179  meta.end_center_lat = l1rec->lat[cpix];
180  unix2yds(l1rec->scantime, &year, &day, &msec);
181  meta.end_year = (int32_t) year;
182  meta.end_day = (int32_t) day;
183  meta.end_msec = (int32_t) (msec * 1.e3);
184  meta.end_time = l1rec->scantime;
185  }
186 
187  if (l1rec->iscan >= cscan && !centerfound) {
188  meta.scene_center_lon = l1rec->lon[cpix];
189  meta.scene_center_lat = l1rec->lat[cpix];
190  meta.scene_center_solz = l1rec->solz[cpix];
191  meta.center_time = l1rec->scantime;
192  centerfound = 1;
193  }
194 
195  for (ip = spix; ip <= epix; ip++) {
196  if ((l1rec->flags[ip] & NAVFAIL) == 0) {
197  northern_lat = MAX(northern_lat, l1rec->lat[ip]);
198  southern_lat = MIN(southern_lat, l1rec->lat[ip]);
199  if (daynight != DAYANDNIGHT) {
200  if (l1rec->solz[ip] > SOLZNIGHT) {
201  if (daynight == DAYSCENE)
202  daynight = DAYANDNIGHT;
203  else
204  daynight = NIGHTSCENE;
205  } else {
206  if (daynight == NIGHTSCENE)
207  daynight = DAYANDNIGHT;
208  else
209  daynight = DAYSCENE;
210  }
211  }
212  }
213  }
214 
215  if (lat_rec[lat_rec_ptr] > -100.)
216  lastLat = lat_rec[lat_rec_ptr];
217  else
218  lastLat = l1rec->lat[cpix];
219  lat_rec[lat_rec_ptr++] = l1rec->lat[cpix];
220  lat_rec_ptr = lat_rec_ptr % 10;
221  lastLon0 = l1rec->lon[spix];
222  lastLonN = l1rec->lon[epix];
223  lastScan = l1rec->iscan;
224 
225  strcpy(meta.start_node, nodestr[start_node]);
226  strcpy(meta.end_node, nodestr[end_node]);
227  strcpy(meta.daynight, daynightstr[daynight]);
228 
229  meta.northern_lat = northern_lat;
230  meta.southern_lat = southern_lat;
231  meta.eastern_lon = eastern_lon;
232  meta.western_lon = western_lon;
233  }
234 
235 }
236 
237 scnstr *scene_meta_get(void) {
238  return (&meta);
239 }
240 
241 void scene_meta_write(idDS ds_id) {
242  scnstr *m = &meta;
243 
244  if (ds_id.fftype == DS_NCDF) {
245 
246  // 1994-11-05T13:15:30Z
247  SetChrGA(ds_id, "time_coverage_start", unix2isodate(m->start_time, 'G'));
248 
249  SetChrGA(ds_id, "time_coverage_end", unix2isodate(m->end_time, 'G'));
250 
251  SetF32GA(ds_id, "start_center_longitude", m->start_center_lon);
252  SetF32GA(ds_id, "start_center_latitude", m->start_center_lat);
253  SetF32GA(ds_id, "end_center_longitude", m->end_center_lon);
254  SetF32GA(ds_id, "end_center_latitude", m->end_center_lat);
255  SetF32GA(ds_id, "northernmost_latitude", m->northern_lat);
256  SetF32GA(ds_id, "southernmost_latitude", m->southern_lat);
257  SetF32GA(ds_id, "easternmost_longitude", m->eastern_lon);
258  SetF32GA(ds_id, "westernmost_longitude", m->western_lon);
259  SetChrGA(ds_id, "geospatial_lat_units", "degrees_north");
260  SetChrGA(ds_id, "geospatial_lon_units", "degrees_east");
261  SetF32GA(ds_id, "geospatial_lat_max", m->northern_lat);
262  SetF32GA(ds_id, "geospatial_lat_min", m->southern_lat);
263  SetF32GA(ds_id, "geospatial_lon_max", m->eastern_lon);
264  SetF32GA(ds_id, "geospatial_lon_min", m->western_lon);
265  SetChrGA(ds_id, "startDirection", m->start_node);
266  SetChrGA(ds_id, "endDirection", m->end_node);
267  SetChrGA(ds_id, "day_night_flag", m->daynight);
268 
269  } else {
270 
271  // write to an HDF4 file
272  SetChrGA(ds_id, "Start Time", unix2ydhmsf(m->start_time, 'G'));
273  SetI16GA(ds_id, "Start Year", m->start_year);
274  SetI16GA(ds_id, "Start Day", m->start_day);
275  SetI32GA(ds_id, "Start Millisec", m->start_msec);
276 
277  SetF32GA(ds_id, "Upper Left Longitude", m->upperleft_lon);
278  SetF32GA(ds_id, "Upper Right Longitude", m->upperright_lon);
279  SetF32GA(ds_id, "Upper Left Latitude", m->upperleft_lat);
280  SetF32GA(ds_id, "Upper Right Latitude", m->upperright_lat);
281 
282  SetF32GA(ds_id, "Start Center Longitude", m->start_center_lon);
283  SetF32GA(ds_id, "Start Center Latitude", m->start_center_lat);
284 
285  SetChrGA(ds_id, "Latitude Units", "degrees North");
286  SetChrGA(ds_id, "Longitude Units", "degrees East");
287 
288  SetChrGA(ds_id, "Scene Center Time", unix2ydhmsf(m->center_time, 'G'));
289  SetF32GA(ds_id, "Scene Center Longitude", m->scene_center_lon);
290  SetF32GA(ds_id, "Scene Center Latitude", m->scene_center_lat);
291  SetF32GA(ds_id, "Scene Center Solar Zenith", m->scene_center_solz);
292 
293  SetChrGA(ds_id, "End Time", unix2ydhmsf(m->end_time, 'G'));
294  SetI16GA(ds_id, "End Year", m->end_year);
295  SetI16GA(ds_id, "End Day", m->end_day);
296  SetI32GA(ds_id, "End Millisec", m->end_msec);
297 
298  SetF32GA(ds_id, "Lower Left Longitude", m->lowerleft_lon);
299  SetF32GA(ds_id, "Lower Right Longitude", m->lowerright_lon);
300  SetF32GA(ds_id, "Lower Left Latitude", m->lowerleft_lat);
301  SetF32GA(ds_id, "Lower Right Latitude", m->lowerright_lat);
302 
303  SetF32GA(ds_id, "End Center Longitude", m->end_center_lon);
304  SetF32GA(ds_id, "End Center Latitude", m->end_center_lat);
305 
306  SetF32GA(ds_id, "Northernmost Latitude", m->northern_lat);
307  SetF32GA(ds_id, "Southernmost Latitude", m->southern_lat);
308  SetF32GA(ds_id, "Easternmost Longitude", m->eastern_lon);
309  SetF32GA(ds_id, "Westernmost Longitude", m->western_lon);
310 
311  SetChrGA(ds_id, "Start Node", m->start_node);
312  SetChrGA(ds_id, "End Node", m->end_node);
313  SetChrGA(ds_id, "Day or Night", m->daynight);
314 
315  }
316 
317 }
int SetF32GA(idDS ds_id, const char *name, float value)
#define MAX(A, B)
Definition: swl0_utils.h:26
#define MIN(x, y)
Definition: rice.h:169
int32_t day
#define DAYSCENE
Definition: l12_parms.h:87
#define UNKNOWNSCENE
Definition: l12_parms.h:90
char * unix2ydhmsf(double usec, char zone)
Definition: unix2ydhmsf.c:8
read l1rec
int32 * msec
Definition: l1_czcs_hdf.c:31
void scene_meta_put(l1str *l1rec)
Definition: scene_meta.c:72
ds_format_t fftype
Definition: dfutils.h:31
#define DAYANDNIGHT
Definition: l12_parms.h:89
#define NIGHTSCENE
Definition: l12_parms.h:88
string nodestr[3]
Definition: DDSensor.cpp:36
void scene_meta_write(idDS ds_id)
Definition: scene_meta.c:241
string daynightstr[4]
Definition: DDSensor.cpp:37
l1_input_t * l1_input
Definition: l1_options.c:9
void unix2yds(double usec, short *year, short *day, double *secs)
float easternmost(float lon1, float lon2)
Definition: scene_meta.c:36
int SetI16GA(idDS ds_id, const char *name, int16_t value)
@ DS_NCDF
Definition: dfutils.h:20
int SetI32GA(idDS ds_id, const char *name, int32_t value)
Definition: wrapper.c:326
#define SOLZNIGHT
Definition: l1.h:57
float westernmost(float lon1, float lon2)
Definition: scene_meta.c:27
int SetChrGA(idDS ds_id, const char *name, const char *value)
Definition: wrapper.c:236
int32 spix
Definition: l1_czcs_hdf.c:21
#define fabs(a)
Definition: misc.h:93
char * unix2isodate(double dtime, char zone)
Definition: unix2isodate.c:10
scnstr * scene_meta_get(void)
Definition: scene_meta.c:237
#define CZCS
Definition: sensorDefs.h:17
Definition: dfutils.h:28
int32 epix
Definition: l1_czcs_hdf.c:23
#define UNKNOWNNODE
Definition: scene_meta.h:14
void scene_meta_init(void)
Definition: scene_meta.c:45
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
#define NAVFAIL
Definition: l2_flags.h:36