Skip to content

Commit ef484fd

Browse files
committed
Fix sort default comparator
Allows avoiding showing spimdata in the tree (partially working)
1 parent 88dd41e commit ef484fd

File tree

2 files changed

+130
-76
lines changed

2 files changed

+130
-76
lines changed

src/main/java/sc/fiji/bdvpg/scijava/services/SourceAndConverterService.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,15 @@ else if (imageLoader instanceof N5ImageLoader) {
363363
*
364364
* @param asd spimdata object to register
365365
*/
366-
public synchronized void register(AbstractSpimData<?> asd) {
366+
public synchronized void register(AbstractSpimData<?> asd, String... options) {
367+
368+
boolean noTree = false;
369+
370+
for (String option: options) {
371+
if (option.equals("no tree")) {
372+
noTree = true;
373+
}
374+
}
367375

368376
if (spimdataToMetadata.getIfPresent(asd) == null) {
369377
Map<String, Object> sourceData = new HashMap<>();
@@ -495,10 +503,14 @@ else if (type instanceof ARGBType) {
495503
});
496504
}
497505

506+
boolean showUI = !noTree;
507+
498508
setupIdToSourceAndConverter.keySet().forEach(id -> {
499-
register(setupIdToSourceAndConverter.get(id));
509+
register(setupIdToSourceAndConverter.get(id), options);
500510
linkToSpimData(setupIdToSourceAndConverter.get(id), asd, id);
501-
ui.update(setupIdToSourceAndConverter.get(id));
511+
if (showUI) {
512+
ui.update(setupIdToSourceAndConverter.get(id));
513+
}
502514
});
503515

504516
WrapBasicImgLoader.removeWrapperIfPresent(asd);
@@ -517,8 +529,8 @@ else if (type instanceof ARGBType) {
517529
}
518530

519531
@Override
520-
public void register(AbstractSpimData<?> asd, String... options) {
521-
register(asd);
532+
public void register(AbstractSpimData<?> asd) {
533+
register(asd, "");
522534
}
523535

524536
private static String createSetupName(final BasicViewSetup setup) {

src/main/java/sc/fiji/bdvpg/sourceandconverter/SourceAndConverterHelper.java

Lines changed: 113 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,9 @@
6868
import java.util.ArrayList;
6969
import java.util.Arrays;
7070
import java.util.Collection;
71-
import java.util.Comparator;
71+
import java.util.HashMap;
7272
import java.util.List;
73+
import java.util.Map;
7374
import java.util.stream.Collectors;
7475

7576
/**
@@ -664,52 +665,90 @@ public static List<SourceAndConverter<?>> sortDefaultGeneric(
664665
List<SourceAndConverter<?>> sortedList = new ArrayList<>(sacs.size());
665666
sortedList.addAll(sacs);
666667

667-
Comparator<SourceAndConverter<?>> sacComparator = (s1, s2) -> {
668-
// Those who do not belong to spimdata are last:
669-
SourceAndConverterService.SpimDataInfo sdi1 = null, sdi2 = null;
670-
if (SourceAndConverterServices.getSourceAndConverterService().getMetadata(
671-
s1, SourceAndConverterService.SPIM_DATA_INFO) != null)
672-
{
673-
sdi1 =
674-
((SourceAndConverterService.SpimDataInfo) (SourceAndConverterServices
675-
.getSourceAndConverterService().getMetadata(s1,
676-
SourceAndConverterService.SPIM_DATA_INFO)));
677-
}
668+
// Build a map of asd objects to unique IDs for stable ordering
669+
final Map<Object, Integer> asdIdMap = new HashMap<>();
670+
final Map<SourceAndConverter<?>, ComparableKey> keyMap = new HashMap<>();
678671

679-
if (SourceAndConverterServices.getSourceAndConverterService().getMetadata(
680-
s2, SourceAndConverterService.SPIM_DATA_INFO) != null)
681-
{
682-
sdi2 =
683-
((SourceAndConverterService.SpimDataInfo) (SourceAndConverterServices
684-
.getSourceAndConverterService().getMetadata(s2,
685-
SourceAndConverterService.SPIM_DATA_INFO)));
686-
}
672+
int index = 0;
673+
int nextAsdId = 0;
687674

688-
if ((sdi1 == null) && (sdi2 != null)) {
689-
return -1;
690-
}
675+
for (SourceAndConverter<?> sac : sortedList) {
676+
Object metadata = SourceAndConverterServices.getSourceAndConverterService()
677+
.getMetadata(sac, SourceAndConverterService.SPIM_DATA_INFO);
691678

692-
if ((sdi1 != null) && (sdi2 == null)) {
693-
return 1;
694-
}
679+
ComparableKey key;
680+
if (metadata != null) {
681+
SourceAndConverterService.SpimDataInfo sdi =
682+
(SourceAndConverterService.SpimDataInfo) metadata;
695683

696-
if (sdi1 != null) {
697-
if (sdi1.asd == sdi2.asd) {
698-
return sdi1.setupId - sdi2.setupId;
699-
}
700-
else {
701-
return sdi2.toString().compareTo(sdi1.toString());
684+
// Assign a stable ID to each unique asd object
685+
if (!asdIdMap.containsKey(sdi.asd)) {
686+
asdIdMap.put(sdi.asd, nextAsdId++);
702687
}
688+
int asdId = asdIdMap.get(sdi.asd);
689+
690+
// Create key: has SpimData (0), asd ID, setupId, then index as tiebreaker
691+
key = new ComparableKey(0, asdId, sdi.setupId, "", index);
692+
} else {
693+
// No SpimData: use (1) to sort after SpimData sources, then by name
694+
String name = sac.getSpimSource().getName();
695+
if (name == null) name = "";
696+
key = new ComparableKey(1, 0, 0, name, index);
703697
}
704698

705-
return s2.getSpimSource().getName().compareTo(s1.getSpimSource()
706-
.getName());
707-
};
699+
keyMap.put(sac, key);
700+
index++;
701+
}
702+
703+
// Sort using the comparable keys
704+
sortedList.sort((s1, s2) -> {
705+
ComparableKey key1 = keyMap.get(s1);
706+
ComparableKey key2 = keyMap.get(s2);
707+
if (key1 == null || key2 == null) {
708+
if (key1 == null && key2 == null) return 0;
709+
return (key1 == null) ? 1 : -1;
710+
}
711+
return key1.compareTo(key2);
712+
});
708713

709-
sortedList.sort(sacComparator);
710714
return sortedList;
711715
}
712716

717+
// Comparable key for guaranteed transitive sorting
718+
private static class ComparableKey implements Comparable<ComparableKey> {
719+
final int group; // 0 = has SpimData, 1 = no SpimData
720+
final int asdId; // Stable ID for asd object (0 if no SpimData)
721+
final int setupId; // Setup ID within same asd (0 if no SpimData)
722+
final String name; // Name for sources without SpimData
723+
final int index; // Original index as final tiebreaker
724+
725+
ComparableKey(int group, int asdId, int setupId, String name, int index) {
726+
this.group = group;
727+
this.asdId = asdId;
728+
this.setupId = setupId;
729+
this.name = name;
730+
this.index = index;
731+
}
732+
733+
@Override
734+
public int compareTo(ComparableKey other) {
735+
// Compare level by level to ensure transitivity
736+
int cmp = Integer.compare(this.group, other.group);
737+
if (cmp != 0) return cmp;
738+
739+
cmp = Integer.compare(this.asdId, other.asdId);
740+
if (cmp != 0) return cmp;
741+
742+
cmp = Integer.compare(this.setupId, other.setupId);
743+
if (cmp != 0) return cmp;
744+
745+
cmp = this.name.compareTo(other.name);
746+
if (cmp != 0) return cmp;
747+
748+
return Integer.compare(this.index, other.index);
749+
}
750+
}
751+
713752
/**
714753
* Default sorting order for SourceAndConverter Because sometimes we want some
715754
* consistency in channel ordering when exporting / importing TODO : find a
@@ -726,49 +765,52 @@ public static List<SourceAndConverter> sortDefaultNoGeneric(
726765
List<SourceAndConverter> sortedList = new ArrayList<>(sacs.size());
727766
sortedList.addAll(sacs);
728767

729-
Comparator<SourceAndConverter> sacComparator = (s1, s2) -> {
730-
// Those who do not belong to spimdata are last:
731-
SourceAndConverterService.SpimDataInfo sdi1 = null, sdi2 = null;
732-
if (SourceAndConverterServices.getSourceAndConverterService().getMetadata(
733-
s1, SourceAndConverterService.SPIM_DATA_INFO) != null)
734-
{
735-
sdi1 =
736-
((SourceAndConverterService.SpimDataInfo) (SourceAndConverterServices
737-
.getSourceAndConverterService().getMetadata(s1,
738-
SourceAndConverterService.SPIM_DATA_INFO)));
739-
}
768+
// Build a map of asd objects to unique IDs for stable ordering
769+
final Map<Object, Integer> asdIdMap = new HashMap<>();
770+
final Map<SourceAndConverter, ComparableKey> keyMap = new HashMap<>();
740771

741-
if (SourceAndConverterServices.getSourceAndConverterService().getMetadata(
742-
s2, SourceAndConverterService.SPIM_DATA_INFO) != null)
743-
{
744-
sdi2 =
745-
((SourceAndConverterService.SpimDataInfo) (SourceAndConverterServices
746-
.getSourceAndConverterService().getMetadata(s2,
747-
SourceAndConverterService.SPIM_DATA_INFO)));
748-
}
772+
int index = 0;
773+
int nextAsdId = 0;
749774

750-
if ((sdi1 == null) && (sdi2 != null)) {
751-
return -1;
752-
}
775+
for (SourceAndConverter sac : sortedList) {
776+
Object metadata = SourceAndConverterServices.getSourceAndConverterService()
777+
.getMetadata(sac, SourceAndConverterService.SPIM_DATA_INFO);
753778

754-
if ((sdi1 != null) && (sdi2 == null)) {
755-
return 1;
756-
}
779+
ComparableKey key;
780+
if (metadata != null) {
781+
SourceAndConverterService.SpimDataInfo sdi =
782+
(SourceAndConverterService.SpimDataInfo) metadata;
757783

758-
if (sdi1 != null) {
759-
if (sdi1.asd == sdi2.asd) {
760-
return sdi1.setupId - sdi2.setupId;
761-
}
762-
else {
763-
return sdi2.toString().compareTo(sdi1.toString());
784+
// Assign a stable ID to each unique asd object
785+
if (!asdIdMap.containsKey(sdi.asd)) {
786+
asdIdMap.put(sdi.asd, nextAsdId++);
764787
}
788+
int asdId = asdIdMap.get(sdi.asd);
789+
790+
// Create key: has SpimData (0), asd ID, setupId, then index as tiebreaker
791+
key = new ComparableKey(0, asdId, sdi.setupId, "", index);
792+
} else {
793+
// No SpimData: use (1) to sort after SpimData sources, then by name
794+
String name = sac.getSpimSource().getName();
795+
if (name == null) name = "";
796+
key = new ComparableKey(1, 0, 0, name, index);
765797
}
766798

767-
return s2.getSpimSource().getName().compareTo(s1.getSpimSource()
768-
.getName());
769-
};
799+
keyMap.put(sac, key);
800+
index++;
801+
}
802+
803+
// Sort using the comparable keys
804+
sortedList.sort((s1, s2) -> {
805+
ComparableKey key1 = keyMap.get(s1);
806+
ComparableKey key2 = keyMap.get(s2);
807+
if (key1 == null || key2 == null) {
808+
if (key1 == null && key2 == null) return 0;
809+
return (key1 == null) ? 1 : -1;
810+
}
811+
return key1.compareTo(key2);
812+
});
770813

771-
sortedList.sort(sacComparator);
772814
return sortedList;
773815
}
774816

0 commit comments

Comments
 (0)