00001
00002 #include "cafe/SelectBranches.hpp"
00003 #include "cafe/Event.hpp"
00004
00005 #include "TBranch.h"
00006 #include "TLeaf.h"
00007 #include "TTree.h"
00008
00009 #include <stdexcept>
00010 #include <algorithm>
00011 #include <set>
00012
00013 namespace cafe {
00014
00015 BranchNames::BranchNames()
00016 : _cookie(-1)
00017 {
00018 }
00019
00020 BranchNames::BranchNames(const std::string& name)
00021 : _branchNames(1, name),
00022 _cookie(-1)
00023 {
00024 }
00025
00026 BranchNames::BranchNames(const std::string& name1, const std::string& name2)
00027 : _cookie(-1)
00028 {
00029 _branchNames.push_back(name1);
00030 _branchNames.push_back(name2);
00031 }
00032
00033 BranchNames::BranchNames(const std::string& name1, const std::string& name2, const std::string& name3)
00034 : _cookie(-1)
00035 {
00036 _branchNames.push_back(name1);
00037 _branchNames.push_back(name2);
00038 _branchNames.push_back(name3);
00039 }
00040
00041 BranchNames::BranchNames(const std::string& name1, const std::string& name2, const std::string& name3, const std::string& name4)
00042 : _cookie(-1)
00043 {
00044 _branchNames.push_back(name1);
00045 _branchNames.push_back(name2);
00046 _branchNames.push_back(name3);
00047 _branchNames.push_back(name4);
00048 }
00049
00050 BranchNames::BranchNames(const std::vector<std::string>& names)
00051 : _branchNames(names),
00052 _cookie(-1)
00053 {
00054 }
00055
00056 BranchNames::BranchNames(const BranchNames& other)
00057 : _branchNames(other._branchNames),
00058 _branches(other._branches),
00059 _oldStatus(other._oldStatus),
00060 _cookie(other._cookie)
00061 {
00062 }
00063
00064 BranchNames& BranchNames::operator=(const BranchNames& other)
00065 {
00066 if(this != &other) {
00067 _branchNames = other._branchNames;
00068 _branches = other._branches;
00069 _oldStatus = other._oldStatus;
00070 _cookie = other._cookie;
00071 }
00072 return *this;
00073 }
00074
00075 void BranchNames::disable(TTree *tree, int cookie) const
00076 {
00077 using namespace std;
00078
00079 if(_branchNames.empty()) return;
00080
00081 if(cookie != _cookie) {
00082
00083
00084
00085 _cookie = cookie;
00086
00087
00088 _branches.clear();
00089 _oldStatus.clear();
00090
00091 set<string> branchesSeen;
00092 set<TBranch*> branchesToDisable;
00093
00094 for(vector<string>::const_iterator it = _branchNames.begin();
00095 it != _branchNames.end();
00096 ++it) {
00097
00098
00099 string::size_type pos = (*it).find('.');
00100 if(pos != string::npos) {
00101
00102 std::string branchName = (*it).substr(0, pos);
00103 std::string memberName = (*it).substr(pos + 1);
00104
00105 if(TBranch *br = tree->FindBranch(branchName.c_str())) {
00106
00107
00108
00109 if(branchesSeen.find(branchName) == branchesSeen.end()) {
00110 TIter iter(br->GetListOfBranches());
00111 while(TBranch *member = (TBranch *)iter.Next()) {
00112 branchesToDisable.insert(member);
00113 }
00114 branchesSeen.insert(branchName);
00115 }
00116
00117
00118 if(TBranch *member = br->FindBranch(memberName.c_str())) {
00119 branchesToDisable.erase(member);
00120 } else {
00121 throw runtime_error("BranchNames: no such member: " + memberName);
00122 }
00123
00124 } else {
00125 throw runtime_error("BranchNames: no such branch: " + branchName);
00126 }
00127 } else {
00128 throw runtime_error("BranchNames: no such branch: " + *it);
00129 }
00130 }
00131 _branches.assign(branchesToDisable.begin(), branchesToDisable.end());
00132 _oldStatus.resize(_branches.size());
00133 }
00134
00135
00136 for(size_t i = 0; i < _branches.size(); ++i) {
00137 _oldStatus[i] = _branches[i]->TestBit(kDoNotProcess);
00138 _branches[i]->SetBit(kDoNotProcess);
00139 }
00140 }
00141
00142 void BranchNames::enable() const
00143 {
00144 using namespace std;
00145
00146 for(size_t i = 0; i < _branches.size(); i++) {
00147 _branches[i]->SetBit(kDoNotProcess, _oldStatus[i]);
00148 }
00149 }
00150
00151 SelectBranches::SelectBranches(cafe::Event& event, const BranchNames& names)
00152 : _names(names)
00153 {
00154 names.disable(event.getTree(), event.getCookie());
00155 }
00156
00157 SelectBranches::~SelectBranches()
00158 {
00159 _names.enable();
00160 }
00161
00162 }