Skip to content

Commit fa73f8f

Browse files
committed
feat: add alphabetical sorting for auto-layered files
Sort matching layers and segment groups alphabetically by filename to provide deterministic ordering. Users can control stacking order using numeric prefixes in filenames (e.g., file.layer.1.nii, file.layer.2.nii). Updated documentation to clarify naming patterns and show that file formats don't need to match between base image and associated files.
1 parent 09716a1 commit fa73f8f

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed

docs/configuration_file.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,24 @@ hdf5, iwi.cbor, mha, nii, nii.gz, nrrd, vtk
184184
## Automatic Layers and Segment Groups by File Name
185185

186186
When loading multiple files, VolView can automatically associate related images based on file naming patterns.
187-
Files matching `base.[extension].format` will be associated with a base image named `base.format`.
187+
Example: `base.[extension].nrrd` will match `base.nii`.
188+
189+
The extension must appear anywhere in the filename after splitting by dots, and the filename must start with the same prefix as the base image (everything before the first dot). Files matching `base.[extension]...` will be associated with a base image named `base.*`.
190+
191+
**Ordering:** When multiple layers/segment groups match a base image, they are sorted alphabetically by filename and added to the stack in that order. To control the stacking order explicitly, you could use numeric prefixes in your filenames.
192+
193+
For example, with a base image `patient001.nrrd`:
194+
195+
- Layers (sorted alphabetically): `patient001.layer.1.pet.nii`, `patient001.layer.2.ct.mha`, `patient001.layer.3.overlay.vtk`
196+
- Segment groups: `patient001.seg.1.tumor.nii.gz`, `patient001.seg.2.lesion.mha`
197+
188198
Both features default to `''` which disables them.
189199

190200
### Segment Groups
191201

192-
Use `segmentGroupExtension` to automatically convert matching non-DICOM images to segment groups. For example, `myFile.seg.nrrd` becomes a segment group for `myFile.nii`:
202+
Use `segmentGroupExtension` to automatically convert matching non-DICOM images to segment groups.
203+
For example, `myFile.seg.nrrd` becomes a segment group for `myFile.nii`.
204+
Defaults to `''` which disables matching.
193205

194206
```json
195207
{
@@ -201,7 +213,8 @@ Use `segmentGroupExtension` to automatically convert matching non-DICOM images t
201213

202214
### Layering
203215

204-
Use `layerExtension` to automatically layer matching non-DICOM images on top of the base image. For example, `myImage.layer.nii` is layered on top of `myImage.nii`:
216+
Use `layerExtension` to automatically layer matching non-DICOM images on top of the base image. For example, `myImage.layer.nii` is layered on top of `myImage.nii`.
217+
Defaults to `''` which disables matching.
205218

206219
```json
207220
{

src/actions/loadUserFiles.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ function isSegmentation(extension: string, name: string) {
8080
return extensions.includes(extension);
8181
}
8282

83+
function sortByDataSourceName(a: LoadableResult, b: LoadableResult) {
84+
const nameA = getDataSourceName(a.dataSource) ?? '';
85+
const nameB = getDataSourceName(b.dataSource) ?? '';
86+
return nameA.localeCompare(nameB);
87+
}
88+
8389
// does not pick segmentation or layer images
8490
function findBaseImage(
8591
loadableDataSources: Array<LoadableResult>,
@@ -209,7 +215,9 @@ function autoLayerByName(
209215
primaryDataSource,
210216
succeeded,
211217
layerExtension
212-
).filter(isVolumeResult);
218+
)
219+
.filter(isVolumeResult)
220+
.sort(sortByDataSourceName);
213221

214222
const primarySelection = toDataSelection(primaryDataSource);
215223
const layersStore = useLayersStore();
@@ -231,9 +239,11 @@ function loadSegmentations(
231239
primaryDataSource,
232240
succeeded,
233241
segmentGroupExtension
234-
).filter(
235-
isVolumeResult // filter out models
236-
);
242+
)
243+
.filter(
244+
isVolumeResult // filter out models
245+
)
246+
.sort(sortByDataSourceName);
237247

238248
const dicomStore = useDICOMStore();
239249
const otherSegVolumesInStudy = filterOtherVolumesInStudy(

0 commit comments

Comments
 (0)