mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
132 lines
5 KiB
Python
132 lines
5 KiB
Python
import csv
|
|
import xml.etree.ElementTree as ET
|
|
import sys
|
|
|
|
def generate_graphs(tsv_path):
|
|
nodes = {}
|
|
edges = []
|
|
|
|
with open(tsv_path, 'r', encoding='utf-8') as f:
|
|
# Skip potential comment lines at start
|
|
lines = f.readlines()
|
|
start_idx = 0
|
|
for i, line in enumerate(lines):
|
|
if line.startswith('1\t') or line.startswith('#\t'):
|
|
start_idx = i
|
|
break
|
|
|
|
reader = csv.DictReader(lines[start_idx:], delimiter='\t')
|
|
|
|
# Normalize field names (sometimes they have # or leading/trailing space)
|
|
fieldnames = [fn.strip().replace('#', 'ID') for fn in reader.fieldnames]
|
|
|
|
for row in reader:
|
|
# Re-map row to clean keys
|
|
clean_row = {fn.strip().replace('#', 'ID'): v for fn, v in zip(reader.fieldnames, row.values())}
|
|
|
|
node_id = clean_row.get('ID')
|
|
if not node_id: continue
|
|
|
|
name = clean_row.get('Model_Name', f"Model_{node_id}")
|
|
family = clean_row.get('Family', 'Uncategorized')
|
|
domain = clean_row.get('Domain_Type', 'Default')
|
|
|
|
nodes[node_id] = {
|
|
'name': name,
|
|
'family': family,
|
|
'domain': domain,
|
|
'equation': clean_row.get('Equation', ''),
|
|
'status': clean_row.get('Status', '')
|
|
}
|
|
|
|
cross_refs = clean_row.get('Cross_Refs', '')
|
|
if cross_refs and cross_refs != '-':
|
|
refs = [r.strip() for r in cross_refs.split(',') if r.strip().isdigit()]
|
|
for ref in refs:
|
|
edges.append((node_id, ref))
|
|
|
|
# 1. Generate Mermaid
|
|
mermaid_content = "graph TD\n"
|
|
# Group by domain
|
|
domains = {}
|
|
for nid, data in nodes.items():
|
|
dom = data['domain']
|
|
if dom not in domains: domains[dom] = []
|
|
domains[dom].append(nid)
|
|
|
|
for dom, nids in domains.items():
|
|
if dom == 'Default': continue
|
|
mermaid_content += f" subgraph {dom.replace('_', ' ')}\n"
|
|
for nid in nids:
|
|
# Clean label for mermaid
|
|
label = nodes[nid]['name'].replace(' ', '_').replace('(', '').replace(')', '')
|
|
mermaid_content += f" N{nid}[{label}]\n"
|
|
mermaid_content += " end\n"
|
|
|
|
for src, dst in edges:
|
|
if src in nodes and dst in nodes:
|
|
mermaid_content += f" N{src} --> N{dst}\n"
|
|
|
|
with open('research_graph.mermaid', 'w') as f:
|
|
f.write(mermaid_content)
|
|
|
|
# 2. Generate GraphML
|
|
graphml = ET.Element('graphml', {
|
|
'xmlns': "http://graphml.graphdrawing.org/xmlns",
|
|
'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance",
|
|
'xsi:schemaLocation': "http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"
|
|
})
|
|
|
|
# Define keys
|
|
key_name = ET.SubElement(graphml, 'key', {'id': 'd0', 'for': 'node', 'attr.name': 'name', 'attr.type': 'string'})
|
|
key_family = ET.SubElement(graphml, 'key', {'id': 'd1', 'for': 'node', 'attr.name': 'family', 'attr.type': 'string'})
|
|
key_domain = ET.SubElement(graphml, 'key', {'id': 'd2', 'for': 'node', 'attr.name': 'domain', 'attr.type': 'string'})
|
|
|
|
graph = ET.SubElement(graphml, 'graph', {'id': 'G', 'edgedefault': 'directed'})
|
|
|
|
for nid, data in nodes.items():
|
|
node = ET.SubElement(graph, 'node', {'id': f"n{nid}"})
|
|
ET.SubElement(node, 'data', {'key': 'd0'}).text = data['name']
|
|
ET.SubElement(node, 'data', {'key': 'd1'}).text = data['family']
|
|
ET.SubElement(node, 'data', {'key': 'd2'}).text = data['domain']
|
|
|
|
for i, (src, dst) in enumerate(edges):
|
|
if src in nodes and dst in nodes:
|
|
ET.SubElement(graph, 'edge', {
|
|
'id': f"e{i}",
|
|
'source': f"n{src}",
|
|
'target': f"n{dst}"
|
|
})
|
|
|
|
tree = ET.ElementTree(graphml)
|
|
tree.write('research_graph.graphml', encoding='utf-8', xml_declaration=True)
|
|
|
|
# 3. Generate simplified Mermaid (Top nodes by degree)
|
|
# Count connections
|
|
degree = {nid: 0 for nid in nodes}
|
|
for src, dst in edges:
|
|
if src in degree: degree[src] += 1
|
|
if dst in degree: degree[dst] += 1
|
|
|
|
top_nodes = sorted(degree.items(), key=lambda x: x[1], reverse=True)[:50]
|
|
top_ids = [nid for nid, deg in top_nodes]
|
|
|
|
simp_mermaid = "graph TD\n"
|
|
for nid in top_ids:
|
|
label = nodes[nid]['name'].replace(' ', '_')
|
|
simp_mermaid += f" N{nid}[{label}]\n"
|
|
|
|
for src, dst in edges:
|
|
if src in top_ids and dst in top_ids:
|
|
simp_mermaid += f" N{src} --> N{dst}\n"
|
|
|
|
with open('research_graph_summary.mermaid', 'w') as f:
|
|
f.write(simp_mermaid)
|
|
|
|
print(f"✅ Generated graphs for {len(nodes)} nodes and {len(edges)} edges.")
|
|
|
|
if __name__ == "__main__":
|
|
import os
|
|
base_path = "/home/allaun/Documents/Research Stack"
|
|
tsv_path = os.path.join(base_path, "3-Mathematical-Models", "MATH_MODEL_MAP.tsv")
|
|
generate_graphs(tsv_path)
|