Search in sources :

Example 6 with ParameterList

use of qupath.lib.plugins.parameters.ParameterList in project qupath by qupath.

the class NeuralNetworksClassifier method createParameterList.

@Override
protected ParameterList createParameterList() {
    ParameterList params = new ParameterList();
    params.addIntParameter("nHidden", "Number of hidden layers", 8, null, "Number of hidden layers for neural network (must be >= 2)");
    params.addIntParameter("termCritMaxIterations", "Termination criterion - max iterations", 100, null, "Optional termination criterion based on maximum number of iterations - set <= 0 to disable and use accuracy criterion only");
    params.addDoubleParameter("termCritEPS", "Termination criterion - accuracy", 0.01, null, "Optional termination criterion based on out-of-bag error - set <= 0 to disable and use max trees only");
    return params;
}
Also used : ParameterList(qupath.lib.plugins.parameters.ParameterList)

Example 7 with ParameterList

use of qupath.lib.plugins.parameters.ParameterList in project qupath by qupath.

the class Commands method promptToSetGridLineSpacing.

/**
 * Prompt to input the spacing for the grid lines optionally displayed on viewers.
 * @param options the {@link OverlayOptions} that manage the grid lines.
 */
public static void promptToSetGridLineSpacing(OverlayOptions options) {
    GridLines gridLines = options.getGridLines();
    ParameterList params = new ParameterList().addDoubleParameter("hSpacing", "Horizontal spacing", gridLines.getSpaceX()).addDoubleParameter("vSpacing", "Vertical spacing", gridLines.getSpaceY()).addBooleanParameter("useMicrons", "Use microns", gridLines.useMicrons());
    if (!Dialogs.showParameterDialog("Set grid spacing", params))
        return;
    gridLines = new GridLines();
    gridLines.setSpaceX(params.getDoubleParameterValue("hSpacing"));
    gridLines.setSpaceY(params.getDoubleParameterValue("vSpacing"));
    gridLines.setUseMicrons(params.getBooleanParameterValue("useMicrons"));
    options.gridLinesProperty().set(gridLines);
}
Also used : ParameterList(qupath.lib.plugins.parameters.ParameterList) GridLines(qupath.lib.gui.viewer.GridLines)

Example 8 with ParameterList

use of qupath.lib.plugins.parameters.ParameterList in project qupath by qupath.

the class ExportObjectsCommand method runGeoJsonExport.

/**
 * Run the path object GeoJSON export command.
 * @param qupath
 * @return success
 * @throws IOException
 */
