Source plate interleaving

This commit is contained in:
Emilia Allison 2023-05-12 20:25:21 -04:00
parent ed8a11e8c7
commit 6bafb0372b
Signed by: emilia
GPG Key ID: 7A3F8997BFE894E0
2 changed files with 39 additions and 4 deletions

View File

@ -10,10 +10,34 @@ pub struct TransferRegion<'a> {
pub source_region: Region, // Even if it is just a point, we don't want corners.
pub dest_plate: &'a Plate,
pub dest_region: Region,
pub offset: Option<(i8,i8)>,
pub interleave_source: Option<(i8,i8)>,
pub interleave_dest: Option<(i8,i8)>,
}
impl TransferRegion<'_> {
pub fn get_source_wells(&self) -> Vec<(u8,u8)> {
if let Region::Rect(c1, c2) = self.source_region {
let mut wells = Vec::<(u8,u8)>::new();
let (ul, br) = standardize_rectangle(&c1, &c2);
let (interleave_i, interleave_j) = self.interleave_source.unwrap_or((1,1));
// NOTE: This will panic if either is 0!
// We'll reassign these values (still not mutable) just in case.
// This behaviour shouldn't be replicated for destination wells
// because a zero step permits pooling.
let (interleave_i, interleave_j) = (i8::max(interleave_i, 1), i8::max(interleave_j, 1));
for i in (ul.0..=br.0).step_by(i8::abs(interleave_i) as usize) {
for j in (ul.0..=br.0).step_by(i8::abs(interleave_j) as usize) {
// NOTE: It looks like we're ignoring negative interleaves,
// because it wouldn't make a difference here---the same
// wells will still be involved in the transfer.
wells.push((i,j))
}
}
return wells;
} else { panic!("Source region is just a point!") }
}
pub fn validate(&self) -> Result<(), String> {
// Checks if the region does anything suspect
//
@ -87,6 +111,14 @@ fn in_region(pt: (u8,u8), r: &Region) -> bool {
}
}
fn standardize_rectangle(c1: &(u8,u8), c2: &(u8,u8)) -> ((u8,u8),(u8,u8)) {
let upper_left_i = u8::min(c1.0, c2.0);
let upper_left_j = u8::min(c1.1, c2.1);
let bottom_right_i = u8::max(c1.0, c2.0);
let bottom_right_j = u8::max(c1.1, c2.1);
return ((upper_left_i,upper_left_j),(bottom_right_i,bottom_right_j));
}
#[cfg(debug_assertions)]
use std::fmt;
@ -95,10 +127,11 @@ impl fmt::Display for TransferRegion<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "Source Plate:")?;
let source_dims = self.source_plate.size();
let source_wells = self.get_source_wells();
let mut source_string = String::new();
for i in 1..=source_dims.0 {
for j in 1..=source_dims.1 {
if in_region((i,j), &self.source_region) {
if source_wells.contains(&(i,j)) {
source_string.push_str("x")
} else {
source_string.push_str("o")

View File

@ -29,7 +29,9 @@ pub fn plate_test() {
source_region: transfer_region::Region::Rect((1,1), (6,6)),
dest_plate: &destination,
dest_region: transfer_region::Region::Rect((1,1), (6,6)),
offset: None
interleave_source: Some((2,1)),
interleave_dest: None
};
println!("{}", transfer)
println!("{}", transfer);
println!("{:?}", transfer.get_source_wells());
}