CCockrum commited on
Commit
f66fd7a
Β·
verified Β·
1 Parent(s): 1347213

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +259 -129
app.py CHANGED
@@ -12,7 +12,7 @@ import plotly.graph_objects as go
12
  from transformers import pipeline
13
  import numpy as np
14
 
15
- class CancerResearchLiteratureMiner:
16
  def __init__(self):
17
  # Initialize NLP pipelines
18
  try:
@@ -23,24 +23,54 @@ class CancerResearchLiteratureMiner:
23
  self.summarizer = None
24
  self.classifier = None
25
 
26
- # Research categories for classification
27
- self.research_categories = [
28
- "drug discovery", "immunotherapy", "chemotherapy", "radiation therapy",
29
- "biomarkers", "diagnostics", "metastasis", "tumor microenvironment",
30
- "animal models", "preclinical studies", "toxicity", "pharmacokinetics"
 
 
31
  ]
32
 
33
- # Animal model keywords
34
- self.animal_keywords = [
35
- "mouse", "mice", "rat", "rats", "xenograft", "orthotopic", "transgenic",
36
- "knockout", "immunodeficient", "nude mice", "SCID", "NOD", "PDX",
37
- "patient-derived xenograft", "syngeneic", "canine", "dog", "feline", "cat"
 
 
 
38
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
- def search_pubmed(self, query: str, max_results: int = 50) -> List[Dict]:
41
- """Search PubMed for cancer research papers"""
42
- # Enhance query with animal model terms
43
- enhanced_query = f"({query}) AND (animal model OR mouse OR mice OR rat OR xenograft OR preclinical)"
44
 
45
  # Search PubMed
46
  search_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
@@ -123,19 +153,33 @@ class CancerResearchLiteratureMiner:
123
 
124
  return papers
125
 
126
- def analyze_papers(self, papers: List[Dict]) -> Dict:
127
- """Analyze the retrieved papers for insights"""
128
  if not papers or papers[0].get("error"):
129
  return {"error": "No papers to analyze"}
130
 
131
  analysis = {
132
  "total_papers": len(papers),
133
  "year_distribution": {},
134
- "animal_models": {},
135
- "research_categories": {},
136
- "key_findings": [],
 
137
  "drug_mentions": [],
138
- "methodology_trends": {}
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
 
141
  # Analyze each paper
@@ -144,42 +188,71 @@ class CancerResearchLiteratureMiner:
144
  year = paper.get("year", "Unknown")
145
  analysis["year_distribution"][year] = analysis["year_distribution"].get(year, 0) + 1
146
 
147
- # Analyze abstract for animal models and categories
 
 
 
 
148
  abstract = paper.get("abstract", "").lower()
149
  title = paper.get("title", "").lower()
150
  full_text = f"{title} {abstract}"
151
 
152
- # Animal model detection
153
- for animal in self.animal_keywords:
154
- if animal in full_text:
155
- analysis["animal_models"][animal] = analysis["animal_models"].get(animal, 0) + 1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
- # Extract drug mentions (simple regex for common drug patterns)
158
- drugs = re.findall(r'\b[A-Z][a-z]*(?:mab|nib|ine|ole|cin|tin)\b', paper.get("abstract", ""))
159
  analysis["drug_mentions"].extend(drugs)
160
 
161
  # Classify research category if classifier is available
162
  if self.classifier and abstract != "n/a":
163
  try:
164
- result = self.classifier(abstract[:512], self.research_categories)
165
  top_category = result["labels"][0]
166
- analysis["research_categories"][top_category] = analysis["research_categories"].get(top_category, 0) + 1
167
  except Exception:
168
  pass
169
 
170
  # Process drug mentions
171
  drug_counter = Counter(analysis["drug_mentions"])
172
- analysis["drug_mentions"] = dict(drug_counter.most_common(10))
173
 
174
  return analysis
175
 
176
- def generate_summary(self, papers: List[Dict], analysis: Dict) -> str:
177
- """Generate a comprehensive summary of findings"""
178
  if not papers or papers[0].get("error"):
179
  return "No papers found or error in retrieval."
180
 
181
  summary = f"""
182
- # Literature Mining Summary
183
 
184
  ## Overview
185
  - **Total Papers Found**: {analysis['total_papers']}
@@ -187,108 +260,143 @@ class CancerResearchLiteratureMiner:
187
 
188
  ## Key Insights
189
 
190
- ### Animal Models Used
191
  """
192
 
193
- # Top animal models
194
- if analysis["animal_models"]:
195
- top_models = sorted(analysis["animal_models"].items(), key=lambda x: x[1], reverse=True)[:5]
196
- for model, count in top_models:
197
- summary += f"- **{model.title()}**: {count} papers\n"
 
198
 
199
- summary += "\n### Research Focus Areas\n"
200
 
201
- # Research categories
202
- if analysis["research_categories"]:
203
- top_categories = sorted(analysis["research_categories"].items(), key=lambda x: x[1], reverse=True)[:5]
204
- for category, count in top_categories:
205
- summary += f"- **{category.title()}**: {count} papers\n"
 
206
 
207
- summary += "\n### Frequently Mentioned Drugs\n"
 
 
 
 
 
 
 
 
208
 
209
  # Drug mentions
210
  if analysis["drug_mentions"]:
211
- for drug, count in list(analysis["drug_mentions"].items())[:5]:
212
  summary += f"- **{drug}**: {count} mentions\n"
213
 
214
- summary += "\n### Recent Highlights\n"
 
 
 
 
 
 
215
 
216
- # Recent papers (last 2 years)
 
 
217
  current_year = datetime.now().year
218
- recent_papers = [p for p in papers if p.get("year", "").isdigit() and int(p["year"]) >= current_year - 2]
219
 
220
- for paper in recent_papers[:3]:
221
  summary += f"- **{paper.get('title', 'N/A')}** ({paper.get('year', 'N/A')})\n"
222
  summary += f" *{paper.get('journal', 'N/A')}*\n\n"
223
 
224
  return summary
225
 
226
- def create_visualizations(self, analysis: Dict):
227
- """Create visualization plots"""
228
  plots = {}
229
 
230
  # Year distribution
231
  if analysis["year_distribution"]:
232
- years = list(analysis["year_distribution"].keys())
233
- counts = list(analysis["year_distribution"].values())
234
 
235
- fig_year = px.bar(
236
  x=years, y=counts,
237
- title="Publication Year Distribution",
238
- labels={"x": "Year", "y": "Number of Papers"}
 
239
  )
 
240
  plots["year_dist"] = fig_year
241
 
242
- # Animal models
243
- if analysis["animal_models"]:
244
- models = list(analysis["animal_models"].keys())[:10]
245
- model_counts = [analysis["animal_models"][m] for m in models]
 
246
 
247
- fig_models = px.bar(
248
- x=model_counts, y=models,
249
  orientation='h',
250
- title="Most Common Animal Models",
251
- labels={"x": "Number of Papers", "y": "Animal Model"}
252
  )
253
- plots["animal_models"] = fig_models
254
 
255
- # Research categories
256
- if analysis["research_categories"]:
257
- categories = list(analysis["research_categories"].keys())
258
- cat_counts = list(analysis["research_categories"].values())
 
259
 
260
- fig_categories = px.pie(
261
- values=cat_counts, names=categories,
262
- title="Research Focus Distribution"
263
  )
264
- plots["categories"] = fig_categories
 
 
 
 
 
 
 
 
 
 
 
 
 
265
 
266
  return plots
267
 
268
- def create_gradio_interface():
269
- """Create the Gradio interface"""
270
- miner = CancerResearchLiteratureMiner()
271
 
272
- def search_and_analyze(query, max_results):
273
- """Main function to search and analyze literature"""
274
  if not query.strip():
275
- return "Please enter a search query.", None, None, None, None
276
 
277
  # Search papers
278
- papers = miner.search_pubmed(query, max_results)
279
 
280
  if not papers or papers[0].get("error"):
281
  error_msg = papers[0].get("error", "No papers found") if papers else "No papers found"
282
- return f"Error: {error_msg}", None, None, None, None
283
 
284
  # Analyze papers
285
- analysis = miner.analyze_papers(papers)
286
 
287
  # Generate summary
288
- summary = miner.generate_summary(papers, analysis)
289
 
290
  # Create visualizations
291
- plots = miner.create_visualizations(analysis)
292
 
293
  # Create papers dataframe
294
  papers_df = pd.DataFrame([
@@ -306,98 +414,120 @@ def create_gradio_interface():
306
  summary,
307
  papers_df,
308
  plots.get("year_dist"),
309
- plots.get("animal_models"),
310
- plots.get("categories")
 
311
  )
312
 
313
  # Create interface
314
- with gr.Blocks(title="Veterinary Oncology Assistant", theme=gr.themes.Soft()) as interface:
315
  gr.Markdown("""
316
- # Veterinary Oncology Assistant
317
 
318
- This AI agent searches and analyzes scientific literature related to cancer research in animal models.
319
- It automatically extracts insights about animal models used, research focus areas, and emerging trends.
320
 
321
  **Features:**
322
- - PubMed literature search with animal model focus
323
- - Automatic categorization of research areas
324
- - Drug mention extraction
325
- - Publication trend analysis
326
  - Interactive visualizations
 
327
  """)
328
 
329
  with gr.Row():
330
  with gr.Column(scale=2):
331
  query_input = gr.Textbox(
332
  label="Research Query",
333
- placeholder="e.g., 'breast cancer immunotherapy', 'lung cancer biomarkers', 'pancreatic cancer treatment'",
334
  lines=2
335
  )
336
- max_results = gr.Slider(
337
- minimum=10, maximum=100, value=50, step=10,
338
- label="Maximum Results"
339
- )
340
- search_btn = gr.Button("πŸ” Search & Analyze Literature", variant="primary")
 
 
 
 
 
 
341
 
342
  with gr.Column(scale=1):
343
  gr.Markdown("""
344
- ### Tips for Better Results:
345
- - Use specific cancer types (e.g., "breast cancer", "melanoma")
346
- - Include treatment modalities (e.g., "immunotherapy", "chemotherapy")
347
- - Add animal model terms (e.g., "mouse model", "xenograft")
 
 
348
  """)
349
 
350
  with gr.Tabs():
351
- with gr.TabItem("Summary & Insights"):
352
- summary_output = gr.Markdown(label="Analysis Summary")
353
 
354
- with gr.TabItem("Papers Found"):
355
  papers_output = gr.Dataframe(
356
  headers=["PMID", "Title", "Authors", "Journal", "Year"],
357
- label="Retrieved Papers"
358
  )
359
 
360
- with gr.TabItem("Visualizations"):
361
  with gr.Row():
362
  year_plot = gr.Plot(label="Publication Timeline")
363
- models_plot = gr.Plot(label="Animal Models")
364
  with gr.Row():
365
- categories_plot = gr.Plot(label="Research Categories")
 
366
 
367
  # Connect the search function
368
  search_btn.click(
369
- search_and_analyze,
370
- inputs=[query_input, max_results],
371
- outputs=[summary_output, papers_output, year_plot, models_plot, categories_plot]
372
  )
373
 
374
  # Add examples
375
  gr.Examples(
376
  examples=[
377
- ["breast cancer immunotherapy mouse model", 50],
378
- ["lung cancer biomarkers xenograft", 30],
379
- ["pancreatic cancer treatment PDX", 40],
380
- ["melanoma drug resistance animal model", 35]
 
 
 
 
381
  ],
382
- inputs=[query_input, max_results]
383
  )
384
 
385
  gr.Markdown("""
386
- ### About This Agent
387
- This literature mining agent is specifically designed for cancer research in animal models.
388
- It searches PubMed for relevant papers and provides automated analysis of research trends,
389
- commonly used animal models, and emerging therapeutic approaches.
 
 
 
 
 
 
 
390
 
391
- **Data Sources:** PubMed/NCBI databases
392
  **Last Updated:** June 2025
393
- **Supported Research Areas:** All cancer types and animal models
394
  """)
395
 
396
  return interface
397
 
398
  # Create and launch the interface
399
  if __name__ == "__main__":
400
- interface = create_gradio_interface()
401
  interface.launch(
402
  server_name="0.0.0.0",
403
  server_port=7860,
 
12
  from transformers import pipeline
13
  import numpy as np
14
 
15
+ class VeterinaryLiteratureMiner:
16
  def __init__(self):
17
  # Initialize NLP pipelines
18
  try:
 
23
  self.summarizer = None
24
  self.classifier = None
25
 
26
+ # Veterinary research categories for classification
27
+ self.veterinary_categories = [
28
+ "oncology", "cardiology", "dermatology", "neurology", "orthopedics",
29
+ "infectious diseases", "parasitology", "pharmacology", "toxicology",
30
+ "surgery", "anesthesia", "emergency medicine", "internal medicine",
31
+ "pathology", "radiology", "nutrition", "behavior", "reproduction",
32
+ "public health", "zoonoses", "immunology", "genetics", "epidemiology"
33
  ]
34
 
35
+ # Animal species categories
36
+ self.animal_species = [
37
+ "canine", "dog", "dogs", "feline", "cat", "cats", "equine", "horse", "horses",
38
+ "bovine", "cattle", "cow", "cows", "porcine", "pig", "pigs", "swine",
39
+ "ovine", "sheep", "caprine", "goat", "goats", "avian", "bird", "birds",
40
+ "poultry", "chicken", "chickens", "rabbit", "rabbits", "ferret", "ferrets",
41
+ "reptile", "reptiles", "fish", "aquatic", "wildlife", "zoo", "exotic",
42
+ "laboratory animals", "mouse", "mice", "rat", "rats"
43
  ]
44
+
45
+ # Veterinary specialties and procedures
46
+ self.vet_procedures = [
47
+ "vaccination", "spay", "neuter", "castration", "ovariohysterectomy",
48
+ "amputation", "biopsy", "endoscopy", "laparoscopy", "arthroscopy",
49
+ "radiography", "ultrasound", "CT", "MRI", "chemotherapy", "radiation",
50
+ "physical therapy", "rehabilitation", "dental", "ophthalmology"
51
+ ]
52
+
53
+ # Common veterinary conditions
54
+ self.vet_conditions = [
55
+ "diabetes", "epilepsy", "heart disease", "kidney disease", "liver disease",
56
+ "arthritis", "hip dysplasia", "allergies", "skin disease", "cancer",
57
+ "tumor", "infection", "parasite", "heartworm", "flea", "tick",
58
+ "obesity", "dental disease", "cataracts", "glaucoma", "IBD"
59
+ ]
60
+
61
+ def search_veterinary_literature(self, query: str, max_results: int = 50, database: str = "pubmed") -> List[Dict]:
62
+ """Search veterinary literature across multiple databases"""
63
+
64
+ if database == "pubmed":
65
+ return self._search_pubmed(query, max_results)
66
+ else:
67
+ # Future: Could add other veterinary databases here
68
+ return self._search_pubmed(query, max_results)
69
 
70
+ def _search_pubmed(self, query: str, max_results: int) -> List[Dict]:
71
+ """Search PubMed for veterinary papers"""
72
+ # Enhance query with veterinary terms
73
+ enhanced_query = f"({query}) AND (veterinary OR animal OR pet OR livestock OR zoo OR wildlife)"
74
 
75
  # Search PubMed
76
  search_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
 
153
 
154
  return papers
155
 
156
+ def analyze_veterinary_papers(self, papers: List[Dict]) -> Dict:
157
+ """Analyze the retrieved veterinary papers for insights"""
158
  if not papers or papers[0].get("error"):
159
  return {"error": "No papers to analyze"}
160
 
161
  analysis = {
162
  "total_papers": len(papers),
163
  "year_distribution": {},
164
+ "animal_species": {},
165
+ "veterinary_specialties": {},
166
+ "common_conditions": {},
167
+ "procedures_mentioned": {},
168
  "drug_mentions": [],
169
+ "journal_distribution": {},
170
+ "research_trends": {}
171
+ }
172
+
173
+ # Keywords for different categories
174
+ specialty_keywords = {
175
+ "oncology": ["cancer", "tumor", "oncology", "chemotherapy", "radiation"],
176
+ "cardiology": ["heart", "cardiac", "cardiology", "arrhythmia", "murmur"],
177
+ "dermatology": ["skin", "dermatology", "allergy", "dermatitis", "eczema"],
178
+ "neurology": ["brain", "neurological", "seizure", "epilepsy", "paralysis"],
179
+ "orthopedics": ["bone", "joint", "fracture", "orthopedic", "lameness"],
180
+ "infectious_diseases": ["infection", "bacteria", "virus", "antibiotic", "pathogen"],
181
+ "surgery": ["surgical", "surgery", "operative", "laparoscopy", "endoscopy"],
182
+ "internal_medicine": ["diabetes", "kidney", "liver", "endocrine", "metabolic"]
183
  }
184
 
185
  # Analyze each paper
 
188
  year = paper.get("year", "Unknown")
189
  analysis["year_distribution"][year] = analysis["year_distribution"].get(year, 0) + 1
190
 
191
+ # Journal distribution
192
+ journal = paper.get("journal", "Unknown")
193
+ analysis["journal_distribution"][journal] = analysis["journal_distribution"].get(journal, 0) + 1
194
+
195
+ # Analyze abstract and title
196
  abstract = paper.get("abstract", "").lower()
197
  title = paper.get("title", "").lower()
198
  full_text = f"{title} {abstract}"
199
 
200
+ # Animal species detection
201
+ for species in self.animal_species:
202
+ if species in full_text:
203
+ species_key = species.replace(" ", "_")
204
+ analysis["animal_species"][species_key] = analysis["animal_species"].get(species_key, 0) + 1
205
+
206
+ # Veterinary specialty detection
207
+ for specialty, keywords in specialty_keywords.items():
208
+ for keyword in keywords:
209
+ if keyword in full_text:
210
+ analysis["veterinary_specialties"][specialty] = analysis["veterinary_specialties"].get(specialty, 0) + 1
211
+ break
212
+
213
+ # Common conditions detection
214
+ for condition in self.vet_conditions:
215
+ if condition in full_text:
216
+ analysis["common_conditions"][condition] = analysis["common_conditions"].get(condition, 0) + 1
217
+
218
+ # Procedures detection
219
+ for procedure in self.vet_procedures:
220
+ if procedure in full_text:
221
+ analysis["procedures_mentioned"][procedure] = analysis["procedures_mentioned"].get(procedure, 0) + 1
222
+
223
+ # Extract drug mentions (veterinary drugs and general pharmaceuticals)
224
+ drugs = re.findall(r'\b[A-Z][a-z]*(?:mab|nib|ine|ole|cin|tin|zole|pril|sartan)\b', paper.get("abstract", ""))
225
+ # Add common veterinary drugs
226
+ vet_drugs = ["prednisolone", "dexamethasone", "amoxicillin", "cephalexin", "enrofloxacin",
227
+ "tramadol", "gabapentin", "furosemide", "enalapril", "pimobendan"]
228
+ for drug in vet_drugs:
229
+ if drug in full_text:
230
+ drugs.append(drug.title())
231
 
 
 
232
  analysis["drug_mentions"].extend(drugs)
233
 
234
  # Classify research category if classifier is available
235
  if self.classifier and abstract != "n/a":
236
  try:
237
+ result = self.classifier(abstract[:512], self.veterinary_categories)
238
  top_category = result["labels"][0]
239
+ analysis["research_trends"][top_category] = analysis["research_trends"].get(top_category, 0) + 1
240
  except Exception:
241
  pass
242
 
243
  # Process drug mentions
244
  drug_counter = Counter(analysis["drug_mentions"])
245
+ analysis["drug_mentions"] = dict(drug_counter.most_common(15))
246
 
247
  return analysis
248
 
249
+ def generate_veterinary_summary(self, papers: List[Dict], analysis: Dict) -> str:
250
+ """Generate a comprehensive summary of veterinary literature findings"""
251
  if not papers or papers[0].get("error"):
252
  return "No papers found or error in retrieval."
253
 
254
  summary = f"""
255
+ # Veterinary Literature Mining Summary
256
 
257
  ## Overview
258
  - **Total Papers Found**: {analysis['total_papers']}
 
260
 
261
  ## Key Insights
262
 
263
+ ### Most Studied Animal Species
264
  """
265
 
266
+ # Top animal species
267
+ if analysis["animal_species"]:
268
+ top_species = sorted(analysis["animal_species"].items(), key=lambda x: x[1], reverse=True)[:8]
269
+ for species, count in top_species:
270
+ formatted_species = species.replace("_", " ").title()
271
+ summary += f"- **{formatted_species}**: {count} papers\n"
272
 
273
+ summary += "\n### Veterinary Specialties Focus\n"
274
 
275
+ # Veterinary specialties
276
+ if analysis["veterinary_specialties"]:
277
+ top_specialties = sorted(analysis["veterinary_specialties"].items(), key=lambda x: x[1], reverse=True)[:6]
278
+ for specialty, count in top_specialties:
279
+ formatted_specialty = specialty.replace("_", " ").title()
280
+ summary += f"- **{formatted_specialty}**: {count} papers\n"
281
 
282
+ summary += "\n### Common Conditions Studied\n"
283
+
284
+ # Common conditions
285
+ if analysis["common_conditions"]:
286
+ top_conditions = sorted(analysis["common_conditions"].items(), key=lambda x: x[1], reverse=True)[:8]
287
+ for condition, count in top_conditions:
288
+ summary += f"- **{condition.title()}**: {count} papers\n"
289
+
290
+ summary += "\n### Frequently Mentioned Treatments/Drugs\n"
291
 
292
  # Drug mentions
293
  if analysis["drug_mentions"]:
294
+ for drug, count in list(analysis["drug_mentions"].items())[:8]:
295
  summary += f"- **{drug}**: {count} mentions\n"
296
 
297
+ summary += "\n### Top Veterinary Journals\n"
298
+
299
+ # Journal distribution
300
+ if analysis["journal_distribution"]:
301
+ top_journals = sorted(analysis["journal_distribution"].items(), key=lambda x: x[1], reverse=True)[:5]
302
+ for journal, count in top_journals:
303
+ summary += f"- **{journal}**: {count} papers\n"
304
 
305
+ summary += "\n### Recent Research Highlights\n"
306
+
307
+ # Recent papers (last 3 years)
308
  current_year = datetime.now().year
309
+ recent_papers = [p for p in papers if p.get("year", "").isdigit() and int(p["year"]) >= current_year - 3]
310
 
311
+ for paper in recent_papers[:4]:
312
  summary += f"- **{paper.get('title', 'N/A')}** ({paper.get('year', 'N/A')})\n"
313
  summary += f" *{paper.get('journal', 'N/A')}*\n\n"
314
 
315
  return summary
316
 
317
+ def create_veterinary_visualizations(self, analysis: Dict):
318
+ """Create visualization plots for veterinary data"""
319
  plots = {}
320
 
321
  # Year distribution
322
  if analysis["year_distribution"]:
323
+ years = [y for y in analysis["year_distribution"].keys() if y.isdigit()]
324
+ counts = [analysis["year_distribution"][y] for y in years]
325
 
326
+ fig_year = px.line(
327
  x=years, y=counts,
328
+ title="Veterinary Research Publications Over Time",
329
+ labels={"x": "Year", "y": "Number of Papers"},
330
+ markers=True
331
  )
332
+ fig_year.update_layout(showlegend=False)
333
  plots["year_dist"] = fig_year
334
 
335
+ # Animal species
336
+ if analysis["animal_species"]:
337
+ species = list(analysis["animal_species"].keys())[:12]
338
+ species_counts = [analysis["animal_species"][s] for s in species]
339
+ formatted_species = [s.replace("_", " ").title() for s in species]
340
 
341
+ fig_species = px.bar(
342
+ x=species_counts, y=formatted_species,
343
  orientation='h',
344
+ title="Most Studied Animal Species",
345
+ labels={"x": "Number of Papers", "y": "Species"}
346
  )
347
+ plots["animal_species"] = fig_species
348
 
349
+ # Veterinary specialties
350
+ if analysis["veterinary_specialties"]:
351
+ specialties = list(analysis["veterinary_specialties"].keys())
352
+ spec_counts = list(analysis["veterinary_specialties"].values())
353
+ formatted_specialties = [s.replace("_", " ").title() for s in specialties]
354
 
355
+ fig_specialties = px.pie(
356
+ values=spec_counts, names=formatted_specialties,
357
+ title="Veterinary Specialty Distribution"
358
  )
359
+ plots["specialties"] = fig_specialties
360
+
361
+ # Common conditions
362
+ if analysis["common_conditions"]:
363
+ conditions = list(analysis["common_conditions"].keys())[:10]
364
+ condition_counts = [analysis["common_conditions"][c] for c in conditions]
365
+
366
+ fig_conditions = px.bar(
367
+ x=[c.title() for c in conditions], y=condition_counts,
368
+ title="Most Commonly Studied Conditions",
369
+ labels={"x": "Condition", "y": "Number of Papers"}
370
+ )
371
+ fig_conditions.update_xaxes(tickangle=45)
372
+ plots["conditions"] = fig_conditions
373
 
374
  return plots
375
 
376
+ def create_veterinary_gradio_interface():
377
+ """Create the Gradio interface for veterinary literature mining"""
378
+ miner = VeterinaryLiteratureMiner()
379
 
380
+ def search_and_analyze_vet(query, max_results, database):
381
+ """Main function to search and analyze veterinary literature"""
382
  if not query.strip():
383
+ return "Please enter a search query.", None, None, None, None, None
384
 
385
  # Search papers
386
+ papers = miner.search_veterinary_literature(query, max_results, database)
387
 
388
  if not papers or papers[0].get("error"):
389
  error_msg = papers[0].get("error", "No papers found") if papers else "No papers found"
390
+ return f"Error: {error_msg}", None, None, None, None, None
391
 
392
  # Analyze papers
393
+ analysis = miner.analyze_veterinary_papers(papers)
394
 
395
  # Generate summary
396
+ summary = miner.generate_veterinary_summary(papers, analysis)
397
 
398
  # Create visualizations
399
+ plots = miner.create_veterinary_visualizations(analysis)
400
 
401
  # Create papers dataframe
402
  papers_df = pd.DataFrame([
 
414
  summary,
415
  papers_df,
416
  plots.get("year_dist"),
417
+ plots.get("animal_species"),
418
+ plots.get("specialties"),
419
+ plots.get("conditions")
420
  )
421
 
422
  # Create interface
423
+ with gr.Blocks(title="Veterinary Literature Mining Agent", theme=gr.themes.Soft()) as interface:
424
  gr.Markdown("""
425
+ # 🐾 Veterinary Literature Mining Agent
426
 
427
+ This AI agent searches and analyzes veterinary and animal health literature across all specialties.
428
+ It automatically extracts insights about animal species, veterinary specialties, common conditions, and treatment trends.
429
 
430
  **Features:**
431
+ - Comprehensive veterinary literature search
432
+ - Multi-species analysis (companion animals, livestock, wildlife, exotics)
433
+ - Veterinary specialty categorization
434
+ - Treatment and drug trend analysis
435
  - Interactive visualizations
436
+ - Journal and publication pattern analysis
437
  """)
438
 
439
  with gr.Row():
440
  with gr.Column(scale=2):
441
  query_input = gr.Textbox(
442
  label="Research Query",
443
+ placeholder="e.g., 'canine diabetes management', 'equine lameness diagnosis', 'feline kidney disease', 'wildlife conservation medicine'",
444
  lines=2
445
  )
446
+ with gr.Row():
447
+ max_results = gr.Slider(
448
+ minimum=10, maximum=100, value=50, step=10,
449
+ label="Maximum Results"
450
+ )
451
+ database_choice = gr.Dropdown(
452
+ choices=["pubmed"],
453
+ value="pubmed",
454
+ label="Database"
455
+ )
456
+ search_btn = gr.Button("πŸ” Search Veterinary Literature", variant="primary")
457
 
458
  with gr.Column(scale=1):
459
  gr.Markdown("""
460
+ ### Search Tips:
461
+ - **Species**: dog, cat, horse, cattle, pig, bird, fish, reptile, wildlife
462
+ - **Specialties**: cardiology, oncology, surgery, dermatology, neurology
463
+ - **Conditions**: diabetes, arthritis, cancer, infection, allergies
464
+ - **Procedures**: vaccination, surgery, imaging, therapy
465
+ - **Combine terms**: "feline diabetes insulin therapy"
466
  """)
467
 
468
  with gr.Tabs():
469
+ with gr.TabItem("πŸ“Š Analysis Summary"):
470
+ summary_output = gr.Markdown(label="Veterinary Literature Analysis")
471
 
472
+ with gr.TabItem("πŸ“‹ Research Papers"):
473
  papers_output = gr.Dataframe(
474
  headers=["PMID", "Title", "Authors", "Journal", "Year"],
475
+ label="Retrieved Veterinary Papers"
476
  )
477
 
478
+ with gr.TabItem("πŸ“ˆ Research Trends"):
479
  with gr.Row():
480
  year_plot = gr.Plot(label="Publication Timeline")
481
+ species_plot = gr.Plot(label="Animal Species")
482
  with gr.Row():
483
+ specialties_plot = gr.Plot(label="Veterinary Specialties")
484
+ conditions_plot = gr.Plot(label="Common Conditions")
485
 
486
  # Connect the search function
487
  search_btn.click(
488
+ search_and_analyze_vet,
489
+ inputs=[query_input, max_results, database_choice],
490
+ outputs=[summary_output, papers_output, year_plot, species_plot, specialties_plot, conditions_plot]
491
  )
492
 
493
  # Add examples
494
  gr.Examples(
495
  examples=[
496
+ ["canine diabetes insulin therapy", 40, "pubmed"],
497
+ ["equine lameness diagnosis imaging", 35, "pubmed"],
498
+ ["feline chronic kidney disease treatment", 45, "pubmed"],
499
+ ["bovine mastitis antibiotic resistance", 30, "pubmed"],
500
+ ["avian influenza surveillance wild birds", 35, "pubmed"],
501
+ ["exotic animal anesthesia protocols", 25, "pubmed"],
502
+ ["wildlife conservation medicine", 40, "pubmed"],
503
+ ["small animal oncology chemotherapy", 50, "pubmed"]
504
  ],
505
+ inputs=[query_input, max_results, database_choice]
506
  )
507
 
508
  gr.Markdown("""
509
+ ### About This Veterinary Literature Mining Agent
510
+
511
+ This comprehensive tool is designed for veterinary professionals, researchers, and students to efficiently
512
+ search and analyze veterinary literature across all animal species and medical specialties.
513
+
514
+ **Supported Areas:**
515
+ - **Companion Animals**: Dogs, cats, rabbits, ferrets, birds, reptiles, fish
516
+ - **Large Animals**: Horses, cattle, pigs, sheep, goats
517
+ - **Wildlife & Zoo Medicine**: All wild species and conservation medicine
518
+ - **Laboratory Animals**: Research and laboratory animal medicine
519
+ - **All Veterinary Specialties**: Internal medicine, surgery, oncology, cardiology, dermatology, etc.
520
 
521
+ **Data Sources:** PubMed/NCBI databases with veterinary focus
522
  **Last Updated:** June 2025
523
+ **Coverage:** All aspects of veterinary medicine and animal health
524
  """)
525
 
526
  return interface
527
 
528
  # Create and launch the interface
529
  if __name__ == "__main__":
530
+ interface = create_veterinary_gradio_interface()
531
  interface.launch(
532
  server_name="0.0.0.0",
533
  server_port=7860,