OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
GEO_write_scan_metadata.c
Go to the documentation of this file.
1 #include "PGS_MODIS_35251.h"
2 #include "GEO_global_arrays.h"
3 #include "GEO_output.h"
4 #include "GEO_product.h"
5 #include "GEO_validation.h"
6 
7 #define DIMSDIM 3
8 #define MAXMSGBUFFLEN 200
9 #define CB_VECTOR_NUMVALUES 9
10 
11 PGSt_SMF_status GEO_write_scan_metadata(
12  int const scan_number,
13  l1a_data_struct const * const l1a_data,
14  celestial_bodies_struct const * const cb_vectors,
15  MODFILE * const geo_file,
16  PGSt_double const rpy[],
17  uint32 frame_quality[][MAX_FRAMES]
18 )
19 /*****************************************************************************
20 !C
21 !Description:
22  Subroutine in output group of the Level-1A geolocation
23  software to write one scan of scan-level metadata
24  to the geolocation product file using the MAPI.
25 
26 !Input Parameters:
27  scan_number the scan (array index) number
28  l1a_data data read from L1A file
29  cb_vectors solar and lunar position vectors.
30  geo_file MAPI structure for geolocation file
31  rpy Roll, pitch, and yaw thermal corrections
32  frame_quality Ephemeris and attitude quality flags
33 
34 !Output Parameters:
35  None
36 
37 Return parameter:
38  SUCCESS if all metadata for the scan written to the
39  geolocation file,
40  FAIL otherwise.
41 
42 Externally defined:
43  ATT_IDX "GEO_global_arrays.h"
44  ATTIT_ANG "GEO_product.h"
45  EPH_IDX "GEO_global_arrays.h"
46  EV_FRAMES "GEO_product.h"
47  EVTIME "GEO_product.h"
48  FILL_INT8 "GEO_output.h"
49  GEO_DOUBLE_FILLVALUE "GEO_output.h"
50  GEO_QUALITY "GEO_product.h"
51  IMPULSE_ENC "GEO_product.h"
52  IMPULSE_TIME "GEO_product.h"
53  L1_QUALITY "GEO_product.h"
54  MAX_FRAMES "GEO_geo.h"
55  MODIS_E_BAD_INPUT_ARG "PGS_MODIS_35251.h"
56  MODIS_E_GEO "PGS_MODIS_35251.h"
57  MODIS_N_GEO_MANEUVER "PGS_MODIS_35251.h"
58  MOON_VECTOR "GEO_product.h"
59  MSIDE "GEO_product.h"
60  NUM_IMPULSE "GEO_product.h"
61  NUM_L1A_QUALITY_FLAGS "GEO_geo.h"
62  ORB_POS "GEO_product.h"
63  ORB_VEL "GEO_product.h"
64  PGS_S_SUCCESS "PGS_SMF.h"
65  S_NUM "GEO_product.h"
66  S_TYPE "GEO_product.h"
67  SCAN_TYPE_LEN "GEO_parameters.h"
68  SCAN_META_GRP "L1A_data.h"
69  SCTIME "GEO_product.h"
70  SD_FRAMES "GEO_product.h"
71  SDTIME "GEO_product.h"
72  SUN_AZIMUTH "GEO_product.h"
73  SUN_REF "GEO_product.h"
74  SUN_ZENITH "GEO_product.h"
75  SV_FRAMES "GEO_product.h"
76  SVTIME "GEO_product.h"
77  T_INST2ECR "GEO_product.h"
78  THERMCORR "GEO_product.h"
79 
80 Called by:
81  GEO_write_one_scan "GEO_output.h"
82 
83 Routines called:
84  modsmf "smfio.h"
85  putMODISarray "mapi.h"
86 
87 !Revision History:
88  * $Log: GEO_write_scan_metadata.c,v $
89  * Revision 6.3 2011/02/14 22:05:45 kuyper
90  * Removed casts that are no longer necessary with current version of M-API.
91  *
92  * Revision 6.2 2010/05/27 15:22:09 kuyper
93  * Corrected dimension of frame_quality.
94  *
95  * Revision 6.1 2010/05/26 22:47:47 kuyper
96  * Changed to return a status code.
97  * Helped resolve Bug 1969 by adding rpy as input, and THERMCORR as output
98  * Helped resolve Bug 2470 by dropping maneuver_list.
99  * Helped resolve Bug 2472 by adding frame_quality as input, and ATT_QUALITY and
100  * EPH_QUALITY as output.
101  * Added SDS name macros to the Externally Defined section of the Prolog.
102  * Improved naming of loop counters.
103  * Changed 'name' and 'data' members to be pointers to const,
104  * Corrected error message to bring code and PDL in sync.
105  *
106  * Revision 5.3 2004/10/25 18:36:38 vlin
107  * typo for GEO_in_maneuver fixed. vlin@saicmodis.com
108  *
109  * Revision 5.2 2004/08/24 15:22:39 vlin
110  * Input parameter maneuver_list added, call to GEO_in_maneuver updated.
111  *
112  * Revision 5.1 2004/08/13 15:16:55 vlin
113  * Added C5 feature: write fourth quality flag as the manuever flag
114  * based upon GEO_in_maneuver().
115  *
116  * Revision 4.2 2004/04/09 22:18:39 kuyper
117  * Replaced FILL_BYTE with FILL_INT8.
118  *
119  * Revision 4.1 2003/02/21 23:10:32 kuyper
120  * Corrected to use void* pointers with %p format code.
121 
122 !Team-unique Header:
123 
124  This software is developed by the MODIS Science Data Support
125  Team for the National Aeronautics and Space Administration,
126  Goddard Space Flight Center, under contract NAS5-32373.
127 
128 !END*************************************************************************
129 */
130 {
131  /* Local variable declarations */
132  float32 moon_vector[3];
133  float32 rpy_angles[3];
134  float32 sun_vector[3];
135  float32 sun_azimuth, sun_zenith;
136  float64 imp_enc[MAX_IMPULSE_NUMBER], imp_time[MAX_IMPULSE_NUMBER];
137  int obj, dim; /* Loop index */
138  PGSt_SMF_status retval = PGS_S_SUCCESS;
139  uint16 scan_id, EV_frames, SD_frames, SV_frames;
140  char msgbuf[MAXMSGBUFFLEN];
141  int8 geoqual[4];
142  char filefunc[] = __FILE__ ", GEO_write_scan_metadata";
143 
144  struct {
145  char const *name; /* Name of the SDS object in the product file. */
146  long start[3]; /* Starting location for write. */
147  long dims[DIMSDIM]; /* dimensions of array to write. */
148  void const *data; /* data to write to the SDS. */
149  }scan_metadata[] =
150  { {S_NUM, {0,0}, {1}, NULL},
151  {EV_FRAMES, {0,0}, {1}, NULL},
152  {SD_FRAMES, {0,0}, {1}, NULL},
153  {SV_FRAMES, {0,0}, {1}, NULL},
154  {EVTIME, {0,0}, {1}, NULL},
155  {SDTIME, {0,0}, {1}, NULL},
156  {SVTIME, {0,0}, {1}, NULL},
157  {S_TYPE, {0,0}, {1,SCAN_TYPE_LEN}, NULL},
158  {MSIDE, {0,0}, {1}, NULL},
159  {L1_QUALITY, {0,0}, {1,NUM_L1A_QUALITY_FLAGS}, NULL},
160  {GEO_QUALITY, {0,0}, {1,4}, NULL},
161  {SCTIME, {0,0}, {1}, NULL},
162  {SUN_ZENITH, {0,0}, {1}, NULL},
163  {SUN_AZIMUTH, {0,0}, {1}, NULL},
164  {MOON_VECTOR, {0,0}, {1,3}, NULL},
165  {ORB_POS, {0,0}, {1,3}, NULL},
166  {ORB_VEL, {0,0}, {1,3}, NULL},
167  {T_INST2ECR, {0,0,0}, {1,3,3}, NULL},
168  {ATTIT_ANG, {0,0}, {1,3}, NULL},
169  {SUN_REF, {0,0}, {1,3}, NULL},
170  {NUM_IMPULSE, {0,0}, {1}, NULL},
171  {IMPULSE_ENC, {0,0}, {1,MAX_IMPULSE_NUMBER}, NULL},
172  {IMPULSE_TIME, {0,0}, {1,MAX_IMPULSE_NUMBER}, NULL},
173  {THERMCORR, {0,0}, {1,3}, NULL},
174  {ATT_QUALITY, {0,0}, {1,MAX_FRAMES}, NULL},
175  {EPH_QUALITY, {0,0}, {1,MAX_FRAMES}, NULL},
176  };
177 
178  if ((l1a_data == NULL) || scan_number < 0 ||
179  scan_number >= l1a_data->num_scans || cb_vectors == NULL ||
180  geo_file == NULL || rpy==NULL || frame_quality == NULL )
181  {
182  sprintf(msgbuf, "l1a_data = %p, scan_number = %i, cb_vectors = %p, "
183  "geo_file = %p, rpy = %p, frame_quality = %p",
184  (void*)l1a_data, scan_number, (void*)cb_vectors, (void*)geo_file,
185  (void*)rpy, (void*)frame_quality);
186  modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
187 
188  return MODIS_E_BAD_INPUT_ARG;
189  }
190 
191  /* Finish initializing the scan_metadata array with the contents
192  defined above. Copy data into local variables, where
193  necessary, to ensure conformity with the SDS's data type. */
194 
195  obj = 0;
196  /* uint16 */
197  scan_metadata[obj].start[0] = (long)scan_number;
198  scan_id = (uint16)l1a_data->frame_data[scan_number].L1A_scan_id;
199  scan_metadata[obj].data = &scan_id;
200  obj++;
201 
202  /* uint16 */
203  scan_metadata[obj].start[0] = (long)scan_number;
204  EV_frames = (uint16)l1a_data->frame_data[scan_number].EV_frames;
205  scan_metadata[obj].data = &EV_frames;
206  obj++;
207 
208  /* uint16 */
209  scan_metadata[obj].start[0] = (long)scan_number;
210  SD_frames = (uint16)l1a_data->frame_data[scan_number].SD_frames;
211  scan_metadata[obj].data = &SD_frames;
212  obj++;
213 
214  /* uint16 */
215  scan_metadata[obj].start[0] = (long)scan_number;
216  SV_frames = (uint16)l1a_data->frame_data[scan_number].SV_frames;
217  scan_metadata[obj].data = &SV_frames;
218  obj++;
219 
220  /* float64 */
221  scan_metadata[obj].start[0] = (long)scan_number;
222  scan_metadata[obj].data = &l1a_data->frame_data[scan_number].EV_start;
223  obj++;
224 
225  /* float64 */
226  scan_metadata[obj].start[0] = (long)scan_number;
227  scan_metadata[obj].data = &l1a_data->frame_data[scan_number].SD_start;
228  obj++;
229 
230  /* float64 */
231  scan_metadata[obj].start[0] = (long)scan_number;
232  scan_metadata[obj].data = &l1a_data->frame_data[scan_number].SV_start;
233  obj++;
234 
235  /* char8 */
236  scan_metadata[obj].start[0] = (long)scan_number;
237  scan_metadata[obj].data = &l1a_data->frame_data[scan_number].Scan_type;
238  obj++;
239 
240  /* uint16 */
241  scan_metadata[obj].start[0] = (long)scan_number;
242  scan_metadata[obj].data = &l1a_data->mirr_data[scan_number].mirr_side;
243  obj++;
244 
245  /* int32 */
246  scan_metadata[obj].start[0] = (long)scan_number;
247  scan_metadata[obj].data =
248  &l1a_data->frame_data[scan_number].L1A_scan_quality;
249  obj++;
250 
251  /* int8 */
252  geoqual[0] = (int8)l1a_data->mirr_data[scan_number].impulse_flag;
253 
254  /* int8 */
255  geoqual[1] = l1a_data->frame_data[scan_number].SCI_ABNORM;
256 
257  /* int8 */
258  geoqual[2] = l1a_data->frame_data[scan_number].SCI_STATE;
259 
260  /* C5 feature: call subroutine GEO_in_maneuver() to check if the */
261  /* spacecraft was in a listed maneuver at the specified time. */
262 
263  switch(GEO_in_maneuver(l1a_data->frame_data[scan_number].EV_start))
264  {
265  case PGS_S_SUCCESS:
266  geoqual[3] = (int8)0;
267  break;
268 
270  geoqual[3] = (int8)1;
271  break;
272 
273  default:
274  geoqual[3] = FILL_INT8;
275  break;
276  }
277 
278  scan_metadata[obj].start[0] = (long)scan_number;
279  scan_metadata[obj].start[1] = 0L;
280  scan_metadata[obj].data = geoqual;
281  obj++;
282 
283  if ( cb_vectors->sc.qa_flag == GOOD_DATA ) {
284 
285  /* float64 EV center time */
286  scan_metadata[obj].start[0] = (long)scan_number;
287  scan_metadata[obj].data = &cb_vectors->sc.time;
288  obj++;
289 
290  /* float32 SD sun zenith */
291  scan_metadata[obj].start[0] = (long)scan_number;
292  sun_zenith = (float32)cb_vectors->SD_sun_zenith;
293  scan_metadata[obj].data = &sun_zenith;
294  obj++;
295 
296  /* float32 SD sun azimuth */
297  scan_metadata[obj].start[0] = (long)scan_number;
298  sun_azimuth = (float32)cb_vectors->SD_sun_azimuth;
299  scan_metadata[obj].data = &sun_azimuth;
300  obj++;
301 
302  /* float32 moon unit vector */
303  scan_metadata[obj].start[0] = (long)scan_number;
304  for(dim=0; dim<3; dim++)
305  moon_vector[dim] = (float32)cb_vectors->moon_unit_vector[dim];
306  scan_metadata[obj].data = &moon_vector;
307  obj++;
308 
309  /* float64 array[3] orb_pos */
310  scan_metadata[obj].start[0] = (long)scan_number;
311  scan_metadata[obj].start[1] = 0L;
312  scan_metadata[obj].data = cb_vectors->sc.positionECR;
313  obj++;
314 
315  /* float64 array[3] orb_vec */
316  scan_metadata[obj].start[0] = (long)scan_number;
317  scan_metadata[obj].start[1] = 0L;
318  scan_metadata[obj].data = cb_vectors->sc.velocityECR;
319  obj++;
320 
321  /* float64 array[3][3] T_inst2ecr */
322  scan_metadata[obj].start[0] = (long)scan_number;
323  scan_metadata[obj].start[1] = 0L;
324  scan_metadata[obj].start[2] = 0L;
325  scan_metadata[obj].data = cb_vectors->sc.T_inst2ecr;
326  obj++;
327 
328  /* float64 array[3] attitude angles */
329  scan_metadata[obj].start[0] = (long)scan_number;
330  scan_metadata[obj].start[1] = 0L;
331  scan_metadata[obj].data = cb_vectors->sc.eulerAngles;
332  obj++;
333 
334  /* float32 array[3] sun unit vector */
335  scan_metadata[obj].start[0] = (long)scan_number;
336  for(dim=0; dim<3; dim++)
337  sun_vector[dim] = (float32)cb_vectors->sun_unit_vector[dim];
338  scan_metadata[obj].data = &sun_vector;
339  obj++;
340 
341  } else
342  /* obj must be incremented by number of members above.
343  * This value will need to be changed if the members
344  * of the scan_metadata struct changes. */
345  obj += CB_VECTOR_NUMVALUES;
346 
347  /* uint8 */
348  scan_metadata[obj].start[0] = (long)scan_number;
349  scan_metadata[obj].data = &l1a_data->mirr_data[scan_number].num_impulse;
350  obj++;
351 
352  if(l1a_data->mirr_data[scan_number].num_impulse != 0)
353  {
354  int imp;
355 
356  scan_metadata[obj].start[0] = (long)scan_number;
357  scan_metadata[obj].dims[1] =
358  (long)l1a_data->mirr_data[scan_number].num_impulse;
359 
360  for (imp=0; imp < MAX_IMPULSE_NUMBER; imp++)
361  imp_enc[imp] =
362  (float64)l1a_data->mirr_data[scan_number].mirr_impulse_enc[imp];
363  scan_metadata[obj].data = &imp_enc;
364  obj++;
365 
366  scan_metadata[obj].start[0] = (long)scan_number;
367  scan_metadata[obj].dims[1] =
368  (long)l1a_data->mirr_data[scan_number].num_impulse;
369 
370  for (imp=0; imp<MAX_IMPULSE_NUMBER; imp++)
371  imp_time[imp] = (float64)l1a_data->mirr_data[scan_number].
372  mirr_impulse_time[imp];
373  scan_metadata[obj].data = &imp_time;
374  obj++;
375  }
376  else
377  obj += 2;
378 
379  scan_metadata[obj].start[0] = (long)scan_number;
380  for(dim = 0; dim < 3; dim++)
381  rpy_angles[dim] = (float32)(rpy[dim] *
382  (rpy[dim] <= THERMCORR_FVALUE ? 1.0 : RAD2DEG));
383  scan_metadata[obj].data = &rpy_angles;
384  obj++;
385 
386  scan_metadata[obj].start[0] = (long)scan_number;
387  scan_metadata[obj].data = frame_quality + ATT_IDX;
388  obj++;
389 
390  scan_metadata[obj].start[0] = (long)scan_number;
391  scan_metadata[obj].data = frame_quality + EPH_IDX;
392  obj++;
393 
394  for(obj = 0; obj < (int)(sizeof(scan_metadata)/sizeof(scan_metadata[0]));
395  obj++)
396  {
397  if (scan_metadata[obj].data)
398  {
399  if (putMODISarray(geo_file, scan_metadata[obj].name,
400  SCAN_META_GRP, scan_metadata[obj].start,
401  scan_metadata[obj].dims, scan_metadata[obj].data)
402  != MAPIOK)
403  {
404  sprintf(msgbuf, "putMODISarray(%.*s, %.*s)",
405  (MAXMSGBUFFLEN-12)/2, geo_file->filename,
406  (MAXMSGBUFFLEN-12)/2, scan_metadata[obj].name);
407  modsmf(MODIS_E_GEO, msgbuf, filefunc);
408 
409  retval = MODIS_E_GEO;
410  }
411  }
412  }
413 
414  return retval;
415 }
#define SUN_REF
Definition: GEO_product.h:182
#define CB_VECTOR_NUMVALUES
float64 eulerAngles[3]
#define L(lambda, T)
Definition: PreprocessP.h:185
double * mirr_impulse_time[MAX_SCAN_NUMBER]
#define SCAN_TYPE_LEN
#define ORB_POS
Definition: GEO_product.h:178
#define SV_FRAMES
Definition: GEO_product.h:167
#define NULL
Definition: decode_rs.h:63
#define ORB_VEL
Definition: GEO_product.h:179
#define MODIS_E_BAD_INPUT_ARG
#define MAX_FRAMES
Definition: GEO_geo.h:79
PGSt_SMF_status GEO_write_scan_metadata(int const scan_number, l1a_data_struct const *const l1a_data, celestial_bodies_struct const *const cb_vectors, MODFILE *const geo_file, PGSt_double const rpy[], uint32 frame_quality[][MAX_FRAMES])
#define GEO_QUALITY
Definition: GEO_product.h:177
int16_t * l1a_data
Definition: l1a_seawifs.c:84
float64 T_inst2ecr[3][3]
#define MOON_VECTOR
Definition: GEO_product.h:175
#define ATTIT_ANG
Definition: GEO_product.h:181
#define S_NUM
Definition: GEO_product.h:163
PGSt_SMF_status GEO_in_maneuver(PGSt_double tai1993)
Definition: GEO_maneuver.c:7
#define IMPULSE_ENC
Definition: GEO_product.h:184
#define IMPULSE_TIME
Definition: GEO_product.h:185
#define MODIS_E_GEO
#define MSIDE
Definition: GEO_product.h:172
#define EPH_QUALITY
Definition: GEO_product.h:194
#define RAD2DEG
Definition: GEO_geo.h:173
frame_state_struct sc
#define T_INST2ECR
Definition: GEO_product.h:180
#define MODIS_N_GEO_MANEUVER
float64 positionECR[3]
#define SVTIME
Definition: GEO_product.h:170
const int GOOD_DATA
#define ATT_QUALITY
Definition: GEO_product.h:193
#define NUM_L1A_QUALITY_FLAGS
Definition: GEO_geo.h:114
#define DIMSDIM
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
#define SUN_AZIMUTH
Definition: GEO_product.h:174
float64 velocityECR[3]
#define THERMCORR
Definition: GEO_product.h:192
#define MAX_IMPULSE_NUMBER
Definition: GEO_geo.h:91
#define EV_FRAMES
Definition: GEO_product.h:165
@ ATT_IDX
#define SDTIME
Definition: GEO_product.h:169
#define NUM_IMPULSE
Definition: GEO_product.h:183
@ EPH_IDX
for(i=0;i< NROOTS;i++) s[i]
Definition: decode_rs.h:85
#define FILL_INT8
Definition: GEO_output.h:108
#define SCTIME
Definition: GEO_product.h:171
#define SUN_ZENITH
Definition: GEO_product.h:173
#define MAXMSGBUFFLEN
#define EVTIME
Definition: GEO_product.h:168
#define SD_FRAMES
Definition: GEO_product.h:166
#define THERMCORR_FVALUE
Definition: GEO_geo.h:155
#define S_TYPE
Definition: GEO_product.h:164
#define L1_QUALITY
Definition: GEO_product.h:176
#define SCAN_META_GRP
Definition: GEO_product.h:150