int ggrd_grdtrack_init(double *west, double *east, double *south, double *north, float **f,int *mm,char *grdfile, struct GRD_HEADER **grd, struct GMT_EDGEINFO **edgeinfo, char *edgeinfo_string, ggrd_boolean *geographic_in, int *pad,ggrd_boolean three_d, char *dfile, float **z,int *nz, ggrd_boolean interpolant, ggrd_boolean verbose, ggrd_boolean change_depth_sign, struct BCR *loc_bcr) #endif { FILE *din; float dz1,dz2; struct GRD_HEADER ogrd; int i,one_or_zero,nx,ny,mx,my; char filename[BUFSIZ*2],*cdummy; static int gmt_init = FALSE; /* deal with edgeinfo */ *edgeinfo = (struct GMT_EDGEINFO *) GMT_memory (VNULL, (size_t)1, sizeof(struct GMT_EDGEINFO), "ggrd_grdtrack_init"); /* init with nonsense to avoid compiler warning */ ogrd.x_min = ogrd.y_min =ogrd.x_max = ogrd.y_max = -100; ogrd.x_inc = ogrd.y_inc = -1; ogrd.node_offset = 0;ogrd.nx = ogrd.ny = -1; #ifndef USE_GMT3 if(!gmt_init){ /* this should be OK as is. init only once globally */ GMT_program = "ggrd"; GMT_make_fnan (GMT_f_NaN); GMT_make_dnan (GMT_d_NaN); GMT_io_init ();/* Init the table i/o structure */ GMT_grdio_init(); if(strcmp(edgeinfo_string,"-fg")==0){ GMT_io.in_col_type[GMT_X] = GMT_io.out_col_type[GMT_X] = GMT_IS_LON; GMT_io.in_col_type[GMT_Y] = GMT_io.out_col_type[GMT_Y] = GMT_IS_LAT; } if(strcmp(edgeinfo_string,"-fx")==0){ GMT_io.in_col_type[GMT_X] = GMT_io.out_col_type[GMT_X] = GMT_IS_LON; } if(strcmp(edgeinfo_string,"-fy")==0){ GMT_io.in_col_type[GMT_Y] = GMT_io.out_col_type[GMT_Y] = GMT_IS_LAT; } gmt_init = TRUE; } #endif /* init first edgeinfo (period/global?) */ GMT_boundcond_init (*edgeinfo); /* check if geographic */ if (strlen(edgeinfo_string)>2){ /* the boundary flag was set */ /* parse */ GMT_boundcond_parse (*edgeinfo, (edgeinfo_string+2)); if ((*edgeinfo)->gn) *geographic_in = 1; else if((*edgeinfo)->nxp == -1) *geographic_in = 2; else *geographic_in = 0; }else{ *geographic_in = 0; } if(verbose >= 2) if(*geographic_in) fprintf(stderr,"ggrd_grdtrack_init: detected geographic region from geostring: %s\n", edgeinfo_string); *z = (float *) GMT_memory (VNULL, (size_t)1, sizeof(float), "ggrd_grdtrack_init"); if(three_d){ /* three D part first */ /* init the layers */ din = fopen(dfile,"r"); if(!din){ fprintf(stderr,"ggrd_grdtrack_init: could not open depth file %s\n", dfile); return 1; } /* read in the layers */ *nz = 0; dz1 = -1; while(fscanf(din,"%f",(*z+ (*nz))) == 1){ if(change_depth_sign) *(*z+ (*nz)) = -(*(*z+ (*nz))); /* read in each depth layer */ *z = (float *) GMT_memory ((void *)(*z), (size_t)((*nz)+2), sizeof(float), "ggrd_grdtrack_init"); if(*nz > 0){ /* check for increasing layers */ if(dz1 < 0){ /* init first interval */ dz1 = *(*z+(*nz)) - *(*z+(*nz)-1); dz2 = dz1; }else{ /* later intervals */ dz2 = *(*z+(*nz)) - *(*z+(*nz)-1); } if(dz2 <= 0.0){ /* check for monotonic increase */ fprintf(stderr,"%s: error: levels in %s have to increase monotonically: n: %i dz; %g\n", "ggrd_grdtrack_init",dfile,*nz,dz2); return 2; } } *nz += 1; } fclose(din); /* end layer init"ggrd_grdtrack_initialization */ if(*nz < 2){ fprintf(stderr,"%s: error: need at least two layers in %s\n", "ggrd_grdtrack_init", dfile); return 3; } if(verbose) fprintf(stderr,"%s: read %i levels from %s between zmin: %g and zmax: %g\n", "ggrd_grdtrack_init",*nz,dfile,*(*z+0),*(*z+(*nz)-1)); }else{ *nz = 1; *(*z) = 0.0; if(verbose >= 2) fprintf(stderr,"ggrd_grdtrack_init: single level at z: %g\n",*(*z)); } /* get nz grd and edgeinfo structures */ *grd = (struct GRD_HEADER *) GMT_memory (NULL, (size_t)(*nz), sizeof(struct GRD_HEADER), "ggrd_grdtrack_init"); *edgeinfo = (struct GMT_EDGEINFO *) GMT_memory (*edgeinfo, (size_t)(*nz), sizeof(struct GMT_EDGEINFO), "ggrd_grdtrack_init"); if(verbose >= 2) fprintf(stderr,"ggrd_grdtrack_init: mem alloc ok\n"); #ifndef USE_GMT3 /* init the header */ GMT_grd_init (*grd,0,&cdummy,FALSE); #endif if(*nz == 1){ if(verbose >= 2) #ifdef USE_GMT3 /* old */ fprintf(stderr,"ggrd_grdtrack_init: opening single file %s, GMT3 mode\n",grdfile); if (GMT_cdf_read_grd_info (grdfile,(*grd))) { fprintf (stderr, "%s: error opening file %s\n", "ggrd_grdtrack_init", grdfile); return 4; } #else /* >=4.1.2 */ if(verbose >= 2) fprintf(stderr,"ggrd_grdtrack_init: opening single file %s, GMT4 mode\n",grdfile); if(GMT_read_grd_info (grdfile,*grd)){ fprintf (stderr, "%s: error opening file %s for header\n", "ggrd_grdtrack_init", grdfile); return 4; } #endif }else{ /* loop through headers for testing purposess */ for(i=0;i<(*nz);i++){ sprintf(filename,"%s.%i.grd",grdfile,i+1); #ifdef USE_GMT3 if (GMT_cdf_read_grd_info (filename, (*grd+i))) { fprintf (stderr, "%s: error opening file %s (-D option was used)\n", "ggrd_grdtrack_init", filename); return 6; } #else /* gmt 4 */ if (GMT_read_grd_info (filename,(*grd+i))) { fprintf (stderr, "%s: error opening file %s (-D option was used)\n", "ggrd_grdtrack_init", filename); return 6; } #endif if(i == 0){ /* save the first grid parameters */ ogrd.x_min = (*grd)[0].x_min; ogrd.y_min = (*grd)[0].y_min; ogrd.x_max = (*grd)[0].x_max; ogrd.y_max = (*grd)[0].y_max; ogrd.x_inc = (*grd)[0].x_inc; ogrd.y_inc = (*grd)[0].y_inc; ogrd.node_offset = (*grd)[0].node_offset; ogrd.nx = (*grd)[0].nx; ogrd.ny = (*grd)[0].ny; /* make sure we are in 0 ... 360 system */ if((ogrd.x_min < 0)||(ogrd.x_max<0)){ fprintf(stderr,"%s: WARNING: geographic grids should be in 0..360 lon system (found %g - %g)\n", "ggrd_grdtrack_init",ogrd.x_min,ogrd.x_max); } }else{ /* test */ if((fabs(ogrd.x_min - (*grd)[i].x_min)>5e-7)|| (fabs(ogrd.y_min - (*grd)[i].y_min)>5e-7)|| (fabs(ogrd.x_max - (*grd)[i].x_max)>5e-7)|| (fabs(ogrd.y_max - (*grd)[i].y_max)>5e-7)|| (fabs(ogrd.x_inc - (*grd)[i].x_inc)>5e-7)|| (fabs(ogrd.y_inc - (*grd)[i].y_inc)>5e-7)|| (fabs(ogrd.nx - (*grd)[i].nx)>5e-7)|| (fabs(ogrd.ny - (*grd)[i].ny)>5e-7)|| (fabs(ogrd.node_offset - (*grd)[i].node_offset)>5e-7)){ fprintf(stderr,"%s: error: grid %i out of %i has different dimensions or setting from first\n", "ggrd_grdtrack_init",i+1,(*nz)); return 8; } } } } if(verbose > 2) fprintf(stderr,"ggrd_grdtrack_init: read %i headers OK, grids appear to be same size\n",*nz); if (fabs(*west - (*east)) < 5e-7) { /* No subset asked for , west same as east*/ *west = (*grd)[0].x_min; *east = (*grd)[0].x_max; *south = (*grd)[0].y_min; *north = (*grd)[0].y_max; } one_or_zero = ((*grd)[0].node_offset) ? 0 : 1; nx = irint ( (*east - *west) / (*grd)[0].x_inc) + one_or_zero; ny = irint ( (*north - *south) / (*grd)[0].y_inc) + one_or_zero; /* real size of data */ //nn = nx * ny; /* padded */ mx = nx + 4; my = ny + 4; /* get space for all layers */ *mm = mx * my; *f = (float *) calloc((*mm) * (*nz) ,sizeof (float)); if(!(*f)){ fprintf(stderr,"ggrd_grdtrack_init: f memory error, mm: %i (%i by %i) by nz: %i \n",*mm,mx,my, *nz); return 9; } if(verbose >= 2){ fprintf(stderr,"ggrd_grdtrack_init: mem alloc 2 ok, %g %g %g %g %i %i\n", *west,*east,*south,*north,nx,ny); } /* pad on sides */ pad[0] = pad[1] = pad[2] = pad[3] = 2; for(i=0;i < (*nz);i++){ /* loop through layers */ if(i != 0) /* copy first edgeinfo over */ memcpy((*edgeinfo+i),(*edgeinfo),sizeof(struct GMT_EDGEINFO)); if((*nz) == 1){ sprintf(filename,"%s",grdfile); }else{ /* construct full filename */ sprintf(filename,"%s.%i.grd",grdfile,i+1); } if (verbose) fprintf(stderr,"ggrd_grdtrack_init: reading grd file %s (%g - %g (%i) %g - %g (%i); geo: %i flag: %s\n", filename,*west,*east,nx,*south,*north,ny, *geographic_in,edgeinfo_string); /* read the grd files */ #ifndef USE_GMT3 /* GMT 4 */ if (GMT_read_grd (filename,(*grd+i), (*f+i* (*mm)), *west, *east, *south, *north, pad, FALSE)) { fprintf (stderr, "%s: error reading file %s\n", "ggrd_grdtrack_init", grdfile); return 10; } //fprintf(stderr,"%g %g %i %i %i %i\n",(*grd)->z_scale_factor,(*grd)->z_add_offset,nx,ny,mx,my); #else /* old GMT */ if (GMT_cdf_read_grd (filename, (*grd+i), (*f+i* (*mm)), *west, *east, *south, *north, pad, FALSE)) { fprintf (stderr, "%s: error reading file %s\n", "ggrd_grdtrack_init", grdfile); return 10; } #endif /* prepare the boundaries */ GMT_boundcond_param_prep ((*grd+i), (*edgeinfo+i)); if(i == 0){ /* Initialize bcr structure, this can be the same for all grids as long as they have the same dimensions */ #ifndef USE_GMT3 GMT_bcr_init ((*grd+i), pad, interpolant,1.0,loc_bcr); #else my_GMT_bcr_init ((*grd+i), pad, interpolant,loc_bcr); #endif } /* Set boundary conditions */ GMT_boundcond_set ((*grd+i), (*edgeinfo+i), pad, (*f+i*(*mm))); } /* end layer loop */ if(verbose){ ggrd_print_layer_avg(*f,*z,mx,my,*nz,stderr,pad); } return 0; }
/* * function write_cdfgrd writes output grid to a * GMT version 2 netCDF grd file */ int write_cdfgrd(int verbose, char *outfile, float *grid, int nx, int ny, double xmin, double xmax, double ymin, double ymax, double zmin, double zmax, double dx, double dy, char *xlab, char *ylab, char *zlab, char *titl, char *projection, int argc, char **argv, int *error) { char *function_name = "write_cdfgrd"; int status = MB_SUCCESS; struct GRD_HEADER grd; double w, e, s, n; #ifdef GMT_MINOR_VERSION GMT_LONG pad[4]; #else int pad[4]; #endif time_t right_now; char date[MB_PATH_MAXLINE], user[MB_PATH_MAXLINE], *user_ptr, host[MB_PATH_MAXLINE]; char remark[MB_PATH_MAXLINE]; char *ctime(); char *getenv(); int i; /* print input debug statements */ if (verbose >= 2) { fprintf(outfp,"\ndbg2 Function <%s> called\n", function_name); fprintf(outfp,"dbg2 Input arguments:\n"); fprintf(outfp,"dbg2 verbose: %d\n",verbose); fprintf(outfp,"dbg2 outfile: %s\n",outfile); fprintf(outfp,"dbg2 grid: %lu\n",(size_t)grid); fprintf(outfp,"dbg2 nx: %d\n",nx); fprintf(outfp,"dbg2 ny: %d\n",ny); fprintf(outfp,"dbg2 xmin: %f\n",xmin); fprintf(outfp,"dbg2 xmax: %f\n",xmax); fprintf(outfp,"dbg2 ymin: %f\n",ymin); fprintf(outfp,"dbg2 ymax: %f\n",ymax); fprintf(outfp,"dbg2 zmin: %f\n",zmin); fprintf(outfp,"dbg2 zmax: %f\n",zmax); fprintf(outfp,"dbg2 dx: %f\n",dx); fprintf(outfp,"dbg2 dy: %f\n",dy); fprintf(outfp,"dbg2 xlab: %s\n",xlab); fprintf(outfp,"dbg2 ylab: %s\n",ylab); fprintf(outfp,"dbg2 zlab: %s\n",zlab); fprintf(outfp,"dbg2 titl: %s\n",titl); fprintf(outfp,"dbg2 argc: %d\n",(int)argc); fprintf(outfp,"dbg2 *argv: %lu\n",(size_t)*argv); } /* inititialize grd header */ GMT_program = program_name; GMT_grd_init (&grd, 1, argv, FALSE); GMT_io_init (); GMT_grdio_init (); GMT_make_fnan (GMT_f_NaN); GMT_make_dnan (GMT_d_NaN); /* copy values to grd header */ grd.nx = nx; grd.ny = ny; grd.node_offset = 1; /* pixel registration */ grd.x_min = xmin; grd.x_max = xmax; grd.y_min = ymin; grd.y_max = ymax; grd.z_min = zmin; grd.z_max = zmax; grd.x_inc = dx; grd.y_inc = dy; grd.z_scale_factor = 1.0; grd.z_add_offset = 0.0; strcpy(grd.x_units,xlab); strcpy(grd.y_units,ylab); strcpy(grd.z_units,zlab); strcpy(grd.title,titl); strcpy(grd.command,"\0"); strncpy(date,"\0",MB_PATH_MAXLINE); right_now = time((time_t *)0); strncpy(date,ctime(&right_now),24);date[24]='\0'; if ((user_ptr = getenv("USER")) == NULL) user_ptr = getenv("LOGNAME"); if (user_ptr != NULL) strcpy(user,user_ptr); else strcpy(user, "unknown"); gethostname(host,MB_PATH_MAXLINE); sprintf(remark,"\n\tProjection: %s\n\tGrid created by %s\n\tMB-system Version %s\n\tRun by <%s> on <%s> at <%s>", projection,program_name,MB_VERSION,user,host,date); strncpy(grd.remark, remark, 159); /* set extract wesn,pad */ w = 0.0; e = 0.0; s = 0.0; n = 0.0; for (i=0;i<4;i++) pad[i] = 0; /* write grid to GMT netCDF grd file */ /*for (i=0;i<nx;i++) for (j=0;j<ny;j++) { k = j * nx + i; fprintf(outfp,"%d %d %d %f\n",i,j,k,grid[k]); }*/ GMT_write_grd(outfile, &grd, grid, w, e, s, n, pad, FALSE); /* free GMT memory */ GMT_free ((void *)GMT_io.skip_if_NaN); GMT_free ((void *)GMT_io.in_col_type); GMT_free ((void *)GMT_io.out_col_type); /* print output debug statements */ if (verbose >= 2) { fprintf(outfp,"\ndbg2 MBIO function <%s> completed\n", function_name); fprintf(outfp,"dbg2 Return values:\n"); fprintf(outfp,"dbg2 error: %d\n",*error); fprintf(outfp,"dbg2 Return status:\n"); fprintf(outfp,"dbg2 status: %d\n",status); } /* return status */ return(status); }