/** * Applies the shifts {@code u} to the trace {@code g}. * * @param sf the sampling that {@code g} is being warped to. * @param u the shifts to apply to {@code g}. * @param sg the sampling of {@code g}. * @param g the trace to be warped. * @return the warped image. */ public static float[][][] applyShifts( Sampling sf, final float[][][] u, Sampling sg, final float[][][] g) { final int n1 = u[0][0].length; final int n2 = u[0].length; final int n3 = u.length; final int ng = g[0][0].length; final double dg = sg.getDelta(); final double df = sf.getDelta(); final double fg = sg.getDelta(); final double ff = sf.getDelta(); final float[][][] hf = new float[n3][n2][n1]; final SincInterp si = new SincInterp(); int n23 = n3 * n2; Parallel.loop( n23, new Parallel.LoopInt() { public void compute(int i23) { int i2 = i23 % n2; int i3 = i23 / n2; double v = ff; for (int i1 = 0; i1 < n1; i1++, v = ff + i1 * df) { hf[i3][i2][i1] = si.interpolate(ng, dg, fg, g[i3][i2], (float) v + u[i3][i2][i1]); } } }); return hf; }
/** * Get the {@code grid} as sample indices. * * @param s Sampling that this {@code grid} subsamples. * @param grid the subsample locations defined in terms of Sampling {@code s}. * @return the {@code grid} as sample indices. * @throws IllegalArgumentException if any of the grid locations are not valid with the given * Sampling {@code s}. */ public static int[] gridCoordsToSamples(Sampling s, float[] grid) { Almost a = new Almost(); float f = (float) s.getFirst(); float l = (float) s.getLast(); int ng = grid.length; int[] t = new int[ng]; // temp sample indices int count = 0; int is = -1; // save last index for (int ig = 0; ig < ng; ig++) { float v = grid[ig]; if (a.ge(v, f) && a.le(v, l)) { int i = s.indexOfNearest(v); if (i != is) { // no duplicate entries t[count] = i; count++; } is = i; } else { print("Error: value " + v + " is out of bounds! First=" + f + ", Last=" + l); } } if (count != ng) { print("Grid values:"); dump(grid); throw new IllegalArgumentException( "Error: Only " + count + " of " + ng + " input grid coordinates are valid " + "with the specified sampling " + s.toString()); } return copy(count, t); }
private static float[] getValues(Sampling s) { int n = s.getCount(); double f = s.getFirst(); double d = s.getDelta(); float[] x = new float[n]; for (int i = 0; i < n; i++) x[i] = (float) (f + i * d); return x; }
public static float[] ps1ToPpTime(Sampling sf, float[] u1, Sampling sg, float[] g) { int n1 = u1.length; int ng = g.length; float[] xg = new float[ng]; for (int ig = 0; ig < ng; ig++) xg[ig] = (float) sg.getValue(ig); CubicInterpolator ci = new CubicInterpolator(Method.LINEAR, xg, g); float[] gp = new float[n1]; for (int i1 = 0; i1 < n1; i1++) gp[i1] = ci.interpolate((float) (sf.getValue(i1) + u1[i1])); return gp; }
/** * Applies the shifts {@code u} to the trace {@code g}. * * @param sf the sampling that {@code g} is being warped to. * @param u the shifts to apply to {@code g}. * @param sg the sampling of {@code g}. * @param g the trace to be warped. * @return the warped trace. */ public static float[] applyShifts(Sampling sf, final float[] u, Sampling sg, final float[] g) { final int n1 = u.length; final int ng = g.length; final double dg = sg.getDelta(); final double df = sf.getDelta(); final double fg = sg.getDelta(); final double ff = sf.getDelta(); final float[] hf = new float[n1]; final SincInterp si = new SincInterp(); double v = ff; for (int i1 = 0; i1 < n1; i1++, v = ff + i1 * df) hf[i1] = si.interpolate(ng, dg, fg, g, (float) v + u[i1]); return hf; }
/** * Computes an array of VpVs ratios an array of shifts u using a backward difference * approximation. The relationship is defined as vpvs(t) = 1+2*(du/dt) * * @param u * @return computed vpvs values. */ public static float[] vpvsBd(Sampling su, float[] u) { float dui = 1.0f / (float) su.getDelta(); int n = u.length; float[] vpvs = new float[n]; vpvs[0] = 1.0f + 2.0f * (u[1] - u[0]) * dui; // at i1=0, forward difference for (int i1 = 1; i1 < n; ++i1) vpvs[i1] = 1.0f + 2.0f * (u[i1] - u[i1 - 1]) * dui; return vpvs; }
/** * Gets the flattening shifts s(u1,u2,u3) = u1 - x1(u1,u2,u3). * * @return the flattening shifts. */ public float[][][] getShiftsS() { int n1 = s1.getCount(); int n2 = s2.getCount(); int n3 = s3.getCount(); float[][][] s = new float[n3][n2][n1]; float d1 = (float) s1.getDelta(); float f1 = (float) s1.getFirst(); for (int i3 = 0; i3 < n3; ++i3) { for (int i2 = 0; i2 < n2; ++i2) { for (int i1 = 0; i1 < n1; ++i1) { float u1i = f1 + i1 * d1; s[i3][i2][i1] = u1i - x1[i3][i2][i1]; } } } return s; }
/** * Scale shifts by compression factor c. * * @param sf the trace sampling corresponding to shifts. * @param u array of shifts to compress. * @param c scale factor. To stretch, c, to compress, 1/c. * @return scaled shifts. */ public static float[] getScaledShifts(Sampling sf, float[] u, float c) { int n = u.length; float[] uc = new float[n]; for (int i = 0; i < n; i++) { float fv = (float) sf.getValue(i); uc[i] = (fv + u[i]) * c - fv; } return uc; }
private float[][][] apply(final float[][][] ux, final float[][][] f) { final int n1 = s1.getCount(); final int n2 = s2.getCount(); final int n3 = s3.getCount(); final double d1 = s1.getDelta(); final double f1 = s1.getFirst(); final SincInterpolator si = new SincInterpolator(); final float[][][] g = new float[n3][n2][n1]; Parallel.loop( n3, new Parallel.LoopInt() { public void compute(int i3) { for (int i2 = 0; i2 < n2; ++i2) si.interpolate(n1, d1, f1, f[i3][i2], n1, ux[i3][i2], g[i3][i2]); } }); return g; }
public static double[] getSubStrainMax(Sampling su, float[] u, double[] rmax) { float dui = 1.0f / (float) su.getDelta(); int n = u.length; int nm1 = n - 1; double[] rmaxNew = new double[n]; rmaxNew[0] = rmax[0] - (u[1] - u[0]) * dui; // forward diff rmaxNew[nm1] = rmax[nm1] - (u[nm1] - u[nm1 - 1]) * dui; // backward diff for (int i1 = 1; i1 < nm1; i1++) rmaxNew[i1] = rmax[i1] - (u[i1 + 1] - u[i1 - 1]) * 0.5 * dui; return rmaxNew; }
/** * Computes gammaS, a measure of the time delay between two split shear waves, from shifts between * PP-PS2 {@code u2} and PS1-PS2 {@code uS}. * * @param sf PP time Sampling. * @param u2 shifts between PP-PS2 in PP time. * @param uS shifts between PS1-PS2 in PP time. * @return gammaS */ public static float[] gammaSu2S(Sampling sf, float[] u2, float[] uS) { int n1 = u2.length; Check.argument(n1 == sf.getCount(), "u2 consistent with sampling"); Check.argument(n1 == uS.length, "u2.length==uS.length"); float[] du2 = firstDerivative(sf, u2); float[] duS = firstDerivative(sf, uS); float[] gs = new float[n1]; for (int i1 = 0; i1 < n1; i1++) gs[i1] = (2.0f * duS[i1]) / (1.0f + 2.0f * (du2[i1] - duS[i1])); return gs; }
public float[][][][] flattenWithShifts( final Sampling s1, final float[][][] r, final float[][][] f) { cleanShifts(r); final int n3 = r.length; final int n2 = r[0].length; final int n1 = r[0][0].length; // Compute u1(x1,x2,x3). final double f1 = s1.getFirst(); final double d1 = s1.getDelta(); final float[][][] u1 = r; for (int i3 = 0; i3 < n3; ++i3) { for (int i2 = 0; i2 < n2; ++i2) { for (int i1 = 0; i1 < n1; ++i1) { float x1i = (float) (f1 + i1 * d1); u1[i3][i2][i1] = (float) (x1i + r[i3][i2][i1] * d1); } } } // Compute x1(u1,u2). final float[][][] x1 = new float[n3][n2][n1]; final InverseInterpolator ii = new InverseInterpolator(s1, s1); Parallel.loop( n3, new Parallel.LoopInt() { public void compute(int i3) { for (int i2 = 0; i2 < n2; ++i2) ii.invert(u1[i3][i2], x1[i3][i2]); } }); final SincInterpolator si = new SincInterpolator(); final float[][][] g = new float[n3][n2][n1]; Parallel.loop( n3, new Parallel.LoopInt() { public void compute(int i3) { for (int i2 = 0; i2 < n2; ++i2) si.interpolate(n1, d1, f1, f[i3][i2], n1, x1[i3][i2], g[i3][i2]); } }); return new float[][][][] {g, u1}; }
private static float[] firstDerivative(Sampling s, float[] f) { int n = f.length; int nm1 = n - 1; float[] g = new float[n]; float di = 1.0f / (float) s.getDelta(); float di2 = 0.5f * di; g[0] = (f[1] - f[0]) * di; // forward diff g[nm1] = (f[nm1] - f[nm1 - 1]) * di; // backward diff for (int i1 = 1; i1 < nm1; i1++) g[i1] = (f[i1 + 1] - f[i1 - 1]) * di2; return g; }
/** * Gets mappings computed from specified slopes and planarities. * * @param s1 sampling of 1st dimension. * @param s2 sampling of 2nd dimension. * @param p2 array of slopes of image features. * @param ep array of planarities of image features. */ public Mappings getMappingsFromSlopes( Sampling s1, Sampling s2, Sampling s3, float[][][] p2, float[][][] p3, float[][][] ep) { // Sampling parameters. final int n1 = s1.getCount(); final int n2 = s2.getCount(); final int n3 = s3.getCount(); float d1 = (float) s1.getDelta(); float d2 = (float) s2.getDelta(); float d3 = (float) s3.getDelta(); float f1 = (float) s1.getFirst(); // If necessary, convert units for slopes to samples per sample. if (d1 != d2) p2 = mul(d2 / d1, p2); if (d1 != d3) p3 = mul(d3 / d1, p3); // Compute shifts r(x1,x2,x3), in samples. float[][][] b = new float[n3][n2][n1]; // right-hand side float[][][] r = new float[n3][n2][n1]; // shifts, in samples VecArrayFloat3 vb = new VecArrayFloat3(b); VecArrayFloat3 vr = new VecArrayFloat3(r); Smoother3 smoother3 = new Smoother3(n1, n2, n3, _sigma1, _sigma2, _sigma3, ep); A3 a3 = new A3(smoother3, _weight1, ep, p2, p3); CgSolver cs = new CgSolver(_small, _niter); makeRhs(ep, p2, p3, b); smoother3.applyTranspose(b); cs.solve(a3, vb, vr); smoother3.apply(r); cleanShifts(r); // Compute u1(x1,x2,x3). final float[][][] u1 = r; for (int i3 = 0; i3 < n3; ++i3) { for (int i2 = 0; i2 < n2; ++i2) { for (int i1 = 0; i1 < n1; ++i1) { float x1i = f1 + i1 * d1; u1[i3][i2][i1] = x1i + r[i3][i2][i1] * d1; } } } // Compute x1(u1,u2). final float[][][] x1 = b; final InverseInterpolator ii = new InverseInterpolator(s1, s1); Parallel.loop( n3, new Parallel.LoopInt() { public void compute(int i3) { for (int i2 = 0; i2 < n2; ++i2) ii.invert(u1[i3][i2], x1[i3][i2]); } }); return new Mappings(s1, s2, s3, u1, x1); }