📄 sustolt.c
字号:
/* Clean up */ efclose(headerfp); if (istmpdir) eremove(headerfile); return(CWP_Exit());} static void makev (int nmig, float *tmig, float *vmig, float vscale, int nt, float dt, float ft, float **v, float *vmin, float *vmax)/*****************************************************************************make uniformly sampled rms velocity function v(t) for migration******************************************************************************Input:nmig number of tmig,vmig pairstmig array[nmig] of timesvmig array[nmig] of rms velocitiesvscale velocity scale factornt number of time samplesdt time sampling intervalft first time sampleOutput:v array[nt] of rms velocitiesvmin minimum velocityvmax maximum velocity******************************************************************************Author: Dave Hale, Colorado School of Mines, 10/22/91*****************************************************************************/{ int it; float t,*vel,velmin,velmax,(*vmigd)[4]; vmigd = (float(*)[4])ealloc1float(nmig*4); cmonot(nmig,tmig,vmig,vmigd); vel = ealloc1float(nt); for (it=0,t=ft; it<nt; ++it,t+=dt) intcub(0,nmig,tmig,vmigd,1,&t,&vel[it]); for (it=0; it<nt; ++it) vel[it] *= vscale; for (it=1,velmin=velmax=vel[0]; it<nt; ++it) { velmin = MIN(velmin,vel[it]); velmax = MAX(velmax,vel[it]); } free1float((float*)vmigd); *v = vel; *vmin = velmin; *vmax = velmax;}static void makeut (float vstolt, float fmax, float *vrms, int nt, float dt, float **ut, int *nu, float *du, float **tu)/*****************************************************************************Compute u(t) and t(u) for Stolt stretch******************************************************************************Input:vstolt Stolt migration velocityfmax maximum frequencyvrms array[nt] of RMS velocitiesnt number of t samplesdt t sampling interval (first t assumed to be zero)Outputut array[nt] of u(t); NULL if constant velocitynu number of u samplesdu u sampling interval (first u assumed to be zero)tu array[nu] of t(u); NULL if constant velocity*****************************************************************************/{ int it; /* check for constant velocity */ for (it=1; it<nt; ++it) if (vrms[it]!=vrms[0]) break; /* if constant velocity */ if (it==nt) { *ut = NULL; *tu = NULL; *nu = nt; *du = dt; /* else if velocity not constant */ } else { int it,nuu; float duu,delu,umax,*u,*t; /* u(t) */ u = alloc1float(nt); makeu(vstolt,vrms,nt,dt,u); /* smallest du and maximum u */ duu = FLT_MAX; for (it=1; it<nt; ++it) { delu = u[it]-u[it-1]; if (delu<duu) duu = delu; } umax = u[nt-1]; /* u sampling */ duu = duu/(2.0*fmax*dt); nuu = 1+NINT(umax/duu); /* t(u) */ t = alloc1float(nuu); yxtoxy(nt,dt,0.0,u,nuu,duu,0.0,0.0,(nt-1)*dt,t); /* set output parameters before returning */ *ut = u; *tu = t; *nu = nuu; *du = duu; }}static void makeu (float vstolt, float *v, int nt, float dt, float *u)/*****************************************************************************Compute t u(t) = sqrt( 2/vstolt^2 * Integral ds*s*(v(s)^2) ) 0via the trapezoidal rule.******************************************************************************Input:vstolt Stolt migration velocityv array[nt] of RMS velocitiesnt number of t samplesdt t sampling intervalOutputu array[nt] of u(t)*****************************************************************************/{ int it; float t,scale,sum; scale = 2.0/(vstolt*vstolt); u[0] = sum = 0.0; for (it=1,t=dt; it<nt; ++it,t+=dt) { sum += 0.5*dt*(t*v[it]*v[it]+(t-dt)*v[it-1]*v[it-1]); u[it] = sqrt(scale*sum); }}static void stolt1k (float k, float v, float s, float fmax, int nt, float dt, complex *p, complex *q)/*****************************************************************************Stolt's migration for one wavenumber k******************************************************************************Input:k wavenumberv velocitys Stolt stretch factor (0<s<2; use s=1 for constant velocity)fmax maximum frequency (in cycles per unit time)nt number of time samplesdt time sampling interval (first time assumed to be zero)p array[nt] containing data to be migratedOutputq array[nt] containing migrated data (may be equivalenced to p)*****************************************************************************/{ int nw,it,nwtau,iwtau,ntau,itau,iwtaul,iwtauh; float vko2s,wmax,dw,fw,dwtau,fwtau,wtau,dtau, wtauh,wtaul,scale,fftscl,a,b,*wwtau; complex czero=cmplx(0.0,0.0),*pp,*qq; /* modify stolt stretch factor to simplify calculations below */ if (s!=1.0) s = 2.0-s; /* (v*k/2)^2 */ vko2s = 0.25*v*v*k*k; /* maximum frequency to migrate in radians per unit time */ wmax = 2.0*PI*MIN(fmax,0.5/dt); /* frequency sampling - must pad to avoid interpolation error; * pad by factor of 2 because time axis is not centered; * pad by factor of 1/0.6 because 8-point sinc is valid * only to about 0.6 Nyquist */ nw = nt*2/0.6; nw = npfao(nw,nw*2); dw = 2.0*PI/(nw*dt); fw = -PI/dt; /* migrated time */ ntau = nt; dtau = dt; /* migrated frequency - no need to pad since no interpolation */ nwtau = npfao(ntau,ntau*2); dwtau = 2.0*PI/(nwtau*dtau); fwtau = -PI/dtau; /* tweak first migrated frequency to avoid wtau==0.0 below */ fwtau += 0.001*dwtau; /* high and low migrated frequencies - don't migrate evanescent */ wtauh = sqrt(MAX(0.0,wmax*wmax-s*vko2s)); iwtauh = MAX(0,MIN(nwtau-1,NINT((wtauh-fwtau)/dwtau))); iwtaul = MAX(0,MIN(nwtau-1,NINT((-wtauh-fwtau)/dwtau))); wtauh = fwtau+iwtauh*dwtau; wtaul = fwtau+iwtaul*dwtau; /* workspace */ pp = alloc1complex(nw); qq = alloc1complex(nwtau); wwtau = alloc1float(nwtau); /* pad with zeros and Fourier transform t to w, with w centered */ for (it=0; it<nt; it+=2) pp[it] = p[it]; for (it=1; it<nt; it+=2) { pp[it].r = -p[it].r; pp[it].i = -p[it].i; } for (it=nt; it<nw; ++it) pp[it].r = pp[it].i = 0.0; pfacc(1,nw,pp); /* zero -Nyquist frequency for symmetry */ pp[0] = czero; /* frequencies at which to interpolate */ if (s==1.0) { for (iwtau=iwtaul,wtau=wtaul; wtau<0.0; ++iwtau,wtau+=dwtau) wwtau[iwtau] = -sqrt(wtau*wtau+vko2s); for (; iwtau<=iwtauh; ++iwtau,wtau+=dwtau) wwtau[iwtau] = sqrt(wtau*wtau+vko2s); } else { a = 1.0/s; b = 1.0-a; for (iwtau=iwtaul,wtau=wtaul; wtau<0.0; ++iwtau,wtau+=dwtau) wwtau[iwtau] = b*wtau-a*sqrt(wtau*wtau+s*vko2s); for (; iwtau<=iwtauh; ++iwtau,wtau+=dwtau) wwtau[iwtau] = b*wtau+a*sqrt(wtau*wtau+s*vko2s); } /* interpolate */ ints8c(nw,dw,fw,pp,czero,czero, iwtauh-iwtaul+1,wwtau+iwtaul,qq+iwtaul); /* fft scaling and obliquity factor */ fftscl = 1.0/nwtau; if (s==1.0) { for (iwtau=iwtaul,wtau=wtaul; iwtau<=iwtauh; ++iwtau,wtau+=dwtau) { scale = fftscl*wtau/wwtau[iwtau]; qq[iwtau].r *= scale; qq[iwtau].i *= scale; } } else { a = 1.0/(s*s); b = 1.0-1.0/s; for (iwtau=iwtaul,wtau=wtaul; iwtau<=iwtauh; ++iwtau,wtau+=dwtau) { scale = fftscl*(b+a*wtau/(wwtau[iwtau]-b*wtau)); qq[iwtau].r *= scale; qq[iwtau].i *= scale; } } /* zero evanescent frequencies */ for (iwtau=0; iwtau<iwtaul; ++iwtau) qq[iwtau] = czero; for (iwtau=iwtauh+1; iwtau<nwtau; ++iwtau) qq[iwtau] = czero; /* Fourier transform wtau to tau, accounting for centered wtau */ pfacc(-1,nwtau,qq); for (itau=0; itau<ntau; itau+=2) q[itau] = qq[itau]; for (itau=1; itau<ntau; itau+=2) { q[itau].r = -qq[itau].r; q[itau].i = -qq[itau].i; } /* free workspace */ free1complex(pp); free1complex(qq); free1float(wwtau);}static void taper (int lxtaper, int lbtaper, int nx, int ix, int nt, float *trace)/*****************************************************************************Taper traces near left and right sides of trace window******************************************************************************Input:lxtaper length (in traces) of side taperlbtaper length (in samples) of bottom tapernx number of traces in windowix index of this trace (0 <= ix <= nx-1)nt number of time samplestrace array[nt] containing traceOutput:trace array[nt] containing trace, tapered if within lxtaper of side*****************************************************************************/{ int it; float xtaper; /* if near left side */ if (ix<lxtaper) { xtaper = 0.54+0.46*cos(PI*(lxtaper-ix)/lxtaper); /* else if near right side */ } else if (ix>=nx-lxtaper) { xtaper = 0.54+0.46*cos(PI*(lxtaper+ix+1-nx)/lxtaper); /* else x tapering is unnecessary */ } else { xtaper = 1.0; } /* if x tapering is necessary, apply it */ if (xtaper!=1.0) for (it=0; it<nt; ++it) trace[it] *= xtaper; /* if requested, apply t tapering */ for (it=MAX(0,nt-lbtaper); it<nt; ++it) trace[it] *= (0.54+0.46*cos(PI*(lbtaper+it+1-nt)/lbtaper));}/* for graceful interrupt termination */static void closefiles(void){ efclose(headerfp); eremove(headerfile); exit(EXIT_FAILURE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -