Project
Loading...
Searching...
No Matches
DataRefUtils.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include <typeinfo>
13#include <cstring>
16#include "Framework/Logger.h"
17#include <TMemFile.h>
18#include <TTree.h>
19#include <TH1.h>
20#include <TError.h>
21#include <algorithm>
22
23namespace o2::framework
24{
25
26namespace
27{
28void* extractFromTFile(TFile& file, TClass const* cl, const char* what)
29{
30 if (!cl) {
31 return nullptr;
32 }
33 auto object = file.GetObjectChecked(what, cl);
34 if (!object) {
35 // it could be that object was stored with previous convention
36 // where the classname was taken as key
37 std::string objectName(cl->GetName());
38 objectName.erase(std::find_if(objectName.rbegin(), objectName.rend(), [](unsigned char ch) {
39 return !std::isspace(ch);
40 }).base(),
41 objectName.end());
42 objectName.erase(objectName.begin(), std::find_if(objectName.begin(), objectName.end(), [](unsigned char ch) {
43 return !std::isspace(ch);
44 }));
45
46 object = file.GetObjectChecked(objectName.c_str(), cl);
47 LOG(warn) << "Did not find object under expected name " << what;
48 if (!object) {
49 return nullptr;
50 }
51 LOG(warn) << "Found object under deprecated name " << cl->GetName();
52 }
53 auto result = object;
54 // We need to handle some specific cases as ROOT ties them deeply
55 // to the file they are contained in
56 if (cl->InheritsFrom("TObject")) {
57 // make a clone
58 // detach from the file
59 auto tree = dynamic_cast<TTree*>((TObject*)object);
60 if (tree) {
61 tree->LoadBaskets(0x1L << 32); // make tree memory based
62 tree->SetDirectory(nullptr);
63 result = tree;
64 } else {
65 auto h = dynamic_cast<TH1*>((TObject*)object);
66 if (h) {
67 h->SetDirectory(nullptr);
68 result = h;
69 }
70 }
71 }
72 return result;
73}
74} // namespace
75// Adapted from CcdbApi private method interpretAsTMemFileAndExtract
76// If the former is moved to public, throws on error and could be changed to
77// not require a mutex we could use it.
78void* DataRefUtils::decodeCCDB(DataRef const& ref, std::type_info const& tinfo)
79{
80 void* result = nullptr;
81 Int_t previousErrorLevel = gErrorIgnoreLevel;
82 gErrorIgnoreLevel = kFatal;
83 auto* dh = o2::header::get<o2::header::DataHeader*>(ref.header);
84 const char* buff = const_cast<char*>(ref.payload);
85 size_t flSize = dh->payloadSize;
86 // does it have a flattened headers map attached in the end?
87 constexpr char FlatHeaderAnnot[] = "$HEADER$";
88 constexpr int Offset = sizeof(int) + sizeof(FlatHeaderAnnot);
89 int headerSize = 0;
90 LOGP(debug, "DHPayloadSize={}>{} Ref:{}/{} Cmp {}:{}", dh->payloadSize, Offset, dh->dataOrigin.as<std::string>(), dh->dataDescription.as<std::string>(), std::string{buff + dh->payloadSize - sizeof(FlatHeaderAnnot)}, std::string{FlatHeaderAnnot});
91
92 if (dh->payloadSize >= Offset &&
93 !std::strncmp(buff + dh->payloadSize - sizeof(FlatHeaderAnnot), FlatHeaderAnnot, sizeof(FlatHeaderAnnot))) {
94 headerSize = *reinterpret_cast<const int*>(buff + dh->payloadSize - Offset);
95 }
96 if (headerSize < 0) {
97 LOGP(fatal, "Anomalous flattened header size {} extracted", headerSize);
98 }
99 TMemFile memFile("name", const_cast<char*>(ref.payload), dh->payloadSize - headerSize, "READ");
100 gErrorIgnoreLevel = previousErrorLevel;
101 if (memFile.IsZombie()) {
102 return nullptr;
103 }
104
105 TClass* tcl = TClass::GetClass(tinfo);
106 result = extractFromTFile(memFile, tcl, "ccdb_object");
107 if (!result) {
108 throw runtime_error_f("Couldn't retrieve object corresponding to %s from TFile", tcl->GetName());
109 }
110 memFile.Close();
111 return result;
112}
113
114std::map<std::string, std::string> DataRefUtils::extractCCDBHeaders(DataRef const& ref)
115{
116 auto* dh = o2::header::get<o2::header::DataHeader*>(ref.header);
117 const char* buff = const_cast<char*>(ref.payload);
118 // does it have a flattened headers map attached in the end?
119 constexpr char FlatHeaderAnnot[] = "$HEADER$";
120 constexpr int Offset = sizeof(int) + sizeof(FlatHeaderAnnot);
121 int headerSize = 0, ss0 = 0;
122 std::map<std::string, std::string> res;
123 if (dh->payloadSize >= Offset && !std::strncmp(buff + dh->payloadSize - sizeof(FlatHeaderAnnot), FlatHeaderAnnot, sizeof(FlatHeaderAnnot))) {
124 headerSize = *reinterpret_cast<const int*>(buff + dh->payloadSize - Offset);
125 } else { // header was not added
126 LOGP(warn, "CCDB headers were not added to condition object blob, returning dummy header map");
127 return res;
128 }
129
130 if (headerSize < 0) {
131 LOGP(fatal, "Anomalous flattened header size {} extracted", headerSize);
132 }
133
134 buff += dh->payloadSize - headerSize; // jump to the start of flattened header
135 headerSize -= Offset;
136 const char* str0 = &buff[ss0++];
137 while (ss0 < headerSize) {
138 if (buff[ss0++] == 0) {
139 if (!str0) {
140 str0 = &buff[ss0]; // new key string is found
141 } else {
142 res.emplace(std::string(str0), std::string(&buff[ss0])); // new value string found, add key value to the map
143 LOGP(debug, "Header{} {}:{}", res.size(), std::string(str0), std::string(&buff[ss0]));
144 str0 = nullptr;
145 }
146 }
147 }
148 return res;
149}
150
151} // namespace o2::framework
uint32_t res
Definition RawData.h:0
std::ostringstream debug
Class for time synchronization of RawReader instances.
GLuint64EXT * result
Definition glcorearb.h:5662
GLuint object
Definition glcorearb.h:4041
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
RuntimeErrorRef runtime_error_f(const char *,...)
static std::map< std::string, std::string > extractCCDBHeaders(DataRef const &ref)
static void * decodeCCDB(DataRef const &ref, std::type_info const &info)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))