Structs for transfers, lots of fixing

This commit is contained in:
Emilia Allison 2023-05-12 16:38:14 -04:00
parent a2d406e9c4
commit ed8a11e8c7
Signed by: emilia
GPG Key ID: 7A3F8997BFE894E0
5 changed files with 112 additions and 52 deletions

View File

@ -1,2 +1,2 @@
pub mod plate; pub mod plate;
pub mod region; pub mod transfer_region;

View File

@ -5,7 +5,6 @@ pub struct Plate {
impl Plate { impl Plate {
pub fn new(plate_type: PlateType, plate_format: PlateFormat) -> Self { pub fn new(plate_type: PlateType, plate_format: PlateFormat) -> Self {
let (l,w) = plate_format.size();
Plate { Plate {
plate_type, plate_type,
plate_format, plate_format,

View File

@ -1,69 +1,111 @@
use super::plate::Plate; use super::plate::Plate;
enum Region { pub enum Region {
Rect((u8,u8),(u8,u8)), Rect((u8,u8),(u8,u8)),
Point(u8,u8) Point(u8,u8)
} }
struct TransferRegion { pub struct TransferRegion<'a> {
source_plate: &Plate, pub source_plate: &'a Plate,
source_region: Region::Rect, // 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.
dest_plate: &Plate, pub dest_plate: &'a Plate,
dest_region: Region, pub dest_region: Region,
offset: Option<(u8,u8)>, pub offset: Option<(i8,i8)>,
} }
impl TransferRegion { impl TransferRegion<'_> {
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
/// //
/// If validation fails, we pass a string to show to the user. // If validation fails, we pass a string to show to the user.
/// //
/// We check: // We check:
/// - Are the wells in the source really there? // - Are the wells in the source really there?
/// - Are the wells in the destination there? (Sometimes running OOB is okay though?) // - Are the wells in the destination there? (Sometimes running OOB is okay though?)
/// - In a replication region, do the source lengths divide the destination lengths? // - In a replication region, do the source lengths divide the destination lengths?
// Easy checks: // Easy checks:
if self.source_region.0.0 == 0 || self.source_region.0.1 == 0 match self.source_region {
|| self.source_region.1.0 == 0 || self.source_region.1.1 == 0 { Region::Point(_, _) => return Err("Source region should not be a point!".to_string()),
Err("Source region is out-of-bounds! (Too small)") Region::Rect(c1, c2) => {
}
// Check if all source wells exist: // Check if all source wells exist:
if c1.0 == 0 || c1.1 == 0
|| c2.0 == 0 || c2.1 == 0 {
return Err("Source region is out-of-bounds! (Too small)".to_string())
}
// Sufficient to check if the corners are in-bounds // Sufficient to check if the corners are in-bounds
let source_max = self.source_plate.size(); let source_max = self.source_plate.size();
if self.source_region.0.0 > source_max.0 || if c1.0 > source_max.0 ||
self.source_region.1.0 > source_max.0 { c2.0 > source_max.0 {
Err("Source region is out-of-bounds! (Too tall)") return Err("Source region is out-of-bounds! (Too tall)".to_string())
} }
if self.source_region.0.1 > source_max.1 || if c1.1 > source_max.1 ||
self.source_region.1.1 > source_max.1 { c2.1 > source_max.1 {
Err("Source region is out-of-bounds! (Too wide)") return Err("Source region is out-of-bounds! (Too wide)".to_string())
} }
// Check if all destination wells exist:
// NOT IMPLEMENTED
// Check that source lengths divide destination lengths // Check that source lengths divide destination lengths
match self.dest_region { match &self.dest_region {
Point => (), Region::Point(_,_) => (),
Region::Rect(c1, c2) => { Region::Rect(c1, c2) => {
let dest_diff_i = u8::abs_diff(c1.0, c2.0); let dest_diff_i = u8::abs_diff(c1.0, c2.0);
let dest_diff_j = u8::abs_diff(c1.1, c2.1); let dest_diff_j = u8::abs_diff(c1.1, c2.1);
let source_diff_i = u8::abs_diff(self.source_region.0.0, self.source_region.1.0); let source_diff_i = u8::abs_diff(c1.0, c2.0);
let source_diff_j = u8::abs_diff(self.source_region.0.1, self.source_region.1.1); let source_diff_j = u8::abs_diff(c1.1, c2.1);
if source_diff_i % dest_diff_i != 0 { if source_diff_i % dest_diff_i != 0 {
Err("Replicate region has indivisible height!") return Err("Replicate region has indivisible height!".to_string())
} }
if source_diff_j % dest_diff_j != 0 { if source_diff_j % dest_diff_j != 0 {
Err("Replicate region has indivisible width!") return Err("Replicate region has indivisible width!".to_string())
} }
} }
} }
}
}
// Check if all destination wells exist:
// NOT IMPLEMENTED
return Ok(()) return Ok(())
} }
} }
fn in_region(pt: (u8,u8), r: &Region) -> bool {
match r {
Region::Rect(c1, c2) => {
pt.0 <= u8::max(c1.0, c2.0)
&& pt.0 >= u8::min(c1.0, c2.0)
&& pt.1 <= u8::max(c1.1, c2.1)
&& pt.1 >= u8::min(c1.1, c2.1)
},
Region::Point(i, j) => {
pt.0 == *i && pt.1 == *j
}
}
}
#[cfg(debug_assertions)]
use std::fmt;
#[cfg(debug_assertions)]
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 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) {
source_string.push_str("x")
} else {
source_string.push_str("o")
}
}
source_string.push_str("\n");
}
write!(f, "{}", source_string)
}
}

View File

@ -5,6 +5,9 @@ mod data;
use components::source_plate::SourcePlate; use components::source_plate::SourcePlate;
use dioxus::prelude::*; use dioxus::prelude::*;
#[cfg(debug_assertions)]
use data::*;
pub fn App(cx: Scope) -> Element { pub fn App(cx: Scope) -> Element {
cx.render(rsx! { cx.render(rsx! {
div { div {
@ -16,3 +19,17 @@ pub fn App(cx: Scope) -> Element {
} }
}) })
} }
pub fn plate_test() {
let source = plate::Plate::new(plate::PlateType::Source, plate::PlateFormat::W96);
let destination = plate::Plate::new(plate::PlateType::Destination, plate::PlateFormat::W96);
let transfer = transfer_region::TransferRegion {
source_plate: &source,
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
};
println!("{}", transfer)
}

View File

@ -1,7 +1,9 @@
use plate_tool::App; use plate_tool::App;
use plate_tool::plate_test;
use wasm_logger; use wasm_logger;
fn main() { fn main() {
wasm_logger::init(wasm_logger::Config::default()); // wasm_logger::init(wasm_logger::Config::default());
dioxus_web::launch(App); // dioxus_web::launch(App);
plate_test();
} }