indata.cpp 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975
  1. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. /// \file indata.cpp
  3. /// \brief Classes for text input data (used mainly for landcover input).
  4. /// File format can be either line 1:lon lat, line 2 etc.: year data-columns OR line 1: header,
  5. /// line 2 etc.: lon lat year data-columns. For local static data, use: lon lat data-columns,
  6. /// for global static data, use: dummy data-columns (with "static" as first word in header).
  7. /// \author Mats Lindeskog
  8. /// $Date: $
  9. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  10. #include "indata.h"
  11. #include "config.h"
  12. #include "guess.h"
  13. using namespace InData;
  14. /// Default value for gridlist and text input spatial resolution.
  15. /* Input data will be parsed for finer resolution than the default value. For coarser resolutions, raise default value.or set manually */
  16. const double DEFAULT_SPATIAL_RESOLUTION = 0.5;
  17. /// Default value for gridlist and text input spatial resolution for EC-EARTH modelling
  18. /* ecev3 - Input data will NO LONGER be parsed for finer resolution than the default value! */
  19. const double ECEARTH_SPATIAL_RESOLUTION = 0.02667;
  20. /// Default value for number of land cells in the reduced gaussian grid (T255) for EC-EARTH modelling
  21. /* ecev3 - Input data will NO LONGER be parsed for this value! */
  22. #ifdef GRID_T255
  23. const int ECEARTH_LAND_CELLS = 25799;
  24. #endif
  25. #ifdef GRID_T159
  26. const int ECEARTH_LAND_CELLS = 10407; // T159
  27. #endif
  28. // const int ECEARTH_LAND_CELLS = 12245; // T159 LGM
  29. /// Write land use fraction data to memory; enables efficient usage of randomised gridlists for parallell simulations
  30. const bool LUTOMEMORY = false; // ecev3 - was true
  31. // Mapping of input file data when LUTOMEMORY not defined
  32. const bool MAPFILE = true; // ecev3 - was false
  33. const bool ascendinglongitudes = false; //Not true for randomised gridlists; set to false for now // ecev3 ?
  34. bool TimeDataD::item_has_data(char* name) {
  35. int column = GetColumn(name);
  36. if(column == -1)
  37. return false;
  38. else
  39. return checkdata[column];
  40. }
  41. bool TimeDataD::item_in_header(char* name) {
  42. if(GetColumn(name) == -1)
  43. return false;
  44. else
  45. return true;
  46. }
  47. void TimeDataD::CheckIfPresent(ListArray_id<Coord>& gridlist) { //Requires gutil.h
  48. if(checkdata) {
  49. delete[] checkdata;
  50. year = NULL;
  51. }
  52. checkdata = new bool[nColumns];
  53. for(int i=0;i<nColumns;i++)
  54. checkdata[i] = false;
  55. ischeckingdata = true;
  56. Rewind();
  57. if(format == GLOBAL_STATIC || format == GLOBAL_YEARLY) {
  58. for(int i=0;i<nYears;i++) {
  59. for(int j=0;j<nColumns;j++) {
  60. if(Get(firstyear + i, j) > 0.0)
  61. checkdata[j]=1;
  62. }
  63. }
  64. return;
  65. }
  66. gridlist.firstobj();
  67. while(gridlist.isobj) {
  68. Coord& c=gridlist.getobj();
  69. if(Load(c)) {
  70. for(int i=0; i<nYears; i++) {
  71. for(int j=0; j<nColumns; j++) {
  72. if(Get(firstyear + i, j) > 0.0)
  73. checkdata[j] = true;
  74. }
  75. }
  76. }
  77. gridlist.nextobj();
  78. }
  79. gridlist.firstobj();
  80. rewind(ifp);
  81. ischeckingdata = false;
  82. }
  83. bool TimeDataD::GetHeader(char *cropnames[MAXRECORDS]) const {
  84. if(ifheader && header_arr) {
  85. for(int i=0; i<nColumns; i++)
  86. strncpy(cropnames[i], header_arr[i], MAXNAMESIZE*sizeof(char));
  87. return true;
  88. }
  89. else {
  90. return false;
  91. }
  92. }
  93. bool TimeDataD::GetHeaderFull(char *header_line) const {
  94. if(ifheader && header_arr) {
  95. if(format==LOCAL_YEARLY)
  96. strcpy(header_line, " Lon\t Lat\t Year");
  97. else if(format==GLOBAL_YEARLY)
  98. strcpy(header_line, " lon\t lat");
  99. else if(format==LOCAL_STATIC)
  100. strcpy(header_line, " year");
  101. for(int i=0; i<nColumns; i++) {
  102. char buffer[MAXNAMESIZE];
  103. sprintf(buffer, "\t%8s", header_arr[i]);
  104. strncat(header_line, buffer, strlen(buffer));
  105. }
  106. return true;
  107. }
  108. else {
  109. return false;
  110. }
  111. }
  112. char* TimeDataD::GetHeader(int record) const {
  113. if(ifheader && header_arr)
  114. return (char*)header_arr[record];
  115. else
  116. return 0;
  117. }
  118. void TimeDataD::Get(double* dataX) const {
  119. memcpy(dataX, data, nYears * nColumns * sizeof(double));
  120. }
  121. int TimeDataD::CalenderYearToPosition(int calender_year) const {
  122. int year = calender_year - firstyear;
  123. // Use first or last year's data if calender year is not within data period.
  124. if(year < 0)
  125. year = 0;
  126. else if(year >= nYears)
  127. year = nYears - 1;
  128. else
  129. year = calender_year - firstyear;
  130. return year;
  131. }
  132. void TimeDataD::Get(int calender_year, double* dataX) const {
  133. int yearX = CalenderYearToPosition(calender_year);
  134. memcpy(dataX, &data[yearX * nColumns], nColumns * sizeof(double));
  135. }
  136. double TimeDataD::Get(int calender_year, int column) const {
  137. if(memory_copy && !(format == GLOBAL_STATIC || format == GLOBAL_YEARLY))
  138. return memory_copy->Get(calender_year, column);
  139. int yearX = CalenderYearToPosition(calender_year);
  140. if(column >= nColumns)
  141. return 0.0;
  142. return data[nColumns * yearX + column];
  143. }
  144. double TimeDataD::Get(int calender_year, const char* name) const {
  145. if(memory_copy && !(format == GLOBAL_STATIC || format == GLOBAL_YEARLY))
  146. return memory_copy->Get(calender_year, name);
  147. int column = -1;
  148. for(int i=0; i<nColumns; i++) {
  149. if(!strcmp(name, header_arr[i])) {
  150. column = i;
  151. break;
  152. }
  153. }
  154. if(column == -1) {
  155. if(calender_year == firstyear)
  156. printf("WARNING: Value for %s not found in %s.\n", name, fileName);
  157. return NOTFOUND;
  158. }
  159. else {
  160. return Get(calender_year, column);
  161. }
  162. }
  163. int TimeDataD::GetColumn(const char* name) const {
  164. int column = -1;
  165. for(int i=0; i<nColumns; i++) {
  166. if(!strcmp(name, header_arr[i])) {
  167. column = i;
  168. break;
  169. }
  170. }
  171. if(column == -1) {
  172. printf("WARNING: Data for %s not found in %s.\n", name, fileName);
  173. return -1;
  174. }
  175. else {
  176. return column;
  177. }
  178. }
  179. bool TimeDataD::Open(const char* name) {
  180. int format_parsed = EMPTY;
  181. if(ifp) {
  182. fclose(ifp);
  183. ifp = NULL;
  184. }
  185. if(fileName) {
  186. delete []fileName;
  187. fileName = NULL;
  188. }
  189. if(name)
  190. ifp = fopen(name, "r");
  191. else
  192. return false;
  193. if(ifp) {
  194. fileName = new char[strlen(name) + 1];
  195. if(!fileName) {
  196. printf("Cannot allocate memory for file name string !\n");
  197. return false;
  198. }
  199. else {
  200. strcpy(fileName,name);
  201. }
  202. format_parsed = ParseFormat();
  203. if(format != format_parsed) { // Checks format (sets it if header), sets nColumns, ifheader and header_arr[]
  204. printf("Wrong format in file %s (failing ParseFormat()!\n", name);
  205. return false;
  206. }
  207. else if(format == GLOBAL_YEARLY || format == LOCAL_YEARLY) {
  208. nYears = ParseNYears(); // Parse numbers of years in input file
  209. if(nYears == 0) {
  210. printf("Wrong format in file %s (nYears=0)!\n", name);
  211. return false;
  212. }
  213. }
  214. else if(format == GLOBAL_STATIC || format == LOCAL_STATIC) {
  215. nYears = 1;
  216. }
  217. else if(format == EMPTY) { //should be set by now
  218. printf("Please set data format at initialization !\n");
  219. return false;
  220. }
  221. if(!Allocate()) { //Allocate memory for dynamic data
  222. printf("Could not allocate memory for data from file %s!\n", name);
  223. return false;
  224. }
  225. // Load global data.
  226. if(format == GLOBAL_STATIC || format == GLOBAL_YEARLY) {
  227. Load();
  228. }
  229. unity_data = ParseNormalisation();
  230. // ecev3 - no need to call ParseSpatialResolution each time. It's slow and static.
  231. if (ECEARTH && !ECEARTHWITHCRUNCEP) {
  232. spatial_resolution = ECEARTH_SPATIAL_RESOLUTION;
  233. SetSpacialResolution(spatial_resolution);
  234. }
  235. else // trunk
  236. spatial_resolution = ParseSpatialResolution();
  237. }
  238. else {
  239. printf("TimeDataD::Open: File %s could not be opened for input !\n\n", name);
  240. return false;
  241. }
  242. return true;
  243. }
  244. bool TimeDataD::ParseNormalisation() {
  245. bool unity_data = true;
  246. int cell = 0;
  247. double sum = 0.0;
  248. const int maxnsample = 200;
  249. int nsample = min(maxnsample, GetNCells());
  250. while(LoadNext() && cell < nsample) {
  251. for(int y=0;y<nYears;y++) {
  252. sum = 0.0;
  253. for(int i=0;i<nColumns;i++) {
  254. sum += Get(y + firstyear, i);
  255. }
  256. if(sum > 0.0 && (sum < 0.99 || sum > 1.01))
  257. unity_data = false;
  258. }
  259. cell++;
  260. }
  261. Rewind();
  262. return unity_data;
  263. }
  264. bool TimeDataD::NormalisedData() {
  265. return unity_data;
  266. }
  267. void TimeDataD::CreateFileMap() {
  268. if(format == GLOBAL_STATIC || format == GLOBAL_YEARLY)
  269. return;
  270. long int pos;
  271. int i = 0;
  272. // ecev3 - to speed up processing
  273. if (ECEARTH && !ECEARTHWITHCRUNCEP)
  274. nCells = ECEARTH_LAND_CELLS;
  275. else // trunk
  276. nCells = GetNCells();
  277. filemap = new CoordPos[nCells];
  278. char mapname[300];
  279. strcpy(mapname, fileName);
  280. strcat(mapname, ".map.bin");
  281. FILE *ifp_map = fopen(mapname,"rb");
  282. long lSize;
  283. if(ifp_map) {
  284. fseek(ifp_map, 0 ,SEEK_END);
  285. lSize = ftell(ifp_map);
  286. rewind(ifp_map);
  287. if(lSize != nCells * sizeof(CoordPos)) {
  288. dprintf("Text data map file format is not up to date. New mapping started.\n");
  289. fclose(ifp_map);
  290. ifp_map = NULL;
  291. }
  292. }
  293. if(!ifp_map) {
  294. rewind(ifp);
  295. while(LoadNext(&pos) && i < nCells) {
  296. Coord c = GetCoord();
  297. filemap[i].lon = c.lon;
  298. filemap[i].lat = c.lat;
  299. filemap[i].pos = pos;
  300. i++;
  301. }
  302. rewind(ifp);
  303. // Save the file map to file
  304. if(ifp_map)
  305. fclose(ifp_map);
  306. FILE *ofp_map = fopen(mapname,"wb");
  307. if(!ofp_map)
  308. fail("File could not be opened for output, quitting\n");
  309. fwrite(filemap, sizeof(CoordPos), nCells, ofp_map);
  310. fclose(ofp_map);
  311. }
  312. else {
  313. // File is already mapped, read map from file.
  314. fread(filemap, sizeof(CoordPos), nCells, ifp_map);
  315. fclose(ifp_map);
  316. }
  317. }
  318. bool TimeDataD::Open(const char* name, ListArray_id<Coord>& gridlist, double gridlist_offset) {
  319. if(Open(name)) {
  320. SetOffset(gridlist_offset);
  321. if(format == GLOBAL_STATIC || format == GLOBAL_YEARLY) {
  322. }
  323. else if (LUTOMEMORY) {
  324. CopyToMemory(gridlist.nobj, gridlist);
  325. }
  326. else if (MAPFILE) {
  327. CreateFileMap();
  328. }
  329. return true;
  330. }
  331. else {
  332. return false;
  333. }
  334. }
  335. fileformat TimeDataD::ParseFormat() {
  336. //Checks format, sets nColumns, ifheader and header_arr[].
  337. //Desired format must be set beforehand by program at initiation of class TimeDataD objects (if no header) !
  338. char line[MAXLINE], *p=NULL, s1[MAXRECORDS][MAXNAMESIZE]={'\0'}, s2[MAXRECORDS][MAXNAMESIZE]={'\0'};
  339. int count1 = 0, count2 = 0, offset = 0;
  340. fileformat format_local = EMPTY;
  341. float d[MAXRECORDS] = {0.0};
  342. //First line:
  343. do {
  344. if(fgets(line,sizeof(line),ifp)) {
  345. p = strtok(line, "\t\n ");
  346. if(!p)
  347. continue;
  348. strncpy(s1[count1], p, MAXNAMESIZE-1);
  349. count1++;
  350. do {
  351. p = strtok(NULL, "\t\n ");
  352. if(p) {
  353. strncpy(s1[count1], p, MAXNAMESIZE-1);
  354. count1++;
  355. }
  356. }
  357. while(p);
  358. p = NULL;
  359. }
  360. else {
  361. return EMPTY;
  362. }
  363. }
  364. while(!(count1 > 0));
  365. for(int q=0;q<count1;q++)
  366. header_arr[q]=new char[MAXNAMESIZE];
  367. if(!strcmp(s1[0], "lon") || !strcmp(s1[0], "Lon") || !strcmp(s1[0], "LON")) {
  368. if(!strcmp(s1[2], "year") || !strcmp(s1[2], "Year")) {
  369. format_local = LOCAL_YEARLY;
  370. offset=2;
  371. for(int i=3; i<count1; i++)
  372. strncpy(header_arr[i-3],s1[i], MAXNAMESIZE-1);
  373. }
  374. else {
  375. format_local=LOCAL_STATIC;
  376. for(int i=2; i<count1; i++)
  377. strncpy(header_arr[i-2],s1[i], MAXNAMESIZE-1);
  378. }
  379. }
  380. else if(!strcmp(s1[0], "year") || !strcmp(s1[0], "Year")) {
  381. format_local = GLOBAL_YEARLY;
  382. for(int i=1; i<count1; i++)
  383. strncpy(header_arr[i-1],s1[i], MAXNAMESIZE-1);
  384. }
  385. else if(!strcmp(s1[0], "static")) {
  386. format_local=GLOBAL_STATIC;
  387. for(int i=1; i<count1; i++)
  388. strncpy(header_arr[i-1],s1[i], MAXNAMESIZE-1);
  389. }
  390. else {
  391. ifheader = false;
  392. }
  393. //Second line:
  394. do {
  395. if(fgets(line,sizeof(line),ifp)) {
  396. p = strtok(line, "\t\n ");
  397. if(!p)
  398. continue;
  399. strncpy(s2[count2], p, 9);
  400. count2++;
  401. do {
  402. p = strtok(NULL, "\t\n ");
  403. if(p) {
  404. strncpy(s2[count2], p, 9);
  405. count2++;
  406. }
  407. }
  408. while(p);
  409. }
  410. else {
  411. return EMPTY;
  412. }
  413. }
  414. while(!(count2>0));
  415. rewind(ifp);
  416. if(format==EMPTY) {
  417. if(ifheader)
  418. format = format_local;
  419. else
  420. printf("Please set data format at initialization !\n");
  421. }
  422. switch(format) {
  423. case GLOBAL_YEARLY:
  424. if(format_local==GLOBAL_YEARLY || count1>1 && count1==count2) {
  425. nColumns = count2 - 1;
  426. return GLOBAL_YEARLY;
  427. }
  428. else {
  429. printf("Format in input file is incompatible with GLOBAL_YEARLY flag\n");
  430. return EMPTY;
  431. }
  432. break;
  433. case LOCAL_STATIC:
  434. if(format_local == LOCAL_STATIC || count1 > 2 && count1 == count2) {
  435. nColumns=count2-2;
  436. return LOCAL_STATIC;
  437. }
  438. else {
  439. printf("Format in input file is incompatible with LOCAL_STATIC flag\n");
  440. return EMPTY;
  441. }
  442. break;
  443. case LOCAL_YEARLY:
  444. if(format_local == LOCAL_YEARLY || count1 == 2 && count2 > 1) {
  445. nColumns = count2 - 1 - offset;
  446. return LOCAL_YEARLY;
  447. }
  448. else {
  449. printf("Format in input file is incompatible with LOCAL_YEARLY flag\n");
  450. return EMPTY;
  451. }
  452. break;
  453. case GLOBAL_STATIC:
  454. if(format_local == GLOBAL_STATIC || count1 > 1 && count1 == count2) {
  455. nColumns = count2 - 1;
  456. return GLOBAL_STATIC;
  457. }
  458. default:
  459. printf("Format is not set correctly in file %s !\n", fileName);
  460. return EMPTY;
  461. }
  462. }
  463. int TimeDataD::ParseNYears() {
  464. int n_yearsX = 0;
  465. switch(format) {
  466. case GLOBAL_YEARLY:
  467. n_yearsX = ParseNYearsGlobal();
  468. break;
  469. case LOCAL_YEARLY:
  470. n_yearsX = ParseNYearsLocal();
  471. break;
  472. default:
  473. printf("Format in is uncorrectly set by program for file %s !\n", fileName);
  474. return 0;
  475. }
  476. return n_yearsX;
  477. }
  478. double TimeDataD::ParseSpatialResolution() {
  479. double precision = 100;
  480. double dif_lon;
  481. double dif_lat;
  482. const int maxnsample = 200;
  483. int nsample = min(maxnsample, GetNCells());
  484. Coord cvect[maxnsample];
  485. for (int i=0; i<nsample; i++) {
  486. LoadNext();
  487. Coord c = GetCoord();
  488. cvect[i].lon = c.lon;
  489. cvect[i].lat = c.lat;
  490. }
  491. for (int i=0; i<nsample; i++) {
  492. for (int j=0; j<nsample; j++) {
  493. dif_lon = fabs(cvect[i].lon - cvect[j].lon);
  494. dif_lat = fabs(cvect[i].lat - cvect[j].lat);
  495. if(largerthanzero(dif_lon, -12))
  496. precision = min(precision, dif_lon);
  497. if(largerthanzero(dif_lat, -12))
  498. precision = min(precision, dif_lat);
  499. }
  500. }
  501. Rewind();
  502. return min(precision, spatial_resolution);
  503. }
  504. int TimeDataD::GetNCells() {
  505. if(!nCells)
  506. ParseNCells();
  507. return nCells;
  508. }
  509. void TimeDataD::ParseNCells() {
  510. if(format == GLOBAL_STATIC || format == GLOBAL_YEARLY) {
  511. nCells = 1;
  512. return;
  513. }
  514. float d1;
  515. long int oldpos;
  516. int i = 0, count = 0;
  517. char line[MAXLINE];
  518. bool error = false;
  519. oldpos=ftell(ifp);
  520. if(oldpos!=0)
  521. rewind(ifp);
  522. if(ifheader)
  523. fgets(line,sizeof(line), ifp); //ignore header line
  524. while(!feof(ifp)) {
  525. line[0] = 0;
  526. fgets(line,sizeof(line), ifp);
  527. count=sscanf(line,"%f", &d1);
  528. if(count > 0)
  529. i++;
  530. }
  531. if(ifheader) {
  532. nCells = i / nYears;
  533. if(i % nYears)
  534. error = true;
  535. }
  536. else {
  537. nCells = i / (nYears + 1);
  538. if(i % (nYears + 1))
  539. error = true;
  540. }
  541. if(error)
  542. dprintf("Unexpected number of lines ! No.lines=%d, No.cells=%d, No.years=%d\n", i, nCells, nYears);
  543. fseek(ifp, oldpos, SEEK_SET); // ecev3 - 0 to SEEK_SET
  544. }
  545. int TimeDataD::ParseNYearsLocal() {
  546. int i = 0, count1 = 0, prevLine = 0, nyears1 = 0, nyears2 = 0, n = 0;
  547. char line[MAXLINE];
  548. bool new_coord = false;
  549. float d1 = 0,d2 = 0,d3 = 0, d1_prevLine = 0, d2_prevLine = 0;
  550. for(i=0; i<MAXLINESPARSE && !feof(ifp);) {
  551. if(fgets(line,sizeof(line), ifp)) {
  552. count1 = sscanf(line,"%f%f%f", &d1, &d2, &d3); // does not count header strings
  553. if(count1 > 0) {
  554. if(ifheader && (d1 != d1_prevLine || d2 != d2_prevLine)) { // First line of new coordinate
  555. nyears2 = i - prevLine;
  556. new_coord = true;
  557. firstyear = (int)d3;
  558. }
  559. else if(count1 == 2 && d1 <= 180.0) {
  560. nyears2 = i - prevLine - 1;
  561. new_coord = true;
  562. }
  563. if(new_coord) {
  564. if((nyears1 != nyears2) && n > 1) {
  565. printf("FORMAT ERROR in input file %s !\n", fileName);
  566. return 0;
  567. }
  568. nyears1 = nyears2; //NB. not set if input file has data for only one coordinate !
  569. prevLine = i;
  570. n++;
  571. new_coord = false;
  572. }
  573. else if(!ifheader && i == prevLine + 1) {
  574. firstyear = (int)d1;
  575. }
  576. i++;
  577. d1_prevLine = d1;
  578. d2_prevLine = d2;
  579. }
  580. }
  581. }
  582. if(feof(ifp)) { // Last cell
  583. if(ifheader)
  584. nyears2 = i - prevLine;
  585. else
  586. nyears2 = i - prevLine - 1;
  587. if((nyears1 != nyears2) && n > 1) {
  588. printf("FORMAT ERROR in input file %s !\n", fileName);
  589. return 0;
  590. }
  591. }
  592. rewind(ifp);
  593. return nyears2;
  594. }
  595. int TimeDataD::ParseNYearsGlobal() {
  596. int count = 0, nyears = 0;
  597. char line[MAXLINE];
  598. float d1 = 0,d2 = 0,d3 = 0;
  599. if(ifheader)
  600. fgets(line,sizeof(line),ifp);
  601. while(!feof(ifp)) {
  602. if(fgets(line,sizeof(line),ifp)) {
  603. count=sscanf(line,"%f%f%f", &d1, &d2 ,&d3);
  604. if(count > 0) {
  605. if(count >= 2) {
  606. nyears++;
  607. if(nyears == 1)
  608. firstyear = (int)d1;
  609. }
  610. else {
  611. printf("FORMAT ERROR in input file %s !\n", fileName);
  612. nyears = 0;
  613. break;
  614. }
  615. }
  616. }
  617. }
  618. rewind(ifp);
  619. return nyears;
  620. }
  621. bool TimeDataD::Allocate() { // Allocates memory for dynamic data: format & nYears must be set before !
  622. if(year) {
  623. delete[] year;
  624. year = NULL;
  625. }
  626. if(data) {
  627. delete[] data;
  628. data = NULL;
  629. }
  630. switch(format) {
  631. case EMPTY:
  632. break;
  633. case GLOBAL_STATIC:
  634. year = new int;
  635. data = new double[nColumns];
  636. if(year)
  637. *year = 0;
  638. if(data)
  639. *data = 0;
  640. break;
  641. case GLOBAL_YEARLY:
  642. year = new int[nYears];
  643. data = new double[nColumns * nYears];
  644. if(year) {
  645. for(int i=0;i<nYears;i++)
  646. year[i] = 0;
  647. }
  648. if(data) {
  649. for(int i=0;i<nColumns*nYears;i++)
  650. data[i] = 0.0;
  651. }
  652. break;
  653. case LOCAL_STATIC:
  654. year = new int;
  655. data = new double[nColumns];
  656. if(year)
  657. *year = 0;
  658. if(data)
  659. for(int j=0;j<nColumns;j++)
  660. data[j] = 0;
  661. break;
  662. case LOCAL_YEARLY:
  663. year = new int[nYears];
  664. data = new double[nColumns * nYears];
  665. if(year) {
  666. for(int i=0;i<nYears;i++)
  667. year[i] = 0;
  668. }
  669. if(data) {
  670. for(int i=0;i<nColumns*nYears;i++)
  671. data[i] = 0.0;
  672. }
  673. break;
  674. default:
  675. ;
  676. }
  677. if(year && data)
  678. return true;
  679. else
  680. return false;
  681. }
  682. void TimeDataD::SetOffset(double gridlist_offset) {
  683. if(gridlist_offset)
  684. offset = gridlist_offset - spatial_resolution / 2.0;
  685. }
  686. bool TimeDataD::Load() { // for GLOBAL_YEARLY and GLOBAL_STATIC data
  687. int i = 0, count = 0, yearX = 0, yearX_previous, k = 0;
  688. char line[MAXLINE], *p = NULL;
  689. double d1 = 0.0;
  690. double d[MAXRECORDS] = {0.0};
  691. float extra = 0.0;
  692. bool error = false;
  693. if(ifp) {
  694. if(format == GLOBAL_YEARLY) {
  695. if(year) {
  696. for(int i=0;i<nYears;i++)
  697. year[i] = 0;
  698. }
  699. if(data) {
  700. for(int i=0;i<nColumns*nYears;i++)
  701. data[i] = 0.0;
  702. }
  703. yearX_previous = firstyear - 1;
  704. if(ifheader)
  705. fgets(line, sizeof(line), ifp);
  706. for(i=0; i<nYears;) {
  707. k = 0;
  708. if(fgets(line, sizeof(line), ifp)) {
  709. for(int j=0;j<nColumns;j++)
  710. d[j] = 0.0;
  711. count = 0;
  712. p=strtok(line, "\t\n "); // year
  713. if(!p)
  714. continue;
  715. sscanf(p, "%d", &yearX);
  716. if(yearX != yearX_previous + 1) {
  717. printf("FORMAT ERROR in input file %s: Load(). Wrong year in data file ! Missing line ?\n", fileName);
  718. error = true;
  719. break;
  720. }
  721. else {
  722. yearX_previous = yearX;
  723. }
  724. do {
  725. p = strtok(NULL, "\t\n ");
  726. if(p)
  727. count += sscanf(p, "%lf", &d[k]);
  728. k++;
  729. }
  730. while(p);
  731. if(count > 0) {
  732. if(count == nColumns) {
  733. year[i] = yearX;
  734. for(int j=0; j<nColumns; j++)
  735. data[nColumns * i + j] = d[j];
  736. }
  737. else {
  738. printf("FORMAT ERROR in input file %s: Load(), count!=%d\n", fileName, i+1);
  739. error = true;
  740. }
  741. i++;
  742. }
  743. }
  744. else {
  745. printf("An ERROR occurred reading file %s\n", fileName);
  746. error = true;
  747. }
  748. }
  749. }
  750. else if(format == GLOBAL_STATIC) {
  751. if(fgets(line, sizeof(line), ifp)) {
  752. if(ifheader) {
  753. if(fgets(line, sizeof(line), ifp)) {
  754. p = strtok(line," \t"); //"static"
  755. }
  756. else {
  757. printf("An ERROR occurred reading file %s\n", fileName);
  758. error = true;
  759. }
  760. }
  761. do {
  762. p = strtok(NULL, "\t\n ");
  763. if(p)
  764. count += sscanf(p, "%lf", &d[k]);
  765. k++;
  766. }
  767. while(p);
  768. if(count == nColumns) {
  769. for(i=0; i<nColumns; i++)
  770. data[i] = d[i];
  771. }
  772. else {
  773. printf("FORMAT ERROR in input file %sf: Load(), count!=%d\n", fileName, nColumns+1);
  774. error = true;
  775. }
  776. }
  777. else {
  778. printf("An ERROR occurred reading file %s\n", fileName);
  779. error = true;
  780. }
  781. }
  782. else {
  783. printf("Wrong usage of Load(void)\n");
  784. error = true;
  785. }
  786. }
  787. else {
  788. printf("Cannot load from unopened file !\n");
  789. error = true;
  790. }
  791. if(ifp) {
  792. fclose(ifp);
  793. ifp = NULL;
  794. }
  795. if(error) {
  796. loaded = false;
  797. return false;
  798. }
  799. else {
  800. loaded = true;
  801. return true;
  802. }
  803. }
  804. bool TimeDataD::LoadFromMap(Coord c) {
  805. double searchradius = min(spatial_resolution / 2.0, MAX_SEARCHRADIUS);
  806. double min_dist = 1000;
  807. long int found_pos = -1;
  808. int found_i;
  809. for(int i=0; i<nCells; i++) {
  810. double dif_lon = fabs(filemap[i].lon - c.lon);
  811. double dif_lat = fabs(filemap[i].lat - c.lat);
  812. if(dif_lon <= searchradius && dif_lat <= searchradius) {
  813. if(min_dist > (dif_lon + dif_lat)) {
  814. min_dist = dif_lon + dif_lat;
  815. found_pos = filemap[i].pos;
  816. found_i = i;
  817. }
  818. }
  819. }
  820. if(found_pos > -1) {
  821. SetPosition(found_pos);
  822. LoadNext();
  823. if(currentStand.lon != filemap[found_i].lon || currentStand.lat != filemap[found_i].lat)
  824. fail("Error in saved file map for %s. Delete map.bin file and retry\n", fileName);
  825. loaded = true;
  826. }
  827. else {
  828. loaded = false;
  829. }
  830. return loaded;
  831. }
  832. bool TimeDataD::Load(Coord c) {
  833. if(format == GLOBAL_STATIC || format == GLOBAL_YEARLY) {
  834. loaded = true;
  835. return true;
  836. }
  837. if(offset) {
  838. c.lon += offset;
  839. c.lat += offset;
  840. }
  841. if(memory_copy)
  842. return memory_copy->Load(c);
  843. else if(filemap)
  844. return LoadFromMap(c);
  845. char line[MAXLINE], *p=NULL;
  846. int i = 0, j = 0, k = 0, count1 = 0, nyears = 0, yearX = 0, yearX_previous;
  847. float lonX = 0.0, latX = 0.0;
  848. double d[MAXRECORDS] = {0.0};
  849. bool error = false;
  850. if(ifp) {
  851. if(format==LOCAL_YEARLY) {
  852. if(FindRecord(c)) {
  853. if(year) {
  854. for(int i=0;i<nYears;i++)
  855. year[i] = 0;
  856. }
  857. if(data) {
  858. for(int i=0;i<nColumns*nYears;i++)
  859. data[i] = 0.0;
  860. }
  861. yearX_previous = firstyear - 1;
  862. while(i < nYears && yearX < firstyear + nYears - 1) {
  863. k = 0;
  864. if(fgets(line, sizeof(line), ifp)) {
  865. for(int q=0;q<nColumns;q++)
  866. d[q] = 0.0;;
  867. count1 = 0;
  868. if(ifheader) {
  869. p = strtok(line," \t"); //lon
  870. sscanf(p, "%f", &lonX);
  871. p = strtok(NULL, " \t"); //lat
  872. sscanf(p, "%f", &latX);
  873. p = strtok(NULL, " \t"); //year
  874. if(fabs(lonX - c.lon) > spatial_resolution / 2.0 || fabs(latX - c.lat) > spatial_resolution / 2.0) {
  875. printf("FORMAT ERROR in input file %s for stand at Coordinate %.2f,%.2f: Load(). Wrong coordinates in data file !\n", fileName, c.lon, c.lat);
  876. printf("Make sure file has correct DOS/Unix text format\n");
  877. error = true;
  878. break;
  879. }
  880. else {
  881. currentStand.lon = lonX;
  882. currentStand.lat = latX;
  883. }
  884. }
  885. else {
  886. p = strtok(line, "\t\n "); //year
  887. }
  888. if(!p)
  889. continue;
  890. sscanf(p, "%d", &yearX);
  891. if(yearX != yearX_previous + 1) {
  892. printf("FORMAT ERROR in input file %s for stand at Coordinate %.2f,%.2f: Load(). Wrong year in data file ! Missing line ?\n", fileName, c.lon, c.lat);
  893. error=1;
  894. }
  895. yearX_previous = yearX;
  896. do {
  897. p = strtok(NULL, "\t\n ");
  898. if(p)
  899. count1 += sscanf(p, "%lf", &d[k]);
  900. k++;
  901. }
  902. while(p);
  903. if(count1 > 0) {
  904. if(count1 == nColumns) {
  905. year[i] = yearX;
  906. for(j=0; j<nColumns; j++)
  907. data[nColumns * i + j] = d[j];
  908. }
  909. else {
  910. printf("FORMAT ERROR in input file %s for stand at Coordinate %.2f,%.2f: Load(), count!=%d, year %d\n", fileName, c.lon, c.lat, nColumns+1, i+1);
  911. error = true;
  912. break;
  913. }
  914. i++;
  915. }
  916. }
  917. else {
  918. printf("An ERROR occurred reading file %s\n", fileName);
  919. error = true;
  920. break;
  921. }
  922. }
  923. }
  924. else {
  925. printf("COULD NOT FIND DATA for %.2f, %.2f in file %s\n", c.lon, c.lat, fileName);
  926. error = true;
  927. }
  928. }
  929. else if(format == LOCAL_STATIC) {
  930. if(FindRecord(c)) {
  931. if(data) {
  932. for(int i=0;i<nColumns;i++)
  933. data[i] = 0.0;;
  934. }
  935. if(fgets(line, sizeof(line), ifp)) {
  936. if(d) {
  937. for(int i=0;i<nColumns;i++)
  938. d[i] = 0.0;;
  939. }
  940. p=strtok(line," \t"); //lon
  941. sscanf(p, "%f", &lonX);
  942. p=strtok(NULL, " \t"); //lat
  943. sscanf(p, "%f", &latX);
  944. currentStand.lon = lonX;
  945. currentStand.lat = latX;
  946. do {
  947. p = strtok(NULL, "\t\n ");
  948. if(p)
  949. count1 += sscanf(p, "%lf", &d[k]);
  950. k++;
  951. }
  952. while(p);
  953. if(count1 > 0) {
  954. if(count1 == nColumns) {
  955. for(j=0; j<nColumns; j++)
  956. data[j] = d[j];
  957. }
  958. else {
  959. printf("FORMAT ERROR in input file %s for stand at Coordinate %.2f,%.2f: Load(), count!=%d, year %d\n", fileName, c.lon, c.lat, nColumns+1, i+1);
  960. error=1;
  961. }
  962. }
  963. }
  964. else {
  965. printf("An ERROR occurred reading file %s\n", fileName);
  966. error = true;
  967. }
  968. }
  969. else {
  970. printf("COULD NOT FIND DATA for %.2f, %.2f in file %s\n",c.lon,c.lat,fileName);
  971. error = true;
  972. }
  973. }
  974. else {
  975. printf("Wrong usage of Load(Coord)\n");
  976. error = true;
  977. }
  978. }
  979. else {
  980. printf("Cannot load from unopened file !\n");
  981. error = true;
  982. }
  983. if(error) {
  984. loaded = false;
  985. return false;
  986. }
  987. else {
  988. loaded = true;
  989. return true;
  990. }
  991. }
  992. bool TimeDataD::isloaded() {
  993. if(memory_copy)
  994. return memory_copy->isloaded();
  995. else
  996. return loaded;
  997. }
  998. bool TimeDataD::LoadNext(long int *pos) {
  999. // To be called after ParseFormat(), ParseNYears() and Allocate()
  1000. // Only implemented for LOCAL_YEARLY and LOCAL_STATIC
  1001. // Needs to be modified to handle missing lines in data files with header ! (see Load)
  1002. if(format == GLOBAL_STATIC || format == GLOBAL_YEARLY) {
  1003. return 1;
  1004. }
  1005. char line[MAXLINE], *p=NULL;
  1006. double d1, d2, d3, d[MAXRECORDS]={0.0};
  1007. bool error = false, firstyear = true;
  1008. long int fpos;
  1009. if(ifp && !feof(ifp)) {
  1010. if(format == LOCAL_YEARLY) {
  1011. if(year) {
  1012. for(int i=0;i<nYears;i++)
  1013. year[i] = 0;
  1014. }
  1015. if(data) {
  1016. for(int i=0;i<nColumns*nYears;i++)
  1017. data[i] = 0.0;
  1018. }
  1019. if(ifheader) {
  1020. fpos = ftell(ifp);
  1021. if(fpos == 0) {
  1022. fgets(line,sizeof(line), ifp); //ignore header line
  1023. fpos = ftell(ifp);
  1024. }
  1025. if(pos)
  1026. *pos = fpos;
  1027. }
  1028. int count = 0;
  1029. if(fgets(line,sizeof(line), ifp)) {
  1030. count = sscanf(line,"%lf%lf%lf", &d1, &d2, &d3);
  1031. if(count > 0) { // Avoid blank lines at the end of the file
  1032. if(count == 2 || count > 2 && (format == LOCAL_STATIC || ifheader)) {
  1033. currentStand.lon = d1;
  1034. currentStand.lat = d2;
  1035. }
  1036. else {
  1037. printf("FORMAT ERROR in input file %s: LoadNext(), count!=2\n", fileName);
  1038. error = true;
  1039. }
  1040. }
  1041. else {
  1042. printf("WARNING: blank line in file %s: LoadNext(), count==0\n", fileName);
  1043. }
  1044. }
  1045. else {
  1046. error = true;
  1047. }
  1048. for(int i=0; i<nYears && error==false && count>0;) {
  1049. if(ifheader && firstyear)
  1050. firstyear = false;
  1051. else
  1052. fgets(line, sizeof(line), ifp);
  1053. if(line) {
  1054. int k = 0;
  1055. int count1 = 0;
  1056. int yearX = 0;
  1057. for(int q=0;q<nColumns;q++)
  1058. d[q] = 0.0;;
  1059. if(ifheader) {
  1060. p = strtok(line," \t"); //lon
  1061. p = strtok(NULL, " \t"); //lat
  1062. p = strtok(NULL, " \t"); //year
  1063. }
  1064. else {
  1065. p = strtok(line, "\t\n "); //year
  1066. }
  1067. if(!p)
  1068. continue;
  1069. sscanf(p, "%d", &yearX);
  1070. do {
  1071. p = strtok(NULL, "\t\n ");
  1072. if(p)
  1073. count1 += sscanf(p, "%lf", &d[k]);
  1074. k++;
  1075. }
  1076. while(p);
  1077. if(count1 > 0) {
  1078. if(count1 == nColumns) {
  1079. year[i] = yearX;
  1080. for(int j=0; j<nColumns; j++)
  1081. data[nColumns * i + j] = d[j];
  1082. }
  1083. else {
  1084. printf("FORMAT ERROR in input file %s: LoadNext(), count!=%d, year %d\n", fileName, nColumns+1, i+1);
  1085. printf("Make sure file has correct DOS/Unix text format\n");
  1086. error = true;
  1087. break;
  1088. }
  1089. i++;
  1090. }
  1091. }
  1092. else {
  1093. printf("An ERROR occurred reading file %s\n", fileName);
  1094. error=true;
  1095. break;
  1096. }
  1097. }
  1098. }
  1099. else if(format == LOCAL_STATIC) {
  1100. if(data) {
  1101. for(int i=0;i<nColumns*nYears;i++)
  1102. data[i] = 0.0;
  1103. }
  1104. if(ifheader) {
  1105. fpos = ftell(ifp);
  1106. if(fpos == 0) {
  1107. fgets(line,sizeof(line), ifp); //ignore header line
  1108. fpos = ftell(ifp);
  1109. }
  1110. if(pos)
  1111. *pos = fpos;
  1112. }
  1113. int count = 0;
  1114. if(fgets(line,sizeof(line), ifp)) {
  1115. count = sscanf(line,"%lf%lf%lf", &d1, &d2, &d3);
  1116. if(count > 0) { // Avoid blank lines at the end of the file
  1117. if(count == 2 || count > 2 && (format == LOCAL_STATIC || ifheader)) {
  1118. currentStand.lon = d1;
  1119. currentStand.lat = d2;
  1120. }
  1121. else {
  1122. printf("FORMAT ERROR in input file %s: LoadNext(), count!=2\n", fileName);
  1123. error = true;
  1124. }
  1125. }
  1126. else {
  1127. printf("WARNING: blank line in file %s: LoadNext(), count==0\n", fileName);
  1128. }
  1129. }
  1130. else {
  1131. error = true;
  1132. }
  1133. for(int i=0; i<nYears && error==false && count>0;) {
  1134. int k = 0;
  1135. int count1 = 0;
  1136. if(ifheader && firstyear)
  1137. firstyear = false;
  1138. else
  1139. fgets(line, sizeof(line), ifp);
  1140. if(line) {
  1141. for(int q=0;q<nColumns;q++)
  1142. d[q] = 0.0;;
  1143. if(ifheader) {
  1144. p = strtok(line," \t"); //lon
  1145. p = strtok(NULL, " \t"); //lat
  1146. }
  1147. if(!p)
  1148. continue;
  1149. do {
  1150. p = strtok(NULL, "\t\n ");
  1151. if(p)
  1152. count1 += sscanf(p, "%lf", &d[k]);
  1153. k++;
  1154. }
  1155. while(p);
  1156. if(count1 > 0) {
  1157. if(count1 == nColumns) {
  1158. for(int j=0; j<nColumns; j++)
  1159. data[nColumns * i + j] = d[j];
  1160. }
  1161. else {
  1162. printf("FORMAT ERROR in input file %s: LoadNext(), count!=%d, year %d\n", fileName, nColumns+1, i+1);
  1163. printf("Make sure file has correct DOS/Unix text format\n");
  1164. error = true;
  1165. break;
  1166. }
  1167. i++;
  1168. }
  1169. }
  1170. else
  1171. {
  1172. printf("An ERROR occurred reading file %s\n", fileName);
  1173. error = true;
  1174. break;
  1175. }
  1176. }
  1177. }
  1178. }
  1179. else {
  1180. error = true;
  1181. }
  1182. if(error)
  1183. return false;
  1184. else
  1185. return true;
  1186. }
  1187. bool TimeDataD::FindRecord(Coord c) const {
  1188. //Fast version. Can not handle blank lines in some cases, will call FindRecord2() in those cases.
  1189. int i = 0, count = 0, n = 0, lap = 0, line_no = 0;
  1190. char line[MAXLINE], *p = NULL;
  1191. double d1 = 0.0,d2 = 0.0,d3 = 0.0;
  1192. bool found = false, error = false, start = true;
  1193. long int oldpos;
  1194. do {
  1195. i = 0;
  1196. start = true;
  1197. while(!feof(ifp)) {
  1198. if(ifheader) {
  1199. if(!(i%nYears))
  1200. oldpos = ftell(ifp);
  1201. }
  1202. if(fgets(line,sizeof(line), ifp)) {
  1203. if(ifheader) {
  1204. if(start == true) {
  1205. start = false;
  1206. if(oldpos == 0)
  1207. continue;
  1208. }
  1209. }
  1210. if(!(i%(nYears+1)) && !ifheader || !(i%nYears) && ifheader) {
  1211. count=sscanf(line,"%lf%lf%lf", &d1, &d2, &d3);
  1212. if(count>0) { // Avoid blank line at the end of the file
  1213. if(count == 2 || count > 2 && (d3 == firstyear || format == LOCAL_STATIC) && (format == LOCAL_STATIC || ifheader)) {
  1214. if(fabs(d1 - c.lon) <= spatial_resolution / 2.0 && fabs(d2 - c.lat) <= spatial_resolution / 2.0) {
  1215. found = true;
  1216. break;
  1217. }
  1218. else if(ascendinglongitudes && c.lon<d1) {
  1219. dprintf("c.lon<d1; rewinding...\n");
  1220. break;
  1221. }
  1222. }
  1223. else {
  1224. if(ifheader)
  1225. dprintf("FORMAT ERROR in input file %s: FindRecord(), wrong firstyear, line %d\n", fileName, i);
  1226. else
  1227. dprintf("FORMAT ERROR in input file %s: FindRecord(), count!=2, line %d\n", fileName, i);
  1228. error = true;
  1229. break;
  1230. }
  1231. }
  1232. else {
  1233. dprintf("WARNING: blank line in file %s: FindRecord(), count==0\n", fileName);
  1234. continue;
  1235. }
  1236. }
  1237. i++;
  1238. }
  1239. }
  1240. if(!found) {
  1241. lap++;
  1242. rewind(ifp);
  1243. if(error)
  1244. break;
  1245. }
  1246. } while(!found && lap<2);
  1247. if(found && !error) {
  1248. if(ifheader)
  1249. fseek(ifp, oldpos, SEEK_SET); // ecev3 - 0 to SEEK_SET
  1250. return true;
  1251. }
  1252. else
  1253. return FindRecord2(c); //If not found, try FindRecord2()
  1254. }
  1255. bool TimeDataD::FindRecord2(Coord c) const {
  1256. //This version should handle blank or missing lines at all positions.
  1257. int i = 0, count = 0, n = 0, lap = 0, lastyear;
  1258. char line[MAXLINE], *p = NULL;
  1259. double d1 = 0.0, d2 = 0.0, d3 = 0.0;
  1260. bool found = false, error = false, start = true;
  1261. long int oldpos;
  1262. lastyear = firstyear + nYears - 1;
  1263. do {
  1264. i = 0;
  1265. start = true;
  1266. while(!feof(ifp)) {
  1267. if(ifheader) {
  1268. if(d3==lastyear || start)
  1269. oldpos = ftell(ifp);
  1270. }
  1271. if(fgets(line,sizeof(line),ifp)) {
  1272. if(ifheader) {
  1273. if(start==true) {
  1274. start = false;
  1275. if(oldpos==0)
  1276. continue;
  1277. }
  1278. }
  1279. count = sscanf(line,"%lf%lf%lf", &d1, &d2, &d3);
  1280. if(count>0) { // Avoid blank lines at the end of the file
  1281. if(count==2 || count>2 && d3==firstyear && (format==LOCAL_STATIC || ifheader)) {
  1282. if(fabs(d1 - c.lon) <= spatial_resolution / 2.0 && fabs(d2 - c.lat) <= spatial_resolution / 2.0) {
  1283. found=1;
  1284. break;
  1285. }
  1286. else if(ascendinglongitudes && c.lon<d1) {
  1287. dprintf("c.lon<d1; rewinding...\n");
  1288. break;
  1289. }
  1290. }
  1291. }
  1292. else {
  1293. dprintf("WARNING: blank line in file %s: FindRecord2(), count==0\n",fileName);
  1294. continue;
  1295. }
  1296. i++;
  1297. }
  1298. }
  1299. if(!found) {
  1300. lap++;
  1301. rewind(ifp);
  1302. }
  1303. } while(!found && lap<2);
  1304. if(found && !error) {
  1305. if(ifheader)
  1306. fseek(ifp, oldpos, SEEK_SET); // ecev3 - 0 to SEEK_SET
  1307. return true;
  1308. }
  1309. else {
  1310. return false;
  1311. }
  1312. }
  1313. void TimeDataD::Output(char *name) {
  1314. int i = 0, j = 0;
  1315. FILE *ofp;
  1316. static bool first_call = true;
  1317. if(first_call)
  1318. remove(name);
  1319. if(format==GLOBAL_STATIC || format==GLOBAL_YEARLY)
  1320. ofp = fopen(name, "w");
  1321. else if(format==LOCAL_STATIC || format==LOCAL_YEARLY)
  1322. ofp = fopen(name, "a");
  1323. if(ifheader && header_arr && first_call) {
  1324. switch (format) {
  1325. case GLOBAL_STATIC:
  1326. break;
  1327. case GLOBAL_YEARLY:
  1328. fprintf(ofp, " year\t");
  1329. break;
  1330. case LOCAL_STATIC:
  1331. fprintf(ofp, " lon\t lat\t");
  1332. break;
  1333. case LOCAL_YEARLY:
  1334. fprintf(ofp, " lon\t lat\t year\t");
  1335. break;
  1336. default:
  1337. ;
  1338. }
  1339. for(int i=0; i<nColumns; i++)
  1340. fprintf(ofp, "%8s\t", header_arr[i]);
  1341. fprintf(ofp, "\n");
  1342. first_call = false;
  1343. }
  1344. switch (format) {
  1345. case GLOBAL_STATIC:
  1346. fprintf(ofp, "%.3lf\n", *data);
  1347. break;
  1348. case GLOBAL_YEARLY:
  1349. for(i=0; i<nYears; i++)
  1350. fprintf(ofp, "%d\t%.3lf\n", year[i], data[i]);
  1351. break;
  1352. case LOCAL_STATIC:
  1353. fprintf(ofp, "%6.2f\t%6.2f",currentStand.lon, currentStand.lat);
  1354. for(j=0; j<nColumns; j++)
  1355. fprintf(ofp, "\t%8.3f", data[nColumns*i+j]);
  1356. fprintf(ofp, "\n");
  1357. break;
  1358. case LOCAL_YEARLY:
  1359. if(!ifheader)
  1360. fprintf(ofp, "%8.2f\t%8.2f\n",currentStand.lon, currentStand.lat);
  1361. for(i=0;i<nYears;i++) {
  1362. if(ifheader)
  1363. fprintf(ofp, "%6.2f\t%6.2f\t",currentStand.lon, currentStand.lat);
  1364. fprintf(ofp, "%6d ", year[i]);
  1365. for(j=0; j<nColumns; j++)
  1366. fprintf(ofp, "\t%8.3f", data[nColumns * i + j]);
  1367. fprintf(ofp, "\n");
  1368. }
  1369. break;
  1370. default:
  1371. ;
  1372. }
  1373. if(ofp)
  1374. fclose(ofp);
  1375. }
  1376. TimeDataD::TimeDataD(fileformat formatX) {
  1377. ifp = NULL;
  1378. fileName = NULL;
  1379. ifheader = true;
  1380. for(int i=0;i<MAXRECORDS;i++) {
  1381. header_arr[i] = NULL;
  1382. }
  1383. currentStand.lon = 0;
  1384. currentStand.lat = 0;
  1385. data = NULL;
  1386. checkdata = NULL;
  1387. ischeckingdata = false;
  1388. unity_data = true;
  1389. nColumns = 0;
  1390. nYears = 0;
  1391. nCells = 0;
  1392. firstyear = -1;
  1393. year = NULL;
  1394. format = formatX;
  1395. memory_copy = NULL;
  1396. filemap = NULL;
  1397. spatial_resolution = DEFAULT_SPATIAL_RESOLUTION;
  1398. offset = 0.0;
  1399. loaded = false;
  1400. }
  1401. //Deconstructor
  1402. TimeDataD::~TimeDataD() {
  1403. Close();
  1404. }
  1405. void TimeDataD::Close() {
  1406. if(ifp)
  1407. fclose(ifp);
  1408. if(fileName) {
  1409. delete []fileName;
  1410. fileName = NULL;
  1411. }
  1412. if(year) {
  1413. delete[] year;
  1414. year = NULL;
  1415. }
  1416. if(data) {
  1417. delete[] data;
  1418. data = NULL;
  1419. }
  1420. if(checkdata) {
  1421. delete []checkdata;
  1422. checkdata = NULL;
  1423. }
  1424. if(memory_copy) {
  1425. memory_copy->Close();
  1426. delete memory_copy;
  1427. }
  1428. if(filemap)
  1429. delete[] filemap;
  1430. for(int i=0;i<MAXRECORDS;i++) {
  1431. if(&header_arr[i]) {
  1432. delete[] header_arr[i];
  1433. header_arr[i] = NULL;
  1434. }
  1435. }
  1436. }
  1437. void TimeDataD::CopyToMemory(int ncells, ListArray_id<Coord>& lonlatlist) { //Requires gutil.h
  1438. if(format == GLOBAL_STATIC)
  1439. ncells = 1;
  1440. memory_copy = new TimeDataDmem;
  1441. memory_copy->Open(ncells, this->nColumns, this->nYears);
  1442. memory_copy->CopyFromTimeDataD(*this, lonlatlist);
  1443. Rewind();
  1444. }
  1445. int TimeDataDmem::CalenderYearToPosition(int calender_year) const {
  1446. int yearX = calender_year - firstyear;
  1447. // Use first or last year's data if calender year is not within data period.
  1448. if(yearX < 0)
  1449. yearX = 0;
  1450. else if(yearX >= nYears)
  1451. yearX = nYears -1;
  1452. else
  1453. yearX = calender_year - firstyear;
  1454. return yearX;
  1455. }
  1456. double TimeDataDmem::Get(int calender_year, int column) const {
  1457. int yearX = CalenderYearToPosition(calender_year);
  1458. if(currentCell >= 0 && column < nColumns)
  1459. return data[currentCell][yearX * nColumns + column];
  1460. else if(nCells == 1)
  1461. return data[0][yearX * nColumns + column];
  1462. else
  1463. return 0.0;
  1464. }
  1465. double TimeDataDmem::Get(int calender_year, const char* name) const {
  1466. int column = -1;
  1467. for(int i=0; i<nColumns; i++) {
  1468. if(!strcmp(name, header_arr[i])) {
  1469. column = i;
  1470. break;
  1471. }
  1472. }
  1473. if(column == -1) {
  1474. if(calender_year == firstyear) // firstyear set to -1 for static inputs
  1475. printf("WARNING: Value for %s not found in input file\n", name);
  1476. return NOTFOUND;
  1477. }
  1478. else {
  1479. return Get(calender_year, column);
  1480. }
  1481. }
  1482. bool TimeDataDmem::Load(Coord c) {
  1483. bool error = true;
  1484. double searchradius = min(spatial_resolution / 2.0, MAX_SEARCHRADIUS);
  1485. //In case gridlist cell order is same as in land use files
  1486. if(currentCell < (nCells - 1) && fabs(gridlist[currentCell+1].lon - c.lon) <= searchradius
  1487. && fabs(gridlist[currentCell+1].lat - c.lat) <= searchradius) {
  1488. currentCell++;
  1489. error = false;
  1490. }
  1491. else {
  1492. for(int i=0;i<nCells;i++) {
  1493. if(fabs(gridlist[i].lon - c.lon) <= searchradius && fabs(gridlist[i].lat - c.lat) <= searchradius) {
  1494. currentCell = i;
  1495. error = false;
  1496. break;
  1497. }
  1498. }
  1499. }
  1500. if(error) {
  1501. loaded = false;
  1502. }
  1503. else {
  1504. loaded = true;
  1505. }
  1506. return loaded;
  1507. }
  1508. void TimeDataDmem::SetData(int index, double* dataX) {
  1509. if(data && data[index])
  1510. memcpy(data[index], dataX, nColumns * nYears * sizeof(double));
  1511. }
  1512. void TimeDataDmem::SetCoord(int index, Coord c) {
  1513. gridlist[index].lon = c.lon;
  1514. gridlist[index].lat = c.lat;
  1515. }
  1516. void TimeDataDmem::Open(int nCellsX, int nColumnsX, int nYearsX) {
  1517. nCells = 0;
  1518. nColumns = nColumnsX;
  1519. nYears = nYearsX;
  1520. gridlist = new Coord[nCellsX];
  1521. data = new double*[nCellsX];
  1522. for(int i=0; i<nCellsX; i++) {
  1523. data[i] = new double[nColumns * nYears];
  1524. if(data[i]) {
  1525. for(int y=0;y<nColumns*nYears;y++)
  1526. data[i][y] = 0.0;
  1527. }
  1528. }
  1529. }
  1530. void TimeDataDmem::Close() {
  1531. nColumns = 0;
  1532. nYears = 0;
  1533. if(gridlist) {
  1534. delete []gridlist;
  1535. gridlist = NULL;
  1536. }
  1537. for(int i=0; i<nCells; i++) {
  1538. if(data[i])
  1539. delete[] data[i];
  1540. }
  1541. if(data) {
  1542. delete[] data;
  1543. data = NULL;
  1544. }
  1545. for(int i=0;i<MAXRECORDS;i++) {
  1546. if(header_arr[i]) {
  1547. delete[] header_arr[i];
  1548. header_arr[i] = NULL;
  1549. }
  1550. }
  1551. nCells = 0;
  1552. }
  1553. void TimeDataDmem::CopyFromTimeDataD(TimeDataD& Data, ListArray_id<Coord>& gridlistX) { //Requires gutil.h
  1554. int cell_no = 0;
  1555. for(int q=0;q<Data.GetnColumns();q++)
  1556. header_arr[q]=new char[MAXNAMESIZE];
  1557. if(Data.GetHeader(header_arr))
  1558. ifheader = true;
  1559. firstyear = Data.GetFirstyear();
  1560. spatial_resolution = Data.GetSpacialResolution();
  1561. double searchradius = min(spatial_resolution / 2.0, MAX_SEARCHRADIUS);
  1562. double offset = Data.GetOffset();
  1563. double *celldata;
  1564. celldata = new double[Data.GetnColumns() * Data.GetnYears()];
  1565. if(Data.GetFormat() == GLOBAL_STATIC) {
  1566. Data.Get(celldata);
  1567. SetData(0, celldata);
  1568. return;
  1569. }
  1570. gridlistX.firstobj();
  1571. while(Data.LoadNext() && cell_no < Data.GetNCells()) {
  1572. Coord c =Data.GetCoord();
  1573. double dif_lon;
  1574. double dif_lat;
  1575. unsigned int no = 0;
  1576. while(no < gridlistX.nobj) {
  1577. Coord cc = gridlistX.getobj();
  1578. // data coord close to gridlist coord ?
  1579. dif_lon = fabs(c.lon - (cc.lon + offset));
  1580. dif_lat = fabs(c.lat - (cc.lat + offset));
  1581. if(dif_lon <= searchradius && dif_lat <= searchradius) {
  1582. bool done = false;
  1583. double dif_lon_saved;
  1584. double dif_lat_saved;
  1585. for(int i=cell_no-1; i>=0;i--) {
  1586. // has data close to the gridlist coord already been saved ?
  1587. dif_lon_saved = fabs(gridlist[i].lon - (cc.lon + offset));
  1588. dif_lat_saved = fabs(gridlist[i].lat - (cc.lat + offset));
  1589. if(dif_lon_saved <= searchradius && dif_lat_saved <= searchradius) {
  1590. // is the new data coord closer to the gridlist coord than the already saved coord is ?
  1591. if((dif_lon_saved + dif_lat_saved) > (dif_lon + dif_lat)) { // This part is probably not needed
  1592. SetCoord(i, c);
  1593. Data.Get(celldata);
  1594. SetData(i, celldata);
  1595. }
  1596. done = true;
  1597. break; // from saved gridlist loop
  1598. }
  1599. }
  1600. if(!done) {
  1601. SetCoord(cell_no, c);
  1602. Data.Get(celldata);
  1603. SetData(cell_no, celldata);
  1604. cell_no++;
  1605. nCells++;
  1606. break; // from gridlist loop
  1607. }
  1608. }
  1609. gridlistX.nextobj();
  1610. no++;
  1611. if(!gridlistX.isobj)
  1612. gridlistX.firstobj();
  1613. }
  1614. }
  1615. delete[] celldata;
  1616. Data.register_memory_copy(this);
  1617. }
  1618. TimeDataDmem::TimeDataDmem() {
  1619. gridlist = NULL;
  1620. data = NULL;
  1621. nCells = 0;
  1622. ifheader = false;
  1623. for(int i=0;i<MAXRECORDS;i++) {
  1624. header_arr[i] = NULL;
  1625. }
  1626. currentCell = -1;
  1627. loaded = false;
  1628. }
  1629. TimeDataDmem::~TimeDataDmem() {
  1630. Close();
  1631. }