main() { int n,nc,nr,i; float *rz=(float*)cz; float cpucc,cpurc; for (nc=npfa(NMIN),nr=npfar(nc); nc<NMAX && nr<NMAX; nc=npfa(nc+1),nr=npfar(nc)) { for (i=0; i<nc*nc; i++) cz[i] = cmplx(0.0,0.0); cpucc = cpusec(); pfa2cc(1,1,nc,nc,cz); cpucc = cpusec()-cpucc; for (i=0; i<nr*nr; i++) rz[i] = 0.0; cpurc = cpusec(); pfa2rc(1,1,nr,nr,rz,cz); cpurc = cpusec()-cpurc; printf("nc,nr,cc,rc,cc/rc = %d %d %f %f %f\n", nc,nr,cpucc,cpurc,cpucc/cpurc); } }
void rc1_fft(REAL *data, complex *cdata, 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) pfarc(sign,n,data,cdata); else rcdft(data,cdata,n,sign); } else { datft = (double *)malloc(n*sizeof(double)); if (datft == NULL) fprintf(stderr,"rc1_fft: memory allocation error\n"); for (j = 0; j < n; j++) datft[j] = (double)data[j]; realfft(n, datft); cdata[0].i = 0.0; for (j = 0; j < n/2; j++) { cdata[j].r = (REAL)datft[j]; cdata[j+1].i = sign*(REAL)datft[n-j-1]; } cdata[n/2].r = datft[n/2]; cdata[n/2].i = 0.0; free(datft); } return; }
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; }
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; }
void rcm_fft(REAL *data, complex *cdata, int n1, int n2, int ldr, int ldc, 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) { pfa2rc(sign, 1, n1, n2, data, cdata); } else { for (i = 0; i < n2; i++) { pfarc(sign, n1, &data[i*ldr], &cdata[i*ldc]); } } } else { for (i = 0; i < n2; i++) { rcdft(&data[i*ldr], &cdata[i*ldc], n1, sign); } } } else { datft = (double *)malloc(n1*sizeof(double)); if (datft == NULL) fprintf(stderr,"rcm_fft: memory allocation error\n"); for (i = 0; i < n2; i++) { for (j = 0; j < n1; j++) datft[j] = (double)data[i*ldr+j]; realfft(n1, datft); cdata[i*ldc].i = 0.0; for (j = 0; j < n1/2; j++) { cdata[i*ldc+j].r = (REAL)datft[j]; cdata[i*ldc+j+1].i = sign*(REAL)datft[n1-j-1]; } cdata[i*ldc+n1/2].r = (REAL)datft[n1/2]; cdata[i*ldc+n1/2].i = 0.0; } free(datft); } return; }
void roughint(int *zp, int minx, int maxx, float dz, float *interface, float ampl, float beta, float seed) { int j, i, ndeltx, optn; long idum; float *fract; float dk, mean, std; complex *fracc, *fracc2; ndeltx = maxx - minx + 1; optn = npfar(npfa(ndeltx)); fract = (float *)malloc(optn*sizeof(float)); fracc = (complex *)malloc((optn/2+1)*sizeof(complex)); fracc2 = (complex *)malloc(optn*sizeof(complex)); /* srandom(seed); fact = 1.0/(float)pow(2.0, 31.0); for (j = 0; j < optn; j++) fract[j] = (float)random()*fact; */ idum = (long) seed; srand48(idum); for (j = 0; j < optn; j++) fract[j] = (float)drand48(); pfarc(-1, optn, fract, fracc); dk = 1.0/(float)optn; for (j = 1; j < optn/2+1; j++) { fracc2[j].r = fracc[j].r*pow(j*dk, -beta/2.0); fracc2[j].i = fracc[j].i*pow(j*dk, -beta/2.0); } for (j = optn/2+2; j < optn; j++) { fracc2[j].r = fracc[optn-j].r; fracc2[j].i = -1.0*fracc[optn-j].i; } fracc2[0].r = 0.0; fracc2[0].i = 0.0; pfacc(1, optn, fracc2); for (j = 0; j < optn; j++) fract[j] = fracc2[j].r; statics(fract, optn, &mean, &std); for (j = 0; j < optn; j++) fract[j] -= mean; dk = ampl/(2*std); for (j = 0; j < optn; j++) fract[j] *= dk; j = 0; for (i = minx; i < maxx; i++) { interface[i] += fract[j]; zp[i] = NINT(interface[i]/dz); j++; if (SGN(zp[i]) < 0) zp[i] = 0; } free(fract); free(fracc); free(fracc2); return; }
static void dmooff (float offset, float fmax, int nx, float dx, int nt, float dt, float ft, float *vrms, float **ptx, float gamma, float *boh, float *zoh, int ntable, float s1, float s2, float sign) /***************************************************************************** perform dmo in f-k domain for one offset ****************************************************************************** Input: offset source receiver offset fmax maximum frequency s1 DMO stretch factor s2 DMO stretch factor sign sign of shift nx number of midpoints dx midpoint sampling interval nt number of time samples dt time sampling interval ft first time vrms array[nt] of rms velocities ptx array[nx][nt] for p(t,x), zero-padded for fft (see notes) Output: ptx array[nx][nt] for dmo-corrected p(t,x) ****************************************************************************** Notes: To avoid having to allocate a separate work space that is larger than the array ptx[nx][nt], ptx must be zero-padded to enable Fourier transform from x to k via prime factor FFT. nxpad (nx after zero-padding) can be estimated by nxpad = 2+npfar(nx+(int)(0.5*ABS(offset/dx))); where npfar() is a function that returns a valid length for real-to-complex prime factor FFT. ptx[nx] to ptx[nxfft-1] must point to zeros. ****************************************************************************** Author: Dave Hale, Colorado School of Mines, 08/08/91 *****************************************************************************/ { int nxfft,itmin,nu,nufft,nw,nk,ix,iu,iw,ik,it,iwn, iwmin,iwmax,nupad,ikmax,*itn,lnt; float dw,dk,tcon,wwscl,wwscl2,scale,scales,kmax,lt, amp,phase,fr,fi,pwr,pwi,cphase,sphase,os1,os2, wmin,wmax,fftscl,du,fu,w,k,*uoft,*tofu,g1,h,vmin,hk,t,*bboh=NULL; complex czero=cmplx(0.0,0.0),**ptk,*pu,*pw; /* number of cdps after padding for fft */ nxfft = npfar(nx+(int)(0.5*ABS(offset/dx))); /* get minimum time of first non-zero sample */ for (ix=0,itmin=nt; ix<nx; ++ix) { for (it=0; it<itmin && ptx[ix][it]==0.0; ++it); itmin = it; } /* if all zeros, simply return */ if (itmin>=nt) return; /* make stretch and compress functions t(u) and u(t) */ maketu(offset,itmin,fmax,nt,dt,ft,vrms,&uoft,&nu,&du,&fu,&tofu,&tcon); /* constants depending on gamma, offset, vrms[0], and nt */ g1 = 2.0*sqrt(gamma)/(1.0+gamma); h = offset/2.0; lnt = nt-1; lt = (nt-1)*dt; vmin = 0.5*MIN((1.0+1.0/gamma)*vrms[0],(1.0+gamma)*vrms[0]); /* if gamma != 1, get bboh[] and itn[] for this offset */ if(gamma!=1.0) getbbohitn (offset,itmin,nt,dt,vrms,ntable,boh,zoh, \ gamma,&bboh,&itn); /* inverse of dmo stretch/squeeze factors */ os1 = 1.0/s1; os2 = 1.0/s2; /* maximum DMO shift (in samples) for any wavenumber k */ nupad = 1.5*((s1+s2)/2.0)*tcon/du; /* frequency sampling */ nufft = npfa(nu+nupad); nw = nufft; dw = 2.0*PI/(nufft*du); /* allocate workspace */ pu = pw = ealloc1complex(nufft); /* wavenumber sampling and maximum wavenumber to apply dmo */ nk = nxfft/2+1; dk = 2.0*PI/ABS(nxfft*dx); kmax = PI/ABS(dx); ikmax = NINT(kmax/dk); /* pointers to complex p(t,k) */ ptk = (complex**)ealloc1(nk,sizeof(complex*)); for (ik=0; ik<nk; ++ik) ptk[ik] = (complex*)ptx[0]+ik*nt; /* fft scale factor */ fftscl = (float)nk/(float)(ikmax+1)/(nufft*nxfft); /* Fourier transform p(t,x) to p(t,k) */ pfa2rc(-1,2,nt,nxfft,ptx[0],ptk[0]); /* loop over wavenumbers less than maximum */ for (ik=0,k=0.0; ik<=ikmax; ++ik,k+=dk) { /* apply time vriant linear phase shift */ hk=sign*h*k; for (it=lnt,t=lt; it>=itmin; --it,t-=dt) { /* calculate phase-shift=boh*h*k, h=offset/2 */ if(gamma != 1.0) phase = bboh[it]*hk; else phase = 0.0; /* phase shift p(t,k) */ cphase=cos(phase); sphase=sin(phase); fr = ptk[ik][it].r; fi = ptk[ik][it].i; ptk[ik][it].r = fr*cphase + fi*sphase; ptk[ik][it].i = -fr*sphase + fi*cphase; } /* stretch p(t;k) to p(u) */ ints8c(nt,dt,ft,ptk[ik],czero,czero,nu,tofu,pu); /* pad with zeros and Fourier transform p(u) to p(w) */ for (iu=nu; iu<nufft; ++iu) pu[iu].r = pu[iu].i = 0.0; pfacc(1,nufft,pu); /* minimum and maximum frequencies to process */ wmin = ABS(0.5*vmin*k); wmax = ABS(PI/du); iwmin = MAX(1,MIN((nw-1)/2,NINT(wmin/dw))); iwmax = MAX(0,MIN((nw-1)/2,NINT(wmax/dw))); /* constant independent of w */ wwscl = os1*pow(g1*hk/tcon,2.0); wwscl2 = wwscl*os2/os1; /* zero dc (should be zero anyway) */ pw[0].r = pw[0].i = 0.0; /* zero frequencies below minimum */ for (iw=1,iwn=nw-iw; iw<iwmin; ++iw,--iwn) pw[iw].r = pw[iw].i = pw[iwn].r = pw[iwn].i = 0.0; /* do dmo between minimum and maximum frequencies */ for (iw=iwmin,iwn=nw-iwmin,w=iwmin*dw; iw<=iwmax; ++iw,--iwn,w+=dw) { /* positive w */ scales = 1.0+wwscl/(w*w); scale = sqrt(scales); phase = s1*w*tcon*(scale-1.0); amp = fftscl*(1.0-s1+s1/scale); fr = amp*cos(phase); fi = amp*sin(phase); pwr = pw[iw].r; pwi = pw[iw].i; pw[iw].r = pwr*fr-pwi*fi; pw[iw].i = pwr*fi+pwi*fr; /* negative w */ scales = 1.0+wwscl2/(w*w); scale = sqrt(scales); phase = s2*w*tcon*(scale-1.0); amp = fftscl*(1.0-s2+s2/scale); fr = amp*cos(phase); fi = amp*sin(phase); pwr = pw[iwn].r; pwi = pw[iwn].i; pw[iwn].r = pwr*fr+pwi*fi; pw[iwn].i = pwi*fr-pwr*fi; } /* zero frequencies above maximum to Nyquist (if present) */ for (iw=iwmax+1,iwn=nw-iw; iw<=nw/2; ++iw,--iwn) pw[iw].r = pw[iw].i = pw[iwn].r = pw[iwn].i = 0.0; /* Fourier transform p(w) to p(u) */ pfacc(-1,nufft,pu); /* compress p(u) to p(t;k) */ ints8c(nu,du,fu,pu,czero,czero,nt,uoft,ptk[ik]); } /* zero wavenumber between maximum and Nyquist */ for (; ik<nk; ++ik) for (it=0; it<nt; ++it) ptk[ik][it].r = ptk[ik][it].i = 0.0; /* Fourier transform p(t,k) to p(t,x) */ pfa2cr(1,2,nt,nxfft,ptk[0],ptx[0]); /* free workspace */ free1float(tofu); free1float(uoft); free1complex(pu); free1(ptk); }
int main(int argc, char **argv) { int nt; /* number of time samples per trace */ float dt; /* time sampling interval */ float ft; /* time of first sample */ int it; /* time sample index */ int cdpmin; /* minimum cdp to process */ int cdpmax; /* maximum cdp to process */ float dx; /* cdp sampling interval */ int nx; /* number of cdps to process */ int nxfft; /* number of cdps after zero padding for fft */ int nxpad; /* minimum number of cdps for zero padding */ int ix; /* cdp index, starting with ix=0 */ int noffmix; /* number of offsets to mix */ float *tdmo; /* times at which rms velocities are specified */ float *vdmo; /* rms velocities at times specified in tdmo */ float gamma; /* upgoing to downging velocity ratio */ float *zoh=NULL;/* tabulated z/h */ float *boh=NULL;/* tabulated b/h */ int ntable; /* number of tabulated zoh and boh */ float sdmo; /* DMO stretch factor */ float s1; /* DMO stretch factor */ float s2; /* DMO stretch factor */ float temps; /* temp value used in excahnging s1 and s2 */ int flip; /* apply negative shifts and exchange s1 and s2 */ float sign; /* + if flip=0, negative if flip=1 */ int ntdmo; /* number tnmo values specified */ int itdmo; /* index into tnmo array */ int nvdmo; /* number vnmo values specified */ float fmax; /* maximum frequency */ float *vrms; /* uniformly sampled vrms(t) */ float **p; /* traces for one offset - common-offset gather */ float **q; /* DMO-corrected and mixed traces to be output */ float offset; /* source-receiver offset of current trace */ float oldoffset;/* offset of previous trace */ int noff; /* number of offsets processed in current mix */ int ntrace; /* number of traces processed in current mix */ int itrace; /* trace index */ int gottrace; /* non-zero if an input trace was read */ int done; /* non-zero if done */ int verbose; /* =1 for diagnostic print */ FILE *hfp; /* file pointer for temporary header file */ /* hook up getpar */ initargs(argc, argv); requestdoc(1); /* get information from the first header */ if (!gettr(&tr)) err("can't get first trace"); nt = tr.ns; dt = tr.dt/1000000.0; ft = tr.delrt/1000.0; offset = tr.offset; /* get parameters */ if (!getparint("cdpmin",&cdpmin)) err("must specify cdpmin"); if (!getparint("cdpmax",&cdpmax)) err("must specify cdpmax"); if (cdpmin>cdpmax) err("cdpmin must not be greater than cdpmax"); if (!getparfloat("dxcdp",&dx)) err("must specify dxcdp"); if (!getparint("noffmix",&noffmix)) err("must specify noffmix"); ntdmo = countparval("tdmo"); if (ntdmo==0) ntdmo = 1; tdmo = ealloc1float(ntdmo); if (!getparfloat("tdmo",tdmo)) tdmo[0] = 0.0; nvdmo = countparval("vdmo"); if (nvdmo==0) nvdmo = 1; if (nvdmo!=ntdmo) err("number of tdmo and vdmo must be equal"); vdmo = ealloc1float(nvdmo); if (!getparfloat("vdmo",vdmo)) vdmo[0] = 1500.0; for (itdmo=1; itdmo<ntdmo; ++itdmo) if (tdmo[itdmo]<=tdmo[itdmo-1]) err("tdmo must increase monotonically"); if (!getparfloat("gamma",&gamma)) gamma = 0.5; if (!getparint("ntable",&ntable)) ntable = 1000; if (!getparfloat("sdmo",&sdmo)) sdmo = 1.0; if (!getparint("flip",&flip)) flip=0; if (flip) sign = -1.0; else sign = 1.0; if (!getparfloat("fmax",&fmax)) fmax = 0.5/dt; if (!getparint("verbose",&verbose)) verbose=0; checkpars(); /* allocate and generate tables of b/h and z/h if gamma not equal 1 */ if(gamma != 1.0){ zoh=alloc1float(ntable); boh=alloc1float(ntable); table(ntable, gamma, zoh, boh); } /* make uniformly sampled rms velocity function of time */ vrms = ealloc1float(nt); mkvrms(ntdmo,tdmo,vdmo,nt,dt,ft,vrms); /* determine number of cdps to process */ nx = cdpmax-cdpmin+1; /* allocate and zero common-offset gather p(t,x) */ nxpad = 0.5*ABS(offset/dx); nxfft = npfar(nx+nxpad); p = ealloc2float(nt,nxfft+2); for (ix=0; ix<nxfft; ++ix) for (it=0; it<nt; ++it) p[ix][it] = 0.0; /* allocate and zero offset mix accumulator q(t,x) */ q = ealloc2float(nt,nx); for (ix=0; ix<nx; ++ix) for (it=0; it<nt; ++it) q[ix][it] = 0.0; /* open temporary file for headers */ hfp = tmpfile(); /* initialize */ oldoffset = offset; gottrace = 1; done = 0; ntrace = 0; noff = 0; /* get DMO stretch/squeeze factors s1 and s2 */ stretchfactor (sdmo,gamma,&s1,&s2); if(flip) { temps = s1; s1 = s2; s2 = temps; } /* print useful information if requested */ if (verbose)fprintf(stderr,"stretching factors: s1=%f s2=%f\n",s1,s2); /* loop over traces */ do { /* if got a trace, determine offset */ if (gottrace) offset = tr.offset; /* if an offset is complete */ if ((gottrace && offset!=oldoffset) || !gottrace) { /* do dmo for old common-offset gather */ dmooff(oldoffset,fmax,nx,dx,nt,dt,ft,vrms,p, gamma,boh,zoh,ntable,s1,s2,sign); /* add dmo-corrected traces to mix */ for (ix=0; ix<nx; ++ix) for (it=0; it<nt; ++it) q[ix][it] += p[ix][it]; /* count offsets in mix */ noff++; /* free space for old common-offset gather */ free2float(p); /* if beginning a new offset */ if (offset!=oldoffset) { /* allocate space for new offset */ nxpad = 0.5*ABS(offset/dx); nxfft = npfar(nx+nxpad); p = ealloc2float(nt,nxfft+2); for (ix=0; ix<nxfft; ++ix) for (it=0; it<nt; ++it) p[ix][it] = 0.0; } } /* if a mix of offsets is complete */ if (noff==noffmix || !gottrace) { /* rewind trace header file */ efseeko(hfp, (off_t) 0,SEEK_SET); /* loop over all output traces */ for (itrace=0; itrace<ntrace; ++itrace) { /* read trace header and determine cdp index */ efread(&tro,HDRBYTES,1,hfp); /* get dmo-corrected data */ memcpy((void *) tro.data, (const void *) q[tro.cdp-cdpmin], nt*sizeof(float)); /* write output trace */ puttr(&tro); } /* report */ if (verbose) fprintf(stderr,"\tCompleted mix of " "%d offsets with %d traces\n", noff,ntrace); /* if no more traces, break */ if (!gottrace) break; /* rewind trace header file */ efseeko(hfp, (off_t) 0,SEEK_SET); /* reset number of offsets and traces in mix */ noff = 0; ntrace = 0; /* zero offset mix accumulator */ for (ix=0; ix<nx; ++ix) for (it=0; it<nt; ++it) q[ix][it] = 0.0; } /* if cdp is within range to process */ if (tr.cdp>=cdpmin && tr.cdp<=cdpmax) { /* save trace header and update number of traces */ efwrite(&tr,HDRBYTES,1,hfp); ntrace++; /* remember offset */ oldoffset = offset; /* get trace samples */ memcpy((void *) p[tr.cdp-cdpmin], (const void *) tr.data, nt*sizeof(float)); } /* get next trace (if there is one) */ if (!gettr(&tr)) gottrace = 0; } while (!done); return(CWP_Exit()); }
void slopefilter (int nslopes, float slopes[], float amps[], float bias, int nt, float dt, int nx, float dx, FILE *tracefp) /****************************************************************************** apply slope filter in frequency-wavenumber domain ******************************************************************************* Input: nslopes number of slopes (and amplitudes) specified slopes slopes at which amplitudes are specified (see notes below) amps amplitudes corresponding to slopes (see notes below) bias linear moveout slope before and after filtering nt number of time samples dt time sampling interval nx number of traces dx trace space (spatial sampling interval) tracefp file pointer to data to be filtered Output: tracefp file pointer to filtered data ******************************************************************************* Notes: Linear interpolation and constant extrapolation are used to determine amplitudes for slopes that are not specified. ******************************************************************************/ { int ntfft; /* nt after padding for FFT */ int nxfft; /* nx after padding for FFT */ float sfft; /* scale factor for FFT */ int nw; /* number of frequencies */ float dw; /* frequency sampling interval */ float fw; /* first frequency */ int nk; /* number of wavenumbers */ float dk; /* wavenumber sampling interval */ float w,k; /* frequency and wavenumber */ int it,ix,iw,ik; /* sample indices */ float slope,amp; /* slope and amplitude for particular w,k */ complex **cpfft; /* complex FFT workspace */ float **pfft; /* float FFT workspace */ float phase; /* phase shift for bias */ complex cshift; /* complex phase shifter for bias */ /* determine lengths and scale factors for prime-factor FFTs */ ntfft = npfar(nt); nxfft = npfa(nx); sfft = 1.0/(ntfft*nxfft); /* determine frequency and wavenumber sampling */ nw = ntfft/2+1; dw = 2.0*PI/(ntfft*dt); fw = 0.000001*dw; /* non-zero to avoid divide by zero w */ nk = nxfft; dk = 2.0*PI/(nxfft*dx); /* allocate real and complex workspace for FFTs */ cpfft = alloc2complex(nw,nk); pfft = alloc2float(ntfft,nxfft); /* copy data from input to FFT array and pad with zeros */ rewind(tracefp); for (ix=0; ix<nx; ix++) { efread(pfft[ix], FSIZE, nt, tracefp); for (it=nt; it<ntfft; it++) pfft[ix][it] = 0.0; } for (ix=nx; ix<nxfft; ix++) for (it=0; it<ntfft; it++) pfft[ix][it] = 0.0; /* Fourier transform t to w */ pfa2rc(1,1,ntfft,nx,pfft[0],cpfft[0]); /* do linear moveout bias via phase shift */ for (ix=0; ix<nx; ix++) { for (iw=0,w=0.0; iw<nw; iw++,w+=dw) { phase = -ix*dx*w*bias; cshift = cmplx(cos(phase),sin(phase)); cpfft[ix][iw] = cmul(cpfft[ix][iw],cshift); } } /* Fourier transform x to k */ pfa2cc(-1,2,nw,nxfft,cpfft[0]); /* loop over wavenumbers */ for (ik=0; ik<nk; ik++) { /* determine wavenumber */ k = (ik<=nk/2) ? ik*dk : (ik-nk)*dk; /* loop over frequencies */ for (iw=0,w=fw; iw<nw; iw++,w+=dw) { /* determine biased slope */ slope = k/w+bias; /* linearly interpolate to find amplitude */ intlin(nslopes,slopes,amps,amps[0],amps[nslopes-1], 1,&slope,&); /* include fft scaling */ amp *= sfft; /* filter real and imaginary parts */ cpfft[ik][iw].r *= amp; cpfft[ik][iw].i *= amp; } } /* Fourier transform k to x */ pfa2cc(1,2,nw,nxfft,cpfft[0]); /* undo linear moveout bias via phase shift */ for (ix=0; ix<nx; ix++) { for (iw=0,w=0.0; iw<nw; iw++,w+=dw) { phase = ix*dx*w*bias; cshift = cmplx(cos(phase),sin(phase)); cpfft[ix][iw] = cmul(cpfft[ix][iw],cshift); } } /* Fourier transform w to t */ pfa2cr(-1,1,ntfft,nx,cpfft[0],pfft[0]); /* copy filtered data from FFT array to output */ rewind(tracefp); for (ix=0; ix<nx; ix++) efwrite(pfft[ix], FSIZE, nt, tracefp); /* free workspace */ free2complex(cpfft); free2float(pfft); }
/**************** 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; }
int main(int argc, char **argv) { int nt; /* number of time samples per trace */ float dt; /* time sampling interval */ float ft; /* time of first sample */ int it; /* time sample index */ int cdpmin; /* minimum cdp to process */ int cdpmax; /* maximum cdp to process */ float dx; /* cdp sampling interval */ int nx; /* number of cdps to process */ int nxfft; /* number of cdps after zero padding for fft */ int nxpad; /* minimum number of cdps for zero padding */ int ix; /* cdp index, starting with ix=0 */ int noffmix; /* number of offsets to mix */ float *tdmo; /* times at which rms velocities are specified */ float *vdmo; /* rms velocities at times specified in tdmo */ float sdmo; /* DMO stretch factor */ int ntdmo; /* number tnmo values specified */ int itdmo; /* index into tnmo array */ int nvdmo; /* number vnmo values specified */ float fmax; /* maximum frequency */ float *vrms; /* uniformly sampled vrms(t) */ float **p; /* traces for one offset - common-offset gather */ float **q; /* DMO-corrected and mixed traces to be output */ float offset; /* source-receiver offset of current trace */ float oldoffset;/* offset of previous trace */ int noff; /* number of offsets processed in current mix */ int ntrace; /* number of traces processed in current mix */ int itrace; /* trace index */ int gottrace; /* non-zero if an input trace was read */ int done; /* non-zero if done */ int verbose; /* =1 for diagnostic print */ char *tmpdir; /* directory path for tmp files */ cwp_Bool istmpdir=cwp_false;/* true for user given path */ /* hook up getpar */ initargs(argc, argv); requestdoc(1); /* get information from the first header */ if (!gettr(&tr)) err("can't get first trace"); nt = tr.ns; dt = ((double) tr.dt)/1000000.0; ft = tr.delrt/1000.0; offset = tr.offset; /* get parameters */ if (!getparint("cdpmin",&cdpmin)) err("must specify cdpmin"); if (!getparint("cdpmax",&cdpmax)) err("must specify cdpmax"); if (cdpmin>cdpmax) err("cdpmin must not be greater than cdpmax"); if (!getparfloat("dxcdp",&dx)) err("must specify dxcdp"); if (!getparint("noffmix",&noffmix)) err("must specify noffmix"); ntdmo = countparval("tdmo"); if (ntdmo==0) ntdmo = 1; tdmo = ealloc1float(ntdmo); if (!getparfloat("tdmo",tdmo)) tdmo[0] = 0.0; nvdmo = countparval("vdmo"); if (nvdmo==0) nvdmo = 1; if (nvdmo!=ntdmo) err("number of tdmo and vdmo must be equal"); vdmo = ealloc1float(nvdmo); if (!getparfloat("vdmo",vdmo)) vdmo[0] = 1500.0; for (itdmo=1; itdmo<ntdmo; ++itdmo) if (tdmo[itdmo]<=tdmo[itdmo-1]) err("tdmo must increase monotonically"); if (!getparfloat("sdmo",&sdmo)) sdmo = 1.0; if (!getparfloat("fmax",&fmax)) fmax = 0.5/dt; if (!getparint("verbose",&verbose)) verbose=0; /* Look for user-supplied tmpdir */ if (!getparstring("tmpdir",&tmpdir) && !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir=""; if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK)) err("you can't write in %s (or it doesn't exist)", tmpdir); /* make uniformly sampled rms velocity function of time */ vrms = ealloc1float(nt); mkvrms(ntdmo,tdmo,vdmo,nt,dt,ft,vrms); /* determine number of cdps to process */ nx = cdpmax-cdpmin+1; /* allocate and zero common-offset gather p(t,x) */ nxpad = 0.5*ABS(offset/dx); nxfft = npfar(nx+nxpad); p = ealloc2float(nt,nxfft+2); for (ix=0; ix<nxfft; ++ix) for (it=0; it<nt; ++it) p[ix][it] = 0.0; /* allocate and zero offset mix accumulator q(t,x) */ q = ealloc2float(nt,nx); for (ix=0; ix<nx; ++ix) for (it=0; it<nt; ++it) q[ix][it] = 0.0; /* open temporary file for headers */ if (STREQ(tmpdir,"")) { headerfp = etmpfile(); if (verbose) warn("using tmpfile() call"); } else { /* user-supplied tmpdir */ char directory[BUFSIZ]; strcpy(directory, tmpdir); strcpy(headerfile, temporary_filename(directory)); /* Trap signals so can remove temp files */ signal(SIGINT, (void (*) (int)) closefiles); signal(SIGQUIT, (void (*) (int)) closefiles); signal(SIGHUP, (void (*) (int)) closefiles); signal(SIGTERM, (void (*) (int)) closefiles); headerfp = efopen(headerfile, "w+"); istmpdir=cwp_true; if (verbose) warn("putting temporary header file in %s", directory); } /* initialize */ oldoffset = offset; gottrace = 1; done = 0; ntrace = 0; noff = 0; /* loop over traces */ do { /* if got a trace, determine offset */ if (gottrace) offset = tr.offset; /* if an offset is complete */ if ((gottrace && offset!=oldoffset) || !gottrace) { /* do dmo for old common-offset gather */ dmooff(oldoffset,fmax,sdmo,nx,dx,nt,dt,ft,vrms,p); /* add dmo-corrected traces to mix */ for (ix=0; ix<nx; ++ix) for (it=0; it<nt; ++it) q[ix][it] += p[ix][it]; /* count offsets in mix */ noff++; /* free space for old common-offset gather */ free2float(p); /* if beginning a new offset */ if (offset!=oldoffset) { /* allocate space for new offset */ nxpad = 0.5*ABS(offset/dx); nxfft = npfar(nx+nxpad); p = ealloc2float(nt,nxfft+2); for (ix=0; ix<nxfft; ++ix) for (it=0; it<nt; ++it) p[ix][it] = 0.0; } } /* if a mix of offsets is complete */ if (noff==noffmix || !gottrace) { /* rewind trace header file */ erewind(headerfp); /* loop over all output traces */ for (itrace=0; itrace<ntrace; ++itrace) { /* read trace header and determine cdp index */ efread(&tro,HDRBYTES,1,headerfp); /* get dmo-corrected data */ memcpy( (void *) tro.data, (const void *) q[tro.cdp-cdpmin], nt*sizeof(float)); /* write output trace */ puttr(&tro); } /* report */ if (verbose) fprintf(stderr,"\tCompleted mix of " "%d offsets with %d traces\n", noff,ntrace); /* if no more traces, break */ if (!gottrace) break; /* rewind trace header file */ erewind(headerfp); /* reset number of offsets and traces in mix */ noff = 0; ntrace = 0; /* zero offset mix accumulator */ for (ix=0; ix<nx; ++ix) for (it=0; it<nt; ++it) q[ix][it] = 0.0; } /* if cdp is within range to process */ if (tr.cdp>=cdpmin && tr.cdp<=cdpmax) { /* save trace header and update number of traces */ efwrite(&tr,HDRBYTES,1,headerfp); ntrace++; /* remember offset */ oldoffset = offset; /* get trace samples */ memcpy( (void *) p[tr.cdp-cdpmin], (const void *) tr.data, nt*sizeof(float)); } /* get next trace (if there is one) */ if (!gettr(&tr)) gottrace = 0; } while (!done); /* clean up */ efclose(headerfp); if (istmpdir) eremove(headerfile); return(CWP_Exit()); }
main(int argc, char **argv) { int nt,nx; /* numbers of samples */ float dt,dx; /* sampling intervals */ float d1,d2; /* output intervals in F, K */ float f1,f2; /* output first samples in F, K */ int it,ix; /* sample indices */ int ntfft,nxfft; /* dimensions after padding for FFT */ int nF,nK; /* transform (output) dimensions */ int iF,iK; /* transform sample indices */ register complex **ct; /* complex FFT workspace */ register float **rt; /* float FFT workspace */ FILE *tracefp; /* temp file to hold traces */ /* Hook up getpar to handle the parameters */ initargs(argc,argv); askdoc(1); /* Get info from first trace */ if (!gettr(&intrace)) err("can't get first trace"); nt = intrace.ns; /* dt is used only to set output header value d1 */ if (!getparfloat("dt", &dt)) { if (intrace.dt) { /* is dt field set? */ dt = (float) intrace.dt / 1000000.0; } else { /* dt not set, assume 4 ms */ dt = 0.004; warn("tr.dt not set, assuming dt=0.004"); } } if (!getparfloat("dx",&dx)) { if (intrace.d2) { /* is d2 field set? */ dx = intrace.d2; } else { dx = 1.0; warn("tr.d2 not set, assuming d2=1.0"); } } /* Store traces in tmpfile while getting a count */ /*tracefp = etmpfile();*/ tracefp = etempfile(NULL); nx = 0; do { ++nx; efwrite(intrace.data, FSIZE, nt, tracefp); } while (gettr(&intrace)); /* Determine lengths for prime-factor FFTs */ ntfft = npfar(nt); nxfft = npfa(nx); if (ntfft >= MIN(SU_NFLTS, PFA_MAX)) err("Padded nt=%d--too big",ntfft); if (nxfft >= MIN(SU_NFLTS, PFA_MAX)) err("Padded nx=%d--too big",nxfft); /* Determine output header values */ d1 = 1.0/(ntfft*dt); d2 = 1.0/(nxfft*dx); f1 = 0.0; f2 = -1.0/(2*dx); /* Determine complex transform sizes */ nF = ntfft/2+1; nK = nxfft; /* Allocate space */ ct = alloc2complex(nF, nK); rt = alloc2float(ntfft, nxfft); /* Load traces into fft arrays and close tmpfile */ rewind(tracefp); for (ix=0; ix<nx; ++ix) { efread(rt[ix], FSIZE, nt, tracefp); /* if ix odd, negate to center transform of dimension 2 */ if (ISODD(ix)) for (it=0; it<nt; ++it) rt[ix][it] = -rt[ix][it]; /* pad dimension 1 with zeros */ for (it=nt; it<ntfft; ++it) rt[ix][it] = 0.0; } efclose(tracefp); /* Pad dimension 2 with zeros */ for (ix=nx; ix<nxfft; ++ix) for (it=0; it<ntfft; ++it) rt[ix][it] = 0.0; /* Fourier transform dimension 1 */ pfa2rc(1,1,ntfft,nx,rt[0],ct[0]); /* Fourier transform dimension 2 */ pfa2cc(-1,2,nF,nxfft,ct[0]); /* Compute and output amplitude spectrum */ for (iK=0; iK<nK; ++iK) { for (iF=0; iF<nF; ++iF) outtrace.data[iF] = fcabs(ct[iK][iF]); /* set header values */ outtrace.tracl = iK + 1; outtrace.ns = nF; outtrace.dt = 0; /* d1 is now the relevant step size */ outtrace.trid = KOMEGA; outtrace.d1 = d1; outtrace.f1 = f1; outtrace.d2 = d2; outtrace.f2 = f2; puttr(&outtrace); } }
int main (int argc, char **argv) { int nt; /* number of time samples */ int nz; /* number of migrated depth samples */ int nx; /* number of horizontal samples */ int nxshot; /* number of shots to be migrated */ /*int nxshot_orig;*/ /* first value of nxshot */ int iz,iw,ix,it; /* loop counters */ int igx; /* integerized gx value */ int ntfft; /* fft size */ int nw,truenw; /* number of wave numbers */ int dip=79; /* dip angle */ float sx,gx; /* x source and geophone location */ float gxmin=0.0,gxmax=0.0; /* x source and geophone location */ float min_sx_gx; /* min(sx,gx) */ float oldgx; /* old gx position */ /* float oldgxmin; */ /* old gx position */ /* float oldgxmax; */ /* old gx position */ float oldsx=0.0; /* old sx position */ int isx=0,nxo; /* index for source and geophone */ int oldisx=0; /* old value of source index */ int oldigx=0; /* old value of integerized gx value */ int ix1,ix2,ix3,ixshot; /* dummy index */ int lpad,rpad; /* padding on both sides of the migrated section */ float *wl=NULL,*wtmp=NULL; float fmax; float f1,f2,f3,f4; int nf1,nf2,nf3,nf4; int ntw; float dt=0.004,dz; /* time and depth sampling interval */ float dw; /* frequency sampling interval */ float fw; /* first frequency */ float w; /* frequency */ float dx; /* spatial sampling interval */ float **p=NULL; /* input data */ float **cresult=NULL; /* output result */ float v1; /* average velocity */ double kz2; float **v=NULL,**vp=NULL;/* pointers for the velocity profile */ complex cshift2; complex *wlsp=NULL; /* complex input,output */ complex **cp=NULL; /* ... */ complex **cp1=NULL; /* ... */ complex **cq=NULL; /* ... */ char *vfile=""; /* name of file containing velocities */ FILE *vfp=NULL; int verbose; /* verbose flag */ /* hook up getpar to handle the parameters */ initargs(argc,argv); requestdoc(1); /* get required parameters */ MUSTGETPARINT("nz",&nz); MUSTGETPARINT("nxo",&nxo); MUSTGETPARFLOAT("dz",&dz); MUSTGETPARSTRING("vfile",&vfile); MUSTGETPARINT("nxshot",&nxshot); /* get optional parameters */ if (!getparfloat("fmax",&fmax)) fmax = 25.0; if (!getparfloat("f1",&f1)) f1 = 10.0; if (!getparfloat("f2",&f2)) f2 = 20.0; if (!getparfloat("f3",&f3)) f3 = 40.0; if (!getparfloat("f4",&f4)) f4 = 50.0; if (!getparint("lpad",&lpad)) lpad=9999; if (!getparint("rpad",&rpad)) rpad=9999; if (!getparint("dip",&dip)) dip=79; if (!getparint("verbose",&verbose)) verbose = 0; /* allocating space */ cresult = alloc2float(nz,nxo); vp = alloc2float(nxo,nz); /* load velicoty file */ vfp=efopen(vfile,"r"); efread(vp[0],FSIZE,nz*nxo,vfp); efclose(vfp); /* zero out cresult array */ memset((void *) cresult[0], 0, nxo*nz*FSIZE); /* save value of nxshot */ /* nxshot_orig=nxshot; */ /* get info from first trace */ if (!gettr(&tr)) err("can't get first trace"); nt = tr.ns; get_sx_gx(&sx,&gx); min_sx_gx = MIN(sx,gx); sx = sx - min_sx_gx; gx = gx - min_sx_gx; /* let user give dt and/or dx from command line */ if (!getparfloat("dt", &dt)) { if (tr.dt) { /* is dt field set? */ dt = ((double) tr.dt)/1000000.0; } else { /* dt not set, assume 4 ms */ dt = 0.004; if(verbose) warn("tr.dt not set, assuming dt=0.004"); } } if (!getparfloat("dx",&dx)) { if (tr.d2) { /* is d2 field set? */ dx = tr.d2; } else { dx = 1.0; if(verbose) warn("tr.d2 not set, assuming d2=1.0"); } } checkpars(); oldisx=0; do { /* begin loop over shots */ /* determine frequency sampling interval*/ ntfft = npfar(nt); nw = ntfft/2+1; dw = 2.0*PI/(ntfft*dt); /* compute the index of the frequency to be migrated*/ fw=2.0*PI*f1; nf1=fw/dw+0.5; fw=2.0*PI*f2; nf2=fw/dw+0.5; fw=2.0*PI*f3; nf3=fw/dw+0.5; fw=2.0*PI*f4; nf4=fw/dw+0.5; /* the number of frequencies to migrated*/ truenw=nf4-nf1+1; fw=0.0+nf1*dw; if(verbose) warn("nf1=%d nf2=%d nf3=%d nf4=%d nw=%d",nf1,nf2,nf3,nf4,truenw); /* allocate space */ wl=alloc1float(ntfft); wlsp=alloc1complex(nw); /* generate the Ricker wavelet */ wtmp=ricker(fmax,dt,&ntw); /* zero out wl[] array */ memset((void *) wl, 0, ntfft*FSIZE); /* CHANGE BY CHRIS STOLK, Dec. 11, 2005 */ /* The next two lines are the old code, */ /* it is erroneous because the peak of */ /* the wavelet occurs at positive time */ /* instead of time zero. */ /* for(it=0;it<ntw;it++) wl[it]=wtmp[it]; */ /* New code: we put in the wavelet in a centered fashion */ for(it=0;it<ntw;it++) wl[(it-ntw/2+ntfft) % ntfft]=wtmp[it]; /* End of new code */ free1float(wtmp); /* fourier transform wl array */ pfarc(-1,ntfft,wl,wlsp); /* allocate space */ p = alloc2float(ntfft,nxo); cq = alloc2complex(nw,nxo); /* zero out p[][] array */ memset((void *) p[0], 0, ntfft*nxo*FSIZE); /* initialize a number of items before looping over traces */ nx = 0; igx=0; oldigx=0; oldsx=sx; oldgx=gx; /* oldgxmax=gxmax; */ /* oldgxmin=gxmin; */ do { /* begin looping over traces within a shot gather */ memcpy( (void *) p[igx], (const void *) tr.data,nt*FSIZE); /* get sx and gx */ get_sx_gx(&sx,&gx); sx = (sx - min_sx_gx); gx = (gx - min_sx_gx); igx = NINT(gx/dx); if (igx==oldigx) warn("repeated igx!!! check dx or scalco value!!!"); oldigx = igx; if(gxmin>gx)gxmin=gx; if(gxmax<gx)gxmax=gx; if(verbose) warn(" inside loop: min_sx_gx %f isx %d igx %d gx %f sx %f",min_sx_gx,isx,igx,gx,sx); /* sx, gx must increase monotonically */ if (!(oldsx <= sx) ) err("sx field must be monotonically increasing!"); if (!(oldgx <= gx) ) err("gx field must be monotonically increasing!"); ++nx; } while(gettr(&tr) && sx==oldsx); isx=NINT(oldsx/dx); ixshot=isx; if (isx==oldisx) warn("repeated isx!!! check dx or scalco value!!!"); oldisx=isx; if(verbose) { warn("sx %f, gx %f , gxmin %f gxmax %f nx %d",sx,gx,gxmin,gxmax, nx); warn("isx %d igx %d ixshot %d" ,isx,igx,ixshot); } /* transform the shot gather from time to frequency domain */ pfa2rc(1,1,ntfft,nxo,p[0],cq[0]); /* compute the most left and right index for the migrated */ /* section */ ix1=NINT(oldsx/dx); ix2=NINT(gxmin/dx); ix3=NINT(gxmax/dx); if(ix1>=ix3)ix3=ix1; if(ix1<=ix2)ix2=ix1; ix2-=lpad; ix3+=rpad; if(ix2<0)ix2=0; if(ix3>nxo-1)ix3=nxo-1; /* the total traces to be migrated */ nx=ix3-ix2+1; nw=truenw; /* allocate space for velocity profile within the aperature */ v=alloc2float(nx,nz); for(iz=0;iz<nz;iz++) for(ix=0;ix<nx;ix++) v[iz][ix]=vp[iz][ix+ix2]; /* allocate space */ cp = alloc2complex(nx,nw); cp1 = alloc2complex(nx,nw); /* transpose the frequency domain data from */ /* data[ix][iw] to data[iw][ix] and apply a */ /* Hamming at the same time */ for (ix=0; ix<nx; ++ix) { for (iw=0; iw<nw; iw++){ float tmpp=0.0,tmppp=0.0; if(iw>=(nf1-nf1)&&iw<=(nf2-nf1)){ tmpp=PI/(nf2-nf1); tmppp=tmpp*(iw-nf1)-PI; tmpp=0.54+0.46*cos(tmppp); cp[iw][ix]=crmul(cq[ix+ix2][iw+nf1],tmpp); } else { if(iw>=(nf3-nf1)&&iw<=(nf4-nf1)) { tmpp=PI/(nf4-nf3); tmppp=tmpp*(iw-nf3); tmpp=0.54+0.46*cos(tmppp); cp[iw][ix]=crmul(cq[ix+ix2][iw+nf1],tmpp); } else { cp[iw][ix]=cq[ix+ix2][iw+nf1]; } } cp1[iw][ix]=cmplx(0.0,0.0); } } for(iw=0;iw<nw;iw++){ cp1[iw][ixshot-ix2]=wlsp[iw+nf1]; } if(verbose) { warn("ixshot %d ix %d ix1 %d ix2 %d ix3 %d",ixshot,ix,ix1,ix2,ix3); warn("oldsx %f ",oldsx); } free2float(p); free2complex(cq); free1float(wl); free1complex(wlsp); /* loops over depth */ for(iz=0; iz<nz; ++iz) { /* the imaging condition */ for(ix=0; ix<nx; ++ix){ for(iw=0,w=fw;iw<nw;w+=dw,iw++){ complex tmp; float ratio=10.0; if(fabs(ix+ix2-ixshot)*dx<ratio*iz*dz) tmp=cmul(cp[iw][ix],cp1[iw][ix]); else tmp=cmplx(0.0,0.0); cresult[ix+ix2][iz]+=tmp.r/ntfft; } } /* get the average velocity */ v1=0.0; for(ix=0;ix<nx;++ix) v1+=v[iz][ix]/nx; /* compute time-invariant wavefield */ for(ix=0;ix<nx;++ix) { for(iw=0,w=fw;iw<nw;w+=dw,++iw) { kz2=-(1.0/v1)*w*dz; cshift2=cmplx(cos(kz2),sin(kz2)); cp[iw][ix]=cmul(cp[iw][ix],cshift2); cp1[iw][ix]=cmul(cp1[iw][ix],cshift2); } } /* wave-propagation using finite-difference method */ fdmig(cp, nx, nw,v[iz],fw,dw,dz,dx,dt,dip); fdmig(cp1,nx, nw,v[iz],fw,dw,dz,dx,dt,dip); /* apply thin lens term here */ for(ix=0;ix<nx;++ix) { for(iw=0,w=fw;iw<nw;w+=dw,++iw){ kz2=-(1.0/v[iz][ix]-1.0/v1)*w*dz; cshift2=cmplx(cos(kz2),sin(kz2)); cp[iw][ix]=cmul(cp[iw][ix],cshift2); cp1[iw][ix]=cmul(cp1[iw][ix],cshift2); } } } free2complex(cp); free2complex(cp1); free2float(v); --nxshot; } while(nxshot); /* restore header fields and write output */ for(ix=0; ix<nxo; ix++){ tr.ns = nz; tr.d1 = dz; tr.d2 = dx; tr.offset = 0; tr.cdp = tr.tracl = ix; memcpy( (void *) tr.data, (const void *) cresult[ix],nz*FSIZE); puttr(&tr); } return(CWP_Exit()); }
int main (int argc, char **argv) { int nt,it,np,ntau,itau,nx,ix,nk,nkmax,ik, ntfft,nxfft,nv,trans,norm,conv,verbose; float dt,dx,dpx,k,dk,kscl,t,*tt,*vt,*tmig,*vmig, (*vsind)[4],**ptx,**divcor; complex **ptk; char *vfile=""; FILE *hfp,*tfp; /* hook up getpar */ initargs(argc,argv); requestdoc(1); /* get information from the first header */ if (!gettr(&tr)) err("can't get first trace"); nt = tr.ns; dt = tr.dt/1000000.0; /* get parameters */ if (!getparfloat("dxcdp",&dx)) err("dxcdp required"); if (!getparint("np",&np)) np=50; if (!getparint("trans",&trans)) trans=0; if (!getparint("norm",&norm)) norm=1; if (!getparint("conv",&conv)) conv=0; if (!getparint("verbose",&verbose)) verbose=0; /* get velocity function */ vt=ealloc1float(nt); tt=ealloc1float(nt); for (it=0; it<nt; it++) tt[it]=it*dt; if (!getparstring ("vfile",&vfile)){ ntau = countparval("tmig"); if (ntau==0) ntau=1; tmig = ealloc1float(ntau); if (!getparfloat("tmig",tmig)) tmig[0] = 0.0; nv = countparval("vmig"); if (nv==0) nv=1; if (nv!=ntau) err("number of tmig and vmig must be equal"); vmig = ealloc1float(nv); if (!getparfloat("vmig",vmig)) vmig[0] = 1500.0; for (itau=1; itau<ntau; itau++) if (tmig[itau]<=tmig[itau-1]) err("tmig must increase monotonically"); for (it=0,t=0.0; it<nt; ++it,t+=dt) intlin(ntau,tmig,vmig,vmig[0],vmig[ntau-1], 1,&t,&vt[it]); if (ntau!=nt){ vsind = (float (*)[4])ealloc1float(ntau*4); cmonot(ntau,tmig,vmig,vsind); intcub(0,ntau,tmig,vsind,nt,tt,vt); } } else{ if (fread(vt,sizeof(float),nt,fopen(vfile,"r"))!=nt) err("Not %d velocities in file %s",nt,vfile); } /* copy traces and headers to temporary files */ tfp = tmpfile(); hfp = tmpfile(); nx = 0; do { nx++; fwrite(&tr,HDRBYTES,1,hfp); fwrite(tr.data,sizeof(float),nt,tfp); } while(gettr(&tr)); fseek(hfp,0L,SEEK_SET); fseek(tfp,0L,SEEK_SET); if (verbose) fprintf(stderr,"\t%d traces input\n",nx); /* determine wavenumber and frequency sampling */ nxfft = npfar(nx); ntfft = npfa(nt); nk = nxfft/2+1; dx *= 0.001; dk = 2.0*PI/(nxfft*dx); /* allocate space for Fourier transform */ ptk = ealloc2complex(nt,nk); ptx = ealloc1(nxfft,sizeof(float*)); for (ix=0; ix<nxfft; ++ix) ptx[ix] = (float*)ptk[0]+ix*nt; /* allocate space for divergence correction */ divcor=ealloc2float(nt,np); /* build table of divergence corrections */ divcortable(nt,np,dt,tt,vt,divcor,trans,norm); /* apply conventional correction if required */ if (conv==1){ for (ix=0; ix<nx; ++ix){ efread(ptx[ix],sizeof(float),nt,tfp); for (it=0; it<nt; ++it) ptx[ix][it] *= divcor[0][it]; } } else { /* read and apply fft scaling to traces */ kscl = 1.0/nxfft; for (ix=0; ix<nx; ++ix) { efread(ptx[ix],sizeof(float),nt,tfp); for (it=0; it<nt; ++it) ptx[ix][it] *= kscl; } /* pad with zeros */ for (ix=nx; ix<nxfft; ++ix) for (it=0; it<nt; ++it) ptx[ix][it] = 0.0; /* Fourier transform ptx(t,x) to ptk(t,k) */ pfa2rc(-1,2,nt,nxfft,ptx[0],ptk[0]); if (verbose) fprintf(stderr,"\tFourier transform done\n"); /* define relevant k range */ nkmax = MIN(nk,NINT(PI/dt/vt[0]/dk)); dpx = 1.0/(np-1)/vt[0]; fprintf(stderr, "nkmax %d nk %d dk %f dpx %f \n",nkmax,nk,dk,dpx); /* special case k=0 */ for (it=0; it<nt; it++){ ptk[0][it].r *= divcor[0][it]; ptk[0][it].i *= divcor[0][it]; } /* loop over wavenumbers */ for (ik=1,k=dk; ik<nkmax; ++ik,k+=dk){ /* report */ if (verbose && ik%(nkmax/10>0?nkmax/10:1)==0) fprintf(stderr,"\t%d of %d wavenumbers done\n", ik,nkmax); /* dip filter divergence correction */ dipfilt(k,dpx,dt,np,ntfft,nt,divcor,ptk[ik],ptk[ik]); } /* Fourier transform p(t,k) to p(t,x) */ pfa2cr(1,2,nt,nxfft,ptk[0],ptx[0]); if (verbose) fprintf(stderr,"\tinverse Fourier transform done\n"); } /* end else dipdivcor */ /* output migrated traces with headers */ for (ix=0; ix<nx; ++ix) { efread(&tr,HDRBYTES,1,hfp); memcpy((void *) tr.data, (const void *) ptx[ix], nt*sizeof(float)); puttr(&tr); } return EXIT_SUCCESS; }
int SeisPipe2D(DsuTask *zz) { int nt,nx,nz,nw,ntpad,ntfft; int it,ix,iz,izz,iw,iw0,iw1,iw2,iw3,iwmin,iwmax; int nfreqs,verbose; float dt,dx,dy,dz,dw; float freqs[4],fw,w,scale,fftscl; float *p, **v, *wdxov,*sx; complex *cpx; float **qx; void *TabInfo; eTable *et; char msg[80]; int info, ToTid, MasterTid; int sz, pz, pei; int SeisIntPars[20]; float SeisFloPars[20]; /* Receive process control information */ MsgLog(zz, "Receiving Control info ... " ); MasterTid = RecvInt(SeisIntPars, 2, -1, MsgCntl); pei = SeisIntPars[0]; ToTid = SeisIntPars[1]; MsgLog(zz, " Ready \n"); /* Receive: efile and other pars ... */ MsgLog(zz, "Receiving parameters ..." ); TabInfo = RecvBytes(-1, MsgTable); RecvFI(SeisFloPars, 10, SeisIntPars, 10, -1, -1); MsgLog(zz, " Ready \n" ); /* get integer parameters */ nt = SeisIntPars[0]; nx = SeisIntPars[1]; nz = SeisIntPars[2]; ntpad = SeisIntPars[3]; verbose = SeisIntPars[4]; sz = SeisIntPars[5]; pz = SeisIntPars[6]; /* get Floating point parameters */ dt = SeisFloPars[0]; dx = SeisFloPars[1]; dz = SeisFloPars[2]; freqs[0] = SeisFloPars[3]; freqs[1] = SeisFloPars[4]; freqs[2] = SeisFloPars[5]; freqs[3] = SeisFloPars[6]; sz = nz / pz; if (pei == (pz - 1)) sz += nz % pz; sprintf(msg, "Receiving Velocity info (pei = %d, sz = %d) ... ", pei, sz); MsgLog(zz,msg); v = alloc2float(nx, sz); for (iz=0; iz<sz; ++iz) RecvFloat(v[iz], nx, -1, MsgVel); MsgLog(zz, " Ready \n" ); /* determine frequency w sampling */ ntfft = npfar(nt+ntpad); nw = ntfft/2+1; dw = 2.0*PI/(ntfft*dt); iwmin = MAX(0,MIN(nw-1,NINT(2.0*PI*freqs[0]/dw))); iwmax = MAX(0,MIN(nw-1,NINT(2.0*PI*freqs[3]/dw))); /* read extrapolator table */ et = ezread(TabInfo); /* pret(zz -> fp_log, et); */ /* allocate workspace */ MsgLog(zz, "Allocating space ... "); qx = alloc2float(nx,sz); sx = alloc1float(nx); wdxov = alloc1float(nx); cpx = alloc1complex(nx); MsgLog(zz, " Ready \n"); sprintf(msg, "Process (%d) starting loop on depth steps(%d,%d)\n", pei, pei*(nz/pz), pei*(nz/pz) + sz); MsgLog(zz, msg); /* Cleanup qx */ for (iz=0; iz<sz; ++iz) for (ix=0; ix<nx; ++ix) qx[iz][ix] = 0.0; /* loop over frequencies w */ for (iw=iwmin,w=iwmin*dw; iw<iwmax; ++iw,w+=dw) { if (verbose && !(iw%1)) { sprintf(msg, "\t%d/%d\n",iw,iwmax); MsgLog(zz, msg); } /* load wavefield */ RecvCplx(cpx, nx, -1, MsgSlice); /* loop over depth steps nz */ for (iz=0; iz<sz; ++iz) { /* compute 2.0*dx/v(x) and zero migrated data */ for (ix=0; ix<nx; ix++) sx[ix] = 2.0*dx/v[iz][ix]; /* make w*dx/v(x) */ for (ix=0; ix<nx; ++ix) wdxov[ix] = w*sx[ix]; /* extrapolate wavefield */ etextrap(et,nx,wdxov,cpx); /* accumulate migrated data */ for (ix=0; ix<nx; ++ix) qx[iz][ix] += cpx[ix].r; } /* Send down the wavefield */ if ( pei != (pz -1)) SendCplx(cpx, nx, ToTid, MsgSlice); } /* End of loop for iw */ for (iz=0; iz<sz; iz++) { izz = pei*(nz/pz) + iz; if (verbose) { sprintf(msg, "Sending values for iz = %d\n",izz); MsgLog(zz, msg); } SendFI(qx[iz], nx, &izz, 1, MasterTid, MsgDepth); } sprintf(msg, "End of processing for (%d)\n",pei); MsgLog(zz, msg); /* free workspace */ free1float(sx); free1float(wdxov); free2float(v); free2float(qx); free1complex(cpx); pvm_exit(); return(0); }
/************************ end self doc ***********************************/ void main (int argc, char **argv) { /* declaration of variables */ FILE *fp, *gp; /* file pointers */ char *orientation = " "; /* orientation of recordings */ char *recFile = " "; /* receiver location file */ char *postFile = " "; /* posteriori file */ char *modelFile = " "; /* elastic model file */ char *corrDataFile = " "; /* data covariance file */ char *corrModelFile[3]; /* model covariance file */ char *frechetFile = " "; /* frechet derivative file */ int verbose; /* verbose flag */ int noFrechet; /* if 1 don't store Frechet derivatives */ int i, j, k, iU, iParam, offset, iR, shift; /* counters */ int wL; /* taper length */ int nParam; /* number of parameters altogether */ int numberParImp; /* number of distinct parameters in */ /* impedance inversion */ float dZ; /* layer thickness within target zone */ float F1, F2, F3; /* source components */ float depth; /* current depth used in defining limits */ /* for Frechet derivatives */ float fR; /* reference frequency */ float percU; /* amount of slowness windowing */ float percW; /* amount of frequency windowing */ float limZ[2]; /* target interval (Km) */ float tMod; /* maximum modeling time */ float phi; /* azimuth angle */ float *buffer1, *buffer2; /* auxiliary buffers */ float **CmPost; /* posteriori model covariance */ float **CmPostInv; /* posteriori model covariance - inverse */ /* allocing for orientation */ orientation = malloc(1); /* complex Zero */ zeroC = cmplx(0, 0); /* getting input parameters */ initargs(argc, argv); requestdoc(0); /* seismic data and model parameters */ if (!getparstring("model", &modelFile)) modelFile = "model"; if (!getparstring("postfile", &postFile)) postFile = "posteriori"; if (!getparstring("corrData", &corrDataFile)) corrDataFile = "corrdata"; if (!getparint("impedance", &IMPEDANCE)) IMPEDANCE = 0; if (!getparstring("frechetfile", &frechetFile)) noFrechet = 0; else noFrechet = 1; if (!getparint("prior", &PRIOR)) PRIOR = 1; if (IMPEDANCE) { if (!getparint("p", &ipFrechet)) vpFrechet = 1; if (!getparint("s", &isFrechet)) vsFrechet = 1; if (!getparint("r", &rhoFrechet)) rhoFrechet = 1; } else { if (!getparint("p", &vpFrechet)) vpFrechet = 1; if (!getparint("s", &vsFrechet)) vsFrechet = 1; if (!getparint("rho", &rhoFrechet)) rhoFrechet = 1; } /* a couple of things to use later in chain rule */ if (!IMPEDANCE) { ipFrechet = 0; isFrechet = 0; } else { if (ipFrechet && !isFrechet) { vpFrechet = 1; vsFrechet = 0; } if (!ipFrechet && isFrechet) { vpFrechet = 0; vsFrechet = 1; } if (!ipFrechet && !isFrechet) { vpFrechet = 0; vsFrechet = 0; } if (ipFrechet && isFrechet) { vpFrechet = 1; vsFrechet = 1; } if (rhoFrechet) { vpFrechet = 1; vsFrechet = 1; rhoFrechet = 1; } } if (!ipFrechet && ! isFrechet && !rhoFrechet && !vpFrechet && !vsFrechet) err("No inverse unknowns to work with!\n"); numberPar = vpFrechet + vsFrechet + rhoFrechet; numberParImp = ipFrechet + isFrechet + rhoFrechet; if (PRIOR) { if (vpFrechet || ipFrechet) { if (!getparstring("corrP", &corrModelFile[0])) corrModelFile[0] = "covP"; } if (vsFrechet || isFrechet) { if (!getparstring("corrS", &corrModelFile[1])) corrModelFile[1] = "covS"; } if (rhoFrechet) { if (!getparstring("corrR", &corrModelFile[2])) corrModelFile[2] = "covR"; } } if (!getparstring("orientation", &orientation)) orientation[0] = 'Z'; if (orientation[0] == 'z' || orientation[0] == 'Z') { VERTICAL = 1; RADIAL = 0; } else { VERTICAL = 0; RADIAL = 1; } if (!getparfloat("dz", &dZ)) dZ = .5; if (!getparfloat("targetbeg", &limZ[0])) limZ[0] = 0.5; if (!getparfloat("targetend", &limZ[1])) limZ[1] = 1.0; /* geometry */ if (!getparfloat("r1", &r1)) r1 = 0.25; if (!getparint("nr", &nR)) nR = 48; if (!getparfloat("dr", &dR)) dR = .025; if (!getparfloat("zs", &zs)) zs = .001; if (!getparfloat("F1", &F1)) F1 = 0; if (!getparfloat("F2", &F2)) F2 = 0; if (!getparfloat("F3", &F3)) F3 = 1; /* modeling */ if (!getparstring("receiverfile", &recFile)) recFile = " "; if (!getparfloat("u1", &u1)) u1 = 0.0; if (!getparfloat("u2", &u2)) u2 = 1.; if (!getparint("directwave", &directWave)) directWave = 1; if (!getparfloat("tau", &tau)) err("Specify tau!\n"); if (!getparint("nu", &nU)) nU = 1000; if (!getparfloat("f1", &f1)) f1 = 2; if (!getparfloat("f2", &f2)) f2 = 50; if (!getparfloat("dt", &dt)) dt = 0.004; if (!getparfloat("tmod", &tMod)) tMod = 8; if (!getparfloat("t1", &t1)) t1 = 0; if (!getparfloat("t2", &t2)) t2 = tMod; if (!getparint("hanning", &hanningFlag)) hanningFlag = 1; if (!getparfloat("wu", &percU)) percU = 10; percU /= 100; if (!getparfloat("ww", &percW)) percW = 25; percW /= 100; /* dialogue */ if (!getparint("verbose", &verbose)) verbose = 0; /* checking number of receivers */ fp = fopen(recFile, "r"); if (fp != NULL) { nR = 0; while (fscanf(fp, "%f\n", &auxm1) != EOF) nR++; } fclose(fp); /* some hard-coded parameters */ fR = 1; wR = 2 * PI * fR; /* reference frequency */ /* how many layers */ fp = fopen(modelFile,"r"); if (fp == NULL) err("No model file!\n"); nL = 0; depth = 0; while (fscanf(fp, "%f %f %f %f %f %f\n", &aux, &aux, &aux, &aux, &aux, &aux) != EOF) nL++; nL--; /* considering the unknown layers */ limRange = NINT((limZ[1] - limZ[0]) / dZ); if (verbose) { fprintf(stderr,"Number of layers: %d\n", nL + 1); fprintf(stderr,"Number of layers in target zone: %d\n", limRange); } if (IMPEDANCE) { nParam = numberParImp * limRange; } else { nParam = numberPar * limRange; } /* basic time-frequency stuff */ nSamples = NINT(tMod / dt) + 1; nSamples = npfar(nSamples); /* length of time misfit */ nDM = NINT((t2 - t1) / dt) + 1; /* maximum time for modeling */ tMod = dt * (nSamples - 1); dF = 1. / (tMod); /* adjusting f1 and f2 */ aux = dF; while (aux < f1) aux += dF; f1 = aux; while (aux < f2) aux += dF; f2 = aux; nF = NINT((f2 - f1) / dF); if (nF%2 == 0) { f2 += dF; nF++; } /* memory allocation */ alpha = alloc1float(nL + 1); beta = alloc1float(nL + 1); rho = alloc1float(nL + 1); qP = alloc1float(nL + 1); qS = alloc1float(nL + 1); thick = alloc1float(nL + 1); recArray = alloc1float(nR); PSlowness = alloc2complex(2, nL + 1); SSlowness = alloc2complex(2, nL + 1); S2Velocity = alloc2complex(2, nL + 1); CD = alloc1float(nDM * (nDM + 1) / 2); if (PRIOR) { if(vpFrechet || ipFrechet) CMP = alloc1float(limRange * (limRange + 1) / 2); if(vsFrechet || isFrechet) CMS = alloc1float(limRange * (limRange + 1) / 2); if(rhoFrechet) CMrho = alloc1float(limRange * (limRange + 1) / 2); } /* FRECHET derivative operator F */ F = alloc2float(nR * nDM, numberPar * limRange); if (IMPEDANCE) CmPostInv = alloc2float(numberParImp * limRange, numberParImp * limRange); else CmPostInv = alloc2float(numberPar * limRange, numberPar * limRange); v1 = alloc2complex(2, numberPar * limRange + 1); v2 = alloc2complex(2, numberPar * limRange + 1); DmB = alloc3complex(4, numberPar * (limRange + 2), nL); derFactor = alloc2complex(2, nL + 1); aux11 = alloc2complex(nR, numberPar * limRange); aux12 = alloc2complex(nR, numberPar * limRange); aux21 = alloc2complex(nR, numberPar * limRange); aux22 = alloc2complex(nR, numberPar * limRange); aux11Old = alloc2complex(nR, numberPar * limRange); aux12Old = alloc2complex(nR, numberPar * limRange); aux21Old = alloc2complex(nR, numberPar * limRange); aux22Old = alloc2complex(nR, numberPar * limRange); /* reading receiver configuration */ fp = fopen(recFile, "r"); if (fp == NULL) { /* standard end-on */ if (verbose) fprintf(stderr, "No receiver file available\n"); for (i = 0; i < nR; i++) { recArray[i] = r1 + i * dR; } } else { if (verbose) fprintf(stderr, "Reading receiver file %s\n", recFile); for (i = 0; i < nR; i++) { fscanf(fp, "%f\n", &recArray[i]); } } fclose(fp); /* reading the model file */ fp = fopen(modelFile,"r"); if (verbose) fprintf(stderr," Thickness rho vP qP vS qS\n"); for (k = 0; k < nL + 1; k++) { fscanf(fp, "%f %f %f %f %f %f\n", &thick[k], &rho[k], &alpha[k], &qP[k], &beta[k], &qS[k]); if (verbose) fprintf(stderr," %7.4f %4.3f %3.2f %5.1f %3.2f %5.1f\n", thick[k], rho[k], alpha[k], qP[k], beta[k], qS[k]); } fclose(fp); /* setting lim[0] and lim[1] */ for (depth = thick[0], i = 1; i <= nL; depth += thick[i], i++) { if (NINT(depth / dZ) <= NINT(limZ[0] / dZ)) lim[0] = i; if (NINT(depth / dZ) < NINT(limZ[1] / dZ)) lim[1] = i; } lim[1]++; /* some modeling parameters */ /* slowness increment */ dU = (u2 - u1) / (float) nU; /* computing the window length for the slowness domain */ epslon1 = (u2 - u1) * percU; wL = NINT(epslon1 / dU); wL = 2 * wL + 1; u2 += epslon1; nU = NINT((u2 - u1) / dU); /* new nU to preserve last slowness */ /* w/o being windowed */ taper = alloc1float(nU); /* building window for slowness integration */ for (i = (wL - 1) / 2, iU = 0; iU < nU; iU++) { taper[iU] = 1; if (iU >= nU - (wL - 1) / 2) { i++; taper[iU] = .42 - .5 * cos(2 * PI * (float) i / ((float) (wL - 1))) + .08 * cos(4 * PI * (float) i / ((float) (wL - 1))); } } /* filtering in frequency domain */ filter(percW); /* building frequency filtering */ /* I will assume that the receivers are in line (at z = 0) so phi = 0 */ phi = 0; epslon1 = F3; epslon2 = F1 * cos(phi) + F2 * sin(phi); /* correction for the 1st layer */ thick[0] -= zs; /* imaginary part of frequency for damping wrap-around */ tau = log(tau) / tMod; if (tau > TAUMAX) tau = TAUMAX; /* normalization for the complex slowness */ if (f1 > 7.5) wRef = f1 * 2 * PI; else wRef = 7.5 * 2 * PI; /* reading data and model covariance matrixes */ inputCovar(corrDataFile, corrModelFile); /* starting inverse procedure */ /* FRECHET derivative matrix */ gradient(); if (!noFrechet) { fp = fopen(frechetFile, "w"); for (i = 0; i < numberPar * limRange; i++) { fwrite(&F[i][0], sizeof(float), nR * nDM, fp); } fclose(fp); } /* building a-posteriori model covariance matrix */ /* prior information is used */ buffer1 = alloc1float(nDM); buffer2 = alloc1float(nDM * nR); if (verbose) fprintf(stderr, "Building posteriori covariance...\n"); for (iParam = 0; iParam < nParam; iParam++) { for (i = 0; i < nDM; i++) { for (offset = i, k = 0; k < nDM; k++) { buffer1[k] = CD[offset]; offset += MAX(SGN0(i - k) * (nDM - 1 - k), 1); } /* doing the product CD F */ for (iR = 0; iR < nR; iR++) { buffer2[iR * nDM + i] = 0; for (k = 0; k < nDM; k++) { buffer2[iR * nDM + i] += buffer1[k] * F[iParam][iR * nDM + k]; } } } for (j = 0; j < nParam; j++) { CmPostInv[j][iParam] = 0; for (k = 0; k < nDM * nR; k++) { CmPostInv[j][iParam] += buffer2[k] * F[j][k]; } } } if (verbose) fprintf(stderr, "Posteriori covariance built. Including prior...\n"); free1float(buffer1); buffer1 = alloc1float(nParam); /* including prior covariance matrix */ if (PRIOR) { shift = 0; if (IMPEDANCE) { if (ipFrechet) { for (iParam = 0; iParam < limRange; iParam++) { for (offset = iParam, k = 0; k < limRange; k++) { buffer1[k] = CMP[offset]; offset += MAX(SGN0(iParam - k) * (limRange - 1 - k), 1); } for (k = 0; k < limRange; k++) { CmPostInv[iParam][k] += buffer1[k]; } } shift += limRange; } } else { if (vpFrechet) { for (iParam = 0; iParam < limRange; iParam++) { for (offset = iParam, k = 0; k < limRange; k++) { buffer1[k] = CMP[offset]; offset += MAX(SGN0(iParam - k) * (limRange - 1 - k), 1); } for (k = 0; k < limRange; k++) { CmPostInv[iParam][k] += buffer1[k]; } } shift += limRange; } } if (IMPEDANCE) { if (isFrechet) { for (iParam = 0; iParam < limRange; iParam++) { for (offset = iParam, k = 0; k < limRange; k++) { buffer1[k] = CMS[offset]; offset += MAX(SGN0(iParam - k) * (limRange - 1 - k), 1); } for (k = 0; k < limRange; k++) { CmPostInv[iParam + shift][k + shift] += buffer1[k]; } } shift += limRange; } } else { if (vsFrechet) { for (iParam = 0; iParam < limRange; iParam++) { for (offset = iParam, k = 0; k < limRange; k++) { buffer1[k] = CMS[offset]; offset += MAX(SGN0(iParam - k) * (limRange - 1 - k), 1); } for (k = 0; k < limRange; k++) { CmPostInv[iParam + shift][k + shift] += buffer1[k]; } } shift += limRange; } } if (rhoFrechet) { for (iParam = 0; iParam < limRange; iParam++) { for (offset = iParam, k = 0; k < limRange; k++) { buffer1[k] = CMrho[offset]; offset += MAX(SGN0(iParam - k) * (limRange - 1 - k), 1); } for (k = 0; k < limRange; k++) { CmPostInv[iParam + shift][k + shift] += buffer1[k]; } } } } if (verbose) fprintf(stderr, "Prior included. Inverting matrix...\n"); /* freeing memory */ free1float(buffer1); free1float(buffer2); free1float(alpha); free1float(beta); free1float(rho); free1float(qP); free1float(qS); free1float(thick); free2complex(PSlowness); free2complex(SSlowness); free2complex(S2Velocity); free1float(CD); free1float(CMP); free1float(CMS); free1float(CMrho); free2float(F); free2complex(v1); free2complex(v2); free3complex(DmB); free2complex(derFactor); free2complex(aux11); free2complex(aux12); free2complex(aux21); free2complex(aux22); free2complex(aux11Old); free2complex(aux12Old); free2complex(aux21Old); free2complex(aux22Old); /* inverting the matrix */ CmPost = alloc2float(nParam, nParam); for (i = 0; i < nParam; i++) for (j = 0; j < nParam; j++) CmPostInv[i][j] = CmPost[i][j]; inverse_matrix(nParam, CmPostInv); if (verbose) fprintf(stderr, "Done with inverse matrix routine.\n"); buffer1 = alloc1float(nParam); gp = fopen(postFile, "w"); for (i = 0; i < nParam; i++) { fwrite(CmPostInv[i], sizeof(float), nParam, gp); } fclose(fp); }
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); }
int main(int argc, char **argv) { int nt,nx; /* numbers of samples */ float dt; /* sampling intervals */ int it,ix; /* sample indices */ int ntfft; /* dimensions after padding for FFT */ int nF; /* transform (output) dimensions */ int iF; /* transform sample indices */ register complex **ct=NULL; /* complex FFT workspace */ register float **rt=NULL; /* float FFT workspace */ int verbose; /* flag for echoing information */ char *tmpdir=NULL; /* directory path for tmp files */ cwp_Bool istmpdir=cwp_false;/* true for user-given path */ float v,fv,dv; /* phase velocity, first, step */ float amp,oamp; /* temp vars for amplitude spectrum */ int nv,iv; /* number of phase vels, counter */ float x; /* offset */ float omega; /* circular frequency */ float domega; /* circular frequency spacing (from dt) */ float onfft; /* 1 / nfft */ float phi; /* omega/phase_velocity */ complex *cDisp=NULL; /* temp array for complex dispersion */ float arg; /* temp var for phase calculation */ complex cExp; /* temp vars for phase calculation */ float *offs=NULL; /* input data offsets */ float fmax; /* max freq to proc (Hz) */ int out; /* output real or abs v(f) spectrum */ int norm; /* normalization flag */ float xmax; /* maximum abs(offset) of input */ float twopi, f; /* constant and frequency (Hz) */ /* Hook up getpar to handle the parameters */ initargs(argc,argv); requestdoc(1); /* Get info from first trace */ if (!gettr(&intrace)) err("can't get first trace"); nt = intrace.ns; /* dt is used only to set output header value d1 */ if (!getparfloat("dt", &dt)) { if (intrace.dt) { /* is dt field set? */ dt = ((double) intrace.dt)/ 1000000.0; } else { /* dt not set, exit */ err("tr.dt not set, stop."); } } warn("dt=%f",dt); if (!getparfloat("fv",&fv)) fv = 330; if (!getparfloat("dv",&dv)) dv = 25; if (!getparint("nv",&nv)) nv = 100; if (!getparint("out",&out)) out = 0; if (!getparint("norm",&norm)) norm = 0; if (!getparfloat("fmax",&fmax)) fmax = 50; if (!getparint("verbose", &verbose)) verbose = 0; /* Look for user-supplied tmpdir */ if (!getparstring("tmpdir",&tmpdir) && !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir=""; if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK)) err("you can't write in %s (or it doesn't exist)", tmpdir); checkpars(); /* Set up tmpfile */ if (STREQ(tmpdir,"")) { tracefp = etmpfile(); if (verbose) warn("using tmpfile() call"); } else { /* user-supplied tmpdir */ char directory[BUFSIZ]; strcpy(directory, tmpdir); strcpy(tracefile, temporary_filename(directory)); /* Trap signals so can remove temp files */ signal(SIGINT, (void (*) (int)) closefiles); signal(SIGQUIT, (void (*) (int)) closefiles); signal(SIGHUP, (void (*) (int)) closefiles); signal(SIGTERM, (void (*) (int)) closefiles); tracefp = efopen(tracefile, "w+"); istmpdir=cwp_true; if (verbose) warn("putting temporary files in %s", directory); } /* we have to allocate offs(nx) before we know nx */ offs = alloc1float(MAX_OFFS); ix = 0; nx = 0; xmax = 0.0; /* get nx and max abs(offset) */ do { ++nx; efwrite(intrace.data, FSIZE, nt, tracefp); offs[ix] = intrace.offset; if ( abs(intrace.offset) > xmax ) xmax = abs(intrace.offset); ++ix; } while (gettr(&intrace)); /* confirm that offsets are set */ if ( xmax == 0.0 ) err("tr.offset not set, stop."); /* Determine lengths for prime-factor FFTs */ ntfft = npfar(nt); if (ntfft >= SU_NFLTS || ntfft >= PFA_MAX) err("Padded nt=%d--too big",ntfft); /* Determine complex transform sizes */ nF = ntfft/2+1; /* must be this nF for fft */ onfft = 1.0 / ntfft; twopi = 2.0 * PI; domega = twopi * onfft / dt; /* Allocate space */ ct = alloc2complex(nF,nx); rt = alloc2float(ntfft,nx); /* Load traces into fft arrays and close tmpfile */ erewind(tracefp); for (ix=0; ix<nx; ++ix) { efread(rt[ix], FSIZE, nt, tracefp); /* pad dimension 1 with zeros */ for (it=nt; it<ntfft; ++it) rt[ix][it] = 0.0; } efclose(tracefp); /* Fourier transform dimension 1 */ pfa2rc(1,1,ntfft,nx,rt[0],ct[0]); /* set nF for processing */ if (fmax == 0) { /* process to nyquist */ nF = ntfft/2+1; } else { /* process to given fmax */ nF = (int) (twopi * fmax / domega); } /* data now in (w,x) domain allocate arrays */ cDisp = alloc1complex(nF); /* if requested, normalize by amplitude spectrum (normalizing by amplitude blows up aliasing and other artifacts) */ if (norm == 1) { for (iF=0; iF<nF; ++iF) { /* calc this frequency */ omega = iF * domega; f = omega / twopi; /* loop over traces */ for (ix=0; ix<nx; ++ix) { /* calc amplitude at this (f,x) location */ amp = rcabs(ct[ix][iF]); oamp = 1.0/amp; /* scale field by amp spectrum */ ct[ix][iF] = crmul(ct[ix][iF],oamp); } } } /* set global output trace headers */ outtrace.ns = 2 * nF; outtrace.dt = dt*1000000.; outtrace.trid = FUNPACKNYQ; outtrace.d1 = 1.0 / (ntfft * dt); /* Hz */ outtrace.f1 = 0; outtrace.d2 = dv; outtrace.f2 = fv; /* loop over phase velocities */ for (iv=0; iv<nv; ++iv) { /* this velocity */ v = fv + iv*dv; /* loop over frequencies */ for (iF=0; iF<nF; ++iF) { /* this frequency and phase */ omega = iF * domega; f = omega / twopi; phi = omega / v; /* initialize */ cDisp[iF] = cmplx(0.0,0.0); /* sum over abs offset (this is ok for 3D, too) */ for (ix=0; ix<nx; ++ix) { /* get this x */ x = abs(offs[ix]); /* target phase */ arg = - phi * x; cExp = cwp_cexp(crmul(cmplx(0.0,1.0), arg)); /* phase vel profile for this frequency */ cDisp[iF] = cadd(cDisp[iF],cmul(ct[ix][iF],cExp)); } } /* set trace counter */ outtrace.tracl = iv + 1; /* copy results to output trace interleaved format like sufft.c */ for (iF = 0; iF < nF; ++iF) { outtrace.data[2*iF] = cDisp[iF].r; outtrace.data[2*iF+1] = cDisp[iF].i; } /* output freqs at this vel */ puttr(&outtrace); } /* next frequency */ /* Clean up */ if (istmpdir) eremove(tracefile); return(CWP_Exit()); }
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; }
int main (int argc, char **argv) { int nt; /* number of time samples */ int nz; /* number of migrated depth samples */ int nx,nxshot; /* number of midpoints,shotgathers, the folds in a shot gather */ int flag=1; /*flag to use ft or meter as the unit*/ int dip=65; /*maximum dip angle to migrate*/ int iz,iw,ix,it,oldsx; /* loop counters*/ int ntfft; /* fft size*/ int nw; /* number of wave numbers */ int mytid,tids[NNTASKS],msgtype,rc,i;/*variable for PVM function*/ int nw1,task; int lpad=9999,rpad=9999; /*zero-traces padded on left and right sides*/ float f1,f2,f3,f4; /*frequencies to build the Hamming window*/ int nf1,nf2,nf3,nf4; /*the index for above frequencies*/ int NTASKS=0; /*number of slave tasks to start*/ char cpu_name[NNTASKS][80]; /*strings to store the computers' name*/ int flag_cpu=0; /*flag to control if using NTASKS variable*/ float sx,gxmin,gxmax; /*location of geophone and receivers*/ int isx,nxo,ifx=0; /*index for geophone and receivers*/ int ix1,ix2,ix3,il,ir; /*dummy index*/ float *wl,*wtmp; /*pointers for the souce function*/ float Fmax=25; /*peak frequency to make the Ricker wavelet*/ int ntw,truenw; /*number of frequencies to be migrated*/ float dt=0.004,dz; /*time, depth sampling interval*/ float ft; /*first time sample*/ float dw; /*frequency sampling interval*/ float fw; /*first frequency*/ float dx; /*spatial sampling interval*/ float **p,**cresult,**result_tmp; /* input, output data*/ float **v; /*double pointer direct to velocity structure*/ complex *wlsp,**cp,**cq,**cq1; /*pointers for internal usage*/ char *vfile=""; /* name of file containing velocities */ char *cpufile=""; /* name of file containing CPU name */ FILE *vfp,*cpu_fp; /* hook up getpar to handle the parameters */ initargs(argc,argv); requestdoc(1); /* get optional parameters */ if (!getparfloat("ft",&ft)) ft = 0.0; if (!getparint("nz",&nz)) err("nz must be specified"); if (!getparfloat("dz",&dz)) err("dz must be specified"); if (!getparstring("vfile", &vfile)) err("vfile must be specified"); if (!getparint("nxo",&nxo)) err("nxo must be specified"); if (!getparint("nxshot",&nxshot)) err("nshot must be specified"); if (!getparfloat("Fmax",&Fmax)) err("Fmax must be specified"); if (!getparfloat("f1",&f1)) f1 = 10.0; if (!getparfloat("f2",&f2)) f2 = 20.0; if (!getparfloat("f3",&f3)) f3 = 40.0; if (!getparfloat("f4",&f4)) f4 = 50.0; if (!getparint("lpad",&lpad)) lpad=9999; if (!getparint("rpad",&rpad)) rpad=9999; if (!getparint("flag",&flag)) flag=1; if (!getparint("dip",&dip)) dip=65; if (getparstring("cpufile", &cpufile)){ cpu_fp=fopen(cpufile,"r"); NTASKS=0; while(!feof(cpu_fp)){ fscanf(cpu_fp,"%s",cpu_name[NTASKS]); NTASKS++; } NTASKS-=1; flag_cpu=1; } else /*if cpufile not specified, the use NTASKS*/ if (!getparint("NTASKS",&NTASKS)) err("No CPUfile specified, NTASKS must be specified"); /*allocate space for the velocity profile*/ tshot=nxshot; v=alloc2float(nxo,nz); /*load velicoty file*/ vfp=efopen(vfile,"r"); efread(v[0],FSIZE,nz*nxo,vfp); efclose(vfp); /*PVM communication starts here*/ mytid=pvm_mytid(); /*get my pid*/ task=NTASKS; warn("\n %d",task); rc=0; /*spawn slave processes here*/ if(!flag_cpu){ rc=pvm_spawn(child,NULL,PvmTaskDefault,"",task,tids); } else{ for(i=0;i<NTASKS;i++){ rc+=pvm_spawn(child,NULL,PvmTaskHost,cpu_name[i],1,&tids[i]); } } /*show the pid of slaves if*/ for(i=0;i<NTASKS;i++){ if(tids[i]<0)warn("\n %d",tids[i]); else warn("\nt%x\t",tids[i]); } /*if not all the slaves start, then quit*/ if(rc<NTASKS){ warn("error");pvm_exit();exit(1);} /*broadcast the global parameters nxo,nz,dip to all slaves*/ pvm_initsend(PvmDataDefault); rc=pvm_pkint(&nxo,1,1); rc=pvm_pkint(&nz,1,1); rc=pvm_pkint(&dip,1,1); msgtype=PARA_MSGTYPE; task=NTASKS; rc=pvm_mcast(tids,task,msgtype); /*broadcast the velocity profile to all slaves*/ pvm_initsend(PvmDataDefault); rc=pvm_pkfloat(v[0],nxo*nz,1); msgtype=VEL_MSGTYPE; rc=pvm_mcast(tids,task,msgtype); /*free the space for velocity profile*/ free2float(v); /*loop over shot gathers begin here*/ loop: /* get info from first trace */ if (!gettr(&tr)) err("can't get first trace"); nt = tr.ns; /* let user give dt and/or dx from command line */ if (!getparfloat("dt", &dt)) { if (tr.dt) { /* is dt field set? */ dt = ((double) tr.dt)/1000000.0; } else { /* dt not set, assume 4 ms */ dt = 0.004; warn("tr.dt not set, assuming dt=0.004"); } } if (!getparfloat("dx",&dx)) { if (tr.d2) { /* is d2 field set? */ dx = tr.d2; } else { dx = 1.0; warn("tr.d2 not set, assuming d2=1.0"); } } sx=tr.sx; isx=sx/dx; gxmin=gxmax=tr.gx; oldsx=sx; /* determine frequency sampling interval*/ ntfft = npfar(nt); nw = ntfft/2+1; dw = 2.0*PI/(ntfft*dt); /*compute the index of the frequency to be migrated*/ fw=2.0*PI*f1; nf1=fw/dw+0.5; fw=2.0*PI*f2; nf2=fw/dw+0.5; fw=2.0*PI*f3; nf3=fw/dw+0.5; fw=2.0*PI*f4; nf4=fw/dw+0.5; /*the number of frequency to migrated*/ truenw=nf4-nf1+1; fw=0.0+nf1*dw; warn("nf1=%d nf2=%d nf3=%d nf4=%d nw=%d",nf1,nf2,nf3,nf4,truenw); fw=0.0; /* allocate space */ wl=alloc1float(ntfft); wlsp=alloc1complex(nw); /*generate the Ricker wavelet*/ wtmp=ricker(Fmax,dt,&ntw); for(it=0;it<ntfft;it++) wl[it]=0.0; for(it=0;it<ntw-12;it++) wl[it]=wtmp[it+12]; free1float( wtmp); /*Fourier transform the Ricker wavelet to frequency domain*/ pfarc(-1,ntfft,wl,wlsp); /* allocate space */ p = alloc2float(ntfft,nxo); cp = alloc2complex(nw,nxo); for (ix=0; ix<nxo; ix++) for (it=0; it<ntfft; it++) p[ix][it] = 0.0; /*read in a single shot gather*/ ix=tr.gx/dx; memcpy( (void *) p[ix], (const void *) tr.data,nt*FSIZE); nx = 0; while(gettr(&tr)){ int igx; if(tr.sx!=oldsx){ fseek(stdin,(long)(-240-nt*4),SEEK_CUR); break;} igx=tr.gx/dx; memcpy( (void *) p[igx], (const void *) tr.data,nt*FSIZE); if(gxmin>tr.gx)gxmin=tr.gx; if(gxmax<tr.gx)gxmax=tr.gx; nx++; oldsx=tr.sx; } warn("\nnx= %d",nx); warn("sx %f , gxmin %f gxmax %f",sx,gxmin,gxmax); /*transform the shot gather from time to frequency domain*/ pfa2rc(1,1,ntfft,nxo,p[0],cp[0]); /*compute the most left and right index for the migrated section*/ ix1=sx/dx; ix2=gxmin/dx; ix3=gxmax/dx; if(ix1>=ix3)ix3=ix1; if(ix1<=ix2)ix2=ix1; il=ix2; ir=ix3; ix2-=lpad; ix3+=rpad; if(ix2<0)ix2=0; if(ix3>nxo-1)ix3=nxo-1; /*the total traces to be migrated*/ nx=ix3-ix2+1; /*allocate space*/ cq = alloc2complex(nx,nw); cq1 = alloc2complex(nx,nw); /*transpose the frequency domain data from data[ix][iw] to data[iw][ix] and apply a Hamming at the same time*/ for (ix=0; ix<nx; ix++) for (iw=0; iw<nw; iw++){ float tmpp=0.0,tmppp=0.0; if(iw<nf1||iw>nf4) cq[iw][ix]=cmplx(0.0,0.0); else{ if(iw>=nf1&&iw<=nf2){tmpp=PI/(nf2-nf1);tmppp=tmpp*(iw-nf1)-PI;tmpp=0.54+0.46*cos(tmppp); cq[iw][ix]=crmul(cp[ix+ix2][iw],tmpp);} else{ if(iw>=nf3&&iw<=nf4){tmpp=PI/(nf4-nf3);tmppp=tmpp*(iw-nf3);tmpp=0.54+0.46*cos(tmppp); cq[iw][ix]=crmul(cp[ix+ix2][iw],tmpp);} else {cq[iw][ix]=cp[ix+ix2][iw];} } } cq[iw][ix]=cp[ix+ix2][iw]; cq1[iw][ix]=cmplx(0.0,0.0); } ix=sx/dx-ifx; warn("ix %d",ix); for(iw=0;iw<nw;iw++){ cq1[iw][ix-ix2]=wlsp[iw]; } free2float(p); free2complex(cp); free1float(wl); free1complex(wlsp); /*if the horizontal spacing interval is in feet, convert it to meter*/ if(!flag) dx*=0.3048; /*start of the timing function*/ time(&t1); /* send local parameters to all slaves*/ pvm_initsend(PvmDataDefault); ix=15; rc=pvm_pkint(&ix,1,1); rc=pvm_pkint(&ntfft,1,1); rc=pvm_pkint(&ix2,1,1); rc=pvm_pkint(&ix3,1,1); rc=pvm_pkint(&isx,1,1); rc=pvm_pkint(&il,1,1); rc=pvm_pkint(&ir,1,1); rc=pvm_pkfloat(&dx,1,1); rc=pvm_pkfloat(&dz,1,1); rc=pvm_pkfloat(&dw,1,1); rc=pvm_pkfloat(&dt,1,1); msgtype=PARA_MSGTYPE; task=NTASKS; rc=pvm_mcast(tids,task,msgtype); /* send all the frequency to slaves*/ count=NTASKS*5; /*count is the number of frequency components in a shot gather*/ nw=truenw; nw1=nw/(count); if(nw1==0)nw1=1; total=count=ceil(nw*1.0/nw1); /* if it is the first shot gather, send equal data to all the slaves, then for the following shot gathers, only send data when slave requests*/ if(nxshot==tshot){ for(i=0;i<NTASKS;i++){ float *tmpp; float fw1; int nww,byte,nwww; pvm_initsend(PvmDataDefault); nww=nf1+i*nw1;fw1=fw+nww*dw; nwww=nw1; byte=UnDone; rc=pvm_pkint(&byte,1,1); rc=pvm_pkfloat(&fw1,1,1); rc=pvm_pkint(&nwww,1,1); rc=pvm_pkfloat((float *)cq[nww],nx*nwww*2,1); rc=pvm_pkfloat((float *)cq1[nww],nx*nwww*2,1); msgtype=DATA_MSGTYPE; pvm_send(tids[i],msgtype); } count-=NTASKS; } while(count){ int tid0,bufid; float *tmpp; float fw1; int nww,byte,nwww; int i; i=total-count; msgtype=COM_MSGTYPE; bufid=pvm_recv(-1,msgtype); rc=pvm_upkint(&tid0,1,1); pvm_freebuf(bufid); pvm_initsend(PvmDataDefault); nww=nf1+i*nw1;fw1=fw+nww*dw; if(i==total-1)nwww=nw-nw1*i; else nwww=nw1; byte=UnDone; rc=pvm_pkint(&byte,1,1); rc=pvm_pkfloat(&fw1,1,1); rc=pvm_pkint(&nwww,1,1); rc=pvm_pkfloat((float *)cq[nww],nx*nwww*2,1); rc=pvm_pkfloat((float *)cq1[nww],nx*nwww*2,1); msgtype=DATA_MSGTYPE; pvm_send(tid0,msgtype); count--; } ix=Done; pvm_initsend(PvmDataDefault); rc=pvm_pkint(&ix,1,1); msgtype=DATA_MSGTYPE; pvm_mcast(tids,task,msgtype); free2complex(cq); free2complex(cq1); time(&t2); warn("\n %d shot been finished in %f seconds, Ntask=%d",nxshot,difftime(t2,t1),NTASKS); nxshot--; if(nxshot)goto loop; /*when all the shot gathers done, send signal to all slaves to request the partial imaging*/ ix=FinalDone; pvm_initsend(PvmDataDefault); rc=pvm_pkint(&ix,1,1); msgtype=PARA_MSGTYPE; pvm_mcast(tids,task,msgtype); /*allocate space for the final image*/ cresult = alloc2float(nz,nxo); for(ix=0;ix<nxo;ix++) for(iz=0;iz<nz;iz++) { cresult[ix][iz]=0.0; } result_tmp= alloc2float(nz,nxo); /*receive partial image from all the slaves*/ msgtype=RESULT_MSGTYPE; i=0; while(i<NTASKS){ int bufid; bufid=pvm_recv(-1,msgtype); rc=pvm_upkfloat(result_tmp[0],nxo*nz,1); pvm_freebuf(bufid); for(ix=0;ix<nxo;ix++) for(iz=0;iz<nz;iz++) { cresult[ix][iz]+=result_tmp[ix][iz]; } i=i+1; warn("\n i=%d been received",i); } /*send signal to all slaves to kill themselves*/ pvm_initsend(PvmDataDefault); pvm_mcast(tids,task,COM_MSGTYPE); /*output the final image*/ for(ix=0; ix<nxo; ix++){ tr.ns = nz ; tr.dt = dz*1000000.0 ; tr.d2 = dx; tr.offset = 0; tr.cdp = tr.tracl = ix; memcpy( (void *) tr.data, (const void *) cresult[ix],nz*FSIZE); puttr(&tr); } pvm_exit(); return EXIT_SUCCESS; }
int main (int argc, char **argv) { int nt; /* number of time samples */ int nz; /* number of migrated depth samples */ int nx; /* number of horizontal samples */ int nxshot; /* number of shots to be migrated */ int iz,iw,ix,it,ik; /* loop counters */ int igx; /* integerized gx value */ int ntfft,nxfft; /* fft size */ int nw,truenw,nk; /* number of wave numbers */ int dip=65; /* dip angle */ int oldigx=0; /* old value of integerized gx value */ int oldisx=0; /* old value of integerized sx value */ float sx,gx; /* x source and geophone location */ float gxmin=0.0,gxmax=0.0; /* x source and geophone location */ float min_sx_gx; /* min(sx,gx) */ float oldgx; /* old gx position */ float oldgxmin; /* old gx position */ float oldgxmax; /* old gx position */ float oldsx=0.0; /* old sx position */ int isx=0,nxo; /* index for source and geophone */ int ix1,ix2,ix3,ixshot,il=0,ir=0; /* dummy index */ int lpad,rpad; /* padding on both sides of the migrated section */ float *wl=NULL,*wtmp=NULL; float fmax; float f1,f2,f3,f4; int nf1,nf2,nf3,nf4; int ntw; float dt=0.004,dz; /* time and depth sampling interval */ float dw,dk; /* wavenumber and frequency sampling interval */ float fw,fk; /* first wavenumber and frequency */ float w,k; /* wavenumber and frequency */ float dx; /* spatial sampling interval */ float **p=NULL; float **cresult=NULL; /* input, output data */ float v1,vmin; double kz1,kz2; double phase1; float **v=NULL; float **vp=NULL; complex cshift1,cshift2; complex *wlsp=NULL; complex **cp=NULL; complex **cp1=NULL; complex **cq=NULL; complex **cq1=NULL; /*complex input,output*/ char *vfile=""; /* name of file containing velocities */ FILE *vfp=NULL; int verbose; /* verbose flag */ /* hook up getpar to handle the parameters */ initargs(argc,argv); requestdoc(1); /* get optional parameters */ MUSTGETPARINT("nz",&nz); MUSTGETPARFLOAT("dz",&dz); MUSTGETPARSTRING("vfile", &vfile); MUSTGETPARINT("nxo",&nxo); MUSTGETPARINT("nxshot",&nxshot); if (!getparfloat("fmax",&fmax)) fmax = 25. ; if (!getparfloat("f1",&f1)) f1 = 10.0; if (!getparfloat("f2",&f2)) f2 = 20.0; if (!getparfloat("f3",&f3)) f3 = 40.0; if (!getparfloat("f4",&f4)) f4 = 50.0; if (!getparint("lpad",&lpad)) lpad=9999; if (!getparint("rpad",&rpad)) rpad=9999; if (!getparint("dip",&dip)) dip=65; if (!getparint("verbose",&verbose)) verbose = 0; /* allocate space */ cresult = alloc2float(nz,nxo); vp=alloc2float(nxo,nz); /* load velocity file */ vfp=efopen(vfile,"r"); efread(vp[0],FSIZE,nz*nxo,vfp); efclose(vfp); /* zero out cresult array */ memset((void *) cresult[0], 0, nxo*nz*FSIZE); if (!gettr(&tr)) err("can't get first trace"); nt = tr.ns; get_sx_gx(&sx,&gx); min_sx_gx = MIN(sx,gx); gxmin=gxmax=gx; erewind(stdin); /* sx = sx - min_sx_gx; gx = gx - min_sx_gx; */ /* let user give dt and/or dx from command line */ if (!getparfloat("dt", &dt)) { if (tr.dt) { /* is dt field set? */ dt = ((double) tr.dt)/1000000.0; } else { /* dt not set, assume 4 ms */ dt = 0.004; warn("tr.dt not set, assuming dt=0.004"); } } if (!getparfloat("dx",&dx)) { if (tr.d2) { /* is d2 field set? */ dx = tr.d2; } else { dx = 1.0; warn("tr.d2 not set, assuming d2=1.0"); } } do { /* begin loop over shots */ /* determine frequency sampling interval*/ ntfft = npfar(nt); nw = ntfft/2+1; dw = 2.0*PI/(ntfft*dt); /* compute the index of the frequency to be migrated */ fw=2.0*PI*f1; nf1=fw/dw+0.5; fw=2.0*PI*f2; nf2=fw/dw+0.5; fw=2.0*PI*f3; nf3=fw/dw+0.5; fw=2.0*PI*f4; nf4=fw/dw+0.5; /* the number of frequencies to migrated */ truenw=nf4-nf1+1; fw=0.0+nf1*dw; if (verbose) warn("nf1=%d nf2=%d nf3=%d nf4=%d nw=%d",nf1,nf2,nf3,nf4,truenw); /* allocate space */ wl=alloc1float(ntfft); wlsp=alloc1complex(nw); /* generate the Ricker wavelet */ wtmp=ricker(fmax,dt,&ntw); /* zero out wl[] array */ memset((void *) wl, 0, ntfft*FSIZE); /* CHANGE BY CHRIS STOLK, Dec. 11, 2005 */ /* The next two lines are the old code, */ /* it is erroneous because the peak of */ /* the wavelet occurs at positive time */ /* instead of time zero. */ for(it=0;it<ntw;it++) wl[it]=wtmp[it]; /* New code: we put in the wavelet in a centered fashion */ /* for(it=0;it<ntw;it++) { wl[(it-ntw/2+ntfft) % ntfft]=wtmp[it]; } */ /* warn("%12i %12f \n",(it-ntw/2+ntfft) % ntfft,wtmp[it]); */ /* End of new code */ free1float(wtmp); /* fourier transform wl array */ pfarc(-1,ntfft,wl,wlsp); /* CS TEST: this was used to output the array wlsp (the wavelet in the frequency domain) to the file CSinfo, no longer needed and commented out */ /* FILE *CSinfo; CSinfo=fopen("CSinfo","w"); fprintf(CSinfo,"ntfft=%10i\n",ntfft); fprintf(CSinfo,"ntw=%10i\n",ntw); for(iw=0;iw<ntfft/2+1;iw++) fprintf(CSinfo,"%12f %12f \n",wlsp[iw].r,wlsp[iw].i); fclose(CSinfo); */ /* conclusion from the analysis of this info: the wavelet (whose fourier transform is in wlsp) is not zero phase!!! so there is a timeshift error!!! Conclusion obtained dec 11 2005 */ /* CS */ /* allocate space */ p = alloc2float(ntfft,nxo); cq = alloc2complex(nw,nxo); /* zero out p[][] array */ memset((void *) p[0], 0, ntfft*nxo*FSIZE); /* initialize a number of items before looping over traces */ nx = 0; if (gx < 0 ) { igx=gx/dx + nxo; } else { igx=gx/dx ; } oldigx=igx; oldsx=sx; oldgx=gx; oldgxmax=gxmax; oldgxmin=gxmin; while(gettr(&tr)) { /* begin looping over traces within a shot gather */ /* get sx and gx */ get_sx_gx(&sx,&gx); /* warn("%d nx=%d", igx, nx); sx = (sx - min_sx_gx); gx = (gx - min_sx_gx); */ if (gx < 0 ) { igx=gx/dx + nxo; } else { igx=gx/dx ; } if (igx==oldigx) warn("repeated igx!!! check dx or scalco value!!!"); oldigx = igx; if(tr.sx!=oldsx){ efseeko(stdin,(off_t)(-240-nt*4),SEEK_CUR); break;} if(gxmin>gx)gxmin=gx; if(gxmax<gx)gxmax=gx; if(verbose) warn(" inside loop: min_sx_gx %f isx %d igx %d gx %f sx %f",min_sx_gx,isx,igx,gx,sx); /* sx, gx must increase monotonically */ if (!(oldsx <= sx) ) err("sx field must be monotonically increasing!"); if (!(oldgx <= gx) ) err("gx field must be monotonically increasing!"); memcpy( (void *) p[igx], (const void *) tr.data,nt*FSIZE); ++nx; } isx=oldsx/dx; if (isx==oldisx) warn("repeated isx!!! check dx or scalco value!!!"); oldisx=isx; ixshot=isx; if(verbose) { warn("sx %f, gx %f , gxmin %f gxmax %f nx %d",sx,gx,gxmin,gxmax, nx); warn("isx %d igx %d ixshot %d" ,isx,igx,ixshot); } /* transform the shot gather from time to frequency domain */ pfa2rc(1,1,ntfft,nxo,p[0],cq[0]); /* compute the most left and right index for the migrated */ /* section */ ix1=oldsx/dx; ix2=gxmin/dx; ix3=gxmax/dx; if(ix1>=ix3)ix3=ix1; if(ix1<=ix2)ix2=ix1; il=ix2; ir=ix3; ix2-=lpad; ix3+=rpad; if(ix2<0)ix2=0; if(ix3>nxo-1)ix3=nxo-1; /* the total traces to be migrated */ nx=ix3-ix2+1; nw=truenw; /* determine wavenumber sampling (for complex to complex FFT) */ nxfft = npfa(nx); nk = nxfft; dk = 2.0*PI/(nxfft*dx); fk = -PI/dx; /* allocate space for velocity profile within the aperature */ v=alloc2float(nx,nz); for(iz=0;iz<nz;iz++) for(ix=0;ix<nx;ix++) v[iz][ix]=vp[iz][ix+ix2]; /* allocate space */ cp = alloc2complex(nx,nw); cp1 = alloc2complex(nx,nw); /* transpose the frequency domain data from */ /* data[ix][iw] to data[iw][ix] and apply a */ /* Hamming at the same time */ for (ix=0; ix<nx; ix++) { for (iw=0; iw<nw; iw++){ float tmpp=0.0,tmppp=0.0; if(iw>=(nf1-nf1)&&iw<=(nf2-nf1)){ tmpp=PI/(nf2-nf1); tmppp=tmpp*(iw-nf1)-PI; tmpp=0.54+0.46*cos(tmppp); cp[iw][ix]=crmul(cq[ix+ix2][iw+nf1],tmpp); } else { if(iw>=(nf3-nf1)&&iw<=(nf4-nf1)){ tmpp=PI/(nf4-nf3); tmppp=tmpp*(iw-nf3); tmpp=0.54+0.46*cos(tmppp); cp[iw][ix]=crmul(cq[ix+ix2][iw+nf1],tmpp); } else { cp[iw][ix]=cq[ix+ix2][iw+nf1];} } cp1[iw][ix]=cmplx(0.0,0.0); } } for(iw=0;iw<nw;iw++){ cp1[iw][ixshot-ix2]=wlsp[iw+nf1]; } if(verbose) { warn("ixshot %d ix %d ix1 %d ix2 %d ix3 %d",ixshot,ix,ix1,ix2,ix3); warn("oldsx %f ",oldsx); } free2float(p); free2complex(cq); free1float(wl); free1complex(wlsp); /* allocating space */ cq=alloc2complex(nxfft,nw); cq1=alloc2complex(nxfft,nw); /* loops over depth */ for(iz=0;iz<nz;++iz){ /* the imaging condition */ for(ix=0;ix<nx;ix++){ for(iw=0,w=fw;iw<nw;w+=dw,iw++){ complex tmp; float ratio=10.0; if(fabs(ix+ix2-ixshot)*dx<ratio*iz*dz) tmp=cmul(cp[iw][ix],cp1[iw][ix]); else tmp=cmplx(0.0,0.0); cresult[ix+ix2][iz]+=tmp.r/ntfft; } } /* get the minimum velocity */ vmin=0; for(ix=il-ix2;ix<=ir-ix2;ix++){ vmin+=1.0/v[iz][ix]/(ir-il+1); } vmin=1.0/vmin; /* compute the shifted wavefield */ for (ik=0;ik<nx;++ik) { for (iw=0; iw<nw; ++iw) { cq[iw][ik] = ik%2 ? cneg(cp[iw][ik]) : cp[iw][ik]; cq1[iw][ik] = ik%2 ? cneg(cp1[iw][ik]) : cp1[iw][ik]; } } /* zero out cq[][] cq1[][] */ for (ik=nx; ik<nk; ++ik) { for (iw=0; iw<nw; ++iw) { cq[iw][ik] = cmplx(0.0,0.0); cq1[iw][ik] = cmplx(0.0,0.0); } } /* FFT to W-K domain */ pfa2cc(-1,1,nk,nw,cq[0]); pfa2cc(-1,1,nk,nw,cq1[0]); v1=vmin; for(ik=0,k=fk;ik<nk;++ik,k+=dk) { for(iw=0,w=fw;iw<nw;++iw,w+=dw){ if(w==0.0)w=1.0e-10/dt; kz1=1.0-pow(v1*k/w,2.0); if(kz1>0.15){ phase1 = -w*sqrt(kz1)*dz/v1; cshift1 = cmplx(cos(phase1), sin(phase1)); cq[iw][ik] = cmul(cq[iw][ik],cshift1); cq1[iw][ik] = cmul(cq1[iw][ik],cshift1); } else { cq[iw][ik] = cq1[iw][ik] = cmplx(0.0,0.0); } } } pfa2cc(1,1,nk,nw,cq[0]); pfa2cc(1,1,nk,nw,cq1[0]); for(ix=0;ix<nx;++ix) { for(iw=0,w=fw;iw<nw;w+=dw,++iw){ float a=0.015,g=1.0; int I=10; if(ix<=I)g=exp(-a*(I-ix)*(I-ix)); if(ix>=nx-I)g=exp(-a*(-nx+I+ix)*(-nx+I+ix)); cq[iw][ix] = crmul( cq[iw][ix],1.0/nxfft); cq[iw][ix] =ix%2 ? cneg(cq[iw][ix]) : cq[iw][ix]; kz2=(1.0/v1-1.0/v[iz][ix])*w*dz; cshift2=cmplx(cos(kz2),sin(kz2)); cp[iw][ix]=cmul(cq[iw][ix],cshift2); cq1[iw][ix] = crmul( cq1[iw][ix],1.0/nxfft); cq1[iw][ix] =ix%2 ? cneg(cq1[iw][ix]) : cq1[iw][ix]; cp1[iw][ix]=cmul(cq1[iw][ix],cshift2); } } } free2complex(cp); free2complex(cp1); free2complex(cq); free2complex(cq1); free2float(v); --nxshot; } while(nxshot); /* restore header fields and write output */ for(ix=0; ix<nxo; ix++){ tr.ns = nz; tr.d1 = dz; tr.d2 = dx; tr.offset = 0; tr.cdp = tr.tracl = ix; memcpy( (void *) tr.data, (const void *) cresult[ix],nz*FSIZE); puttr(&tr); } return(CWP_Exit()); }
int main (int argc, char **argv) { int nt; /* number of time samples */ int ntau; /* number of migrated time samples */ int nx; /* number of midpoints */ int ik,ix,it,itau,itmig;/* loop counters */ int nxfft; /* fft size */ int nk; /* number of wave numbers */ int ntmig,nvmig; float dt; /* time sampling interval */ float ft; /* first time sample */ float dtau; /* migrated time sampling interval */ float ftau; /* first migrated time value */ float dk; /* wave number sampling interval */ float fk; /* first wave number */ float Q, ceil; /* quality factor, ceiling of amplitude */ float t,k; /* time,wave number */ float *tmig, *vmig; /* arrays of time, interval velocities */ float dx; /* spatial sampling interval */ float *vt; /* velocity v(t) */ float **p,**q; /* input, output data */ complex **cp,**cq; /* complex input,output */ char *vfile=""; /* name of file containing velocities */ int verbose=0; /* flag for echoing info */ char *tmpdir; /* directory path for tmp files */ cwp_Bool istmpdir=cwp_false;/* true for user-given path */ /* hook up getpar to handle the parameters */ initargs(argc,argv); requestdoc(1); /* get info from first trace */ if (!gettr(&tr)) err("can't get first trace"); nt = tr.ns; /* let user give dt and/or dx from command line */ if (!getparfloat("dt", &dt)) { if (tr.dt) { /* is dt field set? */ dt = ((double) tr.dt)/1000000.0; } else { /* dt not set, assume 4 ms */ dt = 0.004; warn("tr.dt not set, assuming dt=0.004"); } } if (!getparfloat("dx",&dx)) { if (tr.d2) { /* is d2 field set? */ dx = tr.d2; } else { dx = 1.0; warn("tr.d2 not set, assuming d2=1.0"); } } /* get optional parameters */ if (!getparfloat("ft",&ft)) ft = 0.0; if (!getparint("ntau",&ntau)) ntau = nt; CHECK_NT("ntau",ntau); if (!getparfloat("dtau",&dtau)) dtau = dt; if (!getparfloat("ftau",&ftau)) ftau = ft; if (!getparfloat("Q",&Q)) Q = 1.0e6; if (!getparfloat("ceil",&ceil)) ceil = 1.0e6; if (verbose)warn("Q=%f ceil=%f",Q,ceil); if (!getparint("verbose", &verbose)) verbose = 0; /* Look for user-supplied tmpdir */ if (!getparstring("tmpdir",&tmpdir) && !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir=""; if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK)) err("you can't write in %s (or it doesn't exist)", tmpdir); /* store traces and headers in tempfiles while getting a count */ if (STREQ(tmpdir,"")) { tracefp = etmpfile(); headerfp = etmpfile(); if (verbose) warn("using tmpfile() call"); } else { /* user-supplied tmpdir */ char directory[BUFSIZ]; strcpy(directory, tmpdir); strcpy(tracefile, temporary_filename(directory)); strcpy(headerfile, temporary_filename(directory)); /* Trap signals so can remove temp files */ signal(SIGINT, (void (*) (int)) closefiles); signal(SIGQUIT, (void (*) (int)) closefiles); signal(SIGHUP, (void (*) (int)) closefiles); signal(SIGTERM, (void (*) (int)) closefiles); tracefp = efopen(tracefile, "w+"); headerfp = efopen(headerfile, "w+"); istmpdir=cwp_true; if (verbose) warn("putting temporary files in %s", directory); } nx = 0; do { ++nx; efwrite(&tr,HDRBYTES,1,headerfp); efwrite(tr.data, FSIZE, nt, tracefp); } while (gettr(&tr)); erewind(tracefp); erewind(headerfp); /* determine wavenumber sampling (for real to complex FFT) */ nxfft = npfar(nx); nk = nxfft/2+1; dk = 2.0*PI/(nxfft*dx); fk = 0.0; /* allocate space */ p = alloc2float(nt,nxfft); q = alloc2float(ntau,nxfft); cp = alloc2complex(nt,nk); cq = alloc2complex(ntau,nk); /* load traces into the zero-offset array and close tmpfile */ efread(*p, FSIZE, nt*nx, tracefp); efclose(tracefp); /* determine velocity function v(t) */ vt = ealloc1float(ntau); if (!getparstring("vfile",&vfile)) { ntmig = countparval("tmig"); if (ntmig==0) ntmig = 1; tmig = ealloc1float(ntmig); if (!getparfloat("tmig",tmig)) tmig[0] = 0.0; nvmig = countparval("vmig"); if (nvmig==0) nvmig = 1; if (nvmig!=ntmig) err("number of tmig and vmig must be equal"); vmig = ealloc1float(nvmig); if (!getparfloat("vmig",vmig)) vmig[0] = 1500.0; for (itmig=1; itmig<ntmig; ++itmig) if (tmig[itmig]<=tmig[itmig-1]) err("tmig must increase monotonically"); for (it=0,t=0.0; it<ntau; ++it,t+=dt) intlin(ntmig,tmig,vmig,vmig[0],vmig[ntmig-1], 1,&t,&vt[it]); } else { if (fread(vt,sizeof(float),nt,fopen(vfile,"r"))!=nt) err("cannot read %d velocities from file %s",nt,vfile); } checkpars(); /* pad with zeros and Fourier transform x to k */ for (ix=nx; ix<nxfft; ix++) for (it=0; it<nt; it++) p[ix][it] = 0.0; pfa2rc(-1,2,nt,nxfft,p[0],cp[0]); /* migrate each wavenumber */ for (ik=0,k=fk; ik<nk; ik++,k+=dk) gazdagvt(k,nt,dt,ft,ntau,dtau,ftau,vt,cp[ik],cq[ik], Q, ceil); /* Fourier transform k to x (including FFT scaling) */ pfa2cr(1,2,ntau,nxfft,cq[0],q[0]); for (ix=0; ix<nx; ix++) for (itau=0; itau<ntau; itau++) q[ix][itau] /= nxfft; /* restore header fields and write output */ for (ix=0; ix<nx; ++ix) { efread(&tr,HDRBYTES,1,headerfp); tr.ns = ntau ; tr.dt = dtau * 1000000.0 ; tr.delrt = ftau * 1000.0 ; memcpy( (void *) tr.data, (const void *) q[ix],ntau*FSIZE); puttr(&tr); } /* Clean up */ efclose(headerfp); if (istmpdir) eremove(headerfile); if (istmpdir) eremove(tracefile); return(CWP_Exit()); }
int main(int argc, char **argv) { int ix,it; /* loop counters */ int i,j,k; int ntr; /* number of input traces */ int nt; /* number of time samples */ int nx; /* number of horizontal samples */ float dt; /* Time sample interval */ float dx=1; /* horizontal sample interval */ float pminf; /* Minimum slope for Tau-P transform */ float pmaxf; /* Maximum slope for Tau-P transform */ float dpf; /* slope sampling interval */ int np; /* number of slopes for slant stack */ int nwin; /* spatial window length */ int npoints; /* number of points for rho filter */ float **twin; /* array[nwin][nt] of window traces */ float **pwin; /* array[np][nt] of sl traces */ int ntrw; /* number of traces in processing window */ /* full multiple of nwin */ int ist; /* start processing from this window */ int ntfft; float **traces; int w; /* flag to apply semblance weights */ int s; /* flag to apply smoothing weights */ int sl1; /* length of smoothing window */ int sl2; /* length of smoothing window */ float *smb; /* semblance weights */ double pw; float smbwin; int sn; float *spw; /* array of spatial weights */ float **out_traces; /* array[nx][nt] of output traces */ int verbose; /* flag for echoing information */ char *tmpdir; /* directory path for tmp files */ cwp_Bool istmpdir=cwp_false;/* true for user-given path */ float fh1; /* maximum frequency before taper */ float fh2; /* maximum frequency */ float prw; /* prewithening */ /* hook up getpar to handle the parameters */ initargs(argc,argv); requestdoc(1); if (!getparint("verbose", &verbose)) verbose = 0; /* Look for user-supplied tmpdir */ if (!getparstring("tmpdir",&tmpdir) && !(tmpdir = getenv("CWP_TMPDIR"))) tmpdir=""; if (!STREQ(tmpdir, "") && access(tmpdir, WRITE_OK)) err("you can't write in %s (or it doesn't exist)", tmpdir); /* get info from first trace */ if (!gettr(&tr)) err("can't get first trace"); nt = tr.ns; dt = (float) tr.dt/1000000.0; /* Store traces in tmpfile while getting a count */ if (STREQ(tmpdir,"")) { tracefp = etmpfile(); headerfp = etmpfile(); if (verbose) warn("using tmpfile() call"); } else { /* user-supplied tmpdir */ char directory[BUFSIZ]; strcpy(directory, tmpdir); strcpy(tracefile, temporary_filename(directory)); strcpy(headerfile, temporary_filename(directory)); /* Trap signals so can remove temp files */ signal(SIGINT, (void (*) (int)) closefiles); signal(SIGQUIT, (void (*) (int)) closefiles); signal(SIGHUP, (void (*) (int)) closefiles); signal(SIGTERM, (void (*) (int)) closefiles); tracefp = efopen(tracefile, "w+"); headerfp = efopen(headerfile, "w+"); istmpdir=cwp_true; if (verbose) warn("putting temporary files in %s", directory); } ntr = 0; do { ++ntr; efwrite(&tr, 1, HDRBYTES, headerfp); efwrite(tr.data, FSIZE, nt, tracefp); } while (gettr(&tr)); /* get general flags and parameters and set defaults */ if (!getparint("np",&np)) np = 25; if (!getparfloat("pminf",&pminf)) pminf = -0.01; if (!getparfloat("pmaxf",&pmaxf)) pmaxf = 0.01; if (!getparfloat("fh1",&fh1)) fh1 = 100; if (!getparfloat("fh2",&fh2)) fh2 = 120; if (!getparfloat("prw",&prw)) prw = 0.01; if (!getparfloat("dx",&dx)) dx = 1.0; if (!getparint("npoints",&npoints)) npoints = 71; if (!getparint("nwin",&nwin)) nwin= 5; if (!getparfloat("dt",&dt)) dt = dt; if (!getparfloat("smbwin",&smbwin)) smbwin = 0.05; if (!getpardouble("pw",&pw)) pw = 1.0; if (!getparint("w",&w)) w = 0; if (!getparint("s",&s)) s = 0; if (!getparint("sl1",&sl1)) sl1 = 2*nwin; if (!getparint("sl2",&sl2)) sl2 = nwin; nx = ntr; if (dt == 0.0) err("header field dt not set, must be getparred"); /* allocate space */ ntfft=npfar(nt); ntrw=nwin; while (ntrw < ntr) { ntrw+=nwin; } ist = ntrw-ntr/2; twin = alloc2float(nt, nwin); pwin = ealloc2float(ntfft,np); traces = alloc2float(nt, ntr); out_traces = alloc2float(nt, ntr); smb = ealloc1float(nt); /* Set up some constans*/ dpf=(pmaxf-pminf)/(np-1); sn = (int)(smbwin/dt+0.5); if(sn%2==0) sn++; if(nwin%2==0) nwin++; /* spatial trace weigths */ spw = ealloc1float(nwin); for(k=0,i=1;k<nwin/2+1;k++,i++) spw[k] = (float)i; for(k=nwin/2+1,i=nwin/2;k<nwin;k++,i--) spw[k] = (float)i; /* for(k=0,i=1;k<nwin;k++,i++) spw[k] =1.0; */ /* load traces into an array and close temp file */ erewind(headerfp); erewind(tracefp); memset( (void *) traces[0], (int) '\0', (nt*ntr)*FSIZE); memset( (void *) out_traces[0], (int) '\0', (nt*ntr)*FSIZE); for (ix=0; ix<ntr; ix++) fread (traces[ix], FSIZE, nt, tracefp); efclose (tracefp); if (istmpdir) eremove(tracefile); /* do requested operation */ for(i=0; i<ntr; i+=nwin/2) { memcpy( (void *) twin[0], (const void *) traces[i], nt*nwin*FSIZE); /* compute forward slant stack */ /* fwd_tx_sstack (dt, nt, nwin, -nwin/2*dx, dx, np, pminf, dpf, twin, pwin); */ forward_p_transform(nwin,nt,dt,pmaxf*1000.0,pminf*1000.0,dpf*1000.0, 0.0,fh1,fh2,3.0,30.0,400,5,1,0,0,1,prw, 0.0,nwin*dx,1,dx,0.0,0.0,0.0,twin,pwin); /* fwd_FK_sstack (dt, nt, nwin, -nwin/2*dx, dx, np, pminf, dpf,0, twin, pwin); */ /* compute semplance */ if(w==1) { semb(sn,pwin,np,nt,smb); /* apply weights */ for(j=0;j<nt;j++) for(k=0;k<np;k++) pwin[k][j] *=smb[j]; } if(s==1) { gaussian2d_smoothing (np,nt,sl2,sl1,pwin); } if(s==2) { dlsq_smoothing (nt,np,0,nt,0,np,sl1,sl2,0,pwin); } /* compute inverse slant stack */ /* inv_tx_sstack (dt, nt, nwin, npoints,-nwin/2*dx, dx, np,pminf,dpf, pwin, twin); */ inverse_p_transform(nwin,nt,dt,pmaxf*1000.0,pminf*1000.0,dpf*1000.0, 0.0,fh1,fh2,0.0,nwin*dx,1,dx,0.0, pwin,twin); /* inv_FK_sstack (dt, nt, nwin,-nwin/2*dx, dx, np,pminf,dpf,0, pwin, twin); */ { register int itr,it,spind;; for(itr=0;itr<nwin;itr++) { spind=i+itr; for(it=0;it<nt;it++) { if(spind>0 && spind<ntr) out_traces[spind][it] += spw[itr]*twin[itr][it]; /* out_traces[spind][it] = twin[itr][it]; */ } } } /* fprintf(stderr," Trace #= %5d\n",i); */ } /* write output traces */ erewind(headerfp); { register int itr; for (itr=0; itr<ntr; itr++) { efread(&tr, 1, HDRBYTES, headerfp); for (it=0; it<nt; it++) tr.data[it]=out_traces[itr][it]; puttr(&tr); } } efclose(headerfp); if (istmpdir) eremove(headerfile); /* free allocated space */ free2float(out_traces); free1float(spw); return EXIT_SUCCESS; }
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; }
static void dmooff (float offset, float fmax, float sdmo, int nx, float dx, int nt, float dt, float ft, float *vrms, float **ptx) /***************************************************************************** perform dmo in f-k domain for one offset ****************************************************************************** Input: offset source receiver offset fmax maximum frequency sdmo DMO stretch factor nx number of midpoints dx midpoint sampling interval nt number of time samples dt time sampling interval ft first time vrms array[nt] of rms velocities ptx array[nx][nt] for p(t,x), zero-padded for fft (see notes) Output: ptx array[nx][nt] for dmo-corrected p(t,x) ****************************************************************************** Notes: To avoid having to allocate a separate work space that is larger than the array ptx[nx][nt], ptx must be zero-padded to enable Fourier transform from x to k via prime factor FFT. nxpad (nx after zero-padding) can be estimated by nxpad = 2+npfar(nx+(int)(0.5*ABS(offset/dx))); where npfar() is a function that returns a valid length for real-to-complex prime factor FFT. ptx[nx] to ptx[nxfft-1] must point to zeros. ****************************************************************************** Author: Dave Hale, Colorado School of Mines, 08/08/91 *****************************************************************************/ { int nxfft,itmin,nu,nufft,nw,nk,ix,iu,iw,ik,it,iwn, iwmin,iwmax,nupad,ikmax; float dw,dk,tcon,wwscl,scale,scales,kmax, amp,phase,fr,fi,pwr,pwi, wmin,wmax,fftscl,du,fu,w,k,osdmo,*uoft,*tofu; complex czero=cmplx(0.0,0.0),**ptk,*pu,*pw; /* number of cdps after padding for fft */ nxfft = npfar(nx+(int)(0.5*ABS(offset/dx))); /* get minimum time of first non-zero sample */ for (ix=0,itmin=nt; ix<nx; ++ix) { for (it=0; it<itmin && ptx[ix][it]==0.0; ++it); itmin = it; } /* if all zeros, simply return */ if (itmin>=nt) return; /* make stretch and compress functions t(u) and u(t) */ maketu(offset,itmin,fmax,nt,dt,ft,vrms,&uoft,&nu,&du,&fu,&tofu,&tcon); /* adjust DMO stretch factor for nominal error in log stretch; */ /* solve sdmo*(sqrt(1-a/sdmo)-1) = 0.5*log(1-a), where a=0.5 */ sdmo *= .62; /* inverse of dmo stretch factor */ osdmo = 1.0/sdmo; /* maximum DMO shift (in samples) for any wavenumber k */ nupad = 1.5*sdmo*tcon/du; /* frequency sampling */ nufft = npfa(nu+nupad); nw = nufft; dw = 2.0*PI/(nufft*du); /* allocate workspace */ pu = pw = ealloc1complex(nufft); /* wavenumber sampling and maximum wavenumber to apply dmo */ nk = nxfft/2+1; dk = 2.0*PI/ABS(nxfft*dx); kmax = PI/ABS(dx); ikmax = NINT(kmax/dk); /* pointers to complex p(t,k) */ ptk = (complex**)ealloc1(nk,sizeof(complex*)); for (ik=0; ik<nk; ++ik) ptk[ik] = (complex*)ptx[0]+ik*nt; /* fft scale factor */ fftscl = (float)nk/(float)(ikmax+1)/(nufft*nxfft); /* Fourier transform p(t,x) to p(t,k) */ pfa2rc(-1,2,nt,nxfft,ptx[0],ptk[0]); /* loop over wavenumbers less than maximum */ for (ik=0,k=0.0; ik<=ikmax; ++ik,k+=dk) { /* stretch p(t;k) to p(u) */ ints8c(nt,dt,ft,ptk[ik],czero,czero,nu,tofu,pu); /* pad with zeros and Fourier transform p(u) to p(w) */ for (iu=nu; iu<nufft; ++iu) pu[iu].r = pu[iu].i = 0.0; pfacc(1,nufft,pu); /* minimum and maximum frequencies to process */ wmin = ABS(0.5*vrms[0]*k); wmax = ABS(PI/du); iwmin = MAX(1,MIN((nw-1)/2,NINT(wmin/dw))); iwmax = MAX(0,MIN((nw-1)/2,NINT(wmax/dw))); /* constant independent of w */ wwscl = osdmo*pow(k*0.5*offset/tcon,2.0); /* zero dc (should be zero anyway) */ pw[0].r = pw[0].i = 0.0; /* zero frequencies below minimum */ for (iw=1,iwn=nw-iw; iw<iwmin; ++iw,--iwn) pw[iw].r = pw[iw].i = pw[iwn].r = pw[iwn].i = 0.0; /* do dmo between minimum and maximum frequencies */ for (iw=iwmin,iwn=nw-iwmin,w=iwmin*dw; iw<=iwmax; ++iw,--iwn,w+=dw) { scales = 1.0+wwscl/(w*w); scale = sqrt(scales); phase = sdmo*w*tcon*(scale-1.0); amp = fftscl*(1.0-sdmo+sdmo/scale); fr = amp*cos(phase); fi = amp*sin(phase); pwr = pw[iw].r; pwi = pw[iw].i; pw[iw].r = pwr*fr-pwi*fi; pw[iw].i = pwr*fi+pwi*fr; pwr = pw[iwn].r; pwi = pw[iwn].i; pw[iwn].r = pwr*fr+pwi*fi; pw[iwn].i = pwi*fr-pwr*fi; } /* zero frequencies above maximum to Nyquist (if present) */ for (iw=iwmax+1,iwn=nw-iw; iw<=nw/2; ++iw,--iwn) pw[iw].r = pw[iw].i = pw[iwn].r = pw[iwn].i = 0.0; /* Fourier transform p(w) to p(u) */ pfacc(-1,nufft,pu); /* compress p(u) to p(t;k) */ ints8c(nu,du,fu,pu,czero,czero,nt,uoft,ptk[ik]); } /* zero wavenumber between maximum and Nyquist */ for (; ik<nk; ++ik) for (it=0; it<nt; ++it) ptk[ik][it].r = ptk[ik][it].i = 0.0; /* Fourier transform p(t,k) to p(t,x) */ pfa2cr(1,2,nt,nxfft,ptk[0],ptx[0]); /* free workspace */ free1float(tofu); free1float(uoft); free1complex(pu); free1(ptk); }