17#ifndef ALICEO2_ENCODED_BLOCKS_H
18#define ALICEO2_ENCODED_BLOCKS_H
53template <
class,
class Enable =
void>
59 std::is_base_of_v<std::input_iterator_tag, typename std::iterator_traits<T>::iterator_category> ||
60 std::is_same_v<std::output_iterator_tag, typename std::iterator_traits<T>::iterator_category>>>
99 return (
ptr !=
nullptr) ?
reinterpret_cast<T*
>(newBase + (
reinterpret_cast<const char*
>(
ptr) - oldBase)) :
nullptr;
102template <
typename source_T,
typename dest_T, std::enable_if_t<(sizeof(dest_T) >= sizeof(source_T)),
bool> =
true>
105 const size_t srcBufferSize = nElems *
sizeof(
source_T);
106 return srcBufferSize /
sizeof(dest_T) + (srcBufferSize %
sizeof(dest_T) != 0);
109template <
typename source_T,
typename dest_T, std::enable_if_t<(sizeof(dest_T) >= sizeof(source_T)),
bool> =
true>
112 const size_t sizeOfSourceT =
sizeof(
source_T);
113 const size_t sizeOfDestT =
sizeof(dest_T);
116 return (sizeOfDestT / sizeOfSourceT) * calculateNDestTElements<source_T, dest_T>(nElems);
151template <
typename W = u
int32_t>
235 throw std::runtime_error(
"trying to write in occupied block");
239 assert(sz <= registry->getFreeSize());
240 assert((_ndict > 0) == (_dict !=
nullptr));
252 throw std::runtime_error(
"trying to write in occupied block");
257 assert(sz <= registry->getFreeSize());
258 assert((_ndata > 0) == (_data !=
nullptr));
270 throw std::runtime_error(
"trying to write in occupied block");
275 assert(sz <= registry->getFreeSize());
294 void store(
int _ndict,
int _ndata,
int _nliterals,
const W* _dict,
const W* _data,
const W* _literals)
298 assert(sz <= registry->getFreeSize());
299 assert((_ndict > 0) == (_dict !=
nullptr));
300 assert((_ndata > 0) == (_data !=
nullptr));
322 void relocate(
const char* oldHead,
char* newHeadData,
char* newHeadRegistry)
333template <
typename H,
int N,
typename W = u
int32_t>
340 template <
typename source_T>
369 template <
typename source_T>
376 assert(
static_cast<int64_t
>(std::numeric_limits<source_T>::min()) <=
static_cast<int64_t
>(metadata.max));
377 assert(
static_cast<int64_t
>(std::numeric_limits<source_T>::max()) >=
static_cast<int64_t
>(metadata.min));
381 const int64_t sourceMin = std::numeric_limits<source_T>::min();
382 const int64_t sourceMax = std::numeric_limits<source_T>::max();
385 const int64_t dictMin = view.getMin();
386 const int64_t dictMax = view.getMax();
387 assert(dictMin >= metadata.min);
388 assert(dictMax <= metadata.max);
390 if ((dictMin < sourceMin) || (dictMax > sourceMax)) {
392 LOGP(warn,
"value range of dictionary and target datatype are incompatible: target type [{},{}] vs dictionary [{},{}], tolerate in compat mode for old dictionaries", sourceMin, sourceMax, dictMin, dictMax);
394 throw std::runtime_error(fmt::format(
"value range of dictionary and target datatype are incompatible: target type [{},{}] vs dictionary [{},{}]", sourceMin, sourceMax, dictMin, dictMax));
407 LOG_IF(
debug, renormingBits != metadata.probabilityBits)
408 << fmt::format(
"While reading metadata from external dictionary, rANSV1 is rounding renorming precision from {} to {}", metadata.probabilityBits, renormingBits);
412 if constexpr (
sizeof(
source_T) > 2) {
415 metadata.probabilityBits);
419 metadata.probabilityBits);
423 throw std::runtime_error(fmt::format(
"Failed to load serialized Dictionary. Unsupported ANS Version: {}",
static_cast<std::string
>(ansVersion)));
447 static auto create(
void* head,
size_t sz);
450 template <
typename VD>
475 template <
typename buffer_T>
479 template <
typename V>
492 template <
typename VD>
496 template <
typename VE,
typename buffer_T>
499 return encode(std::begin(
src), std::end(
src), slot, symbolTablePrecision, opt,
buffer, encoderExt, memfc);
503 template <
typename input_IT,
typename buffer_T>
507 template <
class container_T,
class container_IT =
typename container_T::iterator>
511 template <
typename D_IT, std::enable_if_t<detail::is_iterator_v<D_IT>,
bool> = true>
521 void dump(
const std::string& prefix =
"",
int ncol = 20)
const;
524 static_assert(N > 0,
"number of encoded blocks < 1");
541 static void relocate(
const char* oldHead,
char* newHead,
char* wrapper,
size_t newsize = 0);
554 template <
typename D>
555 static size_t fillTreeBranch(TTree&
tree,
const std::string& brname, D& dt,
int compLevel,
int splitLevel = 99);
558 template <
typename D>
561 template <
typename T>
569 const bool isEqual{ansVersion == ctfANSHeader};
573 if (isHeaderUnspecified) {
574 throw std::runtime_error{fmt::format(
"Missmatch of ANSVersions, trying to encode/decode CTF with ANS Version Header {} with ANS Version {}",
575 static_cast<std::string
>(ctfANSHeader),
576 static_cast<std::string
>(ansVersion))};
581 if (isHeaderUnspecified) {
591 template <
typename input_IT,
typename buffer_T>
594 template <
typename input_IT,
typename buffer_T>
597 template <
typename input_IT,
typename buffer_T>
600 template <
typename input_IT,
typename buffer_T>
604 template <
typename input_IT,
typename buffer_T>
607 template <
typename input_IT,
typename buffer_T>
610 using source_type =
typename std::iterator_traits<input_IT>::value_type;
615 if (
metrics.getDatasetProperties().numSamples != 0) {
616 const auto [minIter, maxIter] = std::minmax_element(srcBegin, srcEnd);
617 metrics.getDatasetProperties().min = *minIter;
618 metrics.getDatasetProperties().max = *maxIter;
621 metrics.getDatasetProperties().alphabetRangeBits =
623 metrics.getDatasetProperties().max);
630 template <
typename input_IT,
typename buffer_T>
634 template <
typename dst_IT>
637 template <
typename dst_IT>
640 template <
typename dst_IT>
643 template <
typename dst_IT>
651template <
typename H,
int N,
typename W>
655 for (
int i = 0;
i < N;
i++) {
662template <
typename H,
int N,
typename W>
663template <
typename VD>
666 auto tmp = create(
vec);
668 throw std::runtime_error(fmt::format(
"Failed to read CTF header for {}",
name));
670 tmp = tmp->expand(
vec, tmp->estimateSizeFromMetadata());
671 const auto& meta = tmp->getMetadata();
672 for (
int i = 0;
i < N;
i++) {
675 assert(meta[
i].nDictWords == bl.
getNDict());
676 assert(meta[
i].nDataWords == bl.
getNData());
684template <
typename H,
int N,
typename W>
689 for (
int i = 0;
i < N;
i++) {
693 tree.SetEntries(
tree.GetEntries() + 1);
699template <
typename H,
int N,
typename W>
703 auto* br =
tree.GetBranch(brname.c_str());
705 LOG(
debug) <<
"Branch " << brname <<
" is absent";
709 br->SetAddress(&
ptr);
717template <
typename H,
int N,
typename W>
721 auto* br =
tree.GetBranch(brname.c_str());
723 br =
tree.Branch(brname.c_str(), &dt, 512, splitLevel);
724 br->SetCompressionLevel(compLevel);
731template <
typename H,
int N,
typename W>
738 for (
int i = 0;
i < N;
i++) {
739 dest.
mBlocks[
i].store(mBlocks[
i].getNDict(), mBlocks[
i].getNData(), mBlocks[
i].getDict(), mBlocks[
i].
getData());
745template <
typename H,
int N,
typename W>
749 auto vtsz =
sizeof(
typename std::remove_reference<
decltype(
vec)>::type::value_type), sz =
estimateSize();
750 vec.resize(sz / vtsz);
751 copyToFlat(
vec.data());
757template <
typename H,
int N,
typename W>
762 for (
int i = 0;
i < N;
i++) {
763 sz +=
alignSize(mBlocks[
i].nStored *
sizeof(W));
771template <
typename H,
int N,
typename W>
775 for (
int i = 0;
i < N;
i++) {
776 sz +=
alignSize((mMetadata[
i].nDictWords + mMetadata[
i].nDataWords + mMetadata[
i].nLiteralWords) *
sizeof(W));
783template <
typename H,
int N,
typename W>
784template <
typename buffer_T>
787 auto buftypesize =
sizeof(
typename std::remove_reference<
decltype(
buffer)>::type::value_type);
788 auto* oldHead = get(
buffer.data())->mRegistry.head;
790 relocate(oldHead,
reinterpret_cast<char*
>(
buffer.data()),
reinterpret_cast<char*
>(
buffer.data()), newsizeBytes);
791 return get(
buffer.data());
799template <
typename H,
int N,
typename W>
802 auto newStr = get(wrapper);
803 for (
int i = 0;
i < N;
i++) {
804 newStr->mBlocks[
i].relocate(oldHead, newHead, wrapper);
806 newStr->mRegistry.head = newHead;
809 assert(newStr->estimateSize() <= newsize);
810 newStr->mRegistry.size = newsize;
816template <
typename H,
int N,
typename W>
819 mRegistry.
head =
reinterpret_cast<char*
>(
this);
822 for (
int i = 0;
i < N;
i++) {
823 mMetadata[
i].clear();
824 mBlocks[
i].registry = &mRegistry;
831template <
typename H,
int N,
typename W>
834 for (
int i = 0;
i < N;
i++) {
836 mMetadata[
i].clear();
843template <
typename H,
int N,
typename W>
847 auto image(*get(newHead));
850 relocate(
image.mRegistry.head,
const_cast<char*
>(
reinterpret_cast<const char*
>(newHead)),
reinterpret_cast<char*
>(&
image));
857template <
typename H,
int N,
typename W>
869template <
typename H,
int N,
typename W>
870template <
typename VD>
873 size_t vsz =
sizeof(
typename std::remove_reference<
decltype(
v)>::type::value_type);
874 auto baseSize = getMinAlignedSize() / vsz;
875 if (
v.size() < baseSize) {
878 return create(
v.data(),
v.size() * vsz);
883template <
typename H,
int N,
typename W>
887 LOG(info) << prefix <<
"Container of " << N <<
" blocks, size: " <<
size() <<
" bytes, unused: " << getFreeSize();
888 for (
int i = 0;
i < N;
i++) {
889 LOG(info) <<
"Block " <<
i <<
" for " <<
static_cast<uint32_t
>(mMetadata[
i].messageLength) <<
" message words of "
890 <<
static_cast<uint32_t
>(mMetadata[
i].messageWordSize) <<
" bytes |"
891 <<
" NDictWords: " << mBlocks[
i].getNDict() <<
" NDataWords: " << mBlocks[
i].getNData()
892 <<
" NLiteralWords: " << mBlocks[
i].getNLiterals();
895 size_t inpSize = 0, ndict = 0, ndata = 0, nlit = 0;
896 for (
int i = 0;
i < N;
i++) {
897 inpSize += mMetadata[
i].messageLength * mMetadata[
i].messageWordSize;
898 ndict += mBlocks[
i].getNDict();
899 ndata += mBlocks[
i].getNData();
900 nlit += mBlocks[
i].getNLiterals();
902 LOG(info) << prefix << N <<
" blocks, input size: " << inpSize <<
", output size: " <<
size()
903 <<
" NDictWords: " << ndict <<
" NDataWords: " << ndata <<
" NLiteralWords: " << nlit;
908template <
typename H,
int N,
typename W>
909template <
class container_T,
class container_IT>
912 const std::any& decoderExt)
const
914 dest.resize(mMetadata[slot].messageLength);
915 return decode(std::begin(dest), slot, decoderExt);
919template <
typename H,
int N,
typename W>
920template <
typename D_IT, std::enable_if_t<detail::is_iterator_v<D_IT>,
bool>>
923 const std::any& decoderExt)
const
927 const auto& ansVersion = getANSHeader();
928 const auto& block = mBlocks[slot];
929 const auto& md = mMetadata[slot];
930 LOGP(
debug,
"Slot{} | NStored={} Ndict={} nData={}, MD: messageLength:{} opt:{} min:{} max:{} offs:{} width:{} ", slot, block.getNStored(), block.getNDict(), block.getNData(), md.messageLength, (
int)md.opt, md.min, md.max, md.literalsPackingOffset, md.literalsPackingWidth);
933 if (!block.getNStored()) {
934 return {0, md.getUncompressedSize(), md.getCompressedSize()};
937 return decodeCompatImpl(dest, slot, decoderExt);
939 return decodeCopyImpl(dest, slot);
943 return decodeUnpackImpl(dest, slot);
945 if (!block.getNStored()) {
946 return {0, md.getUncompressedSize(), md.getCompressedSize()};
949 return decodeRansV1Impl(dest, slot, decoderExt);
951 return decodeCopyImpl(dest, slot);
954 throw std::runtime_error(
"unsupported ANS Version");
959template <
typename H,
int N,
typename W>
960template <
typename dst_IT>
965 const auto& block = mBlocks[slot];
966 const auto& md = mMetadata[slot];
968 using dst_type =
typename std::iterator_traits<dst_IT>::value_type;
971 std::optional<decoder_type> inplaceDecoder{};
972 if (md.nDictWords > 0) {
973 inplaceDecoder = decoder_type{std::get<rans::RenormedDenseHistogram<dst_type>>(this->getDictionary<dst_type>(slot))};
974 }
else if (!decoderExt.has_value()) {
975 throw std::runtime_error(
"neither dictionary nor external decoder provided");
978 auto getDecoder = [&]() ->
const decoder_type& {
979 if (inplaceDecoder.has_value()) {
980 return inplaceDecoder.value();
982 return std::any_cast<const decoder_type&>(decoderExt);
988 if (block.getNLiterals()) {
989 auto* literalsEnd =
reinterpret_cast<const dst_type*
>(block.getLiterals()) + md.nLiterals;
990 getDecoder().process(block.getData() + block.getNData(), dstBegin, md.messageLength, NDecoderStreams, literalsEnd);
992 getDecoder().process(block.getData() + block.getNData(), dstBegin, md.messageLength, NDecoderStreams);
994 return {0, md.getUncompressedSize(), md.getCompressedSize()};
997template <
typename H,
int N,
typename W>
998template <
typename dst_IT>
1003 const auto& block = mBlocks[slot];
1004 const auto& md = mMetadata[slot];
1006 using dst_type =
typename std::iterator_traits<dst_IT>::value_type;
1009 std::optional<decoder_type> inplaceDecoder{};
1010 if (md.nDictWords > 0) {
1011 std::visit([&](
auto&& arg) { inplaceDecoder = decoder_type{arg}; }, this->getDictionary<dst_type>(slot));
1012 }
else if (!decoderExt.has_value()) {
1013 throw std::runtime_error(
"no dictionary nor external decoder provided");
1016 auto getDecoder = [&]() ->
const decoder_type& {
1017 if (inplaceDecoder.has_value()) {
1018 return inplaceDecoder.value();
1020 return std::any_cast<const decoder_type&>(decoderExt);
1026 const decoder_type& decoder = getDecoder();
1027 const size_t decoderSymbolTablePrecision = decoder.getSymbolTablePrecision();
1029 if (md.probabilityBits != decoderSymbolTablePrecision) {
1030 throw std::runtime_error(fmt::format(
1031 "Missmatch in decoder renorming precision vs metadata:{} Bits vs {} Bits.",
1032 md.probabilityBits, decoderSymbolTablePrecision));
1035 if (md.streamSize != rans::utils::getStreamingLowerBound_v<typename decoder_type::coder_type>) {
1036 throw std::runtime_error(
"Streaming lower bound of dataset and decoder do not match");
1041 if (block.getNLiterals()) {
1042 std::vector<dst_type> literals(md.nLiterals);
1043 rans::unpack(block.getLiterals(), md.nLiterals, literals.data(), md.literalsPackingWidth, md.literalsPackingOffset);
1044 getDecoder().process(block.getData() + block.getNData(), dstBegin, md.messageLength, md.nStreams, literals.end());
1046 getDecoder().process(block.getData() + block.getNData(), dstBegin, md.messageLength, md.nStreams);
1048 return {0, md.getUncompressedSize(), md.getCompressedSize()};
1051template <
typename H,
int N,
typename W>
1052template <
typename dst_IT>
1055 using dest_t =
typename std::iterator_traits<dst_IT>::value_type;
1057 const auto& block = mBlocks[slot];
1058 const auto& md = mMetadata[slot];
1060 const size_t messageLength = md.messageLength;
1061 const size_t packingWidth = md.probabilityBits;
1062 const dest_t
offset = md.min;
1063 const auto* srcIt = block.getData();
1065 if (packingWidth == 0) {
1066 const dest_t
value = [&]() -> dest_t {
1068 if (md.nDataWords > 0) {
1069 LOGP(
debug,
"packing bug recovery: MD nStreams:{} messageLength:{} nLiterals:{} messageWordSize:{} coderType:{} streamSize:{} probabilityBits:{} (int)opt:{} min:{} max:{} literalsPackingOffset:{} literalsPackingWidth:{} nDictWords:{} nDataWords:{} nLiteralWords:{}",
1070 value, md.nStreams, md.messageLength, md.nLiterals, md.messageWordSize, md.coderType, md.streamSize, md.probabilityBits, (
int)md.opt, md.min, md.max, md.literalsPackingOffset, md.literalsPackingWidth, md.nDictWords, md.nDataWords, md.nLiteralWords);
1071 return offset +
static_cast<dest_t
>(*srcIt);
1076 for (
size_t i = 0;
i < messageLength; ++
i) {
1082 return {0, md.getUncompressedSize(), md.getCompressedSize()};
1085template <
typename H,
int N,
typename W>
1086template <
typename dst_IT>
1090 const auto& block = mBlocks[slot];
1091 const auto& md = mMetadata[slot];
1093 using dest_t =
typename std::iterator_traits<dst_IT>::value_type;
1095 using destPtr_t =
typename std::iterator_traits<dst_IT>::pointer;
1097 destPtr_t srcBegin =
reinterpret_cast<destPtr_t
>(block.payload);
1098 destPtr_t srcEnd = srcBegin + md.messageLength *
sizeof(dest_t);
1099 std::copy(srcBegin, srcEnd, dest);
1101 return {0, md.getUncompressedSize(), md.getCompressedSize()};
1105template <
typename H,
int N,
typename W>
1106template <
typename input_IT,
typename buffer_T>
1108 const input_IT srcEnd,
1110 uint8_t symbolTablePrecision,
1113 const std::any& encoderExt,
1120 const size_t messageLength = std::distance(srcBegin, srcEnd);
1127 if (messageLength == 0) {
1133 const ANSHeader& ansVersion = getANSHeader();
1135 return entropyCodeRANSCompat(srcBegin, srcEnd, slot, symbolTablePrecision,
buffer, encoderExt, memfc);
1137 return entropyCodeRANSV1(srcBegin, srcEnd, slot, opt,
buffer, encoderExt, memfc);
1139 throw std::runtime_error(fmt::format(
"Unsupported ANS Coder Version: {}.{}", ansVersion.
majorVersion, ansVersion.
minorVersion));
1144 return store(srcBegin, srcEnd, slot, opt,
buffer);
1148template <
typename H,
int N,
typename W>
1149template <
typename T>
1153 auto* old = get(
buffer->data());
1154 auto* thisBlock = &(old->mBlocks[slot]);
1155 auto* thisMetadata = &(old->mMetadata[slot]);
1158 auto*
const blockHead = get(thisBlock->registry->head);
1159 const size_t additionalSize = blockHead->estimateBlockSize(nElements);
1160 if (additionalSize >= thisBlock->registry->getFreeSize()) {
1161 LOGP(
debug,
"Slot {} with {} available words needs to allocate {} bytes for a total of {} words.", slot, thisBlock->registry->getFreeSize(), additionalSize, nElements);
1163 blockHead->expand(*
buffer, blockHead->size() + (additionalSize - blockHead->getFreeSize()));
1164 thisMetadata = &(get(
buffer->data())->mMetadata[slot]);
1165 thisBlock = &(get(
buffer->data())->mBlocks[slot]);
1167 throw std::runtime_error(
"failed to allocate additional space in provided external buffer");
1170 return std::make_pair(thisBlock, thisMetadata);
1173template <
typename H,
int N,
typename W>
1174template <
typename input_IT,
typename buffer_T>
1177 using storageBuffer_t = W;
1178 using input_t =
typename std::iterator_traits<input_IT>::value_type;
1180 using ransState_t =
typename ransEncoder_t::coder_type::state_type;
1181 using ransStream_t =
typename ransEncoder_t::stream_type;
1184 static_assert(std::is_same_v<storageBuffer_t, ransStream_t>);
1185 static_assert(std::is_same_v<storageBuffer_t, typename rans::count_t>);
1187 auto* thisBlock = &mBlocks[slot];
1188 auto* thisMetadata = &mMetadata[slot];
1191 constexpr size_t SizeEstMarginAbs = 10 * 1024;
1192 const float SizeEstMarginRel = 1.5 * memfc;
1194 const size_t messageLength = std::distance(srcBegin, srcEnd);
1199 std::tie(inplaceEncoder, frequencyTable) = [&]() {
1200 if (encoderExt.has_value()) {
1205 return std::make_tuple(std::move(encoder), std::move(histogram));
1209 LOGP(warning,
"Failed to build Dictionary for rANS encoding, using fallback option");
1210 return store(srcBegin, srcEnd, slot, this->FallbackStorageType,
buffer);
1212 const ransEncoder_t& encoder = encoderExt.has_value() ? std::any_cast<const ransEncoder_t&>(encoderExt) : inplaceEncoder;
1217 dataSize = SizeEstMarginAbs +
int(SizeEstMarginRel * (
dataSize /
sizeof(storageBuffer_t))) + (
sizeof(input_t) <
sizeof(storageBuffer_t));
1220 std::tie(thisBlock, thisMetadata) = expandStorage(slot, view.size() +
dataSize,
buffer);
1224 if (!view.empty()) {
1225 thisBlock->storeDict(view.size(), view.data());
1226 LOGP(
debug,
"StoreDict {} bytes, offs: {}:{}", view.size() *
sizeof(W), thisBlock->getOffsDict(), thisBlock->getOffsDict() + view.size() *
sizeof(W));
1229 std::vector<input_t> literals;
1231 storageBuffer_t*
const blockBufferBegin = thisBlock->getCreateData();
1232 const size_t maxBufferSize = thisBlock->registry->getFreeSize();
1233 const auto [encodedMessageEnd, literalsEnd] = encoder.process(srcBegin, srcEnd, blockBufferBegin, std::back_inserter(literals));
1235 dataSize = encodedMessageEnd - thisBlock->getDataPointer();
1237 thisBlock->realignBlock();
1238 LOGP(
debug,
"StoreData {} bytes, offs: {}:{}",
dataSize *
sizeof(W), thisBlock->getOffsData(), thisBlock->getOffsData() +
dataSize *
sizeof(W));
1242 const size_t nLiteralSymbols = literals.size();
1243 const size_t nLiteralWords = [&]() {
1244 if (!literals.empty()) {
1245 const size_t nSymbols = literals.size();
1247 const size_t nLiteralSymbolsPadded = calculatePaddedSize<input_t, storageBuffer_t>(nSymbols);
1248 literals.resize(nLiteralSymbolsPadded, {});
1250 const size_t nLiteralStorageElems = calculateNDestTElements<input_t, storageBuffer_t>(nSymbols);
1251 std::tie(thisBlock, thisMetadata) = expandStorage(slot, nLiteralStorageElems,
buffer);
1252 thisBlock->storeLiterals(nLiteralStorageElems,
reinterpret_cast<const storageBuffer_t*
>(literals.data()));
1253 LOGP(
debug,
"StoreLiterals {} bytes, offs: {}:{}", nLiteralStorageElems *
sizeof(W), thisBlock->getOffsLiterals(), thisBlock->getOffsLiterals() + nLiteralStorageElems *
sizeof(W));
1254 return nLiteralStorageElems;
1259 LOGP(
debug,
"Min, {} Max, {}, size, {}, nSamples {}", view.getMin(), view.getMax(), view.size(), frequencyTable.getNumSamples());
1261 *thisMetadata = detail::makeMetadataRansCompat<input_t, ransState_t, ransStream_t>(encoder.getNStreams(),
1264 encoder.getSymbolTable().getPrecision(),
1271 return {0, thisMetadata->getUncompressedSize(), thisMetadata->getCompressedSize()};
1274template <
typename H,
int N,
typename W>
1275template <
typename input_IT,
typename buffer_T>
1280 const size_t nSamples = std::distance(srcBegin, srcEnd);
1282 encoderStatistics =
pack(srcBegin, srcEnd, slot,
buffer);
1285 if (encoderExt.has_value()) {
1286 encoderStatistics = encodeRANSV1External(srcBegin, srcEnd, slot, encoderExt,
buffer, memfc);
1288 encoderStatistics = encodeRANSV1Inplace(srcBegin, srcEnd, slot, opt,
buffer, memfc);
1291 return encoderStatistics;
1294template <
typename H,
int N,
typename W>
1295template <
typename input_IT,
typename buffer_T>
1298 using storageBuffer_t = W;
1299 using input_t =
typename std::iterator_traits<input_IT>::value_type;
1301 using ransState_t =
typename ransEncoder_t::coder_type::state_type;
1302 using ransStream_t =
typename ransEncoder_t::stream_type;
1305 static_assert(std::is_same_v<storageBuffer_t, ransStream_t>);
1306 static_assert(std::is_same_v<storageBuffer_t, typename rans::count_t>);
1308 auto* thisBlock = &mBlocks[slot];
1309 auto* thisMetadata = &mMetadata[slot];
1311 const size_t messageLength = std::distance(srcBegin, srcEnd);
1314 const size_t payloadSizeWords = encoder.template computePayloadSizeEstimate<storageBuffer_t>(messageLength);
1315 std::tie(thisBlock, thisMetadata) = expandStorage(slot, payloadSizeWords,
buffer);
1318 auto encodedMessageEnd = encoder.encode(srcBegin, srcEnd, thisBlock->getCreateData(), thisBlock->getEndOfBlock());
1319 const size_t dataSize = std::distance(thisBlock->getCreateData(), encodedMessageEnd);
1321 thisBlock->realignBlock();
1322 LOGP(
debug,
"StoreData {} bytes, offs: {}:{}",
dataSize *
sizeof(storageBuffer_t), thisBlock->getOffsData(), thisBlock->getOffsData() +
dataSize *
sizeof(storageBuffer_t));
1326 size_t literalsSize = 0;
1327 if (encoder.getNIncompressibleSamples() > 0) {
1328 const size_t literalsBufferSizeWords = encoder.template computePackedIncompressibleSize<storageBuffer_t>();
1329 std::tie(thisBlock, thisMetadata) = expandStorage(slot, literalsBufferSizeWords,
buffer);
1330 auto literalsEnd = encoder.writeIncompressible(thisBlock->getCreateLiterals(), thisBlock->getEndOfBlock());
1331 literalsSize = std::distance(thisBlock->getCreateLiterals(), literalsEnd);
1332 thisBlock->setNLiterals(literalsSize);
1333 thisBlock->realignBlock();
1334 LOGP(
debug,
"StoreLiterals {} bytes, offs: {}:{}", literalsSize *
sizeof(storageBuffer_t), thisBlock->getOffsLiterals(), thisBlock->getOffsLiterals() + literalsSize *
sizeof(storageBuffer_t));
1338 const auto& symbolTable = encoder.getEncoder().getSymbolTable();
1339 *thisMetadata = detail::makeMetadataRansV1<input_t, ransState_t, ransStream_t>(encoder.getEncoder().getNStreams(),
1340 rans::utils::getStreamingLowerBound_v<typename ransEncoder_t::coder_type>,
1342 encoder.getNIncompressibleSamples(),
1343 symbolTable.getPrecision(),
1344 symbolTable.getOffset(),
1345 symbolTable.getOffset() + symbolTable.size(),
1346 encoder.getIncompressibleSymbolOffset(),
1347 encoder.getIncompressibleSymbolPackingBits(),
1352 return {0, thisMetadata->getUncompressedSize(), thisMetadata->getCompressedSize()};
1355template <
typename H,
int N,
typename W>
1356template <
typename input_IT,
typename buffer_T>
1359 using storageBuffer_t = W;
1360 using input_t =
typename std::iterator_traits<input_IT>::value_type;
1362 using ransState_t =
typename ransEncoder_t::coder_type::state_type;
1363 using ransStream_t =
typename ransEncoder_t::stream_type;
1366 static_assert(std::is_same_v<storageBuffer_t, ransStream_t>);
1367 static_assert(std::is_same_v<storageBuffer_t, typename rans::count_t>);
1369 auto* thisBlock = &mBlocks[slot];
1370 auto* thisMetadata = &mMetadata[slot];
1374 const size_t nSamples = std::distance(begin,
end);
1379 if (proxy.isCached()) {
1385 LOGP(warning,
"Failed to build Dictionary for rANS encoding, using fallback option");
1386 if (proxy.isCached()) {
1387 return store(proxy.beginCache(), proxy.endCache(), slot, this->FallbackStorageType,
buffer);
1389 return store(proxy.beginIter(), proxy.endIter(), slot, this->FallbackStorageType,
buffer);
1401 if (proxy.isCached()) {
1408 encoder.makeEncoder();
1414 sizeEstimateSafetyFactor);
1415 std::tie(thisBlock, thisMetadata) = expandStorage(slot, bufferSizeWords,
buffer);
1418 auto encodedDictEnd = encoder.writeDictionary(thisBlock->getCreateDict(), thisBlock->getEndOfBlock());
1419 const size_t dictSize = std::distance(thisBlock->getCreateDict(), encodedDictEnd);
1420 thisBlock->setNDict(dictSize);
1421 thisBlock->realignBlock();
1422 LOGP(
debug,
"StoreDict {} bytes, offs: {}:{}", dictSize *
sizeof(storageBuffer_t), thisBlock->getOffsDict(), thisBlock->getOffsDict() + dictSize *
sizeof(storageBuffer_t));
1425 auto encodedMessageEnd = thisBlock->getCreateData();
1426 if (proxy.isCached()) {
1427 encodedMessageEnd = encoder.encode(proxy.beginCache(), proxy.endCache(), thisBlock->getCreateData(), thisBlock->getEndOfBlock());
1429 encodedMessageEnd = encoder.encode(proxy.beginIter(), proxy.endIter(), thisBlock->getCreateData(), thisBlock->getEndOfBlock());
1431 const size_t dataSize = std::distance(thisBlock->getCreateData(), encodedMessageEnd);
1433 thisBlock->realignBlock();
1434 LOGP(
debug,
"StoreData {} bytes, offs: {}:{}",
dataSize *
sizeof(storageBuffer_t), thisBlock->getOffsData(), thisBlock->getOffsData() +
dataSize *
sizeof(storageBuffer_t));
1438 size_t literalsSize{};
1439 if (encoder.getNIncompressibleSamples() > 0) {
1440 auto literalsEnd = encoder.writeIncompressible(thisBlock->getCreateLiterals(), thisBlock->getEndOfBlock());
1441 literalsSize = std::distance(thisBlock->getCreateLiterals(), literalsEnd);
1442 thisBlock->setNLiterals(literalsSize);
1443 thisBlock->realignBlock();
1444 LOGP(
debug,
"StoreLiterals {} bytes, offs: {}:{}", literalsSize *
sizeof(storageBuffer_t), thisBlock->getOffsLiterals(), thisBlock->getOffsLiterals() + literalsSize *
sizeof(storageBuffer_t));
1448 *thisMetadata = detail::makeMetadataRansV1<input_t, ransState_t, ransStream_t>(encoder.getNStreams(),
1449 rans::utils::getStreamingLowerBound_v<typename ransEncoder_t::coder_type>,
1450 std::distance(srcBegin, srcEnd),
1451 encoder.getNIncompressibleSamples(),
1452 encoder.getSymbolTablePrecision(),
1453 *
metrics.getCoderProperties().min,
1454 *
metrics.getCoderProperties().max,
1455 metrics.getDatasetProperties().min,
1456 metrics.getDatasetProperties().alphabetRangeBits,
1461 return {0, thisMetadata->getUncompressedSize(), thisMetadata->getCompressedSize()};
1464template <
typename H,
int N,
typename W>
1465template <
typename input_IT,
typename buffer_T>
1468 using storageBuffer_t = W;
1469 using input_t =
typename std::iterator_traits<input_IT>::value_type;
1471 const size_t messageLength =
metrics.getDatasetProperties().numSamples;
1472 const auto alphabetRangeBits =
metrics.getDatasetProperties().alphabetRangeBits;
1474 auto* thisBlock = &mBlocks[slot];
1475 auto* thisMetadata = &mMetadata[slot];
1476 size_t packedSize = 0;
1478 if (messageLength == 0) {
1479 *thisMetadata = detail::makeMetadataPack<input_t>(0, 0, 0, 0);
1480 }
else if (
metrics.getDatasetProperties().alphabetRangeBits == 0) {
1481 *thisMetadata = detail::makeMetadataPack<input_t>(messageLength, 0, *srcBegin, 0);
1484 size_t packingBufferWords = packer.template getPackingBufferSize<storageBuffer_t>(messageLength);
1485 std::tie(thisBlock, thisMetadata) = expandStorage(slot, packingBufferWords,
buffer);
1486 auto packedMessageEnd = packer.pack(srcBegin, srcEnd, thisBlock->getCreateData(), thisBlock->getEndOfBlock());
1487 packedSize = std::distance(thisBlock->getCreateData(), packedMessageEnd);
1488 *thisMetadata = detail::makeMetadataPack<input_t>(messageLength, packer.getPackingWidth(), packer.getOffset(), packedSize);
1489 thisBlock->setNData(packedSize);
1490 thisBlock->realignBlock();
1493 LOGP(
debug,
"StoreData {} bytes, offs: {}:{}", packedSize *
sizeof(storageBuffer_t), thisBlock->getOffsData(), thisBlock->getOffsData() + packedSize *
sizeof(storageBuffer_t));
1494 return {0, thisMetadata->getUncompressedSize(), thisMetadata->getCompressedSize()};
1497template <
typename H,
int N,
typename W>
1498template <
typename input_IT,
typename buffer_T>
1501 using storageBuffer_t = W;
1502 using input_t =
typename std::iterator_traits<input_IT>::value_type;
1504 const size_t messageLength = std::distance(srcBegin, srcEnd);
1506 const size_t nSourceElemsPadded = calculatePaddedSize<input_t, storageBuffer_t>(messageLength);
1507 std::vector<input_t> tmp(nSourceElemsPadded, {});
1508 std::copy(srcBegin, srcEnd, std::begin(tmp));
1510 const size_t nBufferElems = calculateNDestTElements<input_t, storageBuffer_t>(messageLength);
1511 auto [thisBlock, thisMetadata] = expandStorage(slot, nBufferElems,
buffer);
1512 thisBlock->storeData(nBufferElems,
reinterpret_cast<const storageBuffer_t*
>(tmp.data()));
1514 *thisMetadata = detail::makeMetadataStore<input_t, storageBuffer_t>(messageLength, opt, nBufferElems);
1516 return {0, thisMetadata->getUncompressedSize(), thisMetadata->getCompressedSize()};
1520template <
typename H,
int N,
typename W>
1524 if (vfreq.size() != N) {
1525 throw std::runtime_error(fmt::format(
"mismatch between the size of frequencies vector {} and number of blocks {}", vfreq.size(), N));
1528 for (
int ib = 0; ib < N; ib++) {
1531 std::vector<char> vdict(sz);
1532 auto dictBlocks = create(vdict.data(), sz);
1533 for (
int ib = 0; ib < N; ib++) {
1534 const auto& thisHistogram = vfreq[ib];
1537 if (!view.empty()) {
1538 LOG(info) <<
"adding dictionary of " << view.size() <<
" words for block " << ib <<
", min/max= " << view.getMin() <<
"/" << view.getMax();
1539 dictBlocks->mBlocks[ib].storeDict(view.size(), view.data());
1540 dictBlocks = get(vdict.data());
1541 dictBlocks->mMetadata[ib] = vmd[ib];
1543 dictBlocks->mBlocks[ib].realignBlock();
1547 dictBlocks->mRegistry.nFilledBlocks++;
1553template <
typename H,
int N,
typename W>
1556 for (
int ibl = 0; ibl < getNBlocks(); ibl++) {
1557 const auto& blc = getBlock(ibl);
1559 LOGP(info,
"{} Bloc:{} Dict: {} words", prefix, ibl, blc.getNDict());
1560 const auto*
ptr = blc.getDict();
1561 for (
int i = 0;
i < blc.getNDict();
i++) {
1562 if (
i && (
i % ncol) == 0) {
1566 ss += fmt::format(
" {:#010x}",
ptr[
i]);
1573 LOGP(info,
"{} Bloc:{} Data: {} words", prefix, ibl, blc.getNData());
1574 ptr = blc.getData();
1575 for (
int i = 0;
i < blc.getNData();
i++) {
1576 if (
i && (
i % ncol) == 0) {
1580 ss += fmt::format(
" {:#010x}",
ptr[
i]);
1587 LOGP(info,
"{} Bloc:{} Literals: {} words", prefix, ibl, blc.getNLiterals());
1588 ptr = blc.getData();
1589 for (
int i = 0;
i < blc.getNLiterals();
i++) {
1590 if (
i && (
i % 20) == 0) {
1594 ss += fmt::format(
" {:#010x}",
ptr[
i]);
Interfaces for BitPacking using librans.
useful public helper functions.
Class for time synchronization of RawReader instances.
<<======================== Auxiliary classes =======================<<
CTFIOSize decodeCopyImpl(dst_IT dest, int slot) const
static constexpr Metadata::OptStore FallbackStorageType
this is in fact stored, but to overcome TBuffer limits we have to define the branches per block!...
void readFromTree(TTree &tree, const std::string &name, int ev=0)
read from tree to non-flat object
o2::ctf::CTFIOSize entropyCodeRANSV1(const input_IT srcBegin, const input_IT srcEnd, int slot, Metadata::OptStore opt, buffer_T *buffer=nullptr, const std::any &encoderExt={}, float memfc=1.f)
static auto get(void *head)
cast arbitrary buffer head to container class. Head is supposed to respect the alignment
ClassDefNV(EncodedBlocks, 3)
static size_t estimateBlockSize(int n)
estimate free size needed to add new block
CTFIOSize decodeCompatImpl(dst_IT dest, int slot, const std::any &decoderExt) const
o2::ctf::CTFIOSize decode(container_T &dest, int slot, const std::any &decoderExt={}) const
decode block at provided slot to destination vector (will be resized as needed)
static auto get(const void *head)
size_t estimateSize() const
size_t estimateSizeFromMetadata() const
do the same using metadata info
static void relocate(const char *oldHead, char *newHead, char *wrapper, size_t newsize=0)
auto expandStorage(size_t slot, size_t nElemets, T *buffer=nullptr) -> decltype(auto)
void setHeader(const H &h)
o2::ctf::CTFIOSize encodeRANSV1External(const input_IT srcBegin, const input_IT srcEnd, int slot, const std::any &encoderExt, buffer_T *buffer=nullptr, double_t sizeEstimateSafetyFactor=1)
static void readFromTree(VD &vec, TTree &tree, const std::string &name, int ev=0)
read from tree to destination buffer vector
void dump(const std::string &prefix="", int ncol=20) const
CTFIOSize decodeRansV1Impl(dst_IT dest, int slot, const std::any &decoderExt) const
ANSHeader checkANSVersion(ANSHeader ansVersion) const
void fillFlatCopy(EncodedBlocks &dest) const
Create its own flat copy in the destination empty flat object.
void copyToFlat(void *base)
copy itself to flat buffer created on the fly at the provided pointer. The destination block should b...
std::array< Block< W >, N > mBlocks
const H & getHeader() const
static size_t fillTreeBranch(TTree &tree, const std::string &brname, D &dt, int compLevel, int splitLevel=99)
add and fill single branch
auto & getMetadata(int i) const
static size_t getMinAlignedSize()
o2::ctf::CTFIOSize pack(const input_IT srcBegin, const input_IT srcEnd, int slot, buffer_T *buffer=nullptr)
static auto expand(buffer_T &buffer, size_t newsizeBytes)
expand the storage to new size in bytes
void print(const std::string &prefix="", int verbosity=1) const
print itself
o2::ctf::CTFIOSize encodeRANSV1Inplace(const input_IT srcBegin, const input_IT srcEnd, int slot, Metadata::OptStore opt, buffer_T *buffer=nullptr, double_t sizeEstimateSafetyFactor=1)
dictionaryType< source_T > getDictionary(int i, ANSHeader ansVersion=ANSVersionUnspecified) const
bool flat() const
check if flat and valid
static std::vector< char > createDictionaryBlocks(const std::vector< rans::DenseHistogram< int32_t > > &vfreq, const std::vector< Metadata > &prbits)
create a special EncodedBlocks containing only dictionaries made from provided vector of frequency ta...
const auto & getMetadata() const
static constexpr int getNBlocks()
const ANSHeader & getANSHeader() const
auto & getBlock(int i) const
bool empty() const
check if empty and valid
static auto getImage(const void *newHead)
get const image of the container wrapper, with pointers in the image relocated to new head
static bool readTreeBranch(TTree &tree, const std::string &brname, D &dt, int ev=0)
read single branch
size_t compactify()
Compactify by eliminating empty space.
CTFIOSize decodeUnpackImpl(dst_IT dest, int slot) const
std::variant< rans::RenormedSparseHistogram< source_T >, rans::RenormedDenseHistogram< source_T > > dictionaryType
o2::ctf::CTFIOSize decode(D_IT dest, int slot, const std::any &decoderExt={}) const
decode block at provided slot to destination pointer, the needed space assumed to be available
size_t size() const
total allocated size in bytes
EncodedBlocks< H, N, W > base
static auto create(VD &v)
create container from vector. Head is supposed to respect the alignment
void setANSHeader(const ANSHeader &h)
o2::ctf::CTFIOSize store(const input_IT srcBegin, const input_IT srcEnd, int slot, Metadata::OptStore opt, buffer_T *buffer=nullptr)
o2::ctf::CTFIOSize encode(const input_IT srcBegin, const input_IT srcEnd, int slot, uint8_t symbolTablePrecision, Metadata::OptStore opt, buffer_T *buffer=nullptr, const std::any &encoderExt={}, float memfc=1.f)
encode vector src to bloc at provided slot
size_t getFreeSize() const
size remaining for additional data
o2::ctf::CTFIOSize encode(const VE &src, int slot, uint8_t symbolTablePrecision, Metadata::OptStore opt, buffer_T *buffer=nullptr, const std::any &encoderExt={}, float memfc=1.f)
encode vector src to bloc at provided slot
const auto & getRegistry() const
static auto create(void *head, size_t sz)
create container from arbitrary buffer of predefined size (in bytes!!!). Head is supposed to respect ...
std::shared_ptr< H > cloneHeader() const
ANSHeader & getANSHeader()
void init(size_t sz)
setup internal structure and registry for given buffer size (in bytes!!!)
void copyToFlat(V &vec)
copy itself to flat buffer created on the fly from the vector
size_t appendToTree(TTree &tree, const std::string &name) const
attach to tree
o2::ctf::CTFIOSize entropyCodeRANSCompat(const input_IT srcBegin, const input_IT srcEnd, int slot, uint8_t symbolTablePrecision, buffer_T *buffer=nullptr, const std::any &encoderExt={}, float memfc=1.f)
std::array< Metadata, N > mMetadata
o2::ctf::CTFIOSize pack(const input_IT srcBegin, const input_IT srcEnd, int slot, rans::Metrics< typename std::iterator_traits< input_IT >::value_type > metrics, buffer_T *buffer=nullptr)
typename rans::denseEncoder_type< source_type > encoder_type
const DatasetProperties< source_type > & getDatasetProperties() const noexcept
size_t getIncompressibleSize(double_t safetyFactor=1.2) const
size_t getCompressedDatasetSize(double_t safetyFactor=1.2) const
size_t getCompressedDictionarySize(double_t safetyFactor=2) const
static decltype(auto) fromHistogram(DenseHistogram< source_T > histogram, size_t renormingPrecision=0)
functionality to maintain compatibility with previous version of this library
static factory classes for building histograms, encoders and decoders.
GLuint const GLchar * name
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * value
public interface for building and renorming histograms from source data.
constexpr bool mayPack(Metadata::OptStore opt) noexcept
constexpr bool is_iterator_v
constexpr bool mayEEncode(Metadata::OptStore opt) noexcept
constexpr size_t calculateNDestTElements(size_t nElems) noexcept
constexpr size_t PackingThreshold
constexpr int WrappersCompressionLevel
uint8_t BufferType
This is the type of the vector to be used for the EncodedBlocks buffer allocation.
constexpr ANSHeader ANSVersionCompat
constexpr ANSHeader ANSVersion1
constexpr ANSHeader ANSVersionUnspecified
size_t calculatePaddedSize(size_t nElems) noexcept
constexpr size_t Alignment
constexpr int WrappersSplitLevel
size_t alignSize(size_t sizeBytes)
align size to given diven number of bytes
T * relocatePointer(const char *oldBase, char *newBase, const T *ptr)
relocate pointer by the difference of addresses
decltype(makeEncoder::fromRenormed(RenormedDenseHistogram< source_T >{})) encoder_type
RenormedDenseHistogram< source_T > renorm(DenseHistogram< source_T > histogram, size_t newPrecision=0)
size_t getAlphabetRangeBits(const DenseHistogram< source_T > &histogram) noexcept
size_t calculateMaxBufferSizeB(size_t nElements, size_t rangeBits)
decltype(makeDecoder::fromRenormed(RenormedDenseHistogram< source_T >{})) decoder_type
constexpr uint32_t getRangeBits(T min, T max) noexcept
constexpr size_t pow2(size_t n) noexcept
void checkBounds(IT iteratorPosition, IT upperBound)
size_t sanitizeRenormingBitRange(size_t renormPrecision)
decltype(makeDenseEncoder<>::fromRenormed(RenormedDenseHistogram< source_T >{})) denseEncoder_type
decltype(makeDecoder<>::fromRenormed(RenormedDenseHistogram< source_T >{})) defaultDecoder_type
auto makeHistogramView(container_T &container, std::ptrdiff_t offset) noexcept -> HistogramView< decltype(std::begin(container))>
void unpack(const input_T *__restrict inputBegin, size_t extent, output_IT outputBegin, size_t packingWidth, typename std::iterator_traits< output_IT >::value_type offset=static_cast< typename std::iterator_traits< output_IT >::value_type >(0))
HistogramView< Hist_IT > trim(const HistogramView< Hist_IT > &buffer)
RenormedDenseHistogram< source_T > readRenormedDictionary(buffer_IT begin, buffer_IT end, source_T min, source_T max, size_t renormingPrecision)
decltype(auto) renorm(histogram_T histogram, size_t newPrecision, RenormingPolicy renormingPolicy=RenormingPolicy::Auto, size_t lowProbabilityCutoffBits=0)
RenormedSparseHistogram< source_T > readRenormedSetDictionary(buffer_IT begin, buffer_IT end, source_T min, source_T max, size_t renormingPrecision)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
std::string to_string(gsl::span< T, Size > span)
public interface for serializing histograms (dictionaries) to JSON or compressed binary.
binary blob for single entropy-compressed column: metadata + (optional) dictionary and data buffer + ...
const W * getData() const
const W * getDict() const
const W * getDataPointer() const
void storeDict(int _ndict, const W *_dict)
void storeLiterals(int _nliterals, const W *_literals)
const W * getLiterals() const
int nDict
non-persistent info for in-memory ops
const W * getEndOfBlock() const
void storeData(int _ndata, const W *_data)
void setNData(int _ndata)
void store(int _ndict, int _ndata, int _nliterals, const W *_dict, const W *_data, const W *_literals)
store binary blob data (buffer filled from head to tail)
void setNDict(int _ndict)
void setNLiterals(int _nliterals)
static size_t estimateSize(int n)
estimate free size needed to add new block
void relocate(const char *oldHead, char *newHeadData, char *newHeadRegistry)
relocate to different head position
>======================== Auxiliary classes =======================>>
int nFilledBlocks
pointer on the head of the CTF
char * getFreeBlockEnd() const
size_t getFreeSize() const
size in bytes available to fill data
size_t size
offset of the start of the writable space (wrt head), in bytes!!!
char * getFreeBlockStart() const
calculate the pointer of the head of the writable space
static constexpr size_t nStreams
static decltype(auto) fromSamples(source_IT begin, source_IT end, typename std::iterator_traits< source_IT >::value_type min, typename std::iterator_traits< source_IT >::value_type max)
static std::string concat_string(Ts const &... ts)
int estimateSize(bool withHB=false)
std::vector< o2::ctf::BufferType > vec
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
coder decode(ctfImage, triggersD, clustersD)
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))