gt:             if (tree.getNodeHeight(i) > newHeight) {
context: /*
   * TransmissionSubtreeSlideA.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.epidemiology.casetocase.operators;
  
  import dr.evolution.tree.NodeRef;
  import dr.evolution.tree.Tree;
  import dr.evomodel.epidemiology.casetocase.AbstractCase;
  import dr.evomodel.epidemiology.casetocase.BranchMapModel;
  import dr.evomodel.epidemiology.casetocase.CaseToCaseTreeLikelihood;
  import dr.evomodel.operators.AbstractAdaptableTreeOperator;
  import dr.evomodel.operators.AbstractTreeOperator;
  import dr.evomodel.tree.TreeModel;
  import dr.inference.operators.*;
  import dr.math.MathUtils;
  import dr.xml.*;
  
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * Implements the subtree slide move where the slide does not affect the transmission tree.
   *
   * @author Matthew Hall
   *
   */
  public class TransmissionSubtreeSlideA extends AbstractAdaptableTreeOperator {
  
      private CaseToCaseTreeLikelihood c2cLikelihood;
      private TreeModel tree;
      private double size = 1.0;
      private boolean gaussian = false;
      private final boolean swapInRandomRate;
      private final boolean swapInRandomTrait;
      private final boolean resampleInfectionTimes;
      private AdaptationMode mode = AdaptationMode.DEFAULT;
      private static final boolean DEBUG = false;
      public static final String TRANSMISSION_SUBTREE_SLIDE_A = "transmissionSubtreeSlideA";
      public static final String SWAP_RATES = "swapInRandomRate";
      public static final String SWAP_TRAITS = "swapInRandomTrait";
      public static final String TARGET_ACCEPTANCE = "targetAcceptance";
  
  
      public TransmissionSubtreeSlideA(CaseToCaseTreeLikelihood c2cLikelihood, double weight, double size,
                                       boolean gaussian, boolean swapRates, boolean swapTraits,  AdaptationMode mode,
                                       boolean resampleInfectionTimes) {
          super(mode);
  
          this.c2cLikelihood = c2cLikelihood;
          tree = c2cLikelihood.getTreeModel();
          setWeight(weight);
  
          if (size == 0.0) {
              double b = 0.0;
              for (int k = 0; k < tree.getNodeCount(); ++k) {
                  b += tree.getBranchLength(tree.getNode(k));
              }
              size = b / (2 * tree.getNodeCount());
          }
  
          this.size = size;
          this.gaussian = gaussian;
          this.swapInRandomRate = swapRates;
          this.swapInRandomTrait = swapTraits;
  
          this.resampleInfectionTimes = resampleInfectionTimes;
  
          this.mode = mode;
      }
  
      /**
       * Do a probabilistic subtree slide move.
       *
       * @return the log-transformed hastings ratio
       */
      public double doOperation() {
  
          if(DEBUG){
              c2cLikelihood.outputTreeToFile("beforeTSSA.nex", false);
          }
  
          BranchMapModel branchMap = c2cLikelihood.getBranchMap();
  
          double logq = 0;
  
          NodeRef i;
  
          // 1. choose a random eligible node
  
          ArrayList<NodeRef> eligibleNodes = getEligibleNodes(tree, branchMap);
  
          i = eligibleNodes.get(MathUtils.nextInt(eligibleNodes.size()));
  
          double eligibleNodeCount = eligibleNodes.size();
  
  
          final NodeRef iP = tree.getParent(i);
          final NodeRef CiP = getOtherChild(tree, iP, i);
          final NodeRef PiP = tree.getParent(iP);
  
          // 2. choose a delta to move
          final double delta = getDelta();
          final double oldHeight = tree.getNodeHeight(iP);
          final double newHeight = oldHeight + delta;
  
          AbstractCase iCase = branchMap.get(i.getNumber());
          AbstractCase iPCase = branchMap.get(iP.getNumber());
          AbstractCase CiPCase = branchMap.get(CiP.getNumber());
          AbstractCase PiPCase = null;
          if(PiP!=null){
              PiPCase = branchMap.get(PiP.getNumber());
          }
  
          if(resampleInfectionTimes) {
              // what happens on i's branch
  
              if (iCase != iPCase) {
                  iCase.setInfectionBranchPosition(MathUtils.nextDouble());
              }
  
              // what happens between PiP and CiP
              if (PiPCase == null || CiPCase != PiPCase) {
                  CiPCase.setInfectionBranchPosition(MathUtils.nextDouble());
              }
  
          }
  
          // 3. if the move is down
          if (delta > 0) {
  
  
              // 3.1 if the topology will change
              if (PiP != null && tree.getNodeHeight(PiP) < newHeight) {
                  // find new parent
                  NodeRef newParent = PiP;
                  NodeRef newChild = iP;
                  while (tree.getNodeHeight(newParent) < newHeight) {
                      newChild = newParent;
                      newParent = tree.getParent(newParent);
                      if (newParent == null) break;
                  }
  
  
                  // if the parent has slid out of its partition
                  if(branchMap.get(newChild.getNumber())!=branchMap.get(iP.getNumber())){
  //                    throw new OperatorFailedException("invalid slide");
                      return Double.NEGATIVE_INFINITY;
                  }
  
                  // if iP is now the earliest node in its subtree
  
  
                  tree.beginTreeEdit();
  
                  // 3.1.1 if creating a new root
                  if (tree.isRoot(newChild)) {
                      tree.removeChild(iP, CiP);
                      tree.removeChild(PiP, iP);
                      tree.addChild(iP, newChild);
                      tree.addChild(PiP, CiP);
                      tree.setRoot(iP);
                      //System.err.println("Creating new root!");
  
                      if (tree.hasNodeTraits()) {
                          // **********************************************
                          // swap traits and rates so that root keeps it trait and rate values
                          // **********************************************
  
                          tree.swapAllTraits(newChild, iP);
  
                      }
  
                      if (tree.hasRates()) {
                          final double rootNodeRate = tree.getNodeRate(newChild);
                          tree.setNodeRate(newChild, tree.getNodeRate(iP));
                          tree.setNodeRate(iP, rootNodeRate);
                      }
  
                      // **********************************************
  
                  }
                  // 3.1.2 no new root
                  else {
                      tree.removeChild(iP, CiP);
                      tree.removeChild(PiP, iP);
                      tree.removeChild(newParent, newChild);
                      tree.addChild(iP, newChild);
                      tree.addChild(PiP, CiP);
                      tree.addChild(newParent, iP);
                      //System.err.println("No new root!");
                  }
  
                  tree.setNodeHeight(iP, newHeight);
  
                  tree.endTreeEdit();
  
  
                  // 3.1.3 count the hypothetical sources of this destination.
                  final int possibleSources = intersectingEdges(tree, newChild, oldHeight, branchMap,
                          branchMap.get(iP.getNumber()), null);
                  //System.out.println("possible sources = " + possibleSources);
  
                  logq -= Math.log(possibleSources);
  
              } else {
                  // just change the node height
  
                  tree.setNodeHeight(iP, newHeight);
                  logq += 0.0;
              }
          }
          // 4 if we are sliding the subtree up.
          else {
  
              // 4.0 is it a valid move?
  