Search in sources :

Example 16 with TMAEntry

use of qupath.lib.gui.tma.TMAEntries.TMAEntry in project qupath by qupath.

the class TMASummaryViewer method createScoresMap.

private Map<String, List<TMAEntry>> createScoresMap(final List<TMAEntry> entries, final String colScore, final String colID) {
    // Create a map of entries
    Map<String, List<TMAEntry>> scoreMap = new HashMap<>();
    for (TMAEntry entry : entries) {
        Number score = model.getNumericValue(entry, colScore);
        String id = entry.getMetadataValue(colID);
        if (id == null && entry.getMeasurement(colID) != null)
            id = Double.toString(entry.getMeasurement(colID).doubleValue());
        if (id != null && score != null && !Double.isNaN(score.doubleValue())) {
            List<TMAEntry> list = scoreMap.get(id);
            if (list == null) {
                list = new ArrayList<>();
                scoreMap.put(id, list);
            }
            list.add(entry);
        }
    }
    return scoreMap;
}
Also used : LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) TMAEntry(qupath.lib.gui.tma.TMAEntries.TMAEntry) ObservableList(javafx.collections.ObservableList) ArrayList(java.util.ArrayList) MeasurementList(qupath.lib.measurements.MeasurementList) SortedList(javafx.collections.transformation.SortedList) FilteredList(javafx.collections.transformation.FilteredList) List(java.util.List)

Example 17 with TMAEntry

use of qupath.lib.gui.tma.TMAEntries.TMAEntry in project qupath by qupath.

the class TMASummaryViewer method importScores.

