/** * FOR TESTING ONLY Add a single split to the hash table * * @param partition BitSet split to add */ public void addTestSplit(BitSet partition) { long tableKey2 = 0; long bucketKey2 = 0; // always calculate the split directly for (int k = 0; k < noOfTaxa; k++) { if (partition.get(k) == true) { tableKey2 += hashUtils.a1[k]; bucketKey2 += hashUtils.a2[k]; } } hashTable.put( partition, 1, (int) (tableKey2 % hashUtils.m1), (int) (bucketKey2 % hashUtils.m2), interestThreshold, partitions); }
/** * Create partitions from an input tree - recursive so will be called by many nodes, beginning * with root but with calculations actually beginning on leaves. * * @param node Node in tree with above split to add to the hash table */ private BitSet createPartitions(TreeNode node) { if (node.isLeaf()) { // Leaf node. int index = taxa.get(node.name); // leaf simply has it's keys stored in the hash utilities node.addProperty("tableHashKey", hashUtils.a1[index]); node.addProperty("bucketHashKey", hashUtils.a2[index]); // Updates the edge length array. leafEdgeLengths[index] += node.edgeLength; // Create a new partition from scratch to represent it BitSet partition = new BitSet(noOfTaxa); partition.set(index); assert partition.cardinality() == 1 : "There should be exactly a single bit set."; return partition; } else { // An internal node: Traverses the tree in post order. BitSet partition = new BitSet(noOfTaxa); // Get the node's partition representation from its children List<TreeNode> children = node.children; for (TreeNode child : children) { partition.or(createPartitions(child)); } // if this node is NOT to the right side of the root then add it... (Avoid adding splits twice // for CNetworks) if (node.parent != root || root.getRight() != node) { noOfPartitions++; long tableKey = 0; long bucketKey = 0; long tableKey2 = 0; long bucketKey2 = 0; // Calculate the hash keys for this partition for (TreeNode child : children) { tableKey += child.getIntProperty("tableHashKey"); bucketKey += child.getIntProperty("bucketHashKey"); } // if first is one then we need to store the flipped version so we store each split in one // representation only. if (partition.get(0) == true) { // copy to a new partition that is the flipped version BitSet partitionF = new BitSet(noOfTaxa); for (int l = 0; l < noOfTaxa; l++) { if (partition.get(l) == false) partitionF.set(l); } // calculate the hash keys for the flipped partition... for (int k = 0; k < noOfTaxa; k++) { if (partitionF.get(k) == true) { tableKey2 += hashUtils.a1[k]; bucketKey2 += hashUtils.a2[k]; } } // store the properties in the node node.addProperty("tableHashKey", (int) (tableKey2 % hashUtils.m1)); node.addProperty("bucketHashKey", (int) (bucketKey2 % hashUtils.m2)); if (noOfPartitions < noOfTaxa - 2) { // Avoids the addition of the star partition hashTable.put( partitionF, node.edgeLength, node.getIntProperty("tableHashKey"), node.getIntProperty("bucketHashKey"), interestThreshold, partitions); } // remember to still return the original partition with its appropriate keys... node.addProperty("tableHashKey", (int) (tableKey % hashUtils.m1)); node.addProperty("bucketHashKey", (int) (bucketKey % hashUtils.m2)); return partition; } // if first is zero then simply add the partition, recursively calculating the hash else { node.addProperty("tableHashKey", (int) (tableKey % hashUtils.m1)); node.addProperty("bucketHashKey", (int) (bucketKey % hashUtils.m2)); if (noOfPartitions < noOfTaxa - 2) { // Avoids the addition of the star partition hashTable.put( partition, node.edgeLength, node.getIntProperty("tableHashKey"), node.getIntProperty("bucketHashKey"), interestThreshold, partitions); } return partition; } } // still return the partition even if node was not added as was right of root... return partition; } }