11
11
from collections .abc import Iterable
12
12
except ImportError :
13
13
from collections import Iterable
14
+ import numpy as np
14
15
from .data_set import DataSet
15
- from .exceptions import OutOfBounds , IncompatibleDimensions
16
+ from .exceptions import OutOfBounds , InvalidSlice
16
17
17
18
18
19
class DataView (DataSet ):
19
20
20
21
def __init__ (self , da , slices ):
21
- if len (slices ) != len (da .shape ):
22
+ self ._valid = slices is not None and all (slices )
23
+ self ._slices = slices
24
+ if not self .valid :
25
+ self ._error_message = (
26
+ "InvalidSlice error!"
27
+ "Given slice {} is invalid! At least one slice along one dimension"
28
+ "does not contain data." .format (slices )
29
+ )
30
+ else :
31
+ self ._error_message = ""
32
+
33
+ if self .valid and len (slices ) != len (da .shape ):
22
34
# This is always checked by the calling function, but we repeat
23
35
# the check here for future bug catching
24
- raise IncompatibleDimensions (
36
+ self ._valid = False
37
+ self ._error_message = (
38
+ "IncompatibleDimensions error."
25
39
"Number of dimensions for DataView does not match underlying "
26
40
"data object: {} != {}" .format (len (slices ), len (da .shape )),
27
- "DataView"
28
41
)
29
42
30
- if any (s .stop > e for s , e in zip (slices , da .data_extent )):
31
- raise OutOfBounds (
32
- "Trying to create DataView which is out of bounds of the "
33
- "underlying DataArray"
43
+ if self .valid and any (s .stop > e for s , e in zip (slices , da .data_extent )):
44
+ self ._valid = False
45
+ self ._error_message = (
46
+ "OutOfBounds error!"
47
+ "Trying to create DataView with slices {} which are out of bounds of the "
48
+ "underlying DataArray {}" .format (self ._slices , da .shape )
34
49
)
35
50
36
51
# Simplify all slices
37
- slices = tuple (slice (* sl .indices (dimlen ))
38
- for sl , dimlen in zip (slices , da .shape ))
52
+ if self .valid :
53
+ slices = tuple (slice (* sl .indices (dimlen ))
54
+ for sl , dimlen in zip (slices , da .shape ))
55
+ self ._slices = slices
39
56
40
57
self .array = da
41
58
self ._h5group = self .array ._h5group
42
- self ._slices = slices
59
+
60
+ @property
61
+ def valid (self ):
62
+ return self ._valid
63
+
64
+ @property
65
+ def debug_message (self ):
66
+ return self ._error_message
43
67
44
68
@property
45
69
def data_extent (self ):
46
- return tuple (s .stop - s .start for s in self ._slices )
70
+ if self .valid :
71
+ return tuple (s .stop - s .start for s in self ._slices )
72
+ else :
73
+ return None
47
74
48
75
@data_extent .setter
49
76
def data_extent (self , v ):
@@ -54,12 +81,19 @@ def data_type(self):
54
81
return self .array .data_type
55
82
56
83
def _write_data (self , data , sl = None ):
84
+ if not self .valid :
85
+ raise InvalidSlice (
86
+ "Write Data failed due to an invalid slice."
87
+ "Reason is: {}" .format (self ._error_message )
88
+ )
57
89
tsl = self ._slices
58
90
if sl :
59
91
tsl = self ._transform_coordinates (sl )
60
92
super (DataView , self )._write_data (data , tsl )
61
93
62
94
def _read_data (self , sl = None ):
95
+ if not self .valid :
96
+ return np .array ([])
63
97
tsl = self ._slices
64
98
if sl is not None :
65
99
tsl = self ._transform_coordinates (sl )
@@ -90,7 +124,7 @@ def transform_slice(uslice, dvslice):
90
124
ustart , ustop , ustep = uslice .indices (dimlen )
91
125
if ustop < 0 : # special case for None stop
92
126
ustop = dimlen + ustop
93
- tslice = slice (dvslice .start + ustart , dvslice .start + ustop , ustep )
127
+ tslice = slice (dvslice .start + ustart , dvslice .start + ustop , ustep )
94
128
if tslice .stop > dvslice .stop :
95
129
raise oob
96
130
@@ -141,7 +175,7 @@ def _expand_user_slices(self, user_slices):
141
175
expidx = user_slices .index (Ellipsis )
142
176
npad = len (self .data_extent ) - len (user_slices ) + 1
143
177
padding = (slice (None ),) * npad
144
- return user_slices [:expidx ] + padding + user_slices [expidx + 1 :]
178
+ return user_slices [:expidx ] + padding + user_slices [expidx + 1 :]
145
179
146
180
# expand slices at the end
147
181
npad = len (self .data_extent ) - len (user_slices )
0 commit comments