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
  • laolivei/Allen
  • pvfinder/inference-engine
  • rmatev/Allen
  • suali/Allen
  • mstahl/Allen
  • roneil/Allen
  • graemes/Allen
  • cburr/Allen
  • jonrob/Allen
  • bjashal/Allen-HIP
  • dcampora/MiniAllen
  • brij/Allen
  • raaij/cuda_hlt
  • bsm-fleet/cuda_hlt
  • abrearod/cuda_hlt
  • aalvesju/cuda_hlt
  • lhcb/Allen
17 results
Show changes
Commits on Source (531)
Showing
with 597 additions and 244 deletions
......@@ -9,7 +9,7 @@ variables:
ALLEN_DATA: "/scratch/allen_data"
LCG_VERSION: "LCG_103"
LCG_VERSION: "LCG_105a"
# LCG_PLATFORM = {LCG_SYSTEM}+{LCG_QUALIFIER}-{LCG_OPTIMIZATION}
LCG_SYSTEM: "x86_64_v3-el9-gcc12"
LCG_QUALIFIER: "cpu"
......@@ -63,10 +63,10 @@ check-copyright:
<<: *active_branches
stage: check
image: gitlab-registry.cern.ch/ci-tools/ci-worker:cc7
image: gitlab-registry.cern.ch/lhcb-docker/os-base/alma9-devel:latest
script:
- curl -o lb-check-copyright "https://gitlab.cern.ch/lhcb-core/LbDevTools/-/raw/master/LbDevTools/SourceTools.py?inline=False"
- python lb-check-copyright --license=Apache-2.0 origin/${TARGET_BRANCH}
- python3 lb-check-copyright --license=Apache-2.0 origin/${TARGET_BRANCH}
needs: []
check-formatting:
......@@ -74,7 +74,7 @@ check-formatting:
stage: check
tags:
- cvmfs
image: gitlab-registry.cern.ch/ci-tools/ci-worker:cc7
image: gitlab-registry.cern.ch/lhcb-docker/os-base/alma9-devel:latest
script:
- . /cvmfs/lhcb.cern.ch/lib/LbEnv.sh
- if [ ! -e .clang-format ] ; then
......@@ -97,7 +97,7 @@ pages:
refs:
- master
stage: publish
image: gitlab-registry.cern.ch/lhcb-core/lbdocker/centos7-build:latest
image: gitlab-registry.cern.ch/lhcb-docker/os-base/alma9-devel:latest
tags:
- cvmfs
variables:
......
......@@ -17,7 +17,7 @@ if(STANDALONE AND NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{CMAKE_TOOLCHA
set(CMAKE_TOOLCHAIN_FILE $ENV{CMAKE_TOOLCHAIN_FILE})
endif()
project(Allen VERSION 4.0
project(Allen VERSION 4.17
LANGUAGES C CXX)
# ---------------
......@@ -74,7 +74,7 @@ endif()
# CUDA compute capability
set(CUDA_ARCH COMPATIBILITY CACHE STRING "CUDA target architecture")
set_property(CACHE CUDA_ARCH PROPERTY STRINGS COMPATIBILITY MAX MIN 53 60 61 62 70 72 75 80 86)
set_property(CACHE CUDA_ARCH PROPERTY STRINGS COMPATIBILITY MAX MIN 60 61 62 70 72 75 80 86)
# HIP architecture
# https://llvm.org/docs/AMDGPUUsage.html
......@@ -193,12 +193,6 @@ if (NOT STANDALONE)
SET ALLEN_PROJECT_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
endif()
# Set the policy of CMP0104 (require CUDA_ARCHITECTURES) to OLD.
# Support it in a future Allen release.
if(${CMAKE_VERSION} VERSION_GREATER "3.18.0" OR ${CMAKE_VERSION} VERSION_EQUAL "3.18.0")
cmake_policy(SET CMP0104 OLD)
endif()
# Detect CUDA architecture
if(TARGET_DEVICE STREQUAL "CUDA")
if (NOT CMAKE_CUDA_COMPILER)
......@@ -238,7 +232,7 @@ if(TARGET_DEVICE STREQUAL "CUDA")
#CUDA_ARCH can be set to MIN
elseif(CUDA_ARCH STREQUAL "MIN")
message(STATUS "Setting lowest CUDA compute capability:")
list(APPEND CUDA_ARCH_LIST 53)
list(APPEND CUDA_ARCH_LIST 60)
#By default, compile for compatibility
elseif(CUDA_ARCH STREQUAL "COMPATIBILITY")
#Compatibility arch flag.
......@@ -248,7 +242,7 @@ if(TARGET_DEVICE STREQUAL "CUDA")
#* Forward compatibility with newer devices is also supported by generating PTX from 8.6
#(- gencode = arch = compute_86, compute = compute_86)
message(STATUS "Setting compute capability to COMPATIBILITY:")
foreach(arch 53 60 70 75 80 86)
foreach(arch 60 70 75 80 86)
list(APPEND CUDA_ARCH_LIST ${arch})
endforeach()
#Finally, compile for the specified architecture
......@@ -289,12 +283,10 @@ if(TARGET_DEVICE STREQUAL "CPU")
set_source_files_properties(${arg} PROPERTIES LANGUAGE CXX)
endif()
endforeach()
add_library(${ARGV})
add_library(Allen::${ARGV0} ALIAS ${ARGV0})
target_compile_definitions(${ARGV0} PRIVATE ${TARGET_DEFINITION} ODIN_WITHOUT_GAUDI)
if (${is_static} EQUAL -1)
install(TARGETS ${ARGV0}
EXPORT Allen
......@@ -371,7 +363,7 @@ elseif(TARGET_DEVICE STREQUAL "HIP")
function(allen_add_host_library)
list(FIND ARGV STATIC is_static)
message(STATUS "Adding host library: ${ARGV0}")
add_library(${ARGV})
target_include_directories(${ARGV0} PRIVATE ${HIP_PATH}/include ${ROCM_PATH}/hsa/include)
target_compile_definitions(${ARGV0} PRIVATE ${TARGET_DEFINITION} ODIN_WITHOUT_GAUDI)
......@@ -598,10 +590,10 @@ add_subdirectory(backend)
add_subdirectory(host)
add_subdirectory(device)
add_subdirectory(checker)
add_subdirectory(mdf)
add_subdirectory(integration)
add_subdirectory(zmq)
add_subdirectory(stream)
add_subdirectory(mdf)
if (STANDALONE)
target_compile_definitions(AllenCommon INTERFACE ALLEN_STANDALONE)
......@@ -627,7 +619,6 @@ foreach(header
FileSystem.h
TransposeTypes.h
InputReader.h
GaudiMonitoring.h
Configuration.h)
list(APPEND AllenHeaders main/include/${header})
endforeach()
......@@ -668,15 +659,17 @@ allen_add_host_library(HostCommon SHARED
main/src/SliceUtils.cpp
main/src/Timer.cpp
main/src/Tools.cpp
main/src/MDFProvider.cpp
main/src/Transpose.cpp)
target_link_libraries(AllenCommon INTERFACE
LHCbEvent AllenFS nlohmann_json::nlohmann_json cppgsl::cppgsl)
target_link_libraries(HostCommon PRIVATE
mdf EventModel Gear Backend mdf AllenCommon LHCbEvent Boost::iostreams)
mdf EventModel Gear Backend mdf AllenCommon LHCbEvent Boost::iostreams Rangev3::rangev3)
allen_add_host_library(AllenLib SHARED
main/src/Allen.cpp
main/src/AllenMonitoring.cpp
main/src/AllenThreads.cpp
main/src/OutputHandler.cpp
main/src/Provider.cpp
......@@ -684,6 +677,8 @@ allen_add_host_library(AllenLib SHARED
main/src/ZMQOutputSender.cpp)
target_compile_definitions(AllenLib PUBLIC ${TARGET_DEFINITION})
target_compile_definitions(AllenLib PUBLIC "CMAKE_ALLEN_BUILD_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\"")
target_include_directories(AllenLib PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
......@@ -706,7 +701,6 @@ target_link_libraries(AllenLib
HostEventModel
HostGEC
HostInitEventList
HostPrefixSum
HostRoutingBits
HostTAEFilter
Kalman
......@@ -730,6 +724,7 @@ target_link_libraries(AllenLib
VertexFitter
mdf
track_matching
Jets
PUBLIC
Gear
AllenCommon
......
......@@ -80,3 +80,17 @@ gaudi_add_module(BinaryDumpersModule
BinaryDumpers)
gaudi_add_tests(QMTest)
pybind11_add_module(bank_mapping NO_EXTRAS src/lib/bindings.cpp)
target_link_libraries(bank_mapping
PRIVATE
AllenCommon
HostCommon
PUBLIC
pybind11::pybind11
${Python_LIBRARIES})
install(TARGETS bank_mapping
EXPORT
Allen
LIBRARY DESTINATION
${GAUDI_INSTALL_PYTHONDIR}/Allen)
......@@ -94,12 +94,4 @@ namespace DumpUtils {
} // namespace DumpUtils
namespace MuonUtils {
size_t size_index(
std::array<unsigned int, 16> const& sizeXOffset,
std::array<int, 16> const& gridX,
std::array<int, 16> const& gridY,
LHCb::Detector::Muon::TileID const& tile);
}
#endif
......@@ -13,8 +13,11 @@ import os
import sys
import zmq
import re
import json
from pathlib import Path
from Configurables import ApplicationMgr
from Configurables import Gaudi__RootCnvSvc as RootCnvSvc
from Configurables import DDDBConf
from AllenCore.configuration_options import is_allen_standalone
is_allen_standalone.global_bind(standalone=True)
......@@ -52,7 +55,6 @@ interpreter.Declare("""
// non-event data manager to its shared interface
template<typename TO>
struct cast_service { TO* operator()(IService* svc) { return dynamic_cast<TO*>(svc); } };
template<typename T>
Allen::NonEventData::IUpdater* binary_updater(std::map<std::string, std::string> const& options);
uintptr_t czmq_context(zmq::context_t& ctx) { return reinterpret_cast<uintptr_t>(ctx.operator void*()); }
""")
......@@ -75,7 +77,8 @@ parser.add_argument("-n", dest="n_events", default=0)
parser.add_argument("-t", dest="threads", default=1)
parser.add_argument("--params", dest="params", default="")
parser.add_argument("-r", dest="repetitions", default=1)
parser.add_argument("-m", dest="reserve", default=1024)
parser.add_argument("-m", dest="reserve", default=1000)
parser.add_argument("--host-memory", dest="host_memory", default=200)
parser.add_argument("-v", dest="verbosity", default=3)
parser.add_argument("-p", dest="print_memory", default=0)
parser.add_argument("--sequence", dest="sequence", default=sequence_default)
......@@ -163,6 +166,20 @@ parser.add_argument(
dest="bindings",
action="store_false",
default=True)
parser.add_argument(
"--tck-from-odin",
help="Respect the TCK requested by ODIN",
dest="tck_from_odin",
action="store_true",
default=False)
parser.add_argument(
"--python-hlt1-node",
type=str,
help=
"Name of the variable that stores the configuration in the python module or file",
default="hlt1_node",
dest="hlt1_node",
)
args = parser.parse_args()
......@@ -184,8 +201,13 @@ options = ApplicationOptions(_enabled=False)
options.simulation = True if not UseDD4Hep else args.simulation
options.data_type = 'Upgrade'
options.input_type = 'MDF'
options.dddb_tag = dddb_tag
options.conddb_tag = conddb_tag
if UseDD4Hep:
options.geometry_version = dddb_tag
options.conditions_version = conddb_tag
else:
options.dddb_tag = dddb_tag
options.conddb_tag = conddb_tag
if args.register_monitoring_counters and args.mon_filename:
fn, ext = os.path.splitext(args.mon_filename)
options.histo_file = fn + "_gaudi" + ext
......@@ -215,10 +237,10 @@ rootSvc = RootCnvSvc("RootCnvSvc", EnableIncident=1)
ApplicationMgr().ExtSvc += ["Gaudi::IODataManager/IODataManager", rootSvc]
# Get Allen JSON configuration
sequence = os.path.expandvars(args.sequence)
sequence_json = ""
sequence = Path(os.path.expandvars(args.sequence))
sequence_json, sequence_source = ("", "")
tck_option = re.compile(r"([^:]+):(0x[a-fA-F0-9]{8})")
if (m := tck_option.match(sequence)):
if (m := tck_option.match(str(sequence))):
from Allen.tck import sequence_from_git, dependencies_from_build_manifest
import json
......@@ -241,9 +263,22 @@ if (m := tck_option.match(sequence)):
print(
f"Loaded TCK {tck} with sequence type {tck_info['type']} and label {tck_info['label']}."
)
else:
with open(sequence) as f:
sequence_source = f"{repo}:{tck}"
elif sequence.suffix in (".py", ""):
from Allen.tck import sequence_from_python
from AllenCore.configuration_options import is_allen_standalone
is_allen_standalone.global_bind(standalone=True)
sequence_json = json.dumps(
sequence_from_python(sequence, node_name=args.hlt1_node, verbose=True),
sort_keys=True)
sequence_source = str(sequence)
elif sequence.suffix in (".json", ):
print(sequence.resolve())
with sequence.open() as f:
sequence_json = f.read()
sequence_source = str(sequence)
else:
raise ValueError(f"Unknown type of sequence specified: {str(sequence)}")
if args.mep:
extSvc += ["AllenConfiguration", "MEPProvider"]
......@@ -278,8 +313,7 @@ if args.mep:
for mep in list_file))
]
else:
mep_provider.Connections = mep_dir.split(',')
# mep_provider.Connections = ["/daqarea1/fest/beam_test/Allen_BU_10.mep"]
mep_provider.Connections = meps
mep_provider.LoopOnMEPs = False
mep_provider.Preload = args.reuse_meps
......@@ -295,13 +329,16 @@ ApplicationMgr().ExtSvc += extSvc
# Copeid from PyConf.application.configure_input
default_raw_event.global_bind(raw_event_format=options.input_raw_format)
if not args.binary_geometry:
config.add(
setup_component(
'DDDBConf',
Simulation=options.simulation,
DataType=options.data_type,
ConditionsVersion=options.conddb_tag))
if not UseDD4Hep:
if UseDD4Hep:
config.add(
setup_component(
'DDDBConf',
Simulation=options.simulation,
DataType=options.data_type,
GeometryVersion=options.geometry_version,
ConditionsVersion=options.conditions_version))
else:
config.add(DDDBConf(Simulation=options.simulation, DataType="Upgrade"))
config.add(
setup_component(
'CondDB',
......@@ -339,11 +376,12 @@ for flag, value in [("g", args.det_folder), ("params", params),
("monitoring-save-period", args.mon_save_period),
("monitoring-filename", args.mon_filename),
("events-per-slice", args.events_per_slice),
("device", args.device),
("device", args.device), ("host-memory", args.host_memory),
("tck-from-odin", int(args.tck_from_odin)),
("enable-monitoring-printing",
args.enable_monitoring_printing),
int(args.enable_monitoring_printing)),
("register-monitoring-counters",
args.register_monitoring_counters)]:
int(args.register_monitoring_counters))]:
if value is not None:
options[flag] = str(value)
......@@ -390,8 +428,8 @@ def allen_thread():
if args.profile == "CUDA":
runtime_lib.cudaProfilerStart()
gbl.allen(options, sequence_json, updater, provider, output_handler,
zmqSvc, con.c_str())
gbl.allen(options, sequence_json, sequence_source, updater, provider,
output_handler, zmqSvc, con.c_str())
if args.profile == "CUDA":
runtime_lib.cudaProfilerStop()
......
......@@ -11,33 +11,25 @@
from AllenCore.gaudi_allen_generator import make_transposed_raw_banks
from Allen.config import allen_non_event_data_config, run_allen_reconstruction
from PyConf.application import ApplicationOptions
from PyConf.application import configure_input, configure
from PyConf.tonic import configurable
from PyConf.application import make_odin
from PyConf.control_flow import CompositeNode, NodeLogic
from DDDB.CheckDD4Hep import UseDD4Hep
options = ApplicationOptions(_enabled=False)
options.geometry_version = 'run3/before-rich1-geom-update-26052022'
options.evt_max = 1
@configurable
def dump_geometry(with_ut=None):
subdetectors = [
"VPRetinaCluster", "FTCluster", "Muon", "ODIN", "Calo", "EcalPacked"
]
if with_ut is None:
with_ut = not UseDD4Hep
if with_ut:
subdetectors += ["UT"]
allen_banks = make_transposed_raw_banks(subdetectors)
# run_allen_reconstruction will setup all device converters by
# default, so we only need a single algorithm here to have something
# to configure
def odin_node():
odin = make_odin()
return CompositeNode(
"dump_geometry", [allen_banks],
"dump_geometry", [odin],
combine_logic=NodeLogic.NONLAZY_OR,
force_order=True)
with (allen_non_event_data_config.bind(dump_geometry=True, out_dir="geometry"),
dump_geometry.bind(with_ut=False)):
run_allen_reconstruction(options, dump_geometry)
with allen_non_event_data_config.bind(dump_geometry=True, out_dir="geometry"):
run_allen_reconstruction(options, odin_node)
......@@ -51,17 +51,6 @@ StatusCode AllenUpdater::initialize()
}
}
for (auto type : m_bankTypes.value()) {
auto bt = ::bank_type(type);
if (bt == BankTypes::Unknown) {
error() << "Failed to obtain bank type for " << type << endmsg;
return StatusCode::FAILURE;
}
else {
m_types.insert(bt);
}
}
return StatusCode::SUCCESS;
}
......@@ -128,7 +117,7 @@ void AllenUpdater::registerProducer(string const& id, Allen::NonEventData::Produ
void AllenUpdater::update(gsl::span<unsigned const> odin_data)
{
{
std::unique_lock {m_odinMutex};
std::scoped_lock lock {m_odinMutex};
LHCb::ODIN odin {odin_data};
if (m_odin && m_odin->runNumber() == odin.runNumber()) {
return;
......
......@@ -86,13 +86,8 @@ public:
LHCb::ODIN odin() const { return m_odin ? *m_odin : LHCb::ODIN {}; }
std::unordered_set<BankTypes> const& bankTypes() const { return m_types; }
private:
Gaudi::Property<bool> m_triggerEventLoop {this, "TriggerEventLoop", false};
Gaudi::Property<std::vector<std::string>> m_bankTypes {this,
"BankTypes",
{"VP", "UT", "FTCluster", "ECal", "Muon", "Rich1", "Rich2"}};
std::map<
std::string,
std::tuple<Allen::NonEventData::Producer, std::vector<std::unique_ptr<Allen::NonEventData::Consumer>>>>
......@@ -104,6 +99,4 @@ private:
std::mutex m_odinMutex;
std::optional<LHCb::ODIN> m_odin = std::nullopt;
std::unordered_set<BankTypes> m_types;
};
......@@ -59,6 +59,9 @@ namespace Dumpers {
vector<float> dxdy;
vector<float> dzdy;
vector<float> globaldy;
vector<float> average_z;
vector<float> average_dxdy;
vector<std::array<float, 128 * 4>> matEndCalibrationVector; // fix me
// First uniqueMat is 512, save space by subtracting
const uint32_t uniqueMatOffset = 512; // FIXME -- hardcoded
......@@ -77,12 +80,18 @@ namespace Dumpers {
dxdy.resize(max_uniqueMat);
dzdy.resize(max_uniqueMat);
globaldy.resize(max_uniqueMat);
matEndCalibrationVector.resize(max_uniqueMat);
average_z.resize(number_of_layers);
average_dxdy.resize(number_of_layers);
std::array<unsigned, number_of_stations> stations = {1, 2, 3};
for (auto i_station : stations) {
FTChannelID::StationID station_id {i_station};
for (unsigned i_layer = 0; i_layer < number_of_layers_per_station; ++i_layer) {
unsigned n_measurements = 0;
unsigned index_layer = (i_station - 1) * number_of_layers_per_station + i_layer;
FTChannelID::LayerID layer_id {i_layer};
auto const& layer = det.findLayer(FTChannelID {station_id,
layer_id,
......@@ -122,9 +131,18 @@ namespace Dumpers {
dxdy[index] = mat->dxdy();
dzdy[index] = mat->dzdy();
globaldy[index] = mat->globaldy();
std::copy(
mat->getmatContractionParameterVector().begin(),
mat->getmatContractionParameterVector().end(),
matEndCalibrationVector[index].begin()); // copy the vector
average_z[index_layer] += (mirrorPoint.z() + mat->dzdy() * mirrorPoint.y());
average_dxdy[index_layer] += mat->dxdy();
n_measurements += 1;
}
}
}
average_z[index_layer] = average_z[index_layer] / n_measurements;
average_dxdy[index_layer] = average_dxdy[index_layer] / n_measurements;
}
}
......@@ -150,7 +168,7 @@ namespace Dumpers {
::FT::nMats,
number_of_mats,
number_of_banks,
0,
2, // v0 hardcoded, v2 read-in geometry (decoding v4,5,6)
bank_first_channel,
::FT::nMatsMax,
mirrorPointX,
......@@ -165,7 +183,10 @@ namespace Dumpers {
sipmPitch,
dxdy,
dzdy,
globaldy);
globaldy,
average_z,
average_dxdy,
matEndCalibrationVector);
}
else if (comp.count(7)) {
constexpr uint32_t nLinksPerBank = 24; // FIXME: change to centralised number
......@@ -188,7 +209,7 @@ namespace Dumpers {
::FT::nMats,
number_of_mats,
number_of_banks,
1,
3, // v1 hardcoded, v3 read-in geometry (decoding v7,8)
source_ids,
linkMap,
max_uniqueMat,
......@@ -204,7 +225,10 @@ namespace Dumpers {
sipmPitch,
dxdy,
dzdy,
globaldy);
globaldy,
average_z,
average_dxdy,
matEndCalibrationVector);
}
else {
std::stringstream s;
......
......@@ -68,8 +68,7 @@ namespace {
assert(nRegions == 4);
vector<float> padSizeX {}, stripXSizeX {}, stripYSizeX {}, padSizeY {}, stripXSizeY {}, stripYSizeY {};
array<unsigned int, 16> padOffset {}, stripXOffset {}, stripYOffset {}, padSizeOffset {}, stripXSizeOffset {},
stripYSizeOffset {};
array<unsigned int, 16> padOffset {}, stripXOffset {}, stripYOffset {};
array<int, 16> padGridY {}, stripXGridY {}, stripYGridX {}, stripYGridY {};
array<vector<array<float, 3>>, 4> padTable {}, stripXTable {}, stripYTable {};
......@@ -102,29 +101,23 @@ namespace {
stripYTable[s].resize(12 * accumulate(views::ints(0, 4), 0, nChannels(s, stripYGridX, stripYGridY)));
}
for (auto& [sizeX, sizeY, offset, gridY] :
{make_tuple(std::ref(padSizeX), std::ref(padSizeY), std::ref(padSizeOffset), std::ref(padGridY)),
make_tuple(std::ref(stripXSizeX), std::ref(stripXSizeY), std::ref(stripXSizeOffset), std::ref(stripXGridY)),
make_tuple(
std::ref(stripYSizeX), std::ref(stripYSizeY), std::ref(stripYSizeOffset), std::ref(stripYGridY))}) {
sizeX.resize(24 * accumulate(gridY, 0));
sizeY.resize(24 * accumulate(gridY, 0));
for (size_t i = 0; i < gridY.size() - 1; ++i) {
offset[i + 1] = offset[i] + 24 * gridY[i];
}
for (auto& [sizeX, sizeY, gridY] :
{make_tuple(std::ref(padSizeX), std::ref(padSizeY), std::ref(padGridY)),
make_tuple(std::ref(stripXSizeX), std::ref(stripXSizeY), std::ref(stripXGridY)),
make_tuple(std::ref(stripYSizeX), std::ref(stripYSizeY), std::ref(stripYGridY))}) {
sizeX.resize(16);
sizeY.resize(16);
}
string padType {"pad"}, stripXType {"stripX"}, stripYType {"stripY"};
// Pads
auto pad = std::tie(padType, padGridX, padGridY, padSizeX, padSizeY, padOffset, padSizeOffset, padTable);
auto pad = std::tie(padType, padGridX, padGridY, padSizeX, padSizeY, padOffset, padTable);
// X strips
auto stripX = std::tie(
stripXType, stripXGridX, stripXGridY, stripXSizeX, stripXSizeY, stripXOffset, stripXSizeOffset, stripXTable);
auto stripX = std::tie(stripXType, stripXGridX, stripXGridY, stripXSizeX, stripXSizeY, stripXOffset, stripXTable);
// Y strips
auto stripY = std::tie(
stripYType, stripYGridX, stripYGridY, stripYSizeX, stripYSizeY, stripYOffset, stripYSizeOffset, stripYTable);
auto stripY = std::tie(stripYType, stripYGridX, stripYGridY, stripYSizeX, stripYSizeY, stripYOffset, stripYTable);
for (auto& [t, gridX, gridY, sizeX, sizeY, offset, sizeOffset, table] : {pad, stripX, stripY}) {
for (auto& [t, gridX, gridY, sizeX, sizeY, offset, table] : {pad, stripX, stripY}) {
for (auto station : views::ints(0, nStations)) {
size_t index = 0;
for (auto region : views::ints(0, nRegions)) {
......@@ -152,15 +145,17 @@ namespace {
throw GaudiException {e.str(), __FILE__, StatusCode::FAILURE};
}
else {
auto sizeIdx = MuonUtils::size_index(sizeOffset, gridX, gridY, tile);
auto sizeIdx = 4 * tile.station() + tile.region();
// positions are always indexed by station
table[station][index++] = {
numeric_cast<float>(pos->x()), numeric_cast<float>(pos->y()), numeric_cast<float>(pos->z())};
// sizes are specially indexed
if (pos->dX() > sizeX[sizeIdx]) sizeX[sizeIdx] = pos->dX();
if (pos->dY() > sizeY[sizeIdx]) sizeY[sizeIdx] = pos->dY();
if (y < gridY[gidx]) {
if ((t == "pad") || (float) pos->dX() > sizeX[sizeIdx]) sizeX[sizeIdx] = pos->dX();
if ((t == "pad") || (float) pos->dY() > sizeY[sizeIdx]) sizeY[sizeIdx] = pos->dY();
}
}
}
}
......
......@@ -20,7 +20,7 @@
#include <Event/ODIN.h>
#include <Event/RawBank.h>
#include <GaudiAlg/Consumer.h>
#include <GaudiKernel/ParsersFactory.h>
#include <Gaudi/Parsers/Factory.h>
#include <Dumpers/Utils.h>
......
......@@ -10,7 +10,7 @@
\*****************************************************************************/
// Gaudi Array properties ( must be first ...)
#include "GaudiKernel/ParsersFactory.h"
#include "Gaudi/Parsers/Factory.h"
#include "GaudiKernel/StdArrayAsProperty.h"
// Rich Kernel
......
......@@ -10,7 +10,7 @@
\*****************************************************************************/
// Gaudi Array properties ( must be first ...)
#include "GaudiKernel/ParsersFactory.h"
#include "Gaudi/Parsers/Factory.h"
#include "GaudiKernel/StdArrayAsProperty.h"
// Rich Kernel
......
......@@ -12,6 +12,9 @@
#include <iostream>
#include <tuple>
#include <vector>
#include <algorithm>
#include <cmath>
#include <limits>
#include <range/v3/view/repeat_n.hpp>
#include "range/v3/range/conversion.hpp"
......@@ -26,12 +29,27 @@
#include <Dumpers/Utils.h>
#include "Dumper.h"
#include "UTUniqueID.cuh"
namespace {
using std::vector;
using namespace ranges;
/// get allen ut sector index
inline int get_allen_ut_sector_index(const DeUTSector& ut_sector)
{
const auto ch = ut_sector.elementID();
const auto side = ch.side();
const auto layer = ch.layer();
const auto stave = ch.stave();
const auto face = ch.face();
const auto module = ch.module();
const auto sector = ch.sector();
return sector_unique_id(side, layer, stave, face, module, sector);
}
#ifdef USE_DD4HEP
const static std::string readoutLocation = "/world/BeforeMagnetRegion/UT:ReadoutMap";
#else
......@@ -48,7 +66,14 @@ namespace {
{
DumpUtils::Writer output {};
// To ensure backward compatibility, we use first 16 bits to store UT geometry version
// and the last 16 bits to store the number of sectors:
// For old UT geometry which uses 32 bits to store number of sectors, the first 16 bits
// are always empty, so the version is always zero
uint32_t number_of_sectors = det.nSectors();
uint32_t version = 1u; // 0 -> hardcoded dxdy, 1 -> per-serctor dxdy
uint32_t metadata = number_of_sectors | (version << 16);
// first strip is always 1
vector<uint32_t> firstStrip = views::repeat_n(1, number_of_sectors) | to<std::vector<uint32_t>>();
vector<float> pitch;
......@@ -60,34 +85,50 @@ namespace {
vector<float> p0X;
vector<float> p0Y;
vector<float> p0Z;
pitch.reserve(number_of_sectors);
cos.reserve(number_of_sectors);
dy.reserve(number_of_sectors);
dp0diX.reserve(number_of_sectors);
dp0diY.reserve(number_of_sectors);
dp0diZ.reserve(number_of_sectors);
p0X.reserve(number_of_sectors);
p0Y.reserve(number_of_sectors);
p0Z.reserve(number_of_sectors);
det.applyToAllSectorsAllen([&](DeUTSector const& sector) {
pitch.push_back(sector.pitch());
cos.push_back(sector.cosAngle());
dy.push_back(sector.get_dy());
vector<float> dxDy;
pitch.resize(number_of_sectors, std::numeric_limits<float>::quiet_NaN());
cos.resize(number_of_sectors, std::numeric_limits<float>::quiet_NaN());
dy.resize(number_of_sectors, std::numeric_limits<float>::quiet_NaN());
dp0diX.resize(number_of_sectors, std::numeric_limits<float>::quiet_NaN());
dp0diY.resize(number_of_sectors, std::numeric_limits<float>::quiet_NaN());
dp0diZ.resize(number_of_sectors, std::numeric_limits<float>::quiet_NaN());
p0X.resize(number_of_sectors, std::numeric_limits<float>::quiet_NaN());
p0Y.resize(number_of_sectors, std::numeric_limits<float>::quiet_NaN());
p0Z.resize(number_of_sectors, std::numeric_limits<float>::quiet_NaN());
dxDy.resize(number_of_sectors, std::numeric_limits<float>::quiet_NaN());
det.applyToAllSectors([&](DeUTSector const& sector) {
const auto idx = get_allen_ut_sector_index(sector);
pitch[idx] = sector.pitch();
cos[idx] = (sector.cosAngle());
dy[idx] = (sector.get_dy());
const auto dp0di = sector.get_dp0di();
dp0diX.push_back(dp0di.x());
dp0diY.push_back(dp0di.y());
dp0diZ.push_back(dp0di.z());
dp0diX[idx] = (dp0di.x());
dp0diY[idx] = (dp0di.y());
dp0diZ[idx] = (dp0di.z());
const auto p0 = sector.get_p0();
p0X.push_back(p0.x());
p0Y.push_back(p0.y());
p0X[idx] = (p0.x());
p0Y[idx] = (p0.y());
// hack: since p0z is always positive, we can use the signbit to encode whether or not to "stripflip"
p0Z.push_back(((sector.xInverted() && sector.getStripflip()) ? -1 : 1) * p0.z());
// this hack will be used in UTPreDecode.cu and UTDecodeRawBanksInOrder.cu
p0Z[idx] = (((sector.xInverted() && sector.getStripflip()) ? -1 : 1) * p0.z());
// this hack will be used in UTClusterAndPreDecode.cu
dxDy[idx] = sector.get_dxdy();
});
output.write(number_of_sectors, firstStrip, pitch, dy, dp0diX, dp0diY, dp0diZ, p0X, p0Y, p0Z, cos);
// cross check
assert(std::all_of(pitch.begin(), pitch.end(), [](auto i) { return !std::isnan(i); }));
assert(std::all_of(cos.begin(), cos.end(), [](auto i) { return !std::isnan(i); }));
assert(std::all_of(dy.begin(), dy.end(), [](auto i) { return !std::isnan(i); }));
assert(std::all_of(dp0diX.begin(), dp0diX.end(), [](auto i) { return !std::isnan(i); }));
assert(std::all_of(dp0diY.begin(), dp0diY.end(), [](auto i) { return !std::isnan(i); }));
assert(std::all_of(dp0diZ.begin(), dp0diZ.end(), [](auto i) { return !std::isnan(i); }));
assert(std::all_of(p0X.begin(), p0X.end(), [](auto i) { return !std::isnan(i); }));
assert(std::all_of(p0Y.begin(), p0Y.end(), [](auto i) { return !std::isnan(i); }));
assert(std::all_of(p0Z.begin(), p0Z.end(), [](auto i) { return !std::isnan(i); }));
assert(std::all_of(dxDy.begin(), dxDy.end(), [](auto i) { return !std::isnan(i); }));
output.write(metadata, firstStrip, pitch, dy, dp0diX, dp0diY, dp0diZ, p0X, p0Y, p0Z, cos, dxDy);
data = output.buffer();
}
......@@ -228,6 +269,7 @@ namespace {
data = output.buffer();
}
};
} // namespace
class DumpUTGeometry final
......
......@@ -94,7 +94,7 @@ DumpVPGeometry::DumpVPGeometry(const std::string& name, ISvcLocator* svcLoc) :
StatusCode DumpVPGeometry::initialize()
{
return Dumper::initialize().andThen([&] {
register_producer(Allen::NonEventData::VeloGeometry::id, "VP_geometry", m_data);
register_producer(Allen::NonEventData::VeloGeometry::id, "velo_geometry", m_data);
addConditionDerivation({DeVPLocation::Default}, inputLocation<Dumpers::VP>(), [&](DeVP const& det) {
auto geo = Dumpers::VP {m_data, det};
dump();
......
......@@ -18,6 +18,7 @@
#include "InputReader.h"
#include "RegisterConsumers.h"
#include "Constants.cuh"
#include "NeuralNetworkDefinition.cuh"
#include "BankTypes.h"
#include "Logger.h"
......@@ -101,7 +102,9 @@ StatusCode ProvideConstants::initialize()
muon_catboost_model_reader.leaf_offsets(),
muon_catboost_model_reader.split_border(),
muon_catboost_model_reader.split_feature());
TwoTrackMVAModelReader two_track_mva_model_reader {geometry_path + "/allen_two_track_mva_model_June22.json"};
LipschitzNNModelReader two_track_mva_model_reader {geometry_path + "/allen_two_track_mva_model_June22.json"};
m_constants.initialize_two_track_mva_model_constants(
two_track_mva_model_reader.weights(),
two_track_mva_model_reader.biases(),
......@@ -110,9 +113,177 @@ StatusCode ProvideConstants::initialize()
two_track_mva_model_reader.monotone_constraints(),
two_track_mva_model_reader.nominal_cut(),
two_track_mva_model_reader.lambda());
LipschitzNNModelReader electronid_mva_model_reader {geometry_path + "/CaloPID/electron_mva_AllenJune2024.json"};
m_constants.initialize_electronid_mva_model_constants(
electronid_mva_model_reader.weights(),
electronid_mva_model_reader.biases(),
electronid_mva_model_reader.layer_sizes(),
electronid_mva_model_reader.n_layers(),
electronid_mva_model_reader.monotone_constraints(),
electronid_mva_model_reader.min_rescales(),
electronid_mva_model_reader.max_rescales(),
electronid_mva_model_reader.nominal_cut(),
electronid_mva_model_reader.lambda());
LipschitzNNModelReader muonid_mva_model_reader {geometry_path + "/muonid_mva_AllenJune2024.json"};
m_constants.initialize_muonid_mva_model_constants(
muonid_mva_model_reader.weights(),
muonid_mva_model_reader.biases(),
muonid_mva_model_reader.layer_sizes(),
muonid_mva_model_reader.n_layers(),
muonid_mva_model_reader.monotone_constraints(),
muonid_mva_model_reader.min_rescales(),
muonid_mva_model_reader.max_rescales(),
muonid_mva_model_reader.nominal_cut(),
muonid_mva_model_reader.lambda());
// Ghost killers
SingleLayerFCNNReader forward_ghostkiller_reader {geometry_path +
"/GhostProbability/Hlt1_LongGhostKiller_Forward.json"};
m_constants.initialize_forward_ghostkiller_constants(
forward_ghostkiller_reader.mean(),
forward_ghostkiller_reader.std(),
forward_ghostkiller_reader.weights1(),
forward_ghostkiller_reader.bias1(),
forward_ghostkiller_reader.weights2(),
forward_ghostkiller_reader.bias2());
SingleLayerFCNNReader forward_no_ut_ghostkiller_reader {geometry_path +
"/GhostProbability/Hlt1_LongGhostKiller_noUT_Forward.json"};
m_constants.initialize_forward_no_ut_ghostkiller_constants(
forward_no_ut_ghostkiller_reader.mean(),
forward_no_ut_ghostkiller_reader.std(),
forward_no_ut_ghostkiller_reader.weights1(),
forward_no_ut_ghostkiller_reader.bias1(),
forward_no_ut_ghostkiller_reader.weights2(),
forward_no_ut_ghostkiller_reader.bias2());
SingleLayerFCNNReader matching_ghostkiller_reader {geometry_path +
"/GhostProbability/Hlt1_LongGhostKiller_Matching.json"};
m_constants.initialize_matching_ghostkiller_constants(
matching_ghostkiller_reader.mean(),
matching_ghostkiller_reader.std(),
matching_ghostkiller_reader.weights1(),
matching_ghostkiller_reader.bias1(),
matching_ghostkiller_reader.weights2(),
matching_ghostkiller_reader.bias2());
SingleLayerFCNNReader downstream_ghostkiller_reader {geometry_path +
"/GhostProbability/Hlt1_DownstreamGhostKiller.json"};
m_constants.initialize_downstream_ghostkiller_constants(
downstream_ghostkiller_reader.mean(),
downstream_ghostkiller_reader.std(),
downstream_ghostkiller_reader.weights1(),
downstream_ghostkiller_reader.bias1(),
downstream_ghostkiller_reader.weights2(),
downstream_ghostkiller_reader.bias2());
SingleLayerFCNNReader matching_with_ut_ghostkiller_reader {
geometry_path + "/GhostProbability/Hlt1_LongGhostKiller_MatchingWithUT.json"};
m_constants.initialize_matching_with_ut_ghostkiller_constants(
matching_with_ut_ghostkiller_reader.mean(),
matching_with_ut_ghostkiller_reader.std(),
matching_with_ut_ghostkiller_reader.weights1(),
matching_with_ut_ghostkiller_reader.bias1(),
matching_with_ut_ghostkiller_reader.weights2(),
matching_with_ut_ghostkiller_reader.bias2());
SingleLayerFCNNReader matching_no_ut_v2_ghostkiller_reader {
geometry_path + "/GhostProbability/Hlt1_LongGhostKiller_MatchingNoUT_V2.json"};
m_constants.initialize_matching_no_ut_v2_ghostkiller_constants(
matching_no_ut_v2_ghostkiller_reader.mean(),
matching_no_ut_v2_ghostkiller_reader.std(),
matching_no_ut_v2_ghostkiller_reader.weights1(),
matching_no_ut_v2_ghostkiller_reader.bias1(),
matching_no_ut_v2_ghostkiller_reader.weights2(),
matching_no_ut_v2_ghostkiller_reader.bias2());
SingleLayerFCNNReader matching_with_ut_v2_ghostkiller_reader {
geometry_path + "/GhostProbability/Hlt1_LongGhostKiller_MatchingWithUT_V2.json"};
m_constants.initialize_matching_with_ut_v2_ghostkiller_constants(
matching_with_ut_v2_ghostkiller_reader.mean(),
matching_with_ut_v2_ghostkiller_reader.std(),
matching_with_ut_v2_ghostkiller_reader.weights1(),
matching_with_ut_v2_ghostkiller_reader.bias1(),
matching_with_ut_v2_ghostkiller_reader.weights2(),
matching_with_ut_v2_ghostkiller_reader.bias2());
// std::unique_ptr<SingleLayerFCNNReader> forward_no_ut_ghostkiller_reader, matching_no_ut_ghostkiller_reader,
// forward_ghostkiller_reader, matching_ghostkiller_reader;
SingleLayerFCNNReader ttrack_selector_reader {geometry_path + "/HLT1Downstream/Hlt1_Downstream_TTrackSelector.json"};
m_constants.initialize_ttrack_selector_constants(
ttrack_selector_reader.mean(),
ttrack_selector_reader.std(),
ttrack_selector_reader.weights1(),
ttrack_selector_reader.bias1(),
ttrack_selector_reader.weights2(),
ttrack_selector_reader.bias2());
SingleLayerFCNNReader downstream_composite_quality_reader {geometry_path +
"/HLT1Downstream/Hlt1_Downstream_Composite_Quality.json"};
m_constants.initialize_downstream_composite_quality_evaluator_constants(
downstream_composite_quality_reader.mean(),
downstream_composite_quality_reader.std(),
downstream_composite_quality_reader.weights1(),
downstream_composite_quality_reader.bias1(),
downstream_composite_quality_reader.weights2(),
downstream_composite_quality_reader.bias2());
SingleLayerFCNNReader downstream_lambda_selector_reader {geometry_path +
"/HLT1Downstream/Hlt1_Downstream_LambdaSelector.json"};
m_constants.initialize_downstream_lambda_selector_constants(
downstream_lambda_selector_reader.mean(),
downstream_lambda_selector_reader.std(),
downstream_lambda_selector_reader.weights1(),
downstream_lambda_selector_reader.bias1(),
downstream_lambda_selector_reader.weights2(),
downstream_lambda_selector_reader.bias2());
SingleLayerFCNNReader downstream_kshort_selector_reader {geometry_path +
"/HLT1Downstream/Hlt1_Downstream_KshortSelector.json"};
m_constants.initialize_downstream_kshort_selector_constants(
downstream_kshort_selector_reader.mean(),
downstream_kshort_selector_reader.std(),
downstream_kshort_selector_reader.weights1(),
downstream_kshort_selector_reader.bias1(),
downstream_kshort_selector_reader.weights2(),
downstream_kshort_selector_reader.bias2());
SingleLayerFCNNReader downstream_detached_lambda_selector_reader {
geometry_path + "/HLT1Downstream/Hlt1_Downstream_DetachedLambdaSelector.json"};
m_constants.initialize_downstream_detached_lambda_selector_constants(
downstream_detached_lambda_selector_reader.mean(),
downstream_detached_lambda_selector_reader.std(),
downstream_detached_lambda_selector_reader.weights1(),
downstream_detached_lambda_selector_reader.bias1(),
downstream_detached_lambda_selector_reader.weights2(),
downstream_detached_lambda_selector_reader.bias2());
SingleLayerFCNNReader downstream_detached_kshort_selector_reader {
geometry_path + "/HLT1Downstream/Hlt1_Downstream_DetachedKshortSelector.json"};
m_constants.initialize_downstream_detached_kshort_selector_constants(
downstream_detached_kshort_selector_reader.mean(),
downstream_detached_kshort_selector_reader.std(),
downstream_detached_kshort_selector_reader.weights1(),
downstream_detached_kshort_selector_reader.bias1(),
downstream_detached_kshort_selector_reader.weights2(),
downstream_detached_kshort_selector_reader.bias2());
SingleLayerFCNNReader downstream_busca_selector_reader {geometry_path +
"/HLT1Downstream/Hlt1_Downstream_BuScaSelector.json"};
m_constants.initialize_downstream_busca_selector_constants(
downstream_busca_selector_reader.mean(),
downstream_busca_selector_reader.std(),
downstream_busca_selector_reader.weights1(),
downstream_busca_selector_reader.bias1(),
downstream_busca_selector_reader.weights2(),
downstream_busca_selector_reader.bias2());
// Allen Consumers
register_consumers(m_updater.get(), m_constants, m_updater->bankTypes());
std::unordered_set<BankTypes> subdetectors;
for (unsigned bt = 0; bt < NBankTypes; ++bt) {
subdetectors.insert(static_cast<BankTypes>(bt));
}
register_consumers(m_updater.get(), m_constants, subdetectors);
return StatusCode::SUCCESS;
}
......
......@@ -108,7 +108,7 @@ void lookup(
y = p[1];
z = p[2];
auto dxi = MuonUtils::size_index(table.sizeOffset, table.gridX, table.gridY, tile);
auto dxi = 4 * tile.station() + tile.region();
deltax = table.sizeX[dxi];
deltay = table.sizeY[dxi];
}
......@@ -182,11 +182,6 @@ void read_muon_table(gsl::span<const char> raw_input, MuonTable& pad, MuonTable&
++n;
});
for (size_t i = 0; i < muonTable.gridY.size() - 1; ++i) {
muonTable.sizeOffset[i + 1] = muonTable.sizeOffset[i] + 24 * muonTable.gridY[i];
}
assert((muonTable.sizeOffset.back() + 24 * muonTable.gridY.back()) == muonTable.sizeX.size());
auto tableSize = pop<size_t>(raw_input);
assert(tableSize == 4);
......@@ -230,11 +225,8 @@ void TestMuonTable::operator()(DeMuonDetector const& det, MuonHitContainer const
auto pos = det.position(hit.tile());
hit_position(hit.tile(), m_pad, m_stripX, m_stripY, hit.uncrossed(), xt, dxt, yt, dyt, zt);
array<tuple<char const*, double, double>, 5> values {{{"x ", pos->x(), xt},
{"dx", pos->dX(), dxt},
{"y ", pos->y(), yt},
{"dy", pos->dY(), dyt},
{"z ", pos->z(), zt}}};
array<tuple<char const*, double, double>, 5> values {
{{"x ", pos->x(), xt}, {"y ", pos->y(), yt}, {"z ", pos->z(), zt}}};
boost::format msg {"%|4d| %|8d| %|6s| %|d| %|d| %|d| %|2d| %|2d| %|d| %|5d| %|5d|"};
......@@ -244,7 +236,7 @@ void TestMuonTable::operator()(DeMuonDetector const& det, MuonHitContainer const
auto [table, tt] = lookup_table(tile, hit.uncrossed(), m_pad, m_stripX, m_stripY);
const auto index = lookup_index(table.get(), tile);
auto dx_index = MuonUtils::size_index(table.get().sizeOffset, table.get().gridX, table.get().gridY, tile);
auto dx_index = 4 * tile.station() + tile.region();
// positions are always indexed by station
error() << (msg % n % static_cast<unsigned int>(tile) % tt % tile.station() % tile.region() % tile.quarter() %
......
......@@ -13,12 +13,13 @@
#include <string>
#include <unordered_map>
#include <vector>
#include <array>
#include <AIDA/IHistogram1D.h>
#include "Gaudi/Accumulators/Histogram.h"
#include <GaudiAlg/MergingTransformer.h>
#include <GaudiAlg/GaudiHistoAlg.h>
#include <GaudiKernel/GaudiException.h>
#include <Gaudi/Parsers/Factory.h>
#include <Event/ODIN.h>
#include <Event/RawBank.h>
......@@ -27,6 +28,7 @@
#include <Dumpers/Utils.h>
#include <BankTypes.h>
#include <BankMapping.h>
template<typename T>
using VOC = Gaudi::Functional::vector_of_const_<T>;
......@@ -38,9 +40,9 @@ using VOC = Gaudi::Functional::vector_of_const_<T>;
// Once
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// number_of_rawbanks | uint32_t | 4
// -----------------------------------------------------------------------------
// raw_bank_offset | uint32_t | number_of_rawbanks * 4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// -----------------------------------------------------------------------------
// for each raw bank:
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// sourceID | uint32_t | 4 |
......@@ -48,39 +50,86 @@ using VOC = Gaudi::Functional::vector_of_const_<T>;
// bank_data | char | variable
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
std::string toString(BankTypes e) { return bank_name(e); }
std::ostream& toStream(BankTypes e, std::ostream& os) { return os << std::quoted(toString(e), '\''); }
std::ostream& operator<<(std::ostream& s, BankTypes e) { return toStream(e, s); }
StatusCode parse(BankTypes& bt, const std::string& in)
{
auto s = std::string_view {in};
if (!s.empty() && s.front() == s.back() && (s.front() == '\'' || s.front() == '\"')) {
s.remove_prefix(1);
s.remove_suffix(1);
}
// Use BankSizes here because it has all he BankTypes as keys.
auto i = std::find_if(BankSizes.begin(), BankSizes.end(), [s](auto e) { return s == bank_name(std::get<0>(e)); });
if (i == BankSizes.end()) return StatusCode::FAILURE;
bt = i->first;
return StatusCode::SUCCESS;
}
namespace Gaudi::Parsers {
StatusCode parse(std::set<BankTypes>& s, const std::string& in)
{
s.clear();
using Gaudi::Parsers::parse;
std::set<std::string> ss;
return parse(ss, in).andThen([&]() -> StatusCode {
try {
std::transform(begin(ss), end(ss), std::inserter(s, begin(s)), [](const std::string& str) {
BankTypes t {};
parse(t, str).orThrow("Bad Parse", "");
return t;
});
return StatusCode::SUCCESS;
} catch (const GaudiException& e) {
return e.code();
}
});
}
} // namespace Gaudi::Parsers
namespace {
bool check_top5(BankTypes bt, LHCb::RawBank const* bank)
{
auto const sys = static_cast<SourceIdSys>(SourceId_sys(bank->sourceID()));
auto it = Allen::subdetectors.find(sys);
return it != Allen::subdetectors.end() && it->second == bt;
}
} // namespace
/** @class TransposeRawBanks TransposeRawBanks.h
* Algorithm that dumps raw banks to binary files.
*
* @author Roel Aaij
* @date 2018-08-27
*/
class TransposeRawBanks : public Gaudi::Functional::MergingTransformer<
std::array<TransposedBanks, LHCb::RawBank::types().size()>(VOC<LHCb::RawEvent*> const&),
Gaudi::Functional::Traits::BaseClass_t<GaudiHistoAlg>> {
class TransposeRawBanks : public Gaudi::Functional::MergingTransformer<std::array<TransposedBanks, NBankTypes>(
VOC<LHCb::RawBank::View> const&)> {
public:
/// Standard constructor
TransposeRawBanks(const std::string& name, ISvcLocator* pSvcLocator);
StatusCode initialize() override;
std::array<TransposedBanks, LHCb::RawBank::types().size()> operator()(
VOC<LHCb::RawEvent*> const& rawEvents) const override;
std::array<TransposedBanks, NBankTypes> operator()(VOC<LHCb::RawBank::View> const& rawEvents) const override;
private:
Gaudi::Property<std::set<LHCb::RawBank::BankType>> m_bankTypes {this,
"BankTypes",
{LHCb::RawBank::VP,
LHCb::RawBank::VPRetinaCluster,
LHCb::RawBank::UT,
LHCb::RawBank::FTCluster,
LHCb::RawBank::EcalPacked,
LHCb::RawBank::Calo,
LHCb::RawBank::Muon,
LHCb::RawBank::ODIN,
LHCb::RawBank::Plume,
LHCb::RawBank::Rich}};
std::array<AIDA::IHistogram1D*, LHCb::RawBank::types().size()> m_histos;
Gaudi::Property<std::set<BankTypes>> m_bankTypes {this,
"BankTypes",
{BankTypes::VP,
BankTypes::UT,
BankTypes::FT,
BankTypes::MUON,
BankTypes::ODIN,
BankTypes::Rich1,
BankTypes::Rich2,
BankTypes::ECal,
BankTypes::Plume}};
std::array<std::unique_ptr<Gaudi::Accumulators::Histogram<1>>, NBankTypes> m_histos;
std::unordered_map<BankTypes, std::unordered_set<LHCb::RawBank::BankType>> m_mapping;
};
TransposeRawBanks::TransposeRawBanks(const std::string& name, ISvcLocator* pSvcLocator) :
......@@ -88,72 +137,94 @@ TransposeRawBanks::TransposeRawBanks(const std::string& name, ISvcLocator* pSvcL
name,
pSvcLocator,
// Inputs
KeyValues {"RawEventLocations", {LHCb::RawEventLocation::Default}},
KeyValues {"RawBankLocations", {LHCb::RawEventLocation::Default}},
// Output
KeyValue {"AllenRawInput", "Allen/Raw/Input"})
{}
StatusCode TransposeRawBanks::initialize()
{
for (auto bt : LHCb::RawBank::types()) {
m_histos[bt] = (m_bankTypes.value().count(bt) ? book1D(toString(bt), -0.5, 603.5, 151) : nullptr);
using Axis1D = Gaudi::Accumulators::Axis<double>;
for (auto const& [lhcb_type, bank_types] : Allen::bank_mapping) {
for (auto bt : bank_types) {
m_mapping[bt].insert(lhcb_type);
}
}
for (auto bt : m_bankTypes.value()) {
if (!m_mapping.count(bt)) {
error() << "Cannot find appropriate LHCb::RawBank::BankType(s) for Allen BankType " << bank_name(bt) << endmsg;
return StatusCode::FAILURE;
}
}
for (size_t i = 0; i < NBankTypes; ++i) {
auto bt = static_cast<BankTypes>(i);
if (m_bankTypes.value().count(bt)) {
auto bn = bank_name(bt);
m_histos[to_integral(bt)] =
std::make_unique<Gaudi::Accumulators::Histogram<1>>(this, bn, bn, Axis1D {151, -0.5, 603.5});
}
}
return StatusCode::SUCCESS;
}
std::array<TransposedBanks, LHCb::RawBank::types().size()> TransposeRawBanks::operator()(
VOC<LHCb::RawEvent*> const& rawEvents) const
std::array<TransposedBanks, NBankTypes> TransposeRawBanks::operator()(VOC<LHCb::RawBank::View> const& allBanks) const
{
std::array<TransposedBanks, NBankTypes> output;
std::array<std::vector<LHCb::RawBank const*>, NBankTypes> rawBanks;
std::array<TransposedBanks, LHCb::RawBank::types().size()> output;
std::array<LHCb::RawBank::View, LHCb::RawBank::types().size()> rawBanks;
for (auto const* rawEvent : rawEvents) {
if (rawEvent == nullptr) continue;
std::for_each(m_bankTypes.begin(), m_bankTypes.end(), [this, rawEvent, &rawBanks](auto bt) {
auto banks = rawEvent->banks(bt);
for (auto banks : allBanks) {
std::for_each(m_bankTypes.begin(), m_bankTypes.end(), [banks, &rawBanks](auto bt) {
auto const bt_idx = to_integral(bt);
if (!banks.empty()) {
if (rawBanks[bt].empty()) {
rawBanks[bt] = banks;
// For the Calo and Rich, use the top5 bits of the source ID
// to determine which banks to add. This will take care of
// splitting Calo banks into ECal and HCal and Rich into
// Rich1 and Rich2.
std::function<bool(BankTypes bt, LHCb::RawBank const* bank)> pred;
// In a RawBank::View all banks have the same type
auto const lhcb_type = banks[0]->type();
auto lhcb_it = Allen::bank_mapping.find(lhcb_type);
if (lhcb_it != Allen::bank_mapping.end() && lhcb_it->second.size() > 1) {
pred = check_top5;
}
else {
pred = [](BankTypes, LHCb::RawBank const*) { return true; };
}
else if (msgLevel(MSG::DEBUG)) {
debug() << "Multiple RawEvents contain " << toString(bt) << " banks. The first ones found will be used."
<< endmsg;
for (auto bank : banks) {
if (pred(bt, bank)) {
rawBanks[bt_idx].emplace_back(bank);
}
}
}
});
}
// We have to deal with the fact that calo banks can come in different types
for (auto bt : m_bankTypes.value()) {
if (bt == LHCb::RawBank::VP || bt == LHCb::RawBank::VPRetinaCluster) {
if (rawBanks[LHCb::RawBank::VP].empty() && rawBanks[LHCb::RawBank::VPRetinaCluster].empty()) {
// Both VP and Retina banks are empty
throw GaudiException {"Cannot find " + toString(bt) + " raw bank.", "", StatusCode::FAILURE};
}
}
else if (bt == LHCb::RawBank::EcalPacked || bt == LHCb::RawBank::HcalPacked) {
if (rawBanks[bt].empty() && rawBanks[LHCb::RawBank::Calo].empty()) {
// Old-style calo banks empty and new-style calo banks also empty
throw GaudiException {"Cannot find " + toString(bt) + " raw bank.", "", StatusCode::FAILURE};
}
}
else if (bt == LHCb::RawBank::Calo) {
if (
rawBanks[bt].empty() &&
((m_bankTypes.value().count(LHCb::RawBank::EcalPacked) && rawBanks[LHCb::RawBank::EcalPacked].empty()) ||
(m_bankTypes.value().count(LHCb::RawBank::HcalPacked) && rawBanks[LHCb::RawBank::HcalPacked].empty()))) {
// New-style calo banks empty and old-style calo banks also empty
throw GaudiException {"Cannot find " + toString(bt) + " raw bank.", "", StatusCode::FAILURE};
// Default comparison for sorting is by source ID
std::function<bool(LHCb::RawBank const* a, LHCb::RawBank const* b)> compare =
[](LHCb::RawBank const* a, LHCb::RawBank const* b) { return a->sourceID() < b->sourceID(); };
if (bt == BankTypes::VP) {
auto const& banks = rawBanks[bt_idx];
if (
std::any_of(
banks.begin(), banks.end(), [](LHCb::RawBank const* bank) { return bank->type() == LHCb::RawBank::VP; }) &&
std::any_of(banks.begin(), banks.end(), [](LHCb::RawBank const* bank) {
return bank->type() == LHCb::RawBank::VPRetinaCluster;
})) {
// Sort VP banks first by bank type and then by source ID to partition in VP and VPRetinaCluster banks.
compare = [](LHCb::RawBank const* a, LHCb::RawBank const* b) {
return a->type() == b->type() ? a->sourceID() < b->sourceID() : a->type() < b->type();
};
}
}
}
else if (rawBanks[bt].empty()) {
throw GaudiException {"Cannot find " + toString(bt) + " raw bank.", "", StatusCode::FAILURE};
}
// Sort banks
std::sort(rawBanks[bt_idx].begin(), rawBanks[bt_idx].end(), compare);
});
}
for (auto bt : LHCb::RawBank::types()) {
auto const& banks = rawBanks[bt];
for (auto bt : m_bankTypes) {
auto const& banks = rawBanks[to_integral(bt)];
if (banks.empty()) continue;
const uint32_t nBanks = banks.size();
......@@ -180,12 +251,11 @@ std::array<TransposedBanks, LHCb::RawBank::types().size()> TransposeRawBanks::op
auto bEnd = bank->end<uint32_t>() + (bank->size() % sizeof(uint32_t) != 0);
// Debug/testing histogram with the sizes of the binary data per bank
auto histo = m_histos[bt];
if (histo == nullptr) {
warning() << "No histogram booked for bank type " << toString(bt) << endmsg;
if (m_histos[to_integral(bt)]) {
++(*m_histos[to_integral(bt)])[(bEnd - bStart) * sizeof(uint32_t)];
}
else {
histo->fill((bEnd - bStart) * sizeof(uint32_t));
warning() << "No histogram booked for bank type " << toString(bt) << endmsg;
}
while (bStart != bEnd) {
......@@ -203,7 +273,7 @@ std::array<TransposedBanks, LHCb::RawBank::types().size()> TransposeRawBanks::op
// Dumping number_of_rawbanks + 1 offsets!
DumpUtils::Writer bank_buffer;
bank_buffer.write(nBanks, bankOffsets, bankData);
output[bt] =
output[to_integral(bt)] =
TransposedBanks {bank_buffer.buffer(), std::move(bankSizes), std::move(bankTypes), banks[0]->version()};
}
return output;
......
......@@ -28,19 +28,3 @@ bool DumpUtils::createDirectory(fs::path directory)
}
return true;
}
size_t MuonUtils::size_index(
std::array<unsigned int, 16> const& offset,
std::array<int, 16> const& gridX,
std::array<int, 16> const& gridY,
LHCb::Detector::Muon::TileID const& tile)
{
auto idx = 4 * tile.station() + tile.region();
auto index = offset[idx] + tile.quarter() * gridY[idx] * 6;
if (tile.nY() < static_cast<unsigned int>(gridY[idx])) {
return index + 2 * tile.nY() + 2 * (tile.nX() - gridX[idx]) / gridX[idx];
}
else {
return index + 4 * tile.nY() - 2 * gridY[idx] + (2 * tile.nX() / gridX[idx]);
}
}
/*****************************************************************************\
* (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration *
* *
* This software is distributed under the terms of the Apache License *
* version 2 (Apache-2.0), 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. *
\*****************************************************************************/
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/iostream.h>
#include <pybind11/pytypes.h>
#include <iostream>
#include <map>
#include <BankMapping.h>
namespace {
namespace py = pybind11;
std::map<std::string, std::set<std::string>> make_mapping()
{
std::map<std::string, std::set<std::string>> mapping;
for (auto const& [lhcb_bt, bts] : Allen::bank_mapping) {
std::set<std::string> to;
for (auto bt : bts) {
auto n = bank_name(bt);
if (n == "Unknown") {
throw StrException {"Cannot map BankType " + std::to_string(to_integral(bt)) +
" with unknown string representation"};
}
to.insert(n);
}
mapping.emplace(LHCb::RawBank::typeName(lhcb_bt), std::move(to));
}
return mapping;
}
} // namespace
namespace Allen::Python {
static const std::map<std::string, std::set<std::string>> mapping = make_mapping();
}
// Python Module and Docstrings
PYBIND11_MODULE(bank_mapping, m)
{
m.doc() = R"pbdoc(
Utility functions to obtain the mapping between HLT1 BankTypes and LHCb::RawBank::BankType
.. currentmodule:: bank_mapping
.. autosummary::
:toctree: _generate
bank_mapping
)pbdoc";
m.attr("mapping") = py::cast(&Allen::Python::mapping);
}