public static boolean runGeoJsonExport(QuPathGUI qupath) throws IOException {
    // Get ImageData
    var imageData = qupath.getImageData();
    if (imageData == null)
        return false;
    // Get hierarchy
    PathObjectHierarchy hierarchy = imageData.getHierarchy();
    String allObjects = "All objects";
    String selectedObjects = "Selected objects";
    String defaultObjects = hierarchy.getSelectionModel().noSelection() ? allObjects : selectedObjects;
    // Params
    var parameterList = new ParameterList().addChoiceParameter("exportOptions", "Export ", defaultObjects, Arrays.asList(allObjects, selectedObjects), "Choose which objects to export - run a 'Select annotations/detections' command first if needed").addBooleanParameter("excludeMeasurements", "Exclude measurements", false, "Exclude object measurements during export - for large numbers of detections this can help reduce the file size").addBooleanParameter("doPretty", "Pretty JSON", false, "Pretty GeoJSON is more human-readable but results in larger file sizes").addBooleanParameter("doFeatureCollection", "Export as FeatureCollection", true, "Export as a 'FeatureCollection', which is a standard GeoJSON way to represent multiple objects; if not, a regular JSON object/array will be export").addBooleanParameter("doZip", "Compress data (zip)", false, "Compressed files take less memory");
    if (!Dialogs.showParameterDialog("Export objects", parameterList))
        return false;
    Collection<PathObject> toProcess;
    var comboChoice = parameterList.getChoiceParameterValue("exportOptions");
    if (comboChoice.equals("Selected objects")) {
        if (hierarchy.getSelectionModel().noSelection()) {
            Dialogs.showErrorMessage("No selection", "No selection detected!");
            return false;
        }
        toProcess = hierarchy.getSelectionModel().getSelectedObjects();
    } else
        toProcess = hierarchy.getObjects(null, null);
    // Remove PathRootObject
    toProcess = toProcess.stream().filter(e -> !e.isRootObject()).collect(Collectors.toList());
    // Check if includes ellipse(s), as they will need to be polygonized
    var nEllipses = toProcess.stream().filter(ann -> isEllipse(ann)).count();
    if (nEllipses > 0) {
        String message = nEllipses == 1 ? "1 ellipse will be polygonized, continue?" : String.format("%d ellipses will be polygonized, continue?", nEllipses);
        var response = Dialogs.showYesNoDialog("Ellipse polygonization", message);
        if (!response)
            return false;
    }
    File outFile;
    // Get default name & output directory
    var project = qupath.getProject();
    String defaultName = imageData.getServer().getMetadata().getName();
    if (project != null) {
        var entry = project.getEntry(imageData);
        if (entry != null)
            defaultName = entry.getImageName();
    }
    defaultName = GeneralTools.getNameWithoutExtension(defaultName);
    File defaultDirectory = project == null || project.getPath() == null ? null : project.getPath().toFile();
    while (defaultDirectory != null && !defaultDirectory.isDirectory()) defaultDirectory = defaultDirectory.getParentFile();
    if (parameterList.getBooleanParameterValue("doZip"))
        outFile = Dialogs.promptToSaveFile("Export to file", defaultDirectory, defaultName + ".zip", "ZIP archive", ".zip");
    else
        outFile = Dialogs.promptToSaveFile("Export to file", defaultDirectory, defaultName + ".geojson", "GeoJSON", ".geojson");
    // If user cancels
    if (outFile == null)
        return false;
    List<GeoJsonExportOptions> options = new ArrayList<>();
    if (parameterList.getBooleanParameterValue("excludeMeasurements"))
        options.add(GeoJsonExportOptions.EXCLUDE_MEASUREMENTS);
    if (parameterList.getBooleanParameterValue("doPretty"))
        options.add(GeoJsonExportOptions.PRETTY_JSON);
    if (parameterList.getBooleanParameterValue("doFeatureCollection"))
        options.add(GeoJsonExportOptions.FEATURE_COLLECTION);
    // Export
    QP.exportObjectsToGeoJson(toProcess, outFile.getAbsolutePath(), options.toArray(GeoJsonExportOptions[]::new));
    // Notify user of success
    int nObjects = toProcess.size();
    String message = nObjects == 1 ? "1 object was exported to " + outFile.getAbsolutePath() : String.format("%d objects were exported to %s", nObjects, outFile.getAbsolutePath());
    Dialogs.showInfoNotification("Succesful export", message);
    // Get history workflow
    var historyWorkflow = imageData.getHistoryWorkflow();
    // args for workflow step
    Map<String, String> map = new LinkedHashMap<>();
    map.put("path", outFile.getPath());
    String method = comboChoice.equals(allObjects) ? "exportAllObjectsToGeoJson" : "exportSelectedObjectsToGeoJson";
    String methodTitle = comboChoice.equals(allObjects) ? "Export all objects" : "Export selected objects";
    String optionsString = options.stream().map(o -> "\"" + o.name() + "\"").collect(Collectors.joining(", "));
    map.put("options", optionsString);
    if (!optionsString.isEmpty())
        optionsString = ", " + optionsString;
    String methodString = String.format("%s(%s%s)", method, "\"" + GeneralTools.escapeFilePath(outFile.getPath()) + "\"", optionsString);
    historyWorkflow.addStep(new DefaultScriptableWorkflowStep(methodTitle, map, methodString));
    return true;
}
Also used : Arrays(java.util.Arrays) GeneralTools(qupath.lib.common.GeneralTools) GeoJsonExportOptions(qupath.lib.io.PathIO.GeoJsonExportOptions) Collection(java.util.Collection) IOException(java.io.IOException) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) Collectors(java.util.stream.Collectors) File(java.io.File) ArrayList(java.util.ArrayList) PathObject(qupath.lib.objects.PathObject) LinkedHashMap(java.util.LinkedHashMap) Dialogs(qupath.lib.gui.dialogs.Dialogs) List(java.util.List) ParameterList(qupath.lib.plugins.parameters.ParameterList) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) Map(java.util.Map) QP(qupath.lib.scripting.QP) QuPathGUI(qupath.lib.gui.QuPathGUI) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) PathObject(qupath.lib.objects.PathObject) ParameterList(qupath.lib.plugins.parameters.ParameterList) GeoJsonExportOptions(qupath.lib.io.PathIO.GeoJsonExportOptions) File(java.io.File)

Example 9 with ParameterList

use of qupath.lib.plugins.parameters.ParameterList in project qupath by qupath.

the class TMACommands method promptToRelabelTMAGrid.

/**
 * Prompt to relabel the core names within a TMA grid.
 * @param imageData image containing the TMA grid
 */
public static void promptToRelabelTMAGrid(ImageData<?> imageData) {
    String title = "Relabel TMA grid";
    if (imageData == null) {
        Dialogs.showNoImageError(title);
        return;
    }
    if (imageData.getHierarchy().getTMAGrid() == null) {
        Dialogs.showErrorMessage(title, "No TMA grid selected!");
        return;
    }
    ParameterList params = new ParameterList();
    params.addStringParameter("labelsHorizontal", "Column labels", columnLabelsProperty.get(), "Enter column labels.\nThis can be a continuous range of letters or numbers (e.g. 1-10 or A-J),\nor a discontinuous list separated by spaces (e.g. A B C E F G).");
    params.addStringParameter("labelsVertical", "Row labels", rowLabelsProperty.get(), "Enter row labels.\nThis can be a continuous range of letters or numbers (e.g. 1-10 or A-J),\nor a discontinuous list separated by spaces (e.g. A B C E F G).");
    params.addChoiceParameter("labelOrder", "Label order", rowFirstProperty.get() ? "Row first" : "Column first", Arrays.asList("Column first", "Row first"), "Create TMA labels either in the form Row-Column or Column-Row");
    if (!Dialogs.showParameterDialog(title, params))
        return;
    // Parse the arguments
    String labelsHorizontal = params.getStringParameterValue("labelsHorizontal");
    String labelsVertical = params.getStringParameterValue("labelsVertical");
    boolean rowFirst = "Row first".equals(params.getChoiceParameterValue("labelOrder"));
    // Figure out if this will work
    TMAGrid grid = imageData.getHierarchy().getTMAGrid();
    String[] columnLabels = PathObjectTools.parseTMALabelString(labelsHorizontal);
    String[] rowLabels = PathObjectTools.parseTMALabelString(labelsVertical);
    if (columnLabels.length < grid.getGridWidth()) {
        Dialogs.showErrorMessage(title, "Not enough column labels specified!");
        return;
    }
    if (rowLabels.length < grid.getGridHeight()) {
        Dialogs.showErrorMessage(title, "Not enough row labels specified!");
        return;
    }
    // Apply the labels
    QP.relabelTMAGrid(imageData.getHierarchy(), labelsHorizontal, labelsVertical, rowFirst);
    // Add to workflow history
    imageData.getHistoryWorkflow().addStep(new DefaultScriptableWorkflowStep("Relabel TMA grid", String.format("relabelTMAGrid(\"%s\", \"%s\", %s)", GeneralTools.escapeFilePath(labelsHorizontal), GeneralTools.escapeFilePath(labelsVertical), Boolean.toString(rowFirst))));
    // Store values
    rowLabelsProperty.set(labelsVertical);
    columnLabelsProperty.set(labelsHorizontal);
    rowFirstProperty.set(rowFirst);
}
Also used : DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) DefaultTMAGrid(qupath.lib.objects.hierarchy.DefaultTMAGrid) TMAGrid(qupath.lib.objects.hierarchy.TMAGrid) ParameterList(qupath.lib.plugins.parameters.ParameterList)

Example 10 with ParameterList

use of qupath.lib.plugins.parameters.ParameterList in project qupath by qupath.

the class EstimateStainVectorsCommand method showStainEditor.

@SuppressWarnings("unchecked")
public static ColorDeconvolutionStains showStainEditor(final BufferedImage img, final ColorDeconvolutionStains stains) {
    // 
    int[] buf = img.getRGB(0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth());
    // int[] rgb = buf;
    int[] rgb = EstimateStainVectors.subsample(buf, 10000);
    float[] red = ColorDeconvolutionHelper.getRedOpticalDensities(rgb, stains.getMaxRed(), null);
    float[] green = ColorDeconvolutionHelper.getGreenOpticalDensities(rgb, stains.getMaxGreen(), null);
    float[] blue = ColorDeconvolutionHelper.getBlueOpticalDensities(rgb, stains.getMaxBlue(), null);
    // panelPlots.setBorder(BorderFactory.createTitledBorder(null, "Stain vector scatterplots", TitledBorder.CENTER, TitledBorder.TOP));
    StainsWrapper stainsWrapper = new StainsWrapper(stains);
    Node panelRedGreen = createScatterPanel(new ScatterPlot(red, green, null, rgb), stainsWrapper, AxisColor.RED, AxisColor.GREEN);
    Node panelRedBlue = createScatterPanel(new ScatterPlot(red, blue, null, rgb), stainsWrapper, AxisColor.RED, AxisColor.BLUE);
    Node panelGreenBlue = createScatterPanel(new ScatterPlot(green, blue, null, rgb), stainsWrapper, AxisColor.GREEN, AxisColor.BLUE);
    // GridPane panelPlots = PanelToolsFX.createColumnGrid(panelRedGreen, panelRedBlue, panelGreenBlue);
    GridPane panelPlots = new GridPane();
    panelPlots.setHgap(10);
    panelPlots.add(panelRedGreen, 0, 0);
    panelPlots.add(panelRedBlue, 1, 0);
    panelPlots.add(panelGreenBlue, 2, 0);
    // panelPlots.getChildren().addAll(panelRedGreen, panelRedBlue, panelGreenBlue);
    panelPlots.setPadding(new Insets(0, 0, 10, 0));
    BorderPane panelSouth = new BorderPane();
    TableView<Integer> table = new TableView<>();
    table.getItems().setAll(1, 2, 3);
    stainsWrapper.addStainListener(new StainChangeListener() {

        @Override
        public void stainChanged(StainsWrapper stainsWrapper) {
            table.refresh();
        }
    });
    TableColumn<Integer, String> colName = new TableColumn<>("Name");
    colName.setCellValueFactory(v -> new SimpleStringProperty(stainsWrapper.getStains().getStain(v.getValue()).getName()));
    TableColumn<Integer, String> colOrig = new TableColumn<>("Original");
    colOrig.setCellValueFactory(v -> new SimpleStringProperty(stainArrayAsString(Locale.getDefault(Category.FORMAT), stainsWrapper.getOriginalStains().getStain(v.getValue()), " | ", 3)));
    TableColumn<Integer, String> colCurrent = new TableColumn<>("Current");
    colCurrent.setCellValueFactory(v -> new SimpleStringProperty(stainArrayAsString(Locale.getDefault(Category.FORMAT), stainsWrapper.getStains().getStain(v.getValue()), " | ", 3)));
    TableColumn<Integer, String> colAngle = new TableColumn<>("Angle");
    colAngle.setCellValueFactory(v -> {
        return new SimpleStringProperty(GeneralTools.formatNumber(StainVector.computeAngle(stainsWrapper.getOriginalStains().getStain(v.getValue()), stainsWrapper.getStains().getStain(v.getValue())), 2));
    });
    // new SimpleStringProperty(stainsWrapper.getStains().getStain(v.getValue()).arrayAsString(", ", 3)));
    table.getColumns().addAll(colName, colOrig, colCurrent, colAngle);
    table.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY);
    table.setPrefHeight(120);
    // // Fix first & preferred column sizes
    // int widthName = 0, widthStain = 0;
    // for (int row = 0; row < table.getRowCount(); row++) {
    // TableCellRenderer renderer = table.getCellRenderer(row, 0);
    // Component comp = table.prepareRenderer(renderer, row, 0);
    // widthName = Math.max(comp.getPreferredSize().width, widthName);
    // 
    // renderer = table.getCellRenderer(row, 1);
    // comp = table.prepareRenderer(renderer, row, 1);
    // widthStain = Math.max(comp.getPreferredSize().width, widthStain);
    // renderer = table.getCellRenderer(row, 2);
    // comp = table.prepareRenderer(renderer, row, 2);
    // widthStain = Math.max(comp.getPreferredSize().width, widthStain);
    // }
    // table.getColumnModel().getColumn(0).setMaxWidth(widthName + 10);
    // table.getColumnModel().getColumn(0).setPreferredWidth(widthName + 10);
    // table.getColumnModel().getColumn(1).setPreferredWidth(widthStain + 20);
    // table.getColumnModel().getColumn(2).setPreferredWidth(widthStain + 20);
    // Create auto detection parameters
    ParameterList params = new ParameterList().addDoubleParameter("minStainOD", "Min channel OD", 0.05, "", "Minimum staining OD - pixels with a lower OD in any channel (RGB) are ignored (default = 0.05)").addDoubleParameter("maxStainOD", "Max total OD", 1., "", "Maximum staining OD - more densely stained pixels are ignored (default = 1)").addDoubleParameter("ignorePercentage", "Ignore extrema", 1., "%", "Percentage of extreme pixels to ignore, to improve robustness in the presence of noise/other artefacts (default = 1)").addBooleanParameter("checkColors", "Exclude unrecognised colors (H&E only)", false, "Exclude unexpected colors (e.g. green) that are likely to be caused by artefacts and not true staining");
    // .addDoubleParameter("ignorePercentage", "Ignore extrema", 1., "%", 0, 20, "Percentage of extreme pixels to ignore, to improve robustness in the presence of noise/other artefacts");
    Button btnAuto = new Button("Auto");
    btnAuto.setOnAction(e -> {
        double minOD = params.getDoubleParameterValue("minStainOD");
        double maxOD = params.getDoubleParameterValue("maxStainOD");
        double ignore = params.getDoubleParameterValue("ignorePercentage");
        // Only accept if H&E
        boolean checkColors = params.getBooleanParameterValue("checkColors") && stainsWrapper.getOriginalStains().isH_E();
        ignore = Math.max(0, Math.min(ignore, 100));
        // ColorDeconvolutionStains stains = estimateStains(imgFinal, stainsWrapper.getStains(), minOD, maxOD, ignore);
        try {
            ColorDeconvolutionStains stainsNew = EstimateStainVectors.estimateStains(img, stainsWrapper.getStains(), minOD, maxOD, ignore, checkColors);
            stainsWrapper.setStains(stainsNew);
        } catch (Exception e2) {
            Dialogs.showErrorMessage("Estimate stain vectors", e2);
        }
    });
    ParameterPanelFX panelParams = new ParameterPanelFX(params);
    // panelParams.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    BorderPane panelAuto = new BorderPane();
    // panelAuto.setBorder(BorderFactory.createTitledBorder("Auto detect"));
    panelAuto.setCenter(panelParams.getPane());
    panelAuto.setBottom(btnAuto);
    // JScrollPane scrollPane = new JScrollPane(table);
    // JPanel panelTable = new JPanel(new BorderLayout());
    // panelTable.add(scrollPane, BorderLayout.CENTER);
    // //		JTextArea textInstructions = new JTextArea();
    // //		textInstructions.setWrapStyleWord(true);
    // //		textInstructions.setLineWrap(true);
    // //		textInstructions.setText(
    // //				"Viewer for manually and automatically adjusting stain vectors used for stain separation.\n\n" +
    // //				"Each stain vector is 3 values describing the red, green and blue components that define the colour of each " +
    // //				"stain (e.g. hematoxylin, DAB, eosin).  The scatterplots show how these relate to pixel colours for each " +
    // //				"combination of red, green and blue.\n\n" +
    // //				"'Good' stain vectors should point along the edges of the scattered points, ignoring any artefacts resulting from " +
    // //				"pixels that don't belong to normal staining patterns."
    // //				);
    // //		panelTable.add(new JScrollPane(textInstructions), BorderLayout.SOUTH);
    // panelTable.setBorder(BorderFactory.createTitledBorder("Stain vectors"));
    panelSouth.setCenter(new TitledPane("Stain vectors", table));
    panelSouth.setBottom(new TitledPane("Auto detect", panelAuto));
    BorderPane panelMain = new BorderPane();
    panelMain.setCenter(panelPlots);
    panelMain.setBottom(panelSouth);
    if (Dialogs.showConfirmDialog("Visual Stain Editor", panelMain)) {
        return stainsWrapper.getStains();
    } else {
        stainsWrapper.resetStains();
        return stainsWrapper.getStains();
    }
}
Also used : BorderPane(javafx.scene.layout.BorderPane) Insets(javafx.geometry.Insets) Node(javafx.scene.Node) ParameterPanelFX(qupath.lib.gui.dialogs.ParameterPanelFX) Button(javafx.scene.control.Button) DialogButton(qupath.lib.gui.dialogs.Dialogs.DialogButton) TableView(javafx.scene.control.TableView) TitledPane(javafx.scene.control.TitledPane) GridPane(javafx.scene.layout.GridPane) SimpleStringProperty(javafx.beans.property.SimpleStringProperty) TableColumn(javafx.scene.control.TableColumn) IOException(java.io.IOException) ParameterList(qupath.lib.plugins.parameters.ParameterList) ColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains)

Aggregations

ParameterList (qupath.lib.plugins.parameters.ParameterList)53 BufferedImage (java.awt.image.BufferedImage)15 ArrayList (java.util.ArrayList)13 IOException (java.io.IOException)11 List (java.util.List)9 Collectors (java.util.stream.Collectors)8 BorderPane (javafx.scene.layout.BorderPane)8 PathObject (qupath.lib.objects.PathObject)8 Logger (org.slf4j.Logger)7 LoggerFactory (org.slf4j.LoggerFactory)7 GeneralTools (qupath.lib.common.GeneralTools)7 Dialogs (qupath.lib.gui.dialogs.Dialogs)7 ImageServer (qupath.lib.images.servers.ImageServer)7 Insets (javafx.geometry.Insets)6 Tooltip (javafx.scene.control.Tooltip)6 Collection (java.util.Collection)5 Map (java.util.Map)5 SimpleStringProperty (javafx.beans.property.SimpleStringProperty)5 ContextMenu (javafx.scene.control.ContextMenu)5 Label (javafx.scene.control.Label)5