Ejemplo n.º 1
0
void integ(float **mig,int nz,float dz,int nx,int m,float **migi) 
/* integration of a two-dimensional array	 
  input: 
    mig[nx][nz]		two-dimensional array
  output:
    migi[nx][nz+2*m] 	integrated array 
*/
{
	int nfft, nw, ix, iz, iw;
	float  *amp, dw, *rt;
	complex *ct;


        /* Set up FFT parameters */
        nfft = npfaro(nz+m, 2 * (nz+m));
        if (nfft >= SU_NFLTS || nfft >= 720720)
                err("Padded nt=%d -- too big", nfft);

        nw = nfft/2 + 1;
	dw = 2.0*PI/(nfft*dz);

	amp = ealloc1float(nw);
	for(iw=1; iw<nw; ++iw) 
		amp[iw] = 0.5/(nfft*(1-cos(iw*dw*dz)));
	amp[0] = amp[1];

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

	for(ix=0; ix<nx; ++ix) {
        	memcpy(rt, mig[ix], nz*FSIZE);
       	 	memset((void *) (rt + nz), 0, (nfft-nz)*FSIZE); 
        	pfarc(1, nfft, rt, ct);

        	/* Integrate traces   */
		for(iw=0; iw<nw; ++iw){
			ct[iw].i = ct[iw].i*amp[iw];
			ct[iw].r = ct[iw].r*amp[iw];
		}

        	pfacr(-1, nfft, ct, rt);

        	for (iz=0; iz<m; ++iz)  migi[ix][iz] = rt[nfft-m+iz];
        	for (iz=0; iz<nz+m; ++iz)  migi[ix][iz+m] = rt[iz];
	}

	free1float(amp);
	free1float(rt);
	free1complex(ct);
}
Ejemplo n.º 2
0
void bandpass(float *data, int nt, int nfft, int nfreq,
		float *filterj, float *ftracej)
{
	float *rt;
	complex *ct;
	int i;

	rt  = ealloc1float(nfft);
	ct  = ealloc1complex(nfreq);
        /* Load trace into rt (zero-padded) */
        memcpy((char*) rt, (char*) data, nt*FSIZE);
        bzero(rt + nt, (nfft-nt)*FSIZE);

        /* FFT, filter, inverse FFT */
        pfarc(1, nfft, rt, ct);
        for (i = 0; i < nfreq; ++i)  ct[i] = crmul(ct[i], filterj[i]);
        pfacr(-1, nfft, ct, rt);

        /* Load traces back in, recall filter had nfft factor */
        for (i = 0; i < nt; ++i)  ftracej[i] = rt[i]; /* ftracej = rt ?? */
	free(rt);
	free(ct);
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
int
main(int argc, char **argv)
{
	float a, b;		/* powers for amp and phase		*/
	register float *rt=NULL;/* real trace				*/
	register complex *ct=NULL;	/* complex transformed trace		*/
	complex filt;		/* pow'd input at one frequency	 	*/
	int nt;			/* number of points on input trace	*/
	size_t ntsize;		/* nt in bytes				*/
	float dt;		/* sample spacing (secs) on input trace	*/
	int nfft;		/* number of points in nfft		*/
	int nf;		 	/* number of frequencies (incl Nyq)     */
	float onfft;		/* 1 / nfft				*/
	int verbose;		/* flag to get advisory messages	*/
	size_t nzeros;		/* number of padded zeroes in bytes	*/
	cwp_Bool seismic;	/* is this seismic data?		*/
	int ntout, sym;		/* output params			*/
	
	
	/* Initialize */
	initargs(argc, argv);
	requestdoc(1);


	/* Set parameters */
	if (!getparint("verbose", &verbose))	  verbose  =  0;
	if (!getparfloat("a", &a))	  a = 0.0;
	if (!getparfloat("b", &b))	  b = 0.0;
	if (!getparint("sym",&sym)) 	  sym = 0;

	/* Get info from first trace */
	if (!gettr(&tr))	err("can't get first trace");
	seismic = ISSEISMIC(tr.trid);
	if (seismic) {
		if (verbose)	warn("input is seismic data, trid=%d",tr.trid);
		dt = ((double) tr.dt)/1000000.0;
	}
	else {
		if (verbose)	warn("input is not seismic data, trid=%d",tr.trid);
		dt = tr.d1;
	}
	if (!dt)	err("dt or d1 field is zero and not getparred");
	nt = tr.ns;
	ntsize = nt * FSIZE;

	if (!getparint("ntout",&ntout))   ntout=tr.ns;

	/* Set up for fft 
	   extra 2 in nfft is to avoid wrap around */
	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;

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

	
	/* Loop over traces */
	do {
		/* Load trace into rt (zero-padded) */
		memcpy( (void *) rt, (const void *) tr.data, ntsize);
		memset((void *) (rt + nt), 0, nzeros);

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

		/* Apply filter */
		{ register int i;
			for (i = 0; i < nf; ++i) {

				filt = dopow(ct[i], a, b);
				ct[i] = cmul(ct[i], filt);

				/* symmetric output: flip sign of odd values */
				if (sym){
					if (ISODD(i)) {
						ct[i].r = -ct[i].r;
						ct[i].i = -ct[i].i;
					}
				}

			}
		}

		/* Invert */
		pfacr(-1, nfft, ct, rt);

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

		puttr(&tr);

	} while (gettr(&tr));


	return(CWP_Exit());
}
Ejemplo n.º 5
0
int
main(int argc, char **argv)
{
    float c;			/* speed			*/
    float dt;			/* sampling rate		*/
    int nt;				/* number of samples		*/
    size_t ntsize;			/* ... in bytes			*/
    int nshot;			/* number of shots		*/
    int nrec;			/* number of receivers		*/
    float x0, y0, z0;		/* point scatterer location	*/
    float sxmin, symin, szmin;	/* first shot location		*/
    float gxmin, gymin, gzmin;	/* first receiver location	*/
    float dsx, dsy, dsz;		/* step in shot location	*/
    float dgx, dgy, dgz;		/* step in receiver location	*/

    float sx, sy, sz;		/* shot location		*/
    float gx, gy, gz;		/* receiver location		*/
    float rs;			/* distance to shot		*/
    float rg;			/* distance to receiver		*/
    float d;			/* rs + rg			*/
    float t;			/* total travel time		*/
    float k;			/* constant part of response	*/

    register float *rt;		/* real trace			*/
    register complex *ct;		/* complex transformed trace	*/
    int nfft;			/* size of fft 			*/
    int nfby2;			/* nfft/2			*/
    int nfby2p1;			/* nfft/2 + 1			*/
    size_t nzeros;			/* padded zeroes in bytes	*/
    float spread;			/* 3-D spreading factor		*/

    register int i;			/* counter			*/
    register int s;			/* shot counter			*/
    register int g;			/* receiver counter		*/
    register int tracl;		/* trace counter		*/

    float amplitude[1];	/* amplitude 			*/
    float *tout;		/* times[nt] for interpolation	*/


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


    /* Get parameters */
    if (!getparint("nshot", &nshot))	nshot = 1;
    if (!getparint("nrec", &nrec))		nrec  = 1;
    if (!getparint("nt", &nt))		nt    = 256;
    if (!getparfloat("c", &c))		c     = 5000.0;
    if (!getparfloat("dt", &dt))		dt    = 0.004;
    if (!getparfloat("x0", &x0))		x0    = 1000.0;
    if (!getparfloat("y0", &y0))		y0    = 0.0;
    if (!getparfloat("z0", &z0))		z0    = 1000.0;
    if (!getparfloat("sxmin", &sxmin))	sxmin = 0.0;
    if (!getparfloat("symin", &symin))	symin = 0.0;
    if (!getparfloat("szmin", &szmin))	szmin = 0.0;
    if (!getparfloat("gxmin", &gxmin))	gxmin = 0.0;
    if (!getparfloat("gymin", &gymin))	gymin = 0.0;
    if (!getparfloat("gzmin", &gzmin))	gzmin = 0.0;
    if (!getparfloat("dsx", &dsx))		dsx   = 100.0;
    if (!getparfloat("dsy", &dsy))		dsy   = 0.0;
    if (!getparfloat("dsz", &dsz))		dsz   = 0.0;
    if (!getparfloat("dgx", &dgx))		dgx   = 100.0;
    if (!getparfloat("dgy", &dgy))		dgy   = 0.0;
    if (!getparfloat("dgz", &dgz))		dgz   = 0.0;


    /* Set the constant header fields */
    tr.ns = nt;
    tr.dt = dt * 1000000.0;
    ntsize = nt * FSIZE;


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

    nfby2 = nfft / 2;
    nfby2p1 = nfby2 + 1;
    nzeros = (nfft - nt) * FSIZE;


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


    /* Set the constant in the response amplitude
       including scale for inverse fft below      */
    k = 1.0 / (4.0 * c * c * dt * dt * dt * nfft * nfft * nfft);

    /* Compute output times for interpolation */
    tout = ealloc1float(nt);
    for (i=0; i<nt; i++) tout[i]=i*dt;

    /* Create the traces */
    tracl = 0;
    for (s = 0; s < nshot; ++s) {	/* loop over shots */
        sx = sxmin + s * dsx;
        sy = symin + s * dsy;
        sz = szmin + s * dsz;
        rs = sqrt((sx - x0)*(sx - x0) + (sy - y0)*(sy - y0) +
                  (sz - z0)*(sz - z0));

        for (g = 0; g < nrec; ++g) {	/* loop over receivers */
            memset( (void *) tr.data, 0, ntsize);
            gx = gxmin + g * dgx;
            gy = gymin + g * dgy;
            gz = gzmin + g * dgz;
            rg = sqrt((gx - x0)*(gx - x0) + (gy - y0)*(gy - y0) +
                      (gz - z0)*(gz - z0));
            d = rs + rg;
            t = d/c;
            spread = rs*rg;
            amplitude[0] = k/spread;

            /* Distribute response over full trace */
            ints8r(1,dt,t,amplitude,0,0,nt,tout,tr.data);

            /* Load trace into rt (zero-padded) */
            memcpy( (void *) rt, (const void *) tr.data, ntsize);
            memset( (void *) (rt + nt), 0, nzeros);

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

            /* Multiply by omega^2 */
            for (i = 0; i < nfby2p1; ++i)
                ct[i] = crmul(ct[i], i*i);

            /* Invert and take real part */
            pfacr(-1, nfft, ct, rt);

            /* Load traces back in */
            memcpy( (void *) tr.data, (const void *) rt, ntsize);

            /* Set header fields---shot fields set above */
            tr.tracl = tr.tracr = ++tracl;
            tr.fldr = 1 + s;
            tr.tracf = 1 + g;
            tr.sx = NINT(sx);
            tr.sy = NINT(sy);
            tr.selev = -NINT(sz); /* above sea level > 0 */
            tr.gx = NINT(gx);
            tr.gy = NINT(gy);
            tr.gelev = -NINT(gz); /* above sea level > 0 */

            /* If along a coordinate axis, use a signed offset */
            tr.offset = sqrt((sx - gx)*(sx - gx) +
                             (sy - gy)*(sy - gy) +
                             (sz - gz)*(sz - gz));
            if (dgy == 0 && dgz == 0)
                tr.offset = NINT(dsx > 0 ? gx - sx : sx - gx);
            if (dgx == 0 && dgz == 0)
                tr.offset = NINT(dsy > 0 ? gy - sy : sy - gy);
            if (dgx == 0 && dgy == 0)
                tr.offset = NINT(dsz > 0 ? gz - sz : sz - gz);

            puttr(&tr);
        } /* end loop on receivers */
    } /* end loop on shots */

    return(CWP_Exit());
}
Ejemplo n.º 6
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);
}	
Ejemplo n.º 7
0
int
main(int argc, char **argv)
{
	cwp_String mode;	/* display: real, imag, amp, arg	*/
	int imode=AMP;		/* integer abbrev. for mode in switch	*/
	register complex *ct;	/* complex trace			*/
	int nt;			/* number of points on input trace	*/
	float dt;		/* sample spacing			*/
	float *data;		/* array of data from each trace	*/
	float *hdata;		/* array of Hilbert transformed data	*/
	float unwrap;		/* PI/unwrap=min dphase assumed to by wrap*/
	int wint;		/* n time sampling to window */
	cwp_Bool seismic;	/* is this seismic data?		*/
	int ntout;
	/* Initialize */
	initargs(argc, argv);
	requestdoc(1);
	

	/* Get info from first trace */
	if (!gettr(&tr)) err("can't get first trace");
	nt = tr.ns;
	dt = ((double) tr.dt)/1000000.0;
	ntout = nt + nt -1;

	/* check to see if data type is seismic */
	seismic = ISSEISMIC(tr.trid);

	if (!seismic)
		warn("input is not seismic data, trid=%d", tr.trid);

	/* Get mode; note that imode is initialized to AMP */
	if (!getparstring("mode", &mode))	mode = "amp";

	if      (STREQ(mode, "phase"))  imode = ARG;
	else if (STREQ(mode, "freq"))	imode = FREQ;
	else if (STREQ(mode, "bandwidth")) imode = BANDWIDTH;
	else if (STREQ(mode, "normamp")) imode = NORMAMP;
	else if (STREQ(mode, "freqw")) imode = FREQW;
	else if (STREQ(mode, "thin")) imode = THIN;
	else if (STREQ(mode, "fdenv")) imode = FENV;
	else if (STREQ(mode, "sdenv")) imode = SENV;
	else if (STREQ(mode, "q")) imode = Q;
	else if (!STREQ(mode, "amp"))
		err("unknown mode=\"%s\", see self-doc", mode);

	/* getpar value of unwrap */
	switch(imode) {
	case FREQ:
		if (!getparfloat("unwrap", &unwrap))	unwrap=1;
	break;
	case Q:
		if (!getparfloat("unwrap", &unwrap))	unwrap=1;
	break;
	case FREQW:
		if (!getparfloat("unwrap", &unwrap))	unwrap=1;
		if (!getparint("wint", &wint))	wint=3; 
	break;
	case THIN:
		if (!getparfloat("unwrap", &unwrap))	unwrap=1;
		if (!getparint("wint", &wint))	wint=3;
	break;
	case ARG:
		if (!getparfloat("unwrap", &unwrap))	unwrap=0;
	break;
	}

	/* allocate space for data and hilbert transformed data, cmplx trace */
	data = ealloc1float(nt);
	hdata = ealloc1float(nt);
	ct = ealloc1complex(nt);


	/* Loop over traces */
	do {
		register int i;

		/* Get data from trace */
		for (i = 0; i < nt; ++i)  data[i] = tr.data[i];

		
		/* construct quadrature trace with hilbert transform */
		hilbert(nt, data, hdata);

		/* build the complex trace */
		for (i = 0; i < nt; ++i)  ct[i] = cmplx(data[i],hdata[i]);

		/* Form absolute value, phase, or frequency */
		switch(imode) {
		case AMP:
			for (i = 0; i < nt; ++i) {
				float re = ct[i].r;
				float im = ct[i].i;
				tr.data[i] = sqrt(re*re + im*im);
			}
			
			/* set trace id */
			tr.trid = ENVELOPE;
		break;
		case ARG:
		{
			float *phase = ealloc1float(nt);

			for (i = 0; i < nt; ++i) {
				float re = ct[i].r;
				float im = ct[i].i;
				if (re*re+im*im)  phase[i] = atan2(im, re);
				else              phase[i] = 0.0;
			}

			/* phase unwrapping */
			/* default unwrap=0 for this mode */
			if (unwrap!=0) unwrap_phase(nt, unwrap, phase);
			
			/* write phase values to tr.data */
			for (i = 0; i < nt; ++i) tr.data[i] = phase[i];
			
			/* set trace id */
			tr.trid = INSTPHASE;
		}
		break;
		case FREQ:
		{
			float *phase = ealloc1float(nt);
			float	fnyq = 0.5 / dt;

			for (i = 0; i < nt; ++i) {
				float re = ct[i].r;
				float im = ct[i].i;
				if (re*re+im*im) {
					phase[i] = atan2(im, re);
				} else {
					phase[i] = 0.0;
				}
				
			}

			/* unwrap the phase */
			if (unwrap!=0) unwrap_phase(nt, unwrap, phase);

			/* compute freq(t)=dphase/dt */
			differentiate(nt, 2.0*PI*dt, phase);
			
			/* correct values greater nyquist frequency */
			for (i=0 ; i < nt; ++i)	{
				if (phase[i] > fnyq)
					phase[i] = 2 * fnyq - phase[i];
			}
                                        
			/* write freq(t) values to tr.data */
			for (i=0 ; i < nt; ++i) tr.data[i] = phase[i];

			/* set trace id */
			tr.trid = INSTFREQ;
		}
		break;
		case FREQW:
		{
			float	fnyq = 0.5 / dt;
			float *freqw = ealloc1float(nt);
			float *phase = ealloc1float(nt);
			float *envelop = ealloc1float(nt);
			float *envelop2 = ealloc1float(nt);
			for (i = 0; i < nt; ++i) {
				float re = ct[i].r;
				float im = ct[i].i;
				if (re*re+im*im) {
					phase[i] = atan2(im, re);
					} else {
						phase[i] = 0.0;
						}
				envelop[i] = sqrt(re*re + im*im);
			}

			/* unwrap the phase */
			if (unwrap!=0) unwrap_phase(nt, unwrap, phase);

			/* compute freq(t)=dphase/dt */
			differentiate(nt, 2.0*PI*dt, phase);
			
			/* correct values greater nyquist frequency */
			for (i=0 ; i < nt; ++i)	{
				if (phase[i] > fnyq)
					phase[i] = 2 * fnyq - phase[i];
			envelop2[i]=envelop[i]*phase[i];
			}
			twindow(nt, wint, envelop);
			twindow(nt, wint, envelop2);
			/* correct values greater nyquist frequency */
			for (i=0 ; i < nt; ++i) {
			freqw[i] = (envelop[i] == 0.0) ? 0.0 :envelop2[i]/envelop[i];
			}
			/* write freq(t) values to tr.data */
			for (i=0 ; i < nt; ++i) tr.data[i] = freqw[i];
			
			/* set trace id */
			tr.trid = INSTFREQ;
		}
		break;
		case THIN:
		{
			float	fnyq = 0.5 / dt;
			float *phase = ealloc1float(nt);
			float *freqw = ealloc1float(nt);
			float *phase2 = ealloc1float(nt);



			for (i = 0; i < nt; ++i) {
				float re = ct[i].r;
				float im = ct[i].i;

				if (re*re+im*im) {
					phase[i] = atan2(im, re);
				} else {
					phase[i] = 0.0;
				}
			}

			/* unwrap the phase */
			if (unwrap!=0) unwrap_phase(nt, unwrap, phase);

			/* compute freq(t)=dphase/dt */
			differentiate(nt, 2.0*PI*dt, phase);

			/* correct values greater nyquist frequency */
			for (i=0 ; i < nt; ++i)	{
				if (phase[i] > fnyq)
					phase[i] = 2 * fnyq - phase[i];
					phase2[i]= 2 * fnyq - phase[i];
			}
			/* Do windowing for Average Ins . Freq over wint*/
			twindow(nt, wint, phase2);

			for (i=0 ; i < nt; ++i)	{
				freqw[i] = phase[i] - phase2[i];
			/*	if (abs(freqw[i]) > fnyq)
				freqw[i] = 2 * fnyq - freqw[i];
			*/
			/* write Thin-Bed(t) values to tr.data */
				tr.data[i] = freqw[i];
				}
			/* set trace id */
			tr.trid = INSTFREQ;
		}
		break;
		case BANDWIDTH:
		{
			float *envelop = ealloc1float(nt);
			float *envelop2 = ealloc1float(nt);

		/* Bandwidth (Barnes 1992)

		          |d(envelope)/dt|
		band =abs |--------------|
		          |2 PI envelope |
	 	*/

			for (i = 0; i < nt; ++i) {
				float er = ct[i].r;
				float em = ct[i].i;
				envelop[i] = sqrt(er*er + em*em);
				envelop2[i]=sqrt(er*er + em*em);

			}
				differentiate(nt, dt, envelop);

				for (i = 0; i < ntout; ++i) {
				   if (2.0*PI*envelop2[i]!=0.0) {
					tr.data[i] = ABS(envelop[i]/(2.0*PI*envelop2[i]));
				   } else {
				        tr.data[i]=0.0;
				   }
				}
				tr.trid = ENVELOPE;
		}
		break;
		case NORMAMP:
		{
			float phase;
			float *na = ealloc1float(nt);
			for (i = 0; i < nt; ++i) {
				float re = ct[i].r;
				float im = ct[i].i;
				if (re*re+im*im)  phase = atan2(im, re);
				else              phase = 0.0;
				na[i] = cos(phase);
			}
			for (i=0 ; i < nt; ++i) tr.data[i] = na[i];
			
			/* set trace id */
			tr.trid = INSTPHASE;
			}
		break;
		case FENV:
		{
			float *amp = ealloc1float(nt);
			for (i = 0; i < nt; ++i) {
				float re = ct[i].r;
				float im = ct[i].i;
				amp[i] = sqrt(re*re + im*im);
			}
		/*conv(nt, 0, envelop, nt, 0, time, ntout, 0, ouput);*/

		differentiate(nt, 2.0*PI*dt, amp);
		for (i=0 ; i < nt; ++i) tr.data[i] = amp[i];
			/* set trace id */
			tr.trid = ENVELOPE;
		}
		break;
		case SENV:
		{
			float *amp = ealloc1float(nt);
			for (i = 0; i < nt; ++i) {
				float re = ct[i].r;
				float im = ct[i].i;
				amp[i] = sqrt(re*re + im*im);
			}

		differentiate(nt, 2.0*PI*dt, amp);
		differentiate(nt, 2.0*PI*dt, amp);
		for (i=0 ; i < nt; ++i) tr.data[i] = amp[i];
			/* set trace id */
			tr.trid = ENVELOPE;
		}
		break;

		case Q:
		{
			float *envelop = ealloc1float(nt);
			float *envelop2 = ealloc1float(nt);
			float *phase = ealloc1float(nt);
			float	fnyq = 0.5 / dt;

		/* Banswith (Barnes 1992)

		        -PI Freq(t) d(envelope)/dt
		band =  --------------------------
		                 envelope(t)
	 	*/

			for (i = 0; i < nt; ++i) {
				float re = ct[i].r;
				float im = ct[i].i;
				envelop[i] = sqrt(re*re + im*im);
				envelop2[i]=sqrt(re*re + im*im);
				if (re*re+im*im) {
					phase[i] = atan2(im, re);
				} else {
					phase[i] = 0.0;
				}

			}
			/* get envelope diff */
			differentiate(nt, dt, envelop);
			/* unwrap the phase */
			if (unwrap!=0) unwrap_phase(nt, unwrap, phase);
			/* compute freq(t)=dphase/dt */
			differentiate(nt, 2.0*PI*dt, phase);

			for (i=0 ; i < nt; ++i)	{
				if (phase[i] > fnyq)
					phase[i] = 2 * fnyq - phase[i];
			}

			for (i = 0; i < ntout; ++i) {
				if (envelop[i]!=0.0)
				tr.data[i] = -1*PI*phase[i]*envelop2[i]/envelop[i];
				else
				tr.data[i]=0.0;
				}
				tr.trid = INSTFREQ;
		}
		break;
		default:
			err("%s: mysterious mode=\"%s\"", __LINE__, mode);
		}


		tr.d1 = dt;   /* for graphics */
		puttr(&tr);

	} while (gettr(&tr));


	return(CWP_Exit());
}
Ejemplo n.º 8
0
int
main(int argc, char **argv)
{
	register float *rt;	/* real trace				*/
	register complex *ct;	/* complex transformed trace		*/
	int nt;			/* number of points on input trace	*/
	int nfft;		/* transform length			*/
	int nf;			/* number of frequencies		*/
	int sign;		/* sign in exponent of transform	*/
	int verbose;		/* flag to get advisory messages	*/
	float dt;		/* sampling interval in secs		*/
	float d1;		/* output sample interval in Hz		*/
	cwp_Bool seismic;	/* is this seismic data? */
	float c;		/* multiplier				*/
	float w0, w1, w2;	/* weights				*/

	/* Initialize */
	initargs(argc, argv);
	requestdoc(1);
	if (!getparint("verbose", &verbose))	verbose=1;

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

	/* check for seismic or well log data */
	seismic = ISSEISMIC(tr.trid);		
	if (seismic) {
		if (verbose)	warn("input is seismic data, trid=%d",tr.trid);
		dt = ((double) tr.dt)/1000000.0;
	}
	else {
		if (verbose)	warn("input is not seismic data, trid=%d",tr.trid);
		dt = tr.d1;
        }
	if (!dt) {
		dt = .004;
		if (verbose) warn("dt or d1 not set, assumed to be .004");
	}

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

	if (!getparint("sign", &sign)) sign = 1;
	if (sign != 1 && sign != -1)   err("sign = %d must be 1 or -1", sign);

	/* get weights */
	if (!getparfloat("w0",&w0)) w0 = 0.75;
	if (!getparfloat("w1",&w1)) w1 = 1.00;
	if (!getparfloat("w2",&w2)) w2 = 0.75;

	rt = ealloc1float(nfft);
	ct = ealloc1complex(nf);

	/* If dt not set, issue advisory on frequency step d1 */
	if (dt && verbose)  warn("d1=%f", 1.0/(nfft*dt));

	/* Main loop over traces */
	do {
		register int i;

		/* Load trace into rt (zero-padded) */
		memcpy((void *) rt, (const void *) tr.data, nt*FSIZE);
		memset((void *) (rt + nt), (int) '\0', (nfft-nt)*FSIZE);

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

		/* Store values */
		for (i = 0; i < nf; ++i) {
			c =w0*rcabs(ct[i-1])+w1*rcabs(ct[i])+w2*rcabs(ct[i+1]);
			if (i==0 || i==nf) {
				tr.data[2*i]   = ct[i].r / rcabs(ct[i]);
				tr.data[2*i+1] = ct[i].i / rcabs(ct[i]);
			} else {
				tr.data[2*i]   = ct[i].r / c;
				tr.data[2*i+1] = ct[i].i / c;
			}
		}

		/* Set header values--npfaro makes nfft even */
		tr.ns = 2 * nf;
		tr.trid = FUNPACKNYQ;
		tr.d1 = d1;
		tr.f1 = 0.0;

		puttr(&tr);

	} while (gettr(&tr));


	return(CWP_Exit());
}
Ejemplo n.º 9
0
int
main(int argc, char **argv)
{
	register float *rt;	/* real trace				*/
	register complex *ct;	/* complex transformed trace		*/
	int nt;			/* number of points on input trace	*/
	int nfft;		/* number of points on output trace	*/
	int nfby2p1;		/* nfft/2 + 1				*/
	float dt;		/* sample interval in secs		*/
	float d1;		/* output sample interval in Hz		*/
	int ntr=0;		/* number of traces			*/
	register int i;		/* counter				*/


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


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

	/* dt is used only to set output header value d1 */
	if (!getparfloat("dt", &dt)) dt = ((double) tr.dt)/1000000.0;
	if (!dt) {
		dt = .004;
		warn("dt not set, assumed to be .004");
	}


        checkpars();


	/* Set up pfa fft */
	nfft = npfaro(nt, LOOKFAC * nt);
	if (nfft >= SU_NFLTS || nfft >= PFA_MAX)
		 err("Padded nt=%d--too big", nfft);
	nfby2p1 = nfft/2 + 1;
	d1 = 1.0/(nfft*dt);

	rt = ealloc1float(nfft);
	ct = ealloc1complex(nfby2p1);


	/* Main loop over traces */
	do {
		++ntr;

		/* Load trace into rt (zero-padded) */
		memcpy( (void *) rt, (const void *) tr.data, nt*FSIZE);
		memset( (void *) (rt + nt), 0, (nfft - nt)*FSIZE);

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

		/* Compute amplitude spectrum */
		tr.data[0] = rcabs(ct[0])/2.0;
		for (i = 1; i < nfby2p1; ++i)  tr.data[i] = rcabs(ct[i]);

		/* Set header values */
		tr.ns = nfby2p1;
		tr.dt = 0;	  /* d1=df is now the relevant step size */
		tr.trid = AMPLITUDE;
		tr.d1 = d1;
		tr.f1 = 0.0;

		puttr(&tr);

	} while (gettr(&tr));


	return(CWP_Exit());
}
Ejemplo n.º 10
0
int
main(int argc, char **argv)
{
	float *rt=NULL;		/* real trace			*/
	float *amp=NULL;	/* amplitude spectra		*/
	float *ph=NULL;		/* phase			*/
	register complex *ct=NULL;	/* complex time trace	*/

	int nt;			/* number of points on input trace	*/
	int nfft;		/* transform length			*/
	int nf;			/* number of frequencies in transform	*/

	float dt;		/* sampling interval in secs		*/
	float d1;		/* output sample interval in Hz		*/
	int count=0;		/* counter				*/

	/* linear phase function */
	float a;		/* bias (intercept) of new phase	*/
	float b;		/* slope of linear phase function	*/
	float c;		/* new phase value			*/
	float onfft;		/* 1/nfft				*/

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


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

	/* get parameters */
	/* dt is used only to set output header value d1 */
	if (!getparfloat("dt", &dt))	dt = ((double) tr.dt)/1000000.0;
	if (!dt) {
		dt = .004;
		warn("dt not set, assumed to be .002");
	}

	/* linear phase paramter values */
	if (!getparfloat("a", &a)) a = 0;
	if (!getparfloat("b", &b)) b = 180/PI;
	if (!getparfloat("c", &c)) c = 0.0;

	a *= PI/180.0;
	b *= PI/180.0;
	
	/* Set up pfa fft */
	nfft = npfaro(nt, LOOKFAC * nt);
	if (nfft >= SU_NFLTS || nfft >= PFA_MAX)  
		err("Padded nt=%d--too big", nfft);
	d1 = 1.0/(nfft*dt);
	nf = nfft/2 + 1;
        onfft = 1.0/nfft;
	 
	checkpars();

	/* Allocate space */
	rt = ealloc1float(nfft);
	ct = ealloc1complex(nf);
	amp = ealloc1float(nf);
	ph = ealloc1float(nf);

	/* Main loop over traces */
	count=0;
	do {
		register int i;
		
		/* Load trace into rt (zero-padded) */
		memcpy((void *) rt, (const void *) &tr.data, nt*FSIZE);
		memset((void *) (rt + nt), (int) '\0', (nfft-nt)*FSIZE);
		
		/* FFT */
		pfarc(1, nfft, rt, ct);
		for (i = 0; i < nf; ++i) {
			amp[i] = AMPSP(ct[i]);
			ph[i]  = a+b*atan2(ct[i].i,ct[i].r)+c*i;
		}
		for (i = 0; i < nf; ++i) {
			ct[i].r = amp[i]*cos(ph[i]);
			ct[i].i = amp[i]*sin(ph[i]);
		}
		pfacr(-1,nfft,ct,rt);
		for (i = 0; i < nt; ++i) rt[i]*=onfft;
		memcpy((void *) tr.data, (const void *) rt, nt*FSIZE);
		puttr(&tr);
		
	} while (gettr(&tr));

	return(CWP_Exit());
}
Ejemplo n.º 11
0
main(int argc, char **argv)
{
        register float *rt;     /* real trace                           */
        register complex *ct;   /* complex transformed trace            */
        float *filter;          /* filter array                         */
        float f1;               /* left lower corner frequency          */
        float f2;               /* left upper corner frequency          */
        float f4;               /* right lower corner frequency         */
        float f3;               /* right upper corner frequency         */
        int if1,if2,if3,if4;    /* integerizations of f1,f2,f3,f4       */
        float dt;               /* sample spacing                       */
        float nyq;              /* nyquist frequency                    */
        int nt;                 /* number of points on input trace      */
        int nfft;               /* number of points for fft trace       */
        int nf;                 /* number of frequencies (incl Nyq)     */
        int nfm1;               /* nf-1                                 */
        float onfft;            /* reciprocal of nfft                   */
        float df;               /* frequency spacing (from dt)          */

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


        /* Get info from first trace */ 
        if (!gettr(&tr))  err("can't get first trace");
        if (tr.trid && tr.trid != TREAL)
                err("input is not seismic data, trid=%d", tr.trid);
        nt = tr.ns;
        if (!getparfloat("dt", &dt))    dt = tr.dt/1000000.0;
        if (!dt) err("dt field is zero and not getparred");
        nyq = 0.5/dt;


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

        nf = nfft/2 + 1;
        nfm1 = nf - 1;
        onfft = 1.0 / nfft;


        /* Get corner frequencies */
        if (!getparfloat("f1", &f1))    f1 = FRAC1 * nyq;
        if (!getparfloat("f2", &f2))    f2 = FRAC2 * nyq;
        if (!getparfloat("f3", &f3))    f3 = FRAC3 * nyq;
        if (!getparfloat("f4", &f4))    f4 = FRAC4 * nyq;
        if (f1 < 0.0 || f1 > f2 || f2 >= f3 || f3 > f4)
                err("Bad filter parameters");


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


        /* Compute integer frequencies */
        df = onfft / dt;
        if1 = NINT(f1/df);
        if2 = NINT(f2/df);
        if3 = NINT(f3/df);
        if (if3 > nfm1) if3 = nfm1;
        if4 = NINT(f4/df);
        if (if4 > nfm1) if4 = nfm1;


        /* Make filter with scale for inverse transform */
	{ register int i;
	  register float c = PIBY2 / (if2 - if1 + 2);
	  for (i = if1; i <= if2; ++i) {
		register float s = sin(c*(i - if1 + 1));
		filter[i] = s * s * onfft;
	  }
        }

        { register int i;
	  register float c = PIBY2 / (if4 - if3 + 2);
	  for (i = if3; i <= if4; ++i) {
		register float s = sin(c*(if4 - i + 1));
		filter[i] = s * s * onfft;
	  }
        }

        { register int i;
          for (i = if2 + 1; i < if3; ++i)  filter[i] = onfft; 
          for (i = 0;       i < if1; ++i)  filter[i] = 0.0; 
          for (i = if4 + 1; i < nf;  ++i)  filter[i] = 0.0; 
        }



        /* Main loop over traces */
        do {
                register int i;

                /* Load trace into rt (zero-padded) */
                memcpy(rt, tr.data, nt*FSIZE);
                bzero(rt + nt, (nfft-nt)*FSIZE);

                /* FFT, filter, inverse FFT */
                pfarc(1, nfft, rt, ct);
                for (i = 0; i < nf; ++i)  ct[i] = crmul(ct[i], filter[i]);
                pfacr(-1, nfft, ct, rt);

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

                puttr(&tr);
        } while (gettr(&tr));

        return EXIT_SUCCESS;
}
Ejemplo n.º 12
0
int
main(int argc, char **argv)
{
	FILE *headerfp=NULL;	/* temporary file for trace header	*/
				/*  ... (1st trace of ensemble);	*/
	char *key=NULL;		/* header key word from segy.h		*/
	char *type=NULL;	/* ... its type				*/
	int index;		/* ... its index			*/
	Value val;		/* ... its value			*/
	float fval = 0;		/* ... its value cast to float		*/
	float prevfval;		/* ... its value of the previous trace	*/

	complex *ct=NULL;	/* complex trace			*/
	complex *psct=NULL;	/* phase-stack data array		*/

	float *data=NULL;	/* input data array			*/
	float *hdata=NULL;	/* array of Hilbert transformed input data */
	float *stdata=NULL;	/* stacked data ("ordinary" stack)	*/
	float *psdata;	/* phase-stack data array (real weights for PWS)*/
	float a;	/* inst. amplitude				*/
	float dt;	/* time sample spacing in seconds		*/
	float pwr;	/* raise  phase stack to power pwr		*/
	float sl;	/* smoothing window length in seconds		*/

	int gottrace;	/* flag: set to 1, if trace is read from stdin	*/

	int i;		/* loop index					*/
	int isl;	/* smoothing window length in samples		*/
	int nt;		/* number of points on input trace		*/
	int ntr;	/* trace counter				*/
	int ps;		/* flag: output is PWS (0) or phase stack (1)	*/
	int verbose;	/* verbose flag					*/

	cwp_Bool pws_and_cdp=cwp_false;	/* are PWS and CDP set?		*/

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

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

	/* Get parameters */
	if (!getparstring("key", &key))			key="cdp";
	if (!getparfloat("pwr", &pwr))			pwr = 1.0;
	if (!getparfloat("dt", &dt)) dt = ((double) intr.dt)/1000000.0;
	if (!getparfloat("sl", &sl))			sl = 0.0;
	if (!getparint("ps", &ps))			ps = 0;
	if (!getparint("verbose", &verbose))		verbose = 0;

	if (STREQ(key, "cdp") &&  !(ps))
		pws_and_cdp = cwp_true;

	/* convert seconds to samples (necessary only for smoothing) */
	if (!dt) {
		dt = 0.004;
		warn("dt not set, assuming dt=0.004");
	}

	/* integerized smoothing window length */
	isl = NINT(fabs(sl)/dt);
	if (isl>nt)
		err("sl=%g too long for trace", fabs(sl));

	/* diagnostic print */
	if (verbose && isl)
		warn("smoothing window = %d samples", isl);

	/* initialize flag */
	gottrace = 1;

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

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

	/* remember previous value of key */
	prevfval = fval;

	/* allocate space for data, hilbert transformed data, */
	/* phase-stacked data and complex trace */
	data = ealloc1float(nt);
	hdata = ealloc1float(nt);
	stdata = ealloc1float(nt);
	psdata = ealloc1float(nt);
	psct = ealloc1complex(nt);
	ct = ealloc1complex(nt);


	/* zero out accumulators */
	memset( (void *) stdata, 0, nt*FSIZE);
	memset( (void *) psct, 0, nt*(sizeof(complex)));


	/* open temporary file for trace header   */
	headerfp = etmpfile();

	/* store trace header in temporary file and read data */
	efwrite(&intr, HDRBYTES, 1, headerfp);

	/* loop over input traces */
	ntr=0;
	while (gottrace|(~gottrace) ) { /* middle exit loop */

		/* if got a trace */
		if (gottrace) {
			/* get value of key */
			gethval(&intr, index, &val);
			fval = vtof(type,val);

			/* get data */
			memcpy((void *) data, (const void *) intr.data,
					nt*FSIZE);
		}

		/* construct quadrature trace with hilbert transform */
		hilbert(nt, data, hdata);

		/* build the complex trace and get rid of amplitude */
		for (i=0; i<nt; i++) {
			ct[i] = cmplx(data[i],hdata[i]);
			a = (rcabs(ct[i])) ? 1.0 / rcabs(ct[i]) : 0.0;
			ct[i] = crmul(ct[i], a);
		}

		/* stacking */
		if (fval==prevfval && gottrace) {
			++ntr;
			for (i=0; i<nt; ++i) {
				stdata[i] += data[i];
				psct[i] = cadd(psct[i],ct[i]);
			}
		}

		/* if key-value has changed or no more input traces */
		if (fval!=prevfval || !gottrace) {

			/* diagnostic print */
			if (verbose)
				warn("%s=%g, fold=%d\n", key, prevfval, ntr);

			/* convert complex phase stack to real weights */
			for (i=0; i<nt; ++i) {
				psdata[i] = rcabs(psct[i]) / (float) ntr;
				psdata[i] = pow(psdata[i], pwr);
			}

			/* smooth phase-stack (weights) */
			if (isl) do_smooth(psdata,nt,isl);

			/* apply weights to "ordinary" stack (do PWS) */
			if (!ps) {
				for (i=0; i<nt; ++i) {
					stdata[i] *= psdata[i] / (float) ntr;
				}
			}

			/* set header and write PS trace or */
			/* PWS trace to stdout */
			erewind(headerfp);
			efread(&outtr, 1, HDRBYTES, headerfp);
			outtr.nhs=ntr;
			if (ps) {
				memcpy((void *) outtr.data,
					(const void *) psdata, nt*FSIZE);
			} else {
				memcpy((void *) outtr.data,
					(const void *) stdata, nt*FSIZE);
			}

			/* zero offset field if a pws and cdp stack */
			if (pws_and_cdp) outtr.offset = 0;

			puttr(&outtr);

			/* if no more input traces, break input trace loop* */
			if (!gottrace) break;


			/* remember previous value of key */
			prevfval = fval;

			/* zero out accumulators */
			ntr=0;
			memset( (void *) stdata, 0, nt*FSIZE);
			memset( (void *) psct, 0, nt*(sizeof(complex)));

			/* stacking */
			if (gottrace) {
				++ntr;
				for (i=0; i<nt; ++i) {
					stdata[i] += data[i];
					psct[i] = cadd(psct[i],ct[i]);
				}
			}

			/* save trace header for output trace */
			erewind(headerfp);
			efwrite(&intr, HDRBYTES, 1, headerfp);
		}

		/* get next trace (if there is one) */
		if (!gettr(&intr)) gottrace = 0;

	} /* end loop over traces */

	return(CWP_Exit());
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
0
static void dmooff (float offset, float fmax, int nx, float dx,
	int nt, float dt, float ft, float *vrms, float **ptx, float gamma,
	float *boh, float *zoh, int ntable, float s1, float s2, float sign)
/*****************************************************************************
perform dmo in f-k domain for one offset
******************************************************************************
Input:
offset		source receiver offset
fmax		maximum frequency
s1		DMO stretch factor
s2		DMO stretch factor
sign		sign of shift
nx		number of midpoints
dx		midpoint sampling interval
nt		number of time samples
dt		time sampling interval
ft		first time
vrms		array[nt] of rms velocities
ptx		array[nx][nt] for p(t,x), zero-padded for fft (see notes)

Output:
ptx		array[nx][nt] for dmo-corrected p(t,x)
******************************************************************************
Notes:
To avoid having to allocate a separate work space that is larger than the
array ptx[nx][nt], ptx must be zero-padded to enable Fourier transform from x
to k via prime factor FFT.  nxpad (nx after zero-padding) can be estimated by
	nxpad = 2+npfar(nx+(int)(0.5*ABS(offset/dx)));
where npfar() is a function that returns a valid length for real-to-complex
prime factor FFT.  ptx[nx] to ptx[nxfft-1] must point to zeros.
******************************************************************************
Author:  Dave Hale, Colorado School of Mines, 08/08/91
*****************************************************************************/
{
	int nxfft,itmin,nu,nufft,nw,nk,ix,iu,iw,ik,it,iwn,
		iwmin,iwmax,nupad,ikmax,*itn,lnt;
	float dw,dk,tcon,wwscl,wwscl2,scale,scales,kmax,lt,
		amp,phase,fr,fi,pwr,pwi,cphase,sphase,os1,os2,
		wmin,wmax,fftscl,du,fu,w,k,*uoft,*tofu,g1,h,vmin,hk,t,*bboh=NULL;
	complex czero=cmplx(0.0,0.0),**ptk,*pu,*pw;

	/* number of cdps after padding for fft */
	nxfft = npfar(nx+(int)(0.5*ABS(offset/dx)));

	/* get minimum time of first non-zero sample */
	for (ix=0,itmin=nt; ix<nx; ++ix) {
		for (it=0; it<itmin && ptx[ix][it]==0.0; ++it);
		itmin = it;
	}

	/* if all zeros, simply return */
	if (itmin>=nt) return;

	/* make stretch and compress functions t(u) and u(t) */
	maketu(offset,itmin,fmax,nt,dt,ft,vrms,&uoft,&nu,&du,&fu,&tofu,&tcon);

	/* constants depending on gamma, offset, vrms[0], and nt */
	g1 = 2.0*sqrt(gamma)/(1.0+gamma);
	h = offset/2.0;
	lnt = nt-1;
	lt = (nt-1)*dt;
	vmin = 0.5*MIN((1.0+1.0/gamma)*vrms[0],(1.0+gamma)*vrms[0]);

	/* if gamma != 1, get bboh[] and itn[] for this offset */
	if(gamma!=1.0)
		getbbohitn (offset,itmin,nt,dt,vrms,ntable,boh,zoh, \
		gamma,&bboh,&itn);

	/* inverse of dmo stretch/squeeze factors */
	os1 = 1.0/s1;
	os2 = 1.0/s2;

	/* maximum DMO shift (in samples) for any wavenumber k */
	nupad = 1.5*((s1+s2)/2.0)*tcon/du;

	/* frequency sampling */
	nufft = npfa(nu+nupad);
	nw = nufft;
	dw = 2.0*PI/(nufft*du);

	/* allocate workspace */
	pu = pw = ealloc1complex(nufft);

	/* wavenumber sampling and maximum wavenumber to apply dmo */
	nk = nxfft/2+1;
	dk = 2.0*PI/ABS(nxfft*dx);
	kmax = PI/ABS(dx);
	ikmax = NINT(kmax/dk);

	/* pointers to complex p(t,k) */
	ptk = (complex**)ealloc1(nk,sizeof(complex*));
	for (ik=0; ik<nk; ++ik)
		ptk[ik] = (complex*)ptx[0]+ik*nt;

	/* fft scale factor */
	fftscl = (float)nk/(float)(ikmax+1)/(nufft*nxfft);

	/* Fourier transform p(t,x) to p(t,k) */
	pfa2rc(-1,2,nt,nxfft,ptx[0],ptk[0]);

	/* loop over wavenumbers less than maximum */
	for (ik=0,k=0.0; ik<=ikmax; ++ik,k+=dk) {

		/* apply time vriant linear phase shift */
		hk=sign*h*k;
	 	for (it=lnt,t=lt; it>=itmin; --it,t-=dt) {

			/* calculate phase-shift=boh*h*k, h=offset/2 */
		 	if(gamma != 1.0)
			   phase = bboh[it]*hk;
			else
			   phase = 0.0;

			/* phase shift p(t,k) */
			cphase=cos(phase);
			sphase=sin(phase);
			fr = ptk[ik][it].r;
			fi = ptk[ik][it].i;
			ptk[ik][it].r = fr*cphase + fi*sphase;
			ptk[ik][it].i = -fr*sphase + fi*cphase;
		}

		/* stretch p(t;k) to p(u) */
		ints8c(nt,dt,ft,ptk[ik],czero,czero,nu,tofu,pu);

		/* pad with zeros and Fourier transform p(u) to p(w) */
		for (iu=nu; iu<nufft; ++iu)
			pu[iu].r = pu[iu].i = 0.0;
		pfacc(1,nufft,pu);

		/* minimum and maximum frequencies to process */
		wmin = ABS(0.5*vmin*k);
		wmax = ABS(PI/du);
		iwmin = MAX(1,MIN((nw-1)/2,NINT(wmin/dw)));
		iwmax = MAX(0,MIN((nw-1)/2,NINT(wmax/dw)));

		/* constant independent of w */
		wwscl = os1*pow(g1*hk/tcon,2.0);
		wwscl2 = wwscl*os2/os1;

		/* zero dc (should be zero anyway) */
		pw[0].r = pw[0].i = 0.0;

		/* zero frequencies below minimum */
		for (iw=1,iwn=nw-iw; iw<iwmin; ++iw,--iwn)
			pw[iw].r = pw[iw].i = pw[iwn].r = pw[iwn].i = 0.0;

		/* do dmo between minimum and maximum frequencies */
		for (iw=iwmin,iwn=nw-iwmin,w=iwmin*dw;
			iw<=iwmax; ++iw,--iwn,w+=dw) {

			/* positive w */
			scales = 1.0+wwscl/(w*w);
			scale = sqrt(scales);
			phase = s1*w*tcon*(scale-1.0);
			amp = fftscl*(1.0-s1+s1/scale);
			fr = amp*cos(phase);
			fi = amp*sin(phase);
			pwr = pw[iw].r;
			pwi = pw[iw].i;
			pw[iw].r = pwr*fr-pwi*fi;
			pw[iw].i = pwr*fi+pwi*fr;

			/* negative w */
			scales = 1.0+wwscl2/(w*w);
			scale = sqrt(scales);
			phase = s2*w*tcon*(scale-1.0);
			amp = fftscl*(1.0-s2+s2/scale);
			fr = amp*cos(phase);
			fi = amp*sin(phase);
			pwr = pw[iwn].r;
			pwi = pw[iwn].i;
			pw[iwn].r = pwr*fr+pwi*fi;
			pw[iwn].i = pwi*fr-pwr*fi;
		}

		/* zero frequencies above maximum to Nyquist (if present) */
		for (iw=iwmax+1,iwn=nw-iw; iw<=nw/2; ++iw,--iwn)
			pw[iw].r = pw[iw].i = pw[iwn].r = pw[iwn].i = 0.0;

		/* Fourier transform p(w) to p(u) */
		pfacc(-1,nufft,pu);

		/* compress p(u) to p(t;k) */
		ints8c(nu,du,fu,pu,czero,czero,nt,uoft,ptk[ik]);
	}

	/* zero wavenumber between maximum and Nyquist */
	for (; ik<nk; ++ik)
		for (it=0; it<nt; ++it)
			ptk[ik][it].r = ptk[ik][it].i = 0.0;

	/* Fourier transform p(t,k) to p(t,x) */
	pfa2cr(1,2,nt,nxfft,ptk[0],ptx[0]);

	/* free workspace */
	free1float(tofu);
	free1float(uoft);
	free1complex(pu);
	free1(ptk);
}
Ejemplo n.º 15
0
void dipfilt(float k,float dpx, float dt, int np, int nw, int nt, float
**div,complex *p,complex *q)
/*********************************************************************
Jacubowicz filter to apply dip-dependent divergence correction
**********************************************************************
Input:
k		wavenumber
dpx		dip sampling interval
dt		time sampling interval
np		number of reflection slopes
nt		number of time samples
nw		number of frequency samples
div		amplitude table
p		array[nt] containing input p(t,k)

Output:
q		array[nt] containing divergence corrected output q(t,k)
*********************************************************************/
{
	int ip,iw,it,iwl,iwh;
	float dw,wny,pscl,fftscl,pmin,ph,pm,pl;
	complex *kq,*qq;

	/* allocate workspace */
	kq = ealloc1complex(nw);
	qq = ealloc1complex(nw);

	dw = 2.0*PI/(nw*dt);
	wny = PI/dt;
	pscl = 0.5;
	fftscl = 1.0/nw;
	pmin = k/wny;
	
	/* initialize qq */
	for (iw=0; iw<nw; iw++){
		qq[iw].r = 0.0;
		qq[iw].i = 0.0;	
	}

	for (ip=np-1; ip>=0; ip--){

		ph=dpx*(ip+1);
		pm=dpx*ip;
		pl=dpx*(ip-1);

		/*if (ip==np-1) ph=pm;*/

		/* define frequency range */
		iwl = k/ph/dw + 1;
		iwh = k/pl/dw;

		if (pl<1.01*pmin) iwh = (nw%2 ? (nw-1)/2 : nw/2-1);
		if (pm<1.01*pmin) iwh = (nw%2 ? nw/2 : nw/2-1);

		/* sum over frequency */
		if (iwh>=iwl){
			for (it=0; it<nt; it++){
				kq[it].r = p[it].r*div[ip][it];
				kq[it].i = p[it].i*div[ip][it];
			}
			for (it=nt; it<nw; it++){
				kq[it].r = 0.0;
				kq[it].i = 0.0;
			}
			pfacc(1,nw,kq);

			/* dip filter positive frequencies */
			for (iw=iwl; iw<=iwh; iw++){
				qq[iw].r += kq[iw].r*pscl;
				qq[iw].i += kq[iw].i*pscl;
			}

			/* dip filter negative frequencies */
			iwl=nw-iwl;
			iwh=nw-iwh;

			for (iw=iwh; iw<=iwl; iw++){
				qq[iw].r += kq[iw].r*pscl;
				qq[iw].i += kq[iw].i*pscl;
			}
		}
		if (pm<1.01*pmin) break;
	}

	/* Fourier transform w to t */
	pfacc(-1,nw,qq);
	for (it=0; it<nt; it++){
		q[it].r = qq[it].r*fftscl;
		q[it].i = qq[it].i*fftscl;
	}

	/* free workspace */
	free1complex(kq);
	free1complex(qq);
}
Ejemplo n.º 16
0
int main( int argc, char *argv[] )
{
	cwp_String keyg;	/* header key word from segy.h		*/
	cwp_String typeg;	/* ... its type				*/
	Value valg;
	cwp_String key[SU_NKEYS];	/* array of keywords		 */
	cwp_String type[SU_NKEYS];	/* array of keywords		 */
	int index[SU_NKEYS];	/* name of type of getparred key	 */
	
	segy **rec_o;		/* trace header+data matrix */	
	
	int first=0;	/* true when we passed the first gather */
	int ng=0;
	float dt;	/* time sampling interval		*/
	int nt;		/* number of time samples per trace	*/
	int ntr;	/* number of traces per ensemble	*/
	
	int nfft=0;		/* lenghth of padded array		*/
	float snfft;		/* scale factor for inverse fft		*/
	int nf=0;		/* number of frequencies		*/
	float d1;		/* frequency sampling int.		*/
	float *rt;		/* real trace				*/
	complex *ctmix;		/* complex trace			*/
	complex **fd;		/* frequency domain data		*/

	
	float padd;
	
	int nd;			/* number of dimensions */
	float *dx=NULL;
	float fac;
	float vmin;
	int vf;
	
	/* Trimming arrays */
	float *itrm=NULL;
	float *rtrm=NULL;
	float *wht=NULL;
	float trimp=15;
		
	/* Initialize */
	initargs(argc, argv);
	requestdoc(1);
	
	if (!getparstring("keyg", &keyg)) keyg ="ep";
	if (!getparint("vf", &vf)) vf = 1;
	if (!getparfloat("vmin", &vmin)) vmin = 5000;
	if (!getparfloat("padd", &padd)) padd = 25.0;
	padd = 1.0+padd/100.0;
	
	/* Get "key" values */
	nd=countparval("key");
	getparstringarray("key",key);

	/* get types and indexes corresponding to the keys */
	{ int ikey;
		for (ikey=0; ikey<nd; ++ikey) {
			type[ikey]=hdtype(key[ikey]);
			index[ikey]=getindex(key[ikey]);
		}
	}

	dx = ealloc1float(nd);
	MUSTGETPARFLOAT("dx",(float *)dx);
	
	if (!getparfloat("fac", &fac)) fac = 1.0;
	fac = MAX(fac,1.0);

	/* get the first record */
	rec_o = get_gather(&keyg,&typeg,&valg,&nt,&ntr,&dt,&first);
	if(ntr==0) err("Can't get first record\n");
	
	/* set up the fft */
	nfft = npfar(nt*padd);
	if (nfft >= SU_NFLTS || nfft >= PFA_MAX)
		 	err("Padded nt=%d--too big", nfft);
	nf = nfft/2 + 1;
	snfft=1.0/nfft;
	d1 = 1.0/(nfft*dt);
	
	rt = ealloc1float(nfft);
	ctmix = ealloc1complex(nf);
	
	
	do {
		ng++;
		 	
		fd = ealloc2complex(nf,ntr); 
		memset( (void *) ctmix, (int) '\0', nf*sizeof(complex));
		
		itrm = ealloc1float(ntr);
		rtrm = ealloc1float(ntr);
		wht = ealloc1float(ntr);

		/* transform the data into FX domain */
		{ unsigned int itr;
			for(itr=0;itr<ntr;itr++) {
				memcpy( (void *) rt, (const void *) (*rec_o[itr]).data,nt*FSIZE);
				memset( (void *) &rt[nt], (int) '\0', (nfft - nt)*FSIZE);
				pfarc(1, nfft, rt, fd[itr]);
			
			}
		}
		
		/* Do the mixing */
		{ unsigned int imx=0,itr,ifr;
		  float dist;
		  
		  	
			/* Find the trace to mix */
			for(itr=0;itr<ntr;itr++) 
				if((*rec_o[itr]).mark) {
					imx = itr;
					break;
				}
			
			memcpy( (void *) ctmix, (const void *) fd[imx],nf*sizeof(complex));
			
			/* Save the header */
			memcpy( (void *) &tr, (const void *) rec_o[imx],HDRBYTES);
 		  	
			/* weights */
			wht[imx] = 1.0;
			for(itr=0;itr<imx;itr++) {
				 dist=n_distance(rec_o,index,type,dx,nd,imx,itr);
				 wht[itr] = MIN(1.0/dist,1.0);
				 wht[itr] = 1.0;
			}
			
			for(itr=imx+1;itr<ntr;itr++) {
				 dist=n_distance(rec_o,index,type,dx,nd,imx,itr);
				 wht[itr] = MIN(1.0/dist,1.0);
				 wht[itr] = 1.0;
			}
				 
			
			/* Do the alpha trim for each trace */			
			for(ifr=0;ifr<nf;ifr++) {
 		  		for(itr=0;itr<ntr;itr++) {
					itrm[itr] = fd[itr][ifr].i;
					rtrm[itr] = fd[itr][ifr].r;
				}
				ctmix[ifr].i = alpha_trim_w(itrm,wht,ntr,trimp);
				ctmix[ifr].r = alpha_trim_w(rtrm,wht,ntr,trimp);
			}
			
					
		}
		
		
		{ unsigned int it;
			pfacr(-1, nfft, ctmix, rt);
				for(it=0;it<nt;it++) 		
					tr.data[it]=rt[it]*snfft;
		}
			
		free2complex(fd);

		{ unsigned int itr;
			for(itr=0;itr<ntr;itr++) {
				free1((void *)rec_o[itr]);
			}
		}
		
		puttr(&tr);
		
	    	rec_o = get_gather(&keyg,&typeg,&valg,&nt,&ntr,&dt,&first);
		
		fprintf(stderr," %d %d\n",ng,ntr);
		
		free1float(rtrm);
		free1float(itrm);
		free1float(wht);
		
	} while(ntr);
		
	
	free1float(rt);

	warn("Number of gathers %10d\n",ng);
	 
	return EXIT_SUCCESS;
}
Ejemplo n.º 17
0
static void dmooff (float offset, float fmax, float sdmo, int nx, float dx,
	int nt, float dt, float ft, float *vrms, float **ptx)
/*****************************************************************************
perform dmo in f-k domain for one offset
******************************************************************************
Input:
offset		source receiver offset
fmax		maximum frequency
sdmo		DMO stretch factor
nx		number of midpoints
dx		midpoint sampling interval
nt		number of time samples
dt		time sampling interval
ft		first time
vrms		array[nt] of rms velocities 
ptx		array[nx][nt] for p(t,x), zero-padded for fft (see notes)

Output:
ptx		array[nx][nt] for dmo-corrected p(t,x)
******************************************************************************
Notes:
To avoid having to allocate a separate work space that is larger than the
array ptx[nx][nt], ptx must be zero-padded to enable Fourier transform from x
to k via prime factor FFT.  nxpad (nx after zero-padding) can be estimated by
	nxpad = 2+npfar(nx+(int)(0.5*ABS(offset/dx)));
where npfar() is a function that returns a valid length for real-to-complex 
prime factor FFT.  ptx[nx] to ptx[nxfft-1] must point to zeros.
******************************************************************************
Author:	 Dave Hale, Colorado School of Mines, 08/08/91
*****************************************************************************/
{
	int nxfft,itmin,nu,nufft,nw,nk,ix,iu,iw,ik,it,iwn,
		iwmin,iwmax,nupad,ikmax;
	float dw,dk,tcon,wwscl,scale,scales,kmax,
		amp,phase,fr,fi,pwr,pwi,
		wmin,wmax,fftscl,du,fu,w,k,osdmo,*uoft,*tofu; 
	complex czero=cmplx(0.0,0.0),**ptk,*pu,*pw;

	/* number of cdps after padding for fft */
	nxfft = npfar(nx+(int)(0.5*ABS(offset/dx)));

	/* get minimum time of first non-zero sample */
	for (ix=0,itmin=nt; ix<nx; ++ix) {
		for (it=0; it<itmin && ptx[ix][it]==0.0; ++it);
		itmin = it;
	}
	
	/* if all zeros, simply return */
	if (itmin>=nt) return;
	
	/* make stretch and compress functions t(u) and u(t) */
	maketu(offset,itmin,fmax,nt,dt,ft,vrms,&uoft,&nu,&du,&fu,&tofu,&tcon);

	/* adjust DMO stretch factor for nominal error in log stretch; */
	/* solve sdmo*(sqrt(1-a/sdmo)-1) = 0.5*log(1-a), where a=0.5 */
	sdmo *= .62;

	/* inverse of dmo stretch factor */
	osdmo = 1.0/sdmo;

	/* maximum DMO shift (in samples) for any wavenumber k */
	nupad = 1.5*sdmo*tcon/du;
	
	/* frequency sampling */
	nufft = npfa(nu+nupad);
	nw = nufft;
	dw = 2.0*PI/(nufft*du);
	
	/* allocate workspace */
	pu = pw = ealloc1complex(nufft);
	
	/* wavenumber sampling and maximum wavenumber to apply dmo */
	nk = nxfft/2+1;
	dk = 2.0*PI/ABS(nxfft*dx);
	kmax = PI/ABS(dx);
	ikmax = NINT(kmax/dk);

	/* pointers to complex p(t,k) */
	ptk = (complex**)ealloc1(nk,sizeof(complex*));
	for (ik=0; ik<nk; ++ik)
		ptk[ik] = (complex*)ptx[0]+ik*nt;
	
	/* fft scale factor */
	fftscl = (float)nk/(float)(ikmax+1)/(nufft*nxfft);
	
	/* Fourier transform p(t,x) to p(t,k) */
	pfa2rc(-1,2,nt,nxfft,ptx[0],ptk[0]);

	/* loop over wavenumbers less than maximum */
	for (ik=0,k=0.0; ik<=ikmax; ++ik,k+=dk) {

		/* stretch p(t;k) to p(u) */
		ints8c(nt,dt,ft,ptk[ik],czero,czero,nu,tofu,pu);
		
		/* pad with zeros and Fourier transform p(u) to p(w) */
		for (iu=nu; iu<nufft; ++iu)
			pu[iu].r = pu[iu].i = 0.0;
		pfacc(1,nufft,pu);

		/* minimum and maximum frequencies to process */
		wmin = ABS(0.5*vrms[0]*k);
		wmax = ABS(PI/du);
		iwmin = MAX(1,MIN((nw-1)/2,NINT(wmin/dw)));
		iwmax = MAX(0,MIN((nw-1)/2,NINT(wmax/dw)));
		
		/* constant independent of w */
		wwscl = osdmo*pow(k*0.5*offset/tcon,2.0);
		
		/* zero dc (should be zero anyway) */
		pw[0].r = pw[0].i = 0.0;

		/* zero frequencies below minimum */
		for (iw=1,iwn=nw-iw; iw<iwmin; ++iw,--iwn)
			pw[iw].r = pw[iw].i = pw[iwn].r = pw[iwn].i = 0.0;
		
		/* do dmo between minimum and maximum frequencies */
		for (iw=iwmin,iwn=nw-iwmin,w=iwmin*dw; 
			iw<=iwmax; ++iw,--iwn,w+=dw) {
			scales = 1.0+wwscl/(w*w);
			scale = sqrt(scales);
			phase = sdmo*w*tcon*(scale-1.0);
			amp = fftscl*(1.0-sdmo+sdmo/scale);
			fr = amp*cos(phase);
			fi = amp*sin(phase);
			pwr = pw[iw].r;
			pwi = pw[iw].i;
			pw[iw].r = pwr*fr-pwi*fi;
			pw[iw].i = pwr*fi+pwi*fr;
			pwr = pw[iwn].r;
			pwi = pw[iwn].i;
			pw[iwn].r = pwr*fr+pwi*fi;
			pw[iwn].i = pwi*fr-pwr*fi;
		}

		/* zero frequencies above maximum to Nyquist (if present) */
		for (iw=iwmax+1,iwn=nw-iw; iw<=nw/2; ++iw,--iwn)
			pw[iw].r = pw[iw].i = pw[iwn].r = pw[iwn].i = 0.0;
		
		/* Fourier transform p(w) to p(u) */
		pfacc(-1,nufft,pu);
		
		/* compress p(u) to p(t;k) */
		ints8c(nu,du,fu,pu,czero,czero,nt,uoft,ptk[ik]);
	}

	/* zero wavenumber between maximum and Nyquist */
	for (; ik<nk; ++ik)
		for (it=0; it<nt; ++it)
			ptk[ik][it].r = ptk[ik][it].i = 0.0;
	
	/* Fourier transform p(t,k) to p(t,x) */
	pfa2cr(1,2,nt,nxfft,ptk[0],ptx[0]);
	
	/* free workspace */
	free1float(tofu);
	free1float(uoft);
	free1complex(pu);
	free1(ptk);
}