Skip to content

Commit 6eef71a

Browse files
committed
ctf-reader can optionally inject only selected CTF IDs from input (multi-ctf) files
1 parent a65fcd4 commit 6eef71a

File tree

4 files changed

+41
-13
lines changed

4 files changed

+41
-13
lines changed

Detectors/CTF/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ There is a possibility to read remote root files directly, w/o caching them loca
111111
2) provide proper regex to define remote files, e.g. for the example above: `--remote-regex "^root://.+/eos/aliceo2/.+"`.
112112
3) pass an option `--copy-cmd no-copy`.
113113

114+
```
115+
--select-ctf-ids <id's of CTFs to select>
116+
```
117+
This is a `ctf-reader` device local option allowing selective reading of particular CTFs. It is useful when dealing with CTF files containing multiple TFs. The comma-separated list of increasing CTFs indices must be provided in the format parsed by the `RangeTokenizer<int>`, e.g. `1,4-6,...`.
118+
Note that the index corresponds not to the entry of the TF in the CTF tree but to the reader own counter incremented throught all input files (e.g. if the 10 CTF files with 20 TFs each are provided for the input and the selection of TFs
119+
`0,2,22,66` is provided, the reader will inject to the DPL the TFs at entries 0 and 2 from the 1st CTF file, entry 5 of the second file, entry 6 of the 3d and will finish the job.
120+
114121
For the ITS and MFT entropy decoding one can request either to decompose clusters to digits and send them instead of clusters (via `o2-ctf-reader-workflow` global options `--its-digits` and `--mft-digits` respectively)
115122
or to apply the noise mask to decoded clusters (or decoded digits). If the masking (e.g. via option `--its-entropy-decoder " --mask-noise "`) is requested, user should provide to the entropy decoder the noise mask file (eventually will be loaded from CCDB) and cluster patterns decoding dictionary (if the clusters were encoded with patterns IDs).
116123
For example,

Detectors/CTF/workflow/include/CTFWorkflow/CTFReaderSpec.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ struct CTFReaderInp {
2929
std::string copyCmd{};
3030
std::string tffileRegex{};
3131
std::string remoteRegex{};
32+
std::vector<int> ctfIDs{};
3233
int maxFileCache = 1;
3334
int64_t delay_us = 0;
3435
int maxLoops = 0;

Detectors/CTF/workflow/src/CTFReaderSpec.cxx

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class CTFReaderSpec : public o2::framework::Task
7777
private:
7878
void openCTFFile(const std::string& flname);
7979
void processTF(ProcessingContext& pc);
80+
void checkTreeEntries();
8081
void stop();
8182
CTFReaderInp mInput{};
8283
std::unique_ptr<o2::utils::FileFetcher> mFileFetcher;
@@ -86,6 +87,7 @@ class CTFReaderSpec : public o2::framework::Task
8687
int mCTFCounter = 0;
8788
long mLastSendTime = 0L;
8889
long mCurrTreeEntry = 0;
90+
size_t mSelIDEntry = 0; // next CTFID to select from the mInput.ctfIDs (if non-empty)
8991
TStopwatch mTimer;
9092
};
9193

@@ -124,6 +126,7 @@ void CTFReaderSpec::stop()
124126
///_______________________________________
125127
void CTFReaderSpec::init(InitContext& ic)
126128
{
129+
mInput.ctfIDs = o2::RangeTokenizer::tokenize<int>(ic.options().get<std::string>("select-ctf-ids"));
127130
mRunning = true;
128131
mFileFetcher = std::make_unique<o2::utils::FileFetcher>(mInput.inpdata, mInput.tffileRegex, mInput.remoteRegex, mInput.copyCmd);
129132
mFileFetcher->setMaxFilesInQueue(mInput.maxFileCache);
@@ -150,15 +153,24 @@ void CTFReaderSpec::openCTFFile(const std::string& flname)
150153
void CTFReaderSpec::run(ProcessingContext& pc)
151154
{
152155
std::string tfFileName;
153-
if (mCTFCounter >= mInput.maxTFs) { // done
156+
if (mCTFCounter >= mInput.maxTFs || (!mInput.ctfIDs.empty() && mSelIDEntry >= mInput.ctfIDs.size())) { // done
157+
LOG(INFO) << "All CTFs from selected range were injected, stopping";
154158
mRunning = false;
155159
}
156160

157161
while (mRunning) {
158162
if (mCTFTree) { // there is a tree open with multiple CTF
159-
LOG(INFO) << "TF " << mCTFCounter << " of " << mInput.maxTFs << " loop " << mFileFetcher->getNLoops();
160-
processTF(pc);
161-
break;
163+
if (mInput.ctfIDs.empty() || mInput.ctfIDs[mSelIDEntry] == mCTFCounter) { // no selection requested or matching CTF ID is found
164+
LOG(DEBUG) << "TF " << mCTFCounter << " of " << mInput.maxTFs << " loop " << mFileFetcher->getNLoops();
165+
mSelIDEntry++;
166+
processTF(pc);
167+
break;
168+
} else { // explict CTF ID selection list was provided and current entry is not selected
169+
LOGP(INFO, "Skipping CTF${} ({} of {} in {})", mCTFCounter, mCurrTreeEntry, mCTFTree->GetEntries(), mCTFFile->GetName());
170+
checkTreeEntries();
171+
mCTFCounter++;
172+
continue;
173+
}
162174
}
163175
//
164176
tfFileName = mFileFetcher->getNextFileInQueue();
@@ -322,14 +334,7 @@ void CTFReaderSpec::processTF(ProcessingContext& pc)
322334
}
323335

324336
auto entryStr = fmt::format("({} of {} in {})", mCurrTreeEntry, mCTFTree->GetEntries(), mCTFFile->GetName());
325-
if (++mCurrTreeEntry >= mCTFTree->GetEntries()) { // this file is done, check if there are other files
326-
mCTFTree.reset();
327-
mCTFFile->Close();
328-
mCTFFile.reset();
329-
if (mFileFetcher) {
330-
mFileFetcher->popFromQueue(mFileFetcher->getNLoops() >= mInput.maxLoops);
331-
}
332-
}
337+
checkTreeEntries();
333338
mTimer.Stop();
334339
// do we need to way to respect the delay ?
335340
long tNow = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
@@ -347,6 +352,20 @@ void CTFReaderSpec::processTF(ProcessingContext& pc)
347352
mCTFCounter++;
348353
}
349354

355+
///_______________________________________
356+
void CTFReaderSpec::checkTreeEntries()
357+
{
358+
// check if the tree has entries left, if needed, close current tree/file
359+
if (++mCurrTreeEntry >= mCTFTree->GetEntries()) { // this file is done, check if there are other files
360+
mCTFTree.reset();
361+
mCTFFile->Close();
362+
mCTFFile.reset();
363+
if (mFileFetcher) {
364+
mFileFetcher->popFromQueue(mFileFetcher->getNLoops() >= mInput.maxLoops);
365+
}
366+
}
367+
}
368+
350369
///_______________________________________
351370
DataProcessorSpec getCTFReaderSpec(const CTFReaderInp& inp)
352371
{
@@ -364,7 +383,7 @@ DataProcessorSpec getCTFReaderSpec(const CTFReaderInp& inp)
364383
Inputs{},
365384
outputs,
366385
AlgorithmSpec{adaptFromTask<CTFReaderSpec>(inp)},
367-
Options{}};
386+
Options{{"select-ctf-ids", VariantType::String, "", {"comma-separated list CTF IDs to inject (from cumulative counter of CTFs seen)"}}}};
368387
}
369388

370389
} // namespace ctf

Detectors/CTF/workflow/src/ctf-reader-workflow.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "DataFormatsParameters/GRPObject.h"
2121
#include "DetectorsCommonDataFormats/DetID.h"
2222
#include "CommonUtils/ConfigurableParam.h"
23+
#include "Algorithm/RangeTokenizer.h"
2324

2425
// Specific detectors specs
2526
#include "ITSMFTWorkflow/EntropyDecoderSpec.h"

0 commit comments

Comments
 (0)