All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.cmu.tetradapp.editor.search.AlgorithmCard Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2019 University of Pittsburgh.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301  USA
 */
package edu.cmu.tetradapp.editor.search;

import edu.cmu.tetrad.algcomparison.algorithm.Algorithm;
import edu.cmu.tetrad.algcomparison.algorithm.AlgorithmFactory;
import edu.cmu.tetrad.algcomparison.algorithm.oracle.cpdag.SingleGraphAlg;
import edu.cmu.tetrad.algcomparison.utils.HasKnowledge;
import edu.cmu.tetrad.algcomparison.utils.TakesExternalGraph;
import edu.cmu.tetrad.annotation.*;
import edu.cmu.tetrad.data.*;
import edu.cmu.tetrad.util.TetradLogger;
import edu.cmu.tetradapp.app.TetradDesktop;
import edu.cmu.tetradapp.model.GeneralAlgorithmRunner;
import edu.cmu.tetradapp.ui.PaddingPanel;
import edu.cmu.tetradapp.ui.model.*;
import edu.cmu.tetradapp.util.DesktopController;

import javax.swing.*;
import javax.swing.LayoutStyle.ComponentPlacement;
import java.awt.*;
import java.io.Serial;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.*;

/**
 * Apr 15, 2019 11:31:10 AM
 *
 * @author Kevin V. Bui ([email protected])
 * @version $Id: $Id
 */
public class AlgorithmCard extends JPanel {
    @Serial
    private static final long serialVersionUID = -7552068626783685630L;

    /**
     * The algorithm runner.
     */
    private final String ALGO_PARAM = "algo";

    /**
     * Independent test parameter.
     */
    private final String IND_TEST_PARAM = "ind_test";

    /**
     * Score parameter.
     */
    private final String SCORE_PARAM = "score";

    /**
     * Algorithm type parameter.
     */
    private final String ALGO_TYPE_PARAM = "algo_type";

    /**
     * Dataset filter parameter.
     */
    private final String DATASET_FILTER = "dataset_filter";

    /**
     * Knowledge parameter.
     */
    private final String KNOWLEDGE_PARAM = "knowledge";

    /**
     * Algorithm type options.
     */
    private final List algoTypeOpts = new ArrayList<>();

    /**
     * Algorithm models.
     */
    private final DefaultListModel algoModels = new DefaultListModel<>();

    /**
     * Algorithm filter button group.
     */
    private final ButtonGroup algoFilterBtnGrp = new ButtonGroup();

    /**
     * Dataset filter button group.
     */
    private final ButtonGroup datasetFilterBtnGrp = new ButtonGroup();

    /**
     * Default independence test models.
     */
    private final Map> defaultIndTestModels = new HashMap<>();

    /**
     * Default score models.
     */
    private final Map> defaultScoreModels = new HashMap<>();

    /**
     * Knowledge checkbox.
     */
    private final JCheckBox knowledgeChkBox = new JCheckBox("accepts knowledge");

    /**
     * Linear, Gaussian radio button.
     */
    private final JRadioButton linearGaussianRadBtn = new JRadioButton("Linear, Gaussian");

    /**
     * Mixed, discrete, Gaussian radio button.
     */
    private final JRadioButton mixedRadBtn = new JRadioButton("Mixed Discrete/Gaussian");

    /**
     * General radio button.
     */
    private final JRadioButton generalRadBtn = new JRadioButton("General");

    /**
     * All radio button.
     */
    private final JRadioButton allRadBtn = new JRadioButton("All");

    /**
     * Independence test combo box.
     */
    private final JComboBox indTestComboBox = new JComboBox<>();

    /**
     * Score combo box.
     */
    private final JComboBox scoreComboBox = new JComboBox<>();

    /**
     * Algorithm list.
     */
    private final JList algorithmList = new JList<>(this.algoModels);

    /**
     * Algorithm description text area.
     */
    private final JTextArea algoDescTextArea = new JTextArea();

    /**
     * Score description text area.
     */
    private final JTextArea scoreDescTextArea = new JTextArea();

    /**
     * Test description text area.
     */
    private final JTextArea testDescTextArea = new JTextArea();

    /**
     * The algorithm runner.
     */
    private final GeneralAlgorithmRunner algorithmRunner;

    /**
     * The data type.
     */
    private final DataType dataType;

    /**
     * The desktop.
     */
    private final TetradDesktop desktop;

    /**
     * Multi-data algorithm.
     */
    private final boolean multiDataAlgo;

    /**
     * Updating test models.
     */
    private boolean updatingTestModels;

    /**
     * Updating score models.
     */
    private boolean updatingScoreModels;

    /**
     * 

Constructor for AlgorithmCard.

* * @param algorithmRunner a {@link edu.cmu.tetradapp.model.GeneralAlgorithmRunner} object */ public AlgorithmCard(GeneralAlgorithmRunner algorithmRunner) { this.algorithmRunner = algorithmRunner; this.dataType = getDataType(algorithmRunner); this.desktop = (TetradDesktop) DesktopController.getInstance(); this.multiDataAlgo = algorithmRunner.getSourceGraph() == null && algorithmRunner.getDataModelList().size() > 1; initComponents(); initListeners(); resetAllSettings(); this.algorithmList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); } private void initComponents() { initDescriptionTextAreas(); JButton resetSettingsBtn = new JButton("Reset All Settings"); resetSettingsBtn.addActionListener(e -> { resetAllSettings(); }); JPanel westMainSouthPanel = new JPanel(new BorderLayout(0, 10)); westMainSouthPanel.add(new TestAndScorePanel(), BorderLayout.CENTER); westMainSouthPanel.add(resetSettingsBtn, BorderLayout.SOUTH); JPanel westMainWestPanel = new JPanel(new BorderLayout(0, 10)); westMainWestPanel.add(new AlgorithmFilterPanel(), BorderLayout.CENTER); westMainWestPanel.add(westMainSouthPanel, BorderLayout.SOUTH); JPanel westMainPanel = new JPanel(new BorderLayout(5, 0)); westMainPanel.add(westMainWestPanel, BorderLayout.WEST); westMainPanel.add(new AlgorithmListPanel(), BorderLayout.EAST); JPanel testAndScoreDescPanel = new JPanel(); testAndScoreDescPanel.setLayout(new BoxLayout(testAndScoreDescPanel, BoxLayout.Y_AXIS)); testAndScoreDescPanel.add(new DescriptionPanel("Test Description", this.testDescTextArea)); testAndScoreDescPanel.add(Box.createVerticalStrut(10)); testAndScoreDescPanel.add(new DescriptionPanel("Score Description", this.scoreDescTextArea)); JPanel centerMainPanel = new JPanel(new BorderLayout(0, 10)); centerMainPanel.add(new DescriptionPanel("Algorithm Description", this.algoDescTextArea), BorderLayout.CENTER); centerMainPanel.add(testAndScoreDescPanel, BorderLayout.SOUTH); centerMainPanel.setPreferredSize(new Dimension(235, 200)); setLayout(new BorderLayout(10, 0)); add(westMainPanel, BorderLayout.WEST); add(centerMainPanel, BorderLayout.CENTER); if (this.algorithmRunner.hasMissingValues()) { setPreferredSize(new Dimension(308, 291)); } else { setPreferredSize(new Dimension(308, 241)); } } private void initListeners() { this.knowledgeChkBox.addActionListener(e -> { refreshAlgorithmList(); }); this.linearGaussianRadBtn.addActionListener(e -> { refreshTestAndScoreList(); }); this.mixedRadBtn.addActionListener(e -> { refreshTestAndScoreList(); }); this.generalRadBtn.addActionListener(e -> { refreshTestAndScoreList(); }); this.allRadBtn.addActionListener(e -> { refreshTestAndScoreList(); }); this.algorithmList.addListSelectionListener(e -> { if (!(e.getValueIsAdjusting() || this.algorithmList.isSelectionEmpty())) { setAlgorithmDescription(); refreshTestAndScoreList(); validateAlgorithmOption(); } }); this.indTestComboBox.addActionListener(e -> { if (!this.updatingTestModels && this.indTestComboBox.getSelectedIndex() >= 0) { setIndepTestDescription(); AlgorithmModel algoModel = this.algorithmList.getSelectedValue(); Map map = this.defaultIndTestModels.get(algoModel); if (map == null) { map = new EnumMap<>(DataType.class); this.defaultIndTestModels.put(algoModel, map); } map.put(this.dataType, this.indTestComboBox.getItemAt(this.indTestComboBox.getSelectedIndex())); } }); this.scoreComboBox.addActionListener(e -> { if (!this.updatingScoreModels && this.scoreComboBox.getSelectedIndex() >= 0) { setScoreDescription(); AlgorithmModel algoModel = this.algorithmList.getSelectedValue(); Map map = this.defaultScoreModels.get(algoModel); if (map == null) { map = new EnumMap<>(DataType.class); this.defaultScoreModels.put(algoModel, map); } map.put(this.dataType, this.scoreComboBox.getItemAt(this.scoreComboBox.getSelectedIndex())); } }); } private void initDescriptionTextAreas() { this.algoDescTextArea.setWrapStyleWord(true); this.algoDescTextArea.setLineWrap(true); this.algoDescTextArea.setEditable(false); this.scoreDescTextArea.setWrapStyleWord(true); this.scoreDescTextArea.setLineWrap(true); this.scoreDescTextArea.setEditable(false); this.scoreDescTextArea.setRows(6); this.testDescTextArea.setWrapStyleWord(true); this.testDescTextArea.setLineWrap(true); this.testDescTextArea.setEditable(false); this.testDescTextArea.setRows(6); } private DataType getDataType(GeneralAlgorithmRunner algorithmRunner) { DataModelList dataModelList = algorithmRunner.getDataModelList(); if (dataModelList.containsEmptyData()) { if (algorithmRunner.getSourceGraph() == null) { return null; } else { return DataType.Graph; } } else { DataModel dataSet = dataModelList.get(0); if (dataSet.isContinuous() && !(dataSet instanceof ICovarianceMatrix)) { // covariance dataset is continuous at the same time - Zhou return DataType.Continuous; } else if (dataSet.isDiscrete()) { return DataType.Discrete; } else if (dataSet.isMixed()) { return DataType.Mixed; } else if (dataSet instanceof ICovarianceMatrix) { // Better to add an isCovariance() - Zhou return DataType.Covariance; } else { return null; } } } /** *

getSelectedAlgorithm.

* * @return a {@link edu.cmu.tetradapp.ui.model.AlgorithmModel} object */ public AlgorithmModel getSelectedAlgorithm() { return this.algorithmList.getSelectedValue(); } /** *

getSelectedIndependenceTest.

* * @return a {@link edu.cmu.tetradapp.ui.model.IndependenceTestModel} object */ public IndependenceTestModel getSelectedIndependenceTest() { if (this.indTestComboBox.isEnabled()) { return this.indTestComboBox.getItemAt(this.indTestComboBox.getSelectedIndex()); } return null; } /** *

getSelectedScore.

* * @return a {@link edu.cmu.tetradapp.ui.model.ScoreModel} object */ public ScoreModel getSelectedScore() { if (this.scoreComboBox.isEnabled()) { this.scoreComboBox.getItemAt(this.scoreComboBox.getSelectedIndex()); } return null; } private void rememberUserAlgoSelections(Map userAlgoSelections) { userAlgoSelections.put(this.IND_TEST_PARAM, this.indTestComboBox.getSelectedItem()); userAlgoSelections.put(this.SCORE_PARAM, this.scoreComboBox.getSelectedItem()); userAlgoSelections.put(this.ALGO_TYPE_PARAM, this.algoFilterBtnGrp.getSelection().getActionCommand()); userAlgoSelections.put(this.DATASET_FILTER, this.datasetFilterBtnGrp.getSelection().getActionCommand()); userAlgoSelections.put(this.KNOWLEDGE_PARAM, this.knowledgeChkBox.isSelected()); // When there's a search result, we store the algo string name from the search so we wont' lose it // when the upstream nodes change. // Otherwise, we use the one that users selcted on the UI - Zhou if (this.algorithmRunner.getGraphs() != null && !this.algorithmRunner.getGraphs().isEmpty()) { userAlgoSelections.put(this.ALGO_PARAM, this.algorithmRunner.getAlgorithm().getClass().getAnnotation(edu.cmu.tetrad.annotation.Algorithm.class).name()); } else { userAlgoSelections.put(this.ALGO_PARAM, this.algorithmList.getSelectedValue().toString()); } } /** * This restore mechanism won't restore user selections other than selected algo name when user changes the upstream * (after clicking the "Execute" button), because a new algo algorithmRunner is created and we lose the stored * models from the old algorithmRunner - Zhou */ private void restoreUserAlgoSelections(Map userAlgoSelections) { Object obj = userAlgoSelections.get(this.DATASET_FILTER); if ((obj != null) && (obj instanceof String)) { String actCmd = String.valueOf(obj); for (Enumeration e = this.datasetFilterBtnGrp.getElements(); e.hasMoreElements(); ) { JRadioButton radBtn = (JRadioButton) e.nextElement(); if (radBtn.getActionCommand().equals(actCmd)) { radBtn.setSelected(true); break; } } } obj = userAlgoSelections.get(this.KNOWLEDGE_PARAM); if ((obj != null) && (obj instanceof Boolean)) { this.knowledgeChkBox.setSelected((Boolean) obj); } obj = userAlgoSelections.get(this.ALGO_TYPE_PARAM); if ((obj != null) && (obj instanceof String)) { String actCmd = String.valueOf(obj); Optional opt = this.algoTypeOpts.stream() .filter(e -> e.getActionCommand().equals(actCmd)) .findFirst(); opt.ifPresent(jRadioButton -> jRadioButton.setSelected(true)); } refreshAlgorithmList(); refreshTestAndScoreList(); // Restore the algo name from search when there's a search result. // Otherwise use the stored name form algorithmRunner.getModels(), which will be lost when the upstream nodes change - Zhou String selectedAlgoName = null; if (this.algorithmRunner.getGraphs() != null && this.algorithmRunner.getGraphs().size() > 0) { selectedAlgoName = this.algorithmRunner.getAlgorithm().getClass().getAnnotation(edu.cmu.tetrad.annotation.Algorithm.class).name(); } else { obj = userAlgoSelections.get(this.ALGO_PARAM); if ((obj != null) && (obj instanceof String)) { selectedAlgoName = (String) obj; } } Enumeration enums = this.algoModels.elements(); while (enums.hasMoreElements()) { AlgorithmModel model = enums.nextElement(); if (model.toString().equals(selectedAlgoName)) { this.algorithmList.setSelectedValue(model, true); break; } } obj = userAlgoSelections.get(this.IND_TEST_PARAM); if ((obj != null) && (obj instanceof IndependenceTestModel)) { String value = obj.toString(); ComboBoxModel comboBoxModels = this.indTestComboBox.getModel(); int size = comboBoxModels.getSize(); for (int i = 0; i < size; i++) { IndependenceTestModel model = comboBoxModels.getElementAt(i); if (model.toString().equals(value)) { userAlgoSelections.put(this.IND_TEST_PARAM, model); this.indTestComboBox.getModel().setSelectedItem(model); break; } } } obj = userAlgoSelections.get(this.SCORE_PARAM); if ((obj != null) && (obj instanceof ScoreModel)) { String value = obj.toString(); ComboBoxModel comboBoxModels = this.scoreComboBox.getModel(); int size = comboBoxModels.getSize(); for (int i = 0; i < size; i++) { ScoreModel model = comboBoxModels.getElementAt(i); if (model.toString().equals(value)) { userAlgoSelections.put(this.SCORE_PARAM, model); this.scoreComboBox.getModel().setSelectedItem(model); break; } } } } /** *

refresh.

*/ public void refresh() { restoreUserAlgoSelections(this.algorithmRunner.getUserAlgoSelections()); } /** *

saveStates.

*/ public void saveStates() { rememberUserAlgoSelections(this.algorithmRunner.getUserAlgoSelections()); } /** * Initialize algorithm * * @param algoModel a {@link edu.cmu.tetradapp.ui.model.AlgorithmModel} object * @param indTestModel a {@link edu.cmu.tetradapp.ui.model.IndependenceTestModel} object * @param scoreModel a {@link edu.cmu.tetradapp.ui.model.ScoreModel} object * @return Algorithm */ public Algorithm getAlgorithmFromInterface(AlgorithmModel algoModel, IndependenceTestModel indTestModel, ScoreModel scoreModel) { Class algoClass = algoModel.getAlgorithm().clazz(); Class indTestClass = (indTestModel == null) ? null : indTestModel.getIndependenceTest().clazz(); Class scoreClass = (scoreModel == null) ? null : scoreModel.getScore().clazz(); Algorithm algorithm = null; try { algorithm = AlgorithmFactory.create(algoClass, indTestClass, scoreClass); } catch (IllegalAccessException | InstantiationException | InvocationTargetException exception) { TetradLogger.getInstance().log(exception.toString()); } // Those pairwise algos (R3, RShew, Skew..) require source graph to initialize - Zhou if (algorithm instanceof TakesExternalGraph && this.algorithmRunner.getSourceGraph() != null /*&& !this.algorithmRunner.getDataModelList().isEmpty()*/) { Algorithm externalGraph = new SingleGraphAlg(this.algorithmRunner.getSourceGraph()); ((TakesExternalGraph) algorithm).setExternalGraph(externalGraph); } return algorithm; } /** *

isAllValid.

* * @return a boolean */ public boolean isAllValid() { AlgorithmModel algoModel = this.algorithmList.getSelectedValue(); IndependenceTestModel indTestModel = this.indTestComboBox.getItemAt(this.indTestComboBox.getSelectedIndex()); ScoreModel scoreModel = this.scoreComboBox.getItemAt(this.scoreComboBox.getSelectedIndex()); boolean missingTest = algoModel.isRequiredTest() && (indTestModel == null); boolean missingScore = algoModel.isRequiredScore() && (scoreModel == null); if (missingTest && missingScore) { String msg = String.format("%s requires both test and score.", algoModel.getAlgorithm().annotation().name()); JOptionPane.showMessageDialog(this.desktop, msg, "Please Note", JOptionPane.INFORMATION_MESSAGE); return false; } else if (missingTest) { String msg = String.format("%s requires independence test.", algoModel.getAlgorithm().annotation().name()); JOptionPane.showMessageDialog(this.desktop, msg, "Please Note", JOptionPane.INFORMATION_MESSAGE); return false; } else if (missingScore) { String msg = String.format("%s requires score.", algoModel.getAlgorithm().annotation().name()); JOptionPane.showMessageDialog(this.desktop, msg, "Please Note", JOptionPane.INFORMATION_MESSAGE); return false; } else { this.algorithmRunner.setAlgorithm(getAlgorithmFromInterface(algoModel, indTestModel, scoreModel)); return true; } } private void validateAlgorithmOption() { firePropertyChange("algoFwdBtn", null, true); AlgorithmModel algoModel = this.algorithmList.getSelectedValue(); Class algoClass = algoModel.getAlgorithm().clazz(); if (algoClass.isAnnotationPresent(Nonexecutable.class)) { String msg; try { Object algo = algoClass.getDeclaredConstructor().newInstance(); Method m = algoClass.getDeclaredMethod("getDescription"); m.setAccessible(true); try { msg = String.valueOf(m.invoke(algo)); } catch (InvocationTargetException exception) { msg = ""; } } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException exception) { TetradLogger.getInstance().log(exception.toString()); msg = ""; } firePropertyChange("algoFwdBtn", null, false); JOptionPane.showMessageDialog(this.desktop, msg, "Please Note", JOptionPane.INFORMATION_MESSAGE); } else { // Check if initial graph is provided for those pairwise algorithms if (TakesExternalGraph.class.isAssignableFrom(algoClass)) { if (this.algorithmRunner.getSourceGraph() == null || this.algorithmRunner.getDataModelList().isEmpty()) { try { Object algo = algoClass.getDeclaredConstructor().newInstance(); Method m = algoClass.getDeclaredMethod("setExternalGraph", Algorithm.class); m.setAccessible(true); try { Algorithm algorithm = null; m.invoke(algo, algorithm); } catch (InvocationTargetException | IllegalArgumentException exception) { firePropertyChange("algoFwdBtn", null, false); JOptionPane.showMessageDialog(this.desktop, exception.getCause().getMessage(), "Please Note", JOptionPane.INFORMATION_MESSAGE); } } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException exception) { TetradLogger.getInstance().log(exception.toString()); } } } // SVAR (SvarFci, SvarGfci) algorithms need lagged data String cmd = algoModel.getAlgorithm().annotation().command(); if (cmd.equalsIgnoreCase("ts-fci") || cmd.equalsIgnoreCase("ts-gfci") || cmd.equalsIgnoreCase("ts-imgs")) { DataModel dataModel = this.algorithmRunner.getDataModel(); Knowledge knowledge = this.algorithmRunner.getKnowledge(); if ((knowledge == null || knowledge.isEmpty()) && (dataModel.getKnowledge() == null || dataModel.getKnowledge().isEmpty())) { firePropertyChange("algoFwdBtn", null, false); JOptionPane.showMessageDialog(this.desktop, "Time-series algorithm needs lagged data", "Please Note", JOptionPane.INFORMATION_MESSAGE); } } } } private void refreshAlgorithmList() { this.algoModels.clear(); ButtonModel selectedAlgoType = this.algoFilterBtnGrp.getSelection(); if (selectedAlgoType != null) { AlgorithmModels algorithmModels = AlgorithmModels.getInstance(); String algoType = selectedAlgoType.getActionCommand(); if ("all".equals(algoType)) { if (this.knowledgeChkBox.isSelected()) { algorithmModels.getModels(this.dataType, this.multiDataAlgo).stream() .filter(e -> HasKnowledge.class.isAssignableFrom(e.getAlgorithm().clazz())) .forEach(this.algoModels::addElement); } else { algorithmModels.getModels(this.dataType, this.multiDataAlgo) .forEach(this.algoModels::addElement); } } else { if (this.knowledgeChkBox.isSelected()) { algorithmModels.getModels(AlgType.valueOf(algoType), this.dataType, this.multiDataAlgo).stream() .filter(e -> HasKnowledge.class.isAssignableFrom(e.getAlgorithm().clazz())) .forEach(this.algoModels::addElement); } else { algorithmModels.getModels(AlgType.valueOf(algoType), this.dataType, this.multiDataAlgo) .forEach(this.algoModels::addElement); } } if (this.algoModels.isEmpty()) { this.algoDescTextArea.setText(""); firePropertyChange("algoFwdBtn", null, false); } else { this.algorithmList.setSelectedIndex(0); firePropertyChange("algoFwdBtn", null, true); } } this.scoreComboBox.setEnabled(this.scoreComboBox.getItemCount() > 0); } private void refreshTestList() { this.updatingTestModels = true; this.indTestComboBox.removeAllItems(); AlgorithmModel algoModel = this.algorithmList.getSelectedValue(); if (algoModel != null && algoModel.isRequiredTest()) { List models = IndependenceTestModels.getInstance().getModels(this.dataType); if (this.linearGaussianRadBtn.isSelected()) { models.stream() .filter(e -> e.getIndependenceTest().clazz().isAnnotationPresent(LinearGaussian.class)) .forEach(this.indTestComboBox::addItem); } else if (this.mixedRadBtn.isSelected()) { for (IndependenceTestModel e : models) { if (e.getIndependenceTest().clazz().isAnnotationPresent(Mixed.class)) { this.indTestComboBox.addItem(e); } } } else if (this.generalRadBtn.isSelected()) { models.stream() .filter(e -> e.getIndependenceTest().clazz().isAnnotationPresent(General.class)) .forEach(this.indTestComboBox::addItem); } else if (this.allRadBtn.isSelected()) { models.forEach(this.indTestComboBox::addItem); } } this.updatingTestModels = false; if (this.indTestComboBox.getItemCount() > 0) { this.indTestComboBox.setEnabled(true); Map map = this.defaultIndTestModels.get(algoModel); if (map == null) { map = new EnumMap<>(DataType.class); this.defaultIndTestModels.put(algoModel, map); } IndependenceTestModel testModel = map.get(this.dataType); if (testModel == null) { testModel = IndependenceTestModels.getInstance().getDefaultModel(this.dataType); if (testModel == null) { testModel = this.indTestComboBox.getItemAt(0); } } this.indTestComboBox.setSelectedItem(testModel); this.indTestComboBox.getSelectedIndex(); } else { this.indTestComboBox.setEnabled(false); } if (this.indTestComboBox.getSelectedIndex() == -1) { this.testDescTextArea.setText(""); } } private void refreshScoreList() { this.updatingScoreModels = true; this.scoreComboBox.removeAllItems(); AlgorithmModel algoModel = this.algorithmList.getSelectedValue(); if (algoModel != null && algoModel.isRequiredScore()) { List models = ScoreModels.getInstance().getModels(this.dataType); if (this.linearGaussianRadBtn.isSelected()) { models.stream() .filter(e -> e.getScore().clazz().isAnnotationPresent(LinearGaussian.class)) .forEach(this.scoreComboBox::addItem); } else if (this.mixedRadBtn.isSelected()) { models.stream() .filter(e -> e.getScore().clazz().isAnnotationPresent(Mixed.class)) .forEach(this.scoreComboBox::addItem); } else if (this.generalRadBtn.isSelected()) { models.stream() .filter(e -> e.getScore().clazz().isAnnotationPresent(General.class)) .forEach(this.scoreComboBox::addItem); } else if (this.allRadBtn.isSelected()) { models.forEach(this.scoreComboBox::addItem); } } this.updatingScoreModels = false; if (this.scoreComboBox.getItemCount() > 0) { this.scoreComboBox.setEnabled(true); Map map = this.defaultScoreModels.get(algoModel); if (map == null) { map = new EnumMap<>(DataType.class); this.defaultScoreModels.put(algoModel, map); } ScoreModel scoreModel = map.get(this.dataType); if (scoreModel == null) { scoreModel = ScoreModels.getInstance().getDefaultModel(this.dataType); if (scoreModel == null) { scoreModel = this.scoreComboBox.getItemAt(0); } } this.scoreComboBox.setSelectedItem(scoreModel); } else { this.scoreComboBox.setEnabled(false); } if (this.scoreComboBox.getSelectedIndex() == -1) { this.scoreDescTextArea.setText(""); } } private void refreshTestAndScoreList() { refreshTestList(); refreshScoreList(); } private void resetAllSettings() { // clear cache this.defaultIndTestModels.clear(); this.defaultScoreModels.clear(); // uncheck all checkboxes this.datasetFilterBtnGrp.setSelected(this.allRadBtn.getModel(), true); this.knowledgeChkBox.setSelected(false); if (!this.algoTypeOpts.isEmpty()) { this.algoTypeOpts.get(0).setSelected(true); } refreshAlgorithmList(); refreshTestList(); refreshScoreList(); } private void setAlgorithmDescription() { AlgorithmModel model = this.algorithmList.getSelectedValue(); if (model == null) { this.algoDescTextArea.setText(""); } else { this.algoDescTextArea.setText(model.getDescription()); this.algoDescTextArea.setCaretPosition(0); } } private void setScoreDescription() { ScoreModel model = this.scoreComboBox.getItemAt(this.scoreComboBox.getSelectedIndex()); if (model == null) { this.scoreDescTextArea.setText(""); } else { this.scoreDescTextArea.setText(model.getDescription()); this.scoreDescTextArea.setCaretPosition(0); } } private void setIndepTestDescription() { IndependenceTestModel model = this.indTestComboBox.getItemAt(this.indTestComboBox.getSelectedIndex()); if (model == null) { this.testDescTextArea.setText(""); } else { this.testDescTextArea.setText(model.getDescription()); this.testDescTextArea.setCaretPosition(0); } } private static class DescriptionPanel extends JPanel { @Serial private static final long serialVersionUID = 2329356999486712496L; final String borderTitle; final Component view; public DescriptionPanel(String borderTitle, Component view) { this.borderTitle = borderTitle; this.view = view; initComponents(); } private void initComponents() { JScrollPane scrollPane = new JScrollPane(this.view); setBorder(BorderFactory.createTitledBorder(this.borderTitle)); setPreferredSize(new Dimension(235, 150)); GroupLayout layout = new GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 366, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 254, Short.MAX_VALUE) .addContainerGap()) ); } } private class AlgorithmListPanel extends JPanel { @Serial private static final long serialVersionUID = -7068543172769683902L; public AlgorithmListPanel() { this.initComponents(); } private void initComponents() { JScrollPane scrollPane = new JScrollPane(algorithmList); this.setBorder(BorderFactory.createTitledBorder("Choose Algorithm")); GroupLayout layout = new GroupLayout(this); setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 206, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 254, Short.MAX_VALUE) .addContainerGap()) ); } } private class AlgorithmFilterPanel extends JPanel { @Serial private static final long serialVersionUID = -3120503093689632462L; public AlgorithmFilterPanel() { this.populateAlgoTypeOptions(); this.initComponents(); } private void initComponents() { // Filter based on algo types dropdown Box algoTypesBox = Box.createVerticalBox(); // Algo types label box Box algTypesBoxLabelBox = Box.createHorizontalBox(); algTypesBoxLabelBox.add(new JLabel("Show algorithms that: ")); algTypesBoxLabelBox.setAlignmentX(Component.LEFT_ALIGNMENT); // Add label to containing box algoTypesBox.add(algTypesBoxLabelBox); // All option Box algoTypeOptionAllBox = Box.createHorizontalBox(); algoTypeOptionAllBox.setAlignmentX(Component.LEFT_ALIGNMENT); // Add all option to containing box algoTypesBox.add(algoTypeOptionAllBox); // add radio buttons to panel if (!algoTypeOpts.isEmpty()) { Dimension indentSize = new Dimension(10, 20); algoTypeOpts.forEach(btn -> { Box box = Box.createHorizontalBox(); box.setAlignmentX(Component.LEFT_ALIGNMENT); box.add(Box.createRigidArea(indentSize)); box.add(btn); algoTypesBox.add(box); }); } // Is there a prior knowledge file? Box priorKnowledgeBox = Box.createVerticalBox(); // Add label into this label box to size Box priorKnowledgeLabelBox = Box.createHorizontalBox(); priorKnowledgeLabelBox.add(new JLabel("Show only: ")); priorKnowledgeLabelBox.setAlignmentX(Component.LEFT_ALIGNMENT); // Checkbox container Box priorKnowledgeOptionBox = Box.createHorizontalBox(); priorKnowledgeOptionBox.setAlignmentX(Component.LEFT_ALIGNMENT); // Add padding and option priorKnowledgeOptionBox.add(Box.createRigidArea(new Dimension(10, 20))); priorKnowledgeOptionBox.add(knowledgeChkBox); // Add to containg box priorKnowledgeBox.add(priorKnowledgeLabelBox); priorKnowledgeBox.add(priorKnowledgeOptionBox); Box algoFiltersBox = Box.createVerticalBox(); algoFiltersBox.setAlignmentX(Component.LEFT_ALIGNMENT); algoFiltersBox.add(algoTypesBox); algoFiltersBox.add(Box.createVerticalStrut(10)); algoFiltersBox.add(priorKnowledgeBox); this.setLayout(new BorderLayout()); this.setBorder(BorderFactory.createTitledBorder("Algorithm Filters")); this.add(new PaddingPanel(algoFiltersBox), BorderLayout.CENTER); } /** * Create new radio buttons and add them to both the radio button list and radio button group. */ private void populateAlgoTypeOptions() { JRadioButton showAllRadBtn = new JRadioButton("show all"); showAllRadBtn.setActionCommand("all"); showAllRadBtn.addActionListener(e -> { AlgorithmCard.this.refreshAlgorithmList(); }); algoTypeOpts.add(showAllRadBtn); algoFilterBtnGrp.add(showAllRadBtn); Arrays.stream(AlgType.values()).forEach(item -> { String name = item.name(); JRadioButton radioButton = new JRadioButton(name.replace("_", " ")); radioButton.setActionCommand(name); radioButton.addActionListener(e -> { AlgorithmCard.this.refreshAlgorithmList(); }); algoTypeOpts.add(radioButton); algoFilterBtnGrp.add(radioButton); }); } } private class TestAndScorePanel extends JPanel { @Serial private static final long serialVersionUID = -1594897454478052884L; public TestAndScorePanel() { this.initComponents(); } private void initComponents() { linearGaussianRadBtn.setActionCommand("linear-gaussian"); mixedRadBtn.setActionCommand("mixed"); generalRadBtn.setActionCommand("general"); allRadBtn.setActionCommand("all"); datasetFilterBtnGrp.add(linearGaussianRadBtn); datasetFilterBtnGrp.add(mixedRadBtn); datasetFilterBtnGrp.add(generalRadBtn); datasetFilterBtnGrp.add(allRadBtn); datasetFilterBtnGrp.setSelected(allRadBtn.getModel(), true); JLabel assumptionsLabel = new JLabel(); JLabel testLabel = new JLabel(); JLabel scoreLabel = new JLabel(); this.setBorder(BorderFactory.createTitledBorder("Choose Statistical Test and Score")); assumptionsLabel.setText("Filter by dataset properties:"); testLabel.setText("Test:"); scoreLabel.setText("Score:"); if (algorithmRunner.hasMissingValues()) { JLabel missingValueAlert = new JLabel(); JLabel testwiseDeletionAlert = new JLabel(); Color red = new Color(255, 0, 0); missingValueAlert.setForeground(red); missingValueAlert.setText("Dataset contains missing values;"); testwiseDeletionAlert.setForeground(red); testwiseDeletionAlert.setText("testwise deletion will be used."); GroupLayout layout = new GroupLayout(this); setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(testLabel) .addComponent(scoreLabel)) // .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addComponent(indTestComboBox, 0, 239, Short.MAX_VALUE) .addComponent(scoreComboBox, 0, 239, Short.MAX_VALUE))) .addComponent(assumptionsLabel) .addGroup(layout.createSequentialGroup() // .addGap(6, 6, 6) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(mixedRadBtn) .addComponent(linearGaussianRadBtn) .addComponent(generalRadBtn) .addComponent(allRadBtn))) .addComponent(missingValueAlert) .addComponent(testwiseDeletionAlert)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(assumptionsLabel) // .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(linearGaussianRadBtn) // .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(mixedRadBtn) // .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(generalRadBtn) // .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(allRadBtn) .addPreferredGap(ComponentPlacement.UNRELATED) .addComponent(missingValueAlert) .addPreferredGap(ComponentPlacement.RELATED) .addComponent(testwiseDeletionAlert) .addPreferredGap(ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(testLabel) .addComponent(indTestComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(scoreComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(scoreLabel)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); } else { GroupLayout layout = new GroupLayout(this); setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(testLabel) .addComponent(scoreLabel)) .addPreferredGap(ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addComponent(indTestComboBox, 0, 239, Short.MAX_VALUE) .addComponent(scoreComboBox, 0, 239, Short.MAX_VALUE))) .addComponent(assumptionsLabel) .addGroup(layout.createSequentialGroup() .addGap(6, 6, 6) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(mixedRadBtn) .addComponent(linearGaussianRadBtn) .addComponent(generalRadBtn) .addComponent(allRadBtn)))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(assumptionsLabel) // .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(linearGaussianRadBtn) // .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(mixedRadBtn) // .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(generalRadBtn) // .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(allRadBtn) .addGap(18, 18, 18) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(testLabel) .addComponent(indTestComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(AlgorithmCard.this.scoreComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(scoreLabel)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy