2 |
3 |4 |
5 |6 |
7 |8 |
9 |10 |
11 |12 |
13 | 14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
31 | Transform your protein structure prediction workflow with AFusion - a sleek, intuitive graphical interface that makes AlphaFold3 accessible to everyone. No more command-line hassles - just point, click, and predict. 32 |
33 | 34 | **[Demo site](https://af3gui.streamlit.app/)** *(generate input JSON files ONLY)* 35 | 36 | [**Usable visualization site**](https://af3vis.streamlit.app/) *(fully usable)* 37 | 38 | ## Table of Contents 39 | 40 | - [Features](#features) 41 | - [Prerequisites](#prerequisites) 42 | - [Installation and Running](#installation-and-running) 43 | - [Usage](#usage) 44 | - [Launching AFusion](#launching-afusion) 45 | - [Using the GUI](#using-the-gui) 46 | - [Enhanced Visualization Features](#enhanced-visualization-features) 47 | - [Documentation](#documentation) 48 | - [ToDo](#todo) 49 | - [Screenshots](#screenshots) 50 | - [License](#license) 51 | - [Acknowledgements](#acknowledgements) 52 | 53 | ## ✨ Key Features 54 | 55 | ### Installation & Setup 56 | - **GUI Installer**: Step-by-step visual installation wizard 57 | - **Auto-Configuration**: Handles environment setup and dependencies 58 | 59 | ### Core Functionality 60 | - **Visual Workflow**: Clean, modern interface for job configuration 61 | - **Multi-Entity Support**: Process proteins, RNA, DNA, and ligands 62 | - **Advanced Options**: Customize MSA, templates, and modifications 63 | 64 | ### Execution & Control 65 | - **🚀 Integrated Pipeline**: Direct AlphaFold3 execution from GUI 66 | - **🖥️ Live Monitoring**: Real-time process tracking and console output 67 | - **🧩 Batch Processing**: Python API for automated predictions 68 | 69 | ### **🌟 New Features!** 70 | - **AlphaFold 3 Output Analysis System**: Automatically analyze and visualize results with customizable visualizations and generate detailed PDF reports for streamlined insights. 71 | - **Enhanced Visualization Features** (New in this fork): 72 | - Multiple visualization styles (cartoon, stick, line, sphere) 73 | - Flexible coloring schemes (confidence, chain, secondary structure, rainbow) 74 | - Interactive residue selection and chain sequence viewer 75 | - Advanced export capabilities for scientific and 3D printing formats 76 | - Improved PAE matrix visualization and confidence metrics display 77 | 78 | ## Prerequisites 79 | 80 | Before using AFusion, ensure that you have the following: 81 | 82 | 1. **🐳 Docker Installed**: Docker is required to run AlphaFold 3. Install Docker from the [official website](https://www.docker.com/get-started/). 83 | 84 | 2. **🧬 AlphaFold 3 Installed**: AFusion requires AlphaFold 3 to be installed and set up on your system. Follow the installation instructions provided in the [AlphaFold 3 GitHub Repository](https://github.com/google-deepmind/alphafold3) to deploy AlphaFold 3. **Or you can run step-by-step GUI by**: 85 | 86 | ```bash 87 | afusion install 88 | ``` 89 | 90 | 3. **🐍 Python 3.10 or Higher**: AFusion is built with Python and requires Python 3.10 or higher. 91 | 92 | ## Installation and Running 93 | 94 | 1. **Install AFusion** 95 | 96 | Run the following command in your terminal to install AFusion: 97 | 98 | ```bash 99 | pip install afusion 100 | ``` 101 | 102 | 2. **Run AFusion GUI** 103 | 104 | After installation, you can start AFusion by running: 105 | 106 | ```bash 107 | afusion run 108 | ``` 109 | 110 | This will launch the AFusion graphical user interface (GUI) in your default web browser. 111 | 112 | **Please Note:** 113 | 114 | - **🧬 AlphaFold 3 Installation**: Ensure you have correctly installed AlphaFold 3, including model parameters and required databases, following the [AlphaFold 3 Installation Guide](https://github.com/google-deepmind/alphafold3/blob/main/docs/installation.md). 115 | 116 | - **⚙️ Docker Configuration**: After installing Docker, make sure it is running properly and that your user has permission to execute Docker commands. 117 | 118 | - **📦 Streamlit is Included in Dependencies**: AFusion's installation will automatically install all required dependencies, including Streamlit. There's no need to install it separately. 119 | 120 | ## Usage 121 | 122 | ### Launching AFusion 123 | 124 | 1. **🚀 Start the Streamlit App** 125 | 126 | From the project directory, run: 127 | 128 | ```bash 129 | afusion run 130 | ``` 131 | 132 | 2. **🌐 Access the Application** 133 | 134 | - The application will launch, and Streamlit will provide a local URL (e.g., `http://localhost:8501`). 135 | - Open the provided URL in your web browser to access AFusion. 136 | 137 | ### Using the GUI 138 | 139 | **Find more about input in [here](https://github.com/google-deepmind/alphafold3/blob/main/docs/input.md)**. 140 | 141 | #### 1. Welcome Page 142 | 143 | - **👋 Logo and Introduction**: You'll see the AFusion logo and a brief description. 144 | - **📑 Navigation Sidebar**: Use the sidebar on the left to navigate to different sections of the app. 145 | 146 | #### 2. Job Settings 147 | 148 | - **🏷️ Job Name**: Enter a descriptive name for your job. 149 | - **🔢 Model Seeds**: Provide integer seeds separated by commas (e.g., `1,2,3`). 150 | 151 | #### 3. Sequences 152 | 153 | - **🔬 Number of Entities**: Select how many entities you want to add (Proteins, RNA, DNA, Ligand). 154 | - **📋 Entity Details**: For each entity: 155 | - **⚛️ Entity Type**: Select the type (Protein, RNA, DNA, Ligand). 156 | - **🆔 Entity ID**: Provide an identifier for the entity. 157 | - **🧬 Sequence Input**: Enter the sequence information. 158 | - **✏️ Modifications**: Optionally add modifications with their types and positions. 159 | - **📂 MSA Options**: Choose MSA generation options and provide MSA data if applicable. 160 | - **📜 Templates**: Optionally add template data with mmCIF content and indices. 161 | 162 | #### 4. Bonded Atom Pairs (Optional) 163 | 164 | - **🔗 Add Bonds**: Check the box to add bonded atom pairs. 165 | - **⚛️ Define Bonds**: For each bond, provide details for the first and second atoms, including entity IDs, residue IDs, and atom names. 166 | 167 | #### 5. User Provided CCD (Optional) 168 | 169 | - **📜 User CCD Input**: Paste or enter custom CCD data in mmCIF format. 170 | 171 | #### 6. Generated JSON 172 | 173 | - **📄 Review JSON Content**: The application generates the JSON input file based on your entries. You can review it here. 174 | 175 | #### 7. AlphaFold 3 Execution Settings 176 | 177 | - **🗂️ Paths Configuration**: 178 | - **📁 AF Input Path**: Specify the path to the AlphaFold input directory (e.g., `/home/user/af_input`). 179 | - **📂 AF Output Path**: Specify the path to the output directory (e.g., `/home/user/af_output`). 180 | - **📂 Model Parameters Directory**: Provide the path to the model parameters directory. 181 | - **📂 Databases Directory**: Provide the path to the databases directory. 182 | 183 | - **⚙️ Execution Options**: 184 | - **🏗️ Run Data Pipeline**: Choose whether to run the data pipeline (CPU-intensive). 185 | - **💻 Run Inference**: Choose whether to run inference (requires GPU). 186 | 187 | #### 8. Run AlphaFold 3 188 | 189 | - **💾 Save JSON File**: Click the "Save JSON File" button to save the generated JSON to the specified input path. 190 | - **▶️ Run AlphaFold 3 Now**: Click the "Run AlphaFold 3 Now ▶️" button to execute the AlphaFold 3 prediction using the Docker command. 191 | - **🔧 Docker Command**: The exact Docker command used is displayed for your reference. 192 | - **📊 Command Output**: Execution output is displayed within the app for monitoring. 193 | 194 | 195 | ## Documentation 196 | - Full Documentation in [here](https://alphafold3-gui.readthedocs.io) 197 | 198 | ## ToDo 199 | 200 | - [X] ~~📄 **Bulid Documentation:** Tutorial for using the AFusion API in Python scripts for batch predictions.~~ 201 | - [X] ~~♻️ **Refactor Code and Publish to PyPI**: Refactor the project code for improved modularity and maintainability, and publish the latest version to PyPI for easy installation.~~ 202 | - [X] ~~🔗 **Develop AlphaFold result analysis system**: Design and implement a comprehensive analysis pipeline for AlphaFold prediction results.~~ 203 | - [X] ~~Update the system.~~ 204 | - [ ] ⚛️ **Preset Common Small Molecules & Metal Ions**: Add a dedicated section for quick access to commonly used small molecules and metal ions. 205 | - [ ] 🛠️ **New Tool for Chemical Small Molecules**: Develop a new tool to handle and model chemical small molecules, supporting seamless integration into the prediction pipeline. 206 | - [X] ~~🖥️ **Add Console Output**: Implement a backend console for output to track processes and debug more effectively.~~ 207 | - [X] ~~🧩 **Create API for Batch Predictions**: Develop a standalone function API to allow users to perform batch predictions with afusion in Python scripts.~~ 208 | - [X] ~~**🧭 Create Guided Installation GUI**: To simplify the installation process.~~ 209 | - [X] ~~**🎨 Enhanced Visualization Features**: Implement advanced visualization capabilities with multiple styles and export options.~~ 210 | 211 | ## Screenshots 212 | 213 | ### Visualization GUI Interface 214 | 215 |23 |
24 |25 |
26 |27 |
28 |29 |
30 |31 |
32 |33 |
34 | 35 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
52 | AFusion is a user-friendly graphical interface designed to simplify the process of AlphaFold 3 installation, prediction and visualization, making it accessible to users who prefer a GUI over command-line interactions. 53 |
54 | 55 | **[Demo site](https://af3gui.streamlit.app/)** *(generate input JSON files ONLY)* 56 | 57 | [**Usable visualization site**](https://af3vis.streamlit.app/) *(fully usable)* 58 | 59 | ## Table of Contents 60 | 61 | - [Features](#features) 62 | - [Prerequisites](#prerequisites) 63 | - [Installation and Running](#installation-and-running) 64 | - [Usage](#usage) 65 | - [Launching AFusion](#launching-afusion) 66 | - [Using the GUI](#using-the-gui) 67 | - [Documentation](#documentation) 68 | - [ToDo](#todo) 69 | - [Screenshots](#screenshots) 70 | - [License](#license) 71 | - [Acknowledgements](#acknowledgements) 72 | 73 | ## Features 74 | - **🧭 Guided Installation**: GUI-based installer to simplify the installation process, easily set up the application step-by-step. 75 | - **✨ Intuitive Interface**: Easily configure job settings, sequences, and execution parameters through a clean and modern GUI. 76 | - **📋 Entity Management**: Add multiple entities (Protein, RNA, DNA, Ligand) with support for modifications, MSA options, and templates. 77 | - **⚙️ Dynamic JSON Generation**: Automatically generates the required JSON input file for AlphaFold 3 based on user inputs. 78 | - **🚀 Integrated Execution**: Run AlphaFold 3 directly from the GUI with customizable Docker execution settings. 79 | - **🖥️ Visual Feedback**: Provides command output within the interface for monitoring and debugging. 80 | - **🖥️ Console Output**: Track processes and debug more effectively with backend console output. 81 | - **🧩 API for Batch Predictions**: Perform batch predictions using the AFusion API in Python scripts. 82 | 83 | ### **🌟 New Feature!** 84 | - **AlphaFold 3 Output Analysis System**: Automatically analyze and visualize results with customizable visualizations and generate detailed PDF reports for streamlined insights. 85 | 86 | ## Prerequisites 87 | 88 | Before using AFusion, ensure that you have the following: 89 | 90 | 1. **🐳 Docker Installed**: Docker is required to run AlphaFold 3. Install Docker from the [official website](https://www.docker.com/get-started/). 91 | 92 | 2. **🧬 AlphaFold 3 Installed**: AFusion requires AlphaFold 3 to be installed and set up on your system. Follow the installation instructions provided in the [AlphaFold 3 GitHub Repository](https://github.com/google-deepmind/alphafold3) to deploy AlphaFold 3. **Or you can run step-by-step GUI by**: 93 | 94 | ```bash 95 | afusion install 96 | ``` 97 | 98 | 3. **🐍 Python 3.10 or Higher**: AFusion is built with Python and requires Python 3.10 or higher. 99 | 100 | ## Installation and Running 101 | 102 | 1. **Install AFusion** 103 | 104 | Run the following command in your terminal to install AFusion: 105 | 106 | ```bash 107 | pip install afusion 108 | ``` 109 | 110 | 2. **Run AFusion GUI** 111 | 112 | After installation, you can start AFusion by running: 113 | 114 | ```bash 115 | afusion run 116 | ``` 117 | 118 | This will launch the AFusion graphical user interface (GUI) in your default web browser. 119 | 120 | **Please Note:** 121 | 122 | - **🧬 AlphaFold 3 Installation**: Ensure you have correctly installed AlphaFold 3, including model parameters and required databases, following the [AlphaFold 3 Installation Guide](https://github.com/google-deepmind/alphafold3/blob/main/docs/installation.md). 123 | 124 | - **⚙️ Docker Configuration**: After installing Docker, make sure it is running properly and that your user has permission to execute Docker commands. 125 | 126 | - **📦 Streamlit is Included in Dependencies**: AFusion's installation will automatically install all required dependencies, including Streamlit. There's no need to install it separately. 127 | 128 | If you encounter any issues during installation or usage, please refer to the relevant official documentation or contact us for support. 129 | 130 | ## Usage 131 | 132 | ### Launching AFusion 133 | 134 | 1. **🚀 Start the Streamlit App** 135 | 136 | From the project directory, run: 137 | 138 | ```bash 139 | afusion run 140 | ``` 141 | 142 | 2. **🌐 Access the Application** 143 | 144 | - The application will launch, and Streamlit will provide a local URL (e.g., `http://localhost:8501`). 145 | - Open the provided URL in your web browser to access AFusion. 146 | 147 | ### Using the GUI 148 | 149 | **Find more about input in [here](https://github.com/google-deepmind/alphafold3/blob/main/docs/input.md)**. 150 | 151 | #### 1. Welcome Page 152 | 153 | - **👋 Logo and Introduction**: You'll see the AFusion logo and a brief description. 154 | - **📑 Navigation Sidebar**: Use the sidebar on the left to navigate to different sections of the app. 155 | 156 | #### 2. Job Settings 157 | 158 | - **🏷️ Job Name**: Enter a descriptive name for your job. 159 | - **🔢 Model Seeds**: Provide integer seeds separated by commas (e.g., `1,2,3`). 160 | 161 | #### 3. Sequences 162 | 163 | - **🔬 Number of Entities**: Select how many entities you want to add (Proteins, RNA, DNA, Ligand). 164 | - **📋 Entity Details**: For each entity: 165 | - **⚛️ Entity Type**: Select the type (Protein, RNA, DNA, Ligand). 166 | - **🆔 Entity ID**: Provide an identifier for the entity. 167 | - **🧬 Sequence Input**: Enter the sequence information. 168 | - **✏️ Modifications**: Optionally add modifications with their types and positions. 169 | - **📂 MSA Options**: Choose MSA generation options and provide MSA data if applicable. 170 | - **📜 Templates**: Optionally add template data with mmCIF content and indices. 171 | 172 | #### 4. Bonded Atom Pairs (Optional) 173 | 174 | - **🔗 Add Bonds**: Check the box to add bonded atom pairs. 175 | - **⚛️ Define Bonds**: For each bond, provide details for the first and second atoms, including entity IDs, residue IDs, and atom names. 176 | 177 | #### 5. User Provided CCD (Optional) 178 | 179 | - **📜 User CCD Input**: Paste or enter custom CCD data in mmCIF format. 180 | 181 | #### 6. Generated JSON 182 | 183 | - **📄 Review JSON Content**: The application generates the JSON input file based on your entries. You can review it here. 184 | 185 | #### 7. AlphaFold 3 Execution Settings 186 | 187 | - **🗂️ Paths Configuration**: 188 | - **📁 AF Input Path**: Specify the path to the AlphaFold input directory (e.g., `/home/user/af_input`). 189 | - **📂 AF Output Path**: Specify the path to the output directory (e.g., `/home/user/af_output`). 190 | - **📂 Model Parameters Directory**: Provide the path to the model parameters directory. 191 | - **📂 Databases Directory**: Provide the path to the databases directory. 192 | 193 | - **⚙️ Execution Options**: 194 | - **🏗️ Run Data Pipeline**: Choose whether to run the data pipeline (CPU-intensive). 195 | - **💻 Run Inference**: Choose whether to run inference (requires GPU). 196 | 197 | #### 8. Run AlphaFold 3 198 | 199 | - **💾 Save JSON File**: Click the "Save JSON File" button to save the generated JSON to the specified input path. 200 | - **▶️ Run AlphaFold 3 Now**: Click the "Run AlphaFold 3 Now ▶️" button to execute the AlphaFold 3 prediction using the Docker command. 201 | - **🔧 Docker Command**: The exact Docker command used is displayed for your reference. 202 | - **📊 Command Output**: Execution output is displayed within the app for monitoring. 203 | 204 | ### Visualization Module 🎨📊 205 | 206 | 1. **🚀 Launch Visualization Interface** 207 | 208 | To start the visualization module, run: 209 | 210 | ```bash 211 | afusion visualization 212 | ``` 213 | 214 | 2. **📂 Upload and Analyze Results** 215 | 216 | - **📤 Upload Files**: Upload AlphaFold 3 output files (e.g., `.cif`, `.json`) directly in the visualization interface. 217 | - **🔬 Visual Analysis**: Perform visual analysis for each prediction, with detailed structure displays and customizable plots. 218 | - **📄 Web Reports**: Generate web reports like Alphafold3 Server for the analysis on demand. 219 | 220 | 3. **🔗 Integrated with Prediction GUI** 221 | 222 | - **🎛️ Seamless Integration**: The visualization tools are also integrated into the prediction GUI. Once predictions are complete, you can switch seamlessly to the visualization tab for analysis. 223 | 224 | ## Documentation 225 | - Full Documentation in [here](https://alphafold3-gui.readthedocs.io) 226 | 227 | ## ToDo 228 | 229 | - [X] ~~📄 **Bulid Documentation:** Tutorial for using the AFusion API in Python scripts for batch predictions.~~ 230 | - [X] ~~♻️ **Refactor Code and Publish to PyPI**: Refactor the project code for improved modularity and maintainability, and publish the latest version to PyPI for easy installation.~~ 231 | - [X] ~~🔗 **Develop AlphaFold result analysis system**: Design and implement a comprehensive analysis pipeline for AlphaFold prediction results.~~ 232 | - [X] ~~Update the system.~~ 233 | - [ ] ⚛️ **Preset Common Small Molecules & Metal Ions**: Add a dedicated section for quick access to commonly used small molecules and metal ions. 234 | - [ ] 🛠️ **New Tool for Chemical Small Molecules**: Develop a new tool to handle and model chemical small molecules, supporting seamless integration into the prediction pipeline. 235 | - [X] ~~🖥️ **Add Console Output**: Implement a backend console for output to track processes and debug more effectively.~~ 236 | - [X] ~~🧩 **Create API for Batch Predictions**: Develop a standalone function API to allow users to perform batch predictions with afusion in Python scripts.~~ 237 | - [X] ~~**🧭 Create Guided Installation GUI**: To simplify the installation process.~~ 238 | 239 | # Screenshots 240 | 241 | ### Prediction GUI Interface 242 |A convenient GUI for running AlphaFold 3 predictions
", unsafe_allow_html=True) 144 | st.markdown("If this project helps you, please ⭐️ my project!
", unsafe_allow_html=True) 145 | 146 | #### Sidebar Navigation #### 147 | with st.sidebar: 148 | st.header("Navigation") 149 | st.sidebar.markdown("---") 150 | sections = { 151 | "Job Settings": "job_settings", 152 | "Sequences": "sequences", 153 | "Bonded Atom Pairs": "bonded_atom_pairs", 154 | "User Provided CCD": "user_ccd", 155 | "Generated JSON": "json_content", 156 | "Execution Settings": "execution_settings", 157 | "Run AlphaFold 3": "run_alphafold", 158 | } 159 | for section_name, section_id in sections.items(): 160 | st.markdown(f"{section_name}", unsafe_allow_html=True) 161 | st.markdown("---") 162 | st.markdown("Created by Hanzi 2024.", unsafe_allow_html=True) 163 | 164 | # Main Content 165 | st.markdown('', unsafe_allow_html=True) 166 | st.markdown("### Welcome to AFusion!") 167 | st.markdown("Use this GUI to generate input JSON files and run AlphaFold 3 predictions with ease. Please [install AlphaFold 3](https://github.com/google-deepmind/alphafold3/blob/main/docs/installation.md) before using.") 168 | 169 | st.markdown('', unsafe_allow_html=True) 170 | st.header("📝 Job Settings") 171 | with st.expander("Configure Job Settings", expanded=True): 172 | job_name = st.text_input("Job Name", value="My AlphaFold Job", help="Enter a descriptive name for your job.") 173 | logger.info(f"Job name set to: {job_name}") 174 | model_seeds = st.text_input("Model Seeds (comma-separated)", value="1,2,3", help="Provide integer seeds separated by commas.") 175 | logger.debug(f"Model seeds input: {model_seeds}") 176 | model_seeds_list = [int(seed.strip()) for seed in model_seeds.split(",") if seed.strip().isdigit()] 177 | if not model_seeds_list: 178 | st.error("Please provide at least one valid model seed.") 179 | logger.error("No valid model seeds provided.") 180 | st.stop() 181 | logger.info(f"Model seeds list: {model_seeds_list}") 182 | 183 | st.markdown('', unsafe_allow_html=True) 184 | st.header("📄 Sequences") 185 | sequences = [] 186 | num_entities = st.number_input("Number of Entities", min_value=1, step=1, value=1, help="Select the number of entities you want to add.") 187 | logger.info(f"Number of entities set to: {num_entities}") 188 | 189 | for i in range(int(num_entities)): 190 | st.markdown(f"### Entity {i+1}") 191 | with st.expander(f"Entity {i+1} Details", expanded=True): 192 | entity_type = st.selectbox(f"Select Entity Type", ["Protein 🧬", "RNA 🧫", "DNA 🧬", "Ligand 💊"], key=f"entity_type_{i}") 193 | logger.info(f"Entity {i+1} type: {entity_type}") 194 | 195 | copy_number = st.number_input(f"Copy Number", min_value=1, step=1, value=1, key=f"copy_number_{i}", help="Specify the number of copies of this sequence.") 196 | logger.info(f"Entity {i+1} copy number: {copy_number}") 197 | 198 | # Collect sequence data 199 | if entity_type.startswith("Protein"): 200 | sequence_data = collect_protein_sequence_data(i) 201 | elif entity_type.startswith("RNA"): 202 | sequence_data = collect_rna_sequence_data(i) 203 | elif entity_type.startswith("DNA"): 204 | sequence_data = collect_dna_sequence_data(i) 205 | elif entity_type.startswith("Ligand"): 206 | sequence_data = collect_ligand_sequence_data(i) 207 | else: 208 | st.error(f"Unknown entity type: {entity_type}") 209 | logger.error(f"Unknown entity type: {entity_type}") 210 | continue # Skip to next entity 211 | 212 | # Handle IDs based on copy number 213 | entity_ids = [] 214 | if copy_number >= 1: 215 | # Allow user to input multiple IDs 216 | entity_id = st.text_input(f"Entity ID(s) (comma-separated)", key=f"entity_id_{i}", help="Provide entity ID(s), separated by commas if multiple.") 217 | if not entity_id.strip(): 218 | st.error("Entity ID is required.") 219 | logger.error("Entity ID missing.") 220 | continue 221 | entity_ids = re.split(r"\s*,\s*", entity_id) 222 | if len(entity_ids) != copy_number: 223 | st.error(f"Please provide {copy_number} ID(s) separated by commas.") 224 | logger.error(f"Number of IDs provided does not match copy number for Entity {i+1}.") 225 | continue 226 | logger.debug(f"Entity {i+1} IDs: {entity_ids}") 227 | 228 | for copy_id in entity_ids: 229 | # Clone the sequence data and set the ID 230 | sequence_entry = sequence_data.copy() 231 | sequence_entry['id'] = copy_id 232 | # Wrap the entry appropriately 233 | if entity_type.startswith("Protein"): 234 | sequences.append({"protein": sequence_entry}) 235 | elif entity_type.startswith("RNA"): 236 | sequences.append({"rna": sequence_entry}) 237 | elif entity_type.startswith("DNA"): 238 | sequences.append({"dna": sequence_entry}) 239 | elif entity_type.startswith("Ligand"): 240 | sequences.append({"ligand": sequence_entry}) 241 | else: 242 | st.error("Copy number must be at least 1.") 243 | logger.error("Invalid copy number.") 244 | continue 245 | 246 | st.markdown('', unsafe_allow_html=True) 247 | st.header("🔗 Bonded Atom Pairs (Optional)") 248 | bonded_atom_pairs = [] 249 | add_bonds = st.checkbox("Add Bonded Atom Pairs") 250 | if add_bonds: 251 | num_bonds = st.number_input("Number of Bonds", min_value=1, step=1, key="num_bonds") 252 | for b in range(int(num_bonds)): 253 | st.markdown(f"**Bond {b+1}**") 254 | bond = handle_bond(b) 255 | if bond: 256 | bonded_atom_pairs.append(bond) 257 | logger.debug(f"Added bond: {bond}") 258 | 259 | st.markdown('', unsafe_allow_html=True) 260 | st.header("🧩 User Provided CCD (Optional)") 261 | user_ccd = st.text_area("User CCD (mmCIF format)") 262 | if user_ccd: 263 | logger.debug("User provided CCD data.") 264 | 265 | # Generate JSON Data 266 | alphafold_input = { 267 | "name": job_name, 268 | "modelSeeds": model_seeds_list, 269 | "sequences": sequences, 270 | "dialect": "alphafold3", 271 | "version": 1 272 | } 273 | 274 | if bonded_atom_pairs: 275 | alphafold_input["bondedAtomPairs"] = bonded_atom_pairs 276 | 277 | if user_ccd: 278 | alphafold_input["userCCD"] = user_ccd 279 | 280 | # Convert JSON to string 281 | json_output = json.dumps(alphafold_input, indent=2) 282 | logger.debug(f"Generated JSON:\n{json_output}") 283 | 284 | st.markdown('', unsafe_allow_html=True) 285 | st.header("📄 Generated JSON Content") 286 | st.code(json_output, language="json") 287 | 288 | st.markdown('', unsafe_allow_html=True) 289 | st.header("⚙️ AlphaFold 3 Execution Settings") 290 | with st.expander("Configure Execution Settings", expanded=True): 291 | # Paths for execution 292 | af_input_path = st.text_input("AF Input Path", value=os.path.expanduser("~/af_input"), help="Path to AlphaFold input directory.") 293 | af_output_path = st.text_input("AF Output Path", value=os.path.expanduser("~/af_output"), help="Path to AlphaFold output directory.") 294 | model_parameters_dir = st.text_input("Model Parameters Directory", value="/path/to/models", help="Path to model parameters directory.") 295 | databases_dir = st.text_input("Databases Directory", value="/path/to/databases", help="Path to databases directory.") 296 | 297 | logger.debug(f"Execution settings: af_input_path={af_input_path}, af_output_path={af_output_path}, model_parameters_dir={model_parameters_dir}, databases_dir={databases_dir}") 298 | 299 | # Additional options 300 | run_data_pipeline = st.checkbox("Run Data Pipeline (CPU only, time-consuming)", value=True) 301 | run_inference = st.checkbox("Run Inference (requires GPU)", value=True) 302 | 303 | logger.info(f"Run data pipeline: {run_data_pipeline}, Run inference: {run_inference}") 304 | 305 | # Bucket Sizes Configuration 306 | use_custom_buckets = st.checkbox("Specify Custom Compilation Buckets", value=False) 307 | if use_custom_buckets: 308 | buckets_input = st.text_input( 309 | "Bucket Sizes (comma-separated)", 310 | value="256,512,768,1024,1280,1536,2048,2560,3072,3584,4096,4608,5120", 311 | help="Specify bucket sizes separated by commas. Example: 256,512,768,..." 312 | ) 313 | # Parse buckets 314 | bucket_sizes = [int(size.strip()) for size in buckets_input.split(",") if size.strip().isdigit()] 315 | if not bucket_sizes: 316 | st.error("Please provide at least one valid bucket size.") 317 | logger.error("No valid bucket sizes provided.") 318 | st.stop() 319 | logger.debug(f"Custom bucket sizes: {bucket_sizes}") 320 | else: 321 | bucket_sizes = [] # Empty list indicates default buckets 322 | 323 | st.markdown('', unsafe_allow_html=True) 324 | st.header("🚀 Run AlphaFold 3") 325 | # Save JSON to file 326 | json_save_path = os.path.join(af_input_path, "fold_input.json") 327 | try: 328 | os.makedirs(af_input_path, exist_ok=True) 329 | with open(json_save_path, "w") as json_file: 330 | json.dump(alphafold_input, json_file, indent=2) 331 | st.success(f"JSON file saved to {json_save_path}") 332 | logger.info(f"JSON file saved to {json_save_path}") 333 | except Exception as e: 334 | st.error(f"Error saving JSON file: {e}") 335 | logger.error(f"Error saving JSON file: {e}") 336 | 337 | # Run AlphaFold 3 338 | if st.button("Run AlphaFold 3 Now ▶️"): 339 | # Build the Docker command 340 | docker_command = ( 341 | f"docker run --rm " 342 | f"--volume {af_input_path}:/root/af_input " 343 | f"--volume {af_output_path}:/root/af_output " 344 | f"--volume {model_parameters_dir}:/root/models " 345 | f"--volume {databases_dir}:/root/public_databases " 346 | f"--gpus all " 347 | f"alphafold3 " 348 | f"python run_alphafold.py " 349 | f"--json_path=/root/af_input/fold_input.json " 350 | f"--model_dir=/root/models " 351 | f"--output_dir=/root/af_output " 352 | f"{'--run_data_pipeline' if run_data_pipeline else ''} " 353 | f"{'--run_inference' if run_inference else ''} " 354 | f"{'--buckets ' + ','.join(map(str, bucket_sizes)) if bucket_sizes else ''}" 355 | ) 356 | 357 | st.markdown("#### Docker Command:") 358 | st.code(docker_command, language="bash") 359 | logger.debug(f"Docker command: {docker_command}") 360 | 361 | # Run the command and display output in a box 362 | with st.spinner('AlphaFold 3 is running...'): 363 | output_placeholder = st.empty() 364 | output = run_alphafold(docker_command, placeholder=output_placeholder) 365 | 366 | # Display the output in an expander box 367 | st.markdown("#### Command Output:") 368 | with st.expander("Show Command Output 📄", expanded=False): 369 | st.text_area("Command Output", value=output, height=400) 370 | 371 | logger.info("AlphaFold 3 execution completed.") 372 | 373 | # Check if the output directory exists 374 | job_output_folder_name = job_name.lower().replace(' ', '_') 375 | output_folder_path = os.path.join(af_output_path, job_output_folder_name) 376 | 377 | if os.path.exists(output_folder_path): 378 | st.success("AlphaFold 3 execution completed successfully.") 379 | st.info(f"Results are saved in: {output_folder_path}") 380 | logger.info(f"Results saved in: {output_folder_path}") 381 | 382 | # Provide download option 383 | st.markdown("### Download Results 📥") 384 | zip_data = compress_output_folder(output_folder_path, job_output_folder_name) 385 | st.download_button( 386 | label="Download ZIP", 387 | data=zip_data, 388 | file_name=f"{job_output_folder_name}.zip", 389 | mime="application/zip" 390 | ) 391 | logger.info("User downloaded the results ZIP file.") 392 | 393 | # Visualize the results directly on the same page 394 | st.markdown("### Visualize Your Results") 395 | st.write("The prediction results are visualized below.") 396 | 397 | # Get the paths to the necessary files 398 | def find_file_by_suffix(directory_path, suffix): 399 | for root, dirs, files in os.walk(directory_path): 400 | for file_name in files: 401 | if file_name.endswith(suffix): 402 | return os.path.join(root, file_name) 403 | return None 404 | 405 | def find_file_by_suffix_exclude_summary(directory_path, suffix, exclude_name): 406 | for root, dirs, files in os.walk(directory_path): 407 | for file_name in files: 408 | if file_name.endswith(suffix) and exclude_name not in file_name: 409 | return os.path.join(root, file_name) 410 | return None 411 | 412 | required_files = { 413 | "model.cif": find_file_by_suffix(output_folder_path, 'model.cif'), 414 | "confidences.json": find_file_by_suffix_exclude_summary(output_folder_path, 'confidences.json', 'summary_confidences.json'), 415 | "summary_confidences.json": find_file_by_suffix(output_folder_path, 'summary_confidences.json') 416 | } 417 | 418 | missing_files = [fname for fname, fpath in required_files.items() if fpath is None] 419 | if missing_files: 420 | st.error(f"Missing files: {', '.join(missing_files)} in the output directory or its subdirectories.") 421 | logger.error(f"Missing files: {', '.join(missing_files)}") 422 | else: 423 | st.success("All required files are found.") 424 | logger.info(f"Required files found: {required_files}") 425 | 426 | # Load the data 427 | structure, cif_content = read_cif_file(required_files["model.cif"]) 428 | residue_bfactors, ligands = extract_residue_bfactors(structure) 429 | pae_matrix, token_chain_ids = extract_pae_from_json(required_files["confidences.json"]) 430 | summary_data = extract_summary_confidences(required_files["summary_confidences.json"]) 431 | 432 | chain_ids = list(set(token_chain_ids)) 433 | chain_ids.sort() # Sort for consistency 434 | 435 | logger.debug("Successfully loaded data from output folder.") 436 | 437 | # Display the visualizations 438 | display_visualization_header() 439 | 440 | # Create two columns with width ratio 3:2 441 | col1, col2 = st.columns([3, 2]) 442 | 443 | with col1: 444 | st.write("### 3D Model Visualization") 445 | if residue_bfactors or ligands: 446 | view_html = visualize_structure(residue_bfactors, ligands, cif_content) 447 | st.components.v1.html(view_html, height=600, scrolling=False) 448 | else: 449 | st.error("Failed to extract atom data.") 450 | logger.error("Failed to extract atom data.") 451 | 452 | with col2: 453 | # Visualize the PAE matrix 454 | visualize_pae(pae_matrix, token_chain_ids) 455 | 456 | # Display summary data 457 | display_summary_data(summary_data, chain_ids) 458 | else: 459 | st.error("AlphaFold 3 execution did not complete successfully. Please check the logs.") 460 | logger.error("AlphaFold 3 execution did not complete successfully.") 461 | else: 462 | st.info("Click the 'Run AlphaFold 3 Now ▶️' button to execute the command.") 463 | 464 | st.markdown("---") 465 | 466 | # Provide access to the log file 467 | st.markdown("### Download Log File 📥") 468 | with open('afusion.log', 'r') as log_file: 469 | log_content = log_file.read() 470 | st.download_button( 471 | label="Download Log File", 472 | data=log_content, 473 | file_name='afusion.log', 474 | mime='text/plain' 475 | ) 476 | 477 | # Display log content in the app 478 | with st.expander("Show Log Content 📄", expanded=False): 479 | st.text_area("Log Content", value=log_content, height=200) 480 | 481 | st.markdown("---") 482 | # Add footer 483 | st.markdown("© 2024 Hanzi. All rights reserved.
", unsafe_allow_html=True) 484 | 485 | if __name__ == "__main__": 486 | main() 487 | -------------------------------------------------------------------------------- /afusion/bonds.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | from loguru import logger 3 | 4 | def handle_bond(b): 5 | bond_col1, bond_col2 = st.columns(2) 6 | with bond_col1: 7 | st.markdown("**First Atom**") 8 | entity_id1 = st.text_input(f"Entity ID 1", key=f"bond_entity1_{b}") 9 | residue_id1 = st.number_input(f"Residue ID 1", min_value=1, step=1, key=f"bond_residue1_{b}") 10 | atom_name1 = st.text_input(f"Atom Name 1", key=f"bond_atom1_{b}") 11 | with bond_col2: 12 | st.markdown("**Second Atom**") 13 | entity_id2 = st.text_input(f"Entity ID 2", key=f"bond_entity2_{b}") 14 | residue_id2 = st.number_input(f"Residue ID 2", min_value=1, step=1, key=f"bond_residue2_{b}") 15 | atom_name2 = st.text_input(f"Atom Name 2", key=f"bond_atom2_{b}") 16 | 17 | if not (entity_id1 and atom_name1 and entity_id2 and atom_name2): 18 | st.error("All fields are required for defining a bond.") 19 | logger.error(f"Fields missing for bond {b+1}.") 20 | return None 21 | 22 | bond = [ 23 | [entity_id1, residue_id1, atom_name1], 24 | [entity_id2, residue_id2, atom_name2] 25 | ] 26 | logger.debug(f"Bond {b+1} defined as: {bond}") 27 | return bond 28 | -------------------------------------------------------------------------------- /afusion/cli.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import sys 5 | import argparse 6 | 7 | def main(): 8 | parser = argparse.ArgumentParser( 9 | prog='afusion', 10 | description='Afusion command line tool' 11 | ) 12 | subparsers = parser.add_subparsers( 13 | dest='command', 14 | help='Sub-commands' 15 | ) 16 | 17 | # 'install' sub-command 18 | install_parser = subparsers.add_parser( 19 | 'install', 20 | help='Launch the installation GUI' 21 | ) 22 | 23 | # 'run' sub-command 24 | run_parser = subparsers.add_parser( 25 | 'run', 26 | help='Run the main application (Alphafold3 GUI)' 27 | ) 28 | 29 | # 'visualization' sub-command 30 | visualization_parser = subparsers.add_parser( 31 | 'visualization', 32 | help='Launch the Visualization App' 33 | ) 34 | visualization_parser.add_argument( 35 | '--output_folder_path', 36 | type=str, 37 | default='', 38 | help='Path to the AlphaFold 3 output directory for visualization' 39 | ) 40 | 41 | # Parse the command-line arguments 42 | args = parser.parse_args() 43 | 44 | if args.command == 'install': 45 | current_dir = os.path.dirname(os.path.abspath(__file__)) 46 | root_dir = os.path.abspath(os.path.join(current_dir, '..')) 47 | if root_dir not in sys.path: 48 | sys.path.insert(0, root_dir) 49 | 50 | app_path = os.path.join(root_dir, 'afusion/install.py') 51 | 52 | streamlit_command = [ 53 | 'streamlit', 'run', app_path, 54 | '--server.fileWatcherType=none' 55 | ] + sys.argv[2:] # Skip the first two arguments ('afusion', 'install') 56 | os.execvp('streamlit', streamlit_command) 57 | 58 | elif args.command == 'run': 59 | # Run the main application (Alphafold3 GUI) 60 | current_dir = os.path.dirname(os.path.abspath(__file__)) 61 | root_dir = os.path.abspath(os.path.join(current_dir, '..')) 62 | if root_dir not in sys.path: 63 | sys.path.insert(0, root_dir) 64 | 65 | app_path = os.path.join(root_dir, 'afusion/app.py') 66 | 67 | streamlit_command = [ 68 | 'streamlit', 'run', app_path, 69 | '--server.fileWatcherType=none' 70 | ] + sys.argv[2:] # Skip the first two arguments ('afusion', 'run') 71 | os.execvp('streamlit', streamlit_command) 72 | 73 | elif args.command == 'visualization': 74 | # Run the Visualization App 75 | current_dir = os.path.dirname(os.path.abspath(__file__)) 76 | root_dir = os.path.abspath(os.path.join(current_dir, '..')) 77 | if root_dir not in sys.path: 78 | sys.path.insert(0, root_dir) 79 | 80 | app_path = os.path.join(root_dir, 'afusion/visualization.py') 81 | 82 | streamlit_command = [ 83 | 'streamlit', 'run', app_path, 84 | '--server.port', '8502', 85 | '--server.fileWatcherType=none' 86 | ] 87 | 88 | # Pass the output_folder_path as command-line argument 89 | if args.output_folder_path: 90 | streamlit_command += ['--', f'--output_folder_path={args.output_folder_path}'] 91 | 92 | os.execvp('streamlit', streamlit_command) 93 | 94 | else: 95 | # Handle other commands or display help information 96 | parser.print_help() 97 | 98 | if __name__ == '__main__': 99 | main() 100 | -------------------------------------------------------------------------------- /afusion/execution.py: -------------------------------------------------------------------------------- 1 | # afusion/execution.py 2 | 3 | import subprocess 4 | from loguru import logger 5 | 6 | def run_alphafold(command, placeholder=None): 7 | """ 8 | Runs the AlphaFold Docker command and captures output. 9 | Uses placeholder to update output in real-time if provided. 10 | """ 11 | process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, shell=True) 12 | output_lines = [] 13 | for line in iter(process.stdout.readline, ''): 14 | if line: 15 | output_lines.append(line) 16 | logger.debug(line.strip()) 17 | # Update placeholder if provided 18 | if placeholder is not None: 19 | placeholder.markdown(f"```\n{''.join(output_lines)}\n```") 20 | process.stdout.close() 21 | process.wait() 22 | return ''.join(output_lines) 23 | -------------------------------------------------------------------------------- /afusion/install.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | import subprocess 3 | import os 4 | import sys 5 | import time 6 | 7 | # Import logging library 8 | from loguru import logger 9 | 10 | # Configure the logger 11 | logger.add("install.log", rotation="1 MB", level="DEBUG") 12 | 13 | # Set page configuration and theme 14 | st.set_page_config( 15 | page_title="AlphaFold 3 Installation Guide", 16 | page_icon="🧬", 17 | layout="wide", 18 | initial_sidebar_state="expanded", 19 | ) 20 | 21 | # Custom CSS styling 22 | st.markdown(""" 23 | 41 | """, unsafe_allow_html=True) 42 | 43 | # Title and subtitle 44 | st.markdown("Please follow the steps below to install AlphaFold 3
", unsafe_allow_html=True) 46 | st.markdown("If this project helps you, please ⭐️ my project!
", unsafe_allow_html=True) 47 | 48 | # Sidebar navigation 49 | st.sidebar.title("Navigation") 50 | st.sidebar.markdown("---") 51 | steps = { 52 | "1️⃣ Environment Preparation": "env_prep", 53 | "2️⃣ Install Docker": "install_docker", 54 | "3️⃣ Install NVIDIA Drivers": "install_nvidia", 55 | "4️⃣ Download AlphaFold 3 Source Code": "download_code", 56 | "5️⃣ Obtain Genetic Databases": "download_db", 57 | "6️⃣ Obtain Model Parameters": "obtain_models", 58 | "7️⃣ Build Docker Container": "build_docker", 59 | "8️⃣ Run Test": "run_test", 60 | } 61 | for step_name, step_id in steps.items(): 62 | st.sidebar.markdown(f"{step_name}", unsafe_allow_html=True) 63 | st.sidebar.markdown("---") 64 | st.sidebar.markdown("© 2024 Your Name. All rights reserved.", unsafe_allow_html=True) 65 | 66 | # Main content 67 | st.markdown("## 1️⃣ Environment Preparation", unsafe_allow_html=True) 68 | st.markdown('', unsafe_allow_html=True) 69 | 70 | st.markdown("Before getting started, please ensure that your system meets the following requirements:") 71 | st.markdown(""" 72 | - Running **Linux** operating system (Ubuntu 22.04 LTS is recommended) 73 | - **NVIDIA GPU** installed with Compute Capability **8.0** or higher 74 | - At least **64GB** of RAM 75 | - At least **1TB** of disk space (**SSD** is recommended) 76 | """) 77 | 78 | with st.expander("Check System Environment", expanded=False): 79 | st.markdown("Click the button below to check your system environment.") 80 | if st.button("Check Environment", key="env_check"): 81 | # Check Operating System 82 | logger.info("Checking Operating System...") 83 | os_info = subprocess.getoutput("lsb_release -a") 84 | st.markdown("#### Operating System Info:") 85 | st.code(os_info, language="bash") 86 | logger.debug(f"Operating System Info:\n{os_info}") 87 | 88 | # Check GPU 89 | logger.info("Checking GPU...") 90 | gpu_info = subprocess.getoutput("nvidia-smi") 91 | st.markdown("#### GPU Info:") 92 | st.code(gpu_info, language="bash") 93 | logger.debug(f"GPU Info:\n{gpu_info}") 94 | 95 | # Check Memory 96 | logger.info("Checking Memory...") 97 | mem_info = subprocess.getoutput("free -h") 98 | st.markdown("#### Memory Info:") 99 | st.code(mem_info, language="bash") 100 | logger.debug(f"Memory Info:\n{mem_info}") 101 | 102 | # Check Disk Space 103 | logger.info("Checking Disk Space...") 104 | disk_info = subprocess.getoutput("df -h") 105 | st.markdown("#### Disk Space Info:") 106 | st.code(disk_info, language="bash") 107 | logger.debug(f"Disk Space Info:\n{disk_info}") 108 | 109 | st.markdown("## 2️⃣ Install Docker", unsafe_allow_html=True) 110 | st.markdown('', unsafe_allow_html=True) 111 | 112 | st.markdown("AlphaFold 3 depends on Docker for execution. Next, we'll install and configure Docker.") 113 | 114 | with st.expander("Install Docker", expanded=False): 115 | st.markdown("Click the button below to begin installing Docker.") 116 | st.warning("**Note:** Some commands require `sudo` privileges. Please run these commands in your terminal when prompted.") 117 | if st.button("Install Docker", key="install_docker"): 118 | st.info("Please run the following commands in your terminal:") 119 | docker_commands = """ 120 | sudo apt-get update 121 | sudo apt-get install -y ca-certificates curl 122 | sudo install -m 0755 -d /etc/apt/keyrings 123 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg 124 | sudo chmod a+r /etc/apt/keyrings/docker.gpg 125 | echo \\ 126 | "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \\ 127 | https://download.docker.com/linux/ubuntu \\ 128 | $(lsb_release -cs) stable" | \\ 129 | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 130 | sudo apt-get update 131 | sudo apt-get install -y docker-ce docker-ce-cli containerd.io 132 | """ 133 | st.code(docker_commands, language="bash") 134 | st.info("After running the above commands, click the 'Verify Docker Installation' button below.") 135 | if st.button("Verify Docker Installation", key="verify_docker"): 136 | try: 137 | docker_version = subprocess.getoutput("docker --version") 138 | st.success(f"Docker installed successfully! {docker_version}") 139 | logger.info(f"Docker installed successfully! {docker_version}") 140 | except Exception as e: 141 | st.error("Docker is not installed correctly. Please ensure you've run the commands above.") 142 | logger.error(f"Docker installation verification error: {e}") 143 | 144 | st.markdown("## 3️⃣ Install NVIDIA Drivers", unsafe_allow_html=True) 145 | st.markdown('', unsafe_allow_html=True) 146 | 147 | st.markdown("Next, we'll install the appropriate NVIDIA drivers for your GPU.") 148 | 149 | with st.expander("Install NVIDIA Drivers", expanded=False): 150 | st.markdown("Click the button below to begin installing NVIDIA drivers.") 151 | st.warning("**Note:** This step requires `sudo` privileges. Please run the commands in your terminal when prompted.") 152 | if st.button("Install NVIDIA Drivers", key="install_nvidia"): 153 | st.info("Please run the following commands in your terminal:") 154 | nvidia_commands = """ 155 | sudo apt-get update 156 | sudo apt-get install -y ubuntu-drivers-common 157 | sudo ubuntu-drivers install 158 | """ 159 | st.code(nvidia_commands, language="bash") 160 | st.info("After running the above commands, reboot your system and then click the 'Verify NVIDIA Installation' button below.") 161 | if st.button("Verify NVIDIA Installation", key="verify_nvidia"): 162 | try: 163 | nvidia_info = subprocess.getoutput("nvidia-smi") 164 | if "NVIDIA-SMI" in nvidia_info: 165 | st.success("NVIDIA drivers installed successfully!") 166 | st.code(nvidia_info, language="bash") 167 | logger.info("NVIDIA drivers installed successfully!") 168 | else: 169 | st.error("NVIDIA drivers are not installed correctly. Please ensure you've run the commands above and rebooted your system.") 170 | logger.error("NVIDIA drivers verification failed.") 171 | except Exception as e: 172 | st.error(f"An error occurred while verifying NVIDIA drivers: {e}") 173 | logger.error(f"NVIDIA drivers verification error: {e}") 174 | 175 | st.markdown("## 4️⃣ Download AlphaFold 3 Source Code", unsafe_allow_html=True) 176 | st.markdown('', unsafe_allow_html=True) 177 | 178 | st.markdown("Now, we'll clone the AlphaFold 3 source code from GitHub.") 179 | 180 | with st.expander("Download Source Code", expanded=False): 181 | st.markdown("Click the button below to begin downloading the AlphaFold 3 source code.") 182 | st.warning("**Note:** Some commands may require `sudo` privileges. Please run these commands in your terminal when prompted.") 183 | if st.button("Download Source Code", key="clone_code"): 184 | st.info("Please run the following commands in your terminal:") 185 | git_commands = """ 186 | sudo apt-get install -y git 187 | git clone https://github.com/google-deepmind/alphafold3.git 188 | """ 189 | st.code(git_commands, language="bash") 190 | st.info("After running the above commands, ensure the 'alphafold3' directory has been created.") 191 | 192 | st.markdown("## 5️⃣ Obtain Genetic Databases", unsafe_allow_html=True) 193 | st.markdown('', unsafe_allow_html=True) 194 | 195 | st.markdown("AlphaFold 3 requires multiple genetic databases to run. Downloading and setting up these databases may take some time.") 196 | 197 | with st.expander("Download Genetic Databases", expanded=False): 198 | st.markdown("Click the button below to begin downloading the genetic databases.") 199 | db_dir = st.text_input("Please enter the database download directory (absolute path):", value=f"{os.path.expanduser('~')}/alphafold3_databases") 200 | st.warning("**Note:** This step requires `sudo` privileges. Please run the commands in your terminal when prompted.") 201 | if st.button("Download Databases", key="download_db"): 202 | st.info("Please run the following commands in your terminal:") 203 | db_commands = f""" 204 | sudo apt-get install -y wget zstd 205 | cd alphafold3 # Navigate to the AlphaFold 3 directory 206 | ./fetch_databases.sh {db_dir} 207 | """ 208 | st.code(db_commands, language="bash") 209 | st.info("This process may take a long time. Please be patient and ensure you have sufficient disk space.") 210 | 211 | st.markdown("## 6️⃣ Obtain Model Parameters", unsafe_allow_html=True) 212 | st.markdown('', unsafe_allow_html=True) 213 | 214 | st.markdown("The AlphaFold 3 model parameters require requesting access.") 215 | 216 | with st.expander("Request Access to Model Parameters", expanded=False): 217 | st.markdown("Please [**click here**](https://forms.gle/svvpY4u2jsHEwWYS6) to fill out the form to request access to AlphaFold 3 model parameters.") 218 | st.markdown("Once you have obtained the model parameters, please place them in an appropriate directory.") 219 | 220 | st.markdown("## 7️⃣ Build Docker Container", unsafe_allow_html=True) 221 | st.markdown('', unsafe_allow_html=True) 222 | 223 | st.markdown("Now, we'll build the Docker container for AlphaFold 3.") 224 | 225 | with st.expander("Build Docker Container", expanded=False): 226 | st.markdown("Click the button below to begin building the Docker container. This may take some time. Please be patient.") 227 | st.warning("**Note:** This step may require `sudo` privileges. Please run the commands in your terminal when prompted.") 228 | if st.button("Build Docker Container", key="build_docker"): 229 | st.info("Please run the following commands in your terminal:") 230 | build_commands = """ 231 | cd alphafold3 # Navigate to the AlphaFold 3 directory 232 | sudo docker build -t alphafold3 -f docker/Dockerfile . 233 | """ 234 | st.code(build_commands, language="bash") 235 | st.info("After running the above commands, the Docker container should be built successfully.") 236 | 237 | st.markdown("## 8️⃣ Run Test", unsafe_allow_html=True) 238 | st.markdown('', unsafe_allow_html=True) 239 | 240 | st.markdown("Finally, we'll run a simple test to verify that AlphaFold 3 has been installed successfully.") 241 | 242 | with st.expander("Run Test", expanded=False): 243 | st.markdown("Click the button below to begin the test.") 244 | input_dir = st.text_input("Please enter the input directory (absolute path):", value=f"{os.path.expanduser('~')}/af_input") 245 | output_dir = st.text_input("Please enter the output directory (absolute path):", value=f"{os.path.expanduser('~')}/af_output") 246 | model_dir = st.text_input("Please enter the model parameters directory (absolute path):", value=f"{os.path.expanduser('~')}/alphafold3_models") 247 | db_dir = st.text_input("Please enter the database directory (absolute path):", value=f"{os.path.expanduser('~')}/alphafold3_databases") 248 | st.warning("**Note:** This step may require `sudo` privileges. Please run the commands in your terminal when prompted.") 249 | if st.button("Run Test", key="run_test"): 250 | st.info("Please ensure that you have prepared an appropriate input JSON file in the input directory.") 251 | st.info("Please run the following command in your terminal:") 252 | test_command = f""" 253 | sudo docker run -it \\ 254 | --volume {input_dir}:/root/af_input \\ 255 | --volume {output_dir}:/root/af_output \\ 256 | --volume {model_dir}:/root/models \\ 257 | --volume {db_dir}:/root/public_databases \\ 258 | --gpus all \\ 259 | alphafold3 \\ 260 | python run_alphafold.py \\ 261 | --json_path=/root/af_input/fold_input.json \\ 262 | --model_dir=/root/models \\ 263 | --output_dir=/root/af_output 264 | """ 265 | st.code(test_command, language="bash") 266 | st.info("After running the above command, the test should execute. Please check the output directory for results.") 267 | 268 | st.markdown("🎉 Congratulations, AlphaFold 3 has been successfully installed!
", unsafe_allow_html=True) 269 | st.markdown("---") 270 | 271 | # Provide access to the log file 272 | st.markdown("### Download Log File 📥") 273 | if os.path.exists('install.log'): 274 | with open('install.log', 'r') as log_file: 275 | log_content = log_file.read() 276 | st.download_button( 277 | label="Download Log File", 278 | data=log_content, 279 | file_name='install.log', 280 | mime='text/plain' 281 | ) 282 | 283 | # Display log content in the app 284 | with st.expander("Show Log Content 📄", expanded=False): 285 | st.text_area("Log Content", value=log_content, height=200) 286 | else: 287 | st.info("Log file not found. It will be created after you run some steps in the installation.") 288 | st.markdown("---") 289 | # Add footer 290 | st.markdown("© 2024 Your Name. All rights reserved.
", unsafe_allow_html=True) 291 | -------------------------------------------------------------------------------- /afusion/sequence_input.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | import re 3 | from loguru import logger 4 | 5 | def collect_protein_sequence_data(i): 6 | sequence = st.text_area(f"Protein Sequence (Entity {i+1})", key=f"sequence_{i}", help="Enter the protein sequence.") 7 | logger.debug(f"Protein sequence input for Entity {i+1}.") 8 | 9 | # Modifications 10 | modifications_list = [] 11 | add_modifications = st.checkbox(f"Add Modifications", key=f"add_modifications_{i}") 12 | if add_modifications: 13 | num_modifications = st.number_input(f"Number of Modifications", min_value=1, step=1, key=f"num_modifications_{i}") 14 | for j in range(int(num_modifications)): 15 | st.markdown(f"**Modification {j+1}**") 16 | mod_col1, mod_col2 = st.columns(2) 17 | with mod_col1: 18 | mod_type = st.text_input(f"Modification Type (ptmType)", key=f"mod_type_{i}_{j}") 19 | with mod_col2: 20 | mod_position = st.number_input(f"Modification Position (ptmPosition)", min_value=1, step=1, key=f"mod_position_{i}_{j}") 21 | modifications_list.append({"ptmType": mod_type, "ptmPosition": mod_position}) 22 | logger.debug(f"Added modification: {modifications_list[-1]}") 23 | 24 | # MSA Options 25 | msa_option = st.selectbox(f"MSA Option", ["Auto-generate 🛠️", "Don't use MSA 🚫", "Upload MSA 📄"], key=f"msa_option_{i}") 26 | 27 | unpaired_msa = "" 28 | paired_msa = "" 29 | if msa_option == "Upload MSA 📄": 30 | unpaired_msa = st.text_area(f"Unpaired MSA", key=f"unpaired_msa_{i}") 31 | paired_msa = st.text_area(f"Paired MSA", key=f"paired_msa_{i}") 32 | logger.debug(f"Entity {i+1} uploaded MSA.") 33 | elif msa_option == "Don't use MSA 🚫": 34 | unpaired_msa = "" 35 | paired_msa = "" 36 | logger.debug(f"Entity {i+1} chose not to use MSA.") 37 | elif msa_option == "Auto-generate 🛠️": 38 | unpaired_msa = None 39 | paired_msa = None 40 | logger.debug(f"Entity {i+1} chose to auto-generate MSA.") 41 | 42 | # Templates 43 | templates_list = [] 44 | add_templates = st.checkbox(f"Add Templates", key=f"add_templates_{i}") 45 | if add_templates: 46 | num_templates = st.number_input(f"Number of Templates", min_value=1, step=1, key=f"num_templates_{i}") 47 | for k in range(int(num_templates)): 48 | st.markdown(f"**Template {k+1}**") 49 | mmcif_content = st.text_area(f"mmCIF Content", key=f"mmcif_{i}_{k}") 50 | query_indices = st.text_input(f"Query Indices List (comma-separated)", key=f"query_indices_{i}_{k}") 51 | template_indices = st.text_input(f"Template Indices List (comma-separated)", key=f"template_indices_{i}_{k}") 52 | try: 53 | query_indices_list = [int(idx.strip()) for idx in query_indices.split(",") if idx.strip()] 54 | template_indices_list = [int(idx.strip()) for idx in template_indices.split(",") if idx.strip()] 55 | except ValueError: 56 | st.error("Indices lists should be integers separated by commas.") 57 | logger.error("Error parsing indices lists.") 58 | query_indices_list = [] 59 | template_indices_list = [] 60 | templates_list.append({ 61 | "mmcif": mmcif_content, 62 | "queryIndices": query_indices_list, 63 | "templateIndices": template_indices_list 64 | }) 65 | logger.debug(f"Added template: {templates_list[-1]}") 66 | 67 | protein_entry = { 68 | "sequence": sequence 69 | } 70 | if modifications_list: 71 | protein_entry["modifications"] = modifications_list 72 | if unpaired_msa is not None: 73 | protein_entry["unpairedMsa"] = unpaired_msa 74 | if paired_msa is not None: 75 | protein_entry["pairedMsa"] = paired_msa 76 | if templates_list or (unpaired_msa is not None) or (paired_msa is not None): 77 | if "unpairedMsa" not in protein_entry: 78 | protein_entry["unpairedMsa"] = "" 79 | if "pairedMsa" not in protein_entry: 80 | protein_entry["pairedMsa"] = "" 81 | if templates_list: 82 | protein_entry["templates"] = templates_list 83 | else: 84 | protein_entry["templates"] = [] 85 | elif msa_option == "Don't use MSA 🚫": 86 | protein_entry["unpairedMsa"] = "" 87 | protein_entry["pairedMsa"] = "" 88 | protein_entry["templates"] = [] 89 | return protein_entry 90 | 91 | def collect_rna_sequence_data(i): 92 | sequence = st.text_area(f"RNA Sequence (Entity {i+1})", key=f"sequence_{i}", help="Enter the RNA sequence.") 93 | logger.debug(f"RNA sequence input for Entity {i+1}.") 94 | 95 | # Modifications 96 | modifications_list = [] 97 | add_modifications = st.checkbox(f"Add Modifications", key=f"add_modifications_{i}") 98 | if add_modifications: 99 | num_modifications = st.number_input(f"Number of Modifications", min_value=1, step=1, key=f"num_modifications_{i}") 100 | for j in range(int(num_modifications)): 101 | st.markdown(f"**Modification {j+1}**") 102 | mod_col1, mod_col2 = st.columns(2) 103 | with mod_col1: 104 | mod_type = st.text_input(f"Modification Type (modificationType)", key=f"mod_type_{i}_{j}") 105 | with mod_col2: 106 | mod_position = st.number_input(f"Modification Position (basePosition)", min_value=1, step=1, key=f"mod_position_{i}_{j}") 107 | modifications_list.append({"modificationType": mod_type, "basePosition": mod_position}) 108 | logger.debug(f"Added modification: {modifications_list[-1]}") 109 | 110 | # MSA Options 111 | msa_option = st.selectbox(f"MSA Option", ["Auto-generate 🛠️", "Don't use MSA 🚫", "Upload MSA 📄"], key=f"msa_option_{i}") 112 | 113 | unpaired_msa = "" 114 | if msa_option == "Upload MSA 📄": 115 | unpaired_msa = st.text_area(f"Unpaired MSA", key=f"unpaired_msa_{i}") 116 | logger.debug(f"Entity {i+1} uploaded MSA.") 117 | elif msa_option == "Don't use MSA 🚫": 118 | unpaired_msa = "" 119 | logger.debug(f"Entity {i+1} chose not to use MSA.") 120 | elif msa_option == "Auto-generate 🛠️": 121 | unpaired_msa = None 122 | logger.debug(f"Entity {i+1} chose to auto-generate MSA.") 123 | 124 | rna_entry = { 125 | "sequence": sequence 126 | } 127 | if modifications_list: 128 | rna_entry["modifications"] = modifications_list 129 | if unpaired_msa is not None: 130 | rna_entry["unpairedMsa"] = unpaired_msa 131 | return rna_entry 132 | 133 | def collect_dna_sequence_data(i): 134 | sequence = st.text_area(f"DNA Sequence (Entity {i+1})", key=f"sequence_{i}", help="Enter the DNA sequence.") 135 | logger.debug(f"DNA sequence input for Entity {i+1}.") 136 | 137 | # Modifications 138 | modifications_list = [] 139 | add_modifications = st.checkbox(f"Add Modifications", key=f"add_modifications_{i}") 140 | if add_modifications: 141 | num_modifications = st.number_input(f"Number of Modifications", min_value=1, step=1, key=f"num_modifications_{i}") 142 | for j in range(int(num_modifications)): 143 | st.markdown(f"**Modification {j+1}**") 144 | mod_col1, mod_col2 = st.columns(2) 145 | with mod_col1: 146 | mod_type = st.text_input(f"Modification Type (modificationType)", key=f"mod_type_{i}_{j}") 147 | with mod_col2: 148 | mod_position = st.number_input(f"Modification Position (basePosition)", min_value=1, step=1, key=f"mod_position_{i}_{j}") 149 | modifications_list.append({"modificationType": mod_type, "basePosition": mod_position}) 150 | logger.debug(f"Added modification: {modifications_list[-1]}") 151 | 152 | dna_entry = { 153 | "sequence": sequence 154 | } 155 | if modifications_list: 156 | dna_entry["modifications"] = modifications_list 157 | 158 | return dna_entry 159 | 160 | def collect_ligand_sequence_data(i): 161 | ccd_codes = st.text_input(f"CCD Codes (comma-separated)", key=f"ccd_codes_{i}", help="Provide CCD Codes, separated by commas. Ions can be specified as ligands with ccdCodes (e.g., MG).") 162 | smiles = st.text_input(f"SMILES String", key=f"smiles_{i}", help="Provide SMILES string of the ligand.") 163 | if ccd_codes and smiles: 164 | st.error("Please provide only one of CCD Codes or SMILES String.") 165 | logger.error("Ligand provided both CCD Codes and SMILES String.") 166 | return {} 167 | elif ccd_codes: 168 | ccd_codes_list = re.split(r"\s*,\s*", ccd_codes) 169 | ligand_entry = { 170 | "ccdCodes": ccd_codes_list 171 | } 172 | logger.debug(f"Ligand CCD Codes: {ccd_codes_list}") 173 | return ligand_entry 174 | elif smiles: 175 | ligand_entry = { 176 | "smiles": smiles 177 | } 178 | logger.debug(f"Ligand SMILES: {smiles}") 179 | return ligand_entry 180 | else: 181 | st.error("Ligand requires either CCD Codes or SMILES String.") 182 | logger.error("Ligand missing CCD Codes or SMILES String.") 183 | return {} 184 | -------------------------------------------------------------------------------- /afusion/utils.py: -------------------------------------------------------------------------------- 1 | # utils.py 2 | 3 | import os 4 | import uuid 5 | import json 6 | import requests 7 | from loguru import logger 8 | import streamlit as st 9 | 10 | def log_to_ga(): 11 | # Replace with your Measurement ID 12 | measurement_id = "G-42P6TDX7LH" 13 | # Get API secret from environment variable 14 | api_secret = "Z-CSzz9hSsK3MSaxJjB8sQ" 15 | 16 | if not api_secret: 17 | logger.error("API secret for Google Analytics not found. Please set the GA_API_SECRET environment variable.") 18 | return 19 | 20 | url = f"https://www.google-analytics.com/mp/collect?measurement_id={measurement_id}&api_secret={api_secret}" 21 | 22 | # Generate or retrieve a unique client ID for each user session 23 | if 'client_id' not in st.session_state: 24 | st.session_state['client_id'] = str(uuid.uuid4()) 25 | 26 | client_id = st.session_state['client_id'] 27 | logger.debug(f"Client ID: {client_id}") 28 | 29 | payload = { 30 | "client_id": client_id, 31 | "events": [{ 32 | "name": "app_start", 33 | "params": {} 34 | }] 35 | } 36 | 37 | headers = { 38 | 'Content-Type': 'application/json' 39 | } 40 | 41 | try: 42 | response = requests.post(url, json=payload, headers=headers) 43 | if response.status_code != 204: 44 | logger.error(f"Failed to log to Google Analytics: {response.content}") 45 | else: 46 | logger.info("Successfully logged to Google Analytics") 47 | except Exception as e: 48 | logger.error(f"Exception occurred while logging to Google Analytics: {e}") 49 | 50 | def compress_output_folder(output_folder_path, job_output_folder_name): 51 | import os 52 | import zipfile 53 | import io 54 | from loguru import logger 55 | 56 | # Create a ZIP file in memory 57 | zip_buffer = io.BytesIO() 58 | with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zipf: 59 | for root, dirs, files in os.walk(output_folder_path): 60 | for file in files: 61 | file_path = os.path.join(root, file) 62 | arcname = os.path.relpath(file_path, start=output_folder_path) 63 | zipf.write(file_path, arcname) 64 | zip_buffer.seek(0) 65 | logger.debug(f"Compressed output folder: {output_folder_path}") 66 | return zip_buffer.getvalue() 67 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | # simplified app.py for streamlit cloud 2 | 3 | import streamlit as st 4 | import json 5 | import re 6 | import os 7 | import sys 8 | from loguru import logger 9 | 10 | # Import your modules (make sure they are correctly installed in your environment) 11 | from afusion.execution import run_alphafold 12 | from afusion.sequence_input import ( 13 | collect_protein_sequence_data, 14 | collect_rna_sequence_data, 15 | collect_dna_sequence_data, 16 | collect_ligand_sequence_data 17 | ) 18 | from afusion.bonds import handle_bond 19 | from afusion.utils import compress_output_folder 20 | 21 | # Configure the logger 22 | logger.add("afusion.log", rotation="1 MB", level="DEBUG") 23 | 24 | def main(): 25 | # Set page configuration and theme 26 | st.set_page_config( 27 | page_title="AFusion: AlphaFold 3 GUI", 28 | page_icon="🧬", 29 | layout="wide", 30 | initial_sidebar_state="expanded", 31 | ) 32 | 33 | # Custom CSS styling 34 | st.markdown(""" 35 | 67 | """, unsafe_allow_html=True) 68 | 69 | # Title and subtitle 70 | st.markdown("A convenient GUI for running AlphaFold 3 predictions
", unsafe_allow_html=True) 72 | st.markdown("If this project helps you, please ⭐️ my project!
", unsafe_allow_html=True) 73 | 74 | #### Sidebar Navigation #### 75 | with st.sidebar: 76 | st.header("Navigation") 77 | st.sidebar.markdown("---") 78 | sections = { 79 | "Job Settings": "job_settings", 80 | "Sequences": "sequences", 81 | "Bonded Atom Pairs": "bonded_atom_pairs", 82 | "User Provided CCD": "user_ccd", 83 | "Generated JSON": "json_content", 84 | "Execution Settings": "execution_settings", 85 | "Run AlphaFold 3": "run_alphafold", 86 | } 87 | for section_name, section_id in sections.items(): 88 | st.markdown(f"{section_name}", unsafe_allow_html=True) 89 | st.markdown("---") 90 | st.markdown("Created by Hanzi 2024.", unsafe_allow_html=True) 91 | 92 | # Main Content 93 | st.markdown('', unsafe_allow_html=True) 94 | st.markdown("### Welcome to AFusion!") 95 | st.markdown("Use this GUI to generate input JSON files and run AlphaFold 3 predictions with ease. Please [install AlphaFold 3](https://github.com/google-deepmind/alphafold3/blob/main/docs/installation.md) before using.") 96 | 97 | st.markdown('', unsafe_allow_html=True) 98 | st.header("📝 Job Settings") 99 | with st.expander("Configure Job Settings", expanded=True): 100 | job_name = st.text_input("Job Name", value="My AlphaFold Job", help="Enter a descriptive name for your job.") 101 | logger.info(f"Job name set to: {job_name}") 102 | model_seeds = st.text_input("Model Seeds (comma-separated)", value="1,2,3", help="Provide integer seeds separated by commas.") 103 | logger.debug(f"Model seeds input: {model_seeds}") 104 | model_seeds_list = [int(seed.strip()) for seed in model_seeds.split(",") if seed.strip().isdigit()] 105 | if not model_seeds_list: 106 | st.error("Please provide at least one valid model seed.") 107 | logger.error("No valid model seeds provided.") 108 | st.stop() 109 | logger.info(f"Model seeds list: {model_seeds_list}") 110 | 111 | st.markdown('', unsafe_allow_html=True) 112 | st.header("📄 Sequences") 113 | sequences = [] 114 | num_entities = st.number_input("Number of Entities", min_value=1, step=1, value=1, help="Select the number of entities you want to add.") 115 | logger.info(f"Number of entities set to: {num_entities}") 116 | 117 | for i in range(int(num_entities)): 118 | st.markdown(f"### Entity {i+1}") 119 | with st.expander(f"Entity {i+1} Details", expanded=True): 120 | entity_type = st.selectbox(f"Select Entity Type", ["Protein 🧬", "RNA 🧫", "DNA 🧬", "Ligand 💊"], key=f"entity_type_{i}") 121 | logger.info(f"Entity {i+1} type: {entity_type}") 122 | 123 | copy_number = st.number_input(f"Copy Number", min_value=1, step=1, value=1, key=f"copy_number_{i}", help="Specify the number of copies of this sequence.") 124 | logger.info(f"Entity {i+1} copy number: {copy_number}") 125 | 126 | # Collect sequence data 127 | if entity_type.startswith("Protein"): 128 | sequence_data = collect_protein_sequence_data(i) 129 | elif entity_type.startswith("RNA"): 130 | sequence_data = collect_rna_sequence_data(i) 131 | elif entity_type.startswith("DNA"): 132 | sequence_data = collect_dna_sequence_data(i) 133 | elif entity_type.startswith("Ligand"): 134 | sequence_data = collect_ligand_sequence_data(i) 135 | else: 136 | st.error(f"Unknown entity type: {entity_type}") 137 | logger.error(f"Unknown entity type: {entity_type}") 138 | continue # Skip to next entity 139 | 140 | # Handle IDs based on copy number 141 | entity_ids = [] 142 | if copy_number >= 1: 143 | # Allow user to input multiple IDs 144 | entity_id = st.text_input(f"Entity ID(s) (comma-separated)", key=f"entity_id_{i}", help="Provide entity ID(s), separated by commas if multiple.") 145 | if not entity_id.strip(): 146 | st.error("Entity ID is required.") 147 | logger.error("Entity ID missing.") 148 | continue 149 | entity_ids = re.split(r"\s*,\s*", entity_id) 150 | if len(entity_ids) != copy_number: 151 | st.error(f"Please provide {copy_number} ID(s) separated by commas.") 152 | logger.error(f"Number of IDs provided does not match copy number for Entity {i+1}.") 153 | continue 154 | logger.debug(f"Entity {i+1} IDs: {entity_ids}") 155 | 156 | for copy_id in entity_ids: 157 | # Clone the sequence data and set the ID 158 | sequence_entry = sequence_data.copy() 159 | sequence_entry['id'] = copy_id 160 | # Wrap the entry appropriately 161 | if entity_type.startswith("Protein"): 162 | sequences.append({"protein": sequence_entry}) 163 | elif entity_type.startswith("RNA"): 164 | sequences.append({"rna": sequence_entry}) 165 | elif entity_type.startswith("DNA"): 166 | sequences.append({"dna": sequence_entry}) 167 | elif entity_type.startswith("Ligand"): 168 | sequences.append({"ligand": sequence_entry}) 169 | else: 170 | st.error("Copy number must be at least 1.") 171 | logger.error("Invalid copy number.") 172 | continue 173 | 174 | st.markdown('', unsafe_allow_html=True) 175 | st.header("🔗 Bonded Atom Pairs (Optional)") 176 | bonded_atom_pairs = [] 177 | add_bonds = st.checkbox("Add Bonded Atom Pairs") 178 | if add_bonds: 179 | num_bonds = st.number_input("Number of Bonds", min_value=1, step=1, key="num_bonds") 180 | for b in range(int(num_bonds)): 181 | st.markdown(f"**Bond {b+1}**") 182 | bond = handle_bond(b) 183 | if bond: 184 | bonded_atom_pairs.append(bond) 185 | logger.debug(f"Added bond: {bond}") 186 | 187 | st.markdown('', unsafe_allow_html=True) 188 | st.header("🧩 User Provided CCD (Optional)") 189 | user_ccd = st.text_area("User CCD (mmCIF format)") 190 | if user_ccd: 191 | logger.debug("User provided CCD data.") 192 | 193 | # Generate JSON Data 194 | alphafold_input = { 195 | "name": job_name, 196 | "modelSeeds": model_seeds_list, 197 | "sequences": sequences, 198 | "dialect": "alphafold3", 199 | "version": 1 200 | } 201 | 202 | if bonded_atom_pairs: 203 | alphafold_input["bondedAtomPairs"] = bonded_atom_pairs 204 | 205 | if user_ccd: 206 | alphafold_input["userCCD"] = user_ccd 207 | 208 | # Convert JSON to string 209 | json_output = json.dumps(alphafold_input, indent=2) 210 | logger.debug(f"Generated JSON:\n{json_output}") 211 | 212 | st.markdown('', unsafe_allow_html=True) 213 | st.header("📄 Generated JSON Content") 214 | st.code(json_output, language="json") 215 | 216 | st.markdown('', unsafe_allow_html=True) 217 | st.header("⚙️ AlphaFold 3 Execution Settings") 218 | with st.expander("Configure Execution Settings", expanded=True): 219 | # Paths for execution 220 | af_input_path = st.text_input("AF Input Path", value=os.path.expanduser("~/af_input"), help="Path to AlphaFold input directory.") 221 | af_output_path = st.text_input("AF Output Path", value=os.path.expanduser("~/af_output"), help="Path to AlphaFold output directory.") 222 | model_parameters_dir = st.text_input("Model Parameters Directory", value="/path/to/models", help="Path to model parameters directory.") 223 | databases_dir = st.text_input("Databases Directory", value="/path/to/databases", help="Path to databases directory.") 224 | 225 | logger.debug(f"Execution settings: af_input_path={af_input_path}, af_output_path={af_output_path}, model_parameters_dir={model_parameters_dir}, databases_dir={databases_dir}") 226 | 227 | # Additional options 228 | run_data_pipeline = st.checkbox("Run Data Pipeline (CPU only, time-consuming)", value=True) 229 | run_inference = st.checkbox("Run Inference (requires GPU)", value=True) 230 | 231 | logger.info(f"Run data pipeline: {run_data_pipeline}, Run inference: {run_inference}") 232 | 233 | # Bucket Sizes Configuration 234 | use_custom_buckets = st.checkbox("Specify Custom Compilation Buckets", value=False) 235 | if use_custom_buckets: 236 | buckets_input = st.text_input( 237 | "Bucket Sizes (comma-separated)", 238 | value="256,512,768,1024,1280,1536,2048,2560,3072,3584,4096,4608,5120", 239 | help="Specify bucket sizes separated by commas. Example: 256,512,768,..." 240 | ) 241 | # Parse buckets 242 | bucket_sizes = [int(size.strip()) for size in buckets_input.split(",") if size.strip().isdigit()] 243 | if not bucket_sizes: 244 | st.error("Please provide at least one valid bucket size.") 245 | logger.error("No valid bucket sizes provided.") 246 | st.stop() 247 | logger.debug(f"Custom bucket sizes: {bucket_sizes}") 248 | else: 249 | bucket_sizes = [] # Empty list indicates default buckets 250 | 251 | st.markdown('', unsafe_allow_html=True) 252 | st.header("🚀 Run AlphaFold 3") 253 | # Save JSON to file 254 | json_save_path = os.path.join(af_input_path, "fold_input.json") 255 | try: 256 | os.makedirs(af_input_path, exist_ok=True) 257 | with open(json_save_path, "w") as json_file: 258 | json.dump(alphafold_input, json_file, indent=2) 259 | st.success(f"JSON file saved to {json_save_path}") 260 | logger.info(f"JSON file saved to {json_save_path}") 261 | except Exception as e: 262 | st.error(f"Error saving JSON file: {e}") 263 | logger.error(f"Error saving JSON file: {e}") 264 | 265 | # Run AlphaFold 3 266 | if st.button("Run AlphaFold 3 Now ▶️"): 267 | # Build the Docker command 268 | docker_command = ( 269 | f"docker run --rm " 270 | f"--volume {af_input_path}:/root/af_input " 271 | f"--volume {af_output_path}:/root/af_output " 272 | f"--volume {model_parameters_dir}:/root/models " 273 | f"--volume {databases_dir}:/root/public_databases " 274 | f"--gpus all " 275 | f"alphafold3 " 276 | f"python run_alphafold.py " 277 | f"--json_path=/root/af_input/fold_input.json " 278 | f"--model_dir=/root/models " 279 | f"--output_dir=/root/af_output " 280 | f"{'--run_data_pipeline' if run_data_pipeline else ''} " 281 | f"{'--run_inference' if run_inference else ''} " 282 | f"{'--buckets ' + ','.join(map(str, bucket_sizes)) if bucket_sizes else ''}" 283 | ) 284 | 285 | st.markdown("#### Docker Command:") 286 | st.code(docker_command, language="bash") 287 | logger.debug(f"Docker command: {docker_command}") 288 | 289 | # Run the command and display output in a box 290 | with st.spinner('AlphaFold 3 is running...'): 291 | output_placeholder = st.empty() 292 | output = run_alphafold(docker_command, placeholder=output_placeholder) 293 | 294 | # Display the output in an expander box 295 | st.markdown("#### Command Output:") 296 | with st.expander("Show Command Output 📄", expanded=False): 297 | st.text_area("Command Output", value=output, height=400) 298 | 299 | logger.info("AlphaFold 3 execution completed.") 300 | 301 | # Check if the output directory exists 302 | job_output_folder_name = job_name.lower().replace(' ', '_') 303 | output_folder_path = os.path.join(af_output_path, job_output_folder_name) 304 | 305 | if os.path.exists(output_folder_path): 306 | st.success("AlphaFold 3 execution completed successfully.") 307 | st.info(f"Results are saved in: {output_folder_path}") 308 | logger.info(f"Results saved in: {output_folder_path}") 309 | 310 | # Provide download option 311 | st.markdown("### Download Results 📥") 312 | zip_data = compress_output_folder(output_folder_path, job_output_folder_name) 313 | st.download_button( 314 | label="Download ZIP", 315 | data=zip_data, 316 | file_name=f"{job_output_folder_name}.zip", 317 | mime="application/zip" 318 | ) 319 | logger.info("User downloaded the results ZIP file.") 320 | 321 | # Provide instructions to run the Visualization App 322 | st.markdown("### Visualize Your Results") 323 | st.write("To visualize your results, run the following command:") 324 | st.code(f"afusion visualization --output_folder_path '{output_folder_path}'", language="bash") 325 | st.write("Or launch the Visualization App and enter the output folder path.") 326 | logger.info("Provided instructions to the user to run the Visualization App.") 327 | 328 | else: 329 | st.error("AlphaFold 3 execution did not complete successfully. Please check the logs.") 330 | logger.error("AlphaFold 3 execution did not complete successfully.") 331 | else: 332 | st.info("Click the 'Run AlphaFold 3 Now ▶️' button to execute the command.") 333 | 334 | st.markdown("---") 335 | 336 | # Provide access to the log file 337 | st.markdown("### Download Log File 📥") 338 | with open('afusion.log', 'r') as log_file: 339 | log_content = log_file.read() 340 | st.download_button( 341 | label="Download Log File", 342 | data=log_content, 343 | file_name='afusion.log', 344 | mime='text/plain' 345 | ) 346 | 347 | # Display log content in the app 348 | with st.expander("Show Log Content 📄", expanded=False): 349 | st.text_area("Log Content", value=log_content, height=200) 350 | 351 | st.markdown("---") 352 | # Add footer 353 | st.markdown("© 2024 Hanzi. All rights reserved.
", unsafe_allow_html=True) 354 | 355 | if __name__ == "__main__": 356 | main() 357 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | %SPHINXBUILD% >NUL 2>NUL 14 | if errorlevel 9009 ( 15 | echo. 16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 17 | echo.installed, then set the SPHINXBUILD environment variable to point 18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 19 | echo.may add the Sphinx directory to PATH. 20 | echo. 21 | echo.If you don't have Sphinx installed, grab it from 22 | echo.https://www.sphinx-doc.org/ 23 | exit /b 1 24 | ) 25 | 26 | if "%1" == "" goto help 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | streamlit 2 | pandas 3 | loguru 4 | numpy 5 | py3Dmol 6 | biopython 7 | plotly 8 | myst-parser 9 | furo 10 | -------------------------------------------------------------------------------- /docs/source/.conf.py.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hanziwww/AlphaFold3-GUI/b18760506a53e8799af2d1d285e36c37544768b6/docs/source/.conf.py.swp -------------------------------------------------------------------------------- /docs/source/api.md: -------------------------------------------------------------------------------- 1 | # API Documentation 2 | 3 | ```{eval-rst} 4 | .. automodule:: afusion.api 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | ``` 9 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # -- Project information ----------------------------------------------------- 2 | import os 3 | import sys 4 | sys.path.insert(0, os.path.abspath('../../')) 5 | 6 | 7 | project = 'AFusion' 8 | copyright = '2024, Hanzi' 9 | author = 'Hanzi' 10 | release = '1.2.2' 11 | 12 | # -- General configuration --------------------------------------------------- 13 | extensions = [ 14 | 'sphinx.ext.autodoc', 15 | 'myst_parser', 16 | ] 17 | # Enable Markdown support 18 | source_suffix = ['.rst', '.md'] 19 | autoclass_content = 'both' 20 | autodoc_member_order = 'bysource' 21 | 22 | templates_path = ['_templates'] 23 | exclude_patterns = [] 24 | 25 | 26 | 27 | # -- Options for HTML output ------------------------------------------------- 28 | # The theme to use for HTML and HTML Help pages. 29 | html_theme = 'furo' 30 | html_theme_options = { 31 | "sidebar_hide_name": False, # 确保页面名称显示在侧边栏 32 | } 33 | html_static_path = ['_static'] 34 | -------------------------------------------------------------------------------- /docs/source/index.md: -------------------------------------------------------------------------------- 1 | # 🔬 AFusion: AlphaFold 3 GUI & Toolkit 2 | 3 |  4 | 5 | ## Introduction 6 | **AFusion** is a user-friendly graphical interface designed to simplify AlphaFold 3 usage, making advanced protein structure modeling accessible to everyone. Whether you prefer a GUI over command-line interactions or need an API for batch predictions, AFusion has you covered. 7 | 8 | [**Demo Site**](https://af3gui.streamlit.app/) *(generates input JSON files ONLY)* 9 | 10 | [**Usable visualization site**](https://af3vis.streamlit.app/) *(fully usable)* 11 | 12 | ## Features 13 | 14 | - **🧭 Guided Installation**: GUI-based installer to simplify the installation process, easily set up the application through step-by-step guidance. 15 | - **✨ Intuitive Interface**: Easily configure job settings, sequences, and execution parameters through a clean and modern GUI. 16 | - **📋 Entity Management**: Add multiple entities (Protein, RNA, DNA, Ligand) with support for modifications, MSA options, and templates. 17 | - **⚙️ Dynamic JSON Generation**: Automatically generates the required JSON input file for AlphaFold 3 based on user inputs. 18 | - **🚀 Integrated Execution**: Run AlphaFold 3 directly from the GUI with customizable Docker execution settings. 19 | - **🖥️ Visual Feedback**: Provides command output within the interface for monitoring and debugging. 20 | - **🖥️ Console Output**: Track processes and debug more effectively with backend console output. 21 | - **🧩 API for Batch Predictions**: Perform batch predictions using the AFusion API in Python scripts. 22 | 23 | ### **🌟 New Feature!** 24 | - **AlphaFold 3 Output Analysis System**: Automatically analyze and visualize results with customizable visualizations and generate detailed PDF reports for streamlined insights. 25 | 26 | ## Acknowledgements 27 | 28 | - **AlphaFold 3**: This GUI is designed to work with [AlphaFold 3](https://github.com/google-deepmind/alphafold3) by DeepMind. 29 | - **Streamlit**: AFusion is built using [Streamlit](https://streamlit.io/), an open-source app framework for machine learning and data science teams. 30 | - **Contributors**: Waiting for more! 31 | 32 | ```{toctree} 33 | :caption: Contents 34 | :maxdepth: 1 35 | 36 | installation 37 | tutorial 38 | api 39 | release 40 | ``` 41 | --- 42 | 43 | If you encounter any issues or have suggestions for improvements, please open an [issue](https://github.com/Hanziwww/AlphaFold3-GUI/issues) or submit a [pull request](https://github.com/Hanziwww/AlphaFold3-GUI/pulls). 44 | 45 | Happy Folding! 🧬 46 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to Afusion's Documentation! 2 | =================================== 3 | 4 | .. toctree:: 5 | :maxdepth: 3 6 | :caption: Contents: 7 | 8 | installation 9 | tutorial 10 | api 11 | 12 | -------------------------------------------------------------------------------- /docs/source/installation.md: -------------------------------------------------------------------------------- 1 | # Installation Guide 2 | 3 | This section provides detailed instructions on how to install and set up AFusion and its prerequisites. 4 | 5 | ## Option 1: Install Using the Terminal 6 | 7 | Before installing AFusion, ensure that you have the following components installed on your system: 8 | 9 | ### 1. 🐳 Docker Installed 10 | 11 | - **Docker** is required to run AlphaFold 3. 12 | - **Installation**: Download and install Docker from the [official website](https://www.docker.com/get-started/). 13 | - **Post-Installation**: 14 | - Ensure Docker is running properly. 15 | - Verify that your user has permission to execute Docker commands. 16 | 17 | ### 2. 🧬 AlphaFold 3 Installed 18 | 19 | - AFusion requires **AlphaFold 3** to be installed and set up on your system. 20 | - **Installation Instructions**: 21 | - Follow the instructions provided in the [AlphaFold 3 GitHub Repository](https://github.com/google-deepmind/alphafold3) to install AlphaFold 3. 22 | - Make sure to download the model parameters and required databases. 23 | 24 | ### 3. 🐍 Python 3.10 or Higher 25 | 26 | - AFusion is built with Python and requires **Python 3.10** or higher. 27 | - **Installation**: 28 | - Download Python from the [official website](https://www.python.org/downloads/). 29 | - Alternatively, use a package manager like `apt`, `brew`, or `conda`. 30 | 31 | ## Option 2: Use the Guided GUI Installation 32 | 33 | Alternatively, you can use the guided GUI installation process provided by AFusion, which simplifies the installation steps through an interactive interface. 34 | 35 | - **Start the Installation GUI**: 36 | - Run the following command in your terminal: 37 | ```bash 38 | afusion install 39 | ``` 40 | - This command will launch the AFusion installation GUI, guiding you step-by-step through the process of installing Docker, AlphaFold 3, and Python if they are not already installed. 41 | 42 | By choosing Option 2, you can streamline the installation process with a user-friendly graphical interface that handles the setup for you. 43 | 44 | ## Installation and Running 45 | 46 | Follow these steps to install and launch AFusion: 47 | 48 | ### 1. Install AFusion 49 | 50 | Run the following command in your terminal to install AFusion: 51 | 52 | ```bash 53 | pip install afusion 54 | ``` 55 | 56 | - **Note**: This command will install AFusion and all its dependencies, including Streamlit. 57 | 58 | ### 2. Run AFusion GUI 59 | 60 | After installation, you can start AFusion by running: 61 | 62 | ```bash 63 | afusion run 64 | ``` 65 | 66 | - This command will launch the AFusion graphical user interface (GUI) in your default web browser. 67 | 68 | --- 69 | 70 | **Important Notes:** 71 | 72 | - **AlphaFold 3 Installation**: Ensure you have correctly installed AlphaFold 3, including model parameters and required databases, following the [AlphaFold 3 Installation Guide](https://github.com/google-deepmind/alphafold3/blob/main/docs/installation.md). 73 | - **Docker Configuration**: After installing Docker, make sure it is running properly and that your user has permission to execute Docker commands. 74 | - **Streamlit Dependency**: AFusion's installation will automatically install all required dependencies, including Streamlit. There's no need to install it separately. 75 | 76 | --- 77 | 78 | ## Troubleshooting 79 | 80 | If you encounter any issues during installation or usage, consider the following steps: 81 | 82 | - **Docker Issues**: 83 | - Ensure Docker is running. 84 | - On Linux, you might need to add your user to the `docker` group: 85 | 86 | ```bash 87 | sudo usermod -aG docker $USER 88 | ``` 89 | 90 | - Log out and log back in for the changes to take effect. 91 | 92 | - **Python Version**: 93 | - Verify your Python version: 94 | 95 | ```bash 96 | python --version 97 | ``` 98 | 99 | - If it's below 3.10, install the correct version. 100 | 101 | - **AlphaFold 3 Setup**: 102 | - Double-check that all paths and environment variables required by AlphaFold 3 are correctly set. 103 | 104 | - **Dependencies**: 105 | - If you have conflicting packages, consider using a virtual environment: 106 | 107 | ```bash 108 | python -m venv afusion_env 109 | source afusion_env/bin/activate 110 | ``` 111 | 112 | - Then install AFusion within this environment. 113 | 114 | --- 115 | 116 | For further assistance, please refer to the official documentation or [open an issue](https://github.com/your-repo/issues) on the GitHub repository. 117 | 118 | --- 119 | 120 | **Next Steps**: 121 | 122 | - Proceed to the [Usage Guide](index.md#usage) to learn how to use AFusion. 123 | - Explore the [API Documentation](api.md) for information on batch predictions (coming soon). 124 | 125 | --- 126 | 127 | **Happy Folding! 🧬** 128 | -------------------------------------------------------------------------------- /docs/source/release.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | ## v1.2.1 "Visualization Optimized" (Release Date: November 23, 2024) 4 | 5 | ### Improvements 6 | 7 | - **Visualization Performance Optimization**: Enhanced the visualization module to improve rendering speed and reduce memory usage, enabling smoother analysis of large AlphaFold 3 output files. 8 | 9 | - **Stability Improvements**: Addressed minor bugs and improved the stability of the visualization tools, ensuring a seamless user experience during structure analysis. 10 | 11 | 12 | ## v1.2.0 "Visualization & Analysis" (Release Date: November 21, 2024) 13 | 14 | ### New Features 15 | 16 | - **Visualization Module**: Introduced a powerful visualization module for AlphaFold 3 results. Users can upload output files (e.g., `.pdb`, `.json`) to analyze predictions with detailed structure displays, customizable plots, and PDF report generation. 17 | 18 | - **Integrated Visualization**: The visualization tools are now seamlessly integrated into the prediction GUI, allowing users to switch to the visualization tab immediately after predictions are complete. 19 | 20 | - **Enhanced Output Analysis**: Added an automated AlphaFold 3 output analysis system that provides streamlined insights with customizable visualizations and detailed reports. 21 | 22 | - **Batch Prediction API Improvements**: Updated the batch prediction API to support visualization integration and enhanced error handling. 23 | 24 | ## v1.1.2 "Guided Installation" (Release Date: November 21, 2024) 25 | 26 | ### New Features 27 | 28 | - **Guided Installation**: Introduced a new GUI-based installer to simplify the installation process. Users can now easily set up the application through step-by-step guidance. 29 | 30 | - **CLI Launch**: Added command-line interface support, allowing users to start the application or installation process directly from the command line using the `afusion` command. 31 | 32 | --- 33 | 34 | Let me know if there's anything else I can help you with! 35 | ## v1.1.1 "Debug and Docs" (Release Date: November 20, 2024) 36 | 37 | ### New Features 38 | 39 | - **Documentation Update**: Created and improved project documentation, providing more detailed usage guidance and API descriptions. 40 | 41 | ### Bug Fixes 42 | 43 | - Resolved known issues, enhancing application stability and reliability. 44 | 45 | --- 46 | 47 | ## v1.1.0 "Console and API" (Release Date: November 19, 2024) 48 | 49 | ### New Features 50 | 51 | - **Console Output**: Integrated console output functionality, allowing users to view the running process in real-time within the interface for easier tracking and debugging. 52 | - **Batch Predictions API**: Added an API for AFusion, supporting batch predictions in Python scripts, increasing automation. 53 | 54 | ### Improvements 55 | 56 | - **Performance Optimization**: Improved application performance and stability, enhancing user experience. 57 | - **Interface Enhancements**: Made minor adjustments to the user interface for smoother and more user-friendly operation. 58 | 59 | --- 60 | 61 | ## v1.0.0 "Refactor" (Release Date: November 18, 2024) 62 | 63 | ### Overview 64 | 65 | AFusion v1.0.0 has been officially released. This marks our first stable version, featuring a complete codebase refactor for improved performance and reliability. 66 | 67 | ### Installation 68 | 69 | ```bash 70 | pip install afusion 71 | ``` 72 | 73 | ### Run 74 | 75 | ```bash 76 | afusion 77 | ``` 78 | 79 | ### Features 80 | 81 | - **Code Refactoring**: Comprehensive optimization of the codebase, improving maintainability and execution efficiency. 82 | - **Stability Enhancements**: Fixed issues from previous versions, significantly enhancing application stability. 83 | 84 | --- 85 | 86 | ## v0.2.2 "Python Package" (Release Date: November 17, 2024) 87 | 88 | ### New Features 89 | 90 | - **Released as a Python Package**: AFusion is now available as a Python package. Users can install and run it with a simple command, making it more convenient. 91 | 92 | ### Installation 93 | 94 | ```bash 95 | pip install afusion 96 | ``` 97 | 98 | ### Run 99 | 100 | ```bash 101 | afusion 102 | ``` 103 | 104 | --- 105 | 106 | ## v0.2.1 "Copies" (Release Date: November 16, 2024) 107 | 108 | ### New Features 109 | 110 | - **Copy Number Specification**: Users can now specify the number of copies for each sequence/entity, making it easy to create multiple copies of a sequence. Each copy can be assigned a unique ID, providing greater flexibility when setting up simulations. 111 | - **Enhanced ID Handling**: Maintained the original functionality where multiple IDs can be specified separated by commas (e.g., `A,B`), while adding the option to explicitly specify the number of copies, offering more customization possibilities. 112 | 113 | ### Improvements 114 | 115 | - **User Interface Improvements**: Optimized the interface design to make the application more intuitive and user-friendly. 116 | - **Performance Enhancements**: Fixed minor issues to enhance stability and performance. 117 | 118 | --- 119 | 120 | ## v0.2.0 "New Features" (Release Date: November 15, 2024) 121 | 122 | ### New Features 123 | 124 | 1. **Run Completion Detection** 125 | 126 | - **Automatic Success Check**: After running AlphaFold 3, the application now automatically checks whether the prediction completed successfully. 127 | - **Output Folder Verification**: Verifies the existence of the output directory named after your job (based on the name field in your input) to ensure results are generated. 128 | - **User Feedback**: Upon successful completion, a confirmation message is displayed along with the path to the results. 129 | 130 | 2. **Download Results as ZIP** 131 | 132 | - **In-App Download Option**: Users can now download the prediction results directly from the app without needing to access the server filesystem. 133 | - **Automatic Compression**: Compresses the output folder into a ZIP file for quick and efficient downloads. 134 | - **Seamless Integration**: The download button appears immediately after a successful run, streamlining the workflow. 135 | 136 | ### Important Notes 137 | 138 | - **Ensure Correct Paths**: Before running, double-check that all directory paths in the execution settings are accurate and accessible by the application. 139 | - **Docker Requirements**: The application runs AlphaFold 3 within a Docker container. Ensure that Docker and AlphaFold 3 are installed and properly configured on your system. 140 | - **Permissions**: The application needs appropriate permissions to read and write to the specified directories. 141 | 142 | --- 143 | 144 | ## v0.1.1 "Flag Bucket" (Release Date: November 14, 2024) 145 | 146 | ### New Features 147 | 148 | - **Compilation Buckets Configuration** 149 | 150 | - **Custom Bucket Sizes**: AFusion now supports specifying custom compilation bucket sizes introduced in AlphaFold 3. Users can define bucket sizes that match the input sequence lengths, reducing unnecessary model recompilations and improving performance. 151 | - **Usage**: 152 | 1. **Enable Custom Buckets**: In the "AlphaFold 3 Execution Settings" section, check the "Specify Custom Compilation Buckets" option. 153 | 2. **Input Bucket Sizes**: Provide a list of bucket sizes separated by commas in the "Bucket Sizes (comma-separated)" field, e.g., `256,512,768,1024`. 154 | 3. **Run**: Review the generated Docker command to confirm it includes the `--buckets` flag, then click "Run AlphaFold 3 Now" to execute the prediction. 155 | - **Benefits**: 156 | - **Performance Optimization**: Matching bucket sizes to input sequences minimizes padding and reduces the number of model recompilations. 157 | - **Flexibility**: Customize bucket sizes to handle a diverse range of input lengths, ensuring efficient processing. 158 | 159 | ### Improvements 160 | 161 | - **User Interface Updates**: Adjusted the execution settings section to include the new compilation buckets configuration in an intuitive manner. Provided helpful tooltips and validation messages to guide users through the new settings. 162 | 163 | --- 164 | 165 | ## v0.1.0 "First Release" (Release Date: November 13, 2024) 166 | 167 | ### Overview 168 | 169 | AFusion v0.1.0 has been released, providing a user-friendly graphical interface for AlphaFold 3. It simplifies the prediction process, making it accessible to users who are not familiar with command-line interactions. 170 | 171 | ### Features 172 | 173 | - **Intuitive Interface**: Easily configure job settings, sequences, and execution parameters through a clean and modern GUI. 174 | - **Entity Management**: Add multiple entities (Protein, RNA, DNA, Ligand) with support for modifications, MSA options, and templates. 175 | - **Dynamic JSON Generation**: Automatically generates the required JSON input file for AlphaFold 3 based on user inputs. 176 | - **Integrated Execution**: Run AlphaFold 3 directly from the GUI with customizable Docker execution settings. 177 | 178 | --- 179 | -------------------------------------------------------------------------------- /docs/source/tutorial.md: -------------------------------------------------------------------------------- 1 | # AlphaFold3 Batch Predictions with `afusion.api` 2 | 3 | ## Introduction 4 | 5 | This tutorial demonstrates how to use the `afusion.api` module to create batch tasks from a pandas DataFrame and run batch predictions using AlphaFold. We'll guide you through the entire process—from preparing your data to interpreting the results—using a minimal example with protein sequences. 6 | 7 | **Prerequisites**: 8 | 9 | - Python 3.10 or higher 10 | - AlphaFold 3 installed and configured 11 | - The `afusion` package installed 12 | - Basic knowledge of Python and pandas 13 | 14 | --- 15 | 16 | ## 1. Import Necessary Modules 17 | 18 | Begin by importing the required modules: 19 | 20 | ```python 21 | import pandas as pd 22 | from afusion.api import create_tasks_from_dataframe, run_batch_predictions 23 | ``` 24 | 25 | - **`pandas`**: Used for data manipulation and analysis. 26 | - **`afusion.api`**: Contains the functions we'll use to create tasks and run predictions. 27 | 28 | --- 29 | 30 | ## 2. Prepare the Data 31 | 32 | We'll create a pandas DataFrame containing the necessary information for our batch predictions. In this example, we'll predict the structure of a minimal protein sequence for two jobs. 33 | 34 | ```python 35 | # Define the DataFrame for the test 36 | data = { 37 | 'job_name': ['TestJob1', 'TestJob1', 'TestJob2'], 38 | 'type': ['protein', 'protein', 'protein'], 39 | 'id': ['A', 'B', 'A'], # Entity IDs 40 | 'sequence': ['MVLSPADKTNVKAAW', 'MVLSPADKTNVKAAW', 'MVLSPADKTNVKAAW'], # Protein sequences 41 | # No modifications or optional parameters in this example 42 | } 43 | 44 | df = pd.DataFrame(data) 45 | ``` 46 | 47 | Let's display the DataFrame to verify its contents: 48 | 49 | ```python 50 | df 51 | ``` 52 | 53 | **Output**: 54 | 55 | | | job_name | type | id | sequence | 56 | |----|----------|---------|------|-----------------| 57 | | 0 | TestJob1 | protein | A | MVLSPADKTNVKAAW | 58 | | 1 | TestJob1 | protein | B | MVLSPADKTNVKAAW | 59 | | 2 | TestJob2 | protein | A | MVLSPADKTNVKAAW | 60 | 61 | **Explanation**: 62 | 63 | - **`job_name`**: Specifies the name of the job. `TestJob1` has two entities, while `TestJob2` has one. 64 | - **`type`**: Indicates the entity type; all are proteins in this case. 65 | - **`id`**: Identifier for each entity. 66 | - **`sequence`**: The protein sequences to be predicted. 67 | 68 | --- 69 | 70 | ## 3. Create Tasks from the DataFrame 71 | 72 | We will use the `create_tasks_from_dataframe` function to convert our DataFrame into a list of task dictionaries suitable for AlphaFold predictions. 73 | 74 | ```python 75 | # Create tasks from DataFrame 76 | tasks = create_tasks_from_dataframe(df) 77 | ``` 78 | 79 | This function processes the DataFrame and creates tasks based on the parameters provided. 80 | 81 | Let's inspect the tasks generated: 82 | 83 | ```python 84 | tasks 85 | ``` 86 | 87 | **Output**: 88 | 89 | ```python 90 | [ 91 | { 92 | 'name': 'TestJob1', 93 | 'modelSeeds': [1], 94 | 'sequences': [ 95 | { 96 | 'protein': { 97 | 'sequence': 'MVLSPADKTNVKAAW', 98 | 'unpairedMsa': None, 99 | 'pairedMsa': None, 100 | 'templates': [], 101 | 'id': 'A' 102 | } 103 | }, 104 | { 105 | 'protein': { 106 | 'sequence': 'MVLSPADKTNVKAAW', 107 | 'unpairedMsa': None, 108 | 'pairedMsa': None, 109 | 'templates': [], 110 | 'id': 'B' 111 | } 112 | } 113 | ], 114 | 'dialect': 'alphafold3', 115 | 'version': 1 116 | }, 117 | { 118 | 'name': 'TestJob2', 119 | 'modelSeeds': [1], 120 | 'sequences': [ 121 | { 122 | 'protein': { 123 | 'sequence': 'MVLSPADKTNVKAAW', 124 | 'unpairedMsa': None, 125 | 'pairedMsa': None, 126 | 'templates': [], 127 | 'id': 'A' 128 | } 129 | } 130 | ], 131 | 'dialect': 'alphafold3', 132 | 'version': 1 133 | } 134 | ] 135 | ``` 136 | 137 | **Explanation**: 138 | 139 | - **`name`**: Corresponds to `job_name` in the DataFrame. 140 | - **`modelSeeds`**: List of model seeds; defaults to `[1]` if not specified. 141 | - **`sequences`**: Contains the sequences and related data for each entity. 142 | - **`protein`**: Dictionary with the protein sequence and optional parameters. 143 | - **`sequence`**: The protein sequence. 144 | - **`unpairedMsa`, `pairedMsa`, `templates`**: Set to `None` or empty lists as we didn't specify them. 145 | - **`id`**: Entity ID. 146 | - **`dialect`**: Specifies the AlphaFold version; set to `'alphafold3'`. 147 | - **`version`**: Version number; set to `1`. 148 | 149 | --- 150 | 151 | ## 4. Configure Paths 152 | 153 | Before running predictions, specify the input and output directories, as well as the locations of the model parameters and databases. 154 | 155 | ```python 156 | # Path configurations (update these paths as needed) 157 | af_input_base_path = "/path/to/af_input" 158 | af_output_base_path = "/path/to/af_output" 159 | model_parameters_dir = "/path/to/model_parameters" # Update with the correct path 160 | databases_dir = "/path/to/databases" # Update with the correct path 161 | ``` 162 | 163 | **Note**: Replace `"/path/to/..."` with the actual paths on your system. 164 | 165 | Ensure that the directories exist: 166 | 167 | ```python 168 | import os 169 | 170 | os.makedirs(af_input_base_path, exist_ok=True) 171 | os.makedirs(af_output_base_path, exist_ok=True) 172 | ``` 173 | 174 | --- 175 | 176 | ## 5. Run Batch Predictions 177 | 178 | Now, run the batch predictions using the `run_batch_predictions` function. 179 | 180 | ```python 181 | # Run batch predictions 182 | results = run_batch_predictions( 183 | tasks=tasks, 184 | af_input_base_path=af_input_base_path, 185 | af_output_base_path=af_output_base_path, 186 | model_parameters_dir=model_parameters_dir, 187 | databases_dir=databases_dir, 188 | run_data_pipeline=False, # Set to True to run the data pipeline 189 | run_inference=False, # Set to True to run inference (requires GPU) 190 | ) 191 | ``` 192 | 193 | **Parameters**: 194 | 195 | - **`tasks`**: The list of tasks generated from the DataFrame. 196 | - **`af_input_base_path`**: Base directory for AlphaFold input files. 197 | - **`af_output_base_path`**: Base directory for AlphaFold output files. 198 | - **`model_parameters_dir`**: Directory containing the model parameters. 199 | - **`databases_dir`**: Directory containing the required databases. 200 | - **`run_data_pipeline`**: Whether to run the data pipeline (`True` or `False`). 201 | - **`run_inference`**: Whether to run inference (`True` if you have a GPU). 202 | 203 | **Important**: For this minimal test, we set `run_data_pipeline` and `run_inference` to `False`. In a real prediction scenario, you should set these to `True`. 204 | 205 | --- 206 | 207 | ## 6. Interpret the Results 208 | 209 | After running the predictions, process and print the results: 210 | 211 | ```python 212 | # Process and print results 213 | for result in results: 214 | print(f"Job Name: {result['job_name']}") 215 | print(f"Output Folder: {result['output_folder']}") 216 | print(f"Status: {result['status']}") 217 | print("---") 218 | ``` 219 | 220 | **Sample Output**: 221 | 222 | ``` 223 | Job Name: TestJob1 224 | Output Folder: /path/to/af_output 225 | Status: Success 226 | --- 227 | Job Name: TestJob2 228 | Output Folder: /path/to/af_output 229 | Status: Success 230 | --- 231 | ``` 232 | 233 | **Explanation**: 234 | 235 | - **`job_name`**: The name of the job. 236 | - **`output_folder`**: The directory where the output files are stored. 237 | - **`status`**: The status of the prediction (`'Success'` or an error message). 238 | 239 | --- 240 | 241 | ## 7. Notes and Considerations 242 | 243 | - **System Configuration**: This example was run on a system with the following configuration: 244 | - CPU: Xeon Silver 4410T 245 | - GPU: NVIDIA RTX 4090 246 | - Operating System: Ubuntu Server 24.04 LTS 247 | 248 | **Note**: Your hardware configuration can significantly affect the performance and runtime of AlphaFold predictions. Ensure that your system meets the necessary requirements, especially regarding GPU capabilities. 249 | 250 | - **GPU Requirement**: AlphaFold predictions require substantial computational resources and are optimized for GPUs. Ensure that your system meets the hardware requirements if you plan to run actual predictions. 251 | 252 | - **Database Availability**: The databases specified in `databases_dir` are essential for AlphaFold's operation. Make sure that you have downloaded and correctly configured all necessary databases. 253 | 254 | - **Model Parameters**: The `model_parameters_dir` should contain the AlphaFold model parameters. Ensure that you have obtained these parameters and placed them in the specified directory. 255 | 256 | - **Adjusting Parameters**: Depending on your use case, you may need to adjust additional parameters such as `model_seeds`, `msa_option`, and others. Refer to the `afusion.api` documentation for more details. 257 | 258 | - **Error Handling**: The `run_batch_predictions` function returns a list of results with status messages. If any job fails, the status will contain the error message, which can be used for debugging. 259 | 260 | --- 261 | 262 | ## Conclusion 263 | 264 | In this tutorial, we demonstrated how to use the `afusion.api` module to create batch tasks from a pandas DataFrame and run batch predictions using AlphaFold. By following these steps, you can streamline the process of setting up and executing multiple predictions, making it efficient to handle large-scale protein structure predictions. 265 | 266 | --- 267 | 268 | ## Additional Resources 269 | 270 | - **AlphaFold GitHub Repository**: [https://github.com/deepmind/alphafold](https://github.com/deepmind/alphafold) 271 | 272 | --- 273 | 274 | **Disclaimer**: Ensure that you comply with all licensing and usage terms when using AlphaFold and associated data. 275 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | streamlit 2 | pandas 3 | loguru 4 | numpy 5 | py3Dmol 6 | biopython 7 | plotly 8 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name='afusion', 5 | version='1.2.2.2', 6 | author='Han Wang', 7 | author_email='marspenman@gmail.com', 8 | description='AFusion: AlphaFold 3 GUI & Toolkit with Visualization', 9 | long_description=open('README.md', encoding='utf-8').read(), 10 | long_description_content_type='text/markdown', 11 | url='https://github.com/Hanziwww/AlphaFold3-GUI', 12 | packages=find_packages(include=['afusion', 'afusion.*']), 13 | include_package_data=True, 14 | install_requires=[ 15 | 'streamlit', 16 | 'pandas', 17 | 'loguru', 18 | 'numpy', 19 | 'py3Dmol', 20 | 'biopython', 21 | 'plotly', 22 | ], 23 | entry_points={ 24 | 'console_scripts': [ 25 | 'afusion = afusion.cli:main', 26 | ], 27 | }, 28 | classifiers=[ 29 | 'Programming Language :: Python :: 3', 30 | 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', 31 | 'Operating System :: POSIX :: Linux', 32 | ], 33 | python_requires='>=3.10', 34 | ) 35 | --------------------------------------------------------------------------------