Skip to content

Commit

Permalink
Updates to folder organization and some of the python scripts.
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelSNelson committed Jan 12, 2024
1 parent 4bc72ed commit d96638c
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 148 deletions.
3 changes: 2 additions & 1 deletion src/main/groovy/qupath/ext/qp_scope/QP_scope.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ class QP_scope implements QuPathExtension {
def qpScope1 = new MenuItem("Start qp_scope")
// TODO: tooltip
qpScope1.setOnAction(e -> {
// TODO: check preferences for all necessary entries
// TODO: check preferences for all necessary entries, and check for micromanager running+version
// search java app with a subprocesses for MicroManager +version number
QP_scope_GUI.createGUI1()
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class QP_scope_GUI {

// New text fields for Python environment, script path, and sample label
static TextField virtualEnvField = new TextField(preferences.environment)
static TextField pythonScriptField = new TextField(preferences.installation)
static TextField pythonScriptField = new TextField(preferences.pycromanager)
static TextField projectsFolderField = new TextField(preferences.projects)
static TextField sampleLabelField = new TextField("First_Test") // New field for sample label
// GUI3
Expand Down Expand Up @@ -83,6 +83,8 @@ class QP_scope_GUI {
boolean dataCheck = true
def annotations = QP.getAnnotationObjects()
// Check if using annotations

//TODO REPLACE ALL OF THIS WITH TILING
if (useAnnotationsCheckBox.isSelected()) {

// Check if annotations are present
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,24 +147,18 @@ class utilityFunctions {
Process process = command.execute();
logger.info("Executing command: " + command);
logger.info("This should get stage coordinates back")
// Construct the command
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
String value1
String value2
while ((line = reader.readLine()) != null) {
// Process the line to retrieve value1 and value2
// For example, if they are printed in a single line separated by space
String[] values = line.split(" ");
value1 = values[0];
value2 = values[1];
// Do something with the values
List<String> result = handleProcessOutput(process)
if (result != null) {
logger.info("Received coordinates: ${result[0]}, ${result[1]}")
return result
} else {
logger.error("Error occurred or no valid output received from the script.")
return null
}
return [value1, value2]
} else if (arguments.size() == 2) {
// Change the script to 'moveStageToCoordinates.py'
File scriptFile = new File(pythonScriptPath);
pythonScriptPath = new File(scriptFile.getParent(), "moveStageToCoordinates.py").getCanonicalPath();
pythonScriptPath = new File(scriptFile.parent, "moveStageToCoordinates.py").canonicalPath
}

String args = arguments != null ? arguments.collect { "\"$it\"" }.join(' ') : "";
Expand All @@ -176,18 +170,52 @@ class utilityFunctions {
// Execute the command
Process process = command.execute();

process.waitFor();
// Redirect the output and error streams to the logger
process.consumeProcessOutput(new StringWriter(), new StringWriter())

// Read and log standard output
process.inputStream.eachLine { line -> logger.info(line) };
// Wait for the process to complete
process.waitFor()

// Read and log standard error
process.errorStream.eachLine { line -> logger.error(line) };
// Log the output and error (or use it as needed)
logger.info(process.text) // This logs the standard output
logger.error(process.err.text) // This logs the standard error
return null
} catch (Exception e) {
e.printStackTrace();
}
}
static List<String> handleProcessOutput(Process process) {
BufferedReader outputReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));

String line;
List<String> outputLines = []
List<String> errorLines = []
String value1 = null
String value2 = null

while ((line = outputReader.readLine()) != null) {
outputLines.add(line)
// Assuming coordinates are on the first line
if (outputLines.size() == 1) {
String[] values = line.split(" ");
value1 = values[0];
value2 = values[1];
}
}

while ((line = errorReader.readLine()) != null) {
errorLines.add(line)
}

// Check for errors or invalid output
if (!errorLines.isEmpty() || value1 == null || value2 == null) {
return null;
}

return [value1, value2];
}

// static void runPythonCommand(String anacondaEnvPath, String pythonScriptPath, List arguments) {
// try {
// def logger = LoggerFactory.getLogger(QuPathGUI.class)
Expand Down Expand Up @@ -221,10 +249,10 @@ class utilityFunctions {
//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
//TODO fix the installation to be a folder with an expected .py file target? Or keep as .py file target?
return [installation : "C:\\ImageAnalysis\\QPExtensionTest\\qp_scope\\src\\main\\pythonScripts/4x_bf_scan_pycromanager.py",
return [ pycromanager : "C:\\ImageAnalysis\\QPExtensionTest\\qp_scope\\src\\main\\pythonScripts/4x_bf_scan_pycromanager.py",
environment : "C:\\Anaconda\\envs\\paquo",
projects : "C:\\ImageAnalysis\\slides",
tissueDetection: "C:\\ImageAnalysis\\QPExtensionTest\\qp_scope\\src\\main\\groovyScripts/DetectTissue.groovy",
projects : "C:\\ImageAnalysis\\QPExtensionTest\\data\\slides",
tissueDetection: "DetectTissue.groovy",
firstScanType : "4x_bf",
secondScanType : "20x_bf",
tileHandling : "Zip"] //Zip Delete or anything else is ignored
Expand Down Expand Up @@ -505,6 +533,10 @@ class utilityFunctions {
//Convert the QuPath pixel based coordinates for a location into the MicroManager micron based stage coordinates
static List<Double> QPtoMicroscopeCoordinates(List<Double> qpCoordinates, Double imagePixelSize, Object transformation) {
//TODO figure out conversion
def xUpperLeft = qpCoordinates[0]*imagePixelSize
def yUpperLeft = qpCoordinates[1]*imagePixelSize


def mmCoordinates = qpCoordinates
return mmCoordinates
}
Expand Down
97 changes: 35 additions & 62 deletions src/main/pythonScripts/4x_bf_scan_pycromanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,138 +3,111 @@
import shutil
import glob

# Function to log messages
def log_message(message):
with open('D:/log.txt', 'a') as log_file:
print(message, file=log_file, flush=True)

def copy_tif_files(projectsFolderPath, sampleLabel, imageType):

if "4x" in imageType:
TILES_LOCATION = 'C:/ImageAnalysis/Brightfield demo/Tiles/BurnTest2-4x-bf'
TILES_LOCATION = 'C:/ImageAnalysis/QPExtensionTest/data/sample_tiles/some_4x_data'
else:
TILES_LOCATION = 'C:/ImageAnalysis/Brightfield demo/Tiles/PDAC.3.A_Unstained-20x--C-7'
TILES_LOCATION = 'C:/ImageAnalysis/QPExtensionTest/data/sample_tiles/some_20x_data'

log_message(f"Copying .tif files from {TILES_LOCATION} to {projectsFolderPath}/{sampleLabel}")
print(f"Copying .tif files from {TILES_LOCATION} to {projectsFolderPath}/{sampleLabel}")

dest_dir = os.path.join(projectsFolderPath, sampleLabel, imageType)
log_message(f"Destination directory: {dest_dir}")
print(f"Destination directory: {dest_dir}")
if not os.path.exists(dest_dir):
log_message("Destination directory does not exist, creating it.")
print("Destination directory does not exist, creating it.")
os.makedirs(dest_dir)

tif_files = []
for extension in ['*.tif', '*.tiff', '*.txt']:
tif_files.extend(glob.glob(os.path.join(TILES_LOCATION, extension)))

log_message(f"Number of .tif files found: {len(tif_files)}")
print(f"Number of .tif files found: {len(tif_files)}")
if not tif_files:
log_message(f"No .tif files found in {TILES_LOCATION}")
print(f"No .tif files found in {TILES_LOCATION}")
return False

for file in tif_files:
try:
log_message(file)
print(file)
shutil.copy(file, dest_dir)
except Exception as e:
print(f"Error copying file {file}: {e}")


return True

log_message("Python script started.")
print("Python script started.")
projectsFolderPath = sys.argv[2]
log_message(f"Projects Folder Path: {projectsFolderPath}")
print(f"Projects Folder Path: {projectsFolderPath}")
sampleLabel = sys.argv[3]
log_message(f"Sample Label: {sampleLabel}")
print(f"Sample Label: {sampleLabel}")
imageType = sys.argv[4]
log_message(f"Image Type: {imageType}")
print(f"Image Type: {imageType}")

success = copy_tif_files(projectsFolderPath, sampleLabel, imageType)

if not success:
log_message("File copying did not complete successfully.")
print("File copying did not complete successfully.")
else:
log_message("File copying completed successfully.")
print("File copying completed successfully.")


# import os
# import sys
# import shutil
# import glob

# # Redirecting print statements to a log file
# sys.stdout = open('logpython.txt', 'w')
# print(os.getcwd())
# # Function to log messages
# def log_message(message):
# with open('D:/log.txt', 'a') as log_file:
# print(message, file=log_file, flush=True)

# def copy_tif_files(projectsFolderPath, sampleLabel, imageType):

# if "4x" in imageType:
# TILES_LOCATION = 'C:/ImageAnalysis/Brightfield demo/Tiles/BurnTest2-4x-bf' # Replace with the absolute path
# TILES_LOCATION = 'C:/ImageAnalysis/QPExtensionTest/data/sample_tiles/some_4x_data'
# else:
# TILES_LOCATION = 'C:/ImageAnalysis/Brightfield demo/Tiles/PDAC_MetroHealth_N352L42-20x--null'

# TILES_LOCATION = 'C:/ImageAnalysis/QPExtensionTest/data/sample_tiles/some_20x_data'

# print(f"Copying .tif files from {TILES_LOCATION} to {projectsFolderPath}/{sampleLabel}")
# log_message(f"Copying .tif files from {TILES_LOCATION} to {projectsFolderPath}/{sampleLabel}")

# dest_dir = os.path.join(projectsFolderPath, sampleLabel, f"{imageType}{sampleLabel}")
# print(f"Destination directory: {dest_dir}")
# dest_dir = os.path.join(projectsFolderPath, sampleLabel, imageType)
# log_message(f"Destination directory: {dest_dir}")
# if not os.path.exists(dest_dir):
# print("Destination directory does not exist, creating it.")
# log_message("Destination directory does not exist, creating it.")
# os.makedirs(dest_dir)

# # Find all .tif files
# tif_files = []
# for extension in ['*.tif', '*.tiff', '*.txt']:
# tif_files.extend(glob.glob(os.path.join(TILES_LOCATION, extension)))

# print(f"Number of .tif files found: {len(tif_files)}")
# #print(f"Files: {tif_files}")
# # Check if any.tif files were found
# log_message(f"Number of .tif files found: {len(tif_files)}")
# if not tif_files:
# print(f"No .tif files found in {TILES_LOCATION}")
# log_message(f"No .tif files found in {TILES_LOCATION}")
# return False
# #Copy each .tif file
# #shutil.copy(tif_files[0], dest_dir)
# # print(f"Copying last file: {tif_files[-1]}")
# # shutil.copy(tif_files[-1], dest_dir)

# # for file in tif_files[:42]:
# # print(f"Copying file: {file}")
# # shutil.copy(file, dest_dir)

# for file in tif_files:
# try:
# print(f"Copying file: {file}")
# log_message(file)
# shutil.copy(file, dest_dir)
# except Exception as e:
# print(f"Error copying file {file}: {e}")

# # print("Copy operation completed.")
# return True


# # if len(sys.argv) != 9:
# # print("Incorrect arguments for function: python script.py <projectsFolderPath> <sampleLabel> <imageType> <x1> <y1> <x2> <y2>")
# # print(len(sys.argv))
# # return
# print("Python script started.")
# log_message("Python script started.")
# projectsFolderPath = sys.argv[2]
# print(f"Projects Folder Path: {projectsFolderPath}")
# log_message(f"Projects Folder Path: {projectsFolderPath}")
# sampleLabel = sys.argv[3]
# print(f"Sample Label: {sampleLabel}")
# log_message(f"Sample Label: {sampleLabel}")
# imageType = sys.argv[4]
# print(f"Image Type: {imageType}")
# # x1, y1, x2, y2 are received but not used in this script. They can be used if needed.

# #jsonFileLocation = sys.arv[9]
# #WOULD NEED FUNCTION HERE TO TRANSLATE COORDINATES TO STAGE COORDINATES
# log_message(f"Image Type: {imageType}")

# success = copy_tif_files(projectsFolderPath, sampleLabel, imageType)

# if not success:
# print("File copying did not complete successfully.")
# log_message("File copying did not complete successfully.")
# else:
# print("File copying completed successfully.")
# log_message("File copying completed successfully.")


# # Close the log file
# sys.stdout.close()
21 changes: 7 additions & 14 deletions src/main/pythonScripts/getStageCoordinates.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
import sys

# Function to log messages
def log_message(message):
with open('D:/log.txt', 'a') as log_file:
print(message, file=log_file, flush=True)

log_message("Python script started.")

# Check if the first command-line argument is None
if len(sys.argv) >= 2:
first_argument = sys.argv[1]
if first_argument is None:
log_message("The first argument is None.")
# Check if any command-line arguments were provided
if len(sys.argv) == 1:
# No arguments were passed, print default coordinates
print('12345', '54321')
else:
log_message("No arguments were provided.")
print('12345', '54321')
# Arguments were passed, print an error message to standard error
print("Error: Unexpected arguments received.", file=sys.stderr)
sys.exit(1) # Optionally exit with a non-zero status to indicate an error
11 changes: 0 additions & 11 deletions src/main/pythonScripts/mat_file_converter.py

This file was deleted.

15 changes: 5 additions & 10 deletions src/main/pythonScripts/moveStageToCoordinates.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import sys

# Function to log messages
def log_message(message):
with open('D:/log.txt', 'a') as log_file:
print(message, file=log_file, flush=True)

log_message("Python script started.")

# Check if there are exactly two command-line arguments
if len(sys.argv) == 3:
try:
# Parse the two arguments as doubles (X and Y)
X = float(sys.argv[1])
Y = float(sys.argv[2])
log_message(f"X: {X}, Y: {Y}")
print(f"X: {X}, Y: {Y}")
except ValueError:
log_message("Invalid arguments. Both X and Y must be doubles.")
print("Invalid arguments. Both X and Y must be doubles.", file=sys.stderr)
sys.exit(1)
else:
log_message("Usage: python script.py <X> <Y>")
print("Expected two arguments, X and Y as doubles", file=sys.stderr)
sys.exit(1)
Loading

0 comments on commit d96638c

Please sign in to comment.