Search in sources :

Example 6 with VectorString3D

use of ini.trakem2.vector.VectorString3D in project TrakEM2 by trakem2.

the class Compare method matchDirect.

private static final Object[] matchDirect(final VectorString3D vs1, final VectorString3D vs2, final double delta, final boolean skip_ends, final int max_mut, final float min_chunk, final int distance_type, final double wi, final double wd, final double wm) {
    // Levenshtein is unfortunately not commutative: must try both
    // (Levenshtein is commutative, but the resampling I'm using makes it not be so)
    final Editions ed1 = new Editions(vs1, vs2, delta, false, wi, wd, wm);
    final double score1 = getScore(ed1, skip_ends, max_mut, min_chunk, distance_type);
    final Editions ed2 = new Editions(vs2, vs1, delta, false, wi, wd, wm);
    final double score2 = getScore(ed2, skip_ends, max_mut, min_chunk, distance_type);
    return score1 < score2 ? new Object[] { ed1, score1 } : new Object[] { ed2, score2 };
}
Also used : Editions(ini.trakem2.vector.Editions)

Example 7 with VectorString3D

use of ini.trakem2.vector.VectorString3D in project TrakEM2 by trakem2.

the class Compare method scoreAllToAll.

/**
 * Returns the half matrix of scores, with values copied from one half matrix to the other, and a diagonal of zeros.
 * @param distance_type ranges from 0 to 5, and includes: 0=Levenshtein, 1=Dissimilarity, 2=Average physical distance, 3=Median physical distance, 4=Cummulative physical distance and 5=Standard deviation.
 */
public static float[][] scoreAllToAll(final VectorString3D[] vs, final int distance_type, final double delta, final boolean skip_ends, final int max_mut, final float min_chunk, final boolean direct, final boolean substring_matching, final Worker worker) {
    final float[][] scores = new float[vs.length][vs.length];
    final AtomicInteger ai = new AtomicInteger(0);
    final Thread[] threads = MultiThreading.newThreads();
    for (int ithread = 0; ithread < threads.length; ithread++) {
        threads[ithread] = new Thread() {

            @Override
            public void run() {
                for (int i = ai.getAndIncrement(); i < vs.length; i = ai.getAndIncrement()) {
                    final VectorString3D vs1 = vs[i];
                    for (int j = i + 1; j < vs.length; j++) {
                        if (null != worker && worker.hasQuitted())
                            return;
                        // TODO should add 'distance_type' as well for the selection of the best match when not direct.
                        final Object[] ob = findBestMatch(vs[i], vs[j], delta, skip_ends, max_mut, min_chunk, distance_type, direct, substring_matching);
                        /*
				switch (distance_type) {
					case 0: // Levenshtein
						scores[i][j] = (float)((Editions)ob[0]).getDistance();
						break;
					case 1: // dissimilarity
						scores[i][j] = (float)((Double)ob[1]).doubleValue();
						break;
					case 2: // average physical distance between mutation pairs
						scores[i][j] = (float)((Editions)ob[0]).getPhysicalDistance(skip_ends, max_mut, min_chunk, true);
						break;
					case 3: // median physical distance between mutation pairs
						scores[i][j] = (float)((Editions)ob[0]).getStatistics(skip_ends, max_mut, min_chunk, false)[3]; // 3 is median
						break;
					case 4: // cummulative physical distance between mutation pairs
						scores[i][j] = (float)((Editions)ob[0]).getPhysicalDistance(skip_ends, max_mut, min_chunk, false);
						break;
					case 5: // stdDev of distances between mutation pairs
						scores[i][j] = (float)((Editions)ob[0]).getStdDev(skip_ends, max_mut, min_chunk);
						break;
				}
				*/
                        final Editions ed = (Editions) ob[0];
                        scores[i][j] = (float) getScore(ed, skip_ends, max_mut, min_chunk, distance_type);
                        // mirror value
                        scores[j][i] = scores[i][j];
                    }
                }
            // //
            }
        };
    }
    MultiThreading.startAndJoin(threads);
    if (null != worker && worker.hasQuitted())
        return null;
    return scores;
}
Also used : Editions(ini.trakem2.vector.Editions) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) VectorString3D(ini.trakem2.vector.VectorString3D)

Example 8 with VectorString3D

use of ini.trakem2.vector.VectorString3D in project TrakEM2 by trakem2.

the class Compare method matchFwdRev.

