Example usage for java.util.concurrent.atomic AtomicInteger getAndIncrement

List of usage examples for java.util.concurrent.atomic AtomicInteger getAndIncrement

Introduction

In this page you can find the example usage for java.util.concurrent.atomic AtomicInteger getAndIncrement.

Prototype

public final int getAndIncrement() 

Source Link

Document

Atomically increments the current value, with memory effects as specified by VarHandle#getAndAdd .

Usage

From source file:Distortions.java

public void calculateGridImageMasks(final double minContrast, final double shrinkBlurSigma,
        final double shrinkBlurLevel, final int threadsMax, final boolean updateStatus) {
    final int numImg = fittingStrategy.distortionCalibrationData.getNumImages();
    final DistortionCalibrationData.GridImageParameters[] distortionCalibrationData = this.fittingStrategy.distortionCalibrationData.gIP;
    if (updateStatus)
        IJ.showStatus("Calculating grid image masks...");
    System.out.print("Calculating grid image masks...");
    System.out.print(" minContrast=" + minContrast + " shrinkBlurSigma=" + shrinkBlurSigma + " shrinkBlurLevel="
            + shrinkBlurLevel);/*from w w w.  ja  v a 2  s  . co  m*/

    final AtomicInteger imageNumberAtomic = new AtomicInteger(0);
    final AtomicInteger imageFinishedAtomic = new AtomicInteger(0);
    final Thread[] threads = newThreadArray(threadsMax);
    for (int ithread = 0; ithread < threads.length; ithread++) {
        threads[ithread] = new Thread() {
            public void run() {
                for (int imgNum = imageNumberAtomic
                        .getAndIncrement(); imgNum < numImg; imgNum = imageNumberAtomic.getAndIncrement()) {
                    distortionCalibrationData[imgNum].calculateMask(minContrast, shrinkBlurSigma,
                            shrinkBlurLevel);
                    final int numFinished = imageFinishedAtomic.getAndIncrement();
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            if (updateStatus)
                                IJ.showProgress(numFinished, numImg);
                        }
                    });

                } // for (int numImage=imageNumberAtomic.getAndIncrement(); ...
            } // public void run() {
        };
    }
    startAndJoin(threads);
    if (updateStatus)
        IJ.showProgress(0);
    if (updateStatus)
        IJ.showStatus("Calculating grid image masks... DONE");
    System.out.println("  Done");

}

From source file:Distortions.java

/**
 * Calculate each sensor correction increment for geometry and photometry contributed by all images selected in a series
 * @param selectedImages process only selected images 
 * @param showIndividual show per-image intermediate results
 * @param threadsMax maximal number of concurrent threads
 * @param updateStatus update IJ status/progress
 * @param debugLevel debug level//  w w  w.j a  va2  s  .  c o m
 * @return [sensor]{dpX,dpY,alpha,R,G,B}[pixelIndex] . dpX, dpY - correction to previous, RGB - total FF, not increment! 
 */

