ferritin_plms/ligandmpnn/
configs.rs1use super::model::ProteinMPNN;
17use super::proteinfeatures::ProteinFeatures;
18use crate::StructureFeatures;
19use anyhow::Error;
20use candle_core::pickle::PthTensors;
21use candle_core::{DType, Device, Tensor};
22use candle_nn::VarBuilder;
23use clap::ValueEnum;
24use ferritin_core::load_structure;
25use ferritin_test_data::TestFile;
26
27#[allow(dead_code)]
30pub struct MPNNExecConfig {
31 pub(crate) protein_inputs: String, pub(crate) run_config: RunConfig,
33 pub(crate) aabias_config: Option<AABiasConfig>,
34 pub(crate) ligand_mpnn_config: Option<LigandMPNNConfig>,
35 pub(crate) membrane_mpnn_config: Option<MembraneMPNNConfig>,
36 pub(crate) multi_pdb_config: Option<MultiPDBConfig>,
37 pub(crate) residue_control_config: Option<ResidueControl>,
38 pub(crate) device: Device,
39}
40
41impl MPNNExecConfig {
42 pub fn new(
43 device: Device,
44 pdb_path: String,
45 run_config: RunConfig,
46 residue_config: Option<ResidueControl>,
47 aa_bias: Option<AABiasConfig>,
48 lig_mpnn_specific: Option<LigandMPNNConfig>,
49 membrane_mpnn_specific: Option<MembraneMPNNConfig>,
50 multi_pdb_specific: Option<MultiPDBConfig>,
51 ) -> Result<Self, Error> {
52 Ok(MPNNExecConfig {
53 protein_inputs: pdb_path,
54 run_config,
55 aabias_config: aa_bias,
56 ligand_mpnn_config: lig_mpnn_specific,
57 membrane_mpnn_config: membrane_mpnn_specific,
58 residue_control_config: residue_config,
59 multi_pdb_config: multi_pdb_specific,
60 device,
61 })
62 }
63 pub fn load_model(&self, model_type: ModelTypes) -> Result<ProteinMPNN, Error> {
65 let default_dtype = DType::F32;
66 match model_type {
67 ModelTypes::ProteinMPNN => {
68 let (mpnn_file, _handle) = TestFile::ligmpnn_pmpnn_01().create_temp()?;
71 let pth = PthTensors::new(mpnn_file, Some("model_state_dict"))?;
72 let vb =
73 VarBuilder::from_backend(Box::new(pth), default_dtype, self.device.clone());
74 let pconf = ProteinMPNNConfig::proteinmpnn();
75 Ok(ProteinMPNN::load(vb, &pconf).expect("Unable to load the PMPNN Model"))
76 }
77 _ => panic!("not implented!"),
78 }
79 }
80 pub fn generate_protein_features(&self) -> Result<ProteinFeatures, Error> {
81 let device = self.device.clone();
82 let base_dtype = DType::F32;
83
84 let ac = load_structure(self.protein_inputs.clone())?;
86
87 let s = ac
88 .encode_amino_acids(&device)
89 .expect("A complete convertion to locations");
90 let x_37 = ac.to_numeric_atom37(&device)?;
91 let x_37_mask = Tensor::ones((x_37.dim(0)?, x_37.dim(1)?), base_dtype, &device)?;
92 let (y, y_t, y_m) = ac.to_numeric_ligand_atoms(&device)?;
93 let res_idx = ac.get_res_index();
94 let res_idx_len = res_idx.len();
95 let res_idx_tensor = Tensor::from_vec(res_idx, (1, res_idx_len), &device)?;
96
97 let chain_letters: Vec<String> = ac
99 .iter_residues_aminoacid()
100 .map(|res| res.chain_id().to_string())
101 .collect();
102
103 let chain_list: Vec<String> = chain_letters
105 .clone()
106 .into_iter()
107 .collect::<std::collections::HashSet<_>>()
108 .into_iter()
109 .collect();
110
111 Ok(ProteinFeatures {
157 s, x: x_37, x_mask: Some(x_37_mask), y, y_t, y_m: Some(y_m), r_idx: res_idx_tensor, chain_labels: None, chain_letters, mask_c: None, chain_list,
168 })
169 }
170}
171
172#[derive(Debug, Clone, ValueEnum, Copy)]
173pub enum ModelTypes {
174 #[value(name = "protein_mpnn")]
175 ProteinMPNN,
176 #[value(name = "ligand_mpnn")]
177 LigandMPNN,
178}
179
180#[derive(Debug)]
181pub struct AABiasConfig {
183 pub bias_aa: Option<String>,
184 pub bias_aa_per_residue: Option<String>,
185 pub omit_aa: Option<String>,
186 pub omit_aa_per_residue: Option<String>,
187}
188
189pub struct LigandMPNNConfig {
191 pub checkpoint_ligand_mpnn: Option<String>,
192 pub ligand_mpnn_use_atom_context: Option<i32>,
193 pub ligand_mpnn_use_side_chain_context: Option<i32>,
194 pub ligand_mpnn_cutoff_for_score: Option<String>,
195}
196
197pub struct MembraneMPNNConfig {
199 pub global_transmembrane_label: Option<i32>,
200 pub transmembrane_buried: Option<String>,
201 pub transmembrane_interface: Option<String>,
202}
203
204pub struct MultiPDBConfig {
206 pub pdb_path_multi: Option<String>,
207 pub fixed_residues_multi: Option<String>,
208 pub redesigned_residues_multi: Option<String>,
209 pub omit_aa_per_residue_multi: Option<String>,
210 pub bias_aa_per_residue_multi: Option<String>,
211}
212#[derive(Clone, Debug)]
213pub struct ProteinMPNNConfig {
214 pub atom_context_num: usize,
215 pub augment_eps: f32,
216 pub dropout_ratio: f32,
217 pub edge_features: i64,
218 pub hidden_dim: i64,
219 pub k_neighbors: i64,
220 pub ligand_mpnn_use_side_chain_context: bool,
221 pub model_type: ModelTypes,
222 pub node_features: i64,
223 pub num_decoder_layers: i64,
224 pub num_encoder_layers: i64,
225 pub num_letters: i64,
226 pub num_rbf: i64,
227 pub scale_factor: f64,
228 pub vocab: i64,
229}
230
231impl ProteinMPNNConfig {
232 pub fn proteinmpnn() -> Self {
233 Self {
234 atom_context_num: 0,
235 augment_eps: 0.0,
236 dropout_ratio: 0.1,
237 edge_features: 128,
238 hidden_dim: 128,
239 k_neighbors: 24,
240 ligand_mpnn_use_side_chain_context: false,
241 model_type: ModelTypes::ProteinMPNN,
242 node_features: 128,
243 num_decoder_layers: 3,
244 num_encoder_layers: 3,
245 num_letters: 21,
246 num_rbf: 16,
247 scale_factor: 1.0,
248 vocab: 21,
249 }
250 }
251}
252
253#[derive(Debug)]
254pub struct ResidueControl {
255 pub fixed_residues: Option<String>,
256 pub redesigned_residues: Option<String>,
257 pub symmetry_residues: Option<String>,
258 pub symmetry_weights: Option<String>,
259 pub chains_to_design: Option<String>,
260 pub parse_these_chains_only: Option<String>,
261}
262
263#[derive(Debug)]
264pub struct RunConfig {
265 pub model_type: Option<ModelTypes>,
266 pub seed: Option<i32>,
267 pub temperature: Option<f32>,
268 pub verbose: Option<i32>,
269 pub save_stats: Option<bool>,
270 pub batch_size: Option<i32>,
271 pub number_of_batches: Option<i32>,
272 pub file_ending: Option<String>,
273 pub zero_indexed: Option<i32>,
274 pub homo_oligomer: Option<i32>,
275 pub fasta_seq_separation: Option<String>,
276}