diff --git a/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/AffineDistributedSolver.java b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/AffineDistributedSolver.java index a99c8d4bc..5525ba7a9 100644 --- a/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/AffineDistributedSolver.java +++ b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/AffineDistributedSolver.java @@ -13,6 +13,7 @@ import org.janelia.render.client.newsolver.assembly.Assembler; import org.janelia.render.client.newsolver.assembly.ZBlockSolver; import org.janelia.render.client.newsolver.assembly.matches.SameTileMatchCreatorAffine2D; +import org.janelia.render.client.newsolver.assembly.matches.SameTileMatchCreatorAffineIntensity; import org.janelia.render.client.newsolver.blockfactories.ZBlockFactory; import org.janelia.render.client.newsolver.blocksolveparameters.FIBSEMAlignmentParameters; import org.janelia.render.client.newsolver.setup.AffineSolverSetup; @@ -24,9 +25,11 @@ import org.slf4j.LoggerFactory; import mpicbg.models.Affine2D; +import mpicbg.models.AffineModel1D; import mpicbg.models.AffineModel2D; import mpicbg.models.Model; import mpicbg.models.RigidModel2D; +import mpicbg.models.TranslationModel1D; public class AffineDistributedSolver { @@ -150,17 +153,27 @@ public static void main( final String[] args ) throws IOException LOG.info( "computed " + allItems.size() + " blocks, maxId=" + maxId); - final ZBlockSolver< RigidModel2D, AffineModel2D > solver = + /* + final ZBlockSolver< List< AffineModel1D >, TranslationModel1D, List< AffineModel1D > > solver1D = + new ZBlockSolver<>( + new TranslationModel1D(), + new SameTileMatchCreatorAffineIntensity(), + cmdLineSetup.maxPlateauWidthGlobal, + cmdLineSetup.maxAllowedErrorGlobal, + cmdLineSetup.maxIterationsGlobal, + cmdLineSetup.threadsGlobal ); + */ + + final ZBlockSolver< AffineModel2D, RigidModel2D, AffineModel2D > solver = new ZBlockSolver<>( new RigidModel2D(), - new AffineModel2D(), - new SameTileMatchCreatorAffine2D<>(), + new SameTileMatchCreatorAffine2D(), cmdLineSetup.maxPlateauWidthGlobal, cmdLineSetup.maxAllowedErrorGlobal, cmdLineSetup.maxIterationsGlobal, cmdLineSetup.threadsGlobal ); - final Assembler< RigidModel2D, AffineModel2D, ZBlockFactory > assembler = new Assembler<>( allItems, solver ); + final Assembler< AffineModel2D, RigidModel2D, AffineModel2D, ZBlockFactory > assembler = new Assembler<>( allItems, solver ); assembler.createAssembly(); /* diff --git a/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/Assembler.java b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/Assembler.java index 7a667b095..849875057 100644 --- a/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/Assembler.java +++ b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/Assembler.java @@ -8,10 +8,19 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class Assembler< M, R, F extends BlockFactory< F > > +/** + * + * @author preibischs + * + * @param - the final output for each TileSpec + * @param - model used for global solve + * @param - the result from the block solves + * @param - the blockFactory that was used + */ +public class Assembler< Z, G, R, F extends BlockFactory< F > > { final List > blocks; - final BlockSolver< M, R, F > blockSolver; + final BlockSolver< Z, G, R, F > blockSolver; /** * @param blocks - all individually computed blocks @@ -19,21 +28,21 @@ public class Assembler< M, R, F extends BlockFactory< F > > */ public Assembler( final List > blocks, - final BlockSolver< M, R, F > blockSolver ) + final BlockSolver< Z, G, R, F > blockSolver ) { this.blocks = blocks; this.blockSolver = blockSolver; } - public AssemblyMaps< M > createAssembly() + public AssemblyMaps< Z > createAssembly() { - AssemblyMaps< M > am; + AssemblyMaps< Z > am; // the trivial case of a single block, would crash with the code below if ( ( am = handleTrivialCase() ) != null ) return am; else - am = new AssemblyMaps< M >(); + am = new AssemblyMaps< Z >(); // now compute the final alignment for each block try @@ -57,13 +66,13 @@ public AssemblyMaps< M > createAssembly() * * @return - the result of the trivial case if it was a single block */ - protected AssemblyMaps< M > handleTrivialCase() + protected AssemblyMaps< Z > handleTrivialCase() { if ( blocks.size() == 1 ) { LOG.info( "Assembler: only a single block, no solve across blocks necessary." ); - final AssemblyMaps< M > am = new AssemblyMaps<>(); + final AssemblyMaps< Z > am = new AssemblyMaps<>(); final BlockData< ?, R, ?, F > solveItem = blocks.get( 0 ); @@ -83,7 +92,7 @@ protected AssemblyMaps< M > handleTrivialCase() am.zToTileIdGlobal.get( z ).add( tileId ); am.idToTileSpecGlobal.put( tileId, solveItem.rtsc().getTileSpec( tileId ) ); - // TODO: Converter from R to M + // TODO: Converter from R to Z //am.idToFinalModelGlobal.put( tileId, solveItem.idToNewModel().get( tileId ) ); } } diff --git a/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/BlockFusion.java b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/BlockFusion.java index 238a43079..097459326 100644 --- a/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/BlockFusion.java +++ b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/BlockFusion.java @@ -5,9 +5,9 @@ import org.janelia.render.client.newsolver.BlockData; import org.janelia.render.client.newsolver.blockfactories.BlockFactory; -public interface BlockFusion< R, F extends BlockFactory< F > > +public interface BlockFusion< Z, G, R, F extends BlockFactory< F > > { public void globalFusion( List< ? extends BlockData > blocks, - AssemblyMaps< ? > am ); + AssemblyMaps< Z > am ); } diff --git a/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/BlockSolver.java b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/BlockSolver.java index e10cd99c3..cdda94115 100644 --- a/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/BlockSolver.java +++ b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/BlockSolver.java @@ -9,18 +9,18 @@ import mpicbg.models.IllDefinedDataPointsException; import mpicbg.models.NotEnoughDataPointsException; -public abstract class BlockSolver< M, R, F extends BlockFactory< F > > +public abstract class BlockSolver< Z, G, R, F extends BlockFactory< F > > { - final private M globalModel; + final private G globalModel; - public BlockSolver( final M globalModel ) + public BlockSolver( final G globalModel ) { this.globalModel = globalModel; } - public M globalModel() { return globalModel; } + public G globalSolveModel() { return globalModel; } public abstract void globalSolve( List< ? extends BlockData > blocks, - AssemblyMaps< M > am ) throws NotEnoughDataPointsException, IllDefinedDataPointsException, InterruptedException, ExecutionException; + AssemblyMaps< Z > am ) throws NotEnoughDataPointsException, IllDefinedDataPointsException, InterruptedException, ExecutionException; } diff --git a/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/ZBlockFusion.java b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/ZBlockFusion.java new file mode 100644 index 000000000..601e3ea7d --- /dev/null +++ b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/ZBlockFusion.java @@ -0,0 +1,17 @@ +package org.janelia.render.client.newsolver.assembly; + +import java.util.List; + +import org.janelia.render.client.newsolver.BlockData; +import org.janelia.render.client.newsolver.blockfactories.ZBlockFactory; + +public class ZBlockFusion< Z, G, R > implements BlockFusion< Z, G, R, ZBlockFactory > +{ + + @Override + public void globalFusion(List> blocks, AssemblyMaps am) { + // TODO Auto-generated method stub + + } + +} diff --git a/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/ZBlockSolver.java b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/ZBlockSolver.java index 164ee2729..ed93541d4 100644 --- a/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/ZBlockSolver.java +++ b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/ZBlockSolver.java @@ -24,10 +24,9 @@ import net.imglib2.util.Pair; import net.imglib2.util.ValuePair; -public class ZBlockSolver< M extends Model< M >, R > extends BlockSolver< M, R, ZBlockFactory > +public class ZBlockSolver< Z, G extends Model< G >, R > extends BlockSolver< Z, G, R, ZBlockFactory > { - final M globalModel; - final R resultModel; + final G globalModel; final SameTileMatchCreator< R > sameTileMatchCreator; final int maxPlateauWidth; @@ -36,8 +35,7 @@ public class ZBlockSolver< M extends Model< M >, R > extends BlockSolver< M, R, final int numThreads; public ZBlockSolver( - final M globalModel, - final R resultModel, + final G globalModel, final SameTileMatchCreator< R > sameTileMatchCreator, final int maxPlateauWidth, final double maxAllowedError, @@ -47,7 +45,6 @@ public ZBlockSolver( super( globalModel ); this.globalModel = globalModel; - this.resultModel = resultModel; this.sameTileMatchCreator = sameTileMatchCreator; this.maxPlateauWidth = maxPlateauWidth; this.maxAllowedError = maxAllowedError; @@ -58,7 +55,7 @@ public ZBlockSolver( @Override public void globalSolve( final List< ? extends BlockData > blocks, - final AssemblyMaps< M > am ) throws NotEnoughDataPointsException, IllDefinedDataPointsException, InterruptedException, ExecutionException + final AssemblyMaps< Z > am ) throws NotEnoughDataPointsException, IllDefinedDataPointsException, InterruptedException, ExecutionException { // local structures required for solvig final HashMap< @@ -72,7 +69,7 @@ public void globalSolve( final TileConfiguration tileConfigBlocks = new TileConfiguration(); - final HashMap< BlockData, Tile< M > > blockToTile = new HashMap<>(); + final HashMap< BlockData, Tile< G > > blockToTile = new HashMap<>(); // important: all images within one block must be connected to each other! @@ -82,7 +79,7 @@ public void globalSolve( for ( int a = 0; a < blocks.size() - 1; ++a ) { final BlockData solveItemA = blocks.get( a ); - blockToTile.putIfAbsent( solveItemA, new Tile( globalModel.copy() ) ); + blockToTile.putIfAbsent( solveItemA, new Tile< G >( globalModel.copy() ) ); for ( int z = solveItemA.minZ(); z <= solveItemA.maxZ(); ++z ) { @@ -94,7 +91,7 @@ public void globalSolve( for ( int b = a + 1; b < blocks.size(); ++b ) { final BlockData solveItemB = blocks.get( b ); - blockToTile.putIfAbsent( solveItemB, new Tile( globalModel.copy() ) ); + blockToTile.putIfAbsent( solveItemB, new Tile< G >( globalModel.copy() ) ); LOG.info( "globalSolve: solveItemB z range is {} to {}", solveItemB.minZ(), solveItemB.maxZ()); @@ -147,8 +144,8 @@ public void globalSolve( sameTileMatchCreator.addMatches( tileSpecAB, modelA, modelB, matchesAtoB ); } - final Tile< M > tileA = blockToTile.get( solveItemA ); - final Tile< M > tileB = blockToTile.get( solveItemB ); + final Tile< G > tileA = blockToTile.get( solveItemA ); + final Tile< G > tileB = blockToTile.get( solveItemB ); tileA.connect( tileB, matchesAtoB ); @@ -194,7 +191,7 @@ public void globalSolve( final BlockData solveItemB = null; //solveItemA.createCorrespondingDummySolveItem( id, z ); zToBlockPairs.get( z ).add( new ValuePair<>( new ValuePair<>( solveItemA, solveItemB ), tileIds ) ); - blockToTile.putIfAbsent( solveItemB, new Tile( globalModel.copy() ) ); + blockToTile.putIfAbsent( solveItemB, new Tile< G >( globalModel.copy() ) ); //++id; diff --git a/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/matches/SameTileMatchCreatorAffineIntensity.java b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/matches/SameTileMatchCreatorAffineIntensity.java new file mode 100644 index 000000000..f950b0edd --- /dev/null +++ b/render-ws-java-client/src/main/java/org/janelia/render/client/newsolver/assembly/matches/SameTileMatchCreatorAffineIntensity.java @@ -0,0 +1,50 @@ +package org.janelia.render.client.newsolver.assembly.matches; + +import java.util.List; + +import org.janelia.alignment.spec.TileSpec; + +import mpicbg.models.Affine2D; +import mpicbg.models.AffineModel1D; +import mpicbg.models.Point; +import mpicbg.models.PointMatch; + +public class SameTileMatchCreatorAffineIntensity implements SameTileMatchCreator< List< AffineModel1D > > +{ + final int samplesPerDimension; + + public SameTileMatchCreatorAffineIntensity( final int samplesPerDimension ) + { + this.samplesPerDimension = samplesPerDimension; + } + + public SameTileMatchCreatorAffineIntensity() { this( 2 ); } + + @Override + public void addMatches(TileSpec tileSpec, List< AffineModel1D > modelA, List< AffineModel1D > modelB, List matchesAtoB) + { + // TODO: make 64 matches that map A to p and B to q + + /* + // make a regular grid + final double sampleWidth = (tileSpec.getWidth() - 1.0) / (samplesPerDimension - 1.0); + final double sampleHeight = (tileSpec.getHeight() - 1.0) / (samplesPerDimension - 1.0); + + for (int y = 0; y < samplesPerDimension; ++y) + { + final double sampleY = y * sampleHeight; + for (int x = 0; x < samplesPerDimension; ++x) + { + final double[] p = new double[] { x * sampleWidth, sampleY }; + final double[] q = new double[] { x * sampleWidth, sampleY }; + + modelA.applyInPlace( p ); + modelB.applyInPlace( q ); + + matchesAtoB.add(new PointMatch( new Point(p), new Point(q) )); + } + } + */ + } + +}