DHI/mikeio1d

'NoneType' object is not iterable

hawklorry opened this issue · 3 comments

When I tried to read the water volume above ground for all nodes, I got following error. The code I'm using is given below. I also tried C# query class, it also give errors (given below). I have uploaded res1d file to the ftp: ftp://tea42@ftp.dhigroup.com/pub/ZHYU/richmond_20200923_2020-09-23RichmondHD.res1d

I'm also wondering if there is function to read all max water volume above ground values for all nodes.


allnode_ids = [n.Id for n in res1d.data.Nodes]

queries = []
for n in allnode_ids:
queries.append(QueryDataNode('WaterVolumeAboveGround', n))

max_level_of_all = res1d.read(queries).max()
max_level_of_all


TypeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_35324/2335864540.py in
5 queries.append(QueryDataNode('WaterVolumeAboveGround', n))
6
----> 7 max_level_of_all = res1d.read(queries).max()
8 max_level_of_all

~\AppData\Roaming\Python\Python37\site-packages\mikeio1d\res1d.py in read(self, queries)
163 df = pd.DataFrame(index=self.time_index)
164 for query in queries:
--> 165 df[str(query)] = query.get_values(self)
166
167 return df

~\AppData\Roaming\Python\Python37\site-packages\mikeio1d\res1d.py in get_values(self, res1d)
126 def get_values(self, res1d):
127 values = res1d.query.GetNodeValues(self._name, self._quantity)
--> 128 return self.from_dotnet_to_python(values)
129
130

~\AppData\Roaming\Python\Python37\site-packages\mikeio1d\res1d.py in from_dotnet_to_python(array)
44 def from_dotnet_to_python(array):
45 """Convert .NET array to numpy."""
---> 46 return np.fromiter(array, np.float64)
47
48 @Property

TypeError: 'NoneType' object is not iterable

Then I used C# query class, it gives the error below.


allnode_ids = [n.Id for n in res1d.data.Nodes]

max_water_volume_above_ground = {}
for n in allnode_ids:
max_water_volume_above_ground[n] = to_numpy(res1d.query.GetNodeValues(n,'WaterVolumeAboveGround')).max

max_water_volume_above_ground


TypeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_35324/535727106.py in
3 max_water_volume_above_ground = {}
4 for n in allnode_ids:
----> 5 max_water_volume_above_ground[n] = to_numpy(res1d.query.GetNodeValues(n,'WaterVolumeAboveGround')).max
6
7 max_water_volume_above_ground

~\AppData\Roaming\Python\Python37\site-packages\mikeio1d\dotnet.py in to_numpy(src)
156 try:
157 src_ptr = src_hndl.AddrOfPinnedObject().ToInt64()
--> 158 bufType = ctypes.c_float * len(src)
159 cbuf = bufType.from_address(src_ptr)
160 d = np.frombuffer(cbuf, dtype=cbuf.type)

TypeError: object of type 'NoneType' has no len()

It turned out that the water volume above ground is not generated for all nodes. If it's not available for a node, then it throw exception. I put the read code to the try catch and it works. It'd be nice to return zero if the result is not generated instead of raising exception.

Good that you have figured out the problem and a workaround. It is an overall problem with mikeio1d reading 'filtered' res1d files, where quantities are not defined on all locations. Especially this can be seen when we have location filtered results from Mike+ and trying to read in the whole file. So you are right this should be fixed :-).

Thanks @gedaskir . Hope this could be fixed soon.