Skip to content

Add center spots docs #72

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

Merged
merged 6 commits into from
Dec 10, 2024
Merged
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
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,17 @@ place.
number only may indicate a spot that was automatically detected and not linked to a track.
* Example: ![isolated_spots.gif](doc/spotsmanagement/isolated_spots.gif)

#### Add center spot
#### Add center spots

* Menu Location: `Plugins > Spots management > Transform spots > Add center spots`
* Adds spots to the model at the average position of the selected spots of each time point. The new spots are connected
by links in the order of the time points.
* If there are time points without selected spots, no spot is added at that time point. In this case, the links span
over the time points without spots.
* If there are time points with multiple selected spots, the average position of the selected spots is calculated at
that time point.
* If no spots are selected, only a message dialog is shown.
* Example: ![add_center_spots.gif](doc/spotsmanagement/add_center_spots.gif)

#### Interpolate missing spots

Expand Down
Binary file added doc/spotsmanagement/add_center_spots.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public class TomancakPlugins extends AbstractContextual implements MamutPlugin
private static final String EXPORT_SPOTS_COUNTS_PER_LINEAGE = "[tomancak] export spots counts per lineage";
private static final String EXPORT_SPOTS_COUNTS_PER_TIMEPOINT = "[tomancak] export spots counts per timepoint";

private static final String ADD_CENTER_SPOTS = "[tomancak] add center spot";
private static final String ADD_CENTER_SPOTS = "[tomancak] add center spots";
private static final String MIRROR_SPOTS = "[tomancak] mirror spots";
private static final String CREATE_CONFLICT_TAG_SET = "[tomancak] create conflict tag set";
private static final String FUSE_SPOTS = "[tomancak] fuse selected spots";
Expand Down Expand Up @@ -149,7 +149,7 @@ public class TomancakPlugins extends AbstractContextual implements MamutPlugin
menuTexts.put( EXPORTS_LINEAGE_LENGTHS, "Export lineage lengths" );
menuTexts.put( EXPORT_SPOTS_COUNTS_PER_LINEAGE, "Export spots counts per lineage" );
menuTexts.put( EXPORT_SPOTS_COUNTS_PER_TIMEPOINT, "Export spots counts per timepoint" );
menuTexts.put( ADD_CENTER_SPOTS, "Add center spot" );
menuTexts.put( ADD_CENTER_SPOTS, "Add center spots" );
menuTexts.put( MIRROR_SPOTS, "Mirror spots along X-axis" );
menuTexts.put( CREATE_CONFLICT_TAG_SET, "Create conflict tag set" );
menuTexts.put( FUSE_SPOTS, "Fuse selected spots" );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,19 +166,31 @@ public static List<double[]> calculateAndInterpolateAveragePosition( int numTime
return averages;
}

public static List< double[] > calculateAveragePosition( int numTimePoint, Collection< Spot > taggedSpots )
/**
* Calculates the average position of the given spots per time point,
* i.e. at each time point the average position of all spots that belong to that time point is calculated.
* If there are no spots at a time point, the average position of that time point is {@code null}.
* <br>
* The result is a list of double arrays, where the index of the array corresponds to the time point and the array contains the average position in three dimensions.
* If there are no spots at a time point, the array is {@code null} at that index.
*
* @param numTimePoints The number of time points.
* @param spots The collection of spots.
* @return A list of double arrays representing the average positions per time point.
*/
public static List< double[] > calculateAveragePosition( int numTimePoints, Collection< Spot > spots )
{
List<double[]> averages = new ArrayList<>( Collections.nCopies( numTimePoint, null ) );
int[] counts = new int[ numTimePoint ];
List< double[] > averages = new ArrayList<>( Collections.nCopies( numTimePoints, null ) );
int[] counts = new int[ numTimePoints ];
Collections.fill(averages, null);
for(Spot spot : taggedSpots )
for ( Spot spot : spots )
{
int timepoint = spot.getTimepoint();
counts[timepoint]++;
double[] average = getOrCreateEntry( averages, timepoint );
add( average, spot );
}
for ( int i = 0; i < numTimePoint; i++ )
for ( int i = 0; i < numTimePoints; i++ )
{
double[] average = averages.get( i );
if(average != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ private AddCenterSpots()
// prevent from instantiation
}

/**
* Adds spots to the model at the average position of the selected spots of each time point.
* The new spots are connected by links in the order of the time points.
* <br>
* If there are time points without selected spots, no spot is added at that time point. In this case, the links span over the time points without spots.
* <br>
* If there are time points with multiple selected spots, the average position of the selected spots is calculated at that time point.
* <br><br>
* If no spots are selected, only a message dialog is shown.
*
* @param appModel the project model
*/
public static void addSpots( ProjectModel appModel )
{
RefSet< Spot > selectedSpots = appModel.getSelectionModel().getSelectedVertices();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@
import org.mastodon.mamut.model.Spot;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

public class SortTreeUtilsTest
{
Expand Down Expand Up @@ -96,6 +98,52 @@ public void testTagAverageLocation() {
assertArrayEquals( array(2,3,4), averagePosition, 0.0 );
}

@Test
public void calculateAveragePosition_withMultipleSpots()
{
// setup
int numTimepoints = 4;
ModelGraph graph = new ModelGraph();
Spot a = graph.addVertex().init( 1, array( 1, 2, 3 ), 0.5 );
Spot b = graph.addVertex().init( 1, array( 3, 4, 5 ), 0.5 );
Spot c = graph.addVertex().init( 2, array( 5, 6, 7 ), 0.5 );
graph.addVertex().init( 3, array( 7, 8, 9 ), 0.5 );
// process
List< double[] > averages = SortTreeUtils.calculateAveragePosition( numTimepoints, Arrays.asList( a, b, c ) );
// test
assertEquals( numTimepoints, averages.size() );
assertNull( averages.get( 0 ) );
assertArrayEquals( array( 2, 3, 4 ), averages.get( 1 ), 0.0 );
assertArrayEquals( array( 5, 6, 7 ), averages.get( 2 ), 0.0 );
assertNull( averages.get( 3 ) );
}

@Test
public void calculateAveragePosition_withNoSpots()
{
// process
int numTimepoints = 2;
List< double[] > averages = SortTreeUtils.calculateAveragePosition( numTimepoints, Collections.emptyList() );
// test
assertEquals( numTimepoints, averages.size() );
assertNull( averages.get( 0 ) );
assertNull( averages.get( 1 ) );
}

@Test
public void calculateAveragePosition_withSingleSpot()
{
// setup
int numTimepoints = 1;
ModelGraph graph = new ModelGraph();
Spot a = graph.addVertex().init( 0, array( 1, 2, 3 ), 0.5 );
// process
List< double[] > averages = SortTreeUtils.calculateAveragePosition( numTimepoints, Collections.singletonList( a ) );
// test
assertEquals( numTimepoints, averages.size() );
assertArrayEquals( array( 1, 2, 3 ), averages.get( 0 ), 0.0 );
}

@Test
public void testInterpolatedLocation() {
ModelGraph graph = new ModelGraph();
Expand Down
Loading