The Gaudi Framework  v38r3 (c3fc9673)
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 291 of file Utils.h.

291  {
292  if constexpr ( std::is_base_of_v<TH3D, Histo> ) {
293  return { *h.GetXaxis(), *h.GetYaxis(), *h.GetZaxis() };
294  } else if constexpr ( std::is_base_of_v<TProfile2D, Histo> || std::is_base_of_v<TH2D, Histo> ) {
295  return { *h.GetXaxis(), *h.GetYaxis() };
296  } else {
297  return { *h.GetXaxis() };
298  }
299  }

◆ binsTojson()

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

Definition at line 302 of file Utils.h.

302  {
303  if constexpr ( std::is_base_of_v<TProfile, Histo> || std::is_base_of_v<TProfile2D, Histo> ) {
305  // ROOT TProfile interface being completely inconsistent, we have to play
306  // with different ways to access values of the histogram... one per value !
307  auto* sums = h.GetArray();
308  auto* sums2 = h.GetSumw2();
309  for ( unsigned long n = 0; n < (unsigned long)h.GetSize(); n++ ) {
310  j.push_back( nlohmann::json{ { h.GetBinEntries( n ), sums[n] }, sums2->At( n ) } );
311  }
312  return j;
313  } else {
314  return gsl::span{ h.GetArray(), (unsigned long)h.GetSize() };
315  }
316  }

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

264  {
265  // remember the current directory
266  auto previousDir = gDirectory;
267  // find or create the directory for the histogram
268  using namespace ranges;
269  auto is_delimiter = []( auto c ) { return c == '/' || c == '.'; };
270  auto transform_to_string = views::transform( []( auto&& rng ) { return rng | to<std::string>; } );
271  auto currentDir = accumulate( dir | views::split_when( is_delimiter ) | transform_to_string,
272  file.GetDirectory( "" ), []( auto current, auto&& dir_level ) {
273  if ( current ) {
274  // try to get next level
275  auto nextDir = current->GetDirectory( dir_level.c_str() );
276  // if it does not exist, create it
277  if ( !nextDir ) nextDir = current->mkdir( dir_level.c_str() );
278  // move to next level
279  current = nextDir;
280  }
281  return current;
282  } );
283  if ( !currentDir )
284  throw GaudiException( "Could not create directory " + dir, "Histogram::Sink::Root", StatusCode::FAILURE );
285  // switch to the directory
286  currentDir->cd();
287  return previousDir;
288  }

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

114  {
115  if ( name[0] == '/' ) {
116  dir = "";
117  name = name.substr( 1 );
118  }
119  // take into account the case where name contains '/'s (e.g. "Group/Name") by
120  // moving the prefix into dir
121  if ( auto pos = name.rfind( '/' ); pos != std::string::npos ) {
122  dir += '/' + name.substr( 0, pos );
123  name = name.substr( pos + 1 );
124  }
125  }

◆ jsonToAxis()

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

extract an Axis from json data

Definition at line 104 of file Utils.h.

104  {
105  return { jAxis.at( "nBins" ).get<unsigned int>(), jAxis.at( "minValue" ).get<double>(),
106  jAxis.at( "maxValue" ).get<double>(),
107  ";" + jAxis.at( "title" ).get<std::string>() }; // ";" to prepare concatenations of titles
108  }

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

