Open DrLachie opened 2 weeks ago
Thanks, this is a helpful description.
Pradeep's existing code for checking this is in the repo here: https://github.com/BioimageAnalysisCoreWEHI/napari_lattice/blob/f2c4824e38880b964de3312bcefe658525acea01/core/lls_core/models/lattice_data.py#L332-L348
However, I need some guidance on when to use it. Conceptually it would be great as a pydantic validation, but that isn't a good idea if it's compute intensive. If it is, then maybe it could become part of the .compute()
method.
Ahh, I think there is a logic error in the code..
volume.shape
and raw_vol.shape
are the same thing.
So, its not running any padding..
I think if the latticedata has a variable that stores the shape of the first image slice (i.e, time=0 and ch=0), we can then access that here to verify.
We will have to check shape after compute though.. as its possible that as a dask array it may store a different shape.
Well after the other validators have run, we're guaranteed to have it as an xarray. I think I can pull out the first and last slice without loading anything else from disk. It depends how "first" and "last" are defined though: which channel, for instance?
Actually, is this function (check_incomplete_acquisition) being accessed anywhere?
It depends how "first" and "last" are defined though: which channel, for instance?
first would be time 0 and channel 0
last could be max timepoint and max channel for now.
No, the function is currently unused.
Ahh, ok.
So, we need to run this when processing
Essentially, this function will
Is it easy to implement this only for last timepoint in save_image functions? OR would it be easier and computationally inexpensive to run this for all timepoints/channels, i.e., compare the shape of each array to original image. We compute the final array anyway in the save image functions.
Correct me if I'm wrong but that function computes the entire raw (non-deskewed/processed) volume? I just gave this a shot and it's computationally expensive. A simpler check is just to attempt to compute the final timepoint of the raw, this raises a value error if it's an incomplete acquisition.
My proposal is to run this test when first accessing the image (which I believe happens in lls_core.models.deskew.read_image, if the value error is raised, then log an error and redefine the raw data omitting the final timepoint. Testing this now
Correct me if I'm wrong but that function computes the entire raw (non-deskewed/processed) volume? I just gave this a shot and it's computationally expensive. A simpler check is just to attempt to compute the final timepoint of the raw, this raises a value error if it's an incomplete acquisition.
You are right it does, but I'm thinking we put this function while processing the data, i.e., when running the saving/workflow processing..
def check_incomplete_acquisition(self, raw_volume: ArrayLike, original_shape: tuple, time_point: int, channel: int):
"""
Checks for a slice with incomplete data, caused by incomplete acquisition
"""
if raw_volume.shape != original_shape:
logger.warn(f"Time {time_point}, channel {channel} is incomplete. Actual shape {original_shape}, got {raw_volume.shape}")
z_diff, y_diff, x_diff = np.subtract(original_shape, raw_volume.shape)
logger.info(f"Padding with{z_diff,y_diff,x_diff}")
raw_volume= np.pad(raw_volume, ((0, z_diff), (0, y_diff), (0, x_diff)))
if raw_volume.shape != original_shape:
raise Exception(f"Shape of last timepoint still doesn't match. Got { raw_volume.shape}")
return raw_volume
I don't think this will be computationaly expensive as its just checking the shape. The added advantage is if there are any other acquisition issues in any frame (not only last timepoint), we can catch that as well.
Your idea works too, but we are omitting the last frame from processing as a solution.
I think it's unlikely there's an issue (of this type) in anything but the last frame, and if there is it's probably a more pressing one that should be dealt with differently.
I like the idea of running the test up front as it at least throws the error/warning immediately. The problem I was having with debugging is everything looked like it was working unitl the final timepoint and then failed.
My inelegant (but working) solution is here: https://github.com/BioimageAnalysisCoreWEHI/napari_lattice/blob/317eb5a91ac30cf21b09a40d3e94bae5416b3c12/core/lls_core/models/deskew.py#L196
Could you create a pull request for this?
Often (relatively) a user will stop an acquisition mid frame, this results in the final timepoing being incomplete. If we draw rois and are decvonvolving (I haven't tested just cropping yet) we get three cases. 1) Final roi frame is filled with signal - decon works 2) Final roi frame is empty - fails with ValueError here: https://github.com/BioimageAnalysisCoreWEHI/napari_lattice/blob/f57b4895fe0479e4fb35cd78a68484dd24445c38/core/lls_core/deconvolution.py#L145 3) Final roi frame partially filled - fails with assertion error here: https://github.com/BioimageAnalysisCoreWEHI/napari_lattice/blob/f57b4895fe0479e4fb35cd78a68484dd24445c38/core/lls_core/deconvolution.py#L210
I think we have a few options for dealing with this:
I think my preference would be number 2