Skip to content

Commit 170c96e

Browse files
committed
Auto-detect CTF dictionary type (tree vs binary)
1 parent 37b86df commit 170c96e

2 files changed

Lines changed: 63 additions & 20 deletions

File tree

Detectors/Base/include/DetectorsBase/CTFCoderBase.h

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,18 @@ class CTFCoderBase
119119
template <typename CTF>
120120
bool finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj);
121121

122-
void updateTimeDependentParams(o2::framework::ProcessingContext& pc);
122+
void updateTimeDependentParams(o2::framework::ProcessingContext& pc, bool askTree = false);
123123

124124
o2::utils::IRFrameSelector& getIRFramesSelector() { return mIRFrameSelector; }
125125
size_t getIRFrameSelMarginBwd() const { return mIRFrameSelMarginBwd; }
126126
size_t getIRFrameSelMarginFwd() const { return mIRFrameSelMarginFwd; }
127127

128128
protected:
129129
std::string getPrefix() const { return o2::utils::Str::concat_string(mDet.getName(), "_CTF: "); }
130-
131130
void checkDictVersion(const CTFDictHeader& h) const;
131+
bool isTreeDictionary(const void* buff) const;
132+
template <typename CTF>
133+
std::vector<char> loadDictionaryFromTree(TTree* tree);
132134
std::vector<std::shared_ptr<void>> mCoders; // encoders/decoders
133135
DetID mDet;
134136
CTFDictHeader mExtHeader; // external dictionary header
@@ -170,6 +172,18 @@ void CTFCoderBase::createCodersFromFile(const std::string& dictPath, o2::ctf::CT
170172
createCoders(buff, op);
171173
}
172174

