Example #1
0
main()
{
	int ixin,ixout;
	float dxin=2.0,fxin=0.0,dxout=2.0,fxout=-5.0;
	float xin[NXIN],yin[NXIN],xout[NXOUT],yout[NXOUT],x;

	for (ixin=0,x=fxin+(NXIN-1)*dxin; ixin<NXIN; ixin++,x-=dxin) {
		xin[ixin] = x;
		yin[ixin] = 1.0;
	}
	for (ixout=0,x=fxout; ixout<NXOUT; ixout++,x+=dxout)
		xout[ixout] = x;
	intlin(NXIN,xin,yin,yin[0],yin[NXIN-1],NXOUT,xout,yout);
	pp1d(stdout,"constant extrapolation",NXOUT,0,yout);
	getchar();
	intlin(NXIN,xin,yin,0.0,0.0,NXOUT,xout,yout);
	pp1d(stdout,"zero extrapolation",NXOUT,0,yout);
}
Example #2
0
int
main(int argc, char **argv)
{
	char *key=NULL;		/* header key word from segy.h		*/
	char *type=NULL;	/* ... its type				*/
	int index;		/* ... its index			*/
	Value val;		/* ... its value			*/
	float fval;		/* ... its value cast to float		*/

	float *xshift=NULL;	/* array of key shift curve values	*/
	float *tshift=NULL;	/* ...		shift curve time values */

	int nxshift;		/* number of key shift values		*/
	int ntshift;		/* ...		shift time values 	*/

	int nxtshift;		/* number of shift values 		*/

	int it;			/* sample counter			*/
	int itr;		/* trace counter			*/
	int nt;			/* number of time samples 		*/
	int ntr=0;		/* number of traces			*/
	int *inshift=NULL;	/* array of (integer) time shift values
				   used for positioning shifted trace in
				   data[][]				*/

	float dt;		/* time sampling interval		*/

	cwp_String xfile="";	/* file containing positions by key	*/
	FILE *xfilep=NULL;	/* ... its file pointer			*/
	cwp_String tfile="";	/* file containing times	 	*/
	FILE *tfilep=NULL;	/* ... its file pointer			*/

	int verbose;		/* flag for printing information	*/
	char *tmpdir=NULL;	/* directory path for tmp files		*/
	cwp_Bool istmpdir=cwp_false;/* true for user-given path		*/

	int median;		/* flag for median filter		*/
	int nmed;		/* no. of traces to median filter	*/
	int nmix;		/* number of traces to mix over		*/
	int imix;		/* mixing counter			*/
	float *mix=NULL;	/* array of mix values			*/
	int sign;		/* flag for up/down shift		*/
	int shiftmin=0;		/* minimum time shift (in samples)	*/
	int shiftmax=0;		/* maximum time shift (in samples)	*/
	int ntdshift;		/* nt + shiftmax			*/

	size_t mixbytes;	/* size of mixing array			*/
	size_t databytes;	/* size of data array			*/
	size_t shiftbytes;	/* size of data array			*/
	float *temp=NULL;	/* temporary array			*/
	float *dtemp=NULL;	/* temporary array			*/
	float *stemp=NULL;	/* rwh median sort array		*/
	float **data=NULL;	/* mixing array 			*/
	int subtract;		/* flag for subtracting shifted data	*/

	/* rwh extra pointers for median sort */
	int first;		/* start pointer in ring buffer */
	int middle;		/* middle pointer in ring buffer */
	int last;		/* last pointer in ring buffer */
	int halfwidth;		/* mid point */
	int trcount;		/* pointer to current start trace number */
	float tmp;		/* temp storage for bubble sort */
	int rindex;		/* wrap around index for ring buffer */
	int jmix;		/* internal pointer for bubble sort */
	

	/* Initialize */
	initargs(argc, argv);
	requestdoc(1);

	/* Get parameters */
	if (!(getparstring("xfile",&xfile) && getparstring("tfile",&tfile))) {
		if (!(nxshift = countparval("xshift")))
			err("must give xshift= vector");
		if (!(ntshift = countparval("tshift")))
			err("must give tshift= vector");
		if (nxshift != ntshift)
			err("lengths of xshift, tshift must be the same");
		xshift = ealloc1float(nxshift);	getparfloat("xshift", xshift);
		tshift = ealloc1float(nxshift);	getparfloat("tshift", tshift);
	} else {
		MUSTGETPARINT("nshift",&nxtshift);
		nxshift = nxtshift;
		xshift = ealloc1float(nxtshift);
		tshift = ealloc1float(nxtshift);

		if((xfilep=fopen(xfile,"r"))==NULL)
			err("cannot open xfile=%s\n",xfile);
		if (fread(xshift,sizeof(float),nxtshift,xfilep)!=nxtshift)
			err("error reading xfile=%s\n",xfile);
		fclose(xfilep);

		if((tfilep=fopen(tfile,"r"))==NULL)
			err("cannot open tfile=%s\n",tfile);
		if (fread(tshift,sizeof(float),nxtshift,tfilep)!=nxtshift)
			err("error reading tfile=%s\n",tfile);
		fclose(tfilep);
	}
	if (!getparstring("key", &key))		key = "tracl";

	/* Get key type and index */
	type = hdtype(key);
	index = getindex(key);   

	/* Get mix weighting values values */
	if ((nmix = countparval("mix"))!=0) {
		mix = ealloc1float(nmix);
		getparfloat("mix",mix);
		/* rwh check nmix is odd */
		if (nmix%2==0) {
			err("number of mixing coefficients must be odd");
		}		
	} else {
		nmix = 5;
		mix = ealloc1float(nmix);
		mix[0] = VAL0;
		mix[1] = VAL1;
		mix[2] = VAL2;
		mix[3] = VAL3;
		mix[4] = VAL4;
	}
	
	/* Get remaning parameters */
	if (!getparint("median",&median))	median = 0;
	if (!getparint("nmed",&nmed) && median)	nmed = 5;
	if (!getparint("sign",&sign))		sign = -1;
	if (!getparint("subtract",&subtract))	subtract = 1;
	if (!getparint("verbose", &verbose))	verbose = 0;

	/* rwh check nmed is odd */
	if (median && nmed%2==0) {
		nmed=nmed+1;
		warn("increased nmed by 1 to ensure it is odd");
	}

	/* Look for user-supplied tmpdir */
	if (!getparstring("tmpdir",&tmpdir) &&
	    !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
	if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
		err("you can't write in %s (or it doesn't exist)", tmpdir);

	/* rwh fix for median filter if median true set nmix=nmed */
	if (!median) {
		/* Divide mixing weights by number of traces to mix */
		for (imix = 0; imix < nmix; ++imix)
			mix[imix]=mix[imix]/((float) nmix);
	} else {
		nmix=nmed;
	}

	/* Get info from first trace */
	if (!gettr(&tr)) err("can't read first trace");
	if (!tr.dt) err("dt header field must be set");
	dt   = ((double) tr.dt)/1000000.0;
	nt = (int) tr.ns;
	databytes = FSIZE*nt;

	/* Tempfiles */
	if (STREQ(tmpdir,"")) {
		tracefp = etmpfile();
		headerfp = etmpfile();
		if (verbose) warn("using tmpfile() call");
	} else { /* user-supplied tmpdir */
		char directory[BUFSIZ];
		strcpy(directory, tmpdir);
		strcpy(tracefile, temporary_filename(directory));
		strcpy(headerfile, temporary_filename(directory));
		/* Trap signals so can remove temp files */
		signal(SIGINT,  (void (*) (int)) closefiles);
		signal(SIGQUIT, (void (*) (int)) closefiles);
		signal(SIGHUP,  (void (*) (int)) closefiles);
		signal(SIGTERM, (void (*) (int)) closefiles);
		tracefp = efopen(tracefile, "w+");
		headerfp = efopen(headerfile, "w+");
      		istmpdir=cwp_true;		
		if (verbose) warn("putting temporary files in %s", directory);
	}

	/* Read headers and data while getting a count */
	do {
		++ntr;
		efwrite(&tr, 1, HDRBYTES, headerfp);
		efwrite(tr.data, 1, databytes, tracefp);   

	} while (gettr(&tr));
	rewind(headerfp);
	rewind(tracefp);
	
	/* Allocate space for inshift vector */
	inshift = ealloc1int(ntr);

	/* Loop over headers */
 	for (itr=0; itr<ntr; ++itr) {
		float tmin=tr.delrt/1000.0;
		float t;

		/* Read header values */
		efread(&tr, 1, HDRBYTES, headerfp);

		/* Get value of key and convert to float */
		gethval(&tr, index, &val);
		fval = vtof(type,val);

		/* Linearly interpolate between (xshift,tshift) values */
		intlin(nxshift,xshift,tshift,tmin,tshift[nxshift-1],1,&fval,&t);
		
		/* allow for fractional shifts -> requires interpolation */ 
		inshift[itr] = NINT((t - tmin)/dt);
		
		/* Find minimum and maximum shifts */
		if (itr==0) {
			 shiftmax=inshift[0];
			 shiftmin=inshift[0];
		} else {
			shiftmax = MAX(inshift[itr],shiftmax);
			shiftmin = MIN(inshift[itr],shiftmin);
		}
	}
	rewind(headerfp);
	rewind(tracefp);

	if (verbose) {
		for (itr=0;itr<ntr;itr++)
			warn("inshift[%d]=%d",itr,inshift[itr]);
	}

	/* Compute databytes per trace and bytes in mixing panel */
	ntdshift = nt + shiftmax;
	shiftbytes = FSIZE*ntdshift;
	mixbytes = shiftbytes*nmix;
	if (verbose) {
		warn("nt=%d  shiftmax=%d  shiftmin=%d",nt,shiftmax,shiftmin);
		warn("ntdshift=%d  shiftbytes=%d  mixbytes=%d",
						ntdshift,shiftbytes,mixbytes);
	}
	
	/* Allocate space and zero  data array */
	data = ealloc2float(ntdshift,nmix);
	temp = ealloc1float(ntdshift);
	dtemp = ealloc1float(nt);
	memset( (void *) data[0], 0, mixbytes);

	/* rwh array for out of place bubble sort (so we do not corrupt order in ring buffer */ 
	stemp = ealloc1float(nmix);

	/* rwh first preload ring buffer symmetrically (now you know why nmix must be odd) */
	trcount=-1;
	halfwidth=(nmix-1)/2+1;
	first = 0;
	last  = nmix-1;
	middle = (nmix-1)/2;

	for (itr=0; itr<halfwidth; itr++) {
		efread(tr.data, 1, databytes, tracefp);
		trcount++;
		for(it=0; it<nt; ++it) {
			/* sign to account for positive or negative shift */
			/* tr.data needs to be interpolated for non-integer shifts */
			data[middle-itr][it + shiftmax + sign*inshift[itr]] = tr.data[it];
			data[middle+itr][it + shiftmax + sign*inshift[itr]] = tr.data[it];
		}
	}
	
	/* Loop over traces performing median filtering  */
 	for (itr=0; itr<ntr; ++itr) {

		/* paste header and data on output trace */
		efread(&tr, 1, HDRBYTES, headerfp);

		/* Zero out temp and dtemp */
		memset((void *) temp, 0, shiftbytes);
		memset((void *) dtemp, 0, databytes);

		/* Loop over time samples */
		for (it=0; it<nt; ++it) {

			/* Weighted moving average (mix) ? */
			if (!median) {
				for(imix=0; imix<nmix; ++imix) {
					temp[it] += data[imix][it] * mix[imix];
				}
			} else {
			
			/* inlcude median stack */
			/* rwh do bubble sort and choose median value */
				for(imix=0; imix<nmix; ++imix) {
					stemp[imix]=data[imix][it];
				}
				for (imix=0; imix<nmix-1; imix++) {
					for (jmix=0; jmix<nmix-1-imix; jmix++) {
						if (stemp[jmix+1] < stemp[jmix]) {
							tmp = stemp[jmix];
							stemp[jmix] = stemp[jmix+1];
							stemp[jmix+1] = tmp;
						}
					}
				}
				temp[it] = stemp[middle];
			}

			/* shift back mixed data and put into dtemp */
			if (subtract) {
				if ((it - shiftmax - sign*inshift[itr])>=0)
					dtemp[it - shiftmax - sign*inshift[itr]] = data[middle][it]-temp[it];
			} else {
				if ((it - shiftmax)>=0)
				dtemp[it - shiftmax - sign*inshift[itr]] = temp[it];
			}
		}
		memcpy((void *) tr.data,(const void *) dtemp,databytes);
			
		/* Bump rows of data[][] over by 1 to free first row for next tr.data */
		for (imix=nmix-1; 0<imix; --imix)
			memcpy((void *) data[imix],(const void *) data[imix-1],shiftbytes);
			/*for (it=0; it<nt; ++it)
				data[imix][it] = data[imix-1][it];*/

		/* Write output trace */
		tr.ns = nt;
		puttr(&tr);

		/* read next trace into buffer */
		if (trcount < ntr) {
			efread(tr.data, 1, databytes, tracefp);
			trcount++;

			/* read tr.data into first row of mixing array */
			/* WMH: changed ntdshift to nt */
			for(it=0; it<nt; ++it) {
				/* sign to account for positive or negative shift */
				/* tr.data needs to be interpolated for non-integer shifts */
				data[0][it + shiftmax + sign*inshift[trcount]] = tr.data[it];
			}
		} else {
			rindex=2*(trcount-ntr);
			memcpy((void *) data[0],(const void *) data[rindex],shiftbytes);
			trcount++;
		}

	}

	if (verbose && subtract)	warn("filtered data subtracted from input");

	/* Clean up */
	efclose(headerfp);
	if (istmpdir) eremove(headerfile);
	efclose(tracefp);
	if (istmpdir) eremove(tracefile);

	return(CWP_Exit());
}
Example #3
0
int
main(int argc, char **argv)
{
	int nt;		/* number of time samples per trace */
	float dt;	/* time sampling interval */
	float ft;	/* time of first sample */
	int it;		/* time sample index */
	int ncdp;	/* number of cdps specified */
	float *cdp;	/* array[ncdp] of cdps */
	int icdp;	/* index into cdp array */
	int jcdp;	/* index into cdp array */
	int nvnmo;	/* number of vnmos specified */
	float *vnmo;	/* array[nvnmo] of vnmos */
	int ntnmo;	/* number of tnmos specified */
	float *tnmo;	/* array[ntnmo] of tnmos */
	float **ovv;	/* array[ncdp][nt] of sloth (1/velocity^2) functions */
	float *ovvt;	/* array[nt] of sloth for a particular trace */
	int nanis1;	/* number of anis1's specified */
	int nanis2;	/* number of anis2's specified */
	float *anis1;	/* array[nanis1] of anis1's */
	float *anis2;	/* array[nanis2] of anis2's */
	float **oa1;	/* array[ncdp][nt] of anis1 functions */
	float **oa2;	/* array[ncdp][nt] of anis2 functions */
	float *oa1t;	/* array[nt] of anis1 for a particular trace */
	float *oa2t;	/* array[nt] of anis2 for a particular trace */
	float smute;	/* zero samples with NMO stretch exceeding smute */
	float osmute;	/* 1/smute */
	int lmute;	/* length in samples of linear ramp for mute */
	int itmute=0;	/* zero samples with indices less than itmute */
	int sscale;	/* if non-zero, apply NMO stretch scaling */
	int invert;	/* if non-zero, do inverse NMO */
	float sy;	/* cross-line offset component */
	int ixoffset;	/* indes for cross-line offset component */
	long oldoffset;	/* offset of previous trace */
	long oldcdp;	/* cdp of previous trace */
	int newsloth;	/* if non-zero, new sloth function was computed */
	float tn;	/* NMO time (time after NMO correction) */
	float v;	/* velocity */
	float *qtn;	/* NMO-corrected trace q(tn) */
	float *ttn;	/* time t(tn) for NMO */
	float *atn;	/* amplitude a(tn) for NMO */
	float *qt;	/* inverse NMO-corrected trace q(t) */
	float *tnt;	/* time tn(t) for inverse NMO */
	float *at;	/* amplitude a(t) for inverse NMO */
	float acdp;	/* temporary used to sort cdp array */
	float *aovv;	/* temporary used to sort ovv array */
	float *aoa1;	/* temporary used to sort oa1 array */
	float *aoa2;	/* temporary used to sort oa2 array */
	float temp;	/* temporary float */
	float tsq;	/* temporary float */
	int i;		/* index used in loop */
	int upward;	/* scans upward if it's nonzero. */

	/* hook up getpar */
	initargs(argc, argv);
	requestdoc(1);

	/* get information from the first header */
	if (!gettr(&tr)) err("can't get first trace");
	nt = tr.ns;
	dt = ((double) tr.dt)/1000000.0;
	ft = tr.delrt/1000.0;
	sy  = tr.sy;

	/* get velocity functions, linearly interpolated in time */
	ncdp = countparval("cdp");
	if (ncdp>0) {
		if (countparname("vnmo")!=ncdp)
			err("a vnmo array must be specified for each cdp");
		if (countparname("tnmo")!=ncdp)
			err("a tnmo array must be specified for each cdp");
		if (countparname("anis1")!=ncdp &&
		    countparname("anis1")!=0)
			err("an anis1 array must be specified for each cdp, "
			    "or omitted at all");
		if (countparname("anis2")!=ncdp &&
		    countparname("anis2")!=0)
			err("an anis2 array must be specified for each cdp, "
			    "or omitted at all");
	} else {
		ncdp = 1;
		if (countparname("vnmo")>1)
			err("only one (or no) vnmo array must be specified");
		if (countparname("tnmo")>1)
			err("only one (or no) tnmo array must be specified");
		if (countparname("anis1")>1)
			err("only one (or no) anis1 array must be specified");
		if (countparname("anis2")>1)
			err("only one (or no) anis2 array must be specified");
	}
	cdp = ealloc1float(ncdp);
	if (!getparfloat("cdp",cdp)) cdp[0] = tr.cdp;
	ovv = ealloc2float(nt,ncdp);
	oa1 = ealloc2float(nt,ncdp);
	oa2 = ealloc2float(nt,ncdp);
	for (icdp=0; icdp<ncdp; ++icdp) {
		nvnmo = countnparval(icdp+1,"vnmo");
		ntnmo = countnparval(icdp+1,"tnmo");
		nanis1 = countnparval(icdp+1,"anis1");
		nanis2 = countnparval(icdp+1,"anis2");
		if (nvnmo!=ntnmo && !(ncdp==1 && nvnmo==1 && ntnmo==0))
			err("number of vnmo and tnmo values must be equal");
		if (nanis1!=nvnmo && nanis1 != 0)
			err("number of vnmo and anis1 values must be equal");
		if (nanis2!=nvnmo && nanis2 != 0)
			err("number of vnmo and anis2 values must be equal");
		if (nvnmo==0) nvnmo = 1;
		if (ntnmo==0) ntnmo = nvnmo;
		if (nanis1==0) nanis1 = nvnmo;
		if (nanis2==0) nanis2 = nvnmo;
		/* equal numbers of parameters vnmo, tnmo, anis1, anis2 */
		vnmo = ealloc1float(nvnmo);
		tnmo = ealloc1float(nvnmo);
		anis1 = ealloc1float(nvnmo);
		anis2 = ealloc1float(nvnmo);
		if (!getnparfloat(icdp+1,"vnmo",vnmo)) vnmo[0] = 1500.0;
		if (!getnparfloat(icdp+1,"tnmo",tnmo)) tnmo[0] = 0.0;
		if (!getnparfloat(icdp+1,"anis1",anis1)) 
			for (i=0; i<nvnmo; i++) anis1[i] = 0.0;
		if (!getnparfloat(icdp+1,"anis2",anis2))
			for (i=0; i<nvnmo; i++) anis2[i] = 0.0;
		for (it=1; it<ntnmo; ++it)
			if (tnmo[it]<=tnmo[it-1])
				err("tnmo values must increase monotonically");
		for (it=0,tn=ft; it<nt; ++it,tn+=dt) {
			intlin(ntnmo,tnmo,vnmo,vnmo[0],vnmo[nvnmo-1],1,&tn,&v);
			ovv[icdp][it] = 1.0/(v*v);
		}
		for (it=0,tn=ft; it<nt; ++it,tn+=dt) {
			intlin(ntnmo,tnmo,anis1,anis1[0],anis1[nanis1-1],1,&tn,
			       &oa1[icdp][it]);
		}
		for (it=0,tn=ft; it<nt; ++it,tn+=dt) {
			intlin(ntnmo,tnmo,anis2,anis2[0],anis2[nanis2-1],1,&tn,
			       &oa2[icdp][it]);
		}
		free1float(vnmo);
		free1float(tnmo);
		free1float(anis1);
		free1float(anis2);
	}

	/* sort (by insertion) sloth and anis functions by increasing cdp */
	for (jcdp=1; jcdp<ncdp; ++jcdp) {
		acdp = cdp[jcdp];
		aovv = ovv[jcdp];
		aoa1 = oa1[jcdp];
		aoa2 = oa2[jcdp];
		for (icdp=jcdp-1; icdp>=0 && cdp[icdp]>acdp; --icdp) {
			cdp[icdp+1] = cdp[icdp];
			ovv[icdp+1] = ovv[icdp];
			oa1[icdp+1] = oa1[icdp];
			oa2[icdp+1] = oa2[icdp];
		}
		cdp[icdp+1] = acdp;
		ovv[icdp+1] = aovv;
		oa1[icdp+1] = aoa1;
		oa2[icdp+1] = aoa2;
	}

	/* get other optional parameters */
	if (!getparfloat("smute",&smute)) smute = 1.5;
	if (!getparint("ixoffset",&ixoffset)) ixoffset=0; 
	  if (ixoffset==0) sy = 0.0;
	if (smute<=0.0) err("smute must be greater than 0.0");
	if (!getparint("lmute",&lmute)) lmute = 25;
	if (!getparint("sscale",&sscale)) sscale = 1;
	if (!getparint("invert",&invert)) invert = 0;
	if (!getparint("upward",&upward)) upward = 0;

	/* allocate workspace */
	ovvt = ealloc1float(nt);
	oa1t = ealloc1float(nt);
	oa2t = ealloc1float(nt);
	ttn = ealloc1float(nt);
	atn = ealloc1float(nt);
	qtn = ealloc1float(nt);
	tnt = ealloc1float(nt);
	at = ealloc1float(nt);
	qt = ealloc1float(nt);

	/* interpolate sloth and anis function for first trace */
	interpovv(nt,ncdp,cdp,ovv,oa1,oa2,(float)tr.cdp,ovvt,oa1t,oa2t);

	/* set old cdp and old offset for first trace */
	oldcdp = tr.cdp;
	oldoffset = tr.offset-1;

	warn("sy = %f",sy);

	/* loop over traces */
	do {
		/* if necessary, compute new sloth and anis function */
		if (tr.cdp!=oldcdp && ncdp>1) {
			interpovv(nt,ncdp,cdp,ovv,oa1,oa2,(float)tr.cdp,
				  ovvt,oa1t,oa2t);
			newsloth = 1;
		} else {
			newsloth = 0;
		}

		/* if sloth and anis function or offset has changed */
		if (newsloth || tr.offset!=oldoffset) {
			/* compute time t(tn) (normalized) */
			temp = ((float) tr.offset*(float) tr.offset + sy*sy)/(dt*dt);
			for (it=0,tn=ft/dt; it<nt; ++it,tn+=1.0) {
				tsq = temp*ovvt[it] + \
				      oa1t[it]*temp*temp / (1.0+oa2t[it]*temp);
				if (tsq<0.0)
					err("negative moveout; check anis1, "
					    "anis2, or suwind far-offset "
					    "traces");
				if ((1.0+oa2t[it]*temp)<=0.0)
					err("anis2 negative and too small; "
					    "check anis2, or suwind far-offset"
					    " traces");
				ttn[it] = sqrt (tn*tn + tsq);
				}
			/* compute inverse of stretch factor a(tn) */
			atn[0] = ttn[1]-ttn[0];
			for (it=1; it<nt; ++it)
				atn[it] = ttn[it]-ttn[it-1];
			
			/* determine index of first sample to survive mute */
			osmute = 1.0/smute;
			if( !upward ) {
				for (it=0; it<nt-1 && atn[it]<osmute; ++it)
					;
			} else {
				/* scan samples from bottom to top */
				for (it=nt-1; it>0 && atn[it]>=osmute; --it)
					;
			}
			itmute = it;

			/* if inverse NMO will be performed */
			if (invert) {
							
				/* compute tn(t) from t(tn) */
				yxtoxy(nt-itmute,1.0,ft/dt+itmute,&ttn[itmute],
					nt-itmute,1.0,ft/dt+itmute,
					ft/dt-nt,ft/dt+nt,&tnt[itmute]);
			
				/* adjust mute time */
				itmute = 1.0+ttn[itmute]-ft/dt;
				itmute = MIN(nt-2,itmute);
								
				/* compute a(t) */
				if (sscale) {
					for (it=itmute+1; it<nt; ++it)
						at[it] = tnt[it]-tnt[it-1];
					at[itmute] = at[itmute+1];
				}
			}
		}
		
		/* if forward (not inverse) nmo */
		if (!invert) {
	
			/* do nmo via 8-point sinc interpolation */
			ints8r(nt,1.0,ft/dt,tr.data,0.0,0.0,
				nt-itmute,&ttn[itmute],&qtn[itmute]);
			
			/* apply mute */
			for (it=0; it<itmute; ++it)
				qtn[it] = 0.0;
			
			/* apply linear ramp */
			for (it=itmute; it<itmute+lmute && it<nt; ++it)
				qtn[it] *= (float)(it-itmute+1)/(float)lmute;
			
			/* if specified, scale by the NMO stretch factor */
			if (sscale)
				for (it=itmute; it<nt; ++it)
					qtn[it] *= atn[it];
			
			/* copy NMO corrected trace to output trace */
			memcpy( (void *) tr.data,
					(const void *) qtn, nt*sizeof(float));
		
		/* else inverse nmo */
		} else {
	
			/* do inverse nmo via 8-point sinc interpolation */
			ints8r(nt,1.0,ft/dt,tr.data,0.0,0.0,
				nt-itmute,&tnt[itmute],&qt[itmute]);
			
			/* apply mute */
			for (it=0; it<itmute; ++it)
				qt[it] = 0.0;
			
			/* if specified, undo NMO stretch factor scaling */
			if (sscale)
				for (it=itmute; it<nt; ++it)
					qt[it] *= at[it];
			
			/* copy inverse NMO corrected trace to output trace */
			memcpy( (void *) tr.data,
					(const void *) qt,nt*sizeof(float));
		}

		/* write output trace */
		puttr(&tr);

		/* remember offset and cdp */
		oldoffset = tr.offset;
		oldcdp = tr.cdp;

	} while (gettr(&tr));

	return(CWP_Exit());
}
Example #4
0
int main (int argc, char **argv)
{
	int nt,it,np,ntau,itau,nx,ix,nk,nkmax,ik,
		ntfft,nxfft,nv,trans,norm,conv,verbose;
	float dt,dx,dpx,k,dk,kscl,t,*tt,*vt,*tmig,*vmig,
		(*vsind)[4],**ptx,**divcor;
	complex **ptk;
	char *vfile="";
	FILE *hfp,*tfp;
	
	/* hook up getpar */
	initargs(argc,argv);
	requestdoc(1);

	/* get information from the first header */
	if (!gettr(&tr)) err("can't get first trace");
	nt = tr.ns;
	dt = tr.dt/1000000.0;

	/* get parameters */
	if (!getparfloat("dxcdp",&dx)) err("dxcdp required");
	if (!getparint("np",&np)) np=50;
	if (!getparint("trans",&trans)) trans=0;
	if (!getparint("norm",&norm)) norm=1;
	if (!getparint("conv",&conv)) conv=0;
	if (!getparint("verbose",&verbose)) verbose=0;

	/* get velocity function */
	vt=ealloc1float(nt);
	tt=ealloc1float(nt);
	for (it=0; it<nt; it++)
		tt[it]=it*dt;
	if (!getparstring ("vfile",&vfile)){
		ntau = countparval("tmig");

		if (ntau==0) ntau=1;
		tmig = ealloc1float(ntau);

		if (!getparfloat("tmig",tmig)) tmig[0] = 0.0;

		nv = countparval("vmig");

		if (nv==0) nv=1;

		if (nv!=ntau) 
			err("number of tmig and vmig must be equal");

		vmig = ealloc1float(nv);

		if (!getparfloat("vmig",vmig)) vmig[0] = 1500.0;
		for (itau=1; itau<ntau; itau++)
			if (tmig[itau]<=tmig[itau-1])
			    err("tmig must increase monotonically");
		for (it=0,t=0.0; it<nt; ++it,t+=dt)
			intlin(ntau,tmig,vmig,vmig[0],vmig[ntau-1],
				1,&t,&vt[it]);
		if (ntau!=nt){
			vsind = (float (*)[4])ealloc1float(ntau*4);
			cmonot(ntau,tmig,vmig,vsind);
			intcub(0,ntau,tmig,vsind,nt,tt,vt);
		}
	} else{
		if (fread(vt,sizeof(float),nt,fopen(vfile,"r"))!=nt)
			err("Not %d velocities in file %s",nt,vfile);
	}

	/* copy traces and headers to temporary files */
	tfp = tmpfile();
	hfp = tmpfile();
	nx = 0;
	do {
		nx++;
		fwrite(&tr,HDRBYTES,1,hfp);
		fwrite(tr.data,sizeof(float),nt,tfp);

	} while(gettr(&tr));
  	fseek(hfp,0L,SEEK_SET);
	fseek(tfp,0L,SEEK_SET);
	if (verbose) fprintf(stderr,"\t%d traces input\n",nx);

	/* determine wavenumber and frequency sampling */
	nxfft = npfar(nx);
	ntfft = npfa(nt);
	nk = nxfft/2+1;
	dx *= 0.001;
	dk = 2.0*PI/(nxfft*dx);

	/* allocate space for Fourier transform */
	ptk = ealloc2complex(nt,nk);
	ptx = ealloc1(nxfft,sizeof(float*));
	for (ix=0; ix<nxfft; ++ix)
		ptx[ix] = (float*)ptk[0]+ix*nt;

	/* allocate space for divergence correction */
	divcor=ealloc2float(nt,np);

	/* build table of divergence corrections */
	divcortable(nt,np,dt,tt,vt,divcor,trans,norm);	

	/* apply conventional correction if required */
	if (conv==1){
		for (ix=0; ix<nx; ++ix){
			efread(ptx[ix],sizeof(float),nt,tfp);
		for (it=0; it<nt; ++it)
			ptx[ix][it] *= divcor[0][it];
		}
	} else {
		/* read and apply fft scaling to traces */ 
		kscl = 1.0/nxfft;
		for (ix=0; ix<nx; ++ix) {
			efread(ptx[ix],sizeof(float),nt,tfp);
			for (it=0; it<nt; ++it)
				ptx[ix][it] *= kscl;
		}
		/* pad with zeros */
		for (ix=nx; ix<nxfft; ++ix)
			for (it=0; it<nt; ++it)
				ptx[ix][it] = 0.0;

		/* Fourier transform ptx(t,x) to ptk(t,k) */
		pfa2rc(-1,2,nt,nxfft,ptx[0],ptk[0]);
		if (verbose) fprintf(stderr,"\tFourier transform done\n");

		/* define relevant k range */
		nkmax = MIN(nk,NINT(PI/dt/vt[0]/dk));
		dpx = 1.0/(np-1)/vt[0];
		fprintf(stderr,
			"nkmax %d nk %d dk %f dpx %f \n",nkmax,nk,dk,dpx);

		/* special case k=0 */
		for (it=0; it<nt; it++){
			ptk[0][it].r *= divcor[0][it];
			ptk[0][it].i *= divcor[0][it];
		}
	
		/* loop over wavenumbers */
		for (ik=1,k=dk; ik<nkmax; ++ik,k+=dk){

			/* report */
			if (verbose && ik%(nkmax/10>0?nkmax/10:1)==0)
				fprintf(stderr,"\t%d of %d wavenumbers done\n",
						ik,nkmax);
		
			/* dip filter divergence correction */
			dipfilt(k,dpx,dt,np,ntfft,nt,divcor,ptk[ik],ptk[ik]);
		}

		/* Fourier transform p(t,k) to p(t,x) */
		pfa2cr(1,2,nt,nxfft,ptk[0],ptx[0]);
		if (verbose) 
			fprintf(stderr,"\tinverse Fourier transform done\n");
	} /* end else dipdivcor */

	/* output migrated traces with headers */
	for (ix=0; ix<nx; ++ix) {
		efread(&tr,HDRBYTES,1,hfp);
		memcpy((void *) tr.data,
			(const void *) ptx[ix], nt*sizeof(float));
		puttr(&tr);
	}
	
	return EXIT_SUCCESS;
}
Example #5
0
int
main (int argc, char **argv)
{
	int nt;			/* number of time samples */
	int ntau;		/* number of migrated time samples */
	int nx;			/* number of midpoints 	*/
	int ik,ix,it,itau,itmig;/* loop counters 	*/
	int nxfft;		/* fft size		*/
	int nk;			/* number of wave numbers */	

	int ntmig,nvmig;	

	float dt;		/* time sampling interval 	*/
	float ft;		/* first time sample		*/
	float dtau;		/* migrated time sampling interval */
	float ftau;		/* first migrated time value 	*/
	float dk;		/* wave number sampling interval */
	float fk;		/* first wave number 		*/
	float Q, ceil;		/* quality factor, ceiling of amplitude */
	float t,k;		/* time,wave number		*/
	float *tmig, *vmig;	/* arrays of time, interval velocities */
	float dx;		/* spatial sampling interval	*/
	float *vt;		/* velocity v(t)		*/
	float **p,**q;		/* input, output data		*/

	complex **cp,**cq;	/* complex input,output		*/

	char *vfile="";		/* name of file containing velocities */
	int verbose=0;		/* flag for echoing info		*/
	char *tmpdir;		/* directory path for tmp files		*/
	cwp_Bool istmpdir=cwp_false;/* true for user-given path		*/

	/* hook up getpar to handle the parameters */
	initargs(argc,argv);
	requestdoc(1);

	/* get info from first trace */
	if (!gettr(&tr))  err("can't get first trace");
	nt = tr.ns;

	/* let user give dt and/or dx from command line */
	if (!getparfloat("dt", &dt)) {
		if (tr.dt) { /* is dt field set? */
			dt = ((double) tr.dt)/1000000.0;
		} else { /* dt not set, assume 4 ms */
			dt = 0.004;
			warn("tr.dt not set, assuming dt=0.004");
		}
	}
	if (!getparfloat("dx",&dx)) {
		if (tr.d2) { /* is d2 field set? */
			dx = tr.d2;
		} else {
			dx = 1.0;
			warn("tr.d2 not set, assuming d2=1.0");
		}
	}


	/* get optional parameters */
	if (!getparfloat("ft",&ft)) ft = 0.0;
	if (!getparint("ntau",&ntau)) ntau = nt; CHECK_NT("ntau",ntau);
	if (!getparfloat("dtau",&dtau)) dtau = dt;
	if (!getparfloat("ftau",&ftau)) ftau = ft;
	if (!getparfloat("Q",&Q)) Q = 1.0e6;
	if (!getparfloat("ceil",&ceil)) ceil = 1.0e6; 
		if (verbose)warn("Q=%f ceil=%f",Q,ceil); 

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

	/* Look for user-supplied tmpdir */
	if (!getparstring("tmpdir",&tmpdir) &&
	    !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir="";
	if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK))
		err("you can't write in %s (or it doesn't exist)", tmpdir);


	/* store traces and headers in tempfiles while getting a count */
	if (STREQ(tmpdir,"")) {
		tracefp = etmpfile();
		headerfp = etmpfile();
		if (verbose) warn("using tmpfile() call");
	} else { /* user-supplied tmpdir */
		char directory[BUFSIZ];
		strcpy(directory, tmpdir);
		strcpy(tracefile, temporary_filename(directory));
		strcpy(headerfile, temporary_filename(directory));
		/* Trap signals so can remove temp files */
		signal(SIGINT,  (void (*) (int)) closefiles);
		signal(SIGQUIT, (void (*) (int)) closefiles);
		signal(SIGHUP,  (void (*) (int)) closefiles);
		signal(SIGTERM, (void (*) (int)) closefiles);
		tracefp = efopen(tracefile, "w+");
		headerfp = efopen(headerfile, "w+");
      		istmpdir=cwp_true;		
		if (verbose) warn("putting temporary files in %s", directory);
	}

	nx = 0;
	do {
		 ++nx;
		efwrite(&tr,HDRBYTES,1,headerfp);
		efwrite(tr.data, FSIZE, nt, tracefp);
	} while (gettr(&tr));
	erewind(tracefp);
	erewind(headerfp);
	
	/* determine wavenumber sampling (for real to complex FFT) */
	nxfft = npfar(nx);
	nk = nxfft/2+1;
	dk = 2.0*PI/(nxfft*dx);
	fk = 0.0;
	
	/* allocate space */
	p = alloc2float(nt,nxfft);
	q = alloc2float(ntau,nxfft);
	cp = alloc2complex(nt,nk);
	cq = alloc2complex(ntau,nk);

	/* load traces into the zero-offset array and close tmpfile */
	efread(*p, FSIZE, nt*nx, tracefp);
	efclose(tracefp);

	/* determine velocity function v(t) */
	vt = ealloc1float(ntau);
	if (!getparstring("vfile",&vfile)) {
		ntmig = countparval("tmig");
		if (ntmig==0) ntmig = 1;
		tmig = ealloc1float(ntmig);
		if (!getparfloat("tmig",tmig)) tmig[0] = 0.0;
		nvmig = countparval("vmig");
		if (nvmig==0) nvmig = 1;
		if (nvmig!=ntmig) err("number of tmig and vmig must be equal");
		vmig = ealloc1float(nvmig);
		if (!getparfloat("vmig",vmig)) vmig[0] = 1500.0;
		for (itmig=1; itmig<ntmig; ++itmig)
			if (tmig[itmig]<=tmig[itmig-1])
				err("tmig must increase monotonically");
		for (it=0,t=0.0; it<ntau; ++it,t+=dt)
			intlin(ntmig,tmig,vmig,vmig[0],vmig[ntmig-1],
				1,&t,&vt[it]);
	} else {
		if (fread(vt,sizeof(float),nt,fopen(vfile,"r"))!=nt)
			err("cannot read %d velocities from file %s",nt,vfile);
	}
	
        checkpars();

	/* pad with zeros and Fourier transform x to k */
	for (ix=nx; ix<nxfft; ix++)
		for (it=0; it<nt; it++)
			p[ix][it] = 0.0;
	pfa2rc(-1,2,nt,nxfft,p[0],cp[0]);
	
	/* migrate each wavenumber */
	for (ik=0,k=fk; ik<nk; ik++,k+=dk)
		gazdagvt(k,nt,dt,ft,ntau,dtau,ftau,vt,cp[ik],cq[ik], Q, ceil);
	
	/* Fourier transform k to x (including FFT scaling) */
	pfa2cr(1,2,ntau,nxfft,cq[0],q[0]);
	for (ix=0; ix<nx; ix++)
		for (itau=0; itau<ntau; itau++)
			q[ix][itau] /= nxfft;

	/* restore header fields and write output */
	for (ix=0; ix<nx; ++ix) {
		efread(&tr,HDRBYTES,1,headerfp);
		tr.ns = ntau ;
		tr.dt = dtau * 1000000.0 ;
		tr.delrt = ftau * 1000.0 ;
		memcpy( (void *) tr.data, (const void *) q[ix],ntau*FSIZE);
		puttr(&tr);
	}
	
	/* Clean up */
	efclose(headerfp);
	if (istmpdir) eremove(headerfile);
	if (istmpdir) eremove(tracefile);

	return(CWP_Exit());	
}
Example #6
0
int
main(int argc, char **argv)
{
	float phase;		/* phase shift = phasefac*PI		*/
	float power;		/* phase shift = phasefac*PI		*/
	register float *rt;	/* real trace				*/
	register complex *ct;	/* complex transformed trace		*/
	complex *filt;		/* complex power	 		*/
	int nt;			/* number of points on input trace	*/
	size_t ntsize;		/* nt in bytes				*/
	int ncdp;               /* number of cdps specified */
	int icdp;       	/* index into cdp array */

	long oldoffset;         /* offset of previous trace */
        long oldcdp;    	/* cdp of previous trace */
        int newsloth;   	/* if non-zero, new sloth function was computed */
	int jcdp;       	/* index into cdp array */
	float dt;		/* sample spacing (secs) on input trace	*/
	float tn;		/* sample spacing (secs) on input trace	*/
	float omega;		/* circular frequency			*/
	float domega;		/* circular frequency spacing (from dt)	*/
	int nfft;		/* number of points in nfft		*/
	int ntnmo;      	/* number of tnmos specified            */
	float *cdp;     	/* array[ncdp] of cdps */

	float *vnmo;   		/* array[nvnmo] of vnmos               */
	float *ovvt;   		/* array[nvnmo] of vnmos               */
	int nvnmo;      	/* number of tnmos specified            */
	float *fnmo;   		 /* array[ntnmo] of tnmos               */
	float **ovv;   		 /* array[nf] of fnmos                  */
	float doffs;             /* offset                            */
	float acdp;     	/* temporary used to sort cdp array */
        float *aovv;    	/* temporary used to sort ovv array */

        int invert;              /*  if non-zero, do invers DLMO       */
        int cm;                  /*  if non-zero, the offset in cm     */
        int nf;                 /* number of frequencies (incl Nyq)     */
        int it;                 /* number of frequencies (incl Nyq)     */
	float onfft;		/* 1 / nfft				*/
	float v;                 /* velocity                            */
	size_t nzeros;		/* number of padded zeroes in bytes	*/
	
	
	/* Initialize */
	initargs(argc, argv);
	requestdoc(1);

	/* Set parameters */
	power=0.0;

	/* Get info from first trace*/ 
	if (!gettr(&tr))	err("can't get first trace");

	nt = tr.ns;

	if (!getparfloat("dt", &dt))	dt = ((double) tr.dt)/1000000.0;
	if (!dt)	err("dt field is zero and not getparred");
	ntsize = nt * FSIZE;

        if (!getparint("invert",&invert)) invert = 0;
        if (!getparint("cm",&cm)) cm = 0;

	/* Set up for fft */
	nfft = npfaro(nt, LOOKFAC * nt);
	if (nfft >= SU_NFLTS || nfft >= PFA_MAX)
		err("Padded nt=%d -- too big", nfft);

        nf = nfft/2 + 1;
        onfft = 1.0 / nfft;
	nzeros = (nfft - nt) * FSIZE;
	domega = TWOPI * onfft / dt;


	/* get velocity functions, linearly interpolated in frequency */

	ncdp = countparval("cdp");

	if (ncdp>0) {
                if (countparname("vnmo")!=ncdp)
                        err("a vnmo array must be specified for each cdp");
                if (countparname("fnmo")!=ncdp)
                        err("a tnmo array must be specified for each cdp");
        } else {
                ncdp = 1;
                if (countparname("vnmo")>1)
                        err("only one (or no) vnmo array must be specified");
                if (countparname("fnmo")>1)
                        err("only one (or no) tnmo array must be specified");
        }

	cdp = ealloc1float(ncdp);
        if (!getparfloat("cdp",cdp)) cdp[0] = tr.cdp;
        ovv = ealloc2float(nf,ncdp);

	for (icdp=0; icdp<ncdp; ++icdp) {
                nvnmo = countnparval(icdp+1,"vnmo");
                ntnmo = countnparval(icdp+1,"fnmo");
                if (nvnmo!=ntnmo && !(ncdp==1 && nvnmo==1 && ntnmo==0))
                        err("number of vnmo and tnmo values must be equal");
                if (nvnmo==0) nvnmo = 1;
                if (ntnmo==0) ntnmo = nvnmo;
                /* equal numbers of parameters vnmo, fnmo  */

                vnmo = ealloc1float(nvnmo);
                fnmo = ealloc1float(nvnmo);

                if (!getnparfloat(icdp+1,"vnmo",vnmo)) vnmo[0] = 400.0;
                if (!getnparfloat(icdp+1,"fnmo",fnmo)) fnmo[0] = 0.0;
		

		for (it=0; it<ntnmo; ++it)
			fnmo[it]*=TWOPI;

                for (it=1; it<ntnmo; ++it)
                        if (fnmo[it]<=fnmo[it-1])
                                err("tnmo values must increase monotonically");

		for (it=0,tn=0; it<nf; ++it,tn+=domega) {
			intlin(ntnmo,fnmo,vnmo,vnmo[0],vnmo[nvnmo-1],1,&tn,&v);
			ovv[icdp][it] = 1.0/(v); 
		}
                free1float(vnmo);
                free1float(fnmo);
        }



/* sort (by insertion) sloth and anis functions by increasing cdp */

        for (jcdp=1; jcdp<ncdp; ++jcdp) {
                acdp = cdp[jcdp];
                aovv = ovv[jcdp];
                for (icdp=jcdp-1; icdp>=0 && cdp[icdp]>acdp; --icdp) {
                        cdp[icdp+1] = cdp[icdp];
                        ovv[icdp+1] = ovv[icdp];
                }
                cdp[icdp+1] = acdp;
                ovv[icdp+1] = aovv;
        }

/* allocate workspace */


        ovvt = ealloc1float(nf);

/* interpolate sloth and anis function for first trace */

        interpovv(nf,ncdp,cdp,ovv,(float)tr.cdp,ovvt);

        /* set old cdp and old offset for first trace */
        oldcdp = tr.cdp;
        oldoffset = tr.offset-1;



	/* Allocate fft arrays */
	rt   = ealloc1float(nfft);
	ct   = ealloc1complex(nf);
	filt = ealloc1complex(nf);


		

	/* Loop over traces */
	do {

		/* if necessary, compute new sloth and anis function */
                	if (tr.cdp!=oldcdp && ncdp>1) {
                        interpovv(nt,ncdp,cdp,ovv,(float)tr.cdp,
                                  ovvt);
                        newsloth = 1;
                } else {
                        newsloth = 0;
                }

		/* if sloth and anis function or offset has changed */

                if (newsloth || tr.offset!=oldoffset) {

		doffs = (fabs)((float)(tr.offset));
		if (cm==1) doffs/=100;
		/* Load trace into rt (zero-padded) */
		memcpy( (void *) rt, (const void *) tr.data, ntsize);
		memset((void *) (rt + nt), (int) '\0', nzeros);

		/* FFT */
		pfarc(1, nfft, rt, ct);


		/* Apply filter */
		{ register int i;
		for (i = 0; i < nf; ++i){
			omega = i * domega;
			if (power < 0 && i == 0) omega = FLT_MAX;
			if (invert==0)
			phase = -1.0*omega*ovvt[i]*doffs;
			else
			phase = 1.0*omega*ovvt[i]*doffs;
			
		/*	filt[i] = cmplx(cos(phase),sin(phase)); */
			filt[i] = cwp_cexp(crmul(I,phase)); 
			filt[i] = crmul(filt[i], onfft);
			ct[i] = cmul(ct[i], filt[i]);
			
			}
		}
	  }
		/* Invert */
		pfacr(-1, nfft, ct, rt);


		/* Load traces back in, recall filter had nfft factor */
		{ register int i;
		for (i = 0; i < nt; ++i)  tr.data[i] = rt[i];
		}


		puttr(&tr);

	} while (gettr(&tr));


	return EXIT_SUCCESS;
}
Example #7
0
/**************** end self doc ********************************/

