The Gaudi Framework  v40r0 (475e45c1)
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::string > 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 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 365 of file Utils.h.

365  {
366  if constexpr ( std::is_base_of_v<TH3D, Histo> ) {
367  return { *h.GetXaxis(), *h.GetYaxis(), *h.GetZaxis() };
368  } else if constexpr ( std::is_base_of_v<TProfile2D, Histo> || std::is_base_of_v<TH2D, Histo> ) {
369  return { *h.GetXaxis(), *h.GetYaxis() };
370  } else {
371  return { *h.GetXaxis() };
372  }
373  }

◆ binsTojson()

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

Definition at line 376 of file Utils.h.

376  {
377  if constexpr ( std::is_base_of_v<TProfile, Histo> || std::is_base_of_v<TProfile2D, Histo> ) {
379  // ROOT TProfile interface being completely inconsistent, we have to play
380  // with different ways to access values of the histogram... one per value !
381  auto* sums = h.GetArray();
382  auto* sums2 = h.GetSumw2();
383  for ( unsigned long n = 0; n < (unsigned long)h.GetSize(); n++ ) {
384  j.push_back( nlohmann::json{ { h.GetBinEntries( n ), sums[n] }, sums2->At( n ) } );
385  }
386  return j;
387  } else {
388  return gsl::span{ h.GetArray(), (unsigned long)h.GetSize() };
389  }
390  }

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

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

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

188  {
189  if ( name[0] == '/' ) {
190  dir = "";
191  name = name.substr( 1 );
192  }
193  // take into account the case where name contains '/'s (e.g. "Group/Name") by
194  // moving the prefix into dir
195  if ( auto pos = name.rfind( '/' ); pos != std::string::npos ) {
196  dir += '/' + name.substr( 0, pos );
197  name = name.substr( pos + 1 );
198  }
199  }

◆ jsonToAxis()

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

extract an Axis from json data

Definition at line 178 of file Utils.h.

178  {
179  return { jAxis.at( "nBins" ).get<unsigned int>(), jAxis.at( "minValue" ).get<double>(),
180  jAxis.at( "maxValue" ).get<double>(),
181  ";" + jAxis.at( "title" ).get<std::string>() }; // ";" to prepare concatenations of titles
182  }

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

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

◆ rootHistogramToJson()

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

automatic translation of Root Histograms to json

Definition at line 394 of file Utils.h.

394  {
395  bool isProfile = std::is_base_of_v<TProfile, Histo> || std::is_base_of_v<TProfile2D, Histo>;
396  std::string type = isProfile ? "histogram:ProfileHistogram:double" : "histogram:Histogram:double";
397  auto j = nlohmann::json{ { "type", type },
398  { "title", h.GetTitle() },
399  { "dimension", h.GetDimension() },
400  { "empty", (int)h.GetEntries() == 0 },
401  { "nEntries", (int)h.GetEntries() },
402  { "axis", allAxisTojson( h ) },
403  { "bins", binsTojson( h ) } };
404  if ( !isProfile ) {
405  double s[13];
406  h.GetStats( s );
407  if ( h.GetDimension() == 1 ) {
408  j["nTotEntries"] = s[0];
409  j["sum"] = s[2];
410  j["sum2"] = s[3];
411  j["mean"] = s[2] / s[0];
412  } else {
413  j["nTotEntries"] = s[0];
414  j["sumx"] = s[2];
415  j["sumx2"] = s[3];
416  j["meanx"] = s[2] / s[0];
417  j["sumy"] = s[4];
418  j["sumy2"] = s[5];
419  j["sumxy"] = s[6];
420  j["meany"] = s[4] / s[0];
421  if ( h.GetDimension() >= 3 ) {
422  j["sumz"] = s[7];
423  j["sumz2"] = s[8];
424  j["sumxz"] = s[9];
425  j["sumyz"] = s[10];
426  j["meanz"] = s[7] / s[0];
427  }
428  }
429  }
430  return j;
431  }
gaudirun.s
string s
Definition: gaudirun.py:346
jsonFromLHCbLog.json
json
Definition: jsonFromLHCbLog.py:86
GaudiException
Definition: GaudiException.h:29
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:188
ranges
Definition: details.h:33
gaudirun.c
c
Definition: gaudirun.py:525
Gaudi::Histograming::Sink::details::binsTojson
nlohmann::json binsTojson(Histo const &h)
Definition: Utils.h:376
ProduceConsume.j
j
Definition: ProduceConsume.py:104
AlgSequencer.h
h
Definition: AlgSequencer.py:31
Gaudi::Histograming::Sink::details::allAxisTojson
nlohmann::json allAxisTojson(Histo const &h)
Definition: Utils.h:365
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:178
gaudirun.type
type
Definition: gaudirun.py:160
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
Containers::array
struct GAUDI_API array
Parametrisation class for redirection array - like implementation.
Definition: KeyedObjectManager.h:29
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:100
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:1229
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