Exemple #1
0
    def test_NexusComments(self):
        """Test the ability to parse nexus comments at internal and leaf nodes."""
        # A tree with simple comments throughout the tree.
        ts1b = "((12:0.13,19[&comment1]:0.13)[&comment2]:0.1,(20:0.171,11:0.171):0.13)[&comment3];"
        tree = Trees.Tree(ts1b)
        self.assertEqual(self._get_flat_nodes(tree),
                         [(None, 0.0, None, "[&comment3]"),
                          (None, 0.1, None, "[&comment2]"),
                          (None, 0.13, None, None), ("12", 0.13, None, None),
                          ("19", 0.13, None, "[&comment1]"),
                          ("20", 0.171, None, None),
                          ("11", 0.171, None, None)])

        # A tree with more complex comments throughout the tree.
        # This is typical of the MCC trees produced by `treeannotator` in the beast-mcmc suite of phylogenetic tools
        # The key difference being tested here is the ability to parse internal node comments that include ','.
        ts1b = "(((9[&rate_range={1.3E-5,0.10958320752991428},height_95%_HPD={0.309132419999969,0.3091324199999691},length_range={3.513906814545109E-4,0.4381986285528381},height_median=0.309132419999969,length_95%_HPD={0.003011577063374571,0.08041621647998398}]:0.055354097721950546,5[&rate_range={1.3E-5,0.10958320752991428},height_95%_HPD={0.309132419999969,0.3091324199999691},length_range={3.865051168833178E-5,0.4391594442572986},height_median=0.309132419999969,length_95%_HPD={0.003011577063374571,0.08041621647998398}]:0.055354097721950546)[&height_95%_HPD={0.3110921040545068,0.38690865205576275},length_range={0.09675588357303178,0.4332959544380489},length_95%_HPD={0.16680375169879613,0.36500804261814374}]:0.20039426358269385)[&height_95%_HPD={0.5289500597932948,0.6973881165460601},length_range={0.02586430194846201,0.29509451958008265},length_95%_HPD={0.0840287249314221,0.2411078625957056}]:0.23042678598484334)[&height_95%_HPD={0.7527502510685965,0.821862094763501},height_median=0.8014438411766163,height=0.795965080422763,posterior=1.0,height_range={0.49863013698599995,0.821862094763501},length=0.0];"
        tree = Trees.Tree(ts1b)
        self.assertEqual(self._get_flat_nodes(tree), [
            (None, 0.0, None,
             "[&height_95%_HPD={0.7527502510685965,0.821862094763501},height_median=0.8014438411766163,height=0.795965080422763,posterior=1.0,height_range={0.49863013698599995,0.821862094763501},length=0.0]"
             ),
            (None, 0.23042678598484334, None,
             "[&height_95%_HPD={0.5289500597932948,0.6973881165460601},length_range={0.02586430194846201,0.29509451958008265},length_95%_HPD={0.0840287249314221,0.2411078625957056}]"
             ),
            (None, 0.20039426358269385, None,
             "[&height_95%_HPD={0.3110921040545068,0.38690865205576275},length_range={0.09675588357303178,0.4332959544380489},length_95%_HPD={0.16680375169879613,0.36500804261814374}]"
             ),
            ("9", 0.055354097721950546, None,
             "[&rate_range={1.3E-5,0.10958320752991428},height_95%_HPD={0.309132419999969,0.3091324199999691},length_range={3.513906814545109E-4,0.4381986285528381},height_median=0.309132419999969,length_95%_HPD={0.003011577063374571,0.08041621647998398}]"
             ),
            ("5", 0.055354097721950546, None,
             "[&rate_range={1.3E-5,0.10958320752991428},height_95%_HPD={0.309132419999969,0.3091324199999691},length_range={3.865051168833178E-5,0.4391594442572986},height_median=0.309132419999969,length_95%_HPD={0.003011577063374571,0.08041621647998398}]"
             )
        ])
Exemple #2
0
    def test_internal_node_labels(self):
        """Handle text labels on internal nodes.
        """
        ts1b = "(Cephalotaxus:125.000000,(Taxus:100.000000,Torreya:100.000000)"\
               "TT1:25.000000)Taxaceae:90.000000;"
        tree = Trees.Tree(ts1b)
        self.assertEqual(self._get_flat_nodes(tree), [('Taxaceae', 90.0, None, None),
                                                      ('Cephalotaxus', 125.0, None, None),
                                                      ('TT1', 25.0, None, None),
                                                      ('Taxus', 100.0, None, None),
                                                      ('Torreya', 100.0, None, None)])

        ts1c = "(Cephalotaxus:125.000000,(Taxus:100.000000,Torreya:100.000000)"\
                "25.000000)90.000000;"
        tree = Trees.Tree(ts1c)
        self.assertEqual(self._get_flat_nodes(tree), [(None, 90.0, None, None),
                                                      ('Cephalotaxus', 125.0, None, None),
                                                      (None, 25.0, None, None),
                                                      ('Taxus', 100.0, None, None),
                                                      ('Torreya', 100.0, None, None)])

        ts2 = "(((t9:0.385832, (t8:0.445135,t4:0.41401)C:0.024032)B:0.041436,"\
          "t6:0.392496)A:0.0291131, t2:0.497673, ((t0:0.301171,"\
          "t7:0.482152)E:0.0268148, ((t5:0.0984167,t3:0.488578)G:0.0349662,"\
          "t1:0.130208)F:0.0318288)D:0.0273876);"
        tree = Trees.Tree(ts2)

        large_ex_handle = open(os.path.join(self.testfile_dir,
            "int_node_labels.nwk"))
        tree = Trees.Tree(large_ex_handle.read())
        large_ex_handle.close()
Exemple #3
0
    def test_merge_with_support(self):
        """Test merge_with_support and consensus method."""
        ts1 = ("(((B 9:0.385832, (C 8:0.445135, C 4:0.41401)C:0.024032)B:0.041436,"
               "A 6:0.392496)A:0.0291131, t2:0.497673, ((E 0:0.301171,"
               "E 7:0.482152)E:0.0268148, ((G 5:0.0984167,G 3:0.488578)G:0.0349662,"
               "F 1:0.130208)F:0.0318288)D:0.0273876);")

        tbs1 = ("(((B 9:0.385832, (C 8:0.445135, C 4:0.41401)C:0.024032)B:0.041436,"
                "A 6:0.392496)A:0.0291131, t2:0.497673, ((G 5:0.0984167,"
                "G 3:0.488578)E:0.0268148, ((E 0:0.301171, E 7:0.482152)G:0.0349662,"
                "F 1:0.130208)F:0.0318288)D:0.0273876);")

        tbs2 = ("(((B 9:0.385832,A 6:0.392496 C:0.024032)B:0.041436, (C 8:0.445135,"
                "C 4:0.41401))A:0.0291131, t2:0.497673, ((E 0:0.301171, E 7:0.482152)"
                "E:0.0268148, ((G 5:0.0984167,G 3:0.488578)G:0.0349662,F 1:0.130208)"
                "F:0.0318288)D:0.0273876);")

        t1 = Trees.Tree(ts1)
        tb1 = Trees.Tree(tbs1)
        tb2 = Trees.Tree(tbs2)

        t1.branchlength2support()
        tb1.branchlength2support()
        tb2.branchlength2support()

        t1.merge_with_support(bstrees=[tb1, tb2], threshold=0.2)

        supports = []
        for i in t1.all_ids():
            node = t1.node(i)
            data = node.get_data()
            supports.append(data.support)
        self.assertTrue(supports, [0.0, 1.0, 0.04, 1.0, 0.5, 1.0, 1.0, 1.0,
                                   1.0, 1.0, 0.5, 1.0, 1.0, 0.5, 1.0, 1.0, 1.0,
                                   1.0])
Exemple #4
0
    def showConsensusTreeBio(self):
        if self.path1 != '' and self.path2 != '':
            # odczytaj rozszerzenie
            self.fileEx1 = (os.path.splitext(self.path1)[1])[1:]
            self.fileEx2 = (os.path.splitext(self.path2)[1])[1:]

            self.trees = []

            # pierwsze
            self.f = open(self.path1, 'r')
            self.tree1 = Trees.Tree(self.f.read())
            self.trees.append(self.tree1)
            self.f.close()

            # drugie
            self.f = open(self.path2, 'r')
            self.tree2 = Trees.Tree(self.f.read())
            self.trees.append(self.tree2)
            self.f.close()

            self.consensus_tree = Trees.consensus(self.trees)

            # SHOWTIME
            # rysuj
            self.handle = StringIO(
                self.consensus_tree.to_string(plain_newick=True))
            self.tree = Phylo.read(self.handle, 'newick')
            #self.tree.root.color = '#808080'
            self.OpenInfoWindow()
        else:
            print "Nie wybrano punktow"

            # WYSWIETLA INFORMACJE
            img = pylab.imread('img/wally.png', 'rb')
            pylab.imshow(img)
            pylab.plot(0, 0)

            # DAJE CZYSTY OBRAZ BEZ OSI ** PEWNIE MOZNA PROSCIEJ
            frame1 = pylab.gca()
            for xlabel_i in frame1.axes.get_xticklabels():
                xlabel_i.set_visible(False)
                xlabel_i.set_fontsize(0.0)
            for xlabel_i in frame1.axes.get_yticklabels():
                xlabel_i.set_fontsize(0.0)
                xlabel_i.set_visible(False)
            for tick in frame1.axes.get_xticklines():
                tick.set_visible(False)
            for tick in frame1.axes.get_yticklines():
                tick.set_visible(False)

            # SHOWTIME
            pylab.show()
Exemple #5
0
    def drawConsensusTreeBioNexus(self):
        if self.path1 != '' and self.path2 != '':
            #get files extensions
            self.fileExtension1 = (os.path.splitext(self.path1)[1])[1:]
            self.fileExtension2 = (os.path.splitext(self.path2)[1])[1:]
            
            #open tree files            
            self.trees = []
            
            #first tree
            self.f = open(self.path1, 'r')
            self.tree1 = Trees.Tree(self.f.read())
            self.trees.append(self.tree1)
            self.f.close()
            
            #second tree
            self.f = open(self.path2, 'r')
            self.tree2 = Trees.Tree(self.f.read())
            self.trees.append(self.tree2)
            self.f.close()


            #generate consensus tree
            self.consensus_tree = Trees.consensus(self.trees)
            
            #draw tree
            self.handle = StringIO(self.consensus_tree.to_string(plain_newick=True))
            self.tree = Phylo.read(self.handle, 'newick')
            self.tree.root.color = '#808080'
            Phylo.draw(self.tree)
Exemple #6
0
    def makeRootUnroot(self, mod):
        if self.path1 != '' and self.path2 == '':
            # get files extensions
            self.fileEx1 = (os.path.splitext(self.path1)[1])[1:]
            self.fileEx2 = (os.path.splitext(self.path2)[1])[1:]

            # open tree files
            self.trees = []
            self.drzewo = []

            # first tree
            self.f = open(self.path1, 'r')
            self.miss = self.f.read()
            self.tree1 = Trees.Tree(self.miss)
            self.dre = ts.Tree(self.miss)
            print "# Before modification"
            print self.tree1

            if mod == 0:
                print "# After modification -- Rooting (at midpoint):"
                self.dre.root_midpoint()
            elif mod == 1:
                print "# After modification -- UnRooting:"
                self.dre.unroot()
            elif mod == 2:
                print "# After modification -- Rooting (balanced):"
                self.dre.root_balanced()
            print self.dre
            print "\nDetails about tree:"
            self.dre.display()
            Phylo.draw_ascii(self.tree1)
            self.show()
            self.f.close()
def parse_trees(filename):
    """Parse trees.

    Helper function until we have Bio.Phylo on trunk.
    """
    # TODO - Can this be removed now?
    data = open("test_file", "r").read()
    for tree_str in data.split(";\n"):
        if tree_str:
            yield Trees.Tree(tree_str + ";")
Exemple #8
0
 def test_to_string(self):
     """Test to_string method."""
     t = Trees.Tree(
         "(((B 9:0.385832, (C 8:0.445135, C 4:0.41401)C:0.024032)B:0.041436,"
         "A 6:0.392496)A:0.0291131, t2:0.497673, ((E 0:0.301171,"
         "E 7:0.482152)E:0.0268148, ((G 5:0.0984167,G 3:0.488578)G:0.0349662,"
         "F 1:0.130208)F:0.0318288)D:0.0273876);")
     tree_a_val = "((A 6,(B 9,(C 8,C 4))),t2,((E 0,E 7),(F 1,(G 5,G 3))));"
     self.assertEqual(t.to_string(ladderize="LEFT"),
                      "tree a_tree = " + tree_a_val)
