First Commit
Browse files- .gitattributes +2 -0
- Dataset.xlsx +3 -0
- README.md +113 -1
- app.py +616 -0
- catboost_cell_response.cbm +3 -0
- catboost_printability.cbm +3 -0
- cell_line_encoder.joblib +3 -0
- scaler_cell_response.joblib +3 -0
- scaler_printability.joblib +3 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
*.cbm filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
Dataset.xlsx filter=lfs diff=lfs merge=lfs -text
|
Dataset.xlsx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:bdb613c74c01c0b60410f283e33d7ea5ffbed8aaef459fe41d11768a2821c781
|
| 3 |
+
size 1016051
|
README.md
CHANGED
|
@@ -11,4 +11,116 @@ license: cc-by-nc-4.0
|
|
| 11 |
short_description: ML Applications in Tissue Engineering
|
| 12 |
---
|
| 13 |
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
short_description: ML Applications in Tissue Engineering
|
| 12 |
---
|
| 13 |
|
| 14 |
+
|
| 15 |
+
# π¬ MLATE V3: Multi-Tissue Scaffold Prediction Platform
|
| 16 |
+
|
| 17 |
+
**MLATE V3** is a fully integrated, machine learning-powered platform for predicting, optimizing, and generating detailed fabrication procedures for 3D-(bio)printed scaffolds in tissue engineering. This app enables researchers to input a wide range of biomaterials, cell lines, and printing parameters, and receive optimized scaffold compositions along with step-by-step printing instructions generated via Google Gemini.
|
| 18 |
+
|
| 19 |
+
> π *Rafieyan et al. (preprint, 2025). MLATE V3: A fully integrated Multi-Tissue, machine learning platform for prediction, optimization and generating procedures for fabricating 3D-(bio)printing scaffolds for tissue engineering*
|
| 20 |
+
|
| 21 |
+
---
|
| 22 |
+
|
| 23 |
+
## π Features
|
| 24 |
+
|
| 25 |
+
- π¬ Predict scaffold quality based on printability and cell response
|
| 26 |
+
- π§ͺ Optimize biomaterial concentrations, cell densities, and printing parameters using Optuna
|
| 27 |
+
- π§ Powered by two fine-tuned **CatBoostClassifier** models
|
| 28 |
+
- π Automatically generates fabrication protocols with Gemini API
|
| 29 |
+
- π Enforces safe defaults and intelligent UI input validation
|
| 30 |
+
- π§± Uses a real-world, curated dataset of **2847 samples** across **multiple tissues and cell lines**
|
| 31 |
+
|
| 32 |
+
---
|
| 33 |
+
|
| 34 |
+
## π Dataset
|
| 35 |
+
|
| 36 |
+
This project includes a publicly available dataset (`Dataset.xlsx`) containing:
|
| 37 |
+
- 123 biomaterials
|
| 38 |
+
- 175 cell lines
|
| 39 |
+
- 7 printing parameters
|
| 40 |
+
- Scaffold performance labels
|
| 41 |
+
|
| 42 |
+
The dataset is available in the [Files and Versions](https://huggingface.co/spaces/your-username/your-space-name/blob/main/Dataset.xlsx) tab of this Space.
|
| 43 |
+
|
| 44 |
+
You may also optionally add this to Hugging Face Datasets for broader access.
|
| 45 |
+
|
| 46 |
+
---
|
| 47 |
+
|
| 48 |
+
## βοΈ How It Works
|
| 49 |
+
|
| 50 |
+
1. **Input**: User selects biomaterials, cell line, and printing parameters with min/max/step values
|
| 51 |
+
2. **Optimization**: Optuna runs 50 trials to maximize predicted scaffold quality (WSSQ)
|
| 52 |
+
3. **Prediction**:
|
| 53 |
+
- Two CatBoost models are used to predict:
|
| 54 |
+
- `Printability` (3-class)
|
| 55 |
+
- `Cell Response` (5-class)
|
| 56 |
+
- Probabilistic predictions are mapped to expected scores
|
| 57 |
+
4. **Scaffold Quality**: A weighted combination of printability and cell response
|
| 58 |
+
5. **Procedure Generation**: A Gemini API prompt generates custom step-by-step fabrication instructions
|
| 59 |
+
|
| 60 |
+
---
|
| 61 |
+
|
| 62 |
+
## π» Running Locally
|
| 63 |
+
|
| 64 |
+
Clone the repo and install dependencies:
|
| 65 |
+
|
| 66 |
+
```bash
|
| 67 |
+
git clone https://huggingface.co/spaces/your-username/MLATE-V3
|
| 68 |
+
cd MLATE-V3
|
| 69 |
+
|
| 70 |
+
# Create virtual environment (optional)
|
| 71 |
+
python -m venv venv
|
| 72 |
+
source venv/bin/activate # or venv\Scripts\activate on Windows
|
| 73 |
+
|
| 74 |
+
# Install dependencies
|
| 75 |
+
pip install -r requirements.txt
|
| 76 |
+
|
| 77 |
+
# Set your Gemini API key
|
| 78 |
+
export GEMINI_API_KEY=your_key_here # or set in .env
|
| 79 |
+
|
| 80 |
+
# Run the app
|
| 81 |
+
streamlit run app.py
|
| 82 |
+
```
|
| 83 |
+
|
| 84 |
+
---
|
| 85 |
+
|
| 86 |
+
## π License
|
| 87 |
+
|
| 88 |
+
This project is licensed under the **Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)**.
|
| 89 |
+
|
| 90 |
+
You are free to:
|
| 91 |
+
- Share and adapt the code
|
| 92 |
+
- Use the dataset for academic research
|
| 93 |
+
|
| 94 |
+
But:
|
| 95 |
+
- **Commercial use is prohibited**
|
| 96 |
+
- **Citation is required** (see below)
|
| 97 |
+
|
| 98 |
+
---
|
| 99 |
+
|
| 100 |
+
## π Citation
|
| 101 |
+
|
| 102 |
+
If you use MLATE V3 or its dataset in your research, please cite:
|
| 103 |
+
|
| 104 |
+
> Rafieyan et al. (preprint, 2025).
|
| 105 |
+
> *MLATE V3: A fully integrated Multi-Tissue, machine learning platform for prediction, optimization and generating procedures for fabricating 3D-(bio)printing scaffolds for tissue engineering*
|
| 106 |
+
> *(Preprint link to be added after publication)*
|
| 107 |
+
|
| 108 |
+
BibTeX:
|
| 109 |
+
```bibtex
|
| 110 |
+
@article{rafieyan2025mlate,
|
| 111 |
+
author = {Rafieyan, Saeed and others},
|
| 112 |
+
title = {MLATE V3: A fully integrated Multi-Tissue, machine learning platform for prediction, optimization and generating procedures for fabricating 3D-(bio)printing scaffolds for tissue engineering},
|
| 113 |
+
journal = {Preprint},
|
| 114 |
+
year = {2025}
|
| 115 |
+
}
|
| 116 |
+
```
|
| 117 |
+
|
| 118 |
+
---
|
| 119 |
+
|
| 120 |
+
## β οΈ Disclaimer
|
| 121 |
+
|
| 122 |
+
This tool is intended for **research and academic use only**. While we strive for accuracy, the predictions and fabrication procedures are generated using machine learning and language models and may contain errors or inconsistencies. The authors are **not responsible for any unintended consequences** arising from use of this tool in experimental or clinical settings.
|
| 123 |
+
|
| 124 |
+
---
|
| 125 |
+
|
| 126 |
+
Developed by [Saeed Rafieyan](https://sraf.ir)
|
app.py
ADDED
|
@@ -0,0 +1,616 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import streamlit as st
|
| 3 |
+
import pandas as pd
|
| 4 |
+
import joblib
|
| 5 |
+
import optuna
|
| 6 |
+
import numpy as np
|
| 7 |
+
import openai
|
| 8 |
+
from catboost import CatBoostClassifier
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
from google import genai
|
| 12 |
+
from google.genai import types
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
# keep a reference to the real number_input
|
| 17 |
+
_original_number_input = st.number_input
|
| 18 |
+
|
| 19 |
+
def safe_number_input(label, **kwargs):
|
| 20 |
+
"""
|
| 21 |
+
Clamp `value` into [min_value, max_value] and warn if we had to adjust.
|
| 22 |
+
Then call the real st.number_input with the clamped default.
|
| 23 |
+
"""
|
| 24 |
+
min_value = kwargs.get("min_value", float("-inf"))
|
| 25 |
+
max_value = kwargs.get("max_value", float("inf"))
|
| 26 |
+
value = kwargs.get("value", min_value)
|
| 27 |
+
# clamp
|
| 28 |
+
clamped = min(max(value, min_value), max_value)
|
| 29 |
+
if clamped != value:
|
| 30 |
+
st.warning(
|
| 31 |
+
f"β οΈ Default for β{label}β ({value}) was outside "
|
| 32 |
+
f"[{min_value}, {max_value}]; using {clamped} instead."
|
| 33 |
+
)
|
| 34 |
+
kwargs["value"] = clamped
|
| 35 |
+
return _original_number_input(label, **kwargs)
|
| 36 |
+
|
| 37 |
+
# override streamlit's number_input globally
|
| 38 |
+
st.number_input = safe_number_input
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
# directly use your Gemini key
|
| 43 |
+
gemini_key = os.getenv("GEMINI_API_KEY")
|
| 44 |
+
if not gemini_key:
|
| 45 |
+
st.error("π¨ Gemini API key not found. Please set GEMINI_API_KEY in your Space settings.")
|
| 46 |
+
st.stop()
|
| 47 |
+
|
| 48 |
+
client = genai.Client(api_key=gemini_key)
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
# βββ Scaffold Quality Function βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 52 |
+
def scaffold_quality_combined(printability, cell_response,
|
| 53 |
+
weight_printability=0.3, weight_cell_response=0.7):
|
| 54 |
+
if printability == 0:
|
| 55 |
+
return 0.0
|
| 56 |
+
if cell_response == 1:
|
| 57 |
+
return 100 * (printability / 3.0)
|
| 58 |
+
norm_p = printability / 3.0
|
| 59 |
+
norm_c = (cell_response - 1) / 4.0
|
| 60 |
+
hm = (weight_printability + weight_cell_response) / (
|
| 61 |
+
(weight_printability / norm_p) +
|
| 62 |
+
(weight_cell_response / norm_c)
|
| 63 |
+
)
|
| 64 |
+
mc = (norm_p**weight_printability) * (norm_c**weight_cell_response)
|
| 65 |
+
return 100 * ((hm + mc) / 2.0)
|
| 66 |
+
|
| 67 |
+
# βββ Constants ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 68 |
+
BIOMATERIAL_OPTIONS = [
|
| 69 |
+
"Alginate (%w/v)",
|
| 70 |
+
"PVA-HA (%w/v)",
|
| 71 |
+
"CaSO4 (%w/v)",
|
| 72 |
+
"Na2HPO4 (%w/v)",
|
| 73 |
+
"Gelatin (%w/v)",
|
| 74 |
+
"GelMA (%w/v)",
|
| 75 |
+
"laponite (%w/v)",
|
| 76 |
+
"graphene oxide (%w/v)",
|
| 77 |
+
"hydroxyapatite (%w/v)",
|
| 78 |
+
"Hyaluronic_Acid (%w/v)",
|
| 79 |
+
"hyaluronan metacrylate (%w/v)",
|
| 80 |
+
"NorHA (%w/v)",
|
| 81 |
+
"Fibroin/Fibrinogen (%w/v)",
|
| 82 |
+
"Pluronic P-123 (%w/v)",
|
| 83 |
+
"Collagen (%w/v)",
|
| 84 |
+
"Chitosan (%w/v)",
|
| 85 |
+
"CS-AEMA (%w/v)",
|
| 86 |
+
"RGD (mM)",
|
| 87 |
+
"TCP (%w/v)",
|
| 88 |
+
"Gellan (%w/v)",
|
| 89 |
+
"bioactive glass (%w/v)",
|
| 90 |
+
"Nano/Methycellulose (%w/v)",
|
| 91 |
+
"PEGTA (%w/v)",
|
| 92 |
+
"PEGMA (%w/v)",
|
| 93 |
+
"PEGDA (%w/v)",
|
| 94 |
+
"Agarose (%w/v)",
|
| 95 |
+
" hyaluronic acid+ Ph moieties (%w/v)",
|
| 96 |
+
"matrigel (%w/v)",
|
| 97 |
+
"CaCl2(mM)",
|
| 98 |
+
"NaCl(mM)",
|
| 99 |
+
"BaCl2(mM)",
|
| 100 |
+
"SrCl2(mM)",
|
| 101 |
+
"CaCO3 (mM)",
|
| 102 |
+
"Genipin (%w/v)",
|
| 103 |
+
"PVA (%wt)",
|
| 104 |
+
"trans-glutaminase (%w/v)",
|
| 105 |
+
"alginate lyase (U/ml)",
|
| 106 |
+
"D-glucose (%w/v)",
|
| 107 |
+
"PLGA (%w/v)",
|
| 108 |
+
"vascular tissued-derived dECM (%w/v)",
|
| 109 |
+
"PEG-8-SH (mM)",
|
| 110 |
+
"Alginate dialdehyde (%w/v)",
|
| 111 |
+
"Alginate sulfate (%w/v)",
|
| 112 |
+
"RGD-modified alginate (%w/v)",
|
| 113 |
+
"poly(N-isopropylacrylamide) grafted hyaluronan (%w/v)",
|
| 114 |
+
"chondroitin sulfate methacrylate (%w/v)",
|
| 115 |
+
"PCL (%w/v)",
|
| 116 |
+
"alginate methacrylate (%w/v)",
|
| 117 |
+
"HRP (U/ml)",
|
| 118 |
+
"Pluronic F127 (%w/v)/Lutrol F127 (%w/v)",
|
| 119 |
+
"Irgacure 2959 (%w/v)",
|
| 120 |
+
"Eosin Y (%w/v)",
|
| 121 |
+
"Ruthenium (mM)",
|
| 122 |
+
"sodium persulfate (SPS) (mM)",
|
| 123 |
+
"HEPES (mM)",
|
| 124 |
+
"LAP (%w/v)",
|
| 125 |
+
"glutaraldehyde (%w/v)",
|
| 126 |
+
"PBS (M)",
|
| 127 |
+
"glycerol (%w/v)",
|
| 128 |
+
"cECM (%w/v)",
|
| 129 |
+
"gel-fu(%w/v)",
|
| 130 |
+
"Rose Bengal (%w/v)",
|
| 131 |
+
"Vitamin B2(%w/v)",
|
| 132 |
+
"VEGF(%w/v)",
|
| 133 |
+
"Polypyrrole:PSS(%w/v)",
|
| 134 |
+
"boratebioactiveglass(%w/v)",
|
| 135 |
+
"astaxanthin(%w/v)",
|
| 136 |
+
"PRP (%v/v)",
|
| 137 |
+
"methacrylated collagen (%w/v)",
|
| 138 |
+
"Ξ±-Toc (Β΅M)",
|
| 139 |
+
"ascorbic acid (mM)",
|
| 140 |
+
"Liver dECM(%w/v)",
|
| 141 |
+
"galactosylated alginate (%w/v)",
|
| 142 |
+
"SC-PEG(%w/v)",
|
| 143 |
+
"SFMA-L(%w/v)",
|
| 144 |
+
"SFMA-M(%w/v)",
|
| 145 |
+
"SFMA-H(%w/v)",
|
| 146 |
+
"KdECMMA(%w/v)",
|
| 147 |
+
"BA silk fibronin (%w/v)",
|
| 148 |
+
"Carrageenan(%v)",
|
| 149 |
+
"Carbopol ETD 2020 NF (%w/v)",
|
| 150 |
+
"Carbopol Ultrez 10 NF(%w/v)",
|
| 151 |
+
"Carbopol NF-980(%w/v)",
|
| 152 |
+
"FBS (%v/v)",
|
| 153 |
+
"MeTro (%w/v)",
|
| 154 |
+
"Triethanolamine (%v/v)",
|
| 155 |
+
"PEG-Fibrinogen (%w/v)",
|
| 156 |
+
"polyethylene glycol dimethacrylate (%w/v)",
|
| 157 |
+
"aprotinin (Β΅g/ml)",
|
| 158 |
+
"gold nanorod (mg/mL)",
|
| 159 |
+
"egg white (w/v)",
|
| 160 |
+
"1-Vinyl-2-Pyrrolidione (v/v)",
|
| 161 |
+
"carboxyl functionalized carbon nanotubes (%w/v)",
|
| 162 |
+
"polyHIPE (%w/v)",
|
| 163 |
+
"Ξ²-D galactose (mM)",
|
| 164 |
+
"hydrogen peroxide (H2O2) (%v/v)",
|
| 165 |
+
"lactic acid v/v",
|
| 166 |
+
"NorCol (%w/v)",
|
| 167 |
+
"DDT (%w/v)",
|
| 168 |
+
"ammonium persulfate (mM)",
|
| 169 |
+
"diTyr-RGD (mM)",
|
| 170 |
+
"PHEG-Tyr (%w/v)",
|
| 171 |
+
"MMP2-degradable peptide (%w/v)",
|
| 172 |
+
"KdECM (%w/v)",
|
| 173 |
+
"EDC (mg)",
|
| 174 |
+
"NHS (mg)",
|
| 175 |
+
"VA086 (%w/v)",
|
| 176 |
+
"PGS (%w/v)",
|
| 177 |
+
"thiolated HA (%w/v)",
|
| 178 |
+
"boron nitride nanotubes (%w/v)",
|
| 179 |
+
"PEDOT:PSS (ul)",
|
| 180 |
+
"KCl (mM)",
|
| 181 |
+
"skeletal muscle ECM methacrylate (%w/v)",
|
| 182 |
+
"PEO (%w/v)",
|
| 183 |
+
"Carbon dots (mg/ml)",
|
| 184 |
+
"Laminin (ug/ml)",
|
| 185 |
+
"DF-PEG (%w/v)",
|
| 186 |
+
"omenta ECM (%w/v)",
|
| 187 |
+
"thrombin (unit/ml)",
|
| 188 |
+
"Carbon nanotube (CNT) (w/v)",
|
| 189 |
+
"Phytagel(%v)",
|
| 190 |
+
"Laponite-XLG (%w/w)"
|
| 191 |
+
]
|
| 192 |
+
|
| 193 |
+
CELL_LINE_OPTIONS = [
|
| 194 |
+
"chondrocyteyte",
|
| 195 |
+
"HepG2",
|
| 196 |
+
"bMSCs",
|
| 197 |
+
"HUVECs",
|
| 198 |
+
"NIH3T3",
|
| 199 |
+
"MESCs",
|
| 200 |
+
"hiPSC-CMs /ATCCs",
|
| 201 |
+
"CPCs",
|
| 202 |
+
"L929",
|
| 203 |
+
"Myoblast cells",
|
| 204 |
+
"hiPSCs",
|
| 205 |
+
"HepaRG",
|
| 206 |
+
"hESCs",
|
| 207 |
+
"10T1/2",
|
| 208 |
+
"Cardiac progenitor cells",
|
| 209 |
+
"NSCLC PDX",
|
| 210 |
+
"RAMECs",
|
| 211 |
+
"hASCs",
|
| 212 |
+
"HAVIC",
|
| 213 |
+
"Primary mouse hepatocyte",
|
| 214 |
+
"PTECs",
|
| 215 |
+
"human nasoseptal chondrocytes",
|
| 216 |
+
"PDX",
|
| 217 |
+
"HPFs",
|
| 218 |
+
"U87-MG",
|
| 219 |
+
"ESCs",
|
| 220 |
+
"HASSMC",
|
| 221 |
+
"dermal fibroblasts",
|
| 222 |
+
"MC3T3-E1",
|
| 223 |
+
"Schwann cells",
|
| 224 |
+
"hiPSC-CMs and HS-27A",
|
| 225 |
+
"Saos-2 ",
|
| 226 |
+
"SU3",
|
| 227 |
+
"hTMSCs",
|
| 228 |
+
"HACs",
|
| 229 |
+
"HADMSCs",
|
| 230 |
+
"HeLa",
|
| 231 |
+
"human primary kidney cells",
|
| 232 |
+
"myoblasts",
|
| 233 |
+
"MSCs",
|
| 234 |
+
"human primary kidneycells",
|
| 235 |
+
"293FT",
|
| 236 |
+
"HEK 293FT",
|
| 237 |
+
"Wnt3a-293FT",
|
| 238 |
+
"RSC96/HUVECs",
|
| 239 |
+
"human adipogenic mesenchymal stem cells",
|
| 240 |
+
"HEPG2/ECs",
|
| 241 |
+
"HUVECs/MSCs",
|
| 242 |
+
"RHECs",
|
| 243 |
+
"Human non-small cell lung cancer line Calu-3 (Calu-3)",
|
| 244 |
+
"HL-1",
|
| 245 |
+
"mouse cardiac cells",
|
| 246 |
+
"IMR-90",
|
| 247 |
+
"EPCs",
|
| 248 |
+
"MRC5",
|
| 249 |
+
"rMSC",
|
| 250 |
+
"basil plant cell",
|
| 251 |
+
"hNCs",
|
| 252 |
+
"A549",
|
| 253 |
+
"human induced pluripotent stem cell-derived cardiomyocytes",
|
| 254 |
+
"bMSCs/hACs",
|
| 255 |
+
"EA.hy 926 cells",
|
| 256 |
+
"HepG2/C3A",
|
| 257 |
+
"human epithelial lung carcinoma cells",
|
| 258 |
+
"Human cardiac fibroblasts",
|
| 259 |
+
"hTERT-MSC",
|
| 260 |
+
"cardiomyocytes",
|
| 261 |
+
"Huh7",
|
| 262 |
+
"NRCMs",
|
| 263 |
+
"HCF",
|
| 264 |
+
"Wnt reporter-293FT",
|
| 265 |
+
"neonatal rat ventricular CFs",
|
| 266 |
+
"human coronary artery endothelial cells",
|
| 267 |
+
"hiPSC-CM / fibroblasts",
|
| 268 |
+
"primary mouse hepatocyte",
|
| 269 |
+
"NIH3T3/ HUVECs",
|
| 270 |
+
"murine macrophage-like cell line",
|
| 271 |
+
"Endothelial cells",
|
| 272 |
+
"Human aortic VIC",
|
| 273 |
+
"sADSC",
|
| 274 |
+
"HUVECs/H9C2",
|
| 275 |
+
"neonatal rat ventricular cardiomyocytes",
|
| 276 |
+
"MG-63",
|
| 277 |
+
"Neonatal mouse cardiomyocytes (NMVCMs)",
|
| 278 |
+
"human hepatic stellate cell line",
|
| 279 |
+
"HEK-293",
|
| 280 |
+
"aHSC",
|
| 281 |
+
"MFCs",
|
| 282 |
+
"fibroblasts",
|
| 283 |
+
"HNDF",
|
| 284 |
+
"cardiomyocyte/MSCs",
|
| 285 |
+
"ADSCs",
|
| 286 |
+
"HCASMCs",
|
| 287 |
+
"cardiomyocyte",
|
| 288 |
+
"hCPCs",
|
| 289 |
+
"Human CM /adult human fibroblasts ",
|
| 290 |
+
"primary rat hepatocyte",
|
| 291 |
+
"human cardiac progenitor cells",
|
| 292 |
+
"SMC",
|
| 293 |
+
"Human MSCs",
|
| 294 |
+
"ACPCs",
|
| 295 |
+
"Huh7/HepaRG",
|
| 296 |
+
"Human umbilical vein endothelial cells",
|
| 297 |
+
"ATDC5",
|
| 298 |
+
"hESC-derived HLCs",
|
| 299 |
+
"NIH 3T3",
|
| 300 |
+
"n neonatal mouse ventricular cardiomyocytes",
|
| 301 |
+
"CFs/CMs/HUVECs",
|
| 302 |
+
"MRC-5",
|
| 303 |
+
"VIC",
|
| 304 |
+
"eHep",
|
| 305 |
+
"hUVECs/NIH3T3",
|
| 306 |
+
"MC3T3",
|
| 307 |
+
"HLC",
|
| 308 |
+
"hepatoma",
|
| 309 |
+
"FB",
|
| 310 |
+
"A549 GFP+",
|
| 311 |
+
"HPAAF",
|
| 312 |
+
"PMHs",
|
| 313 |
+
"HUVSMCs",
|
| 314 |
+
"Human CPCs",
|
| 315 |
+
"Fibroblasts/THP-1",
|
| 316 |
+
"rat ventricular cardiomyocytes",
|
| 317 |
+
"iCMs/iCFs/iECs",
|
| 318 |
+
"HUVEC/HHSC",
|
| 319 |
+
"Human CPCs / MSCs",
|
| 320 |
+
"HepaRG/LX-2 ",
|
| 321 |
+
"iCMs/iCFs/iECs/iCMFs",
|
| 322 |
+
"LX-2 ",
|
| 323 |
+
"SMMC-7721",
|
| 324 |
+
"Hepatoblast- single cell/iESC/iMSC",
|
| 325 |
+
"iCMFs",
|
| 326 |
+
"Hepatoblast- spheroid/iESC/iMSC",
|
| 327 |
+
"hBM-MSCs",
|
| 328 |
+
"BMSCs",
|
| 329 |
+
"HUVECs and HHSCs",
|
| 330 |
+
"Intrahepatic cholangiocarcinoma (ICC)",
|
| 331 |
+
"VICs",
|
| 332 |
+
"CMs/CFs",
|
| 333 |
+
"human neonatal dermal fi broblasts",
|
| 334 |
+
"10T1/2 fibroblast-laden cells",
|
| 335 |
+
"human cardiac fibroblasts",
|
| 336 |
+
"neonatal rat ventricular CMs",
|
| 337 |
+
"HUVECs and hiPSC-CS",
|
| 338 |
+
"iPSC-derived CM",
|
| 339 |
+
"Human Umbilical Vein Endothelial Cells + iPSC-derived CM",
|
| 340 |
+
"rabbit bone marrow mesenchymal stem cells",
|
| 341 |
+
"Neonatal rat cardiomyocytes",
|
| 342 |
+
"NIH 3T3 mouse fibroblasts",
|
| 343 |
+
"Human CPCs & MSCs",
|
| 344 |
+
"NSCLC PDX/CAFs",
|
| 345 |
+
"hiPSCs-derived HLCs",
|
| 346 |
+
"U87",
|
| 347 |
+
"75% hepatoblast cells, 20% iEC and 5% iMSC",
|
| 348 |
+
"SMCs",
|
| 349 |
+
"A549/95-D cells",
|
| 350 |
+
"NCI-H441",
|
| 351 |
+
"pancreatic cancer cell",
|
| 352 |
+
"prostate cancer stem cell",
|
| 353 |
+
"human primary parathyroid cells ",
|
| 354 |
+
"primary human hepatocytes",
|
| 355 |
+
"CPCs / MSCs",
|
| 356 |
+
"CPCs ",
|
| 357 |
+
"cardiac fibroblasts",
|
| 358 |
+
"iPSCs-derived cardiomyocytes",
|
| 359 |
+
"cardiomyocytes/ fibroblasts",
|
| 360 |
+
"hiPSC-CM",
|
| 361 |
+
"iPSCs/HUVECs",
|
| 362 |
+
"iPSC-CMs",
|
| 363 |
+
"iPSCs",
|
| 364 |
+
"H1395",
|
| 365 |
+
"PC9",
|
| 366 |
+
"H1650",
|
| 367 |
+
"HULEC-5a",
|
| 368 |
+
"NCI-H1703"
|
| 369 |
+
]
|
| 370 |
+
|
| 371 |
+
PRINT_PARAM_NAMES = [
|
| 372 |
+
"Physical Crosslinking Duration (s)",
|
| 373 |
+
"Photo Crosslinking Duration (s)",
|
| 374 |
+
"Extrusion Pressure (kPa)",
|
| 375 |
+
"Nozzle Movement Speed (mm/s)",
|
| 376 |
+
"Nozzle Diameter (Β΅m)",
|
| 377 |
+
"Syringe Temperature (Β°C)",
|
| 378 |
+
"Substrate Temperature (Β°C)",
|
| 379 |
+
]
|
| 380 |
+
|
| 381 |
+
# βββ Load Encoder, Scalers, Models ββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 382 |
+
@st.cache_resource
|
| 383 |
+
def load_encoder():
|
| 384 |
+
return joblib.load('cell_line_encoder.joblib')
|
| 385 |
+
|
| 386 |
+
@st.cache_resource
|
| 387 |
+
def load_scalers():
|
| 388 |
+
return (
|
| 389 |
+
joblib.load('scaler_printability.joblib'),
|
| 390 |
+
joblib.load('scaler_cell_response.joblib')
|
| 391 |
+
)
|
| 392 |
+
|
| 393 |
+
@st.cache_resource
|
| 394 |
+
def load_models():
|
| 395 |
+
m_p = CatBoostClassifier(); m_p.load_model('catboost_printability.cbm')
|
| 396 |
+
m_c = CatBoostClassifier(); m_c.load_model('catboost_cell_response.cbm')
|
| 397 |
+
return m_p, m_c
|
| 398 |
+
|
| 399 |
+
encoder = load_encoder()
|
| 400 |
+
scaler_print, scaler_cell = load_scalers()
|
| 401 |
+
model_print, model_cell = load_models()
|
| 402 |
+
|
| 403 |
+
feature_order_print = list(scaler_print.feature_names_in_)
|
| 404 |
+
feature_order_cell = list(scaler_cell.feature_names_in_)
|
| 405 |
+
|
| 406 |
+
# βββ Session State Initialization ββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 407 |
+
if 'bio_rows' not in st.session_state:
|
| 408 |
+
st.session_state.bio_rows = [{
|
| 409 |
+
'mat': BIOMATERIAL_OPTIONS[0],
|
| 410 |
+
'min': 0.0, 'max': 10.0, 'step': 0.1
|
| 411 |
+
}]
|
| 412 |
+
|
| 413 |
+
if 'density_range' not in st.session_state:
|
| 414 |
+
st.session_state.density_range = {'min': 0.0, 'max': 10.0, 'step': 0.1}
|
| 415 |
+
|
| 416 |
+
if 'pp_ranges' not in st.session_state:
|
| 417 |
+
st.session_state.pp_ranges = {
|
| 418 |
+
name: {'min': 0.0, 'max': 10.0, 'step': 3.0}
|
| 419 |
+
for name in PRINT_PARAM_NAMES
|
| 420 |
+
}
|
| 421 |
+
|
| 422 |
+
# βββ App Layout ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 423 |
+
st.title("𧬠MLATE: Machine Learning Applications in Tissue Engieering")
|
| 424 |
+
st.markdown(
|
| 425 |
+
"<p style='font-size:0.8em; color:grey;'>"
|
| 426 |
+
"An integrated platform for predicting the quality of 3D (bio)printed scaffolds "
|
| 427 |
+
"in tissue engineering. For more details, please refer to and cite our paper: "
|
| 428 |
+
"<a href='https://doi.org/xxx' target='_blank'>https://doi.org/xxx</a>"
|
| 429 |
+
"</p>",
|
| 430 |
+
unsafe_allow_html=True
|
| 431 |
+
)
|
| 432 |
+
|
| 433 |
+
# βββ Biomaterials Section ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 434 |
+
st.subheader("Biomaterials (enter range for each)")
|
| 435 |
+
if st.button("β Add Biomaterial"):
|
| 436 |
+
used = {r['mat'] for r in st.session_state.bio_rows}
|
| 437 |
+
available = [m for m in BIOMATERIAL_OPTIONS if m not in used]
|
| 438 |
+
if available:
|
| 439 |
+
st.session_state.bio_rows.append({
|
| 440 |
+
'mat': available[0], 'min': 0.0, 'max': 10.0, 'step': 0.1
|
| 441 |
+
})
|
| 442 |
+
st.rerun()
|
| 443 |
+
|
| 444 |
+
for i, row in enumerate(st.session_state.bio_rows):
|
| 445 |
+
used_except_current = {
|
| 446 |
+
r['mat'] for idx, r in enumerate(st.session_state.bio_rows) if idx != i
|
| 447 |
+
}
|
| 448 |
+
options = [m for m in BIOMATERIAL_OPTIONS if m not in used_except_current]
|
| 449 |
+
|
| 450 |
+
c1, c2, c3, c4, c5 = st.columns([2, 1, 1, 1, 0.3])
|
| 451 |
+
mat = c1.selectbox(
|
| 452 |
+
"", options,
|
| 453 |
+
index=options.index(row['mat']) if row['mat'] in options else 0,
|
| 454 |
+
key=f"bio_mat_{i}"
|
| 455 |
+
)
|
| 456 |
+
st.session_state.bio_rows[i]['mat'] = mat
|
| 457 |
+
|
| 458 |
+
mn = c2.number_input(
|
| 459 |
+
"Min", min_value=0.0, max_value=row['max'],
|
| 460 |
+
value=row['min'], step=row['step'], key=f"bio_min_{i}"
|
| 461 |
+
)
|
| 462 |
+
# β min_value for Max is now the step; default value at least step
|
| 463 |
+
mx = c3.number_input(
|
| 464 |
+
"Max", min_value=row['step'], max_value=100.0,
|
| 465 |
+
value=max(row['max'], row['step']), step=row['step'],
|
| 466 |
+
key=f"bio_max_{i}"
|
| 467 |
+
)
|
| 468 |
+
st.session_state.bio_rows[i].update(min=mn, max=mx)
|
| 469 |
+
|
| 470 |
+
st.session_state.bio_rows[i]['step'] = c4.number_input(
|
| 471 |
+
"Step", min_value=0.0,
|
| 472 |
+
max_value=(mx - mn) if mx > mn else 0.1,
|
| 473 |
+
value=row['step'], step=0.1, key=f"bio_step_{i}"
|
| 474 |
+
)
|
| 475 |
+
|
| 476 |
+
if c5.button("β", key=f"rem_{i}"):
|
| 477 |
+
st.session_state.bio_rows.pop(i)
|
| 478 |
+
st.rerun()
|
| 479 |
+
|
| 480 |
+
st.markdown("---")
|
| 481 |
+
|
| 482 |
+
# βββ Cell Line & Density Section ββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 483 |
+
st.subheader("Cell Line & Density")
|
| 484 |
+
col1, col2, col3, col4 = st.columns([2,1,1,1])
|
| 485 |
+
cell_line = col1.selectbox("Cell Line", CELL_LINE_OPTIONS)
|
| 486 |
+
|
| 487 |
+
dr = st.session_state.density_range
|
| 488 |
+
dmin = col2.number_input(
|
| 489 |
+
"Min Density", min_value=0.0, max_value=dr['max'],
|
| 490 |
+
value=dr['min'], step=dr['step'], key="cd_min"
|
| 491 |
+
)
|
| 492 |
+
# β ensure Max Density cannot go below the step
|
| 493 |
+
dmax = col3.number_input(
|
| 494 |
+
"Max Density", min_value=dr['step'], max_value=1000.0,
|
| 495 |
+
value=max(dr['max'], dr['step']), step=dr['step'], key="cd_max"
|
| 496 |
+
)
|
| 497 |
+
dr.update(min=dmin, max=dmax)
|
| 498 |
+
|
| 499 |
+
dr['step'] = col4.number_input(
|
| 500 |
+
"Step", min_value=0.0,
|
| 501 |
+
max_value=(dmax - dmin) if dmax > dmin else 0.1,
|
| 502 |
+
value=dr['step'], step=0.1, key="cd_step"
|
| 503 |
+
)
|
| 504 |
+
|
| 505 |
+
st.markdown("---")
|
| 506 |
+
|
| 507 |
+
# βββ Printing Parameters Section ββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 508 |
+
st.subheader("Printing Parameters (enter range)")
|
| 509 |
+
for name in PRINT_PARAM_NAMES:
|
| 510 |
+
pmin = st.session_state.pp_ranges[name]['min']
|
| 511 |
+
pmax = st.session_state.pp_ranges[name]['max']
|
| 512 |
+
pstep = st.session_state.pp_ranges[name]['step']
|
| 513 |
+
|
| 514 |
+
c1, c2, c3, c4 = st.columns([2,1,1,1])
|
| 515 |
+
c1.write(name)
|
| 516 |
+
pmin = c2.number_input(
|
| 517 |
+
"Min", min_value=0.0, max_value=pmax,
|
| 518 |
+
value=pmin, step=pstep, key=f"pp_min_{name}"
|
| 519 |
+
)
|
| 520 |
+
# β enforce Max β₯ step
|
| 521 |
+
pmax = c3.number_input(
|
| 522 |
+
"Max", min_value=pstep, max_value=10000.0,
|
| 523 |
+
value=max(pmax, pstep), step=pstep, key=f"pp_max_{name}"
|
| 524 |
+
)
|
| 525 |
+
pstep = c4.number_input(
|
| 526 |
+
"Step", min_value=0.0,
|
| 527 |
+
max_value=(pmax - pmin) if pmax > pmin else 1.0,
|
| 528 |
+
value=pstep, step=max(1e-3, pstep/10),
|
| 529 |
+
key=f"pp_step_{name}"
|
| 530 |
+
)
|
| 531 |
+
st.session_state.pp_ranges[name].update(min=pmin, max=pmax, step=pstep)
|
| 532 |
+
|
| 533 |
+
st.markdown("---")
|
| 534 |
+
|
| 535 |
+
# βββ Optuna Optimize & Display ββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 536 |
+
if st.button("π οΈ Optimize WSSQ"):
|
| 537 |
+
with st.spinner("Running Optunaβ¦"):
|
| 538 |
+
def objective(trial):
|
| 539 |
+
bi_vals = {
|
| 540 |
+
r['mat']: trial.suggest_float(
|
| 541 |
+
f"bio__{r['mat']}", r['min'], r['max'], step=r['step']
|
| 542 |
+
)
|
| 543 |
+
for r in st.session_state.bio_rows
|
| 544 |
+
}
|
| 545 |
+
for m in BIOMATERIAL_OPTIONS:
|
| 546 |
+
bi_vals.setdefault(m, 0.0)
|
| 547 |
+
|
| 548 |
+
cd = 0.0 if cell_line=="NoCellCultured" else trial.suggest_float(
|
| 549 |
+
"cell_density", dr['min'], dr['max'], step=dr['step']
|
| 550 |
+
)
|
| 551 |
+
|
| 552 |
+
pp_vals = {
|
| 553 |
+
name: trial.suggest_float(
|
| 554 |
+
f"pp__{name}",
|
| 555 |
+
st.session_state.pp_ranges[name]['min'],
|
| 556 |
+
st.session_state.pp_ranges[name]['max'],
|
| 557 |
+
step=st.session_state.pp_ranges[name]['step']
|
| 558 |
+
)
|
| 559 |
+
for name in PRINT_PARAM_NAMES
|
| 560 |
+
}
|
| 561 |
+
|
| 562 |
+
feat = {**bi_vals, **pp_vals}
|
| 563 |
+
feat["Cell Density (cells/mL)"] = cd
|
| 564 |
+
feat.update(
|
| 565 |
+
encoder.transform(pd.DataFrame({"Cell Line":[cell_line]}))
|
| 566 |
+
.iloc[0].to_dict()
|
| 567 |
+
)
|
| 568 |
+
|
| 569 |
+
X = pd.DataFrame([feat])
|
| 570 |
+
Xp = X.reindex(columns=feature_order_print, fill_value=0.0)
|
| 571 |
+
Xc = X.reindex(columns=feature_order_cell, fill_value=0.0)
|
| 572 |
+
|
| 573 |
+
p_proba = model_print.predict_proba(scaler_print.transform(Xp))[0]
|
| 574 |
+
c_proba = model_cell .predict_proba(scaler_cell .transform(Xc))[0]
|
| 575 |
+
exp_p = float(np.dot(p_proba, model_print.classes_.astype(float)))
|
| 576 |
+
exp_c = float(np.dot(c_proba, model_cell .classes_.astype(float)))
|
| 577 |
+
|
| 578 |
+
return scaffold_quality_combined(exp_p, exp_c)
|
| 579 |
+
|
| 580 |
+
study = optuna.create_study(direction="maximize")
|
| 581 |
+
study.optimize(objective, n_trials=50)
|
| 582 |
+
best = study.best_trial
|
| 583 |
+
|
| 584 |
+
st.success(f"π Best WSSQ: **{best.value:.3f}**")
|
| 585 |
+
|
| 586 |
+
best_df = pd.Series(best.params, name="value") \
|
| 587 |
+
.rename_axis("parameter") \
|
| 588 |
+
.to_frame()
|
| 589 |
+
st.table(best_df)
|
| 590 |
+
|
| 591 |
+
# βββ Fabrication Procedure via GPT βββββββββββββββββββββββββββββββββββββββββββββββ
|
| 592 |
+
st.markdown("## π Fabrication Procedure")
|
| 593 |
+
with st.spinner("Generating fabrication procedureβ¦"):
|
| 594 |
+
density = best.params.get("cell_density", 0.0)
|
| 595 |
+
prompt = (
|
| 596 |
+
"Based on the following optimized scaffold parameters AND your selected cell line:\n\n"
|
| 597 |
+
f"β’ Cell line: {cell_line}\n"
|
| 598 |
+
"Optimized scaffold parameters:\n"
|
| 599 |
+
f"{best.params}\n\n"
|
| 600 |
+
"Write a detailed, step-by-step fabrication procedure for 3D (bio)printing "
|
| 601 |
+
"this scaffold β including materials, equipment, printing settings, and postβprocessing."
|
| 602 |
+
)
|
| 603 |
+
|
| 604 |
+
resp = client.models.generate_content(
|
| 605 |
+
model="gemini-2.0-flash-001",
|
| 606 |
+
contents=prompt,
|
| 607 |
+
config=types.GenerateContentConfig(
|
| 608 |
+
system_instruction=(
|
| 609 |
+
"You are a biomedical engineering professor with tissue engineering experties. "
|
| 610 |
+
"you know how to print 3d (bio)printed scaffolds in labs."
|
| 611 |
+
)
|
| 612 |
+
)
|
| 613 |
+
)
|
| 614 |
+
|
| 615 |
+
procedure = resp.text
|
| 616 |
+
st.markdown(procedure)
|
catboost_cell_response.cbm
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d8eeb02258c9780147ea7e4030757f3ba7d4d80b7530f74cff79cd3e0481c23e
|
| 3 |
+
size 98406080
|
catboost_printability.cbm
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:3c0a21e8657aa8d990f62750f9a8342227ba51ec7f02136a8882069ba7a64952
|
| 3 |
+
size 81574688
|
cell_line_encoder.joblib
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8c62b2bc4682c3e67f364511201060dea195f93ed9ff90bd930a1443cc3aa73d
|
| 3 |
+
size 25655
|
scaler_cell_response.joblib
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0e8ad571c0a19952513271331ff8140a64eff4325c0b5d11f702ffca2c38a8c9
|
| 3 |
+
size 7703
|
scaler_printability.joblib
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0f5c37a1cb5bd29c1a4fb868808e305545c4930b31a22e25e8e7271e861fe1a4
|
| 3 |
+
size 7703
|