public double[][][] allImagesCorrectionMapped(final boolean[] selectedImages, final boolean showIndividual,
        final int showIndividualNumber, final int threadsMax, final boolean updateStatus,
        final int debugLevel) {
    int numChannels = fittingStrategy.distortionCalibrationData.getNumChannels(); // number of used channels
    final double[][][] gridPCorr = new double[numChannels][][];
    for (int chnNum = 0; chnNum < gridPCorr.length; chnNum++)
        gridPCorr[chnNum] = null;
    int numSelected = 0;
    for (int imgNum = 0; imgNum < selectedImages.length; imgNum++)
        if (selectedImages[imgNum])
            numSelected++;
    final int finalSelected = numSelected;
    if (updateStatus)
        IJ.showStatus("Calculating sensor corrections...");
    final AtomicInteger imageNumberAtomic = new AtomicInteger(0);
    final AtomicInteger imageFinishedAtomic = new AtomicInteger(0);
    final Thread[] threads = newThreadArray(threadsMax);
    final AtomicInteger stopRequested = this.stopRequested;
    final AtomicBoolean interruptedAtomic = new AtomicBoolean();
    final int alphaIndex = 2;

    for (int ithread = 0; ithread < threads.length; ithread++) {
        threads[ithread] = new Thread() {
            public void run() {
                for (int imgNum = imageNumberAtomic.getAndIncrement(); (imgNum < selectedImages.length)
                        && !interruptedAtomic.get(); imgNum = imageNumberAtomic.getAndIncrement()) {
                    if (selectedImages[imgNum]) {
                        int chnNum = fittingStrategy.distortionCalibrationData.gIP[imgNum].channel; // number of sub-camera
                        double[][] singleCorr = singleImageCorrectionMapped(imgNum, // image number
                                showIndividual
                                        && ((showIndividualNumber < 0) || (showIndividualNumber == chnNum)),
                                debugLevel);
                        combineImageCorrection(chnNum, gridPCorr, singleCorr);
                        final int numFinished = imageFinishedAtomic.getAndIncrement();
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                if (updateStatus)
                                    IJ.showProgress(numFinished, finalSelected);
                            }
                        });
                        if (stopRequested.get() == 1) { // ASAP
                            interruptedAtomic.set(true);
                        }
                    } //if (selectedImages[numImage]){
                } // for (int numImage=imageNumberAtomic.getAndIncrement(); ...
            } // public void run() {
        };
    }
    startAndJoin(threads);
    // divide by weight;
    for (int nChn = 0; nChn < gridPCorr.length; nChn++)
        if (gridPCorr[nChn] != null) {
            for (int i = 0; i < gridPCorr[nChn].length; i++) {
                if (i != alphaIndex) {
                    for (int j = 0; j < gridPCorr[nChn][i].length; j++) {
                        if (gridPCorr[nChn][alphaIndex][j] > 0)
                            gridPCorr[nChn][i][j] /= gridPCorr[nChn][alphaIndex][j];
                    }
                }
            }
        }

    if (updateStatus)
        IJ.showProgress(0);

    if (interruptedAtomic.get()) {
        System.out.println("allImagesCorrection() aborted by user request");
        return null;
    }
    return gridPCorr;
}

From source file:Distortions.java

public double[] calculatePatterErrorRMS( // returns worst image number array
        final int series, final int threadsMax, final boolean updateStatus, final int debugLevel

) {// w w w  . j a va  2 s.  c  o  m
    if (fittingStrategy == null) {
        String msg = "Fitting strategy does not exist, exiting";
        IJ.showMessage("Error", msg);
        throw new IllegalArgumentException(msg);
    }
    if (fittingStrategy.distortionCalibrationData.eyesisCameraParameters == null) {
        String msg = "Eyesis camera parameters (and sensor dimensions) are not defined";
        IJ.showMessage("Error", msg);
        throw new IllegalArgumentException(msg);
    }
    //   fittingStrategy.distortionCalibrationData.readAllGrids(); 
    //       if (! selectGridEnhanceParameters()) return false;
    //       if (series<0) return null; // false; // make "all " later?
    this.seriesNumber = series;

    initFittingSeries(true, this.filterForTargetGeometry, this.seriesNumber); // first step in series now uses pattern alpha
    this.currentfX = calculateFxAndJacobian(this.currentVector, false);
    //           this.currentRMS= calcError(calcYminusFx(this.currentfX));
    if (this.debugLevel > 2) {
        System.out.println("this.currentVector");
        for (int i = 0; i < this.currentVector.length; i++) {
            System.out.println(i + ": " + this.currentVector[i]);
        }
    }
    final boolean[] selectedImages = fittingStrategy.selectedImages();
    final Rectangle gridDimensions = patternParameters.getUVDimensions();
    final int width = gridDimensions.width;
    final int height = gridDimensions.height;
    //      final int U0=     gridDimensions.x;
    //      final int V0=     gridDimensions.y;
    final double[][] gridErrors = new double[4][width * height]; // added debug features - worst image number
    for (int n = 0; n < gridErrors.length; n++)
        for (int i = 0; i < gridErrors[n].length; i++)
            gridErrors[n][i] = 0.0;
    int numSelected = 0;
    for (int imgNum = 0; imgNum < selectedImages.length; imgNum++)
        if (selectedImages[imgNum])
            numSelected++;
    final int finalSelected = numSelected;
    if (updateStatus)
        IJ.showStatus("Calculating pattern grid errors...");
    final AtomicInteger imageNumberAtomic = new AtomicInteger(0);
    final AtomicInteger imageFinishedAtomic = new AtomicInteger(0);
    final Thread[] threads = newThreadArray(threadsMax);
    for (int ithread = 0; ithread < threads.length; ithread++) {
        threads[ithread] = new Thread() {
            public void run() {
                double[][] partialGridErrors = new double[4][width * height];
                for (int n = 0; n < partialGridErrors.length; n++)
                    for (int i = 0; i < partialGridErrors[n].length; i++)
                        partialGridErrors[n][i] = 0.0;
                for (int imgNum = imageNumberAtomic
                        .getAndIncrement(); imgNum < selectedImages.length; imgNum = imageNumberAtomic
                                .getAndIncrement()) {
                    if (selectedImages[imgNum]) {
                        accumulatePatternErrors(partialGridErrors, imgNum, gridDimensions);
                        final int numFinished = imageFinishedAtomic.getAndIncrement();
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                if (updateStatus)
                                    IJ.showProgress(numFinished, finalSelected);
                            }
                        });
                    } //if (selectedImages[numImage]){
                } // for (int numImage=imageNumberAtomic.getAndIncrement(); ...
                combinePatternErrors(partialGridErrors, gridErrors);
            } // public void run() {
        };
    }
    startAndJoin(threads);
    for (int i = 0; i < gridErrors[0].length; i++) {
        gridErrors[0][i] = (gridErrors[0][i] > 0.0) ? Math.sqrt(gridErrors[0][i] / gridErrors[1][i])
                : Double.NaN;

    }
    patternParameters.setPatternErrors(gridErrors[0]);
    return gridErrors[2]; // worst image number for target grid nodes
}

From source file:Distortions.java

public double[][][] calculateGridXYZCorr2D(final int width, final int height, final int[] stationGroups,
        final boolean[] selectedImages, final double[][] cameraXYZ,
        final LensDistortionParameters lensDistortionParametersProto, final boolean showIndividual,
        final int threadsMax, final boolean updateStatus) {
    final int[][] dirs = { { 0, 0 }, { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; // possible to make 8 directions
    final double[][][] derivatives = { // for of /du, /dv 3 variants, depending on which neighbors are available
            { { 0.0, -0.5, 0.5, 0.0, 0.0 }, { 1.0, -1.0, 0.0, 0.0, 0.0 }, { -1.0, 0.0, 1.0, 0.0, 0.0 } },
            { { 0.0, 0.0, 0.0, -0.5, 0.5 }, { 1.0, 0.0, 0.0, -1.0, 0.0 }, { -1.0, 0.0, 0.0, 0.0, 1.0 } } };
    final double[][][] gridCorr2d = new double[selectedImages.length][][]; // per-image grid {dx,dy,weight} corrections
    for (int i = 0; i < gridCorr2d.length; i++) {
        gridCorr2d[i] = null;//from   w  w w.  j  av a 2  s. c  o  m
        cameraXYZ[i] = null;
    }
    // Should it be just once - common for all images? (removed from the "for" loop)
    final double[] diff = calcYminusFx(this.currentfX);
    final int debugLevel = this.debugLevel;
    final int[] imageStartIndex = this.imageStartIndex;
    final double[] Y = this.Y;
    final double[] weightFunction = this.weightFunction;
    final Thread[] threads = newThreadArray(threadsMax);
    final AtomicInteger imageNumberAtomic = new AtomicInteger(0);
    final AtomicInteger imageFinishedAtomic = new AtomicInteger(0);
    final double[] progressValues = new double[selectedImages.length];
    int numSelectedImages = 0;
    for (int i = 0; i < selectedImages.length; i++)
        if (selectedImages[i])
            numSelectedImages++;
    int selectedIndex = 0;
    for (int i = 0; i < selectedImages.length; i++) {
        progressValues[i] = (selectedIndex + 1.0) / numSelectedImages;
        if (selectedImages[i])
            selectedIndex++;
        if (selectedIndex >= numSelectedImages)
            selectedIndex--;
    }
    IJ.showStatus("Calculating pattern geometry correction...");
    for (int ithread = 0; ithread < threads.length; ithread++) {
        threads[ithread] = new Thread() {
            public void run() {
                LensDistortionParameters lensDistortionParameters = lensDistortionParametersProto.clone(); // see - if that is needed - maybe new is OK
                //                  LensDistortionParameters lensDistortionParameters= new LensDistortionParameters();
                for (int imgNum = imageNumberAtomic
                        .getAndIncrement(); imgNum < selectedImages.length; imgNum = imageNumberAtomic
                                .getAndIncrement())
                    if (selectedImages[imgNum]) {
                        //      for (int imgNum=0;imgNum<selectedImages.length;imgNum++) if (selectedImages[imgNum]) {
                        int station = fittingStrategy.distortionCalibrationData.gIP[imgNum].getStationNumber(); // number of sub-camera
                        if (stationGroups[station] < 0)
                            continue; // do not process images that do not belong to selected stations
                        gridCorr2d[imgNum] = new double[4][width * height]; // dx, dy only - added zCorr per station
                        for (int n = 0; n < gridCorr2d[imgNum].length; n++)
                            for (int i = 0; i < gridCorr2d[imgNum][0].length; i++)
                                gridCorr2d[imgNum][n][i] = 0.0;
                        //      int chnNum=fittingStrategy.distortionCalibrationData.gIP[imgNum].channel; // number of sub-camera
                        cameraXYZ[imgNum] = new double[3];
                        // The following method sets this.lensDistortionParameters and invokes this.lensDistortionParameters.recalcCommons();
                        calcInterParamers(lensDistortionParameters, null, //this.interParameterDerivatives, // [22][]
                                //                        fittingStrategy.distortionCalibrationData.pars[imgNum], // 22-long parameter vector for the image
                                fittingStrategy.distortionCalibrationData.getParameters(imgNum), // 22-long parameter vector for the image
                                null); // if no derivatives, null is OK
                        //            false); // calculate this.interParameterDerivatives -derivatives array (false - just this.values)
                        cameraXYZ[imgNum] = lensDistortionParameters.getLensCenterCoordinates();
                        if (debugLevel > 2) {
                            System.out.println("calculateGridXYZCorr(): imgNum=" + imgNum
                                    + " lens coordinates (mm)={" + IJ.d2s(cameraXYZ[imgNum][0], 3) + ", "
                                    + IJ.d2s(cameraXYZ[imgNum][1], 3) + ", " + IJ.d2s(cameraXYZ[imgNum][2], 3)
                                    + "}");
                        }
                        //      double [] diff=calcYminusFx(this.currentfX); // removed from the loop
                        // find data range for the selected image
                        int index = imageStartIndex[imgNum]; // set when fitting series is init
                        double[][] imgData = new double[showIndividual ? 7 : 5][getGridHeight() * width]; // dPX, dPY, Px, Py, alpha
                        for (int i = 0; i < imgData.length; i++)
                            for (int j = 0; j < imgData[i].length; j++)
                                imgData[i][j] = 0.0;
                        // first pass - prepare [v][u]arrays
                        for (int i = 0; i < fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsUV.length; i++) {
                            int u = fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsUV[i][0]
                                    + patternParameters.U0;
                            int v = fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsUV[i][1]
                                    + patternParameters.V0;
                            int vu = u + width * v;
                            imgData[0][vu] = diff[2 * (index + i)]; // out of bound 1410
                            imgData[1][vu] = diff[2 * (index + i) + 1];
                            imgData[2][vu] = Y[2 * (index + i)]; // measured pixel x
                            imgData[3][vu] = Y[2 * (index + i) + 1];// measured pixel y

                            //            imgData[4][vu]= fittingStrategy.distortionCalibrationData.getMask(chnNum, imgData[2][vu], imgData[3][vu]);

                            if (weightFunction != null) {
                                imgData[4][vu] = weightFunction[2 * (index + i)];
                            } else {
                                imgData[4][vu] = 1.0;
                            }
                        }
                        // second pass - calculate derivatives, and residuals in mm
                        for (int i = 0; i < fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsUV.length; i++) {
                            int u = fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsUV[i][0]
                                    + patternParameters.U0;
                            int v = fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsUV[i][1]
                                    + patternParameters.V0;
                            int vu = u + width * v;
                            gridCorr2d[imgNum][0][vu] = 0.0;
                            gridCorr2d[imgNum][1][vu] = 0.0;
                            gridCorr2d[imgNum][2][vu] = patternParameters.getZCorr(vu, station); // per-station Z correction from average
                            gridCorr2d[imgNum][3][vu] = 0.0; // weight
                            double[][] gXY = new double[dirs.length][3];
                            //         double [][] gpXY=new double[dirs.length][2];
                            double[][] gpXY = new double[dirs.length][3];
                            boolean[] dirMask = new boolean[dirs.length];
                            for (int dir = 0; dir < dirs.length; dir++) {
                                int u1 = u + dirs[dir][0];
                                int v1 = v + dirs[dir][1];
                                int vu1 = u1 + width * v1;
                                dirMask[dir] = (u1 >= 0) && (v1 >= 0) && (u1 < width) && (v1 < height)
                                        && (imgData[4][vu1] > 0);
                                if (dirMask[dir]) {
                                    gXY[dir][0] = patternParameters.gridGeometry[v1][u1][0];
                                    gXY[dir][1] = patternParameters.gridGeometry[v1][u1][1];
                                    gXY[dir][2] = patternParameters.gridGeometry[v1][u1][2]; // Here - average Z
                                    gpXY[dir][0] = imgData[2][vu1];
                                    gpXY[dir][1] = imgData[3][vu1];
                                } else {
                                    gXY[dir][0] = 0.0;
                                    gXY[dir][1] = 0.0;
                                    gXY[dir][2] = 0.0;
                                    gpXY[dir][0] = 0.0;
                                    gpXY[dir][1] = 0.0;

                                }
                            }
                            int[] variants = { -1, -1 }; // {horizontal, vertical}
                            boolean variantsExist = true;
                            for (int duv = 0; duv < 2; duv++) { // 0 - horizontal, 1 - vertical
                                for (int variant = 0; variant < derivatives[duv].length; variant++) { // variants: 0 half of right/left, 1 left deriv, 2 - right deriv
                                    boolean fit = true;
                                    for (int dir = 0; dir < dirs.length; dir++)
                                        if ((derivatives[duv][variant][dir] != 0) && !dirMask[dir]) {
                                            fit = false;
                                            break;
                                        }
                                    if (fit) {
                                        variants[duv] = variant;
                                        break;
                                    }
                                }
                                if (variants[duv] < 0) { // could not find any variant to calculate derivatives for this direction
                                    variantsExist = false;
                                    break;
                                }
                            }
                            if (!variantsExist) {
                                imgData[4][vu] = 0.0;
                                continue;
                            }
                            double[][] dXY_dUV = new double[2][2];
                            double[][] dpXY_dUV = new double[2][2];
                            for (int nom = 0; nom < 2; nom++) { // 0-x, 1 - y
                                for (int denom = 0; denom < 2; denom++) { //0 - du, 1 - dv
                                    dXY_dUV[nom][denom] = 0.0;
                                    dpXY_dUV[nom][denom] = 0.0;
                                    for (int dir = 0; dir < dirs.length; dir++) {
                                        dXY_dUV[nom][denom] += gXY[dir][nom]
                                                * derivatives[denom][variants[denom]][dir];
                                        dpXY_dUV[nom][denom] += gpXY[dir][nom]
                                                * derivatives[denom][variants[denom]][dir];
                                    }
                                }
                            }
                            double[] dpXY = { imgData[0][vu], imgData[1][vu] };
                            Matrix MdpXY = new Matrix(dpXY, 2); // 2 rows
                            Matrix MdXY_dUV = new Matrix(dXY_dUV);
                            Matrix MdpXY_dUV = new Matrix(dpXY_dUV);
                            if ((new LUDecomposition(MdpXY_dUV)).isNonsingular()) {
                                /*
                                 * MdpXY= MdpXY_dUV* MdUV
                                 * MdXY=  MdXY_dUV * MdUV
                                 * MdUV=  MdpXY_dUV.solve(MdpXY);          
                                 * MdXY=  MdXY_dUV * MdpXY_dUV.solve(MdpXY);
                                 */
                                Matrix MdXY = MdXY_dUV.times(MdpXY_dUV.solve(MdpXY));
                                double[] dXY = MdXY.getRowPackedCopy();
                                gridCorr2d[imgNum][0][vu] = dXY[0];
                                gridCorr2d[imgNum][1][vu] = dXY[1];
                                gridCorr2d[imgNum][3][vu] = imgData[4][vu]; // weight
                            }
                        } // end scanning pixels
                        if (showIndividual) {
                            String[] titles = { "diff-X", "diff-Y", "pX", "pY", "alpha", "X-correction(mm)",
                                    "Y-correction(mm)", "Z-correction(mm)" };
                            (new showDoubleFloatArrays()).showArrays(imgData, width, height, true,
                                    "Grid" + imgNum, titles);
                        }
                        final int numFinished = imageFinishedAtomic.getAndIncrement();
                        //                  IJ.showProgress(progressValues[numFinished]);
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                // Here, we can safely update the GUI
                                // because we'll be called from the
                                // event dispatch thread
                                IJ.showProgress(progressValues[numFinished]);
                            }
                        });
                    }
            }
        };
    }
    startAndJoin(threads);

    IJ.showProgress(1.0);
    return gridCorr2d;
}

