Ejemplo n.º 1
0
int main (int argc, char **argv) {

   char *coeff_x, *coeff_x2, *coeff_x3, file[BUFSIZ];
   cwp_Bool active = TRUE;
	
   struct GRD_HEADER grd_x, grd_x2, grd_x3;
   struct GMT_EDGEINFO edgeinfo_x, edgeinfo_x2, edgeinfo_x3;
   struct GMT_BCR bcr_x, bcr_x2, bcr_x3;

   short  check, verbose;
   int    nz, ntr, ns;
   double value, scale_factor, dz, x_loc, y_loc;
   double weight_x, weight_x2, weight_x3;
   double value_coeff_x, value_coeff_x2, value_coeff_x3, tr_sec, dt_sec;
   float  depth_input, amp_output, *tr_amp, *depth;
   register int k, n;

   initargs(argc, argv);
   argc = GMT_begin (argc, argv);

   if (!getparstring("coeff_x", &coeff_x)) {
      fprintf ( stderr, "Must supply Coefficient_X GMT grid (COEFF_X Parameter) --> exiting\n" );
      return EXIT_FAILURE;
   }

   if (!getparstring("coeff_x2", &coeff_x2)) {
      fprintf ( stderr, "Must supply Coefficient_X2 GMT grid (COEFF_X2 Parameter)--> exiting\n" );
      return EXIT_FAILURE;
   }

   if (!getparstring("coeff_x3", &coeff_x3)) {
      fprintf ( stderr, "Must supply Coefficient_X3 GMT grid (COEFF_X3 Parameter)--> exiting\n" );
      return EXIT_FAILURE;
   }

   if (!getparshort("verbose" , &verbose)) verbose = 0;
   if (!getpardouble("weight_x", &weight_x)) weight_x  = 1.0;
   if (!getpardouble("weight_x2", &weight_x2)) weight_x2  = 1.0;
   if (!getpardouble("weight_x3", &weight_x3)) weight_x3  = 1.0;

   if ( verbose ) {
      fprintf ( stderr, "\n" );
      fprintf ( stderr, "X1 Coefficient GMT grid file name = %s\n", coeff_x );
      fprintf ( stderr, "X2 Coefficient GMT grid file name = %s\n", coeff_x2 );
      fprintf ( stderr, "X3 Coefficient GMT grid file name = %s\n", coeff_x3 );
      fprintf ( stderr, "X1 Grid Weighting Value = %f\n", weight_x );
      fprintf ( stderr, "X2 Grid Weighting Value = %f\n", weight_x2 );
      fprintf ( stderr, "X3 Grid Weighting Value = %f\n", weight_x3 );
      fprintf ( stderr, "\n" );
   }

   weight_x  = 1.0 / weight_x;
   weight_x2 = 1.0 / weight_x2;
   weight_x3 = 1.0 / weight_x3;

   GMT_boundcond_init (&edgeinfo_x);
   GMT_boundcond_init (&edgeinfo_x2);
   GMT_boundcond_init (&edgeinfo_x3);

   GMT_grd_init (&grd_x,  argc, argv, FALSE);
   GMT_grd_init (&grd_x2, argc, argv, FALSE);
   GMT_grd_init (&grd_x3, argc, argv, FALSE);

   if (GMT_read_grd_info (coeff_x,  &grd_x))  fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_x2, &grd_x2)) fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_x3, &grd_x3)) fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
		
   f1 = (float *) GMT_memory (VNULL, (size_t)((grd_x.nx  + 4) * (grd_x.ny  + 4)), sizeof(float), GMT_program);
   f2 = (float *) GMT_memory (VNULL, (size_t)((grd_x2.nx + 4) * (grd_x2.ny + 4)), sizeof(float), GMT_program);
   f3 = (float *) GMT_memory (VNULL, (size_t)((grd_x3.nx + 4) * (grd_x3.ny + 4)), sizeof(float), GMT_program);

   GMT_pad[0] = GMT_pad[1] = GMT_pad[2] = GMT_pad[3] = 2;

   GMT_boundcond_param_prep (&grd_x,  &edgeinfo_x);
   GMT_boundcond_param_prep (&grd_x2, &edgeinfo_x2);
   GMT_boundcond_param_prep (&grd_x3, &edgeinfo_x3);

   GMT_boundcond_set (&grd_x,  &edgeinfo_x,  GMT_pad, f1);
   GMT_boundcond_set (&grd_x2, &edgeinfo_x2, GMT_pad, f2);
   GMT_boundcond_set (&grd_x3, &edgeinfo_x3, GMT_pad, f3);

   value = 0.0;
   GMT_bcr_init (&grd_x,  GMT_pad, active, value, &bcr_x);
   GMT_bcr_init (&grd_x2, GMT_pad, active, value, &bcr_x2);
   GMT_bcr_init (&grd_x3, GMT_pad, active, value, &bcr_x3);

   GMT_read_grd (coeff_x,  &grd_x,  f1, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_x2, &grd_x2, f2, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_x3, &grd_x3, f3, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);

   /* Get info from first trace */
   ntr     = gettra (&tr, 0);
   ns      = tr.ns;
   dt_sec  = tr.dt * 0.000001;
   scale_factor = tr.scalco;
   if (scale_factor < 0.0 ) scale_factor *= -1.0;
   if (scale_factor == 0.0 ) scale_factor = 1.0;

   if (!getpardouble ("dz",&dz)) dz = 2.0;
   if (!getparint    ("nz",&nz)) nz = ns;

   if ( verbose ) {
      fprintf ( stderr, "Output depth sample rate = %f\n", dz );
      fprintf ( stderr, "Coordinate scale factor = %f\n", scale_factor );
      fprintf ( stderr, "Number of output depth samples per trace = %d\n", nz );
      fprintf ( stderr, "number of traces = %d, number of samples per trace = %d\n", ntr, ns );
      fprintf ( stderr, "time sample rate (seconds) = %f\n", dt_sec );
   }

   rewind (stdin);

   depth  = ealloc1float ( ns );
   tr_amp = ealloc1float ( nz );

   /* Main loop over traces */
   for ( k = 0; k < ntr; ++k ) {
      gettr (&tr);
      x_loc = tr.sx / scale_factor;
      y_loc = tr.sy / scale_factor;

      check = 0;
      if ( x_loc >= grd_x.x_min && x_loc <= grd_x.x_max && y_loc >= grd_x.y_min && y_loc <= grd_x.y_max ) check = 1;

      if ( check ) {
         value_coeff_x  = GMT_get_bcr_z (&grd_x,  x_loc, y_loc, f1, &edgeinfo_x,  &bcr_x);
         value_coeff_x2 = GMT_get_bcr_z (&grd_x2, x_loc, y_loc, f2, &edgeinfo_x2, &bcr_x2);
         value_coeff_x3 = GMT_get_bcr_z (&grd_x3, x_loc, y_loc, f3, &edgeinfo_x3, &bcr_x3);

	 if ( verbose ) fprintf ( stderr, "Trace num = %d, X-Loc = %f, Y-Loc = %f, X Coefficient = %0.10f, X2 Coefficient = %0.10f, X3 Coefficient = %0.10f\n", 
         k+1, x_loc, y_loc, value_coeff_x, value_coeff_x2, value_coeff_x3 );

	 for ( n=0; n < ns; ++n ) {
            tr_amp[n] = tr.data[n];
	    tr_sec   = n * dt_sec;
	    depth[n] = (((value_coeff_x*tr_sec)*weight_x) + ((value_coeff_x2*pow(tr_sec,2))*weight_x2) + ((value_coeff_x3*pow(tr_sec,3))*weight_x3)) * -1.0;
            if ( verbose == 2 ) fprintf ( stderr, "Trace no. = %5d, Sample = %5d, TWT (secs.) = %.4f, Depth (feet) = %.4f\n", k, n, tr_sec, depth[n] ); 
	 }
	 for ( n=0; n < nz; ++n ) {
	    depth_input = n * dz;
	    intlin ( ns, depth, tr_amp, tr_amp[0], tr_amp[ns-1], 1, &depth_input, &amp_output );
	    dtr.data[n] = amp_output; 
         }
	 dtr.tracl  = tr.tracl;
	 dtr.tracr  = tr.tracr;
	 dtr.ep     = tr.ep;
	 dtr.ns     = nz;
	 dtr.dt     = nint (dz * 1000.0);
	 dtr.sx     = tr.sx;
	 dtr.sy     = tr.sy;
	 dtr.trid   = 1;
	 dtr.fldr   = tr.fldr;
	 dtr.cdp    = tr.cdp ;
	 puttr (&dtr);
      } else {
         fprintf ( stderr, "input trace = %d, xloc = %.0f yloc = %.0f is out of bounds\n", k, x_loc, y_loc);
      }
   }

   GMT_free ((void *)f1);
   GMT_free ((void *)f2);
   GMT_free ((void *)f3);
   GMT_end  (argc, argv);

   free1float (depth);
   free1float (tr_amp);

   return (0);
}
Ejemplo n.º 2
0
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) {

char *coeff_x, *coeff_x2, file[BUFSIZ];

struct GRD_HEADER grd_x, grd_x2;
struct GMT_EDGEINFO edgeinfo_x, edgeinfo_x2;
struct GMT_BCR bcr_x, bcr_x2;

int  *idx, n, ns, ntr, istart, istop, index;
float scale_factor;
double *x, *y, dt, zero, factor, rns;
double ri, **A, *B, d, sum;
double water_depth, error, rx, ry;
double value_coeff_x, value_coeff_x2, water_velocity, x_loc, y_loc;
short check, verbose, intercept;
register int i, j, k, l;

initargs(argc, argv);
argc = GMT_begin (argc, argv);

if (!getparint("n", &n)) n = 4;
if (!getparshort("intercept", &intercept)) intercept = 0;
if (!getparshort("verbose", &verbose)) verbose = 1;

if (!getparstring("coeff_x", &coeff_x)) coeff_x="/home/user/Field/GRIDS/wb.twt.sm2500.new.grd";
if (!getparstring("coeff_x2", &coeff_x2)) coeff_x2="/home/user/Field/HORIZONS/DC_Base_Reservoir.reform.dat.trimmed.sample.smooth.grd";

if ( verbose ) {
   fprintf ( stderr, "\n" );
   fprintf ( stderr, "WB TWT GMT grid file name = %s\n", coeff_x );
   fprintf ( stderr, "Bottom Horizon GMT grid file name = %s\n", coeff_x2 );
}

GMT_boundcond_init (&edgeinfo_x);
GMT_boundcond_init (&edgeinfo_x2);

GMT_grd_init (&grd_x,  argc, argv, FALSE);
GMT_grd_init (&grd_x2, argc, argv, FALSE);

if (GMT_read_grd_info (coeff_x,  &grd_x))  fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
if (GMT_read_grd_info (coeff_x2, &grd_x2)) fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);

f1 = (float *) GMT_memory (VNULL, (size_t)((grd_x.nx  + 4) * (grd_x.ny  + 4)), sizeof(float), GMT_program);
f2 = (float *) GMT_memory (VNULL, (size_t)((grd_x2.nx + 4) * (grd_x2.ny + 4)), sizeof(float), GMT_program);

GMT_pad[0] = GMT_pad[1] = GMT_pad[2] = GMT_pad[3] = 2;

GMT_boundcond_param_prep (&grd_x,  &edgeinfo_x);
GMT_boundcond_param_prep (&grd_x2, &edgeinfo_x2);

GMT_boundcond_set (&grd_x, &edgeinfo_x, GMT_pad, f1);
GMT_boundcond_set (&grd_x2, &edgeinfo_x2, GMT_pad, f2);

GMT_bcr_init (&grd_x,  GMT_pad, BCR_BSPLINE, 1, &bcr_x);
GMT_bcr_init (&grd_x2, GMT_pad, BCR_BSPLINE, 1, &bcr_x2);

GMT_read_grd (coeff_x,  &grd_x,  f1, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
GMT_read_grd (coeff_x2, &grd_x2, f2, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);

ntr = gettra (&tr, 0);
ns  = tr.ns;
dt  = tr.dt * 0.001;
scale_factor = tr.scalco;
if (scale_factor < 0.0 ) scale_factor *= -1.0;
if (scale_factor == 0.0 ) scale_factor = 1.0;

zero = 0.0;
factor = 0.0005;
rns = ns;

if ( verbose ) {
   fprintf ( stderr, "\n" );
   fprintf ( stderr, "Degree of Polynomial = %d\n", n );
   fprintf ( stderr, "Intercept = %d\n", intercept );
   fprintf ( stderr, "Number of input traces = %d\n", ntr );
   fprintf ( stderr, "Number of samples per trace = %d\n", ns );
   fprintf ( stderr, "Sample rate = %f ms.\n", dt );
   fprintf ( stderr, "Scale Factor for X and Y Coordinates = %f\n", scale_factor );
   fprintf ( stderr, "\n" );
}

A = dmatrix (1,n,1,n);
B = dvector (1,n);

x = ealloc1double (ns);
y = ealloc1double (ns);

rewind (stdin);
for (l=0;l<ntr;l++) {
   gettr (&tr);
   x_loc = tr.sx = nint ( tr.sx / scale_factor );
   y_loc = tr.sy = nint ( tr.sy / scale_factor );

   check = 0;
   istop = ns;
   if ( x_loc >= grd_x.x_min && x_loc <= grd_x.x_max && y_loc >= grd_x.y_min && y_loc <= grd_x.y_max ) check = 1;

   if ( check ) {
      value_coeff_x  = GMT_get_bcr_z (&grd_x,  x_loc, y_loc, f1, &edgeinfo_x,  &bcr_x);
      value_coeff_x2 = GMT_get_bcr_z (&grd_x2, x_loc, y_loc, f2, &edgeinfo_x2, &bcr_x2);
      if (GMT_is_dnan (value_coeff_x) || GMT_is_dnan (value_coeff_x2)) {
         check = 0;
      } else {
         if ( value_coeff_x < 0.0 ) value_coeff_x *= -1.0;
         if ( value_coeff_x2 < 0.0 ) value_coeff_x2 *= -1.0;
         value_coeff_x2 += 100.0;
         istop = nint ( value_coeff_x2 / dt );
         istop = max ( min ( istop, ns ), 0 ); 
         if ( tr.wevel > 0 ) {
            water_velocity = tr.wevel;
         } else {
            index = max ( min ( nint(value_coeff_x/dt), ns ), 0 );
            water_velocity = tr.data[index];
         }
         water_depth = water_velocity * value_coeff_x * factor;
      }
   }

   if ( verbose == 3 && check )  {
      fprintf ( stderr, "input trace = %6d, xloc = %8.2f yloc = %8.2f, WB TWT = %8.2f ms., WB Depth = %10.4f meters, Water Velocity = %8.2f mps, Bottom Horizon = %8.2f\n",
      l, x_loc, y_loc, value_coeff_x, water_depth, water_velocity, value_coeff_x2 );
   }

   if ( check ) {
      for (k=0;k<=istop;k++) {
         x[k] = k * dt;
         y[k] = ( ( tr.data[k] * x[k] ) * factor ) - water_depth; 
         x[k] -= value_coeff_x;
      }

      istart = 0;
      for (k=0;k<=istop;k++) {
         if ( x[k] >= zero && y[k] >= zero ) {
            istart = k;
            break;
         }
      }

      if ( verbose == 3 ) fprintf ( stderr, "istart = %d, istop = %d\n", istart, istop );

      for (i=1;i<=n;i++) {
         for (j=1;j<=n;j++) {
            sum = zero;
            ri = i+j-2;
            for (k=istart;k<=istop;k++) sum += pow ( x[k], ri );
            if (i>1&&j==1&&intercept==0) sum = zero;
            A[i][j] = sum;
         }
      }

      for (i=1;i<=n;i++) {
         sum = zero;
         ri = i - 1;
         for (j=istart;j<=istop;j++) sum += pow( x[j], ri ) * y[j];
         B[i] = sum;
      }

      idx  = ivector (1, n); 
      ludcmp ( A, n, idx, &d ); 
      lubksb ( A, n, idx, B ); 

      error = ry = zero;
      if ( intercept ) {
         for ( i=istart; i<=istop; i++ ) {
            rx = x[i];
            ry = B[1]; 
            for (j=2;j<=n;j++) ry += B[j] * pow ( rx, j-1 );
            error += abs ( ry - y[i] );
            if ( verbose == 2 ) fprintf ( stderr, "%-6d %12.2f %12.2f %12.2f %12.4f %12.4f\n", i, rx, y[i], ry, ry - y[i], error );
         }
      } else {
         for ( i=istart; i<=istop; i++ ) {
            rx = x[i];
            ry = zero;
            for (j=1;j<=n;j++) ry += B[j] * pow ( rx, j-1 );
            error += abs ( ry - y[i] );
            if ( verbose == 2 ) fprintf ( stderr, "%-6d %12.2f %12.2f %12.2f %12.4f %12.4f\n", i, rx, y[i], ry, ry - y[i], error );
         }
      }

      rns = istop - istart + 1;
      if ( verbose ) {
         if ( intercept ) {
            for (i=1;i<=n;i++) printf ( "coefficient number = %5d, Solution vector = %30.25f, Average Error = %12.4f\n", i, B[i], error / rns );
         } else {
            for (i=2;i<=n;i++) printf ( "coefficient number = %5d, Solution vector = %30.25f, Average Error = %12.4f\n", i, B[i], error / rns );
         }
      } else {
         printf ( "%-12.2f %12.2f ", x_loc, y_loc );
         if ( intercept ) {
            for (i=1;i<n;i++) printf ( "%30.25f ", B[i] );
         } else {
            for (i=2;i<n;i++) printf ( "%30.25f ", B[i] );
         }
         printf ( "%30.25f %12.4f %12.4f %12.4f %12.4f %12.4f\n", B[n], error / rns, water_velocity, water_depth, value_coeff_x, value_coeff_x2 );
      }
   }
}

free_dmatrix (A,1,n,1,n);
free_dvector (B,1,n);

free1double (x);
free1double (y);

GMT_free ((void *)f1);
GMT_free ((void *)f2);

GMT_end (argc, argv);

return EXIT_SUCCESS;

}
int main(int argc, char **argv) {

   char *coeff_x, *coeff_x2, *coeff_x3, *coeff_x4, file[BUFSIZ];
   struct GRD_HEADER grd_x, grd_x2, grd_x3, grd_x4;
   struct GMT_EDGEINFO edgeinfo_x, edgeinfo_x2, edgeinfo_x3, edgeinfo_x4;
   struct GMT_BCR bcr_x, bcr_x2, bcr_x3, bcr_x4;

   double x_loc, y_loc, value_coeff_x, value_coeff_x2, value_coeff_x3, value_coeff_x4;

   char temp[256];
   cwp_String pfile;
   FILE *fpp;
   short  verbose, check;
   int    kount, nump1;
   double sum, error1, sign;
   double delta, thresh;
   double *vzero_opt, *k_opt;
   double *datain, *samp, *xloc_array, *yloc_array;
   double depth_water, factor, num, sample;
   double vzero, k;
   double *wb_twt_array, *wb_z_array;
   double error, x, y, zero;
   register int i;

   initargs(argc, argv);
   argc = GMT_begin (argc, argv);

   if (!getparstring("pfile",&pfile)) pfile = "tops.lis";
   if (!getparshort("verbose", &verbose)) verbose = 1;
   if (!getpardouble("delta", &delta)) delta = 0.00001;
   if (!getpardouble("thresh", &thresh)) thresh = 0.01;

   zero = 0.0;

   if (!getparstring("coeff_x", &coeff_x)) coeff_x="wb.twt.grd";
   if (!getparstring("coeff_x2", &coeff_x2)) coeff_x2="wvavg.dat.trimmed.sample.smooth.grd";
   if (!getparstring("coeff_x3", &coeff_x3)) coeff_x3="vzero.seismic.dat.trimmed.sample.smooth.grd";
   if (!getparstring("coeff_x4", &coeff_x4)) coeff_x4="k.seismic.dat.trimmed.sample.smooth.grd";

   if ( verbose ) {
      fprintf ( stderr, "\n" );
      fprintf ( stderr, "WB TWT (ms.) GMT grid file name = %s\n", coeff_x );
      fprintf ( stderr, "WB VAVG (m)  GMT grid file name = %s\n", coeff_x2 );
      fprintf ( stderr, "Seismic VZERO GMT grid file name = %s\n", coeff_x3 );
      fprintf ( stderr, "Seismic K GMT grid file name = %s\n", coeff_x4 );
      fprintf ( stderr, "Delta = %.10f\n", delta );
      fprintf ( stderr, "Threshold = %f\n", thresh );
   }

   GMT_boundcond_init (&edgeinfo_x);
   GMT_boundcond_init (&edgeinfo_x2);
   GMT_boundcond_init (&edgeinfo_x3);
   GMT_boundcond_init (&edgeinfo_x4);

   GMT_grd_init (&grd_x,  argc, argv, FALSE);
   GMT_grd_init (&grd_x2, argc, argv, FALSE);
   GMT_grd_init (&grd_x3, argc, argv, FALSE);
   GMT_grd_init (&grd_x4, argc, argv, FALSE);

   if (GMT_read_grd_info (coeff_x,  &grd_x))  fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_x2, &grd_x2)) fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_x3, &grd_x3)) fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_x4, &grd_x4)) fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);

   f1 = (float *) GMT_memory (VNULL, (size_t)((grd_x.nx  + 4) * (grd_x.ny  + 4)), sizeof(float), GMT_program);
   f2 = (float *) GMT_memory (VNULL, (size_t)((grd_x2.nx + 4) * (grd_x2.ny + 4)), sizeof(float), GMT_program);
   f3 = (float *) GMT_memory (VNULL, (size_t)((grd_x3.nx + 4) * (grd_x3.ny + 4)), sizeof(float), GMT_program);
   f4 = (float *) GMT_memory (VNULL, (size_t)((grd_x4.nx + 4) * (grd_x4.ny + 4)), sizeof(float), GMT_program);

   GMT_pad[0] = GMT_pad[1] = GMT_pad[2] = GMT_pad[3] = 2;

   GMT_boundcond_param_prep (&grd_x,  &edgeinfo_x);
   GMT_boundcond_param_prep (&grd_x2, &edgeinfo_x2);
   GMT_boundcond_param_prep (&grd_x3, &edgeinfo_x3);
   GMT_boundcond_param_prep (&grd_x4, &edgeinfo_x4);

   GMT_boundcond_set (&grd_x, &edgeinfo_x, GMT_pad, f1);
   GMT_boundcond_set (&grd_x2, &edgeinfo_x2, GMT_pad, f2);
   GMT_boundcond_set (&grd_x3, &edgeinfo_x3, GMT_pad, f3);
   GMT_boundcond_set (&grd_x4, &edgeinfo_x4, GMT_pad, f4);

   GMT_bcr_init (&grd_x,  GMT_pad, BCR_BSPLINE, 1, &bcr_x);
   GMT_bcr_init (&grd_x2, GMT_pad, BCR_BSPLINE, 1, &bcr_x2);
   GMT_bcr_init (&grd_x3, GMT_pad, BCR_BSPLINE, 1, &bcr_x3);
   GMT_bcr_init (&grd_x4, GMT_pad, BCR_BSPLINE, 1, &bcr_x4);

   GMT_read_grd (coeff_x,  &grd_x,  f1, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_x2, &grd_x2, f2, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_x3, &grd_x3, f3, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_x4, &grd_x4, f4, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);

   fpp = efopen (pfile, "r");

   kount = 0;
   while (NULL != fgets ( temp, sizeof(temp), fpp )) {
      ++kount;
      (void) sscanf ( ((&(temp[0]))), "%lf%lf%lf%lf", &x_loc, &y_loc, &num, &sample );
   }

   if ( verbose != 0) {
      fprintf (stderr,"\n");
      fprintf (stderr,"Data file name = %s, number of input samples = %d\n", pfile, kount);
      fprintf (stderr,"\n");
   }

   samp       = ealloc1double ( kount );
   datain     = ealloc1double ( kount );
   xloc_array = ealloc1double ( kount );
   yloc_array = ealloc1double ( kount );
   vzero_opt  = ealloc1double ( kount );
   k_opt      = ealloc1double ( kount );

   wb_twt_array = ealloc1double ( kount );
   wb_z_array   = ealloc1double ( kount );

   rewind ( fpp );
   kount = -1;
   while (NULL != fgets ( temp, sizeof(temp), fpp )) {
      ++kount;
      (void) sscanf ( ((&(temp[0]))), "%lf%lf%lf%lf", &x_loc, &y_loc, &num, &sample );
      xloc_array[kount] = x_loc;
      yloc_array[kount] = y_loc;
      samp[kount]   = num;
      datain[kount] = sample;
      if ( verbose == 2 ) fprintf ( stderr, "kount = %5d, x_loc = %12.2f, y_loc = %12.2f, num = %8.2f, sample = %8.2f\n", kount, xloc_array[kount], yloc_array[kount], samp[kount], datain[kount] );
   }
   if ( verbose == 2 ) fprintf ( stderr, "\n" );
   efclose (fpp);

   factor = 0.0005;

   nump1 = kount + 1;
   depth_water = error = zero;
   for ( i=0; i<=kount; i++ ) {
      check = 0;
      x_loc = xloc_array[i];
      y_loc = yloc_array[i];
      if ( x_loc >= grd_x.x_min && x_loc <= grd_x.x_max && y_loc >= grd_x.y_min && y_loc <= grd_x.y_max ) check = 1;

      if ( check ) {
         value_coeff_x  = GMT_get_bcr_z (&grd_x,  x_loc, y_loc, f1, &edgeinfo_x,  &bcr_x);
         value_coeff_x2 = GMT_get_bcr_z (&grd_x2, x_loc, y_loc, f2, &edgeinfo_x2, &bcr_x2);
         value_coeff_x3 = GMT_get_bcr_z (&grd_x3, x_loc, y_loc, f3, &edgeinfo_x3, &bcr_x3);
         value_coeff_x4 = GMT_get_bcr_z (&grd_x4, x_loc, y_loc, f4, &edgeinfo_x4, &bcr_x4);
         if (GMT_is_dnan (value_coeff_x) || GMT_is_dnan (value_coeff_x2) || GMT_is_dnan (value_coeff_x3) || GMT_is_dnan (value_coeff_x4) ) {
            check = 0;
         } else {
            if ( value_coeff_x < 0.0 ) value_coeff_x *= -1.0;
            if ( value_coeff_x2 < 0.0 ) value_coeff_x2 *= -1.0;
            if ( value_coeff_x3 < 0.0 ) value_coeff_x3 *= -1.0;
            if ( value_coeff_x4 < 0.0 ) value_coeff_x4 *= -1.0;
            samp[i] -= value_coeff_x;        
            depth_water = value_coeff_x * value_coeff_x2 * factor;
            datain[i] -= depth_water;        
            wb_twt_array[i] = value_coeff_x;
            wb_z_array[i] = depth_water;
            if ( verbose == 3 ) fprintf ( stderr, "num = %5d, xloc = %10.2f yloc = %10.2f, WB TWT = %8.2f ms., WB Depth = %8.2f m., WB VEL = %8.2f mps., Vzero = %20.15f, K = %20.15f\n", 
              i, x_loc, y_loc, value_coeff_x, depth_water, value_coeff_x2, value_coeff_x3, value_coeff_x4 );
            vzero_opt[i] = value_coeff_x3;
            k_opt[i] = value_coeff_x4;
         }
      }
   }
   if ( verbose == 3 ) fprintf ( stderr, "\n" );

   sum = zero;
   for ( i=0; i<=kount; i++ ) {
      vzero = vzero_opt[i];
      k = k_opt[i];
      x = samp[i];
      y = ( vzero / k ) * ( exp ( k * x * factor ) - 1.0 );
      error += abs ( y - datain[i] );
      if ( verbose == 3 ) fprintf ( stderr, "%-5d %12.2f %12.2f %12.2f %12.4f %12.4f\n", i, x, datain[i], y, y - datain[i], error );

      sign = 1.0;
      error = error1 = y - datain[i];

      for (;;) {
         if ( abs(error1) < thresh ) break;

         vzero = vzero_opt[i];
         k += ( delta * sign );

         x = samp[i];
         y = ( vzero / k ) * ( exp ( k * x * factor ) - 1.0 );
         error1 = y - datain[i];

         if ( verbose == 2 ) fprintf ( stderr, "%-5d %12.2f %12.2f %12.2f %12.4f\n", i, x, datain[i], y, error1 );
         if ( (error1 > zero && error1 > error) || (error1 < zero && error1 < error) ) sign *= -1.0;
      }
      sum += abs ( y - datain[i] );
      if ( verbose ) {
         fprintf ( stderr, "%-5d %12.2f %12.2f %12.2f %12.4f %12.4f\n", i, x, datain[i], y, y - datain[i], sum );
         fprintf ( stderr, "%12.2f %12.2f ", xloc_array[i], yloc_array[i] );
         fprintf ( stderr, "%30.25f %30.25f %8.2f %8.2f %8.2f\n", vzero, k, wb_twt_array[i], wb_z_array[i], sum / (float) nump1 );
      }
      printf ( "%12.2f %12.2f ", xloc_array[i], yloc_array[i] );
      printf ( "%30.25f %30.25f %8.2f %8.2f %8.2f\n", vzero, k, wb_twt_array[i], wb_z_array[i], sum / (float) nump1 );
   }

   free1double (samp);
   free1double (datain);
   free1double (xloc_array);
   free1double (yloc_array);
   free1double (vzero_opt);
   free1double (k_opt);
   free1double (wb_twt_array);
   free1double (wb_z_array);

   GMT_free ((void *)f1);
   GMT_free ((void *)f2);
   GMT_free ((void *)f3);
   GMT_free ((void *)f4);

   GMT_end (argc, argv);

   return EXIT_SUCCESS;
}
int main (int argc, char **argv) {

   char file[BUFSIZ];
   char *coeff_top_k, *coeff_bottom_k;
   char *coeff_wb_twt, *coeff_top_twt, *coeff_middle_twt, *coeff_bottom_twt;
   char *coeff_middle_vint, *coeff_bottom_vint, *coeff_campan_vint;
   char *coeff_top_z, *coeff_bottom_z;

   struct GRD_HEADER grd_top_k, grd_bottom_k;
   struct GRD_HEADER grd_wb_twt, grd_top_twt, grd_middle_twt, grd_bottom_twt;
   struct GRD_HEADER grd_middle_vint, grd_bottom_vint, grd_campan_vint;
   struct GRD_HEADER grd_top_z, grd_bottom_z;

   struct GMT_EDGEINFO edgeinfo_top_k, edgeinfo_bottom_k;
   struct GMT_EDGEINFO edgeinfo_wb_twt, edgeinfo_top_twt, edgeinfo_middle_twt, edgeinfo_bottom_twt;
   struct GMT_EDGEINFO edgeinfo_middle_vint, edgeinfo_bottom_vint, edgeinfo_campan_vint;
   struct GMT_EDGEINFO edgeinfo_top_z, edgeinfo_bottom_z;

   struct GMT_BCR bcr_top_k, bcr_bottom_k;
   struct GMT_BCR bcr_wb_twt, bcr_top_twt, bcr_middle_twt, bcr_bottom_twt;
   struct GMT_BCR bcr_middle_vint, bcr_bottom_vint, bcr_campan_vint;
   struct GMT_BCR bcr_top_z, bcr_bottom_z;

   double value_coeff_top_k, value_coeff_bottom_k;
   double value_coeff_wb_twt, value_coeff_top_twt, value_coeff_middle_twt, value_coeff_bottom_twt;
   double value_coeff_middle_vint, value_coeff_bottom_vint, value_coeff_campan_vint;
   double value_coeff_top_z, value_coeff_bottom_z;

   short  verbose;
   int    scalar, nz, ntr, ns;
   double water_depth, vwater, ratio, factor1, dz, x_loc, y_loc; 
   double tr_msec, tr_msec_orig, dt_msec, depth_input, amp_output;
   double delrt_depth, delta_twt, delta_k, gradient, K;
   double *tr_amp, *depth;
   register int k, n;

   initargs(argc, argv);
   argc = GMT_begin (argc, argv);

   if (!getparstring ("coeff_top_k",       &coeff_top_k))       coeff_top_k       = "/home/user/FIELD.new/PICKS/DEPTH_GRIDS/below.ml.K.grd";
   if (!getparstring ("coeff_bottom_k",    &coeff_bottom_k))    coeff_bottom_k    = "/home/user/FIELD.new/PICKS/DEPTH_GRIDS/bottom.K.grd";
   if (!getparstring ("coeff_wb_twt",      &coeff_wb_twt))      coeff_wb_twt      = "/home/user/FIELD.new/PICKS/wb.twt.grd";
   if (!getparstring ("coeff_top_twt",     &coeff_top_twt))     coeff_top_twt     = "/home/user/FIELD.new/PICKS/TWT_GRIDS/01_FIELD_Top_Reservoir_twt.reform.dat.trimmed.grd";
   if (!getparstring ("coeff_middle_twt",  &coeff_middle_twt))  coeff_middle_twt  = "/home/user/FIELD.new/PICKS/TWT_GRIDS/06_FIELD_C_top_twt.reform.dat.trimmed.grd";
   if (!getparstring ("coeff_bottom_twt",  &coeff_bottom_twt))  coeff_bottom_twt  = "/home/user/FIELD.new/PICKS/TWT_GRIDS/10_FIELD_80MaSB_twt.reform.dat.trimmed.grd";
   if (!getparstring ("coeff_middle_vint", &coeff_middle_vint)) coeff_middle_vint = "/home/user/FIELD.new/PICKS/VINT_GRIDS/vint.top_res.C_Sand.mps.filter.grd";
   if (!getparstring ("coeff_bottom_vint", &coeff_bottom_vint)) coeff_bottom_vint = "/home/user/FIELD.new/PICKS/VINT_GRIDS/vint.C_Sand.80MaSB.mps.filter.grd";
   if (!getparstring ("coeff_campan_vint", &coeff_campan_vint)) coeff_campan_vint = "/home/user/FIELD.new/PICKS/VINT_GRIDS/vint.top_res.80MaSB.mps.filter.grd";
   if (!getparstring ("coeff_top_z",       &coeff_top_z))       coeff_top_z       = "/home/user/FIELD.new/PICKS/DEPTH_GRIDS/01_FIELD_Top_Reservoir.depth.new.grd";
   if (!getparstring ("coeff_bottom_z",    &coeff_bottom_z))    coeff_bottom_z    = "/home/user/FIELD.new/PICKS/DEPTH_GRIDS/10_FIELD_80MaSB.depth.new.grd";

   if (!getparshort ("verbose", &verbose)) verbose = 0;

   if ( verbose ) {
      fprintf ( stderr, "\n" );
      fprintf ( stderr, "Top_K       - GMT grid file name = %s\n", coeff_top_k );
      fprintf ( stderr, "Bottom_K    - GMT grid file name = %s\n", coeff_bottom_k );
      fprintf ( stderr, "WB_TWT      - GMT grid file name = %s\n", coeff_wb_twt );
      fprintf ( stderr, "TOP_TWT     - GMT grid file name = %s\n", coeff_top_twt );
      fprintf ( stderr, "MIDDLE_TWT  - GMT grid file name = %s\n", coeff_middle_twt );
      fprintf ( stderr, "BOTTOM_TWT  - GMT grid file name = %s\n", coeff_bottom_twt );
      fprintf ( stderr, "MIDDLE_VINT - GMT grid file name = %s\n", coeff_middle_vint );
      fprintf ( stderr, "BOTTOM_VINT - GMT grid file name = %s\n", coeff_bottom_vint );
      fprintf ( stderr, "CAMPAN_VINT - GMT grid file name = %s\n", coeff_campan_vint );
      fprintf ( stderr, "TOP_Z       - GMT grid file name = %s\n", coeff_top_z );
      fprintf ( stderr, "BOTTOM_Z    - GMT grid file name = %s\n", coeff_bottom_z );
      fprintf ( stderr, "\n" );
   }

   GMT_boundcond_init (&edgeinfo_top_k);
   GMT_boundcond_init (&edgeinfo_bottom_k);
   GMT_boundcond_init (&edgeinfo_wb_twt);
   GMT_boundcond_init (&edgeinfo_top_twt);
   GMT_boundcond_init (&edgeinfo_middle_twt);
   GMT_boundcond_init (&edgeinfo_bottom_twt);
   GMT_boundcond_init (&edgeinfo_middle_vint);
   GMT_boundcond_init (&edgeinfo_bottom_vint);
   GMT_boundcond_init (&edgeinfo_campan_vint);
   GMT_boundcond_init (&edgeinfo_top_z);
   GMT_boundcond_init (&edgeinfo_bottom_z);

   GMT_grd_init (&grd_top_k,       argc, argv, FALSE);
   GMT_grd_init (&grd_bottom_k,    argc, argv, FALSE);
   GMT_grd_init (&grd_wb_twt,      argc, argv, FALSE);
   GMT_grd_init (&grd_top_twt,     argc, argv, FALSE);
   GMT_grd_init (&grd_middle_twt,  argc, argv, FALSE);
   GMT_grd_init (&grd_bottom_twt,  argc, argv, FALSE);
   GMT_grd_init (&grd_middle_vint, argc, argv, FALSE);
   GMT_grd_init (&grd_bottom_vint, argc, argv, FALSE);
   GMT_grd_init (&grd_campan_vint, argc, argv, FALSE);
   GMT_grd_init (&grd_top_z,       argc, argv, FALSE);
   GMT_grd_init (&grd_bottom_z,    argc, argv, FALSE);

   if (GMT_read_grd_info (coeff_top_k, &grd_top_k))             fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_bottom_k, &grd_bottom_k))       fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_wb_twt, &grd_wb_twt))           fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_top_twt, &grd_top_twt))         fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_middle_twt, &grd_middle_twt))   fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_bottom_twt, &grd_bottom_twt))   fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_middle_vint, &grd_middle_vint)) fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_bottom_vint, &grd_bottom_vint)) fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_campan_vint, &grd_campan_vint)) fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_top_z, &grd_top_z))             fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);
   if (GMT_read_grd_info (coeff_bottom_z, &grd_bottom_z))       fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file);

   f_top_k       = (float *) GMT_memory (VNULL, (size_t)((grd_top_k.nx  + 4)       * (grd_top_k.ny  + 4)),       sizeof(float), GMT_program);
   f_bottom_k    = (float *) GMT_memory (VNULL, (size_t)((grd_bottom_k.nx  + 4)    * (grd_bottom_k.ny  + 4)),    sizeof(float), GMT_program);
   f_wb_twt      = (float *) GMT_memory (VNULL, (size_t)((grd_wb_twt.nx  + 4)      * (grd_wb_twt.ny  + 4)),      sizeof(float), GMT_program);
   f_top_twt     = (float *) GMT_memory (VNULL, (size_t)((grd_top_twt.nx  + 4)     * (grd_top_twt.ny  + 4)),     sizeof(float), GMT_program);
   f_middle_twt  = (float *) GMT_memory (VNULL, (size_t)((grd_middle_twt.nx  + 4)  * (grd_middle_twt.ny  + 4)),  sizeof(float), GMT_program);
   f_bottom_twt  = (float *) GMT_memory (VNULL, (size_t)((grd_bottom_twt.nx  + 4)  * (grd_bottom_twt.ny  + 4)),  sizeof(float), GMT_program);
   f_middle_vint = (float *) GMT_memory (VNULL, (size_t)((grd_middle_vint.nx  + 4) * (grd_middle_vint.ny  + 4)), sizeof(float), GMT_program);
   f_bottom_vint = (float *) GMT_memory (VNULL, (size_t)((grd_bottom_vint.nx  + 4) * (grd_bottom_vint.ny  + 4)), sizeof(float), GMT_program);
   f_campan_vint = (float *) GMT_memory (VNULL, (size_t)((grd_campan_vint.nx  + 4) * (grd_campan_vint.ny  + 4)), sizeof(float), GMT_program);
   f_top_z       = (float *) GMT_memory (VNULL, (size_t)((grd_top_z.nx  + 4)       * (grd_top_z.ny  + 4)),       sizeof(float), GMT_program);
   f_bottom_z    = (float *) GMT_memory (VNULL, (size_t)((grd_bottom_z.nx  + 4)    * (grd_bottom_z.ny  + 4)),    sizeof(float), GMT_program);

   GMT_pad[0] = GMT_pad[1] = GMT_pad[2] = GMT_pad[3] = 2;

   GMT_boundcond_param_prep (&grd_top_k,       &edgeinfo_top_k);
   GMT_boundcond_param_prep (&grd_bottom_k,    &edgeinfo_bottom_k);
   GMT_boundcond_param_prep (&grd_wb_twt,      &edgeinfo_wb_twt);
   GMT_boundcond_param_prep (&grd_top_twt,     &edgeinfo_top_twt);
   GMT_boundcond_param_prep (&grd_middle_twt,  &edgeinfo_middle_twt);
   GMT_boundcond_param_prep (&grd_bottom_twt,  &edgeinfo_bottom_twt);
   GMT_boundcond_param_prep (&grd_middle_vint, &edgeinfo_middle_vint);
   GMT_boundcond_param_prep (&grd_bottom_vint, &edgeinfo_bottom_vint);
   GMT_boundcond_param_prep (&grd_campan_vint, &edgeinfo_campan_vint);
   GMT_boundcond_param_prep (&grd_top_z,       &edgeinfo_top_z);
   GMT_boundcond_param_prep (&grd_bottom_z,    &edgeinfo_bottom_z);

   GMT_boundcond_set (&grd_top_k,       &edgeinfo_top_k,       GMT_pad, f_top_k);
   GMT_boundcond_set (&grd_bottom_k,    &edgeinfo_bottom_k,    GMT_pad, f_bottom_k);
   GMT_boundcond_set (&grd_wb_twt,      &edgeinfo_wb_twt,      GMT_pad, f_wb_twt);
   GMT_boundcond_set (&grd_top_twt,     &edgeinfo_top_twt,     GMT_pad, f_top_twt);
   GMT_boundcond_set (&grd_middle_twt,  &edgeinfo_middle_twt,  GMT_pad, f_middle_twt);
   GMT_boundcond_set (&grd_bottom_twt,  &edgeinfo_bottom_twt,  GMT_pad, f_bottom_twt);
   GMT_boundcond_set (&grd_middle_vint, &edgeinfo_middle_vint, GMT_pad, f_middle_vint);
   GMT_boundcond_set (&grd_bottom_vint, &edgeinfo_bottom_vint, GMT_pad, f_bottom_vint);
   GMT_boundcond_set (&grd_campan_vint, &edgeinfo_campan_vint, GMT_pad, f_campan_vint);
   GMT_boundcond_set (&grd_top_z,       &edgeinfo_top_z,       GMT_pad, f_top_z);
   GMT_boundcond_set (&grd_bottom_z,    &edgeinfo_bottom_z,    GMT_pad, f_bottom_z);

   GMT_bcr_init (&grd_top_k,       GMT_pad, BCR_BSPLINE, 1, &bcr_top_k);
   GMT_bcr_init (&grd_bottom_k,    GMT_pad, BCR_BSPLINE, 1, &bcr_bottom_k);
   GMT_bcr_init (&grd_wb_twt,      GMT_pad, BCR_BSPLINE, 1, &bcr_wb_twt);
   GMT_bcr_init (&grd_top_twt,     GMT_pad, BCR_BSPLINE, 1, &bcr_top_twt);
   GMT_bcr_init (&grd_middle_twt,  GMT_pad, BCR_BSPLINE, 1, &bcr_middle_twt);
   GMT_bcr_init (&grd_bottom_twt,  GMT_pad, BCR_BSPLINE, 1, &bcr_bottom_twt);
   GMT_bcr_init (&grd_middle_vint, GMT_pad, BCR_BSPLINE, 1, &bcr_middle_vint);
   GMT_bcr_init (&grd_bottom_vint, GMT_pad, BCR_BSPLINE, 1, &bcr_bottom_vint);
   GMT_bcr_init (&grd_campan_vint, GMT_pad, BCR_BSPLINE, 1, &bcr_campan_vint);
   GMT_bcr_init (&grd_top_z,       GMT_pad, BCR_BSPLINE, 1, &bcr_top_z);
   GMT_bcr_init (&grd_bottom_z,    GMT_pad, BCR_BSPLINE, 1, &bcr_bottom_z);

   GMT_read_grd (coeff_top_k,       &grd_top_k,       f_top_k,       0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_bottom_k,    &grd_bottom_k,    f_bottom_k,    0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_wb_twt,      &grd_wb_twt,      f_wb_twt,      0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_top_twt,     &grd_top_twt,     f_top_twt,     0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_middle_twt,  &grd_middle_twt,  f_middle_twt,  0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_bottom_twt,  &grd_bottom_twt,  f_bottom_twt,  0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_middle_vint, &grd_middle_vint, f_middle_vint, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_bottom_vint, &grd_bottom_vint, f_bottom_vint, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_campan_vint, &grd_campan_vint, f_campan_vint, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_top_z,       &grd_top_z,       f_top_z,       0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);
   GMT_read_grd (coeff_bottom_z,    &grd_bottom_z,    f_bottom_z,    0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE);

   /* Get info from first trace */
   ntr     = gettra (&tr, 0);
   ns      = tr.ns;
   scalar  = abs ( tr.scalel );
   if ( scalar == 0 ) scalar = 1; 
   dt_msec = tr.dt * 0.001;

   if (!getpardouble ("dz",&dz)) dz = 1;
   if (!getpardouble ("vwater",&vwater)) vwater = 1452.05;
   if (!getparint    ("nz",&nz)) nz = ns;

   if ( verbose ) {
      fprintf ( stderr, "Output depth sample rate (dz) = %f\n", dz );
      fprintf ( stderr, "Number of output depth samples per trace = %d\n", nz );
      fprintf ( stderr, "Number of traces = %d, number of samples per trace = %d\n", ntr, ns );
      fprintf ( stderr, "Time sample rate (milliseconds) = %f\n", dt_msec );
      fprintf ( stderr, "Vwater = %f (meters/second)\n", vwater );
      fprintf ( stderr, "Location scalar = %d\n", scalar );
      fprintf ( stderr, "\n" );
   }

   rewind (stdin);

   if ( ns > nz ) {
      depth = ealloc1double ( ns );
   } else {
      depth = ealloc1double ( nz );
   }
   tr_amp = ealloc1double ( ns );

   factor1 = 0.0005;
   delrt_depth = 0.0;

   /* Main loop over traces */
   for ( k = 0; k < ntr; ++k ) {
      gettr (&tr);
      x_loc = tr.sx / scalar;
      y_loc = tr.sy / scalar;
      for ( n=ns; n < nz; ++n ) depth[n] = 0;

      if ( x_loc >= grd_wb_twt.x_min && x_loc <= grd_wb_twt.x_max && y_loc >= grd_wb_twt.y_min && y_loc <= grd_wb_twt.y_max ) {

         value_coeff_top_k       = GMT_get_bcr_z (&grd_top_k,       x_loc, y_loc, f_top_k,       &edgeinfo_top_k,       &bcr_top_k);
         value_coeff_bottom_k    = GMT_get_bcr_z (&grd_bottom_k,    x_loc, y_loc, f_bottom_k,    &edgeinfo_bottom_k,    &bcr_bottom_k);
         value_coeff_wb_twt      = GMT_get_bcr_z (&grd_wb_twt,      x_loc, y_loc, f_wb_twt,      &edgeinfo_wb_twt,      &bcr_wb_twt);
         value_coeff_top_twt     = GMT_get_bcr_z (&grd_top_twt,     x_loc, y_loc, f_top_twt,     &edgeinfo_top_twt,     &bcr_top_twt);
         value_coeff_middle_twt  = GMT_get_bcr_z (&grd_middle_twt,  x_loc, y_loc, f_middle_twt,  &edgeinfo_middle_twt,  &bcr_middle_twt);
         value_coeff_bottom_twt  = GMT_get_bcr_z (&grd_bottom_twt,  x_loc, y_loc, f_bottom_twt,  &edgeinfo_bottom_twt,  &bcr_bottom_twt);
         value_coeff_middle_vint = GMT_get_bcr_z (&grd_middle_vint, x_loc, y_loc, f_middle_vint, &edgeinfo_middle_vint, &bcr_middle_vint);
         value_coeff_bottom_vint = GMT_get_bcr_z (&grd_bottom_vint, x_loc, y_loc, f_bottom_vint, &edgeinfo_bottom_vint, &bcr_bottom_vint);
         value_coeff_campan_vint = GMT_get_bcr_z (&grd_campan_vint, x_loc, y_loc, f_campan_vint, &edgeinfo_campan_vint, &bcr_campan_vint);
         value_coeff_top_z       = GMT_get_bcr_z (&grd_top_z,       x_loc, y_loc, f_top_z,       &edgeinfo_top_z,       &bcr_top_z);
         value_coeff_bottom_z    = GMT_get_bcr_z (&grd_bottom_z,    x_loc, y_loc, f_bottom_z,    &edgeinfo_bottom_z,    &bcr_bottom_z);

         if ( GMT_is_dnan (value_coeff_wb_twt)     || GMT_is_dnan (value_coeff_top_k)       || GMT_is_dnan (value_coeff_top_twt) ||\
              GMT_is_dnan (value_coeff_bottom_twt) || GMT_is_dnan (value_coeff_campan_vint) || GMT_is_dnan (value_coeff_bottom_k) ||\
              GMT_is_dnan (value_coeff_top_z)      || GMT_is_dnan (value_coeff_bottom_z) ) {

            for ( n=0; n < nz; ++n )  tr.data[n] = 0;
            tr.delrt = 0;
            tr.trid = 0;

         } else {

            water_depth = value_coeff_wb_twt * factor1 * vwater;
            ratio = vwater / value_coeff_top_k;

	    if ( verbose == 2 ) {
               fprintf ( stderr, "\n" );
               fprintf ( stderr, "Trace num = %5d X-Loc = %10.2f Y-Loc = %10.2f\n", k+1, x_loc, y_loc );
               fprintf ( stderr, "Top_K          = %8.5f\n", value_coeff_top_k );
               fprintf ( stderr, "Bottom_K       = %8.5f\n", value_coeff_bottom_k );
               fprintf ( stderr, "WB_TWT         = %8.2f\n", value_coeff_wb_twt );
               fprintf ( stderr, "TOP_TWT        = %8.2f\n", value_coeff_top_twt );
               fprintf ( stderr, "MIDDLE_TWT     = %8.2f\n", value_coeff_middle_twt );
               fprintf ( stderr, "BOTTOM_TWT     = %8.2f\n", value_coeff_bottom_twt );
               fprintf ( stderr, "MIDDLE_VINT    = %8.2f\n", value_coeff_middle_vint );
               fprintf ( stderr, "BOTTOM_VINT    = %8.2f\n", value_coeff_bottom_vint );
               fprintf ( stderr, "CAMPANIAN_VINT = %8.2f\n", value_coeff_campan_vint );
               fprintf ( stderr, "TOP_Z          = %8.2f\n", value_coeff_top_z );
               fprintf ( stderr, "BOTTOM_Z       = %8.2f\n", value_coeff_bottom_z );
            }

            delta_twt = value_coeff_bottom_twt - value_coeff_top_twt;
            delta_k   = value_coeff_bottom_k - value_coeff_top_k;
            gradient  = delta_k / delta_twt;

            for ( n=0; n < ns; ++n ) {
               tr_amp[n] = tr.data[n];

               if ( tr.delrt == 0 ) {
                  tr_msec = n * dt_msec;
               } else {
                  tr_msec = tr.delrt + ( n * dt_msec );
               }
 
               if ( tr_msec <= value_coeff_wb_twt ) {
                  depth[n] = tr_msec * factor1 * vwater;
                  if ( tr_msec <= tr.delrt ) delrt_depth = depth[n];
               } else if ( tr_msec <= value_coeff_top_twt ) {
                  tr_msec_orig = tr_msec;
                  tr_msec = ( tr_msec - value_coeff_wb_twt ) * factor1;
                  depth[n] = ( ratio * (exp (value_coeff_top_k*tr_msec) - 1.0) ) + water_depth;
                  if ( tr_msec_orig <= tr.delrt ) delrt_depth = depth[n];
               } else if ( tr_msec > value_coeff_top_twt && tr_msec <= value_coeff_bottom_twt ) {
                  K = value_coeff_top_k + ( ( tr_msec - value_coeff_top_twt ) * gradient ); 
                  tr_msec_orig = tr_msec;
                  tr_msec = ( tr_msec - value_coeff_wb_twt ) * factor1;
                  ratio = vwater / K;
                  depth[n] = ( ratio * (exp (K*tr_msec) - 1.0) ) + water_depth;
                  if ( tr_msec_orig <= tr.delrt ) delrt_depth = depth[n];

                  /* fprintf ( stderr, "Trace = %5d, Sample = %5d, Top_TWT = %8.2f, TWT = %8.2f, Bottom_TWT = %8.2f, Top_Z = %8.2f, Depth = %8.2f, Bottom_Z = %8.2f, Delta_twt = %8.2f, Delta_K = %10.6f, Gradient = %10.6f, K = %10.6f\n",\
                  k, n, value_coeff_top_twt, n * dt_msec, value_coeff_bottom_twt, value_coeff_top_z, depth[n], value_coeff_bottom_z, delta_twt, delta_k, gradient, K ); */

               } else if ( tr_msec > value_coeff_bottom_twt ) {
                  tr_msec_orig = tr_msec;
                  tr_msec = ( tr_msec - value_coeff_wb_twt ) * factor1;
                  ratio = vwater / value_coeff_bottom_k;
                  depth[n] = ( ratio * (exp (value_coeff_bottom_k*tr_msec) - 1.0) ) + water_depth;
                  if ( tr_msec_orig <= tr.delrt ) delrt_depth = depth[n];
               }
            }

            for ( n=0; n < nz; ++n ) {
               depth_input = n * dz;
               if ( depth_input < delrt_depth ) {
                  tr.data[n] = 0.0;
               } else {
                  dintlin ( ns, depth, tr_amp, tr_amp[0], tr_amp[ns-1], 1, &depth_input, &amp_output );
                  tr.data[n] = (float) amp_output;
               }
            }
            tr.trid = 1;
         }

         tr.ns = nz;
         tr.delrt = 0;
         tr.dt = nint(dz*1000);
         puttr (&tr);

      } else {
         fprintf ( stderr, "Input trace = %d, Xloc = %.0f Yloc = %.0f is out of bounds\n", k, x_loc, y_loc);
      }
   }

   GMT_free ((void *)f_top_k);
   GMT_free ((void *)f_bottom_k);
   GMT_free ((void *)f_wb_twt);
   GMT_free ((void *)f_top_twt);
   GMT_free ((void *)f_middle_twt);
   GMT_free ((void *)f_bottom_twt);
   GMT_free ((void *)f_middle_vint);
   GMT_free ((void *)f_bottom_vint);
   GMT_free ((void *)f_campan_vint);

   free1double (depth);
   free1double (tr_amp);

   GMT_end (argc, argv);

   return (0);
}
Ejemplo n.º 6
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {

	int i, j, nx, ny, n_read = 0, n_points = 0, one_or_zero;
	int n_output = 0, n_fields, n_pts, ii, jj, GMT_pad[4];
	
	int error = FALSE, suppress = FALSE, node = FALSE, z_only = FALSE;
	int is_double = FALSE, is_single = FALSE, is_int32 = FALSE, is_int16 = FALSE;
	int is_uint16 = FALSE, is_uint8 = FALSE, is_int8 = FALSE;
	int free_copy = TRUE, need_padding = FALSE, row_maj = FALSE;
	
	double value, west, east, south, north, threshold = 1.0, i_dx, i_dy, half, *in, *out;
	float *f;

	int	i2, argc = 0, nc_h, nr_h, mx, n_arg_no_char = 0, *i_4, interpolant = BCR_BICUBIC;
	short int *i_2;
	unsigned short int *ui_2;
	char	**argv, *i_1;
	unsigned char *ui_1;
	float	*z_4;
	double	*pdata_d, *z_8, *head;
	
	struct GRD_HEADER grd;
	struct GMT_EDGEINFO edgeinfo;
	struct GMT_BCR bcr;

	argc = nrhs;
	for (i = 0; i < nrhs; i++) {		/* Check input to find how many arguments are of type char */
		if(!mxIsChar(prhs[i])) {
			argc--;
			n_arg_no_char++;	/* Number of arguments that have a type other than char */
		}
	}
	argc++;			/* to account for the program's name to be inserted in argv[0] */

	/* get the length of the input string */
	argv = (char **)mxCalloc(argc, sizeof(char *));
	argv[0] = "grdtrack_m";
	for (i = 1; i < argc; i++)
		argv[i] = (char *)mxArrayToString(prhs[i+n_arg_no_char-1]);

	west = east = south = north = 0.0;
	
	GMT_boundcond_init (&edgeinfo);

	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			switch (argv[i][1]) {
			
				case 'R':
					error += decode_R (argv[i], &west, &east, &south, &north);
					break;
				case 'L':
					if (argv[i][2]) {
						error += GMT_boundcond_parse (&edgeinfo, &argv[i][2]);
						/*if (edgeinfo.gn) {
							GMT_io.in_col_type[0] = GMT_io.out_col_type[0] = GMT_IS_LON;
							GMT_io.in_col_type[1] = GMT_io.out_col_type[1] = GMT_IS_LAT;
						}*/
					}
					/*else {
						GMT_io.in_col_type[0] = GMT_io.out_col_type[0] = GMT_IS_LON;
						GMT_io.in_col_type[1] = GMT_io.out_col_type[1] = GMT_IS_LAT;
					}*/
					break;
				case 'N':
					node = TRUE;
					break;
				case 'Q':
					interpolant = BCR_BILINEAR;
					threshold = (argv[i][2]) ? atof (&argv[i][2]) : 1.0;
					break;
				case 'S':
					suppress = TRUE;
					break;
				case 'Z':
					z_only = TRUE;
					break;
				default:
					error = TRUE;
					break;
			}
		}
	}
	
	if (argc == 1 || error) {
		mexPrintf ("grdtrack - Sampling of a 2-D gridded netCDF grdfile along 1-D trackline\n\n");
		mexPrintf ("usage: out = grdtrack_m(grd,head,xydata, ['-L<flag>'], ['-N']\n"); 
		mexPrintf ("\t['-Q[<value>]'], ['-R<west/east/south/north>[r]'] ['-S'] ['-Z'] ['-f[i|o]<colinfo>']\n");
				
		mexPrintf ("\t<xydata> is an multicolumn array with (lon,lat) in the first two columns\n");
		mexPrintf ("\n\tOPTIONS:\n");
		mexPrintf ("\t-L sets boundary conditions.  <flag> can be either\n");
		mexPrintf ("\t   g for geographic boundary conditions\n");
		mexPrintf ("\t   or one or both of\n");
		mexPrintf ("\t   x for periodic boundary conditions on x\n");
		mexPrintf ("\t   y for periodic boundary conditions on y\n");
		mexPrintf ("\t-N Report value at nearest node instead of interpolating\n");
		mexPrintf ("\t-Q Quick mode, use bilinear rather than bicubic interpolation.\n");
		mexPrintf ("\t   Optionally, append <value> in the 0 < value <= 1 range.\n");
		mexPrintf ("\t   [Default = 1 requires all 4 nodes to be non-NaN.], <value> = 0.5\n");
		mexPrintf ("\t   will interpolate about 1/2 way from a non-NaN to a NaN node, while\n");
		mexPrintf ("\t   0.1 will go about 90%% of the way, etc.\n");
		mexPrintf ("\t-R specifies a subregion [Default is old region]\n");
		mexPrintf ("\t-S Suppress output when result equals NaN\n");
		mexPrintf ("\t-Z only output z-values [Default gives all columns]\n");
		mexPrintf ("\n\tSECRET INFO:\n");
		mexPrintf ("\t   When input points are inside the outer skirt of 2 rows and columns of\n");
		mexPrintf ("\t   the 2-D grid we don't need to set boundary conditions and as\n");
		mexPrintf ("\t   such we can use the input array without further to C order\n");
		mexPrintf ("\t   conversion (to row major). This save a lot of memory and execution\n");
		mexPrintf ("\t   time. However, this possibility works only when input 2-D array is\n");
		mexPrintf ("\t   of tipe SINGLE (though the computations are all done in doubles).\n");
		mexPrintf ("\t   The other cases request using a temporary array of size (M+2)x(N+2)\n");
		return;
	}

	if (threshold <= 0.0 || threshold > 1.0) {
		mexPrintf ("GRDTRACK_M SYNTAX ERROR -Q:  threshold must be in <0,1] range\n");
		error++;
	}
	if (error) return;

	if (nlhs == 0) {
		mexPrintf("ERROR: Must provide an output.\n");
		return;
	}

	/* Find out in which data type was given the input array */
	if (mxIsDouble(prhs[0])) {
		z_8 = mxGetPr(prhs[0]);
		is_double = TRUE;
	}
	else if (mxIsSingle(prhs[0])) {
		z_4 = mxGetData(prhs[0]);
		is_single = TRUE;
	}
	else if (mxIsInt32(prhs[0])) {
		i_4 = mxGetData(prhs[0]);
		is_int32 = TRUE;
	}
	else if (mxIsInt16(prhs[0])) {
		i_2 = mxGetData(prhs[0]);
		is_int16 = TRUE;
	}
	else if (mxIsUint16(prhs[0])) {
		ui_2 = mxGetData(prhs[0]);
		is_uint16 = TRUE;
	}
	else if (mxIsUint8(prhs[0])) {
		ui_1 = mxGetData(prhs[0]);
		is_uint8 = TRUE;
	}
	else if (mxIsInt8(prhs[0])) {
		i_1 = mxGetData(prhs[0]);
		is_int8 = TRUE;
	}
	else {
		mexPrintf("GRDTRACK ERROR: Unknown input data type.\n");
		mexErrMsgTxt("Valid types are:double, single, Int32, Int16, UInt16, UInt8 and Int8.\n");
	}

	nx = mxGetN (prhs[0]);
	ny = mxGetM (prhs[0]);
	if (!mxIsNumeric(prhs[0]) || ny < 2 || nx < 2)
		mexErrMsgTxt("First argument must contain a decent array\n");

	nc_h = mxGetN (prhs[1]);
	nr_h = mxGetM (prhs[1]);
	if (!mxIsNumeric(prhs[1]) || nr_h > 1 || nc_h < 9)
		mexErrMsgTxt("Second argument must contain a valid header of the input array.\n");
	
	head  = mxGetPr(prhs[1]);		/* Get header info */

	/* Check that thirth argument contains at least a mx2 table */
	n_pts = mxGetM (prhs[2]);
	n_fields = mxGetN(prhs[2]);
	if (!mxIsNumeric(prhs[2]) || (n_fields < 2))
		mexErrMsgTxt("GRDTRACK ERROR: thirth argument must contain the x,y positions where to interpolate.\n");
	if (z_only)
		n_fields = 0;

	/* Read the interpolation points and convert them to double */
	if (mxIsDouble(prhs[2]))
		in = mxGetPr(prhs[2]);
	else if (mxIsSingle(prhs[2]))
		in = mxGetData(prhs[2]);

	grd.x_min = head[0];	grd.x_max = head[1];
	grd.y_min = head[2];	grd.y_max = head[3];
	grd.z_min = head[4];	grd.z_max = head[5];
	grd.x_inc = head[7];	grd.y_inc = head[8];
	grd.nx = nx;			grd.ny = ny;
	grd.node_offset = irint(head[6]);
	mx = nx + 4;

	if (west == east) {	/* No subset asked for */
		west = grd.x_min;
		east = grd.x_max;
		south = grd.y_min;
		north = grd.y_max;
	}
	one_or_zero = (grd.node_offset) ? 0 : 1;
	half = (grd.node_offset) ? 0.5 : 0.0;
	nx = irint ( (east - west) / grd.x_inc) + one_or_zero;
	ny = irint ( (north - south) / grd.y_inc) + one_or_zero;
	i_dx = 1.0 / grd.x_inc;
	i_dy = 1.0 / grd.y_inc;

	if (!node) {
		/* If we don't have any point inside the two outer row/columns
		   there is no need to set boundary conditions plus all the extra
		   ovehead that it implies. So check it out here. */
		int n;
		double this_xmin, this_xmax, this_ymin, this_ymax;
		n = (interpolant == BCR_BILINEAR) ? 1 : 2;
		this_xmin = grd.x_min + n * grd.x_inc;
		this_xmax = grd.x_max - n * grd.x_inc;
		this_ymin = grd.y_min + n * grd.y_inc;
		this_ymax = grd.y_max - n * grd.y_inc;
		for (i = 0; i < n_pts; i++) {
			if (in[i] < this_xmin || in[i] > this_xmax) {
				need_padding = TRUE;
				break;
			}
			if (in[i+n_pts] < this_ymin || in[i+n_pts] > this_ymax) {
				need_padding = TRUE;
				break;
			}
		}
	}

