Spaces:
Sleeping
Sleeping
File size: 12,161 Bytes
f368eec |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
"""Drug-Drug Interaction Processor for analyzing and processing drug interactions."""
import re
import networkx as nx
import matplotlib.pyplot as plt
from typing import List, Dict, Tuple, Optional
from .biomedical_llm import BiomedicalLLM
from .drug_interaction_db import DrugInteractionDatabase
class DDIProcessor:
def __init__(self, db: DrugInteractionDatabase, bio_llm: BiomedicalLLM):
self.db = db
self.bio_llm = bio_llm
def extract_drug_names(self, text):
"""Extract potential drug names from text using NLP techniques"""
# In a real implementation, this would use advanced NLP
# For now, we'll use a simple approach based on keywords and patterns
# Clean and standardize text
text = text.lower()
# Common question patterns
patterns = [
r"can\s+i\s+take\s+(.+?)\s+(?:and|with|along\s+with)\s+(.+?)(?:\?|$)",
r"is\s+it\s+safe\s+to\s+take\s+(.+?)\s+(?:and|with|along\s+with)\s+(.+?)(?:\?|$)",
r"(?:interaction|interactions)\s+between\s+(.+?)\s+and\s+(.+?)(?:\?|$)",
r"(?:will|does|do)\s+(.+?)\s+(?:interact|interfere)\s+with\s+(.+?)(?:\?|$)"
]
for pattern in patterns:
match = re.search(pattern, text)
if match:
drug1 = match.group(1).strip()
drug2 = match.group(2).strip()
return drug1, drug2
# If no pattern matches, try to find drug names from the database
words = text.split()
potential_drugs = []
for word in words:
word = word.strip(".,?!()[]{}\"'")
if self.db.search_drug(word):
potential_drugs.append(word)
if len(potential_drugs) >= 2:
return potential_drugs[0], potential_drugs[1]
return None, None
def extract_drugs_from_clinical_notes(self, clinical_text):
"""Use BiomedLM to extract drugs from clinical notes"""
try:
# Use the biomedical LLM to extract drugs and interactions
result = self.bio_llm.analyze_clinical_notes(clinical_text)
# Return the extracted medications
return result
except Exception as e:
print(f"Error extracting drugs from clinical notes: {e}")
return {"medications": [], "potential_interactions": []}
def process_query(self, query):
"""Process a natural language query about drug interactions"""
drug1, drug2 = self.extract_drug_names(query)
# If we couldn't extract drug names
if not drug1 or not drug2:
return {
"status": "error",
"message": "I couldn't identify the drugs in your question. Please specify the drugs clearly, for example: 'Can I take aspirin and warfarin together?'"
}
# Get drug interactions from database
interactions, missing = self.db.get_interactions(drug1, drug2)
# Try biomedical LLM for additional information, especially if not in database
try:
literature_info = self.bio_llm.extract_ddi_from_literature(drug1, drug2)
if "interactions" in literature_info and literature_info["interactions"]:
# Convert LLM information to the format used by the database
for interaction in literature_info["interactions"]:
# Only add if we don't already have interactions from the database
if not interactions:
canonical1 = self.db.search_drug(drug1) or drug1
canonical2 = self.db.search_drug(drug2) or drug2
desc = interaction.get("description", f"Potential interaction between {drug1} and {drug2}")
severity = interaction.get("severity", "Unknown")
source = interaction.get("evidence", "Biomedical literature analysis")
interactions.append((canonical1, canonical2, desc, severity, source))
# Clear missing drugs if LLM found information
if missing and interactions:
missing = []
except Exception as e:
print(f"Error getting additional information: {e}")
# If drugs weren't found
if missing:
return {
"status": "not_found",
"missing_drugs": missing,
"message": f"I couldn't find information on the following drug(s): {', '.join(missing)}"
}
# Format the results
canonical1 = self.db.search_drug(drug1) or drug1
canonical2 = self.db.search_drug(drug2) or drug2
if not interactions:
return {
"status": "no_interaction",
"drugs": [canonical1, canonical2],
"message": f"No known interactions were found between {canonical1} and {canonical2} in our database or medical literature. However, please consult with a healthcare professional for personalized advice."
}
# Format the interaction information
interaction_details = []
for d1, d2, desc, severity, source in interactions:
interaction_details.append({
"description": desc,
"severity": severity,
"source": source
})
return {
"status": "found",
"drugs": [canonical1, canonical2],
"interactions": interaction_details
}
def get_drug_information(self, drug_name):
"""Get comprehensive information about a drug using biomedical LLM"""
try:
# First check if the drug exists in our database
canonical = self.db.search_drug(drug_name)
if not canonical:
# If not in database, use just the provided name
canonical = drug_name
# Use biomedical LLM to get drug information
drug_info = self.bio_llm.get_drug_information(canonical)
# Add interactions from our database
interactions, _ = self.db.get_all_interactions(canonical)
interaction_drugs = []
for d1, d2, _, severity, _ in interactions:
other_drug = d2 if d1 == canonical else d1
interaction_drugs.append(f"{other_drug} ({severity})")
# Add to the drug information
if interaction_drugs and "common_interactions" in drug_info:
# Combine with LLM-provided interactions
existing = drug_info["common_interactions"]
if existing and existing[0] != "Information not available":
drug_info["common_interactions"] = list(set(existing + interaction_drugs))
else:
drug_info["common_interactions"] = interaction_drugs
return drug_info
except Exception as e:
print(f"Error getting drug information: {e}")
return {
"drug_name": drug_name,
"drug_class": "Information not available",
"mechanism": "Information not available",
"indications": ["Information not available"],
"side_effects": ["Information not available"],
"common_interactions": ["Information not available"],
"contraindications": ["Information not available"]
}
def generate_network(self, drug_name=None, depth=1):
"""
Generate a network visualization of drug interactions
If drug_name is provided, show interactions for that drug
Otherwise, show a general interaction network
"""
G = nx.Graph()
# If a specific drug is provided
if drug_name:
canonical = self.db.search_drug(drug_name)
if not canonical:
return None, f"Drug '{drug_name}' not found"
# Get interactions for this drug
interactions, _ = self.db.get_all_interactions(canonical)
# Add nodes and edges
G.add_node(canonical, size=20, color='red')
for drug1, drug2, desc, severity, _ in interactions:
other_drug = drug2 if drug1 == canonical else drug1
# Add nodes and edges
if other_drug not in G:
G.add_node(other_drug, size=15, color='blue')
# Set edge color based on severity
if severity == "Severe":
edge_color = 'red'
weight = 3
elif severity == "Moderate":
edge_color = 'orange'
weight = 2
else:
edge_color = 'yellow'
weight = 1
G.add_edge(canonical, other_drug, color=edge_color, weight=weight, label=desc)
# If depth > 1, add secondary interactions
if depth > 1:
secondary_interactions, _ = self.db.get_all_interactions(other_drug)
for sec_d1, sec_d2, sec_desc, sec_severity, _ in secondary_interactions:
tertiary_drug = sec_d2 if sec_d1 == other_drug else sec_d1
# Skip the original drug
if tertiary_drug == canonical:
continue
if tertiary_drug not in G:
G.add_node(tertiary_drug, size=10, color='green')
# Set edge color based on severity
if sec_severity == "Severe":
sec_edge_color = 'red'
sec_weight = 3
elif sec_severity == "Moderate":
sec_edge_color = 'orange'
sec_weight = 2
else:
sec_edge_color = 'yellow'
sec_weight = 1
G.add_edge(other_drug, tertiary_drug, color=sec_edge_color, weight=sec_weight, label=sec_desc)
else:
# Create a general interaction network with common drugs
sample_drugs = self.db.get_all_drugs()[:10] # Limit to 10 drugs for clarity
for drug in sample_drugs:
G.add_node(drug, size=15, color='blue')
interactions, _ = self.db.get_all_interactions(drug)
for d1, d2, desc, severity, _ in interactions:
other_drug = d2 if d1 == drug else d1
# Only add edges between drugs in our sample
if other_drug in sample_drugs:
# Set edge color based on severity
if severity == "Severe":
edge_color = 'red'
weight = 3
elif severity == "Moderate":
edge_color = 'orange'
weight = 2
else:
edge_color = 'yellow'
weight = 1
G.add_edge(drug, other_drug, color=edge_color, weight=weight, label=desc)
return G, None |