Пример #1
0
void cr1_fft(complex *cdata, REAL *data, int n, int sign)
{
	int    j;
	double *datft;

	if (NINT(pow(2.0, (double)NINT(log((double)n)/log(2.0)))) != n) {
		if (npfar(n) == n) pfacr(sign,n,cdata,data);
		else crdft(cdata,data,n,sign);
	}
	else {
		datft = (double *)malloc(n*sizeof(double));
		if (datft == NULL) fprintf(stderr,"cr1_fft: memory allocation error\n");

		for (j = 0; j < n/2; j++) {
			datft[j] = (double)cdata[j].r;
			datft[n-1-j] = (double)cdata[j+1].i;
		}
		datft[n/2] = (double)cdata[n/2].r;

		realifft(n, datft);
	
		if (sign == -1) {
			for (j = 0; j < n; j++) data[j] = (REAL)datft[j];
		}
		else if (sign == 1) {
			for (j = 1; j < n; j++) data[j] = (REAL)datft[n-j];
			data[0] = (REAL)datft[0];
		}
	
		free(datft);
	}
	
	return;
}
Пример #2
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);
}
Пример #3
0
void crm_fft(complex *cdata, REAL *data, int n1, int n2, int ldc, int ldr, int sign)
{
	int    j, i;
	double *datft;

	if (NINT(pow(2.0, (double)NINT(log((double)n1)/log(2.0)))) != n1) {
		if (npfar(n1) == n1) {
			if (ldr == n1 && ldc == n2) {
				pfa2cr(sign, 1, n1, n2, cdata, data);
			}
			else {
				for (i = 0; i < n2; i++) {
					pfacr(sign, n1, &cdata[i*ldc], &data[i*ldr]);
				}
			}
		}
		else {
			for (i = 0; i < n2; i++) {
				crdft(&cdata[i*ldc], &data[i*ldr], n1, sign);
			}
		}
	}
	else {
		datft = (double *)malloc(n1*sizeof(double));
		if (datft == NULL) fprintf(stderr,"crm_fft: memory allocation error\n");
	
		for (i = 0; i < n2; i++) {
			for (j = 0; j < n1/2; j++) {
				datft[j] = (double)cdata[i*ldc+j].r;
				datft[n1-1-j] = (double)cdata[i*ldc+j+1].i;
			}
			datft[n1/2] = (double)cdata[i*ldc+n1/2].r;
	
			realifft(n1, datft);
	
			if (sign == -1) {
				for (j = 0; j < n1; j++) data[i*ldr+j] = (REAL)datft[j];
			}
			else if (sign == 1) {
				for (j = 1; j < n1; j++) data[i*ldr+j] = (REAL)datft[n1-j];
				data[i*ldr] = (REAL)datft[0];
			}
		}
	
		free(datft);
	}

	return;
}
Пример #4
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);
}
Пример #5
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;
}
Пример #6
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());
}
Пример #7
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());
}
Пример #8
0
/*                                              September 1995  */
#include "stratInv.h"
segy tr;		        /* reading data */
void inputData(char* dataFile)
{
   /* declaration of variables */
   int iS, iR, iF, iF1, iF2;    /* generic counters */
   int ns;			/* # of samples */
   int wL;                      /* window length */
   float *buffer = NULL;	/* to input data */
   float window;                /* windowing purposes */
   complex *bufferC = NULL;	/* to Fourier transform the input data */
   FILE *fp;			/* input file */

   /* memory for bufferC */
   bufferC = alloc1complex(info->nSamples / 2 + 1);
   
   fp = fopen(dataFile,"r");
   if (fp == NULL)
      err("Can't open input data file!\n");

   for (iR = 0; iR < info->nR; iR++)
   {
      fgettr(fp, &tr);
      ns = tr.ns;
      /* DD 
      fprintf(stderr, "ns %d\n", ns);*/

      /* allocating memory */
      if (iR == 0) buffer = alloc1float(MAX(ns, info->nSamples));

      /* reseting */
      for (iS = 0; iS < MAX(ns, info->nSamples); iS++) buffer[iS] = 0;
      memcpy(buffer, tr.data, ns * FSIZE);
      
      /* buffer -> dataObs and compensating for complex frequency */
      for (iS = 0; iS < info->nSamples; iS++)
      {
	 buffer[iS] *= exp(-info->tau * iS * dt);
	 /* DD 
	 fprintf(stderr, "buffer[%d] : %f\n", iS, buffer[iS]);*/
      }

      /* going to the Fourier domain */
      pfarc(-1, info->nSamples, buffer, bufferC);
      
      /* windowing (PERC_WINDOW) spectrum */
      iF1 = NINT(info->f1 / info->dF);
      iF2 = NINT(info->f2 / info->dF);
      wL = info->nF * PERC_WINDOW / 2;
      wL = 2 * wL + 1;
      for (iS = 0, iF = 0; iF < info->nSamples / 2 + 1; iF++)
      {
	 window = 0;
	 if (iF < iF1 || iF >= iF2)
	 {
	    bufferC[iF] = cmplx(0, 0);
	 }
	 else if (iF - iF1 < (wL - 1) / 2)
	 {
	    window =
	       .42 - .5 * cos(2 * PI * (float) iS / ((float) (wL - 1))) +
		  .08 * cos(4 * PI * (float) iS / ((float) (wL - 1)));
	    bufferC[iF].r *= window; bufferC[iF].i *= window;
	    iS++;
	 }
	 else if (iF - iF1 >= info->nF - (wL - 1) / 2)
	 {
	    iS++;
	    window =
	       .42 - .5 * cos(2 * PI * (float) iS / ((float) (wL - 1))) +
		  .08 * cos(4 * PI * (float) iS / ((float) (wL - 1)));
	    bufferC[iF].r *= window; bufferC[iF].i *= window;
	 }
      }

      /* going back to time domain */
      pfacr(1, info->nSamples, bufferC, buffer);

      /* copying to dataObs within target window and scaling */
      for (iF = 0, iS = NINT(t1 / dt); iS <= NINT(t2 / dt); iS++, iF++)
      {
	 dataObs[iR][iF] = (scaleData * buffer[iS]) / (float) info->nSamples;
	 /* DD 
	 fprintf(stderr, "%d %d %f %f %f %f\n", iR, iF, dataObs[iR][iF], 
		 info->f1, info->f2, scaleData);*/
      }
   }
   /* DD 
   fprintf(stderr, "energy %f\n", auxm1 / (nDM * info->nR));
   fwrite(&dataObs[0][0], sizeof(float), nDM * info->nR, stdout);
   exit(-1);*/
   
   /* freeing memory */
   free1float(buffer);
   free1complex(bufferC);

   fclose(fp); 
}
Пример #9
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;
}
Пример #10
0
float modeling()
{
   /* declaration of variables */
   FILE *fp;                       /* to report results */
   int iF, iF1, iR, offset, iT1, iT2, iS, iProc, i, k;
                                   /* counters */
   int wL;                         /* window length */
   int die;                        /* die processor flag */
   int FReceived;                  /* number of frequencies processed */
   int apl_pid;                    /* PVM process id control */
   int pid;                        /* process id */
   int processControl;             /* monitoring PVM start */
   int FInfo[2];                   /* frequency delimiters */
   float wallcpu;                  /* wall clock time */
   float oF;                       /* value of the objective function */
   float residue;                  /* data residue */
   float wdw;                      /* windowing purposes */
   float *buffer, *bufferRCD;      /* auxiliary buffers */
                                   /* upgoing waves */
   complex **dataS;                /* synthethics in the frequency domain */
   complex *bufferC;               /* auxiliary buffer */
   complex **freqPart;             /* frequency arrays sent by the slaves */
   
   /* Clean up log files */
   CleanLog();

   /* Reseting synchronization flags */
   for (i = 0; i < nFreqPart; i++)
   {
      statusFreq[i][2] = 0;
   }
    
   /* allocating some memory */
   dataS = alloc2complex(info->nF, info->nR);
   buffer = alloc1float(info->nSamples);
   bufferRCD = alloc1float(info->nSamples);
   bufferC = alloc1complex(info->nSamples / 2 + 1);
   freqPart = alloc2complex(info->nFreqProc, info->nR);

   /* reseting */
   for (iF = 0; iF < info->nSamples / 2 + 1; iF++)
      bufferC[iF] = zeroC;
   for (iS = 0; iS < info->nSamples; iS++)
   {
      buffer[iS] = 0; bufferRCD[iS] = 0;
   }

   /* DD 
   fprintf(stderr, "nF -> %d\n", info->nF);*/
   fprintf(stderr, "Starting communication with PVM for modeling\n");

   /* starting communication with PVM */
   if ((apl_pid = pvm_mytid()) < 0) 
   {
      pvm_perror("Error enrolling master process");
      exit(-1);
   }
   processControl = CreateSlaves(processes, PROCESS_MODELING, nProc);
   
   if (processControl != nProc)
   {
      fprintf(stderr,"Problem starting PVM daemons\n");
      exit(-1);
   }

   /* converting to velocities */
   if (IMPEDANCE)
   {
      for (i = 0; i < info->nL + 1; i++)
      {
         alpha[i] /= rho[i];
         beta[i] /= rho[i];
      }
   }
   
   /* Broadcasting all processes common information */
   BroadINFO(info, 1, processes, nProc, GENERAL_INFORMATION);
   
   /* sending all profiles */
   BroadFloat(thick, info->nL + 1, processes, nProc, THICKNESS);
   BroadFloat(rho, info->nL + 1, processes, nProc, DENSITY);
   BroadFloat(alpha, info->nL + 1, processes, nProc, ALPHAS);
   BroadFloat(qP, info->nL + 1, processes, nProc, QALPHA);
   BroadFloat(beta, info->nL + 1, processes, nProc, BETAS);
   BroadFloat(qS, info->nL + 1, processes, nProc, QBETA);
   
   /* sending frequency partitions for each process */
   for (iProc = 0; iProc < nProc; iProc++)
   {
      FInfo[0] = statusFreq[iProc][0];
      FInfo[1] = statusFreq[iProc][1];

      if (info->verbose)
	 fprintf(stderr, 
		 "Master sending frequencies [%d, %d] out of %d to slave Modeling %d [id:%d]\n", FInfo[0], FInfo[1], info->nF, iProc, processes[iProc]);
      
      procInfo[iProc][0] = FInfo[0];
      procInfo[iProc][1] = FInfo[1];
      SendInt(FInfo, 2, processes[iProc], FREQUENCY_LIMITS);
      statusFreq[iProc][2] = 1;
   }

   /* waiting modelled frequencies */
   /* master process will send more frequencies if there's more work to do */
   /* measuring elapsed time */
   wallcpu = walltime();

   /* reseting frequency counter */
   FReceived = 0;

   while (FOREVER)
   {
      pid = RecvCplx(freqPart[0], info->nR * info->nFreqProc, -1, 
		     FREQUENCY_PARTITION);

      /* finding the frequency limits of this process */
      /* DD 
      fprintf(stderr, "Master finding the frequency limits of this process\n");
      */

      iProc = 0;
      while (pid != processes[iProc])
	 iProc++;

      /* DD 
      fprintf(stderr, "iProc %d pid %d\n", iProc, pid);*/

      /* copying into proper place of the total frequency array */
      for (iR = 0; iR < info->nR; iR++)
      {
	 for (k = 0, i = procInfo[iProc][0]; i <= procInfo[iProc][1]; i++, k++)
	 {
	    dataS[iR][i - initF] = freqPart[iR][k];
	 }
      }
      
      /* summing frequencies that are done */
      FReceived += procInfo[iProc][1] - procInfo[iProc][0] + 1;

      if (info->verbose)
	 fprintf(stderr, "Master received %d frequencies, remaining %d\n", 
		 FReceived, info->nF - FReceived);

      /* defining new frequency limits */
      i = 0;
      while (i < nFreqPart && statusFreq[i][2])
	 i++;

      /* DD 
      fprintf(stderr, "i %d nFreqPart %d\n", i, nFreqPart);*/
      
      if (i < nFreqPart)
      {
	 /* there is still more work to be done */
	 /* tell this process to not die */
	 die = 0;
	 SendInt(&die, 1, processes[iProc], DIE);
	 FInfo[0] = statusFreq[i][0];
	 FInfo[1] = statusFreq[i][1];

	 if (info->verbose)
	    fprintf(stderr, "Master sending frequencies [%d, %d] to slave %d\n", FInfo[0], FInfo[1], processes[iProc]);

	 procInfo[iProc][0] = FInfo[0];
	 procInfo[iProc][1] = FInfo[1];
	 SendInt(FInfo, 2, processes[iProc], FREQUENCY_LIMITS);
	 statusFreq[i][2] = 1;
      }
      else
      {
	 /* tell this process to die since there is no more work to do */
	 if (info->verbose)
	    fprintf(stderr, "Master ''killing'' slave %d\n", processes[iProc]);
	 die = 1;
	 SendInt(&die, 1, processes[iProc], DIE);
      }

      /* a check to get out the loop */
      if (FReceived >= info->nF) break;
   }
   
   /* quitting PVM */
   EndOfMaster();
   
   /* getting elapsed time */
   wallcpu = walltime() - wallcpu;
   fprintf(stderr, "Modeling wall clock time = %f seconds\n", 
	   wallcpu);
     
   /* back to impedances*/
   if (IMPEDANCE)
   {
      for (i = 0; i < info->nL + 1; i++)
      {
         alpha[i] *= rho[i];
         beta[i] *= rho[i];
      }
   }

   /* computing the objective function for the time window */
   for (oF = 0, residue = 0, iR = 0; iR < info->nR; iR++)
   {
      /* windowing as it was done to the input data */
      iT1 = NINT(info->f1 / info->dF);
      iT2 = NINT(info->f2 / info->dF);
      wL = info->nF * PERC_WINDOW / 2;
      wL = 2 * wL + 1;
      for (iS = 0, iF = 0; iF < info->nSamples / 2 + 1; iF++)
      {
	 if (iF < iT1 || iF >= iT2)
         {
            bufferC[iF] = cmplx(0, 0);
         }
         else if (iF - iT1 < (wL - 1) / 2)
         {
            wdw = .42 - .5 * cos(2 * PI * (float) iS / ((float) (wL - 1))) +
                  .08 * cos(4 * PI * (float) iS / ((float) (wL - 1)));
	    bufferC[iF].r = dataS[iR][iF - iT1].r * wdw;
	    bufferC[iF].i = dataS[iR][iF - iT1].i * wdw;
            iS++;
         }
         else if (iF - iT1 >= info->nF - (wL - 1) / 2)
         {
            iS++;
            wdw = .42 - .5 * cos(2 * PI * (float) iS / ((float) (wL - 1))) +
                  .08 * cos(4 * PI * (float) iS / ((float) (wL - 1)));
	    bufferC[iF].r = dataS[iR][iF - iT1].r * wdw;
	    bufferC[iF].i = dataS[iR][iF - iT1].i * wdw;
         }
	 else
	 {
	    bufferC[iF] = dataS[iR][iF - iT1];
	 }
      }
      
      /* going to time domain */
      /* DD 
      fprintf(stderr, "going to time domain \n");*/

      pfacr(1, info->nSamples, bufferC, buffer);

      /* muting ? */
      if (MUTE)
      {
         for (iS = 0; iS <= NINT(t1Mute[iR] / dt); iS++)
         {
	    buffer[iS] = 0;
         }
      }

      /* and computing data misfit and likelihood function */
      iS = NINT(t1 / dt);
      for (iT1 = 0; iT1 < nDM; iT1++)
      {
	 bufferRCD[iT1 + iS] = 0;

	 for (offset = iT1, iT2 = 0; iT2 < nDM; iT2++)
	 {
	    bufferRCD[iT1 + iS] +=  
	                   (buffer[iT2 + iS] - dataObs[iR][iT2]) * CD[offset];
	    offset += MAX(SGN0(iT1 - iT2) * (nDM - 1 - iT2), 1);
	 }
	 oF += (buffer[iT1 + iS] - dataObs[iR][iT1]) * bufferRCD[iT1 + iS];

	 residue += (buffer[iT1 + iS] - dataObs[iR][iT1]) * 
                    (buffer[iT1 + iS] - dataObs[iR][iT1]);

	 /* DD 
	 fprintf(stdout, "%d %f %f %f %f %f %d %f %f\n", 
		 nTotalSamples, oF, dt, auxm1, 
		 info->tau, residue, iT1, buffer[iT1], 
		 dataObs[iR][iT1 - NINT(t1 / dt)]); */
      }

      /* windowing bufferRCD */
      iT1 = NINT(t1 / dt);
      iT2 = NINT(t2 / dt);
      wL = nDM * PERC_WINDOW / 2;
      wL = 2 * wL + 1;
      for (iS = 0, iF = 0; iF < info->nSamples; iF++)
      {
         if (iF < iT1 || iF >= iT2)
         {
            bufferRCD[iF] = 0;
         }
	 else if (iF - iT1 < (wL - 1) / 2)
         {
            wdw =
               .42 - .5 * cos(2 * PI * (float) iS / ((float) (wL - 1))) +
                  .08 * cos(4 * PI * (float) iS / ((float) (wL - 1)));
            bufferRCD[iF] *= wdw;
            iS++;
         }
         else if (iF - iT1 >= nDM - (wL - 1) / 2)
         {
            iS++;
            wdw =
               .42 - .5 * cos(2 * PI * (float) iS / ((float) (wL - 1))) +
                  .08 * cos(4 * PI * (float) iS / ((float) (wL - 1)));
            bufferRCD[iF] *= wdw;
         }
      }
      
      /* going back to Fourier domain */
      pfarc(-1, info->nSamples, bufferRCD, bufferC);          
      
      for (iF1 = 0, iF = NINT(info->f1 / info->dF); 
	   iF <= NINT(info->f2 / info->dF); iF++, iF1++)
      {
	 resCD[iR][iF1] = bufferC[iF];
      }
   }

   /* considering the .5 factor of the exponent of the Gaussian */
   /* and normalizing the likelihood by the number of samples */
   oF /= (2 * nTotalSamples);

   /* freeing some memory */
   /* allocating some memory */
   free2complex(dataS);
   free1float(buffer);
   free1float(bufferRCD);
   free1complex(bufferC);
   free2complex(freqPart);

   /* considering the regularizaton or model covariance term */
   if (PRIOR)
   {
      auxm1 = 1. / (float) (numberPar * limRange);     /* normalization */
      for (auxm2 = 0, iF = 0; iF < limRange; iF++)
      {
	 for (offset = iF, iF1 = 0; iF1 < limRange; iF1++)
	 {
	    if (vpFrechet)
	    {
	       auxm2 += (alpha[iF + lim[0]] - alphaMean[iF + lim[0]]) * 
		         CMvP[offset] * auxm1 * 
		        (alpha[iF1 + lim[0]] - alphaMean[iF1 + lim[0]]);
	    }
	    
	    if (vsFrechet)
	    {
	       auxm2 += (beta[iF + lim[0]] - betaMean[iF + lim[0]]) * 
	                 CMvS[offset] * auxm1 *
		        (beta[iF1 + lim[0]] - betaMean[iF1 + lim[0]]);
	    }
	    
	    if (rhoFrechet)
	    {
	       auxm2 += (rho[iF + lim[0]] - rhoMean[iF + lim[0]]) * 
		         CMrho[offset] * auxm1 *
		        (rho[iF1 + lim[0]] - rhoMean[iF1 + lim[0]]);
	    }
	    offset += MAX(SGN0(iF - iF1) * (limRange - 1 - iF1), 1);
	 }
      }
   }
   /* getting normalization factor */
   fp = fopen("report", "a");
   fprintf(fp,"-----------------------\n");

   if (modCount == 0) 
   {
      oFNorm = oF;
      fprintf(fp,">> Normalization constant for objective function: %f <<\n",
	      oFNorm);
   }
   
   /* normalizing residue */
   residue /= (nTotalSamples);

   if (!DATACOV && noiseVar == 0) noiseVar = residue / 10.;
   
   if (PRIOR)
   {
      fprintf(fp,
      "residue at iteration [%d] : Data residue variance %f , Noise variance %f , Likelihood %f , Prior %f\n", 
      modCount, residue, noiseVar, oF / oFNorm, auxm2 / oFNorm);
   }
   else
   {
      fprintf(fp,"residue at iteration [%d] : Data residue variance %f , Noise variance %f , Likelihood %f , No Prior\n", modCount, residue, noiseVar, oF / oFNorm);
   }

   /* checking if we reached noise variance with the data residue */
   if (residue / noiseVar <= 1)
   {
      /* DATA IS FIT, stop the procedure */
      fprintf(fp, "[][][][][][][][][][][][][][][][][][][][]\n");
      fprintf(fp, "DATA WAS FIT UP TO 1 VARIANCE!\n");
      fprintf(fp, "[][][][][][][][][][][][][][][][][][][][]\n");
      exit(0);
   }
   
   /* adding Likelihood and Prior */
   if (PRIOR) oF += auxm2 / 2;
   fprintf(fp,"TOTAL residue at iteration [%d] : %f\n", 
	   modCount, oF / oFNorm);

   fprintf(fp,"-----------------------\n");
   fclose(fp);


   /* returning objective function value */
   return(oF / oFNorm);
}
Пример #11
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());
}
Пример #12
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;
}
Пример #13
0
main (int argc, char **argv)
{
   /* declaration of variables */
   FILE *fp;                     /* file pointer */
   char *auxChar;                /* auxiliar character */
   char *modelFile = " ";        /* elastic model file */
                                 /* THICK - RHO - VP - QP - VS - QS */
   int i, k, iProc, iR;          /* counters */
   int initF, lastF;             /* initial and final frequencies */
   int apl_pid;                  /* PVM process id control */
   int nSamplesOrig;             /* time series length */
   int die;                      /* flag used to kill processes */
   int pid;                      /* process id */
   int nProc;                    /* number of processes */
   int processControl;           /* monitoring PVM start */
   int *processes;               /* array with process ids */
   int FReceived;                /* number of frequencies processed */
   int nFreqProc;                /* number of frequencies per process */
   int nFreqPart;                /* number of frequency partitions */
   int **statusFreq;             /* monitors processed frequencies */
   int FInfo[2];                 /* frequency delimiters */
   int **procInfo;               /* frequency limits for each processor */ 
   float wallcpu;                /* wall clock time */
   float dt;                     /* time sampling interval */
   float f;                      /* current frequency */
   float fR;                     /* reference frequency */
   float tMax;                   /* maximum recording time */
   float *thick, *alpha, *beta,
   *rho, *qP, *qS;               /* elastic constants and thickness */
   complex **freqPart;           /* frequency arrays sent by the slaves */
   complex **uRF, **uZF;         /* final frequency components */
   INFO info[1];                 /* basic information for slaves */
   
   /* Logging information */
   /* CleanLog(); */

   /* getting input */
   initargs(argc, argv);
   requestdoc(0);
   
   if (!getparstring("model", &modelFile)) modelFile = "model";
   if (!getparstring("recfile", &auxChar)) auxChar = " ";
   sprintf(info->recFile, "%s", auxChar);
   if (!getparint("directwave", &info->directWave)) info->directWave = 1;
   if (!getparfloat("r1", &info->r1)) info->r1 = 0;
   if (!getparint("nr", &info->nR)) info->nR = 148;
   if (!getparfloat("dr", &info->dR)) info->dR = .025;
   if (!getparfloat("zs", &info->zs)) info->zs = 0.001;
   if (info->zs <= 0) info->zs = 0.001;
   if (!getparfloat("u1", &info->u1)) info->u1 = 0.0002;
   if (!getparfloat("u2", &info->u2)) info->u2 = 1.;
   if (!getparint("nu", &info->nU)) info->nU = 1000;
   if (!getparfloat("f1", &info->f1)) info->f1 = 2;
   if (!getparfloat("f2", &info->f2)) info->f2 = 50;
   if (!getparfloat("dt", &dt)) dt = 0.004;
   if (!getparfloat("tmax", &tMax)) tMax = 8;
   if (!getparfloat("F1", &info->F1)) info->F1 = 0;
   if (!getparfloat("F2", &info->F2)) info->F2 = 0;
   if (!getparfloat("F3", &info->F3)) info->F3 = 1;
   if (!getparint("hanning", &info->hanningFlag)) info->hanningFlag = 0;
   if (!getparfloat("wu", &info->percU)) info->percU = 5; info->percU /= 100;
   if (!getparfloat("ww", &info->percW)) info->percW = 5; info->percW /= 100;
   if (!getparfloat("fr", &fR)) fR = 1; info->wR = 2 * PI * fR;
   if (!getparfloat("tau", &info->tau)) info->tau = 50;
   if (!getparint("nproc", &nProc)) nProc = 1;
   if (!getparint("nfreqproc", &nFreqProc) || nProc == 1) nFreqProc = 0;
   if (!getparint("verbose", &info->verbose)) info->verbose = 0;

   /* how many layers */
   fp = fopen(modelFile,"r");
   if (fp == NULL)
      err("No model file!\n");

   info->nL = 0;
   while (fscanf(fp, "%f %f %f %f %f %f\n", 
		 &f, &f, &f, &f, &f, &f) != EOF)
      info->nL++;
   info->nL--;
   fclose(fp);

   if (info->verbose)
      fprintf(stderr,"Number of layers in model %s : %d\n", 
	      modelFile, info->nL + 1); 
   
   /* if specific geometry, count number of receivers */
   fp = fopen(info->recFile, "r");
   if (fp != NULL)
   {
      info->nR = 0;
      while (fscanf(fp, "%f\n", &f) != EOF)
	 info->nR++;
   }
   fclose(fp);

   /* memory allocation */
   alpha = alloc1float(info->nL + 1);
   beta = alloc1float(info->nL + 1);
   rho = alloc1float(info->nL + 1);
   qP = alloc1float(info->nL + 1);
   qS = alloc1float(info->nL + 1);
   thick = alloc1float(info->nL + 1);
   processes = alloc1int(nProc);
   procInfo = alloc2int(2, nProc);

   /* reading the file */
   fp = fopen(modelFile,"r");
   if (info->verbose)
      fprintf(stderr,"Thickness     rho     vP     qP    vS     qS\n");
   for (i = 0; i < info->nL + 1; i++)
   {
      fscanf(fp, "%f %f %f %f %f %f\n", &thick[i], &rho[i], &alpha[i], 
	     &qP[i], &beta[i], &qS[i]);
      if (info->verbose)
	 fprintf(stderr,"   %7.4f      %4.3f   %3.2f  %5.1f  %3.2f  %5.1f\n",
		 thick[i], rho[i], alpha[i], qP[i], beta[i], qS[i]);
   }
   fclose(fp);

   /* computing frequency interval */
   info->nSamples = NINT(tMax / dt) + 1;
   nSamplesOrig = info->nSamples;
   info->nSamples = npfar(info->nSamples);

   /* slowness increment */
   info->dU = (info->u2 - info->u1) / (float) info->nU;

   /* computing more frequency related quatities */
   tMax = dt * (info->nSamples - 1);
   info->dF = 1. / (tMax);   
   f = info->dF;
   while (f < info->f1) f += info->dF;
   info->f1 = f;
   while (f < info->f2) f += info->dF;
   info->f2 = f; 
   initF = NINT(info->f1 / info->dF);
   lastF = NINT(info->f2 / info->dF);
   info->nF = lastF - initF + 1; 
   if (info->nF%2 == 0) 
   {
      info->nF++;
      lastF++;
   }
 
   /* attenuation of wrap-around */
   info->tau = log(info->tau) / tMax;
   if (info->tau > TAUMAX)
      info->tau = TAUMAX;
      
   if (info->verbose)
      fprintf(stderr, "Discrete frequency range to model: [%d, %d]\n", 
	      initF, lastF);
   
   if (nFreqProc == 0)
      nFreqProc = NINT((float) info->nF / (float) nProc + .5);
   else
      while (nFreqProc > info->nF) nFreqProc /= 2;
   nFreqPart = NINT((float) info->nF / (float) nFreqProc + .5);

   /* memory allocation for frequency arrays */
   uRF = alloc2complex(info->nSamples / 2 + 1, info->nR);
   uZF = alloc2complex(info->nSamples / 2 + 1, info->nR);
   freqPart = alloc2complex(nFreqProc, info->nR);
   statusFreq = alloc2int(3, nFreqPart);

   /* defining frequency partitions */
   for (k = initF, i = 0; i < nFreqPart; i++, k += nFreqProc)
   {
      statusFreq[i][0] = k;
      statusFreq[i][1] = MIN(k + nFreqProc - 1, lastF);
      statusFreq[i][2] = 0;       
   }

   if (info->verbose)
      fprintf(stderr, "Starting communication with PVM\n");
   
   /* starting communication with PVM */
   if ((apl_pid = pvm_mytid()) < 0) 
   {
      err("Error enrolling master process");
      /* exit(-1); */
   } 
   fprintf(stderr, "Starting %d slaves ... ", nProc);
   processControl = CreateSlaves(processes, PROCESS, nProc);
   if (processControl != nProc)
   {
      err("Problem starting Slaves (%s)\n", PROCESS);
      /* exit(-1); */
   }
   fprintf(stderr, " Ready \n");

   info->nFreqProc = nFreqProc;
   /* Broadcasting all processes common information */
   BroadINFO(info, 1, processes, nProc, GENERAL_INFORMATION);
   
   if (info->verbose) {
      fprintf(stderr, "Broadcasting model information to all slaves\n");
      fflush(stderr);
   }

   /* sending all profiles */
   BroadFloat(thick, info->nL + 1, processes, nProc, THICKNESS);
   BroadFloat(rho, info->nL + 1, processes, nProc, DENSITY);
   BroadFloat(alpha, info->nL + 1, processes, nProc, ALPHA);
   BroadFloat(qP, info->nL + 1, processes, nProc, QALPHA);
   BroadFloat(beta, info->nL + 1, processes, nProc, BETA);
   BroadFloat(qS, info->nL + 1, processes, nProc, QBETA);

   /* freeing memory */
   free1float(thick);
   free1float(rho);
   free1float(alpha);
   free1float(qP);
   free1float(beta);
   free1float(qS);

   /* sending frequency partitions for each process */
   for (iProc = 0; iProc < nProc; iProc++)
   {
      FInfo[0] = statusFreq[iProc][0];
      FInfo[1] = statusFreq[iProc][1];

      if (info->verbose) {
	 fprintf(stderr, 
	 "Master sending frequencies [%d, %d] out of %d to slave %d [id:%d]\n"
	  ,FInfo[0], FInfo[1], info->nF, iProc, processes[iProc]);
         fflush(stderr);
      }

      procInfo[iProc][0] = FInfo[0]; procInfo[iProc][1] = FInfo[1];
      SendInt(FInfo, 2, processes[iProc], FREQUENCY_LIMITS);
      statusFreq[iProc][2] = 1;
   }

   /* waiting modelled frequencies */
   /* master process will send more frequencies if there's more work to do */
   /* measuring elapsed time */
   wallcpu = walltime();  
   
   /* reseting frequency counter */
   FReceived = 0;
   
   while (FOREVER)
   {
      pid = RecvCplx(freqPart[0], info->nR * nFreqProc, -1, 
		     FREQUENCY_PARTITION_VERTICAL);

      /* finding the frequency limits of this process */
      iProc = 0;
      while (pid != processes[iProc])
	 iProc++;

      /* copying into proper place of the total frequency array */
      for (iR = 0; iR < info->nR; iR++)
      {
	 for (k = 0, i = procInfo[iProc][0]; i <= procInfo[iProc][1]; i++, k++)
	 {
	    uZF[iR][i] = freqPart[iR][k];
	 }
      }

      pid = RecvCplx(freqPart[0], info->nR * nFreqProc, -1, 
		     FREQUENCY_PARTITION_RADIAL);
      
      /* finding the frequency limits of this process */
      iProc = 0;
      while (pid != processes[iProc])
	 iProc++;
   
      /* copying into proper place of the total frequency array */
      for (iR = 0; iR < info->nR; iR++)
      { 
	 for (k = 0, i = procInfo[iProc][0]; i <= procInfo[iProc][1]; i++, k++)
	 {
	    uRF[iR][i] = freqPart[iR][k];
	 }
      }

      /* summing frequencies that are done */
      FReceived += procInfo[iProc][1] - procInfo[iProc][0] + 1;

      if (info->verbose)
	 fprintf(stderr, "Master received %d frequencies, remaining %d\n", 
	      FReceived, info->nF - FReceived);

/*       if (FReceived >= info->nF) break; */

      /* defining new frequency limits */
      i = 0;
      while (i < nFreqPart && statusFreq[i][2])
	 i++;
      
      if (i < nFreqPart)
      {
	 /* there is still more work to be done */
	 /* tell this process to not die */
	 die = 0;
	 SendInt(&die, 1, processes[iProc], DIE);

	 FInfo[0] = statusFreq[i][0];
	 FInfo[1] = statusFreq[i][1];

	 if (info->verbose)
	    fprintf(stderr, 
		    "Master sending frequencies [%d, %d] to slave %d\n", 
		    FInfo[0], FInfo[1], processes[iProc]);
	 
	 procInfo[iProc][0] = FInfo[0]; procInfo[iProc][1] = FInfo[1];
	 SendInt(FInfo, 2, processes[iProc], FREQUENCY_LIMITS);
	 statusFreq[i][2] = 1;
      }
      else
      {
	 /* tell this process to die since there is no more work to do */
	 if (info->verbose)
	    fprintf(stderr, "Master ''killing'' slave %d\n", processes[iProc]);
	 die = 1;
	 SendInt(&die, 1, processes[iProc], DIE);
      }
      
      /* a check to get out the loop */
      if (FReceived >= info->nF) break; 
   }

   if (info->verbose)
      fprintf(stderr, "Master ''killing'' remaining slaves\n");

   /* getting elapsed time */
   wallcpu = walltime() - wallcpu;
   fprintf(stderr, "Wall clock time = %f seconds\n", wallcpu);  
   
   /* going to time domain */
   memset( (void *) &trZ, (int) '\0', sizeof(trZ));     
   memset( (void *) &trR, (int) '\0', sizeof(trR));     
   trZ.dt = dt * 1000000;
   trZ.ns = nSamplesOrig;
   trR.dt = dt * 1000000;
   trR.ns = nSamplesOrig;
   
   /* z component */
   for (iR = 0; iR < info->nR; iR++)
   {
      trZ.tracl = iR + 1;
      /* inverse FFT */
      pfacr(1, info->nSamples, uZF[iR], trZ.data); 
      for (i = 0; i < info->nSamples; i++)
      {
	 /* compensating for the complex frequency */
	 trZ.data[i] *= exp(info->tau * i * dt);
      }
      puttr(&trZ);
   }

   /* r component */
   for (iR = 0; iR < info->nR; iR++)
   {
      trR.tracl = info->nR + iR + 1;
      /* inverse FFT */
      pfacr(1, info->nSamples, uRF[iR], trR.data); 
      for (i = 0; i < info->nSamples; i++)
      {
	 /* compensating for the complex frequency */
	 trR.data[i] *= exp(info->tau * i * dt);
      }
      puttr(&trR);
   }
   return(EXIT_SUCCESS);
}   
Пример #14
0
int main( int argc, char *argv[] )
{
	cwp_String key;		/* header key word from segy.h		*/
	cwp_String type;	/* ... its type				*/
	Value val;
	segy **rec_o;		/* trace header+data matrix */
	int first=0;		/* true when we passed the first gather */
	int ng=0;
	float dt;
	int nt;
	int ntr;
	
	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 *ct;	       /* complex trace */
	complex **fd;		/* frequency domain data */
	float **cc;		/* correlation coefficinet matrix */
	
	float padd;
	float cch;
	float ccl;
		
	/* Initialize */
	initargs(argc, argv);
	requestdoc(1);
	
	if (!getparstring("key", &key))	key = "ep";
	if (!getparfloat("padd", &padd)) padd = 25.0;
	padd = 1.0+padd/100.0;
	
	if (!getparfloat("cch", &cch)) cch = 1.0;
	if (!getparfloat("ccl", &ccl)) ccl = 0.3;
	
	/* get the first record */
	rec_o = get_gather(&key,&type,&val,&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;
	
	rt = ealloc1float(nfft);
	
	do {
		ng++;

		fd = ealloc2complex(nf,ntr); 
       		cc = ealloc2float(nf,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]);
			}
		}
		
		/* Compute correlation coefficients */
		{ unsigned int itr,ifr;
			for(itr=0;itr<ntr-1;itr++) {
				for(ifr=0;ifr<nf-1;ifr++) { 
					cc[itr][ifr] = cos(PHSSP(fd[itr][ifr])-PHSSP(fd[itr+1][ifr])); 
				}			
			}
		
		}
		
		/* Filter */
		{ unsigned int itr,ifr;
			for(itr=0;itr<ntr-1;itr++) {
				for(ifr=0;ifr<nf-1;ifr++) { 
					if(cc[itr][ifr]> cch || cc[itr][ifr]<ccl) {
						fd[itr][ifr].r = 0.0; 
						fd[itr][ifr].i = 0.0;
					} 
				}			
			}
		
		}
		
		{ unsigned int itr,it;
			for(itr=0;itr<ntr;itr++) {
				
				pfacr(-1, nfft, fd[itr], rt);
				
				for(it=0;it<nt;it++) 		
                			(*rec_o[itr]).data[it]=rt[it]*snfft;
			}
		}
			
		free2complex(fd);
		free2float(cc);

	    	rec_o = put_gather(rec_o,&nt,&ntr);
	    	rec_o = get_gather(&key,&type,&val,&nt,&ntr,&dt,&first);
		
		fprintf(stderr," %d %d\n",ng,ntr);
		
	} while(ntr);
	
	free1float(rt);

	warn("Number of gathers %10d\n",ng);
	 
	return EXIT_SUCCESS;
}
Пример #15
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;
}
Пример #16
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);
}	
Пример #17
0
void gradient()
{
   /* declaration of variables */
   int i, indexF, iF, iR, iU, iDer, iL, iT, iT1;
                                   /* counters */
   float f;                        /* temporal frequency */
   float w;                        /* radian frequency */
   float u;                        /* slowness */
   float cte;                      /* a constant */
   float *buffer;                  /* auxiliary buffer */
   complex dUCEp1, dUCEp2;         /* dUC * epslon1 and dUC * epslon2 */     
   complex wCCte;                  /* auxiliar variable */ 
   complex am;                     /* vertical P-wave slownesses */
   complex amInv;                  /* 1. / am */
   complex amI;                    /* amI = am * I */
   complex bm;                     /* vertical S-wave slownesses */
   complex bmInv;                  /* 1. / bm */
   complex bmI;                    /* bmI = bm * I */
   complex As1, As2;               /* amplitudes of plane wave components (P)*/
   complex Cs1, Cs2;               /* amplitudes of plane wave components (S)*/
                                   /* downgoing waves */
   complex Bs1, Bs2;               /* amplitudes of plane wave components (P)*/
   complex Ds1, Ds2;               /* amplitudes of plane wave components (S)*/
                                   /* upgoing waves */
   complex g[2];                   /* phase-shift vector */ 
   complex ***displ;               /* Frechet derivative of the */
                                   /* displacements in the frequency domain */
   complex dpl;                    /* auxiliary variable */
   
   /* allocating memory */
   displ = alloc3complex(nSamples / 2 + 1, nR, numberPar * limRange);
   buffer = alloc1float(nSamples);
   
   /* auxiliar constant */
   cte = 1. / (4 * PI * rho[0]);

   /* reseting displ */
   for (iDer = 0; iDer < numberPar * limRange; iDer++)
      for (iR = 0; iR < nR; iR++)
	 for (iF = 0; iF < nSamples / 2 + 1; iF++)
	    displ[iDer][iR][iF] = zeroC;
   
   for (indexF = NINT(f1 / dF), f = f1, iF = 0; iF < nF; iF++, 
	f += dF, indexF++)
   {
      fprintf(stderr,"FRECHET derivatives at frequency (Hz): %f\n", f);
      /* reseting */   
      for (i = 0; i < numberPar * limRange; i++)
      {
	 for (iR = 0; iR < nR; iR++)
	 {  
	    aux11[i][iR] = zeroC;	         aux12[i][iR] = zeroC;
	    aux21[i][iR] = zeroC;	         aux22[i][iR] = zeroC;
	    aux11Old[i][iR] = zeroC;	         aux12Old[i][iR] = zeroC;
	    aux21Old[i][iR] = zeroC;	         aux22Old[i][iR] = zeroC;
	 }
      }
      
      w = 2 * PI * f;
      wC.r = w; wC.i = -tau;
      
      /* module and phase of complex frequency */
      wCR = sqrt(wC.r * wC.r + wC.i * wC.i);
      wCP = atan2(wC.i, wC.r);

      /* complex slowness step */
      dUC.r = w * dU / wCR;
      dUC.i = tau * dU / wCR;

      /* wCR / wR */
      wCRwR = wCR / wR;
      
      /* auxiliary variable */
      wCCte.r = wC.r * cte;
      wCCte.i = wC.i * cte;

      /* compute frequency-dependent horizontal slownesses (squared) */
      /* and also the s-wave VELOCITIES (squared) for all layers */
      horSlownessFrechet();
      
      for (u = u1, iU = 0; iU < nU; iU++, 
	   u += dU, uC.r += dUC.r, uC.i += dUC.i)
      {
	 uC.r = u;
	 uC.i = u * tau / wRef;
	 
	 uC2.r = 2 * uC.r;
	 uC2.i = 2 * uC.i;
	 
	 aux = uC.r * uC.r - uC.i * uC.i;
	 uuC.i = 2 * uC.r * uC.i;
	 uuC.r = aux;

	 uuC2.r = 2 * uuC.r;
	 uuC2.i = 2 * uuC.i;
	 
	 muC.r = uC.r * -1;
	 muC.i = uC.i * -1;

	 /* building reflectivity matrices */
	 RmFrechet();
		Rp();
	 
	 /* reseting */
	 As1 = zeroC;      As2 = zeroC;      /* downgoing waves */
	 Cs1 = zeroC;      Cs2 = zeroC;      /* downgoing waves */
	 Bs1 = zeroC;      Bs2 = zeroC;      /* upgoing waves */
	 Ds1 = zeroC;      Ds2 = zeroC;      /* upgoing waves */
	    
	 /* P-wave potential */
	 /* PSlowness^2 - uuC */
	 auxm1 = PSlowness[0][0].r - uuC.r;
	 auxm2 = PSlowness[0][0].i - uuC.i;
	 auxm3 = sqrt(auxm1 * auxm1 + auxm2 * auxm2);
	 auxm3 = sqrt(auxm3);
	 angle = atan2(auxm2, auxm1) / 2;
	 am.r = auxm3 * cos(angle);
	 am.i = auxm3 * sin(angle);

	 /* am * I */
	 amI.r = -am.i;
	 amI.i = am.r;
	    
	 As1 = uC;
	 if (directWave) Bs1 = muC;
	    
	 /* 1 / am */
	 aux = am.r * am.r + am.i * am.i;
	 amInv.r = am.r / aux;
	 amInv.i = -am.i / aux;
	 
	 /* amInv * uuC */
	 aux2.r = amInv.r * uuC.r - uuC.i * amInv.i;
	 aux2.i = amInv.r * uuC.i + amInv.i * uuC.r;

	 /* aux2 * -I */
	 As2.r = aux2.i;
	 As2.i = -aux2.r;

	 /* notice that Bs2 = As2 */
	 if (directWave) Bs2 = As2;
	 
	 /* S-wave potential */
	 /* SSlowness^2 - uuC */
	 auxm1 = SSlowness[0][0].r - uuC.r;
	 auxm2 = SSlowness[0][0].i - uuC.i;
	    
	 /* computing bm */
	 auxm3 = sqrt(auxm1 * auxm1 + auxm2 * auxm2);
	 auxm3 = sqrt(auxm3);
	 angle = atan2(auxm2, auxm1) / 2;
	 bm.r = auxm3 * cos(angle);
	 bm.i = auxm3 * sin(angle);

	 /* bm * I */
	 bmI.r = -bm.i;
	 bmI.i = bm.r;

	 /* 1 / bm */
	 aux = bm.r * bm.r + bm.i * bm.i;
	 bmInv.r = bm.r / aux;
	 bmInv.i = -bm.i / aux;

	 /* 1. / bm * uuC */
	 aux1.r = bmInv.r * uuC.r - bmInv.i * uuC.i;
	 aux1.i = bmInv.r * uuC.i + bmInv.i * uuC.r;
	 
	 /* notice that Cs1 = Ds1 */
	 Cs1 = aux1;
	 if (directWave) Ds1 = aux1;

	 Cs2.r = -uC.i;
	 Cs2.i = uC.r;

	 if (directWave)
	 {
            Ds2.r = -Cs2.r;
	    Ds2.i = -Cs2.i;
         }
	 
	 /* computing compensation for free-surface */
	 buildFreeSurfaceCompensation(am, bm);

	 /* computing phase shift (that's the matrix G in Muller's */
	 /* paper eq. (87) */
	 /* exp(j * am * wC * (-zs)) */
	 auxm1 = zs * (- amI.r * wC.r + amI.i * wC.i);
	 auxm2 = -zs * (amI.r * wC.i + amI.i * wC.r);
	 g[0].r = exp(auxm1) * cos(auxm2);
	 g[0].i = exp(auxm1) * sin(auxm2);

	 /* exp(j * bm * wC * (-zs)) */
	 auxm1 = zs * (- bmI.r * wC.r + bmI.i * wC.i);
	 auxm2 = -zs * (bmI.r * wC.i + bmI.i * wC.r);
	 g[1].r = exp(auxm1) * cos(auxm2);
	 g[1].i = exp(auxm1) * sin(auxm2);
	    
	 /* computing the product I - R-R+ */
	 auxm1 = rm[0][0].r * rp[0][0].r - rm[0][0].i * rp[0][0].i;
	 auxm2 = rm[0][0].r * rp[0][0].i + rm[0][0].i * rp[0][0].r;
	 auxm3 = rm[0][1].r * rp[1][0].r - rm[0][1].i * rp[1][0].i;
	 auxm4 = rm[0][1].r * rp[1][0].i + rm[0][1].i * rp[1][0].r;
         irr[0][0].r = 1 - (auxm1 + auxm3);
         irr[0][0].i = - (auxm2 + auxm4);

	 auxm1 = rm[0][0].r * rp[0][1].r - rm[0][0].i * rp[0][1].i;
	 auxm2 = rm[0][0].r * rp[0][1].i + rm[0][0].i * rp[0][1].r;
	 auxm3 = rm[0][1].r * rp[1][1].r - rm[0][1].i * rp[1][1].i;
	 auxm4 = rm[0][1].r * rp[1][1].i + rm[0][1].i * rp[1][1].r;
         irr[0][1].r = - (auxm1 + auxm3);
         irr[0][1].i = - (auxm2 + auxm4);

	 auxm1 = rm[1][0].r * rp[0][0].r - rm[1][0].i * rp[0][0].i;
	 auxm2 = rm[1][0].r * rp[0][0].i + rm[1][0].i * rp[0][0].r;
	 auxm3 = rm[1][1].r * rp[1][0].r - rm[1][1].i * rp[1][0].i;
	 auxm4 = rm[1][1].r * rp[1][0].i + rm[1][1].i * rp[1][0].r;
         irr[1][0].r = - (auxm1 + auxm3);
         irr[1][0].i = - (auxm2 + auxm4);

	 auxm1 = rm[1][0].r * rp[0][1].r - rm[1][0].i * rp[0][1].i;
	 auxm2 = rm[1][0].r * rp[0][1].i + rm[1][0].i * rp[0][1].r;
	 auxm3 = rm[1][1].r * rp[1][1].r - rm[1][1].i * rp[1][1].i;
	 auxm4 = rm[1][1].r * rp[1][1].i + rm[1][1].i * rp[1][1].r;
         irr[1][1].r = 1 - (auxm1 + auxm3);
         irr[1][1].i = - (auxm2 + auxm4);

	 /* inverting irr explicitly */
	 auxm1 = irr[0][0].r * irr[1][1].r - irr[0][0].i * irr[1][1].i;
	 auxm2 = irr[0][0].r * irr[1][1].i + irr[0][0].i * irr[1][1].r;
	 auxm3 = irr[0][1].r * irr[1][0].r - irr[0][1].i * irr[1][0].i;
	 auxm4 = irr[0][1].r * irr[1][0].i + irr[0][1].i * irr[1][0].r;
	 aux1.r = auxm1 - auxm3;
	 aux1.i = auxm2 - auxm4;

	 /* 1 / aux1 */
	 aux = aux1.r * aux1.r + aux1.i * aux1.i;
	 aux1.r = aux1.r / aux;
	 aux1.i = -aux1.i / aux;

	 /* Inverse of irr */
	 irrI[0][0].r = irr[1][1].r * aux1.r - irr[1][1].i * aux1.i;
	 irrI[0][0].i = irr[1][1].r * aux1.i + irr[1][1].i * aux1.r;
	 
	 irrI[0][1].r = -(irr[0][1].r * aux1.r - irr[0][1].i * aux1.i);
	 irrI[0][1].i = -(irr[0][1].r * aux1.i + irr[0][1].i * aux1.r);
	 
	 irrI[1][0].r = -(irr[1][0].r * aux1.r - irr[1][0].i * aux1.i);
	 irrI[1][0].i = -(irr[1][0].r * aux1.i + irr[1][0].i * aux1.r);

	 irrI[1][1].r = irr[0][0].r * aux1.r - irr[0][0].i * aux1.i;
	 irrI[1][1].i = irr[0][0].r * aux1.i + irr[0][0].i * aux1.r;

	 /* computing vectors V1,2, check eq (76) Muller's paper */
	 auxm1 = As1.r * rm[0][0].r - As1.i * rm[0][0].i;
	 auxm2 = As1.r * rm[0][0].i + As1.i * rm[0][0].r;
	 auxm3 = Cs1.r * rm[0][1].r - Cs1.i * rm[0][1].i;
	 auxm4 = Cs1.r * rm[0][1].i + Cs1.i * rm[0][1].r;
	 aux1.r = Bs1.r + (auxm1 + auxm3);
	 aux1.i = Bs1.i + (auxm2 + auxm4);

	 auxm1 = As1.r * rm[1][0].r - As1.i * rm[1][0].i;
	 auxm2 = As1.r * rm[1][0].i + As1.i * rm[1][0].r;
	 auxm3 = Cs1.r * rm[1][1].r - Cs1.i * rm[1][1].i;
	 auxm4 = Cs1.r * rm[1][1].i + Cs1.i * rm[1][1].r;
	 aux2.r = Ds1.r + (auxm1 + auxm3);
	 aux2.i = Ds1.i + (auxm2 + auxm4);

	 auxm1 = aux1.r * irrI[0][0].r - aux1.i * irrI[0][0].i;
	 auxm2 = aux1.r * irrI[0][0].i + aux1.i * irrI[0][0].r;
	 auxm3 = aux2.r * irrI[0][1].r - aux2.i * irrI[0][1].i;
	 auxm4 = aux2.r * irrI[0][1].i + aux2.i * irrI[0][1].r;
	 v1[0][0].r = auxm1 + auxm3;
	 v1[0][0].i = auxm2 + auxm4;

	 auxm1 = aux1.r * irrI[1][0].r - aux1.i * irrI[1][0].i;
	 auxm2 = aux1.r * irrI[1][0].i + aux1.i * irrI[1][0].r;
	 auxm3 = aux2.r * irrI[1][1].r - aux2.i * irrI[1][1].i;
	 auxm4 = aux2.r * irrI[1][1].i + aux2.i * irrI[1][1].r;
	 v1[0][1].r = auxm1 + auxm3;
	 v1[0][1].i = auxm2 + auxm4;

	 /* loop over "active" layers */
	 for (iDer = 1, i = 0; i < numberPar; i++)
	 {
	    /* i = 0 -> Vp  */
	    /* i = 1 -> Vs  */
	    /* i = 2 -> rho */
	    for (iL = MIN(lim[0], 2); iL < MIN(lim[0], 2) + limRange; 
		 iL++, iDer++)
	    {
	       /* rp * [v1[0], v1[1]] + (As1, Cs1)*/
	       auxm1 = rp[0][0].r * v1[0][0].r - rp[0][0].i * v1[0][0].i;
	       auxm2 = rp[0][0].r * v1[0][0].i + rp[0][0].i * v1[0][0].r;
	       auxm1 += rp[0][1].r * v1[0][1].r - rp[0][1].i * v1[0][1].i 
		     + As1.r;
	       auxm2 += rp[0][1].r * v1[0][1].i + rp[0][1].i * v1[0][1].r 
		     + As1.i;
	    
	       auxm3 = rp[1][0].r * v1[0][0].r - rp[1][0].i * v1[0][0].i;
	       auxm4 = rp[1][0].r * v1[0][0].i + rp[1][0].i * v1[0][0].r;
	       auxm3 += rp[1][1].r * v1[0][1].r - rp[1][1].i * v1[0][1].i 
		     + Cs1.r;
	       auxm4 += rp[1][1].r * v1[0][1].i + rp[1][1].i * v1[0][1].r 
		     + Cs1.i;

	       /* DmB[0][active layers][0 1 2 3] * */
	       /*                      ((auxm1, auxm2), (auxm3, auxm4)) */
	       aux1.r = auxm1 * DmB[0][i * limRange + iL][0].r 
		      - auxm2 * DmB[0][i * limRange + iL][0].i 
 	 	      + auxm3 * DmB[0][i * limRange + iL][1].r 
		      - auxm4 * DmB[0][i * limRange + iL][1].i;
	       aux1.i = auxm1 * DmB[0][i * limRange + iL][0].i 
		      + auxm2 * DmB[0][i * limRange + iL][0].r
		      + auxm3 * DmB[0][i * limRange + iL][1].i 
		      + auxm4 * DmB[0][i * limRange + iL][1].r;
	       
	       aux2.r = auxm1 * DmB[0][i * limRange + iL][2].r 
		      - auxm2 * DmB[0][i * limRange + iL][2].i 
		      + auxm3 * DmB[0][i * limRange + iL][3].r 
		      - auxm4 * DmB[0][i * limRange + iL][3].i;
	       aux2.i = auxm1 * DmB[0][i * limRange + iL][2].i 
		      + auxm2 * DmB[0][i * limRange + iL][2].r  
		      + auxm3 * DmB[0][i * limRange + iL][3].i 
		      + auxm4 * DmB[0][i * limRange + iL][3].r;
	       
	       /* irrI * (aux1, aux2) */
	       auxm1 = irrI[0][0].r * aux1.r - irrI[0][0].i * aux1.i;
	       auxm2 = irrI[0][0].r * aux1.i + irrI[0][0].i * aux1.r;
	       auxm3 = irrI[0][1].r * aux2.r - irrI[0][1].i * aux2.i;
	       auxm4 = irrI[0][1].r * aux2.i + irrI[0][1].i * aux2.r;
	       v1[iDer][0].r = auxm1 + auxm3;
	       v1[iDer][0].i = auxm2 + auxm4;

	       auxm1 = irrI[1][0].r * aux1.r - irrI[1][0].i * aux1.i;
	       auxm2 = irrI[1][0].r * aux1.i + irrI[1][0].i * aux1.r;
	       auxm3 = irrI[1][1].r * aux2.r - irrI[1][1].i * aux2.i;
	       auxm4 = irrI[1][1].r * aux2.i + irrI[1][1].i * aux2.r;
	       v1[iDer][1].r = auxm1 + auxm3;
	       v1[iDer][1].i = auxm2 + auxm4;
	    }
	 }

	 auxm1 = As2.r * rm[0][0].r - As2.i * rm[0][0].i;
	 auxm2 = As2.r * rm[0][0].i + As2.i * rm[0][0].r;
	 auxm3 = Cs2.r * rm[0][1].r - Cs2.i * rm[0][1].i;
	 auxm4 = Cs2.r * rm[0][1].i + Cs2.i * rm[0][1].r;
	 aux1.r = Bs2.r + (auxm1 + auxm3);
	 aux1.i = Bs2.i + (auxm2 + auxm4);

	 auxm1 = As2.r * rm[1][0].r - As2.i * rm[1][0].i;
	 auxm2 = As2.r * rm[1][0].i + As2.i * rm[1][0].r;
	 auxm3 = Cs2.r * rm[1][1].r - Cs2.i * rm[1][1].i;
	 auxm4 = Cs2.r * rm[1][1].i + Cs2.i * rm[1][1].r;
	 aux2.r = Ds2.r + (auxm1 + auxm3);
	 aux2.i = Ds2.i + (auxm2 + auxm4);

	 auxm1 = aux1.r * irrI[0][0].r - aux1.i * irrI[0][0].i;
	 auxm2 = aux1.r * irrI[0][0].i + aux1.i * irrI[0][0].r;
	 auxm3 = aux2.r * irrI[0][1].r - aux2.i * irrI[0][1].i;
	 auxm4 = aux2.r * irrI[0][1].i + aux2.i * irrI[0][1].r;
	 v2[0][0].r = auxm1 + auxm3;
	 v2[0][0].i = auxm2 + auxm4;

	 auxm1 = aux1.r * irrI[1][0].r - aux1.i * irrI[1][0].i;
	 auxm2 = aux1.r * irrI[1][0].i + aux1.i * irrI[1][0].r;
	 auxm3 = aux2.r * irrI[1][1].r - aux2.i * irrI[1][1].i;
	 auxm4 = aux2.r * irrI[1][1].i + aux2.i * irrI[1][1].r;
	 v2[0][1].r = auxm1 + auxm3;
	 v2[0][1].i = auxm2 + auxm4;

	 /* loop over "active" layers */
	 for (iDer = 1, i = 0; i < numberPar; i++)
	 {
	    /* i = 0 -> Vp  */
	    /* i = 1 -> Vs  */
	    /* i = 2 -> rho */
	    for (iL = MIN(lim[0], 2); iL < MIN(lim[0], 2) + limRange; 
		 iL++, iDer++)
	    {
	       /* rp * [v2[0], v2[1]] + (As2, Bs2) */
	       auxm1 = rp[0][0].r * v2[0][0].r - rp[0][0].i * v2[0][0].i;
	       auxm2 = rp[0][0].r * v2[0][0].i + rp[0][0].i * v2[0][0].r;
	       auxm1 += rp[0][1].r * v2[0][1].r - rp[0][1].i * v2[0][1].i 
		     + As2.r;
	       auxm2 += rp[0][1].r * v2[0][1].i + rp[0][1].i * v2[0][1].r 
		     + As2.i;

	       auxm3 = rp[1][0].r * v2[0][0].r - rp[1][0].i * v2[0][0].i;
	       auxm4 = rp[1][0].r * v2[0][0].i + rp[1][0].i * v2[0][0].r;
	       auxm3 += rp[1][1].r * v2[0][1].r - rp[1][1].i * v2[0][1].i 
		     + Cs2.r;
	       auxm4 += rp[1][1].r * v2[0][1].i + rp[1][1].i * v2[0][1].r 
		     + Cs2.i;

	       /* DmB[0][active layers][0 1 2 3] * */
	       /*                      ((auxm1, auxm2), (auxm3, auxm4)) */
	       aux1.r = auxm1 * DmB[0][i * limRange + iL][0].r 
	 	      - auxm2 * DmB[0][i * limRange + iL][0].i 
		      + auxm3 * DmB[0][i * limRange + iL][1].r 
		      - auxm4 * DmB[0][i * limRange + iL][1].i;
	       aux1.i = auxm1 * DmB[0][i * limRange + iL][0].i 
		      + auxm2 * DmB[0][i * limRange + iL][0].r 
		      + auxm3 * DmB[0][i * limRange + iL][1].i 
		      + auxm4 * DmB[0][i * limRange + iL][1].r;
	       
	       aux2.r = auxm1 * DmB[0][i * limRange + iL][2].r 
		      - auxm2 * DmB[0][i * limRange + iL][2].i  
		      + auxm3 * DmB[0][i * limRange + iL][3].r 
		      - auxm4 * DmB[0][i * limRange + iL][3].i;
	       aux2.i = auxm1 * DmB[0][i * limRange + iL][2].i 
		      + auxm2 * DmB[0][i * limRange + iL][2].r 
		      + auxm3 * DmB[0][i * limRange + iL][3].i 
		      + auxm4 * DmB[0][i * limRange + iL][3].r;
	       
	       /* irrI * (aux1, aux2) */
	       auxm1 = irrI[0][0].r * aux1.r - irrI[0][0].i * aux1.i;
	       auxm2 = irrI[0][0].r * aux1.i + irrI[0][0].i * aux1.r;
	       auxm3 = irrI[0][1].r * aux2.r - irrI[0][1].i * aux2.i;
	       auxm4 = irrI[0][1].r * aux2.i + irrI[0][1].i * aux2.r;
	       v2[iDer][0].r = auxm1 + auxm3;
	       v2[iDer][0].i = auxm2 + auxm4;
	       
	       auxm1 = irrI[1][0].r * aux1.r - irrI[1][0].i * aux1.i;
	       auxm2 = irrI[1][0].r * aux1.i + irrI[1][0].i * aux1.r;
	       auxm3 = irrI[1][1].r * aux2.r - irrI[1][1].i * aux2.i;
	       auxm4 = irrI[1][1].r * aux2.i + irrI[1][1].i * aux2.r;
	       v2[iDer][1].r = auxm1 + auxm3;
	       v2[iDer][1].i = auxm2 + auxm4;
	    }
	 }
	 
	 /* applying phase-shift to FRECHET derivatives */
	 /* loop over "active" layers */
	 for (iDer = 1; iDer <= numberPar * limRange; iDer++)
	 {
	    aux = v1[iDer][0].r * g[0].r - v1[iDer][0].i * g[0].i;
	    v1[iDer][0].i = v1[iDer][0].r * g[0].i + 
		            v1[iDer][0].i * g[0].r;
	    v1[iDer][0].r = aux;

	    aux = v1[iDer][1].r * g[1].r - v1[iDer][1].i * g[1].i;
	    v1[iDer][1].i = v1[iDer][1].r * g[1].i + 
	                    v1[iDer][1].i * g[1].r;
	    v1[iDer][1].r = aux;

	    aux = v2[iDer][0].r * g[0].r - v2[iDer][0].i * g[0].i;
	    v2[iDer][0].i = v2[iDer][0].r * g[0].i + 
	                    v2[iDer][0].i * g[0].r;
	    v2[iDer][0].r = aux;
	    
	    aux = v2[iDer][1].r * g[1].r - v2[iDer][1].i * g[1].i;
	    v2[iDer][1].i = v2[iDer][1].r * g[1].i + 
	                    v2[iDer][1].i * g[1].r;
	    v2[iDer][1].r = aux;
	 }

	 /* compensating for free surface */
	 freeSurfaceFrechet(v1, v2);
	 
	 /* loop over offsets for computing the displacements */
	 displacementsFrechet(iU);
      }
      /* displacements in the radial or vertical direction */
      /* (frequency domain) */
      /* there's a 2 (free surface) / 2 (trapezoidal integration) */
      /* simplified in the equation below */
      dUCEp1.r = epslon1 * dUC.r;
      dUCEp1.i = epslon1 * dUC.i;
      dUCEp2.r = epslon2 * dUC.r;
      dUCEp2.i = epslon2 * dUC.i;

      /* loop over "active" layers */
      for (iDer = 0; iDer < numberPar * limRange; iDer++)
      {
	 /* loop over offsets */
	 for (iR = 0; iR < nR; iR++)
	 {
	    /* radial ? */
	    if (RADIAL)
	    {
	       auxm1 = aux11[iDer][iR].r * dUCEp1.r - 
		       aux11[iDer][iR].i * dUCEp1.i;
	       auxm2 = aux11[iDer][iR].r * dUCEp1.i + 
		       aux11[iDer][iR].i * dUCEp1.r;
	       auxm3 = aux21[iDer][iR].r * dUCEp2.r - 
	               aux21[iDer][iR].i * dUCEp2.i;
	       auxm4 = aux21[iDer][iR].r * dUCEp2.i + 
	               aux21[iDer][iR].i * dUCEp2.r;
	 
	       dpl.i = (auxm1 + auxm3) * wCCte.r - (auxm2 + auxm4) * wCCte.i;
	       dpl.i = (auxm1 + auxm3) * wCCte.i + (auxm2 + auxm4) * wCCte.r;

	       /* filtering */
	       dpl.r *= window[indexF] * SGN(recArray[iR]);
	       dpl.i *= window[indexF] * SGN(recArray[iR]);
	    }
	    
	    if (VERTICAL)
	    {
	       auxm1 = aux12[iDer][iR].r * dUCEp1.r - 
		       aux12[iDer][iR].i * dUCEp1.i;
	       auxm2 = aux12[iDer][iR].r * dUCEp1.i + 
		       aux12[iDer][iR].i * dUCEp1.r;
	       auxm3 = aux22[iDer][iR].r * dUCEp2.r - 
	               aux22[iDer][iR].i * dUCEp2.i;
	       auxm4 = aux22[iDer][iR].r * dUCEp2.i + 
	               aux22[iDer][iR].i * dUCEp2.r;

	       dpl.r = (auxm1 + auxm3) * wCCte.r - (auxm2 + auxm4) * wCCte.i;
	       dpl.i = (auxm1 + auxm3) * wCCte.i + (auxm2 + auxm4) * wCCte.r;

	       /* filtering */
	       dpl.r *= window[indexF];
	       dpl.i *= window[indexF];
	    }
	    
	    /* storing displacements in matrix displ */
	    displ[iDer][iR][indexF] = dpl;
	 }
      }
   }

   /* going to time domain and correctig for tau */
   for (iDer = 0; iDer < numberPar; iDer++)
   {
      for (iL = 0; iL < limRange; iL++)
      {
	 for (iR = 0; iR < nR; iR++)
 	 {
	    pfacr(1, nSamples, displ[iDer * limRange + iL][iR], buffer);
	   
	    /* correcting for tau */
	    for (iT = 0; iT < nSamples; iT++)
	    {
	       buffer[iT] *= exp(tau * iT * dt);
	    }
 
	    /* copying to operator F */
	    iT1 = NINT(t1 / dt);
	    for (iT = 0; iT < nDM; iT++)
	    {
	       if (IMPEDANCE && vpFrechet && iDer == 0)
	       {
		  F[iDer * limRange + iL][iR * nDM + iT] = 
  	          buffer[iT1 + iT] / rho[iL + lim[0]];
	       }
	       else if (IMPEDANCE && vsFrechet && (iDer == 0 || iDer == 1))
	       {
		  F[iDer * limRange + iL][iR * nDM + iT] = 
		  buffer[iT1 + iT] / rho[iL + lim[0]];
	       }
	       else if (IMPEDANCE && rhoFrechet && iDer == 2)
	       {
		  F[iDer * limRange + iL][iR * nDM + iT] =
		  - alpha[iL + lim[0]] * F[iL][iR * nDM + iT] 
		  - beta[iL + lim[0]] * F[iL + limRange][iR * nDM + iT] 
  	          + buffer[iT1 + iT];
	       }
	       else if (!IMPEDANCE)
	       {
		  F[iDer * limRange + iL][iR * nDM + iT] = buffer[iT1 + iT] ;
	       }
	    }
	 }
      }
   }
   
   /* if in the IMPEDANCE domain rearrange matrix F */
   if (IMPEDANCE)
   {
      if (rhoFrechet && !ipFrechet && !isFrechet)
      {
	 for (iL = 0; iL < limRange; iL++)
	 {
	    for (iR = 0; iR < nR; iR++)
	    {
	       for (iT = 0; iT < nDM; iT++)
	       {
		  F[iL][iR * nDM + iT] = F[iL + 2 * limRange][iR * nDM + iT];
	       }
	    }
	 }
      }
      else if (rhoFrechet && ipFrechet && !isFrechet)
      {
	 for (iL = 0; iL < limRange; iL++)
	 {
	    for (iR = 0; iR < nR; iR++)
	    {
	       for (iT = 0; iT < nDM; iT++)
	       {
		  F[iL + limRange][iR * nDM + iT] = 
		     F[iL + 2 * limRange][iR * nDM + iT];
	       }
	    }
	 }
      }
      else if (rhoFrechet && !ipFrechet && isFrechet)   
      {
	 for (iL = 0; iL < limRange; iL++)
	 {
	    for (iR = 0; iR < nR; iR++)
	    {
	       for (iT = 0; iT < nDM; iT++)
	       {
		  F[iL][iR * nDM + iT] = F[iL + limRange][iR * nDM + iT];
		  F[iL + limRange][iR * nDM + iT] = 
		     F[iL + 2 * limRange][iR * nDM + iT];
	       }
	    }
	 }
      }
   }
   
   /* freeing memory */
   free3complex(displ);
   free1float(buffer);
}
Пример #18
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;
}