From 57f90ee51e8aeb7c1efaa8d6768a4281fa800611 Mon Sep 17 00:00:00 2001 From: "joeri.brackenhoff" <joeri.brackenhoff@login0.ogun.local> Date: Thu, 14 Mar 2019 10:48:52 -0300 Subject: [PATCH] 3D --- marchenko3D/ampest3D_backup.c | 298 +++++++++++ marchenko3D/imaging3D.c | 49 ++ marchenko3D/makeWindow3D.c | 155 ++++++ marchenko3D/marchenko3D_backup.c | 851 +++++++++++++++++++++++++++++++ marchenko3D/readSnapData3D.c | 56 ++ utils/ampdet.c | 323 ++++++++++++ 6 files changed, 1732 insertions(+) create mode 100644 marchenko3D/ampest3D_backup.c create mode 100644 marchenko3D/imaging3D.c create mode 100644 marchenko3D/makeWindow3D.c create mode 100644 marchenko3D/marchenko3D_backup.c create mode 100644 marchenko3D/readSnapData3D.c create mode 100644 utils/ampdet.c diff --git a/marchenko3D/ampest3D_backup.c b/marchenko3D/ampest3D_backup.c new file mode 100644 index 0000000..08b480b --- /dev/null +++ b/marchenko3D/ampest3D_backup.c @@ -0,0 +1,298 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include "segy.h" +#include <assert.h> +#include "par.h" +#include <genfft.h> + +#ifndef COMPLEX +typedef struct _complexStruct { /* complex number */ + float r,i; +} complex; +#endif/* complex */ + +#define NINT(x) ((long)((x)>0.0?(x)+0.5:(x)-0.5)) + +long loptncr(long n); +long maxest3D(float *data, long nt); +long readData3D(FILE *fp, float *data, segy *hdrs, long n1); +void scl_data(float *data, long nsam, long nrec, float scl, float *datout, long nsamout); +void pad_data(float *data, long nsam, long nrec, long nsamout, float *datout); +void corr(float *data1, float *data2, float *cov, long nrec, long nsam, float dt, long shift); +void convol(float *data1, float *data2, float *con, long nrec, long nsam, float dt, long shift); + +void AmpEst3D(float *f1d, float *Gd, float *ampest, long Nfoc, long nxs, long nys, long ntfft, long *ixpos, long npos, + char *file_wav, float dx, float dy, float dt) +{ + + long l, i, ix, iw, nfreq; + float scl, sclt, *wavelet, *scaled, *conv, *f1dsamp; + float dtm, dxm, cpm, rom, *trace; + FILE *fp_wav; + segy *hdrs_wav; + + scl = dx*dy; + sclt = 1.0*dt/((float)ntfft); + + conv = (float *)calloc(nys*nxs*ntfft,sizeof(float)); + wavelet = (float *)calloc(ntfft,sizeof(float)); + scaled = (float *)calloc(ntfft,sizeof(float)); + f1dsamp = (float *)calloc(nys*nxs*ntfft,sizeof(float)); + + if (file_wav!=NULL) { + trace = (float *)calloc(ntfft,sizeof(float)); + hdrs_wav = (segy *)calloc(1, sizeof(segy)); + fp_wav = fopen(file_wav, "r"); + if (fp_wav==NULL) verr("error on opening wavelet file %s", file_wav); + readData3D(fp_wav, trace, hdrs_wav, 0); + fclose(fp_wav); + corr(trace, trace, wavelet, 1, ntfft, dt, 0); + free(hdrs_wav); free(trace); + /* For a monopole source the scaling is (2.0*dt*cp*cp*rho)/(dx*dx) */ + for (iw=0; iw<ntfft; iw++){ + wavelet[iw] *= dt; + } + } + + for (l=0; l<Nfoc; l++) { + for (i=0; i<npos; i++) { + ix = ixpos[i]; + for (iw=0; iw<ntfft; iw++) { + f1dsamp[i*ntfft+iw] = f1d[l*nxs*nys*ntfft+ix*ntfft+iw]; + } + } + if (file_wav==NULL){ + corr(f1dsamp, f1dsamp, conv, nxs*nys, ntfft, dt, 0); + for (i=0; i<nxs*nys; i++) { + for (iw=0; iw<ntfft; iw++) { + wavelet[iw] += dt*scl*conv[i*ntfft+iw]; + } + } + } + memset(&conv[0],0.0, sizeof(float)*ntfft*nxs*nys); + convol(f1dsamp, &Gd[l*nxs*nys*ntfft], conv, nxs*nys, ntfft, dt, 0); + for (i=0; i<nxs*nys; i++) { + for (iw=0; iw<ntfft; iw++) { + scaled[iw] += dt*scl*conv[i*ntfft+iw]; + } + } + ampest[l] = sqrtf(wavelet[0]/scaled[0]); + memset(&conv[0],0.0, sizeof(float)*ntfft*nxs*nys); + memset(&scaled[0],0.0, sizeof(float)*ntfft); + } + free(wavelet);free(scaled);free(conv);free(f1dsamp); + + return; +} + +long maxest3D(float *data, long nt) +{ + float maxt; + long it; + + maxt = data[0]; + for (it = 0; it < nt; it++) { + if (fabs(data[it]) > fabs(maxt)) maxt=data[it]; + } + + return maxt; +} + +/** +* Calculates the time convolution of two arrays by +* transforming the arrayis to frequency domain, +* multiplies the arrays and transform back to time. +* +**/ + +void convol(float *data1, float *data2, float *con, long nrec, long nsam, float dt, long shift) +{ + long i, j, n, optn, nfreq, sign; + float df, dw, om, tau, scl; + float *qr, *qi, *p1r, *p1i, *p2r, *p2i, *rdata1, *rdata2; + complex *cdata1, *cdata2, *ccon, tmp; + + optn = loptncr(nsam); + nfreq = optn/2+1; + + + cdata1 = (complex *)malloc(nfreq*nrec*sizeof(complex)); + if (cdata1 == NULL) verr("memory allocation error for cdata1"); + cdata2 = (complex *)malloc(nfreq*nrec*sizeof(complex)); + if (cdata2 == NULL) verr("memory allocation error for cdata2"); + ccon = (complex *)malloc(nfreq*nrec*sizeof(complex)); + if (ccon == NULL) verr("memory allocation error for ccov"); + + rdata1 = (float *)malloc(optn*nrec*sizeof(float)); + if (rdata1 == NULL) verr("memory allocation error for rdata1"); + rdata2 = (float *)malloc(optn*nrec*sizeof(float)); + if (rdata2 == NULL) verr("memory allocation error for rdata2"); + + /* pad zeroes until Fourier length is reached */ + pad_data(data1, nsam, nrec, optn, rdata1); + pad_data(data2, nsam, nrec, optn, rdata2); + + /* forward time-frequency FFT */ + sign = -1; + rcmfft(&rdata1[0], &cdata1[0], (int)optn, (int)nrec, (int)optn, (int)nfreq, (int)sign); + rcmfft(&rdata2[0], &cdata2[0], (int)optn, (int)nrec, (int)optn, (int)nfreq, (int)sign); + + /* apply convolution */ + p1r = (float *) &cdata1[0]; + p2r = (float *) &cdata2[0]; + qr = (float *) &ccon[0].r; + p1i = p1r + 1; + p2i = p2r + 1; + qi = qr + 1; + n = nrec*nfreq; + for (j = 0; j < n; j++) { + *qr = (*p2r**p1r-*p2i**p1i); + *qi = (*p2r**p1i+*p2i**p1r); + qr += 2; + qi += 2; + p1r += 2; + p1i += 2; + p2r += 2; + p2i += 2; + } + free(cdata1); + free(cdata2); + + if (shift) { + df = 1.0/(dt*optn); + dw = 2*PI*df; +// tau = 1.0/(2.0*df); + tau = dt*(nsam/2); + for (j = 0; j < nrec; j++) { + om = 0.0; + for (i = 0; i < nfreq; i++) { + tmp.r = ccon[j*nfreq+i].r*cos(om*tau) + ccon[j*nfreq+i].i*sin(om*tau); + tmp.i = ccon[j*nfreq+i].i*cos(om*tau) - ccon[j*nfreq+i].r*sin(om*tau); + ccon[j*nfreq+i] = tmp; + om += dw; + } + } + } + + /* inverse frequency-time FFT and scale result */ + sign = 1; + scl = 1.0/((float)(optn)); + crmfft(&ccon[0], &rdata1[0], (int)optn, (int)nrec, (int)nfreq, (int)optn, (int)sign); + scl_data(rdata1,optn,nrec,scl,con,nsam); + + free(ccon); + free(rdata1); + free(rdata2); + return; +} + +/** +* Calculates the time correlation of two arrays by +* transforming the arrayis to frequency domain, +* multiply the arrays and transform back to time. +* +**/ + + +void corr(float *data1, float *data2, float *cov, long nrec, long nsam, float dt, long shift) +{ + long i, j, n, optn, nfreq, sign; + float df, dw, om, tau, scl; + float *qr, *qi, *p1r, *p1i, *p2r, *p2i, *rdata1, *rdata2; + complex *cdata1, *cdata2, *ccov, tmp; + + optn = loptncr(nsam); + nfreq = optn/2+1; + + cdata1 = (complex *)malloc(nfreq*nrec*sizeof(complex)); + if (cdata1 == NULL) verr("memory allocation error for cdata1"); + cdata2 = (complex *)malloc(nfreq*nrec*sizeof(complex)); + if (cdata2 == NULL) verr("memory allocation error for cdata2"); + ccov = (complex *)malloc(nfreq*nrec*sizeof(complex)); + if (ccov == NULL) verr("memory allocation error for ccov"); + + rdata1 = (float *)malloc(optn*nrec*sizeof(float)); + if (rdata1 == NULL) verr("memory allocation error for rdata1"); + rdata2 = (float *)malloc(optn*nrec*sizeof(float)); + if (rdata2 == NULL) verr("memory allocation error for rdata2"); + + /* pad zeroes until Fourier length is reached */ + pad_data(data1, nsam, nrec, optn, rdata1); + pad_data(data2, nsam, nrec, optn, rdata2); + + /* forward time-frequency FFT */ + sign = -1; + rcmfft(&rdata1[0], &cdata1[0], (int)optn, (int)nrec, (int)optn, (int)nfreq, (int)sign); + rcmfft(&rdata2[0], &cdata2[0], (int)optn, (int)nrec, (int)optn, (int)nfreq, (int)sign); + + /* apply correlation */ + p1r = (float *) &cdata1[0]; + p2r = (float *) &cdata2[0]; + qr = (float *) &ccov[0].r; + p1i = p1r + 1; + p2i = p2r + 1; + qi = qr + 1; + n = nrec*nfreq; + for (j = 0; j < n; j++) { + *qr = (*p1r * *p2r + *p1i * *p2i); + *qi = (*p1i * *p2r - *p1r * *p2i); + qr += 2; + qi += 2; + p1r += 2; + p1i += 2; + p2r += 2; + p2i += 2; + } + free(cdata1); + free(cdata2); + + /* shift t=0 to middle of time window (nsam/2)*/ + if (shift) { + df = 1.0/(dt*optn); + dw = 2*PI*df; + tau = dt*(nsam/2); + + for (j = 0; j < nrec; j++) { + om = 0.0; + for (i = 0; i < nfreq; i++) { + tmp.r = ccov[j*nfreq+i].r*cos(om*tau) + ccov[j*nfreq+i].i*sin(om*tau); + tmp.i = ccov[j*nfreq+i].i*cos(om*tau) - ccov[j*nfreq+i].r*sin(om*tau); + ccov[j*nfreq+i] = tmp; + om += dw; + } + } + } + + /* inverse frequency-time FFT and scale result */ + sign = 1; + scl = 1.0/(float)optn; + crmfft(&ccov[0], &rdata1[0], (int)optn, (int)nrec, (int)nfreq, (int)optn, (int)sign); + scl_data(rdata1,optn,nrec,scl,cov,nsam); + + free(ccov); + free(rdata1); + free(rdata2); + return; +} + +void pad_data(float *data, long nsam, long nrec, long nsamout, float *datout) +{ + long it,ix; + for (ix=0;ix<nrec;ix++) { + for (it=0;it<nsam;it++) + datout[ix*nsamout+it]=data[ix*nsam+it]; + for (it=nsam;it<nsamout;it++) + datout[ix*nsamout+it]=0.0; + } +} + +void scl_data(float *data, long nsam, long nrec, float scl, float *datout, long nsamout) +{ + long it,ix; + for (ix = 0; ix < nrec; ix++) { + for (it = 0 ; it < nsamout ; it++) + datout[ix*nsamout+it] = scl*data[ix*nsam+it]; + } +} \ No newline at end of file diff --git a/marchenko3D/imaging3D.c b/marchenko3D/imaging3D.c new file mode 100644 index 0000000..6245d6e --- /dev/null +++ b/marchenko3D/imaging3D.c @@ -0,0 +1,49 @@ +#include "par.h" +#include "segy.h" +#include <time.h> +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include <assert.h> +#include <genfft.h> + +double wallclock_time(void); + +void scl_data(float *data, long nsam, long nrec, float scl, float *datout, long nsamout); +void pad_data(float *data, long nsam, long nrec, long nsamout, float *datout); +void convol(float *data1, float *data2, float *con, long nrec, long nsam, float dt, long shift); + + +void imaging3D(float *Image, float *Gmin, float *f1plus, long nx, long ny, long nt, float dx, float dy, float dt, long Nfoc, long verbose) +{ + long i, l, count=0; + float *conv; + double t0, t2; + + t0 = wallclock_time(); + +#pragma omp parallel default(shared) \ + private(i,conv) +{ + conv = (float *)calloc(nx*ny*nt,sizeof(float)); + +#pragma omp for + for (l = 0; l < Nfoc; l++) { + count+=1; + if (verbose > 2) vmess("Imaging location %d out of %d",count,Nfoc); + + convol(&Gmin[l*nx*ny*nt], &f1plus[l*nx*ny*nt], conv, nx*ny, nt, dt, 0); + for (i=0; i<nx*ny; i++) { + Image[l] += conv[i*nt]*dx*dy*dt; + } + } + free(conv); +} + + t2 = wallclock_time(); + if (verbose) { + vmess("Total Imaging time = %.3f", t2-t0); + } + + return; +} \ No newline at end of file diff --git a/marchenko3D/makeWindow3D.c b/marchenko3D/makeWindow3D.c new file mode 100644 index 0000000..bd5ba82 --- /dev/null +++ b/marchenko3D/makeWindow3D.c @@ -0,0 +1,155 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include "segy.h" +#include <assert.h> +#include <genfft.h> + +#ifndef COMPLEX +typedef struct _complexStruct { /* complex number */ + float r,i; +} complex; +#endif/* complex */ + +#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) ((long)((x)>0.0?(x)+0.5:(x)-0.5)) + +void findShotInMute(float *xrcvMute, float xrcvShot, long nxs, long *imute); +long readData3D(FILE *fp, float *data, segy *hdrs, long n1); +long readSnapData3D(char *filename, float *data, segy *hdrs, long nsnaps, long nx, long ny, long nz, long sx, long ex, long sy, long ey, long sz, long ez); + + + +void makeWindow3D(char *file_ray, char *file_amp, char *file_wav, float dt, float *xrcv, float *yrcv, float *xsrc, float *ysrc, float *zsrc, + long *xnx, long Nfoc, long nx, long ny, long ntfft, long *maxval, float *tinv, long verbose) +{ + FILE *fp; + segy hdr, *hdrs_mute, *hdrs_amp; + size_t nread; + long ig, is, i, iy, ix, j, l, nfreq, ntwav; + float *wavelet, *wavtmp, scl, *timeval, dw, *amp; + complex *cmute, *cwav; + + /*Define parameters*/ + nfreq = ntfft/2+1; + wavelet = (float *)calloc(ntfft,sizeof(float)); + cwav = (complex *)malloc(nfreq*sizeof(complex)); + cmute = (complex *)malloc(nfreq*sizeof(complex)); + dw = 2*M_PI/(ntfft*dt); + + /*Create wavelet using parameters or read in wavelet*/ + if (file_wav != NULL) { + //Determine the amount of sample + if (verbose>0) vmess("Reading in wavelet"); + fp = fopen( file_wav, "r" ); + if ( fp == NULL ) { + perror("Error opening file containing wavelet"); + } + nread = fread( &hdr, 1, TRCBYTES, fp ); + ntwav = hdr.ns; + fclose(fp); + //Read in the wavelet + fp = fopen( file_wav, "r" ); + wavtmp = (float *)calloc(ntwav,sizeof(float)); + readData3D(fp, wavtmp, &hdr, ntwav); + //Fit the wavelet into the same time-axis as the Marchenko scheme + for (i=0; i<ntwav; i++) { + wavelet[i] = wavtmp[i]; + wavelet[ntfft-1-i] = wavtmp[ntwav-1-i]; + } + rc1fft(wavelet,cwav,ntfft,-1); + free(wavtmp); + free(wavelet); + } + + + timeval = (float *)calloc(Nfoc*nx*ny,sizeof(float)); + if (file_amp!=NULL) amp = (float *)calloc(Nfoc*nx*ny,sizeof(float)); + + + /* Defining mute window using raytimes */ + vmess("Using raytime for mutewindow"); + hdrs_mute = (segy *) calloc(Nfoc,sizeof(segy)); + fp = fopen( file_ray, "r" ); + if ( fp == NULL ) { + perror("Error opening file containing ray"); + } + fclose(fp); + readSnapData3D(file_ray, timeval, hdrs_mute, Nfoc, 1, 1, nx, 0, 1, 0, 1, 0, nx); + // for (is=0; is<Nfoc; is++) { + // readData3D(fp, &timeval[is*nx*ny], &hdrs_mute[is], nx); + // } + + /*Check whether the amplitude is also used*/ + if (file_amp != NULL) { + vmess("Using ray-amplitudes"); + hdrs_amp = (segy *) calloc(Nfoc,sizeof(segy)); + fp = fopen( file_amp, "r" ); + if ( fp == NULL ) { + perror("Error opening file containing ray-amplitude"); + } + fclose(fp); + readSnapData3D(file_amp, amp, hdrs_amp, Nfoc, 1, 1, nx, 0, 1, 0, 1, 0, nx); + // for (is=0; is<Nfoc; is++) { + // readData3D(fp, &[is*nx*ny], &hdrs_amp[is], nx); + // } + } + + /*Define source and receiver locations from the raytime*/ + for (is=0; is<Nfoc; is++) { + for (iy=0; iy<ny; iy++) { + for (ix=0; ix<nx; ix++) { + xrcv[is*nx*ny+iy*nx+ix] = (hdrs_mute[is].f1 + hdrs_mute[is].d1*((float)ix)); + yrcv[is*nx*ny+iy*nx+ix] = hdrs_mute[is].gy; + } + } + xnx[is]=hdrs_mute[is].ns; + if (hdrs_mute[is].scalco < 0) scl=-1.0/hdrs_mute[is].scalco; + else scl=hdrs_mute[is].scalco; + xsrc[is] = hdrs_mute[is].sx*scl; + ysrc[is] = hdrs_mute[is].sy*scl; + zsrc[is] = hdrs_mute[is].sdepth*scl; + } + + + /*Determine the mutewindow*/ + for (j=0; j<Nfoc; j++) { + for (l=0; l<ny; l++) { + for (i=0; i<nx; i++) { + maxval[j*ny*nx+l*nx+i] = (long)roundf(timeval[j*ny*nx+l*nx+i]/dt); + if (maxval[j*ny*nx+l*nx+i] > ntfft-1) maxval[j*ny*nx+l*nx+i] = ntfft-1; + if (file_wav!=NULL) { /*Apply the wavelet to create a first arrival*/ + if (file_amp != NULL) { + for (ig=0; ig<nfreq; ig++) { + cmute[ig].r = (dt/sqrtf((float)ntfft))*(cwav[ig].r*cos(ig*dw*timeval[j*ny*nx+l*nx+i]-M_PI/4.0)-cwav[ig].i*sin(ig*dw*timeval[j*ny*nx+l*nx+i]-M_PI/4.0))/(amp[j*ny*nx+l*nx+i]*amp[j*ny*nx+l*nx+i]); + cmute[ig].i = (dt/sqrtf((float)ntfft))*(cwav[ig].i*cos(ig*dw*timeval[j*ny*nx+l*nx+i]-M_PI/4.0)+cwav[ig].r*sin(ig*dw*timeval[j*ny*nx+l*nx+i]-M_PI/4.0))/(amp[j*ny*nx+l*nx+i]*amp[j*ny*nx+l*nx+i]); + } + } + else { /*Use the raytime only to determine the mutewindow*/ + for (ig=0; ig<nfreq; ig++) { + cmute[ig].r = (dt/sqrtf((float)ntfft))*(cwav[ig].r*cos(ig*dw*timeval[j*ny*nx+l*nx+i]-M_PI/4.0)-cwav[ig].i*sin(ig*dw*timeval[j*ny*nx+l*nx+i]-M_PI/4.0)); + cmute[ig].i = (dt/sqrtf((float)ntfft))*(cwav[ig].i*cos(ig*dw*timeval[j*ny*nx+l*nx+i]-M_PI/4.0)+cwav[ig].r*sin(ig*dw*timeval[j*ny*nx+l*nx+i]-M_PI/4.0)); + } + } + } + else { + for (ig=0; ig<nfreq; ig++) { + cmute[ig].r = (1.0/sqrtf((float)ntfft))*cos(ig*dw*timeval[j*ny*nx+l*nx+i]-M_PI/4.0); + cmute[ig].i = (1.0/sqrtf((float)ntfft))*sin(ig*dw*timeval[j*ny*nx+l*nx+i]-M_PI/4.0); + } + } + cr1fft(cmute,&tinv[j*ny*nx*ntfft+l*nx*ntfft+i*ntfft],ntfft,1); + } + } + } + + + return; +} + diff --git a/marchenko3D/marchenko3D_backup.c b/marchenko3D/marchenko3D_backup.c new file mode 100644 index 0000000..ace2b31 --- /dev/null +++ b/marchenko3D/marchenko3D_backup.c @@ -0,0 +1,851 @@ +/* + * 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) ((long)((x)>0.0?(x)+0.5:(x)-0.5)) + + + +#ifndef COMPLEX +typedef struct _complexStruct { /* complex number */ + float r,i; +} complex; +#endif/* complex */ + +long readShotData3D(char *filename, float *xrcv, float *yrcv, float *xsrc, float *ysrc, float *zsrc, long *xnx, complex *cdata, + long nw, long nw_low, long nshots, long nx, long ny, long ntfft, long mode, float scale, long verbose); +long readTinvData3D(char *filename, float *xrcv, float *yrcv, float *xsrc, float *ysrc, float *zsrc, + long *xnx, long Nfoc, long nx, long ny, long ntfft, long mode, long *maxval, float *tinv, long hw, long 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); +long unique_elements(float *arr, long len); + +void name_ext(char *filename, char *extension); + +void applyMute3D(float *data, long *mute, long smooth, long above, long Nfoc, long nxs, long nt, long *xrcvsyn, long npos, long shift); + +long getFileInfo3D(char *filename, long *n1, long *n2, long *n3, long *ngath, float *d1, float *d2, float *d3, float *f1, float *f2, float *f3, + float *sclsxgxsygy, long *nxm); +long readData3D(FILE *fp, float *data, segy *hdrs, long n1); +long writeData3D(FILE *fp, float *data, segy *hdrs, long n1, long n2); +long disp_fileinfo3D(char *file, long n1, long n2, long n3, float f1, float f2, float f3, float d1, float d2, float d3, segy *hdrs); +double wallclock_time(void); + +void AmpEst3D(float *f1d, float *Gd, float *ampest, long Nfoc, long nxs, long nys, long ntfft, long *ixpos, long npos, + char *file_wav, float dx, float dy, float dt); + +void synthesisPositions3D(long nx, long ny, long nxs, long nys, long Nfoc, float *xrcv, float *yrcv, float *xsrc, float *ysrc, + long *xnx, float fxse, float fyse, float fxsb, float fysb, float dxs, float dys, long nshots, long nxsrc, long nysrc, + long *ixpos, long *npos, long reci, long verbose); +void synthesis3D(complex *Refl, complex *Fop, float *Top, float *iRN, long nx, long ny, long nt, long nxs, long nys, long nts, float dt, + float *xsyn, float *ysyn, long Nfoc, float *xrcv, float *yrcv, float *xsrc, float *ysrc, long *xnx, + float fxse, float fxsb, float fyse, float fysb, float dxs, float dys, float dxsrc, float dysrc, + float dx, float dy, long ntfft, long nw, long nw_low, long nw_high, long mode, long reci, long nshots, long nxsrc, long nysrc, + long *ixpos, long npos, double *tfft, long *isxcount, long *reci_xsrc, long *reci_xrcv, float *ixmask, long verbose); + +long linearsearch(long *array, size_t N, long value); + +/*********************** self documentation **********************/ +char *sdoc[] = { +" ", +" MARCHENKO3D - Iterative Green's function and focusing functions retrieval in 3D", +" ", +" marchenko3D 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)", +" author : Joeri Brackenhoff : 2019 (j.a.brackenhoff@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; + long i, j, l, k, ret, nshots, nxshot, nyshot, Nfoc, nt, nx, ny, nts, nxs, nys, ngath; + long size, n1, n2, n3, ntap, tap, dxi, dyi, ntraces, pad; + long nw, nw_low, nw_high, nfreq, *xnx, *xnxsyn; + long reci, countmin, mode, n2out, n3out, verbose, ntfft; + long iter, niter, tracf, *muteW, ampest; + long hw, smooth, above, shift, *ixpos, npos, ix; + long 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, *ampscl, *Gd; + complex *Refl, *Fop; + char *file_tinv, *file_shot, *file_green, *file_iter, *file_wav; + 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 (!getparstring("file_wav", &file_wav)) file_wav = NULL; + if (!getparlong("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 (!getparlong("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 (!getparlong("tap", &tap)) tap = 0; + if (!getparlong("ntap", &ntap)) ntap = 0; + if (!getparlong("pad", &pad)) pad = 0; + if (!getparlong("ampest", &est)) ampest = 0; + + if(!getparlong("niter", &niter)) niter = 10; + if(!getparlong("hw", &hw)) hw = 15; + if(!getparlong("smooth", &smooth)) smooth = 5; + if(!getparlong("above", &above)) above = 0; + if(!getparlong("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 = loptncr(MAX(nt+pad, nts+pad)); + nfreq = ntfft/2+1; + nw_low = (long)MIN((fmin*ntfft*dt), nfreq-1); + nw_low = MAX(nw_low, 1); + nw_high = MIN((long)(fmax*ntfft*dt), nfreq-1); + nw = nw_high - nw_low + 1; + scl = 1.0/((float)ntfft); + if (!getparlong("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 = (long *)calloc(Nfoc*nys*nxs,sizeof(long)); + 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 = (long *)calloc(Nfoc,sizeof(long)); // number of traces per focal point + ixpos = (long *)calloc(nys*nxs,sizeof(long)); // 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 = (long *)calloc(nshots,sizeof(long)); // number of traces per shot + + if (reci!=0) { + reci_xsrc = (long *)malloc((nxs*nxs*nys*nys)*sizeof(long)); + reci_xrcv = (long *)malloc((nxs*nxs*nys*nys)*sizeof(long)); + isxcount = (long *)calloc(nxs*nys,sizeof(long)); + 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=%li", 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=%li", 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 (%li) and focusing operator (%li) are not equal",nt, nts); + if (verbose) { + vmess("Number of focusing operators = %li", Nfoc); + vmess("Number of receivers in focusop = x:%li y:%li total:%li", nxs, nys, nxs*nys); + vmess("number of shots = %li", nshots); + vmess("number of receiver/shot = x:%li y:%li total:%li", 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:%li y:%li", dxi, dyi); + vmess("number of time samples (nt,nts) = %li (%li,%li)", 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:%li y:%li total:%li", n2out, n3out, n2out*n3out); + vmess("number of output samples = %li", 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=%li nyshot=%li nshots=%li npos=%li", 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 %li: Ni at iteration %li 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) */ + applyMute3D(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 %li finished ***", iter); + + } /* end of iterations */ + + free(Ni); + if (ampest < 1) 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]; + } + } + } + applyMute3D(green, muteW, smooth, 4, Nfoc, nxs*nys, nts, ixpos, npos, shift); + + /* 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 */ + applyMute3D(Gmin, muteW, smooth, 4, Nfoc, nxs*nys, nts, ixpos, npos, shift); + } /* end if Gmin */ + + /* compute downgoing Green's function G^+,+ */ + if (file_gplus != NULL || ampest > 0) { + 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]; + } + } + } + /* Apply mute with window for Gplus */ + applyMute3D(Gplus, muteW, smooth, 4, Nfoc, nxs*nys, nts, ixpos, npos, shift); + } /* end if Gplus */ + + /* Estimate the amplitude of the Marchenko Redatuming */ + if (ampest>0) { + if (verbose>0) vmess("Estimating amplitude scaling"); + Gd = (float *)calloc(Nfoc*nxs*nys*ntfft,sizeof(float)); + memcpy(Gd,Gplus,sizeof(float)*Nfoc*nxs*nys*ntfft); + applyMute3D(Gd, muteW, smooth, 2, Nfoc, nxs*nys, nts, ixpos, npos, shift); + ampscl = (float *)calloc(Nfoc,sizeof(float)); + AmpEst3D(G_d,Gd,ampscl,Nfoc,nxs,nys,ntfft,ixpos,npos,file_wav,dxs,dys,dt); + for (l=0; l<Nfoc; l++) { + for (j=0; j<nxs*nys*nts; j++) { + green[l*nxs*nts+j] *= ampscl[l]; + if (file_gplus != NULL) Gplus[l*nxs*nys*nts+j] *= ampscl[l]; + if (file_gmin != NULL) Gmin[l*nxs*nys*nts+j] *= ampscl[l]; + if (file_f2 != NULL) f2p[l*nxs*nys*nts+j] *= ampscl[l]; + if (file_pmin != NULL) pmin[l*nxs*nys*nts+j] *= ampscl[l]; + if (file_f1plus != NULL) f1plus[l*nxs*nys*nts+j] *= ampscl[l]; + if (file_f1min != NULL) f1min[l*nxs*nys*nts+j] *= ampscl[l]; + } + if (verbose>1) vmess("Amplitude of focal position %li is equal to %.3e",l,ampscl[l]); + } + free(Gd); + if (file_gplus == NULL) free(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 = writeData3D(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 = writeData3D(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 = writeData3D(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 = writeData3D(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 = writeData3D(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 = writeData3D(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 = writeData3D(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 %li 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); +} + +long unique_elements(float *arr, long len) +{ + if (len <= 0) return 0; + long unique = 1; + long 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/readSnapData3D.c b/marchenko3D/readSnapData3D.c new file mode 100644 index 0000000..503d490 --- /dev/null +++ b/marchenko3D/readSnapData3D.c @@ -0,0 +1,56 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include "segy.h" +#include <assert.h> + +typedef struct { /* complex number */ + float r,i; +} complex; + +long readSnapData3D(char *filename, float *data, segy *hdrs, long nsnaps, long nx, long ny, long nz, long sx, long ex, long sy, long ey, long sz, long ez) +{ + FILE *fp; + segy hdr; + size_t nread; + long nt, it, ix, iy, iz, dx, dy, dz; + float *tmpdata; + + tmpdata = (float *)malloc(nsnaps*nx*ny*nz*sizeof(float)); + /* Reading first header */ + if (filename == NULL) fp = stdin; + else fp = fopen( filename, "r" ); + if ( fp == NULL ) { + fprintf(stderr,"input file %s has an error\n", filename); + perror("error in opening file: "); + fflush(stderr); + return -1; + } + //nread = fread(&hdr, 1, TRCBYTES, fp); + for (it = 0; it < nsnaps*nx*ny; it++) { + nread = fread(&hdr, 1, TRCBYTES, fp); + if (nread != TRCBYTES) { + break; + } + assert(nread == TRCBYTES); + nread = fread(&tmpdata[it*nz], sizeof(float), nz, fp); + assert (nread == nz); + memcpy(&hdrs[it], &hdr, TRCBYTES); + } + dx = ex-sx; + dy = ey-sy; + dz = ez-sz; + for (iz = sz; iz < ez; iz++) { + for (iy = sy; iy < ey; iy++) { + for (ix = sx; ix < ex; ix++) { + for (it = 0; it < nsnaps; it++) { + data[it*dy*dx*dz+(iy-sy)*dx*dz+(ix-sx)*dz+iz-sz]=tmpdata[it*ny*nx*nz+iy*nx*nz+ix*nz+iz]; + } + } + } + } + fclose(fp); + free(tmpdata); + return 0; +} diff --git a/utils/ampdet.c b/utils/ampdet.c new file mode 100644 index 0000000..d00a7c4 --- /dev/null +++ b/utils/ampdet.c @@ -0,0 +1,323 @@ +#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 getFileInfo(char *filename, int *n1, int *n2, int *ngath, float *d1, float *d2, float *f1, float *f2, float *xmin, float *xmax, float *sclsxgx, int *nxm); +int readData(FILE *fp, float *data, segy *hdrs, int n1); +int writeData(FILE *fp, float *data, segy *hdrs, int n1, int n2); +void complex_sqrt(complex *z); +void deconv_small(complex *c1, complex *c2, complex *c3, float nkx, float nfreq, float reps, float eps); +void conv_small(complex *c1, complex *c2, complex *c3, float nkx, float nfreq); +void corr_small(complex *c1, complex *c2, complex *c3, float nkx, float nfreq); +void scl_data(float *data, int nsam, int nrec, float scl, float *datout, int nsamout); +void pad2d_data(float *data, int nsam, int nrec, int nsamout, int nrecout, float *datout); +void pad_data(float *data, int nsam, int nrec, int nsamout, float *datout); + +/*********************** self documentation **********************/ +char *sdoc[] = { +" ", +" ampdet - Determine amplitude", +" ", +" author : Jan Thorbecke : 19-04-1995 (janth@xs4all.nl)", +" product : Originates from DELPHI software", +" : revision 2010", +" ", +NULL}; +/**************** end self doc ***********************************/ + +int main (int argc, char **argv) +{ + FILE *fp; + char *file_gp, *file_fp, *file_wav; + int nx, nt, ngath, ntraces, ret, size, nxwav; + int ntfft, nfreq, nxfft, nkx, i, j, n; + float dx, dt, fx, ft, xmin, xmax, scl; + float df, dw, dkx, eps, reps; + float *Gpd, *f1pd, *G_pad, *f_pad, *wav, *wav_pad; + complex *G_w, *f_w, *Gf, *amp, *wav_w, *S, *ZS, *SS; + segy *hdr_gp, *hdr_fp, *hdr_wav; + + initargs(argc, argv); + requestdoc(1); + + if(!getparstring("file_gp", &file_gp)) file_gp=NULL; + if (file_gp==NULL) verr("file %s does not exist",file_gp); + if(!getparstring("file_gp", &file_fp)) file_fp=NULL; + if (file_fp==NULL) verr("file %s does not exist",file_fp); + if(!getparstring("file_wav", &file_wav)) file_wav=NULL; + if (file_wav==NULL) verr("file %s does not exist",file_wav); + if(!getparfloat("eps", &eps)) eps=0.00; + if(!getparfloat("reps", &reps)) reps=0.01; + + ngath = 1; + ret = getFileInfo(file_gp, &nt, &nx, &ngath, &dt, &dx, &ft, &fx, &xmin, &xmax, &scl, &ntraces); + + size = nt*nx; + + Gpd = (float *)malloc(size*sizeof(float)); + hdr_gp = (segy *) calloc(nx,sizeof(segy)); + fp = fopen(file_gp, "r"); + if (fp == NULL) verr("error on opening input file_in1=%s", file_gp); + nx = readData(fp, Gpd, hdr_gp, nt); + fclose(fp); + + f1pd = (float *)malloc(size*sizeof(float)); + hdr_fp = (segy *) calloc(nx,sizeof(segy)); + fp = fopen(file_fp, "r"); + if (fp == NULL) verr("error on opening input file_in1=%s", file_fp); + nx = readData(fp, f1pd, hdr_fp, nt); + fclose(fp); + + wav = (float *)malloc(nt*sizeof(float)); + hdr_wav = (segy *) calloc(1,sizeof(segy)); + fp = fopen(file_wav, "r"); + if (fp == NULL) verr("error on opening input file_in1=%s", file_fp); + nxwav = readData(fp, wav, hdr_wav, nt); + fclose(fp); + vmess("test:%d",nxwav); + + /* Start the scaling */ + ntfft = optncr(nt); + nfreq = ntfft/2+1; + df = 1.0/(ntfft*dt); + dw = 2.0*PI*df; + nkx = optncc(nx); + dkx = 2.0*PI/(nkx*dx); + + vmess("ntfft:%d, nfreq:%d, nkx:%d",ntfft,nfreq,nkx); + + /* Allocate the arrays */ + G_pad = (float *)malloc(ntfft*nkx*sizeof(float)); + if (G_pad == NULL) verr("memory allocation error for G_pad"); + f_pad = (float *)malloc(ntfft*nkx*sizeof(float)); + if (f_pad == NULL) verr("memory allocation error for f_pad"); + wav_pad = (float *)malloc(ntfft*sizeof(float)); + if (wav_pad == NULL) verr("memory allocation error for wav_pad"); + G_w = (complex *)malloc(nfreq*nkx*sizeof(complex)); + if (G_w == NULL) verr("memory allocation error for G_w"); + f_w = (complex *)malloc(nfreq*nkx*sizeof(complex)); + if (f_w == NULL) verr("memory allocation error for f_w"); + Gf = (complex *)malloc(nfreq*nkx*sizeof(complex)); + if (Gf == NULL) verr("memory allocation error for Gf"); + wav_w = (complex *)malloc(nfreq*nkx*sizeof(complex)); + if (wav_w == NULL) verr("memory allocation error for wav_w"); + amp = (complex *)malloc(nfreq*nkx*sizeof(complex)); + if (amp == NULL) verr("memory allocation error for amp"); + S = (complex *)malloc(nfreq*nkx*sizeof(complex)); + if (S == NULL) verr("memory allocation error for S"); + ZS = (complex *)malloc(nfreq*nkx*sizeof(complex)); + if (ZS == NULL) verr("memory allocation error for ZS"); + SS = (complex *)malloc(nfreq*nkx*sizeof(complex)); + if (SS == NULL) verr("memory allocation error for SS"); + + /* pad zeroes in 2 directions to reach FFT lengths */ + pad2d_data(Gpd, nt,nx,ntfft,nkx,G_pad); + pad2d_data(f1pd,nt,nx,ntfft,nkx,f_pad); + pad_data(wav, nt, 1, ntfft, wav_pad); + + /* double forward FFT */ + xt2wkx(&G_pad[0], &G_w[0], ntfft, nkx, ntfft, nkx, 0); + xt2wkx(&f_pad[0], &f_w[0], ntfft, nkx, ntfft, nkx, 0); + rcmfft(&wav_pad[0], &wav_w[0], ntfft, 1, ntfft, nfreq, -1); + + for (i=1; i<nkx; i++) { + for (j=0; j<nfreq; j++) { + wav_w[i*nfreq+j] = wav_w[j]; + } + } + + /* Create Z*(|S|*)/(|S|*(|S|*)) */ + conv_small( G_w, f_w, Gf, nkx, nfreq); // Z + corr_small( wav_w, wav_w, S, nkx, nfreq); //|S| + corr_small( Gf, G_w, ZS, nkx, nfreq); // Z *(|S|*) + corr_small( G_w, G_w, SS, nkx, nfreq); //|S|*(|S|*) + deconv_small(ZS, SS, amp, nkx, nfreq, reps, eps); // amp + + for (i=0; i<nkx*nfreq; i++) { + complex_sqrt(&[i]); + } + + conv_small(G_w, amp, Gf, nkx, nfreq); // Scaled data + + /* inverse double FFT */ + wkx2xt(&Gf[0], &G_pad[0], ntfft, nkx, nkx, ntfft, 0); + /* select original samples and traces */ + scl = 1.0; + scl_data(G_pad,ntfft,nx,scl,Gpd ,nt); + + fp = fopen("out.su", "w+"); + ret = writeData(fp, Gpd, hdr_gp, nt, nx); + if (ret < 0 ) verr("error on writing output file."); + fclose(fp); + + free(f1pd);free(Gpd);free(hdr_gp);free(hdr_fp); + + return 0; +} + +void conv_small(complex *c1, complex *c2, complex *c3, float nkx, float nfreq) +{ + + float *qr, *qi, *p1r, *p1i, *p2r, *p2i; + int n, j; + + /* apply convolution */ + p1r = (float *) &c1[0]; + p2r = (float *) &c2[0]; + qr = (float *) &c3[0].r; + p1i = p1r + 1; + p2i = p2r + 1; + qi = qr + 1; + n = nkx*nfreq; + for (j = 0; j < n; j++) { + *qr = (*p2r**p1r - *p2i**p1i); + *qi = (*p2r**p1i + *p2i**p1r); + qr += 2; + qi += 2; + p1r += 2; + p1i += 2; + p2r += 2; + p2i += 2; + } +} + +void corr_small(complex *c1, complex *c2, complex *c3, float nkx, float nfreq) +{ + + float *qr, *qi, *p1r, *p1i, *p2r, *p2i; + int n, j; + + /* apply convolution */ + p1r = (float *) &c1[0]; + p2r = (float *) &c2[0]; + qr = (float *) &c3[0].r; + p1i = p1r + 1; + p2i = p2r + 1; + qi = qr + 1; + n = nkx*nfreq; + for (j = 0; j < n; j++) { + *qr = (*p2r**p1r + *p2i**p1i); + *qi = (*p2r**p1i - *p2i**p1r); + qr += 2; + qi += 2; + p1r += 2; + p1i += 2; + p2r += 2; + p2i += 2; + } +} + +void deconv_small(complex *c1, complex *c2, complex *c3, float nkx, float nfreq, float reps, float eps) +{ + + float *qr, *qi, *p1r, *p1i, *p2r, *p2i, maxden, *den, leps; + int n, j; + + den = (float *)malloc(nfreq*nkx*sizeof(float)); + if (den == NULL) verr("memory allocation error for den"); + + /* apply deconvolution */ + p1r = (float *) &c1[0]; + p2r = (float *) &c2[0]; + p1i = p1r + 1; + p2i = p2r + 1; + n = nkx*nfreq; + maxden=0.0; + for (j = 0; j < n; j++) { + den[j] = *p2r**p2r + *p2i**p2i; + maxden = MAX(den[j], maxden); + p2r += 2; + p2i += 2; + } + p1r = (float *) &c1[0]; + p2r = (float *) &c2[0]; + qr = (float *) &c3[0].r; + p1i = p1r + 1; + p2i = p2r + 1; + qi = qr + 1; + leps = reps*maxden+eps; + for (j = 0; j < n; j++) { + + if (fabs(*p2r)>=fabs(*p2i)) { + *qr = (*p2r**p1r+*p2i**p1i)/(den[j]+leps); + *qi = (*p2r**p1i-*p2i**p1r)/(den[j]+leps); + } else { + *qr = (*p1r**p2r+*p1i**p2i)/(den[j]+leps); + *qi = (*p1i**p2r-*p1r**p2i)/(den[j]+leps); + } + qr += 2; + qi += 2; + p1r += 2; + p1i += 2; + p2r += 2; + p2i += 2; + } +} + +void complex_sqrt(complex *z) +{ + float zmod, zmodr, zzmr, zzmi, zzm; + + zmod = sqrtf(z[0].r*z[0].r+z[0].i*z[0].i); + zmodr = sqrtf(zmod); + zzmr = z[0].r + zmod; + zzmi = z[0].i; + zzm = sqrtf(zzmr*zzmr+zzmi*zzmi); + + z[0].r = (zmodr*zzmr)/zzm; + z[0].i = (zmodr*zzmi)/zzm; +} + +void pad_data(float *data, int nsam, int nrec, int nsamout, float *datout) +{ + int it,ix; + for (ix=0;ix<nrec;ix++) { + for (it=0;it<nsam;it++) + datout[ix*nsamout+it]=data[ix*nsam+it]; + for (it=nsam;it<nsamout;it++) + datout[ix*nsamout+it]=0.0; + } +} + +void pad2d_data(float *data, int nsam, int nrec, int nsamout, int nrecout, float *datout) +{ + int it,ix; + for (ix=0;ix<nrec;ix++) { + for (it=0;it<nsam;it++) + datout[ix*nsam+it]=data[ix*nsam+it]; + for (it=nsam;it<nsamout;it++) + datout[ix*nsam+it]=0.0; + } + for (ix=nrec;ix<nrecout;ix++) { + for (it=0;it<nsamout;it++) + datout[ix*nsam+it]=0.0; + } +} + +void scl_data(float *data, int nsam, int nrec, float scl, float *datout, int nsamout) +{ + int it,ix; + for (ix = 0; ix < nrec; ix++) { + for (it = 0 ; it < nsamout ; it++) + datout[ix*nsamout+it] = scl*data[ix*nsam+it]; + } +} \ No newline at end of file -- GitLab