Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions ALICE3/Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,30 @@
o2physics_add_library(ALICE3Core
SOURCES TOFResoALICE3.cxx
TrackUtilities.cxx
DelphesO2TrackSmearer.cxx
FlatLutEntry.cxx
FlatTrackSmearer.cxx
GeometryContainer.cxx
PUBLIC_LINK_LIBRARIES O2::Framework
O2Physics::AnalysisCore)

o2physics_target_root_dictionary(ALICE3Core
HEADERS TOFResoALICE3.h
TrackUtilities.h
DelphesO2TrackSmearer.h
FlatLutEntry.h
GeometryContainer.h
LINKDEF ALICE3CoreLinkDef.h)

o2physics_add_library(FastTracker
SOURCES FastTracker.cxx
DetLayer.cxx
DelphesO2LutWriter.cxx
FlatLutEntry.cxx
FlatLutWriter.cxx
PUBLIC_LINK_LIBRARIES O2::Framework
O2Physics::AnalysisCore
O2Physics::ALICE3Core)

o2physics_target_root_dictionary(FastTracker
HEADERS FastTracker.h
DetLayer.h
DelphesO2LutWriter.h
FlatLutWriter.h
LINKDEF FastTrackerLinkDef.h)
2 changes: 1 addition & 1 deletion ALICE3/Core/FastTrackerLinkDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@

#pragma link C++ class o2::fastsim::GeometryContainer + ;
#pragma link C++ class o2::fastsim::FastTracker + ;
#pragma link C++ class o2::fastsim::DelphesO2LutWriter + ;
#pragma link C++ class o2::fastsim::FlatLutWriter + ;

#endif // ALICE3_CORE_FASTTRACKERLINKDEF_H_
268 changes: 268 additions & 0 deletions ALICE3/Core/FlatLutEntry.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license 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 "FlatLutEntry.h"

#include <Framework/Logger.h>
#include <Framework/RuntimeError.h>

#include <cstring>

