Search in sources :

Example 1 with Cell

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();
}
Also used : HashMap(java.util.HashMap) Editions(ini.trakem2.vector.Editions) VectorString3D(ini.trakem2.vector.VectorString3D) Cell(mpicbg.imglib.container.cell.Cell) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) HashSet(java.util.HashSet)

Aggregations

Editions (ini.trakem2.vector.Editions)1 VectorString3D (ini.trakem2.vector.VectorString3D)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 TreeMap (java.util.TreeMap)1 Cell (mpicbg.imglib.container.cell.Cell)1