Generative AI

Develop a Multi-Agent AI Workflow for Biological Network Modeling, Protein Interactions, Metabolism, and Cell Signaling Simulation

class CellSignalingSimulationAgent:
   def run(self, df_signal: pd.DataFrame) -> AgentResult:
       peak_receptor = float(df_signal["receptor_active"].max())
       peak_kinase = float(df_signal["kinase_active"].max())
       peak_tf = float(df_signal["tf_active"].max())


       t_receptor = float(df_signal.loc[df_signal["receptor_active"].idxmax(), "time"])
       t_kinase = float(df_signal.loc[df_signal["kinase_active"].idxmax(), "time"])
       t_tf = float(df_signal.loc[df_signal["tf_active"].idxmax(), "time"])


       final_state = df_signal.iloc[-1].to_dict()


       summary = {
           "peak_receptor_activity": round(peak_receptor, 4),
           "peak_kinase_activity": round(peak_kinase, 4),
           "peak_tf_activity": round(peak_tf, 4),
           "time_to_peak_receptor": round(t_receptor, 4),
           "time_to_peak_kinase": round(t_kinase, 4),
           "time_to_peak_tf": round(t_tf, 4),
           "final_state": {k: round(float(v), 4) for k, v in final_state.items()},
       }
       return AgentResult(name="CellSignalingSimulationAgent", summary=summary)


class PrincipalInvestigatorAgent:
   def __init__(self, client, model=OPENAI_MODEL):
       self.client = client
       self.model = model


   def synthesize(self, results: List[AgentResult]) -> str:
       payload = {r.name: r.summary for r in results}


       prompt = f"""
You are a principal investigator in computational systems biology.


Given the outputs of four specialized AI agents:
1. gene regulatory network analysis
2. protein interaction prediction
3. metabolic pathway optimization
4. cell signaling simulation


Write a rigorous but readable report with these sections:
- Executive Summary
- Key Findings by Agent
- Cross-System Biological Interpretation
- Hypotheses Worth Testing in Wet Lab
- Model Limitations
- Next Computational Extensions


Use concise scientific language.
Do not fabricate datasets beyond what is shown.
When useful, connect regulation, signaling, metabolism, and protein interactions into a single systems biology story.


Agent outputs:
{json.dumps(payload, indent=2)}
"""


       try:
           resp = self.client.chat.completions.create(
               model=self.model,
               messages=[
                   {"role": "user", "content": prompt},
               ],
               temperature=0.4,
           )
           return resp.choices[0].message.content
       except Exception as e:
           return f"OpenAI synthesis failed: {e}"


genes, W = generate_gene_regulatory_network(n_genes=14, edge_prob=0.20)
X_expr = simulate_gene_expression(W, n_steps=80, noise=0.08)
grn_agent = GeneRegulatoryNetworkAgent()
grn_result = grn_agent.run(genes, W, X_expr)


proteins, prot_features, prot_families, prot_localization = generate_protein_features(n_proteins=40, feature_dim=10)
ppi_rows = generate_ppi_dataset(proteins, prot_features, prot_families, prot_localization)
ppi_agent = ProteinInteractionPredictionAgent()
ppi_result = ppi_agent.run(ppi_rows)


metabolites, reactions = generate_metabolic_network()
met_agent = MetabolicOptimizationAgent()
met_result, met_trace = met_agent.run(reactions, oxygen_budget=3.5, substrate_budget=4.2)


df_signal = simulate_cell_signaling(T=220, dt=0.05, ligand_level=1.2)
sig_agent = CellSignalingSimulationAgent()
sig_result = sig_agent.run(df_signal)


all_results = [grn_result, ppi_result, met_result, sig_result]


for r in all_results:
   pretty(r.name, json.dumps(r.summary, indent=2))


fig = plt.figure(figsize=(18, 14))


ax1 = plt.subplot(2, 2, 1)
im = ax1.imshow(W, cmap="coolwarm", aspect="auto")
ax1.set_title("Gene Regulatory Weight Matrix")
ax1.set_xticks(range(len(genes)))
ax1.set_yticks(range(len(genes)))
ax1.set_xticklabels(genes, rotation=90)
ax1.set_yticklabels(genes)
plt.colorbar(im, ax=ax1, fraction=0.046, pad=0.04)


ax2 = plt.subplot(2, 2, 2)
for i in range(min(6, X_expr.shape[1])):
   ax2.plot(X_expr[:, i], label=genes[i])
ax2.set_title("Sample Gene Expression Dynamics")
ax2.set_xlabel("Time step")
ax2.set_ylabel("Expression")
ax2.legend(loc="upper right", fontsize=8)


ax3 = plt.subplot(2, 2, 3)
ax3.plot(df_signal["time"], df_signal["receptor_active"], label="Receptor")
ax3.plot(df_signal["time"], df_signal["kinase_active"], label="Kinase")
ax3.plot(df_signal["time"], df_signal["tf_active"], label="Transcription Factor")
ax3.plot(df_signal["time"], df_signal["phosphatase"], label="Phosphatase")
ax3.set_title("Cell Signaling Simulation")
ax3.set_xlabel("Time")
ax3.set_ylabel("Activity")
ax3.legend()


ax4 = plt.subplot(2, 2, 4)
ax4.plot(met_trace)
ax4.set_title("Metabolic Search Objective Trace")
ax4.set_xlabel("Iteration")
ax4.set_ylabel("Objective score")


plt.tight_layout()
plt.show()


G_grn = nx.DiGraph()
for g in genes:
   G_grn.add_node(g)
for i in range(len(genes)):
   for j in range(len(genes)):
       if abs(W[i, j]) > 0.4:
           G_grn.add_edge(genes[i], genes[j], weight=W[i, j])


plt.figure(figsize=(10, 8))
pos = nx.spring_layout(G_grn, seed=42)
edge_colors = ["green" if G_grn[u][v]["weight"] > 0 else "red" for u, v in G_grn.edges()]
nx.draw_networkx(G_grn, pos, with_labels=True, node_size=900, font_size=9, arrows=True, edge_color=edge_colors)
plt.title("Gene Regulatory Network Graph (green=activation, red=repression)")
plt.axis("off")
plt.show()


top_ppi = ppi_result.summary["top_predicted_interactions"][:12]
G_ppi = nx.Graph()
for row in top_ppi:
   a, b, p = row["protein_a"], row["protein_b"], row["pred_prob"]
   G_ppi.add_edge(a, b, weight=p)


plt.figure(figsize=(10, 8))
pos = nx.spring_layout(G_ppi, seed=7)
widths = [2 + 4 * G_ppi[u][v]["weight"] for u, v in G_ppi.edges()]
nx.draw_networkx(G_ppi, pos, with_labels=True, node_size=1000, font_size=9, width=widths)
plt.title("Top Predicted Protein Interaction Subnetwork")
plt.axis("off")
plt.show()


grn_table = pd.DataFrame(grn_result.summary["most_dynamic_genes"])
ppi_table = pd.DataFrame(ppi_result.summary["top_predicted_interactions"])
met_table = pd.DataFrame(met_result.summary["dominant_reactions"])
sig_table = pd.DataFrame([sig_result.summary])


pretty("Most Dynamic Genes", grn_table.to_string(index=False))
pretty("Top Predicted PPIs", ppi_table.to_string(index=False))
pretty("Dominant Metabolic Reactions", met_table.to_string(index=False))


pi_agent = PrincipalInvestigatorAgent(client=client, model=OPENAI_MODEL)
final_report = pi_agent.synthesize(all_results)


pretty("OPENAI SYSTEMS BIOLOGY REPORT", final_report)


artifact = {
   "grn": grn_result.summary,
   "ppi": ppi_result.summary,
   "metabolic": met_result.summary,
   "signaling": sig_result.summary,
   "llm_report": final_report,
}


with open("bio_agents_tutorial_results.json", "w") as f:
   json.dump(artifact, f, indent=2)


print("nSaved results to: bio_agents_tutorial_results.json")

Source link

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button