Search in sources :

Example 1 with Line3D

use of ini.trakem2.display.Line3D in project TrakEM2 by trakem2.

the class Compare method appendAndFork.

/**
 * Recursive.
 */
private static void appendAndFork(final ProjectThing parent, Chain chain, HashSet<ProjectThing> hs_c_done, final ArrayList<Chain> chains, final LayerSet ls, final Pattern exclude) throws Exception {
    if (null != exclude && exclude.matcher(parent.getTitle()).matches()) {
        Utils.logAll("Excluding node " + parent + " with title " + parent.getTitle() + ", and all its children nodes.");
        return;
    }
    final ArrayList<ProjectThing> children = parent.getChildren();
    if (null == children)
        return;
    if (null == hs_c_done)
        hs_c_done = new HashSet<ProjectThing>();
    for (final ProjectThing child : children) {
        if (hs_c_done.contains(child))
            continue;
        if (null != exclude && exclude.matcher(child.getTitle()).matches()) {
            Utils.log2("Excluding child " + child + " with title " + child.getTitle());
            continue;
        }
        hs_c_done.add(child);
        if (child.getObject() instanceof Line3D) {
            final Line3D pipe = (Line3D) child.getObject();
            // not from the same LayerSet, maybe from a nested one.
            if (!pipe.getLayerSet().equals(ls) || pipe.length() < 2)
                continue;
            if (null == chain) {
                chain = new Chain(pipe);
                chains.add(chain);
            } else {
                chain.append(pipe);
            }
            // find other children in the parent who contain children with child pipes
            boolean first = true;
            final Chain base = chain.duplicate();
            for (final ProjectThing c : children) {
                // already visited
                if (hs_c_done.contains(c))
                    continue;
                // c is at the same tree level as child (which contains a pipe directly)
                final ArrayList<Line3D> child_pipes = c.findChildrenOfType(Line3D.class);
                if (child_pipes.size() > 0) {
                    Chain ca;
                    if (first) {
                        // just append
                        ca = chain;
                        first = false;
                    } else {
                        // otherwise make a copy to branch out
                        // can't duplicate from chain itself, because it would have the previous child added to it.
                        ca = base.duplicate();
                        chains.add(ca);
                    }
                    appendAndFork(c, ca, hs_c_done, chains, ls, exclude);
                }
            }
            // pipe wrapping ProjectThing objects cannot have any children
            continue;
        }
        // if it does not have direct pipe children, cut chain - but keep inspecting
        if (0 == child.findChildrenOfType(Line3D.class).size()) {
            chain = null;
        }
        // inspect others down the unvisited tree nodes
        appendAndFork(child, chain, hs_c_done, chains, ls, exclude);
    }
}
Also used : ProjectThing(ini.trakem2.tree.ProjectThing) Line3D(ini.trakem2.display.Line3D) HashSet(java.util.HashSet)

Example 2 with Line3D

use of ini.trakem2.display.Line3D 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 3 with Line3D

use of ini.trakem2.display.Line3D in project TrakEM2 by trakem2.

the class Identify method invoke.

@Override
public Object invoke(Object... args) {
    if (null == args || args.length < 1 || null == args[0] || !(args[0] instanceof Line3D))
        return null;
    Line3D pipe = (Line3D) args[0];
    Params p = params.clone();
    return identify(pipe, p.libs.get(p.lib_index), p.delta, p.direct, p.substring);
}
Also used : Line3D(ini.trakem2.display.Line3D)

Example 4 with Line3D

use of ini.trakem2.display.Line3D in project TrakEM2 by trakem2.

the class Compare method obtainOrigin.

/**
 * Generate calibrated origin of coordinates.
 */
public static Object[] obtainOrigin(final Line3D[] axes, final int transform_type, final Vector3d[] o_ref) {
    // pipe's axes
    final VectorString3D[] vs = new VectorString3D[3];
    for (int i = 0; i < 3; i++) vs[i] = axes[i].asVectorString3D();
    final Calibration cal = (null != axes[0].getLayerSet() ? axes[0].getLayerSet().getCalibration() : null);
    // 1 - calibrate
    if (null != cal) {
        for (int i = 0; i < 3; i++) vs[i].calibrate(cal);
    }
    // 2 - resample (although it's done before transforming, it's only for aesthetic purposes: it doesn't matter, won't ever go into dynamic programming machinery)
    double delta = 0;
    for (int i = 0; i < 3; i++) delta += vs[i].getAverageDelta();
    delta /= 3;
    for (int i = 0; i < 3; i++) vs[i].resample(delta);
    // return origin vectors for pipe's project
    // requires resampled vs
    final Vector3d[] o = Compare.createOrigin(vs[0], vs[1], vs[2], transform_type, o_ref);
    return new Object[] { vs, o };
}
Also used : VectorString3D(ini.trakem2.vector.VectorString3D) Vector3d(org.scijava.vecmath.Vector3d) Calibration(ij.measure.Calibration)

Aggregations

Line3D (ini.trakem2.display.Line3D)3 Calibration (ij.measure.Calibration)2 ProjectThing (ini.trakem2.tree.ProjectThing)2 VectorString3D (ini.trakem2.vector.VectorString3D)2 Vector3d (org.scijava.vecmath.Vector3d)2 Project (ini.trakem2.Project)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 TreeMap (java.util.TreeMap)1 Transform3D (org.scijava.java3d.Transform3D)1 Tuple3d (org.scijava.vecmath.Tuple3d)1