lib fix: do not permit out-of-plate destinations
This commit is contained in:
parent
2ea2963b22
commit
619f9594cf
|
@ -250,24 +250,39 @@ impl TransferRegion {
|
||||||
|
|
||||||
// Non-replicate transfers:
|
// Non-replicate transfers:
|
||||||
match &self.dest_region {
|
match &self.dest_region {
|
||||||
Region::Point(Well { row: x, col: y }) => {
|
Region::Point(dest_point) => {
|
||||||
Box::new(move |Well { row: i, col: j }| {
|
// Breaking from form somewhat, we really should return an entirely different
|
||||||
if source_wells.contains(&Well { row: i, col: j }) {
|
// function if a point-dest can't fit the whole source.
|
||||||
|
// If the bottom-right well of the source won't fit in the dest,
|
||||||
|
// we can abort.
|
||||||
|
let source_bottom_right = match self.source_region {
|
||||||
|
Region::Point(x) => x,
|
||||||
|
Region::Rect(w1, w2) => standardize_rectangle(&w1, &w2).1,
|
||||||
|
Region::Custom(_) => unreachable!("A point destination region cannot be paired with a custom source destination?"),
|
||||||
|
};
|
||||||
|
let bottom_right_mapped = Self::point_destination_region_calc(
|
||||||
|
source_bottom_right,
|
||||||
|
source_ul,
|
||||||
|
il_source,
|
||||||
|
il_dest,
|
||||||
|
*dest_point,
|
||||||
|
);
|
||||||
|
if bottom_right_mapped.row > self.dest_plate.plate_format.rows()
|
||||||
|
|| bottom_right_mapped.col > self.dest_plate.plate_format.columns()
|
||||||
|
{
|
||||||
|
return Box::new(|_| None);
|
||||||
|
}
|
||||||
|
|
||||||
|
Box::new(move |input| {
|
||||||
|
if source_wells.contains(&input) {
|
||||||
// Validity here already checked by self.validate()
|
// Validity here already checked by self.validate()
|
||||||
Some(vec![Well {
|
Some(vec![Self::point_destination_region_calc(
|
||||||
row: x + i
|
input,
|
||||||
.checked_sub(source_ul.row)
|
source_ul,
|
||||||
.expect("Point cannot have been less than UL")
|
il_source,
|
||||||
.checked_div(il_source.0.unsigned_abs())
|
il_dest,
|
||||||
.expect("Source interleave cannot be 0")
|
*dest_point,
|
||||||
.mul(il_dest.0.unsigned_abs()),
|
)])
|
||||||
col: y + j
|
|
||||||
.checked_sub(source_ul.col)
|
|
||||||
.expect("Point cannot have been less than UL")
|
|
||||||
.checked_div(il_source.1.unsigned_abs())
|
|
||||||
.expect("Source interleave cannot be 0")
|
|
||||||
.mul(il_dest.1.unsigned_abs()),
|
|
||||||
}])
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -387,6 +402,33 @@ impl TransferRegion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn point_destination_region_calc(
|
||||||
|
input: Well,
|
||||||
|
source_ul: Well,
|
||||||
|
il_source: (i8, i8),
|
||||||
|
il_dest: (i8, i8),
|
||||||
|
dest_point: Well,
|
||||||
|
) -> Well {
|
||||||
|
Well {
|
||||||
|
row: dest_point.row
|
||||||
|
+ input
|
||||||
|
.row
|
||||||
|
.checked_sub(source_ul.row)
|
||||||
|
.expect("Point cannot have been less than UL")
|
||||||
|
.checked_div(il_source.0.unsigned_abs())
|
||||||
|
.expect("Source interleave cannot be 0")
|
||||||
|
.mul(il_dest.0.unsigned_abs()),
|
||||||
|
col: dest_point.col
|
||||||
|
+ input
|
||||||
|
.col
|
||||||
|
.checked_sub(source_ul.col)
|
||||||
|
.expect("Point cannot have been less than UL")
|
||||||
|
.checked_div(il_source.1.unsigned_abs())
|
||||||
|
.expect("Source interleave cannot be 0")
|
||||||
|
.mul(il_dest.1.unsigned_abs()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn validate(&self) -> Result<(), &'static str> {
|
pub fn validate(&self) -> Result<(), &'static str> {
|
||||||
// Checks if the region does anything suspect
|
// Checks if the region does anything suspect
|
||||||
//
|
//
|
||||||
|
@ -400,6 +442,12 @@ impl TransferRegion {
|
||||||
let il_dest = self.interleave_dest;
|
let il_dest = self.interleave_dest;
|
||||||
|
|
||||||
match self.source_region {
|
match self.source_region {
|
||||||
|
/*
|
||||||
|
* Note 04Jan2025:
|
||||||
|
* I genuinely cannot think of a reason why we should need to validate a source
|
||||||
|
* point region???
|
||||||
|
* Like, why would it *not* be in the plate?
|
||||||
|
*/
|
||||||
Region::Point(_) => return Ok(()), // Should make sure it's actually in the plate, leave for
|
Region::Point(_) => return Ok(()), // Should make sure it's actually in the plate, leave for
|
||||||
// later
|
// later
|
||||||
Region::Rect(s1, s2) => {
|
Region::Rect(s1, s2) => {
|
||||||
|
|
Loading…
Reference in New Issue