Belle II Software development
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 295 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 307 of file core.py.

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

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 318 of file core.py.

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

Member Data Documentation

◆ config

config = config

config.FeiConfiguration object

Definition at line 316 of file core.py.

◆ particles

particles = particles

list of config.Particle objects

Definition at line 314 of file core.py.


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