// Uses the run field to divide a tree (chain) into smaller ones #include "TROOT.h" #include "TTree.h" #include "TFile.h" #include "TLeaf.h" #include "TString.h" #include "TEventList.h" #include #include #include //#include //#include // for std::pair #include #include class TRunDivider { public: TRunDivider (); // shallow copy OK: ~TRunDivider (); void SetFieldNames (TString& fieldName); // for all functions: - negative returns are errors, otherwise a count // - tree may be a chain void Clear (); int Read (TTree &tree); // tree is the input int WritePart (TTree &tree, const int index, const int Nparts, // tree is the input TString newFileName = "/") const; // a trailing / is replaced with part number int WriteRuns (TTree &tree, TString newFileName = "/") const; // a trailing / is replaced with part number int Size() const; int Dump (int N=10); // shallow copy OK: TRunDivider (const TRunDivider& that); // shallow copy OK: TRunDivider& operator = (const TRunDivider& that); typedef std::set KeySet; typedef std::vector KeyVector; typedef std::vector::iterator KeyIter; private: KeySet _keySet; KeyVector _keyVector; TString _name; }; TRunDivider::TRunDivider () { _name ="run"; } void TRunDivider::Clear () { _keySet.clear(); _keyVector.clear(); } void TRunDivider::SetFieldNames (TString& fieldName) { _name = fieldName; } int TRunDivider::Size () const { return _keyVector.size(); } int TRunDivider::Dump (int N) { if (N <= 0) N=_keyVector.size(); int M=N; std::cout<<" "<<_name<0; ++it, --N) { std::cout<Size(); } int TRunDivider::Read (TTree &tree) { TEventList* list = tree.GetEventList(); TLeaf *plr; Int_t prevTree = -1; _keySet.clear(); _keyVector.clear(); //read everything into the list as before, then copy it into the vector and sort it const Long64_t N = list ? Long64_t (list->GetN()) : Long64_t (tree.GetEntries()); for (int i=0; iGetEntry (i) : Long64_t (i); if (ientry < 0) {std::cerr<<"bug! ientry: "<N-10) cout<<"N: "<N-10) cout<<"Loader itmp: "<N-10) cout<<"checked tree num"< GetValue(); //if (i<10 || 0==i%1000 || i>N-10) cout<<"run: "<N-10) cout<<"Inserted"<Size(); } int TRunDivider::WritePart (TTree &tree, const int index, const int Nparts, TString newFileName) const { if (index >= Nparts || index < 0 || Nparts <1) return 0; if (newFileName.EndsWith("/")) { newFileName.Chop(); // removes / newFileName.Append (Form ("_%d", index)); } // figure out the requested range int nTot = this->Size(); cout<<"DBG: Will look at "< "<CloneTree(0); if (newTree == 0) {std::cerr<<"Can't clone tree."<GetN()) : Long64_t (tree.GetEntriesFast()); for (Int_t i=0; iGetEntry (i) : Long64_t (i); if (ientry < 0) {std::cerr<<"bug! ientry: "< GetValue(); if (run >= minRun && run <= maxRun) { newTree->Fill(); } } newTree->AutoSave(); return newTree->GetEntriesFast(); } int TRunDivider::WriteRuns (TTree &tree, TString newFileName) const { int Nkeys = _keyVector.size(); TFile *files [Nkeys]; TTree *trees [Nkeys]; for (int ikey=0; ikey IsWritable()) {cerr<<"Can't open for writing file #"<CloneTree(0); if (trees [ikey] == 0) {std::cerr<<"Can't clone tree for clone #"<GetN()) : Long64_t (tree.GetEntriesFast()); for (Int_t i=0; iGetEntry (i) : Long64_t (i); if (ientry < 0) {std::cerr<<"bug! ientry: "< GetValue(); bool found = false; for (int ikey=0; ikey Fill(); found = true; } } if (!found) {std::cerr<<"Unknown run ("<GetEntriesFast(); cout<<"Writing tree #"<GetEntriesFast()<<" entries."<AutoSave(); delete trees [ikey]; // calls Close and writes. } return sum; }