SelectBranches.cpp

Go to the documentation of this file.
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             // The TTree has changed. This is called once
00083             // per input file.
00084 
00085             _cookie = cookie;
00086 
00087             // update branches
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                 // Name is of the form BRANCH.MEMBER
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                         // Disable the whole branch
00108                         // the first time we see it.
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                         // Remove the entry we are interested in.
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         // This is called for every event.
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 }

Generated on Thu Apr 3 04:14:23 2008 for CAF by doxygen 1.3.4