diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e8438fa5fee5cd99eac35c44c2b94f38235abc7..6ccdafbfe0ca9b6420e0c071bc7bd2ba18cffb09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,8 +22,10 @@ if (USE_DD4HEP) endif() # Declare project name and version + gaudi_project(Moore v51r0 - USE Phys v31r0 + USE Phys v31r0 + Allen v0r9 DATA AppConfig VERSION v3r* FieldMap VERSION v5r* PRConfig VERSION v1r* diff --git a/Hlt/Hlt1Conf/options/allen_hlt1_pp_default.py b/Hlt/Hlt1Conf/options/allen_hlt1_pp_default.py new file mode 100644 index 0000000000000000000000000000000000000000..1022ff7f5ac64119819d1ce8272a2cf671c902fb --- /dev/null +++ b/Hlt/Hlt1Conf/options/allen_hlt1_pp_default.py @@ -0,0 +1,16 @@ +############################################################################### +# (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. # +############################################################################### +import os, json + +from Moore import options, run_allen +from Hlt1Conf.settings import allen_lines + +run_allen(options) diff --git a/Hlt/Hlt1Conf/python/Hlt1Conf/lines/allen.py b/Hlt/Hlt1Conf/python/Hlt1Conf/lines/allen.py new file mode 100644 index 0000000000000000000000000000000000000000..0289752f1f16aa5c515ac69c970a52b38041c6b2 --- /dev/null +++ b/Hlt/Hlt1Conf/python/Hlt1Conf/lines/allen.py @@ -0,0 +1,20 @@ +############################################################################### +# (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. # +############################################################################### +from Moore.config import HltLine + +from RecoConf.hlt1_allen import make_allen_dec_reports + + +def allen_line(name='Hlt1Allen', prescale=1): + + allen = make_allen_dec_reports() + + return HltLine(name=name, algs=[allen], prescale=prescale) diff --git a/Hlt/Hlt1Conf/python/Hlt1Conf/settings.py b/Hlt/Hlt1Conf/python/Hlt1Conf/settings.py index 5367922e3f7110afd2267676fd2f9802fc510dcb..f620aefcd777e92cf5b2c7b03f25e20c4d671d3f 100644 --- a/Hlt/Hlt1Conf/python/Hlt1Conf/settings.py +++ b/Hlt/Hlt1Conf/python/Hlt1Conf/settings.py @@ -23,6 +23,8 @@ from Hlt1Conf.lines.minimum_bias import ( ) from Hlt1Conf.lines.luminosity import luminosity_line +from Hlt1Conf.lines.allen import allen_line + def track_mva_lines(): return [ @@ -83,3 +85,7 @@ def comparison_lines(): one_track_muon_highpt_line(), #gec_passthrough_line() ] + + +def allen_lines(): + return [allen_line()] diff --git a/Hlt/Hlt1Conf/tests/options/allen_hlt1_mdf_output.py b/Hlt/Hlt1Conf/tests/options/allen_hlt1_mdf_output.py new file mode 100644 index 0000000000000000000000000000000000000000..b6d0fd56e7d6a47f6965a733979de438c7a281d3 --- /dev/null +++ b/Hlt/Hlt1Conf/tests/options/allen_hlt1_mdf_output.py @@ -0,0 +1,15 @@ +############################################################################### +# (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. # +############################################################################### +"""Write an HLT1-filtered MDF file.""" +from Moore import options + +options.output_file = 'test_allen_hlt1_persistence_mdf_write.mdf' +options.output_type = 'MDF' diff --git a/Hlt/Hlt1Conf/tests/options/test_allen_decreports.py b/Hlt/Hlt1Conf/tests/options/test_allen_decreports.py new file mode 100644 index 0000000000000000000000000000000000000000..a91ceb0bb6925ac2166d1a6ac8f9c53664e9ac9d --- /dev/null +++ b/Hlt/Hlt1Conf/tests/options/test_allen_decreports.py @@ -0,0 +1,126 @@ +############################################################################### +# (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. # +############################################################################### +"""Compare decisions from a log file to those stored in a MDF. + +Takes three outputs from a previously-ran job: the options dump, the log +file, and the MDF. The decisions printed in the form of counters of the RunAllen algorithm are +compared to those taken from the DecReports found in the MDF. Any difference +between the two is considered a failure. The options dump is used to +configure the HltANNSvc for the job ran by this script. +""" +from __future__ import print_function +import argparse + +from Configurables import ( + ApplicationMgr, + HistogramPersistencySvc, + HltANNSvc, + IODataManager, + LHCbApp, +) +from DAQSys.Decoders import DecoderDB +from GaudiConf import IOHelper +import GaudiPython + +from PyConf.utilities import read_options + +# Top-level control flow node +ALLEN_KEY = "allen" + + +def get_counts_from_log(f): + """Return the decisions of each line as extracted from a log file.""" + counts = {} + with open(f) as f: + for line in filter(lambda l: "Selected by" in l, f): + columns = line.split() + hlt_line = columns[2].replace('"', '') + count = int(columns[6]) + counts[hlt_line] = count + f.seek(0) + for line in filter(lambda l: "NONLAZY_OR: allen" in l, f): + columns = line.split() + hlt_line = columns[1] + count = int(columns[3].replace("Sum=", "")) + counts[hlt_line] = count + return counts + + +parser = argparse.ArgumentParser() +parser.add_argument("--input-mdf", help="Input MDF file") +parser.add_argument("--input-log", help="Input log file") +parser.add_argument( + "--input-options", help="Input options file (Python format)") +args = parser.parse_args() + +# Configure basic application with inputs +LHCbApp(DataType="Upgrade") +IOHelper("MDF").inputFiles([args.input_mdf]) +# Disable warning about not being able to navigate ancestors +IODataManager(DisablePFNWarning=True) +# Disable warning about histogram saving not being required +HistogramPersistencySvc(OutputLevel=5) +# Decode Hlt DecReports +ApplicationMgr( + TopAlg=[DecoderDB["HltDecReportsDecoder/Hlt1DecReportsDecoder"].setup()]) + +# Get expected lines and HltANNSvc configuration from the previous job +options = read_options(args.input_options) +Hlt1SelectionIDs = options["HltANNSvc"]["Hlt1SelectionID"] +HltANNSvc().Hlt1SelectionID = Hlt1SelectionIDs +print(Hlt1SelectionIDs) + +# Set up counters for recording decisions from MDF +counts_from_mdf = {key: 0 for key in Hlt1SelectionIDs} +counts_from_mdf[ALLEN_KEY] = 0 +# Extract counters from log file of the previous job +counts_from_log = get_counts_from_log(args.input_log) + +gaudi = GaudiPython.AppMgr() +TES = gaudi.evtSvc() +gaudi.run(1) + +error = False +while TES["/Event"]: + decs = TES["/Event/Hlt1/DecReports"] + if not decs: + print("DecReports TES location not found") + error = True + break + + triggered = False + for key in counts_from_mdf.keys(): + if key == ALLEN_KEY: + continue + counts_from_mdf[key] += int(decs.decReport(key).decision()) + if decs.decReport(key).decision(): + triggered = True + if triggered: + counts_from_mdf[ALLEN_KEY] += 1 + + gaudi.run(1) + +for key in counts_from_mdf.keys(): + line_name = key + if line_name not in counts_from_log.keys(): + error = True + print("Test ERROR: Line {} missing".format(line_name)) + else: + if counts_from_mdf[key] != counts_from_log[line_name]: + error = True + print("Test ERROR: Counts of {} wrong, log = {}, mdf = {}".format( + key, counts_from_log[line_name], counts_from_mdf[key])) + else: + print("Counts of {}, log = {}, mdf = {}".format( + key, counts_from_log[line_name], counts_from_mdf[key])) + +if error: + exit("Test failed") # exit with a non-zero code diff --git a/Hlt/Hlt1Conf/tests/qmtest/persistency.qms/allen_mdf_write.qmt b/Hlt/Hlt1Conf/tests/qmtest/persistency.qms/allen_mdf_write.qmt new file mode 100644 index 0000000000000000000000000000000000000000..882146722c67ebf6c3bf840771fe1da996d5f69a --- /dev/null +++ b/Hlt/Hlt1Conf/tests/qmtest/persistency.qms/allen_mdf_write.qmt @@ -0,0 +1,85 @@ + + + + +gaudirun.py + + $MOOREROOT/tests/options/default_input_and_conds_hlt1.py + $HLT1CONFROOT/tests/options/allen_hlt1_mdf_output.py + $HLT1CONFROOT/options/allen_hlt1_pp_default.py + --output=allen_mdf_write.opts.py + --all-opts + +true + + + +import re + +# Check that: +# 1. We read at least two events +# 2. We make a positive decision with the TrackMVA line on at least one event +# 3. We make a negative decision with the TrackMVA line on at least one event +# 4. We make a positive decision with the TwoTrackMVA line on at least one event +# 5. We make a negative decision with the TwoTrackMVA line on at least one event + +pattern = re.compile(r'\s+\|\*"Selected by Hlt1TrackMVADecision"\s+\|\s+(\d+)\s+\|\s+(\d+)') +nread = nselected = -1 +for line in stdout.split('\n'): + m = re.match(pattern, line) + if m: + print m + nread, nselected = map(int, m.groups()) + break +else: + causes.append('could not parse event statistics from stdout') + +if nread < 2: + causes.append('expected at least two events to be processed') + +if nselected < 1: + causes.append('expected at least one event to be selected by TrackMVALine') + +if nselected == nread: + causes.append('expected at least one event to be filtered out by TrackMVALine') + +pattern = re.compile(r'\s+\|\*"Selected by Hlt1TwoTrackMVADecision"\s+\|\s+(\d+)\s+\|\s+(\d+)') +nread = nselected = -1 +for line in stdout.split('\n'): + m = re.match(pattern, line) + if m: + print m + nread, nselected = map(int, m.groups()) + break +else: + causes.append('could not parse event statistics from stdout') + +if nread < 2: + causes.append('expected at least two events to be processed') + +if nselected < 1: + causes.append('expected at least one event to be selected by TwoTrackMVA line') + +if nselected == nread: + causes.append('expected at least one event to be filtered out by TwoTrackMVA line') + + +# Write out the log file so that we can compare the number of +# selected events here with the number of events processed by +# a second HLT1 job that uses the output file as input +with open('test_hlt1_persistence_allen_mdf_write.stdout', 'w') as f: + f.write(stdout) + + + diff --git a/Hlt/Hlt1Conf/tests/qmtest/persistency.qms/mdf_read_decs_allen.qmt b/Hlt/Hlt1Conf/tests/qmtest/persistency.qms/mdf_read_decs_allen.qmt new file mode 100644 index 0000000000000000000000000000000000000000..d1905fbab4ceb78907619a3808e15a03063ce7e4 --- /dev/null +++ b/Hlt/Hlt1Conf/tests/qmtest/persistency.qms/mdf_read_decs_allen.qmt @@ -0,0 +1,34 @@ + + + + + + persistency.allen_mdf_writePASS + +python + + $HLT1CONFROOT/tests/options/test_allen_decreports.py + --input-log=test_hlt1_persistence_allen_mdf_write.stdout + --input-mdf=test_allen_hlt1_persistence_mdf_write.mdf + --input-options=allen_mdf_write.opts.py + +true + + +from Moore.qmtest.exclusions import preprocessor +countErrorLines({"FATAL": 0, "ERROR": 0, "WARNING": 0}, + stdout=preprocessor(stdout)) + + + diff --git a/Hlt/Moore/python/Moore/__init__.py b/Hlt/Moore/python/Moore/__init__.py index 7d6c6220b3e43fda7393aacbed8b2a7113c2dbd8..cf5f1bff822ca95e47456d7779249ef4362e1aa3 100644 --- a/Hlt/Moore/python/Moore/__init__.py +++ b/Hlt/Moore/python/Moore/__init__.py @@ -12,4 +12,5 @@ """ from .config import (options, run_moore, run_reconstruction, - moore_control_flow) # noqa + moore_control_flow, run_allen, + run_allen_reconstruction) # noqa diff --git a/Hlt/Moore/python/Moore/config.py b/Hlt/Moore/python/Moore/config.py index a87b756b9c8fa1a99346b4e8abda3effccabf968..4c1ad0aed4f22426fd331e4ccd016a61767b47a4 100644 --- a/Hlt/Moore/python/Moore/config.py +++ b/Hlt/Moore/python/Moore/config.py @@ -8,9 +8,12 @@ # granted to it by virtue of its status as an Intergovernmental Organization # # or submit itself to any jurisdiction. # ############################################################################### -import re +import re, os, json, logging, inspect from collections import namedtuple -from Configurables import LumiCounterMerger +from Configurables import (LumiCounterMerger, ApplicationMgr, DumpUTGeometry, + DumpFTGeometry, DumpMuonTable, DumpMuonGeometry, + DumpVPGeometry, DumpMagneticField, DumpBeamline, + DumpUTLookupTables, AllenUpdater) from PyConf import configurable from PyConf.Algorithms import (bankKiller, DeterministicPrescaler, ExecutionReportsWriter, HltDecReportsWriter, @@ -29,6 +32,9 @@ from PyConf.application import configure_input, configure from .selreports import make_selreports from .persistency import clone_candidates +from RecoConf.hlt1_allen import make_allen_dec_reports + +log = logging.getLogger(__name__) # TODO move the options global to a separate module such that functions # defined here cannot access it @@ -207,6 +213,12 @@ def report_writers_node(lines, algs.extend([erw, drw]) locations_to_persist.append(drw.OutputRawEventLocation) + Hlt1SelectionIDs = { + line.decision_name: n + for n, line in enumerate(lines, 1) + } + print Hlt1SelectionIDs + hlt_ann_svc = setup_component( "HltANNSvc", # Zero is an invalid DecReport ID, so start from 1 @@ -337,6 +349,163 @@ def run_moore(options, make_lines=None, public_tools=[]): return config +def setup_allen_non_event_data_service(dump_binaries=False): + """Setup Allen non-event data + + An ExtSvc is added to the ApplicationMgr to provide the Allen non-event data (geometries etc.) + """ + producers = [ + p(DumpToFile=dump_binaries) + for p in (DumpVPGeometry, DumpUTGeometry, DumpFTGeometry, + DumpMuonGeometry, DumpMuonTable, DumpMagneticField, + DumpBeamline, DumpUTLookupTables) + ] + ApplicationMgr().ExtSvc += [ + AllenUpdater(OutputLevel=2), + ] + producers + + +def get_allen_hlt1_lines(): + """Read Allen HLT1 lines from json configuration file + + """ + Hlt1SelectionIDs = {} + config_file_path = "$ALLEN_INSTALL_DIR/constants/Sequence.json" + try: + with open(os.path.expandvars(config_file_path)) as config_file: + config = (json.load(config_file)) + except: + log.fatal( + "Could not find Allen sequence file %s; make sure you have built Allen", + config_file_path) + + # lines = [] + # for line in config["configured_lines"]: + # lines.append("Hlt1" + str(line) + "Decision") + # return { + # lines: n + # for n, line in enumerate(lines, 1) + # } + + index = 1 + for line in config["configured_lines"]: + line_name = "Hlt1" + str(line) + "Decision" + Hlt1SelectionIDs[line_name] = index + index += 1 + + return Hlt1SelectionIDs + + +def setup_allen_Hlt1ANN(): + """Configure HltANN service for Allen + + """ + Hlt1SelectionIDs = get_allen_hlt1_lines() + hlt_ann_svc = setup_component( + "HltANNSvc", Hlt1SelectionID=Hlt1SelectionIDs) + + return Hlt1SelectionIDs + + +def allen_control_flow(options): + options.finalize() + + setup_allen_non_event_data_service() + + # Write DecReports raw banks + allen_dec_reports = make_allen_dec_reports() + + # We will write the reports to raw banks at these locations + algs = [] + locations_to_persist = [] + report_banks_to_write = ['HltDecReports'] + reports_raw_event = default_raw_event(report_banks_to_write) + + # TODO we probably shouldn't write in Trigger/RawEvent when + # running on reconstructed data. Instead, we should create a + # RawEvent at DAQ/RawEvent, which would make HltDecReportsWriter + # happy, or make raw events/banks const and adapt everything. + kill_existing = True + if kill_existing: + all_banks_to_write = (report_banks_to_write) + algs.append( + bankKiller( + RawEventLocations=[reports_raw_event], + BankTypes=all_banks_to_write)) + + drw = HltDecReportsWriter( + InputHltDecReportsLocation=allen_dec_reports, + outputs=dict( + OutputRawEventLocation=force_location(reports_raw_event.location)), + ) + + algs.extend([drw]) + locations_to_persist.append(drw.OutputRawEventLocation) + + Hlt1SelectionIDs = setup_allen_Hlt1ANN() + + print Hlt1SelectionIDs + + locations_to_persist.append(reports_raw_event) + + report_writers_node = CompositeNode( + 'report_writers', + combineLogic=NodeLogic.NONLAZY_OR, + children=algs, + forceOrder=True) + + # Transform to a list of unique str + locations_to_persist = list( + set(map(_format_location, locations_to_persist))) + + writers = [report_writers_node] + writers.extend(output_writers(options, locations_to_persist)) + + return CompositeNode( + 'allen', + combineLogic=NodeLogic.NONLAZY_OR, + children=[make_allen_dec_reports()] + writers, + forceOrder=True) + + +def run_allen(options): + """Configure Allen within Mooore. + + Convenience function that sets up an Allen node and sets up services + + Args: + options (ApplicationOptions): holder of application options + + """ + config = configure_input(options) + + top_cf_node = allen_control_flow(options) + + config.update(configure(options, top_cf_node)) + # TODO pass config to gaudi explicitly when that is supported + return config + + +def run_allen_reconstruction(options, + make_reconstruction, + dump_binaries=False, + public_tools=[]): + """Configure the Allen reconstruction data flow + + Convenience function that configures all services and creates a data flow. + + Args: + options (ApplicationOptions): holder of application options + make_reconstruction: function returning a single CompositeNode object + public_tools (list): list of public `Tool` instances to configure + + """ + + setup_allen_non_event_data_service(dump_binaries=dump_binaries) + return run_reconstruction( + options, make_reconstruction, public_tools=public_tools) + + def run_reconstruction(options, make_reconstruction, public_tools=[]): """Configure the reconstruction data flow with a simple control flow. @@ -375,7 +544,6 @@ def _get_arg_default(function, name): Raises TypeError if ``function`` has no default keyword argument called ``name``. """ - import inspect spec = inspect.getargspec(function) try: i = spec.args.index(name) # ValueError if not found diff --git a/Hlt/RecoConf/options/dump_binary_input_for_standalone_Allen.py b/Hlt/RecoConf/options/dump_binary_input_for_standalone_Allen.py new file mode 100644 index 0000000000000000000000000000000000000000..16cc40fac89c89ff1e8ba7e0a939ba3993667bee --- /dev/null +++ b/Hlt/RecoConf/options/dump_binary_input_for_standalone_Allen.py @@ -0,0 +1,40 @@ +############################################################################### +# (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. # +############################################################################### +from Moore import options, run_allen_reconstruction +from Moore.config import Reconstruction +from RecoConf.hlt1_allen import make_dumped_raw_banks +from RecoConf.mc_checking import tracker_dumper, pv_dumper + +outputDir = "dump/" + + +def dump_allen_binary_input(): + """Dump input required for Allen standalone running into binary files + + The following input is dumped: + - Raw bank content of the Velo, UT, SciFi, Muon, ODIN banks + - MC info from the TrackerDumper required for the Allen standalone checker + - Non-event data such as geometry information + """ + + data = [] + data.append(make_dumped_raw_banks(output_dir=outputDir + "banks")) + data.append( + tracker_dumper( + dump_to_root=False, + dump_to_binary=True, + bin_output_dir=outputDir + "MC_info/tracks")) + data.append(pv_dumper(output_dir=outputDir + "MC_info/PVs")) + + return Reconstruction('allen_dump', data) + + +run_allen_reconstruction(options, dump_allen_binary_input, True) diff --git a/Hlt/RecoConf/options/hlt1_reco_allen_IPresolution.py b/Hlt/RecoConf/options/hlt1_reco_allen_IPresolution.py new file mode 100644 index 0000000000000000000000000000000000000000..3eccd94a1e603b3f3c004d3e6dbb663c3282bedd --- /dev/null +++ b/Hlt/RecoConf/options/hlt1_reco_allen_IPresolution.py @@ -0,0 +1,29 @@ +############################################################################### +# (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. # +############################################################################### +from Moore import options, run_allen_reconstruction +from Moore.config import Reconstruction +from RecoConf.hlt1_tracking import require_gec +from RecoConf.hlt1_allen import make_allen_tracks, make_allen_pvs +from RecoConf.mc_checking import monitor_IPresolution +from Configurables import NTupleSvc + + +def hlt1_reco_allen_IPresolution(): + allen_tracks = make_allen_tracks() + allen_pvs = make_allen_pvs() + pr_checker = monitor_IPresolution(allen_tracks["Forward"]["v1"], allen_pvs, + allen_tracks["Velo"]["v1"]) + + return Reconstruction('IPresolution', [pr_checker], [require_gec()]) + + +options.histo_file = "Hlt1ForwardTracking_IPresolution_Allen.root" +run_allen_reconstruction(options, hlt1_reco_allen_IPresolution) diff --git a/Hlt/RecoConf/options/hlt1_reco_allen_muonid_efficiency.py b/Hlt/RecoConf/options/hlt1_reco_allen_muonid_efficiency.py new file mode 100644 index 0000000000000000000000000000000000000000..58e191415c2b08d09761c3420cf71ce18eb1cb47 --- /dev/null +++ b/Hlt/RecoConf/options/hlt1_reco_allen_muonid_efficiency.py @@ -0,0 +1,61 @@ +############################################################################### +# (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. # +############################################################################### +from Moore import options, run_allen_reconstruction +from Moore.config import Reconstruction +from RecoConf.hlt1_tracking import require_gec +from RecoConf.mc_checking import monitor_tracking_efficiency, make_links_tracks_mcparticles, make_links_lhcbids_mcparticles_tracking_system +from RecoConf.mc_checking_categories import get_mc_categories, get_hit_type_mask +from RecoConf.hlt1_allen import (make_allen_forward_tracks, + make_allen_forward_muon_tracks) + + +def hlt1_reco_allen_muonid_efficiency(): + # get the fitted tracks with muon ID + forward_muon_tracks = make_allen_forward_muon_tracks() + + # make links to lhcb id for mc matching + links_to_lhcbids = make_links_lhcbids_mcparticles_tracking_system() + # make links between tracks and mcparticles for mc matching + links_to_tracks_muon_id = make_links_tracks_mcparticles( + InputTracks=forward_muon_tracks, LinksToLHCbIDs=links_to_lhcbids) + + # build the PrChecker algorihm for muon_id track + pr_checker_for_muon_id = monitor_tracking_efficiency( + TrackType="MuonMatch", + InputTracks=forward_muon_tracks, + #InputTracks={"v1": v1_tracks.OutputTracksName}, + LinksToTracks=links_to_tracks_muon_id, + LinksToLHCbIDs=links_to_lhcbids, + MCCategories=get_mc_categories("MuonMatch"), + HitTypesToCheck=get_hit_type_mask("BestLong"), + ) + + # build the PrChecker algorihm for forward track + forward_tracks = make_allen_forward_tracks() + links_to_forward_tracks = make_links_tracks_mcparticles( + InputTracks=forward_tracks, LinksToLHCbIDs=links_to_lhcbids) + + pr_checker_for_forward_track = monitor_tracking_efficiency( + TrackType="Forward", + InputTracks=forward_tracks, + LinksToTracks=links_to_forward_tracks, + LinksToLHCbIDs=links_to_lhcbids, + MCCategories=get_mc_categories("MuonMatch"), + HitTypesToCheck=get_hit_type_mask("BestLong"), + ) + + return Reconstruction( + 'muonideff', [pr_checker_for_forward_track, pr_checker_for_muon_id], + [require_gec()]) + + +options.histo_file = "PrChecker_MuonID.root" +run_allen_reconstruction(options, hlt1_reco_allen_muonid_efficiency) diff --git a/Hlt/RecoConf/options/hlt1_reco_allen_track_reconstruction.py b/Hlt/RecoConf/options/hlt1_reco_allen_track_reconstruction.py new file mode 100644 index 0000000000000000000000000000000000000000..c43b3b0070ba21521067040a01c879465b439d52 --- /dev/null +++ b/Hlt/RecoConf/options/hlt1_reco_allen_track_reconstruction.py @@ -0,0 +1,45 @@ +############################################################################### +# (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. # +############################################################################### +from Moore import options, run_allen_reconstruction +from Moore.config import Reconstruction +from RecoConf.hlt1_tracking import require_gec +from RecoConf.hlt1_allen import make_allen_tracks, make_dumped_raw_banks +from RecoConf.mc_checking import tracker_dumper, pv_dumper, get_track_checkers +from Configurables import RunAllen + +dumpBinaries = False +outputDir = "dump/" + + +def hlt1_reco_allen_tracks(): + + allen_tracks = make_allen_tracks() + + types_and_locations_for_checkers = { + "Velo": allen_tracks["Velo"], + "Upstream": allen_tracks["Upstream"], + "Forward": allen_tracks["Forward"], + } + data = get_track_checkers(types_and_locations_for_checkers) + + if dumpBinaries: + data.append(make_dumped_raw_banks(output_dir=outputDir + "banks")) + data.append( + tracker_dumper( + dump_to_root=False, + dump_to_binary=True, + bin_output_dir=outputDir + "MC_info/tracks")) + data.append(pv_dumper(output_dir=outputDir + "MC_info/PVs")) + + return Reconstruction('allen_reco', data, [require_gec()]) + + +run_allen_reconstruction(options, hlt1_reco_allen_tracks, dumpBinaries) diff --git a/Hlt/RecoConf/options/hlt1_reco_allen_trackresolution.py b/Hlt/RecoConf/options/hlt1_reco_allen_trackresolution.py new file mode 100644 index 0000000000000000000000000000000000000000..46b667812945adc4cbcfd0fd1a6de84d9f5622da --- /dev/null +++ b/Hlt/RecoConf/options/hlt1_reco_allen_trackresolution.py @@ -0,0 +1,31 @@ +############################################################################### +# (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. # +############################################################################### +from Moore import options, run_allen_reconstruction +from Moore.config import Reconstruction +from RecoConf.hlt1_tracking import require_gec +from RecoConf.hlt1_allen import make_allen_tracks +from RecoConf.mc_checking import monitor_track_resolution +from PyConf.application import make_data_with_FetchDataFromFile + + +def hlt1_reco_allen_trackresolution(): + track_type = "Forward" + tracks = make_allen_tracks()[track_type] + pr_checker = monitor_track_resolution(tracks) + + return Reconstruction( + 'track_resolution', + [make_data_with_FetchDataFromFile("/Event/MC/TrackInfo"), pr_checker], + [require_gec()]) + + +options.histo_file = "Hlt1ForwardTrackingResolutionAllen.root" +run_allen_reconstruction(options, hlt1_reco_allen_trackresolution) diff --git a/Hlt/RecoConf/options/hlt1_reco_baseline_with_mcchecking.py b/Hlt/RecoConf/options/hlt1_reco_baseline_with_mcchecking.py index f7995c44efc4b7e82d4c585e8b7d3fd70531c7de..2842fd1b9deead21f9186069f623d912412db235 100644 --- a/Hlt/RecoConf/options/hlt1_reco_baseline_with_mcchecking.py +++ b/Hlt/RecoConf/options/hlt1_reco_baseline_with_mcchecking.py @@ -15,3 +15,5 @@ options.histo_file = "MCMatching_baseline_MiniBias.root" with standalone_hlt1_reco.bind(do_mc_checking=True): run_reconstruction(options, standalone_hlt1_reco) + +options.histo_file = "MCMatching_baseline_MiniBias.root" diff --git a/Hlt/RecoConf/options/hlt1_reco_pvchecker.py b/Hlt/RecoConf/options/hlt1_reco_pvchecker.py new file mode 100644 index 0000000000000000000000000000000000000000..9117561889712f0cebf819d6a5005faebf1d4baf --- /dev/null +++ b/Hlt/RecoConf/options/hlt1_reco_pvchecker.py @@ -0,0 +1,36 @@ +############################################################################### +# (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. # +############################################################################### +from Moore import options, run_reconstruction +from Moore.config import Reconstruction +from RecoConf.hlt1_tracking import require_gec, make_hlt1_tracks, make_VeloKalman_fitted_tracks, make_pvs +from RecoConf.mc_checking import get_pv_checkers, get_track_checkers +from Configurables import ApplicationMgr +from Configurables import NTupleSvc + + +def hlt1_reco_pvchecker(): + + hlt1_tracks = make_hlt1_tracks() + pvs = make_pvs() + + data = [pvs] + data += get_pv_checkers(pvs, hlt1_tracks["Velo"], produce_ntuple=True) + + return Reconstruction('PVperformance', data, [require_gec()]) + + +run_reconstruction(options, hlt1_reco_pvchecker) + +NTupleSvc().Output += [ + "FILE1 DATAFILE='Hlt1_PVperformance.root' TYPE='ROOT' OPT='NEW'" +] +ApplicationMgr().ExtSvc += [NTupleSvc()] +ApplicationMgr().HistogramPersistency = "ROOT" diff --git a/Hlt/RecoConf/python/RecoConf/hlt1_allen.py b/Hlt/RecoConf/python/RecoConf/hlt1_allen.py new file mode 100644 index 0000000000000000000000000000000000000000..1ee345bdf4e30acbd40af9753b9327011f43c614 --- /dev/null +++ b/Hlt/RecoConf/python/RecoConf/hlt1_allen.py @@ -0,0 +1,124 @@ +############################################################################### +# (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. # +############################################################################### +from PyConf import configurable + +from PyConf.application import default_raw_event, make_odin + +from PyConf.Algorithms import (LHCb__Converters__Track__v1__fromV2TrackV1Track + as FromV2TrackV1Track, AllenVeloToV2Tracks, + AllenUTToV2Tracks, AllenForwardToV2Tracks, + AllenPVsToRecVertexV2, AllenDecReportsToTES, + DumpRawBanks, RunAllen, TransposeRawBanks) +from PyConf.Algorithms import HltDecReportsDecoder + + +def make_transposed_raw_banks(make_raw=default_raw_event): + return TransposeRawBanks(RawEventLocations=[make_raw()]).AllenRawInput + + +@configurable +def make_dumped_raw_banks(transposed_raw_banks=make_transposed_raw_banks, + odin_location=make_odin, + output_dir="dump/banks"): + return DumpRawBanks( + BanksLocation=transposed_raw_banks(), + ODINLocation=odin_location(), + OutputDirectory=output_dir) + + +def make_allen_output(odin_location=make_odin, + transposed_raw_banks=make_transposed_raw_banks, + filter_hlt1=False): + return RunAllen( + AllenRawInput=transposed_raw_banks(), + ODINLocation=odin_location(), + ParamDir="${ALLEN_PROJECT_ROOT}/input/detector_configuration/down/", + FilterHLT1=filter_hlt1).AllenOutput + + +def make_allen_dec_reports(odin_location=make_odin, + transposed_raw_banks=make_transposed_raw_banks, + filter_hlt1=False, + dump_to_file=False): + return RunAllen( + AllenRawInput=transposed_raw_banks(), + ODINLocation=odin_location(), + ParamDir="${ALLEN_PROJECT_ROOT}/input/detector_configuration/down/", + FilterHLT1=filter_hlt1).DecReportsLocation + + +def make_allen_velo_tracks(): + allen_output = make_allen_output() + velo_tracks_v2 = AllenVeloToV2Tracks(AllenOutput=allen_output).OutputTracks + velo_tracks_v1 = FromV2TrackV1Track( + InputTracksName=velo_tracks_v2).OutputTracksName + + return {"v2": velo_tracks_v2, "v1": velo_tracks_v1} + + +def make_allen_veloUT_tracks(): + allen_output = make_allen_output() + veloUT_tracks_v2 = AllenUTToV2Tracks(AllenOutput=allen_output).OutputTracks + veloUT_tracks_v1 = FromV2TrackV1Track( + InputTracksName=veloUT_tracks_v2).OutputTracksName + + return {"v2": veloUT_tracks_v2, "v1": veloUT_tracks_v1} + + +def make_allen_forward_tracks(): + allen_output = make_allen_output() + forward_tracks_v2 = AllenForwardToV2Tracks( + AllenOutput=allen_output).OutputTracks + forward_tracks_v1 = FromV2TrackV1Track( + InputTracksName=forward_tracks_v2).OutputTracksName + + return {"v2": forward_tracks_v2, "v1": forward_tracks_v1} + + +def make_allen_forward_muon_tracks(): + allen_output = make_allen_output() + forward_muon_tracks_v2 = AllenForwardToV2Tracks( + AllenOutput=allen_output).OutputMuonTracks + forward_muon_tracks_v1 = FromV2TrackV1Track( + InputTracksName=forward_muon_tracks_v2).OutputTracksName + + return {"v2": forward_muon_tracks_v2, "v1": forward_muon_tracks_v1} + + +def make_allen_tracks(): + velo_tracks = make_allen_velo_tracks() + velo_ut_tracks = make_allen_veloUT_tracks() + forward_tracks = make_allen_forward_tracks() + + return { + "Velo": velo_tracks, + "Upstream": velo_ut_tracks, + "Forward": forward_tracks, + } + + +def make_allen_pvs(): + allen_output = make_allen_output() + return AllenPVsToRecVertexV2(AllenOutput=allen_output).OutputPVs + + +def make_allen_raw_dec_reports(filterHLT1=False): + allen_output = make_allen_output(filter_hlt1=filterHLT1) + allen_dec_reports_raw = AllenDecReportsToTES( + AllenOutput=allen_output).OutputDecReports + return allen_dec_reports_raw + + +def decode_allen_dec_reports(): + allen_dec_reports_raw = make_allen_raw_dec_reports() + return HltDecReportsDecoder( + RawEventLocations=allen_dec_reports_raw, + SourceID=1).OutputHltDecReportsLocation diff --git a/Hlt/RecoConf/python/RecoConf/mc_checking.py b/Hlt/RecoConf/python/RecoConf/mc_checking.py index 4733ffc8b15e12437c34173987ec15e8608cb04b..fa9958936fce50d6a631a986d9bc17f43d7d8cc2 100644 --- a/Hlt/RecoConf/python/RecoConf/mc_checking.py +++ b/Hlt/RecoConf/python/RecoConf/mc_checking.py @@ -16,14 +16,18 @@ from PyConf.tonic import (configurable) from PyConf.dataflow import DataHandle from PyConf.components import Tool -from PyConf.application import default_raw_event, make_data_with_FetchDataFromFile +from PyConf.application import ( + default_raw_event, + make_data_with_FetchDataFromFile, + make_odin, +) from PyConf.Algorithms import ( VPFullCluster2MCParticleLinker, PrLHCbID2MCParticle, PrLHCbID2MCParticleVPUTFTMU, PrTrackAssociator, PrTrackChecker, PrUTHitChecker, TrackListRefiner, TrackResChecker, TrackIPResolutionCheckerNT, DataPacking__Unpack_LHCb__MCVPHitPacker_, - MCParticle2MCHitAlg, + MCParticle2MCHitAlg, PrTrackerDumper, PVDumper, LHCb__Converters__RecVertex__v2__fromVectorLHCbRecVertices as FromVectorLHCbRecVertex) @@ -31,9 +35,9 @@ from PyConf.Tools import (IdealStateCreator, LoKi__Hybrid__MCTool, VisPrimVertTool, LoKi__Hybrid__TrackSelector as LoKiTrackSelector) -from RecoConf.hlt1_tracking import (make_PrStoreUTHit_hits, - make_FTRawBankDecoder_clusters, - make_velo_full_clusters) +from RecoConf.hlt1_tracking import ( + make_PrStoreUTHit_hits, make_FTRawBankDecoder_clusters, + make_velo_full_clusters, make_VPClus_hits, make_PrStoreFTHit_hits) from Hlt2Conf.data_from_file import mc_unpackers @@ -366,3 +370,32 @@ def monitor_IPresolution(InputTracks, InputPVs, VeloTracks): PVContainer=vertexConverter, NTupleLUN="FILE1") return IPres_checker + + +def tracker_dumper(odin_location=make_odin, + root_output_dir="dump/TrackerDumper", + bin_output_dir="dump/MC_info/tracks", + dump_to_root=True, + dump_to_binary=False): + links_to_lhcbids = make_links_lhcbids_mcparticles_tracking_system() + + return PrTrackerDumper( + MCParticlesLocation=mc_unpackers()["MCParticles"], + VPLightClusterLocation=make_VPClus_hits(), + FTHitsLocation=make_PrStoreFTHit_hits(), + UTHitsLocation=make_PrStoreUTHit_hits(), + ODINLocation=odin_location(), + LinkerLocation=links_to_lhcbids, + DumpToROOT=dump_to_root, + DumpToBinary=dump_to_binary, + OutputDirectory=root_output_dir, + MCOutputDirectory=bin_output_dir) + + +def pv_dumper(odin_location=make_odin, output_dir="dump/MC_info/PVs"): + return PVDumper( + MCVerticesLocation=mc_unpackers()["MCVertices"], + MCPropertyLocation=make_data_with_FetchDataFromFile( + "/Event/MC/TrackInfo"), + ODINLocation=odin_location(), + OutputDirectory=output_dir) diff --git a/Hlt/RecoConf/python/RecoConf/mc_checking_categories.py b/Hlt/RecoConf/python/RecoConf/mc_checking_categories.py index 4aa653884f56e31082eb7ddd854093d7541d771f..2b21facfad3135804a34cd56f3217aec5b2130f0 100644 --- a/Hlt/RecoConf/python/RecoConf/mc_checking_categories.py +++ b/Hlt/RecoConf/python/RecoConf/mc_checking_categories.py @@ -14,19 +14,40 @@ from collections import OrderedDict categories = { "Velo": { - "01_velo": "isVelo", - "02_long": "isLong", - "03_long_P>5GeV": "isLong & over5", - "04_long_strange": "isLong & strange", - "05_long_strange_P>5GeV": "isLong & strange & over5", - "06_long_fromB": "isLong & fromB", - "07_long_fromB_P>5GeV": "isLong & fromB & over5", - "08_long_electrons": "isLong & isElectron", - "09_long_fromB_electrons": "isLong & isElectron & fromB", + "01_velo": + "isVelo", + "02_long": + "isLong", + "03_long_P>5GeV": + "isLong & over5", + "04_long_strange": + "isLong & strange", + "05_long_strange_P>5GeV": + "isLong & strange & over5", + "06_long_fromB": + "isLong & fromB", + "06_long_fromD": + "isLong & fromD", + "07_long_fromB_P>5GeV": + "isLong & fromB & over5", + "07_long_fromD_P>5GeV": + "isLong & fromD & over5", + "08_long_electrons": + "isLong & isElectron", + "09_long_fromB_electrons": + "isLong & isElectron & fromB", "10_long_fromB_electrons_P>5GeV": "isLong & isElectron & over5 & fromB", - "11_long_fromB_P>3GeV_Pt>0.5GeV": "isLong & fromB & trigger", - "12_UT_long_fromB_P>3GeV_Pt>0.5GeV": "isLong & fromB & trigger & isUT", + "11_long_fromB_P>3GeV_Pt>0.5GeV": + "isLong & fromB & trigger", + "11_long_fromB_electrons_P>3GeV_Pt>0.5GeV": + "isLong & fromB & trigger & isElectron", + "11_long_strange_P>3GeV_Pt>0.5GeV": + "isLong & strange& trigger", + "11_long_fromD_P>3GeV_Pt>0.5GeV": + "isLong & fromD & trigger", + "12_UT_long_fromB_P>3GeV_Pt>0.5GeV": + "isLong & fromB & trigger & isUT", }, "VeloFull": { "01_notElectron_Velo": @@ -111,36 +132,84 @@ categories = { "isElectron & isLong & strange & (MCETA>2.0) & (MCETA<5.0) & (MCP>3000) & (MCPT>400)" }, "Forward": { - "01_long": "isLong", - "02_long_P>5GeV": "isLong & over5", - "03_long_strange": "isLong & strange", - "04_long_strange_P>5GeV": "isLong & strange & over5", - "05_long_fromB": "isLong & fromB", - "06_long_fromB_P>5GeV": "isLong & fromB & over5", - "07_long_electrons": "isLong & isElectron", - "08_long_fromB_electrons": "isLong & isElectron & fromB", + "01_long": + "isLong", + "02_long_P>5GeV": + "isLong & over5", + "03_long_strange": + "isLong & strange", + "04_long_strange_P>5GeV": + "isLong & strange & over5", + "05_long_fromB": + "isLong & fromB", + "05_long_fromD": + "isLong & fromD", + "06_long_fromB_P>5GeV": + "isLong & fromB & over5", + "06_long_fromD_P>5GeV": + "isLong & fromD & over5", + "07_long_electrons": + "isLong & isElectron", + "08_long_fromB_electrons": + "isLong & isElectron & fromB", "09_long_fromB_electrons_P>5GeV": "isLong & isElectron & over5 & fromB", - "10_long_fromB_P>3GeV_Pt>0.5GeV": "isLong & fromB & trigger", - "11_UT_long_fromB_P>3GeV_Pt>0.5GeV": "isLong & fromB & trigger & isUT", + "10_long_fromB_P>3GeV_Pt>0.5GeV": + "isLong & fromB & trigger", + "10_long_fromB_electrons_P>3GeV_Pt>0.5GeV": + "isLong & fromB & trigger & isElectron", + "10_long_strange_P>3GeV_Pt>0.5GeV": + "isLong & strange & trigger", + "10_long_fromD_P>3GeV_Pt>0.5GeV": + "isLong & fromD & trigger", + "11_UT_long_fromB_P>3GeV_Pt>0.5GeV": + "isLong & fromB & trigger & isUT", }, "Upstream": { - "01_velo": "isVelo", - "02_velo+UT": "isVelo & isUT", - "03_velo+UT_P>5GeV": "isVelo & isUT & over5", - "04_velo+notLong": "isNotLong & isVelo ", - "05_velo+UT+notLong": "isNotLong & isVelo & isUT", - "06_velo+UT+notLong_P>5GeV": "isNotLong & isVelo & isUT & over5", - "07_long": "isLong", - "08_long_P>5GeV": "isLong & over5 ", - "09_long_fromB": "isLong & fromB", - "10_long_fromB_P>5GeV": "isLong & fromB & over5", - "11_long_electrons": "isLong & isElectron", - "12_long_fromB_electrons": "isLong & isElectron & fromB", + "01_velo": + "isVelo", + "02_velo+UT": + "isVelo & isUT", + "03_velo+UT_P>5GeV": + "isVelo & isUT & over5", + "04_velo+notLong": + "isNotLong & isVelo ", + "05_velo+UT+notLong": + "isNotLong & isVelo & isUT", + "06_velo+UT+notLong_P>5GeV": + "isNotLong & isVelo & isUT & over5", + "07_long": + "isLong", + "07_long_strange": + "isLong & strange", + "08_long_P>5GeV": + "isLong & over5 ", + "08_long_strange_P>5GeV": + "isLong & over5 & strange", + "09_long_fromB": + "isLong & fromB", + "09_long_fromD": + "isLong & fromD", + "10_long_fromB_P>5GeV": + "isLong & fromB & over5", + "10_long_fromD_P>5GeV": + "isLong & fromD & over5", + "11_long_electrons": + "isLong & isElectron", + "12_long_fromB_electrons": + "isLong & isElectron & fromB", "13_long_fromB_electrons_P>5GeV": "isLong & isElectron & over5 & fromB", - "14_long_fromB_P>3GeV_Pt>0.5GeV": "isLong & fromB & trigger", - "15_UT_long_fromB_P>3GeV_Pt>0.5GeV": "isLong & fromB & trigger & isUT", + "14_long_fromB_P>3GeV_Pt>0.5GeV": + "isLong & fromB & trigger", + "14_long_fromB_electrons_P>3GeV_Pt>0.5GeV": + "isLong & fromB & isElectron & trigger", + "14_long_strange_P>3GeV_Pt>0.5GeV": + "isLong & strange& trigger", + "14_long_fromD_P>3GeV_Pt>0.5GeV": + "isLong & fromD & trigger", + "15_UT_long_fromB_P>3GeV_Pt>0.5GeV": + "isLong & fromB & trigger & isUT", }, "UpstreamForMuons": { "01_long_muon": "isLong & isMuon", @@ -148,10 +217,20 @@ categories = { "03_long_pion": "isLong & isPion", }, "MuonMatch": { - "01_long": "isLong", - "02_long_muon": "isLong & isMuon", - "03_long_muon_from_strange": "isLong & strange & isMuon", - "04_long_pion": "isLong & isPion", + "01_long": + "isLong", + "02_long_muon": + "isLong & isMuon", + "02_long_muon_P>3GeV_Pt>0.5GeV": + "isLong & isMuon & (MCPT>500) & (MCP>3000)", + "03_long_muon_from_strange": + "isLong & strange & isMuon", + "03_long_muon_strange_P>3GeV_Pt>0.5GeV": + "isLong & isMuon & (MCPT>500) & (MCP>3000) & strange", + "04_long_pion": + "isLong & isPion", + "04_long_pion_P>3GeV_Pt>0.5GeV": + "isLong & isPion & (MCPT>500) & (MCP>3000)", }, "MuonID": { "01_long": "isLong", diff --git a/Hlt/RecoConf/scripts/PrCheckerEfficiency_HLT1.py b/Hlt/RecoConf/scripts/PrCheckerEfficiency_HLT1.py index 0bca93d296350a02da32c9a68a8cd4f961468730..02309ce573e130285b4469fa76e15a87d43f8740 100644 --- a/Hlt/RecoConf/scripts/PrCheckerEfficiency_HLT1.py +++ b/Hlt/RecoConf/scripts/PrCheckerEfficiency_HLT1.py @@ -35,7 +35,7 @@ gROOT.SetBatch(True) def getEfficiencyHistoNames(): - return ["eta", "p", "pt", "phi", "nPV"] + return ["eta", "p", "pt", "phi", "nPV"] #, "docaz"] def getTrackers(): @@ -52,6 +52,16 @@ def getOriginFolders(): return basedict +def getTrackNames(): + basedict = {"Velo": {}, "Upstream": {}, "Forward": {}} + + basedict["Velo"] = "Velo" + basedict["Upstream"] = "VeloUT" + basedict["Forward"] = "Forward" + + return basedict + + def get_colors(): return [kBlack, kAzure, kGreen + 3, kMagenta + 2, kOrange, kCyan + 2] @@ -65,7 +75,11 @@ def get_fillstyles(): def getGhostHistoNames(): - return ["eta", "nPV", "pt", "p"] + basedict = {"Velo": {}, "Upstream": {}, "Forward": {}} + basedict["Velo"] = ["eta", "nPV"] + basedict["Upstream"] = ["eta", "nPV", "pt", "p"] + basedict["Forward"] = ["eta", "nPV", "pt", "p"] + return basedict def argument_parser(): @@ -126,7 +140,7 @@ def get_eff(eff, hist, tf, histoName, label, var): teff.SetStatisticOption(7) eff[lab] = teff.CreateGraph() eff[lab].SetName(lab) - eff[lab].SetTitle(lab + "not elec.") + eff[lab].SetTitle(lab + "not electron") if (histoName.find('strange') != -1): eff[lab].SetTitle(lab + " from stranges") if (histoName.find('electron') != -1): @@ -134,11 +148,11 @@ def get_eff(eff, hist, tf, histoName, label, var): hist[lab] = denominator.Clone() hist[lab].SetName("h_numerator_notElectrons") - hist[lab].SetTitle(var + " histo. not elec.") + hist[lab].SetTitle(var + " distribution, not electron") if (histoName.find('strange') != -1): - hist[lab].SetTitle(var + " histo. stranges") + hist[lab].SetTitle(var + " distribution, stranges") if (histoName.find('electron') != -1): - hist[lab].SetTitle(var + " histo. electron") + hist[lab].SetTitle(var + " distribution, electron") return eff, hist @@ -172,6 +186,7 @@ def PrCheckerEfficiency(filename, outfile, label, plotstyle, dist, plotelec, cuts = getCuts() trackers = getTrackers() folders = getOriginFolders() + names = getTrackNames() for tracker in trackers: outputfile.cd() @@ -232,7 +247,9 @@ def PrCheckerEfficiency(filename, outfile, label, plotstyle, dist, plotelec, for lab in label: eff[lab].Draw("P SAME") cutName = categories[tracker][cut]["title"] - latex.DrawLatex(0.7, 0.85, "LHCb simultaion") + latex.DrawLatex(0.7, 0.85, "LHCb simulation") + track_name = names[tracker] + " tracks" + latex.DrawLatex(0.7, 0.75, track_name) latex.DrawLatex(0.35, 0.3, cutName) canvasName = tracker + "_" + cut + "_" + histo + ".pdf" if savepdf: @@ -272,6 +289,8 @@ def PrCheckerEfficiency(filename, outfile, label, plotstyle, dist, plotelec, scale = gPad.GetUymax() / rightmax hist_elec[lab].Scale(scale) hist_elec[lab].Draw("hist SAME") + set_style(hist_elec[label[0]], kGray + 1, + markers[i], styles[i]) else: rightmax = 1.05 * hist_elec[label[0]].GetMaximum() scale = gPad.GetUymax() / rightmax @@ -283,7 +302,9 @@ def PrCheckerEfficiency(filename, outfile, label, plotstyle, dist, plotelec, canvas_elec.PlaceLegend() for lab in label: eff_elec[lab].Draw("P SAME") - latex.DrawLatex(0.7, 0.85, "LHCb simultaion") + latex.DrawLatex(0.7, 0.85, "LHCb simulation") + track_name = names[tracker] + " tracks" + latex.DrawLatex(0.7, 0.75, track_name) latex.DrawLatex(0.35, 0.3, cutName) canvasName_elec = tracker + "_" + cut + "_" + histo + "_elec.pdf" if savepdf: @@ -331,46 +352,51 @@ def PrCheckerEfficiency(filename, outfile, label, plotstyle, dist, plotelec, for lab in label: eff[lab].Draw("P SAME") eff_elec[lab].Draw("P SAME") - latex.DrawLatex(0.7, 0.85, "LHCb simultaion") + latex.DrawLatex(0.7, 0.85, "LHCb simulation") + track_name = names[tracker] + " tracks" + latex.DrawLatex(0.7, 0.75, track_name) latex.DrawLatex(0.35, 0.3, cutName) canvas_com.SetRightMargin(0.05) canvas_com.Write() # calculate ghost rate - if tracker == "Forward": - histoBaseName = "Track/" + folder + tracker + "/" - for histo in ghostHistos: - trackerDir.cd() - title = "ghost rate vs " + histo - canvas = TCanvas(title, title) - gPad.SetTicks() - numeratorName = histoBaseName + ghostHistoDict[histo][ - "variable"] + "_Ghosts" - denominatorName = histoBaseName + ghostHistoDict[histo][ - "variable"] + "_Total" - print("ghost histo: " + histoBaseName + " " + numeratorName + - " " + denominatorName) - ghost = {} - mg = TMultiGraph() - for i, lab in enumerate(label): - numerator = tf[lab].Get(numeratorName) - denominator = tf[lab].Get(denominatorName) - - teff = TEfficiency(numerator, denominator) - teff.SetStatisticOption(7) - ghost[lab] = teff.CreateGraph() - ghost[lab].SetName(lab) - set_style(ghost[lab], colors[i], markers[i], styles[i]) - mg.Add(ghost[lab]) - - xtitle = ghostHistoDict[histo]["xTitle"] - mg.GetXaxis().SetTitle(xtitle) - mg.GetYaxis().SetTitle("ghost rate") - mg.Draw("ap") - canvas.PlaceLegend() - if savepdf: - canvas.SaveAs("ghost_rate_" + histo + ".pdf") - canvas.Write() + histoBaseName = "Track/" + folder + tracker + "/" + for histo in ghostHistos[tracker]: + trackerDir.cd() + title = "ghost rate vs " + histo + canvas = TCanvas(title, title) + gPad.SetTicks() + numeratorName = histoBaseName + ghostHistoDict[histo][ + "variable"] + "_Ghosts" + denominatorName = histoBaseName + ghostHistoDict[histo][ + "variable"] + "_Total" + print("ghost histo: " + histoBaseName + " " + numeratorName + " " + + denominatorName) + ghost = {} + mg = TMultiGraph() + for i, lab in enumerate(label): + numerator = tf[lab].Get(numeratorName) + denominator = tf[lab].Get(denominatorName) + print("Numerator = " + numeratorName) + print("Denominator = " + denominatorName) + teff = TEfficiency(numerator, denominator) + teff.SetStatisticOption(7) + ghost[lab] = teff.CreateGraph() + ghost[lab].SetName(lab) + set_style(ghost[lab], colors[i], markers[i], styles[i]) + mg.Add(ghost[lab]) + + xtitle = ghostHistoDict[histo]["xTitle"] + mg.GetXaxis().SetTitle(xtitle) + mg.GetYaxis().SetTitle("ghost rate") + mg.Draw("ap") + latex.DrawLatex(0.7, 0.85, "LHCb simulation") + track_name = names[tracker] + " tracks" + latex.DrawLatex(0.7, 0.75, track_name) + #canvas.PlaceLegend() + if savepdf: + canvas.SaveAs("ghost_rate_" + histo + ".pdf") + canvas.Write() outputfile.Write() outputfile.Close() diff --git a/Hlt/RecoConf/scripts/PrCheckerMuonIDEff.py b/Hlt/RecoConf/scripts/PrCheckerMuonIDEff.py index 08b19748de1685660e1faa9c091cee8701d9e0f8..f1251673498f9d7757dc6298d4e7353494180f90 100644 --- a/Hlt/RecoConf/scripts/PrCheckerMuonIDEff.py +++ b/Hlt/RecoConf/scripts/PrCheckerMuonIDEff.py @@ -112,14 +112,14 @@ def get_eff(eff, hist, tf, histoName, histoName_Den, label, var, printval): teff.SetStatisticOption(7) eff[lab] = teff.CreateGraph() eff[lab].SetName(lab) - eff[lab].SetTitle(lab + "not elec.") + eff[lab].SetTitle(lab) if (histoName.find('strange') != -1): eff[lab].SetTitle(lab + " from stranges") if (histoName.find('electron') != -1): eff[lab].SetTitle(lab + " electron") hist[lab] = denominator.Clone() hist[lab].SetName("h_numerator_notElectrons") - hist[lab].SetTitle(var + " histo. not elec.") + hist[lab].SetTitle(var + " distribution") if (histoName.find('strange') != -1): hist[lab].SetTitle(var + " histo. stranges") if (histoName.find('electron') != -1): diff --git a/Hlt/RecoConf/scripts/PrCheckerTrackResolution.py b/Hlt/RecoConf/scripts/PrCheckerTrackResolution.py index 5b5cacf7979ca69851e9811456be493162050b50..348fec5ba3e823ace7c1109a996f956b5e784596 100644 --- a/Hlt/RecoConf/scripts/PrCheckerTrackResolution.py +++ b/Hlt/RecoConf/scripts/PrCheckerTrackResolution.py @@ -80,6 +80,10 @@ def PrCheckerTrackResolution(filename, label, outfile, savepdf, plotstyle): from Legend import place_legend setLHCbStyle() + latex = TLatex() + latex.SetNDC() + latex.SetTextSize(0.05) + markers = get_markers() colors = get_colors() styles = get_fillstyles() @@ -98,7 +102,7 @@ def PrCheckerTrackResolution(filename, label, outfile, savepdf, plotstyle): hdp_p = tf[lab].Get("Track/TrackResChecker/ALL/vertex/dpoverp_vs_p") hdp_p.SetName("dpoverp_p_" + lab) hmom = hdp_p.ProjectionX() - hmom.SetTitle("p histo. " + lab) + hmom.SetTitle("p distribution " + lab) hdp_p.FitSlicesY(gaus, 0, -1, 0, "Q", arrp) hres_p[lab] = arrp[2] @@ -133,6 +137,7 @@ def PrCheckerTrackResolution(filename, label, outfile, savepdf, plotstyle): for lab in label: hres_p[lab].Draw("E1 p1 same") canvas1.SetRightMargin(0.05) + latex.DrawLatex(0.7, 0.85, "LHCb simulation") canvas1.Write() if savepdf: canvas1.SaveAs("trackres_p.pdf") @@ -150,7 +155,7 @@ def PrCheckerTrackResolution(filename, label, outfile, savepdf, plotstyle): hdp_eta.SetName("dpoverp_eta_" + lab) hdp_eta.FitSlicesY(gaus, 0, -1, 0, "Q", arreta) heta = hdp_eta.ProjectionX() - heta.SetTitle("#eta histo. " + lab) + heta.SetTitle("#eta distribution " + lab) hres_eta[lab] = arreta[2] hres_eta[lab].GetYaxis().SetTitle("dp/p [%]") @@ -187,6 +192,7 @@ def PrCheckerTrackResolution(filename, label, outfile, savepdf, plotstyle): for lab in label: hres_eta[lab].Draw("E1 p1 same") canvas2.SetRightMargin(0.05) + latex.DrawLatex(0.7, 0.85, "LHCb simulation") canvas2.Write() if savepdf: canvas2.SaveAs("trackres_eta.pdf") diff --git a/Hlt/RecoConf/scripts/utils/ConfigHistos.py b/Hlt/RecoConf/scripts/utils/ConfigHistos.py index e3f113544cad80b058cc01537ff6515c95131e27..b6b3bf44ca5dc658a7d129425aaec0c984475356 100644 --- a/Hlt/RecoConf/scripts/utils/ConfigHistos.py +++ b/Hlt/RecoConf/scripts/utils/ConfigHistos.py @@ -19,7 +19,8 @@ def efficiencyHistoDict(): "pt": {}, "phi": {}, "nPV": {}, - "docaz": {} + "docaz": {}, + "z": {} } basedict["eta"]["xTitle"] = "#eta" @@ -37,9 +38,12 @@ def efficiencyHistoDict(): basedict["nPV"]["xTitle"] = "# of PVs" basedict["nPV"]["variable"] = "nPV" - basedict["docaz"]["xTitle"] = "docaz (mm)" + basedict["docaz"]["xTitle"] = "docaz [mm]" basedict["docaz"]["variable"] = "docaz" + basedict["z"]["xTitle"] = "PV z coordinate [mm]" + basedict["z"]["variable"] = "z" + return basedict @@ -79,7 +83,7 @@ def getCuts(): "04_long_strange_P>5GeV", "05_long_fromB", "06_long_fromB_P>5GeV", "10_long_fromB_P>3GeV_Pt>0.5GeV", "11_UT_long_fromB_P>3GeV_Pt>0.5GeV" ] - basedict["MuonMatch"] = ["01_long", "02_long_muon"] + basedict["MuonMatch"] = ["01_long", "02_long_muon", "04_long_pion"] return basedict @@ -91,6 +95,8 @@ def categoriesDict(): "title"] = "Long, forward track, 2 <#eta< 5" basedict["MuonMatch"]["02_long_muon"][ "title"] = "Long, #mu, forward track, 2 <#eta< 5" + basedict["MuonMatch"]["04_long_pion"][ + "title"] = "Long, #pi, forward track, 2 <#eta< 5" basedict["Velo"]["01_velo"]["title"] = "Velo, 2 <#eta< 5" basedict["Velo"]["02_long"]["title"] = "Long, 2 <#eta< 5"