|
ocssw
1.0
|
00001 /***************************************************************************** 00002 00003 File: Granule.c 00004 00005 External functions: 00006 Aggregate_L1B 00007 Close_L1A_Granule 00008 Close_L1B_Granule 00009 Read_L1A_EV_Scan 00010 safe_strcat 00011 L1BErrorMsg 00012 SMF_ERROR 00013 Bad_L1A_Error_Out 00014 Write_L1B_EV_Scan 00015 Fill_Dead_Detector_SI 00016 Open_and_Read_L1A 00017 Get_Satellite_ID 00018 Read_Run_Time_Parameters 00019 00020 Other functions: 00021 Compute_Aggregates 00022 Write_L1B_SI_UI 00023 00024 Revision History: 00025 $Log: Granule.c,v $ 00026 Revision 1.19 2006-10-27 10:32:58-04 ltan 00027 Changed to write PGEVersion value extracted from the PCF file (LUN 800500). Also check to make sure the PGE Version from the PCF matchs code macro PGE02_VERSION. 00028 00029 Revision 1.15 2005/01/18 21:57:33 ltan 00030 Added new file attributes prefixed with HDFEOS_FractionalOffset 00031 00032 *****************************************************************************/ 00033 00034 #include "L1B_Tables.h" 00035 #include "GranuleP.h" 00036 #include "HDF_Lib.h" 00037 #include "PGS_PC.h" 00038 #include "PGS_TD.h" 00039 #include "PGS_MET.h" 00040 #include "PGS_Error_Codes.h" 00041 #include "FNames.h" 00042 #include <string.h> 00043 #include <math.h> 00044 #include <time.h> 00045 00046 /* MOD_PR02 exit code */ 00047 00048 int32 MOD_PR02_Failure_Exit_Code = 1; 00049 00050 /*---------------------------------------------------------------------------- 00051 The following are external variables used by other modules 00052 ---------------------------------------------------------------------------*/ 00053 00054 int16 L1B_BANDS_AT_RES[NUM_L1A_RESOLUTIONS] = { 00055 NUM_250M_BANDS, NUM_500M_BANDS, 00056 NUM_1000M_REFL_BANDS, NUM_1000M_EMISS_BANDS 00057 }; 00058 00059 int16 L1A_BANDS_AT_RES[NUM_L1A_RESOLUTIONS] = { 00060 NUM_250M_BANDS, NUM_500M_BANDS, 00061 NUM_1000M_DAY_BANDS, NUM_1000M_NIGHT_BANDS 00062 }; 00063 00064 int16 DETECT_PER_BAND_AT_RES [NUM_L1A_RESOLUTIONS] = { 00065 DETECTORS_PER_1KM_BAND * 4, DETECTORS_PER_1KM_BAND * 2, 00066 DETECTORS_PER_1KM_BAND , DETECTORS_PER_1KM_BAND 00067 }; 00068 00069 int16 BAND_RATIO_AT_RES[NUM_L1A_RESOLUTIONS] = {4,2,1,1}; 00070 00071 int16 RFLAG; 00072 int16 RSCL_FLAG; 00073 00074 PGSt_SMF_status Aggregate_L1B (L1B_Scan_t *L1B_Scan) 00075 /* 00076 !C********************************************************************** 00077 !Description: 00078 For one scan of calibrated earth-view data, this routine performs 00079 spatial integration (or aggregation) of each of the higher 00080 resolution bands (250m or 500m) so that they appear at a lower 00081 resolution appropriate for the 500m or 1km L1B granule products. 00082 00083 !Input Parameters: 00084 L1B_Scan_t *L1B_Scan (->SI, ->UI) 00085 00086 !Output Parameters: 00087 L1B_Scan_t *L1B_Scan (->SI_aggr, ->UI_aggr, ->SU_aggr) 00088 00089 !Revision History: 00090 (continue at top of the file) 00091 00092 Revision 02.11 July 1998 00093 Modified the routine to match the change of L1B_Scant_t change. 00094 Zhenying Gu (zgu@ltpmail.gsfc.nasa.gov) 00095 00096 Revision 01.00 April 1997 00097 Initial development 00098 (based on the routine Compute_Aggregates, which 00099 is a C translation of the FORTRAN code written 00100 by Vicky Lin & Rich Hucek) 00101 Zhidong Hao (hao@barebackride.gsfc.nasa.gov) 00102 00103 !Team-unique Header: 00104 This software is developed by the MODIS Characterization Support 00105 Team (MCST)for the National Aeronautics and Space Administration, 00106 Goddard Space Flight Center, under contract NAS5-32373. 00107 00108 !References and Credits: 00109 HDF portions developed at the National Center for Supercomputing 00110 Applications at the University of Illinois at Urbana-Champaign. 00111 00112 !Design Notes: 00113 00114 !END******************************************************************** 00115 */ 00116 { 00117 PGSt_SMF_status returnStatus = MODIS_S_OK; 00118 int16 B = 0; 00119 int16 line_dim = 0; 00120 int16 pixel_dim = 0; 00121 00122 /*------------------ 00123 250_to_500m 00124 -------------------*/ 00125 line_dim = DETECT_PER_BAND_AT_RES[INDEX_500M]; 00126 pixel_dim = BAND_RATIO_AT_RES[INDEX_500M] * EV_1km_FRAMES; 00127 00128 for (B = 0; B < L1B_BANDS_AT_RES[INDEX_250M]; B++) 00129 { 00130 returnStatus = Compute_Aggregates 00131 (2, line_dim, pixel_dim, 00132 (VOIDP)L1B_Scan->SI.EV_250m_RefSB[B], 00133 (VOIDP)L1B_Scan->UI.EV_250m_RefSB_UI[B], 00134 (VOIDP)L1B_Scan->EV_250m_Aggr500m_RefSB[B], 00135 (VOIDP)L1B_Scan->EV_250m_Aggr500m_RefSB_UI[B], 00136 (VOIDP)L1B_Scan->EV_250m_Aggr500m_RefSB_SU[B]); 00137 if (returnStatus != MODIS_S_OK) 00138 SMF_ERROR(returnStatus, 00139 "Compute_Aggregates(250_to_500m) in " 00140 "Aggregate_L1B(), Granule.c"); 00141 } 00142 00143 00144 /*--------------------------- 00145 250_to_1km & 500_to_1km 00146 ---------------------------*/ 00147 line_dim = DETECT_PER_BAND_AT_RES[INDEX_1000M_REFL]; 00148 pixel_dim = EV_1km_FRAMES; 00149 00150 if ((RFLAG & 1) == 0) { 00151 for (B = 0; B < L1B_BANDS_AT_RES[INDEX_250M]; B++) 00152 { 00153 returnStatus = Compute_Aggregates 00154 (4, line_dim, pixel_dim, 00155 (VOIDP)L1B_Scan->SI.EV_250m_RefSB[B], 00156 (VOIDP)L1B_Scan->UI.EV_250m_RefSB_UI[B], 00157 (VOIDP)L1B_Scan->EV_250m_Aggr1km_RefSB[B], 00158 (VOIDP)L1B_Scan->EV_250m_Aggr1km_RefSB_UI[B], 00159 (VOIDP)L1B_Scan->EV_250m_Aggr1km_RefSB_SU[B]); 00160 if (returnStatus != MODIS_S_OK) 00161 SMF_ERROR(returnStatus, 00162 "Compute_Aggregates(250_to_1km) in " 00163 "Aggregate_L1B(), Granule.c"); 00164 } 00165 } 00166 00167 if ((RFLAG & 2) == 0) { 00168 for (B = 0; B < L1B_BANDS_AT_RES[INDEX_500M]; B++) 00169 { 00170 returnStatus = Compute_Aggregates 00171 (2, line_dim, pixel_dim, 00172 (VOIDP)L1B_Scan->SI.EV_500m_RefSB[B], 00173 (VOIDP)L1B_Scan->UI.EV_500m_RefSB_UI[B], 00174 (VOIDP)L1B_Scan->EV_500m_Aggr1km_RefSB[B], 00175 (VOIDP)L1B_Scan->EV_500m_Aggr1km_RefSB_UI[B], 00176 (VOIDP)L1B_Scan->EV_500m_Aggr1km_RefSB_SU[B]); 00177 if (returnStatus != MODIS_S_OK) 00178 SMF_ERROR(returnStatus, 00179 "Compute_Aggregates(500_to_1km) in " 00180 "Aggregate_L1B(), Granule.c"); 00181 } 00182 } 00183 00184 return(MODIS_S_OK); 00185 } 00186 00187 00188 PGSt_SMF_status Close_L1A_Granule (L1A_granule_t *L1A_Gran, 00189 L1A_Scan_t *L1A_Scan) 00190 /* 00191 !C********************************************************************** 00192 !Description: 00193 This routine ends access to all L1A SDSs and ends the SD and Vdata 00194 interfaces to the L1A middle granule file. 00195 00196 !Input Parameters: 00197 L1A_granule_t *L1A_Gran 00198 L1A_Scan_t *L1A_Scan 00199 00200 !Output Parameters: 00201 L1A_granule_t *L1A_Gran 00202 L1A_Scan_t *L1A_Scan 00203 00204 !Revision History: 00205 (continue at top of the file) 00206 00207 Revision 02.11 July 1998 00208 Removed Cleanup_L1A_Granule ( the arrays are changed to static allocated ) 00209 Zhenying Gu (zgu@ltpmail.gsfc.nasa.gov) 00210 00211 Revision 02.00 March 1997 00212 Modified to match changes in L1A_granule_t & L1A_Scan_t. 00213 Zhidong Hao (hao@barebackride.gsfc.nasa.gov) 00214 00215 (Neal's version between 01.01 & 02.00 ......???) 00216 00217 Revision 01.01 1996/04/05 00218 Updated to match Version Design Document. 00219 John Hannon(hannon@highwire.gsfc.nasa.gov) 00220 Joan Baden (baden@highwire.gsfc.nasa.gov) 00221 00222 Revision 01.00 1993 00223 Initial development 00224 Geir E. Kvaran(geir@highwire.gsfc.nasa.gov) 00225 00226 !Team-unique Header: 00227 00228 !References and Credits: 00229 This software is developed by the MODIS Characterization Support 00230 Team (MCST)for the National Aeronautics and Space Administration, 00231 Goddard Space Flight Center, under contract NAS5-32373. 00232 00233 HDF portions developed at the National Center for Supercomputing 00234 Applications at the University of Illinois at Urbana-Champaign. 00235 00236 !Design Notes: 00237 00238 !END******************************************************************** 00239 */ 00240 { 00241 PGSt_SMF_status returnStatus = MODIS_S_OK; 00242 int16 R = 0; 00243 00244 /*Close L1A EV SDS's*/ 00245 for (R = 0; R < NUM_L1A_RESOLUTIONS; R++) { 00246 if ((RFLAG & (1 << R)) != 0) continue; 00247 if (SDendaccess(L1A_Scan->sds_id[R]) == FAIL) 00248 return(MODIS_F_NOK); 00249 } 00250 00251 /*Clode L1A file*/ 00252 if (SDend(L1A_Gran->sd_id) == FAIL) /* close the SD interface */ 00253 return(MODIS_F_NOK); 00254 00255 if (Vend(L1A_Gran->v_id) == FAIL) 00256 return(MODIS_F_NOK); 00257 00258 if (Hclose(L1A_Gran->v_id) == FAIL) /* close the Vdata interface */ 00259 return(MODIS_F_NOK); 00260 00261 return(returnStatus); 00262 } 00263 00264 PGSt_SMF_status Close_L1B_Granule (L1B_granule_t *L1B_Gran, 00265 L1B_Scan_t *L1B_Scan, 00266 boolean skip_night_hi_res) 00267 /* 00268 !C********************************************************************** 00269 !Description: 00270 This routine ends SDS access to all open EV SDSs and ends swath interface 00271 to all L1B EV granule files. 00272 00273 !Input Parameters: 00274 L1B_granule_t *L1B_Gran 00275 L1B_Scan_t *L1B_Scan 00276 Run_Time_Parameters_t *runtime_params Values read from PCF file. 00277 boolean skip_night_hi_res Logical; TRUE if and only 00278 if all scans in the granule 00279 are in NIGHT mode. 00280 00281 !Output Parameters: 00282 L1B_granule_t *L1B_Gran 00283 L1B_Scan_t *L1B_Scan 00284 00285 !Revision History: 00286 (continue at top of the file) 00287 00288 Revision 02.21 November 13, 2001 (Razor Issue #169) 00289 Added skip_night_hi_res to input variables. 00290 Changed logic so that 250m and 500m data are not written when granule 00291 has no day mode scans and runtime parameter 00292 Write_Night_Mode_HiRes_Data is False. 00293 Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov) 00294 00295 Revision 02.20 May 1999 00296 Added band 26 section. 00297 Jim Rogers (rogers@mcst.gsfc.nasa.gov) 00298 00299 Revision 02.11 July 1998 00300 Removed Cleanup_L1B_Granule(), because all arrays are changed to 00301 static allocated. 00302 Zhenying Gu (zgu@ltpmail.gsfc.nasa.gov) 00303 00304 Revision 02.00 March 1997 00305 Modified to match changes in L1B_granule_t & L1B_Scan_t. 00306 Zhidong Hao (hao@barebackride.gsfc.nasa.gov) 00307 00308 (Neal's version between 01.01 & 02.00 ......???) 00309 00310 Revision 01.01 1996/04/05 00311 Uppdated to match Version 1 Design Document. 00312 John Hannon(hannon@highwire.gsfc.nasa.gov) 00313 Joan Baden (baden@highwire.gsfc.nasa.gov) 00314 00315 Revision 01.00 1993 00316 Initial development 00317 Geir E. Kvaran(geir@highwire.gsfc.nasa.gov) 00318 00319 !Team-unique Header: 00320 00321 !References and Credits: 00322 This software is developed by the MODIS Characterization Support 00323 Team (MCST)for the National Aeronautics and Space Administration, 00324 Goddard Space Flight Center, under contract NAS5-32373. 00325 00326 HDF portions developed at the National Center for Supercomputing 00327 Applications at the University of Illinois at Urbana-Champaign. 00328 00329 !Design Notes: 00330 Code to make Vgroup has been removed. It is not currently implemented 00331 in SDS_Services, although it could be. 00332 !END******************************************************************** 00333 */ 00334 { 00335 PGSt_SMF_status returnStatus = MODIS_S_OK; 00336 int16 R = 0; 00337 int16 f = 0; 00338 int16 start_output_index = 0; 00339 00340 if (skip_night_hi_res == True) 00341 start_output_index = INDEX_L1B_1km; 00342 else 00343 start_output_index = INDEX_L1B_250m; 00344 00345 /*Close L1B EV SDS's*/ 00346 00347 for (R = start_output_index; R < NUM_L1A_RESOLUTIONS; R++) 00348 { 00349 if ((RFLAG & (1 << R)) != 0) continue; 00350 if (SDendaccess(L1B_Scan->SI_sds_id[R]) == FAIL) return(MODIS_F_NOK); 00351 if (SDendaccess(L1B_Scan->UI_sds_id[R]) == FAIL) return(MODIS_F_NOK); 00352 } 00353 if (skip_night_hi_res == False) 00354 { 00355 if (SDendaccess(L1B_Scan->EV_250m_Aggr500m_RefSB_sds_id) == FAIL) 00356 return(MODIS_F_NOK); 00357 if (SDendaccess(L1B_Scan->EV_250m_Aggr500m_RefSB_UI_sds_id) == FAIL) 00358 return(MODIS_F_NOK); 00359 if (SDendaccess(L1B_Scan->EV_250m_Aggr500m_RefSB_SU_sds_id) == FAIL) 00360 return(MODIS_F_NOK); 00361 } 00362 00363 if (SDendaccess(L1B_Scan->EV_250m_Aggr1km_RefSB_sds_id) == FAIL) 00364 return(MODIS_F_NOK); 00365 if (SDendaccess(L1B_Scan->EV_250m_Aggr1km_RefSB_UI_sds_id) == FAIL) 00366 return(MODIS_F_NOK); 00367 if (SDendaccess(L1B_Scan->EV_250m_Aggr1km_RefSB_SU_sds_id) == FAIL) 00368 return(MODIS_F_NOK); 00369 if (SDendaccess(L1B_Scan->EV_500m_Aggr1km_RefSB_sds_id) == FAIL) 00370 return(MODIS_F_NOK); 00371 if (SDendaccess(L1B_Scan->EV_500m_Aggr1km_RefSB_UI_sds_id) == FAIL) 00372 return(MODIS_F_NOK); 00373 if (SDendaccess(L1B_Scan->EV_500m_Aggr1km_RefSB_SU_sds_id) == FAIL) 00374 return(MODIS_F_NOK); 00375 00376 /************************* Begin Band 26 Section **************************/ 00377 #ifdef WRITE_BAND_26_SDS 00378 /* 00379 * Close SDS access to the band 26 SDSs. 00380 */ 00381 if (SDendaccess(L1B_Scan->Band26.SI_sds_id) == FAIL) 00382 return(MODIS_F_NOK); 00383 if (SDendaccess(L1B_Scan->Band26.UI_sds_id) == FAIL) 00384 return(MODIS_F_NOK); 00385 #endif /* WRITE_BAND_26_SDS */ 00386 /************************** End Band 26 Section ***************************/ 00387 00388 /* 00389 * If this granule has no day mode scans and the runtime parameter 00390 * Write_Night_Mode_HiRes_Data is False, the 250m and 500m 00391 * resolution files were not written, and so start with output 00392 * file number 2, not 0. 00393 */ 00394 00395 if (skip_night_hi_res == True) 00396 start_output_index = INDEX_L1B_1km; 00397 else 00398 start_output_index = INDEX_L1B_250m; 00399 00400 00401 /*Close L1B EV files*/ 00402 for (f = start_output_index; f < NUM_L1B_EV_FILES; f++) 00403 if (SWclose(L1B_Gran->sw_f_id[f]) == FAIL) return(MODIS_F_NOK); 00404 00405 return(returnStatus); 00406 } 00407 00408 00409 PGSt_SMF_status Compute_Aggregates (int16 scale, 00410 int16 line_dim_lower, 00411 int16 frame_dim_lower, 00412 uint16 *SI_in, 00413 uint8 *UI_in, 00414 uint16 *SI_out, 00415 uint8 *UI_out, 00416 int8 *SU_out) 00417 /* 00418 !C**************************************************************************** 00419 !Description: 00420 Perform spatial integration (aggregation) of higher resolution L1B data to 00421 appear as lower resolution data. This function computes the aggregated 00422 scaled integer, the aggregated uncertainty index and the number of samples 00423 used in aggregation. 00424 00425 !Input Parameters: 00426 int16 scale spatial integration factor, in both the along track 00427 and along scan directions of the data. (there are 00428 limited valid values -- see the local variables) 00429 int16 line_dim_lower line dimension (along track) of lower resolution data 00430 int16 frame_dim_lower frame dimension (along scan) of lower resolution data 00431 uint16 *SI_in scaled integer data of higher resolution 00432 (size = line_dim_lower * scale * frame_dim_lower * scale) 00433 uint8 *UI_in uncertainty index data of higher resolution 00434 (size = line_dim_lower * scale * frame_dim_lower * scale) 00435 00436 !Output Parameters: 00437 uint16 *SI_out aggregated scaled integer data at lower resolution 00438 (array size = line_dim_lower * frame_dim_lower). 00439 uint8 *UI_out aggregated uncertainty index data at lower resolution 00440 (array size = line_dim_lower * frame_dim_lower). 00441 int8 *SU_out number of samples used in each aggregation 00442 (array size = line_dim_lower * frame_dim_lower). 00443 00444 !Revision History: 00445 (continue at top of the file) 00446 00447 Revision 01.01, January 9, 2001, Razor issue 149 00448 The assumption on how the first samples of different resolution data are 00449 registered was corrected. Also added design notes, made variable names more 00450 meaningful, improved efficiency slightly and added comments. 00451 Jim Rogers (rogers@mcst.gsfc.nasa.gov) 00452 00453 Revision 01.00 April 1997 00454 Initial development 00455 (this is a translation of the FORTRAN code, 00456 Aggregate_L1B, of Vicky Lin & Richard Hucek) 00457 Zhidong Hao (hao@barebackride.gsfc.nasa.gov) 00458 00459 !Team-unique Header: 00460 This software is developed by the MODIS Characterization Support 00461 Team (MCST)for the National Aeronautics and Space Administration, 00462 Goddard Space Flight Center, under contract NAS5-32373. 00463 00464 !References and Credits: 00465 This code is translated from the FORTRAN code written by 00466 Vicky Lin (vlin@ltpmail.gsfc.nasa.gov) 00467 Richard Hucek (rhucek@ltpmail.gsfc.nasa.gov) 00468 HDF portions developed at the National Center for Supercomputing 00469 Applications at the University of Illinois at Urbana-Champaign. 00470 00471 !Design Notes: 00472 1. For the input and output arrays of data, each array represents a 00473 2D array, similar to: 00474 A[line_dim_lower][frame_dim_lower] (lower resolution) 00475 A[line_dim_lower*scale][frame_dim_lower*scale] (higher resolution) 00476 Thus, each higher resolution array has scale^2 times the values of 00477 a lower resolution array. 00478 2. In the line dimension (along track), each set of scale lines of the 00479 higher resolution are averaged (using uniform weighting) to form 00480 one aggregated line at the lower resolution. 00481 3. In the frame dimension (along scan), the effective response of a 00482 detector of either resolution is a triangle function, with the peak of 00483 the triangle at the effective location of the frame, and the base 00484 of the triangle having a total width of 2 times the frame width. The 00485 triangular responses are overlapping by 1/2 the frame width 00486 (see the Geolocation ATBD for an explanation and diagram). 00487 4. The frames of different resolutions are registered such that the 1st 00488 frame of any line at one resolution is aligned with the first frame 00489 in a line of a different resolution. 00490 5. To aggregate in the frame dimension, (2*scale-1) consecutive values 00491 are chosen with triangular weighting to form the aggregated response. 00492 Because of the assumption in item 4 above, the first (scale-1) frames 00493 are missing from the first aggregate in any given line. 00494 00495 !END************************************************************************** 00496 */ 00497 { 00498 int16 lines_to_aggregate; /* number of lines of higher resolution data 00499 * to aggregate to one line of lower resolution 00500 * data (same as input value of "scale"). 00501 */ 00502 int16 frames_to_aggregate; /* number of frames (triangle functions) of 00503 * higher resolution data to aggregate to one 00504 * frame of lower resolution data (2*scale-1). 00505 */ 00506 int16 line_offset; /* essentially this is the index of the first 00507 * line of higher resolution data to use in 00508 * one aggregation across the set of lines. 00509 */ 00510 int16 frame_offset; /* essentially this is the index of the first 00511 * frame of higher resolution data to use in 00512 * one aggregation across the set of frames. 00513 */ 00514 int16 frame_dim_higher; /* number of higher resolution frames in each 00515 * line of higher resolution data (must be 00516 * frame_dim_lower * scale). 00517 */ 00518 int16 L1; /* line index in lower resolution data */ 00519 int16 F1; /* frame index in lower resolution data */ 00520 int16 L2; /* line index in higher resolution data */ 00521 int16 L; /* line index in one set of higher resolution 00522 * lines to aggregate. 00523 */ 00524 int16 F; /* frame index in one set of higher resolution 00525 * frames to aggregate. 00526 */ 00527 int16 F_start; /* starting frame index within one set of 00528 * higher resolution frames to aggregate. 00529 * (not necessarily 0 because of design note 4). 00530 */ 00531 int16 scale_index; /* index in 1st dimension of W and SqW arrays */ 00532 int32 index_higher; /* array index within any higher resolution 00533 * array (must be int32). 00534 */ 00535 int32 index_lower; /* array index within any lower resolution 00536 * array (must be int32). 00537 */ 00538 int8 samples; /* used to count number of valid samples used 00539 * in one aggregation. 00540 */ 00541 float32 sum_W; /* accumulates the weight factors */ 00542 float32 sum_WSI; /* accumulates the weighted scaled integer */ 00543 float32 sum_SqW; /* accumulates the square of the weight factors */ 00544 float32 sum_SqWUI; /* accumulates the square of the weighted UI */ 00545 00546 /* 00547 * The following define how many valid scale factors are handled by this 00548 * function and the maximum number of frames for triangle weighting. 00549 */ 00550 00551 #define NUM_SCALE_FACTORS 2 00552 #define MAX_AGGR_FRAMES 7 00553 00554 /* 00555 * The following arrays hold the valid scale factors and the associated 00556 * weighting factors, for aggregating along the frame (scan) dimension. 00557 * W = weight 00558 * SqW = square of weight. 00559 * The number of frames to aggregate is (2 * scale - 1). 00560 */ 00561 00562 int16 valid_scale_values[NUM_SCALE_FACTORS] = {2, 4}; 00563 00564 float32 W[NUM_SCALE_FACTORS][MAX_AGGR_FRAMES] = { 00565 {1, 2, 1, 0, 0, 0, 0}, 00566 {1, 2, 3, 4, 3, 2, 1} 00567 }; 00568 00569 float32 SqW[NUM_SCALE_FACTORS][MAX_AGGR_FRAMES] = { 00570 {1, 4, 1, 0, 0, 0, 0}, 00571 {1, 4, 9, 16, 9, 4, 1} 00572 }; 00573 00574 /*************************************************************************/ 00575 00576 /* 00577 * Determine the "scale_index", the index in the W and SqW arrays. 00578 * This checks the value of "scale" in the process. 00579 */ 00580 00581 for (scale_index = 0; scale_index < NUM_SCALE_FACTORS; scale_index++) 00582 { 00583 if (scale == valid_scale_values[scale_index]) 00584 break; 00585 } 00586 if (scale_index == NUM_SCALE_FACTORS) 00587 { 00588 char errmsg[512]; 00589 sprintf (errmsg, "Input argument (scale = %d) is invalid.", scale); 00590 L1BErrorMsg("Compute_Aggregates", MODIS_F_INVALID_ARGUMENT, errmsg, NULL, 0, 00591 NULL, True); 00592 } 00593 00594 00595 lines_to_aggregate = scale; 00596 frames_to_aggregate = 2 * scale - 1; 00597 frame_dim_higher = frame_dim_lower * scale; 00598 00599 line_offset = 0; 00600 for (L1 = 0; L1 < line_dim_lower; L1++, line_offset += scale) 00601 { 00602 00603 /* 00604 * frame_offset starts negative. For the first aggregation of a line, 00605 * we will start at the peak of the triangle weight to compensate. 00606 */ 00607 00608 frame_offset = - (scale - 1); 00609 for (F1 = 0; F1 < frame_dim_lower; F1++, frame_offset += scale) 00610 { 00611 00612 /* 00613 * Because the first frames of different resolutions align, for the 00614 * first aggregate of a line we are missing some frames on the left side 00615 * of the triangle weighting function. Set F_start so that we will 00616 * have a valid frame index later. 00617 */ 00618 00619 if (F1 == 0) 00620 F_start = scale - 1; /* start at the peak of triangle weighting */ 00621 else 00622 F_start = 0; /* start at beginning of triangle weighting */ 00623 00624 samples = 0; 00625 sum_W = 0; 00626 sum_WSI = 0; 00627 sum_SqW = 0; 00628 sum_SqWUI = 0; 00629 00630 for (L = 0; L < lines_to_aggregate; L++) 00631 { 00632 L2 = line_offset + L; 00633 00634 index_higher = L2 * frame_dim_higher + frame_offset + F_start; 00635 for (F = F_start; F < frames_to_aggregate; F++, index_higher++) 00636 { 00637 if (SI_in[index_higher] <= DN15_SAT) 00638 { 00639 samples++; 00640 sum_W += W[scale_index][F]; 00641 sum_WSI += W[scale_index][F] * SI_in[index_higher]; 00642 sum_SqW += SqW[scale_index][F]; 00643 sum_SqWUI += SqW[scale_index][F] * UI_in[index_higher] * UI_in[index_higher]; 00644 } 00645 } 00646 } 00647 00648 index_lower = L1 * frame_dim_lower + F1; 00649 if (samples > 0) 00650 { 00651 SI_out[index_lower] = (uint16)(sum_WSI / sum_W + 0.5); 00652 UI_out[index_lower] = (uint8)(sqrt((double)(sum_SqWUI / sum_SqW)) + 0.5); 00653 SU_out[index_lower] = samples; 00654 } 00655 else 00656 { 00657 SI_out[index_lower] = AGGREGATION_FAIL_SI; 00658 UI_out[index_lower] = BAD_DATA_UI; 00659 SU_out[index_lower] = 0; 00660 } 00661 } 00662 } 00663 00664 return(MODIS_S_OK); 00665 } 00666 00667 PGSt_SMF_status Read_L1A_EV_Scan (int16 S, 00668 L1A_granule_t *L1A_Gran, 00669 L1A_Scan_t *L1A_Scan) 00670 /* 00671 !C************************************************************************** 00672 !Description: 00673 For the input scan index, S, this routine reads earth-view (EV) scaled 00674 integer data for each of the four L1A EV SDSs: EV_250m, EV_500m, 00675 EV_1km_day, and EV_1km_night. If the scan is not a "Day" mode scan, 00676 then only the data from the EV_1km_night SDS is read. 00677 00678 !Input Parameters: 00679 int16 S current scan index 00680 L1A_granule_t *L1A_Gran contains day-night flag, number of scans 00681 and valid SDS ids for each L1A EV SDS. 00682 00683 !Output Parameters: 00684 L1A_Scan_t *L1A_Scan filled SDS data for all resolutions of 1 scan 00685 00686 !Revision History: 00687 (continue at top of the file) 00688 00689 Revision 02.1.2, January 22, 2001 00690 Corrected variable names and simplified the logic within this function 00691 to remove unnecessary lines. Added design notes. 00692 Jim Rogers (rogers@mcst.gsfc.nasa.gov) 00693 00694 Revision 02.1.1 July 1997 00695 Modified to match change in L1A_Scan_t; 00696 Zhenying Gu (zgu@ltpmail.gsfc.nasa.gov) 00697 00698 Revision 02.00 March 1997 00699 Modified to match change in L1A_Scan_t; 00700 limited processing to EV data. 00701 Zhidong Hao (hao@barebackride.gsfc.nasa.gov) 00702 00703 (Neal's version between 01.01 & 02.00......???) 00704 00705 Revision 01.01 1996/04/05 00706 Update to match Version 1 Design Document 00707 John Hannon(hannon@highwire.gsfc.nasa.gov) 00708 Joan Baden (baden@highwire.gsfc.nasa.gov) 00709 00710 Revision 01.00 1993 00711 Initial development 00712 Geir E. Kvaran(geir@highwire.gsfc.nasa.gov) 00713 00714 !Team-unique Header: 00715 This software is developed by the MODIS Characterization Support 00716 Team (MCST)for the National Aeronautics and Space Administration, 00717 Goddard Space Flight Center, under contract NAS5-32373. 00718 00719 !References and Credits: 00720 HDF portions developed at the National Center for Supercomputing 00721 Applications at the University of Illinois at Urbana-Champaign. 00722 00723 !Design Notes: 00724 1. We only need to read the 250m, 500m and 1km_day SDS data if the scan 00725 is a "Day" scan, according to the day-night flag. We always read the 00726 1km_night data. 00727 2. The L1A SDSs are oversized in terms of the number of frames. We 00728 read the full set of data for 1 scan to make the internal read 00729 more efficient (each call will read one stream of data from the file 00730 rather than having to read many disjointed streams of data). 00731 !END************************************************************************ 00732 */ 00733 { 00734 int16 R; /* L1A resolution index */ 00735 int16 D; /* Detector index */ 00736 int16 B; /* Band index */ 00737 int32 start[3] = {0, 0, 0}; /* starting indices, each dimension */ 00738 /* (must be initialized to zero) */ 00739 int32 edge[3]; /* # of elements to read, each dimension */ 00740 intn hdf_return; 00741 char *location = "Read_L1A_EV_Scan"; /* This function name */ 00742 int16 *ev_data_p[NUM_L1A_RESOLUTIONS]; /* pointers to each SDS data */ 00743 int32 offset; 00744 00745 /* 00746 * Check gross validity of inputs. 00747 */ 00748 00749 if (S < 0 || S >= L1A_Gran->num_scans || !L1A_Scan || !L1A_Gran) { 00750 L1BErrorMsg(location, MODIS_F_INVALID_ARGUMENT, 00751 "Scan index (S), L1A_Gran or L1A_Scan value is invalid.", 00752 NULL, FIRST_L1A_GRANULE, NULL, True); 00753 return MODIS_F_INVALID_ARGUMENT; 00754 } 00755 00756 /* 00757 * Assign data pointers. 00758 */ 00759 00760 ev_data_p[INDEX_250M] = (int16 *) L1A_Scan->EV_250m; 00761 ev_data_p[INDEX_500M] = (int16 *) L1A_Scan->EV_500m; 00762 ev_data_p[INDEX_1000M_DAY] = (int16 *) L1A_Scan->EV_1km_day; 00763 ev_data_p[INDEX_1000M_NIGHT] = (int16 *) L1A_Scan->EV_1km_night; 00764 00765 /* 00766 * Loop through L1A resolutions and read one scan of L1A data. 00767 * (see design notes regarding which SDSs to read). 00768 */ 00769 00770 for (R = 0; R < NUM_L1A_RESOLUTIONS; R++) 00771 { 00772 if ((RFLAG & (1 << R)) != 0) continue; 00773 00774 if (strcmp(L1A_Gran->ScanType[S],"Day") == SAME || 00775 R == INDEX_1000M_EMISS) 00776 { 00777 00778 if (L1A_Gran->Extract_Pixel_Offset == -1 && 00779 L1A_Gran->Extract_Pixel_Count == -1) { 00780 00781 start[0] = S * DETECT_PER_BAND_AT_RES[R]; 00782 edge[0] = DETECT_PER_BAND_AT_RES[R]; 00783 edge[1] = L1A_BANDS_AT_RES[R]; 00784 edge[2] = EV_1km_FRAMES * BAND_RATIO_AT_RES[R]; 00785 00786 hdf_return = SDreaddata (L1A_Scan->sds_id[R], start, NULL, edge, 00787 ev_data_p[R]); 00788 if (hdf_return == FAIL) { 00789 char errmsg[256]; 00790 char *resnames[NUM_L1A_RESOLUTIONS] = { 00791 "250m", "500m", "1km_day", "1km_night" 00792 }; 00793 sprintf (errmsg, "Could not read L1A SDS: EV_%s.", resnames[R]); 00794 L1BErrorMsg(location, MODIS_F_READ_ERROR, errmsg, 00795 "SDreaddata", FIRST_L1A_GRANULE, NULL, True); 00796 return MODIS_F_READ_ERROR; 00797 } 00798 } else { 00799 00800 /* Clear buffer */ 00801 memset(ev_data_p[R], 0, DETECT_PER_BAND_AT_RES[R] * L1A_BANDS_AT_RES[R] * 00802 EV_1km_FRAMES * BAND_RATIO_AT_RES[R]); 00803 00804 for (D = 0; D < DETECT_PER_BAND_AT_RES[R]; D++) 00805 00806 for (B = 0; B < L1A_BANDS_AT_RES[R]; B++) { 00807 start[0] = S*DETECT_PER_BAND_AT_RES[R] + D; 00808 start[1] = B; 00809 start[2] = 0; 00810 edge[0] = 1; 00811 edge[1] = 1; 00812 edge[2] = L1A_Gran->Extract_Pixel_Count * BAND_RATIO_AT_RES[R]; 00813 00814 offset = (D*L1A_BANDS_AT_RES[R]*EV_1km_FRAMES + 00815 B*EV_1km_FRAMES + L1A_Gran->Extract_Pixel_Offset) * 00816 BAND_RATIO_AT_RES[R]; 00817 00818 hdf_return = SDreaddata (L1A_Scan->sds_id[R], start, NULL, edge, 00819 &ev_data_p[R][offset]); 00820 } 00821 } 00822 } 00823 } 00824 00825 return MODIS_S_OK; 00826 } 00827 00828 00829 #include <string.h> /* for the strcat function */ 00830 00831 int safe_strcat(char *buf, char *str, int buflen) 00832 /* 00833 !C***************************************************************************** 00834 !Description: 00835 Safely concatenate a string onto a buffer. If neccessary, truncate the 00836 string to fit onto the end of the buffer, allowing a null to be at the end. 00837 Return values: 00838 0: the string was completely and successfully concatenated onto the end 00839 of the buffer. 00840 1: the buffer did not exist, the string did not exist or the buffer was 00841 to small to hold the entire string -- in which case as many characters 00842 as possible from the string are concatenated onto the end of the buffer. 00843 00844 !Input Parameters: 00845 char *buf Buffer holding characters to which we are concatenating 00846 a string onto the end of. 00847 char *str The string to be placed at the end of the buffer. 00848 int buflen The memory length of the buffer (not the string length). 00849 00850 !Output Parameters: 00851 (none) 00852 00853 !Revision History: 00854 (continue at top of the file) 00855 00856 Revision 1.0.1 January 17, 2002 Razor Issue #172 00857 Improve portability of code to 64-bit mode. 00858 Change variables j, nb, and ns to type size_t. 00859 Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov) 00860 00861 Revision 1.0 Nov. 1, 1999 00862 Initial development. 00863 Jim Rogers (rogers@mcst.gsfc.nasa.gov) 00864 00865 !Team-unique Header: 00866 This software is developed by the MODIS Characterization Support 00867 Team (MCST)for the National Aeronautics and Space Administration, 00868 Goddard Space Flight Center, under contract NAS5-32373. 00869 00870 !References and Credits: 00871 HDF portions developed at the National Center for Supercomputing 00872 Applications at the University of Illinois at Urbana-Champaign. 00873 00874 !Design Notes: 00875 00876 00877 !END****************************************************************************** 00878 */ 00879 { 00880 int i; /* indexes */ 00881 size_t j; 00882 size_t nb; /* string length of buf */ 00883 size_t ns; /* string length of str */ 00884 int mx; /* maximum number of non-null chars allowed in buffer */ 00885 00886 if (!buf || !str || buflen <= 0) return 1; 00887 00888 /* Compute total length of required memory. */ 00889 00890 nb = strlen(buf); 00891 ns = strlen(str); 00892 if ((nb + ns) < buflen) { 00893 strcat(buf, str); 00894 return 0; 00895 } 00896 else { 00897 mx = buflen - 1; 00898 for (i = 0, j = nb; j < mx; i++, j++) buf[j] = str[i]; 00899 buf[mx] = '\0'; 00900 return 1; 00901 } 00902 } 00903 00904 00905 /* 00906 * The following are global values to use for the "other_msg" input to 00907 * L1BErrorMsg. These errors may occur many times. 00908 */ 00909 00910 char Invalid_MOD01_Msg[] = "\ 00911 The MOD01 granule appears to be invalid. Data values are present\n\ 00912 that are not allowed by the MOD01 file specifications."; 00913 00914 00915 void L1BErrorMsg( 00916 char *L1B_location, /* name of L1B function that error occurred in */ 00917 PGSt_SMF_code code, /* associated error code for this error */ 00918 char *input_message, /* short (usually 1-line) description of error */ 00919 char *assoc_function, /* name of an associated function that failed */ 00920 int32 lun, /* associated LUN for the file being accessed */ 00921 char *other_msg, /* other message to add such as probable cause */ 00922 boolean error_out /* flag to tell whether or not to call SMF_ERROR */ 00923 ) 00924 /* 00925 !C********************************************************************** 00926 !Description: 00927 Format an error message and write it to the LogReport and LogStatus 00928 files. If the flag "error_out" is True, then also call SMF_ERROR. 00929 Otherwise, this function will simply return to continue processing. 00930 The general form of the message created is: 00931 00932 ERROR in [L1B_location](): 00933 [input_message] 00934 Call to [assoc_function]() failed. 00935 File LUN: [lun] ([type of file for this LUN]) 00936 [other_msg] 00937 00938 If an input is NULL (for char *) or zero (for int32), then that part of 00939 the message is not included. 00940 00941 !Input Parameters: 00942 char *L1B_location name of L1B function that error occurred in 00943 PGSt_SMF_code code associated error code for this error 00944 char *input_message short (usually 1-line) description of error 00945 char *assoc_function name of an associated function that failed 00946 int32 LUN associated LUN for the file being accessed 00947 char *other_msg other message to add such as probable cause 00948 boolean error_out flag to tell whether or not to call SMF_ERROR 00949 00950 !Output Parameters: 00951 (none) 00952 00953 !Revision History: 00954 (continue at top of the file) 00955 00956 Revision 1.0.4 October 16, 2004 Razor Issue #200 00957 Casted Int32 variables in sprintf calls to "long" with the 00958 format specifier "%ld" for better code portability. 00959 Liqin Tan, SAIC GSO (ltan@saicmodis.com) 00960 00961 Revision 1.0.3 September 15, 2003 00962 Add messages regarding "ProcessingEnvironment". 00963 Liqin Tan, SAIC GSO (ltan@saicmodis.com) 00964 00965 Revision 1.0.2 August 26, 2002 00966 For MODIS/AQUA Processing only 00967 Added messages for MCST_LUT_VERSION_LUN and WRITE_NIGHT_HIRES_LUN 00968 Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov) 00969 00970 Revision 1.0 Nov. 4, 1999 00971 Initial development. 00972 Jim Rogers (rogers@mcst.gsfc.nasa.gov) 00973 00974 !Team-unique Header: 00975 This software is developed by the MODIS Characterization Support 00976 Team (MCST)for the National Aeronautics and Space Administration, 00977 Goddard Space Flight Center, under contract NAS5-32373. 00978 00979 !References and Credits: 00980 HDF portions developed at the National Center for Supercomputing 00981 Applications at the University of Illinois at Urbana-Champaign. 00982 00983 !Design Notes: 00984 The messages going to the LogStatus and LogReport are formatted to 00985 look similar to each other. 00986 00987 The message size should be smaller than PGS_SMF_MAX_MSGBUF_SIZE 00988 due to internal limits in PGS_SMF_SetDynamicMsg. This routine will 00989 fill up the message buffer until there is no more room and then 00990 call PGS_SMF_SetDynamicMsg. Thus, a message may appear truncated. 00991 00992 The same size message buffer is assumed for the LogReport message. 00993 This could result in the LogReport message being truncated from the 00994 message written to the log status file (since the L1B_location is added 00995 at the beginning of the LogReport file). 00996 00997 This restriction may not be necessary. The source code for 00998 PGS_SMF_GenerateStatusReport does not appear to have any string 00999 length restrictions. 01000 01001 The lun (if one of the list of L1B LUNs) is used to determine the 01002 the category of the file (e.g., QA_Lookup_Tables_file). 01003 01004 All "Concatenate" operations will use the "safe_strcat" function that 01005 ensures that the string can be concatenated onto the end and that flags 01006 when a message is truncated. 01007 01008 !END******************************************************************** 01009 */ 01010 { 01011 PGSt_SMF_status returnStatus; /* Return value for some PGS functs */ 01012 char msg[PGS_SMF_MAX_MSGBUF_SIZE]; /* Buffer for LogStatus message */ 01013 char report[PGS_SMF_MAX_MSGBUF_SIZE]; /* Buffer for LogReport message */ 01014 char lunstr[PGS_SMF_MAX_MSGBUF_SIZE]; /* Buffer for LUN string */ 01015 char category[PGS_SMF_MAX_MSGBUF_SIZE]; /* Buffer for file category */ 01016 PGSt_SMF_boolean internal_failure; /* Flags internal function failure. */ 01017 01018 /* 01019 * First, format the message to be written to the LogStatus file. 01020 * The L1B function name is not needed for that message (it is an argument 01021 * to the PGS_SMF_SetDynamicMsg function). 01022 */ 01023 01024 /* initialize the message buffer */ 01025 01026 strcpy(msg, ""); 01027 01028 /* Add the specific input message */ 01029 01030 if (input_message) { 01031 safe_strcat(msg, input_message, PGS_SMF_MAX_MSGBUF_SIZE); 01032 if (msg[strlen(msg)-1] != '\n') 01033 safe_strcat(msg, "\n", PGS_SMF_MAX_MSGBUF_SIZE); 01034 } 01035 01036 /* Add the associated function name */ 01037 01038 if (assoc_function) { 01039 safe_strcat(msg, "Call to ", PGS_SMF_MAX_MSGBUF_SIZE); 01040 safe_strcat(msg, assoc_function, PGS_SMF_MAX_MSGBUF_SIZE); 01041 safe_strcat(msg, "() failed.\n", PGS_SMF_MAX_MSGBUF_SIZE); 01042 } 01043 01044 /* Add the LUN information */ 01045 01046 if (lun != 0) { 01047 sprintf(lunstr, "File LUN: %ld\nFile type: ", (long)lun); 01048 safe_strcat(msg, lunstr, PGS_SMF_MAX_MSGBUF_SIZE); 01049 switch (lun) { 01050 case MCF_FILE_QKM: 01051 strcpy(category, "MOD02QKM MCF\n"); break; 01052 case MCF_FILE_HKM: 01053 strcpy(category, "MOD02HKM MCF\n"); break; 01054 case MCF_FILE_1KM: 01055 strcpy(category, "MOD021KM MCF\n"); break; 01056 case MCF_FILE_OBC: 01057 strcpy(category, "MOD02OBC MCF\n"); break; 01058 case L1B_EV_250M_FILE: 01059 strcpy(category, "MOD02QKM output granule\n"); break; 01060 case L1B_EV_500M_FILE: 01061 strcpy(category, "MOD02HKM output granule\n"); break; 01062 case L1B_EV_1000M_FILE: 01063 strcpy(category, "MOD021KM output granule\n"); break; 01064 case L1B_OBC_FILE: 01065 strcpy(category, "MOD02OBC output granule\n"); break; 01066 case REFLECTIVE_TABLES_FILE: 01067 strcpy(category, "Reflective_Lookup_Tables_file\n"); break; 01068 case EMISSIVE_TABLES_FILE: 01069 strcpy(category, "Emissive_Lookup_Tables_file\n"); break; 01070 case QA_TABLES_FILE: 01071 strcpy(category, "QA_Lookup_Tables_file\n"); break; 01072 case LEADING_L1A_GRANULE: 01073 strcpy(category, "previous MOD01 input granule\n"); break; 01074 case FIRST_L1A_GRANULE: 01075 strcpy(category, "current MOD01 input granule\n"); break; 01076 case TRAILING_L1A_GRANULE: 01077 strcpy(category, "following MOD01 input granule\n"); break; 01078 case GEOLOCATION_FILE: 01079 strcpy(category, "MOD03 input granule\n"); break; 01080 case PROCESSING_ENVIRONMENT_LUN: strcpy(category, 01081 "PCF File; ProcessingEnvironment; not required.\n"); break; 01082 case MCST_LUT_VERSION_LUN: strcpy(category, 01083 "PCF File; invalid MCSTLUTVersion value\n"); break; 01084 case WRITE_NIGHT_HIRES_LUN: strcpy(category, 01085 "PCF File; invalid Write_Night_Mode_HiRes_Data value\n"); break; 01086 default: 01087 strcpy(category, "invalid value, L1B defect\n"); break; 01088 } 01089 safe_strcat(msg, category, PGS_SMF_MAX_MSGBUF_SIZE); 01090 01091 } 01092 01093 /* 01094 * Add the other message 01095 */ 01096 01097 if (other_msg) { 01098 safe_strcat(msg, other_msg, PGS_SMF_MAX_MSGBUF_SIZE); 01099 } 01100 01101 /* 01102 * Write the message to the LogStatus file. 01103 */ 01104 01105 internal_failure = PGS_FALSE; 01106 returnStatus = PGS_SMF_SetDynamicMsg(code, msg, L1B_location); 01107 if (returnStatus != PGS_S_SUCCESS) 01108 internal_failure = PGS_TRUE; 01109 01110 /* 01111 * Now format the same message to be written to the LogReport file. 01112 * Make the appearance of the message similar in the LogReport file. 01113 */ 01114 01115 strcpy(report, ""); 01116 01117 /* Add the L1B location */ 01118 01119 if (L1B_location) 01120 { 01121 safe_strcat(report, L1B_location, PGS_SMF_MAX_MSGBUF_SIZE); 01122 safe_strcat(report, "():", PGS_SMF_MAX_MSGBUF_SIZE); 01123 } 01124 else 01125 { 01126 safe_strcat(report, ":", PGS_SMF_MAX_MSGBUF_SIZE); 01127 } 01128 01129 /* Add the textual and numerical equivalents of the exit code. */ 01130 01131 switch (code) { 01132 case MODIS_F_OUT_OF_MEMORY: 01133 safe_strcat(report, "MODIS_F_OUT_OF_MEMORY:", 01134 PGS_SMF_MAX_MSGBUF_SIZE); break; 01135 case MODIS_F_MEM_FREE_FAIL: 01136 safe_strcat(report, "MODIS_F_MEM_FREE_FAIL:", 01137 PGS_SMF_MAX_MSGBUF_SIZE); break; 01138 case MODIS_F_FILE_NOT_FOUND: 01139 safe_strcat(report, "MODIS_F_FILE_NOT_FOUND:", 01140 PGS_SMF_MAX_MSGBUF_SIZE); break; 01141 case MODIS_F_READ_ERROR: 01142 safe_strcat(report, "MODIS_F_READ_ERROR:", 01143 PGS_SMF_MAX_MSGBUF_SIZE); break; 01144 case MODIS_F_WRITE_ERROR: 01145 safe_strcat(report, "MODIS_F_WRITE_ERROR:", 01146 PGS_SMF_MAX_MSGBUF_SIZE); break; 01147 case MODIS_F_OUT_OF_RANGE: 01148 safe_strcat(report, "MODIS_F_OUT_OF_RANGE:", 01149 PGS_SMF_MAX_MSGBUF_SIZE); break; 01150 case MODIS_W_OUT_OF_RANGE: 01151 safe_strcat(report, "MODIS_W_OUT_OF_RANGE:", 01152 PGS_SMF_MAX_MSGBUF_SIZE); break; 01153 case MODIS_W_TIME_INCORRECT: 01154 safe_strcat(report, "MODIS_W_TIME_INCORRECT:", 01155 PGS_SMF_MAX_MSGBUF_SIZE); break; 01156 case MODIS_F_NOK: 01157 safe_strcat(report, "MODIS_F_NOK:", 01158 PGS_SMF_MAX_MSGBUF_SIZE); break; 01159 case MODIS_F_HDF_ERROR: 01160 safe_strcat(report, "MODIS_F_HDF_ERROR:", 01161 PGS_SMF_MAX_MSGBUF_SIZE); break; 01162 case MODIS_F_NO_MORE: 01163 safe_strcat(report, "MODIS_F_NO_MORE:", 01164 PGS_SMF_MAX_MSGBUF_SIZE); break; 01165 case MODIS_S_NO_MORE: 01166 safe_strcat(report, "MODIS_S_NO_MORE:", 01167 PGS_SMF_MAX_MSGBUF_SIZE); break; 01168 case MODIS_F_FILE_NOT_OPENED: 01169 safe_strcat(report, "MODIS_F_FILE_NOT_OPENED:", 01170 PGS_SMF_MAX_MSGBUF_SIZE); break; 01171 case MODIS_F_FILE_NOT_CREATED: 01172 safe_strcat(report, "MODIS_F_FILE_NOT_CREATED:", 01173 PGS_SMF_MAX_MSGBUF_SIZE); break; 01174 case MODIS_F_INVALID_ARGUMENT: 01175 safe_strcat(report, "MODIS_F_INVALID_ARGUMENT:", 01176 PGS_SMF_MAX_MSGBUF_SIZE); break; 01177 case MODIS_E_TESTING: 01178 safe_strcat(report, "MODIS_E_TESTING:", 01179 PGS_SMF_MAX_MSGBUF_SIZE); break; 01180 case MODIS_S_OK: 01181 safe_strcat(report, "MODIS_S_OK:", 01182 PGS_SMF_MAX_MSGBUF_SIZE); break; 01183 default: 01184 safe_strcat(report, "UNKNOWN_CODE:", 01185 PGS_SMF_MAX_MSGBUF_SIZE); break; 01186 } 01187 sprintf(lunstr, "%d\n", code); 01188 safe_strcat(report, lunstr, PGS_SMF_MAX_MSGBUF_SIZE); 01189 01190 /* 01191 * Add the previously formatted message written to LogStatus file. 01192 * Write the total message to the LogReport file. 01193 */ 01194 01195 safe_strcat(report, msg, PGS_SMF_MAX_MSGBUF_SIZE); 01196 returnStatus = PGS_SMF_GenerateStatusReport(report); 01197 if (returnStatus != PGS_S_SUCCESS) 01198 internal_failure = PGS_TRUE; 01199 01200 /* 01201 * If there is an internal failure, write fatal error message and 01202 * error out. (The way that SMF_ERROR is designed, the error message 01203 * will probably not get written anyway.) 01204 */ 01205 01206 if (internal_failure == PGS_TRUE) 01207 { 01208 SMF_ERROR(MODIS_F_NOK, 01209 "Fatal error in HDFFuncErrorMsg: Failed to write to\n" 01210 "PGS_SMF_SetDynamicMsg or to PGS_SMF_GenerateStatusReport"); 01211 } 01212 01213 /* 01214 * Call SMF_ERROR to error out if the flag is set to True. 01215 */ 01216 01217 if (error_out == True) 01218 SMF_ERROR(code, NULL); 01219 } 01220 01221 01222 /* 01223 * The following variable contains error message information used in 01224 * SMF_ERROR. The first entry in the variable is the 01225 * default (in case of input error) and the last entry in the table 01226 * must be NULL. 01227 */ 01228 01229 static struct 01230 { 01231 char *name; /* macro name of the error code */ 01232 int32 value; /* numerical value of the code */ 01233 char *actions; /* operator actions to take */ 01234 } err_msg_info[] = 01235 { 01236 01237 { "MODIS_F_NOK", MODIS_F_NOK, "\ 01238 Operator Actions:\n\ 01239 Contact MCST.\n" 01240 }, 01241 01242 { "MODIS_F_OUT_OF_MEMORY", MODIS_F_OUT_OF_MEMORY, "\ 01243 Operator Actions:\n\ 01244 Check the system health to see if it is overloaded.\n\ 01245 Try re-running the PGE with system loading reduced.\n\ 01246 Contact MCST.\n" 01247 }, 01248 01249 { "MODIS_F_MEM_FREE_FAIL", MODIS_F_MEM_FREE_FAIL, "\ 01250 Operator Actions:\n\ 01251 Contact MCST.\n" 01252 }, 01253 01254 { "MODIS_F_FILE_NOT_FOUND", MODIS_F_FILE_NOT_FOUND, "\ 01255 Operator Actions:\n\ 01256 Check previous messages to identify LUN of the file and other possible causes.\n\ 01257 Check the PCF file to ensure that UR exists and PCF format is correct.\n\ 01258 Check the PCF file to ensure that file names and directories are correct.\n\ 01259 Contact MCST.\n" 01260 }, 01261 01262 { "MODIS_F_READ_ERROR", MODIS_F_READ_ERROR, "\ 01263 Operator Actions:\n\ 01264 Check previous messages to identify LUN of the file and other possible causes.\n\ 01265 Check the PCF file to ensure that file names and directories are correct.\n\ 01266 Check the file type and size to see if it is consistent with file category.\n\ 01267 Contact MCST.\n" 01268 }, 01269 01270 { "MODIS_F_WRITE_ERROR", MODIS_F_WRITE_ERROR, "\ 01271 Operator Actions:\n\ 01272 Check previous messages to identify LUN of the file and other possible causes.\n\ 01273 Check the PCF file to ensure that file names and directories are correct.\n\ 01274 Check available system disk space.\n\ 01275 Check to see if file has been moved or corrupted during execution.\n\ 01276 Contact MCST.\n" 01277 }, 01278 01279 { "MODIS_F_OUT_OF_RANGE", MODIS_F_OUT_OF_RANGE, "\ 01280 Operator Actions:\n\ 01281 Check previous messages to identify LUN of the file and other possible causes.\n\ 01282 Contact MCST.\n\ 01283 Also contact SDST if the LUN corresponds to a MOD01 or MOD03 granule.\n" 01284 }, 01285 01286 { "MODIS_W_OUT_OF_RANGE", MODIS_W_OUT_OF_RANGE, "\ 01287 Operator Actions:\n\ 01288 Contact MCST.\n" 01289 }, 01290 01291 { "MODIS_W_TIME_INCORRECT", MODIS_W_TIME_INCORRECT, "\ 01292 Operator Actions:\n\ 01293 Check Leap Seconds and other toolkit files and environment variables.\n\ 01294 Notify L1B product users that time in product may be incorrect.\n\ 01295 Contact MCST.\n" 01296 }, 01297 01298 { "MODIS_F_HDF_ERROR", MODIS_F_HDF_ERROR, "\ 01299 Operator Actions:\n\ 01300 Check previous messages to identify LUN of the file and other possible causes.\n\ 01301 Contact MCST.\n" 01302 }, 01303 01304 { "MODIS_F_NO_MORE", MODIS_F_NO_MORE, "\ 01305 Operator Actions:\n\ 01306 Contact MCST.\n" 01307 }, 01308 01309 { "MODIS_S_NO_MORE", MODIS_S_NO_MORE, NULL }, 01310 01311 { "MODIS_F_FILE_NOT_OPENED", MODIS_F_FILE_NOT_OPENED, "\ 01312 Operator Actions:\n\ 01313 Check previous messages to identify LUN of the file and other possible causes.\n\ 01314 Check the PCF file to ensure that file names and directories are correct.\n\ 01315 Contact MCST.\n" 01316 }, 01317 01318 { "MODIS_F_FILE_NOT_CREATED", MODIS_F_FILE_NOT_CREATED, "\ 01319 Operator Actions:\n\ 01320 Check previous messages to identify LUN of the file and other possible causes.\n\ 01321 Check the PCF file to ensure that file names and directories are correct.\n\ 01322 Check file permissions of the system.\n\ 01323 Contact MCST.\n" 01324 }, 01325 01326 { "MODIS_F_INVALID_ARGUMENT", MODIS_F_INVALID_ARGUMENT, "\ 01327 Operator Actions:\n\ 01328 Contact MCST.\n" 01329 }, 01330 01331 { "MODIS_E_TESTING", MODIS_E_TESTING, "\ 01332 Operator Actions:\n\ 01333 Contact MCST.\n" 01334 }, 01335 01336 { "MODIS_S_OK", MODIS_S_OK, NULL }, 01337 01338 { NULL, 0, NULL } /*** Must be NULL terminated ***/ 01339 }; 01340 01341 01342 void SMF_ERROR (PGSt_SMF_code code, char *messagestring) 01343 /* 01344 !C************************************************************************** 01345 !Description: 01346 Provides the interface to the Status Message Facility in the SDP Toolkit. 01347 A message is formed using the format string from the L1B "seed" file, 01348 the input message string and the local time. The message is written to 01349 both the LogStatus file and the LogReport file. Additionally, operator 01350 actions are written as the last messages to the files. 01351 01352 IMPORTANT: This function will invoke "exit" for fatal error codes or 01353 internal failures that should not occur (such as the environment or 01354 seed messages do not function). See other comments in design notes. 01355 01356 !Input Parameters: 01357 PGSt_SMF_code code One of the L1B message codes defined in 01358 PGS_Error_Codes.h" and in the seed file. 01359 char * messagestring A string which contains a specific error 01360 message. The function name should be already 01361 part of the string, if appropriate. 01362 01363 !Output Parameters: 01364 (none) 01365 01366 !Revision History: 01367 (continue at top of the file) 01368 01369 Revision 2.0.1 January 17, 2002 Razor Issue #172 01370 Improve portability of code to 64-bit mode. 01371 Change variable n to type size_t. Use n instead of i in strlen operations. 01372 Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov) 01373 01374 Revision 02.00 Oct. 27, 1999 01375 Added checks on input validity (NULL, string length). Reformatted 01376 message so that it does not appear all on one line. Added "MOD_PR02" 01377 to the beginning to distinguish the source from other processes that 01378 may write to the same Log files. Added additional error messages and 01379 warnings. Function was completely restructured. Added design notes. 01380 Jim Rogers (rogers@mcst.gsfc.nasa.gov) 01381 01382 Revision 01.00 199604/05 01383 Initial development, new function for Version 1. 01384 John Hannon(hannon@highwire.gsfc.nasa.gov) 01385 01386 !Team-unique Header: 01387 This software is developed by the MODIS Characterization Support 01388 Team (MCST)for the National Aeronautics and Space Administration, 01389 Goddard Space Flight Center, under contract NAS5-32373. 01390 01391 !References and Credits: 01392 This routine is based on the CHECK_ERR function used by Geir Kvaran 01393 in the Beta version of the code. 01394 HDF portions developed at the National Center for Supercomputing 01395 Applications at the University of Illinois at Urbana-Champaign. 01396 01397 !Design Notes: 01398 01399 The final form of the message consists of three parts, concatenated together: 01400 1. leading part: string from the seed file associated with this code 01401 2. middle part: the input "messagestring" 01402 3. last part: the local time that the error occurred 01403 Note that the string from the seed file actually is the format string for the 01404 sprintf function (it has two "%s" fields for the middle and trailing parts). 01405 01406 If the total message is too large to fit into the maximum size allowed by the 01407 Toolkit (PGS_SMF_MAX_MSGBUF_SIZE - 1), then the user supplied message is 01408 truncated so that it will fit. In this case, the process will exit only if the 01409 original message code was fatal. 01410 01411 Side effect: The input messagestring may be modified by this function if the 01412 string length is too long. Thus, the calling function should not plan on using 01413 the string afterward. 01414 01415 For a NULL or zero-length messagestring, assume that the seed file message is 01416 the complete message. 01417 01418 Note: The following conditions could cause an exit invocation: 01419 1. The input "code" corresponds to a fatal error, or 01420 2. There is an internal failure inside this function. 01421 An internal failure is a failure of one of the PGS toolkit functions. Other 01422 errors that occur may generate warnings, but will not halt the process 01423 in and of themselves. 01424 01425 Depending on the internal failure, there may be no error messages written. 01426 If absolutely no message of any kind comes out, perhaps the LogStatus and 01427 LogReport files are not set properly in the PCF. 01428 01429 !END*************************************************************************** 01430 */ 01431 { 01432 PGSt_SMF_status returnStatus; /* Return value for some PGS functs */ 01433 char msgfmt[PGS_SMF_MAX_MSGBUF_SIZE]; /* Holds the format retrieved from 01434 * the seed file (format associated with 01435 * the particular input error code). 01436 */ 01437 #define ASCTIMEBUF 26 01438 char timestr[ASCTIMEBUF]; /* Holds the local time in a string. 01439 * The time function "asctime_r" sets a 01440 * null-terminated string of length 25. 01441 */ 01442 char msgstr[PGS_SMF_MAX_MSGBUF_SIZE]; /* Holds the modified input message (could 01443 * be truncated or have newlines added) 01444 */ 01445 char buf[PGS_SMF_MAX_MSGBUF_SIZE]; /* Holds the final concatenated message. */ 01446 struct tm *tptr; /* used in getting time string */ 01447 time_t local; /* used in getting time string */ 01448 PGSt_SMF_boolean internal_failure; /* Flags any internal function failure. */ 01449 size_t n; /* temporary variable */ 01450 01451 char *defaultmsgfmt = "Error running...%sTIME:%s"; /* backup value */ 01452 PGSt_SMF_code internal_failure_code = MODIS_F_NOK; /* value to use for internal 01453 * failure. 01454 */ 01455 char *s; /* temporary variable */ 01456 int32 i; /* loop index */ 01457 int32 imsg; /* index in "err_mgs_info" for this code */ 01458 01459 /*************************** MACRO WRITE_MSG(c,m) ********************************* 01460 Writes a string to both the LogStatus and LogReport. For writing to the 01461 LogStatus, the function name is not input (set to NULL). Note that if either 01462 call fails, then we probably will not get any messages at all. There is one 01463 final check on the string length, although this should be OK. 01464 c = SMF message code 01465 m = message string to be written 01466 **********************************************************************************/ 01467 #define WRITE_MSG(c,m) \ 01468 if (strlen(m) > (PGS_SMF_MAX_MSGBUF_SIZE - 1)) { \ 01469 m[strlen(m)-1] = '\0'; \ 01470 } \ 01471 returnStatus = PGS_SMF_SetDynamicMsg(c, m, NULL); \ 01472 if (returnStatus != PGS_S_SUCCESS) \ 01473 internal_failure = PGS_TRUE; \ 01474 returnStatus = PGS_SMF_GenerateStatusReport(m); \ 01475 if (returnStatus != PGS_S_SUCCESS) \ 01476 internal_failure = PGS_TRUE; 01477 01478 /******************* Begin code ***************/ 01479 01480 /* 01481 * Initialize flag to false. 01482 */ 01483 01484 internal_failure = PGS_FALSE; 01485 01486 /* 01487 * Get the seed file message format string for this error code. 01488 */ 01489 01490 returnStatus = PGS_SMF_GetMsgByCode(code, msgfmt); 01491 if (returnStatus != PGS_S_SUCCESS) 01492 { 01493 char errmsg[] = "MOD_PR02 Warning in SMF_ERROR: Call to PGS_SMF_GetMsgByCode failed.\n" 01494 "Seed file may not be set up properly or code is invalid.\n" 01495 "The input message will be printed below and process will exit.\n"; 01496 WRITE_MSG(internal_failure_code,errmsg); 01497 internal_failure = PGS_TRUE; 01498 strcpy(msgfmt, defaultmsgfmt); 01499 } 01500 01501 /* 01502 * Form the local time and copy the time string into the timestr. 01503 * If the time functions fail, copy a small error message into the timestr. 01504 */ 01505 01506 local = time(NULL); 01507 tptr = localtime(&local); 01508 s = asctime(tptr); 01509 if (s) 01510 { 01511 strcpy(timestr, s); 01512 } 01513 else 01514 { 01515 strcpy(timestr,"WARNING: asctime failed"); /* this string must be < 26 chars! */ 01516 } 01517 if (strlen(timestr) > (ASCTIMEBUF-1)) 01518 { 01519 strcpy(timestr,"WARNING: asctime failed"); /* this string must be < 26 chars! */ 01520 } 01521 01522 /* 01523 * Put the input message into the msgstr. Truncate if necessary. 01524 */ 01525 01526 if (!messagestring) 01527 { 01528 strcpy(msgstr, "MOD_PR02. "); 01529 } 01530 else if (!strlen(messagestring)) 01531 { 01532 strcpy(msgstr, "MOD_PR02. "); 01533 } 01534 else 01535 { 01536 strcpy(msgstr, "MOD_PR02:"); 01537 if (messagestring[0] != '\n') 01538 strcat(msgstr, "\n"); 01539 n = PGS_SMF_MAX_MSGBUF_SIZE - 1 - strlen(msgfmt) - 01540 strlen(timestr) - strlen(msgstr); 01541 if (strlen(messagestring) > n) 01542 messagestring[n] = '\0'; 01543 strcat(msgstr, messagestring); 01544 n = strlen(msgstr); 01545 if (msgstr[n-1] != '\n') 01546 strcat(msgstr, "\n"); 01547 } 01548 01549 /* 01550 * Form the final message string. 01551 */ 01552 01553 sprintf(buf, msgfmt, msgstr, timestr); 01554 01555 /* 01556 * Determine index of operator actions, based on exit code. 01557 */ 01558 01559 i = 0; imsg = 0; 01560 while (err_msg_info[i].name) 01561 { 01562 if (code == err_msg_info[i].value) 01563 { 01564 imsg = i; 01565 break; 01566 } 01567 i++; 01568 } 01569 01570 /* 01571 * Determine string length of operator actions. 01572 */ 01573 01574 if (err_msg_info[imsg].actions) 01575 n = strlen(err_msg_info[imsg].actions); 01576 else 01577 n = 0; 01578 01579 /* 01580 * If there is room, append the operator actions to the end of the message 01581 * buffer to be written. Otherwise, write the message buffer and the write 01582 * the operator actions separately. 01583 */ 01584 01585 if (n == 0) 01586 { 01587 WRITE_MSG(code,buf); 01588 } 01589 else if ((strlen(buf)+n) < PGS_SMF_MAX_MSGBUF_SIZE) 01590 { 01591 strcat(buf, err_msg_info[imsg].actions); 01592 WRITE_MSG(code,buf); 01593 } 01594 else 01595 { 01596 WRITE_MSG(code,buf); 01597 WRITE_MSG(code,err_msg_info[imsg].actions); 01598 } 01599 01600 /* 01601 * Test to see if the code corresponds to a fatal error or if there was any 01602 * internal failure and then exit. 01603 */ 01604 01605 if ((PGS_SMF_TestFatalLevel(code)) == PGS_TRUE || internal_failure == PGS_TRUE) 01606 { 01607 01608 exit (MOD_PR02_Failure_Exit_Code); 01609 01610 } 01611 } 01612 01613 void Bad_L1A_Error_Out(char *name, char *message) 01614 /* 01615 !C******************************************************************* 01616 !Description: This function posts a error message to log file including 01617 the name of the data and the description of the problem 01618 when bad L1A data are read. 01619 01620 !Input Parameters: 01621 char * name the name of the data being read 01622 char * message error message 01623 01624 !Output Parameters: 01625 01626 !Revision History: 01627 (continue at top of the file) 01628 01629 Revision 01.00 August 27, 1999 01630 Initial development 01631 Zhenying Gu (zgu@mcst.gsfc.nasa.gov) 01632 Jim Rogers (rogers@mcst.gsfc.nasa.gov) 01633 01634 !Team-unique Header: 01635 01636 !References and Credits: 01637 This software is developed by the MODIS Characterization Support 01638 Team (MCST)for the National Aeronautics and Space Administration, 01639 Goddard Space Flight Center, under contract NAS5-32373. 01640 01641 HDF portions developed at the National Center for Supercomputing 01642 Applications at the University of Illinois at Urbana-Champaign. 01643 01644 !Design Notes: 01645 01646 01647 !END******************************************************************** 01648 */ 01649 { 01650 char buffer [MAX_ERROR_MESSAGE_LENGTH]; 01651 char *default_message = "Bad L1A data.\n"; 01652 char *fmt = "\ 01653 ERROR READING DATA FROM ONE OF THE MOD01 FILES INPUT TO PGE02.\n\ 01654 Name of MOD01 data: %s\n\ 01655 Error: %s\n\ 01656 This error is due to:\n\ 01657 (1) the MOD01 file is corrupted,\n\ 01658 (2) the process MOD_PR01 (in PGE01) has a bug in it, or\n\ 01659 (3) there is an address bug in MOD_PR02."; 01660 01661 if (strlen(fmt) + strlen(name) + strlen(message) < MAX_ERROR_MESSAGE_LENGTH) 01662 sprintf(buffer, fmt, name, message); 01663 else 01664 sprintf(buffer, "%s", default_message); 01665 01666 SMF_ERROR(MODIS_F_NOK, buffer); 01667 } 01668 01669 01670 PGSt_SMF_status Write_L1B_EV_Scan (int16 S, 01671 L1B_granule_t *L1B_Gran, 01672 L1B_Scan_t *L1B_Scan, 01673 boolean isdaymode) 01674 /* 01675 !C********************************************************************** 01676 !Description: 01677 This routine writes one scan of L1B EV data, including scaled integers, 01678 uncertainty indices and samples used, as appropriate. For a day-mode 01679 scan, all resolutions are written. For a night mode scan, only data 01680 for the emissive bands are written. 01681 01682 !Input Parameters: 01683 int16 S current scan index 01684 L1B_granule_t *L1B_Gran 01685 L1B_Scan_t *L1B_Scan 01686 boolean isdaymode Flag denoting that scan is a day mode scan 01687 (if True) 01688 !Output Parameters: 01689 01690 !Revision History: 01691 (continue at top of the file) 01692 01693 Revision 03.10 May 13, 1999 01694 Added band 26 section. 01695 Jim Rogers (rogers@mcst.gsfc.nasa.gov) 01696 01697 Revision 03.00 March 1997 01698 Modified to match changes in L1B_Scan_t and in file spec; 01699 limited processing to EV data. 01700 Zhidong Hao (hao@barebackride.gsfc.nasa.gov) 01701 01702 Revision 02.00 1996/06/28 01703 New version using SDS_Services Currently corresponds to version 1 specification 01704 Neal Devine(neal.devine@gsfc.nasa.gov) 01705 01706 Revision 01.01 1996/04/05 01707 Updated to match Version q Design Document 01708 Joan Baden(baden@highwire.gsfc.nasa.gov) 01709 John Hannon(hannon@highwire.gsfc.nasa.gov) 01710 01711 Revision 01.00 1993 01712 Initial development 01713 Geir E. Kvaran(geir@highwire.gsfc.nasa.gov) 01714 01715 !Team-unique Header: 01716 01717 !References and Credits: 01718 This software is developed by the MODIS Characterization Support 01719 Team (MCST)for the National Aeronautics and Space Administration, 01720 Goddard Space Flight Center, under contract NAS5-32373. 01721 01722 HDF portions developed at the National Center for Supercomputing 01723 Applications at the University of Illinois at Urbana-Champaign. 01724 01725 !Design Notes: 01726 New version subsumes version 1 functions Write_L1B_PixelQuality, 01727 Write_L1B_EngMem, and Write_L1B_Slice, which are no longer needed. 01728 01729 !END******************************************************************** 01730 */ 01731 { 01732 PGSt_SMF_status returnStatus; 01733 int16 R = 0; 01734 int32 start[3] = {0, 0, 0}; 01735 int32 edge[3] = {0, 0, 0}; 01736 01737 /*------------------------------------------------------------------------------ 01738 This macro writes a set of three EV_Aggr SDS's (SI & UI & SU) 01739 ------------------------------------------------------------------------------*/ 01740 #define WRITE_EV_Aggr_SDS(SI_id, SI, UI_id, UI, SU_id, SU) \ 01741 if(SDwritedata(SI_id,start,NULL,edge,SI) == FAIL) \ 01742 return(MODIS_F_WRITE_ERROR); \ 01743 if(SDwritedata(UI_id,start,NULL,edge,UI) == FAIL) \ 01744 return(MODIS_F_WRITE_ERROR); \ 01745 if(SDwritedata(SU_id,start,NULL,edge,SU) == FAIL) \ 01746 return(MODIS_F_WRITE_ERROR) 01747 /*----------------------------------------------------------------------------*/ 01748 01749 if (S >= L1B_Gran->num_scans) 01750 return(MODIS_F_NO_MORE); 01751 01752 /************************* Begin Band 26 Section **************************/ 01753 #ifdef WRITE_BAND_26_SDS 01754 /* 01755 * Write this scan's worth of Band 26 data. These are always written, 01756 * regardless of day or night. Note that since these are 2D SDSs, 01757 * we pass in the address of start[1] and edge[1], since the last 01758 * two dimensions of the 3D EV SDSs are the same as the two 01759 * dimensions for these SDSs. 01760 */ 01761 start[1] = S * DETECT_PER_BAND_AT_RES[INDEX_1000M_REFL]; 01762 edge[1] = DETECT_PER_BAND_AT_RES[INDEX_1000M_REFL]; 01763 edge[2] = EV_1km_FRAMES * BAND_RATIO_AT_RES[INDEX_1000M_REFL]; 01764 if (SDwritedata(L1B_Scan->Band26.SI_sds_id, &start[1], NULL, &edge[1], 01765 (VOIDP)L1B_Scan->Band26.SI) == FAIL) 01766 return(MODIS_F_WRITE_ERROR); 01767 if (SDwritedata(L1B_Scan->Band26.UI_sds_id, &start[1], NULL, &edge[1], 01768 (VOIDP)L1B_Scan->Band26.UI) == FAIL) 01769 return(MODIS_F_WRITE_ERROR); 01770 01771 #endif /* WRITE_BAND_26_SDS */ 01772 /************************** End Band 26 Section ***************************/ 01773 01774 for (R = 0; R < NUM_L1A_RESOLUTIONS; R++) 01775 { 01776 start[1] = S * DETECT_PER_BAND_AT_RES[R]; 01777 edge[0] = L1B_BANDS_AT_RES[R]; 01778 edge[1] = DETECT_PER_BAND_AT_RES[R]; 01779 edge[2] = EV_1km_FRAMES * BAND_RATIO_AT_RES[R]; 01780 if (!isdaymode && R != INDEX_1000M_EMISS) 01781 continue; 01782 01783 returnStatus = Write_L1B_SI_UI(S, L1B_Scan, R); 01784 if (returnStatus != MODIS_S_OK) 01785 SMF_ERROR(returnStatus, "Write_L1B_SI_UI() in Write_L1B_EV_Scan(), Granule.c"); 01786 01787 switch(R) 01788 { 01789 case INDEX_250M: 01790 break; 01791 01792 case INDEX_500M: 01793 edge[0] = L1B_BANDS_AT_RES[INDEX_250M]; 01794 WRITE_EV_Aggr_SDS (L1B_Scan->EV_250m_Aggr500m_RefSB_sds_id, 01795 L1B_Scan->EV_250m_Aggr500m_RefSB, 01796 L1B_Scan->EV_250m_Aggr500m_RefSB_UI_sds_id, 01797 L1B_Scan->EV_250m_Aggr500m_RefSB_UI, 01798 L1B_Scan->EV_250m_Aggr500m_RefSB_SU_sds_id, 01799 L1B_Scan->EV_250m_Aggr500m_RefSB_SU); 01800 break; 01801 01802 case INDEX_1000M_REFL: 01803 edge[0] = L1B_BANDS_AT_RES[INDEX_250M]; 01804 WRITE_EV_Aggr_SDS (L1B_Scan->EV_250m_Aggr1km_RefSB_sds_id, 01805 L1B_Scan->EV_250m_Aggr1km_RefSB, 01806 L1B_Scan->EV_250m_Aggr1km_RefSB_UI_sds_id, 01807 L1B_Scan->EV_250m_Aggr1km_RefSB_UI, 01808 L1B_Scan->EV_250m_Aggr1km_RefSB_SU_sds_id, 01809 L1B_Scan->EV_250m_Aggr1km_RefSB_SU); 01810 01811 edge[0] = L1B_BANDS_AT_RES[INDEX_500M]; 01812 WRITE_EV_Aggr_SDS (L1B_Scan->EV_500m_Aggr1km_RefSB_sds_id, 01813 L1B_Scan->EV_500m_Aggr1km_RefSB, 01814 L1B_Scan->EV_500m_Aggr1km_RefSB_UI_sds_id, 01815 L1B_Scan->EV_500m_Aggr1km_RefSB_UI, 01816 L1B_Scan->EV_500m_Aggr1km_RefSB_SU_sds_id, 01817 L1B_Scan->EV_500m_Aggr1km_RefSB_SU); 01818 break; 01819 01820 case INDEX_1000M_EMISS: 01821 ; 01822 }/*End of switch*/ 01823 }/*End of loop over R: L1A_resolution*/ 01824 01825 return(MODIS_S_OK); 01826 } 01827 01828 01829 PGSt_SMF_status Write_L1B_SI_UI (int16 S, L1B_Scan_t *L1B_Scan, int16 R) 01830 /* 01831 !C********************************************************************** 01832 !Description: 01833 For a given resolution, this routine writes one scan of L1B EV scaled 01834 integer and uncertainty index data to the appropriate L1B granule. 01835 01836 !Input Parameters: 01837 int16 S current scan index 01838 L1B_Scan_t *L1B_Scan 01839 int16 R 01840 !Output Parameters: 01841 01842 !Revision History: 01843 (continue at top of the file) 01844 01845 Revision 01.00 1998 01846 Initial development 01847 Zhenying Gu(zgu@ltpmail.gsfc.nasa.gov) 01848 01849 !Team-unique Header: 01850 01851 !References and Credits: 01852 This software is developed by the MODIS Characterization Support 01853 Team (MCST)for the National Aeronautics and Space Administration, 01854 Goddard Space Flight Center, under contract NAS5-32373. 01855 01856 HDF portions developed at the National Center for Supercomputing 01857 Applications at the University of Illinois at Urbana-Champaign. 01858 01859 !Design Notes: 01860 01861 !END******************************************************************** 01862 */ 01863 { 01864 int32 start[3] = {0, 0, 0}; 01865 int32 edge[3] = {0, 0, 0}; 01866 start[1] = S * DETECT_PER_BAND_AT_RES[R]; 01867 edge[0] = L1B_BANDS_AT_RES[R]; 01868 edge[1] = DETECT_PER_BAND_AT_RES[R]; 01869 edge[2] = EV_1km_FRAMES * BAND_RATIO_AT_RES[R]; 01870 01871 if ((RFLAG & (1 << R)) != 0) return(MODIS_S_OK); 01872 01873 switch (R){ 01874 case 0: 01875 if (SDwritedata(L1B_Scan->SI_sds_id[R], start, NULL, edge, 01876 (VOIDP)L1B_Scan->SI.EV_250m_RefSB) == FAIL) 01877 return(MODIS_F_WRITE_ERROR); 01878 if (SDwritedata(L1B_Scan->UI_sds_id[R], start, NULL, edge, 01879 (VOIDP)L1B_Scan->UI.EV_250m_RefSB_UI) == FAIL) 01880 return(MODIS_F_WRITE_ERROR); 01881 break; 01882 01883 case 1: 01884 if (SDwritedata(L1B_Scan->SI_sds_id[R], start, NULL, edge, 01885 (VOIDP)L1B_Scan->SI.EV_500m_RefSB) == FAIL) 01886 return(MODIS_F_WRITE_ERROR); 01887 if (SDwritedata(L1B_Scan->UI_sds_id[R], start, NULL, edge, 01888 (VOIDP)L1B_Scan->UI.EV_500m_RefSB_UI) == FAIL) 01889 return(MODIS_F_WRITE_ERROR); 01890 break; 01891 01892 case 2: 01893 if (SDwritedata(L1B_Scan->SI_sds_id[R], start, NULL, edge, 01894 (VOIDP)L1B_Scan->SI.EV_1km_RefSB) == FAIL) 01895 return(MODIS_F_WRITE_ERROR); 01896 if (SDwritedata(L1B_Scan->UI_sds_id[R], start, NULL, edge, 01897 (VOIDP)L1B_Scan->UI.EV_1km_RefSB_UI) == FAIL) 01898 return(MODIS_F_WRITE_ERROR); 01899 break; 01900 01901 case 3: 01902 if (SDwritedata(L1B_Scan->SI_sds_id[R], start, NULL, edge, 01903 (VOIDP)L1B_Scan->SI.EV_1km_Emissive) == FAIL) 01904 return(MODIS_F_WRITE_ERROR); 01905 if (SDwritedata(L1B_Scan->UI_sds_id[R], start, NULL, edge, 01906 (VOIDP)L1B_Scan->UI.EV_1km_Emissive_UI) == FAIL) 01907 return(MODIS_F_WRITE_ERROR); 01908 break; 01909 01910 default: break; 01911 } 01912 01913 return(MODIS_S_OK); 01914 } 01915 01916 PGSt_SMF_status Fill_Dead_Detector_SI (boolean isdaymode, 01917 int8 *dead_detector, 01918 L1B_Scan_t *L1B_Scan, 01919 L1B_granule_t *L1B_Gran, 01920 QA_Common_t *QA_Common) 01921 /* 01922 !C************************************************************************ 01923 !Description: 01924 This function fills in reasonable pixel values in one Level 1B EV 01925 product file SDSs, for pixels that correspond to dead detectors. 01926 Values from adjacent (live) detectors are used to determine the values 01927 to assign to the dead-detector pixels. If possible, a linear average 01928 from adjacent pixels is calculated. This operation is applied only to 01929 the native resolution L1B data sets, not aggregated data sets. 01930 01931 !Input Parameters: 01932 boolean isdaymode A flag that denotes that the scan is a 01933 day-mode scan. Some RSB SDSs are computed only 01934 if the scan is a day-mode scan. 01935 int8 *dead_detector Array spanning 490 MODIS detectors which 01936 identifies a non-functional detector (if = 1). 01937 L1B_Scan_t *L1B_Scan Scan data to be written to the EV products. 01938 Includes the scaled integers that may be 01939 modified. 01940 01941 !Output Parameters: 01942 L1B_Scan_t *L1B_Scan SI pixel values corresponding to dead detectors 01943 may be changed. Other values should be unchanged. 01944 L1B_granule_t *L1B_Gran Contains interpolated pixel values for each band. 01945 QA_Common_t *QA_Common Contains number of dead detector EV data for each 01946 detector. 01947 01948 !Revision History: 01949 (continue at top of the file) 01950 01951 Revision 01.01 March 2003, Razor Issue #173 01952 Initialized SI, SI_prev,and SI_subs to 0 for ANSI-C compliance. 01953 Liqin Tan, SAIC GSO (ltan@saicmodis.com) 01954 01955 Revision 01.00 June 15, 2000 01956 Initial development 01957 Jim Rogers (rogers@mcst.gfsc.nasa.gov) 01958 01959 !Team-unique Header: 01960 This software is developed by the MODIS Science Data Support 01961 Team for the National Aeronautics and Space Administration, 01962 Goddard Space Flight Center, under contract NAS5-32373. 01963 01964 !References and Credits: 01965 HDF portions developed at the National Center for Supercomputing 01966 Applications at the University of Illinois at Urbana-Champaign. 01967 01968 !Design Notes: 01969 01970 The change is accomplished on a scan-by-scan basis on the native-resolution 01971 SDSs only. No artificial values are used in forming aggregated SI values. 01972 There is no "cross-over" of information between scans. The logic is as 01973 follows. If a detector is flagged as "dead" by the detector quality flag 01974 LUT, then the SI values of nearest "live" detectors in the same frame and 01975 subsample are used to form a linear average value for the dead detector SI 01976 value. This linear average is accomplished independently for each frame and 01977 subsample of the scan line of the dead detector. There are conditions 01978 checked for: 01979 01980 1) if the dead detector is either the first or last detector in the set, 01981 then the second or next-to-last value is simply copied (no linear average). 01982 01983 2) if an adjacent value to be used in either averaging or copying is an 01984 "unusable" value (>32767), then it is not used to form the artificial value. 01985 For example, if we started off with two values to form a linear average but 01986 one of the values is unusable, then the remaining valid value is simply 01987 copied. 01988 01989 3) If there are no usable values available to form the artificial value, 01990 then the pixel value remains at 65533 (the "dead detector" SI value). 01991 01992 In the product, users may read the "Dead Detector List" attribute to 01993 determine which detectors were classified as dead and thus which scan lines 01994 may have the artificial values filled in. 01995 01996 !END********************************************************************** 01997 */ 01998 { 01999 /* Define order and number of SDSs that may need to be modified. 02000 * These are in different multi-dimensional arrays. 02001 */ 02002 02003 typedef enum { 02004 #ifdef WRITE_BAND_26_SDS 02005 FDD_RSB_BAND26, 02006 #endif /* WRITE_BAND_26_SDS */ 02007 FDD_RSB_250M, 02008 FDD_RSB_500M, 02009 FDD_RSB_1KM_DAY, 02010 FDD_TEB_1KM, 02011 NUM_FDD_DATA_SETS 02012 } data_set_enum_t; 02013 #define MAX_BANDS_PER_FDD_SET 16 02014 02015 /* Declare arrays which describe features (such as dimensions) 02016 * of the SDSs. 02017 */ 02018 02019 int32 num_bands_per_set[NUM_FDD_DATA_SETS] = 02020 { 02021 #ifdef WRITE_BAND_26_SDS 02022 1, 02023 #endif /* WRITE_BAND_26_SDS */ 02024 NUM_250M_BANDS, 02025 NUM_500M_BANDS, 02026 NUM_1000M_REFL_BANDS, 02027 NUM_1000M_EMISS_BANDS 02028 }; 02029 02030 int32 num_dets_per_set[NUM_FDD_DATA_SETS] = 02031 { 02032 #ifdef WRITE_BAND_26_SDS 02033 DETECTORS_PER_1KM_BAND, 02034 #endif /* WRITE_BAND_26_SDS */ 02035 DETECTORS_PER_250M_BAND, 02036 DETECTORS_PER_500M_BAND, 02037 DETECTORS_PER_1KM_BAND, 02038 DETECTORS_PER_1KM_BAND 02039 }; 02040 02041 int32 num_frames_per_set[NUM_FDD_DATA_SETS] = 02042 { 02043 #ifdef WRITE_BAND_26_SDS 02044 EV_1km_FRAMES, 02045 #endif /* WRITE_BAND_26_SDS */ 02046 EV_250m_FRAMES, 02047 EV_500m_FRAMES, 02048 EV_1km_FRAMES, 02049 EV_1km_FRAMES 02050 }; 02051 02052 /* The following denotes whether the data set is "Day" only */ 02053 02054 boolean isdayonly[NUM_FDD_DATA_SETS] = 02055 { 02056 #ifdef WRITE_BAND_26_SDS 02057 False, 02058 #endif /* WRITE_BAND_26_SDS */ 02059 True, 02060 True, 02061 True, 02062 False 02063 }; 02064 02065 boolean qa_flag; /* to check if the qa parameter values for band 26 is 02066 * already adjusted. 02067 */ 02068 02069 /* We will use dead_detector to fill the array below. 02070 * This is static because values are determined one time 02071 * and then saved for subsequent scans. 02072 */ 02073 02074 static int8 dead_det_array [NUM_FDD_DATA_SETS][MAX_BANDS_PER_FDD_SET] 02075 [MAX_DETECTORS_PER_BAND]; 02076 02077 /* The following static variable is used to determine if we have 02078 * already defined the above array (we only need to fill it for 02079 * one scan -- it is the same for all scans). 02080 */ 02081 02082 static boolean dead_det_array_is_filled = False; 02083 02084 /* The following static variables is used to map the index of 02085 * bands through all bands to the index of bands within each L1A 02086 * resolution. 02087 */ 02088 02089 static int8 band_38[NUM_FDD_DATA_SETS][MAX_BANDS_PER_FDD_SET]; 02090 02091 /* The following static variables is used to map the index of 02092 * detectors through all detectors to the index of detectors within 02093 * each band within each L1A resolution. 02094 */ 02095 02096 static int16 det_490[NUM_FDD_DATA_SETS][MAX_BANDS_PER_FDD_SET] 02097 [MAX_DETECTORS_PER_BAND]; 02098 02099 int32 R; /* Index through L1A resolutions */ 02100 int32 B; /* Index through bands within one L1A resolution */ 02101 int32 B_38; /* Index through all bands, in order */ 02102 int32 D; /* Index through detectors within a band */ 02103 int32 D_490; /* Index through all detectors, in order */ 02104 int32 B_emiss; /* Index through L1B emissive bands */ 02105 int32 B26_RSB; /* index of band 26 inside L1B RSB band set */ 02106 int32 D_prev; /* index of previous detector. */ 02107 int32 D_subs; /* index of subsequent detector. */ 02108 int32 iset; /* index of data set being operated on */ 02109 int32 F; /* Frame index (frame and sample) */ 02110 02111 PGSt_SMF_status returnStatus = MODIS_S_OK; 02112 char *location = "Fill_Dead_Detector_SI"; 02113 02114 /* Utility pointers -- to an array of frames */ 02115 02116 uint16 *SI = 0; /* SI for scan line in question */ 02117 uint16 *SI_prev = 0; /* SI for previous scan line */ 02118 uint16 *SI_subs = 0; /* SI for subsequent scan line */ 02119 02120 /************************* Declarations complete ***********************/ 02121 02122 02123 if (dead_det_array_is_filled == False) 02124 { 02125 02126 /* Assemble new dead detector array having more convenient 02127 * dimensionality. 02128 */ 02129 02130 /* Initialize to a bad value so we can check later */ 02131 02132 for (iset = 0; iset < NUM_FDD_DATA_SETS; iset++) 02133 { 02134 for (B = 0; B < MAX_BANDS_PER_FDD_SET; B++) 02135 { 02136 for (D = 0; D < MAX_DETECTORS_PER_BAND; D++) 02137 { 02138 dead_det_array [iset][B][D] = -1; 02139 } 02140 } 02141 } 02142 02143 /* Fill the 3D dead detector array. */ 02144 02145 B_38 = 0; 02146 D_490 = 0; 02147 R = INDEX_250M; 02148 for (B = 0; B < L1A_BANDS_AT_RES[R]; B++, B_38++) 02149 { 02150 band_38[FDD_RSB_250M][B] = B_38; 02151 for (D = 0; D < DETECT_PER_BAND_AT_RES[R]; D++, D_490++) 02152 { 02153 dead_det_array[FDD_RSB_250M][B][D] = dead_detector[D_490]; 02154 det_490[FDD_RSB_250M][B][D] = D_490; 02155 } 02156 } 02157 R = INDEX_500M; 02158 for (B = 0; B < L1A_BANDS_AT_RES[R]; B++, B_38++) 02159 { 02160 band_38[FDD_RSB_500M][B] = B_38; 02161 for (D = 0; D < DETECT_PER_BAND_AT_RES[R]; D++, D_490++) 02162 { 02163 dead_det_array[FDD_RSB_500M][B][D] = dead_detector[D_490]; 02164 det_490[FDD_RSB_500M][B][D] = D_490; 02165 } 02166 } 02167 R = INDEX_1000M_DAY; 02168 for (B = 0; B < L1A_BANDS_AT_RES[R]; B++, B_38++) 02169 { 02170 band_38[FDD_RSB_1KM_DAY][B] = B_38; 02171 for (D = 0; D < DETECT_PER_BAND_AT_RES[R]; D++, D_490++) 02172 { 02173 dead_det_array[FDD_RSB_1KM_DAY][B][D] = dead_detector[D_490]; 02174 det_490[FDD_RSB_1KM_DAY][B][D] = D_490; 02175 } 02176 } 02177 R = INDEX_1000M_NIGHT; 02178 B_emiss = 0; 02179 B26_RSB = L1B_BANDS_AT_RES[INDEX_1000M_DAY] - 1; 02180 for (B = 0; B < L1A_BANDS_AT_RES[R]; B++, B_38++) 02181 { 02182 if (B == MODIS_BAND26_INDEX_AT_RES) 02183 { 02184 band_38[FDD_RSB_1KM_DAY][B26_RSB] = B_38; 02185 #ifdef WRITE_BAND_26_SDS 02186 band_38[FDD_RSB_BAND26][0] = B_38; 02187 #endif /* WRITE_BAND_26_SDS */ 02188 02189 for (D = 0; D < DETECT_PER_BAND_AT_RES[R]; D++, D_490++) 02190 { 02191 dead_det_array[FDD_RSB_1KM_DAY][B26_RSB][D] = dead_detector[D_490]; 02192 det_490[FDD_RSB_1KM_DAY][B26_RSB][D] = D_490; 02193 #ifdef WRITE_BAND_26_SDS 02194 dead_det_array[FDD_RSB_BAND26][0][D] = dead_detector[D_490]; 02195 det_490[FDD_RSB_BAND26][0][D] = D_490; 02196 #endif /* WRITE_BAND_26_SDS */ 02197 } 02198 } 02199 else 02200 { 02201 band_38[FDD_TEB_1KM][B_emiss] = B_38; 02202 for (D = 0; D < DETECT_PER_BAND_AT_RES[R]; D++, D_490++) 02203 { 02204 dead_det_array[FDD_TEB_1KM][B_emiss][D] = dead_detector[D_490]; 02205 det_490[FDD_TEB_1KM][B_emiss][D] = D_490; 02206 } 02207 B_emiss++; 02208 } 02209 } 02210 02211 /* Check for a bad value -- make sure we assigned each one. */ 02212 02213 for (iset = 0; iset < NUM_FDD_DATA_SETS; iset++) 02214 { 02215 for (B = 0; B < num_bands_per_set[iset]; B++) 02216 { 02217 for (D = 0; D < num_dets_per_set[iset]; D++) 02218 { 02219 if (dead_det_array [iset][B][D] == -1) 02220 { 02221 returnStatus = MODIS_F_NOK; 02222 L1BErrorMsg(location, returnStatus, 02223 "Dead detector array values not properly assigned.", 02224 NULL, 0, NULL, True); 02225 return returnStatus; 02226 } 02227 } 02228 } 02229 } 02230 02231 dead_det_array_is_filled = True; 02232 } 02233 02234 /* Main loop through all data sets. */ 02235 02236 for (iset = 0; iset < NUM_FDD_DATA_SETS; iset++) 02237 { 02238 02239 /* Skip this set if it is day only and scan is not day */ 02240 02241 if (isdaymode == False && isdayonly[iset] == True) 02242 continue; 02243 02244 /* Loop through bands in this data set */ 02245 02246 for (B = 0; B < num_bands_per_set[iset]; B++) 02247 { 02248 B_38 = band_38[iset][B]; 02249 02250 qa_flag = True; 02251 02252 #ifdef WRITE_BAND_26_SDS 02253 if (iset != FDD_RSB_BAND26 && B_38 == MODIS_BAND26_INDEX) 02254 qa_flag = False; 02255 #endif /* WRITE_BAND_26_SDS */ 02256 02257 /* Loop through detectors */ 02258 02259 for (D = 0; D < num_dets_per_set[iset]; D++) 02260 { 02261 02262 /* If this detector is not "dead", skip it. 02263 * (leave pixels as they are). 02264 */ 02265 02266 if (dead_det_array[iset][B][D] == 0) 02267 continue; 02268 02269 /* Determine D_prev by going back 02270 * and finding the 1st non-dead detector. 02271 */ 02272 02273 D_prev = D - 1; 02274 while (D_prev >= 0) 02275 { 02276 if (dead_det_array[iset][B][D_prev] == 0) 02277 break; 02278 D_prev--; 02279 } 02280 02281 /* Determine D_subs in a similar way. */ 02282 02283 D_subs = D + 1; 02284 while (D_subs < num_dets_per_set[iset]) 02285 { 02286 if (dead_det_array[iset][B][D_subs] == 0) 02287 break; 02288 D_subs++; 02289 } 02290 02291 if (D_subs == num_dets_per_set[iset]) 02292 D_subs = -1; 02293 02294 /* If both D_prev and D_subs are invalid, continue 02295 * (omit this detector) 02296 */ 02297 02298 if (D_prev == -1 && D_subs == -1) 02299 continue; 02300 02301 if (D_prev == D_subs) /*** Should not happen ***/ 02302 continue; 02303 02304 /* Assign the data to be used for filling in values */ 02305 02306 #ifdef WRITE_BAND_26_SDS 02307 if (iset == FDD_RSB_BAND26) 02308 { 02309 SI = L1B_Scan->Band26.SI[D]; 02310 if (D_prev >= 0) 02311 SI_prev = L1B_Scan->Band26.SI[D_prev]; 02312 if (D_subs >= 0) 02313 SI_subs = L1B_Scan->Band26.SI[D_subs]; 02314 } 02315 02316 else 02317 #endif /* WRITE_BAND_26_SDS */ 02318 if (iset == FDD_RSB_250M) 02319 { 02320 SI = L1B_Scan->SI.EV_250m_RefSB[B][D]; 02321 if (D_prev >= 0) 02322 SI_prev = L1B_Scan->SI.EV_250m_RefSB[B][D_prev]; 02323 if (D_subs >= 0) 02324 SI_subs = L1B_Scan->SI.EV_250m_RefSB[B][D_subs]; 02325 } 02326 02327 else if (iset == FDD_RSB_500M) 02328 { 02329 SI = L1B_Scan->SI.EV_500m_RefSB[B][D]; 02330 if (D_prev >= 0) 02331 SI_prev = L1B_Scan->SI.EV_500m_RefSB[B][D_prev]; 02332 if (D_subs >= 0) 02333 SI_subs = L1B_Scan->SI.EV_500m_RefSB[B][D_subs]; 02334 } 02335 02336 else if (iset == FDD_RSB_1KM_DAY) 02337 { 02338 SI = L1B_Scan->SI.EV_1km_RefSB[B][D]; 02339 if (D_prev >= 0) 02340 SI_prev = L1B_Scan->SI.EV_1km_RefSB[B][D_prev]; 02341 if (D_subs >= 0) 02342 SI_subs = L1B_Scan->SI.EV_1km_RefSB[B][D_subs]; 02343 } 02344 02345 else if (iset == FDD_TEB_1KM) 02346 { 02347 SI = L1B_Scan->SI.EV_1km_Emissive[B][D]; 02348 if (D_prev >= 0) 02349 SI_prev = L1B_Scan->SI.EV_1km_Emissive[B][D_prev]; 02350 if (D_subs >= 0) 02351 SI_subs = L1B_Scan->SI.EV_1km_Emissive[B][D_subs]; 02352 } 02353 02354 /* At long last, fill the array of values to be written */ 02355 02356 D_490 = det_490[iset][B][D]; 02357 02358 if (D_prev == -1) 02359 { 02360 for (F = 0; F < num_frames_per_set[iset]; F++) 02361 { 02362 if (SI_subs[F] <= DN15_SAT && SI[F] == DEAD_DETECTOR_SI) 02363 { 02364 SI[F] = SI_subs[F]; 02365 if (qa_flag) 02366 { 02367 L1B_Gran->interpolated_pixels[B_38]++; 02368 L1B_Gran->valid_pixels[B_38]++; 02369 QA_Common->num_dead_detector_EV_data[D_490]--; 02370 } 02371 } 02372 } 02373 } 02374 02375 else if (D_subs == -1) 02376 { 02377 for (F = 0; F < num_frames_per_set[iset]; F++) 02378 { 02379 if (SI_prev[F] <= DN15_SAT && SI[F] == DEAD_DETECTOR_SI) 02380 { 02381 SI[F] = SI_prev[F]; 02382 if (qa_flag) 02383 { 02384 L1B_Gran->interpolated_pixels[B_38]++; 02385 L1B_Gran->valid_pixels[B_38]++; 02386 QA_Common->num_dead_detector_EV_data[D_490]--; 02387 } 02388 } 02389 } 02390 } 02391 02392 else 02393 { 02394 float32 fract = ((float32) (D - D_prev)) / 02395 ((float32) (D_subs - D_prev)); 02396 for (F = 0; F < num_frames_per_set[iset]; F++) 02397 { 02398 if (SI_subs[F] <= DN15_SAT && SI_prev[F] <= DN15_SAT && 02399 SI[F] == DEAD_DETECTOR_SI) 02400 { 02401 SI[F] = (uint16)((float32)SI_prev[F] + 02402 (fract * ((float32)SI_subs[F] - 02403 (float32)SI_prev[F]))); 02404 if (qa_flag) 02405 { 02406 L1B_Gran->interpolated_pixels[B_38]++; 02407 L1B_Gran->valid_pixels[B_38]++; 02408 QA_Common->num_dead_detector_EV_data[D_490]--; 02409 } 02410 } 02411 02412 else if (SI_subs[F] <= DN15_SAT && 02413 SI[F] == DEAD_DETECTOR_SI) 02414 { 02415 SI[F] = SI_subs[F]; 02416 if (qa_flag) 02417 { 02418 L1B_Gran->interpolated_pixels[B_38]++; 02419 L1B_Gran->valid_pixels[B_38]++; 02420 QA_Common->num_dead_detector_EV_data[D_490]--; 02421 } 02422 } 02423 02424 else if (SI_prev[F] <= DN15_SAT && 02425 SI[F] == DEAD_DETECTOR_SI) 02426 { 02427 SI[F] = SI_prev[F]; 02428 if (qa_flag) 02429 { 02430 L1B_Gran->interpolated_pixels[B_38]++; 02431 L1B_Gran->valid_pixels[B_38]++; 02432 QA_Common->num_dead_detector_EV_data[D_490]--; 02433 } 02434 } 02435 } 02436 } 02437 02438 } /* loop through D */ 02439 } /* loop through B */ 02440 } /* loop through iset */ 02441 02442 02443 return returnStatus; 02444 } 02445 02446 PGSt_SMF_status Open_and_Read_L1A 02447 (Run_Time_Parameters_t *runtime_params, 02448 L1A_granule_t *L1A_Gran, 02449 boolean *skip_night_hi_res) 02450 02451 /* 02452 !C************************************************************************** 02453 !Description: This function opens the L1A granule to be processed and reads 02454 in data for all members of the L1A_granule_t structure. The 02455 file remains open (both SD and Vdata) upon function exit. 02456 02457 !Input Parameters: 02458 Run_Time_Parameters_t *runtime_params Values read from PCF file. 02459 02460 !Output Parameters: 02461 L1A_granule_t *L1A_Gran contains SD file interface ID, Vdata 02462 file interface ID, number of scans and 02463 other data relating to the middle 02464 granule 02465 02466 !Revision History: 02467 (continue at top of the file) 02468 02469 Revision 01.02 June 4, 2002 Razor Issue #169 02470 Changed logic to check whether any scans are in day mode and if so, set 02471 skip_night_hi_res to False. 02472 Gwyn Fireman & Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov) 02473 02474 Revision 01.01 November 12, 2001 (Razor Issue #169) 02475 Added boolean skip_night_hi_res as output variable. 02476 Alice Isaacman (Alice.R.Isaacman.1@gsfc.nasa.gov), SAIC GSO 02477 02478 Revision 01.00 June 27, 2000 02479 Initial development. 02480 Zhenying Gu (zgu@mcst.gsfc.nasa.gov) 02481 02482 !Team-unique Header: 02483 This software is developed by the MODIS Science Data Support 02484 Team for the National Aeronautics and Space Administration, 02485 Goddard Space Flight Center, under contract NAS5-32373. 02486 02487 !References and Credits 02488 HDF portions developed at the National Center for Supercomputing 02489 Applications at the University of Illinois at Urbana-Champaign. 02490 02491 !Design Notes: 02492 !END******************************************************************** 02493 */ 02494 { 02495 PGSt_SMF_status returnStatus = MODIS_S_OK; 02496 intn hdf_return = 0; 02497 PGSt_integer Version = 1; 02498 char file_name[PGSd_PC_FILE_PATH_MAX]; 02499 int32 S; /* scan index */ 02500 int32 middle_scan; 02501 int32 geo_satellite_id; 02502 char *location = "Open_and_Read_L1A"; 02503 char *satelliteInstrument; 02504 02505 /* 02506 * Will be set to TRUE by PCF file only if writing 250m and 02507 * 500m files when in night mode is desired. 02508 */ 02509 boolean write_nightmode_hires = 0; 02510 boolean is_nightmode_data = 0; 02511 02512 /* 02513 * Prepare for opening file: convert logical ID to physical name 02514 */ 02515 02516 returnStatus = PGS_PC_GetReference (FIRST_L1A_GRANULE, &Version, file_name); 02517 if (returnStatus != PGS_S_SUCCESS) 02518 { 02519 returnStatus = MODIS_F_FILE_NOT_FOUND; 02520 L1BErrorMsg(location, returnStatus, "Could not retrieve file name from PCF.", 02521 "PGS_PC_GetReference", FIRST_L1A_GRANULE, NULL, True); 02522 return returnStatus; 02523 } 02524 02525 /* 02526 * Open file for HDF science data (SD) access. 02527 */ 02528 02529 L1A_Gran->sd_id = SDstart(file_name,DFACC_RDONLY); /*for SD interface */ 02530 if (L1A_Gran->sd_id == FAIL) 02531 { 02532 returnStatus = MODIS_F_FILE_NOT_OPENED; 02533 L1BErrorMsg(location, returnStatus, "Could not open file for SD read access.", 02534 "SDstart", FIRST_L1A_GRANULE, 02535 "The file may be missing, corrupted or not an HDF-4 file.", True); 02536 return returnStatus; 02537 } 02538 02539 /* 02540 * Open file for HDF Vdata access and initialize Vdata interface. 02541 * Call Hopen() and Vstart() in the same place. 02542 */ 02543 02544 L1A_Gran->v_id = Hopen(file_name,DFACC_RDONLY,0); 02545 if (L1A_Gran->v_id == FAIL) 02546 { 02547 SDend (L1A_Gran->sd_id); 02548 returnStatus = MODIS_F_FILE_NOT_OPENED; 02549 L1BErrorMsg(location, returnStatus, "Could not open file for Vdata read access.", 02550 "Hopen", FIRST_L1A_GRANULE, 02551 "The file may be corrupted or not an HDF-4 file.", True); 02552 return returnStatus; 02553 } 02554 02555 hdf_return = Vstart (L1A_Gran->v_id); /*initialize internal structures*/ 02556 if (hdf_return == FAIL) 02557 { 02558 SDend (L1A_Gran->sd_id); Hclose (L1A_Gran->v_id); 02559 returnStatus = MODIS_F_HDF_ERROR; 02560 L1BErrorMsg(location, returnStatus, "Could not initialize Vdata interface.", 02561 "Vstart", FIRST_L1A_GRANULE, 02562 "The file may be corrupted or not an HDF-4 file.", True); 02563 return returnStatus; 02564 } 02565 02566 /* 02567 * Read num_scans 02568 */ 02569 02570 returnStatus = read_attribute (L1A_Gran->sd_id, "Number of Scans", 02571 DFNT_INT32, (void *)&L1A_Gran->num_scans); 02572 if (returnStatus != MODIS_S_OK) 02573 { 02574 L1BErrorMsg(location, returnStatus, "Could not read Number of Scans.", 02575 "read_attribute", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True); 02576 return returnStatus; 02577 } 02578 02579 if (L1A_Gran->num_scans <= 0) 02580 { 02581 returnStatus = MODIS_F_OUT_OF_RANGE; 02582 MOD_PR02_Failure_Exit_Code = 233; 02583 L1BErrorMsg(location, returnStatus, 02584 "Number of Scans in the MOD01 granule is less than " 02585 "or equal to 0.\n" 02586 "The MOD01 granule is probably empty (no valid data)", 02587 NULL, FIRST_L1A_GRANULE, NULL, True); 02588 return returnStatus; 02589 } 02590 02591 if (L1A_Gran->num_scans > MAX_NUM_SCANS) 02592 { 02593 returnStatus = MODIS_F_OUT_OF_RANGE; 02594 L1BErrorMsg(location, returnStatus, 02595 "Number of Scans in the MOD01 granule is greater " 02596 "than MAX_NUM_SCANS.", 02597 NULL, FIRST_L1A_GRANULE, 02598 "If the file is valid, the code macro must be increased.", True); 02599 return returnStatus; 02600 } 02601 02602 /* 02603 * Read num_day_scans 02604 */ 02605 02606 returnStatus = read_attribute (L1A_Gran->sd_id, "Number of Day mode scans", 02607 DFNT_INT32, (VOIDP)&L1A_Gran->num_day_scans); 02608 if (returnStatus != MODIS_S_OK) 02609 { 02610 L1BErrorMsg(location, returnStatus, "Could not read Number of Day " 02611 "mode scans.", 02612 "read_attribute", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True); 02613 return returnStatus; 02614 } 02615 02616 /* 02617 * Set skip_night_hi_res flag 02618 */ 02619 02620 if (strcmp(runtime_params->Write_Night_Mode_HiRes_Data, "0") == 0) 02621 write_nightmode_hires = False; 02622 else 02623 write_nightmode_hires = True; 02624 02625 if (L1A_Gran->num_day_scans == 0) 02626 is_nightmode_data = True; 02627 else 02628 is_nightmode_data = False; 02629 02630 if (is_nightmode_data == True && write_nightmode_hires == False) 02631 *skip_night_hi_res = True; 02632 else 02633 *skip_night_hi_res = False; 02634 02635 /* 02636 * Read L1A ScanType 02637 */ 02638 02639 returnStatus = read_sds_rank2 (L1A_Gran->sd_id, "Scan Type", 02640 L1A_Gran->num_scans, SCAN_TYPE_TEXT_SIZE, 02641 (void *)L1A_Gran->ScanType); 02642 if (returnStatus != MODIS_S_OK) 02643 { 02644 L1BErrorMsg(location, returnStatus, "Could not read Scan Type.", 02645 "read_sds_rank2", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True); 02646 return returnStatus; 02647 } 02648 02649 for (S = 0; S < L1A_Gran->num_scans; S++) 02650 { 02651 if (strcmp(L1A_Gran->ScanType[S], "Day") != 0 && 02652 strcmp(L1A_Gran->ScanType[S], "Night") != 0 && 02653 strcmp(L1A_Gran->ScanType[S], "Other") != 0) 02654 { 02655 returnStatus = MODIS_F_OUT_OF_RANGE; 02656 L1BErrorMsg(location, returnStatus, 02657 "Scan Type is not \"Day\", \"Night\", or \"Other\".", 02658 NULL, FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True); 02659 return returnStatus; 02660 } 02661 } 02662 02663 /* 02664 * Read L1A EVStartTime_TAIsecond 02665 */ 02666 02667 returnStatus = read_sds_rank1 (L1A_Gran->sd_id, "EV start time", 02668 L1A_Gran->num_scans, 02669 (void *)L1A_Gran->EVStartTime_TAIsecond); 02670 if (returnStatus != MODIS_S_OK) 02671 { 02672 L1BErrorMsg(location, returnStatus, "Could not read EV start time.", 02673 "read_sds_rank1", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True); 02674 return returnStatus; 02675 } 02676 02677 /* 02678 * Determine data collection time. The valid EV start time for the scan 02679 * closest to the middle scan is chosen to be the data collection time. 02680 * This time is used for time-dependent look up tables. 02681 */ 02682 02683 middle_scan = L1A_Gran->num_scans/2; 02684 L1A_Gran->data_collection_time = 0; 02685 for (S = 0; middle_scan-S >= 0 && 02686 middle_scan+S < L1A_Gran->num_scans; S++) { 02687 if (L1A_Gran->EVStartTime_TAIsecond[middle_scan-S] > 0) { 02688 L1A_Gran->data_collection_time = 02689 L1A_Gran->EVStartTime_TAIsecond[middle_scan-S]; 02690 break; 02691 } 02692 else if (L1A_Gran->EVStartTime_TAIsecond[middle_scan+S] > 0) { 02693 L1A_Gran->data_collection_time = 02694 L1A_Gran->EVStartTime_TAIsecond[middle_scan+S]; 02695 break; 02696 } 02697 } 02698 02699 if (L1A_Gran->data_collection_time == 0) { 02700 returnStatus = MODIS_F_NOK; 02701 L1BErrorMsg(location, returnStatus, 02702 "No valid or only one valid EV start time in the " 02703 "array \"EV start time\"", 02704 NULL, 0, NULL, True); 02705 return returnStatus; 02706 } 02707 02708 /* 02709 * Read L1A MirrorSide 02710 */ 02711 02712 returnStatus = read_sds_rank1 (L1A_Gran->sd_id, "Mirror side", 02713 L1A_Gran->num_scans, 02714 (void *)L1A_Gran->MirrorSide); 02715 if ( returnStatus != MODIS_S_OK) 02716 { 02717 L1BErrorMsg(location, returnStatus, "Could not read Mirror side.", 02718 "read_sds_rank1", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True); 02719 return returnStatus; 02720 } 02721 02722 for (S = 0; S < L1A_Gran->num_scans; S++) 02723 { 02724 if (L1A_Gran->MirrorSide[S] != 0 && L1A_Gran->MirrorSide[S] != 1 02725 && L1A_Gran->MirrorSide[S] != -1) 02726 { 02727 returnStatus = MODIS_F_OUT_OF_RANGE; 02728 L1BErrorMsg(location, returnStatus, "Mirror side is not [-1, 0, 1].", 02729 NULL, FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True); 02730 return returnStatus; 02731 } 02732 } 02733 02734 /* 02735 * Read num_night_scans 02736 */ 02737 02738 returnStatus = read_attribute (L1A_Gran->sd_id, 02739 "Number of Night mode scans", 02740 DFNT_INT32, 02741 (VOIDP)&L1A_Gran->num_night_scans); 02742 if (returnStatus != MODIS_S_OK) 02743 { 02744 L1BErrorMsg(location, returnStatus, 02745 "Could not read Number of Night mode scans.", 02746 "read_attribute", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True); 02747 return returnStatus; 02748 } 02749 02750 /* 02751 * Read incomplete_scans 02752 */ 02753 02754 returnStatus = read_attribute (L1A_Gran->sd_id, 02755 "Incomplete Scans", DFNT_INT32, 02756 (VOIDP)&L1A_Gran->incomplete_scans); 02757 if (returnStatus != MODIS_S_OK) 02758 { 02759 L1BErrorMsg(location, returnStatus, 02760 "Could not read number of incomplete scans.", 02761 "read_attribute", 02762 FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True); 02763 return returnStatus; 02764 } 02765 02766 /* 02767 * Read max_ev_frames 02768 */ 02769 02770 returnStatus = read_attribute (L1A_Gran->sd_id, 02771 "Max Earth Frames", DFNT_INT32, 02772 (VOIDP)&L1A_Gran->max_ev_frames); 02773 if (returnStatus != MODIS_S_OK) 02774 { 02775 L1BErrorMsg(location, returnStatus, 02776 "Could not read maximum number of EV frames.", 02777 "read_attribute", FIRST_L1A_GRANULE, 02778 Invalid_MOD01_Msg, True); 02779 return returnStatus; 02780 } 02781 02782 02783 /* 02784 * Read Extract Pixel Offset & Count 02785 */ 02786 02787 if (SDfindattr(L1A_Gran->sd_id, "Extract Pixel Offset") != -1) { 02788 returnStatus = read_attribute (L1A_Gran->sd_id, 02789 "Extract Pixel Offset", DFNT_INT32, 02790 (VOIDP)&L1A_Gran->Extract_Pixel_Offset); 02791 } else L1A_Gran->Extract_Pixel_Offset = -1; 02792 02793 if (SDfindattr(L1A_Gran->sd_id, "Extract Pixel Count") != -1) { 02794 returnStatus = read_attribute (L1A_Gran->sd_id, 02795 "Extract Pixel Count", DFNT_INT32, 02796 (VOIDP)&L1A_Gran->Extract_Pixel_Count); 02797 } else L1A_Gran->Extract_Pixel_Count = -1; 02798 02799 02800 /* 02801 * Read Extract Line Offset & Count 02802 */ 02803 02804 if (SDfindattr(L1A_Gran->sd_id, "Extract Line Offset") != -1) { 02805 returnStatus = read_attribute (L1A_Gran->sd_id, 02806 "Extract Line Offset", DFNT_INT32, 02807 (VOIDP)&L1A_Gran->Extract_Line_Offset); 02808 } else L1A_Gran->Extract_Line_Offset = -1; 02809 02810 if (SDfindattr(L1A_Gran->sd_id, "Extract Line Count") != -1) { 02811 returnStatus = read_attribute (L1A_Gran->sd_id, 02812 "Extract Line Count", DFNT_INT32, 02813 (VOIDP)&L1A_Gran->Extract_Line_Count); 02814 } else L1A_Gran->Extract_Line_Count = -1; 02815 02816 02817 /* 02818 * Read scan quality array 02819 */ 02820 02821 returnStatus = read_sds_rank2(L1A_Gran->sd_id, "Scan quality array", 02822 L1A_Gran->num_scans, 02823 SCAN_QUALITY_ARRAY_NUM_ELEMENTS, 02824 (VOIDP)L1A_Gran->scan_quality); 02825 if (returnStatus != MODIS_S_OK) { 02826 L1BErrorMsg(location, returnStatus, "Could not read scan quality array", 02827 "read_sds_rank2", FIRST_L1A_GRANULE, NULL, True); 02828 return returnStatus; 02829 } 02830 02831 /* 02832 * Determine if a scan is completely missing based on the second element 02833 * of Scan quality array. 02834 */ 02835 02836 for (S = 0; S < L1A_Gran->num_scans; S++) 02837 { 02838 if (L1A_Gran->scan_quality[S][0] == 0) 02839 L1A_Gran->missing_scan[S] = True; 02840 else 02841 L1A_Gran->missing_scan[S] = False; 02842 } 02843 02844 /* 02845 * Determine the satellite 02846 */ 02847 02848 returnStatus = Get_Satellite_ID(FIRST_L1A_GRANULE, &L1A_Gran->satellite_id); 02849 if (returnStatus != MODIS_S_OK) 02850 { 02851 L1BErrorMsg(location, returnStatus, "Could not get satellite ID.", 02852 "Get_Satellite_ID", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True); 02853 return returnStatus; 02854 } 02855 02856 /* 02857 * Determine the satellite instrument value in geo file. 02858 */ 02859 02860 returnStatus = Get_Satellite_ID(GEOLOCATION_FILE, &geo_satellite_id); 02861 if (returnStatus != MODIS_S_OK) 02862 { 02863 L1BErrorMsg(location, returnStatus, "Could not get satellite ID.", 02864 "Get_Satellite_ID", GEOLOCATION_FILE, 02865 "The geolocation file is invalid.", True); 02866 return returnStatus; 02867 } 02868 02869 /* 02870 * Check if the geo granule and L1A granule is for the same instrument. 02871 */ 02872 02873 if (geo_satellite_id != L1A_Gran->satellite_id) 02874 { 02875 returnStatus = MODIS_F_NOK; 02876 L1BErrorMsg(location, returnStatus, 02877 "*** INCORRECT GEOLOCATION FILE ***\n" 02878 "The satellite instrument in the geolocation file (lun 600000) is\n" 02879 "different from that in the middle L1A granule (lun 500001).", 02880 NULL, 0, NULL, True); 02881 return returnStatus; 02882 } 02883 02884 /* 02885 * Check the run time parameter SatelliteInstrument from the PCF file against 02886 * the satellite inherent in the L1A data. 02887 */ 02888 02889 satelliteInstrument = runtime_params->SatelliteInstrument; 02890 if (!((strcmp(satelliteInstrument, "AM1M") == 0 && 02891 L1A_Gran->satellite_id == TERRA) || 02892 (strcmp(satelliteInstrument, "PM1M") == 0 && 02893 L1A_Gran->satellite_id == AQUA))) 02894 { 02895 returnStatus = MODIS_F_NOK; 02896 L1BErrorMsg(location, returnStatus, 02897 "The satellite instrument set in the PCF does not match\n" 02898 "the value inherent in the middle L1A granule.", 02899 NULL, 0, NULL, True); 02900 return returnStatus; 02901 } 02902 02903 02904 RFLAG = 0; 02905 if (SDnametoindex(L1A_Gran->sd_id, "EV_250m") == -1 || 02906 SDnametoindex(L1A_Gran->sd_id, "BB_250m") == -1 || 02907 SDnametoindex(L1A_Gran->sd_id, "SV_250m") == -1 || 02908 SDnametoindex(L1A_Gran->sd_id, "SD_250m") == -1 || 02909 SDnametoindex(L1A_Gran->sd_id, "SRCA_250m") == -1) { 02910 RFLAG = RFLAG | 1; 02911 } 02912 02913 if (SDnametoindex(L1A_Gran->sd_id, "EV_500m") == -1 || 02914 SDnametoindex(L1A_Gran->sd_id, "BB_500m") == -1 || 02915 SDnametoindex(L1A_Gran->sd_id, "SV_500m") == -1 || 02916 SDnametoindex(L1A_Gran->sd_id, "SD_500m") == -1 || 02917 SDnametoindex(L1A_Gran->sd_id, "SRCA_500m") == -1) { 02918 RFLAG = RFLAG | 2; 02919 } 02920 02921 if (SDnametoindex(L1A_Gran->sd_id, "EV_1km_day") == -1 || 02922 SDnametoindex(L1A_Gran->sd_id, "BB_1km_day") == -1 || 02923 SDnametoindex(L1A_Gran->sd_id, "SV_1km_day") == -1 || 02924 SDnametoindex(L1A_Gran->sd_id, "SD_1km_day") == -1 || 02925 SDnametoindex(L1A_Gran->sd_id, "SRCA_1km_day") == -1) { 02926 RFLAG = RFLAG | 4; 02927 } 02928 02929 if (SDnametoindex(L1A_Gran->sd_id, "EV_1km_night") == -1 || 02930 SDnametoindex(L1A_Gran->sd_id, "BB_1km_night") == -1 || 02931 SDnametoindex(L1A_Gran->sd_id, "SV_1km_night") == -1 || 02932 SDnametoindex(L1A_Gran->sd_id, "SD_1km_night") == -1 || 02933 SDnametoindex(L1A_Gran->sd_id, "SRCA_1km_night") == -1) { 02934 RFLAG = RFLAG | 8; 02935 } 02936 02937 if (SDfindattr(L1A_Gran->sd_id, "B_13_scale_parm") != -1) 02938 RSCL_FLAG = RSCL_FLAG | 1; 02939 if (SDfindattr(L1A_Gran->sd_id, "B_16_scale_parm") != -1) 02940 RSCL_FLAG = RSCL_FLAG | 2; 02941 if (SDfindattr(L1A_Gran->sd_id, "B_10_scale_parm") != -1) 02942 RSCL_FLAG = RSCL_FLAG | 4; 02943 if (SDfindattr(L1A_Gran->sd_id, "B_12_scale_parm") != -1) 02944 RSCL_FLAG = RSCL_FLAG | 8; 02945 02946 returnStatus = MODIS_S_OK; /* Successful completion of function */ 02947 return returnStatus; /* L1A granule remains open */ 02948 } 02949 02950 PGSt_SMF_status Get_Satellite_ID (PGSt_PC_Logical lun, int32 *satellite_ID) 02951 /* 02952 !C************************************************************************** 02953 !Description: This function reads the metadata "SHORTNAME" from the file 02954 designated by the lun and determines the satelitte name. 02955 02956 !Input Parameters: 02957 int32 lun logic identifier of the file. 02958 02959 !Output Parameters: 02960 int32 *satellite_ID identifier of the satellite (TERRA = 0, AQUA = 1, 02961 INVALID_SATELLITE_ID = -1) 02962 02963 !Revision History: 02964 (continue at top of the file) 02965 02966 Revision 01.00 June 27, 2000 02967 Initial development. 02968 Zhenying Gu (zgu@mcst.gsfc.nasa.gov) 02969 02970 !Team-unique Header: 02971 This software is developed by the MODIS Science Data Support 02972 Team for the National Aeronautics and Space Administration, 02973 Goddard Space Flight Center, under contract NAS5-32373. 02974 02975 !References and Credits 02976 HDF portions developed at the National Center for Supercomputing 02977 Applications at the University of Illinois at Urbana-Champaign. 02978 02979 !Design Notes: 02980 !END******************************************************************** 02981 */ 02982 { 02983 PGSt_SMF_status returnStatus = MODIS_S_OK; 02984 PGSt_integer Version = 1; 02985 char shortname[10]; 02986 char *shortnameptr; 02987 char *attrName = "SHORTNAME"; 02988 char *location = "Get_Satellite_ID"; 02989 02990 /* To use the address of the shortname[], a pointer is needed. */ 02991 02992 shortnameptr = shortname; 02993 02994 /* Get the shortname */ 02995 02996 returnStatus = PGS_MET_GetPCAttr(lun, Version, "CoreMetadata.0", 02997 attrName, &shortnameptr); 02998 if (returnStatus != PGS_S_SUCCESS) 02999 { 03000 returnStatus = MODIS_F_READ_ERROR; 03001 L1BErrorMsg (location, returnStatus, "Could not get metadata \"SHORTNAME\".", 03002 "PGS_MET_GetPCAttr", lun, NULL, True); 03003 } 03004 03005 if (strncmp(shortname, "MOD", 3) == 0) 03006 *satellite_ID = TERRA; 03007 else if (strncmp(shortname, "MYD", 3) == 0) 03008 *satellite_ID = AQUA; 03009 else 03010 *satellite_ID = INVALID_SATELLITE_ID; 03011 03012 return MODIS_S_OK; 03013 } 03014 03015 PGSt_SMF_status Read_Run_Time_Parameters (Run_Time_Parameters_t *runtime_params) 03016 /* 03017 !C************************************************************************** 03018 !Description: 03019 Read all run-time parameters from the PCF file and set the values in the 03020 output variable. 03021 03022 !Input Parameters: 03023 none 03024 03025 !Output Parameters: 03026 Run_Time_Parameters_t *runtime_params 03027 contains SatelliteInstrument, 03028 ReprocessingPlanned, 03029 ReprocessingActual, 03030 PGE02_Version, 03031 MCST_LUT_Version, 03032 Write_Night_Mode_HiRes_Data, 03033 ProcessingEnvironment 03034 !Revision History: 03035 (continue at top of the file) 03036 03037 Revision 01.04 October 31, 2003 Razor Issue #195 03038 Added the code of reading the ProcessingCenter value from the 03039 Run_Time_Parameters_t structure. 03040 Liqin Tan, SAIC GSO (ltan@saicmodis.com) 03041 03042 Revision 01.03 September 15, 2003 Razor Issue #181 03043 Added ProcessingEnvironment parameter as per SDST request for 03044 Collection 4. It is set by calling the appropriate POSIX 03045 function from within the module, rather than read from the 03046 PCF file. This is to avoid seeing error messages from the 03047 SDP Toolkit for each granule when the field is left blank in 03048 the PCF file, which is allowable. 03049 Liqin Tan, SAIC GSO (ltan@saicmodis.com) 03050 03051 Revision 01.02 November 12, 2001 03052 Added Write_Night_Mode_HiRes_Data (Razor issue #169) 03053 Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov) 03054 03055 Revision 01.01 November 6, 2001 03056 Added MCST_LUT_Version (Razor issue #167) 03057 Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov) 03058 03059 Revision 01.00 February 21, 2001 03060 Initial development. 03061 Jim Rogers (rogers@mcst.gsfc.nasa.gov) 03062 03063 !Team-unique Header: 03064 This software is developed by the MODIS Science Data Support 03065 Team for the National Aeronautics and Space Administration, 03066 Goddard Space Flight Center, under contract NAS5-32373. 03067 03068 !References and Credits 03069 HDF portions developed at the National Center for Supercomputing 03070 Applications at the University of Illinois at Urbana-Champaign. 03071 03072 !Design Notes: 03073 03074 !END******************************************************************** 03075 */ 03076 { 03077 PGSt_SMF_status returnStatus; 03078 03079 char *location = "Read_Run_Time_Parameters"; 03080 /* Default ProcessingEnvironment identifier */ 03081 char thisname[MAX_PROCESSING_ENVIRONMENT_STRLEN] = ""; 03082 char *ename; /* Value of environment variable from "getenv" calls */ 03083 char *osnames[4] = {"OS", "OSTYPE", "BRAND", "MACHINE"}; 03084 char *hostnames[3] = {"HOST", "HOSTNAME", "HOSTTYPE"}; 03085 char *revision = "REVISION"; 03086 03087 int16 j = 0; /* A counter */ 03088 03089 if (!runtime_params) 03090 { 03091 returnStatus = MODIS_F_INVALID_ARGUMENT; 03092 03093 L1BErrorMsg(location, returnStatus, "Input runtime_params is NULL.", 03094 NULL, 0, NULL, True); 03095 return returnStatus; 03096 } 03097 03098 /* 03099 * Read and check the SatelliteInstrument value. 03100 */ 03101 03102 returnStatus = PGS_PC_GetConfigData(SATELLITE_INSTRUMENT_LUN, 03103 runtime_params->SatelliteInstrument); 03104 if (returnStatus != PGS_S_SUCCESS) 03105 { 03106 returnStatus = MODIS_F_NOK; 03107 L1BErrorMsg(location, returnStatus, 03108 "Failed to get parameter SatelliteInstrument from PCF file.", 03109 "PGS_PC_GetConfigData", SATELLITE_INSTRUMENT_LUN, 03110 "Invalid PCF file", True); 03111 return returnStatus; 03112 } 03113 if (!(strcmp(runtime_params->SatelliteInstrument, "AM1M") == 0 || 03114 strcmp(runtime_params->SatelliteInstrument, "PM1M") == 0)) 03115 { 03116 char errmsg[256]; 03117 sprintf (errmsg, 03118 "The SatelliteInstrument value (%s) in the PCF is invalid.", 03119 runtime_params->SatelliteInstrument); 03120 returnStatus = MODIS_F_NOK; 03121 L1BErrorMsg(location, returnStatus, errmsg, 03122 NULL, SATELLITE_INSTRUMENT_LUN, NULL, True); 03123 return returnStatus; 03124 } 03125 /* 03126 * Set the ProcessingEnvironment value. This 03127 * is not a mandatory entry and it is acceptable that 03128 * the value be missing or blank, but in practice it is easier to set it 03129 * within L1B and avoid seeing error messages when it is not in the PCF file. 03130 */ 03131 03132 strcpy((runtime_params->ProcessingEnvironment), ""); 03133 03134 /* 03135 * Obtain the processing environment fields 03136 * by calling the POSIX "getenv" function 03137 */ 03138 03139 for (j = 0; j < 4; j++) 03140 { 03141 ename = getenv(osnames[j]); 03142 03143 if (ename != NULL) 03144 03145 { 03146 /* Concatenate the desired names onto the ProcessingEnvironment string. */ 03147 safe_strcat(thisname, ename, MAX_PROCESSING_ENVIRONMENT_STRLEN); 03148 safe_strcat(thisname, " ", MAX_PROCESSING_ENVIRONMENT_STRLEN); 03149 03150 break; 03151 } 03152 } 03153 03154 for (j = 0; j < 3; j++) 03155 { 03156 ename = getenv(hostnames[j]); 03157 03158 if (ename != NULL) 03159 03160 { 03161 /* Concatenate the desired names onto the ProcessingEnvironment string. */ 03162 safe_strcat(thisname, ename, MAX_PROCESSING_ENVIRONMENT_STRLEN); 03163 safe_strcat(thisname, " ", MAX_PROCESSING_ENVIRONMENT_STRLEN); 03164 03165 break; 03166 } 03167 } 03168 ename = getenv(revision); 03169 03170 if (ename != NULL) 03171 03172 { 03173 /* Concatenate the desired names onto the ProcessingEnvironment string. */ 03174 safe_strcat(thisname, ename, MAX_PROCESSING_ENVIRONMENT_STRLEN); 03175 safe_strcat(thisname, " ", MAX_PROCESSING_ENVIRONMENT_STRLEN); 03176 } 03177 03178 /* 03179 * If the function getenv fails to return any values it is OK. 03180 */ 03181 03182 safe_strcat(runtime_params->ProcessingEnvironment, thisname, 03183 MAX_PROCESSING_ENVIRONMENT_STRLEN); 03184 03185 03186 /* 03187 * Read the ReprocessingPlanned value. This is not checked for specific 03188 * values because it is not clear that there is a constant set of valids 03189 * for this field (some could be added in the future). 03190 */ 03191 03192 returnStatus = PGS_PC_GetConfigData(REPROCESSING_PLANNED_LUN, 03193 runtime_params->ReprocessingPlanned); 03194 if (returnStatus != PGS_S_SUCCESS) 03195 { 03196 returnStatus = MODIS_F_NOK; 03197 L1BErrorMsg(location, returnStatus, 03198 "Failed to get parameter ReprocessingPlanned from PCF file.", 03199 "PGS_PC_GetConfigData", REPROCESSING_PLANNED_LUN, 03200 "Invalid PCF file", True); 03201 return returnStatus; 03202 } 03203 if (strlen(runtime_params->ReprocessingPlanned) == 0) 03204 { 03205 returnStatus = MODIS_F_NOK; 03206 L1BErrorMsg(location, returnStatus, 03207 "The ReprocessingPlanned value in the PCF is invalid (no string).", 03208 NULL, REPROCESSING_PLANNED_LUN, NULL, True); 03209 return returnStatus; 03210 } 03211 03212 /* 03213 * Read the ReprocessingActual value. This is not checked for specific 03214 * values because it is not clear that there is a constant set of valids 03215 * for this field (some could be added in the future). 03216 */ 03217 03218 returnStatus = PGS_PC_GetConfigData(REPROCESSING_ACTUAL_LUN, 03219 runtime_params->ReprocessingActual); 03220 if (returnStatus != PGS_S_SUCCESS) 03221 { 03222 returnStatus = MODIS_F_NOK; 03223 L1BErrorMsg(location, returnStatus, 03224 "Failed to get parameter ReprocessingActual from PCF file.", 03225 "PGS_PC_GetConfigData", REPROCESSING_ACTUAL_LUN, 03226 "Invalid PCF file", True); 03227 return returnStatus; 03228 } 03229 if (strlen(runtime_params->ReprocessingActual) == 0) 03230 { 03231 returnStatus = MODIS_F_NOK; 03232 L1BErrorMsg(location, returnStatus, 03233 "The ReprocessingActual value in the PCF is invalid (no string).", 03234 NULL, REPROCESSING_ACTUAL_LUN, NULL, True); 03235 return returnStatus; 03236 } 03237 03238 /* 03239 * Read the Write_Night_Mode_HiRes_Data value. This value must be 03240 * True (1) or False (0). 03241 */ 03242 returnStatus = PGS_PC_GetConfigData(WRITE_NIGHT_HIRES_LUN, 03243 runtime_params->Write_Night_Mode_HiRes_Data); 03244 if (returnStatus != PGS_S_SUCCESS) 03245 { 03246 returnStatus = MODIS_F_NOK; 03247 L1BErrorMsg(location, returnStatus, 03248 "Failed to get parameter Write_Night_Mode_HiRes_Data " 03249 "from PCF file.", 03250 "PGS_PC_GetConfigData", WRITE_NIGHT_HIRES_LUN, 03251 "Invalid PCF file", True); 03252 return returnStatus; 03253 } 03254 if (!(strcmp(runtime_params->Write_Night_Mode_HiRes_Data, "0") == 0 || 03255 strcmp(runtime_params->Write_Night_Mode_HiRes_Data, "1") == 0)) 03256 { 03257 returnStatus = MODIS_F_NOK; 03258 L1BErrorMsg(location, returnStatus, 03259 "The Write_Night_Mode_HiRes_Data value in the PCF file is " 03260 "invalid (must be 0 (False) or 1 (True)).", 03261 NULL, WRITE_NIGHT_HIRES_LUN, NULL, True); 03262 return returnStatus; 03263 } 03264 03265 /* 03266 * Read the PGE02 Version value from PCF file. 03267 */ 03268 03269 returnStatus = PGS_PC_GetConfigData(PGE02_VERSION_LUN, 03270 runtime_params->PGE02_Version); 03271 03272 if (returnStatus != PGS_S_SUCCESS) 03273 { 03274 returnStatus = MODIS_F_NOK; 03275 L1BErrorMsg(location, returnStatus, 03276 "Failed to get parameter PGE02_Version from PCF file.", 03277 "PGS_PC_GetConfigData", PGE02_VERSION_LUN, 03278 "Invalid PCF file", True); 03279 return returnStatus; 03280 } 03281 if (strlen(runtime_params->PGE02_Version) == 0) 03282 { 03283 returnStatus = MODIS_F_NOK; 03284 L1BErrorMsg(location, returnStatus, 03285 "The PGE02_Version value in the PCF is invalid (no string).", 03286 NULL, PGE02_VERSION_LUN, NULL, True); 03287 return returnStatus; 03288 } 03289 03290 /* 03291 * Check the PGE02 version given in the PCF file against the code macro. 03292 */ 03293 03294 if (strcmp(runtime_params->PGE02_Version, PGE02_VERSION)) 03295 { 03296 returnStatus = MODIS_F_OUT_OF_RANGE; 03297 L1BErrorMsg(location, returnStatus, 03298 "PGE02 version in PCF file does not match that in the code files.", 03299 NULL, 0, 03300 "Code files must have the same PGE02 version as specified in the PCF file.", 03301 True); 03302 return returnStatus; 03303 } 03304 03305 /* 03306 * Read the MCST_LUT_Version value. This is not checked for specific 03307 * values because the values vary with the MCST LUT Version numbers. 03308 */ 03309 03310 returnStatus = PGS_PC_GetConfigData(MCST_LUT_VERSION_LUN, 03311 runtime_params->MCST_LUT_Version); 03312 03313 if (returnStatus != PGS_S_SUCCESS) 03314 { 03315 returnStatus = MODIS_F_NOK; 03316 L1BErrorMsg(location, returnStatus, 03317 "Failed to get parameter MCST_LUT_Version from PCF file.", 03318 "PGS_PC_GetConfigData", MCST_LUT_VERSION_LUN, 03319 "Invalid PCF file", True); 03320 return returnStatus; 03321 } 03322 if (strlen(runtime_params->MCST_LUT_Version) == 0) 03323 { 03324 returnStatus = MODIS_F_NOK; 03325 L1BErrorMsg(location, returnStatus, 03326 "The MCST_LUT_Version value in the PCF is invalid (no string).", 03327 NULL, MCST_LUT_VERSION_LUN, NULL, True); 03328 return returnStatus; 03329 } 03330 03331 /* 03332 * Read the ProcessingCenter value from the Run_Time_Parameters_t 03333 * structure. 03334 */ 03335 03336 returnStatus = PGS_PC_GetConfigData(PROCESSING_CENTER_LUN, 03337 runtime_params->ProcessingCenter); 03338 if (returnStatus != PGS_S_SUCCESS) 03339 { 03340 returnStatus = MODIS_F_NOK; 03341 L1BErrorMsg(location, returnStatus, 03342 "Failed to get parameter ProcessingCenter from PCF file.", 03343 "PGS_PC_GetConfigData", PROCESSING_CENTER_LUN, 03344 "Invalid PCF file", True); 03345 return returnStatus; 03346 } 03347 if (strlen(runtime_params->ProcessingCenter) == 0) 03348 { 03349 returnStatus = MODIS_F_NOK; 03350 L1BErrorMsg(location, returnStatus, 03351 "The ProcessingCenter value in the PCF is invalid (no string).", 03352 NULL, PROCESSING_CENTER_LUN, NULL, True); 03353 return returnStatus; 03354 } 03355 03356 03357 return MODIS_S_OK; 03358 } 03359
1.7.6.1