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

495 def __init__(self, particles: typing.Sequence[config.Particle], config: config.FeiConfiguration):
496 """
497 Create a new PostReconstruction object
498 @param particles list of config.Particle objects
499 @param config config.FeiConfiguration object
500 """
501
502 self.particles = particles
503
504 self.config = config
505

Member Function Documentation

◆ available()

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

Definition at line 519 of file core.py.

519 def available(self) -> bool:
520 """
521 Check if the relevant information is already available
522 """
523 return len(self.get_missing_channels()) == 0
524

◆ get_missing_channels()

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

Definition at line 506 of file core.py.

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

◆ reconstruct()

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

Definition at line 525 of file core.py.

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

Member Data Documentation

◆ config

config = config

config.FeiConfiguration object

Definition at line 504 of file core.py.

◆ particles

particles = particles

list of config.Particle objects

Definition at line 502 of file core.py.


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