org.drugis.addis.util.EmpiricalDensityDataset.java Source code

Java tutorial

Introduction

Here is the source code for org.drugis.addis.util.EmpiricalDensityDataset.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.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.math3.stat.descriptive.rank.Percentile;
import org.drugis.mtc.MCMCResults;
import org.drugis.mtc.MCMCResultsEvent;
import org.drugis.mtc.MCMCResultsListener;
import org.drugis.mtc.Parameter;
import org.drugis.mtc.summary.SummaryUtil;
import org.jfree.data.xy.AbstractXYDataset;

public class EmpiricalDensityDataset extends AbstractXYDataset {

    private static final long serialVersionUID = -9156379642630541775L;
    private static Percentile s_p = new Percentile();
    private int[][] d_counts;
    private double[][] d_densities;
    private double d_interval;
    private double d_bottom;
    private Parameter[] d_parameters;
    private final MCMCResults[] d_results;
    private final int d_nBins;
    private int d_nSeries;
    private double d_top;
    private MCMCResultsListener d_listener = new MCMCResultsListener() {
        public void resultsEvent(MCMCResultsEvent event) {
            calculate();
            fireDatasetChanged();
        }
    };

    public static class PlotParameter {
        public final MCMCResults results;
        public final Parameter parameter;

        public PlotParameter(MCMCResults r, Parameter p) {
            results = r;
            parameter = p;
        }
    }

    public EmpiricalDensityDataset(int nBins, PlotParameter... parameters) {
        d_nBins = nBins;
        d_nSeries = parameters.length;
        d_parameters = new Parameter[parameters.length];
        d_results = new MCMCResults[parameters.length];
        d_densities = new double[d_nSeries][d_nBins];

        Set<MCMCResults> unique = new HashSet<MCMCResults>();
        for (int i = 0; i < parameters.length; ++i) {
            d_parameters[i] = parameters[i].parameter;
            d_results[i] = parameters[i].results;
            unique.add(d_results[i]);
        }
        for (MCMCResults r : unique) {
            r.addResultsListener(d_listener);
        }
        calculate();
    }

    public EmpiricalDensityDataset(int nBins, MCMCResults r, Parameter p) {
        this(nBins, new PlotParameter(r, p));
    }

    private void calculate() {
        List<Integer> paramIndex = new ArrayList<Integer>();

        for (int i = 0; i < d_nSeries; ++i) {
            if (d_results[i].getNumberOfSamples() > 0) {
                paramIndex.add(i);
            }
        }

        if (paramIndex.isEmpty())
            return; // no samples available

        calcBounds(paramIndex);
        calcDensities(paramIndex);
    }

    private void calcBounds(List<Integer> paramIndex) {
        double[] samples = getSamplesArray(paramIndex.get(0));
        d_bottom = s_p.evaluate(samples, 2.5);
        d_top = s_p.evaluate(samples, 97.5);
        for (int j : paramIndex.subList(1, paramIndex.size())) {
            samples = getSamplesArray(j);
            d_bottom = Math.min(s_p.evaluate(samples, 2.5), d_bottom);
            d_top = Math.max(s_p.evaluate(samples, 97.5), d_top);
        }

        d_interval = (d_top - d_bottom) / d_nBins;
    }

    private void calcDensities(List<Integer> paramIndex) {
        d_counts = new int[d_nSeries][d_nBins];
        for (int j : paramIndex) {
            List<Double> samples = getSamples(j);
            double factor = samples.size() * d_interval;
            for (int i = 0; i < samples.size(); ++i) {
                double sample = samples.get(i);
                if (sample >= d_bottom && sample < d_top) {
                    int idx = (int) ((sample - d_bottom) / d_interval);
                    ++d_counts[j][idx];
                }
            }
            for (int i = 0; i < d_nBins; ++i) {
                d_densities[j][i] = d_counts[j][i] / factor;
            }
        }
    }

    @Deprecated
    private double[] getSamplesArray(int j) { // FIXME: eliminate
        List<Double> list = getSamples(j);
        double[] arr = new double[list.size()];
        for (int i = 0; i < list.size(); ++i) {
            arr[i] = list.get(i);
        }
        Arrays.sort(arr);
        return arr;
    }

    private List<Double> getSamples(int j) {
        return SummaryUtil.getAllChainsLastHalfSamples(d_results[j], d_parameters[j]);
    }

    @Override
    public int getSeriesCount() {
        return d_nSeries;
    }

    @Override
    public Comparable<String> getSeriesKey(int series) {
        return d_parameters[series].getName();
    }

    public Double getX(int series, int bin) {
        if (series < 0 || series >= d_nSeries)
            throw new IndexOutOfBoundsException();
        return (0.5 + bin) * d_interval + d_bottom;
    }

    public Double getY(int series, int bin) {
        return d_densities[series][bin];
    }

    public int[] getCounts(int series) {
        return d_counts[series];
    }

    public double[] getDensities(int series) {
        return d_densities[series];
    }

    public int getItemCount(int series) {
        return d_nBins;
    }

    double getLowerBound() {
        return d_bottom;
    }

    double getUpperBound() {
        return d_top;
    }
}