From source file:Distortions.java

public LMAArrays calculateJacobianArrays(final boolean[] selectedImages, // selected images to process
        final double[] Y, // should be initialized 
        final double[] fX, // should be initialized to correct length, data is not needed
        final double[] vector, // parameters vector
        final int[] imageStartIndex, // index of the first point of each image (including extra element in the end so n+1 is always valid)
        final double[][] patternXYZ, // this.targetXYZ
        final double[] weightFunction, // may be null - make it twice smaller? - same for X and Y?
        final LensDistortionParameters lensDistortionParametersProto,
        //         final double lambda,
        int threadsMax, boolean updateStatus) {

    // calculate JtJ
    //      double [] diff=calcYminusFx(fX);
    //      int numPars=this.jacobian.length; // number of parameters to be adjusted
    final int numPars = vector.length; // number of parameters to be adjusted
    //      int length=diff.length; // should be the same as this.jacobian[0].length 
    //      final int length=fX.length; // should be the same as this.jacobian[0].length 
    final double[][] JtByJmod = new double[numPars][numPars]; //Transposed Jacobian multiplied by Jacobian
    final double[] JtByDiff = new double[numPars];
    for (int i = 0; i < numPars; i++) {
        JtByDiff[i] = 0.0;/*from   w  w  w  .j  a va 2 s.com*/
        for (int j = 0; j < numPars; j++)
            JtByJmod[i][j] = 0.0;
    }
    final int debugLevel = this.debugLevel;
    final Thread[] threads = newThreadArray(threadsMax);
    final AtomicInteger imageNumberAtomic = new AtomicInteger(0);
    final AtomicInteger imageFinishedAtomic = new AtomicInteger(0);
    final double[] progressValues = new double[selectedImages.length];
    int numSelectedImages = 0;
    for (int i = 0; i < selectedImages.length; i++)
        if (selectedImages[i])
            numSelectedImages++;
    int selectedIndex = 0;
    for (int i = 0; i < selectedImages.length; i++) {
        progressValues[i] = (selectedIndex + 1.0) / numSelectedImages;
        if (selectedImages[i])
            selectedIndex++;
        if (selectedIndex >= numSelectedImages)
            selectedIndex--;
    }
    final AtomicInteger stopRequested = this.stopRequested;
    final AtomicBoolean interruptedAtomic = new AtomicBoolean();
    for (int ithread = 0; ithread < threads.length; ithread++) {
        threads[ithread] = new Thread() {
            public void run() {
                LensDistortionParameters lensDistortionParameters = lensDistortionParametersProto.clone(); // see - if that is needed - maybe new is OK
                //                  LensDistortionParameters lensDistortionParameters= new LensDistortionParameters();
                for (int numImage = imageNumberAtomic.getAndIncrement(); (numImage < selectedImages.length)
                        && !interruptedAtomic.get(); numImage = imageNumberAtomic.getAndIncrement()) {
                    double[][] partialJacobian = calculatePartialFxAndJacobian(numImage, // number of grid image
                            vector, // parameters vector
                            patternXYZ, // this.targetXYZ
                            fX, // non-overlapping segments will be filled
                            imageStartIndex, // start index in patternXYZ array (length - difference to the next, includes extra last element)
                            lensDistortionParameters, // initialize one per each tread? Or for each call?
                            true); // when false, modifies only this.lensDistortionParameters.*

                    int length = 2 * (imageStartIndex[numImage + 1] - imageStartIndex[numImage]);
                    int start = 2 * imageStartIndex[numImage];

                    double[][] partialJtByJmod = new double[numPars][numPars]; // out of heap space
                    double[] partialJtByDiff = new double[numPars];

                    for (int i = 0; i < numPars; i++)
                        if (partialJacobian[i] != null) {
                            for (int j = i; j < numPars; j++)
                                if (partialJacobian[j] != null) {
                                    partialJtByJmod[i][j] = 0.0;
                                    if (weightFunction != null) {
                                        for (int k = 0; k < length; k++)
                                            partialJtByJmod[i][j] += partialJacobian[i][k]
                                                    * partialJacobian[j][k] * weightFunction[start + k];
                                    } else {
                                        for (int k = 0; k < length; k++)
                                            partialJtByJmod[i][j] += partialJacobian[i][k]
                                                    * partialJacobian[j][k];
                                    }
                                }
                        }

                    double[] partialDiff = new double[length];
                    for (int k = 0; k < length; k++)
                        partialDiff[k] = Y[start + k] - fX[start + k];

                    for (int i = 0; i < numPars; i++)
                        if (partialJacobian[i] != null) {
                            partialJtByDiff[i] = 0.0;
                            if (weightFunction != null)
                                for (int k = 0; k < length; k++)
                                    partialJtByDiff[i] += partialJacobian[i][k] * partialDiff[k]
                                            * weightFunction[start + k];
                            else
                                for (int k = 0; k < length; k++)
                                    partialJtByDiff[i] += partialJacobian[i][k] * partialDiff[k];

                        }
                    // wrong! fix it
                    /*                     
                                         synchronized(this){
                                            for (int i=0;i<numPars;i++) if (partialJacobian[i]!=null){
                                               JtByDiff[i]+=partialJtByDiff[i];
                                               for (int j=i;j<numPars;j++) JtByJmod[i][j]+=partialJtByJmod[i][j];
                                            }
                                         }
                     */
                    synchronizedCombinePartialJacobians(JtByJmod, //Transposed Jacobian multiplied by Jacobian
                            JtByDiff, partialJacobian, partialJtByDiff, partialJtByJmod, numPars);

                    final int numFinished = imageFinishedAtomic.getAndIncrement();
                    //                     IJ.showProgress(progressValues[numFinished]);
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            // Here, we can safely update the GUI
                            // because we'll be called from the
                            // event dispatch thread
                            IJ.showProgress(progressValues[numFinished]);
                        }
                    });
                    if (stopRequested.get() == 1) { // ASAP
                        interruptedAtomic.set(true);
                    }
                    //                     if (debugLevel>1) System.out.println("IJ.showProgress("+progressValues[numImage]+")");
                    //                     if (debugLevel>1) IJ.showStatus("Progress "+IJ.d2s(100*progressValues[numImage],2)+"%");
                }
            }
        };
    }
    startAndJoin(threads);
    if (interruptedAtomic.get()) {
        System.out.println("calculateJacobianArrays() aborted by user request");
        return null;
    }
    if (debugLevel > 3) {
        String msg = "calculateJacobianArrays() ALL_trace=";
        for (int ii = 0; ii < numPars; ii++)
            msg += IJ.d2s(JtByJmod[ii][ii], 5);
        System.out.println(msg);

    }

    for (int i = 0; i < numPars; i++) { // subtract lambda*diagonal , fill the symmetrical half below the diagonal
        for (int j = 0; j < i; j++)
            JtByJmod[i][j] = JtByJmod[j][i]; // it is symmetrical matrix, just copy
    }
    LMAArrays lMAArrays = new LMAArrays();
    lMAArrays.jTByJ = JtByJmod;
    lMAArrays.jTByDiff = JtByDiff;
    if (debugLevel > 3) {
        String msg = "calculateJacobianArrays() lMAArrays.jTByJ trace=";
        for (int ii = 0; ii < numPars; ii++)
            msg += IJ.d2s(lMAArrays.jTByJ[ii][ii], 5);
        System.out.println(msg);

    }
    return lMAArrays;
}