segy tr;	/* Input and output trace data of length nt */
int main (int argc, char **argv)
{
	int nt;
	int icmp;
	int j;
	int neta;
	int nv;
	int ncdps;
	int nc;
	int ic;
	int ic1=0;
	int ic2=0;
	int it;
	int iv;
	int ie;
	int nvel;
	int nvstack;


	float *c;
	float *v;
	float *t;
	float *e;

	float *time;
	float *eta;
	float *vel;
	float *p;

	float vminstack;
	float dt;
	float vmin;
	float vmax;
	float etamin;
	float etamax;
	float dv;
	float deta;
	float wc=0.0;
	float wv;
	float we;
	float ee;
	float vv;
	float vscale;

	initargs(argc,argv);
	requestdoc(1);

	if (!getparint("nv",&nv)) nv = 21;
	if (!getparint("neta",&neta)) neta=11;
	if (!getparint("ncdps",&ncdps)) ncdps = 1130;
	if (!getparfloat("vmin",&vmin)) vmin = 1500.;
	if (!getparfloat("vmax",&vmax)) vmax = 2500.;
	if (!getparfloat("etamin",&etamin)) etamin = 0.10;
	if (!getparfloat("etamax",&etamax)) etamax = 0.25;
	if (!getparint("nvstack",&nvstack)) nvstack = 0;
	if (!getparfloat("vminstack",&vminstack)) vminstack = 0.25;
	if (!getparfloat("vscale",&vscale)) vscale = 1.0;

	dv=(vmax-vmin)/MAX((nv-1),1);
	deta = (etamax-etamin)/MAX((neta-1),1);
	if(deta==0) {
		deta=1;
		neta=1;
	}
	if(nvstack>5) {
		etamin=0;
		etamax=0.;
		deta=1.;
		vmin=0.;
		nv=nvstack;
		neta=1;
		dv=1./(vminstack*vminstack*(nvstack-5));
	}

	if (!gettr(&tr))  err("can't get first trace");
	nt = tr.ns;
	dt = 0.000001*tr.dt;
	fprintf(stderr,"supaint: sample rate = %f s, number of samples = %d\n",
		dt,nt);
	p = ealloc1float(nv*neta*nt);

	nc = countparname("cdp");
	if(countparname("v")!=nc) err("v array must be specified for each cdp");
	if(countparname("t")!=nc) err("t array must be specified for each cdp");
	if(nvstack<6){
		if(countparname("eta")!=nc) err("eta array must be specified for each cdp");
	}
	vel=ealloc1float(nc*nt);
	eta=ealloc1float(nc*nt);
	time=ealloc1float(nt);
	c=ealloc1float(nc);
	for(it=0;it<nt;it++) time[it]=it*dt;
	if(nvstack>5) {
	    for(ic=0;ic<nc;ic++) {
		getnparfloat(ic+1,"cdp",&c[ic]);
		nvel=countnparval(ic+1,"v");
		fprintf(stderr,"cdp=%f, number of (time,velocity) values = %d\n",c[ic],nvel);
		if(countnparval(ic+1,"t")!=nvel)
			err("For each cdp control point, t and v must have the same number of values");
		v=ealloc1float(nvel);
		t=ealloc1float(nvel);
		getnparfloat(ic+1,"t",t);
		getnparfloat(ic+1,"v",v);
		for(j=0;j<nvel;j++) v[j]*=vscale;
		for(j=0;j<nvel;j++) fprintf(stderr,"	time=%f velocity=%f\n",t[j],v[j]);
		intlin(nvel,t,v,v[0],v[nvel-1],nt,time,&vel[ic*nt]);
		free(v);
		free(t);	
	    }
	    for(j=0;j<nt*nc;j++) {
		vel[j]=1./(vel[j]*vel[j]);
		eta[j]=0.;
	    }
	}else{
	    for(ic=0;ic<nc;ic++) {
		getnparfloat(ic+1,"cdp",&c[ic]);
		nvel=countnparval(ic+1,"v");
		fprintf(stderr,"cdp=%f, number of triplet values = %d\n",c[ic],nvel);
		if(countnparval(ic+1,"t")!=nvel || countnparval(ic+1,"eta")!=nvel ) 
			err("For each cdp control point, t,v,and eta must have the same number of values");
		v=ealloc1float(nvel);
		t=ealloc1float(nvel);
		e=ealloc1float(nvel);
		getnparfloat(ic+1,"t",t);
		getnparfloat(ic+1,"v",v);
		for(j=0;j<nvel;j++) v[j]*=vscale;
		getnparfloat(ic+1,"eta",e);
		for(j=0;j<nvel;j++) {
			fprintf(stderr,"	time=%f velocity=%f eta=%f\n",
				t[j],v[j],e[j]);
		}
		intlin(nvel,t,v,v[0],v[nvel-1],nt,time,&vel[ic*nt]);
		intlin(nvel,t,e,e[0],e[nvel-1],nt,time,&eta[ic*nt]);
		free(v);
		free(t);
		free(e);
	    }
	}
	free(time);
	for(icmp=0;icmp<ncdps;icmp++) {
		for(j=0;j<(nv*neta);j++) {
			if(icmp==0 && j==0 ) {
				/* data already in memory */
			}else{
				if (!gettr(&tr))  
					err("can't get input trace");
			}
			for(it=0;it<nt;it++)
				p[it+j*nt]=tr.data[it];
		}
		if(icmp<=c[0]) {
			ic1=0;
			ic2=0;
			wc=0.;
		}else if(icmp>=c[nc-1]) {
			ic1=nc-1;
			ic2=nc-1;
			wc=0.;
		}else{
			for(ic=1;ic<nc;ic++) {
				ic1=ic-1;
				ic2=ic;
				wc=(c[ic2]-icmp)/(c[ic2]-c[ic1]);
				if(icmp>c[ic1] && icmp<=c[ic2]) break;
			}
		}

		for(it=0;it<nt;it++) {
			ee=(wc*eta[it+ic1*nt]+(1.-wc)*eta[it+ic2*nt]-etamin)/deta;
			vv=(wc*vel[it+ic1*nt]+(1.-wc)*vel[it+ic2*nt]-vmin)/dv;
			ie=ee;
			we=ee-ie;
			iv=vv;
			wv=vv-iv;
			tr.data[it]=0.;
			if(neta==1) {
				if(iv>=0 && iv<nv-1) {
					tr.data[it]=(1-wv)*p[it+iv*nt] + 
							wv*p[it+(iv+1)*nt];	
				}
			}else if(iv>=0 && iv<nv-1 && ie>=0 && ie<neta-1) {
				tr.data[it]=(1-we)*(1-wv)*p[it+(ie*nv+iv)*nt]+
					(1-we)*wv*p[it+(ie*nv+iv+1)*nt]+
					we*(1-wv)*p[it+((ie+1)*nv+iv)*nt]+
					we*wv*p[it+((ie+1)*nv+iv+1)*nt];
				}
		}
		tr.f2=0.;
		tr.d2=1.;
		tr.f1=0.;
		tr.d1=dt;
		tr.offset=0;
		tr.cdp=icmp;
		tr.igc=0;
		tr.igi=0;
		tr.sx=0.5*(tr.sx+tr.gx);
		tr.gx=tr.sx;
		tr.cdpt=0;
		puttr(&tr);
		if(icmp==20*(icmp/20)) fprintf(stderr,"supaint: have output cmp %d\n",icmp);
	}
	free(p);
	free(c);
	free(eta);
	free(vel);
	return EXIT_SUCCESS;
}
Example #8
0
int main( int argc, char *argv[] )
{
        int ntr=0;                /* number of traces                     */
        int ntrv=0;               /* number of traces                     */
	int ns=0;
	int nsv=0;
	float dt;
	float dtv;
	
	cwp_String fs;
	cwp_String fv;
	FILE *fps;
	FILE *fpv;
	FILE *headerfp;
		
	float *data;		/* data matrix of the migration volume */
	float *vel;		/* velocity matrix */
	float *velfi;		/* velocity function interpolated to ns values*/
	float *velf;		/* velocity function */
	float *vdt;
	float *ddt;
	float *ap;		/* array of apperture values in m */
	float apr;		/* array of apperture values in m */
	int *apt=NULL;		/* array of apperture time limits in mig. gath*/
	float   r;		/* maximum radius with a given apperture */
	float ir2;		/* r/d2 */
	float ir3;		/* r/d3 */
	float d2;		/* spatial sampling int. in dir 2. */
	float d3;		/* spatial sampling int. in dir 3. */
	float **mgd=NULL;	/* migration gather data */
	float *migt;		/* migrated data trace */
	int **mgdnz=NULL;		/* migration gather data non zero samples*/
	float dm;		/* migration gather spatial sample int. */
	int im;			/* number of traces in migration gather */
	int *mtnz;		/* migrated trace data non zero smaples */
	char **dummyi;		/* index array that the trace contains zeros only */
	float fac;		/* velocity scale factor */
	int sphr;		/* spherical divergence flag */
	int imt;		/* mute time sample of trace */
	float tmp;
	int imoff;
	int **igtr=NULL;
	int nigtr;
	int n2;
	int n3;

	int verbose;
	
	/* phase shift filter stuff */
        float power;            /* power of i omega applied to data     */
        float amp;              /* amplitude associated with the power  */
        float arg;              /* argument of power                    */
        float phasefac;         /* phase factor                         */
        float phase;            /* phase shift = phasefac*PI            */
        complex exparg;         /* cexp(I arg)                          */
        register float *rt;     /* real trace                           */
        register complex *ct;   /* complex transformed trace            */
        complex *filt;          /* complex power                        */
        float omega;            /* circular frequency                   */
        float domega;           /* circular frequency spacing (from dt) */
        float sign;             /* sign in front of i*omega default -1  */
        int nfft;               /* number of points in nfft             */
        int nf;                 /* number of frequencies (incl Nyq)     */
        float onfft;            /* 1 / nfft                             */
        size_t nzeros;          /* number of padded zeroes in bytes     */
	
	initargs(argc, argv);
   	requestdoc(1);
	
        MUSTGETPARSTRING("fs",&fs);
        MUSTGETPARSTRING("fv",&fv);
        MUSTGETPARINT("n2",&n2);
        MUSTGETPARINT("n3",&n3);
        MUSTGETPARFLOAT("d2",&d2);
        MUSTGETPARFLOAT("d3",&d3);
	
	if (!getparfloat("dm", &dm))	dm=(d2+d3)/2.0;
	
	/* open datafile */
        fps = efopen(fs,"r");
	fpv = efopen(fv,"r");
	
	/* Open tmpfile for headers */
	headerfp = etmpfile();

	/* get information from the first data trace */
	ntr = fgettra(fps,&tr,0);
	if(n2*n3!=ntr) err(" Number of traces in file %d not equal to n2*n3 %d \n",
			     ntr,n2*n3);
	ns=tr.ns;
	if (!getparfloat("dt", &dt))	dt = ((float) tr.dt)/1000000.0;
	if (!dt) {
		dt = .002;
		warn("dt not set, assumed to be .002");
	}

	/* get information from the first velocity trace */
	ntrv = fgettra(fpv,&trv,0);
	if(ntrv!=ntr) err(" Number of traces in velocity file %d differ from %d \n",
			     ntrv,ntr);
	nsv=trv.ns;
	if (!getparfloat("dtv", &dtv))	dtv = ((float) trv.dt)/1000000.0;
	if (!dtv) {
		dtv = .002;
		warn("dtv not set, assumed to be .002 for velocity");
	}
	
	if (!getparfloat("fac", &fac))	fac=2.0;
	if (!getparint("verbose", &verbose))	verbose=0;
	if (!getparint("sphr", &sphr))	sphr=0;
	
	if (!getparfloat("apr", &apr))	apr=75;
	apr*=3.141592653/180;

	/* allocate arrays */
	data = bmalloc(sizeof(float),ns,ntr);
	vel = bmalloc(sizeof(float),nsv,ntr);
	velf = ealloc1float(nsv); 
	velfi = ealloc1float(ns);
	migt = ealloc1float(ns);
	vdt = ealloc1float(nsv);
	ddt = ealloc1float(ns);
	ap = ealloc1float(ns);
	mtnz = ealloc1int(ns);
	dummyi = (char **) ealloc2(n2,n3,sizeof(char));
	
	/* Times to do interpolation of velocity from sparse sampling */
	/* to fine sampling of the data */
	{ register int it;
		for(it=0;it<nsv;it++) vdt[it]=it*dtv;
		for(it=0;it<ns;it++)  ddt[it]=it*dt;
	}
	
	/* Read traces into data */
        /* Store headers in tmpfile */
        ntr=0;
	erewind(fps);
	erewind(fpv);
		
	{ register int i2,i3;
	for(i3=0;i3<n3;i3++) 
		for(i2=0;i2<n2;i2++) {
			fgettr(fps,&tr);
			fgettr(fpv,&trv);
			if(tr.trid > 2) dummyi[i3][i2]=1;
			else dummyi[i3][i2]=0;	
			efwrite(&tr, 1, HDRBYTES, headerfp);
		 	bmwrite(data,1,0,i3*n2+i2,ns,tr.data);
		 	bmwrite(vel,1,0,i3*n2+i2,nsv,trv.data);
		}
	erewind(headerfp);

	/* set up the phase filter */
	power = 1.0;sign = 1.0;phasefac = 0.5;
	phase = phasefac * PI;
         
	/* Set up for fft */
        nfft = npfaro(ns, LOOKFAC * ns);
        if (nfft >= SU_NFLTS || nfft >= PFA_MAX)
                err("Padded nt=%d -- too big", nfft);

        nf = nfft/2 + 1;
        onfft = 1.0 / nfft;
        nzeros = (nfft - ns) * FSIZE;
        domega = TWOPI * onfft / dt;
        
	/* Allocate fft arrays */
        rt   = ealloc1float(nfft);
        ct   = ealloc1complex(nf);
        filt = ealloc1complex(nf);
        
	/* Set up args for complex power evaluation */
        arg = sign * PIBY2 * power + phase;
        exparg = cexp(crmul(I, arg));
        {       
		register int i;
                for (i = 0 ; i < nf; ++i) {

                        omega = i * domega;
		
		        /* kludge to handle omega=0 case for power < 0 */
                        if (power < 0 && i == 0) omega = FLT_MAX;

                        /* calculate filter */
                        amp = pow(omega, power) * onfft;
			filt[i] = crmul(exparg, amp);
                }
        }
	
	/* set up constants for migration */ 
	if(verbose) fprintf(stderr," Setting up constants....\n");
	r=0;
	for(i3=0;i3<n3;i3++) 
	    for(i2=0;i2<n2;i2++) {
		if(dummyi[i3][i2] < 1) {
			
			/* get the velocity function */
			bmread(vel,1,0,i3*n2+i2,nsv,velf);
			
			/* linear interpolation from nsv to ns values */  
			intlin(nsv,vdt,velf,velf[0],velf[nsv-1],ns,ddt,velfi);
			
			/* Apply scale factor to velocity */
			{ register int it;
				for(it=0;it<ns;it++) velfi[it] *=fac;
			}
			
			/* compute maximum radius from apperture and velocity */
			{ register int it;
				for(it=0;it<ns;it++) 
				ap[it] = ddt[it]*velfi[it]*tan(apr)/2.0;
			}
			tmp = ap[isamax(ns,ap,1)];
			if(tmp>r) r=tmp;
		}
	}
	r=MIN(r,sqrt(SQR((n2-1)*d2)+SQR((n3-1)*d3)));
	ir2 =  (int)(2*r/d2)+1;
	ir3 =  (int)(2*r/d3)+1;
	im = (int)(r/dm)+1;
		
	/*  allocate migration gather */
	mgd = ealloc2float(ns,im);
	mgdnz = ealloc2int(ns,im);
	apt = ealloc1int(im);
	/* set up the stencil for selecting traces */
	igtr = ealloc2int(ir2*ir3,2);
	stncl(r, d2, d3,igtr,&nigtr);
	
	if(verbose) {
		fprintf(stderr," Maximum radius %f\n",r);
		fprintf(stderr," Maximum offset %f\n",
			sqrt(SQR((n2-1)*d2)+SQR((n3-1)*d3)));
	}

	/* main processing loop */
	for(i3=0;i3<n3;i3++) 
	    for(i2=0;i2<n2;i2++) {
		memset( (void *) tr.data, (int) '\0',ns*FSIZE);
		if(dummyi[i3][i2] < 1) {
			memset( (void *) mgd[0], (int) '\0',ns*im*FSIZE);
			memset( (void *) mgdnz[0], (int) '\0',ns*im*ISIZE);
			/* get the velocity function */
			bmread(vel,1,0,i3*n2+i2,nsv,velf);
		
			/* linear interpolation from nsv to ns values */  
			intlin(nsv,vdt,velf,velf[0],velf[nsv-1],ns,ddt,velfi);
		
			/* Apply scale factor to velocity */
			{ register int it;
				for(it=0;it<ns;it++) velfi[it] *=fac;
			}

			/* create the migration gather */
			{ register int itr,ist2,ist3;
				for(itr=0;itr<nigtr;itr++) {
					ist2=i2+igtr[0][itr];
					ist3=i3+igtr[1][itr];
					if(ist2 >= 0 && ist2 <n2) 
						if(ist3 >= 0 && ist3 <n3) {
							if(dummyi[ist3][ist2] <1) {
								imoff = (int) ( 
								sqrt(SQR(igtr[0][itr]*d2)
							     	    +SQR(igtr[1][itr]*d3))/dm+0.5);
								bmread(data,1,0,ist3*n2+ist2,ns,tr.data);
								imoff=MIN(imoff,im-1);
								{ register int it;									
									/* get the mute time for this 
									  offset, apperture and velocity */
									xindex(ns,ap,imoff*dm,&imt);
									for(it=imt;it<ns;it++)
										if(tr.data[it]!=0) {
											mgd[imoff][it]+=tr.data[it];
											mgdnz[imoff][it]+=1;
									}	
								}
							}
						}
				}
			}

			/* normalize the gather */
				{ register int ix,it;
				for(ix=0;ix<im;ix++)
					for(it=0;it<ns;it++) 
						if(mgdnz[ix][it] > 1) mgd[ix][it] /=(float) mgdnz[ix][it];
			}
			memset( (void *) tr.data, (int) '\0',ns*FSIZE);
			memset( (void *) mtnz, (int) '\0',ns*ISIZE);
		
			/* do a knmo */
			{ register int ix,it;
				for(ix=0;ix<im;ix++) {
					/* get the mute time for this 
					offset, apperture and velocity */
					xindex(ns,ap,ix*dm,&imt);
					knmo(mgd[ix],migt,ns,velfi,0,ix*dm,dt,imt,sphr);
					/* stack the gather */
						for(it=0;it<ns;it++) { 
						if(migt[it]!=0.0) { 
								tr.data[it] += migt[it];
								mtnz[it]++;
						}
/*						tr.data[it] += mgd[ix][it]; */
					}
				}

			}
			{ register int it;
				for(it=0;it<ns;it++) 
					if(mtnz[it]>1) tr.data[it] /=(float)mtnz[it];
			}
		
			/*Do the phase filtering before the trace is released*/
                	/* Load trace into rt (zero-padded) */
               		memcpy( (void *) rt, (const void *) tr.data, ns*FSIZE);
               		memset((void *) (rt + ns), (int) '\0', nzeros);

         		pfarc(1, nfft, rt, ct);
        		{ register int i;
        			for (i = 0; i < nf; ++i)  ct[i] = cmul(ct[i], filt[i]);
        		}
         		pfacr(-1, nfft, ct, rt);
     			memcpy( (void *) tr.data, (const void *) rt, ns*FSIZE);
			
		} /* end of dummy if */
		/* spit out the gather */
		efread(&tr, 1, HDRBYTES, headerfp);
		puttr(&tr);
		if(verbose) fprintf(stderr," %d %d\n",i2,i3);
	    }   /* end of i2 loop */
	}	/* end of i3 loop */
	/* This should be the last thing */
	efclose(headerfp);
	/* Free memory */
	free2int(igtr);
	free2float(mgd);
	free2int(mgdnz);
	free1int(apt);
	bmfree(data);
	bmfree(vel);
	free1float(velfi);
	free1float(velf);
	free1float(ddt);
	free1float(vdt);
	free1float(ap);
	free1int(mtnz);
	free1float(migt);
	free1float(rt);
	free1complex(ct);
	free1complex(filt);
	free2((void **) dummyi);
	
	return EXIT_SUCCESS;
}
Example #9
0
int
main(int argc, char **argv)
{
	char *key=NULL;		/* header key word from segy.h		*/	
	char *type=NULL;	/* ... its type				*/
	int index;		/* ... its index			*/
	Value val;		/* ... its value			*/
	float fval;		/* ... its value cast to float		*/
	float twfval;		/* ... its value cast to float		*/
	float *xmute=NULL;	/* array of key mute curve values	*/
	float *tmute=NULL;	/* ...		mute curve time values 	*/
	float *twindow=NULL;	/* ...	mute window time values mode=4	*/
	float linvel;		/* linear velocity			*/
	float tm0;		/* time shift of mute=2 or 3 for 'key'=0*/
	float *taper=NULL;	/* ...		taper values		*/
	int nxmute=0;		/* number of key mute values		*/
	int ntmute;	/* ...		mute time values 	*/
	int ntwindow;	/* ...		mute time values 	*/
	int ntaper;	/* ...		taper values		*/

	int below;	/* mute below curve			*/
	int mode;	/* kind of mute (top, bottom, linear)	*/
	int absolute;    /* Take absolute value of key for mode=2 */
	int hmute=0;	/* read mute times from header		*/

	int nxtmute;	/* number of mute values 		*/
	cwp_String xfile="";	/* file containing positions by key	*/
	FILE *xfilep;		/* ... its file pointer			*/
	cwp_String tfile="";	/* file containing times	 	*/
	FILE *tfilep;		/* ... its file pointer			*/

	cwp_String twfile="";	/* file containing mute time windows 	*/
	FILE *twfilep;		/* ... its file pointer			*/

	cwp_Bool seismic;	/* cwp_true if seismic, cwp_false not seismic */

	/* Initialize */
	initargs(argc, argv);
	requestdoc(1);


	/* Get parameters */
	if (!getparint("mode", &mode))		mode = 0;

	if (getparstring("hmute", &key)) { hmute = 1; } else

	if (!(getparstring("xfile",&xfile) && getparstring("tfile",&tfile))) {
		if (!(nxmute = countparval("xmute")))
			err("must give xmute= vector");
		if (!(ntmute = countparval("tmute")))
			err("must give tmute= vector");
		if (nxmute != ntmute)
			err("lengths of xmute, tmute must be the same");
		xmute = ealloc1float(nxmute);	getparfloat("xmute", xmute);
		tmute = ealloc1float(nxmute);	getparfloat("tmute", tmute);
		if (mode==4) {
			if (!(ntwindow = countparval("twindow")))
				err("must give twindow= vector");
			if (nxmute != ntwindow)
				err("lengths of xmute, twindow must be the same");
			twindow = ealloc1float(nxmute);
			getparfloat("twindow", twindow);
		}
	} else {
		MUSTGETPARINT("nmute",&nxtmute);
		nxmute = nxtmute;
		xmute = ealloc1float(nxtmute);
		tmute = ealloc1float(nxtmute);

		if((xfilep=fopen(xfile,"r"))==NULL)
			err("cannot open xfile=%s\n",xfile);
		if (fread(xmute,sizeof(float),nxtmute,xfilep)!=nxtmute)
			err("error reading xfile=%s\n",xfile);
		fclose(xfilep);

		if((tfilep=fopen(tfile,"r"))==NULL)
			err("cannot open tfile=%s\n",tfile);
		if (fread(tmute,sizeof(float),nxtmute,tfilep)!=nxtmute)
			err("error reading tfile=%s\n",tfile);
		fclose(tfilep);

		if (mode==4) {
			if((twfilep=fopen(twfile,"r"))==NULL)
				err("cannot open tfile=%s\n",twfile);
			if (fread(twindow,sizeof(float),nxtmute,twfilep)!=nxtmute)
				err("error reading tfile=%s\n",tfile);
			fclose(twfilep);
		}
	}

	if (!getparint("ntaper", &ntaper))	ntaper = 0;
	if (getparint("below", &below))	{
		mode = below; 
		warn ("use of below parameter is obsolete. mode value set to %d \n", mode);
	}
	if (!getparint("absolute", &absolute))		absolute = 1;
	if (hmute==0) if (!getparstring("key", &key))	key = "offset";
	if (!getparfloat("linvel", &linvel))	linvel = 330;
	if (!getparfloat("tm0", &tm0))		tm0 = 0;
        checkpars();
	if (linvel==0) err ("linear velocity can't be 0");

	/* get key type and index */
	type = hdtype(key);
	index = getindex(key);

	/* Set up taper weights if tapering requested */
	if (ntaper) {
		register int k;
		taper = ealloc1float(ntaper);
		for (k = 0; k < ntaper; ++k) {
			float s = sin((k+1)*PI/(2*ntaper));
			taper[k] = s*s;
		}
	}

						
	/* Get info from first trace */
	if (!gettr(&tr)) err("can't read first trace");

	seismic = ISSEISMIC(tr.trid);

	if (seismic) {
		if (!tr.dt) err("dt header field must be set");
	} else if (tr.trid==TRID_DEPTH) {   /* depth section */
		if (!tr.d1) err("d1 header field must be set");
	} else {
		err ("tr.trid = %d, unsupported trace id",tr.trid);
	}

	/* Loop over traces */
	do {
		int nt     = (int) tr.ns;
		float tmin = tr.delrt/1000.0;
		float dt = ((double) tr.dt)/1000000.0;
		float t;
		float tw;
		int nmute;
		int itaper;
		int topmute;
		int botmute;
		int ntair=0;
		register int i;

		if (!seismic) { 
			tmin = 0.0;
			dt = tr.d1;	
		}

		/* get value of key and convert to float */
		gethval(&tr, index, &val);
		fval = vtof(type,val);
		

		if (hmute==1) {
			t = fval/1000.;
		} else {
		/* linearly interpolate between (xmute,tmute) values */
		intlin(nxmute,xmute,tmute,tmin,tmute[nxmute-1],1,&fval,&t); 
		}

		if (absolute) fval = abs(fval);
		/* do the mute */
		if (mode==0) {	/* mute above */
			nmute = MIN(NINT((t - tmin)/dt),nt);
			if (nmute>0) memset( (void *) tr.data, 0, nmute*FSIZE);
			for (i = 0; i < ntaper; ++i)
				if (i+nmute>0) tr.data[i+nmute] *= taper[i];
			if (seismic) {
				tr.muts = NINT(t*1000);
			} else	{
				tr.muts = NINT(t);
			}
		} else if (mode==1){	/* mute below */
			nmute = MAX(0,NINT((tmin + nt*dt - t)/dt));
			memset( (void *) (tr.data+nt-nmute), 0, nmute*FSIZE);
			for (i = 0; i < ntaper; ++i)
				if (nt>nmute+i && nmute+i>0)
					tr.data[nt-nmute-1-i] *= taper[i];
			if (seismic) {
				tr.mute = NINT(t*1000);
			} else	{
				tr.mute = NINT(t);
			}
		} else if (mode==2){	/* air wave mute */
			nmute = NINT((tmin+t)/dt);
			ntair=NINT(tm0/dt+fval/linvel/dt);
			topmute=MIN(MAX(0,ntair-nmute/2),nt);
			botmute=MIN(nt,ntair+nmute/2);
			memset( (void *) (tr.data+topmute), 0,
					(botmute-topmute)*FSIZE);
			for (i = 0; i < ntaper; ++i){
				itaper=ntair-nmute/2-i;
				if (itaper > 0) tr.data[itaper] *=taper[i];
			}	
			for (i = 0; i < ntaper; ++i){
				itaper=ntair+nmute/2+i;
				if (itaper<nt) tr.data[itaper] *=taper[i];
			}
		} else if (mode==3) {	/* hyperbolic mute */
			nmute = NINT((tmin + t)/dt);
			ntair=NINT(sqrt( SQ((float)(tm0/dt))+SQ((float)(fval/linvel/dt)) ));
			topmute=MIN(MAX(0,ntair-nmute/2),nt);
			botmute=MIN(nt,ntair+nmute/2);
			memset( (void *) (tr.data+topmute), 0,
					(botmute-topmute)*FSIZE);
			for (i = 0; i < ntaper; ++i){
				itaper=ntair-nmute/2-i;
				if (itaper > 0) tr.data[itaper] *=taper[i];
			}	
			for (i = 0; i < ntaper; ++i){
				itaper=ntair+nmute/2+i;
				if (itaper<nt) tr.data[itaper] *=taper[i];
			}
		} else if (mode==4) {	/* polygonal mute */
			tmin=twindow[0];
			intlin(nxmute,xmute,twindow,tmin,twindow[nxmute-1],1,&twfval,&tw); 
			if (absolute) twfval = abs(twfval);

			nmute = NINT(tw/dt);
			ntair = NINT(t/dt);

			topmute=MIN(MAX(0,ntair-nmute/2),nt);
			botmute=MIN(nt,ntair+nmute/2);
			memset( (void *) (tr.data+topmute), 0,
					(botmute-topmute)*FSIZE);
			for (i = 0;i < ntaper; ++i){
				itaper=ntair-nmute/2-i;
				if (itaper > 0) tr.data[itaper] *=taper[i];
			}	
			for (i = 0; i < ntaper; ++i){
				itaper=ntair+nmute/2+i;
				if (itaper<nt) tr.data[itaper] *=taper[i];
			}


		}
		puttr(&tr);
	} while (gettr(&tr));
	
	return(CWP_Exit());
}
Example #10
0
void slopefilter (int nslopes, float slopes[], float amps[], float bias,
	int nt, float dt, int nx, float dx, FILE *tracefp)