Exemple #9
0
    def showConsensusTreeBio(self):
        if self.path1 != '' and self.path2 != '':
            # odczytaj rozszerzenie
            self.fileEx1 = (os.path.splitext(self.path1)[1])[1:]
            self.fileEx2 = (os.path.splitext(self.path2)[1])[1:]

            self.trees = []

            # pierwsze
            self.f = open(self.path1, 'r')
            self.tree1 = Trees.Tree(self.f.read())
            self.trees.append(self.tree1)
            self.f.close()

            # drugie
            self.f = open(self.path2, 'r')
            self.tree2 = Trees.Tree(self.f.read())
            self.trees.append(self.tree2)
            self.f.close()

            self.consensus_tree = Trees.consensus(self.trees)

            # SHOWTIME
            # rysuj
            self.handle = StringIO(self.consensus_tree.to_string(plain_newick=True))
            self.tree = Phylo.read(self.handle, 'newick')
            #self.tree.root.color = '#808080'
            self.OpenInfoWindow()
        else:
            print "Nie wybrano punktow"

            # WYSWIETLA INFORMACJE
            img = pylab.imread('img/wally.png', 'rb')
            pylab.imshow(img)
            pylab.plot(0, 0)

            # DAJE CZYSTY OBRAZ BEZ OSI ** PEWNIE MOZNA PROSCIEJ
            frame1 = pylab.gca()
            for xlabel_i in frame1.axes.get_xticklabels():
                xlabel_i.set_visible(False)
                xlabel_i.set_fontsize(0.0)
            for xlabel_i in frame1.axes.get_yticklabels():
                xlabel_i.set_fontsize(0.0)
                xlabel_i.set_visible(False)
            for tick in frame1.axes.get_xticklines():
                tick.set_visible(False)
            for tick in frame1.axes.get_yticklines():
                tick.set_visible(False)

            # SHOWTIME
            pylab.show()
Exemple #10
0
    def showOpenFileWindow(self):
        fname = QtGui.QFileDialog.getOpenFileName(self, 'Otworz plik zawierajacy drzewo', './Trees')
        if fname != '':
            self.chosenFileName = str(fname)
            f = open(str(fname), 'r')
            self.tree1 = Trees.Tree(f.read())
            self.moredata = Trees.Tree.display(self.tree1)
            print self.moredata
            self.tmpf = open('more.txt', 'w')
            self.tmpf.write(str(self.moredata))
            self.tmpf.close()
            # with f:
            # path1 = f.read()
            # self.pathInfo.setText(path1)

            self.fileExtension = (os.path.splitext(str(fname))[1])[1:]
            self.tree = Phylo.read(str(fname), self.fileExtension)
            self.tree1s = self.tree
            self.terminals = self.tree1s.get_terminals()
Exemple #11
0
 def test_large_newick(self):
     with open(os.path.join(self.testfile_dir,
                            "int_node_labels.nwk")) as large_ex_handle:
         tree = Trees.Tree(large_ex_handle.read())
Exemple #12
0
def parse_trees(filename):
    """Helper function until we have Bio.Phylo on trunk."""
    data = open("test_file", "r").read()
    for tree_str in data.split(";\n"):
        if tree_str:
            yield Trees.Tree(tree_str + ";")
