int f_set_ijval(ARG3) { struct local_struct { int ix, iy; float val; }; struct local_struct *save; int x,y; if (mode == -1) { decode = 1; *local = save = (struct local_struct *) malloc( sizeof(struct local_struct)); if (save == NULL) fatal_error("memory allocation f_ijval",""); save->ix = atoi(arg1) - 1; save->iy = atoi(arg2) - 1; save->val = atof(arg3); if (save->ix < 0) fatal_error_i("ijval: ix value (%d) should be >= 1", save->ix + 1); if (save->iy < 0) fatal_error_i("ijval: iy value (%d) should be >= 1", save->iy + 1); } if (mode < 0) return 0; save = (struct local_struct *) *local; x = save->ix; y = save->iy; if (GDS_Scan_staggered(scan)) fatal_error("ijval: does not support staggered grid",""); if (x < nx && y < ny) data[x + y*nx] = save->val; else fatal_error_ii("ijval: failed with problem with grid dimensions (%dx%d)",nx,ny); return 0; }
int cyclic(unsigned char **sec) { int grid_template, nx, ny, res, scan, flag_3_3, no_dx, basic_ang, sub_ang; unsigned int npnts; unsigned char *gds; double dlon, units, lon1, lon2; get_nxny(sec, &nx, &ny, &npnts, &res, &scan); if (GDS_Scan_staggered(scan)) return 0; if (nx <= 1 || ny <= 0) return 0; grid_template = code_table_3_1(sec); gds = sec[3]; flag_3_3 = flag_table_3_3(sec); no_dx = 0; if (flag_3_3 != -1) { if ((flag_3_3 & 0x20) == 0) no_dx = 1; } if (no_dx) return 0; if (grid_template == 0) { basic_ang = GDS_LatLon_basic_ang(gds); sub_ang = GDS_LatLon_sub_ang(gds); units = basic_ang == 0 ? 0.000001 : (double) basic_ang / (double) sub_ang; /* dlon has to be defined */ dlon = units * GDS_LatLon_dlon(gds); return (fabs(nx*dlon-360.0) < ERROR); } if (grid_template == 10) { if (output_order != wesn) return 0; // only works with we:sn order lon1 = GDS_Mercator_lon1(gds); lon2 = GDS_Mercator_lon2(gds); if (lon2 < lon1) lon2 += 360.0; dlon = (lon2-lon1)*nx/(nx-1.0); return (fabs(dlon-360.0) < ERROR); } if (grid_template == 40) { basic_ang = GDS_Gaussian_basic_ang(gds); sub_ang = GDS_Gaussian_sub_ang(gds); units = basic_ang == 0 ? 0.000001 : (double) basic_ang / (double) sub_ang; /* dlon has to be defined */ dlon = units * GDS_Gaussian_dlon(gds); return (fabs(nx*dlon-360.0) < ERROR); } return 0; }
int closest_init(unsigned char **sec) { int i, nnpts; double s, c; int grid_type; if (use_gctpc && output_order == wesn && nx > 0 && ny > 0) { if (gctpc_ll2xy_init(sec, lon, lat) == 0) return 0; } grid_type = code_table_3_1(sec); if (!GDS_Scan_staggered(scan) && nx > 0 && ny > 0) { /* if grids with (lat,lon) -> (i,j) insert code here */ if (grid_type == 0 && output_order == wesn) return latlon_init(sec, nx, ny); if (grid_type == 90 && output_order == wesn) return space_view_init(sec); } nnpts = (int) GB2_Sec3_npts(sec); if (x) { free(x); free(y); free(z); x = y = z = NULL; } if (lat && lon) { x = (double *) malloc(nnpts * sizeof(double)); y = (double *) malloc(nnpts * sizeof(double)); z = (double *) malloc(nnpts * sizeof(double)); if (x == NULL || y == NULL || z == NULL) fatal_error("memory allocation closest_init",""); #pragma omp parallel for private(i,s,c) schedule(static) for (i = 0; i < nnpts; i++) { if (lat[i] >= 999.0 || lon[i] >= 999.0) { /* x[i] = sin() .. cannot be bigger than 1 */ x[i] = y[i] = z[i] = 999.0; } else { s = sin(lat[i] * (M_PI / 180.0)); c = sqrt(1.0 - s * s); z[i] = s; x[i] = c * cos(lon[i] * (M_PI / 180.0)); y[i] = c * sin(lon[i] * (M_PI / 180.0)); } } } return 0; }
int f_set_ijval(ARG3) { size_t i; long int tmp; struct local_struct { unsigned int ix, iy; float val; }; struct local_struct *save; unsigned int x,y; if (mode == -1) { decode = 1; *local = save = (struct local_struct *) malloc( sizeof(struct local_struct)); if (save == NULL) fatal_error("memory allocation f_ijval",""); tmp = atol(arg1); if (tmp < 1) fatal_error_i("ijval: ix value (%d) should be >= 1", (int) tmp); save->ix = atol(arg1) - 1; tmp = atol(arg2); if (tmp < 1) fatal_error_i("ijval: iy value (%d) should be >= 1", (int) tmp); save->iy = atol(arg2) - 1; save->val = atof(arg3); } else if (mode == -2) { free(*local); } if (mode < 0) return 0; save = (struct local_struct *) *local; x = save->ix; y = save->iy; if (GDS_Scan_staggered(scan)) fatal_error("ijval: does not support staggered grid",""); i = x + y * (size_t) nx; if (i < ndata) data[i] = save->val; else fatal_error_uu("ijval: failed with (%ux%u)",x,y); return 0; }
int f_small_grib(ARG3) { struct local_struct { FILE *out; double lonE, lonW, latS, latN; }; struct local_struct *save; int ix0, ix1, iy0, iy1; if (mode == -1) { decode = latlon = 1; *local = save = (struct local_struct *)malloc( sizeof(struct local_struct)); if (save == NULL) fatal_error("small_grib memory allocation ",""); if (sscanf(arg1,"%lf:%lf", &(save->lonW), &(save->lonE)) != 2) fatal_error("small_grib: lonW:lonE = %s?", arg1); if (sscanf(arg2,"%lf:%lf", &(save->latS), &(save->latN)) != 2) fatal_error("small_grib: latS:latN = %s?", arg2); if ((save->out = ffopen(arg3, "wb")) == NULL) fatal_error("small_grib: could not open %s", arg3); if (save->latS > save->latN) fatal_error("small_grib: latS > latN",""); if (save->lonW > save->lonE) fatal_error("small_grib: lonW > lonE",""); } else if (mode == -2) { save = (struct local_struct *) *local; ffclose(save->out); free(save); return 0; } else if (mode >= 0) { save = (struct local_struct *) *local; if (GDS_Scan_staggered(scan)) fatal_error("small_grib: does not work for staggered grids",""); small_domain(sec, save->lonW,save->lonE,save->latS,save->latN, &ix0, &ix1, &iy0, &iy1); if (output_order != wesn) fatal_error("small_grib: data must be in we:sn order",""); small_grib(sec,mode,data,lon,lat, ndata,ix0,ix1,iy0,iy1,save->out); } return 0; }
int f_ijsmall_grib(ARG3) { struct local_struct { FILE *out; int ix0, iy0, ix1, iy1; }; struct local_struct *save; if (mode == -1) { decode = latlon = 1; *local = save = (struct local_struct *)malloc( sizeof(struct local_struct)); if (save == NULL) fatal_error("ijsmall_grib memory allocation ",""); if (sscanf(arg1,"%d:%d", &(save->ix0), &(save->ix1)) != 2) fatal_error("ijsmall_grib: ix0:ix1 = %s?", arg1); if (sscanf(arg2,"%d:%d", &(save->iy0), &(save->iy1)) != 2) fatal_error("ijsmall_grib: iy0:iy1 = %s?", arg2); if ((save->out = ffopen(arg3, "wb")) == NULL) fatal_error("ijsmall_grib: could not open %s", arg3); if (save->iy0 <= 0) fatal_error_i("ijsmall_grib: iy0=%d <= 0", save->iy0); if (save->iy0 > save->iy1) fatal_error("ijsmall_grib: iy0 > iy1",""); if (save->ix0 > save->ix1) fatal_error("ijsmall_grib: ix0 > ix1",""); } else if (mode == -2) { save = (struct local_struct *) *local; ffclose(save->out); free(save); } else if (mode >= 0) { save = (struct local_struct *) *local; if (output_order != wesn) fatal_error("ijsmall_grib: data must be in we:sn order",""); if (GDS_Scan_staggered(scan)) fatal_error("ijsmall_grib: does not work for staggered grids",""); small_grib(sec,mode,data,lon,lat, ndata,save->ix0,save->ix1,save->iy0,save->iy1,save->out); } return 0; }
int f_ijundefine(ARG3) { struct local_struct { int in; int ix0, ix1, iy0, iy1; }; struct local_struct *save; int x,y; int ix, iy; unsigned int i; int x0, x1, y0, y1, nyy, nxx; if (mode == -1) { decode = 1; *local = save = (struct local_struct *) malloc( sizeof(struct local_struct)); if (save == NULL) fatal_error("memory allocation f_undefine",""); if (strcmp("in-box", arg1) && strcmp("out-box", arg1)) { fatal_error("f_undefine expecting in-box/out-box not %s",arg1); } save->in =(strcmp("in-box", arg1) == 0); if (sscanf(arg2,"%d:%d", &x, &y) != 2) { fatal_error("undef: bad ix0:ix1 %s", arg2); } save->ix0 = x-1; save->ix1 = y-1; if (sscanf(arg3,"%d:%d", &x, &y) != 2) { fatal_error("undef: bad iy0:iy0 %s", arg3); } save->iy0 = x-1; save->iy1 = y-1; } if (mode < 0) return 0; save = (struct local_struct *) *local; x0 = save->ix0; x1 = save->ix1; y0 = save->iy0; y1 = save->iy1; if (GDS_Scan_staggered(scan)) fatal_error("ijundefine does not support staggered grids",""); nxx = nx > 0 ? nx : 1; nyy = ny > 0 ? ny : 1; if (save->in == 0) { i = 0; for (iy = 0; iy < nyy; iy++) { for (ix = 0; ix < nxx; ix++) { if (ix < x0 || ix > x1 || iy < y0 || iy > y1) data[i] = UNDEFINED; i++; } } } else { i = 0; for (iy = 0; iy < nyy; iy++) { for (ix = 0; ix < nxx; ix++) { if (ix >= x0 && ix <= x1 && iy >= y0 && iy <= y1) data[i] = UNDEFINED; i++; } } } return 0; }
int small_domain(unsigned char **sec, double lonW, double lonE, double latS, double latN, int *ix0, int *ix1, int *iy0, int *iy1) { int i, j, k, flag, x0, x1, y0, y1; int X0, X1, Y0, Y1, flag0; double e,w,n,s; double tmp; #ifdef DEBUG printf("\n>> small_domain: lon lat %f:%f %f:%f\n", lonW, lonE, latS, latN); #endif if (GDS_Scan_staggered(scan)) fatal_error("small_domain: does not work for staggered grids",""); if (lat == NULL || lon == NULL) { // no lat-lon information return full grid *ix0 = 1; *ix1 = nx; *iy0 = 1; *iy1 = ny; return 1; } if (lonE < lonW) lonE += 360.0; if (lonE-lonW > 360.0) fatal_error("small_domain: longitude range is greater than 360 degrees",""); if (lonW < 0.0) { lonW += 360.0; lonE += 360.0; } #ifdef DEBUG printf("\n>> small_domain: new lon lat %f:%f %f:%f\n", lonW, lonE, latS, latN); printf(">> small_domain: nx %d ny %d\n", nx, ny); #endif flag0 = 0; // initial point on grid X0 = 1; X1 = nx; Y0 = 1; Y1 = ny; #pragma omp parallel for private (i,j,k,flag,tmp,x0,x1,y0,y1,w,e,n,s) for (j = 1; j <= ny; j++) { x0 = x1 = y0 = y1 = w = e = s = n = -1; flag = 0; // initial point on latitude for (i = 1; i <= nx; i++) { k = (i-1) + (j-1)*nx; tmp = lon[k]; if (tmp < lonW) tmp += 360.0; if (tmp < lonW) tmp += 360.0; // tmp is lon > lon if ( (tmp <= lonE) && (lat[k] >= latS) && (lat[k] <= latN)) { // printf(">> small_domain: i %d j %d lon=%f lat=%f\n",i,j,tmp,lat[k]); if (flag == 0) { x0 = x1 = i; y0 = y1 = j; w = e = tmp; n = s = lat[k]; flag = 1; } if (lat[k] < s) { s = lat[k]; y0 = j; } if (lat[k] > n) { n = lat[k]; y1 = j; } if (tmp > e) { e = tmp; x1 = i; } if (tmp < w) { w = tmp; x0 = i; } } } #pragma omp critical if (flag) { // found points if (x1 < x0 && cyclic(sec)) x1 += nx; if (flag0 == 0) { X0 = x0; X1 = x1; Y0 = y0; Y1 = y1; flag0 = 1; } if (x0 < X0) X0 = x0; if (x1 > X1) X1 = x1; if (y0 < Y0) Y0 = y0; if (y1 > Y1) Y1 = y1; } } #ifdef DEBUG printf(">> small domain: flag0 %d flag %d\n", flag0, flag); #endif if (flag0 && X1 < X0) flag0 = 0; if (flag0 == 0) { *ix0 = 1; *ix1 = nx; *iy0 = 1; *iy1 = ny; return 1; } #ifdef DEBUG printf(">> small domain: ix %d:%d iy %d:%d\n", X0, X1, Y0, Y1); #endif *ix0 = X0; *ix1 = X1; *iy0 = Y0; *iy1 = Y1; return 0; }
int f_ijbox(ARG4) { int i1, i2, di, ni; int j1, j2, dj, nj; int i, j, k, nk, n; int x, y, nxny; struct Bbox *self; char open_mode[4]; /* -------------------- Initialization Phase -------------------- */ if (mode == -1) { decode = 1; /* parse arguments */ n = sscanf(arg1,"%d:%d:%d", &i1, &i2, &di); if (n < 2) fatal_error("ijbox parsing i-dimension, expecting i1:i2:di but got %s", arg1); if (n == 2) di = 1; n = sscanf(arg2,"%d:%d:%d", &j1,&j2,&dj); if (n < 2) fatal_error("ijbox parsing j-dimension, expecting j1:j2:dj but got %s", arg2); if (n == 2) dj = 1; if (strcmp(arg4,"spread") != 0 && strcmp(arg4,"text") != 0 && strcmp(arg4,"bin") != 0 ) fatal_error("ijbox bad write mode %s", arg4); strcpy(open_mode, file_append ? "a" : "w"); if (strcmp(arg4,"bin") == 0 || strcmp(arg4,"ieee") == 0 || /* ieee not implemented yet */ strcmp(arg4,"grib") == 0 ) /* grib not implemented yet */ strcat(open_mode,"b"); ni = 1 + (i2-i1)/di; nj = 1 + (j2-j1)/dj; i2 = i1 + (ni-1) * di; /* get real end point */ j2 = j1 + (nj-1) * dj; /* get real end point */ /* state holder */ self = (struct Bbox *)malloc( sizeof(struct Bbox)); if (self == NULL) fatal_error("ijbox memory allocation ",""); *local = self; /* initialize state*/ self->i1=i1; self->i2=i2; self->di=di; self->ni=ni; self->j1=j1; self->j2=j2; self->dj=dj; self->nj=nj; self->iptr = (int *) malloc(ni*((size_t) nj) * sizeof(int)); if (self->iptr == NULL) fatal_error("memory allocation in ijbox",""); if ((self->out = ffopen(arg3,open_mode)) == NULL) fatal_error("ijbox could not open output file %s", arg3); self->last_GDS_change_no = 0; return 0; } self = (struct Bbox *) *local; if (mode == -2) { ffclose(self->out); free(self->iptr); free(self); return 0; } /* ---------------- Processing Phase ---------------- */ i1 = self->i1; i2=self->i2; di=self->di; ni=self->ni; j1 = self->j1; j2=self->j2; dj=self->dj; nj=self->nj; nk = ni * nj; nxny = nx * ny; // printf("ni=%d:nj=%d:di=%d:dj=%d:",ni,nj,di,dj); /* check if grid changed */ if (self->last_GDS_change_no != GDS_change_no) { self->last_GDS_change_no = GDS_change_no; if (data == NULL) fatal_error("ijbox: no data",""); if (GDS_Scan_staggered(scan)) fatal_error("ijbox does not support staggered grids",""); /* record pointers, with wrapping */ k = 0; /* Note: (i,j) are fortran-style 1-offset arrays */ for (j = j1; j <= j2; j+=dj) { y = j - 1; for (i = i1; i <= i2; i+=di) { x = get_cindex (i, nx); n = x + y * nx; if (n < 0 || n >= nxny) fatal_error("ijbox invalid index", ""); self->iptr[k++] = n; } } } /* ----------- File Output ----------- */ /* Spreadsheet output */ if (strcmp(arg4,"spread") == 0) { fprintf(self->out, " i-index, j-index, value,\n"); for (k=0; k<nk; k++ ) { i = get_cindex(di*(k % ni) + i1, nx) + 1; j = dj*(k/ni) + j1; fprintf(self->out, "%d, %d, %g,\n", i,j,data[self->iptr[k]]); } /* binary output */ } else if (strcmp(arg4,"bin") == 0) { i = nk * sizeof(float); if (header) fwrite((void *) &i, sizeof(int), 1, self->out); for (k = 0; k < nk; k++) fwrite(data + self->iptr[k], sizeof(float), 1, self->out); if (header) fwrite((void *) &i, sizeof(int), 1, self->out); /* text output */ } else if (strcmp(arg4,"text") == 0) { if (header == 1) fprintf(self->out ,"%d %d\n", ni, nj); for (k = 0; k < nk; k++) { fprintf(self->out, text_format, data[self->iptr[k]]); fprintf(self->out, ((k+1) % text_column) ? " " : "\n"); } } /* out file type */ if (flush_mode) fflush(self->out); return 0; }