@@ -328,42 +328,66 @@ def resolve_matvec_and_shape(visu_pars,
328328 shape = np .asarray (visu_pars .get ("VisuCoreSize" ), dtype = float )
329329
330330 if dim == 2 :
331- num_rotates = rotate .shape [0 ]
332- num_origins = origin .shape [0 ]
333331 num_slicepack = len (num_slices )
334- if num_rotates != num_origins :
335- raise ValueError ("num_rotates != num_origins" )
336-
337- expected = int (num_slicepack * num_slices [spack_idx ])
338- if rotate .ndim == 2 and rotate .shape [1 ] == 9 and rotate .shape [0 ] > expected :
339- if not np .allclose (rotate , rotate [0 ], atol = 0 , rtol = 0 ):
340- logger .warning (
341- "VisuCoreOrientation has %s entries but expected %s; "
342- "using the first %s entry/entries." ,
343- rotate .shape [0 ],
344- expected ,
345- expected ,
346- )
347- if origin .ndim == 2 and origin .shape [1 ] == 3 and origin .shape [0 ] > expected :
348- if not np .allclose (origin , origin [0 ], atol = 0 , rtol = 0 ):
349- logger .warning (
350- "VisuCorePosition has %s entries but expected %s; "
351- "using the first %s entry/entries." ,
352- origin .shape [0 ],
353- expected ,
354- expected ,
355- )
356- if rotate .ndim == 2 and rotate .shape [1 ] == 9 and rotate .shape [0 ] >= expected :
357- rotate = rotate [:expected , :]
358- if origin .ndim == 2 and origin .shape [1 ] == 3 and origin .shape [0 ] >= expected :
359- origin = origin [:expected , :]
360- rotate = rotate .reshape ((num_slicepack , num_slices [spack_idx ], 9 ))
361- origin = origin .reshape ((num_slicepack , num_slices [spack_idx ], 3 ))
362- _rotate = rotate [spack_idx ]
363- _origin = origin [spack_idx ]
332+
333+ if spack_idx < 0 or spack_idx >= num_slicepack :
334+ raise IndexError (f"spack_idx out of range: { spack_idx } (num packs: { num_slicepack } )" )
335+
336+ total_slices = int (np .sum (np .asarray (num_slices , dtype = int )))
337+ spack_slice_start = int (np .sum (np .asarray (num_slices [:spack_idx ], dtype = int )))
338+ spack_slice_end = spack_slice_start + int (num_slices [spack_idx ])
339+
340+ def _select_slice_entries (arr : np .ndarray , * , width : int , name : str ) -> np .ndarray :
341+ arr = np .asarray (arr , dtype = float )
342+ if arr .ndim == 1 :
343+ if arr .size == width :
344+ arr = arr .reshape ((1 , width ))
345+ else :
346+ raise ValueError (f"{ name } has shape { arr .shape } , expected (*, { width } )" )
347+ if arr .ndim != 2 or arr .shape [1 ] != width :
348+ raise ValueError (f"{ name } has shape { arr .shape } , expected (*, { width } )" )
349+
350+ # Prefer per-slice entries (concatenated across slice packs).
351+ if arr .shape [0 ] > total_slices :
352+ if not np .allclose (arr [:total_slices ], arr [0 ], atol = 0 , rtol = 0 ):
353+ logger .warning (
354+ "%s has %s entries but expected %s; using the first %s entries." ,
355+ name ,
356+ arr .shape [0 ],
357+ total_slices ,
358+ total_slices ,
359+ )
360+ arr = arr [:total_slices , :]
361+
362+ if arr .shape [0 ] == total_slices :
363+ return arr [spack_slice_start :spack_slice_end , :]
364+
365+ # Fallback: per-pack entries (one entry per slice pack).
366+ if arr .shape [0 ] == num_slicepack :
367+ if int (num_slices [spack_idx ]) != 1 :
368+ raise ValueError (
369+ f"{ name } provides one entry per slice pack ({ num_slicepack } ) "
370+ f"but pack { spack_idx } has { num_slices [spack_idx ]} slices; "
371+ "per-slice entries are required to resolve slice positions."
372+ )
373+ return arr [spack_idx :spack_idx + 1 , :]
374+
375+ raise ValueError (
376+ f"{ name } has { arr .shape [0 ]} entries, expected { total_slices } (per-slice) "
377+ f"or { num_slicepack } (per-pack); method num_slices={ num_slices } ."
378+ )
379+
380+ _rotate = _select_slice_entries (rotate , width = 9 , name = "VisuCoreOrientation" )
381+ _origin = _select_slice_entries (origin , width = 3 , name = "VisuCorePosition" )
364382 _num_slices = num_slices [spack_idx ]
365383 _slice_thickness = slice_thickness [spack_idx ]
366384
385+ if _rotate .shape [0 ] > 1 and not np .allclose (_rotate , _rotate [0 ], atol = 0 , rtol = 0 ):
386+ logger .warning (
387+ "VisuCoreOrientation varies across slices in pack %s; using the first slice orientation." ,
388+ spack_idx ,
389+ )
390+
367391 row = _rotate [0 , 0 :3 ]
368392 col = _rotate [0 , 3 :6 ]
369393 slc = _rotate [0 , 6 :9 ]
0 commit comments