Skip to content

Add copy&paste of BDV state as JSON strings #205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,14 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>

<!-- Test dependencies -->
<dependency>
Expand Down
181 changes: 141 additions & 40 deletions src/main/java/bdv/BigDataViewer.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,6 @@
*/
package bdv;

import bdv.tools.PreferencesDialog;
import bdv.ui.UIUtils;
import bdv.ui.keymap.Keymap;
import bdv.ui.keymap.KeymapManager;
import bdv.ui.keymap.KeymapSettingsPage;
import bdv.viewer.ConverterSetups;
import bdv.viewer.ViewerState;
import bdv.ui.appearance.AppearanceManager;
import bdv.ui.appearance.AppearanceSettingsPage;
import dev.dirs.ProjectDirectories;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
Expand All @@ -53,16 +43,6 @@
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;

import net.imglib2.Volatile;
import net.imglib2.converter.Converter;
import net.imglib2.display.ColorConverter;
import net.imglib2.display.RealARGBColorConverter;
import net.imglib2.display.ScaledARGBConverter;
import net.imglib2.type.numeric.ARGBType;
import net.imglib2.type.numeric.NumericType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.type.volatiles.VolatileARGBType;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
Expand All @@ -71,6 +51,7 @@
import org.jdom2.output.XMLOutputter;
import org.scijava.ui.behaviour.io.InputTriggerConfig;
import org.scijava.ui.behaviour.io.yaml.YamlConfigIO;
import org.scijava.ui.behaviour.util.Actions;

import bdv.cache.CacheControl;
import bdv.export.ProgressWriter;
Expand All @@ -80,6 +61,7 @@
import bdv.spimdata.XmlIoSpimDataMinimal;
import bdv.tools.HelpDialog;
import bdv.tools.InitializeViewerState;
import bdv.tools.PreferencesDialog;
import bdv.tools.RecordMaxProjectionDialog;
import bdv.tools.RecordMovieDialog;
import bdv.tools.VisibilityAndGroupingDialog;
Expand All @@ -91,21 +73,47 @@
import bdv.tools.brightness.RealARGBColorConverterSetup;
import bdv.tools.brightness.SetupAssignments;
import bdv.tools.crop.CropDialog;
import bdv.tools.links.LinkActions;
import bdv.tools.links.PasteSettings;
import bdv.tools.links.ResourceManager;
import bdv.tools.links.resource.SpimDataMinimalFileResource;
import bdv.tools.links.resource.SpimDataSetupSourceResource;
import bdv.tools.links.resource.TransformedSourceResource;
import bdv.tools.transformation.ManualTransformation;
import bdv.tools.transformation.ManualTransformationEditor;
import bdv.tools.transformation.TransformedSource;
import bdv.ui.UIUtils;
import bdv.ui.appearance.AppearanceManager;
import bdv.ui.appearance.AppearanceSettingsPage;
import bdv.ui.keymap.Keymap;
import bdv.ui.keymap.KeymapManager;
import bdv.ui.keymap.KeymapSettingsPage;
import bdv.ui.links.LinkCard;
import bdv.ui.links.LinkSettingsManager;
import bdv.ui.links.LinkSettingsPage;
import bdv.viewer.ConverterSetups;
import bdv.viewer.NavigationActions;
import bdv.viewer.SourceAndConverter;
import bdv.viewer.ViewerFrame;
import bdv.viewer.ViewerOptions;
import bdv.viewer.ViewerPanel;
import bdv.viewer.ViewerState;
import dev.dirs.ProjectDirectories;
import mpicbg.spim.data.SpimDataException;
import mpicbg.spim.data.generic.AbstractSpimData;
import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription;
import mpicbg.spim.data.generic.sequence.BasicViewSetup;
import mpicbg.spim.data.sequence.Angle;
import mpicbg.spim.data.sequence.Channel;
import org.scijava.ui.behaviour.util.Actions;
import net.imglib2.Volatile;
import net.imglib2.converter.Converter;
import net.imglib2.display.ColorConverter;
import net.imglib2.display.RealARGBColorConverter;
import net.imglib2.display.ScaledARGBConverter;
import net.imglib2.type.numeric.ARGBType;
import net.imglib2.type.numeric.NumericType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.type.volatiles.VolatileARGBType;

public class BigDataViewer
{
Expand Down Expand Up @@ -137,6 +145,10 @@ public class BigDataViewer

private final AppearanceManager appearanceManager;

private final LinkSettingsManager linkSettingsManager;

private final ResourceManager resourceManager;

protected final PreferencesDialog preferencesDialog;

protected final ManualTransformationEditor manualTransformationEditor;
Expand Down Expand Up @@ -257,49 +269,103 @@ public static ConverterSetup createConverterSetup( final SourceAndConverter< ? >
*/
public static < T, V extends Volatile< T > > SourceAndConverter< T > wrapWithTransformedSource( final SourceAndConverter< T > soc )
{
if ( soc.asVolatile() == null )
return new SourceAndConverter<>( new TransformedSource<>( soc.getSpimSource() ), soc.getConverter() );
return wrapWithTransformedSource( soc, null );
}

@SuppressWarnings( "unchecked" )
final SourceAndConverter< V > vsoc = ( SourceAndConverter< V > ) soc.asVolatile();
/**
* Decorate source with an extra transformation, that can be edited manually
* in this viewer. {@link SourceAndConverter#asVolatile() Nested volatile}
* {@code SourceAndConverter} are wrapped as well, if present.
*
* @param soc
* source to decorate
* @param resources
* if non-null, a {@code ResourceSpec} for the created {@code TransformedSource} wrapper.
*
* @return {@code TransformedSource} wrapper around {@code soc}
*/
public static < T, V extends Volatile< T > > SourceAndConverter< T > wrapWithTransformedSource( final SourceAndConverter< T > soc, final ResourceManager resources )
{
final TransformedSource< T > ts = new TransformedSource<>( soc.getSpimSource() );
final TransformedSource< V > vts = new TransformedSource<>( vsoc.getSpimSource(), ts );
return new SourceAndConverter<>( ts, soc.getConverter(), new SourceAndConverter<>( vts, vsoc.getConverter() ) );

final SourceAndConverter< V > vtsoc;
if ( soc.asVolatile() == null )
{
vtsoc = null;
}
else
{
@SuppressWarnings( "unchecked" )
final SourceAndConverter< V > vsoc = ( SourceAndConverter< V > ) soc.asVolatile();
final TransformedSource< V > vts = new TransformedSource<>( vsoc.getSpimSource(), ts );
vtsoc = new SourceAndConverter<>( vts, vsoc.getConverter() );
}

final SourceAndConverter< T > tsoc = new SourceAndConverter<>( ts, soc.getConverter(), vtsoc );
if (resources != null)
{
final TransformedSourceResource.Spec spec = new TransformedSourceResource.Spec(
resources.getResourceSpec( soc ) );
resources.put( tsoc, spec );
resources.keepAlive( tsoc, soc );
}
return tsoc;
}

private static < T extends NumericType< T >, V extends Volatile< T > & NumericType< V > > void initSetupNumericType(
final AbstractSpimData< ? > spimData,
final BasicViewSetup setup,
final List< ConverterSetup > converterSetups,
final List< SourceAndConverter< ? > > sources )
final List< SourceAndConverter< ? > > sources,
final ResourceManager resources )
{
final int setupId = setup.getId();
final String setupName = createSetupName( setup );
final SourceAndConverter< T > soc = createSetupSourceNumericType( spimData, setupId, setupName, resources );
final SourceAndConverter< T > tsoc = wrapWithTransformedSource( soc, resources );
sources.add( tsoc );

final ConverterSetup converterSetup = createConverterSetup( tsoc, setupId );
if ( converterSetup != null )
converterSetups.add( converterSetup );
}

public static < T extends NumericType< T >, V extends Volatile< T > & NumericType< V > > SourceAndConverter< T > createSetupSourceNumericType(
final AbstractSpimData< ? > spimData,
final int setupId,
final String name,
final ResourceManager resources )
{
final ViewerImgLoader imgLoader = ( ViewerImgLoader ) spimData.getSequenceDescription().getImgLoader();
@SuppressWarnings( "unchecked" )
final ViewerSetupImgLoader< T, V > setupImgLoader = ( ViewerSetupImgLoader< T, V > ) imgLoader.getSetupImgLoader( setupId );
if ( setupImgLoader == null )
throw new IllegalArgumentException( "No SetupImgLoader for setup ID " + setupId + " found." );

final T type = setupImgLoader.getImageType();
final V volatileType = setupImgLoader.getVolatileImageType();

if ( ! ( type instanceof NumericType ) )
throw new IllegalArgumentException( "ImgLoader of type " + type.getClass() + " not supported." );

final String setupName = createSetupName( setup );

SourceAndConverter< V > vsoc = null;
if ( volatileType != null )
{
final VolatileSpimSource< V > vs = new VolatileSpimSource<>( spimData, setupId, setupName );
final VolatileSpimSource< V > vs = new VolatileSpimSource<>( spimData, setupId, name );
vsoc = new SourceAndConverter<>( vs, createConverterToARGB( volatileType ) );
}

final SpimSource< T > s = new SpimSource<>( spimData, setupId, setupName );
final SpimSource< T > s = new SpimSource<>( spimData, setupId, name );
final SourceAndConverter< T > soc = new SourceAndConverter<>( s, createConverterToARGB( type ), vsoc );
final SourceAndConverter< T > tsoc = wrapWithTransformedSource( soc );
sources.add( tsoc );

final ConverterSetup converterSetup = createConverterSetup( tsoc, setupId );
if ( converterSetup != null )
converterSetups.add( converterSetup );
if (resources != null)
{
final SpimDataSetupSourceResource.Spec spec = new SpimDataSetupSourceResource.Spec(
resources.getResourceSpec( spimData ),
setupId, name );
resources.put( soc, spec );
resources.keepAlive( soc, spimData );
}
return soc;
}

public static void initSetups(
Expand All @@ -308,7 +374,17 @@ public static void initSetups(
final List< SourceAndConverter< ? > > sources )
{
for ( final BasicViewSetup setup : spimData.getSequenceDescription().getViewSetupsOrdered() )
initSetupNumericType( spimData, setup, converterSetups, sources );
initSetupNumericType( spimData, setup, converterSetups, sources, null );
}

public static void initSetups(
final AbstractSpimData< ? > spimData,
final List< ConverterSetup > converterSetups,
final List< SourceAndConverter< ? > > sources,
final ResourceManager resources )
{
for ( final BasicViewSetup setup : spimData.getSequenceDescription().getViewSetupsOrdered() )
initSetupNumericType( spimData, setup, converterSetups, sources, resources );
}

@Deprecated
Expand Down Expand Up @@ -353,8 +429,11 @@ public BigDataViewer(
{
final KeymapManager optionsKeymapManager = options.values.getKeymapManager();
final AppearanceManager optionsAppearanceManager = options.values.getAppearanceManager();
final LinkSettingsManager optionsLinkSettingsManager = options.values.getLinkSettingsManager();
keymapManager = optionsKeymapManager != null ? optionsKeymapManager : new KeymapManager( configDir );
appearanceManager = optionsAppearanceManager != null ? optionsAppearanceManager : new AppearanceManager( configDir );
linkSettingsManager = optionsLinkSettingsManager != null ? optionsLinkSettingsManager : new LinkSettingsManager( configDir );
resourceManager = options.values.getResourceManager();

InputTriggerConfig inputTriggerConfig = options.values.getInputTriggerConfig();
final Keymap keymap = this.keymapManager.getForwardSelectedKeymap();
Expand Down Expand Up @@ -442,6 +521,7 @@ public boolean accept( final File f )
preferencesDialog = new PreferencesDialog( viewerFrame, keymap, new String[] { KeyConfigContexts.BIGDATAVIEWER } );
preferencesDialog.addPage( new AppearanceSettingsPage( "Appearance", appearanceManager ) );
preferencesDialog.addPage( new KeymapSettingsPage( "Keymap", this.keymapManager, this.keymapManager.getCommandDescriptions() ) );
preferencesDialog.addPage( new LinkSettingsPage( "Links", linkSettingsManager ) );
appearanceManager.appearance().updateListeners().add( viewerFrame::repaint );
appearanceManager.addLafComponent( fileChooser );
SwingUtilities.invokeLater(() -> appearanceManager.updateLookAndFeel());
Expand All @@ -454,9 +534,17 @@ public boolean accept( final File f )
bdvActions.install( viewerFrame.getKeybindings(), "bdv" );
BigDataViewerActions.install( bdvActions, this );

final Actions linkActions = new Actions( inputTriggerConfig, "bdv" );
linkActions.install( viewerFrame.getKeybindings(), "links" );
final PasteSettings pasteSettings = linkSettingsManager.linkSettings().pasteSettings();
LinkActions.install( linkActions, viewerFrame.getViewerPanel(), viewerFrame.getConverterSetups(), pasteSettings, resourceManager );

LinkCard.install( linkSettingsManager.linkSettings(), viewerFrame.getCardPanel() );

keymap.updateListeners().add( () -> {
navigationActions.updateKeyConfig( keymap.getConfig() );
bdvActions.updateKeyConfig( keymap.getConfig() );
linkActions.updateKeyConfig( keymap.getConfig() );
viewerFrame.getTransformBehaviours().updateKeyConfig( keymap.getConfig() );
} );

Expand Down Expand Up @@ -531,7 +619,8 @@ public static BigDataViewer open( final AbstractSpimData< ? > spimData, final St

final ArrayList< ConverterSetup > converterSetups = new ArrayList<>();
final ArrayList< SourceAndConverter< ? > > sources = new ArrayList<>();
initSetups( spimData, converterSetups, sources );
final ResourceManager resources = options.values.getResourceManager();
initSetups( spimData, converterSetups, sources, resources );

final AbstractSequenceDescription< ?, ?, ? > seq = spimData.getSequenceDescription();
final int numTimepoints = seq.getTimePoints().size();
Expand All @@ -549,6 +638,8 @@ public static BigDataViewer open( final AbstractSpimData< ? > spimData, final St
public static BigDataViewer open( final String xmlFilename, final String windowTitle, final ProgressWriter progressWriter, final ViewerOptions options ) throws SpimDataException
{
final SpimDataMinimal spimData = new XmlIoSpimDataMinimal().load( xmlFilename );
final ResourceManager resources = options.values.getResourceManager();
resources.put( spimData, new SpimDataMinimalFileResource.Spec( xmlFilename ) );
final BigDataViewer bdv = open( spimData, windowTitle, progressWriter, options );
if ( !bdv.tryLoadSettings( xmlFilename ) )
InitializeViewerState.initBrightness( 0.001, 0.999, bdv.viewerFrame );
Expand Down Expand Up @@ -609,6 +700,16 @@ public AppearanceManager getAppearanceManager()
return appearanceManager;
}

public LinkSettingsManager getLinkSettingsManager()
{
return linkSettingsManager;
}

public ResourceManager getResourceManager()
{
return resourceManager;
}

public boolean tryLoadSettings( final String xmlFilename )
{
proposedSettingsFile = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import java.lang.reflect.Type;

import bdv.tools.JsonUtils;
import net.imglib2.realtransform.AffineTransform3D;

import com.google.gson.JsonDeserializationContext;
Expand All @@ -39,6 +40,7 @@
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

@JsonUtils.JsonIo( jsonType = "AffineTransform3D.Anchor", type = AffineTransform3D.class )
public class AffineTransform3DJsonSerializer implements JsonDeserializer< AffineTransform3D >, JsonSerializer< AffineTransform3D >
{
@Override
Expand Down
Loading