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);
69 for (
int iSec = 0; iSec < SECTORSPERSIDE * SIDES; ++iSec) {
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);
88void ResidualsContainer::init(
const TrackResiduals* residualsEngine, std::string outputDir,
bool wFile,
bool wBinnedResid,
bool wUnbinnedResid,
bool wTrackData,
bool wTrackDataMC,
int autosave,
int compression,
long orbitResetTime)
99 bool outFileCreated =
false;
101 fileName +=
std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).
count());
102 while (!outFileCreated && nTries < 100) {
103 std::random_device
rd;
104 std::mt19937
g(
rd());
105 std::uniform_int_distribution<>
distr(0, 99);
108 std::string fileNameTmp = outputDir +
fileName;
109 fileNameTmp +=
".part";
110 if (std::filesystem::exists(fileNameTmp)) {
115 fileOut = std::make_unique<TFile>(fileNameTmp.c_str(),
"recreate",
"", compression);
116 outFileCreated =
true;
118 if (!outFileCreated) {
119 LOG(error) <<
"Could not create output file for this slot after 100 tries. Disable file writing for this slot";
132 treeOutTrackData = std::make_unique<TTree>(
"trackData",
"Track information incl cluster range ref");
139 treeOutResiduals = std::make_unique<TTree>(
"resid",
"TPC binned residuals");
140 treeOutStats = std::make_unique<TTree>(
"stats",
"Voxel statistics mean position and nEntries");
141 for (
int iSec = 0; iSec < SECTORSPERSIDE * SIDES; ++iSec) {
158 treeOutRecords = std::make_unique<TTree>(
"records",
"Statistics per TF slot");
165 LOG(
debug) <<
"Done initializing residuals container for file named " <<
fileName;
179void ResidualsContainer::fill(
const o2::dataformats::TFIDInfo& ti,
const gsl::span<const UnbinnedResid> resid,
const gsl::span<const DetInfoResid> detInfoRes,
const gsl::span<const o2::tpc::TrackDataCompact> trkRefsIn,
const gsl::span<const o2::tpc::TrackData>* trkDataIn,
const gsl::span<const o2::tpc::TrackDataMC>* trkDataMCIn,
const o2::ctp::LumiInfo* lumiInput)
183 LOG(
debug) <<
"Filling ResidualsContainer with vector of size " << resid.size();
184 uint32_t nUnbinnedResidualsInTF = 0;
185 uint32_t nBinnedResidualsInTF = 0;
193 for (
const auto& residIn : resid) {
194 bool counterIncremented =
false;
199 counterIncremented =
true;
201 ++nUnbinnedResidualsInTF;
205 if (residIn.isTgSlpClamped() || residIn.isPositionOnly()) {
210 int sec = residIn.sec;
212 auto& statVecOut =
stats[sec];
213 std::array<unsigned char, TrackResiduals::VoxDim> bvox;
214 float xPos = param::RowX[residIn.row];
215 float yPos = residIn.y * param::MaxY / 0x7fff + residIn.dy * param::MaxResid / 0x7fff;
216 float zPos = residIn.z * param::MaxZ / 0x7fff + residIn.dz * param::MaxResid / 0x7fff;
219 LOGF(
debug,
"Dropping residual in sec(%i), x(%f), y(%f), z(%f)", sec, xPos, yPos, zPos);
222 residVecOut.emplace_back(residIn.dy, residIn.dz, residIn.tgSlp, bvox);
224 float& binEntries = stat.nEntries;
225 float oldEntries = binEntries++;
226 float norm = 1.f / binEntries;
228 float xPosInv = 1.f / xPos;
232 if (!counterIncremented) {
235 ++nBinnedResidualsInTF;
237 for (
const auto& trkRef : trkRefsIn) {
249 for (
const auto& trkIn : *trkDataIn) {
253 trkDataMC.assign(trkDataMCIn->begin(), trkDataMCIn->end());
271 lumi.push_back(*lumiInput);
281 LOG(info) <<
"Writing results to file. Closing afterwards? " << closeFileAfterwards;
296 if (closeFileAfterwards) {
319 for (
int iSec = 0; iSec < SECTORSPERSIDE * SIDES; ++iSec) {
321 const auto& statVecPrev = prev->
stats[iSec];
322 auto& statVec =
stats[iSec];
324 const auto& statPrev = statVecPrev[iVox];
325 auto& stat = statVec[iVox];
327 if (statPrev.nEntries + stat.nEntries > 0.1) {
329 norm /= (statPrev.nEntries + stat.nEntries);
334 stat.nEntries += statPrev.nEntries;
394 LOGP(
debug,
"Done with the merge. Current slot has {} entries",
getNEntries());
399 LOG(info) <<
"There are in total " <<
nResidualsTotal <<
" residuals stored in the container";
412 LOG(
debug) <<
"There are " << slot.
getContainer()->getNEntries() <<
" entries currently. Min entries per voxel: " << mMinEntries;
414 LOGP(
debug,
"Slot has {} entries per voxel, at least {} are required", entriesPerVoxel, mMinEntries);
415 return entriesPerVoxel >= mMinEntries;
425 LOG(info) <<
"Finalizing slot";
426 auto finalizeStartTime = std::chrono::high_resolution_clock::now();
429 if (!mWriteOutput || cont->getNEntries() == 0 || !cont->writeToRootFile) {
430 LOGP(info,
"Skip writing output with {} entries, since file output is disabled or slot is empty", cont->getNEntries());
433 cont->TPCVDriftRef = mTPCVDriftRef;
434 cont->TPCDriftTimeOffsetRef = mTPCDriftTimeOffsetRef;
435 cont->writeToFile(
true);
439 long timeStartMS = mOrbitResetTime + (cont->firstTForbit - orbitOffsetStart) * o2::constants::lhc::LHCOrbitMUS * 1.e-3;
440 long timeEndMS = mOrbitResetTime + (cont->firstTForbit + orbitOffsetEnd) * o2::constants::lhc::LHCOrbitMUS * 1.e-3;
441 auto fileName = fmt::format(
"o2tpc_residuals_{}_{}_{}_{}.root", timeStartMS, timeEndMS, slot.
getTFStart(), slot.
getTFEnd());
442 auto fileNameWithPath = mOutputDir + fileName;
444 if (mStoreMetaData) {
448 fileMetaData.
type =
"calib";
450 auto metaFileNameTmp = fmt::format(
"{}{}.tmp", mMetaOutputDir, fileName);
451 auto metaFileName = fmt::format(
"{}{}.done", mMetaOutputDir, fileName);
453 std::ofstream metaFileOut(metaFileNameTmp);
454 metaFileOut << fileMetaData;
456 std::filesystem::rename(metaFileNameTmp, metaFileName);
457 }
catch (std::exception
const& e) {
458 LOG(error) <<
"Failed to store residuals meta data file " << metaFileName <<
", reason: " << e.what();
461 std::chrono::duration<double, std::milli> finalizeDuration = std::chrono::high_resolution_clock::now() - finalizeStartTime;
462 LOGP(info,
"Finalizing calibration slot took: {} ms", std::chrono::duration_cast<std::chrono::milliseconds>(finalizeDuration).
count());
467 auto emplaceStartTime = std::chrono::high_resolution_clock::now();
469 auto& slot = front ? cont.emplace_front(tStart, tEnd) : cont.emplace_back(tStart, tEnd);
470 slot.setContainer(std::make_unique<ResidualsContainer>());
471 slot.getContainer()->init(&mTrackResiduals, mOutputDir, mWriteOutput, mWriteBinnedResiduals, mWriteUnbinnedResiduals, mWriteTrackData, mWriteTrackDataMC, mAutosaveInterval, mCompressionSetting, mOrbitResetTime);
472 std::chrono::duration<double, std::milli> emplaceDuration = std::chrono::high_resolution_clock::now() - emplaceStartTime;
473 LOGP(info,
"Emplacing new calibration slot took: {} ms", std::chrono::duration_cast<std::chrono::milliseconds>(emplaceDuration).
count());
480 if (
v.refVDrift != mTPCVDriftRef) {
481 mTPCVDriftRef =
v.refVDrift;
482 mTPCDriftTimeOffsetRef =
v.refTimeOffset;
483 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.
Global TPC definitions and constants.
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< TrackDataMC > * trkDataMCPtr
MC truth for the track data (MC only)
std::vector< uint32_t > sumBinnedResid
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
bool writeTrackDataMC
flag, whether the MC truth of the seeding tracks should be written out
uint64_t getNEntries() const
std::vector< DetInfoResid > * detInfoUnbResPtr
detector info associated to unbinned residuals which are sent to the aggregator
void fill(const o2::dataformats::TFIDInfo &ti, const gsl::span< const UnbinnedResid > resid, const gsl::span< const DetInfoResid > detInfoRes, const gsl::span< const o2::tpc::TrackDataCompact > trkRefsIn, const gsl::span< const o2::tpc::TrackData > *trkDataIn, const gsl::span< const o2::tpc::TrackDataMC > *trkDataMCIn, const o2::ctp::LumiInfo *lumiInput)
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
std::vector< TrackDataMC > trkDataMC
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 init(const TrackResiduals *residualsEngine, std::string outputDir, bool wFile, bool wBinnedResid, bool wUnbinnedResid, bool wTrackData, bool wTrackDataMC, int autosave, int compression, long orbitResetTime)
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::vector< DetInfoResid > detInfoUnbRes
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