Exemple #13
0
    def test_TreeTest2(self):
        """Handle text labels on internal nodes."""
        ts1b = (
            "(Cephalotaxus:125.000000,(Taxus:100.000000,Torreya:100.000000)"
            "TT1:25.000000)Taxaceae:90.000000;")
        tree = Trees.Tree(ts1b)
        self.assertEqual(self._get_flat_nodes(tree),
                         [("Taxaceae", 90.0, None, None),
                          ("Cephalotaxus", 125.0, None, None),
                          ("TT1", 25.0, None, None),
                          ("Taxus", 100.0, None, None),
                          ("Torreya", 100.0, None, None)])
        tree.prune("Torreya")
        self.assertEqual(tree.all_ids(), [0, 1, 3])
        ts1c = (
            "(Cephalotaxus:125.000000,(Taxus:100.000000,Torreya:100.000000)"
            "25.000000)90.000000;")
        tree = Trees.Tree(ts1c)
        self.assertEqual(self._get_flat_nodes(tree),
                         [(None, 90.0, None, None),
                          ("Cephalotaxus", 125.0, None, None),
                          (None, 25.0, None, None),
                          ("Taxus", 100.0, None, None),
                          ("Torreya", 100.0, None, None)])
        self.assertFalse(tree.has_support())
        with self.assertRaises(Exception) as context:
            tree.randomize()
        self.assertTrue(
            "Either numer of taxa or list of taxa must be specified." in str(
                context.exception))
        tree_rand = Trees.Tree(ts1c)
        tree_rand.randomize(ntax=4)
        self.assertEqual(sorted(tree_rand.get_taxa()),
                         ["taxon1", "taxon2", "taxon3", "taxon4"])
        tree.branchlength2support()
        tree.convert_absolute_support(2)
        self.assertEqual(self._get_flat_nodes(tree),
                         [(None, 0.0, 90.0, None),
                          ("Cephalotaxus", 0.0, 62.5, None),
                          (None, 0.0, 12.5, None), ("Taxus", 0.0, 50.0, None),
                          ("Torreya", 0.0, 50.0, None)])

        ts2 = (
            "(((t9:0.385832, (t8:0.445135,t4:0.41401)C:0.024032)B:0.041436,"
            "t6:0.392496)A:0.0291131, t2:0.497673, ((t0:0.301171,"
            "t7:0.482152)E:0.0268148, ((t5:0.0984167,t3:0.488578)G:0.0349662,"
            "t1:0.130208)F:0.0318288)D:0.0273876);")
        tree = Trees.Tree(ts2)
        tree.branchlength2support()
        supports = []
        for i in tree.all_ids():
            node = tree.node(i)
            data = node.get_data()
            supports.append(data.support)
        self.assertEqual(supports, [
            0.0, 0.0291131, 0.041436, 0.385832, 0.024032, 0.445135, 0.41401,
            0.392496, 0.497673, 0.0273876, 0.0268148, 0.301171, 0.482152,
            0.0318288, 0.0349662, 0.0984167, 0.488578, 0.130208
        ])
        ts3 = (
            "(((B 9:0.385832, (C 8:0.445135, C4:0.41401)C:0.024032)B:0.041436,"
            "A 6:0.392496)A:0.0291131, t2:0.497673, ((E 0:0.301171,"
            "E 7:0.482152)E:0.0268148, ((G 5:0.0984167,G 3:0.488578)G:0.0349662,"
            "F 1:0.130208)F:0.0318288)D:0.0273876);")
        self.assertFalse(tree.is_identical(Trees.Tree(ts3)))
        tree = Trees.Tree(ts3)
        self.assertTrue(tree.is_bifurcating())
        self.assertTrue(tree.is_bifurcating(1))
        self.assertEqual([tree.distance(0, n) for n in tree.all_ids()], [
            0.0, 0.0291131, 0.0705491, 0.4563811, 0.0945811, 0.5397161,
            0.5085911, 0.4216091, 0.497673, 0.0273876, 0.0542024, 0.3553734,
            0.5363544, 0.0592164, 0.09418259999999999, 0.1925993, 0.5827606,
            0.1894244
        ])

        subtree = tree.set_subtree(10)
        self.assertEqual(sorted(subtree), ["E 0", "E 7"])
        tree.collapse_genera()
        self.assertEqual(tree.all_ids(),
                         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13, 14, 17])
	
	if options.tree=="":
		DoError("No tree file specified")


	print "Reading tree file"
	sys.stdout.flush()
	
	try:
		tree_strings = open(options.tree).readlines()
	except IOError:
		DoError("Cannot open tree file "+options.tree)
	handle = open(options.outputfile, "w")
	for tree_string in tree_strings:
		
		tree = Trees.Tree(tree_string, rooted=True)
		
		
		if options.outgroup!="":
			print "Rooting tree on", options.outgroup
			sys.stdout.flush()
			tree.root_with_outgroup(outgroup=options.outgroup)
		else:
			print "Midpoint rooting tree"
			tree=Si_nexus.midpoint_root(tree)
	
		
		
		#Print tree
		
		treestring=Si_nexus.tree_to_string(tree,plain=False,ladderize=options.ladderise)#tree with branch lengths and support
