/* * This file is part of ADDIS (Aggregate Data Drug Information System). * ADDIS is distributed from http://drugis.org/. * Copyright © 2009 Gert van Valkenhoef, Tommi Tervonen. * Copyright © 2010 Gert van Valkenhoef, Tommi Tervonen, Tijs Zwinkels, * Maarten Jacobs, Hanno Koeslag, Florin Schimbinschi, Ahmad Kamal, Daniel * Reid. * Copyright © 2011 Gert van Valkenhoef, Ahmad Kamal, Daniel Reid, Florin * Schimbinschi. * Copyright © 2012 Gert van Valkenhoef, Daniel Reid, Joël Kuiper, Wouter * Reckman. * Copyright © 2013 Gert van Valkenhoef, Joël Kuiper. * * 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.entities.analysis; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import org.drugis.addis.ADDISTestUtil; import org.drugis.addis.ExampleData; import org.drugis.addis.entities.Arm; import org.drugis.addis.entities.DoseUnit; import org.drugis.addis.entities.Entity; import org.drugis.addis.entities.FixedDose; import org.drugis.addis.entities.Indication; import org.drugis.addis.entities.Measurement; import org.drugis.addis.entities.Study; import org.drugis.addis.entities.StudyArmsEntry; import org.drugis.addis.entities.relativeeffect.BasicMeanDifference; import org.drugis.addis.entities.relativeeffect.BasicOddsRatio; import org.drugis.addis.entities.relativeeffect.BasicRiskRatio; import org.drugis.addis.entities.relativeeffect.RandomEffectMetaAnalysisRelativeEffect; import org.drugis.addis.entities.relativeeffect.RelativeEffect; import org.drugis.addis.entities.relativeeffect.RelativeEffectFactory; import org.drugis.addis.entities.relativeeffect.RelativeEffectTestBase; import org.drugis.addis.entities.treatment.Category; import org.drugis.addis.entities.treatment.DecisionTree; import org.drugis.addis.entities.treatment.LeafNode; import org.drugis.addis.entities.treatment.TreatmentCategorization; import org.drugis.addis.entities.treatment.TreatmentDefinition; import org.drugis.common.JUnitUtil; import org.junit.Before; import org.junit.Test; public class RandomEffectsMetaAnalysisTest extends RelativeEffectTestBase { /* * Test data from Figure 2 in "Efficacy and Safety of Second-Generation * Antidepressants in the Treatment of Major Depressive Disorder" * by Hansen et al. 2005 * */ RandomEffectsMetaAnalysis d_rema; private List<Study> d_studyList; @Before public void setUp() { d_studyList = new ArrayList<Study>(); d_studyList.add(d_bennie); d_studyList.add(d_boyer); d_studyList.add(d_fava); d_studyList.add(d_newhouse); d_studyList.add(d_sechter); d_rema = ExampleData.buildRandomEffectsMetaAnalysis("meta", d_rateEndpoint, d_studyList, TreatmentDefinition.createTrivial(d_fluox), TreatmentDefinition.createTrivial(d_sertr)); } @Test public void testGetStudyArms() { List<StudyArmsEntry> entries = d_rema.getStudyArms(); assertEquals(d_studyList.size(), entries.size()); for (int i = 0; i < d_studyList.size(); ++i) { StudyArmsEntry studyArmsEntry = entries.get(i); assertEquals(d_studyList.get(i), studyArmsEntry.getStudy()); assertEquals(TreatmentDefinition.createTrivial(d_fluox), studyArmsEntry.getStudy().getTreatmentDefinition(studyArmsEntry.getBase())); assertEquals(TreatmentDefinition.createTrivial(d_sertr), studyArmsEntry.getStudy().getTreatmentDefinition(studyArmsEntry.getSubject())); assertTrue(d_studyList.get(i).getArms().contains(studyArmsEntry.getBase())); assertTrue(d_studyList.get(i).getArms().contains(studyArmsEntry.getSubject())); } } @Test(expected=IllegalArgumentException.class) public void testDifferentIndicationsThrows() { Indication newInd = new Indication(666L, "bad"); Study newStudy = ExampleData.buildRateStudy("name", 0, 10, 0, 20); newStudy.setIndication(newInd); d_studyList.add(newStudy); d_rema = ExampleData.buildRandomEffectsMetaAnalysis("meta", d_rateEndpoint, d_studyList, TreatmentDefinition.createTrivial(d_fluox), TreatmentDefinition.createTrivial(d_sertr)); } @Test(expected=IllegalArgumentException.class) public void testDifferentDrugs() { Indication newInd = new Indication(666L, "bad"); Study newStudy = ExampleData.buildRateStudy("name", 0, 10, 0, 20); newStudy.setIndication(newInd); List<StudyArmsEntry> armsList = new ArrayList<StudyArmsEntry>(); Arm subject = newStudy.getArms().get(1); Arm base = newStudy.getArms().get(0); armsList.add(new StudyArmsEntry(newStudy, base, subject)); armsList.add(new StudyArmsEntry(newStudy, subject, base)); d_rema = new RandomEffectsMetaAnalysis("meta", d_rateEndpoint, newStudy.getTreatmentDefinition(base), newStudy.getTreatmentDefinition(subject), armsList, false); } @Test public void testCategoryMatching() { TreatmentCategorization catz = TreatmentCategorization.createDefault("Include Fixed Dose", d_fluox, DoseUnit.createMilliGramsPerDay()); Category fluoxCat = new Category(catz, "Include"); catz.addCategory(fluoxCat); DecisionTree tree = catz.getDecisionTree(); tree.replaceChild(tree.findMatchingEdge(tree.getRoot(), FixedDose.class), new LeafNode(fluoxCat)); Category sertrCat = Category.createTrivial(d_sertr); List<StudyArmsEntry> entries = ExampleData.buildStudyArmEntries(d_studyList, TreatmentDefinition.createTrivial(d_fluox), TreatmentDefinition.createTrivial(d_sertr)); // The following should *not* throw an IllegalArgumentException new RandomEffectsMetaAnalysis("meta", d_rateEndpoint, new TreatmentDefinition(fluoxCat), new TreatmentDefinition(sertrCat), entries, false); } @Test public void testGetToString() { assertEquals(d_rema.getName(), d_rema.toString()); } @Test public void testGetSampleSize() { assertEquals(144+142+120+122+92+96+119+117+120+118, d_rema.getSampleSize()); } @Test public void testGetFirstDrug() { assertEquals(TreatmentDefinition.createTrivial(d_fluox), d_rema.getFirstAlternative()); } @Test public void testGetSecondDrug() { assertEquals(TreatmentDefinition.createTrivial(d_sertr), d_rema.getSecondAlternative()); } @Test public void testIncludedDrugs() { assertEquals(Arrays.asList(new TreatmentDefinition [] {TreatmentDefinition.createTrivial(d_fluox), TreatmentDefinition.createTrivial(d_sertr)}), d_rema.getAlternatives()); } @Test public void testGetStudies() { assertEquals(d_studyList, d_rema.getIncludedStudies()); } @Test public void testGetName() { JUnitUtil.testSetter(d_rema, RandomEffectsMetaAnalysis.PROPERTY_NAME, "meta", "newname"); } @Test public void testGetEndpoint() { assertEquals(d_rateEndpoint, d_rema.getOutcomeMeasure()); } @Test public void testGetIndication() { assertEquals(d_ind, d_rema.getIndication()); } public double calculateI2(double hetr, int k) { return Math.max(0, 100 * ((hetr-(k-1)) / hetr )); } @Test public void testGetRiskRatioRelativeEffect() { RandomEffectMetaAnalysisRelativeEffect<Measurement> riskRatio = d_rema.getRelativeEffect(BasicRiskRatio.class); assertEquals(2.03, riskRatio.getHeterogeneity(), 0.01); assertEquals(calculateI2(2.03,d_rema.getIncludedStudies().size()), riskRatio.getHeterogeneityI2(), 0.01); assertEquals(1.10, (riskRatio.getConfidenceInterval().getPointEstimate()), 0.01); assertEquals(1.01, (riskRatio.getConfidenceInterval().getLowerBound()), 0.01); assertEquals(1.20, (riskRatio.getConfidenceInterval().getUpperBound()), 0.01); } @Test public void testGetOddsRatioRelativeEffect() { RandomEffectMetaAnalysisRelativeEffect<Measurement> oddsRatio = d_rema.getRelativeEffect(BasicOddsRatio.class); assertEquals(2.14, oddsRatio.getHeterogeneity(), 0.01); assertEquals(1.30, (oddsRatio.getConfidenceInterval().getPointEstimate()), 0.01); assertEquals(1.03, (oddsRatio.getConfidenceInterval().getLowerBound()), 0.01); assertEquals(1.65, (oddsRatio.getConfidenceInterval().getUpperBound()), 0.01); } @Test public void testContinuousMetaAnalysis() { Study s1 = ExampleData.buildContinuousStudy("s1", 50, 4, 2, 50, 6, 2); Study s2 = ExampleData.buildContinuousStudy("s2", 50, 4, 2, 50, 7, 2); List<Study> studies = new ArrayList<Study>(); studies.add(s1); studies.add(s2); RandomEffectsMetaAnalysis ma = ExampleData.buildRandomEffectsMetaAnalysis("meta", d_contEndpoint, studies, TreatmentDefinition.createTrivial(d_fluox), TreatmentDefinition.createTrivial(d_sertr)); RandomEffectMetaAnalysisRelativeEffect<Measurement> relativeEffect = ma.getRelativeEffect(BasicMeanDifference.class); assertEquals(2.5, relativeEffect.getConfidenceInterval().getPointEstimate(), 0.01); } @Test public void testGetDependencies() { HashSet<Entity> deps = new HashSet<Entity>(); deps.add(d_fluox); deps.add(d_sertr); deps.add(DoseUnit.createMilliGramsPerDay().getUnit()); deps.add(d_ind); deps.add(d_rateEndpoint); deps.addAll(Arrays.asList(new Study[]{d_bennie, d_boyer, d_fava, d_newhouse, d_sechter})); assertEquals(deps, d_rema.getDependencies()); } @Test public void testFilterUndefinedRelativeEffects() { List<RelativeEffect<? extends Measurement>> expected = d_rema.getFilteredRelativeEffects(BasicOddsRatio.class); Study zeroRate = ExampleData.buildRateStudy("ZeroRate 2012", 0, 120, 86, 118); d_studyList.add(zeroRate); RandomEffectsMetaAnalysis rema = ExampleData.buildRandomEffectsMetaAnalysis("meta", d_rateEndpoint, d_studyList, TreatmentDefinition.createTrivial(d_fluox), TreatmentDefinition.createTrivial(d_sertr)); List<RelativeEffect<? extends Measurement>> actual = rema.getFilteredRelativeEffects(BasicOddsRatio.class); assertFalse(RelativeEffectFactory.buildRelativeEffect(zeroRate, d_rateEndpoint, TreatmentDefinition.createTrivial(d_fluox), TreatmentDefinition.createTrivial(d_sertr), BasicOddsRatio.class, false).isDefined()); ADDISTestUtil.assertRelativeEffectListEquals(expected, actual); } @Test public void testPooledIsNullWhenAllUndefined() { Study zeroRate = ExampleData.buildRateStudy("ZeroRate 2012", 0, 120, 86, 118); RandomEffectsMetaAnalysis rema = ExampleData.buildRandomEffectsMetaAnalysis("meta", d_rateEndpoint, Collections.singletonList(zeroRate), TreatmentDefinition.createTrivial(d_fluox), TreatmentDefinition.createTrivial(d_sertr)); assertNull(rema.getRelativeEffect(BasicOddsRatio.class)); } }