Search in sources :

Example 1 with FSLoader

use of ini.trakem2.persistence.FSLoader in project TrakEM2 by trakem2.

the class MatchIntensities method run.

/**
 * @param layers
 * @param radius
 * @param scale
 * @param numCoefficients
 * @param lambda1
 * @param lambda2
 * @param neighborWeight
 * @param roi
 */
public <M extends Model<M> & Affine1D<M>> void run(final List<Layer> layers, final int radius, final double scale, final int numCoefficients, final double lambda1, final double lambda2, final double neighborWeight, final Rectangle roi) throws InterruptedException, ExecutionException {
    final int firstLayerIndex = layerset.getLayerIndex(layers.get(0).getId());
    final int lastLayerIndex = layerset.getLayerIndex(layers.get(layers.size() - 1).getId());
    // final PointMatchFilter filter = new RansacRegressionFilter();
    final PointMatchFilter filter = new RansacRegressionReduceFilter();
    /* collect patches */
    Utils.log("Collecting patches ... ");
    final ArrayList<Patch> patches = new ArrayList<Patch>();
    for (final Layer layer : layers) patches.addAll((Collection) layer.getDisplayables(Patch.class, roi));
    /* delete existing intensity coefficients */
    Utils.log("Clearing existing intensity maps ... ");
    for (final Patch p : patches) p.clearIntensityMap();
    /* generate coefficient tiles for all patches
		 * TODO consider offering alternative models */
    final HashMap<Patch, ArrayList<Tile<? extends M>>> coefficientsTiles = (HashMap) generateCoefficientsTiles(patches, new InterpolatedAffineModel1D<InterpolatedAffineModel1D<AffineModel1D, TranslationModel1D>, IdentityModel>(new InterpolatedAffineModel1D<AffineModel1D, TranslationModel1D>(new AffineModel1D(), new TranslationModel1D(), lambda1), new IdentityModel(), lambda2), numCoefficients * numCoefficients);
    /* completed patches */
    final HashSet<Patch> completedPatches = new HashSet<Patch>();
    /* collect patch pairs */
    Utils.log("Collecting patch pairs ... ");
    final ArrayList<ValuePair<Patch, Patch>> patchPairs = new ArrayList<ValuePair<Patch, Patch>>();
    for (final Patch p1 : patches) {
        completedPatches.add(p1);
        final Rectangle box1 = p1.getBoundingBox().intersection(roi);
        final ArrayList<Patch> p2s = new ArrayList<Patch>();
        /* across adjacent layers */
        final int layerIndex = layerset.getLayerIndex(p1.getLayer().getId());
        for (int i = Math.max(firstLayerIndex, layerIndex - radius); i <= Math.min(lastLayerIndex, layerIndex + radius); ++i) {
            final Layer layer = layerset.getLayer(i);
            if (layer != null)
                p2s.addAll((Collection) layer.getDisplayables(Patch.class, box1));
        }
        for (final Patch p2 : p2s) {
            /*
				 * if this patch had been processed earlier, all matches are
				 * already in
				 */
            if (completedPatches.contains(p2))
                continue;
            patchPairs.add(new ValuePair<Patch, Patch>(p1, p2));
        }
    }
    final int numThreads = Integer.parseInt(layerset.getProperty("n_mipmap_threads", Integer.toString(Runtime.getRuntime().availableProcessors())));
    Utils.log("Matching intensities using " + numThreads + " threads ... ");
    final ExecutorService exec = Executors.newFixedThreadPool(numThreads);
    final ArrayList<Future<?>> futures = new ArrayList<Future<?>>();
    for (final ValuePair<Patch, Patch> patchPair : patchPairs) {
        futures.add(exec.submit(new Matcher(roi, patchPair, (HashMap) coefficientsTiles, filter, scale, numCoefficients)));
    }
    for (final Future<?> future : futures) future.get();
    /* connect tiles within patches */
    Utils.log("Connecting coefficient tiles in the same patch  ... ");
    for (final Patch p1 : completedPatches) {
        /* get the coefficient tiles */
        final ArrayList<Tile<? extends M>> p1CoefficientsTiles = coefficientsTiles.get(p1);
        for (int y = 1; y < numCoefficients; ++y) {
            final int yr = numCoefficients * y;
            final int yr1 = yr - numCoefficients;
            for (int x = 0; x < numCoefficients; ++x) {
                identityConnect(p1CoefficientsTiles.get(yr1 + x), p1CoefficientsTiles.get(yr + x), neighborWeight);
            }
        }
        for (int y = 0; y < numCoefficients; ++y) {
            final int yr = numCoefficients * y;
            for (int x = 1; x < numCoefficients; ++x) {
                final int yrx = yr + x;
                identityConnect(p1CoefficientsTiles.get(yrx), p1CoefficientsTiles.get(yrx - 1), neighborWeight);
            }
        }
    }
    /* optimize */
    Utils.log("Optimizing ... ");
    final TileConfiguration tc = new TileConfiguration();
    for (final ArrayList<Tile<? extends M>> coefficients : coefficientsTiles.values()) {
        // for ( final Tile< ? > t : coefficients )
        // if ( t.getMatches().size() == 0 )
        // IJ.log( "bang" );
        tc.addTiles(coefficients);
    }
    try {
        tc.optimize(0.01f, iterations, iterations, 0.75f);
    } catch (final NotEnoughDataPointsException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (final IllDefinedDataPointsException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    /* save coefficients */
    final double[] ab = new double[2];
    final FSLoader loader = (FSLoader) layerset.getProject().getLoader();
    final String itsDir = loader.getUNUIdFolder() + "trakem2.its/";
    for (final Entry<Patch, ArrayList<Tile<? extends M>>> entry : coefficientsTiles.entrySet()) {
        final FloatProcessor as = new FloatProcessor(numCoefficients, numCoefficients);
        final FloatProcessor bs = new FloatProcessor(numCoefficients, numCoefficients);
        final Patch p = entry.getKey();
        final double min = p.getMin();
        final double max = p.getMax();
        final ArrayList<Tile<? extends M>> tiles = entry.getValue();
        for (int i = 0; i < numCoefficients * numCoefficients; ++i) {
            final Tile<? extends M> t = tiles.get(i);
            final Affine1D<?> affine = t.getModel();
            affine.toArray(ab);
            /* coefficients mapping into existing [min, max] */
            as.setf(i, (float) ab[0]);
            bs.setf(i, (float) ((max - min) * ab[1] + min - ab[0] * min));
        }
        final ImageStack coefficientsStack = new ImageStack(numCoefficients, numCoefficients);
        coefficientsStack.addSlice(as);
        coefficientsStack.addSlice(bs);
        final String itsPath = itsDir + FSLoader.createIdPath(Long.toString(p.getId()), "it", ".tif");
        new File(itsPath).getParentFile().mkdirs();
        IJ.saveAs(new ImagePlus("", coefficientsStack), "tif", itsPath);
    }
    /* update mipmaps */
    for (final Patch p : patches) p.getProject().getLoader().decacheImagePlus(p.getId());
    final ArrayList<Future<Boolean>> mipmapFutures = new ArrayList<Future<Boolean>>();
    for (final Patch p : patches) mipmapFutures.add(p.updateMipMaps());
    for (final Future<Boolean> f : mipmapFutures) f.get();
    Utils.log("Matching intensities done.");
}
Also used : NotEnoughDataPointsException(mpicbg.models.NotEnoughDataPointsException) HashMap(java.util.HashMap) ValuePair(net.imglib2.util.ValuePair) ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) InterpolatedAffineModel1D(mpicbg.models.InterpolatedAffineModel1D) IdentityModel(mpicbg.models.IdentityModel) TranslationModel1D(mpicbg.models.TranslationModel1D) HashSet(java.util.HashSet) FloatProcessor(ij.process.FloatProcessor) ImageStack(ij.ImageStack) IllDefinedDataPointsException(mpicbg.models.IllDefinedDataPointsException) Tile(mpicbg.models.Tile) Layer(ini.trakem2.display.Layer) ImagePlus(ij.ImagePlus) Point(mpicbg.models.Point) FSLoader(ini.trakem2.persistence.FSLoader) ExecutorService(java.util.concurrent.ExecutorService) Collection(java.util.Collection) InterpolatedAffineModel1D(mpicbg.models.InterpolatedAffineModel1D) AffineModel1D(mpicbg.models.AffineModel1D) Future(java.util.concurrent.Future) TileConfiguration(mpicbg.models.TileConfiguration) Patch(ini.trakem2.display.Patch) File(java.io.File)

Example 2 with FSLoader

use of ini.trakem2.persistence.FSLoader in project TrakEM2 by trakem2.

the class Patch method exportXML.

/**
 * Opens and closes the tag and exports data. The image is saved in the directory provided in @param any as a String.
 */
@Override
public void exportXML(final StringBuilder sb_body, final String indent, final XMLOptions options) {
    // TODO the Loader should handle the saving of images, not this class.
    final String in = indent + "\t";
    String path = null;
    String path2 = null;
    if (options.export_images) {
        path = options.patches_dir + title;
        // save image without overwriting, and add proper extension (.zip)
        path2 = project.getLoader().exportImage(this, path, false);
    // path2 will be null if the file exists already
    }
    sb_body.append(indent).append("<t2_patch\n");
    String rel_path = null;
    if (null != path && path.equals(path2)) {
        // this happens when a DB project is exported. It may be a different path when it's a FS loader
        // Utils.log2("p id=" + id + "  path==path2");
        rel_path = path2;
        // TrakEM2 uses paths that always have '/' and never '\', so using java.io.File.separatorChar would be an error.
        int i_slash = rel_path.lastIndexOf('/');
        if (i_slash > 0) {
            i_slash = rel_path.lastIndexOf('/', i_slash - 1);
            if (-1 != i_slash) {
                rel_path = rel_path.substring(i_slash + 1);
            }
        }
    } else {
        // Utils.log2("Setting rel_path to " + path2);
        rel_path = path2;
    }
    // For FSLoader projects, saving a second time will save images as null unless calling it
    if (null == rel_path) {
        // Utils.log2("path2 was null");
        final Object ob = project.getLoader().getPath(this);
        path2 = null == ob ? null : (String) ob;
        if (null == path2) {
            // Utils.log2("ERROR: No path for Patch id=" + id + " and title: " + title);
            // at least some clue for recovery
            rel_path = title;
        } else {
            rel_path = path2;
        }
    }
    // Utils.log("Patch path is: " + rel_path);
    super.exportXML(sb_body, in, options);
    final String[] RGB = Utils.getHexRGBColor(color);
    int type = this.type;
    if (-1 == this.type) {
        Utils.log2("Retrieving type for p = " + this);
        final ImagePlus imp = project.getLoader().fetchImagePlus(this);
        if (null != imp)
            type = imp.getType();
    }
    sb_body.append(in).append("type=\"").append(type).append("\"\n").append(in).append("file_path=\"").append(rel_path).append("\"\n").append(in).append("style=\"fill-opacity:").append(alpha).append(";stroke:#").append(RGB[0]).append(RGB[1]).append(RGB[2]).append(";\"\n").append(in).append("o_width=\"").append(o_width).append("\"\n").append(in).append("o_height=\"").append(o_height).append("\"\n");
    if (null != original_path) {
        sb_body.append(in).append("original_path=\"").append(original_path).append("\"\n");
    }
    sb_body.append(in).append("min=\"").append(min).append("\"\n");
    sb_body.append(in).append("max=\"").append(max).append("\"\n");
    final String pps = getPreprocessorScriptPath();
    if (null != pps)
        sb_body.append(in).append("pps=\"").append(project.getLoader().makeRelativePath(pps)).append("\"\n");
    sb_body.append(in).append("mres=\"").append(meshResolution).append("\"\n");
    if (hasCoordinateTransform()) {
        sb_body.append(in).append("ct_id=\"").append(ct_id).append("\"\n");
    }
    if (hasAlphaMask()) {
        sb_body.append(in).append("alpha_mask_id=\"").append(alpha_mask_id).append("\"\n");
    }
    sb_body.append(indent).append(">\n");
    if (hasCoordinateTransform()) {
        if (options.include_coordinate_transform) {
            // Write an XML entry for the CoordinateTransform
            char[] ct_chars = null;
            try {
                ct_chars = readCoordinateTransformFile();
            } catch (final Exception e) {
                IJError.print(e);
            }
            if (null != ct_chars) {
                sb_body.append(ct_chars).append('\n');
            } else {
                Utils.log("ERROR: could not write the CoordinateTransform to the XML file!");
            }
        }
    }
    if (null != filters && filters.length > 0) {
        // specify their own line termination
        for (final IFilter f : filters) sb_body.append(f.toXML(in));
    }
    super.restXML(sb_body, in, options);
    sb_body.append(indent).append("</t2_patch>\n");
}
Also used : IFilter(ini.trakem2.imaging.filters.IFilter) ImagePlus(ij.ImagePlus) NoninvertibleModelException(mpicbg.models.NoninvertibleModelException) NoninvertibleTransformException(java.awt.geom.NoninvertibleTransformException) IOException(java.io.IOException)

Example 3 with FSLoader

use of ini.trakem2.persistence.FSLoader in project TrakEM2 by trakem2.

the class FSLoader method deleteStaleFiles.

/**
 * Delete stale files under the {@link FSLoader#unuid} folder.
 * These include "*.ct" files (for {@link CoordinateTransform})
 * and "*.zip" files (for alpha mask images) that are not referenced from any {@link Patch}.
 */
@Override
public boolean deleteStaleFiles(boolean coordinate_transforms, boolean alpha_masks) {
    boolean b = true;
    final Project project = Project.findProject(this);
    if (coordinate_transforms)
        b = b && StaleFiles.deleteCoordinateTransforms(project);
    if (alpha_masks)
        b = b && StaleFiles.deleteAlphaMasks(project);
    return b;
}
Also used : Project(ini.trakem2.Project)

Example 4 with FSLoader

use of ini.trakem2.persistence.FSLoader in project TrakEM2 by trakem2.

the class Project method newFSProject.

public static Project newFSProject(String arg, TemplateThing template_root, String storage_folder, boolean autocreate_one_layer) {
    if (Utils.wrongImageJVersion())
        return null;
    FSLoader loader = null;
    try {
        String dir_project = storage_folder;
        if (null == dir_project || !new File(dir_project).isDirectory()) {
            DirectoryChooser dc = new DirectoryChooser("Select storage folder");
            dir_project = dc.getDirectory();
            // user cancelled dialog
            if (null == dir_project)
                return null;
            if (!Loader.canReadAndWriteTo(dir_project)) {
                Utils.showMessage("Can't read/write to the selected storage folder.\nPlease check folder permissions.");
                return null;
            }
            if (IJ.isWindows())
                dir_project = dir_project.replace('\\', '/');
        }
        loader = new FSLoader(dir_project);
        Project project = createNewProject(loader, !("blank".equals(arg) || "amira".equals(arg)), template_root);
        // help the helpless users:
        if (autocreate_one_layer && null != project && ControlWindow.isGUIEnabled()) {
            Utils.log2("Creating automatic Display.");
            // add a default layer
            Layer layer = new Layer(project, 0, 1, project.layer_set);
            project.layer_set.add(layer);
            project.layer_tree.addLayer(project.layer_set, layer);
            layer.recreateBuckets();
            Display.createDisplay(project, layer);
        }
        try {
            // waiting cheaply for asynchronous swing calls
            Thread.sleep(200);
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
        if ("amira".equals(arg) || "stack".equals(arg)) {
            // forks into a task thread
            loader.importStack(project.layer_set.getLayer(0), null, true);
        }
        project.restartAutosaving();
        return project;
    } catch (Exception e) {
        IJError.print(e);
        if (null != loader)
            loader.destroy();
    }
    return null;
}
Also used : FSLoader(ini.trakem2.persistence.FSLoader) JarFile(java.util.jar.JarFile) File(java.io.File) Layer(ini.trakem2.display.Layer) DirectoryChooser(ij.io.DirectoryChooser)

Example 5 with FSLoader

use of ini.trakem2.persistence.FSLoader in project TrakEM2 by trakem2.

the class Project method createSubproject.

/**
 * Create a new subproject for the given layer range and ROI.
 *   Create a new Project using the given project as template. This means the DTD of the given project is copied, as well as the storage and mipmaps folders; everything else is empty in the new project.
 */
public Project createSubproject(final Rectangle roi, final Layer first, final Layer last, final boolean ignore_hidden_patches) {
    try {
        // The order matters.
        final Project pr = new Project(new FSLoader(this.getLoader().getStorageFolder()));
        pr.id = this.id;
        // copy properties
        pr.title = this.title;
        pr.ht_props.putAll(this.ht_props);
        // copy template
        pr.root_tt = this.root_tt.clone(pr, true);
        pr.template_tree = new TemplateTree(pr, pr.root_tt);
        synchronized (pr.ht_unique_tt) {
            pr.ht_unique_tt.clear();
            pr.ht_unique_tt.putAll(root_tt.getUniqueTypes(new HashMap<String, TemplateThing>()));
        }
        TemplateThing project_template = new TemplateThing("project");
        project_template.addChild(pr.root_tt);
        pr.ht_unique_tt.put("project", project_template);
        // create the layers templates
        pr.createLayerTemplates();
        // copy LayerSet and all involved Displayable objects
        // (A two-step process to provide the layer_set pointer and all Layer pointers to the ZDisplayable to copy and crop.)
        pr.layer_set = (LayerSet) this.layer_set.clone(pr, first, last, roi, false, true, ignore_hidden_patches);
        LayerSet.cloneInto(this.layer_set, first, last, pr, pr.layer_set, roi, true);
        // create layer tree
        pr.root_lt = new LayerThing(Project.layer_set_template, pr, pr.layer_set);
        pr.layer_tree = new LayerTree(pr, pr.root_lt);
        // add layer nodes to the layer tree (solving chicken-and-egg problem)
        pr.layer_set.updateLayerTree();
        // copy project tree
        pr.root_pt = this.root_pt.subclone(pr);
        pr.project_tree = new ProjectTree(pr, pr.root_pt);
        // not copying node expanded state.
        // register
        al_open_projects.add(pr);
        // add to gui:
        ControlWindow.add(pr, pr.template_tree, pr.project_tree, pr.layer_tree);
        // Above, the id of each object is preserved from this project into the subproject.
        // The abstract structure should be copied in full regardless, without the basic objects
        // included if they intersect the roi.
        // Regenerate mipmaps (blocks GUI from interaction other than navigation)
        pr.loader.regenerateMipMaps(pr.layer_set.getDisplayables(Patch.class));
        pr.restartAutosaving();
        return pr;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
Also used : FSLoader(ini.trakem2.persistence.FSLoader) LayerTree(ini.trakem2.tree.LayerTree) ProjectTree(ini.trakem2.tree.ProjectTree) HashMap(java.util.HashMap) LayerThing(ini.trakem2.tree.LayerThing) TemplateTree(ini.trakem2.tree.TemplateTree) TemplateThing(ini.trakem2.tree.TemplateThing) Patch(ini.trakem2.display.Patch)

Aggregations

FSLoader (ini.trakem2.persistence.FSLoader)7 HashMap (java.util.HashMap)6 File (java.io.File)5 ArrayList (java.util.ArrayList)5 Patch (ini.trakem2.display.Patch)4 ImagePlus (ij.ImagePlus)3 Project (ini.trakem2.Project)3 Displayable (ini.trakem2.display.Displayable)3 Layer (ini.trakem2.display.Layer)3 ZDisplayable (ini.trakem2.display.ZDisplayable)3 LayerThing (ini.trakem2.tree.LayerThing)3 TemplateThing (ini.trakem2.tree.TemplateThing)3 Map (java.util.Map)3 LayerSet (ini.trakem2.display.LayerSet)2 DBObject (ini.trakem2.persistence.DBObject)2 LayerTree (ini.trakem2.tree.LayerTree)2 ProjectThing (ini.trakem2.tree.ProjectThing)2 ProjectTree (ini.trakem2.tree.ProjectTree)2 TemplateTree (ini.trakem2.tree.TemplateTree)2 Rectangle (java.awt.Rectangle)2