The Gaudi Framework  v38r1p1 (ae26267b)
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...
 
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 283 of file Utils.h.

283  {
284  if constexpr ( std::is_base_of_v<TH3D, Histo> ) {
285  return { *h.GetXaxis(), *h.GetYaxis(), *h.GetZaxis() };
286  } else if constexpr ( std::is_base_of_v<TProfile2D, Histo> || std::is_base_of_v<TH2D, Histo> ) {
287  return { *h.GetXaxis(), *h.GetYaxis() };
288  } else {
289  return { *h.GetXaxis() };
290  }
291  }

◆ binsTojson()

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

Definition at line 294 of file Utils.h.

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

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

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

◆ jsonToAxis()

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

extract an Axis from json data

Definition at line 101 of file Utils.h.

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

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

113  {
114  // extract data from json
115  auto jsonAxis = j.at( "axis" );
116  auto axis = std::array{ jsonToAxis( jsonAxis[index] )... };
117  auto weights = j.at( "bins" ).get<std::vector<typename Traits::WeightType>>();
118  auto title = j.at( "title" ).get<std::string>();
119  auto nentries = j.at( "nEntries" ).get<unsigned int>();
120  // weird way ROOT has to give titles to axis
121  title += ( axis[index].title + ... );
122  // compute total number of bins, multiplying bins per axis
123  auto totNBins = ( ( axis[index].nBins + 2 ) * ... );
124  assert( weights.size() == totNBins );
125 
126  if ( name[0] == '/' ) {
127  dir = "";
128  name = name.substr( 1 );
129  }
130 
131  // take into account the case where name contains '/'s (e.g. "Group/Name") by
132  // moving the prefix into dir
133  if ( auto pos = name.rfind( '/' ); pos != std::string::npos ) {
134  dir += '/' + name.substr( 0, pos );
135  name = name.substr( pos + 1 );
136  }
137 
138  // Create Root histogram calling constructors with the args tuple
139  auto histo = Traits::create( name, title, axis[index]... );
140 
141  // fill Histo
142  for ( unsigned int i = 0; i < totNBins; i++ ) Traits::fill( histo, i, weights[i] );
143  // in case we have sums, overwrite them in the histogram with our more precise values
144  // FIXME This is only supporting regular histograms. It won't work in case of weighted histograms
145  if constexpr ( sizeof...( index ) == 1 ) {
146  if ( j.find( "sum" ) != j.end() ) {
147  double s[13];
148  s[0] = j.at( "nTotEntries" ).get<double>();
149  s[1] = j.at( "nTotEntries" ).get<double>();
150  s[2] = j.at( "sum" ).get<double>();
151  s[3] = j.at( "sum2" ).get<double>();
152  histo.PutStats( s );
153  }
154  } else {
155  if ( j.find( "sumx" ) != j.end() ) {
156  double s[13];
157  s[0] = j.at( "nTotEntries" ).get<double>();
158  s[1] = j.at( "nTotEntries" ).get<double>();
159  s[2] = j.at( "sumx" ).get<double>();
160  s[3] = j.at( "sumx2" ).get<double>();
161  s[4] = j.at( "sumy" ).get<double>();
162  s[5] = j.at( "sumy2" ).get<double>();
163  s[6] = j.at( "sumxy" ).get<double>();
164  if constexpr ( sizeof...( index ) > 2 ) {
165  s[7] = j.at( "sumz" ).get<double>();
166  s[8] = j.at( "sumz2" ).get<double>();
167  s[9] = j.at( "sumxz" ).get<double>();
168  s[10] = j.at( "sumyz" ).get<double>();
169  }
170  histo.PutStats( s );
171  }
172  }
173  // fill histo metadata, e.g. bins and number of entries
174  Traits::fillMetaData( histo, jsonAxis, nentries );
175  return { histo, dir };
176  }

◆ rootHistogramToJson()

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

automatic translation of Root Histograms to json

Definition at line 312 of file Utils.h.

312  {
313  bool isProfile = std::is_base_of_v<TProfile, Histo> || std::is_base_of_v<TProfile2D, Histo>;
314  std::string type = isProfile ? "histogram:ProfileHistogram:double" : "histogram:Histogram:double";
315  auto j = nlohmann::json{ { "type", type },
316  { "title", h.GetTitle() },
317  { "dimension", h.GetDimension() },
318  { "empty", (int)h.GetEntries() == 0 },
319  { "nEntries", (int)h.GetEntries() },
320  { "axis", allAxisTojson( h ) },
321  { "bins", binsTojson( h ) } };
322  if ( !isProfile ) {
323  double s[13];
324  h.GetStats( s );
325  if ( h.GetDimension() == 1 ) {
326  j["nTotEntries"] = s[0];
327  j["sum"] = s[2];
328  j["sum2"] = s[3];
329  j["mean"] = s[2] / s[0];
330  } else {
331  j["nTotEntries"] = s[0];
332  j["sumx"] = s[2];
333  j["sumx2"] = s[3];
334  j["meanx"] = s[2] / s[0];
335  j["sumy"] = s[4];
336  j["sumy2"] = s[5];
337  j["sumxy"] = s[6];
338  j["meany"] = s[4] / s[0];
339  if ( h.GetDimension() >= 3 ) {
340  j["sumz"] = s[7];
341  j["sumz2"] = s[8];
342  j["sumxz"] = s[9];
343  j["sumyz"] = s[10];
344  j["meanz"] = s[7] / s[0];
345  }
346  }
347  }
348  return j;
349  }
std::string
STL class.
gaudirun.s
string s
Definition: gaudirun.py:346
std::vector
STL class.
jsonFromLHCbLog.json
json
Definition: jsonFromLHCbLog.py:86
GaudiException
Definition: GaudiException.h:31
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:294
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:283
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:101
gaudirun.type
type
Definition: gaudirun.py:160
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:76
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