@classmethod<EOL><INDENT>def read_obo(cls, path, flatten=True, part_of_cc_only=False):<DEDENT>
name2id = {}<EOL>alt_id = {}<EOL>syn2id = {}<EOL>terms = []<EOL>with open(path) as fh:<EOL><INDENT>n = <NUM_LIT:0><EOL>while True:<EOL><INDENT>try:<EOL><INDENT>nextline = next(fh)<EOL><DEDENT>except StopIteration:<EOL><INDENT>break<EOL><DEDENT>if nextline == '<STR_LIT>':<EOL><INDENT>n += <NUM_LIT:1><EOL>id_ = next(fh)[<NUM_LIT:4>:-<NUM_LIT:1>]<EOL>name = next(fh)[<NUM_LIT:6>:-<NUM_LIT:1>]<EOL>name2id[name] = id_<EOL>domain = next(fh)[<NUM_LIT:11>:-<NUM_LIT:1>]<EOL>def_ = None<EOL>is_a = set()<EOL>part_of = set()<EOL>l = next(fh)<EOL>while l != '<STR_LIT:\n>':<EOL><INDENT>if l.startswith('<STR_LIT>'):<EOL><INDENT>alt_id[l[<NUM_LIT:8>:-<NUM_LIT:1>]] = id_<EOL><DEDENT>elif l.startswith('<STR_LIT>'):<EOL><INDENT>idx = l[<NUM_LIT:6>:].index('<STR_LIT:">')<EOL>def_ = l[<NUM_LIT:6>:(idx+<NUM_LIT:6>)]<EOL><DEDENT>elif l.startswith('<STR_LIT>'):<EOL><INDENT>is_a.add(l[<NUM_LIT:6>:<NUM_LIT:16>])<EOL><DEDENT>elif l.startswith('<STR_LIT>'):<EOL><INDENT>idx = l[<NUM_LIT:10>:].index('<STR_LIT:">')<EOL>if l[(<NUM_LIT:10>+idx+<NUM_LIT:2>):].startswith("<STR_LIT>"):<EOL><INDENT>s = l[<NUM_LIT:10>:(<NUM_LIT:10>+idx)]<EOL>syn2id[s] = id_<EOL><DEDENT><DEDENT>elif l.startswith('<STR_LIT>'):<EOL><INDENT>if part_of_cc_only:<EOL><INDENT>if domain == '<STR_LIT>':<EOL><INDENT>part_of.add(l[<NUM_LIT>:<NUM_LIT:32>])<EOL><DEDENT><DEDENT>else:<EOL><INDENT>part_of.add(l[<NUM_LIT>:<NUM_LIT:32>])<EOL><DEDENT><DEDENT>l = next(fh)<EOL><DEDENT>assert def_ is not None<EOL>terms.append(GOTerm(id_, name, domain, def_, is_a, part_of))<EOL><DEDENT><DEDENT><DEDENT>logger.info('<STR_LIT>', n)<EOL>ontology = cls(terms, syn2id, alt_id, name2id)<EOL>logger.info('<STR_LIT>')<EOL>for term in ontology:<EOL><INDENT>for parent in term.is_a:<EOL><INDENT>ontology[parent].children.add(term.id)<EOL><DEDENT>for whole in term.part_of:<EOL><INDENT>ontology[whole].parts.add(term.id)<EOL><DEDENT><DEDENT>if flatten:<EOL><INDENT>logger.info('<STR_LIT>')<EOL>ontology._flatten_ancestors()<EOL>logger.info('<STR_LIT>')<EOL>ontology._flatten_descendants()<EOL>ontology._flattened = True<EOL><DEDENT>return ontology<EOL>
Parse an OBO file and store GO term information.

        Parameters
        ----------
        path: str
            Path of the OBO file.
        flatten: bool, optional
            If set to False, do not generate a list of all ancestors and
            descendants for each GO term.
        part_of_cc_only: bool, optional
            Legacy parameter for backwards compatibility. If set to True,
            ignore ``part_of`` relations outside the ``cellular_component``
            domain.

        Notes
        -----
        The OBO file must end with a line break.