The Gaudi Framework  v39r2 (37c0b60a)
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, 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 354 of file Utils.h.

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

◆ binsTojson()

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

Definition at line 365 of file Utils.h.

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

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

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

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

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

◆ jsonToAxis()

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

extract an Axis from json data

Definition at line 167 of file Utils.h.

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

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

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

◆ rootHistogramToJson()

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

automatic translation of Root Histograms to json

Definition at line 383 of file Utils.h.

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