1515
1616#include " SpacePoints/ResidualAggregator.h"
1717#include " SpacePoints/SpacePointsCalibParam.h"
18+ #include " DetectorsCommonDataFormats/FileMetaData.h"
1819
1920#include < filesystem>
21+ #include < numeric>
22+ #include < algorithm>
2023
2124using namespace o2 ::tpc;
2225
@@ -51,20 +54,24 @@ ResidualsContainer::ResidualsContainer(ResidualsContainer&& rhs)
5154 treeOutStats = std::move (rhs.treeOutStats );
5255 for (int iSec = 0 ; iSec < SECTORSPERSIDE * SIDES; ++iSec) {
5356 residuals[iSec] = std::move (rhs.residuals [iSec]);
54- residualsPtr[iSec] = std::move (rhs.residualsPtr [iSec]);
5557 stats[iSec] = std::move (rhs.stats [iSec]);
56- statsPtr[iSec] = std::move (rhs.statsPtr [iSec]);
5758 }
59+ runNumber = rhs.runNumber ;
60+ tfOrbits = std::move (rhs.tfOrbits );
61+ sumOfResiduals = std::move (rhs.sumOfResiduals );
5862}
5963
60- void ResidualsContainer::init (const TrackResiduals* residualsEngine)
64+ void ResidualsContainer::init (const TrackResiduals* residualsEngine, std::string outputDir )
6165{
6266 trackResiduals = residualsEngine;
6367 fileName += std::to_string (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now ().time_since_epoch ()).count ());
6468 fileName += " .root" ;
65- fileOut = std::make_unique<TFile>(fileName.c_str (), " recreate" );
69+ std::string fileNameTmp = outputDir + fileName;
70+ fileNameTmp += " .part" ; // to prevent premature external usage of the file use temporary name
71+ fileOut = std::make_unique<TFile>(fileNameTmp.c_str (), " recreate" );
6672 treeOutResiduals = std::make_unique<TTree>(treeNameResiduals.c_str (), " TPC binned residuals" );
6773 treeOutStats = std::make_unique<TTree>(treeNameStats.c_str (), " Voxel statistics mean position and nEntries" );
74+ treeOutRecords = std::make_unique<TTree>(treeNameRecords.c_str (), " Statistics per TF slot" );
6875 for (int iSec = 0 ; iSec < SECTORSPERSIDE * SIDES; ++iSec) {
6976 residualsPtr[iSec] = &residuals[iSec];
7077 statsPtr[iSec] = &stats[iSec];
@@ -81,6 +88,8 @@ void ResidualsContainer::init(const TrackResiduals* residualsEngine)
8188 treeOutResiduals->Branch (Form (" sec%d" , iSec), &residualsPtr[iSec]);
8289 treeOutStats->Branch (Form (" sec%d" , iSec), &statsPtr[iSec]);
8390 }
91+ treeOutRecords->Branch (" firstTForbit" , &tfOrbitsPtr);
92+ treeOutRecords->Branch (" sumOfResiduals" , &sumOfResidualsPtr);
8493}
8594
8695void ResidualsContainer::fillStatisticsBranches ()
@@ -89,13 +98,15 @@ void ResidualsContainer::fillStatisticsBranches()
8998 // remains empty and we keep the statistics in memory in the vectors
9099 // (since their size anyway does not change)
91100 treeOutStats->Fill ();
101+ treeOutRecords->Fill ();
92102}
93103
94104void ResidualsContainer::fill (const o2::dataformats::TFIDInfo& ti, const gsl::span<const TrackResiduals::UnbinnedResid> data)
95105{
96106 // receives large vector of unbinned residuals and fills the sector-wise vectors
97107 // with binned residuals and statistics
98108 LOG (debug) << " Filling ResidualsContainer with vector of size " << data.size ();
109+ uint32_t nResidualsInTF = 0 ;
99110 for (const auto & residIn : data) {
100111 int sec = residIn.sec ;
101112 auto & residVecOut = residuals[sec];
@@ -117,11 +128,15 @@ void ResidualsContainer::fill(const o2::dataformats::TFIDInfo& ti, const gsl::sp
117128 stat.meanPos [TrackResiduals::VoxF] = (stat.meanPos [TrackResiduals::VoxF] * oldEntries + yPos / param::RowX[residIn.row ]) * norm;
118129 stat.meanPos [TrackResiduals::VoxZ] = (stat.meanPos [TrackResiduals::VoxZ] * oldEntries + zPos / param::RowX[residIn.row ]) * norm;
119130 ++nResidualsTotal;
131+ ++nResidualsInTF;
120132 }
121133 treeOutResiduals->Fill ();
122134 for (auto & residVecOut : residuals) {
123135 residVecOut.clear ();
124136 }
137+ runNumber = ti.runNumber ;
138+ tfOrbits.push_back (ti.firstTForbit );
139+ sumOfResiduals.push_back (nResidualsInTF);
125140}
126141
127142void ResidualsContainer::merge (ResidualsContainer* prev)
@@ -158,6 +173,13 @@ void ResidualsContainer::merge(ResidualsContainer* prev)
158173 treeOutResiduals = std::move (prev->treeOutResiduals );
159174
160175 nResidualsTotal += prev->nResidualsTotal ;
176+
177+ // append the current vector to the vector of the previous container and afterwards swap them,
178+ // since the vector of the previous container will be deleted
179+ prev->tfOrbits .insert (prev->tfOrbits .end (), tfOrbits.begin (), tfOrbits.end ());
180+ std::swap (prev->tfOrbits , tfOrbits);
181+ prev->sumOfResiduals .insert (prev->sumOfResiduals .end (), sumOfResiduals.begin (), sumOfResiduals.end ());
182+ std::swap (prev->sumOfResiduals , sumOfResiduals);
161183}
162184
163185void ResidualsContainer::print ()
@@ -195,15 +217,41 @@ void ResidualAggregator::finalizeSlot(Slot& slot)
195217 cont->treeOutResiduals .reset ();
196218 cont->treeOutStats ->Write ();
197219 cont->treeOutStats .reset ();
220+ cont->treeOutRecords ->Write ();
221+ cont->treeOutRecords .reset ();
198222 cont->fileOut ->Close ();
199223 cont->fileOut .reset ();
224+ std::filesystem::rename (o2::utils::Str::concat_string (mOutputDir , cont->fileName , " .part" ), mOutputDir + cont->fileName );
225+ if (mStoreMetaData ) {
226+ o2::dataformats::FileMetaData fileMetaData; // object with information for meta data file
227+ fileMetaData.fillFileData (mOutputDir + cont->fileName );
228+ fileMetaData.run = cont->runNumber ;
229+ fileMetaData.LHCPeriod = mLHCPeriod ;
230+ fileMetaData.type = " calib" ;
231+ fileMetaData.priority = " high" ;
232+ auto metaFileNameTmp = fmt::format (" {}{}.tmp" , mMetaOutputDir , cont->fileName );
233+ auto metaFileName = fmt::format (" {}{}.done" , mMetaOutputDir , cont->fileName );
234+ try {
235+ std::ofstream metaFileOut (metaFileNameTmp);
236+ metaFileOut << fileMetaData;
237+ metaFileOut << " TFOrbits: " ;
238+ for (size_t i = 0 ; i < cont->tfOrbits .size (); i++) {
239+ metaFileOut << fmt::format (" {}{}" , i ? " , " : " " , cont->tfOrbits [i]);
240+ }
241+ metaFileOut << ' \n ' ;
242+ metaFileOut.close ();
243+ std::filesystem::rename (metaFileNameTmp, metaFileName);
244+ } catch (std::exception const & e) {
245+ LOG (error) << " Failed to store residuals meta data file " << metaFileName << " , reason: " << e.what ();
246+ }
247+ }
200248}
201249
202250Slot& ResidualAggregator::emplaceNewSlot (bool front, TFType tStart, TFType tEnd)
203251{
204252 auto & cont = getSlots ();
205253 auto & slot = front ? cont.emplace_front (tStart, tEnd) : cont.emplace_back (tStart, tEnd);
206254 slot.setContainer (std::make_unique<ResidualsContainer>());
207- slot.getContainer ()->init (&mTrackResiduals );
255+ slot.getContainer ()->init (&mTrackResiduals , mOutputDir );
208256 return slot;
209257}
0 commit comments