Search in sources :

Example 1 with TracerThread

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;
        }
    }
}
Also used : Path(tracing.Path) SearchInterface(tracing.SearchInterface) ComputeCurvatures(features.ComputeCurvatures) Calibration(ij.measure.Calibration) ImagePlus(ij.ImagePlus) NoninvertibleTransformException(java.awt.geom.NoninvertibleTransformException) Point2D(java.awt.geom.Point2D) LayerStack(ini.trakem2.imaging.LayerStack) TracerThread(tracing.TracerThread) Worker(ini.trakem2.utils.Worker) AffineTransform(java.awt.geom.AffineTransform) SearchProgressCallback(tracing.SearchProgressCallback)

Aggregations

ComputeCurvatures (features.ComputeCurvatures)1 ImagePlus (ij.ImagePlus)1 Calibration (ij.measure.Calibration)1 LayerStack (ini.trakem2.imaging.LayerStack)1 Worker (ini.trakem2.utils.Worker)1 AffineTransform (java.awt.geom.AffineTransform)1 NoninvertibleTransformException (java.awt.geom.NoninvertibleTransformException)1 Point2D (java.awt.geom.Point2D)1 Path (tracing.Path)1 SearchInterface (tracing.SearchInterface)1 SearchProgressCallback (tracing.SearchProgressCallback)1 TracerThread (tracing.TracerThread)1