ATLAS Offline Software
Json2Cool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "Json2Cool.h"
6 
7 #include "IOVDbStringFunctions.h"
8 #include "CoolKernel/RecordSpecification.h"
9 #include "CoolKernel/Record.h"
10 #include "CoralBase/AttributeList.h"
11 #include "CoralBase/Attribute.h"
13 #include "boost/regex.hpp"
14 #include "Base64Codec.h"
15 #include <stdexcept>
16 #include <iostream>
17 
19 using namespace cool;
20 using namespace IOVDbNamespace;
21 
22 
23 namespace {
24 
25 
26 const std::map<std::string, cool::StorageType::TypeId> typeCorrespondance={
27  //http://cool-doxygen.web.cern.ch/COOL-doxygen/classcool_1_1_storage_type.html
28  {"Bool", StorageType::Bool},
29  {"UChar",StorageType::UChar},
30  {"Int16", StorageType::Int16},
31  {"UInt16", StorageType::UInt16},
32  {"Int32", StorageType::Int32},
33  {"UInt32", StorageType::UInt32},
34  {"UInt63",StorageType::UInt63},
35  {"Int64", StorageType::Int64},
36  {"Float", StorageType::Float},
37  {"Double", StorageType::Double},
38  {"String255", StorageType::String255},
39  {"String4k", StorageType::String4k},
40  {"String64k", StorageType::String64k},
41  {"String16M", StorageType::String16M},
42  {"String128M", StorageType::String128M},
43  {"Blob64k", StorageType::Blob64k},
44  {"Blob16M", StorageType::Blob16M},
45  {"Blob128M", StorageType::Blob128M}
46  };
47 
48 
49 } // anonymous namespace
50 
51 
52 namespace IOVDbNamespace{
53 
54 
55  Json2Cool::Json2Cool(std::istream & stream, BasicFolder & b, const std::string & specString, const IovStore::Iov_t* iov):m_basicFolder(b){
56  init(stream, specString, iov);
57  }
58 
59  void
60  Json2Cool::init(std::istream & s, const std::string & specString, const IovStore::Iov_t* iov){
61  if (not s.good() or s.eof()){
62  const std::string msg("Json2Cool constructor; Input is invalid and could not be opened.");
63  throw std::runtime_error(msg);
64  } else {
65  json j;
66  try{
67  s>>j; //read into json
68  }catch (const std::exception& e) {
69  std::cout<<"ERROR AT LINE "<<__LINE__<<" of "<<__FILE__<<std::endl;
70  std::cout<<e.what()<<std::endl; //typically a parsing error
71  }
72  m_sharedSpec = parsePayloadSpec(specString);
73  const auto & payload=j["data"];//payload is an object in any case, of form {"0":["datastring"]}
74  //keep these lines for reference: iov handling is not yet implemented, but should be
75  //const auto & iovFromFile=j["iov"];//iov is a two-element array
76  //const std::pair<cool::ValidityKey, cool::ValidityKey> iov(iovFromFile[0], iovFromFile[1]);
77  if(iov) {
79  }
80  else {
81  m_basicFolder.setIov(IovStore::Iov_t(0, cool::ValidityKeyMax));
82  }
84  for (json::const_iterator k=payload.begin();k!=payload.end();++k){ //k are {"0":}
85  const json& f=k.value(); //channel id
86  const std::string& ks=k.key();
87  const long long key=std::stoll(ks);
88  std::vector<coral::AttributeList> tempVector;//can optimise this by pre constructing it and using 'clear'
89  for (json::const_iterator i=f.begin();i!=f.end();++i){
90  const json& arrayElem=i.value();
91  auto r=createAttributeList(m_sharedSpec,arrayElem);
92  const auto & attList=r.attributeList();
93  tempVector.push_back(attList);
94  }
95  m_basicFolder.addChannelPayload(key, tempVector);
96  //add payload with channelId here
97  }
98  } else {
99  for (json::const_iterator i=payload.begin();i!=payload.end();++i){
100  const json& f=i.value();
101  const std::string& ks=i.key();
102  const long long key=std::stoll(ks);
104  const auto & attList=r.attributeList();
106  }
107  }
108  }
109  }
110 
111  //parsing something like
112  // "folder_payloadspec": "crate: UChar, slot: UChar, ROB: Int32, SRCid: Int32, BCIDOffset: Int16, slave0: Int32, slave1: Int32, slave2: Int32, slave3: Int32"
113  cool::RecordSpecification *
114  Json2Cool::parsePayloadSpec(const std::string & stringSpecification){
115  if (stringSpecification.empty()) return nullptr;
116  std::string input(stringSpecification);
117  auto *spec = new cool::RecordSpecification();
118 
119  std::string regex=R"delim(([^\s,:]*):\s?([^\s,]*),?)delim";
121  boost::smatch what;
122 
123  bool match=boost::regex_search(input, what, expression);
124  while (match){
125  std::string n(what[1]);
126  std::string t(what[2]);
127  //todo: need to catch error if type not found, also
128  spec->extend(n, typeCorrespondance.find(t)->second);
129  input = what.suffix();
130  match=boost::regex_search(input, what, expression);
131 
132  }
133  return spec;
134  }
135 
136  cool::Record
137  Json2Cool::createAttributeList(cool::RecordSpecification * pSpec, const nlohmann::json & j){
138  cool::Record a(*pSpec);
139  unsigned int s=a.size();
140 
141  json::const_iterator it = j.begin();
142  for (unsigned int i(0);i!=s;++i){
143  auto & f=a[i];
144  if (it == j.end()){
145  continue;
146  }
147  const auto thisVal = it.value();
148  ++it;
149 
150  try{
151  // cool::Record does not provide non-const access to AttributeList.
152  // But this is safe because we are filling a local instance.
153  auto & att ATLAS_THREAD_SAFE = const_cast<coral::Attribute&>(a.attributeList()[i]);
154  if (thisVal.is_null()){
155  att.setNull();
156  continue;
157  }
158  cool::StorageType::TypeId typespec = f.storageType().id();
159  std::string strVal = to_string(thisVal);
160  if(strVal.size()>2&& strVal[0]=='"'&& strVal[strVal.size()-1]=='"')
161  strVal=strVal.substr(1,strVal.size()-2);
162 
163  if((strVal.compare("NULL")==0||strVal.compare("null")==0)&&
164  (typespec==StorageType::Bool || typespec==StorageType::Int16 || typespec==StorageType::UInt16
165  || typespec==StorageType::Int32 || typespec==StorageType::UInt32
166  || typespec==StorageType::Int64 || typespec==StorageType::UInt63
167  || typespec==StorageType::Float || typespec==StorageType::Double)){
168  att.setNull();
169  continue;
170  }
171  switch (typespec) {
172  case StorageType::Bool:
173  {
174  const bool newVal=(strVal == "true");
175  att.setValue<bool>(newVal);
176  break;
177  }
178  case StorageType::UChar:
179  {
180  const unsigned char newVal=std::stoul(strVal);
181  att.setValue<unsigned char>(newVal);
182  break;
183  }
184  case StorageType::Int16:
185  {
186  const short newVal=std::stol(strVal);
187  att.setValue<short>(newVal);
188  break;
189  }
190  case StorageType::UInt16:
191  {
192  const unsigned short newVal=std::stoul(strVal);
193  att.setValue<unsigned short>(newVal);
194  break;
195  }
196  case StorageType::Int32:
197  {
198  const int newVal=std::stoi(strVal);
199  att.setValue<int>(newVal);
200  break;
201  }
202  case StorageType::UInt32:
203  {
204  const unsigned int newVal=std::stoull(strVal);
205  att.setValue<unsigned int>(newVal);
206  break;
207  }
208  case StorageType::UInt63:
209  {
210  const unsigned long long newVal=std::stoull(strVal);
211  att.setValue<unsigned long long>(newVal);
212  break;
213  }
214  case StorageType::Int64:
215  {
216  const long long newVal=std::stoll(strVal);
217  att.setValue< long long>(newVal);
218  break;
219  }
220  case StorageType::Float:
221  {
222  const float newVal=std::stof(strVal);
223  att.setValue<float>(newVal);
224  break;
225  }
226  case StorageType::Double:
227  {
228  const double newVal=std::stod(strVal);
229  att.setValue<double>(newVal);
230  break;
231  }
232  case StorageType::String255:
233  case StorageType::String4k:
234  case StorageType::String64k:
235  case StorageType::String16M:
236  case StorageType::String128M:
237  {
238  att.setValue<std::string>(thisVal.get<std::string>());
239  break;
240  }
241  case StorageType::Blob128M:
242  case StorageType::Blob16M:
243  case StorageType::Blob64k:
244  {
245  auto blob = base64Decode(strVal);
246  att.setValue<coral::Blob>(blob);
247  break;
248  }
249  default:
250  {
251  std::string typeName{};
252  for (auto& [key,val] : typeCorrespondance) {
253  if(val==typespec) {
254  typeName = key;
255  break;
256  }
257  }
258  if(typeName.empty()) {
259  typeName = "Unexpected Type";
260  }
261  std::string errorMessage("UNTREATED TYPE! " + typeName);
262  std::cerr << errorMessage << std::endl;
263  throw std::runtime_error(errorMessage);
264  break;
265  }
266  }
267  }
268  catch (json::exception& e){
269  std::cerr << e.what() << std::endl;
270  throw std::runtime_error(e.what());
271  }
272  }
273  return a;
274  }
275 }//end of namespace
276 
IOVDbNamespace::BasicFolder::isVectorPayload
bool isVectorPayload() const
Definition: BasicFolder.cxx:41
beamspotman.r
def r
Definition: beamspotman.py:676
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
Json2Cool.h
dqt_zlumi_alleff_HIST.iov
iov
Definition: dqt_zlumi_alleff_HIST.py:119
json
nlohmann::json json
Definition: HistogramDef.cxx:9
CaloCondBlobAlgs_fillNoiseFromASCII.spec
spec
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:47
IOVDbNamespace::Json2Cool::m_basicFolder
BasicFolder & m_basicFolder
Definition: Json2Cool.h:43
skel.it
it
Definition: skel.GENtoEVGEN.py:423
python.subdetectors.tile.Blob
Blob
Definition: tile.py:17
IOVDbNamespace::base64Decode
coral::Blob base64Decode(const std::string &base64String)
Definition: Base64Codec.cxx:26
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
IOVDbNamespace::IovStore::Iov_t
std::pair< cool::ValidityKey, cool::ValidityKey > Iov_t
Definition: IovStore.h:22
AthenaPoolTestWrite.stream
string stream
Definition: AthenaPoolTestWrite.py:12
cool
Definition: CoolTagInfo.h:12
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
IOVDbStringFunctions.h
HION12.expression
string expression
Definition: HION12.py:56
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
calibdata.exception
exception
Definition: calibdata.py:496
IOVDbNamespace::Json2Cool::parsePayloadSpec
static cool::RecordSpecification * parsePayloadSpec(const std::string &stringSpecification)
Definition: Json2Cool.cxx:114
python.ExitCodes.what
def what(code)
Definition: ExitCodes.py:73
IOVDbNamespace::BasicFolder
Definition: BasicFolder.h:21
Base64Codec.h
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
IOVDbNamespace::Json2Cool::m_sharedSpec
cool::RecordSpecification * m_sharedSpec
Definition: Json2Cool.h:42
PixelModuleFeMask_create_db.payload
string payload
Definition: PixelModuleFeMask_create_db.py:69
IOVDbNamespace::BasicFolder::addChannelPayload
void addChannelPayload(const cool::ChannelId &channelId, const std::string &name, const coral::AttributeList &payload)
Definition: BasicFolder.cxx:52
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
a
TList * a
Definition: liststreamerinfos.cxx:10
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
ReadCalibFromCool.typeName
typeName
Definition: ReadCalibFromCool.py:477
json
nlohmann::json json
Definition: Json2Cool.cxx:18
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
IOVDbNamespace::Json2Cool::createAttributeList
static cool::Record createAttributeList(cool::RecordSpecification *pSpec, const nlohmann::json &j)
Definition: Json2Cool.cxx:137
IOVDbNamespace::Json2Cool::init
void init(std::istream &stream, const std::string &specString, const IovStore::Iov_t *iov)
Definition: Json2Cool.cxx:60
checker_macros.h
Define macros for attributes used to control the static checker.
IOVDbNamespace::BasicFolder::setIov
void setIov(const std::pair< cool::ValidityKey, cool::ValidityKey > &iov)
Definition: BasicFolder.cxx:46
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
CaloCondBlobAlgs_fillNoiseFromASCII.blob
blob
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:96
match
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition: hcg.cxx:356
fitman.k
k
Definition: fitman.py:528
IOVDbNamespace
Definition: Base64Codec.cxx:16
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37