///|
/// PDB Dice Demo - PDB structure extraction and selection tools.
///
/// Run: moon run examples/pdb_dice_demo/main.mbt
fn main {
println("=== PDB Dice Demo ===\n")
// Create a simple PDB structure for demonstration
let pdb_content = "ATOM 1 N ALA A 1 11.104 6.134 10.298 1.00 20.00 N\n" +
"ATOM 2 CA ALA A 1 11.639 6.168 10.426 1.00 20.00 C\n" +
"ATOM 3 C ALA A 1 12.221 6.201 10.542 1.00 20.00 C\n" +
"ATOM 4 O ALA A 1 12.803 6.234 10.658 1.00 20.00 O\n" +
"ATOM 5 CB ALA A 1 12.000 7.000 11.000 1.00 20.00 C\n" +
"ATOM 6 N GLY A 2 13.385 6.267 10.774 1.00 25.00 N\n" +
"ATOM 7 CA GLY A 2 13.968 6.300 10.891 1.00 25.00 C\n" +
"ATOM 8 C GLY A 2 14.549 6.333 11.007 1.00 25.00 C\n" +
"ATOM 9 O GLY A 2 15.131 6.366 11.123 1.00 25.00 O\n" +
"ATOM 10 N VAL A 3 15.500 6.400 11.200 1.00 30.00 N\n" +
"ATOM 11 CA VAL A 3 16.000 6.450 11.300 1.00 30.00 C\n" +
"ATOM 12 C VAL A 3 16.500 6.500 11.400 1.00 30.00 C\n" +
"ATOM 13 O VAL A 3 17.000 6.550 11.500 1.00 30.00 O\n" +
"ATOM 14 CB VAL A 3 16.200 7.200 11.800 1.00 30.00 C\n" +
"ATOM 15 CG1 VAL A 3 15.800 8.000 11.200 1.00 30.00 C\n" +
"ATOM 16 CG2 VAL A 3 17.000 7.800 12.500 1.00 30.00 C\n" +
"ATOM 17 N LEU A 4 17.500 6.600 11.600 1.00 35.00 N\n" +
"ATOM 18 CA LEU A 4 18.000 6.650 11.700 1.00 35.00 C\n" +
"ATOM 19 C LEU A 4 18.500 6.700 11.800 1.00 35.00 C\n" +
"ATOM 20 O LEU A 4 19.000 6.750 11.900 1.00 35.00 O\n" +
"TER 21 LEU A 4\n" +
"END\n"
let structure = @bio.parse_pdb(pdb_content)
println("1. Original structure:")
println(" Models: \{structure.get_num_models()}")
println(" Chains: \{structure.get_num_chains()}")
println(" Residues: \{structure.get_num_residues()}")
println(" Atoms: \{structure.get_num_atoms()}")
// 2. Extract chain A
println("\n2. Extract chain A:")
let chain_a = @bio.extract_chain(structure, 'A')
println(" Chains extracted: \{chain_a.get_num_chains()}")
println(" Residues: \{chain_a.get_num_residues()}")
println(" Atoms: \{chain_a.get_num_atoms()}")
// 3. Extract residue range
println("\n3. Extract residues 2-3 from chain A:")
let res_range = @bio.extract_residue_range(structure, 'A', 2, 3)
println(" Residues in range: \{res_range.get_num_residues()}")
println(" Atoms: \{res_range.get_num_atoms()}")
// 4. Extract specific residues
println("\n4. Extract specific residues (1, 4) from chain A:")
let rid1 = @bio.ResidueId::new('A', 1)
let rid2 = @bio.ResidueId::new('A', 4)
let residue_ids = [rid1, rid2]
let specific_res = @bio.extract_residues(structure, residue_ids)
println(" Residues extracted: \{specific_res.get_num_residues()}")
println(" Atoms: \{specific_res.get_num_atoms()}")
// 5. Extract CA atoms
println("\n5. Extract CA atoms only:")
let ca_structure = @bio.extract_ca_atoms(structure)
println(" Structure with CA atoms:")
println(" Residues: \{ca_structure.get_num_residues()}")
println(" Atoms: \{ca_structure.get_num_atoms()}")
// 6. Filter by B-factor
println("\n6. Filter atoms with B-factor between 25 and 40:")
let filtered = @bio.filter_by_bfactor(structure, 25.0, 40.0)
println(" Atoms after filtering: \{filtered.get_num_atoms()}")
// 7. Select atoms near a point
println("\n7. Select atoms near point (15.0, 6.5, 11.3) within 2.0Å:")
let point = @bio.Vector3::new(15.0, 6.5, 11.3)
let near_atoms = @bio.select_atoms_near_point(structure, point, 2.0)
println(" Atoms near point: \{near_atoms.length()}")
if near_atoms.length() > 0 {
println(
" First atom: \{near_atoms[0].name} (element: \{near_atoms[0].element})",
)
}
// 8. Structure statistics
println("\n8. Structure statistics:")
let stats = @bio.structure_stats(structure)
println(" Structure ID: \{stats.structure_id}")
println(" Atoms: \{stats.num_atoms}")
println(" Residues: \{stats.num_residues}")
println(" Chains: \{stats.num_chains}")
println(" Models: \{stats.num_models}")
// 9. Chain sequence
println("\n9. Chain A sequence:")
let seq = @bio.chain_sequence(structure, 'A')
println(" Sequence: \{seq}")
println("\n=== Demo Complete ===")
}