Skip to content

Commit 87ed312

Browse files
matthias-kleinershahor02
authored andcommitted
TPC ICCs/IDCs: fixing completion policy for ICCs
- adding check for zero - add option to write large IDCFactorization objects to disc - process IDCs when end of stream - store meta data in IDCFactorization - Properly access CCDB objects in case they are not received at the same time
1 parent ad233fc commit 87ed312

7 files changed

Lines changed: 218 additions & 59 deletions

File tree

Detectors/TPC/calibration/include/TPCCalibration/IDCFactorization.h

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ namespace o2::tpc
3131
template <class T>
3232
class CalDet;
3333

34+
struct IDCFactorizeSplit {
35+
std::array<std::vector<float>, CRU::MaxCRU> idcs{};
36+
int relTF{};
37+
ClassDefNV(IDCFactorizeSplit, 1)
38+
};
39+
3440
class IDCFactorization : public IDCGroupHelperSector
3541
{
3642
public:
@@ -193,6 +199,18 @@ class IDCFactorization : public IDCGroupHelperSector
193199
/// \return returns vector of processed CRUs
194200
auto getCRUs() const { return mCRUs; }
195201

202+
/// \param timeStamp time stamp of the first aggregated IDCs
203+
void setTimeStamp(const long timeStamp) { mTimeStamp = timeStamp; }
204+
205+
/// \return returns time stamp of the first aggregated IDCs
206+
long getTimeStamp() const { return mTimeStamp; }
207+
208+
/// \param run of the aggregated IDCs
209+
void setRun(const int run) { mRun = run; }
210+
211+
/// \return returns run of the IDCs
212+
int getRun() const { return mRun; }
213+
196214
// get number of TFs in which the DeltaIDCs are split/stored
197215
unsigned int getTimeFramesDeltaIDC() const { return mTimeFramesDeltaIDC; }
198216

@@ -272,6 +290,17 @@ class IDCFactorization : public IDCGroupHelperSector
272290
/// \param outName name of the object in the output file
273291
void dumpToFile(const char* outFileName = "IDCFactorized.root", const char* outName = "IDCFactorized") const;
274292

293+
/// dump large object to disc which exceeds the maximum size of 1GB for an object in a ROOT file
294+
/// \param outFileName name of the output file
295+
/// \param outName name of the object in the output file
296+
void dumpLargeObjectToFile(const char* outFileName = "IDCFactorized.root", const char* outName = "IDCFactorized") const;
297+
298+
/// read in an object which was created with dumpLargeObjectToFile
299+
/// \param inpFileName name of the output file
300+
/// \param inName name of the object in the output file
301+
/// \return returns the stored object
302+
static std::unique_ptr<IDCFactorization> getLargeObjectFromFile(const char* inpFileName = "IDCFactorized.root", const char* inName = "IDCFactorized");
303+
275304
/// dump the IDC0 to file
276305
void dumpIDCZeroToFile(const Side side, const char* outFileName = "IDCZero.root", const char* outName = "IDC0") const;
277306

@@ -282,6 +311,11 @@ class IDCFactorization : public IDCGroupHelperSector
282311
/// \param outFileName name of the output file
283312
void dumpToTree(int integrationIntervals = -1, const char* outFileName = "IDCTree.root") const;
284313

314+
/// dumping the IDC1 to a TTree including the timestamps (the start time stamp in ms should be set with setTimeStamp())
315+
/// \param integrationTimeOrbits integration time in orbits
316+
/// \param outFileName name of the output file
317+
void dumpToTreeIDC1(const float integrationTimeOrbits = 12, const char* outFileName = "IDC1Tree.root") const;
318+
285319
/// \returns vector containing the number of integration intervals for each stored TF (dropped TFs not taken into account)
286320
/// \param cru cru which is used for the lookup (cru=-1: automatic cru lookup)
287321
std::vector<unsigned int> getIntegrationIntervalsPerTF(const int cru = -1) const;
@@ -350,6 +384,8 @@ class IDCFactorization : public IDCGroupHelperSector
350384
std::array<unsigned int, SIDES> mSideIndex{0, 1}; ///< index to mIDCZero, mIDCOne and mIDCDelta for TPC side
351385
std::vector<Side> mSides{}; ///< processed TPC sides
352386
std::vector<unsigned int> mIntegrationIntervalsPerTF{}; ///< storage of integration intervals per TF (taken dropped TFs into account)
387+
long mTimeStamp{0}; ///< first time stamp of IDCs
388+
int mRun{0}; ///< run number of IDCs
353389

354390
/// helper function for drawing IDCDelta
355391
void drawIDCDeltaHelper(const bool type, const Sector sector, const unsigned int integrationInterval, const IDCDeltaCompression compression, const std::string filename, const float minZ, const float maxZ) const;
@@ -372,7 +408,7 @@ class IDCFactorization : public IDCGroupHelperSector
372408
/// helper function for drawing
373409
void drawPadFlagMap(const bool type, const Sector sector, const std::string filename, const PadFlags flag) const;
374410

375-
ClassDefNV(IDCFactorization, 1)
411+
ClassDefNV(IDCFactorization, 2)
376412
};
377413

378414
} // namespace o2::tpc

Detectors/TPC/calibration/src/IDCFactorization.cxx

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "TPCBase/CalDet.h"
1919
#include <functional>
2020
#include "MemoryResources/MemoryResources.h"
21+
#include "CommonConstants/LHCConstants.h"
22+
#include "TKey.h"
2123

2224
#if (defined(WITH_OPENMP) || defined(_OPENMP))
2325
#include <omp.h>
@@ -76,6 +78,62 @@ void o2::tpc::IDCFactorization::dumpToFile(const char* outFileName, const char*
7678
fOut.Close();
7779
}
7880

81+
void o2::tpc::IDCFactorization::dumpLargeObjectToFile(const char* outFileName, const char* outName) const
82+
{
83+
TFile fOut(outFileName, "RECREATE");
84+
for (int iTF = 0; iTF < mTimeFrames; ++iTF) {
85+
IDCFactorizeSplit idcTmp;
86+
idcTmp.relTF = iTF;
87+
for (int icru = 0; icru < CRU::MaxCRU; ++icru) {
88+
idcTmp.idcs[icru] = mIDCs[icru][iTF];
89+
}
90+
fOut.WriteObject(&idcTmp, fmt::format("IDCs_TF{}", iTF).data());
91+
}
92+
93+
// write empty dummy object to file which can be filled with the previously written IDCs
94+
IDCFactorization idcFacTmp(mTimeFrames, mTimeFramesDeltaIDC, mCRUs);
95+
idcFacTmp.setRun(getRun());
96+
idcFacTmp.setTimeStamp(getTimeStamp());
97+
fOut.WriteObject(&idcFacTmp, outName);
98+
fOut.Close();
99+
}
100+
101+
std::unique_ptr<o2::tpc::IDCFactorization> o2::tpc::IDCFactorization::getLargeObjectFromFile(const char* inpFileName, const char* inName)
102+
{
103+
TFile fInp(inpFileName, "READ");
104+
o2::tpc::IDCFactorization* idcTmp = (o2::tpc::IDCFactorization*)fInp.Get(inName);
105+
std::unique_ptr<IDCFactorization> idc = std::make_unique<IDCFactorization>(idcTmp->getNTimeframes(), idcTmp->getTimeFramesDeltaIDC(), idcTmp->getCRUs());
106+
idc->setRun(idcTmp->getRun());
107+
idc->setTimeStamp(idcTmp->getTimeStamp());
108+
delete idcTmp;
109+
110+
for (TObject* keyAsObj : *fInp.GetListOfKeys()) {
111+
const auto key = dynamic_cast<TKey*>(keyAsObj);
112+
LOGP(info, "Key name: {} Type: {}", key->GetName(), key->GetClassName());
113+
114+
if (std::strcmp(o2::tpc::IDCFactorizeSplit::Class()->GetName(), key->GetClassName()) != 0) {
115+
if (std::strcmp(o2::tpc::IDCFactorization::Class()->GetName(), key->GetClassName()) != 0) {
116+
LOGP(info, "skipping object. wrong class.");
117+
}
118+
continue;
119+
}
120+
121+
IDCFactorizeSplit* idcTmp = (IDCFactorizeSplit*)fInp.Get(key->GetName());
122+
const int relTF = idcTmp->relTF;
123+
if (relTF >= idc->getNTimeframes()) {
124+
LOGP(warning, "stored TF {} is larger than max TF {}", relTF, idc->getNTimeframes());
125+
continue;
126+
}
127+
for (int icru = 0; icru < CRU::MaxCRU; ++icru) {
128+
auto idcVec = idcTmp->idcs[icru];
129+
idc->setIDCs(std::move(idcVec), icru, relTF);
130+
}
131+
delete idcTmp;
132+
}
133+
fInp.Close();
134+
return idc;
135+
}
136+
79137
void o2::tpc::IDCFactorization::dumpIDCZeroToFile(const Side side, const char* outFileName, const char* outName) const
80138
{
81139
TFile fOut(outFileName, "RECREATE");
@@ -184,6 +242,27 @@ void o2::tpc::IDCFactorization::dumpToTree(int integrationIntervals, const char*
184242
pcstream.Close();
185243
}
186244

245+
void o2::tpc::IDCFactorization::dumpToTreeIDC1(const float integrationTimeOrbits, const char* outFileName) const
246+
{
247+
o2::utils::TreeStreamRedirector pcstream(outFileName, "RECREATE");
248+
pcstream.GetFile()->cd();
249+
std::vector<float> idcOneA = getIDCOneVec(Side::A);
250+
std::vector<float> idcOneC = getIDCOneVec(Side::C);
251+
std::vector<double> timestamp;
252+
253+
for (int i = 0; i < idcOneA.size(); ++i) {
254+
timestamp.emplace_back((mTimeStamp + i * integrationTimeOrbits * o2::constants::lhc::LHCOrbitMUS * 0.001) / 1000);
255+
}
256+
257+
pcstream << "tree"
258+
<< "IDC1A=" << idcOneA
259+
<< "IDC1C=" << idcOneC
260+
<< "timestamp=" << timestamp
261+
<< "\n";
262+
263+
pcstream.Close();
264+
}
265+
187266
void o2::tpc::IDCFactorization::calcIDCZero(const bool norm)
188267
{
189268
const unsigned int nIDCsSide = mNIDCsPerSector * o2::tpc::SECTORSPERSIDE;

Detectors/TPC/calibration/src/TPCCalibrationLinkDef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#pragma link C++ class o2::tpc::IDCAverageGroupBase < o2::tpc::IDCAverageGroupCRU> + ;
4646
#pragma link C++ class o2::tpc::IDCAverageGroupBase < o2::tpc::IDCAverageGroupTPC> + ;
4747
#pragma link C++ class o2::tpc::IDCFactorization + ;
48+
#pragma link C++ class o2::tpc::IDCFactorizeSplit + ;
4849
#pragma link C++ class o2::tpc::SACFactorization + ;
4950
#pragma link C++ struct o2::tpc::IDCDelta < float> + ;
5051
#pragma link C++ struct o2::tpc::IDCDelta < unsigned short> + ;

Detectors/TPC/workflow/include/TPCWorkflow/TPCDistributeIDCSpec.h

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class TPCDistributeIDCSpec : public o2::framework::Task
4444
{
4545
public:
4646
TPCDistributeIDCSpec(const std::vector<uint32_t>& crus, const unsigned int timeframes, const int nTFsBuffer, const unsigned int outlanes, const int firstTF, std::shared_ptr<o2::base::GRPGeomRequest> req, const bool processClusters)
47-
: mCRUs{crus}, mTimeFrames{timeframes}, mNTFsBuffer{nTFsBuffer}, mOutLanes{outlanes}, mProcessedCRU{{std::vector<unsigned int>(timeframes), std::vector<unsigned int>(timeframes)}}, mTFStart{{firstTF, firstTF + timeframes}}, mTFEnd{{firstTF + timeframes - 1, mTFStart[1] + timeframes - 1}}, mCCDBRequest(req), mSendCCDBOutput(outlanes), mProcessClusters{processClusters}
47+
: mCRUs{crus}, mTimeFrames{timeframes}, mNTFsBuffer{nTFsBuffer}, mOutLanes{outlanes}, mProcessedCRU{{std::vector<unsigned int>(timeframes), std::vector<unsigned int>(timeframes)}}, mTFStart{{firstTF, firstTF + timeframes}}, mTFEnd{{firstTF + timeframes - 1, mTFStart[1] + timeframes - 1}}, mCCDBRequest(req), mSendCCDBOutputOrbitReset(outlanes), mSendCCDBOutputGRPECS(outlanes), mProcessClusters{processClusters}
4848
{
4949
// pre calculate data description for output
5050
mDataDescrOut.reserve(mOutLanes);
@@ -84,27 +84,39 @@ class TPCDistributeIDCSpec : public o2::framework::Task
8484
mCheckEveryNData = ic.options().get<int>("check-data-every-n");
8585
if (mCheckEveryNData == 0) {
8686
mCheckEveryNData = mTimeFrames / 2;
87+
if (mCheckEveryNData == 0) {
88+
mCheckEveryNData = 1;
89+
}
8790
mNTFsDataDrop = mCheckEveryNData;
8891
}
8992
}
9093

9194
void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) final
9295
{
93-
// send data only when object are updated
94-
if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) {
95-
std::fill(mSendCCDBOutput.begin(), mSendCCDBOutput.end(), true);
96+
o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj);
97+
if (matcher == ConcreteDataMatcher("CTP", "ORBITRESET", 0)) {
98+
LOGP(info, "Updating ORBITRESET");
99+
std::fill(mSendCCDBOutputOrbitReset.begin(), mSendCCDBOutputOrbitReset.end(), true);
100+
} else if (matcher == ConcreteDataMatcher("GLO", "GRPECS", 0)) {
101+
LOGP(info, "Updating GRPECS");
102+
std::fill(mSendCCDBOutputGRPECS.begin(), mSendCCDBOutputGRPECS.end(), true);
96103
}
97104
}
98105

99106
void run(o2::framework::ProcessingContext& pc) final
100107
{
101108
// send orbit reset and orbits per TF only once
102109
if (mCCDBRequest->askTime) {
103-
if (pc.inputs().isValid("grpecs") && pc.inputs().isValid("orbitReset")) {
104-
o2::base::GRPGeomHelper::instance().checkUpdates(pc);
105-
if (pc.inputs().countValidInputs() == 2) {
106-
return;
107-
}
110+
const bool grpecsValid = pc.inputs().isValid("grpecs");
111+
const bool orbitResetValid = pc.inputs().isValid("orbitReset");
112+
if (grpecsValid) {
113+
pc.inputs().get<o2::parameters::GRPECSObject*>("grpecs");
114+
}
115+
if (orbitResetValid) {
116+
pc.inputs().get<std::vector<Long64_t>*>("orbitReset");
117+
}
118+
if (pc.inputs().countValidInputs() == (grpecsValid + orbitResetValid)) {
119+
return;
108120
}
109121
}
110122

@@ -151,8 +163,9 @@ class TPCDistributeIDCSpec : public o2::framework::Task
151163
pc.outputs().snapshot(Output{gDataOriginTPC, getDataDescriptionIDCFirstTF(), header::DataHeader::SubSpecificationType{currentOutLane}}, mTFStart[currentBuffer]);
152164
}
153165

154-
if (mSendCCDBOutput[currentOutLane]) {
155-
mSendCCDBOutput[currentOutLane] = false;
166+
if (mSendCCDBOutputOrbitReset[currentOutLane] && mSendCCDBOutputGRPECS[currentOutLane]) {
167+
mSendCCDBOutputOrbitReset[currentOutLane] = false;
168+
mSendCCDBOutputGRPECS[currentOutLane] = false;
156169
pc.outputs().snapshot(Output{gDataOriginTPC, getDataDescriptionIDCOrbitReset(), header::DataHeader::SubSpecificationType{currentOutLane}}, dataformats::Pair<long, int>{o2::base::GRPGeomHelper::instance().getOrbitResetTimeMS(), o2::base::GRPGeomHelper::instance().getNHBFPerTF()});
157170
}
158171

@@ -222,7 +235,8 @@ class TPCDistributeIDCSpec : public o2::framework::Task
222235
std::array<long, 2> mTFEnd{}; ///< storing of last TF for buffer interval
223236
std::array<bool, 2> mSendOutputStartInfo{true, true}; ///< flag for sending the info for the start of the aggregation interval
224237
std::shared_ptr<o2::base::GRPGeomRequest> mCCDBRequest; ///< info for CCDB request
225-
std::vector<bool> mSendCCDBOutput{}; ///< flag for sending CCDB output
238+
std::vector<bool> mSendCCDBOutputOrbitReset{}; ///< flag for received orbit reset time from CCDB
239+
std::vector<bool> mSendCCDBOutputGRPECS{}; ///< flag for received orbit GRPECS from CCDB
226240
const bool mProcessClusters{false}; ///< processing ICCs instead of IDCs
227241
unsigned int mCurrentOutLane{0}; ///< index for keeping track of the current output lane
228242
bool mBuffer{false}; ///< buffer index

0 commit comments

Comments
 (0)