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