def create_path(self):
     path = basf2.create_path()
     modularAnalysis.inputMdstList(
         'default',
         self.get_input_file_names("reconstructed_output.root"),
         path=path)
     modularAnalysis.fillParticleLists([('K+', 'kaonID > 0.1'),
                                        ('pi+', 'pionID > 0.1')],
                                       path=path)
     modularAnalysis.reconstructDecay('D0 -> K- pi+',
                                      '1.7 < M < 1.9',
                                      path=path)
     modularAnalysis.matchMCTruth('D0', path=path)
     modularAnalysis.reconstructDecay('B- -> D0 pi-',
                                      '5.2 < Mbc < 5.3',
                                      path=path)
     try:  # treeFit is the new function name in light releases after release 4 (e.g. light-2002-janus)
         vertex.treeFit('B+', 0.1, update_all_daughters=True, path=path)
     except AttributeError:  # vertexTree is the function name in release 4
         vertex.vertexTree('B+', 0.1, update_all_daughters=True, path=path)
     modularAnalysis.matchMCTruth('B-', path=path)
     modularAnalysis.variablesToNtuple(
         'D0', [
             'M', 'p', 'E', 'useCMSFrame(p)', 'useCMSFrame(E)',
             'daughter(0, kaonID)', 'daughter(1, pionID)', 'isSignal',
             'mcErrors'
         ],
         filename=self.get_output_file_name("D_n_tuple.root"),
         path=path)
     modularAnalysis.variablesToNtuple(
         'B-', ['Mbc', 'deltaE', 'isSignal', 'mcErrors', 'M'],
         filename=self.get_output_file_name("B_n_tuple.root"),
         path=path)
     return path
def create_analysis_path(
        b_ntuple_filename="B_ntuple.root",
        d_ntuple_filename="D_ntuple.root",
        mbc_range=(5.2, 5.3),
):
    """
    Example of a minimal reconstruction with a cut as a changeable function
    parameter, adapted from code in the ``B2T_Basics_3_FirstAnalysis.ipynb``
    notebook from b2 starter kit.
    """
    path = basf2.create_path()
    # this local inputMdstList will only be used when this steerig file is run locally, gbasf2 overrides it
    local_input_files = [
        "/group/belle2/dataprod/MC/MC13a/prod00009434/s00/e1003/4S/r00000/mixed/mdst/sub00/mdst_000001_prod00009434_task10020000001.root"
    ]
    mA.inputMdstList(
        environmentType="default",
        filelist=local_input_files,
        path=path,
    )
    stdK("higheff", path=path)
    stdPi("higheff", path=path)
    mA.reconstructDecay('D0:Kpi -> K-:higheff pi+:higheff',
                        '1.7 < M < 1.9',
                        path=path)
    # use try except to have this code work for both the old and new function names for the tree fit
    mA.matchMCTruth('D0:Kpi', path=path)
    mA.reconstructDecay('B- -> D0:Kpi pi-:higheff',
                        f"{mbc_range[0]} < Mbc < {mbc_range[1]}",
                        path=path)
    try:
        vx.treeFit('B+', 0.1, path=path)
    except AttributeError:
        vx.vertexTree('B+', 0.1, path=path)
    mA.setAnalysisConfigParams({"mcMatchingVersion": "BelleII"}, path)
    mA.matchMCTruth('B-', path=path)
    vm.addAlias("p_cms",
                "useCMSFrame(p)")  # include aliases to test if they work
    vm.addAlias("E_cms", "useCMSFrame(E)")
    mA.variablesToNtuple('D0:Kpi', [
        'M', 'p', 'E', 'E_cms', 'p_cms', 'daughter(0, kaonID)',
        'daughter(1, pionID)', 'isSignal', 'mcErrors'
    ],
                         filename=d_ntuple_filename,
                         treename="D",
                         path=path)
    mA.variablesToNtuple('B-', ['Mbc', 'deltaE', 'isSignal', 'mcErrors', 'M'],
                         filename=b_ntuple_filename,
                         treename="B",
                         path=path)
    return path
va.variables.addAlias('pi_p_rank', 'extraInfo(pi_p_rank)')

# creates "K+:loose" ParticleList (and c.c.)
stdc.stdK(listtype='loose', path=my_path)

# keep only candidates with 1.8 < M(Kpi) < 1.9 GeV
ma.reconstructDecay(decayString='D0 -> K-:loose pi+:all',
                    cut='1.8 < M < 1.9',
                    path=my_path)

# perform D0 vertex fit
# keep candidates only passing C.L. value of the fit > 0.0 (no cut)
vx.vertexTree(
    list_name='D0',
    conf_level=
    -1,  # keep all cadidates, 0:keep only fit survivors, optimise this cut for your need
    ipConstraint=True,
    # pins the B0 PRODUCTION vertex to the IP (increases SIG and BKG rejection) use for better vertex resolution
    updateAllDaughters=True,  # update momenta off ALL particles
    path=my_path)

# smaller |M_rec - M| is better, add here a different output variable name, due to parentheses
ma.rankByLowest(particleList='D0',
                variable='abs(dM)',
                outputVariable='abs_dM_rank',
                path=my_path)

# maybe not the best idea, but might cut away candidates with failed fits
ma.rankByHighest(particleList='D0', variable='chiProb', path=my_path)

# Now let's do mixed ranking:
# First, we want to rank D candiadtes by the momentum of the pions