Belle II Software development
PostReconstruction Class Reference

Public Member Functions

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

Public Attributes

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

Detailed Description

Steers the reconstruction phase after the mva method was applied
It Includes:
    - The application of the mva method itself.
    - Copying all channel lists in a common one for each particle defined in particles
    - Tag unique signal candidates, to avoid double counting of channels with overlap

Definition at line 480 of file core.py.

Constructor & Destructor Documentation

◆ __init__()

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

Definition at line 489 of file core.py.

489 def __init__(self, particles: typing.Sequence[config.Particle], config: config.FeiConfiguration):
490 """
491 Create a new PostReconstruction object
492 @param particles list of config.Particle objects
493 @param config config.FeiConfiguration object
494 """
495
496 self.particles = particles
497
498 self.config = config
499

Member Function Documentation

◆ available()

bool available ( self)
Check if the relevant information is already available

Definition at line 513 of file core.py.

513 def available(self) -> bool:
514 """
515 Check if the relevant information is already available
516 """
517 return len(self.get_missing_channels()) == 0
518

◆ get_missing_channels()

typing.Sequence[str] get_missing_channels ( self)
Returns all channels for which the weightfile is missing

Definition at line 500 of file core.py.

500 def get_missing_channels(self) -> typing.Sequence[str]:
501 """
502 Returns all channels for which the weightfile is missing
503 """
504 missing = []
505 for particle in self.particles:
506 for channel in particle.channels:
507 # weightfile = self.config.prefix + '_' + channel.label
508 weightfile = f'{channel.label}.xml'
509 if not basf2_mva.available(weightfile):
510 missing += [channel.label]
511 return missing
512

◆ reconstruct()

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

Definition at line 519 of file core.py.