From source file:Distortions.java

public void allSensorsExtrapolationMapped(final int stationNumber, // has to be selected
        final double[][][] gridPCorr, final double shrinkBlurComboSigma, final double shrinkBlurComboLevel,
        final double alphaThreshold, final double step, final double interpolationSigma,
        final double tangentialRadius, final int scanDistance, final int resultDistance,
        final int interpolationDegree, final int threadsMax, final boolean updateStatus,
        final boolean showDebugImages, final int debugLevel) {
    if (updateStatus)
        IJ.showStatus("Extrapolating sensor corrections...");
    final AtomicInteger sensorNumberAtomic = new AtomicInteger(0);
    final AtomicInteger sensorFinishedAtomic = new AtomicInteger(0);
    final Thread[] threads = newThreadArray(threadsMax);
    final AtomicInteger stopRequested = this.stopRequested;
    final AtomicBoolean interruptedAtomic = new AtomicBoolean();
    final EyesisSubCameraParameters[] eyesisSubCameras = this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.eyesisSubCameras[stationNumber];
    final double[][] sensorMasks = this.fittingStrategy.distortionCalibrationData.sensorMasks;

    final int alphaIndex = 2;

    final int sensorWidth = fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth;
    final int sensorHeight = fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight;
    final int decimation = fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
    final int width = (sensorWidth - 1) / decimation + 1; // decimated width (648)
    final int height = (sensorHeight - 1) / decimation + 1; // decimated width (648)
    final boolean extraShowDebug = showDebugImages && (debugLevel > 2);

    for (int ithread = 0; ithread < threads.length; ithread++) {
        threads[ithread] = new Thread() {
            public void run() {
                DoubleGaussianBlur gb = null;
                double[][] debugMasks1 = null;
                double[][] debugMasks2 = null;
                String[] debugMaskTitles = { "original", "blured" };
                if (extraShowDebug) {
                    debugMasks1 = new double[2][];
                    debugMasks2 = new double[2][];
                }//w ww.  ja  v a  2 s.c  o m
                if (shrinkBlurComboSigma > 0.0)
                    gb = new DoubleGaussianBlur();
                for (int sensorNum = sensorNumberAtomic.getAndIncrement(); (sensorNum < gridPCorr.length)
                        && !interruptedAtomic.get(); sensorNum = sensorNumberAtomic.getAndIncrement()) {
                    if (gridPCorr[sensorNum] != null) {
                        final double[] centerPXY = { eyesisSubCameras[sensorNum].px0,
                                eyesisSubCameras[sensorNum].py0 };
                        if (shrinkBlurComboSigma > 0.0) {
                            double sigma = shrinkBlurComboSigma / decimation;
                            int margin = (int) (2 * sigma);
                            int width1 = width + 2 * margin;
                            int height1 = height + 2 * margin;
                            if (extraShowDebug)
                                debugMasks2[0] = gridPCorr[sensorNum][alphaIndex].clone();
                            double[] mask = addMarginsThreshold(gridPCorr[sensorNum][alphaIndex], // double [] data,
                                    0.0, // double threshold,
                                    width, height, margin);
                            if (extraShowDebug)
                                debugMasks1[0] = mask.clone();
                            gb.blurDouble(mask, width1, height1, sigma, sigma, 0.01);

                            double k = 1.0 / (1.0 - shrinkBlurComboLevel);
                            for (int i = 0; i < mask.length; i++) {
                                mask[i] = k * (mask[i] - shrinkBlurComboLevel);
                                mask[i] = (mask[i] > 0.0) ? (mask[i] * mask[i]) : 0.0;
                            }
                            if (extraShowDebug)
                                debugMasks1[1] = mask.clone();
                            gridPCorr[sensorNum][alphaIndex] = removeMargins(mask, //double [] data,
                                    width, // w/o margins
                                    height, margin); //mask; // replace with 0.0 .. 1.0 mask
                            if (extraShowDebug)
                                debugMasks2[1] = gridPCorr[sensorNum][alphaIndex].clone();
                            if (extraShowDebug) {
                                (new showDoubleFloatArrays()).showArrays(debugMasks1, width1, height1, true,
                                        "M1-" + sensorNum, debugMaskTitles);
                                (new showDoubleFloatArrays()).showArrays(debugMasks2, width, height, true,
                                        "M2-" + sensorNum, debugMaskTitles);
                            }

                        }
                        singleSensorExtrapolationMapped(sensorNum, gridPCorr[sensorNum], sensorMasks[sensorNum],
                                width, decimation, alphaThreshold, step, centerPXY, interpolationSigma,
                                tangentialRadius, scanDistance, resultDistance, interpolationDegree,
                                (shrinkBlurComboSigma > 0.0), showDebugImages, debugLevel);
                        final int numFinished = sensorFinishedAtomic.getAndIncrement();
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                if (updateStatus)
                                    IJ.showProgress(numFinished, gridPCorr.length);
                            }
                        });
                        if (stopRequested.get() == 1) { // ASAP
                            interruptedAtomic.set(true);
                        }
                    } //if (selectedImages[numImage]){
                } // for (int numImage=imageNumberAtomic.getAndIncrement(); ...
            } // public void run() {
        };
    }
    startAndJoin(threads);
    if (updateStatus)
        IJ.showProgress(0);
    return;
}