lig_and_protein/
lig_and_protein.rs1use std::{path::Path, time::Instant};
5
6use bio_files::{MmCif, Sdf, create_bonds, md_params::ForceFieldParams};
7use dynamics::{
8 BarostatCfg, ComputationDevice, FfMolType, HydrogenConstraint, Integrator, MdConfig, MdState,
9 MolDynamics, ParamError, SimBoxInit,
10 params::{FfParamSet, prepare_peptide_mmcif},
11 snapshot::{Snapshot, SnapshotHandlers},
12};
13use lin_alg::f64::Vec3;
14
15const STATIC_ATOM_DIST_THRESH: f64 = 8.;
18
19pub fn build_dynamics(
22 dev: &ComputationDevice,
23 ligs: Vec<&mut Sdf>,
24 peptide: &MmCif,
25 param_set: &FfParamSet,
26 cfg: &MdConfig,
27 n_steps: u32,
28 dt: f32,
29) -> Result<MdState, ParamError> {
30 println!("Setting up dynamics...");
31
32 let mut mols = Vec::new();
33
34 for lig in &ligs {
35 mols.push(MolDynamics {
36 ff_mol_type: FfMolType::SmallOrganic,
37 atoms: lig.atoms.clone(),
38 atom_posits: None,
39 atom_init_velocities: None,
40 bonds: lig.bonds.clone(),
41 adjacency_list: None,
43 static_: false,
44 mol_specific_params: None,
45 bonded_only: false,
46 });
48 }
49
50 let atoms: Vec<_> = peptide
53 .atoms
54 .iter()
55 .filter(|a| {
56 let mut closest_dist = f64::MAX;
57 for lig in &ligs {
58 for a in &lig.atoms {
60 let posit = a.posit;
61 let dist = (posit - a.posit).magnitude();
62 if dist < closest_dist {
63 closest_dist = dist;
64 }
65 }
66 }
67
68 !a.hetero && closest_dist < STATIC_ATOM_DIST_THRESH
69 })
70 .map(|a| a.clone())
71 .collect();
72
73 let bonds = create_bonds(&atoms);
74
75 mols.push(MolDynamics {
76 ff_mol_type: FfMolType::Peptide,
77 atoms,
78 bonds,
79 static_: true,
80 ..Default::default()
81 });
82
83 println!("Initializing MD state...");
86 let (mut md_state, _) = MdState::new(dev, cfg, &mols, param_set)?;
87 println!("Done.");
88
89 let start = Instant::now();
90
91 for _ in 0..n_steps {
92 md_state.step(dev, dt, None);
93 }
94
95 let elapsed = start.elapsed();
96 println!("MD complete in {:.2} s", elapsed.as_secs());
97
98 change_snapshot(ligs, &md_state.snapshots[0]);
99
100 Ok(md_state)
101}
102
103pub fn change_snapshot(ligs: Vec<&mut Sdf>, snapshot: &Snapshot) {
106 let mut start_i_this_mol = 0;
112
113 for lig in ligs {
114 let mut atom_posits = vec![Vec3::new_zero(); lig.atoms.len()];
116
117 for (i_snap, posit) in snapshot.atom_posits.iter().enumerate() {
118 if i_snap < start_i_this_mol || i_snap >= atom_posits.len() + start_i_this_mol {
119 continue;
120 }
121 atom_posits[i_snap - start_i_this_mol] = (*posit).into();
122 }
123
124 start_i_this_mol += atom_posits.len();
125 }
126}
127
128fn main() {
129 let dev = ComputationDevice::Cpu;
130 let param_set = FfParamSet::new_amber().unwrap();
131
132 let mut protein = MmCif::load(Path::new("1c8k.cif")).unwrap();
133 let mut mol = Sdf::load(Path::new("123.sdf")).unwrap();
135 let _mol_specific = ForceFieldParams::load_frcmod(Path::new("CPB.frcmod")).unwrap();
137
138 let (_bonds, _dihedrals) = prepare_peptide_mmcif(
145 &mut protein,
146 ¶m_set.peptide_ff_q_map.as_ref().unwrap(),
147 7.0,
148 )
149 .unwrap();
150
151 let cfg = MdConfig {
155 integrator: Integrator::VerletVelocity { thermostat: None },
157 zero_com_drift: true,
159 temp_target: 310.,
161 barostat_cfg: Some(BarostatCfg {
163 pressure_target: 1.,
164 ..Default::default()
165 }),
166 hydrogen_constraint: HydrogenConstraint::Linear { order: 4, iter: 1 },
169 snapshot_handlers: SnapshotHandlers {
171 memory: Some(1),
172 dcd: Some(10),
173 ..Default::default()
174 },
175 sim_box: SimBoxInit::Pad(10.),
177 ..Default::default()
178 };
179
180 let _md = build_dynamics(&dev, vec![&mut mol], &protein, ¶m_set, &cfg, 100, 0.001);
181}