def makeJsonAlign(smo_output, phy_output):
    _writer = json.JsonWriter()
    #Making JSON for root alignment in .smo file
    treeStr = readTree(phy_output)
    #Find left and right IDs using MPTT
    tree = Trees.Tree(rooted=True)
    (clades, vals) = tree._parse(treeStr)
    tree._add_subtree(0, clades)
    rootNode = tree.node(tree.root)
    nodeIdOfLeftId = {}
    leftIdOfSatchmoId = {}
    mptt(tree, 1, 0, nodeIdOfLeftId)
    #tree.display()
    #print(nodeIdOfLeftId)

    smoFile = smo_output
    #Read from .smo file
    f_smo = open(smoFile)
    smoString = ''.join([line for line in f_smo.readlines()])
    f_smo.close()
    #Find the number of nodes
    index1 = string.find(smoString, ' ')
    index2 = string.find(smoString, '\n')
    no_of_nodes = int(smoString[index1 + 1:index2])
    #Read sequence alignment at each node
    curr_index = 0
    i = 0
    ret = {}
    keys = {}
    no_of_leaves = {}
    while i < no_of_nodes:
        curr_index = string.find(smoString, '[', curr_index)
        leaf_index = string.find(smoString, "leaf", curr_index)
        internal_index = string.find(smoString, "internal", curr_index)

        if ((leaf_index < internal_index) or
            (internal_index == -1)) and (leaf_index != -1):
            nodeType = "leaf"
            #print("Its a leaf!")
        elif ((leaf_index > internal_index) or
              (leaf_index == -1)) and (internal_index != -1):
            nodeType = "internal"
            #print("Its an internal node!")
        else:
            print("Invalid node type!")

        if (nodeType == "leaf"):
            curr_index = string.find(smoString, "index", curr_index)
            newLine_index = string.find(smoString, '\n', curr_index)
            satchmo_id = int(smoString[curr_index + len("index") +
                                       1:newLine_index])
            curr_index = string.find(smoString, '>', curr_index)
            newLine_index = string.find(smoString, '\n', curr_index)
            seq_name = smoString[curr_index + 1:newLine_index]
            for id in nodeIdOfLeftId.keys():
                if (tree.is_terminal(
                        nodeIdOfLeftId[id])) and (seq_name in tree.get_taxa(
                            nodeIdOfLeftId[id])):
                    leftIdOfSatchmoId[satchmo_id] = id
                    populate_ret(ret, id, curr_index, keys, no_of_leaves,
                                 smoString)

        elif (nodeType == "internal"):
            curr_index = string.find(smoString, "index", curr_index)
            newLine_index = string.find(smoString, '\n', curr_index)
            satchmo_id = int(smoString[curr_index + len("index") +
                                       1:newLine_index])
            target_index = string.find(smoString, "target", curr_index)
            newLine_index = string.find(smoString, '\n', target_index)
            target = int(smoString[target_index + len("target") +
                                   1:newLine_index])
            target = nodeIdOfLeftId[leftIdOfSatchmoId[target]]
            #print("Target = ." + str(target) + ".");
            template_index = string.find(smoString, "template", curr_index)
            newLine_index = string.find(smoString, '\n', template_index)
            template = int(smoString[template_index + len("template") +
                                     1:newLine_index])
            template = nodeIdOfLeftId[leftIdOfSatchmoId[template]]
            #print("Template = ." + str(template) + ".")
            #print(tree.node(nodeIdOfLeftId[id]).get_succ())
            for id in nodeIdOfLeftId.keys():
                #print(tree.node(nodeIdOfLeftId[id]).get_succ())
                if(not(tree.is_terminal(nodeIdOfLeftId[id]))) \
                and (template in tree.node(nodeIdOfLeftId[id]).get_succ()) \
                and (target in tree.node(nodeIdOfLeftId[id]).get_succ()) \
                and (len(tree.node(nodeIdOfLeftId[id]).get_succ()) == 2):
                    #print("Template = ." + str(template) + ".")
                    #print(tree.node(nodeIdOfLeftId[id]).get_succ())
                    #print("Adding to id = " + str(id))
                    leftIdOfSatchmoId[satchmo_id] = id
                    curr_index = string.find(smoString, '>', curr_index)
                    populate_ret(ret, id, curr_index, keys, no_of_leaves,
                                 smoString)

        i += 1
        #print(leftIdOfSatchmoId)
        #print(ret)
    for id in nodeIdOfLeftId.keys():
        addColorString(ret, keys, no_of_leaves, id)
        #print(ret)
    ans = _writer.write(ret)
    return ans