void homogeneousg(float *HomG, complex *cshot, complex *Refl, int nx, int nt, int nxs, int nts, float dt, float *xsyn, int Nsyn, float *xrcv, float *xsrc, float fxs2, float fxs, float dxs, float dxsrc, float dx, int ixa, int ixb, int ntfft, int nw, int nw_low, int nw_high, int mode, int reci, int nshots, int *ixpossyn, int npossyn, float *pmin, float *f1min, float *f1plus, float *f2p, float *G_d, int *muteW, int smooth, int shift, int above, int pad, int nt0, int *synpos, int verbose) { int i, j, l, ret; int iter, niter, ix, nfreq; float *iRN, *rtrace; complex *Fop, *ctrace, *chom; double t0, t2, tfft; tfft = 0.0; ret = 0; t0 = wallclock_time(); nfreq = ntfft/2+1; #pragma omp parallel default(shared) \ private(i,j,ctrace,chom,rtrace) { ctrace = (complex *)calloc(nfreq,sizeof(complex)); chom = (complex *)calloc(nfreq,sizeof(complex)); rtrace = (float *)calloc(ntfft,sizeof(float)); #pragma omp for for (l = 0; l < Nsyn; l++) { if (verbose > 2) vmess("Creating Homogeneous G at location %d out of %d",l+1,Nsyn); /* Construct the image */ for (i = 0; i < nxs; i++) { rc1fft(&f2p[l*nxs*ntfft+i*ntfft],ctrace,nt,-1); for (j = 0; j < nfreq; j++) { chom[j].r += 2*(ctrace[j].r*cshot[i*nfreq+j].r - ctrace[j].i*cshot[i*nfreq+j].i); } } cr1fft(&chom[0],rtrace,nt,1); for (i = 0; i < ntfft; i++) { HomG[i*Nsyn+synpos[l]] = rtrace[i]; } /*for (i = 0; i < ntfft/2; i++) { HomG[i*Nsyn+synpos[l]] = rtrace[ntfft/2+i]; } for (i = ntfft/2; i < ntfft; i++) { HomG[i*Nsyn+synpos[l]] = rtrace[i-ntfft/2]; }*/ } free(rtrace);free(chom);free(ctrace); } //free(Gmin); t2 = wallclock_time(); if (verbose) { vmess("Total Homogeneous G time = %.3f", t2-t0); } return; }
int main(int argc, char **argv) { modPar mod; recPar rec; srcPar src; shotPar shot; rayPar ray; float *velocity, *slowness, *smooth, *trueslow, **inter; double t0, t1, t2, tinit, tray, tio; size_t size; int nw, n1, ix, iz, ir, ixshot, izshot; int nt, ntfft, nfreq, ig; int irec, sbox, ipos, nrx, nrz, nr; fcoord coordsx, coordgx, Time; icoord grid, isrc; float Jr, *ampl, *time, *ttime, *ttime_p, cp_average, *wavelet, dw, dt; float dxrcv, dzrcv, rdelay, tr, dt_tmp; segy hdr; char filetime[1024], fileamp[1024], *method, *file_rcvtime, *file_src; size_t nwrite, nread; int verbose; complex *cmute, *cwav; FILE *fpt, *fpa, *fpwav, *fprcv; t0= wallclock_time(); initargs(argc,argv); requestdoc(0); if(!getparint("verbose",&verbose)) verbose=0; if(!getparint("sbox", &sbox)) sbox = 1; if(!getparstring("method", &method)) method="jesper"; if (!getparfloat("rec_delay",&rdelay)) rdelay=0.0; getParameters(&mod, &rec, &src, &shot, &ray, verbose); /* read file_src if file_rcvtime is defined */ if (!getparstring("file_rcvtime",&file_rcvtime)) file_rcvtime=NULL; if (file_rcvtime != NULL) { if (!getparstring("file_src",&file_src)) file_src=NULL; if (!getparfloat("dt",&dt)) dt=0.004; if (file_src != NULL ) { fpwav = fopen( file_src, "r" ); assert( fpwav != NULL); nread = fread( &hdr, 1, TRCBYTES, fpwav ); assert(nread == TRCBYTES); ntfft = optncr(MAX(hdr.ns, rec.nt)); wavelet = (float *)calloc(ntfft,sizeof(float)); /* read first trace */ nread = fread(wavelet, sizeof(float), hdr.ns, fpwav); assert (nread == hdr.ns); fclose(fpwav); } else { ntfft = optncr(rec.nt); wavelet = (float *)calloc(ntfft,sizeof(float)); wavelet[0] = 1.0; } nfreq = ntfft/2+1; cwav = (complex *)calloc(nfreq,sizeof(complex)); cmute = (complex *)calloc(nfreq,sizeof(complex)); rc1fft(wavelet,cwav,ntfft,-1); dw = 2*M_PI/(ntfft*dt); } /* allocate arrays for model parameters: the different schemes use different arrays */ n1 = mod.nz; if(!strcmp(method,"fd")) nw = 0; else nw = ray.smoothwindow; velocity = (float *)calloc(mod.nx*mod.nz,sizeof(float)); slowness = (float *)calloc((mod.nx+2*nw)*(mod.nz+2*nw),sizeof(float)); trueslow = (float *)calloc(mod.nx*mod.nz,sizeof(float)); if(!strcmp(method,"fd")) { ttime = (float *)calloc(mod.nx*mod.nz,sizeof(float)); } /* read velocity and density files */ readModel(mod, velocity, slowness, nw); /* allocate arrays for wavefield and receiver arrays */ size = shot.n*rec.n; time = (float *)calloc(size,sizeof(float)); ampl = (float *)calloc(size,sizeof(float)); /* Sinking source and receiver arrays: If P-velocity==0 the source and receiver postions are placed deeper until the P-velocity changes. Setting the option rec.sinkvel only sinks the receiver position (not the source) and uses the velocity of the first receiver to sink through to the next layer. */ /* sink receivers to value different than sinkvel */ for (ir=0; ir<rec.n; ir++) { iz = rec.z[ir]; ix = rec.x[ir]; while(velocity[(ix)*n1+iz] == rec.sinkvel) iz++; rec.z[ir]=iz+rec.sinkdepth; rec.zr[ir]=rec.zr[ir]+(rec.z[ir]-iz)*mod.dz; // rec.zr[ir]=rec.z[ir]*mod.dz; if (verbose>3) vmess("receiver position %d at grid[ix=%d, iz=%d] = (x=%f z=%f)", ir, ix, rec.z[ir], rec.xr[ir]+mod.x0, rec.zr[ir]+mod.z0); } vmess(" - method for ray-tracing = %s", method); /* */ /* sink sources to value different than zero */ for (izshot=0; izshot<shot.nz; izshot++) { for (ixshot=0; ixshot<shot.nx; ixshot++) { iz = shot.z[izshot]; ix = shot.x[ixshot]; while(velocity[(ix)*n1+iz] == 0.0) iz++; shot.z[izshot]=iz+src.sinkdepth; } } if (verbose>3) writeSrcRecPos(&mod, &rec, &src, &shot); /* smooth slowness grid */ grid.x = mod.nx; grid.z = mod.nz; grid.y = 1; if ( nw != 0 ) { /* smooth slowness */ smooth = (float *)calloc(grid.x*grid.z,sizeof(float)); applyMovingAverageFilter(slowness, grid, nw, 2, smooth); memcpy(slowness,smooth,grid.x*grid.z*sizeof(float)); free(smooth); } /* prepare output file and headers */ strcpy(filetime, rec.file_rcv); name_ext(filetime, "_time"); fpt = fopen(filetime, "w"); assert(fpt != NULL); if (ray.geomspread) { strcpy(fileamp, rec.file_rcv); name_ext(fileamp, "_amp"); fpa = fopen(fileamp, "w"); assert(fpa != NULL); } if (file_rcvtime != NULL) { fprcv = fopen(file_rcvtime, "w"); assert(fprcv != NULL); } memset(&hdr,0,sizeof(hdr)); hdr.scalco = -1000; hdr.scalel = -1000; hdr.trid = 0; t1=wallclock_time(); tinit = t1-t0; tray=0.0; tio=0.0; /* Outer loop over number of shots */ for (izshot=0; izshot<shot.nz; izshot++) { for (ixshot=0; ixshot<shot.nx; ixshot++) { t2=wallclock_time(); if (verbose) { vmess("Modeling source %d at gridpoints ix=%d iz=%d", (izshot*shot.n)+ixshot, shot.x[ixshot], shot.z[izshot]); vmess(" which are actual positions x=%.2f z=%.2f", mod.x0+mod.dx*shot.x[ixshot], mod.z0+mod.dz*shot.z[izshot]); vmess("Receivers at gridpoint x-range ix=%d - %d", rec.x[0], rec.x[rec.n-1]); vmess(" which are actual positions x=%.2f - %.2f", mod.x0+rec.xr[0], mod.x0+rec.xr[rec.n-1]); vmess("Receivers at gridpoint z-range iz=%d - %d", rec.z[0], rec.z[rec.n-1]); vmess(" which are actual positions z=%.2f - %.2f", mod.z0+rec.zr[0], mod.z0+rec.zr[rec.n-1]); } coordsx.x = shot.x[ixshot]*mod.dx; coordsx.z = shot.z[izshot]*mod.dz; coordsx.y = 0; t1=wallclock_time(); tio += t1-t2; if (!strcmp(method,"jesper")) { #pragma omp parallel for default(shared) \ private (coordgx,irec,Time,Jr) for (irec=0; irec<rec.n; irec++) { coordgx.x=rec.xr[irec]; coordgx.z=rec.zr[irec]; coordgx.y = 0; getWaveParameter(slowness, grid, mod.dx, coordsx, coordgx, ray, &Time, &Jr); time[((izshot*shot.nx)+ixshot)*rec.n + irec] = Time.x + Time.y + 0.5*Time.z; ampl[((izshot*shot.nx)+ixshot)*rec.n + irec] = Jr; if (verbose>4) vmess("JS: shot=%f,%f receiver at %f,%f T0=%f T1=%f T2=%f Jr=%f",coordsx.x, coordsx.z, coordgx.x, coordgx.z, Time.x, Time.y, Time.z, Jr); } } else if(!strcmp(method,"fd")) { int mzrcv; isrc.x = shot.x[ixshot]; isrc.y = 0; isrc.z = shot.z[izshot]; mzrcv = 0; for (irec = 0; irec < rec.n; irec++) mzrcv = MAX(rec.z[irec], mzrcv); vidale(ttime,slowness,&isrc,grid,mod.dx,sbox, mzrcv); for (irec=0; irec<rec.n; irec++) { coordgx.x=mod.x0+rec.xr[irec]; coordgx.z=mod.z0+rec.zr[irec]; coordgx.y = 0; ipos = ((izshot*shot.nx)+ixshot)*rec.n + irec; time[ipos] = ttime[rec.z[irec]*mod.nx+rec.x[irec]]; /* compute average velocity between source and receiver */ nrx = (rec.x[irec]-isrc.x); nrz = (rec.z[irec]-isrc.z); nr = abs(nrx) + abs(nrz); cp_average = 0.0; for (ir=0; ir<nr; ir++) { ix = isrc.x + floor((ir*nrx)/nr); iz = isrc.z + floor((ir*nrz)/nr); //fprintf(stderr,"ir=%d ix=%d iz=%d velocity=%f\n", ir, ix, iz, velocity[ix*mod.nz+iz]); cp_average += velocity[ix*mod.nz+iz]; } cp_average = cp_average/((float)nr); ampl[ipos] = sqrt(time[ipos]*cp_average); if (verbose>4) vmess("FD: shot=%f,%f receiver at %f(%d),%f(%d) T=%e V=%f Ampl=%f",coordsx.x, coordsx.z, coordgx.x, rec.x[irec], coordgx.z, rec.z[irec], time[ipos], cp_average, ampl[ipos]); } } t2=wallclock_time(); tray += t2-t1; hdr.sx = 1000*(mod.x0+mod.dx*shot.x[ixshot]); hdr.sdepth = 1000*(mod.z0+mod.dz*shot.z[izshot]); hdr.selev = (int)(-1000.0*(mod.z0+mod.dz*shot.z[izshot])); hdr.fldr = ((izshot*shot.nx)+ixshot)+1; hdr.tracl = ((izshot*shot.nx)+ixshot)+1; hdr.tracf = ((izshot*shot.nx)+ixshot)+1; hdr.ntr = shot.n; hdr.dt = (unsigned short)1; hdr.trwf = shot.n; hdr.ns = rec.n; //hdr.d1 = (rec.x[1]-rec.x[0])*mod.dx; // discrete hdr.d1 = (rec.xr[1]-rec.xr[0]); hdr.f1 = mod.x0+rec.x[0]*mod.dx; hdr.d2 = (shot.x[MIN(shot.n-1,1)]-shot.x[0])*mod.dx; hdr.f2 = mod.x0+shot.x[0]*mod.dx; dt_tmp = (fabs(hdr.d1*((float)hdr.scalco))); hdr.dt = (unsigned short)dt_tmp; nwrite = fwrite( &hdr, 1, TRCBYTES, fpt); assert(nwrite == TRCBYTES); nwrite = fwrite( &time[((izshot*shot.nx)+ixshot)*rec.n], sizeof(float), rec.n, fpt); assert(nwrite == rec.n); fflush(fpt); if (ray.geomspread) { nwrite = fwrite( &hdr, 1, TRCBYTES, fpa); assert(nwrite == TRCBYTES); nwrite = fwrite( &l[((izshot*shot.nx)+ixshot)*rec.n], sizeof(float), rec.n, fpa); assert(nwrite == rec.n); fflush(fpa); } if (file_rcvtime != NULL) { hdr.ns = rec.nt; hdr.trwf = rec.n; hdr.ntr = ((izshot*shot.nx)+ixshot+1)*rec.n; hdr.dt = dt*1000000; hdr.d1 = dt; hdr.f1 = 0.0; hdr.d2 = (rec.xr[1]-rec.xr[0]); hdr.f2 = mod.x0+rec.x[0]*mod.dx; for (irec=0; irec<rec.n; irec++) { ipos = ((izshot*shot.nx)+ixshot)*rec.n + irec; hdr.tracf = irec+1; hdr.tracl = ((izshot*shot.nx)+ixshot*shot.nz)+irec+1; hdr.gx = 1000*(mod.x0+rec.xr[irec]); hdr.offset = (rec.xr[irec]-shot.x[ixshot]*mod.dx); hdr.gelev = (int)(-1000*(mod.z0+rec.zr[irec])); tr = time[ipos]+rdelay; for (ig=0; ig<nfreq; ig++) { cmute[ig].r = (cwav[ig].r*cos(ig*dw*tr-M_PI/4.0)-cwav[ig].i*sin(ig*dw*tr-M_PI/4.0))/(ntfft*ampl[ipos]); cmute[ig].i = (cwav[ig].i*cos(ig*dw*tr-M_PI/4.0)+cwav[ig].r*sin(ig*dw*tr-M_PI/4.0))/(ntfft*ampl[ipos]); } cr1fft(cmute,wavelet,ntfft,-1); nwrite = fwrite( &hdr, 1, TRCBYTES, fprcv); nwrite = fwrite( wavelet, sizeof(float), rec.nt, fprcv ); } } t1=wallclock_time(); tio += t1-t2; } /* end of ixshot loop */ } /* end of loop over number of shots */ fclose(fpt); if (file_rcvtime != NULL) fclose(fprcv); if (ray.geomspread) fclose(fpa); t1= wallclock_time(); if (verbose) { vmess("*******************************************"); vmess("************* runtime info ****************"); vmess("*******************************************"); vmess("Total compute time ray-tracing = %.2f s.", t1-t0); vmess(" - intializing arrays and model = %.3f", tinit); vmess(" - ray tracing = %.3f", tray); vmess(" - writing data to file = %.3f", tio); } /* free arrays */ initargs(argc,argv); /* this will free the arg arrays declared */ free(velocity); free(slowness); return 0; }
void synthesis(complex *Refl, complex *Fop, float *Top, float *iRN, int nx, int nt, int nxs, int nts, float dt, float *xsyn, int Nsyn, float *xrcv, float *xsrc, float fxs2, float fxs, float dxs, float dxsrc, float dx, int ixa, int ixb, int ntfft, int nw, int nw_low, int nw_high, int mode, int reci, int nshots, int *ixpossyn, int npossyn, double *tfft, int *first, int verbose) { int nfreq, size, iox, inx; float scl; int i, j, l, m, iw, ix, k; float *rtrace, idxs; complex *sum, *ctrace; int npe; static int *ixrcv; static double t0, t1, t; size = nxs*nts; nfreq = ntfft/2+1; /* scale factor 1/N for backward FFT, * scale dt for correlation/convolution along time, * scale dx (or dxsrc) for integration over receiver (or shot) coordinates */ scl = 1.0*dt/((float)ntfft); #ifdef _OPENMP npe = omp_get_max_threads(); /* parallelisation is over number of virtual source positions (Nsyn) */ if (npe > Nsyn) { vmess("Number of OpenMP threads set to %d (was %d)", Nsyn, npe); omp_set_num_threads(Nsyn); } #endif t0 = wallclock_time(); /* reset output data to zero */ memset(&iRN[0], 0, Nsyn*nxs*nts*sizeof(float)); idxs = 1.0/dxs; if (ixrcv == NULL) { ixrcv = (int *)malloc(nshots*nx*sizeof(int)); } for (k=0; k<nshots; k++) { for (i = 0; i < nx; i++) { ixrcv[k*nx+i] = NINT((xrcv[k*nx+i]-fxs)*idxs); } } ctrace = (complex *)calloc(ntfft,sizeof(complex)); if (!*first) { /* transform muted Ni (Top) to frequency domain, input for next iteration */ for (l = 0; l < Nsyn; l++) { /* set Fop to zero, so new operator can be defined within ixpossyn points */ //memset(&Fop[l*nxs*nw].r, 0, nxs*nw*2*sizeof(float)); bzero(&Fop[l*nxs*nw].r, nxs*nw*2*sizeof(float)); for (i = 0; i < npossyn; i++) { rc1fft(&Top[l*size+i*nts],ctrace,ntfft,-1); ix = ixpossyn[i]; for (iw=0; iw<nw; iw++) { Fop[l*nxs*nw+iw*nxs+ix].r = ctrace[nw_low+iw].r; Fop[l*nxs*nw+iw*nxs+ix].i = mode*ctrace[nw_low+iw].i; } } } } else { /* only for first call to synthesis */ /* transform G_d to frequency domain, over all nxs traces */ *first=0; for (l = 0; l < Nsyn; l++) { /* set Fop to zero, so new operator can be defined within all ix points */ //memset(&Fop[l*nxs*nw].r, 0, nxs*nw*2*sizeof(float)); bzero(&Fop[l*nxs*nw].r, nxs*nw*2*sizeof(float)); for (i = 0; i < nxs; i++) { rc1fft(&Top[l*size+i*nts],ctrace,ntfft,-1); for (iw=0; iw<nw; iw++) { Fop[l*nxs*nw+iw*nxs+i].r = ctrace[nw_low+iw].r; Fop[l*nxs*nw+iw*nxs+i].i = mode*ctrace[nw_low+iw].i; } } } } free(ctrace); t1 = wallclock_time(); *tfft += t1 - t0; for (k=0; k<nshots; k++) { /* if (verbose>=3) { vmess("source position: %.2f ixpossyn=%d", xsrc[k], ixpossyn[k]); vmess("receiver positions: %.2f <--> %.2f", xrcv[k*nx+0], xrcv[k*nx+nx-1]); } */ if ((NINT(xsrc[k]-fxs2) > 0) || (NINT(xrcv[k*nx+nx-1]-fxs2) > 0) || (NINT(xrcv[k*nx+nx-1]-fxs) < 0) || (NINT(xsrc[k]-fxs) < 0) || (NINT(xrcv[k*nx+0]-fxs) < 0) || (NINT(xrcv[k*nx+0]-fxs2) > 0) ) { vwarn("source/receiver positions are outside synthesis model"); vwarn("integration calculation is stopped at gather %d", k); vmess("xsrc = %.2f xrcv_1 = %.2f xrvc_N = %.2f", xsrc[k], xrcv[k*nx+0], xrcv[k*nx+nx-1]); break; } iox = 0; inx = nx; /*================ SYNTHESIS ================*/ #pragma omp parallel default(none) \ shared(iRN, dx, npe, nw, verbose) \ shared(Refl, Nsyn, reci, xrcv, xsrc, xsyn, fxs, nxs, dxs) \ shared(nx, ixa, ixb, dxsrc, iox, inx, k, nfreq, nw_low, nw_high) \ shared(Fop, size, nts, ntfft, scl, ixrcv, stderr) \ private(l, ix, j, m, i, sum, rtrace) { /* start of parallel region */ sum = (complex *)malloc(nfreq*sizeof(complex)); rtrace = (float *)calloc(ntfft,sizeof(float)); #pragma omp for schedule(guided,1) for (l = 0; l < Nsyn; l++) { ix = k; /* multiply R with Fop and sum over nx */ memset(&sum[0].r,0,nfreq*2*sizeof(float)); //for (j = 0; j < nfreq; j++) sum[j].r = sum[j].i = 0.0; for (j = nw_low, m = 0; j <= nw_high; j++, m++) { for (i = iox; i < inx; i++) { sum[j].r += Refl[k*nw*nx+m*nx+i].r*Fop[l*nw*nxs+m*nxs+ixrcv[k*nx+i]].r - Refl[k*nw*nx+m*nx+i].i*Fop[l*nw*nxs+m*nxs+ixrcv[k*nx+i]].i; sum[j].i += Refl[k*nw*nx+m*nx+i].i*Fop[l*nw*nxs+m*nxs+ixrcv[k*nx+i]].r + Refl[k*nw*nx+m*nx+i].r*Fop[l*nw*nxs+m*nxs+ixrcv[k*nx+i]].i; } } /* transfrom result back to time domain */ cr1fft(sum, rtrace, ntfft, 1); /* dx = receiver distance */ for (j = 0; j < nts; j++) iRN[l*size+ix*nts+j] += rtrace[j]*scl*dx; } /* end of parallel Nsyn loop */ free(sum); free(rtrace); #pragma omp single { #ifdef _OPENMP npe = omp_get_num_threads(); #endif } } /* end of parallel region */ if (verbose>3) vmess("*** Shot gather %d processed ***", k); } /* end of nshots (k) loop */ t = wallclock_time() - t0; if (verbose) { vmess("OMP: parallel region = %f seconds (%d threads)", t, npe); } return; }
int main (int argc, char **argv) { FILE *fp_out, *fp_f1plus, *fp_f1min; FILE *fp_gmin, *fp_gplus, *fp_f2, *fp_pmin; int i, j, l, ret, nshots, Nsyn, nt, nx, nts, nxs, ngath; int size, n1, n2, ntap, tap, di, ntraces, nb, ib; int nw, nw_low, nw_high, nfreq, *xnx, *xnxsyn, *synpos; int reci, mode, ixa, ixb, n2out, verbose, ntfft; int iter, niter, niterh, tracf, *muteW, pad, nt0, ampest, *hmuteW, *hxnxsyn; int hw, smooth, above, shift, *ixpossyn, npossyn, ix, first=1; float fmin, fmax, *tapersh, *tapersy, fxf, dxf, fxs2, *xsrc, *xrcv, *zsyn, *zsrc, *xrcvsyn; float *hzsyn, *hxsyn, *hxrcvsyn, *hG_d, xloc, zloc, *HomG; double t0, t1, t2, t3, tsyn, tread, tfft, tcopy, energyNi, *J; float d1, d2, f1, f2, fxs, ft, fx, *xsyn, dxsrc, Q, f0, *Costdet; float *green, *f2p, *pmin, *G_d, dt, dx, dxs, scl, mem, *Image, *Image2; float *f1plus, *f1min, *iRN, *Ni, *trace, *Gmin, *Gplus, *Gm0; float xmin, xmax, weight, tsq, *Gd, *amp, bstart, bend, db, *bdet, bp, b, bmin; complex *Refl, *Fop, *cshot; char *file_tinv, *file_shot, *file_green, *file_iter, *file_wav, *file_ray, *file_amp, *file_img, *file_cp, *file_rays, *file_amps; char *file_f1plus, *file_f1min, *file_gmin, *file_gplus, *file_f2, *file_pmin, *wavtype, *wavtype2, *file_homg, *file_tinvs; segy *hdrs_im, *hdrs_homg; WavePar WP,WPs; modPar mod; recPar rec; srcPar src; shotPar shot; rayPar ray; initargs(argc, argv); requestdoc(1); tsyn = tread = tfft = tcopy = 0.0; t0 = wallclock_time(); if (!getparstring("file_img", &file_img)) file_img = "img.su"; if (!getparstring("file_homg", &file_homg)) file_homg = NULL; if (!getparstring("file_shot", &file_shot)) file_shot = NULL; if (!getparstring("file_tinv", &file_tinv)) file_tinv = NULL; if (!getparstring("file_tinvs", &file_tinvs)) file_tinvs = NULL; if (!getparstring("file_f1plus", &file_f1plus)) file_f1plus = NULL; if (!getparstring("file_f1min", &file_f1min)) file_f1min = NULL; if (!getparstring("file_gplus", &file_gplus)) file_gplus = NULL; if (!getparstring("file_gmin", &file_gmin)) file_gmin = NULL; if (!getparstring("file_pplus", &file_f2)) file_f2 = NULL; if (!getparstring("file_f2", &file_f2)) file_f2 = NULL; if (!getparstring("file_pmin", &file_pmin)) file_pmin = NULL; if (!getparstring("file_iter", &file_iter)) file_iter = NULL; if (!getparstring("file_wav", &file_wav)) file_wav=NULL; if (!getparstring("file_ray", &file_ray)) file_ray=NULL; if (!getparstring("file_amp", &file_amp)) file_amp=NULL; if (!getparstring("file_rays", &file_rays)) file_rays=NULL; if (!getparstring("file_amps", &file_amps)) file_amps=NULL; if (!getparstring("file_cp", &file_cp)) file_cp = NULL; if (!getparint("verbose", &verbose)) verbose = 0; if (file_tinv == NULL && file_shot == NULL) verr("file_tinv and file_shot cannot be both input pipe"); if (!getparstring("file_green", &file_green)) { if (verbose) vwarn("parameter file_green not found, assume pipe"); file_green = NULL; } if (!getparfloat("fmin", &fmin)) fmin = 0.0; if (!getparfloat("fmax", &fmax)) fmax = 70.0; if (!getparint("ixa", &ixa)) ixa = 0; if (!getparint("ixb", &ixb)) ixb = ixa; // if (!getparint("reci", &reci)) reci = 0; reci=0; // source-receiver reciprocity is not yet fully build into the code if (!getparfloat("weight", &weight)) weight = 1.0; if (!getparfloat("tsq", &tsq)) tsq = 0.0; if (!getparfloat("Q", &Q)) Q = 0.0; if (!getparfloat("f0", &f0)) f0 = 0.0; if (!getparint("tap", &tap)) tap = 0; if (!getparint("ntap", &ntap)) ntap = 0; if (!getparint("pad", &pad)) pad = 0; if(!getparint("hw", &hw)) hw = 15; if(!getparint("smooth", &smooth)) smooth = 5; if(!getparint("above", &above)) above = 0; if(!getparint("shift", &shift)) shift=12; if(!getparint("ampest", &est)) ampest=0; if(!getparint("nb", &nb)) nb=0; if (!getparfloat("bstart", &bstart)) bstart = 1.0; if (!getparfloat("bend", &bend)) bend = 1.0; if (reci && ntap) vwarn("tapering influences the reciprocal result"); /* Reading in wavelet parameters */ if(!getparfloat("fpw", &WP.fp)) WP.fp = -1.0; if(!getparfloat("fminw", &WP.fmin)) WP.fmin = 10.0; if(!getparfloat("flefw", &WP.flef)) WP.flef = 20.0; if(!getparfloat("frigw", &WP.frig)) WP.frig = 50.0; if(!getparfloat("fmaxw", &WP.fmax)) WP.fmax = 60.0; else WP.fp = -1; if(!getparfloat("dbw", &WP.db)) WP.db = -20.0; if(!getparfloat("t0w", &WP.t0)) WP.t0 = 0.0; if(!getparint("shiftw", &WP.shift)) WP.shift = 0; if(!getparint("invw", &WP.inv)) WP.inv = 0; if(!getparfloat("epsw", &WP.eps)) WP.eps = 1.0; if(!getparfloat("scalew", &WP.scale)) WP.scale = 1.0; if(!getparint("scfftw", &WP.scfft)) WP.scfft = 1; if(!getparint("cmw", &WP.cm)) WP.cm = 10; if(!getparint("cnw", &WP.cn)) WP.cn = 1; if(!getparint("wav", &WP.wav)) WP.wav = 0; if(!getparstring("file_wav", &WP.file_wav)) WP.file_wav=NULL; if(!getparstring("w", &wavtype)) strcpy(WP.w, "g2"); else strcpy(WP.w, wavtype); if(!getparfloat("fpws", &WPs.fp)) WPs.fp = -1.0; if(!getparfloat("fminws", &WPs.fmin)) WPs.fmin = 10.0; if(!getparfloat("flefws", &WPs.flef)) WPs.flef = 20.0; if(!getparfloat("frigws", &WPs.frig)) WPs.frig = 50.0; if(!getparfloat("fmaxws", &WPs.fmax)) WPs.fmax = 60.0; else WPs.fp = -1; if(!getparfloat("dbw", &WPs.db)) WPs.db = -20.0; if(!getparfloat("t0ws", &WPs.t0)) WPs.t0 = 0.0; if(!getparint("shiftws", &WPs.shift)) WPs.shift = 0; if(!getparint("invws", &WPs.inv)) WPs.inv = 0; if(!getparfloat("epsws", &WPs.eps)) WPs.eps = 1.0; if(!getparfloat("scalews", &WPs.scale)) WPs.scale = 1.0; if(!getparint("scfftws", &WPs.scfft)) WPs.scfft = 1; if(!getparint("cmws", &WPs.cm)) WPs.cm = 10; if(!getparint("cnws", &WPs.cn)) WPs.cn = 1; if(!getparint("wavs", &WPs.wav)) WPs.wav = 0; if(!getparstring("file_wavs", &WPs.file_wav)) WPs.file_wav=NULL; if(!getparstring("ws", &wavtype2)) strcpy(WPs.w, "g2"); else strcpy(WPs.w, wavtype2); if(!getparint("niter", &niter)) niter = 10; if(!getparint("niterh", &niterh)) niterh = niter; /*================ Reading info about shot and initial operator sizes ================*/ ngath = 0; /* setting ngath=0 scans all traces; n2 contains maximum traces/gather */ if (file_ray!=NULL && file_tinv==NULL) { ret = getFileInfo(file_ray, &n2, &n1, &ngath, &d1, &d2, &f2, &f1, &xmin, &xmax, &scl, &ntraces); n1 = 1; ntraces = n2*ngath; scl = 0.0010; d1 = -1.0*xmin; xmin = -1.0*xmax; xmax = d1; WP.wav = 1; WP.xloc = -123456.0; WP.zloc = -123456.0; synpos = (int *)calloc(ngath,sizeof(int)); shot.nz = 1; shot.nx = ngath; shot.n = shot.nx*shot.nz; for (l=0; l<shot.nz; l++) { for (j=0; j<shot.nx; j++) { synpos[l*shot.nx+j] = j*shot.nz+l; } } } else if (file_ray==NULL && file_tinv==NULL) { getParameters(&mod, &rec, &src, &shot, &ray, verbose); n1 = 1; n2 = rec.n; ngath = shot.n; d1 = mod.dt; d2 = (rec.x[1]-rec.x[0])*mod.dx; f1 = 0.0; f2 = mod.x0+rec.x[0]*mod.dx; xmin = mod.x0+rec.x[0]*mod.dx; xmax = mod.x0+rec.x[rec.n-1]*mod.dx; scl = 0.0010; ntraces = n2*ngath; WP.wav = 1; WP.xloc = -123456.0; WP.zloc = -123456.0; synpos = (int *)calloc(ngath,sizeof(int)); for (l=0; l<shot.nz; l++) { for (j=0; j<shot.nx; j++) { synpos[l*shot.nx+j] = j*shot.nz+l; } } } else { ret = getFileInfo(file_tinv, &n1, &n2, &ngath, &d1, &d2, &f1, &f2, &xmin, &xmax, &scl, &ntraces); } Nsyn = ngath; nxs = n2; nts = n1; nt0 = n1; dxs = d2; fxs = f2; ngath = 0; /* setting ngath=0 scans all traces; nx contains maximum traces/gather */ ret = getFileInfo(file_shot, &nt, &nx, &ngath, &d1, &dx, &ft, &fx, &xmin, &xmax, &scl, &ntraces); nshots = ngath; assert (nxs >= nshots); if (!getparfloat("dt", &dt)) dt = d1; ntfft = optncr(MAX(nt+pad, nts+pad)); nfreq = ntfft/2+1; nw_low = (int)MIN((fmin*ntfft*dt), nfreq-1); nw_low = MAX(nw_low, 1); nw_high = MIN((int)(fmax*ntfft*dt), nfreq-1); nw = nw_high - nw_low + 1; scl = 1.0/((float)ntfft); if (nb > 1) { db = (bend-bstart)/((float)(nb-1)); } else if (nb == 1) { db = 0; bend = bstart; } /*================ Allocating all data arrays ================*/ green = (float *)calloc(Nsyn*nxs*ntfft,sizeof(float)); f2p = (float *)calloc(Nsyn*nxs*ntfft,sizeof(float)); pmin = (float *)calloc(Nsyn*nxs*ntfft,sizeof(float)); f1plus = (float *)calloc(Nsyn*nxs*ntfft,sizeof(float)); f1min = (float *)calloc(Nsyn*nxs*ntfft,sizeof(float)); G_d = (float *)calloc(Nsyn*nxs*ntfft,sizeof(float)); muteW = (int *)calloc(Nsyn*nxs,sizeof(int)); trace = (float *)malloc(ntfft*sizeof(float)); ixpossyn = (int *)malloc(nxs*sizeof(int)); xrcvsyn = (float *)calloc(Nsyn*nxs,sizeof(float)); xsyn = (float *)malloc(Nsyn*sizeof(float)); zsyn = (float *)malloc(Nsyn*sizeof(float)); xnxsyn = (int *)calloc(Nsyn,sizeof(int)); tapersy = (float *)malloc(nxs*sizeof(float)); Refl = (complex *)malloc(nw*nx*nshots*sizeof(complex)); tapersh = (float *)malloc(nx*sizeof(float)); xsrc = (float *)calloc(nshots,sizeof(float)); zsrc = (float *)calloc(nshots,sizeof(float)); xrcv = (float *)calloc(nshots*nx,sizeof(float)); xnx = (int *)calloc(nshots,sizeof(int)); /*================ Read and define mute window based on focusing operator(s) ================*/ /* G_d = p_0^+ = G_d (-t) ~ Tinv */ WPs.nt = ntfft; WPs.dt = dt; WP.nt = ntfft; WP.dt = dt; if (file_ray!=NULL || file_cp!=NULL) { makeWindow(WP, file_ray, file_amp, dt, xrcvsyn, xsyn, zsyn, xnxsyn, Nsyn, nxs, ntfft, mode, muteW, G_d, hw, verbose); } else { mode=-1; /* apply complex conjugate to read in data */ readTinvData(file_tinv, dt, xrcvsyn, xsyn, zsyn, xnxsyn, Nsyn, nxs, ntfft, mode, muteW, G_d, hw, verbose); } /* reading data added zero's to the number of time samples to be the same as ntfft */ nts = ntfft; /* define tapers to taper edges of acquisition */ if (tap == 1 || tap == 3) { for (j = 0; j < ntap; j++) tapersy[j] = (cos(PI*(j-ntap)/ntap)+1)/2.0; for (j = ntap; j < nxs-ntap; j++) tapersy[j] = 1.0; for (j = nxs-ntap; j < nxs; j++) tapersy[j] =(cos(PI*(j-(nxs-ntap))/ntap)+1)/2.0; } else { for (j = 0; j < nxs; j++) tapersy[j] = 1.0; } if (tap == 1 || tap == 3) { if (verbose) vmess("Taper for operator applied ntap=%d", ntap); for (l = 0; l < Nsyn; l++) { for (i = 0; i < nxs; i++) { for (j = 0; j < nts; j++) { G_d[l*nxs*nts+i*nts+j] *= tapersy[i]; } } } } /* check consistency of header values */ dxf = (xrcvsyn[nxs-1] - xrcvsyn[0])/(float)(nxs-1); if (NINT(dxs*1e3) != NINT(fabs(dxf)*1e3)) { vmess("dx in hdr.d1 (%.3f) and hdr.gx (%.3f) not equal",d2, dxf); if (dxf != 0) dxs = fabs(dxf); vmess("dx in operator => %f", dxs); } if (xrcvsyn[0] != 0 || xrcvsyn[1] != 0 ) fxs = xrcvsyn[0]; fxs2 = fxs + (float)(nxs-1)*dxs; /*================ Reading shot records ================*/ mode=1; readShotData(file_shot, xrcv, xsrc, zsrc, xnx, Refl, nw, nw_low, ngath, nx, nx, ntfft, mode, weight, tsq, Q, f0, verbose); tapersh = (float *)malloc(nx*sizeof(float)); if (tap == 2 || tap == 3) { for (j = 0; j < ntap; j++) tapersh[j] = (cos(PI*(j-ntap)/ntap)+1)/2.0; for (j = ntap; j < nx-ntap; j++) tapersh[j] = 1.0; for (j = nx-ntap; j < nx; j++) tapersh[j] =(cos(PI*(j-(nx-ntap))/ntap)+1)/2.0; } else { for (j = 0; j < nx; j++) tapersh[j] = 1.0; } if (tap == 2 || tap == 3) { if (verbose) vmess("Taper for shots applied ntap=%d", ntap); for (l = 0; l < nshots; l++) { for (j = 1; j < nw; j++) { for (i = 0; i < nx; i++) { Refl[l*nx*nw+j*nx+i].r *= tapersh[i]; Refl[l*nx*nw+j*nx+i].i *= tapersh[i]; } } } } free(tapersh); /* check consistency of header values */ fxf = xsrc[0]; if (nx > 1) dxf = (xrcv[0] - xrcv[nx-1])/(float)(nx-1); else dxf = d2; if (NINT(dx*1e3) != NINT(fabs(dxf)*1e3)) { vmess("dx in hdr.d1 (%.3f) and hdr.gx (%.3f) not equal",dx, dxf); if (dxf != 0) dx = fabs(dxf); else verr("gx hdrs not set"); vmess("dx used => %f", dx); } dxsrc = (float)xsrc[1] - xsrc[0]; if (dxsrc == 0) { vwarn("sx hdrs are not filled in!!"); dxsrc = dx; } /*================ Check the size of the files ================*/ if (NINT(dxsrc/dx)*dx != NINT(dxsrc)) { vwarn("source (%.2f) and receiver step (%.2f) don't match",dxsrc,dx); if (reci == 2) vwarn("step used from operator (%.2f) ",dxs); } di = NINT(dxf/dxs); if ((NINT(di*dxs) != NINT(dxf)) && verbose) vwarn("dx in receiver (%.2f) and operator (%.2f) don't match",dx,dxs); if (nt != nts) vmess("Time samples in shot (%d) and focusing operator (%d) are not equal",nt, nts); if (verbose) { vmess("Number of focusing operators = %d", Nsyn); vmess("Number of receivers in focusop = %d", nxs); vmess("number of shots = %d", nshots); vmess("number of receiver/shot = %d", nx); vmess("first model position = %.2f", fxs); vmess("last model position = %.2f", fxs2); vmess("first source position fxf = %.2f", fxf); vmess("source distance dxsrc = %.2f", dxsrc); vmess("last source position = %.2f", fxf+(nshots-1)*dxsrc); vmess("receiver distance dxf = %.2f", dxf); vmess("direction of increasing traces = %d", di); vmess("number of time samples (nt,nts) = %d (%d,%d)", ntfft, nt, nts); vmess("time sampling = %e ", dt); if (ampest > 0) vmess("Amplitude correction estimation is switched on"); if (nb > 0) vmess("Scaling estimation in %d step(s) from %.3f to %.3f (db=%.3f)",nb,bstart,bend,db); if (file_green != NULL) vmess("Green output file = %s ", file_green); if (file_gmin != NULL) vmess("Gmin output file = %s ", file_gmin); if (file_gplus != NULL) vmess("Gplus output file = %s ", file_gplus); if (file_pmin != NULL) vmess("Pmin output file = %s ", file_pmin); if (file_f2 != NULL) vmess("f2 (=pplus) output file = %s ", file_f2); if (file_f1min != NULL) vmess("f1min output file = %s ", file_f1min); if (file_f1plus != NULL)vmess("f1plus output file = %s ", file_f1plus); if (file_iter != NULL) vmess("Iterations output file = %s ", file_iter); } /*================ initializations ================*/ if (ixa || ixb) n2out = ixa + ixb + 1; else if (reci) n2out = nxs; else n2out = nshots; mem = Nsyn*n2out*ntfft*sizeof(float)/1048576.0; if (verbose) { vmess("number of output traces = %d", n2out); vmess("number of output samples = %d", ntfft); vmess("Size of output data/file = %.1f MB", mem); } //memcpy(Ni, G_d, Nsyn*nxs*ntfft*sizeof(float)); if (file_homg!=NULL) { hG_d = (float *)calloc(nxs*ntfft,sizeof(float)); hmuteW = (int *)calloc(nxs,sizeof(int)); hxrcvsyn = (float *)calloc(nxs,sizeof(float)); hxsyn = (float *)calloc(1,sizeof(float)); hzsyn = (float *)calloc(1,sizeof(float)); hxnxsyn = (int *)calloc(1,sizeof(int)); cshot = (complex *)calloc(nxs*nfreq,sizeof(complex)); if(!getparfloat("xloc", &WPs.xloc)) WPs.xloc = -123456.0; if(!getparfloat("zloc", &WPs.zloc)) WPs.zloc = -123456.0; if (WPs.xloc == -123456.0 && WPs.zloc == -123456.0) file_cp = NULL; if (WPs.xloc == -123456.0) WPs.xloc = 0.0; if (WPs.zloc == -123456.0) WPs.zloc = 0.0; xloc = WPs.xloc; zloc = WPs.zloc; ngath = 1; if (file_rays!=NULL || file_cp!=NULL) { WPs.wav=1; makeWindow(WPs, file_rays, file_amps, dt, hxrcvsyn, hxsyn, hzsyn, hxnxsyn, ngath, nxs, ntfft, mode, hmuteW, hG_d, hw, verbose); } else { mode=-1; /* apply complex conjugate to read in data */ readTinvData(file_tinvs, dt, hxrcvsyn, hxsyn, hzsyn, hxnxsyn, ngath, nxs, ntfft, mode, hmuteW, hG_d, hw, verbose); } WPs.xloc = -123456.0; WPs.zloc = -123456.0; if (tap == 1 || tap == 3) { if (verbose) vmess("Taper for operator applied ntap=%d", ntap); for (i = 0; i < nxs; i++) { for (j = 0; j < nts; j++) { hG_d[i*nts+j] *= tapersy[i]; } } } ngath = omp_get_max_threads(); synthesisPosistions(nx, nt, nxs, nts, dt, hxsyn, 1, xrcv, xsrc, fxs2, fxs, dxs, dxsrc, dx, ixa, ixb, reci, nshots, ixpossyn, &npossyn, verbose); iterations(Refl,nx,nt,nxs,nts,dt,hxsyn,1,xrcv,xsrc,fxs2,fxs,dxs,dxsrc,dx,ixa,ixb, ntfft,nw,nw_low,nw_high,mode,reci,nshots,ixpossyn,npossyn,pmin,f1min,f1plus, f2p,hG_d,hmuteW,smooth,shift,above,pad,nt0,&first,niterh,verbose); /* compute full Green's function G = int R * f2(t) + f2(-t) = Pplus + Pmin */ for (i = 0; i < npossyn; i++) { j = 0; /* set green to zero if mute-window exceeds nt/2 */ if (hmuteW[ixpossyn[i]] >= nts/2) { memset(&green[i*nts],0, sizeof(float)*nt); continue; } green[i*nts+j] = f2p[i*nts+j] + pmin[i*nts+j]; for (j = 1; j < nts; j++) { green[i*nts+j] = f2p[i*nts+nts-j] + pmin[i*nts+j]; } } applyMute(green, hmuteW, smooth, 4, 1, nxs, nts, ixpossyn, npossyn, shift, pad, nt0); omp_set_num_threads(ngath); /* Transform the green position to the frequency domain */ /*for (i = 0; i < npossyn; i++) { rc1fft(&green[i*nts],&cshot[i*nfreq],ntfft,-1); }*/ //free(hG_d);free(hmuteW);free(hxrcvsyn); free(hmuteW);free(hxrcvsyn); free(hxsyn);free(hzsyn);free(hxnxsyn);free(cshot); } /* dry-run of synthesis to get all x-positions calcalated by the integration */ synthesisPosistions(nx, nt, nxs, nts, dt, xsyn, Nsyn, xrcv, xsrc, fxs2, fxs, dxs, dxsrc, dx, ixa, ixb, reci, nshots, ixpossyn, &npossyn, verbose); if (verbose) { vmess("synthesisPosistions: nshots=%d npossyn=%d", nshots, npossyn); } t1 = wallclock_time(); tread = t1-t0; iterations(Refl,nx,nt,nxs,nts,dt,xsyn,Nsyn,xrcv,xsrc,fxs2,fxs,dxs,dxsrc,dx,ixa,ixb, ntfft,nw,nw_low,nw_high,mode,reci,nshots,ixpossyn,npossyn,pmin,f1min,f1plus, f2p,G_d,muteW,smooth,shift,above,pad,nt0,&first,niter,verbose); /*if (niter==0) { for (l = 0; l < Nsyn; l++) { for (i = 0; i < npossyn; i++) { j = 0; ix = ixpossyn[i]; f2p[l*nxs*nts+i*nts+j] = G_d[l*nxs*nts+ix*nts+j]; f1plus[l*nxs*nts+i*nts+j] = G_d[l*nxs*nts+ix*nts+j]; for (j = 1; j < nts; j++) { f2p[l*nxs*nts+i*nts+j] = G_d[l*nxs*nts+ix*nts+j]; f1plus[l*nxs*nts+i*nts+j] = G_d[l*nxs*nts+ix*nts+j]; } } } }*/ if (niterh==0) { for (l = 0; l < Nsyn; l++) { for (i = 0; i < npossyn; i++) { j = 0; ix = ixpossyn[i]; green[i*nts+j] = hG_d[ix*nts+j]; for (j = 1; j < nts; j++) { green[i*nts+j] = hG_d[ix*nts+nts-j]; } } } } if (file_img!=NULL) { /*================ set variables for output data ================*/ hdrs_im = (segy *) calloc(shot.nx,sizeof(segy)); if (hdrs_im == NULL) verr("allocation for hdrs_out"); Image = (float *)calloc(Nsyn,sizeof(float)); first=0; imaging(Image,WPs,Refl,nx,nt,nxs,nts,dt,xsyn,Nsyn,xrcv,xsrc,fxs2,fxs,dxs,dxsrc,dx,ixa,ixb, ntfft,nw,nw_low,nw_high,mode,reci,nshots,ixpossyn,npossyn,pmin,f1min,f1plus, f2p,G_d,muteW,smooth,shift,above,pad,nt0,synpos,verbose); /*============= write output files ================*/ fp_out = fopen(file_img, "w+"); for (i = 0; i < shot.nx; i++) { hdrs_im[i].fldr = 1; hdrs_im[i].tracl = 1; hdrs_im[i].tracf = i+1; hdrs_im[i].scalco = -1000; hdrs_im[i].scalel = -1000; hdrs_im[i].sdepth = 0; hdrs_im[i].trid = 1; hdrs_im[i].ns = shot.nz; hdrs_im[i].trwf = shot.nx; hdrs_im[i].ntr = hdrs_im[i].fldr*hdrs_im[i].trwf; hdrs_im[i].f1 = zsyn[0]; hdrs_im[i].f2 = xsyn[0]; hdrs_im[i].dt = dt*(1E6); hdrs_im[i].d1 = (float)zsyn[shot.nx]-zsyn[0]; hdrs_im[i].d2 = (float)xsyn[1]-xsyn[0]; hdrs_im[i].sx = (int)roundf(xsyn[0] + (i*hdrs_im[i].d2)); hdrs_im[i].gx = (int)roundf(xsyn[0] + (i*hdrs_im[i].d2)); hdrs_im[i].offset = (hdrs_im[i].gx - hdrs_im[i].sx)/1000.0; } ret = writeData(fp_out, &Image[0], hdrs_im, shot.nz, shot.nx); if (ret < 0 ) verr("error on writing output file."); fclose(fp_out); } if (file_homg!=NULL) { /*================ set variables for output data ================*/ hdrs_homg = (segy *) calloc(shot.nx,sizeof(segy)); if (hdrs_homg == NULL) verr("allocation for hdrs_out"); HomG = (float *)calloc(Nsyn*ntfft,sizeof(float)); homogeneousg(HomG,green,Refl,nx,nt,nxs,nts,dt,xsyn,Nsyn,xrcv,xsrc,fxs2,fxs,dxs,dxsrc,dx,ixa,ixb, ntfft,nw,nw_low,nw_high,mode,reci,nshots,ixpossyn,npossyn,pmin,f1min,f1plus, f2p,G_d,muteW,smooth,shift,above,pad,nt0,synpos,verbose); /*============= write output files ================*/ fp_out = fopen(file_homg, "w+"); for (j = 0; j < ntfft; j++) { for (i = 0; i < shot.nx; i++) { hdrs_homg[i].fldr = j+1; hdrs_homg[i].tracl = j*shot.nx+i+1; hdrs_homg[i].tracf = i+1; hdrs_homg[i].scalco = -1000; hdrs_homg[i].scalel = -1000; hdrs_homg[i].sdepth = (int)(zloc*1000.0); hdrs_homg[i].trid = 1; hdrs_homg[i].ns = shot.nz; hdrs_homg[i].trwf = shot.nx; hdrs_homg[i].ntr = hdrs_homg[i].fldr*hdrs_homg[i].trwf; hdrs_homg[i].f1 = zsyn[0]; hdrs_homg[i].f2 = xsyn[0]; hdrs_homg[i].dt = dt*(1E6); hdrs_homg[i].d1 = (float)zsyn[shot.nx]-zsyn[0]; hdrs_homg[i].d2 = (float)xsyn[1]-xsyn[0]; hdrs_homg[i].sx = (int)roundf(xsyn[0] + (i*hdrs_homg[i].d2)); hdrs_homg[i].gx = (int)roundf(xsyn[0] + (i*hdrs_homg[i].d2)); hdrs_homg[i].offset = (hdrs_homg[i].gx - hdrs_homg[i].sx)/1000.0; } ret = writeData(fp_out, &HomG[j*shot.n], hdrs_homg, shot.nz, shot.nx); if (ret < 0 ) verr("error on writing output file."); } fclose(fp_out); } if (verbose) { t1 = wallclock_time(); vmess("and CPU-time write data = %.3f", t1-t2); } free(tapersy); exit(0); }
void synthesis(complex *Refl, complex *Fop, float *Top, float *iRN, int nx, int nt, int nxs, int nts, float dt, float *xsyn, int Nfoc, float *xrcv, float *xsrc, int *xnx, float fxse, float fxsb, float dxs, float dxsrc, float dx, int ntfft, int nw, int nw_low, int nw_high, int mode, int reci, int nshots, int *ixpos, int npos, double *tfft, int *isxcount, int *reci_xsrc, int *reci_xrcv, float *ixmask, int verbose) { int nfreq, size, inx; float scl; int i, j, l, m, iw, ix, k, ixsrc, il, ik; float *rtrace, idxs; complex *sum, *ctrace; int npe; static int first=1, *ixrcv; static double t0, t1, t; size = nxs*nts; nfreq = ntfft/2+1; /* scale factor 1/N for backward FFT, * scale dt for correlation/convolution along time, * scale dx (or dxsrc) for integration over receiver (or shot) coordinates */ scl = 1.0*dt/((float)ntfft); #ifdef _OPENMP npe = omp_get_max_threads(); /* parallelisation is over number of shot positions (nshots) */ if (npe > nshots) { vmess("Number of OpenMP threads set to %d (was %d)", nshots, npe); omp_set_num_threads(nshots); } #endif t0 = wallclock_time(); /* reset output data to zero */ memset(&iRN[0], 0, Nfoc*nxs*nts*sizeof(float)); ctrace = (complex *)calloc(ntfft,sizeof(complex)); /* this first check is done to support an acquisition geometry that has more receiver than source * postions. In the first iteration the int R(x_r,x_s) Fop(x_r) d x_r results in a grid on x_s. * so for the next interations onlt x_s traces have to be computed on Fop */ if (!first) { /* transform muted Ni (Top) to frequency domain, input for next iteration */ for (l = 0; l < Nfoc; l++) { /* set Fop to zero, so new operator can be defined within ixpos points */ memset(&Fop[l*nxs*nw].r, 0, nxs*nw*2*sizeof(float)); for (i = 0; i < npos; i++) { rc1fft(&Top[l*size+i*nts],ctrace,ntfft,-1); ix = ixpos[i]; for (iw=0; iw<nw; iw++) { Fop[l*nxs*nw+iw*nxs+ix].r = ctrace[nw_low+iw].r; Fop[l*nxs*nw+iw*nxs+ix].i = mode*ctrace[nw_low+iw].i; } } } } else { /* only for first call to synthesis using all nxs traces in G_d */ /* transform G_d to frequency domain, over all nxs traces */ first=0; for (l = 0; l < Nfoc; l++) { /* set Fop to zero, so new operator can be defined within all ix points */ memset(&Fop[l*nxs*nw].r, 0, nxs*nw*2*sizeof(float)); for (i = 0; i < nxs; i++) { rc1fft(&Top[l*size+i*nts],ctrace,ntfft,-1); for (iw=0; iw<nw; iw++) { Fop[l*nxs*nw+iw*nxs+i].r = ctrace[nw_low+iw].r; Fop[l*nxs*nw+iw*nxs+i].i = mode*ctrace[nw_low+iw].i; } } } idxs = 1.0/dxs; ixrcv = (int *)malloc(nshots*nx*sizeof(int)); for (k=0; k<nshots; k++) { for (i = 0; i < nx; i++) { ixrcv[k*nx+i] = NINT((xrcv[k*nx+i]-fxsb)*idxs); } } } free(ctrace); t1 = wallclock_time(); *tfft += t1 - t0; if (reci == 0 || reci == 1) { /*================ SYNTHESIS ================*/ #pragma omp parallel default(none) \ shared(iRN, dx, npe, nw, verbose, nshots, xnx) \ shared(Refl, Nfoc, reci, xsrc, xsyn, fxsb, fxse, nxs, dxs) \ shared(nx, dxsrc, nfreq, nw_low, nw_high) \ shared(Fop, size, nts, ntfft, scl, ixrcv) \ private(l, ix, j, m, i, sum, rtrace, k, ixsrc, inx) { /* start of parallel region */ sum = (complex *)malloc(nfreq*sizeof(complex)); rtrace = (float *)calloc(ntfft,sizeof(float)); /* Loop over total number of shots */ #pragma omp for schedule(guided,1) for (k=0; k<nshots; k++) { if ((xsrc[k] < 0.999*fxsb) || (xsrc[k] > 1.001*fxse)) continue; ixsrc = NINT((xsrc[k] - fxsb)/dxs); inx = xnx[k]; /* number of traces per shot */ for (l = 0; l < Nfoc; l++) { /* compute integral over receiver positions */ /* multiply R with Fop and sum over nx */ memset(&sum[0].r,0,nfreq*2*sizeof(float)); for (j = nw_low, m = 0; j <= nw_high; j++, m++) { for (i = 0; i < inx; i++) { ix = ixrcv[k*nx+i]; sum[j].r += Refl[k*nw*nx+m*nx+i].r*Fop[l*nw*nxs+m*nxs+ix].r - Refl[k*nw*nx+m*nx+i].i*Fop[l*nw*nxs+m*nxs+ix].i; sum[j].i += Refl[k*nw*nx+m*nx+i].i*Fop[l*nw*nxs+m*nxs+ix].r + Refl[k*nw*nx+m*nx+i].r*Fop[l*nw*nxs+m*nxs+ix].i; } } /* transfrom result back to time domain */ cr1fft(sum, rtrace, ntfft, 1); /* place result at source position ixsrc; dx = receiver distance */ for (j = 0; j < nts; j++) iRN[l*size+ixsrc*nts+j] += rtrace[j]*scl*dx; } /* end of parallel Nfoc loop */ if (verbose>4) vmess("*** Shot gather %d processed ***", k); } /* end of nshots (k) loop */ free(sum); free(rtrace); } /* end of parallel region */ } /* end of if reci */ /* if reciprocal traces are enabled start a new loop over reciprocal shot positions */ if (reci != 0) { #pragma omp parallel default(none) \ shared(iRN, dx, nw, verbose) \ shared(Refl, Nfoc, reci, xsrc, xsyn, fxsb, fxse, nxs, dxs) \ shared(nx, dxsrc, nfreq, nw_low, nw_high) \ shared(reci_xrcv, reci_xsrc, ixmask, isxcount) \ shared(Fop, size, nts, ntfft, scl, ixrcv) \ private(l, ix, j, m, i, k, sum, rtrace, ik, il, ixsrc, inx) { /* start of parallel region */ sum = (complex *)malloc(nfreq*sizeof(complex)); rtrace = (float *)calloc(ntfft,sizeof(float)); #pragma omp for schedule(guided,1) for (k=0; k<nxs; k++) { if (isxcount[k] == 0) continue; ixsrc = k; inx = isxcount[ixsrc]; /* number of traces per reciprocal shot */ for (l = 0; l < Nfoc; l++) { /* compute integral over (reciprocal) source positions */ /* multiply R with Fop and sum over nx */ memset(&sum[0].r,0,nfreq*2*sizeof(float)); for (j = nw_low, m = 0; j <= nw_high; j++, m++) { for (i = 0; i < inx; i++) { il = reci_xrcv[ixsrc*nxs+i]; ik = reci_xsrc[ixsrc*nxs+i]; ix = NINT((xsrc[il] - fxsb)/dxs); sum[j].r += Refl[il*nw*nx+m*nx+ik].r*Fop[l*nw*nxs+m*nxs+ix].r - Refl[il*nw*nx+m*nx+ik].i*Fop[l*nw*nxs+m*nxs+ix].i; sum[j].i += Refl[il*nw*nx+m*nx+ik].i*Fop[l*nw*nxs+m*nxs+ix].r + Refl[il*nw*nx+m*nx+ik].r*Fop[l*nw*nxs+m*nxs+ix].i; } } /* transfrom result back to time domain */ cr1fft(sum, rtrace, ntfft, 1); /* place result at source position ixsrc; dxsrc = shot distance */ for (j = 0; j < nts; j++) iRN[l*size+ixsrc*nts+j] = ixmask[ixsrc]*(iRN[l*size+ixsrc*nts+j]+rtrace[j]*scl*dxsrc); } /* end of Nfoc loop */ } /* end of parallel reciprocal shots (k) loop */ free(sum); free(rtrace); } /* end of parallel region */ } /* end of if reci */ t = wallclock_time() - t0; if (verbose>2) { vmess("OMP: parallel region = %f seconds (%d threads)", t, npe); } return; }
double wallclock_time_(void) { return (double)wallclock_time(); }
int main(int argc, char **argv) { modPar mod; recPar rec; snaPar sna; wavPar wav; srcPar src; bndPar bnd; shotPar shot; float **src_nwav; float *rox, *roz, *l2m, *lam, *mul; float *tss, *tes, *tep, *p, *q, *r; float *vx, *vz, *tzz, *txz, *txx; float *rec_vx, *rec_vz, *rec_p; float *rec_txx, *rec_tzz, *rec_txz; float *rec_pp, *rec_ss; float *rec_udp, *rec_udvz; float *beam_vx, *beam_vz, *beam_p; float *beam_txx, *beam_tzz, *beam_txz; float *beam_pp, *beam_ss; float sinkvel; double t0, t1, t2, t3, tt, tinit; size_t size, sizem, nsamp, memsize; int n1, ix, iz, ir, ishot, i; int ioPx, ioPz; int it0, it1, its, it, fileno, isam; int ixsrc, izsrc; int verbose; t0= wallclock_time(); initargs(argc,argv); requestdoc(0); if (!getparint("verbose",&verbose)) verbose=0; getParameters(&mod, &rec, &sna, &wav, &src, &shot, &bnd, verbose); /* allocate arrays for model parameters: the different schemes use different arrays */ n1 = mod.naz; sizem=mod.nax*mod.naz; rox = (float *)calloc(sizem,sizeof(float)); roz = (float *)calloc(sizem,sizeof(float)); l2m = (float *)calloc(sizem,sizeof(float)); if (mod.ischeme==2) { tss = (float *)calloc(sizem,sizeof(float)); tep = (float *)calloc(sizem,sizeof(float)); q = (float *)calloc(sizem,sizeof(float)); } if (mod.ischeme>2) { lam = (float *)calloc(sizem,sizeof(float)); mul = (float *)calloc(sizem,sizeof(float)); } if (mod.ischeme==4) { tss = (float *)calloc(sizem,sizeof(float)); tes = (float *)calloc(sizem,sizeof(float)); tep = (float *)calloc(sizem,sizeof(float)); r = (float *)calloc(sizem,sizeof(float)); p = (float *)calloc(sizem,sizeof(float)); q = (float *)calloc(sizem,sizeof(float)); } /* read velocity and density files */ readModel(mod, bnd, rox, roz, l2m, lam, mul, tss, tes, tep); /* read and/or define source wavelet(s) */ /* Using a random source, which can have a random length for each source position, a pointer array with variable length (wav.nsamp[i]) is used. The total length of all the source lengths together is wav.nst */ if (wav.random) { src_nwav = (float **)calloc(wav.nx,sizeof(float *)); src_nwav[0] = (float *)calloc(wav.nst,sizeof(float)); assert(src_nwav[0] != NULL); nsamp = 0; for (i=0; i<wav.nx; i++) { src_nwav[i] = (float *)(src_nwav[0] + nsamp); nsamp += wav.nsamp[i]; } } else { src_nwav = (float **)calloc(wav.nx,sizeof(float *)); src_nwav[0] = (float *)calloc(wav.nt*wav.nx,sizeof(float)); assert(src_nwav[0] != NULL); for (i=0; i<wav.nx; i++) { src_nwav[i] = (float *)(src_nwav[0] + wav.nt*i); } } defineSource(wav, src, src_nwav, mod.grid_dir, verbose); /* allocate arrays for wavefield and receiver arrays */ vx = (float *)calloc(sizem,sizeof(float)); vz = (float *)calloc(sizem,sizeof(float)); tzz = (float *)calloc(sizem,sizeof(float)); /* =P field for acoustic */ if (mod.ischeme>2) { txz = (float *)calloc(sizem,sizeof(float)); txx = (float *)calloc(sizem,sizeof(float)); } if (rec.type.vz) rec_vz = (float *)calloc(size,sizeof(float)); size = rec.n*rec.nt; if (rec.type.vz) rec_vz = (float *)calloc(size,sizeof(float)); if (rec.type.vx) rec_vx = (float *)calloc(size,sizeof(float)); if (rec.type.p) rec_p = (float *)calloc(size,sizeof(float)); if (rec.type.txx) rec_txx = (float *)calloc(size,sizeof(float)); if (rec.type.tzz) rec_tzz = (float *)calloc(size,sizeof(float)); if (rec.type.txz) rec_txz = (float *)calloc(size,sizeof(float)); if (rec.type.pp) rec_pp = (float *)calloc(size,sizeof(float)); if (rec.type.ss) rec_ss = (float *)calloc(size,sizeof(float)); if (rec.type.ud) { /* get velcity and density at first receiver location */ ir = mod.ioZz + rec.z[0]+(rec.x[0]+mod.ioZx)*n1; rec.rho = mod.dt/(mod.dx*roz[ir]); rec.cp = sqrt(l2m[ir]*(roz[ir]))*mod.dx/mod.dt; rec_udvz = (float *)calloc(mod.nax*rec.nt,sizeof(float)); rec_udp = (float *)calloc(mod.nax*rec.nt,sizeof(float)); } if(sna.beam) { size = sna.nz*sna.nx; if (sna.type.vz) beam_vz = (float *)calloc(size,sizeof(float)); if (sna.type.vx) beam_vx = (float *)calloc(size,sizeof(float)); if (sna.type.p) beam_p = (float *)calloc(size,sizeof(float)); if (sna.type.txx) beam_txx = (float *)calloc(size,sizeof(float)); if (sna.type.tzz) beam_tzz = (float *)calloc(size,sizeof(float)); if (sna.type.txz) beam_txz = (float *)calloc(size,sizeof(float)); if (sna.type.pp) beam_pp = (float *)calloc(size,sizeof(float)); if (sna.type.ss) beam_ss = (float *)calloc(size,sizeof(float)); } t1= wallclock_time(); if (verbose) { tinit = t1-t0; vmess("*******************************************"); vmess("************* runtime info ****************"); vmess("*******************************************"); vmess("CPU time for intializing arrays and model = %f", tinit); } /* Sinking source and receiver arrays: If P-velocity==0 the source and receiver postions are placed deeper until the P-velocity changes. The free-surface position is stored in bnd.surface[ix]. Setting the option rec.sinkvel only sinks the receiver position (not the source) and uses the velocity of the first receiver to sink through to the next layer. */ ioPx=mod.ioPx; ioPz=mod.ioPz; if (bnd.lef==4 || bnd.lef==2) ioPx += bnd.ntap; if (bnd.top==4 || bnd.top==2) ioPz += bnd.ntap; if (rec.sinkvel) sinkvel=l2m[(rec.x[0]+ioPx)*n1+rec.z[0]+ioPz]; else sinkvel = 0.0; /* sink receivers to value different than sinkvel */ for (ir=0; ir<rec.n; ir++) { iz = rec.z[ir]; ix = rec.x[ir]; while(l2m[(ix+ioPx)*n1+iz+ioPz] == sinkvel) iz++; rec.z[ir]=iz+rec.sinkdepth; rec.zr[ir]=rec.zr[ir]+(rec.z[ir]-iz)*mod.dz; // rec.zr[ir]=rec.z[ir]*mod.dz; if (verbose>3) vmess("receiver position %d at grid[ix=%d, iz=%d] = (x=%f z=%f)", ir, ix+ioPx, rec.z[ir]+ioPz, rec.xr[ir]+mod.x0, rec.zr[ir]+mod.z0); } /* sink sources to value different than zero */ for (ishot=0; ishot<shot.n; ishot++) { iz = shot.z[ishot]; ix = shot.x[ishot]; while(l2m[(ix+ioPx)*n1+iz+ioPz] == 0.0) iz++; shot.z[ishot]=iz+src.sinkdepth; } /* scan for free surface boundary in case it has a topography */ for (ix=0; ix<mod.nx; ix++) { iz = ioPz; while(l2m[(ix+ioPx)*n1+iz] == 0.0) iz++; bnd.surface[ix+ioPx] = iz; if ((verbose>3) && (iz != ioPz)) vmess("Topgraphy surface x=%.2f z=%.2f", mod.x0+mod.dx*ix, mod.z0+mod.dz*(iz-ioPz)); } for (ix=0; ix<ioPx; ix++) { bnd.surface[ix] = bnd.surface[ioPx]; } for (ix=ioPx+mod.nx; ix<mod.iePx; ix++) { bnd.surface[ix] = bnd.surface[mod.iePx-1]; } if (verbose>3) writeSrcRecPos(&mod, &rec, &src, &shot); /* Outer loop over number of shots */ for (ishot=0; ishot<shot.n; ishot++) { izsrc = shot.z[ishot]; ixsrc = shot.x[ishot]; fileno= 0; memset(vx,0,sizem*sizeof(float)); memset(vz,0,sizem*sizeof(float)); memset(tzz,0,sizem*sizeof(float)); if (mod.ischeme==2) { memset(q,0,sizem*sizeof(float)); } if (mod.ischeme>2) { memset(txz,0,sizem*sizeof(float)); memset(txx,0,sizem*sizeof(float)); } if (mod.ischeme==4) { memset(r,0,sizem*sizeof(float)); memset(p,0,sizem*sizeof(float)); memset(q,0,sizem*sizeof(float)); } if (verbose) { if (!src.random) { vmess("Modeling source %d at gridpoints ix=%d iz=%d", ishot, shot.x[ishot], shot.z[ishot]); vmess(" which are actual positions x=%.2f z=%.2f", mod.x0+mod.dx*shot.x[ishot], mod.z0+mod.dz*shot.z[ishot]); } vmess("Receivers at gridpoint x-range ix=%d - %d", rec.x[0], rec.x[rec.n-1]); vmess(" which are actual positions x=%.2f - %.2f", mod.x0+rec.xr[0], mod.x0+rec.xr[rec.n-1]); vmess("Receivers at gridpoint z-range iz=%d - %d", rec.z[0], rec.z[rec.n-1]); vmess(" which are actual positions z=%.2f - %.2f", mod.z0+rec.zr[0], mod.z0+rec.zr[rec.n-1]); } if (mod.grid_dir) { /* reverse time modeling */ it0=-mod.nt+1; it1=0; its=-1; it0=0; it1=mod.nt; its=1; } else { it0=0; it1=mod.nt; its=1; } /* Main loop over the number of time steps */ for (it=it0; it<it1; it++) { #pragma omp parallel default (shared) \ shared (rox, roz, l2m, lam, mul, txx, txz, tzz, vx, vz) \ shared (tss, tep, tes, r, q, p) \ shared (tinit, it0, it1, its) \ shared(beam_vx, beam_vz, beam_txx, beam_tzz, beam_txz, beam_p, beam_pp, beam_ss) \ shared(rec_vx, rec_vz, rec_txx, rec_tzz, rec_txz, rec_p, rec_pp, rec_ss) \ private (tt, t2, t3) \ shared (shot, bnd, mod, src, wav, rec, ixsrc, izsrc, it, src_nwav, verbose) { switch ( mod.ischeme ) { case 1 : /* Acoustic FD kernel */ if (mod.iorder==2) { acoustic2(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, vx, vz, tzz, rox, roz, l2m, verbose); } else if (mod.iorder==4) { if (mod.sh) { acousticSH4(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, vx, vz, tzz, rox, roz, l2m, verbose); } else { acoustic4(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, vx, vz, tzz, rox, roz, l2m, verbose); } } else if (mod.iorder==6) { acoustic6(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, vx, vz, tzz, rox, roz, l2m, verbose); } break; case 2 : /* Visco-Acoustic FD kernel */ viscoacoustic4(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, vx, vz, tzz, rox, roz, l2m, tss, tep, q, verbose); break; case 3 : /* Elastic FD kernel */ if (mod.iorder==4) { elastic4(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, vx, vz, tzz, txx, txz, rox, roz, l2m, lam, mul, verbose); } else if (mod.iorder==6) { elastic6(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, vx, vz, tzz, txx, txz, rox, roz, l2m, lam, mul, verbose); } break; case 4 : /* Visco-Elastic FD kernel */ viscoelastic4(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, vx, vz, tzz, txx, txz, rox, roz, l2m, lam, mul, tss, tep, tes, r, q, p, verbose); break; } /* write samples to file if rec.nt samples are calculated */ #pragma omp master { if ( (((it-rec.delay) % rec.skipdt)==0) && (it >= rec.delay) ) { int writeToFile, itwritten; writeToFile = ! ( (((it-rec.delay)/rec.skipdt)+1)%rec.nt ); itwritten = fileno*(rec.nt)*rec.skipdt; isam = (it-rec.delay-itwritten)/rec.skipdt; /* store time at receiver positions */ getRecTimes(mod, rec, bnd, it, isam, vx, vz, tzz, txx, txz, rec_vx, rec_vz, rec_txx, rec_tzz, rec_txz, rec_p, rec_pp, rec_ss, rec_udp, rec_udvz, verbose); /* at the end of modeling a shot, write receiver array to output file(s) */ if (writeToFile && (it+rec.skipdt <= it1-1) ) { fileno = ( ((it-rec.delay)/rec.skipdt)+1)/rec.nt; writeRec(rec, mod, bnd, wav, ixsrc, izsrc, isam+1, ishot, fileno, rec_vx, rec_vz, rec_txx, rec_tzz, rec_txz, rec_p, rec_pp, rec_ss, rec_udp, rec_udvz, verbose); } } /* write snapshots to output file(s) */ if (sna.nsnap) { writeSnapTimes(mod, sna, ixsrc, izsrc, it, vx, vz, tzz, txx, txz, verbose); } /* calculate beams */ if(sna.beam) { getBeamTimes(mod, sna, vx, vz, tzz, txx, txz, beam_vx, beam_vz, beam_txx, beam_tzz, beam_txz, beam_p, beam_pp, beam_ss, verbose); } } /* taper the edges of the model */ // taperEdges(mod, bnd, vx, vz, verbose); #pragma omp master { if (verbose) { if (it==it0+100*its) t2=wallclock_time(); if (it==(it0+500*its)) { t3=wallclock_time(); tt=(t3-t2)*(((it1-it0)*its)/400.0); vmess("Estimated compute time = %.2f s. per shot.",tt); vmess("Estimated total compute time = %.2f s.",tinit+shot.n*tt); } } } } /* end of OpenMP parallel section */ } /* end of loop over time steps it */ /* write output files: receivers and or beams */ if (fileno) fileno++; if (rec.scale==1) { /* scale receiver with distance src-rcv */ float xsrc, zsrc, Rrec, rdx, rdz; int irec; xsrc=mod.x0+mod.dx*ixsrc; zsrc=mod.z0+mod.dz*izsrc; for (irec=0; irec<rec.n; irec++) { rdx=mod.x0+rec.xr[irec]-xsrc; rdz=mod.z0+rec.zr[irec]-zsrc; Rrec = sqrt(rdx*rdx+rdz*rdz); fprintf(stderr,"Rec %d is scaled with distance %f R=%.2f,%.2f S=%.2f,%.2f\n", irec, Rrec,rdx,rdz,xsrc,zsrc); for (it=0; it<rec.nt; it++) { rec_p[irec*rec.nt+it] *= sqrt(Rrec); } } } writeRec(rec, mod, bnd, wav, ixsrc, izsrc, isam+1, ishot, fileno, rec_vx, rec_vz, rec_txx, rec_tzz, rec_txz, rec_p, rec_pp, rec_ss, rec_udp, rec_udvz, verbose); writeBeams(mod, sna, ixsrc, izsrc, ishot, fileno, beam_vx, beam_vz, beam_txx, beam_tzz, beam_txz, beam_p, beam_pp, beam_ss, verbose); } /* end of loop over number of shots */ t1= wallclock_time(); if (verbose) { vmess("Total compute time FD modelling = %.2f s.", t1-t0); } /* free arrays */ free(rox); free(roz); free(l2m); free(src_nwav[0]); free(src_nwav); free(vx); free(vz); free(tzz); if (rec.type.vz) free(rec_vz); if (rec.type.vx) free(rec_vx); if (rec.type.p) free(rec_p); if (rec.type.txx) free(rec_txx); if (rec.type.tzz) free(rec_tzz); if (rec.type.txz) free(rec_txz); if (rec.type.pp) free(rec_pp); if (rec.type.ss) free(rec_ss); if (rec.type.ud) { free(rec_udvz); free(rec_udp); } if(sna.beam) { if (sna.type.vz) free(beam_vz); if (sna.type.vx) free(beam_vx); if (sna.type.p) free(beam_p); if (sna.type.txx) free(beam_txx); if (sna.type.tzz) free(beam_tzz); if (sna.type.txz) free(beam_txz); if (sna.type.pp) free(beam_pp); if (sna.type.ss) free(beam_ss); } if (mod.ischeme==2) { free(tss); free(tep); free(q); } if (mod.ischeme>2) { free(lam); free(mul); free(txz); free(txx); } if (mod.ischeme==4) { free(tss); free(tes); free(tep); free(r); free(p); free(q); } return 0; }
int main(int argc, char *argv[]) { FILE *shot_file, *vel_file, *out_file, *beam_file; size_t nread, bytes, size, trace_sz, size_out; int verbose, method, ntraces, verb_root; int nxv, nyv, nzv, binary_file, dstep, id, id1, id2; int d, nt, ndepth, i, j, conjg, conjgs, mode, out_su; int ntap, tap_opt, order, McC, oplx, oply, fine, MB; int stackmigr, imc, area, ixmin, ixmax, iymin, iymax, ns; int nfft, nfreq, nw_high, nw_low, nw, sx, sy, ix, iy; int npages_w, sxy, iw, one_shot, traces_shot, sign, is; int traces_read_in, nxy, fd, nx, ny, num_threads, nel, oper_opt; int fldr_w, power_of_2, beam_su, nterms, filter_inc, beam; Area shot_area; float alpha, weight, scl, sclw; float fmin, fmax, dt; float *tot_beam, *beams, scale; float *velocity, weights, tshift, zrcv; float xvmin, yvmin, zvmin, dxv, dyv, dzv, vmin, vmax; float dw, df, om, dtw, tdw, t_w, tr, ti; double t0, t1, t2, t3, t_migr=0, t_io=0, t_table=0, t_init=0; double t_comm=0; complex *rec_all, *rec_field, *rec; char *file_vel, *file_in, *file_out, *file_beam, *file_table; char *tmp_dir, sys_call[256]; segy *hdr; int npes, pe, root_pe=0, nlw, maxlw, *freq_index, fdist, ipe; #ifdef MPI int *nlwcounts, *recvcounts, *displacements; int nlw_tag; complex *gath_rec_field; MPI_Status status; MPI_Request request; MPI_Init( &argc, &argv ); MPI_Comm_size( MPI_COMM_WORLD, &npes ); MPI_Comm_rank( MPI_COMM_WORLD, &pe ); #else npes = 1; pe = 0; #endif t0 = wallclock_time(); /* Read in parameters */ initargs(argc,argv); requestdoc(0); if(!getparstring("file_in", &file_in)) file_in=NULL; if(!getparstring("file_vel", &file_vel)) file_vel=NULL; if(!getparstring("file_out", &file_out)) file_out=NULL; if(!getparstring("file_beam", &file_beam)) file_beam=" "; if(!getparstring("file_table", &file_table)) file_table=NULL; if(!getparstring("tmp_dir", &tmp_dir)) tmp_dir="/tmp"; if(!getparfloat("fmin", &fmin)) fmin = 0.0; if(!getparfloat("fmax", &fmax)) fmax = 45.0; if(!getparint("mode", &mode)) mode = 1; if(!getparint("ntap", &ntap)) ntap = 0; if(!getparint("tap_opt", &tap_opt)) tap_opt = 1; if(!getparint("method", &method)) method = 1; if(!getparint("conjg", &conjg)) conjg = 0; if(!getparint("conjgs", &conjgs)) conjgs = 0; if(!getparint("area", &area)) area = 0; if(!getparint("oplx", &oplx)) oplx = 25; if(!getparint("oply", &oply)) oply = oplx; if(!getparint("order", &order)) order = 13; if(!getparint("McC", &McC)) McC = 1; if(!getparint("oper_opt", &oper_opt)) oper_opt = 1; if(!getparint("nterms", &nterms)) nterms = 1; if(!getparint("filter_inc", &filter_inc)) filter_inc = 1; if(!getparfloat("alpha", &alpha)) alpha = 65.0; if(!getparfloat("weight", &weight)) weight = 5e-5; if(!getparfloat("weights", &weights)) weights = 1e-2; if(!getparint("fine", &fine)) fine = 2; if(!getparint("beam", &beam)) beam = 0; if(!getparint("verbose", &verbose)) verbose = 0; if(!ISODD(oplx)) oplx += 1; if(!ISODD(oply)) oply += 1; if(conjg) conjg = -1; else conjg = 1; if(conjgs) conjgs = -1; else conjgs = 1; if(mode >= 0) mode = 1; if(mode < 0) mode = -1; assert(McC <= 2 && McC >= 1); assert(method <= 4 && method >= 1); assert(file_vel != NULL); assert(file_out != NULL); out_su = (strstr(file_out, ".su")!=NULL); beam_su = (strstr(file_beam, ".su")!=NULL); if (verbose && pe==root_pe) verb_root=verbose; else verb_root = 0; t1 = wallclock_time(); t_init += t1-t0; /* Clean up 'old' velocity files */ sprintf(sys_call,"rm -rf %s/velocity*.bin\n",tmp_dir); system(sys_call); #ifdef MPI MPI_Barrier(MPI_COMM_WORLD); #endif /* Open velocity file and determine the size of the file */ openVelocityFile(file_vel, &vel_file, &shot_area, verb_root); #ifdef MPI MPI_Barrier(MPI_COMM_WORLD); #endif xvmin = shot_area.xmin; yvmin = shot_area.ymin; zvmin = shot_area.zmin; nxv = shot_area.nx; nyv = shot_area.ny; nzv = shot_area.nz; dxv = shot_area.dx; dyv = shot_area.dy; dzv = shot_area.dz; nxy = shot_area.sxy; if(!getparfloat("zrcv", &zrcv)) zrcv = zvmin+(nzv-1)*dzv; ndepth = NINT((zrcv-zvmin)/dzv); if(!getparint("dstep", &dstep)) dstep = MIN(5, ndepth); if(!getparfloat("vmin", &vmin)) vmin = 1500; if(!getparfloat("vmax", &vmax)) vmax = 4800; /* Open file_in file and read first header */ hdr = (segy *)calloc(1,sizeof(segy)); if (file_in == NULL) shot_file = stdin; else shot_file = fopen( file_in, "r" ); assert( shot_file ); nread = fread( hdr, 1, TRCBYTES, shot_file ); assert (nread == TRCBYTES); fseek ( shot_file, 0, SEEK_END ); bytes = ftell(shot_file); nt = hdr[0].ns; dt = 1e-6*hdr[0].dt; trace_sz = sizeof(float)*nt+TRCBYTES; ntraces = (int) (bytes/trace_sz); nfft = optncr(nt); nfreq = nfft/2 + 1; df = 1.0/(nfft*dt); dw = 2.*M_PI*df; nw_high = MIN( (int)(fmax/df), nfreq ); nw_low = MAX( (int)((fmin)/df), 1 ); nw = nw_high - nw_low + 1; sx = hdr[0].sx; sy = hdr[0].sy; if (hdr[0].scalco < 0) scl = 1.0/fabs(hdr[0].scalco); else if (hdr[0].scalco == 0) scl = 1.0; else scl = hdr[0].scalco; t2 = wallclock_time(); t_io += t2-t1; /*======= compute frequency distribution for multiple CPU's ========*/ fdist = 0; maxlw = ceil((float)nw/(float)npes); freq_index = (int *)malloc(maxlw*sizeof(int)); nlw = frequency_distribution(nw_low, nw, npes, pe, maxlw, freq_index, fdist ); #ifdef MPI if( verbose ) { /* print out all the frequencies for each process */ MPI_Barrier(MPI_COMM_WORLD); for( ipe=0; ipe<npes; ipe++ ) { if( pe == ipe ) { fprintf(stderr, "pe=%d:\tf[%d] = df*{", pe, nlw ); if( nlw > 0 ) for( iw=0; iw<nlw; iw++ ) fprintf(stderr, " %d", freq_index[iw] ); fprintf( stderr, " }\n" ); fflush(stderr); } MPI_Barrier(MPI_COMM_WORLD); } } if (npes == 1) nlw = nw; nlwcounts = (int *)malloc(npes*sizeof(int)); recvcounts = (int *)malloc(npes*sizeof(int)); displacements = (int *)malloc(npes*sizeof(int)); nlw_tag = 1; if (pe == root_pe) { displacements[0] = 0; nlwcounts[0] = nlw; for( ipe=1; ipe<npes; ipe++ ) { MPI_Recv(&nlwcounts[ipe], 1, MPI_INT, ipe, nlw_tag, MPI_COMM_WORLD, &status); displacements[ipe] = displacements[ipe-1]+nlwcounts[ipe-1]; } } else { MPI_Send(&nlw, 1, MPI_INT, root_pe, nlw_tag, MPI_COMM_WORLD); } #else nlw = nw; #endif fmin = MAX(0,-df + df*freq_index[0]); fmax = df + df*freq_index[nlw-1]; assert( fmax < 1.0/(2.0*dt) ); /* Nyguist in time */ assert( (2.0*fmax)/vmin < 1.0/dxv ); /* Nyguist in space */ assert( (2.0*fmax)/vmin < 1.0/dyv ); /* Nyguist in space */ size = (size_t)nlw*nxy*sizeof(complex); if (verb_root) { fprintf(stderr," minimum velocity = %.2f\n", vmin); fprintf(stderr," maximum velocity = %.2f\n", vmax); MB = 1024*1024; fprintf(stderr,"\n DATA INFORMATION\n"); fprintf(stderr," nw = %d\n", nw); fprintf(stderr," fmin = %.3f fmax = %.3f\n", nw_low*df, nw_high*df); fprintf(stderr," dt = %.4f nt = %d nfft = %d\n", dt, nt, nfft); fprintf(stderr," size of rec_field = %ld Mbytes\n", size/MB); size_out = (size_t)(nt)*(size_t)(nxy)*sizeof(float); if (out_su) size_out += (TRCBYTES*nxy); fprintf(stderr," size of output file = %ld Mbytes\n", size_out/MB); } /* Open beam file if beam == 1 */ if (beam && pe == root_pe) { beam_file = fopen( file_beam, "w+" ); assert( beam_file ); } t1 = wallclock_time(); t_init += t1-t2; /* Calculate operator tables */ if (method == 1) { tablecalc_2D(oplx, oply, nxv, dxv, nyv, dyv, dzv, alpha, fmin, fmax, vmin, vmax, df, weight, fine, oper_opt, file_table, verb_root); } else if (method == 2) { tablecalc_1D(order, nxv, dxv, dzv, alpha, fmin, fmax, vmin, vmax, df, fine, oper_opt, verb_root); } t2 = wallclock_time(); t_table = t2-t1; if (verb_root) fprintf(stderr," time to calculate tables : %.3f s.\n", t_table); /* ============ INITIALIZE AND CHECK PARAMETERS =============== */ /* allocate rec field to zero and distribute along machine */ rec_field = (complex *)calloc(nlw*nxy, sizeof(complex)); assert(rec_field != NULL); velocity = (float *)malloc(dstep*nxy*sizeof(float)); assert(velocity != NULL); if (beam) { beams = (float *)calloc(dstep*nxy, sizeof(float)); assert(beams != NULL); #ifdef MPI tot_beam = (float *)calloc(dstep*nxy, sizeof(float)); assert(tot_beam != NULL); #endif } #ifdef MPI if (pe == root_pe) { gath_rec_field = (complex *)calloc(nxy*nw,sizeof(complex)); assert(gath_rec_field != NULL); } #endif one_shot = 1; traces_shot = 0; traces_read_in = 0; ixmin = nxv-1; ixmax = 0; iymin = nxv-1; iymax = 0; t1 = wallclock_time(); t_init += t1-t2; fseek(shot_file, 0, SEEK_SET); read_FFT_DataFile(shot_file, rec_field, shot_area, nfft, nlw, freq_index[0], &traces_read_in, &traces_shot, &ixmin, &ixmax, &iymin, &iymax, &sx, &sy, conjgs, verb_root); t2 = wallclock_time(); t_io += t2-t1; if (verb_root) fprintf(stderr," time to initialize migration : %.3f s.\n", t1-t0); /* Loop over input traces */ is = 0; while (one_shot) { t1 = wallclock_time(); if (verb_root) { fprintf(stderr,"\n EXTRAPOLATION INFORMATION\n"); fprintf(stderr," source position (x,y) : %.2f, %.2f\n", sx*scl, sy*scl); fprintf(stderr," number of traces in shot : %d\n", traces_shot); fprintf(stderr," traces done = %d to do %d\n", traces_read_in-traces_shot, ntraces-traces_read_in+traces_shot); fprintf(stderr," shot region is x:%d-%d y:%d-%d\n", ixmin, ixmax, iymin, iymax); } /* determine aperture to be extrapolated */ if (area>0) { ixmin = MAX(0,ixmin-area); ixmax = MIN(nxv-1,ixmax+area); iymin = MAX(0,iymin-area); iymax = MIN(nyv-1,iymax+area); } else { ixmin = 0; iymin = 0; ixmax = nxv-1; iymax = nyv-1; } nx = ixmax-ixmin+1; ny = iymax-iymin+1; shot_area.ixmin = ixmin; shot_area.ixmax = ixmax; shot_area.iymin = iymin; shot_area.iymax = iymax; shot_area.dx = dxv; shot_area.dy = dyv; shot_area.dz = dzv; shot_area.nx = nxv; shot_area.ny = nyv; shot_area.sxy = nxy; if (verb_root) { fprintf(stderr," work area is x:%d-%d (%d) y:%d-%d (%d)\n", ixmin, ixmax, nx, iymin, iymax, ny); } t2 = wallclock_time(); t_init += t2-t1; /* write beam for depth=0 */ if (beam) { scale = 1.0/(float)(nw); for (iw=0; iw<nlw; iw++) { rec = (complex*) (rec_field + iw*nxy); for (ix = 0; ix < nxy; ix++) { beams[ix] += sqrt(rec[ix].r*rec[ix].r+rec[ix].i*rec[ix].i)*scale; } } t1 = wallclock_time(); t_init += t1-t2; #ifdef MPI MPI_Reduce(beams, tot_beam, nxy, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD); #else tot_beam = beams; #endif t2 = wallclock_time(); t_comm += t2-t1; /* write image to output file */ if (pe == root_pe) { write_ImageFile(beam_file, tot_beam, shot_area, is, 0, beam_su, verbose); } t1 = wallclock_time(); t_io += t1-t2; } /* Start of depth loop */ for (d=0; d<ndepth; d+=dstep) { t1 = wallclock_time(); id1 = d; id2 = MIN(id1+dstep, ndepth); nel = (id2-id1)*nxy; /* Read dstep depth slices */ for (id=id1,i=0; id<id2; id++,i++) { readVelocitySlice(vel_file, &velocity[i*nxy], id, nyv, nxv); } t2 = wallclock_time(); t_io += t2-t1; if (verb_root > 1) { fprintf(stderr," extrapolating from depth level "); fprintf(stderr,"%d (%.2f) to %d (%.2f) \n", id1, zvmin+dzv*id1, id2, zvmin+dzv*id2); } if (beam) memset(&beams[0], 0, nxy*dstep*sizeof(float)); for (iw=0; iw<nlw; iw++) { om = freq_index[iw]*dw; rec = (complex*) (rec_field + iw*nxy); for (id=id1,i=0; id<id2; id++,i++) { /* Extrapolation */ xwExtr3d(rec, &velocity[i*nxy], vmin, oplx, oply, order, McC, om, nterms, filter_inc, ntap, tap_opt, &shot_area, mode, method); if (beam) { for (ix = 0; ix < nxy; ix++) { beams[i*nxy+ix] += sqrt(rec[ix].r*rec[ix].r+rec[ix].i*rec[ix].i)*scale; } } } /* end of depth loop */ } /* end of frequency loop */ t1 = wallclock_time(); t_migr += t1-t2; if (beam) { #ifdef MPI MPI_Reduce(beams, tot_beam, dstep*nxy, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD); #else tot_beam = beams; #endif t3 = wallclock_time(); t_comm += t3-t1; /* write beam to output file */ if (pe == root_pe) { for (id=id1,i=0; id<id2; id++,i++) { write_ImageFile(beam_file, &tot_beam[i*nxy], shot_area, is, id, beam_su, verbose); } } t2 = wallclock_time(); t_io += t2-t3; } } /* end of outer (dstep) depth loop */ t2 = wallclock_time(); /* communicate data from all PE's to root_pe */ #ifdef MPI fflush(stderr); if (pe == root_pe) { displacements[0] = 0; recvcounts[0] = nlw*nxy*2; for( ipe=1; ipe<npes; ipe++ ) { recvcounts[ipe] = nlwcounts[ipe]*nxy*2; displacements[ipe] = displacements[ipe-1]+recvcounts[ipe-1]; } } MPI_Gatherv(rec_field, nxy*nlw*2, MPI_FLOAT, gath_rec_field, recvcounts, displacements, MPI_FLOAT, root_pe, MPI_COMM_WORLD); if (pe == root_pe) { rec_all = gath_rec_field; } #else rec_all = rec_field; #endif t1 = wallclock_time(); t_comm += t1-t2; if (pe == root_pe) { /* Write modelling result to output file */ if (verb_root) fprintf(stderr," End of depth loop, writing data.\n"); if (is == 0) out_file = fopen( file_out, "w+" ); else out_file = fopen( file_out, "a" ); assert( out_file ); write_FFT_DataFile(out_file, rec_all, shot_area, (is+1), nt, nfft, nw, nw_low, dt, out_su, conjg, verb_root); fclose(out_file); } /* Read next shot record */ if (traces_read_in == ntraces) { one_shot = 0; } else { read_FFT_DataFile(shot_file, rec_field, shot_area, nfft, nlw, freq_index[0], &traces_read_in, &traces_shot, &ixmin, &ixmax, &iymin, &iymax, &sx, &sy, conjgs, verb_root); } is++; t2 = wallclock_time(); t_io += t2-t1; if (verb_root) { fprintf(stderr," subtime for extrapolation : %.3f s.\n", t_migr); fprintf(stderr," subtime for io : %.3f s.\n", t_io); fprintf(stderr," subtime for communication : %.3f s.\n\n", t_comm); } } /* end of while loop over input traces */ free(velocity); free(hdr); free(rec_field); fclose(vel_file); if (beam) { if (pe == root_pe) fclose(beam_file); free(beams); #ifdef MPI free(tot_beam); #endif } /* Write total image result to output file */ fclose(shot_file); t2 = wallclock_time(); t_io += t2-t1; /* clean temporary velocity files */ sprintf(sys_call,"rm -rf %s/velocity%d.bin\n",tmp_dir, getpid()); system(sys_call); /* print the timing results */ if (verb_root) { fprintf(stderr,"Time for total job : %.3f s.\n", t2-t0); fprintf(stderr," time for extrapolation : %.3f s.\n", t_migr); fprintf(stderr," time for tables : %.3f s.\n", t_table); fprintf(stderr," time for io : %.3f s.\n", t_io); fprintf(stderr," time for communication : %.3f s.\n", t_comm); fprintf(stderr," time for initialization : %.3f s.\n", t_init); } #ifdef MPI MPI_Barrier(MPI_COMM_WORLD); if (pe == root_pe) free(gath_rec_field); free(nlwcounts); free(recvcounts); free(displacements); MPI_Finalize(); #endif return; }
void kwZoMigr(float *data, int nx, int nt, float dt, float *velmod, int nxm, int nzm, int ixa, int ixb, float fmin, float fmax, float *xrcv, int izrcv, float ox, float dxm, float dz, int ntap, int conjg, int ndepth, float *image, int verbose, float *exrcv, int ndepthex) { int iomin, iomax, iom, ix, d, i, j; int nfreq, optn, nkx, sign, endkx; int ixrcv, ixmin, ixmax, ixo, ixn, ikx; float k, k2, kz2, kx, kx2; float dom, om, c, dkx, df, sr; float *taper, scl, scl2, *pdata; float *trace; complex *ctrace; float t0, t1; complex *cdata, tmp, ez; complex wa, *ctmp, da, *locdat; complex *cexrcv=(complex *) exrcv; /* define some constants */ optn = optncr(nt); nfreq = optn/2 + 1; df = 1.0/(optn*dt); dom = 2.0*M_PI*df; iomin = (int)MIN((fmin*dt*optn), (nfreq-1)); iomin = MAX(iomin, 1); iomax = MIN((int)(fmax*dt*optn), (nfreq-1)); /* transformation of shot record to frequency domain */ trace = (float *)calloc(optn,sizeof(float)); ctrace = (complex *)malloc(optn*sizeof(complex)); cdata = (complex *)calloc(nxm*nfreq, sizeof(complex)); if (conjg) scl = -1.0; else scl = 1.0; sign = -1; for (ix = 0; ix < nx; ix++) { memcpy(trace,&data[ix*nt],nt*sizeof(float)); if (optn > nt) memset( &trace[nt], 0, sizeof(float)*(optn-nt) ); rc1fft(trace,ctrace,optn,sign); ixrcv = NINT((xrcv[ix]-ox)/dxm); if (ixrcv < 0 || ixrcv > nxm-1) { fprintf(stderr,"kwZoMigr: ixrcv %f (%d) outside model\n", xrcv[ix], ixrcv); continue; } for (iom=0; iom<nfreq; iom++) { /* positioning of shot record into velocity model */ cdata[iom*nxm+ixrcv].r = ctrace[iom].r; cdata[iom*nxm+ixrcv].i = ctrace[iom].i*scl; } } /* determine aperture to be calculated */ ixo = nxm; ixn = 0; for (ix = 0; ix < nx; ix++) { ixrcv = NINT((xrcv[ix]-ox)/dxm); if (ixrcv < ixo) ixo = ixrcv; if (ixrcv > ixn) ixn = ixrcv; } ixmin = MAX(0, ixo-ixb-1); ixmax = MIN(ixn+ixa+1, nxm-1); nx = (ixmax-ixmin)+1; if (verbose>=2) { vmess("kwZoMigr: calculation aperture: %.2f (%d) <--> %.2f (%d) (%d positions)", ixmin*dxm+ox, ixmin, ixmax*dxm+ox, ixmax, nx); } /* define some constants */ scl = 2.0/nfreq; scl = 1.0/(dt*dxm*dxm); nkx = optncc(2*ntap+nxm); ntap = (nkx-nxm)/2; scl2 = 1.0/nkx; dkx = 2.0*M_PI/(nkx*dxm); taper = (float *)malloc(ntap*sizeof(float)); for (ix = 0; ix < ntap; ix++) { taper[ix] = exp(-1.0*(pow((0.4*(ntap-ix)/ntap), 2))); } /* calculate image at depth = 0 */ if(izrcv==0 ) { for (ix = ixmin; ix <= ixmax; ix++) { for (iom = iomin; iom <= iomax; iom++) { image[ix*nzm+0] += scl*cdata[iom*nxm+ix].r; } } } t0 = wallclock_time(); locdat = (complex *)malloc(nkx*sizeof(complex)); /* start extrapolation for all frequencies, depths and x-positions */ for (iom = iomin; iom <= iomax; iom++) { memset(locdat,0,nkx*sizeof(complex)); for (ix = ixmin; ix <= ixmax; ix++) { locdat[ntap+ix] = cdata[iom*nxm+ix]; } om = iom*dom; d = izrcv; /* start extrapolation of receiver arrays */ for (; d < ndepth; d++) { /* transform to wavenumber domain */ cc1fft(locdat, nkx, 1); /* Extrapolation of data */ c = 0.0; for (ix = ixmin; ix <= ixmax; ix++) c += velmod[d*nxm+ix]; k = nx*om/c; k2 = k*k; /* kx = 0 */ ez.r = cos(k*dz); ez.i = -sin(k*dz); tmp.r = ez.r*locdat[0].r; tmp.r += ez.i*locdat[0].i; tmp.i = ez.r*locdat[0].i; tmp.i -= ez.i*locdat[0].r; locdat[0] = tmp; /* kx != 0 */ endkx = MIN((int)(k/dkx),nkx/2); for (ikx = 1; ikx <= endkx; ikx++) { kx = ikx*dkx; kx2 = kx*kx; kz2 = k2 - kx2; ez.r = cos(sqrt(kz2)*dz); ez.i = -sin(sqrt(kz2)*dz); tmp.r = ez.r*locdat[ikx].r; tmp.r += ez.i*locdat[ikx].i; tmp.i = ez.r*locdat[ikx].i; tmp.i -= ez.i*locdat[ikx].r; locdat[ikx] = tmp; tmp.r = ez.r*locdat[nkx-ikx].r; tmp.r += ez.i*locdat[nkx-ikx].i; tmp.i = ez.r*locdat[nkx-ikx].i; tmp.i -= ez.i*locdat[nkx-ikx].r; locdat[nkx-ikx] = tmp; } /* transform data back to space domain */ cc1fft(locdat, nkx, -1); for (j = 0; j < nkx; j++) { locdat[j].r *= scl2; locdat[j].i *= scl2; } /* imaging condition */ for (ix = ixmin; ix <= ixmax; ix++) { image[ix*nzm+d+1]+= scl*locdat[ntap+ix].r; } /* save extrapolated field at requested depth */ if (d==ndepthex-1) { if ( cexrcv != NULL ) { for (ix = 0; ix < nxm; ix++) { cexrcv[iom*nxm+ix] = locdat[ntap+ix]; } } } /* taper extrapolated data at edges */ for (j = 0; j < ntap; j++) { locdat[j].r *= taper[j]; locdat[j].i *= taper[j]; locdat[nkx-j-1].r *= taper[j]; locdat[nkx-j-1].i *= taper[j]; } } /* end of depth loop */ } /* end of iom loop */ if(exrcv) wx2xt(cexrcv, exrcv, optn, nxm, nxm, optn); free(locdat); free(cdata); free(taper); t1 = wallclock_time(); vmess("kwZoMigr took: %f seconds", t1-t0); return; }
int main (int argc, char **argv) { FILE *fp_in1, *fp_in2, *fp_out, *fp_chk, *fp_psline1, *fp_psline2; int verbose, shift, k, nx1, nt1, nx2, nt2; int ntmax, nxmax, ret, i, j, jmax, imax, above, check; int size, ntraces, ngath, *maxval, hw, smooth; int tstart, tend, scale, *xrcv; float dt, d2, f1, f2, t0, t1, f1b, f2b, d1, d1b, d2b; float w1, w2, dxrcv; float *tmpdata, *tmpdata2, *costaper; char *file_mute, *file_shot, *file_out; float scl, sclsxgx, sclshot, xmin, xmax, tmax, lmax; segy *hdrs_in1, *hdrs_in2; t0 = wallclock_time(); initargs(argc, argv); requestdoc(1); if(!getparstring("file_mute", &file_mute)) file_mute=NULL; if(!getparstring("file_shot", &file_shot)) file_shot=NULL; if(!getparstring("file_out", &file_out)) file_out=NULL; if(!getparint("ntmax", &ntmax)) ntmax = 1024; if(!getparint("nxmax", &nxmax)) nxmax = 512; if(!getparint("above", &above)) above = 0; if(!getparint("check", &check)) check = 0; if(!getparint("scale", &scale)) scale = 0; if(!getparint("hw", &hw)) hw = 15; if(!getparint("smooth", &smooth)) smooth = 0; if(!getparfloat("w1", &w1)) w1=1.0; if(!getparfloat("w2", &w2)) w2=1.0; if(!getparint("shift", &shift)) shift=0; if(!getparint("verbose", &verbose)) verbose=0; /* Reading input data for file_mute */ if (file_mute != NULL) { ngath = 1; getFileInfo(file_mute, &nt1, &nx1, &ngath, &d1, &d2, &f1, &f2, &xmin, &xmax, &sclsxgx, &ntraces); if (!getparint("ntmax", &ntmax)) ntmax = nt1; if (!getparint("nxmax", &nxmax)) nxmax = nx1; if (verbose>=2 && (ntmax!=nt1 || nxmax!=nx1)) vmess("dimensions overruled: %d x %d",ntmax,nxmax); if(!getparfloat("dt", &dt)) dt=d1; fp_in1 = fopen(file_mute, "r"); if (fp_in1 == NULL) verr("error on opening input file_mute=%s", file_mute); size = ntmax * nxmax; tmpdata = (float *)malloc(size*sizeof(float)); hdrs_in1 = (segy *) calloc(nxmax,sizeof(segy)); nx1 = readData(fp_in1, tmpdata, hdrs_in1, nt1); if (nx1 == 0) { fclose(fp_in1); if (verbose) vmess("end of file_mute data reached"); } if (verbose) { disp_fileinfo(file_mute, nt1, nx1, f1, f2, dt, d2, hdrs_in1); } } /* Reading input data for file_shot */ ngath = 1; getFileInfo(file_shot, &nt2, &nx2, &ngath, &d1b, &d2b, &f1b, &f2b, &xmin, &xmax, &sclshot, &ntraces); if (!getparint("ntmax", &ntmax)) ntmax = nt2; if (!getparint("nxmax", &nxmax)) nxmax = nx2; size = ntmax * nxmax; tmpdata2 = (float *)malloc(size*sizeof(float)); hdrs_in2 = (segy *) calloc(nxmax,sizeof(segy)); if (file_shot != NULL) fp_in2 = fopen(file_shot, "r"); else fp_in2=stdin; if (fp_in2 == NULL) verr("error on opening input file_shot=%s", file_shot); nx2 = readData(fp_in2, tmpdata2, hdrs_in2, nt2); if (nx2 == 0) { fclose(fp_in2); if (verbose) vmess("end of file_shot data reached"); } nt2 = hdrs_in2[0].ns; f1b = hdrs_in2[0].f1; f2b = hdrs_in2[0].f2; d1b = (float)hdrs_in2[0].dt*1e-6; if (verbose) { disp_fileinfo(file_shot, nt2, nx2, f1b, f2b, d1b, d2b, hdrs_in2); } /* file_shot will be used as well to define the mute window */ if (file_mute == NULL) { nx1=nx2; nt1=nt2; dt=d1b; f1=f1b; f2=f2b; tmpdata = tmpdata2; hdrs_in1 = hdrs_in2; } if (verbose) vmess("sampling file_mute=%d, file_shot=%d", nt1, nt2); /*================ initializations ================*/ maxval = (int *)calloc(nx1,sizeof(int)); xrcv = (int *)calloc(nx1,sizeof(int)); if (file_out==NULL) fp_out = stdout; else { fp_out = fopen(file_out, "w+"); if (fp_out==NULL) verr("error on ceating output file"); } if (check!=0){ fp_chk = fopen("check.su", "w+"); if (fp_chk==NULL) verr("error on ceating output file"); fp_psline1 = fopen("pslinepos.asci", "w+"); if (fp_psline1==NULL) verr("error on ceating output file"); fp_psline2 = fopen("pslineneg.asci", "w+"); if (fp_psline2==NULL) verr("error on ceating output file"); } if (smooth) { costaper = (float *)malloc(smooth*sizeof(float)); scl = M_PI/((float)smooth); for (i=0; i<smooth; i++) { costaper[i] = 0.5*(1.0+cos((i+1)*scl)); /* fprintf(stderr,"costaper[%d]=%f\n",i,costaper[i]);*/ } } /*================ loop over all shot records ================*/ k=1; while (nx1 > 0) { if (verbose) vmess("processing input gather %d", k); /*================ loop over all shot records ================*/ /* find consistent (one event) maximum related to maximum value */ /* find global maximum xmax=0.0; for (i = 0; i < nx1; i++) { tmax=0.0; jmax = 0; for (j = 0; j < nt1; j++) { lmax = fabs(tmpdata[i*nt1+j]); if (lmax > tmax) { jmax = j; tmax = lmax; if (lmax > xmax) { imax = i; xmax=lmax; } } } maxval[i] = jmax; } */ /* alternative find maximum at source position */ dxrcv = (hdrs_in1[nx1-1].gx - hdrs_in1[0].gx)*sclsxgx/(float)(nx1-1); imax = NINT(((hdrs_in1[0].sx-hdrs_in1[0].gx)*sclsxgx)/dxrcv); tmax=0.0; jmax = 0; for (j = 0; j < nt1; j++) { lmax = fabs(tmpdata[imax*nt1+j]); if (lmax > tmax) { jmax = j; tmax = lmax; if (lmax > xmax) { xmax=lmax; } } } maxval[imax] = jmax; if (verbose >= 3) vmess("Mute max at src-trace %d is sample %d", imax, maxval[imax]); /* search forward */ for (i = imax+1; i < nx1; i++) { tstart = MAX(0, (maxval[i-1]-hw)); tend = MIN(nt1-1, (maxval[i-1]+hw)); jmax=tstart; tmax=0.0; for(j = tstart; j <= tend; j++) { lmax = fabs(tmpdata[i*nt1+j]); if (lmax > tmax) { jmax = j; tmax = lmax; } } maxval[i] = jmax; } /* search backward */ for (i = imax-1; i >=0; i--) { tstart = MAX(0, (maxval[i+1]-hw)); tend = MIN(nt1-1, (maxval[i+1]+hw)); jmax=tstart; tmax=0.0; for(j = tstart; j <= tend; j++) { lmax = fabs(tmpdata[i*nt1+j]); if (lmax > tmax) { jmax = j; tmax = lmax; } } maxval[i] = jmax; } /* scale with maximum ampltiude */ if (scale==1) { for (i = 0; i < nx2; i++) { lmax = fabs(tmpdata2[i*nt2+maxval[i]]); xrcv[i] = i; for (j = 0; j < nt2; j++) { tmpdata2[i*nt2+j] = tmpdata2[i*nt2+j]/lmax; } } } /*================ apply mute window ================*/ applyMute(tmpdata2, maxval, smooth, above, 1, nx2, nt2, xrcv, nx2, shift); /*================ write result to output file ================*/ ret = writeData(fp_out, tmpdata2, hdrs_in2, nt2, nx2); if (ret < 0 ) verr("error on writing output file."); /* put mute window in file to check correctness of mute */ if (check !=0) { for (i = 0; i < nx1; i++) { jmax = maxval[i]-shift; tmpdata[i*nt1+jmax] = 2*xmax; } if (above==0){ for (i = 0; i < nx1; i++) { jmax = nt2-maxval[i]+shift; tmpdata[i*nt1+jmax] = 2*xmax; } } ret = writeData(fp_chk, tmpdata, hdrs_in1, nt1, nx1); if (ret < 0 ) verr("error on writing check file."); for (i=0; i<nx1; i++) { jmax = maxval[i]-shift; ret = fprintf(fp_psline1, "%.5f %.5f \n",jmax*dt,hdrs_in1[i].gx*sclshot); jmax =-maxval[i]+shift; ret = fprintf(fp_psline2, "%.5f %.5f \n",jmax*dt,hdrs_in1[i].gx*sclshot); } } /*================ Read next record for muting ================*/ if (file_mute != NULL) { nx1 = readData(fp_in1, tmpdata, hdrs_in1, nt1); if (nx1 == 0) { fclose(fp_in1); if (verbose) vmess("end of file_mute data reached"); fclose(fp_in2); if (fp_out!=stdout) fclose(fp_out); if (check!=0) fclose(fp_chk); if (check!=0) { fclose(fp_psline1); fclose(fp_psline2); } break; } nt1 = (int)hdrs_in1[0].ns; if (nt1 > ntmax) verr("n_samples (%d) greater than ntmax", nt1); if (nx1 > nxmax) verr("n_traces (%d) greater than nxmax", nx1); } /*================ Read next shot record(s) ================*/ nx2 = readData(fp_in2, tmpdata2, hdrs_in2, nt2); if (nx2 == 0) { if (verbose) vmess("end of file_shot data reached"); fclose(fp_in2); break; } nt2 = (int)hdrs_in2[0].ns; if (nt2 > ntmax) verr("n_samples (%d) greater than ntmax", nt2); if (nx2 > nxmax) verr("n_traces (%d) greater than nxmax", nx2); if (file_mute == NULL) { nx1=nx2; nt1=nt2; hdrs_in1 = hdrs_in2; tmpdata = tmpdata2; } k++; } t1 = wallclock_time(); if (verbose) vmess("Total CPU-time = %f",t1-t0); return 0; }