diff --git a/src/main/java/org/mastodon/mamut/tomancak/TomancakPlugins.java b/src/main/java/org/mastodon/mamut/tomancak/TomancakPlugins.java index 74e0d8c7..e6dc1704 100644 --- a/src/main/java/org/mastodon/mamut/tomancak/TomancakPlugins.java +++ b/src/main/java/org/mastodon/mamut/tomancak/TomancakPlugins.java @@ -54,7 +54,7 @@ import org.mastodon.mamut.tomancak.export.ExportCounts; import org.mastodon.mamut.tomancak.export.LineageLengthExporter; import org.mastodon.mamut.tomancak.export.MakePhyloXml; -import org.mastodon.mamut.tomancak.export.spotcounts.ui.ExportSpotCountsView; +import org.mastodon.mamut.tomancak.export.ExportSpotCountsPerTimepointCommand; import org.mastodon.mamut.tomancak.label_systematically.LabelSpotsSystematicallyDialog; import org.mastodon.mamut.tomancak.merging.Dataset; import org.mastodon.mamut.tomancak.merging.MergeDatasets; @@ -94,9 +94,7 @@ public class TomancakPlugins extends AbstractContextual implements MamutPlugin private static final String LABEL_SPOTS_SYSTEMATICALLY = "[tomancak] label spots systematically"; private static final String REMOVE_SOLISTS_SPOTS = "[tomancak] remove solists spots"; private static final String EXPORTS_LINEAGE_LENGTHS = "[tomancak] export lineage lengths"; - 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 MERGE_PROJECTS = "[tomancak] merge projects"; private static final String TWEAK_DATASET_PATH = "[tomancak] fix project image path"; @@ -116,9 +114,7 @@ public class TomancakPlugins extends AbstractContextual implements MamutPlugin private static final String[] LABEL_SPOTS_SYSTEMATICALLY_KEYS = { "not mapped" }; private static final String[] REMOVE_SOLISTS_SPOTS_KEYS = { "not mapped" }; private static final String[] EXPORTS_LINEAGE_LENGTHS_KEYS = { "not mapped" }; - private static final String[] EXPORTS_SPOTS_COUNTS_PER_LINEAGE_KEYS = { "not mapped" }; - private static final String[] EXPORTS_SPOTS_COUNTS_PER_TIMEPOINT_KEYS = { "not mapped" }; private static final String[] MERGE_PROJECTS_KEYS = { "not mapped" }; private static final String[] TWEAK_DATASET_PATH_KEYS = { "not mapped" }; @@ -400,7 +396,7 @@ private void exportCountsPerLineage() private void exportCountsPerTimepoint() { this.getContext().getService( CommandService.class ).run( - ExportSpotCountsView.class, true, + ExportSpotCountsPerTimepointCommand.class, true, "projectModel", pluginAppModel, "context", pluginAppModel.getContext() ); } diff --git a/src/main/java/org/mastodon/mamut/tomancak/export/spotcounts/ExportSpotCountsController.java b/src/main/java/org/mastodon/mamut/tomancak/export/ExportSpotCountsPerTimepointCommand.java similarity index 60% rename from src/main/java/org/mastodon/mamut/tomancak/export/spotcounts/ExportSpotCountsController.java rename to src/main/java/org/mastodon/mamut/tomancak/export/ExportSpotCountsPerTimepointCommand.java index a50dc1e9..5fe28477 100644 --- a/src/main/java/org/mastodon/mamut/tomancak/export/spotcounts/ExportSpotCountsController.java +++ b/src/main/java/org/mastodon/mamut/tomancak/export/ExportSpotCountsPerTimepointCommand.java @@ -1,8 +1,8 @@ /*- * #%L - * mastodon-deep-lineage + * mastodon-tomancak * %% - * Copyright (C) 2022 - 2023 Stefan Hahmann + * Copyright (C) 2018 - 2024 Tobias Pietzsch * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -26,34 +26,60 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package org.mastodon.mamut.tomancak.export.spotcounts; +package org.mastodon.mamut.tomancak.export; -import com.opencsv.CSVWriter; import org.mastodon.mamut.ProjectModel; import org.mastodon.mamut.model.Model; import org.mastodon.util.TreeUtils; import org.scijava.Context; +import org.scijava.ItemVisibility; import org.scijava.app.StatusService; +import org.scijava.command.Command; +import org.scijava.plugin.Parameter; +import org.scijava.plugin.Plugin; import java.io.File; import java.io.FileWriter; import java.io.IOException; -public class ExportSpotCountsController +import com.opencsv.CSVWriter; + +import sun.tools.java.ClassNotFound; + +@Plugin( type = Command.class, label = "Export spot counts per timepoint" ) +public class ExportSpotCountsPerTimepointCommand implements Command { - private final Model model; - private final StatusService statusService; + @Parameter( visibility = ItemVisibility.MESSAGE, required = false, persist = false ) + private String documentation = "\n" + + "\n" + + "

Export spot counts per timepoint

\n" + + "

This command writes the timepoint and the number of spots at each timepoint to a single CSV file.

\n" + + "

The format is: \"timepoint\", \"number of spots\".

\n" + + "

It is recommended to use '*.csv' as file extension.

\n" + + "\n" + + "\n"; - public ExportSpotCountsController( final ProjectModel projectModel, final Context context ) - { - this( projectModel.getModel(), context ); - } + @Parameter( label = "Save to" ) + private File saveTo; + + @Parameter + private ProjectModel projectModel; + + @Parameter + private Context context; - protected ExportSpotCountsController( final Model model, final Context context ) + @Override + public void run() { - this.model = model; - this.statusService = context.service( StatusService.class ); + try + { + writeSpotCountsToFile( projectModel.getModel(), saveTo, context.service( StatusService.class ) ); + } + catch ( IOException e ) + { + System.err.println( "Could not write spot counts to file: " + saveTo.getAbsolutePath() + ". Error message: " + e.getMessage() ); + } } /** @@ -64,28 +90,23 @@ protected ExportSpotCountsController( final Model model, final Context context ) *
  • The format is: "timepoint", "number of spots".
  • *
  • The first line is the header.
  • * - * - * @param file the file to write to. */ - public void writeSpotCountsToFile( final File file ) + public static void writeSpotCountsToFile( final Model model, final File file, final StatusService statusService ) throws IOException { if ( file == null ) throw new IllegalArgumentException( "Cannot write spot counts to file. Given file is null." ); - try (FileWriter fileWriter = new FileWriter( file ); CSVWriter csvWriter = new CSVWriter( fileWriter )) + try (CSVWriter csvWriter = new CSVWriter( new FileWriter( file ) )) { csvWriter.writeNext( new String[] { "timepoint", "spots" } ); + int minTimepoint = TreeUtils.getMinTimepoint( model ); int maxTimepoint = TreeUtils.getMaxTimepoint( model ); - for ( int timepoint = TreeUtils.getMinTimepoint( model ); timepoint <= maxTimepoint; timepoint++ ) + for ( int timepoint = minTimepoint; timepoint <= maxTimepoint; timepoint++ ) { int spots = model.getSpatioTemporalIndex().getSpatialIndex( timepoint ).size(); - csvWriter.writeNext( new String[] { String.valueOf( timepoint ), String.valueOf( spots ) } ); + csvWriter.writeNext( new String[] { String.valueOf( timepoint ), String.valueOf( spots ) }, false ); statusService.showProgress( timepoint, maxTimepoint ); } } - catch ( IOException e ) - { - System.err.println( "Could not write spot counts to file: " + file.getAbsolutePath() + ". Error message: " + e.getMessage() ); - } } } diff --git a/src/main/java/org/mastodon/mamut/tomancak/export/spotcounts/ui/ExportSpotCountsView.java b/src/main/java/org/mastodon/mamut/tomancak/export/spotcounts/ui/ExportSpotCountsView.java deleted file mode 100644 index 3abed8c6..00000000 --- a/src/main/java/org/mastodon/mamut/tomancak/export/spotcounts/ui/ExportSpotCountsView.java +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * #%L - * mastodon-deep-lineage - * %% - * Copyright (C) 2022 - 2023 Stefan Hahmann - * %% - * 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 org.mastodon.mamut.tomancak.export.spotcounts.ui; - -import org.mastodon.mamut.ProjectModel; -import org.mastodon.mamut.tomancak.export.spotcounts.ExportSpotCountsController; -import org.scijava.Context; -import org.scijava.ItemVisibility; -import org.scijava.command.Command; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; - -import java.io.File; - -@Plugin( type = Command.class, label = "Export spot counts per timepoint" ) -public class ExportSpotCountsView implements Command -{ - private static final int WIDTH = 15; - - @SuppressWarnings( "all" ) - @Parameter( visibility = ItemVisibility.MESSAGE, required = false, persist = false ) - private String documentation = "\n" - + "\n" - + "

    Export spot counts per timepoint

    \n" - + "

    This command writes the timepoint and the number of spots at each timepoint to a single CSV file.

    \n" - + "

    The format is: \"timepoint\", \"number of spots\".

    \n" - + "

    It is recommended to use '*.csv' as file extension.

    \n" - + "\n" - + "\n"; - - @SuppressWarnings( "unused" ) - @Parameter( label = "Save to" ) - private File saveTo; - - @SuppressWarnings( "unused" ) - @Parameter - private ProjectModel projectModel; - - @SuppressWarnings( "unused" ) - @Parameter - private Context context; - - @Override - public void run() - { - ExportSpotCountsController controller = new ExportSpotCountsController( projectModel, context ); - controller.writeSpotCountsToFile( saveTo ); - } -} diff --git a/src/test/java/org/mastodon/mamut/tomancak/export/ExportSpotCountsPerTimepointCommandTest.java b/src/test/java/org/mastodon/mamut/tomancak/export/ExportSpotCountsPerTimepointCommandTest.java new file mode 100644 index 00000000..7cd97412 --- /dev/null +++ b/src/test/java/org/mastodon/mamut/tomancak/export/ExportSpotCountsPerTimepointCommandTest.java @@ -0,0 +1,75 @@ +/*- + * #%L + * mastodon-tomancak + * %% + * Copyright (C) 2018 - 2024 Tobias Pietzsch + * %% + * 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 org.mastodon.mamut.tomancak.export; + +import org.apache.commons.io.FileUtils; +import org.junit.Test; +import org.mastodon.mamut.feature.branch.exampleGraph.ExampleGraph2; +import org.mastodon.mamut.model.Model; +import org.mastodon.mamut.tomancak.export.ExportSpotCountsPerTimepointCommand; +import org.scijava.Context; +import org.scijava.app.StatusService; + +import java.io.File; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +/** + * Tests {@link ExportSpotCountsPerTimepointCommand} + */ +public class ExportSpotCountsPerTimepointCommandTest +{ + + @Test + public void testWriteSpotCountsToFile() throws IOException + { + try (Context context = new Context()) + { + Model model = new ExampleGraph2().getModel(); + File outputFile = File.createTempFile( "spotcounts", ".csv" ); + outputFile.deleteOnExit(); + StatusService service = context.service( StatusService.class ); + + ExportSpotCountsPerTimepointCommand.writeSpotCountsToFile( model, outputFile, service ); + + String content = FileUtils.readFileToString( outputFile ); + String expected = "\"timepoint\",\"spots\"\n" + + "0,1\n" + + "1,1\n" + + "2,1\n" + + "3,2\n" + + "4,1\n" + + "5,3\n" + + "6,1\n" + + "7,2\n"; + assertEquals( expected, content ); + } + } +} diff --git a/src/test/java/org/mastodon/mamut/tomancak/export/spotcounts/ExportSpotCountsControllerTest.java b/src/test/java/org/mastodon/mamut/tomancak/export/spotcounts/ExportSpotCountsControllerTest.java deleted file mode 100644 index f3adb42e..00000000 --- a/src/test/java/org/mastodon/mamut/tomancak/export/spotcounts/ExportSpotCountsControllerTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/*- - * #%L - * mastodon-deep-lineage - * %% - * Copyright (C) 2022 - 2023 Stefan Hahmann - * %% - * 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 org.mastodon.mamut.tomancak.export.spotcounts; - -import com.opencsv.CSVReader; -import org.junit.Before; -import org.junit.Test; -import org.mastodon.mamut.feature.branch.exampleGraph.ExampleGraph2; -import org.scijava.Context; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.Iterator; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertThrows; - -public class ExportSpotCountsControllerTest -{ - private ExampleGraph2 exampleGraph2; - - @Before - public void setUp() - { - exampleGraph2 = new ExampleGraph2(); - } - - @Test - public void testWriteSpotCountsToFile() throws IOException - { - File outputFile = File.createTempFile( "spotcounts", ".csv" ); - outputFile.deleteOnExit(); - ExportSpotCountsController controller = new ExportSpotCountsController( exampleGraph2.getModel(), new Context() ); - controller.writeSpotCountsToFile( outputFile ); - - // Check if the file was written correctly - try (CSVReader reader = new CSVReader( new FileReader( outputFile ) );) - { - Iterator< String[] > iterator = reader.iterator(); - String[] header = iterator.next(); - String[] line0 = iterator.next(); - String[] line1 = iterator.next(); - String[] line2 = iterator.next(); - String[] line3 = iterator.next(); - String[] line4 = iterator.next(); - String[] line5 = iterator.next(); - String[] line6 = iterator.next(); - String[] line7 = iterator.next(); - - assertArrayEquals( new String[] { "timepoint", "spots" }, header ); - assertArrayEquals( new String[] { "0", "1" }, line0 ); - assertArrayEquals( new String[] { "1", "1" }, line1 ); - assertArrayEquals( new String[] { "2", "1" }, line2 ); - assertArrayEquals( new String[] { "3", "2" }, line3 ); - assertArrayEquals( new String[] { "4", "1" }, line4 ); - assertArrayEquals( new String[] { "5", "3" }, line5 ); - assertArrayEquals( new String[] { "6", "1" }, line6 ); - assertArrayEquals( new String[] { "7", "2" }, line7 ); - } - } - - @Test - public void testException() - { - ExportSpotCountsController controller = new ExportSpotCountsController( exampleGraph2.getModel(), new Context() ); - assertThrows( IllegalArgumentException.class, () -> controller.writeSpotCountsToFile( null ) ); - } -}