Heather and Matt have initiated a new iteration on our RootTreeAnalysis (RTA) macros. They have served us for some time and form the basis of the System Tests Root macros, but they are a tad awkward and in need of modernizing.
The point was to make it easier to do easy things while accessing our Root trees and ntuples, such as opening files, rewinding them, event navigation; bulk histogram manipulation, such as clearing and writing out; and supplying standard locations to define user histograms and insert their analysis code.
A single class was created that had member functions for these tasks.
It got complicated and did not extend well, as we added more input files and differentiated analyses based on MC, Digi and Recon steps for the 3 subsystems. In addition, access to histogram pointers was awkward.
Matt proposed that we go with new(er) Root concepts of Selectors, Folders, Tasks and tree friends; and Heather has implemented it.
A built-in function of TTrees that permits looping over the tree entries, with a well defined interface for initialization, event processing and termination.
An organizational tool that allows one to segregate different kinds of objects and provides a mechanism for retrieving them. This is akin to Gaudi's TDS.
A configurable list of "algorithms" to run. Tasks can also have lists of sub-tasks. These would be the equivalent of Gaudi Algorithms.
Allows one to associate other trees with one tree. One can then loop over the single tree and it makes sure all the others are read in lock-step too. If we had a naming convention for our trees and files, this would further simplify multi-tree access.
Folders
Create folders for tasks, histograms and data pointers. eg for histograms:
void AcdDigiTask::CreateHistograms(TFolder *folder) { TH1F *PMT0001 = new TH1F("PMT0001", "PMT0001", 1000, 0, 1000); PMT0001->SetDirectory(0); folder->Add(PMT0001); } void AcdDigiTask::Exec(Option_t *option) { TH1F* pmt0001 = (TH1F*)gROOT->FindObjectAny("PMT0001"); if (!pmt0001) { std::cout << "PMT0001 Histogram Not Found!" << std::endl; return; }[though it looks to me like the fetch is depending on the histograms being in Root's "special" list of objects, not the histograms TFolder. Hmm. How does this work, since CreateHistograms provides no default value, but is called with no argument in DigiSelector::Begin. ?]
Selector
The selector needs to know what branches to read and what tasks to execute. Heather has set up an ACD Digi example, where tasks can register for the different types of Digi data and the selector will then only read those branches.
So far it requires hardwired knowledge of the branch structure and names, eg:
RequestedDigiData *rdd = (RequestedDigiData*)taskFolder->FindObjectAny("RequestedDigiData"); if (rdd && rdd->AcdData()) { b_DigiEvent_acdDigiCol->GetEntry(entry); digiFolder->Add(m_acdDigiCol); } else { std::cout << "ACD not requested" << std::endl; }m_digiTask->ExecuteTask();
Another feature of the Selector is that only one Selector operates on a tree at a given time.
So, either we need some hierarchy of classes to handle MC, Digi and Recon or a single Selector with an overall list of tasks and a generic data registration scheme.Tasks
The task's CreateHistograms function is called from the Selector's begin step. There does not seem to be an Init for Tasks, so maybe this is the best place.
User Side
Heather created a top-level macro that runs all this. It sets up paths and compiles everything. It defines the folders and tasks, opens the Digi file and executes the Selector.
Still to be done (IMHO)
- generalize the Selector so it can run on all trees and select the requested branches
- we may need a handy-dandy mechanism to do the requesting (eg. RegisterData("ACD","DIGI")) that knows all our tree structure.
- add a layer of Tasks so that MC, Digi and Recon can all be accommodated from a single overall task list. So either have a hierarchy of 3 tasks with subtasks or a flat list of 7 tasks. The latter might be easier for the user who may just want a single task, at least at the beginning.
- come up with a convenient mechanism for setting up the tree friendship
- perhaps rework the top-level macro to be a class, so that one shouldn't have to unload the macro (or worse restart CINT) to modify anything.
R.Dubois Last Modified: 2004-05-09 19:32:07 -0700