Belle II Software light-2607-kasei
PreReconstruction Class Reference

Public Member Functions

 __init__ (self, typing.Sequence[config.Particle] particles, config.FeiConfiguration config)
 
pybasf2.Path reconstruct (self)
 

Public Attributes

 particles = particles
 list of config.Particle objects
 
 config = config
 config.FeiConfiguration object
 

Detailed Description

Steers the reconstruction phase before the mva method was applied
It Includes:
    - The ParticleCombination (for each particle and channel we create candidates using
                               the daughter candidates from the previous stages)
    - MC Matching
    - Vertex Fitting (this is the slowest part of the whole FEI, KFit is used by default,
                      but you can use fastFit as a drop-in replacement https://github.com/thomaskeck/FastFit/,
                      this will speed up the whole FEI by a factor 2-3)

Definition at line 296 of file core.py.

Constructor & Destructor Documentation

◆ __init__()

__init__ ( self,
typing.Sequence[config.Particle] particles,
config.FeiConfiguration config )
Create a new PreReconstruction object
@param particles list of config.Particle objects
@param config config.FeiConfiguration object

Definition at line 308 of file core.py.

308 def __init__(self, particles: typing.Sequence[config.Particle], config: config.FeiConfiguration):
309 """
310 Create a new PreReconstruction object
311 @param particles list of config.Particle objects
312 @param config config.FeiConfiguration object
313 """
314
315 self.particles = particles
316
317 self.config = config
318

Member Function Documentation

◆ reconstruct()

pybasf2.Path reconstruct ( self)
Returns pybasf2.Path which reconstructs the particles and does the vertex fitting if necessary

Definition at line 319 of file core.py.

319 def reconstruct(self) -> pybasf2.Path:
320 """
321 Returns pybasf2.Path which reconstructs the particles and does the vertex fitting if necessary
322 """
323 path = basf2.create_path()
324
325 for particle in self.particles:
326 for channel in particle.channels:
327
328 if (len(channel.daughters) == 1) and (pdg.from_name(
329 channel.daughters[0].split(':')[0]) == pdg.from_name(particle.name)):
330 ma.cutAndCopyList(channel.name, channel.daughters[0], channel.preCutConfig.userCut, writeOut=True, path=path)
331 v2EI = basf2.register_module('VariablesToExtraInfo')
332 v2EI.set_name(f'VariablesToExtraInfo_{channel.name}')
333 v2EI.param('particleList', channel.name)
334 v2EI.param('variables', {f'constant({channel.decayModeID})': 'decayModeID'})
335 # suppress warning that decay mode ID won't be overwritten if it already exists
336 v2EI.set_log_level(basf2.logging.log_level.ERROR)
337 path.add_module(v2EI)
338 else:
339 ma.reconstructDecay(channel.decayString, channel.preCutConfig.userCut, channel.decayModeID,
340 writeOut=True, path=path)
341
342 # optionaly here we run custom modules, that users provide by themselves
343 # in the channels list (useful for testing custom variables)
344 if channel.extraPathSpec is not None:
345 spec = channel.extraPathSpec
346 mod = importlib.import_module(spec["module"])
347 registerFunc = getattr(mod, spec["function"])
348 registerFunc(path, channel.name, *spec["args"], **spec["kwargs"])
349
350 if self.config.monitor:
351 if "tag" in (channel.name).lower():
352 ma.matchTagTruth(channel.name, path=path)
353 else:
354 ma.matchMCTruth(channel.name, path=path)
355 bc_variable = channel.preCutConfig.bestCandidateVariable
356 if self.config.monitor == 'simple':
357 hist_variables = [channel.mvaConfig.target, 'extraInfo(decayModeID)']
358 hist_variables_2d = [(channel.mvaConfig.target, 'extraInfo(decayModeID)')]
359 else:
360 hist_variables = [bc_variable, 'mcErrors', 'mcParticleStatus',
361 channel.mvaConfig.target] + list(channel.mvaConfig.spectators.keys())
362 hist_variables_2d = [(bc_variable, channel.mvaConfig.target),
363 (bc_variable, 'mcErrors'),
364 (bc_variable, 'mcParticleStatus')]
365 for specVar in channel.mvaConfig.spectators:
366 hist_variables_2d.append((bc_variable, specVar))
367 hist_variables_2d.append((channel.mvaConfig.target, specVar))
368 filename = os.path.join(self.config.monitoring_path, 'Monitor_PreReconstruction_BeforeRanking.root')
369 ma.variablesToHistogram(
370 channel.name,
371 variables=config.variables2binnings(hist_variables),
372 variables_2d=config.variables2binnings_2d(hist_variables_2d),
373 filename=filename,
374 ignoreCommandLineOverride=True,
375 directory=f'{channel.label}',
376 path=path)
377
378 if channel.preCutConfig.bestCandidateMode == 'lowest':
379 ma.rankByLowest(channel.name,
380 channel.preCutConfig.bestCandidateVariable,
381 channel.preCutConfig.bestCandidateCut,
382 'preCut_rank',
383 path=path)
384 elif channel.preCutConfig.bestCandidateMode == 'highest':
385 ma.rankByHighest(channel.name,
386 channel.preCutConfig.bestCandidateVariable,
387 channel.preCutConfig.bestCandidateCut,
388 'preCut_rank',
389 path=path)
390 else:
391 raise RuntimeError(f'Unknown bestCandidateMode {repr(channel.preCutConfig.bestCandidateMode)}')
392
393 if 'gamma' in channel.decayString and channel.pi0veto:
394 ma.buildRestOfEvent(channel.name, path=path)
395 Ddaughter_roe_path = basf2.Path()
396 deadEndPath = basf2.Path()
397 ma.signalSideParticleFilter(channel.name, '', Ddaughter_roe_path, deadEndPath)
398 ma.fillParticleList('gamma:roe', 'isInRestOfEvent == 1', path=Ddaughter_roe_path)
399
400 matches = list(re.finditer('gamma', channel.decayString))
401 pi0lists = []
402 for igamma in range(len(matches)):
403 start, end = matches[igamma-1].span()
404 tempString = f'{channel.decayString[:start]}^gamma{channel.decayString[end:]}'
405 ma.fillSignalSideParticleList(f'gamma:sig_{igamma}', tempString, path=Ddaughter_roe_path)
406 ma.reconstructDecay(f'pi0:veto_{igamma} -> gamma:sig_{igamma} gamma:roe', '', path=Ddaughter_roe_path)
407 pi0lists.append(f'pi0:veto_{igamma}')
408 ma.copyLists('pi0:veto', pi0lists, writeOut=False, path=Ddaughter_roe_path)
409 ma.rankByLowest('pi0:veto', 'abs(dM)', 1, path=Ddaughter_roe_path)
410 ma.matchMCTruth('pi0:veto', path=Ddaughter_roe_path)
411 ma.variableToSignalSideExtraInfo(
412 'pi0:veto',
413 {
414 'InvM': 'pi0vetoMass',
415 'formula((daughter(0,E)-daughter(1,E))/(daughter(0,E)+daughter(1,E)))': 'pi0vetoEneAsy',
416 'cosHelicityAngleMomentum': 'pi0vetoCosHelMom',
417 },
418 path=Ddaughter_roe_path
419 )
420 path.for_each('RestOfEvent', 'RestOfEvents', Ddaughter_roe_path)
421
422 if self.config.monitor:
423 filename = os.path.join(self.config.monitoring_path, 'Monitor_PreReconstruction_AfterRanking.root')
424 if self.config.monitor != 'simple':
425 hist_variables += ['extraInfo(preCut_rank)']
426 hist_variables_2d += [('extraInfo(preCut_rank)', channel.mvaConfig.target),
427 ('extraInfo(preCut_rank)', 'mcErrors'),
428 ('extraInfo(preCut_rank)', 'mcParticleStatus')]
429 for specVar in channel.mvaConfig.spectators:
430 hist_variables_2d.append(('extraInfo(preCut_rank)', specVar))
431 ma.variablesToHistogram(
432 channel.name,
433 variables=config.variables2binnings(hist_variables),
434 variables_2d=config.variables2binnings_2d(hist_variables_2d),
435 filename=filename,
436 ignoreCommandLineOverride=True,
437 directory=f'{channel.label}',
438 path=path)
439 # If we are not in monitor mode we do the mc matching now,
440 # otherwise we did it above already!
441 elif self.config.training:
442 if "tag" in (channel.name).lower():
443 ma.matchTagTruth(channel.name, path=path)
444 else:
445 ma.matchMCTruth(channel.name, path=path)
446
447 if b2bii.isB2BII() and particle.name in ['K_S0', 'Lambda0']:
448 pvfit = basf2.register_module('ParticleVertexFitter')
449 pvfit.set_name(f'ParticleVertexFitter_{channel.name}')
450 pvfit.param('listName', channel.name)
451 pvfit.param('confidenceLevel', channel.preCutConfig.vertexCut)
452 pvfit.param('vertexFitter', 'KFit')
453 pvfit.param('fitType', 'vertex')
454 pvfit.set_log_level(basf2.logging.log_level.ERROR) # let's not produce gigabytes of uninteresting warnings
455 path.add_module(pvfit)
456 elif re.findall(r"[\w']+", channel.decayString).count('pi0') > 1 and particle.name != 'pi0':
457 basf2.B2INFO(f"Ignoring vertex fit for {channel.name} because multiple pi0 are not supported yet.")
458 elif len(channel.daughters) > 1:
459 pvfit = basf2.register_module('ParticleVertexFitter')
460 pvfit.set_name(f'ParticleVertexFitter_{channel.name}')
461 pvfit.param('listName', channel.name)
462 pvfit.param('confidenceLevel', channel.preCutConfig.vertexCut)
463 pvfit.param('vertexFitter', 'KFit')
464 if particle.name in ['pi0']:
465 pvfit.param('fitType', 'mass')
466 else:
467 pvfit.param('fitType', 'vertex')
468 pvfit.set_log_level(basf2.logging.log_level.ERROR) # let's not produce gigabytes of uninteresting warnings
469 path.add_module(pvfit)
470
471 if self.config.monitor:
472 if self.config.monitor == 'simple':
473 hist_variables = [channel.mvaConfig.target, 'extraInfo(decayModeID)']
474 hist_variables_2d = [(channel.mvaConfig.target, 'extraInfo(decayModeID)')]
475 else:
476 hist_variables = ['chiProb', 'mcErrors', 'mcParticleStatus',
477 channel.mvaConfig.target] + list(channel.mvaConfig.spectators.keys())
478 hist_variables_2d = [('chiProb', channel.mvaConfig.target),
479 ('chiProb', 'mcErrors'),
480 ('chiProb', 'mcParticleStatus')]
481 for specVar in channel.mvaConfig.spectators:
482 hist_variables_2d.append(('chiProb', specVar))
483 hist_variables_2d.append((channel.mvaConfig.target, specVar))
484 filename = os.path.join(self.config.monitoring_path, 'Monitor_PreReconstruction_AfterVertex.root')
485 ma.variablesToHistogram(
486 channel.name,
487 variables=config.variables2binnings(hist_variables),
488 variables_2d=config.variables2binnings_2d(hist_variables_2d),
489 filename=filename,
490 ignoreCommandLineOverride=True,
491 directory=f'{channel.label}',
492 path=path)
493
494 return path
495
496
isB2BII()
Definition b2bii.py:14
from_name(name)
Definition pdg.py:63

Member Data Documentation

◆ config

config = config

config.FeiConfiguration object

Definition at line 317 of file core.py.

◆ particles

particles = particles

list of config.Particle objects

Definition at line 315 of file core.py.


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