OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
GEO_read_L1Ascan_metadata.c
Go to the documentation of this file.
1 #include "PGS_MODIS_35251.h"
2 #include "GEO_input.h"
3 #include "L1a_data.h"
4 #include "smfio.h"
5 
7  MODFILE * const l1a_file,
8  int const number_of_scans,
9  l1a_metadata_struct const * const granule_metadata,
11  int16 mirr_side[MAX_SCAN_NUMBER]
12  )
13 
14 /*
15 !C***********************************************************************
16 
17 !Description:
18  Subroutine in the input group of the Level-1A geolocation
19  software to read L1A scan-level metadata from the L1A
20  product file using the MAPI.
21 
22 !Input Parameters:
23  l1a_file - MAPI structure for l1a file
24  number_of_scans - number of scans in the granule
25  granule_metadata - l1a specific granule metadata
26 
27 !Output Parameters:
28  frame_data_struct frame_data - L1A scan start times and
29  scan frame sizes
30  mirr_side - mirror side for each scan
31 
32 Return parameter:
33  SUCCESS if all specified data
34  are successfully retrieved,
35  FAIL otherwise.
36 
37 Global variables:
38  None.
39 
40 Routins called:
41  modsmf - writes error status messages to log
42  int getMODISarray - MAPI routine to read from an array
43 Called by:
44  GEO_prepare_L1Ascan_metadata()
45 
46 !Revision History:
47  * $Log: GEO_read_L1Ascan_metadata.c,v $
48  * Revision 4.1 2003/02/21 22:46:47 kuyper
49  * Corrected to use void* pointers with %p format code.
50  *
51  * Revision 3.1 2002/06/13 22:53:22 kuyper
52  * Removed unnecessary NCSA acknowledgement.
53  *
54  * Revision 2.6 2000/07/26 19:31:31 vlin
55  * Modified the content of the error message for calls to
56  * function "modsmf"
57  *
58  * Revision 2.5 2000/05/05 15:30:20 lma
59  * updated after walkthrough
60  *
61  * Revision 2.4 2000/05/02 20:48:48 lma
62  * added one SDS(Scan Type) per CCR507
63  *
64  * Revision 2.3 1999/02/02 18:07:08 kuyper
65  * Make sprintf() format string consistent with the argument list.
66  *
67  * Revision 2.2 1998/02/08 23:00:57 jjb
68  * Corrected defect described in DDTS MODxl00596:
69  * Check number of Space View frames in each scan
70  * against max_sv_frames.
71  *
72  * Revision 2.1 1997/10/21 18:16:22 kuyper
73  * Returned from ClearCase
74  *
75  * Revision /main/GEO_V2_DEV/3 1997/10/03 kuyper
76  * Corrected MODIS_W_GEO_FRAMENO_INPUT messages.
77  *
78  * Revision /main/GEO_V2_DEV/2 1997/08/29 Ding
79  * Added in SDS sci_state and sci_abnorm.
80  * ding@ltpmail.gsfc.nasa.gov
81  *
82  * Revision 1.4.1.1 1997/07/21 22:20:17 kuyper
83  * Merged in out-of-sequence changes.
84  *
85  * Revision 1.4 1997/07/21 16:24:34 kuyper
86  * Baselined Version 1
87  *
88  *Parallel development:
89  * Revision 1.3 1997/06/02 18:01:11 kuyper
90  * Merged seed files.
91  *
92  * Revision 1.3 1997/03/26 18:13:34 fhliang
93  * Initial revision of SDST delivery of GEO_read_L1Ascan_metadata.c.
94  *
95  Revision 1.2 1997/01/15 17:15:49 kuyper
96  Changed to use M01 M-API macros indirectly.
97  Corrected scan_id, frame_count to int16.
98 
99  James Kuyper kuyper@ltpmail.gsfc.nasa.gov
100 
101  Revision 1.1 1997/01/08 18:29:35 mikej
102  Initial revision
103 
104 
105 !Team-unique Header:
106  This software is developed by the MODIS Science Data Support
107  Team for the National Aeronautics and Space Administration,
108  Goddard Space Flight Center, under contract NAS5-32373.
109 
110 !END****************************************************************************
111 */
112 
113 {
114 
115 /* Note: Earth_Frames, SD_Frames, and SV_Frames are not all capitals to avoid
116 conflict with string literals in GEO_product.h */
117 #define Earth_Frames 1
118 #define SD_Frames 2
119 #define SV_Frames 5
120 /* Magic number, the index of the "Mirror side" entry in the Scan_metadata
121 array. If additional entries are added this must be changed */
122 #define MIRR_SIDE_INDEX 8
123 #define NUM_METADATA (sizeof(Scan_metadata) / sizeof(Scan_metadata[0]))
124 
125  static float64 *EV_start;
126  static float64 *SD_start;
127  static float64 *SV_start;
128  typedef int32 scan_quality_t[NUM_L1A_QUALITY_FLAGS];
129  static scan_quality_t *scan_quality;
130  static int16 *scan_id;
131  typedef int16 frame_count_t[NUM_L1A_SECTOR_VIEWS];
132  static frame_count_t *frame_count;
133  static int8 *sci_state;
134  static int8 *sci_abnorm;
135  typedef char8 scan_type_t[SCAN_TYPE_LEN];
136  static scan_type_t *scan_type;
137 
138  // allocate static memory
139  static firstRun = 1;
140  if(firstRun) {
141  firstRun = 0;
142  EV_start = (float64*) calloc(MAX_SCAN_NUMBER, sizeof(float64));
143  SD_start = (float64*) calloc(MAX_SCAN_NUMBER, sizeof(float64));
144  SV_start = (float64*) calloc(MAX_SCAN_NUMBER, sizeof(float64));
145  scan_quality = (scan_quality_t*) calloc(MAX_SCAN_NUMBER, sizeof(scan_quality_t));
146  scan_id = (int16*) calloc(MAX_SCAN_NUMBER, sizeof(int16));
147  frame_count = (frame_count_t*) calloc(MAX_SCAN_NUMBER, sizeof(frame_count_t));
148  sci_state = (int8*) calloc(MAX_SCAN_NUMBER, sizeof(int8));
149  sci_abnorm = (int8*) calloc(MAX_SCAN_NUMBER, sizeof(int8));
150  scan_type = (scan_type_t*) calloc(MAX_SCAN_NUMBER, sizeof(scan_type_t));
151  }
152 
153  struct scan_meta{
154  char *name; /* name of SDS object in the L1A file */
155  long int dims[2]; /* extent of locations in SDS */
156  void * data; /* pointer to the data */
157  } Scan_metadata[] = {
158  {SCAN_NUMBER, {MAX_SCAN_NUMBER, 0L}, scan_id},
160  , frame_count},
161  {SCAN_START_TIME, {MAX_SCAN_NUMBER, 0L}, EV_start},
162  {SD_START_TIME, {MAX_SCAN_NUMBER, 0L}, SD_start},
163  {SV_START_TIME, {MAX_SCAN_NUMBER, 0L}, SV_start},
165  scan_quality},
166  {SCIENCE_STATE, {MAX_SCAN_NUMBER, 0L}, sci_state},
167  {SCIENCE_ABNORM, {MAX_SCAN_NUMBER, 0L}, sci_abnorm},
169  {SCAN_TYPES, {MAX_SCAN_NUMBER, SCAN_TYPE_LEN}, scan_type}
170  };
171 
172  long start[2] = {0L, 0L}; /* offset for getMODISarray */
173  int retval=SUCCESS;
174  int i, scan; /* loop indices */
175  char msgbuf[PGS_SMF_MAX_MSGBUF_SIZE]; /* scratch string buffer */
176 
177 /* Check input values */
178 
179  if((l1a_file == NULL) || (granule_metadata == NULL) || (number_of_scans < 0)
180  || (number_of_scans > MAX_SCAN_NUMBER) || (frame_data == NULL) ||
181  (mirr_side == NULL))
182  {
183  sprintf(msgbuf, "Invalid input argument l1a_file = %p, "
184  "granule_metadata = %p, number_of_scans = %d, frame_data = %p, "
185  "mirror_side = %p", (void*)l1a_file, (void*)granule_metadata,
186  number_of_scans, (void*)frame_data, (void*)mirr_side );
187  modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf,
188  "GEO_read_L1Ascan_metadata.c, GEO_read_L1Ascan_metadata");
189  return FAIL;
190  }
191  else if(number_of_scans == 0)
192  return SUCCESS;
193 
194 
195 /*
196  Finish initializing the scan_metadata array with the contents
197  defined above. Data is retrieved into data types
198  conforming with the SDS's data type.
199 
200  See magic number warning in define section.
201 */
202  Scan_metadata[MIRR_SIDE_INDEX].data = (void *) mirr_side;
203  for(i = 0; i < (int) NUM_METADATA; i++) {
204  Scan_metadata[i].dims[0] = (long int) number_of_scans;
205  }
206 
207 /* read a scan_metadata[i].dims array into packet_data[i].data */
208 
209  for (i = 0; i < (int) NUM_METADATA; i++) {
210  if (getMODISarray(l1a_file, Scan_metadata[i].name, L1A_SCAN_META_GRP,
211  start, Scan_metadata[i].dims, Scan_metadata[i].data) != MAPIOK) {
212  sprintf(msgbuf, " getMODISarray reading %s", Scan_metadata[i].name);
213  modsmf(MODIS_E_GEO, msgbuf,
214  "GEO_read_L1Ascan_metadata.c, GEO_read_L1Ascan_metadata");
215  retval=FAIL;
216  }
217  }
218 
219 /*
220  load the output structure
221  FOR each of the number_of_scans scan's
222 */
223  for (scan = 0; scan < number_of_scans; scan++) {
224  frame_data[scan].L1A_scan_id = (int32)scan_id[scan];
225  frame_data[scan].EV_start = EV_start[scan];
226  for(i = 0; i < NUM_L1A_QUALITY_FLAGS; i++) {
227  frame_data[scan].L1A_scan_quality[i] = scan_quality[scan][i];
228  }
229  if((frame_count[scan][Earth_Frames]>=0) &&
230  (frame_count[scan][Earth_Frames] <=
231  granule_metadata->max_earth_frames))
232  {
233  frame_data[scan].EV_frames =
234  (int32)frame_count[scan][Earth_Frames];
235  }
236  else
237  {
238  sprintf(msgbuf, "%d Earth frames in scan %d",
239  (int)frame_count[scan][Earth_Frames], scan);
240  modsmf(MODIS_W_GEO_FRAMENO_INPUT, msgbuf,
241  "GEO_read_L1Ascan_metadata.c, GEO_read_L1Ascan_metadata");
242 
243  frame_data[scan].EV_frames = 0;
244  }
245 
246  frame_data[scan].SD_start = SD_start[scan];
247  if((frame_count[scan][SD_Frames] >=0 ) &&
248  (frame_count[scan][SD_Frames] <=
249  granule_metadata->max_sd_frames))
250  {
251  frame_data[scan].SD_frames =
252  (int32)frame_count[scan][SD_Frames];
253  }
254  else
255  {
256  sprintf(msgbuf, "%d SD Frames in scan %d",
257  (int)frame_count[scan][SD_Frames], scan);
258  modsmf(MODIS_W_GEO_FRAMENO_INPUT, msgbuf,
259  "GEO_read_L1Ascan_metadata.c, GEO_read_L1Ascan_metadata");
260 
261  frame_data[scan].SD_frames = 0;
262  }
263 
264  frame_data[scan].SV_start = SV_start[scan];
265  if((frame_count[scan][SV_Frames] >= 0) &&
266  (frame_count[scan][SV_Frames] <=
267  granule_metadata->max_sv_frames))
268  {
269  frame_data[scan].SV_frames =
270  (int32)frame_count[scan][SV_Frames];
271  }
272  else
273  {
274  sprintf(msgbuf, "%d SV frames in scan %d",
275  (int)frame_count[scan][SV_Frames], scan);
276  modsmf(MODIS_W_GEO_FRAMENO_INPUT, msgbuf,
277  "GEO_read_L1Ascan_metadata.c, GEO_read_L1Ascan_metadata");
278 
279  frame_data[scan].SV_frames = 0;
280  }
281 
282  frame_data[scan].SCI_STATE = sci_state[scan];
283  frame_data[scan].SCI_ABNORM = sci_abnorm[scan];
284  memcpy(frame_data[scan].Scan_type, scan_type[scan],sizeof(scan_type[scan]));
285  }
286 
287  return retval;
288 }
#define SCIENCE_ABNORM
Definition: L1a_data.h:129
integer, parameter int16
Definition: cubeio.f90:3
#define SUCCESS
Definition: ObpgReadGrid.h:15
#define SCAN_START_TIME
Definition: L1a_data.h:110
#define L(lambda, T)
Definition: PreprocessP.h:185
#define SCAN_TYPE_LEN
#define MODIS_W_GEO_FRAMENO_INPUT
#define FAIL
Definition: ObpgReadGrid.h:18
#define NULL
Definition: decode_rs.h:63
#define MODIS_E_BAD_INPUT_ARG
MOD_PR01 Production producing one five minute granule of output data in each run It can be configured to produce as many as three five minute granules per run Each execution with one construction record and one date file for each dataset In normal these are created by which splits them out of the hour datasets For LANCE they are created by which merges all session MODIS L0 datasets overlapping the requested time and extracts from the merged data those packets which fall within that time period Each scan of data is stored in the L1A granule that covers the start time of that scan
Definition: MOD_PR01_pr.txt:19
#define SCAN_QUALITY_ARRAY
Definition: L1a_data.h:125
#define SV_START_TIME
Definition: L1a_data.h:127
#define NUM_L1A_SECTOR_VIEWS
Definition: GEO_geo.h:115
#define MODIS_E_GEO
int GEO_read_L1Ascan_metadata(MODFILE *const l1a_file, int const number_of_scans, l1a_metadata_struct const *const granule_metadata, frame_data_struct frame_data[MAX_SCAN_NUMBER], int16 mirr_side[MAX_SCAN_NUMBER])
#define MIRR_SIDE_INDEX
#define SCAN_NUMBER
Definition: L1a_data.h:124
#define SCIENCE_STATE
Definition: L1a_data.h:128
#define NUM_L1A_QUALITY_FLAGS
Definition: GEO_geo.h:114
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
const int MAX_SCAN_NUMBER
#define EARTH_SECTOR_FRAMES
Definition: L1a_data.h:112
#define SV_Frames
#define Earth_Frames
#define MIRROR_SIDE
Definition: L1a_data.h:117
#define SD_START_TIME
Definition: L1a_data.h:126
#define NUM_METADATA
#define L1A_SCAN_META_GRP
Definition: L1a_data.h:104
int i
Definition: decode_rs.h:71
#define SCAN_TYPES
Definition: L1a_data.h:111
#define SD_Frames