gdrsclib
datastruct.c
Go to the documentation of this file.
1 /***************************************************
2 Apache License Version 2.0
3 
4 Copyright 2007-2011 EcoEquity and Stockholm Environment Institute
5 
6 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
7 file except in compliance with the License. You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11 Unless required by applicable law or agreed to in writing, software distributed under
12 the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 KIND, either express or implied. See the License for the specific language governing
14 permissions and limitations under the License.
15 ****************************************************/
16 
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <math.h>
24 #include "datastruct.h"
25 #ifdef DMALLOC
26 #include <dmalloc.h>
27 #endif
28 
29 
40 int getdata(char *fname, struct datablock *dblock, struct appdata ad) {
41  FILE *fp;
42  char iso3[4];
43  int numrecs, row, col, ncol, retval;
44  float x;
45 
46  if((fp = fopen(fname, "r")) == NULL) {
47  return DBLOCK_FREADERROR;
48  }
49 
50  /* This is where it reads it in */
51  fscanf(fp, "%d%d%d", &dblock->y_start, &dblock->y_end, &numrecs);
52  if (numrecs != ad.numrecs) {
53  fclose(fp);
54  return DBLOCK_NRECMISMATCH;
55  }
56 
57  if ((retval = allocdata(dblock, ad))) {
58  fclose(fp);
59  return retval;
60  }
61  ncol = dblock->y_end - dblock->y_start + 1;
62 
63  for (row = 0; row < numrecs; row++) {
64  fscanf(fp, "%s", iso3); // Don't use this
65  for (col = 0; col < ncol; col++) {
66  fscanf(fp, "%f", &x);
67  dblock->data[row * ncol + col] = x;
68  }
69  }
70 
71  if (fclose(fp)) {
72  return DBLOCK_FCLOSEERROR;
73  }
74 
75  return DBLOCK_OK;
76 }
77 
90 int getff(char *fname, struct fixedfactor *ff, char **name, int datacol, struct appdata ad) {
91  FILE *fp;
92  char iso3[4], linebuff[8192], *namebuff;
93  int row, col, retval, ncols, numrecs;
94  float x;
95 
96  if((fp = fopen(fname, "r")) == NULL) {
97  return DBLOCK_FREADERROR;
98  }
99 
100  // This is where it reads it in
101  fscanf(fp, "%d%d", &ncols, &numrecs);
102  if (numrecs != ad.numrecs) {
103  fclose(fp);
104  return DBLOCK_NRECMISMATCH;
105  }
106 
107  if ((retval = allocff(ff, ad))) {
108  fclose(fp);
109  return retval;
110  }
111 
112  // Get the name (assume tabs as separator character, to allow spaces in names)
113  fgetc(fp); // First skip the newline at the end of the current line
114  fgets(linebuff, 8192, fp);
115  namebuff = strtok(linebuff, "\t"); // Ignore the first entry (iso3 code)
116  for (col = 0; col < ncols; col++) {
117  namebuff = strtok(NULL, "\t");
118  if (col == datacol) {
119  *name = strdup(namebuff);
120  break;
121  }
122  }
123 
124  for (row = 0; row < numrecs; row++) {
125  fscanf(fp, "%s", iso3); // Don't use this
126  for (col = 0; col < ncols; col++) {
127  fscanf(fp, "%f", &x);
128  if (col == datacol) {
129  ff->data[row] = x;
130  }
131  }
132  }
133 
134  if (fclose(fp)) {
135  return DBLOCK_FCLOSEERROR;
136  }
137 
138  return DBLOCK_OK;
139 }
140 
150 int getts(char *fname, struct timeseries *ts, struct appdata ad) {
151  FILE *fp;
152  int line, nlines, retval;
153  float x;
154 
155  if((fp = fopen(fname, "r")) == NULL) {
156  return DBLOCK_FREADERROR;
157  }
158 
159  /* This is where it reads it in */
160  fscanf(fp, "%d%d", &ts->y_start, &ts->y_end);
161 
162  if ((retval = allocts(ts, ad))) {
163  fclose(fp);
164  return retval;
165  }
166  nlines = ts->y_end - ts->y_start + 1;
167 
168  for (line = 0; line < nlines; line++) {
169  fscanf(fp, "%f", &x);
170  ts->data[line] = x;
171  }
172 
173  if (fclose(fp)) {
174  return DBLOCK_FCLOSEERROR;
175  }
176 
177  return DBLOCK_OK;
178 
179 }
180 
190 void data2ff(struct datablock dblock, struct fixedfactor ff, int year, struct appdata ad) {
191  int i;
192 
193  for (i = 0; i < ad.numrecs; i++) {
194  ff.data[i] = getval(dblock, i, year, ad);
195  }
196 }
197 
207 void ff2data(struct fixedfactor ff, struct datablock dblock, int year, struct appdata ad) {
208  int i;
209 
210  for (i = 0; i < ad.numrecs; i++) {
211  setval(dblock, ff.data[i], i, year, ad);
212  }
213 }
214 
223 int allocdata(struct datablock *dblock, struct appdata ad) {
224  int ncol, dblock_size, i;
225 
226  ncol = dblock->y_end - dblock->y_start + 1;
227 
228  if (ncol <= 0) {
229  return DBLOCK_BADYEARS;
230  }
231 
232  // A numrecs x year sized block
233  dblock_size = ad.numrecs * ncol;
234  dblock->data = malloc(dblock_size * sizeof(double));
235  if (!dblock->data) {
236  return DBLOCK_NOMEM;
237  }
238  // Initialize to NaN
239  for (i = 0; i < dblock_size; i++) {
240  dblock->data[i] = NAN;
241  }
242 
243  return DBLOCK_OK;
244 }
245 
254 int allocff(struct fixedfactor *ff, struct appdata ad) {
255  int i;
256 
257  // A numrecs-sized block
258  ff->data = malloc(ad.numrecs * sizeof(double));
259  if (!ff->data) {
260  return DBLOCK_NOMEM;
261  }
262  // Initialize to NaN
263  for (i = 0; i < ad.numrecs; i++) {
264  ff->data[i] = NAN;
265  }
266 
267  return DBLOCK_OK;
268 }
269 
278 int allocts(struct timeseries *ts, struct appdata ad) {
279  int ncol, i;
280 
281  // A years-sized block
282  ncol = ts->y_end - ts->y_start + 1;
283 
284  if (ncol <= 0) {
285  return DBLOCK_BADYEARS;
286  }
287 
288  ts->data = malloc(ncol * sizeof(double));
289  if (!ts->data) {
290  return DBLOCK_NOMEM;
291  }
292  // Initialize to NaN
293  for (i = 0; i < ncol; i++) {
294  ts->data[i] = NAN;
295  }
296  return DBLOCK_OK;
297 
298 }
299 
305 void cleardata(struct datablock dblock) {
306  free(dblock.data);
307 }
308 
314 void clearff(struct fixedfactor ff) {
315  free(ff.data);
316 }
317 
323 void clearts(struct timeseries ts) {
324  free(ts.data);
325 }
326 
337 int writedb2delim(struct datablock dblock, char *fname, char delim, struct appdata ad) {
338  FILE *fp;
339  int i, year;
340 
341  if((fp = fopen(fname, "w")) == NULL) {
342  return DBLOCK_FREADERROR;
343  }
344 
345  for (year = dblock.y_start; year < dblock.y_end; year++) {
346  fprintf(fp, "%d%c", year, delim);
347  }
348  fprintf(fp, "%d\n", year);
349 
350  for (i = 0; i < ad.numrecs; i++) {
351  for (year = dblock.y_start; year < dblock.y_end; year++) {
352  fprintf(fp, "%f%c", getval(dblock, i, year, ad), delim);
353  }
354  fprintf(fp, "%f\n", getval(dblock, i, year, ad));
355  }
356 
357  if (fclose(fp)) {
358  return DBLOCK_FCLOSEERROR;
359  }
360 
361  return DBLOCK_OK;
362 }
363 
374 int writets2delim(struct timeseries ts, char * fname, char delim, struct appdata ad) {
375  FILE *fp;
376  int year;
377 
378  if((fp = fopen(fname, "w")) == NULL) {
379  return DBLOCK_FREADERROR;
380  }
381 
382  for (year = ts.y_start; year < ts.y_end; year++) {
383  fprintf(fp, "%d%c%f\n", year, delim, gettsval(ts, year, ad));
384  }
385 
386  if (fclose(fp)) {
387  return DBLOCK_FCLOSEERROR;
388  }
389 
390  return DBLOCK_OK;
391 }
392 
403 int writeff2delim(struct fixedfactor ff, char * fname, char delim, struct appdata ad) {
404  FILE *fp;
405  int i;
406 
407  if((fp = fopen(fname, "w")) == NULL) {
408  return DBLOCK_FREADERROR;
409  }
410 
411  for (i = 0; i < ad.numrecs; i++) {
412  fprintf(fp, "%f\n", ff.data[i]);
413  }
414 
415  if (fclose(fp)) {
416  return DBLOCK_FCLOSEERROR;
417  }
418 
419  return DBLOCK_OK;
420 }
421 
422 
432 double getval(struct datablock db, int row, int year, struct appdata ad) {
433  if (row > ad.numrecs - 1) {
434  return NAN;
435  }
436 
437  if (year < db.y_start || year > db.y_end) {
438  return NAN;
439  }
440 
441  return db.data[(db.y_end - db.y_start + 1) * row + year - db.y_start];
442 }
443 
454 void setval(struct datablock db, double val, int row, int year, struct appdata ad) {
455  if (row > ad.numrecs - 1) {
456  return;
457  }
458 
459  if (year < db.y_start || year > db.y_end) {
460  return;
461  }
462 
463  db.data[(db.y_end - db.y_start + 1) * row + year - db.y_start] = val;
464 }
465 
474 double gettsval(struct timeseries ts, int year, struct appdata ad) {
475  if (year < ts.y_start || year > ts.y_end) {
476  return NAN;
477  }
478 
479  return ts.data[year - ts.y_start];
480 }
481 
491 void settsval(struct timeseries ts, double val, int year, struct appdata ad) {
492  if (year < ts.y_start || year > ts.y_end) {
493  return;
494  }
495 
496  ts.data[year - ts.y_start] = val;
497 }
498 
507 double getffval(struct fixedfactor ff, int row, struct appdata ad) {
508  if ((row > ad.numrecs - 1) || (row < 0)) {
509  return NAN;
510  }
511 
512  return ff.data[row];
513 }
514 
524 void setffval(struct fixedfactor ff, double val, int row, struct appdata ad) {
525  if ((row > ad.numrecs - 1) || (row < 0)) {
526  return;
527  }
528 
529  ff.data[row] = val;
530 }
For the application, basic dimensions: number of countries and bounding years.
Definition: datastruct.h:48
int y_start
The start year.
Definition: datastruct.h:60
int getts(char *fname, struct timeseries *ts, struct appdata ad)
Read a timeseries from a formatted file.
Definition: datastruct.c:150
void ff2data(struct fixedfactor ff, struct datablock dblock, int year, struct appdata ad)
Put the values for a particular year into a datablock.
Definition: datastruct.c:207
#define DBLOCK_BADYEARS
Definition: datastruct.h:41
int writets2delim(struct timeseries ts, char *fname, char delim, struct appdata ad)
Convenience function to dump a timeseries to a file.
Definition: datastruct.c:374
A one-dimensional array that contains information on countries that is the same for all years...
Definition: datastruct.h:84
int numrecs
Number of records (i.e., number of countries)
Definition: datastruct.h:49
int y_end
The end year.
Definition: datastruct.h:95
double * data
The array, dimensioned (y_start - y_end + 1) * ad.numrecs when created.
Definition: datastruct.h:62
int y_end
The end year.
Definition: datastruct.h:61
A one-dimensional array that contains global information that is the same for all countries...
Definition: datastruct.h:93
void data2ff(struct datablock dblock, struct fixedfactor ff, int year, struct appdata ad)
Get all values for a particular year from a datablock.
Definition: datastruct.c:190
double getffval(struct fixedfactor ff, int row, struct appdata ad)
Get a value for a specified row (country) from a fixedfactor.
Definition: datastruct.c:507
void clearts(struct timeseries ts)
Free the memory taken up by a timeseries.
Definition: datastruct.c:323
#define DBLOCK_OK
Definition: datastruct.h:36
int getdata(char *fname, struct datablock *dblock, struct appdata ad)
Read a datablock from a formatted file.
Definition: datastruct.c:40
double gettsval(struct timeseries ts, int year, struct appdata ad)
Get the value for a particular year from a timeseries.
Definition: datastruct.c:474
int getff(char *fname, struct fixedfactor *ff, char **name, int datacol, struct appdata ad)
Read a fixedfactor from a formatted file.
Definition: datastruct.c:90
void setffval(struct fixedfactor ff, double val, int row, struct appdata ad)
Set a value for a specified row (country) for a fixedfactor.
Definition: datastruct.c:524
int allocdata(struct datablock *dblock, struct appdata ad)
Create a datablock in memory, using application-specific dimensions.
Definition: datastruct.c:223
#define DBLOCK_NRECMISMATCH
Definition: datastruct.h:40
#define DBLOCK_FREADERROR
Definition: datastruct.h:37
void settsval(struct timeseries ts, double val, int year, struct appdata ad)
Set the value for a particular year in a timeseries.
Definition: datastruct.c:491
void cleardata(struct datablock dblock)
Free the memory taken up by a datablock.
Definition: datastruct.c:305
double getval(struct datablock db, int row, int year, struct appdata ad)
Get the data value from the datablock for specified row & year.
Definition: datastruct.c:432
void clearff(struct fixedfactor ff)
Free the memory taken up by a fixedfactor.
Definition: datastruct.c:314
int allocff(struct fixedfactor *ff, struct appdata ad)
Create a fixedfactor in memory, of length = number of countries.
Definition: datastruct.c:254
double * data
The array, length = ad.numrecs when created.
Definition: datastruct.h:85
int writedb2delim(struct datablock dblock, char *fname, char delim, struct appdata ad)
Convenience function to dump a datablock to a file.
Definition: datastruct.c:337
int allocts(struct timeseries *ts, struct appdata ad)
Create a timeseries in memory, of length = y_start - y_end + 1.
Definition: datastruct.c:278
#define DBLOCK_NOMEM
Definition: datastruct.h:39
double * data
The data, length = y_start - y_end + 1 when created.
Definition: datastruct.h:96
#define DBLOCK_FCLOSEERROR
Definition: datastruct.h:38
int y_start
The start year.
Definition: datastruct.h:94
A two-dimensional array that contains information for country/year combinations.
Definition: datastruct.h:59
int writeff2delim(struct fixedfactor ff, char *fname, char delim, struct appdata ad)
Convenience function to dump a fixedfactor to a file.
Definition: datastruct.c:403
void setval(struct datablock db, double val, int row, int year, struct appdata ad)
Set a specific value in a datablock, specified by row and year.
Definition: datastruct.c:454