private int importScores(final String text) {
    Map<String, List<String>> data = TMAScoreImporter.readCSV(text);
    List<String> idColumn = data.remove(TMACoreObject.KEY_UNIQUE_ID);
    if (idColumn == null) {
        Dialogs.showErrorMessage("Import TMA data", "No '" + TMACoreObject.KEY_UNIQUE_ID + "' column found!");
        return 0;
    }
    // Nothing left to import...
    if (data.isEmpty())
        return 0;
    // Get the numeric columns, if possible
    Map<String, double[]> dataNumeric = new HashMap<>();
    for (String key : data.keySet().toArray(new String[0])) {
        double[] vals = TMAScoreImporter.parseNumeric(data.get(key), true);
        if (vals != null && GeneralTools.numNaNs(vals) != vals.length) {
            dataNumeric.put(key, vals);
            data.remove(key);
        }
    }
    // Loop through IDs, adding values where needed
    int counter = 0;
    for (int i = 0; i < idColumn.size(); i++) {
        boolean matched = false;
        String id = idColumn.get(i);
        if (id == null) {
            logger.debug("Skipping missing ID");
            continue;
        }
        for (TMAEntry entry : entriesBase) {
            if (id.equals(entry.getMetadataValue(TMACoreObject.KEY_UNIQUE_ID))) {
                matched = true;
                for (Entry<String, double[]> dataEntry : dataNumeric.entrySet()) {
                    entry.putMeasurement(dataEntry.getKey(), dataEntry.getValue()[i]);
                }
                for (Entry<String, List<String>> dataEntry : data.entrySet()) {
                    entry.putMetadata(dataEntry.getKey(), dataEntry.getValue().get(i));
                }
                counter++;
            }
        }
        if (!matched)
            logger.warn("No match for ID: " + id);
    }
    Optional<TMAEntry> objectEntry = entriesBase.stream().filter(t -> t instanceof TMAObjectEntry).findAny();
    if (objectEntry.isPresent()) {
        Dialogs.showInfoNotification("TMA data update", "TMA cores updated!");
    }
    return counter;
}
Also used : Arrays(java.util.Arrays) Change(javafx.collections.ListChangeListener.Change) ServerTools(qupath.lib.images.servers.ServerTools) ActionUtils(org.controlsfx.control.action.ActionUtils) HistogramDisplay(qupath.lib.gui.charts.HistogramDisplay) PathTableData(qupath.lib.gui.measure.PathTableData) MasterDetailPane(org.controlsfx.control.MasterDetailPane) ScrollPane(javafx.scene.control.ScrollPane) TabPane(javafx.scene.control.TabPane) ListChangeListener(javafx.collections.ListChangeListener) SpearmansCorrelation(org.apache.commons.math3.stat.correlation.SpearmansCorrelation) Map(java.util.Map) SimpleIntegerProperty(javafx.beans.property.SimpleIntegerProperty) ScriptException(javax.script.ScriptException) Set(java.util.Set) KeyEvent(javafx.scene.input.KeyEvent) Executors(java.util.concurrent.Executors) Platform(javafx.application.Platform) Separator(javafx.scene.control.Separator) BooleanProperty(javafx.beans.property.BooleanProperty) Project(qupath.lib.projects.Project) Clipboard(javafx.scene.input.Clipboard) ScrollBarPolicy(javafx.scene.control.ScrollPane.ScrollBarPolicy) CheckBoxTableCell(javafx.scene.control.cell.CheckBoxTableCell) SimpleDoubleProperty(javafx.beans.property.SimpleDoubleProperty) SummaryMeasurementTableCommand(qupath.lib.gui.commands.SummaryMeasurementTableCommand) ObservableList(javafx.collections.ObservableList) BorderPane(javafx.scene.layout.BorderPane) TMAObjectEntry(qupath.lib.gui.tma.TMAEntries.TMAObjectEntry) WeakChangeListener(javafx.beans.value.WeakChangeListener) TreeItem(javafx.scene.control.TreeItem) FXCollections(javafx.collections.FXCollections) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) Bindings(javafx.beans.binding.Bindings) IntegerProperty(javafx.beans.property.IntegerProperty) ArrayList(java.util.ArrayList) MeasurementList(qupath.lib.measurements.MeasurementList) LinkedHashMap(java.util.LinkedHashMap) TabClosingPolicy(javafx.scene.control.TabPane.TabClosingPolicy) TextFields(org.controlsfx.control.textfield.TextFields) TreeTableView(javafx.scene.control.TreeTableView) TextAlignment(javafx.scene.text.TextAlignment) LinkedHashSet(java.util.LinkedHashSet) GridPane(javafx.scene.layout.GridPane) TitledPane(javafx.scene.control.TitledPane) ToolBar(javafx.scene.control.ToolBar) GeneralTools(qupath.lib.common.GeneralTools) Node(javafx.scene.Node) CheckBox(javafx.scene.control.CheckBox) IOException(java.io.IOException) ChartTools(qupath.lib.gui.charts.ChartTools) File(java.io.File) Menu(javafx.scene.control.Menu) DefaultTMAGrid(qupath.lib.objects.hierarchy.DefaultTMAGrid) KeyCodeCombination(javafx.scene.input.KeyCodeCombination) SelectionMode(javafx.scene.control.SelectionMode) TreeMap(java.util.TreeMap) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) Tab(javafx.scene.control.Tab) ObservableValue(javafx.beans.value.ObservableValue) TMAGrid(qupath.lib.objects.hierarchy.TMAGrid) PathPrefs(qupath.lib.gui.prefs.PathPrefs) PaneTools(qupath.lib.gui.tools.PaneTools) PathIO(qupath.lib.io.PathIO) Button(javafx.scene.control.Button) Pos(javafx.geometry.Pos) LoggerFactory(org.slf4j.LoggerFactory) Scanner(java.util.Scanner) XYChart(javafx.scene.chart.XYChart) VBox(javafx.scene.layout.VBox) Side(javafx.geometry.Side) KeyCombination(javafx.scene.input.KeyCombination) ObservableMeasurementTableData(qupath.lib.gui.measure.ObservableMeasurementTableData) ComboBox(javafx.scene.control.ComboBox) ContextMenu(javafx.scene.control.ContextMenu) TableView(javafx.scene.control.TableView) QuPathGUI(qupath.lib.gui.QuPathGUI) SortedList(javafx.collections.transformation.SortedList) Pane(javafx.scene.layout.Pane) Orientation(javafx.geometry.Orientation) TextField(javafx.scene.control.TextField) MenuItem(javafx.scene.control.MenuItem) BufferedImage(java.awt.image.BufferedImage) Predicate(java.util.function.Predicate) Collection(java.util.Collection) FilteredList(javafx.collections.transformation.FilteredList) Collectors(java.util.stream.Collectors) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) Text(javafx.scene.text.Text) SimpleBindings(javax.script.SimpleBindings) Priority(javafx.scene.layout.Priority) List(java.util.List) Entry(java.util.Map.Entry) Optional(java.util.Optional) NumberAxis(javafx.scene.chart.NumberAxis) Scene(javafx.scene.Scene) ListView(javafx.scene.control.ListView) ReadOnlyObjectProperty(javafx.beans.property.ReadOnlyObjectProperty) SimpleStringProperty(javafx.beans.property.SimpleStringProperty) Action(org.controlsfx.control.action.Action) HashMap(java.util.HashMap) DoubleProperty(javafx.beans.property.DoubleProperty) TMAScoreImporter(qupath.lib.io.TMAScoreImporter) TreeTableRow(javafx.scene.control.TreeTableRow) TableColumn(javafx.scene.control.TableColumn) HashSet(java.util.HashSet) Dialogs(qupath.lib.gui.dialogs.Dialogs) ScatterChart(javafx.scene.chart.ScatterChart) Insets(javafx.geometry.Insets) Callback(javafx.util.Callback) Tooltip(javafx.scene.control.Tooltip) ExecutorService(java.util.concurrent.ExecutorService) ImageData(qupath.lib.images.ImageData) KeyCode(javafx.scene.input.KeyCode) ObjectProperty(javafx.beans.property.ObjectProperty) Logger(org.slf4j.Logger) Label(javafx.scene.control.Label) MenuBar(javafx.scene.control.MenuBar) CellDataFeatures(javafx.scene.control.TreeTableColumn.CellDataFeatures) ProjectImageEntry(qupath.lib.projects.ProjectImageEntry) ScriptEngineManager(javax.script.ScriptEngineManager) TMACoreObject(qupath.lib.objects.TMACoreObject) PearsonsCorrelation(org.apache.commons.math3.stat.correlation.PearsonsCorrelation) DropShadow(javafx.scene.effect.DropShadow) MenuTools(qupath.lib.gui.tools.MenuTools) ScriptContext(javax.script.ScriptContext) TMAEntry(qupath.lib.gui.tma.TMAEntries.TMAEntry) TreeTableColumn(javafx.scene.control.TreeTableColumn) SimpleBooleanProperty(javafx.beans.property.SimpleBooleanProperty) Stage(javafx.stage.Stage) ScriptEngine(javax.script.ScriptEngine) ChangeListener(javafx.beans.value.ChangeListener) Collections(java.util.Collections) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) TMAEntry(qupath.lib.gui.tma.TMAEntries.TMAEntry) TMAObjectEntry(qupath.lib.gui.tma.TMAEntries.TMAObjectEntry) ObservableList(javafx.collections.ObservableList) ArrayList(java.util.ArrayList) MeasurementList(qupath.lib.measurements.MeasurementList) SortedList(javafx.collections.transformation.SortedList) FilteredList(javafx.collections.transformation.FilteredList) List(java.util.List)

Example 18 with TMAEntry

use of qupath.lib.gui.tma.TMAEntries.TMAEntry in project qupath by qupath.

the class TMASummaryViewer method setInputFile.

/**
 * Set the input file for the summary viewer.
 * @param file
 */
public void setInputFile(File file) {
    if (file == null)
        return;
    if (file.getName().toLowerCase().endsWith(PathPrefs.getSerializationExtension())) {
        try {
            ImageData<BufferedImage> imageData = PathIO.readImageData(file, null, null, BufferedImage.class);
            setTMAEntriesFromImageData(imageData);
        } catch (IOException e) {
            logger.error("Error reading image data", e);
        }
        return;
    }
    List<TMAEntry> entriesTemp = new ArrayList<>();
    File dir = file.isDirectory() ? file : file.getParentFile();
    for (File fileInput : dir.listFiles()) {
        if (fileInput.isHidden() || fileInput.isDirectory() || !fileInput.getName().toLowerCase().endsWith(".qptma"))
            continue;
        parseInputFile(fileInput, entriesTemp);
    }
    if (entriesTemp.isEmpty()) {
        logger.error("No data found for " + file.getAbsolutePath());
        return;
    }
    setTMAEntries(entriesTemp);
    stage.setTitle("TMA Results View: " + dir.getName());
}
Also used : TMAEntry(qupath.lib.gui.tma.TMAEntries.TMAEntry) ArrayList(java.util.ArrayList) IOException(java.io.IOException) File(java.io.File) BufferedImage(java.awt.image.BufferedImage)

