chore: format
This commit is contained in:
		
							parent
							
								
									6a9a7ff0ff
								
							
						
					
					
						commit
						43331ff8f2
					
				| 
						 | 
				
			
			@ -55,7 +55,7 @@ fn SourcePlateCell(cx: Scope<PlateCellProps>, i: u8, j: u8, color: Option<String
 | 
			
		|||
    };
 | 
			
		||||
    let color_string = match color {
 | 
			
		||||
        Some(c) => c.clone(),
 | 
			
		||||
        None => "None".to_string()
 | 
			
		||||
        None => "None".to_string(),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    cx.render(rsx! {
 | 
			
		||||
| 
						 | 
				
			
			@ -126,9 +126,9 @@ mod tests {
 | 
			
		|||
    #[test]
 | 
			
		||||
    fn test_in_rect1() {
 | 
			
		||||
        // Test in center of rect
 | 
			
		||||
        let c1 = (1,1);
 | 
			
		||||
        let c2 = (10,10);
 | 
			
		||||
        let pt = (5,5);
 | 
			
		||||
        let c1 = (1, 1);
 | 
			
		||||
        let c2 = (10, 10);
 | 
			
		||||
        let pt = (5, 5);
 | 
			
		||||
        assert!(in_rect(Some(c1), Some(c2), pt));
 | 
			
		||||
        // Order of the corners should not matter:
 | 
			
		||||
        assert!(in_rect(Some(c2), Some(c1), pt));
 | 
			
		||||
| 
						 | 
				
			
			@ -137,10 +137,10 @@ mod tests {
 | 
			
		|||
    #[test]
 | 
			
		||||
    fn test_in_rect2() {
 | 
			
		||||
        // Test on top/bottom edges of rect
 | 
			
		||||
        let c1 = (1,1);
 | 
			
		||||
        let c2 = (10,10);
 | 
			
		||||
        let pt1 = (1,5);
 | 
			
		||||
        let pt2 = (10,5);
 | 
			
		||||
        let c1 = (1, 1);
 | 
			
		||||
        let c2 = (10, 10);
 | 
			
		||||
        let pt1 = (1, 5);
 | 
			
		||||
        let pt2 = (10, 5);
 | 
			
		||||
        assert!(in_rect(Some(c1), Some(c2), pt1));
 | 
			
		||||
        assert!(in_rect(Some(c1), Some(c2), pt2));
 | 
			
		||||
        // Order of the corners should not matter:
 | 
			
		||||
| 
						 | 
				
			
			@ -151,10 +151,10 @@ mod tests {
 | 
			
		|||
    #[test]
 | 
			
		||||
    fn test_in_rect3() {
 | 
			
		||||
        // Test on left/right edges of rect
 | 
			
		||||
        let c1 = (1,1);
 | 
			
		||||
        let c2 = (10,10);
 | 
			
		||||
        let pt1 = (5,1);
 | 
			
		||||
        let pt2 = (5,10);
 | 
			
		||||
        let c1 = (1, 1);
 | 
			
		||||
        let c2 = (10, 10);
 | 
			
		||||
        let pt1 = (5, 1);
 | 
			
		||||
        let pt2 = (5, 10);
 | 
			
		||||
        assert!(in_rect(Some(c1), Some(c2), pt1));
 | 
			
		||||
        assert!(in_rect(Some(c1), Some(c2), pt2));
 | 
			
		||||
        // Order of the corners should not matter:
 | 
			
		||||
| 
						 | 
				
			
			@ -164,11 +164,11 @@ mod tests {
 | 
			
		|||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_in_rect4() {
 | 
			
		||||
    // Test cases that should fail
 | 
			
		||||
        let c1 = (1,1);
 | 
			
		||||
        let c2 = (10,10);
 | 
			
		||||
        let pt1 = (0,0);
 | 
			
		||||
        let pt2 = (15,15);
 | 
			
		||||
        // Test cases that should fail
 | 
			
		||||
        let c1 = (1, 1);
 | 
			
		||||
        let c2 = (10, 10);
 | 
			
		||||
        let pt1 = (0, 0);
 | 
			
		||||
        let pt2 = (15, 15);
 | 
			
		||||
        assert_eq!(false, in_rect(Some(c1), Some(c2), pt1));
 | 
			
		||||
        assert_eq!(false, in_rect(Some(c1), Some(c2), pt2));
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,14 +11,14 @@ impl Plate {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn size(&self) -> (u8,u8) {
 | 
			
		||||
    pub fn size(&self) -> (u8, u8) {
 | 
			
		||||
        self.plate_format.size()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub enum PlateType {
 | 
			
		||||
    Source,
 | 
			
		||||
    Destination
 | 
			
		||||
    Destination,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub enum PlateFormat {
 | 
			
		||||
| 
						 | 
				
			
			@ -33,16 +33,16 @@ pub enum PlateFormat {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
impl PlateFormat {
 | 
			
		||||
    pub fn size(&self) -> (u8,u8) {
 | 
			
		||||
    pub fn size(&self) -> (u8, u8) {
 | 
			
		||||
        match self {
 | 
			
		||||
            PlateFormat::W6 => (2,3),
 | 
			
		||||
            PlateFormat::W12 => (3,4),
 | 
			
		||||
            PlateFormat::W24 => (4,6),
 | 
			
		||||
            PlateFormat::W48 => (6,8),
 | 
			
		||||
            PlateFormat::W96 => (8,12),
 | 
			
		||||
            PlateFormat::W384 => (16,24),
 | 
			
		||||
            PlateFormat::W1536 => (32,48),
 | 
			
		||||
            PlateFormat::W3456 => (48,72),
 | 
			
		||||
            PlateFormat::W6 => (2, 3),
 | 
			
		||||
            PlateFormat::W12 => (3, 4),
 | 
			
		||||
            PlateFormat::W24 => (4, 6),
 | 
			
		||||
            PlateFormat::W48 => (6, 8),
 | 
			
		||||
            PlateFormat::W96 => (8, 12),
 | 
			
		||||
            PlateFormat::W384 => (16, 24),
 | 
			
		||||
            PlateFormat::W1536 => (32, 48),
 | 
			
		||||
            PlateFormat::W3456 => (48, 72),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,14 +2,14 @@ use super::plate::Plate;
 | 
			
		|||
 | 
			
		||||
#[derive(Clone, Copy)]
 | 
			
		||||
pub enum Region {
 | 
			
		||||
    Rect((u8,u8),(u8,u8)),
 | 
			
		||||
    Point((u8,u8))
 | 
			
		||||
    Rect((u8, u8), (u8, u8)),
 | 
			
		||||
    Point((u8, u8)),
 | 
			
		||||
}
 | 
			
		||||
impl TryFrom<Region> for ((u8,u8),(u8,u8)) {
 | 
			
		||||
impl TryFrom<Region> for ((u8, u8), (u8, u8)) {
 | 
			
		||||
    type Error = &'static str;
 | 
			
		||||
    fn try_from(region: Region) -> Result<Self, Self::Error> {
 | 
			
		||||
        if let Region::Rect(c1, c2) = region {
 | 
			
		||||
            Ok((c1,c2))
 | 
			
		||||
            Ok((c1, c2))
 | 
			
		||||
        } else {
 | 
			
		||||
            // Should consider returning a degenerate rectangle here instead
 | 
			
		||||
            Err("Cannot convert this region to a rectangle, it was a point.")
 | 
			
		||||
| 
						 | 
				
			
			@ -22,16 +22,16 @@ 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 interleave_source: Option<(i8,i8)>,
 | 
			
		||||
    pub interleave_dest: 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)> {
 | 
			
		||||
    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 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));
 | 
			
		||||
            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
 | 
			
		||||
| 
						 | 
				
			
			@ -40,20 +40,22 @@ impl TransferRegion<'_> {
 | 
			
		|||
 | 
			
		||||
            for i in (ul.0..=br.0).step_by(i8::abs(interleave_i) as usize) {
 | 
			
		||||
                for j in (ul.1..=br.1).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))
 | 
			
		||||
                    // 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!") }
 | 
			
		||||
        } else {
 | 
			
		||||
            panic!("Source region is just a point!")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    pub fn get_destination_wells(&self) -> Vec<(u8,u8)> {
 | 
			
		||||
    pub fn get_destination_wells(&self) -> Vec<(u8, u8)> {
 | 
			
		||||
        let map = self.calculate_map();
 | 
			
		||||
        let source_wells = self.get_source_wells();
 | 
			
		||||
 | 
			
		||||
        let mut wells = Vec::<(u8,u8)>::new();
 | 
			
		||||
        let mut wells = Vec::<(u8, u8)>::new();
 | 
			
		||||
 | 
			
		||||
        for well in source_wells {
 | 
			
		||||
            if let Some(mut dest_wells) = map(well) {
 | 
			
		||||
| 
						 | 
				
			
			@ -64,22 +66,23 @@ impl TransferRegion<'_> {
 | 
			
		|||
        return wells;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn calculate_map(&self) -> Box<dyn Fn((u8,u8)) -> Option<Vec<(u8,u8)>> + '_> {
 | 
			
		||||
    pub fn calculate_map(&self) -> Box<dyn Fn((u8, u8)) -> Option<Vec<(u8, u8)>> + '_> {
 | 
			
		||||
        // By validating first, we have a stronger guarantee that
 | 
			
		||||
        // this function will not panic. :)
 | 
			
		||||
        if let Err(msg) = self.validate() {
 | 
			
		||||
            eprintln!("{}", msg);
 | 
			
		||||
            eprintln!("This transfer will be empty.");
 | 
			
		||||
            return Box::new(|(_,_)| None)
 | 
			
		||||
            return Box::new(|(_, _)| None);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let source_wells = self.get_source_wells();
 | 
			
		||||
        let il_dest = self.interleave_dest.unwrap_or((1,1));
 | 
			
		||||
        let il_source = self.interleave_source.unwrap_or((1,1));
 | 
			
		||||
        let il_dest = self.interleave_dest.unwrap_or((1, 1));
 | 
			
		||||
        let il_source = self.interleave_source.unwrap_or((1, 1));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        let source_corners: ((u8,u8),(u8,u8)) = self.source_region.try_into()
 | 
			
		||||
                                                   .expect("Source region should not be a point");
 | 
			
		||||
        let source_corners: ((u8, u8), (u8, u8)) = self
 | 
			
		||||
            .source_region
 | 
			
		||||
            .try_into()
 | 
			
		||||
            .expect("Source region should not be a point");
 | 
			
		||||
        let (source_ul, _) = standardize_rectangle(&source_corners.0, &source_corners.1);
 | 
			
		||||
        // This map is not necessarily injective or surjective,
 | 
			
		||||
        // but we will have these properties in certain cases.
 | 
			
		||||
| 
						 | 
				
			
			@ -88,59 +91,88 @@ impl TransferRegion<'_> {
 | 
			
		|||
 | 
			
		||||
        // Non-replicate transfers:
 | 
			
		||||
        match self.dest_region {
 | 
			
		||||
            Region::Point((x,y)) => return Box::new(move |(i,j)| {
 | 
			
		||||
                if source_wells.contains(&(i,j)) {
 | 
			
		||||
                    // Validity here already checked by self.validate()
 | 
			
		||||
                    Some(vec!((
 | 
			
		||||
                            x + i.checked_sub(source_ul.0).expect("Point cannot have been less than UL")
 | 
			
		||||
                                .checked_div(il_source.0.abs() as u8).expect("Source interleave cannot be 0")
 | 
			
		||||
                                    .mul(il_dest.0.abs() as u8),
 | 
			
		||||
                            y + j.checked_sub(source_ul.1).expect("Point cannot have been less than UL")
 | 
			
		||||
                                .checked_div(il_source.1.abs() as u8).expect("Source interleave cannot be 0")
 | 
			
		||||
                                    .mul(il_dest.1.abs() as u8),
 | 
			
		||||
                            )))
 | 
			
		||||
                } else { None }
 | 
			
		||||
            }),
 | 
			
		||||
            Region::Rect(c1, c2) => return Box::new(move |(i,j)| {
 | 
			
		||||
                // Because of our call to validate,
 | 
			
		||||
                // we can assume that our destination region contains
 | 
			
		||||
                // an integer number of our source regions.
 | 
			
		||||
                if source_wells.contains(&(i,j)) {
 | 
			
		||||
                    // Find points by checking congruence class
 | 
			
		||||
                    let possible_destination_wells = create_dense_rectangle(&c1, &c2);
 | 
			
		||||
                    let (ds1,ds2) = standardize_rectangle(&c1, &c2);
 | 
			
		||||
                    let (s1,s2) = standardize_rectangle(&source_corners.0, &source_corners.1);
 | 
			
		||||
                    let dims = (s2.0.checked_sub(s1.0).unwrap()+1, s2.1.checked_sub(s1.1).unwrap()+1);
 | 
			
		||||
                    let relative_ij = (i.checked_sub(source_ul.0).expect("Point cannot have been less than UL"),
 | 
			
		||||
                                       j.checked_sub(source_ul.1).expect("Point cannot have been less than UL"));
 | 
			
		||||
                    /*
 | 
			
		||||
                    println!("{} % {} == {}", i, dims.0, i*il_dest.0.abs() as u8 % dims.0);
 | 
			
		||||
                    for a in ds1.0..=ds2.0 {
 | 
			
		||||
                        for b in ds1.1..=ds2.1 {
 | 
			
		||||
                            println!("({},{}): {} % {} == {}", a, b,
 | 
			
		||||
                            a.checked_sub(ds1.0).unwrap()+1, dims.0,
 | 
			
		||||
                            (a.checked_sub(ds1.0).unwrap()+1) % dims.0);
 | 
			
		||||
                        }
 | 
			
		||||
            Region::Point((x, y)) => {
 | 
			
		||||
                return Box::new(move |(i, j)| {
 | 
			
		||||
                    if source_wells.contains(&(i, j)) {
 | 
			
		||||
                        // Validity here already checked by self.validate()
 | 
			
		||||
                        Some(vec![(
 | 
			
		||||
                            x + i
 | 
			
		||||
                                .checked_sub(source_ul.0)
 | 
			
		||||
                                .expect("Point cannot have been less than UL")
 | 
			
		||||
                                .checked_div(il_source.0.abs() as u8)
 | 
			
		||||
                                .expect("Source interleave cannot be 0")
 | 
			
		||||
                                .mul(il_dest.0.abs() as u8),
 | 
			
		||||
                            y + j
 | 
			
		||||
                                .checked_sub(source_ul.1)
 | 
			
		||||
                                .expect("Point cannot have been less than UL")
 | 
			
		||||
                                .checked_div(il_source.1.abs() as u8)
 | 
			
		||||
                                .expect("Source interleave cannot be 0")
 | 
			
		||||
                                .mul(il_dest.1.abs() as u8),
 | 
			
		||||
                        )])
 | 
			
		||||
                    } else {
 | 
			
		||||
                        None
 | 
			
		||||
                    }
 | 
			
		||||
                    for a in ds1.0..=ds2.0 {
 | 
			
		||||
                        for b in ds1.1..=ds2.1 {
 | 
			
		||||
                            println!("({},{}): {} % {} == {}", a, b,
 | 
			
		||||
                            a.checked_sub(ds1.0).unwrap()+1, il_dest.0.abs() as u8,
 | 
			
		||||
                            (a.checked_sub(ds1.0).unwrap()+1) % il_dest.0.abs() as u8);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            Region::Rect(c1, c2) => {
 | 
			
		||||
                return Box::new(move |(i, j)| {
 | 
			
		||||
                    // Because of our call to validate,
 | 
			
		||||
                    // we can assume that our destination region contains
 | 
			
		||||
                    // an integer number of our source regions.
 | 
			
		||||
                    if source_wells.contains(&(i, j)) {
 | 
			
		||||
                        // Find points by checking congruence class
 | 
			
		||||
                        let possible_destination_wells = create_dense_rectangle(&c1, &c2);
 | 
			
		||||
                        let (ds1, ds2) = standardize_rectangle(&c1, &c2);
 | 
			
		||||
                        let (s1, s2) = standardize_rectangle(&source_corners.0, &source_corners.1);
 | 
			
		||||
                        let dims = (
 | 
			
		||||
                            s2.0.checked_sub(s1.0).unwrap() + 1,
 | 
			
		||||
                            s2.1.checked_sub(s1.1).unwrap() + 1,
 | 
			
		||||
                        );
 | 
			
		||||
                        let relative_ij = (
 | 
			
		||||
                            i.checked_sub(source_ul.0)
 | 
			
		||||
                                .expect("Point cannot have been less than UL"),
 | 
			
		||||
                            j.checked_sub(source_ul.1)
 | 
			
		||||
                                .expect("Point cannot have been less than UL"),
 | 
			
		||||
                        );
 | 
			
		||||
                        /*
 | 
			
		||||
                        println!("{} % {} == {}", i, dims.0, i*il_dest.0.abs() as u8 % dims.0);
 | 
			
		||||
                        for a in ds1.0..=ds2.0 {
 | 
			
		||||
                            for b in ds1.1..=ds2.1 {
 | 
			
		||||
                                println!("({},{}): {} % {} == {}", a, b,
 | 
			
		||||
                                a.checked_sub(ds1.0).unwrap()+1, dims.0,
 | 
			
		||||
                                (a.checked_sub(ds1.0).unwrap()+1) % dims.0);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    */
 | 
			
		||||
                        for a in ds1.0..=ds2.0 {
 | 
			
		||||
                            for b in ds1.1..=ds2.1 {
 | 
			
		||||
                                println!("({},{}): {} % {} == {}", a, b,
 | 
			
		||||
                                a.checked_sub(ds1.0).unwrap()+1, il_dest.0.abs() as u8,
 | 
			
		||||
                                (a.checked_sub(ds1.0).unwrap()+1) % il_dest.0.abs() as u8);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        */
 | 
			
		||||
 | 
			
		||||
                    Some(possible_destination_wells.into_iter()
 | 
			
		||||
                        .filter(|(x,y)| i*il_dest.0.abs() as u8 % dims.0 
 | 
			
		||||
                                        == (x.checked_sub(ds1.0).unwrap() + 1) % dims.0 &&
 | 
			
		||||
                                        j*il_dest.1.abs() as u8 % dims.1
 | 
			
		||||
                                        == (y.checked_sub(ds1.1).unwrap() + 1) % dims.1)
 | 
			
		||||
                        .filter(|(x,y)| (x.checked_sub(ds1.0).unwrap()) % il_dest.0.abs() as u8 == 0 &&
 | 
			
		||||
                                        (y.checked_sub(ds1.1).unwrap()) % il_dest.1.abs() as u8 == 0)
 | 
			
		||||
                        .collect())
 | 
			
		||||
                } else { None }
 | 
			
		||||
            })
 | 
			
		||||
                        Some(
 | 
			
		||||
                            possible_destination_wells
 | 
			
		||||
                                .into_iter()
 | 
			
		||||
                                .filter(|(x, y)| {
 | 
			
		||||
                                    i * il_dest.0.abs() as u8 % dims.0
 | 
			
		||||
                                        == (x.checked_sub(ds1.0).unwrap() + 1) % dims.0
 | 
			
		||||
                                        && j * il_dest.1.abs() as u8 % dims.1
 | 
			
		||||
                                            == (y.checked_sub(ds1.1).unwrap() + 1) % dims.1
 | 
			
		||||
                                })
 | 
			
		||||
                                .filter(|(x, y)| {
 | 
			
		||||
                                    (x.checked_sub(ds1.0).unwrap()) % il_dest.0.abs() as u8 == 0
 | 
			
		||||
                                        && (y.checked_sub(ds1.1).unwrap()) % il_dest.1.abs() as u8
 | 
			
		||||
                                            == 0
 | 
			
		||||
                                })
 | 
			
		||||
                                .collect(),
 | 
			
		||||
                        )
 | 
			
		||||
                    } else {
 | 
			
		||||
                        None
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -153,27 +185,24 @@ impl TransferRegion<'_> {
 | 
			
		|||
        //     - Are the wells in the source really there?
 | 
			
		||||
        //     - In a replication region, do the source lengths divide the destination lengths?
 | 
			
		||||
        //     - Are the interleaves valid?
 | 
			
		||||
        let il_source = self.interleave_source.unwrap_or((1,1));
 | 
			
		||||
        let il_dest = self.interleave_dest.unwrap_or((1,1));
 | 
			
		||||
        let il_source = self.interleave_source.unwrap_or((1, 1));
 | 
			
		||||
        let il_dest = self.interleave_dest.unwrap_or((1, 1));
 | 
			
		||||
 | 
			
		||||
        match self.source_region {
 | 
			
		||||
            Region::Point(_) => return Err("Source region should not be a point!"),
 | 
			
		||||
            Region::Rect(s1, s2) => {
 | 
			
		||||
                // Check if all source wells exist:
 | 
			
		||||
                if s1.0 == 0 || s1.1 == 0
 | 
			
		||||
                    || s2.0 == 0 || s2.1 == 0 {
 | 
			
		||||
                        return Err("Source region is out-of-bounds! (Too small)")
 | 
			
		||||
                    }
 | 
			
		||||
                if s1.0 == 0 || s1.1 == 0 || s2.0 == 0 || s2.1 == 0 {
 | 
			
		||||
                    return Err("Source region is out-of-bounds! (Too small)");
 | 
			
		||||
                }
 | 
			
		||||
                // Sufficient to check if the corners are in-bounds
 | 
			
		||||
                let source_max = self.source_plate.size();
 | 
			
		||||
                if s1.0 > source_max.0 ||
 | 
			
		||||
                    s2.0 > source_max.0 {
 | 
			
		||||
                        return Err("Source region is out-of-bounds! (Too tall)")
 | 
			
		||||
                    }
 | 
			
		||||
                if s1.1 > source_max.1 ||
 | 
			
		||||
                    s2.1 > source_max.1 {
 | 
			
		||||
                        return Err("Source region is out-of-bounds! (Too wide)")
 | 
			
		||||
                    }
 | 
			
		||||
                if s1.0 > source_max.0 || s2.0 > source_max.0 {
 | 
			
		||||
                    return Err("Source region is out-of-bounds! (Too tall)");
 | 
			
		||||
                }
 | 
			
		||||
                if s1.1 > source_max.1 || s2.1 > source_max.1 {
 | 
			
		||||
                    return Err("Source region is out-of-bounds! (Too wide)");
 | 
			
		||||
                }
 | 
			
		||||
                // Check that source lengths divide destination lengths
 | 
			
		||||
                match &self.dest_region {
 | 
			
		||||
                    Region::Point(_) => (),
 | 
			
		||||
| 
						 | 
				
			
			@ -182,27 +211,30 @@ impl TransferRegion<'_> {
 | 
			
		|||
                        // complicated to compute the true dimensions of
 | 
			
		||||
                        // each region.
 | 
			
		||||
                        // (dim)*(il) - (il - 1)
 | 
			
		||||
                        let dest_diff_i = ((il_dest.0.abs() as u8)*u8::abs_diff(d1.0, d2.0))
 | 
			
		||||
                                            .checked_sub(il_dest.0.abs() as u8 - 1)
 | 
			
		||||
                                            .expect("Dimension is somehow negative?")+1;
 | 
			
		||||
                        let dest_diff_j = ((il_dest.1.abs() as u8)*u8::abs_diff(d1.1, d2.1))
 | 
			
		||||
                                            .checked_sub(il_dest.1.abs() as u8 - 1)
 | 
			
		||||
                                            .expect("Dimension is somehow negative?")+1;
 | 
			
		||||
                        let source_diff_i = ((il_source.0.abs() as u8)*u8::abs_diff(s1.0, s2.0))
 | 
			
		||||
                                            .checked_sub(il_source.0.abs() as u8 - 1)
 | 
			
		||||
                                            .expect("Dimension is somehow negative?")+1;
 | 
			
		||||
                        let source_diff_j = ((il_source.1.abs() as u8)*u8::abs_diff(s1.1, s2.1))
 | 
			
		||||
                                            .checked_sub(il_source.1.abs() as u8 - 1)
 | 
			
		||||
                                            .expect("Dimension is somehow negative?")+1;
 | 
			
		||||
 | 
			
		||||
                        let dest_diff_i = ((il_dest.0.abs() as u8) * u8::abs_diff(d1.0, d2.0))
 | 
			
		||||
                            .checked_sub(il_dest.0.abs() as u8 - 1)
 | 
			
		||||
                            .expect("Dimension is somehow negative?")
 | 
			
		||||
                            + 1;
 | 
			
		||||
                        let dest_diff_j = ((il_dest.1.abs() as u8) * u8::abs_diff(d1.1, d2.1))
 | 
			
		||||
                            .checked_sub(il_dest.1.abs() as u8 - 1)
 | 
			
		||||
                            .expect("Dimension is somehow negative?")
 | 
			
		||||
                            + 1;
 | 
			
		||||
                        let source_diff_i = ((il_source.0.abs() as u8) * u8::abs_diff(s1.0, s2.0))
 | 
			
		||||
                            .checked_sub(il_source.0.abs() as u8 - 1)
 | 
			
		||||
                            .expect("Dimension is somehow negative?")
 | 
			
		||||
                            + 1;
 | 
			
		||||
                        let source_diff_j = ((il_source.1.abs() as u8) * u8::abs_diff(s1.1, s2.1))
 | 
			
		||||
                            .checked_sub(il_source.1.abs() as u8 - 1)
 | 
			
		||||
                            .expect("Dimension is somehow negative?")
 | 
			
		||||
                            + 1;
 | 
			
		||||
 | 
			
		||||
                        if dest_diff_i % source_diff_i != 0 {
 | 
			
		||||
                            eprintln!("{} {}", source_diff_i, dest_diff_i);
 | 
			
		||||
                            return Err("Replicate region has indivisible height!")
 | 
			
		||||
                            return Err("Replicate region has indivisible height!");
 | 
			
		||||
                        }
 | 
			
		||||
                        if dest_diff_j % source_diff_j != 0 {
 | 
			
		||||
                            eprintln!("{} {}", source_diff_j, source_diff_j);
 | 
			
		||||
                            return Err("Replicate region has indivisible width!")
 | 
			
		||||
                            return Err("Replicate region has indivisible width!");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -211,55 +243,54 @@ impl TransferRegion<'_> {
 | 
			
		|||
 | 
			
		||||
        if let Some(source_il) = self.interleave_source {
 | 
			
		||||
            if source_il.0 == 0 || source_il.1 == 0 {
 | 
			
		||||
                return Err("Source interleave cannot be zero!")
 | 
			
		||||
                return Err("Source interleave cannot be zero!");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // Check if all destination wells exist:
 | 
			
		||||
        // NOT IMPLEMENTED
 | 
			
		||||
        // Should *not* happen in this function---otherwise
 | 
			
		||||
        // we'd get a nasty recursive loop.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return Ok(())
 | 
			
		||||
        return Ok(());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn in_region(pt: (u8,u8), r: &Region) -> bool {
 | 
			
		||||
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
 | 
			
		||||
                && 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,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn create_dense_rectangle(c1: &(u8,u8), c2: &(u8,u8)) -> Vec<(u8,u8)> {
 | 
			
		||||
fn create_dense_rectangle(c1: &(u8, u8), c2: &(u8, u8)) -> Vec<(u8, u8)> {
 | 
			
		||||
    // Creates a vector of every point between two corners
 | 
			
		||||
    let (c1, c2) = standardize_rectangle(c1, c2);
 | 
			
		||||
 | 
			
		||||
    let mut points = Vec::<(u8,u8)>::new();
 | 
			
		||||
    let mut points = Vec::<(u8, u8)>::new();
 | 
			
		||||
    for i in c1.0..=c2.0 {
 | 
			
		||||
        for j in c1.1..=c2.1 {
 | 
			
		||||
            points.push((i,j));
 | 
			
		||||
            points.push((i, j));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return points;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn standardize_rectangle(c1: &(u8,u8), c2: &(u8,u8)) -> ((u8,u8),(u8,u8)) {
 | 
			
		||||
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));
 | 
			
		||||
    return (
 | 
			
		||||
        (upper_left_i, upper_left_j),
 | 
			
		||||
        (bottom_right_i, bottom_right_j),
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(debug_assertions)]
 | 
			
		||||
| 
						 | 
				
			
			@ -275,7 +306,7 @@ impl fmt::Display for TransferRegion<'_> {
 | 
			
		|||
        let mut source_string = String::new();
 | 
			
		||||
        for i in 1..=source_dims.0 {
 | 
			
		||||
            for j in 1..=source_dims.1 {
 | 
			
		||||
                if source_wells.contains(&(i,j)) {
 | 
			
		||||
                if source_wells.contains(&(i, j)) {
 | 
			
		||||
                    source_string.push_str("x")
 | 
			
		||||
                } else {
 | 
			
		||||
                    source_string.push_str(".")
 | 
			
		||||
| 
						 | 
				
			
			@ -291,7 +322,7 @@ impl fmt::Display for TransferRegion<'_> {
 | 
			
		|||
        let mut dest_string = String::new();
 | 
			
		||||
        for i in 1..=dest_dims.0 {
 | 
			
		||||
            for j in 1..=dest_dims.1 {
 | 
			
		||||
                if dest_wells.contains(&(i,j)) {
 | 
			
		||||
                if dest_wells.contains(&(i, j)) {
 | 
			
		||||
                    dest_string.push_str("x")
 | 
			
		||||
                } else {
 | 
			
		||||
                    dest_string.push_str(".")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								src/lib.rs
								
								
								
								
							
							
						
						
									
										11
									
								
								src/lib.rs
								
								
								
								
							| 
						 | 
				
			
			@ -22,17 +22,16 @@ 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 destination = plate::Plate::new(plate::PlateType::Destination, plate::PlateFormat::W384);
 | 
			
		||||
 | 
			
		||||
    let transfer = transfer_region::TransferRegion {
 | 
			
		||||
        source_plate: &source,
 | 
			
		||||
        source_region: transfer_region::Region::Rect((1,1), (6,6)),
 | 
			
		||||
        source_region: transfer_region::Region::Rect((1, 1), (5, 1)),
 | 
			
		||||
        dest_plate: &destination,
 | 
			
		||||
        dest_region: transfer_region::Region::Point((2,2)),
 | 
			
		||||
        dest_region: transfer_region::Region::Rect((1, 1), (10, 4)),
 | 
			
		||||
        //dest_region: transfer_region::Region::Point((3,3)),
 | 
			
		||||
        interleave_source: None,
 | 
			
		||||
        interleave_dest: None
 | 
			
		||||
        interleave_dest: Some((1, 2)),
 | 
			
		||||
    };
 | 
			
		||||
    println!("{}", transfer);
 | 
			
		||||
    println!("{:?}", transfer.get_source_wells());
 | 
			
		||||
    println!("{:?}", transfer.get_destination_wells());
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
use plate_tool::App;
 | 
			
		||||
use plate_tool::plate_test;
 | 
			
		||||
use plate_tool::App;
 | 
			
		||||
use wasm_logger;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
//    wasm_logger::init(wasm_logger::Config::default());
 | 
			
		||||
//    dioxus_web::launch(App);
 | 
			
		||||
    //    wasm_logger::init(wasm_logger::Config::default());
 | 
			
		||||
    //    dioxus_web::launch(App);
 | 
			
		||||
    plate_test();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue