org.drugis.addis.gui.ConvergenceSummaryDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.drugis.addis.gui.ConvergenceSummaryDialog.java

Source

/*
 * This file is part of ADDIS (Aggregate Data Drug Information System).
 * ADDIS is distributed from http://drugis.org/.
 * Copyright (C) 2009 Gert van Valkenhoef, Tommi Tervonen.
 * Copyright (C) 2010 Gert van Valkenhoef, Tommi Tervonen, 
 * Tijs Zwinkels, Maarten Jacobs, Hanno Koeslag, Florin Schimbinschi, 
 * Ahmad Kamal, Daniel Reid.
 * Copyright (C) 2011 Gert van Valkenhoef, Ahmad Kamal, 
 * Daniel Reid, Florin Schimbinschi.
 * Copyright (C) 2012 Gert van Valkenhoef, Daniel Reid, 
 * Jol Kuiper, Wouter Reckman.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.drugis.addis.gui;

import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DecimalFormat;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

import org.drugis.addis.entities.mtcwrapper.MCMCModelWrapper;
import org.drugis.addis.gui.components.EnhancedTable;
import org.drugis.addis.gui.components.TablePanel;
import org.drugis.addis.presentation.ConvergenceDiagnosticTableModel;
import org.drugis.addis.presentation.ValueHolder;
import org.drugis.common.gui.LayoutUtil;
import org.drugis.mtc.MCMCSettings;
import org.drugis.mtc.Parameter;

import com.jgoodies.binding.PresentationModel;
import com.jgoodies.binding.adapter.BasicComponentFactory;
import com.jgoodies.binding.value.ValueModel;
import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

public class ConvergenceSummaryDialog extends JDialog {

    private static final String CONVERGENCE_TEXT = "<p>Convergence is assessed using the Brooks-Gelman-Rubin method. "
            + "This method compares within-chain and between-chain variance to calculate the <em>Potential Scale Reduction Factor</em> "
            + "(PSRF). A PSRF close to one indicates approximate convergence has been reached. See S.P. Brooks and A. Gelman (1998), "
            + "<em>General methods for monitoring convergence of iterative simulations</em>, Journal of Computational and Graphical "
            + "Statistics, 7(4): 434-455. <a href=\"http://www.jstor.org/stable/1390675\">JSTOR 1390675</a>."
            + "</p><p>Double click a parameter in the table below to see the convergence plots.</p>";

    private static final long serialVersionUID = -220027860371330394L;
    private final JFrame d_mainWindow;
    private final MCMCModelWrapper d_wrapper;
    private final ValueHolder<Boolean> d_modelConstructed;
    private ConvergenceDiagnosticTableModel d_tableModel;
    private MCMCSettings d_settings;

    private JPanel d_settingsPanel;

    public ConvergenceSummaryDialog(final JFrame main, final MCMCModelWrapper wrapper,
            final ValueHolder<Boolean> modelConstructed, String name) {
        d_mainWindow = main;
        d_wrapper = wrapper;
        d_modelConstructed = modelConstructed;
        d_settings = d_wrapper.getSettings();
        setPreferredSize(new Dimension(d_mainWindow.getWidth() / 6 * 4, d_mainWindow.getHeight() / 8 * 5));
        setMinimumSize(new Dimension(d_mainWindow.getWidth() / 6 * 4, d_mainWindow.getHeight() / 8 * 5));
        setLocationRelativeTo(d_mainWindow);
        setLocationByPlatform(true);
        setTitle(name);
        pack();
        d_tableModel = convergenceTable(wrapper, modelConstructed);
        final JPanel panel = createPanel();
        add(panel);

    }

    private JPanel createPanel() {
        final FormLayout layout = new FormLayout("pref, 3dlu, fill:0:grow", "pref, 3dlu, pref");
        final PanelBuilder builder = new PanelBuilder(layout, new JPanel());
        builder.setDefaultDialogBorder();
        CellConstraints cc = new CellConstraints();

        builder.add(buildConvergenceTable(d_wrapper, d_modelConstructed),
                cc.xy(1, 1, CellConstraints.DEFAULT, CellConstraints.TOP));
        builder.add(AuxComponentFactory.createHtmlField(CONVERGENCE_TEXT), cc.xy(3, 1));
        d_settingsPanel = buildMCMCSettingsPanel();
        builder.add(d_settingsPanel, cc.xyw(1, 3, 3));

        final JPanel panel = builder.getPanel();

        d_tableModel.addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent e) {
                panel.validate();
            }
        });
        return panel;
    }

    private JPanel buildMCMCSettingsPanel() {
        final FormLayout layout = new FormLayout("pref, 7dlu, fill:0:grow", "pref");
        int rows = 1;
        final PanelBuilder builder = new PanelBuilder(layout, new JPanel());
        builder.setDefaultDialogBorder();
        CellConstraints cc = new CellConstraints();

        PresentationModel<MCMCSettings> pm = new PresentationModel<MCMCSettings>(d_settings);
        rows = buildSettingsRow(layout, rows, builder, cc, "Number of chains",
                pm.getModel(MCMCSettings.PROPERTY_NUMBER_OF_CHAINS));
        rows = buildSettingsRow(layout, rows, builder, cc, "Tuning iterations",
                pm.getModel(MCMCSettings.PROPERTY_TUNING_ITERATIONS));
        rows = buildSettingsRow(layout, rows, builder, cc, "Simulation iterations",
                pm.getModel(MCMCSettings.PROPERTY_SIMULATION_ITERATIONS));
        rows = buildSettingsRow(layout, rows, builder, cc, "Thinning interval",
                pm.getModel(MCMCSettings.PROPERTY_THINNING_INTERVAL));
        rows = buildSettingsRow(layout, rows, builder, cc, "Inference samples",
                pm.getModel(MCMCSettings.PROPERTY_INFERENCE_SAMPLES));
        rows = buildSettingsRow(layout, rows, builder, cc, "Variance scaling factor",
                pm.getModel(MCMCSettings.PROPERTY_VARIANCE_SCALING_FACTOR));

        return builder.getPanel();
    }

    private int buildSettingsRow(final FormLayout layout, int rows, final PanelBuilder builder, CellConstraints cc,
            String label, ValueModel model) {
        rows = LayoutUtil.addRow(layout, rows);
        builder.add(new JLabel(label), cc.xy(1, rows));
        builder.add(new JLabel(":"), cc.xy(2, rows));
        builder.add(BasicComponentFactory.createLabel(model, new DecimalFormat()), cc.xy(3, rows));
        return rows;
    }

    private TablePanel buildConvergenceTable(final MCMCModelWrapper wrapper,
            ValueHolder<Boolean> modelConstructed) {
        ConvergenceDiagnosticTableModel tableModel = convergenceTable(wrapper, modelConstructed);
        EnhancedTable convergenceTable = EnhancedTable.createBare(tableModel);

        TablePanel pane = new TablePanel(convergenceTable);
        convergenceTable.autoSizeColumns();

        convergenceTable.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() > 1) {
                    JTable table = (JTable) e.getComponent();
                    int row = table.convertRowIndexToModel(table.rowAtPoint(e.getPoint()));
                    Parameter[] parameters = wrapper.getParameters();
                    if (row <= parameters.length) {
                        Parameter p = parameters[row];
                        showConvergencePlots(wrapper, p);
                    }
                }
            }
        });
        return pane;
    }

    private ConvergenceDiagnosticTableModel convergenceTable(final MCMCModelWrapper wrapper,
            ValueHolder<Boolean> modelConstructed) {
        return (d_tableModel == null) ? new ConvergenceDiagnosticTableModel(wrapper, modelConstructed)
                : d_tableModel;
    }

    private void showConvergencePlots(MCMCModelWrapper wrapper, Parameter p) {
        if (!wrapper.isSaved() && wrapper.getModel().getResults().getNumberOfSamples() > 0) {
            JDialog dialog = new ConvergencePlotsDialog(d_mainWindow, d_settings, wrapper.getModel(), p);
            dialog.setPreferredSize(
                    new Dimension(d_mainWindow.getWidth() / 5 * 4, d_mainWindow.getHeight() / 5 * 4));
            dialog.setMinimumSize(new Dimension(d_mainWindow.getMinimumSize().width - 100,
                    d_mainWindow.getMinimumSize().height - 100));
            dialog.setModal(true);
            dialog.setLocationRelativeTo(d_mainWindow);
            dialog.setLocationByPlatform(true);
            dialog.pack();
            dialog.setVisible(true);
        } else {
            JOptionPane.showMessageDialog(d_mainWindow,
                    "Convergence plots cannot be shown because the results of "
                            + "this analysis has been discarded to save memory.",
                    "No results available", JOptionPane.WARNING_MESSAGE);
        }
    }
}