Skip to content
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

Branch features disappear on project opening #325

9 changes: 8 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<argLine>-Xms256m -Xmx1024m</argLine>
<argLine>-Xms256m -Xmx1536m</argLine>
</configuration>
</plugin>
</plugins>
Expand Down Expand Up @@ -207,6 +207,13 @@
<url>https://github.com/xulman</url>
<properties><id>xulman</id></properties>
</contributor>
<contributor>
<name>Stefan Hahmann</name>
<url>https://github.com/stefanhahmann</url>
<properties>
<id>stefanhahmann</id>
</properties>
</contributor>
</contributors>

<repositories>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,13 @@ public BranchGraphSynchronizer( final GraphListener< ?, ? > bg, final ReadLock r
this.bg = bg;
this.lock = readLock;
this.listeners = new Listeners.SynchronizedList<>();
this.uptodate = true;
}

public void sync()
{
if ( uptodate )
return;
lock.lock();
try
{
Expand Down
37 changes: 37 additions & 0 deletions src/test/java/org/mastodon/mamut/ProjectModelTestUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.mastodon.mamut;

import ij.ImagePlus;
import net.imagej.ImgPlus;
import net.imagej.axis.Axes;
import net.imagej.axis.AxisType;
import net.imglib2.img.Img;
import net.imglib2.img.display.imagej.ImgToVirtualStack;
import net.imglib2.type.numeric.real.FloatType;
import org.mastodon.mamut.io.project.MamutProject;
import org.mastodon.mamut.model.Model;
import org.mastodon.views.bdv.SharedBigDataViewerData;
import org.scijava.Context;

import java.io.File;
import java.io.IOException;
import java.util.Objects;

public class ProjectModelTestUtils
{
public static ProjectModel wrapAsAppModel( final Img< FloatType > image, final Model model, final Context context, final File file )
throws IOException
{
final SharedBigDataViewerData sharedBigDataViewerData = asSharedBdvDataXyz( image );
MamutProject mamutProject = new MamutProject( file );
File datasetXmlFile = File.createTempFile( "test", ".xml" );
mamutProject.setDatasetXmlFile( datasetXmlFile );
return ProjectModel.create( context, model, sharedBigDataViewerData, mamutProject );
}

public static SharedBigDataViewerData asSharedBdvDataXyz( final Img< FloatType > image1 )
{
final ImagePlus image =
ImgToVirtualStack.wrap( new ImgPlus<>( image1, "image", new AxisType[] { Axes.X, Axes.Y, Axes.Z, Axes.TIME } ) );
return Objects.requireNonNull( SharedBigDataViewerData.fromImagePlus( image ) );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ public class FeatureComputerTestUtils
public static < T > Feature< T > getFeature( Context context, Model model, FeatureSpec< ? extends Feature< T >, T > spec )
{
final MamutFeatureComputerService featureComputerService = getMamutFeatureComputerService( context, model );
return Cast.unchecked( featureComputerService.compute( true, spec ).get( spec ) );
Feature< ? > feature = featureComputerService.compute( true, spec ).get( spec );
model.getFeatureModel().declareFeature( feature );
return Cast.unchecked( feature );
}

public static < T > FeatureProjection< T > getFeatureProjection( Context context, Model model,
Expand Down
62 changes: 42 additions & 20 deletions src/test/java/org/mastodon/mamut/io/ProjectLoaderTest.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
package org.mastodon.mamut.io;

import ij.ImagePlus;
import mpicbg.spim.data.SpimDataException;
import net.imagej.ImgPlus;
import net.imagej.axis.Axes;
import net.imagej.axis.AxisType;
import net.imglib2.img.Img;
import net.imglib2.img.array.ArrayImgs;
import net.imglib2.img.display.imagej.ImgToVirtualStack;
import net.imglib2.type.numeric.real.FloatType;
import net.imglib2.util.Cast;
import org.junit.Ignore;
import org.junit.Test;
import org.mastodon.feature.FeatureProjection;
import org.mastodon.feature.FeatureProjectionKey;
import org.mastodon.mamut.ProjectModel;
import org.mastodon.mamut.io.project.MamutProject;
import org.mastodon.mamut.ProjectModelTestUtils;
import org.mastodon.mamut.feature.FeatureComputerTestUtils;
import org.mastodon.mamut.feature.MamutFeatureComputerService;
import org.mastodon.mamut.feature.branch.BranchDisplacementDurationFeature;
import org.mastodon.mamut.feature.branch.exampleGraph.ExampleGraph1;
import org.mastodon.mamut.model.Model;
import org.mastodon.views.bdv.SharedBigDataViewerData;
import org.mastodon.mamut.model.branch.BranchSpot;
import org.scijava.Context;

import java.io.File;
import java.io.IOException;
import java.util.Objects;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
Expand All @@ -37,14 +39,37 @@ public void testLoadAndCloseProjectGarbageCollection() throws IOException, SpimD
File mastodonFile = File.createTempFile( "test", ".mastodon" );
try (Context context = new Context())
{
ProjectModel appModel = wrapAsAppModel( image, model, context, mastodonFile );
ProjectModel appModel = ProjectModelTestUtils.wrapAsAppModel( image, model, context, mastodonFile );
ProjectSaver.saveProject( mastodonFile, appModel );
}
for ( int i = 0; i < 100; i++ )
loadAndCloseProjectModel( mastodonFile );
assertTrue( true );
}

@Test
public void testBranchFeaturesAfterSaveAndReload() throws IOException, SpimDataException
{
ExampleGraph1 graph = new ExampleGraph1();
Model model = graph.getModel();
try (Context context = new Context())
{
File mastodonFile = File.createTempFile( "test", ".mastodon" );
Img< FloatType > image = ArrayImgs.floats( 1, 1, 1 );
ProjectModel projectModel = ProjectModelTestUtils.wrapAsAppModel( image, model, context, mastodonFile );
final MamutFeatureComputerService computerService = MamutFeatureComputerService.newInstance( context );
computerService.setModel( model );
FeatureProjection< BranchSpot > durationProjection = FeatureComputerTestUtils.getFeatureProjection( context, model,
BranchDisplacementDurationFeature.SPEC, BranchDisplacementDurationFeature.DURATION_PROJECTION_SPEC );
double durationBeforeSave = durationProjection.value( graph.branchSpotA );
ProjectModel reloadedProjectModel = saveAndReloadProject( projectModel, mastodonFile, context );
FeatureProjection< BranchSpot > reloadedDurationProjection = getDurationProjectionFromModel( reloadedProjectModel );
BranchSpot branchSpot = reloadedProjectModel.getModel().getBranchGraph().vertices().iterator().next(); // NB: the model only has one branch spot
double durationAfterSave = reloadedDurationProjection.value( branchSpot );
assertEquals( durationBeforeSave, durationAfterSave, 0 );
}
}

private void loadAndCloseProjectModel( final File mastodonFile ) throws SpimDataException, IOException
{
try (Context context = new Context())
Expand All @@ -54,20 +79,17 @@ private void loadAndCloseProjectModel( final File mastodonFile ) throws SpimData
}
}

private static ProjectModel wrapAsAppModel( final Img< FloatType > image, final Model model, final Context context, final File file )
throws IOException
private static FeatureProjection< BranchSpot > getDurationProjectionFromModel( final ProjectModel reloadedProjectModel )
{
final SharedBigDataViewerData sharedBigDataViewerData = asSharedBdvDataXyz( image );
MamutProject mamutProject = new MamutProject( file );
File datasetXmlFile = File.createTempFile( "test", ".xml" );
mamutProject.setDatasetXmlFile( datasetXmlFile );
return ProjectModel.create( context, model, sharedBigDataViewerData, mamutProject );
BranchDisplacementDurationFeature reloadedFeature = Cast
.unchecked( reloadedProjectModel.getModel().getFeatureModel().getFeature( BranchDisplacementDurationFeature.SPEC ) );
return reloadedFeature.project( FeatureProjectionKey.key( BranchDisplacementDurationFeature.DURATION_PROJECTION_SPEC ) );
}

private static SharedBigDataViewerData asSharedBdvDataXyz( final Img< FloatType > image1 )
private static ProjectModel saveAndReloadProject( final ProjectModel projectModel, final File mastodonFile, final Context context )
throws IOException, SpimDataException
{
final ImagePlus image =
ImgToVirtualStack.wrap( new ImgPlus<>( image1, "image", new AxisType[] { Axes.X, Axes.Y, Axes.Z, Axes.TIME } ) );
return Objects.requireNonNull( SharedBigDataViewerData.fromImagePlus( image ) );
ProjectSaver.saveProject( mastodonFile, projectModel );
return ProjectLoader.open( mastodonFile.getAbsolutePath(), context, false, true );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.mastodon.mamut.model.branch;

import net.imglib2.img.Img;
import net.imglib2.img.array.ArrayImgs;
import net.imglib2.type.numeric.real.FloatType;
import org.junit.Ignore;
import org.junit.Test;
import org.mastodon.feature.FeatureProjection;
import org.mastodon.mamut.ProjectModel;
import org.mastodon.mamut.ProjectModelTestUtils;
import org.mastodon.mamut.feature.FeatureComputerTestUtils;
import org.mastodon.mamut.feature.MamutFeatureComputerService;
import org.mastodon.mamut.feature.branch.BranchDisplacementDurationFeature;
import org.mastodon.mamut.feature.branch.exampleGraph.ExampleGraph1;
import org.mastodon.mamut.model.Model;
import org.scijava.Context;

import java.io.File;
import java.io.IOException;

import static org.junit.Assert.assertEquals;

public class BranchGraphSynchronizerTest
{

@Test
public void testKeepBranchFeaturesAfterSyncWithoutChanges() throws IOException
{
ExampleGraph1 graph = new ExampleGraph1();
Model model = graph.getModel();
try (Context context = new Context())
{
File mastodonFile = File.createTempFile( "test", ".mastodon" );
Img< FloatType > image = ArrayImgs.floats( 1, 1, 1 );
ProjectModel projectModel = ProjectModelTestUtils.wrapAsAppModel( image, model, context, mastodonFile );
final MamutFeatureComputerService computerService = MamutFeatureComputerService.newInstance( context );
computerService.setModel( model );
FeatureProjection< BranchSpot > durationProjection =
FeatureComputerTestUtils.getFeatureProjection( context, model, BranchDisplacementDurationFeature.SPEC,
BranchDisplacementDurationFeature.DURATION_PROJECTION_SPEC );
BranchGraphSynchronizer branchGraphSynchronizer = projectModel.getBranchGraphSync();
double durationBeforeSync = durationProjection.value( graph.branchSpotA );
branchGraphSynchronizer.sync();
double durationAfterSync = durationProjection.value( graph.branchSpotA );
assertEquals( durationBeforeSync, durationAfterSync, 0 );
}
}

@Ignore( "This is a known issue. The test is ignored until the issue is fixed." )
@Test
public void testKeepBranchFeaturesAfterSyncWithChanges() throws IOException
{
ExampleGraph1 graph = new ExampleGraph1();
Model model = graph.getModel();
try (Context context = new Context())
{
File mastodonFile = File.createTempFile( "test", ".mastodon" );
Img< FloatType > image = ArrayImgs.floats( 1, 1, 1 );
ProjectModel projectModel = ProjectModelTestUtils.wrapAsAppModel( image, model, context, mastodonFile );
final MamutFeatureComputerService computerService = MamutFeatureComputerService.newInstance( context );
computerService.setModel( model );
FeatureProjection< BranchSpot > durationProjection =
FeatureComputerTestUtils.getFeatureProjection( context, model, BranchDisplacementDurationFeature.SPEC,
BranchDisplacementDurationFeature.DURATION_PROJECTION_SPEC );
BranchGraphSynchronizer branchGraphSynchronizer = projectModel.getBranchGraphSync();
double durationBeforeSync = durationProjection.value( graph.branchSpotA );
model.getGraph().addVertex().init( 0, new double[] { 0, 0, 0 }, 1 );
model.getGraph().notifyGraphChanged();
branchGraphSynchronizer.sync();
double durationAfterSync = durationProjection.value( graph.branchSpotA );
assertEquals( durationBeforeSync, durationAfterSync, 0 );
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.mastodon.views.trackscheme;

import net.imglib2.img.Img;
import net.imglib2.img.array.ArrayImgs;
import net.imglib2.type.numeric.real.FloatType;
import org.junit.Test;
import org.mastodon.feature.FeatureProjection;
import org.mastodon.mamut.ProjectModel;
import org.mastodon.mamut.ProjectModelTestUtils;
import org.mastodon.mamut.feature.FeatureComputerTestUtils;
import org.mastodon.mamut.feature.MamutFeatureComputerService;
import org.mastodon.mamut.feature.branch.BranchDisplacementDurationFeature;
import org.mastodon.mamut.feature.branch.exampleGraph.ExampleGraph1;
import org.mastodon.mamut.model.Model;
import org.mastodon.mamut.model.branch.BranchSpot;
import org.mastodon.mamut.views.trackscheme.MamutBranchViewTrackScheme;
import org.mastodon.mamut.views.trackscheme.MamutBranchViewTrackSchemeHierarchy;
import org.scijava.Context;

import java.io.File;
import java.io.IOException;

import static org.junit.Assert.assertEquals;

public class MamutBranchViewTrackSchemeTest
{
@Test
public void testBranchFeaturesAfterOpeningBranchView() throws IOException, InterruptedException
{
ExampleGraph1 graph = new ExampleGraph1();
Model model = graph.getModel();
try (Context context = new Context())
{
File mastodonFile = File.createTempFile( "test", ".mastodon" );
Img< FloatType > image = ArrayImgs.floats( 1, 1, 1 );
ProjectModel projectModel = ProjectModelTestUtils.wrapAsAppModel( image, model, context, mastodonFile );
final MamutFeatureComputerService computerService = MamutFeatureComputerService.newInstance( context );
computerService.setModel( model );
FeatureProjection< BranchSpot > durationProjection =
FeatureComputerTestUtils.getFeatureProjection( context, model, BranchDisplacementDurationFeature.SPEC,
BranchDisplacementDurationFeature.DURATION_PROJECTION_SPEC );
double duration = durationProjection.value( graph.branchSpotA );
new MamutBranchViewTrackScheme( projectModel );
Thread.sleep( 1_000 );
double durationAfterCreatingTrackSchemeBranch = durationProjection.value( graph.branchSpotA );
assertEquals( duration, durationAfterCreatingTrackSchemeBranch, 0 );
new MamutBranchViewTrackSchemeHierarchy( projectModel );
Thread.sleep( 1_000 );
double durationAfterCreatingTrackSchemeHierarchyBranch = durationProjection.value( graph.branchSpotA );
assertEquals( duration, durationAfterCreatingTrackSchemeHierarchyBranch, 0 );
}
}
}
Loading