2222#include " DetectorsCommonDataFormats/DetID.h"
2323#include " DetectorsCommonDataFormats/NameConf.h"
2424#include " DetectorsCommonDataFormats/CTFDictHeader.h"
25+ #include " DetectorsCommonDataFormats/CTFHeader.h"
2526#include " rANS/rans.h"
2627
2728namespace o2
@@ -43,24 +44,15 @@ class CTFCoderBase
4344
4445 CTFCoderBase () = delete ;
4546 CTFCoderBase (int n, DetID det, float memFactor = 1 .f) : mCoders (n), mDet (det), mMemMarginFactor (memFactor > 1 .f ? memFactor : 1 .f) {}
47+ virtual ~CTFCoderBase () = default ;
4648
47- std::unique_ptr<TFile> loadDictionaryTreeFile (const std::string& dictPath, bool mayFail = false ) ;
49+ virtual void createCoders (const std::vector< char >& bufVec, o2::ctf::CTFCoderBase::OpType op) = 0 ;
4850
4951 template <typename CTF>
50- std::vector<char > readDictionaryFromFile (const std::string& dictPath, bool mayFail = false )
51- {
52- std::vector<char > bufVec;
53- auto fileDict = loadDictionaryTreeFile (dictPath, mayFail);
54- if (fileDict) {
55- std::unique_ptr<TTree> tree ((TTree*)fileDict->Get (std::string (o2::base::NameConf::CTFDICT).c_str ()));
56- CTF::readFromTree (bufVec, *tree.get (), mDet .getName ());
57- if (bufVec.size ()) {
58- mExtHeader = static_cast <CTFDictHeader&>(CTF::get (bufVec.data ())->getHeader ());
59- LOGP (info, " Found {} {} in {}" , mDet .getName (), mExtHeader .asString (), dictPath);
60- }
61- }
62- return bufVec;
63- }
52+ std::vector<char > readDictionaryFromFile (const std::string& dictPath, bool mayFail = false );
53+
54+ template <typename CTF>
55+ void createCodersFromFile (const std::string& dictPath, o2::ctf::CTFCoderBase::OpType op);
6456
6557 template <typename S>
6658 void createCoder (OpType op, const o2::rans::FrequencyTable& freq, uint8_t probabilityBits, int slot)
@@ -92,6 +84,9 @@ class CTFCoderBase
9284 void setVerbosity (int v) { mVerbosity = v; }
9385 int getVerbosity () const { return mVerbosity ; }
9486
87+ template <typename T>
88+ static bool readFromTree (TTree& tree, const std::string brname, T& dest, int ev = 0 );
89+
9590 protected:
9691 std::string getPrefix () const { return o2::utils::Str::concat_string (mDet .getName (), " _CTF: " ); }
9792 void assignDictVersion (CTFDictHeader& h) const
@@ -100,17 +95,98 @@ class CTFCoderBase
10095 h = mExtHeader ;
10196 }
10297 }
98+
10399 void checkDictVersion (const CTFDictHeader& h) const ;
104100
105101 std::vector<std::shared_ptr<void >> mCoders ; // encoders/decoders
106102 DetID mDet ;
107103 CTFDictHeader mExtHeader ; // external dictionary header
108104 float mMemMarginFactor = 1 .0f ; // factor for memory allocation in EncodedBlocks
109105 int mVerbosity = 0 ;
110-
111- ClassDefNV (CTFCoderBase, 1 );
112106};
113107
108+ // /________________________________
109+ template <typename T>
110+ bool CTFCoderBase::readFromTree (TTree& tree, const std::string brname, T& dest, int ev)
111+ {
112+ auto * br = tree.GetBranch (brname.c_str ());
113+ if (br && br->GetEntries () > ev) {
114+ auto * ptr = &dest;
115+ br->SetAddress (&ptr);
116+ br->GetEntry (ev);
117+ br->ResetAddress ();
118+ return true ;
119+ }
120+ return false ;
121+ }
122+
123+ // /________________________________
124+ template <typename CTF>
125+ void CTFCoderBase::createCodersFromFile (const std::string& dictPath, o2::ctf::CTFCoderBase::OpType op)
126+ {
127+ bool mayFail = true ;
128+ auto buff = readDictionaryFromFile<CTF>(dictPath, mayFail);
129+ if (!buff.size ()) {
130+ if (mayFail) {
131+ return ;
132+ }
133+ throw std::runtime_error (" Failed to create CTF dictionaty" );
134+ }
135+ createCoders (buff, op);
136+ }
137+
138+ // /________________________________
139+ template <typename CTF>
140+ std::vector<char > CTFCoderBase::readDictionaryFromFile (const std::string& dictPath, bool mayFail)
141+ {
142+ std::vector<char > bufVec;
143+ std::unique_ptr<TFile> fileDict (TFile::Open (dictPath.c_str ()));
144+ if (!fileDict || fileDict->IsZombie ()) {
145+ std::string errstr = fmt::format (" CTF dictionary file {} for detector {} is absent" , dictPath, mDet .getName ());
146+ if (mayFail) {
147+ LOGP (info, " {}, will assume dictionary stored in CTF" , errstr);
148+ } else {
149+ throw std::runtime_error (errstr);
150+ }
151+ return bufVec;
152+ }
153+ std::unique_ptr<TTree> tree ((TTree*)fileDict->Get (std::string (o2::base::NameConf::CTFDICT).c_str ()));
154+ std::unique_ptr<std::vector<char >> bv ((std::vector<char >*)fileDict->GetObjectChecked (o2::base::NameConf::CCDBOBJECT.data (), " std::vector<char>" ));
155+ if (tree) {
156+ CTFHeader ctfHeader;
157+ if (!readFromTree (*tree.get (), " CTFHeader" , ctfHeader) || !ctfHeader.detectors [mDet ]) {
158+ std::string errstr = fmt::format (" CTF dictionary file for detector {} is absent in the tree from file {}" , mDet .getName (), dictPath);
159+ if (mayFail) {
160+ LOGP (info, " {}, will assume dictionary stored in CTF" , errstr);
161+ } else {
162+ throw std::runtime_error (errstr);
163+ }
164+ return bufVec;
165+ }
166+ CTF::readFromTree (bufVec, *tree.get (), mDet .getName ());
167+ } else if (bv) {
168+ bufVec.swap (*bv);
169+ if (bufVec.size ()) {
170+ auto dictHeader = static_cast <o2::ctf::CTFDictHeader&>(CTF::get (bufVec.data ())->getHeader ());
171+ if (dictHeader.det != mDet ) {
172+ throw std::runtime_error (fmt::format (" {} contains dictionary vector for {}, expected {}" , dictPath, dictHeader.det .getName (), mDet .getName ()));
173+ }
174+ }
175+ }
176+ if (bufVec.size ()) {
177+ mExtHeader = static_cast <CTFDictHeader&>(CTF::get (bufVec.data ())->getHeader ());
178+ LOGP (info, " Found {} in {}" , mExtHeader .asString (), dictPath);
179+ } else {
180+ std::string errstr = fmt::format (" CTF dictionary file for detector {} is empty" , mDet .getName ());
181+ if (mayFail) {
182+ LOGP (info, " {}, will assume dictionary stored in CTF" , errstr);
183+ } else {
184+ throw std::runtime_error (errstr);
185+ }
186+ }
187+ return bufVec;
188+ }
189+
114190} // namespace ctf
115191} // namespace o2
116192
0 commit comments