array-like frame indexing

This commit is contained in:
daniel
2020-11-17 09:00:11 +01:00
parent a29faf9d63
commit ee9158555e
3 changed files with 66 additions and 8 deletions

View File

@@ -29,7 +29,7 @@ fn main() -> Result<()> {
assert_eq!(frame.step, 1);
assert_eq!(frame.len(), num_atoms);
let first_atom_coords = frame.coords[0];
let first_atom_coords = frame[0]; // shorthand for frame.coords[0]
assert_eq!(first_atom_coords, [-0.8901, 0.4127, -0.055499997]);
Ok(())

View File

@@ -1,3 +1,5 @@
use std::ops::{Index, IndexMut};
/// A frame represents a single step in a trajectory.
#[derive(Clone, Debug)]
pub struct Frame {
@@ -66,6 +68,20 @@ impl Frame {
}
}
impl Index<usize> for Frame {
type Output = [f32; 3];
fn index(&self, index: usize) -> &Self::Output {
&self.coords[index]
}
}
impl IndexMut<usize> for Frame {
fn index_mut(&mut self, index: usize) -> &mut Self::Output { {
&mut self.coords[index]
}}
}
#[cfg(test)]
mod tests {
use super::*;
@@ -80,15 +96,15 @@ mod tests {
#[test]
fn test_frame_filter_atoms() {
let mut frame = Frame::with_len(3);
frame.coords[0] = [1.0, 2.0, 3.0];
frame.coords[1] = [4.0, 5.0, 6.0];
frame.coords[2] = [7.0, 8.0, 9.0];
frame[0] = [1.0, 2.0, 3.0];
frame[1] = [4.0, 5.0, 6.0];
frame[2] = [7.0, 8.0, 9.0];
let filter: Vec<usize> = vec![1, 2];
let mut frame_new = frame.clone();
frame_new.filter_coords(&filter);
assert!(frame_new.len() == filter.len());
assert!(frame_new.coords[0] == frame.coords[1]);
assert!(frame_new.coords[1] == frame.coords[2]);
assert!(frame_new.coords[0] == frame[1]);
assert!(frame_new.coords[1] == frame[2]);
}
#[test]
@@ -108,7 +124,48 @@ mod tests {
frame.filter_coords(&[1]);
for i in 0..3 {
assert_approx_eq!(frame.coords[0][i], 1.0);
assert_approx_eq!(frame[0][i], 1.0);
}
}
#[test]
#[allow(unused_mut)]
fn test_index() {
// test Index
let frame = Frame {
step: 0,
time: 0.0,
box_vector: [[0.0; 3]; 3],
coords: vec![[0.0; 3], [1.0; 3], [2.0; 3]]
};
for i in 0..frame.len() {
for j in 0..3 {
assert_approx_eq!(frame[i][j], frame[i][j]);
}
}
// test IndexMut
let mut frame = Frame {
step: 0,
time: 0.0,
box_vector: [[0.0; 3]; 3],
coords: vec![[0.0; 3], [1.0; 3], [2.0; 3]]
};
for i in 0..frame.len() {
for j in 0..3 {
assert_approx_eq!(frame[i][j], frame.coords[i][j]);
}
}
frame[0] = [123.0; 3];
for i in 0..frame.len() {
for j in 0..3 {
assert_approx_eq!(frame[i][j], frame.coords[i][j]);
if i == 0 {
assert_approx_eq!(frame[i][j], 123.0);
}
}
}
}
}

View File

@@ -26,7 +26,7 @@
//! assert_eq!(frame.step, 1);
//! assert_eq!(frame.len(), num_atoms);
//!
//! let first_atom_coords = frame.coords[0];
//! let first_atom_coords = frame[0];
//! assert_eq!(first_atom_coords, [-0.8901, 0.4127, -0.055499997]);
//!
//! Ok(())
@@ -232,6 +232,7 @@ pub trait Trajectory {
/// Get the number of atoms from the give trajectory
fn get_num_atoms(&mut self) -> Result<usize>;
}
/// Handle to Read/Write XTC Trajectories