#if original_GMT_code
	need_padding = TRUE;
#endif

	if (need_padding) row_maj = TRUE;	/* Here we have to use the old row major code */

	if (!need_padding) {		/* We can use the column major order of the Matlab array */

		if (!is_single)
			f = mxCalloc (nx * ny, sizeof (float));

		if (is_double) 
			for (j = 0; j < nx*ny; j++) f[j] = (float)z_8[j];

		else if (is_single) {
			f = z_4;
			free_copy = FALSE;	/* Signal that we shouldn't free f */
		}

		else if (is_int32)
			for (j = 0; j < nx*ny; j++) f[j] = (float)i_4[j];

		else if (is_int16)
			for (j = 0; j < nx*ny; j++) f[j] = (float)i_2[j];

		else if (is_uint16)
			for (j = 0; j < nx*ny; j++) f[j] = (float)ui_2[j];

		else if (is_uint8)
			for (j = 0; j < nx*ny; j++) f[j] = (float)ui_1[j];

		else if (is_int8)
			for (j = 0; j < nx*ny; j++) f[j] = (float)i_1[j];

		GMT_pad[0] = GMT_pad[1] = GMT_pad[2] = GMT_pad[3] = 0;
	}

	else {

		f = mxCalloc ((nx+4)*(ny+4), sizeof (float));

		/* Transpose from Matlab orientation to gmt grd orientation */
		if (is_double) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
				ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = (float)z_8[j*ny+i];
			}
		}
		else if (is_single) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
				ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = z_4[j*ny+i];
			}
		}
		else if (is_int32) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
				ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = (float)i_4[j*ny+i];
			}
		}
		else if (is_int16) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
			ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = (float)i_2[j*ny+i];
			}
		}
		else if (is_uint16) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
				ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = (float)ui_2[j*ny+i];
			}
		}
		else if (is_uint8) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
				ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = (float)ui_1[j*ny+i];
			}
		}
		else if (is_int8) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
				ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = (float)i_1[j*ny+i];
			}
		}

		GMT_pad[0] = GMT_pad[1] = GMT_pad[2] = GMT_pad[3] = 2;

		GMT_boundcond_param_prep (&grd, &edgeinfo);
	}
	
	/*project_info.w = west;	project_info.e = east;
	project_info.s = south;	project_info.n = north;*/
	
	/* Initialize bcr structure:  */

	GMT_bcr_init (&grd, GMT_pad, interpolant, threshold, &bcr);

	if (need_padding)
		/* Set boundary conditions  */
		GMT_boundcond_set (&grd, &edgeinfo, GMT_pad, f);
	
	if ((out = mxCalloc(n_pts * (n_fields+1), sizeof (double))) == 0)
		mexErrMsgTxt("GRDTRACK ERROR: Could not allocate memory\n");

	for (i = 0; i < n_pts; i++) {
		while ( (mxIsNaN(in[i]) || mxIsNaN(in[i+n_pts])) && !z_only) {
			for (j = 0; j < n_fields; j++) out[j*n_pts+i] = in[j*n_pts+i];
			out[j*n_pts+i] = mxGetNaN();
			i++;
		}

		/* If point is outside grd area, shift it using periodicity or skip if not periodic. */
		while ( (in[i+n_pts] < grd.y_min) && (edgeinfo.nyp > 0) ) in[i+n_pts] += (grd.y_inc * edgeinfo.nyp);
		if (in[i+n_pts] < grd.y_min) continue;

		while ( (in[i+n_pts] > grd.y_max) && (edgeinfo.nyp > 0) ) in[i+n_pts] -= (grd.y_inc * edgeinfo.nyp);
		if (in[i+n_pts] > grd.y_max) continue;

		while ( (in[i] < grd.x_min) && (edgeinfo.nxp > 0) ) in[i] += (grd.x_inc * edgeinfo.nxp);
		if (in[i] < grd.x_min) continue;

		while ( (in[i] > grd.x_max) && (edgeinfo.nxp > 0) ) in[i] -= (grd.x_inc * edgeinfo.nxp);
		if (in[i] > grd.x_max) continue;
		
		if (node) {
			ii = irint ((in[i] - grd.x_min) * i_dx - half) + one_or_zero;
			jj = irint ((grd.y_max - in[i+n_pts]) * i_dy - half) + one_or_zero;
			value = f[(jj+GMT_pad[3])*mx+ii+GMT_pad[0]];
		}
		else
			value = GMT_get_bcr_z(&grd, in[i], in[i+n_pts], f, &edgeinfo, &bcr, row_maj);

		if (suppress && mxIsNaN (value)) continue;

		if (z_only) {	/* Simply print out value */
			out[i] = value;
		}
		else {	/* Simply copy other columns, append value, and output */
			for (j = 0; j < n_fields; j++) out[j*n_pts+i] = in[j*n_pts+i];
			out[j*n_pts+i] = value;
		}
	}

	/*if (!(!need_padding && !is_single)) {
		mexPrintf("Merda vou Friar %d\t%d\n", need_padding, is_single);
		mxFree((void *)f);
	}*/
	if (free_copy)
		mxFree((void *)f);

	plhs[0] = mxCreateDoubleMatrix (n_pts,n_fields+1, mxREAL);
	pdata_d = mxGetPr(plhs[0]);
	memcpy(pdata_d, out, n_pts*(n_fields+1)*8);
	mxFree(out);
}