/////////////////////////////////////////////////////////////////////////// // NAME: ABI_GranuleData.cpp // FUNCTION: Implementation of the ABI_GranuleData class. // DESCRIPTION: This is the major program of handling ABI granule data. // REFERENCE: none // CALLING SEQUENCE: N/A // INPUTS: none // OUTPUTS: none // DEPENDENCIES: ABI_GranuleData.h // RESTRICTIONS: none // HISTORY: none ////////////////////////////////////////////////////////////////////////// #include #include #include #include "ABI_GranuleData.h" #include "ABI_const.h" #include #include #include #include #include #include "utility.h" #include "ABI_const.h" #include "ABI_ADP.h" /*******************************************/ /***** P U B L I C F U N C T I O N S *****/ /*******************************************/ /////////////////////////////////////////////////////////////////////////// // NAME: ABI_GranuleData::ABI_GranuleData() // FUNCTION: Initial housekeeping // DESCRIPTION: Constructor of class "ABI_GranuleData" // REFERENCE: non // CALLING SEQUENCE: non // INPUTS: non // OUTPUTS: non // DEPENDENCIES: non // RESTRICTIONS: non // HISTORY: non ////////////////////////////////////////////////////////////////////////// ABI_GranuleData::ABI_GranuleData() { int index_dataset; for (index_dataset=0; index_datasetm_bDataFilesNeeded[index] = bDataFileNeeded[index]; if(this->m_bDataFilesNeeded[index] == false) { printf("m_bDataFilesNeeded ='%d'\n", this->m_bDataFilesNeeded[index]); return false; } //continue; printf("search in folder='%s'\n", folder.c_str()); if(getFileName(folder,keywords[index], m_inputFileNames[index]) == 0) return false; //not processing the night mode if (index== 0 && isNightMode(m_inputFileNames[MXD021KM])) return false; printf(" open '%s'\n", m_inputFileNames[index]); m_fileID[index] = SDstart(m_inputFileNames[index], DFACC_READ); } int32 sd_id,ind; //------------------------------------------------------------------------- // select SDS of 1km data: reflectance at band 1,2,3,5,6,7 //------------------------------------------------------------------------- if (m_bDataFilesNeeded[MXD021KM]) { sd_id = m_fileID[MXD021KM]; /* Reflectance data */ for (ind=REFB1; ind<=REFB2; ind++) selectSD(ind, sd_id,"EV_250_Aggr1km_RefSB", 1); for (ind=REFB3; ind<=REFB7; ind++) selectSD(ind, sd_id,"EV_500_Aggr1km_RefSB", 1); for (ind=REFB8; ind<=REFB26; ind++) selectSD(ind, sd_id,"EV_1KM_RefSB", 1); // get the size of 1.0 km RefB1 char sds_name[256]; int32 rank, data_type, count, dimsize[3]; SDgetinfo(m_sdsID[REFB1], sds_name, &rank, dimsize, &data_type, &count); // assign the class data members m_nPixTrack_2KM = dimsize[1]; m_nPixScan_2KM = dimsize[2]; } //------------------------------------------------------------------------- // select SDS of of 1km data: reflectance at deep blue: 411nm, 442nm and 486nm // and at band 26 and // brightness temperature at channels 20, 21, 29, 31, 32. //------------------------------------------------------------------------- if (m_bDataFilesNeeded[MXD021KM]) { // selectSD(REFB26, m_fileID[MXD021KM],"EV_Band26", 1); selectSD(BTB20, m_fileID[MXD021KM],"EV_1KM_Emissive", 1); selectSD(BTB21, m_fileID[MXD021KM],"EV_1KM_Emissive", 1); selectSD(BTB29, m_fileID[MXD021KM],"EV_1KM_Emissive", 1); selectSD(BTB31, m_fileID[MXD021KM],"EV_1KM_Emissive", 1); selectSD(BTB32, m_fileID[MXD021KM],"EV_1KM_Emissive", 1); } //------------------------------------------------------------------------- // Select SDS of L2 MXD03 data: lat/lon/hgt/geometry/landMask //------------------------------------------------------------------------- if (m_bDataFilesNeeded[MXD03]) { char *dataName[] = {"Latitude", "Longitude", "Height", "SolarZenith", "SensorZenith", "SolarAzimuth", "SensorAzimuth", "Land/SeaMask"}; for (int32 id=0; id<8; id++) { selectSD(LATGD + id, m_fileID[MXD03],dataName[id], 1); } } //------------------------------------------------------------------------- // Select SDS of L2 MXD35 data // cloud mask - 6 bytes per 1x1KM "pixel" // need: (byte2-bit3; byte2-bit7; byte3-bit2) //------------------------------------------------------------------------- if (m_bDataFilesNeeded[MXD35]) { selectSD(CLDMS_Bit09, m_fileID[MXD35],"Cloud_Mask", 1); // selectSD(CLDMS_Bit15, m_fileID[MXD35],"Cloud_Mask", 1); // selectSD(CLDMS_Bit16, m_fileID[MXD35],"Cloud_Mask", 1); // selectSD(CLDMS_Bit18, m_fileID[MXD35],"Cloud_Mask", 1); // selectSD(CLDMS_Bit20, m_fileID[MXD35],"Cloud_Mask", 1); // selectSD(CLDMS_Bit27, m_fileID[MXD35],"Cloud_Mask", 1); // selectSD(SICMS, m_fileID[MXD35],"Cloud_Mask", 1); // selectSD(SUNGNT, m_fileID[MXD35],"Cloud_Mask", 1); // selectSD(CLDMSA, m_fileID[MXD35],"Cloud_Mask", 1); // selectSD(CMSQA, m_fileID[MXD35],"Quality_Assurance", 1); } //------------------------------------------------------------------------- // Get the information of L2 MXD07 data: // columnar O3 (Dobson) / Water vapor (cm) concentration //------------------------------------------------------------------------- // if (m_bDataFilesNeeded[MXD07]) { // selectSD(OZONE, m_fileID[MXD07],"Total_Ozone", 5); // selectSD(WATER, m_fileID[MXD07],"Water_Vapor", 5); // } //XXX // for(int i_index=0; i_index<6; i_index++) // for(int j_index=0;j_index<7;j_index++) m_count_REFL[i_index][j_index]=0; return true; } /*************************************************/ /***** P R O T E C T E D F U N C T I O N S *****/ /*************************************************/ /////////////////////////////////////////////////////////////////////////// // NAME: void ABI_GranuleData::readScanDataToBuffer // FUNCTION: Read scan data into memory and covert to the physical values. // DESCRIPTION: This routine allocate memory to hold the input data. // REFERENCE: none // CALLING SEQUENCE: readScanDataToBuffer(scanStart, scanEnd) // INPUTS: // int scanStart - start position of the can line // int scanEnd - end position of the scan line. // OUTPUTS: none // DEPENDENCIES: getMXD021KMData, getMXD021KMBTData, getMXD03Data, // getMXD35Data, getMXD07Data, calRefl // RESTRICTIONS: Memory will be allocated after the 1KM file is read because // we need array size of the file. // HISTORY: none ////////////////////////////////////////////////////////////////////////// void ABI_GranuleData::readScanDataToBuffer(int scanStart, int scanEnd) { this->scanStart= scanStart; this->scanEnd = scanEnd; m_linesInBuffer_2KM = (scanEnd- scanStart+1)* ABI_LINES_PER_SCAN_2KM ; // printf("reading=MXD021KMData\n"); if (m_bDataFilesNeeded[MXD021KM]) getMXD021KMData(); // printf("reading=MXD021KMData\n"); if (m_bDataFilesNeeded[MXD021KM]) getMXD021KMBTData(); // printf("reading=MXD03Data\n"); if (m_bDataFilesNeeded[MXD03]) getMXD03Data(); // printf("reading=MXD35KMData\n"); if (m_bDataFilesNeeded[MXD35]) getMXD35Data(); // if (m_bDataFilesNeeded[MXD07]) getMXD07Data(); calRefl(); } /////////////////////////////////////////////////////////////////////////// // NAME: bool ABI_GranuleData::isNightMode // FUNCTION: Check whether the granule is in night mode // DESCRIPTION: Check whether the granule is in night mode // REFERENCE: none // CALLING SEQUENCE: isNightMode(filename) // INPUTS: char *filename - pointer to the current input file // OUTPUTS: Return: true or false // DEPENDENCIES: none // RESTRICTIONS: none // HISTORY: none ////////////////////////////////////////////////////////////////////////// bool ABI_GranuleData::isNightMode(char *filename) { int32 tcount, ncount, attIndex; int32 sd_id = SDstart(filename, DFACC_READ); attIndex = SDfindattr(sd_id, "Number of Night mode scans"); SDreadattr(sd_id, attIndex, &ncount); attIndex = SDfindattr(sd_id, "Number of Scans"); SDreadattr(sd_id, attIndex, &tcount); SDend(sd_id); if (ncount == tcount) return true; return false; } /////////////////////////////////////////////////////////////////////////// // NAME: void ABI_GranuleData::getMXD021KMData() // FUNCTION: Get the L1B 1KM data // DESCRIPTION: Get the L1B 1KM data // REFERENCE: none // CALLING SEQUENCE:none // INPUTS: none // OUTPUTS: Updated stract data member: // m_modisData - MODIS data struct STRUCT_MODIS_DATA // DEPENDENCIES: none // RESTRICTIONS: none // HISTORY: none ////////////////////////////////////////////////////////////////////////// void ABI_GranuleData::getMXD021KMData() { int32 start[] = {0, scanStart * ABI_LINES_PER_SCAN_2KM, 0}; int32 edge[] = {1, m_linesInBuffer_2KM, m_nPixScan_2KM }; int32 size = edge[0] * edge[1] * edge[2]; float32 scaFac[15], offset[15]; uint16 valid_range[2]; float32 corrected_counts_scales[15]; uint16 fillValue_ui16; uint8 fillValue_ui8,validRange_ui8[2]; int32 ind,ind2; /* Reflectance data */ // Convert to the reflectance // float32 **pMdata= (float32 **)&m_ABIData; float32 * data_pointers[] ={m_ABIData.pREFB1,m_ABIData.pREFB2,m_ABIData.pREFB3, m_ABIData.pREFB5,m_ABIData.pREFB6,m_ABIData.pREFB7,m_ABIData.pREFB8, m_ABIData.pREFB9,m_ABIData.pREFB10,m_ABIData.pREFB26}; for (ind=REFB1; ind<=REFB26; ind++) { ind2=ind; int iPosition=ind-REFB1; if (ind2 ==2) iPosition=ind-REFB3; if (ind2 >2) iPosition=ind-REFB3+1; if (ind2 >=6) iPosition=ind-REFB8; if (ind2==9) iPosition=14; // printf("ind=%i\n",ind2); // float32* data = pMdata[ind2]; float32* data = data_pointers[ind2]; // printf("data=%i\n",*(data+0)); start[0]=iPosition; unsigned short* hdfData = (unsigned short *) data; int32 sds_id= m_sdsID[ind]; int ret=SDreaddata(sds_id, start, NULL, edge, hdfData); // printf("data=%i\n",*(hdfData+0)); // get info/attributes SDreadattr(sds_id, SDfindattr(sds_id, "reflectance_scales"), scaFac); SDreadattr(sds_id, SDfindattr(sds_id, "reflectance_offsets"), offset); SDreadattr(sds_id, SDfindattr(sds_id, "_FillValue"), &fillValue_ui16); SDreadattr(sds_id, SDfindattr(sds_id, "valid_range"), &valid_range); SDreadattr(sds_id, SDfindattr(sds_id, "corrected_counts_scales"), &corrected_counts_scales); float32 Scal= scaFac[iPosition]; float32 BSet= offset[iPosition]; float32 corrected_counts_scale= corrected_counts_scales[iPosition]; uint16 zmin = valid_range[0]; uint16 zmax = valid_range[1]; for (int32 j_index=size-1; j_index>=0; j_index--) { uint16 RRefl= *(hdfData +j_index); *(data + j_index) = (RRefl >= zmin && RRefl <= zmax) ? Scal * (RRefl - BSet) : MISVAL ; } int32 Nvalid=0; for(int i_index=0; i_index0) Nvalid++; } } } /////////////////////////////////////////////////////////////////////////// // NAME: void ABI_GranuleData::getMXD021KMBTData() // FUNCTION: Get the L1B 1KM data // DESCRIPTION: Get the L1B 1KM data (Reflectance at 1.38um, 4.11um, 4.42um and 4.86um // and 3.75,3.96,8.55, 11.0, and 12.0um brightness temperature) // REFERENCE: none // CALLING SEQUENCE: none // INPUTS: none // OUTPUTS: Updated stract data member: // m_modisData - MODIS data struct STRUCT_MODIS_DATA // DEPENDENCIES: none // RESTRICTIONS: none // HISTORY: none ////////////////////////////////////////////////////////////////////////// void ABI_GranuleData::getMXD021KMBTData() { float32 scaFac[15], offset[15]; //Brightness Temperature at band 20,21,29,31,32 int position_at_InputSDS[]={0,1,8,10,11}; double wave_lengths[]={3.78533e-6, 3.99157e-6, 8.52377e-6,11.0121e-6, 12.0259e-6}; double tcs[ ]={9.993411E-01, 9.998646E-01,9.995495E-01,9.995608E-01, 9.997256E-01}; double tci[ ]={4.770532E-01, 9.262664E-02,1.599191E-01,1.302699E-01, 7.181833E-02}; float32 * data_pointers[] ={ m_ABIData.pBTB20,m_ABIData.pBTB21, m_ABIData.pBTB29,m_ABIData.pBTB31,m_ABIData.pBTB32}; for (int iBand=0; iBand<5; iBand++){ float32* data = data_pointers[iBand]; int32 sds_id = m_sdsID[BTB20 + iBand]; int32 bind = position_at_InputSDS[iBand]; int32 start[] = {bind,scanStart * (ABI_LINES_PER_SCAN_2KM), 0}; int32 edge[] = {1,(m_linesInBuffer_2KM), (m_nPixScan_2KM)}; // Convert radiance to the brightness temperature int32 size= edge[1] * edge[2]; uint16* hdfData = (uint16 *) data; SDreaddata(sds_id, start, NULL, edge, hdfData); float64 radiance; float64 wavlen = wave_lengths[iBand]; float64 c1 = 2.0*PLANCK_CONSTANT*(SPEED_LIGHT*SPEED_LIGHT); float64 c2 = (PLANCK_CONSTANT*SPEED_LIGHT)/BOLTZ_CONS; double cc2= c1/(1.0e+6 * pow(wavlen, 5)); double cc1= c2/wavlen; double ti = tci[iBand]; double ts = tcs[iBand]; uint16 fillValue_ui16; SDreadattr(sds_id, SDfindattr(sds_id, "_FillValue"), &fillValue_ui16); SDreadattr(sds_id, SDfindattr(sds_id, "radiance_scales"), scaFac); SDreadattr(sds_id, SDfindattr(sds_id, "radiance_offsets"), offset); uint16 valid_range[2]; SDreadattr(sds_id, SDfindattr(sds_id, "valid_range"), &valid_range); uint16 zmin = valid_range[0]; uint16 zmax = valid_range[1]; float32 Scal= scaFac[bind]; float32 BSet= offset[bind]; for (int32 j_index=size-1; j_index>=0; j_index--) { uint16 RRefl= *(hdfData +j_index); if (RRefl >= zmin && RRefl <= zmax) { radiance = Scal * (RRefl - BSet); *(data + j_index) = cc1 /log(cc2 /radiance +1.0) ; // *(data + j_index) = (cc1 /log(cc2 /radiance +1.0)-ti)/ts ; // printf("bt=%f\n",*(data + j_index)); }else *(data + j_index) = MISVAL; } } } /////////////////////////////////////////////////////////////////////////// // NAME: void ABI_GranuleData::getMXD03Data() // FUNCTION: Get the L1B M?D03 data // DESCRIPTION: Get the L1 M?D03 data (lat/lon/hgt/sza/vza/sazi/vazi/landMask) // REFERENCE: none // CALLING SEQUENCE: none // INPUTS: none // OUTPUTS: Updated stract data member: // m_modisData - MODIS data struct STRUCT_MODIS_DATA // DEPENDENCIES: none // RESTRICTIONS: none // HISTORY: none /////////////////////////////////////////////////////////////////////////// void ABI_GranuleData::getMXD03Data() { int32 start[] = {scanStart * (ABI_LINES_PER_SCAN_2KM), 0}; int32 edge[] = {(m_linesInBuffer_2KM), (m_nPixScan_2KM)}; int32 size = edge[0] * edge[1]; int32 ind; /* lat/lon */ SDreaddata(m_sdsID[LATGD], start, NULL, edge, m_ABIData.pLATGD); SDreaddata(m_sdsID[LONGD], start, NULL, edge, m_ABIData.pLONGD); /* hgt */ SDreaddata(m_sdsID[HEGHT], start, NULL, edge, m_ABIData.pHEGHT); /* sza/vza/sazi/vazi angles */ float32 **pMdata= (float32 **)&m_ABIData; for (ind=SOLZA; ind<=SENAZ; ind++) { float32* data = pMdata[ind]; int32 sds_id = m_sdsID[ind]; float64 scaFac; int16 fillValue_i16; SDreadattr(sds_id, SDfindattr(sds_id, "scale_factor"), &scaFac); SDreadattr(sds_id, SDfindattr(sds_id, "_FillValue"), &fillValue_i16); int16 valid_range[2]; SDreadattr(sds_id, SDfindattr(sds_id, "valid_range"), &valid_range); int16 zmin = valid_range[0]; int16 zmax = valid_range[1]; int16* hdfData = (int16 *) data; SDreaddata(sds_id, start, NULL, edge, hdfData); float32 Scal= float(scaFac); for (int32 j_index=size-1; j_index>=0; j_index--) { int16 RRefl= *(hdfData +j_index); *(data + j_index) = (RRefl >= zmin && RRefl <= zmax) ? (Scal * RRefl) : MISVAL ; } } /* land/seaMask DN values: 0: Shallow Ocean (Ocean <5k from coast OR <50m deep). 1: Land (not anything else). 2: Ocean Coastlines and Lake Shorelines. 3: Shallow Inland Water (Inland Water < 5km from shore OR < 50m deep). 4: Ephemeral (intermittent) Water. 5: Deep Inland Water (Inland water > 5km from shoreline AND > 50m deep). 6: Moderate or Continental Ocean (Ocean > 5km from coast AND > 50m deep AND < 500m deep). 7: Deep Ocean (Ocean > 500m deep). */ { SDreaddata(m_sdsID[LSMSK], start, NULL, edge, m_ABIData.pLSMSK); } } /////////////////////////////////////////////////////////////////////////// // NAME: void ABI_GranuleData::getMXD35Data() // FUNCTION: Get the L2 M?D35 data // DESCRIPTION: Get the L2 M?D35 data (Cloud Mask) // Retrieve 6 bits [byte2-bit1( 9:B2b1); byte2-bit7(15:B2b7); // byte3-bit2(18:B3b2); byte3-bit0(16:B3b0); // byte3-bit3(19:B3b3); // byte3-bit4(20:B3b4); byte4-bit3(27:B4b3)] // and snow/ice mask (SICMS), Sunglint mask (SUNGNT) // byte0-bit5(SICMS:B0b5); byte0-bit3(SUNGNT:B0b3); // REFERENCE: none // CALLING SEQUENCE: none // INPUTS: none // OUTPUTS: Updated stract data member: // MOD35ASD - cloud mask struct STRUCT_CM which is included in // the struct STRUCT_MODIS_DATA // DEPENDENCIES: none // RESTRICTIONS: none // HISTORY: none /////////////////////////////////////////////////////////////////////////// void ABI_GranuleData::getMXD35Data() { int32 start[] = {0,scanStart * (ABI_LINES_PER_SCAN_2KM), 0}; int32 edge[] = {6,(m_linesInBuffer_2KM), (m_nPixScan_2KM)}; int32 size = edge[1] * edge[2]; int32 sds_id; int32 ind; int32 j_index; /* 6 bytes cloud masks */ int8* hdfData = (int8 *) malloc(size*6); sds_id = m_sdsID[CLDMS_Bit09]; SDreaddata(sds_id, start, NULL, edge, hdfData); int8 byte; bool det; /* Snow/ice mask and sunglint*/ uint8* data1 = (uint8*) m_ABIData.pSICMS; uint8* data2 = (uint8*) m_ABIData.pSUNGNT; uint8* data3 = (uint8*) m_ABIData.pCLDMS_Bit09; uint8* data4 = (uint8*) m_ABIData.pCLDMS_Bit15; uint8* data5 = (uint8*) m_ABIData.pCLDMS_Bit16; uint8* data6 = (uint8*) m_ABIData.pCLDMS_Bit18; uint8* data7 = (uint8*) m_ABIData.pCLDMS_Bit19; uint8* data8 = (uint8*) m_ABIData.pCLDMS_Bit20; uint8* data9 = (uint8*) m_ABIData.pCLDMS_Bit27; memset(data1, 0, size * sizeof(uint8)); memset(data2, 0, size * sizeof(uint8)); memset(data3, 0, size * sizeof(uint8)); memset(data4, 0, size * sizeof(uint8)); memset(data5, 0, size * sizeof(uint8)); memset(data6, 0, size * sizeof(uint8)); memset(data7, 0, size * sizeof(uint8)); memset(data8, 0, size * sizeof(uint8)); memset(data9, 0, size * sizeof(uint8)); for (j_index=0; j_index>7) & 0x01; // bit 5 *(data1 + j_index) = ( 1 - Temp_Flag); Temp_Flag = ((byte<<3)>>7) & 0x01; // bit 4 *(data2 + j_index) = ( 1 - Temp_Flag); // Byte 2 byte = *(hdfData + j_index + size); //from bit 1 shift to bit 0 Temp_Flag = (((byte<<6)>>7) & 0x01); *(data3 + j_index) = ( 1- Temp_Flag); // bit09 in MOXD35 //from bit 7 shift to bit 0 Temp_Flag = ((byte>>7) & 0x01); *(data4 + j_index) = ( 1- Temp_Flag); // bit15 in MOXD35 // Byte 3 byte = *(hdfData + j_index + size * 2); //from bit 0 shift to bit 0 Temp_Flag = (((byte<<7)>>7) & 0x01); *(data5 + j_index) = ( 1 - Temp_Flag); // bit16 in MOXD35 //from bit 2 shift to bit 0 Temp_Flag = (((byte<<5)>>7) & 0x01); *(data6 + j_index) = ( 1 - Temp_Flag); // bit18 in MOXD35 //from bit 3 shift to bit 0 Temp_Flag = (((byte<<4)>>7) & 0x01); *(data7 + j_index) = ( 1 - Temp_Flag); // bit19 in MOXD35 //from bit 4 shift to bit 0 Temp_Flag = (((byte<<3)>>7) & 0x01); *(data8 + j_index) = ( 1 - Temp_Flag); // bit20 in MOXD35 //Byte 4 byte = *(hdfData + j_index + size*3); //from bit 2 shift to bit 0 Temp_Flag = (((byte<<3)>>7) & 0x01); *(data9 + j_index) = ( 1 - Temp_Flag); // bit27 in MOXD35 } free(hdfData); } /////////////////////////////////////////////////////////////////////////// // NAME: void ABI_GranuleData::calRefl() // FUNCTION: Calculate the reflectance // DESCRIPTION: Calculate the reflectance - dividing cosine solar zenith // angle from read-in data. // REFERENCE: none // CALLING SEQUENCE: none // INPUTS: none // OUTPUTS: none // DEPENDENCIES: none // RESTRICTIONS: none // HISTORY: none /////////////////////////////////////////////////////////////////////////// void ABI_GranuleData::calRefl() { float64 SolZen, xcossa; float32 *Tmpy; int32 index1KM; int32 size1KM = (m_linesInBuffer_2KM) * (m_nPixScan_2KM) ; int32 nPixScan_2KM = m_nPixScan_2KM; float32 **pMdata= (float32 **)&m_ABIData; for (int32 i_index=0; i_index 0.) xcossa = 1./ cos(SolZen * DEG2RAD); int32 row1KM= (i_index / nPixScan_2KM); int32 col1KM= (i_index % nPixScan_2KM); int32 index1KM0= row1KM * m_nPixScan_2KM + col1KM ; index1KM = index1KM0; for (int32 iband=REFB1; iband<=REFB26; iband++) { Tmpy = pMdata[iband] + index1KM; //XXX //if( *Tmpy >0 && *Tmpy <1 ) m_count_REFL[0][iband]++; if ((*Tmpy > 0.) && (xcossa > 0.)) *Tmpy = float(*Tmpy * xcossa); else *Tmpy = MISVAL; //XXX //if( *Tmpy >0 && *Tmpy <1 ) m_count_REFL[1][iband]++; } } } /////////////////////////////////////////////////////////////////////////// // NAME: void ABI_GranuleData::closeInputFiles() // FUNCTION: Close the input data files. // DESCRIPTION: Close the input MODIS data files. // REFERENCE: none // CALLING SEQUENCE: none // INPUTS: none // OUTPUTS: none // DEPENDENCIES: none // RESTRICTIONS: none // HISTORY: none /////////////////////////////////////////////////////////////////////////// void ABI_GranuleData::closeInputFiles() { int i_index; for ( i_index=0; i_index 0 && (m_sdsID[i_index] == m_sdsID[i_index-1])) continue; SDendaccess(m_sdsID[i_index]); } for ( i_index=0; i_index 0 ) { cout<