OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
L1B_Setup.c
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 File: L1B_Setup.c
4 
5 External functions:
6  L1B_Setup
7  Write_L1B_ScanMeta
8  Determine_Other_Missing_Scans
9 
10 Other functions:
11  Open_L1A_EV_SDS
12  Calculate_Earth_Sun_Distance
13  Calculate_RSB_Cal_Coeff
14  Init_L1B_ScaleOffset
15  Calculate_B26_B5_Correction
16  Open_W_L1B_Granule
17  Create_L1B_Swath
18  Write_Swath_Band_Number
19  Open_L1B_EV_SDS
20  Set_L1B_EV_SDS_Attrs
21  Set_Unit_Range_Fillvalue
22  Get_SDS_id
23  Set_SDS_Attributes
24  Create_Band_Subsetting_SDS
25  Copy_Geo_SDS
26  Scan_Meta_Cal
27  Calculate_DCR_Change
28  Init_QA_Parameters
29  Determine_Split_Scans
30  Get_Split_Scan_Indexes
31  Set_UI_ConvertToPercent_Attrs
32 
33 Note:
34  In the the various functions, there is a return statement after each
35  L1BErrorMsg function call. These are actually not necessary if the last
36  argument to L1BErrorMsg is "True". These returns make it easier to test
37  error out conditions (with SMF_ERROR used in UNIT_TEST_MODE_ONLY -- it does
38  not actually exit).
39 
40 Revision History:
41  $Log: L1B_Setup.c,v $
42  Revision 1.26 2015-03-17 10:48:11-04 xgeng
43  Fix the anomaly before and after the sector rotation due to the timing mismatch between the command performed and the status updated.
44 
45  Revision 1.25 2010-11-15 11:37:49-05 xgeng
46  Added a QA flag to identify the scan with both sides of PCLW electronics on.
47 
48  Revision 1.24 2008/11/18 16:25:15 xgeng
49  merge the branch for V6.0.1
50 
51  Revision 1.23.1.3 2008/06/02 15:38:38 xgeng
52  Initialize dead_subframe_pixels and num_dead_subframe_EV_data
53 
54 
55  Revision 1.23 2006/10/27 14:34:39 ltan
56  Removed the "Mixed" option from ScanType since L1A "Scan Type" never "Mixed". Some comments regarding Night mode handling corrected.
57 
58 
59  *****************************************************************************/
60 
61 #include <string.h>
62 #include <math.h>
63 /* Replace <malloc.h> with the standard head file <stdlib.h> for ANSI-C
64  compliance (Razor Issue 173). */
65 #include <stdlib.h>
66 #include <time.h>
67 #include "L1B_Setup.h"
68 #include "L1B_Tables.h"
69 #include "Metadata.h"
70 #include "HDF_Lib.h"
71 #include "PGS_PC.h"
72 #include "PGS_TD.h"
73 #include "PGS_Error_Codes.h"
74 #include "FNames.h"
75 #include "L1B_SetupP.h" /* local prototypes and structures */
76 
77 /*
78  * L1A_EV_SDS_NAME -- names of the earth-view SDSs in the L1A granule.
79  * Used in opening access to those SDSs.
80  */
82  "EV_250m", "EV_500m", "EV_1km_day", "EV_1km_night"
83 };
84 
85 /*-----------------------------------------
86  L1B file spec
87  (SI = Scaled Integer)
88  (UI = Uncertainty Index)
89  (SU = Samples Used)
90  L1B_EV_SDS_index_t Defines macros for the indices in the SDS name arrays.
91  L1B_EV_SDS_NAME Names of all earth-view SDSs in the L1B files.
92  L1B_EV_SDS_LONG_NAME Long names for the EV SDSs
93 -----------------------------------------*/
94 typedef enum
95 {
105 
107 {
108  "EV_250_RefSB", "EV_250_RefSB_Uncert_Indexes",
109  "EV_500_RefSB", "EV_500_RefSB_Uncert_Indexes",
110  "EV_1KM_RefSB", "EV_1KM_RefSB_Uncert_Indexes",
111  "EV_1KM_Emissive", "EV_1KM_Emissive_Uncert_Indexes",
112  "EV_250_Aggr500_RefSB", "EV_250_Aggr500_RefSB_Uncert_Indexes",
113  "EV_250_Aggr500_RefSB_Samples_Used",
114  "EV_250_Aggr1km_RefSB", "EV_250_Aggr1km_RefSB_Uncert_Indexes",
115  "EV_250_Aggr1km_RefSB_Samples_Used",
116  "EV_500_Aggr1km_RefSB", "EV_500_Aggr1km_RefSB_Uncert_Indexes",
117  "EV_500_Aggr1km_RefSB_Samples_Used"
118 };
119 
121 {
122  "Earth View 250M Reflective Solar Bands Scaled Integers",
123  "Earth View 250M Reflective Solar Bands Uncertainty Indexes",
124  "Earth View 500M Reflective Solar Bands Scaled Integers",
125  "Earth View 500M Reflective Solar Bands Uncertainty Indexes",
126  "Earth View 1KM Reflective Solar Bands Scaled Integers",
127  "Earth View 1KM Reflective Solar Bands Uncertainty Indexes",
128  "Earth View 1KM Emissive Bands Scaled Integers",
129  "Earth View 1KM Emissive Bands Uncertainty Indexes",
130  "Earth View 250M Aggregated 500M Reflective Solar Bands "
131  "Scaled Integers",
132  "Earth View 250M Aggregated 500M Reflective Solar Bands "
133  "Uncertainty Indexes",
134  "Earth View 250M Aggregated 500M Reflective Solar Bands "
135  "Number of Samples Used in Aggregation",
136  "Earth View 250M Aggregated 1km Reflective Solar Bands "
137  "Scaled Integers",
138  "Earth View 250M Aggregated 1km Reflective Solar Bands "
139  "Uncertainty Indexes",
140  "Earth View 250M Aggregated 1km Reflective Solar Bands "
141  "Number of Samples Used in Aggregation",
142  "Earth View 500M Aggregated 1km Reflective Solar Bands "
143  "Scaled Integers",
144  "Earth View 500M Aggregated 1km Reflective Solar Bands "
145  "Uncertainty Indexes",
146  "Earth View 500M Aggregated 1km Reflective Solar Bands "
147  "Number of Samples Used in Aggregation"
148 };
149 
150 /*
151  * Band_subsetting_names Names of the swath fields for bands subsetting SDSs.
152  * L1B_EV_DIM_NAME Dimension names. 1st column for band subsetting.
153  */
154 
156  "Band_250M",
157  "Band_500M",
158  "Band_1KM_RefSB",
159  "Band_1KM_Emissive"
160 };
161 
162 #define L1B_EV_SDS_RANK 3
163 
165  {"Band_250M", "40*nscans", "4*Max_EV_frames"},
166  {"Band_500M", "20*nscans", "2*Max_EV_frames"},
167  {"Band_1KM_RefSB", "10*nscans", "Max_EV_frames"},
168  {"Band_1KM_Emissive", "10*nscans", "Max_EV_frames"}
169 };
170 
171 /* Mapping offsets in scan and track directions:
172 */
174  {1, 0}, {0, 0}, {0, 0}, {0, 0}
175 };
176 
177 /* Mapping fractional offsets in scan and track directions:
178 */
180  {0.5, 0.0}, {0.5, 0.0}, {0.0, 0.0}, {0.0, 0.0}
181 };
182 
183  /*Neal's notation of geo_sds*/
184 
185  /* NOTE: only the name, src_name and type are currently being used
186  * in the code.
187  */
188 /* Enclosed the rows in the initializer of array GEO_SDS with braces for
189  ANSI-C compliance (Razor Issue 173). */
191 /* name src_name type units
192  valid_range[2] FillValue line_numbers frame_numbers scale_factor */
193  {"Latitude" , "Latitude" , DFNT_FLOAT32, "degrees" ,
194  {-90.,90.} , -999. , "3,8" , "3,8,13,...", 1.f} ,
195  {"Longitude" , "Longitude" , DFNT_FLOAT32, "degrees" ,
196  {-180., 180.} , -999. , "3,8" , "3,8,13,...", 1.f} ,
197  {"Height" , "Height" , DFNT_INT16 , "meters" ,
198  {-400,10000} , -32767 , "3,8" , "3,8,13,...", 1.f} ,
199  {"SensorZenith" , "SensorZenith" , DFNT_INT16 , "degrees" ,
200  {0,18000} , -32767 , "3,8" , "3,8,13,...", 0.01f},
201  {"SensorAzimuth", "SensorAzimuth", DFNT_INT16 , "degrees" ,
202  {-18000,18000} , -32767 , "3,8" , "3,8,13,...", 0.01f},
203  {"Range" , "Range" , DFNT_UINT16 , "meters" ,
204  {27000.,65535.}, 0 , "3,8" , "3,8,13,...", 25.f} ,
205  {"SolarZenith" , "SolarZenith" , DFNT_INT16 , "degrees" ,
206  {0,18000} , -32767 , "3,8" , "3,8,13,...", 0.01f},
207  {"SolarAzimuth" , "SolarAzimuth" , DFNT_INT16 , "degrees" ,
208  {-18000,18000} , -32767 , "3,8" , "3,8,13,...", 0.01f},
209  {"gflags" , "gflags" , DFNT_UINT8 , "" ,
210  {0.,0.} , 255 , "" , "" , 1.}
211 };
212 
213 extern int16 RFLAG;
214 extern int16 RSCL_FLAG;
215 
216 /******************************** FUNCTIONS *********************************/
217 
218 PGSt_SMF_status L1B_Setup (lookup_tables_t *tables,
219  L1A_granule_t *L1A_Gran,
220  L1B_granule_t *L1B_Gran,
221  L1A_Scan_t *L1A_Scan,
222  L1B_Scan_t *L1B_Scan,
223  QA_Data_t *QA,
224  L1B_Scan_Metadata_t *L1B_Scan_Meta,
225  boolean skip_night_hi_res)
226 /*
227 !C************************************************************************
228 !Description:
229  This routine performs a variety of functions in preparation for EV
230  calibration: (1) opens SDS access to each of the four L1A EV SDSs,
231  (2) calculates radiance and reflectance coefficients, populating the
232  "momos_t" structure, (3) sets the radiance, reflectance and emissive
233  scales and offsets for the L1B data products, (4) creates HDFEOS Swaths
234  and data fields for each L1B output file, (5) creates band-subsetting
235  SDSs, (6) opens SDS access for each of the EV SDSs in the L1B EV files
236  and create attributes for all, (7) reads subsampled SDSs from geolocation
237  file and write those data and their attributes into the 1km L1B file,
238  (8) assigns nadir-frame lattitude and longitude to members of L1B_Scan_Meta
239  to be written later in Write_L1B_ScanMeta, (9) assigns members of the
240  L1B_Scan_Meta to be written to the L1B EV files later in
241  Write_L1B_ScanMeta, and (10) initializes the QA values of total number of
242  pixels, number of valid pixels, number of saturated pixels, number of
243  missing pixels and pixels representing negative values below noise.
244 
245 !Input Parameters:
246  lookup_tables_t *tables
247  L1A_granule_t *L1A_Gran
248  boolean skip_night_hi_res True if and only if all scans are
249  night mode scans and writing of 250m
250  and 500m night mode granules has been
251  turned off
252 
253 !Output Parameters:
254  L1B_granule_t *L1B_Gran
255  L1A_Scan_t *L1A_Scan
256  L1B_Scan_t *L1B_Scan
257  QA_Data_t *QA
258 
259 !Revision History:
260  (continue at top of the file)
261 
262  Revision 02.15 March 26, 2003 Razor Issue #191
263  Added assignment of SWIR OOB correction band from LUT value
264  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
265 
266  Revision 02.14 March 26, 2003 Razor Issue #190
267  Added Call to Calculate_B26_B5_Correction
268  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
269 
270  Revision 02.13 November 15, 2001 Razor Issue #169
271  Changed call to Open_W_L1B_Granule to include boolean skip_night_hi_res
272  Added boolean skip_night_hi_res to input parameters to L1B_Setup
273  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
274 
275  Revision 02.12 Feb 10, 1999
276  Moved call to function Write_L1B_ScanMeta to L1B (main).
277  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
278 
279  Revision 02.11 Feb. 1999
280  The following L1A_Gran members are now read in Read_L1A_OBCEng:
281  Number of Day mode scans, EV start time and Scan Type. This eliminates
282  the need for Get_EV_Start_Time and Read_L1A_ScanMeta.
283  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
284 
285  Revision 02.10 April 1998
286  Added scan_meta_cal().
287  Zhenying Gu(zgu@gscmail.gsfc.nasa.gov)
288 
289  Revision 02.10 April 1998
290  Added the Get_EV_Start_Time() and Calculate_MOMOs() calls.
291  David Catozzi (cato@ltpmail.gsfc.nasa.gov)
292 
293  Revision 02.00 March 1997
294  Exluded everything associated with LookupTables & PreprocessData;
295  changed processing metadata one scan a time to all scans at once.
296  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
297 
298  Revision 01.01 1996/04/05
299  Updated to match Version 1 Design Document
300  John Hannon(hannon@highwire.gsfc.nasa.gov)
301  Joan Baden (baden@highwire.gsfc.nasa.gov)
302 
303  Revision 01.00 1993
304  Initial development
305  Geir Kvaran(geir@highwire.gsfc.nasa.gov)
306 
307 !Team-unique Header:
308 
309 !References and Credits:
310  This software is developed by the MODIS Characterization Support
311  Team (MCST)for the National Aeronautics and Space Administration,
312  Goddard Space Flight Center, under contract NAS5-32373.
313 
314  HDF portions developed at the National Center for Supercomputing
315  Applications at the University of Illinois at Urbana-Champaign.
316 
317 !Design Notes:
318 
319 !END********************************************************************
320 */
321 {
322  PGSt_SMF_status returnStatus = MODIS_S_OK;
323  char *location = "L1B_Setup"; /* L1B location */
324  SWIR_correction_tables_t *swir_tables =
325  &tables->refl.SWIR_correction_tables;
326 
327  /*
328  * Assign L1B_Scan->band_X based on reflective LUT value
329  * Assignment is as night band index for use with L1A data.
330  */
331  /* MODIS_BAND20_INDEX = 21 NUM_BANDS = 38 MODIS_BAND26_INDEX = 27 */
332 
333 
334  if ((swir_tables->SWIR_corr_sending_band >= MODIS_BAND20_INDEX - 1 &&
335  swir_tables->SWIR_corr_sending_band < MODIS_BAND26_INDEX - 1) ||
336  (swir_tables->SWIR_corr_sending_band > MODIS_BAND26_INDEX - 1 &&
337  swir_tables->SWIR_corr_sending_band < NUM_BANDS - 1))
338  L1B_Scan->band_X = swir_tables->SWIR_corr_sending_band - MODIS_BAND20_INDEX + 1;
339  else
340  {
341  returnStatus = MODIS_F_OUT_OF_RANGE;
342  L1BErrorMsg(location, returnStatus,
343  "Band to use for SWIR OOB Correction is out of range.",
345  "This is most likely due to an invalid LUT file.", True);
346  return returnStatus;
347  }
348 
349  /*
350  * Assign L1B_Gran->num_scans & L1B_Gran->num_day_scans
351  */
352  L1B_Gran->num_scans = L1A_Gran->num_scans;
353  L1B_Gran->num_day_scans = L1A_Gran->num_day_scans;
354 
355 
356  returnStatus = Open_L1A_EV_SDS (L1A_Gran, L1A_Scan);
357  if (returnStatus != MODIS_S_OK)
358  SMF_ERROR(returnStatus,"Open_L1A_EV_SDS() in L1B_Setup");
359 
360  returnStatus = Calculate_Earth_Sun_Distance(L1A_Gran,
361  &L1B_Gran->Earth_Sun_Dist);
362  if (returnStatus != MODIS_S_OK)
363  L1BErrorMsg(location, returnStatus, NULL,
364  "Calculate_Earth_Sun_Distance",
365  0, NULL, True);
366 
367  returnStatus = Calculate_RSB_Cal_Coeff(tables,
368  L1B_Gran->Earth_Sun_Dist,
369  &L1B_Gran->RSB_Cal_Coeff);
370  if (returnStatus != MODIS_S_OK)
371  SMF_ERROR(returnStatus,"Calculate_RSB_Cal_Coeff() in L1B_Setup");
372 
373  returnStatus = Init_L1B_ScaleOffset(&L1B_Gran->SO,
374  &L1B_Gran->RSB_Cal_Coeff,
375  L1B_Gran->Earth_Sun_Dist, tables);
376  if (returnStatus != MODIS_S_OK)
377  SMF_ERROR(returnStatus,"Init_L1B_ScaleOffset() in L1B_Setup");
378 
379  /*
380  * Scale the Band 5 to Band 26 crosstalk correction coefficients by the
381  * ratio of the Band 5 to Band 26 scales and store the result in the
382  * L1B_Gran->RSB_Cal_Coeff structure.
383  */
384 
385  returnStatus = Calculate_B26_B5_Correction
386  (tables->refl.B26_B5_Corr,
387  L1B_Gran->b26_fr_b5_scaled_corr,
388  &L1B_Gran->SO);
389 
390  if (returnStatus != MODIS_S_OK)
391  SMF_ERROR (returnStatus,
392  "Calculate_B26_B5_Correction() in L1B_Setup");
393 
394  returnStatus = Open_W_L1B_Granule (tables, L1B_Gran, L1B_Scan,
395  skip_night_hi_res);
396  if (returnStatus != MODIS_S_OK)
397  SMF_ERROR(returnStatus, "Open_W_L1B_Granule() in L1B_Setup");
398 
399  returnStatus = Copy_Geo_SDS (L1B_Gran, skip_night_hi_res);
400  if (returnStatus != MODIS_S_OK)
401  SMF_ERROR(returnStatus, "Copy_Geo_SDS() in L1B_Setup");
402 
403  returnStatus = Scan_Meta_Cal(tables,
404  L1A_Gran, L1B_Gran, L1B_Scan_Meta, QA);
405  if (returnStatus != MODIS_S_OK)
406  SMF_ERROR(returnStatus, "Scan_Meta_Cal() in L1B_Setup");
407 
408  returnStatus = Calculate_DCR_Change(L1A_Gran, QA, L1B_Scan_Meta);
409  if(returnStatus != MODIS_S_OK)
410  SMF_ERROR(returnStatus, "Calculate_DCR_Change() in Gran_Meta_Cal()");
411 
412  returnStatus = Init_QA_Parameters (L1A_Gran, L1B_Gran, QA);
413  if (returnStatus != MODIS_S_OK)
414  SMF_ERROR(returnStatus, "Init_QA_Parameters() in L1B_Setup");
415 
416  return(MODIS_S_OK);
417 }
418 
419 PGSt_SMF_status Open_L1A_EV_SDS (L1A_granule_t *L1A_Gran,
420  L1A_Scan_t *L1A_Scan)
421 /*
422 !C****************************************************************************
423 !Description: Create SDS access to each of the four L1A EV SDSs. The sds_ids
424  are stored in L1A_Scan. These SDS accesses are not terminated
425  until after all processing has been complete.
426 
427 !Input Parameters:
428  L1A_Gran (->sd_id) SD file access ID -- already opened.
429 
430 !Output Parameters:
431  L1A_Scan (->sds_id[R]) SDS access IDs for each EV SDS in L1A file.
432 
433 !Revision History:
434  (continue at top of the file)
435 
436  Revision 02.10 March 1997
437  Modified to match the change in L1A_Scan_t.
438  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
439 
440  Revision 02.00 1996/07/02
441  Version 2, initial redesign
442  Neal Devine(neal.devine@gsfc.nasa.gov)
443 
444  Revision 01.01 1996/04/05
445  Update to match Version 1 Design Document
446  John Hannon(hannon@highwire.gsfc.nasa.gov)
447  Neal Devine(neal.devine@gsfc.nasa.gov)
448  Joan Baden (baden@highwire.gsfc.nasa.gov)
449 
450  Revision 01.00 1993
451  Initial development
452  Geir E. Kvaran(geir@highwire.gsfc.nasa.gov)
453 
454 !Team-unique Header:
455  This software is developed by the MODIS Characterization Support
456  Team (MCST)for the National Aeronautics and Space Administration,
457  Goddard Space Flight Center, under contract NAS5-32373.
458 
459 !References and Credits:
460  HDF portions developed at the National Center for Supercomputing
461  Applications at the University of Illinois at Urbana-Champaign.
462 
463 !Design Notes:
464 
465 !END**************************************************************************
466 */
467 {
468  PGSt_SMF_status returnStatus = MODIS_S_OK;
469  char *location = "Open_L1A_EV_SDS";
470  int16 R = 0;
471  int32 sds_index = 0;
472  char errmsg[256];
473 
474  for (R = 0; R < NUM_L1A_RESOLUTIONS; R++)
475  {
476  if ((RFLAG & (1 << R)) != 0) continue;
477 
478  sds_index = SDnametoindex (L1A_Gran->sd_id, L1A_EV_SDS_NAME[R]);
479  if (sds_index == FAIL)
480  {
481  sprintf(errmsg, "Could not get SDS index of \"%s\".",
482  L1A_EV_SDS_NAME[R]);
483  returnStatus = MODIS_F_READ_ERROR;
484  L1BErrorMsg(location, returnStatus, errmsg,
485  "SDnametoindex", FIRST_L1A_GRANULE, NULL, True);
486  return returnStatus;
487  }
488 
489  L1A_Scan->sds_id[R] = SDselect (L1A_Gran->sd_id, sds_index);
490  if (L1A_Scan->sds_id[R] == FAIL)
491  {
492  sprintf(errmsg, "Could not get SDS ID for \"%s\".",
493  L1A_EV_SDS_NAME[R]);
494  returnStatus = MODIS_F_HDF_ERROR;
495  L1BErrorMsg(location, returnStatus, errmsg,
496  "SDselect", FIRST_L1A_GRANULE, NULL, True);
497  return returnStatus;
498  }
499  }
500 
501  return(MODIS_S_OK);
502 }
503 
504 PGSt_SMF_status Calculate_Earth_Sun_Distance( L1A_granule_t *L1A_Gran,
505  float32 *Earth_Sun_Dist)
506 /*
507 !C****************************************************************************
508 !Description: This function calculates the Earth Sun distance based on the TAI
509  time.
510 
511 !Input Parameters:
512  L1A_granule_t *L1A_Gran contains number of scans in middle
513  L1A granule and EV start time.
514 
515 !Output Parameters:
516  float32 * Earth_Sun_Dist to store Earth Sun distance
517 
518 !Revision History:
519  $Log: L1B_Setup.c,v $
520  Revision 1.26 2015-03-17 10:48:11-04 xgeng
521  Fix the anomaly before and after the sector rotation due to the timing mismatch between the command performed and the status updated.
522 
523  Revision 1.25 2010-11-15 11:37:49-05 xgeng
524  Added a QA flag to identify the scan with both sides of PCLW electronics on.
525 
526  Revision 1.24 2008/11/18 16:25:15 xgeng
527  merge the branch for V6.0.1
528 
529  Revision 1.23.1.3 2008/06/02 15:38:38 xgeng
530  Initialize dead_subframe_pixels and num_dead_subframe_EV_data
531 
532  (continue at top of the file)
533 
534  Revision 1.20 2005/03/01 20:34:31 ltan
535  Code changes to correct the HDFEOS dimension mapping offset for QKM data and
536  1KM geolocation from 0 to 1.
537 
538  Revision 1.19 2005/01/18 21:57:36 ltan
539  Added new file attributes prefixed with HDFEOS_FractionalOffset
540 
541 
542  Revision 1.02 June 3, 2003 Razor Issue #193
543  The calculation of the Earth-Sun distance was amended after it was
544  discovered that the memo on which it is based has a typographical
545  error; the "+" in front of the second order term should be a "-".
546  Comments were also clarified.
547  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
548 
549  Revision 01.01 November 7, 2001
550  Change use of PI to PGS_PI (Razor issue #168); clean up some spelling
551  and grammar
552  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
553 
554  Revision 01.00 Nov. 04, 1999
555  Initial development.
556  Zhenying Gu (zgu@mcst.gsfc.nasa.gov)
557 
558 !Team-unique Header:
559  This software is developed by the MODIS Characterization Support
560  Team (MCST)for the National Aeronautics and Space Administration,
561  Goddard Space Flight Center, under contract NAS5-32373.
562 
563 !References and Credits:
564  HDF portions developed at the National Center for Supercomputing
565  Applications at the University of Illinois at Urbana-Champaign.
566 
567 !Design Notes:
568 
569 !END**************************************************************************
570 */
571 {
572  PGSt_SMF_status returnStatus = MODIS_S_OK;
573  char *location = "Calculate_Earth_Sun_Distance";
574  float64 TAItime;
575  float64 EMA;
576  int32 middle_scan;
577 
578  if (L1A_Gran == NULL || Earth_Sun_Dist == NULL)
580  "Input parameter is NULL pointer.", NULL, 0, NULL, True);
581 
582  /*
583  * The formula calculating earth sun distance uses one TAI time for
584  * the granule. The memo referred to below does not specify with time
585  * to use. Logically, it would be near the middle of the granule.
586  */
587 
588 
589  middle_scan = L1A_Gran->num_scans/2;
590  TAItime = L1A_Gran->EVStartTime_TAIsecond[middle_scan];
591 
592 /*
593  * Calculate EMA using the expression for m appropriate for use with secTAI93
594  * (TAItime) input. This equation appears on the last page of the memo, "The
595  * Earth-Sun Distance Correction for the MODIS Reflective Product", M0612.
596  * The additional modulo 360 equation in this reference can be ignored as it
597  * will not affect the answer.
598  */
599 
600  EMA = -2.15802 + 0.0000114074107 * TAItime -
601  1.56645046e-23 * TAItime * TAItime;
602 
603 /*
604  * Calculate Earth-Sun distance using equation (2) with e = 0.167075 from the
605  * memo "The Earth-Sun Distance Correction for the MODIS Reflective Product",
606  * M0612.
607  */
608 
609  *Earth_Sun_Dist = 1.0001396 - 0.0167068 * cos((double)(EMA * PGS_PI/180.0))
610  - 0.0001396 * cos((double)(2 * EMA * PGS_PI/180.0));
611 
612  return returnStatus;
613 }
614 
616  float32 E_S_Dist,
617  RSB_Cal_Coeff_t *RSB_Cal_Coeff)
618 /*
619 !C****************************************************************************
620 !Description:
621  This function calculates the reflective calibration coefficient m1_des_sq,
622  which is the values of LUT m1 multiplied by the square of the Earth-Sun
623  distance for the current granule, and it's maximum values. It also calculates
624  minimum values of R*, from the time-dependent LUT quantities. The calculated
625  values are stored in the RSB_Cal_Coeff_t structure for use in Reflective_Cal
626  and Init_L1B_ScaleOffset.
627 
628 !Input Parameters:
629  lookup_tables_t * tables Contains structure members for m1 and R*
630  time-dependent LUTs and dead detector list.
631  float32 E_S_Dist earth-sun distance
632 
633 !Output Parameters:
634  RSB_Cal_Coeff_t * RSB_Cal_Coeff Contains the structure members to be filled
635  in this array: m1_des_sq, m1_des_sq_max,
636  R_star, R_star_min.
637 
638 !Revision History:
639  (continue at top of the file)
640 
641  Revision 01.01 Nov, 1999
642  Zhenying Gu (zgu@mcst.gsfc.nasa.gov)
643 
644  Revision 01.00 May, 1999
645  See SDF, Initial development.
646  Zhenying Gu (zgu@mcst.gsfc.nasa.gov) and Jim Rogers (rogers@mcst.gsfc.nasa.gov)
647 
648 !Team-unique Header:
649  This software is developed by the MODIS Characterization Support
650  Team (MCST)for the National Aeronautics and Space Administration,
651  Goddard Space Flight Center, under contract NAS5-32373.
652 
653 !References and Credits:
654  HDF portions developed at the National Center for Supercomputing
655  Applications at the University of Illinois at Urbana-Champaign.
656 
657 !Design Notes:
658 
659 !END**************************************************************************
660 */
661 
662 {
663  PGSt_SMF_status returnStatus = MODIS_S_OK;
664  int16 band, det, sample, mirr_side;
665  int16 det_490; /* index for all detectors */
666  int16 num_detectors[NUM_REFLECTIVE_BANDS] =
667  {40, 40, 20, 20, 20, 20, 20, 10,
668  10, 10, 10, 10, 10, 10, 10, 10,
669  10, 10, 10, 10, 10, 10};
670 
671  int16 num_subsamps [NUM_REFLECTIVE_BANDS] =
672  {4, 4, 2, 2, 2, 2, 2, 1, 1, 1, 1,
673  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
674 
675  int32 i, n;
676  float32 *work;
677  work = malloc(MAX_DETECTORS_PER_BAND *
680  sizeof(float32));
681  float32 m1;
682 
683  /* Calculate m1 and m1 max */
684 
685  det_490 = 0;
686  for (band = 0; band < NUM_REFLECTIVE_BANDS; band++ )
687  {
688  n = 0;
689 
690  /*
691  * (NUM_REFLECTIVE_DETECTORS - 10) is the index of the first
692  * detector in band 20. MODIS_BAND26_INDEX_AT_RES equals the
693  * difference of band index between band 26 and band 20, which
694  * is 6. Every band has 10 detectors for 1km bands.
695  */
696 
697  if (band == NUM_REFLECTIVE_BANDS - 1) /* band 26 */
698  det_490 = (NUM_REFLECTIVE_DETECTORS - 10) +
700 
701  for ( det = 0; det < num_detectors[band]; det++, det_490++ )
702  {
703  for ( sample = 0; sample < num_subsamps[band]; sample++ )
704  {
705  for ( mirr_side = 0; mirr_side < NUM_MIRROR_SIDES; mirr_side++ )
706  {
707  m1 = tables->refl.m1[band][det][sample][mirr_side];
708  RSB_Cal_Coeff->m1_des_sq[band][det][sample][mirr_side] =
709  m1 * E_S_Dist * E_S_Dist;
710 
711  if (tables->QA.common_QA_tables.dead_detector[det_490] != 1)
712  {
713  work[n] = RSB_Cal_Coeff->m1_des_sq[band][det][sample][mirr_side];
714  n++;
715  }
716  } /* end loop through mirr_side */
717  } /* end loop through sample */
718  } /* end loop through det */
719 
720 
721  RSB_Cal_Coeff->m1_des_sq_max[band] = work[0];
722  for (i = 0; i < n; i++)
723  if (RSB_Cal_Coeff->m1_des_sq_max[band] < work[i])
724  RSB_Cal_Coeff->m1_des_sq_max[band] = work[i];
725 
726  if (RSB_Cal_Coeff->m1_des_sq_max[band] == 0 || n == 0)
728  "invalid m1 maximum value in Calculate_RSB_Cal_Coeff()");
729  }/* end loop through band */
730 
731  free(work);
732 
733  return (returnStatus);
734 }
735 
737  RSB_Cal_Coeff_t *RSB_Cal_Coeff,
738  float E_S_Dist,
740 /*
741 !C**********************************************************************
742 !Description: This routine sets the radiance, reflectance and emissive scales
743  and offsets for the L1B data products.
744 
745 !Input Parameters:
746  lookup_tables_t *tables contains L_Min, L_Max, dn_star_Min
747  dn_star_Max
748  RSB_Cal_Coeff_t *RSB_Cal_Coeff contains m1_des_sq_max and
749  R_star_min
750  float E_S_Dist Earth-sun distance in AU
751 
752 !Output Parameters:
753  L1B_ScaleOffset_t *SO contains all scales and offsets
754  for reflectance, radiance and count
755 
756 !Revision History:
757  (continue at top of the file)
758 
759  Revision 02.13 August 12, 1999
760  Used L_Max, L_Min Luts
761  Zhenying Gu (zgu@mcst.gsfc.nasa.gov)
762 
763  Revision 02.12 May 18, 1999
764  Changed to match RSB calibration coefficient algorithm change.
765  Jim Rogers (rogers@mcst.gsfc.nasa.gov) and Zhenying Gu (zgu@mcst.gsfc.nasa.gov)
766 
767  Revision 02.11 Feb 16, 1999
768  Removed outdated and unused variable DN_Star_Max_Band1_7.
769  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
770 
771  Revision 02.10 Apr 6, 1998
772  Commented out the Reflective Scale and Offset expressions,
773  awaiting the V2.1 algorithm.
774  David Catozzi (cato@ltpmail.gsfc.nasa.gov)
775 
776  Revision 02.00 Dec. 1996.
777  Modified Scale and Offset expressions according to V2 spec.
778  Zhidong Hao (hao@acrobat.gsfc.nasa.gov)
779 
780  Revision 01.01 1996/04/05
781  Updated to match Version 1 Design Document.
782  Neal Devine(neal.devine@gsfc.nasa.gov)
783  John Hannon(hannon@highwire.gsfc.nasa.gov)
784 
785  Revision 01.00 1995/12/05
786  Initial development
787  Shi_Yue Qiu(syqiu@ltpmail.gsfc.nasa.gov)
788 
789 !Team-unique Header:
790 
791 !References and Credits:
792  This software is developed by the MODIS Characterization Support
793  Team (MCST)for the National Aeronautics and Space Administration,
794  Goddard Space Flight Center, under contract NAS5-32373.
795 
796  HDF portions developed at the National Center for Supercomputing
797  Applications at the University of Illinois at Urbana-Champaign.
798 
799 !Design Notes:
800  Reflectance does not contain the Sun_Adj factor which varies from slightly
801  less than 1 to 1.03something. See comment below.
802 
803  Replaced `SIL_t *E_Sun' by `refl_tables_t *refl_tables' and
804  removed Sun_Adj as an input parameter, as it is not needed here.
805  --- zh 11/21/96
806 
807 !END********************************************************************
808 */
809 {
810  int16 B = 0;
811  int16 B_emiss = 0;
812  float32 E_sun_over_pi_B[NUM_REFLECTIVE_BANDS];
813  int16 D, D_330;
814 
815  /*set dn_star_Max, dn_star_Min*/
816  for (B = 0; B < NUM_REFLECTIVE_BANDS; B++)
817  {
818  SO->dn_star_Max[B] = tables->refl.dn_star_Max[B];
819  SO->dn_star_Min[B] = tables->refl.dn_star_Min[B];
820  if (SO->dn_star_Max[B] <= SO->dn_star_Min[B])
822  "LUT dn_star_Max <= dn_star_Min, Init_L1B_ScaleOffset");
823  }
824 
825  /*set Emiss radiance scale/offset*/
826  B_emiss = 0;
827  for (B = 0; B < L1A_BANDS_AT_RES[INDEX_1000M_EMISS]; B++)
828  {
829  if (B == MODIS_BAND26_INDEX_AT_RES)
830  continue;
831  SO->rad_scale_Emiss[B_emiss] =
832  (tables->emiss.L_Max[B_emiss] -
833  tables->emiss.L_Min[B_emiss]) / DN15_SAT;
834  SO->rad_offset_Emiss[B_emiss] =
835  -DN15_SAT * tables->emiss.L_Min[B_emiss]/
836  (tables->emiss.L_Max[B_emiss] -
837  tables->emiss.L_Min[B_emiss]);
838  B_emiss++;
839  }
840 
841  /*
842  * Calculate the mean E_sun_over_pi for each band.
843  */
844 
845  D_330 = 0;
846  for (B = 0; B < NUM_250M_BANDS; B++)
847  {
848  E_sun_over_pi_B[B] = 0;
849  for (D = 0; D < DETECTORS_PER_250M_BAND; D++, D_330++)
850  E_sun_over_pi_B[B] += tables->refl.E_sun_over_pi[D_330];
851  E_sun_over_pi_B[B] /= (float32) DETECTORS_PER_250M_BAND;
852  }
853  for ( ; B < (NUM_250M_BANDS+NUM_500M_BANDS); B++)
854  {
855  E_sun_over_pi_B[B] = 0;
856  for (D = 0; D < DETECTORS_PER_500M_BAND; D++, D_330++)
857  E_sun_over_pi_B[B] += tables->refl.E_sun_over_pi[D_330];
858  E_sun_over_pi_B[B] /= (float32) DETECTORS_PER_500M_BAND;
859  }
860  for ( ; B < NUM_REFLECTIVE_BANDS; B++)
861  {
862  E_sun_over_pi_B[B] = 0;
863  for (D = 0; D < DETECTORS_PER_1KM_BAND; D++, D_330++)
864  E_sun_over_pi_B[B] += tables->refl.E_sun_over_pi[D_330];
865  E_sun_over_pi_B[B] /= (float32) DETECTORS_PER_1KM_BAND;
866  }
867 
868  /*set RefSB radiance, reflectance and counts scale/offset*/
869 
870  for (B = 0; B < NUM_REFLECTIVE_BANDS; B++)
871  {
872  SO->counts_scale_RefSB[B] =
873  (SO->dn_star_Max[B] - SO->dn_star_Min[B])/DN15_SAT;
874  SO->counts_offset_RefSB[B] =
875  -DN15_SAT * SO->dn_star_Min[B] /
876  (SO->dn_star_Max[B] - SO->dn_star_Min[B]);
877 
878  SO->refl_scale_RefSB[B] =
879  RSB_Cal_Coeff->m1_des_sq_max[B] * SO->counts_scale_RefSB[B];
880  SO->refl_offset_RefSB[B] =
881  SO->counts_offset_RefSB[B];
882 
883  SO->rad_scale_RefSB[B] =
884  (E_sun_over_pi_B[B] / (E_S_Dist * E_S_Dist))
885  * SO->refl_scale_RefSB[B];
886  SO->rad_offset_RefSB[B] =
887  SO->counts_offset_RefSB[B];
888  }
889 
890  return(MODIS_S_OK);
891 }
892 
893 PGSt_SMF_status Open_W_L1B_Granule
895  L1B_granule_t *L1B_Gran,
896  L1B_Scan_t *L1B_Scan,
897  boolean skip_night_hi_res)
898 /*
899 !C**********************************************************************
900 !Description: Create HDFEOS Swaths and data fields for each L1B output file.
901  Also get SD & V HDF interface ids. The band-subsetting data
902  fields (one-dimensional arrays) are implemented as Vdata while
903  the other fields are implemented as SDSs. Separate band-
904  subsetting SDSs are also created. Open SDS access for each of
905  the EV SDSs in the L1B EV files and create attributes for all.
906  SDS access will remain open until after all scan-by-scan
907  processing is complete.
908 
909 !Input Parameters:
910  lookup_tables_t *tables
911  L1B_granule_t *L1B_Gran
912  L1B_Scan_t *L1B_Scan
913  boolean skip_night_hi_res True if and only if all scans are
914  night mode scans and writing of 250m
915  and 500m night mode granules has been
916  turned off
917 
918 !Output Parameters:
919  L1B_Gran (->sw_f_id[]) Swath file ID for each of the L1B EV files.
920  L1B_Scan_t *L1B_Scan
921 
922 !Revision History:
923  (continue at top of the file)
924 
925  Revision 02.01, November 14, 2001, Razor Issue #169
926  Added input parameter skip_night_hi_res and changed logic so that
927  250m and 500m data are not written when granule has no day mode
928  scans and runtime parameter Write_Night_Mode_HiRes_Data is False.
929  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
930 
931  Revision 02.01, Dec 5, 2000, Razor issue 141.
932  Added "tables" to argument list, add to arg list of "Set_L1B_EV_SDS_Attrs"
933  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
934 
935  Revision 02.00 Feb 16, 1999
936  Split Write_Band_Subsetting_SDS and its subordinate function
937  Write_Subsetting_SDS into two functions: Set_L1B_EV_SDS_Attrs and
938  Create_Band_Subsetting_SDS for clarity.
939  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
940 
941  Revision 02.00 March 1997
942  Modified to match version 2 design.
943  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
944 
945  Revision 01.01 1996/04/05
946  Update to match Version 1 Design Document
947  John Hannon(hannon@highwire.gsfc.nasa.gov)
948  Joan Baden (baden@highwire.gsfc.nasa.gov)
949 
950  Revision 01.00 1993
951  Initial development
952  Geir E. Kvaran(geir@highwire.gsfc.nasa.gov)
953 
954 !Team-unique Header:
955  This software is developed by the MODIS Characterization Support
956  Team (MCST)for the National Aeronautics and Space Administration,
957  Goddard Space Flight Center, under contract NAS5-32373.
958 
959 !References and Credits:
960  HDF portions developed at the National Center for Supercomputing
961  Applications at the University of Illinois at Urbana-Champaign.
962 
963 !Design Notes:
964  1. The PGS_PC logical reference IDs are defined in Fnames.h. These are
965  consecutive integers for the EV files and are indexed as such below.
966 
967 !END********************************************************************
968 */
969 {
970  PGSt_SMF_status returnStatus = MODIS_S_OK;
971  PGSt_PC_Logical logical_id = 0;
972  PGSt_integer version = 1;
973  char fname[PGSd_PC_FILE_PATH_MAX];
974  int16 f = 0;
975  char *location = "Open_W_L1B_Granule";
976  int16 start_output_res = INDEX_L1B_250m;
977 
978  /*
979  * If we are in night mode and we do not wish to write 250m and 500m data
980  * sets, start with the 1KM output data sets.
981  */
982 
983  if (skip_night_hi_res == True)
984  {
985  start_output_res = INDEX_L1B_1km;
986  logical_id = L1B_EV_1000M_FILE;
987  }
988  else
989  {
990  start_output_res = INDEX_L1B_250m;
991  logical_id = L1B_EV_250M_FILE;
992  }
993 
994  for (f = start_output_res; f < NUM_L1B_EV_FILES; f++, logical_id++)
995  {
996  version = 1;
997 
998  if (PGS_PC_GetReference(logical_id, &version, fname) != PGS_S_SUCCESS)
999  {
1000  returnStatus = MODIS_F_FILE_NOT_FOUND;
1001  L1BErrorMsg(location, returnStatus,
1002  "Could not retrieve file name from PCF.",
1003  "PGS_PC_GetReference", logical_id, NULL, True);
1004  return returnStatus;
1005  }
1006 
1007  if ((L1B_Gran->sw_f_id[f] = SWopen(fname, DFACC_CREATE)) == FAIL)
1008  {
1009  returnStatus = MODIS_F_FILE_NOT_CREATED;
1010  L1BErrorMsg(location, returnStatus,
1011  "Could not create output granule.",
1012  "SWopen", logical_id, NULL, True);
1013  return returnStatus;
1014  }
1015  }
1016 
1017  returnStatus = Create_L1B_Swath (L1B_Gran, skip_night_hi_res);
1018  if (returnStatus != MODIS_S_OK)
1019  {
1020  L1BErrorMsg(location, returnStatus, NULL,
1021  "Create_L1B_Swath", 0, NULL, True);
1022  return returnStatus;
1023  }
1024 
1025  returnStatus = Open_L1B_EV_SDS (L1B_Gran,
1026  L1B_Scan,
1027  skip_night_hi_res);
1028  if (returnStatus != MODIS_S_OK)
1029  {
1030  L1BErrorMsg(location, returnStatus, NULL,
1031  "Open_L1B_EV_SDS", 0, NULL, True);
1032  return returnStatus;
1033  }
1034 
1035  returnStatus = Set_L1B_EV_SDS_Attrs (tables,
1036  L1B_Gran,
1037  L1B_Scan,
1038  skip_night_hi_res);
1039  if (returnStatus != MODIS_S_OK)
1040  {
1041  L1BErrorMsg(location, returnStatus, NULL,
1042  "Set_L1B_EV_SDS_Attrs", 0, NULL, True);
1043  return returnStatus;
1044  }
1045 
1046  returnStatus = Create_Band_Subsetting_SDS (L1B_Gran,
1047  skip_night_hi_res);
1048  if (returnStatus != MODIS_S_OK)
1049  {
1050  L1BErrorMsg(location, returnStatus, NULL,
1051  "Create_Band_Subsetting_SDS", 0, NULL, True);
1052  return returnStatus;
1053  }
1054 
1055  return(MODIS_S_OK);
1056 }
1057 
1058 
1059 PGSt_SMF_status Create_L1B_Swath (L1B_granule_t *L1B_Gran,
1060  boolean skip_night_hi_res)
1061 /*
1062 !C****************************************************************
1063 !Description: Create HDFEOS Swaths and data fields for each L1B output file.
1064  Also get SD & V HDF interface ids. The band-subsetting data
1065  fields (one-dimensional arrays) are implemented as Vdata while
1066  the other data fields (for EV data) are implemented as SDSs.
1067  The values for the band-subsetting fields are assigned here.
1068  For the EV data, after fixing fields here, accesses will be
1069  opened to the SDSs in another routine and used normally
1070  thereafter.
1071 
1072 !Input Parameters:
1073  L1B_Gran (->sw_f_id[]) HDF-EOS swath file IDs for each EV file.
1074  boolean skip_night_hi_res True if and only if all scans are
1075  night mode scans and writing of 250m
1076  and 500m night mode granules has been
1077  turned off
1078 
1079 
1080 !Output Parameters:
1081  L1B_Gran (->v_id[]) Vdata interface IDs for each EV file.
1082  L1B_Gran (->sd_id[]) SD interface IDs for each EV file.
1083 
1084 !Revision History:
1085  (continue at top of the file)
1086 
1087  Revision 02.12, January 12, 2005 (Razor Issue #202)
1088  Added new file attribute prefixed with HDFEOS_FractionalOffset for each
1089  dimension of the swath in every MODIS product file.
1090  Liqin Tan SAIC/GSO (ltan@saicmodis.com)
1091 
1092  Revision 02.11 November 15, 2001 Razor Issue #169
1093  Added boolean skip_night_hi_res to input parameters and altered logic so that
1094  if skip_night_hi_res is True, output data sets for 250m and 500m resolution
1095  data are not created.
1096  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
1097 
1098  Revision 02.10 May 13, 1999
1099  Added band 26 section
1100  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
1101 
1102  Revision 02.01 Feb 10, 1999
1103  In defining the data fields for band subsetting, changed to use the global
1104  variables Band_subsetting_names and L1B_EV_DIM_NAME defined at the top of
1105  the file.
1106  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
1107 
1108  Revision 02.00 April 1997
1109  Modified to match changes in data structures.
1110  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
1111 
1112  Revision 01.00 1997/02/21
1113  Initial development
1114  Neal Devine (neal.devine@gsfc.nasa.gov)
1115 
1116 !Team-unique Header:
1117  This software is developed by the MODIS Characterization Support
1118  Team (MCST)for the National Aeronautics and Space Administration,
1119  Goddard Space Flight Center, under contract NAS5-32373.
1120 
1121 !References and Credits:
1122  HDF portions developed at the National Center for Supercomputing
1123  Applications at the University of Illinois at Urbana-Champaign.
1124 
1125 !Design Notes:
1126  Attributes not yet implemented.
1127  The opening of target SDS's is lengthy enough to warrant a separate sub
1128  function.
1129 
1130 !END********************************************************************
1131 */
1132 {
1133  PGSt_SMF_status returnStatus;
1134  char *location = "Create_L1B_Swath";
1135  int16 file_index = 0; /*file index*/
1136  int16 R = 0; /*L1A resolution index*/
1137  int16 isds = 0; /*sds_index*/
1138  int32 track_dim = 0;
1139  int32 frame_dim = 0;
1140  int16 BG_index = 0; /*Band_Group_index*/
1141  int16 num_BGs = 0; /*num_band_groups*/
1142  int32 sw_id[NUM_L1B_EV_FILES] = {0, 0, 0};
1143  intn hdf_return = 0;
1144  int32 evfile_luns[NUM_L1B_EV_FILES] = {
1148  };
1149  int16 start_output_res = INDEX_L1B_250m;
1150 #define MAX_ATTR_NAME_SIZE2 72
1151  char attr_name_buffer[MAX_ATTR_NAME_SIZE2];
1152 
1153 /*------------------------------------------------------------------------*/
1154 #define SW_DEF_EV_SDS(SI_name, UI_name, str) \
1155 if (SWdefdatafield(sw_id[file_index], SI_name, str, DFNT_UINT16, \
1156  HDFE_NOMERGE) == FAIL) \
1157  { \
1158  returnStatus = MODIS_F_HDF_ERROR; \
1159  L1BErrorMsg(location, returnStatus, SI_name, \
1160  "SWdefdatafield", evfile_luns[file_index], NULL, True); \
1161  return returnStatus; \
1162  } \
1163 if (SWdefdatafield(sw_id[file_index], UI_name, str, DFNT_UINT8, \
1164  HDFE_NOMERGE) == FAIL) \
1165  { \
1166  returnStatus = MODIS_F_HDF_ERROR; \
1167  L1BErrorMsg(location, returnStatus, UI_name, \
1168  "SWdefdatafield", evfile_luns[file_index], NULL, True); \
1169  return returnStatus; \
1170  }
1171 /*------------------------------------------------------------------------*/
1172 #define SW_DEF_EV_Aggr_SDS(SI_name, UI_name, SU_name, str) \
1173 SW_DEF_EV_SDS(SI_name,UI_name,str); \
1174 if (SWdefdatafield(sw_id[file_index], SU_name, str, DFNT_INT8, \
1175  HDFE_NOMERGE) == FAIL) \
1176  { \
1177  returnStatus = MODIS_F_HDF_ERROR; \
1178  L1BErrorMsg(location, returnStatus, SU_name, \
1179  "SWdefdatafield", evfile_luns[file_index], NULL, True); \
1180  return returnStatus; \
1181  }
1182 /*------------------------------------------------------------------------*/
1183 
1184  /*
1185  * If we are in night mode and we do not wish to write 250m and 500m data
1186  * sets, start with the 1KM output data sets.
1187  */
1188 
1189  if (skip_night_hi_res == True)
1190  start_output_res = INDEX_L1B_1km;
1191  else
1192  start_output_res = INDEX_L1B_250m;
1193 
1194  /* create EV swaths */
1195  for (file_index = start_output_res;
1196  file_index < NUM_L1B_EV_FILES; file_index++)
1197  {
1198  /* The V2 Delivery Guide suggests to use "MOD_SWATH_"
1199  Here we use the name in the file spec, "MODIS_SWATH_"
1200  */
1201  sw_id[file_index] = SWcreate(L1B_Gran->sw_f_id[file_index],
1202  "MODIS_SWATH_Type_L1B");
1203  if (sw_id[file_index] == FAIL)
1204  {
1205  returnStatus = MODIS_F_HDF_ERROR;
1206  L1BErrorMsg(location, returnStatus, NULL,
1207  "SWcreate", evfile_luns[file_index], NULL, True);
1208  return returnStatus;
1209  }
1210 
1211  /* Get equivalent HDF v_id & sd_id and assign to L1B_Gran members.
1212  */
1213  if (EHidinfo(L1B_Gran->sw_f_id[file_index],
1214  &L1B_Gran->v_id[file_index],
1215  &L1B_Gran->sd_id[file_index]) == FAIL)
1216  {
1217  returnStatus = MODIS_F_HDF_ERROR;
1218  L1BErrorMsg(location, returnStatus, NULL,
1219  "EHidinfo", evfile_luns[file_index], NULL, True);
1220  return returnStatus;
1221  }
1222 
1223  /* define band_dim and data field
1224  */
1225  num_BGs = file_index + 1;
1226  if (file_index == INDEX_L1B_1km) num_BGs++;
1227 
1228  for (BG_index = 0; BG_index < num_BGs; BG_index++)
1229  {
1230  R = BG_index; /* R = [0], [0, 1], [0, 1, 2, 3] */
1231  hdf_return = SWdefdim(sw_id[file_index], L1B_EV_DIM_NAME[R][0],
1232  (int32)L1B_BANDS_AT_RES[R]);
1233  if (hdf_return == FAIL)
1234  {
1235  returnStatus = MODIS_F_HDF_ERROR;
1236  L1BErrorMsg(location, returnStatus, L1B_EV_DIM_NAME[R][0],
1237  "SWdefdim", evfile_luns[file_index], NULL, True);
1238  return returnStatus;
1239  }
1240  }
1241 
1242  /* The Offset and Increment entries in the HDF-EOS metadata need to be
1243  set appropriately to preserve the geolocation accuracy when the data
1244  stored has a different resolution than the geolocation (see "MODIS
1245  Science Software Delivery Guide" -- 9/23/2004). Because HDF-EOS does
1246  not support fractional offset values, it doesn't properly handle
1247  sub-pixel offsets in Swath files. In order to better document the
1248  true offset, file global attributes of fractional offset are added
1249  to each files (the addition to the "integer" offset provided in the
1250  HDF-EOS metadata).
1251  */
1252  sprintf(attr_name_buffer,
1253  "HDFEOS_FractionalOffset_%s_MODIS_SWATH_Type_L1B",
1254  L1B_EV_DIM_NAME[num_BGs-1][1]);
1255 
1256  if(SDsetattr(L1B_Gran->sd_id[file_index],
1257  attr_name_buffer, DFNT_FLOAT32, 1,
1258  (VOIDP)&L1B_EV_DIM_FRAC_OFFSET[num_BGs-1][0]) == FAIL)
1259  {
1260  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
1261  "Could not write L1B EV file dimensional attribute.",
1262  "SDsetattr", evfile_luns[file_index], NULL, True);
1263  }
1264 
1265  sprintf(attr_name_buffer,
1266  "HDFEOS_FractionalOffset_%s_MODIS_SWATH_Type_L1B",
1267  L1B_EV_DIM_NAME[num_BGs-1][2]);
1268 
1269  if(SDsetattr(L1B_Gran->sd_id[file_index],
1270  attr_name_buffer, DFNT_FLOAT32, 1,
1271  (VOIDP)&L1B_EV_DIM_FRAC_OFFSET[num_BGs-1][1]) == FAIL)
1272  {
1273  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
1274  "Could not write L1B EV file dimensional attribute.",
1275  "SDsetattr", evfile_luns[file_index], NULL, True);
1276  }
1277 
1278  /* define track & frame dims
1279  */
1280  R = file_index;
1281 
1282  track_dim = DETECT_PER_BAND_AT_RES[R] * L1B_Gran->num_scans;
1283  frame_dim = BAND_RATIO_AT_RES[R] * EV_1km_FRAMES;
1284 
1285  if (SWdefdim(sw_id[file_index], L1B_EV_DIM_NAME[R][1],
1286  track_dim) == FAIL)
1287  {
1288  returnStatus = MODIS_F_HDF_ERROR;
1289  L1BErrorMsg(location, returnStatus, L1B_EV_DIM_NAME[R][1],
1290  "SWdefdim", evfile_luns[file_index], NULL, True);
1291  return returnStatus;
1292  }
1293 
1294  if (SWdefdim(sw_id[file_index], L1B_EV_DIM_NAME[R][2],
1295  frame_dim) == FAIL)
1296  {
1297  returnStatus = MODIS_F_HDF_ERROR;
1298  L1BErrorMsg(location, returnStatus, L1B_EV_DIM_NAME[R][2],
1299  "SWdefdim", evfile_luns[file_index], NULL, True);
1300  return returnStatus;
1301  }
1302 
1303  /* define geo track & frame dims, and geo/data fields, and dimmaps
1304  */
1305  if (file_index == INDEX_L1B_1km)
1306  {
1307  if (SWdefdim(sw_id[file_index], "2*nscans",
1308  (int32)(2*L1B_Gran->num_scans)) == FAIL)
1309  {
1310  returnStatus = MODIS_F_HDF_ERROR;
1311  L1BErrorMsg(location, returnStatus, "2*nscans",
1312  "SWdefdim", evfile_luns[file_index], NULL, True);
1313  return returnStatus;
1314  }
1315 
1316  if (SWdefdim(sw_id[file_index], "1KM_geo_dim",
1317  (int32)(EV_1km_FRAMES/5 + 1)) == FAIL)
1318  {
1319  returnStatus = MODIS_F_HDF_ERROR;
1320  L1BErrorMsg(location, returnStatus, "1KM_geo_dim",
1321  "SWdefdim", evfile_luns[file_index], NULL, True);
1322  return returnStatus;
1323  }
1324 
1325  if (SWdefgeofield(sw_id[file_index], "Latitude",
1326  "2*nscans,1KM_geo_dim", DFNT_FLOAT32,
1327  HDFE_NOMERGE) == FAIL)
1328  {
1329  returnStatus = MODIS_F_HDF_ERROR;
1330  L1BErrorMsg(location, returnStatus, "Latitude",
1331  "SWdefgeofield", evfile_luns[file_index],
1332  NULL, True);
1333  return returnStatus;
1334  }
1335 
1336  if (SWdefgeofield(sw_id[file_index], "Longitude",
1337  "2*nscans,1KM_geo_dim", DFNT_FLOAT32,
1338  HDFE_NOMERGE) == FAIL)
1339  {
1340  returnStatus = MODIS_F_HDF_ERROR;
1341  L1BErrorMsg(location, returnStatus, "Longitude",
1342  "SWdefgeofield", evfile_luns[file_index],
1343  NULL, True);
1344  return returnStatus;
1345  }
1346 
1349  "Band_1KM_RefSB,10*nscans,Max_EV_frames");
1350 
1353  "Band_1KM_Emissive,10*nscans,Max_EV_frames");
1354 
1358  "Band_250M,10*nscans,Max_EV_frames");
1359 
1363  "Band_500M,10*nscans,Max_EV_frames");
1364 
1365  for (isds = INDEX_HEIGHT; isds < NUM_GEO_SDS; isds++)
1366  {
1367  if (SWdefdatafield(sw_id[file_index], GEO_SDS[isds].name,
1368  "2*nscans,1KM_geo_dim",
1369  GEO_SDS[isds].type,HDFE_NOMERGE) == FAIL)
1370  {
1371  returnStatus = MODIS_F_HDF_ERROR;
1372  L1BErrorMsg(location, returnStatus, GEO_SDS[isds].name,
1373  "SWdefdatafield", evfile_luns[file_index], NULL, True);
1374  return returnStatus;
1375  }
1376  }
1377 
1378  if (SWdefdimmap(sw_id[file_index], "2*nscans", "10*nscans",
1379  GEO_OFFSET, GEO_STRIDE) == FAIL)
1380  {
1381  returnStatus = MODIS_F_HDF_ERROR;
1382  L1BErrorMsg(location, returnStatus, "2*nscans to 10*nscans",
1383  "SWdefdimmap", evfile_luns[file_index], NULL, True);
1384  return returnStatus;
1385  }
1386 
1387  if (SWdefdimmap(sw_id[file_index], "1KM_geo_dim", "Max_EV_frames",
1388  GEO_OFFSET, GEO_STRIDE) == FAIL)
1389  {
1390  returnStatus = MODIS_F_HDF_ERROR;
1391  L1BErrorMsg(location, returnStatus, "1KM_geo_dim to Max_EV_frames",
1392  "SWdefdimmap", evfile_luns[file_index], NULL, True);
1393  return returnStatus;
1394  }
1395 
1396  /* define data fields for band_subsetting
1397  */
1398 
1399  for (R = 0; R < 4; R++) {
1400  if (SWdefdatafield(sw_id[file_index],
1402  L1B_EV_DIM_NAME[R][0],
1403  DFNT_FLOAT32, HDFE_NOMERGE) == FAIL)
1404  {
1405  returnStatus = MODIS_F_HDF_ERROR;
1406  L1BErrorMsg(location, returnStatus, Band_subsetting_names[R],
1407  "SWdefdatafield", evfile_luns[file_index], NULL, True);
1408  return returnStatus;
1409  }
1410  }
1411 
1412  }
1413  else
1414  {
1415  if (SWdefdim(sw_id[file_index], "10*nscans",
1416  (int32)(10*L1B_Gran->num_scans)) == FAIL)
1417  {
1418  returnStatus = MODIS_F_HDF_ERROR;
1419  L1BErrorMsg(location, returnStatus, "10*nscans",
1420  "SWdefdim", evfile_luns[file_index], NULL, True);
1421  return returnStatus;
1422  }
1423 
1424  if (SWdefdim(sw_id[file_index], "Max_EV_frames",
1425  (int32)EV_1km_FRAMES) == FAIL)
1426  {
1427  returnStatus = MODIS_F_HDF_ERROR;
1428  L1BErrorMsg(location, returnStatus, "Max_EV_frames",
1429  "SWdefdim", evfile_luns[file_index], NULL, True);
1430  return returnStatus;
1431  }
1432 
1433  if (SWdefgeofield(sw_id[file_index], "Latitude",
1434  "10*nscans,Max_EV_frames", DFNT_FLOAT32,
1435  HDFE_NOMERGE) == FAIL)
1436  {
1437  returnStatus = MODIS_F_HDF_ERROR;
1438  L1BErrorMsg(location, returnStatus, "Latitude",
1439  "SWdefgeofield", evfile_luns[file_index], NULL, True);
1440  return returnStatus;
1441  }
1442 
1443  if (SWdefgeofield(sw_id[file_index], "Longitude",
1444  "10*nscans,Max_EV_frames", DFNT_FLOAT32,
1445  HDFE_NOMERGE) == FAIL)
1446  {
1447  returnStatus = MODIS_F_HDF_ERROR;
1448  L1BErrorMsg(location, returnStatus, "Longitude",
1449  "SWdefgeofield", evfile_luns[file_index], NULL, True);
1450  return returnStatus;
1451  }
1452 
1453  switch(file_index)
1454  {
1455  case INDEX_L1B_250m:
1458  "Band_250M,40*nscans,4*Max_EV_frames");
1459 
1460  if (SWdefdatafield(sw_id[file_index],
1463  DFNT_FLOAT32, HDFE_NOMERGE) == FAIL)
1464  {
1465  returnStatus = MODIS_F_HDF_ERROR;
1466  L1BErrorMsg(location, returnStatus,
1468  "SWdefdatafield",
1469  evfile_luns[file_index], NULL, True);
1470  return returnStatus;
1471  }
1472 
1473  break;
1474 
1475  case INDEX_L1B_500m:
1478  "Band_500M,20*nscans,2*Max_EV_frames");
1479 
1483  "Band_250M,20*nscans,2*Max_EV_frames");
1484 
1485  for (R = 0; R < 2; R++) {
1486  if (SWdefdatafield(sw_id[file_index],
1488  L1B_EV_DIM_NAME[R][0],
1489  DFNT_FLOAT32, HDFE_NOMERGE) == FAIL)
1490  {
1491  returnStatus = MODIS_F_HDF_ERROR;
1492  L1BErrorMsg(location, returnStatus,
1494  "SWdefdatafield",
1495  evfile_luns[file_index], NULL, True);
1496  return returnStatus;
1497  }
1498  }
1499 
1500  }
1501 
1502  R = file_index;
1503 
1504  if (SWdefdimmap(sw_id[file_index],
1505  "10*nscans",
1506  L1B_EV_DIM_NAME[R][1],
1508  {
1509  returnStatus = MODIS_F_HDF_ERROR;
1510  L1BErrorMsg(location, returnStatus,
1511  "L1B_EV_DIM_NAME[R][1] to 10*nscans",
1512  "SWdefdimmap",
1513  evfile_luns[file_index], NULL, True);
1514  return returnStatus;
1515  }
1516 
1517  if (SWdefdimmap(sw_id[file_index],
1518  "Max_EV_frames",
1519  L1B_EV_DIM_NAME[R][2],
1521  {
1522  returnStatus = MODIS_F_HDF_ERROR;
1523  L1BErrorMsg(location, returnStatus,
1524  "L1B_EV_DIM_NAME[R][2] to 10*nscans",
1525  "SWdefdimmap",
1526  evfile_luns[file_index], NULL, True);
1527  return returnStatus;
1528  }
1529  }
1530 
1531 /************************* Begin Band 26 Section **************************/
1532 #ifdef WRITE_BAND_26_SDS
1533  if (file_index == INDEX_L1B_1km)
1534  {
1535  /*
1536  * Create the band 26 SI and UI SDSs as part of the HDF-EOS
1537  * swath. These are 2D SDSs, using the dimensions indicated.
1538  * These are only created for the L1B 1km EV product.
1539  */
1542  "10*nscans,Max_EV_frames");
1543  }
1544 #endif /* WRITE_BAND_26_SDS */
1545 /************************** End Band 26 Section ***************************/
1546 
1547  }
1548 
1549  for (file_index = start_output_res;
1550  file_index < NUM_L1B_EV_FILES; file_index++)
1551  {
1552 
1553  /* detach from swath (this should be done prior to accessing members
1554  * to ensure that fields are set properly).
1555  */
1556 
1557  if (SWdetach(sw_id[file_index]) == FAIL)
1558  {
1559  returnStatus = MODIS_F_HDF_ERROR;
1560  L1BErrorMsg(location, returnStatus, NULL,
1561  "SWdetach", evfile_luns[file_index], NULL, True);
1562  return returnStatus;
1563  }
1564 
1565  /* Write the band-subsetting fields numerical values to file.
1566  */
1567 
1568  returnStatus = Write_Swath_Band_Number(file_index, L1B_Gran);
1569  if (returnStatus != MODIS_S_OK)
1570  {
1571  L1BErrorMsg(location, returnStatus, NULL,
1572  "Write_Swath_Band_Number",
1573  evfile_luns[file_index], NULL, True);
1574  return returnStatus;
1575  }
1576  }
1577 
1578  return(MODIS_S_OK);
1579 }
1580 
1581 PGSt_SMF_status Write_Swath_Band_Number(int32 file_index,
1582  L1B_granule_t *L1B_Gran)
1583 /*
1584 !C**********************************************************************
1585 !Description: For one EV file, this function writes the numerical values
1586  of the band-subsetting SDS data fields.
1587 
1588 !Input Parameters:
1589  file_index index of the EV file that we will write data to.
1590  L1B_Gran (->sw_f_id[]) array of swath file IDs for the EV files.
1591 
1592 !Output Parameters:
1593 
1594 !Revision History:
1595  (continue at top of the file)
1596 
1597  Revision 01.00 1998
1598  Initial development
1599  Zhenying Gu(zgu@ltpmail.gsfc.nasa.gov)
1600 
1601 !Team-unique Header:
1602  This software is developed by the MODIS Characterization Support
1603  Team (MCST)for the National Aeronautics and Space Administration,
1604  Goddard Space Flight Center, under contract NAS5-32373.
1605 
1606 !References and Credits:
1607  HDF portions developed at the National Center for Supercomputing
1608  Applications at the University of Illinois at Urbana-Champaign.
1609 
1610 !Design Notes:
1611 
1612 !END********************************************************************
1613 */
1614 {
1615  PGSt_SMF_status returnStatus = MODIS_S_OK;
1616  char *location = "Write_Swath_Band_Number";
1617 
1618  int32 swId;
1619  float32 data_250m[2] = {1, 2};
1620  float32 data_500m[5] = {3, 4, 5, 6, 7};
1621  float32 data_1km_refl[15] =
1622  {8, 9, 10, 11, 12, 13, 13.5, 14, 14.5,
1623  15, 16, 17, 18, 19, 26};
1624  float32 data_1km_emiss[16] =
1625  {20, 21, 22, 23, 24, 25, 27, 28, 29,
1626  30, 31, 32, 33, 34, 35, 36};
1627  int32 evfile_luns[NUM_L1B_EV_FILES] =
1628  {
1632  };
1633 
1634  swId = SWattach(L1B_Gran->sw_f_id[file_index], "MODIS_SWATH_Type_L1B");
1635  if (swId == FAIL)
1636  {
1637  returnStatus = MODIS_F_HDF_ERROR;
1638  L1BErrorMsg(location, returnStatus, NULL,
1639  "SWattach", evfile_luns[file_index], NULL, True);
1640  return returnStatus;
1641  }
1642 
1643  switch(file_index)
1644  {
1645  case INDEX_L1B_1km:
1646  if (SWwritefield(swId, "Band_250M", (int32*)NULL, (int32*)NULL,
1647  (int32*)NULL, (VOIDP)data_250m) == FAIL)
1648  {
1649  returnStatus = MODIS_F_WRITE_ERROR;
1650  L1BErrorMsg(location, returnStatus, "Band_250M",
1651  "SWwritefield", evfile_luns[file_index], NULL, True);
1652  return returnStatus;
1653  }
1654 
1655  if (SWwritefield(swId, "Band_500M", (int32*)NULL, (int32*)NULL,
1656  (int32*)NULL, (VOIDP)data_500m) == FAIL)
1657  {
1658  returnStatus = MODIS_F_WRITE_ERROR;
1659  L1BErrorMsg(location, returnStatus, "Band_500M",
1660  "SWwritefield", evfile_luns[file_index], NULL, True);
1661  return returnStatus;
1662  }
1663 
1664  if (SWwritefield(swId, "Band_1KM_RefSB", (int32*)NULL, (int32*)NULL,
1665  (int32*)NULL, (VOIDP)data_1km_refl)== FAIL)
1666  {
1667  returnStatus = MODIS_F_WRITE_ERROR;
1668  L1BErrorMsg(location, returnStatus, "Band_1KM_RefSB",
1669  "SWwritefield", evfile_luns[file_index], NULL, True);
1670  return returnStatus;
1671  }
1672 
1673  if (SWwritefield(swId, "Band_1KM_Emissive", (int32*)NULL, (int32*)NULL,
1674  (int32*)NULL, (VOIDP)data_1km_emiss)== FAIL)
1675  {
1676  returnStatus = MODIS_F_WRITE_ERROR;
1677  L1BErrorMsg(location, returnStatus, "Band_1KM_Emissive",
1678  "SWwritefield", evfile_luns[file_index], NULL, True);
1679  return returnStatus;
1680  }
1681  break;
1682 
1683  case INDEX_L1B_500m:
1684  if (SWwritefield(swId, "Band_250M", (int32*)NULL, (int32*)NULL,
1685  (int32*)NULL, (VOIDP)data_250m) == FAIL)
1686  {
1687  returnStatus = MODIS_F_WRITE_ERROR;
1688  L1BErrorMsg(location, returnStatus, "Band_250M",
1689  "SWwritefield", evfile_luns[file_index], NULL, True);
1690  return returnStatus;
1691  }
1692 
1693  if (SWwritefield(swId, "Band_500M", (int32*)NULL, (int32*)NULL,
1694  (int32*)NULL, (VOIDP)data_500m) == FAIL)
1695  {
1696  returnStatus = MODIS_F_WRITE_ERROR;
1697  L1BErrorMsg(location, returnStatus, "Band_500M",
1698  "SWwritefield", evfile_luns[file_index], NULL, True);
1699  return returnStatus;
1700  }
1701  break;
1702 
1703  case INDEX_L1B_250m:
1704  if (SWwritefield(swId, "Band_250M", (int32*)NULL, (int32*)NULL,
1705  (int32*)NULL, (VOIDP)data_250m) == FAIL)
1706  {
1707  returnStatus = MODIS_F_WRITE_ERROR;
1708  L1BErrorMsg(location, returnStatus, "Band_250M",
1709  "SWwritefield", evfile_luns[file_index], NULL, True);
1710  return returnStatus;
1711  }
1712  break;
1713  }
1714 
1715  if (SWdetach(swId) == FAIL)
1716  {
1717  returnStatus = MODIS_F_HDF_ERROR;
1718  L1BErrorMsg(location, returnStatus, NULL,
1719  "SWdetach", evfile_luns[file_index], NULL, True);
1720  return returnStatus;
1721  }
1722 
1723  return(MODIS_S_OK);
1724 }
1725 
1726 PGSt_SMF_status Open_L1B_EV_SDS (L1B_granule_t *L1B_Gran,
1727  L1B_Scan_t *L1B_Scan,
1728  boolean skip_night_hi_res)
1729 /*
1730 !C****************************************************************
1731 !Description: Given the L1B file swaths and their EV data fields created
1732  earlier (implemented as SDSs), open SDS access for each of the
1733  SDSs. Additionally, set the "long name" attribute for each SDS.
1734  SDS access will remain open until after all scan-by-scan
1735  processing is complete.
1736 
1737 !Input Parameters:
1738  L1B_Gran (->sd_id) SD file IDs for each of the L1B EV files.
1739  boolean skip_night_hi_res True if and only if all scans are
1740  night mode scans and writing of 250m
1741  and 500m night mode granules has been
1742  turned off
1743 !Output Parameters:
1744  L1B_Scan SDS access ID members:
1745  SI_sds_id[]
1746  EV_250m_Aggr500m_RefSB_sds_id
1747  EV_250m_Aggr1km_RefSB_sds_id
1748  EV_500m_Aggr1km_RefSB_sds_id
1749  UI_sds_id[]
1750  EV_250m_Aggr500m_RefSB_UI_sds_id
1751  EV_250m_Aggr1km_RefSB_UI_sds_id
1752  EV_500m_Aggr1km_RefSB_UI_sds_id
1753  EV_250m_Aggr500m_RefSB_SU_sds_id
1754  EV_250m_Aggr1km_RefSB_SU_sds_id
1755  EV_500m_Aggr1km_RefSB_SU_sds_id
1756 
1757 !Revision History:
1758  (continue at top of the file)
1759 
1760  Revision 03.11 November 15, 2001 Razor Issue #169
1761  Added boolean skip_night_hi_res to input parameters and altered logic so that
1762  if skip_night_hi_res is True, output data sets for 250m and 500m resolution
1763  data are not created.
1764  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
1765 
1766  Revision 03.10 May 1999
1767  Added Band 26 SDS.
1768  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
1769 
1770  Revision 03.00 April 1997
1771  Modified to match changes in data structures.
1772  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
1773 
1774  Revision 02.0 1996/06/28
1775  Version 2, initial redesign
1776  Neal Devine(neal.devine@gsfc.nasa.gov)
1777 
1778  Revision 01.02 1996/04/05
1779  Update to match Version 1 Design Document
1780  Neal Devine(neal.devine@gsfc.nasa.gov)
1781  John Hannon(hannon@highwire.gsfc.nasa.gov)
1782 
1783  Revision 01.00 1993
1784  Initial development
1785  Geir E. Kvaran(geir@highwire.gsfc.nasa.gov)
1786 
1787 !Team-unique Header:
1788  This software is developed by the MODIS Characterization Support
1789  Team (MCST)for the National Aeronautics and Space Administration,
1790  Goddard Space Flight Center, under contract NAS5-32373.
1791 
1792 !References and Credits:
1793  HDF portions developed at the National Center for Supercomputing
1794  Applications at the University of Illinois at Urbana-Champaign.
1795 
1796 !Design Notes:
1797 
1798 !END********************************************************************
1799 */
1800 {
1801  PGSt_SMF_status returnStatus;
1802  char *location = "Open_L1B_EV_SDS";
1803  int32 sds_index = 0;
1804  int16 file_index = 0;
1805  int32 evfile_luns[NUM_L1B_EV_FILES] = {
1809  };
1810 
1811  int32 scaled_250[2] = {13,16};
1812  int32 scaled_500[2] = {10,12};
1813 
1814  /*
1815  * ----------------------------------------------------------------------
1816  * This macro opens SDS access to a pair of L1B EV SDS's (Scaled_Integer
1817  * and Uncert_Index) and sets the long-name attribute for each SDS.
1818  * Input: sd_id, SI_name, UI_name, SI_longName, UI_longName
1819  * Output: SI_id, UI_id
1820  * ----------------------------------------------------------------------
1821  */
1822 #define CREATE_EV_SDS(sd_id, SI_name, UI_name, SI_longName, UI_longName, \
1823  SI_id,UI_id) \
1824 if((sds_index = SDnametoindex(sd_id, SI_name)) == FAIL) \
1825  { \
1826  returnStatus = MODIS_F_HDF_ERROR; \
1827  L1BErrorMsg(location, returnStatus, SI_name, \
1828  "SDnametoindex", evfile_luns[file_index], NULL, True); \
1829  return returnStatus; \
1830  } \
1831 if((SI_id = SDselect(sd_id, sds_index)) == FAIL) \
1832  { \
1833  returnStatus = MODIS_F_HDF_ERROR; \
1834  L1BErrorMsg(location, returnStatus, SI_name, \
1835  "SDselect", evfile_luns[file_index], NULL, True); \
1836  return returnStatus; \
1837  } \
1838 if(SDsetattr(SI_id, "long_name", DFNT_CHAR8,(int32)strlen(SI_longName), \
1839  SI_longName) == FAIL) \
1840  { \
1841  returnStatus = MODIS_F_HDF_ERROR; \
1842  L1BErrorMsg(location, returnStatus, SI_name, \
1843  "SDsetattr", evfile_luns[file_index], "long_name", True); \
1844  return returnStatus; \
1845  } \
1846 if((sds_index = SDnametoindex(sd_id, UI_name)) == FAIL) \
1847  { \
1848  returnStatus = MODIS_F_HDF_ERROR; \
1849  L1BErrorMsg(location, returnStatus, UI_name, \
1850  "SDnametoindex", evfile_luns[file_index], NULL, True); \
1851  return returnStatus; \
1852  } \
1853 if((UI_id = SDselect(sd_id, sds_index)) == FAIL) \
1854  { \
1855  returnStatus = MODIS_F_HDF_ERROR; \
1856  L1BErrorMsg(location, returnStatus, UI_name, \
1857  "SDselect", evfile_luns[file_index], NULL, True); \
1858  return returnStatus; \
1859  } \
1860 if(SDsetattr(UI_id, "long_name", DFNT_CHAR8,(int32)strlen(UI_longName), \
1861  UI_longName) == FAIL) \
1862  { \
1863  returnStatus = MODIS_F_HDF_ERROR; \
1864  L1BErrorMsg(location, returnStatus, UI_name, \
1865  "SDsetattr", evfile_luns[file_index], "long_name", True); \
1866  return returnStatus; \
1867  }
1868 
1869  /*
1870  * -----------------------------------------------------------------------
1871  * This macro opens SDS access to a set of three L1B EV_Aggr SDS's
1872  * (SI, UI and SU) and sets the long-name attribute for each SDS
1873  * Input: sd_id, SI_name, UI_name, SU_name, SI_LName, UI_LName, SU_LName
1874  * Output: SI_id, UI_id, SU_id
1875  * -----------------------------------------------------------------------
1876  */
1877 #define CREATE_EV_Aggr_SDS(sd_id, SI_name, UI_name, SU_name, SI_LName, \
1878  UI_LName, SU_LName, SI_id, UI_id, SU_id) \
1879 CREATE_EV_SDS(sd_id, SI_name, UI_name, SI_LName, UI_LName, SI_id, UI_id); \
1880 if((sds_index = SDnametoindex(sd_id, SU_name)) == FAIL) \
1881  { \
1882  returnStatus = MODIS_F_HDF_ERROR; \
1883  L1BErrorMsg(location, returnStatus, SU_name, \
1884  "SDnametoindex", evfile_luns[file_index], NULL, True); \
1885  return returnStatus; \
1886  } \
1887 if((SU_id = SDselect(sd_id, sds_index)) == FAIL) \
1888  { \
1889  returnStatus = MODIS_F_HDF_ERROR; \
1890  L1BErrorMsg(location, returnStatus, SU_name, \
1891  "SDselect", evfile_luns[file_index], NULL, True); \
1892  return returnStatus; \
1893  } \
1894 if(SDsetattr(SU_id, "long_name", DFNT_CHAR8,(int32)strlen(SU_LName), \
1895  SU_LName) == FAIL) \
1896  { \
1897  returnStatus = MODIS_F_HDF_ERROR; \
1898  L1BErrorMsg(location, returnStatus, SU_name, \
1899  "SDsetattr", evfile_luns[file_index], "long_name", True); \
1900  return returnStatus; \
1901  }
1902 /*--------------------------------------------------------------------*/
1903 
1904  /* Create 250m and 500m files only when skip_night_hi_res is False. */
1905 
1906  if (skip_night_hi_res == False)
1907  {
1908  /*250m file*/
1909  file_index = INDEX_L1B_250m;
1910 
1911  CREATE_EV_SDS (L1B_Gran->sd_id[INDEX_L1B_250m],
1916  L1B_Scan->SI_sds_id[INDEX_250M],
1917  L1B_Scan->UI_sds_id[INDEX_250M]);
1918 
1919  /*500m file*/
1920  file_index = INDEX_L1B_500m;
1921  CREATE_EV_SDS (L1B_Gran->sd_id[INDEX_L1B_500m],
1926  L1B_Scan->SI_sds_id[INDEX_500M],
1927  L1B_Scan->UI_sds_id[INDEX_500M]);
1928 
1939  }
1940 
1941  /*1km file*/
1942  file_index = INDEX_L1B_1km;
1943  CREATE_EV_SDS (L1B_Gran->sd_id[INDEX_L1B_1km],
1948  L1B_Scan->SI_sds_id[INDEX_1000M_REFL],
1949  L1B_Scan->UI_sds_id[INDEX_1000M_REFL]);
1950 
1958  L1B_Scan->EV_250m_Aggr1km_RefSB_sds_id,
1961 
1969  L1B_Scan->EV_500m_Aggr1km_RefSB_sds_id,
1972 
1973  CREATE_EV_SDS (L1B_Gran->sd_id[INDEX_L1B_1km],
1978  L1B_Scan->SI_sds_id[INDEX_1000M_EMISS],
1979  L1B_Scan->UI_sds_id[INDEX_1000M_EMISS]);
1980 
1981  if ((RSCL_FLAG & 1) == 1)
1982  {
1983  if (SDsetattr(L1B_Scan->EV_250m_Aggr1km_RefSB_sds_id,
1984  "Rescaled Ocean R", DFNT_INT32,
1985  1, &scaled_250[0]) == FAIL)
1986  {
1987  returnStatus = MODIS_F_WRITE_ERROR;
1988  L1BErrorMsg(location, returnStatus, "Rescaled Ocean R",
1989  "SDsetattr", 0, NULL, False);
1990  return returnStatus;
1991  }
1992  }
1993 
1994  if ((RSCL_FLAG & 2) == 2)
1995  {
1996  if (SDsetattr(L1B_Scan->EV_250m_Aggr1km_RefSB_sds_id,
1997  "Rescaled Ocean NIR", DFNT_INT32,
1998  1, &scaled_250[1]) == FAIL)
1999  {
2000  returnStatus = MODIS_F_WRITE_ERROR;
2001  L1BErrorMsg(location, returnStatus, "Rescaled Ocean NIR",
2002  "SDsetattr", 0, NULL, False);
2003  return returnStatus;
2004  }
2005  }
2006 
2007  if ((RSCL_FLAG & 4) == 4)
2008  {
2009  if (SDsetattr(L1B_Scan->EV_500m_Aggr1km_RefSB_sds_id,
2010  "Rescaled Ocean B", DFNT_INT32,
2011  1, &scaled_500[0]) == FAIL)
2012  {
2013  returnStatus = MODIS_F_WRITE_ERROR;
2014  L1BErrorMsg(location, returnStatus, "Rescaled Ocean B",
2015  "SDsetattr", 0, NULL, False);
2016  return returnStatus;
2017  }
2018  }
2019 
2020  if ((RSCL_FLAG & 8) == 8)
2021  {
2022  if (SDsetattr(L1B_Scan->EV_500m_Aggr1km_RefSB_sds_id,
2023  "Rescaled Ocean G", DFNT_INT32,
2024  1, &scaled_500[1]) == FAIL)
2025  {
2026  returnStatus = MODIS_F_WRITE_ERROR;
2027  L1BErrorMsg(location, returnStatus, "Rescaled Ocean G",
2028  "SDsetattr", 0, NULL, False);
2029  return returnStatus;
2030  }
2031  }
2032 
2033 /************************* Begin Band 26 Section **************************/
2034 #ifdef WRITE_BAND_26_SDS
2035 /*
2036  * Open SDS access to the band 26 SDSs and save the
2037  * SDS ids in the L1B_Scan structure. SDS access is closed in function
2038  * Close_L1B_Granule. Note that the SDSs are not really created here
2039  * depite the name of the macro. They were created in Create_L1B_Swath.
2040  */
2041  CREATE_EV_SDS (L1B_Gran->sd_id[INDEX_L1B_1km],
2046  L1B_Scan->Band26.SI_sds_id,
2047  L1B_Scan->Band26.UI_sds_id);
2048 #endif /* WRITE_BAND_26_SDS */
2049 /************************** End Band 26 Section ***************************/
2050 
2051  return(MODIS_S_OK);
2052 }
2053 
2054 
2056  L1B_granule_t *L1B_Gran,
2057  L1B_Scan_t *L1B_Scan,
2058  boolean skip_night_hi_res)
2059 /*
2060 !C****************************************************************
2061 !Description: This routine creates and set the units, valid range and
2062  fill-value attributes for each of the EV SDSs (SI, UI and SU).
2063  This routine also writes the following attributes of scaled
2064  integer SDSs: (1) band names, (2) reflectance scales, offsets
2065  and units (only if reflectance SDSs are present), (3) radiance
2066  scales, offsets and units and (4) corrected counts scales,
2067  offsets and units.
2068 
2069 !Input Parameters:
2070  L1B_Gran ->sd_id[] SD file ids for the EV files.
2071  ->SO Scale-Offset struct, contains the radiance,
2072  reflectance and corrected counts scales,
2073  offsets.
2074  L1B_Scan SDS access ids used in Get_SDS_id and in
2075  Set_Unit_Range_Fillvalue.
2076  boolean skip_night_hi_res True if and only if all scans are
2077  night mode scans and writing of 250m
2078  and 500m night mode granules has been
2079  turned off
2080 !Output Parameters:
2081  None
2082 
2083 !Revision History:
2084  (continue at top of the file)
2085 
2086  Revision 02.21 November 15, 2001 Razor Issue #169
2087  Added boolean skip_night_hi_res to input parameters and altered logic so that
2088  if skip_night_hi_res is True, output data sets for 250m and 500m resolution
2089  data are not created.
2090  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
2091 
2092  Revision 02.20 May 13, 1999
2093  Added band 26 section.
2094  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
2095 
2096  Revision 02.11 Sept 14 1998
2097  Change dimension attribute to sds attribute based on
2098  file specs V2.1.1
2099  Zhenying Gu (zgu@mcst.gsfc.nasa.gov)
2100 
2101  Revision 02.10 April 10 1998
2102  Changed to the V2.1 L1B_Gran->momos (from the V2
2103  L1B_Gran->SO.rad_scale_RefSB and L1B_Gran->SO.refl_scale_RefSB)
2104  David Catozzi (cato@ltpmail.gsfc.nasa.gov)
2105 
2106  Revision 02.00 April 1997
2107  Modified to match changes in data structures.
2108  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
2109 
2110  Revision 01.00 1997/03/01
2111  Initial development
2112  Neal Devine (neal.devine@gsfc.nasa.gov)
2113 
2114 !Team-unique Header:
2115  This software is developed by the MODIS Characterization Support
2116  Team (MCST)for the National Aeronautics and Space Administration,
2117  Goddard Space Flight Center, under contract NAS5-32373.
2118 
2119 !References and Credits:
2120  HDF portions developed at the National Center for Supercomputing
2121  Applications at the University of Illinois at Urbana-Champaign.
2122 
2123 !Design Notes:
2124  Note that the band dim sds's are used for two distinct purposes:
2125  dim attributes, which happen to create float32 sdss, and band subsetting
2126  numbers.
2127 
2128 !END********************************************************************
2129 */
2130 {
2131  PGSt_SMF_status returnStatus;
2132  char *location = "Set_L1B_EV_SDS_Attrs";
2133  int16 f = 0; /*L1B EV file index (0,2)*/
2134  int16 loc = 0; /*location in an array*/
2135  int16 num_sds = 0; /*num band subsetting sds's within one file*/
2136  int32 sds_ids[4] = {0, 0, 0, 0}; /* added by gu */
2137 
2138  typedef enum {
2139  radiance,
2140  reflectance,
2141  counts,
2142  Num_Kinds
2143  } ScaleOffset_Kind_t;
2144 
2145  float32 *scale[Num_Kinds][NUM_L1A_RESOLUTIONS];
2146  float32 *offset[Num_Kinds][NUM_L1A_RESOLUTIONS];
2147  char *BandNames[NUM_L1A_RESOLUTIONS] = {
2148  "1,2",
2149  "3,4,5,6,7",
2150  "8,9,10,11,12,13lo,13hi,14lo,14hi,15,16,17,18,19,26",
2151  "20,21,22,23,24,25,27,28,29,30,31,32,33,34,35,36"
2152  };
2153  char *rad_units = "Watts/m^2/micrometer/steradian";
2154  char *refl_units = "none";
2155  char *counts_units = "counts";
2156  int32 evfile_luns[NUM_L1B_EV_FILES] =
2157  {
2161  };
2162  int16 start_output_res = INDEX_L1B_250m;
2163 
2164  returnStatus = Set_Unit_Range_Fillvalue(L1B_Scan, skip_night_hi_res);
2165  if (returnStatus != MODIS_S_OK)
2166  {
2167  L1BErrorMsg(location, returnStatus, NULL,
2168  "Set_Unit_Range_Fillvalue", 0, NULL, True);
2169  return returnStatus;
2170  }
2171 
2172  /*
2173  * Add additional attributes to uncertainty index SDSs.
2174  */
2175 
2176  returnStatus = Set_UI_ConvertToPercent_Attrs(tables,
2177  L1B_Scan,
2178  skip_night_hi_res);
2179  if (returnStatus != MODIS_S_OK)
2180  {
2181  L1BErrorMsg(location, returnStatus, NULL,
2182  "Set_UI_ConvertToPercent_Attrs", 0, NULL, True);
2183  return returnStatus;
2184  }
2185 
2186  /********************************
2187  * 250m scales and offsets *
2188  ********************************/
2189  scale[radiance][INDEX_250M] = &(L1B_Gran->SO.rad_scale_RefSB[0]);
2190  scale[reflectance][INDEX_250M] = &(L1B_Gran->SO.refl_scale_RefSB[0]);
2191 
2192  offset[radiance][INDEX_250M] = &(L1B_Gran->SO.rad_offset_RefSB[0]);
2193  offset[reflectance][INDEX_250M] = &(L1B_Gran->SO.refl_offset_RefSB[0]);
2194 
2195  scale[counts][INDEX_250M] = &(L1B_Gran->SO.counts_scale_RefSB[0]);
2196  offset[counts][INDEX_250M] = &(L1B_Gran->SO.counts_offset_RefSB[0]);
2197 
2198 
2199  /********************************
2200  * 500m scales and offsets *
2201  ********************************/
2203 
2204  scale[radiance][INDEX_500M] =
2205  &(L1B_Gran->SO.rad_scale_RefSB[loc]);
2206  scale[reflectance][INDEX_500M] =
2207  &(L1B_Gran->SO.refl_scale_RefSB[loc]);
2208 
2209  offset[radiance][INDEX_500M] =
2210  &(L1B_Gran->SO.rad_offset_RefSB[loc]);
2211  offset[reflectance][INDEX_500M] =
2212  &(L1B_Gran->SO.refl_offset_RefSB[loc]);
2213 
2214  scale[counts][INDEX_500M] =
2215  &(L1B_Gran->SO.counts_scale_RefSB[loc]);
2216  offset[counts][INDEX_500M] =
2217  &(L1B_Gran->SO.counts_offset_RefSB[loc]);
2218 
2219  /********************************
2220  * 1Km Refl scales and offsets *
2221  ********************************/
2223 
2224  scale[radiance][INDEX_1000M_REFL] =
2225  &(L1B_Gran->SO.rad_scale_RefSB[loc]);
2226  scale[reflectance][INDEX_1000M_REFL] =
2227  &(L1B_Gran->SO.refl_scale_RefSB[loc]);
2228 
2229  offset[radiance][INDEX_1000M_REFL] =
2230  &(L1B_Gran->SO.rad_offset_RefSB[loc]);
2231  offset[reflectance][INDEX_1000M_REFL] =
2232  &(L1B_Gran->SO.refl_offset_RefSB[loc]);
2233 
2235  &(L1B_Gran->SO.counts_scale_RefSB[loc]);
2237  &(L1B_Gran->SO.counts_offset_RefSB[loc]);
2238 
2239 
2240  /********************************
2241  * 1Km Emiss scales and offsets *
2242  ********************************/
2243  scale[radiance][INDEX_1000M_EMISS] =
2244  &(L1B_Gran->SO.rad_scale_Emiss[0]);
2245  offset[radiance][INDEX_1000M_EMISS] =
2246  &(L1B_Gran->SO.rad_offset_Emiss[0]);
2247 
2248  /*******************************
2249  * 250m holds rescaled R & NIR *
2250  *******************************/
2251  if ((RFLAG & 1) == 1) {
2252  scale[reflectance][INDEX_250M][0] = scale[counts][INDEX_250M][0]*
2253  scale[reflectance][INDEX_1000M_REFL][5]/scale[counts][INDEX_1000M_REFL][5];
2254  scale[reflectance][INDEX_250M][1] = scale[counts][INDEX_250M][1]*
2255  scale[reflectance][INDEX_1000M_REFL][10]/scale[counts][INDEX_1000M_REFL][10];
2256  }
2257 
2258  /*****************************
2259  * 500m holds rescaled B & G *
2260  *****************************/
2261  if ((RFLAG & 2) == 2) {
2262  scale[reflectance][INDEX_500M][0] = scale[counts][INDEX_500M][0]*
2263  scale[reflectance][INDEX_1000M_REFL][2]/scale[counts][INDEX_1000M_REFL][2];
2264  scale[reflectance][INDEX_500M][1] = scale[counts][INDEX_500M][1]*
2265  scale[reflectance][INDEX_1000M_REFL][4]/scale[counts][INDEX_1000M_REFL][4];
2266  }
2267 
2268  /*
2269  * If we are in night mode and we do not wish to write 250m and 500m data
2270  * sets, start with the 1KM output data sets.
2271  */
2272 
2273  if (skip_night_hi_res == True)
2274  start_output_res = INDEX_L1B_1km;
2275  else
2276  start_output_res = INDEX_L1B_250m;
2277 
2278  for (f = start_output_res; f < NUM_L1B_EV_FILES; f++)
2279  {
2280  returnStatus = Get_SDS_id(f, L1B_Scan, &num_sds, sds_ids);
2281 
2282  if (returnStatus != MODIS_S_OK)
2283  {
2284  L1BErrorMsg(location, returnStatus, NULL,
2285  "Get_SDS_id", evfile_luns[f], NULL, True);
2286  return returnStatus;
2287  }
2288 
2289  returnStatus = Set_SDS_Attributes(sds_ids, BandNames,
2290  (float32 **)scale,
2291  (float32 **)offset,
2292  rad_units,
2293  refl_units,
2294  counts_units,
2295  num_sds);
2296 
2297  if (returnStatus != MODIS_S_OK)
2298  {
2299  L1BErrorMsg(location, returnStatus, NULL,
2300  "Set_SDS_Attributes", evfile_luns[f], NULL, True);
2301  return returnStatus;
2302  }
2303 
2304  } /*f*/
2305 
2306 /************************* Begin Band 26 Section **************************/
2307 #ifdef WRITE_BAND_26_SDS
2308  /*
2309  * Set the radiance, reflectance and corrected counts scales for
2310  * the Band 26 scaled integer SDS.
2311  */
2312 
2313  f = INDEX_L1B_1km; /* file index, for LUN identification */
2314  loc = NUM_REFLECTIVE_BANDS - 1; /* index of Band 26 in SO arrays */
2315 
2316  if (SDsetattr(L1B_Scan->Band26.SI_sds_id, "radiance_scales",
2317  DFNT_FLOAT32,
2318  1, &(L1B_Gran->SO.rad_scale_RefSB[loc])) == FAIL)
2319  {
2320  returnStatus = MODIS_F_WRITE_ERROR;
2321  L1BErrorMsg(location, returnStatus,
2322  "Could not write Band 26 SI SDS "
2323  "attribute "
2324  "\"radiance_scales\".",
2325  "SDsetattr", evfile_luns[f], NULL, True);
2326  return returnStatus;
2327  }
2328 
2329  if (SDsetattr(L1B_Scan->Band26.SI_sds_id, "radiance_offsets",
2330  DFNT_FLOAT32,
2331  1, &(L1B_Gran->SO.rad_offset_RefSB[loc])) == FAIL)
2332  {
2333  returnStatus = MODIS_F_WRITE_ERROR;
2334  L1BErrorMsg(location, returnStatus,
2335  "Could not write Band 26 SI SDS "
2336  "attribute "
2337  "\"radiance_offsets\".",
2338  "SDsetattr", evfile_luns[f], NULL, True);
2339  return returnStatus;
2340  }
2341 
2342  if (SDsetattr(L1B_Scan->Band26.SI_sds_id, "radiance_units",
2343  DFNT_CHAR8,
2344  (int32)strlen(rad_units), rad_units) == FAIL)
2345  {
2346  returnStatus = MODIS_F_WRITE_ERROR;
2347  L1BErrorMsg(location, returnStatus,
2348  "Could not write Band 26 SI SDS "
2349  "attribute "
2350  "\"radiance_units\".",
2351  "SDsetattr", evfile_luns[f], NULL, True);
2352  return returnStatus;
2353  }
2354 
2355  if (SDsetattr(L1B_Scan->Band26.SI_sds_id, "reflectance_scales",
2356  DFNT_FLOAT32,
2357  1, &(L1B_Gran->SO.refl_scale_RefSB[loc])) == FAIL)
2358  {
2359  returnStatus = MODIS_F_WRITE_ERROR;
2360  L1BErrorMsg(location, returnStatus,
2361  "Could not write Band 26 SI SDS "
2362  "attribute "
2363  "\"reflectance_scales\".",
2364  "SDsetattr", evfile_luns[f], NULL, True);
2365  return returnStatus;
2366  }
2367 
2368  if (SDsetattr(L1B_Scan->Band26.SI_sds_id, "reflectance_offsets",
2369  DFNT_FLOAT32,
2370  1, &(L1B_Gran->SO.refl_offset_RefSB[loc])) == FAIL)
2371  {
2372  returnStatus = MODIS_F_WRITE_ERROR;
2373  L1BErrorMsg(location, returnStatus,
2374  "Could not write Band 26 SI SDS "
2375  "attribute "
2376  "\"reflectance_offsets\".",
2377  "SDsetattr", evfile_luns[f], NULL, True);
2378  return returnStatus;
2379  }
2380 
2381  if (SDsetattr(L1B_Scan->Band26.SI_sds_id, "reflectance_units",
2382  DFNT_CHAR8,
2383  (int32)strlen(refl_units), refl_units) == FAIL)
2384  {
2385  returnStatus = MODIS_F_WRITE_ERROR;
2386  L1BErrorMsg(location, returnStatus,
2387  "Could not write Band 26 SI SDS "
2388  "attribute "
2389  "\"reflectance_units\".",
2390  "SDsetattr", evfile_luns[f], NULL, True);
2391  return returnStatus;
2392  }
2393 
2394  if (SDsetattr(L1B_Scan->Band26.SI_sds_id, "corrected_counts_scales",
2395  DFNT_FLOAT32,
2396  1, &(L1B_Gran->SO.counts_scale_RefSB[loc])) == FAIL)
2397  {
2398  returnStatus = MODIS_F_WRITE_ERROR;
2399  L1BErrorMsg(location, returnStatus,
2400  "Could not write Band 26 SI SDS "
2401  "attribute "
2402  "\"corrected_counts_scales\".",
2403  "SDsetattr", evfile_luns[f], NULL, True);
2404  return returnStatus;
2405  }
2406 
2407  if (SDsetattr(L1B_Scan->Band26.SI_sds_id, "corrected_counts_offsets",
2408  DFNT_FLOAT32,
2409  1, &(L1B_Gran->SO.counts_offset_RefSB[loc])) == FAIL)
2410  {
2411  returnStatus = MODIS_F_WRITE_ERROR;
2412  L1BErrorMsg(location, returnStatus,
2413  "Could not write Band 26 SI SDS "
2414  "attribute "
2415  "\"corrected_counts_offsets\".",
2416  "SDsetattr", evfile_luns[f], NULL, True);
2417  return returnStatus;
2418  }
2419 
2420  if (SDsetattr(L1B_Scan->Band26.SI_sds_id, "corrected_counts_units",
2421  DFNT_CHAR8,
2422  (int32)strlen(counts_units), counts_units) == FAIL)
2423  {
2424  returnStatus = MODIS_F_WRITE_ERROR;
2425  L1BErrorMsg(location, returnStatus,
2426  "Could not write Band 26 SI SDS "
2427  "attribute "
2428  "\"corrected_counts_units\".",
2429  "SDsetattr", evfile_luns[f], NULL, True);
2430  return returnStatus;
2431  }
2432 
2433 #endif /* WRITE_BAND_26_SDS */
2434 /************************** End Band 26 Section ***************************/
2435 
2436  return(MODIS_S_OK);
2437 }
2438 
2439 PGSt_SMF_status Set_Unit_Range_Fillvalue(L1B_Scan_t *L1B_Scan,
2440  boolean skip_night_hi_res)
2441 /*
2442 !C**********************************************************************
2443 !Description: This routine creates and set the units, valid range and
2444  fill-value attributes for each of the EV SDSs (SI, UI and SU).
2445 
2446 !Input Parameters:
2447  L1B_Scan_t * L1B_Scan
2448  boolean skip_night_hi_res True if and only if all scans are
2449  night mode scans and writing of 250m
2450  and 500m night mode granules has been
2451  turned off
2452 
2453 !Output Parameters:
2454 
2455 !Revision History:
2456  (continue at top of the file)
2457 
2458  Revision 01.11 October 16, 2004 Razor Issue #200
2459  Casted Int32 variables in sprintf calls to "long" with the
2460  format specifier "%ld" for better code portability.
2461  Liqin Tan, SAIC GSO (ltan@saicmodis.com)
2462 
2463  Revision 01.10 May 13, 1999
2464  Added band 26 section.
2465  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
2466 
2467  Revision 01.01 Feb 18, 1999
2468  Made the SU_valid_range an array of pointers, since there are different
2469  valid ranges for the different aggregated SDSs.
2470  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
2471 
2472  Revision 01.00 1998
2473  Initial development
2474  Zhenying Gu(zgu@ltpmail.gsfc.nasa.gov)
2475 
2476 !Team-unique Header:
2477  This software is developed by the MODIS Characterization Support
2478  Team (MCST)for the National Aeronautics and Space Administration,
2479  Goddard Space Flight Center, under contract NAS5-32373.
2480 
2481 !References and Credits:
2482  HDF portions developed at the National Center for Supercomputing
2483  Applications at the University of Illinois at Urbana-Champaign.
2484 
2485 !Design Notes:
2486 
2487 !END********************************************************************
2488 */
2489 
2490 {
2491  PGSt_SMF_status returnStatus = MODIS_S_OK;
2492  char *location = "Set_Unit_Range_Fillvalue";
2493  char errmsg[256];
2494  char *errmsgfmt = "Could not write attribute \"%s\", "
2495  "type[%ld], sds_number[%ld].";
2496  typedef enum {
2497  SI,
2498  UI,
2499  SU,
2500  Num_Data_types
2501  } EV_Data_Type_t;
2502  typedef enum { RefSB_250_Data,
2503  RefSB_500_Data,
2504  RefSB_1KM_Data,
2505  Emissive_Data,
2506  Aggr_250_500_RefSB_Data,
2507  Aggr_250_1km_RefSB_Data,
2508  Aggr_500_1km_RefSB_Data,
2509  NUM_EV_DATA_SETS
2510  } ev_Data_Sets_t;
2511  typedef enum { Aggr_250_500_RefSB_Samples,
2512  Aggr_250_1km_RefSB_Samples,
2513  Aggr_500_1km_RefSB_Samples,
2514  NUM_EV_AGGR_SAMPLES
2515  } ev_Aggr_Samples_t;
2516  int32 type;
2517  int32 sds_number;
2518  int32 num_sds_ids[Num_Data_types] = {7, 7, 3};
2519  int32 R;
2520  char *units = "none";
2521  uint16 SI_valid_range[2] = {0, 32767};
2522  uint8 UI_valid_range[2] = {0, 15};
2523  int8 SU_valid_range_X2[2] = {0, 6}; /* aggregating by a factor of 2 */
2524  int8 SU_valid_range_X4[2] = {0, 28}; /* aggregating by a factor of 4 */
2525  int8 *SU_valid_range[3];
2526  uint16 SI_fillvalue = 65535;
2527  uint8 UI_fillvalue = 255;
2528  int8 SU_fillvalue = -1;
2529  int32 SI_sds_ids[7];
2530  int32 UI_sds_ids[7];
2531  int32 SU_sds_ids[3];
2532  int32 *sds_ids[Num_Data_types];
2533  int16 start_output_res = INDEX_L1B_250m;
2534  /* in the loop below, these are indexed with sds_number for SU case */
2535 
2536  /* 250m_Aggr500 */
2537  SU_valid_range[Aggr_250_500_RefSB_Samples] = SU_valid_range_X2;
2538  /* 250m_Aggr1km */
2539  SU_valid_range[Aggr_250_1km_RefSB_Samples] = SU_valid_range_X4;
2540  /* 500m_Aggr1km */
2541  SU_valid_range[Aggr_500_1km_RefSB_Samples] = SU_valid_range_X2;
2542 
2543  sds_ids[0] = SI_sds_ids;
2544  sds_ids[1] = UI_sds_ids;
2545  sds_ids[2] = SU_sds_ids;
2546 
2547  for(R = 0; R < NUM_L1A_RESOLUTIONS; R++)
2548  {
2549  SI_sds_ids[R] = L1B_Scan->SI_sds_id[R];
2550  UI_sds_ids[R] = L1B_Scan->UI_sds_id[R];
2551  }
2552 
2553  SI_sds_ids[Aggr_250_500_RefSB_Data] =
2555  SI_sds_ids[Aggr_250_1km_RefSB_Data] =
2556  L1B_Scan->EV_250m_Aggr1km_RefSB_sds_id;
2557  SI_sds_ids[Aggr_500_1km_RefSB_Data] =
2558  L1B_Scan->EV_500m_Aggr1km_RefSB_sds_id;
2559 
2560  UI_sds_ids[Aggr_250_500_RefSB_Data] =
2562  UI_sds_ids[Aggr_250_1km_RefSB_Data] =
2564  UI_sds_ids[Aggr_500_1km_RefSB_Data] =
2566 
2567  SU_sds_ids[Aggr_250_500_RefSB_Samples] =
2569  SU_sds_ids[Aggr_250_1km_RefSB_Samples] =
2571  SU_sds_ids[Aggr_500_1km_RefSB_Samples] =
2573 
2574  /*
2575  * The following shows the relationship between index, type, and sds#.
2576  * index type sds# good night indices = [2, 3, 5, 6]
2577  * 0 0 0 SI_name = EV_250_RefSB
2578  * 1 0 1 SI_name = EV_500_RefSB
2579  * 2 0 2 SI_name = EV_1KM_RefSB
2580  * 2 0 3 SI_name = EV_1KM_Emissive
2581  * 1 0 4 SI_name = EV_250_Aggr500_RefSB
2582  * 2 0 5 SI_name = EV_250_Aggr1km_RefSB
2583  * 2 0 6 SI_name = EV_500_Aggr1km_RefSB
2584  * good night indices = [2, 3, 5, 6]
2585  * 0 1 0 UI_name = EV_250_RefSB_Uncert_Indexes
2586  * 1 1 1 UI_name = EV_500_RefSB_Uncert_Indexes
2587  * 2 1 2 UI_name = EV_1KM_RefSB_Uncert_Indexes
2588  * 2 1 3 UI_name = EV_1KM_Emissive_Uncert_Indexes
2589  * 1 1 4 UI_name = EV_250_Aggr500_RefSB_Uncert_Indexes
2590  * 2 1 5 UI_name = EV_250_Aggr1km_RefSB_Uncert_Indexes
2591  * 2 1 6 UI_name = EV_500_Aggr1km_RefSB_Uncert_Indexes
2592  * good night indices = none
2593  * 1 2 0 SU_name = EV_250_Aggr500_RefSB_Samples_Used
2594  * 2 2 1 SU_name = EV_250_Aggr1km_RefSB_Samples_Used
2595  * 2 2 2 SU_name = EV_500_Aggr1km_RefSB_Samples_Used
2596  */
2597 
2598 
2599 
2600  for (type = 0; type < Num_Data_types; type++)
2601  {
2602  if (type < SU && skip_night_hi_res == True)
2603  start_output_res = INDEX_L1B_1km;
2604  else
2605  start_output_res = INDEX_L1B_250m;
2606 
2607  for (sds_number = start_output_res;
2608  sds_number < num_sds_ids[type]; sds_number++)
2609 
2610  {
2611  if (skip_night_hi_res == True)
2612  if ((type < SU && sds_number == Aggr_250_500_RefSB_Data) ||
2613  (type == SU && sds_number == Aggr_250_500_RefSB_Samples))
2614  continue;
2615 
2616  if (SDsetattr(sds_ids[type][sds_number], "units",
2617  DFNT_CHAR, 4, (VOIDP)units) == FAIL)
2618  {
2619  sprintf(errmsg, errmsgfmt, "units", (long)type, (long)sds_number);
2620  returnStatus = MODIS_F_WRITE_ERROR;
2621  L1BErrorMsg(location, returnStatus, errmsg,
2622  "SDsetattr", 0, NULL, True);
2623  return returnStatus;
2624  }
2625 
2626  switch(type)
2627  {
2628  case SI:
2629 
2630  if (SDsetattr(sds_ids[type][sds_number], "valid_range",
2631  DFNT_UINT16, 2, (VOIDP)SI_valid_range) == FAIL)
2632  {
2633  sprintf(errmsg, errmsgfmt, "valid_range", (long)type, (long)sds_number);
2634  returnStatus = MODIS_F_WRITE_ERROR;
2635  L1BErrorMsg(location, returnStatus, errmsg,
2636  "SDsetattr", 0, NULL, True);
2637  return returnStatus;
2638  }
2639 
2640  if (SDsetattr(sds_ids[type][sds_number], "_FillValue",
2641  DFNT_UINT16, 1,(VOIDP)&SI_fillvalue) == FAIL)
2642  {
2643  sprintf(errmsg, errmsgfmt, "_FillValue", (long)type, (long)sds_number);
2644  returnStatus = MODIS_F_WRITE_ERROR;
2645  L1BErrorMsg(location, returnStatus, errmsg,
2646  "SDsetattr", 0, NULL, True);
2647  return returnStatus;
2648  }
2649  break;
2650 
2651  case UI:
2652 
2653  if (SDsetattr(sds_ids[type][sds_number], "valid_range",
2654  DFNT_UINT8, 2, (VOIDP)UI_valid_range) == FAIL)
2655  {
2656  sprintf(errmsg, errmsgfmt, "valid_range", (long)type, (long)sds_number);
2657  returnStatus = MODIS_F_WRITE_ERROR;
2658  L1BErrorMsg(location, returnStatus, errmsg,
2659  "SDsetattr", 0, NULL, True);
2660  return returnStatus;
2661  }
2662 
2663  if (SDsetattr(sds_ids[type][sds_number], "_FillValue",
2664  DFNT_UINT8, 1,(VOIDP)&UI_fillvalue) == FAIL)
2665  {
2666  sprintf(errmsg, errmsgfmt, "_FillValue", (long)type, (long)sds_number);
2667  returnStatus = MODIS_F_WRITE_ERROR;
2668  L1BErrorMsg(location, returnStatus, errmsg,
2669  "SDsetattr", 0, NULL, True);
2670  return returnStatus;
2671  }
2672  break;
2673 
2674  case SU:
2675 
2676  if (SDsetattr(sds_ids[type][sds_number], "valid_range",
2677  DFNT_INT8, 2,
2678  (VOIDP)SU_valid_range[sds_number]) == FAIL)
2679  {
2680  sprintf(errmsg, errmsgfmt, "valid_range", (long)type, (long)sds_number);
2681  returnStatus = MODIS_F_WRITE_ERROR;
2682  L1BErrorMsg(location, returnStatus, errmsg,
2683  "SDsetattr", 0, NULL, True);
2684  return returnStatus;
2685  }
2686 
2687  if (SDsetattr(sds_ids[type][sds_number], "_FillValue",
2688  DFNT_INT8, 1,(VOIDP)&SU_fillvalue) == FAIL)
2689  {
2690  sprintf(errmsg, errmsgfmt, "_FillValue", (long)type, (long)sds_number);
2691  returnStatus = MODIS_F_WRITE_ERROR;
2692  L1BErrorMsg(location, returnStatus, errmsg,
2693  "SDsetattr", 0, NULL, True);
2694  return returnStatus;
2695  }
2696  break;
2697  default:
2698  {
2699  returnStatus = MODIS_F_NOK;
2700  L1BErrorMsg(location, returnStatus,
2701  "Invalid \"type\" ... must be code bug.",
2702  "SDsetattr", 0, NULL, True);
2703  return returnStatus;
2704  }
2705  }
2706  }
2707  }/* end loop through type */
2708 
2709 /************************* Begin Band 26 Section **************************/
2710 #ifdef WRITE_BAND_26_SDS
2711  /*
2712  * Set the units, valid_range and _FillValue attributes for the
2713  * Band 26 SDSs.
2714  */
2715  /* Scaled Integer SDS */
2716 
2717  if (SDsetattr(L1B_Scan->Band26.SI_sds_id, "units",
2718  DFNT_CHAR, 4, (VOIDP)units) == FAIL)
2719  {
2720  strcpy(errmsg, "Could not write Band 26 SI SDS "
2721  "attribute \"units\".");
2722  returnStatus = MODIS_F_WRITE_ERROR;
2723  L1BErrorMsg(location, returnStatus, errmsg,
2724  "SDsetattr", 0, NULL, True);
2725  return returnStatus;
2726  }
2727  if (SDsetattr(L1B_Scan->Band26.SI_sds_id, "valid_range",
2728  DFNT_UINT16, 2, (VOIDP)SI_valid_range) == FAIL)
2729  {
2730  strcpy(errmsg, "Could not write Band 26 SI SDS "
2731  "attribute \"valid_range\".");
2732  returnStatus = MODIS_F_WRITE_ERROR;
2733  L1BErrorMsg(location, returnStatus, errmsg,
2734  "SDsetattr", 0, NULL, True);
2735  return returnStatus;
2736  }
2737  if (SDsetattr(L1B_Scan->Band26.SI_sds_id, "_FillValue",
2738  DFNT_UINT16, 1,(VOIDP)&SI_fillvalue) == FAIL)
2739  {
2740  strcpy(errmsg, "Could not write Band 26 SI SDS "
2741  "attribute \"_FillValue\".");
2742  returnStatus = MODIS_F_WRITE_ERROR;
2743  L1BErrorMsg(location, returnStatus, errmsg,
2744  "SDsetattr", 0, NULL, True);
2745  return returnStatus;
2746  }
2747 
2748  /* Undertainty SDS */
2749 
2750  if (SDsetattr(L1B_Scan->Band26.UI_sds_id, "units",
2751  DFNT_CHAR, 4, (VOIDP)units) == FAIL)
2752  {
2753  strcpy(errmsg, "Could not write Band 26 UI SDS "
2754  "attribute \"units\".");
2755  returnStatus = MODIS_F_WRITE_ERROR;
2756  L1BErrorMsg(location, returnStatus, errmsg,
2757  "SDsetattr", 0, NULL, True);
2758  return returnStatus;
2759  }
2760  if (SDsetattr(L1B_Scan->Band26.UI_sds_id, "valid_range",
2761  DFNT_UINT8, 2, (VOIDP)UI_valid_range) == FAIL)
2762  {
2763  strcpy(errmsg, "Could not write Band 26 UI SDS "
2764  "attribute \"valid_range\".");
2765  returnStatus = MODIS_F_WRITE_ERROR;
2766  L1BErrorMsg(location, returnStatus, errmsg,
2767  "SDsetattr", 0, NULL, True);
2768  return returnStatus;
2769  }
2770  if (SDsetattr(L1B_Scan->Band26.UI_sds_id, "_FillValue",
2771  DFNT_UINT8, 1,(VOIDP)&UI_fillvalue) == FAIL)
2772  {
2773  strcpy(errmsg, "Could not write Band 26 UI SDS "
2774  "attribute \"_FillValue\".");
2775  returnStatus = MODIS_F_WRITE_ERROR;
2776  L1BErrorMsg(location, returnStatus, errmsg,
2777  "SDsetattr", 0, NULL, True);
2778  return returnStatus;
2779  }
2780 
2781 #endif /* WRITE_BAND_26_SDS */
2782 /************************** End Band 26 Section ***************************/
2783 
2784  return(MODIS_S_OK);
2785 }
2786 
2787 PGSt_SMF_status Get_SDS_id(int32 f,
2788  L1B_Scan_t *L1B_Scan,
2789  int16 *num_sds,
2790  int32 *sds_id)
2791 /*
2792 !C**********************************************************************
2793 !Description: For one L1B EV file of index f, this routine gets the number
2794  of EV, scaled integer (SI), SDSs and an array of the SDS ids.
2795  These include both aggregated and non-aggregated SI SDSs.
2796 
2797 !Input Parameters:
2798  f Index of one of the L1B EV files.
2799  L1B_Scan Members which are SDS ids for scaled integer (SI) SDSs.
2800 
2801 !Output Parameters:
2802  num_sds Number of SDS ids assigned to array sds_id.
2803  sds_id Array of SDS ids pertaining to the particular file
2804  of index f. This array should be allocated large
2805  enough to hold at least 4 ids.
2806 
2807 !Revision History:
2808  (continue at top of the file)
2809 
2810  Revision 01.01 Feb 10, 1999
2811  Added address of num_sds to argument list to be able to assign the variable
2812  in this function.
2813  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
2814 
2815  Revision 01.00 1998
2816  Initial development
2817  Zhenying Gu(zgu@ltpmail.gsfc.nasa.gov)
2818 
2819 !Team-unique Header:
2820 
2821 !References and Credits:
2822  This software is developed by the MODIS Characterization Support
2823  Team (MCST)for the National Aeronautics and Space Administration,
2824  Goddard Space Flight Center, under contract NAS5-32373.
2825 
2826  HDF portions developed at the National Center for Supercomputing
2827  Applications at the University of Illinois at Urbana-Champaign.
2828 
2829 !Design Notes:
2830  The ordering of the SDS ids follows the ordering in resolution_index_t
2831  so that we can later use the macros INDEX_250M, ... INDEX_1000M_EMISS.
2832 
2833 !END********************************************************************
2834 */
2835 {
2836  switch(f)
2837  {
2838  case INDEX_L1B_250m:
2839  *num_sds = 1;
2840  sds_id[INDEX_250M] = L1B_Scan->SI_sds_id[INDEX_250M];
2841  break;
2842 
2843  case INDEX_L1B_500m:
2844  *num_sds = 2;
2845  sds_id[INDEX_250M] =
2847  sds_id[INDEX_500M] =
2848  L1B_Scan->SI_sds_id[INDEX_500M];
2849  break;
2850 
2851  case INDEX_L1B_1km:
2852  *num_sds =
2853  4;
2854  sds_id[INDEX_250M] =
2855  L1B_Scan->EV_250m_Aggr1km_RefSB_sds_id;
2856  sds_id[INDEX_500M] =
2857  L1B_Scan->EV_500m_Aggr1km_RefSB_sds_id;
2858  sds_id[INDEX_1000M_REFL] =
2859  L1B_Scan->SI_sds_id[INDEX_1000M_REFL];
2860  sds_id[INDEX_1000M_EMISS] =
2861  L1B_Scan->SI_sds_id[INDEX_1000M_EMISS];
2862  break;
2863 
2864  default:
2865  break;
2866  }
2867 
2868  return(MODIS_S_OK);
2869 }
2870 
2871 PGSt_SMF_status Set_SDS_Attributes(int32 *sds_id,
2872  char **BandNames,
2873  float32 **scale,
2874  float32 **offset,
2875  char *rad_units,
2876  char *refl_units,
2877  char *counts_units,
2878  int32 num_sds)
2879 /*
2880 !C**********************************************************************
2881 !Description: This routine writes the the following attributes of
2882  scaled integer SDSs: (1) band names, (2) reflectance
2883  scales, offsets and units (only if reflectance SDSs are
2884  present), (3) radiance scales, offsets and units and
2885  (4) corrected counts scales, offsets and units.
2886 
2887 !Input Parameters:
2888  int32 * sds_id array of SDS ids for EV SDSs. The ordering
2889  follows the order in resolution_index_t
2890  so we can use the macros defined there.
2891  char ** BandNames Array of band names for each SDS.
2892  float32 ** scale
2893  float32 ** offset
2894  char * rad_units String containing radiance units.
2895  char * refl_units String containing reflectance units.
2896  char * counts_units String containing corrected counts units.
2897  int32 num_sds Number of SDSs in array sds_id.
2898 !Output Parameters:
2899 
2900 !Revision History:
2901  (continue at top of the file)
2902 
2903  Revision 01.01 October 16, 2004 Razor Issue #200
2904  Casted Int32 variables in sprintf calls to "long" with the
2905  format specifier "%ld" for better code portability.
2906  Liqin Tan, SAIC GSO (ltan@saicmodis.com)
2907 
2908  Revision 01.00 1998
2909  Initial development
2910  Zhenying Gu(zgu@ltpmail.gsfc.nasa.gov)
2911 
2912 !Team-unique Header:
2913  This software is developed by the MODIS Characterization Support
2914  Team (MCST)for the National Aeronautics and Space Administration,
2915  Goddard Space Flight Center, under contract NAS5-32373.
2916 
2917 !References and Credits:
2918  HDF portions developed at the National Center for Supercomputing
2919  Applications at the University of Illinois at Urbana-Champaign.
2920 
2921 !Design Notes:
2922  If there is an error, write the L1BErrorMsg but do not error-out.
2923  Let the parent error out so that LUN can be identified.
2924 
2925 !END********************************************************************
2926 */
2927 {
2928  PGSt_SMF_status returnStatus = MODIS_S_OK;
2929  char *location = "Set_SDS_Attributes";
2930  char *errmsgfmt = "Could not write attribute \"%s\" for R = %ld";
2931  char errmsg[256];
2932  int32 R;
2933  typedef enum {
2934  radiance,
2935  reflectance,
2936  counts,
2937  Num_Kinds
2938  } ScaleOffset_Kind_t;
2939 
2940  int16 sds_dim = 4;
2941  int32 dim_size[4] = {2, 5, 15, 16};
2942 
2943  for (R = 0; R < num_sds; R++)
2944  {
2945  if (SDsetattr(sds_id[R],"band_names",DFNT_CHAR8,
2946  (int32)strlen(BandNames[R]), BandNames[R]) == FAIL)
2947  {
2948  returnStatus = MODIS_F_WRITE_ERROR;
2949  sprintf(errmsg, errmsgfmt, "band_names", (long)R);
2950  L1BErrorMsg(location, returnStatus, errmsg,
2951  "SDsetattr", 0, NULL, False);
2952  return returnStatus;
2953  }
2954 
2955  if (SDsetattr(sds_id[R],"radiance_scales",DFNT_FLOAT32,
2956  dim_size[R],scale[radiance * sds_dim + R]) == FAIL)
2957  {
2958  returnStatus = MODIS_F_WRITE_ERROR;
2959  sprintf(errmsg, errmsgfmt, "radiance_scales", (long)R);
2960  L1BErrorMsg(location, returnStatus, errmsg,
2961  "SDsetattr", 0, NULL, False);
2962  return returnStatus;
2963  }
2964 
2965  if (SDsetattr(sds_id[R],"radiance_offsets",DFNT_FLOAT32,
2966  dim_size[R], offset[radiance * sds_dim + R]) == FAIL)
2967  {
2968  returnStatus = MODIS_F_WRITE_ERROR;
2969  sprintf(errmsg, errmsgfmt, "radiance_offsets", (long)R);
2970  L1BErrorMsg(location, returnStatus, errmsg,
2971  "SDsetattr", 0, NULL, False);
2972  return returnStatus;
2973  }
2974 
2975  if (SDsetattr(sds_id[R],"radiance_units",DFNT_CHAR8,
2976  (int32)strlen(rad_units), rad_units) == FAIL)
2977  {
2978  returnStatus = MODIS_F_WRITE_ERROR;
2979  sprintf(errmsg, errmsgfmt, "radiance_units", (long)R);
2980  L1BErrorMsg(location, returnStatus, errmsg,
2981  "SDsetattr", 0, NULL, False);
2982  return returnStatus;
2983  }
2984 
2985  if (R != INDEX_1000M_EMISS)
2986  {
2987  if (SDsetattr(sds_id[R],"reflectance_scales",DFNT_FLOAT32,
2988  dim_size[R],scale[reflectance * sds_dim + R])
2989  == FAIL)
2990  {
2991  returnStatus = MODIS_F_WRITE_ERROR;
2992  sprintf(errmsg, errmsgfmt, "reflectance_scales", (long)R);
2993  L1BErrorMsg(location, returnStatus, errmsg,
2994  "SDsetattr", 0, NULL, False);
2995  return returnStatus;
2996  }
2997 
2998  if (SDsetattr(sds_id[R],"reflectance_offsets",DFNT_FLOAT32,
2999  dim_size[R],offset[reflectance * sds_dim + R])
3000  == FAIL)
3001  {
3002  returnStatus = MODIS_F_WRITE_ERROR;
3003  sprintf(errmsg, errmsgfmt, "reflectance_offsets", (long)R);
3004  L1BErrorMsg(location, returnStatus, errmsg,
3005  "SDsetattr", 0, NULL, False);
3006  return returnStatus;
3007  }
3008 
3009  if (SDsetattr(sds_id[R],"reflectance_units",DFNT_CHAR8,
3010  (int32)strlen(refl_units),refl_units) == FAIL)
3011  {
3012  returnStatus = MODIS_F_WRITE_ERROR;
3013  sprintf(errmsg, errmsgfmt, "reflectance_units", (long)R);
3014  L1BErrorMsg(location, returnStatus, errmsg,
3015  "SDsetattr", 0, NULL, False);
3016  return returnStatus;
3017  }
3018 
3019  if (SDsetattr(sds_id[R],"corrected_counts_scales",DFNT_FLOAT32,
3020  dim_size[R],scale[counts * sds_dim + R]) == FAIL)
3021  {
3022  returnStatus = MODIS_F_WRITE_ERROR;
3023  sprintf(errmsg, errmsgfmt, "corrected_counts_scales", (long)R);
3024  L1BErrorMsg(location, returnStatus, errmsg,
3025  "SDsetattr", 0, NULL, False);
3026  return returnStatus;
3027  }
3028 
3029  if (SDsetattr(sds_id[R],"corrected_counts_offsets",DFNT_FLOAT32,
3030  dim_size[R],offset[counts * sds_dim + R]) == FAIL)
3031  {
3032  returnStatus = MODIS_F_WRITE_ERROR;
3033  sprintf(errmsg, errmsgfmt, "corrected_counts_offsets", (long)R);
3034  L1BErrorMsg(location, returnStatus, errmsg,
3035  "SDsetattr", 0, NULL, False);
3036  return returnStatus;
3037  }
3038 
3039  if (SDsetattr(sds_id[R],"corrected_counts_units",DFNT_CHAR8,
3040  (int32)strlen(counts_units),counts_units) == FAIL)
3041  {
3042  returnStatus = MODIS_F_WRITE_ERROR;
3043  sprintf(errmsg, errmsgfmt, "corrected_counts_units", (long)R);
3044  L1BErrorMsg(location, returnStatus, errmsg,
3045  "SDsetattr", 0, NULL, False);
3046  return returnStatus;
3047  }
3048  }
3049 
3050  } /*R*/
3051 
3052  return(MODIS_S_OK);
3053 }
3054 
3055 PGSt_SMF_status Create_Band_Subsetting_SDS(L1B_granule_t *L1B_Gran,
3056  boolean skip_night_hi_res)
3057 /*
3058 !C**********************************************************************
3059 !Description: For each of the L1B output granule files, this routine
3060  creates band-subsetting SDSs, writes the
3061  numerical equivalents of the band values and writes
3062  long-name attributes for each. Note that this creates new
3063  SDSs, independent of the Swath data fields (which are
3064  implemented as Vdata, not as SDSs).
3065 
3066 !Input Parameters:
3067  L1B_Gran (->sd_id[]) SD file interface ID for all L1B EV files.
3068  boolean skip_night_hi_res True if and only if all scans are
3069  night mode scans and writing of 250m
3070  and 500m night mode granules has been
3071  turned off
3072 !Output Parameters:
3073  None
3074 
3075 !Revision History:
3076  (continue at top of the file)
3077 
3078  Revision 01.04 January 17, 2002 Razor Issue #171
3079  Improve portability of code to 64-bit mode.
3080  Cast strlen returns to int32 in calls to SDSetattr.
3081  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
3082 
3083  Revision 01.03 November 16, 2001 Razor Issue #169
3084  Added boolean skip_night_hi_res to input parameters and altered logic so that
3085  if skip_night_hi_res is True, output data sets for 250m and 500m resolution
3086  data are not created.
3087  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
3088 
3089  Revision 01.02 Feb 12, 1999
3090  Formed this by including the loop through L1B output files in
3091  Write_Subsetting_SDS and changing the name to an appropriate name.
3092  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
3093 
3094  Revision 01.01 Feb 10, 1999
3095  Made the Band_subsetting_names variable a global at top of file so that the
3096  same names can be used in create Swath. Used the L1B_EV_DIM_NAME variable
3097  for dimension name rather than re-defining it here. Added SDendaccess.
3098  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
3099 
3100  Revision 01.00 1998
3101  Initial development
3102  Zhenying Gu(zgu@ltpmail.gsfc.nasa.gov)
3103 
3104 !Team-unique Header:
3105 
3106 !References and Credits:
3107  This software is developed by the MODIS Characterization Support
3108  Team (MCST)for the National Aeronautics and Space Administration,
3109  Goddard Space Flight Center, under contract NAS5-32373.
3110 
3111  HDF portions developed at the National Center for Supercomputing
3112  Applications at the University of Illinois at Urbana-Champaign.
3113 
3114 !Design Notes:
3115  file index res. # bnd. sub. SDSs
3116  ---------- ------ ---------------
3117  0 250m 1
3118  1 500m 2
3119  2 1km 4
3120 
3121 !END********************************************************************
3122 */
3123 {
3124  PGSt_SMF_status returnStatus;
3125  char *location = "Create_Band_Subsetting_SDS";
3126  int32 f;
3127  int32 hdf_return;
3128  int32 sds_index;
3129  int32 sds_id;
3130  int32 num_sds = 0;
3131  int32 R = 0;
3132  int32 dims[NUM_L1A_RESOLUTIONS] = {2, 5, 15, 16};
3133  float32 data_250m[2] = {1, 2};
3134  float32 data_500m[5] = {3, 4, 5, 6, 7};
3135  float32 data_1km_refl[15] = {8, 9, 10, 11, 12, 13, 13.5, 14, 14.5, 15,
3136  16, 17, 18, 19, 26};
3137  float32 data_1km_emiss[16] = {20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31,
3138  32, 33, 34, 35, 36};
3139  float32 *data[NUM_L1A_RESOLUTIONS];
3140  char *SDS_LongName[NUM_L1A_RESOLUTIONS] =
3141  {
3142  "250M Band Numbers for Subsetting",
3143  "500M Band Numbers for Subsetting",
3144  "1KM Reflective Solar Band Numbers for Subsetting",
3145  "1KM Emissive Band Numbers for Subsetting"
3146  };
3147  int32 evfile_luns[NUM_L1B_EV_FILES] = {
3151  };
3152  char errmsg[256];
3153  int16 start_output_res = INDEX_L1B_250m;
3154 
3155  data[0] = data_250m;
3156  data[1] = data_500m;
3157  data[2] = data_1km_refl;
3158  data[3] = data_1km_emiss;
3159 
3160  /*
3161  * If we are in night mode and we do not wish to write 250m and
3162  * 500m data sets, start with the 1KM output data sets.
3163  */
3164 
3165  if (skip_night_hi_res == True)
3166  start_output_res = INDEX_L1B_1km;
3167  else
3168  start_output_res = INDEX_L1B_250m;
3169 
3170  for (f = start_output_res; f < NUM_L1B_EV_FILES; f++)
3171  {
3172 
3173  num_sds = f + 1;
3174  if (f == INDEX_L1B_1km)
3175  num_sds++;
3176 
3177  for (R = 0; R < num_sds; R++)
3178  {
3179 
3180  returnStatus = write_sds_rank1(L1B_Gran->sd_id[f],
3182  L1B_EV_DIM_NAME[R][0], dims[R],
3183  "float32", data[R]);
3184  if(returnStatus != MODIS_S_OK)
3185  {
3186  L1BErrorMsg(location, returnStatus, NULL,
3187  "write_sds_rank1", evfile_luns[f], NULL, True);
3188  return returnStatus;
3189  }
3190 
3191  sds_index = SDnametoindex(L1B_Gran->sd_id[f],
3193  if(sds_index == FAIL)
3194  {
3195  sprintf(errmsg, "Could not get SDS index of \"%s\".",
3197  returnStatus = MODIS_F_HDF_ERROR;
3198  L1BErrorMsg(location, returnStatus, errmsg,
3199  "SDnametoindex", evfile_luns[f], NULL, True);
3200  return returnStatus;
3201  }
3202 
3203  sds_id = SDselect(L1B_Gran->sd_id[f], sds_index);
3204  if(sds_id == FAIL)
3205  {
3206  sprintf(errmsg, "Could not get SDS ID for \"%s\".",
3208  returnStatus = MODIS_F_HDF_ERROR;
3209  L1BErrorMsg(location, returnStatus, errmsg,
3210  "SDselect", evfile_luns[f], NULL, True);
3211  return returnStatus;
3212  }
3213 
3214  if(SDsetattr(sds_id, "long_name", DFNT_CHAR8,
3215  (int32)strlen(SDS_LongName[R]),
3216  (VOIDP)SDS_LongName[R]) == FAIL)
3217  {
3218  sprintf(errmsg,
3219  "Could not write long_name attribute for SDS \"%s\".",
3221  returnStatus = MODIS_F_WRITE_ERROR;
3222  L1BErrorMsg(location, returnStatus, errmsg,
3223  "SDsetattr", evfile_luns[f], NULL, True);
3224  return returnStatus;
3225  }
3226 
3227  hdf_return = SDendaccess(sds_id);
3228  if (hdf_return == FAIL)
3229  {
3230  sprintf(errmsg, "Could not end access to SDS \"%s\".",
3232  returnStatus = MODIS_F_HDF_ERROR;
3233  L1BErrorMsg(location, returnStatus, errmsg,
3234  "SDendaccess", evfile_luns[f], NULL, True);
3235  return returnStatus;
3236  }
3237 
3238  } /* R */
3239  } /* f */
3240  return(MODIS_S_OK);
3241 }
3242 
3243 PGSt_SMF_status Copy_Geo_SDS (L1B_granule_t *L1B_Gran,
3244  boolean skip_night_hi_res)
3245 
3246 /*
3247 !C****************************************************************
3248 !Description:
3249  Read subsampled SDSs from geolocation file and write those data and
3250  their attributes into the 1km L1B file. For the 250m and 500m L1B
3251  granules, read and write the full geolocation latitude and longitude
3252  SDS (but not others). Only the units, valid_range and fill-value
3253  attributes are written to the 250m and 500m granules. Note that SDSs
3254  have been previously created (in function Create_L1B_Swath), but open
3255  access, read/write, and end access, are performed for both input and
3256  output here.
3257 
3258 !Input Parameters:
3259  L1B_granule_t *L1B_Gran
3260  boolean skip_night_hi_res True if and only if all scans are
3261  night mode scans and writing of 250m
3262  and 500m night mode granules has been
3263  turned off
3264 
3265 !Output Parameters:
3266  L1B_granule_t *L1B_Gran
3267 
3268 !Revision History:
3269  (continue at top of the file)
3270 
3271  Revision 02.14 March 27, 2003 Razor Issue #173
3272  Iinitialized both "attr_name" and "attr_value" to NULL for ANSI-C compliance.
3273  Liqin Tan, SAIC GSO (ltan@saicmodis.com)
3274 
3275  Revision 02.13 November 16, 2001 Razor Issue #169
3276  Added boolean skip_night_hi_res to input parameters and altered logic
3277  so that if skip_night_hi_res is True, output data sets for 250m and
3278  500m resolution data are not created.
3279  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
3280 
3281  Revision 02.12, Feb 22, 1999
3282  Moved calculations of Nadir_Frame ... to Scan_Meta_Cal, deleted
3283  L1B_ScanMeta from argument list since no longer needed.
3284  Jim Rogers (rogers@msct.gsfc.nasa.gov)
3285 
3286  Revision 02.11, Feb 19, 1999
3287  Added SDendaccess for the L1B sds_ids in the loop through 250m and
3288  500m files when writing the lat and long SDSs.
3289  Also, for the geo_sds_id in the 1st loop through isds, the SDendaccess
3290  was moved to be just before the end-loop curly brace (after the loop
3291  through L1B granules).
3292  Jim Rogers (rogers@msct.gsfc.nasa.gov)
3293 
3294  Revision 02.10 Oct. 1997
3295  Modified to copy SDS attributes instead of write.
3296  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
3297 
3298  Revision 02.00 April 1997
3299  Modified to match some changes in data structures.
3300  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
3301 
3302  Revision 01.00 1997/02/23
3303  Initial development
3304  Neal Devine(neal.devine@gsfc.nasa.gov)
3305 
3306 !Team-unique Header:
3307  This software is developed by the MODIS Characterization Support
3308  Team (MCST)for the National Aeronautics and Space Administration,
3309  Goddard Space Flight Center, under contract NAS5-32373.
3310 
3311 !References and Credits:
3312  HDF portions developed at the National Center for Supercomputing
3313  Applications at the University of Illinois at Urbana-Champaign.
3314 
3315 !Design Notes:
3316 
3317 !END********************************************************************
3318 */
3319 {
3320  PGSt_SMF_status returnStatus = MODIS_S_OK;
3321  char *location = "Copy_Geo_SDS";
3322  PGSt_integer Version = 1;
3323  char fname[512];
3324  int32 geo_sd_id = 0;
3325  geo_sds_index_t isds = INDEX_LATITUDE; /*Geo sds index*/
3326  int16 i = 0; /*generic index*/
3327  int32 geo_sds_index = 0; /*Geo sds index in hdf file*/
3328  int32 geo_sds_id = 0;
3329  int32 geo_attr_index = 0;
3330  int32 L1B_sds_index = 0;
3331  int32 L1B_sds_id = 0;
3332  int32 geo_start[2] = {GEO_OFFSET, GEO_OFFSET};
3333  int32 geo_stride[2] = {GEO_STRIDE, GEO_STRIDE};
3334  int32 start[2] = {0, 0};
3335  int32 edge[2] = {0, 0};
3336  intn hdf_return = FAIL;
3337  int32 evfile_luns[NUM_L1B_EV_FILES]
3338  = {
3342  };
3343 
3344  /* these two are used for setting gflags attributes */
3345  char *attr_name = NULL;
3346  char *attr_value = NULL;
3347 
3348 #define MAX_ATTR_NAME_SIZE 26
3349 #define MAX_ATTR_BUFFER_SIZE 72
3350 
3351  /* used in SDattrinfo() */
3352  char attr_name_buffer[MAX_ATTR_NAME_SIZE];
3353 
3354  int32 attr_data_type = 0;
3355  int32 attr_count = 0;
3356  char attr_buffer[MAX_ATTR_BUFFER_SIZE];
3357  float32 *buffer;
3358  buffer = malloc(10 * MAX_NUM_SCANS * EV_1km_FRAMES * sizeof(float32));
3359  char errmsg[256];
3360 
3361 
3362 #define COPY_ATTR(attr_name) \
3363  geo_attr_index = SDfindattr(geo_sds_id, attr_name); \
3364  if (geo_attr_index == FAIL) \
3365  { \
3366  sprintf(errmsg, "Could not get attribute index for \"%s\".", \
3367  attr_name); \
3368  returnStatus = MODIS_F_READ_ERROR; \
3369  L1BErrorMsg(location, returnStatus, errmsg, \
3370  "SDfindattr", GEOLOCATION_FILE, NULL, True); \
3371  return returnStatus; \
3372  } \
3373  hdf_return = SDattrinfo(geo_sds_id, geo_attr_index, attr_name_buffer, \
3374  &attr_data_type, &attr_count); \
3375  if (hdf_return == FAIL) \
3376  { \
3377  sprintf(errmsg, "Could not get attribute info for \"%s\".", \
3378  attr_name); \
3379  returnStatus = MODIS_F_HDF_ERROR; \
3380  L1BErrorMsg(location, returnStatus, errmsg, \
3381  "SDattrinfo", GEOLOCATION_FILE, NULL, True); \
3382  return returnStatus; \
3383  } \
3384  hdf_return = SDreadattr(geo_sds_id, geo_attr_index, \
3385  (void *)attr_buffer); \
3386  if (hdf_return == FAIL) \
3387  { \
3388  sprintf(errmsg, "Could not read attribute \"%s\".", attr_name); \
3389  returnStatus = MODIS_F_READ_ERROR; \
3390  L1BErrorMsg(location, returnStatus, errmsg, \
3391  "SDreadattr", GEOLOCATION_FILE, NULL, True); \
3392  return returnStatus; \
3393  } \
3394  hdf_return = SDsetattr(L1B_sds_id, attr_name, attr_data_type, \
3395  attr_count, (void *)attr_buffer); \
3396  if (hdf_return == FAIL) \
3397  { \
3398  sprintf(errmsg, "Could not write attribute \"%s\".", attr_name); \
3399  returnStatus = MODIS_F_WRITE_ERROR; \
3400  L1BErrorMsg(location, returnStatus, errmsg, \
3401  "SDsetattr", evfile_luns[i], NULL, True); \
3402  return returnStatus; \
3403  }
3404 
3405  /* Get Geoloc file name */
3406 
3407  Version = 1;
3408  if ( PGS_PC_GetReference(GEOLOCATION_FILE, &Version, fname) !=
3409  PGS_S_SUCCESS )
3410  {
3411  returnStatus = MODIS_F_FILE_NOT_FOUND;
3412  L1BErrorMsg(location, returnStatus,
3413  "Could not retrieve file name from PCF.",
3414  "PGS_PC_GetReference", GEOLOCATION_FILE, NULL, True);
3415  return returnStatus;
3416  }
3417 
3418  /* Open geolocation file */
3419 
3420  geo_sd_id = SDstart(fname, DFACC_RDONLY);
3421  if (geo_sd_id == FAIL)
3422  {
3423  returnStatus = MODIS_F_FILE_NOT_OPENED;
3424  L1BErrorMsg(location, returnStatus,
3425  "Could not open file for SD read access.",
3426  "SDstart", GEOLOCATION_FILE,
3427  "The file may be missing, corrupted or "
3428  "not an HDF-4 file.", True);
3429  return returnStatus;
3430  }
3431 
3432  /* loop over all Geo_SDSs. This first loop is for L1B EV 250m
3433  * and EV 500m granules only, so if skip_night_hi_res is True, will not
3434  * be executed.
3435  */
3436 
3437  if (skip_night_hi_res == False)
3438  {
3439  edge[0] = 10 * L1B_Gran->num_scans;
3440  edge[1] = EV_1km_FRAMES ;
3441 
3442  for (isds = INDEX_LATITUDE; isds < INDEX_HEIGHT; isds++)
3443  {
3444  geo_sds_index = SDnametoindex(geo_sd_id, GEO_SDS[isds].src_name);
3445  if (geo_sds_index == FAIL)
3446  {
3447  sprintf(errmsg, "Could not get SDS index of \"%s\".",
3448  GEO_SDS[isds].src_name);
3449  returnStatus = MODIS_F_READ_ERROR;
3450  L1BErrorMsg(location, returnStatus, errmsg,
3451  "SDnametoindex", GEOLOCATION_FILE, NULL, True);
3452  return returnStatus;
3453  }
3454 
3455  geo_sds_id = SDselect(geo_sd_id, geo_sds_index);
3456  if (geo_sds_id == FAIL)
3457  {
3458  sprintf(errmsg, "Could not get SDS ID for \"%s\".",
3459  GEO_SDS[isds].src_name);
3460  returnStatus = MODIS_F_HDF_ERROR;
3461  L1BErrorMsg(location, returnStatus, errmsg,
3462  "SDselect", GEOLOCATION_FILE, NULL, True);
3463  return returnStatus;
3464  }
3465 
3466  hdf_return = SDreaddata(geo_sds_id, start, NULL, edge,
3467  (void *)buffer);
3468  if (hdf_return == FAIL)
3469  {
3470  sprintf(errmsg, "Could not read data for SDS \"%s\".",
3471  GEO_SDS[isds].src_name);
3472  returnStatus = MODIS_F_READ_ERROR;
3473  L1BErrorMsg(location, returnStatus, errmsg,
3474  "SDreaddata", GEOLOCATION_FILE, NULL, True);
3475  return returnStatus;
3476  }
3477 
3478  for (i = INDEX_L1B_250m; i < INDEX_L1B_1km; i++)
3479  {
3480  L1B_sds_index = SDnametoindex(L1B_Gran->sd_id[i],
3481  GEO_SDS[isds].name);
3482  if (L1B_sds_index == FAIL)
3483  {
3484  sprintf(errmsg, "Could not get SDS index of \"%s\".",
3485  GEO_SDS[isds].name);
3486  returnStatus = MODIS_F_HDF_ERROR;
3487  L1BErrorMsg(location, returnStatus, errmsg,
3488  "SDnametoindex", evfile_luns[i], NULL, True);
3489  return returnStatus;
3490  }
3491 
3492  L1B_sds_id = SDselect(L1B_Gran->sd_id[i], L1B_sds_index);
3493  if (L1B_sds_id == FAIL)
3494  {
3495  sprintf(errmsg, "Could not get SDS ID for \"%s\".",
3496  GEO_SDS[isds].name);
3497  returnStatus = MODIS_F_HDF_ERROR;
3498  L1BErrorMsg(location, returnStatus, errmsg,
3499  "SDselect", evfile_luns[i], NULL, True);
3500  return returnStatus;
3501  }
3502 
3503  hdf_return = SDwritedata(L1B_sds_id, start,
3504  NULL, edge, (void *)buffer);
3505  if (hdf_return == FAIL)
3506  {
3507  sprintf(errmsg, "Could not write SDS \"%s\".",
3508  GEO_SDS[isds].name);
3509  returnStatus = MODIS_F_WRITE_ERROR;
3510  L1BErrorMsg(location, returnStatus, errmsg,
3511  "SDwritedata", evfile_luns[i], NULL, True);
3512  return returnStatus;
3513  }
3514 
3515  COPY_ATTR("units");
3516  COPY_ATTR("valid_range");
3517  COPY_ATTR("_FillValue");
3518 
3519  /* Done with this L1B_sds_id
3520  */
3521  hdf_return = SDendaccess(L1B_sds_id);
3522  if (hdf_return == FAIL)
3523  {
3524  sprintf(errmsg, "Could not end access for SDS \"%s\".",
3525  GEO_SDS[isds].name);
3526  returnStatus = MODIS_F_HDF_ERROR;
3527  L1BErrorMsg(location, returnStatus, errmsg,
3528  "SDendaccess", evfile_luns[i], NULL, True);
3529  return returnStatus;
3530  }
3531 
3532  }
3533 
3534  /* End access for this geolocation SDS.
3535  */
3536  hdf_return = SDendaccess(geo_sds_id);
3537  if (hdf_return == FAIL)
3538  {
3539  sprintf(errmsg, "Could not end access for SDS \"%s\".",
3540  GEO_SDS[isds].src_name);
3541  returnStatus = MODIS_F_HDF_ERROR;
3542  L1BErrorMsg(location, returnStatus, errmsg,
3543  "SDendaccess", GEOLOCATION_FILE, NULL, True);
3544  return returnStatus;
3545  }
3546 
3547  } /* for (isds = INDEX_LATITUDE; isds < INDEX_HEIGHT; isds++) */
3548  } /* if (skip_night_hi_res == False) */
3549 
3550  /* Loop through all geolocations SDSs. This loop is for the
3551  * L1B EV 1km granule.
3552  */
3553 
3554  edge[0] = 2 * L1B_Gran->num_scans;
3555  edge[1] = 1 + (EV_1km_FRAMES - 3) / 5;
3556 
3557  for (isds = INDEX_LATITUDE; isds < NUM_GEO_SDS; isds++)
3558  {
3559  /* Open a geo sds */
3560 
3561  geo_sds_index = SDnametoindex(geo_sd_id, GEO_SDS[isds].src_name);
3562  if (geo_sds_index == FAIL)
3563  {
3564  sprintf(errmsg, "Could not get SDS index of \"%s\".",
3565  GEO_SDS[isds].src_name);
3566  returnStatus = MODIS_F_READ_ERROR;
3567  L1BErrorMsg(location, returnStatus, errmsg,
3568  "SDnametoindex", GEOLOCATION_FILE, NULL, True);
3569  return returnStatus;
3570  }
3571 
3572  geo_sds_id = SDselect(geo_sd_id, geo_sds_index);
3573  if (geo_sds_id == FAIL)
3574  {
3575  sprintf(errmsg, "Could not get SDS ID for \"%s\".",
3576  GEO_SDS[isds].src_name);
3577  returnStatus = MODIS_F_HDF_ERROR;
3578  L1BErrorMsg(location, returnStatus, errmsg,
3579  "SDselect", GEOLOCATION_FILE, NULL, True);
3580  return returnStatus;
3581  }
3582 
3583  /* Open an L1B sds */
3584 
3585  L1B_sds_index = SDnametoindex(L1B_Gran->sd_id[INDEX_L1B_1km],
3586  GEO_SDS[isds].name);
3587  if (L1B_sds_index == FAIL)
3588  {
3589  sprintf(errmsg, "Could not get SDS index of \"%s\".",
3590  GEO_SDS[isds].name);
3591  returnStatus = MODIS_F_HDF_ERROR;
3592  L1BErrorMsg(location, returnStatus, errmsg,
3593  "SDnametoindex", evfile_luns[INDEX_L1B_1km], NULL, True);
3594  return returnStatus;
3595  }
3596 
3597  L1B_sds_id = SDselect(L1B_Gran->sd_id[INDEX_L1B_1km], L1B_sds_index);
3598  if (L1B_sds_id == FAIL)
3599  {
3600  sprintf(errmsg, "Could not get SDS ID for \"%s\".",
3601  GEO_SDS[isds].name);
3602  returnStatus = MODIS_F_HDF_ERROR;
3603  L1BErrorMsg(location, returnStatus, errmsg,
3604  "SDselect", evfile_luns[INDEX_L1B_1km], NULL, True);
3605  return returnStatus;
3606  }
3607 
3608  /* Read an sds from geo file into buffer */
3609 
3610  hdf_return = SDreaddata(geo_sds_id, geo_start, geo_stride,
3611  edge, (void *)buffer);
3612  if (hdf_return == FAIL)
3613  {
3614  sprintf(errmsg, "Could not read data for SDS \"%s\".",
3615  GEO_SDS[isds].src_name);
3616  returnStatus = MODIS_F_READ_ERROR;
3617  L1BErrorMsg(location, returnStatus, errmsg,
3618  "SDreaddata", GEOLOCATION_FILE, NULL, True);
3619  return returnStatus;
3620  }
3621 
3622  /* Write the sds stored in the buffer to L1B_1km file */
3623 
3624  hdf_return = SDwritedata(L1B_sds_id, start, NULL, edge, (void *)buffer);
3625  if (hdf_return == FAIL)
3626  {
3627  sprintf(errmsg, "Could not write SDS \"%s\".", GEO_SDS[isds].name);
3628  returnStatus = MODIS_F_WRITE_ERROR;
3629  L1BErrorMsg(location, returnStatus, errmsg,
3630  "SDwritedata", evfile_luns[INDEX_L1B_1km], NULL, True);
3631  return returnStatus;
3632  }
3633 
3634  /*
3635  * Copy attributes:
3636  * copy units, valid_range, _FillValue for all sdss except gflags,
3637  * and scale_factor for all except Latitude and Longitude and gflags
3638  * Set other attributes:
3639  * set line_numbers and frame_numbers for all sdss except gflags
3640  */
3641 
3642  if (isds != INDEX_GFLAGS)
3643  {
3644  i = INDEX_L1B_1km; /* to set correct lun in the macro */
3645  COPY_ATTR("units");
3646  COPY_ATTR("valid_range");
3647  COPY_ATTR("_FillValue");
3648 
3649  if (isds > INDEX_HEIGHT)
3650  {
3651  COPY_ATTR("scale_factor");
3652  }
3653 
3654  hdf_return = SDsetattr(L1B_sds_id, "line_numbers", DFNT_CHAR8,
3655  (int32)strlen("3,8"), (VOIDP)"3,8");
3656  if (hdf_return == FAIL)
3657  {
3658  sprintf(errmsg, "Could not write attribute \"line_numbers\" "
3659  "to SDS \"%s\".",
3660  GEO_SDS[isds].name);
3661  returnStatus = MODIS_F_WRITE_ERROR;
3662  L1BErrorMsg(location, returnStatus, errmsg,
3663  "SDsetattr", evfile_luns[INDEX_L1B_1km], NULL, True);
3664  return returnStatus;
3665  }
3666 
3667  hdf_return = SDsetattr(L1B_sds_id, "frame_numbers", DFNT_CHAR8,
3668  (int32)strlen("3,8,13,..."),
3669  (VOIDP)"3,8,13,...");
3670  if (hdf_return == FAIL)
3671  {
3672  sprintf(errmsg, "Could not write attribute \"frame_numbers\" "
3673  "to SDS \"%s\".",
3674  GEO_SDS[isds].name);
3675  returnStatus = MODIS_F_WRITE_ERROR;
3676  L1BErrorMsg(location, returnStatus, errmsg,
3677  "SDsetattr", evfile_luns[INDEX_L1B_1km],
3678  NULL, True);
3679  return returnStatus;
3680  }
3681  }
3682  else
3683  {
3684  i = INDEX_L1B_1km; /* to set correct lun in the macro */
3685  COPY_ATTR("_FillValue");
3686  for (i = 0; i < 5; i++)
3687  {
3688  switch(i)
3689  {
3690  case 0: attr_name = "Bit 7(MSB)";
3691  attr_value = "1 = invalid input data";
3692  break;
3693  case 1: attr_name = "Bit 6";
3694  attr_value = "1 = no ellipsoid intersection";
3695  break;
3696  case 2: attr_name = "Bit 5";
3697  attr_value = "1 = no valid terrain data";
3698  break;
3699  case 3: attr_name = "Bit 4";
3700  attr_value = "1 = DEM missing or of inferior quality";
3701  break;
3702  case 4: attr_name = "Bit 3";
3703  attr_value = "1 = invalid sensor range";
3704  }
3705  hdf_return = SDsetattr(L1B_sds_id, attr_name, DFNT_CHAR8,
3706  (int32)strlen(attr_value), attr_value);
3707  if (hdf_return == FAIL)
3708  {
3709  sprintf(errmsg,
3710  "Could not write attribute \"%s\" to SDS \"%s\".",
3711  attr_name, GEO_SDS[isds].name);
3712  returnStatus = MODIS_F_WRITE_ERROR;
3713  L1BErrorMsg(location, returnStatus, errmsg,
3714  "SDsetattr", evfile_luns[INDEX_L1B_1km], NULL, True);
3715  return returnStatus;
3716  }
3717  }
3718  }
3719 
3720  /* Done with this geo_sds */
3721 
3722  hdf_return = SDendaccess(geo_sds_id);
3723  if (hdf_return == FAIL)
3724  {
3725  sprintf(errmsg, "Could not end access for SDS \"%s\".",
3726  GEO_SDS[isds].src_name);
3727  returnStatus = MODIS_F_HDF_ERROR;
3728  L1BErrorMsg(location, returnStatus, errmsg,
3729  "SDendaccess", GEOLOCATION_FILE, NULL, True);
3730  return returnStatus;
3731  }
3732 
3733  /* Done with this L1B_sds */
3734 
3735  hdf_return = SDendaccess(L1B_sds_id);
3736  if (hdf_return == FAIL)
3737  {
3738  sprintf(errmsg, "Could not end access for SDS \"%s\".",
3739  GEO_SDS[isds].name);
3740  returnStatus = MODIS_F_HDF_ERROR;
3741  L1BErrorMsg(location, returnStatus, errmsg,
3742  "SDendaccess", evfile_luns[INDEX_L1B_1km], NULL, True);
3743  return returnStatus;
3744  }
3745 
3746  } /* for (isds = INDEX_LATITUDE; isds < NUM_GEO_SDS; isds++) */
3747 
3748  /* Done with the geo file */
3749 
3750  hdf_return = SDend(geo_sd_id);
3751  if (hdf_return == FAIL)
3752  {
3753  returnStatus = MODIS_F_HDF_ERROR;
3754  L1BErrorMsg(location, returnStatus, NULL, "SDend",
3756  "Memory or the disk file must have become corrupted.",
3757  True);
3758  return returnStatus;
3759  }
3760 
3761  free(buffer);
3762 
3763  return(MODIS_S_OK);
3764 }
3765 
3767  L1A_granule_t *L1A_Gran,
3768  L1B_granule_t *L1B_Gran,
3769  L1B_Scan_Metadata_t *L1B_Scan_Meta,
3770  QA_Data_t *QA)
3771 /*
3772 !C****************************************************************
3773 !Description:
3774  This routine assigns members of the L1B_Scan_Meta to be written to
3775  the L1B EV files later in Write_L1B_ScanMeta. Values already
3776  determined are simply assigned while other data, such as telemetry
3777  and SRCA calibration mode, are read in from the L1A granule and
3778  then assigned.
3779 
3780 !Input Parameters:
3781  L1A_granule_t *L1A_Gran
3782  L1B_granule_t *L1B_Gran
3783  QA_Data_t *QA
3784 !Output Parameters:
3785  L1B_Scan_Metadata_t *L1B_Scan_Meta
3786  QA_Data_t *QA
3787 !Revision History:
3788  (continue at top of the file)
3789 
3790  Revision 01.06 October 24, 2003 Razor Issue #196 (formerly Issue #184)
3791  All changes are in the function "Scan_Meta_Cal". Added parameter "tables",
3792  array "Attitude_Angles", and constant "rtod". Moved the code which opens the
3793  geolocation file to just before the Scan-by-Scan loop which sets bit flags.
3794  Added the code which reads "Attitude_Angles" from the geolocation file.
3795  Changed the setting of QA flag bit 1 (Spacecraft Maneuver) so that the code
3796  will check the attitude angles against their threshold angles in the QA LUT.
3797  If any one of them is more than its threshold angle set the "maneuver" bit
3798  for that scan. Added a new "Sci Abnormal" bit (bit 26) which is set when
3799  SS_FR_SCIABNORM was set (the way the "maneuver" flag is originaly set).
3800  Liqin Tan, SAIC GSO (ltan@saicmodis.com)
3801 
3802  Revision 01.05 April 23, 2003
3803  Changed the telemetry mnemonic which determines whether the nadir aperture
3804  door (NAD) is open from "CR_DR_NAD_OPEN" to the equivalent "CR_DR_NAD_CLSD"
3805  mnemonic and altered the L1B code logic to correctly use the new value. It
3806  was discovered that at two different times in the history of the MODIS/Terra
3807  instrument the mnemonic "CR_DR_NAD_OPEN" did not correctly reflect the state
3808  of the NAD, whereas the mnemonic "CR_DR_NAD_CLSD" has been consistently
3809  reliable.
3810  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
3811 
3812  Revision 01.04 March 27, 2003 Razor Issue #173
3813  Enclosed the rows in the initializer of array-of-struct "temp" with braces
3814  for ANSI-C compliance.
3815  Liqin Tan, SAIC GSO (ltan@saicmodis.com)
3816 
3817  Revision 01.03 April 16, 2002 Razor Issue #166
3818  Added leading/trailing granule scan gap to bit QA flags.
3819  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
3820 
3821  Revision 01.02 August 26, 1999
3822  Added checking if the data read from L1A are valid.
3823  Zhenying Gu (zgu@mcst.gsfc.nasa.gov)
3824  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
3825 
3826  Revision 01.01 Feb 20, 1999
3827  Fixed some minor bugs. Moved the assignment of nadir frame values into
3828  macro NADIR_FRAME_GEO_VALS. Moved the assignment of nadir frame
3829  latitude and longitude into here from Create_L1B_Swath to have all
3830  these in one place.
3831  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
3832 
3833  Revision 01.00 1998/4/8
3834  Original Development
3835  Zhenying Gu (zgu@gscmail.gsfc.nasa.gov)
3836 
3837 !Team-unique Header:
3838  This software is developed by the MODIS Characterization Support
3839  Team (MCST)for the National Aeronautics and Space Administration,
3840  Goddard Space Flight Center, under contract NAS5-32373.
3841 
3842 !References and Credits:
3843  HDF portions developed at the National Center for Supercomputing
3844  Applications at the University of Illinois at Urbana-Champaign.
3845 
3846 !Design Notes:
3847 
3848 !END********************************************************************
3849 */
3850 {
3851  PGSt_SMF_status returnStatus;
3852  PGSt_integer Version = 1;
3853  int32 geo_sd_id;
3854  char fname[512];
3855  int f = 0;
3856  int S = 0;
3857  int start_scan = 0;
3858  int16 *SRCA_mode;
3859  SRCA_mode = (int16*) malloc(MAX_NUM_SCANS * sizeof(int16));
3860  int16 *i16_buffer;
3861  i16_buffer = (int16*) malloc(10 * MAX_NUM_SCANS * EV_1km_FRAMES * sizeof(int16));
3862  float32 *f32_buffer;
3863  f32_buffer = (float32*) malloc(10 * MAX_NUM_SCANS * EV_1km_FRAMES * sizeof(float32));
3864  int32 buf_index = 0;
3865  float32 *SD_Sun_zenith;
3866  SD_Sun_zenith = (float32*) malloc(MAX_NUM_SCANS * sizeof(float32));
3867  float32 *SD_Sun_Azimuth;
3868  SD_Sun_Azimuth = (float32*) malloc(MAX_NUM_SCANS * sizeof(float32));
3869  float32 Z_MODIS;
3870  char *location = "Scan_Meta_Cal";
3871  char upper_bound_str[20];
3872  typedef float64 Attitude_Angles_t[NUM_ATTITUDE_ANGLES];
3873  Attitude_Angles_t *Attitude_Angles;
3874  Attitude_Angles = (Attitude_Angles_t*) malloc(MAX_NUM_SCANS * sizeof(Attitude_Angles_t));
3875  float32 rtod = 180.0/PGS_PI;
3876 
3877 
3878  enum {
3879  SCAN_SECTOR_ROTATION,
3880  PC_LW_A,
3881  PC_LW_B,
3882  PV_VIS_A,
3883  PV_VIS_B,
3884  PV_NIR_A,
3885  PV_NIR_B,
3886  PV_SW_A,
3887  PV_SW_B,
3888  PV_LW_A,
3889  PV_LW_B,
3890  SDSM_A,
3891  SDSM_B,
3892  RC_CSH,
3893  RC_ISH,
3894  RC_OSH,
3895  BB_HEATER_A,
3896  BB_HEATER_B,
3897  SD_DOOR,
3898  SD_SCREEN,
3899  SCI_ABNORM,
3900  NAD_DOOR,
3901  MACRO_ID,
3902  PCLW_ADC_PRI,
3903  PCLW_ADC_RED,
3904  NUM_FIELD
3905  }i;
3906  struct {
3907  char *vname; /*vdata_name*/
3908  char *fname; /*field_name*/
3909  /*data buffer; all eng_vdata are type of uint16*/
3910  uint16 buffer[MAX_NUM_SCANS];
3911  } temp[NUM_FIELD] = {
3912  /* XG 3/12/2015
3913  * use SET_FR_ENC_DELTA in the field Command Parameters to get the
3914  * sector rotation status
3915  */
3916  /*{"Telemetry Major Cycle 6 of 7", "CS_FR_ENC_DELTA", {0} },*/
3917  {"Command Parameters", "SET_FR_ENC_DELTA", {0} },
3918  {"Telemetry Major Cycle 4A of 7", "CR_PCLWA_ECAL_ON", {0} },
3919  {"Telemetry Major Cycle 4A of 7", "CR_PCLWB_ECAL_ON", {0} },
3920  {"Telemetry Major Cycle 4B of 7", "CR_PVVISA_ECALON", {0} },
3921  {"Telemetry Major Cycle 4B of 7", "CR_PVVISB_ECALON", {0} },
3922  {"Telemetry Major Cycle 4B of 7", "CR_PVNIRA_ECALON", {0} },
3923  {"Telemetry Major Cycle 4B of 7", "CR_PVNIRB_ECALON", {0} },
3924  {"Telemetry Major Cycle 4B of 7", "CR_PVSMA_ECAL_ON", {0} },
3925  {"Telemetry Major Cycle 4B of 7", "CR_PVSMB_ECAL_ON", {0} },
3926  {"Telemetry Major Cycle 4A of 7", "CR_PVLWA_ECAL_ON", {0} },
3927  {"Telemetry Major Cycle 4A of 7", "CR_PVLWB_ECAL_ON", {0} },
3928  {"Telemetry Major Cycle 5B of 7", "CR_SM_SDSM_A_ON", {0} },
3929  {"Telemetry Major Cycle 5B of 7", "CR_SM_SDSM_B_ON", {0} },
3930  {"Telemetry Major Cycle 5A of 7", "CR_RC_CSHTR_ON", {0} },
3931  {"Telemetry Major Cycle 5A of 7", "CR_RC_ISHTR_ON", {0} },
3932  {"Telemetry Major Cycle 5A of 7", "CR_RC_OSHTR_ON", {0} },
3933  {"Telemetry Major Cycle 0 of 7", "CR_BB_A_PWR_ON", {0} },
3934  {"Telemetry Major Cycle 0 of 7", "CR_BB_B_PWR_ON", {0} },
3935  {"Telemetry Major Cycle 3A of 7", "CR_DR_SDD_OPEN", {0} },
3936  {"Telemetry Major Cycle 3A of 7", "CR_DR_SDS_OPEN", {0} },
3937  {"Telemetry Major Cycle 1 of 7", "SS_FR_SCIABNORM", {0} },
3938  {"Telemetry Major Cycle 3A of 7", "CR_DR_NAD_CLSD", {0} },
3939  {"Telemetry Major Cycle All Part 3", "SS_CP_MACRO_ID", {0} },
3940  {"Telemetry Major Cycle 4A of 7" , "CR_PCLW_A_ON", {0} },
3941  {"Telemetry Major Cycle 4A of 7" , "CR_PCLW_B_ON", {0} }
3942  };
3943 
3944 /********************** MACRO NADIR_FRAME_GEO_VALS ************************
3945  For one geolocation SDS, this macro will read the data from the
3946  geolocation SDS (includes all scan lines and all frames) and assign
3947  one value for the nadir frame per scan to an appropriate variable
3948  in L1B_Scan_Meta. "geoname" is a string that is the name of the
3949  geolocation SDS and "var" is the variable to assign values to.
3950  "scalefactor" converts numbers in the SDS to match the units of the
3951  data. The geolocation file should already be open and the variable
3952  geo_sd_id should thus be valid. "buf" is the buffer (either int16
3953  or float 32) that we read data into. Lat and Long use float32, the
3954  others use int16.
3955 ****************************************************************************/
3956 #define NADIR_FRAME_GEO_VALS(geoname,var,scalefactor,buf) \
3957  returnStatus = read_sds_rank2(geo_sd_id, geoname, \
3958  10 * L1A_Gran->num_scans, \
3959  EV_1km_FRAMES, buf); \
3960  if (returnStatus != MODIS_S_OK) \
3961  { \
3962  L1BErrorMsg(location, returnStatus, NULL, \
3963  "read_sds_rank2", GEOLOCATION_FILE, NULL, True); \
3964  return returnStatus; \
3965  } \
3966  for (S = 0; S < L1A_Gran->num_scans; S++) { \
3967  buf_index = (S * 10 + 4) * EV_1km_FRAMES + NADIR_1km_FRAME_NUM - 1; \
3968  var[S] = buf[buf_index] * scalefactor; \
3969  }
3970 
3971  for (i = SCAN_SECTOR_ROTATION; i < NUM_FIELD; i++)
3972  {
3973  returnStatus = read_vdata (L1A_Gran->v_id,
3974  start_scan,
3975  L1A_Gran->num_scans,
3976  temp[i].vname,
3977  temp[i].fname,
3978  (VOIDP)temp[i].buffer);
3979  if (returnStatus != MODIS_S_OK)
3980  {
3981  L1BErrorMsg(location, returnStatus, NULL,
3982  "read_vdata", FIRST_L1A_GRANULE, NULL, True);
3983  return returnStatus;
3984  }
3985 
3986  if (i == MACRO_ID)
3987  strcpy(upper_bound_str, "31");
3988  else if (i == SCAN_SECTOR_ROTATION)
3989  strcpy(upper_bound_str, "16383");
3990  else
3991  strcpy(upper_bound_str, "1");
3992 
3993  returnStatus = Check_Valid_Range(temp[i].fname, DFNT_UINT16,
3994  NULL, upper_bound_str, NULL,
3995  L1A_Gran->num_scans,
3996  (void *) temp[i].buffer);
3997  if (returnStatus != MODIS_S_OK)
3998  {
3999  L1BErrorMsg(location, returnStatus, NULL, "Check_Valid_Range",
4001  return returnStatus;
4002  }
4003  }
4004 
4005 
4006  /*
4007  * Set the SRCA calibration mode based on macro ID. This will be a
4008  * more accurate determination than using the SDS "SRCA calibration
4009  * mode". If the mode is "undetermined", use the electronics
4010  * redundancy vector to determine if the SRCA is actually on or
4011  * off. If ON, then either the macro has not turned on yet or this
4012  * is a special SRCA event (not one of the normal OAs).
4013  */
4014 
4015 
4016  for (S = 0; S < L1A_Gran->num_scans; S++)
4017  {
4018  if (temp[MACRO_ID].buffer[S] == 15 ||
4019  temp[MACRO_ID].buffer[S] == 16 ||
4020  temp[MACRO_ID].buffer[S] == 17)
4021  SRCA_mode[S] = 0; /* Radiometric */
4022  else if (temp[MACRO_ID].buffer[S] == 18 ||
4023  temp[MACRO_ID].buffer[S] == 19 ||
4024  temp[MACRO_ID].buffer[S] == 20 ||
4025  temp[MACRO_ID].buffer[S] == 21)
4026  SRCA_mode[S] = 2; /* Spectral */
4027  else if (temp[MACRO_ID].buffer[S] == 22 ||
4028  temp[MACRO_ID].buffer[S] == 23 ||
4029  temp[MACRO_ID].buffer[S] == 24)
4030  SRCA_mode[S] = 1; /* Spatial */
4031  else
4032  SRCA_mode[S] = 3; /* undetermined */
4033  }
4034 
4035  /* calculate Nadir frame quantities and assign to L1B_Scan_Meta */
4036 
4037  if (PGS_PC_GetReference(GEOLOCATION_FILE, &Version, fname) !=
4038  PGS_S_SUCCESS)
4039  {
4040  returnStatus = MODIS_F_FILE_NOT_FOUND;
4041  L1BErrorMsg(location, returnStatus,
4042  "Could not retrieve file name from PCF.",
4043  "PGS_PC_GetReference", GEOLOCATION_FILE, NULL, True);
4044  return returnStatus;
4045  }
4046 
4047  /* Open geolocation file
4048  */
4049  geo_sd_id = SDstart(fname, DFACC_RDONLY);
4050  if (geo_sd_id == FAIL)
4051  {
4052  returnStatus = MODIS_F_FILE_NOT_OPENED;
4053  L1BErrorMsg(location, returnStatus,
4054  "Could not open file for SD read access.",
4055  "SDstart", GEOLOCATION_FILE,
4056  "The file may be missing, corrupted or "
4057  "not an HDF-4 file.", True);
4058  return returnStatus;
4059  }
4060 
4061  /* Read s/c attitude angles */
4062  returnStatus = read_sds_rank2(geo_sd_id, "attitude_angles",
4063  L1A_Gran->num_scans,
4064  NUM_ATTITUDE_ANGLES, Attitude_Angles);
4065  if (returnStatus != MODIS_S_OK)
4066  {
4067  L1BErrorMsg(location, returnStatus, NULL, "read_sds_rank2",
4069  return returnStatus;
4070  }
4071 
4072  for (S = 0; S < L1A_Gran->num_scans; S++)
4073  {
4074  /* initialize all bits to zero */
4075 
4076  L1B_Scan_Meta->Bit_QA_Flags[S] = 0;
4077 
4078  /* bit 0: Moon within defined limits of SVP */
4079 
4082  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00000001;
4083 
4084  /* bit 1: Spacecraft Maneuver */
4085 
4086  if ( fabs((double) (Attitude_Angles[S][0]))*rtod >
4087  tables->QA.common_QA_tables.roll_threshold_angle ||
4088  fabs((double) (Attitude_Angles[S][1]))*rtod >
4089  tables->QA.common_QA_tables.pitch_threshold_angle ||
4090  fabs((double) (Attitude_Angles[S][2]))*rtod >
4091  tables->QA.common_QA_tables.yaw_threshold_angle )
4092  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00000002;
4093 
4094  /* bit 2: Sector Rotation */
4095 
4096  if ( temp[SCAN_SECTOR_ROTATION].buffer[S])
4097  {
4098  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00000004;
4099  QA->QA_common.Sector_Rotation[S] = True;
4100  }
4101  else
4102  QA->QA_common.Sector_Rotation[S] = False;
4103 
4104  /* Set QA flag for both PCLW A and B on */
4105  if ( temp[PCLW_ADC_PRI].buffer[S] == 1 && temp[PCLW_ADC_RED].buffer[S] == 1)
4106  {
4108  }
4109  else
4111 
4112 
4113  /* bit 3: Negative Radiance Beyond Noise Level, is set in Emissive_Cal. */
4114 
4115  /* bit 4: PC Ecal on */
4116 
4117  if (temp[PC_LW_A].buffer[S] || temp[PC_LW_B].buffer[S])
4118  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00000010;
4119 
4120  /* bit 5: PV Ecal on */
4121 
4122  if (temp[PV_VIS_A].buffer[S] || temp[PV_VIS_B].buffer[S]
4123  || temp[PV_NIR_A].buffer[S] || temp[PV_NIR_B].buffer[S]
4124  || temp[PV_SW_A].buffer[S] || temp[PV_SW_B].buffer[S]
4125  || temp[PV_LW_A].buffer[S] || temp[PV_LW_B].buffer[S])
4126  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00000020;
4127 
4128  /* bit 6: SD Door Open */
4129 
4130  if (temp[SD_DOOR].buffer[S] == 1)
4131  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00000040;
4132 
4133  /* bit 7: SD Screen Down */
4134 
4135  if (temp[SD_SCREEN].buffer[S] == 0)
4136  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00000080;
4137 
4138  /*
4139  * check NAD door open and this will be used in Reflective_Cal
4140  * and Emissive_Cal
4141  */
4142 
4143  if (temp[NAD_DOOR].buffer[S] == 0)
4144  QA->QA_common.NAD_Door_Open[S] = True;
4145  else
4146  {
4147  QA->QA_common.NAD_Door_Open[S] = False;
4148 
4149  /* bit 8: NAD closed. Added by CCR-508. */
4150 
4151  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00000100;
4152  }
4153 
4154  /* bit 9: SDSM on */
4155 
4156  if (temp[SDSM_A].buffer[S] || temp[SDSM_B].buffer[S])
4157  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00000200;
4158 
4159  /* bit 10: Radcooler Heaters On */
4160 
4161  if (temp[RC_CSH].buffer[S] || temp[RC_ISH].buffer[S]
4162  || temp[RC_OSH].buffer[S])
4163  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00000400;
4164 
4165  /*
4166  * bit 11: Day mode bands telemetered at night. Added by CCR-508.
4167  * It is set at the end of this function.
4168  */
4169 
4170  /*
4171  * bit 12: Linear Emissive Calibration.
4172  * The current emissive algorithm is non-linear. So it is not set.
4173  */
4174 
4175  /* bit 13: DC Restore Change. Set in Calculate_DCR_Change() */
4176 
4177  /* bit 14: Unused. */
4178 
4179  /* bit 15: BB Heater on */
4180  if (temp[BB_HEATER_A].buffer[S] || temp[BB_HEATER_B].buffer[S])
4181  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00008000;
4182 
4183  /* bit 16: Missing Leading Granule */
4184 
4186  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00010000;
4187 
4188  /* bit 17: Missing Trailing Granule */
4189 
4191  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00020000;
4192 
4193  /* bit 18, 19: SRCA calibration mode */
4194 
4195  if (SRCA_mode[S] == 2 || SRCA_mode[S] == 3 || SRCA_mode[S] == -1)
4196  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00040000;
4197  if (SRCA_mode[S] == 1 || SRCA_mode[S] == 3 || SRCA_mode[S] == -1)
4198  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00080000;
4199 
4200  /* bit 20: Moon within the SV keep-out box for RSB (any band)*/
4201 
4203  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00100000;
4204 
4205  /* bit 21: Moon within the SV keep-out box for Emissive bands (any band)*/
4206 
4208  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00200000;
4209 
4210  /* bit 22: all SV data are bad for any subsamples, detectors and bands */
4211 
4212  if (QA->QA_refl.all_SV_DN_bad[S] == 1)
4213  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00400000;
4214 
4215  /* bit 23: all BB data are bad for any subsamples, detectors and bands */
4216 
4217  if (QA->QA_refl.all_BB_DN_bad[S] == 1)
4218  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00800000;
4219 
4220  /* bit 24: Leading Granule Scan Gap */
4221 
4223  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x01000000;
4224 
4225  /* bit 25: Trailing Granule Scan Gap */
4226 
4228  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x02000000;
4229 
4230  /* bit 26: Sci Abnormal*/
4231 
4232  if (temp[SCI_ABNORM].buffer[S] == 0)
4233  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x04000000;
4234 
4235  /* bits 27 - 31: Remaining bits reserved for future use */
4236 
4237  }
4238 
4239  /********************************
4240  * Initialize variable values *
4241  ********************************/
4242 
4243  L1B_Scan_Meta->num_scans = L1A_Gran->num_scans;
4244  L1B_Scan_Meta->EV_frames = EV_1km_FRAMES;
4245  L1B_Scan_Meta->Nadir_Frame_Number = NADIR_1km_FRAME_NUM;
4246 
4247  for (S = 0; S < L1A_Gran->num_scans; S++)
4248  {
4249  strcpy(L1B_Scan_Meta->ScanType[S], L1A_Gran->ScanType[S]);
4250  L1B_Scan_Meta->MirrorSide[S] =
4251  L1A_Gran->MirrorSide[S];
4252  L1B_Scan_Meta->EVStartTime_TAIsecond[S] =
4253  L1A_Gran->EVStartTime_TAIsecond[S];
4254  }
4255 
4256  for (f = 0; f< NUM_L1B_EV_FILES; f++)
4257  L1B_Scan_Meta->v_id[f] = L1B_Gran->v_id[f];
4258 
4259  returnStatus = read_sds_rank1(geo_sd_id, "SD Sun azimuth",
4260  L1A_Gran->num_scans, SD_Sun_Azimuth);
4261  if (returnStatus != MODIS_S_OK)
4262  {
4263  L1BErrorMsg(location, returnStatus, NULL, "read_sds_rank1",
4265  return returnStatus;
4266  }
4267 
4268  returnStatus = read_sds_rank1(geo_sd_id, "SD Sun zenith",
4269  L1A_Gran->num_scans, SD_Sun_zenith);
4270  if (returnStatus != MODIS_S_OK)
4271  {
4272  L1BErrorMsg(location, returnStatus, NULL, "read_sds_rank1",
4274  return returnStatus;
4275  }
4276 
4277  /*
4278  * Validation of the SWIR out-of-band correction algorithm requires
4279  * the collection of reflective band data at night. In this case, the
4280  * scan type is "Day", even it is really night. The following calculation
4281  * determines the MODIS nadir pixel sees day or night. If it is night and
4282  * the scan type is "Day", set bit 11 to 1. See MCST internal memo "How
4283  * To Determine Whether the MODIS Nadir Pixel Seeds Day Or Night" by
4284  * Joe Esposito and Bruce Berriman, Nov 1, 1999 (Draft) and CCR-508.
4285  */
4286 
4287  /*
4288  * The SD sun zenith and azimuth angles in the MOD03 file are in radians.
4289  */
4290 
4291  for (S = 0; S < L1A_Gran->num_scans; S++)
4292  {
4293  Z_MODIS = - 0.34582 * sin((double)SD_Sun_zenith[S]) *
4294  cos((double)SD_Sun_Azimuth[S]) +
4295  0.923830 * cos((double)SD_Sun_zenith[S]);
4296 
4297  /* bit 11: Day mode bands telemetered at night */
4298 
4299  if (Z_MODIS > 0 && strcmp(L1A_Gran->ScanType[S], "Day") == 0)
4300  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00000800;
4301  }
4302 
4303  NADIR_FRAME_GEO_VALS("SolarAzimuth",
4304  L1B_Scan_Meta->Nadir_Frame_Solar_Azimuth,
4306 
4307  NADIR_FRAME_GEO_VALS("SolarZenith",
4308  L1B_Scan_Meta->Nadir_Frame_Solar_Zenith,
4310 
4311  NADIR_FRAME_GEO_VALS("Latitude",
4312  L1B_Scan_Meta->Nadir_Frame_Latitude,
4313  1.0,f32_buffer);
4314 
4315  NADIR_FRAME_GEO_VALS("Longitude",
4316  L1B_Scan_Meta->Nadir_Frame_Longitude,
4317  1.0,f32_buffer);
4318 
4319  if (SDend(geo_sd_id) == FAIL)
4320  {
4321  returnStatus = MODIS_F_HDF_ERROR;
4322  L1BErrorMsg(location, returnStatus, NULL, "SDend",
4324  "Memory or the disk file must have become corrupted.",
4325  True);
4326  return returnStatus;
4327  }
4328 
4329  free(SRCA_mode);
4330  free(i16_buffer);
4331  free(f32_buffer);
4332  free(SD_Sun_zenith);
4333  free(SD_Sun_Azimuth);
4334  free(Attitude_Angles);
4335 
4336  return(MODIS_S_OK);
4337 }
4338 
4339 PGSt_SMF_status Calculate_DCR_Change(L1A_granule_t *L1A_Gran,
4340  QA_Data_t *QA,
4341  L1B_Scan_Metadata_t *L1B_Scan_Meta)
4342 /*
4343 !C****************************************************************
4344 !Description: Read in the DCR offset values of the last scan in
4345  leading granule and all the DCR values of L1A granule.
4346  Compare the DCR values of the current scan with the
4347  same ones in previous scan. Set DCR changes to 1, if
4348  they are different. Otherwise set them to 0.
4349 
4350 !Input Parameters:
4351  L1A_granule_t *L1A_Gran
4352 !Output Parameters:
4353  QA_Data_t *QA
4354 
4355 !Revision History:
4356  (continue at top of the file)
4357 
4358  Revision 01.02 8/26/1999
4359  Added checking if the dcr offset values are valid.
4360  Zhenying Gu (zgu@mcst.gsfc.nasa.gov)
4361 
4362  Revision 01.01 1/26/1999
4363  Two minor bug fixes. Move DCR_550 = 0 into loop through scans,
4364  change the last "or" to an "and".
4365  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
4366 
4367  Revision 01.00 1/26/1999
4368  Original Development
4369  Zhenying Gu (zgu@gscmail.gsfc.nasa.gov)
4370 
4371 !Team-unique Header:
4372  This software is developed by the MODIS Characterization Support
4373  Team (MCST)for the National Aeronautics and Space Administration,
4374  Goddard Space Flight Center, under contract NAS5-32373.
4375 
4376 !References and Credits:
4377  The time setting code was borrowed from Paul Fishers timea.c
4378 
4379  HDF portions developed at the National Center for Supercomputing
4380  Applications at the University of Illinois at Urbana-Champaign.
4381 
4382 !Design Notes:
4383 
4384 !END********************************************************************
4385 */
4386 
4387 {
4388  PGSt_SMF_status returnStatus;
4389  int32 S, B, B_emiss, D, D_1km, num_scans;
4390  int32 DCR_550;
4391  int32 file_id;
4392  int16 flag = 0;
4393  int8 Leading_DCR_offset[NUM_DCR_VALUE];
4394  typedef int8 DCR_offset_t[NUM_DCR_VALUE];
4395  DCR_offset_t *DCR_offset;
4396  DCR_offset = (DCR_offset_t*) malloc(MAX_NUM_SCANS * sizeof(DCR_offset_t));
4397  typedef int8 XDCR_offset_t[NUM_DCR_VALUE];
4398  XDCR_offset_t *XDCR_offset;
4399  XDCR_offset = (XDCR_offset_t*) malloc((MAX_NUM_SCANS + 1) * sizeof(XDCR_offset_t));
4400  PGSt_integer Version = 1;
4401  char file_name[PGSd_PC_FILE_PATH_MAX];
4402  char *location = "Calculate_DCR_Change";
4403 
4404  /* Read DCR_offset from the last scan of the leading granule, if present */
4405 
4407  returnStatus = PGS_PC_GetReference (LEADING_L1A_GRANULE,
4408  &Version, file_name);
4409  if (returnStatus != PGS_S_SUCCESS)
4410  {
4411  returnStatus = MODIS_F_FILE_NOT_FOUND;
4412  L1BErrorMsg(location, returnStatus,
4413  "Could not retrieve file name from PCF.",
4414  "PGS_PC_GetReference", LEADING_L1A_GRANULE, NULL, True);
4415  return returnStatus;
4416  }
4417 
4418  /* Open file */
4419 
4420  file_id = SDstart(file_name, DFACC_RDONLY); /*for sds interfaces*/
4421  if (file_id == FAIL)
4422  {
4423  returnStatus = MODIS_F_FILE_NOT_OPENED;
4424  L1BErrorMsg(location, returnStatus,
4425  "Could not open file for SD read access.",
4426  "SDstart", LEADING_L1A_GRANULE,
4427  "The file may be missing, corrupted or "
4428  "not an HDF-4 file.", True);
4429  return returnStatus;
4430  }
4431 
4432  returnStatus = read_attribute (file_id, "Number of Scans",
4433  DFNT_INT32, (void *)&num_scans);
4434  if (returnStatus != MODIS_S_OK)
4435  {
4436  L1BErrorMsg(location, returnStatus,
4437  "Could not read Number of Scans.",
4438  "read_attribute", LEADING_L1A_GRANULE,
4440  return returnStatus;
4441  }
4442 
4443  returnStatus = read_part_sds_rank2 (file_id,
4444  "fpa_dcr_offset",
4445  num_scans - 1,
4446  0,
4447  1,
4448  NUM_DCR_VALUE,
4449  Leading_DCR_offset);
4450  if (returnStatus != MODIS_S_OK)
4451  {
4452  L1BErrorMsg(location, returnStatus,
4453  "Could not read fpa_dcr_offset.",
4454  "read_part_sds_rank2", LEADING_L1A_GRANULE,
4456  return returnStatus;
4457  }
4458 
4459  if (SDend(file_id) == FAIL)
4460  {
4461  returnStatus = MODIS_F_HDF_ERROR;
4462  L1BErrorMsg(location, returnStatus, NULL, "SDend",
4464  "Memory or the disk file must have become "
4465  "corrupted.", True);
4466  return returnStatus;
4467  }
4468 
4469  }
4470 
4471  /* Read DCR_offset from all scans of the middle granule */
4472 
4473  returnStatus = read_sds_rank2(L1A_Gran->sd_id, "fpa_dcr_offset",
4474  L1A_Gran->num_scans,
4475  NUM_DCR_VALUE, DCR_offset);
4476  if (returnStatus != MODIS_S_OK)
4477  {
4478  L1BErrorMsg(location, returnStatus,
4479  "Could not read fpa_dcr_offset.",
4480  "read_sds_rank2", FIRST_L1A_GRANULE,
4482  return returnStatus;
4483  }
4484 
4485  /* Place data in the XDCR_offset array. If the leading granule
4486  * is missing, use the values from the first scan of the
4487  * middle granule to begin the XDCR array.
4488  */
4489 
4491  for(DCR_550 = 0; DCR_550 < NUM_DCR_VALUE; DCR_550++)
4492  XDCR_offset[0][DCR_550] = Leading_DCR_offset[DCR_550];
4493  }
4494  else {
4495  for(DCR_550 = 0; DCR_550 < NUM_DCR_VALUE; DCR_550++)
4496  XDCR_offset[0][DCR_550] = DCR_offset[0][DCR_550];
4497  }
4498 
4499  for(S = 0; S < L1A_Gran->num_scans; S++) {
4500  for(DCR_550 = 0; DCR_550 < NUM_DCR_VALUE; DCR_550++)
4501  XDCR_offset[S+1][DCR_550] = DCR_offset[S][DCR_550];
4502  }
4503 
4504  for(S = 0; S < L1A_Gran->num_scans; S++)
4505  {
4506  DCR_550 = 0;
4507  flag = 0;
4508 
4509  for(D_1km = 0; D_1km < DETECTORS_PER_1KM_BAND; D_1km++)
4510  {
4511  for(B = 0; B < NUM_250M_BANDS; B++)
4512  {
4513  for(D = 0; D < BAND_RATIO_AT_RES[INDEX_250M]; D++, DCR_550++)
4514  {
4515  if(XDCR_offset[S+1][DCR_550] == XDCR_offset[S][DCR_550])
4517  [S][B][(DETECTORS_PER_1KM_BAND - D_1km) * 4 - D - 1] = 0;
4518  else
4519  {
4521  [S][B][(DETECTORS_PER_1KM_BAND - D_1km) * 4 - D - 1] = 1;
4522  flag = 1;
4523  }
4524  }
4525  }
4526 
4527  for(B = 0; B < NUM_500M_BANDS; B++)
4528  {
4529  for(D = 0; D < BAND_RATIO_AT_RES[INDEX_500M]; D++, DCR_550++)
4530  {
4531  if(XDCR_offset[S+1][DCR_550] == XDCR_offset[S][DCR_550])
4533  [S][B][(DETECTORS_PER_1KM_BAND -D_1km) * 2 - D - 1] = 0;
4534  else
4535  {
4537  [S][B][(DETECTORS_PER_1KM_BAND -D_1km) * 2 - D - 1] = 1;
4538  flag = 1;
4539  }
4540  }
4541  }
4542 
4543  for(B = 0; B < NUM_1000M_REFL_BANDS - 1; B++, DCR_550++)
4544  {
4545  if(XDCR_offset[S+1][DCR_550] == XDCR_offset[S][DCR_550])
4547  [S][B][DETECTORS_PER_1KM_BAND - D_1km - 1] = 0;
4548  else
4549  {
4551  [S][B][DETECTORS_PER_1KM_BAND - D_1km - 1] = 1;
4552  flag = 1;
4553  }
4554  }
4555 
4556  B_emiss = 0;
4557  for(B = 0; B <= NUM_EMISSIVE_BANDS; B++, DCR_550++)
4558  {
4559  if(B < BAND31)
4560  {
4561  if(B == BAND26)
4562  {
4563  if(XDCR_offset[S+1][DCR_550] == XDCR_offset[S][DCR_550])
4565  [S][NUM_1000M_REFL_BANDS - 1]
4566  [DETECTORS_PER_1KM_BAND - D_1km - 1] = 0;
4567  else
4568  {
4570  [S][NUM_1000M_REFL_BANDS - 1]
4571  [DETECTORS_PER_1KM_BAND - D_1km - 1] = 1;
4572  flag = 1;
4573  }
4574  continue;
4575  }
4576 
4577  if(XDCR_offset[S+1][DCR_550] == XDCR_offset[S][DCR_550])
4579  [S][B_emiss][DETECTORS_PER_1KM_BAND - D_1km - 1] = 0;
4580  else
4581  {
4583  [S][B_emiss][DETECTORS_PER_1KM_BAND - D_1km - 1] = 1;
4584  flag = 1;
4585  }
4586  }
4587 
4588  else
4589  {
4590  if(XDCR_offset[S+1][DCR_550] == XDCR_offset[S][DCR_550] &&
4591  XDCR_offset[S+1][DCR_550 + 1] == XDCR_offset[S][DCR_550 + 1])
4593  [S][B_emiss][DETECTORS_PER_1KM_BAND - D_1km - 1] = 0;
4594  else
4595  {
4597  [S][B_emiss][DETECTORS_PER_1KM_BAND - D_1km - 1] = 1;
4598  flag = 1;
4599  }
4600  DCR_550++;
4601  }
4602 
4603  B_emiss++;
4604  }
4605  }/*end D_1km */
4606 
4607  if (flag == 1)
4608  L1B_Scan_Meta->Bit_QA_Flags[S] |= 0x00002000;
4609  }/*end S */
4610 
4611  free(DCR_offset);
4612  free(XDCR_offset);
4613 
4614  return(returnStatus);
4615 }
4616 
4617 PGSt_SMF_status Init_QA_Parameters (L1A_granule_t *L1A_Gran,
4618  L1B_granule_t *L1B_Gran,
4619  QA_Data_t *QA)
4620 /*
4621 !C**********************************************************************
4622 !Description:
4623  This routine initializes the QA values of total numbr of pixels, number of
4624  valid pixels, number of saturated pixels, number of missing pixels and
4625  pixels representing negative values below noise. Initially, all pixels
4626  are assumed to be valid. Then it checks missing scans. If there is missing
4627  scan, the function update these values and set bad data flag to be true.
4628  Later, in Emissive_Cal and Reflective_Cal, these values will be adjusted
4629  on a pixel by pixel basis if some values are determined to be missing,
4630  saturated, etc.
4631 
4632 !Input Parameters:
4633  L1A_granule_t *L1A_Gran contains L1A granule sd_id and scan type and
4634  scan quality array
4635  L1B_granule_t *L1B_Gran contains number scans and number day mode scans
4636 
4637 !Output Parameters:
4638  L1B_granule_t *L1B_Gran contains number of total pixels, missing pixels,
4639  valid pixels, saturate pixels, negative value
4640  below noise level pixels and bad data flag for
4641  each band
4642 
4643  QA_Data_t *QA contains QA data such as number of missing scans,
4644  number of dead detector EV data, number of sector
4645  rotation EV data, etc.
4646 
4647 !Revision History:
4648  (continue at top of the file)
4649 
4650  Revision 01.04 February 7, 2002 Razor Issue 180
4651  Added counting num_b1_lt_0
4652  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
4653 
4654  Revision 01.03 October 29, 2000
4655  The missing scans are now flagged in an array in L1A_Gran, Razor issue 142.
4656  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
4657 
4658  Revision 01.02 September 21, 2000
4659  Added counting num_rsb_at_night_scans as per Razor issue 137.
4660  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
4661 
4662  ... (many changes not logged) ...
4663 
4664  Revision 01.01 Nov. 16, 1999
4665  Added checking missing scans and consequentially update the QA parameters
4666  Zhenying Gu (zgu@mcst.gsfc.nasa.gov)
4667 
4668  Revision 01.00 Oct. 1997
4669  Initial development
4670  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
4671 
4672 !Team-unique Header:
4673  This software is developed by the MODIS Characterization Support
4674  Team (MCST)for the National Aeronautics and Space Administration,
4675  Goddard Space Flight Center, under contract NAS5-32373.
4676 
4677 !References and Credits:
4678  HDF portions developed at the National Center for Supercomputing
4679  Applications at the University of Illinois at Urbana-Champaign.
4680 
4681 !Design Notes:
4682 
4683 !END********************************************************************
4684 */
4685 {
4686  int16 B = 0; /* band index within L1A resolution */
4687  int16 B_38 = 0;
4688  int16 D_490 = 0; /* detector index within set of MODIS bands (0-489) */
4689  int16 R = 0;
4690  int16 S = 0; /* scan index */
4691 
4692  QA->QA_common.num_missing_scans = 0;
4694  for(D_490 = 0; D_490 < NUM_DETECTORS; D_490++)
4695  {
4696  QA->QA_common.num_missing_data_in_scans[D_490] = 0;
4697  QA->QA_common.num_dead_detector_EV_data[D_490] = 0;
4698  QA->QA_common.num_sector_rotation_EV_data[D_490] = 0;
4699  QA->QA_common.num_saturated_EV_data[D_490] = 0;
4700  QA->QA_common.num_no_bg_DN_EV_data[D_490] = 0;
4701  QA->QA_common.num_moon_in_SVP_TEB_EV_data[D_490] = 0;
4703  QA->QA_common.num_exceed_max_for_scaling[D_490] = 0;
4705  QA->QA_common.num_negative_b1[D_490] = 0;
4706  if(D_490 < NUM_HIGH_RESOLUTION_DETECTORS)
4707  QA->QA_common.num_dead_subframe_EV_data[D_490] = 0;
4708  }
4709 
4710  for (R = 0; R < NUM_L1A_RESOLUTIONS; R++)
4711  for (B = 0; B < L1A_BANDS_AT_RES[R]; B++, B_38++)
4712  {
4713  if (R != INDEX_1000M_EMISS || B_38 == MODIS_BAND26_INDEX)
4714  {
4715  L1B_Gran->valid_pixels[B_38] = L1B_Gran->num_day_scans *
4717  BAND_RATIO_AT_RES[R] *
4718  EV_1km_FRAMES;
4719  }
4720  else
4721  {
4722  L1B_Gran->valid_pixels[B_38] = L1B_Gran->num_scans *
4724  BAND_RATIO_AT_RES[R] *
4725  EV_1km_FRAMES;
4726  }
4727 
4728 /************************* Begin Band 26 Section **************************/
4729 #ifdef WRITE_BAND_26_SDS
4730  /*
4731  * This resets the number of valid pixels for band 26 to
4732  * include all scans, both day and night.
4733  */
4734  if (B_38 == MODIS_BAND26_INDEX)
4735  L1B_Gran->valid_pixels[B_38] = L1B_Gran->num_scans *
4738 #endif /* WRITE_BAND_26_SDS */
4739 /************************** End Band 26 Section ***************************/
4740 
4741  L1B_Gran->total_pixels[B_38] =
4742  L1B_Gran->num_scans *
4745  L1B_Gran->saturated_pixels[B_38] = 0;
4746  L1B_Gran->missing_pixels[B_38] =
4747  L1B_Gran->total_pixels[B_38] -
4748  L1B_Gran->valid_pixels[B_38];
4749  L1B_Gran->negative_value_below_noise_pixels[B_38] = 0;
4750  L1B_Gran->interpolated_pixels[B_38] = 0;
4751  L1B_Gran->dead_detector_pixels[B_38] = 0;
4752  L1B_Gran->dead_subframe_pixels[B_38] = 0;
4753  L1B_Gran->bad_data_flag[B_38] = 0;
4754  }
4755 
4756  /*
4757  * Adjust qa counter variables for scans that are completely missing.
4758  */
4759 
4760  for (S = 0; S < L1B_Gran->num_scans; S++)
4761  {
4762  if (L1A_Gran->missing_scan[S] == True)
4763  {
4764  B_38 = 0;
4765  for (R = 0; R < NUM_L1A_RESOLUTIONS; R++)
4766  for (B = 0; B < L1A_BANDS_AT_RES[R]; B++, B_38++)
4767  {
4768  if (strcmp(L1A_Gran->ScanType[S], "Day") == SAME ||
4769  (R == INDEX_1000M_EMISS && B_38 != MODIS_BAND26_INDEX))
4770  {
4771  L1B_Gran->missing_pixels[B_38] +=
4774  L1B_Gran->valid_pixels[B_38] -=
4777  }
4778 /************************* Begin Band 26 Section **************************/
4779 #ifdef WRITE_BAND_26_SDS
4780 
4781  /*
4782  * If WRITE_BAND_26_SDS is defined, the valid pixels for band 26
4783  * is computed based on the number of all scans. So, if the scan
4784  * is missing, number of the missing pixels and valid pixels should
4785  * be recalculated even if the scan is in night mode.
4786  */
4787 
4788  else if (B_38 == MODIS_BAND26_INDEX)
4789  {
4790  L1B_Gran->missing_pixels[B_38] +=
4793  L1B_Gran->valid_pixels[B_38] -=
4796  }
4797 
4798 #endif /* WRITE_BAND_26_SDS */
4799 /************************** End Band 26 Section ***************************/
4800 
4801  L1B_Gran->bad_data_flag[B_38] = 1;
4802  }
4804  }
4805  }
4806 
4807  return MODIS_S_OK;
4808 }
4809 
4810 PGSt_SMF_status Write_L1B_ScanMeta (L1B_Scan_Metadata_t *L1B_Scan_Meta,
4811  L1A_granule_t *L1A_Gran,
4812  QA_Data_t *QA,
4813  boolean skip_night_hi_res)
4814 /*
4815 !C**************************************************************************
4816 !Description: This routine writes level 1B scan metadata into EV files and
4817  also writes bit QA flags into OBC file.
4818 
4819 !Input Parameters:
4820  L1B_Scan_Metadata_t *L1B_Scan_Meta contains L1A scan metadata
4821  L1A_granule_t *L1A_Gran contains number of scans, v_id
4822  and scan quality array
4823  QA_Data_t *QA contains number of thermistor
4824  outliers
4825  boolean skip_night_hi_res True if and only if all scans are
4826  night mode scans and writing of 250m
4827  and 500m night mode granules has been
4828  turned off
4829 
4830 !Output Parameters:
4831  none
4832 !Revision History:
4833  (continue at top of the file)
4834 
4835  Revision 02.20 March 27, 2003 Razor Issue #173
4836  Enclosed the rows in the initializer of array-of-struct "vd_field" with braces
4837  for ANSI-C compliance.
4838  Liqin Tan, SAIC GSO (ltan@saicmodis.com)
4839 
4840  Revision 02.19 November 19, 2001 Razor Issue #169
4841  Added boolean skip_night_hi_res to input parameters and altered logic
4842  so that if skip_night_hi_res is True, output data sets for 250m and
4843  500m resolution data are not created.
4844  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
4845 
4846  Revision 02.18 September 30, 1999
4847  The structure member "num_thermistor_outliers" is now indexed thorugh scan.
4848  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
4849 
4850  Revision 02.17 August 1999
4851  Added checking if the scan quality array data are valid in L1A file.
4852  Zhenying Gu (zgu@mcst.gsfc.nasa.gov)
4853 
4854  Revision 02.16 May 1999
4855  Wrote bit QA flags into OBC file also
4856  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
4857  Zhenying Gu(zgu@mcst.gsfc.nasa.gov)
4858 
4859  Revision 02.00 April 1997
4860  Combined V_Data_Create & Write_L1B_ScanMeta of version 1.
4861  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
4862 
4863  Revision 01.01 1996/04/05
4864  Update to match Version 1 Design Document
4865  Neal Devine(devine@ltpmail.gsfc.nasa.gov)
4866  John Hannon(hannon@highwire.gsfc.nasa.gov)
4867  Joan Baden (baden@highwire.gsfc.nasa.gov)
4868 
4869  Revision 01.00 1993
4870  Initial development
4871  Geir E. Kvaran(geir@highwire.gsfc.nasa.gov)
4872 
4873 !Team-unique Header:
4874 
4875 !References and Credits:
4876  This software is developed by the MODIS Characterization Support
4877  Team (MCST)for the National Aeronautics and Space Administration,
4878  Goddard Space Flight Center, under contract NAS5-32373.
4879 
4880  HDF portions developed at the National Center for Supercomputing
4881  Applications at the University of Illinois at Urbana-Champaign.
4882 
4883 !Design Notes:
4884 
4885 !END********************************************************************
4886 */
4887 {
4888  PGSt_SMF_status returnStatus = MODIS_S_OK;
4889  char *location = "Write_L1B_ScanMeta";
4890  PGSt_integer Version = 1;
4891  int16 f = 0; /*L1B_file index (0,2)*/
4892  int16 i = 0; /*vdata field index*/
4893  int32 S = 0; /*Scan index*/
4894  int16 num_fields = 14;
4895  int32 vd_id = 0;
4896  int32 list_len = 0;
4897  char *list = NULL;
4898  int32 scan_number = 0;
4899  int32 complete_scan_flag = 0;
4900  char8 scan_type[4] = {' ', ' ', ' ', ' '};
4901  int32 mirror_side = 0;
4902  int32 EV_frames = 0;
4903  int32 nadir_frame = 0;
4904  float32 nadir_frame_latitude = 0;
4905  float32 nadir_frame_longitude = 0;
4906  float32 nadir_frame_solar_azimuth = 0;
4907  float32 nadir_frame_solar_zenith = 0;
4908  int32 BB_thermistor_outliers = 0;
4909  uint32 bit_QA_flags = 0;
4910  uint16 sector_rotation_dn[MAX_NUM_SCANS];
4911  float32 sector_rotation_angle;
4912  char buffer[64];
4913  char *buffer_ptr;
4914  int32 obc_file_id;
4915  intn hdf_return;
4916  char file_name[512];
4917  struct { char *name; int32 type; int32 order; } vd_field[14] =
4918  {
4919  {"Scan Number" , DFNT_INT32 , 1},
4920  {"Complete Scan Flag" , DFNT_INT32 , 1},
4921  {"Scan Type" , DFNT_CHAR8 , 4},
4922  {"Mirror Side" , DFNT_INT32 , 1},
4923  {"EV Sector Start Time" , DFNT_FLOAT64, 1},
4924  {"EV_Frames" , DFNT_INT32 , 1},
4925  {"Nadir_Frame_Number" , DFNT_INT32 , 1},
4926  {"Latitude of Nadir Frame" , DFNT_FLOAT32, 1},
4927  {"Longitude of Nadir Frame" , DFNT_FLOAT32, 1},
4928  {"Solar Azimuth of Nadir Frame" , DFNT_FLOAT32, 1},
4929  {"Solar Zenith of Nadir Frame" , DFNT_FLOAT32, 1},
4930  {"No. OBC BB thermistor outliers" , DFNT_INT32 , 1},
4931  {"Bit QA Flags" , DFNT_UINT32 , 1},
4932  {"Sector Rotation Angle" , DFNT_FLOAT32, 1}
4933  };
4934  int32 evfile_luns[NUM_L1B_EV_FILES] =
4935  {
4939  };
4940  int16 start_output_res = INDEX_L1B_250m;
4941 
4942 #define PACK_MEMBER(member, buffer_ptr) \
4943 memcpy(buffer_ptr, (void *)&member, sizeof(member)); \
4944 buffer_ptr += sizeof(member)
4945 
4946  if (skip_night_hi_res == True)
4947  start_output_res = INDEX_L1B_1km;
4948  else
4949  start_output_res = INDEX_L1B_250m;
4950 
4951  for (f = start_output_res; f < NUM_L1B_EV_FILES; f++)
4952  {
4953 
4954  /*create a new v_data*/
4955 
4956  if ((vd_id = VSattach(L1B_Scan_Meta->v_id[f],-1,"w")) == FAIL)
4957  {
4958  returnStatus = MODIS_F_HDF_ERROR;
4959  L1BErrorMsg(location, returnStatus,
4960  "Could not attach to vdata for writing Level "
4961  "1B Swath Metadata",
4962  "VSattach", evfile_luns[f], NULL, True);
4963  return returnStatus;
4964  }
4965 
4966  /*give it a name*/
4967 
4968  if (VSsetname(vd_id,"Level 1B Swath Metadata") == FAIL)
4969  {
4970  returnStatus = MODIS_F_HDF_ERROR;
4971  L1BErrorMsg(location, returnStatus,
4972  "Could not create vdata name for writing "
4973  "Level 1B Swath Metadata",
4974  "VSsetname", evfile_luns[f], NULL, True);
4975  return returnStatus;
4976  }
4977 
4978  /*define and set fields of the v_data*/
4979 
4980  list_len = 0;
4981  for (i = 0; i < num_fields; i++)
4982  {
4983  if (VSfdefine(vd_id,
4984  vd_field[i].name,
4985  vd_field[i].type,
4986  vd_field[i].order) == FAIL)
4987  {
4988  char errmsg[256];
4989  if (vd_field[i].name)
4990  sprintf(errmsg,
4991  "Could not define vdata field for \"%s\".",
4992  vd_field[i].name);
4993  else
4994  strcpy(errmsg, "Could not define vdata field -- name is NULL.");
4995  returnStatus = MODIS_F_HDF_ERROR;
4996  L1BErrorMsg(location, returnStatus, errmsg,
4997  "VSfdefine", evfile_luns[f], NULL, True);
4998  return returnStatus;
4999  }
5000 
5001  /*total num of char's in all names*/
5002  list_len += strlen(vd_field[i].name);
5003  }
5004 
5005  /*allocate memory for char's & commas & \0*/
5006  list = (char *)malloc((list_len + num_fields + 1) * sizeof(char));
5007  if (!list)
5008  {
5009  returnStatus = MODIS_F_OUT_OF_MEMORY;
5010  L1BErrorMsg(location, returnStatus, NULL, "malloc", 0, NULL, True);
5011  return returnStatus;
5012  }
5013 
5014  /* Initialize list */
5015 
5016  list[0] = '\0';
5017 
5018  /*Append names and commas*/
5019 
5020  for (i = 0; i < num_fields - 1; i++)
5021  {
5022  strcat(list,vd_field[i].name);
5023  strcat(list,",");
5024  }
5025 
5026  /*Last name is not followed by a comma*/
5027 
5028  strcat(list,vd_field[i].name);
5029 
5030  /*set fields*/
5031 
5032  if (VSsetfields(vd_id,list) == FAIL)
5033  {
5034  returnStatus = MODIS_F_HDF_ERROR;
5035  L1BErrorMsg(location, returnStatus, NULL,
5036  "VSsetfields", evfile_luns[f], NULL, True);
5037  return returnStatus;
5038  }
5039 
5040  /* read sector rotation dn */
5041  /* XG 3/12/2015
5042  * use SET_FR_ENC_DELTA from "Command Parameters" field for sector rotation status
5043  */
5044  /*
5045  returnStatus = read_vdata(L1A_Gran->v_id, 0,
5046  L1B_Scan_Meta->num_scans,
5047  "Telemetry Major Cycle 6 of 7",
5048  "CS_FR_ENC_DELTA",
5049  (VOIDP)sector_rotation_dn);
5050  if (returnStatus != MODIS_S_OK)
5051  {
5052  L1BErrorMsg(location, returnStatus, NULL,
5053  "read_vdata", FIRST_L1A_GRANULE, NULL, True);
5054  return returnStatus;
5055  }
5056  returnStatus = Check_Valid_Range("CS_FR_ENC_DELTA",
5057  DFNT_UINT16,
5058  NULL,
5059  "16383",
5060  NULL,
5061  L1A_Gran->num_scans,
5062  (void *) sector_rotation_dn);
5063  */
5064 
5065  returnStatus = read_vdata(L1A_Gran->v_id, 0,
5066  L1B_Scan_Meta->num_scans,
5067  "Command Parameters",
5068  "SET_FR_ENC_DELTA",
5069  (VOIDP)sector_rotation_dn);
5070  if (returnStatus != MODIS_S_OK)
5071  {
5072  L1BErrorMsg(location, returnStatus, NULL,
5073  "read_vdata", FIRST_L1A_GRANULE, NULL, True);
5074  return returnStatus;
5075  }
5076  returnStatus = Check_Valid_Range("SET_FR_ENC_DELTA",
5077  DFNT_UINT16,
5078  NULL,
5079  "16383",
5080  NULL,
5081  L1A_Gran->num_scans,
5082  (void *) sector_rotation_dn);
5083 
5084  if (returnStatus != MODIS_S_OK)
5085  {
5086  L1BErrorMsg(location, returnStatus, NULL, "Check_Valid_Range",
5088  return returnStatus;
5089  }
5090 
5091  for (S = 0; S < L1B_Scan_Meta->num_scans; S++)
5092  {
5093  buffer_ptr = buffer;
5094 
5095  scan_number = S + 1;
5096  PACK_MEMBER(scan_number, buffer_ptr);
5097 
5098  if (L1A_Gran->scan_quality[S][1] != 0)
5099  complete_scan_flag = 0;
5100  else
5101  complete_scan_flag = 1;
5102 
5103 
5104  PACK_MEMBER(complete_scan_flag, buffer_ptr);
5105 
5106  if (strcmp(L1B_Scan_Meta->ScanType[S],"Day") == SAME)
5107  scan_type[0] = 'D';
5108  else if (strcmp(L1B_Scan_Meta->ScanType[S],"Night") == SAME)
5109  scan_type[0] = 'N';
5110  else
5111  scan_type[0] = 'O';
5112  memcpy(buffer_ptr, (void *)scan_type, sizeof(scan_type));
5113  buffer_ptr += sizeof(scan_type);
5114 
5115  mirror_side =
5116  L1B_Scan_Meta->MirrorSide[S];
5117  PACK_MEMBER(mirror_side, buffer_ptr);
5118 
5119  PACK_MEMBER(L1B_Scan_Meta->EVStartTime_TAIsecond[S], buffer_ptr);
5120 
5121  EV_frames =
5122  L1B_Scan_Meta->EV_frames;
5123  PACK_MEMBER(EV_frames, buffer_ptr);
5124 
5125  nadir_frame =
5126  L1B_Scan_Meta->Nadir_Frame_Number;
5127  PACK_MEMBER(nadir_frame, buffer_ptr);
5128 
5129  nadir_frame_latitude =
5130  L1B_Scan_Meta->Nadir_Frame_Latitude[S];
5131  PACK_MEMBER(nadir_frame_latitude, buffer_ptr);
5132 
5133  nadir_frame_longitude =
5134  L1B_Scan_Meta->Nadir_Frame_Longitude[S];
5135  PACK_MEMBER(nadir_frame_longitude, buffer_ptr);
5136 
5137  nadir_frame_solar_azimuth =
5138  L1B_Scan_Meta->Nadir_Frame_Solar_Azimuth[S];
5139  PACK_MEMBER(nadir_frame_solar_azimuth, buffer_ptr);
5140 
5141  nadir_frame_solar_zenith =
5142  L1B_Scan_Meta->Nadir_Frame_Solar_Zenith[S];
5143  PACK_MEMBER(nadir_frame_solar_zenith, buffer_ptr);
5144 
5145  BB_thermistor_outliers =
5146  (int32) QA->QA_emiss.num_thermistor_outliers[S];
5147  PACK_MEMBER(BB_thermistor_outliers, buffer_ptr);
5148 
5149  bit_QA_flags =
5150  L1B_Scan_Meta->Bit_QA_Flags[S];
5151  PACK_MEMBER(bit_QA_flags, buffer_ptr);
5152 
5153  sector_rotation_angle =
5154  (180.0/8192.0)*(float32)sector_rotation_dn[S];
5155  PACK_MEMBER(sector_rotation_angle, buffer_ptr);
5156 
5157  if (VSwrite(vd_id,
5158  (unsigned char *)buffer,
5159  1,
5160  FULL_INTERLACE) == FAIL)
5161  {
5162  returnStatus = MODIS_F_WRITE_ERROR;
5163  L1BErrorMsg(location, returnStatus, NULL,
5164  "VSwrite", evfile_luns[f], NULL, True);
5165  return returnStatus;
5166  }
5167 
5168  } /* S */
5169 
5170  free(list);
5171 
5172  VSdetach(vd_id);
5173 
5174  }/* f */
5175 
5176  /*
5177  * Convert logical ID to physical file name.
5178  */
5179 
5180  returnStatus = PGS_PC_GetReference (L1B_OBC_FILE, &Version, file_name);
5181  if (returnStatus != PGS_S_SUCCESS)
5182  {
5183  returnStatus = MODIS_F_FILE_NOT_FOUND;
5184  L1BErrorMsg(location, returnStatus,
5185  "Could not retrieve file name from PCF.",
5186  "PGS_PC_GetReference", L1B_OBC_FILE, NULL, True);
5187  return returnStatus;
5188  }
5189 
5190  /*
5191  * Open file for Write. The file should already exist since most of the
5192  * data was written in the Preprocess module (the file was closed there).
5193  */
5194 
5195  obc_file_id = SDstart (file_name, DFACC_RDWR); /* for SD interfaces */
5196  if (obc_file_id == FAIL)
5197  {
5198  returnStatus = MODIS_F_FILE_NOT_OPENED;
5199  L1BErrorMsg(location, returnStatus,
5200  "Could not open file for SD read/write access.",
5201  "SDstart", L1B_OBC_FILE,
5202  "The file may be missing, corrupted or "
5203  "not an HDF-4 file.", True);
5204  return returnStatus;
5205  }
5206 
5207  /*
5208  * Write the Bit_QA_Flags as a 1D SDS to the OBC file.
5209  */
5210 
5211  returnStatus = write_sds_rank1(obc_file_id,
5212  "Bit QA Flags",
5214  L1B_Scan_Meta->num_scans,
5215  "uint32",
5216  L1B_Scan_Meta->Bit_QA_Flags);
5217  if (returnStatus != MODIS_S_OK)
5218  {
5219  L1BErrorMsg(location, returnStatus, NULL, "write_sds_rank1",
5220  L1B_OBC_FILE, NULL, True);
5221  return returnStatus;
5222  }
5223 
5224  /*
5225  * Close the file.
5226  */
5227 
5228  hdf_return = SDend(obc_file_id);
5229  if (hdf_return == FAIL)
5230  {
5231  returnStatus = MODIS_F_HDF_ERROR;
5232  L1BErrorMsg(location, returnStatus, NULL, "SDend", L1B_OBC_FILE,
5233  "Memory or the disk file must have become corrupted.",
5234  True);
5235  return returnStatus;
5236  }
5237 
5238  return(MODIS_S_OK);
5239 }
5240 
5241 
5243  L1A_granule_t *L1A_Gran)
5244 /*
5245 !C**************************************************************************
5246 !Description:
5247  This function examines validity of certain L1A data and, based on options
5248  defined in the LUTs, determines additional scans to be treated as
5249  completely missing (meaning that data will not be calibrated for any
5250  band of the scan).
5251 
5252 !Input Parameters:
5253  lookup_tables_t *tables Pointer to all L1B LUTs. The common
5254  QA LUT "control_options" is used.
5255  L1A_granule_t *L1A_Gran All members are filled, including
5256  structure member "missing_scan", based
5257  on normal values of L1A data.
5258 
5259 !Output Parameters:
5260  L1A_granule_t *L1A_Gran structure member "missing_scans" may
5261  be adjusted based on the data.
5262 
5263 !Revision History:
5264  (continue at top of the file)
5265 
5266  Revision 01.00 October 29, 2000
5267  Initial development.
5268  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
5269 
5270 !Team-unique Header:
5271  This software is developed by the MODIS Science Data Support
5272  Team for the National Aeronautics and Space Administration,
5273  Goddard Space Flight Center, under contract NAS5-32373.
5274 
5275 !References and Credits
5276  HDF portions developed at the National Center for Supercomputing
5277  Applications at the University of Illinois at Urbana-Champaign.
5278 
5279 !Design Notes:
5280 
5281 !END********************************************************************
5282 */
5283 {
5284  PGSt_SMF_status returnStatus = MODIS_S_OK;
5285  boolean split_scan[MAX_NUM_SCANS];
5286  boolean bad_scan_quality[MAX_NUM_SCANS];
5287  int32 S;
5288  char *location = "Determine_Other_Missing_Scans";
5289  common_QA_tables_t *common_QA_LUT = &tables->QA.common_QA_tables;
5290 
5291  /*
5292  * Set all elements of the array "split_scan" to True or False.
5293  */
5294 
5295  if (common_QA_LUT->control_options[SPLIT_SCAN_CONTROL] == ON)
5296  {
5297  returnStatus = Determine_Split_Scans(L1A_Gran, split_scan);
5298  if (returnStatus != MODIS_S_OK) {
5299  L1BErrorMsg(location, returnStatus, NULL,
5300  "Determine_Split_Scans", 0, NULL, True);
5301  }
5302  }
5303  else {
5304  for (S = 0; S < L1A_Gran->num_scans; S++)
5305  split_scan[S] = False;
5306  }
5307 
5308  /*
5309  * Set all elements of the array "bad_scan_quality" to True or False.
5310  */
5311 
5312  if (common_QA_LUT->control_options[BAD_SCAN_QUALITY_CONTROL] == ON)
5313  {
5314  for (S = 0; S < L1A_Gran->num_scans; S++) {
5315  if ((L1A_Gran->scan_quality[S][0] != 0 &&
5316  L1A_Gran->scan_quality[S][0] != 1) ||
5317  L1A_Gran->scan_quality[S][1] < 0 ||
5318  L1A_Gran->scan_quality[S][2] < 0 ||
5319  L1A_Gran->scan_quality[S][3] < 0)
5320  bad_scan_quality[S] = True;
5321  else
5322  bad_scan_quality[S] = False;
5323  }
5324  }
5325  else
5326  {
5327  for (S = 0; S < L1A_Gran->num_scans; S++)
5328  bad_scan_quality[S] = False;
5329  }
5330 
5331  /*
5332  * adjust the values of "missing_scan", if necessary.
5333  */
5334 
5335  for (S = 0; S < L1A_Gran->num_scans; S++)
5336  {
5337  if (split_scan[S] || bad_scan_quality[S])
5338  L1A_Gran->missing_scan[S] = True;
5339  }
5340 
5341 
5342  /*
5343  * Check the mirror side flags. So far, there has not been a
5344  * situation where the mirror side flag was not valid but there were
5345  * data on the scan. However, just in case this happens, this will
5346  * allow the scan to be skipped rather than causing the code to error
5347  * out.
5348  */
5349 
5350 
5351  for (S = 0; S < L1A_Gran->num_scans; S++)
5352  {
5353  if (!(L1A_Gran->MirrorSide[S] == 0 || L1A_Gran->MirrorSide[S] == 1))
5354  L1A_Gran->missing_scan[S] = True;
5355  }
5356 
5357 
5358  return MODIS_S_OK;
5359 }
5360 
5361 PGSt_SMF_status Determine_Split_Scans(L1A_granule_t *L1A_Gran,
5362  boolean *split_scan)
5363 /*
5364 !C**************************************************************************
5365 !Description:
5366  This function determines scan indices of "split scans". A split scan
5367  arises from a bit flip in the scan time of a packet. The L1A code takes
5368  the out-of-order packet and starts a new scan in the granule. Thus, the
5369  original scan is split into two parts. A split scan causes the number
5370  of scans in the granule to exceed the normal 203 or 204 scans.
5371 
5372  See the design notes for comments on the algorithm for detecting a split
5373  scan.
5374 
5375 !Input parameters:
5376 
5377  L1A_granule_t *L1A_Gran contains L1A variables for SD start
5378  time, scan quality and mirror side
5379 
5380 !Output parameters:
5381 
5382  boolean split_scan array which defines if a scan
5383 
5384 !Revision History:
5385  (continue at top of the file)
5386 
5387  Revision 01.02, October 29, 2000
5388  Moved from L1B.c and removed adjusting the QA counters. (issue 142)
5389  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
5390 
5391  Revision 01.01 September 20, 2000
5392  Correct logic errors which led to PGE02 failures (see Razor issue 136).
5393  Call new function, Get_Split_Scan_Indexes.
5394  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
5395 
5396  Revision 01.00 May 2, 2000
5397  Initial development
5398  Zhenying Gu (zgu@mcst.gsfc.nasa.gov)
5399 
5400 !Team-unique Header:
5401  This software is developed by the MODIS Science Data Support
5402  Team for the National Aeronautics and Space Administration,
5403  Goddard Space Flight Center, under contract NAS5-32373.
5404 
5405 !References and Credits:
5406  HDF portions developed at the National Center for Supercomputing
5407  Applications at the University of Illinois at Urbana-Champaign.
5408 
5409 !Design Notes:
5410 
5411  The algorithm for finding the two parts of a split scan begins by
5412  finding an abnormally short time interval between two scans. The
5413  "SD start time" is used for this because in examining many cases of
5414  split scans, it appeared to be the most reliable time among the
5415  various sector start times ("EV start time" was the least reliable).
5416 
5417  The two scans with the abnormally short time interval are not
5418  necessarily the two parts of the split scan. If there are no
5419  repeated mirror side indexes or no missing packets, then the
5420  abnormal time interval is assumed to not be a marker for a split
5421  scan.
5422 
5423  If the short time interval does correspond to a split scan, then at
5424  least one of the two scans will be part of the split scan. To find
5425  the other part, we expand the range of scan indexes by 1 in each
5426  direction and look at "Mirror side" and "Scan quality array". A
5427  repeated mirror side index is the next most reliable indicator.
5428  However, occasionally, one part of the split scan will have a mirror
5429  side index of -1. In this case, we then turn to the number of
5430  missing packets (recorded in the second element of the scan quality
5431  array). The two adjacent scans with large numbers of missing packets
5432  are the next most reliable indicator.
5433 
5434  There is no attempt to find the two parts of a split scan if they
5435  reside in different granules.
5436 
5437 !END********************************************************************
5438 */
5439 {
5440 #define SCAN_INTERVAL 1.4771
5441  PGSt_SMF_status returnStatus;
5442  int32 i; /* scan index in loop through scans */
5443  int32 j; /* used for scan interval */
5444  int32 S_split_1; /* scan index of 1st part of split scan */
5445  int32 S_split_2; /* scan index of 2nd part of split scan */
5446  float64 SD_start_time[MAX_NUM_SCANS];
5447  char *location = "Determine_Split_Scans";
5448 
5449  for (i = 0; i < L1A_Gran->num_scans; i++)
5450  {
5451  split_scan[i] = False;
5452  }
5453 
5454  /* Read SD start time */
5455 
5456  returnStatus = read_sds_rank1 (L1A_Gran->sd_id, "SD start time",
5457  L1A_Gran->num_scans,
5458  (void *)SD_start_time);
5459  if (returnStatus != MODIS_S_OK)
5460  {
5461  L1BErrorMsg(location, returnStatus,
5462  "Could not read SD start time.",
5463  "read_sds_rank1",
5465  return returnStatus;
5466  }
5467 
5468  /* Loop through all scans looking for potential split scans */
5469 
5470  for (i = 1; i < L1A_Gran->num_scans; i++)
5471  {
5472 
5473  /*
5474  * Look at the time interval between scans i-1 and i. If the time
5475  * interval is smaller than 1/2 the normal time interval between
5476  * MODIS scans, then define this to be "abnormally short".
5477  */
5478 
5479  j = (int32)((SD_start_time[i] - SD_start_time[i-1])/SCAN_INTERVAL + 0.5);
5480  if (j <= 0)
5481  {
5482 
5483  /*
5484  * An abnormally short time interval was detected between scans
5485  * i-1 and i. Get the two indexes of the split scan. If the
5486  * indexes return as invalid indexes, assume that the abnormally
5487  * short time interval does not correspond to a split scan.
5488  */
5489 
5490  returnStatus = Get_Split_Scan_Indexes(i-1,
5491  L1A_Gran->num_scans,
5492  L1A_Gran->MirrorSide,
5493  L1A_Gran->scan_quality,
5494  &S_split_1,
5495  &S_split_2);
5496  if (returnStatus != MODIS_S_OK)
5497  {
5498  L1BErrorMsg(location, returnStatus, NULL,
5499  "Get_Split_Scan_Indexes", 0, NULL, False);
5500  return MODIS_S_OK;
5501  }
5502 
5503  if (S_split_1 >= 0 && S_split_1 < L1A_Gran->num_scans)
5504  split_scan[S_split_1] = True;
5505  if (S_split_2 >= 0 && S_split_2 < L1A_Gran->num_scans)
5506  split_scan[S_split_2] = True;
5507 
5508  }
5509  }
5510 
5511  return MODIS_S_OK;
5512 }
5513 
5514 PGSt_SMF_status Get_Split_Scan_Indexes
5515  (int32 S1,
5516  int32 num_scans,
5517  int16 mirror_side[],
5518  int32 scan_quality[]
5520  int32 *S_split_1,
5521  int32 *S_split_2)
5522 /*
5523 !C**************************************************************************
5524 !Description:
5525  Given a pair of scans with an abnormally short time interval,
5526  examine the mirror side and scan quality array indexes to find the
5527  actual split scan indexes. If the split scan indexes cannot be
5528  determined, return invalid values (-1) for the indexes.
5529 
5530 !Input parameters:
5531  int32 S1 1st scan index of the pair of scans with an
5532  abnormally short time interval
5533  int32 num_scans Number of scans in the granule
5534  int32 mirror_side[] mirror side indexes
5535  int32 scan_quality[][] Scan quality array
5536 
5537 !Output parameters:
5538  int32 *S_split_1 Index of 1st part of split scan (or -1
5539  if there is no split scan)
5540  int32 *S_split_2 Index of 2nd part of split scan (or -1
5541  if there is no split scan)
5542 
5543 !Revision History:
5544  (continue at top of the file)
5545 
5546  Revision 01.01 October 16, 2004 Razor Issue #200
5547  Casted Int32 variables in sprintf calls to "long" with the
5548  format specifier "%ld" for better code portability.
5549  Liqin Tan, SAIC GSO (ltan@saicmodis.com)
5550 
5551  Revision 01.00 September 20, 2000
5552  Initial development
5553  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
5554 
5555 !Team-unique Header:
5556  This software is developed by the MODIS Science Data Support
5557  Team for the National Aeronautics and Space Administration,
5558  Goddard Space Flight Center, under contract NAS5-32373.
5559 
5560 !References and Credits:
5561  HDF portions developed at the National Center for Supercomputing
5562  Applications at the University of Illinois at Urbana-Champaign.
5563 
5564 !Design Notes:
5565 
5566 !END********************************************************************
5567 */
5568 {
5569  int32 S, S_begin, S_end;
5570  int32 num_invalid_ms, n, max_n;
5571  char *location = "Get_Split_Scan_Indexes";
5572 
5573  /*
5574  * Check S1 and num_scans
5575  */
5576 
5577  if (S1 < 0 || S1 >= num_scans || num_scans <= 0)
5578  {
5579  char errmsg[256];
5580  sprintf (errmsg,
5581  "Input error in S1 or num_scans:\nS1 = %ld\nnum_scans = %ld\n",
5582  (long)S1, (long)num_scans);
5583  L1BErrorMsg(location, MODIS_F_INVALID_ARGUMENT, errmsg,
5584  NULL, 0, NULL, True);
5585  return MODIS_F_INVALID_ARGUMENT;
5586  }
5587 
5588  /*
5589  * Initialize the return indexes to invalid values.
5590  */
5591 
5592  *S_split_1 = -1;
5593  *S_split_2 = -1;
5594 
5595  /*
5596  * Find the begin and end scan indexes of the range of scans
5597  * to look through. The normal range is a set of 4 scans, starting
5598  * at the scan just before S1.
5599  */
5600 
5601  S_begin = S1 - 1;
5602  if (S_begin < 0) S_begin = 0;
5603  S_end = S1 + 2;
5604  if (S_end >= num_scans) S_end = num_scans - 1;
5605 
5606  /*
5607  * determine if any of the scans has an invalid mirror side index.
5608  */
5609 
5610  num_invalid_ms = 0;
5611  for (S = S_begin; S <= S_end; S++) {
5612  if (!(mirror_side[S] == 0 || mirror_side[S] == 1))
5613  num_invalid_ms++;
5614  }
5615 
5616  /*
5617  * If all the mirror side indexes are valid, base the determination
5618  * on mirror side. Otherwise, base the determination on the pair
5619  * with the largest number of missing packets.
5620  */
5621 
5622  if (num_invalid_ms == 0) {
5623  for (S = S_begin; S < S_end; S++) {
5624  if (mirror_side[S] == mirror_side[S+1]) {
5625  *S_split_1 = S;
5626  *S_split_2 = S+1;
5627  break;
5628  }
5629  }
5630  }
5631  else {
5632  max_n = 0;
5633  for (S = S_begin; S < S_end; S++) {
5634  n = 0;
5635  if (scan_quality[S][1] > 0)
5636  n+= scan_quality[S][1];
5637  if (scan_quality[S+1][1] > 0)
5638  n+= scan_quality[S+1][1];
5639  if (n > max_n) {
5640  max_n = n;
5641  if (scan_quality[S][0] == 0) {
5642  *S_split_1 = S; /* extra scan, blank */
5643  *S_split_2 = -1; /* assume this one is OK */
5644  }
5645  else if (scan_quality[S+1][0] == 0) {
5646  *S_split_1 = -1; /* assume this one is OK */
5647  *S_split_2 = S+1; /* extra scan, blank */
5648  }
5649  else {
5650  *S_split_1 = S;
5651  *S_split_2 = S+1;
5652  }
5653  }
5654  }
5655  if (max_n < 2800) {
5656  *S_split_1 = -1;
5657  *S_split_2 = -1;
5658  }
5659  }
5660 
5661  return MODIS_S_OK;
5662 }
5663 
5664 
5665 PGSt_SMF_status Set_UI_ConvertToPercent_Attrs
5667  L1B_Scan_t *L1B_Scan,
5668  boolean skip_night_hi_res)
5669 /*
5670 !C****************************************************************************
5671 !Description:
5672  Add attributes to all EV UI SDSs which allow conversion of UI to
5673  percent uncertainty. These attributes are: "specified_uncertainty",
5674  "scaling_factor" and "uncertainty_units".
5675 
5676 !Input Parameters:
5677  lookup_tables_t *tables Contains values for the attributes in LUTs
5678  L1B_Scan_t *L1B_Scan Contains the UI SDS IDs (opened)
5679  boolean skip_night_hi_res True if and only if all scans are
5680  night mode scans and writing of 250m
5681  and 500m night mode granules has been
5682  turned off
5683 
5684 !Output Parameters:
5685  (none -- the HDF files themselves are modified)
5686 
5687 !Revision History:
5688  (continue at top of the file)
5689 
5690  Revision 01.02 January 17, 2002 Razor Issue #171
5691  Improve portability of code to 64-bit mode.
5692  Cast strlen returns to int32 in calls to SDSetattr.
5693  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
5694 
5695  Revision 01.01, November 16, 2001, Razor Issue #169
5696  Added input parameter skip_night_hi_res and changed logic so that
5697  250m and 500m data are not written when granule has no day mode
5698  scans and runtime parameter Write_Night_Mode_HiRes_Data is False.
5699  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
5700 
5701  Revision 01.00 Nov. 29, 2000
5702  Initial development
5703  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
5704 
5705 !Team-unique Header:
5706  This software is developed by the MODIS Science Data Support
5707  Team for the National Aeronautics and Space Administration,
5708  Goddard Space Flight Center, under contract NAS5-32373.
5709 
5710 !References and Credits:
5711  HDF portions developed at the National Center for Supercomputing
5712  Applications at the University of Illinois at Urbana-Champaign.
5713 
5714 !Design Notes:
5715  The arrays contained in the LUTs are for all emissive bands (TEB LUTs)
5716  and all reflective bands (RSB LUTs). Within these linear arrays, the
5717  numbers to be set in the attributes are consecutive. Thus, use a macro
5718  where the beginning index and number of values define which subset of
5719  the arrays to write into the attributes.
5720 
5721 !END**************************************************************************
5722 */
5723 {
5724  PGSt_SMF_status returnStatus;
5725  char *units_attr_value = "percent";
5726  char *location = "Set_UI_ConvertToPercent_Attrs";
5727 
5728 #define REFL_250M_START_INDEX 0
5729 #define REFL_500M_START_INDEX 2
5730 #define REFL_1000M_START_INDEX 7
5731 #define REFL_BAND26_START_INDEX 21
5732 
5733 /* Macro: SET_UI_SDS_CONV_ATTRS
5734  * sds_id = opened SDS ID for the SDS to set attributes for
5735  * spec_uncert = variable containing specified uncertainty float array
5736  * scale_factor = variable containing scaling factor float array
5737  * indx = the starting element index in the arrays
5738  * numval = number of values in the attribute
5739  */
5740 #define SET_UI_SDS_CONV_ATTRS(sds_id, spec_uncert, scale_factor, indx, \
5741  numval, lun) \
5742  if (SDsetattr(sds_id, "specified_uncertainty", DFNT_FLOAT32, \
5743  numval, &(spec_uncert[indx])) == FAIL) { \
5744  returnStatus = MODIS_F_WRITE_ERROR; \
5745  L1BErrorMsg(location, returnStatus, \
5746  "Could not write UI SDS attribute" \
5747  "\"specified_uncertainty\".", \
5748  "SDsetattr", lun, NULL, True); \
5749  return returnStatus; \
5750  } \
5751  if (SDsetattr(sds_id, "scaling_factor", DFNT_FLOAT32, \
5752  numval, &(scale_factor[indx])) == FAIL) { \
5753  returnStatus = MODIS_F_WRITE_ERROR; \
5754  L1BErrorMsg(location, returnStatus, \
5755  "Could not write UI SDS attribute \"scaling_factor\".", \
5756  "SDsetattr", lun, NULL, True); \
5757  return returnStatus; \
5758  } \
5759  if (SDsetattr(sds_id, "uncertainty_units", DFNT_CHAR8, \
5760  (int32)strlen(units_attr_value), units_attr_value) == FAIL) { \
5761  returnStatus = MODIS_F_WRITE_ERROR; \
5762  L1BErrorMsg(location, returnStatus, \
5763  "Could not write UI SDS attribute \"uncertainty_units\".", \
5764  "SDsetattr", lun, NULL, True); \
5765  return returnStatus; \
5766  }
5767 
5768  if (skip_night_hi_res == False)
5769  {
5771  tables->refl.RSB_specified_uncertainty,
5772  tables->refl.RSB_UI_scaling_factor,
5775 
5777  tables->refl.RSB_specified_uncertainty,
5778  tables->refl.RSB_UI_scaling_factor,
5781 
5783  tables->refl.RSB_specified_uncertainty,
5784  tables->refl.RSB_UI_scaling_factor,
5787  }
5788 
5790  tables->refl.RSB_specified_uncertainty,
5791  tables->refl.RSB_UI_scaling_factor,
5794 
5796  tables->emiss.TEB_specified_uncertainty,
5797  tables->emiss.TEB_UI_scaling_factor,
5798  0, NUM_EMISSIVE_BANDS,
5800 
5802  tables->refl.RSB_specified_uncertainty,
5803  tables->refl.RSB_UI_scaling_factor,
5806 
5808  tables->refl.RSB_specified_uncertainty,
5809  tables->refl.RSB_UI_scaling_factor,
5812 
5813 /************************* Begin Band 26 Section **************************/
5814 #ifdef WRITE_BAND_26_SDS
5815 
5817  tables->refl.RSB_specified_uncertainty,
5818  tables->refl.RSB_UI_scaling_factor,
5821 
5822 #endif /* WRITE_BAND_26_SDS */
5823 /************************** End Band 26 Section ***************************/
5824 
5825  return MODIS_S_OK;
5826 }
5827 
5828 PGSt_SMF_status Calculate_B26_B5_Correction
5829  (float32 *original_correction,
5830  float32 *scaled_correction,
5831  L1B_ScaleOffset_t *ScaleOffset)
5832 
5833 /*
5834 !C****************************************************************************
5835 !Description:
5836  This function scales crosstalk correction factors which are used to adjust
5837  Band 26 data by crosstalk from Band 5. The scaling factor is the Band 5
5838  radiance scale divided by the Band 26 radiance scale.
5839 
5840 !Input Parameters:
5841  float32 *original_correction Lookup table correction values
5842  L1B_ScaleOffset_t *ScaleOffset Granule-specific scales and offsets
5843 
5844 !Output Parameters:
5845  float32 *scaled_correction Correction values scaled by the
5846  granule-specific scales and offsets
5847 
5848 !Revision History:
5849  (continue at top of the file)
5850 
5851  Initial development March 19, 2002 Razor Issue #182
5852  Added to Aqua code March 26, 2003 Razor Issue #190
5853  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
5854 
5855 !Team-unique Header:
5856  This software is developed by the MODIS Characterization Support
5857  Team (MCST)for the National Aeronautics and Space Administration,
5858  Goddard Space Flight Center, under contract NAS5-32373.
5859 
5860 !References and Credits:
5861  HDF portions developed at the National Center for Supercomputing
5862  Applications at the University of Illinois at Urbana-Champaign.
5863 
5864 !Design Notes:
5865 
5866 !END**************************************************************************
5867 */
5868 
5869 {
5870  PGSt_SMF_status returnStatus = MODIS_S_OK;
5871  int16 D = 0; /* Detector */
5872  float32 scale_factor = 1.; /* Scaling factor */
5873 
5874 
5875  scale_factor = ScaleOffset->rad_scale_RefSB[MODIS_BAND5_INDEX]/
5876  ScaleOffset->rad_scale_RefSB[BAND_26_REFL_INDEX];
5877  for (D = 0; D < DETECTORS_PER_1KM_BAND; D++)
5878  scaled_correction[D] = scale_factor*original_correction[D];
5879 
5880  return returnStatus;
5881 }
GEO_SDS
Definition: l1_hmodis_hdf.c:56
float32 rad_scale_RefSB[NUM_REFLECTIVE_BANDS]
Definition: Granule.h:800
PGSt_SMF_status Determine_Split_Scans(L1A_granule_t *L1A_Gran, boolean *split_scan)
Definition: L1B_Setup.c:5361
#define BAND_26_UI_SDS_NAME
Definition: Granule.h:942
#define MODIS_BAND5_INDEX
Definition: Granule.h:445
#define MODIS_S_OK
#define MODIS_F_FILE_NOT_FOUND
PGSt_SMF_status Calculate_Earth_Sun_Distance(L1A_granule_t *L1A_Gran, float32 *Earth_Sun_Dist)
Definition: L1B_Setup.c:504
boolean missing_scan[MAX_NUM_SCANS]
Definition: Granule.h:769
integer, parameter int16
Definition: cubeio.f90:3
float32 Nadir_Frame_Solar_Zenith[MAX_NUM_SCANS]
Definition: L1B_Setup.h:69
int32 v_id[NUM_L1B_EV_FILES]
Definition: Granule.h:858
int32 num_bad_dn_star_star_RSB_EV_data[NUM_DETECTORS]
Definition: Granule.h:1086
#define NADIR_1km_FRAME_NUM
Definition: Granule.h:473
an array had not been initialized Several spelling and grammar corrections were which is read from the appropriate MCF the above metadata values were hard coded A problem calculating the average background DN for SWIR bands when the moon is in the space view port was corrected The new algorithm used to calculate the average background DN for all reflective bands when the moon is in the space view port is now the same as the algorithm employed by the thermal bands For non SWIR changes in the averages are typically less than Also for non SWIR the black body DNs remain a backup in case the SV DNs are not available For SWIR the changes in computed averages were larger because the old which used the black body suffered from contamination by the micron leak As a consequence of the if SV DNs are not available for the SWIR the EV pixels will not be the granule time is used to identify the appropriate tables within the set given for one LUT the first two or last two tables respectively will be used for the interpolation If there is only one LUT in the set of tables
Definition: HISTORY.txt:695
#define SCAN_QUALITY_ARRAY_NUM_ELEMENTS
Definition: Granule.h:488
@ SI_500to1km
Definition: L1B_Setup.c:102
boolean leading_granule_scan_gap
Definition: Granule.h:1072
#define MAX_SAMPLES_PER_BAND
Definition: Granule.h:475
#define MODIS_F_WRITE_ERROR
int j
Definition: decode_rs.h:73
QA_Common_t QA_common
Definition: Granule.h:1097
uint32 dead_subframe_pixels[NUM_BANDS]
Definition: Granule.h:883
float32 refl_scale_RefSB[NUM_REFLECTIVE_BANDS]
Definition: Granule.h:802
float32 m1_des_sq[NUM_REFLECTIVE_BANDS][MAX_DETECTORS_PER_BAND][MAX_SAMPLES_PER_BAND][NUM_MIRROR_SIDES]
Definition: Granule.h:818
#define MAX_ATTR_BUFFER_SIZE
uint32 interpolated_pixels[NUM_BANDS]
Definition: Granule.h:881
list(APPEND LIBS ${PGSTK_LIBRARIES}) add_executable(atteph_info_modis atteph_info_modis.c) target_link_libraries(atteph_info_modis $
Definition: CMakeLists.txt:7
boolean missing_trailing_granule
Definition: Granule.h:1071
L1B_ScaleOffset_t SO
Definition: Granule.h:865
uint32 valid_pixels[NUM_BANDS]
Definition: Granule.h:878
#define SW_DEF_EV_Aggr_SDS(SI_name, UI_name, SU_name, str)
#define SW_DEF_EV_SDS(SI_name, UI_name, str)
int16 MirrorSide[MAX_NUM_SCANS]
Definition: L1B_Setup.h:70
int32 num_sector_rotation_EV_data[NUM_DETECTORS]
Definition: Granule.h:1082
int8 all_BB_DN_bad[MAX_NUM_SCANS]
Definition: Granule.h:1064
float32 Nadir_Frame_Solar_Azimuth[MAX_NUM_SCANS]
Definition: L1B_Setup.h:68
@ SPLIT_SCAN_CONTROL
Definition: L1B_Tables.h:873
int32 UI_sds_id[NUM_L1A_RESOLUTIONS]
Definition: Granule.h:966
PGSt_SMF_status Open_L1A_EV_SDS(L1A_granule_t *L1A_Gran, L1A_Scan_t *L1A_Scan)
Definition: L1B_Setup.c:419
@ INDEX_LATITUDE
Definition: L1B_SetupP.h:100
#define BAND_26_UI_SDS_LONG_NAME
Definition: Granule.h:944
int32 num_nadir_door_closed_EV_data[NUM_DETECTORS]
Definition: Granule.h:1088
#define GEO_OFFSET
Definition: L1B_SetupP.h:95
#define FAIL
Definition: ObpgReadGrid.h:18
int32 num_saturated_EV_data[NUM_DETECTORS]
Definition: Granule.h:1083
#define MODIS_F_OUT_OF_MEMORY
@ INDEX_500M
Definition: Granule.h:570
char * L1B_EV_DIM_NAME[NUM_L1A_RESOLUTIONS][L1B_EV_SDS_RANK]
Definition: L1B_Setup.c:164
#define NULL
Definition: decode_rs.h:63
float32 dn_star_Min[NUM_REFLECTIVE_BANDS]
Definition: Granule.h:798
#define MODIS_BAND26_INDEX
Definition: Granule.h:446
int32 EV_500m_Aggr1km_RefSB_sds_id
Definition: Granule.h:965
#define FIRST_L1A_GRANULE
Definition: FNames.h:79
#define PGS_PI
Definition: GEO_geo.h:172
@ SI_1km_EMISS
Definition: L1B_Setup.c:99
Band_26_t Band26
Definition: Granule.h:1022
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second band
@ UI_500to1km
Definition: L1B_Setup.c:102
float64 EVStartTime_TAIsecond[MAX_NUM_SCANS]
Definition: L1B_Setup.h:72
@ SI_250m
Definition: L1B_Setup.c:96
int32 EV_250m_Aggr500m_RefSB_SU_sds_id
Definition: Granule.h:970
PGSt_SMF_status Set_UI_ConvertToPercent_Attrs(lookup_tables_t *tables, L1B_Scan_t *L1B_Scan, boolean skip_night_hi_res)
Definition: L1B_Setup.c:5666
int32 EV_500m_Aggr1km_RefSB_SU_sds_id
Definition: Granule.h:972
#define NUM_500M_BANDS
Definition: Granule.h:431
int32 SI_sds_id
Definition: Granule.h:947
#define MODIS_F_OUT_OF_RANGE
int32 num_exceed_max_for_scaling[NUM_DETECTORS]
Definition: Granule.h:1087
#define NADIR_FRAME_GEO_VALS(geoname, var, scalefactor, buf)
int32 num_scans
Definition: Granule.h:749
#define MODIS_BAND26_INDEX_AT_RES
Definition: Granule.h:447
int8 change_dc_restore[MAX_NUM_SCANS][NUM_EMISSIVE_BANDS][DETECTORS_PER_1KM_BAND]
Definition: Granule.h:1046
uint8 * counts
Definition: l1_czcs_hdf.c:30
boolean Sector_Rotation[MAX_NUM_SCANS]
Definition: Granule.h:1075
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
@ INDEX_250M
Definition: Granule.h:569
int8 all_SV_DN_bad[MAX_NUM_SCANS]
Definition: Granule.h:1063
#define ON
Definition: l1.h:43
const int NUM_MIRROR_SIDES
#define DETECTORS_PER_500M_BAND
Definition: Granule.h:439
int32 num_moon_in_SVP_TEB_EV_data[NUM_DETECTORS]
Definition: Granule.h:1085
int16 BAND_RATIO_AT_RES[NUM_L1A_RESOLUTIONS]
Definition: Granule.c:73
float32 m1_des_sq_max[NUM_REFLECTIVE_BANDS]
Definition: Granule.h:820
#define COPY_ATTR(attr_name)
int8 moon_in_SV_KOB_TEB[MAX_NUM_SCANS]
Definition: Granule.h:1048
@ NUM_GEO_SDS
Definition: L1B_SetupP.h:109
#define DETECTORS_PER_1KM_BAND
Definition: Granule.h:438
PGSt_SMF_status Copy_Geo_SDS(L1B_granule_t *L1B_Gran, boolean skip_night_hi_res)
Definition: L1B_Setup.c:3243
#define MODIS_BAND20_INDEX
Definition: Granule.h:448
PGSt_SMF_status Determine_Other_Missing_Scans(lookup_tables_t *tables, L1A_granule_t *L1A_Gran)
Definition: L1B_Setup.c:5242
int32 num_missing_scans
Definition: Granule.h:1077
@ SI_250to500m
Definition: L1B_Setup.c:100
PGSt_SMF_status write_sds_rank1(int32 file_id, char *sds_name, char *dim_name, int32 dim, char *datatype, void *data)
Definition: HDF_Lib.c:944
@ SU_500to1km
Definition: L1B_Setup.c:102
float32 rad_offset_RefSB[NUM_REFLECTIVE_BANDS]
Definition: Granule.h:801
#define L1B_EV_500M_FILE
Definition: FNames.h:70
@ SU_250to500m
Definition: L1B_Setup.c:100
#define DN15_SAT
Definition: Granule.h:1103
@ INDEX_L1B_250m
Definition: Granule.h:587
PGSt_SMF_status Open_L1B_EV_SDS(L1B_granule_t *L1B_Gran, L1B_Scan_t *L1B_Scan, boolean skip_night_hi_res)
Definition: L1B_Setup.c:1726
#define MODIS_F_FILE_NOT_CREATED
uint32 total_pixels[NUM_BANDS]
Definition: Granule.h:877
int32 num_day_scans
Definition: Granule.h:750
PGSt_SMF_status read_sds_rank1(int32 file_id, char *sds_name, int32 dim, void *data)
Definition: HDF_Lib.c:359
int32 num_negative_b1[NUM_DETECTORS]
Definition: Granule.h:1089
#define LEADING_L1A_GRANULE
Definition: FNames.h:78
#define CREATE_EV_Aggr_SDS(sd_id, SI_name, UI_name, SU_name, SI_LName, UI_LName, SU_LName, SI_id, UI_id, SU_id)
QA_Refl_t QA_refl
Definition: Granule.h:1099
PGSt_SMF_status Scan_Meta_Cal(lookup_tables_t *tables, L1A_granule_t *L1A_Gran, L1B_granule_t *L1B_Gran, L1B_Scan_Metadata_t *L1B_Scan_Meta, QA_Data_t *QA)
Definition: L1B_Setup.c:3766
#define GEOLOCATION_FILE
Definition: FNames.h:82
boolean Electronic_Anomaly[MAX_NUM_SCANS]
Definition: Granule.h:1076
uint32 saturated_pixels[NUM_BANDS]
Definition: Granule.h:879
int32 L1B_EV_DIM_OFFSET[NUM_L1A_RESOLUTIONS][L1B_EV_SDS_RANK-1]
Definition: L1B_Setup.c:173
int32 v_id
Definition: Granule.h:746
const int NUM_BANDS
int32 sds_id[NUM_L1A_RESOLUTIONS]
Definition: Granule.h:775
const int NUM_DETECTORS
#define L1B_EV_250M_FILE
Definition: FNames.h:69
float32 counts_scale_RefSB[NUM_REFLECTIVE_BANDS]
Definition: Granule.h:805
@ NUM_L1B_EV_FILES
Definition: Granule.h:590
double precision function f(R1)
Definition: tmd.lp.f:1454
#define SAME
Definition: Granule.h:494
#define GEO_STRIDE
Definition: L1B_SetupP.h:94
#define CREATE_EV_SDS(sd_id, SI_name, UI_name, SI_longName, UI_longName, SI_id, UI_id)
int16 L1A_BANDS_AT_RES[NUM_L1A_RESOLUTIONS]
Definition: Granule.c:63
@ BAND26
Definition: Granule.h:643
@ UI_250to1km
Definition: L1B_Setup.c:101
#define REFL_1000M_START_INDEX
#define NUM_SCANS_DIM_NAME
Definition: Granule.h:416
PGSt_SMF_status Create_Band_Subsetting_SDS(L1B_granule_t *L1B_Gran, boolean skip_night_hi_res)
Definition: L1B_Setup.c:3055
#define REFL_250M_START_INDEX
#define BAND_26_SI_SDS_LONG_NAME
Definition: Granule.h:943
float32 Earth_Sun_Dist
Definition: Granule.h:886
int8 moon_in_SV_KOB_RSB[MAX_NUM_SCANS]
Definition: Granule.h:1062
float32 rad_offset_Emiss[NUM_EMISSIVE_BANDS]
Definition: Granule.h:809
#define SOLAR_AZIMUTH_ZENITH_SCALE_FACTOR
Definition: L1B_SetupP.h:136
#define MODIS_F_READ_ERROR
@ UI_500m
Definition: L1B_Setup.c:97
geo_sds_index_t
Definition: L1B_SetupP.h:99
int32 SI_sds_id[NUM_L1A_RESOLUTIONS]
Definition: Granule.h:962
#define EV_1km_FRAMES
Definition: Granule.h:469
#define MAX_ATTR_NAME_SIZE2
const int NUM_REFLECTIVE_BANDS
PGSt_SMF_status Open_W_L1B_Granule(lookup_tables_t *tables, L1B_granule_t *L1B_Gran, L1B_Scan_t *L1B_Scan, boolean skip_night_hi_res)
Definition: L1B_Setup.c:894
int32 EV_250m_Aggr500m_RefSB_UI_sds_id
Definition: Granule.h:967
PGSt_SMF_status Check_Valid_Range(char *data_name, int32 data_type, char *a_lb, char *a_ub, char *a_fillvalue, int32 count, void *buffer)
Definition: HDF_Lib.c:1782
#define REFL_BAND26_START_INDEX
int32 scan_quality[MAX_NUM_SCANS][SCAN_QUALITY_ARRAY_NUM_ELEMENTS]
Definition: Granule.h:754
float32 dn_star_Max[NUM_REFLECTIVE_BANDS]
Definition: Granule.h:797
uint32 Bit_QA_Flags[MAX_NUM_SCANS]
Definition: L1B_Setup.h:73
PGSt_SMF_status Set_SDS_Attributes(int32 *sds_id, char **BandNames, float32 **scale, float32 **offset, char *rad_units, char *refl_units, char *counts_units, int32 num_sds)
Definition: L1B_Setup.c:2871
#define L1B_EV_SDS_RANK
Definition: L1B_Setup.c:162
#define INDEX_1000M_EMISS
Definition: Granule.h:576
void SMF_ERROR(PGSt_SMF_code code, char *messagestring)
Definition: Granule.c:1345
PGSt_SMF_status Init_QA_Parameters(L1A_granule_t *L1A_Gran, L1B_granule_t *L1B_Gran, QA_Data_t *QA)
Definition: L1B_Setup.c:4617
char ScanType[MAX_NUM_SCANS][SCAN_TYPE_TEXT_SIZE]
Definition: Granule.h:752
PGSt_SMF_status L1B_Setup(lookup_tables_t *tables, L1A_granule_t *L1A_Gran, L1B_granule_t *L1B_Gran, L1A_Scan_t *L1A_Scan, L1B_Scan_t *L1B_Scan, QA_Data_t *QA, L1B_Scan_Metadata_t *L1B_Scan_Meta, boolean skip_night_hi_res)
Definition: L1B_Setup.c:218
#define SCAN_INTERVAL
PGSt_SMF_status Create_L1B_Swath(L1B_granule_t *L1B_Gran, boolean skip_night_hi_res)
Definition: L1B_Setup.c:1059
int32 num_day_scans
Definition: Granule.h:861
int32 num_missing_data_in_scans[NUM_DETECTORS]
Definition: Granule.h:1079
int32 EV_250m_Aggr1km_RefSB_SU_sds_id
Definition: Granule.h:971
int32 EV_250m_Aggr500m_RefSB_sds_id
Definition: Granule.h:963
int8 change_dc_restore_500m[MAX_NUM_SCANS][NUM_500M_BANDS][DETECTORS_PER_500M_BAND]
Definition: Granule.h:1058
#define NUM_HIGH_RESOLUTION_DETECTORS
Definition: Granule.h:425
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
float32 L1B_EV_DIM_FRAC_OFFSET[NUM_L1A_RESOLUTIONS][L1B_EV_SDS_RANK-1]
Definition: L1B_Setup.c:179
#define REFL_500M_START_INDEX
PGSt_SMF_status read_attribute(int32 s_id, char *attr_name, int32 TypeID, void *buffer)
Definition: HDF_Lib.c:33
char * L1B_EV_SDS_NAME[NUM_L1B_EV_SDS]
Definition: L1B_Setup.c:106
@ UI_250to500m
Definition: L1B_Setup.c:100
#define MODIS_F_NOK
instead the metadata field ProcessingEnvinronment is filled in from the output of a call to the POSIX compliant function uname from within the L1B code A small bug in L1B_Tables an incorrect comparison of RVS coefficients for TEBs to RVS coefficients for RSBs was being made This was replaced with a comparison between TEB coefficients This error never resulted in an incorrect RVS correction but did lead to recalculating the coefficients for each detector in a thermal band even if the coefficients were the same for all detectors To reduce to overall size of the reflective LUT HDF fill values were eliminated from all LUTs previously dimensioned where and where NUM_TIMES is the number of time dependent table pieces In Preprocess a small error where the trailing dropped scan counter was incremented when the leading dropped scan counter should have been was fixed This counter is internal only and is not yet used for any chiefly to casting of were added to make it LINUX compatible Output of code run on LINUX machines displays differences of at most scaled sector incalculable values of the Emissive calibration factor and incalculable values of SV or BB averages was moved outside the loop over frames in Emissive_Cal c since none of these quantities are frame dependent Initialization of b1 and XMS values in Preprocess c routine Process_OBCENG_Emiss was moved inside the detector loops The code was altered so that if up to five scans are dropped between the leading middle or middle trailing the leading or trailing granule will still be used in emissive calibration to form a cross granule average QA bits and are set for a gap between the leading middle and middle trailing granules respectively This may in rare instances lead to a change in emissive calibration coefficients for scans at the beginning or end of a granule A small bug in the Band correction algorithm was corrected an uncertainty value was being checked against an upper bound whereas the proper quantity to be checked was the corresponding SI
Definition: HISTORY.txt:595
uint8 num_thermistor_outliers[MAX_NUM_SCANS]
Definition: Granule.h:1043
PGSt_SMF_status Set_Unit_Range_Fillvalue(L1B_Scan_t *L1B_Scan, boolean skip_night_hi_res)
Definition: L1B_Setup.c:2439
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
@ BAD_SCAN_QUALITY_CONTROL
Definition: L1B_Tables.h:874
#define L1B_EV_1000M_FILE
Definition: FNames.h:71
PGSt_SMF_status Get_Split_Scan_Indexes(int32 S1, int32 num_scans, int16 mirror_side[], int32 scan_quality[][SCAN_QUALITY_ARRAY_NUM_ELEMENTS], int32 *S_split_1, int32 *S_split_2)
Definition: L1B_Setup.c:5515
int32 num_scans
Definition: Granule.h:860
@ INDEX_GFLAGS
Definition: L1B_SetupP.h:108
PGSt_SMF_status Write_L1B_ScanMeta(L1B_Scan_Metadata_t *L1B_Scan_Meta, L1A_granule_t *L1A_Gran, QA_Data_t *QA, boolean skip_night_hi_res)
Definition: L1B_Setup.c:4810
#define True
Definition: Granule.h:537
@ SI_1km
Definition: L1B_Setup.c:98
char ScanType[MAX_NUM_SCANS][SCAN_TYPE_TEXT_SIZE]
Definition: L1B_Setup.h:71
int32 sd_id[NUM_L1B_EV_FILES]
Definition: Granule.h:859
#define MAX_NUM_SCANS
Definition: Granule.h:422
@ SU_250to1km
Definition: L1B_Setup.c:101
#define PACK_MEMBER(member, buffer_ptr)
int32 num_dead_detector_EV_data[NUM_DETECTORS]
Definition: Granule.h:1080
uint32 missing_pixels[NUM_BANDS]
Definition: Granule.h:880
data_t loc[NROOTS]
Definition: decode_rs.h:78
@ INDEX_L1B_1km
Definition: Granule.h:589
@ NUM_L1B_EV_SDS
Definition: L1B_Setup.c:103
float32 b26_fr_b5_scaled_corr[DETECTORS_PER_1KM_BAND]
Definition: Granule.h:867
int16 RFLAG
Definition: Granule.c:75
L1B_EV_SDS_index_t
Definition: L1B_Setup.c:94
@ SI_500m
Definition: L1B_Setup.c:97
PGSt_SMF_status read_sds_rank2(int32 file_id, char *sds_name, int32 dim1, int32 dim2, void *data)
Definition: HDF_Lib.c:449
int32 Nadir_Frame_Number
Definition: L1B_Setup.h:67
@ UI_250m
Definition: L1B_Setup.c:96
float32 counts_offset_RefSB[NUM_REFLECTIVE_BANDS]
Definition: Granule.h:806
int32 num_rsb_at_night_scans
Definition: Granule.h:1078
#define REFLECTIVE_TABLES_FILE
Definition: FNames.h:74
int32 num_dead_subframe_EV_data[NUM_HIGH_RESOLUTION_DETECTORS]
Definition: Granule.h:1081
int32 sw_f_id[NUM_L1B_EV_FILES]
Definition: Granule.h:857
#define fabs(a)
Definition: misc.h:93
boolean trailing_granule_scan_gap
Definition: Granule.h:1073
float32 rad_scale_Emiss[NUM_EMISSIVE_BANDS]
Definition: Granule.h:808
int16 RSCL_FLAG
Definition: Granule.c:76
#define NUM_DCR_VALUE
Definition: Metadata.h:67
#define NUM_ATTITUDE_ANGLES
Definition: L1B_Tables.h:434
PGSt_SMF_status Set_L1B_EV_SDS_Attrs(lookup_tables_t *tables, L1B_granule_t *L1B_Gran, L1B_Scan_t *L1B_Scan, boolean skip_night_hi_res)
Definition: L1B_Setup.c:2055
int16 bad_data_flag[NUM_BANDS]
Definition: Granule.h:885
@ INDEX_HEIGHT
Definition: L1B_SetupP.h:102
int32 num_no_bg_DN_EV_data[NUM_DETECTORS]
Definition: Granule.h:1084
PGSt_SMF_status Calculate_B26_B5_Correction(float32 *original_correction, float32 *scaled_correction, L1B_ScaleOffset_t *ScaleOffset)
Definition: L1B_Setup.c:5829
QA_Emiss_t QA_emiss
Definition: Granule.h:1098
#define NUM_REFLECTIVE_DETECTORS
Definition: Granule.h:427
#define BAND_26_REFL_INDEX
Definition: L1B_SetupP.h:91
RSB_Cal_Coeff_t RSB_Cal_Coeff
Definition: Granule.h:863
int32 sd_id
Definition: Granule.h:747
float32 Nadir_Frame_Latitude[MAX_NUM_SCANS]
Definition: L1B_Setup.h:65
int32 v_id[NUM_L1B_EV_FILES]
Definition: L1B_Setup.h:60
#define NUM_250M_BANDS
Definition: Granule.h:430
boolean missing_leading_granule
Definition: Granule.h:1070
int16 L1B_BANDS_AT_RES[NUM_L1A_RESOLUTIONS]
Definition: Granule.c:58
#define MODIS_F_HDF_ERROR
int32 EV_250m_Aggr1km_RefSB_sds_id
Definition: Granule.h:964
#define SET_UI_SDS_CONV_ATTRS(sds_id, spec_uncert, scale_factor, indx, numval, lun)
l2prod offset
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
@ UI_1km_EMISS
Definition: L1B_Setup.c:99
#define L1B_OBC_FILE
Definition: FNames.h:72
#define MAX_DETECTORS_PER_BAND
Definition: Granule.h:474
int16 DETECT_PER_BAND_AT_RES[NUM_L1A_RESOLUTIONS]
Definition: Granule.c:68
int8 change_dc_restore_1km[MAX_NUM_SCANS][NUM_1000M_REFL_BANDS][DETECTORS_PER_1KM_BAND]
Definition: Granule.h:1060
#define MAX_ATTR_NAME_SIZE
#define R
Definition: make_L3_v1.1.c:96
void L1BErrorMsg(char *L1B_location, PGSt_SMF_code code, char *input_message, char *assoc_function, int32 lun, char *other_msg, boolean error_out)
Definition: Granule.c:918
char Invalid_MOD01_Msg[]
Definition: Granule.c:913
#define MODIS_F_FILE_NOT_OPENED
@ INDEX_L1B_500m
Definition: Granule.h:588
@ NUM_L1A_RESOLUTIONS
Definition: Granule.h:573
char * Band_subsetting_names[NUM_L1A_RESOLUTIONS]
Definition: L1B_Setup.c:155
int32 EV_250m_Aggr1km_RefSB_UI_sds_id
Definition: Granule.h:968
char * L1A_EV_SDS_NAME[NUM_L1A_RESOLUTIONS]
Definition: L1B_Setup.c:81
GNU GENERAL PUBLIC LICENSE Version
Definition: LICENSE.txt:2
PGSt_SMF_status Write_Swath_Band_Number(int32 file_index, L1B_granule_t *L1B_Gran)
Definition: L1B_Setup.c:1581
#define NUM_1000M_REFL_BANDS
Definition: Granule.h:432
int8 change_dc_restore_250m[MAX_NUM_SCANS][NUM_250M_BANDS][DETECTORS_PER_250M_BAND]
Definition: Granule.h:1056
@ BAND31
Definition: Granule.h:644
const int NUM_EMISSIVE_BANDS
char * L1B_EV_SDS_LONG_NAME[NUM_L1B_EV_SDS]
Definition: L1B_Setup.c:120
PGSt_SMF_status read_vdata(int32 v_id, int32 start_record, int32 records, char *vname, char *fname, void *buffer)
Definition: HDF_Lib.c:748
int i
Definition: decode_rs.h:71
#define MODIS_F_INVALID_ARGUMENT
uint32 dead_detector_pixels[NUM_BANDS]
Definition: Granule.h:882
const int MOON_INSIDE_SV_KOB
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
#define BAND_26_SI_SDS_NAME
Definition: Granule.h:941
int16 MirrorSide[MAX_NUM_SCANS]
Definition: Granule.h:751
uint8 control_options[NUM_CONTROL_OPTIONS]
Definition: L1B_Tables.h:902
float32 Nadir_Frame_Longitude[MAX_NUM_SCANS]
Definition: L1B_Setup.h:66
int32 EV_500m_Aggr1km_RefSB_UI_sds_id
Definition: Granule.h:969
@ SI_250to1km
Definition: L1B_Setup.c:101
PGSt_SMF_status read_part_sds_rank2(int32 sd_id, char *sds_name, int32 start0, int32 start1, int32 edge0, int32 edge1, void *data)
Definition: HDF_Lib.c:150
int16 band_X
Definition: Granule.h:1026
PGSt_SMF_status Calculate_RSB_Cal_Coeff(lookup_tables_t *tables, float32 E_S_Dist, RSB_Cal_Coeff_t *RSB_Cal_Coeff)
Definition: L1B_Setup.c:615
boolean NAD_Door_Open[MAX_NUM_SCANS]
Definition: Granule.h:1074
float64 EVStartTime_TAIsecond[MAX_NUM_SCANS]
Definition: Granule.h:753
#define DETECTORS_PER_250M_BAND
Definition: Granule.h:440
@ UI_1km
Definition: L1B_Setup.c:98
int32 UI_sds_id
Definition: Granule.h:948
version
Definition: setup.py:15
PGSt_SMF_status Get_SDS_id(int32 f, L1B_Scan_t *L1B_Scan, int16 *num_sds, int32 *sds_id)
Definition: L1B_Setup.c:2787
uint32 negative_value_below_noise_pixels[NUM_BANDS]
Definition: Granule.h:884
#define False
Definition: Granule.h:538
PGSt_SMF_status Calculate_DCR_Change(L1A_granule_t *L1A_Gran, QA_Data_t *QA, L1B_Scan_Metadata_t *L1B_Scan_Meta)
Definition: L1B_Setup.c:4339
#define INDEX_1000M_REFL
Definition: Granule.h:575
float32 refl_offset_RefSB[NUM_REFLECTIVE_BANDS]
Definition: Granule.h:803
PGSt_SMF_status Init_L1B_ScaleOffset(L1B_ScaleOffset_t *SO, RSB_Cal_Coeff_t *RSB_Cal_Coeff, float E_S_Dist, lookup_tables_t *tables)
Definition: L1B_Setup.c:736