Example 19 with TMAEntry

use of qupath.lib.gui.tma.TMAEntries.TMAEntry in project qupath by qupath.

the class TMASummaryViewer method createSummaryEntries.

// class SummaryTreeItem extends TreeItem<TMAEntry> implements ChangeListener<Predicate<? super TMAEntry>> {
// 
// private TMASummaryEntry entry;
// 
// SummaryTreeItem(final TMASummaryEntry entry) {
// super(entry);
// this.entry = entry;
// combinedPredicate.addListener(new WeakChangeListener<Predicate<? super TMAEntry>>(this));
// updateChildren();
// }
// 
// private void updateChildren() {
// ArrayList<TreeItem<TMAEntry>> children = new ArrayList<>();
// for (TMAEntry subEntry : entry.getEntries())
// children.add(new TreeItem<>(subEntry));
// super.getChildren().setAll(children);
// }
// 
// @Override
// public void changed(ObservableValue<? extends Predicate<? super TMAEntry>> observable,
// Predicate<? super TMAEntry> oldValue, Predicate<? super TMAEntry> newValue) {
// updateChildren();
// }
// 
// }
/**
 * Create summaries entries by grouping according to Unique ID.
 *
 * @param entries
 * @return
 */
private Collection<? extends TMAEntry> createSummaryEntries(final List<? extends TMAEntry> entries) {
    Map<String, TMASummaryEntry> summaryEntryMap = new TreeMap<>();
    int maxSummaryLength = 0;
    for (TMAEntry entry : entries) {
        String id = entry.getMetadataValue(TMACoreObject.KEY_UNIQUE_ID);
        if (id == null && entry.getMeasurement(TMACoreObject.KEY_UNIQUE_ID) != null)
            id = entry.getMeasurement(TMACoreObject.KEY_UNIQUE_ID).toString();
        if (id == null || id.trim().length() == 0) {
            if (!"True".equals(entry.getMetadataValue(MISSING_COLUMN)))
                logger.trace("No ID found for {}", entry);
            continue;
        }
        TMASummaryEntry summary = summaryEntryMap.get(id);
        if (summary == null) {
            summary = new TMASummaryEntry(selectedMeasurementCombinationProperty, skipMissingCoresProperty, combinedPredicate);
            summaryEntryMap.put(id, summary);
        }
        summary.addEntry(entry);
        maxSummaryLength = Math.max(maxSummaryLength, summary.getEntries().size());
    }
    // If we don't have any summaries, just return the original entries
    if (summaryEntryMap.isEmpty() || maxSummaryLength <= 1)
        return entries;
    return summaryEntryMap.values();
}
Also used : TMAEntry(qupath.lib.gui.tma.TMAEntries.TMAEntry) TreeMap(java.util.TreeMap)

