Skip to content

Commit

Permalink
Merge pull request #483 from FZJ-INM1-BDA/maint_use_dictfromkeys_to_s…
Browse files Browse the repository at this point in the history
…eive_query_results

Use dict.fromkeys for removing duplicates  in feature query (for reproducible results order)
  • Loading branch information
AhmetNSimsek authored Sep 28, 2023
2 parents c2c25aa + 2211797 commit 0079b3c
Showing 1 changed file with 28 additions and 12 deletions.
40 changes: 28 additions & 12 deletions siibra/features/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,12 +363,16 @@ def deserialize_query_context(Cls, feature_id: str) -> Tuple[Type['Feature'], co

@classmethod
def parse_featuretype(cls, feature_type: str) -> List[Type['Feature']]:
return [
ftypes = {
feattype
for FeatCls, feattypes in cls.SUBCLASSES.items()
if all(w.lower() in FeatCls.__name__.lower() for w in feature_type.split())
for feattype in feattypes
]
}
if len(ftypes) > 1:
return [ft for ft in ftypes if getattr(ft, 'category')]
else:
return list(ftypes)

@classmethod
def livequery(cls, concept: Union[region.Region, parcellation.Parcellation, space.Space], **kwargs) -> List['Feature']:
Expand Down Expand Up @@ -405,18 +409,30 @@ def match(cls, concept: Union[region.Region, parcellation.Parcellation, space.Sp
"""
if isinstance(feature_type, list):
# a list of feature types is given, collect match results on those
assert all((isinstance(t, str) or issubclass(t, cls)) for t in feature_type)
return list(set(sum((cls.match(concept, t, **kwargs) for t in feature_type), [])))
assert all(
(isinstance(t, str) or issubclass(t, cls))
for t in feature_type
)
return list(dict.fromkeys(
sum((
cls.match(concept, t, **kwargs) for t in feature_type
), [])
))

if isinstance(feature_type, str):
# feature type given as a string. Decode the corresponding class.
# Some string inputs, such as connectivity, may hit multiple matches
# In this case
candidates = cls.parse_featuretype(feature_type)
if len(candidates) == 0:
raise ValueError(f"feature_type {str(feature_type)} did not match with any features. Available features are: {', '.join(cls.SUBCLASSES.keys())}")

return list({feat for c in candidates for feat in cls.match(concept, c, **kwargs)})
# Some string inputs, such as connectivity, may hit multiple matches.
ftype_candidates = cls.parse_featuretype(feature_type)
if len(ftype_candidates) == 0:
raise ValueError(
f"feature_type {str(feature_type)} did not match with any "
f"features. Available features are: {', '.join(cls.SUBCLASSES.keys())}"
)
logger.info(
f"'{feature_type}' decoded as feature type/s: "
f"{[c.__name__ for c in ftype_candidates]}."
)
return cls.match(concept, ftype_candidates, **kwargs)

assert issubclass(feature_type, Feature)

Expand All @@ -441,7 +457,7 @@ def match(cls, concept: Union[region.Region, parcellation.Parcellation, space.Sp

live_instances = feature_type.livequery(concept, **kwargs)

return list(set((preconfigured_instances + live_instances)))
return list(dict.fromkeys(preconfigured_instances + live_instances))

@classmethod
def get_instance_by_id(cls, feature_id: str, **kwargs):
Expand Down

0 comments on commit 0079b3c

Please sign in to comment.