The Gaudi Framework  v39r1 (adb068b2)
Gaudi::Histograming::Sink::details Namespace Reference

Classes

struct  Axis
 Small helper struct representing the Axis of an Histogram. More...
 
struct  ProfileWrapper
 helper Wrapper around TProfileX to be able to fill it More...
 
struct  TraitsBase
 Common base for Traits dealing with Histogram conversions to Root Provides generic implementation for creating the histogram and filling meta data The filling (method fill) is not implemented. More...
 

Functions

Axis jsonToAxis (nlohmann::json &jAxis)
 extract an Axis from json data More...
 
void fixNameAndDir (std::string &name, std::string &dir)
 handles cases where name includes '/' character(s) and move needed part of it to dir. More...
 
template<typename Traits , std::size_t... index>
std::tuple< typename Traits::Histo, std::stringjsonToRootHistogramInternal (std::string &dir, std::string &name, nlohmann::json const &j, std::index_sequence< index... >)
 generic function to convert json to a ROOT Histogram - internal implementation More...
 
TDirectory * changeDir (TFile &file, std::string dir)
 changes to the ROOT directory given in the current ROOT file and returns the current directory before the change More...
 
template<typename Histo >
nlohmann::json allAxisTojson (Histo const &h)
 
template<typename Histo >
nlohmann::json binsTojson (Histo const &h)
 
template<typename Histo >
nlohmann::json rootHistogramToJson (Histo const &h)
 automatic translation of Root Histograms to json More...
 

Function Documentation

◆ allAxisTojson()

template<typename Histo >
nlohmann::json Gaudi::Histograming::Sink::details::allAxisTojson ( Histo const &  h)

Definition at line 346 of file Utils.h.

346  {
347  if constexpr ( std::is_base_of_v<TH3D, Histo> ) {
348  return { *h.GetXaxis(), *h.GetYaxis(), *h.GetZaxis() };
349  } else if constexpr ( std::is_base_of_v<TProfile2D, Histo> || std::is_base_of_v<TH2D, Histo> ) {
350  return { *h.GetXaxis(), *h.GetYaxis() };
351  } else {
352  return { *h.GetXaxis() };
353  }
354  }

◆ binsTojson()

template<typename Histo >
nlohmann::json Gaudi::Histograming::Sink::details::binsTojson ( Histo const &  h)

Definition at line 357 of file Utils.h.

357  {
358  if constexpr ( std::is_base_of_v<TProfile, Histo> || std::is_base_of_v<TProfile2D, Histo> ) {
360  // ROOT TProfile interface being completely inconsistent, we have to play
361  // with different ways to access values of the histogram... one per value !
362  auto* sums = h.GetArray();
363  auto* sums2 = h.GetSumw2();
364  for ( unsigned long n = 0; n < (unsigned long)h.GetSize(); n++ ) {
365  j.push_back( nlohmann::json{ { h.GetBinEntries( n ), sums[n] }, sums2->At( n ) } );
366  }
367  return j;
368  } else {
369  return gsl::span{ h.GetArray(), (unsigned long)h.GetSize() };
370  }
371  }

◆ changeDir()

TDirectory* Gaudi::Histograming::Sink::details::changeDir ( TFile &  file,
std::string  dir 
)
inline

changes to the ROOT directory given in the current ROOT file and returns the current directory before the change

Definition at line 319 of file Utils.h.

319  {
320  // remember the current directory
321  auto previousDir = gDirectory;
322  // find or create the directory for the histogram
323  using namespace ranges;
324  auto is_delimiter = []( auto c ) { return c == '/' || c == '.'; };
325  auto transform_to_string = views::transform( []( auto&& rng ) { return rng | to<std::string>; } );
326  auto currentDir = accumulate( dir | views::split_when( is_delimiter ) | transform_to_string,
327  file.GetDirectory( "" ), []( auto current, auto&& dir_level ) {
328  if ( current ) {
329  // try to get next level
330  auto nextDir = current->GetDirectory( dir_level.c_str() );
331  // if it does not exist, create it
332  if ( !nextDir ) nextDir = current->mkdir( dir_level.c_str() );
333  // move to next level
334  current = nextDir;
335  }
336  return current;
337  } );
338  if ( !currentDir )
339  throw GaudiException( "Could not create directory " + dir, "Histogram::Sink::Root", StatusCode::FAILURE );
340  // switch to the directory
341  currentDir->cd();
342  return previousDir;
343  }

◆ fixNameAndDir()

void Gaudi::Histograming::Sink::details::fixNameAndDir ( std::string name,
std::string dir 
)
inline

handles cases where name includes '/' character(s) and move needed part of it to dir.

Also handle case of absolute names

Definition at line 169 of file Utils.h.

169  {
170  if ( name[0] == '/' ) {
171  dir = "";
172  name = name.substr( 1 );
173  }
174  // take into account the case where name contains '/'s (e.g. "Group/Name") by
175  // moving the prefix into dir
176  if ( auto pos = name.rfind( '/' ); pos != std::string::npos ) {
177  dir += '/' + name.substr( 0, pos );
178  name = name.substr( pos + 1 );
179  }
180  }

◆ jsonToAxis()

Axis Gaudi::Histograming::Sink::details::jsonToAxis ( nlohmann::json &  jAxis)
inline

extract an Axis from json data

Definition at line 159 of file Utils.h.

159  {
160  return { jAxis.at( "nBins" ).get<unsigned int>(), jAxis.at( "minValue" ).get<double>(),
161  jAxis.at( "maxValue" ).get<double>(),
162  ";" + jAxis.at( "title" ).get<std::string>() }; // ";" to prepare concatenations of titles
163  }

◆ jsonToRootHistogramInternal()

template<typename Traits , std::size_t... index>
std::tuple<typename Traits::Histo, std::string> Gaudi::Histograming::Sink::details::jsonToRootHistogramInternal ( std::string dir,
std::string name,
nlohmann::json const &  j,
std::index_sequence< index... >   
)

generic function to convert json to a ROOT Histogram - internal implementation

Definition at line 186 of file Utils.h.

188  {
189  // extract data from json
190  auto jsonAxis = j.at( "axis" );
191  auto axis = std::array{ jsonToAxis( jsonAxis[index] )... };
192  auto weights = j.at( "bins" ).get<typename Traits::WeightType>();
193  auto title = j.at( "title" ).get<std::string>();
194  auto nentries = j.at( "nEntries" ).get<unsigned int>();
195  // weird way ROOT has to give titles to axis
196  title += ( axis[index].title + ... );
197  // compute total number of bins, multiplying bins per axis
198  auto totNBins = ( ( axis[index].nBins + 2 ) * ... );
199  // fix name and dir if needed
200  fixNameAndDir( name, dir );
201  // Create Root histogram calling constructors with the args tuple
202  auto histo = Traits::create( name, title, axis[index]... );
203  // fill Histo
204  Traits::fill( histo, totNBins, weights );
205  // in case we have sums, overwrite them in the histogram with our more precise values
206  // FIXME This is only supporting regular histograms. It won't work in case of weighted histograms
207  if constexpr ( sizeof...( index ) == 1 ) {
208  if ( j.find( "sum" ) != j.end() ) {
209  double s[13];
210  s[0] = j.at( "nTotEntries" ).get<double>();
211  s[1] = j.at( "nTotEntries" ).get<double>();
212  s[2] = j.at( "sum" ).get<double>();
213  s[3] = j.at( "sum2" ).get<double>();
214  histo.PutStats( s );
215  }
216  } else {
217  if ( j.find( "sumx" ) != j.end() ) {
218  double s[13];
219  s[0] = j.at( "nTotEntries" ).get<double>();
220  s[1] = j.at( "nTotEntries" ).get<double>();
221  s[2] = j.at( "sumx" ).get<double>();
222  s[3] = j.at( "sumx2" ).get<double>();
223  s[4] = j.at( "sumy" ).get<double>();
224  s[5] = j.at( "sumy2" ).get<double>();
225  s[6] = j.at( "sumxy" ).get<double>();
226  if constexpr ( sizeof...( index ) > 2 ) {
227  s[7] = j.at( "sumz" ).get<double>();
228  s[8] = j.at( "sumz2" ).get<double>();
229  s[9] = j.at( "sumxz" ).get<double>();
230  s[10] = j.at( "sumyz" ).get<double>();
231  }
232  histo.PutStats( s );
233  }
234  }
235  // fill histo metadata, e.g. bins and number of entries
236  Traits::fillMetaData( histo, jsonAxis, nentries );
237  return { histo, dir };
238  }

