Skip to content

Commit 82afc52

Browse files
committed
CTFWriter skips detector storage if an empty CTF container is passed
In case of direct ctf filtering as o2-ctf-reader-workflow ... --onlyDet <dets> --allow-missing-detectors | o2-ctf-writer-workflow ... --onlyDet <dets> the writer would get an empty CTF pointer if the requested detector was missing in the original CTF. With this patch, the writing of new CTF for such detector will be skipped, provided this detector did not send non-empty data for previous events. Otherwise an exception will be thrown to avoid misalignment between different CTF branches. The same happens if non-empty CTF data is supplied after null data in the previous TF.
1 parent 528bea3 commit 82afc52

2 files changed

Lines changed: 52 additions & 36 deletions

File tree

DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/EncodedBlocks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,7 @@ void EncodedBlocks<H, N, W>::clear()
695695
template <typename H, int N, typename W>
696696
auto EncodedBlocks<H, N, W>::getImage(const void* newHead)
697697
{
698+
assert(newHead);
698699
auto image(*get(newHead)); // 1st make a shalow copy
699700
// now fix its pointers
700701
// we don't modify newHead, but still need to remove constness for relocation interface

Detectors/CTF/workflow/src/CTFWriterSpec.cxx

Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -283,54 +283,69 @@ void CTFWriterSpec::updateTimeDependentParams(ProcessingContext& pc)
283283
template <typename C>
284284
size_t CTFWriterSpec::processDet(o2::framework::ProcessingContext& pc, DetID det, CTFHeader& header, TTree* tree)
285285
{
286+
static bool warnedEmpty = false;
286287
size_t sz = 0;
287288
if (!isPresent(det) || !pc.inputs().isValid(det.getName())) {
288289
mSizeReport += fmt::format(" {}:N/A", det.getName());
289290
return sz;
290291
}
291292
auto ctfBuffer = pc.inputs().get<gsl::span<o2::ctf::BufferType>>(det.getName());
292-
const auto ctfImage = C::getImage(ctfBuffer.data());
293-
ctfImage.print(o2::utils::Str::concat_string(det.getName(), ": "), mVerbosity);
294-
if (mWriteCTF && !mRejectCurrentTF) {
295-
sz = ctfImage.appendToTree(*tree, det.getName());
296-
header.detectors.set(det);
297-
} else {
298-
sz = ctfBuffer.size();
299-
}
300-
if (mCreateDict) {
301-
if (!mFreqsAccumulation[det].size()) {
302-
mFreqsAccumulation[det].resize(C::getNBlocks());
303-
mFreqsMetaData[det].resize(C::getNBlocks());
293+
const o2::ctf::BufferType* bdata = ctfBuffer.data();
294+
if (bdata) {
295+
if (warnedEmpty) {
296+
throw std::runtime_error(fmt::format("Non-empty input was seen at {}-th TF after empty one for {}, this will lead misalignment of detectors in CTF", mNCTF, det.getName()));
304297
}
305-
if (!mHeaders[det]) { // store 1st header
306-
mHeaders[det] = ctfImage.cloneHeader();
307-
auto& hb = *static_cast<o2::ctf::CTFDictHeader*>(mHeaders[det].get());
308-
hb.det = det;
298+
const auto ctfImage = C::getImage(bdata);
299+
ctfImage.print(o2::utils::Str::concat_string(det.getName(), ": "), mVerbosity);
300+
if (mWriteCTF && !mRejectCurrentTF) {
301+
sz = ctfImage.appendToTree(*tree, det.getName());
302+
header.detectors.set(det);
303+
} else {
304+
sz = ctfBuffer.size();
309305
}
310-
for (int ib = 0; ib < C::getNBlocks(); ib++) {
311-
if (!mIsSaturatedFrequencyTable[det][ib]) {
312-
const auto& bl = ctfImage.getBlock(ib);
313-
if (bl.getNDict()) {
314-
auto freq = mFreqsAccumulation[det][ib];
315-
auto& mdSave = mFreqsMetaData[det][ib];
316-
const auto& md = ctfImage.getMetadata(ib);
317-
if ([&, this]() {
318-
try {
319-
freq.addFrequencies(bl.getDict(), bl.getDict() + bl.getNDict(), md.min);
320-
} catch (const std::overflow_error& e) {
321-
LOGP(warning, "unable to frequency table for {}, block {} due to overflow", det.getName(), ib);
322-
mIsSaturatedFrequencyTable[det][ib] = true;
323-
return false;
324-
}
325-
return true;
326-
}()) {
327-
auto newProbBits = static_cast<uint8_t>(o2::rans::computeRenormingPrecision(freq));
328-
mdSave = o2::ctf::Metadata{0, 0, md.messageWordSize, md.coderType, md.streamSize, newProbBits, md.opt, freq.getMinSymbol(), freq.getMaxSymbol(), static_cast<int32_t>(freq.size()), 0, 0};
329-
mFreqsAccumulation[det][ib] = std::move(freq);
306+
if (mCreateDict) {
307+
if (!mFreqsAccumulation[det].size()) {
308+
mFreqsAccumulation[det].resize(C::getNBlocks());
309+
mFreqsMetaData[det].resize(C::getNBlocks());
310+
}
311+
if (!mHeaders[det]) { // store 1st header
312+
mHeaders[det] = ctfImage.cloneHeader();
313+
auto& hb = *static_cast<o2::ctf::CTFDictHeader*>(mHeaders[det].get());
314+
hb.det = det;
315+
}
316+
for (int ib = 0; ib < C::getNBlocks(); ib++) {
317+
if (!mIsSaturatedFrequencyTable[det][ib]) {
318+
const auto& bl = ctfImage.getBlock(ib);
319+
if (bl.getNDict()) {
320+
auto freq = mFreqsAccumulation[det][ib];
321+
auto& mdSave = mFreqsMetaData[det][ib];
322+
const auto& md = ctfImage.getMetadata(ib);
323+
if ([&, this]() {
324+
try {
325+
freq.addFrequencies(bl.getDict(), bl.getDict() + bl.getNDict(), md.min);
326+
} catch (const std::overflow_error& e) {
327+
LOGP(warning, "unable to frequency table for {}, block {} due to overflow", det.getName(), ib);
328+
mIsSaturatedFrequencyTable[det][ib] = true;
329+
return false;
330+
}
331+
return true;
332+
}()) {
333+
auto newProbBits = static_cast<uint8_t>(o2::rans::computeRenormingPrecision(freq));
334+
mdSave = o2::ctf::Metadata{0, 0, md.messageWordSize, md.coderType, md.streamSize, newProbBits, md.opt, freq.getMinSymbol(), freq.getMaxSymbol(), static_cast<int32_t>(freq.size()), 0, 0};
335+
mFreqsAccumulation[det][ib] = std::move(freq);
336+
}
330337
}
331338
}
332339
}
333340
}
341+
} else {
342+
if (!warnedEmpty) {
343+
if (mNCTF) {
344+
throw std::runtime_error(fmt::format("Empty input was seen at {}-th TF after non-empty one for {}, this will lead misalignment of detectors in CTF", mNCTF, det.getName()));
345+
}
346+
LOGP(important, "Empty CTF provided for {}, skipping and will not report anymore", det.getName());
347+
warnedEmpty = true;
348+
}
334349
}
335350
mSizeReport += fmt::format(" {}:{}", det.getName(), fmt::group_digits(sz));
336351
return sz;

0 commit comments

Comments
 (0)