From fffdfe85bf1c3fd8085430b01356077acc7e1f29 Mon Sep 17 00:00:00 2001 From: Joel Therrien Date: Mon, 16 Jul 2018 16:58:11 -0700 Subject: [PATCH] Finish competing risk implementation. Fix a bug in tree training algorithm. --- .../randomforest/Bootstrapper.java | 4 +- .../randomforest/CovariateRow.java | 17 + .../joeltherrien/randomforest/DataLoader.java | 6 - .../ca/joeltherrien/randomforest/Main.java | 14 +- .../joeltherrien/randomforest/Settings.java | 99 +- .../covariates/BooleanCovariate.java | 5 + .../covariates/FactorCovariate.java | 5 + .../covariates/NumericCovariate.java | 11 +- .../competingrisk/CompetingRiskFunction.java | 11 - .../CompetingRiskFunctionCombiner.java | 81 ++ .../competingrisk/CompetingRiskFunctions.java | 25 + .../CompetingRiskGroupDifferentiator.java | 38 +- ...sponse.java => CompetingRiskResponse.java} | 12 +- .../CompetingRiskResponseCombiner.java | 123 ++ ... CompetingRiskResponseWithCensorTime.java} | 10 +- ...rayLogRankMultipleGroupDifferentiator.java | 15 +- .../GrayLogRankSingleGroupDifferentiator.java | 12 +- .../LogRankMultipleGroupDifferentiator.java | 14 +- .../LogRankSingleGroupDifferentiator.java | 9 +- .../responses/competingrisk/MathFunction.java | 60 + .../responses/competingrisk/Point.java | 2 - .../regression/MeanResponseCombiner.java | 57 +- .../randomforest/tree/Forest.java | 17 +- .../randomforest/tree/ForestTrainer.java | 51 +- .../tree/GroupDifferentiator.java | 11 - .../randomforest/tree/ResponseCombiner.java | 15 +- .../randomforest/tree/TreeTrainer.java | 61 +- .../competingrisk/TestCompetingRisk.R | 99 ++ .../competingrisk/TestCompetingRisk.java | 325 +++++ .../TestCompetingRiskResponseCombiner.R | 12 + .../TestCompetingRiskResponseCombiner.java | 94 ++ .../TestLogRankSingleGroupDifferentiator.R | 62 + .../TestLogRankSingleGroupDifferentiator.java | 61 + .../competingrisk/TestMathFunction.java | 43 + .../settings/TestPersistence.java | 10 +- .../randomforest/workshop/TrainForest.java | 6 +- .../workshop/TrainSingleTree.java | 8 +- .../workshop/TrainSingleTreeFactor.java | 9 +- src/test/resources/wihs.bootstrapped.csv | 1165 +++++++++++++++++ src/test/resources/wihs.bootstrapped2.csv | 1165 +++++++++++++++++ src/test/resources/wihs.csv | 1165 +++++++++++++++++ 41 files changed, 4768 insertions(+), 241 deletions(-) delete mode 100644 src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskFunction.java create mode 100644 src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskFunctionCombiner.java create mode 100644 src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskFunctions.java rename src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/{CompetingResponse.java => CompetingRiskResponse.java} (76%) create mode 100644 src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskResponseCombiner.java rename src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/{CompetingResponseWithCensorTime.java => CompetingRiskResponseWithCensorTime.java} (75%) create mode 100644 src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/MathFunction.java create mode 100644 src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRisk.R create mode 100644 src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRisk.java create mode 100644 src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRiskResponseCombiner.R create mode 100644 src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRiskResponseCombiner.java create mode 100644 src/test/java/ca/joeltherrien/randomforest/competingrisk/TestLogRankSingleGroupDifferentiator.R create mode 100644 src/test/java/ca/joeltherrien/randomforest/competingrisk/TestLogRankSingleGroupDifferentiator.java create mode 100644 src/test/java/ca/joeltherrien/randomforest/competingrisk/TestMathFunction.java create mode 100644 src/test/resources/wihs.bootstrapped.csv create mode 100644 src/test/resources/wihs.bootstrapped2.csv create mode 100644 src/test/resources/wihs.csv diff --git a/src/main/java/ca/joeltherrien/randomforest/Bootstrapper.java b/src/main/java/ca/joeltherrien/randomforest/Bootstrapper.java index 88b064b..2570201 100644 --- a/src/main/java/ca/joeltherrien/randomforest/Bootstrapper.java +++ b/src/main/java/ca/joeltherrien/randomforest/Bootstrapper.java @@ -5,12 +5,12 @@ import lombok.RequiredArgsConstructor; import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; @RequiredArgsConstructor public class Bootstrapper { final private List originalData; - final private Random random = new Random(); public List bootstrap(){ final int n = originalData.size(); @@ -18,7 +18,7 @@ public class Bootstrapper { final List newList = new ArrayList<>(n); for(int i=0; i simpleMap, List covariateList, int id){ + final Map valueMap = new HashMap<>(); + final Map covariateMap = new HashMap<>(); + + covariateList.forEach(covariate -> covariateMap.put(covariate.getName(), covariate)); + + simpleMap.forEach((name, valueStr) -> { + if(covariateMap.containsKey(name)){ + valueMap.put(name, covariateMap.get(name).createValue(valueStr)); + } + }); + + return new CovariateRow(valueMap, id); + } + } diff --git a/src/main/java/ca/joeltherrien/randomforest/DataLoader.java b/src/main/java/ca/joeltherrien/randomforest/DataLoader.java index 56f6431..01f0992 100644 --- a/src/main/java/ca/joeltherrien/randomforest/DataLoader.java +++ b/src/main/java/ca/joeltherrien/randomforest/DataLoader.java @@ -1,7 +1,6 @@ package ca.joeltherrien.randomforest; import ca.joeltherrien.randomforest.covariates.Covariate; -import ca.joeltherrien.randomforest.tree.GroupDifferentiator; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.RequiredArgsConstructor; import org.apache.commons.csv.CSVFormat; @@ -49,11 +48,6 @@ public class DataLoader { Y parse(CSVRecord record); } - @FunctionalInterface - public interface ResponseLoaderConstructor{ - ResponseLoader construct(ObjectNode node); - } - @RequiredArgsConstructor public static class DoubleLoader implements ResponseLoader { diff --git a/src/main/java/ca/joeltherrien/randomforest/Main.java b/src/main/java/ca/joeltherrien/randomforest/Main.java index 49db7a4..38d9a6f 100644 --- a/src/main/java/ca/joeltherrien/randomforest/Main.java +++ b/src/main/java/ca/joeltherrien/randomforest/Main.java @@ -44,7 +44,7 @@ public class Main { final List> dataset = DataLoader.loadData(covariates, settings.getResponseLoader(), settings.getDataFileLocation()); - final ForestTrainer forestTrainer = new ForestTrainer<>(settings, dataset, covariates); + final ForestTrainer forestTrainer = new ForestTrainer<>(settings, dataset, covariates); if(settings.isSaveProgress()){ forestTrainer.trainParallelOnDisk(settings.getNumberOfThreads()); @@ -63,8 +63,14 @@ public class Main { final ObjectNode groupDifferentiatorSettings = new ObjectNode(JsonNodeFactory.instance); groupDifferentiatorSettings.set("type", new TextNode("WeightedVarianceGroupDifferentiator")); + final ObjectNode responseCombinerSettings = new ObjectNode(JsonNodeFactory.instance); + responseCombinerSettings.set("type", new TextNode("MeanResponseCombiner")); + + final ObjectNode treeCombinerSettings = new ObjectNode(JsonNodeFactory.instance); + treeCombinerSettings.set("type", new TextNode("MeanResponseCombiner")); + final ObjectNode yVarSettings = new ObjectNode(JsonNodeFactory.instance); - yVarSettings.set("type", new TextNode("y")); + yVarSettings.set("type", new TextNode("Double")); yVarSettings.set("name", new TextNode("y")); final Settings settings = Settings.builder() @@ -75,8 +81,8 @@ public class Main { ) ) .dataFileLocation("data.csv") - .responseCombiner("MeanResponseCombiner") - .treeResponseCombiner("MeanResponseCombiner") + .responseCombinerSettings(responseCombinerSettings) + .treeCombinerSettings(treeCombinerSettings) .groupDifferentiatorSettings(groupDifferentiatorSettings) .yVarSettings(yVarSettings) .maxNodeDepth(100000) diff --git a/src/main/java/ca/joeltherrien/randomforest/Settings.java b/src/main/java/ca/joeltherrien/randomforest/Settings.java index cdc7c70..74dfb25 100644 --- a/src/main/java/ca/joeltherrien/randomforest/Settings.java +++ b/src/main/java/ca/joeltherrien/randomforest/Settings.java @@ -3,8 +3,10 @@ package ca.joeltherrien.randomforest; import ca.joeltherrien.randomforest.covariates.CovariateSettings; import ca.joeltherrien.randomforest.responses.competingrisk.*; import ca.joeltherrien.randomforest.responses.regression.MeanGroupDifferentiator; +import ca.joeltherrien.randomforest.responses.regression.MeanResponseCombiner; import ca.joeltherrien.randomforest.responses.regression.WeightedVarianceGroupDifferentiator; import ca.joeltherrien.randomforest.tree.GroupDifferentiator; +import ca.joeltherrien.randomforest.tree.ResponseCombiner; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -16,6 +18,7 @@ import lombok.*; import java.io.File; import java.io.IOException; import java.util.*; +import java.util.function.Function; /** * This class is saved & loaded using a saved configuration file. It contains all relevant settings when training a forest. @@ -26,11 +29,11 @@ import java.util.*; @EqualsAndHashCode public class Settings { - private static Map RESPONSE_LOADER_MAP = new HashMap<>(); - public static DataLoader.ResponseLoaderConstructor getResponseLoaderConstructor(final String name){ + private static Map> RESPONSE_LOADER_MAP = new HashMap<>(); + public static Function getResponseLoaderConstructor(final String name){ return RESPONSE_LOADER_MAP.get(name.toLowerCase()); } - public static void registerResponseLoaderConstructor(final String name, final DataLoader.ResponseLoaderConstructor responseLoaderConstructor){ + public static void registerResponseLoaderConstructor(final String name, final Function responseLoaderConstructor){ RESPONSE_LOADER_MAP.put(name.toLowerCase(), responseLoaderConstructor); } @@ -38,19 +41,19 @@ public class Settings { registerResponseLoaderConstructor("double", node -> new DataLoader.DoubleLoader(node) ); - registerResponseLoaderConstructor("CompetingResponse", - node -> new CompetingResponse.CompetingResponseLoader(node) + registerResponseLoaderConstructor("CompetingRiskResponse", + node -> new CompetingRiskResponse.CompetingResponseLoader(node) ); - registerResponseLoaderConstructor("CompetingResponseWithCensorTime", - node -> new CompetingResponseWithCensorTime.CompetingResponseWithCensorTimeLoader(node) + registerResponseLoaderConstructor("CompetingRiskResponseWithCensorTime", + node -> new CompetingRiskResponseWithCensorTime.CompetingResponseWithCensorTimeLoader(node) ); } - private static Map GROUP_DIFFERENTIATOR_MAP = new HashMap<>(); - public static GroupDifferentiator.GroupDifferentiatorConstructor getGroupDifferentiatorConstructor(final String name){ + private static Map> GROUP_DIFFERENTIATOR_MAP = new HashMap<>(); + public static Function getGroupDifferentiatorConstructor(final String name){ return GROUP_DIFFERENTIATOR_MAP.get(name.toLowerCase()); } - public static void registerGroupDifferentiatorConstructor(final String name, final GroupDifferentiator.GroupDifferentiatorConstructor groupDifferentiatorConstructor){ + public static void registerGroupDifferentiatorConstructor(final String name, final Function groupDifferentiatorConstructor){ GROUP_DIFFERENTIATOR_MAP.put(name.toLowerCase(), groupDifferentiatorConstructor); } static{ @@ -98,13 +101,67 @@ public class Settings { ); } + private static Map> RESPONSE_COMBINER_MAP = new HashMap<>(); + public static Function getResponseCombinerConstructor(final String name){ + return RESPONSE_COMBINER_MAP.get(name.toLowerCase()); + } + public static void registerResponseCombinerConstructor(final String name, final Function responseCombinerConstructor){ + RESPONSE_COMBINER_MAP.put(name.toLowerCase(), responseCombinerConstructor); + } + + static{ + + registerResponseCombinerConstructor("MeanResponseCombiner", + (node) -> new MeanResponseCombiner() + ); + registerResponseCombinerConstructor("CompetingRiskResponseCombiner", + (node) -> { + final List eventList = new ArrayList<>(); + node.get("events").elements().forEachRemaining(event -> eventList.add(event.asInt())); + final int[] events = eventList.stream().mapToInt(i -> i).toArray(); + + double[] times = null; + // note that times may be null + if(node.hasNonNull("times")){ + final List timeList = new ArrayList<>(); + node.get("times").elements().forEachRemaining(event -> timeList.add(event.asDouble())); + times = eventList.stream().mapToDouble(db -> db).toArray(); + } + + return new CompetingRiskResponseCombiner(events, times); + + } + ); + + registerResponseCombinerConstructor("CompetingRiskFunctionCombiner", + (node) -> { + final List eventList = new ArrayList<>(); + node.get("events").elements().forEachRemaining(event -> eventList.add(event.asInt())); + final int[] events = eventList.stream().mapToInt(i -> i).toArray(); + + double[] times = null; + // note that times may be null + if(node.hasNonNull("times")){ + final List timeList = new ArrayList<>(); + node.get("times").elements().forEachRemaining(event -> timeList.add(event.asDouble())); + times = eventList.stream().mapToDouble(db -> db).toArray(); + } + + return new CompetingRiskFunctionCombiner(events, times); + + } + ); + + + } + private int numberOfSplits = 5; private int nodeSize = 5; private int maxNodeDepth = 1000000; // basically no maxNodeDepth - private String responseCombiner; + private ObjectNode responseCombinerSettings = new ObjectNode(JsonNodeFactory.instance); private ObjectNode groupDifferentiatorSettings = new ObjectNode(JsonNodeFactory.instance); - private String treeResponseCombiner; + private ObjectNode treeCombinerSettings = new ObjectNode(JsonNodeFactory.instance); private List covariates = new ArrayList<>(); private ObjectNode yVarSettings = new ObjectNode(JsonNodeFactory.instance); @@ -148,14 +205,28 @@ public class Settings { public GroupDifferentiator getGroupDifferentiator(){ final String type = groupDifferentiatorSettings.get("type").asText(); - return getGroupDifferentiatorConstructor(type).construct(groupDifferentiatorSettings); + return getGroupDifferentiatorConstructor(type).apply(groupDifferentiatorSettings); } @JsonIgnore public DataLoader.ResponseLoader getResponseLoader(){ final String type = yVarSettings.get("type").asText(); - return getResponseLoaderConstructor(type).construct(yVarSettings); + return getResponseLoaderConstructor(type).apply(yVarSettings); + } + + @JsonIgnore + public ResponseCombiner getResponseCombiner(){ + final String type = responseCombinerSettings.get("type").asText(); + + return getResponseCombinerConstructor(type).apply(responseCombinerSettings); + } + + @JsonIgnore + public ResponseCombiner getTreeCombiner(){ + final String type = treeCombinerSettings.get("type").asText(); + + return getResponseCombinerConstructor(type).apply(treeCombinerSettings); } } diff --git a/src/main/java/ca/joeltherrien/randomforest/covariates/BooleanCovariate.java b/src/main/java/ca/joeltherrien/randomforest/covariates/BooleanCovariate.java index 9b5250e..c4581ff 100644 --- a/src/main/java/ca/joeltherrien/randomforest/covariates/BooleanCovariate.java +++ b/src/main/java/ca/joeltherrien/randomforest/covariates/BooleanCovariate.java @@ -42,6 +42,11 @@ public final class BooleanCovariate implements Covariate{ } } + @Override + public String toString(){ + return "BooleanCovariate(name=" + name + ")"; + } + public class BooleanValue implements Value{ private final Boolean value; diff --git a/src/main/java/ca/joeltherrien/randomforest/covariates/FactorCovariate.java b/src/main/java/ca/joeltherrien/randomforest/covariates/FactorCovariate.java index ebf6cf4..4638f92 100644 --- a/src/main/java/ca/joeltherrien/randomforest/covariates/FactorCovariate.java +++ b/src/main/java/ca/joeltherrien/randomforest/covariates/FactorCovariate.java @@ -82,6 +82,11 @@ public final class FactorCovariate implements Covariate{ return factorValue; } + @Override + public String toString(){ + return "FactorCovariate(name=" + name + ")"; + } + @EqualsAndHashCode public final class FactorValue implements Covariate.Value{ diff --git a/src/main/java/ca/joeltherrien/randomforest/covariates/NumericCovariate.java b/src/main/java/ca/joeltherrien/randomforest/covariates/NumericCovariate.java index 2746697..6ec8d05 100644 --- a/src/main/java/ca/joeltherrien/randomforest/covariates/NumericCovariate.java +++ b/src/main/java/ca/joeltherrien/randomforest/covariates/NumericCovariate.java @@ -1,13 +1,16 @@ package ca.joeltherrien.randomforest.covariates; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.ToString; import java.util.*; import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Collectors; @RequiredArgsConstructor +@ToString public final class NumericCovariate implements Covariate{ @Getter @@ -20,16 +23,18 @@ public final class NumericCovariate implements Covariate{ // only work with non-NA values data = data.stream().filter(value -> !value.isNA()).collect(Collectors.toList()); + //data = data.stream().filter(value -> !value.isNA()).distinct().collect(Collectors.toList()); // TODO which to use? // for this implementation we need to shuffle the data final List> shuffledData; - if(number > data.size()){ + if(number >= data.size()){ shuffledData = new ArrayList<>(data); Collections.shuffle(shuffledData, random); } else{ // only need the top number entries shuffledData = new ArrayList<>(number); final Set indexesToUse = new HashSet<>(); + //final List indexesToUse = new ArrayList<>(); // TODO which to use? while(indexesToUse.size() < number){ final int index = random.nextInt(data.size()); @@ -56,7 +61,7 @@ public final class NumericCovariate implements Covariate{ } @Override - public Value createValue(String value) { + public NumericValue createValue(String value) { if(value == null || value.equalsIgnoreCase("na")){ return createValue((Double) null); } @@ -64,6 +69,7 @@ public final class NumericCovariate implements Covariate{ return createValue(Double.parseDouble(value)); } + @EqualsAndHashCode public class NumericValue implements Covariate.Value{ private final Double value; // may be null @@ -88,6 +94,7 @@ public final class NumericCovariate implements Covariate{ } } + @EqualsAndHashCode public class NumericSplitRule implements Covariate.SplitRule{ private final double threshold; diff --git a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskFunction.java b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskFunction.java deleted file mode 100644 index 0cdd742..0000000 --- a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskFunction.java +++ /dev/null @@ -1,11 +0,0 @@ -package ca.joeltherrien.randomforest.responses.competingrisk; - -import java.util.List; - -public class CompetingRiskFunction { - - private List pointList; - - - -} diff --git a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskFunctionCombiner.java b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskFunctionCombiner.java new file mode 100644 index 0000000..3e9733e --- /dev/null +++ b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskFunctionCombiner.java @@ -0,0 +1,81 @@ +package ca.joeltherrien.randomforest.responses.competingrisk; + +import ca.joeltherrien.randomforest.tree.ResponseCombiner; +import lombok.RequiredArgsConstructor; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RequiredArgsConstructor +public class CompetingRiskFunctionCombiner implements ResponseCombiner { + + private final int[] events; + private final double[] times; // We may restrict ourselves to specific times. + + @Override + public CompetingRiskFunctions combine(List responses) { + + final double[] timesToUse; + if(times != null){ + timesToUse = times; + } + else{ + timesToUse = responses.stream() + .map(functions -> functions.getSurvivalCurve()) + .flatMapToDouble( + function -> function.getPoints().stream() + .mapToDouble(point -> point.getTime()) + ).sorted().distinct().toArray(); + } + + final double n = responses.size(); + + final List survivalPoints = new ArrayList<>(timesToUse.length); + for(final double time : timesToUse){ + + final double survivalY = responses.stream() + .mapToDouble(functions -> functions.getSurvivalCurve().evaluate(time).getY() / n) + .sum(); + + survivalPoints.add(new Point(time, survivalY)); + + } + + final MathFunction survivalFunction = new MathFunction(survivalPoints, new Point(0.0, 1.0)); + final Map causeSpecificCumulativeHazardFunctionMap = new HashMap<>(); + final Map cumulativeIncidenceFunctionMap = new HashMap<>(); + + for(final int event : events){ + + final List cumulativeHazardFunctionPoints = new ArrayList<>(timesToUse.length); + final List cumulativeIncidenceFunctionPoints = new ArrayList<>(timesToUse.length); + + for(final double time : timesToUse){ + + final double hazardY = responses.stream() + .mapToDouble(functions -> functions.getCauseSpecificHazardFunction(event).evaluate(time).getY() / n) + .sum(); + + final double incidenceY = responses.stream() + .mapToDouble(functions -> functions.getCumulativeIncidenceFunction(event).evaluate(time).getY() / n) + .sum(); + + cumulativeHazardFunctionPoints.add(new Point(time, hazardY)); + cumulativeIncidenceFunctionPoints.add(new Point(time, incidenceY)); + + } + + causeSpecificCumulativeHazardFunctionMap.put(event, new MathFunction(cumulativeHazardFunctionPoints)); + cumulativeIncidenceFunctionMap.put(event, new MathFunction(cumulativeIncidenceFunctionPoints)); + + } + + return CompetingRiskFunctions.builder() + .causeSpecificHazardFunctionMap(causeSpecificCumulativeHazardFunctionMap) + .cumulativeIncidenceFunctionMap(cumulativeIncidenceFunctionMap) + .survivalCurve(survivalFunction) + .build(); + } +} diff --git a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskFunctions.java b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskFunctions.java new file mode 100644 index 0000000..6fef9f8 --- /dev/null +++ b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskFunctions.java @@ -0,0 +1,25 @@ +package ca.joeltherrien.randomforest.responses.competingrisk; + +import lombok.Builder; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Map; + +@Builder +public class CompetingRiskFunctions { + + private final Map causeSpecificHazardFunctionMap; + private final Map cumulativeIncidenceFunctionMap; + + @Getter + private final MathFunction survivalCurve; + + public MathFunction getCauseSpecificHazardFunction(int cause){ + return causeSpecificHazardFunctionMap.get(cause); + } + + public MathFunction getCumulativeIncidenceFunction(int cause) { + return cumulativeIncidenceFunctionMap.get(cause); + } +} diff --git a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskGroupDifferentiator.java b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskGroupDifferentiator.java index 3b15926..35ff237 100644 --- a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskGroupDifferentiator.java +++ b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskGroupDifferentiator.java @@ -12,14 +12,14 @@ import java.util.stream.Stream; * modifies the abstract method. * */ -public abstract class CompetingRiskGroupDifferentiator implements GroupDifferentiator{ +public abstract class CompetingRiskGroupDifferentiator implements GroupDifferentiator{ @Override public abstract Double differentiate(List leftHand, List rightHand); abstract double riskSet(final List eventList, double time, int eventOfFocus); - private double numberOFEventsAtTime(int eventOfFocus, List eventList, double time){ + private double numberOfEventsAtTime(int eventOfFocus, List eventList, double time){ return (double) eventList.stream() .filter(event -> event.getDelta() == eventOfFocus) .filter(event -> event.getU() == time) // since delta != 0 we know censoring didn't occur prior to this @@ -31,8 +31,8 @@ public abstract class CompetingRiskGroupDifferentiator leftHand, List rightHand){ @@ -40,34 +40,42 @@ public abstract class CompetingRiskGroupDifferentiator event.getDelta() != 0) // remove censored events + .filter(event -> !event.isCensored()) .mapToDouble(event -> event.getU()) .distinct() .toArray(); double summation = 0.0; - double varianceSquared = 0.0; + double variance = 0.0; for(final double time_k : distinctEventTimes){ final double weight = weight(time_k); // W_j(t_k) - final double numberEventsAtTimeDaughterLeft = numberOFEventsAtTime(eventOfFocus, leftHand, time_k); // d_{j,l}(t_k) - final double numberEventsAtTimeDaughterRight = numberOFEventsAtTime(eventOfFocus, rightHand, time_k); // d_{j,r}(t_k) + final double numberEventsAtTimeDaughterLeft = numberOfEventsAtTime(eventOfFocus, leftHand, time_k); // d_{j,l}(t_k) + final double numberEventsAtTimeDaughterRight = numberOfEventsAtTime(eventOfFocus, rightHand, time_k); // d_{j,r}(t_k) final double numberOfEventsAtTime = numberEventsAtTimeDaughterLeft + numberEventsAtTimeDaughterRight; // d_j(t_k) final double individualsAtRiskDaughterLeft = riskSet(leftHand, time_k, eventOfFocus); // Y_l(t_k) final double individualsAtRiskDaughterRight = riskSet(rightHand, time_k, eventOfFocus); // Y_r(t_k) final double individualsAtRisk = individualsAtRiskDaughterLeft + individualsAtRiskDaughterRight; // Y(t_k) - summation = summation + weight*(numberEventsAtTimeDaughterLeft - numberOfEventsAtTime*individualsAtRiskDaughterLeft/individualsAtRisk); - - varianceSquared = varianceSquared + weight*weight*numberOfEventsAtTime*individualsAtRiskDaughterLeft/individualsAtRisk + final double deltaSummation = weight*(numberEventsAtTimeDaughterLeft - numberOfEventsAtTime*individualsAtRiskDaughterLeft/individualsAtRisk); + final double deltaVariance = weight*weight*numberOfEventsAtTime*individualsAtRiskDaughterLeft/individualsAtRisk * (1.0 - individualsAtRiskDaughterLeft / individualsAtRisk) * ((individualsAtRisk - numberOfEventsAtTime) / (individualsAtRisk - 1.0)); + // Note - notation differs slightly with what is found in STAT 855 notes, but they are equivalent. + // Note - if individualsAtRisk == 1 then variance will be NaN. + if(!Double.isNaN(deltaVariance)){ + summation += deltaSummation; + variance += deltaVariance; + } + else{ + // Do nothing; else statement left for breakpoints. + } } - return new LogRankValue(summation, varianceSquared); + return new LogRankValue(summation, variance); } double weight(double time){ @@ -80,10 +88,10 @@ public abstract class CompetingRiskGroupDifferentiator{ + public static class CompetingResponseLoader implements DataLoader.ResponseLoader{ private final String deltaName; private final String uName; @@ -25,11 +29,11 @@ public class CompetingResponse { } @Override - public CompetingResponse parse(CSVRecord record) { + public CompetingRiskResponse parse(CSVRecord record) { final int delta = Integer.parseInt(record.get(deltaName)); final double u = Double.parseDouble(record.get(uName)); - return new CompetingResponse(delta, u); + return new CompetingRiskResponse(delta, u); } } diff --git a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskResponseCombiner.java b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskResponseCombiner.java new file mode 100644 index 0000000..d728879 --- /dev/null +++ b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskResponseCombiner.java @@ -0,0 +1,123 @@ +package ca.joeltherrien.randomforest.responses.competingrisk; + +import ca.joeltherrien.randomforest.tree.ResponseCombiner; +import lombok.RequiredArgsConstructor; + +import java.util.*; + +/** + * This class takes all of the observations in a terminal node and combines them to produce estimates of the cause-specific hazard function + * and the cumulative incidence curve. + * + * See https://kogalur.github.io/randomForestSRC/theory.html for details. + * + */ +@RequiredArgsConstructor +public class CompetingRiskResponseCombiner implements ResponseCombiner { + + private final int[] events; + private final double[] times; // We may restrict ourselves to specific times. + + @Override + public CompetingRiskFunctions combine(List responses) { + + final Map causeSpecificCumulativeHazardFunctionMap = new HashMap<>(); + final Map cumulativeIncidenceFunctionMap = new HashMap<>(); + + final double[] timesToUse; + if(times != null){ + timesToUse = this.times; + } + else{ + timesToUse = responses.stream() + .filter(response -> !response.isCensored()) + .mapToDouble(response -> response.getU()) + .sorted().distinct() + .toArray(); + } + + final double[] individualsAtRiskArray = Arrays.stream(timesToUse).map(time -> riskSet(responses, time)).toArray(); + + // First we need to develop the overall survival curve! + final List survivalPoints = new ArrayList<>(timesToUse.length); + double previousSurvivalValue = 1.0; + for(int i=0; i !event.isCensored()) + .filter(event -> event.getU() == time_k) // since delta != 0 we know censoring didn't occur prior to this + .count(); + + final double newValue = previousSurvivalValue * (1.0 - numberOfEventsAtTime / individualsAtRisk); + survivalPoints.add(new Point(time_k, newValue)); + previousSurvivalValue = newValue; + + } + + final MathFunction survivalCurve = new MathFunction(survivalPoints, new Point(0.0, 1.0)); + + + for(final int event : events){ + + final List hazardFunctionPoints = new ArrayList<>(timesToUse.length); + Point previousHazardFunctionPoint = new Point(0.0, 0.0); + + final List cifPoints = new ArrayList<>(timesToUse.length); + Point previousCIFPoint = new Point(0.0, 0.0); + + for(int i=0; i 0 ? survivalCurve.evaluate(timesToUse[i-1]).getY() : survivalCurve.evaluate(0.0).getY(); + final double previousSurvivalEvaluation = i > 0 ? survivalCurve.evaluate(timesToUse[i-1]).getY() : 1.0; + + final double cifDeltaY = previousSurvivalEvaluation * (numberEventsAtTime / individualsAtRisk); + final Point newCIFPoint = new Point(time_k, previousCIFPoint.getY() + cifDeltaY); + cifPoints.add(newCIFPoint); + previousCIFPoint = newCIFPoint; + + } + + final MathFunction causeSpecificCumulativeHazardFunction = new MathFunction(hazardFunctionPoints); + causeSpecificCumulativeHazardFunctionMap.put(event, causeSpecificCumulativeHazardFunction); + + final MathFunction cifFunction = new MathFunction(cifPoints); + cumulativeIncidenceFunctionMap.put(event, cifFunction); + } + + + return CompetingRiskFunctions.builder() + .causeSpecificHazardFunctionMap(causeSpecificCumulativeHazardFunctionMap) + .cumulativeIncidenceFunctionMap(cumulativeIncidenceFunctionMap) + .survivalCurve(survivalCurve) + .build(); + } + + + private double riskSet(List eventList, double time) { + return eventList.stream() + .filter(event -> event.getU() >= time) + .count(); + } + + private double numberOfEventsAtTime(int eventOfFocus, List eventList, double time){ + return (double) eventList.stream() + .filter(event -> event.getDelta() == eventOfFocus) + .filter(event -> event.getU() == time) // since delta != 0 we know censoring didn't occur prior to this + .count(); + + } + +} diff --git a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingResponseWithCensorTime.java b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskResponseWithCensorTime.java similarity index 75% rename from src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingResponseWithCensorTime.java rename to src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskResponseWithCensorTime.java index adb56f1..220cfea 100644 --- a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingResponseWithCensorTime.java +++ b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/CompetingRiskResponseWithCensorTime.java @@ -11,16 +11,16 @@ import org.apache.commons.csv.CSVRecord; * */ @Data -public class CompetingResponseWithCensorTime extends CompetingResponse{ +public class CompetingRiskResponseWithCensorTime extends CompetingRiskResponse { private final double c; - public CompetingResponseWithCensorTime(int delta, double u, double c) { + public CompetingRiskResponseWithCensorTime(int delta, double u, double c) { super(delta, u); this.c = c; } @RequiredArgsConstructor - public static class CompetingResponseWithCensorTimeLoader implements DataLoader.ResponseLoader{ + public static class CompetingResponseWithCensorTimeLoader implements DataLoader.ResponseLoader{ private final String deltaName; private final String uName; @@ -33,12 +33,12 @@ public class CompetingResponseWithCensorTime extends CompetingResponse{ } @Override - public CompetingResponseWithCensorTime parse(CSVRecord record) { + public CompetingRiskResponseWithCensorTime parse(CSVRecord record) { final int delta = Integer.parseInt(record.get(deltaName)); final double u = Double.parseDouble(record.get(uName)); final double c = Double.parseDouble(record.get(cName)); - return new CompetingResponseWithCensorTime(delta, u, c); + return new CompetingRiskResponseWithCensorTime(delta, u, c); } } } diff --git a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/GrayLogRankMultipleGroupDifferentiator.java b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/GrayLogRankMultipleGroupDifferentiator.java index 10694eb..dc3df9b 100644 --- a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/GrayLogRankMultipleGroupDifferentiator.java +++ b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/GrayLogRankMultipleGroupDifferentiator.java @@ -1,12 +1,7 @@ package ca.joeltherrien.randomforest.responses.competingrisk; -import ca.joeltherrien.randomforest.responses.regression.WeightedVarianceGroupDifferentiator; -import ca.joeltherrien.randomforest.tree.GroupDifferentiator; -import com.fasterxml.jackson.databind.JsonNode; import lombok.RequiredArgsConstructor; -import java.util.ArrayList; -import java.util.Iterator; import java.util.List; /** @@ -14,12 +9,12 @@ import java.util.List; * */ @RequiredArgsConstructor -public class GrayLogRankMultipleGroupDifferentiator extends CompetingRiskGroupDifferentiator { +public class GrayLogRankMultipleGroupDifferentiator extends CompetingRiskGroupDifferentiator { private final int[] events; @Override - public Double differentiate(List leftHand, List rightHand) { + public Double differentiate(List leftHand, List rightHand) { if(leftHand.size() == 0 || rightHand.size() == 0){ return null; } @@ -30,8 +25,8 @@ public class GrayLogRankMultipleGroupDifferentiator extends CompetingRiskGroupDi for(final int eventOfFocus : events){ final LogRankValue valueOfInterest = specificLogRankValue(eventOfFocus, leftHand, rightHand); - numerator += valueOfInterest.getNumerator()*valueOfInterest.getVariance(); - denominatorSquared += valueOfInterest.getVarianceSquared(); + numerator += valueOfInterest.getNumerator()*valueOfInterest.getVarianceSqrt(); + denominatorSquared += valueOfInterest.getVariance(); } @@ -40,7 +35,7 @@ public class GrayLogRankMultipleGroupDifferentiator extends CompetingRiskGroupDi } @Override - double riskSet(List eventList, double time, int eventOfFocus) { + double riskSet(List eventList, double time, int eventOfFocus) { return eventList.stream() .filter(event -> event.getU() >= time || (event.getU() < time && event.getDelta() != eventOfFocus && event.getC() > time) diff --git a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/GrayLogRankSingleGroupDifferentiator.java b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/GrayLogRankSingleGroupDifferentiator.java index 4982144..7ce5d76 100644 --- a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/GrayLogRankSingleGroupDifferentiator.java +++ b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/GrayLogRankSingleGroupDifferentiator.java @@ -1,11 +1,7 @@ package ca.joeltherrien.randomforest.responses.competingrisk; -import ca.joeltherrien.randomforest.tree.GroupDifferentiator; -import com.fasterxml.jackson.databind.JsonNode; import lombok.RequiredArgsConstructor; -import java.util.ArrayList; -import java.util.Iterator; import java.util.List; /** @@ -13,24 +9,24 @@ import java.util.List; * */ @RequiredArgsConstructor -public class GrayLogRankSingleGroupDifferentiator extends CompetingRiskGroupDifferentiator { +public class GrayLogRankSingleGroupDifferentiator extends CompetingRiskGroupDifferentiator { private final int eventOfFocus; @Override - public Double differentiate(List leftHand, List rightHand) { + public Double differentiate(List leftHand, List rightHand) { if(leftHand.size() == 0 || rightHand.size() == 0){ return null; } final LogRankValue valueOfInterest = specificLogRankValue(eventOfFocus, leftHand, rightHand); - return Math.abs(valueOfInterest.getNumerator() / valueOfInterest.getVariance()); + return Math.abs(valueOfInterest.getNumerator() / valueOfInterest.getVarianceSqrt()); } @Override - double riskSet(List eventList, double time, int eventOfFocus) { + double riskSet(List eventList, double time, int eventOfFocus) { return eventList.stream() .filter(event -> event.getU() >= time || (event.getU() < time && event.getDelta() != eventOfFocus && event.getC() > time) diff --git a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/LogRankMultipleGroupDifferentiator.java b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/LogRankMultipleGroupDifferentiator.java index 8926b1a..64404b9 100644 --- a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/LogRankMultipleGroupDifferentiator.java +++ b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/LogRankMultipleGroupDifferentiator.java @@ -1,11 +1,7 @@ package ca.joeltherrien.randomforest.responses.competingrisk; -import ca.joeltherrien.randomforest.tree.GroupDifferentiator; -import com.fasterxml.jackson.databind.JsonNode; import lombok.RequiredArgsConstructor; -import java.util.ArrayList; -import java.util.Iterator; import java.util.List; /** @@ -13,12 +9,12 @@ import java.util.List; * */ @RequiredArgsConstructor -public class LogRankMultipleGroupDifferentiator extends CompetingRiskGroupDifferentiator { +public class LogRankMultipleGroupDifferentiator extends CompetingRiskGroupDifferentiator { private final int[] events; @Override - public Double differentiate(List leftHand, List rightHand) { + public Double differentiate(List leftHand, List rightHand) { if(leftHand.size() == 0 || rightHand.size() == 0){ return null; } @@ -29,8 +25,8 @@ public class LogRankMultipleGroupDifferentiator extends CompetingRiskGroupDiffer for(final int eventOfFocus : events){ final LogRankValue valueOfInterest = specificLogRankValue(eventOfFocus, leftHand, rightHand); - numerator += valueOfInterest.getNumerator()*valueOfInterest.getVariance(); - denominatorSquared += valueOfInterest.getVarianceSquared(); + numerator += valueOfInterest.getNumerator()*valueOfInterest.getVarianceSqrt(); + denominatorSquared += valueOfInterest.getVariance(); } @@ -39,7 +35,7 @@ public class LogRankMultipleGroupDifferentiator extends CompetingRiskGroupDiffer } @Override - double riskSet(List eventList, double time, int eventOfFocus) { + double riskSet(List eventList, double time, int eventOfFocus) { return eventList.stream() .filter(event -> event.getU() >= time) .count(); diff --git a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/LogRankSingleGroupDifferentiator.java b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/LogRankSingleGroupDifferentiator.java index 14688df..26405a5 100644 --- a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/LogRankSingleGroupDifferentiator.java +++ b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/LogRankSingleGroupDifferentiator.java @@ -1,6 +1,5 @@ package ca.joeltherrien.randomforest.responses.competingrisk; -import ca.joeltherrien.randomforest.tree.GroupDifferentiator; import lombok.RequiredArgsConstructor; import java.util.List; @@ -10,24 +9,24 @@ import java.util.List; * */ @RequiredArgsConstructor -public class LogRankSingleGroupDifferentiator extends CompetingRiskGroupDifferentiator { +public class LogRankSingleGroupDifferentiator extends CompetingRiskGroupDifferentiator { private final int eventOfFocus; @Override - public Double differentiate(List leftHand, List rightHand) { + public Double differentiate(List leftHand, List rightHand) { if(leftHand.size() == 0 || rightHand.size() == 0){ return null; } final LogRankValue valueOfInterest = specificLogRankValue(eventOfFocus, leftHand, rightHand); - return Math.abs(valueOfInterest.getNumerator() / valueOfInterest.getVariance()); + return Math.abs(valueOfInterest.getNumerator() / valueOfInterest.getVarianceSqrt()); } @Override - double riskSet(List eventList, double time, int eventOfFocus) { + double riskSet(List eventList, double time, int eventOfFocus) { return eventList.stream() .filter(event -> event.getU() >= time) .count(); diff --git a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/MathFunction.java b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/MathFunction.java new file mode 100644 index 0000000..fcb8cb9 --- /dev/null +++ b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/MathFunction.java @@ -0,0 +1,60 @@ +package ca.joeltherrien.randomforest.responses.competingrisk; + +import lombok.Getter; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; + +/** + * Represents a function represented by discrete points. We assume that the function is a stepwise continuous function, + * constant at the value of the previous encountered point. + * + */ +public class MathFunction { + + @Getter + private final List points; + + /** + * Represents the value that should be returned by evaluate if there are points prior to the time the function is being evaluated at. + * + * Map be null. + */ + private final Point defaultValue; + + public MathFunction(final List points){ + this(points, new Point(0.0, 0.0)); + } + + public MathFunction(final List points, final Point defaultValue){ + this.points = Collections.unmodifiableList(points); + this.defaultValue = defaultValue; + } + + public Point evaluate(double time){ + final Optional pointOptional = points.stream() + .filter(point -> point.getTime() <= time) + .max(Comparator.comparingDouble(Point::getTime)); + + return pointOptional.orElse(defaultValue); + + } + + @Override + public String toString(){ + final StringBuilder builder = new StringBuilder(); + builder.append("Default point: "); + builder.append(defaultValue); + builder.append("\n"); + + for(final Point point : points){ + builder.append(point); + builder.append("\n"); + } + + return builder.toString(); + } + +} diff --git a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/Point.java b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/Point.java index 1bef210..f417af9 100644 --- a/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/Point.java +++ b/src/main/java/ca/joeltherrien/randomforest/responses/competingrisk/Point.java @@ -8,8 +8,6 @@ import lombok.Data; */ @Data public class Point { - private final Double time; private final Double y; - } diff --git a/src/main/java/ca/joeltherrien/randomforest/responses/regression/MeanResponseCombiner.java b/src/main/java/ca/joeltherrien/randomforest/responses/regression/MeanResponseCombiner.java index 36e5701..a5e32d3 100644 --- a/src/main/java/ca/joeltherrien/randomforest/responses/regression/MeanResponseCombiner.java +++ b/src/main/java/ca/joeltherrien/randomforest/responses/regression/MeanResponseCombiner.java @@ -3,11 +3,6 @@ package ca.joeltherrien.randomforest.responses.regression; import ca.joeltherrien.randomforest.tree.ResponseCombiner; import java.util.List; -import java.util.Set; -import java.util.function.BiConsumer; -import java.util.function.BinaryOperator; -import java.util.function.Function; -import java.util.function.Supplier; /** * This implementation of the collector isn't great... but good enough given that I'm not planning to fully support regression trees. @@ -15,11 +10,7 @@ import java.util.function.Supplier; * (It's not great because you'll lose accuracy as you sum up the doubles, since dividing by n is the very last step.) * */ -public class MeanResponseCombiner implements ResponseCombiner { - - static{ - ResponseCombiner.registerResponseCombiner("MeanResponseCombiner", new MeanResponseCombiner()); - } +public class MeanResponseCombiner implements ResponseCombiner { @Override public Double combine(List responses) { @@ -29,51 +20,5 @@ public class MeanResponseCombiner implements ResponseCombiner supplier() { - return () -> new Container(0 ,0); - } - - @Override - public BiConsumer accumulator() { - return (container, number) -> { - container.number+=number; - container.n++; - }; - } - - @Override - public BinaryOperator combiner() { - return (c1, c2) -> { - c1.number += c2.number; - c1.n += c2.n; - - return c1; - }; - } - - @Override - public Function finisher() { - return (container) -> container.number/(double)container.n; - } - - @Override - public Set characteristics() { - return Set.of(Characteristics.UNORDERED); - } - - - public static class Container{ - - Container(double number, int n){ - this.number = number; - this.n = n; - } - - public Double number; - public int n; - - } - } diff --git a/src/main/java/ca/joeltherrien/randomforest/tree/Forest.java b/src/main/java/ca/joeltherrien/randomforest/tree/Forest.java index 427d7ab..c25db8c 100644 --- a/src/main/java/ca/joeltherrien/randomforest/tree/Forest.java +++ b/src/main/java/ca/joeltherrien/randomforest/tree/Forest.java @@ -4,17 +4,22 @@ import ca.joeltherrien.randomforest.CovariateRow; import lombok.Builder; import java.util.Collection; +import java.util.stream.Collectors; @Builder -public class Forest { +public class Forest { // O = output of trees, FO = forest output. In practice O == FO, even in competing risk & survival settings - private final Collection> trees; - private final ResponseCombiner treeResponseCombiner; + private final Collection> trees; + private final ResponseCombiner treeResponseCombiner; - public Y evaluate(CovariateRow row){ - return trees.parallelStream() + public FO evaluate(CovariateRow row){ + + return treeResponseCombiner.combine( + trees.parallelStream() .map(node -> node.evaluate(row)) - .collect(treeResponseCombiner); + .collect(Collectors.toList()) + ); + } } diff --git a/src/main/java/ca/joeltherrien/randomforest/tree/ForestTrainer.java b/src/main/java/ca/joeltherrien/randomforest/tree/ForestTrainer.java index f04a2f2..1617b67 100644 --- a/src/main/java/ca/joeltherrien/randomforest/tree/ForestTrainer.java +++ b/src/main/java/ca/joeltherrien/randomforest/tree/ForestTrainer.java @@ -16,17 +16,18 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import java.util.stream.Stream; @Builder @AllArgsConstructor(access=AccessLevel.PRIVATE) -public class ForestTrainer { +public class ForestTrainer { - private final TreeTrainer treeTrainer; - private final List covariatesToTry; - private final ResponseCombiner treeResponseCombiner; + private final TreeTrainer treeTrainer; + private final List covariates; + private final ResponseCombiner treeResponseCombiner; private final List> data; // number of covariates to randomly try @@ -45,15 +46,15 @@ public class ForestTrainer { this.displayProgress = true; this.saveTreeLocation = settings.getSaveTreeLocation(); - this.covariatesToTry = covariates; - this.treeResponseCombiner = ResponseCombiner.loadResponseCombinerByName(settings.getTreeResponseCombiner()); - this.treeTrainer = new TreeTrainer<>(settings); + this.covariates = covariates; + this.treeResponseCombiner = settings.getTreeCombiner(); + this.treeTrainer = new TreeTrainer<>(settings, covariates); } - public Forest trainSerial(){ + public Forest trainSerial(){ - final List> trees = new ArrayList<>(ntree); + final List> trees = new ArrayList<>(ntree); final Bootstrapper> bootstrapper = new Bootstrapper<>(data); for(int j=0; j { } } - return Forest.builder() + return Forest.builder() .treeResponseCombiner(treeResponseCombiner) .trees(trees) .build(); } - public Forest trainParallelInMemory(int threads){ + public Forest trainParallelInMemory(int threads){ // create a list that is prespecified in size (I can call the .set method at any index < ntree without // the earlier indexes being filled. - final List> trees = Stream.>generate(() -> null).limit(ntree).collect(Collectors.toList()); + final List> trees = Stream.>generate(() -> null).limit(ntree).collect(Collectors.toList()); final ExecutorService executorService = Executors.newFixedThreadPool(threads); @@ -102,7 +103,7 @@ public class ForestTrainer { if(displayProgress) { int numberTreesSet = 0; - for (final Node tree : trees) { + for (final Node tree : trees) { if (tree != null) { numberTreesSet++; } @@ -117,7 +118,7 @@ public class ForestTrainer { System.out.println("\nFinished"); } - return Forest.builder() + return Forest.builder() .treeResponseCombiner(treeResponseCombiner) .trees(trees) .build(); @@ -156,20 +157,12 @@ public class ForestTrainer { } - private Node trainTree(final Bootstrapper> bootstrapper){ - final List treeCovariates = new ArrayList<>(covariatesToTry); - Collections.shuffle(treeCovariates); - - for(int treeIndex = covariatesToTry.size()-1; treeIndex >= mtry; treeIndex--){ - treeCovariates.remove(treeIndex); - } - + private Node trainTree(final Bootstrapper> bootstrapper){ final List> bootstrappedData = bootstrapper.bootstrap(); - - return treeTrainer.growTree(bootstrappedData, treeCovariates); + return treeTrainer.growTree(bootstrappedData); } - public void saveTree(final Node tree, String name) throws IOException { + public void saveTree(final Node tree, String name) throws IOException { final String filename = saveTreeLocation + "/" + name; final ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(filename)); @@ -184,9 +177,9 @@ public class ForestTrainer { private final Bootstrapper> bootstrapper; private final int treeIndex; - private final List> treeList; + private final List> treeList; - public TreeInMemoryWorker(final List> data, final int treeIndex, final List> treeList) { + public TreeInMemoryWorker(final List> data, final int treeIndex, final List> treeList) { this.bootstrapper = new Bootstrapper<>(data); this.treeIndex = treeIndex; this.treeList = treeList; @@ -195,7 +188,7 @@ public class ForestTrainer { @Override public void run() { - final Node tree = trainTree(bootstrapper); + final Node tree = trainTree(bootstrapper); // should be okay as the list structure isn't changing treeList.set(treeIndex, tree); @@ -218,7 +211,7 @@ public class ForestTrainer { @Override public void run() { - final Node tree = trainTree(bootstrapper); + final Node tree = trainTree(bootstrapper); try { saveTree(tree, filename); diff --git a/src/main/java/ca/joeltherrien/randomforest/tree/GroupDifferentiator.java b/src/main/java/ca/joeltherrien/randomforest/tree/GroupDifferentiator.java index bb67a95..cbd1247 100644 --- a/src/main/java/ca/joeltherrien/randomforest/tree/GroupDifferentiator.java +++ b/src/main/java/ca/joeltherrien/randomforest/tree/GroupDifferentiator.java @@ -1,10 +1,6 @@ package ca.joeltherrien.randomforest.tree; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import java.util.HashMap; import java.util.List; -import java.util.Map; /** * When choosing an optimal node to split on, we choose the split that maximizes the difference between the two groups. @@ -16,11 +12,4 @@ public interface GroupDifferentiator { Double differentiate(List leftHand, List rightHand); - @FunctionalInterface - interface GroupDifferentiatorConstructor{ - - GroupDifferentiator construct(ObjectNode node); - - } - } diff --git a/src/main/java/ca/joeltherrien/randomforest/tree/ResponseCombiner.java b/src/main/java/ca/joeltherrien/randomforest/tree/ResponseCombiner.java index 8c3eab6..20a3239 100644 --- a/src/main/java/ca/joeltherrien/randomforest/tree/ResponseCombiner.java +++ b/src/main/java/ca/joeltherrien/randomforest/tree/ResponseCombiner.java @@ -1,20 +1,9 @@ package ca.joeltherrien.randomforest.tree; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.stream.Collector; -public interface ResponseCombiner extends Collector { +public interface ResponseCombiner { - Y combine(List responses); - - final static Map RESPONSE_COMBINER_MAP = new HashMap<>(); - static ResponseCombiner loadResponseCombinerByName(final String name){ - return RESPONSE_COMBINER_MAP.get(name); - } - static void registerResponseCombiner(final String name, final ResponseCombiner responseCombiner){ - RESPONSE_COMBINER_MAP.put(name, responseCombiner); - } + O combine(List responses); } diff --git a/src/main/java/ca/joeltherrien/randomforest/tree/TreeTrainer.java b/src/main/java/ca/joeltherrien/randomforest/tree/TreeTrainer.java index 9fb0eaf..5bcf510 100644 --- a/src/main/java/ca/joeltherrien/randomforest/tree/TreeTrainer.java +++ b/src/main/java/ca/joeltherrien/randomforest/tree/TreeTrainer.java @@ -7,13 +7,14 @@ import lombok.AllArgsConstructor; import lombok.Builder; import java.util.*; +import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Collectors; @Builder @AllArgsConstructor(access = AccessLevel.PRIVATE) -public class TreeTrainer { +public class TreeTrainer { - private final ResponseCombiner responseCombiner; + private final ResponseCombiner responseCombiner; private final GroupDifferentiator groupDifferentiator; /** @@ -23,54 +24,76 @@ public class TreeTrainer { private final int numberOfSplits; private final int nodeSize; private final int maxNodeDepth; + private final int mtry; - public TreeTrainer(final Settings settings){ + private final List covariates; + + public TreeTrainer(final Settings settings, final List covariates){ this.numberOfSplits = settings.getNumberOfSplits(); this.nodeSize = settings.getNodeSize(); this.maxNodeDepth = settings.getMaxNodeDepth(); + this.mtry = settings.getMtry(); - this.responseCombiner = ResponseCombiner.loadResponseCombinerByName(settings.getResponseCombiner()); + this.responseCombiner = settings.getResponseCombiner(); this.groupDifferentiator = settings.getGroupDifferentiator(); + this.covariates = covariates; } - public Node growTree(List> data, List covariatesToTry){ - return growNode(data, covariatesToTry, 0); + public Node growTree(List> data){ + return growNode(data, 0); } - private Node growNode(List> data, List covariatesToTry, int depth){ + private Node growNode(List> data, int depth){ // TODO; what is minimum per tree? if(data.size() >= 2*nodeSize && depth < maxNodeDepth && !nodeIsPure(data)){ + final List covariatesToTry = selectCovariates(this.mtry); final Covariate.SplitRule bestSplitRule = findBestSplitRule(data, covariatesToTry); if(bestSplitRule == null){ - return new TerminalNode<>( - data.stream() - .map(row -> row.getResponse()) - .collect(responseCombiner) + return new TerminalNode<>( + responseCombiner.combine( + data.stream().map(row -> row.getResponse()).collect(Collectors.toList()) + ) ); + + } final Split split = bestSplitRule.applyRule(data); // TODO optimize this as we're duplicating work done in findBestSplitRule - final Node leftNode = growNode(split.leftHand, covariatesToTry, depth+1); - final Node rightNode = growNode(split.rightHand, covariatesToTry, depth+1); + final Node leftNode = growNode(split.leftHand, depth+1); + final Node rightNode = growNode(split.rightHand, depth+1); return new SplitNode<>(leftNode, rightNode, bestSplitRule); } else{ return new TerminalNode<>( - data.stream() - .map(row -> row.getResponse()) - .collect(responseCombiner) - + responseCombiner.combine( + data.stream().map(row -> row.getResponse()).collect(Collectors.toList()) + ) ); } } + private List selectCovariates(int mtry){ + if(mtry >= covariates.size()){ + return covariates; + } + + final List splitCovariates = new ArrayList<>(covariates); + Collections.shuffle(splitCovariates, ThreadLocalRandom.current()); + + for(int treeIndex = splitCovariates.size()-1; treeIndex >= mtry; treeIndex--){ + splitCovariates.remove(treeIndex); + } + + return splitCovariates; + } + private Covariate.SplitRule findBestSplitRule(List> data, List covariatesToTry){ Covariate.SplitRule bestSplitRule = null; double bestSplitScore = 0.0; @@ -96,7 +119,9 @@ public class TreeTrainer { possibleSplit.rightHand.stream().map(row -> row.getResponse()).collect(Collectors.toList()) ); - if(score != null && (score > bestSplitScore || first)){ + + + if(score != null && !Double.isNaN(score) && (score > bestSplitScore || first)){ bestSplitRule = possibleRule; bestSplitScore = score; first = false; diff --git a/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRisk.R b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRisk.R new file mode 100644 index 0000000..02dbe81 --- /dev/null +++ b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRisk.R @@ -0,0 +1,99 @@ +# Comparing output between my two packages + +require(survival) +require(randomForestSRC) + +data(wihs, package = "randomForestSRC") + +wihs$idu = as.logical(wihs$idu) +wihs$black = as.logical(wihs$black) + +set.seed(100) + +wihs = wihs[sample(1:nrow(wihs), replace = FALSE),] + +# example row +# time status ageatfda idu black cd4nadir +#409 1.3 1 35 FALSE FALSE 0.81 +newData = data.frame(ageatfda=35, idu=FALSE, black=FALSE, cd4nadir=0.81) + +one.tree <- rfsrc(Surv(time, status) ~ idu + black, wihs, nsplit = 5, ntree = 1, splitrule="logrank", cause=1, mtry=2, seed=-5, membership=TRUE) +# next get membership +membership=one.tree$inbag[,1] + +if(FALSE){ + bootstrappedData = wihs[c(),] + for(i in 1:length(membership)){ + times = membership[i] + + if(times > 0){ + for(j in 1:times){ + bootstrappedData = rbind(bootstrappedData, wihs[i,]) + } + + } + } +} +output.one.tree = predict(one.tree, newData) +output.one.tree$cif[,,1] +output.one.tree$chf[,c(11,66,103),1] + +# Note that "... ~ ." means 'use all explanatory variables" +#output = predict(wihs.obj, newData) +#output$cif[,,1] # CIF for cause 1 +#output$cif[,,2] # CIF for cause 2 + +many.trees <- rfsrc(Surv(time, status) ~ idu + black, wihs, nsplit = 5, ntree = 100, splitrule="logrank", cause=1, mtry=2, membership=TRUE) +output.many.trees = predict(many.trees, newData) +output.many.trees$cif[,41,1] +output.many.trees$cif[,41,2] + +many.trees.all <- rfsrc(Surv(time, status) ~ ageatfda + cd4nadir + idu + black, wihs, nsplit = 5, ntree = 100, splitrule="logrank", cause=1, mtry=2, membership=TRUE) +output.many.trees.all = predict(many.trees.all, newData) +output.many.trees.all$cif[,103,1] +output.many.trees.all$cif[,103,2] + + + + + +end.numbers = c() +end.times = c() +lgths = c() +trees = list() +for(i in 1:100){ + one.tree = rfsrc(Surv(time, status) ~ ageatfda + cd4nadir + idu + black, wihs, nsplit = 0, ntree = 1, splitrule="logrank", cause=1, mtry=4, membership=TRUE, statistics = TRUE) + trees[[i]] = one.tree + prediction = predict(one.tree, newData) + lgth = length(prediction$cif[,,1]) + lgths = c(lgths, lgth) + end.numbers = c(end.numbers, prediction$cif[,lgth,1]) + end.times = c(end.times, max(prediction$time.interest)) +} + +special.tree = trees[[100]] + + +prediction = predict(special.tree, newData) +prediction$cif[,,1] + + + + + + +membership = special.tree$inbag[,1] +bootstrappedData = wihs[c(),] +for(i in 1:length(membership)){ + times = membership[i] + + if(times > 0){ + for(j in 1:times){ + bootstrappedData = rbind(bootstrappedData, wihs[i,]) + } + + } +} +write.csv(bootstrappedData, "RandomSurvivalForests/src/test/resources/wihs.bootstrapped2.csv", row.names=FALSE) +prediction$cif[,,1] + diff --git a/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRisk.java b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRisk.java new file mode 100644 index 0000000..320c077 --- /dev/null +++ b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRisk.java @@ -0,0 +1,325 @@ +package ca.joeltherrien.randomforest.competingrisk; + +import ca.joeltherrien.randomforest.*; +import ca.joeltherrien.randomforest.covariates.*; +import ca.joeltherrien.randomforest.responses.competingrisk.CompetingRiskFunctions; +import ca.joeltherrien.randomforest.responses.competingrisk.CompetingRiskResponse; +import ca.joeltherrien.randomforest.responses.competingrisk.MathFunction; +import ca.joeltherrien.randomforest.responses.competingrisk.Point; +import ca.joeltherrien.randomforest.tree.Forest; +import ca.joeltherrien.randomforest.tree.ForestTrainer; +import ca.joeltherrien.randomforest.tree.Node; +import ca.joeltherrien.randomforest.tree.TreeTrainer; +import com.fasterxml.jackson.databind.node.*; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; + +public class TestCompetingRisk { + + + /** + * By default uses single log-rank test. + * + * @return + */ + public Settings getSettings(){ + final ObjectNode groupDifferentiatorSettings = new ObjectNode(JsonNodeFactory.instance); + groupDifferentiatorSettings.set("type", new TextNode("LogRankSingleGroupDifferentiator")); + groupDifferentiatorSettings.set("eventOfFocus", new IntNode(1)); + + final ObjectNode responseCombinerSettings = new ObjectNode(JsonNodeFactory.instance); + responseCombinerSettings.set("type", new TextNode("CompetingRiskResponseCombiner")); + responseCombinerSettings.set("events", + new ArrayNode(JsonNodeFactory.instance, List.of(new IntNode(1), new IntNode(2))) + ); + // not setting times + + + final ObjectNode treeCombinerSettings = new ObjectNode(JsonNodeFactory.instance); + treeCombinerSettings.set("type", new TextNode("CompetingRiskFunctionCombiner")); + treeCombinerSettings.set("events", + new ArrayNode(JsonNodeFactory.instance, List.of(new IntNode(1), new IntNode(2))) + ); + // not setting times + + final ObjectNode yVarSettings = new ObjectNode(JsonNodeFactory.instance); + yVarSettings.set("type", new TextNode("CompetingRiskResponse")); + yVarSettings.set("u", new TextNode("time")); + yVarSettings.set("delta", new TextNode("status")); + + return Settings.builder() + .covariates(List.of( + new NumericCovariateSettings("ageatfda"), + new BooleanCovariateSettings("idu"), + new BooleanCovariateSettings("black"), + new NumericCovariateSettings("cd4nadir") + ) + ) + .dataFileLocation("src/test/resources/wihs.csv") + .responseCombinerSettings(responseCombinerSettings) + .treeCombinerSettings(treeCombinerSettings) + .groupDifferentiatorSettings(groupDifferentiatorSettings) + .yVarSettings(yVarSettings) + .maxNodeDepth(100000) + // TODO fill in these settings + .mtry(2) + .nodeSize(6) + .ntree(100) + .numberOfSplits(5) + .numberOfThreads(3) + .saveProgress(true) + .saveTreeLocation("trees/") + .build(); + } + + public CovariateRow getPredictionRow(List covariates){ + return CovariateRow.createSimple(Map.of( + "ageatfda", "35", + "idu", "false", + "black", "false", + "cd4nadir", "0.81") + , covariates, 1); + } + + @Test + public void testSingleTree() throws IOException { + final Settings settings = getSettings(); + settings.setDataFileLocation("src/test/resources/wihs.bootstrapped.csv"); + settings.setCovariates(List.of( + new BooleanCovariateSettings("idu"), + new BooleanCovariateSettings("black") + )); // by only using BooleanCovariates (only one split rule) we can guarantee identical results with randomForestSRC on one tree. + + final List covariates = getCovariates(settings); + + final List> dataset = DataLoader.loadData(covariates, settings.getResponseLoader(), settings.getDataFileLocation()); + + final TreeTrainer treeTrainer = new TreeTrainer<>(settings, covariates); + final Node node = treeTrainer.growTree(dataset); + + final CovariateRow newRow = getPredictionRow(covariates); + + final CompetingRiskFunctions functions = node.evaluate(newRow); + + final MathFunction causeOneCIFFunction = functions.getCumulativeIncidenceFunction(1); + final MathFunction causeTwoCIFFunction = functions.getCumulativeIncidenceFunction(2); + final MathFunction cumHazOneFunction = functions.getCauseSpecificHazardFunction(1); + final MathFunction cumHazTwoFunction = functions.getCauseSpecificHazardFunction(2); + + final double margin = 0.0000001; + closeEnough(0.003003003, causeOneCIFFunction.evaluate(0.02).getY(), margin); + closeEnough(0.166183852, causeOneCIFFunction.evaluate(1.00).getY(), margin); + closeEnough(0.715625487, causeOneCIFFunction.evaluate(6.50).getY(), margin); + closeEnough(0.794796334, causeOneCIFFunction.evaluate(10.60).getY(), margin); + closeEnough(0.794796334, causeOneCIFFunction.evaluate(10.80).getY(), margin); + + + closeEnough(0.08149211, causeTwoCIFFunction.evaluate(1.00).getY(), margin); + closeEnough(0.14926318, causeTwoCIFFunction.evaluate(6.50).getY(), margin); + closeEnough(0.15332850, causeTwoCIFFunction.evaluate(10.80).getY(), margin); + + + closeEnough(0.1888601, cumHazOneFunction.evaluate(1.00).getY(), margin); + closeEnough(1.6189759, cumHazOneFunction.evaluate(6.50).getY(), margin); + closeEnough(2.4878342, cumHazOneFunction.evaluate(10.80).getY(), margin); + + + closeEnough(0.08946513, cumHazTwoFunction.evaluate(1.00).getY(), margin); + closeEnough(0.32801830, cumHazTwoFunction.evaluate(6.50).getY(), margin); + closeEnough(0.36505534, cumHazTwoFunction.evaluate(10.80).getY(), margin); + + + } + + /** + * Note - this test triggers a situation where the variance calculation in the log-rank test experiences an NaN. + * + * @throws IOException + */ + @Test + public void testSingleTree2() throws IOException { + final Settings settings = getSettings(); + settings.setMtry(4); + settings.setNumberOfSplits(0); + settings.setDataFileLocation("src/test/resources/wihs.bootstrapped2.csv"); + + final List covariates = getCovariates(settings); + + final List> dataset = DataLoader.loadData(covariates, settings.getResponseLoader(), settings.getDataFileLocation()); + + final TreeTrainer treeTrainer = new TreeTrainer<>(settings, covariates); + final Node node = treeTrainer.growTree(dataset); + + final CovariateRow newRow = getPredictionRow(covariates); + + final CompetingRiskFunctions functions = node.evaluate(newRow); + + final MathFunction causeOneCIFFunction = functions.getCumulativeIncidenceFunction(1); + final MathFunction causeTwoCIFFunction = functions.getCumulativeIncidenceFunction(2); + final MathFunction cumHazOneFunction = functions.getCauseSpecificHazardFunction(1); + final MathFunction cumHazTwoFunction = functions.getCauseSpecificHazardFunction(2); + + + final double margin = 0.0000001; + closeEnough(0, causeOneCIFFunction.evaluate(0.02).getY(), margin); + closeEnough(0.555555555, causeOneCIFFunction.evaluate(0.4).getY(), margin); + closeEnough(0.66666666666, causeOneCIFFunction.evaluate(0.8).getY(), margin); + closeEnough(0.88888888888, causeOneCIFFunction.evaluate(0.9).getY(), margin); + closeEnough(1.0, causeOneCIFFunction.evaluate(1.0).getY(), margin); + + /* + closeEnough(0.08149211, causeTwoCIFFunction.evaluate(1.00).getY(), margin); + closeEnough(0.14926318, causeTwoCIFFunction.evaluate(6.50).getY(), margin); + closeEnough(0.15332850, causeTwoCIFFunction.evaluate(10.80).getY(), margin); + + + closeEnough(0.1888601, cumHazOneFunction.evaluate(1.00).getY(), margin); + closeEnough(1.6189759, cumHazOneFunction.evaluate(6.50).getY(), margin); + closeEnough(2.4878342, cumHazOneFunction.evaluate(10.80).getY(), margin); + + + closeEnough(0.08946513, cumHazTwoFunction.evaluate(1.00).getY(), margin); + closeEnough(0.32801830, cumHazTwoFunction.evaluate(6.50).getY(), margin); + closeEnough(0.36505534, cumHazTwoFunction.evaluate(10.80).getY(), margin); + */ + + } + + public List getCovariates(Settings settings){ + return settings.getCovariates().stream().map(covariateSettings -> covariateSettings.build()).collect(Collectors.toList()); + } + + @Test + public void testLogRankSingleGroupDifferentiatorTwoBooleans() throws IOException { + final Settings settings = getSettings(); + settings.setCovariates(List.of( + new BooleanCovariateSettings("idu"), + new BooleanCovariateSettings("black") + )); + + final List covariates = getCovariates(settings); + + final List> dataset = DataLoader.loadData(covariates, settings.getResponseLoader(), settings.getDataFileLocation()); + + final ForestTrainer forestTrainer = new ForestTrainer<>(settings, dataset, covariates); + + final Forest forest = forestTrainer.trainSerial(); + + // prediction row + // time status ageatfda idu black cd4nadir + //409 1.3 1 35 FALSE FALSE 0.81 + final CovariateRow newRow = getPredictionRow(covariates); + + final CompetingRiskFunctions functions = forest.evaluate(newRow); + + assertCumulativeFunction(functions.getCauseSpecificHazardFunction(1)); + assertCumulativeFunction(functions.getCauseSpecificHazardFunction(2)); + assertCumulativeFunction(functions.getCumulativeIncidenceFunction(1)); + assertCumulativeFunction(functions.getCumulativeIncidenceFunction(2)); + + + closeEnough(0.63, functions.getCumulativeIncidenceFunction(1).evaluate(4.0).getY(), 0.01); + closeEnough(0.765, functions.getCumulativeIncidenceFunction(1).evaluate(10.8).getY(), 0.01); + + closeEnough(0.163, functions.getCumulativeIncidenceFunction(2).evaluate(4.0).getY(), 0.01); + closeEnough(0.195, functions.getCumulativeIncidenceFunction(2).evaluate(10.8).getY(), 0.01); + } + + @Test + public void verifyDataset() throws IOException { + final Settings settings = getSettings(); + + final List covariates = getCovariates(settings); + + final List> dataset = DataLoader.loadData(covariates, settings.getResponseLoader(), settings.getDataFileLocation()); + + // Let's count the events and make sure the data was correctly read. + int countCensored = 0; + int countEventOne = 0; + int countEventTwo = 0; + for(final Row row : dataset){ + final CompetingRiskResponse response = row.getResponse(); + + if(response.getDelta() == 0){ + countCensored++; + } + else if(response.getDelta() == 1){ + countEventOne++; + } + else if(response.getDelta() == 2){ + countEventTwo++; + } + else{ + throw new RuntimeException("There's an event of type " + response.getDelta()); + } + + } + + assertEquals(126, countCensored); + assertEquals(679, countEventOne); + assertEquals(359, countEventTwo); + } + + @Test + public void testLogRankSingleGroupDifferentiatorAllCovariates() throws IOException { + + final Settings settings = getSettings(); + + final List covariates = getCovariates(settings); + final List> dataset = DataLoader.loadData(covariates, settings.getResponseLoader(), settings.getDataFileLocation()); + final ForestTrainer forestTrainer = new ForestTrainer<>(settings, dataset, covariates); + final Forest forest = forestTrainer.trainSerial(); + + // prediction row + // time status ageatfda idu black cd4nadir + //409 1.3 1 35 FALSE FALSE 0.81 + final CovariateRow newRow = getPredictionRow(covariates); + + final CompetingRiskFunctions functions = forest.evaluate(newRow); + + assertCumulativeFunction(functions.getCauseSpecificHazardFunction(1)); + assertCumulativeFunction(functions.getCauseSpecificHazardFunction(2)); + assertCumulativeFunction(functions.getCumulativeIncidenceFunction(1)); + assertCumulativeFunction(functions.getCumulativeIncidenceFunction(2)); + + final List causeOneCIFPoints = functions.getCumulativeIncidenceFunction(1).getPoints(); + + // We seem to consistently underestimate the results. + assertTrue(causeOneCIFPoints.get(causeOneCIFPoints.size()-1).getY() > 0.75, "Results should match randomForestSRC"); + + + } + + /** + * We know the function is cumulative; make sure it is ordered correctly and that that function is monotone. + * + * @param function + */ + private void assertCumulativeFunction(MathFunction function){ + Point previousPoint = null; + for(final Point point : function.getPoints()){ + + if(previousPoint != null){ + assertTrue(previousPoint.getTime() < point.getTime(), "Points should be ordered and strictly different"); + assertTrue(previousPoint.getY() <= point.getY(), "Cumulative incidence functions are monotone"); + } + + + previousPoint = point; + } + } + + private void closeEnough(double expected, double actual, double margin){ + assertTrue(Math.abs(expected - actual) < margin, "Expected " + expected + " but saw " + actual); + } + +} diff --git a/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRiskResponseCombiner.R b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRiskResponseCombiner.R new file mode 100644 index 0000000..ae73c3a --- /dev/null +++ b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRiskResponseCombiner.R @@ -0,0 +1,12 @@ +testData = data.frame(delta=c(1,1,1,2,2,0,0), u=c(1,1,2,1.5,2,1.5,2.5)) +testData$survDelta = ifelse(testData$delta==0, 0, 1) # for KM curves on any events + +require(survival) + +kmCurve = survfit(Surv(u, survDelta, type="right") ~ 1, data=testData) +kmCurve$surv + +curve = survfit(Surv(u, event=delta, type="mstate") ~ 1, data=testData) +curve$cumhaz[3,1:2,] + +print(t(curve$pstate[,1:2])) diff --git a/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRiskResponseCombiner.java b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRiskResponseCombiner.java new file mode 100644 index 0000000..cdbd10b --- /dev/null +++ b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestCompetingRiskResponseCombiner.java @@ -0,0 +1,94 @@ +package ca.joeltherrien.randomforest.competingrisk; + +import ca.joeltherrien.randomforest.responses.competingrisk.CompetingRiskFunctions; +import ca.joeltherrien.randomforest.responses.competingrisk.CompetingRiskResponse; +import ca.joeltherrien.randomforest.responses.competingrisk.CompetingRiskResponseCombiner; +import ca.joeltherrien.randomforest.responses.competingrisk.MathFunction; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.ArrayList; +import java.util.List; + +public class TestCompetingRiskResponseCombiner { + + private CompetingRiskFunctions generateFunctions(){ + final List data = new ArrayList<>(); + + data.add(new CompetingRiskResponse(1, 1.0)); + data.add(new CompetingRiskResponse(1, 1.0)); + data.add(new CompetingRiskResponse(1, 2.0)); + data.add(new CompetingRiskResponse(2, 1.5)); + data.add(new CompetingRiskResponse(2, 2.0)); + data.add(new CompetingRiskResponse(0, 1.5)); + data.add(new CompetingRiskResponse(0, 2.5)); + + final CompetingRiskResponseCombiner combiner = new CompetingRiskResponseCombiner(new int[]{1,2}, null); + + final CompetingRiskFunctions functions = combiner.combine(data); + + return functions; + } + + @Test + public void testCompetingRiskResponseCombiner(){ + final CompetingRiskFunctions functions = generateFunctions(); + + final MathFunction survivalCurve = functions.getSurvivalCurve(); + + // time = 1.0 1.5 2.0 2.5 + // surv = 0.7142857 0.5714286 0.1904762 0.1904762 + + final double margin = 0.0000001; + + closeEnough(0.7142857, survivalCurve.evaluate(1.0).getY(), margin); + closeEnough(0.5714286, survivalCurve.evaluate(1.5).getY(), margin); + closeEnough(0.1904762, survivalCurve.evaluate(2.0).getY(), margin); + closeEnough(0.1904762, survivalCurve.evaluate(2.5).getY(), margin); + + + // Time = 1.0 1.5 2.0 2.5 + /* Cumulative hazard function. Each row for one event. + [,1] [,2] [,3] [,4] + [1,] 0.2857143 0.2857143 0.6190476 0.6190476 + [2,] 0.0000000 0.2000000 0.5333333 0.5333333 + */ + + final MathFunction cumHaz1 = functions.getCauseSpecificHazardFunction(1); + closeEnough(0.2857143, cumHaz1.evaluate(1.0).getY(), margin); + closeEnough(0.2857143, cumHaz1.evaluate(1.5).getY(), margin); + closeEnough(0.6190476, cumHaz1.evaluate(2.0).getY(), margin); + closeEnough(0.6190476, cumHaz1.evaluate(2.5).getY(), margin); + + final MathFunction cumHaz2 = functions.getCauseSpecificHazardFunction(2); + closeEnough(0.0, cumHaz2.evaluate(1.0).getY(), margin); + closeEnough(0.2, cumHaz2.evaluate(1.5).getY(), margin); + closeEnough(0.5333333, cumHaz2.evaluate(2.0).getY(), margin); + closeEnough(0.5333333, cumHaz2.evaluate(2.5).getY(), margin); + + /* Time = 1.0 1.5 2.0 2.5 + Cumulative Incidence Curve. Each row for one event. + [,1] [,2] [,3] [,4] + [1,] 0.2857143 0.2857143 0.4761905 0.4761905 + [2,] 0.0000000 0.1428571 0.3333333 0.3333333 + */ + + final MathFunction cic1 = functions.getCumulativeIncidenceFunction(1); + closeEnough(0.2857143, cic1.evaluate(1.0).getY(), margin); + closeEnough(0.2857143, cic1.evaluate(1.5).getY(), margin); + closeEnough(0.4761905, cic1.evaluate(2.0).getY(), margin); + closeEnough(0.4761905, cic1.evaluate(2.5).getY(), margin); + + final MathFunction cic2 = functions.getCumulativeIncidenceFunction(2); + closeEnough(0.0, cic2.evaluate(1.0).getY(), margin); + closeEnough(0.1428571, cic2.evaluate(1.5).getY(), margin); + closeEnough(0.3333333, cic2.evaluate(2.0).getY(), margin); + closeEnough(0.3333333, cic2.evaluate(2.5).getY(), margin); + + } + + private void closeEnough(double expected, double actual, double margin){ + assertTrue(Math.abs(expected - actual) < margin, "Expected " + expected + " but saw " + actual); + } + +} diff --git a/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestLogRankSingleGroupDifferentiator.R b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestLogRankSingleGroupDifferentiator.R new file mode 100644 index 0000000..17429dd --- /dev/null +++ b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestLogRankSingleGroupDifferentiator.R @@ -0,0 +1,62 @@ +testData1 = data.frame(delta=c(1,1,1,1,0,0,0), u=c(1,1,2,1.5,2,1.5,2.5), group=TRUE) +testData2 = data.frame(delta=c(1,1,1,1,0,0,0), u=c(2,2,4,3,4,3,5), group=FALSE) # just doubled everything + +testData = rbind(testData1, testData2) +require(survival) + +results = survdiff(Surv(u, delta, type="right") ~ group, data=testData) + +mantelTest = function(times, observed, group0, group1=!group0){ + U0 = times[group0] + observed0 = observed[group0] + U1 = times[group1] + observed1 = observed[group1] + + Vs = sort(unique(c(U0[observed0], U1[observed1]))) + + atRisk = function(v, u){ + u = subset(u, u >= v) + return(length(u)) + } + + Os = c() + Es = c() + varOs = c() + + # we're going to treat group 1 as treatment + for(v in Vs){ + placeboAtRisk = atRisk(v, U0) + treatmentAtRisk = atRisk(v, U1) + totalAtRisk = placeboAtRisk + treatmentAtRisk + + numTreatmentFailures = length(subset(U1, observed1 & U1 == v)) + numPlaceboFailures = length(subset(U0, observed0 & U0 == v)) + totalFailures = numTreatmentFailures + numPlaceboFailures + + Os = c(Os, numTreatmentFailures) + Es = c(Es, (totalFailures)*treatmentAtRisk/totalAtRisk) + + varOfO = (totalAtRisk - treatmentAtRisk)/(totalAtRisk - 1) * + treatmentAtRisk * (totalFailures / totalAtRisk) * + (1 - totalFailures / totalAtRisk) + + if(totalAtRisk == 1){ + varOfO = 0 + } + + varOs = c(varOs, varOfO) + } + + numerator = sum(Os - Es) + variance = sum(varOs) + + Z = numerator/sqrt(variance) + return(list( + statistic = Z, + pvalue = 2*pnorm(abs(Z), lower.tail=FALSE), + numerator = numerator, + variance = variance + )) +} + +myTest = mantelTest(testData$u, testData$delta == 1, group0=testData$group==1) diff --git a/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestLogRankSingleGroupDifferentiator.java b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestLogRankSingleGroupDifferentiator.java new file mode 100644 index 0000000..c8e7090 --- /dev/null +++ b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestLogRankSingleGroupDifferentiator.java @@ -0,0 +1,61 @@ +package ca.joeltherrien.randomforest.competingrisk; + +import ca.joeltherrien.randomforest.responses.competingrisk.*; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TestLogRankSingleGroupDifferentiator { + + private List generateData1(){ + final List data = new ArrayList<>(); + + data.add(new CompetingRiskResponse(1, 1.0)); + data.add(new CompetingRiskResponse(1, 1.0)); + data.add(new CompetingRiskResponse(1, 2.0)); + data.add(new CompetingRiskResponse(1, 1.5)); + data.add(new CompetingRiskResponse(0, 2.0)); + data.add(new CompetingRiskResponse(0, 1.5)); + data.add(new CompetingRiskResponse(0, 2.5)); + + return data; + } + + private List generateData2(){ + final List data = new ArrayList<>(); + + data.add(new CompetingRiskResponse(1, 2.0)); + data.add(new CompetingRiskResponse(1, 2.0)); + data.add(new CompetingRiskResponse(1, 4.0)); + data.add(new CompetingRiskResponse(1, 3.0)); + data.add(new CompetingRiskResponse(0, 4.0)); + data.add(new CompetingRiskResponse(0, 3.0)); + data.add(new CompetingRiskResponse(0, 5.0)); + + return data; + } + + @Test + public void testCompetingRiskResponseCombiner(){ + final List data1 = generateData1(); + final List data2 = generateData2(); + + final LogRankSingleGroupDifferentiator differentiator = new LogRankSingleGroupDifferentiator(1); + + final double score = differentiator.differentiate(data1, data2); + final double margin = 0.000001; + + // Tested using 855 method + closeEnough(1.540139, score, margin); + + + } + + private void closeEnough(double expected, double actual, double margin){ + assertTrue(Math.abs(expected - actual) < margin, "Expected " + expected + " but saw " + actual); + } + +} diff --git a/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestMathFunction.java b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestMathFunction.java new file mode 100644 index 0000000..a602e73 --- /dev/null +++ b/src/test/java/ca/joeltherrien/randomforest/competingrisk/TestMathFunction.java @@ -0,0 +1,43 @@ +package ca.joeltherrien.randomforest.competingrisk; + +import ca.joeltherrien.randomforest.responses.competingrisk.MathFunction; +import ca.joeltherrien.randomforest.responses.competingrisk.Point; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.ArrayList; +import java.util.List; + +public class TestMathFunction { + + private MathFunction generateMathFunction(){ + final double[] time = new double[]{1.0, 2.0, 3.0}; + final double[] y = new double[]{-1.0, 1.0, 0.5}; + + final List pointList = new ArrayList<>(); + for(int i=0; i treeTrainer = TreeTrainer.builder() + final TreeTrainer treeTrainer = TreeTrainer.builder() .numberOfSplits(5) .nodeSize(5) .maxNodeDepth(100000000) @@ -59,10 +59,10 @@ public class TrainForest { .responseCombiner(new MeanResponseCombiner()) .build(); - final ForestTrainer forestTrainer = ForestTrainer.builder() + final ForestTrainer forestTrainer = ForestTrainer.builder() .treeTrainer(treeTrainer) .data(data) - .covariatesToTry(covariateList) + .covariates(covariateList) .mtry(4) .ntree(100) .treeResponseCombiner(new MeanResponseCombiner()) diff --git a/src/test/java/ca/joeltherrien/randomforest/workshop/TrainSingleTree.java b/src/test/java/ca/joeltherrien/randomforest/workshop/TrainSingleTree.java index dec417e..3c3234e 100644 --- a/src/test/java/ca/joeltherrien/randomforest/workshop/TrainSingleTree.java +++ b/src/test/java/ca/joeltherrien/randomforest/workshop/TrainSingleTree.java @@ -48,18 +48,20 @@ public class TrainSingleTree { trainingSet.add(generateRow(x1, x2, i)); } - final TreeTrainer treeTrainer = TreeTrainer.builder() + final List covariateNames = List.of(x1Covariate, x2Covariate); + + final TreeTrainer treeTrainer = TreeTrainer.builder() .groupDifferentiator(new WeightedVarianceGroupDifferentiator()) + .covariates(covariateNames) .responseCombiner(new MeanResponseCombiner()) .maxNodeDepth(30) .nodeSize(5) .numberOfSplits(0) .build(); - final List covariateNames = List.of(x1Covariate, x2Covariate); final long startTime = System.currentTimeMillis(); - final Node baseNode = treeTrainer.growTree(trainingSet, covariateNames); + final Node baseNode = treeTrainer.growTree(trainingSet); final long endTime = System.currentTimeMillis(); System.out.println(((double)(endTime - startTime))/1000.0); diff --git a/src/test/java/ca/joeltherrien/randomforest/workshop/TrainSingleTreeFactor.java b/src/test/java/ca/joeltherrien/randomforest/workshop/TrainSingleTreeFactor.java index 9b30229..dd719fc 100644 --- a/src/test/java/ca/joeltherrien/randomforest/workshop/TrainSingleTreeFactor.java +++ b/src/test/java/ca/joeltherrien/randomforest/workshop/TrainSingleTreeFactor.java @@ -69,18 +69,21 @@ public class TrainSingleTreeFactor { trainingSet.add(generateRow(x1, x2, x3, i)); } - final TreeTrainer treeTrainer = TreeTrainer.builder() + final List covariateNames = List.of(x1Covariate, x2Covariate); + + final TreeTrainer treeTrainer = TreeTrainer.builder() .groupDifferentiator(new WeightedVarianceGroupDifferentiator()) .responseCombiner(new MeanResponseCombiner()) + .covariates(covariateNames) .maxNodeDepth(30) .nodeSize(5) .numberOfSplits(5) .build(); - final List covariateNames = List.of(x1Covariate, x2Covariate); + final long startTime = System.currentTimeMillis(); - final Node baseNode = treeTrainer.growTree(trainingSet, covariateNames); + final Node baseNode = treeTrainer.growTree(trainingSet); final long endTime = System.currentTimeMillis(); System.out.println(((double)(endTime - startTime))/1000.0); diff --git a/src/test/resources/wihs.bootstrapped.csv b/src/test/resources/wihs.bootstrapped.csv new file mode 100644 index 0000000..a90fd84 --- /dev/null +++ b/src/test/resources/wihs.bootstrapped.csv @@ -0,0 +1,1165 @@ +"time","status","ageatfda","idu","black","cd4nadir" +1.2,1,52,FALSE,TRUE,4.21 +1.1,1,40,TRUE,TRUE,1.89 +0.4,0,46,TRUE,TRUE,3.04 +1.7,2,39,FALSE,TRUE,2.05 +1.8,1,24,FALSE,TRUE,4.55 +4.7,1,37,TRUE,TRUE,8.68 +4.7,1,37,TRUE,TRUE,8.68 +1.4,1,27,TRUE,FALSE,3.69 +2.1,1,30,FALSE,TRUE,5.17 +0.8,2,32,TRUE,FALSE,2.08 +0.8,2,32,TRUE,FALSE,2.08 +0.8,2,32,TRUE,FALSE,2.08 +0.8,2,32,TRUE,FALSE,2.08 +2.6,1,31,FALSE,TRUE,7.99 +2.6,1,31,FALSE,TRUE,7.99 +6.7,1,31,FALSE,TRUE,4 +1.5,1,33,FALSE,TRUE,3.96 +4,1,30,TRUE,FALSE,6.81 +3,2,42,TRUE,TRUE,3.79 +1.3,1,41,FALSE,FALSE,2.6 +3.2,1,43,TRUE,TRUE,1.32 +3.2,1,43,TRUE,TRUE,1.32 +3.3,1,39,FALSE,TRUE,1.49 +3.3,1,39,FALSE,TRUE,1.49 +2,1,30,FALSE,TRUE,3.22 +2,1,30,FALSE,TRUE,3.22 +3.7,1,46,TRUE,FALSE,1.33 +1.5,1,48,FALSE,TRUE,2.23 +1.5,1,48,FALSE,TRUE,2.23 +0.8,1,35,TRUE,FALSE,1.66 +0.8,1,35,TRUE,FALSE,1.66 +10.7,0,29,FALSE,FALSE,5.23 +10.7,0,29,FALSE,FALSE,5.23 +1.1,1,33,FALSE,FALSE,3.39 +1.8,1,24,FALSE,TRUE,3.36 +1.8,1,24,FALSE,TRUE,3.36 +1.3,2,34,TRUE,FALSE,5.18 +1.3,2,34,TRUE,FALSE,5.18 +1.3,2,34,TRUE,FALSE,5.18 +9.3,0,37,FALSE,TRUE,6.65 +3.1,1,35,FALSE,TRUE,1.98 +3.1,1,35,FALSE,TRUE,1.98 +3.1,1,35,FALSE,TRUE,1.98 +6.2,2,42,TRUE,FALSE,8.36 +0.8,1,50,TRUE,TRUE,3.24 +0.8,1,50,TRUE,TRUE,3.24 +2.5,1,33,FALSE,TRUE,6.64 +2.5,1,33,FALSE,TRUE,6.64 +2.5,1,33,FALSE,TRUE,6.64 +10.4,0,44,TRUE,TRUE,11.63 +10.4,0,44,TRUE,TRUE,11.63 +1.2,1,56,FALSE,TRUE,2.36 +5.3,2,45,FALSE,TRUE,1.72 +4.5,2,41,TRUE,FALSE,4.09 +4.5,2,41,TRUE,FALSE,4.09 +2.3,1,40,TRUE,TRUE,2.68 +2.3,1,40,TRUE,TRUE,2.68 +0.9,1,33,FALSE,FALSE,2.16 +1.2,1,39,TRUE,TRUE,4.97 +0.9,2,39,TRUE,TRUE,0.06 +0.9,2,39,TRUE,TRUE,0.06 +1,1,45,TRUE,TRUE,1.04 +2.2,1,29,FALSE,FALSE,2.85 +0.6,2,57,FALSE,FALSE,0.54 +1,1,31,FALSE,FALSE,0.93 +2.2,2,45,TRUE,TRUE,8.4 +1.6,1,33,FALSE,TRUE,2.2 +1.6,1,33,FALSE,TRUE,2.2 +2.5,1,29,FALSE,TRUE,4.89 +8.4,1,28,TRUE,FALSE,9.63 +2.8,2,39,TRUE,FALSE,4.13 +1.5,1,34,TRUE,TRUE,7.67 +1.5,1,34,TRUE,TRUE,7.67 +1.6,1,53,TRUE,TRUE,3.96 +2.9,1,51,TRUE,FALSE,4.76 +2.9,1,51,TRUE,FALSE,4.76 +1.4,1,35,FALSE,FALSE,2.88 +1.4,1,35,FALSE,FALSE,2.88 +1.4,1,35,FALSE,FALSE,2.88 +8.2,0,36,FALSE,FALSE,6.11 +10.7,0,28,FALSE,TRUE,5.62 +10.7,0,28,FALSE,TRUE,5.62 +4.6,1,33,TRUE,FALSE,8.78 +4.6,1,33,TRUE,FALSE,8.78 +4.6,1,33,TRUE,FALSE,8.78 +3.6,2,54,FALSE,TRUE,4.6 +3.6,2,54,FALSE,TRUE,4.6 +4.3,1,23,TRUE,TRUE,3.87 +4.3,1,23,TRUE,TRUE,3.87 +0.5,2,48,TRUE,TRUE,1.6 +1.6,1,40,FALSE,FALSE,5.35 +1.6,1,40,FALSE,FALSE,5.35 +2.2,2,39,FALSE,TRUE,3.44 +2.2,2,39,FALSE,TRUE,3.44 +2.2,2,39,FALSE,TRUE,3.44 +6,2,29,FALSE,TRUE,3.79 +8.7,1,31,TRUE,FALSE,4.84 +8.7,1,31,TRUE,FALSE,4.84 +10.5,0,49,FALSE,TRUE,5.33 +10.6,1,23,FALSE,FALSE,4.89 +3.1,1,27,FALSE,TRUE,2.54 +5.4,1,34,FALSE,FALSE,3.51 +5.4,1,34,FALSE,FALSE,3.51 +5.4,1,34,FALSE,FALSE,3.51 +0.9,1,35,FALSE,FALSE,4.85 +0.9,1,35,FALSE,FALSE,4.85 +1.3,1,41,TRUE,TRUE,2.02 +1.3,1,41,TRUE,TRUE,2.02 +1.5,2,44,TRUE,TRUE,1.76 +5.3,1,23,FALSE,FALSE,6.42 +5.3,1,23,FALSE,FALSE,6.42 +5.3,1,23,FALSE,FALSE,6.42 +1.4,2,27,FALSE,TRUE,2.58 +1.7,1,24,FALSE,TRUE,4.49 +1.7,1,24,FALSE,TRUE,4.49 +3.4,2,44,TRUE,FALSE,3.4 +3.4,2,44,TRUE,FALSE,3.4 +1.3,1,46,TRUE,TRUE,3.24 +0.3,2,31,TRUE,TRUE,6.29 +0.3,2,31,TRUE,TRUE,6.29 +2,1,22,FALSE,FALSE,2.84 +2,1,22,FALSE,FALSE,2.84 +2,1,22,FALSE,FALSE,2.84 +2.6,2,37,TRUE,TRUE,1.94 +7,2,45,TRUE,TRUE,2.52 +2.8,1,44,TRUE,FALSE,13.17 +2.8,1,44,TRUE,FALSE,13.17 +2.8,1,44,TRUE,FALSE,13.17 +1.8,2,42,TRUE,FALSE,1.66 +3.6,2,39,TRUE,FALSE,1.18 +0.4,1,36,FALSE,FALSE,2.75 +0.3,2,34,TRUE,TRUE,2 +10.2,0,32,FALSE,TRUE,2.9 +10.2,0,32,FALSE,TRUE,2.9 +0.9,1,37,FALSE,FALSE,0.52 +4,1,37,TRUE,TRUE,2.87 +9.3,1,26,FALSE,FALSE,2.52 +9.3,1,26,FALSE,FALSE,2.52 +1.3,1,29,FALSE,TRUE,4.85 +2,1,34,FALSE,TRUE,3.3 +0.2,2,39,FALSE,TRUE,0.41 +0.2,2,39,FALSE,TRUE,0.41 +7.3,1,29,FALSE,TRUE,10.67 +7.3,1,29,FALSE,TRUE,10.67 +7.3,1,29,FALSE,TRUE,10.67 +5.9,2,21,FALSE,FALSE,8 +0.5,1,45,TRUE,FALSE,1.74 +0.9,1,40,FALSE,FALSE,4.54 +0.9,1,40,FALSE,FALSE,4.54 +1.6,1,31,FALSE,FALSE,2.5 +2,1,47,TRUE,TRUE,5.28 +0.1,2,31,FALSE,TRUE,0.35 +1.5,1,33,FALSE,FALSE,1.34 +1.5,1,33,FALSE,FALSE,1.34 +8.7,1,45,FALSE,TRUE,2.55 +8.7,1,45,FALSE,TRUE,2.55 +1.5,2,28,FALSE,FALSE,4.74 +1.5,2,28,FALSE,FALSE,4.74 +2.2,1,34,FALSE,FALSE,3.63 +2.2,1,34,FALSE,FALSE,3.63 +2.2,1,34,FALSE,FALSE,3.63 +2.4,1,19,FALSE,TRUE,2.26 +0.5,2,54,TRUE,TRUE,1.55 +10.4,0,34,TRUE,TRUE,3.87 +10.4,0,34,TRUE,TRUE,3.87 +5.3,2,35,FALSE,TRUE,3.75 +0.3,2,44,TRUE,TRUE,2.97 +0.3,2,44,TRUE,TRUE,2.97 +0.1,2,43,TRUE,TRUE,2.37 +7.2,0,27,FALSE,FALSE,4.04 +7.2,0,27,FALSE,FALSE,4.04 +4.7,1,37,TRUE,TRUE,2.9 +0.6,0,37,FALSE,TRUE,4.85 +0.6,0,37,FALSE,TRUE,4.85 +3.4,1,28,TRUE,TRUE,1.72 +3.4,1,28,TRUE,TRUE,1.72 +3.2,2,48,TRUE,TRUE,4.99 +6.6,0,36,FALSE,TRUE,4.23 +3.3,1,26,FALSE,FALSE,2.42 +3.3,1,26,FALSE,FALSE,2.42 +1.8,1,30,FALSE,FALSE,3.82 +0.7,1,37,FALSE,FALSE,6.52 +0.7,1,37,FALSE,FALSE,6.52 +6.8,0,27,FALSE,TRUE,6.38 +0.2,2,40,TRUE,TRUE,0.06 +2.9,1,39,TRUE,FALSE,3.12 +7.8,1,30,FALSE,TRUE,4.59 +7.8,1,30,FALSE,TRUE,4.59 +1.9,1,39,FALSE,TRUE,3.6 +3.3,1,46,FALSE,TRUE,3.64 +10.5,0,28,FALSE,TRUE,7.07 +10.5,0,28,FALSE,TRUE,7.07 +10.5,0,28,FALSE,TRUE,7.07 +10.7,0,39,FALSE,TRUE,3.21 +4.8,1,60,TRUE,FALSE,4.29 +1.4,1,34,FALSE,FALSE,0.72 +1.9,1,31,FALSE,TRUE,2.98 +4.3,2,44,FALSE,FALSE,4.44 +4.3,2,44,FALSE,FALSE,4.44 +0.8,1,31,FALSE,FALSE,0.08 +1.2,1,36,FALSE,TRUE,1.56 +0.6,1,38,TRUE,FALSE,0.75 +7.3,2,37,TRUE,FALSE,0.23 +5.8,1,49,TRUE,TRUE,4.23 +1.4,1,46,FALSE,TRUE,3.74 +2.2,2,38,TRUE,TRUE,3.44 +0.6,1,38,TRUE,TRUE,3.38 +0.6,1,38,TRUE,TRUE,3.38 +0.6,1,38,TRUE,TRUE,3.38 +0.6,0,30,TRUE,FALSE,3.49 +7.8,1,46,FALSE,TRUE,3.86 +1.2,1,52,FALSE,TRUE,2.13 +1.2,1,52,FALSE,TRUE,2.13 +4.4,1,35,FALSE,FALSE,4.31 +4.4,1,35,FALSE,FALSE,4.31 +3.2,1,35,FALSE,FALSE,4.26 +1.1,1,46,FALSE,TRUE,1.42 +3.6,2,28,FALSE,FALSE,3.03 +3,1,38,TRUE,FALSE,4.75 +1.3,1,31,FALSE,FALSE,1.83 +1.2,1,29,FALSE,FALSE,0.61 +2.6,1,61,FALSE,FALSE,3.75 +0.8,1,38,FALSE,FALSE,3.38 +0.8,1,38,FALSE,FALSE,3.38 +0.8,1,38,FALSE,FALSE,3.38 +1,2,46,TRUE,FALSE,1.29 +3.6,1,58,FALSE,TRUE,3.91 +2.5,1,39,FALSE,FALSE,2.59 +1.4,1,40,FALSE,FALSE,2.49 +1.4,1,40,FALSE,FALSE,2.49 +0.2,2,35,TRUE,TRUE,0.84 +0.2,2,35,TRUE,TRUE,0.84 +0.2,2,35,TRUE,TRUE,0.84 +1.3,2,42,TRUE,TRUE,1.84 +1.8,1,45,FALSE,FALSE,5.26 +1.8,1,45,FALSE,FALSE,5.26 +1.8,1,45,FALSE,FALSE,5.26 +1.8,1,45,FALSE,FALSE,5.26 +4.2,1,47,TRUE,TRUE,5.88 +1,2,40,TRUE,TRUE,1.05 +2,2,26,FALSE,TRUE,3.48 +0.4,2,36,FALSE,TRUE,4.44 +0.4,2,36,FALSE,TRUE,4.44 +0.4,2,36,FALSE,TRUE,4.44 +0.4,2,36,FALSE,TRUE,4.44 +4.9,1,41,TRUE,TRUE,4.62 +4.9,1,41,TRUE,TRUE,4.62 +1.6,1,54,FALSE,TRUE,2.41 +1.2,1,38,TRUE,FALSE,4.14 +10.4,0,32,FALSE,TRUE,7.99 +10.4,0,32,FALSE,TRUE,7.99 +1.2,2,32,TRUE,FALSE,3.92 +9.3,1,31,FALSE,TRUE,9.7 +9.3,1,31,FALSE,TRUE,9.7 +9.3,1,31,FALSE,TRUE,9.7 +9.3,1,31,FALSE,TRUE,9.7 +10.5,0,37,FALSE,FALSE,7.02 +2.6,1,32,FALSE,FALSE,2.48 +2.6,1,32,FALSE,FALSE,2.48 +10.3,2,51,FALSE,TRUE,10.68 +10.3,2,51,FALSE,TRUE,10.68 +6.4,1,33,FALSE,FALSE,6.53 +2.2,1,40,FALSE,FALSE,5.28 +1,1,32,FALSE,FALSE,0 +2.2,1,29,FALSE,TRUE,2.81 +2.2,1,29,FALSE,TRUE,2.81 +0.2,1,38,FALSE,FALSE,1.02 +1,1,42,TRUE,TRUE,2.19 +1,1,42,TRUE,TRUE,2.19 +1,2,54,FALSE,TRUE,6.42 +1.2,1,38,FALSE,TRUE,3 +3,1,21,FALSE,TRUE,4.77 +3,1,21,FALSE,TRUE,4.77 +1.1,1,36,TRUE,FALSE,1.92 +1.8,1,44,TRUE,FALSE,6.54 +1.8,1,44,TRUE,FALSE,6.54 +1.8,1,44,TRUE,FALSE,6.54 +1.8,1,44,TRUE,FALSE,6.54 +10.4,0,38,TRUE,FALSE,3.69 +0.8,1,31,FALSE,TRUE,1.66 +2.6,1,31,FALSE,TRUE,2.2 +2.3,1,48,TRUE,FALSE,2.13 +2.3,1,48,TRUE,FALSE,2.13 +4.3,2,40,TRUE,TRUE,1.91 +2,1,36,FALSE,TRUE,5.44 +2,1,36,FALSE,TRUE,5.44 +1.4,1,27,FALSE,FALSE,1.33 +1.4,1,27,FALSE,FALSE,1.33 +0.7,2,45,TRUE,TRUE,2.17 +2,1,38,FALSE,FALSE,3.3 +2,1,38,FALSE,FALSE,3.3 +1.1,2,27,FALSE,FALSE,2.78 +1.1,2,27,FALSE,FALSE,2.78 +0.8,1,27,FALSE,FALSE,0.8 +0.8,1,27,FALSE,FALSE,0.8 +0.1,2,47,FALSE,FALSE,0.14 +1.6,2,29,FALSE,TRUE,0.05 +7.2,1,37,FALSE,TRUE,3.53 +7.2,1,37,FALSE,TRUE,3.53 +7.2,1,37,FALSE,TRUE,3.53 +4.4,1,35,FALSE,FALSE,4.01 +3.5,0,61,FALSE,FALSE,7.98 +3.5,0,61,FALSE,FALSE,7.98 +3.5,0,61,FALSE,FALSE,7.98 +5.6,2,36,TRUE,TRUE,8.41 +1.8,1,43,TRUE,FALSE,4.09 +1.8,1,43,TRUE,FALSE,4.09 +5.3,2,27,FALSE,TRUE,2.94 +5.3,2,27,FALSE,TRUE,2.94 +5.3,2,27,FALSE,TRUE,2.94 +1,1,38,TRUE,TRUE,0.2 +0.4,1,37,TRUE,TRUE,1.53 +2.2,1,31,FALSE,FALSE,2.36 +2.2,1,31,FALSE,FALSE,2.36 +1.5,0,30,FALSE,FALSE,3.36 +1.5,2,44,TRUE,TRUE,4.35 +1.7,1,54,FALSE,TRUE,2.81 +1.7,1,54,FALSE,TRUE,2.81 +1.4,1,25,FALSE,FALSE,0.93 +1.4,1,25,FALSE,FALSE,0.93 +1.4,1,25,FALSE,FALSE,0.93 +3.6,1,25,FALSE,FALSE,3.34 +3.6,1,25,FALSE,FALSE,3.34 +6.5,2,22,FALSE,FALSE,10.42 +6.5,2,22,FALSE,FALSE,10.42 +1.1,1,39,FALSE,FALSE,1.87 +1.1,1,39,FALSE,FALSE,1.87 +2.8,1,36,FALSE,TRUE,4.91 +1.3,1,33,FALSE,FALSE,0.3 +4.2,2,41,FALSE,TRUE,1.72 +1.4,1,32,FALSE,FALSE,4.36 +1.4,1,32,FALSE,FALSE,4.36 +1.4,1,28,FALSE,FALSE,7.36 +1.2,1,37,TRUE,TRUE,2.45 +1.2,1,37,TRUE,TRUE,2.45 +3.5,1,48,FALSE,TRUE,5.35 +2.2,1,37,FALSE,FALSE,3.1 +2.2,1,37,FALSE,FALSE,3.1 +1.4,1,32,FALSE,FALSE,1.88 +3.7,2,40,FALSE,FALSE,7.38 +7.3,2,28,FALSE,TRUE,0.99 +7.3,2,28,FALSE,TRUE,0.99 +0.9,2,42,TRUE,TRUE,1.94 +0.6,2,44,FALSE,FALSE,0.87 +1.2,1,38,TRUE,TRUE,5.95 +1.4,1,52,FALSE,TRUE,3.92 +1.4,1,52,FALSE,TRUE,3.92 +1.1,1,37,FALSE,FALSE,2 +9,1,26,FALSE,FALSE,3.45 +0.7,1,42,TRUE,TRUE,0.11 +2.2,1,40,FALSE,TRUE,8.2 +2.2,1,40,FALSE,TRUE,8.2 +1.6,1,37,FALSE,FALSE,5.85 +1.6,1,37,FALSE,FALSE,5.85 +1.6,1,37,FALSE,FALSE,5.85 +1.2,1,33,TRUE,FALSE,3.38 +1.3,1,41,TRUE,TRUE,1.35 +1.6,2,45,TRUE,TRUE,4.23 +3.1,2,29,FALSE,TRUE,2.47 +1.3,1,37,FALSE,TRUE,4.52 +1.3,1,37,FALSE,TRUE,4.52 +1.3,1,37,FALSE,TRUE,4.52 +4.4,1,20,FALSE,FALSE,4.54 +6.1,1,33,TRUE,TRUE,4.52 +6.1,1,33,TRUE,TRUE,4.52 +6.1,1,33,TRUE,TRUE,4.52 +6.1,1,33,TRUE,TRUE,4.52 +8.8,2,47,FALSE,TRUE,2.74 +0.7,2,32,FALSE,TRUE,0.5 +0.7,2,32,FALSE,TRUE,0.5 +0.7,2,32,FALSE,TRUE,0.5 +10.3,0,25,FALSE,FALSE,4.97 +10.3,0,25,FALSE,FALSE,4.97 +10.3,0,25,FALSE,FALSE,4.97 +10.3,0,25,FALSE,FALSE,4.97 +0.8,2,49,FALSE,FALSE,2.65 +0.4,2,36,TRUE,TRUE,1.79 +0.4,2,36,TRUE,TRUE,1.79 +10.4,0,36,TRUE,FALSE,6.19 +1.7,2,57,TRUE,TRUE,10.07 +1.7,2,57,TRUE,TRUE,10.07 +0.9,1,40,FALSE,TRUE,1.83 +0.9,1,40,FALSE,TRUE,1.83 +1.1,1,45,TRUE,TRUE,2.17 +3,1,35,TRUE,FALSE,6.13 +2,1,34,TRUE,FALSE,1.49 +7.5,1,34,FALSE,TRUE,6.85 +10.3,0,33,TRUE,TRUE,4.62 +10.3,0,33,TRUE,TRUE,4.62 +10.3,0,33,TRUE,TRUE,4.62 +1.1,1,30,TRUE,FALSE,3.43 +0.5,2,54,TRUE,TRUE,0.57 +0.5,2,54,TRUE,TRUE,0.57 +1.1,2,34,TRUE,TRUE,3.27 +0.7,1,37,TRUE,FALSE,3.91 +0.7,1,37,TRUE,FALSE,3.91 +10.6,0,33,FALSE,TRUE,3.97 +1.1,2,45,TRUE,TRUE,4.13 +1.1,2,45,TRUE,TRUE,4.13 +1.4,2,36,TRUE,FALSE,3.95 +2.9,1,57,FALSE,FALSE,6.69 +1.6,0,32,FALSE,TRUE,2.57 +1,1,28,FALSE,TRUE,2.34 +1,1,28,FALSE,TRUE,2.34 +2.7,1,40,TRUE,TRUE,4.58 +1.1,2,36,FALSE,TRUE,5.18 +5.9,1,21,FALSE,FALSE,6.82 +10.3,0,29,FALSE,TRUE,8.18 +0.8,1,35,FALSE,FALSE,4.84 +10.4,0,38,TRUE,TRUE,5.5 +10.4,0,38,TRUE,TRUE,5.5 +0.9,2,38,FALSE,TRUE,3.67 +0.9,2,38,FALSE,TRUE,3.67 +3.3,1,30,FALSE,TRUE,5.62 +3.3,1,30,FALSE,TRUE,5.62 +0.9,2,38,FALSE,TRUE,3.36 +0.9,2,38,FALSE,TRUE,3.36 +2,2,32,FALSE,FALSE,3.18 +1.1,1,48,FALSE,TRUE,4.74 +4.4,2,41,TRUE,TRUE,3.91 +6.1,1,24,FALSE,TRUE,3.62 +9.7,1,31,FALSE,TRUE,3.42 +0.02,2,48,FALSE,TRUE,6.95 +0.02,2,48,FALSE,TRUE,6.95 +1.6,1,21,FALSE,FALSE,5.62 +1.6,1,21,FALSE,FALSE,5.62 +1.5,1,37,TRUE,TRUE,3.19 +2.2,2,44,TRUE,TRUE,3.76 +2.2,2,44,TRUE,TRUE,3.76 +1.3,2,46,TRUE,TRUE,0.35 +1.8,1,18,FALSE,TRUE,5.72 +1.8,1,18,FALSE,TRUE,5.72 +0.4,1,34,FALSE,FALSE,0.86 +0.4,1,34,FALSE,FALSE,0.86 +1.2,1,21,FALSE,FALSE,4.29 +0.7,1,40,FALSE,FALSE,0.97 +2.7,1,31,FALSE,FALSE,5.28 +0.7,2,29,FALSE,TRUE,0.15 +2.2,1,42,TRUE,TRUE,6.33 +0.4,2,42,FALSE,FALSE,4.86 +1,2,21,FALSE,TRUE,2.75 +0.6,1,34,TRUE,FALSE,3.38 +0.6,0,36,FALSE,TRUE,3.47 +0.6,0,36,FALSE,TRUE,3.47 +0.6,0,36,FALSE,TRUE,3.47 +1.9,2,44,TRUE,TRUE,1.69 +1.9,2,44,TRUE,TRUE,1.69 +2,1,58,FALSE,TRUE,2.9 +0.3,2,38,TRUE,FALSE,0.38 +1.2,1,39,FALSE,FALSE,3.95 +1.2,1,39,FALSE,FALSE,3.95 +1.2,1,39,FALSE,FALSE,3.95 +1.2,1,39,FALSE,FALSE,3.95 +1.2,1,39,FALSE,FALSE,3.95 +2.7,1,38,TRUE,TRUE,5.22 +2.7,1,38,TRUE,TRUE,5.22 +1.8,1,32,FALSE,TRUE,2.89 +1.8,1,32,FALSE,TRUE,2.89 +4.7,2,37,FALSE,TRUE,1.76 +6.4,2,50,TRUE,TRUE,3.17 +0.8,1,42,FALSE,FALSE,3.26 +0.8,1,42,FALSE,FALSE,3.26 +1.2,2,35,TRUE,TRUE,5.26 +1.6,2,25,FALSE,TRUE,0.63 +1.8,1,26,FALSE,FALSE,3.48 +1.8,1,26,FALSE,FALSE,3.48 +0.4,2,33,FALSE,TRUE,0.13 +3,2,47,TRUE,FALSE,6.03 +5.6,1,48,FALSE,TRUE,6.92 +5.6,1,48,FALSE,TRUE,6.92 +0.9,1,41,TRUE,FALSE,6.49 +0.9,1,41,TRUE,FALSE,6.49 +0.9,1,41,TRUE,FALSE,6.49 +3.6,1,31,FALSE,FALSE,6.79 +3.6,1,31,FALSE,FALSE,6.79 +3.6,1,31,FALSE,FALSE,6.79 +6,1,30,TRUE,FALSE,3.87 +6,1,30,TRUE,FALSE,3.87 +9.2,1,26,FALSE,TRUE,3.27 +9.2,1,26,FALSE,TRUE,3.27 +0.2,0,22,FALSE,TRUE,9.72 +0.8,2,37,TRUE,TRUE,9.96 +0.8,2,37,TRUE,TRUE,9.96 +4.4,2,35,TRUE,TRUE,6.76 +1,1,24,FALSE,TRUE,2.23 +1,1,24,FALSE,TRUE,2.23 +0.8,1,32,FALSE,FALSE,3.25 +1,1,33,FALSE,FALSE,2.24 +1,1,33,FALSE,FALSE,2.24 +1,1,33,FALSE,FALSE,2.24 +0.8,1,32,FALSE,FALSE,2.26 +3.1,1,36,FALSE,TRUE,7.56 +2.4,1,23,FALSE,TRUE,3.36 +1.3,1,69,FALSE,TRUE,1.6 +1.3,1,69,FALSE,TRUE,1.6 +1.3,1,42,FALSE,FALSE,2.7 +1.3,1,42,FALSE,FALSE,2.7 +1.3,1,42,FALSE,FALSE,2.7 +2.3,1,29,FALSE,TRUE,6.42 +4.4,1,38,FALSE,TRUE,2.83 +4.4,1,38,FALSE,TRUE,2.83 +0.2,0,37,FALSE,TRUE,4.73 +10.8,0,29,TRUE,FALSE,8.83 +10.4,0,27,TRUE,TRUE,5.51 +3.6,2,32,TRUE,FALSE,4.48 +0.02,2,28,FALSE,TRUE,0.18 +5.5,2,39,FALSE,FALSE,2.38 +5.5,2,39,FALSE,FALSE,2.38 +0.9,2,31,TRUE,FALSE,2.34 +6.8,0,33,FALSE,FALSE,5.79 +6.8,0,33,FALSE,FALSE,5.79 +7.7,1,44,FALSE,TRUE,6.15 +7.7,1,44,FALSE,TRUE,6.15 +7.7,1,44,FALSE,TRUE,6.15 +7.7,1,44,FALSE,TRUE,6.15 +4.5,2,38,TRUE,TRUE,3.16 +1,2,30,TRUE,FALSE,1.39 +3.3,1,37,FALSE,TRUE,7.64 +1.6,1,43,TRUE,TRUE,1.7 +1.5,1,34,FALSE,FALSE,1.98 +0.9,1,44,TRUE,TRUE,4.62 +3.2,1,24,FALSE,TRUE,3.77 +5.9,2,50,TRUE,TRUE,2.98 +2.1,0,48,FALSE,FALSE,5.28 +2.1,0,48,FALSE,FALSE,5.28 +2.8,2,41,FALSE,FALSE,1.83 +0.4,1,41,FALSE,TRUE,1.22 +0.4,1,41,FALSE,TRUE,1.22 +4,2,34,TRUE,FALSE,7.99 +2.1,1,38,TRUE,FALSE,2.04 +1.2,1,38,FALSE,FALSE,2.14 +1.2,1,38,FALSE,FALSE,2.14 +4.2,1,31,FALSE,TRUE,8.15 +1.5,2,29,FALSE,TRUE,2.61 +1.5,2,29,FALSE,TRUE,2.61 +1.5,2,29,FALSE,TRUE,2.61 +4.7,1,17,FALSE,FALSE,14.24 +1.3,2,37,FALSE,TRUE,0.04 +2,1,38,FALSE,TRUE,3.06 +8.2,1,47,TRUE,TRUE,3.02 +8.2,1,47,TRUE,TRUE,3.02 +4.8,2,33,FALSE,TRUE,10.08 +2.5,1,39,FALSE,FALSE,4.08 +2.5,1,39,FALSE,FALSE,4.08 +3.7,2,43,FALSE,TRUE,18.12 +3.7,2,43,FALSE,TRUE,18.12 +3.7,2,43,FALSE,TRUE,18.12 +0.3,1,29,FALSE,FALSE,1.8 +2.3,1,40,TRUE,TRUE,2.91 +1.7,1,34,FALSE,TRUE,1 +1.7,1,34,FALSE,TRUE,1 +1.7,1,34,FALSE,TRUE,1 +1.7,0,37,FALSE,TRUE,3.7 +1.7,0,37,FALSE,TRUE,3.7 +1.7,0,37,FALSE,TRUE,3.7 +1.4,1,26,FALSE,TRUE,3.82 +1.4,1,26,FALSE,TRUE,3.82 +1.3,2,39,TRUE,TRUE,2.33 +1.7,1,41,FALSE,TRUE,2.98 +3.6,2,35,TRUE,FALSE,1.69 +1.2,1,29,FALSE,FALSE,2.54 +5.6,1,41,TRUE,TRUE,5.26 +5.6,1,41,TRUE,TRUE,5.26 +1.6,1,33,FALSE,TRUE,4.46 +4.2,1,37,TRUE,TRUE,7.85 +4.2,1,37,TRUE,TRUE,7.85 +4.2,1,37,TRUE,TRUE,7.85 +10.5,1,40,TRUE,TRUE,5.48 +10.5,1,40,TRUE,TRUE,5.48 +0.6,1,35,TRUE,FALSE,3.33 +0.6,1,35,TRUE,FALSE,3.33 +0.7,1,26,FALSE,FALSE,0.07 +1.3,1,39,FALSE,TRUE,2.05 +2.1,1,33,FALSE,TRUE,5.46 +10.3,0,42,FALSE,TRUE,6.15 +1.6,1,38,FALSE,FALSE,7.96 +1.6,1,38,FALSE,FALSE,7.96 +1.6,1,38,FALSE,FALSE,7.96 +3.1,1,29,FALSE,FALSE,5.42 +3.1,1,29,FALSE,FALSE,5.42 +7.4,2,42,TRUE,TRUE,6.73 +4.4,1,30,FALSE,TRUE,5.16 +4.4,1,30,FALSE,TRUE,5.16 +5.1,1,26,FALSE,FALSE,5.84 +9.3,1,38,FALSE,FALSE,8.6 +0.4,1,41,FALSE,FALSE,3.1 +2.4,1,33,TRUE,FALSE,2.69 +2.4,1,33,TRUE,FALSE,2.69 +2.4,1,33,TRUE,FALSE,2.69 +7.3,1,30,FALSE,TRUE,3.84 +1.5,1,42,TRUE,FALSE,5.15 +2.7,1,39,TRUE,FALSE,4.32 +2.9,1,35,FALSE,TRUE,4.69 +2.2,1,34,FALSE,FALSE,3.46 +2.2,1,34,FALSE,FALSE,3.46 +4.2,1,40,FALSE,TRUE,3.62 +0.6,2,51,FALSE,FALSE,1.89 +1.2,1,60,FALSE,TRUE,2.26 +1.2,1,60,FALSE,TRUE,2.26 +1.4,1,35,FALSE,FALSE,3.82 +1.4,1,35,FALSE,FALSE,3.82 +1.4,2,41,TRUE,TRUE,0.82 +0.8,1,34,FALSE,FALSE,8.83 +0.3,0,31,FALSE,TRUE,8.27 +0.3,0,31,FALSE,TRUE,8.27 +2.2,1,30,FALSE,TRUE,2.81 +1.2,1,32,FALSE,FALSE,3.87 +1.2,1,32,FALSE,FALSE,3.87 +3.2,1,39,FALSE,TRUE,4.22 +0.4,2,39,FALSE,TRUE,0.62 +0.4,2,39,FALSE,TRUE,0.62 +0.4,1,43,FALSE,FALSE,4.19 +0.4,1,43,FALSE,FALSE,4.19 +6.3,1,45,FALSE,FALSE,6.44 +6.3,1,45,FALSE,FALSE,6.44 +6.3,1,45,FALSE,FALSE,6.44 +1.1,1,32,FALSE,TRUE,3.08 +3.8,2,35,FALSE,TRUE,5.94 +2.8,1,31,TRUE,FALSE,4.56 +2.8,1,31,TRUE,FALSE,4.56 +1.1,1,36,FALSE,FALSE,1.21 +1.1,1,36,FALSE,FALSE,1.21 +4.4,2,33,FALSE,TRUE,4.47 +2.6,2,51,FALSE,TRUE,6.69 +10.5,0,33,FALSE,FALSE,6.83 +2.4,1,28,FALSE,TRUE,3.47 +1.4,2,49,FALSE,FALSE,2.56 +1.4,2,49,FALSE,FALSE,2.56 +0.6,1,32,FALSE,TRUE,4.1 +0.9,1,37,TRUE,TRUE,3.41 +2.5,1,43,TRUE,TRUE,9.48 +3.5,0,34,FALSE,TRUE,2.86 +3.5,0,34,FALSE,TRUE,2.86 +1.2,0,28,FALSE,TRUE,5.05 +1.2,0,28,FALSE,TRUE,5.05 +1.2,0,28,FALSE,TRUE,5.05 +0.5,1,40,TRUE,FALSE,1.53 +0.5,1,40,TRUE,FALSE,1.53 +0.8,1,36,FALSE,FALSE,1.8 +0.8,1,36,FALSE,FALSE,1.8 +0.4,2,38,TRUE,TRUE,0.15 +3.1,1,37,FALSE,TRUE,3.98 +3.1,1,37,FALSE,TRUE,3.98 +0.9,1,43,FALSE,TRUE,3.98 +0.9,1,43,FALSE,TRUE,3.98 +0.9,1,43,FALSE,TRUE,3.98 +0.3,1,39,FALSE,TRUE,3.82 +1.5,1,36,FALSE,TRUE,1.6 +1.4,1,41,TRUE,TRUE,1.79 +4.1,1,31,FALSE,TRUE,3.5 +1.1,1,39,TRUE,TRUE,0.25 +2.1,1,37,TRUE,FALSE,2.47 +10.8,0,20,FALSE,TRUE,11.05 +10.3,0,29,FALSE,TRUE,4.38 +8.8,1,26,FALSE,FALSE,4.75 +1.2,1,28,FALSE,TRUE,0.36 +1.7,1,32,FALSE,FALSE,1.89 +1.7,1,32,FALSE,FALSE,1.89 +1.7,1,32,FALSE,FALSE,1.89 +1.7,1,32,FALSE,FALSE,1.89 +1.3,2,40,TRUE,TRUE,7.66 +1.3,2,40,TRUE,TRUE,7.66 +4,2,47,TRUE,TRUE,1.39 +4,2,47,TRUE,TRUE,1.39 +7.9,2,46,TRUE,FALSE,3.86 +1.5,1,26,FALSE,TRUE,2.14 +1.1,2,32,TRUE,FALSE,3.88 +1.1,2,32,TRUE,FALSE,3.88 +1.1,2,32,TRUE,FALSE,3.88 +2.3,1,39,FALSE,FALSE,7.08 +2.3,1,39,FALSE,FALSE,7.08 +3.5,1,33,FALSE,TRUE,6.29 +4,1,33,FALSE,FALSE,4.24 +0.9,1,45,FALSE,FALSE,3.48 +0.3,2,49,FALSE,TRUE,0.99 +0.3,2,49,FALSE,TRUE,0.99 +1.1,0,28,FALSE,FALSE,3.39 +2.7,1,32,TRUE,TRUE,2.44 +1.6,1,32,FALSE,TRUE,2.36 +1.6,1,32,FALSE,TRUE,2.36 +0.6,2,41,FALSE,TRUE,1.12 +1.5,1,24,FALSE,TRUE,0.99 +3.1,1,40,FALSE,TRUE,1.07 +10.7,0,40,FALSE,TRUE,10.73 +10.8,0,35,TRUE,TRUE,5.98 +10.8,0,35,TRUE,TRUE,5.98 +10.8,0,35,TRUE,TRUE,5.98 +1.9,1,29,FALSE,TRUE,0.11 +1.9,1,29,FALSE,TRUE,0.11 +1.8,1,40,TRUE,TRUE,0.84 +1.8,1,40,TRUE,TRUE,0.84 +1.8,1,40,TRUE,TRUE,0.84 +0.9,1,37,FALSE,FALSE,0.5 +0.9,1,37,FALSE,FALSE,0.5 +3,2,32,FALSE,FALSE,4.77 +6.8,1,24,TRUE,FALSE,3.08 +0.7,2,35,TRUE,FALSE,0.73 +1.5,1,35,FALSE,TRUE,3.5 +10.8,0,28,FALSE,TRUE,7.24 +1.1,2,42,FALSE,TRUE,4.41 +1.4,2,23,TRUE,FALSE,10.96 +1.4,2,23,TRUE,FALSE,10.96 +0.1,2,51,TRUE,TRUE,6.91 +0.9,2,24,FALSE,FALSE,8.11 +0.8,2,45,FALSE,FALSE,1.92 +0.8,2,45,FALSE,FALSE,1.92 +0.8,2,45,FALSE,FALSE,1.92 +3.1,1,40,FALSE,TRUE,4.61 +3.1,1,40,FALSE,TRUE,4.61 +3.1,1,40,FALSE,TRUE,4.61 +3.1,1,33,TRUE,TRUE,3.65 +3.1,1,29,FALSE,TRUE,7.43 +3.1,1,29,FALSE,TRUE,7.43 +4.1,2,40,TRUE,TRUE,3.52 +6.3,0,36,FALSE,FALSE,1.53 +1.3,2,34,TRUE,TRUE,2.88 +3.2,1,30,TRUE,TRUE,2.49 +3.2,1,30,TRUE,TRUE,2.49 +3.2,1,30,TRUE,TRUE,2.49 +1.7,1,28,FALSE,FALSE,4.4 +1.7,1,66,FALSE,FALSE,2.16 +5.7,2,41,TRUE,TRUE,3.39 +5.7,2,41,TRUE,TRUE,3.39 +0.9,2,33,FALSE,TRUE,4.41 +0.9,2,33,FALSE,TRUE,4.41 +0.9,2,33,FALSE,TRUE,4.41 +10.5,0,43,TRUE,TRUE,8.42 +3.3,1,22,FALSE,FALSE,6.19 +1.9,1,34,TRUE,TRUE,5.54 +0.3,1,43,FALSE,FALSE,1.1 +0.3,1,43,FALSE,FALSE,1.1 +6.8,1,24,FALSE,TRUE,4.94 +2.3,1,32,FALSE,TRUE,3.32 +2.3,1,32,FALSE,TRUE,3.32 +4.4,1,42,TRUE,TRUE,1.93 +3.1,2,48,FALSE,TRUE,9.35 +3.1,2,48,FALSE,TRUE,9.35 +1,2,39,TRUE,TRUE,0.96 +1,2,39,TRUE,TRUE,0.96 +0.9,1,31,FALSE,FALSE,0.96 +2.4,1,21,FALSE,FALSE,5.99 +1.3,1,46,TRUE,TRUE,3.46 +1.9,2,34,FALSE,TRUE,2.57 +1.9,2,34,FALSE,TRUE,2.57 +4.1,1,35,FALSE,TRUE,3.92 +2.3,1,42,TRUE,TRUE,4.94 +1.1,1,31,FALSE,FALSE,5.05 +9.2,1,28,TRUE,TRUE,8.82 +1,2,42,TRUE,FALSE,6.38 +1,2,42,TRUE,FALSE,6.38 +10.5,0,37,TRUE,FALSE,2.32 +0.02,2,36,TRUE,TRUE,3.89 +0.8,1,34,FALSE,FALSE,2.87 +4.7,1,47,TRUE,TRUE,5.14 +4.7,1,47,TRUE,TRUE,5.14 +0.2,1,23,FALSE,FALSE,0.64 +0.6,2,33,FALSE,FALSE,0.53 +10.3,0,28,FALSE,TRUE,6.18 +10.3,0,28,FALSE,TRUE,6.18 +10.3,0,28,FALSE,TRUE,6.18 +10.3,0,28,FALSE,TRUE,6.18 +7.4,0,37,TRUE,TRUE,8.93 +5.7,1,27,FALSE,FALSE,9.95 +0.5,0,34,FALSE,TRUE,3.29 +1.4,1,35,FALSE,FALSE,2.71 +1,1,54,TRUE,FALSE,4.92 +1,1,54,TRUE,FALSE,4.92 +0.9,2,27,FALSE,FALSE,2.92 +0.9,2,27,FALSE,FALSE,2.92 +0.9,2,27,FALSE,FALSE,2.92 +10.4,0,44,TRUE,TRUE,4.95 +0.6,2,43,TRUE,TRUE,1.3 +9.4,2,48,TRUE,TRUE,8.53 +9.4,2,48,TRUE,TRUE,8.53 +1.7,1,31,FALSE,FALSE,2.87 +1.7,1,31,FALSE,FALSE,2.87 +2.1,1,56,FALSE,TRUE,4.41 +3.7,1,34,FALSE,TRUE,5.19 +9.3,1,32,TRUE,TRUE,4.29 +0.3,2,42,TRUE,FALSE,3.67 +0.3,2,42,TRUE,FALSE,3.67 +10.5,0,53,TRUE,TRUE,4.19 +10.3,0,33,FALSE,TRUE,7.99 +10.3,0,33,FALSE,TRUE,7.99 +10.3,0,33,FALSE,TRUE,7.99 +1.1,1,36,FALSE,TRUE,4.91 +6.9,1,33,FALSE,FALSE,4.29 +6.9,1,33,FALSE,FALSE,4.29 +1.2,1,24,FALSE,FALSE,6.77 +3.8,2,44,TRUE,TRUE,2.49 +3.8,2,44,TRUE,TRUE,2.49 +0.1,2,44,TRUE,FALSE,7.84 +0.1,2,44,TRUE,FALSE,7.84 +0.3,2,38,FALSE,TRUE,5.13 +0.3,2,38,FALSE,TRUE,5.13 +1.5,1,28,FALSE,TRUE,1.55 +6.6,1,29,FALSE,FALSE,4.4 +6.6,1,29,FALSE,FALSE,4.4 +6.6,1,29,FALSE,FALSE,4.4 +6.6,1,29,FALSE,FALSE,4.4 +6.6,1,29,FALSE,FALSE,4.4 +2.6,1,34,FALSE,FALSE,3.4 +2.6,1,34,FALSE,FALSE,3.4 +2.1,2,30,FALSE,TRUE,4.94 +2.1,2,30,FALSE,TRUE,4.94 +0.7,1,38,TRUE,TRUE,4.92 +10.6,0,32,TRUE,TRUE,9.81 +0.1,2,44,TRUE,TRUE,0.3 +10.4,0,25,FALSE,TRUE,10.35 +0.3,2,24,FALSE,TRUE,5.2 +0.3,2,24,FALSE,TRUE,5.2 +0.3,2,24,FALSE,TRUE,5.2 +0.3,2,24,FALSE,TRUE,5.2 +1.1,2,51,TRUE,TRUE,2.13 +1.1,2,51,TRUE,TRUE,2.13 +2.9,1,36,FALSE,FALSE,4.95 +0.9,1,45,TRUE,TRUE,13.53 +0.9,1,45,TRUE,TRUE,13.53 +0.02,2,29,TRUE,FALSE,3.29 +1.6,1,45,FALSE,TRUE,1.75 +0.2,2,36,TRUE,TRUE,8.02 +1.3,1,38,FALSE,FALSE,4.75 +1.3,1,38,FALSE,FALSE,4.75 +1.3,1,38,FALSE,FALSE,4.75 +1.4,1,42,TRUE,TRUE,1.03 +1.4,1,42,TRUE,TRUE,1.03 +1.4,1,42,TRUE,TRUE,1.03 +1.4,1,42,TRUE,TRUE,1.03 +1.4,1,42,TRUE,TRUE,1.03 +1.2,1,36,FALSE,FALSE,2.98 +1.1,2,32,TRUE,FALSE,0.21 +1.1,2,32,TRUE,FALSE,0.21 +2.2,1,22,FALSE,TRUE,6.38 +2.2,1,22,FALSE,TRUE,6.38 +5.6,1,35,TRUE,TRUE,2.97 +2,1,35,TRUE,FALSE,3.48 +2,1,35,TRUE,FALSE,3.48 +5.6,1,41,FALSE,TRUE,2.25 +2.4,1,40,FALSE,FALSE,3.65 +2.4,1,40,FALSE,FALSE,3.65 +7.8,0,37,TRUE,FALSE,12.22 +7.8,0,37,TRUE,FALSE,12.22 +1.7,1,44,TRUE,TRUE,3.39 +2.1,2,29,FALSE,FALSE,3.61 +2.1,2,29,FALSE,FALSE,3.61 +9.3,2,32,TRUE,FALSE,5.22 +9.3,2,32,TRUE,FALSE,5.22 +1.6,1,47,TRUE,FALSE,7.16 +5.1,1,27,TRUE,FALSE,3.7 +5.1,1,27,TRUE,FALSE,3.7 +0.8,2,35,FALSE,TRUE,0.46 +0.8,2,35,FALSE,TRUE,0.46 +0.8,2,35,FALSE,TRUE,0.46 +1.3,0,32,FALSE,TRUE,6.1 +1.3,0,32,FALSE,TRUE,6.1 +10.4,1,45,TRUE,TRUE,3.99 +0.5,1,32,FALSE,FALSE,3.88 +10.5,0,28,FALSE,TRUE,8.28 +10.5,0,28,FALSE,TRUE,8.28 +10.5,0,28,FALSE,TRUE,8.28 +3,0,38,FALSE,FALSE,2 +3,0,38,FALSE,FALSE,2 +3,0,38,FALSE,FALSE,2 +0.7,2,32,FALSE,FALSE,5.65 +8.3,2,34,FALSE,TRUE,2.23 +8.3,2,34,FALSE,TRUE,2.23 +1.5,1,26,FALSE,TRUE,4.16 +0.7,2,40,TRUE,FALSE,7.05 +0.7,2,40,TRUE,FALSE,7.05 +2.2,1,42,TRUE,TRUE,1.78 +10.4,0,30,FALSE,TRUE,6.61 +10.4,0,30,FALSE,TRUE,6.61 +4.2,1,34,TRUE,TRUE,4.97 +9.6,2,42,TRUE,TRUE,3.34 +9.6,2,42,TRUE,TRUE,3.34 +0.4,2,47,FALSE,TRUE,1.53 +0.4,2,47,FALSE,TRUE,1.53 +0.4,2,47,FALSE,TRUE,1.53 +1,1,35,TRUE,FALSE,2.4 +2.4,1,61,FALSE,FALSE,3.5 +2.4,1,61,FALSE,FALSE,3.5 +4.6,2,38,TRUE,TRUE,5.03 +0.4,2,38,TRUE,TRUE,2.43 +1.5,2,29,FALSE,TRUE,0.08 +4.1,1,37,TRUE,FALSE,4.09 +4.1,1,37,TRUE,FALSE,4.09 +2.3,1,46,TRUE,TRUE,3.48 +2.3,1,46,TRUE,TRUE,3.48 +2.3,1,46,TRUE,TRUE,3.48 +10.4,0,36,TRUE,FALSE,4.47 +8.5,1,29,FALSE,FALSE,3.52 +2.4,1,38,FALSE,TRUE,1.05 +1.2,1,29,FALSE,FALSE,2.83 +4.8,2,35,FALSE,TRUE,5.6 +4.8,2,35,FALSE,TRUE,5.6 +2.2,1,39,FALSE,TRUE,7.4 +6.5,1,23,FALSE,FALSE,2.32 +0.8,1,48,FALSE,TRUE,1.37 +0.9,1,26,FALSE,TRUE,3.16 +3.4,1,34,FALSE,TRUE,1.33 +1.6,1,20,FALSE,FALSE,4.96 +3.2,1,31,FALSE,TRUE,4.45 +3.2,1,31,FALSE,TRUE,4.45 +3.2,1,31,FALSE,TRUE,4.45 +0.5,1,56,FALSE,TRUE,0.16 +1.5,2,37,FALSE,TRUE,4.6 +2.1,1,31,FALSE,FALSE,8.41 +1.7,1,41,TRUE,TRUE,6.69 +0.8,1,49,TRUE,TRUE,3.13 +0.8,1,49,TRUE,TRUE,3.13 +0.02,2,30,FALSE,FALSE,5.29 +0.02,2,30,FALSE,FALSE,5.29 +0.02,2,30,FALSE,FALSE,5.29 +0.02,2,30,FALSE,FALSE,5.29 +0.02,2,30,FALSE,FALSE,5.29 +1.4,1,47,TRUE,TRUE,7.28 +1.4,1,47,TRUE,TRUE,7.28 +1.4,1,47,TRUE,TRUE,7.28 +1.4,1,47,TRUE,TRUE,7.28 +1.4,1,47,TRUE,TRUE,7.28 +2.2,1,37,FALSE,FALSE,2.84 +0.6,2,42,TRUE,TRUE,0.96 +0.6,2,42,TRUE,TRUE,0.96 +0.5,1,34,FALSE,FALSE,0.07 +0.5,1,34,FALSE,FALSE,0.07 +3.1,1,46,FALSE,FALSE,3.64 +6.4,0,29,FALSE,TRUE,5.62 +6.4,0,29,FALSE,TRUE,5.62 +6.4,0,29,FALSE,TRUE,5.62 +0.6,1,32,TRUE,FALSE,5.79 +2,1,41,FALSE,FALSE,4.67 +2,1,41,FALSE,FALSE,4.67 +1.6,1,36,TRUE,FALSE,3.39 +1.6,1,36,TRUE,FALSE,3.39 +0.02,2,45,TRUE,FALSE,4.69 +0.02,2,45,TRUE,FALSE,4.69 +2.1,1,47,FALSE,FALSE,3.32 +4,2,34,FALSE,TRUE,3.97 +10.8,0,32,FALSE,FALSE,7.29 +10.8,0,32,FALSE,FALSE,7.29 +4.8,0,27,FALSE,FALSE,12.25 +4.8,0,27,FALSE,FALSE,12.25 +0.02,2,31,TRUE,FALSE,5.39 +10.5,0,35,TRUE,TRUE,4.44 +1.9,2,37,FALSE,TRUE,0.22 +0.4,1,40,FALSE,TRUE,2.09 +2.3,2,28,FALSE,TRUE,5.48 +4.7,1,32,FALSE,TRUE,6.04 +1.9,1,28,FALSE,TRUE,4.66 +1.9,1,28,FALSE,TRUE,4.66 +3.1,2,27,TRUE,TRUE,1.61 +0.8,2,38,FALSE,TRUE,0 +1.6,2,33,FALSE,TRUE,2.31 +1.6,2,33,FALSE,TRUE,2.31 +1.6,2,33,FALSE,TRUE,2.31 +0.9,1,39,FALSE,TRUE,2.84 +0.3,2,43,TRUE,TRUE,2.44 +0.7,2,49,TRUE,FALSE,4.44 +3.2,1,31,FALSE,FALSE,5.05 +2.9,1,47,FALSE,FALSE,3.15 +0.3,0,32,FALSE,FALSE,2.88 +1.5,2,42,FALSE,TRUE,0.84 +1.9,1,41,FALSE,TRUE,2.63 +2.6,1,40,FALSE,FALSE,5.47 +0.5,2,37,FALSE,TRUE,0.68 +4.2,1,25,FALSE,FALSE,3.29 +5.4,1,50,TRUE,TRUE,2.57 +1.7,1,47,TRUE,TRUE,2.56 +10.6,0,21,FALSE,FALSE,5.97 +1.9,1,36,TRUE,FALSE,1.68 +1.9,1,36,TRUE,FALSE,1.68 +7.4,2,26,FALSE,FALSE,8.61 +0.9,1,24,FALSE,TRUE,1.3 +0.9,1,24,FALSE,TRUE,1.3 +0.9,1,24,FALSE,TRUE,1.3 +0.9,1,24,FALSE,TRUE,1.3 +0.4,1,27,FALSE,TRUE,2.56 +0.4,1,27,FALSE,TRUE,2.56 +2.1,2,33,FALSE,TRUE,11.79 +2.5,1,23,FALSE,FALSE,2.3 +2.5,1,23,FALSE,FALSE,2.3 +2.5,1,23,FALSE,FALSE,2.3 +8.4,1,27,FALSE,TRUE,4.43 +0.4,2,35,FALSE,FALSE,0.98 +0.9,1,48,FALSE,FALSE,0.99 +0.9,1,48,FALSE,FALSE,0.99 +0.3,2,34,TRUE,TRUE,0.6 +3.4,2,39,TRUE,FALSE,9.83 +0.1,2,43,TRUE,FALSE,10.94 +1.8,1,28,FALSE,FALSE,4.58 +3.3,1,28,FALSE,TRUE,7.45 +3.3,1,28,FALSE,TRUE,7.45 +1.9,1,40,TRUE,TRUE,0.1 +1.9,1,40,TRUE,TRUE,0.1 +1.9,1,40,TRUE,TRUE,0.1 +0.4,1,34,FALSE,FALSE,0.77 +1.4,1,56,FALSE,TRUE,0.28 +1.4,1,56,FALSE,TRUE,0.28 +3.6,1,27,FALSE,TRUE,2.86 +3.6,1,27,FALSE,TRUE,2.86 +1,1,36,FALSE,TRUE,4.25 +1,1,36,FALSE,TRUE,4.25 +1,1,36,FALSE,TRUE,4.25 +4,1,35,FALSE,TRUE,3.19 +1.1,1,43,FALSE,FALSE,2.03 +1.1,1,43,FALSE,FALSE,2.03 +1.1,1,43,FALSE,FALSE,2.03 +1.2,1,53,FALSE,TRUE,1.25 +1.2,1,53,FALSE,TRUE,1.25 +1.2,1,53,FALSE,TRUE,1.25 +4.8,1,33,FALSE,TRUE,3.92 +4.8,1,33,FALSE,TRUE,3.92 +7.5,1,39,FALSE,FALSE,3.28 +0.5,2,44,TRUE,TRUE,2.18 +1.3,1,22,FALSE,FALSE,6.5 +1.4,0,34,TRUE,FALSE,2.3 +8.4,1,28,FALSE,FALSE,4.65 +8.4,1,28,FALSE,FALSE,4.65 +1.7,2,35,TRUE,TRUE,12.67 +1.7,2,35,TRUE,TRUE,12.67 +3.5,1,40,TRUE,TRUE,2.51 +1.6,1,50,TRUE,FALSE,4.23 +2.3,1,26,TRUE,TRUE,6.53 +1.6,1,43,FALSE,TRUE,2.23 +2.9,1,26,FALSE,TRUE,3.28 +2.9,1,26,FALSE,TRUE,3.28 +0.9,2,41,FALSE,TRUE,4.46 +10.7,0,32,FALSE,FALSE,9.46 +10.7,0,32,FALSE,FALSE,9.46 +8.8,1,32,FALSE,TRUE,3.99 +8.8,1,32,FALSE,TRUE,3.99 +8.8,1,32,FALSE,TRUE,3.99 +0.02,1,35,FALSE,FALSE,2.79 +3.2,1,31,FALSE,TRUE,5.73 +3.2,1,31,FALSE,TRUE,5.73 +3.3,2,44,TRUE,FALSE,4.99 +3.3,2,44,TRUE,FALSE,4.99 +2.7,1,27,FALSE,TRUE,6.2 +10.3,0,46,TRUE,TRUE,9.31 +10.3,0,46,TRUE,TRUE,9.31 +2.7,2,47,TRUE,TRUE,2.02 +0.8,2,46,FALSE,FALSE,1.98 +1.2,1,41,FALSE,FALSE,1.71 +1.3,1,36,FALSE,FALSE,1.47 +1,2,29,TRUE,FALSE,2.33 +6.2,1,59,FALSE,FALSE,3.89 +3.7,1,26,FALSE,TRUE,5.71 +1.9,2,37,FALSE,TRUE,4.25 +1.9,2,37,FALSE,TRUE,4.25 +0.4,2,36,FALSE,TRUE,0.19 +0.4,2,36,FALSE,TRUE,0.19 +1.7,1,27,FALSE,FALSE,2.51 +1.7,1,27,FALSE,FALSE,2.51 +4.4,2,28,FALSE,TRUE,1.82 +4.4,2,28,FALSE,TRUE,1.82 +2.4,1,43,FALSE,TRUE,3.56 +1.2,1,48,TRUE,TRUE,2.81 +1.2,1,48,TRUE,TRUE,2.81 +2.5,1,41,FALSE,TRUE,7.78 +1.2,1,57,FALSE,FALSE,0.17 +2.6,0,38,TRUE,FALSE,0.14 +0.5,0,37,FALSE,FALSE,2.85 +4,0,43,TRUE,TRUE,9.07 +4,0,43,TRUE,TRUE,9.07 +4,0,43,TRUE,TRUE,9.07 +10.5,0,44,TRUE,TRUE,3.16 +5.5,0,29,FALSE,TRUE,12.32 +5.5,0,29,FALSE,TRUE,12.32 +9.5,1,41,FALSE,FALSE,6.1 +9.5,1,41,FALSE,FALSE,6.1 +3.8,1,27,FALSE,TRUE,2.53 +0.8,2,46,TRUE,FALSE,12.24 +0.8,2,46,TRUE,FALSE,12.24 +1,1,46,TRUE,FALSE,3.24 +0.8,2,39,FALSE,FALSE,1.16 +0.8,2,39,FALSE,FALSE,1.16 +2.3,1,44,TRUE,FALSE,4.53 +1.8,2,31,FALSE,TRUE,1.9 +1.8,2,31,FALSE,TRUE,1.9 +4.8,2,41,TRUE,TRUE,0.63 +4.8,2,41,TRUE,TRUE,0.63 +2.2,1,26,FALSE,TRUE,5.42 +2.2,1,26,FALSE,TRUE,5.42 +1.9,1,48,TRUE,TRUE,1.63 +0.5,2,34,TRUE,TRUE,7.83 +1.1,1,21,FALSE,FALSE,3.79 +3,1,21,FALSE,FALSE,2.99 +3,1,21,FALSE,FALSE,2.99 +3,1,21,FALSE,FALSE,2.99 +1.4,1,28,FALSE,FALSE,5.37 +1.4,1,28,FALSE,FALSE,5.37 +1.2,2,37,TRUE,FALSE,3.23 +1.2,2,37,TRUE,FALSE,3.23 +1.2,2,37,TRUE,FALSE,3.23 +1.2,2,37,TRUE,FALSE,3.23 +0.9,0,36,TRUE,TRUE,1.32 +2.2,2,42,TRUE,TRUE,3.33 +2.2,2,42,TRUE,TRUE,3.33 +2.2,2,42,TRUE,TRUE,3.33 +4.3,1,66,FALSE,TRUE,3.4 +4.5,1,40,TRUE,TRUE,5.19 +4.5,1,40,TRUE,TRUE,5.19 +3.2,2,42,TRUE,FALSE,7.57 +3.2,2,42,TRUE,FALSE,7.57 +1.5,1,25,FALSE,TRUE,2.25 +0.7,2,21,FALSE,TRUE,0.99 +1.2,2,44,FALSE,FALSE,0.45 +0.9,2,37,FALSE,TRUE,0.13 +0.9,2,37,FALSE,TRUE,0.13 +2.6,1,46,FALSE,TRUE,1.88 +0.4,2,32,TRUE,FALSE,7.18 +0.4,2,32,TRUE,FALSE,7.18 +0.4,2,32,TRUE,FALSE,7.18 +0.4,2,32,TRUE,FALSE,7.18 +1.6,0,31,FALSE,FALSE,1.46 +1.2,1,36,TRUE,TRUE,2.64 +1.2,1,36,TRUE,TRUE,2.64 +1.2,1,36,TRUE,TRUE,2.64 +4,1,41,FALSE,FALSE,2.49 +4.2,2,67,TRUE,TRUE,3.24 +2.4,1,38,TRUE,TRUE,5.39 +2.4,1,38,TRUE,TRUE,5.39 +0.02,2,45,TRUE,TRUE,2.05 +0.5,1,73,FALSE,FALSE,1.12 +0.5,1,73,FALSE,FALSE,1.12 +2.5,1,42,FALSE,TRUE,1.67 +2.5,1,42,FALSE,TRUE,1.67 +2.9,1,21,FALSE,TRUE,4.9 +0.3,1,35,TRUE,FALSE,3.07 +10.3,0,42,TRUE,TRUE,8.17 +0.2,2,40,TRUE,TRUE,19.33 +2.6,2,47,TRUE,TRUE,1.69 +2.6,2,47,TRUE,TRUE,1.69 +2.6,2,47,TRUE,TRUE,1.69 +2.6,2,47,TRUE,TRUE,1.69 +2.6,2,47,TRUE,TRUE,1.69 +2.6,2,47,TRUE,TRUE,1.69 +4.6,2,29,FALSE,TRUE,1.67 +4.6,2,29,FALSE,TRUE,1.67 +4.4,1,40,TRUE,TRUE,5.34 +4.4,1,40,TRUE,TRUE,5.34 +1.4,2,29,TRUE,FALSE,2.02 +1.4,2,29,TRUE,FALSE,2.02 +0.6,1,35,FALSE,FALSE,0.61 +0.7,2,37,TRUE,TRUE,1.11 +0.7,2,37,TRUE,TRUE,1.11 +10.6,0,49,TRUE,FALSE,6.27 +10.6,0,49,TRUE,FALSE,6.27 +2.3,1,37,TRUE,FALSE,6 +0.9,2,30,TRUE,TRUE,0.63 +0.9,2,30,TRUE,TRUE,0.63 +3.5,2,43,TRUE,TRUE,1.94 +3.5,2,43,TRUE,TRUE,1.94 +0.8,0,31,FALSE,FALSE,6.39 +2.5,1,43,TRUE,TRUE,4.54 +2.5,1,43,TRUE,TRUE,4.54 +5.3,2,45,TRUE,TRUE,2.35 +5.3,2,45,TRUE,TRUE,2.35 +0.6,2,38,FALSE,FALSE,2.22 +1.6,1,32,FALSE,TRUE,2.37 +1,2,36,FALSE,TRUE,1.59 +1,2,36,FALSE,TRUE,1.59 +0.5,2,22,FALSE,FALSE,1.94 +0.5,2,22,FALSE,FALSE,1.94 diff --git a/src/test/resources/wihs.bootstrapped2.csv b/src/test/resources/wihs.bootstrapped2.csv new file mode 100644 index 0000000..b430ce2 --- /dev/null +++ b/src/test/resources/wihs.bootstrapped2.csv @@ -0,0 +1,1165 @@ +"time","status","ageatfda","idu","black","cd4nadir" +1.2,1,52,FALSE,TRUE,4.21 +2.2,2,27,FALSE,TRUE,6.87 +0.4,0,46,TRUE,TRUE,3.04 +1.7,2,39,FALSE,TRUE,2.05 +1.7,2,39,FALSE,TRUE,2.05 +1.7,2,39,FALSE,TRUE,2.05 +1.8,1,24,FALSE,TRUE,4.55 +1.8,1,24,FALSE,TRUE,4.55 +1.8,1,24,FALSE,TRUE,4.55 +1.4,1,27,TRUE,FALSE,3.69 +1.4,1,27,TRUE,FALSE,3.69 +2.1,1,30,FALSE,TRUE,5.17 +0.8,2,32,TRUE,FALSE,2.08 +2.6,1,31,FALSE,TRUE,7.99 +6.7,1,31,FALSE,TRUE,4 +1.1,1,33,TRUE,FALSE,2.83 +1.1,1,33,TRUE,FALSE,2.83 +1.5,1,33,FALSE,TRUE,3.96 +4,1,30,TRUE,FALSE,6.81 +1.3,1,41,FALSE,FALSE,2.6 +2,1,34,TRUE,TRUE,3.48 +3.3,1,39,FALSE,TRUE,1.49 +3.3,1,39,FALSE,TRUE,1.49 +2,1,30,FALSE,TRUE,3.22 +2,1,30,FALSE,TRUE,3.22 +2,1,30,FALSE,TRUE,3.22 +1.5,1,48,FALSE,TRUE,2.23 +0.8,1,35,TRUE,FALSE,1.66 +0.8,1,35,TRUE,FALSE,1.66 +10.7,0,29,FALSE,FALSE,5.23 +10.7,0,29,FALSE,FALSE,5.23 +10.7,0,29,FALSE,FALSE,5.23 +6.1,0,45,TRUE,TRUE,12.06 +2.1,1,30,TRUE,TRUE,5.33 +2.1,1,30,TRUE,TRUE,5.33 +1.1,1,33,FALSE,FALSE,3.39 +1.1,1,33,FALSE,FALSE,3.39 +6.2,2,42,TRUE,FALSE,8.36 +0.8,1,50,TRUE,TRUE,3.24 +2.5,1,33,FALSE,TRUE,6.64 +2.5,1,33,FALSE,TRUE,6.64 +2.5,1,33,FALSE,TRUE,6.64 +2.5,1,33,FALSE,TRUE,6.64 +2.5,1,33,FALSE,TRUE,6.64 +10.4,0,44,TRUE,TRUE,11.63 +10.4,0,44,TRUE,TRUE,11.63 +0.7,0,29,TRUE,TRUE,6.26 +1.2,1,56,FALSE,TRUE,2.36 +5.3,2,45,FALSE,TRUE,1.72 +3.9,1,39,TRUE,TRUE,4.05 +10.4,0,38,FALSE,TRUE,4.77 +5.6,2,45,TRUE,TRUE,9.92 +0.9,1,33,FALSE,FALSE,2.16 +1.2,1,39,TRUE,TRUE,4.97 +0.9,2,39,TRUE,TRUE,0.06 +1.1,1,39,FALSE,TRUE,3.59 +2.2,1,29,FALSE,FALSE,2.85 +2.2,1,29,FALSE,FALSE,2.85 +2.2,1,29,FALSE,FALSE,2.85 +2.2,1,29,FALSE,FALSE,2.85 +1,1,31,FALSE,FALSE,0.93 +2.2,2,45,TRUE,TRUE,8.4 +1.6,1,33,FALSE,TRUE,2.2 +1.6,1,33,FALSE,TRUE,2.2 +2.5,1,29,FALSE,TRUE,4.89 +2.5,1,29,FALSE,TRUE,4.89 +2.8,2,39,TRUE,FALSE,4.13 +2.8,2,39,TRUE,FALSE,4.13 +1.5,1,34,TRUE,TRUE,7.67 +1.5,1,34,TRUE,TRUE,7.67 +1.3,1,56,TRUE,TRUE,2.23 +1.3,1,56,TRUE,TRUE,2.23 +1,1,38,FALSE,FALSE,1.88 +1.4,1,35,FALSE,FALSE,2.88 +1.4,1,35,FALSE,FALSE,2.88 +1.4,1,35,FALSE,FALSE,2.88 +1.4,1,35,FALSE,FALSE,2.88 +2.1,1,30,FALSE,TRUE,1.17 +8.2,0,36,FALSE,FALSE,6.11 +8.2,0,36,FALSE,FALSE,6.11 +8.2,0,36,FALSE,FALSE,6.11 +10.7,0,28,FALSE,TRUE,5.62 +4.6,1,33,TRUE,FALSE,8.78 +4.3,1,23,TRUE,TRUE,3.87 +6,2,29,FALSE,TRUE,3.79 +6,2,29,FALSE,TRUE,3.79 +0.3,2,40,TRUE,TRUE,1.94 +0.3,2,40,TRUE,TRUE,1.94 +10.6,1,23,FALSE,FALSE,4.89 +10.6,1,23,FALSE,FALSE,4.89 +1,2,44,TRUE,TRUE,5.95 +1.1,2,37,FALSE,FALSE,5.51 +1.1,2,37,FALSE,FALSE,5.51 +1.4,2,27,FALSE,TRUE,2.58 +1.7,1,24,FALSE,TRUE,4.49 +0.2,2,44,TRUE,TRUE,1.16 +3.4,2,44,TRUE,FALSE,3.4 +3.4,2,44,TRUE,FALSE,3.4 +3.4,2,44,TRUE,FALSE,3.4 +1.3,1,46,TRUE,TRUE,3.24 +1.3,1,46,TRUE,TRUE,3.24 +1.3,1,46,TRUE,TRUE,3.24 +1.3,1,46,TRUE,TRUE,3.24 +0.3,2,31,TRUE,TRUE,6.29 +9,1,44,FALSE,TRUE,8.21 +9,1,44,FALSE,TRUE,8.21 +2,1,22,FALSE,FALSE,2.84 +2,1,22,FALSE,FALSE,2.84 +2.6,2,37,TRUE,TRUE,1.94 +2.6,2,37,TRUE,TRUE,1.94 +7,2,45,TRUE,TRUE,2.52 +0.1,2,67,TRUE,TRUE,1.47 +0.1,2,67,TRUE,TRUE,1.47 +1.8,2,42,TRUE,FALSE,1.66 +1.8,2,42,TRUE,FALSE,1.66 +4,1,35,TRUE,FALSE,4.84 +3.6,2,39,TRUE,FALSE,1.18 +5.2,1,30,FALSE,TRUE,2.8 +10.2,0,32,FALSE,TRUE,2.9 +10.2,0,32,FALSE,TRUE,2.9 +0.9,1,37,FALSE,FALSE,0.52 +1.5,1,37,TRUE,FALSE,3.2 +1.5,1,37,TRUE,FALSE,3.2 +2,1,34,FALSE,TRUE,3.3 +2,1,34,FALSE,TRUE,3.3 +1.2,1,26,FALSE,FALSE,5.63 +0.2,2,39,FALSE,TRUE,0.41 +7.3,1,29,FALSE,TRUE,10.67 +7.3,1,29,FALSE,TRUE,10.67 +5.9,2,21,FALSE,FALSE,8 +1.8,2,32,TRUE,FALSE,0.34 +1.8,2,32,TRUE,FALSE,0.34 +4.1,2,27,FALSE,FALSE,11.91 +4.1,2,27,FALSE,FALSE,11.91 +2.9,2,40,FALSE,TRUE,1.01 +2.9,2,40,FALSE,TRUE,1.01 +2.9,2,40,FALSE,TRUE,1.01 +2,1,47,TRUE,TRUE,5.28 +0.1,2,31,FALSE,TRUE,0.35 +0.1,2,31,FALSE,TRUE,0.35 +8.7,1,45,FALSE,TRUE,2.55 +8.7,1,45,FALSE,TRUE,2.55 +10.4,0,34,TRUE,TRUE,3.87 +10.4,0,34,TRUE,TRUE,3.87 +10.4,1,26,FALSE,FALSE,5.66 +2.8,1,29,FALSE,TRUE,4.68 +2.8,1,29,FALSE,TRUE,4.68 +5.3,2,35,FALSE,TRUE,3.75 +0.3,2,44,TRUE,TRUE,2.97 +0.8,1,38,FALSE,TRUE,3.5 +7.2,0,27,FALSE,FALSE,4.04 +4.7,1,37,TRUE,TRUE,2.9 +4.7,1,37,TRUE,TRUE,2.9 +4.7,1,37,TRUE,TRUE,2.9 +4.7,1,37,TRUE,TRUE,2.9 +0.6,0,37,FALSE,TRUE,4.85 +0.6,0,37,FALSE,TRUE,4.85 +0.7,0,40,FALSE,TRUE,3.34 +10.6,0,42,TRUE,TRUE,3.73 +3.4,1,28,TRUE,TRUE,1.72 +3.4,1,28,TRUE,TRUE,1.72 +3.4,1,28,TRUE,TRUE,1.72 +3.6,1,36,FALSE,TRUE,5.6 +3.6,1,36,FALSE,TRUE,5.6 +3.6,1,36,FALSE,TRUE,5.6 +3.6,1,36,FALSE,TRUE,5.6 +3.2,2,48,TRUE,TRUE,4.99 +6.6,0,36,FALSE,TRUE,4.23 +6.6,0,36,FALSE,TRUE,4.23 +6.6,0,36,FALSE,TRUE,4.23 +2.4,1,18,FALSE,TRUE,4.52 +2.4,1,18,FALSE,TRUE,4.52 +3.3,1,26,FALSE,FALSE,2.42 +3.3,1,26,FALSE,FALSE,2.42 +1.8,1,30,FALSE,FALSE,3.82 +1.5,1,35,FALSE,FALSE,3.29 +1.5,1,35,FALSE,FALSE,3.29 +0.7,1,37,FALSE,FALSE,6.52 +6.8,0,27,FALSE,TRUE,6.38 +0.7,1,45,FALSE,TRUE,0.77 +0.2,2,40,TRUE,TRUE,0.06 +3.7,1,43,TRUE,TRUE,2.95 +7.8,1,30,FALSE,TRUE,4.59 +7.8,1,30,FALSE,TRUE,4.59 +3.3,1,46,FALSE,TRUE,3.64 +3.3,1,46,FALSE,TRUE,3.64 +10.7,0,39,FALSE,TRUE,3.21 +1.4,1,34,FALSE,FALSE,0.72 +1.9,1,31,FALSE,TRUE,2.98 +1,1,36,FALSE,FALSE,1.98 +2.2,1,42,FALSE,TRUE,3.23 +2.2,1,42,FALSE,TRUE,3.23 +2.2,1,42,FALSE,TRUE,3.23 +1.2,1,36,FALSE,TRUE,1.56 +1.2,1,36,FALSE,TRUE,1.56 +0.6,1,38,TRUE,FALSE,0.75 +1.1,2,32,FALSE,TRUE,2.11 +5.8,1,49,TRUE,TRUE,4.23 +5.8,1,49,TRUE,TRUE,4.23 +4.7,1,43,TRUE,TRUE,5.46 +4.7,1,43,TRUE,TRUE,5.46 +2.2,2,38,TRUE,TRUE,3.44 +0.6,1,38,TRUE,TRUE,3.38 +0.6,1,38,TRUE,TRUE,3.38 +1.9,1,27,FALSE,TRUE,4.13 +7.8,1,46,FALSE,TRUE,3.86 +7.8,1,46,FALSE,TRUE,3.86 +7.8,1,46,FALSE,TRUE,3.86 +1.2,1,52,FALSE,TRUE,2.13 +4.4,1,35,FALSE,FALSE,4.31 +4.4,1,35,FALSE,FALSE,4.31 +7.8,1,37,TRUE,FALSE,3.64 +7.8,1,37,TRUE,FALSE,3.64 +1.1,1,46,FALSE,TRUE,1.42 +3.6,2,28,FALSE,FALSE,3.03 +0.4,2,38,FALSE,FALSE,1.94 +2.6,1,61,FALSE,FALSE,3.75 +2.6,1,61,FALSE,FALSE,3.75 +0.8,1,38,FALSE,FALSE,3.38 +1.2,2,41,TRUE,FALSE,2.81 +2,1,30,TRUE,FALSE,3.65 +3.6,1,58,FALSE,TRUE,3.91 +3.6,1,58,FALSE,TRUE,3.91 +3.6,1,58,FALSE,TRUE,3.91 +3.6,1,58,FALSE,TRUE,3.91 +2.5,1,39,FALSE,FALSE,2.59 +1.4,1,40,FALSE,FALSE,2.49 +1.7,1,35,FALSE,TRUE,4.87 +1.7,1,35,FALSE,TRUE,4.87 +1.3,2,42,TRUE,TRUE,1.84 +1.8,1,45,FALSE,FALSE,5.26 +1.8,1,45,FALSE,FALSE,5.26 +4.2,1,47,TRUE,TRUE,5.88 +2,2,26,FALSE,TRUE,3.48 +2,2,26,FALSE,TRUE,3.48 +0.4,1,37,FALSE,FALSE,0.52 +0.4,2,36,FALSE,TRUE,4.44 +0.4,2,36,FALSE,TRUE,4.44 +0.4,2,36,FALSE,TRUE,4.44 +0.4,2,36,FALSE,TRUE,4.44 +1.2,2,42,FALSE,FALSE,8.52 +1.6,1,54,FALSE,TRUE,2.41 +1.6,1,54,FALSE,TRUE,2.41 +1.6,1,54,FALSE,TRUE,2.41 +1.2,1,38,TRUE,FALSE,4.14 +9.1,1,49,TRUE,TRUE,7.13 +9.3,1,31,FALSE,TRUE,9.7 +10.5,0,37,FALSE,FALSE,7.02 +10.3,2,51,FALSE,TRUE,10.68 +1,1,32,FALSE,FALSE,0 +2.2,1,29,FALSE,TRUE,2.81 +0.2,1,38,FALSE,FALSE,1.02 +0.2,1,38,FALSE,FALSE,1.02 +0.2,1,38,FALSE,FALSE,1.02 +0.2,1,38,FALSE,FALSE,1.02 +0.3,2,32,TRUE,FALSE,0.09 +1,1,42,TRUE,TRUE,2.19 +1,2,54,FALSE,TRUE,6.42 +3.9,1,32,FALSE,TRUE,3.35 +3.9,1,32,FALSE,TRUE,3.35 +1.2,1,38,FALSE,TRUE,3 +4.8,1,39,FALSE,TRUE,8.96 +4.8,1,39,FALSE,TRUE,8.96 +4.8,1,39,FALSE,TRUE,8.96 +3,2,38,TRUE,TRUE,5.27 +1.1,1,36,TRUE,FALSE,1.92 +1.8,1,44,TRUE,FALSE,6.54 +4.9,0,29,FALSE,TRUE,3.71 +10.4,0,38,TRUE,FALSE,3.69 +10.4,0,38,TRUE,FALSE,3.69 +9.1,1,34,FALSE,FALSE,5.95 +1.3,1,33,FALSE,FALSE,2.9 +1.4,1,27,FALSE,FALSE,1.33 +1.4,1,27,FALSE,FALSE,1.33 +0.7,2,45,TRUE,TRUE,2.17 +0.7,2,45,TRUE,TRUE,2.17 +0.7,2,45,TRUE,TRUE,2.17 +2,1,38,FALSE,FALSE,3.3 +0.8,1,27,FALSE,FALSE,0.8 +0.1,2,47,FALSE,FALSE,0.14 +1.2,1,43,FALSE,FALSE,12.06 +1.2,1,43,FALSE,FALSE,12.06 +1.2,1,43,FALSE,FALSE,12.06 +7.2,1,37,FALSE,TRUE,3.53 +4.4,1,35,FALSE,FALSE,4.01 +4.4,1,35,FALSE,FALSE,4.01 +0.6,2,29,TRUE,TRUE,5.44 +5.6,2,36,TRUE,TRUE,8.41 +5.6,2,36,TRUE,TRUE,8.41 +5.6,2,36,TRUE,TRUE,8.41 +10.7,0,33,FALSE,TRUE,3.56 +10.7,0,33,FALSE,TRUE,3.56 +4.8,1,28,FALSE,TRUE,7.85 +1,1,38,TRUE,TRUE,0.2 +0.4,1,37,TRUE,TRUE,1.53 +0.4,1,37,TRUE,TRUE,1.53 +1.8,1,42,TRUE,TRUE,1.15 +2.2,1,31,FALSE,FALSE,2.36 +2.2,1,31,FALSE,FALSE,2.36 +2.2,1,31,FALSE,FALSE,2.36 +2.2,1,31,FALSE,FALSE,2.36 +1.5,0,30,FALSE,FALSE,3.36 +1.5,0,30,FALSE,FALSE,3.36 +1.5,2,44,TRUE,TRUE,4.35 +1.5,2,44,TRUE,TRUE,4.35 +1.8,1,38,FALSE,FALSE,5.43 +4.2,1,29,FALSE,TRUE,2.89 +1.7,1,54,FALSE,TRUE,2.81 +1.4,1,25,FALSE,FALSE,0.93 +1.4,1,27,FALSE,TRUE,4.49 +1.4,1,27,FALSE,TRUE,4.49 +1.8,1,26,FALSE,FALSE,6.36 +3.3,1,37,FALSE,TRUE,6.15 +1.3,1,56,FALSE,FALSE,2.86 +1.4,1,41,TRUE,TRUE,2.28 +1.4,1,41,TRUE,TRUE,2.28 +1.4,1,41,TRUE,TRUE,2.28 +1.4,1,41,TRUE,TRUE,2.28 +1.3,1,33,FALSE,FALSE,0.3 +3.7,1,28,TRUE,TRUE,3.58 +3.7,1,28,TRUE,TRUE,3.58 +3.7,1,28,TRUE,TRUE,3.58 +4.2,2,41,FALSE,TRUE,1.72 +1.5,1,39,TRUE,TRUE,2.94 +1.5,1,39,TRUE,TRUE,2.94 +1.5,1,39,TRUE,TRUE,2.94 +4.5,1,24,FALSE,TRUE,5.88 +1.2,1,28,FALSE,FALSE,4.58 +1.2,1,28,FALSE,FALSE,4.58 +1.2,1,28,FALSE,FALSE,4.58 +1.4,1,32,FALSE,FALSE,4.36 +3.5,1,42,TRUE,FALSE,4.78 +3.5,1,42,TRUE,FALSE,4.78 +3.5,1,42,TRUE,FALSE,4.78 +3.5,1,42,TRUE,FALSE,4.78 +1.4,1,32,FALSE,FALSE,1.88 +3.7,2,40,FALSE,FALSE,7.38 +7.3,2,28,FALSE,TRUE,0.99 +7.3,2,28,FALSE,TRUE,0.99 +7.3,2,28,FALSE,TRUE,0.99 +0.9,2,42,TRUE,TRUE,1.94 +0.9,2,42,TRUE,TRUE,1.94 +0.6,2,44,FALSE,FALSE,0.87 +1.2,1,38,TRUE,TRUE,5.95 +1.4,1,52,FALSE,TRUE,3.92 +1.4,1,52,FALSE,TRUE,3.92 +10.5,0,29,FALSE,TRUE,4.72 +2.2,1,40,FALSE,TRUE,8.2 +2.2,1,40,FALSE,TRUE,8.2 +1.6,1,37,FALSE,FALSE,5.85 +1.6,1,37,FALSE,FALSE,5.85 +1.6,1,37,FALSE,FALSE,5.85 +4.4,2,32,TRUE,FALSE,2.26 +1.2,1,33,TRUE,FALSE,3.38 +1.5,1,41,TRUE,TRUE,3.94 +7.8,0,40,TRUE,FALSE,3.08 +1.3,1,41,TRUE,TRUE,1.35 +1.3,1,41,TRUE,TRUE,1.35 +1.3,1,41,TRUE,TRUE,1.35 +0.6,1,42,TRUE,TRUE,2.12 +1.6,2,45,TRUE,TRUE,4.23 +3.1,2,29,FALSE,TRUE,2.47 +1.3,1,37,FALSE,TRUE,4.52 +1.3,1,37,FALSE,TRUE,4.52 +6.1,1,33,TRUE,TRUE,4.52 +0.7,2,32,FALSE,TRUE,0.5 +10.3,0,25,FALSE,FALSE,4.97 +5.4,1,30,FALSE,TRUE,4.61 +6,0,24,FALSE,TRUE,13.9 +0.9,1,40,FALSE,TRUE,1.83 +0.9,1,40,FALSE,TRUE,1.83 +0.9,1,40,FALSE,TRUE,1.83 +3,1,35,TRUE,FALSE,6.13 +2,1,34,TRUE,FALSE,1.49 +2,1,34,TRUE,FALSE,1.49 +1.5,1,35,TRUE,FALSE,3.96 +7.5,1,34,FALSE,TRUE,6.85 +5.1,1,37,FALSE,TRUE,2.87 +5.1,1,37,FALSE,TRUE,2.87 +5.1,1,37,FALSE,TRUE,2.87 +0.8,2,45,TRUE,TRUE,9.82 +0.8,2,45,TRUE,TRUE,9.82 +1.1,2,34,TRUE,TRUE,3.27 +0.7,1,37,TRUE,FALSE,3.91 +0.7,1,37,TRUE,FALSE,3.91 +2.2,2,39,TRUE,FALSE,1.59 +2.2,2,39,TRUE,FALSE,1.59 +2.2,2,39,TRUE,FALSE,1.59 +2.2,2,39,TRUE,FALSE,1.59 +1.1,2,45,TRUE,TRUE,4.13 +2.9,1,57,FALSE,FALSE,6.69 +1.6,0,32,FALSE,TRUE,2.57 +1,1,33,TRUE,TRUE,0.88 +1,1,33,TRUE,TRUE,0.88 +1,1,28,FALSE,TRUE,2.34 +1,1,28,FALSE,TRUE,2.34 +1,1,28,FALSE,TRUE,2.34 +2.7,1,40,TRUE,TRUE,4.58 +2.7,1,40,TRUE,TRUE,4.58 +0.8,1,35,FALSE,FALSE,4.84 +10.4,0,38,TRUE,TRUE,5.5 +10.4,0,38,TRUE,TRUE,5.5 +10.4,0,38,TRUE,TRUE,5.5 +10.4,0,38,TRUE,TRUE,5.5 +1.2,1,33,TRUE,TRUE,3.6 +10.8,0,30,FALSE,FALSE,4.94 +2.2,1,23,FALSE,FALSE,3.84 +1.1,1,48,FALSE,TRUE,4.74 +1.1,1,48,FALSE,TRUE,4.74 +1.1,1,48,FALSE,TRUE,4.74 +6.1,1,24,FALSE,TRUE,3.62 +6.1,1,24,FALSE,TRUE,3.62 +9.7,1,31,FALSE,TRUE,3.42 +0.02,2,48,FALSE,TRUE,6.95 +0.02,2,48,FALSE,TRUE,6.95 +1.6,1,21,FALSE,FALSE,5.62 +2.2,2,44,TRUE,TRUE,3.76 +2.2,2,44,TRUE,TRUE,3.76 +1.3,2,46,TRUE,TRUE,0.35 +1.8,1,18,FALSE,TRUE,5.72 +0.4,1,34,FALSE,FALSE,0.86 +0.4,1,34,FALSE,FALSE,0.86 +0.4,1,34,FALSE,FALSE,0.86 +2.7,1,31,FALSE,FALSE,5.28 +2.7,1,31,FALSE,FALSE,5.28 +2.2,1,42,TRUE,TRUE,6.33 +2.2,1,42,TRUE,TRUE,6.33 +2.2,1,42,TRUE,TRUE,6.33 +2.2,1,42,TRUE,TRUE,6.33 +2.2,1,42,TRUE,TRUE,6.33 +0.4,2,42,FALSE,FALSE,4.86 +0.4,2,42,FALSE,FALSE,4.86 +1,2,21,FALSE,TRUE,2.75 +0.6,1,34,TRUE,FALSE,3.38 +0.6,1,34,TRUE,FALSE,3.38 +1.9,2,44,TRUE,TRUE,1.69 +1.9,2,44,TRUE,TRUE,1.69 +2,1,58,FALSE,TRUE,2.9 +1.5,2,40,FALSE,TRUE,3.91 +1.5,2,40,FALSE,TRUE,3.91 +2.7,1,38,TRUE,TRUE,5.22 +2.7,1,38,TRUE,TRUE,5.22 +2.7,1,38,TRUE,TRUE,5.22 +1.8,1,32,FALSE,TRUE,2.89 +1.3,1,42,FALSE,FALSE,7.71 +1.3,1,42,FALSE,FALSE,7.71 +4.7,2,37,FALSE,TRUE,1.76 +1.5,2,44,TRUE,FALSE,1.47 +0.8,1,42,FALSE,FALSE,3.26 +1.8,1,26,FALSE,FALSE,3.48 +1.8,1,26,FALSE,FALSE,3.48 +1.8,1,26,FALSE,FALSE,3.48 +3,2,47,TRUE,FALSE,6.03 +1.4,1,38,FALSE,TRUE,1.84 +1.4,1,38,FALSE,TRUE,1.84 +1.4,1,38,FALSE,TRUE,1.84 +0.8,1,40,TRUE,TRUE,0.25 +0.8,1,40,TRUE,TRUE,0.25 +0.9,1,41,TRUE,FALSE,6.49 +0.9,1,41,TRUE,FALSE,6.49 +0.9,1,41,TRUE,FALSE,6.49 +0.9,1,41,TRUE,FALSE,6.49 +1.5,1,57,FALSE,TRUE,3.32 +2.2,0,39,FALSE,TRUE,3.73 +3.6,1,31,FALSE,FALSE,6.79 +3.6,1,31,FALSE,FALSE,6.79 +3.6,1,31,FALSE,FALSE,6.79 +6,1,30,TRUE,FALSE,3.87 +6,1,30,TRUE,FALSE,3.87 +5.2,2,38,TRUE,TRUE,3.82 +5.2,2,38,TRUE,TRUE,3.82 +0.8,2,37,TRUE,TRUE,9.96 +0.8,1,32,FALSE,FALSE,3.25 +0.8,1,32,FALSE,FALSE,3.25 +0.9,2,34,FALSE,FALSE,2.1 +3.1,1,36,FALSE,TRUE,7.56 +3.1,1,36,FALSE,TRUE,7.56 +3.1,1,36,FALSE,TRUE,7.56 +1.3,1,69,FALSE,TRUE,1.6 +1.3,1,42,FALSE,FALSE,2.7 +0.7,2,34,FALSE,TRUE,0.05 +0.7,2,34,FALSE,TRUE,0.05 +1.1,1,39,FALSE,FALSE,4.02 +1.1,1,39,FALSE,FALSE,4.02 +1.1,1,39,FALSE,FALSE,4.02 +2.3,1,29,FALSE,TRUE,6.42 +4.4,1,38,FALSE,TRUE,2.83 +4.4,1,38,FALSE,TRUE,2.83 +0.2,0,37,FALSE,TRUE,4.73 +1.2,1,36,FALSE,FALSE,4.12 +1.2,1,36,FALSE,FALSE,4.12 +1.2,1,36,FALSE,FALSE,4.12 +2.2,1,33,FALSE,TRUE,4.16 +10.8,0,29,TRUE,FALSE,8.83 +5.5,2,54,FALSE,TRUE,5.17 +0.9,2,34,FALSE,TRUE,1.26 +0.9,1,38,TRUE,FALSE,1.78 +0.9,1,38,TRUE,FALSE,1.78 +10.4,0,27,TRUE,TRUE,5.51 +5,1,41,TRUE,TRUE,3.8 +0.02,2,28,FALSE,TRUE,0.18 +0.02,2,28,FALSE,TRUE,0.18 +5.5,2,39,FALSE,FALSE,2.38 +0.9,2,31,TRUE,FALSE,2.34 +6.8,0,33,FALSE,FALSE,5.79 +6.8,0,33,FALSE,FALSE,5.79 +6.8,0,33,FALSE,FALSE,5.79 +1,2,42,TRUE,TRUE,2.87 +1,2,42,TRUE,TRUE,2.87 +3.3,1,37,FALSE,TRUE,7.64 +1.6,1,43,TRUE,TRUE,1.7 +1.6,1,43,TRUE,TRUE,1.7 +1.5,1,34,FALSE,FALSE,1.98 +8.7,0,30,FALSE,FALSE,4.73 +0.9,1,33,TRUE,FALSE,1.48 +5.9,2,50,TRUE,TRUE,2.98 +2.1,0,48,FALSE,FALSE,5.28 +4,2,34,TRUE,FALSE,7.99 +4.2,1,31,FALSE,TRUE,8.15 +5.4,1,28,FALSE,TRUE,2.92 +5.4,1,28,FALSE,TRUE,2.92 +1.5,2,29,FALSE,TRUE,2.61 +1.6,1,39,FALSE,FALSE,0.6 +8.2,1,47,TRUE,TRUE,3.02 +8.2,1,47,TRUE,TRUE,3.02 +1.6,1,32,FALSE,FALSE,9.96 +1.6,1,32,FALSE,FALSE,9.96 +3.7,2,43,FALSE,TRUE,18.12 +3.7,2,43,FALSE,TRUE,18.12 +3.7,2,43,FALSE,TRUE,18.12 +3.7,2,43,FALSE,TRUE,18.12 +3.7,2,43,FALSE,TRUE,18.12 +2.7,1,41,TRUE,TRUE,3.99 +2.7,1,41,TRUE,TRUE,3.99 +0.3,1,29,FALSE,FALSE,1.8 +1.7,1,34,FALSE,TRUE,1 +1.7,0,37,FALSE,TRUE,3.7 +1.7,0,37,FALSE,TRUE,3.7 +1.3,2,39,TRUE,TRUE,2.33 +1.3,2,39,TRUE,TRUE,2.33 +1.7,1,41,FALSE,TRUE,2.98 +1.7,1,41,FALSE,TRUE,2.98 +1.7,1,41,FALSE,TRUE,2.98 +3.6,1,48,TRUE,TRUE,1.44 +3.6,2,35,TRUE,FALSE,1.69 +6.8,1,37,TRUE,TRUE,4.51 +1.6,1,33,FALSE,TRUE,4.46 +1.6,1,33,FALSE,TRUE,4.46 +0.6,1,37,TRUE,FALSE,2.85 +4.2,1,37,TRUE,TRUE,7.85 +4.2,1,37,TRUE,TRUE,7.85 +10.5,1,40,TRUE,TRUE,5.48 +10.5,1,40,TRUE,TRUE,5.48 +2.7,1,31,FALSE,FALSE,5.36 +2.7,1,31,FALSE,FALSE,5.36 +0.6,1,35,TRUE,FALSE,3.33 +3.8,1,42,FALSE,TRUE,1.79 +3.8,1,42,FALSE,TRUE,1.79 +1.6,1,54,FALSE,TRUE,4.43 +0.7,1,26,FALSE,FALSE,0.07 +1.3,1,39,FALSE,TRUE,2.05 +1.3,1,39,FALSE,TRUE,2.05 +2.8,1,37,TRUE,TRUE,7.54 +2.8,1,37,TRUE,TRUE,7.54 +2.1,1,33,FALSE,TRUE,5.46 +10.3,0,42,FALSE,TRUE,6.15 +10.3,0,42,FALSE,TRUE,6.15 +1.6,1,38,FALSE,FALSE,7.96 +3.1,1,29,FALSE,FALSE,5.42 +1.4,1,35,FALSE,FALSE,0.6 +0.8,2,35,TRUE,FALSE,2.09 +5.1,1,26,FALSE,FALSE,5.84 +1,1,43,FALSE,TRUE,1.63 +3,1,57,TRUE,TRUE,3.91 +0.4,1,41,FALSE,FALSE,3.1 +0.4,1,41,FALSE,FALSE,3.1 +7.3,1,30,FALSE,TRUE,3.84 +7.3,1,30,FALSE,TRUE,3.84 +1.5,1,42,TRUE,FALSE,5.15 +1.2,1,58,FALSE,FALSE,0.44 +1.2,1,58,FALSE,FALSE,0.44 +1.2,1,58,FALSE,FALSE,0.44 +1.2,1,58,FALSE,FALSE,0.44 +2.2,1,34,FALSE,FALSE,3.46 +2.2,1,34,FALSE,FALSE,3.46 +6.7,1,33,FALSE,TRUE,4.06 +6.7,1,33,FALSE,TRUE,4.06 +1.7,0,40,FALSE,FALSE,4.11 +4.2,1,40,FALSE,TRUE,3.62 +9.4,0,30,FALSE,TRUE,4.04 +3.2,1,32,FALSE,TRUE,5.2 +0.6,2,51,FALSE,FALSE,1.89 +1.4,1,35,FALSE,FALSE,3.82 +3.2,2,47,TRUE,FALSE,1.53 +3.2,2,47,TRUE,FALSE,1.53 +1.7,1,33,FALSE,TRUE,1.57 +1.7,1,33,FALSE,TRUE,1.57 +1.4,2,41,TRUE,TRUE,0.82 +0.8,1,34,FALSE,FALSE,8.83 +0.8,1,34,FALSE,FALSE,8.83 +0.8,1,34,FALSE,FALSE,8.83 +0.8,1,34,FALSE,FALSE,8.83 +0.6,2,27,FALSE,TRUE,1.47 +2.2,1,30,FALSE,TRUE,2.81 +2.2,1,30,FALSE,TRUE,2.81 +2.2,1,30,FALSE,TRUE,2.81 +1.2,1,32,FALSE,FALSE,3.87 +3.2,1,39,FALSE,TRUE,4.22 +0.4,2,39,FALSE,TRUE,0.62 +0.4,1,43,FALSE,FALSE,4.19 +10.8,0,20,FALSE,TRUE,12.31 +10.8,0,20,FALSE,TRUE,12.31 +10.8,0,20,FALSE,TRUE,12.31 +1.1,1,32,FALSE,TRUE,3.08 +4.6,1,40,TRUE,TRUE,5.49 +2.9,1,34,FALSE,FALSE,6.95 +2.6,2,51,FALSE,TRUE,6.69 +2.6,2,51,FALSE,TRUE,6.69 +3.3,2,40,TRUE,FALSE,2.24 +10.5,0,33,FALSE,FALSE,6.83 +1.3,1,20,FALSE,FALSE,4.14 +1.3,1,20,FALSE,FALSE,4.14 +2.4,1,28,FALSE,TRUE,3.47 +1.4,2,49,FALSE,FALSE,2.56 +1.4,2,49,FALSE,FALSE,2.56 +1.4,2,49,FALSE,FALSE,2.56 +0.8,2,38,FALSE,FALSE,10.95 +0.7,2,33,TRUE,TRUE,2.46 +0.7,2,33,TRUE,TRUE,2.46 +1.5,1,41,TRUE,FALSE,4.51 +1.5,1,41,TRUE,FALSE,4.51 +0.9,1,37,TRUE,TRUE,3.41 +2.5,1,43,TRUE,TRUE,9.48 +3.5,0,34,FALSE,TRUE,2.86 +3.5,0,34,FALSE,TRUE,2.86 +1.9,2,25,FALSE,TRUE,4.24 +1.9,2,25,FALSE,TRUE,4.24 +1.9,2,25,FALSE,TRUE,4.24 +3.5,1,35,FALSE,TRUE,2.22 +3.5,1,35,FALSE,TRUE,2.22 +0.5,1,40,TRUE,FALSE,1.53 +0.8,1,36,FALSE,FALSE,1.8 +0.8,1,36,FALSE,FALSE,1.8 +0.4,2,38,TRUE,TRUE,0.15 +0.3,1,39,FALSE,TRUE,3.82 +1.5,1,36,FALSE,TRUE,1.6 +1.5,1,36,FALSE,TRUE,1.6 +1.5,1,36,FALSE,TRUE,1.6 +1.5,1,36,FALSE,TRUE,1.6 +4.1,1,31,FALSE,TRUE,3.5 +4.1,1,31,FALSE,TRUE,3.5 +1.1,1,39,TRUE,TRUE,0.25 +1.1,1,39,TRUE,TRUE,0.25 +0.1,2,32,FALSE,TRUE,4.63 +2.8,1,28,FALSE,FALSE,2.06 +1.8,1,38,FALSE,TRUE,6.21 +1.8,1,38,FALSE,TRUE,6.21 +10.3,0,29,FALSE,TRUE,4.38 +8.8,1,26,FALSE,FALSE,4.75 +1.2,1,28,FALSE,TRUE,0.36 +1.7,1,32,FALSE,FALSE,1.89 +1.7,1,32,FALSE,FALSE,1.89 +3.7,2,23,FALSE,TRUE,5.3 +3.7,2,23,FALSE,TRUE,5.3 +9.1,1,44,TRUE,TRUE,3.79 +9.1,1,44,TRUE,TRUE,3.79 +4,2,47,TRUE,TRUE,1.39 +1.5,1,26,FALSE,TRUE,2.14 +1.1,2,32,TRUE,FALSE,3.88 +2.3,1,39,FALSE,FALSE,7.08 +3.5,1,33,FALSE,TRUE,6.29 +4,1,33,FALSE,FALSE,4.24 +4,1,33,FALSE,FALSE,4.24 +4,1,33,FALSE,FALSE,4.24 +10,2,42,TRUE,TRUE,4.8 +0.4,1,40,FALSE,TRUE,0.6 +1.6,1,50,TRUE,FALSE,2.93 +0.9,1,45,FALSE,FALSE,3.48 +0.6,1,42,FALSE,TRUE,1.38 +0.3,2,49,FALSE,TRUE,0.99 +0.3,2,49,FALSE,TRUE,0.99 +0.02,2,31,FALSE,TRUE,0.08 +1.1,0,28,FALSE,FALSE,3.39 +0.4,2,36,TRUE,TRUE,1.95 +0.4,2,36,TRUE,TRUE,1.95 +1.6,1,32,FALSE,TRUE,2.36 +1.6,1,32,FALSE,TRUE,2.36 +0.6,2,41,FALSE,TRUE,1.12 +0.6,2,41,FALSE,TRUE,1.12 +1.2,1,28,FALSE,FALSE,0.32 +10.8,0,35,TRUE,TRUE,5.98 +1.9,1,29,FALSE,TRUE,0.11 +0.9,1,37,FALSE,FALSE,0.5 +0.9,1,37,FALSE,FALSE,0.5 +3,2,32,FALSE,FALSE,4.77 +3,2,32,FALSE,FALSE,4.77 +6.8,1,24,TRUE,FALSE,3.08 +0.7,2,35,TRUE,FALSE,0.73 +1.5,1,35,FALSE,TRUE,3.5 +10.8,0,28,FALSE,TRUE,7.24 +1.1,2,42,FALSE,TRUE,4.41 +0.1,2,51,TRUE,TRUE,6.91 +0.1,2,51,TRUE,TRUE,6.91 +0.8,2,45,FALSE,FALSE,1.92 +3.1,1,40,FALSE,TRUE,4.61 +3.1,1,33,TRUE,TRUE,3.65 +2.4,2,42,TRUE,TRUE,1.37 +3.1,1,29,FALSE,TRUE,7.43 +4.1,2,40,TRUE,TRUE,3.52 +6.3,0,36,FALSE,FALSE,1.53 +3.2,1,30,TRUE,TRUE,2.49 +3.2,1,30,TRUE,TRUE,2.49 +3.2,1,30,TRUE,TRUE,2.49 +1.7,1,28,FALSE,FALSE,4.4 +1.7,1,28,FALSE,FALSE,4.4 +1.7,1,28,FALSE,FALSE,4.4 +1.7,1,66,FALSE,FALSE,2.16 +10.5,0,43,TRUE,TRUE,8.42 +3.3,1,22,FALSE,FALSE,6.19 +1.9,1,34,TRUE,TRUE,5.54 +6.8,1,24,FALSE,TRUE,4.94 +6.8,1,24,FALSE,TRUE,4.94 +1.3,1,22,FALSE,FALSE,4.56 +3.2,1,37,TRUE,FALSE,5.03 +4.4,1,42,TRUE,TRUE,1.93 +1.4,1,49,TRUE,FALSE,0.44 +10.3,1,48,FALSE,FALSE,3.46 +10.3,1,48,FALSE,FALSE,3.46 +10.3,1,48,FALSE,FALSE,3.46 +1,2,39,TRUE,TRUE,0.96 +0.9,1,31,FALSE,FALSE,0.96 +0.9,1,31,FALSE,FALSE,0.96 +4,1,35,TRUE,TRUE,4.03 +4,1,35,TRUE,TRUE,4.03 +1.3,1,46,TRUE,TRUE,3.46 +1.3,1,46,TRUE,TRUE,3.46 +1.3,1,46,TRUE,TRUE,3.46 +2.3,1,42,TRUE,TRUE,4.94 +9.2,1,28,TRUE,TRUE,8.82 +9.2,1,28,TRUE,TRUE,8.82 +9.2,1,28,TRUE,TRUE,8.82 +1,2,42,TRUE,FALSE,6.38 +1,2,42,TRUE,FALSE,6.38 +1.6,0,33,FALSE,FALSE,2.54 +1.6,0,33,FALSE,FALSE,2.54 +1.6,0,33,FALSE,FALSE,2.54 +0.5,2,35,FALSE,FALSE,2.2 +1,2,36,FALSE,TRUE,1.05 +0.02,2,46,TRUE,FALSE,4.65 +0.2,1,23,FALSE,FALSE,0.64 +0.6,2,33,FALSE,FALSE,0.53 +10.3,0,28,FALSE,TRUE,6.18 +7.4,0,37,TRUE,TRUE,8.93 +1.2,1,44,FALSE,TRUE,1.81 +5.7,1,27,FALSE,FALSE,9.95 +3.7,1,31,FALSE,TRUE,3.37 +1.4,1,34,FALSE,FALSE,3.03 +1.4,1,34,FALSE,FALSE,3.03 +1,1,54,TRUE,FALSE,4.92 +0.3,2,30,FALSE,TRUE,3.02 +0.3,2,30,FALSE,TRUE,3.02 +0.9,2,27,FALSE,FALSE,2.92 +0.9,2,27,FALSE,FALSE,2.92 +0.9,2,27,FALSE,FALSE,2.92 +3.5,2,39,TRUE,FALSE,0.59 +10.4,0,44,TRUE,TRUE,4.95 +0.6,2,43,TRUE,TRUE,1.3 +0.6,2,43,TRUE,TRUE,1.3 +4.2,2,35,FALSE,TRUE,5 +4.2,2,35,FALSE,TRUE,5 +4.2,2,35,FALSE,TRUE,5 +9.4,2,48,TRUE,TRUE,8.53 +1.8,1,32,TRUE,FALSE,5.52 +2.1,1,56,FALSE,TRUE,4.41 +1.8,1,46,TRUE,TRUE,2.26 +1.8,1,46,TRUE,TRUE,2.26 +3.7,1,34,FALSE,TRUE,5.19 +9.3,1,32,TRUE,TRUE,4.29 +10.3,0,33,FALSE,TRUE,7.99 +1.1,1,36,FALSE,TRUE,4.91 +0.8,1,31,FALSE,FALSE,1.48 +6.9,1,33,FALSE,FALSE,4.29 +6.9,1,33,FALSE,FALSE,4.29 +1.7,1,39,FALSE,TRUE,4.79 +1.7,1,39,FALSE,TRUE,4.79 +4.3,1,28,FALSE,TRUE,6.45 +4.3,1,28,FALSE,TRUE,6.45 +1.2,1,24,FALSE,FALSE,6.77 +1.2,1,24,FALSE,FALSE,6.77 +3.8,2,44,TRUE,TRUE,2.49 +3.8,2,44,TRUE,TRUE,2.49 +0.1,2,44,TRUE,FALSE,7.84 +0.1,2,33,FALSE,FALSE,0.11 +0.3,2,38,FALSE,TRUE,5.13 +6.6,1,29,FALSE,FALSE,4.4 +6.6,1,29,FALSE,FALSE,4.4 +1.4,1,36,TRUE,TRUE,3.03 +0.7,1,38,TRUE,TRUE,4.92 +0.1,2,44,TRUE,TRUE,0.3 +10.4,0,25,FALSE,TRUE,10.35 +1.1,2,51,TRUE,TRUE,2.13 +2.9,1,36,FALSE,FALSE,4.95 +0.9,1,45,TRUE,TRUE,13.53 +0.9,1,45,TRUE,TRUE,13.53 +0.02,2,29,TRUE,FALSE,3.29 +1.2,2,32,FALSE,TRUE,1.29 +1.6,1,45,FALSE,TRUE,1.75 +0.2,2,36,TRUE,TRUE,8.02 +2.2,1,22,FALSE,TRUE,6.38 +2.2,1,22,FALSE,TRUE,6.38 +2.6,1,25,FALSE,TRUE,2.23 +2.6,1,25,FALSE,TRUE,2.23 +5.6,1,35,TRUE,TRUE,2.97 +5.6,1,35,TRUE,TRUE,2.97 +3.3,1,42,TRUE,TRUE,0.73 +3.3,1,42,TRUE,TRUE,0.73 +3.3,1,42,TRUE,TRUE,0.73 +2,1,35,TRUE,FALSE,3.48 +0.7,2,38,TRUE,FALSE,1.65 +5.2,1,22,FALSE,FALSE,3.36 +5.2,1,22,FALSE,FALSE,3.36 +5.6,1,41,FALSE,TRUE,2.25 +7.8,0,37,TRUE,FALSE,12.22 +10.5,0,36,TRUE,TRUE,4.87 +1.7,1,44,TRUE,TRUE,3.39 +2.1,2,29,FALSE,FALSE,3.61 +2.1,2,29,FALSE,FALSE,3.61 +9.3,2,32,TRUE,FALSE,5.22 +9.3,2,32,TRUE,FALSE,5.22 +1.6,1,47,TRUE,FALSE,7.16 +5.1,1,27,TRUE,FALSE,3.7 +5.1,1,27,TRUE,FALSE,3.7 +1.3,0,32,FALSE,TRUE,6.1 +10.4,1,45,TRUE,TRUE,3.99 +0.6,2,43,TRUE,TRUE,7.07 +1,2,40,FALSE,TRUE,0.86 +0.7,2,32,FALSE,FALSE,5.65 +2.2,1,32,FALSE,FALSE,2.41 +2.2,1,32,FALSE,FALSE,2.41 +8.3,2,34,FALSE,TRUE,2.23 +8.3,2,34,FALSE,TRUE,2.23 +1.5,1,26,FALSE,TRUE,4.16 +1.5,1,26,FALSE,TRUE,4.16 +10.4,0,30,FALSE,TRUE,6.61 +0.4,2,47,FALSE,TRUE,1.53 +0.4,2,47,FALSE,TRUE,1.53 +10.3,0,40,TRUE,FALSE,12.09 +1,1,35,TRUE,FALSE,2.4 +1,1,35,TRUE,FALSE,2.4 +1,1,35,TRUE,FALSE,2.4 +2.4,1,61,FALSE,FALSE,3.5 +3.4,1,34,FALSE,TRUE,7.73 +0.4,2,38,TRUE,TRUE,2.43 +0.4,2,38,TRUE,TRUE,2.43 +0.4,2,38,TRUE,TRUE,2.43 +1.5,2,29,FALSE,TRUE,0.08 +1.5,2,29,FALSE,TRUE,0.08 +4.1,1,37,TRUE,FALSE,4.09 +2.3,1,46,TRUE,TRUE,3.48 +2.4,1,38,FALSE,TRUE,1.05 +2,1,25,FALSE,TRUE,3.24 +2.2,1,39,FALSE,TRUE,7.4 +2.2,1,39,FALSE,TRUE,7.4 +10,1,54,FALSE,FALSE,5.21 +1.2,1,45,FALSE,TRUE,1.86 +1.2,1,45,FALSE,TRUE,1.86 +2.7,2,37,TRUE,FALSE,3.22 +2.7,2,37,TRUE,FALSE,3.22 +6.5,1,23,FALSE,FALSE,2.32 +0.8,1,48,FALSE,TRUE,1.37 +0.8,1,48,FALSE,TRUE,1.37 +3.4,1,34,FALSE,TRUE,1.33 +1.6,1,20,FALSE,FALSE,4.96 +1.6,1,20,FALSE,FALSE,4.96 +1.6,1,20,FALSE,FALSE,4.96 +3.2,1,31,FALSE,TRUE,4.45 +0.5,1,56,FALSE,TRUE,0.16 +0.5,1,56,FALSE,TRUE,0.16 +1.5,2,37,FALSE,TRUE,4.6 +1.5,2,37,FALSE,TRUE,4.6 +2.1,1,31,FALSE,FALSE,8.41 +1.7,1,41,TRUE,TRUE,6.69 +0.8,1,49,TRUE,TRUE,3.13 +0.8,1,49,TRUE,TRUE,3.13 +4.2,1,37,TRUE,TRUE,4.32 +4.2,1,37,TRUE,TRUE,4.32 +1.4,1,47,TRUE,TRUE,7.28 +1.4,1,47,TRUE,TRUE,7.28 +1.4,1,33,FALSE,TRUE,1.92 +1.3,1,23,FALSE,FALSE,2.7 +0.6,2,42,TRUE,TRUE,0.96 +0.6,2,42,TRUE,TRUE,0.96 +0.6,2,42,TRUE,TRUE,0.96 +0.5,1,34,FALSE,FALSE,0.07 +0.5,1,34,FALSE,FALSE,0.07 +3.1,1,46,FALSE,FALSE,3.64 +3.1,1,46,FALSE,FALSE,3.64 +6,2,43,TRUE,FALSE,7.83 +6,2,43,TRUE,FALSE,7.83 +6,2,43,TRUE,FALSE,7.83 +2.7,1,46,TRUE,FALSE,2.33 +2.7,1,46,TRUE,FALSE,2.33 +2.7,1,46,TRUE,FALSE,2.33 +6.4,0,29,FALSE,TRUE,5.62 +3.5,2,34,TRUE,FALSE,4.62 +3.5,2,34,TRUE,FALSE,4.62 +3.5,2,34,TRUE,FALSE,4.62 +2,1,41,FALSE,FALSE,4.67 +1.6,1,36,TRUE,FALSE,3.39 +0.02,2,45,TRUE,FALSE,4.69 +0.02,2,45,TRUE,FALSE,4.69 +10.8,0,32,FALSE,FALSE,7.29 +10.4,0,30,FALSE,TRUE,7.56 +10.4,0,30,FALSE,TRUE,7.56 +0.02,2,31,TRUE,FALSE,5.39 +0.02,2,31,TRUE,FALSE,5.39 +1.8,1,34,FALSE,FALSE,2.77 +5.6,2,31,FALSE,TRUE,2.45 +5.6,2,31,FALSE,TRUE,2.45 +10.5,0,35,TRUE,TRUE,4.44 +3.2,1,30,FALSE,FALSE,6.56 +5.1,2,41,FALSE,FALSE,8.97 +1.9,2,37,FALSE,TRUE,0.22 +2.8,1,48,TRUE,TRUE,4.33 +2.8,1,48,TRUE,TRUE,4.33 +1.9,1,28,FALSE,TRUE,4.66 +1.9,1,28,FALSE,TRUE,4.66 +1.9,1,28,FALSE,TRUE,4.66 +1.9,1,28,FALSE,TRUE,4.66 +4.5,2,32,FALSE,FALSE,4.99 +4.5,2,32,FALSE,FALSE,4.99 +4.5,2,32,FALSE,FALSE,4.99 +3.1,2,27,TRUE,TRUE,1.61 +1.6,2,33,FALSE,TRUE,2.31 +1.6,2,33,FALSE,TRUE,2.31 +1.6,2,33,FALSE,TRUE,2.31 +0.9,1,39,FALSE,TRUE,2.84 +0.9,1,39,FALSE,TRUE,2.84 +0.9,1,39,FALSE,TRUE,2.84 +0.3,2,43,TRUE,TRUE,2.44 +1.9,1,25,FALSE,TRUE,2.63 +0.7,2,49,TRUE,FALSE,4.44 +0.7,2,49,TRUE,FALSE,4.44 +3.2,1,31,FALSE,FALSE,5.05 +3.2,1,34,FALSE,FALSE,5.6 +0.3,0,32,FALSE,FALSE,2.88 +1.9,1,41,FALSE,TRUE,2.63 +1.9,1,41,FALSE,TRUE,2.63 +2.9,1,36,FALSE,TRUE,4.65 +1.2,1,43,FALSE,FALSE,3.63 +1.2,1,43,FALSE,FALSE,3.63 +2.6,1,40,FALSE,FALSE,5.47 +2.6,1,40,FALSE,FALSE,5.47 +4.2,1,25,FALSE,FALSE,3.29 +4.2,1,25,FALSE,FALSE,3.29 +5.4,1,50,TRUE,TRUE,2.57 +1.2,2,30,FALSE,TRUE,4.98 +1.2,2,30,FALSE,TRUE,4.98 +1.7,1,47,TRUE,TRUE,2.56 +1.7,1,47,TRUE,TRUE,2.56 +1.7,1,47,TRUE,TRUE,2.56 +10.6,0,21,FALSE,FALSE,5.97 +10.6,0,21,FALSE,FALSE,5.97 +3.9,1,44,FALSE,TRUE,6.38 +3.9,1,44,FALSE,TRUE,6.38 +7.4,2,26,FALSE,FALSE,8.61 +3.8,1,21,FALSE,TRUE,2.83 +1.5,1,44,TRUE,FALSE,3.15 +1.5,1,44,TRUE,FALSE,3.15 +4.8,1,41,TRUE,FALSE,10.5 +0.4,1,27,FALSE,TRUE,2.56 +2.5,1,23,FALSE,FALSE,2.3 +0.8,1,44,FALSE,FALSE,0.91 +1.8,0,27,FALSE,FALSE,3.54 +0.4,2,35,FALSE,FALSE,0.98 +0.5,2,28,FALSE,FALSE,2.08 +0.7,2,29,FALSE,TRUE,1.15 +0.7,2,29,FALSE,TRUE,1.15 +0.7,2,29,FALSE,TRUE,1.15 +0.9,1,48,FALSE,FALSE,0.99 +2.4,1,42,TRUE,TRUE,4.26 +0.3,2,34,TRUE,TRUE,0.6 +1.3,1,26,FALSE,FALSE,4.96 +0.1,2,43,TRUE,FALSE,10.94 +0.1,2,43,TRUE,FALSE,10.94 +1.8,1,28,FALSE,FALSE,4.58 +1.9,1,40,TRUE,TRUE,0.1 +1.9,1,40,TRUE,TRUE,0.1 +0.4,1,34,FALSE,FALSE,0.77 +0.4,1,34,FALSE,FALSE,0.77 +1.4,1,56,FALSE,TRUE,0.28 +1.4,1,56,FALSE,TRUE,0.28 +8.8,0,28,FALSE,FALSE,5.9 +3.6,1,27,FALSE,TRUE,2.86 +3.6,1,27,FALSE,TRUE,2.86 +3.6,1,27,FALSE,TRUE,2.86 +1,2,31,TRUE,FALSE,2.05 +1,2,31,TRUE,FALSE,2.05 +1,1,36,FALSE,TRUE,4.25 +1,1,36,FALSE,TRUE,4.25 +1,1,36,FALSE,TRUE,4.25 +8.8,1,45,FALSE,FALSE,3.61 +2,1,40,FALSE,FALSE,3.07 +4,1,35,FALSE,TRUE,3.19 +1.2,1,53,FALSE,TRUE,1.25 +1.2,1,53,FALSE,TRUE,1.25 +1.9,2,28,FALSE,FALSE,1.24 +4.8,1,33,FALSE,TRUE,3.92 +0.5,2,44,TRUE,TRUE,2.18 +0.5,2,44,TRUE,TRUE,2.18 +1.4,0,34,TRUE,FALSE,2.3 +1.4,0,34,TRUE,FALSE,2.3 +8.4,1,28,FALSE,FALSE,4.65 +3.3,1,32,FALSE,TRUE,3.4 +1.7,2,35,TRUE,TRUE,12.67 +1.7,2,35,TRUE,TRUE,12.67 +1.7,2,35,TRUE,TRUE,12.67 +3.9,1,35,FALSE,FALSE,5.36 +2.4,2,36,FALSE,FALSE,3.49 +2.4,2,36,FALSE,FALSE,3.49 +1.6,1,50,TRUE,FALSE,4.23 +1.6,1,50,TRUE,FALSE,4.23 +2.3,1,26,TRUE,TRUE,6.53 +1.6,1,29,FALSE,FALSE,3.67 +1.6,1,43,FALSE,TRUE,2.23 +3.9,0,31,FALSE,FALSE,8.16 +3.9,0,31,FALSE,FALSE,8.16 +1.6,1,31,FALSE,TRUE,2.93 +2.3,1,19,FALSE,FALSE,5.29 +2.3,1,19,FALSE,FALSE,5.29 +2.9,1,26,FALSE,TRUE,3.28 +0.9,2,41,FALSE,TRUE,4.46 +10.7,0,32,FALSE,FALSE,9.46 +6.9,2,38,TRUE,TRUE,8.23 +8.8,1,32,FALSE,TRUE,3.99 +10.4,0,29,FALSE,TRUE,9.64 +2.7,1,27,FALSE,TRUE,6.2 +2.7,1,27,FALSE,TRUE,6.2 +10.3,0,46,TRUE,TRUE,9.31 +0.8,1,28,FALSE,FALSE,0.66 +0.8,1,28,FALSE,FALSE,0.66 +0.8,1,28,FALSE,FALSE,0.66 +4.7,0,19,FALSE,TRUE,7.25 +1.2,1,41,FALSE,FALSE,1.71 +1.2,1,41,FALSE,FALSE,1.71 +1,1,29,FALSE,FALSE,1.56 +1,2,29,TRUE,FALSE,2.33 +6.2,1,59,FALSE,FALSE,3.89 +3.7,1,26,FALSE,TRUE,5.71 +0.4,2,36,FALSE,TRUE,0.19 +1.7,1,27,FALSE,FALSE,2.51 +1.7,1,27,FALSE,FALSE,2.51 +4.4,2,28,FALSE,TRUE,1.82 +4.4,2,28,FALSE,TRUE,1.82 +4.4,2,28,FALSE,TRUE,1.82 +4.4,2,28,FALSE,TRUE,1.82 +3.1,1,31,FALSE,TRUE,3.97 +3.1,1,31,FALSE,TRUE,3.97 +2.4,1,43,FALSE,TRUE,3.56 +2.5,1,41,FALSE,TRUE,7.78 +1.2,1,57,FALSE,FALSE,0.17 +2.6,0,38,TRUE,FALSE,0.14 +0.5,0,37,FALSE,FALSE,2.85 +0.5,0,37,FALSE,FALSE,2.85 +4,0,43,TRUE,TRUE,9.07 +4,0,43,TRUE,TRUE,9.07 +9.7,1,40,TRUE,TRUE,4.74 +9.5,1,41,FALSE,FALSE,6.1 +9.5,1,41,FALSE,FALSE,6.1 +6,2,29,FALSE,TRUE,9.71 +6,2,29,FALSE,TRUE,9.71 +0.8,2,46,TRUE,FALSE,12.24 +0.8,2,46,TRUE,FALSE,12.24 +2.1,1,45,FALSE,TRUE,2.29 +2.1,1,45,FALSE,TRUE,2.29 +2.1,1,45,FALSE,TRUE,2.29 +2.1,1,45,FALSE,TRUE,2.29 +2.1,1,45,FALSE,TRUE,2.29 +1,1,46,TRUE,FALSE,3.24 +1,1,46,TRUE,FALSE,3.24 +1,1,46,TRUE,FALSE,3.24 +1,1,46,TRUE,FALSE,3.24 +4.8,2,41,TRUE,TRUE,0.63 +0.5,1,30,FALSE,FALSE,6.26 +3.7,1,36,FALSE,TRUE,2.93 +3.7,1,36,FALSE,TRUE,2.93 +3.7,1,36,FALSE,TRUE,2.93 +3.7,1,36,FALSE,TRUE,2.93 +3.7,1,36,FALSE,TRUE,2.93 +3.7,1,36,FALSE,TRUE,2.93 +2.2,1,26,FALSE,TRUE,5.42 +1.9,1,48,TRUE,TRUE,1.63 +0.5,2,34,TRUE,TRUE,7.83 +2.3,1,29,FALSE,TRUE,5.25 +2.3,1,29,FALSE,TRUE,5.25 +1.2,1,34,FALSE,TRUE,4.24 +3,1,21,FALSE,FALSE,2.99 +3,1,21,FALSE,FALSE,2.99 +1.2,2,37,TRUE,FALSE,3.23 +1.2,2,37,TRUE,FALSE,3.23 +1.5,2,48,TRUE,FALSE,6.53 +2.2,2,42,TRUE,TRUE,3.33 +2.2,2,42,TRUE,TRUE,3.33 +4.5,1,40,TRUE,TRUE,5.19 +4.5,1,40,TRUE,TRUE,5.19 +3.2,2,42,TRUE,FALSE,7.57 +5,1,38,TRUE,TRUE,9.94 +1.3,1,38,FALSE,FALSE,0.73 +4.6,1,49,TRUE,FALSE,1.09 +4.6,1,49,TRUE,FALSE,1.09 +1.3,2,44,TRUE,TRUE,6.44 +1.3,2,44,TRUE,TRUE,6.44 +0.7,2,21,FALSE,TRUE,0.99 +0.2,2,30,FALSE,TRUE,1.85 +0.9,2,37,FALSE,TRUE,0.13 +0.9,2,37,FALSE,TRUE,0.13 +1.9,1,27,FALSE,TRUE,3.06 +1.9,1,27,FALSE,TRUE,3.06 +4.1,1,17,FALSE,TRUE,5.79 +10.5,0,39,FALSE,FALSE,6.66 +10.5,0,39,FALSE,FALSE,6.66 +10.5,0,39,FALSE,FALSE,6.66 +10.5,0,39,FALSE,FALSE,6.66 +10.5,0,39,FALSE,FALSE,6.66 +2.6,1,46,FALSE,TRUE,1.88 +1.6,0,31,FALSE,FALSE,1.46 +5.9,1,43,FALSE,TRUE,3.76 +1.2,1,36,TRUE,TRUE,2.64 +4,1,41,FALSE,FALSE,2.49 +10.4,0,32,FALSE,FALSE,6.46 +1.3,1,50,FALSE,FALSE,1.86 +1.3,1,50,FALSE,FALSE,1.86 +10.3,0,33,FALSE,TRUE,6.3 +10.3,0,33,FALSE,TRUE,6.3 +0.5,1,73,FALSE,FALSE,1.12 +0.5,1,73,FALSE,FALSE,1.12 +1.1,1,41,TRUE,FALSE,3.45 +1.1,1,41,TRUE,FALSE,3.45 +2.9,1,21,FALSE,TRUE,4.9 +0.2,2,40,TRUE,TRUE,19.33 +2.6,2,47,TRUE,TRUE,1.69 +4.6,2,29,FALSE,TRUE,1.67 +2.1,1,35,FALSE,TRUE,3.05 +2.1,1,35,FALSE,TRUE,3.05 +2.1,1,35,FALSE,TRUE,3.05 +2.4,2,36,FALSE,TRUE,3.24 +8.8,1,41,TRUE,TRUE,5.29 +8.8,1,41,TRUE,TRUE,5.29 +8.8,1,41,TRUE,TRUE,5.29 +1.4,2,29,TRUE,FALSE,2.02 +1.4,2,29,TRUE,FALSE,2.02 +0.6,1,35,FALSE,FALSE,0.61 +3.1,1,35,FALSE,FALSE,2.41 +3.1,1,35,FALSE,FALSE,2.41 +3.1,1,35,FALSE,FALSE,2.41 +10.6,0,49,TRUE,FALSE,6.27 +3.5,2,43,TRUE,TRUE,1.94 +1.4,2,32,FALSE,FALSE,4.24 +0.6,2,38,FALSE,FALSE,2.22 +0.6,2,38,FALSE,FALSE,2.22 +1.6,1,32,FALSE,TRUE,2.37 +1,2,36,FALSE,TRUE,1.59 +0.5,2,22,FALSE,FALSE,1.94 +0.5,2,22,FALSE,FALSE,1.94 diff --git a/src/test/resources/wihs.csv b/src/test/resources/wihs.csv new file mode 100644 index 0000000..30a4d52 --- /dev/null +++ b/src/test/resources/wihs.csv @@ -0,0 +1,1165 @@ +"time","status","ageatfda","idu","black","cd4nadir" +0.02,2,48,FALSE,TRUE,6.95 +0.02,2,35,TRUE,TRUE,2.51 +0.02,2,28,FALSE,TRUE,0.18 +0.02,2,46,TRUE,FALSE,4.65 +0.02,2,31,FALSE,TRUE,0.08 +0.02,2,45,TRUE,TRUE,2.05 +0.02,2,30,FALSE,FALSE,5.29 +0.02,2,29,TRUE,FALSE,3.29 +0.02,2,45,TRUE,FALSE,4.69 +0.02,2,31,TRUE,FALSE,5.39 +0.02,1,35,FALSE,FALSE,2.79 +0.02,2,36,TRUE,TRUE,3.89 +0.1,2,67,TRUE,TRUE,1.47 +0.1,2,51,TRUE,TRUE,6.91 +0.1,2,47,FALSE,FALSE,0.14 +0.1,2,44,TRUE,TRUE,0.3 +0.1,2,31,FALSE,TRUE,0.35 +0.1,2,42,TRUE,TRUE,2.11 +0.1,2,33,FALSE,FALSE,0.11 +0.1,2,43,TRUE,TRUE,2.37 +0.1,2,32,FALSE,TRUE,4.63 +0.1,2,44,TRUE,FALSE,7.84 +0.1,2,40,FALSE,FALSE,2.01 +0.1,2,32,FALSE,FALSE,1.51 +0.1,2,43,TRUE,FALSE,10.94 +0.2,1,23,FALSE,FALSE,0.64 +0.2,2,40,TRUE,TRUE,0.06 +0.2,1,40,FALSE,FALSE,4.32 +0.2,2,36,TRUE,TRUE,8.02 +0.2,2,39,FALSE,TRUE,0.41 +0.2,2,40,TRUE,TRUE,19.33 +0.2,2,30,FALSE,TRUE,1.85 +0.2,2,44,TRUE,TRUE,1.16 +0.2,0,41,TRUE,TRUE,10.18 +0.2,2,35,TRUE,TRUE,0.84 +0.2,0,37,FALSE,TRUE,4.73 +0.2,2,34,TRUE,FALSE,4.49 +0.2,1,38,FALSE,FALSE,1.02 +0.2,0,22,FALSE,TRUE,9.72 +0.3,2,34,TRUE,TRUE,2 +0.3,2,40,TRUE,TRUE,1.94 +0.3,2,35,TRUE,FALSE,1.08 +0.3,1,43,FALSE,FALSE,1.1 +0.3,2,31,TRUE,TRUE,6.29 +0.3,2,44,TRUE,TRUE,2.97 +0.3,2,30,FALSE,TRUE,3.02 +0.3,2,38,TRUE,FALSE,0.38 +0.3,2,34,TRUE,FALSE,0.26 +0.3,2,38,FALSE,TRUE,5.13 +0.3,2,43,TRUE,TRUE,2.44 +0.3,2,34,TRUE,TRUE,0.6 +0.3,2,42,TRUE,FALSE,3.67 +0.3,0,31,FALSE,TRUE,8.27 +0.3,2,46,FALSE,TRUE,3.68 +0.3,2,24,FALSE,TRUE,5.2 +0.3,0,32,FALSE,FALSE,2.88 +0.3,2,32,TRUE,FALSE,0.09 +0.3,2,49,FALSE,TRUE,0.99 +0.3,1,39,FALSE,TRUE,3.82 +0.3,1,29,FALSE,FALSE,1.8 +0.3,1,35,TRUE,FALSE,3.07 +0.4,1,37,TRUE,TRUE,1.53 +0.4,1,41,FALSE,FALSE,3.1 +0.4,2,36,TRUE,TRUE,1.95 +0.4,2,38,TRUE,TRUE,0.15 +0.4,0,46,TRUE,TRUE,3.04 +0.4,2,36,FALSE,TRUE,4.44 +0.4,1,34,FALSE,FALSE,0.86 +0.4,1,41,FALSE,TRUE,1.22 +0.4,2,38,FALSE,FALSE,1.94 +0.4,2,39,FALSE,TRUE,0.62 +0.4,1,37,FALSE,FALSE,0.52 +0.4,2,36,FALSE,TRUE,0.19 +0.4,2,32,TRUE,FALSE,5 +0.4,2,35,FALSE,FALSE,0.98 +0.4,1,40,FALSE,TRUE,0.6 +0.4,2,38,TRUE,TRUE,2.43 +0.4,2,39,TRUE,TRUE,4.98 +0.4,1,40,FALSE,TRUE,2.09 +0.4,2,32,TRUE,FALSE,7.18 +0.4,2,47,FALSE,TRUE,1.53 +0.4,2,33,FALSE,TRUE,0.13 +0.4,1,43,FALSE,FALSE,4.19 +0.4,0,40,FALSE,TRUE,2.86 +0.4,1,27,FALSE,TRUE,2.56 +0.4,1,36,FALSE,FALSE,2.75 +0.4,2,36,TRUE,TRUE,1.79 +0.4,2,42,FALSE,FALSE,4.86 +0.4,1,34,FALSE,FALSE,0.77 +0.5,2,54,TRUE,TRUE,1.55 +0.5,2,51,TRUE,TRUE,2.8 +0.5,1,73,FALSE,FALSE,1.12 +0.5,2,44,TRUE,TRUE,2.18 +0.5,2,38,FALSE,FALSE,0.89 +0.5,2,37,FALSE,TRUE,0.68 +0.5,2,31,FALSE,TRUE,3.14 +0.5,2,35,FALSE,FALSE,2.2 +0.5,0,34,FALSE,TRUE,3.29 +0.5,1,40,TRUE,FALSE,1.53 +0.5,2,48,TRUE,TRUE,1.6 +0.5,0,37,FALSE,FALSE,2.85 +0.5,1,34,FALSE,FALSE,0.07 +0.5,2,40,TRUE,TRUE,6.04 +0.5,2,30,FALSE,FALSE,2.54 +0.5,2,34,TRUE,TRUE,7.83 +0.5,1,45,TRUE,FALSE,1.74 +0.5,1,34,FALSE,TRUE,4.36 +0.5,1,30,FALSE,FALSE,6.26 +0.5,2,28,FALSE,FALSE,2.08 +0.5,2,54,TRUE,TRUE,0.57 +0.5,1,56,FALSE,TRUE,0.16 +0.5,1,32,FALSE,FALSE,3.88 +0.5,2,22,FALSE,FALSE,1.94 +0.6,2,33,FALSE,FALSE,0.53 +0.6,1,32,FALSE,TRUE,4.1 +0.6,1,38,TRUE,TRUE,3.38 +0.6,0,30,TRUE,FALSE,3.49 +0.6,2,27,FALSE,TRUE,1.47 +0.6,1,34,TRUE,FALSE,3.38 +0.6,1,42,FALSE,TRUE,1.38 +0.6,1,38,TRUE,FALSE,0.75 +0.6,0,36,FALSE,TRUE,3.47 +0.6,1,35,FALSE,FALSE,0.61 +0.6,2,43,TRUE,TRUE,1.3 +0.6,2,46,FALSE,FALSE,0 +0.6,2,41,FALSE,TRUE,1.12 +0.6,1,37,TRUE,FALSE,2.85 +0.6,1,32,TRUE,FALSE,5.79 +0.6,1,20,FALSE,FALSE,0.41 +0.6,2,39,TRUE,TRUE,2.86 +0.6,2,43,TRUE,TRUE,7.07 +0.6,2,43,TRUE,TRUE,4.87 +0.6,2,42,TRUE,TRUE,0.96 +0.6,2,38,TRUE,TRUE,3.84 +0.6,1,37,FALSE,FALSE,3.98 +0.6,2,51,FALSE,FALSE,1.89 +0.6,2,57,FALSE,FALSE,0.54 +0.6,2,37,TRUE,TRUE,0.28 +0.6,1,42,TRUE,TRUE,2.12 +0.6,2,39,FALSE,FALSE,2.33 +0.6,0,37,FALSE,TRUE,4.85 +0.6,2,38,FALSE,FALSE,2.22 +0.6,2,29,TRUE,TRUE,5.44 +0.6,1,35,TRUE,FALSE,3.33 +0.6,2,44,FALSE,FALSE,0.87 +0.7,1,40,FALSE,FALSE,0.97 +0.7,0,29,TRUE,TRUE,6.26 +0.7,2,36,FALSE,FALSE,4.11 +0.7,1,33,FALSE,FALSE,5.98 +0.7,2,32,FALSE,FALSE,5.65 +0.7,2,32,FALSE,TRUE,0.5 +0.7,2,45,TRUE,TRUE,2.17 +0.7,1,28,FALSE,FALSE,2.8 +0.7,2,38,TRUE,FALSE,1.65 +0.7,1,37,TRUE,FALSE,3.91 +0.7,2,35,TRUE,FALSE,0.73 +0.7,2,49,TRUE,FALSE,4.44 +0.7,2,40,TRUE,FALSE,7.05 +0.7,1,26,FALSE,FALSE,0.07 +0.7,2,29,FALSE,TRUE,0.15 +0.7,1,38,TRUE,TRUE,4.92 +0.7,1,37,FALSE,FALSE,6.52 +0.7,1,45,FALSE,TRUE,0.77 +0.7,2,34,FALSE,TRUE,0.05 +0.7,2,29,FALSE,TRUE,1.15 +0.7,2,30,FALSE,TRUE,4.53 +0.7,2,38,TRUE,FALSE,1.7 +0.7,2,44,FALSE,TRUE,0.12 +0.7,2,33,TRUE,TRUE,2.46 +0.7,2,21,FALSE,TRUE,0.99 +0.7,2,37,TRUE,TRUE,1.11 +0.7,0,40,FALSE,TRUE,3.34 +0.7,1,42,TRUE,TRUE,0.11 +0.8,1,49,TRUE,TRUE,3.13 +0.8,1,28,FALSE,TRUE,0.26 +0.8,1,36,FALSE,FALSE,1.8 +0.8,1,34,FALSE,FALSE,8.83 +0.8,2,37,TRUE,TRUE,9.96 +0.8,1,31,FALSE,TRUE,1.66 +0.8,2,38,FALSE,TRUE,0 +0.8,1,29,TRUE,FALSE,4.63 +0.8,1,28,FALSE,FALSE,0.66 +0.8,1,31,FALSE,FALSE,0.08 +0.8,1,35,FALSE,FALSE,4.84 +0.8,2,35,TRUE,FALSE,2.09 +0.8,1,27,FALSE,FALSE,0.8 +0.8,1,34,FALSE,FALSE,2.87 +0.8,2,45,FALSE,FALSE,1.92 +0.8,1,44,FALSE,FALSE,0.91 +0.8,1,42,FALSE,FALSE,3.26 +0.8,2,39,FALSE,FALSE,1.16 +0.8,2,49,FALSE,FALSE,2.65 +0.8,1,32,FALSE,FALSE,2.26 +0.8,1,40,TRUE,TRUE,0.25 +0.8,1,32,FALSE,FALSE,3.25 +0.8,1,35,TRUE,FALSE,1.66 +0.8,2,32,TRUE,FALSE,2.08 +0.8,2,35,FALSE,TRUE,0.46 +0.8,2,46,TRUE,FALSE,12.24 +0.8,0,31,FALSE,FALSE,6.39 +0.8,1,48,FALSE,TRUE,1.37 +0.8,1,43,FALSE,TRUE,1.67 +0.8,1,38,FALSE,TRUE,3.5 +0.8,1,50,TRUE,TRUE,3.24 +0.8,2,38,FALSE,FALSE,10.95 +0.8,2,46,FALSE,FALSE,1.98 +0.8,1,31,FALSE,FALSE,1.48 +0.8,2,35,FALSE,FALSE,1.18 +0.8,1,38,FALSE,FALSE,3.38 +0.8,2,45,TRUE,TRUE,9.82 +0.9,1,37,FALSE,FALSE,0.52 +0.9,2,38,FALSE,TRUE,3.36 +0.9,1,44,TRUE,TRUE,4.62 +0.9,2,30,TRUE,TRUE,0.63 +0.9,2,33,FALSE,TRUE,4.41 +0.9,2,35,FALSE,TRUE,0 +0.9,1,24,FALSE,TRUE,1.3 +0.9,2,24,FALSE,FALSE,8.11 +0.9,2,30,TRUE,FALSE,6.2 +0.9,1,48,FALSE,FALSE,0.99 +0.9,2,42,TRUE,TRUE,1.94 +0.9,2,39,TRUE,TRUE,0.06 +0.9,1,56,TRUE,TRUE,3.16 +0.9,0,36,TRUE,TRUE,1.32 +0.9,1,37,TRUE,TRUE,3.41 +0.9,1,35,FALSE,FALSE,4.85 +0.9,1,39,FALSE,TRUE,2.84 +0.9,2,38,FALSE,TRUE,3.67 +0.9,1,45,FALSE,FALSE,3.48 +0.9,2,41,FALSE,TRUE,4.46 +0.9,1,45,TRUE,TRUE,13.53 +0.9,1,33,FALSE,FALSE,2.16 +0.9,2,35,TRUE,TRUE,0 +0.9,0,39,TRUE,TRUE,6.78 +0.9,1,33,TRUE,FALSE,1.07 +0.9,1,31,FALSE,FALSE,0.96 +0.9,2,27,FALSE,FALSE,2.92 +0.9,1,43,FALSE,TRUE,3.98 +0.9,2,37,FALSE,TRUE,0.13 +0.9,1,40,FALSE,TRUE,1.83 +0.9,2,34,FALSE,FALSE,2.1 +0.9,2,34,FALSE,TRUE,1.26 +0.9,1,29,FALSE,FALSE,2.16 +0.9,1,37,FALSE,FALSE,0.5 +0.9,1,33,TRUE,FALSE,1.48 +0.9,2,31,TRUE,FALSE,2.34 +0.9,1,40,FALSE,FALSE,4.54 +0.9,1,26,FALSE,TRUE,3.16 +0.9,1,41,TRUE,FALSE,6.49 +0.9,1,38,TRUE,FALSE,1.78 +1,1,24,FALSE,TRUE,2.23 +1,2,35,FALSE,TRUE,4.88 +1,2,42,TRUE,FALSE,6.38 +1,2,40,TRUE,TRUE,1.05 +1,1,31,FALSE,FALSE,0.93 +1,1,42,TRUE,TRUE,2.19 +1,1,28,FALSE,TRUE,2.34 +1,1,32,FALSE,FALSE,0 +1,1,33,TRUE,TRUE,0.88 +1,2,30,TRUE,FALSE,1.39 +1,1,36,FALSE,FALSE,0.12 +1,2,31,TRUE,FALSE,2.05 +1,1,45,TRUE,TRUE,1.04 +1,1,38,TRUE,TRUE,0.2 +1,1,29,FALSE,FALSE,1.56 +1,2,42,TRUE,TRUE,2.87 +1,1,30,FALSE,FALSE,3 +1,2,44,TRUE,TRUE,5.95 +1,1,38,FALSE,FALSE,1.88 +1,1,33,FALSE,FALSE,2.24 +1,2,21,FALSE,TRUE,2.75 +1,1,35,TRUE,FALSE,2.4 +1,2,40,FALSE,TRUE,0.86 +1,1,36,FALSE,TRUE,4.25 +1,1,34,FALSE,FALSE,3.68 +1,2,54,FALSE,TRUE,6.42 +1,2,36,FALSE,TRUE,1.05 +1,2,46,TRUE,FALSE,1.29 +1,2,47,TRUE,TRUE,0.21 +1,1,43,FALSE,TRUE,1.63 +1,1,54,TRUE,FALSE,4.92 +1,1,42,TRUE,FALSE,2.86 +1,2,29,TRUE,FALSE,2.33 +1,1,46,TRUE,FALSE,3.24 +1,1,36,FALSE,FALSE,1.98 +1,2,36,FALSE,TRUE,1.59 +1,2,39,TRUE,TRUE,0.96 +1.1,2,26,FALSE,TRUE,0.04 +1.1,1,41,TRUE,TRUE,1.15 +1.1,1,36,TRUE,FALSE,1.92 +1.1,2,32,FALSE,TRUE,2.11 +1.1,1,31,FALSE,FALSE,5.05 +1.1,2,51,TRUE,TRUE,2.13 +1.1,2,36,FALSE,TRUE,5.18 +1.1,1,43,FALSE,FALSE,2.03 +1.1,1,48,FALSE,TRUE,4.74 +1.1,2,32,TRUE,FALSE,0.21 +1.1,1,41,TRUE,TRUE,1.12 +1.1,1,21,FALSE,FALSE,3.79 +1.1,1,40,TRUE,TRUE,1.89 +1.1,1,41,TRUE,FALSE,3.45 +1.1,2,27,FALSE,FALSE,2.78 +1.1,1,32,FALSE,TRUE,3.08 +1.1,1,30,TRUE,FALSE,3.43 +1.1,1,36,FALSE,FALSE,1.21 +1.1,1,39,FALSE,TRUE,3.59 +1.1,1,46,FALSE,TRUE,1.42 +1.1,2,45,TRUE,TRUE,4.13 +1.1,2,32,TRUE,FALSE,3.88 +1.1,1,45,TRUE,TRUE,2.17 +1.1,1,39,FALSE,FALSE,4.02 +1.1,1,37,FALSE,FALSE,2 +1.1,1,39,TRUE,TRUE,0.25 +1.1,2,34,TRUE,TRUE,3.27 +1.1,1,39,FALSE,FALSE,1.87 +1.1,1,33,FALSE,FALSE,3.39 +1.1,0,28,FALSE,FALSE,3.39 +1.1,1,36,FALSE,TRUE,5.39 +1.1,1,36,FALSE,TRUE,4.91 +1.1,1,49,TRUE,TRUE,1.73 +1.1,1,26,FALSE,TRUE,3.33 +1.1,2,42,FALSE,TRUE,4.41 +1.1,1,33,TRUE,FALSE,2.83 +1.1,2,37,FALSE,FALSE,5.51 +1.2,1,49,TRUE,FALSE,1.13 +1.2,1,30,FALSE,FALSE,3.17 +1.2,1,32,FALSE,FALSE,3.87 +1.2,1,29,FALSE,FALSE,2.83 +1.2,1,29,FALSE,FALSE,0.61 +1.2,0,28,FALSE,TRUE,5.05 +1.2,1,24,FALSE,FALSE,6.77 +1.2,1,43,FALSE,FALSE,12.06 +1.2,1,33,TRUE,TRUE,3.6 +1.2,1,38,TRUE,TRUE,5.95 +1.2,1,57,FALSE,FALSE,0.17 +1.2,1,36,FALSE,FALSE,4.12 +1.2,1,52,TRUE,TRUE,5.86 +1.2,1,29,FALSE,FALSE,2.54 +1.2,2,41,TRUE,FALSE,2.81 +1.2,1,36,TRUE,TRUE,2.64 +1.2,1,36,FALSE,TRUE,1.56 +1.2,1,28,FALSE,FALSE,4.58 +1.2,2,37,TRUE,TRUE,4.35 +1.2,1,34,FALSE,TRUE,4.24 +1.2,1,40,FALSE,TRUE,2.34 +1.2,1,38,TRUE,FALSE,4.14 +1.2,2,42,FALSE,FALSE,8.52 +1.2,1,28,FALSE,FALSE,0.32 +1.2,2,34,TRUE,TRUE,3.58 +1.2,1,48,TRUE,TRUE,2.81 +1.2,2,32,FALSE,TRUE,1.29 +1.2,1,39,FALSE,TRUE,1.4 +1.2,1,60,FALSE,TRUE,2.26 +1.2,2,32,TRUE,FALSE,3.92 +1.2,1,39,FALSE,FALSE,3.95 +1.2,1,38,FALSE,TRUE,3 +1.2,1,52,FALSE,TRUE,2.13 +1.2,2,30,FALSE,TRUE,4.98 +1.2,1,52,FALSE,TRUE,4.21 +1.2,1,58,FALSE,FALSE,0.44 +1.2,1,37,TRUE,TRUE,2.45 +1.2,1,33,TRUE,FALSE,3.38 +1.2,1,44,FALSE,TRUE,1.81 +1.2,1,45,FALSE,TRUE,1.86 +1.2,1,53,FALSE,TRUE,1.25 +1.2,2,37,TRUE,FALSE,3.23 +1.2,1,26,FALSE,FALSE,5.63 +1.2,1,21,FALSE,FALSE,4.29 +1.2,1,39,TRUE,TRUE,4.97 +1.2,2,35,TRUE,TRUE,5.26 +1.2,1,36,FALSE,FALSE,2.98 +1.2,1,56,FALSE,TRUE,2.36 +1.2,1,41,FALSE,FALSE,1.71 +1.2,1,43,FALSE,FALSE,3.63 +1.2,2,44,FALSE,FALSE,0.45 +1.2,1,32,FALSE,FALSE,1.8 +1.2,1,38,FALSE,FALSE,2.14 +1.2,1,28,FALSE,TRUE,0.36 +1.3,0,32,FALSE,TRUE,6.1 +1.3,2,46,TRUE,TRUE,0.35 +1.3,1,41,TRUE,TRUE,1.35 +1.3,1,20,FALSE,FALSE,4.14 +1.3,2,40,TRUE,TRUE,7.66 +1.3,1,41,TRUE,TRUE,2.02 +1.3,1,22,FALSE,FALSE,4.56 +1.3,1,26,FALSE,FALSE,4.96 +1.3,1,38,FALSE,FALSE,4.75 +1.3,1,56,FALSE,FALSE,2.86 +1.3,2,44,TRUE,TRUE,6.44 +1.3,1,38,FALSE,FALSE,0.73 +1.3,1,37,FALSE,TRUE,4.52 +1.3,1,33,FALSE,FALSE,0.3 +1.3,1,33,FALSE,FALSE,2.9 +1.3,1,56,TRUE,TRUE,2.23 +1.3,2,34,TRUE,FALSE,5.18 +1.3,1,42,TRUE,FALSE,8.01 +1.3,1,23,FALSE,FALSE,2.7 +1.3,2,37,FALSE,TRUE,0.04 +1.3,1,42,FALSE,FALSE,2.7 +1.3,1,39,FALSE,TRUE,2.05 +1.3,2,50,TRUE,TRUE,2.18 +1.3,2,39,TRUE,TRUE,2.33 +1.3,1,31,FALSE,FALSE,1.83 +1.3,1,22,FALSE,FALSE,6.5 +1.3,1,50,FALSE,FALSE,1.86 +1.3,1,42,FALSE,FALSE,7.71 +1.3,1,36,FALSE,FALSE,1.47 +1.3,1,69,FALSE,TRUE,1.6 +1.3,1,35,FALSE,FALSE,0.81 +1.3,1,29,FALSE,TRUE,4.85 +1.3,2,40,TRUE,TRUE,3.07 +1.3,1,41,FALSE,FALSE,2.6 +1.3,1,46,TRUE,TRUE,3.46 +1.3,2,42,TRUE,TRUE,1.84 +1.3,1,46,TRUE,TRUE,3.24 +1.3,2,34,TRUE,TRUE,2.88 +1.4,2,27,FALSE,TRUE,2.58 +1.4,2,23,TRUE,FALSE,10.96 +1.4,1,42,TRUE,TRUE,1.03 +1.4,2,39,FALSE,FALSE,4.21 +1.4,1,27,FALSE,TRUE,4.49 +1.4,1,47,TRUE,TRUE,7.28 +1.4,1,41,TRUE,TRUE,2.28 +1.4,1,25,FALSE,FALSE,0.93 +1.4,1,41,TRUE,TRUE,1.79 +1.4,1,46,FALSE,TRUE,3.74 +1.4,1,35,FALSE,FALSE,3.82 +1.4,1,56,FALSE,TRUE,0.28 +1.4,1,27,TRUE,FALSE,3.69 +1.4,1,27,FALSE,FALSE,1.33 +1.4,1,32,FALSE,FALSE,4.36 +1.4,1,32,FALSE,FALSE,1.88 +1.4,1,40,FALSE,FALSE,2.49 +1.4,0,34,TRUE,FALSE,2.3 +1.4,1,27,FALSE,TRUE,3.12 +1.4,1,26,FALSE,TRUE,3.82 +1.4,1,35,FALSE,FALSE,2.71 +1.4,2,49,FALSE,FALSE,2.56 +1.4,1,36,TRUE,TRUE,3.03 +1.4,1,24,FALSE,TRUE,0.68 +1.4,1,28,FALSE,FALSE,7.36 +1.4,1,35,FALSE,FALSE,0.6 +1.4,1,33,FALSE,TRUE,1.92 +1.4,1,28,FALSE,FALSE,5.37 +1.4,1,29,FALSE,FALSE,2.08 +1.4,2,36,TRUE,FALSE,3.95 +1.4,1,49,TRUE,FALSE,0.44 +1.4,1,52,FALSE,TRUE,3.92 +1.4,1,38,FALSE,TRUE,1.84 +1.4,2,41,TRUE,TRUE,0.82 +1.4,1,35,FALSE,FALSE,2.88 +1.4,1,21,FALSE,FALSE,3.95 +1.4,1,34,FALSE,FALSE,0.72 +1.4,1,34,FALSE,FALSE,3.03 +1.4,2,29,TRUE,FALSE,2.02 +1.4,2,32,FALSE,FALSE,4.24 +1.5,1,44,TRUE,FALSE,3.15 +1.5,2,29,FALSE,TRUE,0.08 +1.5,1,33,FALSE,TRUE,3.96 +1.5,1,26,FALSE,TRUE,2.14 +1.5,1,28,FALSE,TRUE,1.55 +1.5,1,35,TRUE,FALSE,3.96 +1.5,2,41,TRUE,TRUE,0 +1.5,2,29,FALSE,TRUE,2.61 +1.5,1,36,FALSE,TRUE,1.6 +1.5,2,40,FALSE,TRUE,3.91 +1.5,2,44,TRUE,TRUE,4.35 +1.5,1,42,TRUE,FALSE,5.15 +1.5,1,35,FALSE,TRUE,3.5 +1.5,1,39,TRUE,TRUE,2.94 +1.5,1,37,TRUE,TRUE,3.19 +1.5,2,44,TRUE,FALSE,1.47 +1.5,1,57,FALSE,TRUE,3.32 +1.5,2,42,FALSE,TRUE,0.84 +1.5,2,48,TRUE,FALSE,6.53 +1.5,2,28,FALSE,FALSE,4.74 +1.5,1,41,TRUE,TRUE,3.94 +1.5,1,24,FALSE,TRUE,0.99 +1.5,1,48,FALSE,TRUE,2.23 +1.5,0,30,FALSE,FALSE,3.36 +1.5,2,44,TRUE,TRUE,1.76 +1.5,1,35,FALSE,FALSE,3.29 +1.5,2,37,FALSE,TRUE,4.6 +1.5,1,41,TRUE,FALSE,4.51 +1.5,1,25,FALSE,TRUE,2.25 +1.5,1,33,FALSE,FALSE,1.34 +1.5,1,26,FALSE,TRUE,4.16 +1.5,1,53,FALSE,FALSE,3.92 +1.5,1,30,FALSE,FALSE,0.35 +1.5,1,34,TRUE,TRUE,7.67 +1.5,1,34,FALSE,FALSE,1.98 +1.5,2,54,TRUE,TRUE,1.96 +1.5,1,37,TRUE,FALSE,3.2 +1.6,1,43,FALSE,TRUE,2.23 +1.6,2,29,FALSE,TRUE,0.05 +1.6,1,33,FALSE,TRUE,4.46 +1.6,2,33,FALSE,TRUE,2.31 +1.6,1,36,TRUE,FALSE,3.39 +1.6,1,40,FALSE,FALSE,5.35 +1.6,1,50,TRUE,FALSE,4.23 +1.6,1,53,TRUE,TRUE,3.96 +1.6,1,39,TRUE,FALSE,2.46 +1.6,2,45,TRUE,TRUE,4.23 +1.6,0,32,FALSE,TRUE,2.57 +1.6,1,50,TRUE,FALSE,2.93 +1.6,1,32,FALSE,TRUE,2.37 +1.6,1,45,FALSE,TRUE,1.75 +1.6,1,47,TRUE,FALSE,7.16 +1.6,1,43,TRUE,TRUE,1.7 +1.6,0,33,FALSE,FALSE,2.54 +1.6,1,32,FALSE,FALSE,9.96 +1.6,1,33,FALSE,TRUE,2.2 +1.6,1,31,FALSE,FALSE,2.5 +1.6,1,20,FALSE,FALSE,4.96 +1.6,1,54,FALSE,TRUE,2.41 +1.6,0,31,FALSE,FALSE,1.46 +1.6,1,39,FALSE,FALSE,0.6 +1.6,1,38,FALSE,FALSE,7.96 +1.6,2,38,FALSE,FALSE,3.15 +1.6,2,39,FALSE,TRUE,1.46 +1.6,1,29,FALSE,FALSE,3.67 +1.6,1,31,FALSE,TRUE,2.93 +1.6,1,32,FALSE,TRUE,2.36 +1.6,0,46,TRUE,TRUE,4.28 +1.6,1,27,FALSE,FALSE,2.75 +1.6,2,25,FALSE,TRUE,0.63 +1.6,1,54,FALSE,TRUE,4.43 +1.6,1,37,FALSE,FALSE,5.85 +1.6,1,21,FALSE,FALSE,5.62 +1.7,1,47,TRUE,TRUE,2.56 +1.7,1,33,FALSE,TRUE,1.57 +1.7,1,54,FALSE,TRUE,2.81 +1.7,0,37,FALSE,TRUE,3.7 +1.7,1,41,TRUE,TRUE,6.69 +1.7,0,40,FALSE,FALSE,6.53 +1.7,1,28,FALSE,FALSE,4.4 +1.7,1,35,FALSE,TRUE,4.87 +1.7,1,32,FALSE,FALSE,1.89 +1.7,1,26,FALSE,FALSE,4.77 +1.7,2,42,FALSE,TRUE,0.22 +1.7,1,34,FALSE,TRUE,1 +1.7,0,40,FALSE,FALSE,4.11 +1.7,1,31,FALSE,FALSE,2.87 +1.7,2,39,FALSE,TRUE,2.05 +1.7,1,44,TRUE,TRUE,3.39 +1.7,2,57,TRUE,TRUE,10.07 +1.7,1,41,FALSE,TRUE,2.98 +1.7,1,39,FALSE,TRUE,4.79 +1.7,1,27,FALSE,FALSE,2.51 +1.7,2,38,FALSE,FALSE,0.48 +1.7,1,66,FALSE,FALSE,2.16 +1.7,2,35,TRUE,TRUE,12.67 +1.7,1,24,FALSE,TRUE,4.49 +1.8,1,24,FALSE,TRUE,3.36 +1.8,1,26,FALSE,FALSE,3.48 +1.8,1,18,FALSE,TRUE,5.72 +1.8,1,43,TRUE,FALSE,4.09 +1.8,1,40,TRUE,TRUE,0.84 +1.8,1,38,FALSE,TRUE,6.21 +1.8,1,44,TRUE,FALSE,6.54 +1.8,1,24,FALSE,TRUE,4.55 +1.8,1,26,FALSE,FALSE,6.36 +1.8,1,32,TRUE,FALSE,5.52 +1.8,1,38,FALSE,FALSE,5.43 +1.8,2,42,TRUE,FALSE,1.66 +1.8,1,45,FALSE,FALSE,5.26 +1.8,1,46,TRUE,TRUE,2.26 +1.8,2,31,FALSE,TRUE,1.9 +1.8,0,27,FALSE,FALSE,3.54 +1.8,1,28,FALSE,FALSE,4.58 +1.8,1,30,FALSE,FALSE,3.82 +1.8,2,32,TRUE,FALSE,0.34 +1.8,1,34,FALSE,FALSE,2.77 +1.8,1,32,FALSE,TRUE,2.89 +1.8,1,42,TRUE,TRUE,1.15 +1.9,1,37,TRUE,FALSE,3.99 +1.9,1,48,TRUE,TRUE,1.63 +1.9,2,34,TRUE,FALSE,10.95 +1.9,1,29,FALSE,TRUE,0.11 +1.9,1,27,FALSE,TRUE,4.13 +1.9,1,39,FALSE,TRUE,3.6 +1.9,2,34,FALSE,TRUE,2.57 +1.9,2,25,FALSE,TRUE,4.24 +1.9,1,30,TRUE,TRUE,1.79 +1.9,2,37,FALSE,TRUE,4.25 +1.9,2,28,FALSE,FALSE,4.31 +1.9,1,28,FALSE,TRUE,4.66 +1.9,2,37,FALSE,TRUE,0.22 +1.9,1,36,TRUE,FALSE,1.68 +1.9,2,44,TRUE,TRUE,1.69 +1.9,1,40,TRUE,TRUE,0.1 +1.9,1,25,FALSE,TRUE,2.63 +1.9,1,41,FALSE,TRUE,2.63 +1.9,2,28,FALSE,FALSE,1.24 +1.9,1,27,FALSE,TRUE,3.06 +1.9,1,34,TRUE,TRUE,5.54 +1.9,1,31,FALSE,TRUE,2.98 +2,1,47,TRUE,TRUE,5.28 +2,1,38,FALSE,FALSE,3.3 +2,1,30,TRUE,FALSE,3.65 +2,1,50,FALSE,FALSE,4.08 +2,1,36,FALSE,TRUE,5.44 +2,1,37,FALSE,TRUE,4.56 +2,1,34,TRUE,FALSE,1.49 +2,1,62,FALSE,FALSE,7.45 +2,1,22,FALSE,FALSE,2.84 +2,1,39,TRUE,TRUE,1.29 +2,1,34,FALSE,TRUE,3.3 +2,1,25,FALSE,TRUE,3.24 +2,1,35,TRUE,FALSE,3.48 +2,2,32,FALSE,FALSE,3.18 +2,1,38,FALSE,TRUE,3.06 +2,1,34,TRUE,TRUE,3.48 +2,0,32,FALSE,TRUE,6.24 +2,1,30,FALSE,TRUE,3.22 +2,1,40,FALSE,FALSE,3.07 +2,1,41,FALSE,FALSE,4.67 +2,1,58,FALSE,TRUE,2.9 +2,2,26,FALSE,TRUE,3.48 +2.1,2,29,FALSE,FALSE,3.61 +2.1,1,33,FALSE,TRUE,5.46 +2.1,1,35,FALSE,TRUE,3.05 +2.1,1,37,TRUE,FALSE,2.47 +2.1,1,30,TRUE,TRUE,5.33 +2.1,1,45,FALSE,TRUE,2.29 +2.1,1,30,FALSE,TRUE,1.17 +2.1,1,38,TRUE,FALSE,2.04 +2.1,2,33,FALSE,TRUE,11.79 +2.1,1,47,FALSE,FALSE,3.32 +2.1,1,31,FALSE,FALSE,8.41 +2.1,0,48,FALSE,FALSE,5.28 +2.1,1,30,FALSE,TRUE,5.17 +2.1,2,30,FALSE,TRUE,4.94 +2.1,1,56,FALSE,TRUE,4.41 +2.1,1,32,FALSE,TRUE,4.95 +2.2,1,34,FALSE,FALSE,3.46 +2.2,1,26,FALSE,TRUE,5.42 +2.2,0,39,FALSE,TRUE,3.73 +2.2,1,22,FALSE,TRUE,6.38 +2.2,1,23,FALSE,FALSE,3.84 +2.2,2,38,TRUE,TRUE,3.44 +2.2,2,27,FALSE,TRUE,6.87 +2.2,1,32,FALSE,FALSE,2.41 +2.2,1,33,FALSE,TRUE,4.16 +2.2,2,28,FALSE,TRUE,3.62 +2.2,1,34,FALSE,FALSE,3.63 +2.2,1,39,FALSE,TRUE,7.4 +2.2,2,39,TRUE,FALSE,1.59 +2.2,1,37,FALSE,FALSE,2.84 +2.2,2,39,FALSE,TRUE,3.44 +2.2,1,40,FALSE,FALSE,5.28 +2.2,1,30,FALSE,TRUE,2.81 +2.2,1,31,FALSE,FALSE,2.14 +2.2,1,42,TRUE,TRUE,6.33 +2.2,1,29,FALSE,TRUE,2.81 +2.2,1,33,FALSE,TRUE,1.85 +2.2,1,29,FALSE,FALSE,2.85 +2.2,1,42,TRUE,TRUE,1.78 +2.2,1,31,FALSE,FALSE,2.36 +2.2,1,37,FALSE,FALSE,3.1 +2.2,2,45,TRUE,TRUE,8.4 +2.2,1,40,FALSE,TRUE,8.2 +2.2,1,42,FALSE,TRUE,3.23 +2.2,2,42,TRUE,TRUE,3.33 +2.2,2,44,TRUE,TRUE,3.76 +2.3,0,25,FALSE,FALSE,3.37 +2.3,1,39,FALSE,FALSE,2.93 +2.3,1,37,TRUE,FALSE,6 +2.3,1,42,TRUE,TRUE,4.94 +2.3,1,26,TRUE,TRUE,6.53 +2.3,1,19,FALSE,FALSE,5.29 +2.3,0,38,FALSE,TRUE,9.14 +2.3,1,44,TRUE,FALSE,4.53 +2.3,1,46,TRUE,TRUE,3.48 +2.3,1,39,FALSE,FALSE,7.08 +2.3,1,40,TRUE,TRUE,2.68 +2.3,1,40,TRUE,TRUE,2.91 +2.3,1,32,FALSE,TRUE,3.32 +2.3,1,29,FALSE,TRUE,6.42 +2.3,1,48,TRUE,FALSE,2.13 +2.3,1,56,FALSE,TRUE,3.42 +2.3,1,29,FALSE,TRUE,5.25 +2.3,2,28,FALSE,TRUE,5.48 +2.4,1,28,FALSE,TRUE,3.47 +2.4,2,42,TRUE,TRUE,1.37 +2.4,1,23,FALSE,TRUE,3.36 +2.4,1,28,FALSE,TRUE,2.28 +2.4,1,43,FALSE,TRUE,3.56 +2.4,2,28,FALSE,TRUE,13.72 +2.4,1,19,FALSE,TRUE,2.26 +2.4,1,40,FALSE,FALSE,3.65 +2.4,1,42,TRUE,TRUE,4.26 +2.4,2,36,FALSE,TRUE,3.24 +2.4,1,32,TRUE,FALSE,4.2 +2.4,1,38,TRUE,TRUE,5.39 +2.4,1,21,FALSE,FALSE,5.99 +2.4,1,61,FALSE,FALSE,3.5 +2.4,1,28,FALSE,TRUE,6.89 +2.4,2,36,FALSE,FALSE,3.49 +2.4,1,38,FALSE,TRUE,1.05 +2.4,1,33,TRUE,FALSE,2.69 +2.4,1,18,FALSE,TRUE,4.52 +2.5,1,42,FALSE,TRUE,1.67 +2.5,1,43,TRUE,TRUE,4.54 +2.5,1,39,FALSE,FALSE,2.59 +2.5,2,43,TRUE,TRUE,6.73 +2.5,1,43,TRUE,TRUE,9.48 +2.5,2,34,TRUE,TRUE,2.44 +2.5,2,44,TRUE,TRUE,2.1 +2.5,1,33,FALSE,TRUE,6.64 +2.5,1,41,FALSE,TRUE,7.78 +2.5,1,39,FALSE,FALSE,4.08 +2.5,1,23,FALSE,FALSE,2.3 +2.5,1,29,FALSE,TRUE,4.89 +2.6,1,32,FALSE,FALSE,2.48 +2.6,1,31,FALSE,TRUE,2.2 +2.6,1,61,FALSE,FALSE,3.75 +2.6,1,40,FALSE,FALSE,5.47 +2.6,0,38,TRUE,FALSE,0.14 +2.6,1,46,FALSE,TRUE,1.88 +2.6,2,47,TRUE,TRUE,1.69 +2.6,1,31,FALSE,TRUE,7.99 +2.6,2,51,FALSE,TRUE,6.69 +2.6,1,34,FALSE,FALSE,3.4 +2.6,1,47,TRUE,TRUE,4.07 +2.6,2,37,TRUE,TRUE,1.94 +2.6,1,25,FALSE,TRUE,2.23 +2.7,1,40,TRUE,TRUE,4.58 +2.7,1,31,FALSE,FALSE,5.36 +2.7,1,46,TRUE,FALSE,2.33 +2.7,1,41,TRUE,TRUE,3.99 +2.7,2,48,TRUE,TRUE,2.45 +2.7,1,31,FALSE,FALSE,5.28 +2.7,2,37,TRUE,FALSE,3.22 +2.7,2,24,FALSE,FALSE,0.39 +2.7,1,32,TRUE,TRUE,2.44 +2.7,2,47,TRUE,TRUE,2.02 +2.7,1,39,TRUE,FALSE,4.32 +2.7,1,38,TRUE,TRUE,5.22 +2.7,1,27,FALSE,TRUE,6.2 +2.7,1,31,FALSE,FALSE,2.27 +2.8,1,44,TRUE,FALSE,13.17 +2.8,1,29,FALSE,TRUE,4.68 +2.8,1,28,FALSE,FALSE,2.06 +2.8,2,39,TRUE,FALSE,4.13 +2.8,1,31,TRUE,FALSE,4.56 +2.8,1,37,TRUE,TRUE,7.54 +2.8,2,41,FALSE,FALSE,1.83 +2.8,1,48,TRUE,TRUE,4.33 +2.8,1,36,FALSE,TRUE,4.91 +2.9,1,26,FALSE,TRUE,3.28 +2.9,1,34,TRUE,TRUE,3.04 +2.9,1,34,FALSE,FALSE,6.95 +2.9,1,57,FALSE,FALSE,6.69 +2.9,1,36,FALSE,TRUE,4.65 +2.9,1,21,FALSE,TRUE,4.9 +2.9,1,36,FALSE,FALSE,4.95 +2.9,1,39,TRUE,FALSE,3.12 +2.9,1,35,FALSE,TRUE,4.69 +2.9,1,47,FALSE,FALSE,3.15 +2.9,1,51,TRUE,FALSE,4.76 +2.9,2,40,FALSE,TRUE,1.01 +2.9,1,26,FALSE,TRUE,3.24 +3,2,32,FALSE,FALSE,4.77 +3,0,38,FALSE,FALSE,2 +3,1,35,TRUE,FALSE,6.13 +3,1,38,TRUE,FALSE,4.75 +3,2,38,TRUE,TRUE,5.27 +3,2,42,TRUE,TRUE,3.79 +3,2,47,TRUE,FALSE,6.03 +3,1,21,FALSE,TRUE,4.77 +3,1,57,TRUE,TRUE,3.91 +3,1,47,TRUE,TRUE,4.27 +3,1,21,FALSE,FALSE,2.99 +3.1,1,29,FALSE,TRUE,7.43 +3.1,1,35,FALSE,FALSE,2.41 +3.1,2,48,FALSE,TRUE,9.35 +3.1,1,29,FALSE,FALSE,5.42 +3.1,1,37,FALSE,TRUE,3.98 +3.1,2,28,FALSE,TRUE,0.14 +3.1,1,40,FALSE,TRUE,4.61 +3.1,1,40,FALSE,TRUE,1.07 +3.1,2,29,FALSE,TRUE,2.47 +3.1,2,27,TRUE,TRUE,1.61 +3.1,1,36,FALSE,TRUE,7.56 +3.1,1,35,FALSE,TRUE,1.98 +3.1,1,31,FALSE,TRUE,3.97 +3.1,1,46,FALSE,FALSE,3.64 +3.1,1,27,FALSE,TRUE,2.54 +3.1,1,33,TRUE,TRUE,3.65 +3.2,1,43,TRUE,TRUE,1.32 +3.2,1,35,FALSE,FALSE,4.26 +3.2,1,53,FALSE,FALSE,4.78 +3.2,2,48,TRUE,TRUE,4.99 +3.2,2,47,TRUE,FALSE,1.53 +3.2,1,37,TRUE,FALSE,5.03 +3.2,1,30,TRUE,TRUE,2.49 +3.2,1,34,FALSE,FALSE,5.6 +3.2,1,31,FALSE,TRUE,5.73 +3.2,1,31,FALSE,TRUE,4.45 +3.2,2,42,TRUE,FALSE,7.57 +3.2,1,32,FALSE,TRUE,5.2 +3.2,1,30,FALSE,FALSE,6.56 +3.2,1,39,FALSE,TRUE,4.22 +3.2,1,24,FALSE,TRUE,3.77 +3.2,1,31,FALSE,FALSE,5.05 +3.3,2,44,TRUE,FALSE,4.99 +3.3,1,37,FALSE,TRUE,7.64 +3.3,1,32,FALSE,TRUE,3.4 +3.3,1,42,TRUE,TRUE,0.73 +3.3,1,37,FALSE,TRUE,6.15 +3.3,1,28,FALSE,TRUE,7.45 +3.3,1,39,FALSE,TRUE,1.49 +3.3,2,40,TRUE,FALSE,2.24 +3.3,1,22,FALSE,FALSE,6.19 +3.3,1,30,FALSE,TRUE,5.62 +3.3,2,29,FALSE,FALSE,3.25 +3.3,1,46,FALSE,TRUE,3.64 +3.3,1,26,FALSE,FALSE,2.42 +3.4,1,34,TRUE,TRUE,4.39 +3.4,1,34,FALSE,TRUE,7.73 +3.4,2,44,TRUE,FALSE,3.4 +3.4,2,39,TRUE,FALSE,9.83 +3.4,1,28,TRUE,TRUE,1.72 +3.4,1,34,TRUE,FALSE,6.95 +3.4,1,34,FALSE,TRUE,1.33 +3.5,0,34,FALSE,TRUE,2.86 +3.5,1,40,TRUE,TRUE,2.51 +3.5,2,43,TRUE,TRUE,1.94 +3.5,1,33,FALSE,TRUE,6.29 +3.5,2,34,TRUE,FALSE,4.62 +3.5,2,39,TRUE,FALSE,0.59 +3.5,1,35,FALSE,TRUE,2.22 +3.5,0,61,FALSE,FALSE,7.98 +3.5,1,42,TRUE,FALSE,4.78 +3.5,1,48,FALSE,TRUE,5.35 +3.5,1,36,TRUE,FALSE,3.14 +3.6,1,33,FALSE,TRUE,5.04 +3.6,1,25,FALSE,FALSE,3.34 +3.6,2,40,TRUE,TRUE,2.57 +3.6,1,27,FALSE,TRUE,2.86 +3.6,2,28,FALSE,FALSE,3.03 +3.6,2,54,FALSE,TRUE,4.6 +3.6,1,31,FALSE,TRUE,3.55 +3.6,1,48,TRUE,TRUE,1.44 +3.6,1,30,FALSE,TRUE,0.63 +3.6,1,58,FALSE,TRUE,3.91 +3.6,1,31,FALSE,FALSE,6.79 +3.6,2,35,TRUE,FALSE,1.69 +3.6,2,39,TRUE,FALSE,1.18 +3.6,1,36,FALSE,TRUE,5.6 +3.6,2,32,TRUE,FALSE,4.48 +3.7,1,31,FALSE,TRUE,3.37 +3.7,1,43,TRUE,TRUE,2.95 +3.7,1,46,TRUE,FALSE,1.33 +3.7,1,28,TRUE,TRUE,3.58 +3.7,1,31,TRUE,TRUE,10.45 +3.7,2,40,FALSE,FALSE,7.38 +3.7,1,33,FALSE,FALSE,3.64 +3.7,1,36,FALSE,TRUE,2.93 +3.7,2,43,FALSE,TRUE,18.12 +3.7,2,23,FALSE,TRUE,5.3 +3.7,1,26,FALSE,TRUE,5.71 +3.7,1,34,FALSE,TRUE,5.19 +3.8,1,27,FALSE,TRUE,2.53 +3.8,2,44,TRUE,TRUE,2.49 +3.8,1,42,FALSE,TRUE,1.79 +3.8,2,35,FALSE,TRUE,5.94 +3.8,1,21,FALSE,TRUE,2.83 +3.9,1,35,FALSE,FALSE,5.36 +3.9,0,31,FALSE,FALSE,8.16 +3.9,1,44,FALSE,TRUE,6.38 +3.9,1,39,TRUE,TRUE,4.05 +3.9,1,32,FALSE,TRUE,3.35 +4,2,34,TRUE,FALSE,7.99 +4,0,43,TRUE,TRUE,9.07 +4,1,30,TRUE,FALSE,6.81 +4,1,35,TRUE,TRUE,4.03 +4,1,37,TRUE,TRUE,2.87 +4,1,35,FALSE,TRUE,3.19 +4,1,33,FALSE,FALSE,4.24 +4,1,35,TRUE,FALSE,4.84 +4,2,47,TRUE,TRUE,1.39 +4,1,41,FALSE,FALSE,2.49 +4,2,34,FALSE,TRUE,3.97 +4.1,1,37,TRUE,FALSE,4.09 +4.1,2,40,TRUE,TRUE,3.52 +4.1,1,31,TRUE,FALSE,4.17 +4.1,2,27,FALSE,FALSE,11.91 +4.1,1,17,FALSE,TRUE,5.79 +4.1,1,31,FALSE,TRUE,3.5 +4.1,1,35,FALSE,TRUE,3.92 +4.2,2,41,FALSE,TRUE,1.72 +4.2,1,37,TRUE,TRUE,7.85 +4.2,2,67,TRUE,TRUE,3.24 +4.2,1,47,TRUE,TRUE,5.88 +4.2,1,40,FALSE,TRUE,3.62 +4.2,1,34,TRUE,TRUE,4.97 +4.2,1,29,FALSE,TRUE,2.89 +4.2,1,24,FALSE,TRUE,4.91 +4.2,1,31,FALSE,TRUE,8.15 +4.2,1,25,FALSE,FALSE,3.29 +4.2,1,37,TRUE,TRUE,4.32 +4.2,2,35,FALSE,TRUE,5 +4.3,1,66,FALSE,TRUE,3.4 +4.3,1,23,TRUE,TRUE,3.87 +4.3,2,44,FALSE,FALSE,4.44 +4.3,2,40,TRUE,TRUE,1.91 +4.3,2,38,TRUE,FALSE,8.97 +4.3,1,28,FALSE,TRUE,6.45 +4.4,1,30,FALSE,TRUE,5.16 +4.4,2,33,FALSE,TRUE,4.47 +4.4,2,41,TRUE,TRUE,3.91 +4.4,2,29,FALSE,TRUE,4.89 +4.4,2,35,TRUE,TRUE,6.76 +4.4,1,38,FALSE,TRUE,2.83 +4.4,1,40,TRUE,TRUE,5.34 +4.4,2,32,TRUE,FALSE,2.26 +4.4,1,35,FALSE,FALSE,4.01 +4.4,2,28,FALSE,TRUE,1.82 +4.4,1,35,FALSE,FALSE,4.31 +4.4,1,20,FALSE,FALSE,4.54 +4.4,1,42,TRUE,TRUE,1.93 +4.5,2,38,TRUE,TRUE,3.16 +4.5,1,40,TRUE,TRUE,5.19 +4.5,2,32,FALSE,FALSE,4.99 +4.5,1,24,FALSE,TRUE,5.88 +4.5,2,41,TRUE,FALSE,4.09 +4.6,2,29,FALSE,TRUE,1.67 +4.6,2,38,TRUE,TRUE,5.03 +4.6,1,49,TRUE,FALSE,1.09 +4.6,1,40,TRUE,TRUE,5.49 +4.6,1,33,TRUE,FALSE,8.78 +4.7,1,32,FALSE,TRUE,6.04 +4.7,1,47,TRUE,TRUE,5.14 +4.7,1,43,TRUE,TRUE,5.46 +4.7,0,19,FALSE,TRUE,7.25 +4.7,1,17,FALSE,FALSE,14.24 +4.7,1,37,TRUE,TRUE,2.9 +4.7,2,37,FALSE,TRUE,1.76 +4.7,1,37,TRUE,TRUE,8.68 +4.8,1,28,FALSE,TRUE,7.85 +4.8,0,27,FALSE,FALSE,12.25 +4.8,1,33,FALSE,TRUE,3.92 +4.8,1,41,TRUE,FALSE,10.5 +4.8,2,33,FALSE,TRUE,10.08 +4.8,1,60,TRUE,FALSE,4.29 +4.8,2,41,TRUE,TRUE,0.63 +4.8,2,35,FALSE,TRUE,5.6 +4.8,1,39,FALSE,TRUE,8.96 +4.9,1,41,TRUE,TRUE,4.62 +4.9,2,30,TRUE,FALSE,5.39 +4.9,0,29,FALSE,TRUE,3.71 +5,1,38,TRUE,TRUE,9.94 +5,1,31,TRUE,FALSE,2.42 +5,1,41,TRUE,TRUE,3.8 +5.1,2,41,FALSE,FALSE,8.97 +5.1,1,27,TRUE,FALSE,3.7 +5.1,1,26,FALSE,FALSE,5.84 +5.1,1,37,FALSE,TRUE,2.87 +5.2,1,30,FALSE,TRUE,2.8 +5.2,2,38,TRUE,TRUE,3.82 +5.2,1,30,FALSE,FALSE,2.3 +5.2,1,22,FALSE,FALSE,3.36 +5.2,1,37,FALSE,TRUE,0.54 +5.2,0,35,TRUE,TRUE,4.97 +5.3,1,46,TRUE,FALSE,6.19 +5.3,2,35,FALSE,TRUE,3.75 +5.3,2,27,FALSE,TRUE,2.94 +5.3,1,23,FALSE,FALSE,6.42 +5.3,2,45,TRUE,TRUE,2.35 +5.3,2,45,FALSE,TRUE,1.72 +5.4,1,28,FALSE,TRUE,2.92 +5.4,1,30,FALSE,TRUE,4.61 +5.4,1,34,FALSE,FALSE,3.51 +5.4,0,28,FALSE,FALSE,6.13 +5.4,1,50,TRUE,TRUE,2.57 +5.4,2,38,TRUE,TRUE,5.67 +5.5,0,29,FALSE,TRUE,12.32 +5.5,2,54,FALSE,TRUE,5.17 +5.5,2,39,FALSE,FALSE,2.38 +5.6,1,41,FALSE,TRUE,2.25 +5.6,2,31,FALSE,TRUE,2.45 +5.6,2,36,TRUE,TRUE,8.41 +5.6,1,35,TRUE,TRUE,2.97 +5.6,1,41,TRUE,TRUE,5.26 +5.6,1,48,FALSE,TRUE,6.92 +5.6,2,45,TRUE,TRUE,9.92 +5.7,2,41,TRUE,TRUE,3.39 +5.7,1,27,FALSE,FALSE,9.95 +5.8,1,49,TRUE,TRUE,4.23 +5.9,1,43,FALSE,TRUE,3.76 +5.9,2,21,FALSE,FALSE,8 +5.9,1,21,FALSE,FALSE,6.82 +5.9,2,50,TRUE,TRUE,2.98 +6,2,29,FALSE,TRUE,3.79 +6,1,30,TRUE,FALSE,3.87 +6,0,24,FALSE,TRUE,13.9 +6,2,31,FALSE,FALSE,7.73 +6,2,29,FALSE,TRUE,9.71 +6,2,43,TRUE,FALSE,7.83 +6.1,1,24,FALSE,TRUE,3.62 +6.1,0,45,TRUE,TRUE,12.06 +6.1,1,33,TRUE,TRUE,4.52 +6.2,2,42,TRUE,FALSE,8.36 +6.2,1,59,FALSE,FALSE,3.89 +6.3,2,42,TRUE,TRUE,1.81 +6.3,0,36,FALSE,FALSE,1.53 +6.3,1,45,FALSE,FALSE,6.44 +6.4,1,33,FALSE,FALSE,6.53 +6.4,2,50,TRUE,TRUE,3.17 +6.4,0,29,FALSE,TRUE,5.62 +6.5,1,23,FALSE,FALSE,2.32 +6.5,2,22,FALSE,FALSE,10.42 +6.5,2,34,FALSE,TRUE,6.41 +6.6,0,36,FALSE,TRUE,4.23 +6.6,1,29,FALSE,FALSE,4.4 +6.7,1,31,FALSE,TRUE,4 +6.7,1,33,FALSE,TRUE,4.06 +6.8,1,33,FALSE,FALSE,7.87 +6.8,1,24,FALSE,TRUE,4.94 +6.8,0,33,FALSE,FALSE,5.79 +6.8,0,27,FALSE,TRUE,6.38 +6.8,1,24,TRUE,FALSE,3.08 +6.8,1,37,TRUE,TRUE,4.51 +6.9,2,38,TRUE,TRUE,8.23 +6.9,1,33,FALSE,FALSE,4.29 +7,2,45,TRUE,TRUE,2.52 +7.1,2,37,TRUE,TRUE,7.32 +7.2,1,37,FALSE,TRUE,3.53 +7.2,0,27,FALSE,FALSE,4.04 +7.3,2,28,FALSE,TRUE,0.99 +7.3,1,29,FALSE,TRUE,10.67 +7.3,1,30,FALSE,TRUE,3.84 +7.3,2,37,TRUE,FALSE,0.23 +7.4,2,42,TRUE,TRUE,6.73 +7.4,2,45,TRUE,FALSE,5.58 +7.4,0,37,TRUE,TRUE,8.93 +7.4,2,26,FALSE,FALSE,8.61 +7.5,1,34,FALSE,TRUE,6.85 +7.5,1,39,FALSE,FALSE,3.28 +7.7,1,44,FALSE,TRUE,6.15 +7.7,1,39,TRUE,TRUE,4.5 +7.8,1,30,FALSE,TRUE,4.59 +7.8,1,37,TRUE,FALSE,3.64 +7.8,0,40,TRUE,FALSE,3.08 +7.8,1,46,FALSE,TRUE,3.86 +7.8,0,37,TRUE,FALSE,12.22 +7.9,2,46,TRUE,FALSE,3.86 +8,1,30,FALSE,TRUE,5.67 +8.2,2,31,FALSE,TRUE,3.33 +8.2,1,19,FALSE,TRUE,4.08 +8.2,1,38,TRUE,FALSE,3.67 +8.2,1,47,TRUE,TRUE,3.02 +8.2,0,36,FALSE,FALSE,6.11 +8.3,2,34,FALSE,TRUE,2.23 +8.4,1,27,FALSE,TRUE,4.43 +8.4,1,28,FALSE,FALSE,4.65 +8.4,1,28,TRUE,FALSE,9.63 +8.5,1,29,FALSE,FALSE,3.52 +8.7,0,30,FALSE,FALSE,4.73 +8.7,1,45,FALSE,TRUE,2.55 +8.7,1,31,TRUE,FALSE,4.84 +8.8,1,26,FALSE,FALSE,4.75 +8.8,1,32,FALSE,TRUE,3.99 +8.8,1,41,TRUE,TRUE,5.29 +8.8,2,47,FALSE,TRUE,2.74 +8.8,1,27,FALSE,TRUE,2.7 +8.8,1,45,FALSE,FALSE,3.61 +8.8,0,28,FALSE,FALSE,5.9 +9,1,26,FALSE,FALSE,3.45 +9,1,44,FALSE,TRUE,8.21 +9.1,1,44,TRUE,TRUE,3.79 +9.1,1,34,FALSE,FALSE,5.95 +9.1,1,49,TRUE,TRUE,7.13 +9.2,1,28,TRUE,TRUE,8.82 +9.2,1,26,FALSE,TRUE,3.27 +9.3,0,30,FALSE,TRUE,9.27 +9.3,1,38,FALSE,FALSE,8.6 +9.3,0,37,FALSE,TRUE,6.65 +9.3,1,26,FALSE,FALSE,2.52 +9.3,1,32,TRUE,TRUE,4.29 +9.3,1,31,FALSE,TRUE,9.7 +9.3,2,32,TRUE,FALSE,5.22 +9.4,2,48,TRUE,TRUE,8.53 +9.4,0,30,FALSE,TRUE,4.04 +9.5,1,41,FALSE,FALSE,6.1 +9.6,2,42,TRUE,TRUE,3.34 +9.7,1,40,TRUE,TRUE,4.74 +9.7,1,31,FALSE,TRUE,3.42 +9.8,1,25,FALSE,TRUE,3.42 +10,2,42,TRUE,TRUE,4.8 +10,1,54,FALSE,FALSE,5.21 +10.2,1,30,FALSE,TRUE,6.23 +10.2,0,32,FALSE,TRUE,2.9 +10.3,0,33,FALSE,TRUE,6.3 +10.3,0,33,FALSE,TRUE,7.99 +10.3,0,34,FALSE,TRUE,7.68 +10.3,0,29,FALSE,TRUE,8.18 +10.3,1,48,FALSE,FALSE,3.46 +10.3,0,40,TRUE,FALSE,12.09 +10.3,0,25,FALSE,FALSE,4.97 +10.3,0,28,FALSE,TRUE,6.18 +10.3,0,46,TRUE,TRUE,9.31 +10.3,0,42,FALSE,TRUE,6.15 +10.3,2,51,FALSE,TRUE,10.68 +10.3,0,29,FALSE,TRUE,4.38 +10.3,0,42,TRUE,TRUE,8.17 +10.3,0,33,TRUE,TRUE,4.62 +10.4,0,44,TRUE,TRUE,4.95 +10.4,0,38,TRUE,FALSE,3.69 +10.4,0,32,FALSE,FALSE,6.46 +10.4,0,27,TRUE,TRUE,5.51 +10.4,0,36,TRUE,FALSE,4.47 +10.4,0,44,TRUE,TRUE,11.63 +10.4,0,30,FALSE,TRUE,7.56 +10.4,0,29,FALSE,TRUE,9.64 +10.4,0,25,FALSE,TRUE,10.35 +10.4,0,38,TRUE,TRUE,5.5 +10.4,1,45,TRUE,TRUE,3.99 +10.4,1,26,FALSE,FALSE,5.66 +10.4,0,38,FALSE,TRUE,4.77 +10.4,0,36,TRUE,FALSE,6.19 +10.4,0,32,FALSE,TRUE,7.99 +10.4,0,34,TRUE,TRUE,3.87 +10.4,0,33,FALSE,TRUE,2.88 +10.4,0,30,FALSE,TRUE,6.61 +10.5,0,29,FALSE,TRUE,4.72 +10.5,0,43,TRUE,TRUE,8.42 +10.5,0,28,FALSE,TRUE,7.07 +10.5,0,37,TRUE,FALSE,2.32 +10.5,0,36,TRUE,TRUE,4.87 +10.5,0,39,FALSE,FALSE,6.66 +10.5,1,40,TRUE,TRUE,5.48 +10.5,0,28,FALSE,TRUE,8.28 +10.5,0,49,FALSE,TRUE,5.33 +10.5,0,35,TRUE,TRUE,4.44 +10.5,0,37,FALSE,FALSE,7.02 +10.5,0,33,FALSE,FALSE,6.83 +10.5,0,53,TRUE,TRUE,4.19 +10.5,0,31,FALSE,TRUE,18.23 +10.5,0,44,TRUE,TRUE,3.16 +10.6,0,21,FALSE,FALSE,5.97 +10.6,0,42,TRUE,TRUE,3.73 +10.6,1,23,FALSE,FALSE,4.89 +10.6,0,33,FALSE,TRUE,3.97 +10.6,0,32,TRUE,TRUE,9.81 +10.6,0,49,TRUE,FALSE,6.27 +10.7,0,40,FALSE,TRUE,10.73 +10.7,0,29,FALSE,FALSE,5.23 +10.7,0,32,FALSE,FALSE,9.46 +10.7,0,39,FALSE,TRUE,3.21 +10.7,0,33,FALSE,TRUE,3.56 +10.7,0,28,FALSE,TRUE,5.62 +10.7,1,21,FALSE,TRUE,2.6 +10.8,0,20,FALSE,TRUE,12.31 +10.8,0,29,TRUE,FALSE,8.83 +10.8,0,28,FALSE,TRUE,7.24 +10.8,0,35,TRUE,TRUE,5.98 +10.8,0,40,TRUE,FALSE,3.85 +10.8,0,32,FALSE,FALSE,7.29 +10.8,0,30,FALSE,FALSE,4.94 +10.8,0,20,FALSE,TRUE,11.05 +10.8,2,42,TRUE,TRUE,12.36