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