Skip to content

Commit

Permalink
Update to build
Browse files Browse the repository at this point in the history
Access the BasicStitching plugin through maven local.
  • Loading branch information
MichaelSNelson committed Dec 20, 2023
1 parent b785116 commit d880c4d
Show file tree
Hide file tree
Showing 17 changed files with 87 additions and 36 deletions.
Binary file modified .gradle/7.5.1/checksums/checksums.lock
Binary file not shown.
Binary file modified .gradle/7.5.1/checksums/md5-checksums.bin
Binary file not shown.
Binary file modified .gradle/7.5.1/checksums/sha1-checksums.bin
Binary file not shown.
Binary file modified .gradle/7.5.1/dependencies-accessors/dependencies-accessors.lock
Binary file not shown.
Binary file modified .gradle/7.5.1/dependencies-accessors/executionHistory.bin
Binary file not shown.
Binary file modified .gradle/7.5.1/executionHistory/executionHistory.bin
Binary file not shown.
Binary file modified .gradle/7.5.1/executionHistory/executionHistory.lock
Binary file not shown.
Binary file modified .gradle/7.5.1/fileHashes/fileHashes.bin
Binary file not shown.
Binary file modified .gradle/7.5.1/fileHashes/fileHashes.lock
Binary file not shown.
Binary file modified .gradle/7.5.1/fileHashes/resourceHashesCache.bin
Binary file not shown.
Binary file modified .gradle/buildOutputCleanup/buildOutputCleanup.lock
Binary file not shown.
Binary file modified .gradle/file-system.probe
Binary file not shown.
10 changes: 10 additions & 0 deletions .idea/jarRepositories.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ dependencies {
shadow "io.github.qupath:qupath-gui-fx:${qupathVersion}"
//Access to BioFormats extension for writing ome.tif files
implementation "io.github.qupath:qupath-extension-bioformats:${qupathVersion}"
//implementation "qupath.ext.basicstitching:BasicStitching:${qupathVersion}"

//TODO figure out syntax for other plugins
//implementation "io.github.qupath:BasicStitchingExtension:${qupathVersion}"
// For logging - the version comes from QuPath's version catalog at
// https://github.com/qupath/qupath/blob/main/gradle/libs.versions.toml
// See https://docs.gradle.org/current/userguide/platforms.html
Expand Down Expand Up @@ -138,17 +139,16 @@ tasks.named('test') {
// within QuPath itself (which is useful during development).
repositories {
// Add this if you need access to dependencies only installed locally
// mavenLocal()

mavenLocal()
/*
flatDir{
dirs 'C:/ImageAnalysis/QPExtensionTest/BasicStitching/build/libs'
}
*/
mavenCentral()

// Add scijava - which is where QuPath's jars are hosted
maven {
url "https://maven.scijava.org/content/repositories/releases"
}

maven {
url "https://maven.scijava.org/content/repositories/snapshots"
url "https://maven.scijava.org/content/groups/public"
}

}
}
17 changes: 9 additions & 8 deletions src/main/groovy/qupath/ext/qp_scope/QP_scope.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,10 @@ import qupath.lib.common.Version;
import qupath.lib.gui.QuPathGUI
import qupath.lib.gui.extensions.QuPathExtension;
import qupath.ext.qp_scope.functions.*
import org.slf4j.LoggerFactory

/**
* This is a demo to provide a template for creating a new QuPath extension in Groovy.
* <p>
* <b>Important!</b> For your extension to work in QuPath, you need to make sure the name & package
* of this class is consistent with the file
* <pre>
* /resources/META-INF/services/qupath.lib.gui.extensions.QuPathExtension
* </pre>
* Built from the QuPath extension template - an extension to control a microscope through a Python interface
*/
class QP_scope implements QuPathExtension {

Expand Down Expand Up @@ -53,9 +48,15 @@ class QP_scope implements QuPathExtension {
}

private void addMenuItem(QuPathGUI qupath) {
def logger = LoggerFactory.getLogger(QuPathGUI.class)
//Check for dependencies and QuPath version
logger.info("QuPath Version")
logger.info(getQuPathVersion().toString())
//TODO how to check if version is supported?

def menu = qupath.getMenu("Extensions>${name}", true)
def fileNameStitching = new MenuItem("Start qp_scope")
// TODO tooltip "Coordinates are expected to be in the format ImageName[xCoordinateInMicrons, yCoordinateInMicrons].tif"
// TODO tooltip
fileNameStitching.setOnAction(e -> {
//TODO check preferences for all necessary entries

Expand Down
32 changes: 24 additions & 8 deletions src/main/groovy/qupath/ext/qp_scope/functions/QP_scope_GUI.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ import javafx.stage.Modality
import qupath.ext.qp_scope.utilities.utilityFunctions
import qupath.lib.gui.dialogs.Dialogs
import groovy.io.FileType
import java.awt.image.BufferedImage
import qupath.lib.images.servers.ImageServerProvider
import qupath.lib.projects.Project
import qupath.lib.gui.QuPathGUI
import qupath.lib.scripting.QP
import qupath.lib.gui.scripting.QPEx
import qupath.ext.basicstitching.BasicStitchingExtension


class QP_scope_GUI {
public class QP_scope_GUI {

// Existing text fields
static TextField x1Field = new TextField("");
Expand All @@ -35,7 +38,7 @@ class QP_scope_GUI {
def dlg = new Dialog<ButtonType>();
dlg.initModality(Modality.APPLICATION_MODAL);
dlg.setTitle("qp_scope");
dlg.setHeaderText("Enter details:");
dlg.setHeaderText("Enter details (LOOK MA! " + BasicStitchingExtension.class.getName() + "!):");

// Set the content
dlg.getDialogPane().setContent(createContent());
Expand Down Expand Up @@ -75,14 +78,28 @@ class QP_scope_GUI {
if ([sampleLabel, x1, y1, x2, y2, virtualEnvPath, pythonScriptPath].any { it == null || it.isEmpty() }) {
Dialogs.showWarningNotification("Warning!", "Incomplete data entered.");
} else {
Object project = utilityFunctions.createProjectFolder(projectsFolderPath,sampleLabel, preferences.firstScanType)
Project currentQuPathProject= utilityFunctions.createProjectFolder(projectsFolderPath, sampleLabel, preferences.firstScanType)

utilityFunctions.runPythonCommand(virtualEnvPath, pythonScriptPath, projectsFolderPath, sampleLabel, x1, y1, x2, y2);

//TODO figure out how to call stitching function in other plugin

utilityFunctions.showAlertDialog("Wait and complete stitching in other version of QuPath")
String stitchedImagePathStr = projectsFolderPath + File.separator + sampleLabel + File.separator + "SlideImages" + File.separator + preferences.firstScanType + sampleLabel;
String stitchedImagePathStr = projectsFolderPath + File.separator + sampleLabel + File.separator + "SlideImages" + File.separator + preferences.firstScanType + sampleLabel + ".ome.tif";
File stitchedImagePath = new File(stitchedImagePathStr);
utilityFunctions.addImageToProject(stitchedImagePath, project)
utilityFunctions.addImageToProject(stitchedImagePath, currentQuPathProject)

//open the newly created project
//https://qupath.github.io/javadoc/docs/qupath/lib/gui/QuPathGUI.html#setProject(qupath.lib.projects.Project)
def qupathGUI = QPEx.getQuPath()

qupathGUI.setProject(currentQuPathProject)
//Find the existing images - there should only be one since the project was just created
def firstImage = currentQuPathProject.getImageList()[0]

//Open the first image
//https://qupath.github.io/javadoc/docs/qupath/lib/gui/QuPathGUI.html#openImageEntry(qupath.lib.projects.ProjectImageEntry)
qupathGUI.openImageEntry(firstImage)

//}
}
Expand Down Expand Up @@ -118,5 +135,4 @@ class QP_scope_GUI {
pane.add(control, 1, rowIndex);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package qupath.ext.qp_scope.utilities

import org.slf4j.LoggerFactory
import qupath.lib.gui.QuPathGUI
import qupath.lib.gui.dialogs.Dialogs
import qupath.lib.images.servers.ImageServerProvider

import qupath.lib.projects.ProjectIO
import java.awt.image.BufferedImage
import qupath.lib.projects.Projects;
import java.io.File
Expand All @@ -30,20 +31,26 @@ class utilityFunctions {
}

static boolean addImageToProject(File stitchedImagePath, Project project){
def logger = LoggerFactory.getLogger(QuPathGUI.class)

def imagePath = stitchedImagePath.getCanonicalPath()
def imagePath = stitchedImagePath.toURI().toString()
//logger.info(imagePath)

def support = ImageServerProvider.getPreferredUriImageSupport(BufferedImage.class, imagePath, "")
println(support)
def support = ImageServerProvider.getPreferredUriImageSupport(BufferedImage.class, imagePath)
//logger.info(support as String)
def builder = support.builders.get(0)
// Make sure we don't have null
if (builder == null) {
print "Image not supported: " + imagePath
logger.warn("Image not supported: " + imagePath)
return false
}

// Add the image as entry to the project
print "Adding: " + imagePath
logger.info("Adding: " + imagePath)
if (project == null) {
logger.warn("Project is null, there must have been a problem creating the project")
return false
}
Object entry = project.addImage(builder)

// Set a particular image type
Expand All @@ -63,6 +70,8 @@ class utilityFunctions {
}

static Project createProjectFolder(String projectsFolderPath, String sampleLabel, String scanType) {
//TODO check if a project is open! It probably should not be?

// Ensure that the projectsFolderPath exists, if it does not, create it.
File projectsFolder = new File(projectsFolderPath)
if (!projectsFolder.exists()) {
Expand All @@ -76,15 +85,28 @@ class utilityFunctions {
}

// Check for a .qpproj file in the sampleLabel folder
File[] qpprojFiles = sampleLabelFolder.listFiles({ File f -> f.name.endsWith('.qpproj') } as FilenameFilter)
//Create a QuPath project in the sampleLabelFolder, within the projects folder
File[] qpprojFiles = sampleLabelFolder.listFiles({ dir, name -> name.endsWith('.qpproj') } as FilenameFilter)
//Create a QuPath project in the sampleLabelFolder, within the projects folder, provided there are no existing .qpproj files
Project project = null
if (qpprojFiles == null || qpprojFiles.length == 0) {
project = Projects.createProject(sampleLabelFolder, BufferedImage.class)
}else{
//WARNING: This assumes there will be only one file ending in .qpproj
// this should USUALLY be a safe assumption
if (qpprojFiles.length > 1){
Dialogs.showWarningNotification("Warning!", "Multiple Project files found, may cause unexpected behavior!")
}

project = ProjectIO.loadProject(qpprojFiles[0], BufferedImage.class)
}

if (project == null) {
Dialogs.showWarningNotification("Warning!", "Project is null!")
}
// Within projectsFolderPath, check for a folder with the name "SlideImages", if it does not exist, create it
File slideImagesFolder = new File(projectsFolder, sampleLabelFolder, "SlideImages")
String slideImagesFolderPathStr = projectsFolderPath + File.separator + sampleLabel + File.separator + "SlideImages" ;
File slideImagesFolder = new File(slideImagesFolderPathStr);

if (!slideImagesFolder.exists()) {
slideImagesFolder.mkdirs()
}
Expand All @@ -94,6 +116,7 @@ class utilityFunctions {
if (!scanTypeFolder.exists()) {
scanTypeFolder.mkdirs()
}

return project
}

Expand Down Expand Up @@ -143,6 +166,7 @@ class utilityFunctions {
//TODO add code to access Preferences fields
//If preferences are null or missing, throw an error and close
//Open to discussion whether scan types should be included here or typed every time, or some other option
return [installation: "C:\\ImageAnalysis\\python", environment: "C:\\Anaconda\\envs\\paquo", projects: "C:\\ImageAnalysis\\slides", firstScanType: "4x_bf_", secondScanType:"20x_bf"]
//TODO fix the installation to be a folder with an expected .py file target? Or keep as .py file target?
return [installation: "C:\\ImageAnalysis\\python\\py_dummydoc.py", environment: "C:\\Anaconda\\envs\\paquo", projects: "C:\\ImageAnalysis\\slides", firstScanType: "4x_bf_", secondScanType:"20x_bf"]
}
}

0 comments on commit d880c4d

Please sign in to comment.