@@ -230,8 +230,8 @@ export function initLayerStateFromSource(source: SourceData & { id: string }): L
230
230
lut : label . lut ,
231
231
} ) ) ,
232
232
transformSourceSelection : getTransformSourceSelectionFromLabels (
233
- source . labels . map ( ( label ) => label . loader [ 0 ] . labels ) ,
234
- source . loader [ 0 ] . labels ,
233
+ source . labels . map ( ( label ) => label . loader [ 0 ] ) ,
234
+ source . loader [ 0 ] ,
235
235
) ,
236
236
} ;
237
237
}
@@ -247,25 +247,44 @@ export function initLayerStateFromSource(source: SourceData & { id: string }): L
247
247
} ;
248
248
}
249
249
250
- function getTransformSourceSelectionFromLabels ( labelAxesNames : Array < Array < string > > , sourceAxesNames : Array < string > ) {
250
+ function getTransformSourceSelectionFromLabels (
251
+ labelsResolutions : Array < { shape : Array < number > ; labels : Array < string > } > ,
252
+ source : { shape : Array < number > ; labels : Array < string > } ,
253
+ ) {
254
+ // representative source for labels
255
+ const labelsSource = labelsResolutions [ 0 ] ;
251
256
utils . assert (
252
- labelAxesNames [ 0 ] . every ( ( name ) => sourceAxesNames . includes ( name ) ) ,
253
- ( ) =>
254
- `Label axes names be a subset of source. Source: ${ JSON . stringify ( sourceAxesNames ) } Labels: ${ JSON . stringify ( labelAxesNames ) } ` ,
257
+ source . shape . length === source . labels . length ,
258
+ `Image source axes and shape are not same rank. Got ${ JSON . stringify ( source ) } ` ,
255
259
) ;
256
- for ( const axes of labelAxesNames ) {
260
+ utils . assert (
261
+ labelsSource . shape . length === labelsSource . labels . length ,
262
+ `Label axes and shape are not same rank. Got ${ JSON . stringify ( labelsSource ) } ` ,
263
+ ) ;
264
+ utils . assert (
265
+ utils . zip ( labelsSource . labels , source . labels ) . every ( ( [ a , b ] ) => a === b ) ,
266
+ `Label axes MUST be a subset of source. Source: ${ JSON . stringify ( source . labels ) } Labels: ${ JSON . stringify ( labelsSource . labels ) } ` ,
267
+ ) ;
268
+ for ( const { labels, shape } of labelsResolutions . slice ( 1 ) ) {
257
269
utils . assert (
258
- axes . every ( ( name , i ) => name === labelAxesNames [ 0 ] [ i ] ) ,
259
- ( ) => {
260
- const mismatchedLabels = labelAxesNames . map ( ( axes ) => ( { axes } ) ) ;
261
- return `Error: All labels must share the same axes. Mismatched labels found: ${ JSON . stringify ( mismatchedLabels ) } ` ;
262
- } ,
270
+ utils . zip ( labels , labelsSource . labels ) . every ( ( [ a , b ] ) => a === b ) ,
271
+ `Error: All labels must share the same axes. Mismatched labels found: ${ JSON . stringify ( labels ) } ` ,
272
+ ) ;
273
+ utils . assert (
274
+ utils . zip ( shape , labelsSource . shape ) . every ( ( [ a , b ] ) => a === b ) ,
275
+ `Error: All labels must share the same shape. Mismatched labels found: ${ JSON . stringify ( shape ) } ` ,
263
276
) ;
264
277
}
278
+ // Identify labels that should always map to 0, regardless of the source selection.
279
+ const excludeFromTransformedSelection = new Set (
280
+ utils
281
+ . zip ( labelsSource . labels , labelsSource . shape )
282
+ . filter ( ( [ _ , size ] ) => size === 1 )
283
+ . map ( ( [ name , _ ] ) => name ) ,
284
+ ) ;
265
285
return ( sourceSelection : Array < number > ) : Array < number > => {
266
- return labelAxesNames [ 0 ] . map ( ( name ) => {
267
- if ( name === "c" ) return 0 ; // skip
268
- return sourceSelection [ sourceAxesNames . indexOf ( name ) ] ;
269
- } ) ;
286
+ return labelsSource . labels . map ( ( name ) =>
287
+ excludeFromTransformedSelection . has ( name ) ? 0 : sourceSelection [ source . labels . indexOf ( name ) ] ,
288
+ ) ;
270
289
} ;
271
290
}
0 commit comments