@@ -6,6 +6,8 @@ export type H5adData = {
66 statements : { statement_id : string ; txt : string ; moderated : number } [ ] ;
77 votesRows : { participant_id : string ; comment_id : string ; vote : number } [ ] ;
88 availableEmbeddings : string [ ] ;
9+ /** All 2D embeddings keyed by pipeline-style ID (X_ prefix stripped) */
10+ allEmbeddings : Record < string , [ string , [ number , number ] ] [ ] > ;
911} ;
1012
1113/**
@@ -148,35 +150,47 @@ export async function loadH5adFile(
148150 if ( ! obsGroup ) throw new Error ( 'Missing /obs group' ) ;
149151 const obsNames = readIndex ( obsGroup ) ;
150152
151- // --- Read embedding coordinates ---
153+ // --- Read embedding coordinates for all available embeddings ---
152154 const obsmGroup = file . get ( 'obsm' ) as Group ;
153155 if ( ! obsmGroup ) throw new Error ( 'Missing /obsm group' ) ;
154- const embeddingDs = obsmGroup . get ( selectedEmbedding ) as Dataset | null ;
155- if ( ! embeddingDs ) throw new Error ( `Embedding "${ selectedEmbedding } " not found in /obsm` ) ;
156156
157- const shape = embeddingDs . shape ;
158- if ( ! shape || shape . length !== 2 ) {
159- throw new Error ( `Embedding "${ selectedEmbedding } " has unexpected shape` ) ;
160- }
161- const nObs = shape [ 0 ] ;
162- const nDims = shape [ 1 ] ;
163-
164- // Read the flat typed array and reshape to [n_obs, 2]
165- const rawValue = embeddingDs . value ;
166- let flatCoords : number [ ] ;
167- if ( ArrayBuffer . isView ( rawValue ) ) {
168- flatCoords = Array . from ( rawValue as Float64Array | Float32Array ) ;
169- } else if ( Array . isArray ( rawValue ) ) {
170- flatCoords = ( rawValue as number [ ] [ ] ) . flat ( ) ;
171- } else {
172- throw new Error ( `Unexpected embedding data format` ) ;
157+ const allEmbeddings : Record < string , [ string , [ number , number ] ] [ ] > = { } ;
158+ for ( const embKey of availableEmbeddings ) {
159+ const ds = obsmGroup . get ( embKey ) as Dataset | null ;
160+ if ( ! ds ) continue ;
161+
162+ const shape = ds . shape ;
163+ if ( ! shape || shape . length !== 2 ) continue ;
164+ const nObs = shape [ 0 ] ;
165+ const nDims = shape [ 1 ] ;
166+
167+ const rawValue = ds . value ;
168+ let flatCoords : number [ ] ;
169+ if ( ArrayBuffer . isView ( rawValue ) ) {
170+ flatCoords = Array . from ( rawValue as Float64Array | Float32Array ) ;
171+ } else if ( Array . isArray ( rawValue ) ) {
172+ flatCoords = ( rawValue as number [ ] [ ] ) . flat ( ) ;
173+ } else {
174+ continue ;
175+ }
176+
177+ const embDataset : [ string , [ number , number ] ] [ ] = [ ] ;
178+ for ( let i = 0 ; i < nObs ; i ++ ) {
179+ const x = flatCoords [ i * nDims ] ;
180+ const y = flatCoords [ i * nDims + 1 ] ;
181+ embDataset . push ( [ obsNames [ i ] , [ x , y ] ] ) ;
182+ }
183+
184+ // Strip X_ prefix for pipeline-style IDs
185+ const pipelineId = embKey . replace ( / ^ X _ / , '' ) ;
186+ allEmbeddings [ pipelineId ] = embDataset ;
173187 }
174188
175- const dataset : [ string , [ number , number ] ] [ ] = [ ] ;
176- for ( let i = 0 ; i < nObs ; i ++ ) {
177- const x = flatCoords [ i * nDims ] ;
178- const y = flatCoords [ i * nDims + 1 ] ;
179- dataset . push ( [ obsNames [ i ] , [ x , y ] ] ) ;
189+ // Use the selected embedding as the default dataset
190+ const pipelineId = selectedEmbedding . replace ( / ^ X _ / , '' ) ;
191+ const dataset = allEmbeddings [ pipelineId ] ;
192+ if ( ! dataset ) {
193+ throw new Error ( `Embedding " ${ selectedEmbedding } " could not be read from /obsm` ) ;
180194 }
181195
182196 // --- Read statements (var) ---
@@ -224,7 +238,7 @@ export async function loadH5adFile(
224238 // --- Read votes from uns/votes ---
225239 const votesRows = readVotes ( file ) ;
226240
227- return { dataset, statements, votesRows, availableEmbeddings } ;
241+ return { dataset, statements, votesRows, availableEmbeddings, allEmbeddings } ;
228242 } finally {
229243 if ( file ) {
230244 file . close ( ) ;
0 commit comments