Skip to content
Snippets Groups Projects
Commit 223e7f3a authored by Nicole Skidmore's avatar Nicole Skidmore Committed by Sebastien Ponce
Browse files

First test of DV with overlap fixes -> TurboSpruce

parent 48c1edeb
No related branches found
No related tags found
1 merge request!1230First test of DV with overlap fixes -> TurboSpruce
......@@ -27,6 +27,7 @@ if(BUILD_TESTING AND NOT USE_DD4HEP)
DaVinciExamples.tupling.test_davinci_tupling_from_spruced_turbo
DaVinciExamples.tupling.test_davinci_tupling_from_spruce_data
DaVinciExamples.tupling.test_davinci_tupling_from_spruced_turbo_with_refitting
DaVinciExamples.tupling.test_davinci_tupling_All_TurboSpruce
PROPERTY
DISABLED TRUE
)
......
input_files:
- /eos/lhcb/wg/dpa/wp1/temp/spruce_overlaptest.streamone.dst
input_manifest_file: '/eos/lhcb/wg/dpa/wp1/temp/spruce_overlaptest.tck.json'
input_type: ROOT
simulation: False
conddb_tag: sim-20171127-vc-md100
dddb_tag: dddb-20171126
conditions_version: master
geometry_version: run3/trunk
input_raw_format: 0.5
persistreco_version: 0.0
lumi: false
ntuple_file: 'DV_example_allFunctors_ntp_TurboSpruce.root'
print_freq: 1
input_process: TurboSpruce
input_stream: streamone
output_level: 3
###############################################################################
# (c) Copyright 2021-2024 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 of a DaVinci job filling all available functors for input_proces=TurboSpruce. This is obviously a stress test and not realistic.
rst_title: All Functors in DaVinci
rst_description: This example shows how to:
1. create a dictionary with functors of interest for various type of particles
2. add a tuple with the selected functors.
rst_running: lbexec DaVinciExamples.tupling.AllFunctors_TurboSpruce:alg_config $DAVINCIEXAMPLESROOT/example_options/example_tupling_allfunctors_TurboSpruce.yaml
rst_yaml: ../DaVinciExamples/example_options/example_tupling_allfunctors_TurboSpruce.yaml
"""
__author__ = "P. Koppenburg"
__date__ = "2021-11-23"
import Functors as F
import FunTuple.functorcollections as FC
from FunTuple import FunctorCollection
from FunTuple import FunTuple_Particles as Funtuple
from PyConf.reading import get_particles, get_pvs
from DaVinci.algorithms import create_lines_filter
from PyConf.reading import get_odin # get_decreports,
from DecayTreeFitter import DecayTreeFitter
from PyConf.Algorithms import PrintDecayTree
from DaVinci import Options, make_config
#
# Definition of TurboSpruce line taken from the output of Moore.sprucing.qms.test_spruce_turbooverlap.qmt
#
b02kstgamma_line = "Hlt2Lineone_extraoutputs"
_basic = "basic"
_composite = "composite"
_toplevel = "toplevel"
def all_variables(pvs, dtf, ptype, candidates=None):
"""
function that returns dictionary of functors that work.
functors are listed in order of https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors_reference.html#module-Functors
"""
if ptype not in [_basic, _composite]:
Exception(f"I want {_basic} or {_composite}. Got {ptype}")
all_vars = FunctorCollection({})
comp = _composite == ptype or _toplevel == ptype # is composite
basic = _basic == ptype # is not composite
top = _toplevel == ptype # the B
# First import everything that comes in functorcollections
all_vars += FC.Kinematics()
if basic:
all_vars += FC.ParticleID(extra_info=True)
Hlt1_decisions = ["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"]
if candidates:
all_vars += FC.HltTisTos(
selection_type="Hlt", trigger_lines=Hlt1_decisions, data=candidates
)
#
# FTAlg not yet implemented
# For Track isolation see weightedrelations_trackvariables
#
# Now all other functors
# ALL : Not useful for tupling
if comp:
all_vars.update({"ALV": F.ALV(Child1=1, Child2=2)})
if comp: # all these require a vertex
all_vars.update({"BPVCORRM": F.BPVCORRM(pvs)})
all_vars.update({"BPVCORRMERR": F.BPVCORRMERR(pvs)})
all_vars.update({"BPVDIRA": F.BPVDIRA(pvs)})
all_vars.update({"BPVDLS": F.BPVDLS(pvs)})
all_vars.update({"BPVETA": F.BPVETA(pvs)})
all_vars.update({"BPVFD": F.BPVFD(pvs)})
all_vars.update({"BPVFDCHI2": F.BPVFDCHI2(pvs)})
all_vars.update({"BPVFDIR": F.BPVFDIR(pvs)})
all_vars.update({"BPVFDVEC": F.BPVFDVEC(pvs)})
all_vars.update({"BPVIP": F.BPVIP(pvs)})
all_vars.update({"BPVIPCHI2": F.BPVIPCHI2(pvs)})
all_vars.update({"BPVX": F.BPVX(pvs)})
all_vars.update({"BPVY": F.BPVY(pvs)})
all_vars.update({"BPVZ": F.BPVZ(pvs)})
# When storing variable length array one can
# give a custom branch name for the index.
# This can be achieved by enclosing custom index
# name within square brackets (see code below).
# The branch name ("nPV") will correspond to the
# index of the PV. If no index branch name given i.e.
# all_vars.update({ 'ALLPVX'] the default "indx" is used.
all_vars.update({"ALLPVX[nPVs]": F.ALLPVX(pvs)})
all_vars.update({"ALLPVY[nPVs]": F.ALLPVY(pvs)})
all_vars.update({"ALLPVZ[nPVs]": F.ALLPVZ(pvs)})
if comp: # all these require a vertex
all_vars.update({"ALLPV_FD[nPVs]": F.ALLPV_FD(pvs)})
all_vars.update({"ALLPV_IP[nPVs]": F.ALLPV_IP(pvs)})
all_vars.update({"BPVLTIME": F.BPVLTIME(pvs)})
all_vars.update({"BPVVDRHO": F.BPVVDRHO(pvs)})
all_vars.update({"BPVVDX": F.BPVVDX(pvs)})
all_vars.update({"BPVVDY": F.BPVVDY(pvs)})
all_vars.update({"BPVVDZ": F.BPVVDZ(pvs)})
all_vars.update({"CHARGE": F.CHARGE})
all_vars.update({"CHI2": F.CHI2})
all_vars.update({"CHI2DOF": F.CHI2DOF})
if top: # apply this only to B
all_vars.update({"CHILD1_PT": F.CHILD(1, F.PT)}) # example of CHILD
all_vars.update({"Ds_END_VZ": F.CHILD(1, F.END_VZ)})
all_vars.update({"Delta_END_VZ_DsB0": F.CHILD(1, F.END_VZ) - F.END_VZ})
# if basic: all_vars.update({ 'CLOSESTTOBEAM' : F.CLOSESTTOBEAM # 'Track__ClosestToBeamState' object has no attribute 'to_json'
# COMB
# if basic: all_vars.update({ 'COV' : F.COV # 'Track__Covariance' object has no attribute 'to_json'
if comp:
all_vars.update({"DOCA": F.SDOCA(Child1=1, Child2=2)})
all_vars.update({"DOCACHI2": F.SDOCACHI2(Child1=1, Child2=2)})
all_vars.update({"END_VRHO": F.END_VRHO})
all_vars.update({"END_VX": F.END_VX})
all_vars.update({"END_VY": F.END_VY})
all_vars.update({"END_VZ": F.END_VZ})
# duplicated from FC all_vars.update({ 'ENERGY' : F.ENERGY})
all_vars.update({"ETA": F.ETA})
all_vars.update({"FOURMOMENTUM": F.FOURMOMENTUM})
all_vars.update({"ISBASIC": F.ISBASICPARTICLE})
if basic:
all_vars.update({"GHOSTPROB": F.GHOSTPROB})
all_vars.update({"ISMUON": F.ISMUON})
all_vars.update({"INMUON": F.INMUON})
all_vars.update({"INECAL": F.INECAL})
all_vars.update({"INHCAL": F.INHCAL})
all_vars.update({"HASBREM": F.HASBREM})
all_vars.update({"HASBREMADDED": F.HASBREMADDED})
all_vars.update({"BREMENERGY": F.BREMENERGY})
all_vars.update({"BREMBENDCORR": F.BREMBENDCORR})
all_vars.update({"BREMPIDE": F.BREMPIDE})
all_vars.update({"ECALPIDE": F.ECALPIDE})
all_vars.update({"ECALPIDMU": F.ECALPIDMU})
all_vars.update({"HCALPIDE": F.HCALPIDE})
all_vars.update({"HCALPIDMU": F.HCALPIDMU})
all_vars.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP})
all_vars.update({"ELECTRONSHOWERDLL": F.ELECTRONSHOWERDLL})
all_vars.update({"CLUSTERID": F.CLUSTERID})
all_vars.update({"CLUSTERMATCH_CHI2": F.CLUSTERMATCH_CHI2})
all_vars.update({"ELECTRONMATCH_CHI2": F.ELECTRONMATCH_CHI2})
all_vars.update({"BREMHYPOMATCH_CHI2": F.BREMHYPOMATCH_CHI2})
all_vars.update({"ELECTRONENERGY": F.ELECTRONENERGY})
all_vars.update({"BREMHYPOENERGY": F.BREMHYPOENERGY})
all_vars.update({"BREMHYPODELTAX": F.BREMHYPODELTAX})
all_vars.update({"BREMTRACKBASEDENERGY": F.BREMTRACKBASEDENERGY})
all_vars.update({"ELECTRONID": F.ELECTRONID})
all_vars.update({"HCALEOP": F.HCALEOP})
# Note: the observables for the two functors below are (TRACK_MOM_X, TRACK_MOM_Y, TRACK_MOM_Z})
# and (TRACK_POS_CLOSEST_TO_BEAM_X, TRACK_POS_CLOSEST_TO_BEAM_Y, TRACK_POS_CLOSEST_TO_BEAM_Z),
# which is why the trailing underscore in the name is added i.e. "TRACK_MOM_" and "TRACK_POS_CLOSEST_TO_BEAM_"
all_vars.update({"TRACK_MOM_": F.TRACK_MOMVEC})
all_vars.update({"TRACK_POS_CLOSESTTOBEAM_": F.TRACK_POSVEC_CLOSESTTOBEAM})
all_vars.update({"IS_ABS_ID_pi": F.IS_ABS_ID("pi+")})
all_vars.update({"IS_ID_pi": F.IS_ID("pi-")})
all_vars.update({"PDG_MASS_pi": F.PDG_MASS("pi+")})
all_vars.update({"SIGNED_DELTA_MASS_pi": F.SIGNED_DELTA_MASS("pi+")})
all_vars.update({"ABS_DELTA_MASS_pi": F.ABS_DELTA_MASS("pi+")})
all_vars.update({"IS_NOT_H": F.IS_NOT_H})
all_vars.update({"IS_PHOTON": F.IS_PHOTON})
all_vars.update({"THREE_MOM_COV_MATRIX": F.THREE_MOM_COV_MATRIX})
all_vars.update({"POS_COV_MATRIX": F.POS_COV_MATRIX})
all_vars.update({"MOM_POS_COV_MATRIX": F.MOM_POS_COV_MATRIX})
all_vars.update({"THREE_MOM_POS_COV_MATRIX": F.THREE_MOM_POS_COV_MATRIX})
all_vars.update({"DTF_PT": dtf(F.PT)})
all_vars.update({"DTF_BPVIPCHI2": dtf(F.BPVIPCHI2(pvs))})
all_vars.update(
{
"DTF_MASS_SmallestDELTAPT": F.MASS
@ F.TO
@ F.ENTRY_WITH_MIN_REL_VALUE_OF(
F.PT @ F.TO @ F.FORWARDARG0 - F.PT @ F.FORWARDARG1
).bind(
F.RELATIONS.bind(F.TES(dtf.OutputRelations), F.FORWARDARGS),
F.FORWARDARGS,
)
}
)
all_vars.update(
{
"DTF_MASS_BiggestDELTAPT": F.MASS
@ F.TO
@ F.ENTRY_WITH_MAX_REL_VALUE_OF(
F.PT @ F.TO @ F.FORWARDARG0 - F.PT @ F.FORWARDARG1
).bind(
F.RELATIONS.bind(F.TES(dtf.OutputRelations), F.FORWARDARGS),
F.FORWARDARGS,
)
}
)
if top:
all_vars.update({"DTF_NITER": dtf.NITER})
all_vars.update({"DTF_CHI2": dtf.CHI2})
all_vars.update({"DTF_NDOF": dtf.NDOF})
all_vars.update({"DTF_CHI2DOF": dtf.CHI2DOF})
if comp:
all_vars.update({"DTF_MASS": dtf.MASS})
all_vars.update({"DTF_MASSERR": dtf.MASSERR})
all_vars.update({"DTF_P": dtf.P})
all_vars.update({"DTF_PERR": dtf.PERR})
all_vars.update({"DTF_CTAU": dtf.CTAU})
all_vars.update({"DTF_CTAUERR": dtf.CTAUERR})
all_vars.update({"DTF_FD": dtf.FD})
all_vars.update({"DTF_FDERR": dtf.FDERR})
all_vars.update({"MASS": F.MASS})
if top: # B
all_vars.update(
{"MASSWITHHYPOTHESES": F.MASSWITHHYPOTHESES((939.0, 939.0))}
) # unphysical
elif comp: # Kst
all_vars.update({"MASSWITHHYPOTHESES": F.MASSWITHHYPOTHESES((493.7, 139.6))})
if comp:
all_vars.update({"MAXPT": F.MAX(F.PT)})
all_vars.update({"MAXDOCA": F.MAXSDOCA})
all_vars.update({"MAXDOCACHI2": F.MAXSDOCACHI2})
# the above in cut versions.
# duplicated from FC all_vars.update({ 'MC_MOTHER_ID' : F.VALUE_OR(0) @ mctruth(
# duplicated from FC F.MC_MOTHER(1, F.PARTICLE_ID))})
if comp:
all_vars.update({"MINPT": F.MIN(F.PT)})
all_vars.update({"MINIP": F.MINIP(pvs)})
all_vars.update({"MINIPCHI2": F.MINIPCHI2(pvs)})
if basic:
all_vars.update({"TRACKPT": F.TRACK_PT})
all_vars.update({"TRACKHISTORY": F.VALUE_OR(-1) @ F.TRACKHISTORY @ F.TRACK})
all_vars.update({"QOVERP": F.QOVERP @ F.TRACK})
all_vars.update({"NDOF": F.VALUE_OR(-1) @ F.NDOF @ F.TRACK})
all_vars.update({"NFTHITS": F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK})
all_vars.update({"NHITS": F.VALUE_OR(-1) @ F.NHITS @ F.TRACK})
all_vars.update({"NUTHITS": F.VALUE_OR(-1) @ F.NUTHITS @ F.TRACK})
all_vars.update({"NVPHITS": F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK})
all_vars.update({"TRACKHASVELO": F.VALUE_OR(-1) @ F.TRACKHASVELO @ F.TRACK})
all_vars.update({"TRACKHASUT": F.VALUE_OR(-1) @ F.TRACKHASUT @ F.TRACK})
all_vars.update({"STATE_AT_T1": F.EXTRAPOLATE_TRACK(7931.0) @ F.TRACK})
all_vars.update({"OBJECT_KEY": F.OBJECT_KEY})
# duplicated from FC all_vars.update({ 'ORIGIN_VX' : mctruth(F.ORIGIN_VX)})
# duplicated from FC all_vars.update({ 'ORIGIN_VY' : mctruth(F.ORIGIN_VY)})
# duplicated from FC all_vars.update({ 'ORIGIN_VZ' : mctruth(F.ORIGIN_VZ)})
# duplicated from FC all_vars.update({ 'P' : F.P})
# duplicated from FC all_vars.update({ 'PARTICLE_ID' : F.PARTICLE_ID})
all_vars.update({"PHI": F.PHI})
# duplicated from FC if basic:
# duplicated from FC all_vars.update({ 'PID_E' : F.PID_E})
# duplicated from FC all_vars.update({ 'PID_K' : F.PID_K})
# duplicated from FC all_vars.update({ 'PID_MU' : F.PID_MU})
# duplicated from FC all_vars.update({ 'PID_P' : F.PID_P})
# duplicated from FC all_vars.update({ 'PID_PI' : F.PID_PI})
# POD
# duplicated from FC all_vars.update({ 'PROBNN_D' : F.PROBNN_D})
# duplicated from FC all_vars.update({ 'PROBNN_E' : F.PROBNN_E})
# duplicated from FC all_vars.update({ 'PROBNN_GHOST' : F.PROBNN_GHOST})
# duplicated from FC all_vars.update({ 'PROBNN_K' : F.PROBNN_K})
# duplicated from FC all_vars.update({ 'PROBNN_MU' : F.PROBNN_MU})
# duplicated from FC all_vars.update({ 'PROBNN_P' : F.PROBNN_P})
# duplicated from FC all_vars.update({ 'PROBNN_PI' : F.PROBNN_PI})
# duplicated from FC all_vars.update({ 'PT' : F.PT})
# duplicated from FC all_vars.update({ 'PX' : F.PX})
# duplicated from FC all_vars.update({ 'PY' : F.PY})
# duplicated from FC all_vars.update({ 'PZ' : F.PZ})
all_vars.update({"ABS_PX": F.ABS @ F.PX})
all_vars.update({"REFERENCEPOINT_X": F.REFERENCEPOINT_X})
all_vars.update({"REFERENCEPOINT_Y": F.REFERENCEPOINT_Y})
all_vars.update({"REFERENCEPOINT_Z": F.REFERENCEPOINT_Z})
if comp:
all_vars.update({"SDOCA": F.SDOCA(1, 2)})
all_vars.update({"SDOCACHI2": F.SDOCACHI2(1, 2)})
if basic:
all_vars.update({"SHOWER_SHAPE": F.CALO_NEUTRAL_SHOWER_SHAPE})
if comp:
all_vars.update({"SUBCOMB12_MM": F.SUBCOMB(Functor=F.MASS, Indices=(1, 2))})
all_vars.update({"SUMPT": F.SUM(F.PT)})
if basic:
all_vars.update({"TX": F.TX})
all_vars.update({"TY": F.TY})
print(f"### For {ptype} returning variables {all_vars.functor_dict.keys()}")
return all_vars
def event_variables(PVs, ODIN, decreports, lines):
"""
event variables
"""
evt_vars = FunctorCollection({})
evt_vars += FC.EventInfo()
evt_vars += FC.SelectionInfo(selection_type="Hlt2", trigger_lines=lines)
# duplicated from FC if ODIN:
# duplicated from FC evt_vars.update({ 'BUNCHCROSSING_ID' : F.BUNCHCROSSING_ID(ODIN)})
# duplicated from FC evt_vars.update({ 'BUNCHCROSSING_TYPE' : F.BUNCHCROSSING_TYPE(ODIN)})
if decreports:
evt_vars.update(
{
"DECISIONS": F.DECISIONS(
Lines=[b02kstgamma_line + "Decision"], DecReports=decreports
)
}
)
evt_vars.update(
{
"DECREPORTS_FILTER": F.DECREPORTS_FILTER(
Lines=[b02kstgamma_line + "Decision"], DecReports=decreports
)
}
)
if ODIN:
evt_vars.update({"EVENTTYPE": F.EVENTTYPE(ODIN)})
# duplicated from FC evt_vars.update({ 'GPSTIME' : F.GPSTIME(ODIN)})
# duplicated from FC evt_vars.update({ 'ODINTCK' : F.ODINTCK(ODIN)})
evt_vars.update({"PV_SIZE": F.SIZE(PVs)})
# duplicated from FC evt_vars.update({ 'GPSTIME' : F.GPSTIME(ODIN)})
# duplicated from FC evt_vars.update({ 'ODINTCK' : F.ODINTCK(ODIN)})
if decreports:
evt_vars.update({"TCK": F.TCK(decreports)})
print(f"### For event returning variables {evt_vars.functor_dict.keys()}")
return evt_vars
def alg_config(options: Options):
"""
Algorithm configuration function called from the command line
"""
# get the particles from line
b02kstgamma_data = get_particles(f"/Event/Turbo/{b02kstgamma_line}/Particles")
#
# DecayTreeFitter Algorithm
#
v2_pvs = get_pvs()
#
# DecayTreeFitter Algorithm with "name" and "input_particles" as arguments
#
DTF = DecayTreeFitter(name="DTF_B02Kstgamma", input_particles=b02kstgamma_data)
#
# Definition of fields (branches) and functors
#
fields_dsk = {
"B0": "[B0 -> (K*(892)0 -> K+ pi-) gamma]CC",
"Kst": "[B0 -> ^(K*(892)0 -> K+ pi-) gamma]CC",
"Kp": "[B0 -> (K*(892)0 -> ^K+ pi-) gamma]CC",
"pim": "[B0 -> (K*(892)0 -> K+ ^pi-) gamma]CC",
"gamma": "[B0 -> (K*(892)0 -> K+ pi-) ^gamma]CC",
}
variables_dsk = {
"B0": all_variables(v2_pvs, DTF, _toplevel),
"Kp": all_variables(v2_pvs, DTF, _basic),
# "gamma": all_variables(v2_pvs, DTF, _basic),
"Kst": all_variables(v2_pvs, DTF, _composite),
}
#
# event variables
odin = get_odin()
# decreports = get_decreports('Spruce')
decreports = None
evt_vars = event_variables(
v2_pvs, odin, decreports, [b02kstgamma_line + "Decision"]
)
#
# Sprucing filter
#
my_filter = create_lines_filter(
name="HDRFilter_B0DsK", lines=[f"{b02kstgamma_line}"]
)
#
# FunTuple
#
my_tuple = Funtuple(
name="B0DsK_Tuple",
tuple_name="DecayTree",
fields=fields_dsk,
variables=variables_dsk,
event_variables=evt_vars,
loki_preamble=[],
inputs=b02kstgamma_data,
)
#
# Algorithms to be run
#
return make_config(
options, [my_filter, PrintDecayTree(Input=b02kstgamma_data), my_tuple]
)
<?xml version="1.0" ?>
<!--
###############################################################################
# (c) Copyright 2021-2024 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. #
###############################################################################
-->
<!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
<!--
#######################################################
# SUMMARY OF THIS TEST
# ...................
# Author: nskidmor
# Purpose: Test for All functors for TurboSpruce
# Prerequisites: None
#######################################################
-->
<extension class="GaudiTest.GaudiExeTest" kind="test">
<argument name="program"><text>lbexec</text></argument>
<!-- Uses output of Moore.sprucing.qms.test_spruce_turbooverlap.qmt -->
<argument name="extra_options_yaml"><text>
input_files:
- root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp1/temp/spruce_overlaptest.streamone.dst
input_manifest_file: 'root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp1/temp/spruce_overlaptest.tck.json'
input_type: ROOT
simulation: False
conddb_tag: sim-20171127-vc-md100
dddb_tag: dddb-20171126
conditions_version: master
geometry_version: run3/trunk
input_raw_format: 0.5
persistreco_version: 0.0
lumi: false
ntuple_file: 'DV_example_allFunctors_ntp_TurboSpruce.root'
print_freq: 1
input_process: TurboSpruce
input_stream: streamone
output_level: 3
</text></argument>
<argument name="timeout"><integer>1000</integer></argument>
<argument name="args"><set>
<text>DaVinciExamples.tupling.AllFunctors_TurboSpruce:alg_config</text>
</set></argument>
<argument name="validator"><text>
from Moore.qmtest.exclusions import remove_known_warnings
countErrorLines({"FATAL": 0, "WARNING": 0, "ERROR": 0},
stdout=remove_known_warnings(stdout))
findReferenceBlock("""HLTControlFlowMgr INFO StateTree: CFNode #executed #passed
LAZY_AND: DaVinci #=60 Sum=60 Eff=|( 100.0000 +- 0.00000 )%|
NONLAZY_OR: UserAnalysis #=60 Sum=60 Eff=|( 100.0000 +- 0.00000 )%|
LAZY_AND: default #=60 Sum=60 Eff=|( 100.0000 +- 0.00000 )%|
VoidFilter/HDRFilter_B0DsK #=60 Sum=60 Eff=|( 100.0000 +- 0.00000 )%|
PrintDecayTree/PrintDecayTree_62b3178c #=60 Sum=60 Eff=|( 100.0000 +- 0.00000 )%|
FunTupleBase_Particles/B0DsK_Tuple #=60 Sum=60 Eff=|( 100.0000 +- 0.00000 )%|""")
</text></argument>
</extension>
testfiledb_key: DaVinciTutorialsHLT2MC
evt_max: 100
ntuple_file: davinci_ntuple.root
input_process: Hlt2
print_freq: 1
lumi: False
......@@ -14,9 +14,10 @@
<!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
<extension class="GaudiTest.GaudiExeTest" kind="test">
<argument name="program"><text>lbexec</text></argument>
<argument name="options_yaml_fn"><text>$DAVINCITUTORIALSROOT/options.yaml</text></argument>
<argument name="options_yaml_fn"><text>$DAVINCITUTORIALSROOT/options_mctruth.yaml</text></argument>
<argument name="extra_options_yaml"><text>
ntuple_file: tutorial5_MCTruth.root
simulation: True
</text></argument>
<argument name="args"><set>
<text>DaVinciTutorials.tutorial5_MCTruth:main</text>
......@@ -44,7 +45,7 @@ df = get_pandas_dataframe(ntuple.name, 'TDirectoryName/TTreeName')
# Check ntuple structure
if df.empty:
causes.append(f"File {ntuple}: ntuple does not contain any branches")
if df.shape != (41, 39):
if df.shape != (15, 39):
causes.append("Ntuple not with expected number of entries and/or branches")
# Check there are no NaN values in the ntuple except where expected
......@@ -58,13 +59,14 @@ if sorted(l_test) != sorted(l_branches_with_nans):
if ((df.filter(regex=("[B|J|P].*TRUEID"))==0).all().all() or (df.filter(regex=("[K|Mu].*TRUEID"))==0).all().all()): # If all TRUEIDS are 0 something is wrong
causes.append("Ntuple contains unexpected TRUEID values") # no matched MC
if not ((df["Km_TRUEID"]).sum() + (df["Kp_TRUEID"]).sum() + (df["Mum_TRUEID"]).sum() + (df["Mup_TRUEID"]).sum() == 0 ): # ABS(TRUEID) should be consistent for particles and particles in final state
causes.append("Ntuple contains unexpected TRUEID values")
# Check background categories
if not (df.filter(regex=("[K|Mu].*BKGCAT"))==-1).all().all() or ((df.filter(regex=("[B|J|P].*BKGCAT"))!=0).all().all()): #Should have some true signal and K and Mu have BKGCAT=-1
causes.append("Ntuple contains unexpected BKGCAT values")
# To check the TRUEIDs we need to be sure we are dealing with true signal
df = df[(df["Bs_BKGCAT"]==0)]
if not ((df["Km_TRUEID"]).sum() + (df["Kp_TRUEID"]).sum() + (df["Mum_TRUEID"]).sum() + (df["Mup_TRUEID"]).sum() == 0 ): # ABS(TRUEID) should be consistent for particles and particles in final state
causes.append("Ntuple contains unexpected TRUEID values")
ntuple.unlink()
print('Test successfully completed!')
......
This diff is collapsed.
......@@ -75,7 +75,12 @@ class Options(DefaultOptions):
values["input_stream"] = input_stream.lower()
if (
input_process not in {InputProcessTypes.Spruce, InputProcessTypes.TurboPass}
input_process
not in {
InputProcessTypes.Spruce,
InputProcessTypes.TurboPass,
InputProcessTypes.TurboSpruce,
}
and input_stream != ""
):
logging.getLogger(__name__).warning(
......@@ -100,6 +105,7 @@ class Options(DefaultOptions):
input_process = values.get("input_process", None)
input_type = values.get("input_type", FileFormats.NONE)
output_type = values.get("output_type", FileFormats.ROOT)
simulation = values.get("simulation", None)
# Jobs on Spruced samples are DST -> DST only
if input_process in {InputProcessTypes.TurboPass, InputProcessTypes.Spruce}:
......@@ -111,6 +117,14 @@ class Options(DefaultOptions):
raise ValueError(
f"Jobs on Spruced data are DST -> ROOT but output_type={output_type!r} was given."
)
if (
input_process
in [InputProcessTypes.TurboSpruce, InputProcessTypes.TurboPass]
and simulation
) and not issubclass(cls, TestOptions):
raise ValueError(
f"TurboSpruce and TurboPass is not supported for simulation. input_process={input_process!r} and simulation={simulation!r} was given."
)
return values
......@@ -167,6 +181,7 @@ class Options(DefaultOptions):
InputProcessTypes.Hlt2,
InputProcessTypes.Spruce,
InputProcessTypes.TurboPass,
InputProcessTypes.TurboSpruce,
]:
reconstruction.global_bind(from_file=True, spruce=True)
......@@ -174,6 +189,7 @@ class Options(DefaultOptions):
InputProcessTypes.Hlt2,
InputProcessTypes.Spruce,
InputProcessTypes.TurboPass,
InputProcessTypes.TurboSpruce,
InputProcessTypes.Brunel,
]:
......
......@@ -43,7 +43,7 @@ def test_add_hlt2_filter():
options = Options(
input_raw_format=0.5,
evt_max=1,
simulation=True,
simulation=False,
input_process="Hlt2",
input_type="ROOT",
input_files="/Some/Dummy.DST",
......@@ -68,7 +68,7 @@ def test_add_spruce_filter():
options = Options(
input_raw_format=0.5,
evt_max=1,
simulation=True,
simulation=False,
input_type="ROOT",
input_process="Spruce",
input_stream="default",
......@@ -109,7 +109,7 @@ def test_configured_funtuple():
evt_max=1,
output_level=3,
input_raw_format=0.5,
simulation=True,
simulation=False,
)
with default_raw_event.bind(
raw_event_format=options.input_raw_format, stream=options.input_stream
......@@ -130,7 +130,7 @@ def test_get_odin():
input_process="Gen",
evt_max=1,
input_raw_format=0.5,
simulation=True,
simulation=False,
)
with default_raw_event.bind(raw_event_format=options.input_raw_format):
odin = get_odin()
......@@ -145,7 +145,7 @@ def test_get_decreports():
options = Options(
input_raw_format=0.5,
evt_max=1,
simulation=True,
simulation=False,
input_process="TurboPass",
input_stream="TurboSP",
input_type="ROOT",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment