Structs for transfers, lots of fixing
This commit is contained in:
parent
a2d406e9c4
commit
ed8a11e8c7
|
@ -1,2 +1,2 @@
|
||||||
pub mod plate;
|
pub mod plate;
|
||||||
pub mod region;
|
pub mod transfer_region;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if all source wells exist:
|
|
||||||
// Sufficient to check if the corners are in-bounds
|
|
||||||
let source_max = self.source_plate.size();
|
|
||||||
if self.source_region.0.0 > source_max.0 ||
|
|
||||||
self.source_region.1.0 > source_max.0 {
|
|
||||||
Err("Source region is out-of-bounds! (Too tall)")
|
|
||||||
}
|
|
||||||
if self.source_region.0.1 > source_max.1 ||
|
|
||||||
self.source_region.1.1 > source_max.1 {
|
|
||||||
Err("Source region is out-of-bounds! (Too wide)")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if all destination wells exist:
|
|
||||||
// NOT IMPLEMENTED
|
|
||||||
|
|
||||||
// Check that source lengths divide destination lengths
|
|
||||||
match self.dest_region {
|
|
||||||
Point => (),
|
|
||||||
Region::Rect(c1, c2) => {
|
Region::Rect(c1, c2) => {
|
||||||
let dest_diff_i = u8::abs_diff(c1.0, c2.0);
|
// Check if all source wells exist:
|
||||||
let dest_diff_j = u8::abs_diff(c1.1, c2.1);
|
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
|
||||||
|
let source_max = self.source_plate.size();
|
||||||
|
if c1.0 > source_max.0 ||
|
||||||
|
c2.0 > source_max.0 {
|
||||||
|
return Err("Source region is out-of-bounds! (Too tall)".to_string())
|
||||||
|
}
|
||||||
|
if c1.1 > source_max.1 ||
|
||||||
|
c2.1 > source_max.1 {
|
||||||
|
return Err("Source region is out-of-bounds! (Too wide)".to_string())
|
||||||
|
}
|
||||||
|
// Check that source lengths divide destination lengths
|
||||||
|
match &self.dest_region {
|
||||||
|
Region::Point(_,_) => (),
|
||||||
|
Region::Rect(c1, c2) => {
|
||||||
|
let dest_diff_i = u8::abs_diff(c1.0, c2.0);
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
17
src/lib.rs
17
src/lib.rs
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue