Esempio n. 1
0
int f_grib_out_irr(ARG2) {

    float *data_tmp;
    int all, i, j;
    unsigned int n;
    unsigned char *gds, *old_gds, *p;

    if (mode == -1) {
        latlon = decode = 1;
	if (strcmp(arg1,"defined") && strcmp(arg1,"all")) fatal_error("grib_out_irr: %s should be all or defined", arg1);
	*local = (void *) ffopen(arg2, file_append? "ab" : "wb" );
        if (*local == NULL) fatal_error("Could not open %s", arg2);
	return 0;
    }

    if (mode == -2) {
	ffclose((FILE *) *local);
	return 0;
    }

    if (lat == NULL || lon == NULL) fatal_error("grid_out_irr: failed, no lat-lon information","");

    all = strcmp(arg1,"all") == 0;
    if (all) {
	n = ndata;
    }
    else {
	for (i = n = 0; i < ndata; i++) {
	    if (DEFINED_VAL(data[i])) n++;
	}
    }

    if (n == 0) {
	fprintf(stderr,"grib_out_irr: no grid points to write out, no write\n");
	return 0;
    }

    if ((gds = (unsigned char *) malloc(n * 8 + 30)) == NULL) fatal_error("grib_out_irr: memory allocation","");
    if ((data_tmp = (float *) malloc(n* sizeof(float))) == NULL) fatal_error("grib_out_irr: memory allocation","");

    /* sec3 = grid defintion */
    uint_char(30+n*8, gds);
    gds[4] = 3;            // sec3
    gds[5] = 0;            // use table 3.1
    uint_char(n, gds+6);
    gds[10] = 0;           // no optional list octets
    gds[11] = 0;
    uint2_char(130, gds+12);

    p = code_table_3_2_location(sec);
    if (p == NULL) {  // no earth descripition
        for (i = 14; i < 30; i++) {
            gds[i] = 255;
        }
    }
    else {
        for (i = 14; i < 30; i++) {
            gds[i] = p[i-14];
        }
    }

    if (all) {
	for (i = 0; i < ndata; i++) {
	    int_char( (int) (lat[i] * 1000000.0), gds + 30 + i*8);
	    int_char( (int) (lon[i] * 1000000.0), gds + 34 + i*8);
	    data_tmp[i] = data[i];
	}
    }
    else {
	for (j = i = 0; i < ndata; i++) {
	    if (DEFINED_VAL(data[i])) {
	        int_char( (int) (lat[i] * 1000000.0), gds + 30 + j*8);
	        int_char( (int) (lon[i] * 1000000.0), gds + 34 + j*8);
	        data_tmp[j++] = data[i];
	    }
	}
    }

    old_gds = sec[3];
    sec[3] = gds;
    grib_wrt(sec, data_tmp, n, n, 1, use_scale, dec_scale, 
		bin_scale, wanted_bits, max_bits, grib_type, (FILE *) *local);
    sec[3] = old_gds;
    if (flush_mode) fflush((FILE *) *local);

    free(data_tmp);
    free(gds);

    return 0;
}
Esempio n. 2
0
int f_lola(ARG4) {

    int nx, ny, j, k;
    int i, nxny;
    double latitude, longitude;
    double x0,dx, y0,dy;
    unsigned char *new_sec[8];
    float *tmp, t;

    struct local_struct {
        int nlat, nlon;
        double lat0, lon0, dlat, dlon;
        FILE *out;
        int *iptr;
    };
    struct local_struct *save;
    char open_mode[4];

    /* initialization phase */

    if (mode == -1) {
        decode = latlon = 1;
        if (sscanf(arg1,"%lf:%d:%lf", &x0, &nx, &dx) != 3) {
            fatal_error("lola parsing longitudes lon0:nx:dlon  %s", arg1);
        }
        if (sscanf(arg2,"%lf:%d:%lf", &y0,&ny,&dy) != 3) {
            fatal_error("lola parsing latitudes lat0:nx:dlat  %s", arg2);
        }

        if (strcmp(arg4,"spread") != 0 
                && strcmp(arg4,"text") != 0 
                && strcmp(arg4,"grib") != 0
                && strcmp(arg4,"bin") != 0) fatal_error("lola bad write mode %s", arg4);

	if (strcmp(arg4,"grib") == 0 && (dx <= 0 || dy <= 0))
		fatal_error("lola parsing, for grib dlat > 0 and dlon > 0","");

        strcpy(open_mode, file_append ? "a" : "w");
        if (strcmp(arg4,"bin") == 0 || strcmp(arg4,"grib") == 0) strcat(open_mode,"b");

        nxny = nx*ny;
        *local = save = (struct local_struct *)malloc( sizeof(struct local_struct));
        if (save == NULL) fatal_error("lola memory allocation ","");
	if (x0 < 0.0) x0 += 360.0;
	if (x0 >= 360.0) x0 -= 360.0;
	if (x0 < 0.0 || x0 >= 360.0) fatal_error("-lola: bad initial longitude","");
	if (nx <= 0) fatal_error_i("-lola: bad nlon %d", nx);
        save->nlon = nx;
        save->lon0 = x0;
        save->dlon = dx;

	if (y0 < -90.0 || y0 > 90.0) fatal_error("-lola: bad initial latitude","");
	if (ny <= 0) fatal_error_i("-lola: bad nlat %d", ny);
        save->nlat = ny;
        save->lat0 = y0;
        save->dlat = dy;
        save->iptr = (int *) malloc(nx*ny * sizeof(int));
	if (save->iptr == NULL) fatal_error("-lola: memory allocation","");
        if ((save->out = ffopen(arg3,open_mode)) == NULL) 
              fatal_error("lola could not open file %s", arg3);
        return 0;
    }

    /* cleanup phase */

    if (mode == -2) return 0;

    /* processing phase */

    save = *local;
    nx = save->nlon;
    ny = save->nlat;
    nxny = nx*ny;

    if (new_GDS) {

        // if (output_order != wesn) fatal_error("lola only works in we:sn order","");
        if (lat == NULL || lon == NULL || data == NULL) fatal_error("lola: no val","");

        /* find the nearest points for the grid */
        closest_init(sec);
        k = 0;
        for (j = 0; j < ny; j++) {
            latitude = save->lat0 + j*save->dlat;
            for (i = 0; i < nx; i++) {
               longitude = save->lon0 + i*save->dlon;
               save->iptr[k++] = closest(sec, latitude, longitude);
            }
        }
    }

    if (strcmp(arg4,"spread") == 0) {
        k = 0;
        fprintf(save->out, "longitude, latitude, value,\n");
        for (j = 0; j < ny; j++) {
            latitude = save->lat0 + j*save->dlat;
            for (i = 0; i < nx; i++) {
                t = save->iptr[k] >= 0 ? data[save->iptr[k]] : UNDEFINED;
		if (DEFINED_VAL(t)) {
                    longitude = save->lon0 + i*save->dlon;
		    if (longitude >= 360.0) longitude -= 360.0;
                    fprintf(save->out, "%.6lf, %.6lf, %g,\n",longitude,latitude,t);
		}
		k++;
            }
        }
    }

    else if (strcmp(arg4,"bin") == 0) {
        i = nxny * sizeof(float);
        if (header) fwrite((void *) &i, sizeof(int), 1, save->out);
        for (i = 0; i < nxny; i++) {
            t = save->iptr[i] >= 0 ? data[save->iptr[i]] : UNDEFINED;
            fwrite(&t, sizeof(float), 1, save->out);
	}
        if (header) fwrite((void *) &i, sizeof(int), 1, save->out);
    }

    else if (strcmp(arg4,"text") == 0) {
        /* text output */
        if (header == 1) {
            fprintf(save->out ,"%d %d\n", nx, ny);
        }
        for (i = 0; i < nxny; i++) {
            t = save->iptr[i] >= 0 ? data[save->iptr[i]] : UNDEFINED;
            fprintf(save->out, text_format, t);
            fprintf(save->out, ((i+1) % text_column) ? " " : "\n");
        }
    }

    else if (strcmp(arg4,"grib") == 0) {
	/* make new_sec[] with new grid definition */
	for (i = 0; i < 8; i++) new_sec[i] = sec[i];
	new_sec[3] = sec3_lola(nx, save->lon0, save->dlon, ny, save->lat0, save->dlat, sec, NULL, NULL);

	/* get grid values */
	tmp = (float *) malloc(nx*ny * sizeof (float));
	if (tmp == NULL) fatal_error("-lola: memory allocation","");
        for (i = 0; i < nxny; i++) 
            tmp[i] = save->iptr[i] >= 0 ? data[save->iptr[i]] : UNDEFINED;

        grib_wrt(new_sec, tmp, nx*ny, nx, ny, use_scale, dec_scale, bin_scale, 
		wanted_bits, max_bits, grib_type, save->out);

	free(tmp);
    }

    if (flush_mode) fflush(save->out);
    return 0;
}
Esempio n. 3
0
int f_new_grid(ARG4) {
    struct local_struct *save;

    unsigned int i;
    int is_u, is_v, ftn_npnts, ftn_nout;
    int kgds[200], km;
    float *data_in, *data_out;
    double x0, y0, dx, dy, xn, yn;
    double lov, lad, latin1, latin2;
    int proj;					// projection: for LC 0 = NP, 128 = SP
    char name[NAMELEN];
    int j, ibi, ibo, iret, nnx, nny, n_out;
    unsigned char *new_sec[8], *s, *bitmap, *bitmap_out, *p;

    /* for lambertc */
    double r_maj, r_min, ref_lon, ref_lat;

    if (mode == -1) {			// initialization
        decode = 1;
        output_order_wanted = raw;	// in raw order


#ifdef G95
        // initialize g95 runtime library
        if (g95_runstop == 0) {
            g95_runtime_start(0,NULL);
            g95_runstop = 1;
        }
#endif

//        if ( (sizeof(vectors) / sizeof (vectors[0])) % 2 == 1) fatal_error("new_grid: program error in vectors[]","");

        // allocate static variables

        *local = save = (struct local_struct *) malloc( sizeof(struct local_struct));
        if (save == NULL) fatal_error("memory allocation -wind_speed","");

        if ((save->out = ffopen(arg4, file_append ? "ab" : "wb")) == NULL) {
            fatal_error("-new_grid: could not open file %s", arg1);
        }
        save->has_u = 0;
        save->radius_major = save->radius_minor = 0.0;
        init_sec(save->clone_sec);
        s = NULL;

        // parse NCEP grids */
        ncep_grids(&arg1, &arg2, &arg3);

        // for each output grid
        if (strcmp(arg1,"latlon") == 0) {
            if (sscanf(arg2,"%lf:%d:%lf", &x0, &nnx, &dx) != 3)
                fatal_error("new_grid: XDEF wrong:%s",arg2);
            if (sscanf(arg3,"%lf:%d:%lf", &y0, &nny, &dy) != 3)
                fatal_error("new_grid: YDEF wrong:%s",arg3);

            if (x0 < 0.0) x0 += 360.0;
            save->nx = nnx;
            save->ny = nny;
            save->npnts_out = n_out = nnx*nny;
            if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");

            // make a new section 3
            s = sec3_lola(nnx, x0, dx, nny, y0, dy, sec);
        }
        else if (strncmp(arg1,"mercator:",9) == 0) {
            if (sscanf(arg1,"mercator:%lf",  &lad) != 1)
                fatal_error("new_grid: LaD (latitude interesection) not specified","");
            if (sscanf(arg2,"%lf:%d:%lf:%lf", &x0, &nnx, &dx, &xn) != 4)
                fatal_error("new_grid: XDEF wrong:%s",arg2);
            if (sscanf(arg3,"%lf:%d:%lf:%lf", &y0, &nny, &dy, &yn) != 4)

                if (x0 < 0.0) x0 += 360.0;
            save->nx = nnx;
            save->ny = nny;
            save->npnts_out = n_out = nnx*nny;
            if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");

            // make a new section 3
            s = sec3_mercator(lad, nnx, x0, dx, xn, nny, y0, dy, yn, sec);
        }
        else if (strcmp(arg1,"gaussian") == 0) {
            if (sscanf(arg2,"%lf:%d:%lf", &x0, &nnx, &dx) != 3)
                fatal_error("new_grid: XDEF wrong:%s",arg2);
            if (sscanf(arg3,"%lf:%d", &y0, &nny) != 2)
                fatal_error("new_grid: YDEF wrong:%s",arg3);

            if (x0 < 0.0) x0 += 360.0;
            save->nx = nnx;
            save->ny = nny;
            save->npnts_out = n_out = nnx*nny;
            if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");
            // make a new section 3
            s = sec3_gaussian(nnx, x0, dx, nny, y0, sec);
        }
        else if (strncmp(arg1,"lambert:",8) == 0) {
            i = sscanf(arg1,"lambert:%lf:%lf:%lf:%lf", &lov, &latin1, &latin2, &lad);
            if (i < 2) fatal_error("new_grid: arg1 wrong:%s",arg1);
            if (lov < 0.0)  lov += 360.0;
            if (i < 3) latin2 = latin1;
            if (i < 4) lad = latin2;
            proj = 0;
            if (latin2 < 0.0) proj = 128;

            if (sscanf(arg2,"%lf:%d:%lf", &x0, &nnx, &dx) != 3)
                fatal_error("new_grid: XDEF wrong:%s",arg2);
            if (sscanf(arg3,"%lf:%d:%lf", &y0, &nny, &dy) != 3)
                fatal_error("new_grid: YDEF wrong:%s",arg3);

            if (x0 < 0.0) x0 += 360.0;
            save->nx = nnx;
            save->ny = nny;
            save->npnts_out = n_out = nnx*nny;
            if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");

            // make a new section 3
            s = sec3_lc(lov, lad, latin1, latin2, proj, nnx, x0, dx, nny, y0, dy, sec);
        }

        /* for lambertc, input is the lon-lat of center point */
        /* can not calc grid until radius is given, so do lambert code to check args */

        else if (strncmp(arg1,"lambertc:",9) == 0) {
            i = sscanf(arg1,"lambertc:%lf:%lf:%lf:%lf", &lov, &latin1, &latin2, &lad);
            if (i < 2) fatal_error("new_grid: arg1 wrong:%s",arg1);
            if (lov < 0.0)  lov += 360.0;
            if (i < 3) latin2 = latin1;
            if (i < 4) lad = latin2;
            proj = 0;
            if (latin2 < 0.0) proj = 128;

            if (sscanf(arg2,"%lf:%d:%lf", &x0, &nnx, &dx) != 3)
                fatal_error("new_grid: XDEF wrong:%s",arg2);
            if (sscanf(arg3,"%lf:%d:%lf", &y0, &nny, &dy) != 3)
                fatal_error("new_grid: YDEF wrong:%s",arg3);

            if (x0 < 0.0) x0 += 360.0;
            save->nx = nnx;
            save->ny = nny;
            save->npnts_out = n_out = nnx*nny;
            if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");

            // make a new section 3
            s = sec3_lc(lov, lad, latin1, latin2, proj, nnx, x0, dx, nny, y0, dy, sec);
        }

        else if (strncmp(arg1,"nps:",4) == 0 || strncmp(arg1,"sps:",4) == 0)  {
            if (sscanf(arg1,"%*[ns]ps:%lf:%lf", &lov, &lad) != 2) fatal_error("new_grid: arg1 wrong:%s",arg1);
            if (lad != 60.0) fatal_error("New_grid: only LatD = 60 is supported","");
            proj = 0;
            if (arg1[0] == 's') proj = 128;
            if (sscanf(arg2,"%lf:%d:%lf", &x0, &nnx, &dx) != 3)
                fatal_error("new_grid: XDEF wrong:%s",arg2);
            if (sscanf(arg3,"%lf:%d:%lf", &y0, &nny, &dy) != 3)
                fatal_error("new_grid: YDEF wrong:%s",arg3);
            if (lov < 0.0)  lov += 360.0;

            if (x0 < 0.0) x0 += 360.0;
            save->nx = nnx;
            save->ny = nny;
            save->npnts_out = n_out = nnx*nny;
            if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");

            // make a new section 3
            s = sec3_polar_stereo(lov, lad, proj, nnx, x0, dx, nny, y0, dy, sec);
        }
        else fatal_error("new_grid: unsupported output grid %s", arg1);

        // save new section 3
        i = (int) uint4(s);         // size of section 3
        new_sec[3] = save->sec3 = (unsigned char *) malloc(i * sizeof(unsigned char));
        for (j = 0; j < i; j++) save->sec3[j] = s[j];

        // apply wind rotation .. change flag 3.3
        if (wind_rotation == undefined) {
            fprintf(stderr,"Warning: -new_grid wind orientation undefined, "
                    "use \"-new_grid_winds (grid|earth)\", earth used (N=North Pole)\n");
            if ( (p = flag_table_3_3_location(new_sec)) ) *p = *p & (255 - 8);
        }

        if (wind_rotation == grid && (p = flag_table_3_3_location(new_sec))) *p = *p | 8;

        if (mk_kgds(new_sec, save->kgds_out)) fatal_error("new_grid: encoding output kgds","");

        /* some vectors need by interpolation routines */
        if ((save->rlat = (float *) malloc(n_out * sizeof(float))) == NULL)
            fatal_error("new_grid memory allocation","");
        if ((save->rlon = (float *) malloc(n_out * sizeof(float))) == NULL)
            fatal_error("new_grid memory allocation","");
        if ((save->crot = (float *) malloc(n_out * sizeof(float))) == NULL)
            fatal_error("new_grid memory allocation","");
        if ((save->srot = (float *) malloc(n_out * sizeof(float))) == NULL)
            fatal_error("new_grid memory allocation","");

        return 0;
    }

    save = (struct local_struct *) *local;

    if (mode == -2) {			// cleanup
#ifdef G95
        if (g95_runstop == 1) {
            g95_runtime_stop();
            g95_runstop = 0;
        }
#endif
        if (save->has_u > 0) {
            fprintf(stderr,"-new_grid: last field %s was not interpolated (missing V)\n", save->name);
            free(save->u_val);
            free_sec(save->clone_sec);
        }
        free(save->rlon);
        free(save->rlat);
        free(save->crot);
        free(save->srot);
        free(save->sec3);
        ffclose(save->out);
        free(save);

        return 0;
    }

    if (mode >= 0) {			// processing

        /* The kgds of some output grids will change depending on input grid */
        /* for example, radius of earth is not known grib file is read, */
        /*   and mass vs wind fields */
        /* right nowm, only affects lambertc */

        if (strncmp(arg1,"lambertc:",8) == 0) {

            // lambertc depends on the radius of the earth which is
            // set by the input grib file

            /* read earth radius */
            i = axes_earth(sec, &r_maj, &r_min);
            if (i) fatal_error_i("axes_earth: error code %d", i);

            if (save->radius_major != r_maj || save->radius_minor != r_min) {

                // update sec3 and kgds

                i = sscanf(arg1,"lambertc:%lf:%lf:%lf:%lf", &lov, &latin1, &latin2, &lad);
                if (i < 2) fatal_error("new_grid: arg1 wrong:%s",arg1);
                if (lov < 0.0)  lov += 360.0;
                if (i < 3) latin2 = latin1;
                if (i < 4) lad = latin2;
                proj = 0;
                if (latin2 < 0.0) proj = 128;

                if (sscanf(arg2,"%lf:%d:%lf", &x0, &nnx, &dx) != 3)
                    fatal_error("new_grid: XDEF wrong:%s",arg2);
                if (sscanf(arg3,"%lf:%d:%lf", &y0, &nny, &dy) != 3)
                    fatal_error("new_grid: YDEF wrong:%s",arg3);

                if (x0 < 0.0) x0 += 360.0;
                save->nx = nnx;
                save->ny = nny;
                save->npnts_out = n_out = nnx*nny;
                if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");

                ref_lon = x0;
                ref_lat = y0;

                i = new_grid_lambertc(nnx, nny, ref_lon, ref_lat, latin1, latin2, lov, lad, r_maj, r_min, dx, dy, &x0, &y0);
                if (i) fatal_error_i("new_grid_lambertc: error code %d", i);

                // make a new section 3
                s = sec3_lc(lov, lad, latin1, latin2, proj, nnx, x0, dx, nny, y0, dy, sec);

                // save new section 3
                i = (int) uint4(s);         // size of section 3
                for (j = 0; j < i; j++) save->sec3[j] = s[j];

                // make kgds
                new_sec[3] = save->sec3;
                if (mk_kgds(new_sec, save->kgds_out)) fatal_error("new_grid: encoding output kgds","");

                // save radius of earth, to show sec3 and kgds has been done
                save->radius_major = r_maj;
                save->radius_minor = r_min;
            }
        }

        if (output_order != raw) fatal_error("new_grid: must be in raw output order","");
        i = getName(sec, mode, NULL, name, NULL, NULL);
        is_u = is_v = 0;
//	for (j = 0 ; j < sizeof(vectors) / sizeof(vectors[0]); j++) {
        for (j = 0; vectors[j] != NULL; j++) {
            if (strcmp(name,vectors[j]) == 0) {
                if (j % 2 == 0) is_u = 1;
                else is_v = 1;
                break;
            }
        }

// fprintf(stderr, " %s isu %d isv %d has_u %d\n", name, is_u, is_v, save->has_u);
//  for (i = 0; i < 12; i++) { printf("kgds_out[%d] = %d ",i,save->kgds_out[i]); }

        // check if V matches expectation

        if (is_v && (save->has_u == 0  || (same_sec0(sec,save->clone_sec) != 1 ||
                                           same_sec1(sec,save->clone_sec) != 1 ||
                                           same_sec3(sec,save->clone_sec) != 1 ||
                                           same_sec4(sec,save->clone_sec) != 1) )) {
            fprintf(stderr,"-new_grid: %s doesn't pair with previous vector field, field ignored\n", name);
            return 0;
        }

        // if U field - save

        if (is_u) {
            if (save->has_u > 0) {
                fprintf(stderr,"-new_grid: missing V, %s not interpolated\n",save->name);
                free(save->u_val);
                free_sec(save->clone_sec);
            }
            copy_sec(sec, save->clone_sec);
            copy_data(data,ndata,&(save->u_val));
            GB2_ParmNum(save->clone_sec) = GB2_ParmNum(sec) + 1;
            save->has_u = 1;
            strncpy(save->name, name,NAMELEN-1);
            save->name[NAMELEN-2]=0;
            return 0;
        }

        // at this point will call polates with either a scalar or vector

        n_out = save->npnts_out;
        nnx = save->nx;
        nny = save->ny;
        km = 1;			// only one field

        if (mk_kgds(sec, kgds)) fatal_error("new_grid: encoding input kgds","");

        data_in = (float *) malloc(npnts * (1 + (is_v != 0)) * sizeof(float));
        bitmap = (unsigned char *) malloc(npnts * sizeof(unsigned char));
        bitmap_out = (unsigned char *) malloc(n_out * sizeof(unsigned char));
        data_out = (float *) malloc(n_out * (1 + (is_v != 0)) * sizeof(float));

        if (data_in == NULL || data_out == NULL || bitmap == NULL || bitmap_out == NULL)
            fatal_error("new_grid: memory allocation problem","");

        ibi = 0;                        // input bitmap is not used
        if (is_v) {
            for (i = 0; i < npnts; i++) {
                if (DEFINED_VAL(data[i]) && DEFINED_VAL(save->u_val[i])) {
                    data_in[i] = save->u_val[i];
                    data_in[i+npnts] = data[i];
                    bitmap[i] = 1;
                }
                else {
                    data_in[i] = data_in[i + npnts] = 0.0;
                    bitmap[i] = 0;
                    ibi = 1;                // input bitmap is used
                }
            }
            if (mode == 98) fprintf(stderr," UV interpolation %s , %s\n", save->name, name);
        }
        else {
            for (i = 0; i < npnts; i++) {
                if (DEFINED_VAL(data[i])) {
                    data_in[i] = data[i];
                    bitmap[i] = 1;
                }
                else {
                    data_in[i] = 0.0;
                    bitmap[i] = 0;
                    ibi = 1;                // input bitmap is used
                }
            }
        }

        // interpolate

// for (i = 0; i < 12; i++) { printf("\nkgds_in[%d] = %d  out=%d ",i,kgds[i],save->kgds_out[i]); }
        ftn_npnts = (int) npnts;
        ftn_nout = (int) n_out;
        if (is_v) {
            IPOLATEV(&interpol_type, ipopt,kgds,save->kgds_out,
                     &ftn_npnts, &n_out, &km, &ibi, bitmap, data_in, data_in+npnts,
                     &ftn_nout,save->rlat,save->rlon, save->crot, save->srot,
                     &ibo, bitmap_out, data_out, data_out + n_out, &iret);
        }
        else {
            IPOLATES(&interpol_type, ipopt,kgds,save->kgds_out,
                     &ftn_npnts, &n_out, &km, &ibi, bitmap, data_in, &ftn_nout,
                     save->rlat,save->rlon, &ibo, bitmap_out, data_out, &iret);
        }
        if (iret != 0) {
            for (i = 0; i < 12; i++) {
                fprintf(stderr," IPOLATES error: kgds[%d] input %d output %d\n", i+1,kgds[i],save->kgds_out[i]);
            }
            if (iret == 2) fatal_error("IPOLATES failed, unrecognized input grid or no grid overlap","");
            if (iret == 3) fatal_error("IPOLATES failed, unrecognized output grid","");
            fatal_error_i("IPOLATES failed, error %d",iret);

        }
        n_out = (unsigned int) ftn_nout;

        /* use bitmap to set UNDEFINED values */
        if (ibo == 1) {         // has a bitmap
            if (is_v) {
                for (i = 0; i < n_out; i++) {
                    if (bitmap_out[i] == 0) data_out[i] = data_out[i+n_out] = UNDEFINED;
                }
            }
            else {
                for (i = 0; i < n_out; i++) {
                    if (bitmap_out[i] == 0) data_out[i] = UNDEFINED;
                }
            }
        }

        // now to write out the grib file

        for (i = 0; i < 8; i++) new_sec[i] = sec[i];
        new_sec[3] = save->sec3;

        if (is_v != 0) {
            GB2_ParmNum(new_sec) = GB2_ParmNum(new_sec) - 1;
            grib_wrt(new_sec, data_out, n_out, nnx, nny, use_scale, dec_scale, bin_scale,
                     wanted_bits, max_bits, grib_type, save->out);
            GB2_ParmNum(new_sec) = GB2_ParmNum(new_sec) + 1;
            grib_wrt(new_sec, data_out+n_out, n_out, nnx, nny, use_scale, dec_scale, bin_scale,
                     wanted_bits, max_bits, grib_type, save->out);
        }
        else {
            grib_wrt(new_sec, data_out, n_out, nnx, nny, use_scale, dec_scale, bin_scale,
                     wanted_bits, max_bits, grib_type, save->out);
        }
        if (flush_mode) fflush(save->out);
        free(data_in);
        free(bitmap);
        free(bitmap_out);
        free(data_out);
        if (is_v != 0) {
            save->has_u = 0;
            free(save->u_val);
            free_sec(save->clone_sec);
        }
    }
    return 0;
}
Esempio n. 4
0
int f_cress_lola(ARG4) {

    int n, nx, ny, nxny, ix, iy, i, j, k, m, iradius;
    double x0,dx, y0,dy, x, y, z, r_sq, sum;
    unsigned char *new_sec[8];
    double *cos_lon, *sin_lon, s, c, tmp, *tmpv, *inc, *wt;
    float *background;

    struct local_struct {
        int nlat, nlon, nRadius;
        double lat0, lon0, dlat, dlon, latn, lonn;
        FILE *out;
	int last_GDS_change_no;
	double Radius[MAX_SCANS];
	double R_earth;
        double *in_x, *in_y, *in_z;
        double *out_x, *out_y, *out_z;
	char *mask;
    };
    struct local_struct *save;

    /* initialization phase */

    if (mode == -1) {
        decode = latlon = 1;	/* request decode of data, lat and lon */

        *local = save = (struct local_struct *) malloc( sizeof(struct local_struct));
        if (save == NULL) fatal_error("cress_lola memory allocation ","");

	/* parse command line arguments */

        if (sscanf(arg1,"%lf:%d:%lf", &x0, &nx, &dx) != 3)
            fatal_error("cress_lola parsing longitudes lon0:nx:dlon  %s", arg1);

        if (dx < 0) fatal_error("cress_lola: dlon < 0", "");
        if (nx <= 0) fatal_error_i("cress_lola: bad nlon %d", nx);
        if (x0 < 0.0) x0 += 360.0;
        if (x0 < 0.0 || x0 >= 360.0) fatal_error("cress_lola: bad initial longitude","");
        save->nlon = nx;
        save->lon0 = x0;
        save->dlon = dx;
        save->lonn = x0 + (nx-1) * dx;

        if (sscanf(arg2,"%lf:%d:%lf", &y0, &ny, &dy) != 3) 
            fatal_error("cress_lola parsing latitudes lat0:nx:dlat  %s", arg2);

        if (dy < 0) fatal_error("cress_lola: dlat < 0","");
        if (ny <= 0) fatal_error_i("cress_lola: bad nlat %d", ny);
        save->nlat = ny;
        save->lat0 = y0;
        save->dlat = dy;
        save->latn = y0 + (ny-1)*dy;
        if (save->latn > 90.0 || save->lat0 < -90.0) fatal_error("cress_lola: bad latitude","");
        nxny = nx*ny;

        if ((save->out = ffopen(arg3,file_append ? "ab" : "wb")) == NULL) 
              fatal_error("cress_lola could not open file %s", arg3);

	iradius = 0;
	save->mask = NULL;
	k = sscanf(arg4, "%lf%n", &tmp, &m);
        while (k == 1) {
            if (iradius >= MAX_SCANS) fatal_error("cres_lola: too many radius parameters","");
            save->Radius[iradius++] = tmp;
	    if (tmp < 0.0 && save->mask == NULL) {
		save->mask = (char *) malloc(nxny * sizeof(char));
		if (save->mask == NULL) fatal_error("cress_lola memory allocation ","");
	    }
            arg4 += m;
            k = sscanf(arg4, ":%lf%n", &tmp, &m);
	}
	save->nRadius = iradius;

fprintf(stderr,"nRadius=%d nx=%d ny=%d\n",save->nRadius, nx, ny);

	save->out_x = (double *) malloc(nxny * sizeof(double));
	save->out_y = (double *) malloc(nxny * sizeof(double));
	save->out_z = (double *) malloc(nxny * sizeof(double));
	if (save->out_x == NULL || save->out_y == NULL || save->out_z == NULL) 
		fatal_error("cress_lola: memory allocation","");

	save->in_x = save->in_y = save->in_z = NULL;
	save->last_GDS_change_no = 0;

	/* out_x, out_y, out_z have the 3-d coordinates of the lola grid */

	cos_lon = (double *) malloc(nx * sizeof(double));
	sin_lon = (double *) malloc(nx * sizeof(double));
	if (cos_lon == NULL || sin_lon == NULL) fatal_error("cress_lola: memory allocation","");
	for (i = 0; i < nx; i++) {
	    x = (x0 + i*dx) * (M_PI / 180.0);
	    cos_lon[i] = cos(x);
	    sin_lon[i] = sin(x);
	}

        for (k = j = 0; j < ny; j++) {
	    y = (y0 + j*dy) * (M_PI / 180.0);
            s = sin(y);
            c = sqrt(1.0 - s * s);
	    for (i = 0; i < nx; i++) {
                save->out_z[k] = s;
                save->out_x[k] = c * cos_lon[i];
                save->out_y[k] = c * sin_lon[i];
		k++;
	    }
	}
	free(cos_lon);
	free(sin_lon);
        return 0;
    }

    save = (struct local_struct *) *local;
    if (mode == -2) {
	ffclose(save->out);
        return 0;
    }

    /* processing phase */
fprintf(stderr,">>processing\n");

    nx = save->nlon;
    ny = save->nlat;
    nxny = nx*ny;

    background = (float *) malloc(nxny * sizeof(float));
    tmpv = (double *) malloc(nxny * sizeof(double));
    inc = (double *) malloc(nxny * sizeof(double));
    wt = (double *) malloc(nxny * sizeof(double));
    if (background == NULL || tmpv == NULL || wt == NULL || inc == NULL) fatal_error("cress_lola: memory allocation","");

    /* Calculate x, y and z of input grid if new grid */
    if (save->last_GDS_change_no != GDS_change_no || save->in_x == NULL) {
	save->last_GDS_change_no = GDS_change_no;
        if (lat == NULL || lon == NULL || data == NULL) fatal_error("cress_lola: no lat, lon, or data","");

	save->R_earth  =  radius_earth(sec);

	if (save->in_x) free(save->in_x);
	if (save->in_y) free(save->in_y);
	if (save->in_z) free(save->in_z);

	save->in_x = (double *) malloc(npnts * sizeof(double));
	save->in_y = (double *) malloc(npnts * sizeof(double));
	save->in_z = (double *) malloc(npnts * sizeof(double));
	if (save->in_x == NULL || save->in_y == NULL || save->in_z == NULL)
	    fatal_error("cress_lola: memory allocation","");

	for (i = 0; i < npnts; i++) {
	    tmp = lon[i];
	    if (tmp < save->lon0) tmp += 360.0;
	    if (lat[i] >= 999.0 || lat[i] > save->latn || lat[i] < save->lat0 || tmp > save->lonn) {
		save->in_x[i] = 999.9;
	    }
	    else {
                s = sin(lat[i] * (M_PI / 180.0));
                c = sqrt(1.0 - s * s);
                save->in_z[i] = s;
                save->in_x[i] = c * cos(lon[i] * (M_PI / 180.0));
                save->in_y[i] = c * sin(lon[i] * (M_PI / 180.0));
            }
        }
fprintf(stderr,"done new gds processing npnts=%d\n", npnts);
    }

    /* at this point x, y, and z of input and output grids have been made */

    /* make new_sec[] with new grid definition */
    for (i = 0; i < 8; i++) new_sec[i] = sec[i];
    new_sec[3] = sec3_lola(nx, save->lon0, save->dlon, ny, save->lat0, save->dlat, sec);

    /* set background to average value of data */

    n = 0;
    sum = 0.0;
    /* make background = ave value */
    for (i = 0; i < npnts; i++) {
        if (save->in_x[i] < 999.0  && ! UNDEFINED_VAL(data[i]) ) {
	    n++;
	    sum += data[i];
	}
    }
    if (n == 0) {
	/* write undefined grid */
	for (i = 0; i < nxny; i++) background[i] = UNDEFINED;
        grib_wrt(new_sec, background, nxny, nx, ny, use_scale, dec_scale, bin_scale,
                wanted_bits, max_bits, grib_type, save->out);
        if (flush_mode) fflush(save->out);
	free(background);
	free(tmpv);
	free(inc);
	free(wt);
	return 0;
    }
    sum /= n;
    for (i = 0; i < nxny; i++) background[i] = sum;
fprintf(stderr,">>sum=%lf n %d background[1] %lf\n", sum, n, background[1]);

    for (iradius = 0; iradius < save->nRadius; iradius++) {
fprintf(stderr,">>radias=%lf nxny %d npnts %d\n", save->Radius[iradius],nxny, npnts);
	/* save->Radius has units of km */
	/* normalize to a sphere of unit radius */
	r_sq = save->Radius[iradius] / (save->R_earth / 1000.0);
	r_sq = r_sq * r_sq;
	/* wt = inc = 0.0; */
	for (k = 0; k < nxny; k++) inc[k] = wt[k] = 0.0;

	for (j = 0; j < npnts; j++) {
	    if (save->in_x[j] > 999.0 || UNDEFINED_VAL(data[j]) ) continue;

	    /* find the background value */
	    x = lon[j] - save->lon0;
	    x = (x < 0.0) ? (x + 360.0) / save->dlon : x / save->dlon;
	    y = (lat[j] - save->lat0) / save->dlat;

	    ix = floor(x);
	    iy = floor(y);
	    if ((double) ix == x && ix == nx-1) ix--;
	    if ((double) iy == y && iy == ny-1) iy--;

	    if (ix < 0 || iy < 0 || ix >= nx || iy >= ny) fatal_error("cress_lola: prog error ix, iy","");

	    x = x - ix;
	    y = y - iy;

	    /* find background value */

	    tmp = background[ix+iy*nx] * (1-x)*(1-y) +
		  background[ix+1+iy*nx] * (x)*(1-y) +
		  background[ix+(iy+1)*nx] * (1-x)*(y) +
		  background[(ix+1)+(iy+1)*nx] * (x)*(y);

// fprintf(stderr,"obs: lat/lon %lf %lf, ix %d / %d iy %d data %lf, background %lf\n", lat[j],lon[j], ix, nx, iy, data[j], tmp);
	    /* data increment */
	    tmp = data[j] - tmp;

	    x = save->in_x[j];
	    y = save->in_y[j];
	    z = save->in_z[j];

	    for (k = 0; k < nxny; k++) {
		tmpv[k] = DIST_SQ(x-save->out_x[k], y-save->out_y[k], z-save->out_z[k]);
		if (tmpv[k] < r_sq) {
		    tmpv[k] = (r_sq - tmpv[k]) / (r_sq + tmpv[k]);
		    wt[k] += tmpv[k];
		    inc[k] += tmpv[k] * tmp;
		}
	    }
	}		

	/* make mask or update background */

	if (save->Radius[iradius] < 0.0) {
	    for (k = 0; k < nxny; k++) save->mask[k] = (wt[k] > 0) ? 1 : 0;
	}
	for (k = 0; k < nxny; k++) {
	    if (wt[k] > 0) background[k] += inc[k]/wt[k];
	}
    }

    if (save->mask) {
	for (k = 0; k < nxny; k++) {
	    if (save->mask[k] == 0) background[k] = UNDEFINED;
	}
    }
    grib_wrt(new_sec, background, nxny, nx, ny, use_scale, dec_scale, bin_scale,
	wanted_bits, max_bits, grib_type, save->out);

    if (flush_mode) fflush(save->out);
    free(background);
    free(tmpv);
    free(wt);
    free(inc);
    return 0;
}
Esempio n. 5
0
int small_grib(unsigned char **sec, int mode, float *data, double *lon, double *lat, unsigned int ndata,
               int ix0, int ix1, int iy0, int iy1, FILE *out) {

    int can_subset, grid_template;
    int nx, ny, res, scan, new_nx, new_ny, i, j;
    unsigned int sec3_len, new_ndata, k, npnts;
    unsigned char *sec3, *new_sec[9];
    double units;
    int basic_ang, sub_ang, cyclic_grid;
    float *new_data;

    get_nxny(sec, &nx, &ny, &npnts, &res, &scan);        /* get nx, ny, and scan mode of grid */
    grid_template = code_table_3_1(sec);

    // make a copy of the gds (sec3)
    sec3_len = GB2_Sec3_size(sec);
    sec3 = (unsigned char *) malloc(sec3_len);
    for (k = 0; k < sec3_len; k++) sec3[k] = sec[3][k];

    // make a copy of the sec[] with new sec3
    new_sec[0] = sec[0];
    new_sec[1] = sec[1];
    new_sec[2] = sec[2];
    new_sec[3] = sec3;
    new_sec[4] = sec[4];
    new_sec[5] = sec[5];
    new_sec[6] = sec[6];
    new_sec[7] = sec[7];
//    new_sec[8] = sec[8];  not needed by writing routines

    can_subset = 1;
    if (lat == NULL || lon == NULL) can_subset = 0;
    new_nx = ix1-ix0+1;
    new_ny = iy1-iy0+1;
    if (new_nx <= 0) fatal_error("small_grib, new_nx is <= 0","");
    if (new_ny <= 0) fatal_error("small_grib, new_ny is <= 0","");
    new_ndata = new_nx * new_ny;
    cyclic_grid = 0;

    if (can_subset) {
        cyclic_grid = cyclic(sec);

        // lat-lon grid - no thinning
        if ((grid_template == 0 && sec3_len == 72) || (grid_template == 1 && sec3_len == 04)) {
            uint_char(new_nx,sec3+30);		// nx
            uint_char(new_ny,sec3+34);		// ny

            basic_ang = GDS_LatLon_basic_ang(sec3);
            sub_ang = GDS_LatLon_sub_ang(sec3);
            if (basic_ang != 0) {
                units = (double) basic_ang / (double) sub_ang;
            }
            else {
                units = 0.000001;
            }
            i = lat[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units;		// lat1
            int_char(i,sec3+46);
            i = lon[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units;		// lon1
            int_char(i,sec3+50);
            i = lat[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units;		// lat2
            int_char(i,sec3+55);
            i = lon[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units;		// lon2
            int_char(i,sec3+59);
        }

        else if ((grid_template == 40 && sec3_len == 72)) { // full Gaussian grid
            uint_char(new_nx,sec3+30);		// nx
            uint_char(new_ny,sec3+34);		// ny

            basic_ang = GDS_Gaussian_basic_ang(sec3);
            sub_ang = GDS_Gaussian_sub_ang(sec3);
            if (basic_ang != 0) {
                units = (double) basic_ang / (double) sub_ang;
            }
            else {
                units = 0.000001;
            }

            i = lat[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units;          // lat1
            int_char(i,sec3+46);
            i = lon[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units;          // lon1
            int_char(i,sec3+50);
            i = lat[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units;          // lat2
            int_char(i,sec3+55);
            i = lon[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units;          // lon2
            int_char(i,sec3+59);
        }

        // polar-stereo graphic, lambert conformal , no thinning
        else if ((grid_template == 20 && sec3_len == 65) || 		// polar stereographic
                 (grid_template == 30 && sec3_len == 81)) {	// lambert conformal
            uint_char(new_nx,sec3+30);		// nx
            uint_char(new_ny,sec3+34);		// ny

            i = (int) (lat[ idx(ix0,iy0,nx,ny,cyclic_grid) ] * 1000000.0);		// lat1
            int_char(i,sec3+38);
            i = (int) (lon[ idx(ix0,iy0,nx,ny,cyclic_grid) ] * 1000000.0);		// lon1
            int_char(i,sec3+42);
        }

        // mercator, no thinning
        else if (grid_template == 10 && sec3_len == 72) { 		// mercator

            uint_char(new_nx,sec3+30);		// nx
            uint_char(new_ny,sec3+34);		// ny

            units = 0.000001;
            i = lat[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units;		// lat1
            int_char(i,sec3+38);
            i = lon[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units;		// lon1
            int_char(i,sec3+42);
            i = lat[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units;		// lat2
            int_char(i,sec3+51);
            i = lon[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units;		// lon2
            int_char(i,sec3+55);
        }

        else {
            can_subset = 0;
        }
    }

    // copy data to a new array

    if (can_subset) {
        uint_char(new_ndata, sec3+6);
        new_data = (float *) malloc(new_ndata * sizeof(float));

        #pragma omp parallel for private(i,j,k)
        for(j = iy0; j <= iy1; j++) {
            k = (j-iy0)*(ix1-ix0+1);
            for(i = ix0; i <= ix1; i++) {
                new_data[(i-ix0) + k ] = data[ idx(i,j,nx,ny,cyclic_grid) ];
            }
        }
    }
    else {
        new_ndata = ndata;
        new_data = (float *) malloc(new_ndata * sizeof(float));
        for (k = 0; k < ndata; k++) new_data[k] = data[k];
        new_nx = nx;
        new_ny = ny;
    }

    set_order(new_sec, output_order);

    grib_wrt(new_sec, new_data, new_ndata, new_nx, new_ny, use_scale, dec_scale,
             bin_scale, wanted_bits, max_bits, grib_type, out);

    if (flush_mode) fflush(out);

    free(new_data);
    free(sec3);
    return 0;
}
Esempio n. 6
0
int f_wind_speed(ARG1) {

    struct local_struct {
        float *val;
        int has_u;
        unsigned char *clone_sec[9];
        FILE *output;
    };
    struct local_struct *save;

    unsigned int i;
    int is_u;
    float *d1, *data_tmp;
    int discipline, mastertab, parmcat, parmnum;

    if (mode == -1) {			// initialization
        save_translation = decode = 1;

	// allocate static variables

        *local = save = (struct local_struct *) malloc( sizeof(struct local_struct));
        if (save == NULL) fatal_error("memory allocation -wind_speed","");

        if ((save->output = (void *) ffopen(arg1, file_append ? "ab" : "wb")) == NULL) {
	    fatal_error("-wind_speed: could not open file %s", arg1);
	}
	save->has_u = 0;
	init_sec(save->clone_sec);
	return 0;
    }

    save = *local;

    if (mode == -2) {			// cleanup
	if (save->has_u == 1) {
	    free(save->val);
	    free_sec(save->clone_sec);
	}
	return 0;
    }

    if (mode >= 0) {			// processing

	// get variable name parameters

        discipline = GB2_Discipline(sec);
        mastertab = GB2_MasterTable(sec);
        parmcat = GB2_ParmCat(sec);
        parmnum = GB2_ParmNum(sec);

	if (mode == 99) fprintf(stderr,"-wind_speed %d %d %d %d\n",mastertab,discipline,parmcat,parmnum);

	is_u = (mastertab <= 6) && (discipline == 0) && (parmcat == 2) && (parmnum == 2);
	if (mode == 99 && is_u) fprintf(stderr,"\n-wind_speed: is u\n");
	if (is_u) {		// save data
	    if (save->has_u) {
	        free(save->val);
	        free_sec(save->clone_sec);
	    }
            copy_sec(sec, save->clone_sec);
	    copy_data(data,ndata,&(save->val));
            GB2_ParmNum(save->clone_sec) = 3;		// set id to V
	    save->has_u = 1;
	    return 0;
	}

	// check for V

        if (same_sec0(sec,save->clone_sec) == 1 &&
            same_sec1(sec,save->clone_sec) == 1 &&
            same_sec3(sec,save->clone_sec) == 1 &&
            same_sec4(sec,save->clone_sec) == 1) {

	    // calculate wind speed

	    if (mode == 99) fprintf(stderr,"\n-wind_speed: calc wind speed\n");

            d1= save->val;
	    for (i = 0; i < ndata; i++) {
                if (!UNDEFINED_VAL(data[i]) && !UNDEFINED_VAL(*d1)) {
	            *d1 = sqrt(data[i]*data[i] + *d1 * *d1);
		}
	        else *d1 = UNDEFINED;
	        d1++;
	    }
            GB2_ParmNum(save->clone_sec) = 1;		// set id to wind speed

	    // copy data to temp space

            if ((data_tmp = (float *) malloc(ndata * sizeof(float))) == NULL)
                fatal_error("memory allocation - data_tmp","");
            undo_output_order(save->val, data_tmp, ndata);

            grib_wrt(save->clone_sec, data_tmp, ndata, nx, ny, use_scale, dec_scale, 
		bin_scale, wanted_bits, max_bits, grib_type, save->output);

            if (flush_mode) fflush(save->output);
            free(data_tmp);

            // cleanup
            free(save->val);
            free_sec(save->clone_sec);
	    save->has_u = 0;
	}
    }
    return 0;
}
Esempio n. 7
0
int f_ncep_norm(ARG1) {

    struct local_struct {
        float *val;
        int has_val;
        unsigned char *clone_sec[9];
        FILE *output;
    };
    struct local_struct *save;

    int idx, j, fhr_1, fhr_2,  dt1, dt2, new_type, is_ave;
    unsigned int i;
    float *d1, *data_tmp;

    if (mode == -1) {			// initialization
        save_translation = decode = 1;
        // 1/2015 use_scale = 0;

	// allocate static variables

        *local = save = (struct local_struct *) malloc( sizeof(struct local_struct));
        if (save == NULL) fatal_error("memory allocation f_ncep_norm","");

        if ((save->output = ffopen(arg1, file_append ? "ab" : "wb")) == NULL) {
	    fatal_error("f_ncep_norm: could not open file %s", arg1);
	}
	save->has_val = 0;
	init_sec(save->clone_sec);
	return 0;
    }

    save = (struct local_struct *) *local;

    if (mode == -2) {			// cleanup
	ffclose(save->output);
	if (save->has_val == 1) {
	    free(save->val);
	    free_sec(save->clone_sec);
	}
	free(save);
	return 0;
    }

    if (mode >= 0) {			// processing

	idx = stat_proc_n_time_ranges_index(sec);

	// only process stat processed fields
	if (idx < 0) return 0;

	// n_time_ranges has to be one
	if (sec[4][idx] != 1) return 0;

	// only process averages or accumulations
	j = code_table_4_10(sec);
	if (mode == 99) fprintf(stderr,"\nncep_norm: code table 4.10 (ave/acc/etc)=%d\n",j);
	if (j == 0) is_ave = 1;			// average
	else if (j == 1) is_ave = 0;		// accumulation
	else return 0;				// only process average or accumulations

        fhr_2 = forecast_time_in_units(sec);		// start time
        dt2 = int4(sec[4]+idx+50-42);			// delta-time
	if (mode == 99) fprintf(stderr,"\nncep_norm: fhr_2=%d dt2=%d index of dt2=%d\n",fhr_2, dt2, idx+50-42);
	if (dt2 == 0) return 0;	 			// dt == 0

	// units of fcst and stat proc should be the same if fcst time != 0
	if (fhr_2 != 0 && code_table_4_4(sec) != sec[4][49-42+idx]) return 0;

	if (save->has_val == 0) {			// new data: write and save
            if ((data_tmp = (float *) malloc(ndata * sizeof(float))) == NULL)
                fatal_error("memory allocation - data_tmp","");
            undo_output_order(data, data_tmp, ndata);
            grib_wrt(sec, data_tmp, ndata, nx, ny, use_scale, dec_scale, bin_scale,
                wanted_bits, max_bits, grib_type, save->output);

            if (flush_mode) fflush(save->output);
            free(data_tmp);

            if (save->has_val  == 1) {			// copy data to save
                free(save->val);			// save = new field
                free_sec(save->clone_sec);
	    }
            copy_sec(sec, save->clone_sec);
            copy_data(data,ndata,&(save->val));
            save->has_val = 1;
	    if (mode == 99) fprintf(stderr," ncep_norm: saved as new field\n");
            return 0;
        }

        new_type = 0;

        fhr_1 = forecast_time_in_units(save->clone_sec);		// start_time of save message
        dt1 = int4(save->clone_sec[4]+idx+50-42);			// delta-time

	if (mode == 99) fprintf(stderr,"ncep_norm: is_ave = %d\n fhr_1 %d dt1 %d fhr_2 %d dt2 %d\n",is_ave,
		fhr_1, dt1, fhr_2, dt2);

	if (fhr_1 != fhr_2) new_type = 1;

	if (new_type == 0) {
	    if (same_sec0(sec,save->clone_sec) == 0 ||
            same_sec1(sec,save->clone_sec) == 0 ||
            same_sec3(sec,save->clone_sec) == 0 ||
            same_sec4_diff_ave_period(sec,save->clone_sec) == 0) {
	
               if (mode == 99) fprintf(stderr,"ncep_norm: new_type sec test %d %d %d %d\n",
  		same_sec0(sec,save->clone_sec), same_sec1(sec,save->clone_sec), same_sec3(sec,save->clone_sec),
	            same_sec4_diff_ave_period(sec,save->clone_sec));
                new_type = 1;
	    }
        }
	if (mode == 99) fprintf(stderr,"ncep_norm: new_type=%d write and save\n",new_type);

        if (new_type == 1) {                    // fields dont match: write and save
            if ((data_tmp = (float *) malloc(ndata * sizeof(float))) == NULL)
                fatal_error("memory allocation - data_tmp","");
            undo_output_order(data, data_tmp, ndata);
            grib_wrt(sec, data_tmp, ndata, nx, ny, use_scale, dec_scale, bin_scale,
                wanted_bits, max_bits, grib_type, save->output);

            if (flush_mode) fflush(save->output);
            free(data_tmp);

            if (save->has_val  == 1) {                  // copy data to save
                free(save->val);                        // save = new field
                free_sec(save->clone_sec);
            }
            copy_sec(sec, save->clone_sec);
            copy_data(data,ndata,&(save->val));
            save->has_val = 1;
	    if (mode == 99) fprintf(stderr," ncep_norm: saved as new type/sequence\n");
            return 0;
        }

        /* now do stuff */

	if (dt1 == dt2) return 0;			// same ending time

        // change metadata

        int_char(dt2-dt1, save->clone_sec[4]+50-42+idx);	//  dt = dt2 - dt1

        save->clone_sec[4][17] = sec[4][49-42+idx];             // new forecast time unit
        int_char(dt1+fhr_1, save->clone_sec[4]+18);             // fhr = fhr + dt1
        if (mode == 99) fprintf(stderr,"ncep_norm new fcst time %d + %d\n", dt1,fhr_1);

        for (i = idx-7; i < idx; i++) {                             // ending time from pds2
            save->clone_sec[4][i] = sec[4][i];
        }

	if (mode == 99) {
	    if (is_ave)
	        fprintf(stderr," process: factor: NEW*%g - OLD*%g\n", dt2/ (double) (dt2 - dt1),
			dt1/ (double) (dt2-dt1));
	    else fprintf(stderr," process: current-last\n");
	}

        // change floating point data

        d1= save->val;
        for (i = 0; i < ndata; i++) {
            if (!UNDEFINED_VAL(data[i]) && !UNDEFINED_VAL(*d1) ) {
		if (is_ave) {
                    *d1 = (data[i]*dt2 - *d1*dt1) / (double) (dt2 - dt1);
		}
		else {		// accumulation
                    *d1 = data[i] - *d1;
		}
	    }
            else *d1 = UNDEFINED;
            d1++;
	}

        // write grib output

        if ((data_tmp = (float *) malloc(ndata * sizeof(float))) == NULL)
                fatal_error("memory allocation - data_tmp","");
        undo_output_order(save->val, data_tmp, ndata);
        grib_wrt(save->clone_sec, data_tmp, ndata, nx, ny, use_scale, dec_scale, bin_scale,
            wanted_bits, max_bits, grib_type, save->output);

        if (flush_mode) fflush(save->output);
        free(data_tmp);

	// save data
        free(save->val);                    // save = new field
        free_sec(save->clone_sec);
        copy_sec(sec, save->clone_sec);
        copy_data(data,ndata,&(save->val));
        return 0;
    }
    return 0;
}
Esempio n. 8
0
/*
 * HEADER:100:irr_grid:output:3:make irregular grid, nearest neighbor, X=lon-lat list Y=radius (km) Z=output grib file
 */
int f_irr_grid(ARG3) {

    int i, k, m;
    struct local_struct {
        int ngrid;
        double *lon_lat_list, radius;
        FILE *out;
        int *iptr;
        int last_GDS_change_no;
    };
    struct local_struct *save;
    const char *t;
    unsigned char *p;
    double tmp;
    float *array;
    unsigned char *new_sec[8], *new_sec3;

    /* initialization phase */

    if (mode == -1) {
        decode = latlon = 1;
        *local = save = (struct local_struct *)malloc( sizeof(struct local_struct));
	if (save == NULL) fatal_error("irr_grid: memory allocation","");

	/* count number of colons */
	t = arg1;
	i = 0;
	while (*t) {
	    if (*t++ == ':') i++;
	}
	if (i % 2 != 1) fatal_error("irr_grid: need lon0:lat0:lon1:lat1:..:lonN:latN","");
        save->ngrid = (i + 1)/2;
	save->lon_lat_list = (double *) malloc(save->ngrid * 2 * sizeof(double));
	save->iptr = (int *) malloc(save->ngrid  * sizeof(int));
	if (save->lon_lat_list == NULL || save->iptr == NULL ) fatal_error("irr_grid: memory allocation","");

	t = arg1;
        k = sscanf(t, "%lf%n", &tmp, &m);
	if (k != 1) fatal_error("irr_grid: lat-lon list, %s",t);
	save->lon_lat_list[0] = tmp;
	t += m;
	for (i = 1; i < 2*save->ngrid; i++) {
            k = sscanf(t, ":%lf%n", &tmp, &m);
	    if (k != 1) fatal_error("irr_grid: lat-lon list, %s",t);
	    save->lon_lat_list[i] = tmp;
	    t += m;
	}

	for (i = 0 ; i < save->ngrid; i++) {
	    tmp = save->lon_lat_list[i*2];
	    if (tmp < 0.0) save->lon_lat_list[i*2] = tmp + 360.0;
	    if (tmp > 360.0) save->lon_lat_list[i*2] = tmp - 360.0;
	    if (fabs(save->lon_lat_list[i*2+1]) > 90.0) fatal_error("irr_grid: bad latitude","");
	}

	if (sscanf(arg2,"%lf",&(save->radius)) != 1) fatal_error("irr_grid: radius %s", arg2);
        if ((save->out = ffopen(arg3, file_append ? "ab" : "wb" )) == NULL) fatal_error("irr_grid could not open file %s", arg3);
    }
    if (mode < 0) return 0;

    save = (struct local_struct *) *local;

    if (save->last_GDS_change_no != GDS_change_no) {
        save->last_GDS_change_no = GDS_change_no;
        if (lat == NULL || lon == NULL || data == NULL) fatal_error("irr_grid: no val","");

        /* find the nearest points for the grid */
        closest_init(sec);
        for (i = 0; i < save->ngrid; i++) {
            save->iptr[i] = closest(sec, save->lon_lat_list[i*2+1], save->lon_lat_list[i*2]);
        }
    }

    array = (float *) malloc(save->ngrid * sizeof(float));
    new_sec3 = (unsigned char *) malloc((30+8*save->ngrid) * sizeof(unsigned char));
    if (array == NULL || new_sec3 == NULL) fatal_error("irr_grid: memory allocation","");

    /* sec3 = grid defintion */
    uint_char(30+save->ngrid*8, new_sec3);
    new_sec3[4] = 3;		// sec3
    new_sec3[5] = 0;		// use table 3.1
    uint_char(save->ngrid, new_sec3+6);
    new_sec3[10] = 0;		// no optional list octets
    new_sec3[11] = 0;
    uint2_char(130, new_sec3+12);

    p = code_table_3_2_location(sec);
    if (p == NULL) {  // no earth descripition
	for (i = 14; i < 30; i++) {
	    new_sec3[i] = 255;
	}
    }
    else {
	for (i = 14; i < 30; i++) {
	    new_sec3[i] = p[i-14];
	}
    }

    /* make new_sec[] with new grid definition */
    for (i = 0; i < 8; i++) new_sec[i] = sec[i];
    new_sec[3] = new_sec3;

    for (i = 0; i < save->ngrid; i++) {
	array[i] = save->iptr[i] >= 0 ?  data[save->iptr[i]] : UNDEFINED;
	int_char( (int) (save->lon_lat_list[i*2+1] * 1000000.0), new_sec3 + 30 + i*8);
	uint_char( (int) (save->lon_lat_list[i*2] * 1000000.0), new_sec3 + 34 + i*8);
    }

    grib_wrt(new_sec, array, save->ngrid, save->ngrid, 1, use_scale, dec_scale, bin_scale,
                wanted_bits, max_bits, grib_type, save->out);

    free(array);
    free(new_sec3);

    return 0;
}
Esempio n. 9
0
int f_ncep_norm(ARG1) {

    struct local_struct {
        float *val;
        int has_val;
        unsigned char *clone_sec[9];
        FILE *output;
    };
    struct local_struct *save;

    int j, pdt, fhr_1, fhr_2,  dt1, dt2, new_type, is_ave;
    unsigned int i;
    float *d1, *data_tmp;

    if (mode == -1) {			// initialization
        save_translation = decode = 1;

        // allocate static variables

        *local = save = (struct local_struct *) malloc( sizeof(struct local_struct));
        if (save == NULL) fatal_error("memory allocation f_normalize","");

        if ((save->output = (void *) ffopen(arg1, file_append ? "ab" : "wb")) == NULL) {
            fatal_error("f_ncep_norm: could not open file %s", arg1);
        }
        save->has_val = 0;
        init_sec(save->clone_sec);
        return 0;
    }

    save = *local;

    if (mode == -2) {			// cleanup
        if (save->has_val == 1) {
            free(save->val);
            free_sec(save->clone_sec);
            free(save);
        }
        return 0;
    }

    if (mode >= 0) {			// processing

        // only hande PDT = 8
        pdt = GB2_ProdDefTemplateNo(sec);
        if (pdt != 8) return 0;

        // only process averages or accumulations

        // check for code table 4.8

        j = code_table_4_10(sec);
        if (mode == 99) fprintf(stderr,"\nncep_norm: code table 4.10 (ave/acc/etc)=%d\n",j);
        if (j == 0) is_ave = 1;			// average
        else if (j == 1) is_ave = 0;		// accumulation
        else return 0;				// only process average or accumulations


        // only process when fcst time units == ave/acc time units
        if (sec[4][17] != sec[4][48]) {
            if (int4(sec[4]+18) != 0) {
                return 0;
            }
        }

        fhr_2 = int4(sec[4]+18);			// start time
        dt2 = int4(sec[4]+49);				// delta-time
        if (dt2 == 0) return 0;	 			// dt == 0

        if (save->has_val == 0) {			// new data: write and save
            if ((data_tmp = (float *) malloc(ndata * sizeof(float))) == NULL)
                fatal_error("memory allocation - data_tmp","");
            undo_output_order(data, data_tmp, ndata);

            grib_wrt(sec, data_tmp, ndata, nx, ny, use_scale, dec_scale, bin_scale,
                     wanted_bits, max_bits, grib_type, save->output);
            /*
                        if (grib_type == simple) grib_out(sec, data_tmp, ndata, save->output);
                        else if (grib_type == jpeg) jpeg_grib_out(sec, data_tmp, ndata, nx,
                                 ny, use_scale, dec_scale, bin_scale, save->output);
                        else if (grib_type == ieee) ieee_grib_out(sec, data_tmp, ndata,
                            save->output);
            	    else fatal_error("NCEP_norm: unsupported grib type output","");
            */

            if (flush_mode) fflush(save->output);
            free(data_tmp);

            if (save->has_val  == 1) {			// copy data to save
                free(save->val);			// save = new field
                free_sec(save->clone_sec);
            }
            copy_sec(sec, save->clone_sec);
            copy_data(data,ndata,&(save->val));
            save->has_val = 1;
            if (mode == 99) fprintf(stderr," ncep_norm: saved as new field\n");
            return 0;
        }


        new_type = 0;

        fhr_1 = int4(save->clone_sec[4]+18);             // start time of save message
        dt1 = int4(save->clone_sec[4]+49);               // delta time

        if (mode == 99) fprintf(stderr,"ncep_norm: is_ave = %d\n fhr_1 %d dt1 %d fhr_2 %d dt2 %d\n",is_ave,
                                    fhr_1, dt1, fhr_2, dt2);

        if (fhr_1 != fhr_2) new_type = 1;

        if (new_type == 0) {
            if (same_sec0(sec,save->clone_sec) == 0 ||
                    same_sec1(sec,save->clone_sec) == 0 ||
                    same_sec3(sec,save->clone_sec) == 0 ||
                    same_sec4_diff_ave_period(sec,save->clone_sec) == 0) {
                new_type = 1;
            }
        }

        if (new_type == 1) {                    // fields dont match: write and save
            if ((data_tmp = (float *) malloc(ndata * sizeof(float))) == NULL)
                fatal_error("memory allocation - data_tmp","");
            undo_output_order(data, data_tmp, ndata);

            grib_wrt(sec, data_tmp, ndata, nx, ny, use_scale, dec_scale, bin_scale,
                     wanted_bits, max_bits, grib_type, save->output);
            /*
                        if (grib_type == simple) grib_out(sec, data_tmp, ndata, save->output);
                        else if (grib_type == jpeg) jpeg_grib_out(sec, data_tmp, ndata, nx,
                                 ny, use_scale, dec_scale, bin_scale, save->output);
                        else if (grib_type == ieee) ieee_grib_out(sec, data_tmp, ndata,
                            save->output);
            */

            if (flush_mode) fflush(save->output);
            free(data_tmp);

            if (save->has_val  == 1) {                  // copy data to save
                free(save->val);                        // save = new field
                free_sec(save->clone_sec);
            }
            copy_sec(sec, save->clone_sec);
            copy_data(data,ndata,&(save->val));
            save->has_val = 1;
            if (mode == 99) fprintf(stderr," ncep_norm: saved as new type/sequence\n");
            return 0;
        }

        /* now do stuff */

        if (dt1 == dt2) return 0;			// same ending time

        // change metadata

        int_char(dt2-dt1, save->clone_sec[4]+49);		//  dt = dt2 - dt1
        save->clone_sec[4][17] = sec[4][48];                    // new forecast time unit
        int_char(dt1+fhr_1, save->clone_sec[4]+18);             // fhr = fhr + dt1

        for (i = 34; i < 41; i++) {                             // ending time from pds2
            save->clone_sec[4][i] = sec[4][i];
        }

        if (mode == 99) {
            if (is_ave)
                fprintf(stderr," process: factor: NEW*%g - OLD*%g\n", dt2/ (double) (dt2 - dt1),
                        dt1/ (double) (dt2-dt1));
            else fprintf(stderr," process: current-last\n");
        }

        // change floating point data

        d1= save->val;
        for (i = 0; i < ndata; i++) {
            if (!UNDEFINED_VAL(data[i]) && !UNDEFINED_VAL(*d1) ) {
                if (is_ave) {
                    *d1 = (data[i]*dt2 - *d1*dt1) / (double) (dt2 - dt1);
                }
                else {		// accumulation
                    *d1 = data[i] - *d1;
                }
            }
            else *d1 = UNDEFINED;
            d1++;
        }

        // write grib output

        if ((data_tmp = (float *) malloc(ndata * sizeof(float))) == NULL)
            fatal_error("memory allocation - data_tmp","");
        undo_output_order(save->val, data_tmp, ndata);

        grib_wrt(save->clone_sec, data_tmp, ndata, nx, ny, use_scale, dec_scale, bin_scale,
                 wanted_bits, max_bits, grib_type, save->output);
        /*
                if (grib_type == simple) grib_out(save->clone_sec, data_tmp, ndata, save->output);
                else if (grib_type == jpeg) jpeg_grib_out(save->clone_sec, data_tmp, ndata, nx,
                             ny, use_scale, dec_scale, bin_scale, save->output);
                else if (grib_type == ieee) ieee_grib_out(save->clone_sec, data_tmp, ndata,
                        save->output);
                else if (grib_type == complex1) complex_grib_out(save->clone_sec, data_tmp, ndata,
        		use_scale, dec_scale, bin_scale, wanted_bits, max_bits, 1, save->output);
                else if (grib_type == complex2) complex_grib_out(save->clone_sec, data_tmp, ndata,
        		use_scale, dec_scale, bin_scale, wanted_bits, max_bits, 2, save->output);
                else if (grib_type == complex3) complex_grib_out(save->clone_sec, data_tmp, ndata,
        		use_scale, dec_scale, bin_scale, wanted_bits, max_bits, 3, save->output);
        	else fatal_error("NCEP_norm: unsupported grib output type","");
        */

        if (flush_mode) fflush(save->output);
        free(data_tmp);

        // save data
        free(save->val);                    // save = new field
        free_sec(save->clone_sec);
        copy_sec(sec, save->clone_sec);
        copy_data(data,ndata,&(save->val));
        return 0;
    }
    return 0;
}
Esempio n. 10
0
static int do_ave(struct ave_struct *save) {
    int i, j, n, ndata, pdt;
    float *data;
    unsigned char *p, *sec4;
    double factor;

    sec4 = NULL;
    if (save->has_val == 0) return 0; 
#ifdef DEBUG
printf(" ave nfields=%d missing=%d\n",save->n_fields,save->n_missing);
#endif

    ndata = save->n_sum;
    if ((data = (float *) malloc(sizeof(float) * ndata)) == NULL) fatal_error("ave: memory allocation","");
    factor = 1.0 / save->n_fields;
    for (i = 0; i < ndata; i++) {
    	if (save->n[i] != save->n_fields) data[i] = UNDEFINED;
    	else data[i] = factor * save->sum[i];
#ifdef DEBUG
        if (i < 10) printf("data[%d]=%lf n[%d]=%d, sum[%d]=%lf\n",
	    i,data[i],i,save->n[i],i,save->sum[i]);
#endif
    }

    pdt = GB2_ProdDefTemplateNo(save->first_sec);

    // average of a forecast

    if (pdt == 0) {
        sec4 = (unsigned char *) malloc(58 * sizeof(unsigned char));
	if (sec4 == NULL) fatal_error("fcst_ave: memory allocation","");
	for (i = 0; i < 34; i++) {
	    sec4[i] = save->first_sec[4][i];
	}
	uint_char((unsigned int) 58, sec4);		// length
	sec4[8] = 8;			// pdt
	// verification time
        save_time(save->year2,save->month2,save->day2,save->hour2,save->minute2,save->second2, sec4+34);
	sec4[41] = 1;					// 1 time range
	uint_char(save->n_missing, sec4+42);
	sec4[46] = 0;					// average
	sec4[47] = 2;					// rt=constant, ft++
	sec4[48] = save->dt_unit;					// total length of stat processing
	uint_char(save->dt*(save->n_fields+save->n_missing-1), sec4+49);
	sec4[53] = save->dt_unit;					// time step
	uint_char(save->dt, sec4+54);
    }

    // average of an ensemble forecast, use pdt 4.11

    else if (pdt == 1) {
        sec4 = (unsigned char *) malloc(61 * sizeof(unsigned char));
        if (sec4 == NULL) fatal_error("fcst_ave: memory allocation","");
        for (i = 0; i < 37; i++) {
            sec4[i] = save->first_sec[4][i];
        }
        uint_char((unsigned int) 61, sec4);             // length
        sec4[8] = 11;                    // pdt
        // verification time
        save_time(save->year2,save->month2,save->day2,save->hour2,save->minute2,save->second2, sec4+37);
        sec4[44] = 1;                                   // 1 time range
        uint_char(save->n_missing, sec4+45);
        sec4[49] = 0;                                   // average
        sec4[50] = 2;                                   // rt=constant, ft++
        sec4[51] = save->dt_unit;                                       // total length of stat processing
        uint_char(save->dt*(save->n_fields+save->n_missing-1), sec4+52);
        sec4[56] = save->dt_unit;                                       // time step
        uint_char(save->dt, sec4+57);
    }

    // average of an average or accumulation

    else if (pdt == 8) {
	i = GB2_Sec4_size(save->first_sec);
	n = save->first_sec[4][41];
	if (i != 46 + 12*n) fatal_error("ave: invalid sec4 size for pdt=8","");

        // keep pdt == 8 but make it 12 bytes bigger
        sec4 = (unsigned char *) malloc( (i+12) * sizeof(unsigned char));
	if (sec4 == NULL) fatal_error("fcst_ave: memory allocation","");

	uint_char((unsigned int) i+12, sec4);		// new length

	for (i = 4; i < 34; i++) {			// keep base of pdt
	    sec4[i] = save->first_sec[4][i];
	}
	
	// new verification time
        save_time(save->year2,save->month2,save->day2,save->hour2,save->minute2,save->second2, sec4+34);

	// number of stat-proc loops is increased by 1
	sec4[41] = n + 1;

	// copy old stat-proc loops 
	// for (j = n*12-1;  j >= 0; j--) sec4[58+j] = save->first_sec[4][46+j];
	for (j = 0; j < n*12; j++) sec4[46+12+j] = save->first_sec[4][46+j];

#ifdef DEBUG
printf("save->n_missing =%d save->n_fields=%d\n",save->n_missing,save->n_fields);
#endif
	uint_char(save->n_missing, sec4+42);
	sec4[46] = 0;			// average
	sec4[47] = 2;			// fcst++
	sec4[48] = save->dt_unit;						// total length of stat processing
	uint_char(save->dt*(save->n_fields+save->n_missing-1), sec4+49);	// missing
	sec4[53] = save->dt_unit;						// time step
	uint_char(save->dt, sec4+54);

    }
    else {
	fatal_error_i("ave with pdt %d is not supported",pdt);
    }


    // write grib file
    p = save->first_sec[4];
    save->first_sec[4] = sec4;

    grib_wrt(save->first_sec, data, ndata, save->nx, save->ny, 
	save->use_scale, save->dec_scale, save->bin_scale, 
	save->wanted_bits, save->max_bits, save->grib_type, save->output);

    if (flush_mode) fflush(save->output);
    save->first_sec[4] = p;
    free(data);
    free(sec4);
    return 0;
}