Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • qhan/Moore
  • allightb/Moore
  • gpietrzy/Moore
  • smaccoli/Moore
  • rmatev/Moore
  • bldelane/Moore
  • egranado/Moore
  • peilian/Moore
  • rcurrie/Moore
  • mstahl/Moore
  • jonrob/Moore
  • raaij/Moore
  • lhcb/Moore
13 results
Show changes
Commits on Source (12)
Showing
with 6658 additions and 17 deletions
......@@ -15,6 +15,7 @@ Check content of Allen DecReports rawbank and check that they agree with logfile
<extension class="GaudiTest.GaudiExeTest" kind="test">
<argument name="prerequisites"><set>
<tuple><text>persistency.allen_mdf_write</text><enumeral>PASS</enumeral></tuple>
<tuple><text>persistency.make_allen_tck</text><enumeral>PASS</enumeral></tuple>
</set></argument>
<argument name="program"><text>python</text></argument>
<argument name="args"><set>
......
###############################################################################
# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration #
# #
# This software is distributed under the terms of the GNU General Public #
# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". #
# #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization #
# or submit itself to any jurisdiction. #
###############################################################################
"""Test pass-through Sprucing line (defined with `pass_through=True`). Produces spruce_passthrough.dst
Run like any other options file:
./Moore/run gaudirun.py spruce_passthrough.py
"""
from __future__ import absolute_import, division, print_function
from Moore import options, run_moore
from Moore.tcks import dump_sprucing_configuration, load_hlt2_configuration
from RecoConf.global_tools import stateProvider_with_simplified_geom
from RecoConf.reconstruction_objects import reconstruction
from Moore.lines import SpruceLine
input_files = ['hlt2_2or3bodytopo_realtime.mdf']
options.input_raw_format = 0.3
options.input_files = input_files
options.input_type = 'MDF'
options.evt_max = -1
options.simulation = True
options.data_type = 'Upgrade'
options.dddb_tag = 'dddb-20171126'
options.conddb_tag = 'sim-20171127-vc-md100'
options.output_file = 'spruce_passthrough.dst'
options.output_type = 'ROOT'
load_hlt2_configuration("hlt2_2or3bodytopo_realtime.tck.json")
def pass_through_line(name="SprucePassThroughLine"):
"""Return a Sprucing line that performs no selection
"""
return SpruceLine(name=name, prescale=1, algs=[], pass_through=True)
def make_lines():
return [pass_through_line()]
public_tools = [stateProvider_with_simplified_geom()]
with reconstruction.bind(from_file=True, spruce=True):
config = run_moore(options, make_lines, public_tools)
dump_sprucing_configuration(config, "spruce_passthrough.tck.json")
# (c) Copyright 2019 CERN for the benefit of the LHCb Collaboration #
# #
# This software is distributed under the terms of the GNU General Public #
# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". #
# #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization #
# or submit itself to any jurisdiction. #
###############################################################################
"""
Submodule that defines the generic ThOr HLT2 lines
"""
from . import generic_lines
# provide "all_lines" for correct registration by the overall HLT2 lines module
all_lines = {}
all_lines.update(generic_lines.all_lines)
###############################################################################
# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration #
# #
# This software is distributed under the terms of the GNU General Public #
# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". #
# #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization #
# or submit itself to any jurisdiction. #
###############################################################################
import Functors as F
from Functors.math import in_range
from GaudiKernel.SystemOfUnits import GeV, MeV
from Hlt2Conf.algorithms_thor import ParticleFilter, ParticleCombiner, require_all
from Hlt2Conf.standard_particles import make_long_kaons, make_long_muons, make_long_electrons_with_brem
def make_mass_constrained_jpsi2mumu(name='MassConstrJpsi2MuMuMaker',
pid_mu=0,
pt_mu=0.5 * GeV,
am_min=2900 * MeV,
am_max=3300 * MeV,
adoca_chi2=20,
vchi2=16):
muons = make_long_muons()
filteredMuons = ParticleFilter(
name="FilteredPIDMuons", Input=muons, Cut=F.FILTER(F.PID_MU > pid_mu))
mother_code = require_all(F.CHI2 < vchi2)
combination_code = require_all(
in_range(am_min, F.MASS, am_max), F.MAXDOCACHI2 < adoca_chi2,
F.SUM(F.PT > pt_mu) > 0)
return ParticleCombiner(
name=name,
Inputs=[muons, filteredMuons],
DecayDescriptor="[J/psi(1S) -> mu+ mu-]cc",
CombinationCut=combination_code,
CompositeCut=mother_code)
def make_mass_constrained_jpsi2ee(name='MassConstrJpsi2eeMaker',
pid_e=0,
pt_e=0.5 * GeV,
am_min=2900 * MeV,
am_max=3300 * MeV,
adoca_chi2=20,
vchi2=16):
electrons = make_long_electrons_with_brem()
filteredElectrons = ParticleFilter(
name="FilteredPIDElectrons",
Input=electrons,
Cut=F.FILTER(F.PID_E > pid_e))
mother_code = require_all(F.CHI2 < vchi2)
combination_code = require_all(
in_range(am_min, F.MASS, am_max), F.MAXDOCACHI2 < adoca_chi2,
F.SUM(F.PT > pt_e) > 0)
return ParticleCombiner(
name=name,
Inputs=[electrons, filteredElectrons],
DecayDescriptor="[J/psi(1S) -> e+ e-]cc",
CombinationCut=combination_code,
CompositeCut=mother_code)
def make_phi(name="Phi2KKMaker",
adoca_chi2=30.,
am_min=980. * MeV,
am_max=1060. * MeV,
pt=1 * GeV,
vchi2=10,
tr_chi2pdof=5,
pid_k=0):
kaons = make_long_kaons()
filteredKaons = ParticleFilter(
name="FilteredPIDkaons", Input=kaons, Cut=F.FILTER(F.PID_K > pid_k))
combination_code = require_all(
in_range(am_min, F.MASS, am_max), F.MAXDOCACHI2CUT(adoca_chi2),
F.SUM(F.CHI2DOF < tr_chi2pdof) > 0)
vertex_code = require_all(F.CHI2 < vchi2, F.PT > pt)
return ParticleCombiner(
name=name,
Inputs=[kaons, filteredKaons],
DecayDescriptor="[phi(1020) -> K+ K-]cc",
CombinationCut=combination_code,
CompositeCut=vertex_code)
def make_bs2jpsiphi(name="Bs2JPsiPhiCombiner",
jpsi_maker=make_mass_constrained_jpsi2mumu,
am_min=5100 * MeV,
am_max=5600 * MeV,
am_min_vtx=5100 * MeV,
am_max_vtx=5600 * MeV,
vtx_chi2pdof=20):
phi = make_phi()
jpsi = jpsi_maker()
combination_code = require_all(in_range(am_min, F.MASS, am_max))
vertex_code = require_all(
in_range(am_min_vtx, F.MASS, am_max_vtx), F.CHI2DOF < vtx_chi2pdof)
return ParticleCombiner(
name=name,
Inputs=[jpsi, phi],
DecayDescriptor="B_s0 -> J/psi(1S) phi(1020)",
CombinationCut=combination_code,
CompositeCut=vertex_code)
def make_bs2jpsiphi_jpsi2mumu_phi2kk():
return make_bs2jpsiphi(
name="Bs2JPsiPhi_JPsi2MuMu_Combiner",
jpsi_maker=make_mass_constrained_jpsi2mumu)
def make_bs2jpsiphi_jpsi2ee_phi2kk():
return make_bs2jpsiphi(
name="Bs2JPsiPhi_JPsi2ee_Combiner",
jpsi_maker=make_mass_constrained_jpsi2ee)
###############################################################################
# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration #
# #
# This software is distributed under the terms of the GNU General Public #
# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". #
# #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization #
# or submit itself to any jurisdiction. #
###############################################################################
import Functors as F
from Functors.math import in_range
from GaudiKernel.SystemOfUnits import GeV, MeV, mm, micrometer as um
from Hlt2Conf.algorithms_thor import ParticleCombiner, ParticleFilter, require_all
def filter_long_protons(particles,
pvs,
name="LongProtonsFilter",
pt_min=200 * MeV,
p_min=1 * GeV,
mipchi2_min=9.,
dllp_min=-5.):
cut = require_all(F.PT > pt_min, F.P > p_min,
F.MINIPCHI2CUT(IPChi2Cut=mipchi2_min, Vertices=pvs),
F.PID_P > dllp_min)
return ParticleFilter(name=name, Input=particles, Cut=F.FILTER(cut))
def filter_long_kaons(particles,
pvs,
name="LongKaonsFilter",
pt_min=180 * MeV,
p_min=3 * GeV,
mipchi2_min=16.,
dllk_min=-5.):
cut = require_all(F.PT > pt_min, F.P > p_min,
F.MINIPCHI2CUT(IPChi2Cut=mipchi2_min, Vertices=pvs),
F.PID_K > dllk_min)
return ParticleFilter(name=name, Input=particles, Cut=F.FILTER(cut))
def filter_long_pions(particles,
pvs,
name="LongPionsFilter",
pt_min=100 * MeV,
p_min=2 * GeV,
mipchi2_min=16.,
dllk_max=5.):
cut = require_all(F.PT > pt_min, F.P > p_min,
F.MINIPCHI2CUT(IPChi2Cut=mipchi2_min, Vertices=pvs),
F.PID_K < dllk_max)
return ParticleFilter(name=name, Input=particles, Cut=F.FILTER(cut))
def filter_down_protons(particles,
name="DownstreamProtonsFilter",
pt_min=200 * MeV,
dllp_min=-5.):
cut = require_all(F.PT > pt_min, F.PID_P > dllp_min)
return ParticleFilter(name=name, Input=particles, Cut=F.FILTER(cut))
def filter_down_pions(particles,
name="DownstreamPionsFilter",
pt_min=200 * MeV,
p_min=2 * GeV,
dllk_max=5.):
cut = require_all(F.PT > pt_min, F.PID_K < dllk_max)
return ParticleFilter(name=name, Input=particles, Cut=F.FILTER(cut))
def make_dd_lambda(protons,
pions,
name="ddLambda0Combiner",
m_max=1300 * MeV,
comb_pt_min=0.2 * GeV,
pt_min=0.2 * GeV,
doca_max=5 * mm,
docachi2_max=16.,
vchi2pdof_max=12.):
comb_cut = require_all(
F.MAXDOCACUT(doca_max), F.MAXDOCACHI2CUT(docachi2_max),
F.PT > comb_pt_min)
vertex_cut = require_all(
F.MASS < m_max,
F.PT > pt_min, # F.P > p_min,
F.CHI2DOF < vchi2pdof_max)
return ParticleCombiner(
name=name,
Inputs=[protons, pions],
DecayDescriptor="[Lambda0 -> p+ pi-]cc",
CombinationCut=comb_cut,
CompositeCut=vertex_cut)
def make_ll_lambda(protons,
pions,
pvs,
name="llLambda0Combiner",
m_max=3000 * MeV,
comb_pt_min=200 * MeV,
pt_min=200 * MeV,
comb_p_min=1 * GeV,
p_min=1.5 * GeV,
doca_max=1 * mm,
vchi2pdof_max=12.,
bpvfdchi2_min=80.):
comb_cut = require_all(
F.MAXDOCACUT(doca_max), F.PT > comb_pt_min, F.P > comb_p_min)
vertex_cut = require_all(F.MASS < m_max, F.PT > pt_min, F.P > p_min,
F.CHI2DOF < vchi2pdof_max,
F.BPVFDCHI2(pvs) > bpvfdchi2_min)
return ParticleCombiner(
name=name,
Inputs=[protons, pions],
DecayDescriptor="[Lambda0 -> p+ pi-]cc",
CombinationCut=comb_cut,
CompositeCut=vertex_cut)
def make_xi(lambdas,
pions,
pvs,
name="xiCombiner",
comb_pt_min=200 * MeV,
pt_min=200 * MeV,
comb_p_min=0.5 * GeV,
p_min=1 * GeV,
doca_max=300 * um,
vchi2pdof_max=16.,
bpvfdchi2_min=9.):
comb_cut = require_all(
F.MAXDOCACUT(doca_max), F.PT > comb_pt_min, F.P > comb_p_min)
vertex_cut = require_all(F.PT > pt_min, F.P > p_min,
F.CHI2DOF < vchi2pdof_max,
F.BPVFDCHI2(pvs) > bpvfdchi2_min)
return ParticleCombiner(
name=name,
Inputs=[lambdas, pions],
DecayDescriptor="[Xi- -> Lambda0 pi-]cc",
CombinationCut=comb_cut,
CompositeCut=vertex_cut)
def combine_prompt_hyperon_hh(hyperon,
p1,
p2,
pvs,
decay_descriptor,
name="PromptHyperonHHCombiner",
doca12_max=2 * mm,
doca13_max=2 * mm,
doca23_max=2 * mm,
comb_m_min=2000 * MeV,
comb_m_max=2800 * MeV,
m_min=2100 * MeV,
m_max=2700 * MeV,
comb_pt_min=0.5 * GeV,
pt_min=1 * GeV,
bpvipchi2_max=9.,
bpvdira_min=0.95):
comb12_cut = require_all(F.MAXDOCACUT(doca12_max))
comb_cut = require_all(
in_range(comb_m_min, F.MASS, comb_m_max),
F.DOCA(1, 3) < doca13_max,
F.DOCA(2, 3) < doca23_max, F.PT > comb_pt_min)
vertex_cut = require_all(
in_range(m_min, F.MASS, m_max), F.PT > pt_min,
F.BPVIPCHI2(pvs) < bpvipchi2_max,
F.BPVDIRA(pvs) > bpvdira_min)
return ParticleCombiner(
name=name,
Inputs=[hyperon, p1, p2],
DecayDescriptor=decay_descriptor,
Combination12Cut=comb12_cut,
CombinationCut=comb_cut,
CompositeCut=vertex_cut)
def combine_prompt_hyperon_hhh(hyperon,
p1,
p2,
p3,
pvs,
decay_descriptor,
name="PromptHyperonHHHCombiner",
comb12_m_max=4000 * MeV,
doca12_max=3 * mm,
comb123_m_max=5000 * MeV,
doca13_max=3 * mm,
doca23_max=3 * mm,
doca14_max=3 * mm,
doca24_max=3 * mm,
doca34_max=3 * mm,
comb_m_min=1400 * MeV,
comb_m_max=4000 * MeV,
comb_pt_min=0.4 * GeV,
comb_p_min=3 * GeV,
sum_pt_min=1.5 * GeV,
m_min=1600 * MeV,
m_max=3800 * MeV,
bpvipchi2_max=16.,
bpvdira_min=0.95):
comb12_cut = require_all(F.MASS < comb12_m_max, F.MAXDOCACUT(doca12_max))
comb123_cut = require_all(F.MASS < comb123_m_max,
F.DOCA(1, 3) < doca13_max,
F.DOCA(2, 3) < doca23_max)
comb_cut = require_all(
in_range(comb_m_min, F.MASS, comb_m_max), F.PT > comb_pt_min,
F.P > comb_p_min,
F.SUM(F.PT) > sum_pt_min,
F.DOCA(1, 4) < doca14_max,
F.DOCA(2, 4) < doca24_max,
F.DOCA(3, 4) < doca34_max)
vertex_cut = require_all(
in_range(m_min, F.MASS, m_max),
F.BPVIPCHI2(pvs) < bpvipchi2_max,
F.BPVDIRA(pvs) > bpvdira_min)
return ParticleCombiner(
name=name,
Inputs=[hyperon, p1, p2, p3],
DecayDescriptor=decay_descriptor,
Combination12Cut=comb12_cut,
Combination123Cut=comb123_cut,
CombinationCut=comb_cut,
CompositeCut=vertex_cut)
###############################################################################
# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration #
# #
# This software is distributed under the terms of the GNU General Public #
# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". #
# #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization #
# or submit itself to any jurisdiction. #
###############################################################################
import Functors as F
from GaudiKernel.SystemOfUnits import GeV, MeV
from Hlt2Conf.algorithms_thor import ParticleFilter
from Hlt2Conf.standard_particles import (
make_has_rich_long_pions, make_photons, make_has_rich_down_protons,
make_has_rich_down_pions, make_has_rich_long_kaons,
make_has_rich_long_protons)
from Moore.lines import Hlt2Line
from Moore.config import register_line_builder
from RecoConf.reconstruction_objects import make_pvs_v2 as make_pvs
from Hlt2Conf.lines.generic_lines_thor.builders import hyperon_builders
from Hlt2Conf.lines.generic_lines_thor.builders import bs_builders
all_lines = {}
#Dummy line, included to trigger neutral reconstruction.
@register_line_builder(all_lines)
def photons_line(name="Hlt2PhotonsLine", prescale=1):
photons = make_photons()
line_alg = ParticleFilter(
name="Hlt2PhotonFilter", Input=photons, Cut=F.FILTER(F.P > 40 * GeV))
return Hlt2Line(name=name, prescale=prescale, algs=[line_alg])
#From Hlt2Conf/lines/charm/hyperons.py
@register_line_builder(all_lines)
def xicz_to_lpipi_dd_line(name="Hlt2XiczToLPimPip_DDLine", prescale=1):
pvs = make_pvs()
down_protons = hyperon_builders.filter_down_protons(
particles=make_has_rich_down_protons())
down_pions = hyperon_builders.filter_down_pions(
particles=make_has_rich_down_pions())
lambda_dd = hyperon_builders.make_dd_lambda(
protons=down_protons, pions=down_pions)
long_xicz_pions = hyperon_builders.filter_long_pions(
particles=make_has_rich_long_pions(),
pvs=pvs,
pt_min=300 * MeV,
mipchi2_min=4.)
hyperon = hyperon_builders.combine_prompt_hyperon_hh(
hyperon=lambda_dd,
p1=long_xicz_pions,
p2=long_xicz_pions,
pvs=pvs,
decay_descriptor="[Xi_c0 -> Lambda0 pi- pi+]cc")
return Hlt2Line(name=name, algs=[hyperon], prescale=prescale)
#From Hlt2Conf/lines/charm/hyperons.py
@register_line_builder(all_lines)
def oc_to_ximkpipi_lll_line(name="Hlt2OcToXimKmPipPip_LLLLine", prescale=1):
pvs = make_pvs()
long_protons = hyperon_builders.filter_long_protons(
particles=make_has_rich_long_protons(), pvs=pvs)
long_pions = hyperon_builders.filter_long_pions(
particles=make_has_rich_long_pions(), pvs=pvs)
lambda_ll = hyperon_builders.make_ll_lambda(
protons=long_protons, pions=long_pions, pvs=pvs)
long_xi_pions = hyperon_builders.filter_long_pions(
particles=make_has_rich_long_pions(),
pvs=pvs,
pt_min=120 * MeV,
mipchi2_min=12.)
xi_lll = hyperon_builders.make_xi(
lambdas=lambda_ll, pions=long_xi_pions, pvs=pvs)
long_oc_kaons = hyperon_builders.filter_long_kaons(
particles=make_has_rich_long_kaons(),
pvs=pvs,
pt_min=200 * MeV,
p_min=1 * GeV,
mipchi2_min=4.,
dllk_min=-5)
long_oc_pions = hyperon_builders.filter_long_pions(
particles=make_has_rich_long_pions(),
pvs=pvs,
pt_min=200 * MeV,
mipchi2_min=4.)
oc_lll = hyperon_builders.combine_prompt_hyperon_hhh(
hyperon=xi_lll,
p1=long_oc_kaons,
p2=long_oc_pions,
p3=long_oc_pions,
pvs=pvs,
decay_descriptor="[Omega_c0 -> Xi- K- pi+ pi+]cc")
return Hlt2Line(name=name, algs=[oc_lll], prescale=prescale)
#From Hlt2Conf/lines/Bs2JpsiPhi.py
@register_line_builder(all_lines)
def bs2jpsiphi_jpsi2mumu_phi2kk_line(
name='Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line', prescale=1):
return Hlt2Line(
name=name,
algs=[bs_builders.make_bs2jpsiphi_jpsi2mumu_phi2kk()],
prescale=prescale,
)
@register_line_builder(all_lines)
def bs2jpsiphi_jpsi2ee_phi2kk_line(name='Hlt2BsToJpsiPhi_JPsi2ee_PhiToKK_Line',
prescale=1):
return Hlt2Line(
name=name,
algs=[bs_builders.make_bs2jpsiphi_jpsi2ee_phi2kk()],
prescale=prescale,
)
###############################################################################
# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration #
# #
# This software is distributed under the terms of the GNU General Public #
# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". #
# #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization #
# or submit itself to any jurisdiction. #
###############################################################################
"""Simple configuration that enables checksums and DEBUG output for HltPackedDataWriter.
"""
from Moore import options, run_moore
from PyConf.Algorithms import HltPackedDataWriter
from Gaudi.Configuration import DEBUG
from RecoConf.global_tools import stateProvider_with_simplified_geom
from RecoConf.reconstruction_objects import reconstruction
from Hlt2Conf.lines.generic_lines_thor import all_lines
def make_lines():
print(len(all_lines))
return [builder() for builder in all_lines.values()]
public_tools = [stateProvider_with_simplified_geom()]
with reconstruction.bind(from_file=False), HltPackedDataWriter.bind(
OutputLevel=DEBUG, EnableChecksum=True):
config = run_moore(options, make_lines, public_tools)
###############################################################################
# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration #
# #
# This software is distributed under the terms of the GNU General Public #
# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". #
# #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization #
# or submit itself to any jurisdiction. #
###############################################################################
"""Example configuration of ThOr-based LHCb::Particle selection algorithms.
The thresholds in each selection algorithm are designed to accept and reject at
least some events to verify that the functors are not simply accepting or
rejecting all input.
"""
from Moore import options, run_moore
from RecoConf.global_tools import stateProvider_with_simplified_geom
from RecoConf.reconstruction_objects import reconstruction
from Hlt2Conf.lines.generic_lines_thor import all_lines
def make_lines():
print(len(all_lines))
return [builder() for builder in all_lines.values()]
public_tools = [stateProvider_with_simplified_geom()]
with reconstruction.bind(from_file=False):
config = run_moore(options, make_lines, public_tools)
###############################################################################
# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration #
# #
# This software is distributed under the terms of the GNU General Public #
# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". #
# #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization #
# or submit itself to any jurisdiction. #
###############################################################################
"""Test Sprucing output.
Runs over the output file passed as the last argument to this script.
A cleverer version of this script would check the number of packed objects
against the number of objects created upstream in Moore. But we cannot yet
run a GaudiPython job in Moore to get the container counts (see LBCOMP-101),
so instead we use heuristics to estimate the number of objects we should
expect.
"""
from __future__ import print_function
import argparse
import GaudiPython as GP
from GaudiConf import IOExtension
from Configurables import (
ApplicationMgr,
CondDB,
LHCbApp,
HltDecReportsDecoder,
IODataManager,
HistogramPersistencySvc,
)
from Moore.persistence import DEFAULT_OUTPUT_PREFIX
from GaudiConf.PersistRecoConf import PersistRecoPacking
from GaudiConf.reading import decoder, unpackers, mc_unpackers
from Moore.tcks import load_hlt2_configuration
def error(msg):
print("Hlt2CheckOutput ERROR", msg)
Unexpected = ['SplitPhotons', 'MuonPID', 'Neutrals', 'MergedPi0s', 'Photons']
parser = argparse.ArgumentParser()
parser.add_argument('input', help='Input filename')
parser.add_argument('hlt2_tck', help='HLT2 JSON TCK dump')
args = parser.parse_args()
prp = PersistRecoPacking(stream=DEFAULT_OUTPUT_PREFIX, data_type='Upgrade')
hlt2_ann = load_hlt2_configuration(args.hlt2_tck, annsvc_name="HltANNSvc")
##Prepare application
LHCbApp(
DataType="Upgrade",
Simulation=True,
DDDBtag="dddb-20201211",
CondDBtag="sim-20201218-vc-md100",
)
CondDB(Upgrade=True)
dec_reports = HltDecReportsDecoder(SourceID=2)
algs = [decoder()]
algs += [dec_reports]
algs += unpackers(stream=DEFAULT_OUTPUT_PREFIX, data_type='Upgrade')
algs += mc_unpackers(stream=DEFAULT_OUTPUT_PREFIX)
ApplicationMgr(TopAlg=algs)
IOExtension().inputFiles([args.input], clear=True)
# Disable warning about not being able to navigate ancestors
IODataManager(DisablePFNWarning=True)
# Disable warning about histogram saving not being required
HistogramPersistencySvc(OutputLevel=5)
appMgr = GP.AppMgr()
TES = appMgr.evtsvc()
appMgr.run(1)
# MonkeyPatch for the fact that RegistryEntry.__bool__
# changed in newer cppyy. Proper fix should go into Gaudi
import cppyy
cppyy.gbl.DataSvcHelpers.RegistryEntry.__bool__ = lambda x: True
# needed to check if we didn't find something in TES
not_found = cppyy.bind_object(0, cppyy.gbl.DataObject)
found_events = False
found_child_relations = False
npacked_avg = {loc_packed: 0 for loc_packed in prp.packedToOutputLocationMap()}
nevents = 1
for ii in range(nevents):
print('Checking next event.')
appMgr.run(1)
if not TES['/Event']:
break
if ii == 0:
TES.dump()
# First step: check the output of 2or3bodytopo lines
# Flag to record whether we saw any events
# The test can't check anything if no event fired
# get decReport
hlt2reports = TES['/Event/Hlt/DecReports']
hlt2report1 = hlt2reports.decReport('Hlt2Topo2BodyLineDecision').decision()
hlt2report2 = hlt2reports.decReport('Hlt2Topo3BodyLineDecision').decision()
print("hlt2report1: ", hlt2report1, " , hlt2report2: ", hlt2report2)
if hlt2report1 != 1 and hlt2report2 != 1:
print("Decision ERROR HLT2 DecReports not working.")
# Check the particles saved in Hlt2 lines,
# no output is saved in Sprucing pass through line
if hlt2report1: prefix = '/Event/HLT2/Hlt2Topo2BodyLine'
else: prefix = '/Event/HLT2/Hlt2Topo3BodyLine'
container = TES[prefix + '/Particles']
# The CopyParticles algorithm should ensure P2PV relations are saved for the
# top-level object (the decay head)
relations = TES[prefix + '/Particle2VertexRelations']
if not relations:
error("no P2PV relations")
# Special selection algorithm configuration is required to ensure
# P2PV relations for the descendents are propagated (they are only
# created if an object uses PVs in its selection). Here we check
# that at least some lines have child relations, but don't require
# it for every line (it's valid for a line not to require PVs to
# perform its selection).
if relations.size() > container.size():
found_child_relations = True
found_events = True
# Check a protoparticle
proto = container[0].daughtersVector()[1].proto()
print("proto: ", proto)
if proto == not_found:
print("Proto ERROR Proto particles are not saved")
# Check logic of decay tree
if hlt2report1:
mothers = TES['/Event/HLT2/Hlt2Topo2BodyLine/Particles'].size()
firstdaughters = TES['/Event/HLT2/Hlt2Topo2BodyLine/Particles'][
0].daughtersVector().size()
print("mothers: ", mothers, " firstdaughters: ", firstdaughters)
if mothers + firstdaughters < 3:
print(
"Particle ERROR Decay tree of particles not being saved correctly."
)
if hlt2report2:
mothers = TES['/Event/HLT2/Hlt2Topo3BodyLine/Particles'].size()
firstdaughters = TES['/Event/HLT2/Hlt2Topo3BodyLine/Particles'][
0].daughtersVector().size()
seconddaughters = TES['/Event/HLT2/Hlt2Topo3BodyLine/Particles'][
0].daughtersVector()[0].daughtersVector().size()
print("mothers: ", mothers, " firstdaughters: ", firstdaughters,
" seconddaughters: ", seconddaughters)
if mothers + firstdaughters + seconddaughters < 5:
print(
"Particle ERROR Decay tree of particles not being saved correctly."
)
# Second step: Check persistency of packed containers
for loc_packed, loc_unpacked in prp.packedToOutputLocationMap().items():
packed = TES[loc_packed]
unpacked = TES[loc_unpacked]
if packed == not_found:
print("Unpacking ERROR Unpacked location not found: ", loc_packed)
npacked = -1
else:
npacked = packed.data().size()
npacked_avg[loc_packed] += npacked
if unpacked == not_found:
print("Packing ERROR Packed location not found: ", loc_unpacked)
nunpacked = -1
else:
nunpacked = len(unpacked)
if npacked != nunpacked:
print("(Un)packing ERROR Unpacked/packed number mismatched: ",
loc_packed, npacked, loc_unpacked, nunpacked)
# We should still be persisting the HLT2 line candidates
print("Event size: " +
str((TES["/Event/HLT2/pPhys/Particles"]).data().size()))
if (TES["/Event/HLT2/pPhys/Particles"]).data().size() < 3:
print("Persistence ERROR Physics objects are not being persisted")
# Check a random RawBank is populated
RawBank = TES['/Event/DAQ/RawEvent'].banks(GP.gbl.LHCb.RawBank.Rich).size()
print("Det RawBank has size ", RawBank)
if RawBank == 0:
print("RawBank ERROR Expected Rich raw banks")
# Third step: Check the DecReports of Sprucing
sprucereports = TES['/Event/Spruce/DecReports']
sprucereport = sprucereports.decReport(
'SprucePassThroughLineDecision').decision()
print("sprucereport: ", sprucereport)
if sprucereport != 1:
print("Decision ERROR Spruce DecReports not working.")
# Results of first step
if not found_events:
error('ERROR: no positive decisions found')
if not found_child_relations:
error('ERROR: no child P2PV relations found')
# Results of second step
for loc_packed in prp.packedToOutputLocationMap():
npacked = 1. * npacked_avg[loc_packed] / nevents
print(loc_packed, " has average size", npacked)
if npacked_avg[loc_packed] < 2 and not any(x in loc_packed
for x in Unexpected):
print("Packing ERROR Too few objects in packed location: ", loc_packed,
npacked)
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
<!--
(c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration
This software is distributed under the terms of the GNU General Public
Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".
In applying this licence, CERN does not waive the privileges and immunities
granted to it by virtue of its status as an Intergovernmental Organization
or submit itself to any jurisdiction.
-->
<!--
Runs hlt2_check_packed_data.py with DEBUG output and checksum enabled on HltPackedDataWriter
and checks the output against a reference.
-->
<extension class="GaudiTest.GaudiExeTest" kind="test">
<argument name="program"><text>gaudirun.py</text></argument>
<argument name="args"><set>
<text>$MOOREROOT/tests/options/default_input_and_conds_hlt2.py</text>
<text>$HLT2CONFROOT/tests/options/hlt2_check_packed_data.py</text>
</set></argument>
<argument name="use_temp_dir"><enumeral>true</enumeral></argument>
<argument name="reference"><text>../refs/hlt2_check_packed_data_checksums.ref</text></argument>
<argument name="validator"><text>
from Moore.qmtest.exclusions import remove_known_warnings
countErrorLines({"FATAL": 0, "ERROR": 0, "WARNING": 0},
stdout=remove_known_warnings(stdout))
from Moore.qmtest.exclusions import skip_initialize, skip_scheduler, remove_known_fluctuating_counters
from GaudiConf.QMTest.LHCbExclusions import preprocessor as LHCbPreprocessor
validateWithReference(preproc = skip_initialize + LHCbPreprocessor + skip_scheduler, counter_preproc = remove_known_fluctuating_counters)
</text></argument>
<!--
TODO: Test fails.
Will remain disabled until https://gitlab.cern.ch/lhcb/LHCb/-/issues/151 is solved.
-->
<argument name="unsupported_platforms"><set>
<text>.*</text>
</set></argument>
</extension>
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
<!--
(c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration
This software is distributed under the terms of the GNU General Public
Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".
In applying this licence, CERN does not waive the privileges and immunities
granted to it by virtue of its status as an Intergovernmental Organization
or submit itself to any jurisdiction.
-->
<!--
Run reconstruction + ThOr selection.
-->
<extension class="GaudiTest.GaudiExeTest" kind="test">
<argument name="program"><text>gaudirun.py</text></argument>
<argument name="args"><set>
<text>$MOOREROOT/tests/options/mdf_input_and_conds_hlt2.py</text>
<text>$MOOREROOT/tests/options/download_mdf_input.py</text>
<text>$MOOREROOT/tests/options/multi_threaded_4_threads.py</text>
<text>$HLT2CONFROOT/tests/options/hlt2_reco_plus_thor_selections.py</text>
</set></argument>
<argument name="use_temp_dir"><enumeral>true</enumeral></argument>
<argument name="reference"><text>../refs/hlt2_reco_plus_thor_selections.ref</text></argument>
<argument name="error_reference"><text>../../../RecoConf/tests/refs/empty.ref</text></argument>
<argument name="validator"><text>
from Moore.qmtest.exclusions import remove_known_warnings
countErrorLines({"FATAL": 0, "ERROR": 0, "WARNING": 0},
stdout=remove_known_warnings(stdout))
from Moore.qmtest.exclusions import ref_preprocessor, remove_known_fluctuating_counters
validateWithReference(preproc=ref_preprocessor, counter_preproc = remove_known_fluctuating_counters)
</text></argument>
</extension>
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
<!--
(c) Copyright 2021 CERN for the benefit of the LHCb Collaboration
This software is distributed under the terms of the GNU General Public
Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".
In applying this licence, CERN does not waive the privileges and immunities
granted to it by virtue of its status as an Intergovernmental Organization
or submit itself to any jurisdiction.
-->
<!--
Test sprucing on output of {2, 3}body topo lines run using real time reco.
Runs over hlt2_2or3bodytopo_realtime.dst from hlt2_2or3bodytopo_realtime.py and requires the dumped TCK.
The pass through line runs no selection and persists whatever in Hlt2 stage
-->
<extension class="GaudiTest.GaudiExeTest" kind="test">
<argument name="prerequisites"><set>
<tuple><text>test_hlt2_2or3bodytopo_realtime</text><enumeral>PASS</enumeral></tuple>
</set></argument>
<argument name="program"><text>gaudirun.py</text></argument>
<argument name="timeout"><integer>3000</integer></argument>
<argument name="args"><set>
<text>$HLT2CONFROOT/options/Sprucing/spruce_passthrough.py</text>
</set></argument>
<argument name="use_temp_dir"><enumeral>true</enumeral></argument>
<argument name="validator"><text>
from Moore.qmtest.exclusions import remove_known_warnings
countErrorLines({"FATAL": 0, "ERROR": 0, "WARNING": 0},
stdout=remove_known_warnings(stdout))
</text></argument>
</extension>
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
<!--
(c) Copyright 2021 CERN for the benefit of the LHCb Collaboration
This software is distributed under the terms of the GNU General Public
Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".
In applying this licence, CERN does not waive the privileges and immunities
granted to it by virtue of its status as an Intergovernmental Organization
or submit itself to any jurisdiction.
-->
<!--
Test Sprucing output. Runs over spruce_realtimereco.dst from spruce_example_realtime.py. Tests "live" persistency.
-->
<extension class="GaudiTest.GaudiExeTest" kind="test">
<argument name="prerequisites"><set>
<tuple><text>test_spruce_passthrough</text><enumeral>PASS</enumeral></tuple>
</set></argument>
<argument name="program"><text>python</text></argument>
<argument name="timeout"><integer>300</integer></argument>
<argument name="args"><set>
<text>$HLT2CONFROOT/tests/options/spruce_passthrough_check.py</text>
<text>spruce_passthrough.dst</text>
<text>hlt2_2or3bodytopo_realtime.tck.json</text>
</set></argument>
<argument name="use_temp_dir"><enumeral>true</enumeral></argument>
<argument name="validator"><text>
countErrorLines({"FATAL": 0, "ERROR": 0, "WARNING": 0})
</text></argument>
</extension>
This diff is collapsed.
This diff is collapsed.
......@@ -36,6 +36,7 @@ from PyConf.application import (
make_odin,
default_raw_event,
)
from PyConf.utilities import ConfigurationError
# "forward" some useful functions from PyConf.application
from PyConf.application import configure_input, configure
......@@ -226,6 +227,11 @@ def report_writers_node(streams,
new_hlt_banks['DstData'] = packed_data
extra_locations_to_persist.extend(line_output_locations)
elif process == "spruce":
# never mix use pass through lines and usual selection lines
is_pass_through = [line.pass_through for line in lines]
if not (pass_through:=all(is_pass_through)) and any(is_pass_through):
raise ConfigurationError("Do not mix pass through lines and normal selection lines.")
erw = ExecutionReportsWriter(
Persist=[line.name for line in lines],
ANNSvcKey="SpruceSelectionID",
......@@ -237,22 +243,25 @@ def report_writers_node(streams,
algs.append(erw)
extra_locations_to_persist.append(erw.outputs['DecReportsLocation'])
algs.insert(
0,
bankKiller(
RawEventLocations=[default_raw_event(['DstData'])],
BankTypes=['DstData']))
line_output_cf, line_output_locations, packed_data = persist_line_outputs(
physics_lines,
data_type,
erw.DecReportsLocation,
associate_mc=False,
stream="/Event/Spruce",
out_stream="/Event/Spruce/HLT2")
new_hlt_banks['DstData'] = packed_data
algs.append(line_output_cf)
extra_locations_to_persist.extend(line_output_locations)
if not pass_through:
# do not kill and overwrite Hlt2 raw banks for pass through line
algs.insert(
0,
bankKiller(
RawEventLocations=[default_raw_event(['DstData'])],
BankTypes=['DstData']))
line_output_cf, line_output_locations, packed_data = persist_line_outputs(
physics_lines,
data_type,
erw.DecReportsLocation,
associate_mc=False,
stream="/Event/Spruce",
out_stream="/Event/Spruce/HLT2")
new_hlt_banks['DstData'] = packed_data
algs.append(line_output_cf)
extra_locations_to_persist.extend(line_output_locations)
# We can handle multiple lines by using a LumiCounterMerger algorithm, but
# for now simplify the logic by assuming there's a single line
......
......@@ -25,6 +25,7 @@ from Moore.selreports import (
)
from PyConf.application import default_raw_event
from PyConf.utilities import ConfigurationError
from .persistence.particle_moving import (
CopyParticles,
......@@ -481,10 +482,20 @@ class SpruceLine(Hlt2Line):
prescale=1.,
extra_outputs=None,
persistreco=False,
pass_through=False,
hlt1_filter_code="",
hlt2_filter_code="",
):
self.pass_through = pass_through
# For pass through line, all other arguments should have default values
if self.pass_through:
if (algs != []) or (extra_outputs is not None) or (
persistreco) or (hlt1_filter_code !=
"") or (hlt2_filter_code != ""):
raise ConfigurationError(
"Pass through option doesn't support non-default values.")
assert not hlt1_filter_code, 'Filtering on HLT1 decisions in the Sprucing is not yet functional'
##This is very ugly but we require the _SPRUCE_ANNSVC_NAME for the HLT1 filter. See RecoConf/python/RecoConf/reco_objects_for_spruce.py
##Revise when the tck framework is in
......
......@@ -52,6 +52,12 @@ remove_known_fluctuating_counters = LineSkipper(regexps=[
# Functor cache hit/miss counters; can vary in uninteresting ways in
# reconstruction tests based on HLT2 line content
r' \| "# loaded from (?:CACHE|PYTHON)" .*',
# The HltPackedDataWriter uses two data buffers: one that holds uncompressed
# data and another that holds this data after compression. For some reason,
# the size of the compressed data buffer fluctuates slightly (~0.001%) between runs.
# The same does not happen for the uncompressed data buffer.
# See https://gitlab.cern.ch/lhcb/LHCb/-/issues/151
r' \| "Size of compressed data" .*'
])
# In most cases everything interesting happens at finalize: counters,
......
......@@ -33,7 +33,7 @@ endif()
set(LOKI_FUNCTORS_CACHE_POST_ACTION_OPTS)
list(APPEND hlt1_settings hlt1_pp_default hlt1_pp_comparison)
list(APPEND hlt2_settings options/hlt2_pp_default tests/options/thor/loki_comparison)
list(APPEND hlt2_settings options/hlt2_pp_default tests/options/thor/loki_comparison tests/options/hlt2_reco_plus_thor_selections)
if(NOT DEFINED REC_ROOT_DIR)
# Rec uses new CMake configuration so we need a different way to locate
......