Conversation
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
| } | ||
|
|
||
| export function isScalarSelection(selection: string | undefined): boolean { | ||
| return selection !== undefined && /^\d+(?:,\d+)*$/u.test(selection); |
There was a problem hiding this comment.
I struggle to understand what you mean by "scalar selection".
Is it a selection that will produce a scalar value ? If so, the test should check also the dataset shape ?
Is it a selection that only has scalar values inside ? In that case, perhaps "selected indices" would be a better name ?
There was a problem hiding this comment.
It's a selection that produces a scalar value, like 2,0,1 or 3, as opposed to 2,0,: or :.
The dataset shape doesn't matter here: when we have a selection string, the dataset is expected to have an array shape (cf. assertDatasetValue). The selection string is also expected to have the same number of elements as the number of dimensions in the dataset.
The problem I'm facing (which is why I've switched the PR to draft) is that the Value type has to be aware of the selection so it can conditionally return ScalarValue for "scalar selections".
I've managed to make it work with:
type ValueSelection = (number | null)[];
type ScalarSelection = number[];
export type Value<
D extends Dataset,
V extends ValueSelection | undefined = undefined,
> =
D extends Dataset<infer S, infer T>
? S extends ScalarShape
? ScalarValue<T>
: S extends ArrayShape
? V extends ScalarSelection
? ScalarValue<T>
: ArrayValue<T>
: never
: never;It requires keeping the selection as an array for longer, which changes quite a few things.
I'm now trying to use the dimension mapping array directly instead of introducing a new structure. I'll keep you updated.
There was a problem hiding this comment.
It's a selection that produces a scalar value, like 2,0,1 or 3, as opposed to 2,0,: or :.
I see. The issue I had is that I am used to Python where you can do stuff like threeD[3] and get a 2D array. In essence, the 3 is a short hand for 3, :, :.
But since we enforce the same number of elements as the number of dimensions in the dataset, we should never have this.
f224ad4 to
193b553
Compare
d150840 to
769a09a
Compare
|
/approve |
|
I'm finally bringing this PR back to life, as I found a solution I like to the scalar selection problem. Sorry for the spam, it took a while to finalise... I've updated the PR description and deleted or hid all the outdated comments. Here's the deploy preview https://deploy-preview-1768--h5web.netlify.app/ |
loichuder
left a comment
There was a problem hiding this comment.
Yes, I think adding a new fetcher is the way to go.
We know ahead of time whether we want to fetch a scalar since we already have the selection and the number of dims of the dataset.
| h5wDataset: H5WasmDataset, | ||
| selection: string | undefined, | ||
| ): OutputData | null { | ||
| ): unknown { |
There was a problem hiding this comment.
Yes, the return type gets in the way a bit and DataProvider#getValue has return type unknown, so it "swallows" whichever return type we specify here. We assert the value after it's returned by the provider, so we don't need to assert it more than strictly necessary inside this function.
| const { dims } = entity.shape; | ||
| const [dimMapping, setDimMapping] = useDimMappingState({ | ||
| dims, | ||
| axesCount: 0, // slicing only |
There was a problem hiding this comment.
It says that the visualization doesn't have any "axes" and therefore that every dimension needs to be "sliced". The returned dimMapping is either an empty array if dims is empty (i.e. scalar dataset), or an array with as many zeros as there are dimensions in the array dataset.
This is why we are guaranteed to end up with either an undefined selection for scalar datasets, or a "scalar selection" for array datasets.
As a reminder, when
axesCountis 1,dimMappingincludes one'x', and whenaxesCountis 2,dimMappingincludes one'x'and one'y'. You can check out the unit tests ofinitDimMappingfor some examples.
This PR improves handling of array datasets by the Raw visualization. The idea is to visualize only one scalar slice at a time instead of the entire array, notably to support stacks of raw JPEG/PNG images.
It's the first of three steps. I'm planning to then:
This way we'll end up with a single Scalar vis fallback to visualize all scalar values (whether from a scalar dataset or from a scalar slice of an array dataset).
The main challenge was dealing with "scalar selections". I'm talking about
selectionstrings of the form[0-9](,[0-9])*(e.g."2","0,1","2,0,4", etc.) This was previously discussed here.The first problem came from the providers. h5grove handles these scalar selections as expected — i.e. it returns a scalar value — but h5wasm and HSDS have quirks:
The second problem came from our
Value<D extends HasShape & HasType>type, which is not aware of "scalar selections" — i.e. if you give it a dataset with an array shape as parameter, it returns anArrayValuetype, full stop. So theValueFetchercomponent,useValuehook andassertValueguard would either lie or fail when encountering scalar slices taken from array datasets.For a while, I considered making
Value<D>,ValueFetcher,useValueandassertValueaware of selections but this made everything way more complicated and messy. Instead, I ended up creating aScalarFetchercomponent that handles this case specifically inRawVisContainerwithout affecting any of the types, hooks and guards.I've updated
sample.h5(demos: h5grove, h5wasm) by mergingcompound_nested_scalarandcompound_array_vlen_1Dinto a more comprehensivecompound_mixed_1Ddataset that demonstrates everything at once (vlen/array dtypes + nested compound with int64 and complex fields).I've updated the mock file with a similar
oneD_compound_mixeddataset, as well as with multiple opaque datasets:oneD_opaque,oneD_opaque_png, andtwoD_opaque.The mock
oneD_opaque_pngdataset demonstrates how the new Array vis handles stacks of PNG images, but you can also try it withfrogs.h5: