Belle II Software light-2607-kasei
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 497 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 506 of file core.py.

506 def __init__(self, particles: typing.Sequence[config.Particle], config: config.FeiConfiguration):
507 """
508 Create a new PostReconstruction object
509 @param particles list of config.Particle objects
510 @param config config.FeiConfiguration object
511 """
512
513 self.particles = particles
514
515 self.config = config
516

Member Function Documentation

◆ available()

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

Definition at line 530 of file core.py.

530 def available(self) -> bool:
531 """
532 Check if the relevant information is already available
533 """
534 return len(self.get_missing_channels()) == 0
535

◆ get_missing_channels()

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

Definition at line 517 of file core.py.

517 def get_missing_channels(self) -> typing.Sequence[str]:
518 """
519 Returns all channels for which the weightfile is missing
520 """
521 missing = []
522 for particle in self.particles:
523 for channel in particle.channels:
524 # weightfile = self.config.prefix + '_' + channel.label
525 weightfile = f'{channel.label}.xml'
526 if not basf2_mva.available(weightfile):
527 missing += [channel.label]
528 return missing
529

◆ reconstruct()

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

Definition at line 536 of file core.py.

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

Member Data Documentation

◆ config

config = config

config.FeiConfiguration object

Definition at line 515 of file core.py.

◆ particles

particles = particles

list of config.Particle objects

Definition at line 513 of file core.py.


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