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

fix: Track channel load status individually #344

Merged
merged 2 commits into from
Dec 18, 2024

Conversation

ShrimpCryptid
Copy link
Contributor

@ShrimpCryptid ShrimpCryptid commented Dec 17, 2024

Problem

Fixes #342, "Volumes that are initially disabled are remapped incorrectly when enabled."

The issue seemed to be caused by the initialLoadRef only allowing normal initialization of channels for enabled channels were loaded for the first time. Channels that were initially disabled, but then enabled later, would have the initial default ramps or control points remapped to incorrect values.

This change fixes the issue by changing initialLoadRef to be a boolean array, and the loaded status of each channel is tracked individually. This way, the normal initialization can occur even when a channel is loaded later.

From testing it seems like the bug was introduced in #338, but I can't tell exactly what changes to the viewer would have broken this behavior.

Estimated review size: tiny, <5 minutes

Solution

  • Channel load status is now tracked using channelLoadedRef, and checks for initial load are performed against it.
    • This allows channel LUTs to be initialized for channels that are initially disabled and later reenabled.

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)

Steps to Verify:

  1. Open this URL: http://localhost:9020/viewer?url=https%3A%2F%2Fallencell.s3.amazonaws.com%2Faics%2Femt_timelapse_dataset%2Fdata%2F3500005829_4_raw_converted.ome.zarr&mode=maxproject&c0=cps:0:0:1:108:0:1:127:1:1:255:1:1,rmp:108:127&c1=ven:1,col:ffffff,cps:0:0:1:30:0:1:42:1:1:255:1:1,rmp:30:65.495&c2=col:bd10e0,cps:0:0:1:13:0:1:21:1:1:255:1:1,rmp:13:21
  2. Enable the Brightfield channel. It should have the expected range of 108, 127.

Screenshots (optional):

image

Copy link

github-actions bot commented Dec 17, 2024

PR Preview Action v1.4.8
Preview removed because the pull request was closed.
2024-12-18 00:12 UTC

@ShrimpCryptid ShrimpCryptid self-assigned this Dec 17, 2024
@ShrimpCryptid ShrimpCryptid added the bug Something isn't working label Dec 17, 2024
@ShrimpCryptid ShrimpCryptid marked this pull request as ready for review December 17, 2024 21:54
@ShrimpCryptid ShrimpCryptid requested a review from a team as a code owner December 17, 2024 21:54
Copy link
Contributor

@toloudis toloudis left a comment

Choose a reason for hiding this comment

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

Very clean! Ship it!

Copy link
Contributor

@frasercl frasercl left a comment

Choose a reason for hiding this comment

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

Thinking out loud here: I wonder if, in the spirit of not duplicating state, hasChannelLoadedRef should be merged with channelVersions below now that it's also responsible for tracking per-channel load states? e.g. an initial load would be version -1? I'm okay letting this fix in as-is but might return to this in the future

@ShrimpCryptid
Copy link
Contributor Author

ShrimpCryptid commented Dec 17, 2024

Thinking out loud here: I wonder if, in the spirit of not duplicating state, hasChannelLoadedRef should be merged with channelVersions below now that it's also responsible for tracking per-channel load states? e.g. an initial load would be version -1? I'm okay letting this fix in as-is but might return to this in the future

I tested this and it seems to work great! I think it's initialized to version 0 by default which I can test against. Are there any concerns with not using a ref value?

Edit: channelVersions is backed by a ref, so this won't cause any issues :)

@@ -232,7 +232,7 @@ const App: React.FC<AppProps> = (props) => {
};

const setAllChannelsUnloaded = (numberOfChannels: number): void => {
setChannelVersions(new Array(numberOfChannels).fill(0));
setChannelVersions(new Array(numberOfChannels).fill(INITIAL_CHANNEL_VERSION));
};

const setOneChannelLoaded = (index: number): void => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Channel versions are incremented once they're loaded once!

Copy link
Contributor

@frasercl frasercl Dec 17, 2024

Choose a reason for hiding this comment

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

Looks like channel transfer functions are now getting recomputed rather than remapped on initial load. This is why I suggested -1 for INITIAL_CHANNEL_VERSION initially. Though it does add some additional complexity: setOneChannelLoaded has to go from simply incrementing channel versions to something like Math.max(version + 1, 1), and we need two different versions of setAllChannelsUnloaded for when channels are unloaded due to an image switch vs. due to loading new data from the same image, where the second does something like setChannelVersions(getChannelVersions().map((version) => Math.min(version, 0)));.

Not sure whether the additional complexity is worth the unification; I'm leaning towards yes, but I'm on the fence. If so, the representation of channelVersions should definitely get a few lines of documentation. (And honestly, it should already have documentation - the current representation had me confused for a bit just now, and I wrote it. The rationale for representing loaded state as a number rather than a boolean is described all the way back in #156, though I'm not sure if it's still necessary given all the smarter loading behaviors we've added in the meantime.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved this to a new branch because of some complexity that was worth checking a little more thoroughly! It's now on refactor/remove-channel-loaded-ref.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm all for any change that both makes things work correctly and improves the readability, maintainability, and simplicity of the codebase. Do you really think we can get rid of the channelversions?

@ShrimpCryptid ShrimpCryptid force-pushed the fix/load-disabled-channels branch from c5cdbfe to e728061 Compare December 17, 2024 23:42
@ShrimpCryptid ShrimpCryptid merged commit 63d6dab into main Dec 18, 2024
8 checks passed
@ShrimpCryptid ShrimpCryptid deleted the fix/load-disabled-channels branch December 18, 2024 00:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Volumes that are initially disabled are remapped incorrectly when enabled
3 participants