gt:                 total += patternCounts[i];
context: /*
   * MultiPartitionTreeLikelihood.java
   *
   * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard
   *
   * This file is part of BEAST.
   * See the NOTICE file distributed with this work for additional
   * information regarding copyright ownership and licensing.
   *
   * BEAST is free software; you can redistribute it and/or modify
   * it under the terms of the GNU Lesser General Public License as
   * published by the Free Software Foundation; either version 2
   * of the License, or (at your option) any later version.
   *
   *  BEAST is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with BEAST; if not, write to the
   * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
   * Boston, MA  02110-1301  USA
   */
  
  package dr.evomodel.treelikelihood;
  
  import beagle.*;
  import dr.evolution.tree.TreeUtils;
  import dr.evomodel.branchmodel.BranchModel;
  import dr.evomodel.tree.TreeChangedEvent;
  import dr.evomodel.treedatalikelihood.BufferIndexHelper;
  import dr.evomodelxml.treelikelihood.BeagleTreeLikelihoodParser;
  import dr.evomodel.siteratemodel.SiteRateModel;
  import dr.evolution.alignment.AscertainedSitePatterns;
  import dr.evolution.alignment.PatternList;
  import dr.evolution.datatype.DataType;
  import dr.evolution.tree.NodeRef;
  import dr.evolution.tree.Tree;
  import dr.evolution.util.Taxon;
  import dr.evolution.util.TaxonList;
  import dr.evomodel.branchratemodel.BranchRateModel;
  import dr.evomodel.branchratemodel.DefaultBranchRateModel;
  import dr.evomodel.tree.TreeModel;
  import dr.evomodel.tipstatesmodel.TipStatesModel;
  import dr.inference.model.Model;
  import dr.inference.model.Parameter;
  import dr.inference.model.ThreadAwareLikelihood;
  
  import java.util.*;
  import java.util.logging.Logger;
  
  import static dr.evomodel.treedatalikelihood.BeagleFunctionality.parseSystemPropertyIntegerArray;
  import static dr.evomodel.treedatalikelihood.BeagleFunctionality.parseSystemPropertyStringArray;
  
  /**
   * BeagleTreeLikelihoodModel - implements a Likelihood Function for sequences on a tree.
   *
   * @author Andrew Rambaut
   * @author Alexei Drummond
   * @author Marc Suchard
   * @version $Id$
   */
  
  @Deprecated
  @SuppressWarnings("serial")
  public class MultiPartitionTreeLikelihood extends AbstractTreeLikelihood implements ThreadAwareLikelihood {
  
      // This property is a comma-delimited list of resource numbers (0 == CPU) to
      // allocate each BEAGLE instance to. If less than the number of instances then
      // will wrap around.
      private static final String RESOURCE_ORDER_PROPERTY = "beagle.resource.order";
      private static final String PREFERRED_FLAGS_PROPERTY = "beagle.preferred.flags";
      private static final String REQUIRED_FLAGS_PROPERTY = "beagle.required.flags";
      private static final String SCALING_PROPERTY = "beagle.scaling";
      private static final String RESCALE_FREQUENCY_PROPERTY = "beagle.rescale";
      private static final String EXTRA_BUFFER_COUNT_PROPERTY = "beagle.extra.buffer.count";
      private static final String FORCE_VECTORIZATION = "beagle.force.vectorization";
  
      // Which scheme to use if choice not specified (or 'default' is selected):
      private static final PartialsRescalingScheme DEFAULT_RESCALING_SCHEME = PartialsRescalingScheme.DYNAMIC;
  
      private static int instanceCount = 0;
      private static List<Integer> resourceOrder = null;
      private static List<Integer> preferredOrder = null;
      private static List<Integer> requiredOrder = null;
      private static List<String> scalingOrder = null;
      private static List<Integer> extraBufferOrder = null;
  
      // Default frequency for complete recomputation of scaling factors under the 'dynamic' scheme
      private static final int RESCALE_FREQUENCY = 100;
      private static final int RESCALE_TIMES = 1;
  
      public MultiPartitionTreeLikelihood(List<PatternList> patternLists,
                                          List<SiteRateModel> siteRateModels,
                                          TreeModel treeModel,
                                          BranchModel branchModel,
                                          BranchRateModel branchRateModel,
                                          TipStatesModel tipStatesModel,
                                          boolean useAmbiguities,
                                          PartialsRescalingScheme rescalingScheme) {
  
          this(patternLists, siteRateModels, treeModel, branchModel, branchRateModel, tipStatesModel, useAmbiguities, rescalingScheme, null);
      }
  
      public MultiPartitionTreeLikelihood(List<PatternList> patternLists,
                                          List<SiteRateModel> siteRateModels,
                                          TreeModel treeModel,
                                          BranchModel branchModel,
                                          BranchRateModel branchRateModel,
                                          TipStatesModel tipStatesModel,
                                          boolean useAmbiguities,
                                          PartialsRescalingScheme rescalingScheme,
                                          Map<Set<String>, Parameter> partialsRestrictions) {
  
          super(BeagleTreeLikelihoodParser.TREE_LIKELIHOOD, treeModel);
  
          try {
              final Logger logger = Logger.getLogger("dr.evomodel");
  
              logger.info("Using BEAGLE TreeLikelihood");
  
              // should be a 1 to 1 correspondence of patternLists to siteModels.
              assert(patternLists.size() == siteRateModels.size());
  
              this.dataType = patternLists.get(0).getDataType();
              this.stateCount = dataType.getStateCount();
              partitionCount = patternLists.size();
  
              this.patternLists.addAll(patternLists);
              for (PatternList patternList : patternLists) {
                  // check all patternLists).
                  assert(patternList.getDataType() == dataType);
              }
  
  
              this.siteRateModels.addAll(siteRateModels);
              this.categoryCount = this.siteRateModels.get(0).getCategoryCount();
  
              for (SiteRateModel siteRateModel : siteRateModels) {
                  // check all siteRateModels use the same number of categories
                  // (could be relaxed but this will make for easier bookkeeping).
                  assert(siteRateModel.getCategoryCount() == categoryCount);
                  addModel(siteRateModel);
              }
  
              this.branchModel = branchModel;
              addModel(this.branchModel);
  
              if (branchRateModel != null) {
                  this.branchRateModel = branchRateModel;
                  logger.info("  Branch rate model used: " + branchRateModel.getModelName());
              } else {
                  this.branchRateModel = new DefaultBranchRateModel();
              }
              addModel(this.branchRateModel);
  
              this.tipStatesModel = tipStatesModel;
  
              this.tipCount = treeModel.getExternalNodeCount();
  
              internalNodeCount = nodeCount - tipCount;
  
              int compactPartialsCount = tipCount;
              if (useAmbiguities) {
                  // if we are using ambiguities then we don't use tip partials
                  compactPartialsCount = 0;
              }
  
              // one partials buffer for each tip and two for each internal node (for store restore)
              partialBufferHelper = new BufferIndexHelper(nodeCount, tipCount);
  
              // one scaling buffer for each internal node plus an extra for the accumulation, then doubled for store/restore
              scaleBufferHelper = new BufferIndexHelper(getScaleBufferCount(), 0);
  
              // Attempt to get the resource order from the System Property
              if (resourceOrder == null) {
                  resourceOrder = parseSystemPropertyIntegerArray(RESOURCE_ORDER_PROPERTY);
              }
              if (preferredOrder == null) {
                  preferredOrder = parseSystemPropertyIntegerArray(PREFERRED_FLAGS_PROPERTY);
              }
              if (requiredOrder == null) {
                  requiredOrder = parseSystemPropertyIntegerArray(REQUIRED_FLAGS_PROPERTY);
              }
              if (scalingOrder == null) {
                  scalingOrder = parseSystemPropertyStringArray(SCALING_PROPERTY);
              }
              if (extraBufferOrder == null) {
                  extraBufferOrder = parseSystemPropertyIntegerArray(EXTRA_BUFFER_COUNT_PROPERTY);
              }
  
              int extraBufferCount = -1; // default
              if (extraBufferOrder.size() > 0) {
                  extraBufferCount = extraBufferOrder.get(instanceCount % extraBufferOrder.size());
              }
  
              substitutionModelDelegates = new SubstitutionModelDelegate[partitionCount];
              for (int i = 0; i < partitionCount; i++) {
                  substitutionModelDelegates[i] = new SubstitutionModelDelegate(treeModel, branchModel, extraBufferCount);
              }
  
              // first set the rescaling scheme to use from the parser
              this.rescalingScheme = rescalingScheme;
              int[] resourceList = null;
              long preferenceFlags = 0;
              long requirementFlags = 0;
  
              if (scalingOrder.size() > 0) {
                  this.rescalingScheme = PartialsRescalingScheme.parseFromString(
                          scalingOrder.get(instanceCount % scalingOrder.size()));
              }
  
              if (resourceOrder.size() > 0) {
                  // added the zero on the end so that a CPU is selected if requested resource fails
                  resourceList = new int[]{resourceOrder.get(instanceCount % resourceOrder.size()), 0};
                  if (resourceList[0] > 0) {
                      preferenceFlags |= BeagleFlag.PROCESSOR_GPU.getMask(); // Add preference weight against CPU
                  }
              }
  
              if (preferredOrder.size() > 0) {
                  preferenceFlags = preferredOrder.get(instanceCount % preferredOrder.size());
              }
  
              if (requiredOrder.size() > 0) {
                  requirementFlags = requiredOrder.get(instanceCount % requiredOrder.size());
              }
  
              // Define default behaviour here
              if (this.rescalingScheme == PartialsRescalingScheme.DEFAULT) {
                  //if GPU: the default is dynamic scaling in BEAST
                  if (resourceList != null && resourceList[0] > 1) {
                      this.rescalingScheme = DEFAULT_RESCALING_SCHEME;
                  } else { // if CPU: just run as fast as possible
  //                    this.rescalingScheme = PartialsRescalingScheme.NONE;
                      // Dynamic should run as fast as none until first underflow
                      this.rescalingScheme = DEFAULT_RESCALING_SCHEME;
                  }
              }
  
              if (this.rescalingScheme == PartialsRescalingScheme.AUTO) {
                  preferenceFlags |= BeagleFlag.SCALING_AUTO.getMask();
                  useAutoScaling = true;
              } else {
  //                preferenceFlags |= BeagleFlag.SCALING_MANUAL.getMask();
              }
              String r = System.getProperty(RESCALE_FREQUENCY_PROPERTY);
              if (r != null) {
                  rescalingFrequency = Integer.parseInt(r);
                  if (rescalingFrequency < 1) {
                      rescalingFrequency = RESCALE_FREQUENCY;
                  }
              }
  
              patternCounts = new int[partitionCount];
              int total = 0;
              for (int i = 0; i < patternLists.size(); i++) {
                  patternCounts[i] = patternLists.get(i).getPatternCount();
  