/* * 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); }
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; }
int main (int argc, char **argv) { extern char *optarg; int errflg = 0; int c; int help = 0; int flag = 0; /* MBIO status variables */ int status = MB_SUCCESS; int verbose = 0; int error = MB_ERROR_NO_ERROR; char *message; /* segy data */ char segyfile[MB_PATH_MAXLINE]; void *mbsegyioptr; struct mb_segyasciiheader_struct asciiheader; struct mb_segyfileheader_struct fileheader; struct mb_segytraceheader_struct traceheader; float *trace = NULL; float *worktrace = NULL; double *spsd = NULL; double *wpsd = NULL; double *spsdtot = NULL; double *wpsdtot = NULL; /* fft controls */ int nfft = 1024; fftw_plan plan; fftw_complex *fftw_in = NULL; fftw_complex *fftw_out = NULL; int nsection; /* grid controls */ char fileroot[MB_PATH_MAXLINE]; char gridfile[MB_PATH_MAXLINE]; char psdfile[MB_PATH_MAXLINE]; int decimatex = 1; int tracemode = MBSEGYPSD_USESHOT; int tracestart = 0; int traceend = 0; int chanstart = 0; int chanend = -1; double timesweep = 0.0; double timedelay = 0.0; double sampleinterval = 0.0; int windowmode = MBSEGYPSD_WINDOW_OFF; double windowstart, windowend; int ntraces; int ngridx = 0; int ngridy = 0; int ngridxy = 0; float *grid = NULL; double xmin; double xmax; double ymin; double ymax; double dx; double dy; double gridmintot = 0.0; double gridmaxtot = 0.0; char projection[MB_PATH_MAXLINE]; char xlabel[MB_PATH_MAXLINE]; char ylabel[MB_PATH_MAXLINE]; char zlabel[MB_PATH_MAXLINE]; char title[MB_PATH_MAXLINE]; char plot_cmd[MB_PATH_MAXLINE]; int scale2distance = MB_NO; double shotscale = 1.0; double frequencyscale = 1.0; int logscale = MB_NO; int sinftracemode = MBSEGYPSD_USESHOT; int sinftracestart = 0; int sinftraceend = 0; int sinfchanstart = 0; int sinfchanend = -1; double sinftimesweep = 0.0; double sinftimedelay = 0.0; double soundpressurelevel; double sint, taper; double norm, normraw, normtaper, normfft; FILE *fp; int nread; int tracecount, tracenum, channum, traceok; double tracemin, tracemax; double xwidth, ywidth; int ix, iy, iys; int itstart, itend; double factor, btime, stime, dtime; double btimesave = 0.0; double stimesave = 0.0; double dtimesave = 0.0; int plot_status; int kstart, kend; int i, j, k, n; /* set file to null */ segyfile[0] = '\0'; /* get NaN value */ GMT_make_fnan(NaN); /* process argument list */ while ((c = getopt(argc, argv, "A:a:D:d:I:i:LlN:n:O:o:PpS:s:T:t:VvW:w:Hh")) != -1) switch (c) { case 'H': case 'h': help++; break; case 'V': case 'v': verbose++; break; case 'A': case 'a': n = sscanf (optarg,"%lf/%lf", &shotscale, &frequencyscale); if (n == 2) scale2distance = MB_YES; flag++; break; case 'D': case 'd': n = sscanf (optarg,"%d", &decimatex); flag++; break; case 'I': case 'i': sscanf (optarg,"%s", segyfile); flag++; break; case 'L': case 'l': logscale = MB_YES; flag++; break; case 'N': case 'n': n = sscanf (optarg,"%d", &nfft); flag++; break; case 'G': case 'O': case 'o': sscanf (optarg,"%s", fileroot); flag++; break; case 'S': case 's': n = sscanf (optarg,"%d/%d/%d/%d/%d", &tracemode, &tracestart, &traceend, &chanstart, &chanend); if (n < 5) { chanstart = 0; chanend = -1; } if (n < 3) { tracestart = 0; traceend = 0; } if (n < 1) { tracemode = MBSEGYPSD_USESHOT; } flag++; break; case 'T': case 't': n = sscanf (optarg,"%lf/%lf", ×weep, &timedelay); if (n < 2) timedelay = 0.0; flag++; break; case 'W': case 'w': n = sscanf (optarg,"%d/%lf/%lf", &windowmode, &windowstart, &windowend); flag++; break; case '?': errflg++; } /* set output stream to stdout or stderr */ if (verbose >= 2) outfp = stderr; else outfp = stdout; /* if error flagged then print it and exit */ if (errflg) { fprintf(outfp,"usage: %s\n", usage_message); fprintf(outfp,"\nProgram <%s> Terminated\n", program_name); error = MB_ERROR_BAD_USAGE; exit(error); } /* print starting message */ if (verbose == 1 || help) { fprintf(outfp,"\nProgram %s\n",program_name); fprintf(outfp,"MB-system Version %s\n",MB_VERSION); } /* print starting debug statements */ if (verbose >= 2) { fprintf(outfp,"\ndbg2 Program <%s>\n",program_name); fprintf(outfp,"dbg2 MB-system Version %s\n",MB_VERSION); fprintf(outfp,"dbg2 Control Parameters:\n"); fprintf(outfp,"dbg2 verbose: %d\n",verbose); fprintf(outfp,"dbg2 help: %d\n",help); fprintf(outfp,"dbg2 segyfile: %s\n",segyfile); fprintf(outfp,"dbg2 fileroot: %s\n",fileroot); fprintf(outfp,"dbg2 nfft: %d\n",nfft); fprintf(outfp,"dbg2 decimatex: %d\n",decimatex); fprintf(outfp,"dbg2 tracemode: %d\n",tracemode); fprintf(outfp,"dbg2 tracestart: %d\n",tracestart); fprintf(outfp,"dbg2 traceend: %d\n",traceend); fprintf(outfp,"dbg2 chanstart: %d\n",chanstart); fprintf(outfp,"dbg2 chanend: %d\n",chanend); fprintf(outfp,"dbg2 timesweep: %f\n",timesweep); fprintf(outfp,"dbg2 timedelay: %f\n",timedelay); fprintf(outfp,"dbg2 ngridx: %d\n",ngridx); fprintf(outfp,"dbg2 ngridy: %d\n",ngridy); fprintf(outfp,"dbg2 ngridxy: %d\n",ngridxy); fprintf(outfp,"dbg2 windowmode: %d\n",windowmode); fprintf(outfp,"dbg2 windowstart: %f\n",windowstart); fprintf(outfp,"dbg2 windowend: %f\n",windowend); fprintf(outfp,"dbg2 scale2distance: %d\n",scale2distance); fprintf(outfp,"dbg2 shotscale: %f\n",shotscale); fprintf(outfp,"dbg2 frequencyscale: %f\n",frequencyscale); fprintf(outfp,"dbg2 logscale: %d\n",logscale); } /* if help desired then print it and exit */ if (help) { fprintf(outfp,"\n%s\n",help_message); fprintf(outfp,"\nusage: %s\n", usage_message); exit(error); } /* get segy limits if required */ if (traceend < 1 || traceend < tracestart || timesweep <= 0.0) { get_segy_limits(verbose, segyfile, &sinftracemode, &sinftracestart, &sinftraceend, &sinfchanstart, &sinfchanend, &sinftimesweep, &sinftimedelay, &error); if (traceend < 1 || traceend < tracestart) { tracemode = sinftracemode; tracestart = sinftracestart; traceend = sinftraceend; } if (chanend < 1 || chanend < chanstart) { chanstart = sinfchanstart; chanend = sinfchanend; } if (timesweep <= 0.0) { timesweep = sinftimesweep; timedelay = sinftimedelay; } } /* check specified parameters */ if (traceend < 1 || traceend < tracestart) { fprintf(outfp,"\nBad trace numbers: %d %d specified...\n", tracestart, traceend); fprintf(outfp,"\nProgram <%s> Terminated\n", program_name); exit(error); } if (timesweep <= 0.0) { fprintf(outfp,"\nBad time sweep: %f specified...\n", timesweep); fprintf(outfp,"\nProgram <%s> Terminated\n", program_name); exit(error); } /* initialize reading the segy file */ if (mb_segy_read_init(verbose, segyfile, &mbsegyioptr, &asciiheader, &fileheader, &error) != MB_SUCCESS) { mb_error(verbose,error,&message); fprintf(outfp,"\nMBIO Error returned from function <mb_segy_read_init>:\n%s\n",message); fprintf(outfp,"\nSEGY File <%s> not initialized for reading\n",segyfile); fprintf(outfp,"\nProgram <%s> Terminated\n", program_name); exit(error); } /* calculate implied grid parameters */ strcpy(gridfile,fileroot); strcat(gridfile,".grd"); strcpy(psdfile,fileroot); strcat(psdfile,"_psd.txt"); if (chanend >= chanstart) ntraces = (traceend - tracestart + 1) * (chanend - chanstart + 1); else ntraces = traceend - tracestart + 1; ngridx = ntraces / decimatex; sampleinterval = 0.000001 * (double) (fileheader.sample_interval); ngridy = nfft / 2 + 1; ngridxy = ngridx * ngridy; dx = decimatex; xmin = (double) tracestart - 0.5; xmax = (double) traceend + 0.5; dy = 1.0 / (2.0 * sampleinterval * ngridy); ymin = -0.5 * dy; ymax = (ngridy - 0.5) * dy; /* get start and end samples */ if (windowmode == MBSEGYPSD_WINDOW_OFF) { itstart = 0; itend = ngridy - 1; } else if (windowmode == MBSEGYPSD_WINDOW_ON) { itstart = MAX((windowstart) / sampleinterval, 0); itend = MIN((windowend) / sampleinterval, ngridy - 1); } /* allocate memory for grid array */ status = mb_mallocd(verbose,__FILE__,__LINE__, 2 * ngridxy * sizeof(float), (void **)&grid, &error); status = mb_mallocd(verbose,__FILE__,__LINE__, ngridy * sizeof(double), (void **)&spsd, &error); status = mb_mallocd(verbose,__FILE__,__LINE__, ngridy * sizeof(double), (void **)&wpsd, &error); status = mb_mallocd(verbose,__FILE__,__LINE__, ngridy * sizeof(double), (void **)&spsdtot, &error); status = mb_mallocd(verbose,__FILE__,__LINE__, ngridy * sizeof(double), (void **)&wpsdtot, &error); /* zero working psd array */ for (iy=0;iy<ngridy;iy++) { spsdtot[iy] = 0.0; wpsdtot[iy] = 0.0; } /* output info */ if (verbose >= 0) { fprintf(outfp,"\nMBsegypsd Parameters:\n"); fprintf(outfp,"Input segy file: %s\n",segyfile); fprintf(outfp,"Output fileroot: %s\n",fileroot); fprintf(outfp,"Input Parameters:\n"); fprintf(outfp," trace mode: %d\n",tracemode); fprintf(outfp," trace start: %d\n",tracestart); fprintf(outfp," trace end: %d\n",traceend); fprintf(outfp," channel start: %d\n",chanstart); fprintf(outfp," channel end: %d\n",chanend); fprintf(outfp," trace decimation: %d\n",decimatex); fprintf(outfp," time sweep: %f seconds\n",timesweep); fprintf(outfp," time delay: %f seconds\n",timedelay); fprintf(outfp," sample interval: %f seconds\n",sampleinterval); fprintf(outfp," window mode: %d\n",windowmode); fprintf(outfp," window start: %f seconds\n",windowstart); fprintf(outfp," window end: %f seconds\n",windowend); fprintf(outfp,"Output Parameters:\n"); fprintf(outfp," grid filename: %s\n",gridfile); fprintf(outfp," psd filename: %s\n",psdfile); fprintf(outfp," x grid dimension: %d\n",ngridx); fprintf(outfp," y grid dimension: %d\n",ngridy); fprintf(outfp," grid xmin: %f\n",xmin); fprintf(outfp," grid xmax: %f\n",xmax); fprintf(outfp," grid ymin: %f\n",ymin); fprintf(outfp," grid ymax: %f\n",ymax); fprintf(outfp," NaN values used to flag regions with no data\n"); fprintf(outfp," shotscale: %f\n",shotscale); fprintf(outfp," frequencyscale: %f\n",frequencyscale); if (scale2distance == MB_YES) { fprintf(outfp," trace numbers scaled to distance in meters\n"); fprintf(outfp," scaled grid xmin %f\n",0.0); fprintf(outfp," scaled grid xmax: %f\n",shotscale * (xmax - xmin)); } } if (verbose > 0) fprintf(outfp,"\n"); /* proceed if all ok */ if (status == MB_SUCCESS) { /* fill grid with NaNs */ for (i=0;i<ngridxy;i++) grid[i] = NaN; /* generate the fftw plan */ fftw_in = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nfft); fftw_out = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nfft); plan = fftw_plan_dft_1d(nfft, fftw_in, fftw_out, FFTW_FORWARD, FFTW_MEASURE); /* read and print data */ nread = 0; while (error <= MB_ERROR_NO_ERROR) { /* reset error */ error = MB_ERROR_NO_ERROR; /* read a trace */ status = mb_segy_read_trace(verbose, mbsegyioptr, &traceheader, &trace, &error); /* now process the trace */ if (status == MB_SUCCESS) { /* figure out where this trace is in the grid */ if (tracemode == MBSEGYPSD_USESHOT) { tracenum = traceheader.shot_num; channum = traceheader.shot_tr; } else { tracenum = traceheader.rp_num; channum = traceheader.rp_tr; } if (chanend >= chanstart) { tracecount = (tracenum - tracestart) * (chanend - chanstart + 1) + (channum - chanstart); } else { tracecount = tracenum - tracestart; } ix = tracecount / decimatex; if (traceheader.elev_scalar < 0) factor = 1.0 / ((float) (-traceheader.elev_scalar)); else factor = (float) traceheader.elev_scalar; if (traceheader.src_depth > 0) { btime = factor * traceheader.src_depth / 750.0 + 0.001 * traceheader.delay_mils; dtime = factor * traceheader.src_depth / 750.0; btimesave = btime; dtimesave = dtime; } else if (traceheader.src_elev > 0) { btime = -factor * traceheader.src_elev / 750.0 + 0.001 * traceheader.delay_mils; dtime = -factor * traceheader.src_elev / 750.0; btimesave = btime; dtimesave = dtime; } else { btime = btimesave; dtime = dtimesave; } if (traceheader.src_wbd > 0) { stime = factor * traceheader.src_wbd / 750.0; stimesave = stime; } else { stime = stimesave; } iys = (btime - timedelay) / sampleinterval; /* now check if this is a trace of interest */ traceok = MB_YES; if (tracenum < tracestart || tracenum > traceend) traceok = MB_NO; else if (chanend >= chanstart && (channum < chanstart || channum > chanend)) traceok = MB_NO; else if (tracecount % decimatex != 0) traceok = MB_NO; /* get trace min and max */ tracemin = trace[0]; tracemax = trace[0]; for (i=0;i<traceheader.nsamps;i++) { tracemin = MIN(tracemin, trace[i]); tracemax = MAX(tracemin, trace[i]); } if ((verbose == 0 && nread % 250 == 0) || (nread % 25 == 0)) { if (traceok == MB_YES) fprintf(outfp,"PROCESS "); else fprintf(outfp,"IGNORE "); if (tracemode == MBSEGYPSD_USESHOT) fprintf(outfp,"read:%d position:%d shot:%d channel:%d ", nread,tracecount,tracenum,channum); else fprintf(outfp,"read:%d position:%d rp:%d channel:%d ", nread,tracecount,tracenum,channum); fprintf(outfp,"%4.4d/%3.3d %2.2d:%2.2d:%2.2d.%3.3d samples:%d interval:%d usec minmax: %f %f\n", traceheader.year,traceheader.day_of_yr, traceheader.hour,traceheader.min,traceheader.sec,traceheader.mils, traceheader.nsamps,traceheader.si_micros, tracemin, tracemax); } /* now actually process traces of interest */ if (traceok == MB_YES) { /* zero working psd array */ for (iy=0;iy<ngridy;iy++) { spsd[iy] = 0.0; wpsd[iy] = 0.0; } /* get bounds of trace in depth window mode */ if (windowmode == MBSEGYPSD_WINDOW_DEPTH) { itstart = (int)((dtime + windowstart - timedelay) / sampleinterval); itstart = MAX(itstart, 0); itend = (int)((dtime + windowend - timedelay) / sampleinterval); itend = MIN(itend, ngridy - 1); } else if (windowmode == MBSEGYPSD_WINDOW_SEAFLOOR) { itstart = MAX((stime + windowstart - timedelay) / sampleinterval, 0); itend = MIN((stime + windowend - timedelay) / sampleinterval, ngridy - 1); } /* loop over the data calculating fft in nfft long sections */ nsection = (itend - itstart + 1) / nfft; if (((itend - itstart + 1) % nfft) > 0) nsection++; for (j=0;j<nsection;j++) { /* initialize normalization factors */ normraw = 0.0; normtaper = 0.0; normfft = 0.0; /* extract data section to be fft'd with taper */ kstart = itstart + j * nfft; kend = MIN(kstart + nfft, itend); for (i=0;i<nfft;i++) { k = itstart + j * nfft + i; if (k <= kend) { sint = sin(M_PI * ((double)(k - kstart)) / ((double)(kend - kstart))); taper = sint * sint; fftw_in[i][0] = taper * trace[k]; normraw += trace[k] * trace[k]; normtaper += fftw_in[i][0] * fftw_in[i][0]; } else fftw_in[i][0] = 0.0; /*if (ix < 500) fftw_in[i][0] = sin(2.0 * M_PI * 1000.0 * i * sampleinterval) + sin(2.0 * M_PI * 3000.0 * i * sampleinterval) + sin(2.0 * M_PI * 6000.0 * i * sampleinterval);*/ fftw_in[i][1] = 0.0; } soundpressurelevel = 20.0 * log10(normraw / nfft); /*fprintf(stderr,"Sound Pressure Level: %f dB re 1 uPa\n",soundpressurelevel);*/ /* execute the fft */ fftw_execute(plan); /* get normalization factor - require variance of transform to equal variance of input */ for (i=1;i<nfft;i++) { normfft += fftw_out[i][0] * fftw_out[i][0] + fftw_out[i][1] * fftw_out[i][1]; } norm = normraw / normfft; /* apply normalization factor */ for (i=1;i<nfft;i++) { fftw_out[i][0] = norm * fftw_out[i][0]; fftw_out[i][1] = norm * fftw_out[i][1]; } /* calculate psd from result of transform */ spsd[0] += fftw_out[0][0] * fftw_out[0][0] + fftw_out[0][1] * fftw_out[0][1]; wpsd[0] += 1.0; /* fprintf(stderr,"FFT result: i:%d %f %f %f\n", 0,fftw_out[0][0],fftw_out[0][1],fftw_out[0][0] * fftw_out[0][0] + fftw_out[0][1] * fftw_out[0][1]);*/ for (i=1;i<nfft/2;i++) { spsd[i] += 2.0 * (fftw_out[i][0] * fftw_out[i][0] + fftw_out[i][1] * fftw_out[i][1]); wpsd[i] += 1.0; /* fprintf(stderr,"FFT result: i:%d %f %f %f\n", i,fftw_out[i][0],fftw_out[i][1],2.0 * fftw_out[i][0] * fftw_out[i][0] + fftw_out[i][1] * fftw_out[i][1]);*/ } if (nfft % 2 == 0) { spsd[i] += fftw_out[nfft/2][0] * fftw_out[nfft/2][0] + fftw_out[nfft/2][1] * fftw_out[nfft/2][1]; wpsd[i] += 1.0; /* fprintf(stderr,"FFT result: i:%d %f %f %f\n", nfft/2,fftw_out[nfft/2][0],fftw_out[nfft/2][1],fftw_out[nfft/2][0] * fftw_out[nfft/2][0] + fftw_out[nfft/2][1] * fftw_out[nfft/2][1]); */ } } /* output psd for this trace to the grid */ /*fprintf(stderr,"N:%d Normalization: %f %f %f ratios: %f %f %f %f\n", nfft,normraw,normtaper,normfft,normraw/normfft,normfft/normraw,normtaper/normfft,normfft/normtaper);*/ for (iy=0;iy<ngridy;iy++) { k = (ngridy - 1 - iy) * ngridx + ix; if (wpsd[iy] > 0.0) { if (logscale == MB_NO) grid[k] = spsd[iy] / wpsd[iy]; else grid[k] = 20.0 * log10(spsd[iy] / wpsd[iy]); spsdtot[iy] += grid[k]; wpsdtot[iy] += 1.0; /*fprintf(stderr,"ix:%d iy:%d k:%d spsd:%f wpsd:%f f:%f p:%f\n", ix,iy,k,spsd[iy],wpsd[iy],ymax * iy / ngridy,grid[k]);*/ gridmintot = MIN(grid[k], gridmintot); gridmaxtot = MAX(grid[k], gridmaxtot); } } } } /* now process the trace */ if (status == MB_SUCCESS) nread++; } /* deallocate fftw arrays and plan */ fftw_destroy_plan(plan); fftw_free(fftw_in); fftw_free(fftw_out); } /* write out the grid */ error = MB_ERROR_NO_ERROR; status = MB_SUCCESS; strcpy(projection, "GenericLinear"); if (scale2distance == MB_YES) { strcpy(xlabel, "Distance (m)"); strcpy(ylabel, "Frequency (Hz)"); xmax *= shotscale; xmin *= shotscale; dx *= shotscale; } else { strcpy(xlabel, "Trace Number"); strcpy(ylabel, "Frequency (Hz)"); dx = (double) decimatex; } if (logscale == MB_YES) strcpy(zlabel, "dB/Hz"); else strcpy(zlabel, "Intensity/Hz"); sprintf(title, "Power Spectral Density Grid from %s", segyfile); status = write_cdfgrd(verbose, gridfile, grid, ngridx, ngridy, xmin, xmax, ymin, ymax, gridmintot, gridmaxtot, dx, dy, xlabel, ylabel, zlabel, title, projection, argc, argv, &error); /* output average power spectra */ if ((fp = fopen(psdfile, "w")) != NULL) { for (iy=0;iy<ngridy;iy++) { if (wpsdtot[iy] > 0.0) { spsdtot[iy] = spsdtot[iy] / wpsdtot[iy]; } fprintf(fp, "%f %f\n", dy * iy, spsdtot[iy]); } fclose(fp); } /* close the segy file */ status = mb_segy_close(verbose,&mbsegyioptr,&error); /* deallocate memory for grid array */ if (worktrace != NULL) status = mb_freed(verbose,__FILE__,__LINE__,(void **)&worktrace, &error); status = mb_freed(verbose,__FILE__,__LINE__,(void **)&grid, &error); status = mb_freed(verbose,__FILE__,__LINE__,(void **)&spsd, &error); status = mb_freed(verbose,__FILE__,__LINE__,(void **)&wpsd, &error); status = mb_freed(verbose,__FILE__,__LINE__,(void **)&spsdtot, &error); status = mb_freed(verbose,__FILE__,__LINE__,(void **)&wpsdtot, &error); /* run mbm_grdplot */ xwidth = MIN(0.01 * (double) ngridx, 55.0); ywidth = MIN(0.01 * (double) ngridy, 28.0); sprintf(plot_cmd, "mbm_grdplot -I%s -JX%f/%f -G1 -S -V -L\"File %s - %s:%s\"", gridfile, xwidth, ywidth, gridfile, title, zlabel); if (verbose) { fprintf(outfp, "\nexecuting mbm_grdplot...\n%s\n", plot_cmd); } plot_status = system(plot_cmd); if (plot_status == -1) { fprintf(outfp, "\nError executing mbm_grdplot on grid file %s\n", gridfile); } /* run mbm_xyplot */ xwidth = 9.0; ywidth = 7.0; sprintf(plot_cmd, "mbm_xyplot -I%s -JX%f/%f -V -L\"File %s - %s:%s\"", psdfile, xwidth, ywidth, psdfile, title, zlabel); if (verbose) { fprintf(outfp, "\nexecuting mbm_xyplot...\n%s\n", plot_cmd); } plot_status = system(plot_cmd); if (plot_status == -1) { fprintf(outfp, "\nError executing mbm_xyplot on psd file %s\n", psdfile); } /* check memory */ if (verbose >= 4) status = mb_memory_list(verbose,&error); /* print output debug statements */ if (verbose >= 2) { fprintf(outfp,"\ndbg2 Program <%s> completed\n", program_name); fprintf(outfp,"dbg2 Ending status:\n"); fprintf(outfp,"dbg2 status: %d\n",status); } /* end it all */ exit(error); }