package de.randi2.core.unit.randomization;
import static de.randi2.core.unit.randomization.RandomizationHelper.randomize;
import static de.randi2.utility.IntegerIterator.upto;
import static org.junit.Assert.assertEquals;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import de.randi2.model.SubjectProperty;
import de.randi2.model.TreatmentArm;
import de.randi2.model.Trial;
import de.randi2.model.TrialSubject;
import de.randi2.model.criteria.DichotomousCriterion;
import de.randi2.model.criteria.OrdinalCriterion;
import de.randi2.model.criteria.constraints.DichotomousConstraint;
import de.randi2.model.criteria.constraints.OrdinalConstraint;
import de.randi2.model.randomization.MinimizationConfig;
import de.randi2.model.randomization.MinimizationMapElementWrapper;
import de.randi2.randomization.Minimization;
import de.randi2.simulation.distribution.UniformDistribution;
import de.randi2.simulation.model.DistributionSubjectProperty;
import de.randi2.unsorted.ConstraintViolatedException;
public class MinimizationTest {
private Trial trial;
private MinimizationConfig conf;
private int id = 0;
private int nextId() {
return id++;
}
@Before
public void setUp() {
trial = new Trial();
}
@Test
@SuppressWarnings("unused")
public void testNaiveMinimization() {
RandomizationHelper.addArms(trial, 70, 50, 30);
conf = new MinimizationConfig();
conf.setWithRandomizedSubjects(false);
conf.setBiasedCoinMinimization(false);
conf.setP(0.95);
trial.setRandomizationConfiguration(conf);
for (int i : upto(150)) {
randomize(trial, new TrialSubject());
}
assertEquals(150, trial.getSubjects().size());
}
@Test
@SuppressWarnings("unused")
public void testNaiveMinimizationWithRandomizedSubjects() {
RandomizationHelper.addArms(trial, 70, 50, 30);
conf = new MinimizationConfig();
conf.setWithRandomizedSubjects(true);
conf.setBiasedCoinMinimization(false);
conf.setP(0.9);
trial.setRandomizationConfiguration(conf);
for (int i : upto(150)) {
randomize(trial, new TrialSubject());
}
assertEquals(150, trial.getSubjects().size());
}
@Test
@SuppressWarnings("unused")
public void testNaiveMinimizationWithRandomizedSubjects_5_Treatments() {
RandomizationHelper.addArms(trial, 56, 23, 78, 47, 29);
conf = new MinimizationConfig();
conf.setWithRandomizedSubjects(true);
conf.setBiasedCoinMinimization(false);
conf.setP(0.95);
trial.setRandomizationConfiguration(conf);
for (int i : upto(233)) {
randomize(trial, new TrialSubject());
}
assertEquals(233, trial.getSubjects().size());
}
@Test
public void testBiasedCoinMinimization() {
ArrayList<String> allocationSequence = new ArrayList<String>(Arrays
.asList("dummy:3", "dummy:2", "dummy:3", "dummy:1", "dummy:3",
"dummy:1", "dummy:3", "dummy:3", "dummy:3", "dummy:3",
"dummy:2", "dummy:2", "dummy:1", "dummy:3", "dummy:2",
"dummy:2", "dummy:3", "dummy:2", "dummy:2", "dummy:2",
"dummy:1", "dummy:3", "dummy:1", "dummy:3", "dummy:3",
"dummy:2", "dummy:1", "dummy:3", "dummy:3", "dummy:2",
"dummy:2", "dummy:1", "dummy:1", "dummy:2", "dummy:2",
"dummy:3", "dummy:3", "dummy:2", "dummy:3", "dummy:3",
"dummy:3", "dummy:2", "dummy:3", "dummy:1", "dummy:2",
"dummy:3", "dummy:2", "dummy:3", "dummy:3", "dummy:3",
"dummy:2", "dummy:3", "dummy:3", "dummy:3", "dummy:3",
"dummy:3", "dummy:2", "dummy:3", "dummy:3", "dummy:3"));
RandomizationHelper.addArms(trial, 10, 20, 30);
trial.setId(nextId());
List<TreatmentArm> arms = new ArrayList<TreatmentArm>(trial.getTreatmentArms());
Collections.sort(arms, new TreatmentArmIdComparator());
ArrayList<DistributionSubjectProperty> dProperties = new ArrayList<DistributionSubjectProperty>();
DichotomousCriterion cr1 = new DichotomousCriterion();
cr1.setName("SEX");
cr1.setOption1("M");
cr1.setOption2("F");
cr1.setId(nextId());
OrdinalCriterion cr2 = new OrdinalCriterion();
List<String> elements = new ArrayList<String>();
elements.add("1");
elements.add("2");
elements.add("3");
elements.add("4");
elements.add("5");
cr2.setElements(elements);
cr2.setName("TrialSite");
cr2.setId(nextId());
try {
cr1.addStrata(new DichotomousConstraint(Arrays
.asList(new String[] { "M" })));
cr1.addStrata(new DichotomousConstraint(Arrays
.asList(new String[] { "F" })));
cr2.addStrata(new OrdinalConstraint(Arrays
.asList(new String[] { "1" })));
cr2.addStrata(new OrdinalConstraint(Arrays
.asList(new String[] { "2" })));
cr2.addStrata(new OrdinalConstraint(Arrays
.asList(new String[] { "3" })));
cr2.addStrata(new OrdinalConstraint(Arrays
.asList(new String[] { "4" })));
cr2.addStrata(new OrdinalConstraint(Arrays
.asList(new String[] { "5" })));
for (DichotomousConstraint cc : cr1.getStrata())
cc.setId(nextId());
for (OrdinalConstraint cc : cr2.getStrata())
cc.setId(nextId());
dProperties.add(new DistributionSubjectProperty(cr1,
new UniformDistribution<String>(cr1.getConfiguredValues(),
1)));
dProperties.add(new DistributionSubjectProperty(cr2,
new UniformDistribution<String>(cr2.getConfiguredValues(),
1)));
} catch (ConstraintViolatedException e) {
e.printStackTrace();
}
trial.addCriterion(cr1);
trial.addCriterion(cr2);
conf = new MinimizationConfig(1L);
conf.setWithRandomizedSubjects(false);
conf.setBiasedCoinMinimization(true);
conf.setP(0.70);
trial.setRandomizationConfiguration(conf);
//Test calculated probabilities
Map<TreatmentArm, MinimizationMapElementWrapper> internalCalculatedProbabilities = ((Minimization) conf.getAlgorithm()).getProbabilitiesPerPreferredTreatment();
Map<TreatmentArm, MinimizationMapElementWrapper> externelCalculatedProbabilies = new HashMap<TreatmentArm, MinimizationMapElementWrapper>();
Map<TreatmentArm, Double> calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.7);
calculatedProbabilies.put(arms.get(1), 0.12);
calculatedProbabilies.put(arms.get(2), 0.18);
externelCalculatedProbabilies.put(arms.get(0), new MinimizationMapElementWrapper(calculatedProbabilies));
calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.06);
calculatedProbabilies.put(arms.get(1), 0.76);
calculatedProbabilies.put(arms.get(2), 0.18);
externelCalculatedProbabilies.put(arms.get(1), new MinimizationMapElementWrapper(calculatedProbabilies));
calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.06);
calculatedProbabilies.put(arms.get(1), 0.12);
calculatedProbabilies.put(arms.get(2), 0.82);
externelCalculatedProbabilies.put(arms.get(2), new MinimizationMapElementWrapper(calculatedProbabilies));
testProbabilityMaps(externelCalculatedProbabilies,
internalCalculatedProbabilities);
//Test randomization sequence
for (int i : upto(60)) {
TrialSubject subject = new TrialSubject();
TreatmentArm assignedArm = conf.getAlgorithm()
.randomize(generateTrialSubject(dProperties, subject));
subject.setArm(assignedArm);
assignedArm.addSubject(subject);
assertEquals(allocationSequence.get(i), assignedArm.getName());
}
assertEquals(60, trial.getSubjects().size());
}
private static TrialSubject generateTrialSubject(
List<DistributionSubjectProperty> properties,
TrialSubject oldSubject) {
oldSubject.setProperties(null);
HashSet<SubjectProperty<?>> tempSet = new HashSet<SubjectProperty<?>>();
for (DistributionSubjectProperty dsp : properties) {
SubjectProperty<Serializable> pr = new SubjectProperty<Serializable>(
dsp.getCriterion());
try {
pr.setValue(dsp.getNextSubjectValue());
} catch (ConstraintViolatedException e) {
}
tempSet.add(pr);
}
oldSubject.setProperties(tempSet);
return oldSubject;
}
@Test
// Minimization_Prop_Table (1).pdf
public void testProbabilityInitBiasedCoin1() {
RandomizationHelper.addArms(trial, 10, 20, 30);
List<TreatmentArm> arms = new ArrayList<TreatmentArm>(trial.getTreatmentArms());;
Collections.sort(arms, new TreatmentArmIdComparator());
conf = new MinimizationConfig();
conf.setWithRandomizedSubjects(false);
conf.setBiasedCoinMinimization(true);
conf.setP(0.70);
trial.setRandomizationConfiguration(conf);
Minimization alg = (Minimization) conf.getAlgorithm();
Map<TreatmentArm, MinimizationMapElementWrapper> internalCalculatedProbabilities = alg
.getProbabilitiesPerPreferredTreatment();
Map<TreatmentArm, MinimizationMapElementWrapper> externelCalculatedProbabilies = new HashMap<TreatmentArm, MinimizationMapElementWrapper>();
Map<TreatmentArm, Double> calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.7);
calculatedProbabilies.put(arms.get(1), 0.12);
calculatedProbabilies.put(arms.get(2), 0.18);
externelCalculatedProbabilies.put(arms.get(0), new MinimizationMapElementWrapper(calculatedProbabilies));
calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.06);
calculatedProbabilies.put(arms.get(1), 0.76);
calculatedProbabilies.put(arms.get(2), 0.18);
externelCalculatedProbabilies.put(arms.get(1), new MinimizationMapElementWrapper(calculatedProbabilies));
calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.06);
calculatedProbabilies.put(arms.get(1), 0.12);
calculatedProbabilies.put(arms.get(2), 0.82);
externelCalculatedProbabilies.put(arms.get(2), new MinimizationMapElementWrapper(calculatedProbabilies));
testProbabilityMaps(externelCalculatedProbabilies,
internalCalculatedProbabilities);
}
@Test
// Minimization_Prop_Table (2).pdf
public void testProbabilityInitBiasedCoin2() {
RandomizationHelper.addArms(trial, 10, 20, 30);
List<TreatmentArm> arms = new ArrayList<TreatmentArm>(trial.getTreatmentArms());;
Collections.sort(arms, new TreatmentArmIdComparator());
conf = new MinimizationConfig();
conf.setWithRandomizedSubjects(false);
conf.setBiasedCoinMinimization(true);
conf.setP(0.80);
trial.setRandomizationConfiguration(conf);
Minimization alg = (Minimization) conf.getAlgorithm();
Map<TreatmentArm, MinimizationMapElementWrapper> internalCalculatedProbabilities = alg
.getProbabilitiesPerPreferredTreatment();
Map<TreatmentArm, MinimizationMapElementWrapper> externelCalculatedProbabilies = new HashMap<TreatmentArm, MinimizationMapElementWrapper>();
Map<TreatmentArm, Double> calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.8);
calculatedProbabilies.put(arms.get(1), 0.08);
calculatedProbabilies.put(arms.get(2), 0.12);
externelCalculatedProbabilies.put(arms.get(0), new MinimizationMapElementWrapper(calculatedProbabilies));
calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.04);
calculatedProbabilies.put(arms.get(1), 0.84);
calculatedProbabilies.put(arms.get(2), 0.12);
externelCalculatedProbabilies.put(arms.get(1), new MinimizationMapElementWrapper(calculatedProbabilies));
calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.04);
calculatedProbabilies.put(arms.get(1), 0.08);
calculatedProbabilies.put(arms.get(2), 0.88);
externelCalculatedProbabilies.put(arms.get(2), new MinimizationMapElementWrapper(calculatedProbabilies));
testProbabilityMaps(externelCalculatedProbabilies,
internalCalculatedProbabilities);
}
@Test
// Minimization_Prop_Table (3).pdf
public void testProbabilityInitBiasedCoin3() {
RandomizationHelper.addArms(trial, 10, 20, 30);
List<TreatmentArm> arms = new ArrayList<TreatmentArm>(trial.getTreatmentArms());;
Collections.sort(arms, new TreatmentArmIdComparator());
conf = new MinimizationConfig();
conf.setWithRandomizedSubjects(false);
conf.setBiasedCoinMinimization(true);
conf.setP(0.60);
trial.setRandomizationConfiguration(conf);
Minimization alg = (Minimization) conf.getAlgorithm();
Map<TreatmentArm, MinimizationMapElementWrapper> internalCalculatedProbabilities = alg
.getProbabilitiesPerPreferredTreatment();
Map<TreatmentArm, MinimizationMapElementWrapper> externelCalculatedProbabilies = new HashMap<TreatmentArm, MinimizationMapElementWrapper>();
Map<TreatmentArm, Double> calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.6);
calculatedProbabilies.put(arms.get(1), 0.16);
calculatedProbabilies.put(arms.get(2), 0.24);
externelCalculatedProbabilies.put(arms.get(0), new MinimizationMapElementWrapper(calculatedProbabilies));
calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.08);
calculatedProbabilies.put(arms.get(1), 0.68);
calculatedProbabilies.put(arms.get(2), 0.24);
externelCalculatedProbabilies.put(arms.get(1), new MinimizationMapElementWrapper(calculatedProbabilies));
calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.08);
calculatedProbabilies.put(arms.get(1), 0.16);
calculatedProbabilies.put(arms.get(2), 0.76);
externelCalculatedProbabilies.put(arms.get(2), new MinimizationMapElementWrapper(calculatedProbabilies));
testProbabilityMaps(externelCalculatedProbabilies,
internalCalculatedProbabilities);
}
@Test
// Minimization_Prop_Table (4).pdf
public void testProbabilityInitBiasedCoin4() {
RandomizationHelper.addArms(trial, 10, 10, 10);
List<TreatmentArm> arms = new ArrayList<TreatmentArm>(trial.getTreatmentArms());;
Collections.sort(arms, new TreatmentArmIdComparator());
conf = new MinimizationConfig();
conf.setWithRandomizedSubjects(false);
conf.setBiasedCoinMinimization(true);
conf.setP(0.60);
trial.setRandomizationConfiguration(conf);
Minimization alg = (Minimization) conf.getAlgorithm();
Map<TreatmentArm, MinimizationMapElementWrapper> internalCalculatedProbabilities = alg
.getProbabilitiesPerPreferredTreatment();
Map<TreatmentArm, MinimizationMapElementWrapper> externelCalculatedProbabilies = new HashMap<TreatmentArm,MinimizationMapElementWrapper>();
Map<TreatmentArm, Double> calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.6);
calculatedProbabilies.put(arms.get(1), 0.2);
calculatedProbabilies.put(arms.get(2), 0.2);
externelCalculatedProbabilies.put(arms.get(0), new MinimizationMapElementWrapper(calculatedProbabilies));
calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.2);
calculatedProbabilies.put(arms.get(1), 0.6);
calculatedProbabilies.put(arms.get(2), 0.2);
externelCalculatedProbabilies.put(arms.get(1), new MinimizationMapElementWrapper(calculatedProbabilies));
calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.2);
calculatedProbabilies.put(arms.get(1), 0.2);
calculatedProbabilies.put(arms.get(2), 0.6);
externelCalculatedProbabilies.put(arms.get(2), new MinimizationMapElementWrapper(calculatedProbabilies));
testProbabilityMaps(externelCalculatedProbabilies,
internalCalculatedProbabilities);
}
@Test
// Minimization_Prop_Table (5).pdf
public void testProbabilityInitBiasedCoin5() {
RandomizationHelper.addArms(trial, 1, 2, 2, 4);
List<TreatmentArm> arms = new ArrayList<TreatmentArm>(trial.getTreatmentArms());
Collections.sort(arms, new TreatmentArmIdComparator());
conf = new MinimizationConfig();
conf.setWithRandomizedSubjects(false);
conf.setBiasedCoinMinimization(true);
conf.setP(0.80);
trial.setRandomizationConfiguration(conf);
Minimization alg = (Minimization) conf.getAlgorithm();
Map<TreatmentArm, MinimizationMapElementWrapper> internalCalculatedProbabilities = alg
.getProbabilitiesPerPreferredTreatment();
Map<TreatmentArm,MinimizationMapElementWrapper> externelCalculatedProbabilies = new HashMap<TreatmentArm,MinimizationMapElementWrapper>();
Map<TreatmentArm, Double> calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.8);
calculatedProbabilies.put(arms.get(1), 0.05);
calculatedProbabilies.put(arms.get(2), 0.05);
calculatedProbabilies.put(arms.get(3), 0.1);
externelCalculatedProbabilies.put(arms.get(0), new MinimizationMapElementWrapper(calculatedProbabilies));
calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.025);
calculatedProbabilies.put(arms.get(1), 0.825);
calculatedProbabilies.put(arms.get(2), 0.05);
calculatedProbabilies.put(arms.get(3), 0.1);
externelCalculatedProbabilies.put(arms.get(1), new MinimizationMapElementWrapper(calculatedProbabilies));
calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.025);
calculatedProbabilies.put(arms.get(1), 0.05);
calculatedProbabilies.put(arms.get(2), 0.825);
calculatedProbabilies.put(arms.get(3), 0.1);
externelCalculatedProbabilies.put(arms.get(2), new MinimizationMapElementWrapper(calculatedProbabilies));
testProbabilityMaps(externelCalculatedProbabilies,
internalCalculatedProbabilities);
calculatedProbabilies = new HashMap<TreatmentArm, Double>();
calculatedProbabilies.put(arms.get(0), 0.025);
calculatedProbabilies.put(arms.get(1), 0.05);
calculatedProbabilies.put(arms.get(2), 0.05);
calculatedProbabilies.put(arms.get(3), 0.875);
externelCalculatedProbabilies.put(arms.get(3), new MinimizationMapElementWrapper(calculatedProbabilies));
testProbabilityMaps(externelCalculatedProbabilies,
internalCalculatedProbabilities);
}
@Test
public void testProbabilityInitBiasedCoinSum_1() {
RandomizationHelper.addArms(trial, 1, 2, 2, 4);
conf = new MinimizationConfig();
conf.setWithRandomizedSubjects(false);
conf.setBiasedCoinMinimization(true);
conf.setP(0.80);
trial.setRandomizationConfiguration(conf);
Minimization alg = (Minimization) conf.getAlgorithm();
Map<TreatmentArm, MinimizationMapElementWrapper> internalCalculatedProbabilities = alg
.getProbabilitiesPerPreferredTreatment();
testSumEquals1(internalCalculatedProbabilities);
}
private void testSumEquals1(
Map<TreatmentArm, MinimizationMapElementWrapper> internalCalculatedProbabilities) {
DecimalFormat df = new DecimalFormat("#0.0000000000");
for (TreatmentArm arm_pref : internalCalculatedProbabilities.keySet()) {
Map<TreatmentArm, Double> prob_calc = internalCalculatedProbabilities
.get(arm_pref).getMap();
double sum = 0.0;
for (TreatmentArm arm_act : prob_calc.keySet()) {
sum += internalCalculatedProbabilities.get(arm_pref).getMap().get(
arm_act);
}
assertEquals(df.format(1.0), df.format(sum));
}
}
private void testProbabilityMaps(
Map<TreatmentArm, MinimizationMapElementWrapper> externelCalculatedProbabilies,
Map<TreatmentArm,MinimizationMapElementWrapper> internalCalculatedProbabilities) {
DecimalFormat df = new DecimalFormat("#0.0000000000");
testSumEquals1(internalCalculatedProbabilities);
for (TreatmentArm arm_pref : externelCalculatedProbabilies.keySet()) {
Map<TreatmentArm, Double> prob_calc = externelCalculatedProbabilies
.get(arm_pref).getMap();
for (TreatmentArm arm_act : prob_calc.keySet()) {
assertEquals(df.format(externelCalculatedProbabilies.get(
arm_pref).getMap().get(arm_act)), df
.format(internalCalculatedProbabilities.get(arm_pref).getMap()
.get(arm_act)));
}
}
}
class TreatmentArmIdComparator implements Comparator<TreatmentArm>{
@Override
public int compare(TreatmentArm o1, TreatmentArm o2) {
return (o1.getId()<o2.getId() ? -1 : (o1.getId()==o2.getId() ? 0 : 1));
}
}
}