Repository: scikit-hep/uproot5

Issue:
Unable to parse higher-dimensional (basic) arrays in leaves
An issue in UnROOT was raised (https://github.com/tamasgal/UnROOT.jl/issues/9) since the automatic higher dimensional data or in general is still not possible or experimental, so I did what I usually do: fire up `uproot` and `uproo4` 😉  however there seems to be a problem to parse the dimensionality of those arrays. I am quite sure this worked in other files in the past, so I am not sure what's happening here but you see that the data under `structs` is correctly parsed, however the same data saved as multi-dimensional arrays in as `TLeafD` does not parse correctly.

I have not worked much with uproot4 yet, so I am sorry to just dump the error here, but I guess you already know what's going wrong:

```python
In [21]: import uproot4

In [22]: f = uproot4.open("/Users/tamasgal/Downloads/test_array.root")

In [23]: f["arrays"].show()
name                 | typename             | interpretation
---------------------+----------------------+-----------------------------------
nInt                 | int32_t              | AsDtype('>i4')
6dVec                | double               | AsDtype('>f8')
2x3Mat               | double               | AsDtype('>f8')

In [24]: f["structs"].show()
name                 | typename             | interpretation
---------------------+----------------------+-----------------------------------
nInt                 | int32_t              | AsDtype('>i4')
2x3mat               | double[6]            | AsDtype("('>f8', (6,))")

In [25]: f["arrays/6dVec"].array()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-25-dbf33b2ce1b8> in <module>
----> 1 f["arrays/6dVec"].array()

~/.virtualenvs/km3net/lib/python3.7/site-packages/uproot4/behaviors/TBranch.py in array(self, interpretation, entry_start, entry_stop, decompression_executor, interpretation_executor, array_cache, library)
   1620             interpretation_executor,
   1621             library,
-> 1622             arrays,
   1623         )
   1624

~/.virtualenvs/km3net/lib/python3.7/site-packages/uproot4/behaviors/TBranch.py in _ranges_or_baskets_to_arrays(hasbranches, ranges_or_baskets, branchid_interpretation, entry_start, entry_stop, decompression_executor, interpretation_executor, library, arrays)
    516
    517         elif isinstance(obj, tuple) and len(obj) == 3:
--> 518             uproot4.source.futures.delayed_raise(*obj)
    519
    520         else:

~/.virtualenvs/km3net/lib/python3.7/site-packages/uproot4/source/futures.py in delayed_raise(exception_class, exception_value, traceback)
     35         exec("raise exception_class, exception_value, traceback")
     36     else:
---> 37         raise exception_value.with_traceback(traceback)
     38
     39

~/.virtualenvs/km3net/lib/python3.7/site-packages/uproot4/behaviors/TBranch.py in basket_to_array(basket)
    482                         len(basket_arrays[basket.basket_num]),
    483                         interpretation,
--> 484                         branch.file.file_path,
    485                     )
    486                 )

ValueError: basket 0 in tree/branch /arrays;1:6dVec has the wrong number of entries (expected 1, obtained 6) when interpreted as AsDtype('>f8')
    in file /Users/tamasgal/Downloads/test_array.root
```
Unable to parse higher-dimensional (basic) arrays in leaves
An issue in UnROOT was raised (https://github.com/tamasgal/UnROOT.jl/issues/9) since the automatic higher dimensional data or in general is still not possible or experimental, so I did what I usually do: fire up `uproot` and `uproo4` 😉  however there seems to be a problem to parse the dimensionality of those arrays. I am quite sure this worked in other files in the past, so I am not sure what's happening here but you see that the data under `structs` is correctly parsed, however the same data saved as multi-dimensional arrays in as `TLeafD` does not parse correctly.

I have not worked much with uproot4 yet, so I am sorry to just dump the error here, but I guess you already know what's going wrong:

```python
In [21]: import uproot4

In [22]: f = uproot4.open("/Users/tamasgal/Downloads/test_array.root")

In [23]: f["arrays"].show()
name                 | typename             | interpretation
---------------------+----------------------+-----------------------------------
nInt                 | int32_t              | AsDtype('>i4')
6dVec                | double               | AsDtype('>f8')
2x3Mat               | double               | AsDtype('>f8')

In [24]: f["structs"].show()
name                 | typename             | interpretation
---------------------+----------------------+-----------------------------------
nInt                 | int32_t              | AsDtype('>i4')
2x3mat               | double[6]            | AsDtype("('>f8', (6,))")

In [25]: f["arrays/6dVec"].array()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-25-dbf33b2ce1b8> in <module>
----> 1 f["arrays/6dVec"].array()

~/.virtualenvs/km3net/lib/python3.7/site-packages/uproot4/behaviors/TBranch.py in array(self, interpretation, entry_start, entry_stop, decompression_executor, interpretation_executor, array_cache, library)
   1620             interpretation_executor,
   1621             library,
-> 1622             arrays,
   1623         )
   1624

~/.virtualenvs/km3net/lib/python3.7/site-packages/uproot4/behaviors/TBranch.py in _ranges_or_baskets_to_arrays(hasbranches, ranges_or_baskets, branchid_interpretation, entry_start, entry_stop, decompression_executor, interpretation_executor, library, arrays)
    516
    517         elif isinstance(obj, tuple) and len(obj) == 3:
--> 518             uproot4.source.futures.delayed_raise(*obj)
    519
    520         else:

~/.virtualenvs/km3net/lib/python3.7/site-packages/uproot4/source/futures.py in delayed_raise(exception_class, exception_value, traceback)
     35         exec("raise exception_class, exception_value, traceback")
     36     else:
---> 37         raise exception_value.with_traceback(traceback)
     38
     39

~/.virtualenvs/km3net/lib/python3.7/site-packages/uproot4/behaviors/TBranch.py in basket_to_array(basket)
    482                         len(basket_arrays[basket.basket_num]),
    483                         interpretation,
--> 484                         branch.file.file_path,
    485                     )
    486                 )

ValueError: basket 0 in tree/branch /arrays;1:6dVec has the wrong number of entries (expected 1, obtained 6) when interpreted as AsDtype('>f8')
    in file /Users/tamasgal/Downloads/test_array.root
```


Discussion:
Thanks, I'll take a look! The UnROOT.jl issue you pointed to has examples of how to make the file.

It might be more instructive to look at files with more than one entry. Is also a good debugging technique to make the two factors we have to disambiguate relatively prime, or make every size a prime number (e.g. 2, 3, and 5)—it helps to narrow down how what it's doing is different from what you want. Since we can create the files ourselves in this case, that's a possibility.
Thanks, I'll take a look! The UnROOT.jl issue you pointed to has examples of how to make the file.

It might be more instructive to look at files with more than one entry. Is also a good debugging technique to make the two factors we have to disambiguate relatively prime, or make every size a prime number (e.g. 2, 3, and 5)—it helps to narrow down how what it's doing is different from what you want. Since we can create the files ourselves in this case, that's a possibility.

Resolving patch:
diff --git a/uproot4/interpretation/identify.py b/uproot4/interpretation/identify.py
--- a/uproot4/interpretation/identify.py
+++ b/uproot4/interpretation/identify.py
@@ -755,7 +755,7 @@ def parse_typename_for_streamer(typename, file):
     return out
 
 
-_title_has_dims = re.compile(r"^([^\[\]]+)(\[[^\[\]]+\])+")
+_title_has_dims = re.compile(r"^([^\[\]]*)(\[[^\[\]]+\])+")
 _item_dim_pattern = re.compile(r"\[([1-9][0-9]*)\]")
 _item_any_pattern = re.compile(r"\[(.*)\]")
 _vector_pointer = re.compile(r"vector\<([^<>]*)\*\>")


Test patch: