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