def reconstructLambda(outlist, match=False, only=None, path=None): """Reconstruct Lambda based on Lambda0:mdst outlist: Output particle list name. You can use for example 'Lambda0:belle' match: Perform MC truth match or not only: If only == 'signal', then only keep matched signal If only == 'background', then only keep background Otherwise, no further cuts. This option is for generating balanced training samples """ if path == None: raise Exception('Path cannot be None!') if outlist == 'Lambda0:mdst': raise Exception('outlist name cannot be Lambda0:mdst') inlist = 'Lambda0:mdst' ma.vertexTree(inlist, path=path) if match: ma.matchMCTruth(inlist, path=path) if only == 'signal': ma.cutAndCopyList(outlist, inlist, 'isSignal == 1', path=path) elif only == 'background': ma.cutAndCopyList(outlist, inlist, 'isSignal == 0', path=path) else: ma.cutAndCopyList(outlist, inlist, '', path=path)
def stdSigmas(listtype='std', gammatype='pi0eff50', path=None): """ Load standard ``Sigma+`` reconstructed from ``Sigma+ -> p+ [pi0 -> gamma gamma]```. The ``pi0`` is reconstructed using the specified gamma list and ``pi0``s in mass range ``100 ~ 160 MeV`` are combined the with protons from ``p+:loose`` list to form a ``Sigma+``. Tree fitter is used for the vertex fit with IP constraint and mass constraint on the ``pi0``. The particle list is named ``Sigma+:std`` with mass range ``1.66 ~ 1.22 GeV``. Parameters: gamma_type (str): the gamma list to use path (basf2.path): path to load the particle list """ stdPhotons(gammatype, path=path) stdPr('loose', path=path) ma.reconstructDecay( f'pi0:for_sigma -> gamma:{gammatype} gamma:{gammatype}', '0.1 < M < 0.16', path=path) ma.reconstructDecay('Sigma+:std -> p+:loose pi0:for_sigma', '1.1 < M < 1.3', path=path) ma.vertexTree('Sigma+:std', 0, ipConstraint=True, massConstraint=[111], updateAllDaughters=False, path=path) ma.applyCuts('Sigma+:std', '1.16 < M < 1.22', path=path) if listtype == 'std': pass elif listtype == 'loose': vtx_cuts = 'cosaXY > 0.99 and dr > 0.12 and abs(dz) > 0.1 and chiProb > 0.001' ma.cutAndCopyList('Sigma+:loose', 'Sigma+:std', vtx_cuts, path=path) else: B2ERROR( f'stdSigmas: Invalid listtype ({listtype}. Choose from std, loose.' )
'gamma1_theta', 'gamma2_theta', 'gamma1_E', 'gamma2_E' ] ntuple_vars = sigma_vars + proton_vars + pi0_vars + gamma_vars + event_vars # Reconstruction # ============================================== # Standard PID cuts for charged final state particles ma.fillParticleList('p+:good', 'pid_ppi >= 0.6 and pid_pk >= 0.6', path=mp) ma.reconstructDecay('Sigma+:loose -> p+:good pi0:mdst', 'M >= 1.0 and M <= 1.4', path=mp) ## !!! Have to set updateAllDaughters = True because the pi0:mdst list is mass constrained ma.vertexTree('Sigma+:loose', 0, ipConstraint=True, updateAllDaughters=True, path=mp) ma.applyCuts('Sigma+:loose', 'M >= 1.1 and M <= 1.3', path=mp) # ma.matchMCTruth('Sigma+:loose', path = mp) # mp.add_module('VariablesToNtuple', particleList = 'Sigma+:loose', # variables=ntuple_vars, treeName='sigma_loose', fileName=sys.argv[2]) # Eff of this cut is about 96% and rejects about 50% of the background for Sigma+ pi0_mass_cut = 'daughter(1, M) >= 0.12 and daughter(1, M) <= 0.15' ma.cutAndCopyList('Sigma+:good', 'Sigma+:loose', pi0_mass_cut, path=mp) ma.vertexTree('Sigma+:good', 0, ipConstraint=True, massConstraint=[], updateAllDaughters=False,
ma.cutAndCopyList('p+:berger', 'p+:all', 'pid_ppi > 0.6 and pid_pk > 0.6', path=mp) # M Berger: photons > 40 MeV and pi0 lab frame momentum > 100 MeV ma.cutAndCopyList( 'pi0:berger', 'pi0:mdst', 'daughter(0, E) > 0.05 and daughter(0, E) > 0.05 and p > 0.1', path=mp) ma.reconstructDecay('Sigma+:berger_loose -> p+:berger pi0:berger', 'M >= 1.0 and M <= 1.4', path=mp) # Set updateAllDaughters = True because the pi0:mdst list is mass constrained ma.vertexTree('Sigma+:berger_loose', 0, ipConstraint=True, massConstraint=[111], path=mp) # M Berger: discard condidates with wrong sign of flight distance ma.applyCuts('Sigma+:berger_loose', 'M >= 1.15 and M <= 1.225', path=mp) ma.matchMCTruth('Sigma+:berger_loose', path=mp) mp.add_module('VariablesToNtuple', particleList='Sigma+:berger_loose', variables=ntuple_vars, treeName='sigma_loose', fileName=sys.argv[2]) b2.process(path=mp) print(b2.statistics)
'Sigma+ -> p+ [pi0 -> ^gamma ^gamma]', prefix = ['gamma1', 'gamma2']) # variables.addAlias('gamma_min_E', 'min(gamma1_E, gamma2_E)') # variables.addAlias('gamma_phi_diff', 'abs(formula(gamma1_phi - gamma2_phi))') # variables.addAlias('gamma_theta_diff', 'abs(formula(gamma1_theta - gamma2_theta))') # variables.addAlias('gamma_E_asym', 'abs(formula((gamma1_E - gamma2_E) / (gamma1_E + gamma2_E)))') # gamma_vars += ['gamma_min_E', 'gamma_phi_diff', 'gamma_theta_diff', 'gamma_E_asym', 'gamma1_theta', 'gamma2_theta', # 'gamma1_E', 'gamma2_E'] gamma_vars += ['gamma1_E', 'gamma2_E', 'gamma1_theta', 'gamma2_theta', 'genMotherPDG', 'isSignal'] ntuple_vars = sigma_vars + proton_vars + pi0_vars + gamma_vars + event_vars # RECONSTRUCTION # ============================================== ma.fillParticleList('p+:all', '', path = mp) # M Berger: standard pairwise PID > 0.6 and impact parameter > 0.003 ma.cutAndCopyList('p+:berger', 'p+:all', 'pid_ppi > 0.6 and pid_pk > 0.6 and dr > 0.003', path = mp) # M Berger: photons > 40 MeV and pi0 lab frame momentum > 100 MeV ma.cutAndCopyList('pi0:berger', 'pi0:mdst', 'daughter(0, E) > 0.04 and daughter(0, E) > 0.04 and p > 0.1', path = mp) ma.reconstructDecay('Sigma+:berger_loose -> p+:berger pi0:berger', 'M >= 1.0 and M <= 1.4', path = mp) # Set updateAllDaughters = True because the pi0:mdst list is mass constrained ma.vertexTree('Sigma+:berger_loose', 0, ipConstraint = True, updateAllDaughters = True, path = mp) # M Berger: discard condidates with wrong sign of flight distance ma.applyCuts('Sigma+:berger_loose', 'M >= 1.1 and M <= 1.3', path = mp) ma.matchMCTruth('Sigma+:berger_loose', path = mp) mp.add_module('VariablesToNtuple', particleList = 'Sigma+:berger_loose', variables=ntuple_vars, treeName='sigma_loose', fileName=sys.argv[2]) b2.process(path=mp) print(b2.statistics)
va.addAlias('abs_dr', 'abs(dr)') va.addAlias('pid_ppi', 'atcPIDBelle(4,2)') va.addAlias('pid_pk', 'atcPIDBelle(4,3)') va.addAlias('pid_kpi', 'atcPIDBelle(3,2)') va.addAlias('ppi0_angle', 'daughterAngle(0, 1)') va.addAlias('p_decayAngle', 'decayAngle(0)') va.addAlias('pi0_decayAngle', 'decayAngle(1)') ma.fillParticleList('p+:good', 'pid_ppi > 0.6 and pid_pk > 0.6', path=mp) # ma.vertexTree('pi0:mdst', ipConstraint = True, massConstraint = ['pi0'], path = mp) ma.reconstructDecay('Sigma+:std -> p+:good pi0:mdst', '1.1 < M < 1.3', path=mp) ma.vertexTree('Sigma+:std', 0, ipConstraint=True, updateAllDaughters=True, path=mp) # Select good pi0 based on mass and gamma energy ma.applyCuts( 'Sigma+:std', 'daughter(1, daughter(0, E)) > 0.04 and daughter(1, daughter(1, E)) > 0.04 and daughter(1, abs(dM)) < 0.02', path=mp) ma.vertexTree('Sigma+:std', 0, ipConstraint=True, massConstraint=['pi0'], path=mp) # 100 MeV mass window for Sigma+ should be large enough ma.applyCuts('Sigma+:std', 'cosaXY > 0 and daughter(1, p) > 0.1 and 1.16 < M < 1.22',
list_pid = ['pid_ppi', 'pid_pk', 'pid_kpi'] list_event = ['IPX', 'IPY', 'IPZ'] # Variables # ============================================= # Lambda0 list_ntuple = list_basics + list_lambda + list_event + list_mc # proton and pion list_ntuple += create_aliases_for_selected(list_basics + list_pid + list_mc, 'Lambda0 -> ^p+ ^pi-', prefix=['p', 'pi']) # Reconstruction # ============================================== # No reconstruction. Just MC match the Lambda0:mdst list ma.vertexTree('Lambda0:mdst', 0, path=mp) ma.matchMCTruth('Lambda0:mdst', path=mp) ma.applyCuts('Lambda0:mdst', 'isSignal == 0', path=mp) # Output # ============================================= mp.add_module('VariablesToNtuple', particleList='Lambda0:mdst', variables=list_ntuple, treeName='lambda', fileName=sys.argv[2]) b2.process(path=mp) print(b2.statistics)
ma.fillParticleList('p+:all', '', path=mp) ma.fillParticleList('pi+:all', '', path=mp) # M Berger: standard pairwise PID > 0.6 and impact parameter > 0.003 ma.cutAndCopyList('p+:berger', 'p+:all', 'pid_ppi > 0.6 and pid_pk > 0.6', path=mp) # M Berger: photons > 40 MeV and pi0 lab frame momentum > 100 MeV ma.cutAndCopyList('pi0:loose', 'pi0:mdst', '', path=mp) ma.reconstructDecay('Sigma+:loose -> p+:berger pi0:loose', 'M >= 1.15 and M <= 1.23', path=mp) # Set updateAllDaughters = True because the pi0:mdst list is mass constrained ma.vertexTree('Sigma+:loose', 0, ipConstraint=True, updateAllDaughters=True, path=mp) # M Berger: discard condidates with wrong sign of flight distance ma.cutAndCopyList( 'Sigma+:good', 'Sigma+:loose', 'gamma1_E > 0.03 and gamma2_E > 0.03 and pi0_M >= 0.11 and pi0_M <= 0.16 and pi0_p > 0.05', path=mp) ma.vertexTree('Sigma+:good', 0, ipConstraint=True, massConstraint=[111], path=mp) ma.applyCuts('Sigma+:good', 'M >= 1.17 and M <= 1.21', path=mp)