use of qupath.lib.io.UriResource in project qupath by qupath.
the class QP method loadObjectClassifier.
/**
* Load an object classifier for a project or file path.
*
* @param names the names of the classifier within the current project, or file paths to a classifier to load from disk.
* If more than one name is provided, a composite classifier is created (applying each classifier in sequence).
* @return the requested {@link ObjectClassifier}
* @throws IllegalArgumentException if the classifier cannot be found
*/
public static ObjectClassifier<BufferedImage> loadObjectClassifier(String... names) throws IllegalArgumentException {
var project = getProject();
List<ObjectClassifier<BufferedImage>> classifiers = new ArrayList<>();
for (String name : names) {
ObjectClassifier<BufferedImage> classifier = null;
Exception exception = null;
if (project != null) {
try {
var objectClassifiers = project.getObjectClassifiers();
if (objectClassifiers.contains(name))
classifier = objectClassifiers.get(name);
} catch (Exception e) {
exception = e;
logger.debug("Object classifier '{}' not found in project", name);
}
}
if (classifier == null) {
try {
var path = Paths.get(name);
if (Files.exists(path))
classifier = ObjectClassifiers.readClassifier(path);
} catch (Exception e) {
exception = e;
logger.debug("Object classifier '{}' cannot be read from file", name);
}
}
if (classifier == null) {
throw new IllegalArgumentException("Unable to find object classifier " + name, exception);
}
// Try to fix URIs, if we can
if (classifier instanceof UriResource) {
UriUpdater.fixUris((UriResource) classifier, project);
}
if (names.length == 1)
return classifier;
else
classifiers.add(classifier);
}
return ObjectClassifiers.createCompositeClassifier(classifiers);
}
use of qupath.lib.io.UriResource in project qupath by qupath.
the class QP method loadPixelClassifier.
/**
* Load a pixel classifier for a project or file path.
*
* @param name the name of the classifier within the current project, or file path to a classifier to load from disk.
* @return the requested {@link PixelClassifier}
* @throws IllegalArgumentException if the classifier cannot be found
*/
public static PixelClassifier loadPixelClassifier(String name) throws IllegalArgumentException {
var project = getProject();
Exception exception = null;
PixelClassifier pixelClassifier = null;
if (project != null) {
try {
var pixelClassifiers = project.getPixelClassifiers();
if (pixelClassifiers.contains(name))
pixelClassifier = pixelClassifiers.get(name);
} catch (Exception e) {
exception = e;
logger.debug("Pixel classifier '{}' not found in project", name);
}
}
try {
var path = Paths.get(name);
if (Files.exists(path))
pixelClassifier = PixelClassifiers.readClassifier(path);
} catch (Exception e) {
exception = e;
logger.debug("Pixel classifier '{}' cannot be read from file", name);
}
if (pixelClassifier == null)
throw new IllegalArgumentException("Unable to find pixel classifier " + name, exception);
// Fix URIs if we need to
if (pixelClassifier instanceof UriResource) {
UriUpdater.fixUris((UriResource) pixelClassifier, project);
}
return pixelClassifier;
}
use of qupath.lib.io.UriResource in project qupath by qupath.
the class LoadResourceCommand method run.
@Override
public void run() {
String title = resourceType.getDialogTitle();
var cachedServers = new WeakHashMap<ImageData<BufferedImage>, ImageServer<BufferedImage>>();
var overlay = PixelClassificationOverlay.create(qupath.getOverlayOptions(), cachedServers, new ColorModelRenderer(null));
overlay.setMaxThreads(nThreads);
for (var viewer : qupath.getViewers()) viewer.setCustomPixelLayerOverlay(overlay);
var comboClassifiers = new ComboBox<String>();
try {
updateAvailableItems(comboClassifiers.getItems());
} catch (IOException e) {
logger.error(e.getLocalizedMessage(), e);
}
var selectedResource = Bindings.createObjectBinding(() -> {
String name = comboClassifiers.getSelectionModel().getSelectedItem();
cachedServers.clear();
if (name != null) {
try {
var project = qupath.getProject();
var manager = resourceType.getManager(project);
S resource;
if (manager != null && manager.contains(name))
resource = manager.get(name);
else
resource = extras.get(name);
if (resource instanceof UriResource) {
UriUpdater.fixUris((UriResource) resource, project);
}
return resource;
} catch (Exception ex) {
// TODO: Investigate why this is triggered twice
Dialogs.showErrorNotification(resourceType.getDialogTitle(), ex);
}
}
return null;
}, comboClassifiers.getSelectionModel().selectedItemProperty());
var label = new Label(resourceType.choosePrompt());
label.setLabelFor(comboClassifiers);
selectedResource.addListener((v, o, n) -> {
cachedServers.clear();
updateServers(n, cachedServers);
});
// Add file chooser
var menu = new ContextMenu();
var miLoadClassifier = new MenuItem("Import from files");
miLoadClassifier.setOnAction(e -> {
List<File> files = Dialogs.promptForMultipleFiles(title, null, resourceType.filePrompt(), "json");
if (files == null || files.isEmpty())
return;
try {
addExternalJson(files, resourceType.getManager(qupath.getProject()), extras);
updateAvailableItems(comboClassifiers.getItems());
} catch (IOException ex) {
Dialogs.showErrorMessage(title, ex);
}
});
var miOpenAsText = new MenuItem("Show as text");
miOpenAsText.setOnAction(e -> {
var name = comboClassifiers.getSelectionModel().getSelectedItem();
var resource = selectedResource.get();
if (resource == null)
return;
try {
// Pass the resource class, since it can be required for including the appropriate JSON properties
var json = GsonTools.getInstance(true).toJson(resource, resourceType.getResourceClass());
if (!name.endsWith(".json"))
name = name + ".json";
// Show in script editor if possible; this may include better formatting and syntax highlighting
var scriptEditor = qupath == null ? null : qupath.getScriptEditor();
if (scriptEditor != null)
scriptEditor.showScript(name, json);
else
Dialogs.showTextWindow(qupath.getStage(), name, json, Modality.NONE, false);
} catch (Exception ex) {
Dialogs.showErrorMessage("Show model as text", "Unable to create a text representation of '" + name + "', sorry!");
}
});
miOpenAsText.disableProperty().bind(selectedResource.isNull());
// Enable setting number of threads
var miThreads = new MenuItem("Set parallel threads");
miThreads.setOnAction(e -> {
var params = new ParameterList().addIntParameter("nThreads", "Number of parallel threads", nThreads, null, "Number of threads to use for live prediction");
if (!Dialogs.showParameterDialog("Set parallel threads", params))
return;
// var result = Dialogs.showInputDialog("Set parallel threads", "Number of threads to use for live prediction", (double)nThreads);
var val = params.getIntParameterValue("nThreads");
if (val == nThreads)
return;
if (val < 0)
nThreads = PathPrefs.numCommandThreadsProperty().get();
else
nThreads = Math.max(1, val);
if (overlay != null)
overlay.setMaxThreads(nThreads);
});
menu.getItems().addAll(miLoadClassifier, miOpenAsText, new SeparatorMenuItem(), miThreads);
var btnLoadExistingClassifier = GuiTools.createMoreButton(menu, Side.RIGHT);
var classifierName = new SimpleStringProperty(null);
classifierName.bind(comboClassifiers.getSelectionModel().selectedItemProperty());
var pane = new GridPane();
pane.setPadding(new Insets(10.0));
pane.setHgap(5);
pane.setVgap(10);
pane.setPrefWidth(350.0);
int row = 0;
PaneTools.addGridRow(pane, row++, 0, "Choose model to apply to the current image", label, comboClassifiers, btnLoadExistingClassifier);
PaneTools.setToExpandGridPaneWidth(comboClassifiers);
if (resourceType.getResourceClass().equals(PixelClassifier.class)) {
var labelRegion = new Label("Region");
var comboRegionFilter = PixelClassifierUI.createRegionFilterCombo(qupath.getOverlayOptions());
@SuppressWarnings("unchecked") var tilePane = PixelClassifierUI.createPixelClassifierButtons(qupath.imageDataProperty(), (ObjectExpression<PixelClassifier>) selectedResource, classifierName);
PaneTools.addGridRow(pane, row++, 0, "Control where the pixel classification is applied during preview", labelRegion, comboRegionFilter, comboRegionFilter);
PaneTools.addGridRow(pane, row++, 0, "Apply pixel classification", tilePane, tilePane, tilePane);
PaneTools.setToExpandGridPaneWidth(tilePane);
} else if (resourceType.getResourceClass().equals(DensityMapBuilder.class)) {
@SuppressWarnings("unchecked") var buttonPane = DensityMapUI.createButtonPane(qupath, qupath.imageDataProperty(), (ObjectExpression<DensityMapBuilder>) selectedResource, classifierName, Bindings.createObjectBinding(() -> overlay), false);
PaneTools.addGridRow(pane, row++, 0, null, buttonPane, buttonPane, buttonPane);
PaneTools.setToExpandGridPaneWidth(buttonPane);
}
// Handle drag and drop
pane.setOnDragOver(e -> {
e.acceptTransferModes(TransferMode.COPY);
e.consume();
});
pane.setOnDragDropped(e -> {
logger.trace("File(s) dragged onto pane");
Dragboard dragboard = e.getDragboard();
if (dragboard.hasFiles()) {
try {
addExternalJson(dragboard.getFiles(), resourceType.getManager(qupath.getProject()), extras);
updateAvailableItems(comboClassifiers.getItems());
} catch (Exception ex) {
Dialogs.showErrorMessage(title, ex);
}
}
});
var stage = new Stage();
stage.setTitle(title);
stage.setScene(new Scene(pane));
stage.initOwner(qupath.getStage());
stage.sizeToScene();
stage.setResizable(false);
stage.show();
stage.setOnHiding(e -> {
if (overlay != null)
overlay.stop();
logger.debug("Resetting overlay");
for (var viewer : qupath.getViewers()) {
if (viewer.getCustomPixelLayerOverlay() == overlay)
viewer.resetCustomPixelLayerOverlay();
}
});
stage.focusedProperty().addListener((v, o, n) -> {
if (n && overlay != null) {
for (var viewer : qupath.getViewers()) viewer.setCustomPixelLayerOverlay(overlay);
}
// Make sure we have all the servers we need - but don't reset existing ones
updateServers(selectedResource.get(), cachedServers);
});
overlay.setLivePrediction(true);
}
Aggregations