Error when using awkward array 1.0 combinatorics function to make two-particle combinations

82 Views Asked by At

I'm running into some trouble when using awkward array 1.0 to make combinations of particles with ak.combinations. I see the error when trying to do ak.unzip on the combinations I have made (following the tutorial here: https://mybinder.org/v2/gh/jpivarski/2020-07-13-pyhep2020-tutorial.git/1.1?urlpath=lab/tree/tutorial.ipynb).

I have put an example which reproduces the error here:

https://github.com/donalrinho/awkward1_combinatorics_test

and would be very grateful for any help to understand what I'm doing wrong. The error I see is:

Traceback (most recent call last):
  File "python/simple_combiner.py", line 41, in <module>
    pi1, pi2 = ak.unzip(pi_pairs)
ValueError: too many values to unpack (expected 2)

The error doesn't occur when I restrict the input data to a specific variable, so for instance:

pi_pairs = ak.combinations(pi["pt"], 2)
pi1, pi2 = ak.unzip(pi_pairs)

where I pass in only the pt of the pi array.

2

There are 2 best solutions below

0
On

The ValueError: too many values to unpack (expected 2) is a Python (not Awkward) error message saying that the tuple on the right hand side of the assignment has a length that is not 2. We can get the same error message like this:

>>> pi1, pi2 = ("a", "b", "c")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)

So the ak.unzip(pi_pairs) must have a length that is not 2. All that ak.unzip does is to find record fields in the array that it's given and make a tuple where each of these is projected out. All it would take to get the above error message is for the array to have more or less than two fields. Here's an example with three:

>>> ak.unzip(ak.Array([{"x": 1, "y": 2, "z": 3}, {"x": 10, "y": 20, "z": 30}]))
(<Array [1, 10] type='2 * int64'>,
 <Array [2, 20] type='2 * int64'>,
 <Array [3, 30] type='2 * int64'>)

The ak.combinations function should create an array of records with n fields, where n is the argument you passed. That seems to be 2 in your code example, but before we can tell what's going on, you need to print out the output of ak.zip. Is it returning a tuple with zero items? One? Three? More?

It looks like you're developing this as a script. I'd recommend developing interactively, on a Python console, iPython, Jupyter, etc. At least when I am building up an analysis based on NumPy-like indexing, I get the indexing wrong more than half the time, but with the immediate feedback, such mistakes can be fixed in seconds. ("Oh yeah, I forgot to include a...") It's likely that the pi you're passing into the ak.combinations(pi, 2) is not what you think it is. I'd recommend breaking it down and examining small examples (slice the first event or two and call ak.to_list and ak.type on it), working backward until you get to a structure that is shaped as you expect it to be.

0
On

Thanks a lot for the prompt feedback Jim, very helpful. I tried using zip when doing tree.arrays(). This lets me group things like you do for Muon in the tutorial ( for me the equivalent is pfcharged.core, which is just a detail).

Then I have the following code which works:

arrays = tree.arrays(filter_name="pfcharged.core*",how="zip")
pairs = ak.combinations(arrays["pfcharged.core"],2)
p1, p2 = ak.unzip(pairs)

I'm not sure if using zip with tree.arrays() is a prerequisite for the ak.unzip function to operate, but anyhow using zip seems like a sensible thing to do!

Cheers, Donal