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) { cwp_String key; /* header key word from segy.h */ cwp_String type;/* ... its type */ int index; /* ... its index */ int nsegy; /* number of bytes in the segy */ Value val; /* value of key in current gather */ Value valnew; /* value of key in trace being treated */ int verbose; /* verbose flag */ int val_i; /* key value as an integer */ int ntr=0; /* count of number of traces in an ensemble */ int numlength; /* length of numerical part of filenames */ FILE *tmpfp=NULL; /* file pointer */ FILE *outfp=NULL; /* file pointer */ cwp_String dir; /* directory name */ cwp_String suffix; /* suffix of output files */ char directory[BUFSIZ]; /* storage for directory name */ char tempfilename[BUFSIZ]; /* ...temporary filename */ char middle[BUFSIZ]; /* ...middle of final filename */ char stem[BUFSIZ]; /* ...stem of final filename */ char format[BUFSIZ]; /* ...format of numeric part */ char outfile[BUFSIZ]; /* ...final filename */ /* Initialize */ initargs(argc, argv); requestdoc(1); /* Get parameters */ MUSTGETPARSTRING("dir", &dir); if (!getparint ("verbose", &verbose)) verbose = 0; if (!getparstring("key", &key)) key = "ep"; if (!getparstring("suffix", &suffix)) suffix = ".hsu"; if (!getparint("numlength", &numlength)) numlength=7; /* Initialize */ /* tempfilename = ealloc1(strlen(tmplt)+3,sizeof(char)); */ type = hdtype(key); index = getindex(key); /* Set up for first trace (must compare new key field each time) */ nsegy = gettr(&intrace); /* Create temporary filename for the first gather */ strcpy(directory, dir); strcpy(tempfilename, temporary_filename(directory)); if((tmpfp = fopen(tempfilename,"w+")) == NULL) err("Cannot open file %s\n",tempfilename); if (verbose) warn(" temporary filename = %s", tempfilename); /* get key header value */ gethval(&intrace, index, &val); ntr=0; do { ++ntr; /* Get header value */ gethval(&intrace, index, &valnew); /* compare past header value to current value */ if (valcmp(type, val, valnew) || !nsegy) { /* Either val and valnew differ, indicating a */ /* new gather or nsegy is zero, indicating the */ /* end of the traces. */ /* capture key field value */ /* and build output filename */ val_i=vtoi(type,val); /* zero out name parts */ strcpy(outfile,""); strcpy(middle,""); strcpy(stem,""); /* build output name parts */ strcat(middle,directory); strcat(middle,"/"); strcat(stem,key); strcat(stem,"="); /* format for numeric part */ (void)sprintf(format, "%%s%%s%%0%dd%%s",numlength); /* build name of output file */ (void)sprintf(outfile, format,middle,stem, val_i, suffix); if (verbose) warn(" outfile = %s", outfile); /* rewind file */ rewind(tmpfp); /* open the new file */ if((outfp = fopen(outfile,"w+")) == NULL) err("Cannot open file %s\n",outfile); /* loop over traces setting ntr field */ /* and write to finalfile */ while(fgettr(tmpfp,&tmptr)) { tmptr.ntr = ntr; fputtr(outfp,&tmptr); } /* Close files */ fclose(tmpfp); fclose(outfp); remove(tempfilename); if (verbose) warn("val= %i", val_i); /* Set up for next gather */ /* create new tempfname first */ strcpy(tempfilename, temporary_filename(directory)); /* open filename */ if((tmpfp = fopen(tempfilename,"w+")) == NULL) err("Cannot open file %s\n",tempfilename); val = valnew; ntr=0; } fputtr(tmpfp,&intrace); } while(gettr(&intrace)); /* Close file */ rewind(tmpfp); val_i=vtoi(type,val); /* Move last gather into new location */ /* capture key field value */ /* and build output filename */ /* null out name parts */ strcpy(outfile,""); strcpy(middle,""); strcpy(stem,""); /* build name parts */ strcat(middle,directory); strcat(middle,"/"); strcat(stem,key); strcat(stem,"="); /* write format of numeric part of output filename */ (void)sprintf(format, "%%s%%s%%0%dd%%s",numlength); /* write output filename */ (void)sprintf(outfile, format,middle,stem, val_i, suffix); /* open the output file */ if((outfp = fopen(outfile,"w+")) == NULL) err("Cannot open file %s\n",outfile); /* loop over traces setting ntr field */ while(fgettr(tmpfp,&tmptr)) { tmptr.ntr = ntr; fputtr(outfp,&tmptr); } /* Close file */ fclose(tmpfp); fclose(outfp); remove(tempfilename); if (verbose) warn(" outfile = %s", outfile); if (verbose) warn("val= %i",val_i); return(CWP_Exit()); }
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 ntr=0; /* number of traces */ int ntrv=0; /* number of traces */ int ns=0; int nsv=0; float dt; float dtv; cwp_String fs; cwp_String fv; FILE *fps; FILE *fpv; FILE *headerfp; float *data; /* data matrix of the migration volume */ float *vel; /* velocity matrix */ float *velfi; /* velocity function interpolated to ns values*/ float *velf; /* velocity function */ float *vdt; float *ddt; float *ap; /* array of apperture values in m */ float apr; /* array of apperture values in m */ int *apt=NULL; /* array of apperture time limits in mig. gath*/ float r; /* maximum radius with a given apperture */ float ir2; /* r/d2 */ float ir3; /* r/d3 */ float d2; /* spatial sampling int. in dir 2. */ float d3; /* spatial sampling int. in dir 3. */ float **mgd=NULL; /* migration gather data */ float *migt; /* migrated data trace */ int **mgdnz=NULL; /* migration gather data non zero samples*/ float dm; /* migration gather spatial sample int. */ int im; /* number of traces in migration gather */ int *mtnz; /* migrated trace data non zero smaples */ char **dummyi; /* index array that the trace contains zeros only */ float fac; /* velocity scale factor */ int sphr; /* spherical divergence flag */ int imt; /* mute time sample of trace */ float tmp; int imoff; int **igtr=NULL; int nigtr; int n2; int n3; int verbose; /* phase shift filter stuff */ float power; /* power of i omega applied to data */ float amp; /* amplitude associated with the power */ float arg; /* argument of power */ float phasefac; /* phase factor */ float phase; /* phase shift = phasefac*PI */ complex exparg; /* cexp(I arg) */ register float *rt; /* real trace */ register complex *ct; /* complex transformed trace */ complex *filt; /* complex power */ float omega; /* circular frequency */ float domega; /* circular frequency spacing (from dt) */ float sign; /* sign in front of i*omega default -1 */ int nfft; /* number of points in nfft */ int nf; /* number of frequencies (incl Nyq) */ float onfft; /* 1 / nfft */ size_t nzeros; /* number of padded zeroes in bytes */ initargs(argc, argv); requestdoc(1); MUSTGETPARSTRING("fs",&fs); MUSTGETPARSTRING("fv",&fv); MUSTGETPARINT("n2",&n2); MUSTGETPARINT("n3",&n3); MUSTGETPARFLOAT("d2",&d2); MUSTGETPARFLOAT("d3",&d3); if (!getparfloat("dm", &dm)) dm=(d2+d3)/2.0; /* open datafile */ fps = efopen(fs,"r"); fpv = efopen(fv,"r"); /* Open tmpfile for headers */ headerfp = etmpfile(); /* get information from the first data trace */ ntr = fgettra(fps,&tr,0); if(n2*n3!=ntr) err(" Number of traces in file %d not equal to n2*n3 %d \n", ntr,n2*n3); ns=tr.ns; if (!getparfloat("dt", &dt)) dt = ((float) tr.dt)/1000000.0; if (!dt) { dt = .002; warn("dt not set, assumed to be .002"); } /* get information from the first velocity trace */ ntrv = fgettra(fpv,&trv,0); if(ntrv!=ntr) err(" Number of traces in velocity file %d differ from %d \n", ntrv,ntr); nsv=trv.ns; if (!getparfloat("dtv", &dtv)) dtv = ((float) trv.dt)/1000000.0; if (!dtv) { dtv = .002; warn("dtv not set, assumed to be .002 for velocity"); } if (!getparfloat("fac", &fac)) fac=2.0; if (!getparint("verbose", &verbose)) verbose=0; if (!getparint("sphr", &sphr)) sphr=0; if (!getparfloat("apr", &apr)) apr=75; apr*=3.141592653/180; /* allocate arrays */ data = bmalloc(sizeof(float),ns,ntr); vel = bmalloc(sizeof(float),nsv,ntr); velf = ealloc1float(nsv); velfi = ealloc1float(ns); migt = ealloc1float(ns); vdt = ealloc1float(nsv); ddt = ealloc1float(ns); ap = ealloc1float(ns); mtnz = ealloc1int(ns); dummyi = (char **) ealloc2(n2,n3,sizeof(char)); /* Times to do interpolation of velocity from sparse sampling */ /* to fine sampling of the data */ { register int it; for(it=0;it<nsv;it++) vdt[it]=it*dtv; for(it=0;it<ns;it++) ddt[it]=it*dt; } /* Read traces into data */ /* Store headers in tmpfile */ ntr=0; erewind(fps); erewind(fpv); { register int i2,i3; for(i3=0;i3<n3;i3++) for(i2=0;i2<n2;i2++) { fgettr(fps,&tr); fgettr(fpv,&trv); if(tr.trid > 2) dummyi[i3][i2]=1; else dummyi[i3][i2]=0; efwrite(&tr, 1, HDRBYTES, headerfp); bmwrite(data,1,0,i3*n2+i2,ns,tr.data); bmwrite(vel,1,0,i3*n2+i2,nsv,trv.data); } erewind(headerfp); /* set up the phase filter */ power = 1.0;sign = 1.0;phasefac = 0.5; phase = phasefac * PI; /* Set up for fft */ nfft = npfaro(ns, LOOKFAC * ns); if (nfft >= SU_NFLTS || nfft >= PFA_MAX) err("Padded nt=%d -- too big", nfft); nf = nfft/2 + 1; onfft = 1.0 / nfft; nzeros = (nfft - ns) * FSIZE; domega = TWOPI * onfft / dt; /* Allocate fft arrays */ rt = ealloc1float(nfft); ct = ealloc1complex(nf); filt = ealloc1complex(nf); /* Set up args for complex power evaluation */ arg = sign * PIBY2 * power + phase; exparg = cexp(crmul(I, arg)); { register int i; for (i = 0 ; i < nf; ++i) { omega = i * domega; /* kludge to handle omega=0 case for power < 0 */ if (power < 0 && i == 0) omega = FLT_MAX; /* calculate filter */ amp = pow(omega, power) * onfft; filt[i] = crmul(exparg, amp); } } /* set up constants for migration */ if(verbose) fprintf(stderr," Setting up constants....\n"); r=0; for(i3=0;i3<n3;i3++) for(i2=0;i2<n2;i2++) { if(dummyi[i3][i2] < 1) { /* get the velocity function */ bmread(vel,1,0,i3*n2+i2,nsv,velf); /* linear interpolation from nsv to ns values */ intlin(nsv,vdt,velf,velf[0],velf[nsv-1],ns,ddt,velfi); /* Apply scale factor to velocity */ { register int it; for(it=0;it<ns;it++) velfi[it] *=fac; } /* compute maximum radius from apperture and velocity */ { register int it; for(it=0;it<ns;it++) ap[it] = ddt[it]*velfi[it]*tan(apr)/2.0; } tmp = ap[isamax(ns,ap,1)]; if(tmp>r) r=tmp; } } r=MIN(r,sqrt(SQR((n2-1)*d2)+SQR((n3-1)*d3))); ir2 = (int)(2*r/d2)+1; ir3 = (int)(2*r/d3)+1; im = (int)(r/dm)+1; /* allocate migration gather */ mgd = ealloc2float(ns,im); mgdnz = ealloc2int(ns,im); apt = ealloc1int(im); /* set up the stencil for selecting traces */ igtr = ealloc2int(ir2*ir3,2); stncl(r, d2, d3,igtr,&nigtr); if(verbose) { fprintf(stderr," Maximum radius %f\n",r); fprintf(stderr," Maximum offset %f\n", sqrt(SQR((n2-1)*d2)+SQR((n3-1)*d3))); } /* main processing loop */ for(i3=0;i3<n3;i3++) for(i2=0;i2<n2;i2++) { memset( (void *) tr.data, (int) '\0',ns*FSIZE); if(dummyi[i3][i2] < 1) { memset( (void *) mgd[0], (int) '\0',ns*im*FSIZE); memset( (void *) mgdnz[0], (int) '\0',ns*im*ISIZE); /* get the velocity function */ bmread(vel,1,0,i3*n2+i2,nsv,velf); /* linear interpolation from nsv to ns values */ intlin(nsv,vdt,velf,velf[0],velf[nsv-1],ns,ddt,velfi); /* Apply scale factor to velocity */ { register int it; for(it=0;it<ns;it++) velfi[it] *=fac; } /* create the migration gather */ { register int itr,ist2,ist3; for(itr=0;itr<nigtr;itr++) { ist2=i2+igtr[0][itr]; ist3=i3+igtr[1][itr]; if(ist2 >= 0 && ist2 <n2) if(ist3 >= 0 && ist3 <n3) { if(dummyi[ist3][ist2] <1) { imoff = (int) ( sqrt(SQR(igtr[0][itr]*d2) +SQR(igtr[1][itr]*d3))/dm+0.5); bmread(data,1,0,ist3*n2+ist2,ns,tr.data); imoff=MIN(imoff,im-1); { register int it; /* get the mute time for this offset, apperture and velocity */ xindex(ns,ap,imoff*dm,&imt); for(it=imt;it<ns;it++) if(tr.data[it]!=0) { mgd[imoff][it]+=tr.data[it]; mgdnz[imoff][it]+=1; } } } } } } /* normalize the gather */ { register int ix,it; for(ix=0;ix<im;ix++) for(it=0;it<ns;it++) if(mgdnz[ix][it] > 1) mgd[ix][it] /=(float) mgdnz[ix][it]; } memset( (void *) tr.data, (int) '\0',ns*FSIZE); memset( (void *) mtnz, (int) '\0',ns*ISIZE); /* do a knmo */ { register int ix,it; for(ix=0;ix<im;ix++) { /* get the mute time for this offset, apperture and velocity */ xindex(ns,ap,ix*dm,&imt); knmo(mgd[ix],migt,ns,velfi,0,ix*dm,dt,imt,sphr); /* stack the gather */ for(it=0;it<ns;it++) { if(migt[it]!=0.0) { tr.data[it] += migt[it]; mtnz[it]++; } /* tr.data[it] += mgd[ix][it]; */ } } } { register int it; for(it=0;it<ns;it++) if(mtnz[it]>1) tr.data[it] /=(float)mtnz[it]; } /*Do the phase filtering before the trace is released*/ /* Load trace into rt (zero-padded) */ memcpy( (void *) rt, (const void *) tr.data, ns*FSIZE); memset((void *) (rt + ns), (int) '\0', nzeros); pfarc(1, nfft, rt, ct); { register int i; for (i = 0; i < nf; ++i) ct[i] = cmul(ct[i], filt[i]); } pfacr(-1, nfft, ct, rt); memcpy( (void *) tr.data, (const void *) rt, ns*FSIZE); } /* end of dummy if */ /* spit out the gather */ efread(&tr, 1, HDRBYTES, headerfp); puttr(&tr); if(verbose) fprintf(stderr," %d %d\n",i2,i3); } /* end of i2 loop */ } /* end of i3 loop */ /* This should be the last thing */ efclose(headerfp); /* Free memory */ free2int(igtr); free2float(mgd); free2int(mgdnz); free1int(apt); bmfree(data); bmfree(vel); free1float(velfi); free1float(velf); free1float(ddt); free1float(vdt); free1float(ap); free1int(mtnz); free1float(migt); free1float(rt); free1complex(ct); free1complex(filt); free2((void **) dummyi); return EXIT_SUCCESS; }