use of qupath.lib.analysis.heatmaps.DensityMaps.DensityMapBuilder 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