Sync netCDF modules with WRF
[WPS.git] / geogrid / util / retile-cat.c
blobc2b77f0c7ff16d8d39d59a62d519a5c1725931d9
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #include <unistd.h>
6 #include <math.h>
7 #include <string.h>
9 #define MSG_FLAG 0x80000001
11 #define N_BYTES 1
12 #define IN_TILE_DEGREES_LON 10.0
13 #define IN_TILE_DEGREES_LAT 10.0
14 #define IN_TILE_PTS_X 1200
15 #define IN_TILE_PTS_Y 1200
16 #define OUT_TILE_DEGREES_LON 20.0
17 #define OUT_TILE_DEGREES_LAT 20.0
18 #define OUT_TILE_PTS_X 600
19 #define OUT_TILE_PTS_Y 600
20 #define HALO_WIDTH 0
21 #define ZDIM 1
22 #define NCATS 24
23 #define CATMIN 1
25 #define CACHESIZE 12
27 int **** data_cache = NULL;
28 char ** fname_cache = NULL;
29 int * lru = NULL;
31 int *** supertile = NULL;
32 int supertile_min_x = 999999;
33 int supertile_min_y = 999999;
35 void free_newtile(int *** x)
37 int i, j, k;
39 for(i=0; i<IN_TILE_PTS_X; i++)
41 for(j=0; j<IN_TILE_PTS_Y; j++)
43 free(x[i][j]);
45 free(x[i]);
47 free(x);
50 int *** read_tile(char * fname)
52 int *** retval;
53 int i, j, k, b;
54 unsigned char buf[IN_TILE_PTS_X*IN_TILE_PTS_Y*ZDIM*N_BYTES];
55 int fd;
57 retval = (int ***)malloc(sizeof(int **)*IN_TILE_PTS_X);
58 for(i=0; i<IN_TILE_PTS_X; i++)
60 retval[i] = (int **)malloc(sizeof(int *)*IN_TILE_PTS_Y);
61 for(j=0; j<IN_TILE_PTS_Y; j++)
63 retval[i][j] = (int *)malloc(sizeof(int)*ZDIM);
67 if ((fd = open(fname,O_RDONLY)) == -1)
69 fprintf(stderr,"Error opening source file %s\n", fname);
70 return 0;
73 read(fd, (void *)&buf, IN_TILE_PTS_X*IN_TILE_PTS_Y*ZDIM*N_BYTES);
75 close(fd);
77 /* Put buf into retval */
78 for(i=0; i<IN_TILE_PTS_X; i++)
80 for(j=0; j<IN_TILE_PTS_Y; j++)
82 for(k=0; k<ZDIM; k++)
84 retval[i][j][k] = 0;
85 for(b=0; b<N_BYTES; b++)
87 retval[i][j][k] |= buf[k*N_BYTES*IN_TILE_PTS_X*IN_TILE_PTS_Y+j*N_BYTES*IN_TILE_PTS_X+i*N_BYTES+b] << 8*(N_BYTES-b-1);
93 return retval;
96 int *** get_tile_from_cache(int i, int j)
98 int ii, jj, kk, k, least, least_idx;
99 int *** retval, *** localptr;
100 char * fname;
102 fname = (char *)malloc(256);
104 i = (i/IN_TILE_PTS_X)*IN_TILE_PTS_X+1;
105 j = (j/IN_TILE_PTS_Y)*IN_TILE_PTS_Y+1;
107 snprintf(fname,256,"%5.5i-%5.5i.%5.5i-%5.5i",i,i+IN_TILE_PTS_X-1,j,j+IN_TILE_PTS_Y-1);
109 /* Find out whether tile containing (i,j) is in cache */
110 if (data_cache != NULL)
112 for(k=0; k<CACHESIZE; k++)
114 if (fname_cache[k] != NULL)
116 if (strncmp(fname_cache[k],fname,256) == 0)
118 free(fname);
119 retval = data_cache[k];
120 return retval;
126 /* If not, read from file */
127 localptr = read_tile(fname);
129 /* Also store tile in the cache */
130 if (data_cache == NULL)
132 data_cache = (int ****)malloc(sizeof(int ***)*CACHESIZE);
133 fname_cache = (char **)malloc(sizeof(char *)*CACHESIZE);
134 lru = (int *)malloc(sizeof(int)*CACHESIZE);
135 for(k=0; k<CACHESIZE; k++)
137 data_cache[k] = NULL;
138 fname_cache[k] = NULL;
139 lru[k] = 0;
143 least = 0;
144 least_idx = 0;
145 for(k=0; k<CACHESIZE; k++)
147 lru[k]++;
148 if (lru[k] > least)
150 least = lru[k];
151 least_idx = k;
155 if (data_cache[least_idx] == NULL)
157 data_cache[least_idx] = localptr;
158 fname_cache[least_idx] = fname;
159 lru[least_idx] = 0;
161 else
163 free_newtile(data_cache[least_idx]);
164 data_cache[least_idx] = localptr;
165 free(fname_cache[least_idx]);
166 fname_cache[least_idx] = fname;
167 lru[least_idx] = 0;
170 retval = localptr;
171 return retval;
174 void build_supertile(int i, int j)
176 int ii, jj, kk;
177 int doflip;
178 int *** newtile;
180 if (i < 0)
181 i = i + IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON);
182 if (i >= IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON))
183 i = i - IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON);
184 if (j < 0)
185 j = j + IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT);
186 if (j >= IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT))
187 j = j - IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT);
189 if (supertile == NULL)
191 supertile = (int ***)malloc(sizeof(int **)*3*IN_TILE_PTS_X);
192 for(ii=0; ii<3*IN_TILE_PTS_X; ii++)
194 supertile[ii] = (int **)malloc(sizeof(int *)*3*IN_TILE_PTS_Y);
195 for(jj=0; jj<3*IN_TILE_PTS_Y; jj++)
197 supertile[ii][jj] = (int *)malloc(sizeof(int)*ZDIM);
202 supertile_min_x = (i / IN_TILE_PTS_X)*IN_TILE_PTS_X;
203 supertile_min_y = (j / IN_TILE_PTS_Y)*IN_TILE_PTS_Y;
205 /* Get tile containing (i,j) from cache*/
206 /* Get surrounding tiles from cache */
208 /* Lower-left */
209 ii = i - IN_TILE_PTS_X;
210 if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
211 doflip = 0;
212 jj = j - IN_TILE_PTS_Y;
213 if (jj < 0)
215 doflip = 1;
216 jj = j;
217 ii -= (int)(180./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
218 if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
220 newtile = get_tile_from_cache(ii, jj);
221 if (doflip)
223 for(ii=0; ii<IN_TILE_PTS_X; ii++)
225 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
227 for(kk=0; kk<ZDIM; kk++)
228 supertile[ii][jj][kk] = newtile[ii][IN_TILE_PTS_Y-1-jj][kk];
232 else
234 for(ii=0; ii<IN_TILE_PTS_X; ii++)
236 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
238 for(kk=0; kk<ZDIM; kk++)
239 supertile[ii][jj][kk] = newtile[ii][jj][kk];
244 /* Left */
245 ii = i - IN_TILE_PTS_X;
246 if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
247 jj = j;
248 newtile = get_tile_from_cache(ii, jj);
249 for(ii=0; ii<IN_TILE_PTS_X; ii++)
251 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
253 for(kk=0; kk<ZDIM; kk++)
254 supertile[ii][jj+IN_TILE_PTS_Y][kk] = newtile[ii][jj][kk];
258 /* Upper-left */
259 ii = i - IN_TILE_PTS_X;
260 if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
261 doflip = 0;
262 jj = j + IN_TILE_PTS_Y;
263 if (jj >= (int)(180./IN_TILE_DEGREES_LAT)*IN_TILE_PTS_Y)
265 doflip = 1;
266 jj = j;
267 ii -= (int)(180./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
268 if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
270 newtile = get_tile_from_cache(ii, jj);
271 if (doflip)
273 for(ii=0; ii<IN_TILE_PTS_X; ii++)
275 for(jj=0; jj<IN_TILE_PTS_X; jj++)
277 for(kk=0; kk<ZDIM; kk++)
278 supertile[ii][jj+2*IN_TILE_PTS_Y][kk] = newtile[ii][IN_TILE_PTS_Y-1-jj][kk];
282 else
284 for(ii=0; ii<IN_TILE_PTS_X; ii++)
286 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
288 for(kk=0; kk<ZDIM; kk++)
289 supertile[ii][jj+2*IN_TILE_PTS_Y][kk] = newtile[ii][jj][kk];
294 /* Below */
295 ii = i;
296 doflip = 0;
297 jj = j - IN_TILE_PTS_Y;
298 if (jj < 0)
300 doflip = 1;
301 jj = j;
302 ii -= (int)(180./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
303 if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
305 newtile = get_tile_from_cache(ii, jj);
306 if (doflip)
308 for(ii=0; ii<IN_TILE_PTS_X; ii++)
310 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
312 for(kk=0; kk<ZDIM; kk++)
313 supertile[ii+IN_TILE_PTS_X][jj][kk] = newtile[ii][IN_TILE_PTS_Y-1-jj][kk];
317 else
319 for(ii=0; ii<IN_TILE_PTS_X; ii++)
321 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
323 for(kk=0; kk<ZDIM; kk++)
324 supertile[ii+IN_TILE_PTS_X][jj][kk] = newtile[ii][jj][kk];
329 /* Center */
330 newtile = get_tile_from_cache(i, j);
331 for(ii=0; ii<IN_TILE_PTS_X; ii++)
333 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
335 for(kk=0; kk<ZDIM; kk++)
336 supertile[ii+IN_TILE_PTS_X][jj+IN_TILE_PTS_Y][kk] = newtile[ii][jj][kk];
340 /* Above */
341 ii = i;
342 doflip = 0;
343 jj = j + IN_TILE_PTS_Y;
344 if (jj >= (int)(180./IN_TILE_DEGREES_LAT)*IN_TILE_PTS_Y)
346 doflip = 1;
347 jj = j;
348 ii -= (int)(180./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
349 if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
351 newtile = get_tile_from_cache(ii, jj);
352 if (doflip)
354 for(ii=0; ii<IN_TILE_PTS_X; ii++)
356 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
358 for(kk=0; kk<ZDIM; kk++)
359 supertile[ii+IN_TILE_PTS_X][jj+2*IN_TILE_PTS_Y][kk] = newtile[ii][IN_TILE_PTS_Y-1-jj][kk];
363 else
365 for(ii=0; ii<IN_TILE_PTS_X; ii++)
367 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
369 for(kk=0; kk<ZDIM; kk++)
370 supertile[ii+IN_TILE_PTS_X][jj+2*IN_TILE_PTS_Y][kk] = newtile[ii][jj][kk];
375 /* Lower-right */
376 ii = i + IN_TILE_PTS_X;
377 if (ii >= (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X) ii -= (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
378 doflip = 0;
379 jj = j - IN_TILE_PTS_Y;
380 if (jj < 0)
382 doflip = 1;
383 jj = j;
384 ii -= (int)(180./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
385 if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
387 newtile = get_tile_from_cache(ii, jj);
388 if (doflip)
390 for(ii=0; ii<IN_TILE_PTS_X; ii++)
392 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
394 for(kk=0; kk<ZDIM; kk++)
395 supertile[ii+2*IN_TILE_PTS_X][jj][kk] = newtile[ii][IN_TILE_PTS_Y-1-jj][kk];
399 else
401 for(ii=0; ii<IN_TILE_PTS_X; ii++)
403 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
405 for(kk=0; kk<ZDIM; kk++)
406 supertile[ii+2*IN_TILE_PTS_X][jj][kk] = newtile[ii][jj][kk];
411 /* Right */
412 ii = i + IN_TILE_PTS_X;
413 if (ii >= (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X) ii -= (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
414 jj = j;
415 newtile = get_tile_from_cache(ii, jj);
416 for(ii=0; ii<IN_TILE_PTS_X; ii++)
418 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
420 for(kk=0; kk<ZDIM; kk++)
421 supertile[ii+2*IN_TILE_PTS_X][jj+IN_TILE_PTS_Y][kk] = newtile[ii][jj][kk];
425 /* Upper-right */
426 ii = i + IN_TILE_PTS_X;
427 if (ii >= (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X) ii -= (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
428 doflip = 0;
429 jj = j + IN_TILE_PTS_Y;
430 if (jj >= (int)(180./IN_TILE_DEGREES_LAT)*IN_TILE_PTS_Y)
432 doflip = 1;
433 jj = j;
434 ii -= (int)(180./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
435 if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X;
437 newtile = get_tile_from_cache(ii, jj);
438 if (doflip)
440 for(ii=0; ii<IN_TILE_PTS_X; ii++)
442 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
444 for(kk=0; kk<ZDIM; kk++)
445 supertile[ii+2*IN_TILE_PTS_X][jj+2*IN_TILE_PTS_Y][kk] = newtile[ii][IN_TILE_PTS_Y-1-jj][kk];
449 else
451 for(ii=0; ii<IN_TILE_PTS_X; ii++)
453 for(jj=0; jj<IN_TILE_PTS_Y; jj++)
455 for(kk=0; kk<ZDIM; kk++)
456 supertile[ii+2*IN_TILE_PTS_X][jj+2*IN_TILE_PTS_Y][kk] = newtile[ii][jj][kk];
462 void get_value(int * num_cats, int i, int j, int k, int irad)
464 int i_src, j_src;
465 int ii, jj;
466 int n, sum;
467 float r_rel;
469 if (i < 0)
470 i = i + IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON);
471 if (i >= IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON))
472 i = i - IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON);
473 if (j < 0)
474 j = j + IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT);
475 if (j >= IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT))
476 j = j - IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT);
478 i_src = i % IN_TILE_PTS_X + IN_TILE_PTS_X;
479 j_src = j % IN_TILE_PTS_Y + IN_TILE_PTS_Y;
481 /* Interpolate values from supertile */
482 for(ii=0; ii<NCATS; ii++)
483 num_cats[ii] = 0;
485 for(ii=i_src-irad; ii<=i_src+irad; ii++)
487 for(jj=j_src-irad; jj<=j_src+irad; jj++)
489 num_cats[supertile[ii][jj][k]-CATMIN]++;
493 sum = 0;
494 n = 0;
495 for(ii=i_src-irad; ii<=i_src+irad; ii++)
497 for(jj=j_src-irad; jj<=j_src+irad; jj++)
499 sum += supertile[i_src][j_src][k];
500 n++;
504 if (n > 0) return sum/n;
505 else return 0;
509 int is_in_supertile(int i, int j)
511 if (i < 0)
512 i = i + IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON);
513 if (i >= IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON))
514 i = i - IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON);
515 if (j < 0)
516 j = j + IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT);
517 if (j >= IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT))
518 j = j - IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT);
520 /* Check whether (i,j) is in the interior of supertile */
521 if ((i >= supertile_min_x) && (i < supertile_min_x+IN_TILE_PTS_X) &&
522 (j >= supertile_min_y) && (j < supertile_min_y+IN_TILE_PTS_Y))
523 return 1;
524 else
525 return 0;
528 int main(int argc, char ** argv)
530 int tile_x, tile_y, input_x, input_y, temp_x, temp_y, temp;
531 int i, j, k, z, ii, jj;
532 int i_src, j_src;
533 int *** intdata;
534 int * num_cats;
535 int out_fd;
536 int ir_rel;
537 float r_rel;
538 unsigned char * outdata;
539 char out_filename[256];
541 r_rel = (float)IN_TILE_PTS_X/(float)OUT_TILE_PTS_X*OUT_TILE_DEGREES_LON/IN_TILE_DEGREES_LON;
542 ir_rel = (int)rint(r_rel);
544 /* Allocate memory to hold a single output tile */
545 intdata = (int ***)malloc(sizeof(int **)*(OUT_TILE_PTS_X+2*HALO_WIDTH));
546 for(i=0; i<(OUT_TILE_PTS_X+2*HALO_WIDTH); i++)
548 intdata[i] = (int **)malloc(sizeof(int *)*(OUT_TILE_PTS_Y+2*HALO_WIDTH));
549 for(j=0; j<(OUT_TILE_PTS_Y+2*HALO_WIDTH); j++)
551 intdata[i][j] = (int *)malloc(sizeof(int)*ZDIM);
555 num_cats = (int *)malloc(sizeof(int)*NCATS);
557 /* Allocate output buffer */
558 outdata = (unsigned char *)malloc((OUT_TILE_PTS_X+2*HALO_WIDTH)*(OUT_TILE_PTS_Y+2*HALO_WIDTH)*ZDIM*N_BYTES);
560 for(tile_x=0; tile_x<OUT_TILE_PTS_X*(int)(360.0/OUT_TILE_DEGREES_LON); tile_x+=OUT_TILE_PTS_X)
562 for(tile_y=0; tile_y<OUT_TILE_PTS_Y*(int)(180.0/OUT_TILE_DEGREES_LAT); tile_y+=OUT_TILE_PTS_Y)
564 /* Build name of output file for current tile_x and tile_y */
565 sprintf(out_filename,"retiled/%5.5i-%5.5i.%5.5i-%5.5i",tile_x+1,tile_x+OUT_TILE_PTS_X,tile_y+1,tile_y+OUT_TILE_PTS_Y);
567 /* Initialize the output data for current tile */
568 for(i=0; i<(OUT_TILE_PTS_X+2*HALO_WIDTH); i++)
570 for(j=0; j<(OUT_TILE_PTS_Y+2*HALO_WIDTH); j++)
572 intdata[i][j][0] = MSG_FLAG;
576 /* Attempt to open output file */
577 if ((out_fd = open(out_filename, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1)
579 fprintf(stderr, "Error: Could not create or open file %s\n", out_filename);
580 return 1;
583 /* Fill tile with data */
584 for(i=-1*HALO_WIDTH; i<OUT_TILE_PTS_X+HALO_WIDTH; i++)
586 for(j=-1*HALO_WIDTH; j<OUT_TILE_PTS_Y+HALO_WIDTH; j++)
588 if (intdata[i+HALO_WIDTH][j+HALO_WIDTH][0] == MSG_FLAG)
590 i_src = ir_rel*(tile_x+i);
591 j_src = ir_rel*(tile_y+j);
593 build_supertile(i_src,j_src);
595 for(ii=-1*HALO_WIDTH; ii<OUT_TILE_PTS_X+HALO_WIDTH; ii++)
597 for(jj=-1*HALO_WIDTH; jj<OUT_TILE_PTS_Y+HALO_WIDTH; jj++)
599 i_src = ir_rel*(tile_x+ii);
600 j_src = ir_rel*(tile_y+jj);
601 if (is_in_supertile(i_src,j_src))
603 get_value(num_cats, i_src, j_src, 0, ir_rel-1);
604 intdata[ii+HALO_WIDTH][jj+HALO_WIDTH][0] = CATMIN-1;
605 temp = 0;
606 for(k=0; k<NCATS; k++)
608 if (num_cats[k] >= temp)
610 temp = num_cats[k];
611 intdata[ii+HALO_WIDTH][jj+HALO_WIDTH][0] = k+CATMIN;
622 /* Write out the data */
623 for(i=0; i<(OUT_TILE_PTS_X+2*HALO_WIDTH); i++)
625 for(j=0; j<(OUT_TILE_PTS_Y+2*HALO_WIDTH); j++)
627 for(z=0; z<ZDIM; z++)
629 for(k=0; k<N_BYTES; k++)
631 outdata[z*N_BYTES*(OUT_TILE_PTS_Y+2*HALO_WIDTH)*(OUT_TILE_PTS_X+2*HALO_WIDTH)+j*N_BYTES*(OUT_TILE_PTS_X+2*HALO_WIDTH)+i*N_BYTES+k] =
632 (intdata[i][j][z] & (0xff << 8*(N_BYTES-k-1))) >> (8*(N_BYTES-k-1));
637 write(out_fd,(void *)outdata,(OUT_TILE_PTS_X+2*HALO_WIDTH)*(OUT_TILE_PTS_Y+2*HALO_WIDTH)*ZDIM*N_BYTES);
638 close(out_fd);
639 printf("Wrote file %s\n",out_filename);
643 free(num_cats);
645 /* Deallocate memory */
646 for(i=0; i<(OUT_TILE_PTS_X+2*HALO_WIDTH); i++)
648 for(j=0; j<(OUT_TILE_PTS_Y+2*HALO_WIDTH); j++)
650 free(intdata[i][j]);
652 free(intdata[i]);
654 free(intdata);
657 return 0;