69 Warning(
"TTreeReaderGenerator::AddReader",
"Ignored branch %s because type is unsupported.",
branchName.Data());
77 Warning(
"AddReader",
"Ignored branch %s because a branch with the same name already exists. "
78 "TTreeReader requires an unique name for the branches. You may need to "
79 "put a dot at the end of the name of top-level branches.",
branchName.Data());
83 name.ReplaceAll(
'.',
'_');
84 name.ReplaceAll(
',',
'_');
85 name.ReplaceAll(
':',
'_');
86 name.ReplaceAll(
'<',
'_');
87 name.ReplaceAll(
'>',
'_');
88 name.ReplaceAll(
'#',
'_');
89 name.ReplaceAll(
'@',
'_');
91 while (
name.Index(
'[') >= 0 &&
name.Index(
']') >= 0 &&
name.Index(
']') >
name.Index(
'[')) {
103 if (info==
nullptr) info = branch->
GetInfo();
119 bool skipped =
false;
123 TIter peek = branches;
127 containerName =
"TClonesArray";
128 }
else if (desc && desc->
IsSTL()) {
129 outer_isclones =
kSTL;
134 containerName =
"TClonesArray";
136 outer_isclones =
kSTL;
154 subBranchPrefix = mom->
GetName();
155 if (subBranchPrefix[subBranchPrefix.
Length()-1]==
'.') {
158 subBranchPrefix =
"";
174 bool usedBranch =
true;
176 TIter peek = branches;
181 if (branch==
nullptr) {
183 Error(
"AnalyzeBranches",
"Ran out of branches when looking in branch %s, class %s",
186 Error(
"AnalyzeBranches",
"Ran out of branches when looking in class %s, element %s",
187 info->
GetName(), element->GetName());
196 if (element->GetType() == -1) {
205 if (leaf && outer_isclones ==
kOut
207 else branchEndName = branch->
GetName();
211 if (subBranchPrefix.
Length() && branchEndName.
BeginsWith(subBranchPrefix)) {
219 bool ispointer =
false;
222 switch(element->GetType()) {
299 TClass *cl = element->GetClassPointer();
305 containerName =
"TClonesArray";
306 if (outer_isclones !=
kOut) {
307 isclones = outer_isclones;
308 dataType =
"TClonesArray";
316 if (outer_isclones !=
kOut || containerName.
EqualTo(
"vector<bool>")) {
322 isclones = outer_isclones;
328 dataType = valueClass->
GetName();
332 if (valueClassBuiltIn) dataType = valueClassBuiltIn->
GetName();
333 else Error(
"AnalyzeBranches",
"Could not get type from collection %s in branch %s", cl->
GetName(), branch->
GetName());
357 if (element->IsBase()) {
366 if (branchEndName == element->GetName()) {
377 isclones, containerName, desc);
390 if (objInfo ==
nullptr) {
395 isclones, containerName, desc);
403 if (branchEndName == element->GetName()) {
408 if (isclones !=
kOut) {
414 isclones, containerName, desc);
421 if (local_prefix.
Length()) local_prefix +=
".";
422 local_prefix += element->GetName();
428 if (isclones !=
kOut) {
434 isclones, containerName, desc);
446 Error(
"AnalyzeBranch",
"Unsupported type for %s (%d).", branch->
GetName(), element->GetType());
449 if (!isBase && !skipped) {
451 Error(
"AnalyzeBranch",
"Arrays inside collections are not supported yet (branch: %s).", branch->
GetName());
453 if (outer_isclones !=
kOut || isclones !=
kOut) {
485 for(
int l=0;
l<nleaves;
l++) {
490 return extraLookedAt;
499 Error(
"AnalyzeOldLeaf",
"TLeafObject not supported yet");
509 std::vector<Int_t>
maxDim;
534 if (current[0] ==
']') {
537 scanindex = sscanf(current,
"%d",&index);
545 current = (
char*)strstr( current,
"[" );
558 dataType = leafTypeName;
563 dataType = leafTypeName;
642 if ( token.
Length() == 0 || (token.
Length() == 1 && token[0] ==
'@') ) {
643 Warning(
"ParseOptions",
"Ignored empty branch name in option string.");
644 }
else if (token[0] ==
'@') {
650 if (!
fTree->GetBranch(token)) {
651 Warning(
"ParseOptions",
"Tree %s does not contain a branch named %s.",
fTree->GetName(), token.
Data());
667 while ( (branch = (
TBranch*)next()) ) {
675 if (branchClassName && strlen(branchClassName)) {
688 containerName =
"TClonesArray";
698 "Introspection of TClonesArray in older file not implemented yet.");
714 "Introspection of TClonesArray for %s failed.",branch->
GetName());
729 if (containerName.
EqualTo(
"vector<bool>")) {
783 Error(
"AnalyzeTree",
"Cannot analyze branch %s because it is not a TBranchElement.",
branchName);
805 if (
fTree->GetDirectory() &&
fTree->GetDirectory()->GetFile()) {
806 treefile =
fTree->GetDirectory()->GetFile()->GetName();
808 treefile =
"Memory Directory";
814 bool isHbook =
fTree->InheritsFrom(
"THbookTree");
816 treefile =
fTree->GetTitle();
822 if (cppClassName != fileNameStem)
823 Warning(
"TTreeReaderGenerator::WriteSelector",
"The class name provided ('%s') is not a valid C++ identifier and will be converted to '%s', the code produced will likely fail to compile.", fileNameStem.
Data(), cppClassName.
Data());
824 thead.
Form(
"%s.h", fileNameStem.
Data());
825 std::ofstream ofs (thead, std::ofstream::out);
827 Error(
"WriteSelector",
"cannot open output file %s", thead.
Data());
833R
"CODE(//////////////////////////////////////////////////////////
834// This class has been automatically generated on
835// )CODE" << td.AsString() << R"CODE( by ROOT version )CODE" << gROOT->GetVersion() << std::endl;
837 ofs <<
"// from TTree " <<
fTree->GetName() <<
"/" <<
fTree->GetTitle() << std::endl
838 <<
"// found on file: " << treefile << std::endl;
840 ofs <<
"// from TChain " <<
fTree->GetName() <<
"/" <<
fTree->GetTitle() << std::endl;
843R
"CODE(//////////////////////////////////////////////////////////
845#ifndef )CODE" << cppClassName << R"CODE(_h
846#define )CODE" << cppClassName << R"CODE(_h
852 if (isHbook) ofs <<
"#include <THbookFile.h>" << std::endl;
854R
"CODE(#include <TSelector.h>
855#include <TTreeReader.h>
856#include <TTreeReaderValue.h>
857#include <TTreeReaderArray.h>
859// Headers needed by this particular selector
864 while ( (header = next()) ) {
865 ofs << header->
GetTitle() << std::endl;
867 ofs << std::endl << std::endl;
871R
"CODE(class )CODE" << cppClassName << R"CODE( : public TSelector {
873 TTreeReader fReader; ///<!the tree reader
874 TTree *fChain = 0; ///<!pointer to the analyzed TTree or TChain
876 // Readers to access the data (delete the ones you do not need).
885 <<
" = {fReader, \"" << descriptor->
fBranchName <<
"\"};" << std::endl;
891 )CODE" << cppClassName << R"CODE((TTree * /*tree*/ =0) { }
892 ~)CODE" << cppClassName << R"CODE(() override { }
893 Int_t Version() const override { return 2; }
894 void Begin(TTree *tree) override;
895 void SlaveBegin(TTree *tree) override;
896 void Init(TTree *tree) override;
897 bool Notify() override;
898 bool Process(Long64_t entry) override;
899 Int_t GetEntry(Long64_t entry, Int_t getall = 0) override { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; }
900 void SetOption(const char *option) override { fOption = option; }
901 void SetObject(TObject *obj) override { fObject = obj; }
902 void SetInputList(TList *input) override { fInput = input; }
903 TList *GetOutputList() const override { return fOutput; }
904 void SlaveTerminate() override;
905 void Terminate() override;
907 ClassDefOverride()CODE" << cppClassName << R"CODE(,0);
913#ifdef )CODE" << cppClassName << R"CODE(_cxx
914void )CODE" << cppClassName << R"CODE(::Init(TTree *tree)
916 // The Init() function is called when the selector needs to initialize
917 // a new tree or chain. Typically here the reader is initialized.
918 // It is normally not necessary to make changes to the generated
919 // code, but the routine can be extended by the user if needed.
921 fReader.SetTree(tree);
924bool )CODE" << cppClassName << R"CODE(::Notify()
926 // The Notify() function is called when a new file is opened. This
927 // can be for a new TTree in a TChain.
928 // It is normally not necessary to make changes
929 // to the generated code, but the routine can be extended by the
930 // user if needed. The return value is currently not used.
936#endif // #ifdef )CODE" << cppClassName << R"CODE(_cxx
942 tcimp.
Form(
"%s.C", fileNameStem.
Data());
943 std::ofstream ofsc (tcimp, std::ofstream::out);
945 Error(
"WriteSelector",
"cannot open output file %s", tcimp.
Data());
950R
"CODE(#define )CODE" << cppClassName << R"CODE(_cxx
951// The class definition in )CODE" << cppClassName << R"CODE(.h has been generated automatically
952// by the ROOT utility TTree::MakeSelector(). This class is derived
953// from the ROOT class TSelector. For more information on the TSelector
954// framework see $ROOTSYS/README/README.SELECTOR or the ROOT User Manual.
957// The following methods are defined in this file:
958// Begin(): called every time a loop on the tree starts,
959// a convenient place to create your histograms.
960// SlaveBegin(): called after Begin()
961// Process(): called for each event, in this function you decide what
962// to read and fill your histograms.
963// SlaveTerminate(): called at the end of the loop on the tree.
964// Terminate(): called at the end of the loop on the tree,
965// a convenient place to draw/fit your histograms.
967// To use this file, try the following session on your Tree T:
969// root> T->Process(")CODE" << fClassname << R"CODE(.C")
970// root> T->Process(")CODE" << fClassname << R"CODE(.C","some options")
971// root> T->Process(")CODE" << fClassname << R"CODE(.C+")
975#include ")CODE" << thead << R"CODE("
979void )CODE" << cppClassName << R"CODE(::Begin(TTree * /*tree*/)
981 // The Begin() function is called at the start of the query.
982 // The tree argument is deprecated.
984 TString option = GetOption();
987void )CODE" << cppClassName << R"CODE(::SlaveBegin(TTree * /*tree*/)
989 // The SlaveBegin() function is called after the Begin() function.
990 // The tree argument is deprecated.
992 TString option = GetOption();
996bool )CODE" << cppClassName << R"CODE(::Process(Long64_t entry)
998 // The Process() function is called for each entry in the tree
999 // to be processed. The entry argument
1000 // specifies which entry in the currently loaded tree is to be processed.
1002 // This function should contain the \"body\" of the analysis. It can contain
1003 // simple or elaborate selection criteria, run algorithms on the data
1004 // of the event and typically fill histograms.
1006 // The processing can be stopped by calling Abort().
1008 // Use fStatus to set the return value of TTree::Process().
1010 // The return value is currently not used.
1012 fReader.SetLocalEntry(entry);
1017void )CODE" << cppClassName << R"CODE(::SlaveTerminate()
1019 // The SlaveTerminate() function is called after all entries or objects
1020 // have been processed.
1024void )CODE" << cppClassName << R"CODE(::Terminate()
1026 // The Terminate() function is the last function to be called during
1027 // a query. It always runs on the client, it can be used to present
1028 // the results graphically or save the results to file.
int Int_t
Signed integer 4 bytes (int).
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int).
const char Option_t
Option string (const char).
Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.", GetName(), objname)
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
TString fBranchName
Name of the branch.
TBranchDescriptor * fParent
Descriptor of the parent branch (NULL for topmost).
TString fContainerName
Name of the container.
TString fSubBranchPrefix
Prefix (e.g. if the branch name is "A." the prefix is "A".
TList fListOfHeaders
List of included headers.
void AddHeader(TClass *cl)
Add a header inclusion request.
TVirtualStreamerInfo * GetStreamerInfo(TBranch *branch, TIter current, TClass *cl)
Return the correct TStreamerInfo of class 'cl' in the list of branches (current) [Assuming these bran...
TVirtualStreamerInfo * GetBaseClass(TStreamerElement *element)
Check if element is a base class and if yes, return the base class.
TTree * fTree
Pointer to the tree.
TString fOptionStr
User options as a string.
TString GetContainedClassName(TBranchElement *branch, TStreamerElement *element, bool ispointer)
Get name of class inside a container.
TTreeGeneratorBase(TTree *tree, const char *option)
Constructor.
TString fBranchName
Branch corresponding to the reader.
ReaderType fType
Type of the reader: Value or Array.
TString fDataType
Data type of reader.
TString fName
Reader name.
std::vector< TString > fIncludeStruct
Branches whom should be included.
void AnalyzeTree(TTree *tree)
Analyze tree and extract readers.
TString fClassname
Class name of the selector.
std::vector< TString > fIncludeLeaves
Branches whose leaves should be included.
UInt_t AnalyzeBranches(TBranchDescriptor *desc, TBranchElement *branch, TVirtualStreamerInfo *info)
Analyse sub-branches of 'branch' recursively and extract readers.
void ParseOptions()
Parse the user options.
bool fIncludeAllTopmost
Should all topmost branches be included.
void AddReader(TTreeReaderDescriptor::ReaderType type, TString dataType, TString name, TString branchName, TBranchDescriptor *parent=nullptr, bool isLeaf=true)
Add a reader to the generated code.
bool BranchNeedsReader(TString branchName, TBranchDescriptor *parent, bool isLeaf)
Check whether a branch should have a corresponding reader added, depending on the options provided by...
bool fIncludeAllLeaves
Should all leaves be included.
TTreeReaderGenerator(TTree *tree, const char *classname, Option_t *option)
Constructor. Analyzes the tree and writes selector.
TList fListOfReaders
List of readers.
UInt_t AnalyzeOldLeaf(TLeaf *leaf, Int_t nleaves)
Analyze the leaf and add the variables found.
UInt_t AnalyzeOldBranch(TBranch *branch)
Analyze branch and add the variables found.
void WriteSelector()
Generate code for selector class.
A Branch for the case of an object.
TBranchElement * GetBranchCount() const
TStreamerInfo * GetInfo() const
Get streamer info for the branch class.
A TTree is a list of TBranches.
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any.
virtual char * GetAddress() const
TObjArray * GetListOfBranches()
Int_t GetSplitLevel() const
virtual Int_t GetEntry(Long64_t entry=0, Int_t getall=0)
Read all leaves of entry and return total number of bytes read.
TClass * IsA() const override
TBranch * GetSubBranch(const TBranch *br) const
Find the parent branch of child.
virtual void SetAddress(void *add)
Set address of this branch.
TObjArray * GetListOfLeaves()
TBranch * GetMother() const
Get our top-level parent branch in the tree.
TClass instances represent classes, structs and namespaces in the ROOT type system.
Bool_t CanIgnoreTObjectStreamer()
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0, Bool_t isTransient=kFALSE) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist,...
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
An array of clone (identical) objects.
TClass * GetClass() const
Basic data type descriptor (datatype information is obtained from CINT).
static TDataType * GetDataType(EDataType type)
Given a EDataType type, get the TDataType* that represents it.
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
const char * AsString() const
Return the date & time as a string (ctime() format).
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
virtual const char * GetTypeName() const
TClass * IsA() const override
TBranch * GetBranch() const
const char * GetName() const override
Returns name of object.
const char * GetTitle() const override
Returns title of object.
Int_t GetEntriesFast() const
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * At(Int_t idx) const override
TObject * UncheckedAt(Int_t i) const
Collectable string class.
Mother of all ROOT objects.
virtual const char * GetTitle() const
Returns title of object.
Describe one element (data member) to be Streamed.
const char * Data() const
Bool_t EqualTo(const char *cs, ECaseCompare cmp=kExact) const
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
TString & Remove(Ssiz_t pos)
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
A TTree represents a columnar dataset.
virtual TObjArray * GetListOfBranches()
virtual EDataType GetType() const =0
If the value type is a fundamental data type, return its type (see enumeration EDataType).
virtual TClass * GetValueClass() const =0
If the value type is a user-defined class, return a pointer to the TClass representing the value type...
Abstract Interface class describing Streamer information for one class.
@ kUChar
Equal to TDataType's kchar.
virtual TObjArray * GetElements() const =0
virtual TClass * GetClass() const =0
ELocation
0 for the general case, 1 when this a split clases inside a TClonesArray, 2 when this is a split clas...
std::vector< Int_t > maxDim
TString GetCppName(TString name)
Convert a valid TTree branch name or filename into a valid C++ variable name.
The namespace of The Lean Mean C++ Option Parser.