OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
GEO_read_L1Apacket_data.c
Go to the documentation of this file.
1 #include "smfio.h"
2 #include "GEO_input.h"
3 #include "L1a_data.h"
4 #include "PGS_MODIS_35251.h"
5 
6 PGSt_SMF_status GEO_read_L1Apacket_data(
7  MODFILE *l1a_file,
8  int const number_of_scans,
9  uint16 earth_encoder_times[MAX_SCAN_NUMBER][ENCODER_LENGTH],
10  sc_ancil_struct sc_ancillary_data[2],
11  int16 view_sector_start[MAX_SCAN_NUMBER][SECTOR_LENGTH],
12  uint16 FRside[MAX_SCAN_NUMBER][ELEC_SIDES],
13  uint16 SAside[MAX_SCAN_NUMBER][ELEC_SIDES],
14  uint16 ss_cp_mode[]
15 )
16 
17 /*
18 !C************************************************************************
19 
20 !Description:
21  Subroutine in the input group of the Level-1A geolocation
22  software to read mirror and spacecraft ancillary data
23  from the L1A product file using the MAPI.
24  PR03-CSC-07
25 
26 !Input Parameters:
27  number_of_scans - number of scans in the granule
28  l1a_file - MAPI structure for L1A file
29 
30 !Output Parameters:
31  earth_encoder_times - array of Earth Encoder Time Data
32  sc_ancillary_data - array of Spacecraft ancillary data.
33  view_sector_start - array of View Sector Start Encoder
34  Count and Vernier Count words
35  FRside - Indicates which side of formatter electronics is
36  turned on
37  SAside - Indicates which sides (sic) of the scan assembly
38  electronics are turned on.
39 
40 Return parameter:
41  MODIS_E_BAD_INPUT_ARG If any argument has an invalid value.
42  MODIS_E_GEO If any subroutine failed.
43  PGS_S_SUCCESS Otherwise
44 
45 Externally Defined:
46  ATTITUDE_ANGLE_ROLL "L1A_data.h"
47  ATTITUDE_ANGLE_PITCH "L1A_data.h"
48  ATTITUDE_ANGLE_YAW "L1A_data.h"
49  ATTITUDE_RATE_ROLL "L1A_data.c"
50  ATTITUDE_RATE_PITCH "L1A_data.h"
51  ATTITUDE_RATE_YAW "L1A_data.h"
52  CR_FR_A_ON "L1A_data.h"
53  CR_FR_B_ON "L1A_data.h"
54  CR_SA_A_SCAN_ON "L1A_data.h"
55  CR_SA_B_SCAN_ON "L1A_data.h"
56  ELEC_SIDES "GEO_geo.h"
57  ENCODER_LENGTH "GEO_geo.h"
58  EARTH_ENCODER_TIMES "L1A_data.h"
59  VIEW_SECTOR_START "L1A_data.h"
60  LAST_VALID_SCAN "L1A_data.h"
61  CURR_SC_ANCIL_DATA "L1A_data.h"
62  MAJCYC3COF7 "L1A_data.h"
63  MAJCYC5BOF7 "L1A_data.h"
64  PRIOR_SC_ANCIL_DATA "L1A_data.h"
65  MAPIOK "mapi.h"
66  MAX_SCAN_NUMBER "GEO_geo.h"
67  MODIS_E_BAD_INPUT_ARG "PGS_MODIS_35251.h"
68  MODIS_E_GEO "PGS_MODIS_35251.h"
69  MODIS_W_GEO_MIRR_CHAN "PGS_MODIS_35251.h"
70  SC_PRIOR "GEO_input.h"
71  SC_CURRENT "GEO_input.h"
72  SC_POSITION_X "L1A_data.h"
73  SC_POSITION_Y "L1A_data.h"
74  SC_POSITION_Z "L1A_data.h"
75  SC_VELOCITY_X "L1A_data.h"
76  SC_VALOCITY_Y "L1A_data.h"
77  SC_VALOCITY_Z "L1A_data.h"
78  SECTOR_LENGTH "GEO_input.h"
79 
80 Called By:
81  GEO_prepare_l1a_data
82 
83 Call functions:
84  modsmf - writes error status messages to log
85  getMODISarray - MAPI routine to read from an array.
86  getMODIStable - MAPI routine to read from a table.
87 
88 Requirements:
89  PR03-F-2.1-1
90  PR03-F-2.1-2
91  PR03-I-3
92 
93 !Revision History:
94  * $Log: GEO_read_L1Apacket_data.c,v $
95  * Revision 6.2 2010/06/01 20:33:30 kuyper
96  * Changed to return status codes.
97  * Made error messages more informative.
98  *
99  * Revision 6.1 2010/03/17 13:44:55 gbritz
100  * Add ephemeris/attitude quality information to MOD03 file.
101  *
102  * Georgios Britzolakis georgios.britzolakis-1@nasa.gov
103  *
104  * Revision 5.1 2005/04/21 20:45:45 kuyper
105  * Correct error message.
106  *
107  * Revision 4.1 2003/02/21 22:48:33 kuyper
108  * Corrected to use void* pointers with %p format code.
109  *
110  * Revision 3.3 2002/06/13 22:52:21 kuyper
111  * Removed unnecessary NCSA acknowledgement.
112  *
113  * Revision 3.2 2001/04/13 22:50:27 kuyper
114  * Changed back to uint16 for earth_encoder_times. Re-written to portably
115  * decode the incorrectly typed data in the raw_mir_enc SDS.
116  *
117  * Revision 3.1 2001/04/02 20:34:21 kuyper
118  * Corrected message mnemonic for getMODISarray message.
119  *
120  * Revision 2.8 2001/04/02 14:49:30 seaton
121  * Changed
122  *
123  * Revision 2.7 2001/04/02 14:44:50 seaton
124  * Entered walkthrough corrections.
125  *
126  * Revision 2.6 2001/03/14 17:59:00 seaton
127  * Added electronics side information from the formatter to the set of data read in.
128  *
129  * Revision 2.5 1999/02/05 19:03:01 seaton
130  * Made walkthrough modifications.
131  *
132  * Revision 2.4 1999/02/02 15:01:47 seaton
133  * Changes to reflect S/C Ancillary Data being read from Vdatas instead of SDS from L1A product.
134  *
135  * Revision 2.3 1998/03/04 00:37:50 jjb
136  * Changed earth_encoder_times and view_sector_start parameters
137  * to uint16's.
138  *
139  * Revision 2.2 1997/11/06 21:39:34 kuyper
140  * Make implicit conversion explicit.
141  *
142  * Revision 2.1 1997/10/21 18:16:22 kuyper
143  * Returned from ClearCase
144  *
145  * Revision /main/GEO_V2_DEV/3 1997/09/26 kuyper
146  * Fixed error messages.
147  *
148  * Revision /main/GEO_V2_DEV/2 1997/08/25 Ding
149  * Added in mirror channel fields.
150  * ding@ltpmail.gsfc.nasa.gov
151  *
152  * Revision 1.4.1.1 1997/07/21 22:20:17 kuyper
153  * Merged in out-of-sequence changes.
154  *
155  * Revision 1.4 1997/07/21 16:24:34 kuyper
156  * Baselined Version 1
157  *
158  * Revision 1.3 1997/03/26 18:13:15 fhliang
159  * Initial revision SDST delivery of GEO_read_L1Apacket_data.c.
160  *
161  *Parallel development:
162  * Revision 1.3 1997/06/02 17:55:35 kuyper
163  * Merged seed files.
164  *
165  Revision 1.2 1997/01/14 23:35:44 kuyper
166  Adjusted header file list.
167  James Kuyper Jr. <kuyper@ltpmail.gsfc.nasa.gov>
168 
169  Revision 1.1 1996/12/20 16:15:39 mikej
170  Initial revision
171 
172 
173 !Team-unique Header:
174  This software is developed by the MODIS Science Data Support
175  Team for the National Aeronautics and Space Administration,
176  Goddard Space Flight Center, under contract NAS5-32373.
177 
178 !END****************************************************************************
179 */
180 
181 {
182 #define N_ELEMENTS(foo) ((int) (sizeof(foo) / sizeof(foo[0])))
183 #define STRMAX 512
184 #define ARGMAX 80
185 #define MAX_SC_DATA_NAME 30
186 #define LAST_VALID_SCAN_INDEX 2
187 
188  /* Warning: The order and sequence of the packet_data initilizations can
189  * not be changed. We finish the initilization later and count on this
190  * order.
191  */
192  struct pack{
193  char *name; /* name of SDS object in the L1A file */
194  long int dims[2]; /* extent of locations in SDS */
195  void * data; /* pointer to the data */
196  } packet_data[] = {
199  };
200  long buffsize;
201  int obj;
202  char msgbuf[STRMAX];
203  static const char filefunc[] = __FILE__ ", GEO_read_L1Apacket_data";
204 
205  static char SAfieldnm[] =
207  static char FRfieldnm[] = CR_FR_A_ON "," CR_FR_B_ON "," LAST_VALID_SCAN;
208  uint16 FRdata[MAX_SCAN_NUMBER][3];
209  uint16 SAdata[MAX_SCAN_NUMBER][3];
210  int16 raw_mir_enc[MAX_SCAN_NUMBER][ENCODER_LENGTH];
211  /* SC Ancillary Data Field Structure */
212  static struct{
213  char *field_names;
214  size_t offset;
215  long int size;
216  } vdata_fields[] =
217  {
218  {TIME_STAMP, offsetof(sc_ancil_struct, second_header),
219  (long)sizeof(sc_ancillary_data[0].second_header) },
222  offsetof(sc_ancil_struct, posvel),
223  (long)sizeof(sc_ancillary_data[0].posvel) },
226  offsetof(sc_ancil_struct, attit_angvel),
227  (long)sizeof(sc_ancillary_data[0].attit_angvel) }
228  };
229  char *ancil_data_name[2];
230  int phase;
231  int scan;
232 
233  if (number_of_scans == 0)
234  return PGS_S_SUCCESS;
235 
236  /* Checking input values */
237  if(l1a_file == NULL || number_of_scans < 0 ||
238  number_of_scans > MAX_SCAN_NUMBER || sc_ancillary_data == NULL ||
239  SAside == NULL || FRside == NULL || ss_cp_mode == NULL)
240  {
241  sprintf(msgbuf, "l1a_file = %p, number_of_scans = %d, "
242  "sc_ancillary_data = %p, SAside = %p, FRside = %p, ss_cp_mode = %p",
243  (void*)l1a_file, number_of_scans, (void*)sc_ancillary_data,
244  (void*)SAside, (void*)FRside, (void*)ss_cp_mode);
245  modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
246 
247  return MODIS_E_BAD_INPUT_ARG;
248  }
249 
250  ancil_data_name[SC_PRIOR] = PRIOR_SC_ANCIL_DATA;
251  ancil_data_name[SC_CURRENT] = CURR_SC_ANCIL_DATA;
252 
253 /* Finish initializing the packet_data array with the contents
254  defined above.
255 
256  See warning about sequence in declaration section
257 */
258  packet_data[0].dims[0] = (long int) number_of_scans;
259  packet_data[0].data = raw_mir_enc;
260  packet_data[1].dims[0] = (long int) number_of_scans;
261  packet_data[1].data = view_sector_start;
262 
263 
264  for (obj = 0; obj < N_ELEMENTS(packet_data); obj++)
265  {
266  long start[2] = {0L, 0L};
267 
268  if (getMODISarray(l1a_file, packet_data[obj].name, L1A_ENGINEERING_GRP,
269  start, packet_data[obj].dims, packet_data[obj].data) != MAPIOK)
270  {
271  sprintf(msgbuf, "getMODISarray(\"%s\", \"%s\", \""
272  L1A_ENGINEERING_GRP "\")", l1a_file->filename,
273  packet_data[obj].name);
274  modsmf(MODIS_E_GEO, msgbuf, filefunc);
275 
276  return MODIS_E_GEO;
277  }
278  }
279 
280  /* raw_mir_enc is incorrectly stored in the L1A file as an int16; it's
281  * actually uint16. The decision has been made to not correct the MOD01
282  * filespec. Therefore, the following loop emulates the 16-bit 2's
283  * complement conversion that occured before the defect was detected, even
284  * if on the current platform int16 is 1's complement, sign/magnitude, or
285  * larger than 16 bits (which it will be, on platforms with no 16 bit
286  * type).
287  */
288  for(scan = 0; scan < MAX_SCAN_NUMBER; scan++)
289  {
290  int enc;
291 
292  for(enc = 0; enc < ENCODER_LENGTH; enc++)
293  {
294  int32 i32 = (int32)raw_mir_enc[scan][enc];
295  earth_encoder_times[scan][enc] =
296  (uint16)(i32 <0 ? (int32)0x10000 + i32 : i32);
297  }
298  }
299 
300 
301 
302 /* FOR Each Prior and Current S/C Ancillary Data */
303  for (phase = SC_PRIOR; phase <= SC_CURRENT; phase++)
304  {
305  for (obj = 0; obj < N_ELEMENTS(vdata_fields); obj++)
306  {
307  buffsize = vdata_fields[obj].size;
308  if (getMODIStable(l1a_file, ancil_data_name[phase],
309  L1A_ENGINEERING_GRP, vdata_fields[obj].field_names, 0L,
310  (long)number_of_scans, &buffsize,
311  (unsigned char *)&sc_ancillary_data[phase] +
312  vdata_fields[obj].offset) != MAPIOK)
313  {
314  sprintf(msgbuf, "getMODIStable(\"%s\", \"%s\", \""
315  L1A_ENGINEERING_GRP "\", \"%s\", %ld)\n",
316  l1a_file->filename, ancil_data_name[phase],
317  vdata_fields[obj].field_names, (long)number_of_scans);
318  modsmf(MODIS_E_GEO, msgbuf, filefunc);
319 
320  return MODIS_E_GEO;
321  } /* if getMODIStable */
322  } /* end for each element */
323  } /* end for phase */
324 
325 
326 /* retrieve mirr_chan data */
327 
328  buffsize=(long)sizeof(FRdata);
329  if(getMODIStable(l1a_file, MAJCYC3COF7, L1A_ENGINEERING_GRP, FRfieldnm, 0L,
330  (long)number_of_scans, &buffsize, (unsigned char *) FRdata) != MAPIOK)
331  {
332  sprintf(msgbuf, "getMODIStable(\"%s\", \"" MAJCYC3COF7 "\", \""
333  L1A_ENGINEERING_GRP "\", \"%s\", 0, %ld)\n",
334  l1a_file->filename, FRfieldnm, (long)number_of_scans);
335  modsmf(MODIS_E_GEO, msgbuf, filefunc);
336 
337  return MODIS_E_GEO;
338  }
339 
340 
341  buffsize=(long)sizeof(SAdata);
342  if(getMODIStable(l1a_file, MAJCYC5BOF7, L1A_ENGINEERING_GRP, SAfieldnm, 0L,
343  (long)number_of_scans, &buffsize, (unsigned char *) SAdata) != MAPIOK)
344  {
345  sprintf(msgbuf, "getMODIStable(\"%s\", \"" MAJCYC5BOF7 "\", \""
346  L1A_ENGINEERING_GRP "\", \"%s\", 0, %ld)\n",
347  l1a_file->filename, SAfieldnm, (long)number_of_scans);
348  modsmf(MODIS_E_GEO, msgbuf, filefunc);
349 
350  return MODIS_E_GEO;
351  }
352 
353  buffsize = (long)(number_of_scans*sizeof*ss_cp_mode);
354  if(getMODIStable(l1a_file, M01MAJCYCALL1, L1A_ENGINEERING_GRP,
355  M01SS_CP_MODE, 0L, (long)number_of_scans, &buffsize,
356  (unsigned char *)ss_cp_mode) != MAPIOK)
357  {
358  sprintf(msgbuf, "getMODIStable(\"%s\", \"" M01MAJCYCALL1 "\", \""
359  L1A_ENGINEERING_GRP "\", \"" M01SS_CP_MODE "\", 0, %ld)\n",
360  l1a_file->filename, (long)number_of_scans);
361  modsmf(MODIS_E_GEO, msgbuf, filefunc);
362 
363  return MODIS_E_GEO;
364  }
365 
366 
367  if((SAdata[number_of_scans-1][LAST_VALID_SCAN_INDEX])==65535)
368  {
369  modsmf(MODIS_W_GEO_MIRR_CHAN, "", filefunc);
370  for(obj=number_of_scans-1; obj>=0; obj--)
371  {
372  FRside[obj][CHAN_A]=0;
373  FRside[obj][CHAN_B]=0;
374  SAside[obj][CHAN_A]=0;
375  SAside[obj][CHAN_B]=0;
376  }
377  }
378  else for(obj=number_of_scans-1; obj>=0; obj--)
379  {
380  if(FRdata[obj][LAST_VALID_SCAN_INDEX] != 65535)
381  {
382  FRside[obj][CHAN_A] = FRdata[obj][CHAN_A];
383  FRside[obj][CHAN_B] = FRdata[obj][CHAN_B];
384  }
385  else
386  {
387  if (obj == number_of_scans-1)
388  {
389  FRside[obj][CHAN_A] = 0;
390  FRside[obj][CHAN_B] = 0;
391  }
392  else
393  {
394  FRside[obj][CHAN_A] = FRside[obj + 1][CHAN_A];
395  FRside[obj][CHAN_B] = FRside[obj + 1][CHAN_B];
396  }
397  }
398 
399  if(SAdata[obj][LAST_VALID_SCAN_INDEX] != 65535)
400  {
401  SAside[obj][CHAN_A] = SAdata[obj][CHAN_A];
402  SAside[obj][CHAN_B] = SAdata[obj][CHAN_B];
403  }
404  else
405  {
406  if(obj == number_of_scans - 1)
407  {
408  SAside[obj][CHAN_A] = 0;
409  SAside[obj][CHAN_B] = 0;
410  }
411  else
412  {
413  SAside[obj][CHAN_A] = SAside[obj + 1][CHAN_A];
414  SAside[obj][CHAN_B] = SAside[obj + 1][CHAN_B];
415  }
416  }
417  }
418  return PGS_S_SUCCESS;
419 }
#define MODIS_W_GEO_MIRR_CHAN
integer, parameter int16
Definition: cubeio.f90:3
#define ATTITUDE_RATE_YAW
Definition: L1a_data.h:153
#define L(lambda, T)
Definition: PreprocessP.h:185
#define L1A_ENGINEERING_GRP
Definition: L1a_data.h:105
#define CR_FR_A_ON
Definition: L1a_data.h:156
@ SC_CURRENT
Definition: GEO_input.h:94
#define SC_POSITION_Z
Definition: L1a_data.h:144
#define NULL
Definition: decode_rs.h:63
#define MODIS_E_BAD_INPUT_ARG
#define N_ELEMENTS(foo)
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 EARTH_ENCODER_TIMES
Definition: L1a_data.h:121
#define SC_VELOCITY_X
Definition: L1a_data.h:145
#define PRIOR_SC_ANCIL_DATA
Definition: L1a_data.h:154
#define MODIS_E_GEO
#define LAST_VALID_SCAN
Definition: L1a_data.h:160
#define VIEW_SECTOR_START
Definition: L1a_data.h:123
const int SECTOR_LENGTH
#define CR_FR_B_ON
Definition: L1a_data.h:157
#define CHAN_A
#define MAJCYC5BOF7
Definition: L1a_data.h:163
@ SC_PRIOR
Definition: GEO_input.h:94
#define CURR_SC_ANCIL_DATA
Definition: L1a_data.h:155
#define ATTITUDE_ANGLE_YAW
Definition: L1a_data.h:150
#define ATTITUDE_RATE_PITCH
Definition: L1a_data.h:152
#define ELEC_SIDES
Definition: GEO_geo.h:108
#define STRMAX
#define LAST_VALID_SCAN_INDEX
#define ATTITUDE_RATE_ROLL
Definition: L1a_data.h:151
#define TIME_STAMP
Definition: L1a_data.h:141
#define CR_SA_B_SCAN_ON
Definition: L1a_data.h:159
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
#define CHAN_B
#define ATTITUDE_ANGLE_PITCH
Definition: L1a_data.h:149
subroutine phase
Definition: phase.f:2
const int MAX_SCAN_NUMBER
PGSt_SMF_status GEO_read_L1Apacket_data(MODFILE *l1a_file, int const number_of_scans, uint16 earth_encoder_times[MAX_SCAN_NUMBER][ENCODER_LENGTH], sc_ancil_struct sc_ancillary_data[2], int16 view_sector_start[MAX_SCAN_NUMBER][SECTOR_LENGTH], uint16 FRside[MAX_SCAN_NUMBER][ELEC_SIDES], uint16 SAside[MAX_SCAN_NUMBER][ELEC_SIDES], uint16 ss_cp_mode[])
#define ATTITUDE_ANGLE_ROLL
Definition: L1a_data.h:148
#define SC_VELOCITY_Z
Definition: L1a_data.h:147
#define MAJCYC3COF7
Definition: L1a_data.h:162
l2prod offset
#define SC_POSITION_Y
Definition: L1a_data.h:143
#define SC_POSITION_X
Definition: L1a_data.h:142
#define SC_VELOCITY_Y
Definition: L1a_data.h:146
#define ENCODER_LENGTH
Definition: GEO_geo.h:111
#define CR_SA_A_SCAN_ON
Definition: L1a_data.h:158