@@ -53,8 +53,8 @@ class Region(anytree.NodeMixin, concept.AtlasConcept, structure.BrainStructure):
53
53
_regex_re = re .compile (r'^\/(?P<expression>.+)\/(?P<flags>[a-zA-Z]*)$' )
54
54
_accepted_flags = "aiLmsux"
55
55
56
- _GETMAP_CACHE = {}
57
- _GETMAP_CACHE_MAX_ENTRIES = 1
56
+ _GETMASK_CACHE = {}
57
+ _GETMASK_CACHE_MAX_ENTRIES = 1
58
58
59
59
def __init__ (
60
60
self ,
@@ -441,12 +441,21 @@ def get_regional_mask(
441
441
maptype = MapType [maptype .upper ()]
442
442
443
443
threshold_info = "" if maptype == MapType .LABELLED else f"(threshold: { threshold } ) "
444
+ # check cache
445
+ getmap_hash = hash (f"{ self .id } - { space } - { maptype } { threshold_info } " )
446
+ if getmap_hash in self ._GETMASK_CACHE :
447
+ return self ._GETMASK_CACHE [getmap_hash ]
448
+
444
449
name = f"Mask { threshold_info } of '{ self .name } ({ self .parcellation } )' in "
445
450
try :
446
451
regional_map = self .get_regional_map (space = space , maptype = maptype )
447
452
if maptype == MapType .LABELLED :
448
453
assert threshold == 0.0 , f"threshold can only be set for { MapType .STATISTICAL } maps."
449
- result = regional_map
454
+ result = volume .FilteredVolume (
455
+ parent_volume = regional_map ,
456
+ label = regional_map .label ,
457
+ fragment = regional_map .fragment
458
+ )
450
459
result ._boundingbox = None
451
460
if maptype == MapType .STATISTICAL :
452
461
result = volume .FilteredVolume (
@@ -459,18 +468,25 @@ def get_regional_mask(
459
468
except NoMapAvailableError :
460
469
# This region is not mapped directly in any map in the registry.
461
470
# Try building a map from the child regions
462
- if (len (self .children ) > 0 ) and all (c .mapped_in_space (space , recurse = True ) for c in self .children ):
463
- logger .info (f"{ self .name } is not mapped in { space } . Merging the masks of its { len (self .children )} child regions." )
464
- child_volumes = [
465
- child .get_regional_mask (space = space , maptype = maptype , threshold = threshold )
466
- for child in self .children
471
+ if (len (self .children ) > 0 ) and self .mapped_in_space (space , recurse = True ):
472
+ mapped_descendants : List [Region ] = [
473
+ d for d in self .descendants if d .mapped_in_space (space , recurse = False )
474
+ ]
475
+ logger .info (f"{ self .name } is not mapped in { space } . Merging the masks of its { len (mapped_descendants )} map descendants." )
476
+ descendant_volumes = [
477
+ descendant .get_regional_mask (space = space , maptype = maptype , threshold = threshold )
478
+ for descendant in mapped_descendants
467
479
]
468
480
result = volume .FilteredVolume (
469
- volume .merge (child_volumes ),
481
+ volume .merge (descendant_volumes ),
470
482
label = 1
471
483
)
472
484
name += f"'{ result .space } ' (built by merging the mask { threshold_info } of its decendants)"
473
485
result ._name = name
486
+
487
+ while len (self ._GETMASK_CACHE ) > self ._GETMASK_CACHE_MAX_ENTRIES :
488
+ self ._GETMASK_CACHE .pop (next (iter (self ._GETMASK_CACHE )))
489
+ self ._GETMASK_CACHE [getmap_hash ] = result
474
490
return result
475
491
476
492
def get_regional_map (
@@ -515,11 +531,10 @@ def get_regional_map(
515
531
and self .name in m .regions
516
532
):
517
533
return m .get_volume (region = self )
518
- else :
519
- raise NoMapAvailableError (
520
- f"{ self .name } is not mapped in { space } as a { str (maptype )} map."
521
- " Please try getting the children or getting the mask."
522
- )
534
+ raise NoMapAvailableError (
535
+ f"{ self .name } is not mapped in { space } as a { str (maptype )} map."
536
+ " Please try getting the children or getting the mask."
537
+ )
523
538
524
539
def mapped_in_space (self , space , recurse : bool = False ) -> bool :
525
540
"""
0 commit comments