// Match in all possible ways
private static final Object[] matchFwdRev(final VectorString3D vs1, final VectorString3D vs2, final double delta, final boolean skip_ends, final int max_mut, final float min_chunk, final int distance_type, final double wi, final double wd, final double wm) {
    final VectorString3D vs1rev = vs1.makeReversedCopy();
    final VectorString3D vs2rev = vs2.makeReversedCopy();
    final Editions[] ed = new Editions[4];
    // vs1 vs2
    ed[0] = new Editions(vs1, vs2, delta, false, wi, wd, wm);
    // vs1rev vs2rev
    ed[1] = new Editions(vs1rev, vs2rev, delta, false, wi, wd, wm);
    // vs1 vs2rev
    ed[2] = new Editions(vs1, vs2rev, delta, false, wi, wd, wm);
    // vs1rev vs2
    ed[3] = new Editions(vs1rev, vs2, delta, false, wi, wd, wm);
    // double best_score1 = 0;
    // worst possible
    double best_score = Double.MAX_VALUE;
    Editions best_ed = null;
    for (int i = 0; i < ed.length; i++) {
        final double score = getScore(ed[i], skip_ends, max_mut, min_chunk, distance_type);
        if (score < best_score) {
            best_ed = ed[i];
            best_score = score;
        // best_score1 = score1;
        }
    }
    // now test also starting from the middle of the longest mutation chunk of the best matching
    try {
        final Editions ed_center = best_ed.recreateFromCenter(max_mut);
        // is null if no chunks were found
        if (null != ed_center) {
            final double score_center = getScore(ed_center, skip_ends, max_mut, min_chunk, distance_type);
            if (score_center < best_score) {
                best_ed = ed_center;
                best_score = score_center;
            }
        }
    } catch (final Exception e) {
        e.printStackTrace();
    }
    return new Object[] { best_ed, new Double(best_score) };
}
Also used : Editions(ini.trakem2.vector.Editions) VectorString3D(ini.trakem2.vector.VectorString3D)

Example 9 with VectorString3D

use of ini.trakem2.vector.VectorString3D in project TrakEM2 by trakem2.

the class Compare method gatherChains.

/**
 * Gather chains for all projects considering the cp.regex, and transforms all relative to the reference Project p[0].
 *  Will ignore any for which a match exists in @param ignore.
 */
