Skip to content
Snippets Groups Projects
Commit 44cdb8a1 authored by buczekp's avatar buczekp
Browse files

[SE-156] improved output, added accuracy tester

SVN: 13023
parent dc56cf50
No related branches found
No related tags found
No related merge requests found
27 f:2 p:20
28 f:3 p:5
29 f:4 p:10
30 f:5 p:1
31 f:5 p:12
32 f:5 p:16
36 f:14 p:0
39 f:16 p:7
40 f:18 p:34
41 f:18 p:21
46 f:21 p:3
48 f:24 p:47
49 f:28 p:20
51 f:32 p:24
52 f:35 p:13
54 f:36 p:48
55 f:37 p:25
58 f:38 p:48
56 f:38 p:7
61 f:40 p:45
60 f:40 p:5
65 f:47 p:14
68 f:51 p:47
70 f:53 p:46
71 f:56 p:20
77 f:59 p:24
78 f:61 p:12
79 f:62 p:25
81 f:64 p:56
84 f:68 p:5
85 f:69 p:49
89 f:75 p:20
93 f:79 p:76
96 f:82 p:92
98 f:84 p:3
101 f:86 p:15
103 f:87 p:78
102 f:87 p:7
106 f:90 p:70
118 f:105 p:24
123 f:110 p:5
124 f:112 p:102
125 f:114 p:92
128 f:118 p:23
129 f:118 p:25
131 f:119 p:44
132 f:120 p:31
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
+16 857 (check excentricity) +16 857 (check excentricity)
12 932 12 932
33 f:6 p:16 c(3): FAKE:33 f:6 p:16 c(3):
++16 389 +16 389 (wrong id - 32)
14 1405 14 1405
12 1780 12 1780
...@@ -185,7 +185,7 @@ FAKE:69 f:52 p:17 c(8): ...@@ -185,7 +185,7 @@ FAKE:69 f:52 p:17 c(8):
49 1640 (far) 49 1640 (far)
19 4049 19 4049
FAKE POS:72 f:57 p:49 c(1): FAKE:72 f:57 p:49 c(1):
49 685 (small appears close) 49 685 (small appears close)
FAKE:75 f:58 p:74 c(4): FAKE:75 f:58 p:74 c(4):
......
27 f:2 p:20 c(1): 27 f:2 p:20 c(1):
28 f:3 p:5 c(1): 28 f:3 p:5 c(1):
31 f:5 p:12 c(3): 31 f:5 p:12 c(3):
33 f:6 p:16 c(3):
46 f:21 p:3 c(1): 46 f:21 p:3 c(1):
56 f:38 p:7 c(1): 56 f:38 p:7 c(1):
84 f:68 p:5 c(1): 84 f:68 p:5 c(1):
101 f:86 p:15 c(1): 101 f:86 p:15 c(1):
123 f:110 p:5 c(1): 123 f:110 p:5 c(1):
9 out of 81 = 11% 8 out of 81 = 10%
9 out of 47 = 19% (ignoring FAKE) 8 out of 46 = 17% (ignoring FAKE)
\ No newline at end of file \ No newline at end of file
FAKE:33 f:6 p:16 c(3):
FAKE:44 f:19 p:17 c(5): FAKE:44 f:19 p:17 c(5):
FAKE:45 f:19 p:17 c(6): FAKE:45 f:19 p:17 c(6):
FAKE:58 f:38 p:48 c(9): FAKE:58 f:38 p:48 c(9):
...@@ -33,5 +34,5 @@ FAKE:130 f:118 p:104 c(7): ...@@ -33,5 +34,5 @@ FAKE:130 f:118 p:104 c(7):
FAKE:127 f:118 p:83 c(6): FAKE:127 f:118 p:83 c(6):
FAKE:133 f:120 p:82 c(5): FAKE:133 f:120 p:82 c(5):
34 out of 81 = 42% 35 out of 81 = 43%
rest = 81-34 = 47 rest = 81-35 = 46
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
132 f:120 p:31 c(5):+31 1261,12 1413,82 1444, 132 f:120 p:31 c(5):+31 1261,12 1413,82 1444,
13 out of 81 = 16% 13 out of 81 = 16%
13 out of 47 = 27.5% (ignoring FAKE) 13 out of 46 = 28% (ignoring FAKE)
overall good answers (with certain) overall good answers (with certain)
22 out of 81 = 27% 21 out of 81 = 26%
22 out of 47 = 47% (ignoring FAKE) 21 out of 46 = 45% (ignoring FAKE)
\ No newline at end of file \ No newline at end of file
...@@ -26,4 +26,4 @@ MISSING 57!!! ...@@ -26,4 +26,4 @@ MISSING 57!!!
!(long)131 f:119 p:40 c(4):-40 778,+44 1385,-14 2178 !(long)131 f:119 p:40 c(4):-40 778,+44 1385,-14 2178
26 out of 81 = 32% 26 out of 81 = 32%
26 out of 47 = 55% (ignoring FAKE) 26 out of 46 = 56% (ignoring FAKE)
...@@ -43,8 +43,14 @@ public class GenerationDetection ...@@ -43,8 +43,14 @@ public class GenerationDetection
private static final String OUTPUT_FILE = "resource/examples/output/pos2"; private static final String OUTPUT_FILE = "resource/examples/output/pos2";
private static final boolean DEBUG = true;
private static final int FIRST_FRAME_NUM = 0; private static final int FIRST_FRAME_NUM = 0;
private static final int INITIAL_GENERATION = 1;
private static final int FAKE_CELL_GENERATION = 0;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private static final String PARENT_ID_COL_NAME = "parentID"; private static final String PARENT_ID_COL_NAME = "parentID";
...@@ -98,8 +104,10 @@ public class GenerationDetection ...@@ -98,8 +104,10 @@ public class GenerationDetection
// no need to use distance values and getting sqrt from values is an additional operation // no need to use distance values and getting sqrt from values is an additional operation
private static int maxAxisSq; // (ceiling of) square of maximal major axis found in input data private static int maxAxisSq; // (ceiling of) square of maximal major axis found in input data
private static int maxFrame; // maximal frame number (easy to read from file)
/** information about a cell in given */ /** information about a cell in given */
private static class Cell static class Cell
{ {
/** cell identification number */ /** cell identification number */
private final int id; // cellID private final int id; // cellID
...@@ -146,12 +154,7 @@ public class GenerationDetection ...@@ -146,12 +154,7 @@ public class GenerationDetection
// new data to output // new data to output
private int parentCellId = -1; // present from the beginning private int generation = INITIAL_GENERATION; // number of children produced +1
private int generation = 1; // number of children produced +1
// ids of all candidates for parent
private ParentCandidate[] parentCandidates = new ParentCandidate[0];
public Cell(final String inputRow) public Cell(final String inputRow)
{ {
...@@ -175,19 +178,21 @@ public class GenerationDetection ...@@ -175,19 +178,21 @@ public class GenerationDetection
this.sphereVol = Double.parseDouble(StringUtils.trim(tokens[SPHERE_VOL_POSITION])); this.sphereVol = Double.parseDouble(StringUtils.trim(tokens[SPHERE_VOL_POSITION]));
} }
public int getParentCellId() private ParentCandidate[] getParentCandidates()
{ {
return parentCellId; return parentCandidatesByChildId.get(id); // not null - initialized at startup
} }
public void setParentCellId(int parentCellId) public int getParentCellId()
{
this.parentCellId = parentCellId;
}
public void setParentCandidates(ParentCandidate parentCandidates[])
{ {
this.parentCandidates = parentCandidates; final ParentCandidate[] candidates = getParentCandidates();
if (candidates.length == 0)
{
return -1;
} else
{
return candidates[0].parent.id;
}
} }
public int getGeneration() public int getGeneration()
...@@ -272,7 +277,7 @@ public class GenerationDetection ...@@ -272,7 +277,7 @@ public class GenerationDetection
private int getAlternatives() private int getAlternatives()
{ {
return parentCandidates.length - 1; return getParentCandidates().length - 1;
} }
@Override @Override
...@@ -284,12 +289,13 @@ public class GenerationDetection ...@@ -284,12 +289,13 @@ public class GenerationDetection
public String parentInformation() public String parentInformation()
{ {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
for (ParentCandidate candidate : parentCandidates) final ParentCandidate[] candidates = getParentCandidates();
for (ParentCandidate candidate : candidates)
{ {
sb.append(candidate.parent.id + "\t" + candidate.distanceSq); sb.append(candidate.parent.id + "\t" + candidate.distanceSq + ",");
} }
return String.format("%d \t f:%d \t p:%d \t c(%d):%s", id, frame + 1, parentCellId, return String.format("%d \t f:%d \t p:%d \t c(%d):%s", id, frame + 1,
parentCandidates.length, sb.toString()); getParentCellId(), candidates.length, sb.toString());
} }
public String longToString() public String longToString()
...@@ -302,7 +308,7 @@ public class GenerationDetection ...@@ -302,7 +308,7 @@ public class GenerationDetection
Double.toString(fTot), Double.toString(aTot), Double.toString(fTot), Double.toString(aTot),
Double.toString(rotVol), Double.toString(conVol), Double.toString(rotVol), Double.toString(conVol),
Double.toString(aSurf), Double.toString(sphereVol), Double.toString(aSurf), Double.toString(sphereVol),
Integer.toString(parentCellId), Integer.toString(getParentCellId()),
Integer.toString(getAlternatives()), Integer.toString(generation) }; Integer.toString(getAlternatives()), Integer.toString(generation) };
return StringUtils.join(tokens, SEPARATOR); return StringUtils.join(tokens, SEPARATOR);
} }
...@@ -400,8 +406,9 @@ public class GenerationDetection ...@@ -400,8 +406,9 @@ public class GenerationDetection
} }
// // <id, <frame, cell>> // <id, <frame, cell>>
// private static Map<Integer, Map<Integer, Cell>> cellsByIdAndFrame; private static Map<Integer, Map<Integer, Cell>> cellsByIdAndFrame;
// //
// // <frame, <id, cell>> // // <frame, <id, cell>>
// private static Map<Integer, Map<Integer, Cell>> cellsByFrameAndId; // private static Map<Integer, Map<Integer, Cell>> cellsByFrameAndId;
...@@ -409,6 +416,9 @@ public class GenerationDetection ...@@ -409,6 +416,9 @@ public class GenerationDetection
// <frame, cells> // <frame, cells>
private static Map<Integer, Set<Cell>> cellsByFrame; private static Map<Integer, Set<Cell>> cellsByFrame;
// <child id, parent candidates sorted in order (first cell is most likely a parent)>
private static Map<Integer, ParentCandidate[]> parentCandidatesByChildId;
public static void main(String[] args) public static void main(String[] args)
{ {
final long start = System.currentTimeMillis(); final long start = System.currentTimeMillis();
...@@ -473,27 +483,39 @@ public class GenerationDetection ...@@ -473,27 +483,39 @@ public class GenerationDetection
} }
System.err.println((System.currentTimeMillis() - start) / 1000.0); System.err.println((System.currentTimeMillis() - start) / 1000.0);
for (String cellInfo : newBornCellsInfo)
if (DEBUG)
{ {
System.out.println(cellInfo); for (Cell cell : newBornCells)
{
System.out.println(cell.parentInformation());
}
GenerationDetectionAccuracyTester.computeResultsAccuracy(newBornCells);
} }
} }
private static void createDataStructures(List<Cell> cells) private static void createDataStructures(List<Cell> cells)
{ {
// cellsByIdAndFrame = new LinkedHashMap<Integer, Map<Integer, Cell>>();
// common empty array to avoid null checks
final ParentCandidate[] initialCandidates = new ParentCandidate[0];
cellsByIdAndFrame = new LinkedHashMap<Integer, Map<Integer, Cell>>();
// cellsByFrameAndId = new LinkedHashMap<Integer, Map<Integer, Cell>>(); // cellsByFrameAndId = new LinkedHashMap<Integer, Map<Integer, Cell>>();
cellsByFrame = new LinkedHashMap<Integer, Set<Cell>>(); cellsByFrame = new LinkedHashMap<Integer, Set<Cell>>();
parentCandidatesByChildId = new LinkedHashMap<Integer, ParentCandidate[]>();
double maxAxis = 0; double maxAxis = 0;
maxFrame = -1;
for (Cell cell : cells) for (Cell cell : cells)
{ {
// // cellsByIdAndFrame // cellsByIdAndFrame
// Map<Integer, Cell> byFrame = cellsByIdAndFrame.get(cell.getId()); Map<Integer, Cell> byFrame = cellsByIdAndFrame.get(cell.getId());
// if (byFrame == null) if (byFrame == null)
// { {
// byFrame = new HashMap<Integer, Cell>(); // increasing order of frames (not needed)
// } byFrame = new LinkedHashMap<Integer, Cell>();
// byFrame.put(cell.getFrame(), cell); cellsByIdAndFrame.put(cell.getId(), byFrame);
}
byFrame.put(cell.getFrame(), cell);
// // cellsByFrameAndId // // cellsByFrameAndId
// Map<Integer, Cell> byId = cellsByFrameAndId.get(cell.getFrame()); // Map<Integer, Cell> byId = cellsByFrameAndId.get(cell.getFrame());
// if (byId == null) // if (byId == null)
...@@ -509,11 +531,17 @@ public class GenerationDetection ...@@ -509,11 +531,17 @@ public class GenerationDetection
cellsByFrame.put(cell.getFrame(), frameCells); cellsByFrame.put(cell.getFrame(), frameCells);
} }
frameCells.add(cell); frameCells.add(cell);
// initialize candidates
parentCandidatesByChildId.put(cell.getId(), initialCandidates);
// //
if (cell.getMajAxis() > maxAxis) if (cell.getMajAxis() > maxAxis)
{ {
maxAxis = cell.getMajAxis(); maxAxis = cell.getMajAxis();
} }
if (cell.getFrame() > maxFrame)
{
maxFrame = cell.getFrame();
}
} }
maxAxisSq = (int) Math.ceil(maxAxis * maxAxis); maxAxisSq = (int) Math.ceil(maxAxis * maxAxis);
} }
...@@ -539,7 +567,7 @@ public class GenerationDetection ...@@ -539,7 +567,7 @@ public class GenerationDetection
} }
} }
private static List<String> newBornCellsInfo = new ArrayList<String>(); private static List<Cell> newBornCells = new ArrayList<Cell>();
private static void analyzeNewFrameCells(int frame, Set<Cell> newCells) throws Exception private static void analyzeNewFrameCells(int frame, Set<Cell> newCells) throws Exception
{ {
...@@ -552,6 +580,7 @@ public class GenerationDetection ...@@ -552,6 +580,7 @@ public class GenerationDetection
{ {
if (isValidNewBornCell(cell) == false) // ignore cells that are not new born if (isValidNewBornCell(cell) == false) // ignore cells that are not new born
{ {
cell.generation = FAKE_CELL_GENERATION;
continue; continue;
} }
// could take previousFrameCells from previous step // could take previousFrameCells from previous step
...@@ -563,8 +592,6 @@ public class GenerationDetection ...@@ -563,8 +592,6 @@ public class GenerationDetection
// } // }
final List<ParentCandidate> parentCandidates = new ArrayList<ParentCandidate>(4); final List<ParentCandidate> parentCandidates = new ArrayList<ParentCandidate>(4);
// final List<Cell> possibleParents = new ArrayList<Cell>();
// final List<Integer> possibleParentDistances = new ArrayList<Integer>();
for (Cell previousFrameCell : previousFrameCells) for (Cell previousFrameCell : previousFrameCells)
{ {
final ParentCandidate candidate = new ParentCandidate(previousFrameCell, cell); final ParentCandidate candidate = new ParentCandidate(previousFrameCell, cell);
...@@ -574,14 +601,17 @@ public class GenerationDetection ...@@ -574,14 +601,17 @@ public class GenerationDetection
// Parent cells have to be bigger than new born cells. // Parent cells have to be bigger than new born cells.
if (candidate.isDistanceValid()) // simplify if (candidate.isDistanceValid()) // simplify
{ {
// System.err.println(candidate.parent.id + " distance is OK");
if (candidate.isNumPixValid()) // could be tested before candidate is created if (candidate.isNumPixValid()) // could be tested before candidate is created
{ {
// System.err.println(candidate.parent.id + " size is OK");
parentCandidates.add(candidate); parentCandidates.add(candidate);
} else } else
{ {
System.err.println(candidate.parent.id + " is too small"); System.err
.println(String
.format(
"Cell %d is to small (%d) to be a parent of %d that appeared on frame %d.",
candidate.parent.id, +candidate.parent.numPix,
cell.id, candidate.distanceSq, frame));
} }
} }
} }
...@@ -595,21 +625,35 @@ public class GenerationDetection ...@@ -595,21 +625,35 @@ public class GenerationDetection
// sort parent - best will be first // sort parent - best will be first
Collections.sort(parentCandidates); Collections.sort(parentCandidates);
setParents(cell, parentCandidates.toArray(new ParentCandidate[0])); setParents(cell, parentCandidates.toArray(new ParentCandidate[0]));
newBornCellsInfo.add(cell.toString()); newBornCells.add(cell);
} }
} }
} }
private static void setParents(Cell cell, ParentCandidate... candidates) private static void setParents(Cell child, ParentCandidate... candidates)
{ {
assert candidates.length != 0; assert candidates.length != 0;
final Cell parent = candidates[0].parent; final Cell parent = candidates[0].parent;
// TODO 2009-10-20, Piotr Buczek: keep parents and generation separate from cells parentCandidatesByChildId.put(child.id, candidates);
cell.setParentCellId(parent.getId()); increaseGeneration(parent.getId(), parent.getFrame()); // change to child.getFrame()?
parent.increaseGeneration(); }
cell.setParentCandidates(candidates);
/**
* Increases generations of all cells with specified <var>id</var> and frame number at least
* equal to <var>startFrame</var>.
*/
private static void increaseGeneration(int cellID, int startFrame)
{
for (Entry<Integer, Cell> byFrame : cellsByIdAndFrame.get(cellID).entrySet())
{
final Integer frame = byFrame.getKey();
final Cell cell = byFrame.getValue();
if (frame >= startFrame)
{
cell.increaseGeneration();
}
}
} }
private static boolean isValidNewBornCell(Cell cell) private static boolean isValidNewBornCell(Cell cell)
......
/*
* Copyright 2009 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.ethz.bsse.cisd.yeastlab;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import ch.ethz.bsse.cisd.yeastlab.GenerationDetection.Cell;
/**
* @author Piotr Buczek
*/
public class GenerationDetectionAccuracyTester
{
// the right connections for data in pos2 file: <child id, parent id>
private final static Map<Integer, Integer> parents = new HashMap<Integer, Integer>();
static
{
parents.put(27, 20);
parents.put(28, 5);
parents.put(29, 10);
parents.put(30, 1);
parents.put(31, 12);
parents.put(32, 16);
parents.put(36, 0);
parents.put(39, 7);
parents.put(40, 34);
parents.put(41, 21);
parents.put(46, 3);
parents.put(48, 47);
parents.put(49, 20);
parents.put(51, 24);
parents.put(52, 13);
parents.put(54, 48);
parents.put(55, 25);
parents.put(58, 48);
parents.put(56, 7);
parents.put(61, 45);
parents.put(60, 5);
parents.put(65, 14);
parents.put(68, 47);
parents.put(70, 46);
parents.put(71, 20);
parents.put(77, 24);
parents.put(78, 12);
parents.put(79, 25);
parents.put(81, 56);
parents.put(84, 5);
parents.put(85, 49);
parents.put(89, 20);
parents.put(93, 76);
parents.put(96, 92);
parents.put(98, 3);
parents.put(101, 15);
parents.put(103, 78);
parents.put(102, 7);
parents.put(106, 70);
parents.put(118, 24);
parents.put(123, 5);
parents.put(124, 102);
parents.put(125, 92);
parents.put(128, 23);
parents.put(129, 25);
parents.put(131, 44);
parents.put(132, 31);
}
public static void computeResultsAccuracy(List<Cell> results)
{
int rightResults = 0;
int wrongResults = 0;
int fakeResults = 0;
int missingResults = 0;
Set<Integer> missingChildrenIds = parents.keySet();
for (Cell result : results)
{
Integer resultParentId = result.getParentCellId();
Integer rightParentId = parents.get(result.getId());
if (rightParentId == null)
{
fakeResults++;
} else
{
if (resultParentId.equals(rightParentId))
{
rightResults++;
} else
{
wrongResults++;
}
}
missingChildrenIds.remove(result.getId());
}
missingResults = missingChildrenIds.size();
final int resultsSize = results.size();
final int withoutFakeSize = resultsSize - fakeResults;
System.out.println("\nAccuracy results:\n");
System.out.println(percentageMessage("right", "", rightResults, resultsSize));
System.out.println(percentageMessage("right", "(no fake)", rightResults, withoutFakeSize));
System.out.println(percentageMessage("wrong", "", wrongResults, resultsSize));
System.out.println(percentageMessage("wrong", "(no fake)", wrongResults, withoutFakeSize));
System.out.println(percentageMessage("fake", "", fakeResults, resultsSize));
System.out.println(percentageMessage("miss", "", missingResults, resultsSize));
}
private static String percentageMessage(String prefix, String suffix, int numerator,
int denominator)
{
final StringBuilder sb = new StringBuilder();
sb.append(prefix + ":\t");
sb.append(numerator + "/" + denominator);
sb.append(" = " + (numerator * 100) / denominator + "%");
sb.append("\t" + suffix);
return sb.toString();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment