Beispiel #1
0
void do_minphdec(float *tr,int nt, float *filter,int fnl,int fnr,float prw)
{

	float *rtr;
	float *rtx;     
	complex *f;
	complex *w;
	complex a;
	int iamp;
	float amp;
	float ampm=-1.0e+20;
	float amps;
	float *am;
	float *ph;	
	float mean=0.0;
	float sum=0.0;

	int nfftc; 
        int nf;    
	int i,j;			/* counter */
	float snfftc;
	

	/* Set up pfa fft */
	nfftc = npfao(nt,LOOKFAC*nt); 
        if (nfftc >= SU_NFLTS || nfftc >= PFA_MAX)
                 err("Padded nt=%d--too big", nfftc);
        nf = nfftc/2 + 1;
	snfftc=1.0/nfftc;

        rtr = ealloc1float(nfftc);
        rtx = ealloc1float(nf);
	f = ealloc1complex(nfftc);
	w = ealloc1complex(nfftc);
	am = ealloc1float(nf);
	ph = ealloc1float(nf);
        
	/* clean the arrays */
	memset( (void *) w, (int) '\0', nfftc*sizeof(complex));
        memset( (void *) rtr, (int) '\0', nfftc*FSIZE);
	
	/* Cross correlation */
	xcor(nt,0,tr,nt,0,tr,nf,0,rtr);

        /* FFT */
	pfarc(1, nfftc,rtr,w);

	/* stabilize */
	for(i=0;i<nf;i++) {
		am[i] += am[i]*prw;
	}
	
	/* Normalize */
	for(i=0;i<nf;i++) {
		a=w[i];
		am[i]= sqrt(a.r*a.r+a.i*a.i);
		sum += am[i];
		if(am[i]!=0) ph[i] = atan2(a.i,a.r);
		else ph[i]=0;
	}
	sum *=	1.0/nf;
	sum = 1.0/sum;
	sscal(nf,sum,am,1);
	
	/* Smooth the apmlitude spectra  */
	if(fnl!=0) conv (fnl+fnr+1,-fnl,filter,nf,0,am,nf,0,am);

	fprintf(stderr," %f\n",sum);	
	
	for(i=0;i<nf;i++) {
		w[i].r = am[i]*cos(ph[i]);
		w[i].i = am[i]*sin(ph[i]);
	}
	for(i=nf,j=nf-1;i<nfftc;i++,j--) {
		w[i].r = am[j]*cos(ph[j]);
		w[i].i = am[j]*sin(ph[j]);
	}
		
	/* log spectra */
	for (i = 0; i < nfftc; ++i)  w[i] =
		crmul(clog(cmul(w[i],conjg(w[i]))),0.5);

	/* Hilbert transform */
	pfacc(-1,nfftc,w);
        for (i=0; i<nfftc; ++i) {
		w[i].r *=snfftc;
		w[i].i *=snfftc;
	}
	for(i=1;i<nfftc/2;i++) w[i] = cadd(w[i],w[i]);
	for(i=nfftc/2;i<nfftc;i++) w[i] = cmplx(0,0);
	pfacc(1,nfftc,w);
	/* end of Hilbert transform */
	
	/* exponentiate */
	for(i=0;i<nfftc;i++) w[i] = cexp(w[i]);
	
	/* inverse filter */
	for(i=0;i<nfftc;i++) f[i] = cdiv(cmplx(1.0,0),w[i]);
	
	/* Load trace into tr (zero-padded) */
        memset( (void *) w, (int) '\0',nfftc*sizeof(complex));
	for(i=0;i<nt;i++) w[i].r = tr[i];

	/* Trace to frequency domain */
	pfacc(1,nfftc,w);
      
      	/* apply filter */
        for(i=0;i<nfftc;i++) w[i] = cmul(w[i],f[i]);
             
        /* Time domain */
        pfacr(-1, nfftc,w,rtr);
	for(i=0;i<nt;i++) rtr[i] *=snfftc;
	
	memcpy( (void *) tr, (const void *) rtr, nt*FSIZE);				
	
	free1float(rtr);
	free1float(am);
	free1float(ph);
	free1complex(f);
	free1complex(w);
}	
Beispiel #2
0
/**************** end self doc ********************************/


static void cvstack(VND *vnda, VND *vnd, int icmp, int noff, float *off,
		float *mute, int lmute, int nv, float *p2,
		float dt, float dtout);
