cruncep_1901_2015misc.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. //////////////////////////////////////////////////////////////////////////////////////
  2. // CRUNCEP_1901_2015MISC.H
  3. // Header file for input from a fast data archive
  4. // Created automatically by FastArchive on Tue Aug 30 14:13:49 2016
  5. //
  6. // The following #includes should appear in your source code file:
  7. //
  8. // #include <stdio.h>
  9. // #include <stdlib.h>
  10. // #include <string.h>
  11. // #include "/data/cruncep_v7/to_fast_archive_conversion/nc_monthly_files_verJuly1//cruncep_1901_2015misc.h"
  12. //
  13. // Functionality to retrieve data from the archive is provided by class Cruncep_1901_2015miscArchive.
  14. // The following public functions are provided:
  15. //
  16. // bool open(char* filename)
  17. // Attempts to open the specified file as a fast data archive. The format must be
  18. // exactly compatible with this version of cruncep_1901_2015misc.h (normally the archive and
  19. // header file should have been produced together by the same program using class
  20. // CFastArchive). Returns false if the file could not be opened or had format
  21. // errors. open() with no argument is equivalent to open("cruncep_1901_2015misc.bin").
  22. //
  23. // void close()
  24. // Closes the archive (if open).
  25. //
  26. // bool rewind()
  27. // Sets the file pointer to the first record in the archive file. Returns false if
  28. // no archive file is currently open.
  29. //
  30. // bool getnext(Cruncep_1901_2015misc& obj)
  31. // Retrieves the next record in the archive file and advances the file pointer to
  32. // the next record. Data are written to the member variables of obj. Returns false if
  33. // no archive file is currently open or if the file pointer is beyond the last
  34. // record. Use rewind() and getnext() to retrieve data sequentially from the archive.
  35. //
  36. // bool getindex(Cruncep_1901_2015misc& obj)
  37. // Searches the archive for a record matching the values specified for the index
  38. // items (lon and lat) in obj. If a matching record is found, the data are
  39. // written to the member variables of obj. Returns true if the archive was open and
  40. // a matching record was found, otherwise false. The search is iterative and fast.
  41. //
  42. // Sample program:
  43. //
  44. // Cruncep_1901_2015miscArchive ark;
  45. // Cruncep_1901_2015misc data;
  46. // bool success,flag;
  47. //
  48. // // Retrieve all records in sequence and print values of lon and lat:
  49. //
  50. // success=ark.open("cruncep_1901_2015misc.bin");
  51. // if (success) {
  52. // flag=ark.rewind();
  53. // while (flag) {
  54. // flag=ark.getnext(data);
  55. // if (flag)
  56. // printf("Loaded record: lon=%g, lat=%g\n",data.lon,data.lat);
  57. // }
  58. // }
  59. //
  60. // // Look for a record with lon=-180, lat=-90:
  61. //
  62. // data.lon=-180;
  63. // data.lat=-90;
  64. // success=ark.getindex(data);
  65. // if (success) printf("Found it!\n");
  66. // else printf("Not found\n");
  67. //
  68. // ark.close();
  69. struct Cruncep_1901_2015misc {
  70. // Index part
  71. double lon;
  72. double lat;
  73. // Data part
  74. double mdtr[1380];
  75. double mwet[1380];
  76. double mfrs[1380];
  77. double elv[1];
  78. };
  79. const long CRUNCEP_1901_2015MISC_NRECORD=59191;
  80. const int CRUNCEP_1901_2015MISC_DATA_LENGTH=6903;
  81. const int CRUNCEP_1901_2015MISC_INDEX_LENGTH=7;
  82. const int CRUNCEP_1901_2015MISC_HEADERSIZE=650;
  83. unsigned char CRUNCEP_1901_2015MISC_HEADER[CRUNCEP_1901_2015MISC_HEADERSIZE-4]={
  84. 0x01,0x02,0x8A,0x00,0x00,0x00,0x07,0x00,0x02,0x04,0x6C,0x6F,0x6E,0x00,0x2D,0x31,0x38,0x30,0x00,0x00,
  85. 0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,
  86. 0xBE,0x25,0xD8,0x7F,0x00,0x00,0x31,0x38,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,
  87. 0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x30,0x2E,
  88. 0x32,0x35,0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,
  89. 0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x0B,0x04,0x6C,0x61,0x74,0x00,0x2D,0x39,0x30,0x00,
  90. 0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,
  91. 0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x39,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,
  92. 0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,
  93. 0x30,0x2E,0x32,0x35,0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,
  94. 0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x0A,0x00,0x00,0x1A,0xF7,0x00,0x04,0x05,
  95. 0x6D,0x64,0x74,0x72,0x00,0x30,0x00,0x1A,0xF7,0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,
  96. 0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x31,0x30,0x30,
  97. 0x00,0x00,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,
  98. 0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x30,0x2E,0x30,0x30,0x30,0x31,0x00,0x00,0x30,0xC5,0x4E,
  99. 0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,
  100. 0x00,0x14,0x00,0x00,0x05,0x64,0x05,0x6D,0x77,0x65,0x74,0x00,0x30,0x00,0x05,0x64,0x30,0x31,0x00,0x00,
  101. 0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,
  102. 0xD8,0x7F,0x00,0x00,0x31,0x30,0x30,0x00,0x30,0x31,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,
  103. 0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x30,0x2E,0x31,0x00,
  104. 0x30,0x31,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,
  105. 0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x0A,0x00,0x00,0x05,0x64,0x05,0x6D,0x66,0x72,0x73,0x00,0x30,
  106. 0x00,0x05,0x64,0x30,0x31,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,
  107. 0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x31,0x30,0x30,0x00,0x30,0x31,0x00,0x00,0x30,
  108. 0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,
  109. 0x7F,0x00,0x00,0x30,0x2E,0x31,0x00,0x30,0x31,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,
  110. 0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x0A,0x00,0x00,0x05,0x64,
  111. 0x04,0x65,0x6C,0x76,0x00,0x2D,0x31,0x30,0x30,0x00,0x31,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,
  112. 0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x31,0x30,0x30,
  113. 0x30,0x30,0x00,0x00,0x00,0x30,0xC5,0x4E,0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,
  114. 0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,0x00,0x30,0x2E,0x30,0x30,0x31,0x00,0x00,0x00,0x30,0xC5,0x4E,
  115. 0x01,0x00,0x00,0x00,0x00,0x1C,0xF8,0x40,0x00,0x00,0x00,0x00,0x00,0x15,0x85,0xBE,0x25,0xD8,0x7F,0x00,
  116. 0x00,0x18,0x00,0x00,0x00,0x01};
  117. class Cruncep_1901_2015miscArchive {
  118. private:
  119. FILE* pfile;
  120. long recno;
  121. long datano;
  122. unsigned char pindex[CRUNCEP_1901_2015MISC_INDEX_LENGTH];
  123. unsigned char pdata[CRUNCEP_1901_2015MISC_DATA_LENGTH];
  124. bool iseof;
  125. long readbin(int nbyte) {
  126. unsigned char buf[4];
  127. long mult[4]={0x1000000,0x10000,0x100,1},val;
  128. int i;
  129. fread(buf,nbyte,1,pfile);
  130. val=0;
  131. for (i=0;i<nbyte;i++) {
  132. val+=buf[i]*mult[4-nbyte+i];
  133. }
  134. return val;
  135. }
  136. void getindex(long n) {
  137. fseek(pfile,CRUNCEP_1901_2015MISC_INDEX_LENGTH*(n-recno),SEEK_CUR);
  138. fread(pindex,CRUNCEP_1901_2015MISC_INDEX_LENGTH,1,pfile);
  139. datano=pindex[CRUNCEP_1901_2015MISC_INDEX_LENGTH-4]*0x1000000+pindex[CRUNCEP_1901_2015MISC_INDEX_LENGTH-3]*0x10000+
  140. pindex[CRUNCEP_1901_2015MISC_INDEX_LENGTH-2]*0x100+pindex[CRUNCEP_1901_2015MISC_INDEX_LENGTH-1];
  141. recno=n+1;
  142. iseof=(recno==CRUNCEP_1901_2015MISC_NRECORD);
  143. }
  144. void getdata() {
  145. fseek(pfile,CRUNCEP_1901_2015MISC_INDEX_LENGTH*-recno+(datano-CRUNCEP_1901_2015MISC_NRECORD)*CRUNCEP_1901_2015MISC_DATA_LENGTH,SEEK_CUR);
  146. fread(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,1,pfile);
  147. fseek(pfile,CRUNCEP_1901_2015MISC_DATA_LENGTH*(CRUNCEP_1901_2015MISC_NRECORD-datano-1)+CRUNCEP_1901_2015MISC_INDEX_LENGTH*recno,SEEK_CUR);
  148. }
  149. double popreal(unsigned char* bits,int nbyte,int nbit,double scalar,double offset) {
  150. unsigned char buf;
  151. int nb=nbit/8,i;
  152. double rval=0.0;
  153. long mult[4]={1,0x100,0x10000,0x1000000};
  154. for (i=0;i<4;i++) {
  155. if (i<nb) rval+=bits[nbyte-i-1]*mult[i];
  156. else if (i==nb) {
  157. buf=bits[nbyte-i-1]<<(8-nbit%8);
  158. buf>>=8-nbit%8;
  159. rval+=buf*mult[i];
  160. }
  161. }
  162. for (i=nbyte-1;i>=0;i--) {
  163. if (i>=nb)
  164. bits[i]=bits[i-nb];
  165. else
  166. bits[i]=0;
  167. }
  168. nb=nbit%8;
  169. for (i=nbyte-1;i>=0;i--) {
  170. bits[i]>>=nb;
  171. if (i>0) {
  172. buf=bits[i-1];
  173. buf<<=8-nb;
  174. bits[i]|=buf;
  175. }
  176. }
  177. rval=rval*scalar+offset;
  178. return rval;
  179. }
  180. void bitify(unsigned char buf[4],double fval,double offset,double scalar) {
  181. long ival = (long)((fval-offset)/scalar + 0.5);
  182. buf[0]=(unsigned char)(ival/0x1000000);
  183. ival-=buf[0]*0x1000000;
  184. buf[1]=(unsigned char)(ival/0x10000);
  185. ival-=buf[1]*0x10000;
  186. buf[2]=(unsigned char)(ival/0x100);
  187. ival-=buf[2]*0x100;
  188. buf[3]=(unsigned char)(ival);
  189. }
  190. void merge(unsigned char ptarget[3],unsigned char buf[4],int bits) {
  191. int nb=bits/8;
  192. int i;
  193. unsigned char nib;
  194. for (i=0;i<3;i++) {
  195. if (i<3-nb)
  196. ptarget[i]=ptarget[i+nb];
  197. else
  198. ptarget[i]=0;
  199. }
  200. nb=bits%8;
  201. for (i=0;i<3;i++) {
  202. ptarget[i]<<=nb;
  203. if (i<3-1) {
  204. nib=ptarget[i+1]>>(8-nb);
  205. ptarget[i]|=nib;
  206. }
  207. }
  208. nb=bits/8;
  209. if (bits%8) nb++;
  210. for (i=1;i<=nb;i++)
  211. ptarget[3-i]|=buf[4-i];
  212. }
  213. int compare_index(unsigned char* a,unsigned char* b) {
  214. int i;
  215. for (i=0;i<3;i++) {
  216. if (a[i]<b[i]) return -1;
  217. else if (a[i]>b[i]) return +1;
  218. }
  219. return 0;
  220. }
  221. bool initialise(const char* filename) {
  222. int i;
  223. unsigned char* pheader;
  224. if (pfile) fclose(pfile);
  225. pfile=fopen(filename,"rb");
  226. if (!pfile) {
  227. printf("Could not open %s for input\n",filename);
  228. return false;
  229. }
  230. pheader=new unsigned char[CRUNCEP_1901_2015MISC_HEADERSIZE-4];
  231. if (!pheader) {
  232. printf("Out of memory\n");
  233. fclose(pfile);
  234. pfile=NULL;
  235. return false;
  236. }
  237. ::rewind(pfile);
  238. fread(pheader,CRUNCEP_1901_2015MISC_HEADERSIZE-4,1,pfile);
  239. for (i=0;i<CRUNCEP_1901_2015MISC_HEADERSIZE-4;i++) {
  240. if (pheader[i]!=CRUNCEP_1901_2015MISC_HEADER[i]) {
  241. printf("Format of %s incompatible with this version of cruncep_1901_2015misc.h\n",filename);
  242. fclose(pfile);
  243. pfile=NULL;
  244. delete pheader;
  245. return false;
  246. }
  247. }
  248. delete[] pheader;
  249. ::rewind(pfile);
  250. fseek(pfile,CRUNCEP_1901_2015MISC_HEADERSIZE+CRUNCEP_1901_2015MISC_DATA_LENGTH*CRUNCEP_1901_2015MISC_NRECORD,SEEK_CUR);
  251. recno=0;
  252. iseof=false;
  253. return true;
  254. }
  255. public:
  256. Cruncep_1901_2015miscArchive() {
  257. pfile=NULL;
  258. }
  259. ~Cruncep_1901_2015miscArchive() {
  260. if (pfile) fclose(pfile);
  261. }
  262. bool open(const char* filename) {
  263. return initialise(filename);
  264. }
  265. bool open() {
  266. return open("cruncep_1901_2015misc.bin");
  267. }
  268. void close() {
  269. if (pfile) {
  270. fclose(pfile);
  271. pfile=NULL;
  272. }
  273. }
  274. bool rewind() {
  275. if (!pfile) return false;
  276. ::rewind(pfile);
  277. fseek(pfile,CRUNCEP_1901_2015MISC_HEADERSIZE+CRUNCEP_1901_2015MISC_DATA_LENGTH*CRUNCEP_1901_2015MISC_NRECORD,SEEK_CUR);
  278. recno=0;
  279. iseof=false;
  280. return true;
  281. }
  282. bool getnext(Cruncep_1901_2015misc& obj) {
  283. if (!pfile || iseof) return false;
  284. int i;
  285. getindex(recno);
  286. getdata();
  287. obj.lat=popreal(pindex,3,10,0.25,-90);
  288. obj.lon=popreal(pindex,3,11,0.25,-180);
  289. for (i=0;i>=0;i--) obj.elv[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,24,0.001,-100);
  290. for (i=1379;i>=0;i--) obj.mfrs[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,10,0.1,0);
  291. for (i=1379;i>=0;i--) obj.mwet[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,10,0.1,0);
  292. for (i=1379;i>=0;i--) obj.mdtr[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,20,0.0001,0);
  293. return true;
  294. }
  295. bool getindex(Cruncep_1901_2015misc& obj) {
  296. if (!CRUNCEP_1901_2015MISC_NRECORD || !pfile) return false;
  297. // else
  298. unsigned char ptarget[3]={0,0,0};
  299. unsigned char buf[4];
  300. bitify(buf,obj.lon,-180,0.25);
  301. merge(ptarget,buf,11);
  302. bitify(buf,obj.lat,-90,0.25);
  303. merge(ptarget,buf,10);
  304. long begin = 0;
  305. long end = CRUNCEP_1901_2015MISC_NRECORD;
  306. while (begin < end) {
  307. long middle = (begin+end)/2;
  308. getindex(middle);
  309. getdata();
  310. int c = compare_index(pindex, ptarget);
  311. if (c < 0) {
  312. begin = middle + 1;
  313. }
  314. else if (c > 0) {
  315. end = middle;
  316. }
  317. else {
  318. for (int i=0;i>=0;i--) obj.elv[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,24,0.001,-100);
  319. for (int i=1379;i>=0;i--) obj.mfrs[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,10,0.1,0);
  320. for (int i=1379;i>=0;i--) obj.mwet[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,10,0.1,0);
  321. for (int i=1379;i>=0;i--) obj.mdtr[i]=popreal(pdata,CRUNCEP_1901_2015MISC_DATA_LENGTH,20,0.0001,0);
  322. return true;
  323. }
  324. }
  325. return false;
  326. }
  327. };