예제 #1
0
파일: Tosubmsg.c 프로젝트: erget/wgrib2
/*
 * init_tosubmsg: Initialisation (mode = -1)
 */
int init_tosubmsg(ARG1, struct submsg *save) {

    /* Open output file */
    /* Note that we have to use rb+ instead of ab in append mode, otherwise we cannot
       overwrite section 0 somewhere in the middle of the file */

    if (fopen_file(&(save->out), arg1, file_append ? "rb+" : "wb") != 0) {
        free(save);
        fatal_error("Could not open %s", arg1);
    }
    if (file_append) {
        /* rb+ mode positions file at the beginning */
        fseek_file(&(save->out), 0L, SEEK_END);
    }
    if (save->out.file_type == PIPE) fatal_error("tosubmsg: does not work with pipes %s", arg1);

    /* save start position in file for rewriting section 0 */
    save->start_pos = ftell_file(&(save->out));
    save->saved_space = 0;
    save->written_count = 0;
    save->written_bytes = 0;
    init_sec(save->last_sec);

    return 0;
}
예제 #2
0
파일: Tosubmsg.c 프로젝트: mmase/wgrib2
/*
 * init_tosubmsg: Initialisation (mode = -1)
 */
int init_tosubmsg(ARG1, struct submsg *save) {

    /* Open output file */
    /* Note that we have to use rb+ instead of ab in append mode, otherwise we cannot
       overwrite section 0 somewhere in the middle of the file */

    if ((save->output  = ffopen(arg1, file_append ? "rb+" : "wb")) == NULL) {
        fatal_error("Tosubmsg: Could not open %s", arg1);
    }
    if (file_append) {
        /* rb+ mode positions file at the beginning */
        fseek(save->output, 0L, SEEK_END);
    }

    /* save start position in file for rewriting section 0 */
    save->start_pos = ftell(save->output);
    save->saved_space = 0;
    save->written_count = 0;
    save->written_bytes = 0;
    init_sec(save->last_sec);

    return 0;
}
static int
read_map (struct read_map_ctxt *ctxt, struct so_list *so)
{
  ldr_module_info_t minf;
  ldr_region_info_t rinf;

#ifdef USE_LDR_ROUTINES
  size_t size;
  ldr_region_t i;

  /* Retrieve the next element.  */
  if (ldr_next_module (ctxt->proc, &ctxt->next) != 0)
    return 0;
  if (ctxt->next == LDR_NULL_MODULE)
    return 0;
  if (ldr_inq_module (ctxt->proc, ctxt->next, &minf, sizeof minf, &size) != 0)
    return 0;

  /* Initialize the module name and section count.  */
  init_so (so, minf.lmi_name, 0, minf.lmi_nregion);

  /* Retrieve section names and offsets.  */
  for (i = 0; i < minf.lmi_nregion; i++)
    {
      if (ldr_inq_region (ctxt->proc, ctxt->next, i, &rinf,
			  sizeof rinf, &size) != 0)
	goto err;
      init_sec (so, (int) i, 0, xstrdup (rinf.lri_name),
		(CORE_ADDR) rinf.lri_vaddr, (CORE_ADDR) rinf.lri_mapaddr);
    }
  lm_secs_sort (so->lm_info);
#else
  char *name;
  int errcode, i;

  /* Retrieve the next element.  */
  if (!ctxt->next)
    return 0;
  if (target_read_memory (ctxt->next, (char *) &minf, sizeof minf) != 0)
    return 0;
  if (ctxt->next == ctxt->tail)
    ctxt->next = 0;
  else
    ctxt->next = minf.next;

  /* Initialize the module name and section count.  */
  target_read_string (minf.module_name, &name, PATH_MAX, &errcode);
  if (errcode != 0)
    return 0;
  init_so (so, name, !minf.modinfo_addr, minf.region_count);
  xfree (name);

  /* Retrieve section names and offsets.  */
  for (i = 0; i < minf.region_count; i++)
    {
      if (target_read_memory (minf.regioninfo_addr + i * sizeof rinf,
			      (char *) &rinf, sizeof rinf) != 0)
	goto err;
      init_sec (so, i, rinf.regionname_addr, NULL, rinf.vaddr, rinf.mapaddr);
    }
#endif   /* !USE_LDR_ROUTINES */
  return 1;

 err:
  osf_free_so (so);
  return 0;
}
예제 #4
0
파일: New_grid.c 프로젝트: mmase/wgrib2
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;
}
예제 #5
0
void cce_dbdump(void)
{
	uint4	channel, status, flags, pid, real_size, req_size, size, addrs[2], sec_addrs[2];
	int		i, j, k, l;
	gds_file_id	file;
	m_iosb		stat_blk;
	sgmnt_data	*sd;
	unsigned char	mbuff[512], *c, *cptr, *ctop;
	$DESCRIPTOR(d_sec,mbuff);
	static readonly $DESCRIPTOR(d_cmd,"install lis/glo");
	static readonly $DESCRIPTOR(d_mnam,"CCE$DBDUMPMBX");
	static readonly $DESCRIPTOR(d_pnam,"CCE$DBDUMPPRC");
	char		filename[]="SYS$LOGIN:CCE_DBDUMP.DMP", buff[RECORD_SIZE], id_lab[]=" FILE ID:";
	struct FAB	fab;
	struct RAB	rab;
	error_def(ERR_CCEDBDUMP);
	error_def(ERR_CCEDBNODUMP);


	util_out_open(0);
	status = sys$crembx(0, &channel, 512, 0, 0, PSL$C_USER, &d_mnam);
	if (status != SS$_NORMAL)
		sys$exit(status);
	flags = CLI$M_NOWAIT | CLI$M_NOLOGNAM;
	status = lib$spawn(&d_cmd, 0, &d_mnam, &flags, &d_pnam, &pid);
	if (status != SS$_NORMAL)
	{	if (status == SS$_DUPLNAM)
		{	util_out_print("Spawned process CCE$DBDUMPPRC already exists, cannot continue rundown",TRUE);
		}
		sys$exit(status);
	}
	/* the following guess at the dump file size is modeled on the calculation for a section */
	size = DIVIDE_ROUND_UP((SIZEOF(sgmnt_data) + (WC_MAX_BUFFS + getprime(WC_MAX_BUFFS) + 1) * SIZEOF(bt_rec)
				+ (DEF_LOCK_SIZE / OS_PAGELET_SIZE)
				 + (WC_MAX_BUFFS + getprime(WC_MAX_BUFFS)) * SIZEOF(cache_rec) + SIZEOF(cache_que_heads)),
				OS_PAGELET_SIZE);
	size += EXTRA_SPACE;

	fab = cc$rms_fab;
	fab.fab$b_fac = FAB$M_PUT;
	fab.fab$l_fop = FAB$M_CBT | FAB$M_MXV | FAB$M_TEF;
	fab.fab$l_fna = filename;
	fab.fab$b_fns = SIZEOF(filename);
	fab.fab$b_rfm = FAB$C_FIX;
	fab.fab$w_mrs = RECORD_SIZE;
	fab.fab$w_deq = size;
	fab.fab$l_alq = size;
	switch (status = sys$create(&fab))
	{
	case RMS$_NORMAL:
	case RMS$_CREATED:
	case RMS$_SUPERSEDE:
	case RMS$_FILEPURGED:
		break;
	default:
		util_out_print("Error: Cannot create dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna);
		sys$exit(status);
	}

	rab = cc$rms_rab;
	rab.rab$l_fab = &fab;
	status = sys$connect(&rab);
	if (status != RMS$_NORMAL)
	{	util_out_print("Error: Cannot connect to dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna);
		sys$exit(status);
	}
	rab.rab$w_rsz = SIZEOF(buff);

	for (; ;)
	{	status = sys$qiow (0, channel,IO$_READVBLK ,&stat_blk, 0, 0, mbuff, 512,0,0,0,0);
		if (status != SS$_NORMAL)
		{	sys$exit(status);
			break;
		}
		if (stat_blk.status == SS$_ENDOFFILE)
			break;
		if (stat_blk.status != SS$_NORMAL)
		{	sys$exit(stat_blk.status);
			break;
		}
		if (!memcmp("GT$S",mbuff,4))
		{	for ( c = mbuff; *c > 32 ; c++)
				;
			d_sec.dsc$w_length = c - mbuff;
			flags = SEC$M_GBL | SEC$M_WRT | SEC$M_SYSGBL | SEC$M_PAGFIL | SEC$M_DZRO | SEC$M_PERM;
			addrs[0] = addrs[1] = 0;
			fid_from_sec(&d_sec,&file);

			real_size = cce_sec_size(&file);
			if (real_size == 0)
				real_size = size;
			real_size += 1;

			assert(OS_PAGE_SIZE % OS_PAGELET_SIZE == 0);

			/* Request enough pagelets to ensure enough contiguous pages to contain desired number of pagelets. */
			req_size = ROUND_UP(real_size, OS_PAGE_SIZE);
			lib$get_vm_page(&req_size, &addrs[0]);

			/* addrs will hold addresses of start and end of contiguous block of pagelets for use by $deltva. */
			assert((addrs[0] + (req_size * OS_PAGELET_SIZE) - 1) == addrs[1]);

			/* $get_vm_page returns pagelets; we must align to integral page boundary. */
			/* sec_addrs will contain the starting and ending addresses of the mapped section. */
			sec_addrs[0] = ROUND_UP(addrs[0], OS_PAGE_SIZE);	/* align to first integral page boundary */
			sec_addrs[1] = addrs[0] + (real_size * OS_PAGELET_SIZE);
			sec_addrs[1] = ROUND_UP(addrs[1], OS_PAGE_SIZE) - 1;  /* A(last byte of last page) */

			status = init_sec(sec_addrs, &d_sec, 0, real_size, flags);
			if (status & 1)
			{
				sd = sec_addrs[0];
				memset(buff, 0, RECORD_SIZE);
				memcpy(buff, d_sec.dsc$a_pointer, d_sec.dsc$w_length);
				cptr = &buff[0] + d_sec.dsc$w_length;
				memcpy(cptr,id_lab,SIZEOF(id_lab));
				cptr += SIZEOF(id_lab);
				memcpy(cptr,&file,SIZEOF(file));
				rab.rab$l_rbf = buff;
				status = sys$put(&rab);
				if (status != RMS$_NORMAL)
				{	util_out_print("Error writing to dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna);
					util_out_print("Status code is !UL.",TRUE,status);
					break;
				}
				for (c = sd, i = 0; (real_size + EXTRA_SPACE) >= i;
					c += RECORD_SIZE, i += (RECORD_SIZE / DISK_BLOCK_SIZE))
				{
					rab.rab$l_rbf = c;
					status = sys$put(&rab);
					if (status != RMS$_NORMAL)
					{	util_out_print("Error writing to dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna);
						util_out_print("Status code is !UL.",TRUE,status);
						break;
					}
				}
				lib$signal(ERR_CCEDBDUMP,2,d_sec.dsc$w_length,d_sec.dsc$a_pointer);
			}else
			{	lib$signal(ERR_CCEDBNODUMP,2,d_sec.dsc$w_length,d_sec.dsc$a_pointer,status,0);
			}
			gtm_deltva(&addrs[0],0,0);
			lib$free_vm_page(&real_size,&addrs[0]);
		}
	}
	sys$exit(SS$_NORMAL);
}
예제 #6
0
unsigned char mu_cre_file(void)
{
	unsigned char		*inadr[2], *c, exit_stat;
	enum db_acc_method	temp_acc_meth;
	uint4			lcnt, retadr[2];
	int4			blk_init_size, initial_alq, free_blocks;
	gtm_uint64_t		free_blocks_ll, blocks_for_extension;
	char			buff[GLO_NAME_MAXLEN], fn_buff[MAX_FN_LEN];
	unsigned int		status;
	int			free_space;
	struct FAB		*fcb;
	struct NAM		nam;
	gds_file_id		new_id;
	io_status_block_disk	iosb;
	char			node[16];
	short			len;
	struct {
		short	blen;
		short	code;
		char	*buf;
		short	*len;
		int4	terminator;
	} item = {15, SYI$_NODENAME, &node, &len, 0};
	$DESCRIPTOR(desc, buff);

	exit_stat = EXIT_NRM;
/* The following calculations should duplicate the BT_SIZE macro from GDSBT and the LOCK_BLOCK macro from GDSFHEAD.H,
 * but without using a sgmnt_data which is not yet set up at this point
 */

#ifdef GT_CX_DEF
	/* This section needs serious chnages for the fileheader changes in V5 if it is ever resurrected */
	over_head = DIVIDE_ROUND_UP(SIZEOF_FILE_HDR_DFLT
			+ (WC_MAX_BUFFS + getprime(WC_MAX_BUFFS) + 1) * SIZEOF(bt_rec), DISK_BLOCK_SIZE);
	if (gv_cur_region->dyn.addr->acc_meth == dba_bg)
	{
		free_space = over_head - DIVIDE_ROUND_UP(SIZEOF_FILE_HDR_DFLT
			+ (gv_cur_region->dyn.addr->global_buffers + getprime(gv_cur_region->dyn.addr->global_buffers) + 1)
				* SIZEOF(bt_rec), DISK_BLOCK_SIZE);
		over_head += gv_cur_region->dyn.addr->lock_space ? gv_cur_region->dyn.addr->lock_space
								 : DEF_LOCK_SIZE / OS_PAGELET_SIZE;
	} else if (gv_cur_region->dyn.addr->acc_meth == dba_mm)
	{
		free_space = over_head - DIVIDE_ROUND_UP(SIZEOF_FILE_HDR_DFLT, DISK_BLOCK_SIZE);
		if (gv_cur_region->dyn.addr->lock_space)
		{
			over_head += gv_cur_region->dyn.addr->lock_space;
			free_space += gv_cur_region->dyn.addr->lock_space;
		} else
		{
			over_head += DEF_LOCK_SIZE / OS_PAGELET_SIZE;
			free_space += DEF_LOCK_SIZE / OS_PAGELET_SIZE;
		}
	}
	free_space *= DISK_BLOCK_SIZE;
#else
	assert(START_VBN_CURRENT > DIVIDE_ROUND_UP(SIZEOF_FILE_HDR_DFLT, DISK_BLOCK_SIZE));
	free_space = ((START_VBN_CURRENT - 1) * DISK_BLOCK_SIZE) - SIZEOF_FILE_HDR_DFLT;
#endif
	switch (gv_cur_region->dyn.addr->acc_meth)
	{
		case dba_bg:
		case dba_mm:
			mu_cre_vms_structs(gv_cur_region);
			fcb = ((vms_gds_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->fab;
			cs_addrs = &((vms_gds_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->s_addrs;

			fcb->fab$b_shr &= FAB$M_NIL;	/* No access to this file while it is created */
			fcb->fab$l_nam = &nam;
			nam = cc$rms_nam;
			/* There are (bplmap - 1) non-bitmap blocks per bitmap, so add (bplmap - 2) to number of non-bitmap blocks
			 * and divide by (bplmap - 1) to get total number of bitmaps for expanded database. (must round up in this
			 * manner as every non-bitmap block must have an associated bitmap)
			*/
			fcb->fab$l_alq += DIVIDE_ROUND_UP(fcb->fab$l_alq, BLKS_PER_LMAP - 1);	/* Bitmaps */
			blk_init_size = fcb->fab$l_alq;
			fcb->fab$l_alq *= BLK_SIZE / DISK_BLOCK_SIZE;
			fcb->fab$l_alq += START_VBN_CURRENT - 1;
			initial_alq = fcb->fab$l_alq;
			fcb->fab$w_mrs = 512;				/* no longer a relevent field to us */
			break;
		case dba_usr:
			util_out_print("Database file for region !AD not created; access method is not GDS.", TRUE,
				REG_LEN_STR(gv_cur_region));
			return EXIT_WRN;
		default:
			gtm_putmsg(VARLSTCNT(1) ERR_BADACCMTHD);
			return EXIT_ERR;
	}
	nam.nam$b_ess = SIZEOF(fn_buff);
	nam.nam$l_esa = fn_buff;
	nam.nam$b_nop |= NAM$M_SYNCHK;
	status = sys$parse(fcb, 0, 0);
	if (RMS$_NORMAL != status)
	{
		gtm_putmsg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna, status, 0, fcb->fab$l_stv, 0);
		return EXIT_ERR;
	}
	if (nam.nam$b_node != 0)
	{
		status = sys$getsyiw(EFN$C_ENF, 0, 0, &item, &iosb, 0, 0);
		if (SS$_NORMAL == status)
			status = iosb.cond;
		if (SS$_NORMAL == status)
		{
			if (len == nam.nam$b_node-2 && !memcmp(nam.nam$l_esa, node, len))
			{
				fcb->fab$l_fna = nam.nam$l_esa + nam.nam$b_node;
				fcb->fab$b_fns = nam.nam$b_esl - nam.nam$b_node;
			}
		} else
		{
			util_out_print("Could not get node for !AD.", TRUE, REG_LEN_STR(gv_cur_region));
			exit_stat = EXIT_WRN;
		}
	}
	assert(gv_cur_region->dyn.addr->acc_meth == dba_bg || gv_cur_region->dyn.addr->acc_meth == dba_mm);
	nam.nam$l_esa = NULL;
	nam.nam$b_esl = 0;
	status = sys$create(fcb);
	if (status != RMS$_CREATED && status != RMS$_FILEPURGED)
	{
		switch(status)
		{
			case RMS$_FLK:
		 		util_out_print("Database file for region !AD not created; currently locked by another user.", TRUE,
					REG_LEN_STR(gv_cur_region));
				exit_stat = EXIT_INF;
				break;
			case RMS$_NORMAL:
		 		util_out_print("Database file for region !AD not created; already exists.", TRUE,
					REG_LEN_STR(gv_cur_region));
				exit_stat = EXIT_INF;
				break;
			case RMS$_SUPPORT:
				util_out_print("Database file for region !AD not created; cannot create across network.", TRUE,
					REG_LEN_STR(gv_cur_region));
				exit_stat = EXIT_WRN;
				break;
			case RMS$_FUL:
				send_msg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna,
					status, 0, fcb->fab$l_stv, 0);
				/* intentionally falling through */
			default:
				gtm_putmsg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna,
					status, 0, fcb->fab$l_stv, 0);
				exit_stat = EXIT_ERR;
		}
		sys$dassgn(fcb->fab$l_stv);
		return exit_stat;
	}

	memcpy(new_id.dvi, nam.nam$t_dvi, SIZEOF(nam.nam$t_dvi));
	memcpy(new_id.did, nam.nam$w_did, SIZEOF(nam.nam$w_did));
	memcpy(new_id.fid, nam.nam$w_fid, SIZEOF(nam.nam$w_fid));
	global_name("GT$S", &new_id, buff);		/* 2nd parm is actually a gds_file_id * in global_name */
	desc.dsc$w_length = buff[0];			/* By definition, a gds_file_id is dvi,fid,did from nam */
	desc.dsc$a_pointer = &buff[1];
	cs_addrs->db_addrs[0] = cs_addrs->db_addrs[1] = inadr[0] = inadr[1] = inadr;	/* used to determine p0 or p1 allocation */
	status = init_sec(cs_addrs->db_addrs, &desc, fcb->fab$l_stv, (START_VBN_CURRENT - 1),
			  SEC$M_DZRO|SEC$M_GBL|SEC$M_WRT|SEC$M_EXPREG);
	if ((SS$_CREATED != status) && (SS$_NORMAL != status))
	{
		gtm_putmsg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna, status, 0, fcb->fab$l_stv, 0);
		sys$dassgn(fcb->fab$l_stv);
		return EXIT_ERR;
	}
	cs_data = (sgmnt_data *)cs_addrs->db_addrs[0];
	memset(cs_data, 0, SIZEOF_FILE_HDR_DFLT);
	cs_data->createinprogress = TRUE;
	cs_data->trans_hist.total_blks = (initial_alq - (START_VBN_CURRENT - 1)) / (BLK_SIZE / DISK_BLOCK_SIZE);
	/* assert that total_blks stored in file-header = non-bitmap blocks (initial allocation) + bitmap blocks */
	assert(cs_data->trans_hist.total_blks == gv_cur_region->dyn.addr->allocation +
				DIVIDE_ROUND_UP(gv_cur_region->dyn.addr->allocation, BLKS_PER_LMAP - 1));
	cs_data->start_vbn = START_VBN_CURRENT;
	temp_acc_meth = gv_cur_region->dyn.addr->acc_meth;
	cs_data->acc_meth = gv_cur_region->dyn.addr->acc_meth = dba_bg;
	cs_data->extension_size = gv_cur_region->dyn.addr->ext_blk_count;
	mucregini(blk_init_size);
	cs_addrs->hdr->free_space = free_space;
#ifndef GT_CX_DEF
	cs_addrs->hdr->unbacked_cache = TRUE;
#endif
	cs_data->acc_meth = gv_cur_region->dyn.addr->acc_meth = temp_acc_meth;
	cs_data->createinprogress = FALSE;
	if (SS$_NORMAL == (status = disk_block_available(fcb->fab$l_stv, &free_blocks)))
	{
		blocks_for_extension = (cs_data->blk_size / DISK_BLOCK_SIZE *
				  (DIVIDE_ROUND_UP(EXTEND_WARNING_FACTOR * (gtm_uint64_t)cs_data->extension_size, BLKS_PER_LMAP - 1)
					 + EXTEND_WARNING_FACTOR * (gtm_uint64_t)cs_data->extension_size));
		if ((gtm_uint64_t)free_blocks < blocks_for_extension)
		{
			free_blocks_ll = (gtm_uint64_t)free_blocks;
			gtm_putmsg(VARLSTCNT(8) ERR_LOWSPACECRE, 6, fcb->fab$b_fns, fcb->fab$l_fna, EXTEND_WARNING_FACTOR,
					&blocks_for_extension, DISK_BLOCK_SIZE, &free_blocks_ll);
			send_msg(VARLSTCNT(8) ERR_LOWSPACECRE, 6, fcb->fab$b_fns, fcb->fab$l_fna, EXTEND_WARNING_FACTOR,
					&blocks_for_extension, DISK_BLOCK_SIZE, &free_blocks_ll);
		}
	}
	if (SS$_NORMAL == (status = sys$updsec(((vms_gds_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->s_addrs.db_addrs,
			NULL, PSL$C_USER, 0, efn_immed_wait, &iosb, NULL, 0)))
	{
		status = sys$synch(efn_immed_wait, &iosb);
		if (SS$_NORMAL == status)
			status = iosb.cond;
	} else  if (SS$_NOTMODIFIED == status)
		status = SS$_NORMAL;
	if (SS$_NORMAL == status)
		status = del_sec(SEC$M_GBL, &desc, 0);
	if (SS$_NORMAL == status)
		status = sys$deltva(cs_addrs->db_addrs, retadr, PSL$C_USER);
	if (SS$_NORMAL == status)
		status = sys$dassgn(fcb->fab$l_stv);
	if (SS$_NORMAL == status)
	{
	 	util_out_print("Database file for region !AD created.", TRUE, REG_LEN_STR(gv_cur_region));
		/* the open and close are an attempt to ensure that the file is available, not under the control of an ACP,
		 * before MUPIP exits */
		fcb->fab$b_shr = FAB$M_SHRPUT | FAB$M_SHRGET | FAB$M_UPI;
		fcb->fab$l_fop = 0;
		for (lcnt = 1;  (60 * MAX_OPEN_RETRY) >= lcnt;  lcnt++)
		{	/* per VMS engineering a delay is expected.  We will wait up to an hour as a
			 * Delete Global Section operation is essentially and inherently asynchronous in nature
			 * and could take an arbitrary amount of time.
			 */
			if (RMS$_FLK != (status = sys$open(fcb, NULL, NULL)))
				break;
			wcs_sleep(lcnt);
		}
		assert(RMS$_NORMAL == status);
		if (RMS$_NORMAL == status)
		{
			status = sys$close(fcb);
			assert(RMS$_NORMAL == status);
		}
		if (RMS$_NORMAL != status)
			exit_stat = EXIT_WRN;
	} else
		exit_stat = EXIT_ERR;
	if (RMS$_NORMAL != status)
		gtm_putmsg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna, status, 0, fcb->fab$l_stv, 0);
	if ((MAX_RMS_RECORDSIZE - SIZEOF(shmpool_blk_hdr)) < cs_data->blk_size)
		gtm_putmsg(VARLSTCNT(5) ERR_MUNOSTRMBKUP, 3, fcb->fab$b_fns, fcb->fab$l_fna, 32 * 1024 - DISK_BLOCK_SIZE);
	return exit_stat;
}
예제 #7
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;
}
예제 #8
0
파일: Submsg_uv.c 프로젝트: mmase/wgrib2
int f_submsg_uv(ARG1) {

    struct local_struct {
        unsigned char *sec[9];
	const char *vname;    
        FILE *output;
    };

    struct local_struct *save;
    int i, j, is_v;
    unsigned long int size;
    char name[NAMELEN];
    unsigned char s[8];

    if (mode == -1) {		// initialization

        // allocate static structure

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

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

    save = (struct local_struct *) *local;

    if (mode == -2)  {		// cleanup
	if (save->vname != NULL) {		// write out cached field
	   i = wrt_sec(save->sec[0], save->sec[1], save->sec[2], save->sec[3], 
		save->sec[4], save->sec[5], save->sec[6], save->sec[7], save->output);
	   if (i) fatal_error_i("submsg_uv: last record problem %i",i);
           free_sec(save->sec);
	}
	ffclose(save->output);
        free(save);
	return 0;
    }

    if (mode >= 0 )  {					// processing
        i = getName(sec, mode, NULL, name, NULL, NULL);

	/* see if name == expected vname */
	is_v = 0;
	if (save->vname != NULL && strcmp(name, save->vname) == 0) {
	    is_v = 1;
            if (same_sec0(sec,save->sec) == 0) is_v = 0;
            if (same_sec1(sec,save->sec) == 0) is_v = 0;
            if (same_sec2(sec,save->sec) == 0) is_v = 0;
            if (same_sec3(sec,save->sec) == 0) is_v = 0;

	    i = GB2_ParmNum(sec);
	    j = GB2_ParmCat(sec);
	    GB2_ParmNum(sec) = GB2_ParmNum(save->sec);
	    GB2_ParmCat(sec) = GB2_ParmCat(save->sec);
            if (same_sec4(sec,save->sec) == 0) is_v = 0;
	    GB2_ParmNum(sec) = i;
	    GB2_ParmCat(sec) = j;
	}

	/* finished tests for U/V sequence */

	/* is U/V sequence */
	if (is_v) {
	    size = (unsigned long int) GB2_Sec0_size + GB2_Sec8_size +
	    (sec[1] ? uint4(sec[1]) : 0) +
	    (sec[2] ? uint4(sec[2]) : 0) +
	    (sec[3] ? uint4(sec[3]) : 0) +
	    (sec[4] ? uint4(sec[4]) : 0) +
	    (sec[5] ? uint4(sec[5]) : 0) +
	    (sec[6] ? uint4(sec[6]) : 0) +
	    (sec[7] ? uint4(sec[7]) : 0) +
	    (save->sec[4] ? uint4(save->sec[4]) : 0) +
	    (save->sec[5] ? uint4(save->sec[5]) : 0) +
	    (save->sec[6] ? uint4(save->sec[6]) : 0) +
	    (save->sec[7] ? uint4(save->sec[7]) : 0);

	    fwrite((void *) sec[0], sizeof(char), 8, save->output);
            uint8_char(size, s);
            fwrite((void *) s, sizeof(char), 8, save->output);

            if (sec[1]) {
                i = uint4(sec[1]);
                if (fwrite((void *)sec[1], sizeof(char), i, save->output) != i) return 1;
            }
            if (sec[2]) {
                i = uint4(sec[2]);
                if (fwrite((void *)sec[2], sizeof(char), i, save->output) != i) return 1;
            }
            if (sec[3]) {
                i = uint4(sec[3]);
                if (fwrite((void *)sec[3], sizeof(char), i, save->output) != i) return 1;
            }
            if (save->sec[4]) {
                i = uint4(save->sec[4]);
                if (fwrite((void *)save->sec[4], sizeof(char), i, save->output) != i) return 1;
            }
            if (save->sec[5]) {
                i = uint4(save->sec[5]);
                if (fwrite((void *)save->sec[5],sizeof(char), i, save->output) != i) return 1;
            }
            if (save->sec[6]) {
                i = uint4(save->sec[6]);
                if (fwrite((void *)save->sec[6],sizeof(char), i, save->output) != i) return 1;
            }
            if (save->sec[7]) {
                i = uint4(save->sec[7]);
                if (fwrite((void *)save->sec[7],sizeof(char), i, save->output) != i) return 1;
            }
            if (sec[4]) {
                i = uint4(sec[4]);
                if (fwrite((void *)sec[4], sizeof(char), i, save->output) != i) return 1;
            }
            if (sec[5]) {
                i = uint4(sec[5]);
                if (fwrite((void *)sec[5], sizeof(char), i, save->output) != i) return 1;
            }
            if (sec[6]) {
                i = uint4(sec[6]);
                if (fwrite((void *)sec[6], sizeof(char), i, save->output) != i) return 1;
            }
            if (sec[7]) {
                i = uint4(sec[7]);
                if (fwrite((void *)sec[7], sizeof(char), i, save->output) != i) return 1;
            }

            s[0] = s[1] = s[2] = s[3] = 55; /* s = "7777" */
            if (fwrite((void *) s, sizeof(char), 4, save->output) != 4)
	           fatal_error("submsg_uv: write record problem","");

	    save->vname = NULL;
            free_sec(save->sec);
            return 0;
	}

	/* has U but not V, write U */    

	if (save->vname != NULL) {
	   i = wrt_sec(save->sec[0], save->sec[1], save->sec[2], save->sec[3], 
		save->sec[4], save->sec[5], save->sec[6], save->sec[7], save->output);
	   if (i) fatal_error_i("submsg_uv: write record problem %i",i);
	   free_sec(save->sec);
	   save->vname = NULL;
	}

	/* check to see if new field is a U */

	save->vname = is_u(name);

	/* if U, cache it */
	if (save->vname != NULL) {
	    copy_sec(sec,save->sec);
	    return 0;
	}

	/* not U, write it out */
	i = wrt_sec(sec[0], sec[1], sec[2], sec[3], sec[4], sec[5], sec[6], sec[7], save->output);
	if (i) fatal_error_i("submsg_uv: write problem %i",i);
	return 0;
    }
    return 0;
}
예제 #9
0
파일: NCEP_norm.c 프로젝트: mmase/wgrib2
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;
}
예제 #10
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;
}
예제 #11
0
파일: Fcst_ave.c 프로젝트: mmase/wgrib2
int f_fcst_ave(ARG2) {

    struct ave_struct *save;

    int i, pdt, new_type;
    int year, month, day, hour, minute, second;
    int tyear, tmonth, tday, thour, tminute, tsecond;
    int missing;
    char string[10];

    // initialization

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

	// allocate static structure

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

	i = sscanf(arg1, "%d%2s", &save->dt,string);
	if (i != 2) fatal_error("fcst_ave: delta-time: (int)(2 characters) %s", arg1);
	save->dt_unit = -1;
	if (strcmp(string,"hr") == 0) save->dt_unit = 1;
	else if (strcmp(string,"dy") == 0) save->dt_unit = 2;
	else if (strcmp(string,"mo") == 0) save->dt_unit = 3;
	else if (strcmp(string,"yr") == 0) save->dt_unit = 4;
	if (save->dt_unit == -1) fatal_error("fcst_ave: unsupported time unit %s", string);

        if ((save->output = ffopen(arg2, file_append ? "ab" : "wb")) == NULL) {
	    fatal_error("fcst_ave: could not open file %s", arg2);
	}

	save->has_val = 0;
	save->n = NULL;
	save->sum = NULL;
        init_sec(save->first_sec);
        init_sec(save->next_sec);

	return 0;
    }

    save = (struct ave_struct *) *local;

    if (mode == -2) {			// cleanup
	if (save->has_val == 1) {
	    do_ave(save);
	}
	ffclose(save->output);
	free_ave_struct(save);
	return 0;
    }

    // if data
    if (mode >= 0) {
	// 1/2015 use_scale = 0;
	pdt = GB2_ProdDefTemplateNo(sec);

if (mode == 98) fprintf(stderr,"fcst_ave: pdt=%d\n",pdt);
	// only support pdt == 0, 1 and 8
	if (pdt != 0 && pdt != 1 && pdt != 8) return 0;

	// first time through .. save data and return


	if (save->has_val == 0) {		// new data: write and save
	    init_ave_struct(save,ndata);
	    add_to_ave_struct(save, sec, data, ndata, 0);

	    // copy sec
            copy_sec(sec, save->first_sec);
            copy_sec(sec, save->next_sec);

	    // get reference time and save it
            get_time(sec[1]+12,&save->ref_year, &save->ref_month, &save->ref_day, &save->ref_hour, &save->ref_minute, &save->ref_second);

	    if (start_ft(sec, &save->fcst_year, &save->fcst_month, &save->fcst_day, &save->fcst_hour, 
			&save->fcst_minute, &save->fcst_second) != 0) {
		fatal_error("fcst_ave: could not determine the start FT time","");
	    }

	    // get verf time and save it
	    if (verftime(sec, &save->year2, &save->month2, &save->day2, &save->hour2, &save->minute2, &save->second2) != 0) {
		fatal_error("fcst_ave: could not determine the verification time","");
	    }

	    save->has_val = 1;
	    return 0;
	}

	// check to see if new variable

        new_type = 0;

	// get the reference time of field
	get_time(sec[1]+12, &year, &month, &day, &hour, &minute, &second);

	// see if reference time has not changed
        if (year != save->ref_year) new_type = 1;
        else if (month != save->ref_month) new_type = 1;
        else if (day != save->ref_day) new_type = 1;
        else if (hour != save->ref_hour) new_type = 1;
        else if (minute != save->ref_minute) new_type = 1;
        else if (second != save->ref_second) new_type = 1;

        if (new_type == 0) {
	    if (same_sec0(sec,save->first_sec) == 0 ||
                same_sec1_not_time(sec,save->first_sec) == 0 ||
                same_sec3(sec,save->first_sec) == 0 ||
                same_sec4_not_time(sec,save->first_sec) == 0) 
	        new_type = 1;
if (mode == 98) fprintf(stderr, "fcst_ave: testsec %d %d %d %d\n", same_sec0(sec,save->first_sec),
                same_sec1_not_time(sec,save->first_sec),
                same_sec3(sec,save->first_sec),
                same_sec4_not_time(sec,save->first_sec));
        }
if (mode == 98) fprintf(stderr, "fcst_ave: new_type %d\n", new_type);

	// unlike f_ave, assume no missing .. it is a fcst not observations
	// check to see if verification date is expected value

	if (new_type == 0) {
	    tyear = save->fcst_year;
	    tmonth = save->fcst_month;
	    tday = save->fcst_day;
	    thour = save->fcst_hour;
	    tminute = save->fcst_minute;
	    tsecond = save->fcst_second;
            add_time(&tyear, &tmonth, &tday, &thour, &tminute, &tsecond, save->dt, save->dt_unit);
	    if (start_ft(sec, &year, &month, &day, &hour, &minute, &second) != 0) 
		fatal_error("fcst_ave: could not determine the start_ft time","");
            if (cmp_time(year,month,day,hour,minute,second,tyear,tmonth,tday,thour,tminute,tsecond)) {
		new_type = 1;
if (mode == 98) fprintf(stderr, "fcst_ave: unexpected verf time, new_type=1\n");
	    }
	    else {
	        save->fcst_year = year;
	        save->fcst_month = month;
	        save->fcst_day = day;
	        save->fcst_hour = hour;
	        save->fcst_minute = minute;
	        save->fcst_second = second;
	    }
	}

	// check to see if verification date is expected value

        missing = 0;
	if (new_type == 0) {
	    if (verftime(sec, &year, &month, &day, &hour, &minute, &second) != 0) 
		fatal_error("fcst_ave: could not determine the verification time","");
	    tyear = save->year2;
	    tmonth = save->month2;
	    tday = save->day2;
	    thour = save->hour2;
	    tminute = save->minute2;
	    tsecond = save->second2;
            add_time(&tyear, &tmonth, &tday, &thour, &tminute, &tsecond, save->dt, save->dt_unit);
            if (cmp_time(year,month,day,hour,minute,second,tyear,tmonth,tday,thour,tminute,tsecond) != 0) new_type = 1;
	    else {
	        save->year2 = year;
	        save->month2 = month;
	        save->day2 = day;
	        save->hour2 = hour;
	        save->minute2 = minute;
	        save->second2 = second;
	    }
	}

	// if data is the same as the previous, update the sum

if (mode == 98) fprintf(stderr, "fcst_ave ave: before update_sum  new_type %d\n", new_type);

	if (new_type == 0) {		// update sum
if (mode == 98) fprintf(stderr, "fcst_ave: update sum\n");
	    add_to_ave_struct(save, sec, data, ndata, missing);
	    return 0;
	}

	// new field, do grib output and save current data

	do_ave(save);
        init_ave_struct(save, ndata);
	add_to_ave_struct(save, sec, data, ndata, 0);
        copy_sec(sec, save->first_sec);
        copy_sec(sec, save->next_sec);

        // get reference time and save it
        get_time(sec[1]+12,&save->ref_year, &save->ref_month, &save->ref_day, &save->ref_hour, &save->ref_minute, &save->ref_second);
        if (start_ft(sec, &save->fcst_year, &save->fcst_month, &save->fcst_day, &save->fcst_hour,
                     &save->fcst_minute, &save->fcst_second) != 0) {
           fatal_error("fcst_ave: could not determine the start FT time","");
        }

        // get verf time and save it
        if (verftime(sec, &save->year2, &save->month2, &save->day2, &save->hour2, &save->minute2, &save->second2) != 0) {
            fatal_error("fcst_ave: could not determine the verification time","");
        }

        save->has_val = 1;
	return 0;
    }
    return 0;
}