diff --git a/pom.xml b/pom.xml index 43d91eae..544f6e61 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ org.embl.mobie mobie-viewer-fiji - 5.0.11 + 5.1.0 diff --git a/src/main/java/org/embl/mobie/MoBIE.java b/src/main/java/org/embl/mobie/MoBIE.java index 89d2e3ff..50a8eec4 100644 --- a/src/main/java/org/embl/mobie/MoBIE.java +++ b/src/main/java/org/embl/mobie/MoBIE.java @@ -38,12 +38,10 @@ import net.imagej.ImageJ; import org.embl.mobie.io.ImageDataFormat; import org.embl.mobie.io.imagedata.ImageData; +import org.embl.mobie.io.util.IOHelper; import org.embl.mobie.io.util.S3Utils; import org.embl.mobie.lib.*; -import org.embl.mobie.lib.files.FileSourcesDataSetter; -import org.embl.mobie.lib.files.ImageFileSources; -import org.embl.mobie.lib.files.LabelFileSources; -import org.embl.mobie.lib.files.SourcesFromPathsCreator; +import org.embl.mobie.lib.data.*; import org.embl.mobie.lib.hcs.HCSPlateAdder; import org.embl.mobie.lib.hcs.Plate; import org.embl.mobie.lib.hcs.Site; @@ -97,7 +95,7 @@ public class MoBIE public static ImageJ imageJ; private String projectLocation; - private MoBIESettings settings; + private MoBIESettings settings = new MoBIESettings(); private Project project; private Dataset dataset; private String projectRoot = ""; @@ -151,13 +149,13 @@ public MoBIE( List< String > imagePaths, List< String > labelPaths, List< String this.settings = settings; - final SourcesFromPathsCreator sourcesCreator = new SourcesFromPathsCreator( imagePaths, labelPaths, labelTablePaths, root, grid ); + final GridSourcesFromPathsCreator sourcesCreator = new GridSourcesFromPathsCreator( imagePaths, labelPaths, labelTablePaths, root, grid ); - final List< ImageFileSources > imageSources = sourcesCreator.getImageSources(); - final List< LabelFileSources > labelSources = sourcesCreator.getLabelSources(); + final List< ImageGridSources > imageSources = sourcesCreator.getImageSources(); + final List< LabelGridSources > labelSources = sourcesCreator.getLabelSources(); Table regionTable = sourcesCreator.getRegionTable(); - openImagesAndLabels( imageSources, labelSources, regionTable ); + openImageAndLabelGrids( imageSources, labelSources, regionTable ); } // open an image or object table @@ -177,11 +175,31 @@ public MoBIE( String tablePath, List< String > imageColumns, List< String > labe // Both can be useful and I guess we should keep on supporting both final SourcesFromTableCreator sourcesCreator = new SourcesFromTableCreator( tablePath, imageColumns, labelColumns, root, pathMapping, grid ); - final List< ImageFileSources > imageSources = sourcesCreator.getImageSources(); - final List< LabelFileSources > labelSources = sourcesCreator.getLabelSources(); + final List< ImageGridSources > imageSources = sourcesCreator.getImageSources(); + final List< LabelGridSources > labelSources = sourcesCreator.getLabelSources(); Table regionTable = sourcesCreator.getRegionTable(); - openImagesAndLabels( imageSources, labelSources, regionTable ); + openImageAndLabelGrids( imageSources, labelSources, regionTable ); + } + + // Open a MoBIE table with MoBIETableColumnNames + // TODO: get rid of the boolean with for now is just not to have the same signature twice + public MoBIE( String tablePath, MoBIESettings settings, boolean isMoBIETable ) + { + settings = settings; + + IJ.log("\n# MoBIE" ); + IJ.log("Opening data from table: " + tablePath ); + + final Table table = TableOpener.openDelimitedTextFile( tablePath ); + + initImageJAndMoBIE(); + initProject( IOHelper.getFileName( tablePath ) ); + + TableSourcesDataSetter dataSetter = new TableSourcesDataSetter( table ); + dataSetter.addToDataset( dataset ); + + initUiAndShowView( null ); } private void initTableSaw() @@ -205,13 +223,13 @@ private void openMoBIEProject() throws IOException } // TODO 2D or 3D? - private void openImagesAndLabels( List< ImageFileSources > images, List< LabelFileSources > labels, Table regionTable ) + private void openImageAndLabelGrids( List< ImageGridSources > images, List< LabelGridSources > labels, Table regionTable ) { initImageJAndMoBIE(); initProject( "" ); - new FileSourcesDataSetter( images, labels, regionTable ).addDataAndDisplaysAndViews( dataset ); + new GridSourcesDataSetter( images, labels, regionTable ).addDataAndDisplaysAndViews( dataset ); initUiAndShowView( null ); //dataset.views().keySet().iterator().next() ); } @@ -239,8 +257,7 @@ private void initImageJAndMoBIE() if ( settings.values.isOpenedFromCLI() ) { - // TODO: if possible open init the SciJava Services - // by different means + // TODO: if possible init the SciJava Services by different means imageJ = new ImageJ(); // Init SciJava Services imageJ.ui().showUI(); // Enable SciJava Command rendering } diff --git a/src/main/java/org/embl/mobie/command/context/ScreenShotMakerCommand.java b/src/main/java/org/embl/mobie/command/context/ScreenShotMakerCommand.java index 745eb578..0429a0b0 100644 --- a/src/main/java/org/embl/mobie/command/context/ScreenShotMakerCommand.java +++ b/src/main/java/org/embl/mobie/command/context/ScreenShotMakerCommand.java @@ -54,7 +54,12 @@ public class ScreenShotMakerCommand extends DynamicCommand implements BdvPlaygro @Parameter public BdvHandle bdvHandle; - @Parameter(label="Sampling (in below units)", persist = false, callback = "showNumPixels", min = "0.0", style="format:#.00000", stepSize = "0.01") + @Parameter(label="Sampling (in below units)", + persist = false, + callback = "showNumPixels", + min = "0.0", + style="format:#.00000", + stepSize = "0.01") public Double targetSamplingInXY = 1D; @Parameter(label="Pixel unit", persist = false, choices = {"micrometer"} ) diff --git a/src/main/java/org/embl/mobie/command/context/SourcesInfoCommand.java b/src/main/java/org/embl/mobie/command/context/SourcesInfoCommand.java index 9bfc9d24..bc17a01c 100644 --- a/src/main/java/org/embl/mobie/command/context/SourcesInfoCommand.java +++ b/src/main/java/org/embl/mobie/command/context/SourcesInfoCommand.java @@ -32,10 +32,13 @@ import bdv.viewer.Source; import bdv.viewer.SourceAndConverter; import ij.IJ; +import net.imglib2.realtransform.AffineTransform3D; import org.embl.mobie.DataStore; import org.embl.mobie.command.CommandConstants; import org.embl.mobie.lib.MoBIEHelper; import org.embl.mobie.lib.image.Image; +import org.embl.mobie.lib.io.ImageDataInfo; +import org.embl.mobie.lib.serialize.transformation.AffineTransformation; import org.embl.mobie.lib.serialize.transformation.Transformation; import org.embl.mobie.lib.transform.TransformHelper; import org.scijava.plugin.Parameter; @@ -46,7 +49,8 @@ import java.util.Arrays; import java.util.List; -@Plugin(type = BdvPlaygroundActionCommand.class, menuPath = CommandConstants.CONTEXT_MENU_ITEMS_ROOT + "Log Images Info") +@Plugin(type = BdvPlaygroundActionCommand.class, + menuPath = CommandConstants.CONTEXT_MENU_ITEMS_ROOT + "Log Images Info") public class SourcesInfoCommand implements BdvPlaygroundActionCommand { static { net.imagej.patcher.LegacyInjector.preinit(); } @@ -54,31 +58,50 @@ public class SourcesInfoCommand implements BdvPlaygroundActionCommand @Parameter public BdvHandle bdvHandle; + @Parameter (label = "Show transformation history") + public Boolean showTransformationHistory = false; + @Override public void run() { + int t = bdvHandle.getViewerPanel().state().getCurrentTimepoint(); List< SourceAndConverter< ? > > visibleSacs = MoBIEHelper.getVisibleSacs( bdvHandle ); visibleSacs.forEach( sac -> { + Image< ? > image = DataStore.sourceToImage().get( sac ); + ImageDataInfo imageDataInfo = MoBIEHelper.fetchImageDataInfo( image ); + Source< ? > source = sac.getSpimSource(); + AffineTransform3D transform3D = new AffineTransform3D(); + sac.getSpimSource().getSourceTransform( t, 0, transform3D ); + IJ.log( "" ); IJ.log( "# " + source.getName() ); - IJ.log( "" ); + IJ.log( "Source URI: " + imageDataInfo.uri ); + IJ.log( "Dataset index within URI: " + imageDataInfo.datasetId ); IJ.log( "Data type: " + source.getType().getClass().getSimpleName() ); - IJ.log( "Shape: " + Arrays.toString( source.getSource( 0,0 ).dimensionsAsLongArray() ) ); + IJ.log( "Shape: " + Arrays.toString( source.getSource( t,0 ).dimensionsAsLongArray() ) ); IJ.log( "Number of resolution levels: " + source.getNumMipmapLevels() ); IJ.log( "Voxel size: " + Arrays.toString( source.getVoxelDimensions().dimensionsAsDoubleArray() ) ); - Image< ? > image = DataStore.sourceToImage().get( sac ); ArrayList< Transformation > transformations = TransformHelper.fetchAllImageTransformations( image ); - - transformations.forEach( transformation -> + Transformation imageTransformation = transformations.get( 0 ); + if ( imageTransformation instanceof AffineTransformation ) { - IJ.log( "" ); - IJ.log( transformation.toString() ); - }); + AffineTransform3D imageTransform = ( ( AffineTransformation ) imageTransformation ).getAffineTransform3D(); + IJ.log( "Original image transformation: " + MoBIEHelper.print( imageTransform.getRowPackedCopy(), 3 ) ); + AffineTransform3D additionalTransform = transform3D.copy().concatenate( imageTransform.inverse() ); + IJ.log( "Additional MoBIE transformation: " + MoBIEHelper.print( additionalTransform.getRowPackedCopy(), 3 ) ); + IJ.log( "Total transformation: " + MoBIEHelper.print( transform3D.getRowPackedCopy(), 3 ) ); + } - IJ.log( "" ); + if ( showTransformationHistory ) + { + transformations.forEach( transformation -> + { + IJ.log( transformation.toString() ); + } ); + } }); } } diff --git a/src/main/java/org/embl/mobie/lib/ImageDataAdder.java b/src/main/java/org/embl/mobie/lib/ImageDataAdder.java index bec52987..bf73796c 100644 --- a/src/main/java/org/embl/mobie/lib/ImageDataAdder.java +++ b/src/main/java/org/embl/mobie/lib/ImageDataAdder.java @@ -81,7 +81,6 @@ public void addData( Dataset dataset, MoBIESettings settings ) private void addData( ImageData< ? > imageData, boolean isSegmentation ) { - final ImageDataFormat imageDataFormat = ImageDataFormat.ImageData; if ( tableDataFormat != null ) @@ -153,7 +152,7 @@ private void addImageView( ImageData< ? > imageData, int datasetIndex, String im dataset.views().put( view.getName(), view ); } - private void addSegmentationView( ImageData< ? > imageData, int setupId, String name ) + private void addSegmentationView( ImageData< ? > imageData, int setupId, String name ) { final SegmentationDisplay< ? > display = new SegmentationDisplay<>( name, Arrays.asList( name ) ); final double pixelWidth = imageData.getSourcePair( setupId ).getB().getVoxelDimensions().dimension( 0 ); diff --git a/src/main/java/org/embl/mobie/lib/MoBIEHelper.java b/src/main/java/org/embl/mobie/lib/MoBIEHelper.java index e044dac2..f0c514b4 100644 --- a/src/main/java/org/embl/mobie/lib/MoBIEHelper.java +++ b/src/main/java/org/embl/mobie/lib/MoBIEHelper.java @@ -32,15 +32,13 @@ import bdv.viewer.SourceAndConverter; import mpicbg.spim.data.sequence.FinalVoxelDimensions; import mpicbg.spim.data.sequence.VoxelDimensions; -import net.imglib2.Cursor; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.type.numeric.RealType; -import net.imglib2.util.Intervals; -import net.imglib2.util.ValuePair; -import net.imglib2.view.Views; import org.embl.mobie.io.ImageDataOpener; import org.embl.mobie.io.github.GitHubUtils; import org.embl.mobie.io.imagedata.ImageData; +import org.embl.mobie.lib.image.Image; +import org.embl.mobie.lib.image.ImageDataImage; +import org.embl.mobie.lib.image.TransformedImage; +import org.embl.mobie.lib.io.ImageDataInfo; import org.janelia.saalfeldlab.n5.universe.metadata.canonical.CanonicalDatasetMetadata; import sc.fiji.bdvpg.scijava.services.SourceAndConverterBdvDisplayService; import sc.fiji.bdvpg.services.SourceAndConverterServices; @@ -61,6 +59,29 @@ public abstract class MoBIEHelper { + public static ImageDataInfo fetchImageDataInfo( Image< ? > image ) + { + if ( image instanceof ImageDataImage ) + { + ImageDataInfo imageDataInfo = new ImageDataInfo(); + imageDataInfo.uri = ( ( ImageDataImage ) image ).getUri(); + imageDataInfo.datasetId = ( ( ImageDataImage ) image ).getSetupId(); + return imageDataInfo; + } + else if ( image instanceof TransformedImage ) + { + TransformedImage transformedImage = ( TransformedImage ) image; + Image< ? > wrappedImage = transformedImage.getWrappedImage(); + return fetchImageDataInfo( wrappedImage ); + } + else + { + ImageDataInfo imageDataInfo = new ImageDataInfo(); + imageDataInfo.uri = "Could not determine URI of " + image.getClass().getSimpleName(); + return imageDataInfo; + } + } + public static final String GRID_TYPE_HELP = "If the images are different and not too many, use Transformed for more flexible visualisation.\n" + "If all images are identical use Stitched for better performance."; @@ -73,12 +94,17 @@ public static String print(double[] array, int numSignificantDigits) { DecimalFormat formatter = new DecimalFormat(pattern.toString()); StringBuilder result = new StringBuilder(); + result.append( "(" ); for (int i = 0; i < array.length; i++) { + if (Math.abs(array[i]) < 1e-10) { + array[i] = 0.0; // Explicitly set to zero to remove negative sign + } result.append(formatter.format(array[i])); if (i < array.length - 1) { result.append(", "); } } + result.append( ")" ); return result.toString(); } @@ -311,47 +337,6 @@ public static List< String > getFullPaths( String regex, String root ) } } - public static double[] estimateMinMax( - RandomAccessibleInterval > rai) - { - Cursor> cursor = Views.iterable(rai).cursor(); - if (!cursor.hasNext()) return new double[]{0, 255}; - long stepSize = Intervals.numElements(rai) / 10000 + 1; - int randomLimit = (int) Math.min(Integer.MAX_VALUE, stepSize); - Random random = new Random(42); - double min = cursor.next().getRealDouble(); - double max = min; - while (cursor.hasNext()) { - double value = cursor.get().getRealDouble(); - cursor.jumpFwd(stepSize + random.nextInt(randomLimit)); - min = Math.min(min, value); - max = Math.max(max, value); - } - return new double[]{min, max}; - } - - public static > double[] computeMinMax( RandomAccessibleInterval rai) { - Cursor cursor = Views.iterable(rai).cursor(); - - // Initialize min and max with the first element - T type = cursor.next(); - T min = type.copy(); - T max = type.copy(); - - // Iterate over the remaining elements to find min and max - while (cursor.hasNext()) { - type = cursor.next(); - if (type.compareTo(min) < 0) { - min.set(type); - } - if (type.compareTo(max) > 0) { - max.set(type); - } - } - - return new double[]{ min.getRealDouble(), max.getRealDouble() }; - } - public static String toURI( File file ) { String string = file.toString(); diff --git a/src/main/java/org/embl/mobie/lib/SourcesFromTableCreator.java b/src/main/java/org/embl/mobie/lib/SourcesFromTableCreator.java index 0e78891d..91f3bc67 100644 --- a/src/main/java/org/embl/mobie/lib/SourcesFromTableCreator.java +++ b/src/main/java/org/embl/mobie/lib/SourcesFromTableCreator.java @@ -30,8 +30,8 @@ import ij.IJ; import org.embl.mobie.io.ImageDataOpener; -import org.embl.mobie.lib.files.ImageFileSources; -import org.embl.mobie.lib.files.LabelFileSources; +import org.embl.mobie.lib.data.ImageGridSources; +import org.embl.mobie.lib.data.LabelGridSources; import org.embl.mobie.lib.io.TableImageSource; import org.embl.mobie.lib.table.ColumnNames; import org.embl.mobie.lib.table.saw.Aggregators; @@ -43,16 +43,14 @@ import tech.tablesaw.api.TextColumn; import tech.tablesaw.columns.Column; -import java.io.File; -import java.lang.reflect.Array; import java.util.*; import static tech.tablesaw.aggregate.AggregateFunctions.mean; public class SourcesFromTableCreator { - private final List< ImageFileSources > imageFileSources; - private final List< LabelFileSources > labelSources; + private final List< ImageGridSources > imageGridSources; + private final List< LabelGridSources > labelSources; private Table regionTable; public SourcesFromTableCreator( String tablePath, List< String > imageColumns, List< String > labelColumns, String root, String pathMapping, GridType gridType ) @@ -61,7 +59,7 @@ public SourcesFromTableCreator( String tablePath, List< String > imageColumns, L // images // - imageFileSources = new ArrayList<>(); + imageGridSources = new ArrayList<>(); for ( String imageColumn : imageColumns ) { @@ -78,7 +76,7 @@ public SourcesFromTableCreator( String tablePath, List< String > imageColumns, L IJ.log( "Number of channels: " + numChannels ); for ( int channelIndex = 0; channelIndex < numChannels; channelIndex++ ) { - imageFileSources.add( new ImageFileSources( + imageGridSources.add( new ImageGridSources( imageColumn + "_C" + channelIndex, table, imageColumn, @@ -92,7 +90,7 @@ public SourcesFromTableCreator( String tablePath, List< String > imageColumns, L { // Default table final TableImageSource tableImageSource = new TableImageSource( imageColumn ); - imageFileSources.add( new ImageFileSources( tableImageSource.name, table, tableImageSource.columnName, tableImageSource.channelIndex, root, pathMapping, gridType ) ); + imageGridSources.add( new ImageGridSources( tableImageSource.name, table, tableImageSource.columnName, tableImageSource.channelIndex, root, pathMapping, gridType ) ); } } @@ -105,17 +103,17 @@ public SourcesFromTableCreator( String tablePath, List< String > imageColumns, L for ( String label : labelColumns ) { final TableImageSource tableImageSource = new TableImageSource( label ); - labelSources.add( new LabelFileSources( tableImageSource.name, table, tableImageSource.columnName, tableImageSource.channelIndex, root, pathMapping, gridType, label.equals( firstLabel ) ) ); + labelSources.add( new LabelGridSources( tableImageSource.name, table, tableImageSource.columnName, tableImageSource.channelIndex, root, pathMapping, gridType, label.equals( firstLabel ) ) ); } } // region table for grid view // - if ( imageFileSources.isEmpty() ) + if ( imageGridSources.isEmpty() ) throw new RuntimeException("No images found in the table! Please check your table and image column names: " + imageColumns ); - int numSources = imageFileSources.get( 0 ).getSources().size(); + int numSources = imageGridSources.get( 0 ).getSources().size(); if ( table.rowCount() == numSources ) { @@ -174,12 +172,12 @@ else if ( column instanceof TextColumn ) } } - public List< ImageFileSources > getImageSources() + public List< ImageGridSources > getImageSources() { - return imageFileSources; + return imageGridSources; } - public List< LabelFileSources > getLabelSources() + public List< LabelGridSources > getLabelSources() { return labelSources; } diff --git a/src/main/java/org/embl/mobie/lib/bdv/ScreenShotMaker.java b/src/main/java/org/embl/mobie/lib/bdv/ScreenShotMaker.java index cea65974..7c0db420 100644 --- a/src/main/java/org/embl/mobie/lib/bdv/ScreenShotMaker.java +++ b/src/main/java/org/embl/mobie/lib/bdv/ScreenShotMaker.java @@ -123,10 +123,10 @@ public void run( List< SourceAndConverter< ? > > sacs, double targetVoxelSpacing return; } - final AffineTransform3D viewerTransform = new AffineTransform3D(); - bdvHandle.getViewerPanel().state().getViewerTransform( viewerTransform ); final int currentTimepoint = bdvHandle.getViewerPanel().state().getCurrentTimepoint(); + final AffineTransform3D viewerTransform = new AffineTransform3D(); + bdvHandle.getViewerPanel().state().getViewerTransform( viewerTransform ); canvasToGlobalTransform = new AffineTransform3D(); // target canvas to viewer canvas... double targetToViewer = targetVoxelSpacing / getViewerVoxelSpacing( bdvHandle ); diff --git a/src/main/java/org/embl/mobie/lib/bdv/view/SliceViewer.java b/src/main/java/org/embl/mobie/lib/bdv/view/SliceViewer.java index 5ddda122..ec8dca80 100644 --- a/src/main/java/org/embl/mobie/lib/bdv/view/SliceViewer.java +++ b/src/main/java/org/embl/mobie/lib/bdv/view/SliceViewer.java @@ -220,7 +220,7 @@ public static BdvHandle createBdv( boolean is2D, String frameTitle ) IJ.log("BigDataViewer (BDV) initialised."); IJ.log("BDV navigation mode: " + ( is2D ? "2D" : "3D" )); IJ.log("BDV interpolation: Nearest neighbour"); - IJ.log(" - Use [I] keyboard shortcut in BDV window to change this" ); + IJ.log("- Use [I] keyboard shortcut in BDV window to change the interpolation mode" ); IJ.log("" ); IBdvSupplier bdvSupplier = new MobieBdvSupplier( sOptions ); diff --git a/src/main/java/org/embl/mobie/lib/files/FileSourcesDataSetter.java b/src/main/java/org/embl/mobie/lib/data/GridSourcesDataSetter.java similarity index 91% rename from src/main/java/org/embl/mobie/lib/files/FileSourcesDataSetter.java rename to src/main/java/org/embl/mobie/lib/data/GridSourcesDataSetter.java index b064ab52..9680ebad 100644 --- a/src/main/java/org/embl/mobie/lib/files/FileSourcesDataSetter.java +++ b/src/main/java/org/embl/mobie/lib/data/GridSourcesDataSetter.java @@ -26,7 +26,7 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package org.embl.mobie.lib.files; +package org.embl.mobie.lib.data; import ij.IJ; import org.embl.mobie.io.ImageDataFormat; @@ -58,14 +58,14 @@ import java.util.List; import java.util.stream.Collectors; -public class FileSourcesDataSetter +public class GridSourcesDataSetter { - private final List< ImageFileSources > images; - private final List< LabelFileSources > labels; + private final List< ImageGridSources > images; + private final List< LabelGridSources > labels; private final Table regionTable; - public FileSourcesDataSetter( List< ImageFileSources > images, - List< LabelFileSources > labels, + public GridSourcesDataSetter( List< ImageGridSources > images, + List< LabelGridSources > labels, Table regionTable ) { this.images = images; @@ -75,12 +75,12 @@ public FileSourcesDataSetter( List< ImageFileSources > images, public void addDataAndDisplaysAndViews( Dataset dataset ) { - final ArrayList< ImageFileSources > allSources = new ArrayList<>(); + final ArrayList< ImageGridSources > allSources = new ArrayList<>(); allSources.addAll( images ); allSources.addAll( labels ); // create and add data sources to the dataset - for ( ImageFileSources sources : allSources ) + for ( ImageGridSources sources : allSources ) { if ( sources.getMetadata().numZSlices > 1 ) { @@ -98,9 +98,9 @@ public void addDataAndDisplaysAndViews( Dataset dataset ) final StorageLocation storageLocation = new StorageLocation(); storageLocation.absolutePath = path; storageLocation.setChannel( sources.getChannelIndex() ); - if ( sources instanceof LabelFileSources ) + if ( sources instanceof LabelGridSources ) { - final TableSource tableSource = ( ( LabelFileSources ) sources ).getLabelTable( imageName ); + final TableSource tableSource = ( ( LabelGridSources ) sources ).getLabelTable( imageName ); SegmentationDataSource segmentationDataSource = SegmentationDataSource.create( imageName, imageDataFormat, storageLocation, tableSource ); segmentationDataSource.preInit( false ); dataset.addDataSource( segmentationDataSource ); @@ -133,21 +133,21 @@ public void addDataAndDisplaysAndViews( Dataset dataset ) // This assumes that all the individual views are similar // that are part of the same ImageFileSources, as they get the same initial metadata // in terms of number of channels, timepoints and contrast limits - private void addIndividualViews( Dataset dataset, ArrayList< ImageFileSources > fileSourcesList ) + private void addIndividualViews( Dataset dataset, ArrayList< ImageGridSources > fileSourcesList ) { - for ( ImageFileSources sources : fileSourcesList ) + for ( ImageGridSources sources : fileSourcesList ) { for ( String source : sources.getSources() ) { final List< Display< ? > > displays = new ArrayList<>(); final List< Transformation > transformations = new ArrayList<>(); - if ( sources instanceof LabelFileSources ) + if ( sources instanceof LabelGridSources ) { // SegmentationDisplay final SegmentationDisplay< AnnotatedSegment > segmentationDisplay = new SegmentationDisplay<>( source, Collections.singletonList( source ) ); - final int numLabelTables = ( ( LabelFileSources ) sources ).getNumLabelTables(); + final int numLabelTables = ( ( LabelGridSources ) sources ).getNumLabelTables(); segmentationDisplay.setShowTable( numLabelTables > 0 ); displays.add( segmentationDisplay ); } @@ -180,13 +180,13 @@ private void addIndividualViews( Dataset dataset, ArrayList< ImageFileSources > } - private void addGridView( Dataset dataset, ArrayList< ImageFileSources > fileSourcesList ) + private void addGridView( Dataset dataset, ArrayList< ImageGridSources > fileSourcesList ) { RegionDisplay< AnnotatedRegion > regionDisplay = null; final List< Display< ? > > displays = new ArrayList<>(); final List< Transformation > transformations = new ArrayList<>(); - for ( ImageFileSources sources : fileSourcesList ) + for ( ImageGridSources sources : fileSourcesList ) { List< String > sourceNames = sources.getSources(); final int numRegions = sourceNames.size(); @@ -239,12 +239,12 @@ private void addGridView( Dataset dataset, ArrayList< ImageFileSources > fileSou { String source = sources.getSources().get( 0 ); - if ( sources instanceof LabelFileSources ) + if ( sources instanceof LabelGridSources ) { // SegmentationDisplay final SegmentationDisplay< AnnotatedSegment > segmentationDisplay = new SegmentationDisplay<>( source, Collections.singletonList( source ) ); - final int numLabelTables = ( ( LabelFileSources ) sources ).getNumLabelTables(); + final int numLabelTables = ( ( LabelGridSources ) sources ).getNumLabelTables(); segmentationDisplay.setShowTable( numLabelTables > 0 ); displays.add( segmentationDisplay ); } @@ -274,11 +274,11 @@ private void addGridView( Dataset dataset, ArrayList< ImageFileSources > fileSou .map(row -> new int[]{row.getInt(ColumnNames.COLUMN_INDEX), row.getInt(ColumnNames.ROW_INDEX)}) .collect( Collectors.toList()); - if ( sources instanceof LabelFileSources ) + if ( sources instanceof LabelGridSources ) { // SegmentationDisplay final SegmentationDisplay< AnnotatedSegment > segmentationDisplay = new SegmentationDisplay<>( grid.getName(), Collections.singletonList( grid.getName() ) ); - final int numLabelTables = ( ( LabelFileSources ) sources ).getNumLabelTables(); + final int numLabelTables = ( ( LabelGridSources ) sources ).getNumLabelTables(); segmentationDisplay.setShowTable( numLabelTables > 0 ); displays.add( segmentationDisplay ); } @@ -295,11 +295,11 @@ else if ( sources.getGridType().equals( GridType.Transformed ) ) { // Add the individual images to the displays // - if ( sources instanceof LabelFileSources ) + if ( sources instanceof LabelGridSources ) { // SegmentationDisplay final SegmentationDisplay< AnnotatedSegment > segmentationDisplay = new SegmentationDisplay<>( sources.getName(), sourceNames ); - final int numLabelTables = ( ( LabelFileSources ) sources ).getNumLabelTables(); + final int numLabelTables = ( ( LabelGridSources ) sources ).getNumLabelTables(); segmentationDisplay.setShowTable( numLabelTables > 0 ); displays.add( segmentationDisplay ); } diff --git a/src/main/java/org/embl/mobie/lib/files/SourcesFromPathsCreator.java b/src/main/java/org/embl/mobie/lib/data/GridSourcesFromPathsCreator.java similarity index 81% rename from src/main/java/org/embl/mobie/lib/files/SourcesFromPathsCreator.java rename to src/main/java/org/embl/mobie/lib/data/GridSourcesFromPathsCreator.java index c4c0e0d9..19d136ce 100644 --- a/src/main/java/org/embl/mobie/lib/files/SourcesFromPathsCreator.java +++ b/src/main/java/org/embl/mobie/lib/data/GridSourcesFromPathsCreator.java @@ -26,7 +26,7 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package org.embl.mobie.lib.files; +package org.embl.mobie.lib.data; import org.embl.mobie.lib.io.FileImageSource; import org.embl.mobie.lib.transform.GridType; @@ -35,12 +35,12 @@ import java.util.ArrayList; import java.util.List; -public class SourcesFromPathsCreator +public class GridSourcesFromPathsCreator { - private final List< ImageFileSources > imageSources; - private final List< LabelFileSources > labelSources; + private final List< ImageGridSources > imageSources; + private final List< LabelGridSources > labelSources; - public SourcesFromPathsCreator( List < String > imagePaths, List < String > labelPaths, List < String > labelTablePaths, String root, GridType grid ) + public GridSourcesFromPathsCreator( List < String > imagePaths, List < String > labelPaths, List < String > labelTablePaths, String root, GridType grid ) { // images // @@ -48,7 +48,7 @@ public SourcesFromPathsCreator( List < String > imagePaths, List < String > labe for ( String imagePath : imagePaths ) { final FileImageSource fileImageSource = new FileImageSource( imagePath ); - imageSources.add( new ImageFileSources( fileImageSource.name, fileImageSource.path, fileImageSource.channelIndex, root, grid ) ); + imageSources.add( new ImageGridSources( fileImageSource.name, fileImageSource.path, fileImageSource.channelIndex, root, grid ) ); } // segmentation images @@ -61,21 +61,21 @@ public SourcesFromPathsCreator( List < String > imagePaths, List < String > labe if ( labelTablePaths.size() > labelSourceIndex ) { final String labelTablePath = labelTablePaths.get( labelSourceIndex ); - labelSources.add( new LabelFileSources( fileImageSource.name, fileImageSource.path, fileImageSource.channelIndex, labelTablePath, root, grid ) ); + labelSources.add( new LabelGridSources( fileImageSource.name, fileImageSource.path, fileImageSource.channelIndex, labelTablePath, root, grid ) ); } else { - labelSources.add( new LabelFileSources( fileImageSource.name, fileImageSource.path, fileImageSource.channelIndex, root, grid ) ); + labelSources.add( new LabelGridSources( fileImageSource.name, fileImageSource.path, fileImageSource.channelIndex, root, grid ) ); } } } - public List< ImageFileSources > getImageSources() + public List< ImageGridSources > getImageSources() { return imageSources; } - public List< LabelFileSources > getLabelSources() + public List< LabelGridSources > getLabelSources() { return labelSources; } diff --git a/src/main/java/org/embl/mobie/lib/files/ImageFileSources.java b/src/main/java/org/embl/mobie/lib/data/ImageGridSources.java similarity index 96% rename from src/main/java/org/embl/mobie/lib/files/ImageFileSources.java rename to src/main/java/org/embl/mobie/lib/data/ImageGridSources.java index 9860d7f7..5f64b0f0 100644 --- a/src/main/java/org/embl/mobie/lib/files/ImageFileSources.java +++ b/src/main/java/org/embl/mobie/lib/data/ImageGridSources.java @@ -26,17 +26,13 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package org.embl.mobie.lib.files; +package org.embl.mobie.lib.data; import bdv.viewer.Source; import ij.IJ; -import loci.formats.in.CellSensReader; import net.imglib2.RandomAccessibleInterval; -import net.imglib2.Volatile; import net.imglib2.realtransform.AffineTransform3D; import org.apache.commons.io.FilenameUtils; -import org.embl.mobie.DataStore; -import org.embl.mobie.MoBIE; import org.embl.mobie.io.ImageDataOpener; import org.embl.mobie.io.imagedata.ImageData; import org.embl.mobie.io.util.IOHelper; @@ -52,11 +48,10 @@ import tech.tablesaw.api.StringColumn; import tech.tablesaw.api.Table; -import javax.xml.crypto.Data; import java.io.File; import java.util.*; -public class ImageFileSources +public class ImageGridSources { protected final String name; protected Map< String, AffineTransform3D > nameToAffineTransform = new LinkedHashMap<>(); @@ -70,7 +65,7 @@ public class ImageFileSources protected Metadata metadata; private String metadataSource; - public ImageFileSources( String name, String pathRegex, Integer channelIndex, String root, GridType gridType ) + public ImageGridSources( String name, String pathRegex, Integer channelIndex, String root, GridType gridType ) { this.gridType = gridType; this.name = name; @@ -99,7 +94,7 @@ public ImageFileSources( String name, String pathRegex, Integer channelIndex, St regionTable.addColumns( StringColumn.create( "source_path", new ArrayList<>( nameToFullPath.values() ) ) ); } - public ImageFileSources( String name, Table table, String imageColumn, Integer channelIndex, String root, String pathMapping, GridType gridType ) + public ImageGridSources( String name, Table table, String imageColumn, Integer channelIndex, String root, String pathMapping, GridType gridType ) { this.name = name; this.channelIndex = channelIndex; @@ -191,7 +186,7 @@ private void setMetadata( Integer channelIndex ) Source< ? > source = imageData.getSourcePair( channelIndex ).getA(); metadata.numZSlices = (int) source.getSource( 0, 0 ).dimension( 2 ); metadata.numTimePoints = SourceHelper.getNumTimePoints( source ); - metadata.contrastLimits = MoBIEHelper.estimateMinMax( ( RandomAccessibleInterval ) source.getSource( 0, source.getNumMipmapLevels() -1 ) ); + metadata.contrastLimits = SourceHelper.estimateMinMax( ( RandomAccessibleInterval ) source.getSource( 0, source.getNumMipmapLevels() -1 ) ); IJ.log( "Slices: " + metadata.numZSlices ); IJ.log( "Frames: " + metadata.numTimePoints ); IJ.log( "Contrast limits: " + Arrays.toString( metadata.contrastLimits ) ); diff --git a/src/main/java/org/embl/mobie/lib/files/LabelFileSources.java b/src/main/java/org/embl/mobie/lib/data/LabelGridSources.java similarity index 93% rename from src/main/java/org/embl/mobie/lib/files/LabelFileSources.java rename to src/main/java/org/embl/mobie/lib/data/LabelGridSources.java index 1fa712a6..8347a3bf 100644 --- a/src/main/java/org/embl/mobie/lib/files/LabelFileSources.java +++ b/src/main/java/org/embl/mobie/lib/data/LabelGridSources.java @@ -26,7 +26,7 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package org.embl.mobie.lib.files; +package org.embl.mobie.lib.data; import ij.IJ; import org.embl.mobie.lib.MoBIEHelper; @@ -43,12 +43,12 @@ import java.util.List; import java.util.Map; -public class LabelFileSources extends ImageFileSources +public class LabelGridSources extends ImageGridSources { protected Map< String, TableSource > nameToLabelTable = new LinkedHashMap<>(); private static boolean logLabelParsingError = true; - public LabelFileSources( String name, Table table, String columnName, Integer channelIndex, String root, String pathMapping, GridType gridType, boolean useTableForSegments ) + public LabelGridSources( String name, Table table, String columnName, Integer channelIndex, String root, String pathMapping, GridType gridType, boolean useTableForSegments ) { super( name, table, columnName, channelIndex, root, pathMapping, gridType); @@ -78,13 +78,13 @@ public LabelFileSources( String name, Table table, String columnName, Integer ch } } - public LabelFileSources( String name, String labelsPath, Integer channelIndex, String root, GridType grid ) + public LabelGridSources( String name, String labelsPath, Integer channelIndex, String root, GridType grid ) { super( name, labelsPath, channelIndex, root, grid ); } - public LabelFileSources( String name, String path, Integer channelIndex, String labelTablePath, String root, GridType grid ) + public LabelGridSources( String name, String path, Integer channelIndex, String labelTablePath, String root, GridType grid ) { super( name, path, channelIndex, root, grid ); diff --git a/src/main/java/org/embl/mobie/lib/data/TableSourcesDataSetter.java b/src/main/java/org/embl/mobie/lib/data/TableSourcesDataSetter.java new file mode 100644 index 00000000..ac797609 --- /dev/null +++ b/src/main/java/org/embl/mobie/lib/data/TableSourcesDataSetter.java @@ -0,0 +1,91 @@ +package org.embl.mobie.lib.data; + +import ij.IJ; +import org.embl.mobie.io.ImageDataFormat; +import org.embl.mobie.io.util.IOHelper; +import org.embl.mobie.lib.io.StorageLocation; +import org.embl.mobie.lib.serialize.Dataset; +import org.embl.mobie.lib.serialize.ImageDataSource; +import org.embl.mobie.lib.serialize.SegmentationDataSource; +import org.embl.mobie.lib.serialize.View; +import org.embl.mobie.lib.serialize.display.ImageDisplay; +import org.embl.mobie.lib.table.TableSource; +import org.embl.mobie.lib.table.columns.MoBIETableColumnNames; +import org.jetbrains.annotations.NotNull; +import tech.tablesaw.api.Row; +import tech.tablesaw.api.Table; + +import java.util.Collections; + +public class TableSourcesDataSetter +{ + private final Table table; + + public TableSourcesDataSetter( Table table ) + { + this.table = table; + } + + public void addToDataset( Dataset dataset ) + { + for ( Row row : table ) + { + final StorageLocation storageLocation = new StorageLocation(); + storageLocation.absolutePath = row.getString( MoBIETableColumnNames.URI ); + ImageDataFormat imageDataFormat = ImageDataFormat.fromPath( storageLocation.absolutePath ); + String imageName = IOHelper.getFileName( storageLocation.absolutePath ); + storageLocation.setChannel( 0 ); // TODO: Fetch from table or URI? https://forum.image.sc/t/loading-only-one-channel-from-an-ome-zarr/97798 + // TODO: probably one needs to add the channel to the imageName + IJ.log("## " + imageName ); + IJ.log("URI: " + storageLocation.absolutePath ); + IJ.log("Format: " + imageDataFormat ); + + String pixelType = row.getString( MoBIETableColumnNames.PIXEL_TYPE ); + + if ( pixelType.equals( MoBIETableColumnNames.LABELS ) ) + { + final TableSource tableSource = null; // TODO: table path could be added to the table + SegmentationDataSource segmentationDataSource = + SegmentationDataSource.create( + imageName, + imageDataFormat, + storageLocation, + tableSource ); + segmentationDataSource.preInit( false ); + dataset.addDataSource( segmentationDataSource ); + } + else // intensities + { + final ImageDataSource imageDataSource = new ImageDataSource( imageName, imageDataFormat, storageLocation ); + imageDataSource.preInit( false ); + dataset.addDataSource( imageDataSource ); + + final View view = createImageView( imageName ); + dataset.views().put( view.getName(), view ); + } + } + } + + @NotNull + private static View createImageView( String imageName ) + { + final ImageDisplay< ? > imageDisplay = new ImageDisplay<>( + imageName, + Collections.singletonList( imageName ), + null, // ColorHelper.getString( metadata.getColor() ), + null //new double[]{ metadata.minIntensity(), metadata.minIntensity() } + ); + + final View view = new View( + imageName, + "images", + Collections.singletonList( imageDisplay ), + null, + null, + false, + null ); + + return view; + } + +} diff --git a/src/main/java/org/embl/mobie/lib/hcs/Plate.java b/src/main/java/org/embl/mobie/lib/hcs/Plate.java index d9db995e..046564b6 100644 --- a/src/main/java/org/embl/mobie/lib/hcs/Plate.java +++ b/src/main/java/org/embl/mobie/lib/hcs/Plate.java @@ -29,9 +29,7 @@ package org.embl.mobie.lib.hcs; import bdv.viewer.Source; -import ch.epfl.biop.bdv.img.bioformats.entity.SeriesIndex; import ij.IJ; -import ij.ImagePlus; import mpicbg.spim.data.generic.AbstractSpimData; import mpicbg.spim.data.generic.base.Entity; import mpicbg.spim.data.generic.sequence.BasicViewSetup; @@ -57,12 +55,10 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; -import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; import java.util.stream.IntStream; -import java.util.stream.Stream; -import static org.embl.mobie.lib.MoBIEHelper.computeMinMax; +import static org.embl.mobie.lib.source.SourceHelper.computeMinMax; public class Plate diff --git a/src/main/java/org/embl/mobie/lib/image/ImageDataImage.java b/src/main/java/org/embl/mobie/lib/image/ImageDataImage.java index d59e50f6..22922dbd 100644 --- a/src/main/java/org/embl/mobie/lib/image/ImageDataImage.java +++ b/src/main/java/org/embl/mobie/lib/image/ImageDataImage.java @@ -206,4 +206,13 @@ private ImageData< T > openImageData( ) return ( ImageData< T > ) DataStore.fetchImageData( uri, imageDataFormat, sharedQueue ); } + public String getUri() + { + return uri; + } + + public int getSetupId() + { + return setupId; + } } diff --git a/src/main/java/org/embl/mobie/lib/io/ImageDataInfo.java b/src/main/java/org/embl/mobie/lib/io/ImageDataInfo.java new file mode 100644 index 00000000..b99bd977 --- /dev/null +++ b/src/main/java/org/embl/mobie/lib/io/ImageDataInfo.java @@ -0,0 +1,7 @@ +package org.embl.mobie.lib.io; + +public class ImageDataInfo +{ + public String uri; + public Integer datasetId; +} diff --git a/src/main/java/org/embl/mobie/lib/serialize/transformation/AffineTransformation.java b/src/main/java/org/embl/mobie/lib/serialize/transformation/AffineTransformation.java index 130acc6f..72acfdd3 100644 --- a/src/main/java/org/embl/mobie/lib/serialize/transformation/AffineTransformation.java +++ b/src/main/java/org/embl/mobie/lib/serialize/transformation/AffineTransformation.java @@ -78,16 +78,17 @@ public String toString() int count = 0; for ( String entry : entries ) { - output.append( entry ); + output.append( entry.trim() ); count++; if ( count == 4 ) { lines.add( output.toString() ); + output = new StringBuilder(); count = 0; } else { - output.append( "," ); + output.append( ", " ); } } diff --git a/src/main/java/org/embl/mobie/lib/source/SourceHelper.java b/src/main/java/org/embl/mobie/lib/source/SourceHelper.java index ae9b97b7..5dc0b15d 100644 --- a/src/main/java/org/embl/mobie/lib/source/SourceHelper.java +++ b/src/main/java/org/embl/mobie/lib/source/SourceHelper.java @@ -45,11 +45,9 @@ import net.imglib2.roi.geom.real.WritableBox; import net.imglib2.type.numeric.RealType; import net.imglib2.util.Intervals; -import net.imglib2.util.ValuePair; import net.imglib2.view.Views; import org.embl.mobie.lib.bdv.CalibratedMousePositionProvider; import org.jetbrains.annotations.NotNull; -import sc.fiji.bdvpg.sourceandconverter.SourceAndConverterHelper; import java.lang.reflect.Field; import java.util.*; @@ -374,4 +372,70 @@ public static boolean isPositionWithinSourceInterval( Source< ? > source, RealPo // else { } + public static > double[] computeMinMax( RandomAccessibleInterval rai) { + Cursor cursor = Views.iterable(rai).cursor(); + + // Initialize min and max with the first element + T type = cursor.next(); + T min = type.copy(); + T max = type.copy(); + + // Iterate over the remaining elements to find min and max + while (cursor.hasNext()) { + type = cursor.next(); + if (type.compareTo(min) < 0) { + min.set(type); + } + if (type.compareTo(max) > 0) { + max.set(type); + } + } + + return new double[]{ min.getRealDouble(), max.getRealDouble() }; + } + + public static double[] estimateMinMax( RandomAccessibleInterval > rai) + { + Cursor> cursor = Views.iterable(rai).cursor(); + if (!cursor.hasNext()) return new double[]{0, 255}; + long stepSize = Intervals.numElements(rai) / 10000 + 1; + int randomLimit = (int) Math.min(Integer.MAX_VALUE, stepSize); + Random random = new Random(42); + double min = cursor.next().getRealDouble(); + double max = min; + while (cursor.hasNext()) { + double value = cursor.get().getRealDouble(); + cursor.jumpFwd(stepSize + random.nextInt(randomLimit)); + min = Math.min(min, value); + max = Math.max(max, value); + } + return new double[]{min, max}; + } + + // TODO: finish implementation + public static double[] estimateMinMaxWithinViewerUNFINISHED( + RandomAccessibleInterval > rai, + AffineTransform3D sourceToGlobal, + BdvHandle bdvHandle) + { + AffineTransform3D globalToViewer = bdvHandle.getViewerPanel().state().getViewerTransform(); + AffineTransform3D sourceToViewer = sourceToGlobal.preConcatenate( globalToViewer ); + + Cursor> cursor = Views.iterable(rai).cursor(); + if (!cursor.hasNext()) return new double[]{0, 255}; + long stepSize = Intervals.numElements(rai) / 10000 + 1; + int randomLimit = (int) Math.min(Integer.MAX_VALUE, stepSize); + Random random = new Random(42); + double min = cursor.next().getRealDouble(); + double max = min; + while (cursor.hasNext()) { + // TODO: how to move without triggering data access? + double value = cursor.get().getRealDouble(); + cursor.jumpFwd(stepSize + random.nextInt(randomLimit)); + long[] longs = cursor.positionAsLongArray(); + min = Math.min(min, value); + max = Math.max(max, value); + } + return new double[]{min, max}; + } } diff --git a/src/main/java/org/embl/mobie/lib/table/columns/MoBIETableColumnNames.java b/src/main/java/org/embl/mobie/lib/table/columns/MoBIETableColumnNames.java new file mode 100644 index 00000000..427794af --- /dev/null +++ b/src/main/java/org/embl/mobie/lib/table/columns/MoBIETableColumnNames.java @@ -0,0 +1,17 @@ +package org.embl.mobie.lib.table.columns; + +public class MoBIETableColumnNames +{ + // Column names + + public static String URI = "uri"; + public static String PIXEL_TYPE = "pixel_type"; + + + // Vocabulary + + // Pixel type values + public static String INTENSITIES = "intensities"; + public static String LABELS = "labels"; + +} diff --git a/src/main/java/org/embl/mobie/lib/transform/ImageTransformer.java b/src/main/java/org/embl/mobie/lib/transform/ImageTransformer.java index 6b9fef25..79486e74 100644 --- a/src/main/java/org/embl/mobie/lib/transform/ImageTransformer.java +++ b/src/main/java/org/embl/mobie/lib/transform/ImageTransformer.java @@ -52,13 +52,17 @@ public class ImageTransformer public static Image< ? > affineTransform( Image< ? > image, AffineTransformation affineTransformation ) { String transformedImageName = affineTransformation.getTransformedImageName( image.getName() ); - - if( transformedImageName == null || image.getName().equals( transformedImageName ) ) - { - // in place transformation - image.transform( affineTransformation.getAffineTransform3D() ); - return image; - } + if( transformedImageName == null ) + transformedImageName = image.getName(); + + // FIXME The below will destroy the Transformation History of this image + // Not sure why we have this? For performance?? +// if( transformedImageName == null || image.getName().equals( transformedImageName ) ) +// { +// // in place transformation +// image.transform( affineTransformation.getAffineTransform3D() ); +// return image; +// } if ( image instanceof AnnotationLabelImage ) { diff --git a/src/main/java/org/embl/mobie/lib/transform/TransformHelper.java b/src/main/java/org/embl/mobie/lib/transform/TransformHelper.java index 0deb6186..00b97002 100644 --- a/src/main/java/org/embl/mobie/lib/transform/TransformHelper.java +++ b/src/main/java/org/embl/mobie/lib/transform/TransformHelper.java @@ -407,11 +407,10 @@ private static void collectTransformations( Image< ? > image, Collection< Transf } else { - // The raw data with the voxel calibration AffineTransform3D affineTransform3D = new AffineTransform3D(); image.getSourcePair().getSource().getSourceTransform( 0, 0, affineTransform3D ); AffineTransformation affineTransformation = new AffineTransformation( - "calibration", + "image transform", affineTransform3D, Collections.singletonList( image.getName() ) ); transformations.add( affineTransformation ); diff --git a/src/main/java/org/embl/mobie/lib/view/ViewManager.java b/src/main/java/org/embl/mobie/lib/view/ViewManager.java index 8a3f87cd..526fee47 100644 --- a/src/main/java/org/embl/mobie/lib/view/ViewManager.java +++ b/src/main/java/org/embl/mobie/lib/view/ViewManager.java @@ -243,7 +243,7 @@ public synchronized void show( View view ) if ( view.isExclusive() ) { removeAllSourceDisplays( true ); - DataStore.clearImages(); + DataStore.clearImages(); MoBIEWindowManager.closeAllWindows(); } diff --git a/src/main/java/org/embl/mobie/ui/UserInterfaceHelper.java b/src/main/java/org/embl/mobie/ui/UserInterfaceHelper.java index dc4f815b..a28e0f5f 100644 --- a/src/main/java/org/embl/mobie/ui/UserInterfaceHelper.java +++ b/src/main/java/org/embl/mobie/ui/UserInterfaceHelper.java @@ -45,7 +45,6 @@ import org.embl.mobie.command.context.ConfigureSegmentRenderingCommand; import org.embl.mobie.io.util.IOHelper; import org.embl.mobie.MoBIE; -import org.embl.mobie.lib.MoBIEHelper; import org.embl.mobie.lib.io.FileLocation; import org.embl.mobie.lib.MoBIEInfo; import org.embl.mobie.lib.Services; @@ -66,6 +65,7 @@ import org.embl.mobie.lib.serialize.display.SegmentationDisplay; import org.embl.mobie.lib.serialize.display.SpotDisplay; import org.embl.mobie.lib.serialize.display.VisibilityListener; +import org.embl.mobie.lib.source.SourceHelper; import org.embl.mobie.lib.table.AnnData; import org.embl.mobie.lib.transform.viewer.MoBIEViewerTransformAdjuster; import org.embl.mobie.lib.transform.viewer.ViewerTransformChanger; @@ -554,7 +554,7 @@ public static JFrame showOpacityAndContrastLimitsDialog( Source< ? > source = sacs.get( 0 ).getSpimSource(); RandomAccessibleInterval< ? > rai = source.getSource( bdvHandle.getViewerPanel().state().getCurrentTimepoint(), source.getNumMipmapLevels() - 1 ); - double[] minMax = MoBIEHelper.estimateMinMax( ( RandomAccessibleInterval ) rai ); + double[] minMax = SourceHelper.estimateMinMax( ( RandomAccessibleInterval ) rai ); min.setCurrentValue( minMax[ 0 ] ); max.setCurrentValue( minMax[ 1 ] ); }); diff --git a/src/test/java/examples/OpenPlatybrowser.java b/src/test/java/examples/OpenPlatybrowser.java new file mode 100644 index 00000000..72e35704 --- /dev/null +++ b/src/test/java/examples/OpenPlatybrowser.java @@ -0,0 +1,47 @@ +/*- + * #%L + * Fiji viewer for MoBIE projects + * %% + * Copyright (C) 2018 - 2024 EMBL + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ +package examples; + +import net.imagej.ImageJ; +import org.embl.mobie.MoBIE; +import org.embl.mobie.MoBIESettings; + +import java.io.IOException; + +public class OpenPlatybrowser +{ + public static void main( String[] args ) throws IOException + { + final ImageJ imageJ = new ImageJ(); + imageJ.ui().showUI(); + + final MoBIE moBIE = new MoBIE( "https://github.com/mobie/covid-if-project", + MoBIESettings.settings().gitProjectBranch( "main" ).view( "default" ) ); + } +} diff --git a/src/test/java/examples/OpenProjectTable.java b/src/test/java/examples/OpenProjectTable.java new file mode 100644 index 00000000..1a4b9865 --- /dev/null +++ b/src/test/java/examples/OpenProjectTable.java @@ -0,0 +1,18 @@ +package examples; + +import net.imagej.ImageJ; +import org.embl.mobie.MoBIE; +import org.embl.mobie.MoBIESettings; + +public class OpenProjectTable +{ + public static void main( String[] args ) + { + final ImageJ imageJ = new ImageJ(); + imageJ.ui().showUI(); + + final MoBIE moBIE = new MoBIE( "src/test/resources/project-tables/clem-table.txt", + new MoBIESettings(), + true ); + } +} diff --git a/src/test/java/projects/OpenRemotePlatynereis.java b/src/test/java/projects/OpenRemotePlatynereis.java index 756dd3d1..ae0f1d15 100644 --- a/src/test/java/projects/OpenRemotePlatynereis.java +++ b/src/test/java/projects/OpenRemotePlatynereis.java @@ -41,6 +41,7 @@ public static void main( String[] args ) throws IOException final ImageJ imageJ = new ImageJ(); imageJ.ui().showUI(); - final MoBIE moBIE = new MoBIE( "https://github.com/mobie/covid-if-project", MoBIESettings.settings().gitProjectBranch( "main" ).view( "default" ) ); //"full_grid" + final MoBIE moBIE = new MoBIE( "https://github.com/mobie/covid-if-project", + MoBIESettings.settings().gitProjectBranch( "main" ).view( "default" ) ); } } diff --git a/src/test/resources/project-tables/clem-table.csv b/src/test/resources/project-tables/clem-table.csv new file mode 100644 index 00000000..00b7bd30 --- /dev/null +++ b/src/test/resources/project-tables/clem-table.csv @@ -0,0 +1,3 @@ +uri,pixel_type +https://s3.embl.de/yeast-clem/hela/images/ome-zarr/em-overview.ome.zarr,intensities +https://raw.githubusercontent.com/mobie/clem-example-project/main/data/hela/images/bdv-n5-s3/fluorescence-a2-FMR-c2.xml,intensities diff --git a/src/test/resources/project-tables/clem-table.txt b/src/test/resources/project-tables/clem-table.txt new file mode 100644 index 00000000..958ab9e6 --- /dev/null +++ b/src/test/resources/project-tables/clem-table.txt @@ -0,0 +1,3 @@ +uri pixel_type transform +https://s3.embl.de/yeast-clem/hela/images/ome-zarr/em-overview.ome.zarr intensities (-0.102, -0.971, 0, 483.043, -0.985, 0.119, 0, 487.003, 0, 0, 29.308, 0) +https://raw.githubusercontent.com/mobie/clem-example-project/main/data/hela/images/bdv-n5-s3/fluorescence-a2-FMR-c2.xml intensities (-0.377, 0.951, 0, 193.574, 0.974, 0.359, 0, -39.55, 0, 0, 15.546, 0) \ No newline at end of file diff --git a/src/test/resources/project-tables/clem-table.xlsx b/src/test/resources/project-tables/clem-table.xlsx new file mode 100644 index 00000000..e2d809e7 Binary files /dev/null and b/src/test/resources/project-tables/clem-table.xlsx differ