From f528715e9ec471f45cd23391ad7280afe3aeb12d Mon Sep 17 00:00:00 2001 From: "joeri.brackenhoff" <joeri.brackenhoff@login0.ogun.local> Date: Wed, 30 Jan 2019 15:50:29 -0300 Subject: [PATCH] 3D --- marchenko3D/Makefile | 12 +- marchenko3D/applyMute3D.c | 115 ++++++ marchenko3D/fmute3D.c | 508 ++++++++++++++++++++++++ marchenko3D/marchenko3D.c | 812 ++++++++++++++++++++++++++++++++++++++ marchenko3D/readData3D.c | 54 +++ marchenko3D/synthesis3D.c | 275 +++++++++++++ marchenko3D/test.c | 214 ---------- 7 files changed, 1770 insertions(+), 220 deletions(-) create mode 100644 marchenko3D/applyMute3D.c create mode 100644 marchenko3D/fmute3D.c create mode 100644 marchenko3D/marchenko3D.c create mode 100644 marchenko3D/readData3D.c create mode 100644 marchenko3D/synthesis3D.c delete mode 100755 marchenko3D/test.c diff --git a/marchenko3D/Makefile b/marchenko3D/Makefile index dd2432e..491a1c0 100644 --- a/marchenko3D/Makefile +++ b/marchenko3D/Makefile @@ -7,7 +7,7 @@ LIBS += -L$L -lgenfft -lm $(LIBSM) #ALL: fmute marchenko marchenko2 -ALL: fmute marchenko test fmute3D +ALL: fmute marchenko marchenko3D fmute3D SRCJ = fmute.c \ getFileInfo.c \ @@ -69,8 +69,8 @@ fmute: $(OBJJ) OBJT = $(SRCT:%.c=%.o) -test: $(OBJT) - $(CC) $(LDFLAGS) $(OPTC) $(CFLAGS) -o test $(OBJT) $(LIBS) +marchenko3D: $(OBJT) + $(CC) $(LDFLAGS) $(OPTC) $(CFLAGS) -o marchenko3D $(OBJT) $(LIBS) OBJH = $(SRCH:%.c=%.o) @@ -90,13 +90,13 @@ fmute3D: $(OBJJ3) install: fmute marchenko test fmute3D cp fmute $B cp marchenko $B - cp test $B + cp marchenko3D $B cp fmute3D $B # cp marchenko2 $B clean: - rm -f core fmute $(OBJJ) marchenko $(OBJH) marchenko2 $(OBJH2) test $(OBJT) fmute3D $(OBJJ3) + rm -f core fmute $(OBJJ) marchenko $(OBJH) marchenko2 $(OBJH2) marchenko3D $(OBJT) fmute3D $(OBJJ3) realclean: clean - rm -f $B/fmute $B/marchenko $B/marchenko2 $B/test $B/fmute3D + rm -f $B/fmute $B/marchenko $B/marchenko2 $B/marchenko3D $B/fmute3D diff --git a/marchenko3D/applyMute3D.c b/marchenko3D/applyMute3D.c new file mode 100644 index 0000000..cc6f86d --- /dev/null +++ b/marchenko3D/applyMute3D.c @@ -0,0 +1,115 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <assert.h> + +#ifndef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif +#ifndef MIN +#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif +#define NINT(x) ((int)((x)>0.0?(x)+0.5:(x)-0.5)) + +void applyMute3D( float *data, int *mute, int smooth, int above, int Nfoc, int nxs, int nt, int *ixpos, int npos, int shift) +{ + int ix, iy, i, j, l, isyn; + float *costaper, scl; + int imute, tmute; + + if (smooth) { + costaper = (float *)malloc(smooth*sizeof(float)); + scl = M_PI/((float)smooth); + for (ix=0; ix<smooth; ix++) { + costaper[ix] = 0.5*(1.0+cos((ix+1)*scl)); + } + } + + for (isyn = 0; isyn < Nfoc; isyn++) { + if (above==1) { + for (i = 0; i < npos; i++) { + imute = ixpos[i]; + tmute = mute[isyn*nxs+imute]; + for (j = 0; j < MAX(0,tmute-shift-smooth); j++) { + data[isyn*nxs*nt+i*nt+j] = 0.0; + } + for (j = MAX(0,tmute-shift-smooth),l=0; j < MAX(0,tmute-shift); j++,l++) { + data[isyn*nxs*nt+i*nt+j] *= costaper[smooth-l-1]; + } + } + } + else if (above==0){ + for (i = 0; i < npos; i++) { + imute = ixpos[i]; + tmute = mute[isyn*nxs+imute]; + if (tmute >= nt/2) { + memset(&data[isyn*nxs*nt+i*nt],0, sizeof(float)*nt); + continue; + } + for (j = MAX(0,tmute-shift),l=0; j < MAX(0,tmute-shift+smooth); j++,l++) { + data[isyn*nxs*nt+i*nt+j] *= costaper[l]; + } + for (j = MAX(0,tmute-shift+smooth)+1; j < MIN(nt,nt+1-tmute+shift-smooth); j++) { + data[isyn*nxs*nt+i*nt+j] = 0.0; + } + for (j = MIN(nt,nt-tmute+shift-smooth),l=0; j < MIN(nt,nt-tmute+shift); j++,l++) { + data[isyn*nxs*nt+i*nt+j] *= costaper[smooth-l-1]; + } + } + } + else if (above==-1){ + for (i = 0; i < npos; i++) { + imute = ixpos[i]; + tmute = mute[isyn*nxs+imute]; + for (j = MAX(0,tmute-shift),l=0; j < MAX(0,tmute-shift+smooth); j++,l++) { + data[isyn*nxs*nt+i*nt+j] *= costaper[l]; + } + for (j = MAX(0,tmute-shift+smooth); j < nt; j++) { + data[isyn*nxs*nt+i*nt+j] = 0.0; + } + } + } + else if (above==4) { //Psi gate which is the inverse of the Theta gate (above=0) + for (i = 0; i < npos; i++) { + imute = ixpos[i]; + tmute = mute[isyn*nxs+imute]; + for (j = MAX(0,tmute-shift-smooth),l=0; j < MAX(0,tmute-shift); j++,l++) { + data[isyn*nxs*nt+i*nt+j] *= costaper[smooth-l-1]; + } + for (j = 0; j < MAX(0,tmute-shift-smooth-1); j++) { + data[isyn*nxs*nt+i*nt+j] = 0.0; + } + for (j = MIN(nt,nt+1-tmute+shift+smooth); j < nt; j++) { + data[isyn*nxs*nt+i*nt+j] = 0.0; + } + for (j = MIN(nt,nt-tmute+shift),l=0; j < MIN(nt,nt-tmute+shift+smooth); j++,l++) { + data[isyn*nxs*nt+i*nt+j] *= costaper[l]; + } + } + } + else if (above==2){//Separates the direct part of the wavefield from the coda + for (i = 0; i < npos; i++) { + imute = ixpos[i]; + tmute = mute[isyn*nxs+imute]; + for (j = 0; j < MAX(0,tmute-shift-smooth); j++) { + data[isyn*nxs*nt+i*nt+j] = 0.0; + } + for (j = MAX(0,tmute-shift-smooth),l=0; j < MAX(0,tmute-shift); j++,l++) { + data[isyn*nxs*nt+i*nt+j] *= costaper[smooth-l-1]; + } + for (j = MAX(0,tmute+shift),l=0; j < MAX(0,tmute+shift+smooth); j++,l++) { + data[isyn*nxs*nt+i*nt+j] *= costaper[l]; + } + for (j = MAX(0,tmute+shift+smooth); j < nt; j++) { + data[isyn*nxs*nt+i*nt+j] = 0.0; + } + } + } + } + + if (smooth) free(costaper); + + return; +} + diff --git a/marchenko3D/fmute3D.c b/marchenko3D/fmute3D.c new file mode 100644 index 0000000..533c7eb --- /dev/null +++ b/marchenko3D/fmute3D.c @@ -0,0 +1,508 @@ +#include "par.h" +#include "segy.h" +#include <time.h> +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include <assert.h> +#include <genfft.h> + +#ifndef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif +#ifndef MIN +#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif +#define NINT(x) ((int)((x)>0.0?(x)+0.5:(x)-0.5)) + +#ifndef COMPLEX +typedef struct _complexStruct { /* complex number */ + float r,i; +} complex; +#endif/* complex */ + +int getFileInfo3D(char *filename, int *n1, int *n2, int *n3, int *ngath, float *d1, float *d2, float *d3, float *f1, float *f2, float *f3, float *sclsxgxsygy, int *nxm); +int readData3D(FILE *fp, float *data, segy *hdrs, int n1); +int writeData(FILE *fp, float *data, segy *hdrs, int n1, int n2); +int disp_fileinfo3D(char *file, int n1, int n2, int n3, float f1, float f2, float f3, float d1, float d2, float d3, segy *hdrs); +void applyMute( float *data, int *mute, int smooth, int above, int Nfoc, int nxs, int nt, int *ixpos, int npos, int shift); +double wallclock_time(void); + +/*********************** self documentation **********************/ +char *sdoc[] = { +" ", +" fmute3D - mute in time domain file_shot along 3D curves of maximum amplitude in file_mute ", +" ", +" fmute3D file_shot= {file_mute=} [optional parameters]", +" ", +" Required parameters: ", +" ", +" file_mute= ................ input file with event that defines the mute line", +" file_shot= ................ input data that is muted", +" ", +" Optional parameters: ", +" ", +" file_out= ................ output file", +" above=0 .................. mute after(0), before(1) or around(2) the maximum times of file_mute", +" .......................... options 4 is the inverse of 0 and -1 the inverse of 1", +" shift=0 .................. number of points above(positive) / below(negative) maximum time for mute", +" check=0 .................. plots muting window on top of file_mute: output file check.su", +" scale=0 .................. scale data by dividing through maximum", +" hw=15 .................... number of time samples to look up and down in next trace for maximum", +" smooth=0 ................. number of points to smooth mute with cosine window", +//" nxmax=512 ................ maximum number of traces in input file", +//" ntmax=1024 ............... maximum number of samples/trace in input file", +" verbose=0 ................ silent option; >0 display info", +" ", +" author : Jan Thorbecke : 2012 (janth@xs4all.nl)", +" author 3D: Joeri Brackenhoff : 2019 (j.a.brackenhoff@tudelft.nl)" +" ", +NULL}; +/**************** end self doc ***********************************/ + +int main (int argc, char **argv) +{ + FILE *fp_in1, *fp_in2, *fp_out, *fp_chk, *fp_psline1, *fp_psline2; + int verbose, shift, k, nx1, ny1, nt1, nx2, ny2, nt2, nxy; + int ntmax, nxmax, nymax, ret, i, j, l, jmax, ixmax, iymax, above, check; + int size, ntraces, ngath, *maxval, hw, smooth; + int tstart, tend, scale, *xrcv; + float dt, dt1, dx1, dy1, ft1, fx1, fy1, t0, t1, dt2, dx2, dy2, ft2, fx2, fy2; + float w1, w2, dxrcv, dyrcv; + 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; + ret = getFileInfo3D(file_mute, &nt1, &nx1, &ny1, &ngath, &dt1, &dx1, &dy1, &ft1, &fx1, &fy1, &sclsxgx, &ntraces); + + if (!getparint("ntmax", &ntmax)) ntmax = nt1; + if (!getparint("nxmax", &nxmax)) nxmax = nx1; + if (!getparint("nymax", &nymax)) nymax = ny1; + if (verbose>=2 && (ntmax!=nt1 || nxmax!=nx1 || nymax!= ny1)) + vmess("dimensions overruled: %d x %d y %d",ntmax,nxmax,nymax); + if(!getparfloat("dt", &dt)) dt=dt1; + + fp_in1 = fopen(file_mute, "r"); + if (fp_in1 == NULL) verr("error on opening input file_mute=%s", file_mute); + + size = ntmax * nxmax *nymax; + tmpdata = (float *)malloc(size*sizeof(float)); + hdrs_in1 = (segy *)calloc(nxmax*nymax,sizeof(segy)); + + nx1,ny1 = readData3D(fp_in1, tmpdata, hdrs_in1, nt1); + nxy = nx1*ny1; + if (nxy == 0) { + fclose(fp_in1); + if (verbose) vmess("end of file_mute data reached"); + } + + if (verbose) { + disp_fileinfo3D(file_mute, nt1, nx1, ny1, ft1, fx1, fy1, dt, dx1, dy1, hdrs_in1); + } + } + +/* Reading input data for file_shot */ + + ngath = 1; + ret = getFileInfo3D(file_shot, &nt2, &nx2, &ny2, &ngath, &dt2, &dx2, &dy2, &ft2, &fx2, &fy2, &sclshot, &ntraces); + + if (!getparint("ntmax", &ntmax)) ntmax = nt2; + if (!getparint("nxmax", &nxmax)) nxmax = nx2; + if (!getparint("nymax", &nymax)) nymax = ny2; + + size = ntmax * nxmax * nymax; + tmpdata2 = (float *)malloc(size*sizeof(float)); + hdrs_in2 = (segy *)calloc(nxmax*nymax,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,ny2 = readData3D(fp_in2, tmpdata2, hdrs_in2, nt2); + nxy = nx2*ny2; + if (nxy == 0) { + fclose(fp_in2); + if (verbose) vmess("end of file_shot data reached"); + } + nt2 = hdrs_in2[0].ns; + ft2 = hdrs_in2[0].f1; + fx2 = hdrs_in2[0].f2; + dt2 = (float)hdrs_in2[0].dt*1e-6; + + if (verbose) { + disp_fileinfo3D(file_shot, nt2, nx2, ny2, ft2, fx2, fy2, dt2, dx2, dy2, hdrs_in2); + } + + /* file_shot will be used as well to define the mute window */ + if (file_mute == NULL) { + nx1=nx2; + nt1=nt2; + ny1=ny2; + dt=dt2; + ft1=ft2; + fx1=fx2; + fy1=fy2; + tmpdata = tmpdata2; + hdrs_in1 = hdrs_in2; + sclsxgx = sclshot; + } + + if (verbose) vmess("sampling file_mute=%d, file_shot=%d", nt1, nt2); + +/*================ initializations ================*/ + + nxy = nx1*ny1; + maxval = (int *)calloc(nxy,sizeof(int)); + xrcv = (int *)calloc(nxy,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 (nxy > 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[nxy-1].gx - hdrs_in1[0].gx)*sclsxgx/(float)(nx1-1); + dyrcv = (hdrs_in1[nxy-1].gy - hdrs_in1[0].gy)*sclsxgx/(float)(ny1-1); + ixmax = NINT(((hdrs_in1[0].sx-hdrs_in1[0].gx)*sclsxgx)/dxrcv); + iymax = NINT(((hdrs_in1[0].sy-hdrs_in1[0].gy)*sclsxgx)/dxrcv); + if (iymax > ny1-1) { + vmess("source of y is past array, snapping to nearest y"); + iymax = ny1-1; + } + if (iymax < 0) { + vmess("source of y is before array, snapping to nearest y"); + iymax = 0; + } + if (ixmax > nx1-1) { + vmess("source of x is past array, snapping to nearest x"); + ixmax = nx1-1; + } + if (ixmax < 0) { + vmess("source of x is before array, snapping to nearest x"); + ixmax = 0; + } + tmax=0.0; + jmax = 0; + xmax=0.0; + for (j = 0; j < nt1; j++) { + lmax = fabs(tmpdata[iymax*nx1*nt1+ixmax*nt1+j]); + if (lmax > tmax) { + jmax = j; + tmax = lmax; + if (lmax > xmax) { + xmax=lmax; + } + } + } + maxval[iymax*nx1+ixmax] = jmax; + if (verbose >= 3) vmess("Mute max at src-trace x=%d y=%d is sample %d", ixmax, iymax, maxval[iymax*nx1+ixmax]); + + /* search forward in x-trace direction from maximum in file */ + for (i = ixmax+1; i < nx1; i++) { + tstart = MAX(0, (maxval[iymax*nx1+i-1]-hw)); + tend = MIN(nt1-1, (maxval[iymax*nx1+i-1]+hw)); + jmax=tstart; + tmax=0.0; + for(j = tstart; j <= tend; j++) { + lmax = fabs(tmpdata[iymax*nx1*nt1+i*nt1+j]); + if (lmax > tmax) { + jmax = j; + tmax = lmax; + } + } + maxval[iymax*nx1+i] = jmax; + } + /* search backward in x-trace direction from maximum in file */ + for (i = ixmax-1; i >=0; i--) { + tstart = MAX(0, (maxval[iymax*nx1+i+1]-hw)); + tend = MIN(nt1-1, (maxval[iymax*nx1+i+1]+hw)); + jmax=tstart; + tmax=0.0; + for(j = tstart; j <= tend; j++) { + lmax = fabs(tmpdata[iymax*nx1*nt1+i*nt1+j]); + if (lmax > tmax) { + jmax = j; + tmax = lmax; + } + } + maxval[iymax*nx1+i] = jmax; + } + + /* search forward in y-trace direction from maximum in file */ + for (i = iymax+1; i < ny1; i++) { + tmax=0.0; + jmax = 0; + for (j = 0; j < nt1; j++) { + lmax = fabs(tmpdata[i*nx1*nt1+ixmax*nt1+j]); + if (lmax > tmax) { + jmax = j; + tmax = lmax; + } + } + maxval[i*nx1+ixmax] = jmax; + if (verbose >= 8) vmess("Mute max at src-trace x=%d y=%d is sample %d", ixmax, i, maxval[i*nx1+ixmax]); + /* search forward in x-trace direction from maximum in file */ + for (l = ixmax+1; l < nx1; l++) { + tstart = MAX(0, (maxval[i*nx1+l-1]-hw)); + tend = MIN(nt1-1, (maxval[i*nx1+l-1]+hw)); + jmax=tstart; + tmax=0.0; + for(j = tstart; j <= tend; j++) { + lmax = fabs(tmpdata[i*nx1*nt1+l*nt1+j]); + if (lmax > tmax) { + jmax = j; + tmax = lmax; + } + } + maxval[i*nx1+l] = jmax; + } + /* search backward in x-trace direction from maximum in file */ + for (l = ixmax-1; l >=0; l--) { + tstart = MAX(0, (maxval[i*nx1+l+1]-hw)); + tend = MIN(nt1-1, (maxval[i*nx1+l+1]+hw)); + jmax=tstart; + tmax=0.0; + for(j = tstart; j <= tend; j++) { + lmax = fabs(tmpdata[i*nx1*nt1+l*nt1+j]); + if (lmax > tmax) { + jmax = j; + tmax = lmax; + } + } + maxval[i*nx1+l] = jmax; + } + } + + /* search backward in y-trace direction from maximum in file */ + for (i = iymax-1; i >= 0; i--) { + tmax=0.0; + jmax = 0; + for (j = 0; j < nt1; j++) { + lmax = fabs(tmpdata[i*nx1*nt1+ixmax*nt1+j]); + if (lmax > tmax) { + jmax = j; + tmax = lmax; + } + } + maxval[i*nx1+ixmax] = jmax; + if (verbose >= 8) vmess("Mute max at src-trace x=%d y=%d is sample %d", ixmax, i, maxval[i*nx1+ixmax]); + /* search forward in x-trace direction from maximum in file */ + for (l = ixmax+1; l < nx1; l++) { + tstart = MAX(0, (maxval[i*nx1+l-1]-hw)); + tend = MIN(nt1-1, (maxval[i*nx1+l-1]+hw)); + jmax=tstart; + tmax=0.0; + for(j = tstart; j <= tend; j++) { + lmax = fabs(tmpdata[i*nx1*nt1+l*nt1+j]); + if (lmax > tmax) { + jmax = j; + tmax = lmax; + } + } + maxval[i*nx1+l] = jmax; + } + /* search backward in x-trace direction from maximum in file */ + for (l = ixmax-1; l >=0; l--) { + tstart = MAX(0, (maxval[i*nx1+l+1]-hw)); + tend = MIN(nt1-1, (maxval[i*nx1+l+1]+hw)); + jmax=tstart; + tmax=0.0; + for(j = tstart; j <= tend; j++) { + lmax = fabs(tmpdata[i*nx1*nt1+l*nt1+j]); + if (lmax > tmax) { + jmax = j; + tmax = lmax; + } + } + maxval[i*nx1+l] = jmax; + } + } + +/* scale with maximum ampltiude */ + + if (scale==1) { + for (l = 0; l < ny2; l++) { + for (i = 0; i < nx2; i++) { + lmax = fabs(tmpdata2[l*nx2*nt2+i*nt2+maxval[i]]); + for (j = 0; j < nt2; j++) { + tmpdata2[l*nx2*nt2+i*nt2+j] = tmpdata2[l*nx2*nt2+i*nt2+j]/lmax; + } + } + } + } + + for (l = 0; l < ny2; l++) { + for (i = 0; i < nx2; i++) { + xrcv[l*nx2+i] = l*nx2+i; + } + } + +/*================ apply mute window ================*/ + + applyMute(tmpdata2, maxval, smooth, above, 1, nx2*ny2, nt2, xrcv, nx2*ny2, shift); + +/*================ write result to output file ================*/ + + ret = writeData(fp_out, tmpdata2, hdrs_in2, nt2, nx2*ny2); + if (ret < 0 ) verr("error on writing output file."); + + /* put mute window in file to check correctness of mute */ + if (check !=0) { + for (l=0; l<ny1; l++) { + for (i = 0; i < nx1; i++) { + jmax = maxval[l*nx1+i]-shift; + tmpdata[l*nx1*nt1+i*nt1+jmax] = 2*xmax; + } + } + if (above==0){ + for (l=0; l<ny1; l++) { + for (i = 0; i < nx1; i++) { + jmax = nt2-maxval[l*nx1+i]+shift; + tmpdata[l*nx1*nt1+i*nt1+jmax] = 2*xmax; + } + } + } + ret = writeData(fp_chk, tmpdata, hdrs_in1, nt1, nx1*ny1); + if (ret < 0 ) verr("error on writing check file."); + for (l=0; l<ny1; l++) { + for (i=0; i<nx1; i++) { + jmax = maxval[l*nx1+i]-shift; + ret = fprintf(fp_psline1, "%.5f %.5f \n",jmax*dt,hdrs_in1[l*nx1+i].gx*sclshot,hdrs_in1[l*nx1+i].gy*sclshot); + jmax =-maxval[l*nx1+i]+shift; + ret = fprintf(fp_psline2, "%.5f %.5f \n",jmax*dt,hdrs_in1[l*nx1+i].gx*sclshot,hdrs_in1[l*nx1+i].gy*sclshot); + } + } + } + +/*================ Read next record for muting ================*/ + + if (file_mute != NULL) { + nx1, ny1 = readData3D(fp_in1, tmpdata, hdrs_in1, nt1); + nxy = nx1*ny1; + if (nxy == 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); + if (ny1 > nymax) verr("n_traces (%d) greater than nymax", ny1); + if (verbose) { + disp_fileinfo3D(file_mute, nt1, nx1, ny1, ft1, fx1, fy1, dt, dx1, dy1, hdrs_in1); + } + } + +/*================ Read next shot record(s) ================*/ + + nx2,ny2 = readData3D(fp_in2, tmpdata2, hdrs_in2, nt2); + nxy = nx2*ny2; + if (nxy == 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 (ny2 > nymax) verr("n_traces (%d) greater than nymax", ny2); + if (verbose) { + disp_fileinfo3D(file_shot, nt2, nx2, ny2, ft2, fx2, fy2, dt, dx2, dy2, hdrs_in2); + } + + if (file_mute == NULL) { + nx1=nx2; + ny1=ny2; + nt1=nt2; + hdrs_in1 = hdrs_in2; + tmpdata = tmpdata2; + } + + k++; + } + + t1 = wallclock_time(); + if (verbose) vmess("Total CPU-time = %f",t1-t0); + + + return 0; +} \ No newline at end of file diff --git a/marchenko3D/marchenko3D.c b/marchenko3D/marchenko3D.c new file mode 100644 index 0000000..7323516 --- /dev/null +++ b/marchenko3D/marchenko3D.c @@ -0,0 +1,812 @@ +/* + * Copyright (c) 2017 by the Society of Exploration Geophysicists. + * For more information, go to http://software.seg.org/2017/00XX . + * You must read and accept usage terms at: + * http://software.seg.org/disclaimer.txt before use. + */ + +#include "par.h" +#include "segy.h" +#include <time.h> +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include <assert.h> +#include <genfft.h> + +int omp_get_max_threads(void); +int omp_get_num_threads(void); +void omp_set_num_threads(int num_threads); + +#ifndef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif +#ifndef MIN +#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif +#define NINT(x) ((int)((x)>0.0?(x)+0.5:(x)-0.5)) + + + +#ifndef COMPLEX +typedef struct _complexStruct { /* complex number */ + float r,i; +} complex; +#endif/* complex */ + +int readShotData3D(char *filename, float *xrcv, float *yrcv, float *xsrc, float *ysrc, float *zsrc, int *xnx, complex *cdata, int nw, int nw_low, int nshots, int nx, int ny, int ntfft, int mode, float scale, int verbose); +int readTinvData3D(char *filename, float *xrcv, float *yrcv, float *xsrc, float *ysrc, float *zsrc, int *xnx, int Nfoc, int nx, int ny, int ntfft, int mode, int *maxval, float *tinv, int hw, int verbose); +int writeDataIter(char *file_iter, float *data, segy *hdrs, int n1, int n2, float d2, float f2, int n2out, int Nfoc, float *xsyn, +float *zsyn, int *ixpos, int npos, int iter); +int unique_elements(float *arr, int len); + +void name_ext(char *filename, char *extension); + +void applyMute(float *data, int *mute, int smooth, int above, int Nfoc, int nxs, int nt, int *xrcvsyn, int npos, int shift); + +int getFileInfo3D(char *filename, int *n1, int *n2, int *n3, int *ngath, float *d1, float *d2, float *d3, float *f1, float *f2, float *f3, float *sclsxgxsygy, int *nxm); +int readData(FILE *fp, float *data, segy *hdrs, int n1); +int writeData(FILE *fp, float *data, segy *hdrs, int n1, int n2); +int disp_fileinfo3D(char *file, int n1, int n2, int n3, float f1, float f2, float f3, float d1, float d2, float d3, segy *hdrs); +double wallclock_time(void); + +void synthesisPositions3D(int nx, int ny, int nxs, int nys, int Nfoc, float *xrcv, float *yrcv, float *xsrc, float *ysrc, int *xnx, float fxse, float fyse, float fxsb, float fysb, float dxs, float dys, int nshots, int nxsrc, int nysrc, int *ixpos, int *npos, int reci, int verbose); +void synthesis3D(complex *Refl, complex *Fop, float *Top, float *iRN, int nx, int ny, int nt, int nxs, int nys, int nts, float dt, float *xsyn, float *ysyn, +int Nfoc, float *xrcv, float *yrcv, float *xsrc, float *ysrc, int *xnx, float fxse, float fxsb, float fyse, float fysb, float dxs, float dys, float dxsrc, +float dysrc, float dx, float dy, int ntfft, int nw, int nw_low, int nw_high, int mode, int reci, int nshots, int nxsrc, int nysrc, +int *ixpos, int npos, double *tfft, int *isxcount, int *reci_xsrc, int *reci_xrcv, float *ixmask, int verbose); + +int linearsearch(int *array, size_t N, int value); + +/*********************** self documentation **********************/ +char *sdoc[] = { +" ", +" MARCHENKO - Iterative Green's function and focusing functions retrieval", +" ", +" marchenko file_tinv= file_shot= [optional parameters]", +" ", +" Required parameters: ", +" ", +" file_tinv= ............... direct arrival from focal point: G_d", +" file_shot= ............... Reflection response: R", +" ", +" Optional parameters: ", +" ", +" INTEGRATION ", +" tap=0 .................... lateral taper focusing(1), shot(2) or both(3)", +" ntap=0 ................... number of taper points at boundaries", +" fmin=0 ................... minimum frequency in the Fourier transform", +" fmax=70 .................. maximum frequency in the Fourier transform", +" MARCHENKO ITERATIONS ", +" niter=10 ................. number of iterations", +" MUTE-WINDOW ", +" above=0 .................. mute above(1), around(0) or below(-1) the first travel times of file_tinv", +" shift=12 ................. number of points above(positive) / below(negative) travel time for mute", +" hw=8 ..................... window in time samples to look for maximum in next trace", +" smooth=5 ................. number of points to smooth mute with cosine window", +" REFLECTION RESPONSE CORRECTION ", +" scale=2 .................. scale factor of R for summation of Ni with G_d", +" pad=0 .................... amount of samples to pad the reflection series", +" reci=0 ................... 1; add receivers as shots 2; only use receivers as shot positions", +" countmin=0 ............... 0.3*nxrcv; minumum number of reciprocal traces for a contribution", +" OUTPUT DEFINITION ", +" file_green= .............. output file with full Green function(s)", +" file_gplus= .............. output file with G+ ", +" file_gmin= ............... output file with G- ", +" file_f1plus= ............. output file with f1+ ", +" file_f1min= .............. output file with f1- ", +" file_f2= ................. output file with f2 (=p+) ", +" file_pplus= .............. output file with p+ ", +" file_pmin= ............... output file with p- ", +" file_iter= ............... output file with -Ni(-t) for each iteration", +" verbose=0 ................ silent option; >0 displays info", +" ", +" ", +" author : Jan Thorbecke : 2016 (j.w.thorbecke@tudelft.nl)", +" ", +NULL}; +/**************** end self doc ***********************************/ + +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, k, ret, nshots, nxshot, nyshot, Nfoc, nt, nx, ny, nts, nxs, nys, ngath; + int size, n1, n2, n3, ntap, tap, dxi, dyi, ntraces, pad; + int nw, nw_low, nw_high, nfreq, *xnx, *xnxsyn; + int reci, countmin, mode, n2out, n3out, verbose, ntfft; + int iter, niter, tracf, *muteW; + int hw, smooth, above, shift, *ixpos, npos, ix; + int nshots_r, *isxcount, *reci_xsrc, *reci_xrcv; + float fmin, fmax, *tapersh, *tapersy, fxf, fyf, dxf, dyf, *xsrc, *ysrc, *xrcv, *yrcv, *zsyn, *zsrc, *xrcvsyn, *yrcvsyn; + double t0, t1, t2, t3, tsyn, tread, tfft, tcopy, energyNi, energyN0; + float d1, d2, d3, f1, f2, f3, fxsb, fxse, fysb, fyse, ft, fx, fy, *xsyn, *ysyn, dxsrc, dysrc; + float *green, *f2p, *pmin, *G_d, dt, dx, dy, dxs, dys, scl, mem; + float *f1plus, *f1min, *iRN, *Ni, *trace, *Gmin, *Gplus; + float xmin, xmax, ymin, ymax, scale, tsq, Q, f0; + float *ixmask, *iymask; + complex *Refl, *Fop; + char *file_tinv, *file_shot, *file_green, *file_iter; + char *file_f1plus, *file_f1min, *file_gmin, *file_gplus, *file_f2, *file_pmin; + segy *hdrs_out; + + initargs(argc, argv); + requestdoc(1); + + tsyn = tread = tfft = tcopy = 0.0; + t0 = wallclock_time(); + + if (!getparstring("file_shot", &file_shot)) file_shot = NULL; + if (!getparstring("file_tinv", &file_tinv)) file_tinv = 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 (!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("reci", &reci)) reci = 0; + if (!getparfloat("scale", &scale)) scale = 2.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("niter", &niter)) niter = 10; + 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 (reci && ntap) vwarn("tapering influences the reciprocal result"); + +/*================ Reading info about shot and initial operator sizes ================*/ + + ngath = 0; /* setting ngath=0 scans all traces; n2 contains maximum traces/gather */ + ret = getFileInfo3D(file_tinv, &n1, &n2, &n3, &ngath, &d1, &d2, &d3, &f1, &f2, &f3, &scl, &ntraces); + Nfoc = ngath; + nxs = n2; + nys = n3; + nts = n1; + dxs = d2; + dys = d3; + fxsb = f2; + fysb = f3; + + ngath = 0; /* setting ngath=0 scans all traces; nx contains maximum traces/gather */ + ret = getFileInfo3D(file_shot, &nt, &nx, &ny, &ngath, &d1, &dx, &dy, &ft, &fx, &fy, &scl, &ntraces); + nshots = ngath; + assert (nxs*nys >= 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 (!getparint("countmin", &countmin)) countmin = 0.3*nx*ny; + +/*================ Allocating all data arrays ================*/ + + Fop = (complex *)calloc(nys*nxs*nw*Nfoc,sizeof(complex)); + green = (float *)calloc(Nfoc*nys*nxs*ntfft,sizeof(float)); + f2p = (float *)calloc(Nfoc*nys*nxs*ntfft,sizeof(float)); + pmin = (float *)calloc(Nfoc*nys*nxs*ntfft,sizeof(float)); + f1plus = (float *)calloc(Nfoc*nys*nxs*ntfft,sizeof(float)); + f1min = (float *)calloc(Nfoc*nys*nxs*ntfft,sizeof(float)); + iRN = (float *)calloc(Nfoc*nys*nxs*ntfft,sizeof(float)); + Ni = (float *)calloc(Nfoc*nys*nxs*ntfft,sizeof(float)); + G_d = (float *)calloc(Nfoc*nys*nxs*ntfft,sizeof(float)); + muteW = (int *)calloc(Nfoc*nys*nxs,sizeof(int)); + trace = (float *)malloc(ntfft*sizeof(float)); + tapersy = (float *)malloc(nxs*sizeof(float)); + xrcvsyn = (float *)calloc(Nfoc*nys*nxs,sizeof(float)); // x-rcv postions of focal points + yrcvsyn = (float *)calloc(Nfoc*nys*nxs,sizeof(float)); // x-rcv postions of focal points + xsyn = (float *)malloc(Nfoc*sizeof(float)); // x-src position of focal points + ysyn = (float *)malloc(Nfoc*sizeof(float)); // x-src position of focal points + zsyn = (float *)malloc(Nfoc*sizeof(float)); // z-src position of focal points + xnxsyn = (int *)calloc(Nfoc,sizeof(int)); // number of traces per focal point + ixpos = (int *)calloc(nys*nxs,sizeof(int)); // x-position of source of shot in G_d domain (nxs*nys with dxs, dys) + + Refl = (complex *)malloc(nw*ny*nx*nshots*sizeof(complex)); + tapersh = (float *)malloc(nx*sizeof(float)); + xrcv = (float *)calloc(nshots*ny*nx,sizeof(float)); // x-rcv postions of shots + yrcv = (float *)calloc(nshots*ny*nx,sizeof(float)); // x-rcv postions of shots + xsrc = (float *)calloc(nshots,sizeof(float)); //x-src position of shots + ysrc = (float *)calloc(nshots,sizeof(float)); //x-src position of shots + zsrc = (float *)calloc(nshots,sizeof(float)); // z-src position of shots + xnx = (int *)calloc(nshots,sizeof(int)); // number of traces per shot + + if (reci!=0) { + reci_xsrc = (int *)malloc((nxs*nxs*nys*nys)*sizeof(int)); + reci_xrcv = (int *)malloc((nxs*nxs*nys*nys)*sizeof(int)); + isxcount = (int *)calloc(nxs*nys,sizeof(int)); + ixmask = (float *)calloc(nxs*nys,sizeof(float)); + } + +/*================ Read and define mute window based on focusing operator(s) ================*/ +/* G_d = p_0^+ = G_d (-t) ~ Tinv */ + + mode=-1; /* apply complex conjugate to read in data */ + readTinvData3D(file_tinv, xrcvsyn, yrcvsyn, xsyn, ysyn, zsyn, xnxsyn, Nfoc, + nxs, nys, 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 < Nfoc; l++) { + for (k = 0; k < nys; k++) { + for (i = 0; i < nxs; i++) { + for (j = 0; j < nts; j++) { + G_d[l*nys*nxs*nts+k*nxs*nts+i*nts+j] *= tapersy[i]; + } + } + } + } + } + + /* check consistency of header values */ + if (xrcvsyn[0] != 0 || xrcvsyn[1] != 0 ) fxsb = xrcvsyn[0]; + if (yrcvsyn[0] != 0 || yrcvsyn[nys*nxs-1] != 0 ) fysb = yrcvsyn[0]; + if (nxs>1) { + fxse = fxsb + (float)(nxs-1)*dxs; + dxf = (xrcvsyn[nys*nxs-1] - xrcvsyn[0])/(float)(nxs-1); + } + else { + fxse = fxsb; + dxs = 1.0; + dx = 1.0; + d2 = 1.0; + dxf = 1.0; + } + if (nys>1) { + fyse = fysb + (float)(nys-1)*dys; + dyf = (yrcvsyn[nys*nxs-1] - yrcvsyn[0])/(float)(nys-1); + } + else { + fyse = fysb; + dys = 1.0; + d3 = 1.0; + dy = 1.0; + dyf = 1.0; + } + if (NINT(dxs*1e3) != NINT(fabs(dxf)*1e3)) { + vmess("dx in hdr.d2 (%.3f) and hdr.gx (%.3f) not equal",d2, dxf); + if (dxf != 0) dxs = fabs(dxf); + vmess("dx in operator => %f", dxs); + } + if (NINT(dys*1e3) != NINT(fabs(dyf)*1e3)) { + vmess("dy in hdr.d3 (%.3f) and hdr.gy (%.3f) not equal",d3, dyf); + if (dyf != 0) dys = fabs(dyf); + vmess("dy in operator => %f", dys); + } + +/*================ Reading shot records ================*/ + + mode=1; + readShotData3D(file_shot, xrcv, yrcv, xsrc, ysrc, zsrc, xnx, Refl, nw, + nw_low, nshots, nx, ny, ntfft, mode, scale, 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 (k = 0; k < ny; k++) { + for (i = 0; i < nx; i++) { + Refl[l*nx*ny*nw+j*nx*ny+k*nx+i].r *= tapersh[i]; + Refl[l*nx*ny*nw+j*nx*ny+k*nx+i].i *= tapersh[i]; + } + } + } + } + } + free(tapersh); + + /* check consistency of header values */ + nxshot = unique_elements(xsrc,nshots); + nyshot = nshots/nxshot; + + fxf = xsrc[0]; + if (nx > 1) dxf = (xrcv[ny*nx-1] - xrcv[0])/(float)(nx-1); + else dxf = d2; + if (NINT(dx*1e3) != NINT(fabs(dxf)*1e3)) { + vmess("dx in hdr.d2 (%.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); + } + fyf = ysrc[0]; + if (ny > 1) dyf = (yrcv[ny*nx-1] - yrcv[0])/(float)(ny-1); + else dyf = d3; + if (NINT(dy*1e3) != NINT(fabs(dyf)*1e3)) { + vmess("dy in hdr.d3 (%.3f) and hdr.gy (%.3f) not equal",dy, dyf); + if (dyf != 0) dy = fabs(dyf); + else verr("gy hdrs not set"); + vmess("dy used => %f", dy); + } + + dxsrc = (float)xsrc[1] - xsrc[0]; + if (dxsrc == 0) { + vwarn("sx hdrs are not filled in!!"); + dxsrc = dx; + } + dysrc = (float)ysrc[nxshot-1] - ysrc[0]; + if (dysrc == 0) { + vwarn("sy hdrs are not filled in!!"); + dysrc = dy; + } + +/*================ Check the size of the files ================*/ + + if (NINT(dxsrc/dx)*dx != NINT(dxsrc)) { + vwarn("x: source (%.2f) and receiver step (%.2f) don't match",dxsrc,dx); + if (reci == 2) vwarn("x: step used from operator (%.2f) ",dxs); + } + if (NINT(dysrc/dy)*dy != NINT(dysrc)) { + vwarn("y: source (%.2f) and receiver step (%.2f) don't match",dysrc,dy); + if (reci == 2) vwarn("y: step used from operator (%.2f) ",dys); + } + dxi = NINT(dxf/dxs); + if ((NINT(dxi*dxs) != NINT(dxf)) && verbose) + vwarn("dx in receiver (%.2f) and operator (%.2f) don't match",dx,dxs); + dyi = NINT(dyf/dys); + if ((NINT(dyi*dys) != NINT(dyf)) && verbose) + vwarn("dy in receiver (%.2f) and operator (%.2f) don't match",dy,dys); + 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", Nfoc); + vmess("Number of receivers in focusop = x:%d y:%d total:%d", nxs, nys, nxs*nys); + vmess("number of shots = %d", nshots); + vmess("number of receiver/shot = x:%d y:%d total:%d", nx, ny, nx*ny); + vmess("first model position = x:%.2f y:%.2f", fxsb, fysb); + vmess("last model position = x:%.2f y:%.2f", fxse, fyse); + vmess("first source position = x:%.2f y:%.2f", fxf, fyf); + vmess("source distance = x:%.2f y:%.2f", dxsrc, dysrc); + vmess("last source position = x:%.2f y:%.2f", fxf+(nxshot-1)*dxsrc, fyf+(nyshot-1)*dysrc); + vmess("receiver distance = x:%.2f y:%.2f", dxf, dyf); + vmess("direction of increasing traces = x:%d y:%d", dxi, dyi); + vmess("number of time samples (nt,nts) = %d (%d,%d)", ntfft, nt, nts); + vmess("time sampling = %e ", dt); + 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 (reci) { + n2out = nxs; + n3out = nys; + } + else { + n2out = nxshot; + n3out = nyshot; + } + mem = Nfoc*n2out*n3out*ntfft*sizeof(float)/1048576.0; + if (verbose) { + vmess("number of output traces = x:%d y:%d total:%d", n2out, n3out, n2out*n3out); + vmess("number of output samples = %d", ntfft); + vmess("Size of output data/file = %.1f MB", mem); + } + + + /* dry-run of synthesis to get all x-positions calcalated by the integration */ + synthesisPositions3D(nx, ny, nxs, nys, Nfoc, xrcv, yrcv, xsrc, ysrc, xnx, + fxse, fyse, fxsb, fysb, dxs, dys, nshots, nxshot, nyshot, ixpos, &npos, reci, verbose); + if (verbose) { + vmess("synthesisPosistions: nxshot=%d nyshot=%d nshots=%d npos=%d", nxshot, nyshot, nshots, npos); + } + +/*================ set variables for output data ================*/ + + n1 = nts; n2 = n2out; n3 = n3out; + f1 = ft; f2 = xrcvsyn[ixpos[0]]; f3 = yrcvsyn[ixpos[0]]; + d1 = dt; + if (reci == 0) { // distance between sources in R + d2 = dxsrc; + d3 = dysrc; + } + else if (reci == 1) { // distance between traces in G_d + d2 = dxs; + d3 = dys; + } + else if (reci == 2) { // distance between receivers in R + d2 = dx; + d3 = dy; + } + + hdrs_out = (segy *) calloc(n2*n3,sizeof(segy)); + if (hdrs_out == NULL) verr("allocation for hdrs_out"); + size = nys*nxs*nts; + + for (k = 0; k < n3; k++) { + for (i = 0; i < n2; i++) { + hdrs_out[k*n2+i].ns = n1; + hdrs_out[k*n2+i].trid = 1; + hdrs_out[k*n2+i].dt = dt*1000000; + hdrs_out[k*n2+i].f1 = f1; + hdrs_out[k*n2+i].f2 = f2; + hdrs_out[k*n2+i].d1 = d1; + hdrs_out[k*n2+i].d2 = d2; + hdrs_out[k*n2+i].trwf = n2out*n3out; + hdrs_out[k*n2+i].scalco = -1000; + hdrs_out[k*n2+i].gx = NINT(1000*(f2+i*d2)); + hdrs_out[k*n2+i].gy = NINT(1000*(f3+k*d3)); + hdrs_out[k*n2+i].scalel = -1000; + hdrs_out[k*n2+i].tracl = k*n2+i+1; + } + } + t1 = wallclock_time(); + tread = t1-t0; + +/*================ initialization ================*/ + + memcpy(Ni, G_d, Nfoc*nys*nxs*ntfft*sizeof(float)); + for (l = 0; l < Nfoc; l++) { + for (i = 0; i < npos; i++) { + j = 0; + ix = ixpos[i]; /* select the traces that have an output trace after integration */ + f2p[l*nys*nxs*nts+i*nts+j] = G_d[l*nys*nxs*nts+ix*nts+j]; + f1plus[l*nys*nxs*nts+i*nts+j] = G_d[l*nys*nxs*nts+ix*nts+j]; + for (j = 1; j < nts; j++) { + f2p[l*nys*nxs*nts+i*nts+j] = G_d[l*nys*nxs*nts+ix*nts+j]; + f1plus[l*nys*nxs*nts+i*nts+j] = G_d[l*nys*nxs*nts+ix*nts+j]; + } + } + } + +/*================ start Marchenko iterations ================*/ + + for (iter=0; iter<niter; iter++) { + + t2 = wallclock_time(); + +/*================ construction of Ni(-t) = - \int R(x,t) Ni(t) ================*/ + + synthesis3D(Refl, Fop, Ni, iRN, nx, ny, nt, nxs, nys, nts, dt, xsyn, ysyn, + Nfoc, xrcv, yrcv, xsrc, ysrc, xnx, fxse, fxsb, fyse, fysb, dxs, dys, + dxsrc, dysrc, dx, dy, ntfft, nw, nw_low, nw_high, mode, reci, nshots, + nxshot, nyshot, ixpos, npos, &tfft, isxcount, reci_xsrc, reci_xrcv, + ixmask, verbose); + + t3 = wallclock_time(); + tsyn += t3 - t2; + + if (file_iter != NULL) { + writeDataIter(file_iter, iRN, hdrs_out, ntfft, nxs*nys, d2, f2, n2out*n3out, Nfoc, xsyn, zsyn, ixpos, npos, iter); + } + /* N_k(x,t) = -N_(k-1)(x,-t) */ + /* p0^-(x,t) += iRN = (R * T_d^inv)(t) */ + for (l = 0; l < Nfoc; l++) { + energyNi = 0.0; + for (i = 0; i < npos; i++) { + j = 0; + ix = ixpos[i]; + Ni[l*nys*nxs*nts+i*nts+j] = -iRN[l*nys*nxs*nts+ix*nts+j]; + pmin[l*nys*nxs*nts+i*nts+j] += iRN[l*nys*nxs*nts+ix*nts+j]; + energyNi += iRN[l*nys*nxs*nts+ix*nts+j]*iRN[l*nys*nxs*nts+ix*nts+j]; + for (j = 1; j < nts; j++) { + Ni[l*nys*nxs*nts+i*nts+j] = -iRN[l*nys*nxs*nts+ix*nts+nts-j]; + pmin[l*nys*nxs*nts+i*nts+j] += iRN[l*nys*nxs*nts+ix*nts+j]; + energyNi += iRN[l*nys*nxs*nts+ix*nts+j]*iRN[l*nys*nxs*nts+ix*nts+j]; + } + } + if (iter==0) energyN0 = energyNi; + if (verbose >=2) vmess(" - iSyn %d: Ni at iteration %d has energy %e; relative to N0 %e", + l, iter, sqrt(energyNi), sqrt(energyNi/energyN0)); + } + + /* apply mute window based on times of direct arrival (in muteW) */ + applyMute(Ni, muteW, smooth, above, Nfoc, nxs*nys, nts, ixpos, npos, shift); + + /* update f2 */ + for (l = 0; l < Nfoc; l++) { + for (i = 0; i < npos; i++) { + j = 0; + f2p[l*nys*nxs*nts+i*nts+j] += Ni[l*nys*nxs*nts+i*nts+j]; + for (j = 1; j < nts; j++) { + f2p[l*nys*nxs*nts+i*nts+j] += Ni[l*nys*nxs*nts+i*nts+j]; + } + } + } + + if (iter % 2 == 0) { /* even iterations update: => f_1^-(t) */ + for (l = 0; l < Nfoc; l++) { + for (i = 0; i < npos; i++) { + j = 0; + f1min[l*nys*nxs*nts+i*nts+j] -= Ni[l*nys*nxs*nts+i*nts+j]; + for (j = 1; j < nts; j++) { + f1min[l*nys*nxs*nts+i*nts+j] -= Ni[l*nys*nxs*nts+i*nts+nts-j]; + } + } + } + } + else {/* odd iterations update: => f_1^+(t) */ + for (l = 0; l < Nfoc; l++) { + for (i = 0; i < npos; i++) { + j = 0; + f1plus[l*nys*nxs*nts+i*nts+j] += Ni[l*nys*nxs*nts+i*nts+j]; + for (j = 1; j < nts; j++) { + f1plus[l*nys*nxs*nts+i*nts+j] += Ni[l*nys*nxs*nts+i*nts+j]; + } + } + } + } + + t2 = wallclock_time(); + tcopy += t2 - t3; + + if (verbose) vmess("*** Iteration %d finished ***", iter); + + } /* end of iterations */ + + free(Ni); + free(G_d); + + /* compute full Green's function G = int R * f2(t) + f2(-t) = Pplus + Pmin */ + for (l = 0; l < Nfoc; l++) { + for (i = 0; i < npos; i++) { + j = 0; + /* set green to zero if mute-window exceeds nt/2 */ + if (muteW[l*nys*nxs+ixpos[i]] >= nts/2) { + memset(&green[l*nys*nxs*nts+i*nts],0, sizeof(float)*nt); + continue; + } + green[l*nys*nxs*nts+i*nts+j] = f2p[l*nys*nxs*nts+i*nts+j] + pmin[l*nys*nxs*nts+i*nts+j]; + for (j = 1; j < nts; j++) { + green[l*nys*nxs*nts+i*nts+j] = f2p[l*nys*nxs*nts+i*nts+nts-j] + pmin[l*nys*nxs*nts+i*nts+j]; + } + } + } + + /* compute upgoing Green's function G^+,- */ + if (file_gmin != NULL) { + Gmin = (float *)calloc(Nfoc*nys*nxs*ntfft,sizeof(float)); + + /* use f1+ as operator on R in frequency domain */ + mode=1; + synthesis3D(Refl, Fop, f1plus, iRN, nx, ny, nt, nxs, nys, nts, dt, xsyn, ysyn, + Nfoc, xrcv, yrcv, xsrc, ysrc, xnx, fxse, fxsb, fyse, fysb, dxs, dys, + dxsrc, dysrc, dx, dy, ntfft, nw, nw_low, nw_high, mode, reci, nshots, + nxshot, nyshot, ixpos, npos, &tfft, isxcount, reci_xsrc, reci_xrcv, + ixmask, verbose); + + /* compute upgoing Green's G^-,+ */ + for (l = 0; l < Nfoc; l++) { + for (i = 0; i < npos; i++) { + j=0; + ix = ixpos[i]; + Gmin[l*nys*nxs*nts+i*nts+j] = iRN[l*nys*nxs*nts+ix*nts+j] - f1min[l*nys*nxs*nts+i*nts+j]; + for (j = 1; j < nts; j++) { + Gmin[l*nys*nxs*nts+i*nts+j] = iRN[l*nys*nxs*nts+ix*nts+j] - f1min[l*nys*nxs*nts+i*nts+j]; + } + } + } + /* Apply mute with window for Gmin */ + applyMute(Gmin, muteW, smooth, 1, Nfoc, nxs*nys, nts, ixpos, npos, shift); + } /* end if Gmin */ + + /* compute downgoing Green's function G^+,+ */ + if (file_gplus != NULL) { + Gplus = (float *)calloc(Nfoc*nys*nxs*ntfft,sizeof(float)); + + /* use f1-(*) as operator on R in frequency domain */ + mode=-1; + synthesis3D(Refl, Fop, f1min, iRN, nx, ny, nt, nxs, nys, nts, dt, xsyn, ysyn, + Nfoc, xrcv, yrcv, xsrc, ysrc, xnx, fxse, fxsb, fyse, fysb, dxs, dys, + dxsrc, dysrc, dx, dy, ntfft, nw, nw_low, nw_high, mode, reci, nshots, + nxshot, nyshot, ixpos, npos, &tfft, isxcount, reci_xsrc, reci_xrcv, + ixmask, verbose); + + /* compute downgoing Green's G^+,+ */ + for (l = 0; l < Nfoc; l++) { + for (i = 0; i < npos; i++) { + j=0; + ix = ixpos[i]; + Gplus[l*nys*nxs*nts+i*nts+j] = -iRN[l*nys*nxs*nts+ix*nts+j] + f1plus[l*nys*nxs*nts+i*nts+j]; + for (j = 1; j < nts; j++) { + Gplus[l*nys*nxs*nts+i*nts+j] = -iRN[l*nys*nxs*nts+ix*nts+j] + f1plus[l*nys*nxs*nts+i*nts+nts-j]; + } + } + } + } /* end if Gplus */ + + t2 = wallclock_time(); + if (verbose) { + vmess("Total CPU-time marchenko = %.3f", t2-t0); + vmess("with CPU-time synthesis = %.3f", tsyn); + vmess("with CPU-time copy array = %.3f", tcopy); + vmess(" CPU-time fft data = %.3f", tfft); + vmess("and CPU-time read data = %.3f", tread); + } + +/*================ write output files ================*/ + + + fp_out = fopen(file_green, "w+"); + if (fp_out==NULL) verr("error on creating output file %s", file_green); + if (file_gmin != NULL) { + fp_gmin = fopen(file_gmin, "w+"); + if (fp_gmin==NULL) verr("error on creating output file %s", file_gmin); + } + if (file_gplus != NULL) { + fp_gplus = fopen(file_gplus, "w+"); + if (fp_gplus==NULL) verr("error on creating output file %s", file_gplus); + } + if (file_f2 != NULL) { + fp_f2 = fopen(file_f2, "w+"); + if (fp_f2==NULL) verr("error on creating output file %s", file_f2); + } + if (file_pmin != NULL) { + fp_pmin = fopen(file_pmin, "w+"); + if (fp_pmin==NULL) verr("error on creating output file %s", file_pmin); + } + if (file_f1plus != NULL) { + fp_f1plus = fopen(file_f1plus, "w+"); + if (fp_f1plus==NULL) verr("error on creating output file %s", file_f1plus); + } + if (file_f1min != NULL) { + fp_f1min = fopen(file_f1min, "w+"); + if (fp_f1min==NULL) verr("error on creating output file %s", file_f1min); + } + + + tracf = 1; + for (l = 0; l < Nfoc; l++) { + if (reci) { + f2 = fxsb; + f3 = fysb; + } + else { + f2 = fxf; + f3 = fyf; + } + + for (k = 0; k < n3; k++) { + for (i = 0; i < n2; i++) { + hdrs_out[k*n2+i].fldr = l+1; + hdrs_out[k*n2+i].sx = NINT(xsyn[l]*1000); + hdrs_out[k*n2+i].sy = NINT(ysyn[l]*1000); + hdrs_out[k*n2+i].offset = (long)NINT((f2+i*d2) - xsyn[l]); + hdrs_out[k*n2+i].tracf = tracf++; + hdrs_out[k*n2+i].selev = NINT(zsyn[l]*1000); + hdrs_out[k*n2+i].sdepth = NINT(-zsyn[l]*1000); + hdrs_out[k*n2+i].f1 = f1; + } + } + + ret = writeData(fp_out, (float *)&green[l*size], hdrs_out, n1, n2*n3); + if (ret < 0 ) verr("error on writing output file."); + + if (file_gmin != NULL) { + ret = writeData(fp_gmin, (float *)&Gmin[l*size], hdrs_out, n1, n2*n3); + if (ret < 0 ) verr("error on writing output file."); + } + if (file_gplus != NULL) { + ret = writeData(fp_gplus, (float *)&Gplus[l*size], hdrs_out, n1, n2*n3); + if (ret < 0 ) verr("error on writing output file."); + } + if (file_f2 != NULL) { + ret = writeData(fp_f2, (float *)&f2p[l*size], hdrs_out, n1, n2*n3); + if (ret < 0 ) verr("error on writing output file."); + } + if (file_pmin != NULL) { + ret = writeData(fp_pmin, (float *)&pmin[l*size], hdrs_out, n1, n2*n3); + if (ret < 0 ) verr("error on writing output file."); + } + if (file_f1plus != NULL) { + /* rotate to get t=0 in the middle */ + for (i = 0; i < n2*n3; i++) { + hdrs_out[i].f1 = -n1*0.5*dt; + memcpy(&trace[0],&f1plus[l*size+i*nts],nts*sizeof(float)); + for (j = 0; j < n1/2; j++) { + f1plus[l*size+i*nts+n1/2+j] = trace[j]; + } + for (j = n1/2; j < n1; j++) { + f1plus[l*size+i*nts+j-n1/2] = trace[j]; + } + } + ret = writeData(fp_f1plus, (float *)&f1plus[l*size], hdrs_out, n1, n2*n3); + if (ret < 0 ) verr("error on writing output file."); + } + if (file_f1min != NULL) { + /* rotate to get t=0 in the middle */ + for (i = 0; i < n2*n3; i++) { + hdrs_out[i].f1 = -n1*0.5*dt; + memcpy(&trace[0],&f1min[l*size+i*nts],nts*sizeof(float)); + for (j = 0; j < n1/2; j++) { + f1min[l*size+i*nts+n1/2+j] = trace[j]; + } + for (j = n1/2; j < n1; j++) { + f1min[l*size+i*nts+j-n1/2] = trace[j]; + } + } + ret = writeData(fp_f1min, (float *)&f1min[l*size], hdrs_out, n1, n2*n3); + if (ret < 0 ) verr("error on writing output file."); + } + } + ret = fclose(fp_out); + if (file_gplus != NULL) {ret += fclose(fp_gplus);} + if (file_gmin != NULL) {ret += fclose(fp_gmin);} + if (file_f2 != NULL) {ret += fclose(fp_f2);} + if (file_pmin != NULL) {ret += fclose(fp_pmin);} + if (file_f1plus != NULL) {ret += fclose(fp_f1plus);} + if (file_f1min != NULL) {ret += fclose(fp_f1min);} + if (ret < 0) verr("err %d on closing output file",ret); + + if (verbose) { + t1 = wallclock_time(); + vmess("and CPU-time write data = %.3f", t1-t2); + } + +/*================ free memory ================*/ + + free(hdrs_out); + free(tapersy); + + exit(0); +} + +int unique_elements(float *arr, int len) +{ + if (len <= 0) return 0; + int unique = 1; + int outer, inner, is_unique; + + for (outer = 1; outer < len; ++outer) + { + is_unique = 1; + for (inner = 0; is_unique && inner < outer; ++inner) + { + if ((arr[inner] >= arr[outer]-1.0) && (arr[inner] <= arr[outer]+1.0)) is_unique = 0; + } + if (is_unique) ++unique; + } + return unique; +} \ No newline at end of file diff --git a/marchenko3D/readData3D.c b/marchenko3D/readData3D.c new file mode 100644 index 0000000..09b121a --- /dev/null +++ b/marchenko3D/readData3D.c @@ -0,0 +1,54 @@ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "segy.h" + +/** +* reads SU file and returns header and 2D array +* +* AUTHOR: +* Jan Thorbecke (janth@xs4all.nl) +* The Netherlands +**/ + + +int readData3D(FILE *fp, float *data, segy *hdrs, int n1) +{ + size_t nread; + int oneshot, itrace, sx, sy, fldr, gy, nx, ny; + segy hdr; + + oneshot = 1; + itrace = 0; + ny = 1; + + nread = fread(&hdrs[0], 1, TRCBYTES, fp); + if (nread == 0) return 0; /* end of file reached */ + + if (n1==0) n1 = hdrs[0].ns; + sx = hdrs[0].sx; + sy = hdrs[0].sy; + fldr = hdrs[0].fldr; + gy = hdrs[0].gy; + while (oneshot) { + nread = fread(&data[itrace*n1], sizeof(float), n1, fp); + assert (nread == n1); + itrace++; + nread = fread(&hdr, 1, TRCBYTES, fp); + if (nread == 0) break; + assert(nread == TRCBYTES); + if ( (sx != hdr.sx) || (sy != hdr.sy) || (fldr != hdr.fldr)) { /* end of shot record */ + fseek( fp, -TRCBYTES, SEEK_CUR ); + break; + } + if ( (gy != hdr.gy)) { + ny++; + gy = hdr.gy; + } + memcpy(&hdrs[itrace], &hdr, TRCBYTES); + } + nx = itrace/ny; + + return nx, ny; +} diff --git a/marchenko3D/synthesis3D.c b/marchenko3D/synthesis3D.c new file mode 100644 index 0000000..8ab12a9 --- /dev/null +++ b/marchenko3D/synthesis3D.c @@ -0,0 +1,275 @@ +#include "par.h" +#include "segy.h" +#include <time.h> +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include <assert.h> +#include <genfft.h> + +int omp_get_max_threads(void); +int omp_get_num_threads(void); +void omp_set_num_threads(int num_threads); + +#ifndef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif +#ifndef MIN +#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif +#define NINT(x) ((int)((x)>0.0?(x)+0.5:(x)-0.5)) +int compareInt(const void *a, const void *b) +{ return (*(int *)a-*(int *)b); } + +#ifndef COMPLEX +typedef struct _complexStruct { /* complex number */ + float r,i; +} complex; +#endif/* complex */ + +void synthesisPositions3D(int nx, int ny, int nxs, int nys, int Nfoc, float *xrcv, float *yrcv, +float *xsrc, float *ysrc, int *xnx, float fxse, float fyse, float fxsb, float fysb, float dxs, float dys, +int nshots, int nxsrc, int nysrc, int *ixpos, int *npos, int reci, int verbose) +{ + int j, l, ixsrc, iysrc, isrc, k, *count, nxy; + float fxb, fxe, fyb, fye; + + if (fxsb < 0) fxb = 1.001*fxsb; + else fxb = 0.999*fxsb; + if (fysb < 0) fyb = 1.001*fysb; + else fyb = 0.999*fysb; + if (fxse > 0) fxe = 1.001*fxse; + else fxe = 0.999*fxse; + if (fyse > 0) fye = 1.001*fyse; + else fye = 0.999*fyse; + + nxy = nx*ny; + + count = (int *)calloc(nxs*nys,sizeof(int)); // number of traces that contribute to the integration over x + +/*================ SYNTHESIS ================*/ + + for (l = 0; l < 1; l++) { /* assuming all focal operators cover the same lateral area */ +// for (l = 0; l < Nfoc; l++) { + *npos=0; + + if (reci == 0 || reci == 1) { + for (k=0; k<nshots; k++) { + + ixsrc = NINT((xsrc[k] - fxsb)/dxs); + iysrc = NINT((ysrc[k] - fysb)/dys); + isrc = iysrc*nxs + ixsrc; + if (verbose>=3) { + vmess("source position: x=%.2f y=%.2f in operator x=%d y=%d pos=%d", xsrc[k], ysrc[k], ixsrc, iysrc, isrc); + vmess("receiver positions: x:%.2f <--> %.2f y:%.2f <--> %.2f", xrcv[k*nxy+0], xrcv[k*nxy+nxy-1], yrcv[k*nxy+0], yrcv[k*nxy+nxy-1]); + vmess("focal point positions: x:%.2f <--> %.2f y:%.2f <--> %.2f", fxsb, fxse, fysb, fyse); + } + + if ((NINT(xsrc[k]-fxse) > 0) || (NINT(xrcv[k*nxy+nxy-1]-fxse) > 0) || + (NINT(xrcv[k*nxy+nxy-1]-fxsb) < 0) || (NINT(xsrc[k]-fxsb) < 0) || + (NINT(xrcv[k*nxy+0]-fxsb) < 0) || (NINT(xrcv[k*nxy+0]-fxse) > 0) || + (NINT(ysrc[k]-fyse) > 0) || (NINT(yrcv[k*nxy+nxy-1]-fyse) > 0) || + (NINT(yrcv[k*nxy+nxy-1]-fysb) < 0) || (NINT(ysrc[k]-fysb) < 0) || + (NINT(yrcv[k*nxy+0]-fysb) < 0) || (NINT(yrcv[k*nxy+0]-fyse) > 0) ) { + vwarn("source/receiver positions are outside synthesis aperture"); + vmess("xsrc = %.2f xrcv_1 = %.2f xrvc_N = %.2f", xsrc[k], xrcv[k*nxy+0], xrcv[k*nxy+nxy-1]); + vmess("ysrc = %.2f yrcv_1 = %.2f yrvc_N = %.2f", ysrc[k], yrcv[k*nxy+0], yrcv[k*nxy+nxy-1]); + vmess("source position x: %.2f in operator %d", xsrc[k], ixsrc); + vmess("source position y: %.2f in operator %d", ysrc[k], iysrc); + vmess("receiver positions x: %.2f <--> %.2f", xrcv[k*nxy+0], xrcv[k*nxy+nxy-1]); + vmess("receiver positions y: %.2f <--> %.2f", yrcv[k*nxy+0], yrcv[k*nxy+nxy-1]); + vmess("focal point positions x: %.2f <--> %.2f", fxsb, fxse); + vmess("focal point positions y: %.2f <--> %.2f", fysb, fyse); + } + + if ( (xsrc[k] >= fxb) && (xsrc[k] <= fxe) && + (ysrc[k] >= fyb) && (ysrc[k] <= fye) ) { + + j = linearsearch(ixpos, *npos, isrc); + if (j < *npos) { /* the position (at j) is already included */ + count[j] += xnx[k]; + } + else { /* add new postion */ + ixpos[*npos] = isrc; + count[*npos] += xnx[k]; + *npos += 1; + } + // vmess("source position %d is inside synthesis model %f *npos=%d count=%d", k, xsrc[k], *npos, count[*npos]); + } + + } /* end of nshots (k) loop */ + } /* end of reci branch */ + } /* end of Nfoc loop */ + + if (verbose>=4) { + for (j=0; j < *npos; j++) { + vmess("ixpos[%d] = %d count=%d", j, ixpos[j], count[j]); + } + } + free(count); + +/* sort ixpos into increasing values */ + qsort(ixpos, *npos, sizeof(int), compareInt); + + + return; +} + +int linearsearch(int *array, size_t N, int value) +{ + int j; +/* Check is position is already in array */ + j = 0; + while (j < N && value != array[j]) { + j++; + } + return j; +} + +/*================ Convolution and Integration ================*/ + +void synthesis3D(complex *Refl, complex *Fop, float *Top, float *iRN, int nx, int ny, int nt, int nxs, int nys, int nts, float dt, float *xsyn, float *ysyn, +int Nfoc, float *xrcv, float *yrcv, float *xsrc, float *ysrc, int *xnx, float fxse, float fxsb, float fyse, float fysb, float dxs, float dys, float dxsrc, +float dysrc, float dx, float dy, int ntfft, int nw, int nw_low, int nw_high, int mode, int reci, int nshots, int nxsrc, int nysrc, +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, isrc, il, ik, nxy, nxys; + float *rtrace, idxs, idys; + complex *sum, *ctrace; + int npe; + static int first=1, *ircv; + static double t0, t1, t; + + nxy = nx*ny; + nxys = nxs*nys; + + size = nxys*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 (Nfoc) */ + if (npe > Nfoc) { + vmess("Number of OpenMP threads set to %d (was %d)", Nfoc, npe); + omp_set_num_threads(Nfoc); + } +#endif + + t0 = wallclock_time(); + + /* reset output data to zero */ + memset(&iRN[0], 0, Nfoc*nxys*nts*sizeof(float)); + ctrace = (complex *)calloc(ntfft,sizeof(complex)); + + 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*nxys*nw].r, 0, nxys*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*nxys*nw+iw*nxys+ix].r = ctrace[nw_low+iw].r; + Fop[l*nxys*nw+iw*nxys+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*nxys*nw].r, 0, nxys*nw*2*sizeof(float)); + for (i = 0; i < nxys; i++) { + rc1fft(&Top[l*size+i*nts],ctrace,ntfft,-1); + for (iw=0; iw<nw; iw++) { + Fop[l*nxys*nw+iw*nxys+i].r = ctrace[nw_low+iw].r; + Fop[l*nxys*nw+iw*nxys+i].i = mode*ctrace[nw_low+iw].i; + } + } + } + idxs = 1.0/dxs; + idys = 1.0/dys; + ircv = (int *)malloc(nshots*nxy*sizeof(int)); + for (k=0; k<nshots; k++) { + for (i = 0; i < nxy; i++) { + ircv[k*nxy+i] = NINT((yrcv[k*nxy+i]-fysb)*idys)*nx+NINT((xrcv[k*nxy+i]-fxsb)*idxs); + } + } + } + free(ctrace); + t1 = wallclock_time(); + *tfft += t1 - t0; + +/* Loop over total number of shots */ + if (reci == 0 || reci == 1) { + for (k=0; k<nshots; k++) { + if ((xsrc[k] < 0.999*fxsb) || (xsrc[k] > 1.001*fxse) || (ysrc[k] < 0.999*fysb) || (ysrc[k] > 1.001*fyse)) continue; + isrc = NINT((ysrc[k] - fysb)/dys)*nxs+NINT((xsrc[k] - fxsb)/dxs); + inx = xnx[k]; /* number of traces per shot */ + +/*================ SYNTHESIS ================*/ + +#pragma omp parallel default(none) \ + shared(iRN, dx, dy, npe, nw, verbose) \ + shared(Refl, Nfoc, reci, xrcv, xsrc, yrcv, ysrc, xsyn, ysyn) \ + shared(fxsb, fxse, fysb, fyse, nxs, nys, nxys, dxs, dys) \ + shared(nx, ny, nxy, dysrc, dxsrc, inx, k, nfreq, nw_low, nw_high) \ + shared(Fop, size, nts, ntfft, scl, ircv, isrc) \ + 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 < 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 = ircv[k*nxy+i]; + sum[j].r += Refl[k*nw*nxy+m*nxy+i].r*Fop[l*nw*nxys+m*nxys+ix].r - + Refl[k*nw*nxy+m*nxy+i].i*Fop[l*nw*nxys+m*nxys+ix].i; + sum[j].i += Refl[k*nw*nxy+m*nxy+i].i*Fop[l*nw*nxys+m*nxys+ix].r + + Refl[k*nw*nxy+m*nxy+i].r*Fop[l*nw*nxys+m*nxys+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+isrc*nts+j] += rtrace[j]*scl*dx*dy; + + } /* end of parallel Nfoc loop */ + free(sum); + free(rtrace); + +#ifdef _OPENMP +#pragma omp single + npe = omp_get_num_threads(); +#endif +} /* end of parallel region */ + + if (verbose>4) vmess("*** Shot gather %d processed ***", k); + + } /* end of nshots (k) loop */ + } /* end of if reci */ + + t = wallclock_time() - t0; + if (verbose) { + vmess("OMP: parallel region = %f seconds (%d threads)", t, npe); + } + + return; +} \ No newline at end of file diff --git a/marchenko3D/test.c b/marchenko3D/test.c deleted file mode 100755 index 613719b..0000000 --- a/marchenko3D/test.c +++ /dev/null @@ -1,214 +0,0 @@ -#include "par.h" -#include "segy.h" -#include <time.h> -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <assert.h> -#include <genfft.h> - -#ifndef MAX -#define MAX(x,y) ((x) > (y) ? (x) : (y)) -#endif -#ifndef MIN -#define MIN(x,y) ((x) < (y) ? (x) : (y)) -#endif -#define NINT(x) ((int)((x)>0.0?(x)+0.5:(x)-0.5)) - -#ifndef COMPLEX -typedef struct _complexStruct { /* complex number */ - float r,i; -} complex; -#endif/* complex */ - -void cr1fft(complex *cdata, REAL *rdata, int n, int sign); -int getFileInfo3D(char *filename, int *n1, int *n2, int *n3, int *ngath, float *d1, float *d2, float *d3, float *f1, float *f2, float *f3, float *sclsxgxsygy, int *nxm); -int disp_fileinfo3D(char *file, int n1, int n2, int n3, float f1, float f2, float f3, float d1, float d2, float d3, segy *hdrs); -int readShotData3D(char *filename, float *xrcv, float *yrcv, float *xsrc, float *ysrc, float *zsrc, int *xnx, complex *cdata, int nw, int nw_low, int nshots, int nx, int ny, int ntfft, int mode, float scale, int verbose); -int unique_elements(float *arr, int len); -int writeData(FILE *fp, float *data, segy *hdrs, int n1, int n2); -int readTinvData3D(char *filename, float *xrcv, float *yrcv, float *xsrc, float *ysrc, float *zsrc, int *xnx, int Nfoc, int nx, int ny, int ntfft, int mode, int *maxval, float *tinv, int hw, int verbose); -void synthesisPosistions3D(int nx, int ny, int nxs, int nys, int Nfoc, float *xrcv, float *yrcv, float *xsrc, float *ysrc, int *xnx, float fxse, float fyse, float fxsb, float fysb, float dxs, float dys, int nshots, int nxsrc, int nysrc, int *ixpos, int *npos, int reci, int verbose); -void synthesis3D(complex *Refl, complex *Fop, float *Top, float *iRN, int nx, int ny, int nt, int nxs, int nys, int nts, float dt, float *xsyn, float *ysyn, -int Nfoc, float *xrcv, float *yrcv, float *xsrc, float *ysrc, int *xnx, float fxse, float fxsb, float fyse, float fysb, float dxs, float dys, float dxsrc, -float dysrc, float dx, float dy, int ntfft, int nw, int nw_low, int nw_high, int mode, int reci, int nshots, int nxsrc, int nysrc, -int *ixpos, int npos, double *tfft, int *isxcount, int *reci_xsrc, int *reci_xrcv, float *ixmask, int verbose) - -char *sdoc[] = { -" ", -" test 3D - Test 3D functions ", -" ", -"fin=.......................... File name of input", -" ", -" authors : Joeri Brackenhoff (J.A.Brackenhoff@tudelft.nl)", -" : Jan Thorbecke (janth@xs4all.nl)", -NULL}; - -int main (int argc, char **argv) -{ - char *file_shot, *file_out, *file_tinv, *file_shot_out; - FILE *fp_out; - float dts, dxs, dys, fts, fxs, fys, scl, fmin, fmax; - float dtd, dxd, dyd, ftd, fxd, fyd, scld; - float *xrcv, *yrcv, *xsrc, *ysrc, *zsrc; - float *xrcvsyn, *yrcvsyn, *xsyn, *ysyn, *zsyn, *f1d, *iRN; - float fxsb, fysb, fxse, fyse; - complex *Refl; - int nts, nxs, nys, nxys, nshots, ntrs, ret, *xnx, *xnxsyn; - int ntd, nxd, nyd, nxyd, Nfoc, ntrd, *muteW; - int ntfft, nfreq, nw_low, nw_high, nw, mode, verbose; - int i, j, l, it, nxsrc, nysrc, hw, shift, smooth, tracf; - int *ixpos, npos; - segy *hdrs_out, *hdrs_shot; - - initargs(argc, argv); - requestdoc(1); - - if (!getparstring("file_shot", &file_shot)) file_shot = NULL; - if (!getparstring("file_out", &file_out)) file_out = "out.su"; - if (!getparstring("file_shot_out", &file_shot_out)) file_shot_out = "shot_out.su"; - if (!getparstring("file_tinv", &file_tinv)) file_tinv = NULL; - if (!getparfloat("fmin", &fmin)) fmin = 0.0; - if (!getparfloat("fmax", &fmax)) fmax = 70.0; - if (!getparint("hw", &hw)) hw = 15; - if (!getparint("smooth", &smooth)) smooth = 5; - if (!getparint("shift", &shift)) shift = 5; - if (file_shot == NULL) verr("Give me a shot name for the love of God"); - if (file_tinv == NULL) verr("Give me a tinv name for the love of God"); - - nshots=0; - mode=1; - verbose=10; - - ret = getFileInfo3D(file_shot, &nts, &nxs, &nys, &nshots, &dts, &dxs, &dys, &fts, &fxs, &fys, &scl, &ntrs); - vmess("nts=%d nxs=%d nys=%d nshots=%d ntrs=%d",nts,nxs,nys,nshots,ntrs); - vmess("dts=%.5f dxs=%.5f dys=%.5f fts=%.5f fxs=%.5f fys=%.5f scl=%.5f",dts,dxs,dys,fts,fxs,fys,scl); - - ntfft = optncr(nts); - nfreq = ntfft/2+1; - nw_low = (int)MIN((fmin*ntfft*dts), nfreq-1); - nw_low = MAX(nw_low, 1); - nw_high = MIN((int)(fmax*ntfft*dts), nfreq-1); - nw = nw_high - nw_low + 1; - scl = 1.0/((float)ntfft); - - Refl = (complex *)malloc(nw*nxs*nys*nshots*sizeof(complex)); // reflection response in frequency domain - xrcv = (float *)calloc(nshots*nxs*nys,sizeof(float)); // x-rcv postions of shots - xsrc = (float *)calloc(nshots,sizeof(float)); // x-src position of shots - yrcv = (float *)calloc(nshots*nxs*nys,sizeof(float)); // y-rcv postions of shots - ysrc = (float *)calloc(nshots,sizeof(float)); // y-src position of shots - zsrc = (float *)calloc(nshots,sizeof(float)); // z-src position of shots - xnx = (int *)calloc(nshots,sizeof(int)); // number of traces per shot - - readShotData3D(file_shot, xrcv, yrcv, xsrc, ysrc, zsrc, xnx, Refl, nw, nw_low, nshots, nxs, nys, ntfft, mode, scl, verbose); - - for (i=0;i<nshots;i++) { - vmess("xsrc=%.3f ysrc=%.3f zsrc=%.3f xrcv1=%.3f xrcv2=%.3f yrcv1=%.3f yrcv2=%.3f",xsrc[i],ysrc[i],zsrc[i],xrcv[i*nxs*nys],xrcv[(i+1)*nxs*nys-1],yrcv[i*nxs*nys],yrcv[(i+1)*nxs*nys-1]); - } - - nxsrc = unique_elements(xsrc,nshots); - nysrc = unique_elements(ysrc,nshots); - - vmess("nxsrc=%d nysrc=%d",nxsrc,nysrc); - - ret = getFileInfo3D(file_tinv, &ntd, &nxd, &nyd, &Nfoc, &dtd, &dxd, &dyd, &ftd, &fxd, &fyd, &scld, &ntrd); - vmess("ntd=%d nxd=%d nyd=%d Nfoc=%d ntrd=%d",ntd,nxd,nyd,Nfoc,ntrd); - vmess("dtd=%.5f dxd=%.5f dyd=%.5f ftd=%.5f fxd=%.5f fyd=%.5f scld=%.5f",dtd,dxd,dyd,ftd,fxd,fyd,scld); - - f1d = (float *)calloc(Nfoc*nxd*nyd*ntfft,sizeof(float)); - muteW = (int *)calloc(Nfoc*nxd*nyd,sizeof(int)); - xrcvsyn = (float *)calloc(Nfoc*nxd*nyd,sizeof(float)); // x-rcv postions of focal points - yrcvsyn = (float *)calloc(Nfoc*nxd*nyd,sizeof(float)); // x-rcv postions of focal points - xsyn = (float *)malloc(Nfoc*sizeof(float)); // x-src position of focal points - ysyn = (float *)malloc(Nfoc*sizeof(float)); // x-src position of focal points - zsyn = (float *)malloc(Nfoc*sizeof(float)); // z-src position of focal points - xnxsyn = (int *)calloc(Nfoc,sizeof(int)); // number of traces per focal point - ixpos = (int *)calloc(nxd,sizeof(int)); // x-position of source of shot in G_d domain (nxd with dxd) - - mode=-1; - readTinvData3D(file_tinv, xrcvsyn, yrcvsyn, xsyn, ysyn, zsyn, xnxsyn, Nfoc, nxd, nyd, ntfft, mode, muteW, f1d, hw, verbose); - - fxsb = fxd; - fysb = fyd; - if (xrcvsyn[0] != 0 || xrcvsyn[1] != 0 ) fxsb = xrcvsyn[0]; - fxse = fxsb + (float)(nxd-1)*dxd; - if (yrcvsyn[0] != 0 || yrcvsyn[1] != 0 ) fysb = yrcvsyn[0]; - fyse = fysb + (float)(nyd-1)*dyd; - - vmess("fxsb=%.3f fysb=%.3f fxse=%.3f fyse=%.3f",fxsb,fysb,fxse,fyse); - - synthesisPosistions3D(nxs, nys, nxd, nyd, Nfoc, xrcv, yrcv, - xsrc, ysrc, xnx, fxse, fyse, fxsb, fysb, dxs, dys, - nshots, nxsrc, nysrc, ixpos, &npos, 0, verbose); - - vmess("npos:%d",npos); - - iRN = (float *)calloc(Nfoc*nxd*nyd*ntfft,sizeof(float)); - nxys = nxs*nys; - nxyd = nxd*nyd; - - synthesis3D(Refl, Fop, f1d, iRN, nxs, nys, nts, nxd, nyd, ntd, dts, xsyn, ysyn, - Nfoc, xrcv, yrcv, xsrc, ysrc, xnx, fxse, fxsb, fyse, fysb, dxs, dys, dxsrc, dysrc, dx, dy, ntfft, nw, nw_low, nw_high, mode, - 0, nshots, nxsrc, nysrc, ixpos, npos, &tfft, isxcount, reci_xsrc, reci_xrcv, ixmask, verbose); - - - hdrs_out = (segy *)calloc(Nfoc*nxd*nyd,sizeof(segy)); - - tracf = 1; - - for (l = 0; l < Nfoc; l++) { - for (j = 0; j < nyd; j++) { - for (i = 0; i < nxd; i++) { - hdrs_out[l*nyd*nxd+j*nxd+i].ns = ntfft; - hdrs_out[l*nyd*nxd+j*nxd+i].fldr = l+1; - hdrs_out[l*nyd*nxd+j*nxd+i].trid = 1; - hdrs_out[l*nyd*nxd+j*nxd+i].dt = dtd*1000000; - hdrs_out[l*nyd*nxd+j*nxd+i].f1 = ftd; - hdrs_out[l*nyd*nxd+j*nxd+i].f2 = fxd; - hdrs_out[l*nyd*nxd+j*nxd+i].d1 = dtd; - hdrs_out[l*nyd*nxd+j*nxd+i].d2 = dxd; - hdrs_out[l*nyd*nxd+j*nxd+i].trwf = nxd*nyd; - hdrs_out[l*nyd*nxd+j*nxd+i].scalco = -1000; - hdrs_out[l*nyd*nxd+j*nxd+i].sx = NINT(1000*(xsyn[l])); - hdrs_out[l*nyd*nxd+j*nxd+i].sy = NINT(1000*(ysyn[l])); - hdrs_out[l*nyd*nxd+j*nxd+i].gx = NINT(1000*(xrcvsyn[l*nyd*nxd+j*nxd+i])); - hdrs_out[l*nyd*nxd+j*nxd+i].gy = NINT(1000*(yrcvsyn[l*nyd*nxd+j*nxd+i])); - hdrs_out[l*nyd*nxd+j*nxd+i].scalel = -1000; - hdrs_out[l*nyd*nxd+j*nxd+i].tracl = i+1; - hdrs_out[l*nyd*nxd+j*nxd+i].offset = (long)NINT(xrcvsyn[l*nyd*nxd+j*nxd+i] - xsyn[l]); - hdrs_out[l*nyd*nxd+j*nxd+i].tracf = tracf++; - hdrs_out[l*nyd*nxd+j*nxd+i].selev = NINT(zsyn[l]*1000); - hdrs_out[l*nyd*nxd+j*nxd+i].sdepth = NINT(-zsyn[l]*1000); - } - } - } - - fp_out = fopen(file_out,"w+"); - ret = writeData(fp_out, iRN, hdrs_out, ntfft, Nfoc*nxd*nyd); - if (ret < 0 ) verr("error on writing output file."); - fclose(fp_out); - - free(Refl);free(xrcv);free(yrcv);free(xsrc);free(ysrc);free(zsrc);free(xnx); - free(f1d);free(xrcvsyn);free(yrcvsyn);free(xsyn);free(ysyn);free(zsyn);free(xnxsyn);free(muteW); - - return; -} - - -int unique_elements(float *arr, int len) -{ - if (len <= 0) return 0; - int unique = 1; - int outer, inner, is_unique; - - for (outer = 1; outer < len; ++outer) - { - is_unique = 1; - for (inner = 0; is_unique && inner < outer; ++inner) - { - if ((arr[inner] >= arr[outer]-1.0) && (arr[inner] <= arr[outer]+1.0)) is_unique = 0; - } - if (is_unique) ++unique; - } - return unique; -} \ No newline at end of file -- GitLab