1

I'm building on a previous question about the best way to use awkward efficiently with combinations of particles.

Suppose I have a final state of 4 muons and my hypothesis is that these come from some resonance or particle (Higgs?) that decays to two Z bosons, which themselves decay to 2 muons. The Z's should be neutral. So let me start building a test case.

!curl http://opendata.cern.ch/record/12361/files/SMHiggsToZZTo4L.root --output SMHiggsToZZTo4L.root

Then import the usual suspects

import awkward as ak
import uproot

import vector
vector.register_awkward()

Read in the data and create a MomentumArray4D.

infile = uproot.open("SMHiggsToZZTo4L.root")

muon_branch_arrays = infile["Events"].arrays(filter_name="Muon_*")

muons = ak.zip({
    "pt": muon_branch_arrays["Muon_pt"],
    "phi": muon_branch_arrays["Muon_phi"],
    "eta": muon_branch_arrays["Muon_eta"],
    "mass": muon_branch_arrays["Muon_mass"],
    "charge": muon_branch_arrays["Muon_charge"],
}, with_name="Momentum4D")

Now physics!

quads = ak.combinations(muons, 4)

mu1, mu2, mu3, mu4 = ak.unzip(quads)

p4 = mu1 + mu2 + mu3 + mu4

This all works swimmingly and I could plot the mass from the p4 object if I wanted.

However, I want to select the data based on the masses and charge combinations of the muon pairs. For example, if I have 4 muons, I have multiple combinations that could have come from the Z.

  • Z1 --> mu1 + mu2, Z2 --> mu3 + mu4
  • Z1 --> mu1 + mu3, Z2 --> mu2 + mu4
  • Z1 --> mu1 + mu4, Z2 --> mu2 + mu3

So I might require that both Z1 and Z2 are neutral and that they are in some mass window and then use that requirement to mask the p4 observables.

I thought maybe I could just do

pairs = ak.combinations(quads,2)

zmu1,zmu2 = ak.unzip(pairs)

zp4 = zmu1 + zmu2

But I get a lot of errors at the last step. muons and quads are <class 'vector.backends.awkward.MomentumArray4D'> and <class 'awkward.highlevel.Array'> objects respectively, so I get that they won't behave the same.

So what's the proper awkward syntax to handle this?

Thanks!

Matt

Matt Bellis
  • 289
  • 2
  • 10
  • Since the behaviors are registered globally (`vector.register_awkward()`), the `zmu2` must be losing its `Momentum4D` property somewhere along the way. Do you see where it gets lost in the data type? – Jim Pivarski Jul 30 '23 at 21:22
  • 1
    Also, this worked example might be helpful: https://github.com/jpivarski-talks/2023-05-01-hsf-india-tutorial/blob/main/exercise-3-solved.ipynb – Jim Pivarski Jul 30 '23 at 21:22
  • Ah, this is what I'm looking for! Thanks @JimPivarski! – Matt Bellis Aug 02 '23 at 05:03

0 Answers0