Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolves #865 #868

Merged
merged 2 commits into from
Oct 18, 2024
Merged

Resolves #865 #868

merged 2 commits into from
Oct 18, 2024

Conversation

k1o0
Copy link
Contributor

@k1o0 k1o0 commented Oct 17, 2024

I've refactored the function and added the following test:

exptQC = [
    {'frameQC_names': np.array(['ok', 'PMT off', 'galvos fault', 'high signal'], dtype=object),
     'frameQC_frames': np.array([0, 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4])},
    {'frameQC_names': np.array(['ok', 'PMT off', 'foo', 'galvos fault', np.array([])], dtype=object),
     'frameQC_frames': np.array([0, 0, 1, 1, 2, 2, 2, 2, 3, 4])},
    {'frameQC_names': 'ok',  # check with single str instead of array
     'frameQC_frames': np.array([0, 0])}
]

This will produce a new enumeration that looks like this:

   qc_values     qc_labels
0          0            ok
1          1       PMT off
2          2  galvos fault
3          3   high signal
4          4           foo
5          5       unknown

So the behaviour is this:

  • ok is always 0, the other values are purely determined by the order of frameQC names first encountered;
  • if values correspond to different names across bouts this will not result in an error
  • all values that don't correspond to a label will be assigned the 'unknown' label
  • an empty str or empty array will be assigned the same 'unknown' label instead of raising
  • if names is simply an 'ok' str (instead of an array) this is handled as usual

@k1o0 k1o0 requested a review from samupicard October 17, 2024 13:19
Copy link
Member

@samupicard samupicard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the intended behavior of _consolidate_exptQC looks good to me! Thanks for adding a test as well. Just have a separate comment about the bad_frames

qc_labels.append('unknown')
frame_qc[missing_name] = i
frame_qc = frame_qc.astype(np.uint32) # case to uint
bad_frames, = np.where(frame_qc != 0)
Copy link
Member

@samupicard samupicard Oct 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the frames that should be excluded from suite2p cell detection are not necessarily all frame_qc != 0. E.g. 'PMT off' or 'galvos fault' will mean those frames need to be excluded, but e.g. 'adjust spout' will not. However, this doesn't need to be figured out here - the acquirer will have written a separate badframes.mat vector specifying which frames suite2p should be excluding from analysis. So probably best to not try to impute the bad_frames variable here at all, and instead load it from disk?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if loaded from disk, this badframes array will also need to be consolidated (the indexing of the badframes.mat vectors is relative to each bout)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can confirm that the bad_frames var returned by this method is not at all used. The badframes.mat files are loaded afterward, and there is an assertion that all badframes indices are a subset of the non-zero frameQC indices:

# If applicable, save as bad_frames.npy in first raw_imaging_folder for suite2p
# badframes.mat contains QC values that do affect ROI detection (e.g. no PMT, lens artefacts)
badframes = np.array([], dtype='i8')
total_frames = 0
# Ensure all indices are relative to total cumulative frames
for m, collection in zip(all_meta, raw_image_collections):
badframes_path = self.session_path.joinpath(collection, 'badframes.mat')
if badframes_path.exists():
raw_mat = loadmat(badframes_path, squeeze_me=True, simplify_cells=True)['badframes']
badframes = np.r_[badframes, raw_mat + total_frames]
total_frames += m['nFrames']
if len(badframes) > 0 and use_badframes is True:
# The badframes array should always be a subset of the frameQC array
assert np.max(badframes) < frameQC.size and np.all(frameQC[badframes])
np.save(raw_image_collections[0].joinpath('bad_frames.npy'), badframes)

@k1o0 k1o0 merged commit 62d76fa into develop Oct 18, 2024
6 checks passed
@k1o0 k1o0 deleted the consolidateExptQC branch October 18, 2024 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants