OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
process_a_granule.c
Go to the documentation of this file.
1 #include <time.h>
2 #include "PGS_IO.h"
3 #include "PGS_SMF.h"
4 #include "mapi.h"
5 #include "L1A_prototype.h"
6 #include "packet_stats.h"
7 #include "PGS_MODIS_35005.h"
8 
9 PGSt_SMF_status process_a_granule (PGSt_IO_L0_VirtualDataSet L0_file,
10  PGSt_double gran_start_time,
11  PGSt_double gran_end_time,
12  PCF_CONFIG_t *pcf_config,
13  EN_VDATA_TYPE_t *eng_data,
14  PH_PACKET_HEADER_t *pkt_header,
15  PGSt_IO_L0_Packet *pkt,
16  FP_QUEUE_t *failed_pkts)
17 
18 /******************************************************************************
19 !C
20 
21 !Description: Function process_a_granule processes scans within a granule,
22  collects global metadata about the scans for the granule, and
23  writes the scans into a L1A granule.
24 
25 !Input Parameters:
26  L0_file L0 file descriptor
27  gran_start_time Start time of the L1A granule to be made
28  gran_end_time End time of the L1A granule to be made
29  pcf_config PCF configuration parameters
30 
31 !Output Parameters: None
32 
33 !Input/Output Parameters:
34  *eng_data Engineering data
35  *pkt_header Packet header information
36  *pkt Packet buffer
37  *failed_pkts Discarded packets
38 
39 Return Values:
40  MODIS_E_NULL_POINTER
41  MODIS_F_PROCESSAGRANULE
42  MODIS_F_UNABLE_TO_INIT_MCF
43  MODIS_F_PKT_READ_FAILED
44  MODIS_F_WRITE_ENG_DATA_FAIL
45  MODIS_S_SUCCESS
46  MODIS_W_NO_MORE_PACKETS
47 
48 Externally Defined:
49  ARCHIVED_METADATA (mapi.h)
50  ECSattr_names_for_all_handles (mapi.h)
51  EN_VDATA_TYPE_t (EN_eng_data.h)
52  FALSE (hdf.h)
53  FP_QUEUE_t (FP_failed_pkt_queue.h)
54  INVENTORY_METADATA (mapi.h)
55  MAPIOK (mapi.h)
56  MD_ECS_GRA_INV_MET_t (MD_metadata.h)
57  MD_L1A_SPECIFIC_MET_t (MD_metadata.h)
58  MD_SCAN_MET_t (MD_metadata.h)
59  MECS_ARCHIVE (mapi.h)
60  MECS_CORE (mapi.h)
61  MODFILE (mapi.h)
62  MODIS_E_CHECKSUM_NOT_VALID (PGS_MODIS_35005.h)
63  MODIS_E_CREATE_L1A_GRANULE (PGS_MODIS_35005.h)
64  MODIS_E_INV_PKT_SEQ_FLAG (PGS_MODIS_35005.h)
65  MODIS_E_INV_PKT_TIME (PGS_MODIS_35005.h)
66  MODIS_E_L1A (PGS_MODIS_35005.h)
67  MODIS_E_NULL_POINTER (PGS_MODIS_35005.h)
68  MODIS_E_SCANCNT_NOT_VALID (PGS_MODIS_35005.h)
69  MODIS_E_WRITE_GLOBAL_METADATA (PGS_MODIS_35005.h)
70  MODIS_F_PROCESSAGRANULE (PGS_MODIS_35005.h)
71  MODIS_F_UNABLE_TO_INIT_MCF (PGS_MODIS_35005.h)
72  MODIS_F_PKT_READ_FAILED (PGS_MODIS_35005.h)
73  MODIS_F_WRITE_ENG_DATA_FAIL (PGS_MODIS_35005.h)
74  MODIS_M_PKT_NOT_IN_SCAN (PGS_MODIS_35005.h)
75  MODIS_S_SUCCESS (PGS_MODIS_35005.h)
76  MODIS_W_INV_PKTLEN (PGS_MODIS_35005.h)
77  MODIS_W_NO_MORE_PACKETS (PGS_MODIS_35005.h)
78  PC_MCF_PCF_ID (PC_pcf_info.h)
79  PCF_CONFIG_t (PC_pcf_info.h)
80  PGS_SMF_MASK_LEV_F (PGS_SMF.h)
81  PGS_TRUE (PGS_SMF.h)
82  PGSt_double (PGS_TYPES.h)
83  PGSt_IO_L0_Packet (PGS_IO.h)
84  PGSt_IO_L0_VirtualDataSet (PGS_IO.h)
85  PGSt_MET_all_handles (PGS_MET.h)
86  PGSt_PC_Logical (PGS_IO.h)
87  PGSt_SMF_status (PGS_SMF.h)
88  PH_PACKET_HEADER_t (PH_pkt_hdr.h)
89  SC_SCAN_DATA_t (SC_scan.h)
90  SC_PIXEL_QUALITY_DATA_t (SC_scan.h)
91  stats (packet_stats.h)
92  TRUE (hdf.h)
93 
94 Called By:
95  level1a
96 
97 Routines Called:
98  completeMODISfile
99  compute_SD_start_time
100  create_L1A_granule
101  end_eng_data_access_to_file
102  handle_missing_scans
103  initialize_global_metadata
104  log_fmt_msg
105  PGS_MET_Init
106  PGS_SMF_TestSuccessLevel
107  reset_last_valid_scan
108  update_global_metadata
109  process_a_scan
110  write_global_metadata
111  write_scan
112 
113 !Revision History:
114  $Log: process_a_granule.c,v $
115  Revision 6.5 2014/09/10 21:44:06 jkuyper
116  Resolve Bug 5555 by handling records with invalid sector values correctly.
117 
118  Revision 6.4 2012/06/22 20:02:50 kuyper
119  Corrected to initialize gran_start_time_used.
120 
121  Revision 6.3 2012/02/02 23:19:12 kuyper
122  Merged changes made between 5.2 and 6.1 with changes made between 5.2 and 5.2.1.2. Did it manually
123  this time, hopefully with better results.
124 
125  Revision 6.2 2011/12/12 23:24:45 kuyper
126  Merged changes made in 5.2.1.2 back to main branch.
127 
128  Revision 6.1 2010/08/25 16:41:35 kuyper
129  Corrected to handle all valid returns from process_a_scan(), and to treat
130  invalid return values as errors.
131  Added initialization and printout of packet filtering statistics.
132 
133  Revision 5.2 2007/01/26 21:15:11 kuyper
134  Changed to pass gran_start_time to handle_missing_scans(), allowing a full
135  resolution to Bug 199.
136 
137  Revision 5.1 2006/11/09 18:00:39 kuyper
138  Changed to prevent processing one more than the maximum number of scans.
139 
140  Revision 4.2 2006/01/05 16:38:56 kuyper
141  Corrected to make md_handles static.
142 
143  Revision 4.1 2003/04/15 18:23:55 vlin
144  calculate scan number after null pointers were checked.
145 
146  Revision 4.0 2002/12/26 20:22:20 vlin
147  Updated to match process_a_granule.pdl V4.0
148  vlin@saicmodis.com
149 
150  Revision 1.3 2000/07/11
151  John Seaton/GSC (seaton@ltpmail.gsfc.nasa.gov)
152  Removed revision 1.2 changes. Code has been developed to
153  fix the split scan problem
154 
155  revision 1.0 1997/08/27 17:30:00
156  Qi Huang/RDC (qhuang@ltpmail.gsfc.nasa.gov)
157  Original development
158 
159 !Team-unique Header:
160  This software is developed by the MODIS Science Data Support
161  Team for the National Aeronautics and Space Administration,
162  Goddard Space Flight Center, under contract NAS5-32373.
163 
164 References and Credits: None
165 
166 Design Notes: None
167 
168 !END
169 ******************************************************************************/
170 
171 {
172  const char filefunc[] = "process_a_granule";
173  PGSt_SMF_status returnStatus = MODIS_S_SUCCESS;
174  PGSt_SMF_status PGS_status = MODIS_S_SUCCESS, L1A_status;
175  int nscans;
176  ECSattr_names_for_all_handles ECS_attr_names;
177 
178  static PGSt_MET_all_handles md_handles;
179  static int MET_Init_flag = TRUE;
180 
181  memset(&stats, 0, sizeof(stats));
182  strcpy(ECS_attr_names[INVENTORY_METADATA], MECS_CORE);
183  strcpy(ECS_attr_names[ARCHIVED_METADATA], MECS_ARCHIVE);
184 
185  if (pcf_config == NULL || eng_data == NULL || pkt_header == NULL ||
186  pkt == NULL || failed_pkts == NULL) {
187  log_fmt_msg(MODIS_E_NULL_POINTER, filefunc, "");
188  return MODIS_E_NULL_POINTER;
189  }
190 
191  nscans = ((gran_end_time - gran_start_time) / pcf_config->scan_rate) + 5;
192 
193  if (MET_Init_flag == TRUE) {
194  PGS_status = PGS_MET_Init(PC_MCF_PCF_ID, md_handles);
195  MET_Init_flag = FALSE;
196  }
197 
198  if (PGS_SMF_TestSuccessLevel(PGS_status) != PGS_TRUE) {
199  returnStatus = MODIS_F_UNABLE_TO_INIT_MCF;
200  log_fmt_msg(MODIS_F_UNABLE_TO_INIT_MCF, filefunc, "MCF LUN: %d",
201  PC_MCF_PCF_ID);
202  }
203 
204  else /* MCF initialization is OK */
205  {
206  time_t tnow;
207  PGSt_double SD_start_time;
208  int prev_scan_number;
209  MODFILE *L1A_file_ptr = NULL;
210  MD_ECS_GRA_INV_MET_t ecs_gra_inv_met;
211  MD_L1A_SPECIFIC_MET_t l1a_specific_met;
212  static int last_granule_was_empty = TRUE;
213  static PGSt_double pre_SD_time = -1.0;
214  int Mapi_R_Status = MAPIOK;
215  int gran_start_time_used = FALSE;
216 
217  L1A_status = initialize_global_metadata(gran_start_time, gran_end_time,
218  nscans, pcf_config, &ecs_gra_inv_met, &l1a_specific_met);
219 
220  if (L1A_status != MODIS_S_SUCCESS)
222 
223  reset_last_valid_scan(eng_data);
224 
225 
226  if ((pre_SD_time < 0.0) || (last_granule_was_empty == TRUE))
227  {
228  pre_SD_time = gran_start_time;
229  gran_start_time_used = TRUE;
230  }
231 
232  compute_SD_start_time(pkt_header, &SD_start_time);
233  prev_scan_number = 0;
234 
235  if ((SD_start_time >= gran_start_time) &&
236  (SD_start_time < gran_end_time))
237  {
238  int continue_processing = TRUE;
239 
240  last_granule_was_empty = FALSE;
241  if(create_L1A_granule(eng_data, nscans, &L1A_file_ptr)
242  != MODIS_S_SUCCESS)
243  {
244  returnStatus = MODIS_F_PROCESSAGRANULE;
245  log_fmt_msg(MODIS_E_CREATE_L1A_GRANULE, filefunc, " ");
246  }
247  else while ((SD_start_time >= gran_start_time) &&
248  (SD_start_time < gran_end_time) &&
249  (l1a_specific_met.num_scans < nscans) &&
250  (continue_processing == TRUE))
251  {
252  if (prev_scan_number % 10 == 0) {
253  time(&tnow);
254  printf("scan: %d out of %d %s",
255  prev_scan_number, nscans, asctime(localtime(&tnow)));
256  }
257 
258  MD_SCAN_MET_t scan_metadata;
259 
260  L1A_status = handle_missing_scans(L1A_file_ptr, SD_start_time,
261  &pre_SD_time, pcf_config->scan_rate,
262  &prev_scan_number, &ecs_gra_inv_met,
263  &l1a_specific_met, &gran_start_time_used,
264  gran_start_time, eng_data);
265 
266  if (L1A_status == MODIS_F_WRITE_ENG_DATA_FAIL) {
267  returnStatus = L1A_status;
269  "Could not write data for the missing scans at either the\n"
270  "beginning or the middle of the granule");
271  continue_processing = FALSE;
272  }
273  else
274  {
275  SC_SCAN_DATA_t scan_data;
276  SC_PIXEL_QUALITY_DATA_t pixel_quality_data;
277 
278  if (L1A_status != MODIS_S_SUCCESS)
279  log_fmt_msg(MODIS_E_HANDLE_MISSING_SCANS, filefunc, "The scan "
280  "metadata could not be written for the missing scans at\n"
281  "either the beginning or the middle of the granule");
282 
283  L1A_status = process_a_scan(&prev_scan_number, pkt,
284  &pcf_config->scan_rate, &SD_start_time,
285  &scan_data, &scan_metadata, eng_data, failed_pkts,
286  pkt_header, &pixel_quality_data, &L0_file);
287 
288  switch (L1A_status) {
292  case MODIS_E_L1A:
295  case MODIS_S_SUCCESS:
296  case MODIS_W_INV_PKTLEN:
297  case MODIS_E_INV_SECTOR:
298  break;
299 
302  "A fatal error occurred while creating scan number %d ",
303  scan_metadata.scan_num);
304  continue_processing = FALSE;
305  returnStatus = L1A_status;
306  break;
307 
310  "Unable to finish creating L1A scan number %d",
311  scan_metadata.scan_num);
312  continue_processing = FALSE;
313  returnStatus = MODIS_W_NO_MORE_PACKETS;
314  break;
315 
316  default:
317  log_fmt_msg(MODIS_E_SCAN_PROCESS, filefunc, "Scan number %d",
318  scan_metadata.scan_num);
319  returnStatus = MODIS_E_L1A;
320  continue_processing = FALSE;
321  }
322 
323  L1A_status = write_scan(L1A_file_ptr, &scan_data,
324  &scan_metadata, &pixel_quality_data,
325  *failed_pkts, eng_data);
326 
327  if (L1A_status == MODIS_F_WRITE_ENG_DATA_FAIL) {
328  returnStatus = L1A_status;
330  "The engineering data could not be written for\n"
331  "scan number %d", scan_metadata.scan_num);
332  continue_processing = FALSE;
333  }
334  else if (L1A_status != MODIS_S_SUCCESS)
336  "Not all of the data could be written for scan number %d",
337  scan_metadata.scan_num);
338  }
339 
340  update_global_metadata(&scan_metadata, &ecs_gra_inv_met,
341  &l1a_specific_met);
342 
343  } /* End while */
344  if(l1a_specific_met.num_scans >= nscans && SD_start_time < gran_end_time)
345  log_fmt_msg(MODIS_W_TOO_MANY_SCANS, filefunc, "");
346 
347  L1A_status = PGS_SMF_TestStatusLevel(returnStatus);
348 
349  if (L1A_status < PGS_SMF_MASK_LEV_F && L1A_file_ptr)
350  {
351  L1A_status = handle_missing_scans(L1A_file_ptr, gran_end_time,
352  &pre_SD_time, pcf_config->scan_rate,
353  &prev_scan_number, &ecs_gra_inv_met,
354  &l1a_specific_met, &gran_start_time_used,
355  gran_start_time, eng_data);
356 
357  if (L1A_status == MODIS_F_WRITE_ENG_DATA_FAIL) {
358  returnStatus = L1A_status;
360  "The engineering data could not be written successfully for\n"
361  "the missing scans at the end of the granule");
362  }
363  else if (L1A_status != MODIS_S_SUCCESS)
365  "The scan metadata could not be written successfully for\n"
366  "the missing scans at the end of the granule");
367  }
368  } /* gran_start_time < SD_start_time < gran_end_time */
369  else
370  last_granule_was_empty = TRUE;
371 
372  if(L1A_file_ptr)
373  {
374  const long int num_handles = 2L;
375 
376  L1A_status = write_global_metadata(L1A_file_ptr, md_handles,
377  &ecs_gra_inv_met, &l1a_specific_met);
378  if (L1A_status != MODIS_S_SUCCESS)
380  "The global metadata could not be written successfully for\n"
381  "granule number %s", ecs_gra_inv_met.parametervalue_1);
382  L1A_status = end_eng_data_access_to_file (L1A_file_ptr, eng_data);
383  if (L1A_status == FAIL) {
384  returnStatus = MODIS_F_PROCESSAGRANULE;
385  log_fmt_msg(MODIS_F_PROCESSAGRANULE, filefunc, "Either the "
386  "Discarded Packets vdata or the Engineering Data vdata could\n"
387  "not end its access to the L1A granule for granule number %s",
388  ecs_gra_inv_met.parametervalue_1);
389  }
390 
391  Mapi_R_Status = completeMODISfile(&L1A_file_ptr, md_handles,
392  ECS_attr_names, num_handles);
393  }
394  else
395  log_fmt_msg(MODIS_W_CREATE_L1A_GRANULE, filefunc, "%s %s",
396  ecs_gra_inv_met.rangebeginningdate,
397  ecs_gra_inv_met.rangebeginningtime);
398 
399  if (Mapi_R_Status != MAPIOK) {
400  returnStatus = MODIS_F_PROCESSAGRANULE;
402  "The L1A granule could not be closed for granule number %s",
403  ecs_gra_inv_met.parametervalue_1);
404  }
405  } /* MCF Initialization check */
406  print_stats();
407 
408  return returnStatus;
409 }
PGSt_SMF_status initialize_global_metadata(PGSt_double gran_start_time, PGSt_double gran_end_time, int nscans, PCF_CONFIG_t *pcf_config, MD_ECS_GRA_INV_MET_t *ecs_gra_inv_met, MD_L1A_SPECIFIC_MET_t *l1a_specific_met)
#define MODIS_E_INV_PKT_SEQ_FLAG
#define MODIS_E_HANDLE_MISSING_SCANS
PGSt_SMF_status create_L1A_granule(EN_VDATA_TYPE_t *eng_data, int16 nscans, MODFILE **L1A_file_ptr)
char rangebeginningdate[MD_TIMECODEADATELEN]
Definition: MD_metadata.h:162
#define ARCHIVED_METADATA
#define L(lambda, T)
Definition: PreprocessP.h:185
void compute_SD_start_time(PH_PACKET_HEADER_t *pkt_header, PGSt_double *SD_start_time)
#define MODIS_E_CREATE_L1A_GRANULE
PGSt_SMF_status write_scan(MODFILE *L1A_file_ptr, SC_SCAN_DATA_t *L1A_scan, MD_SCAN_MET_t *scan_meta, SC_PIXEL_QUALITY_DATA_t *pix_qual, FP_QUEUE_t failed_pkts, EN_VDATA_TYPE_t *eng_data)
Definition: write_scan.c:12
#define FAIL
Definition: ObpgReadGrid.h:18
#define FALSE
Definition: rice.h:164
#define NULL
Definition: decode_rs.h:63
void update_global_metadata(MD_SCAN_MET_t *scan_meta, MD_ECS_GRA_INV_MET_t *ecs_gra_inv_met, MD_L1A_SPECIFIC_MET_t *l1a_specific_met)
#define MODIS_E_CHECKSUM_NOT_VALID
#define TRUE
Definition: rice.h:165
#define MODIS_E_WRITE_GLOBAL_METADATA
#define INVENTORY_METADATA
#define MODIS_F_PROCESSAGRANULE
struct packet_stats stats
PGSt_SMF_status process_a_scan(int *scan_number, PGSt_IO_L0_Packet *pkt, PGSt_double *scan_rate, PGSt_double *scan_time, SC_SCAN_DATA_t *L1A_scan, MD_SCAN_MET_t *scan_meta, EN_VDATA_TYPE_t *eng_data, FP_QUEUE_t *failed_pkts, PH_PACKET_HEADER_t *pkt_header, SC_PIXEL_QUALITY_DATA_t *scan_pixel, PGSt_IO_L0_VirtualDataSet *L0_file)
PGSt_double scan_rate
Definition: PC_pcf_info.h:84
#define PC_MCF_PCF_ID
Definition: PC_pcf_info.h:68
char rangebeginningtime[MD_TIMECODEATIMELEN]
Definition: MD_metadata.h:163
#define MODIS_E_SCANCNT_NOT_VALID
PGSt_SMF_status process_a_granule(PGSt_IO_L0_VirtualDataSet L0_file, PGSt_double gran_start_time, PGSt_double gran_end_time, PCF_CONFIG_t *pcf_config, EN_VDATA_TYPE_t *eng_data, PH_PACKET_HEADER_t *pkt_header, PGSt_IO_L0_Packet *pkt, FP_QUEUE_t *failed_pkts)
void log_fmt_msg(PGSt_SMF_status code, const char *routine, const char *msg_fmt,...)
Definition: log_fmt_msg.c:6
#define MECS_CORE
Definition: Metadata.c:60
PGSt_SMF_status end_eng_data_access_to_file(MODFILE *L1A_file, EN_VDATA_TYPE_t *eng_data)
PGSt_SMF_status write_global_metadata(MODFILE *mfile, PGSt_MET_all_handles md_handles, MD_ECS_GRA_INV_MET_t *ecs_gra_inv_met, MD_L1A_SPECIFIC_MET_t *l1a_specific_met)
void reset_last_valid_scan(EN_VDATA_TYPE_t *eng_data)
#define MODIS_W_CREATE_L1A_GRANULE
#define MODIS_E_INV_PKT_TIME
#define MODIS_E_INITIALIZE_GLOBAL_MD
PGSt_SMF_status handle_missing_scans(MODFILE *L1A_file_ptr, PGSt_double SD_start_time, PGSt_double *pre_SD_time, PGSt_double scan_rate, int *scan_number, MD_ECS_GRA_INV_MET_t *ecs_gran_meta, MD_L1A_SPECIFIC_MET_t *L1A_specific_meta, PGSt_SMF_boolean *gran_start_time_used, PGSt_double gran_start_time, EN_VDATA_TYPE_t *eng_data)
#define MODIS_E_SCAN_PROCESS
#define MODIS_E_L1A
#define MODIS_E_WRITE_SCAN_FAIL
#define MODIS_F_UNABLE_TO_INIT_MCF
#define MODIS_F_WRITE_ENG_DATA_FAIL
#define MODIS_S_SUCCESS
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 MODIS_W_INV_PKTLEN
#define MODIS_W_TOO_MANY_SCANS
#define MODIS_M_PKT_NOT_IN_SCAN
void print_stats(void)
Definition: print_stats.c:6
#define MODIS_W_NO_MORE_PACKETS
#define MODIS_F_PKT_READ_FAILED
#define MODIS_E_NULL_POINTER
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
#define MODIS_E_INV_SECTOR