<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 obonet tutorial
Step1:  Read the Gene Ontology
Learn more about the Gene Ontology (GO) downloads here. Note how we can read the OBO file from a URL. obonet.read_obo automically detects whether it's passed a local path, URL, or open file. In addition, obonet.read_obo will automtically decompress files ending in .gz, .bz2, or .gz.
Step2:  Lookup node properties
Returns a dictionary.
Step3:  Create name mappings
Note that for some OBO ontologies, some nodes only have an id and not a name (see issue).
Step4:  Find parent or child relationships
Step5:  Find all superterms of myelination
Step6:  Find all subterms of myelination
Step7:  Find all paths to the root
Step8:  See the ontology metadata
Step9:  Create a dictionary of obsolete terms to their replacements
<ASSISTANT_TASK:>
Python Code:
import networkx
import obonet
Explanation: obonet tutorial: import and analyze the Gene Ontology in Python
This tutotial shows:
How to read the Gene Ontology OBO export into networkx using the obonet package.
Simple tasks you can do with the networkx.MultiDiGraph data structure.
End of explanation
%%time
url = 'http://purl.obolibrary.org/obo/go/go-basic.obo'
graph = obonet.read_obo(url)
# Number of nodes
len(graph)
# Number of edges
graph.number_of_edges()
# Check if the ontology is a DAG
networkx.is_directed_acyclic_graph(graph)
Explanation: Read the Gene Ontology
Learn more about the Gene Ontology (GO) downloads here. Note how we can read the OBO file from a URL. obonet.read_obo automically detects whether it's passed a local path, URL, or open file. In addition, obonet.read_obo will automtically decompress files ending in .gz, .bz2, or .gz.
End of explanation
# Retreive properties of phagocytosis
graph.nodes['GO:0006909']
# Retreive properties of pilus shaft
graph.nodes['GO:0009418']
Explanation: Lookup node properties
Returns a dictionary.
End of explanation
id_to_name = {id_: data.get('name') for id_, data in graph.nodes(data=True)}
name_to_id = {data['name']: id_ for id_, data in graph.nodes(data=True) if 'name' in data}
# Get the name for GO:0042552
id_to_name['GO:0042552']
# Get the id for myelination
name_to_id['myelination']
Explanation: Create name mappings
Note that for some OBO ontologies, some nodes only have an id and not a name (see issue).
End of explanation
# Find edges to parent terms
node = name_to_id['pilus']
for child, parent, key in graph.out_edges(node, keys=True):
    print(f'• {id_to_name[child]} ⟶ {key} ⟶ {id_to_name[parent]}')
# Find edges to children terms
node = name_to_id['pilus']
for parent, child, key in graph.in_edges(node, keys=True):
    print(f'• {id_to_name[child]} ⟵ {key} ⟵ {id_to_name[parent]}')
Explanation: Find parent or child relationships
End of explanation
sorted(id_to_name[superterm] for superterm in networkx.descendants(graph, 'GO:0042552'))
Explanation: Find all superterms of myelination
End of explanation
sorted(id_to_name[subterm] for subterm in networkx.ancestors(graph, 'GO:0042552'))
Explanation: Find all subterms of myelination
End of explanation
paths = networkx.all_simple_paths(
    graph,
    source=name_to_id['starch binding'],
    target=name_to_id['molecular_function']
)
for path in paths:
    print('•', ' ⟶ '.join(id_to_name[node] for node in path))
Explanation: Find all paths to the root
End of explanation
graph.graph
Explanation: See the ontology metadata
End of explanation
graph_with_obs = obonet.read_obo(url, ignore_obsolete=False)
len(graph_with_obs)
old_to_new = dict()
for node, data in graph_with_obs.nodes(data=True):
    for replaced_by in data.get("replaced_by", []):
        old_to_new[node] = replaced_by
list(old_to_new.items())[:5]
Explanation: Create a dictionary of obsolete terms to their replacements
End of explanation
<END_TASK>