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