123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- //////////////////////////////////////////////////////////////////////////////////////
- // CRUNCEP_1901_2015.H
- // Header file for input from a fast data archive
- // Created automatically by FastArchive on Mon Sep 12 18:08:07 2016
- //
- // The following #includes should appear in your source code file:
- //
- // #include <stdio.h>
- // #include <stdlib.h>
- // #include <string.h>
- // #include "/data/cruncep_v7/to_fast_archive_conversion/nc_monthly_files_verJuly1//cruncep_1901_2015.h"
- //
- // Functionality to retrieve data from the archive is provided by class Cruncep_1901_2015Archive.
- // 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_2015.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_2015.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_2015& 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_2015& 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_2015Archive ark;
- // Cruncep_1901_2015 data;
- // bool success,flag;
- //
- // // Retrieve all records in sequence and print values of lon and lat:
- //
- // success=ark.open("cruncep_1901_2015.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_2015 {
- // Index part
- double lon;
- double lat;
- // Data part
- double mtemp[1380];
- double mprec[1380];
- double mswrad[1380];
- double soilcode[1];
- };
- const long CRUNCEP_1901_2015_NRECORD=59191;
- const int CRUNCEP_1901_2015_DATA_LENGTH=12422;
- const int CRUNCEP_1901_2015_INDEX_LENGTH=7;
- const int CRUNCEP_1901_2015_HEADERSIZE=659;
- unsigned char CRUNCEP_1901_2015_HEADER[CRUNCEP_1901_2015_HEADERSIZE-4]={
- 0x01,0x02,0x93,0x00,0x00,0x00,0x07,0x00,0x02,0x04,0x6C,0x6F,0x6E,0x00,0x2D,0x31,0x38,0x30,0x00,0x00,
- 0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x15,0x95,
- 0xD3,0x9D,0x42,0x7F,0x00,0x00,0x31,0x38,0x30,0x00,0x00,0x00,0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,
- 0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x15,0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,0x30,0x2E,
- 0x32,0x35,0x00,0x00,0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,
- 0x00,0x00,0x15,0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,0x0B,0x04,0x6C,0x61,0x74,0x00,0x2D,0x39,0x30,0x00,
- 0x00,0x00,0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,0x00,0x00,
- 0x15,0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,0x39,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0xB5,0xBF,0x01,
- 0x00,0x00,0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x15,0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,
- 0x30,0x2E,0x32,0x35,0x00,0x00,0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,0x00,0x00,0xD2,0x00,0x41,0x00,
- 0x00,0x00,0x00,0x00,0x15,0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,0x0A,0x00,0x00,0x30,0x86,0x00,0x04,0x06,
- 0x6D,0x74,0x65,0x6D,0x70,0x00,0x2D,0x31,0x30,0x30,0x00,0x00,0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,
- 0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x15,0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,0x31,0x30,
- 0x30,0x00,0x00,0x00,0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,
- 0x00,0x00,0x15,0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,0x30,0x2E,0x30,0x30,0x31,0x00,0x00,0x00,0xA0,0xB5,
- 0xBF,0x01,0x00,0x00,0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x15,0x95,0xD3,0x9D,0x42,0x7F,
- 0x00,0x00,0x12,0x00,0x00,0x05,0x64,0x06,0x6D,0x70,0x72,0x65,0x63,0x00,0x30,0x00,0x05,0x64,0x31,0x00,
- 0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x15,0x95,
- 0xD3,0x9D,0x42,0x7F,0x00,0x00,0x31,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,
- 0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x15,0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,0x30,0x2E,
- 0x30,0x30,0x30,0x31,0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,
- 0x00,0x00,0x15,0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,0x1B,0x00,0x00,0x05,0x64,0x07,0x6D,0x73,0x77,0x72,
- 0x61,0x64,0x00,0x30,0x00,0x05,0x64,0x30,0x31,0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,0x00,0x00,0xD2,
- 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x15,0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,0x31,0x30,0x30,0x30,0x30,
- 0x30,0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x15,
- 0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,0x30,0x2E,0x30,0x30,0x31,0x00,0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,
- 0x00,0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x15,0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,0x1B,
- 0x00,0x00,0x05,0x64,0x09,0x73,0x6F,0x69,0x6C,0x63,0x6F,0x64,0x65,0x00,0x30,0x00,0x05,0x64,0x31,0x00,
- 0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x15,0x95,
- 0xD3,0x9D,0x42,0x7F,0x00,0x00,0x35,0x30,0x00,0x64,0x31,0x00,0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,
- 0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x15,0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,0x30,0x2E,
- 0x31,0x00,0x31,0x00,0x00,0x00,0xA0,0xB5,0xBF,0x01,0x00,0x00,0x00,0x00,0xD2,0x00,0x41,0x00,0x00,0x00,
- 0x00,0x00,0x15,0x95,0xD3,0x9D,0x42,0x7F,0x00,0x00,0x09,0x00,0x00,0x00,0x01};
- class Cruncep_1901_2015Archive {
- private:
- FILE* pfile;
- long recno;
- long datano;
- unsigned char pindex[CRUNCEP_1901_2015_INDEX_LENGTH];
- unsigned char pdata[CRUNCEP_1901_2015_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<nbyte;i++) {
- val+=buf[i]*mult[4-nbyte+i];
- }
- return val;
- }
- void getindex(long n) {
- fseek(pfile,CRUNCEP_1901_2015_INDEX_LENGTH*(n-recno),SEEK_CUR);
- fread(pindex,CRUNCEP_1901_2015_INDEX_LENGTH,1,pfile);
- datano=pindex[CRUNCEP_1901_2015_INDEX_LENGTH-4]*0x1000000+pindex[CRUNCEP_1901_2015_INDEX_LENGTH-3]*0x10000+
- pindex[CRUNCEP_1901_2015_INDEX_LENGTH-2]*0x100+pindex[CRUNCEP_1901_2015_INDEX_LENGTH-1];
- recno=n+1;
- iseof=(recno==CRUNCEP_1901_2015_NRECORD);
- }
- void getdata() {
- fseek(pfile,CRUNCEP_1901_2015_INDEX_LENGTH*-recno+(datano-CRUNCEP_1901_2015_NRECORD)*CRUNCEP_1901_2015_DATA_LENGTH,SEEK_CUR);
- fread(pdata,CRUNCEP_1901_2015_DATA_LENGTH,1,pfile);
- fseek(pfile,CRUNCEP_1901_2015_DATA_LENGTH*(CRUNCEP_1901_2015_NRECORD-datano-1)+CRUNCEP_1901_2015_INDEX_LENGTH*recno,SEEK_CUR);
- }
- double popreal(unsigned char* bits,int nbyte,int nbit,double scalar,double offset) {
- unsigned char buf;
- int nb=nbit/8,i;
- double rval=0.0;
- long mult[4]={1,0x100,0x10000,0x1000000};
- for (i=0;i<4;i++) {
- if (i<nb) rval+=bits[nbyte-i-1]*mult[i];
- else if (i==nb) {
- buf=bits[nbyte-i-1]<<(8-nbit%8);
- buf>>=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;
- else 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_2015_HEADERSIZE-4];
- if (!pheader) {
- printf("Out of memory\n");
- fclose(pfile);
- pfile=NULL;
- return false;
- }
- ::rewind(pfile);
- fread(pheader,CRUNCEP_1901_2015_HEADERSIZE-4,1,pfile);
- for (i=0;i<CRUNCEP_1901_2015_HEADERSIZE-4;i++) {
- if (pheader[i]!=CRUNCEP_1901_2015_HEADER[i]) {
- printf("Format of %s incompatible with this version of cruncep_1901_2015.h\n",filename);
- fclose(pfile);
- pfile=NULL;
- delete pheader;
- return false;
- }
- }
- delete[] pheader;
- ::rewind(pfile);
- fseek(pfile,CRUNCEP_1901_2015_HEADERSIZE+CRUNCEP_1901_2015_DATA_LENGTH*CRUNCEP_1901_2015_NRECORD,SEEK_CUR);
- recno=0;
- iseof=false;
- return true;
- }
- public:
- Cruncep_1901_2015Archive() {
- pfile=NULL;
- }
- ~Cruncep_1901_2015Archive() {
- if (pfile) fclose(pfile);
- }
- bool open(const char* filename) {
- return initialise(filename);
- }
- bool open() {
- return open("cruncep_1901_2015.bin");
- }
- void close() {
- if (pfile) {
- fclose(pfile);
- pfile=NULL;
- }
- }
- bool rewind() {
- if (!pfile) return false;
- ::rewind(pfile);
- fseek(pfile,CRUNCEP_1901_2015_HEADERSIZE+CRUNCEP_1901_2015_DATA_LENGTH*CRUNCEP_1901_2015_NRECORD,SEEK_CUR);
- recno=0;
- iseof=false;
- return true;
- }
- bool getnext(Cruncep_1901_2015& obj) {
- if (!pfile || iseof) return false;
- int i;
- getindex(recno);
- getdata();
- obj.lat=popreal(pindex,3,10,0.25,-90);
- obj.lon=popreal(pindex,3,11,0.25,-180);
- for (i=0;i>=0;i--) obj.soilcode[i]=popreal(pdata,CRUNCEP_1901_2015_DATA_LENGTH,9,0.1,0);
- for (i=1379;i>=0;i--) obj.mswrad[i]=popreal(pdata,CRUNCEP_1901_2015_DATA_LENGTH,27,0.001,0);
- for (i=1379;i>=0;i--) obj.mprec[i]=popreal(pdata,CRUNCEP_1901_2015_DATA_LENGTH,27,0.0001,0);
- for (i=1379;i>=0;i--) obj.mtemp[i]=popreal(pdata,CRUNCEP_1901_2015_DATA_LENGTH,18,0.001,-100);
- return true;
- }
- bool getindex(Cruncep_1901_2015& obj) {
- if (!CRUNCEP_1901_2015_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_2015_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.soilcode[i]=popreal(pdata,CRUNCEP_1901_2015_DATA_LENGTH,9,0.1,0);
- for (int i=1379;i>=0;i--) obj.mswrad[i]=popreal(pdata,CRUNCEP_1901_2015_DATA_LENGTH,27,0.001,0);
- for (int i=1379;i>=0;i--) obj.mprec[i]=popreal(pdata,CRUNCEP_1901_2015_DATA_LENGTH,27,0.0001,0);
- for (int i=1379;i>=0;i--) obj.mtemp[i]=popreal(pdata,CRUNCEP_1901_2015_DATA_LENGTH,18,0.001,-100);
- return true;
- }
- }
- return false;
- }
- };
|