/******************************************************************************
apply slope filter in frequency-wavenumber domain
*******************************************************************************
Input:
nslopes		number of slopes (and amplitudes) specified
slopes		slopes at which amplitudes are specified (see notes below)
amps		amplitudes corresponding to slopes (see notes below)
bias		linear moveout slope before and after filtering
nt		number of time samples
dt		time sampling interval
nx		number of traces
dx		trace space (spatial sampling interval)
tracefp		file pointer to data to be filtered

Output:
tracefp		file pointer to filtered data
*******************************************************************************
Notes:
Linear interpolation and constant extrapolation are used to
determine amplitudes for slopes that are not specified.
******************************************************************************/
{
	int ntfft;		/* nt after padding for FFT */
	int nxfft;		/* nx after padding for FFT */
	float sfft;		/* scale factor for FFT */
	int nw;			/* number of frequencies */
	float dw;		/* frequency sampling interval */
	float fw;		/* first frequency */
	int nk;			/* number of wavenumbers */
	float dk;		/* wavenumber sampling interval */
	float w,k;		/* frequency and wavenumber */
	int it,ix,iw,ik;	/* sample indices */
	float slope,amp;	/* slope and amplitude for particular w,k */
	complex **cpfft;	/* complex FFT workspace */
	float **pfft;		/* float FFT workspace */
	float phase;		/* phase shift for bias */
	complex cshift;		/* complex phase shifter for bias */

	/* determine lengths and scale factors for prime-factor FFTs */
	ntfft = npfar(nt);
	nxfft = npfa(nx);
	sfft = 1.0/(ntfft*nxfft);
	
	/* determine frequency and wavenumber sampling */
	nw = ntfft/2+1;
	dw = 2.0*PI/(ntfft*dt);
	fw = 0.000001*dw; /* non-zero to avoid divide by zero w */
	nk = nxfft;
	dk = 2.0*PI/(nxfft*dx);

	/* allocate real and complex workspace for FFTs */
	cpfft = alloc2complex(nw,nk);
	pfft = alloc2float(ntfft,nxfft);

	/* copy data from input to FFT array and pad with zeros */
	rewind(tracefp);
	for (ix=0; ix<nx; ix++) {
		efread(pfft[ix], FSIZE, nt, tracefp);
		for (it=nt; it<ntfft; it++)
			pfft[ix][it] = 0.0;
	}
	for (ix=nx; ix<nxfft; ix++)
		for (it=0; it<ntfft; it++)
			pfft[ix][it] = 0.0;
	
	/* Fourier transform t to w */
	pfa2rc(1,1,ntfft,nx,pfft[0],cpfft[0]);
	
	/* do linear moveout bias via phase shift */
	for (ix=0; ix<nx; ix++) {
		for (iw=0,w=0.0; iw<nw; iw++,w+=dw) {
			phase = -ix*dx*w*bias;
			cshift = cmplx(cos(phase),sin(phase));
			cpfft[ix][iw] = cmul(cpfft[ix][iw],cshift);
		}
	}
	
	/* Fourier transform x to k */
	pfa2cc(-1,2,nw,nxfft,cpfft[0]);
	
	/* loop over wavenumbers */
	for (ik=0; ik<nk; ik++) {
	
		/* determine wavenumber */
		k = (ik<=nk/2) ? ik*dk : (ik-nk)*dk;
		
		/* loop over frequencies */
		for (iw=0,w=fw; iw<nw; iw++,w+=dw) {
		
			/* determine biased slope */
			slope = k/w+bias;
			
			/* linearly interpolate to find amplitude */
			intlin(nslopes,slopes,amps,amps[0],amps[nslopes-1],
				1,&slope,&amp);
			
			/* include fft scaling */
			amp *= sfft;
			
			/* filter real and imaginary parts */
			cpfft[ik][iw].r *= amp;
			cpfft[ik][iw].i *= amp;
		}
	}

	/* Fourier transform k to x */
	pfa2cc(1,2,nw,nxfft,cpfft[0]);

	/* undo linear moveout bias via phase shift */
	for (ix=0; ix<nx; ix++) {
		for (iw=0,w=0.0; iw<nw; iw++,w+=dw) {
			phase = ix*dx*w*bias;
			cshift = cmplx(cos(phase),sin(phase));
			cpfft[ix][iw] = cmul(cpfft[ix][iw],cshift);
		}
	}

	/* Fourier transform w to t */
	pfa2cr(-1,1,ntfft,nx,cpfft[0],pfft[0]);
	
	/* copy filtered data from FFT array to output */
	rewind(tracefp);
	for (ix=0; ix<nx; ix++)
		efwrite(pfft[ix], FSIZE, nt, tracefp);

	/* free workspace */
	free2complex(cpfft);
	free2float(pfft);
}
Example #11
0
int main(int argc, char* argv[])
{
  int verbose;
  sf_file in=NULL, out=NULL;
  int n1_traces;
  int n1_headers;

  char* header_format=NULL;
  sf_datatype typehead;
  /* kls do I need to add this?  sf_datatype typein; */
  float* fheader=NULL;
  float* intrace=NULL;
  int numkeys;
  int ikey;
  char** list_of_keys;
  int *indx_of_keys;
  int indx_time;
  bool pkeychanged;
  float* stktrace=NULL;
  float* stkheader=NULL;
  float* time_variant_fold=NULL;
  int eof_get_tah;
  int fold;
  int itrace=0;
  int ntaper;
  int numxmute;
  int numtmute;
  float* taper;
  char **list_of_floats;
  float* xmute;
  float* tmute;
  int indx_of_offset;
  float offset;
  float d1;
  float o1;
  float mute_start;
  int imute_start;
  int indx_taper;


  /*****************************/
  /* initialize verbose switch */
  /*****************************/
  sf_init (argc,argv);

  if(!sf_getint("verbose",&verbose))verbose=1;
    /* \n
     flag to control amount of print
     0 terse, 1 informative, 2 chatty, 3 debug
  */
  sf_warning("verbose=%d",verbose);
 
  /******************************************/
  /* input and output data are stdin/stdout */
  /******************************************/

  if(verbose>0)fprintf(stderr,"read in file name\n");  
  in = sf_input ("in");

  if(verbose>0)fprintf(stderr,"read out file name\n");
  out = sf_output ("out");

  if (!sf_histint(in,"n1_traces",&n1_traces))
    sf_error("input data not define n1_traces");
  if (!sf_histint(in,"n1_headers",&n1_headers)) 
    sf_error("input data does not define n1_headers");

  header_format=sf_histstring(in,"header_format");
  if(strcmp (header_format,"native_int")==0) typehead=SF_INT;
  else                                       typehead=SF_FLOAT;

  if(verbose>0)fprintf(stderr,"allocate headers.  n1_headers=%d\n",n1_headers);
  fheader = sf_floatalloc(n1_headers);
 
  if(verbose>0)fprintf(stderr,"allocate intrace.  n1_traces=%d\n",n1_traces);
  intrace= sf_floatalloc(n1_traces);

  if(verbose>0)fprintf(stderr,"call list of keys\n");
 
  if(!(list_of_keys=sf_getnstring("key",&numkeys)))
    fprintf(stderr,"key not input\n");
  /*  List of header keys to monitor to determine when to break between 
      gathers.  A gather is a sequence of traces with the same value for
      all the header keys.  Stack summs traces in the gather, divides
      by the fold, and outputs the stack trace. */

  if(verbose>0)fprintf(stderr,"after sf_getnstring\n");

  if(list_of_keys==NULL)
    sf_error("The required parameter \"key\" was not found.");
  /* I wanted to use sf_getstrings, but it seems to want a colon seperated
     list of keys (eg key=offset:ep:fldr:cdp) and I wanted a comma seperated
     list of keys (eg key=offset:ep:fldr:cdp).
  numkeys=sf_getnumpars("key");
  if(numkeys==0)
    sf_error("The required parameter \"key\" was not found.");
  fprintf(stderr,"alloc list_of_keys numkeys=%d\n",numkeys);
  list_of_keys=(char**)sf_alloc(numkeys,sizeof(char*)); 
  sf_getstrings("key",list_of_keys,numkeys);
  */
  /* print the list of keys */
  if(verbose>1){
    fprintf(stderr,"numkeys=%d\n",numkeys);
    for(ikey=0; ikey<numkeys; ikey++){
      fprintf(stderr,"list_of_keys[%d]=%s\n",ikey,list_of_keys[ikey]);
    }
  }
  
  /* maybe I should add some validation that n1== n1_traces+n1_headers+2
     and the record length read in the second word is consistent with 
     n1.  */

  /**********************************************************/
  /* end code block for standard tah Trace And Header setup */
  /* continue with any sf_puthist this tah program calls to */
  /* add to the history file                                */
  /**********************************************************/

  /* put the history from the input file to the output */
  sf_fileflush(out,in);

  /********************************************************/
  /* continue initialization specific to this tah program */
  /********************************************************/

  /* segy_init gets the list header keys required by segykey function  */
  segy_init(n1_headers,in);
  indx_of_keys=sf_intalloc(numkeys);
  for (ikey=0; ikey<numkeys; ikey++){
    /* kls need to check each of these key names are in the segy header and
       make error message for invalid keys.  Of does segykey do this? NO, just
       segmentation fault. */
    indx_of_keys[ikey]=segykey(list_of_keys[ikey]);
  }
  /* get the mute parameters */
  if(NULL==(list_of_floats=sf_getnstring("xmute",&numxmute))){
    xmute=NULL;
    numxmute=0;
  } else {
    xmute=sf_floatalloc(numxmute);
    if(!sf_getfloats("xmute",xmute,numxmute))sf_error("unable to read xmute");
  }
  if(NULL==(list_of_floats=sf_getnstring("tmute",&numtmute))){
    tmute=NULL;
    numtmute=0;
  } else {
    tmute=sf_floatalloc(numtmute);
    if(!sf_getfloats("tmute",tmute,numtmute))sf_error("unable to read tmute");
  }
  if(numxmute!=numtmute)sf_error("bad mute parameters: numxmute!=numtmute");
  if(numxmute<=0) {
      ntaper=0;
      indx_of_offset=0;
      taper=NULL;
  } else {
    if(!sf_getint("ntaper",&ntaper))ntaper=12;
    /* \n
       length of the taper on the stack mute
    */
    taper=sf_floatalloc(ntaper);
    for(indx_time=0; indx_time<ntaper; indx_time++){
      float val_sin=sin((indx_time+1)*SF_PI/(2*ntaper));
      taper[indx_time]=val_sin*val_sin;
    }
    indx_of_offset=segykey("offset");
  }

  if (!sf_histfloat(in,"d1",&d1))
    sf_error("input data does not define d1");
  if (!sf_histfloat(in,"o1",&o1))
    sf_error("input data does not define o1");

  stktrace          = sf_floatalloc(n1_traces);
  stkheader         = sf_floatalloc(n1_headers);
  time_variant_fold = sf_floatalloc(n1_traces);

  /***************************/
  /* start trace loop        */
  /***************************/
  if(verbose>0)fprintf(stderr,"start trace loop\n");
 
  itrace=0;
  eof_get_tah=get_tah(intrace, fheader, n1_traces, n1_headers, in);
  fold=0;
  while (!eof_get_tah){
    if(verbose>1 && itrace<5)fprintf(stderr,"process the tah in sftahstack\n");
    /********************/
    /* process the tah. */
    /********************/
    /* this program stacks sequential traces with matching pkey.  If one of the 
       headers in pkey changes, the summed trace is divided by the time 
       variant fold and output.
    */
    if(fold==0){
      memcpy(stkheader,fheader,n1_headers*sizeof(int));
      for(indx_time=0; indx_time<n1_traces; indx_time++){
	time_variant_fold[indx_time]=0.0;
	stktrace[indx_time]=0.0;
      }
    }
    if(xmute==NULL)mute_start=o1;
    else{
      if(typehead == SF_INT)offset=((int  *)fheader)[indx_of_offset];
      else                  offset=((float*)fheader)[indx_of_offset];
      intlin(numxmute,xmute,tmute,
	     tmute[0],tmute[numxmute-1],1,
	     &offset,&mute_start);
      if(mute_start<o1)mute_start=o1;
    }
    imute_start=(int)(((mute_start-o1)/d1)+.5);
    if(0)fprintf(stderr,"imute_start=%d\n",imute_start);
    for(; imute_start<n1_traces && intrace[imute_start]==0;
	  imute_start++); /* increate imute_start to first non-zero sample */
    if(0)fprintf(stderr,"updated imute_start=%d\n",imute_start);
    for(indx_time=imute_start, indx_taper=0; 
	indx_time<imute_start+ntaper && indx_time<n1_traces; 
	indx_time++, indx_taper++){
      stktrace[indx_time]+=taper[indx_taper]*intrace[indx_time];
      time_variant_fold[indx_time]+=taper[indx_taper];
    }
    for(; indx_time<n1_traces; indx_time++){
      stktrace[indx_time]+=intrace[indx_time];
      time_variant_fold[indx_time]++;
    }

    fold++;
    eof_get_tah=get_tah(intrace, fheader, n1_traces, n1_headers, in);

    /* did any of the header keys in indx_of_keys change? */
    pkeychanged=false;
    if(itrace>0){
      for(ikey=0; ikey<numkeys; ikey++){
	if(typehead == SF_INT){
	  if(((int*)fheader  )[indx_of_keys[ikey]]!=
	     ((int*)stkheader)[indx_of_keys[ikey]]){
	    pkeychanged=true;
	    break;
	  }
	} else {
	  if(fheader[indx_of_keys[ikey]]!=stkheader[indx_of_keys[ikey]]){
	    pkeychanged=true;
	    break;
	  }
	}
      }
    }
    /* if one of the headers changes, apply fold recovery, output trace, and 
       set fold=0.  Fold=0 will initialize the stktrace to zero at top f loop*/
    if(pkeychanged){
      /***********************************/
      /* divide by the time variant fold */
      /***********************************/
      if(verbose>1)fprintf(stderr,"pkeychanged.  divide by fold\n");
      for(indx_time=0; indx_time<n1_traces; indx_time++){
	if(time_variant_fold[indx_time]<1.0)time_variant_fold[indx_time]=1.0;
	stktrace[indx_time]/=time_variant_fold[indx_time];
      }   
      /* kls set any headers? Maybe fold? offset? */
      /***************************/
      /* write trace and headers */
      /***************************/
      if(verbose>1)fprintf(stderr,"put_tah\n");
      put_tah(stktrace, stkheader, n1_traces, n1_headers, out);
      fold=0;
    }
    itrace++;
  }

  exit(0);
}
Example #12
0
VND *ptablemig(int nv, float *v, float etamin, float deta, int neta,
		float d, float vsvp, int np, char *file)
/***************************************************************************
	returns a VND table where dimension 0 is along k/(2*wmig) axis
	and dimension 1 is along v axis (note a=v/sqrt(1+2d)).

	The first element in dimension 0 will be dp, the mig slowness
	increment which corresponds to increments in tan(theta)/a. 
	Thereafter, the values will be

	factor = v/( a*cos(theta) )

	where p corresponds to (i-1)*dp and a is the vertical p-wave
	phase velocity.  A Stolt migration can use this factor to
	compute		

		wdmo = wmig*factor

	using k/(2*wmig) = tan(theta)/a to find the appropriate location
	in the table.
*****************************************************************************
int nv		number of input velocities
float v[]	array of input velocities
float etamin	Alkhalifah's minimum eta value
float deta	Alkhalifah's eta increment
int neta	number of eta values
float d	 Thomsen's delta
float vsvp      vs/vp ratio
int np		number of output slownesses
char *file	root name for temporary file to be created
***************************************************************************
Author: John Anderson (visitor to CSM from Mobil) Spring 1993
***************************************************************************/
{
	VND *vndvel;
	float a,b,dangle,angle,theta,pmax,dp,dscale;
	float vel[5];
	int nangle,iangle,ip;
	long iv,newnv,newnp,ieta;
	float *pin;
	float *vin;
	float *pout;
	float *vout;
	float e;
	char *fname;

	newnv=nv*neta;
	newnp=np;
	fname=VNDtempname(file);
	vndvel=V2Dop(2,125000,sizeof(float),
		fname,newnp,newnv);
	VNDfree(fname,"pmigtable: freeing fname");

	dscale=1./sqrt(1+2*d);
	nangle=10001;
	dangle = 89./(nangle-1);
	pin = (float *)VNDemalloc(nangle*sizeof(float),
			"sutifowler:ptable: allocating pin");
	vin = (float *)VNDemalloc(nangle*sizeof(float),
			"sutifowler:ptable: allocating vin");
	pout = (float *)VNDemalloc(np*sizeof(float),
			"sutifowler:ptable: allocating pout");
	vout = (float *)VNDemalloc(np*sizeof(float),
			"sutifowler:ptable: allocating vout");
	for(ieta=0;ieta<neta;ieta++) {
	    e= (etamin + ieta*deta)*(1+2*d)+d;
	    for(iv=0;iv<nv;iv++) {
		a=v[iv]*dscale;	/* vertical p-wave phase velocity */
		b=vsvp*a;	/* vertical s-wave phase velocity */
		for(iangle=0;iangle<nangle;iangle++) {
			angle=iangle*dangle;
			theta=angle*PI/180.;
			vget(a,b,e,d,theta,vel);
			pin[iangle]=tan(theta)/a;
			vin[iangle]=vel[0]/( a*cos(theta) );
		}
		pmax=pin[nangle-1];
		dp=pmax/(np-2);
		vout[0]=dp;
		for(ip=0;ip<(np-1);ip++) pout[ip]=ip*dp;
		intlin(nangle,pin,vin,vin[0],vin[iangle-1],np-1,pout,&vout[1]);
		V2Dw0(vndvel,iv+ieta*nv,(char *)vout,101);
	    }
	}
	VNDfree(pin,"ptablemig: freeing pin");
	VNDfree(vin,"ptablemig: freeing vin");
	VNDfree(pout,"ptablemig: freeing pout");
	VNDfree(vout,"ptablemig: freeing vout");
	return (vndvel);
}
Example #13
0
VND *ptabledmo(int nv, float *v, float etamin, float deta, int neta,
	float d, float vsvp, int np, float dp, float dp2, char *file)
