File indexing completed on 2025-01-31 02:18:54
0001 #include "ShallowTree.h"
0002
0003 #include "FWCore/Framework/interface/ProductSelector.h"
0004 #include "FWCore/Framework/interface/ProductSelectorRules.h"
0005
0006 #include <map>
0007 #include <TBranch.h>
0008
0009 ShallowTree::ShallowTree(const edm::ParameterSet& iConfig) {
0010 usesResource(TFileService::kSharedResource);
0011
0012
0013 int compSettings = iConfig.getUntrackedParameter<int>("CompressionSettings", -1);
0014 edm::Service<TFileService> fs;
0015 if (compSettings > 0)
0016 fs->file().SetCompressionSettings(compSettings);
0017 tree_ = fs->make<TTree>("tree", "");
0018
0019 std::map<std::string, LEAFTYPE> leafmap;
0020 leafmap["bool"] = BOOL;
0021 leafmap["bools"] = BOOL_V;
0022 leafmap["short int"] = SHORT;
0023 leafmap["shorts"] = SHORT_V;
0024 leafmap["ushort int"] = U_SHORT;
0025 leafmap["ushorts"] = U_SHORT_V;
0026 leafmap["int"] = INT;
0027 leafmap["ints"] = INT_V;
0028 leafmap["uint"] = U_INT;
0029 leafmap["uints"] = U_INT_V;
0030 leafmap["float"] = FLOAT;
0031 leafmap["floats"] = FLOAT_V;
0032 leafmap["double"] = DOUBLE;
0033 leafmap["doubles"] = DOUBLE_V;
0034 leafmap["lint"] = LONG;
0035 leafmap["longs"] = LONG_V;
0036 leafmap["ulint"] = U_LONG;
0037 leafmap["ulongs"] = U_LONG_V;
0038 leafmap["char"] = CHAR;
0039 leafmap["chars"] = CHAR_V;
0040 leafmap["uchar"] = U_CHAR;
0041 leafmap["uchars"] = U_CHAR_V;
0042
0043 edm::ProductSelectorRules productSelectorRules(iConfig, "outputCommands", "ShallowTree");
0044
0045 std::set<std::string> branchnames;
0046 callWhenNewProductsRegistered(
0047 [productSelectorRules, branchnames, leafmap, this](edm::ProductDescription const& selection) mutable {
0048 if (productSelectorRules.select(selection)) {
0049
0050 if (branchnames.find(selection.productInstanceName()) != branchnames.end()) {
0051 throw edm::Exception(edm::errors::Configuration)
0052 << "More than one branch named: " << selection.productInstanceName() << std::endl
0053 << "Exception thrown from ShallowTree::ShallowTree" << std::endl;
0054 } else {
0055 branchnames.insert(selection.productInstanceName());
0056 }
0057
0058
0059 switch (leafmap.find(selection.friendlyClassName())->second) {
0060 case BOOL:
0061 connectors_.push_back(std::make_unique<TypedBranchConnector<bool>>(&selection, "/O", tree_));
0062 eat<bool>(selection);
0063 break;
0064 case BOOL_V:
0065 connectors_.push_back(std::make_unique<TypedBranchConnector<std::vector<bool>>>(&selection, "", tree_));
0066 eat<std::vector<bool>>(selection);
0067 break;
0068 case INT:
0069 connectors_.push_back(std::make_unique<TypedBranchConnector<int>>(&selection, "/I", tree_));
0070 eat<int>(selection);
0071 break;
0072 case INT_V:
0073 connectors_.push_back(std::make_unique<TypedBranchConnector<std::vector<int>>>(&selection, "", tree_));
0074 eat<std::vector<int>>(selection);
0075 break;
0076 case U_INT:
0077 connectors_.push_back(std::make_unique<TypedBranchConnector<unsigned int>>(&selection, "/i", tree_));
0078 eat<unsigned int>(selection);
0079 break;
0080 case U_INT_V:
0081 connectors_.push_back(
0082 std::make_unique<TypedBranchConnector<std::vector<unsigned int>>>(&selection, "", tree_));
0083 eat<std::vector<unsigned int>>(selection);
0084 break;
0085 case SHORT:
0086 connectors_.push_back(std::make_unique<TypedBranchConnector<short>>(&selection, "/S", tree_));
0087 eat<short>(selection);
0088 break;
0089 case SHORT_V:
0090 connectors_.push_back(std::make_unique<TypedBranchConnector<std::vector<short>>>(&selection, "", tree_));
0091 eat<std::vector<short>>(selection);
0092 break;
0093 case U_SHORT:
0094 connectors_.push_back(std::make_unique<TypedBranchConnector<unsigned short>>(&selection, "/s", tree_));
0095 eat<unsigned short>(selection);
0096 break;
0097 case U_SHORT_V:
0098 connectors_.push_back(
0099 std::make_unique<TypedBranchConnector<std::vector<unsigned short>>>(&selection, "", tree_));
0100 eat<std::vector<unsigned short>>(selection);
0101 break;
0102 case FLOAT:
0103 connectors_.push_back(std::make_unique<TypedBranchConnector<float>>(&selection, "/F", tree_));
0104 eat<float>(selection);
0105 break;
0106 case FLOAT_V:
0107 connectors_.push_back(std::make_unique<TypedBranchConnector<std::vector<float>>>(&selection, "", tree_));
0108 eat<std::vector<float>>(selection);
0109 break;
0110 case DOUBLE:
0111 connectors_.push_back(std::make_unique<TypedBranchConnector<double>>(&selection, "/D", tree_));
0112 eat<double>(selection);
0113 break;
0114 case DOUBLE_V:
0115 connectors_.push_back(std::make_unique<TypedBranchConnector<std::vector<double>>>(&selection, "", tree_));
0116 eat<std::vector<double>>(selection);
0117 break;
0118 case LONG:
0119 connectors_.push_back(std::make_unique<TypedBranchConnector<long>>(&selection, "/L", tree_));
0120 eat<long>(selection);
0121 break;
0122 case LONG_V:
0123 connectors_.push_back(std::make_unique<TypedBranchConnector<std::vector<long>>>(&selection, "", tree_));
0124 eat<std::vector<long>>(selection);
0125 break;
0126 case U_LONG:
0127 connectors_.push_back(std::make_unique<TypedBranchConnector<unsigned long>>(&selection, "/l", tree_));
0128 eat<unsigned long>(selection);
0129 break;
0130 case U_LONG_V:
0131 connectors_.push_back(
0132 std::make_unique<TypedBranchConnector<std::vector<unsigned long>>>(&selection, "", tree_));
0133 eat<std::vector<unsigned long>>(selection);
0134 break;
0135 case CHAR:
0136 connectors_.push_back(std::make_unique<TypedBranchConnector<char>>(&selection, "/B", tree_));
0137 eat<char>(selection);
0138 break;
0139 case CHAR_V:
0140 connectors_.push_back(std::make_unique<TypedBranchConnector<std::vector<char>>>(&selection, "", tree_));
0141 eat<std::vector<char>>(selection);
0142 break;
0143 case U_CHAR:
0144 connectors_.push_back(std::make_unique<TypedBranchConnector<unsigned char>>(&selection, "/b", tree_));
0145 eat<unsigned char>(selection);
0146 break;
0147 case U_CHAR_V:
0148 connectors_.push_back(
0149 std::make_unique<TypedBranchConnector<std::vector<unsigned char>>>(&selection, "", tree_));
0150 eat<std::vector<unsigned char>>(selection);
0151 break;
0152 default: {
0153 std::string leafstring = "";
0154 typedef std::pair<std::string, LEAFTYPE> pair_t;
0155 for (const auto& leaf : leafmap) {
0156 leafstring += "\t" + leaf.first + "\n";
0157 }
0158
0159 throw edm::Exception(edm::errors::Configuration)
0160 << "class ShallowTree does not handle leaves of type " << selection.className() << " like\n"
0161 << selection.friendlyClassName() << "_" << selection.moduleLabel() << "_"
0162 << selection.productInstanceName() << "_" << selection.processName() << std::endl
0163 << "Valid leaf types are (friendlyClassName):\n"
0164 << leafstring << "Exception thrown from ShallowTree::ShallowTree\n";
0165 }
0166 }
0167 }
0168 });
0169 }
0170
0171 void ShallowTree::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0172 for (auto& connector : connectors_) {
0173 connector->connect(iEvent);
0174 }
0175 tree_->Fill();
0176 }
0177
0178 template <class T>
0179 void ShallowTree::TypedBranchConnector<T>::connect(const edm::Event& iEvent) {
0180 edm::Handle<T> handle;
0181 iEvent.getByLabel(ml_, pin_, handle);
0182 object_ = *handle;
0183 }
0184
0185 template <class T>
0186 ShallowTree::TypedBranchConnector<T>::TypedBranchConnector(edm::ProductDescription const* desc,
0187 std::string t,
0188 TTree* tree)
0189 : ml_(desc->moduleLabel()), pin_(desc->productInstanceName()) {
0190 object_ptr_ = &object_;
0191 std::string s = pin_ + t;
0192 if (!t.empty()) {
0193 tree->Branch(pin_.c_str(), object_ptr_, s.c_str());
0194 }
0195 else {
0196 tree->Branch(pin_.c_str(), &object_ptr_);
0197 }
0198 }