use of mpicbg.imglib.container.cell.Cell in project TrakEM2 by trakem2.
the class Compare method condense.
/**
* Do an all-to-all distance matrix of the given vs, then do a neighbor joining, do a weighted merge of the two VectorString3D being merged, and then finally output the resulting condensed unique VectorString3D with its source array full with all points that make each point in it. Expects VectorString3D which are already calibrated and transformed.
*/
public static VectorString3D condense(final CATAParameters cp, final VectorString3D[] vs, final Worker worker) throws Exception {
// Trivial case 1:
if (1 == vs.length)
return vs[0];
// Estimate delta
if (0 == cp.delta) {
for (int i = 0; i < vs.length; i++) {
cp.delta += vs[i].getAverageDelta();
}
cp.delta /= vs.length;
}
// Resample all:
for (int i = 0; i < vs.length; i++) vs[i].resample(cp.delta, true);
// Trivial case 2:
try {
if (2 == vs.length)
VectorString3D.createInterpolatedPoints(new Editions(vs[0], vs[1], cp.delta, false), 0.5f);
} catch (final Exception e) {
IJError.print(e);
return null;
}
// Else, do neighbor joining
final float[][] scores = Compare.scoreAllToAll(vs, cp.distance_type, cp.delta, cp.skip_ends, cp.max_mut, cp.min_chunk, cp.direct, cp.substring_matching, worker);
final HashMap<Compare.Cell<VectorString3D>, Float> table = new HashMap<Compare.Cell<VectorString3D>, Float>();
// Input the half matrix only into the table, since it's mirrored. And without the diagonal of zeros:
for (int i = 1; i < scores.length; i++) {
for (int j = 0; j < i; j++) {
table.put(new Cell<VectorString3D>(vs[i], vs[j]), scores[i][j]);
}
}
final HashSet<VectorString3D> remaining = new HashSet<VectorString3D>();
for (final VectorString3D v : vs) remaining.add(v);
while (table.size() > 0) {
if (null != worker && worker.hasQuitted()) {
return null;
}
// find smallest value
float min = Float.MAX_VALUE;
Cell<VectorString3D> cell = null;
for (final Map.Entry<Cell<VectorString3D>, Float> e : table.entrySet()) {
final float f = e.getValue();
if (f < min) {
min = f;
cell = e.getKey();
}
}
// done below//table.remove(cell);
for (final Iterator<Cell<VectorString3D>> it = table.keySet().iterator(); it.hasNext(); ) {
final Cell<VectorString3D> c = it.next();
if (c.t1 == cell.t1 || c.t2 == cell.t2 || c.t2 == cell.t1 || c.t1 == cell.t2) {
it.remove();
}
}
// pop the two merged VectorString3D
remaining.remove(cell.t1);
remaining.remove(cell.t2);
// merge, weighted by number of sources of each
// in createInterpolated, the alpha is the opposite of what one would think: a 0.2 alpha means 0.8 for the first and 0.2 for the second. So alpha should be 1-alpha
final double alpha = (double) (cell.t1.getNSources()) / (double) (cell.t1.getNSources() + cell.t2.getNSources());
final Editions eds = new Editions(cell.t1, cell.t2, cp.delta, false);
VectorString3D vs_merged = null;
if (cp.cut_uneven_ends) {
// crop ends to eliminate strings of insertions or deletions sparsed by strings of max cp.max_mut mutations inside
// (This reduces or eliminates variability noise caused by unequal sequence length)
final int[][] editions = eds.getEditions();
int first = 0;
int last = editions.length - 1;
int n_mut = 0;
for (int i = 0; i < last; i++) {
if (Editions.MUTATION == editions[i][0]) {
n_mut++;
if (n_mut > cp.max_mut) {
first = i - n_mut + 1;
break;
}
}
}
// reset
n_mut = 0;
for (int i = last; i > first; i--) {
if (Editions.MUTATION == editions[i][0]) {
n_mut++;
if (n_mut > cp.max_mut) {
last = i + n_mut - 1;
break;
}
}
}
vs_merged = VectorString3D.createInterpolatedPoints(eds, alpha, first, last);
} else {
vs_merged = VectorString3D.createInterpolatedPoints(eds, alpha);
}
vs_merged.resample(cp.delta, true);
// add a new cell for each possible comparison with all other unique vs
for (final VectorString3D v : remaining) {
final Object[] ob = findBestMatch(vs_merged, v, cp.delta, cp.skip_ends, cp.max_mut, cp.min_chunk, cp.distance_type, cp.direct, cp.substring_matching);
final Editions ed = (Editions) ob[0];
final float score = (float) getScore(ed, cp.skip_ends, cp.max_mut, cp.min_chunk, cp.distance_type);
table.put(new Cell<VectorString3D>(vs_merged, v), score);
}
// add the new VectorString3D
remaining.add(vs_merged);
}
// test:
if (1 != remaining.size()) {
Utils.log2("WARNING: remaining.size() == " + remaining.size());
}
return remaining.iterator().next();
}