#[cfg(test)]
mod tests {
use pdbtbx::{Format, ReadOptions};
use rust_sasa::structures::atomic::{ChainResult, ProteinResult, ResidueResult};
use rust_sasa::{SASAResult, sasa_result_to_protein_object};
use std::io::{BufReader, Cursor};
#[test]
fn test_sasa_result_to_protein_object_atom() {
let pdb_content = r#"ATOM 1 N ALA A 1 20.154 16.967 25.000 1.00 10.00 N
ATOM 2 CA ALA A 1 19.030 16.155 25.000 1.00 15.00 C
ATOM 3 C ALA A 1 17.948 16.712 25.000 1.00 20.00 C
END
"#;
let mut pdb = ReadOptions::default()
.set_format(Format::Pdb)
.read_raw(BufReader::new(Cursor::new(pdb_content.as_bytes())))
.unwrap()
.0;
let sasa_result = SASAResult::Atom(vec![5.0, 10.0, 15.0]);
sasa_result_to_protein_object(&mut pdb, &sasa_result).unwrap();
let atoms: Vec<_> = pdb.atoms().collect();
assert_eq!(atoms.len(), 3);
assert!((atoms[0].b_factor() - 5.0).abs() < 0.001);
assert!((atoms[1].b_factor() - 10.0).abs() < 0.001);
assert!((atoms[2].b_factor() - 15.0).abs() < 0.001);
}
#[test]
fn test_sasa_result_to_protein_object_residue() {
let pdb_content = r#"ATOM 1 N ALA A 1 20.154 16.967 25.000 1.00 10.00 N
ATOM 2 CA ALA A 1 19.030 16.155 25.000 1.00 15.00 C
ATOM 3 N GLY A 2 17.948 16.712 25.000 1.00 20.00 N
ATOM 4 CA GLY A 2 16.500 17.000 25.000 1.00 25.00 C
END
"#;
let mut pdb = ReadOptions::default()
.set_format(Format::Pdb)
.read_raw(BufReader::new(Cursor::new(pdb_content.as_bytes())))
.unwrap()
.0;
let sasa_result = SASAResult::Residue(vec![
ResidueResult {
serial_number: 1,
insertion_code: "".to_string(),
value: 100.0,
name: "ALA".to_string(),
is_polar: false,
chain_id: "A".to_string(),
},
ResidueResult {
serial_number: 2,
insertion_code: "".to_string(),
value: 200.0,
name: "GLY".to_string(),
is_polar: false,
chain_id: "A".to_string(),
},
]);
sasa_result_to_protein_object(&mut pdb, &sasa_result).unwrap();
let residues: Vec<_> = pdb.residues().collect();
assert_eq!(residues.len(), 2);
for atom in residues[0].atoms() {
assert!((atom.b_factor() - 100.0).abs() < 0.001);
}
for atom in residues[1].atoms() {
assert!((atom.b_factor() - 200.0).abs() < 0.001);
}
}
#[test]
fn test_sasa_result_to_protein_object_chain() {
let pdb_content = r#"ATOM 1 N ALA A 1 20.154 16.967 25.000 1.00 10.00 N
ATOM 2 CA ALA A 1 19.030 16.155 25.000 1.00 15.00 C
ATOM 3 N GLY B 1 17.948 16.712 25.000 1.00 20.00 N
ATOM 4 CA GLY B 1 16.500 17.000 25.000 1.00 25.00 C
END
"#;
let mut pdb = ReadOptions::default()
.set_format(Format::Pdb)
.read_raw(BufReader::new(Cursor::new(pdb_content.as_bytes())))
.unwrap()
.0;
let sasa_result = SASAResult::Chain(vec![
ChainResult {
name: "A".to_string(),
value: 300.0,
},
ChainResult {
name: "B".to_string(),
value: 400.0,
},
]);
sasa_result_to_protein_object(&mut pdb, &sasa_result).unwrap();
let chains: Vec<_> = pdb.chains().collect();
assert_eq!(chains.len(), 2);
for atom in chains[0].atoms() {
assert!((atom.b_factor() - 300.0).abs() < 0.001);
}
for atom in chains[1].atoms() {
assert!((atom.b_factor() - 400.0).abs() < 0.001);
}
}
#[test]
fn test_sasa_result_to_protein_object_protein() {
let pdb_content = r#"ATOM 1 N ALA A 1 20.154 16.967 25.000 1.00 10.00 N
ATOM 2 CA ALA A 1 19.030 16.155 25.000 1.00 15.00 C
ATOM 3 N GLY A 2 17.948 16.712 25.000 1.00 20.00 N
END
"#;
let mut pdb = ReadOptions::default()
.set_format(Format::Pdb)
.read_raw(BufReader::new(Cursor::new(pdb_content.as_bytes())))
.unwrap()
.0;
let sasa_result = SASAResult::Protein(ProteinResult {
global_total: 500.0,
polar_total: 200.0,
non_polar_total: 300.0,
});
sasa_result_to_protein_object(&mut pdb, &sasa_result).unwrap();
for atom in pdb.atoms() {
assert!((atom.b_factor() - 500.0).abs() < 0.001);
}
}
#[test]
fn test_hetatm_excluded_gets_zero_sasa_with_multi_chain() {
use rust_sasa::{ResidueLevel, SASAOptions};
let pdb_content = r#"ATOM 1 N ALA A 1 0.000 0.000 0.000 1.00 10.00 N
ATOM 2 CA ALA A 1 1.458 0.000 0.000 1.00 10.00 C
ATOM 3 N GLY A 2 3.000 0.000 0.000 1.00 10.00 N
ATOM 4 CA GLY A 2 4.458 0.000 0.000 1.00 10.00 C
ATOM 5 N ALA B 1 10.000 0.000 0.000 1.00 10.00 N
ATOM 6 CA ALA B 1 11.458 0.000 0.000 1.00 10.00 C
HETATM 7 O HOH A 3 6.000 0.000 0.000 1.00 10.00 O
HETATM 8 O HOH B 2 13.000 0.000 0.000 1.00 10.00 O
END
"#;
let (pdb, _) = ReadOptions::default()
.set_format(Format::Pdb)
.read_raw(BufReader::new(Cursor::new(pdb_content.as_bytes())))
.unwrap();
let result = SASAOptions::<ResidueLevel>::new()
.with_allow_vdw_fallback(true)
.process(&pdb)
.unwrap();
for res in &result {
if res.name == "HOH" {
assert_eq!(
res.value, 0.0,
"HETATM residue {} in chain {} should have SASA 0.0, got {}",
res.serial_number, res.chain_id, res.value
);
} else {
assert!(
res.value > 0.0,
"ATOM residue {} in chain {} should have non-zero SASA",
res.serial_number,
res.chain_id
);
}
}
let chain_a_res1: Vec<_> = result
.iter()
.filter(|r| r.chain_id == "A" && r.serial_number == 1)
.collect();
let chain_b_res1: Vec<_> = result
.iter()
.filter(|r| r.chain_id == "B" && r.serial_number == 1)
.collect();
assert_eq!(chain_a_res1.len(), 1, "Should have exactly one A:1 residue");
assert_eq!(chain_b_res1.len(), 1, "Should have exactly one B:1 residue");
}
}