/*.................................................................................................................*/
 public String getStringForTree(int ic) {
   if (treesBlock == null) return "";
   Tree tree = treesBlock.getTree(ic);
   if (tree == null) return "";
   if (tree.hasPolytomies(tree.getRoot())) return "Yes";
   else return "No";
 }
 /*..........................................ContinuousHistory................*/
 private void fillDistribution(Tree tree, int node, ContinuousAdjustable dist) {
   if (tree.nodeIsTerminal(node)) {
     int t = tree.taxonNumberOfNode(node);
     for (int i = 0; i < getNumItems(); i++) dist.setState(t, i, getState(node, i));
   } else
     for (int d = tree.firstDaughterOfNode(node); tree.nodeExists(d); d = tree.nextSisterOfNode(d))
       fillDistribution(tree, d, dist);
 }
 /*..........................................ContinuousHistory................*/
 public void calcMinMaxStates(Tree tree, int node) {
   for (int i = 0; i < getNumItems(); i++) {
     double s = getState(node, i);
     maxState = MesquiteDouble.maximum(maxState, s);
     minState = MesquiteDouble.minimum(minState, s);
   }
   for (int d = tree.firstDaughterOfNode(node); tree.nodeExists(d); d = tree.nextSisterOfNode(d))
     calcMinMaxStates(tree, d);
 }
 /**
  * Returns a new object indicating the states at the tips (used whether or not History is
  * reconstruction)
  */
 public CharacterDistribution getStatesAtTips(Tree tree) {
   if (observedStates != null) return (CharacterDistribution) observedStates.getAdjustableClone();
   else {
     ContinuousAdjustable d =
         new ContinuousAdjustable(tree.getTaxa(), tree.getTaxa().getNumTaxa());
     d.setItemsAs(this);
     fillDistribution(tree, tree.getRoot(), d);
     return d;
   }
 }
 /**
  * This readjust procedure can be called to readjust the size of storage of states of a character
  * for nodes.
  */
 public CharacterHistory adjustSize(Tree tree) {
   if (tree.getNumNodeSpaces() == this.getNumNodes()) return this;
   else {
     ContinuousHistory soc =
         new ContinuousHistory(
             tree.getTaxa(), tree.getNumNodeSpaces(), (ContinuousData) getParentData());
     soc.setItemsAs(this);
     soc.setParentData(getParentData());
     soc.setParentCharacter(getParentCharacter());
     ((CharacterStates) soc).setExplanation(getExplanation());
     return soc;
   }
 }
 /*.................................................................................................................*/
 public void modifyTree(Tree tree, MesquiteTree modified, RandomBetween rng) {
   if (tree == null || modified == null) return;
   if (tree.getTaxa().anySelected()) { // error fixed in 1. 12
     int[] terminals = tree.getTerminalTaxa(tree.getRoot());
     if (terminals == null) return;
     int numTerminals = 0;
     for (int i = 0; i < terminals.length; i++)
       if (tree.getTaxa().getSelected(terminals[i])) numTerminals++;
     if (numTerminals > numExcluded) {
       int[] selTerminals = new int[numTerminals];
       int icount = 0;
       for (int i = 0; i < terminals.length; i++)
         if (tree.getTaxa().getSelected(terminals[i])) {
           selTerminals[icount] = terminals[i];
           icount++;
         }
       terminals = selTerminals;
       for (int it = 0; it < numExcluded; it++) {
         int taxon = -1;
         int count = 0;
         int ntries = 100000;
         while (terminals[taxon = rng.randomIntBetween(0, numTerminals - 1)] < 0
             && count < ntries) {
           count++;
         }
         if (count >= ntries)
           discreetAlert(
               "ERROR: Rarefy tree failed to find taxon to delete in " + ntries + " tries.");
         else {
           int nT = modified.nodeOfTaxonNumber(terminals[taxon]);
           modified.deleteClade(nT, false);
           terminals[taxon] = -1;
         }
       }
     } else
       MesquiteMessage.warnUser(
           "Sorry, the tree could not be rarefied because more taxa are to be excluded than those available");
   } else {
     int numTerminals = tree.numberOfTerminalsInClade(tree.getRoot());
     if (numTerminals > numExcluded) {
       for (int it = 0; it < numExcluded; it++) {
         int taxon = rng.randomIntBetween(0, numTerminals - it - 1);
         int nT = modified.getTerminalNode(modified.getRoot(), taxon);
         modified.deleteClade(nT, false);
       }
     } else
       MesquiteMessage.warnUser(
           "Sorry, the tree could not be rarefied because more taxa are to be excluded than those available");
   }
 }
  /*.................................................................................................................*/
  public void calculateNumber(
      Tree tree1, Tree tree2, MesquiteNumber result, MesquiteString resultString) {
    if (result == null) return;
    clearResultAndLastResult(result);
    if (tree1 == null) return;
    if (tree2 == null) return;

    int numTaxa = tree1.getTaxa().getNumTaxa();

    double[][] patristic1 = null;
    patristic1 =
        p1.calculatePatristic(
            tree1,
            numTaxa,
            patristic1); // for this tree calculate patristic distances (number of nodes separating
                         // terminals; no branch lengths)
    double[][] patristic2 = null;
    patristic2 =
        p2.calculatePatristic(
            tree2,
            numTaxa,
            patristic2); // for this tree calculate patristic distances (number of nodes separating
                         // terminals; no branch lengths)

    double correl = offDiagonalPMCorrelationFILTERED(patristic1, patristic2);
    if (isDistance && (MesquiteDouble.isCombinable(correl)))
      correl = -correl + 1.0; // shifting 1 to -1 to be 0 to 2 to act as distance
    result.setValue(correl);
    if (resultString != null) {
      if (isDistance)
        resultString.setValue(
            "Patristic correlation (converted to distance): " + result.toString());
      else resultString.setValue("Patristic correlation: " + result.toString());
    }
    saveLastResult(result);
    saveLastResultString(resultString);
  }
  /*.................................................................................................................*/
  public Object doCommand(String commandName, String arguments, CommandChecker checker) {
    Tree trt = treeDisplay.getTree();
    MesquiteTree t = null;
    if (trt instanceof MesquiteTree) t = (MesquiteTree) trt;
    if (checker.compare(
        this.getClass(),
        "Adjust tool has touched branch",
        "[branch number][x coordinate touched][y coordinate touched][modifiers]",
        commandName,
        "touchedPositionAdjust")) {
      if (t == null) return null;
      MesquiteInteger io = new MesquiteInteger(0);
      int node = MesquiteInteger.fromString(arguments, io);
      int x = MesquiteInteger.fromString(arguments, io);
      int y = MesquiteInteger.fromString(arguments, io);
      String mod = ParseUtil.getRemaining(arguments, io);

      Point newOnLine = treeDisplay.getTreeDrawing().projectionOnLine(node, x, y);
      originalX = newOnLine.x;
      originalY = newOnLine.y;
      // lastX= newOnLine.x;
      // lastY = newOnLine.y;
      Graphics g = null;
      if (GraphicsUtil.useXORMode(null, false)) {
        g = treeDisplay.getGraphics();
        g.setXORMode(Color.white);
        g.setColor(Color.red);
      }
      // double bX = treeDisplay.getTreeDrawing().lineBaseX[node];
      // double bY = treeDisplay.getTreeDrawing().lineBaseY[node];
      // Math.sqrt((originalY-bY)*(originalY-bY) + (originalX-bX)*(originalX-bX));
      lastBL = tree.getBranchLength(node);
      double shortestAbove = MesquiteDouble.unassigned;
      for (int daughter = t.firstDaughterOfNode(node);
          t.nodeExists(daughter);
          daughter = t.nextSisterOfNode(daughter))
        shortestAbove = MesquiteDouble.minimum(shortestAbove, tree.getBranchLength(daughter));
      if (shortestAbove == MesquiteDouble.unassigned) upperLimit = MesquiteDouble.infinite;
      else if (MesquiteDouble.isCombinable(lastBL)) upperLimit = shortestAbove + lastBL;
      else upperLimit = shortestAbove + 1.0;
      int ibX = treeDisplay.getTreeDrawing().lineBaseX[node];
      int ibY = treeDisplay.getTreeDrawing().lineBaseY[node];
      lastX = treeDisplay.getTreeDrawing().lineTipX[node];
      lastY = treeDisplay.getTreeDrawing().lineTipY[node];
      if (GraphicsUtil.useXORMode(null, false)) {
        drawThickLine(g, ibX, ibY, lastX, lastY);
        for (int daughter = t.firstDaughterOfNode(node);
            t.nodeExists(daughter);
            daughter = t.nextSisterOfNode(daughter))
          drawThickLine(
              g,
              treeDisplay.getTreeDrawing().lineTipX[daughter],
              treeDisplay.getTreeDrawing().lineTipY[daughter],
              lastX,
              lastY);
        g.fillOval(
            lastX - ovalRadius,
            lastY - ovalRadius,
            ovalRadius + ovalRadius,
            ovalRadius + ovalRadius);
        try {
          g.drawString(MesquiteDouble.toString(lastBL), lastX + 10, lastY);
        } catch (InternalError e) { // workaround for bug on windows java 1.7.
        } catch (Throwable e) {
        }
        lineOn = true;
        g.dispose();
      }
    } else if (checker.compare(
        this.getClass(),
        "Adjust tool has been dropped",
        "[branch number][x coordinate dropped][y coordinate dropped]",
        commandName,
        "droppedPositionAdjust")) {
      if (t == null) return null;
      if (editorOn) return null;
      MesquiteInteger io = new MesquiteInteger(0);
      int node = MesquiteInteger.fromString(arguments, io);
      int x = MesquiteInteger.fromString(arguments, io);
      int y = MesquiteInteger.fromString(arguments, io);
      if (lineOn) {
        Point newOnLine = treeDisplay.getTreeDrawing().projectionOnLine(node, x, y);
        double bX = treeDisplay.getTreeDrawing().lineBaseX[node];
        double bY = treeDisplay.getTreeDrawing().lineBaseY[node];
        double tX = treeDisplay.getTreeDrawing().lineTipX[node];
        double tY = treeDisplay.getTreeDrawing().lineTipY[node];
        double lengthLine =
            Math.sqrt((originalY - bY) * (originalY - bY) + (originalX - bX) * (originalX - bX));
        double bL;
        if (lengthLine != 0) {
          double extension =
              Math.sqrt(
                      (newOnLine.y - bY) * (newOnLine.y - bY)
                          + (newOnLine.x - bX) * (newOnLine.x - bX))
                  / lengthLine;
          if (t.getBranchLength(node) == 0 || t.branchLengthUnassigned(node)) bL = extension;
          else bL = t.getBranchLength(node) * extension;
        } else bL = 1;

        if (bL > upperLimit) bL = upperLimit;
        else if (bL < lowerLimit) bL = lowerLimit;
        double oldBL = t.getBranchLength(node);
        if (!MesquiteDouble.isCombinable(oldBL)) oldBL = 1.0;
        t.setBranchLength(node, bL, false);
        double difference = oldBL - t.getBranchLength(node);
        for (int daughter = t.firstDaughterOfNode(node);
            t.nodeExists(daughter);
            daughter = t.nextSisterOfNode(daughter))
          if (MesquiteDouble.isCombinable(t.getBranchLength(daughter)))
            t.setBranchLength(daughter, t.getBranchLength(daughter) + difference, false);
        t.notifyListeners(this, new Notification(MesquiteListener.BRANCHLENGTHS_CHANGED));
        Graphics g = treeDisplay.getGraphics();
        g.setPaintMode();
        g.dispose();
        treeDisplay.pleaseUpdate(true);
        lineOn = false;
      }
    } else if (checker.compare(
        this.getClass(),
        "Adjust tool is being dragged",
        "[branch number][x coordinate][y coordinate]",
        commandName,
        "draggedPositionAdjust")) {
      if (t == null) return null;
      if (editorOn) return null;
      MesquiteInteger io = new MesquiteInteger(0);
      int node = MesquiteInteger.fromString(arguments, io);
      int x = MesquiteInteger.fromString(arguments, io);
      int y = MesquiteInteger.fromString(arguments, io);
      if (lineOn) {
        Point newOnLine = treeDisplay.getTreeDrawing().projectionOnLine(node, x, y);
        // WARNING":  This shouldn't result in length increase if simple click and release with no
        // drag; must subtract original X, Y
        Graphics g = null;
        if (GraphicsUtil.useXORMode(null, false)) {
          g = treeDisplay.getGraphics();
          g.setXORMode(Color.white);
          g.setColor(Color.red);
        }
        // g.fillOval(lastX-ovalRadius, lastY-ovalRadius, ovalRadius + ovalRadius, ovalRadius +
        // ovalRadius);
        // g.fillOval(newOnLine.x-ovalRadius, newOnLine.y -ovalRadius, ovalRadius + ovalRadius,
        // ovalRadius + ovalRadius);

        // g.drawLine(originalX, originalY, lastX, lastY);
        // g.drawLine(originalX, originalY, newOnLine.x, newOnLine.y);

        //				if decreasing, & unassigned involved: push unassigned down and assign values to
        // unassigned above; if increasing, push unassigne up
        int ibX = treeDisplay.getTreeDrawing().lineBaseX[node];
        int ibY = treeDisplay.getTreeDrawing().lineBaseY[node];
        int itX = treeDisplay.getTreeDrawing().lineTipX[node];
        int itY = treeDisplay.getTreeDrawing().lineTipY[node];

        double bX = ibX;
        double bY = ibY;
        double tX = itX;
        double tY = itY;
        double lengthLine =
            Math.sqrt((originalY - bY) * (originalY - bY) + (originalX - bX) * (originalX - bX));
        if (lengthLine != 0) {
          if (GraphicsUtil.useXORMode(null, false)) {
            if (MesquiteTrunk.isMacOSX()
                && MesquiteTrunk.getJavaVersionAsDouble() >= 1.5
                && MesquiteTrunk.getJavaVersionAsDouble() < 1.6) // due to a JVM bug
            g.fillRect(lastX, lastY - 20, 100, 20);
            g.drawString(MesquiteDouble.toString(lastBL), lastX + 10, lastY);
            if (MesquiteTrunk.isMacOSX()
                && MesquiteTrunk.getJavaVersionAsDouble() >= 1.5
                && MesquiteTrunk.getJavaVersionAsDouble() < 1.6) // due to a JVM bug
            g.fillRect(lastX, lastY - 20, 100, 20);
          }
          double extension =
              Math.sqrt(
                      (newOnLine.y - bY) * (newOnLine.y - bY)
                          + (newOnLine.x - bX) * (newOnLine.x - bX))
                  / lengthLine;
          double bL;
          if (t.getBranchLength(node) == 0 || t.branchLengthUnassigned(node)) bL = extension;
          else bL = t.getBranchLength(node) * extension;
          if (bL > upperLimit) {
            bL = upperLimit;
            if (t.getBranchLength(node) == 0 || t.branchLengthUnassigned(node))
              extension = upperLimit;
            else extension = upperLimit / t.getBranchLength(node);
          } else if (bL < lowerLimit) {
            bL = lowerLimit;
            if (t.getBranchLength(node) == 0 || t.branchLengthUnassigned(node))
              extension = lowerLimit;
            else extension = lowerLimit / t.getBranchLength(node);
          }
          lastBL = bL;
          if (GraphicsUtil.useXORMode(null, false)) {
            drawThickLine(g, ibX, ibY, lastX, lastY);
            for (int daughter = t.firstDaughterOfNode(node);
                t.nodeExists(daughter);
                daughter = t.nextSisterOfNode(daughter))
              drawThickLine(
                  g,
                  treeDisplay.getTreeDrawing().lineTipX[daughter],
                  treeDisplay.getTreeDrawing().lineTipY[daughter],
                  lastX,
                  lastY);
            g.fillOval(
                lastX - ovalRadius,
                lastY - ovalRadius,
                ovalRadius + ovalRadius,
                ovalRadius + ovalRadius);
          }
          int newX = ibX + (int) (extension * (tX - bX));
          int newY = ibY + (int) (extension * (tY - bY));
          if (GraphicsUtil.useXORMode(null, false)) {
            g.drawString(MesquiteDouble.toString(bL), newX + 10, newY);
            drawThickLine(g, ibX, ibY, newX, newY);
            for (int daughter = t.firstDaughterOfNode(node);
                t.nodeExists(daughter);
                daughter = t.nextSisterOfNode(daughter))
              drawThickLine(
                  g,
                  treeDisplay.getTreeDrawing().lineTipX[daughter],
                  treeDisplay.getTreeDrawing().lineTipY[daughter],
                  newX,
                  newY);
            g.fillOval(
                newX - ovalRadius,
                newY - ovalRadius,
                ovalRadius + ovalRadius,
                ovalRadius + ovalRadius);
          }
          lastX = newX;
          lastY = newY;
        }

        // lastX= newOnLine.x;
        // lastY = newOnLine.y;
      }
    }
    return null;
  }
  /*.................................................................................................................*/
  public Tree retrieveTreeBlock(TreeVector treeList, MesquiteDouble finalScore) {
    logln("Preparing to receive TNT trees.");
    boolean success = false;
    taxa = treeList.getTaxa();
    // TODO		finalScore.setValue(finalValue);

    suppressProjectPanelReset();
    CommandRecord oldCR = MesquiteThread.getCurrentCommandRecord();
    CommandRecord scr = new CommandRecord(true);
    MesquiteThread.setCurrentCommandRecord(scr);

    // define file paths and set tree files as needed.
    setFileNames();
    String[] outputFilePaths = externalProcRunner.getOutputFilePaths();

    String treeFilePath = outputFilePaths[OUT_TREEFILE];
    taxonNumberTranslation = getTaxonNumberTranslation(taxa);
    namer.setNumberTranslationTable(taxonNumberTranslation);

    runFilesAvailable();

    // read in the tree files
    success = false;
    Tree t = null;

    MesquiteBoolean readSuccess = new MesquiteBoolean(false);
    // TreeVector tv = new TreeVector(taxa);
    if (bootstrapOrJackknife()) {
      if (resamplingAllConsensusTrees)
        t =
            ZephyrUtil.readTNTTreeFile(
                this,
                treeList,
                taxa,
                treeFilePath,
                "TNT " + getResamplingKindName() + " Rep",
                0,
                readSuccess,
                false,
                false,
                null,
                namer); // set first tree number as 0 as will remove the first one later.
      else
        t =
            ZephyrUtil.readTNTTreeFile(
                this,
                treeList,
                taxa,
                treeFilePath,
                "TNT " + getResamplingKindName() + " Majority Rule Tree",
                1,
                readSuccess,
                false,
                false,
                freqRef,
                namer);
    } else
      t =
          ZephyrUtil.readTNTTreeFile(
              this,
              treeList,
              taxa,
              treeFilePath,
              "TNTTree",
              1,
              readSuccess,
              false,
              harvestOnlyStrictConsensus,
              null,
              namer);
    success = t != null;
    if (success && bootstrapOrJackknife() && resamplingAllConsensusTrees) {
      t = t.cloneTree();
      treeList.removeElementAt(0, false); // get rid of first one as this is the bootstrap tree
    }

    MesquiteThread.setCurrentCommandRecord(oldCR);
    success = readSuccess.getValue();
    if (!success) {
      logln("Execution of TNT unsuccessful [2]");
      if (!beanWritten) postBean("unsuccessful [2]", false);
      beanWritten = true;
    } else {
      if (!beanWritten) postBean("successful", false);
      beanWritten = true;
    }

    desuppressProjectPanelReset();
    if (data != null) data.decrementEditInhibition();
    //	manager.deleteElement(tv);  // get rid of temporary tree block
    externalProcRunner.finalCleanup();
    if (success) return t;
    return null;
  }