13from itertools
import combinations
14from variables
import variables
as vm
17def get_object_list(pointerVec):
19 Workaround to avoid memory problems in basf2.
22 pointerVec: Input particle list.
25 list: Output python list.
27 from ROOT
import Belle2
31 pointerVec.getListSize()
36 objList.append(pointerVec[i])
40def pdg_to_lca_converter(pdg):
42 Converts PDG code to LCAS classes.
44 .. tip:: If you want to modify the LCAS classes, it's here. Don't forget to update the number of edge classes accordingly in the yaml file.
47 pdg (int): PDG code to convert.
50 int or None: Corresponding LCAS
class,
or None if PDG
not present
in ``pdg_lca_match``.
70 if pdg
in pdg_lca_match:
71 return pdg_lca_match[pdg]
76def _update_levels(levels, hist, pdg):
78 Assigns LCAS level to each particle in the decay tree.
80 Arguments are automatically set.
82 for i, n
in enumerate(hist):
83 if n
in levels.keys():
86 lca = pdg_to_lca_converter(pdg[n])
90 for j
in range(i + 1):
91 lca = pdg_to_lca_converter(pdg[hist[i - j]])
109 Recursive function to traverse down to the leaves saving the history.
112 particle: The current particle being inspected.
113 Other arguments are automatically set.
116 neutrino_pdgs = [12, 14, 16, 18]
120 if (abs(particle.getPDG())
in neutrino_pdgs)
and particle.isPrimaryParticle():
124 hist = copy.deepcopy(hist)
125 leaf_hist = copy.deepcopy(leaf_hist)
126 leaf_pdg = copy.deepcopy(leaf_pdg)
127 levels = copy.deepcopy(levels)
128 pdg = copy.deepcopy(pdg)
139 prim_no_prim_daughters = (
141 [d
for d
in get_object_list(particle.getDaughters())
if d.isPrimaryParticle()]
150 (particle.getNDaughters() == 0)
151 or prim_no_prim_daughters
154 if abs(particle.getPDG())
not in neutrino_pdgs
and not (
155 particle.getPDG() == 22
and particle.getEnergy() < 1e-4
158 leaf_hist[particle.getArrayIndex()] = hist
159 leaf_pdg[particle.getArrayIndex()] = particle.getPDG()
163 levels = _update_levels(levels, hist, pdg)
168 particle.getNDaughters() != 0
169 )
and not prim_no_prim_daughters:
171 if particle.isPrimaryParticle():
172 hist.append(particle.getArrayIndex())
174 pdg[particle.getArrayIndex()] = particle.getPDG()
177 daughters = get_object_list(particle.getDaughters())
178 for daughter
in daughters:
206 Save Lowest Common Ancestor matrix of each MC Particle in the given list.
209 particle_lists (list): Name of particle lists to save features of.
210 features (list): List of features to save
for each particle.
211 mcparticle_list (str): Name of particle list to build LCAs
from (will use
as root).
212 output_file (str): Path to output file to save.
242 Called once at the beginning.
244 from ROOT
import Belle2, TFile, TTree
252 self.
tree = TTree(
"Tree",
"tree")
255 self.
event_num = np.zeros(1, dtype=np.int32)
258 self.
isB = np.zeros(1, dtype=bool)
266 self.
truth_dict[f
"n_LCA_leaves_{i}"] = np.zeros(1, dtype=np.int32)
267 self.
truth_dict[f
"LCA_leaves_{i}"] = np.zeros(
273 f
"n_LCA_leaves_{i}/I",
278 f
"LCA_leaves_{i}[n_LCA_leaves_{i}]/I",
281 self.
truth_dict[f
"n_LCA_{i}"] = np.zeros(1, dtype=np.int32)
285 self.
tree.Branch(f
"n_LCA_{i}", self.
truth_dict[f
"n_LCA_{i}"], f
"n_LCA_{i}/I")
287 f
"LCAS_{i}", self.
truth_dict[f
"LCAS_{i}"], f
"LCAS_{i}[n_LCA_{i}]/b"
297 self.
tree.Branch(
"primary", self.
primary,
"primary[n_particles]/O")
301 self.
tree.Branch(
"leaves", self.
leaves,
"leaves[n_particles]/I")
305 self.
tree.Branch(
"b_index", self.
b_index,
"b_index[n_particles]/I")
312 f
"feat_{feat}", self.
feat_dict[feat], f
"feat_{feat}[n_particles]/F"
317 self.
tree.Branch(
"mcPDG", self.
mc_pdg,
"mcPDG[n_particles]/F")
321 Resets the value of the LCA to 0.
323 for p_index
in [1, 2]:
325 self.
truth_dict[f
"n_LCA_leaves_{p_index}"][0] *= 0
331 Called for each event.
333 from ROOT
import Belle2
334 from ROOT.Belle2
import PyStoreObj
355 if p_list.getListSize() > 0:
356 for part
in p_list.obj():
358 mcp = part.getMCParticle()
363 array_index = 1
if self.
isB[0] == 0
else mcp.getArrayIndex()
382 lcas = np.zeros([len(lcas_leaf_hist), len(lcas_leaf_hist)])
384 for x, y
in combinations(enumerate(lcas_leaf_hist), 2):
385 lcas_intersection = [
386 i
for i
in lcas_leaf_hist[x[1]]
if i
in lcas_leaf_hist[y[1]]
388 lcas[x[0], y[0]] = lcas_levels[lcas_intersection[-1]]
389 lcas[y[0], x[0]] = lcas_levels[lcas_intersection[-1]]
391 self.
truth_dict[f
"LCAS_{array_index}"][: lcas.size] = lcas.flatten()
393 self.
truth_dict[f
"n_LCA_leaves_{array_index}"][0] = len(lcas_leaf_hist.keys())
395 : len(lcas_leaf_hist.keys())
396 ] = list(lcas_leaf_hist.keys())
398 self.
truth_dict[f
"n_LCA_{array_index}"][0] = lcas.size
402 evt_feats = {f: []
for f
in self.
features}
417 p_list = PyStoreObj(p_list_name)
419 for particle
in p_list.obj():
421 b_index = int(vm.evaluate(
"ancestorBIndex", particle))
424 p_index = particle.getMCParticle().getArrayIndex()
425 p_primary = particle.getMCParticle().isPrimaryParticle()
427 mc_pdg = particle.getMCParticle().getPDG()
433 evt_leaf_dict[
"primary"].append(p_primary)
434 evt_leaf_dict[
"leaves"].append(p_index)
435 evt_leaf_dict[
"b_index"].append(b_index)
436 evt_leaf_dict[
"mc_pdg"].append(mc_pdg)
438 evt_feats[feat].append(vm.evaluate(feat, particle))
440 n_particles = len(evt_leaf_dict[
"primary"])
443 self.
primary[:n_particles] = evt_leaf_dict[
"primary"]
444 self.
leaves[:n_particles] = evt_leaf_dict[
"leaves"]
445 self.
b_index[:n_particles] = evt_leaf_dict[
"b_index"]
446 self.
mc_pdg[:n_particles] = evt_leaf_dict[
"mc_pdg"]
449 self.
feat_dict[feat][:n_particles] = evt_feats[feat]
ParticleList is a container class that stores a collection of Particle objects.
a (simplified) python wrapper for StoreObjPtr.
primary
Particle-is-primary flag.
isB
bool containing information whether we reconstruct B or Upsilon
features
Features to save.
truth_dict
Truth information.
max_particles
Max number of particles It doesn't actually matter what this is as long as it's bigger than the numbe...
root_outfile
ROOT output file.
output_file
Output file name.
n_particles
Number of particles.
particle_lists
Input particle lists.
def __init__(self, particle_lists, features, mcparticle_list, output_file)
feat_dict
Features dictionary.
mcparticle_list
MC particle list (Upsilon, B0, B+)