The Gaudi Framework  v38r0 (2143aa4c)
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 281 of file Utils.h.

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

◆ binsTojson()

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

Definition at line 292 of file Utils.h.

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

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

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

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

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