Commit 0a1cc28c authored by gonciarz's avatar gonciarz

Merge branch 'roiInputInIA' into develop

parents 142d3c35 ed95294f
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="MosaicSuite" />
</profile>
</annotationProcessing>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$" charset="UTF-8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
package mosaic.ia;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
......@@ -8,14 +9,11 @@ import org.apache.log4j.Logger;
import org.scijava.vecmath.Point3d;
import fr.inria.optimization.cmaes.CMAEvolutionStrategy;
import ij.IJ;
import ij.ImagePlus;
import mosaic.ia.HypothesisTesting.TestResult;
import mosaic.ia.Potentials.Potential;
import mosaic.ia.Potentials.PotentialType;
import mosaic.ia.gui.DistributionsPlot;
import mosaic.ia.gui.EstimatedPotentialPlot;
import mosaic.ia.gui.PlotHistogram;
import mosaic.ia.gui.Utils;
import mosaic.utils.Debug;
import mosaic.utils.math.StatisticsUtils;
import mosaic.utils.math.StatisticsUtils.MinMaxMean;
......@@ -25,12 +23,17 @@ public class Analysis {
private Potential iPotential;
private DistanceCalculations iDistanceCalculations;
private double[] iContextQdDistancesGrid;
private double[] iContextQdPdf;
private double[] iNearestNeighborDistancesXtoY;
private double[] iNearestNeighborDistancesXtoYPdf;
private double[] iObservedModelFitPdPdf;
private List<CmaResult> iCmaResults;
private double[][] iBestPointsFound;
private double[] iBestFunctionValue;
private int iBestPointIndex = -1;
public void calcDist(double gridSize, double kernelWeightq, double kernelWeightp, float[][][] genMask, ImagePlus iImageX, ImagePlus iImageY) {
......@@ -51,12 +54,6 @@ public class Analysis {
StatisticsUtils.normalizePdf(iContextQdPdf, iContextQdDistancesGrid, false);
StatisticsUtils.normalizePdf(iNearestNeighborDistancesXtoYPdf, iContextQdDistancesGrid, false);
new DistributionsPlot(iContextQdDistancesGrid, iContextQdPdf, iNearestNeighborDistancesXtoYPdf).show();
PlotHistogram.plot("ObservedDistances", iNearestNeighborDistancesXtoY, getOptimBins(iNearestNeighborDistancesXtoY, 8, iNearestNeighborDistancesXtoY.length / 8));
double suggestedKernel = calcWekaWeights(iNearestNeighborDistancesXtoY);
IJ.showMessage("Suggested Kernel wt(p): " + suggestedKernel);
logger.debug("Suggested kernel wt(p)=" + suggestedKernel);
}
public static class CmaResult {
......@@ -76,10 +73,11 @@ public class Analysis {
}
}
public void cmaOptimization(List<CmaResult> aResultsOutput, int cmaReRunTimes, boolean aRepetitiveResults) {
public void cmaOptimization(int cmaReRunTimes, boolean aRepetitiveResults) {
final FitFunction fitfun = new FitFunction(iContextQdPdf, iContextQdDistancesGrid, iNearestNeighborDistancesXtoYPdf, iNearestNeighborDistancesXtoY, iPotential);
iBestPointsFound = new double[cmaReRunTimes][iPotential.numOfDimensions()];
double[] bestFunctionValue = new double[cmaReRunTimes];
iBestFunctionValue = new double[cmaReRunTimes];
iCmaResults = new ArrayList<CmaResult>();
double bestFitness = Double.MAX_VALUE;
boolean diffFitness = false;
......@@ -108,29 +106,27 @@ public class Analysis {
cma.setFitnessOfMeanX(fitfun.valueOf(cma.getMeanX()));
logCmaResultInfo(cma);
bestFunctionValue[cmaRunNumber] = cma.getBestFunctionValue();
if (bestFunctionValue[cmaRunNumber] < bestFitness) {
if (cmaRunNumber > 0 && bestFitness - bestFunctionValue[cmaRunNumber] > bestFunctionValue[cmaRunNumber] * 0.00001) {
iBestFunctionValue[cmaRunNumber] = cma.getBestFunctionValue();
if (iBestFunctionValue[cmaRunNumber] < bestFitness) {
if (cmaRunNumber > 0 && bestFitness - iBestFunctionValue[cmaRunNumber] > iBestFunctionValue[cmaRunNumber] * 0.00001) {
diffFitness = true;
}
bestFitness = bestFunctionValue[cmaRunNumber];
bestFitness = iBestFunctionValue[cmaRunNumber];
iBestPointIndex = cmaRunNumber;
}
iBestPointsFound[cmaRunNumber] = cma.getBestX();
addNewOutputResult(aResultsOutput, bestFunctionValue[cmaRunNumber], iBestPointsFound[cmaRunNumber]);
addNewOutputResult(iCmaResults, iBestFunctionValue[cmaRunNumber], iBestPointsFound[cmaRunNumber]);
}
logger.debug("Best Parameters Found:" + Debug.getString(iBestPointsFound[iBestPointIndex]) + " fit function value=" + bestFunctionValue[iBestPointIndex]);
logger.debug("Best Parameters Found:" + Debug.getString(iBestPointsFound[iBestPointIndex]) + " fit function value=" + iBestFunctionValue[iBestPointIndex]);
if (diffFitness) {
IJ.showMessage("Warning: Optimization returned different results for reruns. The results may not be accurate. Displaying the parameters and the plots corr. to best fitness.");
Utils.messageDialog("IA - CMA optimization", "Warning: Optimization returned different results for reruns. The results may not be accurate. Displaying the parameters and the plots corr. to best fitness.");
}
fitfun.l2Norm(iBestPointsFound[iBestPointIndex]); // to calc pgrid for best params
new EstimatedPotentialPlot(iContextQdDistancesGrid, iPotential, iBestPointsFound[iBestPointIndex], bestFunctionValue[iBestPointIndex]).show();
double[] observedModelFitPdPdf = fitfun.getObservedModelFitPdPdf() ;
StatisticsUtils.normalizePdf(observedModelFitPdPdf, iContextQdDistancesGrid, false);
new DistributionsPlot(iContextQdDistancesGrid, observedModelFitPdPdf, iContextQdPdf, iNearestNeighborDistancesXtoYPdf, iPotential, iBestPointsFound[iBestPointIndex], bestFunctionValue[iBestPointIndex]).show();
iObservedModelFitPdPdf = fitfun.getObservedModelFitPdPdf() ;
StatisticsUtils.normalizePdf(iObservedModelFitPdPdf, iContextQdDistancesGrid, false);
}
private void addNewOutputResult(List<CmaResult> aResultsOutput, double aBestFunctionValue, double[] aBestPointFound) {
......@@ -210,11 +206,11 @@ public class Analysis {
public TestResult hypothesisTesting(int monteCarloRunsForTest, double alpha) {
if (iBestPointsFound == null) {
IJ.showMessage("Error: Run estimation first");
Utils.messageDialog("IA - hypothesis testing", "Error: Run estimation first");
return null;
}
else if (iPotential.getType() == PotentialType.NONPARAM) {
IJ.showMessage("Hypothesis test is not applicable for Non Parametric potential \n since it does not have 'strength' parameter");
Utils.messageDialog("IA - hypothesis testing", "Hypothesis test is not applicable for Non Parametric potential \n since it does not have 'strength' parameter");
return null;
}
else {
......@@ -279,11 +275,45 @@ public class Analysis {
return iDistanceCalculations.getMaxXtoYdistance();
}
public double[] getDistances() {
public double[] getContextQdDistancesGrid() {
return iContextQdDistancesGrid;
}
public double[] getContextQdPdf() {
return iContextQdPdf;
}
public double[] getNearestNeighborDistancesXtoY() {
return iNearestNeighborDistancesXtoY;
}
public double[] getNearestNeighborDistancesXtoYPdf() {
return iNearestNeighborDistancesXtoYPdf;
}
public double[] getObservedModelFitPdPdf() {
return iObservedModelFitPdPdf;
}
/**
* @return best point coordinates found by CMA optimization
*/
public double[] getBestPointFound() {
return iBestPointsFound[iBestPointIndex];
}
/**
* @return best function value found by CMA optimization
*/
public double getBestFunctionValue() {
return iBestFunctionValue[iBestPointIndex];
}
public List<CmaResult> getCmaResults() {
return iCmaResults;
}
public void setPotentialType(Potential potentialType) {
this.iPotential = potentialType;
iPotential = potentialType;
}
}
......@@ -6,7 +6,7 @@ import java.util.ArrayList;
import org.apache.log4j.Logger;
import org.scijava.vecmath.Point3d;
import ij.IJ;
import mosaic.ia.gui.Utils;
import mosaic.utils.Debug;
import mosaic.utils.math.NearestNeighborTree;
import mosaic.utils.math.StatisticsUtils;
......@@ -84,7 +84,7 @@ public abstract class DistanceCalculations {
logger.debug("Number of points (X/Y): " + iParticlesX.length + " / " + iParticlesY.length);
logger.debug("min/max of x: " + aMinX + "/" + aMaxX + " y: " + aMinY + "/" + aMaxY + " z: " + aMinZ + "/" + aMaxZ);
if (iParticlesX.length == 0 || iParticlesY.length == 0) {
IJ.showMessage("Number discaverd (and filtered) particles cannot be 0 for further calculations.\nNumber of particles (x/y): " + iParticlesX.length + " " + iParticlesY.length);
Utils.messageDialog("IA - state density", "Number discaverd (and filtered) particles cannot be 0 for further calculations.\nNumber of particles (x/y): " + iParticlesX.length + " " + iParticlesY.length);
throw new RuntimeException("Not enough particles to perform calculations!");
}
......
......@@ -5,14 +5,13 @@ import java.io.File;
import java.util.Vector;
import org.scijava.vecmath.Point3d;
import org.supercsv.cellprocessor.ParseDouble;
import org.supercsv.cellprocessor.ift.CellProcessor;
import ij.IJ;
import ij.ImagePlus;
import ij.io.OpenDialog;
import ij.io.Opener;
import mosaic.ia.gui.Utils;
import mosaic.utils.io.csv.CSV;
import mosaic.utils.io.csv.CsvColumnConfig;
......@@ -75,7 +74,7 @@ public class FileUtils {
file = new File(aFileName);
}
if (!file.exists()) {
IJ.showMessage("There is no file [" + file.getName() + "]");
Utils.messageDialog("IA - open CSV file", "There is no file [" + file.getName() + "]");
return null;
}
......@@ -83,7 +82,7 @@ public class FileUtils {
CSV<Point3dCsvReadWrapper>csv = new CSV<Point3dCsvReadWrapper>(Point3dCsvReadWrapper.class);
int numOfCols = csv.setCSVPreferenceFromFile(file.getAbsolutePath());
if (numOfCols <= 1 || numOfCols > 3) {
IJ.showMessage("CSV file should have 2 or 3 columns of data with comma or semicolon delimieters and no header!");
Utils.messageDialog("IA - open CSV file", "CSV file should have 2 or 3 columns of data with comma or semicolon delimieters and no header!");
return null;
}
CsvColumnConfig ccc = numOfCols == 2
......@@ -91,7 +90,7 @@ public class FileUtils {
: Point3dCsvReadWrapper.getConfig3D();
final Vector<Point3dCsvReadWrapper> outdst = csv.Read(file.getAbsolutePath(), ccc, true);
if (outdst.isEmpty()) {
IJ.showMessage("Incorrect CSV file chosen [" + file.getName() + "]\nCSV file should have 2 or 3 columns of data with comma or semicolon delimieters and no header!\n");
Utils.messageDialog("IA - open CSV file", "Incorrect CSV file chosen [" + file.getName() + "]\nCSV file should have 2 or 3 columns of data with comma or semicolon delimieters and no header!\n");
return null;
}
......
......@@ -6,8 +6,8 @@ import java.util.Random;
import org.apache.log4j.Logger;
import ij.IJ;
import mosaic.ia.Potentials.Potential;
import mosaic.ia.gui.Utils;
class HypothesisTesting {
......@@ -58,7 +58,7 @@ class HypothesisTesting {
}
logger.debug(s);
IJ.showMessage(s);
Utils.messageDialog("IA - hypothesis testing result", s);
return new TestResult (
i,
......
......@@ -2,6 +2,7 @@ package mosaic.ia.gui;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
......@@ -12,13 +13,18 @@ import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
* This class contain GUI creation stuff (probably back in time generated in NetBeans or sth).
......@@ -47,6 +53,11 @@ abstract public class InteractionAnalysisGuiBase implements ActionListener {
protected JButton testHypothesis;
protected JTabbedPane tabbedPane;
private String roiTabTitle = "Load ROI";
JList<String> xRois;
JList<String> yRois;
/**
* Create the application.
*/
......@@ -363,6 +374,56 @@ abstract public class InteractionAnalysisGuiBase implements ActionListener {
);
panelCsvCoordinates.setLayout(glCsvCoordinates);
final JPanel panelRoiCoordinates = new JPanel();
tabbedPane.addTab(roiTabTitle, null, panelRoiCoordinates, null);
xRois = new JList<>();
JScrollPane sp = new JScrollPane(xRois);
xRois.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
xRois.setLayoutOrientation(JList.VERTICAL);
xRois.setVisibleRowCount(4);
yRois = new JList<>();
JScrollPane spY = new JScrollPane(yRois);
yRois.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
yRois.setLayoutOrientation(JList.VERTICAL);
yRois.setVisibleRowCount(4);
GridBagConstraints gbc_fileInitList = new GridBagConstraints();
gbc_fileInitList.fill = GridBagConstraints.BOTH;
gbc_fileInitList.gridx = 0;
gbc_fileInitList.gridy = 1;
JLabel xCol = new JLabel("X");
JLabel yCol = new JLabel("Y ref");
final GroupLayout glRoi = new GroupLayout(panelRoiCoordinates);
glRoi.setHorizontalGroup(glRoi.createSequentialGroup()
.addGap(11)
.addGroup(glRoi.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(xCol)
.addComponent(sp))
.addGap(11)
.addGroup(glRoi.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(yCol)
.addComponent(spY))
.addGap(11));
glRoi.setVerticalGroup(glRoi.createSequentialGroup()
.addGroup(glRoi.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addGap(5).addComponent(xCol).addGap(5).addComponent(yCol).addGap(5))
.addGroup(glRoi.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addGap(5).addComponent(sp).addGap(5).addComponent(spY).addGap(5))
);
panelRoiCoordinates.setLayout(glRoi);
tabbedPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (tabbedPane.getSelectedIndex() == 2) {
roiInitChosen();
}
}
});
final GroupLayout groupLayout = new GroupLayout(frmInteractionAnalysis.getContentPane());
groupLayout.setHorizontalGroup(groupLayout.createParallelGroup(Alignment.LEADING).addGroup(
groupLayout
......@@ -414,4 +475,7 @@ abstract public class InteractionAnalysisGuiBase implements ActionListener {
smoothnessLabel.setEnabled(aShow);
numOfsupportPointsLabel.setEnabled(aShow);
}
abstract void roiInitChosen();
}
package mosaic.ia.gui;
import javax.swing.JOptionPane;
import ij.IJ;
import ij.ImagePlus;
import ij.gui.HistogramWindow;
import ij.process.FloatProcessor;
public class PlotHistogram {
public class Utils {
/**
* Plots histogram for provided values using aNumOfBins
......@@ -15,8 +18,21 @@ public class PlotHistogram {
* @param aNumOfBins
* @return number of elements in each bin
*/
public static HistogramWindow plot(String aTitle, double[] aValues, int aNumOfBins) {
public static HistogramWindow plotHistogram(String aTitle, double[] aValues, int aNumOfBins) {
final FloatProcessor hist = new FloatProcessor(aValues.length, 1, aValues);
System.out.println("HISTOGRAM..");
return new ij.gui.HistogramWindow(aTitle, new ImagePlus(aTitle, hist), aNumOfBins);
}
/**
* Shows message - when IJ instance is found then IJ component is used (which is good since it is IJ window
* and it's managed by IJ), swig component otherwise.
* @param aTitle
* @param aMessage
*/
public static void messageDialog(String aTitle, String aMessage) {
if (IJ.getInstance() != null) IJ.showMessage(aMessage);
else JOptionPane.showMessageDialog(null, aMessage, aTitle, JOptionPane.PLAIN_MESSAGE);
}
}
......@@ -17,8 +17,8 @@ import ij.gui.Roi;
import mosaic.regions.RegionsUtils.EnergyFunctionalType;
import mosaic.regions.RegionsUtils.InitializationType;
import mosaic.regions.RegionsUtils.RegularizationType;
import mosaic.utils.ImgUtils;
import mosaic.regions.DRS.PluginSettingsDRS;
import mosaic.utils.ImgUtils;
/**
* This class creates GUI for DRS.
......
......@@ -42,11 +42,11 @@ import ij.WindowManager;
import ij.gui.GenericDialog;
import ij.gui.NonBlockingGenericDialog;
import ij.gui.Roi;
import mosaic.regions.Settings;
import mosaic.regions.RC.PluginSettingsRC;
import mosaic.regions.RegionsUtils.EnergyFunctionalType;
import mosaic.regions.RegionsUtils.InitializationType;
import mosaic.regions.RegionsUtils.RegularizationType;
import mosaic.regions.Settings;
import mosaic.regions.RC.PluginSettingsRC;
/**
* TODO: ALL this GUI stuff must be rewritten. It is now too patched and over-complicated.
......
......@@ -43,7 +43,7 @@ public class AnalysisTest extends CommonBase {
double epsilon = 1e-10;
assertEquals(0, analysis.getMinDistance(), epsilon);
assertEquals(2, analysis.getMaxDistance(), epsilon);
assertArrayEquals(new double[] {2, 1, 0, 1, 2}, analysis.getDistances(), epsilon);
assertArrayEquals(new double[] {2, 1, 0, 1, 2}, analysis.getNearestNeighborDistancesXtoY(), epsilon);
}
@Test
......@@ -53,10 +53,10 @@ public class AnalysisTest extends CommonBase {
double epsilon = 1e-6;
assertEquals(0.418188, analysis.getMinDistance(), epsilon);
assertEquals(112.924864, analysis.getMaxDistance(), epsilon);
assertEquals(77.722986, Analysis.calcWekaWeights(analysis.getDistances()), epsilon);
assertEquals(77.722986, Analysis.calcWekaWeights(analysis.getNearestNeighborDistancesXtoY()), epsilon);
analysis.setPotentialType(Potentials.createPotential(PotentialType.HERNQUIST));
List<CmaResult> results = new ArrayList<CmaResult>();
analysis.cmaOptimization(results, 1, true);
analysis.cmaOptimization(1, true);
List<CmaResult> results = analysis.getCmaResults();
epsilon = 1e-6;
assertEquals(36.545593028698356, results.get(0).iStrength, epsilon);
......@@ -94,11 +94,11 @@ public class AnalysisTest extends CommonBase {
double epsilon = 1e-6;
assertEquals(0.418188, analysis.getMinDistance(), epsilon);
assertEquals(112.924864, analysis.getMaxDistance(), epsilon);
assertEquals(77.722986, Analysis.calcWekaWeights(analysis.getDistances()), epsilon);
assertEquals(77.722986, Analysis.calcWekaWeights(analysis.getNearestNeighborDistancesXtoY()), epsilon);
analysis.setPotentialType(Potentials.createPotential(PotentialType.NONPARAM, analysis.getMinDistance(), analysis.getMaxDistance(), 41, 0.1));
List<CmaResult> results = new ArrayList<CmaResult>();
analysis.cmaOptimization(results, 1, true);
analysis.cmaOptimization(1, true);
List<CmaResult> results = analysis.getCmaResults();
epsilon = 1e-6;
assertEquals(0.0, results.get(0).iStrength, epsilon);
......@@ -116,11 +116,11 @@ public class AnalysisTest extends CommonBase {
double epsilon = 1e-6;
assertEquals(0.418188, analysis.getMinDistance(), epsilon);
assertEquals(112.924864, analysis.getMaxDistance(), epsilon);
assertEquals(77.722986, Analysis.calcWekaWeights(analysis.getDistances()), epsilon);
assertEquals(77.722986, Analysis.calcWekaWeights(analysis.getNearestNeighborDistancesXtoY()), epsilon);
analysis.setPotentialType(Potentials.createPotential(PotentialType.STEP));
List<CmaResult> results = new ArrayList<CmaResult>();
analysis.cmaOptimization(results, 1, true);
analysis.cmaOptimization(1, true);
List<CmaResult> results = analysis.getCmaResults();
epsilon = 1e-6;
assertEquals(2.4113236274803262, results.get(0).iStrength, epsilon);
......
......@@ -5,14 +5,14 @@ import static org.junit.Assert.assertArrayEquals;
import org.junit.Test;
import ij.gui.HistogramWindow;
import mosaic.ia.gui.PlotHistogram;
import mosaic.ia.gui.Utils;
public class PlotHistogramTest {
@Test
public void testPlotHistogram() {
HistogramWindow hist = PlotHistogram.plot("Hello", /* input values */ new double[] {1, 2, 10, 19}, /* num of bins */ 3);
HistogramWindow hist = Utils.plotHistogram("Hello", /* input values */ new double[] {1, 2, 10, 19}, /* num of bins */ 3);
assertArrayEquals(new int[] {2, 1, 1}, hist.getHistogram());
// Expected ranges are: [1, 7) [7, 13) [13, 19)
assertArrayEquals(new double[] {1, 7, 13}, hist.getXValues(), 0.01);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment