File indexing completed on 2023-03-17 11:16:07
0001 #include "PhysicsTools/NanoAOD/plugins/TableOutputBranches.h"
0002
0003 #include <iostream>
0004 #include <limits>
0005
0006 namespace {
0007 std::string makeBranchName(const std::string &baseName, const std::string &leafName) {
0008 return baseName.empty() ? leafName : (leafName.empty() ? baseName : baseName + "_" + leafName);
0009 }
0010 }
0011
0012 void TableOutputBranches::defineBranchesFromFirstEvent(const nanoaod::FlatTable &tab) {
0013 m_baseName = tab.name();
0014 for (size_t i = 0; i < tab.nColumns(); i++) {
0015 const std::string &var = tab.columnName(i);
0016 switch (tab.columnType(i)) {
0017 case nanoaod::FlatTable::ColumnType::Int8:
0018 m_int8Branches.emplace_back(var, tab.columnDoc(i), "B");
0019 break;
0020 case nanoaod::FlatTable::ColumnType::UInt8:
0021 m_uint8Branches.emplace_back(var, tab.columnDoc(i), "b");
0022 break;
0023 case nanoaod::FlatTable::ColumnType::Int16:
0024 m_int16Branches.emplace_back(var, tab.columnDoc(i), "S");
0025 break;
0026 case nanoaod::FlatTable::ColumnType::UInt16:
0027 m_uint16Branches.emplace_back(var, tab.columnDoc(i), "s");
0028 break;
0029 case nanoaod::FlatTable::ColumnType::Int32:
0030 m_int32Branches.emplace_back(var, tab.columnDoc(i), "I");
0031 break;
0032 case nanoaod::FlatTable::ColumnType::UInt32:
0033 m_uint32Branches.emplace_back(var, tab.columnDoc(i), "i");
0034 break;
0035 case nanoaod::FlatTable::ColumnType::Bool:
0036 m_uint8Branches.emplace_back(var, tab.columnDoc(i), "O");
0037 break;
0038 case nanoaod::FlatTable::ColumnType::Float:
0039 m_floatBranches.emplace_back(var, tab.columnDoc(i), "F");
0040 break;
0041 case nanoaod::FlatTable::ColumnType::Double:
0042 m_doubleBranches.emplace_back(var, tab.columnDoc(i), "D");
0043 break;
0044 default:
0045 throw cms::Exception("LogicError", "Unsupported type");
0046 }
0047 }
0048 }
0049
0050 void TableOutputBranches::branch(TTree &tree) {
0051 if (!m_singleton) {
0052 if (m_extension == IsExtension) {
0053 m_counterBranch = tree.FindBranch(("n" + m_baseName).c_str());
0054 if (!m_counterBranch) {
0055 throw cms::Exception("LogicError",
0056 "Trying to save an extension table for " + m_baseName +
0057 " before having saved the corresponding main table\n");
0058 }
0059 } else {
0060 if (tree.FindBranch(("n" + m_baseName).c_str()) != nullptr) {
0061 throw cms::Exception("LogicError", "Trying to save multiple main tables for " + m_baseName + "\n");
0062 }
0063 m_counterBranch = tree.Branch(("n" + m_baseName).c_str(), &m_counter, ("n" + m_baseName + "/I").c_str());
0064 m_counterBranch->SetTitle(m_doc.c_str());
0065 }
0066 }
0067 std::string varsize = m_singleton ? "" : "[n" + m_baseName + "]";
0068 for (std::vector<NamedBranchPtr> *branches : {&m_int8Branches,
0069 &m_uint8Branches,
0070 &m_int16Branches,
0071 &m_uint16Branches,
0072 &m_int32Branches,
0073 &m_uint32Branches,
0074 &m_floatBranches,
0075 &m_doubleBranches}) {
0076 for (auto &pair : *branches) {
0077 std::string branchName = makeBranchName(m_baseName, pair.name);
0078 pair.branch =
0079 tree.Branch(branchName.c_str(), (void *)nullptr, (branchName + varsize + "/" + pair.rootTypeCode).c_str());
0080 pair.branch->SetTitle(pair.title.c_str());
0081 }
0082 }
0083 }
0084
0085 void TableOutputBranches::fill(const edm::OccurrenceForOutput &iWhatever, TTree &tree, bool extensions) {
0086 if (m_extension != DontKnowYetIfMainOrExtension) {
0087 if (extensions != m_extension)
0088 return;
0089 }
0090
0091 edm::Handle<nanoaod::FlatTable> handle;
0092 iWhatever.getByToken(m_token, handle);
0093 const nanoaod::FlatTable &tab = *handle;
0094 auto size = tab.size();
0095
0096
0097 if (size > std::numeric_limits<CounterType>::max()) {
0098 throw cms::Exception("Table " + tab.name() + " size is " + std::to_string(size) +
0099 ", is too large for ROOT native array branch");
0100 }
0101 m_counter = size;
0102 m_singleton = tab.singleton();
0103 if (!m_branchesBooked) {
0104 m_extension = tab.extension() ? IsExtension : IsMain;
0105 if (extensions != m_extension)
0106 return;
0107 defineBranchesFromFirstEvent(tab);
0108 m_doc = tab.doc();
0109 m_branchesBooked = true;
0110 branch(tree);
0111 }
0112 if (!m_singleton && m_extension == IsExtension) {
0113 if (m_counter != *reinterpret_cast<CounterType *>(m_counterBranch->GetAddress())) {
0114 throw cms::Exception("LogicError",
0115 "Mismatch in number of entries between extension and main table for " + tab.name());
0116 }
0117 }
0118 for (auto &pair : m_int8Branches)
0119 fillColumn<int8_t>(pair, tab);
0120 for (auto &pair : m_uint8Branches)
0121 fillColumn<uint8_t>(pair, tab);
0122 for (auto &pair : m_int16Branches)
0123 fillColumn<int16_t>(pair, tab);
0124 for (auto &pair : m_uint16Branches)
0125 fillColumn<uint16_t>(pair, tab);
0126 for (auto &pair : m_int32Branches)
0127 fillColumn<int32_t>(pair, tab);
0128 for (auto &pair : m_uint32Branches)
0129 fillColumn<uint32_t>(pair, tab);
0130 for (auto &pair : m_floatBranches)
0131 fillColumn<float>(pair, tab);
0132 for (auto &pair : m_doubleBranches)
0133 fillColumn<double>(pair, tab);
0134 }