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);
}
}
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 };
}
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);
}
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 };
}
Aggregations