Coverage for src/hdmf/region.py: 55%

46 statements  

« prev     ^ index     » next       coverage.py v7.2.5, created at 2023-07-21 22:12 +0000

1from abc import ABCMeta, abstractmethod 

2from operator import itemgetter 

3 

4from .container import Data, DataRegion 

5from .utils import docval, getargs 

6 

7 

8class RegionSlicer(DataRegion, metaclass=ABCMeta): 

9 ''' 

10 A abstract base class to control getting using a region 

11 

12 Subclasses must implement `__getitem__` and `__len__` 

13 ''' 

14 

15 @docval({'name': 'target', 'type': None, 'doc': 'the target to slice'}, 

16 {'name': 'slice', 'type': None, 'doc': 'the region to slice'}) 

17 def __init__(self, **kwargs): 

18 self.__target = getargs('target', kwargs) 

19 self.__slice = getargs('slice', kwargs) 

20 

21 @property 

22 def data(self): 

23 """The target data. Same as self.target""" 

24 return self.target 

25 

26 @property 

27 def region(self): 

28 """The selected region. Same as self.slice""" 

29 return self.slice 

30 

31 @property 

32 def target(self): 

33 """The target data""" 

34 return self.__target 

35 

36 @property 

37 def slice(self): 

38 """The selected slice""" 

39 return self.__slice 

40 

41 @property 

42 @abstractmethod 

43 def __getitem__(self, idx): 

44 """Must be implemented by subclasses""" 

45 pass 

46 

47 @property 

48 @abstractmethod 

49 def __len__(self): 

50 """Must be implemented by subclasses""" 

51 pass 

52 

53 

54class ListSlicer(RegionSlicer): 

55 """Implementation of RegionSlicer for slicing Lists and Data""" 

56 

57 @docval({'name': 'dataset', 'type': (list, tuple, Data), 'doc': 'the dataset to slice'}, 

58 {'name': 'region', 'type': (list, tuple, slice), 'doc': 'the region reference to use to slice'}) 

59 def __init__(self, **kwargs): 

60 self.__dataset, self.__region = getargs('dataset', 'region', kwargs) 

61 super().__init__(self.__dataset, self.__region) 

62 if isinstance(self.__region, slice): 

63 self.__getter = itemgetter(self.__region) 

64 self.__len = len(range(*self.__region.indices(len(self.__dataset)))) 

65 else: 

66 self.__getter = itemgetter(*self.__region) 

67 self.__len = len(self.__region) 

68 

69 def __read_region(self): 

70 """ 

71 Internal helper function used to define self._read 

72 """ 

73 if not hasattr(self, '_read'): 

74 self._read = self.__getter(self.__dataset) 

75 del self.__getter 

76 

77 def __getitem__(self, idx): 

78 """ 

79 Get data values from selected data 

80 """ 

81 self.__read_region() 

82 getter = None 

83 if isinstance(idx, (list, tuple)): 

84 getter = itemgetter(*idx) 

85 else: 

86 getter = itemgetter(idx) 

87 return getter(self._read) 

88 

89 def __len__(self): 

90 """Number of values in the slice/region""" 

91 return self.__len