Package: pyfastg
pyfastg: a minimal Python library for parsing SPAdes FASTG filesThe FASTG file formatFASTG is a format for describing sequencing assembly graphs. It is geared toward
accurately representing the ambiguity resulting from sequencing limitations, ploidy,
or other factors that complicate representation of a seqence as a simple string.The latest specification for the FASTG format is version 1.00, as of writing;
this specification is locatedhere.
Whenever the rest of this documentation mentions "the FASTG spec," this is in reference
to this version of the specification.pyfastg parses graphs that followa subset of the FASTG spec: in
particular, pyfastg is designed to work with files output by theSPAdesfamily of assemblers.The pyfastg librarypyfastg is a Python library that containsparse_fastg(), a function that
takes as input a path to a SPAdes FASTG file.parse_fastg()reads the
specified FASTG file and returns aNetworkXDiGraphobject representing the structure of the assembly graph. From here, the
graph can be analyzed, visualized, etc. as needed.pyfastg is very much in its infancy, so it may be most useful as a starting point.
Pull requests are welcome!Note about the graph topologyThe FASTG spec contains the following sentence (in section 6, page 7):Note also that strictly speaking, [the structure described in a FASTG file] is not a graph at all, as we have not specified a notion of vertex. However in many cases one can without ambiguity define vertices and thereby associate abona fidedigraph, and we do so frequently in this document to illustrate concepts.We take this approach in pyfastg."Edges" in the FASTG file will be represented as nodes
in the NetworkX graph, and "adjacencies" between edges in the FASTG file will
be represented as edges in the NetworkX graph.As far as we're aware, this is
usually how these files are visualized.Installationpyfastg can be installed usingpip:pipinstallpyfastgpyfastg's only dependency (which should be installed automatically with
the above command) isNetworkX≥ 2.As of writing, pyfastg supports all Python versions ≥ 3.6. pyfastg might be able to work with earlier versions of Python, but we do not explicitly test against these.Quick ExampleThe second line (which points to one of pyfastg's test assembly graphs)
assumes that you're located in the root directory of the pyfastg repo.>>>importpyfastg>>>g=pyfastg.parse_fastg("pyfastg/tests/input/assembly_graph.fastg")>>># g is now a NetworkX DiGraph! We can do whatever we want with this object.>>>>>># Example: List the sequences in this graph (these are "edges" in the FASTG>>># file, but are represented as nodes in g)>>>g.nodes()NodeView(('1+','29-','1-','6-','2+','26+','27+','2-','3+','4+','6+','7+','3-','33-','9-','4-','5+','5-','28+','7-','8+','28-','9+','8-','12-','10+','12+','10-','24-','32-','11+','30-','11-','27-','19-','13+','25+','31-','13-','14+','14-','26-','15+','15-','23-','16+','16-','17+','17-','19+','18+','33+','18-','20+','20-','22+','21+','21-','22-','23+','24+','25-','29+','30+','31+','32+'))>>>>>># Example: Get details for a single sequence (length, coverage, GC-content)>>>g.nodes["15+"]{'length':193,'cov':6.93966,'gc':0.5492227979274611}>>>>>># Example: Get information about the graph's connectivity>>>importnetworkxasnx>>>components=list(nx.weakly_connected_components(g))>>>forcincomponents:...print(len(c),"nodes")...print(c)...33nodes{'8-','17-','15+','30+','16+','26-','25+','19+','7+','23+','14-','18-','10-','29-','20-','27-','11-','5-','3+','2-','12-','13+','31-','6+','1+','21-','24-','32-','22+','28+','4+','33-','9-'}33nodes{'26+','29+','18+','3-','2+','8+','15-','24+','9+','17+','27+','28-','11+','6-','20+','14+','19-','13-','4-','21+','5+','31+','22-','12+','25-','30-','10+','1-','7-','32+','23-','33+','16-'}Details about the required input file format (tl;dr: SPAdes-dialect FASTG files only)Currently, pyfastg is hardcoded to parse FASTG files created by the SPAdes assembler.
Other valid FASTG files that don't follow the pattern used by SPAdes for edge names
are not supported.Edge namesIn particular, each edge in the file must have a name formatted like:EDGE_1_length_9909_cov_6.94721The edge ID (here,1) can contain the charactersa-z,A-Z, and0-9.The edge length (here,9909) can contain the characters0-9.The edge coverage (here,6.94721) can contain the characters0-9and..An edge name can optionally end with a'character, indicating that
this edge is a reverse complement. We will refer to whether or not an edge name
ends with'as itsorientation: an edge that does not end with a'has a+orientation, and an edge name that ends with a'has a-orientation.Edge names in a FASTG file should be consistent, with respect to their ID and orientation.
If, in a single FASTG file, pyfastg sees a reference to an edge namedEDGE_1_length_9909_cov_6.94721and also a reference to an edge namedEDGE_1_length_8109_cov_6.94721(with the same ID [1]
and orientation [+], but a different length and/or coverage)
then it will throw an error.Edge declaration linesHere, we refer to each line starting with>as anedge declaration. An
edge's sequence is described in the line(s) following its edge declaration
(until the next edge declaration); additionally, the outgoing adjacencies from
this edge to other edges may be described on this line, if present. For example,
the line>EDGE_1_length_5_cov_10:EDGE_2_length_3_cov_1,EDGE_3_length_6_cov_2.5',EDGE_4_length_8_cov_5.1;indicates that the edgeEDGE_1_length_5_cov_10has three outgoing adjacencies: to the
edgesEDGE_2_length_3_cov_1,EDGE_3_length_6_cov_2.5', andEDGE_4_length_8_cov_5.1.
This line would thus result in three "edges" being created
in the NetworkX graph produced by pyfastg: (1+→2+), (1+→3-), and (1+→4+).Each edge declaration must end with a;character (after removing trailing
whitespace). Section 15 of the FASTG spec mentions that having a newline
after the semicolon isn't required, but we require it here for the sake of
simplicity.Edge sequencesWe assume that each sequence (the line(s) between edge declarations)
consists only of the charactersA,C,G,T, orU. So, more complex
types of strings (e.g. the "stuffed gaps" described in the FASTG spec) are
not allowed in an edge's sequence.Additionally, lowercase characters or degenerate nucleotides are not allowed;
this matches section 15 of the FASTG spec.
The FASTG spec doesn't explicitly allow for uracil (U), but we allow it
anyway in order to support RNA sequences. (UandTare allowed to be contained
in the same sequence,in the unlikely case that this is needed.)Leading and trailing whitespace in sequence lines will be ignored, so something
likeATCGis technically valid, and describes the sequenceATCG.
However, a line likeATC Gis not valid since the inner
space,, would be considered part of the sequence.Details about the output NetworkX graphNode names and attributesNodes in the returnedDiGraph(corresponding to edges in the FASTG file)
will contain three attribute fields:length: the length of the sequence (represented as a pythonint)cov: the coverage of the sequence (represented as a pythonfloat)gc: the GC-content (in the range [0, 1]) of the sequence (represented as a pythonfloat)Each node's name is a pythonstrcreated by concatenating edge IDs and orientations.
For example,EDGE_1_length_9909_cov_6.94721will correspond to a node named1+.
This naming scheme is analogous to that used byBandage.About reverse complementspyfastgonly creates nodes based on the edges
explicitly described in the FASTG file. If a file only describes edgesEDGE_1_length_5_cov_10,EDGE_2_length_6_cov_10', andEDGE_3_length_7_cov_15, then
pyfastg will only create nodes1+,2-, and3+, and not the reverse complement
nodes1-,2+,3-, etc.Similarly, if a file contains an adjacency from edgeEDGE_1_length_5_cov_10toEDGE_2_length_6_cov_10', then this adjacency will only be represented as a single edge
(1+→2-) in pyfastg's output graph. The implied reverse-complement of this
edge (2+→1-) will not be created unless the file explicitly
contains an adjacency fromEDGE_2_length_6_cov_10toEDGE_1_length_5_cov_10'.Information for pyfastg developersInstallationIf you're interested in developing the code, you will probably want to fork this repository
and then clone your fork. Once you do this,cdinto the root of the repository and runpipinstall-e.[dev]to install pyfastg in "editable mode." Thanks to the[dev]flag, this will also install
pyfastg's development dependencies (see theextras_requireline insetup.pyfor details).Testing, linting, and formatting the codeAll of these commands are covered in pyfastg'sMakefile.Run tests:make testLint and style-check the code:make stylecheckAutomtaically style the code:make styleChangelogSee pyfastg'sCHANGELOG.mdfile
for information on the changes included with new pyfastg releases.Licensepyfastg is licensed under the MIT License. Please see pyfastg'sLICENSEfile for details.