133  {
134  // extract data from json
135  auto jsonAxis = j.at( "axis" );
136  auto axis = std::array{ jsonToAxis( jsonAxis[index] )... };
137  auto weights = j.at( "bins" ).get<typename Traits::WeightType>();
138  auto title = j.at( "title" ).get<std::string>();
139  auto nentries = j.at( "nEntries" ).get<unsigned int>();
140  // weird way ROOT has to give titles to axis
141  title += ( axis[index].title + ... );
142  // compute total number of bins, multiplying bins per axis
143  auto totNBins = ( ( axis[index].nBins + 2 ) * ... );
144  // fix name and dir if needed
145  fixNameAndDir( name, dir );
146  // Create Root histogram calling constructors with the args tuple
147  auto histo = Traits::create( name, title, axis[index]... );
148  // fill Histo
149  Traits::fill( histo, totNBins, weights );
150  // in case we have sums, overwrite them in the histogram with our more precise values
151  // FIXME This is only supporting regular histograms. It won't work in case of weighted histograms
152  if constexpr ( sizeof...( index ) == 1 ) {
153  if ( j.find( "sum" ) != j.end() ) {
154  double s[13];
155  s[0] = j.at( "nTotEntries" ).get<double>();
156  s[1] = j.at( "nTotEntries" ).get<double>();
157  s[2] = j.at( "sum" ).get<double>();
158  s[3] = j.at( "sum2" ).get<double>();
159  histo.PutStats( s );
160  }
161  } else {
162  if ( j.find( "sumx" ) != j.end() ) {
163  double s[13];
164  s[0] = j.at( "nTotEntries" ).get<double>();
165  s[1] = j.at( "nTotEntries" ).get<double>();
166  s[2] = j.at( "sumx" ).get<double>();
167  s[3] = j.at( "sumx2" ).get<double>();
168  s[4] = j.at( "sumy" ).get<double>();
169  s[5] = j.at( "sumy2" ).get<double>();
170  s[6] = j.at( "sumxy" ).get<double>();
171  if constexpr ( sizeof...( index ) > 2 ) {
172  s[7] = j.at( "sumz" ).get<double>();
173  s[8] = j.at( "sumz2" ).get<double>();
174  s[9] = j.at( "sumxz" ).get<double>();
175  s[10] = j.at( "sumyz" ).get<double>();
176  }
177  histo.PutStats( s );
178  }
179  }
180  // fill histo metadata, e.g. bins and number of entries
181  Traits::fillMetaData( histo, jsonAxis, nentries );
182  return { histo, dir };
183  }

◆ rootHistogramToJson()

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

automatic translation of Root Histograms to json

Definition at line 320 of file Utils.h.

320  {
321  bool isProfile = std::is_base_of_v<TProfile, Histo> || std::is_base_of_v<TProfile2D, Histo>;
322  std::string type = isProfile ? "histogram:ProfileHistogram:double" : "histogram:Histogram:double";
323  auto j = nlohmann::json{ { "type", type },
324  { "title", h.GetTitle() },
325  { "dimension", h.GetDimension() },
326  { "empty", (int)h.GetEntries() == 0 },
327  { "nEntries", (int)h.GetEntries() },
328  { "axis", allAxisTojson( h ) },
329  { "bins", binsTojson( h ) } };
330  if ( !isProfile ) {
331  double s[13];
332  h.GetStats( s );
333  if ( h.GetDimension() == 1 ) {
334  j["nTotEntries"] = s[0];
335  j["sum"] = s[2];
336  j["sum2"] = s[3];
337  j["mean"] = s[2] / s[0];
338  } else {
339  j["nTotEntries"] = s[0];
340  j["sumx"] = s[2];
341  j["sumx2"] = s[3];
342  j["meanx"] = s[2] / s[0];
343  j["sumy"] = s[4];
344  j["sumy2"] = s[5];
345  j["sumxy"] = s[6];
346  j["meany"] = s[4] / s[0];
347  if ( h.GetDimension() >= 3 ) {
348  j["sumz"] = s[7];
349  j["sumz2"] = s[8];
350  j["sumxz"] = s[9];
351  j["sumyz"] = s[10];
352  j["meanz"] = s[7] / s[0];
353  }
354  }
355  }
356  return j;
357  }
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:114
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:302
ProduceConsume.j
j
Definition: ProduceConsume.py:101
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:291
GaudiPluginService.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:104
gaudirun.type
type
Definition: gaudirun.py:160
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
Gaudi::Utils::Histos::fill
GAUDI_API void fill(AIDA::IHistogram1D *histo, const double value, const double weight=1.0)
simple function to fill AIDA::IHistogram1D objects
Definition: Fill.cpp:45
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:1239
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