The Gaudi Framework  v39r3 (979e3109)
Gaudi::Histograming::Sink::details Namespace Reference

Classes

struct  Axis
 Small helper struct representing the Axis of an Histogram. More...
 
struct  BinAvValue
 
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, const 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 355 of file Utils.h.

355  {
356  if constexpr ( std::is_base_of_v<TH3D, Histo> ) {
357  return { *h.GetXaxis(), *h.GetYaxis(), *h.GetZaxis() };
358  } else if constexpr ( std::is_base_of_v<TProfile2D, Histo> || std::is_base_of_v<TH2D, Histo> ) {
359  return { *h.GetXaxis(), *h.GetYaxis() };
360  } else {
361  return { *h.GetXaxis() };
362  }
363  }

◆ binsTojson()

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

Definition at line 366 of file Utils.h.

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

◆ changeDir()

TDirectory* Gaudi::Histograming::Sink::details::changeDir ( TFile &  file,
const 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 328 of file Utils.h.

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

◆ 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 178 of file Utils.h.

178  {
179  if ( name[0] == '/' ) {
180  dir = "";
181  name = name.substr( 1 );
182  }
183  // take into account the case where name contains '/'s (e.g. "Group/Name") by
184  // moving the prefix into dir
185  if ( auto pos = name.rfind( '/' ); pos != std::string::npos ) {
186  dir += '/' + name.substr( 0, pos );
187  name = name.substr( pos + 1 );
188  }
189  }

◆ jsonToAxis()

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

extract an Axis from json data

Definition at line 168 of file Utils.h.

168  {
169  return { jAxis.at( "nBins" ).get<unsigned int>(), jAxis.at( "minValue" ).get<double>(),
170  jAxis.at( "maxValue" ).get<double>(),
171  ";" + jAxis.at( "title" ).get<std::string>() }; // ";" to prepare concatenations of titles
172  }

◆ 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 195 of file Utils.h.

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

◆ rootHistogramToJson()

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

automatic translation of Root Histograms to json

Definition at line 384 of file Utils.h.

384  {
385  bool isProfile = std::is_base_of_v<TProfile, Histo> || std::is_base_of_v<TProfile2D, Histo>;
386  std::string type = isProfile ? "histogram:ProfileHistogram:double" : "histogram:Histogram:double";
387  auto j = nlohmann::json{ { "type", type },
388  { "title", h.GetTitle() },
389  { "dimension", h.GetDimension() },
390  { "empty", (int)h.GetEntries() == 0 },
391  { "nEntries", (int)h.GetEntries() },
392  { "axis", allAxisTojson( h ) },
393  { "bins", binsTojson( h ) } };
394  if ( !isProfile ) {
395  double s[13];
396  h.GetStats( s );
397  if ( h.GetDimension() == 1 ) {
398  j["nTotEntries"] = s[0];
399  j["sum"] = s[2];
400  j["sum2"] = s[3];
401  j["mean"] = s[2] / s[0];
402  } else {
403  j["nTotEntries"] = s[0];
404  j["sumx"] = s[2];
405  j["sumx2"] = s[3];
406  j["meanx"] = s[2] / s[0];
407  j["sumy"] = s[4];
408  j["sumy2"] = s[5];
409  j["sumxy"] = s[6];
410  j["meany"] = s[4] / s[0];
411  if ( h.GetDimension() >= 3 ) {
412  j["sumz"] = s[7];
413  j["sumz2"] = s[8];
414  j["sumxz"] = s[9];
415  j["sumyz"] = s[10];
416  j["meanz"] = s[7] / s[0];
417  }
418  }
419  }
420  return j;
421  }
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:178
ranges
Definition: details.h:29
gaudirun.c
c
Definition: gaudirun.py:525
Gaudi::Histograming::Sink::details::binsTojson
nlohmann::json binsTojson(Histo const &h)
Definition: Utils.h:366
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:355
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:168
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