175+
///________________________________
176+
template <typename CTF>
177+
std::vector<char> CTFCoderBase::loadDictionaryFromTree(TTree* tree)
178+
{
179+
std::vector<char> bufVec;
180+
CTFHeader ctfHeader;
181+
if (readFromTree(*tree, "CTFHeader", ctfHeader) && ctfHeader.detectors[mDet]) {
182+
CTF::readFromTree(bufVec, *tree, mDet.getName());
183+
}
184+
return bufVec;
185+
}
186+
173187
///________________________________
174188
template <typename CTF>
175189
std::vector<char> CTFCoderBase::readDictionaryFromFile(const std::string& dictPath, bool mayFail)
@@ -188,38 +202,33 @@ std::vector<char> CTFCoderBase::readDictionaryFromFile(const std::string& dictPa
188202
}
189203
return bufVec;
190204
}
191-
std::unique_ptr<TTree> tree((TTree*)fileDict->Get(std::string(o2::base::NameConf::CTFDICT).c_str()));
205+
std::unique_ptr<TTree> tree;
192206
std::unique_ptr<std::vector<char>> bv((std::vector<char>*)fileDict->GetObjectChecked(o2::base::NameConf::CCDBOBJECT.data(), "std::vector<char>"));
207+
tree.reset((TTree*)fileDict->GetObjectChecked(o2::base::NameConf::CTFDICT.data(), "TTree"));
208+
if (!tree) {
209+
tree.reset((TTree*)fileDict->GetObjectChecked(o2::base::NameConf::CCDBOBJECT.data(), "TTree"));
210+
}
193211
if (tree) {
194-
CTFHeader ctfHeader;
195-
if (!readFromTree(*tree.get(), "CTFHeader", ctfHeader) || !ctfHeader.detectors[mDet]) {
196-
std::string errstr = fmt::format("CTF dictionary file for detector {} is absent in the tree from file {}", mDet.getName(), dictPath);
197-
if (mayFail) {
198-
LOGP(info, "{}, will assume dictionary stored in CTF", errstr);
199-
} else {
200-
throw std::runtime_error(errstr);
201-
}
202-
return bufVec;
203-
}
204-
CTF::readFromTree(bufVec, *tree.get(), mDet.getName());
212+
auto v = loadDictionaryFromTree<CTF>(tree.get());
213+
bufVec.swap(v);
205214
} else if (bv) {
206215
bufVec.swap(*bv);
207216
if (bufVec.size()) {
208217
auto dictHeader = static_cast<const o2::ctf::CTFDictHeader&>(CTF::get(bufVec.data())->getHeader());
209218
if (dictHeader.det != mDet) {
210-
throw std::runtime_error(fmt::format("{} contains dictionary vector for {}, expected {}", dictPath, dictHeader.det.getName(), mDet.getName()));
219+
bufVec.clear();
220+
LOGP(error, "{} contains dictionary vector for {}, expected {}", dictPath, dictHeader.det.getName(), mDet.getName());
211221
}
212222
}
213223
}
214224
if (bufVec.size()) {
215225
mExtHeader = static_cast<CTFDictHeader&>(CTF::get(bufVec.data())->getHeader());
216226
LOGP(debug, "Found {} in {}", mExtHeader.asString(), dictPath);
217227
} else {
218-
std::string errstr = fmt::format("CTF dictionary file for detector {} is empty", mDet.getName());
219228
if (mayFail) {
220-
LOGP(info, "{}, will assume dictionary stored in CTF", errstr);
229+
LOGP(info, "{}, will assume dictionary stored in CTF", mDet.getName());
221230
} else {
222-
throw std::runtime_error(errstr);
231+
LOGP(fatal, "CTF dictionary file for detector {} is empty", mDet.getName());
223232
}
224233
}
225234
return bufVec;
@@ -273,6 +282,12 @@ bool CTFCoderBase::finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, voi
273282
if (dict->empty()) {
274283
LOGP(info, "Empty dictionary object fetched from CCDB, internal per-TF CTF Dict will be created");
275284
} else {
285+
std::vector<char> bufVec;
286+
if (isTreeDictionary(obj)) {
287+
auto v = loadDictionaryFromTree<CTF>(reinterpret_cast<TTree*>(obj));
288+
bufVec.swap(v);
289+
dict = &bufVec;
290+
}
276291
createCoders(*dict, mOpType);
277292
mExtHeader = static_cast<const CTFDictHeader&>(CTF::get(dict->data())->getHeader());
278293
LOGP(info, "Loaded {} from CCDB", mExtHeader.asString());

Detectors/Base/src/CTFCoderBase.cxx

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,37 @@ void CTFCoderBase::assignDictVersion(CTFDictHeader& h) const
4545
// }
4646
}
4747

48-
void CTFCoderBase::updateTimeDependentParams(ProcessingContext& pc)
48+
void CTFCoderBase::updateTimeDependentParams(ProcessingContext& pc, bool askTree)
4949
{
5050
if (mLoadDictFromCCDB) {
51-
pc.inputs().get<std::vector<char>*>("ctfdict"); // just to trigger the finaliseCCDB
51+
if (askTree) {
52+
pc.inputs().get<TTree*>("ctfdict"); // just to trigger the finaliseCCDB
53+
} else {
54+
pc.inputs().get<std::vector<char>*>("ctfdict"); // just to trigger the finaliseCCDB
55+
}
56+
}
57+
}
58+
59+
bool CTFCoderBase::isTreeDictionary(const void* buff) const
60+
{
61+
// heuristic check for the dictionary being a tree
62+
const char* patt[] = {"ccdb_object", "ctf_dictionary"};
63+
const char* ptr = reinterpret_cast<const char*>(buff);
64+
bool found = false;
65+
int i = 0, np = sizeof(patt) / sizeof(char*);
66+
while (i < 50 && !found) {
67+
for (int ip = 0; ip < np; ip++) {
68+
const auto *p = patt[ip], *s = &ptr[i];
69+
while (*p && *s == *p) {
70+
p++;
71+
s++;
72+
}
73+
if (!*p) {
74+
found = true;
75+
break;
76+
}
77+
}
78+
i++;
5279
}
80+
return found;
5381
}

0 commit comments

Comments
 (0)