public boolean remove(boolean check) { if (check) { if (!Utils.check( "Really delete " + this.toString() + (null == al_children || 0 == al_children.size() ? "" : " and all its children?"))) return false; } // remove the children, recursively if (null != al_children) { Object[] children = new Object[al_children.size()]; al_children.toArray( children); // can't delete directly from the al_children because the child will call // removeChild on its parent for (int i = 0; i < children.length; i++) { Object ob = children[i]; if (ob instanceof DBObject) { if (!((DBObject) ob).remove(false)) { Utils.showMessage("Deletion incomplete, check database, for child: " + ob.toString()); return false; } } } } // remove the Thing itself if (null != parent && !parent.removeChild(this)) { Utils.showMessage( "Deletion incomplete, check database, for parent of TemplateThing id=" + id); return false; } return removeFromDatabase(); }
public final void exec(final List<Patch> patches, final Set<Patch> fixedPatches) throws Exception { /* make sure that passed patches are ok */ if (patches.size() < 2) { Utils.log( "Elastic montage requires at least 2 patches to be montaged. You passed me " + patches.size()); return; } final Project project = patches.get(0).getProject(); for (final Patch patch : patches) { if (patch.getProject() != project) { Utils.log( "Elastic montage requires all patches to be member of a single project. You passed me patches from several projects."); return; } } for (final Patch patch : fixedPatches) { if (patch.getProject() != project) { Utils.log( "Elastic montage requires all fixed patches to be member of a single project. You passed me fixed patches from several projects."); return; } } final Param param = setup(); if (param == null) return; else exec(param, patches, fixedPatches); }
public boolean removeChild(TemplateThing child) { // check that it is contained here if (-1 == al_children.indexOf(child)) { Utils.log("TemplateThing.removeChild: child " + child + " not contained in parent " + this); return false; } al_children.remove(child); return true; }
@Override public ResultsTable measure(ResultsTable rt) { if (0 == al_items.size()) return rt; if (null == rt) rt = Utils.createResultsTable( "Dissector results", new String[] {"id", "tag", "x", "y", "z", "radius", "nameid"}); for (final Item item : al_items) item.addResults(rt, layer_set.getCalibration(), getNameId()); return rt; }
final void addResults(final ResultsTable rt, final Calibration cal, final double nameid) { for (int i = 0; i < n_points; i++) { final Layer la = layer_set.getLayer(p_layer[i]); if (null == layer) { Utils.log("Dissector.addResults: could not find layer with id " + p_layer[i]); continue; } final Point2D.Double po = M.transform(Dissector.this.at, p[0][i], p[1][i]); rt.incrementCounter(); rt.addLabel("units", cal.getUnit()); rt.addValue(0, Dissector.this.id); rt.addValue(1, tag); rt.addValue(2, po.x * cal.pixelWidth); rt.addValue(3, po.y * cal.pixelHeight); rt.addValue(4, la.getZ() * cal.pixelWidth); // layer Z is in pixels rt.addValue(5, radius * cal.pixelWidth); rt.addValue(6, nameid); } }
public boolean addChild(Thing child) { if (null == child) return false; if (null == al_children) al_children = new ArrayList<TemplateThing>(); else { // check that no child is already of the same type as the new child for (final TemplateThing tc : al_children) { if (tc.type.equals(((TemplateThing) child).type)) { Utils.log2("TemplateThing.addChild: already have a child of type " + tc.type); // Utils.printCaller(this, 10); return false; } } // TODO should change to use a Map<String,TemplateThing>. // but then there wouldn't be a sequential order. } // Utils.log2("Added child of type " + ((TemplateThing)child).type); al_children.add((TemplateThing) child); child.setParent(this); return true; }
@Override public void exportXML( final StringBuilder sb_body, final String indent, final XMLOptions options) { sb_body.append(indent).append("<t2_dissector\n"); final String in = indent + "\t"; super.exportXML(sb_body, in, options); final String[] RGB = Utils.getHexRGBColor(color); sb_body .append(in) .append("style=\"fill:none;stroke-opacity:") .append(alpha) .append(";stroke:#") .append(RGB[0]) .append(RGB[1]) .append(RGB[2]) .append(";stroke-width:1.0px;\"\n"); sb_body.append(indent).append(">\n"); for (final Item item : al_items) { item.exportXML(sb_body, in); } super.restXML(sb_body, in, options); sb_body.append(indent).append("</t2_dissector>\n"); }
@SuppressWarnings("deprecation") public final void exec( final Param param, final List<Patch> patches, final Set<Patch> fixedPatches) throws Exception { /* free memory */ patches.get(0).getProject().getLoader().releaseAll(); /* create tiles and models for all patches */ final ArrayList<AbstractAffineTile2D<?>> tiles = new ArrayList<AbstractAffineTile2D<?>>(); final ArrayList<AbstractAffineTile2D<?>> fixedTiles = new ArrayList<AbstractAffineTile2D<?>>(); Align.tilesFromPatches(param.po, patches, fixedPatches, tiles, fixedTiles); if (!param.isAligned) { Align.alignTiles(param.po, tiles, fixedTiles, param.tilesAreInPlace, param.maxNumThreads); /* Apply the estimated affine transform to patches */ for (final AbstractAffineTile2D<?> t : tiles) t.getPatch().setAffineTransform(t.createAffine()); Display.update(); } /* generate tile pairs for all by now overlapping tiles */ final ArrayList<AbstractAffineTile2D<?>[]> tilePairs = new ArrayList<AbstractAffineTile2D<?>[]>(); AbstractAffineTile2D.pairOverlappingTiles(tiles, tilePairs); /* check if there was any pair */ if (tilePairs.size() == 0) { Utils.log("Elastic montage could not find any overlapping patches after pre-montaging."); return; } Utils.log(tilePairs.size() + " pairs of patches will be block-matched..."); /* make pairwise global models local */ final ArrayList< Triple<AbstractAffineTile2D<?>, AbstractAffineTile2D<?>, InvertibleCoordinateTransform>> pairs = new ArrayList< Triple< AbstractAffineTile2D<?>, AbstractAffineTile2D<?>, InvertibleCoordinateTransform>>(); /* * The following casting madness is necessary to get this code compiled * with Sun/Oracle Java 6 which otherwise generates an inconvertible * type exception. * * TODO Remove as soon as this bug is fixed in Sun/Oracle javac. */ for (final AbstractAffineTile2D<?>[] pair : tilePairs) { final AbstractAffineModel2D<?> m; switch (param.po.desiredModelIndex) { case 0: final TranslationModel2D t = (TranslationModel2D) (Object) pair[1].getModel().createInverse(); t.concatenate((TranslationModel2D) (Object) pair[0].getModel()); m = t; break; case 1: final RigidModel2D r = (RigidModel2D) (Object) pair[1].getModel().createInverse(); r.concatenate((RigidModel2D) (Object) pair[0].getModel()); m = r; break; case 2: final SimilarityModel2D s = (SimilarityModel2D) (Object) pair[1].getModel().createInverse(); s.concatenate((SimilarityModel2D) (Object) pair[0].getModel()); m = s; break; case 3: final AffineModel2D a = (AffineModel2D) (Object) pair[1].getModel().createInverse(); a.concatenate((AffineModel2D) (Object) pair[0].getModel()); m = a; break; default: m = null; } pairs.add( new Triple< AbstractAffineTile2D<?>, AbstractAffineTile2D<?>, InvertibleCoordinateTransform>( pair[0], pair[1], m)); } /* Elastic alignment */ /* Initialization */ final double springTriangleHeightTwice = 2 * Math.sqrt(0.75 * param.springLengthSpringMesh * param.springLengthSpringMesh); final ArrayList<SpringMesh> meshes = new ArrayList<SpringMesh>(tiles.size()); final HashMap<AbstractAffineTile2D<?>, SpringMesh> tileMeshMap = new HashMap<AbstractAffineTile2D<?>, SpringMesh>(); for (final AbstractAffineTile2D<?> tile : tiles) { final double w = tile.getWidth(); final double h = tile.getHeight(); final int numX = Math.max(2, (int) Math.ceil(w / param.springLengthSpringMesh) + 1); final int numY = Math.max(2, (int) Math.ceil(h / springTriangleHeightTwice) + 1); final double wMesh = (numX - 1) * param.springLengthSpringMesh; final double hMesh = (numY - 1) * springTriangleHeightTwice; final SpringMesh mesh = new SpringMesh( numX, numY, wMesh, hMesh, param.stiffnessSpringMesh, param.maxStretchSpringMesh * param.bmScale, param.dampSpringMesh); meshes.add(mesh); tileMeshMap.put(tile, mesh); } // final int blockRadius = Math.max( 32, Util.roundPos( param.springLengthSpringMesh / 2 ) ); final int blockRadius = Math.max(Util.roundPos(16 / param.bmScale), param.bmBlockRadius); /** TODO set this something more than the largest error by the approximate model */ final int searchRadius = param.bmSearchRadius; final AbstractModel<?> localSmoothnessFilterModel = mpicbg.trakem2.align.Util.createModel(param.bmLocalModelIndex); for (final Triple< AbstractAffineTile2D<?>, AbstractAffineTile2D<?>, InvertibleCoordinateTransform> pair : pairs) { final AbstractAffineTile2D<?> t1 = pair.a; final AbstractAffineTile2D<?> t2 = pair.b; final SpringMesh m1 = tileMeshMap.get(t1); final SpringMesh m2 = tileMeshMap.get(t2); final ArrayList<PointMatch> pm12 = new ArrayList<PointMatch>(); final ArrayList<PointMatch> pm21 = new ArrayList<PointMatch>(); final ArrayList<Vertex> v1 = m1.getVertices(); final ArrayList<Vertex> v2 = m2.getVertices(); final String patchName1 = patchName(t1.getPatch()); final String patchName2 = patchName(t2.getPatch()); final PatchImage pi1 = t1.getPatch().createTransformedImage(); if (pi1 == null) { Utils.log("Patch `" + patchName1 + "' failed generating a transformed image. Skipping..."); continue; } final PatchImage pi2 = t2.getPatch().createTransformedImage(); if (pi2 == null) { Utils.log("Patch `" + patchName2 + "' failed generating a transformed image. Skipping..."); continue; } final FloatProcessor fp1 = (FloatProcessor) pi1.target.convertToFloat(); final ByteProcessor mask1 = pi1.getMask(); final FloatProcessor fpMask1 = mask1 == null ? null : scaleByte(mask1); final FloatProcessor fp2 = (FloatProcessor) pi2.target.convertToFloat(); final ByteProcessor mask2 = pi2.getMask(); final FloatProcessor fpMask2 = mask2 == null ? null : scaleByte(mask2); if (!fixedTiles.contains(t1)) { BlockMatching.matchByMaximalPMCC( fp1, fp2, fpMask1, fpMask2, param.bmScale, pair.c, blockRadius, blockRadius, searchRadius, searchRadius, param.bmMinR, param.bmRodR, param.bmMaxCurvatureR, v1, pm12, new ErrorStatistic(1)); if (param.bmUseLocalSmoothnessFilter) { Utils.log( "`" + patchName1 + "' > `" + patchName2 + "': found " + pm12.size() + " correspondence candidates."); localSmoothnessFilterModel.localSmoothnessFilter( pm12, pm12, param.bmLocalRegionSigma, param.bmMaxLocalEpsilon, param.bmMaxLocalTrust); Utils.log( "`" + patchName1 + "' > `" + patchName2 + "': " + pm12.size() + " candidates passed local smoothness filter."); } else { Utils.log( "`" + patchName1 + "' > `" + patchName2 + "': found " + pm12.size() + " correspondences."); } } else { Utils.log("Skipping fixed patch `" + patchName1 + "'."); } // /* <visualisation> */ // // final List< Point > s1 = new ArrayList< Point >(); // // PointMatch.sourcePoints( pm12, s1 ); // // final ImagePlus imp1 = new ImagePlus( i + " >", ip1 ); // // imp1.show(); // // imp1.setOverlay( BlockMatching.illustrateMatches( pm12 ), Color.yellow, null ); // // imp1.setRoi( Util.pointsToPointRoi( s1 ) ); // // imp1.updateAndDraw(); // /* </visualisation> */ if (!fixedTiles.contains(t2)) { BlockMatching.matchByMaximalPMCC( fp2, fp1, fpMask2, fpMask1, param.bmScale, pair.c.createInverse(), blockRadius, blockRadius, searchRadius, searchRadius, param.bmMinR, param.bmRodR, param.bmMaxCurvatureR, v2, pm21, new ErrorStatistic(1)); if (param.bmUseLocalSmoothnessFilter) { Utils.log( "`" + patchName1 + "' < `" + patchName2 + "': found " + pm21.size() + " correspondence candidates."); localSmoothnessFilterModel.localSmoothnessFilter( pm21, pm21, param.bmLocalRegionSigma, param.bmMaxLocalEpsilon, param.bmMaxLocalTrust); Utils.log( "`" + patchName1 + "' < `" + patchName2 + "': " + pm21.size() + " candidates passed local smoothness filter."); } else { Utils.log( "`" + patchName1 + "' < `" + patchName2 + "': found " + pm21.size() + " correspondences."); } } else { Utils.log("Skipping fixed patch `" + patchName2 + "'."); } /* <visualisation> */ // final List< Point > s2 = new ArrayList< Point >(); // PointMatch.sourcePoints( pm21, s2 ); // final ImagePlus imp2 = new ImagePlus( i + " <", ip2 ); // imp2.show(); // imp2.setOverlay( BlockMatching.illustrateMatches( pm21 ), Color.yellow, null ); // imp2.setRoi( Util.pointsToPointRoi( s2 ) ); // imp2.updateAndDraw(); /* </visualisation> */ for (final PointMatch pm : pm12) { final Vertex p1 = (Vertex) pm.getP1(); final Vertex p2 = new Vertex(pm.getP2()); p1.addSpring(p2, new Spring(0, 1.0f)); m2.addPassiveVertex(p2); } for (final PointMatch pm : pm21) { final Vertex p1 = (Vertex) pm.getP1(); final Vertex p2 = new Vertex(pm.getP2()); p1.addSpring(p2, new Spring(0, 1.0f)); m1.addPassiveVertex(p2); } } /* initialize */ for (final Map.Entry<AbstractAffineTile2D<?>, SpringMesh> entry : tileMeshMap.entrySet()) entry.getValue().init(entry.getKey().getModel()); /* optimize the meshes */ try { final long t0 = System.currentTimeMillis(); IJ.log("Optimizing spring meshes..."); if (param.useLegacyOptimizer) { Utils.log(" ...using legacy optimizer..."); SpringMesh.optimizeMeshes2( meshes, param.po.maxEpsilon, param.maxIterationsSpringMesh, param.maxPlateauwidthSpringMesh, param.visualize); } else { SpringMesh.optimizeMeshes( meshes, param.po.maxEpsilon, param.maxIterationsSpringMesh, param.maxPlateauwidthSpringMesh, param.visualize); } IJ.log("Done optimizing spring meshes. Took " + (System.currentTimeMillis() - t0) + " ms"); } catch (final NotEnoughDataPointsException e) { Utils.log("There were not enough data points to get the spring mesh optimizing."); e.printStackTrace(); return; } /* apply */ for (final Map.Entry<AbstractAffineTile2D<?>, SpringMesh> entry : tileMeshMap.entrySet()) { final AbstractAffineTile2D<?> tile = entry.getKey(); if (!fixedTiles.contains(tile)) { final Patch patch = tile.getPatch(); final SpringMesh mesh = entry.getValue(); final Set<PointMatch> matches = mesh.getVA().keySet(); Rectangle box = patch.getCoordinateTransformBoundingBox(); /* compensate for existing coordinate transform bounding box */ for (final PointMatch pm : matches) { final Point p1 = pm.getP1(); final double[] l = p1.getL(); l[0] += box.x; l[1] += box.y; } final MovingLeastSquaresTransform2 mlt = new MovingLeastSquaresTransform2(); mlt.setModel(AffineModel2D.class); mlt.setAlpha(2.0f); mlt.setMatches(matches); patch.appendCoordinateTransform(mlt); box = patch.getCoordinateTransformBoundingBox(); patch.getAffineTransform().setToTranslation(box.x, box.y); patch.updateInDatabase("transform"); patch.updateBucket(); patch.updateMipMaps(); } } Utils.log("Done."); }
@Override public synchronized Collection<Long> getLayerIds() { final HashSet<Long> lids = new HashSet<Long>(); for (final Item item : al_items) lids.addAll(Utils.asList(item.p_layer, 0, item.n_points)); return lids; }
@Override public void mousePressed( final MouseEvent me, final Layer la, int x_p, int y_p, final double mag) { final int tool = ProjectToolbar.getToolId(); if (ProjectToolbar.PEN != tool) return; final long lid = la.getId(); // isn't this.layer pointing to the current layer always? // transform the x_p, y_p to the local coordinates if (!this.at.isIdentity()) { final Point2D.Double p = inverseTransformPoint(x_p, y_p); x_p = (int) p.x; y_p = (int) p.y; } // find if the click is within radius of an existing point for the current layer for (final Item tmp : al_items) { index = tmp.find(lid, x_p, y_p, mag); if (-1 != index) { this.item = tmp; break; } } // final boolean is_zoom_invariant = "true".equals(project.getProperty("dissector_zoom")); // TODO: if zoom invariant, should check for nearest point. Or nearest point anyway, when // deleting // (but also for adding a new one?) if (me.isShiftDown() && Utils.isControlDown(me)) { if (-1 != index) { // delete item.remove(index); if (0 == item.n_points) al_items.remove(item); item = null; index = -1; Display.repaint(layer_set, this, 0); } // in any case: return; } if (-1 != index) return; // else try to add a point to a suitable item // Find an item in the previous or the next layer, // which falls within radius of the clicked point try { for (final Item tmp : al_items) { index = tmp.add(x_p, y_p, la); if (-1 != index) { this.item = tmp; return; } } // could not be added to an existing item, so creating a new item with a new point in it int max_tag = 0; for (final Item tmp : al_items) { if (tmp.tag > max_tag) max_tag = tmp.tag; } int radius = 8; // default if (al_items.size() > 0) radius = al_items.get(al_items.size() - 1).radius; this.item = new Item(max_tag + 1, radius, x_p, y_p, la); index = 0; al_items.add(this.item); } finally { if (null != item) { bbox = this.at.createTransformedShape(item.getBoundingBox()).getBounds(); Display.repaint(layer_set, bbox); } else Display.repaint(layer_set, this, 0); } }