////////////////////////////////////////////////////////////////////////////////////// // CRUNCEP_1901_2015MISC.H // Header file for input from a fast data archive // Created automatically by FastArchive on Tue Aug 30 14:13:49 2016 // // The following #includes should appear in your source code file: // // #include // #include // #include // #include "/data/cruncep_v7/to_fast_archive_conversion/nc_monthly_files_verJuly1//cruncep_1901_2015misc.h" // // Functionality to retrieve data from the archive is provided by class Cruncep_1901_2015miscArchive. // The following public functions are provided: // // bool open(char* filename) // Attempts to open the specified file as a fast data archive. The format must be // exactly compatible with this version of cruncep_1901_2015misc.h (normally the archive and // header file should have been produced together by the same program using class // CFastArchive). Returns false if the file could not be opened or had format // errors. open() with no argument is equivalent to open("cruncep_1901_2015misc.bin"). // // void close() // Closes the archive (if open). // // bool rewind() // Sets the file pointer to the first record in the archive file. Returns false if // no archive file is currently open. // // bool getnext(Cruncep_1901_2015misc& obj) // Retrieves the next record in the archive file and advances the file pointer to // the next record. Data are written to the member variables of obj. Returns false if // no archive file is currently open or if the file pointer is beyond the last // record. Use rewind() and getnext() to retrieve data sequentially from the archive. // // bool getindex(Cruncep_1901_2015misc& obj) // Searches the archive for a record matching the values specified for the index // items (lon and lat) in obj. If a matching record is found, the data are // written to the member variables of obj. Returns true if the archive was open and // a matching record was found, otherwise false. The search is iterative and fast. // // Sample program: // // Cruncep_1901_2015miscArchive ark; // Cruncep_1901_2015misc data; // bool success,flag; // // // Retrieve all records in sequence and print values of lon and lat: // // success=ark.open("cruncep_1901_2015misc.bin"); // if (success) { // flag=ark.rewind(); // while (flag) { // flag=ark.getnext(data); // if (flag) // printf("Loaded record: lon=%g, lat=%g\n",data.lon,data.lat); // } // } // // // Look for a record with lon=-180, lat=-90: // // data.lon=-180; // data.lat=-90; // success=ark.getindex(data); // if (success) printf("Found it!\n"); // else printf("Not found\n"); // // ark.close(); struct Cruncep_1901_2015misc { // Index part double lon; double lat; // Data part double mdtr[1380]; double mwet[1380]; double mfrs[1380]; double elv[1]; }; const long CRUNCEP_1901_2015MISC_NRECORD=59191; const int CRUNCEP_1901_2015MISC_DATA_LENGTH=6903; const int CRUNCEP_1901_2015MISC_INDEX_LENGTH=7; const int CRUNCEP_1901_2015MISC_HEADERSIZE=650; unsigned char CRUNCEP_1901_2015MISC_HEADER[CRUNCEP_1901_2015MISC_HEADERSIZE-4]={ 0x01,0x02,0x8A,0x00,0x00,0x00,0x07,0x00,0x02,0x04,0x6C,0x6F,0x6E,0x00,0x2D,0x31,0x38,0x30,0x00,0x00, 0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85, 0xBE,0x25,0xD8,0x7F,0x00,0x00,0x31,0x38,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00, 0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x30,0x2E, 0x32,0x35,0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00, 0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x0B,0x04,0x6C,0x61,0x74,0x00,0x2D,0x39,0x30,0x00, 0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00, 0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x39,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01, 0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00, 0x30,0x2E,0x32,0x35,0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00, 0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x0A,0x00,0x00,0x1A,0xF7,0x00,0x04,0x05, 0x6D,0x64,0x74,0x72,0x00,0x30,0x00,0x1A,0xF7,0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00, 0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x31,0x30,0x30, 0x00,0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00, 0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x30,0x2E,0x30,0x30,0x30,0x31,0x00,0x00,0x30,0xC5,0x4E, 0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00, 0x00,0x14,0x00,0x00,0x05,0x64,0x05,0x6D,0x77,0x65,0x74,0x00,0x30,0x00,0x05,0x64,0x30,0x31,0x00,0x00, 0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25, 0xD8,0x7F,0x00,0x00,0x31,0x30,0x30,0x00,0x30,0x31,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00, 0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x30,0x2E,0x31,0x00, 0x30,0x31,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00, 0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x0A,0x00,0x00,0x05,0x64,0x05,0x6D,0x66,0x72,0x73,0x00,0x30, 0x00,0x05,0x64,0x30,0x31,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00, 0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x31,0x30,0x30,0x00,0x30,0x31,0x00,0x00,0x30, 0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8, 0x7F,0x00,0x00,0x30,0x2E,0x31,0x00,0x30,0x31,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C, 0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x0A,0x00,0x00,0x05,0x64, 0x04,0x65,0x6C,0x76,0x00,0x2D,0x31,0x30,0x30,0x00,0x31,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00, 0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x31,0x30,0x30, 0x30,0x30,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00, 0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x30,0x2E,0x30,0x30,0x31,0x00,0x00,0x00,0x30,0xC5,0x4E, 0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00, 0x00,0x18,0x00,0x00,0x00,0x01}; class Cruncep_1901_2015miscArchive { private: FILE* pfile; long recno; long datano; unsigned char pindex[CRUNCEP_1901_2015MISC_INDEX_LENGTH]; unsigned char pdata[CRUNCEP_1901_2015MISC_DATA_LENGTH]; bool iseof; long readbin(int nbyte) { unsigned char buf[4]; long mult[4]={0x1000000,0x10000,0x100,1},val; int i; fread(buf,nbyte,1,pfile); val=0; for (i=0;i>=8-nbit%8; rval+=buf*mult[i]; } } for (i=nbyte-1;i>=0;i--) { if (i>=nb) bits[i]=bits[i-nb]; else bits[i]=0; } nb=nbit%8; for (i=nbyte-1;i>=0;i--) { bits[i]>>=nb; if (i>0) { buf=bits[i-1]; buf<<=8-nb; bits[i]|=buf; } } rval=rval*scalar+offset; return rval; } void bitify(unsigned char buf[4],double fval,double offset,double scalar) { long ival = (long)((fval-offset)/scalar + 0.5); buf[0]=(unsigned char)(ival/0x1000000); ival-=buf[0]*0x1000000; buf[1]=(unsigned char)(ival/0x10000); ival-=buf[1]*0x10000; buf[2]=(unsigned char)(ival/0x100); ival-=buf[2]*0x100; buf[3]=(unsigned char)(ival); } void merge(unsigned char ptarget[3],unsigned char buf[4],int bits) { int nb=bits/8; int i; unsigned char nib; for (i=0;i<3;i++) { if (i<3-nb) ptarget[i]=ptarget[i+nb]; else ptarget[i]=0; } nb=bits%8; for (i=0;i<3;i++) { ptarget[i]<<=nb; if (i<3-1) { nib=ptarget[i+1]>>(8-nb); ptarget[i]|=nib; } } nb=bits/8; if (bits%8) nb++; for (i=1;i<=nb;i++) ptarget[3-i]|=buf[4-i]; } int compare_index(unsigned char* a,unsigned char* b) { int i; for (i=0;i<3;i++) { if (a[i]b[i]) return +1; } return 0; } bool initialise(const char* filename) { int i; unsigned char* pheader; if (pfile) fclose(pfile); pfile=fopen(filename,"rb"); if (!pfile) { printf("Could not open %s for input\n",filename); return false; } pheader=new unsigned char[CRUNCEP_1901_2015MISC_HEADERSIZE-4]; if (!pheader) { printf("Out of memory\n"); fclose(pfile); pfile=NULL; return false; } ::rewind(pfile); fread(pheader,CRUNCEP_1901_2015MISC_HEADERSIZE-4,1,pfile); for (i=0;i=0;i--) obj.elv[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,24,0.001,-100); for (i=1379;i>=0;i--) obj.mfrs[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,10,0.1,0); for (i=1379;i>=0;i--) obj.mwet[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,10,0.1,0); for (i=1379;i>=0;i--) obj.mdtr[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,20,0.0001,0); return true; } bool getindex(Cruncep_1901_2015misc& obj) { if (!CRUNCEP_1901_2015MISC_NRECORD || !pfile) return false; // else unsigned char ptarget[3]={0,0,0}; unsigned char buf[4]; bitify(buf,obj.lon,-180,0.25); merge(ptarget,buf,11); bitify(buf,obj.lat,-90,0.25); merge(ptarget,buf,10); long begin = 0; long end = CRUNCEP_1901_2015MISC_NRECORD; while (begin < end) { long middle = (begin+end)/2; getindex(middle); getdata(); int c = compare_index(pindex, ptarget); if (c < 0) { begin = middle + 1; } else if (c > 0) { end = middle; } else { for (int i=0;i>=0;i--) obj.elv[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,24,0.001,-100); for (int i=1379;i>=0;i--) obj.mfrs[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,10,0.1,0); for (int i=1379;i>=0;i--) obj.mwet[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,10,0.1,0); for (int i=1379;i>=0;i--) obj.mdtr[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,20,0.0001,0); return true; } } return false; } };