### Clone and Install Project Dependencies Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/README.md Commands to initialize the repository and install required Python packages. ```bash git clone https://github.com/fair2wise/FAIRtoWISE-FORUM-AI ``` ```bash cd FAIRtoWISE-FORUM-AI pip install -r requirements.txt ``` -------------------------------- ### Start FastAPI Server with Specific KG Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/README.md Launch the KG-RAG LLM chat as a FastAPI server, configured to use a specified knowledge graph JSON file. ```bash python kg_rag_ollama.py \ --graph storage/kg/opv_expert_graph.json \ --api ``` -------------------------------- ### Start KG-RAG FastAPI Server Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Starts the FastAPI server for the KG-RAG system, making it accessible as an Ollama-compatible proxy. This is useful for integrating with front-end applications like OpenWebUI. ```bash # Start the FastAPI server python -m modules.kg_rag_ollama_api --api --graph ./storage/kg/matkg_graph.json # Server starts at http://0.0.0.0:11435 # Configure OpenWebUI: # Admin Settings → Connections → Ollama API → http://localhost:11435 ``` -------------------------------- ### KG-RAG CLI Usage Examples Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Demonstrates various command-line options for the KG-RAG system, including interactive mode, one-shot questions, specifying a knowledge graph, and running competency evaluations. ```bash # Interactive mode python -m modules.kg_rag_ollama_api # Ask (exit to quit): What are the key factors affecting OPV efficiency? # One-shot question python -m modules.kg_rag_ollama_api --question "How does annealing influence phase separation in P3HT:PCBM?" # Use specific knowledge graph python -m modules.kg_rag_ollama_api \ --graph ./storage/kg/matkg_qwen3_235b_580papers.json \ --question "What characterization techniques are used for morphology analysis?" # Run competency question evaluation (baseline vs KG-RAG) python -m modules.kg_rag_ollama_api --competency # Results saved to: ./storage/competency_questions/competency_results_qwen3_235b_580papers.json ``` -------------------------------- ### Start Open WebUI Server Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/README.md Launch the Open WebUI server. Ensure the Ollama API URL is set to http://localhost:11435 in Admin Settings to connect with the kg_rag_ollama.py FastAPI server. ```bash open-webui serve ``` -------------------------------- ### Start KG-RAG LLM Chat FastAPI Server Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/README.md Launch the kg_rag_ollama.py script as a FastAPI server, making it accessible via HTTP. The server will run on http://0.0.0.0:11435. ```bash python kg_rag_ollama.py --api ``` -------------------------------- ### D3.js Node Dragging Behavior Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Implements drag-and-drop functionality for nodes in a D3.js force-directed graph. When dragging starts, node positions are fixed; when dragging ends, fixed positions are released. ```javascript function dragstarted(event,d) { if (!event.active) sim.alphaTarget(0.3).restart(); d.fx = d.x; d.fy = d.y; } function dragged(event,d) { d.fx = event.x; d.fy = event.y; } function dragended(event,d) { if (!event.active) sim.alphaTarget(0); d.fx = null; d.fy = null; } return d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended); ``` -------------------------------- ### KG-RAG System Initialization and Query Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Initializes the Knowledge Graph and Ollama client, then retrieves relevant nodes and generates an answer to a question using the RAG prompt. Requires `KnowledgeGraph`, `OllamaClient`, `Conversation`, `retrieve_nodes`, `build_rag_prompt`, and `RAG_SYSTEM`. ```python from modules.kg_rag_ollama_api import ( KnowledgeGraph, OllamaClient, Conversation, retrieve_nodes, build_rag_prompt, RAG_SYSTEM ) import asyncio # Load knowledge graph with embeddings kg = KnowledgeGraph( graph_file="./storage/kg/matkg_qwen3_235b_580papers.json", embed_model="all-MiniLM-L6-v2" ) # Initialize Ollama client client = OllamaClient( url="http://localhost:11434/api/chat", model="qwen3:235b" ) # Create conversation with RAG system prompt conversation = Conversation(RAG_SYSTEM) # Retrieve relevant nodes for a query question = "What is the role of P3HT crystallinity in OPV performance?" node_infos = retrieve_nodes(question, kg) # Build context from retrieved nodes context = kg.build_context( nodes=node_infos, include_structured=True, char_budget=12000, hint_terms=["P3HT", "crystallinity", "OPV"] ) # Generate RAG prompt and get answer rag_prompt = build_rag_prompt(question, context) messages = conversation.build(rag_prompt) async def get_answer(): response = await client.chat(messages) print(response) asyncio.run(get_answer()) ``` -------------------------------- ### Initialize LLMTermExtractor with CBORG backend Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Initializes the LLMTermExtractor for processing PDF documents using a cloud-based CBORG backend. Requires a chat client configured with backend details, model, API key, and base URL. ```python from modules.extract_terms import LLMTermExtractor, make_chat_client # Or use CBORG backend for cloud LLM chat_client = make_chat_client( backend="cborg", model="google/gemini-flash", cborg_api_key="your-api-key", cborg_base="https://api.cborg.lbl.gov" ) extractor_cborg = LLMTermExtractor( model_name="google/gemini-flash", data_dir="./polymer_papers", output_file="./storage/terminology/extracted_terms_gemini.json", schema_path="./storage/schema/matkg_schema.yaml", chat_client=chat_client, ) ``` -------------------------------- ### Initialize D3.js Visualization Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Sets up the SVG canvas, tooltip, color scale, and D3 force simulation. Renders initial nodes and links. ```javascript const width = window.innerWidth, height = window.innerHeight; const svg = d3.select("svg"); const tooltip = d3.select(".tooltip"); const neonColors = d3.scaleSequential(d3.interpolateRainbow).domain([0, d3.max(Object.values(degree)) || 1]); const g = svg.append("g"); let link = g.append("g").selectAll("line").data(links).join("line").attr("class", "link").attr("stroke-width", 1); let node = g.append("g").selectAll("circle").data(nodes).join("circle").attr("class", "node").attr("r", 6).attr("fill", d => neonColors(degree[d.id] || 0)).attr("stroke", "#fff").attr("stroke-width", 0.5).call(drag(simulation())); ``` -------------------------------- ### Run KG-RAG Chat with Specific KG (CLI) Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/README.md Load and use a custom knowledge graph JSON file for CLI-based chat interactions. ```bash python kg_rag_ollama.py --graph storage/kg/my_custom_kg.json ``` -------------------------------- ### Programmatic FastAPI Server Creation Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Creates and runs the FastAPI application for the KG-RAG system programmatically using `uvicorn`. This allows for custom server configurations. ```python # Programmatic server creation from modules.kg_rag_ollama_api import create_fastapi_app, run_fastapi import uvicorn app = create_fastapi_app("./storage/kg/matkg_graph.json") uvicorn.run(app, host="0.0.0.0", port=11435) ``` -------------------------------- ### Run One-Shot Question with Specific KG Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/README.md Query the KG-RAG LLM with a specific question, utilizing a custom knowledge graph file. ```bash python kg_rag_ollama.py \ --graph storage/kg/opv_expert_graph.json \ --question "How does annealing influence phase separation in P3HT:PCBM?" ``` -------------------------------- ### Initialize LLMTermExtractor with Ollama Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Initializes the LLMTermExtractor for processing PDF documents using a local Ollama model. Specify model name, base URL, data directory, output file, context length, schema path, and worker count. ```python from modules.extract_terms import LLMTermExtractor, make_chat_client # Initialize with Ollama backend extractor = LLMTermExtractor( model_name="gemma3:27b", ollama_base_url="http://localhost:11434", temperature=0.0, data_dir="./polymer_papers", output_file="./storage/terminology/extracted_terms.json", context_length=50, schema_path="./storage/schema/matkg_schema.yaml", max_workers=4, ) # Process all PDFs in directory result = extractor.process_directory() # Returns: { # "status": "success", # "processed_files": 100, # "processed_pages_total": 2847, # "processed_pages_with_terms": 1523, # "unique_terms": 4521, # "output_file": "./storage/terminology/extracted_terms.json" # } ``` -------------------------------- ### Run KG-RAG Competency Evaluation Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/README.md Evaluate the KG-RAG model against a baseline using a predefined competency question set. Results are saved incrementally. ```bash python kg_rag_ollama.py --competency ``` -------------------------------- ### Run KG-RAG LLM Chat CLI Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/README.md Execute the KG-RAG LLM chat script for interactive console-based questions. ```bash python kg_rag_ollama.py ``` -------------------------------- ### Ask One-Shot Question with KG-RAG LLM Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/README.md Ask a single question to the KG-RAG LLM without entering the interactive REPL. This performs semantic search, node expansion, PDF grounding, and RAG answer generation. ```bash python kg_rag_ollama.py --question "What is the role of P3HT crystallinity in OPV performance?" ``` -------------------------------- ### Execute Pipeline via CLI Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Run the extraction pipeline, organize directories, or perform dry runs using the command line interface. ```bash python run_pipeline_cborg.py --pdf-root ./polymer_papers --models google/gemini-flash-lite ``` ```bash python run_pipeline_cborg.py --organize --source-dir ./all_papers --pdf-root ./polymer_papers ``` ```bash python run_pipeline_cborg.py --dry-run --models qwen3:235b lbl/cborg-chat:latest ``` -------------------------------- ### JSON to Knowledge Graph Conversion CLI Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Command-line interface for converting extracted JSON terms into a knowledge graph. Use this for batch processing of terminology data. ```bash # Basic conversion python -m modules.json2kg ./storage/terminology/extracted_terms.json ./storage/kg/matkg_graph.json # With verbose output python -m modules.json2kg ./storage/terminology/extracted_terms.json ./storage/kg/matkg_graph.json --verbose # Output: INFO: Wrote 4521 nodes and 12847 edges → ./storage/kg/matkg_graph.json ``` -------------------------------- ### Run Term Extraction with CBORG Cloud API Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Runs term extraction on a directory of PDFs using the CBORG cloud API. Configure PDF directory, output file, model, backend, CBORG API key, CBORG base URL, schema path, and max workers. Note that lower parallelism is recommended for cloud APIs. ```python from pathlib import Path from modules.extract_terms import run_extraction import os result = run_extraction( pdf_dir=Path("./research_papers"), output_json=Path("./storage/terminology/terms_cborg.json"), model="lbl/cborg-chat:latest", backend="cborg", cborg_api_key=os.environ.get("CBORG_API_KEY"), cborg_base="https://api.cborg.lbl.gov", schema_path="storage/schema/matkg_schema.yaml", max_workers=1, # Lower parallelism for cloud APIs ) ``` -------------------------------- ### D3.js Pathfinding: Shortest Path Highlighting Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Finds and highlights the shortest path between two selected nodes using Breadth-First Search (BFS). Nodes and links on the path are styled differently to indicate their inclusion. ```javascript function highlightPath(source, target) { const adj = {}; nodes.forEach(n => { adj[n.id] = []; }); links.forEach(l => { adj[l.source.id || l.source].push(l.target.id || l.target); adj[l.target.id || l.target].push(l.source.id || l.source); }); const queue = [[source.id]]; const visited = new Set([source.id]); let path = null; while (queue.length) { const curr = queue.shift(); const nodeId = curr[curr.length-1]; if (nodeId === target.id) { path = curr; break; } for (let neigh of adj[nodeId]) { if (!visited.has(neigh)) { visited.add(neigh); queue.push([...curr, neigh]); } } } if (!path) return; node.attr("stroke", d => path.includes(d.id) ? "#f0f":"#333") .attr("stroke-width", d => path.includes(d.id) ? 3:0.5); link.attr("class", l => isConsecutive(path, l.source.id||l.source, l.target.id||l.target) ? "path-highlight" : "link"); } ``` -------------------------------- ### Run Term Extraction with Ollama Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Provides a high-level API to run term extraction on a directory of PDFs using the Ollama backend. Configure PDF directory, output file, model, backend, Ollama URL, schema path, temperature, context length, and max workers. ```python from pathlib import Path from modules.extract_terms import run_extraction # Run extraction with Ollama result = run_extraction( pdf_dir=Path("./polymer_papers"), output_json=Path("./storage/terminology/extracted_terms.json"), model="qwen3:235b", backend="ollama", ollama_url="http://localhost:11434", schema_path="storage/schema/matkg_schema.yaml", temperature=0.0, context_length=50, max_workers=4, ) print(f"Extracted {result['unique_terms']} terms from {result['processed_files']} files") ``` -------------------------------- ### Organize and Process Research Papers in Python Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Use these functions to batch papers into checkpoint folders and execute the extraction pipeline across specified models. ```python organize_papers_into_folders( source_dir=Path("./all_papers"), output_root=Path("./polymer_papers"), papers_per_folder=25 ) ``` ```python run_checkpoint_pipeline( pdf_root=Path("./polymer_papers"), models=["google/gemini-flash-lite", "lbl/cborg-chat:latest"], dry_run=False ) ``` -------------------------------- ### Lookup Chemical Entities in ChEBI Ontology Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Use ChebiOboLookup to enrich chemical data by querying the ChEBI ontology. Load the ontology from a .obo file and then look up compounds by name or synonym to retrieve detailed information. ```python from modules.agents.chebi import ChebiOboLookup # Load ChEBI ontology chebi = ChebiOboLookup("./storage/ontologies/chebi.obo") # Lookup chemical by name or synonym result = chebi.lookup("methanol") # Returns: # { # "chebi_id": "CHEBI:17790", # "name": "methanol", # "definition": "The simplest alcohol...", # "synonyms": ["methyl alcohol", "wood alcohol", "MeOH"], # "formula": "CH4O", # "mass": "32.04186", # "charge": "0", # "inchi": "InChI=1S/CH4O/c1-2/h2H,1H3", # "inchikey": "OKKJLVBELUTLKV-UHFFFAOYSA-N", # "smiles": "CO", # "roles": ["CHEBI:33292"], # ChEBI role IDs # "parents": ["CHEBI:30879"], # "relationships": {...}, # "xrefs": {"CAS": ["67-56-1"], "KEGG": ["C00132"]} # } ``` ```python # Lookup P3HT monomer result = chebi.lookup("thiophene") if result: print(f"Formula: {result['formula']}, SMILES: {result['smiles']}") ``` -------------------------------- ### Link Interaction: Tooltips Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Configures mouseover events for links (associations) to display relationship details in a tooltip. ```javascript link.on("mouseover", (e,d) => { tooltip.style("display","block").style("left",(e.pageX+10)+"px").style("top",(e.pageY+10)+"px").html(` Relation: ${d.label}
Source: ${(d.source.label||d.source.id||d.source)}
Target: ${(d.target.label||d.target.id||d.target)} `); d3.select(e.currentTarget).attr("stroke","#ff0").attr("stroke-width",3); }).on("mouseout", (e,d) => { tooltip.style("display","none"); d3.select(e.currentTarget).attr("stroke","#0ff").attr("stroke-width",1); }); ``` -------------------------------- ### Orchestrate Pipeline Execution Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt The run_pipeline_cborg module provides functions to run checkpoint-based evaluation pipelines and organize research papers into folders for batch processing. ```python from pathlib import Path from run_pipeline_cborg import run_checkpoint_pipeline, organize_papers_into_folders ``` -------------------------------- ### Node Interaction: Tooltips and Dragging Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Configures mouseover events for nodes to display detailed tooltips and enable drag-and-drop functionality via the D3 simulation. ```javascript node.on("mouseover", (e,d) => { d3.select(e.currentTarget).transition().duration(200).attr("r", 12).attr("stroke", "#f0f").attr("stroke-width", 2); const props = d.properties.map(p => `
  • ${p.property}: ${p.value||'?'}
  • `).join(""); const snippets = d.context_snippets.map(s => `
  • ${s.text}
  • `).join(""); const papers = d.source_papers.map(s => `
  • ${s}
  • `).join(""); tooltip.style("display","block").style("left",(e.pageX+10)+"px").style("top",(e.pageY+10)+"px").html(` ${d.label}
    ${d.category}
    ID: ${d.id}
    Degree: ${degree[d.id]}

    ${d.description || ""}

    ${d.formula ? `

    Formula: ${d.formula}

    ` : ""} ${props ? "Properties:" : ""} ${papers ? "Source Papers:" : ""} ${snippets ? "Snippets:" : ""} `); }).on("mouseout", (e,d) => { d3.select(e.currentTarget).transition().duration(200).attr("r", 6).attr("fill", neonColors(degree[d.id] || 0)).attr("stroke", "#fff").attr("stroke-width", 0.5); tooltip.style("display","none"); }); ``` -------------------------------- ### Build Knowledge Graph from Raw Term Data Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Constructs a knowledge graph from a list of raw term dictionaries. The `build_graph` function processes the input data to create structured graph data. ```python raw_terms = [ { "term": "P3HT", "definition": "Poly(3-hexylthiophene), a conjugated polymer for OPVs", "category": "ConjugatedPolymer", "formula": "C10H14S", "formula_validation": {"status": "ok"}, "properties": [{"property": "band_gap", "value": 1.9, "unit": "eV"}], "relations": [ {"related_term": "organic photovoltaics", "relation": "has_application"} ] }, { "term": "PCBM", "definition": "Phenyl-C61-butyric acid methyl ester, a fullerene acceptor", "category": "ChemicalEntity", "formula": "C72H14O2", "relations": [ {"related_term": "P3HT", "relation": "blends_with"} ] } ] graph = build_graph(raw_terms) ``` -------------------------------- ### Generate Node ID and Ensure List Format Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Utility functions for creating unique node identifiers and ensuring data is in a list format. `make_id` generates a prefixed ID, and `ensure_list` converts single values or `None` into a list. ```python node_id = make_id("Bulk Heterojunction OPV") # Returns: "matkg:BulkHeterojunctionOPV" normalized = ensure_list(None) # Returns: [] normalized = ensure_list("single_value") # Returns: ["single_value"] ``` -------------------------------- ### D3.js Search with Live Suggestions Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Adds input event listeners to a search box to filter and display node suggestions. Suggestions are dynamically updated based on user input and limited to the first 20 matches. Clicking a suggestion highlights the node and updates the search box. ```javascript const searchBox = document.getElementById("searchBox"); const suggestions = document.getElementById("suggestions"); searchBox.addEventListener("input", () => { const val = searchBox.value.toLowerCase(); suggestions.innerHTML = ""; if (!val) { suggestions.style.display="none"; return; } const matches = nodes.filter(n => (n.label||"").toLowerCase().includes(val)); matches.slice(0,20).forEach(m => { const div = document.createElement("div"); div.textContent = m.label; div.onclick = () => { highlightNode(m); suggestions.style.display="none"; searchBox.value = m.label; }; suggestions.appendChild(div); }); suggestions.style.display = matches.length ? "block":"none"; }); ``` -------------------------------- ### Validate Terms with LinkML Schema Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt SchemaHelper loads LinkML schemas for validation and fuzzy matching of class and slot names. It aids in auto-correcting extracted terms and checking relation validity within the schema. ```python from modules.extract_terms import SchemaHelper # Load schema schema = SchemaHelper( schema_path="./storage/schema/matkg_schema.yaml", fuzzy_cutoff=80 # RapidFuzz score threshold ) # Get schema context for LLM prompts context = schema.get_schema_context_for_llm() # Returns formatted string with entity types and valid relationships # Validate and fix a term term_data = { "term": "P3HT", "category": "conjugated polymer", # Fuzzy match to "ConjugatedPolymer" "relations": [ {"relation": "has_applications", "related_term": "OPV"} # May need correction ] } fixed = schema.validate_and_fix_term(term_data) # Category corrected to "ConjugatedPolymer", relations validated # Check relation validity is_valid = schema.check_relation_validity( subj_cls="Material", pred="has_property", obj_cls="MaterialProperty" ) ``` -------------------------------- ### Extract and Normalize Physical Properties Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Use PhysicalPropertyExtractor to find property mentions in text and PropertyNormalizer to standardize them to common units. The extractor can identify properties associated with specified materials. ```python from modules.agents.properties import PhysicalPropertyExtractor, PropertyNormalizer extractor = PhysicalPropertyExtractor() normalizer = PropertyNormalizer() # Extract properties from text text = """ The Na3Bi film exhibited a band gap of 1.9 ± 0.1 eV at room temperature. The density of P3HT is 1.1 g/cm3. The mobility reached 0.1 cm2/Vs. """ # Extract raw property mentions raw_props = extractor.extract(text, materials=["Na3Bi", "P3HT"]) # Returns: # [ # {"material": "Na3Bi", "property": "band_gap", "raw_value": "1.9", # "raw_unit": "eV", "uncertainty": "0.1", "context": "...", "verified": True}, # {"material": "P3HT", "property": "density", "raw_value": "1.1", # "raw_unit": "g/cm3", "uncertainty": None, "context": "...", "verified": True} # ] ``` ```python # Normalize to standard units normalized = normalizer.normalize(raw_props) # Returns entries with added fields: # { # ..., # "normalized_value": 1100.0, # kg/m3 for density # "normalized_unit": "kg/m3", # "uncertainty_value": None, # "unit_conversion_failed": False # } ``` ```python # Extract from term relations term_record = { "term": "P3HT", "relations": [ {"relation": "measured_property", "related_term": "band gap", "verified": True} ] } rel_props = extractor.extract_from_relations(term_record) ``` -------------------------------- ### D3.js Pathfinding: Node Selection Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Enables selecting up to two nodes for pathfinding. Selected nodes are visually highlighted with a yellow stroke. Once two nodes are selected, the `highlightPath` function is called. ```javascript let selected = []; node.on("click", (event, d) => { if (selected.length < 2) { selected.push(d); d3.select(event.currentTarget).attr("stroke","#ff0").attr("stroke-width",3); if (selected.length === 2) highlightPath(selected[0], selected[1]); } event.stopPropagation(); }); ``` -------------------------------- ### D3.js Force Simulation Configuration Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Defines the forces (link, charge, center) for the D3 simulation and specifies the 'tick' event handler for updating element positions. ```javascript function simulation() { return d3.forceSimulation(nodes).force("link", d3.forceLink(links).id(d => d.id).distance(100)).force("charge", d3.forceManyBody().strength(-80)).force("center", d3.forceCenter(width/2, height/2)).on("tick", ticked); } ``` -------------------------------- ### Load and Process Graph Data Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Fetches JSON data and transforms it into nodes and links suitable for D3.js visualization. Initializes degree counts for nodes. ```javascript (async function() { const raw = await fetch("matkg_qwen3_235b_580papers.json").then(r => r.json()); const nodes = raw.things.map(t => ({ id: t.id, label: t.label, category: t.category, description: t.description, context_snippets: t.context_snippets || [], source_papers: t.source_papers || [], formula: t.formula || "", properties: t.properties || [] })); const links = raw.associations.map(a => ({ source: a.subject, target: a.object, label: a.predicate })); const degree = {}; nodes.forEach(n => { degree[n.id] = 0; }); links.forEach(l => { degree[l.source]++; degree[l.target]++; }); ``` -------------------------------- ### Convert Extracted Terms to Knowledge Graph Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt Converts extracted terms from a JSON file into a knowledge graph format compatible with MatKG. This process creates nodes (things) and edges (associations) based on the extracted terminology and relationships. ```python from pathlib import Path from modules.json2kg import build_graph, convert_terms_to_graph, make_id, ensure_list # Convert extracted terms to knowledge graph graph = convert_terms_to_graph( input_json=Path("./storage/terminology/extracted_terms.json"), output_json=Path("./storage/kg/matkg_output.json") ) print(f"Graph contains {len(graph['things'])} nodes and {len(graph['associations'])} edges") ``` -------------------------------- ### D3.js Drag Behavior Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Implements drag-and-drop functionality for nodes within the D3 force simulation. ```javascript function drag(sim) { function dragstarted(e ``` -------------------------------- ### D3.js Simulation Tick Handler Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Updates the positions of links and nodes on each tick of the D3 force simulation. ```javascript function ticked() { link.attr("x1", d => d.source.x).attr("y1", d => d.source.y).attr("x2", d => d.target.x).attr("y2", d => d.target.y); node.attr("cx", d => d.x).attr("cy", d => d.y); } ``` -------------------------------- ### Validate Chemical Formulas with pymatgen Source: https://context7.com/fair2wise/fairtowise-forum-ai/llms.txt The ChemicalFormulaValidator validates chemical formulas. Initialize with an optional Materials Project API key for enhanced validation. It returns the canonical form, Materials Project hits, and status. ```python from modules.agents.chem_checker import ChemicalFormulaValidator # Initialize with Materials Project API key for enhanced validation validator = ChemicalFormulaValidator(api_key="your-mp-api-key") # Validate a formula result = validator.validate("C10H14S") # Returns: # { # "input": "C10H14S", # "canonical": "C10 H14 S1", # Hill-ordered # "mp_hits": 3, # Materials found in MP database # "status": "ok", # "error": None # } ``` ```python # Invalid formula result = validator.validate("XYZ123") # Returns: # { # "input": "XYZ123", # "canonical": None, # "mp_hits": -1, # "status": "invalid", # "error": "parse-error: ..." # } ``` ```python # Formula with correction result = validator.validate("H2O") # Returns: {"status": "ok", "canonical": "H2 O1", ...} ``` -------------------------------- ### D3.js Node Highlighting and View Focus Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Highlights a selected node by changing its stroke color and width. It then smoothly transitions the SVG view to focus on the highlighted node, applying a zoom transform. ```javascript function highlightNode(target) { node.attr("stroke", d => d.id === target.id ? "#ff0":"#fff") .attr("stroke-width", d => d.id === target.id ? 3:0.5); const scale = 2; const transform = d3.zoomIdentity .translate(width/2 - target.x * scale, height/2 - target.y * scale) .scale(scale); svg.transition().duration(750).call(zoom.transform, transform); } ``` -------------------------------- ### D3.js Pathfinding: Consecutive Link Check Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Helper function to determine if a link is part of a given path. It checks if the source and target of the link appear consecutively in the path array. ```javascript function isConsecutive(path,a,b) { for (let i=0;i { hideWeak = !hideWeak; node.attr("display", d => hideWeak && degree[d.id] < 2 ? "none":"block"); link.attr("display", d => hideWeak && (degree[d.source.id||d.source] < 2 || degree[d.target.id||d.target] < 2) ? "none":"block"); }; ``` -------------------------------- ### D3.js Graph Isolation Logic Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Implements the logic to isolate a node and its neighbors. It identifies all neighbors, then sets the display property of nodes and links to hide elements not part of the isolated subgraph. ```javascript function isolateNode(center) { const neighbors = new Set(); links.forEach(l => { if (l.source.id === center.id || l.source === center.id) neighbors.add(l.target.id||l.target); if (l.target.id === center.id || l.target === center.id) neighbors.add(l.source.id||l.source); }); neighbors.add(center.id); node.attr("display", n => neighbors.has(n.id) ? "block":"none"); link.attr("display", l => (neighbors.has(l.source.id||l.source) && neighbors.has(l.target.id||l.target)) ? "block":"none"); isolated = true; } ``` -------------------------------- ### D3.js Node Isolation on Double Click Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Handles double-click events on nodes to isolate them, showing only the clicked node and its immediate neighbors. A click on the SVG background resets the graph if it was previously isolated. ```javascript let isolated = false; node.on("dblclick", (event, d) => { event.stopPropagation(); isolateNode(d); }); svg.on("click", () => { if (isolated) resetGraph(); }); ``` -------------------------------- ### D3.js Zoom and Pan Behavior Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Configures zoom and pan behavior for a D3.js SVG element. The scale extent is limited to prevent excessive zooming in or out. The zoom event updates the group's transform attribute. ```javascript const zoom = d3.zoom().scaleExtent([0.1,5]).on("zoom", e => { g.attr("transform", e.transform); }); svg.call(zoom); ``` -------------------------------- ### D3.js Graph Reset Functionality Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Resets the graph view to its default state. This includes resetting node strokes, link styles, clearing selections, and applying the default zoom transform. ```javascript document.getElementById("resetBtn").onclick = () => { resetGraph(); node.attr("stroke","#fff").attr("stroke-width",0.5); link.attr("class","link").attr("stroke","#0ff").attr("stroke-width",1); selected = []; svg.transition().duration(750).call(zoom.transform, d3.zoomIdentity); }; ``` -------------------------------- ### D3.js Graph Reset Function (Isolation) Source: https://github.com/fair2wise/fairtowise-forum-ai/blob/main/storage/kg/view_kg.html Resets the graph display to show all nodes and links, effectively disabling the isolation mode. This is called after isolating nodes or when clicking the background after isolation. ```javascript function resetGraph() { node.attr("display","block"); link.attr("display","block"); isolated = false; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.