int main(int argc,char* argv[]) { grib_index* index=NULL; grib_handle* h=NULL; char* infile=NULL; int i,j,k,l; long ostep,olevel,onumber; char oshortName[200]; size_t lenshortName=200; int ret=0,count=0; if (argc != 2) usage(argv[0]); infile=argv[1]; outfile=argv[2]; printf("indexing...\n"); /* Create an index from a grib file with a given set of keys*/ index=grib_index_new_from_file(0,infile,"shortName,level,number,step",&ret); if (ret) {printf("error: %s\n",grib_get_error_message(ret)); exit(ret);} printf("end indexing...\n"); /* ask the index to order the fields thorough some keys*/ ret=grib_index_orderby(index,"level,shortName,number:desc,step:asc"); if (ret!=GRIB_SUCCESS) exit(1); count=0; /* loop through all the fields in the asked order*/ while ((h=grib_handle_new_from_index(index,&ret))!=NULL){ count++; if (ret) {printf("error: %d\n",ret); exit(ret);} lenshortName=200; grib_get_string(h,"shortName",oshortName,&lenshortName); grib_get_long(h,"level",&olevel); grib_get_long(h,"number",&onumber); grib_get_long(h,"step",&ostep); printf("shortName=%s ",oshortName); printf("level=%ld ",olevel); printf("number=%ld ",onumber); printf("step=%ld \n",ostep); grib_handle_delete(h); } if (ret!=GRIB_END_OF_INDEX) { printf("error: %s\n",grib_get_error_message(ret)); exit(ret); } printf(" %d messages selected\n",count); return 0; }
grib_handle* codes_handle_new_from_index(grib_index* index,int *err) { return grib_handle_new_from_index(index,err); }
float InputGrib::getValueCore(const Key::Input& iKey) const { #ifdef WITH_GRIB // Check that date hasn't been checked before std::map<int,std::map<float, bool> >::const_iterator it0 = mMissingFiles.find(iKey.date); if(it0 != mMissingFiles.end()) { // Date has missing files std::map<float, bool>::const_iterator it1 = it0->second.find(iKey.offset); if(it1 != it0->second.end()) { writeMissingToCache(iKey); return Global::MV; } } std::string localVariable; bool found = getLocalVariableName(iKey.variable, localVariable); assert(found); int numLocations = Input::getNumLocations(); std::string filename = getFilename(iKey); std::stringstream ss; ss << "InputGrib: Loading " << filename << " " << iKey.date << " " << iKey.offset << " " << iKey.location << " " << localVariable; Global::logger->write(ss.str(), Logger::message); bool foundVariable = false; FILE* fid = fopen(filename.c_str(),"r"); float value = Global::MV; if(fid) { // GRIB File found int err = 0; grib_handle* h = NULL; // double s = Global::clock(); // Try to use an index to read file as this is much faster. Fall back on just reading the // GRIB file. grib_index* gribIndex = getIndex(iKey, localVariable); bool validIndex = (gribIndex != NULL); if(!validIndex) { std::stringstream ss; ss << "InputGrib: No index file available for " << filename; Global::logger->write(ss.str(), Logger::message); } int counter = 1; // Loop over available variables (in index or in file) while(1) { // Read message from file or index if(!validIndex) { h = grib_handle_new_from_file(0,fid,&err); } else { h = grib_handle_new_from_index(gribIndex,&err); } if(h == NULL) break; // No more messages to process std::string currVariable = getVariableName(h); std::stringstream ss; ss << "InputGrib: Reading message #" << counter << ": " << currVariable; Global::logger->write(ss.str(), Logger::message); // Check if the current variable is defined in the variable list int variableId; found = getVariableIdFromLocalVariable(currVariable, variableId); if(!found) { std::stringstream ss; ss << "InputGrib: Found variable " << currVariable << " in " << filename << " but this is not mapped to any variable in namelist" << std::endl; Global::logger->write(ss.str(), Logger::message); } else { // Only read the current variable if necessary if(mCacheOtherVariables || currVariable == localVariable) { std::vector<float> currValues; currValues.resize(numLocations, Global::MV); int numValid = 0; // Check that the message has the right number of locations size_t N; GRIB_CHECK(grib_get_size(h,"values",&N),0); if(N == numLocations) { foundVariable = foundVariable || (currVariable == localVariable); double* arr = new double[N]; GRIB_CHECK(grib_get_double_array(h,"values",arr,&N),0); currValues.assign(arr, arr + numLocations); for(int i = 0; i < (int) currValues.size(); i++) { if(currValues[i] == mMV) currValues[i] = Global::MV; else numValid++; } std::stringstream ss; ss << "InputGrib: Number of valid values: " << numValid; Global::logger->write(ss.str(), Logger::message); delete arr; } else { std::stringstream ss; ss << "GribInput: Discarding variable " << currVariable << " in " << filename << " because it has incorrect number of locations"; Global::logger->write(ss.str(), Logger::debug); } Key::Input key = iKey; key.offset = getOffset(h); // Cache values for(int i = 0; i < numLocations; i++) { key.location = i; key.variable = variableId; if(key.location == iKey.location && currVariable == localVariable) { // Found the value value = currValues[i]; } if(mCacheOtherLocations || key.location == iKey.location) { //if(currVariable == localVariable) // std::cout << currValues[i] << std::endl; Input::addToCache(key, currValues[i]); } } } } if(h) { grib_handle_delete(h); } // Quit reading file if we have found the variable we need if(!mCacheOtherVariables && (currVariable == localVariable)) { break; } counter++; } if(!foundVariable) { // File was there, but couldn't find variable std::stringstream ss; ss << "InputGrib: Could not find variable " << localVariable << " in " << filename; Global::logger->write(ss.str(), Logger::warning); writeMissingToCache(iKey); } if(validIndex) { grib_index_delete(gribIndex); } // double e = Global::clock(); //std::cout << "Grib read time: " << e - s << " seconds" << std::endl; fclose(fid); return value; } else { // GRIB file not found std::stringstream ss; ss << "GribInput: File not found: " << filename; Global::logger->write(ss.str(), Logger::message); std::vector<float> currValues; currValues.resize(numLocations, Global::MV); for(int i = 0; i < numLocations; i++) { Key::Input key = iKey; key.location = i; if(mCacheOtherLocations || key.location == iKey.location) Input::addToCache(key, currValues[i]); } return Global::MV; } #else return Global::MV; #endif }
int main(int argc,char* argv[]) { grib_index* index=NULL; grib_handle* h=NULL; long *step,*level,*number; char** shortName=NULL; int i,j,k,l; size_t stepSize,levelSize,shortNameSize,numberSize; long ostep,olevel,onumber; char oshortName[200]; size_t lenshortName=200; int ret=0,count=0; if (argc != 2) usage(argv[0]); printf("indexing...\n"); index=grib_index_read(0,"out.gribidx",&ret); GRIB_CHECK(ret,0); printf("end indexing...\n"); /* get the number of distinct values of "step" in the index */ GRIB_CHECK(grib_index_get_size(index,"step",&stepSize),0); step=(long*)malloc(sizeof(long)*stepSize); if (!step) exit(1); /* get the list of distinct steps from the index */ /* the list is in ascending order */ GRIB_CHECK(grib_index_get_long(index,"step",step,&stepSize),0); printf("stepSize=%ld\n",(long)stepSize); for (i=0;i<stepSize;i++) printf("%ld ",step[i]); printf("\n"); /*same as for "step"*/ GRIB_CHECK(grib_index_get_size(index,"level",&levelSize),0); level=(long*)malloc(sizeof(long)*levelSize); if (!level) exit(1); /*same as for "step"*/ GRIB_CHECK(grib_index_get_long(index,"level",level,&levelSize),0); printf("levelSize=%ld\n",(long)levelSize); for (i=0;i<levelSize;i++) printf("%ld ",level[i]); printf("\n"); /*same as for "step"*/ GRIB_CHECK(grib_index_get_size(index,"number",&numberSize),0); number=(long*)malloc(sizeof(long)*numberSize); if (!number) exit(1); /*same as for "step"*/ GRIB_CHECK(grib_index_get_long(index,"number",number,&numberSize),0); printf("numberSize=%ld\n",(long)numberSize); for (i=0;i<numberSize;i++) printf("%ld ",number[i]); printf("\n"); /*same as for "step"*/ GRIB_CHECK(grib_index_get_size(index,"shortName",&shortNameSize),0); shortName=(char**)malloc(sizeof(char*)*shortNameSize); if (!shortName) exit(1); /*same as for "step"*/ GRIB_CHECK(grib_index_get_string(index,"shortName",shortName,&shortNameSize),0); printf("shortNameSize=%ld\n",(long)shortNameSize); for (i=0;i<shortNameSize;i++) printf("%s ",shortName[i]); printf("\n"); count=0; /* nested loops on the keys values of the index */ /* different order of the nested loops doesn't affect performance*/ for (i=0;i<shortNameSize;i++) { /* select the grib with shortName=shortName[i] */ grib_index_select_string(index,"shortName",shortName[i]); for (l=0;l<levelSize;l++) { /* select the grib with level=level[i] */ grib_index_select_long(index,"level",level[l]); for (j=0;j<numberSize;j++) { /* select the grib with number=number[i] */ grib_index_select_long(index,"number",number[j]); for (k=0;k<stepSize;k++) { /* select the grib with step=step[i] */ grib_index_select_long(index,"step",step[k]); /* create a new grib_handle from the index with the constraints imposed by the select statements. It is a loop because in the index there could be more than one grib with those constrants */ while ((h=grib_handle_new_from_index(index,&ret))!=NULL){ count++; if (ret) {printf("error: %d\n",ret); exit(ret);} lenshortName=200; grib_get_string(h,"shortName",oshortName,&lenshortName); grib_get_long(h,"level",&olevel); grib_get_long(h,"number",&onumber); grib_get_long(h,"step",&ostep); printf("shortName=%s ",oshortName); printf("level=%ld ",olevel); printf("number=%ld ",onumber); printf("step=%ld \n",ostep); grib_handle_delete(h); } if (ret!=GRIB_END_OF_INDEX) {printf("error: %s\n",grib_get_error_message(ret)); exit(ret);} } } } } printf(" %d messages selected\n",count); return 0; }