The Gaudi Framework  master (ff829712)
Loading...
Searching...
No Matches
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
 
void fixNameAndDir (std::string &name, std::string &dir)
 handles cases where name includes '/' character(s) and move needed part of it to dir.
 
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
 
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
 
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
 

Function Documentation

◆ allAxisTojson()

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

Definition at line 358 of file Utils.h.

358 {
359 if constexpr ( std::is_base_of_v<TH3D, Histo> ) {
360 return { *h.GetXaxis(), *h.GetYaxis(), *h.GetZaxis() };
361 } else if constexpr ( std::is_base_of_v<TProfile2D, Histo> || std::is_base_of_v<TH2D, Histo> ) {
362 return { *h.GetXaxis(), *h.GetYaxis() };
363 } else {
364 return { *h.GetXaxis() };
365 }
366 }

◆ binsTojson()

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

Definition at line 369 of file Utils.h.

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

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

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

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

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

◆ jsonToAxis()

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

extract an Axis from json data

Definition at line 171 of file Utils.h.

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

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

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

◆ rootHistogramToJson()

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

automatic translation of Root Histograms to json

Definition at line 387 of file Utils.h.

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