def test_unordered_groups_create_virtual_unknown_records(self): g = gfapy.Gfa(version="gfa2") set = gfapy.Line("U\tset\tchildpath b childset edge") g.append(set) for i in set.items: assert (i.virtual) self.assertEqual("\n", i.record_type) childpath = gfapy.Line("O\tchildpath\tf+ a+") g.append(childpath) assert (not set.items[0].virtual) self.assertEqual(childpath, set.items[0]) self.assertEqual([set], childpath.sets) sB = gfapy.Line("S\tb\t1000\t*") g.append(sB) assert (not set.items[1].virtual) self.assertEqual(sB, set.items[1]) self.assertEqual([set], sB.sets) childset = gfapy.Line("U\tchildset\tg edge2") g.append(childset) assert (not set.items[2].virtual) self.assertEqual(childset, set.items[2]) self.assertEqual([set], childset.sets) edge = gfapy.Line("E\tedge\te-\tc+\t0\t100\t900\t1000$\t*") g.append(edge) assert (not set.items[3].virtual) self.assertEqual(edge, set.items[3]) self.assertEqual([set], edge.sets)
def test_gaps_backreferences(self): g = gfapy.Gfa() sa = gfapy.Line("S\ta\t100\t*") g.append(sa) # gaps s = {} gap = {} for name in ["b", "c", "d", "e", "f", "g", "h", "i"]: s[name] = gfapy.Line("S\t{}\t100\t*".format(name)) g.append(s[name]) for name in \ ["a+b+", "a+c-", "a-d+", "a-e-", "f+a+", "g+a-", "h-a+", "i-a-"]: gap[name] = gfapy.Line("\t".join( ["G","*",name[0:2],name[2:4],"200","*"])) g.append(gap[name]) # gaps_[LR]() self.assertEqual([gap["a-d+"], gap["a-e-"], gap["f+a+"], gap["h-a+"]], sa.gaps_L) self.assertEqual([gap["a+b+"], gap["a+c-"], gap["g+a-"], gap["i-a-"]], sa.gaps_R) # gaps() self.assertEqual(sa.gaps_L, sa.gaps_of_end("L")) self.assertEqual(sa.gaps_R, sa.gaps_of_end("R")) self.assertEqual(sa.gaps_L + sa.gaps_R, sa.gaps) # disconnection effects gap["a-d+"].disconnect() self.assertEqual([gap["a-e-"], gap["f+a+"], gap["h-a+"]], sa.gaps_L) sa.disconnect() self.assertEqual([], sa.gaps_L) self.assertEqual([], sa.gaps_R) self.assertEqual([], sa.gaps_of_end("L")) self.assertEqual([], sa.gaps_of_end("R")) self.assertEqual([], sa.gaps)
def test_header_conversion(self): gfa1str = "H\tVN:Z:1.0" gfa2str = "H\tVN:Z:2.0" self.assertEqual(gfa1str, str(gfapy.Line(gfa2str).to_gfa1())) self.assertEqual(gfa1str, str(gfapy.Line(gfa2str).to_gfa1())) self.assertEqual(gfa2str, str(gfapy.Line(gfa1str).to_gfa2())) self.assertEqual(gfa2str, str(gfapy.Line(gfa2str).to_gfa2()))
def test_path_conversion(self): path_gfa1 = "P\t1\ta+,b-\t100M" path_gfa2 = "O\t1\ta+ a_to_b+ b-" # gfa1 => gfa2 l1 = "L\ta\t+\tb\t-\t100M\tID:Z:a_to_b" g1 = gfapy.Gfa() path_gfa1_line = gfapy.Line(path_gfa1) g1.add_line(path_gfa1_line) g1.add_line(l1) g1.process_line_queue() # not connected self.assertRaises(gfapy.RuntimeError, gfapy.Line(path_gfa1).to_gfa2) # connected self.assertEqual(path_gfa1,str(path_gfa1_line.to_gfa1())) self.assertEqual(path_gfa2,str(path_gfa1_line.to_gfa2())) # gfa2 => gfa1 e = "E\ta_to_b\ta+\tb-\t100\t200$\t100\t200$\t100M" sA = "S\ta\t200\t*" sB = "S\tb\t200\t*" g2 = gfapy.Gfa() path_gfa2_line = gfapy.Line(path_gfa2) g2.add_line(path_gfa2_line) g2.add_line(e) g2.add_line(sA) g2.add_line(sB) # not connected self.assertRaises(gfapy.RuntimeError, gfapy.Line(path_gfa2).to_gfa1) # connected self.assertEqual(path_gfa1,str( path_gfa2_line.to_gfa1())) self.assertEqual(path_gfa2,str( path_gfa2_line.to_gfa2()))
def test_string_to_gfa_line(self): gfapy.Line("H\tVN:Z:1.0") assert (isinstance(gfapy.Line("H\tVN:Z:1.0"), gfapy.line.Header)) self.assertEqual(gfapy.line.Header(["H", "VN:Z:1.0", "xx:i:11"]), gfapy.Line("H\tVN:Z:1.0\txx:i:11")) self.assertRaises(gfapy.FormatError, gfapy.Line, "H\tH2\tVN:Z:1.0") self.assertRaises(gfapy.TypeError, gfapy.Line, "H\tVN:i:1.0")
def __add_line_GFA1(self, gfa_line): if isinstance(gfa_line, str): if gfa_line[0] == "S": gfa_line = gfapy.Line(gfa_line, vlevel=self._vlevel) else: gfa_line = gfapy.Line(gfa_line, vlevel=self._vlevel, version="gfa1") elif gfa_line.__class__ in gfapy.Lines.GFA2Specific: raise gfapy.VersionError( "Version: 1.0 ({})\n".format(self._version_explanation) + "Cannot add instance of incompatible line type " + str(type(gfa_line))) if gfa_line.record_type == "H": if self._vlevel > 0 and gfa_line.VN and gfa_line.VN != "1.0": raise gfapy.VersionError( "Header line specified wrong version ({})\n".format( gfa_line.VN) + "Line: {}\n".format(gfa_line) + "File version: 1.0 ({})".format(self._version_explanation)) self.header._merge(gfa_line) elif gfa_line.record_type == "S": if gfa_line.version == "gfa2": raise gfapy.VersionError( "Version: 1.0 ({})\n".format(self._version_explanation) + "GFA2 segment found: {}".format(gfa_line)) gfa_line.connect(self) elif gfa_line.record_type in ["L", "P", "C", "#"]: gfa_line.connect(self) else: raise gfapy.AssertionError( "Invalid record type {}. This should never happen".format(rt))
def test_duplicate_tag(self): for version in ["gfa1", "gfa2"]: gfapy.line.Header(["H", "zz:i:1", "VN:Z:1", "zz:i:2"], version=version, vlevel=0) # nothing raised gfapy.Line("H\tzz:i:1\tVN:Z:0\tzz:i:2", version=version, vlevel=0) # nothing raised gfapy.Line("H\tzz:i:1\tVN:Z:0\tzz:i:2", version=version, vlevel=0) # nothing raised for level in [1, 2, 3]: self.assertRaises(gfapy.NotUniqueError, gfapy.line.Header, ["H", "zz:i:1", "VN:Z:0", "zz:i:2"], version=version, vlevel=level) self.assertRaises(gfapy.NotUniqueError, gfapy.Line, "H\tzz:i:1\tVN:Z:0\tzz:i:2", version=version, vlevel=level) self.assertRaises(gfapy.NotUniqueError, gfapy.Gfa, "H\tzz:i:1\tVN:Z:#{version}\tzz:i:2", version=version, vlevel=level)
def test_delete_tag(self): for version in ["gfa1","gfa2"]: for level in [0,1,2,3]: l = gfapy.Line(["S", "12","*","xx:f:13","KC:i:10"], vlevel=level) # delete method l.delete("KC") # nothing raised self.assertEqual(None, l.KC) self.assertEqual(["xx"], l.tagnames) l.delete("RC") # nothing raised l.delete("XX") # nothing raised l.delete("xx") # nothing raised self.assertEqual([], l.tagnames) l.delete("zz") # nothing raised l = gfapy.Line(["S", "12","*","xx:f:13","KC:i:10"], vlevel=level) # set to None l.set("KC",None) # nothing raised self.assertEqual(None, l.KC) self.assertEqual(["xx"], l.tagnames) l.set("RC",None) # nothing raised if level == 0: l.set("XX",None) # nothing raised else: self.assertRaises(gfapy.FormatError,l.set,"XX",None) l.set("xx",None) # nothing raised self.assertEqual([], l.tagnames) l.set("zz",None) # nothing raised
def __add_line_GFA2(self, gfa_line): if isinstance(gfa_line, str): if gfa_line[0] == "S": gfa_line = gfapy.Line(gfa_line, vlevel=self._vlevel) else: gfa_line = gfapy.Line(gfa_line, vlevel=self._vlevel, version="gfa2") elif gfa_line.__class__ in gfapy.Lines.GFA1Specific: raise gfapy.VersionError( "Version: 2.0 ({})\n".format(self._version_explanation) + "Cannot add instance of incompatible line type " + str(type(gfa_line))) if gfa_line.record_type == "H": if self._vlevel > 0 and gfa_line.VN and gfa_line.VN != "2.0": raise gfapy.VersionError( "Header line specified wrong version ({})\n".format( gfa_line.VN) + "Line: {}\n".format(gfa_line) + "File version: 2.0 ({})".format(self._version_explanation)) self.header._merge(gfa_line) elif gfa_line.record_type == "S": if gfa_line.version == "gfa1": raise gfapy.VersionError( "Version: 2.0 ({})\n".format(self._version_explanation) + "GFA1 segment found: {}".format(gfa_line)) gfa_line.connect(self) else: gfa_line.connect(self)
def test_paths_create_virtual_links(self): g = gfapy.Gfa(version="gfa1") path = gfapy.Line("P\tp1\tb+,ccc-,e+\t10M1I2M,15M") g.append(path) for i in path.segment_names: assert (i.line.virtual) self.assertEqual(set(["b", "ccc", "e"]), set([x.name for x in g.segments])) sB = gfapy.Line("S\tb\t*") g.append(sB) assert (not path.segment_names[0].line.virtual) self.assertEqual(sB, path.segment_names[0].line) self.assertEqual([path], sB.paths) for i in path.links: assert (i.line.virtual) l = gfapy.Line("L\tccc\t+\tb\t-\t2M1D10M") g.append(l) assert (not path.links[0].line.virtual) self.assertEqual(l, path.links[0].line) self.assertEqual([path], l.paths) l = gfapy.Line("L\tccc\t-\te\t+\t15M") g.append(l) assert (not path.links[1].line.virtual) self.assertEqual(l, path.links[1].line) self.assertEqual([path], l.paths)
def test_merge(self): line1 = gfapy.Line("H\tVN:Z:1.0\txx:i:1") line2 = gfapy.Line("H\txx:i:2\tyy:f:1.0") line1._merge(line2) self.assertEqual("1.0", line1.VN) self.assertEqual([1, 2], line1.xx) self.assertEqual(1.0, line1.yy)
def test_paths_backreferences(self): g = gfapy.Gfa() s = {}; l = {} for name in ["a", "b", "c", "d", "e", "f"]: s[name] = gfapy.Line("S\t{}\t*".format(name)) g.append(s[name]) path = gfapy.Line("P\tp1\tf+,a+,b+,c-,e+\t*") g.append(path) for sname in ["a", "b", "c", "e", "f"]: self.assertEqual([path], s[sname].paths) self.assertEqual([], s["d"].paths) for name in ["a+b+", "b+c-", "c-d+", "e-c+", "a-f-"]: l[name] = gfapy.Line("\t".join(list("L{}*".format(name)))) g.append(l[name]) for lname in ["a+b+", "b+c-", "e-c+", "a-f-"]: self.assertEqual([path], l[lname].paths) self.assertEqual([], l["c-d+"].paths) # disconnection effects path.disconnect() for lname in ["a+b+", "b+c-", "c-d+", "e-c+", "a-f-"]: self.assertEqual([], l[lname].paths) for sname in ["a", "b", "c", "d", "e", "f"]: self.assertEqual([], s[sname].paths) # reconnection path.connect(g) for sname in ["a", "b", "c", "e", "f"]: self.assertEqual([path], s[sname].paths) self.assertEqual([], s["d"].paths) for lname in ["a+b+", "b+c-", "e-c+", "a-f-"]: self.assertEqual([path], l[lname].paths) self.assertEqual([], l["c-d+"].paths)
def test_from_string(self): gfapy.Line("H\tVN:Z:1.0") self.assertIsInstance(gfapy.Line("H\tVN:Z:1.0"), gfapy.line.Header) with self.assertRaises(gfapy.FormatError): gfapy.Line("H\tH2\tVN:Z:1.0") with self.assertRaises(gfapy.TypeError): gfapy.Line("H\tVN:i:1.0")
def test_paths_references(self): g = gfapy.Gfa() s = {}; l = {} for name in ["a", "b", "c", "d", "e", "f"]: s[name] = gfapy.Line("S\t{}\t*".format(name)) g.append(s[name]) path = gfapy.Line("P\tp1\tf+,a+,b+,c-,e+\t*") self.assertEqual([gfapy.OrientedLine("f","+"), gfapy.OrientedLine("a","+"), gfapy.OrientedLine("b","+"), gfapy.OrientedLine("c","-"), gfapy.OrientedLine("e","+")], path.segment_names) self.assertEqual([], path.links) # connection g.append(path) # add links for name in ["a+b+", "b+c-", "c-d+", "e-c+", "a-f-"]: l[name] = gfapy.Line("\t".join((list("L{}*".format(name))))) g.append(l[name]) # segment_names self.assertEqual([gfapy.OrientedLine(s["f"],"+"), gfapy.OrientedLine(s["a"],"+"), gfapy.OrientedLine(s["b"],"+"), gfapy.OrientedLine(s["c"],"-"), gfapy.OrientedLine(s["e"],"+")], path.segment_names) # links self.assertEqual([gfapy.OrientedLine(l["a-f-"],"-"), gfapy.OrientedLine(l["a+b+"],"+"), gfapy.OrientedLine(l["b+c-"],"+"), gfapy.OrientedLine(l["e-c+"],"-")], path.links) # path disconnection path.disconnect() self.assertEqual([gfapy.OrientedLine("f","+"), gfapy.OrientedLine("a","+"), gfapy.OrientedLine("b","+"), gfapy.OrientedLine("c","-"), gfapy.OrientedLine("e","+")], path.segment_names) self.assertEqual([], path.links) g.append(path) # links disconnection cascades on paths: assert(path.is_connected()) l["a-f-"].disconnect() assert(not path.is_connected()) self.assertEqual([gfapy.OrientedLine("f","+"), gfapy.OrientedLine("a","+"), gfapy.OrientedLine("b","+"), gfapy.OrientedLine("c","-"), gfapy.OrientedLine("e","+")], path.segment_names) g.append(path) g.append(l["a-f-"]) # segment disconnection cascades on links and then paths: assert(path.is_connected()) s["a"].disconnect() assert(not path.is_connected()) self.assertEqual([gfapy.OrientedLine("f","+"), gfapy.OrientedLine("a","+"), gfapy.OrientedLine("b","+"), gfapy.OrientedLine("c","-"), gfapy.OrientedLine("e","+")], path.segment_names) self.assertEqual([], path.links)
def test_custom_record(self): self.assertEqual("gfa2", gfapy.Line("X\tVN:Z:1.0").version) self.assertEqual("gfa2", gfapy.Line("X\tVN:Z:1.0", version="gfa2").version) with self.assertRaises(gfapy.VersionError): gfapy.Line("X\tVN:Z:1.0", version="gfa1") with self.assertRaises(gfapy.VersionError): gfapy.line.CustomRecord(["X", "VN:Z:1.0"], version="gfa1")
def test_forbidden_segment_names(self): gfapy.Line("S\tA+B\t*") # nothing raised gfapy.Line("S\tA-B\t*") # nothing raised gfapy.Line("S\tA,B\t*") # nothing raised with self.assertRaises(gfapy.FormatError): gfapy.Line("S\tA+,B\t*", vlevel=1) with self.assertRaises(gfapy.FormatError): gfapy.Line("S\tA-,B\t*", vlevel=1)
def test_set_version(self): string = "U\t1\tA B C" self.assertEqual("gfa2", gfapy.Line(string).version) self.assertEqual("gfa2", gfapy.Line(string, version="gfa2").version) self.assertRaises(gfapy.VersionError, gfapy.Line, string, version="gfa1")
def test_comment_conversion(self): self.assertEqual("# comment", str(gfapy.Line("# comment",version="gfa1").to_gfa1())) self.assertEqual("# comment", str(gfapy.Line("# comment",version="gfa2").to_gfa1())) self.assertEqual("# comment", str(gfapy.Line("# comment",version="gfa1").to_gfa2())) self.assertEqual("# comment", str(gfapy.Line("# comment",version="gfa2").to_gfa2()))
def test_to_gfa2_a(self): line = gfapy.Line("H\tVN:Z:1.0\txx:i:1") self.assertEqual("H", line._to_gfa2_a()[0]) self.assertEqual(sorted(["VN:Z:2.0", "xx:i:1"]), sorted(line._to_gfa2_a()[1:])) line = gfapy.Line("H\tVN:Z:2.0\txx:i:1") self.assertEqual("H", line._to_gfa2_a()[0]) self.assertEqual(sorted(["VN:Z:2.0", "xx:i:1"]), sorted(line._to_gfa2_a()[1:]))
def test_disconnect_disconnects_depent_lines(self): s1 = gfapy.Line("S\t1\tACCAT") l = gfapy.Line("L\t1\t+\t2\t-\t*") g = gfapy.Gfa() g.append(s1) g.append(l) assert (l.is_connected()) s1.disconnect() assert (not l.is_connected())
def test_disconnect_removes_field_backreferences(self): s1 = gfapy.Line("S\t1\tACCAT") l = gfapy.Line("L\t1\t+\t2\t-\t*") g = gfapy.Gfa() g.append(s1) g.append(l) self.assertEqual([l], s1.dovetails) l.disconnect() self.assertEqual([], s1.dovetails)
def test_edge_conversion(self): dovetail = "E\t*\tA+\tB-\t100\t200$\t100\t200$\t100M" dovetail_gfa1 = "L\tA\t+\tB\t-\t100M" containment = "E\t*\tA+\tB-\t20\t120\t0\t100$\t100M" containment_gfa1 = "C\tA\t+\tB\t-\t20\t100M" internal = "E\t*\tA+\tB-\t20\t110\t10\t100$\t90M" self.assertEqual(dovetail_gfa1,str( gfapy.Line(dovetail).to_gfa1())) self.assertEqual(containment_gfa1,str( gfapy.Line(containment).to_gfa1())) self.assertRaises(gfapy.RuntimeError,gfapy.Line(internal).to_gfa1)
def test_edges_gaps_create_virtual_segments(self): data = [[ "gfa1", { "lines": ["L\ta\t+\tb\t-\t*", "C\ta\t-\tb\t+\t100\t*"], "m1": "oriented_from", "m2": "oriented_to", "sA": "S\ta\t*", "sB": "S\tb\t*", "collection": "edges" } ], [ "gfa2", { "lines": ["E\t*\ta+\tb-\t0\t100\t900\t1000$\t*"], "m1": "sid1", "m2": "sid2", "sA": "S\ta\t1000\t*", "sB": "S\tb\t1000\t*", "collection": "edges" } ], [ "gfa2", { "lines": ["G\t*\ta+\tb-\t1000\t100"], "m1": "sid1", "m2": "sid2", "sA": "S\ta\t1000\t*", "sB": "S\tb\t1000\t*", "collection": "gaps" } ]] for v, values in data: for linestr in values["lines"]: g = gfapy.Gfa(version=v) line = gfapy.Line(linestr) g.append(line) self.assertEqual(set(["a", "b"]), set([x.name for x in g.segments])) for s in g.segments: assert (s.virtual) sA = gfapy.Line(values["sA"]) g.append(sA) self.assertEqual(set(["a", "b"]), set([x.name for x in g.segments])) assert (not g.segment("a").virtual) assert (g.segment("b").virtual) self.assertEqual(sA, getattr(line, values["m1"]).line) self.assertEqual(sA, g.segment("a")) self.assertEqual([line], getattr(sA, values["collection"])) sB = gfapy.Line(values["sB"]) g.append(sB) self.assertEqual(set(["a", "b"]), set([x.name for x in g.segments])) assert (not g.segment("b").virtual) self.assertEqual(sB, getattr(line, values["m2"]).line) self.assertEqual(sB, g.segment("b")) self.assertEqual([line], getattr(sB, values["collection"]))
def test_link(self): self.assertEqual("gfa1", gfapy.Line("L\tA\t+\tB\t-\t*").version) self.assertEqual( "gfa1", gfapy.Line("L\tA\t+\tB\t-\t*", version="gfa1").version) with self.assertRaises(gfapy.VersionError): gfapy.Line("L\tA\t+\tB\t-\t*", version="gfa2") with self.assertRaises(gfapy.VersionError): gfapy.line.edge.Link(["A", "+", "B", "-", "*"], version="gfa2")
def test_disconnect_removes_field_references(self): s1 = gfapy.Line("S\t1\tACCAT") l = gfapy.Line("L\t1\t+\t2\t-\t*") g = gfapy.Gfa() g.append(s1) g.append(l) assert (l.get("from") is s1) l.disconnect() assert (not l.get("from") is s1) self.assertEqual("1", l.get("from"))
def test_containment(self): self.assertEqual("gfa1", gfapy.Line("C\tA\t+\tB\t-\t10\t*").version) self.assertEqual( "gfa1", gfapy.Line("C\tA\t+\tB\t-\t10\t*", version="gfa1").version) with self.assertRaises(gfapy.VersionError): gfapy.Line("C\tA\t+\tB\t-\t10\t*", version="gfa2") with self.assertRaises(gfapy.VersionError): gfapy.line.edge.Containment(["A", "+", "B", "-", "10", "*"], version="gfa2")
def __add_line_unknown_version(self, gfa_line): if isinstance(gfa_line, str): rt = gfa_line[0] elif isinstance(gfa_line, gfapy.Line): rt = gfa_line.record_type else: raise gfapy.ArgumentError(\ "Only strings and gfapy.Line instances can be added") if rt == "#": if isinstance(gfa_line, str): gfa_line = gfapy.Line(gfa_line, dialect=self._dialect) gfa_line.connect(self) elif rt == "H": if isinstance(gfa_line, str): gfa_line = gfapy.Line(gfa_line, vlevel=self._vlevel, dialect=self._dialect) self.header._merge(gfa_line) if gfa_line.VN: if gfa_line.VN == "1.0": self._version = "gfa1" elif gfa_line.VN == "2.0": self._version = "gfa2" else: self._version = gfa_line.VN self._version_explanation = "specified in header VN tag" if self._vlevel > 0: self._validate_version() self.process_line_queue() elif rt == "S": if isinstance(gfa_line, str): gfa_line = gfapy.Line(gfa_line, vlevel=self._vlevel, dialect=self._dialect) self._version = gfa_line.version self._version_explanation = \ "implied by: syntax of S {} line".format(gfa_line.name) self.process_line_queue() gfa_line.connect(self) elif rt in ["E", "F", "G", "U", "O"]: self._version = "gfa2" self._version_explanation = "implied by: presence of a {} line".format( rt) if isinstance(gfa_line, str): gfa_line = gfapy.Line(gfa_line, vlevel=self._vlevel, version=self._version, dialect=self._dialect) self.process_line_queue() gfa_line.connect(self) elif rt in ["L", "C", "P"]: self._version_guess = "gfa1" self._line_queue.append(gfa_line) else: self._line_queue.append(gfa_line)
def test_to_s(self): s = "# this is a comment" l = gfapy.Line(s) self.assertEqual(s, str(l)) s = "#this is another\tcomment" l = gfapy.Line(s) self.assertEqual(s, str(l)) s = "#this is another\tcomment" l = gfapy.Line(s) l.spacer = " " self.assertEqual("# " + s[1:], str(l))
def test_link_version(self): string = "L\tA\t+\tB\t-\t*" self.assertEqual("gfa1", gfapy.Line(string).version) self.assertEqual("gfa1", gfapy.Line(string, version="gfa1").version) self.assertRaises(gfapy.VersionError, gfapy.Line, string, version="gfa2") self.assertRaises(gfapy.VersionError, gfapy.line.edge.Link, ["A", "+", "B", "-", "*"], version="gfa2")
def test_gap_version(self): self.assertEqual("gfa2", gfapy.Line("G\t*\tA-\tB+\t100\t*").version) self.assertEqual( "gfa2", gfapy.Line("G\t*\tA-\tB+\t100\t*", version="gfa2").version) self.assertRaises(gfapy.VersionError, gfapy.Line, "G\t*\tA-\tB+\t100\t*", version="gfa1") self.assertRaises(gfapy.VersionError, gfapy.line.Gap, ["A-", "B+", "100", "*"], version="gfa1")