2525#include " DetectorsCommonDataFormats/CTFHeader.h"
2626#include " rANS/rans.h"
2727#include < filesystem>
28+ #include " Framework/InitContext.h"
29+ #include " Framework/ConcreteDataMatcher.h"
30+ #include " Framework/ConfigParamRegistry.h"
2831
2932namespace o2
3033{
34+ namespace framework
35+ {
36+ class ProcessingContext ;
37+ }
3138namespace ctf
3239{
3340
@@ -45,6 +52,7 @@ class CTFCoderBase
4552
4653 CTFCoderBase () = delete ;
4754 CTFCoderBase (int n, DetID det, float memFactor = 1 .f) : mCoders (n), mDet (det), mMemMarginFactor (memFactor > 1 .f ? memFactor : 1 .f) {}
55+ CTFCoderBase (OpType op, int n, DetID det, float memFactor = 1 .f) : mOpType (op), mCoders (n), mDet (det), mMemMarginFactor (memFactor > 1 .f ? memFactor : 1 .f) {}
4856 virtual ~CTFCoderBase () = default ;
4957
5058 virtual void createCoders (const std::vector<char >& bufVec, o2::ctf::CTFCoderBase::OpType op) = 0;
@@ -85,9 +93,23 @@ class CTFCoderBase
8593 void setVerbosity (int v) { mVerbosity = v; }
8694 int getVerbosity () const { return mVerbosity ; }
8795
96+ const CTFDictHeader& getExtDictHeader () const { return mExtHeader ; }
97+
8898 template <typename T>
8999 static bool readFromTree (TTree& tree, const std::string brname, T& dest, int ev = 0 );
90100
101+ // these are the helper methods for the parent encoding/decoding task
102+ template <typename CTF >
103+ void init (o2::framework::InitContext& ic);
104+
105+ template <typename CTF , typename BUF >
106+ size_t finaliseCTFOutput (BUF & buffer);
107+
108+ template <typename CTF >
109+ bool finaliseCCDB (o2::framework::ConcreteDataMatcher& matcher, void * obj);
110+
111+ void updateTimeDependentParams (o2::framework::ProcessingContext& pc);
112+
91113 protected:
92114 std::string getPrefix () const { return o2::utils::Str::concat_string (mDet .getName (), " _CTF: " ); }
93115 void assignDictVersion (CTFDictHeader& h) const
@@ -103,6 +125,8 @@ class CTFCoderBase
103125 DetID mDet ;
104126 CTFDictHeader mExtHeader ; // external dictionary header
105127 float mMemMarginFactor = 1 .0f ; // factor for memory allocation in EncodedBlocks
128+ bool mLoadDictFromCCDB {true };
129+ OpType mOpType ; // Encoder or Decoder
106130 int mVerbosity = 0 ;
107131};
108132
@@ -170,15 +194,15 @@ std::vector<char> CTFCoderBase::readDictionaryFromFile(const std::string& dictPa
170194 } else if (bv) {
171195 bufVec.swap (*bv);
172196 if (bufVec.size ()) {
173- auto dictHeader = static_cast <o2::ctf::CTFDictHeader&>(CTF::get (bufVec.data ())->getHeader ());
197+ auto dictHeader = static_cast <const o2::ctf::CTFDictHeader&>(CTF::get (bufVec.data ())->getHeader ());
174198 if (dictHeader.det != mDet ) {
175199 throw std::runtime_error (fmt::format (" {} contains dictionary vector for {}, expected {}" , dictPath, dictHeader.det .getName (), mDet .getName ()));
176200 }
177201 }
178202 }
179203 if (bufVec.size ()) {
180204 mExtHeader = static_cast <CTFDictHeader&>(CTF::get (bufVec.data ())->getHeader ());
181- LOGP (info , " Found {} in {}" , mExtHeader .asString (), dictPath);
205+ LOGP (debug , " Found {} in {}" , mExtHeader .asString (), dictPath);
182206 } else {
183207 std::string errstr = fmt::format (" CTF dictionary file for detector {} is empty" , mDet .getName ());
184208 if (mayFail) {
@@ -190,6 +214,57 @@ std::vector<char> CTFCoderBase::readDictionaryFromFile(const std::string& dictPa
190214 return bufVec;
191215}
192216
217+ // /________________________________
218+ template <typename CTF >
219+ void CTFCoderBase::init (o2::framework::InitContext& ic)
220+ {
221+ if (ic.options ().hasOption (" mem-factor" )) {
222+ setMemMarginFactor (ic.options ().get <float >(" mem-factor" ));
223+ }
224+ auto dict = ic.options ().get <std::string>(" ctf-dict" );
225+ if (dict.empty ()) { // load from CCDB
226+ mLoadDictFromCCDB = true ;
227+ } else {
228+ if (dict != " none" ) { // none means per-CTF dictionary will created on the fly
229+ createCodersFromFile<CTF >(dict, mOpType );
230+ LOGP (info, " Loaded {} from {}" , mExtHeader .asString (), dict);
231+ } else {
232+ LOGP (info, " Internal per-TF CTF Dict will be created" );
233+ }
234+ mLoadDictFromCCDB = false ; // don't try to load from CCDB
235+ }
236+ }
237+
238+ // /________________________________
239+ template <typename CTF , typename BUF >
240+ size_t CTFCoderBase::finaliseCTFOutput (BUF & buffer)
241+ {
242+ auto eeb = CTF::get (buffer.data ()); // cast to container pointer
243+ eeb->compactify (); // eliminate unnecessary padding
244+ buffer.resize (eeb->size ()); // shrink buffer to strictly necessary size
245+ // eeb->print();
246+ return eeb->size ();
247+ }
248+
249+ // /________________________________
250+ template <typename CTF >
251+ bool CTFCoderBase::finaliseCCDB (o2::framework::ConcreteDataMatcher& matcher, void * obj)
252+ {
253+ bool match = false ;
254+ if (mLoadDictFromCCDB && (match = (matcher == o2::framework::ConcreteDataMatcher (mDet .getDataOrigin (), " CTFDICT" , 0 )))) {
255+ const auto * dict = (std::vector<char >*)obj;
256+ if (dict->empty ()) {
257+ LOGP (info, " Empty dictionary object fetched from CCDB, internal per-TF CTF Dict will be created" );
258+ } else {
259+ createCoders (*dict, mOpType );
260+ mExtHeader = static_cast <const CTFDictHeader&>(CTF::get (dict->data ())->getHeader ());
261+ LOGP (info, " Loaded {} from CCDB" , mExtHeader .asString ());
262+ }
263+ mLoadDictFromCCDB = false ; // we read the dictionary at most once!
264+ }
265+ return match;
266+ }
267+
193268} // namespace ctf
194269} // namespace o2
195270
0 commit comments