Creating and Sorting Vectors of Collections

Perhaps whilst we wait for @pcanal to get back on the shared library bit I can ask one of my others.

My idea for the classes was to try to make the programming logic simpler for me. To check that my logic is working correctly (in an event I want to loop over each jet and then each truth_jet to get the one with the smallest deltaR) I’d like to create a small data frame with my own events. I have the following test script in python:

### Helper functions and classes
class jet:
    def __init__(self,pt,eta,phi):
        self.pt = pt
        self.eta = eta
        self.phi = phi

    def set_match(self, match):
        self.matched = match
        
    def get_dr(self, seed):
        self.dr = dr(seed,self)

### (I know this isn't how dR works)
def dr(jet1,jet2):
    dphi = jet1.phi-jet2.phi
    deta = jet1.eta-jet2.eta
    return abs(dphi+deta)

### one event
reco_jets = [jet(1,1,1),jet(2,2,1)]
truth_jets = [jet(1,3,1),jet(2,1,1),jet(3,2,1)]
event1 = {'reco_jets':reco_jets,'truth_jets':truth_jets}

### analysis logic
#### for each jet
for j in event1['reco_jets']:
    #### find distances of this jet to all truth jets
    for k in event1['truth_jets']:
        k.get_dr(j)
    #### sort truth jets based on this value
    sorted_truth = sorted(event1['truth_jets'], key=lambda x: x.dr)

    #### if value is below a threshold return it
    if sorted_truth[0].dr < 2:
        j.set_match(sorted_truth[0])


### test logic worked
for j in event1['reco_jets']:
    print(j.matched.pt)

so I’d like to first know how to create a test data frame eg df = ROOT.RDataFrame([event1]) such that I can then work out how to create a vector of vectors needed to recreate the logic represented above.
(something along the lines of)

df0 = ROOT.RDataFrame(event1)
df = df.Define('drs',DeltaR(reco_eta,reco_phi,truth_eta,truth_phi))
df = df.Define('matched_truth','ArgSort(drs)')
df = df.Filter(drs<2)
df = df.Define('lead_matched','truth_pt[Take(matched_truth,1)]')
h = df.Histo1D('lead_matched')

…or whatever…

in any case my question is about building a simple data frame in order to test this logic and hopefully that gives me some insight into creating and sorting the members within.

Hi Philippe,
yes after some work (my anaconda install of root refuses to compile macros it seems) I got to the same place as before. Now that I have compiled the header and loaded it, I can use it to create branches as before but still cannot snapshot them.

[Photon_PY-2.pdf|attachment](https://root-forum.cern.ch/uploads/short-url/b94Rj1KDO7npR49b3PImGf3F6BM.pdf) (49.8 KB)

Maybe @eguiraud has a better answer.

It looks like you need to also generate the dictionary for RVec<photon> and/or vector<photon,ROOT::Detail::VecOps::RAdoptAllocator<photon> >

So adding to photon_struct.h:

#ifdef __ROOTCLING__
#pragma link C++ class vector<photon,ROOT::Detail::VecOps::RAdoptAllocator<photon> >+;
#pragma link C++ class ROOT::VecOps::RVec<photon>+;
#endif

and (of course) the corresponding headers:

#include "ROOT/RVec.hxx"
#include <vector>

should solve the problem.

Ah wonderful. Indeed now I don’t have any warnings when snapshotting the object however I do have issues when reading the outputted tree.

AttributeError: 'vector<photon,ROOT::Detail::VecOps::RAdoptAllocato' object has no attribute 'pt'

do I have to explicitly tell ROOT that this is an instance of my photon class?

image

Heres the full notebook as before.
Photon_PY.pdf (51.4 KB)

The intriguing part is that the class name is truncated. @etejedor Do you have any idea what’s going on?

Hi,

IIUC event.photons is a vector<photon>, and photon is what has the attribute pt. So I’d try e.g. for photon in event.photons: print(photon.pt).

1 Like

:man_facepalming:

ok yes, this worked. Obviously. Thanks @etejedor!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.