26#include <fmt/format.h>
40 LOG(
debug) <<
"Removing output file of discarded slot";
44 std::string fileToRemove =
fileName +
".part";
45 if (!std::filesystem::remove(fileToRemove)) {
46 LOG(warning) <<
"Tried to delete, but could not find file named " << fileToRemove;
53 LOG(error) <<
"Must not call copy constructor of ResidualsContainer";
60 LOGP(
debug,
"Move operator called for rhs with {} entries", rhs.nResidualsTotal);
62 fileOut = std::move(rhs.fileOut);
70 residuals[iSec] = std::move(rhs.residuals[iSec]);
71 stats[iSec] = std::move(rhs.stats[iSec]);
76 lumi = std::move(rhs.lumi);
79 trkData = std::move(rhs.trkData);
87void ResidualsContainer::init(
const TrackResiduals* residualsEngine, std::string outputDir,
bool wFile,
bool wBinnedResid,
bool wUnbinnedResid,
bool wTrackData,
int autosave,
int compression,
long orbitResetTime)
97 bool outFileCreated =
false;
99 fileName +=
std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).
count());
100 while (!outFileCreated && nTries < 100) {
101 std::random_device
rd;
102 std::mt19937
g(
rd());
103 std::uniform_int_distribution<>
distr(0, 99);
106 std::string fileNameTmp = outputDir +
fileName;
107 fileNameTmp +=
".part";
108 if (std::filesystem::exists(fileNameTmp)) {
113 fileOut = std::make_unique<TFile>(fileNameTmp.c_str(),
"recreate",
"", compression);
114 outFileCreated =
true;
116 if (!outFileCreated) {
117 LOG(error) <<
"Could not create output file for this slot after 100 tries. Disable file writing for this slot";
129 treeOutTrackData = std::make_unique<TTree>(
"trackData",
"Track information incl cluster range ref");
133 treeOutResiduals = std::make_unique<TTree>(
"resid",
"TPC binned residuals");
134 treeOutStats = std::make_unique<TTree>(
"stats",
"Voxel statistics mean position and nEntries");
152 treeOutRecords = std::make_unique<TTree>(
"records",
"Statistics per TF slot");
159 LOG(
debug) <<
"Done initializing residuals container for file named " <<
fileName;
177 LOG(
debug) <<
"Filling ResidualsContainer with vector of size " << resid.size();
178 uint32_t nUnbinnedResidualsInTF = 0;
179 uint32_t nBinnedResidualsInTF = 0;
187 for (
const auto& residIn : resid) {
188 ++nUnbinnedResidualsInTF;
189 bool counterIncremented =
false;
193 counterIncremented =
true;
198 int sec = residIn.sec;
200 auto& statVecOut =
stats[sec];
201 std::array<unsigned char, TrackResiduals::VoxDim> bvox;
202 float xPos = param::RowX[residIn.row];
203 float yPos = residIn.y * param::MaxY / 0x7fff + residIn.dy * param::MaxResid / 0x7fff;
204 float zPos = residIn.z * param::MaxZ / 0x7fff + residIn.dz * param::MaxResid / 0x7fff;
207 LOGF(
debug,
"Dropping residual in sec(%i), x(%f), y(%f), z(%f)", sec, xPos, yPos, zPos);
210 residVecOut.emplace_back(residIn.dy, residIn.dz, residIn.tgSlp, bvox);
212 float& binEntries = stat.nEntries;
213 float oldEntries = binEntries++;
214 float norm = 1.f / binEntries;
216 float xPosInv = 1.f / xPos;
220 if (!counterIncremented) {
223 ++nBinnedResidualsInTF;
225 for (
const auto& trkRef : trkRefsIn) {
237 for (
const auto& trkIn : *trkDataIn) {
254 lumi.push_back(*lumiInput);
264 LOG(info) <<
"Writing results to file. Closing afterwards? " << closeFileAfterwards;
279 if (closeFileAfterwards) {
304 const auto& statVecPrev = prev->
stats[iSec];
305 auto& statVec =
stats[iSec];
307 const auto& statPrev = statVecPrev[iVox];
308 auto& stat = statVec[iVox];
310 if (statPrev.nEntries + stat.nEntries > 0.1) {
312 norm /= (statPrev.nEntries + stat.nEntries);
317 stat.nEntries += statPrev.nEntries;
371 LOGP(
debug,
"Done with the merge. Current slot has {} entries",
getNEntries());
376 LOG(info) <<
"There are in total " <<
nResidualsTotal <<
" residuals stored in the container";
389 LOG(
debug) <<
"There are " << slot.
getContainer()->getNEntries() <<
" entries currently. Min entries per voxel: " << mMinEntries;
391 LOGP(
debug,
"Slot has {} entries per voxel, at least {} are required", entriesPerVoxel, mMinEntries);
392 return entriesPerVoxel >= mMinEntries;
402 LOG(info) <<
"Finalizing slot";
403 auto finalizeStartTime = std::chrono::high_resolution_clock::now();
406 if (!mWriteOutput || cont->getNEntries() == 0 || !cont->writeToRootFile) {
407 LOGP(info,
"Skip writing output with {} entries, since file output is disabled or slot is empty", cont->getNEntries());
410 cont->TPCVDriftRef = mTPCVDriftRef;
411 cont->TPCDriftTimeOffsetRef = mTPCDriftTimeOffsetRef;
412 cont->writeToFile(
true);
418 auto fileName = fmt::format(
"o2tpc_residuals_{}_{}_{}_{}.root", timeStartMS, timeEndMS, slot.
getTFStart(), slot.
getTFEnd());
419 auto fileNameWithPath = mOutputDir + fileName;
421 if (mStoreMetaData) {
425 fileMetaData.
type =
"calib";
427 auto metaFileNameTmp = fmt::format(
"{}{}.tmp", mMetaOutputDir, fileName);
428 auto metaFileName = fmt::format(
"{}{}.done", mMetaOutputDir, fileName);
430 std::ofstream metaFileOut(metaFileNameTmp);
431 metaFileOut << fileMetaData;
433 std::filesystem::rename(metaFileNameTmp, metaFileName);
434 }
catch (std::exception
const& e) {
435 LOG(error) <<
"Failed to store residuals meta data file " << metaFileName <<
", reason: " << e.what();
438 std::chrono::duration<double, std::milli> finalizeDuration = std::chrono::high_resolution_clock::now() - finalizeStartTime;
439 LOGP(info,
"Finalizing calibration slot took: {} ms", std::chrono::duration_cast<std::chrono::milliseconds>(finalizeDuration).
count());
444 auto emplaceStartTime = std::chrono::high_resolution_clock::now();
446 auto& slot = front ? cont.emplace_front(tStart, tEnd) : cont.emplace_back(tStart, tEnd);
447 slot.setContainer(std::make_unique<ResidualsContainer>());
448 slot.getContainer()->init(&mTrackResiduals, mOutputDir, mWriteOutput, mWriteBinnedResiduals, mWriteUnbinnedResiduals, mWriteTrackData, mAutosaveInterval, mCompressionSetting, mOrbitResetTime);
449 std::chrono::duration<double, std::milli> emplaceDuration = std::chrono::high_resolution_clock::now() - emplaceStartTime;
450 LOGP(info,
"Emplacing new calibration slot took: {} ms", std::chrono::duration_cast<std::chrono::milliseconds>(emplaceDuration).
count());
457 if (
v.refVDrift != mTPCVDriftRef) {
458 mTPCVDriftRef =
v.refVDrift;
459 mTPCDriftTimeOffsetRef =
v.refTimeOffset;
460 LOGP(info,
"Imposing reference VDrift={}/TDrift={} for TPC residuals extraction", mTPCVDriftRef, mTPCDriftTimeOffsetRef);
Collects local TPC cluster residuals from EPNs.
Parameters used for TPC space point calibration.
calibration data from laser track calibration
static int getNHBFPerTF()
o2::calibration::TFType TFType
const Container * getContainer() const
TFType getTFStart() const
Slot & emplaceNewSlot(bool front, TFType tStart, TFType tEnd) final
bool hasEnoughData(const Slot &slot) const final
void setTPCVDrift(const o2::tpc::VDriftCorrFact &v)
void finalizeSlot(Slot &slot) final
~ResidualAggregator() final
size_t getGlbVoxBin(int ix, int ip, int iz) const
int getNVoxelsPerSector() const
Get the total number of voxels per TPC sector (mNXBins * mNY2XBins * mNZ2XBins)
void getVoxelCoordinates(int isec, int ix, int ip, int iz, float &x, float &p, float &z) const
bool findVoxelBin(int secID, float x, float y, float z, std::array< unsigned char, VoxDim > &bvox) const
Calculates the bin indices for given x, y, z in sector coordinates.
constexpr double LHCOrbitMUS
Global TPC definitions and constants.
constexpr unsigned char SECTORSPERSIDE
constexpr unsigned char SIDES
std::string to_string(gsl::span< T, Size > span)
std::unique_ptr< TTree > treeOutResidualsUnbinned
std::vector< TrackDataCompact > * trackInfoPtr
allows to obtain track type for each unbinned residual downstream
long orbitReset
current orbit reset time in ms
std::array< std::vector< TrackResiduals::VoxStats > *, SECTORSPERSIDE *SIDES > statsPtr
std::vector< TrackData > * trkDataPtr
track data and cluster ranges
std::unique_ptr< TTree > treeOutRecords
ResidualsContainer()=default
float TPCVDriftRef
TPC nominal drift speed in cm/microseconds.
void fillStatisticsBranches()
std::vector< uint32_t > sumBinnedResid
void init(const TrackResiduals *residualsEngine, std::string outputDir, bool wFile, bool wBinnedResid, bool wUnbinnedResid, bool wTrackData, int autosave, int compression, long orbitResetTime)
TFType lastSeenTF
the last TF which was added to this container
uint64_t timeMS
for each processed TF we store its absolute time in ms in the tree of unbinned residuals
uint64_t getNEntries() const
std::vector< UnbinnedResid > * unbinnedResPtr
unbinned residuals which are sent to the aggregator
std::vector< uint32_t > tfOrbits
std::vector< uint32_t > * sumBinnedResidPtr
sum of binned residuals for each TF
uint32_t firstTForbit
stored for the first seen TF to allow conversion to time stamp
std::vector< o2::ctp::LumiInfo > * lumiPtr
luminosity information from CTP per TF
void fill(const o2::dataformats::TFIDInfo &ti, const gsl::span< const UnbinnedResid > resid, const gsl::span< const o2::tpc::TrackDataCompact > trkRefsIn, const gsl::span< const o2::tpc::TrackData > *trkDataIn, const o2::ctp::LumiInfo *lumiInput)
std::array< std::vector< TrackResiduals::LocalResid > *, SECTORSPERSIDE *SIDES > residualsPtr
bool writeBinnedResid
flag, whether binned residuals should be written out
std::vector< o2::ctp::LumiInfo > lumi
bool writeTrackData
flag, whether full seeding track information should be written out
std::vector< TrackDataCompact > trackInfo
std::vector< uint32_t > * tfOrbitsPtr
first TF orbit
bool writeUnbinnedResiduals
flag, whether unbinned residuals should be written out
void writeToFile(bool closeFileAfterwards)
o2::ctp::LumiInfo lumiTF
for each processed TF we store the lumi information in the tree of unbinned residuals
std::array< std::vector< TrackResiduals::LocalResid >, SECTORSPERSIDE *SIDES > residuals
local (binned) residuals per sector
void merge(ResidualsContainer *prev)
std::vector< UnbinnedResid > unbinnedRes
float TPCDriftTimeOffsetRef
TPC nominal (e.g. at the start of run) drift time bias in cm/mus.
std::unique_ptr< TFile > fileOut
std::vector< uint32_t > sumUnbinnedResid
std::array< std::vector< TrackResiduals::VoxStats >, SECTORSPERSIDE *SIDES > stats
voxel statistics per sector
std::unique_ptr< TTree > treeOutStats
const TrackResiduals * trackResiduals
TFType firstSeenTF
the first TF which was added to this container
uint64_t nResidualsTotal
the total number of residuals for this container
std::vector< uint32_t > * sumUnbinnedResidPtr
sum of unbinned residuals for each TF
std::unique_ptr< TTree > treeOutResiduals
int autosaveInterval
if > 0, then the output written to file for every n-th TF
std::unique_ptr< TTree > treeOutTrackData
std::vector< TrackData > trkData
bool writeToRootFile
set to false to avoid that any output file is produced
static std::string concat_string(Ts const &... ts)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::uniform_int_distribution< unsigned long long > distr