namespace o2::delphes
{

float map_t::fracPositionWithinBin(float val) const
{
float width = (max - min) / nbins;
int bin;
float returnVal = 0.5f;
if (log) {
bin = static_cast<int>((std::log10(val) - min) / width);
returnVal = ((std::log10(val) - min) / width) - bin;
} else {
bin = static_cast<int>((val - min) / width);
returnVal = val / width - bin;
}
return returnVal;
}

int map_t::find(float val) const
{
float width = (max - min) / nbins;
int bin;
if (log) {
bin = static_cast<int>((std::log10(val) - min) / width);
} else {
bin = static_cast<int>((val - min) / width);
}
if (bin < 0) {
return 0;
}
if (bin > nbins - 1) {
return nbins - 1;
}
return bin;
}

void map_t::print() const
{
LOGF(info, "nbins = %d, min = %f, max = %f, log = %s \n", nbins, min, max, log ? "on" : "off");
}

bool lutHeader_t::check_version() const
{
return (version == LUTCOVM_VERSION);
}

void lutHeader_t::print() const
{
LOGF(info, " version: %d \n", version);
LOGF(info, " pdg: %d \n", pdg);
LOGF(info, " field: %f \n", field);
LOGF(info, " nchmap: ");
nchmap.print();
LOGF(info, " radmap: ");
radmap.print();
LOGF(info, " etamap: ");
etamap.print();
LOGF(info, " ptmap: ");
ptmap.print();
}

void FlatLutData::initialize(const lutHeader_t& header)
{
mNchBins = header.nchmap.nbins;
mRadBins = header.radmap.nbins;
mEtaBins = header.etamap.nbins;
mPtBins = header.ptmap.nbins;

size_t headerSize = sizeof(lutHeader_t);
size_t numEntries = static_cast<size_t>(mNchBins) * mRadBins * mEtaBins * mPtBins;
size_t entriesSize = numEntries * sizeof(lutEntry_t);
size_t totalSize = headerSize + entriesSize;

mData.resize(totalSize);
// Write header at the beginning
std::memcpy(mData.data(), &header, headerSize);
updateRef();
}

size_t FlatLutData::getEntryOffset(int nch_bin, int rad_bin, int eta_bin, int pt_bin) const
{
size_t headerSize = sizeof(lutHeader_t);

// Linear index: nch varies slowest, pt varies fastest
// idx = nch * (rad*eta*pt) + rad * (eta*pt) + eta * pt + pt
size_t linearIdx = static_cast<size_t>(nch_bin) * (mRadBins * mEtaBins * mPtBins) + static_cast<size_t>(rad_bin) * (mEtaBins * mPtBins) + static_cast<size_t>(eta_bin) * mPtBins + static_cast<size_t>(pt_bin);

return headerSize + linearIdx * sizeof(lutEntry_t);
}

const lutEntry_t* FlatLutData::getEntryRef(int nch_bin, int rad_bin, int eta_bin, int pt_bin) const
{
size_t offset = getEntryOffset(nch_bin, rad_bin, eta_bin, pt_bin);
return reinterpret_cast<const lutEntry_t*>(mDataRef.data() + offset);
}

lutEntry_t* FlatLutData::getEntry(int nch_bin, int rad_bin, int eta_bin, int pt_bin)
{
size_t offset = getEntryOffset(nch_bin, rad_bin, eta_bin, pt_bin);
return reinterpret_cast<lutEntry_t*>(mData.data() + offset);
}

const lutHeader_t& FlatLutData::getHeaderRef() const
{
return *reinterpret_cast<const lutHeader_t*>(mDataRef.data());
}

lutHeader_t& FlatLutData::getHeader()
{
return *reinterpret_cast<lutHeader_t*>(mData.data());
}

void FlatLutData::updateRef()
{
mDataRef = std::span{mData.data(), mData.size()};
}

void FlatLutData::cacheDimensions()
{
auto const& header = getHeaderRef();
mNchBins = header.nchmap.nbins;
mRadBins = header.radmap.nbins;
mEtaBins = header.etamap.nbins;
mPtBins = header.ptmap.nbins;
}

void FlatLutData::resetDimensions()
{
mNchBins = 0;
mRadBins = 0;
mEtaBins = 0;
mPtBins = 0;
}

void FlatLutData::adopt(const uint8_t* buffer, size_t size)
{
mData.resize(size);
std::memcpy(mData.data(), buffer, size);
updateRef();
cacheDimensions();
}

void FlatLutData::view(const uint8_t* buffer, size_t size)
{
mData.clear();
mDataRef = std::span{buffer, size};
cacheDimensions();
}

void FlatLutData::validateBuffer(const uint8_t* buffer, size_t size)
{
auto header = PreviewHeader(buffer, size);
if (!header.check_version()) {
throw framework::runtime_error_f("LUT header version mismatch: expected %d, got %d", LUTCOVM_VERSION, header.version);
}
auto mNchBins = header.nchmap.nbins;
auto mRadBins = header.radmap.nbins;
auto mEtaBins = header.etamap.nbins;
auto mPtBins = header.ptmap.nbins;

size_t expectedSize = sizeof(lutHeader_t) + static_cast<size_t>(mNchBins) * mRadBins * mEtaBins * mPtBins * sizeof(lutEntry_t);

if (size < expectedSize) {
throw framework::runtime_error_f("Buffer size mismatch: expected %zu, got %zu", expectedSize, size);
}
}

lutHeader_t FlatLutData::PreviewHeader(const uint8_t* buffer, size_t size)
{
if (size < sizeof(lutHeader_t)) {
throw framework::runtime_error_f("Buffer too small for LUT header: expected at least %zu, got %zu", sizeof(lutHeader_t), size);
}
const auto* header = reinterpret_cast<const lutHeader_t*>(buffer);
if (!header->check_version()) {
throw framework::runtime_error_f("LUT header version mismatch: expected %d, got %d", LUTCOVM_VERSION, header->version);
}
return *header;
}

FlatLutData FlatLutData::AdoptFromBuffer(const uint8_t* buffer, size_t size)
{
validateBuffer(buffer, size);
FlatLutData data;

// Copy buffer
data.adopt(buffer, size);
return data;
}

FlatLutData FlatLutData::ViewFromBuffer(const uint8_t* buffer, size_t size)
{
validateBuffer(buffer, size);
FlatLutData data;

// Store reference to external buffer
// WARNING: Caller must ensure buffer lifetime exceeds FlatLutData usage
data.view(buffer, size);
return data;
}

bool FlatLutData::isLoaded() const
{
return ((!mData.empty()) || (!mDataRef.empty()));
}

lutHeader_t FlatLutData::PreviewHeader(std::ifstream& file, const char* filename)
{
lutHeader_t tempHeader;
file.read(reinterpret_cast<char*>(&tempHeader), sizeof(lutHeader_t));
if (file.gcount() != static_cast<std::streamsize>(sizeof(lutHeader_t))) {
throw framework::runtime_error_f("Failed to read LUT header from %s", filename);
}
if (!tempHeader.check_version()) {
throw framework::runtime_error_f("LUT header version mismatch: expected %d, got %d", LUTCOVM_VERSION, tempHeader.version);
}
return tempHeader;
}

FlatLutData FlatLutData::loadFromFile(std::ifstream& file, const char* filename)
{
// Read header first
lutHeader_t tempHeader = PreviewHeader(file, filename);

FlatLutData data;

// Initialize flat data structure
data.initialize(tempHeader);

// Read all entries sequentially into flat buffer
size_t headerSize = sizeof(lutHeader_t);
size_t numEntries = static_cast<size_t>(data.mNchBins) * data.mRadBins * data.mEtaBins * data.mPtBins;
size_t entriesSize = numEntries * sizeof(lutEntry_t);

file.read(reinterpret_cast<char*>(data.data() + headerSize), entriesSize);
if (file.gcount() != static_cast<std::streamsize>(entriesSize)) {
throw framework::runtime_error_f("Failed to read LUT entries from %s: expected %zu bytes, got %zu", filename, entriesSize, static_cast<size_t>(file.gcount()));
}

LOGF(info, "Successfully loaded LUT from %s: %zu entries", filename, numEntries);
return data;
}

void FlatLutData::reset()
{
mData.clear();
updateRef();
resetDimensions();
}

} // namespace o2::delphes
Loading
Loading