519 def reconstruct(self) -> pybasf2.Path:
520 """
521 Returns pybasf2.Path which reconstructs the particles and does the vertex fitting if necessary
522 """
523 import ROOT # noqa
524 path = basf2.create_path()
525
526 for particle in self.particles:
527 for channel in particle.channels:
528 expert = basf2.register_module('MVAExpert')
529 expert.set_name(f'MVAExpert_{channel.name}')
530 if self.config.training:
531 expert.param('identifier', f'{channel.label}.xml')
532 else:
533 expert.param('identifier', f'{self.config.prefix}_{channel.label}')
534 expert.param('extraInfoName', 'SignalProbability')
535 expert.param('listNames', [channel.name])
536 # suppress warning that signal probability won't be overwritten if it already exists
537 expert.set_log_level(basf2.logging.log_level.ERROR)
538 path.add_module(expert)
539
540 if self.config.monitor:
541 if self.config.monitor == 'simple':
542 hist_variables = [channel.mvaConfig.target, 'extraInfo(decayModeID)']
543 hist_variables_2d = [(channel.mvaConfig.target, 'extraInfo(decayModeID)')]
544 else:
545 hist_variables = ['mcErrors',
546 'mcParticleStatus',
547 'extraInfo(SignalProbability)',
548 channel.mvaConfig.target,
549 'extraInfo(decayModeID)'] + list(channel.mvaConfig.spectators.keys())
550 hist_variables_2d = [('extraInfo(SignalProbability)', channel.mvaConfig.target),
551 ('extraInfo(SignalProbability)', 'mcErrors'),
552 ('extraInfo(SignalProbability)', 'mcParticleStatus'),
553 ('extraInfo(decayModeID)', channel.mvaConfig.target),
554 ('extraInfo(decayModeID)', 'mcErrors'),
555 ('extraInfo(decayModeID)', 'mcParticleStatus')]
556 for specVar in channel.mvaConfig.spectators:
557 hist_variables_2d.append(('extraInfo(SignalProbability)', specVar))
558 hist_variables_2d.append(('extraInfo(decayModeID)', specVar))
559 hist_variables_2d.append((channel.mvaConfig.target, specVar))
560 filename = os.path.join(self.config.monitoring_path, 'Monitor_PostReconstruction_AfterMVA.root')
561 ma.variablesToHistogram(
562 channel.name,
563 variables=config.variables2binnings(hist_variables),
564 variables_2d=config.variables2binnings_2d(hist_variables_2d),
565 filename=filename,
566 ignoreCommandLineOverride=True,
567 directory=f'{channel.label}',
568 path=path)
569
570 cutstring = ''
571 if particle.postCutConfig.value > 0.0:
572 cutstring = f'{particle.postCutConfig.value} < extraInfo(SignalProbability)'
573
574 ma.mergeListsWithBestDuplicate(particle.identifier, [c.name for c in particle.channels],
575 variable='particleSource', writeOut=True, path=path)
576
577 if self.config.monitor:
578 if self.config.monitor == 'simple':
579 hist_variables = [particle.mvaConfig.target, 'extraInfo(decayModeID)']
580 hist_variables_2d = [(particle.mvaConfig.target, 'extraInfo(decayModeID)')]
581 else:
582 hist_variables = ['mcErrors',
583 'mcParticleStatus',
584 'extraInfo(SignalProbability)',
585 particle.mvaConfig.target,
586 'extraInfo(decayModeID)'] + list(particle.mvaConfig.spectators.keys())
587 hist_variables_2d = [('extraInfo(decayModeID)', particle.mvaConfig.target),
588 ('extraInfo(decayModeID)', 'mcErrors'),
589 ('extraInfo(decayModeID)', 'mcParticleStatus')]
590 for specVar in particle.mvaConfig.spectators:
591 hist_variables_2d.append(('extraInfo(SignalProbability)', specVar))
592 hist_variables_2d.append(('extraInfo(decayModeID)', specVar))
593 hist_variables_2d.append((particle.mvaConfig.target, specVar))
594 filename = os.path.join(self.config.monitoring_path, 'Monitor_PostReconstruction_BeforePostCut.root')
595 ma.variablesToHistogram(
596 particle.identifier,
597 variables=config.variables2binnings(hist_variables),
598 variables_2d=config.variables2binnings_2d(hist_variables_2d),
599 filename=filename,
600 ignoreCommandLineOverride=True,
601 directory=config.removeJPsiSlash(f'{particle.identifier}'),
602 path=path)
603
604 ma.applyCuts(particle.identifier, cutstring, path=path)
605
606 if self.config.monitor:
607 filename = os.path.join(self.config.monitoring_path, 'Monitor_PostReconstruction_BeforeRanking.root')
608 ma.variablesToHistogram(
609 particle.identifier,
610 variables=config.variables2binnings(hist_variables),
611 variables_2d=config.variables2binnings_2d(hist_variables_2d),
612 filename=filename,
613 ignoreCommandLineOverride=True,
614 directory=config.removeJPsiSlash(f'{particle.identifier}'),
615 path=path)
616
617 ma.rankByHighest(particle.identifier, 'extraInfo(SignalProbability)',
618 particle.postCutConfig.bestCandidateCut, 'postCut_rank', path=path)
619
620 uniqueSignal = basf2.register_module('TagUniqueSignal')
621 uniqueSignal.param('particleList', particle.identifier)
622 uniqueSignal.param('target', particle.mvaConfig.target)
623 uniqueSignal.param('extraInfoName', 'uniqueSignal')
624 uniqueSignal.set_name(f'TagUniqueSignal_{particle.identifier}')
625 # suppress warning that unique signal extra info won't be overwritten if it already exists
626 uniqueSignal.set_log_level(basf2.logging.log_level.ERROR)
627 path.add_module(uniqueSignal)
628
629 if self.config.monitor:
630 if self.config.monitor != 'simple':
631 hist_variables += ['extraInfo(postCut_rank)']
632 hist_variables_2d += [('extraInfo(decayModeID)', 'extraInfo(postCut_rank)'),
633 (particle.mvaConfig.target, 'extraInfo(postCut_rank)'),
634 ('mcErrors', 'extraInfo(postCut_rank)'),
635 ('mcParticleStatus', 'extraInfo(postCut_rank)')]
636 for specVar in particle.mvaConfig.spectators:
637 hist_variables_2d.append(('extraInfo(postCut_rank)', specVar))
638 filename = os.path.join(self.config.monitoring_path, 'Monitor_PostReconstruction_AfterRanking.root')
639 ma.variablesToHistogram(
640 particle.identifier,
641 variables=config.variables2binnings(hist_variables),
642 variables_2d=config.variables2binnings_2d(hist_variables_2d),
643 filename=filename,
644 ignoreCommandLineOverride=True,
645 directory=config.removeJPsiSlash(f'{particle.identifier}'),
646 path=path)
647
648 filename = os.path.join(self.config.monitoring_path, 'Monitor_Final.root')
649 if self.config.monitor == 'simple':
650 hist_variables = ['extraInfo(uniqueSignal)', 'extraInfo(decayModeID)']
651 hist_variables_2d = [('extraInfo(uniqueSignal)', 'extraInfo(decayModeID)')]
652 ma.variablesToHistogram(
653 particle.identifier,
654 variables=config.variables2binnings(hist_variables),
655 variables_2d=config.variables2binnings_2d(hist_variables_2d),
656 filename=filename,
657 ignoreCommandLineOverride=True,
658 directory=config.removeJPsiSlash(f'{particle.identifier}'),
659 path=path)
660 else:
661 variables = ['extraInfo(SignalProbability)', 'mcErrors', 'mcParticleStatus', particle.mvaConfig.target,
662 'extraInfo(uniqueSignal)', 'extraInfo(decayModeID)'] + list(particle.mvaConfig.spectators.keys())
663
664 ma.variablesToNtuple(
665 particle.identifier,
666 variables,
667 treename=ROOT.Belle2.MakeROOTCompatible.makeROOTCompatible(
668 config.removeJPsiSlash(f'{particle.identifier} variables')),
669 filename=filename,
670 ignoreCommandLineOverride=True,
671 path=path)
672 return path
673
674

Member Data Documentation

◆ config

config = config

config.FeiConfiguration object

Definition at line 498 of file core.py.

◆ particles

particles = particles

list of config.Particle objects

Definition at line 496 of file core.py.


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