Example 20 with TMAEntry

use of qupath.lib.gui.tma.TMAEntries.TMAEntry in project qupath by qupath.

the class TMASummaryViewer method createSidePane.

private Pane createSidePane() {
    BorderPane pane = new BorderPane();
    TabPane tabPane = new TabPane();
    kmDisplay = new KaplanMeierDisplay(null, null, null, null);
    BorderPane paneKaplanMeier = new BorderPane();
    paneKaplanMeier.setCenter(kmDisplay.getView());
    paneKaplanMeier.setPadding(new Insets(10, 10, 10, 10));
    // comboMainMeasurement.prefWidthProperty().bind(paneKaplanMeier.widthProperty());
    comboMainMeasurement.setMaxWidth(Double.MAX_VALUE);
    comboMainMeasurement.setTooltip(new Tooltip("Measurement thresholded to create survival curves etc."));
    GridPane kmTop = new GridPane();
    kmTop.add(new Label("Score"), 0, 0);
    kmTop.add(comboMainMeasurement, 1, 0);
    kmTop.add(new Label("Survival type"), 0, 1);
    kmTop.add(comboSurvival, 1, 1);
    comboSurvival.setTooltip(new Tooltip("Specify overall or recurrence-free survival (if applicable)"));
    comboSurvival.setMaxWidth(Double.MAX_VALUE);
    GridPane.setHgrow(comboMainMeasurement, Priority.ALWAYS);
    GridPane.setHgrow(comboSurvival, Priority.ALWAYS);
    kmTop.setHgap(5);
    paneKaplanMeier.setTop(kmTop);
    // kmDisplay.setOrientation(Orientation.VERTICAL);
    histogramDisplay = new HistogramDisplay(model, false);
    comboMainMeasurement.getSelectionModel().selectedItemProperty().addListener((v, o, n) -> {
        histogramDisplay.refreshCombo();
        histogramDisplay.showHistogram(n);
        updateSurvivalCurves();
    });
    comboMeasurementMethod.getSelectionModel().selectedItemProperty().addListener((v, o, n) -> {
        histogramDisplay.refreshHistogram();
        scatterPane.updateChart();
        updateSurvivalCurves();
    });
    comboSurvival.getSelectionModel().selectedItemProperty().addListener((v, o, n) -> {
        updateSurvivalCurves();
    });
    // Create a Tab for showing images
    BorderPane paneImages = new BorderPane();
    CheckBox cbShowOverlay = new CheckBox("Show overlay");
    imageAvailability.addListener((c, v, n) -> {
        if (n == ImageAvailability.OVERLAY_ONLY)
            cbShowOverlay.setSelected(true);
        else if (n == ImageAvailability.IMAGE_ONLY)
            cbShowOverlay.setSelected(false);
        cbShowOverlay.setDisable(n != ImageAvailability.BOTH);
    });
    ListView<TMAEntry> listImages = new ListView<>();
    listImages.setCellFactory(v -> new ImageListCell(cbShowOverlay.selectedProperty(), imageCache));
    listImages.widthProperty().addListener((v, o, n) -> listImages.refresh());
    listImages.setStyle("-fx-control-inner-background-alt: -fx-control-inner-background ;");
    table.getSelectionModel().getSelectedItems().addListener((Change<? extends TreeItem<TMAEntry>> e) -> {
        List<TMAEntry> entries = new ArrayList<>();
        for (TreeItem<TMAEntry> item : e.getList()) {
            if (item.getChildren().isEmpty()) {
                if (item.getValue().hasImage() || item.getValue().hasOverlay())
                    entries.add(item.getValue());
            } else {
                for (TreeItem<TMAEntry> item2 : item.getChildren()) {
                    if (item2.getValue().hasImage() || item2.getValue().hasOverlay())
                        entries.add(item2.getValue());
                }
            }
            listImages.getItems().setAll(entries);
        }
    });
    cbShowOverlay.setAlignment(Pos.CENTER);
    cbShowOverlay.setMaxWidth(Double.MAX_VALUE);
    cbShowOverlay.setPadding(new Insets(5, 5, 5, 5));
    cbShowOverlay.selectedProperty().addListener((v, o, n) -> listImages.refresh());
    paneImages.setCenter(listImages);
    paneImages.setTop(cbShowOverlay);
    // Determine visibility based upon whether there are any images to show
    // Tab tabImages = new Tab("Images", paneImages);
    ScrollPane scrollPane = new ScrollPane(paneKaplanMeier);
    scrollPane.setFitToWidth(true);
    scrollPane.setFitToHeight(true);
    scrollPane.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
    scrollPane.setHbarPolicy(ScrollBarPolicy.AS_NEEDED);
    Tab tabSurvival = new Tab("Survival", scrollPane);
    tabPane.getTabs().addAll(new Tab("Table", getCustomizeTablePane()), // tabImages,
    new Tab("Histogram", histogramDisplay.getPane()), new Tab("Scatterplot", scatterPane.getPane()), tabSurvival);
    tabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
    // if (imageAvailability.get() != ImageAvailability.NONE)
    // tabPane.getTabs().add(1, tabImages);
    // 
    // imageAvailability.addListener((c, v, n) -> {
    // if (n == ImageAvailability.NONE)
    // tabPane.getTabs().remove(tabImages);
    // else if (!tabPane.getTabs().contains(tabImages))
    // tabPane.getTabs().add(1, tabImages);
    // });
    // tabSurvival.visibleProperty().bind(
    // Bindings.createBooleanBinding(() -> !survivalColumns.isEmpty(), survivalColumns)
    // );
    pane.setCenter(tabPane);
    pane.setMinWidth(350);
    return pane;
}
Also used : TabPane(javafx.scene.control.TabPane) BorderPane(javafx.scene.layout.BorderPane) Insets(javafx.geometry.Insets) GridPane(javafx.scene.layout.GridPane) TreeItem(javafx.scene.control.TreeItem) Tooltip(javafx.scene.control.Tooltip) TMAEntry(qupath.lib.gui.tma.TMAEntries.TMAEntry) Label(javafx.scene.control.Label) ArrayList(java.util.ArrayList) Change(javafx.collections.ListChangeListener.Change) HistogramDisplay(qupath.lib.gui.charts.HistogramDisplay) ListView(javafx.scene.control.ListView) Tab(javafx.scene.control.Tab) CheckBox(javafx.scene.control.CheckBox) ScrollPane(javafx.scene.control.ScrollPane)

Aggregations

TMAEntry (qupath.lib.gui.tma.TMAEntries.TMAEntry)22 ArrayList (java.util.ArrayList)12 IOException (java.io.IOException)8 MeasurementList (qupath.lib.measurements.MeasurementList)8 TMACoreObject (qupath.lib.objects.TMACoreObject)8 BufferedImage (java.awt.image.BufferedImage)7 File (java.io.File)7 List (java.util.List)7 ObservableList (javafx.collections.ObservableList)7 FilteredList (javafx.collections.transformation.FilteredList)7 SortedList (javafx.collections.transformation.SortedList)7 HashMap (java.util.HashMap)6 LinkedHashMap (java.util.LinkedHashMap)6 TMAGrid (qupath.lib.objects.hierarchy.TMAGrid)6 TreeMap (java.util.TreeMap)5 Arrays (java.util.Arrays)4 Collection (java.util.Collection)4 Collections (java.util.Collections)4 HashSet (java.util.HashSet)4 LinkedHashSet (java.util.LinkedHashSet)4