code: def calculateProbableRootOfGeneTree(speciesTree, geneTree, processID=lambda x : x):
      
      #get all rooted trees
      #run dup calc on each tree
      #return tree with fewest number of dups
      if geneTree.traversalID.midEnd <= 3:
          return (0, 0, geneTree)
      checkGeneTreeMatchesSpeciesTree(speciesTree, geneTree, processID)
      l = []
      def fn(tree):
          if tree.traversalID.mid != geneTree.left.traversalID.mid and tree.traversalID.mid != geneTree.right.traversalID.mid:
              newGeneTree = moveRoot(geneTree, tree.traversalID.mid)
              binaryTree_depthFirstNumbers(newGeneTree)
              dupCount, lossCount = calculateDupsAndLossesByReconcilingTrees(speciesTree, newGeneTree, processID)
              l.append((dupCount, lossCount, newGeneTree))
          if tree.internal:
              fn(tree.left)
              fn(tree.right)
      fn(geneTree)
      l.sort()
      return l[0][2], l[0][0], l[0][1]
docs: Goes through each root possible branch making it the root. 
      Returns tree that requires the minimum number of duplications.