package dr.evomodel.antigenic.phyloClustering.misc.obsolete; import dr.evolution.util.*; import dr.inference.model.*; import dr.math.MathUtils; import dr.math.LogTricks; import dr.math.distributions.NormalDistribution; import dr.util.*; import dr.xml.*; import java.io.*; import java.util.*; import java.util.logging.Logger; /** * @author Charles Cheung * @author Andrew Rambaut * @author Trevor Bedford * @author Marc Suchard * @version $Id$ */ /* Both virus locations and serum locations are shifted by the parameter locationDrift. A location is increased by locationDrift x offset. Offset is set to 0 for the earliest virus and increasing with difference in date from earliest virus. This makes the raw virusLocations and serumLocations parameters not directly interpretable. */ public class AGLikelihoodTreeCluster extends AbstractModelLikelihood implements Citable { private static final boolean CHECK_INFINITE = false; private static final boolean USE_THRESHOLDS = true; private static final boolean USE_INTERVALS = true; public final static String AG_LIKELIHOOD = "aglikelihoodtreecluster"; // column indices in table private static final int VIRUS_ISOLATE = 0; private static final int VIRUS_STRAIN = 1; private static final int VIRUS_DATE = 2; private static final int SERUM_ISOLATE = 3; private static final int SERUM_STRAIN = 4; private static final int SERUM_DATE = 5; private static final int TITRE = 6; private double oldLogLikelihood =0; public enum MeasurementType { INTERVAL, POINT, THRESHOLD, MISSING } public AGLikelihoodTreeCluster( int mdsDimension, Parameter mdsPrecisionParameter, Parameter locationDriftParameter, Parameter virusDriftParameter, Parameter serumDriftParameter, MatrixParameter virusLocationsParameter, MatrixParameter serumLocationsParameter, CompoundParameter tipTraitsParameter, Parameter virusOffsetsParameter, Parameter serumOffsetsParameter, Parameter serumPotenciesParameter, Parameter serumBreadthsParameter, Parameter virusAviditiesParameter, DataTable<String[]> dataTable, boolean mergeSerumIsolates, double intervalWidth, double driftInitialLocations, boolean clusterMeans, Parameter clusterOffsetsParameter) { super(AG_LIKELIHOOD); this.intervalWidth = intervalWidth; boolean useIntervals = USE_INTERVALS && intervalWidth > 0.0; int thresholdCount = 0; double earliestDate = Double.POSITIVE_INFINITY; for (int i = 0; i < dataTable.getRowCount(); i++) { String[] values = dataTable.getRow(i); String virusName = values[VIRUS_STRAIN]; double virusDate = Double.parseDouble(values[VIRUS_DATE]); int virus = virusNames.indexOf(virusName); if (virus == -1) { virusNames.add(virusName); virusDates.add(virusDate); virus = virusNames.size() - 1; } String serumName = ""; if (mergeSerumIsolates) { serumName = values[SERUM_STRAIN]; } else { serumName = values[SERUM_ISOLATE]; } double serumDate = Double.parseDouble(values[SERUM_DATE]); int serum = serumNames.indexOf(serumName); if (serum == -1) { serumNames.add(serumName); serumDates.add(serumDate); serum = serumNames.size() - 1; } boolean isThreshold = false; boolean isLowerThreshold = false; double rawTitre = Double.NaN; if (values[TITRE].length() > 0) { try { rawTitre = Double.parseDouble(values[TITRE]); } catch (NumberFormatException nfe) { // check if threshold below if (values[TITRE].contains("<")) { rawTitre = Double.parseDouble(values[TITRE].replace("<","")); isThreshold = true; isLowerThreshold = true; thresholdCount++; } // check if threshold above if (values[TITRE].contains(">")) { rawTitre = Double.parseDouble(values[TITRE].replace(">","")); isThreshold = true; isLowerThreshold = false; thresholdCount++; //throw new IllegalArgumentException("Error in measurement: unsupported greater than threshold at row " + (i+1)); } } } if (serumDate < earliestDate) { earliestDate = serumDate; } if (virusDate < earliestDate) { earliestDate = virusDate; } MeasurementType type = (isThreshold ? MeasurementType.THRESHOLD : (useIntervals ? MeasurementType.INTERVAL : MeasurementType.POINT)); Measurement measurement = new Measurement(virus, serum, virusDate, serumDate, type, rawTitre, isLowerThreshold); if (USE_THRESHOLDS || !isThreshold) { measurements.add(measurement); } } double[] maxColumnTitres = new double[serumNames.size()]; for (Measurement measurement : measurements) { double titre = measurement.log2Titre; if (Double.isNaN(titre)) { titre = measurement.log2Titre; } if (titre > maxColumnTitres[measurement.serum]) { maxColumnTitres[measurement.serum] = titre; } } this.mdsDimension = mdsDimension; this.mdsPrecisionParameter = mdsPrecisionParameter; addVariable(mdsPrecisionParameter); this.locationDriftParameter = locationDriftParameter; if (this.locationDriftParameter != null) { addVariable(locationDriftParameter); } this.virusDriftParameter = virusDriftParameter; if (this.virusDriftParameter != null) { addVariable(virusDriftParameter); } this.serumDriftParameter = serumDriftParameter; if (this.serumDriftParameter != null) { addVariable(serumDriftParameter); } this.virusLocationsParameter = virusLocationsParameter; if (this.virusLocationsParameter != null) { setupLocationsParameter(virusLocationsParameter, virusNames); } this.serumLocationsParameter = serumLocationsParameter; if (this.serumLocationsParameter != null) { setupLocationsParameter(serumLocationsParameter, serumNames); } this.tipTraitsParameter = tipTraitsParameter; if (tipTraitsParameter != null) { setupTipTraitsParameter(this.tipTraitsParameter, virusNames); } this.virusOffsetsParameter = virusOffsetsParameter; if (virusOffsetsParameter != null) { setupOffsetsParameter(virusOffsetsParameter, virusNames, virusDates, earliestDate); } this.serumOffsetsParameter = serumOffsetsParameter; if (serumOffsetsParameter != null) { setupOffsetsParameter(serumOffsetsParameter, serumNames, serumDates, earliestDate); } this.serumPotenciesParameter = setupSerumPotencies(serumPotenciesParameter, maxColumnTitres); this.serumBreadthsParameter = setupSerumBreadths(serumBreadthsParameter); this.virusAviditiesParameter = setupVirusAvidities(virusAviditiesParameter); StringBuilder sb = new StringBuilder(); sb.append("\tAntigenicLikelihood:\n"); sb.append("\t\t" + virusNames.size() + " viruses\n"); sb.append("\t\t" + serumNames.size() + " sera\n"); sb.append("\t\t" + measurements.size() + " assay measurements\n"); if (USE_THRESHOLDS) { sb.append("\t\t" + thresholdCount + " thresholded measurements\n"); } if (useIntervals) { sb.append("\n\t\tAssuming a log 2 measurement interval width of " + intervalWidth + "\n"); } Logger.getLogger("dr.evomodel").info(sb.toString()); virusLocationChanged = new boolean[this.virusLocationsParameter.getParameterCount()]; serumLocationChanged = new boolean[this.serumLocationsParameter.getParameterCount()]; virusEffectChanged = new boolean[virusNames.size()]; serumEffectChanged = new boolean[serumNames.size()]; logLikelihoods = new double[measurements.size()]; storedLogLikelihoods = new double[measurements.size()]; // driftInitialLocations = 1; //charles added - now specified in the xml // setupInitialLocations(driftInitialLocations); // loadInitialLocations(virusNames, serumNames); //System.out.println("Print now!"); // for (int i = 0; i < virusLocationsParameter.getParameterCount(); i++) { // System.out.print(virusLocationsParameter.getParameter(i).getParameterValue(0) + " "); // System.out.print(virusLocationsParameter.getParameter(i).getParameterValue(1) + " "); // } // System.out.println(""); if(clusterMeans){ this.clusterMeans = clusterMeans; this.clusterOffsetsParameter = clusterOffsetsParameter; //if(clusterOffsetsParameter != null){ //System.out.println("virusNames.size()="+ virusNames.size()); //clusterOffsetsParameter.setDimension( virusNames.size()); // for (int i = 0; i < virusNames.size(); i++) { // clusterOffsetsParameter.setId(virusNames.get(i)); // } //addVariable(clusterOffsetsParameter); //} //stay null if (clusterOffsetsParameter == null) { // clusterOffsetsParameter = new Parameter.Default("clusterOffsets"); } else { //clusterOffsetsParameter.addBounds(new Parameter.DefaultBounds(Double.MAX_VALUE, 0.0, 1000)); addVariable(clusterOffsetsParameter); clusterOffsetsParameter.setDimension(virusNames.size()); } System.out.println(" clusterMeans = true"); //System.exit(0); } makeDirty(); loadInitialSerumLocations(serumNames); System.out.println("======================================"); double sum=0; double s2 = 0; for(int i=0; i < serumLocationsParameter.getParameterCount(); i++){ sum+=serumLocationsParameter.getParameter(i).getParameterValue(0); s2+=serumLocationsParameter.getParameter(i).getParameterValue(1); } System.out.println("sum sera location dimension 1 = " + sum); System.out.println("sum sera location dimension 2 = " + s2); System.out.println("======================================"); // System.exit(0); } //load initial serum location - load the last line private void loadInitialSerumLocations(List<String> serumNames) { FileReader fileReader2; try { // fileReader2 = new FileReader("/Users/charles/Documents/researchData/clustering/output/test23/run4/H3N2_mds.serumLocs.log"); //fileReader2 = new FileReader("/Users/charles/Documents/researchData/clustering/output/test25/run64/H3N2_mds.serumLocs.log"); fileReader2 = new FileReader("/Users/charles/Documents/researchData/clustering/output/test25/run79/H3N2_mds.serumLocs.log"); /** * Creating a buffered reader to read the file */ BufferedReader bReader2 = new BufferedReader( fileReader2); String line; line = bReader2.readLine(); line = bReader2.readLine(); line = bReader2.readLine(); System.out.println(line); String namevalue[] = line.split("\t"); //skip to the last line String testLine; while ((testLine = bReader2.readLine()) != null){ line = testLine; } System.out.println(line); String datavalue[] = line.split("\t"); // double sumDim2=0; // System.out.println(serumLocationsParameter.getParameterCount()); for (int i = 0; i < serumLocationsParameter.getParameterCount(); i++) { //int index = findStrain( namevalue[i*2+1], serumNames); //don't enable this.. this will cause a bug because the serumNames are not unique. //System.out.println("index=" + index); double dim1 = Double.parseDouble(datavalue[i*2+1])- serumDriftParameter.getParameterValue(0)*serumOffsetsParameter.getParameterValue(i); double dim2 = Double.parseDouble(datavalue[i*2+2]); // System.out.println(datavalue[i*2+1]); serumLocationsParameter.getParameter(i).setParameterValue(0, dim1); serumLocationsParameter.getParameter(i).setParameterValue(1, dim2); // sumDim2+= dim2; // System.out.print(dim2 + "\t"); //virusLocationsParameter.getParameter(i).setParameterValue(0, 1); } // System.out.println("\n sum dim2 = " + sumDim2); // System.exit(0); bReader2.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private Parameter setupVirusAvidities(Parameter virusAviditiesParameter) { // If no row parameter is given, then we will only use the serum effects if (virusAviditiesParameter != null) { virusAviditiesParameter.addBounds(new Parameter.DefaultBounds(Double.MAX_VALUE, Double.MIN_VALUE, 1)); virusAviditiesParameter.setDimension(virusNames.size()); addVariable(virusAviditiesParameter); String[] labelArray = new String[virusNames.size()]; virusNames.toArray(labelArray); virusAviditiesParameter.setDimensionNames(labelArray); for (int i = 0; i < virusNames.size(); i++) { virusAviditiesParameter.setParameterValueQuietly(i, 0.0); } } return virusAviditiesParameter; } private Parameter setupSerumPotencies(Parameter serumPotenciesParameter, double[] maxColumnTitres) { // If no serum potencies parameter is given, make one to hold maximum values for scaling titres... if (serumPotenciesParameter == null) { serumPotenciesParameter = new Parameter.Default("serumPotencies"); } else { serumPotenciesParameter.addBounds(new Parameter.DefaultBounds(Double.MAX_VALUE, 0.0, 1)); addVariable(serumPotenciesParameter); } serumPotenciesParameter.setDimension(serumNames.size()); String[] labelArray = new String[serumNames.size()]; serumNames.toArray(labelArray); serumPotenciesParameter.setDimensionNames(labelArray); for (int i = 0; i < maxColumnTitres.length; i++) { serumPotenciesParameter.setParameterValueQuietly(i, maxColumnTitres[i]); } return serumPotenciesParameter; } private Parameter setupSerumBreadths(Parameter serumBreadthsParameter) { // If no serum breadths parameter is given, then we will only use the serum potencies if (serumBreadthsParameter != null) { serumBreadthsParameter.addBounds(new Parameter.DefaultBounds(Double.MAX_VALUE, 0.0, 1)); serumBreadthsParameter.setDimension(serumNames.size()); addVariable(serumBreadthsParameter); String[] labelArray = new String[serumNames.size()]; serumNames.toArray(labelArray); serumBreadthsParameter.setDimensionNames(labelArray); for (int i = 0; i < serumNames.size(); i++) { serumBreadthsParameter.setParameterValueQuietly(i, 1.0); } } return serumBreadthsParameter; } protected void setupLocationsParameter(MatrixParameter locationsParameter, List<String> strains) { locationsParameter.setColumnDimension(mdsDimension); locationsParameter.setRowDimension(strains.size()); for (int i = 0; i < strains.size(); i++) { locationsParameter.getParameter(i).setId(strains.get(i)); } addVariable(locationsParameter); } private void setupOffsetsParameter(Parameter offsetsParameter, List<String> strainNames, List<Double> strainDates, double earliest) { offsetsParameter.setDimension(strainNames.size()); String[] labelArray = new String[strainNames.size()]; strainNames.toArray(labelArray); offsetsParameter.setDimensionNames(labelArray); for (int i = 0; i < strainNames.size(); i++) { Double offset = strainDates.get(i) - new Double(earliest); if (offset == null) { throw new IllegalArgumentException("Date missing for strain: " + strainNames.get(i)); } offsetsParameter.setParameterValue(i, offset); } addVariable(offsetsParameter); } private void setupTipTraitsParameter(CompoundParameter tipTraitsParameter, List<String> strainNames) { tipIndices = new int[strainNames.size()]; for (int i = 0; i < strainNames.size(); i++) { tipIndices[i] = -1; } for (int i = 0; i < tipTraitsParameter.getParameterCount(); i++) { Parameter tip = tipTraitsParameter.getParameter(i); String label = tip.getParameterName(); int index = findStrain(label, strainNames); if (index != -1) { if (tipIndices[index] != -1) { throw new IllegalArgumentException("Duplicated tip name: " + label); } tipIndices[index] = i; // rather than setting these here, we set them when the locations are set so the changes propagate // through to the diffusion model. // Parameter location = locationsParameter.getParameter(index); // for (int dim = 0; dim < mdsDimension; dim++) { // tip.setParameterValue(dim, location.getParameterValue(dim)); // } } else { // The tree may contain viruses not present in the assay data // throw new IllegalArgumentException("Unmatched tip name in assay data: " + label); } } // we are only setting this parameter not listening to it: // addVariable(this.tipTraitsParameter); } private final int findStrain(String label, List<String> strainNames) { int index = 0; for (String strainName : strainNames) { if (label.startsWith(strainName)) { return index; } index ++; } return -1; } private void setupInitialLocations(double drift) { //System.out.println("hihi"); for (int i = 0; i < virusLocationsParameter.getParameterCount(); i++) { double offset = 0.0; if (virusOffsetsParameter != null) { //System.out.print("virus Offset Parameter present"+ ": "); //System.out.print( virusOffsetsParameter.getParameterValue(i) + " "); //System.out.print(" drift= " + drift + " "); offset = drift * virusOffsetsParameter.getParameterValue(i); } else{ System.out.println("virus Offeset Parameter NOT present"); } double r = MathUtils.nextGaussian() + offset; virusLocationsParameter.getParameter(i).setParameterValue(0, r); // System.out.println ( virusLocationsParameter.getParameter(i).getParameterValue(0)); if (mdsDimension > 1) { for (int j = 1; j < mdsDimension; j++) { r = MathUtils.nextGaussian(); virusLocationsParameter.getParameter(i).setParameterValue(j, r); } } } for (int i = 0; i < serumLocationsParameter.getParameterCount(); i++) { double offset = 0.0; if (serumOffsetsParameter != null) { offset = drift * serumOffsetsParameter.getParameterValue(i); } double r = MathUtils.nextGaussian() + offset; serumLocationsParameter.getParameter(i).setParameterValue(0, r); if (mdsDimension > 1) { for (int j = 1; j < mdsDimension; j++) { r = MathUtils.nextGaussian(); serumLocationsParameter.getParameter(i).setParameterValue(j, r); } } } } //load initial private void loadInitialLocations(List<String> strainNames, List<String> serumNames) { FileReader fileReader; try { //fileReader = new FileReader("/Users/charles/Documents/research/antigenic/GenoPheno/Gabriela/results/initialCondition/H3N2_mds.virusLocs.log"); fileReader = new FileReader("/Users/charles/Documents/research/antigenic/GenoPheno/Gabriela/results/initialConditionWithInitialLocationDrift/lastIteration/H3N2_mds.virusLocs.log"); /** * Creating a buffered reader to read the file */ BufferedReader bReader = new BufferedReader( fileReader); String line; //this routine may give false results if there are extra lines with spaces line = bReader.readLine(); System.out.println(line); String namevalue[] = line.split("\t"); line = bReader.readLine(); System.out.println(line); String datavalue[] = line.split("\t"); for (int i = 0; i < virusLocationsParameter.getParameterCount(); i++) { int index = findStrain( namevalue[i*2+1], strainNames); //note. namevalue actually has the extra 1 or 2attached to it.. but it doesn't seem to matter // System.out.println("name: " + virusLocationsParameter.getParameter(i).getParameterName() + " :" + index); // System.out.println(datavalue[i*2+1]); virusLocationsParameter.getParameter(index).setParameterValue(0, Double.parseDouble(datavalue[i*2+1])); virusLocationsParameter.getParameter(index).setParameterValue(1, Double.parseDouble(datavalue[i*2+2])); //virusLocationsParameter.getParameter(i).setParameterValue(0, 1); // System.out.print(virusLocationsParameter.getParameter(i).getParameterValue(0) + " "); // System.out.print(virusLocationsParameter.getParameter(i).getParameterValue(1) + " "); } bReader.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } FileReader fileReader2; try { //fileReader2 = new FileReader("/Users/charles/Documents/research/antigenic/GenoPheno/Gabriela/results/initialCondition/H3N2.serumLocs.log"); fileReader2 = new FileReader("/Users/charles/Documents/research/antigenic/GenoPheno/Gabriela/results/initialConditionWithInitialLocationDrift/lastIteration/H3N2.serumLocs.log"); /** * Creating a buffered reader to read the file */ BufferedReader bReader2 = new BufferedReader( fileReader2); String line; line = bReader2.readLine(); System.out.println(line); String namevalue[] = line.split("\t"); line = bReader2.readLine(); System.out.println(line); String datavalue[] = line.split("\t"); // System.out.println(serumLocationsParameter.getParameterCount()); for (int i = 0; i < serumLocationsParameter.getParameterCount(); i++) { int index = findStrain( namevalue[i*2+1], serumNames); // System.out.println(datavalue[i*2+1]); serumLocationsParameter.getParameter(index).setParameterValue(0, Double.parseDouble(datavalue[i*2+1])); serumLocationsParameter.getParameter(index).setParameterValue(1, Double.parseDouble(datavalue[i*2+2])); //virusLocationsParameter.getParameter(i).setParameterValue(0, 1); } bReader2.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override protected void handleModelChangedEvent(Model model, Object object, int index) { } @Override protected void handleVariableChangedEvent(Variable variable, int index, Variable.ChangeType type) { if (variable == virusLocationsParameter) { int loc = index / mdsDimension; virusLocationChanged[loc] = true; if (tipTraitsParameter != null && tipIndices[loc] != -1) { Parameter location = virusLocationsParameter.getParameter(loc); Parameter tip = tipTraitsParameter.getParameter(tipIndices[loc]); int dim = index % mdsDimension; tip.setParameterValue(dim, location.getParameterValue(dim)); } } else if (variable == serumLocationsParameter) { int loc = index / mdsDimension; serumLocationChanged[loc] = true; } else if (variable == mdsPrecisionParameter) { setLocationChangedFlags(true); } else if (variable == locationDriftParameter) { setLocationChangedFlags(true); } else if (variable == virusDriftParameter) { setLocationChangedFlags(true); } else if (variable == serumDriftParameter) { setLocationChangedFlags(true); } else if (variable == serumPotenciesParameter) { serumEffectChanged[index] = true; } else if (variable == serumBreadthsParameter) { serumEffectChanged[index] = true; } else if (variable == virusAviditiesParameter) { virusEffectChanged[index] = true; } else { // could be a derived class's parameter // throw new IllegalArgumentException("Unknown parameter"); } likelihoodKnown = false; } @Override protected void storeState() { System.arraycopy(logLikelihoods, 0, storedLogLikelihoods, 0, logLikelihoods.length); } @Override protected void restoreState() { double[] tmp = logLikelihoods; logLikelihoods = storedLogLikelihoods; storedLogLikelihoods = tmp; likelihoodKnown = false; } @Override protected void acceptState() { } public Model getModel() { return this; } public double getLogLikelihood() { //uncommenting for testing only //System.exit(0); // if (!likelihoodKnown) { logLikelihood = computeLogLikelihood(); // } //System.out.println(" logL of AGLikelihoodTreeCluster =" + logLikelihood); //System.out.println(" p(new)/p(old) = " + Math.exp(logLikelihood - oldLogLikelihood) ); //oldLogLikelihood = logLikelihood; // logLikelihood=0; //for testing purpose only //System.out.println("logLikelihood of AGLikelihoodCluster= " + logLikelihood); return logLikelihood; } // This function can be overwritten to implement other sampling densities, i.e. discrete ranks private double computeLogLikelihood() { double precision = mdsPrecisionParameter.getParameterValue(0); double sd = 1.0 / Math.sqrt(precision); logLikelihood = 0.0; int i = 0; for (Measurement measurement : measurements) { if (virusLocationChanged[measurement.virus] || serumLocationChanged[measurement.serum] || virusEffectChanged[measurement.virus] || serumEffectChanged[measurement.serum]) { double expectation = calculateBaseline(measurement.virus, measurement.serum) - computeDistance(measurement.virus, measurement.serum); switch (measurement.type) { case INTERVAL: { double minTitre = measurement.log2Titre; double maxTitre = measurement.log2Titre + intervalWidth; logLikelihoods[i] = computeMeasurementIntervalLikelihood(minTitre, maxTitre, expectation, sd); } break; case POINT: { logLikelihoods[i] = computeMeasurementLikelihood(measurement.log2Titre, expectation, sd); } break; case THRESHOLD: { if(measurement.isLowerThreshold){ logLikelihoods[i] = computeMeasurementThresholdLikelihood(measurement.log2Titre, expectation, sd); } else{ logLikelihoods[i] = computeMeasurementUpperThresholdLikelihood(measurement.log2Titre, expectation, sd); } } break; case MISSING: break; } } logLikelihood += logLikelihoods[i]; i++; } //System.out.println("\nlogLikelihood sum = " + logLikelihood); likelihoodKnown = true; setLocationChangedFlags(false); setSerumEffectChangedFlags(false); setVirusEffectChangedFlags(false); return logLikelihood; } private void setLocationChangedFlags(boolean flag) { for (int i = 0; i < virusLocationChanged.length; i++) { virusLocationChanged[i] = flag; } for (int i = 0; i < serumLocationChanged.length; i++) { serumLocationChanged[i] = flag; } } private void setSerumEffectChangedFlags(boolean flag) { for (int i = 0; i < serumEffectChanged.length; i++) { serumEffectChanged[i] = flag; } } private void setVirusEffectChangedFlags(boolean flag) { for (int i = 0; i < virusEffectChanged.length; i++) { virusEffectChanged[i] = flag; } } // offset virus and serum location when computing protected double computeDistance(int virus, int serum) { Parameter vLoc = virusLocationsParameter.getParameter(virus); Parameter sLoc = serumLocationsParameter.getParameter(serum); double sum = 0.0; // first dimension is shifted double vxOffset = 0.0; double sxOffset = 0.0; if(clusterMeans == true){ if(virusDriftParameter!= null && virusOffsetsParameter != null && serumOffsetsParameter != null && clusterOffsetsParameter!=null){ // vxOffset = virusDriftParameter.getParameterValue(0)* clusterOffsetsParameter.getParameterValue(virus); sxOffset = serumDriftParameter.getParameterValue(0) * serumOffsetsParameter.getParameterValue(serum); //vxOffset = locationDriftParameter.getParameterValue(0)* ; // System.out.println("clusterOffset =" + clusterOffsetsParameter.getParameterValue(virus)); //System.out.println("offset = " + vxOffset); } //overwrite serum drift if (serumDriftParameter != null && serumOffsetsParameter != null) { // System.out.println("hihi ya"); sxOffset = serumDriftParameter.getParameterValue(0) * serumOffsetsParameter.getParameterValue(serum); } } else{ if (locationDriftParameter != null && virusOffsetsParameter != null && serumOffsetsParameter != null) { vxOffset = locationDriftParameter.getParameterValue(0) * virusOffsetsParameter.getParameterValue(virus); sxOffset = locationDriftParameter.getParameterValue(0) * serumOffsetsParameter.getParameterValue(serum); } if (virusDriftParameter != null && virusOffsetsParameter != null) { vxOffset = virusDriftParameter.getParameterValue(0) * virusOffsetsParameter.getParameterValue(virus); } if (serumDriftParameter != null && serumOffsetsParameter != null) { sxOffset = serumDriftParameter.getParameterValue(0) * serumOffsetsParameter.getParameterValue(serum); } } double vxLoc = vLoc.getParameterValue(0) + vxOffset; double sxLoc = sLoc.getParameterValue(0) + sxOffset; // if(virus ==1){ // System.out.println("virus " + virus + " has vxLoc of " + vxLoc + " = " + vLoc.getParameterValue(0) + "+" + vxOffset); //} double difference = vxLoc - sxLoc; sum += difference * difference; // other dimensions are not for (int i = 1; i < mdsDimension; i++) { difference = vLoc.getParameterValue(i) - sLoc.getParameterValue(i); sum += difference * difference; } double dist = Math.sqrt(sum); if (serumBreadthsParameter != null) { double serumBreadth = serumBreadthsParameter.getParameterValue(serum); dist /= serumBreadth; } //if(serum ==0){ //System.out.println("The serum location is " + sxLoc +"," + sLoc.getParameterValue(1)); // } return(dist); } // offset virus and serum location when computing protected double computeDistanceBasedOnArray(int virus, int serum, double[][] virusLocArray) { // Parameter vLoc = virusLocationsParameter.getParameter(virus); Parameter sLoc = serumLocationsParameter.getParameter(serum); double sum = 0.0; // first dimension is shifted double vxOffset = 0.0; double sxOffset = 0.0; if(clusterMeans == true){ if(virusDriftParameter!= null && virusOffsetsParameter != null && serumOffsetsParameter != null && clusterOffsetsParameter!=null){ vxOffset = virusDriftParameter.getParameterValue(0)* clusterOffsetsParameter.getParameterValue(virus); sxOffset = virusDriftParameter.getParameterValue(0) * serumOffsetsParameter.getParameterValue(serum); //vxOffset = locationDriftParameter.getParameterValue(0)* ; // System.out.println("clusterOffset =" + clusterOffsetsParameter.getParameterValue(virus)); //System.out.println("offset = " + vxOffset); } //overwrite serum drift if (serumDriftParameter != null && serumOffsetsParameter != null) { // System.out.println("hihi ya"); sxOffset = serumDriftParameter.getParameterValue(0) * serumOffsetsParameter.getParameterValue(serum); } } else{ if (locationDriftParameter != null && virusOffsetsParameter != null && serumOffsetsParameter != null) { vxOffset = locationDriftParameter.getParameterValue(0) * virusOffsetsParameter.getParameterValue(virus); sxOffset = locationDriftParameter.getParameterValue(0) * serumOffsetsParameter.getParameterValue(serum); } if (virusDriftParameter != null && virusOffsetsParameter != null) { vxOffset = virusDriftParameter.getParameterValue(0) * virusOffsetsParameter.getParameterValue(virus); } if (serumDriftParameter != null && serumOffsetsParameter != null) { sxOffset = serumDriftParameter.getParameterValue(0) * serumOffsetsParameter.getParameterValue(serum); } } //double vxLoc = vLoc.getParameterValue(0) + vxOffset; double vxLoc = virusLocArray[virus][0] + vxOffset; double sxLoc = sLoc.getParameterValue(0) + sxOffset; // if(virus ==1){ // System.out.println("virus " + virus + " has vxLoc of " + vxLoc + " = " + vLoc.getParameterValue(0) + "+" + vxOffset); //} double difference = vxLoc - sxLoc; sum += difference * difference; // other dimensions are not for (int i = 1; i < mdsDimension; i++) { // difference = vLoc.getParameterValue(i) - sLoc.getParameterValue(i); difference = virusLocArray[virus][i] - sLoc.getParameterValue(i); sum += difference * difference; } double dist = Math.sqrt(sum); if (serumBreadthsParameter != null) { double serumBreadth = serumBreadthsParameter.getParameterValue(serum); dist /= serumBreadth; } return dist; } // Calculates the expected log2 titre when mapDistance = 0 private double calculateBaseline(int virus, int serum) { double baseline = serumPotenciesParameter.getParameterValue(serum); if (virusAviditiesParameter != null) { baseline += virusAviditiesParameter.getParameterValue(virus); } return baseline; } private static double computeMeasurementLikelihood(double titre, double expectation, double sd) { double lnL = NormalDistribution.logPdf(titre, expectation, sd); if (CHECK_INFINITE && Double.isNaN(lnL) || Double.isInfinite(lnL)) { throw new RuntimeException("infinite point measurement"); } return lnL; } private static double computeMeasurementThresholdLikelihood(double titre, double expectation, double sd) { // real titre is somewhere between -infinity and measured 'titre' // want the lower tail of the normal CDF double lnL = NormalDistribution.cdf(titre, expectation, sd, true); // returns logged CDF if (CHECK_INFINITE && Double.isNaN(lnL) || Double.isInfinite(lnL)) { throw new RuntimeException("infinite threshold measurement"); } return lnL; } private static double computeMeasurementUpperThresholdLikelihood(double titre, double expectation, double sd) { // real titre is somewhere between -infinity and measured 'titre' // want the lower tail of the normal CDF double L = NormalDistribution.cdf(titre, expectation, sd, false); // returns CDF double lnL = Math.log(1-L); //get the upper tail probability, then log it if (CHECK_INFINITE && Double.isNaN(lnL) || Double.isInfinite(lnL)) { throw new RuntimeException("infinite threshold measurement"); } return lnL; } private static double computeMeasurementIntervalLikelihood(double minTitre, double maxTitre, double expectation, double sd) { // real titre is somewhere between measured minTitre and maxTitre double cdf1 = NormalDistribution.cdf(maxTitre, expectation, sd, true); // returns logged CDF double cdf2 = NormalDistribution.cdf(minTitre, expectation, sd, true); // returns logged CDF double lnL = LogTricks.logDiff(cdf1, cdf2); if (CHECK_INFINITE && Double.isNaN(lnL) || Double.isInfinite(lnL)) { // this occurs when the interval is in the far tail of the distribution, cdf1 == cdf2 // instead return logPDF of the point lnL = NormalDistribution.logPdf(minTitre, expectation, sd); if (CHECK_INFINITE && Double.isNaN(lnL) || Double.isInfinite(lnL)) { throw new RuntimeException("infinite interval measurement"); } } return lnL; } public void makeDirty() { likelihoodKnown = false; setLocationChangedFlags(true); } private class Measurement { private Measurement(final int virus, final int serum, final double virusDate, final double serumDate, final MeasurementType type, final double titre, final boolean isLowerThreshold) { this.virus = virus; this.serum = serum; this.virusDate = virusDate; this.serumDate = serumDate; this.type = type; this.titre = titre; this.log2Titre = Math.log(titre) / Math.log(2); this.isLowerThreshold = isLowerThreshold; } final int virus; final int serum; final double virusDate; final double serumDate; final MeasurementType type; final double titre; final double log2Titre; final boolean isLowerThreshold; }; private final List<Measurement> measurements = new ArrayList<Measurement>(); private final List<String> virusNames = new ArrayList<String>(); private final List<String> serumNames = new ArrayList<String>(); private final List<Double> virusDates = new ArrayList<Double>(); private final List<Double> serumDates = new ArrayList<Double>(); private final int mdsDimension; private final double intervalWidth; private final Parameter mdsPrecisionParameter; private final Parameter locationDriftParameter; private final Parameter virusDriftParameter; private final Parameter serumDriftParameter; private final MatrixParameter virusLocationsParameter; private final MatrixParameter serumLocationsParameter; private final Parameter virusOffsetsParameter; private final Parameter serumOffsetsParameter; private final CompoundParameter tipTraitsParameter; private int[] tipIndices; private final Parameter virusAviditiesParameter; private final Parameter serumPotenciesParameter; private final Parameter serumBreadthsParameter; private double logLikelihood = 0.0; private boolean likelihoodKnown = false; private final boolean[] virusLocationChanged; private final boolean[] serumLocationChanged; private final boolean[] serumEffectChanged; private final boolean[] virusEffectChanged; private double[] logLikelihoods; private double[] storedLogLikelihoods; private boolean clusterMeans = false; private Parameter clusterOffsetsParameter; // ************************************************************** // XMLObjectParser // ************************************************************** public static XMLObjectParser PARSER = new AbstractXMLObjectParser() { public final static String FILE_NAME = "fileName"; public final static String TIP_TRAIT = "tipTrait"; public final static String VIRUS_LOCATIONS = "virusLocations"; public final static String SERUM_LOCATIONS = "serumLocations"; public static final String MDS_DIMENSION = "mdsDimension"; public static final String MERGE_SERUM_ISOLATES = "mergeSerumIsolates"; public static final String DRIFT_INITIAL_LOCATIONS = "driftInitialLocations"; public static final String INTERVAL_WIDTH = "intervalWidth"; public static final String MDS_PRECISION = "mdsPrecision"; public static final String LOCATION_DRIFT = "locationDrift"; public static final String VIRUS_DRIFT = "virusDrift"; public static final String SERUM_DRIFT = "serumDrift"; public static final String VIRUS_AVIDITIES = "virusAvidities"; public static final String SERUM_POTENCIES = "serumPotencies"; public static final String SERUM_BREADTHS = "serumBreadths"; public final static String VIRUS_OFFSETS = "virusOffsets"; public final static String SERUM_OFFSETS = "serumOffsets"; public final static String CLUSTER_MEANS = "clusterMeans"; public final static String CLUSTER_OFFSETS = "clusterOffsetsParameter"; public String getParserName() { return AG_LIKELIHOOD; } public Object parseXMLObject(XMLObject xo) throws XMLParseException { String fileName = xo.getStringAttribute(FILE_NAME); DataTable<String[]> assayTable; try { assayTable = DataTable.Text.parse(new FileReader(fileName), true, false); } catch (IOException e) { throw new XMLParseException("Unable to read assay data from file: " + e.getMessage()); } System.out.println("Loaded HI table file: " + fileName); boolean mergeSerumIsolates = xo.getAttribute(MERGE_SERUM_ISOLATES, false); boolean cluster_means = xo.getAttribute(CLUSTER_MEANS, false); int mdsDimension = xo.getIntegerAttribute(MDS_DIMENSION); double intervalWidth = 0.0; if (xo.hasAttribute(INTERVAL_WIDTH)) { intervalWidth = xo.getDoubleAttribute(INTERVAL_WIDTH); } double driftInitialLocations = 0.0; if (xo.hasAttribute(DRIFT_INITIAL_LOCATIONS)) { driftInitialLocations = xo.getDoubleAttribute(DRIFT_INITIAL_LOCATIONS); } CompoundParameter tipTraitParameter = null; if (xo.hasChildNamed(TIP_TRAIT)) { tipTraitParameter = (CompoundParameter) xo.getElementFirstChild(TIP_TRAIT); } MatrixParameter virusLocationsParameter = null; if (xo.hasChildNamed(VIRUS_LOCATIONS)) { virusLocationsParameter = (MatrixParameter) xo.getElementFirstChild(VIRUS_LOCATIONS); } MatrixParameter serumLocationsParameter = null; if (xo.hasChildNamed(SERUM_LOCATIONS)) { serumLocationsParameter = (MatrixParameter) xo.getElementFirstChild(SERUM_LOCATIONS); } Parameter mdsPrecision = (Parameter) xo.getElementFirstChild(MDS_PRECISION); Parameter locationDrift = null; if (xo.hasChildNamed(LOCATION_DRIFT)) { locationDrift = (Parameter) xo.getElementFirstChild(LOCATION_DRIFT); } Parameter virusDrift = null; if (xo.hasChildNamed(VIRUS_DRIFT)) { virusDrift = (Parameter) xo.getElementFirstChild(VIRUS_DRIFT); } Parameter serumDrift = null; if (xo.hasChildNamed(SERUM_DRIFT)) { serumDrift = (Parameter) xo.getElementFirstChild(SERUM_DRIFT); } Parameter virusOffsetsParameter = null; if (xo.hasChildNamed(VIRUS_OFFSETS)) { virusOffsetsParameter = (Parameter) xo.getElementFirstChild(VIRUS_OFFSETS); } Parameter serumOffsetsParameter = null; if (xo.hasChildNamed(SERUM_OFFSETS)) { serumOffsetsParameter = (Parameter) xo.getElementFirstChild(SERUM_OFFSETS); } Parameter serumPotenciesParameter = null; if (xo.hasChildNamed(SERUM_POTENCIES)) { serumPotenciesParameter = (Parameter) xo.getElementFirstChild(SERUM_POTENCIES); } Parameter serumBreadthsParameter = null; if (xo.hasChildNamed(SERUM_BREADTHS)) { serumBreadthsParameter = (Parameter) xo.getElementFirstChild(SERUM_BREADTHS); } Parameter virusAviditiesParameter = null; if (xo.hasChildNamed(VIRUS_AVIDITIES)) { virusAviditiesParameter = (Parameter) xo.getElementFirstChild(VIRUS_AVIDITIES); } Parameter clusterOffsetsParameter = null; if (xo.hasChildNamed(CLUSTER_OFFSETS)) { clusterOffsetsParameter = (Parameter) xo.getElementFirstChild(CLUSTER_OFFSETS); } AGLikelihoodTreeCluster AGL = new AGLikelihoodTreeCluster( mdsDimension, mdsPrecision, locationDrift, virusDrift, serumDrift, virusLocationsParameter, serumLocationsParameter, tipTraitParameter, virusOffsetsParameter, serumOffsetsParameter, serumPotenciesParameter, serumBreadthsParameter, virusAviditiesParameter, assayTable, mergeSerumIsolates, intervalWidth, driftInitialLocations, cluster_means, clusterOffsetsParameter); Logger.getLogger("dr.evomodel").info("Using EvolutionaryCartography model. Please cite:\n" + Utils.getCitationString(AGL)); return AGL; } //************************************************************************ // AbstractXMLObjectParser implementation //************************************************************************ public String getParserDescription() { return "Provides the likelihood of immunological assay data such as Hemagglutinin inhibition (HI) given vectors of coordinates" + "for viruses and sera/antisera in some multidimensional 'antigenic' space."; } public XMLSyntaxRule[] getSyntaxRules() { return rules; } private final XMLSyntaxRule[] rules = { AttributeRule.newStringRule(FILE_NAME, false, "The name of the file containing the assay table"), AttributeRule.newIntegerRule(MDS_DIMENSION, false, "The dimension of the space for MDS"), AttributeRule.newBooleanRule(MERGE_SERUM_ISOLATES, true, "Should multiple serum isolates from the same strain have their locations merged (defaults to false)"), AttributeRule.newDoubleRule(INTERVAL_WIDTH, true, "The width of the titre interval in log 2 space"), AttributeRule.newDoubleRule(DRIFT_INITIAL_LOCATIONS, true, "The degree to drift initial virus and serum locations, defaults to 0.0"), new ElementRule(TIP_TRAIT, CompoundParameter.class, "Optional parameter of tip locations from the tree", true), new ElementRule(VIRUS_LOCATIONS, MatrixParameter.class, "Parameter of locations of all virus"), new ElementRule(SERUM_LOCATIONS, MatrixParameter.class, "Parameter of locations of all sera"), new ElementRule(VIRUS_OFFSETS, Parameter.class, "Optional parameter for virus dates to be stored", true), new ElementRule(SERUM_OFFSETS, Parameter.class, "Optional parameter for serum dates to be stored", true), new ElementRule(SERUM_POTENCIES, Parameter.class, "Optional parameter for serum potencies", true), new ElementRule(SERUM_BREADTHS, Parameter.class, "Optional parameter for serum breadths", true), new ElementRule(VIRUS_AVIDITIES, Parameter.class, "Optional parameter for virus avidities", true), new ElementRule(MDS_PRECISION, Parameter.class, "Parameter for precision of MDS embedding"), new ElementRule(LOCATION_DRIFT, Parameter.class, "Optional parameter for drifting locations with time", true), new ElementRule(VIRUS_DRIFT, Parameter.class, "Optional parameter for drifting only virus locations, overrides locationDrift", true), new ElementRule(SERUM_DRIFT, Parameter.class, "Optional parameter for drifting only serum locations, overrides locationDrift", true), AttributeRule.newBooleanRule(CLUSTER_MEANS, true, "Should we use cluster means to control the virus locations"), new ElementRule(CLUSTER_OFFSETS, Parameter.class, "Parameter of cluster offsets of all virus"), }; public Class getReturnType() { return AGLikelihoodTreeCluster.class; } }; @Override public Citation.Category getCategory() { return Citation.Category.TRAIT_MODELS; } @Override public String getDescription() { return "Bayesian Antigenic Cartography framework"; } public List<Citation> getCitations() { return Arrays.asList(new Citation( new Author[]{ new Author("C", "Cheung"), new Author("A", "Rambaut"), new Author("P", "Lemey"), new Author("MA", "Suchard"), new Author("T", "Bedford") }, Citation.Status.IN_PREPARATION ), CommonCitations.BEDFORD_2015_INTEGRATING); } public double getLogLikelihoodBasedOnPrecompute(int[] clusterLabel, int numClusters, int[] oldObservationCluster, double[] oldContribution, int[] newObservationCluster, double[] newContribution) { double precision = mdsPrecisionParameter.getParameterValue(0); double sd = 1.0 / Math.sqrt(precision); for (int i=0; i < measurements.size(); i++) { newObservationCluster[i] = clusterLabel[measurements.get(i).virus]; } double logL=0; for(int i=0; i< measurements.size(); i++ ){ if(oldObservationCluster != null && newObservationCluster[i] == oldObservationCluster[i]){ double newC = computeContribution(measurements.get(i), precision, sd); if(newC != oldContribution[i]){ System.out.println("newObservationCluster[i]=" + newObservationCluster[i] + " and old =" + oldObservationCluster[i]); System.out.println("old contribution of i=" + i + " is " + oldContribution[i] + " but new is " + newC); System.out.println("They should be the same. Why are they different?"); System.exit(0); } // System.out.println("run!"); newContribution[i] = oldContribution[i]; } else{ //recompute. newContribution[i] = computeContribution(measurements.get(i), precision, sd); } logL += newContribution[i]; } return(logL); } public double computeContribution(Measurement measurement, double precision, double sd){ double curLogL=0; double expectation = calculateBaseline(measurement.virus, measurement.serum) - computeDistance(measurement.virus, measurement.serum); switch (measurement.type) { case INTERVAL: { double minTitre = measurement.log2Titre; double maxTitre = measurement.log2Titre + intervalWidth; curLogL = computeMeasurementIntervalLikelihood(minTitre, maxTitre, expectation, sd); } break; case POINT: { curLogL = computeMeasurementLikelihood(measurement.log2Titre, expectation, sd); } break; case THRESHOLD: { if(measurement.isLowerThreshold){ curLogL = computeMeasurementThresholdLikelihood(measurement.log2Titre, expectation, sd); } else{ curLogL = computeMeasurementUpperThresholdLikelihood(measurement.log2Titre, expectation, sd); } } break; case MISSING: break; } return curLogL; } public double getClusterLogLikelihoodUpdate(int[] clusterLabel, int numClusters, int[] oldObservationCluster, double[] oldContribution, int[] newObservationCluster, double[] newContribution, double[] oldClusterSum, double[] newClusterSum) { double precision = mdsPrecisionParameter.getParameterValue(0); double sd = 1.0 / Math.sqrt(precision); List<Measurement>[] partition = new List[clusterLabel.length]; // the size may be an overkill, but it's ok for(int i=0; i < clusterLabel.length; i++){ partition[i] = new LinkedList(); } int []needUpdateCluster = new int[numClusters]; if(oldObservationCluster == null){ for (int i=0; i < measurements.size(); i++) { Measurement m = measurements.get(i); newObservationCluster[i] = clusterLabel[m.virus]; partition[clusterLabel[m.virus]].add(m); // this is correct } for(int i=0; i<numClusters; i++){ needUpdateCluster[i] = 1; } } else{ for (int i=0; i < measurements.size(); i++) { Measurement m = measurements.get(i); newObservationCluster[i] = clusterLabel[m.virus]; partition[clusterLabel[m.virus]].add(m); // this is correct if(newObservationCluster[i] != oldObservationCluster[i]){ needUpdateCluster[newObservationCluster[i]] = 1; needUpdateCluster[oldObservationCluster[i]] = 1; } } } //for(int i=0; i < needUpdateCluster.length; i++){ // System.out.println("update cluster " +i + "="+ needUpdateCluster[i] ); //} //System.out.println("=================="); //Method 1 /* double logL=0; for(int i=0; i< measurements.size(); i++ ){ if(oldContribution != null && needUpdateCluster[newObservationCluster[i]]==0){ //System.out.println("don't need to update cluster"); newContribution[i] = oldContribution[i]; } else{ //recompute. newContribution[i] = computeContribution(measurements.get(i), precision, sd); } logL += newContribution[i]; } */ //Method 2 double logL=0; for(int i=0; i < numClusters; i++ ){ if(partition[i].size() >0){ if(needUpdateCluster[i] == 0 && oldClusterSum != null){ //update the cluster i's contribution newClusterSum[i] += oldClusterSum[i]; } else{ newClusterSum[i] += computeLikelihoodBasedOnClusters(partition[i]); } logL += newClusterSum[i]; } else{ newClusterSum[i] = 0; } }//for return(logL); } public double getClusterLogLikelihood(int[] clusterLabel, int numClusters) { //public double getClusterLogLikelihood(double[][] vLoc, double[] mu0_offset, // int[] clusterLabel, int numClusters, int[] needUpdateCluster) { //double logL = computeLogLikelihood(); List<Measurement>[] partition = new List[clusterLabel.length]; // the size may be an overkill, but it's ok for(int i=0; i < clusterLabel.length; i++){ partition[i] = new LinkedList(); } //partition measurements into clusters using viruses // int j=0; // for(Measurement measurement: measurements){ // if(j < 5000){ // partition[0].add(measurement); //} //else{ // partition[1].add(measurement); // } // j++; //} for (Measurement measurement : measurements) { //System.out.println("partition #: " + clusterLabel[measurement.virus]); partition[clusterLabel[measurement.virus]].add(measurement); // this is correct } //System.exit(0); double logL=0; // TODO Auto-generated method stub for(int i=0; i < numClusters; i++ ){ //for(int i=0; i < clusterLabel.length; i++ ){ if(partition[i].size() >0){ //System.out.println("partition size is = " + partition[i].size()); logL += computeLikelihoodBasedOnClusters(partition[i]); } //if(needUpdateCluster[i] == 1){ //update the cluster i's contribution //logClusterL[i] = 1; //} //calculate logClusterL[i] //logL += logClusterL[i]; } return(logL); } private double computeLikelihoodBasedOnClusters( List<Measurement> linkedList) { double precision = mdsPrecisionParameter.getParameterValue(0); double sd = 1.0 / Math.sqrt(precision); double logL = 0.0; int i = 0; for (Measurement measurement : linkedList) { double curLogL=0; double expectation = calculateBaseline(measurement.virus, measurement.serum) - computeDistance(measurement.virus, measurement.serum); switch (measurement.type) { case INTERVAL: { double minTitre = measurement.log2Titre; double maxTitre = measurement.log2Titre + intervalWidth; curLogL = computeMeasurementIntervalLikelihood(minTitre, maxTitre, expectation, sd); } break; case POINT: { curLogL = computeMeasurementLikelihood(measurement.log2Titre, expectation, sd); } break; case THRESHOLD: { if(measurement.isLowerThreshold){ curLogL = computeMeasurementThresholdLikelihood(measurement.log2Titre, expectation, sd); } else{ curLogL = computeMeasurementUpperThresholdLikelihood(measurement.log2Titre, expectation, sd); } } break; case MISSING: break; } logL += curLogL; i++; // System.out.println("curLogL = " + curLogL); } // likelihoodKnown = true; // setLocationChangedFlags(false); // setSerumEffectChangedFlags(false); // setVirusEffectChangedFlags(false); //System.out.println("logL = " + logL); return logL; } public int getNumObservations() { return measurements.size(); } public double getNumSera() { return serumLocationsParameter.getParameterCount(); } public MatrixParameter getSerumLocationsParameter() { return serumLocationsParameter; } public void printVirusLocations() { for(int i=0; i < virusLocationsParameter.getParameterCount(); i++){ Parameter v = virusLocationsParameter.getParameter(i); System.out.println(v.getId() + " " + v.getParameterValue(0) + "," + v.getParameterValue(1)); } } }