/*************************************************************************
	returns a VND table where dimension 0 is along v axis
	and dimension 1 is along p axis providing 

	1./(vnmo(p)*vnmo(p)*dp2)

	which will be the desired index in the stacking velocity
	analysis table for a given output velocity index and p
**************************************************************************
int nv		number of input velocities
float v[]	array of input velocities
float etamin	Alkhalifah's minimum eta value
float deta	Alkhalifah's eta increment
int neta	number of eta values
float d		Thomsen's delta
float vsvp	vs/vp ratio
int np		number of output slownesses
float dp	output slowness increment
float dp2	increment in slowness squared used for stacking
		velocity analysis
char *file	root name for temporary file to be created
***************************************************************************
Author: John Anderson (visitor to CSM from Mobil) Spring 1993
***************************************************************************/
{
	VND *vndvel;
	float a,b,dangle,angle,theta,dscale;
	float vel[5];
	int nangle,iangle,ip;
	long iv,newnv,newnp,ieta;
	float *pin;
	float *vin;
	float *pout;
	float *vout;
	float e;
	char *fname;

	newnv=nv*neta;
	newnp=np;
	fname=VNDtempname(file);
	dscale=1./sqrt(1+2*d);
	vndvel=V2Dop(2,125000,sizeof(float),
		fname,newnv,newnp);
	VNDfree(fname,"ptabledmo: freeing fname");

	nangle=10001;
	dangle = 89./(nangle-1);
	pin = (float *)VNDemalloc(nangle*sizeof(float),
			"sutifowler:ptable: allocating pin");
	vin = (float *)VNDemalloc(nangle*sizeof(float),
			"sutifowler:ptable: allocating vin");
	pout = (float *)VNDemalloc(np*sizeof(float),
			"sutifowler:ptable: allocating pout");
	vout = (float *)VNDemalloc(np*sizeof(float),
			"sutifowler:ptable: allocating vout");
	for(ip=0;ip<np;ip++) pout[ip]=ip*dp;
	for(ieta=0;ieta<neta;ieta++) {
	    e= (etamin + ieta*deta)*(1+2*d)+d;
	    for(iv=0;iv<nv;iv++) {
		a=v[iv]*dscale;	/* vertical p-wave phase velocity */
		b=vsvp*a;	/* vertical s-wave phase velocity */
		for(iangle=0;iangle<nangle;iangle++) {
			angle=iangle*dangle;
			theta=angle*PI/180.;
			vget(a,b,e,d,theta,vel);
			pin[iangle]=vel[4];
			vin[iangle]=vel[3];
		}
		intlin(nangle,pin,vin,vin[0],vin[nangle-1],np,pout,vout);
		for(ip=0;ip<np;ip++)
			vout[ip]=1./(vout[ip]*vout[ip]*dp2);
		V2Dw1(vndvel,iv+ieta*nv,(char *)vout,101);
	    }
	}
	VNDfree(pin,"ptabledmo: freeing pin");
	VNDfree(vin,"ptabledmo: freeing vin");
	VNDfree(pout,"ptabledmo: freeing pout");
	VNDfree(vout,"ptabledmo: freeing vout");
	return (vndvel);
}
Example #14
0
int
main(int argc, char **argv)
{
	int nz;		/* numer of depth samples */
	int iz;		/* counter */
	int nt;		/* number of time samples */

	int nzpar;	/* number of getparred depth values for velocities */
	int nvpar;	/* number of getparred velocity values */
	int izpar;	/* counter */

	int verbose;	/* verbose flag, =0 silent, =1 chatty */

	float dz=0.0;	/* depth sampling interval */
	float fz=0.0;	/* first depth value */
	float dt=0.0;	/* time sampling interval for velocities */
	float ft=0.0;	/* first time value */
	float z=0.0;	/* depth values for times */
	float vmin=0.0;	/* minimum velocity */
	float vmax=0.0;	/* maximum velocity */

	float *zpar=NULL;	/* values of z getparred */
	float *vpar=NULL;	/* values of v getparred */
	float *vz=NULL;		/* v(z) velocity as a function of z */
	float *zt=NULL;		/* z(t) depth as a function of t */
	float *temp=NULL;	/* temporary storage array */
	char *vfile="";		/* name of the velocity file */

	/* hook up getpar */
	initargs(argc,argv);
	requestdoc(1);

	/* get time sampling from first header */
	if (!gettr(&tr)) err("can't get first trace");
	nz = tr.ns;

	/* get depth sampling */
	if (!getparfloat("dz",&dz)) dz = ((float) tr.d1);

	/* determine velocity function v(t) */
	vz = ealloc1float(nz);
	if (!getparstring("vfile",&vfile)) {
		nzpar = countparval("z");
		if (nzpar==0) nzpar = 1;
		zpar = ealloc1float(nzpar);
		if (!getparfloat("z",zpar)) zpar[0] = 0.0;
		nvpar = countparval("v");
		if (nvpar==0) nvpar = 1;
		if (nvpar!=nzpar)err("number of t and v values must be equal");
		vpar = ealloc1float(nvpar);
		if (!getparfloat("v",vpar)) vpar[0] = 1500.0;
		for (izpar=1; izpar<nzpar; ++izpar)
			if (zpar[izpar]<=zpar[izpar-1])
				err("zpar must increase monotonically");
		for (iz=0,z=0.0; iz<nz; ++iz,z+=dz)
			intlin(nzpar,zpar,vpar,vpar[0],vpar[nzpar-1],
				1,&z,&vz[iz]);
	} else { /* read from a file */
		if (fread(vz,sizeof(float),nz,fopen(vfile,"r"))!=nz)
			err("cannot read %d velocities from file %s",nz,vfile);
	}

	/* determine minimum and maximum velocities */
	for (iz=1,vmin=vmax=vz[0]; iz<nz; ++iz) {
		if (vz[iz]<vmin) vmin = vz[iz];
		if (vz[iz]>vmax) vmax = vz[iz];
	}

	/* get parameters */
	if (!getparfloat("dt",&dt)) dt = 2.0*dz/vmin;
	if (!getparfloat("ft",&ft)) ft = 2.0*ft/vz[0];
	if (!getparint("nt",&nt)) nt = 1+(nz-1)*dz*2.0/(dt*vmax);
	if (!getparint("verbose",&verbose)) verbose = 0;
	CHECK_NT("nt",nt);

	/* if requested, print time sampling, etc */
	if (verbose) {
		warn("Input:");
		warn("\tnumber of depth samples = %d",nz);
		warn("\tdepth sampling interval = %g",dz);
		warn("\tfirst depth sample = %g",fz);
		warn("Output:");
		warn("\tnumber of time samples = %d",nt);
		warn("\ttime sampling interval = %g",dt);
		warn("\tfirst time sample = %g",ft);
	}

	/* allocate workspace */
	zt = ealloc1float(nt);
	temp = ealloc1float(nz);

	/* make z(t) function */
	makezt(nz,dz,fz,vz,nt,dt,ft,zt);
	
	/* loop over traces */
	do {
		/* update header fields */
		tr.trid = TREAL;
		tr.ns = nt;
		tr.dt = dt*1000000.0;
		tr.f1 = ft;
		tr.d1 = 0.0;

		/* resample */
		memcpy((void *) temp, (const void *) tr.data,nz*sizeof(float));
		ints8r(nz,dz,fz,temp,0.0,0.0,nt,zt,tr.data);

		/* put this trace before getting another */
		puttr(&tr);

	} while(gettr(&tr));

	return(CWP_Exit());
}
Example #15
0
int
main(int argc, char **argv)
{
	int nt;			/* number of points on input trace	*/
	float dt;		/* sample spacing			*/
	float tmin;		/* time of first sample			*/
	float *vt;		/* velocity function			*/
	float *vrms;		/* rms velocity picks			*/
	float *trms;		/* times corresponding to vrms picks	*/
	cwp_String vfile="";	/* binary file giving vrms(t)		*/
	float *divcor;		/* divergence correction function	*/
	float denom=1.0; 	/* vrms to divide by 			*/

	/* Hook up getpar */
	initargs(argc, argv);
	requestdoc(1);


	/* Get information from the first header */
	if (!gettr(&tr)) err("can't get first trace");
	nt = tr.ns;
	dt = ((double) tr.dt)/1000000.0;
	tmin = tr.delrt/1000.0;


	/* Determine velocity function v(t) */
	vt = ealloc1float(nt);
	if (!getparstring("vfile", &vfile)) {
		int ntrms = countparval("trms");
		int nvrms = countparval("vrms");
		int npar;
		register int it, itrms;

		if (nvrms != ntrms)
			err("number of trms and vrms must be equal");

		if (!ntrms)  ntrms = 2;  /* default case */
		trms = ealloc1float(ntrms);
		if (!(npar = getparfloat("trms", trms))) {
			trms[0] = 0.0;
			trms[1] = dt;
		}
		if (npar == 1) trms[1] = trms[0] + dt; /* const vel case */
		
		if (!nvrms)  nvrms = 2;  /* default case */
		vrms = ealloc1float(nvrms);
		if (!(npar = getparfloat("vrms", vrms))) {
			vrms[0] = 1500.0;
			vrms[1] = 1500.0;
		}
		if (npar == 1) vrms[1] = vrms[0];  /* const vel case */

		for (itrms = 1; itrms < ntrms; ++itrms)
			if (trms[itrms] <= trms[itrms-1])
				err("trms must increase monotonically");

		for (it = 0; it < nt; ++it) {
			float t = tmin + it*dt;
			intlin(ntrms,trms,vrms,vrms[0],vrms[ntrms-1],
				1,&t,&vt[it]);
		}
		denom = trms[1]*vrms[1]*vrms[1];
		
	} else {  /* user gave a vfile */
		FILE *fp = efopen(vfile, "r");
		
		if (nt != efread(vt, FSIZE, nt, fp)) {
			err("cannot read %d velocities from file %s",
				nt, vfile);
		} else denom = (tmin + dt)*vt[1]*vt[1];
	}

	/* Form divergence correction vector */
	{ register int it;
	  
	  divcor = ealloc1float(nt);
	  for (it = 0; it < nt; ++it) {
	  	float t = tmin + it*dt;
		divcor[it] = t*vt[it]*vt[it] / denom;
	  }
	}
   
	  
	/* Main loop over traces */
	do {
		register int it;

	  	for (it = 0; it < nt; ++it)  tr.data[it] *=  divcor[it];
		puttr(&tr);
	} while (gettr(&tr));

	return(CWP_Exit());
}
Example #16
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);
}
Example #17
0
int main(int argc, char* argv[])
{
  int verbose;
  sf_file in=NULL, out=NULL;
  int n1_traces;
  int n1_headers;

  char* header_format=NULL;
  sf_datatype typehead;
  /* kls do I need to add this?  sf_datatype typein; */
  float* fheader=NULL;
  float* intrace=NULL;
  float o1;
  float d1;
  int indx_offset;
  float* local_sloth=NULL;
  float v0;
  int indx_time;
  float offset;
  float offset2;
  float* r_index_tx_of_it0=NULL;
  float* r_index_t0_of_itx=NULL;
  int start_indx_nmo;
  int start_indx_nmo_tx;
  float* outtrace=NULL;
  float itrace=0;
  float nmostretch;
  char* offsetname;
  float lmute;
  bool inv;
  /******************************************************/
  /* code block for standard tah Trace And Header setup */
  /******************************************************/

  sf_init (argc,argv);

  /*****************************/
  /* initialize verbose switch */
  /*****************************/
  if(!sf_getint("verbose",&verbose))verbose=1;
  /* \n
     flag to control amount of print
     0 terse, 1 informative, 2 chatty, 3 debug
  */
  sf_warning("verbose=%d",verbose);
 
  /******************************************/
  /* input and output data are stdin/stdout */
  /******************************************/

  if(verbose>0)fprintf(stderr,"read in file name\n");  
  in = sf_input ("in");

  if(verbose>0)fprintf(stderr,"read out file name\n");
  out = sf_output ("out");

  if (!sf_histint(in,"n1_traces",&n1_traces))
    sf_error("input data not define n1_traces");
  if (!sf_histint(in,"n1_headers",&n1_headers)) 
    sf_error("input data does not define n1_headers");

  header_format=sf_histstring(in,"header_format");
  if(strcmp (header_format,"native_int")==0) typehead=SF_INT;
  else                                       typehead=SF_FLOAT;

  if(verbose>0)fprintf(stderr,"allocate headers.  n1_headers=%d\n",n1_headers);
  fheader = sf_floatalloc(n1_headers);
 
  if(verbose>0)fprintf(stderr,"allocate intrace.  n1_traces=%d\n",n1_traces);
  intrace= sf_floatalloc(n1_traces);

  /* maybe I should add some validation that n1== n1_traces+n1_headers+2
     and the record length read in the second word is consistent with 
     n1.  */
  /**********************************************************/
  /* end code block for standard tah Trace And Header setup */
  /* continue with any sf_puthist this tah program calls to */
  /* add to the history file                                */
  /**********************************************************/

  /* put the history from the input file to the output */
  sf_fileflush(out,in);


  /********************************************************/
  /* continue initialization specific to this tah program */
  /********************************************************/
  if (!sf_histfloat(in,"d1",&d1))
    sf_error("input data does not define d1");
  if (!sf_histfloat(in,"o1",&o1))
    sf_error("input data does not define o1");
  /* Kls should read label1 and verify it is time  
  if (!sf_histstring(in,"label1",&label1))
    sf_error("input data not define label1");
  */

  /* segy_init gets the list header keys required by segykey function  */
  segy_init(n1_headers,in);
  /* get index to keys I will be using */
  if(NULL==(offsetname=sf_getstring("offset")))offsetname="offset";
  /* name of the header key to use for offset (usually just offset) */
  indx_offset=segykey(offsetname);
  /* kls what other header keys do I use?  inline? xline? cdp? */

  /* get the parameter for the maximum nmo stretch. */
  if (!sf_getfloat("str",&nmostretch)) nmostretch=0.5;
  /* maximum stretch allowed */

  if (!sf_getfloat("lmute",&lmute)) lmute=12.*d1; 
  /* length of the mute zone in seconds */
  if(verbose>0)  fprintf(stderr,"lmute=%f seconds.\n",lmute);
  lmute/=d1;
  if(!sf_getbool("inv",&inv)) inv=false;
  /* if y, do inverse nmo.  Otherwise forward nmo */ 
   
  if(verbose>0){
    if(inv)fprintf(stderr,"inv=true\n");
    else fprintf(stderr,"inv=false\n");
  }
   
  /* set up velocity function ( really (1/v)**2, sloth */
  local_sloth=sf_floatalloc(n1_traces);
  /* just constant velocity today */
  if(1==1){
    char** list_of_floats;
    float* vnmo;
    float* tnmo;
    int numvnmo;
    int numtnmo;
    float t0;

    if(verbose>1)fprintf(stderr,"read vnmo/tnmo\n");
    /* use this fundtion to find out number of velocities and time 
       input in vnmo and tnmo */
    list_of_floats=sf_getnstring("vnmo",&numvnmo);
    /* list of NMO velocities for the time in tnmo */
    if(verbose>1){
      int i;
      fprintf(stderr,"numvnmo=%d\n",numvnmo);
      for (i=0; i<numvnmo; i++){
	fprintf(stderr,"velocities=%s\n",list_of_floats[i]);
      }
    }
    /* should free this list of strings, but that is only a little memory */\
    list_of_floats=sf_getnstring("tnmo",&numtnmo);
    /* NMO times for the vnmo velocities. */
    if(verbose>1){
      int i;
      for (i=0; i<numtnmo; i++){
	fprintf(stderr,"times=%s\n",list_of_floats[i]);
      }
    }
    if(numvnmo!=numtnmo){
      sf_error("number vnmo floats=%d != number tnmo floats=%d",
	       numvnmo,numtnmo);
    }
    if(numvnmo==0)sf_error("vnmo parameter is required");
    vnmo=sf_floatalloc(numvnmo);
    tnmo=sf_floatalloc(numtnmo);
    if(verbose>1)fprintf(stderr,"sf_getfloats(vnmo)");
    if (!sf_getfloats("vnmo",vnmo,numvnmo))
      sf_error("unable to read vnmo");
    /* list of NMO velocities for the tnmo times. */
    if(verbose>1)fprintf(stderr,"sf_getfloats(tnmo)");
    if (!sf_getfloats("tnmo",tnmo,numtnmo))
      sf_error("unable to read tnmo");
    /* list of NMO times for the vnmo velocities. */
    if(verbose>1){
      for(indx_time=0; indx_time<numvnmo; indx_time++){
	fprintf(stderr,"indx=%d, vnmo=%f, tnmo=%f\n",
		indx_time,vnmo[indx_time],tnmo[indx_time]);
      }
    }
    if(verbose>1)fprintf(stderr,"interpolate the velocity\n");
    for(indx_time=0; indx_time<n1_traces; indx_time++){
      t0=indx_time*d1+o1;
      intlin(numtnmo,tnmo,vnmo,vnmo[0],vnmo[numvnmo-1],1,&t0,&v0);
      local_sloth[indx_time]=1.0/(v0*v0);
    }    
  } 
  /* kls
     previous if(1==1) clause if for it no input velocity file
     need to add else { set up the input velocity file (ie open the file(
     inside the trace loop need to get iline and xline form trace heder
     and use that to read the velocity at (iline,xline) into local_sloth
     then compute local_sloth as 1/(v*v)

     will need to get input velocity shape:
       if (!sf_histint(invelocity,"n1",&n1_velocity))
          sf_error("input velocity file does not define n1");
     test n1_velocity!=n1_trace error
     and do the same for d1, o2, d2, etc 
   */

  if(verbose>0)fprintf(stderr,"allocate arrays for the trace loop\n");
  r_index_tx_of_it0=sf_floatalloc(n1_traces);
  r_index_t0_of_itx=sf_floatalloc(n1_traces);
  outtrace         =sf_floatalloc(n1_traces);
  

  /***************************/
  /* start trace loop        */
  /***************************/
  if(verbose>0)fprintf(stderr,"start trace loop\n");
  while (0==get_tah(intrace, fheader, n1_traces, n1_headers, in)){
    if(verbose>1)fprintf(stderr,"process the tah in sftahnmo\n");
    /********************/
    /* process the tah. */
    /********************/
    /* this program applies moveout */
    /* kls this should be only be done when velocity (local_sloth) 
       or offset changes */
    if(typehead == SF_INT){   
      /* just cast the header to int so the print works */
      offset=((int*)fheader)[indx_offset];
    } else {
      offset=       fheader [indx_offset];
    }
    offset2=offset*offset;
    for(indx_time=0; indx_time<n1_traces; indx_time++){
      float tx, t0;
      t0=indx_time*d1+o1;
      tx=sqrt(t0*t0+offset2*local_sloth[indx_time]);
      r_index_tx_of_it0[indx_time]=(tx-o1)/d1;
      if(itrace==0 && verbose>4){
	fprintf(stderr,"indx_time=%d, tx=%f, sloth=%g, offset=%f, t0=%f\n",
		        indx_time   , tx   , local_sloth[indx_time]  ,
                                                       offset   , t0);
      }
    }
    /* kls nmo start time should depend on the nmo stretch limit.
       Find the excessive stretch closest to the bottom of the trace.  This 
       is the last time nmstrewtch is violated.  It is OK to apply nmo
       to the rest of the trace. */
    for (start_indx_nmo=n1_traces-1; start_indx_nmo>1; start_indx_nmo--){
      /* pfrintf(stderr,"r_indx[it]=%f, rindx */
      if((r_index_tx_of_it0[start_indx_nmo  ]-
	  r_index_tx_of_it0[start_indx_nmo-1])  <nmostretch) break;
    }
    if(inv){
      start_indx_nmo_tx = 1.0+r_index_tx_of_it0[start_indx_nmo];
      if(start_indx_nmo_tx>n1_traces-2)start_indx_nmo_tx = n1_traces-2;
      /* compute r_index_t0_of_itx from r_index_tx_of_it0 */
      yxtoxy(n1_traces-start_indx_nmo,1.0, start_indx_nmo,
	     &r_index_tx_of_it0[start_indx_nmo],
 
	     n1_traces-start_indx_nmo_tx,1.0, start_indx_nmo_tx,
	     -1,n1_traces,&r_index_t0_of_itx[start_indx_nmo_tx]);
    }
    /* kls inverse nmo? will need more code */
    /* do nmo via 8-point sinc interpolation */
    /* void ints8r (int nxin, float dxin, float fxin,      
                    float yin[], float yinl, float yinr, 
		    int nxout, float xout[], 
		    float yout[]) */
    if(!inv){
      ints8r(n1_traces,1.0,0,
	     intrace,0.0,0.0,
	     n1_traces-start_indx_nmo,&r_index_tx_of_it0[start_indx_nmo],
	     &outtrace[start_indx_nmo]);
      /* zero above the start time */
      for(indx_time=0; indx_time<start_indx_nmo; indx_time++){
	outtrace[indx_time]=0.0;
      }
      /* apply linear ramp kls */
      for (indx_time=start_indx_nmo; 
	   indx_time<start_indx_nmo+lmute && indx_time<n1_traces;
	   indx_time++){
	outtrace[indx_time] *= (float)(indx_time-start_indx_nmo+1)/(float)lmute;
      }
    }else{
      ints8r(n1_traces,1.0,0,
	     intrace,0.0,0.0,
	     n1_traces-start_indx_nmo_tx,&r_index_t0_of_itx[start_indx_nmo_tx],
	     &outtrace[start_indx_nmo_tx]);      
      /* zero above the start time */
      for(indx_time=0; indx_time<start_indx_nmo_tx; indx_time++){
	outtrace[indx_time]=0.0;
      }
    }
    /***************************/
    /* write trace and headers */
    /***************************/
    put_tah(outtrace, fheader, n1_traces, n1_headers, out);
    itrace++;
  }
  
  exit(0);
}