use of tracing.TracerThread in project TrakEM2 by trakem2.
the class Polyline method mousePressed.
@Override
public void mousePressed(final MouseEvent me, final Layer layer, int x_p, int y_p, final double mag) {
// transform the x_p, y_p to the local coordinates
final int x_pd = x_p;
final int y_pd = y_p;
if (!this.at.isIdentity()) {
final Point2D.Double po = inverseTransformPoint(x_p, y_p);
x_p = (int) po.x;
y_p = (int) po.y;
}
final int tool = ProjectToolbar.getToolId();
final Display display = ((DisplayCanvas) me.getSource()).getDisplay();
final long layer_id = layer.getId();
index = findPoint(x_p, y_p, layer_id, mag);
if (ProjectToolbar.PENCIL == tool && n_points > 0 && -1 == index && !me.isShiftDown() && !Utils.isControlDown(me)) {
// Check that there are any images -- otherwise may hang. TODO
if (layer_set.getDisplayables(Patch.class).isEmpty()) {
Utils.log("No images are present!");
return;
}
final double scale = layer_set.getVirtualizationScale();
// Ok now with all found images, create a virtual stack that provides access to them all, with caching.
final Worker[] worker = new Worker[2];
final TraceParameters tr_ = tr_map.get(layer_set);
final TraceParameters tr = null == tr_ ? new TraceParameters() : tr_;
if (null == tr_) {
synchronized (tr_map) {
tr_map.put(layer_set, tr);
}
}
if (tr.update) {
worker[0] = new Worker("Preparing Hessian...") {
@Override
public void run() {
startedWorking();
try {
Utils.log("Push ESCAPE key to cancel autotrace anytime.");
final ImagePlus virtual = new LayerStack(layer_set, scale, ImagePlus.GRAY8, Patch.class, display.getDisplayChannelAlphas(), Segmentation.fmp.SNT_invert_image).getImagePlus();
// virtual.show();
final Calibration cal = virtual.getCalibration();
double minimumSeparation = 1;
if (cal != null)
minimumSeparation = Math.min(cal.pixelWidth, Math.min(cal.pixelHeight, cal.pixelDepth));
final ComputeCurvatures hessian = new ComputeCurvatures(virtual, minimumSeparation, null, cal != null);
hessian.run();
tr.virtual = virtual;
// tr.scale = scale;
tr.hessian = hessian;
tr.update = false;
} catch (final Exception e) {
IJError.print(e);
}
finishedWorking();
}
};
Bureaucrat.createAndStart(worker[0], project);
}
final Point2D.Double po = transformPoint(p[0][n_points - 1], p[1][n_points - 1]);
final int start_x = (int) po.x;
final int start_y = (int) po.y;
// 0-based
final int start_z = layer_set.indexOf(layer_set.getLayer(p_layer[n_points - 1]));
// must transform into virtual space
final int goal_x = (int) (x_pd * scale);
final int goal_y = (int) (y_pd * scale);
final int goal_z = layer_set.indexOf(layer);
/*
Utils.log2("x_pd, y_pd : " + x_pd + ", " + y_pd);
Utils.log2("scale: " + scale);
Utils.log2("start: " + start_x + "," + start_y + ", " + start_z);
Utils.log2("goal: " + goal_x + "," + goal_y + ", " + goal_z);
Utils.log2("virtual: " + tr.virtual);
*/
final boolean simplify = me.isAltDown();
worker[1] = new Worker("Tracer - waiting on hessian") {
@Override
public void run() {
startedWorking();
try {
if (null != worker[0]) {
// Wait until hessian is ready
worker[0].join();
}
setTaskName("Tracing path");
final int reportEveryMilliseconds = 2000;
tr.tracer = new TracerThread(tr.virtual, 0, 255, // timeout seconds
120, reportEveryMilliseconds, start_x, start_y, start_z, goal_x, goal_y, goal_z, // reciproal pix values at start and goal
true, tr.virtual.getStackSize() == 1, tr.hessian, null == tr.hessian ? 1 : 4, null, null != tr.hessian);
tr.tracer.addProgressListener(new SearchProgressCallback() {
@Override
public void pointsInSearch(final SearchInterface source, final int inOpen, final int inClosed) {
worker[1].setTaskName("Tracing path: open=" + inOpen + " closed=" + inClosed);
}
@Override
public void finished(final SearchInterface source, final boolean success) {
if (!success) {
Utils.logAll("Could NOT trace a path");
}
}
@Override
public void threadStatus(final SearchInterface source, final int currentStatus) {
// This method gets called every reportEveryMilliseconds
if (worker[1].hasQuitted()) {
source.requestStop();
}
}
});
tr.tracer.run();
final Path result = tr.tracer.getResult();
tr.tracer = null;
if (null == result) {
// : "+
Utils.log("Finding a path failed");
// not public //SearchThread.exitReasonStrings[tracer.getExitReason()]);
return;
}
// TODO: precise_x_positions etc are likely to be broken (calibrated or something)
// Remove bogus points: those at the end with 0,0 coords
int len = result.points;
final double[][] pos = result.getXYZUnscaled();
for (int i = len - 1; i > -1; i--) {
if (0 == pos[0][i] && 0 == pos[1][i]) {
len--;
} else
break;
}
// Transform points: undo scale, and bring to this Polyline AffineTransform:
final AffineTransform aff = new AffineTransform();
/* Inverse order: */
/* 2 */
aff.concatenate(Polyline.this.at.createInverse());
/* 1 */
aff.scale(1 / scale, 1 / scale);
final double[] po = new double[len * 2];
for (int i = 0, j = 0; i < len; i++, j += 2) {
po[j] = pos[0][i];
po[j + 1] = pos[1][i];
}
final double[] po2 = new double[len * 2];
// what a stupid format: consecutive x,y pairs
aff.transform(po, 0, po2, 0, len);
long[] p_layer_ids = new long[len];
double[] pox = new double[len];
double[] poy = new double[len];
for (int i = 0, j = 0; i < len; i++, j += 2) {
// z_positions in 0-(N-1), not in 1-N like slices!
p_layer_ids[i] = layer_set.getLayer((int) pos[2][i]).getId();
pox[i] = po2[j];
poy[i] = po2[j + 1];
}
// Simplify path: to steps of 5 calibration units, or 5 pixels when not calibrated.
if (simplify) {
setTaskName("Simplifying path");
final Object[] ob = Polyline.simplify(pox, poy, p_layer_ids, 10000, layer_set);
pox = (double[]) ob[0];
poy = (double[]) ob[1];
p_layer_ids = (long[]) ob[2];
len = pox.length;
}
// Record the first newly-added autotraced point index:
last_autotrace_start = Polyline.this.n_points;
Polyline.this.appendPoints(pox, poy, p_layer_ids, len);
Polyline.this.repaint(true, null);
Utils.logAll("Added " + len + " new points.");
} catch (final Exception e) {
IJError.print(e);
}
finishedWorking();
}
};
Bureaucrat.createAndStart(worker[1], project);
index = -1;
return;
}
if (ProjectToolbar.PEN == tool || ProjectToolbar.PENCIL == tool) {
if (Utils.isControlDown(me) && me.isShiftDown()) {
final long lid = Display.getFrontLayer(this.project).getId();
if (-1 == index || lid != p_layer[index]) {
index = findNearestPoint(x_p, y_p, layer_id);
}
if (-1 != index) {
// delete point
removePoint(index);
index = -1;
repaint(false, null);
}
// In any case, terminate
return;
}
if (// disable!
-1 != index && layer_id != p_layer[index])
// disable!
index = -1;
else // if no conditions are met, attempt to add point
if (-1 == index && !me.isShiftDown() && !me.isAltDown()) {
// add a new point
index = addPoint(x_p, y_p, layer_id, mag);
is_new_point = true;
repaint(false, null);
return;
}
}
}
Aggregations