public static final Object[] gatherChains(final Project[] p, final CATAParameters cp, final String[] ignore) throws Exception {
    String regex_exclude = null;
    if (null != ignore) {
        final StringBuilder sb = new StringBuilder();
        for (final String ig : ignore) {
            sb.append("(.*").append(ig).append(".*)|");
        }
        sb.setLength(sb.length() - 1);
        regex_exclude = sb.toString();
    }
    Utils.logAll("Compare/gatherChains: using ignore string: " + regex_exclude);
    Utils.logAll("Compare/gatherChains: using regex: " + cp.regex);
    // gather all chains
    // to keep track of each project's chains
    final ArrayList[] p_chains = new ArrayList[p.length];
    final ArrayList<Chain> chains = new ArrayList<Chain>();
    for (int i = 0; i < p.length; i++) {
        // for each project:
        if (null == cp.regex) {
            p_chains[i] = createPipeChains(p[i].getRootProjectThing(), p[i].getRootLayerSet(), regex_exclude);
        } else {
            // Search (shallow) for cp.regex matches
            for (final ProjectThing pt : p[i].getRootProjectThing().findChildren(cp.regex, regex_exclude, true)) {
                final ArrayList<Chain> ac = createPipeChains(pt, p[i].getRootLayerSet(), regex_exclude);
                if (null == p_chains[i])
                    p_chains[i] = ac;
                else
                    p_chains[i].addAll(ac);
            }
            // empty
            if (null == p_chains[i])
                p_chains[i] = new ArrayList<Chain>();
        }
        chains.addAll(p_chains[i]);
        // calibrate
        final Calibration cal = p[i].getRootLayerSet().getCalibrationCopy();
        for (final Chain chain : (ArrayList<Chain>) p_chains[i]) chain.vs.calibrate(cal);
    }
    final int n_chains = chains.size();
    // register all, or relative
    if (4 == cp.transform_type) {
        // compute global average delta
        if (0 == cp.delta) {
            for (final Chain chain : chains) {
                cp.delta += (chain.vs.getAverageDelta() / n_chains);
            }
        }
        Utils.log2("Using delta: " + cp.delta);
        for (final Chain chain : chains) {
            // BEFORE making it relative
            chain.vs.resample(cp.delta, cp.with_source);
            chain.vs.relative();
        }
    } else {
        if (3 == cp.transform_type) {
            // '3' means moving least squares computed from 3D landmarks
            Utils.log2("Moving Least Squares Registration based on common fiducial points");
            // Find fiducial points, if any
            final HashMap<Project, Map<String, Tuple3d>> fiducials = new HashMap<Project, Map<String, Tuple3d>>();
            for (final Project pr : p) {
                final Set<ProjectThing> fids = pr.getRootProjectThing().findChildrenOfTypeR("fiducial_points");
                if (null == fids || 0 == fids.size()) {
                    Utils.log("No fiducial points found in project: " + pr);
                } else {
                    // the first fiducial group
                    fiducials.put(pr, Compare.extractPoints(fids.iterator().next()));
                }
            }
            if (!fiducials.isEmpty()) {
                // Register all VectorString3D relative to the first project:
                final List<VectorString3D> lvs = new ArrayList<VectorString3D>();
                final Calibration cal2 = p[0].getRootLayerSet().getCalibrationCopy();
                for (final Chain chain : chains) {
                    final Project pr = chain.pipes.get(0).getProject();
                    // first project is reference, no need to transform.
                    if (pr == p[0])
                        continue;
                    lvs.clear();
                    lvs.add(chain.vs);
                    chain.vs = transferVectorStrings(lvs, fiducials.get(pr), fiducials.get(p[0])).get(0);
                    // Set (but do not apply!) the calibration of the reference project
                    chain.vs.setCalibration(cal2);
                }
            }
        } else if (cp.transform_type < 3) {
            // '0', '1' and '2' involve a 3D affine computed from the 3 axes
            // no need //VectorString3D[][] vs_axes = new VectorString3D[p.length][];
            Vector3d[][] o = new Vector3d[p.length][];
            for (int i = 0; i < p.length; i++) {
                // 1 - find pipes to work as axes for each project
                final ArrayList<ZDisplayable> pipes = p[i].getRootLayerSet().getZDisplayables(Line3D.class, true);
                final String[] pipe_names = new String[pipes.size()];
                for (int k = 0; k < pipes.size(); k++) {
                    pipe_names[k] = p[i].getMeaningfulTitle(pipes.get(k));
                }
                final int[] s = findFirstXYZAxes(cp.preset, pipes, pipe_names);
                // if axes are -1, forget it: not found
                if (-1 == s[0] || -1 == s[1] || -1 == s[2]) {
                    Utils.log("Can't find axes for project " + p[i]);
                    o = null;
                    return null;
                }
                // obtain axes and origin
                final Object[] pack = obtainOrigin(new Line3D[] { (Line3D) pipes.get(s[0]), (Line3D) pipes.get(s[1]), (Line3D) pipes.get(s[2]) }, cp.transform_type, // will be null for the first, which will then be non-null and act as the reference for the others.
                o[0]);
                // no need //vs_axes[i] = (VectorString3D[])pack[0];
                o[i] = (Vector3d[]) pack[1];
            }
            /* // OLD WAY
				// match the scales to make the largest be 1.0
				final double scaling_factor = VectorString3D.matchOrigins(o, transform_type);
				Utils.log2("matchOrigins scaling factor: " + scaling_factor + " for transform_type " + transform_type);
				*/
            // transform all except the first (which acts as reference)
            final Transform3D M_ref = Compare.createTransform(o[0]);
            for (int i = 1; i < p.length; i++) {
                final Vector3d trans = new Vector3d(-o[i][3].x, -o[i][3].y, -o[i][3].z);
                final Transform3D M_query = Compare.createTransform(o[i]);
                // The transfer T transform: from query space to reference space.
                final Transform3D T = new Transform3D(M_ref);
                T.mulInverse(M_query);
                for (final Chain chain : (ArrayList<Chain>) p_chains[i]) {
                    // in place
                    chain.vs.transform(T);
                }
            }
        }
        // compute global average delta, after correcting calibration and transformation
        if (0 == cp.delta) {
            for (final Chain chain : chains) {
                cp.delta += (chain.vs.getAverageDelta() / n_chains);
            }
        }
        Utils.log2("Using delta: " + cp.delta);
        // After calibration and transformation, resample all to the same delta
        for (final Chain chain : chains) chain.vs.resample(cp.delta, cp.with_source);
    }
    return new Object[] { chains, p_chains };
}
Also used : HashMap(java.util.HashMap) Transform3D(org.scijava.java3d.Transform3D) ArrayList(java.util.ArrayList) Calibration(ij.measure.Calibration) Line3D(ini.trakem2.display.Line3D) Project(ini.trakem2.Project) VectorString3D(ini.trakem2.vector.VectorString3D) Vector3d(org.scijava.vecmath.Vector3d) Tuple3d(org.scijava.vecmath.Tuple3d) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) ProjectThing(ini.trakem2.tree.ProjectThing)

