diff --git a/fdelmodc3D/.fuse_hidden0000015000000001 b/fdelmodc3D/.fuse_hidden0000015000000001
new file mode 100644
index 0000000000000000000000000000000000000000..158899df6305898453f54fc4344e21bd645b7fe8
--- /dev/null
+++ b/fdelmodc3D/.fuse_hidden0000015000000001
@@ -0,0 +1,227 @@
+#include<stdlib.h>
+#include<stdio.h>
+#include<math.h>
+
+typedef struct _compType { /* Receiver Type */
+	long vz;
+	long vx;
+	long vy;
+	long p;
+	long txx;
+	long tyy;
+	long tzz;
+	long txz;
+	long tyz;
+	long txy;
+	long pp;
+	long ss;
+	long ud;
+} compType;
+
+typedef struct _receiverPar { /* Receiver Parameters */
+	char *file_rcv;
+	compType type;
+	long n;
+	long nt;
+	long delay;
+	long skipdt;
+	long max_nrec;
+	long *z;
+	long *y;
+	long *x;
+	float *zr;
+	float *yr;
+	float *xr;
+	long int_p;
+	long int_vx;
+	long int_vy;
+	long int_vz;
+	long scale;
+	long sinkdepth;
+	long sinkvel;
+	float cp;
+	float rho;
+} recPar;
+
+typedef struct _snapshotPar { /* Snapshot Parameters */
+	char *file_snap;
+	char *file_beam;
+	compType type;
+	long nsnap;
+	long delay;
+	long skipdt;
+	long skipdz;
+	long skipdy;
+	long skipdx;
+	long nz;
+	long ny;
+	long nx;
+	long z1;
+	long z2;
+	long x1;
+	long x2;
+	long y1;
+	long y2;
+	long vxvztime;
+	long beam;
+	long withbnd;
+} snaPar;
+
+typedef struct _modelPar { /* Model Parameters */
+	long iorder;
+	long ischeme;
+	long grid_dir;
+	long sh;
+	char *file_cp;
+	char *file_ro;
+	char *file_cs;
+	char *file_qp;
+	char *file_qs;
+	float dz;
+	float dy;
+	float dx;
+	float dt;
+	float tmod;
+	long nt;
+	float z0;
+	float y0;
+	float x0;
+	/* medium max/min values */
+	float cp_min;
+	float cp_max;
+	float cs_min;
+	float cs_max;
+	float ro_min;
+	float ro_max;
+	long nz;
+	long ny;
+	long nx;
+	long naz;
+	long nay;
+	long nax;
+	/* Vx: rox */
+	long ioXx;
+	long ioXy;
+	long ioXz;
+	long ieXx;
+	long ieXy;
+	long ieXz;
+	/* Vy: roy */
+	long ioYx;
+	long ioYy;
+	long ioYz;
+	long ieYx;
+	long ieYy;
+	long ieYz;
+	/* Vz: roz */
+	long ioZx;
+	long ioZy;
+	long ioZz;
+	long ieZx;
+	long ieZy;
+	long ieZz;
+	/* P, Txx, Tyy, Tzz: lam, l2m */
+	long ioPx;
+	long ioPy;
+	long ioPz;
+	long iePx;
+	long iePy;
+	long iePz;
+	/* Txz, Txy, Tyz: muu */
+	long ioTx;
+	long ioTy;
+	long ioTz;
+	long ieTx;
+	long ieTy;
+	long ieTz;
+	/* attenuation / dissipative medium */
+	float Qp;
+	float Qs;
+	float fw;
+	float qr;
+} modPar;
+
+typedef struct _waveletPar { /* Wavelet Parameters */
+	char *file_src; /* general source */
+	long nsrcf;
+	long nt;
+	long ns;
+	long nx;
+	float dt;
+	float ds;
+	float fmax;
+	long random;
+	long seed;
+	long nst;
+	size_t *nsamp;
+} wavPar;
+
+typedef struct _sourcePar { /* Source Array Parameters */
+	long n;
+	long type;
+	long orient;
+	long *z;
+	long *y;
+	long *x;
+	long single;	
+	long plane;
+	long circle;
+	long array;
+	long random;
+	float *tbeg;
+	float *tend;
+	long multiwav;
+	float angle;
+	float velo;
+	float amplitude;
+	float dip;
+	float strike;
+	long distribution;
+	long window;
+    long injectionrate;
+	long sinkdepth;
+	long src_at_rcv; /* Indicates that wavefield should be injected at receivers */
+} srcPar;
+
+typedef struct _shotPar { /* Shot Parameters */
+	long n;
+	long *z;
+	long *y;
+	long *x;
+} shotPar;
+
+typedef struct _boundPar { /* Boundary Parameters */
+	long top;
+	long bot;
+	long lef;
+	long rig;
+	long fro;
+	long bac;
+	float *tapz;
+	float *tapy;
+	float *tapx;
+	float *tapxz;
+	float *tapxyz;
+	long cfree;
+	long ntap;
+	long *surface;
+    long npml;
+    float R; /* reflection at side of model */
+    float m; /* scaling order */
+    float *pml_Vx;
+		float *pml_Vy;
+    float *pml_nzVx;
+    float *pml_nxVz;
+    float *pml_nzVz;
+    float *pml_nxP;
+    float *pml_nzP;
+
+} bndPar;
+
+
+#if __STDC_VERSION__ >= 199901L
+  /* "restrict" is a keyword */
+#else
+#define restrict 
+#endif
+
diff --git a/fdelmodc3D/.vscode/ipch/11fe2e9e61e2b910/getParameters3D.ipch b/fdelmodc3D/.vscode/ipch/11fe2e9e61e2b910/getParameters3D.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..9cd31ffd6b9fcc59a5489c8d6fd0dfe4eaa9be80
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/11fe2e9e61e2b910/getParameters3D.ipch differ
diff --git a/fdelmodc3D/.vscode/ipch/16a260b5d7ee2f9d/recvPar3D2.ipch b/fdelmodc3D/.vscode/ipch/16a260b5d7ee2f9d/recvPar3D2.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..93d0ed663e6423b14cf069c548fcb6ce13be7a63
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/16a260b5d7ee2f9d/recvPar3D2.ipch differ
diff --git a/fdelmodc3D/.vscode/ipch/1a8c6c824f2eab6a/fdelmodc3D.ipch b/fdelmodc3D/.vscode/ipch/1a8c6c824f2eab6a/fdelmodc3D.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..c18c88f3757fe06614612656f3dcc51cb80c165d
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/1a8c6c824f2eab6a/fdelmodc3D.ipch differ
diff --git a/fdelmodc3D/.vscode/ipch/3ee1e657dc99568b/readShotData.ipch b/fdelmodc3D/.vscode/ipch/3ee1e657dc99568b/readShotData.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..1b9761865bfcba6ad4bda83ae325a747cf731f3e
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/3ee1e657dc99568b/readShotData.ipch differ
diff --git a/fdelmodc3D/.vscode/ipch/4830a1098baa3bdf/verbosepkg.ipch b/fdelmodc3D/.vscode/ipch/4830a1098baa3bdf/verbosepkg.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..8754327e6160df5786c792d568d3d98aa9fbe750
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/4830a1098baa3bdf/verbosepkg.ipch differ
diff --git a/fdelmodc3D/.vscode/ipch/48723368edd108e9/readModel3D.ipch b/fdelmodc3D/.vscode/ipch/48723368edd108e9/readModel3D.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..722c9dec70d66fae5eed6d22487bac9966c12c13
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/48723368edd108e9/readModel3D.ipch differ
diff --git a/fdelmodc3D/.vscode/ipch/526c4e54862923f9/acousticSH4_3D.ipch b/fdelmodc3D/.vscode/ipch/526c4e54862923f9/acousticSH4_3D.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..08df798b1fe724f614ba2e199dc63167d2a1bbf9
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/526c4e54862923f9/acousticSH4_3D.ipch differ
diff --git a/fdelmodc3D/.vscode/ipch/6745a5efb4bc7dd9/getModelInfo3D.ipch b/fdelmodc3D/.vscode/ipch/6745a5efb4bc7dd9/getModelInfo3D.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..cbcef594dda0c8db5ac6ac4c5ad43fe392b0785b
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/6745a5efb4bc7dd9/getModelInfo3D.ipch differ
diff --git a/fdelmodc3D/.vscode/ipch/831f69dbf595ea3a/fdelmodc3D.ipch b/fdelmodc3D/.vscode/ipch/831f69dbf595ea3a/fdelmodc3D.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..91123e7257f04aba13fff62dbc0537794a5d94ba
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/831f69dbf595ea3a/fdelmodc3D.ipch differ
diff --git a/fdelmodc3D/.vscode/ipch/83635c32f9f90e59/applySource3D.ipch b/fdelmodc3D/.vscode/ipch/83635c32f9f90e59/applySource3D.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..66978c0ab7005ef8556a75138dc02475062f7386
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/83635c32f9f90e59/applySource3D.ipch differ
diff --git a/fdelmodc3D/.vscode/ipch/847dd54c2b898c08/readData3D.ipch b/fdelmodc3D/.vscode/ipch/847dd54c2b898c08/readData3D.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..37fe75980cbc24c90748ef01ef63964fd1fd5090
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/847dd54c2b898c08/readData3D.ipch differ
diff --git a/fdelmodc3D/.vscode/ipch/9f2017a83bdbb877/writeSrcRecPos3D.ipch b/fdelmodc3D/.vscode/ipch/9f2017a83bdbb877/writeSrcRecPos3D.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..f62cd6c090a8f37985f80b57d36fd107c96a50a2
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/9f2017a83bdbb877/writeSrcRecPos3D.ipch differ
diff --git a/fdelmodc3D/.vscode/ipch/ac86bad5751142ef/recvPar3D.ipch b/fdelmodc3D/.vscode/ipch/ac86bad5751142ef/recvPar3D.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..90a29767bfad5b83aa1454dc1dbae7d2211d9f2c
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/ac86bad5751142ef/recvPar3D.ipch differ
diff --git a/fdelmodc3D/.vscode/ipch/ec7efccdebdf26ea/boundaries3D.ipch b/fdelmodc3D/.vscode/ipch/ec7efccdebdf26ea/boundaries3D.ipch
new file mode 100644
index 0000000000000000000000000000000000000000..ddf85fe31526697d617906063cf584f957b83435
Binary files /dev/null and b/fdelmodc3D/.vscode/ipch/ec7efccdebdf26ea/boundaries3D.ipch differ
diff --git a/fdelmodc3D/Makefile b/fdelmodc3D/Makefile
index 113490ac7ee23f7a5bdc045116630c21e2d926dc..6e103682a7d1295b5c5659b130004210b2e6a498 100644
--- a/fdelmodc3D/Makefile
+++ b/fdelmodc3D/Makefile
@@ -20,7 +20,11 @@ all: fdelmodc3D
 PRG = fdelmodc3D
 
 SRCC	= $(PRG).c \
+		acoustic2_3D.c \
 		acoustic4_3D.c \
+		acoustic6_3D.c \
+		acousticSH4_3D.c \
+		acoustic4_qr_3D.c \
 		defineSource3D.c  \
 		getParameters3D.c  \
 		getWaveletInfo3D.c  \
diff --git a/fdelmodc3D/acoustic2_3D.c b/fdelmodc3D/acoustic2_3D.c
new file mode 100644
index 0000000000000000000000000000000000000000..3793a59c72b62d68547ee636df9700f1da082bcd
--- /dev/null
+++ b/fdelmodc3D/acoustic2_3D.c
@@ -0,0 +1,201 @@
+#include<stdlib.h>
+#include<stdio.h>
+#include<math.h>
+#include<assert.h>
+#include"fdelmodc3D.h"
+
+long applySource3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime,
+    long ixsrc, long iysrc, long izsrc, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float **src_nwav, long verbose);
+
+long storeSourceOnSurface3D(modPar mod, srcPar src, bndPar bnd, long ixsrc, long iysrc, long izsrc,
+    float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx,
+    float *txz, float *txy, float *tyz, long verbose);
+
+long reStoreSourceOnSurface3D(modPar mod, srcPar src, bndPar bnd, long ixsrc, long iysrc, long izsrc,
+    float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx,
+    float *txz, float *txy, float *tyz, long verbose);
+
+long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul,
+    long itime, long verbose);
+
+long boundariesV3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul,
+    long itime, long verbose);
+
+long acoustic2_3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime,
+    long ixsrc, long iysrc, long izsrc, float **src_nwav, float *vx, float *vy, float *vz,
+    float *p, float *rox, float *roy, float *roz, float *l2m, long verbose)
+{
+
+/*********************************************************************
+       COMPUTATIONAL OVERVIEW OF THE 4th ORDER STAGGERED GRID: 
+
+  The captial symbols T (=Txx,Tzz) Txz,Vx,Vz represent the actual grid
+  The indices ix,iz are related to the T grid, so the capital T 
+  symbols represent the actual modelled grid.
+
+  one cel (iz,ix)
+       |
+       V                              extra column of vx,txz
+                                                      |
+    -------                                           V
+   | txz vz| txz vz  txz vz  txz vz  txz vz  txz vz txz
+   |       |      
+   | vx  t | vx  t   vx  t   vx  t   vx  t   vx  t  vx
+    -------
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz
+
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   | 
+     txz vz  txz Vz--Txz-Vz--Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   |
+     txz vz  txz Vz  Txz-Vz  Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   |
+     txz vz  txz Vz  Txz-Vz  Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz
+
+     vx  t   vx  t   vx  t   vx  t   vx  t   vx  t  vx
+
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz  <--| 
+                                                             |
+                                         extra row of txz/vz |
+
+
+   AUTHOR:
+           Jan Thorbecke (janth@xs4all.nl)
+           The Netherlands 
+
+***********************************************************************/
+
+	long    ix, iy, iz;
+	long    n1, n2;
+	long    ioXx, ioXy, ioXz, ioYx, ioYy, ioYz, ioZx, ioZy, ioZz, ioPx, ioPy, ioPz;
+	long    ieXx, ieXy, ieXz, ieYx, ieYy, ieYz, ieZx, ieZy, ieZz, iePx, iePy, iePz;
+
+	n1  = mod.naz;
+    n2  = mod.nax;
+
+	/* Vx: rox */
+	ioXx=mod.ioXx;
+	ioXy=mod.ioXy;
+	ioXz=mod.ioXz;
+	ieXx=mod.ieXx;
+	ieXy=mod.ieXy;
+	ieXz=mod.ieXz;
+	/* Vy: roy */
+	ioYx=mod.ioYx;
+	ioYy=mod.ioYy;
+	ioYz=mod.ioYz;
+	ieYx=mod.ieYx;
+	ieYy=mod.ieYy;
+	ieYz=mod.ieYz;
+	/* Vz: roz */
+	ioZx=mod.ioZx;
+	ioZy=mod.ioZy;
+	ioZz=mod.ioZz;
+	ieZx=mod.ieZx;
+	ieZy=mod.ieZy;
+	ieZz=mod.ieZz;
+	/* P, Txx, Tzz: lam, l2m */
+	ioPx=mod.ioPx;
+	ioPy=mod.ioPy;
+	ioPz=mod.ioPz;
+	iePx=mod.iePx;
+	iePy=mod.iePy;
+	iePz=mod.iePz;
+
+	/* calculate vx for all grid points except on the virtual boundary*/
+#pragma omp for private (ix, iy, iz) schedule(guided,1) 
+	for (iy=ioXy; iy<ieXy; iy++) {
+	    for (ix=ioXx; ix<ieXx; ix++) {
+            #pragma ivdep 
+            for (iz=ioXz; iz<ieXz; iz++) {
+                vx[iy*n2*n1+ix*n1+iz] -=
+                    rox[iy*n2*n1+ix*n1+iz]*(p[iy*n2*n1+ix*n1+iz] - p[iy*n2*n1+(ix-1)*n1+iz]);
+            }
+        }
+	}
+
+	/* calculate vy for all grid points except on the virtual boundary */
+#pragma omp for private (ix, iy, iz) schedule(guided,1) 
+	for (iy=ioYy; iy<ieYy; iy++) {
+        for (ix=ioYx; ix<ieYx; ix++) {
+            #pragma ivdep 
+            for (iz=ioYz; iz<ieYz; iz++) {
+                vy[iy*n2*n1+ix*n1+iz] -=
+                    roy[iy*n2*n1+ix*n1+iz]*(p[iy*n2*n1+ix*n1+iz] - p[(iy-1)*n2*n1+ix*n1+iz]);
+            }
+        }
+    }
+
+	/* calculate vz for all grid points except on the virtual boundary */
+#pragma omp for private (ix, iy, iz) schedule(guided,1) 
+	for (iy=ioZy; iy<ieZy; iy++) {
+        for (ix=ioZx; ix<ieZx; ix++) {
+            #pragma ivdep 
+            for (iz=ioZz; iz<ieZz; iz++) {
+                vz[iy*n2*n1+ix*n1+iz] -=
+                    roz[iy*n2*n1+ix*n1+iz]*(p[iy*n2*n1+ix*n1+iz] - p[iy*n2*n1+ix*n1+iz-1]);
+            }
+        }
+    }
+
+	/* boundary condition clears velocities on boundaries */
+    boundariesP3D(mod, bnd, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, NULL, NULL, itime, verbose);
+    
+
+	/* Add force source */
+	if (src.type > 5) {
+         applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, src_nwav, verbose);
+	}
+
+	/* this is needed because the P fields are not using tapered boundaries (bnd....=4) */
+    if (bnd.top==2) ioPz += bnd.npml;
+    if (bnd.bot==2) iePz -= bnd.npml;
+    if (bnd.fro==2) ioPy += bnd.npml;
+    if (bnd.bac==2) iePy -= bnd.npml;
+    if (bnd.lef==2) ioPx += bnd.npml;
+    if (bnd.rig==2) iePx -= bnd.npml;
+
+	/* calculate p/tzz for all grid points except on the virtual boundary */
+#pragma omp for private (ix, iy, iz) schedule(guided,1) 
+	for (iy=ioPy; iy<iePy; iy++) {
+	    for (ix=ioPx; ix<iePx; ix++) {
+            #pragma ivdep 
+            for (iz=ioPz; iz<iePz; iz++) {
+                p[iy*n2*n1+ix*n1+iz] -= l2m[iy*n2*n1+ix*n1+iz]*(
+                            (vx[iy*n2*n1+(ix+1)*n1+iz] - vx[iy*n2*n1+ix*n1+iz]) +
+                            (vy[(iy+1)*n2*n1+ix*n1+iz] - vy[iy*n2*n1+ix*n1+iz]) +
+                            (vz[iy*n2*n1+ix*n1+iz+1]   - vz[iy*n2*n1+ix*n1+iz]));
+            }
+        }
+	}
+
+	/* Add stress source */
+	if (src.type < 6) {
+        applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, src_nwav, verbose);
+	}
+
+	/* check if there are sources placed on the free surface */
+    storeSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, verbose);
+
+	/* Free surface: calculate free surface conditions for stresses */
+    boundariesV3D(mod, bnd, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, NULL, NULL, itime, verbose);
+
+	/* restore source positions on the edge */
+    reStoreSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, verbose);
+
+	return 0;
+}
diff --git a/fdelmodc3D/acoustic4_qr_3D.c b/fdelmodc3D/acoustic4_qr_3D.c
new file mode 100644
index 0000000000000000000000000000000000000000..08d8d1b4910d9040fdf756c84355ee9d326823eb
--- /dev/null
+++ b/fdelmodc3D/acoustic4_qr_3D.c
@@ -0,0 +1,320 @@
+#include<stdlib.h>
+#include<stdio.h>
+#include<math.h>
+#include<assert.h>
+#include"fdelmodc3D.h"
+
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+
+long applySource3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime,
+    long ixsrc, long iysrc, long izsrc, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float **src_nwav, long verbose);
+
+long storeSourceOnSurface3D(modPar mod, srcPar src, bndPar bnd, long ixsrc, long iysrc, long izsrc,
+    float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx,
+    float *txz, float *txy, float *tyz, long verbose);
+
+long reStoreSourceOnSurface3D(modPar mod, srcPar src, bndPar bnd, long ixsrc, long iysrc, long izsrc,
+    float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx,
+    float *txz, float *txy, float *tyz, long verbose);
+
+long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul,
+    long itime, long verbose);
+
+long boundariesV3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul,
+    long itime, long verbose);
+
+long acoustic4_qr_3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime, 
+    long ixsrc, long iysrc, long izsrc, float **src_nwav, float *vx, float *vy, float *vz,
+    float *p, float *rox, float *roy, float *roz, float *l2m, long verbose)
+{
+/*********************************************************************
+       COMPUTATIONAL OVERVIEW OF THE 4th ORDER STAGGERED GRID: 
+
+  The captial symbols T (=P) Txz,Vx,Vz represent the actual grid
+  The indices ix,iz are related to the T grid, so the capital T 
+  symbols represent the actual modelled grid.
+
+  one cel (iz,ix)
+       |
+       V                              extra column of vx,txz
+                                                      |
+    -------                                           V
+   | txz vz| txz vz  txz vz  txz vz  txz vz  txz vz txz
+   |       |      
+   | vx  t | vx  t   vx  t   vx  t   vx  t   vx  t  vx
+    -------
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz
+
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   | 
+     txz vz  txz Vz--Txz-Vz--Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   |
+     txz vz  txz Vz  Txz-Vz  Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   |
+     txz vz  txz Vz  Txz-Vz  Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz
+
+     vx  t   vx  t   vx  t   vx  t   vx  t   vx  t  vx
+
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz  <--| 
+                                                             |
+                                         extra row of txz/vz |
+
+   AUTHOR:
+           Jan Thorbecke (janth@xs4all.nl)
+           The Netherlands 
+
+***********************************************************************/
+
+	float   c1, c2, *timep;
+	long    ix, iy, iz, ib;
+	long    nx, ny, nz, n1, n2;
+	long    ioXx, ioXy, ioXz, ioYx, ioYy, ioYz, ioZx, ioZy, ioZz, ioPx, ioPy, ioPz, ioTx, ioTy, ioTz;
+	long    ieXx, ieXy, ieXz, ieYx, ieYy, ieYz, ieZx, ieZy, ieZz, iePx, iePy, iePz, ieTx, ieTy, ieTz;
+
+	c1 = 9.0/8.0; 
+	c2 = -1.0/24.0;
+	nx  = mod.nx;
+	ny  = mod.ny;
+	nz  = mod.nz;
+	n1  = mod.naz;
+	n2  = mod.nax;
+
+	timep=(float *) malloc(n1*sizeof(float));
+
+    /* Vx: rox */
+    ioXx=mod.iorder/2;
+    ioXy=mod.iorder/2-1;
+    ioXz=mod.iorder/2-1;
+    /* Vy: roy */
+    ioYx=mod.iorder/2-1;
+    ioYy=mod.iorder/2;
+    ioYz=mod.iorder/2-1;
+    /* Vz: roz */
+    ioZx=mod.iorder/2-1;
+    ioZy=mod.iorder/2-1;
+    ioZz=mod.iorder/2;
+    /* P, Txx, Tzz: lam, l2m */
+    ioPx=mod.iorder/2-1;
+    ioPy=ioPx;
+    ioPz=ioPx;
+    /* Txz: mul */
+    ioTx=mod.iorder/2;
+    ioTy=ioTx;
+    ioTz=ioTx;
+
+    /* Vx: rox */
+    ieXx=nx+ioXx;
+    ieXy=ny+ioXy;
+    ieXz=nz+ioXz;
+    /* Vx: rox */
+    ieYx=nx+ioYx;
+    ieYy=ny+ioYy;
+    ieYz=nz+ioYz;
+    /* Vz: roz */
+    ieZx=nx+ioZx;
+    ieZy=ny+ioZy;
+    ieZz=nz+ioZz;
+    /* P, Txx, Tzz: lam, l2m */
+    iePx=nx+ioPx;
+    iePy=ny+ioPy;
+    iePz=nz+ioPz;
+    /* Txz: muu */
+    ieTx=nx+ioTx;
+    ieTy=ny+ioTy;
+    ieTz=nz+ioTz;
+
+    if (bnd.top==4 || bnd.top==2) {
+        ieXz += bnd.ntap;
+        ieYz += bnd.ntap;
+        ieZz += bnd.ntap;
+        iePz += bnd.ntap;
+        ieTz += bnd.ntap;
+    }
+    if (bnd.bot==4 || bnd.bot==2) {
+        ieXz += bnd.ntap;
+        ieYz += bnd.ntap;
+        ieZz += bnd.ntap;
+        iePz += bnd.ntap;
+        ieTz += bnd.ntap;
+    }
+    if (bnd.fro==4 || bnd.fro==2) {
+        ieXy += bnd.ntap;
+        ieYy += bnd.ntap;
+        ieZy += bnd.ntap;
+        iePy += bnd.ntap;
+        ieTy += bnd.ntap;
+    }
+    if (bnd.bac==4 || bnd.bac==2) {
+        ieXy += bnd.ntap;
+        ieYy += bnd.ntap;
+        ieZy += bnd.ntap;
+        iePy += bnd.ntap;
+        ieTy += bnd.ntap;
+    }
+    if (bnd.lef==4 || bnd.lef==2) {
+        ieXx += bnd.ntap;
+        ieYx += bnd.ntap;
+        ieZx += bnd.ntap;
+        iePx += bnd.ntap;
+        ieTx += bnd.ntap;
+    }
+    if (bnd.rig==4 || bnd.rig==2) {
+        ieXx += bnd.ntap;
+        ieYx += bnd.ntap;
+        ieZx += bnd.ntap;
+        iePx += bnd.ntap;
+        ieTx += bnd.ntap;
+    }
+
+
+     if (itime == 0) {
+        fprintf(stderr,"ioXx=%li ieXx=%li\n", ioXx, ieXx);
+        fprintf(stderr,"ioYx=%li ieYx=%li\n", ioYx, ieYx);
+        fprintf(stderr,"ioZx=%li ieZx=%li\n", ioZx, ieZx);
+        fprintf(stderr,"ioPx=%li iePx=%li\n", ioPx, iePx);
+        fprintf(stderr,"ioTx=%li ieTx=%li\n", ioTx, ieTx);
+        
+        fprintf(stderr,"ioXy=%li ieXy=%li\n", ioXy, ieXy);
+        fprintf(stderr,"ioYy=%li ieYy=%li\n", ioYy, ieYy);
+        fprintf(stderr,"ioZy=%li ieZy=%li\n", ioZy, ieZy);
+        fprintf(stderr,"ioPy=%li iePy=%li\n", ioPy, iePy);
+        fprintf(stderr,"ioTy=%li ieTy=%li\n", ioTy, ieTy);
+        
+        fprintf(stderr,"ioXz=%li ieXz=%li\n", ioXz, ieXz);
+        fprintf(stderr,"ioYz=%li ieYz=%li\n", ioYz, ieYz);
+        fprintf(stderr,"ioZz=%li ieZz=%li\n", ioZz, ieZz);
+        fprintf(stderr,"ioPz=%li iePz=%li\n", ioPz, iePz);
+        fprintf(stderr,"ioTz=%li ieTz=%li\n", ioTz, ieTz);
+	}
+
+	/* calculate vx for all grid points except on the virtual boundary*/
+#pragma omp for private (ix, iy, iz) nowait
+	for (iy=ioXy; iy<ieXy; iy++) {
+	    for (ix=ioXx; ix<ieXx; ix++) {
+#pragma ivdep
+            for (iz=ioXz; iz<ieXz; iz++) {
+                timep[iz] = vx[iy*n2*n1+ix*n1+iz];
+            }
+#pragma ivdep
+            for (iz=ioXz; iz<ieXz; iz++) {
+                vx[iy*n2*n1+ix*n1+iz] -= rox[iy*n2*n1+ix*n1+iz]*(
+                    c1*(p[iy*n2*n1+ix*n1+iz]     - p[iy*n2*n1+(ix-1)*n1+iz]) +
+                    c2*(p[iy*n2*n1+(ix+1)*n1+iz] - p[iy*n2*n1+(ix-2)*n1+iz]));
+            }
+#pragma ivdep
+            for (iz=ioXz; iz<ieXz; iz++) {
+                vx[iy*n2*n1+ix*n1+iz] += 0.5*(vx[iy*n2*n1+ix*n1+iz]+timep[iz])*mod.qr;
+            }
+        }
+	}
+
+	/* calculate vy for all grid points except on the virtual boundary */
+#pragma omp for private (ix, iy, iz) 
+	for (iy=ioYy; iy<ieYy; iy++) { 
+	    for (ix=ioYx; ix<ieYx; ix++) {
+#pragma ivdep
+            for (iz=ioYz; iz<ieYz; iz++) {
+                timep[iz] = vy[iy*n2*n1+ix*n1+iz];
+            }
+#pragma ivdep
+            for (iz=ioYz; iz<ieYz; iz++) {
+                vy[iy*n2*n1+ix*n1+iz] -= roy[iy*n2*n1+ix*n1+iz]*(
+                            c1*(p[iy*n2*n1+ix*n1+iz]     - p[(iy-1)*n2*n1+ix*n1+iz]) +
+                            c2*(p[(iy+1)*n2*n1+ix*n1+iz] - p[(iy-2)*n2*n1+ix*n1+iz]));
+            }
+#pragma ivdep
+            for (iz=ioYz; iz<ieYz; iz++) {
+                vy[iy*n2*n1+ix*n1+iz] += 0.5*(vy[iy*n2*n1+ix*n1+iz]+timep[iz])*mod.qr;
+            }
+        }
+	}
+
+	/* calculate vz for all grid points except on the virtual boundary */
+#pragma omp for private (ix, iy, iz) 
+	for (iy=ioZy; iy<ieZy; iy++) { 
+	    for (ix=ioZx; ix<ieZx; ix++) {
+#pragma ivdep
+            for (iz=ioZz; iz<ieZz; iz++) {
+                timep[iz] = vz[iy*n2*n1+ix*n1+iz];
+            }
+#pragma ivdep
+            for (iz=ioZz; iz<ieZz; iz++) {
+                vz[iy*n2*n1+ix*n1+iz] -= roz[iy*n2*n1+ix*n1+iz]*(
+                            c1*(p[iy*n2*n1+ix*n1+iz]   - p[iy*n2*n1+ix*n1+iz-1]) +
+                            c2*(p[iy*n2*n1+ix*n1+iz+1] - p[iy*n2*n1+ix*n1+iz-2]));
+            }
+#pragma ivdep
+            for (iz=ioZz; iz<ieZz; iz++) {
+                vz[iy*n2*n1+ix*n1+iz] += 0.5*(vz[iy*n2*n1+ix*n1+iz]+timep[iz])*mod.qr;
+            }
+        }
+	}
+
+	/* boundary condition clears velocities on boundaries */
+    boundariesP3D(mod, bnd, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, NULL, NULL, itime, verbose);
+    
+
+	/* Add force source */
+	if (src.type > 5) {
+         applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, src_nwav, verbose);
+	}
+
+	/* calculate p/tzz for all grid points except on the virtual boundary */
+#pragma omp	for private (ix, iy, iz)
+	for (iy=ioPy; iy<iePy; iy++) {
+	    for (ix=ioPx; ix<iePx; ix++) {
+#pragma ivdep
+            for (iz=ioXz; iz<ieXz; iz++) {
+                timep[iz] = p[iy*n2*n1+ix*n1+iz];
+            }
+#pragma ivdep
+            for (iz=ioPz; iz<iePz; iz++) {
+                p[iy*n2*n1+ix*n1+iz] -= l2m[iy*n2*n1+ix*n1+iz]*(
+                            c1*(vx[iy*n2*n1+(ix+1)*n1+iz] - vx[iy*n2*n1+ix*n1+iz]) +
+                            c2*(vx[iy*n2*n1+(ix+2)*n1+iz] - vx[iy*n2*n1+(ix-1)*n1+iz]) +
+                            c1*(vy[(iy+1)*n2*n1+ix*n1+iz] - vy[iy*n2*n1+ix*n1+iz]) +
+                            c2*(vy[(iy+2)*n2*n1+ix*n1+iz] - vy[(iy-1)*n2*n1+ix*n1+iz]) +
+                            c1*(vz[iy*n2*n1+ix*n1+iz+1]   - vz[iy*n2*n1+ix*n1+iz]) +
+                            c2*(vz[iy*n2*n1+ix*n1+iz+2]   - vz[iy*n2*n1+ix*n1+iz-1]));
+            }
+#pragma ivdep
+            for (iz=ioXz; iz<ieXz; iz++) {
+                p[iy*n2*n1+ix*n1+iz] += 0.5*(p[iy*n2*n1+ix*n1+iz]+timep[iz])*mod.qr;
+            }
+        }
+	}
+
+	/* Add stress source */
+	if (src.type < 6) {
+        applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, src_nwav, verbose);
+	}
+
+/* Free surface: calculate free surface conditions for stresses */
+
+	/* check if there are sources placed on the free surface */
+    storeSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, verbose);
+
+	/* Free surface: calculate free surface conditions for stresses */
+    boundariesV3D(mod, bnd, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, NULL, NULL, itime, verbose);
+
+	/* restore source positions on the edge */
+    reStoreSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, verbose);
+
+	free(timep);
+
+	return 0;
+}
diff --git a/fdelmodc3D/acoustic6_3D.c b/fdelmodc3D/acoustic6_3D.c
new file mode 100644
index 0000000000000000000000000000000000000000..1ae3f359516d271ef583f621db30c5db67a97e30
--- /dev/null
+++ b/fdelmodc3D/acoustic6_3D.c
@@ -0,0 +1,218 @@
+#include<stdlib.h>
+#include<stdio.h>
+#include<math.h>
+#include<assert.h>
+#include"fdelmodc3D.h"
+
+long applySource3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime,
+    long ixsrc, long iysrc, long izsrc, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float **src_nwav, long verbose);
+
+long storeSourceOnSurface3D(modPar mod, srcPar src, bndPar bnd, long ixsrc, long iysrc, long izsrc,
+    float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx,
+    float *txz, float *txy, float *tyz, long verbose);
+
+long reStoreSourceOnSurface3D(modPar mod, srcPar src, bndPar bnd, long ixsrc, long iysrc, long izsrc,
+    float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx,
+    float *txz, float *txy, float *tyz, long verbose);
+
+long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul,
+    long itime, long verbose);
+
+long boundariesV3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul,
+    long itime, long verbose);
+
+long acoustic6_3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime,
+    long ixsrc, long iysrc, long izsrc, float **src_nwav, float *vx, float *vy, float *vz,
+    float *p, float *rox, float *roy, float *roz, float *l2m, long verbose)
+{
+/*********************************************************************
+       COMPUTATIONAL OVERVIEW OF THE 4th ORDER STAGGERED GRID: 
+
+  The captial symbols T (=Txx,Tzz) Txz,Vx,Vz represent the actual grid
+  The indices ix,iz are related to the T grid, so the capital T 
+  symbols represent the actual modelled grid.
+
+  one cel (iz,ix)
+       |
+       V                              extra column of vx,txz
+                                                      |
+    -------                                           V
+   | txz vz| txz vz  txz vz  txz vz  txz vz  txz vz txz
+   |       |      
+   | vx  t | vx  t   vx  t   vx  t   vx  t   vx  t  vx
+    -------
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz
+
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   | 
+     txz vz  txz Vz--Txz-Vz--Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   |
+     txz vz  txz Vz  Txz-Vz  Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   |
+     txz vz  txz Vz  Txz-Vz  Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz
+
+     vx  t   vx  t   vx  t   vx  t   vx  t   vx  t  vx
+
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz  <--| 
+                                                             |
+                                         extra row of txz/vz |
+
+   AUTHOR:
+           Jan Thorbecke (janth@xs4all.nl)
+           The Netherlands 
+
+***********************************************************************/
+
+	float   c1, c2, c3;
+	long    ix, iy, iz;
+	long    n1, n2;
+	long    ioXx, ioXy, ioXz, ioYx, ioYy, ioYz, ioZx, ioZy, ioZz, ioPx, ioPy, ioPz;
+	long    ieXx, ieXy, ieXz, ieYx, ieYy, ieYz, ieZx, ieZy, ieZz, iePx, iePy, iePz;
+
+
+	c1 = 75.0/64.0;
+	c2 = -25.0/384.0;
+	c3 = 3.0/640.0;
+	n1  = mod.naz;
+    n2  = mod.nax;
+
+    /* Vx: rox */
+	ioXx=mod.ioXx;
+	ioXy=mod.ioXy;
+	ioXz=mod.ioXz;
+	ieXx=mod.ieXx;
+	ieXy=mod.ieXy;
+	ieXz=mod.ieXz;
+	/* Vy: roy */
+	ioYx=mod.ioYx;
+	ioYy=mod.ioYy;
+	ioYz=mod.ioYz;
+	ieYx=mod.ieYx;
+	ieYy=mod.ieYy;
+	ieYz=mod.ieYz;
+	/* Vz: roz */
+	ioZx=mod.ioZx;
+	ioZy=mod.ioZy;
+	ioZz=mod.ioZz;
+	ieZx=mod.ieZx;
+	ieZy=mod.ieZy;
+	ieZz=mod.ieZz;
+	/* P, Txx, Tzz: lam, l2m */
+	ioPx=mod.ioPx;
+	ioPy=mod.ioPy;
+	ioPz=mod.ioPz;
+	iePx=mod.iePx;
+	iePy=mod.iePy;
+	iePz=mod.iePz;
+
+	/* calculate vx for all grid points except on the virtual boundary*/
+#pragma omp for private (ix, iy, iz) nowait
+	for (iy=ioXy; iy<ieXy; iy++) {
+	    for (ix=ioXx; ix<ieXx; ix++) {
+#pragma ivdep
+            for (iz=ioXz; iz<ieXz; iz++) {
+                vx[iy*n2*n1+ix*n1+iz] -= rox[iy*n2*n1+ix*n1+iz]*(
+                            c1*(p[iy*n2*n1+ix*n1+iz]     - p[iy*n2*n1+(ix-1)*n1+iz]) +
+                            c2*(p[iy*n2*n1+(ix+1)*n1+iz] - p[iy*n2*n1+(ix-2)*n1+iz]) +
+                            c3*(p[iy*n2*n1+(ix+2)*n1+iz] - p[iy*n2*n1+(ix-3)*n1+iz]));
+            }
+        }
+	}
+
+	/* calculate vy for all grid points except on the virtual boundary */
+#pragma omp for private (ix, iy, iz) 
+	for (iy=ioYy; iy<ieYy; iy++) {
+	    for (ix=ioYx; ix<ieYx; ix++) {
+#pragma ivdep
+            for (iz=ioYz; iz<ieYz; iz++) {
+                vy[iy*n2*n1+ix*n1+iz] -= roy[iy*n2*n1+ix*n1+iz]*(
+                            c1*(p[iy*n2*n1+ix*n1+iz]     - p[(iy-1)*n2*n1+ix*n1+iz]) +
+                            c2*(p[(iy+1)*n2*n1+ix*n1+iz] - p[(iy-2)*n2*n1+ix*n1+iz]) +
+                            c3*(p[(iy+2)*n2*n1+ix*n1+iz] - p[(iy-3)*n2*n1+ix*n1+iz]));
+            }
+        }
+	}
+
+	/* calculate vz for all grid points except on the virtual boundary */
+#pragma omp for private (ix, iy, iz) 
+	for (iy=ioZy; iy<ieZy; iy++) {
+	    for (ix=ioZx; ix<ieZx; ix++) {
+#pragma ivdep
+            for (iz=ioZz; iz<ieZz; iz++) {
+                vz[iy*n2*n1+ix*n1+iz] -= roz[iy*n2*n1+ix*n1+iz]*(
+                            c1*(p[iy*n2*n1+ix*n1+iz]   - p[iy*n2*n1+ix*n1+iz-1]) +
+                            c2*(p[iy*n2*n1+ix*n1+iz+1] - p[iy*n2*n1+ix*n1+iz-2]) +
+                            c3*(p[iy*n2*n1+ix*n1+iz+2] - p[iy*n2*n1+ix*n1+iz-3]));
+            }
+        }
+	}
+
+	/* boundary condition clears velocities on boundaries */
+    boundariesP3D(mod, bnd, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, NULL, NULL, itime, verbose);
+    
+
+	/* Add force source */
+	if (src.type > 5) {
+         applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, src_nwav, verbose);
+	}
+
+    /* this is needed because the P fields are not using tapered boundaries (bnd....=4) */
+    if (bnd.top==2) ioPz += bnd.npml;
+    if (bnd.bot==2) iePz -= bnd.npml;
+    if (bnd.fro==2) ioPy += bnd.npml;
+    if (bnd.bac==2) iePy -= bnd.npml;
+    if (bnd.lef==2) ioPx += bnd.npml;
+    if (bnd.rig==2) iePx -= bnd.npml;
+
+	/* calculate p/tzz for all grid points except on the virtual boundary */
+#pragma omp for private (ix, iy, iz) 
+	for (iy=ioPy; iy<iePy; iy++) {
+	    for (ix=ioPx; ix<iePx; ix++) {
+#pragma ivdep
+            for (iz=ioPz; iz<iePz; iz++) {
+                p[iy*n2*n1+ix*n1+iz] -= l2m[iy*n2*n1+ix*n1+iz]*(
+                            c1*(vx[iy*n2*n1+(ix+1)*n1+iz] - vx[iy*n2*n1+ix*n1+iz]) +
+                            c2*(vx[iy*n2*n1+(ix+2)*n1+iz] - vx[iy*n2*n1+(ix-1)*n1+iz]) +
+                            c3*(vx[iy*n2*n1+(ix+3)*n1+iz] - vx[iy*n2*n1+(ix-2)*n1+iz]) +
+                            c1*(vy[(iy+1)*n2*n1+ix*n1+iz] - vy[iy*n2*n1+ix*n1+iz]) +
+                            c2*(vy[(iy+2)*n2*n1+ix*n1+iz] - vy[(iy-1)*n2*n1+ix*n1+iz]) +
+                            c3*(vy[(iy+3)*n2*n1+ix*n1+iz] - vy[(iy-2)*n2*n1+ix*n1+iz]) +
+                            c1*(vz[iy*n2*n1+ix*n1+iz+1]   - vz[iy*n2*n1+ix*n1+iz]) +
+                            c2*(vz[iy*n2*n1+ix*n1+iz+2]   - vz[iy*n2*n1+ix*n1+iz-1]) +
+                            c3*(vz[iy*n2*n1+ix*n1+iz+3]   - vz[iy*n2*n1+ix*n1+iz-2]));
+            }
+        }
+	}
+
+	/* Add stress source */
+	if (src.type < 6) {
+        applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, src_nwav, verbose);
+	}
+
+/* Free surface: calculate free surface conditions for stresses */
+
+	/* check if there are sources placed on the free surface */
+    storeSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, verbose);
+
+	/* Free surface: calculate free surface conditions for stresses */
+    boundariesV3D(mod, bnd, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, NULL, NULL, itime, verbose);
+
+	/* restore source positions on the edge */
+    reStoreSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, verbose);
+
+	return 0;
+}
diff --git a/fdelmodc3D/acousticSH4_3D.c b/fdelmodc3D/acousticSH4_3D.c
new file mode 100644
index 0000000000000000000000000000000000000000..dc7c5648e0ce178afdb04a14bed3c4f985398071
--- /dev/null
+++ b/fdelmodc3D/acousticSH4_3D.c
@@ -0,0 +1,202 @@
+#include<stdlib.h>
+#include<stdio.h>
+#include<math.h>
+#include<assert.h>
+#include"fdelmodc3D.h"
+
+long applySource3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime,
+    long ixsrc, long iysrc, long izsrc, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float **src_nwav, long verbose);
+
+long storeSourceOnSurface3D(modPar mod, srcPar src, bndPar bnd, long ixsrc, long iysrc, long izsrc,
+    float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx,
+    float *txz, float *txy, float *tyz, long verbose);
+
+long reStoreSourceOnSurface3D(modPar mod, srcPar src, bndPar bnd, long ixsrc, long iysrc, long izsrc,
+    float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx,
+    float *txz, float *txy, float *tyz, long verbose);
+
+long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul,
+    long itime, long verbose);
+
+long boundariesV3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul,
+    long itime, long verbose);
+
+long acousticSH4_3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime,
+	long ixsrc, long iysrc, long izsrc, float **src_nwav, float *tx, float *ty, float *tz,
+	float *vz, float *rox, float *roy, float *roz, float *mul, long verbose)
+{
+/*********************************************************************
+       COMPUTATIONAL OVERVIEW OF THE 4th ORDER STAGGERED GRID: 
+
+  The captial symbols T (=Txx,Tzz) Txz,Vx,Vz represent the actual grid
+  The indices ix,iz are related to the T grid, so the capital T 
+  symbols represent the actual modelled grid.
+
+  one cel (iz,ix)
+       |
+       V                              extra column of vx,txz
+                                                      |
+    -------                                           V
+   | txz vz| txz vz  txz vz  txz vz  txz vz  txz vz txz
+   |       |      
+   | vx  t | vx  t   vx  t   vx  t   vx  t   vx  t  vx
+    -------
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz
+
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   | 
+     txz vz  txz Vz--Txz-Vz--Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   |
+     txz vz  txz Vz  Txz-Vz  Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   |
+     txz vz  txz Vz  Txz-Vz  Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz
+
+     vx  t   vx  t   vx  t   vx  t   vx  t   vx  t  vx
+
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz  <--| 
+                                                             |
+                                         extra row of txz/vz |
+
+   AUTHOR:
+           Jan Thorbecke (janth@xs4all.nl)
+           The Netherlands 
+
+***********************************************************************/
+
+	float	c1, c2;
+	long	ix, iy, iz;
+	long	n1, n2;
+	long	ioXx, ioXy, ioXz, ioYx, ioYy, ioYz, ioZx, ioZy, ioZz, ioPx, ioPy, ioPz;
+	long	ieXx, ieXy, ieXz, ieYx, ieYy, ieYz, ieZx, ieZy, ieZz, iePx, iePy, iePz;
+
+	c1 = 9.0/8.0; 
+	c2 = -1.0/24.0;
+	n1  = mod.naz;
+	n2  = mod.nax;
+
+	/* Vx: rox */
+	ioXx=mod.ioXx;
+	ioXy=mod.ioXy;
+	ioXz=mod.ioXz;
+	ieXx=mod.ieXx;
+	ieXy=mod.ieXy;
+	ieXz=mod.ieXz;
+	/* Vy: roy */
+	ioYx=mod.ioYx;
+	ioYy=mod.ioYy;
+	ioYz=mod.ioYz;
+	ieYx=mod.ieYx;
+	ieYy=mod.ieYy;
+	ieYz=mod.ieYz;
+	/* Vz: roz */
+	ioZx=mod.ioZx;
+	ioZy=mod.ioZy;
+	ioZz=mod.ioZz;
+	ieZx=mod.ieZx;
+	ieZy=mod.ieZy;
+	ieZz=mod.ieZz;
+	/* P, Txx, Tzz: lam, l2m */
+	ioPx=mod.ioPx;
+	ioPy=mod.ioPy;
+	ioPz=mod.ioPz;
+	iePx=mod.iePx;
+	iePy=mod.iePy;
+	iePz=mod.iePz;
+
+	/* calculate vx for all grid points except on the virtual boundary*/
+#pragma omp for private (ix, iy, iz) nowait
+	for (iy=ioXy; iy<ieXy; iy++) {
+		for (ix=ioXx; ix<ieXx; ix++) {
+#pragma ivdep
+			for (iz=ioXz; iz<ieXz; iz++) {
+				tx[iy*n2*n1+ix*n1+iz] -= mul[iy*n2*n1+ix*n1+iz]*(
+							c1*(vz[iy*n2*n1+ix*n1+iz]     - vz[iy*n2*n1+(ix-1)*n1+iz]) +
+							c2*(vz[iy*n2*n1+(ix+1)*n1+iz] - vz[iy*n2*n1+(ix-2)*n1+iz]));
+			}
+		}
+	}
+
+	/* calculate vy for all grid points except on the virtual boundary */
+#pragma omp for private (ix, iy, iz) 
+	for (iy=ioYy; iy<ieYy; iy++) {
+		for (ix=ioYx; ix<ieYx; ix++) {
+#pragma ivdep
+			for (iz=ioYz; iz<ieYz; iz++) {
+				ty[iy*n2*n1+ix*n1+iz] -= mul[iy*n2*n1+ix*n1+iz]*(
+							c1*(vz[iy*n2*n1+ix*n1+iz]     - vz[(iy-1)*n2*n1+ix*n1+iz]) +
+							c2*(vz[(iy+1)*n2*n1+ix*n1+iz] - vz[(iy-2)*n2*n1+ix*n1+iz]));
+			}
+		}
+	}
+
+	/* calculate vz for all grid points except on the virtual boundary */
+#pragma omp for private (ix, iy, iz) 
+	for (iy=ioZy; iy<ieZy; iy++) {
+		for (ix=ioZx; ix<ieZx; ix++) {
+#pragma ivdep
+			for (iz=ioZz; iz<ieZz; iz++) {
+				tz[iy*n2*n1+ix*n1+iz] -= mul[iy*n2*n1+ix*n1+iz]*(
+							c1*(vz[iy*n2*n1+ix*n1+iz]   - vz[iy*n2*n1+ix*n1+iz-1]) +
+							c2*(vz[iy*n2*n1+ix*n1+iz+1] - vz[iy*n2*n1+ix*n1+iz-2]));
+			}
+		}
+	}
+
+	/* boundary condition clears velocities on boundaries */
+    boundariesP3D(mod, bnd, tx, ty, tz, vz, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, mul, NULL, NULL, itime, verbose);
+    
+
+	/* Add force source */
+	if (src.type > 5) {
+         applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, tx, ty, tz, vz, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, mul, src_nwav, verbose);
+	}
+
+	/* calculate p/tzz for all grid points except on the virtual boundary */
+#pragma omp	for private (ix, iy, iz)
+	for (iy=ioPy; iy<iePy; iy++) {
+		for (ix=ioPx; ix<iePx; ix++) {
+#pragma ivdep
+			for (iz=ioPz; iz<iePz; iz++) {
+				vz[iy*n2*n1+ix*n1+iz] -= rox[iy*n2*n1+ix*n1+iz]*(
+							c1*(tx[iy*n2*n1+(ix+1)*n1+iz] - tx[iy*n2*n1+ix*n1+iz]) +
+							c2*(tx[iy*n2*n1+(ix+2)*n1+iz] - tx[iy*n2*n1+(ix-1)*n1+iz]) +
+							c1*(ty[iy*n2*n1+(ix+1)*n1+iz] - ty[iy*n2*n1+ix*n1+iz]) +
+							c2*(ty[iy*n2*n1+(ix+2)*n1+iz] - ty[iy*n2*n1+(ix-1)*n1+iz]) +
+							c1*(tz[iy*n2*n1+ix*n1+iz+1]   - tz[iy*n2*n1+ix*n1+iz]) +
+							c2*(tz[iy*n2*n1+ix*n1+iz+2]   - tz[iy*n2*n1+ix*n1+iz-1]));
+			}
+		}
+	}
+
+	/* Add stress source */
+	if (src.type < 6) {
+		 applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, tx, ty, tz, vz, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, mul, src_nwav, verbose);
+	}
+    
+/* Free surface: calculate free surface conditions for stresses */
+
+	/* check if there are sources placed on the free surface */
+	storeSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, tx, ty, tz, vz, NULL, NULL, NULL, NULL, NULL, verbose);
+
+	/* Free surface: calculate free surface conditions for stresses */
+	boundariesV3D(mod, bnd, tx, ty, tz, vz, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, mul, NULL, NULL, itime, verbose);
+
+	/* restore source positions on the edge */
+	reStoreSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, tx, ty, tz, vz, NULL, NULL, NULL, NULL, NULL, verbose);
+
+	return 0;
+}
diff --git a/fdelmodc3D/applySource3D.c b/fdelmodc3D/applySource3D.c
index 6c526632f056482622f36129b9fa3ed2fc85519b..fa6437dab6aea1d48056c02a62228145728b9816 100644
--- a/fdelmodc3D/applySource3D.c
+++ b/fdelmodc3D/applySource3D.c
@@ -146,7 +146,7 @@ long applySource3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime, l
 
 /* in older version added factor 2.0 to be compliant with defined Green's functions in Marchenko algorithm */
 /* this is now set to 1.0 */
-		src_ampl *= (1.0/mod.dx)*l2m[iy*n1*n2+ix*n1+iz];
+		src_ampl *= (1.0/(mod.dx*mod.dx))*l2m[iy*n1*n2+ix*n1+iz];
 
 		if (verbose>5) {
 			vmess("Source %li at grid [ix=%li,iy=%li,iz=%li] at itime %li has value %e",isrc, ix, iy, iz, itime, src_ampl);
diff --git a/fdelmodc3D/boundaries3D.c b/fdelmodc3D/boundaries3D.c
index 1fa97c4e9007a77a26dbf730e115db4b1d0bd3ad..180e774d6ae6be26f7d07f14bfd3aef92eaeb617 100644
--- a/fdelmodc3D/boundaries3D.c
+++ b/fdelmodc3D/boundaries3D.c
@@ -9,6 +9,42 @@ void vmess(char *fmt, ...);
 long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz, float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul, long itime, long verbose)
 {
 /*********************************************************************
+Joeri's original filling order
+26 minicubes ordered as x-y-z
+x can be left, mid, right
+y can be top, mid, bottom
+z can be front, mid, back
+
+Code ordering:
+TOP 	mid		top 	mid
+		right 	top 	mid
+		right 	top 	back 
+		left  	top 	mid
+		left 	top 	front
+		left 	top 	back
+		mid 	top 	front
+		mid 	top 	back
+
+BOTTOM 	mid  	bottom 	mid
+		right 	bottom 	mid
+		right 	bottom 	front
+		right 	bottom 	back
+		left 	bottom 	mid
+		left 	bottom 	front
+		left 	bottom 	back
+		mid 	bottom 	front
+		mid 	bottom 	back
+
+MID 	left 	mid 	mid
+		left 	mid 	front
+		left 	mid 	back
+		right 	mid 	mid
+		right 	mid 	front
+		right 	mid 	back 
+		mid 	mid 	front
+		mid 	mid 	back
+
+26*3 minicubes total (vz, vx, vy).
 
    AUTHOR:
 		   Jan Thorbecke (janth@xs4all.nl)
@@ -173,6 +209,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 		if (mod.ischeme <= 2) { /* Acoustic scheme */
 			
 			/* Vx field */
+			/* mid top mid vx */
 			ixo = mod.ioXx;
 			ixe = mod.ieXx;
 			iyo = mod.ioXy;
@@ -180,7 +217,6 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			izo = mod.ioXz-bnd.ntap;
 			ize = mod.ioXz;
 	
-
 			ibz = (bnd.ntap+izo-1);
 #pragma omp for private(ix,iy,iz)
 			for (ix=ixo; ix<ixe; ix++) {
@@ -198,7 +234,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			}
 
 
-			/* right top corner */
+			/* right top mid corner vx */
 			if (bnd.rig==4) {
 				ixo = mod.ieXx;
 				ixe = mod.ieXx+bnd.ntap;
@@ -220,7 +256,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 				}
 
 
-				/* right top front corner */
+				/* right top front corner vx */
 				if (bnd.fro==4) {
 					iyo = mod.ioXy-bnd.ntap;
 					iye = mod.ioXy;
@@ -242,7 +278,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 				}
 		
 		
-				/* right top back corner */
+				/* right top back corner vx */
 				if (bnd.bac==4) {
 					iyo = mod.ieXy;
 					iye = mod.ieXy+bnd.ntap;
@@ -271,7 +307,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			izo = mod.ioXz-bnd.ntap;
 			ize = mod.ioXz;
 
-			/* left top corner */
+			/* left top mid corner vx */
 			if (bnd.lef==4) {
 				ixo = mod.ioXx-bnd.ntap;
 				ixe = mod.ioXx;
@@ -292,7 +328,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 
-				/* left top front corner */
+				/* left top front corner vx */
 				if (bnd.fro==4) {
 					iyo = mod.ioXy-bnd.ntap;
 					iye = mod.ioXy;
@@ -314,7 +350,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 				}
 
 
-				/* left top back corner */
+				/* left top back corner vx */
 				if (bnd.bac==4) {
 					iyo = mod.ieXy;
 					iye = mod.ieXy+bnd.ntap;
@@ -337,7 +373,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			}
 
 
-			/* front top corner */
+			/* mid top front corner vx */
 			if (bnd.fro==4) {
 				ixo = mod.ioXx;
 				ixe = mod.ieXx;
@@ -362,7 +398,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			}
 
 
-			/* Back top corner */
+			/* mid top back corner vx */
 			if (bnd.bac==4) {
 				iyo = mod.ieXy;
 				iye = mod.ieXy+bnd.ntap;
@@ -386,6 +422,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 	
 
 			/* Vy field */
+			/* mid top mid vy */
 			ixo = mod.ioYx;
 			ixe = mod.ieYx;
 			iyo = mod.ioYy;
@@ -410,7 +447,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			}
 	
 
-			/* right top corner */
+			/* right top mid corner vy */
 			if (bnd.rig==4) {
 				ixo = mod.ieYx;
 				ixe = mod.ieYx+bnd.ntap;
@@ -430,7 +467,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 						}
 					}
 				}
-				/* right top front corner */
+				/* right top front corner vy */
 				if (bnd.fro==4) {
 					iyo = mod.ioYy-bnd.ntap;
 					iye = mod.ioYy;
@@ -453,7 +490,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 
 	
 
-				/* right top back corner */
+				/* right top back corner vy */
 				if (bnd.bac==4) {
 					iyo = mod.ieYy;
 					iye = mod.ieYy+bnd.ntap;
@@ -482,7 +519,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			ize = mod.ioYz;
 
 
-			/* left top corner */
+			/* left top mid corner vy */
 			if (bnd.lef==4) {
 				ixo = mod.ioYx-bnd.ntap;
 				ixe = mod.ioYx;
@@ -502,7 +539,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 
-				/* left top front corner */
+				/* left top front corner vy */
 				if (bnd.fro==4) {
 					iyo = mod.ioYy-bnd.ntap;
 					iye = mod.ioYy;
@@ -522,7 +559,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 
-				/* left top back corner */
+				/* left top back corner vy */
 				if (bnd.bac==4) {
 					iyo = mod.ieYy;
 					iye = mod.ieYy+bnd.ntap;
@@ -542,7 +579,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* front top corner */
+			/* front top mid corner vy */
 			if (bnd.fro==4) {
 				ixo = mod.ioYx;
 				ixe = mod.ieYx;
@@ -564,7 +601,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* Back top corner */
+			/* back top mid corner vy */
 			if (bnd.bac==4) {
 				iyo = mod.ieYy;
 				iye = mod.ieYy+bnd.ntap;
@@ -587,6 +624,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 
 
 			/* Vz field */
+			/* mid top mid vz*/
 			ixo = mod.ioZx;
 			ixe = mod.ieZx;
 			iyo = mod.ioZy;
@@ -608,7 +646,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* right top corner */
+			/* right top mid corner vz */
 			if (bnd.rig==4) {
 				ixo = mod.ieZx;
 				ixe = ixo+bnd.ntap;
@@ -627,7 +665,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 						}
 					}
 				}
-				/* right top front corner */
+				/* right top front corner vz */
 				if (bnd.fro==4) {
 					iyo = mod.ioZy-bnd.ntap;
 					iye = mod.ioZy;
@@ -646,7 +684,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 						}
 					}
 				}
-				/* right top back corner */
+				/* right top back corner vz */
 				if (bnd.bac==4) {
 					iyo = mod.ieZy;
 					iye = mod.ieZy+bnd.ntap;
@@ -674,7 +712,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			izo = mod.ioZz-bnd.ntap;
 			ize = mod.ioZz;
 
-			/* left top corner */
+			/* left top mid corner vz */
 			if (bnd.lef==4) {
 				ixo = mod.ioZx-bnd.ntap;
 				ixe = mod.ioZx;
@@ -683,15 +721,17 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 #pragma omp for private(ix,iy,iz)
 				for (ix=ixo; ix<ixe; ix++) {
 #pragma ivdep
-					for (iz=izo; iz<ize; iz++) {
-						vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*(
-									c1*(tzz[iy*n1*n2+ix*n1+iz]   - tzz[iy*n1*n2+ix*n1+iz-1]) +
-									c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2]));
-						
-						vz[iy*n1*n2+ix*n1+iz]   *= bnd.tapxz[(ibx-ix)*bnd.ntap+(ibz-iz)];
+					for (iy=iyo; iy<iye; iy++) {
+						for (iz=izo; iz<ize; iz++) {
+							vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*(
+										c1*(tzz[iy*n1*n2+ix*n1+iz]   - tzz[iy*n1*n2+ix*n1+iz-1]) +
+										c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2]));
+							
+							vz[iy*n1*n2+ix*n1+iz]   *= bnd.tapxz[(ibx-ix)*bnd.ntap+(ibz-iz)];
+						}
 					}
 				}
-				/* left top front corner */
+				/* left top front corner vz */
 				if (bnd.fro==4) {
 					iyo = mod.ioZy-bnd.ntap;
 					iye = mod.ioZy;
@@ -705,12 +745,12 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 											c1*(tzz[iy*n1*n2+ix*n1+iz]	 - tzz[iy*n1*n2+ix*n1+iz-1]) +
 											c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2]));
 			
-								vz[iy*n1*n2+ix*n1+iz]   *= bnd.tapxyz[(iby-iy)*(bnd.ntap)*(bnd.ntap)+(ibx-ix)*bnd.ntap+(ibz-iz)];
+								vz[iy*n1*n2+ix*n1+iz]   *= bnd.tapxyz[(iby-iy)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(ibz-iz)];
 							}
 						}
 					}
 				}
-				/* left top back corner */
+				/* left top back corner vz */
 				if (bnd.bac==4) {
 					iyo = mod.ieZy;
 					iye = mod.ieZy+bnd.ntap;
@@ -724,13 +764,13 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 											c1*(tzz[iy*n1*n2+ix*n1+iz]	 - tzz[iy*n1*n2+ix*n1+iz-1]) +
 											c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2]));
 			
-								vz[iy*n1*n2+ix*n1+iz]   *= bnd.tapxyz[(iy-iby)*(bnd.ntap)*(bnd.ntap)+(ibx-ix)*bnd.ntap+(ibz-iz)];
+								vz[iy*n1*n2+ix*n1+iz]   *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(ibz-iz)];
 							}
 						}
 					}
 				}
 			}
-			/* front top corner */
+			/* mid top front corner vz */
 			if (bnd.fro==4) {
 				ixo = mod.ioZx;
 				ixe = mod.ieZx;
@@ -752,7 +792,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* Back top corner */
+			/* mid top back corner vz */
 			if (bnd.bac==4) {
 				iyo = mod.ieZy;
 				iye = mod.ieZy+bnd.ntap;
@@ -784,6 +824,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 		if (mod.ischeme <= 2) { /* Acoustic scheme */
 			
 			/* Vx field */
+			/* mid bottom mid vx*/
 			ixo = mod.ioXx;
 			ixe = mod.ieXx;
 			iyo = mod.ioXy;
@@ -805,7 +846,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* right bottom corner */
+			/* right bottom mid corner vx */
 			if (bnd.rig==4) {
 				ixo = mod.ieXx;
 				ixe = mod.ieXx+bnd.ntap;
@@ -824,7 +865,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 						}
 					}
 				}
-				/* right bottom front corner */
+				/* right bottom front corner vx */
 				if (bnd.fro==4) {
 					iyo = mod.ioXy-bnd.ntap;
 					iye = mod.ioXy;
@@ -843,7 +884,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 						}
 					}
 				}
-				/* right bottom back corner */
+				/* right bottom back corner vx */
 				if (bnd.bac==4) {
 					iyo = mod.ieXy;
 					iye = mod.ieXy+bnd.ntap;
@@ -871,7 +912,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			izo = mod.ieXz;
 			ize = mod.ieXz+bnd.ntap;
 
-			/* left bottom corner */
+			/* left bottom mid corner vx*/
 			if (bnd.lef==4) {
 				ixo = mod.ioXx-bnd.ntap;
 				ixe = mod.ioXx;
@@ -890,7 +931,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 						}
 					}
 				}
-				/* left bottom front corner */
+				/* left bottom front corner vx */
 				if (bnd.fro==4) {
 					iyo = mod.ioXy-bnd.ntap;
 					iye = mod.ioXy;
@@ -909,7 +950,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 						}
 					}
 				}
-				/* left bottom back corner */
+				/* left bottom back corner vx*/
 				if (bnd.bac==4) {
 					iyo = mod.ieXy;
 					iye = mod.ieXy+bnd.ntap;
@@ -929,7 +970,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* front bottom corner */
+			/* mid bottom front corner vx */
 			if (bnd.fro==4) {
 				ixo = mod.ioXx;
 				ixe = mod.ieXx;
@@ -951,7 +992,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* Back bottom corner */
+			/*  mid bottom back corner vx */
 			if (bnd.bac==4) {
 				iyo = mod.ieXy;
 				iye = mod.ieXy+bnd.ntap;
@@ -974,6 +1015,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 
 
 			/* Vy field */
+			/* mid bottom mid vy */
 			ixo = mod.ioYx;
 			ixe = mod.ieYx;
 			iyo = mod.ioYy;
@@ -981,7 +1023,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			izo = mod.ieYz;
 			ize = mod.ieYz+bnd.ntap;
 	
-			ib = (bnd.ntap+izo-1);
+			ib = (ize-bnd.ntap);
 #pragma omp for private(ix,iy,iz)
 			for (ix=ixo; ix<ixe; ix++) {
 #pragma ivdep
@@ -995,7 +1037,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* right bottom corner */
+			/* right bottom mid corner vy */
 			if (bnd.rig==4) {
 				ixo = mod.ieYx;
 				ixe = ixo+bnd.ntap;
@@ -1014,7 +1056,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 						}
 					}
 				}
-				/* right bottom front corner */
+				/* right bottom front corner vy */
 				if (bnd.fro==4) {
 					iyo = mod.ioYy-bnd.ntap;
 					iye = mod.ioYy;
@@ -1033,7 +1075,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 						}
 					}
 				}
-				/* right bottom back corner */
+				/* right bottom back corner vy */
 				if (bnd.bac==4) {
 					iyo = mod.ieYy;
 					iye = mod.ieYy+bnd.ntap;
@@ -1057,10 +1099,10 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			ixe = mod.ieYx;
 			iyo = mod.ioYy;
 			iye = mod.ieYy;
-			izo = mod.ioYz;
-			ize = mod.ioYz+bnd.ntap;
+			izo = mod.ieYz;
+			ize = mod.ieYz+bnd.ntap;
 
-			/* left bottom corner */
+			/* left bottom mid corner vy */
 			if (bnd.lef==4) {
 				ixo = mod.ioYx-bnd.ntap;
 				ixe = mod.ioYx;
@@ -1079,7 +1121,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 						}
 					}
 				}
-				/* left bottom front corner */
+				/* left bottom front corner vy */
 				if (bnd.fro==4) {
 					iyo = mod.ioYy-bnd.ntap;
 					iye = mod.ioYy;
@@ -1098,7 +1140,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 						}
 					}
 				}
-				/* left bottom back corner */
+				/* left bottom back corner vy */
 				if (bnd.bac==4) {
 					iyo = mod.ieYy;
 					iye = mod.ieYy+bnd.ntap;
@@ -1118,7 +1160,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* front bottom corner */
+			/* mid bottom front corner vy */
 			if (bnd.fro==4) {
 				ixo = mod.ioYx;
 				ixe = mod.ieYx;
@@ -1140,7 +1182,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* Back bottom corner */
+			/* mid bottom back corner vy */
 			if (bnd.bac==4) {
 				iyo = mod.ieYy;
 				iye = mod.ieYy+bnd.ntap;
@@ -1247,6 +1289,14 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
+			
+			ixo = mod.ioZx;
+			ixe = mod.ieZx;
+			iyo = mod.ioZy;
+			iye = mod.ieZy;
+			izo = mod.ieZz;
+			ize = mod.ieZz+bnd.ntap;
+
 			/* left bottom corner */
 			if (bnd.lef==4) {
 				ixo = mod.ioZx-bnd.ntap;
@@ -1274,7 +1324,6 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					iby = (bnd.ntap+iyo-1);
 #pragma omp for private(ix,iy,iz)
 					for (ix=ixo; ix<ixe; ix++) {
-//#pragma ivdep
 						for (iy=iyo; iy<iye; iy++) {
 							#pragma ivdep
 							for (iz=izo; iz<ize; iz++) {
@@ -1297,11 +1346,11 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 #pragma ivdep
 						for (iy=iyo; iy<iye; iy++) {
 							for (iz=izo; iz<ize; iz++) {
-								vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*(
+								vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*(
 											c1*(tzz[iy*n1*n2+ix*n1+iz]	 - tzz[iy*n1*n2+ix*n1+iz-1]) +
 											c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2]));
 			
-								vy[iy*n1*n2+ix*n1+iz]   *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(iz-ibz)];
+								vz[iy*n1*n2+ix*n1+iz]   *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(iz-ibz)];
 							}
 						}
 					}
@@ -1363,6 +1412,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 		if (mod.ischeme <= 2) { /* Acoustic scheme */
 			
 			/* Vx field */
+			/* left mid mid vx */
 			ixo = mod.ioXx-bnd.ntap;
 			ixe = mod.ioXx;
 			iyo = mod.ioXy;
@@ -1371,6 +1421,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			ize = mod.ieXz;
 			
 			ib = (bnd.ntap+ixo-1);
+
 #pragma omp for private(ix,iy,iz)
 			for (ix=ixo; ix<ixe; ix++) {
 #pragma ivdep
@@ -1379,12 +1430,12 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 						vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*(
 									c1*(tzz[iy*n1*n2+ix*n1+iz]	   - tzz[iy*n1*n2+(ix-1)*n1+iz]) +
 									c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz]));
-						
-						vx[iy*n1*n2+ix*n1+iz]   *= bnd.tapx[ib-ix];
+
+						vx[iy*n1*n2+ix*n1+iz]   *= bnd.tapx[ib-ix]; 
 					}
 				}
 			}
-			/* left front corner */
+			/* left mid front corner vx */
 			if (bnd.fro==4) {
 				iyo = mod.ioXy-bnd.ntap;
 				iye = mod.ioXy;
@@ -1399,12 +1450,12 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 										c1*(tzz[iy*n1*n2+ix*n1+iz]	   - tzz[iy*n1*n2+(ix-1)*n1+iz]) +
 										c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz]));
 		
-							vx[iy*n1*n2+ix*n1+iz]   *= bnd.tapxz[(iby-iy)*bnd.ntap+(ibx-ix)];
+							vx[iy*n1*n2+ix*n1+iz]   *= bnd.tapxz[(iby-iy)*bnd.ntap+(ibx-ix)]; 
 						}
 					}
 				}
 			}
-			/* left back corner */
+			/* left mid back corner vx */
 			if (bnd.bac==4) {
 				iyo = mod.ieXy;
 				iye = mod.ieXy+bnd.ntap;
@@ -1426,6 +1477,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			}
 
 			/* Vy field */
+			/* left mid mid vy */
 			ixo = mod.ioYx-bnd.ntap;
 			ixe = mod.ioYx;
 			iyo = mod.ioYy;
@@ -1447,7 +1499,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* left front corner */
+			/* left mid front corner vy */
 			if (bnd.fro==4) {
 				iyo = mod.ioYy-bnd.ntap;
 				iye = mod.ioYy;
@@ -1467,7 +1519,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* left back corner */
+			/* left mid back corner vy */
 			if (bnd.bac==4) {
 				iyo = mod.ieYy;
 				iye = mod.ieYy+bnd.ntap;
@@ -1489,6 +1541,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			}
 			
 			/* Vz field */
+			/* left mid mid vz */
 			ixo = mod.ioZx-bnd.ntap;
 			ixe = mod.ioZx;
 			iyo = mod.ioZy;
@@ -1497,6 +1550,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			ize = mod.ieZz;
 
 			ib = (bnd.ntap+ixo-1);
+
 #pragma omp for private (ix,iy,iz)
 			for (ix=ixo; ix<ixe; ix++) {
 #pragma ivdep
@@ -1510,7 +1564,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* left front corner */
+			/* left mid front corner vz*/
 			if (bnd.fro==4) {
 				iyo = mod.ioZy-bnd.ntap;
 				iye = mod.ioZy;
@@ -1530,7 +1584,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* left back corner */
+			/* left mid back corner vz */
 			if (bnd.bac==4) {
 				iyo = mod.ieZy;
 				iye = mod.ieZy+bnd.ntap;
@@ -1563,6 +1617,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 		if (mod.ischeme <= 2) { /* Acoustic scheme */
 			
 			/* Vx field */
+			/* right mid mid vx */
 			ixo = mod.ieXx;
 			ixe = mod.ieXx+bnd.ntap;
 			iyo = mod.ioXy;
@@ -1571,6 +1626,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			ize = mod.ieXz;
 		
 			ib = (ixo);
+
 #pragma omp for private(ix,iy,iz)
 			for (ix=ixo; ix<ixe; ix++) {
 #pragma ivdep
@@ -1579,17 +1635,18 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 						vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*(
 									c1*(tzz[iy*n1*n2+ix*n1+iz]	   - tzz[iy*n1*n2+(ix-1)*n1+iz]) +
 									c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz]));
-		
-						vx[iy*n1*n2+ix*n1+iz]   *= bnd.tapx[ix-ib];
+
+						vx[iy*n1*n2+ix*n1+iz] *= bnd.tapx[ix-ib]; 
 					}
 				}
 			}
-			/* Right front corner */
+			/* right mid front corner vx */
 			if (bnd.fro==4) {
 				iyo = mod.ioXy-bnd.ntap;
 				iye = mod.ioXy;
 				ibx = (ixo);
 				iby = (bnd.ntap+iyo-1);
+
 #pragma omp for private(ix,iy,iz)
 				for (ix=ixo; ix<ixe; ix++) {
 #pragma ivdep
@@ -1599,17 +1656,18 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 										c1*(tzz[iy*n1*n2+ix*n1+iz]	   - tzz[iy*n1*n2+(ix-1)*n1+iz]) +
 										c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz]));
 		
-							vx[iy*n1*n2+ix*n1+iz]   *= bnd.tapxz[(iby-iy)*bnd.ntap+(ix-ibx)];
+							vx[iy*n1*n2+ix*n1+iz]   *= bnd.tapxz[(iby-iy)*bnd.ntap+(ix-ibx)]; 
 						}
 					}
 				}
 			}
-			/* Right back corner */
+			/* right mid back corner vx*/
 			if (bnd.bac==4) {
 				iyo = mod.ieXy;
 				iye = mod.ieXy+bnd.ntap;
 				ibx = (ixo);
 				iby = (iyo);
+
 #pragma omp for private(ix,iy,iz)
 				for (ix=ixo; ix<ixe; ix++) {
 #pragma ivdep
@@ -1626,6 +1684,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			}
 
 			/* Vy field */
+			/* right mid mid vy */
 			ixo = mod.ieYx;
 			ixe = mod.ieYx+bnd.ntap;
 			iyo = mod.ioYy;
@@ -1634,6 +1693,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			ize = mod.ieYz;
 		
 			ib = (ixo);
+
 #pragma omp for private(ix,iy,iz)
 			for (ix=ixo; ix<ixe; ix++) {
 #pragma ivdep
@@ -1644,15 +1704,17 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 									c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz]));
 		
 						vy[iy*n1*n2+ix*n1+iz]   *= bnd.tapx[ix-ib];
+						//vy[iy*n1*n2+ix*n1+iz]   *= bnd.tapy[ix-ib]; 
 					}
 				}
 			}
-			/* Right front corner */
+			/* right mid front corner vy */
 			if (bnd.fro==4) {
 				iyo = mod.ioYy-bnd.ntap;
 				iye = mod.ioYy;
 				ibx = (ixo);
 				iby = (bnd.ntap+iyo-1);
+
 #pragma omp for private(ix,iy,iz)
 				for (ix=ixo; ix<ixe; ix++) {
 #pragma ivdep
@@ -1662,17 +1724,18 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 										c1*(tzz[iy*n1*n2+ix*n1+iz]	   - tzz[(iy-1)*n1*n2+ix*n1+iz]) +
 										c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz]));
 		
-							vy[iy*n1*n2+ix*n1+iz]   *= bnd.tapxz[(iby-iy)*bnd.ntap+(ix-ibx)];
+							vy[iy*n1*n2+ix*n1+iz]   *= bnd.tapxz[(iby-iy)*bnd.ntap+(ix-ibx)]; 
 						}
 					}
 				}
 			}
-			/* Right back corner */
+			/* right mid back corner vy */
 			if (bnd.bac==4) {
 				iyo = mod.ieYy;
 				iye = mod.ieYy+bnd.ntap;
 				ibx = (ixo);
 				iby = (iyo);
+
 #pragma omp for private(ix,iy,iz)
 				for (ix=ixo; ix<ixe; ix++) {
 #pragma ivdep
@@ -1689,6 +1752,8 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			}
 
 			/* Vz field */
+			/* right mid mid vz */
+
 			ixo = mod.ieZx;
 			ixe = mod.ieZx+bnd.ntap;
 			iyo = mod.ioZy;
@@ -1697,6 +1762,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			ize = mod.ieZz;
 			
 			ib = (ixo);
+
 #pragma omp for private (ix,iy,iz) 
 			for (ix=ixo; ix<ixe; ix++) {
 #pragma ivdep
@@ -1706,16 +1772,18 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 									c1*(tzz[iy*n1*n2+ix*n1+iz]   - tzz[iy*n1*n2+ix*n1+iz-1]) +
 									c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2]));
 		
-						vz[iy*n1*n2+ix*n1+iz] *= bnd.tapz[ix-ib];
+						vz[iy*n1*n2+ix*n1+iz] *= bnd.tapz[ix-ib]; 
+						//vz[iy*n1*n2+ix*n1+iz] *= bnd.tapx[ix-ib]; 
 					}
 				}
 			}
-			/* right front corner */
+			/* right mid front corner vz */
 			if (bnd.fro==4) {
 				iyo = mod.ioZy-bnd.ntap;
 				iye = mod.ioZy;
 				ibx = (ixo);
 				iby = (bnd.ntap+iyo-1);
+
 #pragma omp for private(ix,iy,iz)
 				for (ix=ixo; ix<ixe; ix++) {
 #pragma ivdep
@@ -1730,12 +1798,13 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 					}
 				}
 			}
-			/* right back corner */
+			/* right mid back corner vz */
 			if (bnd.bac==4) {
 				iyo = mod.ieZy;
 				iye = mod.ieZy+bnd.ntap;
 				ibx = (ixo);
 				iby = (iyo);
+
 #pragma omp for private(ix,iy,iz)
 				for (ix=ixo; ix<ixe; ix++) {
 #pragma ivdep
@@ -1763,6 +1832,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 		if (mod.ischeme <= 2) { /* Acoustic scheme */
 			
 			/* Vx field */
+			/* mid mid front vx */
 			ixo = mod.ioXx;
 			ixe = mod.ieXx;
 			iyo = mod.ioXy-bnd.ntap;
@@ -1780,12 +1850,13 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 									c1*(tzz[iy*n1*n2+ix*n1+iz]	   - tzz[iy*n1*n2+(ix-1)*n1+iz]) +
 									c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz]));
 		
-						vx[iy*n1*n2+ix*n1+iz]   *= bnd.tapy[iby-iy];
+						vx[iy*n1*n2+ix*n1+iz]   *= bnd.tapy[iby-iy]; 
 					}
 				}
 			}
 
 			/* Vy field */
+			/* mid mid front vy */
 			ixo = mod.ioYx;
 			ixe = mod.ieYx;
 			iyo = mod.ioYy-bnd.ntap;
@@ -1803,12 +1874,13 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 									c1*(tzz[iy*n1*n2+ix*n1+iz]	   - tzz[(iy-1)*n1*n2+ix*n1+iz]) +
 									c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz]));
 		
-						vy[iy*n1*n2+ix*n1+iz]   *= bnd.tapy[iby-iy];
+						vy[iy*n1*n2+ix*n1+iz]   *= bnd.tapy[iby-iy]; 
 					}
 				}
 			}
 
 			/* Vz field */
+			/* mid mid front vz */
 			ixo = mod.ioZx;
 			ixe = mod.ieZx;
 			iyo = mod.ioZy-bnd.ntap;
@@ -1826,7 +1898,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 									c1*(tzz[iy*n1*n2+ix*n1+iz]   - tzz[iy*n1*n2+ix*n1+iz-1]) +
 									c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2]));
 		
-						vz[iy*n1*n2+ix*n1+iz] *= bnd.tapy[iby-iy];
+						vz[iy*n1*n2+ix*n1+iz] *= bnd.tapy[iby-iy]; 
 					}
 				}
 			}
@@ -1842,6 +1914,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 		if (mod.ischeme <= 2) { /* Acoustic scheme */
 			
 			/* Vx field */
+			/* mid mid back vx */
 			ixo = mod.ioXx;
 			ixe = mod.ieXx;
 			iyo = mod.ieXy;
@@ -1865,6 +1938,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			}
 
 			/* Vy field */
+			/* mid mid back vy */
 			ixo = mod.ioYx;
 			ixe = mod.ieYx;
 			iyo = mod.ieYy;
@@ -1888,6 +1962,7 @@ long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, floa
 			}
 
 			/* Vz field */
+			/* mid mid back vz */
 			ixo = mod.ioZx;
 			ixe = mod.ieZx;
 			iyo = mod.ieZy;
diff --git a/fdelmodc3D/demo/mytests/marmo125x383-test/.omf b/fdelmodc3D/demo/mytests/marmo125x383-test/.omf
new file mode 100644
index 0000000000000000000000000000000000000000..7ef92a1caefd6907690e7a03b9378acb7bd80719
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/marmo125x383-test/.omf
@@ -0,0 +1,10 @@
+dTect V4.0
+Object Management file
+sex mar 29 14:43:42 -03 2019
+!
+ID: -1
+!
+Appl dir: 1
+Appl: dGB`Stream
+$Name: appl
+!
diff --git a/fdelmodc3D/demo/mytests/marmo125x383-test/binary b/fdelmodc3D/demo/mytests/marmo125x383-test/binary
new file mode 100644
index 0000000000000000000000000000000000000000..7f4a503f52b02aaaca6516fd3ac0a5c999932cf8
Binary files /dev/null and b/fdelmodc3D/demo/mytests/marmo125x383-test/binary differ
diff --git a/fdelmodc3D/demo/mytests/marmo125x383-test/create-vel-rho-3d.sh b/fdelmodc3D/demo/mytests/marmo125x383-test/create-vel-rho-3d.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b40d2c8e7e3dbfc836e81253d6b1ff0ccbb01e78
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/marmo125x383-test/create-vel-rho-3d.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# Create 2.5-d binary model
+echo "CREATING 3D BINARY VELmodel"
+velName=vel125x383
+nz=125
+nx=383
+ny=104
+twoD_to_twoHalfD.exe nz=$nz nx=$nx ny=$ny input2d=$velName.bin output3d=$velName-3d.bin
+echo ""
+
+# Create rho from vel3d
+echo "CREATING 3D BINARY RHOmodel"
+rhoName=rho125x383
+nsamp=$(($nz*$nx*$ny))
+vel2rho.exe nsamp=$nsamp velfile=$velName-3d.bin rhofile=$rhoName-3d.bin
+echo ""
+
+# Put SU headers on vel3d and rho3d
+echo "PUTTING SU HEADERS"
+dz=24.0
+dx=24.0
+dy=24.0
+bin2su.exe binmodel=$velName-3d.bin sumodel=$velName-3d.su nz=$nz nx=$nx ny=$ny dz=$dz dx=$dx dy=$dy opendt=1
+bin2su.exe binmodel=$rhoName-3d.bin sumodel=$rhoName-3d.su nz=$nz nx=$nx ny=$ny dz=$dz dx=$dx dy=$dy opendt=1
+echo ""
+
+
+
+
+
+
diff --git a/fdelmodc3D/demo/mytests/marmo125x383-test/header b/fdelmodc3D/demo/mytests/marmo125x383-test/header
new file mode 100644
index 0000000000000000000000000000000000000000..f5d72c01d7649db8f895a2987a10c001ad03c555
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/marmo125x383-test/header
@@ -0,0 +1,40 @@
+C      This tape was made at the                                               
+C                                                                              
+C      Center for Wave Phenomena                                               
+C      Colorado School of Mines                                                
+C      Golden, CO, 80401                                                       
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
+C                                                                              
diff --git a/fdelmodc3D/demo/mytests/marmo125x383-test/marmo3d-data.dat b/fdelmodc3D/demo/mytests/marmo125x383-test/marmo3d-data.dat
new file mode 100644
index 0000000000000000000000000000000000000000..839247576d2d21d8af8763226258a145b700fa75
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/marmo125x383-test/marmo3d-data.dat
@@ -0,0 +1,44 @@
+# Scheme and aux vars
+ischeme=1 
+iorder=4
+verbose=4
+
+# Input files
+file_cp=vel125x383-3d.su
+file_den=rho125x383-3d.su
+file_src=wave.su
+file_rcv=shot3d_marmo_fd.su
+
+# Source vars
+src_type=1
+src_orient=1
+src_injectionrate=1
+
+# Rec vars
+rec_type_vz=0
+rec_type_p=1
+rec_int_vz=2
+dtrcv=0.0005
+rec_delay=0.0 # delays seismogram
+
+# Time
+tmod=4.0
+
+# Geometry
+dxrcv=10.0
+xrcv1=0
+xrcv2=920
+zrcv1=0 
+zrcv2=0
+xsrc=0 
+zsrc=0
+
+# ABC vars
+ntaper=30
+left=4 right=4 top=4 bottom=4
+
+# Snap vars
+sna_type_p=1 
+tsnap1=0.1 
+tsnap2=4.0 
+
diff --git a/fdelmodc3D/demo/mytests/marmo125x383-test/opendtect.sh b/fdelmodc3D/demo/mytests/marmo125x383-test/opendtect.sh
new file mode 100644
index 0000000000000000000000000000000000000000..5fcb66c219f056b4664924531c2787dcb43fb36a
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/marmo125x383-test/opendtect.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+ODTPATH=/home/victork/OpendTect/6.4.0
+
+here=$(pwd)
+
+$ODTPATH/mk_datadir $here
+$ODTPATH/start_dtect 
diff --git a/fdelmodc3D/demo/mytests/marmo125x383-test/run-3d-marmo-staggered.sh b/fdelmodc3D/demo/mytests/marmo125x383-test/run-3d-marmo-staggered.sh
new file mode 100755
index 0000000000000000000000000000000000000000..282d22a1a374faf99b060c3850bdf00a9c323d26
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/marmo125x383-test/run-3d-marmo-staggered.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+
+dt=0.0005
+../../../utils/makewave fp=3 dt=$dt file_out=wave.su nt=4096 t0=0.0 scale=1 shift=1
+
+../../fdelmodc3D par=marmo3d-data.dat
+
+
diff --git a/fdelmodc3D/demo/mytests/marmo125x383-test/send-odt.sh b/fdelmodc3D/demo/mytests/marmo125x383-test/send-odt.sh
new file mode 100644
index 0000000000000000000000000000000000000000..a9bf588e2f88457fdf73ac7361ef1d596fb81453
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/marmo125x383-test/send-odt.sh
@@ -0,0 +1 @@
+#!/bin/bash
diff --git a/fdelmodc3D/demo/mytests/model10-test/2dSU_to_3dSU_v1.sh b/fdelmodc3D/demo/mytests/model10-test/2dSU_to_3dSU_v1.sh
new file mode 100755
index 0000000000000000000000000000000000000000..834a4f5b668a046ff68c238591425c6d21c5eb1a
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/model10-test/2dSU_to_3dSU_v1.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+
+# Check inputs
+if [ "$#" -ne 4 ]; then
+	echo "2dSU_to_3dSU_v1.sh: wrong number of input parameters. Exiting."
+	echo "Creates a 3D SU model by replicating 2D SU model in the y-direction."
+	echo "Usage: "
+	echo "./2dSU_to_3dSU_v1.sh dx dy ny file.su"
+	echo "Ex: "
+	echo "./2dSU_to_3dSU_v1.sh 2.5 2.5 120 file.su" 
+	echo "(outputs file-3d.su)"
+	#return #for function
+	exit #for script
+fi
+
+dx=$1
+dy=$2
+ny=$3
+indata=$4
+
+name="${4%%.*}" #strips extension from name
+outdata=$name-3d.su
+
+tmp=tmp1.su
+tmp2=tmp2.su
+
+rm $outdata
+rm $tmp
+
+t1=`date +%s`
+for (( iy=1; iy<=$ny; iy++ ))
+do  
+	echo "Adding y-slice $iy "
+
+	# Set y-slice with correct fldr
+	cp $indata $tmp
+	sushw <$tmp >$tmp2 key=fldr a=$iy b=0 c=0
+
+	# Cat it to our 2.5D
+	cat $tmp2 >>$outdata
+done
+t2=`date +%s`
+echo "Extending data with cat took $((t2-t1)) seconds"
+
+rm $tmp2
+
+# Add cdp (x coordinate for odtect)
+echo "Setting CDP key"
+#suchw <$outdata >$tmp key1=cdp key2=tracl a=1
+time suchw <$outdata >$tmp key1=cdp key2=tracl a=1
+
+# Set sx
+echo "Setting sx key"
+factor=$( echo "$dx*1000" | bc)
+#suchw <$tmp >$outdata key1=sx key2=cdp a=0 b=$factor 
+time suchw <$tmp >$outdata key1=sx key2=cdp a=0 b=$factor 
+
+# Set sy
+echo "Setting sy key"
+factor=$( echo "$dy*1000" | bc)
+#suchw <$outdata >$tmp key1=sy key2=fldr a=0 b=$factor 
+time suchw <$outdata >$tmp key1=sy key2=fldr a=0 b=$factor 
+
+# Set dt
+echo "Setting dt key"
+#suchw <$tmp >$outdata key1=dt key2=d1 b=1000
+time suchw <$tmp >$outdata key1=dt key2=d1 b=1000
+
+rm $tmp
+#mv $tmp $outdata
+
+
+
+
+
+
+
diff --git a/fdelmodc3D/demo/mytests/model10-test/2dSU_to_3dSU_v2.sh b/fdelmodc3D/demo/mytests/model10-test/2dSU_to_3dSU_v2.sh
new file mode 100755
index 0000000000000000000000000000000000000000..61425ab846f5ca4731d8cefc15338ce37e2f23d4
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/model10-test/2dSU_to_3dSU_v2.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+# Check inputs
+if [ "$#" -ne 3 ]; then
+	echo "2dSU_to_3dSU_v2: wrong number of input parameters. Exiting."
+	echo "Creates a 3D SU model by replicating 2D SU model in the y-direction."
+	echo "Usage: "
+	echo "./2dSU_to_3dSU_v2.sh file.su ny dy"
+	echo "Ex: "
+	echo "./2dSU_to_3dSU_v2.sh file.su 120 2.5" 
+	echo "(outputs file-3d.su)"
+	#return #for function
+	exit #for script
+fi
+
+# Functions
+function gethdrval(){
+	val=$(cat $1 | grep $2) # get parameter
+	val=${val#$2} # remove prefix
+	val="${val#"${val%%[![:space:]]*}"}" #remove whitespaces
+	
+	echo "$val"
+	#return "$val";
+}
+
+# Main 
+name="${1%%.*}" #strip the extension
+ny=$2
+dy=$3
+
+# Get header values
+surange <$1 >hdr.txt
+nz=$(gethdrval hdr.txt ns)
+nx=$(gethdrval hdr.txt trwf)
+dz=$(gethdrval hdr.txt d1)
+dx=$(gethdrval hdr.txt d2)
+
+
+echo "nz is $nz"
+echo "nx is $nx"
+echo "ny is $ny"
+echo "dz is $dz"
+echo "dx is $dx"
+echo "dy is $dy"
+
+echo -e "\n Running sustrip"
+sustrip <$1 >$name.bin outpar=hdr.txt
+
+echo -e "\n Running twoD_to_twoHalfD "
+twoD_to_twoHalfD.exe nz=$nz nx=$nx ny=$ny input2d=$name.bin output3d=$name-3d.bin
+
+echo -e "\n Running bin2su "
+bin2su.exe binmodel=$name-3d.bin sumodel=$name-3d.su nz=$nz nx=$nx ny=$ny dz=$dz dx=$dx dy=$dy odtkey=1
+
+
+# Clean up
+rm hdr.txt
+rm $name.bin
+rm $name-3d.bin
+
+
+
+
+
+
diff --git a/fdelmodc3D/demo/mytests/model10-test/Makefile b/fdelmodc3D/demo/mytests/model10-test/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..0e7d8448da89b346aa592bf19e132a0bc261ab26
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/model10-test/Makefile
@@ -0,0 +1,27 @@
+#Make cheatsheet
+#out.o: src.c src.h
+#  $@   # "out.o" (target)
+#  $<   # "src.c" (first prerequisite)
+#  $^   # "src.c src.h" (all prerequisites)
+
+#gcc flags cheatsheet
+#-I($PATH): look for headers here (besides standard dirs). 
+#-L($PATH): look for libfiles here (besides standard dirs). Only exe's need libfiles.
+
+
+MOBJ= checkNaN.o
+OBJ= 
+
+
+all: checkNaN.exe
+
+checkNaN.exe: $(MOBJ) $(OBJ)
+	gcc -o $@ $< -L$(CWPROOT)/lib -lsu -lpar -lcwp -lm
+
+
+%.o: %.c
+	gcc -c $< -I$(CWPROOT)/include
+
+clean:
+	rm *.o *.exe
+
diff --git a/fdelmodc3D/demo/mytests/model10-test/checkNaN.c b/fdelmodc3D/demo/mytests/model10-test/checkNaN.c
new file mode 100644
index 0000000000000000000000000000000000000000..81649a610616d84e9de0835fcc4450a4c2111416
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/model10-test/checkNaN.c
@@ -0,0 +1,132 @@
+/*
+HOW TO COMPILE (need SU installed):
+gcc -c sutemplate.c -I$(CWPROOT)/include
+gcc sutemplate.o -o sutemplate.exe -L$(CWPROOT)/lib -lsu -lpar -lcwp
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "su.h"
+#include "par.h"
+
+// SU header read/write*/
+#include "segy.h"
+#include "math.h"
+#define TRCBYTES                240		//SU-header size
+
+
+/*********************** self documentation **********************/
+char *sdoc[] = {
+"  ",
+" Checks NaN in a binfile",
+"  ",
+" ./module required_par1= required_par2= [optional parameters]",
+"  ",
+" Required parameters:",
+" ",
+"   required_par1= ................ quick description",
+"   required_par2= ................ quick description",
+"  ",
+" Optional parameters:",
+" ",
+"   opt_par1=defaultVal1 ................. quick description",
+"   opt_par2=defaultVal2 ................. quick description",
+" ",
+" extra text to explain things",
+" extra text to explain things",
+" extra text to explain things",
+" extra text to explain things",
+" extra text to explain things.",
+" ",
+"      Author 2018",
+"      Institution",
+"      E-mail: email@domain.com ",
+"  ",
+NULL};
+/**************** end self doc ***********************************/
+
+
+int main(int argc, char *argv[]){
+// INIT ARGS, REQUESTDOC //////////////////////////////////////////////////////////
+	initargs(argc, argv);
+	requestdoc(0);
+
+
+// DECLARE VARIABLES //////////////////////////////////////////////////////////////
+	int iz, ix, iy;
+	int nz, nx, ny;
+	char *filename;
+	float *data;
+
+
+// GET INPUT PARAMETERS ///////////////////////////////////////////////////////////
+	if( !getparint("nz", &nz) ) err("No nz. Exiting.\n");
+	if( !getparint("nx", &nx) ) err("No nx. Exiting.\n");
+	if( !getparint("ny", &ny) ) err("No ny. Exiting.\n");
+	//if( !getparfloat("dz", &dz) ) err("No dz. Exiting.\n");
+	if(!getparstring("filename", &filename)) filename=NULL;
+	
+
+// ALLOCATE VARIABLES /////////////////////////////////////////////////////////////
+	data = (float*)malloc(nz*nx*ny*sizeof(float));
+
+	FILE *fp;
+	fp = fopen(filename,"r");
+	fread(data, nz*nx*ny, sizeof(float), fp);
+	fclose(fp);
+
+// FILL INITIAL VALUES ///////////////////////////////////////////////////////////
+
+
+// TEST HEADER ///////////////////////////////////////////////////////////////////
+
+
+// PROCESS DATA ///////////////////////////////////////////////////////////////
+	float val;
+	float max=0.0;
+	for(iy=0; iy<ny; iy++){
+		for(ix=0; ix<nx; ix++){
+			for(iz=0; iz<nz; iz++){
+				
+
+				val = data[iy*nz*nx + ix*nz + iz];
+				if(val>max) max = val;
+				if( isinf(val)==1 ) printf("inf at iz,ix,iy = %d,%d,%d\n", iz, ix, iy);
+				if( isnan(val)==1 ) printf("NaN at iz,ix,iy = %d,%d,%d\n", iz, ix, iy);
+
+			}
+		}
+	}
+
+	printf("max is %f\n", max);
+	
+// FREE VARIABLES /////////////////////////////////////////////////////////////
+	free(data);
+	
+// END MAIN ///////////////////////////////////////////////////////////////////
+
+	return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fdelmodc3D/demo/mytests/model10-test/convAndSendODT.sh b/fdelmodc3D/demo/mytests/model10-test/convAndSendODT.sh
new file mode 100755
index 0000000000000000000000000000000000000000..fa5bc4e1ef89752f511b1d1bccc85fedbef0701c
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/model10-test/convAndSendODT.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# Check inputs
+if [ "$#" -ne 1 ]; then
+	echo "convAndSendODT: wrong number of input parameters. Exiting."
+	echo "Converts SU file to SEGY file, move it to $ODTAREA"
+	echo "Usage: "
+	echo "./convAndSendODT file.su"
+	#return #for function
+	exit #for script
+fi
+
+
+su2sgy.sh $1 
+
+name="${1%%.*}" # strip name
+
+mv $name.sgy $ODTAREA
diff --git a/fdelmodc3D/demo/mytests/model10-test/create-model10.sh b/fdelmodc3D/demo/mytests/model10-test/create-model10.sh
new file mode 100755
index 0000000000000000000000000000000000000000..84f6982ca28052c1415f42d2fda5b123636ad92f
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/model10-test/create-model10.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+dx=2.5
+dt=0.0005
+
+makemod sizex=2000 sizez=1000 dx=$dx dz=$dx cp0=1800 ro0=1000 \
+        orig=-1000,0 file_base=model10.su verbose=2 \
+        intt=def x=-1000,1000 z=400,400 poly=0 cp=2300 ro=3000 \
+        intt=def x=-1000,1000 z=700,700 poly=0 cp=2000 ro=1100 \
+        intt=def x=-1000,1000 z=900,900 poly=0 cp=2500 ro=4000
+
diff --git a/fdelmodc3D/demo/mytests/model10-test/model.scr b/fdelmodc3D/demo/mytests/model10-test/model.scr
new file mode 100755
index 0000000000000000000000000000000000000000..9165e8758862d4cef0b497ca585bea46336e9d13
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/model10-test/model.scr
@@ -0,0 +1,77 @@
+#!/bin/bash
+
+#adjust this PATH to where the code is installed
+export PATH=$HOME/src/OpenSource/bin:$PATH:
+
+dx=2.5
+dt=0.0005
+
+#define gridded model for FD computations
+makemod sizex=10000 sizez=1400 dx=$dx dz=$dx cp0=1800 ro0=1000 \
+        orig=-5000,0 file_base=model10.su verbose=2 \
+        intt=def x=-5000,5000 z=400,400 poly=0 cp=2300 ro=3000 \
+        intt=def x=-5000,5000 z=700,700 poly=0 cp=2000 ro=1100 \
+        intt=def x=-5000,5000 z=1100,1100 poly=0 cp=2500 ro=4000
+
+#define wavelet for modeling R
+makewave w=fw fmin=0 flef=5 frig=80 fmax=100  dt=$dt file_out=wavefw.su nt=4096 t0=0.3 scale=0 scfft=1
+
+#define wavelet for reference and intial focusing field.
+makewave fp=25 dt=$dt file_out=wave.su nt=4096 t0=0.1 scale=1
+
+export OMP_NUM_THREADS=4
+
+#Model shot record in middle of model
+fdelmodc \
+    file_cp=model10_cp.su ischeme=1 iorder=4 \
+    file_den=model10_ro.su \
+    file_src=wavefw.su \
+    file_rcv=shot5_fd.su \
+    src_type=7 \
+    src_orient=1 \
+    src_injectionrate=1 \
+    rec_type_vz=0 \
+    rec_type_p=1 \
+    rec_int_vz=2 \
+    dtrcv=0.004 \
+    rec_delay=0.3 \
+    verbose=2 \
+    tmod=4.392 \
+    dxrcv=5.0 \
+    xrcv1=-4500 xrcv2=4500 \
+    zrcv1=0 zrcv2=0 \
+    xsrc=0 zsrc=0 \
+    npml=101 \
+    left=2 right=2 top=2 bottom=2 
+
+#define homogenoeus model to compute direct wave only
+makemod sizex=10000 sizez=1200 dx=$dx dz=$dx cp0=1800 ro0=1000 \
+        orig=-5000,0 file_base=hom.su verbose=2
+
+#Model direct wave only in middle of model
+fdelmodc \
+    file_cp=hom_cp.su ischeme=1 iorder=4 \
+    file_den=hom_ro.su \
+    file_src=wavefw.su \
+    file_rcv=shot5_hom_fd.su \
+    src_type=7 \
+    src_orient=1 \
+    src_injectionrate=1 \
+    rec_type_vz=0 \
+    rec_type_p=1 \
+    rec_int_vz=2 \
+    dtrcv=0.004 \
+    rec_delay=0.3 \
+    verbose=2 \
+    tmod=4.392 \
+    dxrcv=5.0 \
+    xrcv1=-4500 xrcv2=4500 \
+    zrcv1=0 zrcv2=0 \
+    xsrc=0 zsrc=0 \
+    npml=101 \
+    left=2 right=2 top=2 bottom=2 
+
+#subtract direct wave from full model shot record: this defines R
+sudiff shot5_fd_rp.su shot5_hom_fd_rp.su > shot5_rp.su
+
+
diff --git a/fdelmodc3D/demo/mytests/model10-test/model.sh b/fdelmodc3D/demo/mytests/model10-test/model.sh
new file mode 100755
index 0000000000000000000000000000000000000000..69bd00c58bf87964d422c2f1eb70d2b24a1bcda9
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/model10-test/model.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+#adjust this PATH to where the code is installed
+export PATH=$HOME/src/OpenSource/bin:$PATH:
+
+dx=2.5
+
+	#define gridded model for FD computations
+makemod sizex=2000 sizez=1400 dx=$dx dz=$dx cp0=1800 ro0=1000 \
+	orig=-1000,0 file_base=model10.su verbose=2 \
+        intt=def x=-1000,1000 z=400,400 poly=0 cp=2300 ro=3000 \
+        intt=def x=-1000,1000 z=700,700 poly=0 cp=2000 ro=1100 \
+        intt=def x=-1000,1000 z=1100,1100 poly=0 cp=2500 ro=4000
+
diff --git a/fdelmodc3D/demo/mytests/model10-test/model10_data.dat b/fdelmodc3D/demo/mytests/model10-test/model10_data.dat
new file mode 100644
index 0000000000000000000000000000000000000000..edf71af79603f0ddf15c20144f61b41c669e343f
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/model10-test/model10_data.dat
@@ -0,0 +1,52 @@
+# Scheme and aux vars
+ischeme=1 
+iorder=4
+verbose=1
+
+# Input files
+file_cp=model10_cp-3d.su
+file_den=model10_ro-3d.su
+file_src=wave.su
+file_rcv=shot3d_model10_fd.su
+
+# Source vars
+src_type=1
+src_orient=1
+src_injectionrate=1
+
+# Rec vars
+rec_type_vz=0
+rec_type_p=1
+rec_int_vz=2
+dtrcv=0.004
+rec_delay=0.0 # delays seismogram
+
+# Time
+#tmod=0.9
+tmod=0.8
+
+# Geometry
+dxrcv=10.0
+dyrcv=10.0
+xrcv1=100
+xrcv2=1900
+zrcv1=450 
+zrcv2=450
+yrcv1=50 
+yrcv2=200
+xsrc=1000 
+zsrc=500
+ysrc=125
+
+# ABC vars
+ntaper=60 left=4 right=4 top=4 bottom=4 front=4 back=4
+
+# Snap vars
+sna_type_p=1 
+tsnap1=0.0 
+dtsnap=0.05
+tsnap2=0.5 
+
+
+
+
diff --git a/fdelmodc3D/demo/mytests/model10-test/run-model10-3d.sh b/fdelmodc3D/demo/mytests/model10-test/run-model10-3d.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6a6e54d86bd0bd95c5ec49572cfa4a2c0ccb2b50
--- /dev/null
+++ b/fdelmodc3D/demo/mytests/model10-test/run-model10-3d.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+
+dt=0.0004
+../../../../utils/makewave fp=25 dt=$dt file_out=wave.su nt=4096 t0=0.1 scale=1
+
+export OMP_NUM_THREADS=80
+../../../fdelmodc3D par=model10_data.dat
+
+
diff --git a/fdelmodc3D/fdelmodc3D b/fdelmodc3D/fdelmodc3D
new file mode 100755
index 0000000000000000000000000000000000000000..7fd32fbba9bd29bbbedf15be688a851a8c6c8fee
Binary files /dev/null and b/fdelmodc3D/fdelmodc3D differ
diff --git a/fdelmodc3D/fdelmodc3D.c b/fdelmodc3D/fdelmodc3D.c
index 617e79cb1a19920f50f81614724607c2ef3a77c6..7cc4e25a275328fa6cf8ebece1facf9bcf041506 100644
--- a/fdelmodc3D/fdelmodc3D.c
+++ b/fdelmodc3D/fdelmodc3D.c
@@ -28,10 +28,26 @@ long defineSource3D(wavPar wav, srcPar src, modPar mod, recPar rec, float **src_
 
 long writeSrcRecPos3D(modPar *mod, recPar *rec, srcPar *src, shotPar *shot);
 
+long acoustic6_3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime,
+    long ixsrc, long iysrc, long izsrc, float **src_nwav, float *vx, float *vy, float *vz, 
+	float *p, float *rox, float *roy, float *roz, float *l2m, long verbose);
+
 long acoustic4_3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime,
 	long ixsrc, long iysrc, long izsrc, float **src_nwav, float *vx, float *vy, float *vz,
 	float *p, float *rox, float *roy, float *roz, float *l2m, long verbose);
 
+long acoustic2_3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime,
+    long ixsrc, long iysrc, long izsrc, float **src_nwav, float *vx, float *vy, float *vz,
+    float *p, float *rox, float *roy, float *roz, float *l2m, long verbose);
+
+long acoustic4_qr_3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime, 
+    long ixsrc, long iysrc, long izsrc, float **src_nwav, float *vx, float *vy, float *vz,
+    float *p, float *rox, float *roy, float *roz, float *l2m, long verbose);
+
+long acousticSH4_3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime,
+	long ixsrc, long iysrc, long izsrc, float **src_nwav, float *tx, float *ty, float *tz,
+	float *vz, float *rox, float *roy, float *roz, float *mul, long verbose);
+
 long getRecTimes3D(modPar mod, recPar rec, bndPar bnd, long itime, long isam,
 	float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx,
 	float *txz, float *txy, float *tyz, float *l2m, float *rox, float *roy, float *roz,
@@ -302,7 +318,6 @@ int main(int argc, char **argv)
 	if (!getparlong("verbose",&verbose)) verbose=0;
 	getParameters3D(&mod, &rec, &sna, &wav, &src, &shot, &bnd, verbose);
 
-
 	/* allocate arrays for model parameters: the different schemes use different arrays */ 
 
 	n1 = mod.naz;
@@ -577,29 +592,28 @@ shared (shot, bnd, mod, src, wav, rec, ixsrc, iysrc, izsrc, it, src_nwav, verbos
 				threadAffinity();
 			}
 			switch ( mod.ischeme ) {
-//				case -2 : /* test code for PML */
-//					acoustic4_test(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, 
-//						vx, vz, tzz, rox, roz, l2m, verbose);
-//					break;
 				case -1 : /* Acoustic dissipative media FD kernel */
-					vmess("Acoustic dissipative not yet available");
+					acoustic4_qr_3D(mod, src, wav, bnd, it, ixsrc, iysrc, izsrc, src_nwav,
+									vx, vy, vz, tzz, rox, roy, roz, l2m, verbose);
 					break;
 				case 1 : /* Acoustic FD kernel */
 					if (mod.iorder==2) {
-						vmess("Acoustic order 2 not yet available");
+						acoustic2_3D(mod, src, wav, bnd, it, ixsrc, iysrc, izsrc, src_nwav,
+								vx, vy, vz, tzz, rox, roy, roz, l2m, verbose);
 					}
 					else if (mod.iorder==4) {
                         if (mod.sh) {
-                            vmess("SH order 4 not yet available");
+                            acousticSH4_3D(mod, src, wav, bnd, it, ixsrc, iysrc, izsrc, src_nwav, 
+                                    vx, vy, vz, tzz, rox, roy, roz, l2m, verbose);
                         }
                         else {
-                        	
 							acoustic4_3D(mod, src, wav, bnd, it, ixsrc, iysrc, izsrc, src_nwav,
 									vx, vy, vz, tzz, rox, roy, roz, l2m, verbose);
                         }
 					}
 					else if (mod.iorder==6) {
-						vmess("Acoustic order 6 not yet available");
+							acoustic6_3D(mod, src, wav, bnd, it, ixsrc, iysrc, izsrc, src_nwav,
+									vx, vy, vz, tzz, rox, roy, roz, l2m, verbose);
 					}
 					break;
 				case 2 : /* Visco-Acoustic FD kernel */
diff --git a/fdelmodc3D/getParameters3D.c b/fdelmodc3D/getParameters3D.c
index 31c91b77ce7c08cf048303d9cbb135a35633b2a4..8771c6bacae14eeafa0e16f643d681555dc454ba 100644
--- a/fdelmodc3D/getParameters3D.c
+++ b/fdelmodc3D/getParameters3D.c
@@ -581,7 +581,7 @@ criteria we have imposed.*/
 		shot->y[is] = src_iy0+is*idyshot;
 		shot->z[is] = src_iz0+is*idzshot;
 		if (shot->x[is] > nx-1) shot->n = is-1;
-		if (shot->y[is] > nz-1) shot->n = is-1;
+		if (shot->y[is] > ny-1) shot->n = is-1;
 		if (shot->z[is] > nz-1) shot->n = is-1;
 	}
 
diff --git a/fdelmodc3D/readModel3D.c b/fdelmodc3D/readModel3D.c
index 51718094ba93b4020388d53074ca559aab25db5c..df93d7185f08428f42294fb63779a08a6e8daf9a 100644
--- a/fdelmodc3D/readModel3D.c
+++ b/fdelmodc3D/readModel3D.c
@@ -52,6 +52,7 @@ long readModel3D(modPar mod, bndPar bnd, float *rox, float *roy, float *roz,
 	n3 = mod.nay;
 	fac = mod.dt/mod.dx;
 
+
 	/* Vx: rox */
 	ioXx=mod.ioXx;
 	ioXy=mod.ioXy;
@@ -556,7 +557,7 @@ Robbert van Vossen, Johan O. A. Robertsson, and Chris H. Chapman
         for (iy=iyo; iy<iye; iy++) {
             for (ix=ixo; ix<ixe; ix++) {
                 for (iz=izo; iz<ize; iz++) {
-                    roy[iy*n2*n1+ix*n1+iz] = rox[iy*n2*n1+ixe*n1+iz];
+                    roy[iy*n2*n1+ix*n1+iz] = roy[iy*n2*n1+ixe*n1+iz];
                 }
             }
         }
@@ -821,7 +822,7 @@ Robbert van Vossen, Johan O. A. Robertsson, and Chris H. Chapman
         for (iy=iyo; iy<iye; iy++) {
             for (ix=ixo; ix<ixe; ix++) {
                 for (iz=izo; iz<ize; iz++) {
-                    roy[iy*n2*n1+ix*n1+iz] = rox[iye*n2*n1+ix*n1+iz];
+                    roy[iy*n2*n1+ix*n1+iz] = roy[iye*n2*n1+ix*n1+iz];
                 }
             }
         }
@@ -846,8 +847,10 @@ Robbert van Vossen, Johan O. A. Robertsson, and Chris H. Chapman
         /* l2m field */
         ixo = mod.ioPx;
         ixe = mod.iePx;
+        /*
         if (bnd.lef==4 || bnd.lef==2) ixo -= bnd.ntap;
         if (bnd.rig==4 || bnd.rig==2) ixe += bnd.ntap;
+        */
         iyo = mod.ioPy;
         iye = mod.ioPy+bnd.ntap;
         izo = mod.ioPz;
@@ -992,8 +995,10 @@ Robbert van Vossen, Johan O. A. Robertsson, and Chris H. Chapman
         /* l2m field */
         ixo = mod.ioPx;
         ixe = mod.iePx;
+        /*
         if (bnd.lef==4 || bnd.lef==2) ixo -= bnd.ntap;
         if (bnd.rig==4 || bnd.rig==2) ixe += bnd.ntap;
+        */
         iyo = mod.iePy-bnd.ntap;
         iye = mod.iePy;
         izo = mod.ioPz;
@@ -1366,6 +1371,16 @@ Robbert van Vossen, Johan O. A. Robertsson, and Chris H. Chapman
 
     }
 
+
+    FILE *fptest;
+    fptest = fopen("cp-test.bin","w");
+    fwrite(cp, nz*ny*nx, sizeof(float), fptest);
+    fclose(fptest);
+
+    fptest = fopen("ro-test.bin","w");
+    fwrite(ro, nz*ny*nx, sizeof(float), fptest);
+    fclose(fptest);
+
 	free(cp);
 	free(ro);
    	free(cs);
diff --git a/fdelmodc3D/viscoacoustic4_3D.c b/fdelmodc3D/viscoacoustic4_3D.c
new file mode 100644
index 0000000000000000000000000000000000000000..f4d984ba533f4bce422efd75989cc316cc97a521
--- /dev/null
+++ b/fdelmodc3D/viscoacoustic4_3D.c
@@ -0,0 +1,210 @@
+#include<stdlib.h>
+#include<stdio.h>
+#include<math.h>
+#include<assert.h>
+#include"fdelmodc3D.h"
+
+long applySource3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime,
+    long ixsrc, long iysrc, long izsrc, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float **src_nwav, long verbose);
+
+long storeSourceOnSurface3D(modPar mod, srcPar src, bndPar bnd, long ixsrc, long iysrc, long izsrc,
+    float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx,
+    float *txz, float *txy, float *tyz, long verbose);
+
+long reStoreSourceOnSurface3D(modPar mod, srcPar src, bndPar bnd, long ixsrc, long iysrc, long izsrc,
+    float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx,
+    float *txz, float *txy, float *tyz, long verbose);
+
+long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul,
+    long itime, long verbose);
+
+long boundariesV3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz,
+    float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz,
+    float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul,
+    long itime, long verbose);
+
+long viscoacoustic4_3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime,
+	long ixsrc, long iysrc, long izsrc, float **src_nwav, float *vx, float *vy, float *vz,
+	float *p, float *rox, float *roy, float *roz, float *l2m, float *tss, float *tep,
+	float *q, long verbose)
+{
+/*********************************************************************
+       COMPUTATIONAL OVERVIEW OF THE 4th ORDER STAGGERED GRID: 
+
+  The captial symbols T (=Txx,Tzz) Txz,Vx,Vz represent the actual grid
+  The indices ix,iz are related to the T grid, so the capital T 
+  symbols represent the actual modelled grid.
+
+  one cel (iz,ix)
+       |
+       V                              extra column of vx,txz
+                                                      |
+    -------                                           V
+   | txz vz| txz vz  txz vz  txz vz  txz vz  txz vz txz
+   |       |      
+   | vx  t | vx  t   vx  t   vx  t   vx  t   vx  t  vx
+    -------
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz
+
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   | 
+     txz vz  txz Vz--Txz-Vz--Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   |
+     txz vz  txz Vz  Txz-Vz  Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+                 |   |   |   |   |   |   |
+     txz vz  txz Vz  Txz-Vz  Txz-Vz  Txz-Vz  txz vz  txz
+                 |   |   |   |   |   |   |
+     vx  t   vx  T---Vx--T---Vx--T---Vx--T   vx  t   vx
+
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz
+
+     vx  t   vx  t   vx  t   vx  t   vx  t   vx  t  vx
+
+     txz vz  txz vz  txz vz  txz vz  txz vz  txz vz  txz  <--| 
+                                                             |
+                                         extra row of txz/vz |
+
+   AUTHOR:
+           Jan Thorbecke (janth@xs4all.nl)
+           The Netherlands 
+
+***********************************************************************/
+
+	float	c1, c2;
+	long	ix, iy, iz;
+	long	n1, n2;
+	float	ddt, Tpp, *Tlm, *Tlp, *Tt1, *Tt2, *dxvx, *dyvy, *dzvz;
+
+
+	c1 = 9.0/8.0; 
+	c2 = -1.0/24.0;
+	n1  = mod.naz;
+	n2  = mod.nax;
+	ddt = 1.0/mod.dt;
+
+	dxvx = (float *)malloc(n1*sizeof(float));
+	dyvy = (float *)malloc(n1*sizeof(float));
+	dzvz = (float *)malloc(n1*sizeof(float));
+	Tlm = (float *)malloc(n1*sizeof(float));
+	Tlp = (float *)malloc(n1*sizeof(float));
+	Tt1 = (float *)malloc(n1*sizeof(float));
+	Tt2 = (float *)malloc(n1*sizeof(float));
+
+	/* calculate vx for all grid points except on the virtual boundary*/
+#pragma omp for private (ix, iy, iz) nowait schedule(guided,1)
+	for (iy=mod.ioXy; iy<mod.ieXy; iy++) {
+		for (ix=mod.ioXx; ix<mod.ieXx; ix++) {
+#pragma ivdep
+			for (iz=mod.ioXz; iz<mod.ieXz; iz++) {
+				vx[iy*n2*n1+ix*n1+iz] -= rox[iy*n2*n1+ix*n1+iz]*(
+							c1*(p[iy*n2*n1+ix*n1+iz]     - p[iy*n2*n1+(ix-1)*n1+iz]) +
+							c2*(p[iy*n2*n1+(ix+1)*n1+iz] - p[iy*n2*n1+(ix-2)*n1+iz]));
+			}
+		}
+	}
+
+	/* calculate vy for all grid points except on the virtual boundary */
+#pragma omp for private (ix, iy, iz)  schedule(guided,1)
+	for (iy=mod.ioYy; iy<mod.ieYy; iy++) {
+		for (ix=mod.ioYx; ix<mod.ieYx; ix++) {
+#pragma ivdep
+			for (iz=mod.ioYz; iz<mod.ieYz; iz++) {
+				vy[iy*n2*n1+ix*n1+iz] -= roy[iy*n2*n1+ix*n1+iz]*(
+							c1*(p[iy*n2*n1+ix*n1+iz]     - p[(iy-1)*n2*n1+ix*n1+iz]) +
+							c2*(p[(iy+1)*n2*n1+ix*n1+iz] - p[(iy-2)*n2*n1+ix*n1+iz]));
+			}
+		}
+	}
+
+	/* calculate vz for all grid points except on the virtual boundary */
+#pragma omp for private (ix, iy, iz)  schedule(guided,1)
+	for (iy=mod.ioZy; iy<mod.ieZy; iy++) {
+		for (ix=mod.ioZx; ix<mod.ieZx; ix++) {
+#pragma ivdep
+			for (iz=mod.ioZz; iz<mod.ieZz; iz++) {
+				vz[iy*n2*n1+ix*n1+iz] -= roz[iy*n2*n1+ix*n1+iz]*(
+							c1*(p[iy*n2*n1+ix*n1+iz]   - p[iy*n2*n1+ix*n1+iz-1]) +
+							c2*(p[iy*n2*n1+ix*n1+iz+1] - p[iy*n2*n1+ix*n1+iz-2]));
+			}
+		}
+	}
+
+	/* boundary condition clears velocities on boundaries */
+    boundariesP3D(mod, bnd, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, NULL, NULL, itime, verbose);
+    
+	/* Add force source */
+	if (src.type > 5) {
+         applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, src_nwav, verbose);
+	}
+
+	/* calculate p/tzz for all grid points except on the virtual boundary */
+#pragma omp	for private (iz, iy, ix, Tpp) nowait schedule(guided,1)
+	for (iy=mod.ioPy; iy<mod.iePy; iy++) {
+		for (ix=mod.ioPx; ix<mod.iePx; ix++) {
+#pragma ivdep
+			for (iz=mod.ioPz; iz<mod.iePz; iz++) {
+				dxvx[iz] = c1*(vx[iy*n2*n1+(ix+1)*n1+iz] - vx[iy*n2*n1+ix*n1+iz]) +
+						   c2*(vx[iy*n2*n1+(ix+2)*n1+iz] - vx[iy*n2*n1+(ix-1)*n1+iz]);
+				dyvy[iz] = c1*(vy[(iy+1)*n2*n1+ix*n1+iz] - vy[iy*n2*n1+ix*n1+iz]) +
+						   c2*(vy[(iy+2)*n2*n1+ix*n1+iz] - vy[(iy-1)*n2*n1+ix*n1+iz]);
+				dzvz[iz] = c1*(vz[iy*n2*n1+ix*n1+iz+1]   - vz[iy*n2*n1+ix*n1+iz]) +
+						   c2*(vz[iy*n2*n1+ix*n1+iz+2]   - vz[iy*n2*n1+ix*n1+iz-1]);
+			}
+
+			/* help variables to let the compiler vectorize the loops */
+#pragma ivdep
+			for (iz=mod.ioPz; iz<mod.iePz; iz++) {
+				Tpp     = tep[iy*n2*n1+ix*n1+iz]*tss[iy*n2*n1+ix*n1+iz];
+				Tlm[iz] = (1.0-Tpp)*tss[iy*n2*n1+ix*n1+iz]*l2m[iy*n2*n1+ix*n1+iz]*0.5;
+				Tlp[iz] = l2m[iy*n2*n1+ix*n1+iz]*Tpp;
+				Tt1[iz] = 1.0/(ddt+0.5*tss[iy*n2*n1+ix*n1+iz]);
+				Tt2[iz] = ddt-0.5*tss[iy*n2*n1+ix*n1+iz];
+			}   
+
+			/* the update with the relaxation correction */
+#pragma ivdep
+			for (iz=mod.ioPz; iz<mod.iePz; iz++) {
+				p[iy*n2*n1+ix*n1+iz] -= Tlp[iz]*(dzvz[iz]+dxvx[iz]) + q[ix*n1+iz];
+			}
+#pragma ivdep
+			for (iz=mod.ioPz; iz<mod.iePz; iz++) {
+				q[iy*n2*n1+ix*n1+iz] = (Tt2[iz]*q[iy*n2*n1+ix*n1+iz] + Tlm[iz]*(dxvx[iz]+dyvy[iz]+dzvz[iz]))*Tt1[iz];
+				p[iy*n2*n1+ix*n1+iz] -= q[iy*n2*n1+ix*n1+iz];
+			}
+		}
+	}
+
+	/* Add stress source */
+	if (src.type < 6) {
+        applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, src_nwav, verbose);
+	}
+
+/* Free surface: calculate free surface conditions for stresses */
+
+	/* check if there are sources placed on the free surface */
+    storeSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, verbose);
+
+	/* Free surface: calculate free surface conditions for stresses */
+    boundariesV3D(mod, bnd, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, NULL, NULL, itime, verbose);
+
+	/* restore source positions on the edge */
+    reStoreSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, verbose);
+
+	free(dxvx);
+	free(dyvy);
+	free(dzvz);
+	free(Tlm);
+	free(Tlp);
+	free(Tt1);
+	free(Tt2);
+
+	return 0;
+}
diff --git a/fdelmodc3D/writeRec3D.c b/fdelmodc3D/writeRec3D.c
index c29d669a46711e08bb028f9ab7488260e288617a..35349c287d08b37f59e7accfd80bc677597ef656 100644
--- a/fdelmodc3D/writeRec3D.c
+++ b/fdelmodc3D/writeRec3D.c
@@ -86,7 +86,7 @@ long writeRec3D(recPar rec, modPar mod, bndPar bnd, wavPar wav, long ixsrc, long
     hdr.scalco = -1000;
     hdr.scalel = -1000;
     hdr.sx     = 1000*(mod.x0+ixsrc*mod.dx);
-    hdr.sy     = 1000*(mod.y0+ixsrc*mod.dy);
+    hdr.sy     = 1000*(mod.y0+iysrc*mod.dy);
     hdr.sdepth = 1000*(mod.z0+izsrc*mod.dz);
     hdr.selev  = (int)(-1000.0*(mod.z0+izsrc*mod.dz));
     hdr.fldr   = ishot+1;
diff --git a/marchenko3D/ampest3D.c b/marchenko3D/ampest3D.c
index 08b480b642ec861b4b0d6222e5ed238c6b7a1a17..269ea16a9e6bb91d0831b66d7abf18e0532a6d3d 100644
--- a/marchenko3D/ampest3D.c
+++ b/marchenko3D/ampest3D.c
@@ -23,11 +23,11 @@ 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,
+void AmpEst3D(float *f1d, float *Gd, float *ampest, long Nfoc, long nxs, long nys, long ntfft, long *ixpos, long *iypos, long npos,
     char *file_wav, float dx, float dy, float dt)
 {
 	
-	long 	l, i, ix, iw, nfreq;
+	long 	l, i, ix, iy, iw, nfreq;
 	float 	scl, sclt, *wavelet, *scaled, *conv, *f1dsamp;
 	float   dtm, dxm, cpm, rom, *trace;
 	FILE 	*fp_wav;
@@ -59,8 +59,9 @@ void AmpEst3D(float *f1d, float *Gd, float *ampest, long Nfoc, long nxs, long ny
 	for (l=0; l<Nfoc; l++) {
 		for (i=0; i<npos; i++) {
 			ix = ixpos[i];
+			iy = iypos[i];
 			for (iw=0; iw<ntfft; iw++) {
-				f1dsamp[i*ntfft+iw] = f1d[l*nxs*nys*ntfft+ix*ntfft+iw];
+				f1dsamp[i*ntfft+iw] = f1d[l*nxs*nys*ntfft+iy*nxs*ntfft+ix*ntfft+iw];
 			}
 		}
 		if (file_wav==NULL){
diff --git a/marchenko3D/applyMute.c b/marchenko3D/applyMute.c
deleted file mode 100644
index df98e8bc39f8b132c10b237f7e3e01f3167cdf7d..0000000000000000000000000000000000000000
--- a/marchenko3D/applyMute.c
+++ /dev/null
@@ -1,115 +0,0 @@
-#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 applyMute( float *data, int *mute, int smooth, int above, int Nfoc, int nxs, int nt, int *ixpos, int npos, int shift)
-{
-     int i, j, l, isyn;
-    float *costaper, scl;
-    int imute, tmute;
-
-    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));
-        }
-    }
-
-    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/applyMute3D.c b/marchenko3D/applyMute3D.c
index 82adead728e57f820e49dbf3ea14b337ae6f64dd..b50fd4467e447ab5d7bc22e967de72ea779c3bed 100644
--- a/marchenko3D/applyMute3D.c
+++ b/marchenko3D/applyMute3D.c
@@ -12,12 +12,14 @@
 #endif
 #define NINT(x) ((long)((x)>0.0?(x)+0.5:(x)-0.5))
 
-void applyMute3D( float *data, long *mute, long smooth, long above, long Nfoc, long nxs, long nt, long *ixpos, long npos, long shift)
+void applyMute3D( float *data, long *mute, long smooth, long above, long Nfoc, long nxs, long nys, long nt, long *ixpos, long *iypos, long npos, long shift)
 {
-    long ix, iy, i, j, l, isyn;
+    long ix, iy, i, j, l, isyn, nxys;
     float *costaper, scl;
     long imute, tmute;
 
+    nxys = nxs*nys;
+
     if (smooth) {
         costaper = (float *)malloc(smooth*sizeof(float));
         scl = M_PI/((float)smooth);
@@ -29,80 +31,80 @@ void applyMute3D( float *data, long *mute, long smooth, long above, long Nfoc, l
     for (isyn = 0; isyn < Nfoc; isyn++) {
         if (above==1) {
             for (i = 0; i < npos; i++) {
-                imute = ixpos[i];
-                tmute = mute[isyn*nxs+imute];
+                imute = iypos[i]*nxs+ixpos[i];
+                tmute = mute[isyn*nxys+imute];
                 for (j = 0; j < MAX(0,tmute-shift-smooth); j++) {
-                    data[isyn*nxs*nt+i*nt+j] = 0.0;
+                    data[isyn*nxys*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];
+                    data[isyn*nxys*nt+i*nt+j] *= costaper[smooth-l-1];
                 }
             }
         }
         else if (above==0){
             for (i = 0; i < npos; i++) {
-                imute = ixpos[i];
+                imute = iypos[i]*nxs+ixpos[i];
                 tmute = mute[isyn*nxs+imute];
                 if (tmute >= nt/2) {
-                    memset(&data[isyn*nxs*nt+i*nt],0, sizeof(float)*nt);
+                    memset(&data[isyn*nxys*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];
+                    data[isyn*nxys*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;
+                    data[isyn*nxys*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];
+                    data[isyn*nxys*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];
+                imute = iypos[i]*nxs+ixpos[i];
+                tmute = mute[isyn*nxys+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];
+                    data[isyn*nxys*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;
+                    data[isyn*nxys*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];
+                imute = iypos[i]*nxs+ixpos[i];
+                tmute = mute[isyn*nxys+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];
+                    data[isyn*nxys*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;
+                    data[isyn*nxys*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;
+                    data[isyn*nxys*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];
+                    data[isyn*nxys*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];
+                imute = iypos[i]*nxs+ixpos[i];
+                tmute = mute[isyn*nxys+imute];
                 for (j = 0; j < MAX(0,tmute-shift-smooth); j++) {
-                    data[isyn*nxs*nt+i*nt+j] = 0.0;
+                    data[isyn*nxys*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];
+                    data[isyn*nxys*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];
+                    data[isyn*nxys*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;
+                    data[isyn*nxys*nt+i*nt+j] = 0.0;
                 }
             }
         }
diff --git a/marchenko3D/fmute.c b/marchenko3D/fmute.c
deleted file mode 100644
index ba4f39acb407d3dacf414096dafc0b3ab67a2c8d..0000000000000000000000000000000000000000
--- a/marchenko3D/fmute.c
+++ /dev/null
@@ -1,370 +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 */
-
-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);
-int disp_fileinfo(char *file, int n1, int n2, float f1, float f2, float d1, float d2, 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[] = {
-" ",
-" fmute - mute in time domain file_shot along curve of maximum amplitude in file_mute ",
-" ",
-" fmute 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)",
-" ",
-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, nt1, nx2, nt2;
-    int     ntmax, nxmax, ret, i, j, jmax, imax, above, check;
-    int     size, ntraces, ngath, *maxval, hw, smooth;
-    int     tstart, tend, scale, *xrcv;
-    float   dt, d2, f1, f2, t0, t1, f1b, f2b, d1, d1b, d2b;
-    float    w1, w2, dxrcv;
-    float     *tmpdata, *tmpdata2, *costaper;
-    char     *file_mute, *file_shot, *file_out;
-    float   scl, sclsxgx, sclshot, xmin, xmax, tmax, lmax;
-    segy    *hdrs_in1, *hdrs_in2;
-
-    t0 = wallclock_time();
-    initargs(argc, argv);
-    requestdoc(1);
-
-    if(!getparstring("file_mute", &file_mute)) file_mute=NULL;
-    if(!getparstring("file_shot", &file_shot)) file_shot=NULL;
-    if(!getparstring("file_out", &file_out)) file_out=NULL;
-    if(!getparint("ntmax", &ntmax)) ntmax = 1024;
-    if(!getparint("nxmax", &nxmax)) nxmax = 512;
-    if(!getparint("above", &above)) above = 0;
-    if(!getparint("check", &check)) check = 0;
-    if(!getparint("scale", &scale)) scale = 0;
-    if(!getparint("hw", &hw)) hw = 15;
-    if(!getparint("smooth", &smooth)) smooth = 0;
-    if(!getparfloat("w1", &w1)) w1=1.0;
-    if(!getparfloat("w2", &w2)) w2=1.0;
-    if(!getparint("shift", &shift)) shift=0;
-    if(!getparint("verbose", &verbose)) verbose=0;
-
-/* Reading input data for file_mute */
-
-    if (file_mute != NULL) {
-        ngath = 1;
-        getFileInfo(file_mute, &nt1, &nx1, &ngath, &d1, &d2, &f1, &f2, &xmin, &xmax, &sclsxgx, &ntraces);
-
-        if (!getparint("ntmax", &ntmax)) ntmax = nt1;
-        if (!getparint("nxmax", &nxmax)) nxmax = nx1;
-        if (verbose>=2 && (ntmax!=nt1 || nxmax!=nx1))
-            vmess("dimensions overruled: %d x %d",ntmax,nxmax);
-        if(!getparfloat("dt", &dt)) dt=d1;
-
-        fp_in1 = fopen(file_mute, "r");
-        if (fp_in1 == NULL) verr("error on opening input file_mute=%s", file_mute);
-
-        size = ntmax * nxmax;
-        tmpdata = (float *)malloc(size*sizeof(float));
-        hdrs_in1 = (segy *) calloc(nxmax,sizeof(segy));
-
-        nx1 = readData(fp_in1, tmpdata, hdrs_in1, nt1);
-        if (nx1 == 0) {
-            fclose(fp_in1);
-            if (verbose) vmess("end of file_mute data reached");
-        }
-
-        if (verbose) {
-            disp_fileinfo(file_mute, nt1, nx1, f1,  f2,  dt,  d2, hdrs_in1);
-        }
-    }
-
-/* Reading input data for file_shot */
-
-    ngath = 1;
-    getFileInfo(file_shot, &nt2, &nx2, &ngath, &d1b, &d2b, &f1b, &f2b, &xmin, &xmax, &sclshot, &ntraces);
-
-    if (!getparint("ntmax", &ntmax)) ntmax = nt2;
-    if (!getparint("nxmax", &nxmax)) nxmax = nx2;
-
-    size = ntmax * nxmax;
-    tmpdata2 = (float *)malloc(size*sizeof(float));
-    hdrs_in2 = (segy *) calloc(nxmax,sizeof(segy));
-
-    if (file_shot != NULL) fp_in2 = fopen(file_shot, "r");
-    else fp_in2=stdin;
-    if (fp_in2 == NULL) verr("error on opening input file_shot=%s", file_shot);
-
-    nx2 = readData(fp_in2, tmpdata2, hdrs_in2, nt2);
-    if (nx2 == 0) {
-        fclose(fp_in2);
-        if (verbose) vmess("end of file_shot data reached");
-    }
-    nt2 = hdrs_in2[0].ns;
-    f1b = hdrs_in2[0].f1;
-    f2b = hdrs_in2[0].f2;
-    d1b = (float)hdrs_in2[0].dt*1e-6;
-        
-    if (verbose) {
-        disp_fileinfo(file_shot, nt2, nx2, f1b,  f2b,  d1b,  d2b, hdrs_in2);
-    }
-    
-    /* file_shot will be used as well to define the mute window */
-    if (file_mute == NULL) {
-        nx1=nx2;
-        nt1=nt2;
-        dt=d1b;
-        f1=f1b;
-        f2=f2b;
-        tmpdata = tmpdata2;
-        hdrs_in1 = hdrs_in2;
-        sclsxgx = sclshot;
-    }
-
-    if (verbose) vmess("sampling file_mute=%d, file_shot=%d", nt1, nt2);
-
-/*================ initializations ================*/
-
-    maxval = (int *)calloc(nx1,sizeof(int));
-    xrcv   = (int *)calloc(nx1,sizeof(int));
-    
-    if (file_out==NULL) fp_out = stdout;
-    else {
-        fp_out = fopen(file_out, "w+");
-        if (fp_out==NULL) verr("error on ceating output file");
-    }
-    if (check!=0){
-        fp_chk = fopen("check.su", "w+");
-        if (fp_chk==NULL) verr("error on ceating output file");
-        fp_psline1 = fopen("pslinepos.asci", "w+");
-        if (fp_psline1==NULL) verr("error on ceating output file");
-        fp_psline2 = fopen("pslineneg.asci", "w+");
-        if (fp_psline2==NULL) verr("error on ceating output file");
-        
-    }
-    if (smooth) {
-        costaper = (float *)malloc(smooth*sizeof(float));
-        scl = M_PI/((float)smooth);
-        for (i=0; i<smooth; i++) {
-            costaper[i] = 0.5*(1.0+cos((i+1)*scl));
-/*            fprintf(stderr,"costaper[%d]=%f\n",i,costaper[i]);*/
-        }
-    }
-
-/*================ loop over all shot records ================*/
-
-    k=1;
-    while (nx1 > 0) {
-        if (verbose) vmess("processing input gather %d", k);
-
-/*================ loop over all shot records ================*/
-
-        /* find consistent (one event) maximum related to maximum value */
-        
-        /* find global maximum 
-        xmax=0.0;
-        for (i = 0; i < nx1; i++) {
-            tmax=0.0;
-            jmax = 0;
-            for (j = 0; j < nt1; j++) {
-                lmax = fabs(tmpdata[i*nt1+j]);
-                if (lmax > tmax) {
-                    jmax = j;
-                    tmax = lmax;
-                    if (lmax > xmax) {
-                        imax = i;
-                        xmax=lmax;
-                    }
-                }
-            }
-            maxval[i] = jmax;
-        }
-        */
-
-        /* alternative find maximum at source position */
-        dxrcv = (hdrs_in1[nx1-1].gx - hdrs_in1[0].gx)*sclsxgx/(float)(nx1-1);
-        imax = NINT(((hdrs_in1[0].sx-hdrs_in1[0].gx)*sclsxgx)/dxrcv);
-        tmax=0.0;
-        jmax = 0;
-        xmax=0.0;
-        for (j = 0; j < nt1; j++) {
-            lmax = fabs(tmpdata[imax*nt1+j]);
-            if (lmax > tmax) {
-                jmax = j;
-                tmax = lmax;
-                   if (lmax > xmax) {
-                       xmax=lmax;
-                   }
-            }
-        }
-        maxval[imax] = jmax;
-        if (verbose >= 3) vmess("Mute max at src-trace %d is sample %d", imax, maxval[imax]);
-
-        /* search forward */
-        for (i = imax+1; i < nx1; i++) {
-            tstart = MAX(0, (maxval[i-1]-hw));
-            tend   = MIN(nt1-1, (maxval[i-1]+hw));
-            jmax=tstart;
-            tmax=0.0;
-            for(j = tstart; j <= tend; j++) {
-                lmax = fabs(tmpdata[i*nt1+j]);
-                if (lmax > tmax) {
-                    jmax = j;
-                    tmax = lmax;
-                }
-            }
-            maxval[i] = jmax;
-        }
-        /* search backward */
-        for (i = imax-1; i >=0; i--) {
-            tstart = MAX(0, (maxval[i+1]-hw));
-            tend   = MIN(nt1-1, (maxval[i+1]+hw));
-            jmax=tstart;
-            tmax=0.0;
-            for(j = tstart; j <= tend; j++) {
-                lmax = fabs(tmpdata[i*nt1+j]);
-                if (lmax > tmax) {
-                    jmax = j;
-                    tmax = lmax;
-                }
-            }
-            maxval[i] = jmax;
-        }
-
-/* scale with maximum ampltiude */
-
-        if (scale==1) {
-            for (i = 0; i < nx2; i++) {
-                lmax = fabs(tmpdata2[i*nt2+maxval[i]]);
-                for (j = 0; j < nt2; j++) {
-                    tmpdata2[i*nt2+j] = tmpdata2[i*nt2+j]/lmax;
-                }
-            }
-        }
-
-        for (i = 0; i < nx2; i++) xrcv[i] = i;
-
-/*================ apply mute window ================*/
-
-        applyMute(tmpdata2, maxval, smooth, above, 1, nx2, nt2, xrcv, nx2, shift);
-
-/*================ write result to output file ================*/
-
-        ret = writeData(fp_out, tmpdata2, hdrs_in2, nt2, nx2);
-        if (ret < 0 ) verr("error on writing output file.");
-
-        /* put mute window in file to check correctness of mute */
-        if (check !=0) {
-            for (i = 0; i < nx1; i++) {
-                jmax = maxval[i]-shift;
-                tmpdata[i*nt1+jmax] = 2*xmax;
-            }
-            if (above==0){
-                for (i = 0; i < nx1; i++) {
-                    jmax = nt2-maxval[i]+shift;
-                    tmpdata[i*nt1+jmax] = 2*xmax;
-                }
-            }
-            ret = writeData(fp_chk, tmpdata, hdrs_in1, nt1, nx1);
-            if (ret < 0 ) verr("error on writing check file.");
-            for (i=0; i<nx1; i++) {
-                jmax = maxval[i]-shift;
-                ret = fprintf(fp_psline1, "%.5f %.5f \n",jmax*dt,hdrs_in1[i].gx*sclshot);
-                jmax =-maxval[i]+shift;
-                ret = fprintf(fp_psline2, "%.5f %.5f \n",jmax*dt,hdrs_in1[i].gx*sclshot);
-            }
-        }
-
-/*================ Read next record for muting ================*/
-
-        if (file_mute != NULL) {    
-            nx1 = readData(fp_in1, tmpdata, hdrs_in1, nt1);
-            if (nx1 == 0) {
-                fclose(fp_in1);
-                if (verbose) vmess("end of file_mute data reached");
-                fclose(fp_in2);
-                if (fp_out!=stdout) fclose(fp_out);
-                if (check!=0) fclose(fp_chk);
-                if (check!=0) {
-                    fclose(fp_psline1);
-                    fclose(fp_psline2);
-                }
-                break;
-            }
-            nt1 = (int)hdrs_in1[0].ns;
-            if (nt1 > ntmax) verr("n_samples (%d) greater than ntmax", nt1);
-            if (nx1 > nxmax) verr("n_traces  (%d) greater than nxmax", nx1);
-        }
-
-/*================ Read next shot record(s) ================*/
-
-        nx2 = readData(fp_in2, tmpdata2, hdrs_in2, nt2);
-        if (nx2 == 0) {
-            if (verbose) vmess("end of file_shot data reached");
-            fclose(fp_in2);
-            break;
-        }
-        nt2 = (int)hdrs_in2[0].ns;
-        if (nt2 > ntmax) verr("n_samples (%d) greater than ntmax", nt2);
-        if (nx2 > nxmax) verr("n_traces  (%d) greater than nxmax", nx2);
-
-        if (file_mute == NULL) {
-            nx1=nx2;
-            nt1=nt2;
-            hdrs_in1 = hdrs_in2;
-            tmpdata = tmpdata2;
-        }
-
-        k++;
-    }
-
-    t1 = wallclock_time();
-    if (verbose) vmess("Total CPU-time = %f",t1-t0);
-    
-
-    return 0;
-}
-
diff --git a/marchenko3D/fmute3D.c b/marchenko3D/fmute3D.c
index fa03b817592628cb532ae04bc489f758ac704fbb..9c5207350e3ed5ac705749ea1cf4cb2c4a2d4a27 100644
--- a/marchenko3D/fmute3D.c
+++ b/marchenko3D/fmute3D.c
@@ -26,7 +26,7 @@ long getFileInfo3D(char *filename, long *n1, long *n2, long *n3, long *ngath, fl
 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);
-void applyMute3D( float *data, long *mute, long smooth, long above, long Nfoc, long nxs, long nt, long *ixpos, long npos, long shift);
+void applyMute3D( float *data, long *mute, long smooth, long above, long Nfoc, long nxs, long nys, long nt, long *ixpos, long *iypos, long npos, long shift);
 double wallclock_time(void);
 
 /*********************** self documentation **********************/
@@ -67,7 +67,7 @@ long main (int argc, char **argv)
     long        verbose, shift, k, nx1, ny1, nt1, nx2, ny2, nt2, nxy;
     long     ntmax, nxmax, nymax, ret, i, j, l, jmax, ixmax, iymax, above, check;
     long     size, ntraces, ngath, *maxval, hw, smooth;
-    long     tstart, tend, scale, *xrcv;
+    long     tstart, tend, scale, *xrcv, *yrcv;
     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;
@@ -179,6 +179,7 @@ long main (int argc, char **argv)
     nxy    = nx1*ny1;
     maxval = (long *)calloc(nxy,sizeof(long));
     xrcv   = (long *)calloc(nxy,sizeof(long));
+    yrcv   = (long *)calloc(nxy,sizeof(long));
     
     if (file_out==NULL) fp_out = stdout;
     else {
@@ -406,13 +407,14 @@ long main (int argc, char **argv)
 
         for (l = 0; l < ny2; l++) {
             for (i = 0; i < nx2; i++) {
-                xrcv[l*nx2+i] = l*nx2+i;
+                xrcv[l*nx2+i] = i;
+                yrcv[l*nx2+i] = l;
             }
         }
 
 /*================ apply mute window ================*/
         
-        applyMute3D(tmpdata2, maxval, smooth, above, 1, nx2*ny2, nt2, xrcv, nx2*ny2, shift);
+        applyMute3D(tmpdata2, maxval, smooth, above, 1, nx2, ny2, nt2, xrcv, yrcv, nx2*ny2, shift);
 
 /*================ write result to output file ================*/
 
diff --git a/marchenko3D/getFileInfo.c b/marchenko3D/getFileInfo.c
deleted file mode 120000
index ae38ea27f17697d65d7248c8e89038b632314182..0000000000000000000000000000000000000000
--- a/marchenko3D/getFileInfo.c
+++ /dev/null
@@ -1 +0,0 @@
-../utils/getFileInfo.c
\ No newline at end of file
diff --git a/marchenko3D/marchenko.c b/marchenko3D/marchenko.c
deleted file mode 100644
index 9812335d5eeca1883de2be2810350e053687f58b..0000000000000000000000000000000000000000
--- a/marchenko3D/marchenko.c
+++ /dev/null
@@ -1,1030 +0,0 @@
-/*
- * 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))
-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 */
-
-int readShotData(char *filename, float *xrcv, float *xsrc, float *zsrc, int *xnx, complex *cdata, int nw, int nw_low, int nshots,
-int nx, int nxs, float fxsb, float dxs, int ntfft, int mode, float scale, float tsq, float Q, float f0, int reci, int *nshots_r, int *isxcount, int *reci_xsrc,  int *reci_xrcv, float *ixmask, int verbose);
-int readTinvData(char *filename, float *xrcv, float *xsrc, float *zsrc, int *xnx, int Nfoc, int nx, 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);
-
-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 getFileInfo(char *filename, int *n1, int *n2, int *ngath, float *d1, float *d2, float *f1, float *f2, float *xmin, float *xmax, float *sclsxgx, int *ntraces);
-int readData(FILE *fp, float *data, segy *hdrs, int n1);
-int writeData(FILE *fp, float *data, segy *hdrs, int n1, int n2);
-int disp_fileinfo(char *file, int n1, int n2, float f1, float f2, float d1, float d2, segy *hdrs);
-double wallclock_time(void);
-
-void synthesis(complex *Refl, complex *Fop, float *Top, float *iRN, int nx, int nt, int nxs, int nts, float dt, float *xsyn, int
-Nfoc, float *xrcv, float *xsrc, int *xnx, float fxse, float fxsb, float dxs, float dxsrc, float dx, int ntfft, int
-nw, int nw_low, int nw_high,  int mode, int reci, int nshots, int *ixpos, int npos, double *tfft, int *isxcount, int
-*reci_xsrc,  int *reci_xrcv, float *ixmask, int verbose);
-
-void synthesisPosistions(int nx, int nt, int nxs, int nts, float dt, float *xsyn, int Nfoc, float *xrcv, float *xsrc, int *xnx,
-float fxse, float fxsb, float dxs, float dxsrc, float dx, int nshots, int *ixpos, int *npos, int *isxcount, int countmin, int reci, 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 ",
-"   tsq=0.0 .................. scale factor n for t^n for true amplitude recovery",
-"   Q=0.0 .......,............ Q correction factor",
-"   f0=0.0 ................... ... for Q correction factor",
-"   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, ret, nshots, Nfoc, nt, nx, nts, nxs, ngath;
-    int     size, n1, n2, ntap, tap, di, ntraces, pad;
-    int     nw, nw_low, nw_high, nfreq, *xnx, *xnxsyn;
-    int     reci, countmin, mode, n2out, 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, dxf, *xsrc, *xrcv, *zsyn, *zsrc, *xrcvsyn;
-    double  t0, t1, t2, t3, tsyn, tread, tfft, tcopy, energyNi, energyN0;
-    float   d1, d2, f1, f2, fxsb, fxse, ft, fx, *xsyn, dxsrc;
-    float   *green, *f2p, *pmin, *G_d, dt, dx, dxs, scl, mem;
-    float   *f1plus, *f1min, *iRN, *Ni, *trace, *Gmin, *Gplus;
-    float   xmin, xmax, scale, tsq, Q, f0;
-    float   *ixmask;
-    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 = getFileInfo(file_tinv, &n1, &n2, &ngath, &d1, &d2, &f1, &f2, &xmin, &xmax, &scl, &ntraces);
-    Nfoc = ngath;
-    nxs  = n2; 
-    nts  = n1;
-    dxs  = d2; 
-    fxsb = f2; 
-
-    ngath = 0; /* setting ngath=0 scans all traces; nx contains maximum traces/gather */
-    ret = getFileInfo(file_shot, &nt, &nx, &ngath, &d1, &dx, &ft, &fx, &xmin, &xmax, &scl, &ntraces);
-    nshots = ngath;
-    assert (nxs >= nshots);
-
-    if (!getparfloat("dt", &dt)) dt = d1;
-
-    ntfft = optncr(MAX(nt+pad, nts+pad)); 
-    nfreq = ntfft/2+1;
-    nw_low = (int)MIN((fmin*ntfft*dt), nfreq-1);
-    nw_low = MAX(nw_low, 1);
-    nw_high = MIN((int)(fmax*ntfft*dt), nfreq-1);
-    nw  = nw_high - nw_low + 1;
-    scl   = 1.0/((float)ntfft);
-    if (!getparint("countmin", &countmin)) countmin = 0.3*nx;
-    
-/*================ Allocating all data arrays ================*/
-
-    Fop     = (complex *)calloc(nxs*nw*Nfoc,sizeof(complex));
-    green   = (float *)calloc(Nfoc*nxs*ntfft,sizeof(float));
-    f2p     = (float *)calloc(Nfoc*nxs*ntfft,sizeof(float));
-    pmin    = (float *)calloc(Nfoc*nxs*ntfft,sizeof(float));
-    f1plus  = (float *)calloc(Nfoc*nxs*ntfft,sizeof(float));
-    f1min   = (float *)calloc(Nfoc*nxs*ntfft,sizeof(float));
-    iRN     = (float *)calloc(Nfoc*nxs*ntfft,sizeof(float));
-    Ni      = (float *)calloc(Nfoc*nxs*ntfft,sizeof(float));
-    G_d     = (float *)calloc(Nfoc*nxs*ntfft,sizeof(float));
-    muteW   = (int *)calloc(Nfoc*nxs,sizeof(int));
-    trace   = (float *)malloc(ntfft*sizeof(float));
-    tapersy = (float *)malloc(nxs*sizeof(float));
-    xrcvsyn = (float *)calloc(Nfoc*nxs,sizeof(float)); // x-rcv postions of focal points
-    xsyn    = (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(nxs,sizeof(int)); // x-position of source of shot in G_d domain (nxs with dxs)
-
-    Refl    = (complex *)malloc(nw*nx*nshots*sizeof(complex));
-    tapersh = (float *)malloc(nx*sizeof(float));
-    xrcv    = (float *)calloc(nshots*nx,sizeof(float)); // x-rcv postions of shots
-    xsrc    = (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)*sizeof(int));
-        reci_xrcv = (int *)malloc((nxs*nxs)*sizeof(int));
-        isxcount  = (int *)calloc(nxs,sizeof(int));
-        ixmask  = (float *)calloc(nxs,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 */
-    readTinvData(file_tinv, xrcvsyn, xsyn, zsyn, xnxsyn, Nfoc, nxs, ntfft, 
-         mode, muteW, G_d, hw, verbose);
-    /* reading data added zero's to the number of time samples to be the same as ntfft */
-    nts   = ntfft;
-                             
-    /* define tapers to taper edges of acquisition */
-    if (tap == 1 || tap == 3) {
-        for (j = 0; j < ntap; j++)
-            tapersy[j] = (cos(PI*(j-ntap)/ntap)+1)/2.0;
-        for (j = ntap; j < nxs-ntap; j++)
-            tapersy[j] = 1.0;
-        for (j = nxs-ntap; j < nxs; j++)
-            tapersy[j] =(cos(PI*(j-(nxs-ntap))/ntap)+1)/2.0;
-    }
-    else {
-        for (j = 0; j < nxs; j++) tapersy[j] = 1.0;
-    }
-    if (tap == 1 || tap == 3) {
-        if (verbose) vmess("Taper for operator applied ntap=%d", ntap);
-        for (l = 0; l < Nfoc; l++) {
-            for (i = 0; i < nxs; i++) {
-                for (j = 0; j < nts; j++) {
-                    G_d[l*nxs*nts+i*nts+j] *= tapersy[i];
-                }   
-            }   
-        }   
-    }
-
-    /* check consistency of header values */
-    if (xrcvsyn[0] != 0 || xrcvsyn[1] != 0 ) fxsb = xrcvsyn[0];
-    fxse = fxsb + (float)(nxs-1)*dxs;
-    dxf = (xrcvsyn[nxs-1] - xrcvsyn[0])/(float)(nxs-1);
-    if (NINT(dxs*1e3) != NINT(fabs(dxf)*1e3)) {
-        vmess("dx in hdr.d1 (%.3f) and hdr.gx (%.3f) not equal",d2, dxf);
-        if (dxf != 0) dxs = fabs(dxf);
-        vmess("dx in operator => %f", dxs);
-    }
-
-/*================ Reading shot records ================*/
-
-    mode=1;
-    readShotData(file_shot, xrcv, xsrc, zsrc, xnx, Refl, nw, nw_low, nshots, nx, nxs, fxsb, dxs, ntfft, 
-         mode, scale, tsq, Q, f0, reci, &nshots_r, isxcount, reci_xsrc, reci_xrcv, ixmask, verbose);
-
-    tapersh = (float *)malloc(nx*sizeof(float));
-    if (tap == 2 || tap == 3) {
-        for (j = 0; j < ntap; j++)
-            tapersh[j] = (cos(PI*(j-ntap)/ntap)+1)/2.0;
-        for (j = ntap; j < nx-ntap; j++)
-            tapersh[j] = 1.0;
-        for (j = nx-ntap; j < nx; j++)
-            tapersh[j] =(cos(PI*(j-(nx-ntap))/ntap)+1)/2.0;
-    }
-    else {
-        for (j = 0; j < nx; j++) tapersh[j] = 1.0;
-    }
-    if (tap == 2 || tap == 3) {
-        if (verbose) vmess("Taper for shots applied ntap=%d", ntap);
-        for (l = 0; l < nshots; l++) {
-            for (j = 1; j < nw; j++) {
-                for (i = 0; i < nx; i++) {
-                    Refl[l*nx*nw+j*nx+i].r *= tapersh[i];
-                    Refl[l*nx*nw+j*nx+i].i *= tapersh[i];
-                }   
-            }   
-        }
-    }
-    free(tapersh);
-
-    /* check consistency of header values */
-    fxf = xsrc[0];
-    if (nx > 1) dxf = (xrcv[nx-1] - xrcv[0])/(float)(nx-1);
-    else dxf = d2;
-    if (NINT(dx*1e3) != NINT(fabs(dxf)*1e3)) {
-        vmess("dx in hdr.d1 (%.3f) and hdr.gx (%.3f) not equal",dx, dxf);
-        if (dxf != 0) dx = fabs(dxf);
-        else verr("gx hdrs not set");
-        vmess("dx used => %f", dx);
-    }
-    
-    dxsrc = (float)xsrc[1] - xsrc[0];
-    if (dxsrc == 0) {
-        vwarn("sx hdrs are not filled in!!");
-        dxsrc = dx;
-    }
-
-/*================ Check the size of the files ================*/
-
-    if (NINT(dxsrc/dx)*dx != NINT(dxsrc)) {
-        vwarn("source (%.2f) and receiver step (%.2f) don't match",dxsrc,dx);
-        if (reci == 2) vwarn("step used from operator (%.2f) ",dxs);
-    }
-    di = NINT(dxf/dxs);
-    if ((NINT(di*dxs) != NINT(dxf)) && verbose) 
-        vwarn("dx in receiver (%.2f) and operator (%.2f) don't match",dx,dxs);
-    if (nt != nts) 
-        vmess("Time samples in shot (%d) and focusing operator (%d) are not equal",nt, nts);
-    if (verbose) {
-        vmess("Number of focusing operators   = %d", Nfoc);
-        vmess("Number of receivers in focusop = %d", nxs);
-        vmess("number of shots                = %d", nshots);
-        vmess("number of receiver/shot        = %d", nx);
-        vmess("first model position           = %.2f", fxsb);
-        vmess("last model position            = %.2f", fxse);
-        vmess("first source position fxf      = %.2f", fxf);
-        vmess("source distance dxsrc          = %.2f", dxsrc);
-        vmess("last source position           = %.2f", fxf+(nshots-1)*dxsrc);
-        vmess("receiver distance     dxf      = %.2f", dxf);
-        vmess("direction of increasing traces = %d", di);
-        vmess("number of time samples (nt,nts) = %d (%d,%d)", ntfft, nt, nts);
-        vmess("time sampling                  = %e ", dt);
-        if (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;
-    else n2out = nshots;
-    mem = Nfoc*n2out*ntfft*sizeof(float)/1048576.0;
-    if (verbose) {
-        vmess("number of output traces        = %d", n2out);
-        vmess("number of output samples       = %d", ntfft);
-        vmess("Size of output data/file       = %.1f MB", mem);
-    }
-
-
-    /* dry-run of synthesis to get all x-positions calcalated by the integration */
-    synthesisPosistions(nx, nt, nxs, nts, dt, xsyn, Nfoc, xrcv, xsrc, xnx, fxse, fxsb, 
-        dxs, dxsrc, dx, nshots, ixpos, &npos, isxcount, countmin, reci, verbose);
-    if (verbose) {
-        vmess("synthesisPosistions: nshots=%d npos=%d", nshots, npos);
-    }
-
-/*================ set variables for output data ================*/
-
-    n1 = nts; n2 = n2out;
-    f1 = ft; f2 = fxsb+dxs*ixpos[0];
-    d1 = dt;
-    if (reci == 0) d2 = dxsrc; // distance between sources in R
-    else if (reci == 1) d2 = dxs; // distance between traces in G_d 
-    else if (reci == 2) d2 = dx; // distance between receivers in R
-
-    hdrs_out = (segy *) calloc(n2,sizeof(segy));
-    if (hdrs_out == NULL) verr("allocation for hdrs_out");
-    size  = nxs*nts;
-
-    for (i = 0; i < n2; i++) {
-        hdrs_out[i].ns     = n1;
-        hdrs_out[i].trid   = 1;
-        hdrs_out[i].dt     = dt*1000000;
-        hdrs_out[i].f1     = f1;
-        hdrs_out[i].f2     = f2;
-        hdrs_out[i].d1     = d1;
-        hdrs_out[i].d2     = d2;
-        hdrs_out[i].trwf   = n2out;
-        hdrs_out[i].scalco = -1000;
-        hdrs_out[i].gx = NINT(1000*(f2+i*d2));
-        hdrs_out[i].scalel = -1000;
-        hdrs_out[i].tracl = i+1;
-    }
-    t1    = wallclock_time();
-    tread = t1-t0;
-
-/*================ initialization ================*/
-
-    memcpy(Ni, G_d, Nfoc*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*nxs*nts+i*nts+j] = G_d[l*nxs*nts+ix*nts+j];
-            f1plus[l*nxs*nts+i*nts+j] = G_d[l*nxs*nts+ix*nts+j];
-            for (j = 1; j < nts; j++) {
-                f2p[l*nxs*nts+i*nts+j] = G_d[l*nxs*nts+ix*nts+j];
-                f1plus[l*nxs*nts+i*nts+j] = G_d[l*nxs*nts+ix*nts+j];
-            }
-        }
-    }
-
-/*================ start Marchenko iterations ================*/
-
-    for (iter=0; iter<niter; iter++) {
-
-        t2    = wallclock_time();
-    
-/*================ construction of Ni(-t) = - \int R(x,t) Ni(t)  ================*/
-
-        synthesis(Refl, Fop, Ni, iRN, nx, nt, nxs, nts, dt, xsyn, Nfoc, 
-            xrcv, xsrc, xnx, fxse, fxsb, dxs, dxsrc, dx, ntfft, nw, nw_low, nw_high, mode,
-            reci, nshots, 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, d2, f2, n2out, 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*nxs*nts+i*nts+j]    = -iRN[l*nxs*nts+ix*nts+j];
-                pmin[l*nxs*nts+i*nts+j] += iRN[l*nxs*nts+ix*nts+j];
-                energyNi += iRN[l*nxs*nts+ix*nts+j]*iRN[l*nxs*nts+ix*nts+j];
-                for (j = 1; j < nts; j++) {
-                    Ni[l*nxs*nts+i*nts+j]    = -iRN[l*nxs*nts+ix*nts+nts-j];
-                    pmin[l*nxs*nts+i*nts+j] += iRN[l*nxs*nts+ix*nts+j];
-                    energyNi += iRN[l*nxs*nts+ix*nts+j]*iRN[l*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, nts, ixpos, npos, shift);
-
-        /* update f2 */
-        for (l = 0; l < Nfoc; l++) {
-            for (i = 0; i < npos; i++) {
-                j = 0;
-                f2p[l*nxs*nts+i*nts+j] += Ni[l*nxs*nts+i*nts+j];
-                for (j = 1; j < nts; j++) {
-                    f2p[l*nxs*nts+i*nts+j] += Ni[l*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*nxs*nts+i*nts+j] -= Ni[l*nxs*nts+i*nts+j];
-                    for (j = 1; j < nts; j++) {
-                        f1min[l*nxs*nts+i*nts+j] -= Ni[l*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*nxs*nts+i*nts+j] += Ni[l*nxs*nts+i*nts+j];
-                    for (j = 1; j < nts; j++) {
-                        f1plus[l*nxs*nts+i*nts+j] += Ni[l*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*nxs+ixpos[i]] >= nts/2) {
-                memset(&green[l*nxs*nts+i*nts],0, sizeof(float)*nt);
-                continue;
-            }
-            green[l*nxs*nts+i*nts+j] = f2p[l*nxs*nts+i*nts+j] + pmin[l*nxs*nts+i*nts+j];
-            for (j = 1; j < nts; j++) {
-                green[l*nxs*nts+i*nts+j] = f2p[l*nxs*nts+i*nts+nts-j] + pmin[l*nxs*nts+i*nts+j];
-            }
-        }
-    }
-
-    /* compute upgoing Green's function G^+,- */
-    if (file_gmin != NULL) {
-        Gmin    = (float *)calloc(Nfoc*nxs*ntfft,sizeof(float));
-
-        /* use f1+ as operator on R in frequency domain */
-        mode=1;
-        synthesis(Refl, Fop, f1plus, iRN, nx, nt, nxs, nts, dt, xsyn, Nfoc, 
-            xrcv, xsrc, xnx, fxse, fxsb, dxs, dxsrc, dx, ntfft, nw, nw_low, nw_high, mode,
-            reci, nshots, 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*nxs*nts+i*nts+j] = iRN[l*nxs*nts+ix*nts+j] - f1min[l*nxs*nts+i*nts+j];
-                for (j = 1; j < nts; j++) {
-                    Gmin[l*nxs*nts+i*nts+j] = iRN[l*nxs*nts+ix*nts+j] - f1min[l*nxs*nts+i*nts+j];
-                }
-            }
-        }
-        /* Apply mute with window for Gmin */
-        applyMute(Gmin, muteW, smooth, 1, Nfoc, nxs, nts, ixpos, npos, shift);
-    } /* end if Gmin */
-
-    /* compute downgoing Green's function G^+,+ */
-    if (file_gplus != NULL) {
-        Gplus   = (float *)calloc(Nfoc*nxs*ntfft,sizeof(float));
-
-        /* use f1-(*) as operator on R in frequency domain */
-        mode=-1;
-        synthesis(Refl, Fop, f1min, iRN, nx, nt, nxs, nts, dt, xsyn, Nfoc, 
-            xrcv, xsrc, xnx, fxse, fxsb, dxs, dxsrc, dx, ntfft, nw, nw_low, nw_high, mode,
-            reci, nshots, 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*nxs*nts+i*nts+j] = -iRN[l*nxs*nts+ix*nts+j] + f1plus[l*nxs*nts+i*nts+j];
-                for (j = 1; j < nts; j++) {
-                    Gplus[l*nxs*nts+i*nts+j] = -iRN[l*nxs*nts+ix*nts+j] + f1plus[l*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;
-        else f2 = fxf;
-
-        for (i = 0; i < n2; i++) {
-            hdrs_out[i].fldr   = l+1;
-            hdrs_out[i].sx     = NINT(xsyn[l]*1000);
-            hdrs_out[i].offset = (long)NINT((f2+i*d2) - xsyn[l]);
-            hdrs_out[i].tracf  = tracf++;
-            hdrs_out[i].selev  = NINT(zsyn[l]*1000);
-            hdrs_out[i].sdepth = NINT(-zsyn[l]*1000);
-            hdrs_out[i].f1     = f1;
-        }
-
-        ret = writeData(fp_out, (float *)&green[l*size], hdrs_out, n1, n2);
-        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);
-            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);
-            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);
-            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);
-            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; 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);
-            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; 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);
-            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);
-}
-
-
-/*================ Convolution and Integration ================*/
-
-void synthesis(complex *Refl, complex *Fop, float *Top, float *iRN, int nx, int nt, int nxs, int nts, float dt, float *xsyn, int
-Nfoc, float *xrcv, float *xsrc, int *xnx, float fxse, float fxsb, float dxs, float dxsrc, float dx, int ntfft, int
-nw, int nw_low, int nw_high,  int mode, int reci, int nshots, int *ixpos, int npos, double *tfft, int *isxcount, int
-*reci_xsrc,  int *reci_xrcv, float *ixmask, int verbose)
-{
-    int     nfreq, size, inx;
-    float   scl;
-    int     i, j, l, m, iw, ix, k, ixsrc, il, ik;
-    float   *rtrace, idxs;
-    complex *sum, *ctrace;
-    int     npe;
-    static int first=1, *ixrcv;
-    static double t0, t1, t;
-
-    size  = nxs*nts;
-    nfreq = ntfft/2+1;
-    /* scale factor 1/N for backward FFT,
-     * scale dt for correlation/convolution along time, 
-     * scale dx (or dxsrc) for integration over receiver (or shot) coordinates */
-    scl   = 1.0*dt/((float)ntfft);
-
-#ifdef _OPENMP
-    npe   = omp_get_max_threads();
-    /* parallelisation is over number of 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*nxs*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*nxs*nw].r, 0, nxs*nw*2*sizeof(float));
-            for (i = 0; i < npos; i++) {
-                   rc1fft(&Top[l*size+i*nts],ctrace,ntfft,-1);
-                   ix = ixpos[i];
-                   for (iw=0; iw<nw; iw++) {
-                       Fop[l*nxs*nw+iw*nxs+ix].r = ctrace[nw_low+iw].r;
-                       Fop[l*nxs*nw+iw*nxs+ix].i = mode*ctrace[nw_low+iw].i;
-                   }
-            }
-        }
-    }
-    else { /* only for first call to synthesis using all nxs traces in G_d */
-    /* transform G_d to frequency domain, over all nxs traces */
-        first=0;
-        for (l = 0; l < Nfoc; l++) {
-            /* set Fop to zero, so new operator can be defined within all ix points */
-            memset(&Fop[l*nxs*nw].r, 0, nxs*nw*2*sizeof(float));
-            for (i = 0; i < nxs; i++) {
-                   rc1fft(&Top[l*size+i*nts],ctrace,ntfft,-1);
-                   for (iw=0; iw<nw; iw++) {
-                       Fop[l*nxs*nw+iw*nxs+i].r = ctrace[nw_low+iw].r;
-                       Fop[l*nxs*nw+iw*nxs+i].i = mode*ctrace[nw_low+iw].i;
-                   }
-            }
-        }
-        idxs = 1.0/dxs;
-        ixrcv = (int *)malloc(nshots*nx*sizeof(int));
-        for (k=0; k<nshots; k++) {
-            for (i = 0; i < nx; i++) {
-                ixrcv[k*nx+i] = NINT((xrcv[k*nx+i]-fxsb)*idxs);
-            }
-        }
-    }
-    free(ctrace);
-    t1 = wallclock_time();
-    *tfft += t1 - t0;
-
-/* 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)) continue;
-            ixsrc = NINT((xsrc[k] - fxsb)/dxs);
-            inx = xnx[k]; /* number of traces per shot */
-
-/*================ SYNTHESIS ================*/
-
-#pragma omp parallel default(none) \
- shared(iRN, dx, npe, nw, verbose) \
- shared(Refl, Nfoc, reci, xrcv, xsrc, xsyn, fxsb, fxse, nxs, dxs) \
- shared(nx, dxsrc, inx, k, nfreq, nw_low, nw_high) \
- shared(Fop, size, nts, ntfft, scl, ixrcv, ixsrc) \
- 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 = ixrcv[k*nx+i];
-                        sum[j].r += Refl[k*nw*nx+m*nx+i].r*Fop[l*nw*nxs+m*nxs+ix].r -
-                                    Refl[k*nw*nx+m*nx+i].i*Fop[l*nw*nxs+m*nxs+ix].i;
-                        sum[j].i += Refl[k*nw*nx+m*nx+i].i*Fop[l*nw*nxs+m*nxs+ix].r +
-                                    Refl[k*nw*nx+m*nx+i].r*Fop[l*nw*nxs+m*nxs+ix].i;
-                    }
-                }
-
-                /* transfrom result back to time domain */
-                cr1fft(sum, rtrace, ntfft, 1);
-
-                /* place result at source position ixsrc; dx = receiver distance */
-                for (j = 0; j < nts; j++) 
-                    iRN[l*size+ixsrc*nts+j] += rtrace[j]*scl*dx;
-            
-            } /* end of parallel Nfoc loop */
-            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 */
-
-/* if reciprocal traces are enabled start a new loop over reciprocal shot positions */
-    if (reci != 0) {
-        for (k=0; k<nxs; k++) {
-            if (isxcount[k] == 0) continue;
-            ixsrc = k;
-            inx = isxcount[ixsrc]; /* number of traces per reciprocal shot */
-
-#pragma omp parallel default(none) \
- shared(iRN, dx, nw, verbose) \
- shared(Refl, Nfoc, reci, xrcv, xsrc, xsyn, fxsb, fxse, nxs, dxs) \
- shared(nx, dxsrc, inx, k, nfreq, nw_low, nw_high) \
- shared(reci_xrcv, reci_xsrc, ixmask) \
- shared(Fop, size, nts, ntfft, scl, ixrcv, ixsrc) \
- private(l, ix, j, m, i, sum, rtrace, ik, il)
-{ /* 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 (reciprocal) source positions */
-                /* multiply R with Fop and sum over nx */
-                memset(&sum[0].r,0,nfreq*2*sizeof(float));
-                for (j = nw_low, m = 0; j <= nw_high; j++, m++) {
-                    for (i = 0; i < inx; i++) {
-                        il = reci_xrcv[ixsrc*nxs+i];
-                        ik = reci_xsrc[ixsrc*nxs+i];
-            			ix = NINT((xsrc[il] - fxsb)/dxs);
-                        sum[j].r += Refl[il*nw*nx+m*nx+ik].r*Fop[l*nw*nxs+m*nxs+ix].r -
-                                    Refl[il*nw*nx+m*nx+ik].i*Fop[l*nw*nxs+m*nxs+ix].i;
-                        sum[j].i += Refl[il*nw*nx+m*nx+ik].i*Fop[l*nw*nxs+m*nxs+ix].r +
-                                    Refl[il*nw*nx+m*nx+ik].r*Fop[l*nw*nxs+m*nxs+ix].i;
-                    }
-                }
-
-                /* transfrom result back to time domain */
-                cr1fft(sum, rtrace, ntfft, 1);
-
-                /* place result at source position ixsrc; dxsrc = shot distance */
-                for (j = 0; j < nts; j++) 
-                    iRN[l*size+ixsrc*nts+j] = ixmask[ixsrc]*(iRN[l*size+ixsrc*nts+j]+rtrace[j]*scl*dxsrc);
-                
-            } /* end of parallel Nfoc loop */
-        
-            free(sum);
-            free(rtrace);
-        
- } /* end of parallel region */
-
-        } /* end of reciprocal shots (k) loop */
-	} /* end of if reci */
-
-    t = wallclock_time() - t0;
-    if (verbose) {
-        vmess("OMP: parallel region = %f seconds (%d threads)", t, npe);
-    }
-
-    return;
-}
-
-void synthesisPosistions(int nx, int nt, int nxs, int nts, float dt, float *xsyn, int Nfoc, float *xrcv, float *xsrc, int *xnx,
-float fxse, float fxsb, float dxs, float dxsrc, float dx, int nshots, int *ixpos, int *npos, int *isxcount, int countmin, int reci, int verbose)
-{
-    int     i, j, l, ixsrc, ixrcv, dosrc, k, *count;
-    float   x0, x1;
-
-    count   = (int *)calloc(nxs,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);
-                if (verbose>=3) {
-                    vmess("source position:     %.2f in operator %d", xsrc[k], ixsrc);
-                    vmess("receiver positions:  %.2f <--> %.2f", xrcv[k*nx+0], xrcv[k*nx+nx-1]);
-                    vmess("focal point positions:  %.2f <--> %.2f", fxsb, fxse);
-                }
-        
-                if ((NINT(xsrc[k]-fxse) > 0) || (NINT(xrcv[k*nx+nx-1]-fxse) > 0) ||
-                    (NINT(xrcv[k*nx+nx-1]-fxsb) < 0) || (NINT(xsrc[k]-fxsb) < 0) || 
-                    (NINT(xrcv[k*nx+0]-fxsb) < 0) || (NINT(xrcv[k*nx+0]-fxse) > 0) ) {
-                    vwarn("source/receiver positions are outside synthesis aperture");
-                    vmess("xsrc = %.2f xrcv_1 = %.2f xrvc_N = %.2f", xsrc[k], xrcv[k*nx+0], xrcv[k*nx+nx-1]);
-                    vmess("source position:     %.2f in operator %d", xsrc[k], ixsrc);
-                    vmess("receiver positions:  %.2f <--> %.2f", xrcv[k*nx+0], xrcv[k*nx+nx-1]);
-                    vmess("focal point positions:  %.2f <--> %.2f", fxsb, fxse);
-                }
-        
-                if ( (xsrc[k] >= 0.999*fxsb) && (xsrc[k] <= 1.001*fxse) ) {
-				    j = linearsearch(ixpos, *npos, ixsrc);
-				    if (j < *npos) { /* the position (at j) is already included */
-					    count[j] += xnx[k];
-				    }
-				    else { /* add new postion */
-            		    ixpos[*npos]=ixsrc;
-					    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 */
-
-        /* if reci=1 or reci=2 source-receive reciprocity is used and new (reciprocal-)sources are added */
-        if (reci != 0) {
-            for (k=0; k<nxs; k++) { /* check count in total number of shots added by reciprocity */
-                if (isxcount[k] >= countmin) {
-				    j = linearsearch(ixpos, *npos, k);
-				    if (j < *npos) { /* the position (at j) is already included */
-					    count[j] += isxcount[k];
-				    }
-				    else { /* add new postion */
-            		    ixpos[*npos]=k;
-					    count[*npos] += isxcount[k];
-                   	    *npos += 1;
-				    }
-                }
-                else {
-                    isxcount[k] = 0;
-                }
-            }
-   	    } /* 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;
-}
-
-/*
-void update(float *field, float *term, int Nfoc, int nx, int nt, int reverse, int ixpos)
-{
-    int   i, j, l, ix;
-
-    if (reverse) {
-        for (l = 0; l < Nfoc; l++) {
-            for (i = 0; i < npos; i++) {
-                j = 0;
-                Ni[l*nxs*nts+i*nts+j] = -iRN[l*nxs*nts+i*nts+j];
-                for (j = 1; j < nts; j++) {
-                    Ni[l*nxs*nts+i*nts+j] = -iRN[l*nxs*nts+i*nts+nts-j];
-                }
-            }
-        }
-    }
-    else {
-        for (l = 0; l < Nfoc; l++) {
-            for (i = 0; i < npos; i++) {
-                j = 0;
-                Ni[l*nxs*nts+i*nts+j] = -iRN[l*nxs*nts+i*nts+j];
-                for (j = 1; j < nts; j++) {
-                    Ni[l*nxs*nts+i*nts+j] = -iRN[l*nxs*nts+i*nts+nts-j];
-                }
-            }
-        }
-    }
-    return;
-}
-*/
diff --git a/marchenko3D/marchenko3D.c b/marchenko3D/marchenko3D.c
index 42ca94123ee53f6b75fa017fed0b9e8a8796ed73..21e71c1b0ba0694a7647196accefb88c7e8e2842 100644
--- a/marchenko3D/marchenko3D.c
+++ b/marchenko3D/marchenko3D.c
@@ -44,7 +44,7 @@ void name_ext(char *filename, char *extension);
 
 void convol(float *data1, float *data2, float *con, long nrec, long nsam, float dt, long shift);
 
-void applyMute3D(float *data, long *mute, long smooth, long above, long Nfoc, long nxs, long nt, long *xrcvsyn, long npos, long shift);
+void applyMute3D(float *data, long *mute, long smooth, long above, long Nfoc, long nxs, long nys, long nt, long *xrcvsyn, long *yrcvsyn, 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);
@@ -53,7 +53,7 @@ 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,
+void AmpEst3D(float *f1d, float *Gd, float *ampest, long Nfoc, long nxs, long nys, long ntfft, long *ixpos, long *iypos, long npos,
     char *file_wav, float dx, float dy, float dt);
 
 void makeWindow3D(char *file_ray, char *file_amp, char *file_wav, float dt, float *xrcv, float *yrcv, float *xsrc, float *ysrc, float *zsrc, 
@@ -61,12 +61,12 @@ void makeWindow3D(char *file_ray, char *file_amp, char *file_wav, float dt, floa
 
 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);
+    long *ixpos, long *iypos, 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 *ixpos, long *iypos, long npos, double *tfft, long *isxcount, long *reci_xsrc,  long *reci_xrcv, float *ixmask, long verbose);
 
 void imaging3D(float *Image, float *Gmin, float *f1plus, long nx, long ny, long nt, float dx, float dy, float dt, long Nfoc, long verbose);
 
@@ -143,7 +143,7 @@ int main (int argc, char **argv)
     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, nzim, nxim, nyim;
+    long    hw, smooth, above, shift, *ixpos, *iypos, npos, ix, iy, nzim, nxim, nyim;
     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;
@@ -269,6 +269,7 @@ int main (int argc, char **argv)
     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)
+    iypos   = (long *)calloc(nys*nxs,sizeof(long)); // y-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));
@@ -498,7 +499,7 @@ int main (int argc, char **argv)
 
     /* 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);
+        fxse, fyse, fxsb, fysb, dxs, dys, nshots, nxshot, nyshot, ixpos, iypos, &npos, reci, verbose);
     if (verbose) {
         vmess("synthesisPosistions: nxshot=%li nyshot=%li nshots=%li npos=%li", nxshot, nyshot, nshots, npos);
     }
@@ -506,7 +507,7 @@ int main (int argc, char **argv)
 /*================ set variables for output data ================*/
 
     n1 = nts; n2 = n2out; n3 = n3out;
-    f1 = ft; f2 = xrcvsyn[ixpos[0]]; f3 = yrcvsyn[ixpos[0]];
+    f1 = ft; f2 = xrcvsyn[iypos[0]*nxs+ixpos[0]]; f3 = yrcvsyn[iypos[0]*nxs+ixpos[0]];
     d1 = dt;
     if (reci == 0) {      // distance between sources in R
         d2 = dxsrc; 
@@ -552,11 +553,12 @@ int main (int argc, char **argv)
         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];
+            iy = iypos[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+iy*nxs*nts+ix*nts+j];
+            f1plus[l*nys*nxs*nts+i*nts+j] = G_d[l*nys*nxs*nts+iy*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];
+                f2p[l*nys*nxs*nts+i*nts+j] = G_d[l*nys*nxs*nts+iy*nxs*nts+ix*nts+j];
+                f1plus[l*nys*nxs*nts+i*nts+j] = G_d[l*nys*nxs*nts+iy*nxs*nts+ix*nts+j];
             }
         }
     }
@@ -572,7 +574,7 @@ int main (int argc, char **argv)
         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,
+            nxshot, nyshot, ixpos, iypos, npos, &tfft, isxcount, reci_xsrc, reci_xrcv,
             ixmask, verbose);
 
         t3 = wallclock_time();
@@ -588,13 +590,14 @@ int main (int argc, char **argv)
             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];
+                iy = iypos[i]; 
+                Ni[l*nys*nxs*nts+i*nts+j]    = -iRN[l*nys*nxs*nts+iy*nxs*nts+ix*nts+j];
+                pmin[l*nys*nxs*nts+i*nts+j] += iRN[l*nys*nxs*nts+iy*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];
+                    Ni[l*nys*nxs*nts+i*nts+j]    = -iRN[l*nys*nxs*nts+iy*nxs*nts+ix*nts+nts-j];
+                    pmin[l*nys*nxs*nts+i*nts+j] += iRN[l*nys*nxs*nts+iy*nxs*nts+ix*nts+j];
+                    energyNi += iRN[l*nys*nxs*nts+iy*nxs*nts+ix*nts+j]*iRN[l*nys*nxs*nts+iy*nxs*nts+ix*nts+j];
                 }
             }
             if (iter==0) energyN0 = energyNi;
@@ -603,7 +606,7 @@ int main (int argc, char **argv)
         }
 
         /* apply mute window based on times of direct arrival (in muteW) */
-        applyMute3D(Ni, muteW, smooth, above, Nfoc, nxs*nys, nts, ixpos, npos, shift);
+        applyMute3D(Ni, muteW, smooth, above, Nfoc, nxs, nys, nts, ixpos, iypos, npos, shift);
 
         /* update f2 */
         for (l = 0; l < Nfoc; l++) {
@@ -654,7 +657,7 @@ int main (int argc, char **argv)
         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) {
+            if (muteW[l*nys*nxs+iypos[i]*nxs+ixpos[i]] >= nts/2) {
                 memset(&green[l*nys*nxs*nts+i*nts],0, sizeof(float)*nt);
                 continue;
             }
@@ -664,7 +667,7 @@ int main (int argc, char **argv)
             }
         }
     }
-    applyMute3D(green, muteW, smooth, 4, Nfoc, nxs*nys, nts, ixpos, npos, shift);
+    applyMute3D(green, muteW, smooth, 4, Nfoc, nxs, nys, nts, ixpos, iypos, npos, shift);
 
     /* compute upgoing Green's function G^+,- */
     if (file_gmin != NULL || file_imag!= NULL) {
@@ -672,25 +675,35 @@ int main (int argc, char **argv)
 
         /* 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);
+        if (niter==0) {
+            synthesis3D(Refl, Fop, G_d, 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, iypos, npos, &tfft, isxcount, reci_xsrc, reci_xrcv,
+                ixmask, verbose);
+        }
+        else {
+            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, iypos, 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];
+                iy = iypos[i];
+                Gmin[l*nys*nxs*nts+i*nts+j] = iRN[l*nys*nxs*nts+iy*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];
+                    Gmin[l*nys*nxs*nts+i*nts+j] = iRN[l*nys*nxs*nts+iy*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);
+        applyMute3D(Gmin, muteW, smooth, 4, Nfoc, nxs, nys, nts, ixpos, iypos, npos, shift);
     } /* end if Gmin */
 
     /* compute downgoing Green's function G^+,+ */
@@ -702,7 +715,7 @@ int main (int argc, char **argv)
         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,
+            nxshot, nyshot, ixpos, iypos, npos, &tfft, isxcount, reci_xsrc, reci_xrcv,
             ixmask, verbose);
 
         /* compute downgoing Green's G^+,+ */
@@ -710,14 +723,15 @@ int main (int argc, char **argv)
             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];
+                iy = iypos[i];
+                Gplus[l*nys*nxs*nts+i*nts+j] = -iRN[l*nys*nxs*nts+iy*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];
+                    Gplus[l*nys*nxs*nts+i*nts+j] = -iRN[l*nys*nxs*nts+iy*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);
+        applyMute3D(Gplus, muteW, smooth, 4, Nfoc, nxs, nys, nts, ixpos, iypos, npos, shift);
     } /* end if Gplus */
 
     /* Estimate the amplitude of the Marchenko Redatuming */
@@ -728,10 +742,10 @@ int main (int argc, char **argv)
         ampscl	= (float *)calloc(Nfoc,sizeof(float));
 		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);
+		applyMute3D(Gd, muteW, smooth, 2, Nfoc, nxs, nys, nts, ixpos, iypos, npos, shift);
 
         // Determine amplitude and apply scaling
-		AmpEst3D(G_d,Gd,ampscl,Nfoc,nxs,nys,ntfft,ixpos,npos,file_wav,dxs,dys,dt);
+		AmpEst3D(G_d, Gd, ampscl, Nfoc, nxs, nys, ntfft, ixpos, iypos, 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];
diff --git a/marchenko3D/marchenko3D_backup.c b/marchenko3D/marchenko3D_backup.c
index ace2b3179f7110a2d0884615c06fefa5ac7096bc..42ca94123ee53f6b75fa017fed0b9e8a8796ed73 100644
--- a/marchenko3D/marchenko3D_backup.c
+++ b/marchenko3D/marchenko3D_backup.c
@@ -38,12 +38,12 @@ long readShotData3D(char *filename, float *xrcv, float *yrcv, float *xsrc, float
     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 convol(float *data1, float *data2, float *con, long nrec, long nsam, float dt, long shift);
+
 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,
@@ -56,6 +56,9 @@ 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 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);
+
 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);
@@ -65,6 +68,10 @@ void synthesis3D(complex *Refl, complex *Fop, float *Top, float *iRN, long nx, l
     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);
 
+void imaging3D(float *Image, float *Gmin, float *f1plus, long nx, long ny, long nt, float dx, float dy, float dt, long Nfoc, long verbose);
+
+void homogeneousg3D(float *HomG, float *green, float *f2, long nx, long ny, long nt, float dx, float dy, float dt, long Nfoc, long verbose);
+
 long linearsearch(long *array, size_t N, long value);
 
 /*********************** self documentation **********************/
@@ -77,6 +84,7 @@ char *sdoc[] = {
 " Required parameters: ",
 " ",
 "   file_tinv= ............... direct arrival from focal point: G_d",
+"   file_ray= ................ direct arrival from raytimes",
 "   file_shot= ............... Reflection response: R",
 " ",
 " Optional parameters: ",
@@ -89,6 +97,7 @@ char *sdoc[] = {
 " MARCHENKO ITERATIONS ",
 "   niter=10 ................. number of iterations",
 " MUTE-WINDOW ",
+"   file_amp= ................ amplitudes for the raytime estimation",
 "   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",
@@ -98,6 +107,11 @@ char *sdoc[] = {
 "   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",
+" HOMOGENEOUS GREEN'S FUNCTION RETRIEVAL OPTIONS ",
+"   file_inp= ................ Input source function for the retrieval",
+"   scheme=0 ................. Scheme for homogeneous Green's function retrieval",
+"   .......................... Scheme for homogeneous Green's function retrieval",
+"   kxwfilt=0 ................ Apply a dip filter before integration",
 " OUTPUT DEFINITION ",
 "   file_green= .............. output file with full Green function(s)",
 "   file_gplus= .............. output file with G+ ",
@@ -107,6 +121,9 @@ char *sdoc[] = {
 "   file_f2= ................. output file with f2 (=p+) ",
 "   file_pplus= .............. output file with p+ ",
 "   file_pmin= ............... output file with p- ",
+"   file_imag= ............... output file with image ",
+"   file_homg= ............... output file with homogeneous Green's function ",
+"   file_ampscl= ............. output file with estimated amplitudes ",
 "   file_iter= ............... output file with -Ni(-t) for each iteration",
 "   verbose=0 ................ silent option; >0 displays info",
 " ",
@@ -119,26 +136,27 @@ NULL};
 
 int main (int argc, char **argv)
 {
-    FILE    *fp_out, *fp_f1plus, *fp_f1min;
-    FILE    *fp_gmin, *fp_gplus, *fp_f2, *fp_pmin;
+    FILE    *fp_out, *fp_f1plus, *fp_f1min, *fp_imag;
+    FILE    *fp_gmin, *fp_gplus, *fp_f2, *fp_pmin, *fp_amp;
     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    hw, smooth, above, shift, *ixpos, npos, ix, nzim, nxim, nyim;
     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;
+    float   xmin, xmax, ymin, ymax, scale, tsq, Q, f0, *tmpdata;
+    float   *ixmask, *iymask, *ampscl, *Gd, *Image, dzim, dyim, dxim;
     complex *Refl, *Fop;
-    char    *file_tinv, *file_shot, *file_green, *file_iter, *file_wav;
+    char    *file_tinv, *file_shot, *file_green, *file_iter, *file_imag, *file_ampscl;
     char    *file_f1plus, *file_f1min, *file_gmin, *file_gplus, *file_f2, *file_pmin;
-    segy    *hdrs_out;
+    char    *file_ray, *file_amp, *file_wav;
+    segy    *hdrs_out, *hdrs_Nfoc;
 
     initargs(argc, argv);
     requestdoc(1);
@@ -148,6 +166,8 @@ int main (int argc, char **argv)
 
     if (!getparstring("file_shot", &file_shot)) file_shot = NULL;
     if (!getparstring("file_tinv", &file_tinv)) file_tinv = NULL;
+    if (!getparstring("file_ray", &file_ray)) file_ray = NULL;
+    if (!getparstring("file_amp", &file_amp)) file_amp = 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;
@@ -157,6 +177,8 @@ int main (int argc, char **argv)
     if (!getparstring("file_pmin", &file_pmin)) file_pmin = NULL;
     if (!getparstring("file_iter", &file_iter)) file_iter = NULL;
     if (!getparstring("file_wav", &file_wav)) file_wav = NULL;
+    if (!getparstring("file_imag", &file_imag)) file_imag = NULL;
+    if (!getparstring("file_ampscl", &file_ampscl)) file_ampscl = 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");
@@ -187,15 +209,28 @@ int main (int argc, char **argv)
 /*================ 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;
+    if (file_ray!=NULL) {
+        ret = getFileInfo3D(file_ray, &n2, &n1, &n3, &ngath, &d2, &d1, &d3, &f2, &f1, &f3, &scl, &ntraces);
+		Nfoc = ngath;
+        nxs  = n2; 
+        nys  = n3;
+        nts  = n1;
+        dxs  = d2*1e3;
+        dys  = d3; 
+        fxsb = f2;
+        fysb = f3;
+    }
+    else {
+        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);
@@ -253,12 +288,25 @@ int main (int argc, char **argv)
 
 /*================ 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);
+    if (file_ray!=NULL) {
+        makeWindow3D(file_ray, file_amp, file_wav, dt, xrcvsyn, yrcvsyn, xsyn, ysyn, zsyn, 
+            xnxsyn, Nfoc, nxs, nys, ntfft, muteW, G_d, verbose);
+    }
+    else {
+        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;
+
+    /*Determine the shape of the focal positions*/
+    nzim = unique_elements(zsyn,Nfoc);
+    if (nzim>1) dzim = zsyn[1]-zsyn[0];
+    else dzim = 1.0;
+    nyim = unique_elements(ysyn,Nfoc);
+    nxim = unique_elements(xsyn,Nfoc);
+
                              
     /* define tapers to taper edges of acquisition */
     if (tap == 1 || tap == 3) {
@@ -290,7 +338,7 @@ int main (int argc, char **argv)
     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);
+        dxf = (fxse - fxsb)/(float)(nxs-1);
     }
     else {
         fxse = fxsb;
@@ -301,7 +349,7 @@ int main (int argc, char **argv)
     }
     if (nys>1) {
         fyse = fysb + (float)(nys-1)*dys;
-        dyf = (yrcvsyn[nys*nxs-1] - yrcvsyn[0])/(float)(nys-1);
+        dyf = (fyse - fysb)/(float)(nys-1);
     }
     else {
         fyse = fysb;
@@ -619,7 +667,7 @@ int main (int argc, char **argv)
     applyMute3D(green, muteW, smooth, 4, Nfoc, nxs*nys, nts, ixpos, npos, shift);
 
     /* compute upgoing Green's function G^+,- */
-    if (file_gmin != NULL) {
+    if (file_gmin != NULL || file_imag!= NULL) {
         Gmin    = (float *)calloc(Nfoc*nys*nxs*ntfft,sizeof(float));
 
         /* use f1+ as operator on R in frequency domain */
@@ -675,27 +723,107 @@ int main (int argc, char **argv)
     /* Estimate the amplitude of the Marchenko Redatuming */
 	if (ampest>0) {
         if (verbose>0) vmess("Estimating amplitude scaling");
+
+        // Allocate memory and copy data
+        ampscl	= (float *)calloc(Nfoc,sizeof(float));
 		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));
+
+        // Determine amplitude and apply scaling
 		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_gmin != NULL || file_imag != 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_f1plus != NULL || file_imag != 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]);
 		}
+
+        if (file_ampscl!=NULL) { //Write the estimation of the amplitude to file
+            hdrs_Nfoc = (segy *)calloc(nxim*nyim,sizeof(segy));
+            for (l=0; l<nyim; l++){
+                for (j=0; j<nxim; j++){
+                    hdrs_Nfoc[l*nxim+j].ns      = nzim;
+                    hdrs_Nfoc[l*nxim+j].fldr    = 1;
+                    hdrs_Nfoc[l*nxim+j].tracl   = 1;
+                    hdrs_Nfoc[l*nxim+j].tracf   = l*nxim+j+1;
+                    hdrs_Nfoc[l*nxim+j].trid    = 1;
+                    hdrs_Nfoc[l*nxim+j].scalco  = -1000;
+                    hdrs_Nfoc[l*nxim+j].scalel  = -1000;
+                    hdrs_Nfoc[l*nxim+j].sx      = xsyn[j]*(1e3);
+                    hdrs_Nfoc[l*nxim+j].sy      = ysyn[l]*(1e3);
+                    hdrs_Nfoc[l*nxim+j].gx      = xsyn[j]*(1e3);
+                    hdrs_Nfoc[l*nxim+j].gy      = ysyn[l]*(1e3);
+                    hdrs_Nfoc[l*nxim+j].sdepth  = zsyn[l]*(1e3);
+                    hdrs_Nfoc[l*nxim+j].f1      = zsyn[0];
+                    hdrs_Nfoc[l*nxim+j].f2      = xsyn[0];
+                    hdrs_Nfoc[l*nxim+j].d1      = zsyn[1]-zsyn[0];
+                    hdrs_Nfoc[l*nxim+j].d2      = xsyn[1]-xsyn[0];
+                    hdrs_Nfoc[l*nxim+j].dt      = (int)(hdrs_Nfoc[l*nxim+j].d1*(1E6));
+                    hdrs_Nfoc[l*nxim+j].trwf    = nxim*nyim;
+                    hdrs_Nfoc[l*nxim+j].ntr     = nxim*nyim;
+                }
+            }
+            // Write the data
+            fp_amp = fopen(file_ampscl, "w+");
+            if (fp_amp==NULL) verr("error on creating output file %s", file_ampscl);
+            ret = writeData3D(fp_amp, (float *)&ampscl[0], hdrs_Nfoc, nzim, nxim*nyim);
+            if (ret < 0 ) verr("error on writing output file.");
+            fclose(fp_amp);
+            free(hdrs_Nfoc);
+            free(ampscl);
+        }
         free(Gd);
         if (file_gplus == NULL) free(Gplus);
 	}
 
+    /* Apply imaging*/
+    if (file_imag!=NULL) {
+        // Determine Image
+        Image = (float *)calloc(Nfoc,sizeof(float));
+        imaging3D(Image, Gmin, f1plus, nxs, nys, ntfft, dxs, dys, dt, Nfoc, verbose);
+        if (file_gmin==NULL) free(Gmin);
+        // Set headers
+        hdrs_Nfoc = (segy *)calloc(nxim*nyim,sizeof(segy));
+        for (l=0; l<nyim; l++){
+            for (j=0; j<nxim; j++){
+                hdrs_Nfoc[l*nxim+j].ns      = nzim;
+                hdrs_Nfoc[l*nxim+j].fldr    = 1;
+                hdrs_Nfoc[l*nxim+j].tracl   = 1;
+                hdrs_Nfoc[l*nxim+j].tracf   = l*nxim+j+1;
+                hdrs_Nfoc[l*nxim+j].trid    = 1;
+                hdrs_Nfoc[l*nxim+j].scalco  = -1000;
+                hdrs_Nfoc[l*nxim+j].scalel  = -1000;
+                hdrs_Nfoc[l*nxim+j].sx      = xsyn[j]*(1e3);
+                hdrs_Nfoc[l*nxim+j].sy      = ysyn[l]*(1e3);
+                hdrs_Nfoc[l*nxim+j].gx      = xsyn[j]*(1e3);
+                hdrs_Nfoc[l*nxim+j].gy      = ysyn[l]*(1e3);
+                hdrs_Nfoc[l*nxim+j].sdepth  = zsyn[l]*(1e3);
+                hdrs_Nfoc[l*nxim+j].f1      = zsyn[0];
+                hdrs_Nfoc[l*nxim+j].f2      = xsyn[0];
+                hdrs_Nfoc[l*nxim+j].d1      = zsyn[1]-zsyn[0];
+                hdrs_Nfoc[l*nxim+j].d2      = xsyn[1]-xsyn[0];
+                hdrs_Nfoc[l*nxim+j].dt      = (int)(hdrs_Nfoc[l*nxim+j].d1*(1E6));
+                hdrs_Nfoc[l*nxim+j].trwf    = nxim*nyim;
+                hdrs_Nfoc[l*nxim+j].ntr     = nxim*nyim;
+            }
+        }
+        // Write out image
+        fp_imag = fopen(file_imag, "w+");
+        if (fp_imag==NULL) verr("error on creating output file %s", file_imag);
+        ret = writeData3D(fp_imag, (float *)&Image[0], hdrs_Nfoc, nzim, nxim*nyim);
+        if (ret < 0 ) verr("error on writing output file.");
+        fclose(fp_imag);
+        free(hdrs_Nfoc);
+        free(Image);
+    }
+
     t2 = wallclock_time();
     if (verbose) {
         vmess("Total CPU-time marchenko = %.3f", t2-t0);
@@ -848,4 +976,4 @@ long unique_elements(float *arr, long len)
         if (is_unique) ++unique;
      }
      return unique;
-}
\ No newline at end of file
+}
diff --git a/marchenko3D/readData.c b/marchenko3D/readData.c
deleted file mode 120000
index af43798573495d45a669aacf2dfe5d1094834bf8..0000000000000000000000000000000000000000
--- a/marchenko3D/readData.c
+++ /dev/null
@@ -1 +0,0 @@
-../utils/readData.c
\ No newline at end of file
diff --git a/marchenko3D/readShotData.c b/marchenko3D/readShotData.c
deleted file mode 100644
index a619799113de01c77af1a667cb060e3de055731b..0000000000000000000000000000000000000000
--- a/marchenko3D/readShotData.c
+++ /dev/null
@@ -1,207 +0,0 @@
-#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;
-
-#define NINT(x) ((int)((x)>0.0?(x)+0.5:(x)-0.5))
-#define MAX(x,y) ((x) > (y) ? (x) : (y))
-
-int optncr(int n);
-void cc1fft(complex *data, int n, int sign);
-void rc1fft(float *rdata, complex *cdata, int n, int sign);
-
-int readShotData(char *filename, float *xrcv, float *xsrc, float *zsrc, int *xnx, complex *cdata, int nw, int nw_low, int nshots,
-int nx, int nxs, float fxsb, float dxs, int ntfft, int mode, float scale, float tsq, float Q, float f0, int reci, int *nshots_r, int *isxcount, int *reci_xsrc,  int *reci_xrcv, float *ixmask, int verbose)
-{
-    FILE *fp;
-    segy hdr;
-    size_t nread;
-    int fldr_shot, sx_shot, itrace, one_shot, igath, iw;
-    int end_of_file, nt;
-    int *isx, *igx, k, l, m, j, nreci;
-	int samercv, samesrc, nxrk, nxrm, maxtraces, ixsrc;
-    float scl, scel, *trace, dt;
-    complex *ctrace;
-
-    /* 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;
-    }
-
-    fseek(fp, 0, SEEK_SET);
-    nread = fread( &hdr, 1, TRCBYTES, fp );
-    assert(nread == TRCBYTES);
-    if (hdr.scalco < 0) scl = 1.0/fabs(hdr.scalco);
-    else if (hdr.scalco == 0) scl = 1.0;
-    else scl = hdr.scalco;
-    if (hdr.scalel < 0) scel = 1.0/fabs(hdr.scalel);
-    else if (hdr.scalel == 0) scel = 1.0;
-    else scel = hdr.scalel;
-
-    fseek(fp, 0, SEEK_SET);
-
-    nt = hdr.ns;
-    dt = hdr.dt/(1E6);
-
-    trace  = (float *)calloc(ntfft,sizeof(float));
-    ctrace = (complex *)malloc(ntfft*sizeof(complex));
-    isx = (int *)malloc((nx*nshots)*sizeof(int));
-    igx = (int *)malloc((nx*nshots)*sizeof(int));
-
-    end_of_file = 0;
-    one_shot    = 1;
-    igath       = 0;
-
-    /* Read shots in file */
-
-    while (!end_of_file) {
-
-        /* start reading data (shot records) */
-        itrace = 0;
-        nread = fread( &hdr, 1, TRCBYTES, fp );
-        if (nread != TRCBYTES) { /* no more data in file */
-            break;
-        }
-
-/* ToDo Don't store the traces that are not in the aperture */
-/*
-        if ( (NINT(sx_shot*scl-fxse) > 0) || (NINT(-fxsb) > 0) ) {
-           vwarn("source positions are outside synthesis aperture");
-           vmess("xsrc = %.2f", xsrc[k], xrcv[k*nx+0], xrcv[k*nx+nx-1]);
-        }
-*/
-
-        sx_shot  = hdr.sx;
-        fldr_shot  = hdr.fldr;
-        isx[igath] = sx_shot;
-        xsrc[igath] = sx_shot*scl;
-        zsrc[igath] = hdr.selev*scel;
-        xnx[igath]=0;
-        while (one_shot) {
-        	igx[igath*nx+itrace] = hdr.gx;
-            xrcv[igath*nx+itrace] = hdr.gx*scl;
-
-            nread = fread( trace, sizeof(float), nt, fp );
-            assert (nread == hdr.ns);
-
-            /* True Amplitude Recovery */
-            if (tsq != 0.0) {
-                for (iw=0; iw<nt; iw++) {
-                    trace[iw] *= powf(dt*iw,tsq);
-                }
-            }
-
-            /* Q-correction */
-            if (Q != 0.0 && f0 != 0.0) {
-                for (iw=0; iw<nt; iw++) {
-                    trace[iw] *= expf(((dt*iw)*M_PI*f0)/Q);
-                }
-            }
-
-            /* transform to frequency domain */
-            if (ntfft > hdr.ns) 
-                memset( &trace[nt-1], 0, sizeof(float)*(ntfft-nt) );
-
-            rc1fft(trace,ctrace,ntfft,-1);
-            for (iw=0; iw<nw; iw++) {
-                cdata[igath*nx*nw+iw*nx+itrace].r = scale*ctrace[nw_low+iw].r;
-                cdata[igath*nx*nw+iw*nx+itrace].i = scale*mode*ctrace[nw_low+iw].i;
-            }
-            itrace++;
-            xnx[igath]+=1;
-
-            /* read next hdr of next trace */
-            nread = fread( &hdr, 1, TRCBYTES, fp );
-            if (nread != TRCBYTES) { 
-                one_shot = 0;
-                end_of_file = 1;
-                break;
-            }
-            if ((sx_shot != hdr.sx) || (fldr_shot != hdr.fldr) ) break;
-        }
-        if (verbose>2) {
-            vmess("finished reading shot %d (%d) with %d traces",sx_shot,igath,itrace);
-        }
-
-        if (itrace != 0) { /* end of shot record */
-            fseek( fp, -TRCBYTES, SEEK_CUR );
-            igath++;
-        }
-        else {
-            end_of_file = 1;
-        }
-    }
-
-    free(ctrace);
-    free(trace);
-
-/* if reci=1 or reci=2 source-receive reciprocity is used and traces are added */
-   
-	if (reci != 0) {
-    	for (k=0; k<nxs; k++) ixmask[k] = 1.0;
-        for (k=0; k<nshots; k++) {
-            ixsrc = NINT((xsrc[k] - fxsb)/dxs);
-			nxrk = xnx[k];
-        	for (l=0; l<nxrk; l++) {
-				samercv = 0;
-				samesrc = 0;
-                for (m=0; m<nshots; m++) {
-			        if (igx[k*nx+l] == isx[m] && reci == 1) { // receiver position already present as source position m
-						nxrm = xnx[m];
-        			    for (j=0; j<nxrm; j++) { // check if receiver l with source k is also present in shot m
-			                if (isx[k] == igx[m*nx+j]) { // shot k with receiver l already known as receiver j in shot m: same data
-								samercv = 1;
-								break;
-							}
-						}
-						if (samercv == 0) { // source k of receiver l -> accept trace as new receiver position for source l
-            				ixsrc = NINT((xrcv[k*nx+l] - fxsb)/dxs);
-            				if ((ixsrc >= 0) && (ixsrc < nxs)) {
-								reci_xrcv[ixsrc*nxs+isxcount[ixsrc]] = k;
-								reci_xsrc[ixsrc*nxs+isxcount[ixsrc]] = l;
-								isxcount[ixsrc] += 1;
-								if (reci==1) ixmask[ixsrc] = 0.5; // traces are added to already existing traces and must be scaled
-							}
-						}
-						samesrc = 1;
-						break;
-                    }
-				}
-                if (samesrc == 0) { // receiver l with source k -> accept trace as new source position l with receiver k
-					//fprintf(stderr,"not a samesrc for receiver l=%d for source k=%d\n", l,k);
-            		ixsrc = NINT((xrcv[k*nx+l] - fxsb)/dxs);
-            		if ((ixsrc >= 0) && (ixsrc < nxs)) { // is this correct or should k and l be reversed: rcv=l src=k
-						reci_xrcv[ixsrc*nxs+isxcount[ixsrc]] = k;
-						reci_xsrc[ixsrc*nxs+isxcount[ixsrc]] = l;
-						isxcount[ixsrc] += 1;
-					}
-                }
-			}
-	    }
-        nreci = 0;
-        for (k=0; k<nxs; k++) { // count total number of shots added by reciprocity
-			if (isxcount[k] != 0) {
-				maxtraces = MAX(maxtraces,isxcount[k]);
-				nreci++;
-				if (verbose>1) vmess("reciprocal receiver at %f (%d) has %d sources contributing", k, k*dxs+fxsb, isxcount[k]);
-        	}
-    	}
-		*nshots_r = nreci;
-    }
-
-    return 0;
-}
-
-
diff --git a/marchenko3D/readTinvData.c b/marchenko3D/readTinvData.c
deleted file mode 100644
index 028d4c21b4ddef73fe08edc7fcec0f1400b6d518..0000000000000000000000000000000000000000
--- a/marchenko3D/readTinvData.c
+++ /dev/null
@@ -1,240 +0,0 @@
-#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;
-
-#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 findShotInMute(float *xrcvMute, float xrcvShot, int nxs, int *imute);
-
-int readTinvData(char *filename, float *xrcv, float *xsrc, float *zsrc, int *xnx, int Nfoc, int nx, int ntfft, int mode, int *maxval, float *tinv, int hw, int verbose)
-{
-	FILE *fp;
-	segy hdr;
-	size_t nread;
-	int fldr_shot, sx_shot, itrace, one_shot, ig, isyn, i, j;
-	int end_of_file, nt, gx0, gx1;
-	int nx1, jmax, imax, tstart, tend;
-	float xmax, tmax, lmax;
-	float scl, scel, *trace, dxrcv;
-	complex *ctrace;
-
-	/* 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;
-	}
-
-	fseek(fp, 0, SEEK_SET);
-	nread = fread( &hdr, 1, TRCBYTES, fp );
-	assert(nread == TRCBYTES);
-	if (hdr.scalco < 0) scl = 1.0/fabs(hdr.scalco);
-	else if (hdr.scalco == 0) scl = 1.0;
-	else scl = hdr.scalco;
-	if (hdr.scalel < 0) scel = 1.0/fabs(hdr.scalel);
-	else if (hdr.scalel == 0) scel = 1.0;
-	else scel = hdr.scalel;
-	fseek(fp, 0, SEEK_SET);
-
-	nt     = hdr.ns;
-	trace  = (float *)calloc(ntfft,sizeof(float));
-	ctrace = (complex *)malloc(ntfft*sizeof(complex));
-
-	end_of_file = 0;
-	one_shot    = 1;
-	isyn        = 0;
-
-	/* Read shots in file */
-
-	while (!end_of_file) {
-
-		/* start reading data (shot records) */
-		itrace     = 0;
-		nread = fread( &hdr, 1, TRCBYTES, fp );
-		if (nread != TRCBYTES) { /* no more data in file */
-			break;
-		}
-
-		sx_shot    = hdr.sx;
-		fldr_shot  = hdr.fldr;
-        gx0        = hdr.gx;
-		xsrc[isyn] = sx_shot*scl;
-		zsrc[isyn] = hdr.selev*scel;
-		xnx[isyn]  = 0;
-        ig = isyn*nx*ntfft;
-		while (one_shot) {
-			xrcv[isyn*nx+itrace] = hdr.gx*scl;
-			nread = fread( trace, sizeof(float), nt, fp );
-			assert (nread == hdr.ns);
-
-			/* copy trace to data array */
-            memcpy( &tinv[ig+itrace*ntfft], trace, nt*sizeof(float));
-
-            gx1 = hdr.gx;
-			itrace++;
-
-			/* read next hdr of next trace */
-			nread = fread( &hdr, 1, TRCBYTES, fp );
-			if (nread != TRCBYTES) { 
-				one_shot = 0;
-				end_of_file = 1;
-				break;
-			}
-			if ((sx_shot != hdr.sx) || (fldr_shot != hdr.fldr) ) break;
-		}
-		if (verbose>2) {
-			fprintf(stderr,"finished reading shot %d (%d) with %d traces\n",sx_shot,isyn,itrace);
-			//disp_fileinfo(filename, nt, xnx[isyn], hdr.f1, xrcv[isyn*nxm], d1, d2, &hdr);
-		}
-
-		/* look for maximum in shot record to define mute window */
-        /* find consistent (one event) maximum related to maximum value */
-		nx1 = itrace;
-		xnx[isyn]=nx1;
-        /* find global maximum 
-		xmax=0.0;
-		for (i = 0; i < nx1; i++) {
-            tmax=0.0;
-            jmax = 0;
-            for (j = 0; j < nt; j++) {
-                lmax = fabs(tinv[ig+i*ntfft+j]);
-                if (lmax > tmax) {
-                    jmax = j;
-                    tmax = lmax;
-                    if (lmax > xmax) {
-                        imax = i;
-                        xmax=lmax;
-                    }
-                }
-            }
-            maxval[isyn*nx+i] = jmax;
-		}
-		*/
-
-        /* alternative find maximum at source position */
-        dxrcv = (gx1 - gx0)*scl/(float)(nx1-1);
-        imax = NINT(((sx_shot-gx0)*scl)/dxrcv);
-        tmax=0.0;
-        jmax = 0;
-        for (j = 0; j < nt; j++) {
-            lmax = fabs(tinv[ig+imax*ntfft+j]);
-            if (lmax > tmax) {
-                jmax = j;
-                tmax = lmax;
-                   if (lmax > xmax) {
-                       xmax=lmax;
-                   }
-            }
-        }
-        maxval[isyn*nx+imax] = jmax;
-        if (verbose >= 3) vmess("Mute max at src-trace %d is sample %d", imax, maxval[imax]);
-
-        /* search forward in trace direction from maximum in file */
-        for (i = imax+1; i < nx1; i++) {
-            tstart = MAX(0, (maxval[isyn*nx+i-1]-hw));
-            tend   = MIN(nt-1, (maxval[isyn*nx+i-1]+hw));
-            jmax=tstart;
-            tmax=0.0;
-            for(j = tstart; j <= tend; j++) {
-                lmax = fabs(tinv[ig+i*ntfft+j]);
-                if (lmax > tmax) {
-                    jmax = j;
-                    tmax = lmax;
-                }
-            }
-            maxval[isyn*nx+i] = jmax;
-        }
-        /* search backward in trace direction from maximum in file */
-        for (i = imax-1; i >=0; i--) {
-            tstart = MAX(0, (maxval[isyn*nx+i+1]-hw));
-            tend   = MIN(nt-1, (maxval[isyn*nx+i+1]+hw));
-            jmax=tstart;
-            tmax=0.0;
-            for(j = tstart; j <= tend; j++) {
-                lmax = fabs(tinv[ig+i*ntfft+j]);
-                if (lmax > tmax) {
-                    jmax = j;
-                    tmax = lmax;
-                }
-            }
-            maxval[isyn*nx+i] = jmax;
-        }
-
-		if (itrace != 0) { /* end of shot record, but not end-of-file */
-			fseek( fp, -TRCBYTES, SEEK_CUR );
-			isyn++;
-		}
-		else {
-			end_of_file = 1;
-		}
-
-		/* copy trace to data array for mode=-1 */
-        /* time reverse trace */
-		if (mode==-1) {
-			for (i = 0; i < nx1; i++) {
-            	memcpy( trace, &tinv[ig+i*ntfft], ntfft*sizeof(float));
-				j=0;
-				tinv[ig+i*ntfft+j] = trace[j];
-				for (j=1; j<ntfft; j++) tinv[ig+i*ntfft+ntfft-j] = trace[j];
-			}
-		}
-	}
-
-	free(ctrace);
-	free(trace);
-
-	return 0;
-}
-
-
-/* simple sort algorithm */
-void findShotInMute(float *xrcvMute, float xrcvShot, int nxs, int *imute)
-{
-	int i, sign;
-	float diff1, diff2;
-
-	*imute=0;
-
-	if (xrcvMute[0] < xrcvMute[1]) sign = 1;
-	else sign = -1;
-
-	if (sign == 1) {
-		i = 0;
-		while (xrcvMute[i] < xrcvShot && i < nxs) {
-			i++;
-		}
-		/* i is now position larger than xrcvShot */
-	}
-	else {
-		i = 0;
-		while (xrcvMute[i] > xrcvShot && i < nxs) {
-			i++;
-		}
-		/* i is now position smaller than xrcvShot */
-	}
-
-	diff1 = fabsf(xrcvMute[i]-xrcvShot);
-	diff2 = fabsf(xrcvMute[i-1]-xrcvShot);
-	if (diff1 < diff2) *imute = i;
-	else *imute = i-1;
-
-	return;
-}
-
diff --git a/marchenko3D/synthesis3D.c b/marchenko3D/synthesis3D.c
index d93200daee1113418bafc9dc823d8c253eca1879..416542d19aaf4a4420fd9aa0b3eaafe7166d4bd0 100644
--- a/marchenko3D/synthesis3D.c
+++ b/marchenko3D/synthesis3D.c
@@ -31,9 +31,9 @@ long linearsearch(long *array, size_t N, long value);
 
 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)
+long nshots, long nxsrc, long nysrc, long *ixpos, long *iypos, long *npos, long reci, long verbose)
 {
-    long     j, l, ixsrc, iysrc, isrc, k, *count, nxy;
+    long     j, i, l, ixsrc, iysrc, isrc, k, *count, nxy;
     float   fxb, fxe, fyb, fye;
 
     if (fxsb < 0) fxb = 1.001*fxsb;
@@ -87,12 +87,14 @@ long nshots, long nxsrc, long nysrc, long *ixpos, long *npos, long reci, long ve
                 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 */
+				    j = linearsearch(ixpos, *npos, ixsrc);
+                    i = linearsearch(iypos, *npos, iysrc);
+				    if ((i*nxs+j) < *npos) { /* the position (at j) is already included */
 					    count[j] += xnx[k];
 				    }
 				    else { /* add new postion */
-            		    ixpos[*npos] =  isrc;
+            		    ixpos[*npos] =  ixsrc;
+                        iypos[*npos] =  iysrc;
 					    count[*npos] += xnx[k];
                    	    *npos += 1;
 				    }
@@ -105,13 +107,14 @@ long nshots, long nxsrc, long nysrc, long *ixpos, long *npos, long reci, long ve
 
     if (verbose>=4) {
 	    for (j=0; j < *npos; j++) { 
-            vmess("ixpos[%li] = %li count=%li", j, ixpos[j], count[j]);
+            vmess("ixpos[%li] = %li iypos = %li ipos = %li count=%li", j, ixpos[j], iypos[j], iypos[j]*nxs+ixpos[j], count[j]);
 		}
     }
     free(count);
 
 /* sort ixpos into increasing values */
-    qsort(ixpos, *npos, sizeof(long), compareInt);
+    // qsort(ixpos, *npos, sizeof(long), compareInt);
+    // qsort(iypos, *npos, sizeof(long), compareInt);
 
 
     return;
@@ -133,15 +136,15 @@ long linearsearch(long *array, size_t N, long value)
 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 *ixpos, long *iypos, long npos, double *tfft, long *isxcount, long *reci_xsrc,  long *reci_xrcv, float *ixmask, long verbose)
 {
     long     nfreq, size, inx;
     float   scl;
-    long     i, j, l, m, iw, ix, k, isrc, il, ik, nxy, nxys;
+    long     i, j, l, m, iw, ix, iy, k, isrc, il, ik, nxy, nxys;
     float   *rtrace, idxs, idys, fxb, fyb, fxe, fye;
     complex *sum, *ctrace;
     long     npe;
-    static long first=1, *ircv;
+    static long first=1, *ixrcv, *iyrcv;
     static double t0, t1, t;
 
     if (fxsb < 0) fxb = 1.001*fxsb;
@@ -184,12 +187,13 @@ long *ixpos, long npos, double *tfft, long *isxcount, long *reci_xsrc,  long *re
             /* 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;
-                   }
+                rc1fft(&Top[l*size+i*nts],ctrace,ntfft,-1);
+                ix = ixpos[i];
+                iy = iypos[i];
+                for (iw=0; iw<nw; iw++) {
+                    Fop[l*nxys*nw+iw*nxys+iy*nxs+ix].r = ctrace[nw_low+iw].r;
+                    Fop[l*nxys*nw+iw*nxys+iy*nxs+ix].i = mode*ctrace[nw_low+iw].i;
+                }
             }
         }
     }
@@ -200,19 +204,21 @@ long *ixpos, long npos, double *tfft, long *isxcount, long *reci_xsrc,  long *re
             /* 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;
-                   }
+                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 = (long *)malloc(nshots*nxy*sizeof(long));
+        iyrcv = (long *)malloc(nshots*nxy*sizeof(long));
+        ixrcv = (long *)malloc(nshots*nxy*sizeof(long));
         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);
+                iyrcv[k*nxy+i] = NINT((yrcv[k*nxy+i]-fysb)*idys);
+                ixrcv[k*nxy+i] = NINT((xrcv[k*nxy+i]-fxsb)*idxs);
             }
         }
     }
@@ -234,8 +240,8 @@ long *ixpos, long npos, double *tfft, long *isxcount, long *reci_xsrc,  long *re
  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)
+ shared(Fop, size, nts, ntfft, scl, iyrcv, ixrcv, isrc) \
+ private(l, ix, iy, j, m, i, sum, rtrace)
 { /* start of parallel region */
             sum   = (complex *)malloc(nfreq*sizeof(complex));
             rtrace = (float *)calloc(ntfft,sizeof(float));
@@ -247,11 +253,12 @@ long *ixpos, long npos, double *tfft, long *isxcount, long *reci_xsrc,  long *re
                 memset(&sum[0].r,0,nfreq*2*sizeof(float));
                 for (i = 0; i < inx; i++) {
                     for (j = nw_low, m = 0; j <= nw_high; j++, m++) {
-                        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;
+                        ix = ixrcv[k*nxy+i];
+                        iy = iyrcv[k*nxy+i];
+                        sum[j].r += Refl[k*nw*nxy+m*nxy+i].r*Fop[l*nw*nxys+m*nxys+iy*nxs+ix].r -
+                                    Refl[k*nw*nxy+m*nxy+i].i*Fop[l*nw*nxys+m*nxys+iy*nxs+ix].i;
+                        sum[j].i += Refl[k*nw*nxy+m*nxy+i].i*Fop[l*nw*nxys+m*nxys+iy*nxs+ix].r +
+                                    Refl[k*nw*nxy+m*nxy+i].r*Fop[l*nw*nxys+m*nxys+iy*nxs+ix].i;
                     }
                 }
 
diff --git a/marchenko3D/writeData.c b/marchenko3D/writeData.c
deleted file mode 120000
index b761f28f24545fb2e550406a85b67afe0410db7e..0000000000000000000000000000000000000000
--- a/marchenko3D/writeData.c
+++ /dev/null
@@ -1 +0,0 @@
-../utils/writeData.c
\ No newline at end of file
diff --git a/utils/Makefile b/utils/Makefile
index 1eb7b80f47f9622dca28aba432da738da126e5d7..7d84e9b3f32f1141f01c9b485b496072ec3b0900 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -6,7 +6,7 @@ include ../Make_include
 #OPTC += -openmp 
 #OPTC += -g -O0
 
-ALL: makemod makewave extendModel fconv correigen green green3D basop syn2d mat2su ftr1d ampdet
+ALL: makemod makewave extendModel fconv correigen green green3D basop syn2d mat2su ftr1d
 
 SRCM	= \
 		makemod.c  \
@@ -133,15 +133,6 @@ SRCT	= ftr1d.c \
 		docpkge.c \
 		getpars.c
 
-SRCAD	= ampdet.c \
-		getFileInfo.c  \
-		readData.c \
-		writeData.c \
-		verbosepkg.c  \
-		atopkge.c \
-		docpkge.c \
-		getpars.c
-
 OBJM	= $(SRCM:%.c=%.o)
 
 makemod:	$(OBJM) 
@@ -197,11 +188,6 @@ OBJT	= $(SRCT:%.c=%.o)
 ftr1d:	$(OBJT) 
 	$(CC) $(LDFLAGS) $(OPTC) $(CFLAGS) -o ftr1d $(OBJT) $(LIBS)
 
-OBJAD	= $(SRCAD:%.c=%.o)
-
-ampdet:	$(OBJAD) 
-	$(CC) $(LDFLAGS) $(OPTC) $(CFLAGS) -o ampdet $(OBJAD) $(LIBS)
-
 install: makemod makewave extendModel fconv correigen green green3D basop syn2d mat2su ftr1d 
 	cp makemod $B
 	cp makewave $B
@@ -216,11 +202,7 @@ install: makemod makewave extendModel fconv correigen green green3D basop syn2d
 	cp ftr1d $B
 
 clean:
-		rm -f core $(OBJM) makemod $(OBJW) makewave $(OBJE) extendModel $(OBJF) fconv $(OBJG) $(OBJC) correigen green $(OBJG3) green3D $(OBJB) basop $(OBJJ) syn2d $(OBJS) mat2su $(OBJA) ftr1d $(OBJT) ampdet $(OBJAD)
+		rm -f core $(OBJM) makemod $(OBJW) makewave $(OBJE) extendModel $(OBJF) fconv $(OBJG) $(OBJC) correigen green $(OBJG3) green3D $(OBJB) basop $(OBJJ) syn2d $(OBJS) mat2su $(OBJA) ftr1d $(OBJT)
 
 realclean: clean
 		rm -f $B/makemod $B/makewave $B/extendModel $B/fconv $B/correigen $B/green $B/green3D $B/basop $B/syn2d $B/mat2su $B/ftr1d
-
-
-
-
diff --git a/utils/ampdet b/utils/ampdet
new file mode 100755
index 0000000000000000000000000000000000000000..574ead227792513d2bfdcafdf433560e4a3ee50c
Binary files /dev/null and b/utils/ampdet differ
diff --git a/utils/ampdet_amp.c b/utils/ampdet_amp.c
new file mode 100644
index 0000000000000000000000000000000000000000..a7b7bed0e5fb6d9405a485c11da57c170a22bd23
--- /dev/null
+++ b/utils/ampdet_amp.c
@@ -0,0 +1,261 @@
+#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 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, *den, dentmp;
+    float   df, dw, dkx, eps, reps, leps;
+    float   *Gpd, *f1pd, *G_pad, *f_pad, *wav, *wav_pad, *outdata;
+    complex *G_w, *f_w, *Gf, *amp, *wav_w, *S, *ZS, *SS;
+    segy    *hdr_gp, *hdr_fp, *hdr_wav, *hdr_out;
+
+	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_fp", &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);
+
+    /* 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 *)calloc(ntfft*nkx,sizeof(float));
+	if (G_pad == NULL) verr("memory allocation error for G_pad");
+    f_pad = (float *)calloc(ntfft*nkx,sizeof(float));
+	if (f_pad == NULL) verr("memory allocation error for f_pad");
+    wav_pad = (float *)calloc(ntfft,sizeof(float));
+	if (wav_pad == NULL) verr("memory allocation error for wav_pad");
+    G_w   = (complex *)calloc(nfreq*nkx,sizeof(complex));
+	if (G_w == NULL) verr("memory allocation error for G_w");
+    f_w   = (complex *)calloc(nfreq*nkx,sizeof(complex));
+	if (f_w == NULL) verr("memory allocation error for f_w");
+    Gf    = (complex *)calloc(nfreq*nkx,sizeof(complex));
+	if (Gf == NULL) verr("memory allocation error for Gf");
+    wav_w = (complex *)calloc(nfreq*nkx,sizeof(complex));
+	if (wav_w == NULL) verr("memory allocation error for wav_w");
+    amp   = (complex *)calloc(nfreq*nkx,sizeof(complex));
+	if (amp == NULL) verr("memory allocation error for amp");
+    S   = (complex *)calloc(nfreq*nkx,sizeof(complex));
+	if (S == NULL) verr("memory allocation error for S");
+    ZS   = (complex *)calloc(nfreq*nkx,sizeof(complex));
+	if (ZS == NULL) verr("memory allocation error for ZS");
+    SS   = (complex *)calloc(nfreq*nkx,sizeof(complex));
+	if (SS == NULL) verr("memory allocation error for SS");
+    den   = (float *)calloc(nfreq*nkx,sizeof(float));
+	if (den == NULL) verr("memory allocation error for den");
+
+    /* 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], &Gf[0], ntfft, 1, ntfft, nfreq, -1);
+
+    for (i=0; i<nkx; i++) {
+        for (j=0; j<nfreq; j++) {
+            wav_w[j*nkx+i].r = Gf[j].r;
+            wav_w[j*nkx+i].i = Gf[j].i;	
+		}
+    }
+
+	dt = 1.0;
+
+	for (i = 0; i < nkx*nfreq; i++) {
+		Gf[i].r = dt*(G_w[i].r*f_w[i].r - G_w[i].i*f_w[i].i);
+		Gf[i].i = dt*(G_w[i].r*f_w[i].i + G_w[i].i*f_w[i].r);
+
+		S[i].r = dt*(wav_w[i].r*wav_w[i].r + wav_w[i].i*wav_w[i].i);
+		S[i].i = dt*(wav_w[i].r*wav_w[i].i - wav_w[i].i*wav_w[i].r);
+
+		ZS[i].r = dt*(Gf[i].r*S[i].r + Gf[i].i*S[i].i);
+		ZS[i].i = dt*(Gf[i].r*S[i].i - Gf[i].i*S[i].r);
+
+		SS[i].r = dt*(S[i].r*S[i].r + S[i].i*S[i].i);
+		SS[i].i = dt*(S[i].r*S[i].i - S[i].i*S[i].r);
+
+		if (i==0) dentmp=SS[i].r;
+		else dentmp=MAX(dentmp,SS[i].r);
+	}
+
+	leps = reps*dentmp+eps;
+	vmess("dentmp:%.4e leps:%.4e",dentmp,leps);
+
+	for (i = 0; i < nkx*nfreq; i++) {
+		amp[i].r = (ZS[i].r*SS[i].r+ZS[i].i*SS[i].i)/(SS[i].r*SS[i].r+SS[i].i*SS[i].i+leps);
+		amp[i].i = (ZS[i].i*SS[i].r-ZS[i].r*SS[i].i)/(SS[i].r*SS[i].r+SS[i].i*SS[i].i+leps);
+		
+		// complex_sqrt(&amp[i]);
+		// if (isnan(amp[i].r)) amp[i].r = 0;
+		// if (isnan(amp[i].i)) amp[i].i = 0;
+
+		Gf[i].r = dt*(G_w[i].r*amp[i].r - G_w[i].i*amp[i].i);
+		Gf[i].i = dt*(G_w[i].r*amp[i].i + G_w[i].i*amp[i].r);
+	}
+
+	// for (i=0; i<nfreq; i++) {
+	// 	for (j=0; j<nkx; j++) {
+	// 		Gpd[j*nfreq+i] = sqrtf(amp[i*nkx+j].r*amp[i*nkx+j].r+amp[i*nkx+j].i*amp[i*nkx+j].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);
+
+	// fp      = fopen("wav.su", "w+");
+	// for (j=0; j<nkx; j++) {
+	// 	hdr_gp[j].ns = nfreq;
+	// }
+    // ret = writeData(fp, Gpd, hdr_gp, nfreq, nkx);
+	// if (ret < 0 ) verr("error on writing output file.");
+    // fclose(fp);
+
+    free(f1pd);free(Gpd);free(hdr_gp);free(hdr_fp);
+
+	return 0;
+}
+
+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