static void vget( float a, float b, float e, float d,
		float theta, float *vel);
VND *ptabledmo(int nv, float *v, float etamin, float deta, int neta,
		float d, float vsvp, int np, float dp, float dp2, char *file);
VND *ptablemig(int nv, float *v, float etamin, float deta,
		int neta, float d, float vsvp, int np, char *file);
static void taper (int lxtaper, int lbtaper,
		int nx, int ix, int nt, float *trace);

segy tr;	/* input and output SEGY data */
FILE *fpl;	/* file pointer for print listing */
int main(int argc, char **argv)
{
	VND *vnd=NULL;	/* big file holding data, all cmps, all etas, all velocities */
	VND *vnda=NULL;	/* holds one input cmp gather */
	VND *vndb=NULL;	/* holds (w,v) for one k component */
	VND *vndvnmo=NULL;	/* holds (vnmo,p) table for ti dmo */
	VND *vndvphase=NULL;	/* holds (vphase,p) table for ti Stolt migration */
	long N[2];	/* holds number of values in each dimension for VND opens */
	long key[2];	/* holds key in each dimension for VND i/o */
	char **dir=NULL; /* could hold list of directories where to put VND temp files */
	char *file;	/* root name for temporary files */
	char *printfile; /* name of file for printout */
	complex *crt;
	complex *ctemp;
	complex czero;
	float *rt;
	char *ccrt;
	char *fname;
	
	float etamin;	/* minimum eta scan to compute */
	float etamax;	/* maximum eta scan to compute */
	float deta;	/* increment in eta to compute for eta scan */
	float dx;	/* cmp spatial sampling interval */
	float dk;	/* wavenumber increment */
	float dv;	/* velocity increment */
	float vmin;	/* minimum output velocity */
	float vmax;	/* maximum output velocity */
	float dt;	/* input sample rate in seconds */
	float dtout;	/* output sample rate in seconds */
	float *mute;	/* array of mute times for this cmp */
	float *off;	/* array of offsets for this cmp */
	float *v;	/* array of output velocities */
	float *p2stack;	/* array of stacking 1/(v*v) */
	float *rindex;	/* array of interpolation indices */
	float dp2=0.0;	/* increment in slowness squared for input cvstacks */
	float scale;	/* used for trace scale factor */
	float p;	/* horizontal slowness */
	float p2;	/* p*p */
	float v2;	/* velocity squared */
	float ak;	/* horizontal wavenumber */
	float dw;	/* angular frequency increment */
	float *w;	/* array holding w values for Fowler */
	float factor;	/* scale factor */
	float d;	/* Thomsen's delta */
	float vsvp;	/* vs/vp ratio */
	float dp;	/* increment of slowness values in vndvnmo table */
	float rp;	/* real valued index in p */
	float wgt;	/* weight for linear interpolation */
	float fmax;	/* maximum frequency to use for antialias mute */
	float salias;	/* fraction of frequencies to be within sloth antialias limit */
	float dpm;	/* slowness increment in TI migration table */
	float fw;	/* first w in Stolt data table */
	float vminstack;/* only used if reading precomputed cvstacks, minimum stacking vel */

	int neta;	/* number of eta scans to compute */
	int ichoose;	/* defines type of processing to do */
	int ncmps;	/* number of input and output cmps */
	int nv;		/* number of output velocity panels to generate */
	int nvstack;	/* number of cvstack panels to generate */
	int ntpad;	/* number of time samples to padd to avoid wraparound */
	int nxpad;	/* number of traces to padd to avoid wraparound */
	int lmute;	/* number of samples to taper mute */
	int lbtaper;	/* length of bottom time taper in ms */
	int lstaper;	/* length of side taper in traces */
	int mxfold;	/* maximum allowed number of input offsets/cmp */
	int icmp;	/* cmp index */
	int ntfft;	/* length of temporal fft for Fowler */
	int ntffts;	/* length of temporal fft for Stolt */
	int nxfft;	/* length of spatial fft */
	int ntfftny;	/* count of freq to nyquist */
	int nxfftny;	/* count of wavenumbers to nyquist */
	int nmax;	/* used to compute max number of samples for array allocation */
	int oldcmp;	/* current cdp header value */
	int noff;	/* number of offsets */
	int k;		/* wavenumber index */
	int iwmin;	/* minimum freq index */
	int TI;		/* 0 for isotropic, 1 for transversely isotropic */
	long it;	/* time index */
	long iw;	/* index for angular frequency */
	long nt;	/* number of input time samples */
	long ntout;	/* number of output time samples */
	long iv;	/* velocity index */
	long ip;	/* slowness index */
	long ieta;
	int nonhyp;	/* flag equals 1 if do mute to avoid non-hyperbolic events */
	int getcvstacks;/* flag equals 1 if input cvstacks precomputed */
	int ngroup;	/* number of traces per vel anal group */
	int ndir;	/* number of user specified directories for temp files */

/******************************************************************************/
/* 	input parameters, allocate buffers, and define reusable constants     */
/******************************************************************************/
	initargs(argc, argv);
	requestdoc(1);

	/* get first trace and extract critical info from header */
	if(!gettr(&tr)) err("Can't get first trace \n");
	nt=tr.ns;
	dt=0.000001*tr.dt;
	oldcmp=tr.cdp;

	if (!getparstring("printfile",&printfile)) printfile=NULL;
	if (printfile==NULL) {
		fpl=stderr;
	}else{
		fpl=fopen(printfile,"w");
	}

	if (!getparfloat("salias",&salias)) salias=0.8;
 	if(salias>1.0) salias=1.0;
	if (!getparfloat("dtout",&dtout)) dtout=1.5*dt;
	ntout=1+nt*dt/dtout;
	if (!getparint("getcvstacks",&getcvstacks)) getcvstacks=0;
	if(getcvstacks) {
		dtout=dt;
		ntout=nt;
	}
	fmax=salias*0.5/dtout;
	fprintf(fpl,"sutifowler: ntin=%ld dtin=%f\n",nt,dt);
	fprintf(fpl,"sutifowler: ntout=%ld dtout=%f\n",ntout,dtout);
	if (!getparstring("file",&file)) file="sutifowler";
	if (!getparfloat("dx",&dx)) dx=25.;
	if (!getparfloat("vmin",&vmin)) vmin=1500.;
	if (!getparfloat("vmax",&vmax)) vmax=8000.;
	if (!getparfloat("vminstack",&vminstack)) vminstack=vmin;
	if (!getparfloat("d",&d)) d=0.0;
	if (!getparfloat("etamin",&etamin)) etamin=0.0;
	if (!getparfloat("etamax",&etamax)) etamax=0.5;
	if (!getparfloat("vsvp",&vsvp)) vsvp=0.5;
	if (!getparint("neta", &neta)) neta = 1;
	if (fabs(etamax-etamin)<1.0e-7) neta = 1;
	if (neta < 1) neta = 1;
	if (!getparint("choose", &ichoose)) ichoose = 1;
	if (!getparint("ncdps", &ncmps)) err("sutifowler: must enter ncdps");
	if (!getparint("nv", &nv)) nv = 75;
	if (!getparint("nvstack", &nvstack)) nvstack = 180;
	if (!getparint("ntpad", &ntpad)) ntpad = 0.1*ntout;
	if (!getparint("nxpad", &nxpad)) nxpad = 0;
	if (!getparint("lmute", &lmute)) lmute = 24;
	lmute=1 + 0.001*lmute/dtout;
	if (!getparint("lbtaper", &lbtaper)) lbtaper = 0;
	if (!getparint("lstaper", &lstaper)) lstaper = 0;
	if (!getparint("mxfold", &mxfold)) mxfold = 120;
	if (!getparint("nonhyp",&nonhyp)) nonhyp=1.;
	if (!getparint("ngroup", &ngroup)) ngroup = 20;
	ndir = countparname("p");
	if(ndir==0) {
		ndir=-1;
	}else{
		dir = (char **)VNDemalloc(ndir*sizeof(char *),"dir");
		for(k=0;k<ndir;k++) {
			it=getnparstring(k+1,"p",&dir[k]);
		}
	}
	lbtaper=lbtaper/(1000.*dt);
	TI=0;
	if(fabs(d)>0. || fabs(etamin)>0 || neta>1 ) TI=1;
	if(TI) fprintf(fpl,"sutifowler: operation in TI mode\n");
	deta = 0.;
	if(neta>1) deta=(etamax-etamin)/(neta-1);
	dp=1./(vmin*(NP-5));
	if(TI) dp=dp*sqrt(1.+2.*fabs(etamin));
	if(ichoose>2) nvstack=nv;
	if(ichoose==1 || ichoose==2 || ichoose==3) {
		ntfft=ntout+ntpad;
	}else{
		ntfft=1;
	}
	if(ichoose==1 || ichoose==3) {
		ntffts=2*ntout/0.6;
	}else{
		ntffts=1;
	}
	ntfft=npfao(ntfft,2*ntfft);
	ntffts=npfao(ntffts,2*ntffts);
	dw=2.*PI/(ntfft*dtout);
	nxfft=npfar(ncmps+nxpad);
	dk=2.*PI/(nxfft*dx);
	fprintf(fpl,"sutifowler: ntfft=%d ntffts=%d nxfft=%d\n",ntfft,ntffts,nxfft);
	czero.r=czero.i=0.;
	scale=1.;
	if(ichoose<5) scale=1./(nxfft);
	if(ichoose==1 || ichoose==2 ) scale*=1./ntfft;
	if(ichoose==1 || ichoose==3 ) scale*=1./ntffts;
	nxfftny = nxfft/2 + 1;
	ntfftny = ntfft/2 + 1;
	nmax = nxfftny;
	if(ntfft > nmax) nmax=ntfft;
	if((NP/2+1)>nmax) nmax=(NP/2+1);
	if(nvstack>nmax) nmax=nvstack;
	if(nv*neta>nmax) nmax=nv*neta;
	ctemp = (complex *)VNDemalloc(nmax*sizeof(complex),"allocating ctemp");
	rindex=(float *)VNDemalloc(nmax*sizeof(float),"allocating rindex");
	if(ntffts > nmax) nmax=ntffts;
	crt = (complex *)VNDemalloc(nmax*sizeof(complex),"allocating crt");
	rt = (float *)crt;
	ccrt = (char *)crt;
	fprintf(fpl,"sutifowler: nv=%d nvstack=%d\n",nv,nvstack);
	v=(float *)VNDemalloc(nv*sizeof(float),"allocating v");
	p2stack=(float *)VNDemalloc(nvstack*sizeof(float),"allocating p2stack");
	mute=(float *)VNDemalloc(mxfold*sizeof(float),"allocating mute");
	off=(float *)VNDemalloc(mxfold*sizeof(float),"allocating off");
	fprintf(fpl,"sutifowler: allocating and filling w array\n");
	w=(float *)VNDemalloc(ntfft*sizeof(float),"allocating w");
	for(iw=0;iw<ntfft;iw++) {
		if(iw<ntfftny){
			w[iw]=iw*dw;
		}else{
			w[iw]=(iw-ntfft)*dw;
		}
		if(iw==0) w[0]=0.1*dw;  	/* fudge for dc component */
	}

/******************************************************************************/
	fprintf(fpl,"sutifowler: building function for stacking velocity analysis\n");
/******************************************************************************/
	dv=(vmax-vmin)/MAX((nv-1),1);
	for(iv=0;iv<nv;iv++) v[iv]=vmin+iv*dv;
	if(ichoose>=3){
	  	for(iv=0;iv<nvstack;iv++) {
			p2stack[iv]=1./(v[iv]*v[iv]);
			fprintf(fpl,"	    stacking velocity %ld %f\n",iv,v[iv]);
		}
	}else{
		if(nvstack<6) err("sutifowler: nvstack must be 6 or more");
		dp2 = 1./(vminstack*vminstack*(nvstack-5));
		for(iv=0;iv<nvstack;iv++) {
			p2stack[iv]=iv*dp2;
			if(iv>0) {
				factor=1./sqrt(p2stack[iv]);
				fprintf(fpl,"	    stacking velocity %ld %f\n",iv,factor);
			}else{
				fprintf(fpl,"	    stacking velocity %ld infinity\n",iv);
			}
		}		
	}

/******************************************************************************/
	fprintf(fpl,"sutifowler: Opening and zeroing large block matrix disk file\n");
	fprintf(fpl,"	    This can take a while, but all is fruitless if the \n");
	fprintf(fpl,"	    necessary disk space is not there...\n");
/******************************************************************************/
	N[0]=nxfft+2;
	N[1]=ntout*MAX(nv*neta,nvstack);
	fname=VNDtempname(file);
	vnd = VNDop(2,0,2,N,1,sizeof(float),fname,ndir,dir,1);
	VNDfree(fname,"main: freeing fname 1");
	fprintf(fpl,"sutifowler: large file RAM mem buf = %ld bytes\n",
		vnd->NumBytesMemBuf);
	fprintf(fpl,"sutifowler: large file disk area = %ld bytes\n",
		vnd->NumBytesPerBlock*vnd->NumBlocksPerPanel*vnd->NumPanels);


	if(getcvstacks) {
/******************************************************************************/
		fprintf(fpl,"sutifowler: reading input cvstacks\n");
/******************************************************************************/
		for(icmp=0;icmp<ncmps;icmp++) {
			key[0]=icmp;
			key[1]=0;
			for(iv=0;iv<nvstack;iv++) {
				VNDrw('w',0,vnd,1,key,0,
					(char *) tr.data,iv*ntout,1,ntout,
					1,"writing cvstacks to disk");
				if( !gettr(&tr) ) {
				    if(icmp==ncmps-1 && iv==nvstack-1 ) {
					/* all ok, read all the input data */
				    }else{
					err("sutifowler: error reading input cvstacks");
				    }
				}
			}
		}
		goto xffts;
	}
/******************************************************************************/
	fprintf(fpl,
	"sutifowler: beginning constant velocity stacks of the input cmp gathers\n");
/******************************************************************************/
	fname=VNDtempname(file);
	vnda = V2Dop(2,1000000,sizeof(float),fname,nt,mxfold);
	VNDfree(fname,"main: freeing fname 2");
	fprintf(fpl,"sutifowler: cmp gather RAM mem buf = %ld bytes\n",
		vnda->NumBytesMemBuf);

	icmp=0;
	noff=0;
	do {
	   if(tr.cdp!=oldcmp) {
		cvstack(vnda,vnd,icmp,noff,off,mute,lmute,
			nvstack,p2stack,dt,dtout);
		icmp++;
		if(icmp==ncmps) {
			fprintf(fpl,"sutifowler: more input cdps than ncdps parameter\n");
			fprintf(fpl,"	    Will only process ncdps gathers.\n");
			goto done_with_input;
			}
		oldcmp=tr.cdp;
		noff=0;
	   }
	   if(lbtaper>0 || lstaper>0) taper (lstaper,lbtaper,ncmps,icmp,nt,tr.data);
	   factor=scale;
	   for(it=0;it<nt;it++) tr.data[it]*=factor;
	   V2Dw0(vnda,noff,(char *)tr.data,1);
	   off[noff]=tr.offset;
 	   if(ichoose==1 || ichoose==2) {
 		mute[noff]=fmax*off[noff]*off[noff]*dp2;
 	   }else{
 		mute[noff]=0.;
 	   }
	   if(nonhyp) mute[noff]=MAX(mute[noff],2*off[noff]/vmin);
	   noff++;
	   if(noff>mxfold) err("tifowler: input cdp has more traces than mxfold");
	} while ( gettr(&tr) );
	cvstack(vnda,vnd,icmp,noff,off,mute,lmute,
		nvstack,p2stack,dt,dtout);
	icmp++;
done_with_input:
	ncmps=icmp;
	fprintf(fpl,"sutifowler: read and stacked %d cmp gathers\n",ncmps);
	VNDcl(vnda,1);
xffts:
	VNDflush(vnd);

	if(ichoose<5){
/******************************************************************************/
	    fprintf(fpl,"sutifowler: doing forward x -> k spatial fft's\n");
/******************************************************************************/
	    for(it=0;it<(ntout*nvstack);it++) {
		V2Dr0(vnd,it,ccrt,21);
		for(k=ncmps;k<nxfft+2;k++) rt[k]=0.;
		pfarc(1,nxfft,rt,crt);
		V2Dw0(vnd,it,ccrt,22);
	    }
	    VNDr2c(vnd);
	}

	if(ichoose<=3) {
	    fprintf(fpl,"sutifowler: looping over k\n");
	    if(TI && (ichoose==1 || ichoose==2)) { /* build ti vnmo(p) table */
		vndvnmo=ptabledmo(nv,v,etamin,deta,neta,d,vsvp,NP,dp,dp2,file);
		fprintf(fpl,"sutifowler: dmo index(p) RAM mem buf = %ld bytes\n",
			vndvnmo->NumBytesMemBuf);
	    }
	    if(TI && (ichoose==1 || ichoose==3)){ /* build ti vphase(p) table */
		vndvphase=ptablemig(nv,v,etamin,deta,neta,d,vsvp,NP,file);
		fprintf(fpl,"sutifowler: migration scaler(p) RAM mem buf = %ld bytes\n",
			vndvphase->NumBytesMemBuf);
	    }
	    if(ichoose==1 || ichoose==2){
	    	iv=MAX(nv*neta,nvstack);
		fname=VNDtempname(file);
	    	vndb = V2Dop(2,750000,sizeof(complex),
			fname,(long)ntfft,iv);
	    		fprintf(fpl,"sutifowler: (w,v) RAM mem buf = %ld bytes\n",
				vndb->NumBytesMemBuf);
		VNDfree(fname,"main: freeing fname 3");
	    }

/******************************************************************************/
	    for(k=0;k<nxfftny;k++){ 	/* loop over spatial wavenumbers */
/******************************************************************************/
		if(k==(20*(k/20))) {
			fprintf(fpl,"sutifowler: k index = %d out of %d\n",
				k,nxfftny);
		}
		ak=k*dk;
		key[0]=k;
		key[1]=0;
/******************************************************************************/
		if(ichoose==1 || ichoose==2) { /* do Fowler DMO */
/******************************************************************************/
			for(iv=0;iv<nvstack;iv++) {	/* loop over input velocities */
				VNDrw('r',0,vnd,1,key,0,ccrt,iv*ntout,1,ntout,
				31,"Fowler DMO t -> w fft read");
				for(it=ntout;it<ntfft;it++) crt[it]=czero;
				pfacc(-1,ntfft,crt);
				V2Dw0(vndb,iv,ccrt,32);
			}

			for(iw=0;iw<ntfft;iw++) {
				p=0.5*ak/fabs(w[iw]);
				if(TI) {	/* anisotropic TI*/
				    ip=p/dp;
				    if(ip<NP) {
					V2Dr0(vndvnmo,ip,(char *)rindex,40);
				    }else{
					for(iv=0;iv<(nv*neta);iv++) rindex[iv]=-1.;
				    }
				}else{			/* isotropic */
				    p2=p*p;
				    for(iv=0;iv<nv;iv++){
					v2=v[iv]*v[iv];
					rindex[iv]=(1-v2*p2)/(v2*dp2);
				    }
				}	
				V2Dr1(vndb,iw,ccrt,41);
				for(iv=0;iv<nvstack;iv++) ctemp[iv]=crt[iv];
				ints8c(nvstack,1.0,0.0,ctemp,czero,czero,nv*neta,rindex,crt);
				V2Dw1(vndb,iw,ccrt,42);
			}
			for(iv=0;iv<(nv*neta);iv++) {	/* loop over output vel */
				V2Dr0(vndb,iv,ccrt,51);
				pfacc(1,ntfft,crt);
				VNDrw('w',0,vnd,1,key,0,ccrt,iv*ntout,1,ntout,
				52,"Fowler DMO w -> t fft write");		
			}
		}
/******************************************************************************/
		if( ichoose==3 && neta>1 ) {  /* fix up disk order if only doing TI migrations */
/******************************************************************************/
			for(iv=0;iv<nv;iv++) {
				VNDrw('r',0,vnd,1,key,0,ccrt,iv*ntout,1,ntout,
				57,"option 3 fixup for multiple eta read");
				for(ieta=1;ieta<neta;ieta++) {
					VNDrw('w',0,vnd,1,key,0,ccrt,
					iv*ntout+ieta*nv*ntout,1,ntout,
					58,"option 3 fixup for multiple eta write");
				}
			}
		}
/******************************************************************************/
		if( (ichoose==1 || ichoose==3 ) ) { 	/* do Stolt migration */
/******************************************************************************/
			for(iv=0;iv<(nv*neta);iv++) {
				if(TI) {	/* anisotropic TI */
				    V2Dr0(vndvphase,iv,ccrt,50);
				    dpm=rt[0];
				    dw=2.*PI/(ntfft*dtout);
				    iwmin=0.5*ak/( (NP-3)*dpm*dw);
				    for(iw=iwmin+1;iw<ntfftny;iw++) {
					p=0.5*ak/fabs(w[iw]);
					rp=1.0+p/dpm;
					ip=rp;
					wgt=rp-ip;
					factor=wgt*rt[ip+1]+(1.-wgt)*rt[ip];
					rindex[iw]=w[iw]*factor;
					rindex[ntfft-iw]=w[ntfft-iw]*factor;
				    }
				    fw=-2.*PI/dtout;
				    rindex[0]=fw;
				    for(iw=1;iw<iwmin+1;iw++) {
					rindex[iw]=fw;
					rindex[ntfft-iw]=fw;
				    }
				}else{			/* isotropic */
					scale=0.5*v[iv]*ak;
				    	for(iw=0;iw<ntfft;iw++) {
					    if(fabs(w[iw])>scale) {
						factor=scale/w[iw];
						factor=sqrt(1+factor*factor);
						rindex[iw]=w[iw]*factor;
					    }else{
						rindex[iw]=-2.*PI/dtout;
					    }
					}
				}

				VNDrw('r',0,vnd,1,key,0,ccrt,iv*ntout,1,ntout,
					61,"Stolt t -> w fft read");
				for(it=1;it<ntout;it+=2){
					crt[it].r=-crt[it].r;
					crt[it].i=-crt[it].i;
				}
				for(it=ntout;it<ntffts;it++) crt[it]=czero;
				pfacc(1,ntffts,crt);
				dw=2.*PI/(ntffts*dtout);
				fw=-PI/dtout;
				ints8c(ntffts,dw,fw,crt,czero,czero,
					ntfft,rindex,ctemp);
				/* obliquity factor code */
 				for(iw=0;iw<ntfft;iw++){
 					factor=fabs(w[iw]/rindex[iw]);
 					crt[iw].r=factor*ctemp[iw].r;
 					crt[iw].i=factor*ctemp[iw].i;
 				}
				pfacc(-1,ntfft,crt);
				VNDrw('w',0,vnd,1,key,0,ccrt,iv*ntout,1,ntout,
					62,"Stolt w->t fft write");		
			}
		}

	    }
	    fprintf(fpl,"sutifowler: completed loop over wavenumbers\n");
	    if(ichoose==1 || ichoose==2) VNDcl(vndb,1);
	    if(TI && (ichoose==1 || ichoose==2)) VNDcl(vndvnmo,1);
	    if(TI && (ichoose==1 || ichoose==3)) VNDcl(vndvphase,1);
	}

	if(ichoose<5) {
/******************************************************************************/
	    fprintf(fpl,"sutifowler: doing inverse spatial fft's k->x\n");
/******************************************************************************/
	    for(it=0;it<(ntout*nv*neta);it++) {
		V2Dr0(vnd,it,ccrt,71);
		pfacr(-1,nxfft,crt,rt);
		V2Dw0(vnd,it,ccrt,72);
	    }
	    VNDc2r(vnd);
	}

/*****************************************************************/
	fprintf(fpl,"sutifowler: outputting results\n");
/******************************************************************/
	it=0;
	for(icmp=0;icmp<ncmps;icmp++) {
		key[0]=icmp;
		key[1]=0;
		for(ieta=0;ieta<neta;ieta++) {
			for(iv=0;iv<nv;iv++) {
				VNDrw('r',0,vnd,1,key,0,(char *)tr.data,
					iv*ntout+ieta*nv*ntout,1,ntout,82,
					"outputting all velocities for each cmp");
				tr.ns=ntout;
				tr.dt=1000000*dtout;
				tr.cdp=icmp;
				tr.tracf=iv;
				tr.offset=v[iv];
				tr.cdpt=iv;
				tr.sx=icmp*dx;
				tr.gx=icmp*dx;
				it++;
				tr.tracl=it;
				tr.tracr=it;
				tr.fldr=icmp/ngroup;
				tr.ep=10+tr.fldr*ngroup;
				tr.igc=ieta;
				tr.igi=100*(etamin+ieta*deta);
				tr.d1=dtout;
				tr.f1=0.;
				tr.d2=1.;
				tr.f2=0.;
				puttr(&tr);
			}
		}
	}

/* close files and return */
	VNDcl(vnd,1);
	VNDfree(crt,"main: freeing crt");
	VNDfree(ctemp,"main: freeing ctemp");
	VNDfree(v,"main: freeing v");
	VNDfree(p2stack,"main: freeing p2stack");
	VNDfree(mute,"main: freeing mute");
	VNDfree(off,"main: freeing off");
	VNDfree(rindex,"main: freeing rindex");
	VNDfree(w,"main: freeing w");
	if(VNDtotalmem()!=0) {
		fprintf(stderr,"total VND memory at end = %ld\n",
		VNDtotalmem());
	}
	return EXIT_SUCCESS;
}