#include #include #include #include "TError.h" #include "TROOT.h" #include "TFile.h" #include "TKey.h" #include "TTree.h" #include "JSystem/JGlob.hh" #include "JLang/JEquals.hh" #include "JLang/JVectorize.hh" #include "Jeep/JeepToolkit.hh" #include "Jeep/JProperties.hh" #include "Jeep/JParser.hh" #include "Jeep/JMessage.hh" namespace { using JLANG::JEquals; /** * Auxiliary class for TTree information. */ struct tree_info : public JEquals { /** * Default constructor. */ tree_info() : name(), type(), number_of_entries(0), number_of_bytes(0), number_of_bytes_zipped(0), compression_factor(0.) {} /** * Constructor. * * \param tree TTree */ tree_info(TTree* tree) : tree_info() { if (tree != NULL) { name = tree->GetName(); number_of_entries = tree->GetEntries(); number_of_bytes = tree->GetTotBytes(); number_of_bytes_zipped = tree->GetZipBytes(); if (number_of_bytes != 0){ compression_factor = double(number_of_bytes) / number_of_bytes_zipped; } TBranch* branch = dynamic_cast(tree->GetListOfBranches()->At(0)); // KM3NeT policy if (branch != NULL) { type = branch->GetClassName(); } } } /** * Check equality. * * \param object tree type * \return true if this tree type equals given tree type; else false */ bool equals(const tree_info& object) const { return ((this->name == "" || object.name == "" || this->name == object.name) && (this->type == "" || object.type == "" || equals(this->type, object.type))); } /** * Check validity. * * \return true is valid; else false */ bool is_valid() const { return (name != "" && type != ""); } /** * Write TTree information to output stream. * * \param out output stream * \param object TTree information * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const tree_info& object) { using namespace std; return out << setw(24) << left << object.name << ' ' << setw(32) << left << object.type << ' ' << setw(10) << right << object.number_of_entries << ' ' << setw( 6) << right << (object.number_of_bytes >> 20) << " [MB] " << setw( 6) << right << (object.number_of_bytes_zipped >> 20) << " [MB] " << FIXED(5,2) << (object.compression_factor) << ' '; } std::string name; std::string type; Long64_t number_of_entries; Long64_t number_of_bytes; Long64_t number_of_bytes_zipped; double compression_factor; private: /** * Check equality of data types. * * \param first first data type * \param second second data type * \return true if first data type equals second; else false */ static bool equals(const std::string& first, const std::string& second) { using namespace std; using namespace JPP; if (first == "") { return true; } if (second == "") { return true; } if (getNamespace(first) == "" || getNamespace(second) == "") return getClassname(first) == getClassname(second); else return first == second; } }; } /** * \file * * Auxiliary program to print ROOT TTree information. * \author mdejong */ int main(int argc, char **argv) { using namespace std; using namespace JPP; vector inputFile; tree_info ta; // selection tree_info tb; // actual string key; // format int debug; JProperties format; format.insert(gmake_property(tb.name)); format.insert(gmake_property(tb.type)); format.insert(gmake_property(tb.number_of_entries)); format.insert(gmake_property(tb.number_of_bytes)); format.insert(gmake_property(tb.number_of_bytes_zipped)); format.insert(gmake_property(tb.compression_factor)); try { JProperties properties; properties.insert(gmake_property(ta.name)); properties.insert(gmake_property(ta.type)); JParser<> zap("Auxiliary program to print ROOT TTree information."); zap['f'] = make_field(inputFile); zap['@'] = make_field(properties) = JPARSER::initialised(); zap['k'] = make_field(key) = "", get_keys(format); zap['d'] = make_field(debug) = 1; zap(argc, argv); } catch(const exception &error) { FATAL(error.what() << endl); } gErrorIgnoreLevel = kFatal; inputFile = getFilenames(inputFile); int number_of_errors = 0; for (vector::const_iterator file_name = inputFile.begin(); file_name != inputFile.end(); ++file_name) { TFile* file = TFile::Open(file_name->c_str()); if (file == NULL) { ++number_of_errors; cerr << *file_name << " not opened." << endl; continue; } if (key == "") { cout << *file_name << endl; } TIter iter(file->GetListOfKeys(), kIterBackward); for (TKey* _key; (_key = (TKey*) iter.Next()) != NULL; ) { TKey* p = dynamic_cast(file->GetListOfKeys()->Before(_key)); if (p == NULL || strcmp(_key->GetName(), p->GetName()) != 0) { // select last key tb = tree_info(dynamic_cast(_key->ReadObj())); if (tb.is_valid() && ta == tb) { if (key == "") cout << tb << endl; else format.write(cout, key) << ' '; } } } file->Close(); delete file; } return (number_of_errors == 0 ? 0 : 1); }