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

Conda returns #50

Merged
merged 3 commits into from
Aug 12, 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
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ ext.qupathVersion = gradle.ext.qupathVersion

description = 'QuPath extension to use Cellpose'

version = "0.9.3"
version = "0.9.4-SNAPSHOT"

dependencies {
implementation "io.github.qupath:qupath-gui-fx:${qupathVersion}"
Expand Down
197 changes: 131 additions & 66 deletions src/main/java/qupath/ext/biop/cellpose/Cellpose2D.java

Large diffs are not rendered by default.

27 changes: 15 additions & 12 deletions src/main/java/qupath/ext/biop/cellpose/CellposeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public class CellposeBuilder {
// Cellpose Related Options
private String modelNameOrPath;
// Cellpose Training options
private File modelDirectory = null;
private transient File modelDirectory = null;
// QuPath Object handling options
private ColorTransform[] channels = new ColorTransform[0];
private Double cellExpansion = Double.NaN;
Expand All @@ -89,13 +89,14 @@ public class CellposeBuilder {
private TileOpCreator globalPreprocessing;
private int nThreads = -1;

private File tempDirectory = null;
private File groundTruthDirectory = null;
private transient File tempDirectory = null;
private transient File groundTruthDirectory = null;

private ImageOp extendChannelOp = null;

private boolean doReadResultsAsynchronously = false;
private boolean useGPU = true;
private String outputModelName;

/**
* can create a cellpose builder from a serialized JSON version of this builder.
Expand Down Expand Up @@ -581,7 +582,7 @@ public CellposeBuilder addParameter(String flagName) {
* @return this builder
*/
public CellposeBuilder useOmnipose() {
if (cellposeSetup.getOmniposePytonPath() == "")
if (cellposeSetup.getOmniposePythonPath() == "")
logger.warn("Omnipose environment path not set. Using cellpose path instead.");
addParameter("omni");
return this;
Expand Down Expand Up @@ -759,7 +760,7 @@ public CellposeBuilder normalizePercentilesGlobal(double percentileMin, double p
// Deactivate cellpose normalization
this.noCellposeNormalization();

// Add this operation the the preprocessing
// Add this operation to the preprocessing
return this.preprocess(normOp);
}

Expand All @@ -772,6 +773,10 @@ public CellposeBuilder noCellposeNormalization() {
return this.addParameter("no_norm");
}

public CellposeBuilder setOutputModelName(String outputName) {
this.outputModelName = outputName;
return this;
}
/**
* Create a {@link Cellpose2D}, all ready for detection.
*
Expand Down Expand Up @@ -812,13 +817,10 @@ public Cellpose2D build() {

if (this.modelDirectory == null) {
this.modelDirectory = new File(quPathProjectDir, "models");
this.modelDirectory.mkdirs();
}

// Define training and validation directories inside the QuPath Project
File trainDirectory = new File(groundTruthDirectory, "train");
File valDirectory = new File(groundTruthDirectory, "test");


cellpose.outputModelName = outputModelName;
cellpose.modelDirectory = modelDirectory;
cellpose.groundTruthDirectory = groundTruthDirectory;
cellpose.tempDirectory = tempDirectory;
Expand Down Expand Up @@ -851,6 +853,7 @@ public Cellpose2D build() {
cellpose.constrainToParent = constrainToParent;
cellpose.creatorFun = creatorFun;
cellpose.globalPathClass = globalPathClass;
cellpose.outputModelName = outputModelName;

cellpose.compartments = new LinkedHashSet<>(compartments);

Expand All @@ -869,9 +872,9 @@ public Cellpose2D build() {
cellpose.overlap = 30 * 2;
logger.info("Tile overlap was not set and diameter was set to {}. Will default to {} pixels overlap. Use `.setOverlap( int )` to modify overlap", diameter, cellpose.overlap);
} else {
cellpose.overlap = (int) (diameter * 2);
logger.info("Tile overlap was not set, but diameter exists. Using provided diameter {} x 2: {} pixels overlap", diameter, cellpose.overlap);
}
cellpose.overlap = (int) (diameter * 2);
logger.info("Tile overlap was not set, but diameter exists. Using provided diameter {} x 2: {} pixels overlap", diameter, cellpose.overlap);
} else { // Nothing was set, let's get lucky
cellpose.overlap = 30 * 2;
logger.info("Neither diameter nor overlap provided. Overlap defaulting to {} pixels. Use `.setOverlap( int )` to modify overlap", cellpose.overlap);
Expand Down
21 changes: 16 additions & 5 deletions src/main/java/qupath/ext/biop/cellpose/CellposeExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,19 @@ public void installExtension(QuPathGUI qupath) {
// Create the options we need
StringProperty cellposePath = PathPrefs.createPersistentPreference("cellposePythonPath", "");
StringProperty omniposePath = PathPrefs.createPersistentPreference("omniposePythonPath", "");
StringProperty condaPath = PathPrefs.createPersistentPreference("condaPath", "");


//Set options to current values
options.setCellposePytonPath(cellposePath.get());
options.setOmniposePytonPath(omniposePath.get());
options.setCellposePythonPath(cellposePath.get());
options.setOmniposePythonPath(omniposePath.get());
options.setCondaPath(condaPath.get());

// Listen for property changes
cellposePath.addListener((v, o, n) -> options.setCellposePytonPath(n));
omniposePath.addListener((v, o, n) -> options.setOmniposePytonPath(n));
cellposePath.addListener((v, o, n) -> options.setCellposePythonPath(n));
omniposePath.addListener((v, o, n) -> options.setOmniposePythonPath(n));
condaPath.addListener((v, o, n) -> options.setCondaPath(n));


PropertySheet.Item cellposePathItem = new PropertyItemBuilder<>(cellposePath, String.class)
.propertyType(PropertyItemBuilder.PropertyType.GENERAL)
Expand All @@ -91,8 +95,15 @@ public void installExtension(QuPathGUI qupath) {
.description("Enter the full path to your omnipose environment, including 'python.exe'")
.build();

PropertySheet.Item condaPathItem = new PropertyItemBuilder<>(condaPath, String.class)
.propertyType(PropertyItemBuilder.PropertyType.GENERAL)
.name("'Conda' script location (optional)")
.category("Cellpose/Omnipose")
.description("The full path to you conda/mamba command, in case you want the extension to use the 'conda activate' command.\ne.g 'C:\\ProgramData\\Miniconda3\\condabin\\mamba.bat'")
.build();

// Add Permanent Preferences and Populate Preferences
QuPathGUI.getInstance().getPreferencePane().getPropertySheet().getItems().addAll(cellposePathItem, omniposePathItem);
QuPathGUI.getInstance().getPreferencePane().getPropertySheet().getItems().addAll(cellposePathItem, omniposePathItem, condaPathItem);

}

Expand Down
16 changes: 10 additions & 6 deletions src/main/java/qupath/ext/biop/cellpose/CellposeSetup.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
package qupath.ext.biop.cellpose;

import qupath.ext.biop.cmd.VirtualEnvironmentRunner.EnvType;

public class CellposeSetup {
private static final CellposeSetup instance = new CellposeSetup();
private String cellposePythonPath = null;
private String omniposePythonPath = null;

private String condaPath = null;

public static CellposeSetup getInstance() {
return instance;
}

public String getCellposePytonPath() {
public String getCellposePythonPath() {
return cellposePythonPath;
}

public void setCellposePytonPath(String path) {
public void setCellposePythonPath(String path) {
this.cellposePythonPath = path;
}

public String getOmniposePytonPath() {
public String getOmniposePythonPath() {
return omniposePythonPath;
}

public void setOmniposePytonPath(String path) {
public void setOmniposePythonPath(String path) {
this.omniposePythonPath = path;
}

public void setCondaPath(String condaPath) { this.condaPath = condaPath; }

public String getCondaPath() { return condaPath; }
}
19 changes: 17 additions & 2 deletions src/main/java/qupath/ext/biop/cmd/VirtualEnvironmentRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
public class VirtualEnvironmentRunner {
private final static Logger logger = LoggerFactory.getLogger(VirtualEnvironmentRunner.class);
private final EnvType envType;

private final String condaPath;

private WatchService watchService;
private String name;
private String pythonPath;
Expand Down Expand Up @@ -61,9 +64,14 @@ public String toString() {
}

public VirtualEnvironmentRunner(String environmentNameOrPath, EnvType type, String name) {
this(environmentNameOrPath, type, null, name );
}

public VirtualEnvironmentRunner(String environmentNameOrPath, EnvType type, String condaPath, String name) {
this.pythonPath = environmentNameOrPath;
this.envType = type;
this.name = name;
this.condaPath = condaPath;
if (envType.equals(EnvType.OTHER))
logger.error("Environment is unknown, please set the environment type to something different than 'Other'");
}
Expand All @@ -79,18 +87,25 @@ private List<String> getActivationCommand() {

Platform platform = Platform.getCurrent();
List<String> cmd = new ArrayList<>();
String condaCommand = this.condaPath;

switch (envType) {
case CONDA:
switch (platform) {
case WINDOWS:
if( condaCommand == null ) {
condaCommand = "conda.bat";
}
// Adjust path to the folder with the env name based on the python location. On Windows it's at the root of the environment
cmd.addAll(Arrays.asList("CALL", "conda.bat", "activate", new File(pythonPath).getParent(), "&", "python"));
cmd.addAll(Arrays.asList("CALL", condaCommand, "activate", new File(pythonPath).getParent(), "&", "python"));
break;
case UNIX:
case OSX:
if( condaCommand == null ) {
condaCommand = "conda";
}
// Adjust path to the folder with the env name based on the python location. In Linux/MacOS it's in the 'bin' sub folder
cmd.addAll(Arrays.asList("conda", "activate", new File(pythonPath).getParentFile().getParent(), ";", "python"));
cmd.addAll(Arrays.asList(condaCommand, "activate", new File(pythonPath).getParentFile().getParent(), ";", "python"));
break;
}
break;
Expand Down
Loading