diff --git a/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose3.java b/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose3.java index 57f88952f..da4745af1 100644 --- a/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose3.java +++ b/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose3.java @@ -33,6 +33,7 @@ import javax.annotation.Nullable; import org.apposed.appose.Service; +import org.mastodon.mamut.util.ResourceUtils; /** * Cellpose3 is a specialized implementation of the {@link Cellpose} class, specifically @@ -43,21 +44,11 @@ public class Cellpose3 extends Cellpose { public static final String ENV_NAME = "cellpose3"; - public static final String ENV_FILE_CONTENT = "name: " + ENV_NAME + "\n" - + "channels:\n" - + " - nvidia\n" - + " - pytorch\n" - + " - conda-forge\n" - + "channel_priority: strict\n" - + "dependencies:\n" - + " - python=3.10\n" - + " - pip\n" - + " - pip:\n" - + " - cellpose==3.1.1.2\n" - + " - appose==" + APPOSE_PYTHON_VERSION + "\n" - + " - pytorch\n" - + " - pytorch-cuda\n" - + " - numpy\n"; + public static final String ENV_FILE_CONTENT = + ResourceUtils.readResourceAsString( "org/mastodon/mamut/detection/cellpose/cellpose3.toml", Cellpose3.class ) + .replace( "{ENV_NAME}", ENV_NAME ) + .replace( "{APPOSE_VERSION}", APPOSE_PYTHON_VERSION ); + private final ModelType modelType; diff --git a/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose3Detector.java b/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose3Detector.java index 3138a8e96..4a19f6f68 100644 --- a/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose3Detector.java +++ b/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose3Detector.java @@ -179,7 +179,7 @@ protected String getPythonEnvName() @Override protected Builder< ? > getBuilder() { - return Appose.mamba().scheme( "environment.yml" ); + return Appose.pixi(); } @Override diff --git a/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose4.java b/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose4.java index 9f99a39e6..2f0ba78cf 100644 --- a/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose4.java +++ b/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose4.java @@ -33,6 +33,7 @@ import javax.annotation.Nullable; import org.apposed.appose.Service; +import org.mastodon.mamut.util.ResourceUtils; /** * Cellpose3 is a specialized implementation of the {@link Cellpose} class, specifically @@ -42,21 +43,10 @@ public class Cellpose4 extends Cellpose { public static final String ENV_NAME = "cellpose4"; - public static final String ENV_FILE_CONTENT = "name: " + ENV_NAME + "\n" - + "channels:\n" - + " - nvidia\n" - + " - pytorch\n" - + " - conda-forge\n" - + "channel_priority: strict\n" - + "dependencies:\n" - + " - python=3.10\n" - + " - cellpose==4.0.6\n" - + " - pytorch\n" - + " - pytorch-cuda\n" - + " - numpy\n" - + " - pip\n" - + " - pip:\n" - + " - appose==" + APPOSE_PYTHON_VERSION + "\n"; + public static final String ENV_FILE_CONTENT = + ResourceUtils.readResourceAsString( "org/mastodon/mamut/detection/cellpose/cellpose4.toml", Cellpose4.class ) + .replace( "{ENV_NAME}", ENV_NAME ) + .replace( "{APPOSE_VERSION}", APPOSE_PYTHON_VERSION ); public Cellpose4( final Service python, final @Nullable org.scijava.log.Logger scijavaLogger ) throws IOException { diff --git a/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose4Detector.java b/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose4Detector.java index 553c58343..cdee6f066 100644 --- a/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose4Detector.java +++ b/src/main/java/org/mastodon/mamut/detection/cellpose/Cellpose4Detector.java @@ -163,7 +163,7 @@ protected String getPythonEnvName() @Override protected Builder< ? > getBuilder() { - return Appose.mamba().scheme( "environment.yml" ); + return Appose.pixi(); } @Override diff --git a/src/main/java/org/mastodon/mamut/detection/stardist/StarDist.java b/src/main/java/org/mastodon/mamut/detection/stardist/StarDist.java index 516d2dde8..4b55ab5c1 100644 --- a/src/main/java/org/mastodon/mamut/detection/stardist/StarDist.java +++ b/src/main/java/org/mastodon/mamut/detection/stardist/StarDist.java @@ -178,13 +178,13 @@ private Path getStarDistModelRoot() { if ( modelType.getModelPath() == null ) return null; - return Paths.get( System.getProperty( "user.home" ), ".local", "share", "appose", "stardist", "models", modelType.getModelPath() ); + return Paths.get( System.getProperty( "user.home" ), ".local", "share", "appose", ENV_NAME, "models", modelType.getModelPath() ); } private static void createConfigFromBioimageio( final ModelDescriptor descriptor, final String modelDir ) throws IOException { - Map< String, Object > stardistMap = Cast.unchecked( descriptor.getConfig().getSpecMap().get( "stardist" ) ); + Map< String, Object > stardistMap = Cast.unchecked( descriptor.getConfig().getSpecMap().get( ENV_NAME ) ); Map< String, Object > stardistConfig = Cast.unchecked( stardistMap.get( "config" ) ); File jsonFile = new File( modelDir, "config.json" ); logger.info( "Creating config.json file: {}", jsonFile.getAbsolutePath() ); diff --git a/src/main/java/org/mastodon/mamut/util/appose/ApposeUtils.java b/src/main/java/org/mastodon/mamut/util/appose/ApposeUtils.java index b08d9ef91..e149bb5bd 100644 --- a/src/main/java/org/mastodon/mamut/util/appose/ApposeUtils.java +++ b/src/main/java/org/mastodon/mamut/util/appose/ApposeUtils.java @@ -46,7 +46,7 @@ import javax.swing.SwingUtilities; import org.apache.commons.lang3.tuple.Pair; -import org.apposed.appose.Appose; +import org.apposed.appose.Builder; import org.apposed.appose.builder.Builders; import org.apposed.appose.util.Environments; import org.mastodon.mamut.util.ByteFormatter; @@ -71,9 +71,9 @@ private ApposeUtils() * to set up the environment. * @throws IOException If an I/O error occurs during the installation process. */ - public static void installEnvironment( final String envContent ) throws IOException + public static void installEnvironment(final String envContent, final Builder envBuilder) throws IOException { - Appose.mamba().content( envContent ).scheme( "environment.yml" ).logDebug().rebuild(); + envBuilder.content( envContent ).logDebug().rebuild(); } /** diff --git a/src/main/java/org/mastodon/mamut/util/appose/PythonEnvironmentManagerUI.java b/src/main/java/org/mastodon/mamut/util/appose/PythonEnvironmentManagerUI.java index 86353d26b..5cc0457a8 100644 --- a/src/main/java/org/mastodon/mamut/util/appose/PythonEnvironmentManagerUI.java +++ b/src/main/java/org/mastodon/mamut/util/appose/PythonEnvironmentManagerUI.java @@ -60,6 +60,8 @@ import net.miginfocom.swing.MigLayout; +import org.apposed.appose.Appose; +import org.apposed.appose.Builder; import org.apposed.appose.util.Environments; import org.mastodon.app.MastodonIcons; import org.mastodon.mamut.detection.cellpose.Cellpose3; @@ -104,10 +106,10 @@ public PythonEnvironmentManagerUI( JFrame owner ) private void initEnvironmentPanels() { environmentPanels = new ArrayList<>(); - environmentPanels.add( new EnvironmentPanel( Cellpose3.ENV_NAME, Cellpose3.ENV_FILE_CONTENT ) ); - environmentPanels.add( new EnvironmentPanel( Cellpose4.ENV_NAME, Cellpose4.ENV_FILE_CONTENT ) ); - environmentPanels.add( new EnvironmentPanel( StarDist.ENV_NAME, StarDist.ENV_FILE_CONTENT ) ); - environmentPanels.add( new EnvironmentPanel( TrackastraUtils.ENV_NAME, TrackastraUtils.ENV_FILE_CONTENT ) ); + environmentPanels.add( new EnvironmentPanel( Cellpose3.ENV_NAME, Cellpose3.ENV_FILE_CONTENT, Appose.pixi() ) ); + environmentPanels.add( new EnvironmentPanel( Cellpose4.ENV_NAME, Cellpose4.ENV_FILE_CONTENT, Appose.pixi() ) ); + environmentPanels.add( new EnvironmentPanel( StarDist.ENV_NAME, StarDist.ENV_FILE_CONTENT, Appose.pixi() ) ); + environmentPanels.add( new EnvironmentPanel( TrackastraUtils.ENV_NAME, TrackastraUtils.ENV_FILE_CONTENT, Appose.mamba().scheme( "environment.yml" ) ) ); } private void initLayout() @@ -163,6 +165,8 @@ private class EnvironmentPanel extends JPanel private final String envContent; + private final Builder< ? > envBuilder; + private final JLabel statusIcon; private final JLabel statusLabel; @@ -173,11 +177,12 @@ private class EnvironmentPanel extends JPanel private final JLabel sizeValueLabel; - private EnvironmentPanel( String envName, String envContent ) + private EnvironmentPanel( final String envName, final String envContent, final Builder< ? > envBuilder ) { super( new MigLayout( "fill, insets 8", "[][80!][grow][]", "[]5[]5[]" ) ); this.envName = envName; this.envContent = envContent; + this.envBuilder = envBuilder; statusIcon = new JLabel(); statusLabel = new JLabel(); @@ -358,7 +363,7 @@ private void installEnvironmentUI() () -> { try { - ApposeUtils.installEnvironment( envContent ); + ApposeUtils.installEnvironment( envContent, envBuilder ); } catch ( IOException e ) { diff --git a/src/main/resources/org/mastodon/mamut/detection/cellpose/cellpose3.toml b/src/main/resources/org/mastodon/mamut/detection/cellpose/cellpose3.toml new file mode 100644 index 000000000..85a3ede65 --- /dev/null +++ b/src/main/resources/org/mastodon/mamut/detection/cellpose/cellpose3.toml @@ -0,0 +1,58 @@ +[workspace] +name = "{ENV_NAME}" +version = "0.0.1" +description = "Cellpose3 segmentation environment." +authors = ["Stefan Hahmann"] +channels = ["conda-forge", "pytorch", "nvidia"] +platforms = ["osx-arm64", "osx-64", "linux-64", "win-64"] + +[dependencies] +numpy = ">=1.20,<2.1" +pip = "*" + +[pypi-dependencies] +appose = "=={APPOSE_VERSION}" + +# --------------------------------------------------------------------------- +# macOS Apple Silicon +# --------------------------------------------------------------------------- +[target.osx-arm64.dependencies] +python = "3.10.*" + +[target.osx-arm64.pypi-dependencies] +cellpose = "==3.1.1.2" +torch = "==2.10.0" +torchvision = "==0.25.0" + +# --------------------------------------------------------------------------- +# macOS Intel +# --------------------------------------------------------------------------- +[target.osx-64.dependencies] +python = "3.10.*" + +[target.osx-64.pypi-dependencies] +cellpose = "==3.1.1.2" +torch = "==2.1.2" +torchvision = "==0.16.2" + +# --------------------------------------------------------------------------- +# Linux +# --------------------------------------------------------------------------- +[target.linux-64.dependencies] +python = "3.10.*" +pytorch = "*" +pytorch-gpu = "*" + +[target.linux-64.pypi-dependencies] +cellpose = "==3.1.1.2" + +# --------------------------------------------------------------------------- +# Windows +# --------------------------------------------------------------------------- +[target.win-64.dependencies] +python = "3.10.*" +pytorch = "*" +pytorch-gpu = "*" + +[target.win-64.pypi-dependencies] +cellpose = "==3.1.1.2" diff --git a/src/main/resources/org/mastodon/mamut/detection/cellpose/cellpose4.toml b/src/main/resources/org/mastodon/mamut/detection/cellpose/cellpose4.toml new file mode 100644 index 000000000..459cd820e --- /dev/null +++ b/src/main/resources/org/mastodon/mamut/detection/cellpose/cellpose4.toml @@ -0,0 +1,58 @@ +[workspace] +name = "{ENV_NAME}" +version = "0.0.1" +description = "Cellpose4 segmentation environment." +authors = ["Stefan Hahmann"] +channels = ["conda-forge", "pytorch", "nvidia"] +platforms = ["osx-arm64", "osx-64", "linux-64", "win-64"] + +[dependencies] +numpy = "*" +pip = "*" + +[pypi-dependencies] +appose = "=={APPOSE_VERSION}" + +# --------------------------------------------------------------------------- +# macOS Apple Silicon +# --------------------------------------------------------------------------- +[target.osx-arm64.dependencies] +python = "3.11.*" + +[target.osx-arm64.pypi-dependencies] +cellpose = "==4.0.8" +torch = "==2.10.0" +torchvision = "==0.25.0" + +# --------------------------------------------------------------------------- +# macOS Intel +# --------------------------------------------------------------------------- +[target.osx-64.dependencies] +python = "3.10.*" + +[target.osx-64.pypi-dependencies] +cellpose = "==4.0.8" +torch = "==2.1.2" +torchvision = "==0.16.2" + +# --------------------------------------------------------------------------- +# Linux +# --------------------------------------------------------------------------- +[target.linux-64.dependencies] +python = "3.10.*" +pytorch = "*" +pytorch-gpu = "*" + +[target.linux-64.pypi-dependencies] +cellpose = "==4.0.8" + +# --------------------------------------------------------------------------- +# Windows +# --------------------------------------------------------------------------- +[target.win-64.dependencies] +python = "3.10.*" +pytorch = "*" +pytorch-gpu = "*" + +[target.win-64.pypi-dependencies] +cellpose = "==4.0.8" diff --git a/src/test/java/org/mastodon/mamut/detection/cellpose/Cellpose4DetectorTest.java b/src/test/java/org/mastodon/mamut/detection/cellpose/Cellpose4DetectorTest.java index 9547dcc6b..2f60c00fb 100644 --- a/src/test/java/org/mastodon/mamut/detection/cellpose/Cellpose4DetectorTest.java +++ b/src/test/java/org/mastodon/mamut/detection/cellpose/Cellpose4DetectorTest.java @@ -58,7 +58,7 @@ class Cellpose4DetectorTest { - @Disabled( "This test is disabled, because it has very long runtime (> 5 minutes)" ) + // @Disabled( "This test is disabled, because it has very long runtime (> 5 minutes)" ) @Test void testCompute3D() throws IllegalAccessException, NoSuchFieldException { diff --git a/src/test/java/org/mastodon/mamut/util/appose/ApposeUtilsTest.java b/src/test/java/org/mastodon/mamut/util/appose/ApposeUtilsTest.java index 8fcd20ddc..933979d9c 100644 --- a/src/test/java/org/mastodon/mamut/util/appose/ApposeUtilsTest.java +++ b/src/test/java/org/mastodon/mamut/util/appose/ApposeUtilsTest.java @@ -38,6 +38,8 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import org.apposed.appose.Appose; +import org.apposed.appose.Builder; import org.junit.jupiter.api.Test; class ApposeUtilsTest @@ -51,8 +53,9 @@ void testInstallDeleteExistsSize() throws IOException + " - conda-forge\n" + "dependencies:\n" + " - python=3.10\n"; + Builder envBuilder = Appose.mamba().scheme( "environment.yml" ); - ApposeUtils.installEnvironment( testEnvContent ); + ApposeUtils.installEnvironment( testEnvContent, envBuilder ); assertTrue( ApposeUtils.checkEnvironmentInstalled( testEnvName ) ); String size = ApposeUtils.calculateEnvironmentSize( testEnvName ); String numberPart = size.split( " " )[ 0 ]; // "123,4"