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 source_region: Region, // Even if it is just a point, we don't want corners.
pub dest_plate: &'a Plate, pub dest_plate: &'a Plate,
pub dest_region: Region, pub dest_region: Region,
pub offset: Option<(i8,i8)>, pub interleave_source: Option<(i8,i8)>,
pub interleave_dest: Option<(i8,i8)>,
} }
impl TransferRegion<'_> { 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> { pub fn validate(&self) -> Result<(), String> {
// Checks if the region does anything suspect // 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)] #[cfg(debug_assertions)]
use std::fmt; use std::fmt;
@ -95,10 +127,11 @@ impl fmt::Display for TransferRegion<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "Source Plate:")?; writeln!(f, "Source Plate:")?;
let source_dims = self.source_plate.size(); let source_dims = self.source_plate.size();
let source_wells = self.get_source_wells();
let mut source_string = String::new(); let mut source_string = String::new();
for i in 1..=source_dims.0 { for i in 1..=source_dims.0 {
for j in 1..=source_dims.1 { 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") source_string.push_str("x")
} else { } else {
source_string.push_str("o") 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)), source_region: transfer_region::Region::Rect((1,1), (6,6)),
dest_plate: &destination, dest_plate: &destination,
dest_region: transfer_region::Region::Rect((1,1), (6,6)), 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());
} }