use of qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep in project qupath by qupath.
the class Commands method createFullImageAnnotation.
/**
* Create a full image annotation for the image in the specified viewer.
* The z and t positions of the viewer will be used.
* @param viewer the viewer containing the image to be processed
*/
public static void createFullImageAnnotation(QuPathViewer viewer) {
if (viewer == null)
return;
ImageData<?> imageData = viewer.getImageData();
if (imageData == null)
return;
PathObjectHierarchy hierarchy = imageData.getHierarchy();
// Check if we already have a comparable annotation
int z = viewer.getZPosition();
int t = viewer.getTPosition();
ImageRegion bounds = viewer.getServerBounds();
ROI roi = ROIs.createRectangleROI(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(), ImagePlane.getPlane(z, t));
for (PathObject pathObject : hierarchy.getAnnotationObjects()) {
ROI r2 = pathObject.getROI();
if (r2 instanceof RectangleROI && roi.getBoundsX() == r2.getBoundsX() && roi.getBoundsY() == r2.getBoundsY() && roi.getBoundsWidth() == r2.getBoundsWidth() && roi.getBoundsHeight() == r2.getBoundsHeight() && roi.getImagePlane().equals(r2.getImagePlane())) {
logger.info("Full image annotation already exists! {}", pathObject);
viewer.setSelectedObject(pathObject);
return;
}
}
PathObject pathObject = PathObjects.createAnnotationObject(roi);
hierarchy.addPathObject(pathObject);
viewer.setSelectedObject(pathObject);
// Log in the history
if (z == 0 && t == 0)
imageData.getHistoryWorkflow().addStep(new DefaultScriptableWorkflowStep("Create full image annotation", "createSelectAllObject(true);"));
else
imageData.getHistoryWorkflow().addStep(new DefaultScriptableWorkflowStep("Create full image annotation", String.format("createSelectAllObject(true, %d, %d);", z, t)));
}
use of qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep in project qupath by qupath.
the class Commands method distanceToAnnotations2D.
/**
* Compute the distance between all detections and the closest annotation, for all annotation classifications.
* @param imageData the image data to process
*/
public static void distanceToAnnotations2D(ImageData<?> imageData) {
String title = "Distance to annotations 2D";
if (imageData == null) {
Dialogs.showNoImageError(title);
return;
}
if (imageData.getServer().nZSlices() > 1) {
logger.debug("Warning user that measurements will be 2D...");
if (!Dialogs.showConfirmDialog(title, "Distance to annotations command works only in 2D - distances will not be calculated for objects on different z-slices or time-points")) {
logger.debug("Command cancelled");
return;
}
}
var result = Dialogs.showYesNoCancelDialog(title, "Split multi-part classifications?\nIf yes, each component of classifications such as \"Class1: Class2\" will be treated separately.");
boolean doSplit = false;
if (result == DialogButton.YES)
doSplit = true;
else if (result != DialogButton.NO)
return;
DistanceTools.detectionToAnnotationDistances(imageData, doSplit);
imageData.getHistoryWorkflow().addStep(new DefaultScriptableWorkflowStep("Distance to annotations 2D", doSplit ? "detectionToAnnotationDistances(true)" : "detectionToAnnotationDistances(false)"));
}
use of qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep in project qupath by qupath.
the class Commands method resetTMAMetadata.
/**
* Reset TMA metadata, if available.
* @param imageData
* @return true if changes were made, false otherwise
*/
public static boolean resetTMAMetadata(ImageData<?> imageData) {
if (imageData == null || imageData.getHierarchy().getTMAGrid() == null) {
logger.warn("No TMA grid available!");
return false;
}
QP.resetTMAMetadata(imageData.getHierarchy(), true);
imageData.getHistoryWorkflow().addStep(new DefaultScriptableWorkflowStep("Reset TMA metadata", "resetTMAMetadata(true);"));
return true;
}
use of qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep in project qupath by qupath.
the class MeasurementManager method promptToRemoveMeasurements.
private boolean promptToRemoveMeasurements() {
var selectedItems = new ArrayList<>(listView.getSelectionModel().getSelectedItems());
if (selectedItems.isEmpty()) {
Dialogs.showErrorMessage("Remove measurements", "No measurements selected!");
return false;
}
String number = selectedItems.size() == 1 ? String.format("'%s'", selectedItems.iterator().next()) : selectedItems.size() + " measurements";
if (!Dialogs.showConfirmDialog("Remove measurements", "Are you sure you want to permanently remove " + number + "?"))
return false;
String removeString = selectedItems.stream().map(m -> "\"" + m + "\"").collect(Collectors.joining(", "));
logger.info("Removing measurements: {}", removeString);
Class<? extends PathObject> cls = comboBox.getSelectionModel().getSelectedItem();
QP.removeMeasurements(imageData.getHierarchy(), cls, selectedItems.toArray(String[]::new));
// Keep for scripting
WorkflowStep step = new DefaultScriptableWorkflowStep("Remove measurements", String.format("removeMeasurements(%s, %s);", cls.getName(), removeString));
imageData.getHistoryWorkflow().addStep(step);
// Update
refreshMeasurements();
updateCurrentList();
filterText.set("");
return true;
}
use of qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep in project qupath by qupath.
the class Commands method detectionCentroidDistances2D.
/**
* Compute the distance between the centroids of all detections, for all available classifications.
* @param imageData the image data to process
*/
public static void detectionCentroidDistances2D(ImageData<?> imageData) {
String title = "Detection centroid distances 2D";
if (imageData == null) {
Dialogs.showNoImageError(title);
return;
}
if (imageData.getServer().nZSlices() > 1) {
logger.debug("Warning user that measurements will be 2D...");
if (!Dialogs.showConfirmDialog(title, "Detection centroid distances command works only in 2D - distances will not be calculated for objects on different z-slices or time-points")) {
logger.debug("Command cancelled");
return;
}
}
var result = Dialogs.showYesNoCancelDialog(title, "Split multi-part classifications?\nIf yes, each component of classifications such as \"Class1: Class2\" will be treated separately.");
boolean doSplit = false;
if (result == DialogButton.YES)
doSplit = true;
else if (result != DialogButton.NO)
return;
DistanceTools.detectionCentroidDistances(imageData, doSplit);
imageData.getHistoryWorkflow().addStep(new DefaultScriptableWorkflowStep("Detection centroid distances 2D", doSplit ? "detectionCentroidDistances(true)" : "detectionCentroidDistances(false)"));
}
Aggregations