Example 10 with VectorString3D

use of ini.trakem2.vector.VectorString3D in project TrakEM2 by trakem2.

the class Compare method findBestMatch.

public static final Object[] findBestMatch(final VectorString3D vs1, final VectorString3D vs2, final double delta, final boolean skip_ends, final int max_mut, final float min_chunk, final int distance_type, final boolean direct, final boolean substring_matching, final double wi, final double wd, final double wm) {
    if (substring_matching) {
        // identify shorter chain
        final VectorString3D shorter = vs1.length() < vs2.length() ? vs1 : vs2;
        final VectorString3D longer = vs1 == shorter ? vs2 : vs1;
        // iterate matching of shorter string inside longer string:
        // (so that the match is always between two equally long strings)
        // aaaaaaaa   : 8 elements
        // bbbbb      : 5 elements
        // bbbbb      --- total 4 matches to try
        // bbbbb
        // bbbbb
        // 
        final int shorter_len = shorter.length();
        // when of equal length, the loop runs once.
        final int max_offset = longer.length() - shorter_len + 1;
        Object[] best = null;
        for (int k = 0; k < max_offset; k++) {
            final VectorString3D longer_sub = longer.substring(k, k + shorter_len);
            // Utils.log2("#######");
            // Utils.log2(k + " delta of shorter: " + shorter.getDelta());
            // Utils.log2(k + " substring_matching lengths: shorter, longer_sub : " + shorter.length() + ", " + longer_sub.length());
            // Utils.log2(k + " shorter is" + shorter + " of length " + shorter.length());
            // Utils.log2(k + " longer_sub is " + longer_sub + " made from " + longer + " with first,last: " + k + ", " + (k + shorter_len));
            final Object[] ob = direct ? matchDirect(shorter, longer_sub, delta, skip_ends, max_mut, min_chunk, distance_type, wi, wd, wm) : matchFwdRev(shorter, longer_sub, delta, skip_ends, max_mut, min_chunk, distance_type, wi, wd, wm);
            if (null == best)
                best = ob;
            else {
                // values generated in getScore
                final double dob = ((Double) ob[1]).doubleValue();
                final double dbest = ((Double) best[1]).doubleValue();
                // and also COMBINED, since getScore does 1 / score
                if (dob < dbest)
                    best = ob;
            }
        }
        return best;
    } else {
        if (direct) {
            return matchDirect(vs1, vs2, delta, skip_ends, max_mut, min_chunk, distance_type, wi, wd, wm);
        } else {
            return matchFwdRev(vs1, vs2, delta, skip_ends, max_mut, min_chunk, distance_type, wi, wd, wm);
        }
    }
}
Also used : VectorString3D(ini.trakem2.vector.VectorString3D)

Aggregations

VectorString3D (ini.trakem2.vector.VectorString3D)19 ArrayList (java.util.ArrayList)6 Editions (ini.trakem2.vector.Editions)5 Calibration (ij.measure.Calibration)4 Project (ini.trakem2.Project)4 HashMap (java.util.HashMap)4 Map (java.util.Map)4 TreeMap (java.util.TreeMap)4 CATAParameters (ini.trakem2.analysis.Compare.CATAParameters)3 Worker (ini.trakem2.utils.Worker)3 HashSet (java.util.HashSet)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 Vector3d (org.scijava.vecmath.Vector3d)3 File (java.io.File)2 Tuple3d (org.scijava.vecmath.Tuple3d)2 ImagePlus (ij.ImagePlus)1 OvalRoi (ij.gui.OvalRoi)1 Plot (ij.gui.Plot)1 DirectoryChooser (ij.io.DirectoryChooser)1 FileSaver (ij.io.FileSaver)1