◆ rootHistogramToJson()

template<typename Histo >
nlohmann::json Gaudi::Histograming::Sink::details::rootHistogramToJson ( Histo const &  h)

automatic translation of Root Histograms to json

Definition at line 375 of file Utils.h.

375  {
376  bool isProfile = std::is_base_of_v<TProfile, Histo> || std::is_base_of_v<TProfile2D, Histo>;
377  std::string type = isProfile ? "histogram:ProfileHistogram:double" : "histogram:Histogram:double";
378  auto j = nlohmann::json{ { "type", type },
379  { "title", h.GetTitle() },
380  { "dimension", h.GetDimension() },
381  { "empty", (int)h.GetEntries() == 0 },
382  { "nEntries", (int)h.GetEntries() },
383  { "axis", allAxisTojson( h ) },
384  { "bins", binsTojson( h ) } };
385  if ( !isProfile ) {
386  double s[13];
387  h.GetStats( s );
388  if ( h.GetDimension() == 1 ) {
389  j["nTotEntries"] = s[0];
390  j["sum"] = s[2];
391  j["sum2"] = s[3];
392  j["mean"] = s[2] / s[0];
393  } else {
394  j["nTotEntries"] = s[0];
395  j["sumx"] = s[2];
396  j["sumx2"] = s[3];
397  j["meanx"] = s[2] / s[0];
398  j["sumy"] = s[4];
399  j["sumy2"] = s[5];
400  j["sumxy"] = s[6];
401  j["meany"] = s[4] / s[0];
402  if ( h.GetDimension() >= 3 ) {
403  j["sumz"] = s[7];
404  j["sumz2"] = s[8];
405  j["sumxz"] = s[9];
406  j["sumyz"] = s[10];
407  j["meanz"] = s[7] / s[0];
408  }
409  }
410  }
411  return j;
412  }
std::string
STL class.
gaudirun.s
string s
Definition: gaudirun.py:346
jsonFromLHCbLog.json
json
Definition: jsonFromLHCbLog.py:86
GaudiException
Definition: GaudiException.h:31
Gaudi::Histograming::Sink::details::fixNameAndDir
void fixNameAndDir(std::string &name, std::string &dir)
handles cases where name includes '/' character(s) and move needed part of it to dir.
Definition: Utils.h:169
ranges
Definition: details.h:30
gaudirun.c
c
Definition: gaudirun.py:525
Gaudi::Histograming::Sink::details::binsTojson
nlohmann::json binsTojson(Histo const &h)
Definition: Utils.h:357
ProduceConsume.j
j
Definition: ProduceConsume.py:104
AlgSequencer.h
h
Definition: AlgSequencer.py:31
std::array
STL class.
Gaudi::Histograming::Sink::details::allAxisTojson
nlohmann::json allAxisTojson(Histo const &h)
Definition: Utils.h:346
cpluginsvc.n
n
Definition: cpluginsvc.py:234
Gaudi::Histograming::Sink::details::jsonToAxis
Axis jsonToAxis(nlohmann::json &jAxis)
extract an Axis from json data
Definition: Utils.h:159
gaudirun.type
type
Definition: gaudirun.py:160
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
Gaudi::Accumulators::accumulate
void accumulate(Counter &counter, const Container &container, Fun f=Identity{})
A helper function for accumulating data from a container into a counter This is internally using buff...
Definition: Accumulators.h:1242
Gaudi::ParticleProperties::index
size_t index(const Gaudi::ParticleProperty *property, const Gaudi::Interfaces::IParticlePropertySvc *service)
helper utility for mapping of Gaudi::ParticleProperty object into non-negative integral sequential id...
Definition: IParticlePropertySvc.cpp:39