Belle II Software development
DecayParticleNode Class Reference

Public Member Functions

def __init__ (self, name)
 
def get_prefixes (self, always_include_indices=False, use_relative_indices=False)
 
def build (cls, decay_string)
 

Public Attributes

 name
 name of the particle
 
 selected
 whether or not this particle is selected
 
 children
 mapping of children decayIndex->Node
 

Private Member Functions

def __walk (self, always_include_indices, use_relative_indices, current_prefix, current_path)
 

Detailed Description

Class to present selected particles from a DecayString as tree structure.
For each node of the tree we safe the name of the particle, whether it is
selected and a dictionary of all children (as mapping decayIndex -> Node)

Definition at line 170 of file utils.py.

Constructor & Destructor Documentation

◆ __init__()

def __init__ (   self,
  name 
)
Just set default values

Definition at line 177 of file utils.py.

177 def __init__(self, name):
178 """Just set default values"""
179
180 self.name = name
181
182 self.selected = False
183
184 self.children = {}
185

Member Function Documentation

◆ __walk()

def __walk (   self,
  always_include_indices,
  use_relative_indices,
  current_prefix,
  current_path 
)
private
Recursively walk the tree and collect all prefixes

See:
    `get_prefixes`

Arguments:
    always_include_indices (bool): see `get_prefixes()`
    use_relative_indices (bool): see `get_prefixes()`
    current_prefix: the current prefix so far collected from any parent
        particle.
    current_path: the current path of indices so far collected from any
        parent particle.

Definition at line 217 of file utils.py.

217 def __walk(self, always_include_indices, use_relative_indices, current_prefix, current_path):
218 """Recursively walk the tree and collect all prefixes
219
220 See:
221 `get_prefixes`
222
223 Arguments:
224 always_include_indices (bool): see `get_prefixes()`
225 use_relative_indices (bool): see `get_prefixes()`
226 current_prefix: the current prefix so far collected from any parent
227 particle.
228 current_path: the current path of indices so far collected from any
229 parent particle.
230 """
231
232 result = []
233 # are we the mother particle and selected selected? if so, add a "no-prefix" to the output
234 if not current_path and self.selected:
235 result.append(("", None))
236
237 # count the particle names of all daughters so that we know which ones we
238 # have to index
239 names = collections.Counter(e.name for e in self.children.values())
240 # if we use relative indices start counting them at zero
241 relative_indices = collections.defaultdict(int)
242
243 # now loop over all children
244 for index, c in sorted(self.children.items()):
245 # prepare the full index path
246 full_path = current_path + (index,)
247 # and prepare the prefix
248 prefix = current_prefix + c.name
249 # is this particle name ambiguous or are all indices requested? add index
250 if always_include_indices or names[c.name] > 1:
251 prefix += f"_{relative_indices[c.name] if use_relative_indices else index}"
252 # always increase the relative indices
253 relative_indices[c.name] += 1
254
255 # if the particle is selected add the prefix and the path
256 if c.selected:
257 result.append((prefix, full_path))
258
259 # but in any case also process all children recursively
260 result += c.__walk(always_include_indices, use_relative_indices, prefix + "_", full_path)
261
262 # done, return all prefixes and their paths
263 return result
264

◆ build()

def build (   cls,
  decay_string 
)
Build a tree of selected particles from a `DecayString`

This will return a `DecayParticleNode` instance which is the top of a
tree of all the selected particles from the decat string.

Arguments:
    decay_string (str): `DecayString` containing at least one selected particle

Definition at line 266 of file utils.py.

266 def build(cls, decay_string):
267 """Build a tree of selected particles from a `DecayString`
268
269 This will return a `DecayParticleNode` instance which is the top of a
270 tree of all the selected particles from the decat string.
271
272 Arguments:
273 decay_string (str): `DecayString` containing at least one selected particle
274 """
275 selected = get_hierarchy_of_decay(decay_string)
276 if not selected:
277 raise ValueError("No particle selected in decay string")
278 # create the top of the tree
279 top = cls("")
280 # now loop over all selected particles
281 for path in selected:
282 current = top
283 # and walk through the path
284 for index, name in path:
285 # creating tree children as needed
286 if index not in current.children:
287 current.children[index] = cls(name)
288 # and update the pointer
289 current = current.children[index]
290 # after walking the tree the pointer is at the selected particle so
291 # just set the selected to True
292 current.selected = True
293
294 # done, return the tree
295 return top
296
297

◆ get_prefixes()

def get_prefixes (   self,
  always_include_indices = False,
  use_relative_indices = False 
)
Recursively walk through the tree of selected particles and return a list
of prefixes for aliases and a tuple of decay indexes for that prefix.

For example for ``B0 -> [D0 -> ^pi+] ^pi0`` it might return

>>> DecayParticleNode.build('^B0 -> [D0 -> ^pi+] ^pi0').get_prefixes()
[ ("", None), ("D0_pi", (0, 0)), ("pi0", (1,)) ]

and to create aliases from these one would use the indices as arguments for
the b2:var:`daughter` meta variable.

This function will make sure that prefix names are unique: If there are
multiple siblings of one node with the same particle name they will be
distinguished by either suffixing them with the decay index (if
``use_relative_indices=False``) or they will just be enumerated
starting at 0 otherwise.

Arguments:
    always_include_indices (bool): If True always add the index of the
        particle to the prefix, otherwise the index is only added if
        more than one sibling of the same particle exist.
    use_relative_indices (bool): If True the indices used will **not**
        be the daughter indices in the full decay string but just the
        relative indices: If multiple sibling particles with the same
        name they will be just numbered starting at zero as they appear
        in the aliases.

Definition at line 186 of file utils.py.

186 def get_prefixes(self, always_include_indices=False, use_relative_indices=False):
187 """
188 Recursively walk through the tree of selected particles and return a list
189 of prefixes for aliases and a tuple of decay indexes for that prefix.
190
191 For example for ``B0 -> [D0 -> ^pi+] ^pi0`` it might return
192
193 >>> DecayParticleNode.build('^B0 -> [D0 -> ^pi+] ^pi0').get_prefixes()
194 [ ("", None), ("D0_pi", (0, 0)), ("pi0", (1,)) ]
195
196 and to create aliases from these one would use the indices as arguments for
197 the b2:var:`daughter` meta variable.
198
199 This function will make sure that prefix names are unique: If there are
200 multiple siblings of one node with the same particle name they will be
201 distinguished by either suffixing them with the decay index (if
202 ``use_relative_indices=False``) or they will just be enumerated
203 starting at 0 otherwise.
204
205 Arguments:
206 always_include_indices (bool): If True always add the index of the
207 particle to the prefix, otherwise the index is only added if
208 more than one sibling of the same particle exist.
209 use_relative_indices (bool): If True the indices used will **not**
210 be the daughter indices in the full decay string but just the
211 relative indices: If multiple sibling particles with the same
212 name they will be just numbered starting at zero as they appear
213 in the aliases.
214 """
215 return self.__walk(always_include_indices, use_relative_indices, "", tuple())
216

Member Data Documentation

◆ children

children

mapping of children decayIndex->Node

Definition at line 184 of file utils.py.

◆ name

name

name of the particle

Definition at line 180 of file utils.py.

◆ selected

selected

whether or not this particle is selected

Definition at line 182 of file utils.py.


The documentation for this class was generated from the following file: