import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantLock; import dr.app.tools.NexusExporter; import dr.evolution.io.NewickImporter; import dr.evolution.tree.FlexibleNode; import dr.evolution.tree.FlexibleTree; import dr.evolution.tree.Tree; import dr.evolution.util.Taxon; public class TIPars{ private String OUTPUT_FOLDER; private static boolean isMultiplePlacements = true; ///is output multiple placements private static boolean isFastaFile = true; ///is fasta file private boolean DEBUG = false; ///for debug private boolean OUTPUT_PNODE = false; ///is output P node sequence private Tree mytree = null; private static String internalnode_nidname = "label"; private static HashMap node2edge = new HashMap (); private static String[] placements = null; private static int edge_number = 1; private static ArrayList stringSequencesList = new ArrayList(); ///fasta: store taxaseq and ancseq, ordered follow the seqIdxMap private static HashMap seqIdxMap = new HashMap (); ///sequence names (taxaseq and ancseq) map to their reading orders from file private static int sequence_character_length = -1; ///alignment length private static HashMap node2seqName = new HashMap (); ///tree_nodes map to their sequences name private static ArrayList > multationSequencesMap = new ArrayList>(); ///vcf: store taxaseq and ancseq, ordered follow the seqIdxMap private static byte[] ref_sequence = new byte[100000]; ///reference sequence string private double minGlobalMemoryBranchScore = Double.MAX_VALUE; private ArrayList minGlobalMemoryBranchScoreNodeList = new ArrayList(); public static char[] alphabet_nt = {'A', 'C', 'G', 'T', 'R', 'Y', 'M', 'K', 'S', 'W', 'H', 'B', 'V', 'D', 'N', '-'}; ///IUPAC nucleotide codes public static char[] alphabet_aa = {'A', 'R', 'N', 'D', 'C', 'Q', 'E', 'G', 'H', 'I', 'L', 'K', 'M', 'F', 'P', 'S', 'T', 'W', 'Y', 'V', 'B', 'Z', 'X', '-'}; ///IUPAC nucleotide codes public static HashMap> _nucleotide_nomenclature = null; private static double[][] _nucleotide_nomenclature_scoreTable = null; private static HashMap _nucleotide_nomenclature_map2char = null; private static double[][] _aminoacid_scoreTable = null; private static double[][] _used_scoreTable = null; private ReentrantLock lock = new ReentrantLock(); public static double MinDoubleNumLimit = 10 * Double.MIN_VALUE; public TIPars(){ } // initialization public TIPars(Tree mytree, String otype, String output_folder){ this.mytree = mytree; this.OUTPUT_FOLDER = output_folder; setupHashtableOfnode2seqName(); setupHashtableOfNode2edge(otype); } private void setupHashtableOfNode2edge(String otype) { node2edge.clear(); edge_number = 1; if (otype.equals("placement")) { for (int i=0; i setupHashtableOfseqName2node(Tree tree){ HashMap mySeqName2node = new HashMap (); for(int i=0; i nodeQseq, String qid, String pid, boolean printDisInfoOnScreen, double[] ABQ_brlen, String otype, int ii){ return addQuerySequence_global(qname, nodeQseq, qid, pid, printDisInfoOnScreen, ABQ_brlen, otype, ii); } public Tree addQuerySequence(String qname, String nodeQseq, String qid, String pid, boolean printDisInfoOnScreen, double[] ABQ_brlen, String otype, int ii){ return addQuerySequence_global(qname, nodeQseq, qid, pid, printDisInfoOnScreen, ABQ_brlen, otype, ii); } // Travel all internal nodes for all possible nodeA-nodeB pairs //for vcf file public Tree addQuerySequence_global(String qname, ConcurrentHashMap nodeQseq, String qid, String pid, boolean printDisInfoOnScreen, double[] ABQ_brlen, String otype, int ii){ minGlobalMemoryBranchScore = Double.MAX_VALUE; minGlobalMemoryBranchScoreNodeList.clear(); ///if parallel computes branchscore is bigger than minGlobalMemoryBranchScore, the calculation will stop. ArrayList nodeIdxAndScoreList = new ArrayList(mytree.getNodeCount()); ////initialize the nodeIdxAndScoreList to store nodeIdx for(int i=0; i { double score = computeBranchScore(nodeIdx, nodeQseq, qname); } ); ArrayList selectedNodeList = minGlobalMemoryBranchScoreNodeList; ////try to remove ambiguous results selectedNodeList = reduceAmbiguousBranch(selectedNodeList, isMultiplePlacements); if(DEBUG) System.out.println("minQScore: " + minGlobalMemoryBranchScore + ", selectedNodeList:" + selectedNodeList.size()); MyFlexibleTree best_mynewTree = null; String placementStrings = ""; ///the first element of selectedNodeList is the best node to be inserted for(int k=0; k < selectedNodeList.size(); ++k) { ///get sequences FlexibleNode selectedNode = selectedNodeList.get(k); int selectedNodeBIndex = selectedNode.getNumber(); ConcurrentHashMap nodeAseq = getVariantSequenceByNode((FlexibleNode)selectedNode.getParent()); ConcurrentHashMap nodeBseq = getVariantSequenceByNode(selectedNode); Double[] selectedScores = new Double[3]; selectedScores[0] = (double) get_num_leaves(selectedNode.getParent()); selectedScores[1] = (double) get_num_leaves(selectedNode); ConcurrentHashMap nodePseq = getStringAndScoreFromNodeABQSeq(nodeAseq, nodeBseq, nodeQseq, selectedScores); String selectedBnid = (String)selectedNode.getAttribute(internalnode_nidname); if (selectedBnid == null) { selectedBnid = selectedNode.getTaxon().getId(); } String selectAName = (String)selectedNode.getParent().getAttribute(internalnode_nidname); // Q-P pendent length local estimation double pqlen = 0.0; if(selectedScores[2] <= MinDoubleNumLimit) pqlen = 0.0; else ///selectedScores[2] > Double.MIN_VALUE { double scoreAB = computeNodeScore(nodeAseq, nodeBseq); FlexibleNode myNodeB = selectedNode; FlexibleNode myNodeA = myNodeB.getParent(); ///iteratively consider upper branch of A’s parent to A for scaling if selectedScores[2] > Double.MIN_VALUE and scoreAB <= MinDoubleNumLimit. while((scoreAB <= MinDoubleNumLimit || myNodeB.getLength() <= MinDoubleNumLimit) && !myNodeA.isRoot()) { myNodeB = myNodeA; myNodeA = myNodeB.getParent(); scoreAB = computeNodeScore(getVariantSequenceByNode(myNodeA), getVariantSequenceByNode(myNodeB)); } if(scoreAB > MinDoubleNumLimit && myNodeB.getLength() > MinDoubleNumLimit) pqlen = localEstimation(selectedScores[2], scoreAB, myNodeB.getLength()); else { double p = selectedScores[2]/((double)getAlignmentLength()); pqlen = JC69(p); } } double original_branchAB = selectedNode.getLength(); if(selectedScores[1] <= MinDoubleNumLimit){ ABQ_brlen[0] = original_branchAB; ABQ_brlen[1] = 0.0; ABQ_brlen[2] = pqlen; } else if(selectedScores[0] <= MinDoubleNumLimit) { ABQ_brlen[0] = 0.0; ABQ_brlen[1] = original_branchAB; ABQ_brlen[2] = pqlen; } else { double Pratio = selectedScores[0]/((double)(selectedScores[0]+selectedScores[1])); double newNodePLength = original_branchAB*Pratio; double newNodeBLength = original_branchAB*(1.0-Pratio); ABQ_brlen[0] = newNodePLength; ABQ_brlen[1] = newNodeBLength; ABQ_brlen[2] = pqlen; } if(printDisInfoOnScreen) { if(k == 0) //the best inserted branch System.out.println(qname + "\t" + "*" + selectAName + "-" + selectedBnid + "\t" + "ABQ_brlen: " + ABQ_brlen[0] + "\t" + ABQ_brlen[1] + "\t" + ABQ_brlen[2]); else System.out.println(qname + "\t" + selectAName + "-" + selectedBnid + "\t" + "ABQ_brlen: " + ABQ_brlen[0] + "\t" + ABQ_brlen[1] + "\t" + ABQ_brlen[2]); } ///for placement only if (otype.equals("placement")) { placementStrings += "[" + node2edge.get((FlexibleNode) mytree.getNode(selectedNodeBIndex)) + ", " + ABQ_brlen[0] + ", " + ABQ_brlen[2] + "]"; if(k < selectedNodeList.size()-1) placementStrings += ",\n\t"; else placementStrings += "\n\t"; } if(k > 0) continue; // real add the query node to the Tree copy. MyFlexibleTree mynewTree = new MyFlexibleTree(mytree, true); this.copyAttributeFromOneNodeToAnother((FlexibleNode)mytree.getRoot(), (FlexibleNode)mynewTree.getRoot()); mynewTree.beginTreeEdit(); FlexibleNode selected_nodeB = (FlexibleNode)mynewTree.getNode(selectedNodeBIndex); FlexibleNode selected_nodeA = selected_nodeB.getParent(); Taxon qtaxon = new Taxon(qname); FlexibleNode selected_nodeQ = new FlexibleNode(qtaxon); selected_nodeQ.setLength(pqlen); FlexibleNode selected_nodeP = new FlexibleNode(); // set the attributes of newly added node. selected_nodeP.setAttribute(internalnode_nidname, pid); selected_nodeQ.setAttribute(internalnode_nidname, qname); if(selectedScores[1] <= MinDoubleNumLimit){ // P-B is zero branch length, meaning that Q is inserted into B directly. if(selected_nodeB.isExternal()) { // If B is leaf, cannot add the Q directly there, must add P node. selected_nodeP.setLength(original_branchAB); selected_nodeP.addChild(selected_nodeQ); selected_nodeA.addChild(selected_nodeP); selected_nodeB.setLength(0.0); selected_nodeA.removeChild(selected_nodeB); selected_nodeP.addChild(selected_nodeB); } else { selected_nodeB.addChild(selected_nodeQ); } } else if(selectedScores[0] <= MinDoubleNumLimit){ // A-P is zero branch length, meaning that Q is inserted into A directly. selected_nodeP = selected_nodeA; selected_nodeA.addChild(selected_nodeQ); } else { selected_nodeP.setLength(ABQ_brlen[0]); selected_nodeB.setLength(ABQ_brlen[1]); selected_nodeP.addChild(selected_nodeQ); selected_nodeA.addChild(selected_nodeP); selected_nodeA.removeChild(selected_nodeB); selected_nodeP.addChild(selected_nodeB); } mynewTree.endTreeEdit(); //adding the query sequence for next insertion if(!seqIdxMap.containsKey(qname)) { seqIdxMap.put(qname, multationSequencesMap.size()); multationSequencesMap.add(nodeQseq); } if(!seqIdxMap.containsKey(pid)) { seqIdxMap.put(pid, multationSequencesMap.size()); multationSequencesMap.add(nodePseq); } //output the new added p node if (OUTPUT_PNODE) { writeMutation(pid, nodePseq, OUTPUT_FOLDER); } mynewTree.toAdoptNodes((FlexibleNode)mynewTree.getRoot()); best_mynewTree = mynewTree; } ///to generate jplace file format info string if (otype.equals("placement")) { String placeInfo = "\t{\"p\":[\n\t" + placementStrings + "],\n\t" + "\"n\":[\"" + qname + "\"]}"; placements[ii] = placeInfo; return mytree; } return best_mynewTree; } ///for fasta file public Tree addQuerySequence_global(String qname, String nodeQseq, String qid, String pid, boolean printDisInfoOnScreen, double[] ABQ_brlen, String otype, int ii){ // Travel all internal nodes for all possible nodeA-nodeB pairs minGlobalMemoryBranchScore = Double.MAX_VALUE; minGlobalMemoryBranchScoreNodeList.clear(); ///if parallel computes branchscore is bigger than minGlobalMemoryBranchScore, the calculation will stop. ArrayList nodeIdxAndScoreList = new ArrayList(mytree.getNodeCount()); ////initialize the nodeIdxAndScoreList to store nodeIdx for(int i=0; i { double score = computeBranchScore(nodeIdx, nodeQseq, qname); } ); ArrayList selectedNodeList = minGlobalMemoryBranchScoreNodeList; if(DEBUG) System.out.println("minQScore: " + minGlobalMemoryBranchScore + ", selectedNodeList:" + selectedNodeList.size()); ////try to remove ambiguous results selectedNodeList = reduceAmbiguousBranch(selectedNodeList, isMultiplePlacements); MyFlexibleTree best_mynewTree = null; String placementStrings = ""; for(int k=0; k < selectedNodeList.size(); ++k) { FlexibleNode selectedNode = selectedNodeList.get(k); int selectedNodeBIndex = selectedNode.getNumber(); String nodeAseq = getStringSequenceByNode((FlexibleNode)selectedNode.getParent()); String nodeBseq = getStringSequenceByNode(selectedNode); Double[] selectedScores = new Double[3]; selectedScores[0] = (double) get_num_leaves(selectedNode.getParent()); selectedScores[1] = (double) get_num_leaves(selectedNode); String nodePseq = getStringAndScoreFromNodeABQSeq(nodeAseq, nodeBseq, nodeQseq, selectedScores); String selectedBnid = (String)selectedNode.getAttribute(internalnode_nidname); if (selectedBnid == null) { selectedBnid = selectedNode.getTaxon().getId(); } String selectAName = (String)selectedNode.getParent().getAttribute(internalnode_nidname); // Q-P pendent length local estimation double pqlen = 0.0; if(selectedScores[2] <= MinDoubleNumLimit) pqlen = 0.0; else ///selectedScores[2] > Double.MIN_VALUE { double scoreAB = computeNodeScore(nodeAseq, nodeBseq); FlexibleNode myNodeB = selectedNode; FlexibleNode myNodeA = myNodeB.getParent(); while((scoreAB <= MinDoubleNumLimit || myNodeB.getLength() <= MinDoubleNumLimit) && !myNodeA.isRoot()) { myNodeB = myNodeA; myNodeA = myNodeB.getParent(); scoreAB = computeNodeScore(getStringSequenceByNode(myNodeA), getStringSequenceByNode(myNodeB)); } if(scoreAB > MinDoubleNumLimit && myNodeB.getLength() > MinDoubleNumLimit) pqlen = localEstimation(selectedScores[2], scoreAB, myNodeB.getLength()); else { double p = selectedScores[2]/((double)getAlignmentLength()); pqlen = JC69(p); } } double original_branchAB = selectedNode.getLength(); if(selectedScores[1] <= MinDoubleNumLimit){ ABQ_brlen[0] = original_branchAB; ABQ_brlen[1] = 0.0; ABQ_brlen[2] = pqlen; } else if(selectedScores[0] <= MinDoubleNumLimit) { ABQ_brlen[0] = 0.0; ABQ_brlen[1] = original_branchAB; ABQ_brlen[2] = pqlen; } else { double Pratio = selectedScores[0]/((double)(selectedScores[0]+selectedScores[1])); double newNodePLength = original_branchAB*Pratio; double newNodeBLength = original_branchAB*(1.0-Pratio); ABQ_brlen[0] = newNodePLength; ABQ_brlen[1] = newNodeBLength; ABQ_brlen[2] = pqlen; } if(printDisInfoOnScreen) { if(k == 0) System.out.println(qname + "\t" + "*" + selectAName + "-" + selectedBnid + "\t" + "ABQ_brlen: " + ABQ_brlen[0] + "\t" + ABQ_brlen[1] + "\t" + ABQ_brlen[2]); else System.out.println(qname + "\t" + selectAName + "-" + selectedBnid + "\t" + "ABQ_brlen: " + ABQ_brlen[0] + "\t" + ABQ_brlen[1] + "\t" + ABQ_brlen[2]); } if (otype.equals("placement")) { placementStrings += "[" + node2edge.get((FlexibleNode) mytree.getNode(selectedNodeBIndex)) + ", " + ABQ_brlen[0] + ", " + ABQ_brlen[2] + "]"; if(k < selectedNodeList.size()-1) placementStrings += ",\n\t"; else placementStrings += "\n\t"; } if(k > 0) continue; // add the query node to the Tree copy. MyFlexibleTree mynewTree = new MyFlexibleTree(mytree, true); this.copyAttributeFromOneNodeToAnother((FlexibleNode)mytree.getRoot(), (FlexibleNode)mynewTree.getRoot()); mynewTree.beginTreeEdit(); FlexibleNode selected_nodeB = (FlexibleNode)mynewTree.getNode(selectedNodeBIndex); FlexibleNode selected_nodeA = selected_nodeB.getParent(); Taxon qtaxon = new Taxon(qname); FlexibleNode selected_nodeQ = new FlexibleNode(qtaxon); selected_nodeQ.setLength(pqlen); FlexibleNode selected_nodeP = new FlexibleNode(); // set the attributes of newly added node. selected_nodeP.setAttribute(this.internalnode_nidname, pid); selected_nodeQ.setAttribute(this.internalnode_nidname, qname); double original_scoreAB = computeNodeScore(nodeAseq, nodeBseq); if(selectedScores[1] <= MinDoubleNumLimit){ // P-B is zero branch length, meaning that Q is inserted into B directly. if(selected_nodeB.isExternal()) { // If B is leaf, cannot add the Q directly there, must add P node. selected_nodeP.setLength(original_branchAB); selected_nodeP.addChild(selected_nodeQ); selected_nodeA.addChild(selected_nodeP); selected_nodeB.setLength(0.0); selected_nodeA.removeChild(selected_nodeB); selected_nodeP.addChild(selected_nodeB); } else { selected_nodeB.addChild(selected_nodeQ); } } else if(selectedScores[0] <= MinDoubleNumLimit){ // A-P is zero branch length, meaning that Q is inserted into A directly. selected_nodeP = selected_nodeA; selected_nodeA.addChild(selected_nodeQ); } else { selected_nodeP.setLength(ABQ_brlen[0]); selected_nodeB.setLength(ABQ_brlen[1]); selected_nodeP.addChild(selected_nodeQ); selected_nodeA.addChild(selected_nodeP); selected_nodeA.removeChild(selected_nodeB); selected_nodeP.addChild(selected_nodeB); } mynewTree.endTreeEdit(); if(!seqIdxMap.containsKey(qname)) { seqIdxMap.put(qname, stringSequencesList.size()); stringSequencesList.add(nodeQseq); } if(!seqIdxMap.containsKey(pid)) { seqIdxMap.put(pid, stringSequencesList.size()); stringSequencesList.add(nodePseq); } if (OUTPUT_PNODE) { writeFASTA(pid, nodePseq, OUTPUT_FOLDER); } mynewTree.toAdoptNodes((FlexibleNode)mynewTree.getRoot()); best_mynewTree = mynewTree; } if (otype.equals("placement")) { String placeInfo = "\t{\"p\":[\n\t" + placementStrings + "],\n\t" + "\"n\":[\"" + qname + "\"]}"; placements[ii] = placeInfo; return mytree; } return best_mynewTree; } ///compute the branchscore that nodeQseq difference from both nodeA and nodeB ////for fasta file public double computeBranchScore(int nodeIdx, String nodeQseq, String qname) { FlexibleNode nodeB = (FlexibleNode)mytree.getNode(nodeIdx); return computeBranchScore(nodeB, nodeQseq, qname); } public double computeBranchScore(FlexibleNode nodeB, String nodeQseq, String qname) { // We use this annotation: // nodeA // | // nodeP // | \ // | \ // nodeB nodeQ if(nodeB.isRoot()) return Double.MAX_VALUE; // nodeA-nodeB pairs FlexibleNode nodeA = (FlexibleNode)nodeB.getParent(); if(nodeA == null) { System.out.println("nodeA is null, and its nodeB is " + node2seqName.get(nodeB)); } String nodeAseq = getStringSequenceByNode(nodeA); String nodeBseq = getStringSequenceByNode(nodeB); if(nodeAseq == null){ if(DEBUG) System.out.println("nodeAseq cannot find seq - " + node2seqName.get(nodeA)); } else if(nodeBseq == null){ if(DEBUG) System.out.println("nodeBseq cannot find seq - " + node2seqName.get(nodeB)); } double score = 0; for(int i=0; i < getAlignmentLength(); i++){ char a_i = nodeAseq.charAt(i); char b_i = nodeBseq.charAt(i); char c_i = nodeQseq.charAt(i); //get the substitution scores double score_ab = _used_scoreTable[(byte)a_i][(byte)b_i]; double score_ac = _used_scoreTable[(byte)a_i][(byte)c_i]; double score_bc = _used_scoreTable[(byte)b_i][(byte)c_i]; if(a_i != b_i && a_i != c_i && b_i != c_i){ // ATC score += (score_ac + score_bc) / 2; } else if(a_i == b_i && b_i != c_i){ // AAT score += score_bc; } ///stop when score larger than current minGlobalMemoryBranchScore if(score - minGlobalMemoryBranchScore > MinDoubleNumLimit) return score; } lock.lock(); if(minGlobalMemoryBranchScore - score > MinDoubleNumLimit) { minGlobalMemoryBranchScore = score; minGlobalMemoryBranchScoreNodeList.clear(); minGlobalMemoryBranchScoreNodeList.add(nodeB); } else if (Math.abs(minGlobalMemoryBranchScore - score) <= MinDoubleNumLimit) { minGlobalMemoryBranchScoreNodeList.add(nodeB); } lock.unlock(); return score; } public double computeBranchScore(String nodeAseq, String nodeBseq, String nodeQseq) { double score = 0; for(int i=0; i < getAlignmentLength(); i++){ char a_i = nodeAseq.charAt(i); char b_i = nodeBseq.charAt(i); char c_i = nodeQseq.charAt(i); double score_ab = _used_scoreTable[(byte)a_i][(byte)b_i]; double score_ac = _used_scoreTable[(byte)a_i][(byte)c_i]; double score_bc = _used_scoreTable[(byte)b_i][(byte)c_i]; if(a_i != b_i && a_i != c_i && b_i != c_i){ // ATC score += (score_ac + score_bc) / 2; } else if(a_i == b_i && b_i != c_i){ // AAT score += score_bc; } } return score; } ////compute the branch score and generate the P node string. public String getStringAndScoreFromNodeABQSeq(String aSeq, String bSeq, String cSeq, Double[] scores){ scores[0] = 0.0; scores[1] = 0.0; scores[2] = 0.0; StringBuilder pSeq = new StringBuilder(aSeq); //scores[3] is the difference between A and B for(int i = 0; i < getAlignmentLength(); i++){ char a_i = aSeq.charAt(i); char b_i = bSeq.charAt(i); char c_i = cSeq.charAt(i); double score_ac = _used_scoreTable[(byte)a_i][(byte)c_i]; double score_bc = _used_scoreTable[(byte)b_i][(byte)c_i]; double score_ab = _used_scoreTable[(byte)a_i][(byte)b_i]; if(a_i == b_i && a_i == c_i){ continue; // do nothing } else if(a_i != b_i && a_i != c_i && b_i != c_i){ // ATC scores[2] += (score_ac + score_bc) / 2.0; if(score_ac > score_bc) pSeq.setCharAt(i, b_i); } else if(a_i == b_i && b_i != c_i){ // AAT scores[2] += score_bc; pSeq.setCharAt(i, a_i); } else if(a_i != b_i && b_i == c_i){ // ATT scores[0] += score_ab; pSeq.setCharAt(i, b_i); } else if(a_i == c_i && b_i != c_i){ // TAT scores[1] += score_ab; pSeq.setCharAt(i, a_i); } else if(DEBUG){ System.out.println("Unmatched ABQ type"); } } return pSeq.toString(); } ////for vcf file public double computeBranchScore(int nodeIdx, ConcurrentHashMap nodeQseq, String qname) { FlexibleNode nodeB = (FlexibleNode)mytree.getNode(nodeIdx); return computeBranchScore(nodeB, nodeQseq, qname); } public double computeBranchScore(FlexibleNode nodeB, ConcurrentHashMap nodeQseq, String qname) { // We use this annotation: // nodeA // | // nodeP // | \ // | \ // nodeB nodeQ if(nodeB.isRoot()) return Double.MAX_VALUE; // nodeA-nodeB pairs FlexibleNode nodeA = (FlexibleNode)nodeB.getParent(); ConcurrentHashMap nodeAseq = getVariantSequenceByNode(nodeA); ConcurrentHashMap nodeBseq = getVariantSequenceByNode(nodeB); double score = 0; HashSet mergeIdxSet = new HashSet(nodeQseq.keySet()); mergeIdxSet.addAll(nodeAseq.keySet()); mergeIdxSet.addAll(nodeBseq.keySet()); for(Integer key : mergeIdxSet) { byte a = nodeAseq.containsKey(key) ? nodeAseq.get(key) : ref_sequence[key]; byte b = nodeBseq.containsKey(key) ? nodeBseq.get(key) : ref_sequence[key]; byte c = nodeQseq.containsKey(key) ? nodeQseq.get(key) : ref_sequence[key]; if(a != b && a != c && b != c){ // ATC score += (_used_scoreTable[a][c] + _used_scoreTable[b][c]) / 2; } else if(a == b && b != c){ // AAT score += _used_scoreTable[b][c]; } if(score - minGlobalMemoryBranchScore > MinDoubleNumLimit) return score; } lock.lock(); if(minGlobalMemoryBranchScore - score > MinDoubleNumLimit) { minGlobalMemoryBranchScore = score; minGlobalMemoryBranchScoreNodeList.clear(); minGlobalMemoryBranchScoreNodeList.add(nodeB); } else if (Math.abs(minGlobalMemoryBranchScore - score) <= MinDoubleNumLimit) { minGlobalMemoryBranchScoreNodeList.add(nodeB); } lock.unlock(); return score; } public double computeBranchScore(ConcurrentHashMap nodeAseq, ConcurrentHashMap nodeBseq, ConcurrentHashMap nodeQseq) { double score = 0; HashSet mergeIdxSet = new HashSet(nodeQseq.keySet()); mergeIdxSet.addAll(nodeAseq.keySet()); mergeIdxSet.addAll(nodeBseq.keySet()); for(Integer key : mergeIdxSet) { byte a = nodeAseq.containsKey(key) ? nodeAseq.get(key) : ref_sequence[key]; byte b = nodeBseq.containsKey(key) ? nodeBseq.get(key) : ref_sequence[key]; byte c = nodeQseq.containsKey(key) ? nodeQseq.get(key) : ref_sequence[key]; double score_ab = _used_scoreTable[a][b]; double score_ac = _used_scoreTable[a][c]; double score_bc = _used_scoreTable[b][c]; if(a != b && a != c && b != c){ // ATC score += (score_ac + score_bc) / 2; } else if(a == b && b != c){ // AAT score += score_bc; } } return score; } public ConcurrentHashMap getStringAndScoreFromNodeABQSeq(ConcurrentHashMap nodeAseq, ConcurrentHashMap nodeBseq, ConcurrentHashMap nodeQseq, Double[] scores){ scores[0] = 0.0; scores[1] = 0.0; scores[2] = 0.0; ConcurrentHashMap pSeq = new ConcurrentHashMap(); HashSet mergeIdxSet = new HashSet(nodeQseq.keySet()); mergeIdxSet.addAll(nodeAseq.keySet()); mergeIdxSet.addAll(nodeBseq.keySet()); for(Integer key : mergeIdxSet) { byte a = nodeAseq.containsKey(key) ? nodeAseq.get(key) : ref_sequence[key]; byte b = nodeBseq.containsKey(key) ? nodeBseq.get(key) : ref_sequence[key]; byte c = nodeQseq.containsKey(key) ? nodeQseq.get(key) : ref_sequence[key]; double score_ab = _used_scoreTable[(byte)a][(byte)b]; double score_ac = _used_scoreTable[(byte)a][(byte)c]; double score_bc = _used_scoreTable[(byte)b][(byte)c]; byte placeCharacter = a; ///default place a if(a == b && a == c) { continue; } else if(a != b && a != c && b != c){ // ATC scores[2] += (score_ac + score_bc) / 2.0; if(score_ac > score_bc) placeCharacter = b; } else if(a == b && b != c){ // AAT scores[2] += score_bc; } else if(a != b && b == c){ // ATT scores[0] += score_ab; placeCharacter = b; } else if(a == c && b != c){ // TAT scores[1] += score_ab; } if(placeCharacter != ref_sequence[key]) { pSeq.put(key, placeCharacter); } } return pSeq; } public double computeNodeScore(FlexibleNode nodeB, String nodeQseq) { if(nodeB.isRoot()) return Double.MAX_VALUE; String nodeBseq = getStringSequenceByNode(nodeB); double scoreNode = 0; for(int i= 0; i < getAlignmentLength(); i++){ char a_i = nodeBseq.charAt(i); char b_i = nodeQseq.charAt(i); scoreNode += _used_scoreTable[(byte)a_i][(byte)b_i]; } return scoreNode; } public double computeNodeScore(String nodeBseq, String nodeQseq) { double score = 0; for(int i= 0; i < getAlignmentLength(); i++){ char a_i = nodeBseq.charAt(i); char b_i = nodeQseq.charAt(i); score += _used_scoreTable[(byte)a_i][(byte)b_i]; } return score; } public double computeNodeScore(ConcurrentHashMap nodeBseq, ConcurrentHashMap nodeQseq) { double score = 0; HashSet mergeIdxSet = new HashSet(nodeQseq.keySet()); mergeIdxSet.addAll(nodeBseq.keySet()); for(Integer key : mergeIdxSet) { byte b = nodeBseq.containsKey(key) ? nodeBseq.get(key) : ref_sequence[key]; byte c = nodeQseq.containsKey(key) ? nodeQseq.get(key) : ref_sequence[key]; score += _used_scoreTable[b][c]; } return score; } ///filter rules for multiple placements public ArrayList reduceAmbiguousBranch(ArrayList selectedNodeList) { return reduceAmbiguousBranch(selectedNodeList, false); } @SuppressWarnings("unchecked") public ArrayList reduceAmbiguousBranch(ArrayList selectedNodeList, Boolean returnMulti) { if(selectedNodeList.size() < 2) return selectedNodeList; ArrayList finalSelectedNode = new ArrayList(); ///mapping slected nodes' parents to themselves HashMap> parentCluster = new HashMap>(); for(int i=0; i temp = new ArrayList(); temp.add(nodeB); parentCluster.put(nodeA, temp); } else { parentCluster.get(nodeA).add(nodeB); } } ///remove duplicate if potential placements are relationships of parent and child ArrayList parentCluste_keySet = new ArrayList(parentCluster.keySet()); ///post transversal order parentCluste_keySet.sort((d1,d2) -> (d2.getNumber()-d1.getNumber())); for(int k=0; k temp = parentCluster.get(nodeA); for(int i=0; i temp = parentCluster.get(nodeA); int maxChildrenB = 0; ArrayList selectIdxs = new ArrayList(); for(int i=0; i maxChildrenB) { maxChildrenB = temp.get(i).getChildCount(); selectIdxs.clear(); selectIdxs.add(i); } else if(temp.get(i).getChildCount() == maxChildrenB) { selectIdxs.add(i); } } if(selectIdxs.size() < 2) finalSelectedNode.add(temp.get(selectIdxs.get(0))); else { double minHeight = Double.MAX_VALUE; for(int i=0; i) finalSelectedNode.clone(); finalSelectedNode.clear(); ///return the best placement ArrayList bestBranch = reduceBestBranch(selectedNodeList, parentCluster); if(returnMulti) { finalSelectedNode.add(bestBranch.get(0)); //if multiple placements are allowed to print out, add all others for(int i=0; i reduceBestBranch(ArrayList selectedNodeList, HashMap> parentCluster) { if(selectedNodeList.size() < 2) return selectedNodeList; ArrayList finalSelectedNode = new ArrayList(); ////select best answer ammong multiple placements ///select the maximum children then minimum height branch length int maxChildren = 0; for(int i=0; i maxChildren) { maxChildren = total; finalSelectedNode.clear(); finalSelectedNode.add(nodeB); } else if(maxChildren == total) { finalSelectedNode.add(nodeB); } } if(finalSelectedNode.size() < 2) return finalSelectedNode; selectedNodeList = new ArrayList(finalSelectedNode); finalSelectedNode.clear(); double minHeight = Double.MAX_VALUE; for(int i=0; i MinDoubleNumLimit) { minHeight = total; finalSelectedNode.clear(); finalSelectedNode.add(nodeB); } else if(Math.abs(minHeight - total) <= MinDoubleNumLimit) { finalSelectedNode.add(nodeB); } } if(finalSelectedNode.size() > 1) { int randomIdx = (int) (Math.random() * finalSelectedNode.size()); selectedNodeList = (ArrayList) finalSelectedNode.clone(); finalSelectedNode.clear(); finalSelectedNode.add(selectedNodeList.get(randomIdx)); //random select } return finalSelectedNode; } public int get_num_leaves(FlexibleNode node) { if(!node.hasChildren()) return 1; int num_leaves = 0; for(int i=0; i bAncestors = new HashMap(); FlexibleNode parent = b; double dist = 0.0; bAncestors.put(b, dist); while(parent != null && !parent.isRoot()) { dist = dist + parent.getLength(); bAncestors.put(parent.getParent(), dist); parent = parent.getParent(); } parent = a; dist = 0.0; while(!bAncestors.containsKey(parent) && !tree.isRoot(parent)) { dist = dist + parent.getLength(); parent = parent.getParent(); } nodeAndBranch.a = parent; nodeAndBranch.b = dist; if(bAncestors.containsKey(parent)) nodeAndBranch.b += bAncestors.get(parent); return nodeAndBranch; } } //remove single taxon public static FlexibleNodeBranch removeTaxon(FlexibleTree tree, FlexibleNode node) { try{ MyFlexibleTree t = new TIPars().new MyFlexibleTree(tree, true); copyAttributeFromOneNodeToAnother((FlexibleNode)tree.getRoot(), (FlexibleNode) t.getRoot()); t.beginTreeEdit(); FlexibleNode n = (FlexibleNode) t.getNode(node.getNumber()); FlexibleNode p = n.getParent(); FlexibleNode pReturn = (FlexibleNode)tree.getNode(p.getNumber()); FlexibleNode aReturn = (FlexibleNode)(pReturn.getParent()); double true_dist1 = p.getLength() + n.getLength(); double true_dist2 = n.getLength(); p.removeChild(n); n.setParent(null); if(p.getChildCount() == 1){ // Remove this p node if if has less than 2 child nodes if(!p.isRoot()) { FlexibleNode b = (FlexibleNode)(p.getChild(0)); FlexibleNode a = (FlexibleNode)(p.getParent()); a.addChild(b); a.removeChild(p); b.setParent(a); double oldb2p = b.getLength(); b.setLength(b.getLength()+p.getLength()); p.setParent(null); t.endTreeEdit(); FlexibleNodeBranch result = new TIPars().new FlexibleNodeBranch(aReturn, true_dist1); result.tree = t; t.toAdoptNodes((FlexibleNode)t.getRoot()); return result; } else { FlexibleNode b = (FlexibleNode)(p.getChild(0)); for(int i=0; i nodes) { try{ MyFlexibleTree t = new TIPars().new MyFlexibleTree(tree, true); copyAttributeFromOneNodeToAnother((FlexibleNode)tree.getRoot(), (FlexibleNode) t.getRoot()); ArrayList removeNodes = new ArrayList(); for(int i=0; i(); t.beginTreeEdit(); for(FlexibleNode node : removeNodes) { FlexibleNode n = node; //(FlexibleNode) t.getNode(node.getNumber()); FlexibleNode p = n.getParent(); System.out.println(p.getNumber()); FlexibleNode pReturn = (FlexibleNode)tree.getNode(p.getNumber()); String pName = (String)p.getAttribute(internalnode_nidname); String pReturnName = (String)pReturn.getAttribute(internalnode_nidname); if(!pName.equals(pReturnName)) { System.out.println("removeTaxon: "+pName+"|"+pReturnName); return null; } FlexibleNode aReturn = (FlexibleNode)(pReturn.getParent()); double true_dist1 = p.getLength() + n.getLength(); double true_dist2 = n.getLength(); p.removeChild(n); n.setParent(null); if(p.getChildCount() == 1){ // Remove this p node if if has less than 2 child nodes FlexibleNode b = (FlexibleNode)(p.getChild(0)); FlexibleNode a = (FlexibleNode)(p.getParent()); a.addChild(b); b.setParent(a); double oldb2p = b.getLength(); b.setLength(b.getLength()+p.getLength()); a.removeChild(p); p.setParent(null); FlexibleNodeBranch result = new TIPars().new FlexibleNodeBranch(aReturn, true_dist1); result.tree = null; flexibleNodeBranchList.nodeBranchList.add(result); } else{ FlexibleNodeBranch result = new TIPars().new FlexibleNodeBranch(pReturn, true_dist2); result.tree = null; flexibleNodeBranchList.nodeBranchList.add(result); } } t.endTreeEdit(); t.toAdoptNodes((FlexibleNode)t.getRoot()); flexibleNodeBranchList.tree = t; return flexibleNodeBranchList; } catch(Exception e){ e.printStackTrace(); return null; } } //remove a list of taxa and return a resulting tree public static MyFlexibleTree removeTaxonReturnTree(FlexibleTree tree, ArrayList nodes) { try{ MyFlexibleTree t = new TIPars().new MyFlexibleTree(tree, true); copyAttributeFromOneNodeToAnother((FlexibleNode)tree.getRoot(), (FlexibleNode) t.getRoot()); ArrayList removeNodes = new ArrayList(); for(int i=0; i(); t.beginTreeEdit(); for(FlexibleNode n : removeNodes) { if(n.isRoot()) { System.out.println(n.getTaxon().getId() + " is root"); if(n.getParent() != null) System.out.println("root but not null"); return null; } FlexibleNode p = n.getParent(); if(p == null) { System.out.println(n.getTaxon().getId() + " no parent"); return null; } if(p.getChildCount() > 2) { p.removeChild(n); } else if(p.getChildCount() == 2) { for(int j=0; j<2; ++j) { if(!p.getChild(j).equals(n)) { if(p.isRoot()) { System.out.println(n.getTaxon().getId() + "'s parent is root and has only two children"); return null; } FlexibleNode a = (FlexibleNode)(p.getParent()); FlexibleNode b = (FlexibleNode)(p.getChild(j)); double newbl = b.getLength() + p.getLength(); b.setLength(newbl); a.addChild(b); a.removeChild(p); } } } else { System.out.println(n.getTaxon().getId() + " has no sister"); return null; } } t.endTreeEdit(); t.toAdoptNodes((FlexibleNode)t.getRoot()); return t; } catch(Exception e){ e.printStackTrace(); return null; } } //copy a node private static void copyAttributeFromOneNodeToAnother(FlexibleNode n, FlexibleNode m){ Iterator attnames = n.getAttributeNames(); while(attnames != null && attnames.hasNext()){ String ahname = (String)attnames.next(); m.setAttribute(ahname, n.getAttribute(ahname)); } } //get string sequence private static String getStringSequenceByNode(FlexibleNode a){ if(node2seqName.containsKey(a)) { if(!seqIdxMap.containsKey((node2seqName.get(a)))) { System.out.println("seqIdxMap can not access " + (node2seqName.get(a))); } String seq = stringSequencesList.get(seqIdxMap.get((node2seqName.get(a)))); return seq; } else { String selectedBnid = (String)a.getAttribute(internalnode_nidname); if (selectedBnid == null) { selectedBnid = a.getTaxon().getId(); } System.out.println("node2seqName can not access " + a.getNumber() + "/" + selectedBnid); System.exit(-1); return null; } } //get variants sequence private static ConcurrentHashMap getVariantSequenceByNode(FlexibleNode a){ ConcurrentHashMap seq = multationSequencesMap.get(seqIdxMap.get((node2seqName.get(a)))); return seq; } public class FlexibleNodeBranch { public FlexibleNode a; public Double b; public Tree tree; public String nodeAName; public FlexibleNodeBranch(FlexibleNode a, Double b) { this.a = a; this.b = b; } public FlexibleNodeBranch() { this.a = null; this.b = null; } public void setNode(FlexibleNode a2){ this.a = a2; } public void setBrlen(Double b2){ this.b = b2; } public FlexibleNode getNode(){ return this.a; } public Double getBrlen(){ return this.b; } } public static int getAlignmentLength(){ return sequence_character_length; } //read fasta file to a hashmap public static HashMap readFastaFile2Alignment(String fn){ HashMap alignmnetIdxList = new HashMap(); int startIndex = stringSequencesList.size(); try{ BufferedReader br2 = new BufferedReader(new InputStreamReader(new FileInputStream(fn))); String fasline = br2.readLine().trim(); String desc; while(fasline != null){ StringBuffer sequence = new StringBuffer(); if(fasline.matches("^>.+")){ desc = fasline; fasline = br2.readLine().trim(); while(fasline != null && !fasline.matches("^>.+")) { sequence.append(fasline); fasline = br2.readLine(); } desc = desc.replaceAll(">", ""); String seqseq = sequence.toString(); seqIdxMap.put(desc, startIndex); stringSequencesList.add(seqseq.toUpperCase()); alignmnetIdxList.put(startIndex, desc); startIndex++; } } } catch(Exception e){ e.printStackTrace(); } System.gc(); return alignmnetIdxList; } //read fasta file public static void readFastaAlignmentFile(String fn){ int startIndex = stringSequencesList.size(); try{ BufferedReader br2 = new BufferedReader(new InputStreamReader(new FileInputStream(fn))); String fasline = br2.readLine().trim(); String desc; while(fasline != null){ StringBuffer sequence = new StringBuffer(); if(fasline.matches("^>.+")){ desc = fasline; fasline = br2.readLine().trim(); while(fasline != null && !fasline.matches("^>.+")) { sequence.append(fasline); fasline = br2.readLine(); } desc = desc.replaceAll(">", ""); String seqseq = sequence.toString(); if(sequence_character_length < 0) sequence_character_length = seqseq.length(); seqIdxMap.put(desc, startIndex++); stringSequencesList.add(seqseq.toUpperCase()); } } } catch(Exception e){ e.printStackTrace(); } System.gc(); } //read vcf file public static void readVCFAlignmentFile(String fn){ int startIndex = multationSequencesMap.size(); boolean header_found = false; try{ BufferedReader br2 = new BufferedReader(new InputStreamReader(new FileInputStream(fn))); ////read header while(!header_found){ String vcfline = br2.readLine().trim(); if(vcfline == null || vcfline.isEmpty()) continue; String[] words = vcfline.trim().split("\\s+"); if(words.length > 2) { if(words[1].contains("POS")) { // Sample names start from the 10th word in the header for (int j=9; j < words.length; j++) { seqIdxMap.put(words[j], startIndex + j - 9); multationSequencesMap.add(new ConcurrentHashMap()); } header_found = true; } } } if(!header_found) { System.out.println("Error! Incorrect VCF file. No Header"); System.exit(-1); } int numberofThreads = Runtime.getRuntime().availableProcessors(); //System.out.println("numberofThreads = " + numberofThreads); ArrayList nodeIdxList = new ArrayList(numberofThreads); for(int i=0; i { String vcfline = null; try { while((vcfline = br2.readLine()) != null){ if(vcfline.isEmpty()) continue; String[] words = vcfline.trim().split("\\s+"); if (words.length != 9 + multationSequencesMap.size() - startIndex) { System.out.println("Error! Incorrect VCF file."); System.exit(-1); } int variant_pos = Integer.parseInt(words[1]); byte ref_nuc = (byte)words[3].charAt(0); if(ref_sequence[variant_pos] == (byte)'\0') { ref_sequence[variant_pos] = ref_nuc; } else if(ref_nuc != ref_sequence[variant_pos]) { System.out.println("Error! Different referen sequence."); System.exit(-1); } String[] alleles = words[4].split(","); for (int j=9; j < words.length; j++) { if (Character.isDigit(words[j].charAt(0))) { int allele_id = Integer.parseInt(words[j]); if (allele_id > 0) { byte allele = (byte)alleles[allele_id-1].charAt(0); multationSequencesMap.get(startIndex + j - 9).put(variant_pos, allele); } } } } } catch (NumberFormatException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } ); br2.close(); for(int i=0; i readVCFFile2Alignment(String fn){ HashMap alignmnetIdxList = new HashMap(); int startIndex = multationSequencesMap.size(); boolean header_found = false; try{ BufferedReader br2 = new BufferedReader(new InputStreamReader(new FileInputStream(fn))); ////read header while(!header_found){ String vcfline = br2.readLine().trim(); if(vcfline == null || vcfline.isEmpty()) continue; String[] words = vcfline.trim().split("\\s+"); if(words.length > 2) { if(words[1].contains("POS")) { // Sample names start from the 10th word in the header for (int j=9; j < words.length; j++) { seqIdxMap.put(words[j], startIndex + j - 9); multationSequencesMap.add(new ConcurrentHashMap()); alignmnetIdxList.put(startIndex + j - 9, words[j]); } header_found = true; } } } if(!header_found) { System.out.println("Error! Incorrect VCF file. No Header"); System.exit(-1); } int numberofThreads = Runtime.getRuntime().availableProcessors(); ArrayList nodeIdxList = new ArrayList(numberofThreads); for(int i=0; i { String vcfline = null; try { while((vcfline = br2.readLine()) != null){ if(vcfline == null) break; if(vcfline.isEmpty()) continue; String[] words = vcfline.trim().split("\\s+"); if(words.length > 1) { if (words.length != 9 + multationSequencesMap.size() - startIndex) { System.out.println("Error! Incorrect VCF file."); System.exit(-1); } int variant_pos = Integer.parseInt(words[1]); byte ref_nuc = (byte)words[3].charAt(0); if(ref_sequence[variant_pos] == (byte)'\0') { ref_sequence[variant_pos] = ref_nuc; } else if(ref_nuc != ref_sequence[variant_pos]) { System.out.println("Error! Different referen sequence."); System.exit(-1); } String[] alleles = words[4].split(","); for (int j=9; j < words.length; j++) { if (Character.isDigit(words[j].charAt(0))) { int allele_id = Integer.parseInt(words[j]); if (allele_id > 0) { byte allele = (byte)alleles[allele_id-1].charAt(0); multationSequencesMap.get(startIndex + j - 9).put(variant_pos, allele); } } } } } } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } ); br2.close(); for(int i=0; i"); buffer.append(desc); buffer.append("\n"); buffer.append(seq); try{ PrintStream out = new PrintStream(new FileOutputStream(new File(output))); out.println(buffer.toString()); out.close(); } catch(Exception e) { e.printStackTrace(); } } public static void writeFASTAwithFullPath(String desc, String seq, String output_folder) { String output = output_folder; StringBuilder buffer = new StringBuilder(); buffer.append(">"); buffer.append(desc); buffer.append("\n"); buffer.append(seq); try{ PrintStream out = new PrintStream(new FileOutputStream(new File(output))); out.println(buffer.toString()); out.close(); } catch(Exception e) { e.printStackTrace(); } } public static void writeFASTA(ArrayList desc, ArrayList seq, String output_folder) { String output = output_folder; StringBuilder buffer = new StringBuilder(); for(int i=0; i"); buffer.append(desc.get(i)); buffer.append("\n"); buffer.append(seq.get(i)); buffer.append("\n"); } try{ PrintStream out = new PrintStream(new FileOutputStream(new File(output))); out.print(buffer.toString()); out.close(); } catch(Exception e) { e.printStackTrace(); } } public static void writeFASTA(String[] desc, String[] seq, String output_folder) { String output = output_folder; StringBuilder buffer = new StringBuilder(); for(int i=0; i"); buffer.append(desc[i]); buffer.append("\n"); buffer.append(seq[i]); buffer.append("\n"); } try{ PrintStream out = new PrintStream(new FileOutputStream(new File(output))); out.print(buffer.toString()); out.close(); } catch(Exception e) { e.printStackTrace(); } } //write variants public static void writeMutation(String desc, ConcurrentHashMap seqMutaion, String output_folder) { String output = output_folder + desc + ".fas"; StringBuilder buffer = new StringBuilder(); buffer.append(desc); buffer.append("\n"); for (ConcurrentHashMap.Entry < Integer, Byte > entry: seqMutaion.entrySet()) { System.out.println(entry.getKey()); System.out.println(entry.getValue()); buffer.append(ref_sequence[entry.getKey()] + "|" + entry.getKey() + "|" + entry.getValue() + "\n"); } try{ PrintStream out = new PrintStream(new FileOutputStream(new File(output))); out.println(buffer.toString()); out.close(); } catch(Exception e) { e.printStackTrace(); } } public class FlexibleNodeBranchList { public ArrayList nodeBranchList = new ArrayList(); public Tree tree; } public static boolean isNumeric(String str) { for (int i = 0; i < str.length(); i++) { //System.out.println(str.charAt(i)); if (!Character.isDigit(str.charAt(i))) { return false; } } return true; } //generate IUPAC nucleotide codes substitution table public static double[][] generate_nucleotide_nomenclature_scoreTable() { int size = 0; for(int i=0; i size) size = (byte)alphabet_nt[i]; size = size + 1; double[][] NodeScoreBigTable = new double[size][size]; for(int i=0; i generate_nucleotide_nomenclature_characterTable() { HashMap nucleotide_nomenclature_map2char = new HashMap(); Byte[] nucleotide_nomenclature_array = {'A', 'C', 'G', 'T', 'R', 'Y', 'M', 'K', 'S', 'W', 'H', 'B', 'V', 'D', 'N'}; for(int i=0; i> generate_nucleotide_nomenclature() { HashMap> nucleotide_nomenclature = new HashMap>(); //A HashSet tempA = new HashSet(); tempA.add((byte) 'A'); nucleotide_nomenclature.put((byte) 'A',tempA); //C HashSet tempC = new HashSet(); tempC.add((byte) 'C'); nucleotide_nomenclature.put((byte) 'C',tempC); //G HashSet tempG = new HashSet(); tempG.add((byte) 'G'); nucleotide_nomenclature.put((byte) 'G',tempG); //T HashSet tempT = new HashSet(); tempT.add((byte) 'T'); nucleotide_nomenclature.put((byte) 'T',tempT); //R HashSet tempR = new HashSet(); tempR.add((byte) 'A'); tempR.add((byte) 'G'); nucleotide_nomenclature.put((byte) 'R',tempR); //R HashSet tempY = new HashSet(); tempY.add((byte) 'C'); tempY.add((byte) 'T'); nucleotide_nomenclature.put((byte) 'Y',tempY); //M HashSet tempM = new HashSet(); tempM.add((byte) 'A'); tempM.add((byte) 'C'); nucleotide_nomenclature.put((byte) 'M',tempM); //K HashSet tempK = new HashSet(); tempK.add((byte) 'G'); tempK.add((byte) 'T'); nucleotide_nomenclature.put((byte) 'K',tempK); //S HashSet tempS = new HashSet(); tempS.add((byte) 'C'); tempS.add((byte) 'G'); nucleotide_nomenclature.put((byte) 'S',tempS); //W HashSet tempW = new HashSet(); tempW.add((byte) 'A'); tempW.add((byte) 'T'); nucleotide_nomenclature.put((byte) 'W',tempW); //H HashSet tempH = new HashSet(); tempH.add((byte) 'A'); tempH.add((byte) 'C'); tempH.add((byte) 'T'); nucleotide_nomenclature.put((byte) 'H',tempH); //B HashSet tempB = new HashSet(); tempB.add((byte) 'C'); tempB.add((byte) 'G'); tempB.add((byte) 'T'); nucleotide_nomenclature.put((byte) 'B',tempB); //V HashSet tempV = new HashSet(); tempV.add((byte) 'A'); tempV.add((byte) 'C'); tempV.add((byte) 'G'); nucleotide_nomenclature.put((byte) 'V',tempV); //D HashSet tempD = new HashSet(); tempD.add((byte) 'A'); tempD.add((byte) 'G'); tempD.add((byte) 'T'); nucleotide_nomenclature.put((byte) 'D',tempD); //N HashSet tempN = new HashSet(); tempN.add((byte) 'A'); tempN.add((byte) 'C'); tempN.add((byte) 'G'); tempN.add((byte) 'T'); nucleotide_nomenclature.put((byte) 'N',tempN); return nucleotide_nomenclature; } //generate blosum62 substitution table public static double[][] generate_aminoacid_scoreTable() { int size = 0; for(int i=0; i size) size = (byte)alphabet_aa[i]; //change char to integer based on ascii code size = size + 1; double[][] NodeScoreBigTable = new double[size][size]; for(int i=0; i queryList = null; ///////read vcf file if(informat.contains("vcf") || informat.contains("Vcf") || informat.contains("VCF")) { multationSequencesMap.clear(); seqIdxMap.clear(); Arrays.fill(ref_sequence, (byte)'\0'); readVCFAlignmentFile(insfn); readVCFAlignmentFile(inafn); queryList = readVCFFile2Alignment(inqfn); } else { //// Read fasta file stringSequencesList.clear(); seqIdxMap.clear(); ///input msa readFastaAlignmentFile(insfn); ///input ancestral readFastaAlignmentFile(inafn); ///input query queryList = readFastaFile2Alignment(inqfn); } //read tree NewickImporter tni = new NewickImporter(new FileReader(intfn)); Tree tree = tni.importTree(null); //init TIPars TIPars myAdd = new TIPars(tree, otype, output_folder); Tree outtree = null; long startTime2 = System.currentTimeMillis(); if(!printDisInfoOnScreen) System.out.print("Progress: "); String progressInfo = ""; //mutiple taxa insertion for vcf input if (otype.equals("insertion") && informat.contains("vcf")) { ArrayList queryIdxs = new ArrayList(queryList.keySet()); queryIdxs.sort(Comparator.naturalOrder()); for (int i=0; i query = multationSequencesMap.get(idx); String qid = "q" + (i+1); String pid = "p" + (i+1); outtree = myAdd.addQuerySequence(name, query, qid, pid, printDisInfoOnScreen, new double[3], otype, 0); myAdd.mytree = outtree; myAdd.setupHashtableOfnode2seqName(); if(!printDisInfoOnScreen) { for (int j = 0; j < progressInfo.length(); j++) System.out.print("\b"); progressInfo = (i+1) + "/" + queryIdxs.size(); System.out.print(progressInfo); if(i == queryIdxs.size()-1) System.out.println(); } } } //mutiple taxa insertion for fasta input else if (otype.equals("insertion")) { ArrayList queryIdxs = new ArrayList(queryList.keySet()); queryIdxs.sort(Comparator.naturalOrder()); for (int i=0; i queryIdxs = new ArrayList(queryList.keySet()); queryIdxs.sort(Comparator.naturalOrder()); placements = new String[queryIdxs.size()]; for (int i=0; i query = multationSequencesMap.get(idx); String qid = "q" + (i+1); String pid = "p" + (i+1); outtree = myAdd.addQuerySequence(name, query, qid, pid, printDisInfoOnScreen, new double[3], otype, i); if(!printDisInfoOnScreen) { for (int j = 0; j < progressInfo.length(); j++) System.out.print("\b"); progressInfo = (i+1) + "/" + queryIdxs.size(); System.out.print(progressInfo); if(i == queryIdxs.size()-1) System.out.println(); } } } //mutiple taxa placement for fasta input else if(otype.equals("placement")){ ArrayList queryIdxs = new ArrayList(queryList.keySet()); queryIdxs.sort(Comparator.naturalOrder()); placements = new String[queryIdxs.size()]; for (int i=0; i