ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/FGolf/Tools/makeCMS2ClassFiles.C
Revision: 1.3
Committed: Wed Feb 8 05:45:49 2012 UTC (13 years, 2 months ago) by fgolf
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +820 -775 lines
Log Message:
more better version that supports making CMS2 file for any kind of tree

File Contents

# User Rev Content
1 fgolf 1.1 // Original author: Puneeth Kalavase (UCSB)
2     //
3     /*
4     ROOT macro to make CMS2.h and ScanChain.C files for basic analysis
5     of CMS2 ntuples. Usage:
6    
7     root [0] .L makeCMS2ClassFiles.C++
8     root [1] makeCMS2ClassFiles(filename, paranoia, branchfilename, classname )
9    
10     filename = location+name of ntuple file
11     paranoia = boolean. If true, will add checks for branches that have nans
12     branchfilename = See http://www.t2.ucsd.edu/tastwiki/bin/view/CMS/SkimNtuples
13     classname = you can change the default name of the class "CMS2" to whatever you want
14    
15     */
16    
17    
18     #include "TBranch.h"
19     #include "TString.h"
20     #include "TFile.h"
21     #include "TTree.h"
22 fgolf 1.3 #include "TSeqCollection.h"
23 fgolf 1.1 #include <iostream>
24     #include <fstream>
25     #include <set>
26     #include <algorithm>
27     #include <vector>
28     #include "Math/LorentzVector.h"
29     #include <sys/stat.h>
30    
31     using namespace std;
32     ofstream headerf;
33     ofstream codef;
34     ofstream implf;
35     ofstream branchfile;
36    
37 fgolf 1.3 void makeHeaderFile(TFile *f, std::string treeName, bool paranoid, string Classname);
38 fgolf 1.1 void makeSrcFile(std::string Classname, std::string branchNamesFile);
39     void makeBranchFile(std::string branchNamesFile);
40     void makeDriverFile(std::string fname);
41    
42    
43     //-------------------------------------------------------------------------------------------------
44 fgolf 1.3 void makeCMS2ClassFiles (std::string fname, bool paranoid = true, std::string treeName="",
45     std::string branchNamesFile="", std::string className = "CMS2") {
46 fgolf 1.1
47 fgolf 1.3 using namespace std;
48 fgolf 1.1
49 fgolf 1.3 TFile *f = TFile::Open( fname.c_str() );
50 fgolf 1.1
51 fgolf 1.3 if(f==NULL) {
52     cout << "File does not exist. Exiting program" << endl;
53     return;
54     }
55 fgolf 1.1
56 fgolf 1.3 if(f->IsZombie()) {
57     cout << "File is not a valid root file, or root file is corruped" << endl;
58     cout << "Exiting..." << endl;
59     return;
60     }
61 fgolf 1.1
62 fgolf 1.3 //check if the branchNamesFile exists
63     if(branchNamesFile != "") {
64     struct stat results;
65     int intStat = stat(branchNamesFile.c_str(), &results);
66     if(intStat != 0) {
67     cout << "Cannot open " << branchNamesFile << endl;
68     cout << "Please make sure that the file exists" << endl;
69     return;
70     }
71 fgolf 1.1 }
72    
73    
74 fgolf 1.3 //class is CMS2 by default
75     //std::string Classname = className=="" ? "CMS2" : className;
76 fgolf 1.1
77 fgolf 1.3 headerf.open((className+".h").c_str());
78     implf.open((className+".cc").c_str());
79     codef.open("ScanChain.C");
80 fgolf 1.1
81 fgolf 1.3 implf << "#include \"" << className+".h" << "\"\n" << className << " cms2;" << endl;
82     makeHeaderFile(f, treeName, paranoid, className);
83     makeSrcFile(className, branchNamesFile);
84     if(branchNamesFile!="")
85     makeBranchFile(branchNamesFile);
86     implf << "}" << endl;
87     implf.close();
88     headerf << "}" << endl;
89     headerf << "#endif" << endl;
90     headerf.close();
91 fgolf 1.1
92    
93 fgolf 1.3 codef.close();
94 fgolf 1.1
95 fgolf 1.3 makeDriverFile(fname);
96 fgolf 1.1
97 fgolf 1.3 f->Close();
98 fgolf 1.1 }
99    
100    
101     //-------------------------------------------------------------------------------------------------
102 fgolf 1.3 void makeHeaderFile(TFile *f, std::string treeName, bool paranoid, string Classname) {
103 fgolf 1.1
104    
105    
106 fgolf 1.3 headerf << "// -*- C++ -*-" << endl;
107     headerf << "#ifndef " << Classname << "_H" << endl;
108     headerf << "#define " << Classname << "_H" << endl;
109     headerf << "#include \"Math/LorentzVector.h\"" << endl;
110     headerf << "#include \"Math/Point3D.h\"" << endl;
111     headerf << "#include \"TMath.h\"" << endl;
112     headerf << "#include \"TBranch.h\"" << endl;
113     headerf << "#include \"TTree.h\"" << endl;
114     headerf << "#include \"TH1F.h\"" << endl;
115     headerf << "#include \"TFile.h\"" << endl;
116     headerf << "#include \"TBits.h\"" << endl;
117     headerf << "#include <vector> " << endl;
118     headerf << "typedef ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> > LorentzVector;" << endl << endl;
119     if (paranoid)
120     headerf << "#define PARANOIA" << endl << endl;
121     headerf << "using namespace std; " << endl;
122     headerf << "class " << Classname << " {" << endl;
123     headerf << "private: " << endl;
124     headerf << "protected: " << endl;
125     headerf << "\tunsigned int index;" << endl;
126     // TTree *ev = (TTree*)f->Get("Events");
127     TList* list_of_keys = f->GetListOfKeys();
128     std::string tree_name = "";
129     if (treeName.empty()) {
130     unsigned int ntrees = 0;
131     for (unsigned int idx = 0; idx < (unsigned int)list_of_keys->GetSize(); idx++) {
132     const char* obj_name = list_of_keys->At(idx)->GetName();
133     TObject* obj = f->Get(obj_name);
134     if (obj->InheritsFrom("TTree")) {
135     ++ntrees;
136     tree_name = obj_name;
137     }
138     }
139     if (ntrees == 0) {
140     std::cout << "Did not find a tree. Exiting." << std::endl;
141     return;
142     }
143     if (ntrees > 1) {
144     std::cout << "Found more than one tree. Please specify a tree to use." << std::endl;
145     return;
146     }
147     }
148     else
149     tree_name = treeName;
150    
151     TTree *ev = (TTree*)f->Get(tree_name.c_str());
152    
153     TSeqCollection *fullarray = ev->GetListOfAliases();
154     bool have_aliases = true;
155     if (!fullarray) {
156     have_aliases = false;
157     fullarray = ev->GetListOfBranches();
158     }
159    
160     // if (have_aliases && fullarray->GetSize() != ev->GetListOfBranches()->GetSize()) {
161     // std::cout << "Tree has " << fullarray->GetSize() << " aliases and " << ev->GetListOfBranches()->GetSize() << " branches. Exiting." << std::endl;
162     // return;
163     // }
164    
165     TList *aliasarray = new TList();
166 fgolf 1.1
167 fgolf 1.3 for(Int_t i = 0; i < fullarray->GetSize(); ++i) {
168     TString aliasname(fullarray->At(i)->GetName());
169     // TBranch *branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
170     TBranch *branch = 0;
171     if (have_aliases)
172     branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
173     else
174     branch = (TBranch*)fullarray->At(i);
175    
176     TString branchname(branch->GetName());
177     TString branchtitle(branch->GetTitle());
178     if(!branchname.BeginsWith("int") &&
179     !branchname.BeginsWith("uint") &&
180     !branchname.BeginsWith("bool") &&
181     !branchname.BeginsWith("float") &&
182     !branchname.BeginsWith("double") &&
183     !branchtitle.EndsWith("/F") &&
184     !branchtitle.EndsWith("/I") &&
185     !branchtitle.EndsWith("/i") &&
186     !branchtitle.EndsWith("/O") &&
187     !branchtitle.BeginsWith("TString") &&
188     !branchtitle.BeginsWith("TBits"))
189     continue;
190     aliasarray->Add(fullarray->At(i));
191     }
192 fgolf 1.1
193    
194 fgolf 1.3 for(Int_t i = 0; i< aliasarray->GetSize(); ++i) {
195 fgolf 1.1
196 fgolf 1.3 //Class name is blank for a int of float
197     TString aliasname(aliasarray->At(i)->GetName());
198     // TBranch *branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
199     TBranch *branch = 0;
200     if (have_aliases)
201     branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
202     else
203     branch = (TBranch*)aliasarray->At(i);
204 fgolf 1.1
205 fgolf 1.3 TString classname = branch->GetClassName();
206     TString title = branch->GetTitle();
207     if ( classname.Contains("vector") ) {
208     if(classname.Contains("edm::Wrapper<") ) {
209     classname = classname(0,classname.Length()-2);
210     classname.ReplaceAll("edm::Wrapper<","");
211     headerf << "\t" << classname << " " << aliasname << "_;" << endl;
212     } else {
213     headerf << "\t" << classname << " *" << aliasname << "_;" << endl;
214     }
215     } else {
216 fgolf 1.1
217 fgolf 1.3 if(classname != "" ) { //LorentzVector
218     if(classname.Contains("edm::Wrapper<") ) {
219     classname = classname(0,classname.Length()-1);
220     classname.ReplaceAll("edm::Wrapper<","");
221     headerf << "\t" << classname << " " << aliasname << "_;" << endl;
222     } else {
223     headerf << "\t" << classname << " *" << aliasname << "_;" << endl;
224     }
225     } else {
226     if(title.EndsWith("/i"))
227     headerf << "\tunsigned int" << "\t" << aliasname << "_;" << endl;
228     if(title.EndsWith("/F"))
229     headerf << "\tfloat" << "\t" << aliasname << "_;" << endl;
230     if(title.EndsWith("/I"))
231     headerf << "\tint" << "\t" << aliasname << "_;" << endl;
232     if(title.EndsWith("/O"))
233     headerf << "\tbool" << "\t" << aliasname << "_;" << endl;
234     }
235     }
236     headerf << "\tTBranch *" << Form("%s_branch",aliasname.Data()) << ";" << endl;
237     headerf << "\tbool " << Form("%s_isLoaded",aliasname.Data()) << ";" << endl;
238     }
239 fgolf 1.1
240    
241 fgolf 1.3 headerf << "public: " << endl;
242     headerf << "void Init(TTree *tree) {" << endl;
243 fgolf 1.1
244    
245 fgolf 1.3 // SetBranchAddresses for LorentzVectors
246     // TBits also needs SetMakeClass(0)...
247     for(Int_t i = 0; i< aliasarray->GetSize(); i++) {
248     TString aliasname(aliasarray->At(i)->GetName());
249     // TBranch *branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
250     TBranch *branch = 0;
251     if (have_aliases)
252     branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
253     else
254     branch = (TBranch*)aliasarray->At(i);
255    
256     TString classname = branch->GetClassName();
257     if ( !classname.Contains("vector<vector") ) {
258     if ( classname.Contains("Lorentz") || classname.Contains("PositionVector") || classname.Contains("TBits")) {
259     headerf << "\t" << Form("%s_branch",aliasname.Data()) << " = 0;" << endl;
260     if (have_aliases) {
261     headerf << "\t" << "if (tree->GetAlias(\"" << aliasname << "\") != 0) {" << endl;
262     headerf << "\t\t" << Form("%s_branch",aliasname.Data()) << " = tree->GetBranch(tree->GetAlias(\"" << aliasname << "\"));" << endl;
263     headerf << "\t\t" << Form("%s_branch",aliasname.Data()) << "->SetAddress(&" << aliasname << "_);" << endl << "\t}" << endl;
264     }
265     else {
266     headerf << "\t" << "if (tree->GetBranch(\"" << aliasname << "\") != 0) {" << endl;
267     headerf << "\t\t" << Form("%s_branch",aliasname.Data()) << " = tree->GetBranch(\"" << aliasname << "\");" << endl;
268     headerf << "\t\t" << Form("%s_branch",aliasname.Data()) << "->SetAddress(&" << aliasname << "_);" << endl << "\t}" << endl;
269     }
270     }
271     }
272     }
273    
274    
275     // SetBranchAddresses for everything else
276     headerf << " tree->SetMakeClass(1);" << endl;
277     for(Int_t i = 0; i< aliasarray->GetSize(); i++) {
278     TString aliasname(aliasarray->At(i)->GetName());
279     // TBranch *branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
280     TBranch *branch = 0;
281     if (have_aliases)
282     branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
283     else
284     branch = (TBranch*)aliasarray->At(i);
285    
286     TString classname = branch->GetClassName();
287     if ( ! (classname.Contains("Lorentz") || classname.Contains("PositionVector") || classname.Contains("TBits")) || classname.Contains("vector<vector") ) {
288     headerf << "\t" << Form("%s_branch",aliasname.Data()) << " = 0;" << endl;
289     if (have_aliases) {
290     headerf << "\t" << "if (tree->GetAlias(\"" << aliasname << "\") != 0) {" << endl;
291     headerf << "\t\t" << Form("%s_branch",aliasname.Data()) << " = tree->GetBranch(tree->GetAlias(\"" << aliasname << "\"));" << endl;
292     headerf << "\t\t" << Form("%s_branch",aliasname.Data()) << "->SetAddress(&" << aliasname << "_);" << endl << "\t}" << endl;
293     }
294     else {
295     headerf << "\t" << "if (tree->GetBranch(\"" << aliasname << "\") != 0) {" << endl;
296     headerf << "\t\t" << Form("%s_branch",aliasname.Data()) << " = tree->GetBranch(\"" << aliasname << "\");" << endl;
297     headerf << "\t\t" << Form("%s_branch",aliasname.Data()) << "->SetAddress(&" << aliasname << "_);" << endl << "\t}" << endl;
298     }
299     }
300     }
301    
302     headerf << " tree->SetMakeClass(0);" << endl;
303     headerf << "}" << endl;
304    
305     // GetEntry
306     headerf << "void GetEntry(unsigned int idx) " << endl;
307     headerf << "\t// this only marks branches as not loaded, saving a lot of time" << endl << "\t{" << endl;
308     headerf << "\t\tindex = idx;" << endl;
309     for(Int_t i = 0; i< aliasarray->GetSize(); i++) {
310     TString aliasname(aliasarray->At(i)->GetName());
311     headerf << "\t\t" << Form("%s_isLoaded",aliasname.Data()) << " = false;" << endl;
312     }
313     headerf << "\t}" << endl << endl;
314    
315     // LoadAllBranches
316     headerf << "void LoadAllBranches() " << endl;
317     headerf << "\t// load all branches" << endl << "{" << endl;
318     for(Int_t i = 0; i< aliasarray->GetSize(); i++) {
319     TString aliasname(aliasarray->At(i)->GetName());
320     headerf << "\t" << "if (" << aliasname.Data() << "_branch != 0) " << Form("%s();",aliasname.Data()) << endl;
321     }
322     headerf << "}" << endl << endl;
323    
324     // accessor functions
325     for (Int_t i = 0; i< aliasarray->GetSize(); i++) {
326     TString aliasname(aliasarray->At(i)->GetName());
327     // TBranch *branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
328     TBranch *branch = 0;
329     if (have_aliases)
330     branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
331     else
332     branch = (TBranch*)aliasarray->At(i);
333    
334     TString classname = branch->GetClassName();
335     TString title = branch->GetTitle();
336     bool isSkimmedNtuple = false;
337     if(!classname.Contains("edm::Wrapper<") &&
338     (classname.Contains("vector") || classname.Contains("LorentzVector") ) )
339     isSkimmedNtuple = true;
340     if ( classname.Contains("vector") ) {
341     if(classname.Contains("edm::Wrapper<") ) {
342     classname = classname(0,classname.Length()-2);
343     classname.ReplaceAll("edm::Wrapper<","");
344     }
345     headerf << "\t" << classname << " &" << aliasname << "()" << endl;
346     } else {
347     if(classname.Contains("edm::Wrapper<") ) {
348     classname = classname(0,classname.Length()-1);
349     classname.ReplaceAll("edm::Wrapper<","");
350     }
351     if(classname != "" ) {
352     headerf << "\t" << classname << " &" << aliasname << "()" << endl;
353     } else {
354     if(title.EndsWith("/i"))
355     headerf << "\tunsigned int &" << aliasname << "()" << endl;
356     if(title.EndsWith("/F"))
357     headerf << "\tfloat &" << aliasname << "()" << endl;
358     if(title.EndsWith("/I"))
359     headerf << "\tint &" << aliasname << "()" << endl;
360     if(title.EndsWith("/O"))
361     headerf << "\tbool &" << "\t" << aliasname << "()" << endl;
362     }
363     }
364     aliasname = aliasarray->At(i)->GetName();
365     headerf << "\t{" << endl;
366     headerf << "\t\t" << "if (not " << Form("%s_isLoaded) {",aliasname.Data()) << endl;
367     headerf << "\t\t\t" << "if (" << Form("%s_branch",aliasname.Data()) << " != 0) {" << endl;
368     headerf << "\t\t\t\t" << Form("%s_branch",aliasname.Data()) << "->GetEntry(index);" << endl;
369     if (paranoid) {
370     headerf << "\t\t\t\t#ifdef PARANOIA" << endl;
371     if (classname == "vector<vector<float> >") {
372     if(isSkimmedNtuple) {
373     headerf << "\t\t\t\t" << "for (vector<vector<float> >::const_iterator i = "
374     << aliasname << "_->begin(); i != "<< aliasname << "_->end(); ++i) {" << endl;
375     } else {
376     headerf << "\t\t\t\t" << "for (vector<vector<float> >::const_iterator i = "
377     << aliasname << "_.begin(); i != "<< aliasname << "_.end(); ++i) {" << endl;
378     }
379     headerf << "\t\t\t\t\t" << "for (vector<float>::const_iterator j = i->begin(); "
380     "j != i->end(); ++j) {" << endl;
381     headerf << "\t\t\t\t\t\t" << "if (not isfinite(*j)) {" << endl;
382     headerf << "\t\t\t\t\t\t\t" << "printf(\"branch " << Form("%s_branch",aliasname.Data())
383     << " contains a bad float: %f\\n\", *j);" << endl << "\t\t\t\t\t\t\t" << "exit(1);"
384     << endl;
385     headerf << "\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}" << endl;
386     } else if (classname == "vector<float>") {
387     if(isSkimmedNtuple) {
388     headerf << "\t\t\t\t" << "for (vector<float>::const_iterator i = "
389     << aliasname << "_->begin(); i != "<< aliasname << "_->end(); ++i) {" << endl;
390     } else {
391     headerf << "\t\t\t\t" << "for (vector<float>::const_iterator i = "
392     << aliasname << "_.begin(); i != "<< aliasname << "_.end(); ++i) {" << endl;
393     }
394     headerf << "\t\t\t\t\t" << "if (not isfinite(*i)) {" << endl;
395     headerf << "\t\t\t\t\t\t" << "printf(\"branch " << Form("%s_branch",aliasname.Data())
396     << " contains a bad float: %f\\n\", *i);" << endl << "\t\t\t\t\t\t" << "exit(1);"
397     << endl;
398     headerf << "\t\t\t\t\t}\n\t\t\t\t}" << endl;
399     } else if (classname == "float") {
400     headerf << "\t\t\t\t" << "if (not isfinite(" << aliasname << "_)) {" << endl;
401     headerf << "\t\t\t\t\t" << "printf(\"branch " << Form("%s_branch",aliasname.Data())
402     << " contains a bad float: %f\\n\", " << aliasname << "_);" << endl
403     << "\t\t\t\t\t" << "exit(1);"
404     << endl;
405     headerf << "\t\t\t\t}" << endl;
406     } else if (classname.BeginsWith("vector<vector<ROOT::Math::LorentzVector")) {
407     if(isSkimmedNtuple) {
408     headerf << "\t\t\t\t" << "for (" << classname.Data() <<"::const_iterator i = "
409     << aliasname << "_->begin(); i != "<< aliasname << "_->end(); ++i) {" << endl;
410     } else {
411     headerf << "\t\t\t\t" << "for (" << classname.Data() <<"::const_iterator i = "
412     << aliasname << "_.begin(); i != "<< aliasname << "_.end(); ++i) {" << endl;
413     }
414     // this is a slightly hacky way to get rid of the outer vector< > ...
415     std::string str = classname.Data() + 7;
416     str[str.length() - 2] = 0;
417     headerf << "\t\t\t\t\t" << "for (" << str.c_str() << "::const_iterator j = i->begin(); "
418     "j != i->end(); ++j) {" << endl;
419     headerf << "\t\t\t\t\t\t" << "int e;" << endl;
420     headerf << "\t\t\t\t\t\t" << "frexp(j->pt(), &e);" << endl;
421     headerf << "\t\t\t\t\t\t" << "if (not isfinite(j->pt()) || e > 30) {" << endl;
422     headerf << "\t\t\t\t\t\t\t" << "printf(\"branch " << Form("%s_branch",aliasname.Data())
423     << " contains a bad float: %f\\n\", j->pt());" << endl << "\t\t\t\t\t\t\t" << "exit(1);"
424     << endl;
425     headerf << "\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}" << endl;
426     } else if (classname.BeginsWith("vector<ROOT::Math::LorentzVector")) {
427     if(isSkimmedNtuple) {
428     headerf << "\t\t\t\t" << "for (" << classname.Data() << "::const_iterator i = "
429     << aliasname << "_->begin(); i != "<< aliasname << "_->end(); ++i) {" << endl;
430     } else {
431     headerf << "\t\t\t\t" << "for (" << classname.Data() << "::const_iterator i = "
432     << aliasname << "_.begin(); i != "<< aliasname << "_.end(); ++i) {" << endl;
433     }
434     headerf << "\t\t\t\t\t" << "int e;" << endl;
435     headerf << "\t\t\t\t\t" << "frexp(i->pt(), &e);" << endl;
436     headerf << "\t\t\t\t\t" << "if (not isfinite(i->pt()) || e > 30) {" << endl;
437     headerf << "\t\t\t\t\t\t" << "printf(\"branch " << Form("%s_branch",aliasname.Data())
438     << " contains a bad float: %f\\n\", i->pt());" << endl << "\t\t\t\t\t\t" << "exit(1);"
439     << endl;
440     headerf << "\t\t\t\t\t}\n\t\t\t\t}" << endl;
441     } else if (classname.BeginsWith("ROOT::Math::LorentzVector")) {
442     headerf << "\t\t\t\t" << "int e;" << endl;
443     if(isSkimmedNtuple) {
444     headerf << "\t\t\t\t" << "frexp(" << aliasname << "_->pt(), &e);" << endl;
445     headerf << "\t\t\t\t" << "if (not isfinite(" << aliasname << "_->pt()) || e > 30) {" << endl;
446     headerf << "\t\t\t\t\t" << "printf(\"branch " << Form("%s_branch",aliasname.Data())
447     << " contains a bad float: %f\\n\", " << aliasname << "_->pt());" << endl
448     << "\t\t\t\t\t" << "exit(1);"
449     << endl;
450     } else {
451     headerf << "\t\t\t\t" << "frexp(" << aliasname << "_.pt(), &e);" << endl;
452     headerf << "\t\t\t\t" << "if (not isfinite(" << aliasname << "_.pt()) || e > 30) {" << endl;
453     headerf << "\t\t\t\t\t" << "printf(\"branch " << Form("%s_branch",aliasname.Data())
454     << " contains a bad float: %f\\n\", " << aliasname << "_.pt());" << endl
455     << "\t\t\t\t\t" << "exit(1);"
456     << endl;
457     }
458     headerf << "\t\t\t\t}" << endl;
459     }
460     headerf << "\t\t\t\t#endif // #ifdef PARANOIA" << endl;
461     }
462     headerf << "\t\t\t" << "} else { " << endl;
463     headerf << "\t\t\t\t" << "printf(\"branch " << Form("%s_branch",aliasname.Data())
464     << " does not exist!\\n\");" << endl;
465     headerf << "\t\t\t\t" << "exit(1);" << endl << "\t\t\t}" << endl;
466     headerf << "\t\t\t" << Form("%s_isLoaded",aliasname.Data()) << " = true;" << endl;
467     headerf << "\t\t" << "}" << endl;
468     if(isSkimmedNtuple) {
469     headerf << "\t\t" << "return *" << aliasname << "_;" << endl << "\t}" << endl;
470     }
471     else {
472     headerf << "\t\t" << "return " << aliasname << "_;" << endl << "\t}" << endl;
473     }
474     }
475    
476     bool haveHLTInfo = false;
477     bool haveL1Info = false;
478     bool haveHLT8E29Info = false;
479     for(int i = 0; i < aliasarray->GetSize(); i++) {
480     TString aliasname(aliasarray->At(i)->GetName());
481     if(aliasname=="hlt_trigNames")
482     haveHLTInfo = true;
483     if(aliasname=="l1_trigNames")
484     haveL1Info = true;
485     if(aliasname=="hlt8e29_trigNames")
486     haveHLT8E29Info = true;
487     }
488 fgolf 1.1
489 fgolf 1.3 if(haveHLTInfo) {
490     //functions to return whether or not trigger fired - HLT
491     headerf << "\t" << "bool passHLTTrigger(TString trigName) {" << endl;
492     headerf << "\t\t" << "int trigIndx;" << endl;
493     headerf << "\t\t" << "vector<TString>::const_iterator begin_it = hlt_trigNames().begin();" << endl;
494     headerf << "\t\t" << "vector<TString>::const_iterator end_it = hlt_trigNames().end();" << endl;
495     headerf << "\t\t" << "vector<TString>::const_iterator found_it = find(begin_it, end_it, trigName);" << endl;
496     headerf << "\t\t" << "if(found_it != end_it)" << endl;
497     headerf << "\t\t\t" << "trigIndx = found_it - begin_it;" << endl;
498     headerf << "\t\t" << "else {" << endl;
499     headerf << "\t\t\t" << "cout << \"Cannot find Trigger \" << trigName << endl; " << endl;
500     headerf << "\t\t\t" << "return 0;" << endl;
501     headerf << "\t\t" << "}" << endl << endl;
502     headerf << "\t" << "return hlt_bits().TestBitNumber(trigIndx);" << endl;
503     headerf << "\t" << "}" << endl;
504     }//if(haveHLTInfo)
505    
506     if(haveHLT8E29Info) {
507     //functions to return whether or not trigger fired - HLT
508     headerf << "\t" << "bool passHLT8E29Trigger(TString trigName) {" << endl;
509     headerf << "\t\t" << "int trigIndx;" << endl;
510     headerf << "\t\t" << "vector<TString>::const_iterator begin_it = hlt8e29_trigNames().begin();" << endl;
511     headerf << "\t\t" << "vector<TString>::const_iterator end_it = hlt8e29_trigNames().end();" << endl;
512     headerf << "\t\t" << "vector<TString>::const_iterator found_it = find(begin_it, end_it, trigName);" << endl;
513     headerf << "\t\t" << "if(found_it != end_it)" << endl;
514     headerf << "\t\t\t" << "trigIndx = found_it - begin_it;" << endl;
515     headerf << "\t\t" << "else {" << endl;
516     headerf << "\t\t\t" << "cout << \"Cannot find Trigger \" << trigName << endl; " << endl;
517     headerf << "\t\t\t" << "return 0;" << endl;
518     headerf << "\t\t" << "}" << endl << endl;
519     headerf << "\t" << "return hlt8e29_bits().TestBitNumber(trigIndx);" << endl;
520     headerf << "\t" << "}" << endl;
521     }//if(haveHLT8E29Info)
522    
523    
524     if(haveL1Info) {
525     //functions to return whether or not trigger fired - L1
526     headerf << "\t" << "bool passL1Trigger(TString trigName) {" << endl;
527     headerf << "\t\t" << "int trigIndx;" << endl;
528     headerf << "\t\t" << "vector<TString>::const_iterator begin_it = l1_trigNames().begin();" << endl;
529     headerf << "\t\t" << "vector<TString>::const_iterator end_it = l1_trigNames().end();" << endl;
530     headerf << "\t\t" << "vector<TString>::const_iterator found_it = find(begin_it, end_it, trigName);" << endl;
531     headerf << "\t\t" << "if(found_it != end_it)" << endl;
532     headerf << "\t\t\t" << "trigIndx = found_it - begin_it;" << endl;
533     headerf << "\t\t" << "else {" << endl;
534     headerf << "\t\t\t" << "cout << \"Cannot find Trigger \" << trigName << endl; " << endl;
535     headerf << "\t\t\t" << "return 0;" << endl;
536     headerf << "\t\t" << "}" << endl << endl;
537     //get the list of branches that hold the L1 bitmasks
538     //store in a set 'cause its automatically sorted
539     set<TString> s_L1bitmasks;
540     for(int j = 0; j < aliasarray->GetSize(); j++) {
541     TString aliasname(aliasarray->At(j)->GetName());
542     // TBranch *branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
543     TBranch *branch = 0;
544     if (have_aliases)
545     branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
546     else
547     branch = (TBranch*)aliasarray->At(j);
548    
549     TString classname = branch->GetClassName();
550     if(aliasname.Contains("l1_bits") && classname.Contains("int")) {
551     s_L1bitmasks.insert(aliasname);
552     }
553 fgolf 1.1
554 fgolf 1.3 }
555     int i = 0;
556     for(set<TString>::const_iterator s_it = s_L1bitmasks.begin();
557     s_it != s_L1bitmasks.end(); s_it++, i++) {
558 fgolf 1.1
559 fgolf 1.3 if(i==0) {
560     headerf << "\t\t" << "if(trigIndx <= 31) {" << endl;
561     headerf << "\t\t\t" << "unsigned int bitmask = 1;" << endl;
562     headerf << "\t\t\t" << "bitmask <<= trigIndx;" << endl;
563     headerf << "\t\t\t" << "return " << *s_it << "() & bitmask;" << endl;
564     headerf << "\t\t" << "}" << endl;
565     continue;
566     }
567     headerf << "\t\t" << "if(trigIndx >= " << Form("%d && trigIndx <= %d", 32*i, 32*i+31) << ") {" << endl;
568     headerf << "\t\t\t" << "unsigned int bitmask = 1;" << endl;
569     headerf << "\t\t\t" << "bitmask <<= (trigIndx - " << Form("%d",32*i) << "); " << endl;
570     headerf << "\t\t\t" << "return " << *s_it << "() & bitmask;" << endl;
571     headerf << "\t\t" << "}" << endl;
572     }
573     headerf << "\t" << "return 0;" << endl;
574     headerf << "\t" << "}" << endl;
575     }//if(haveL1Info)
576 fgolf 1.1
577 fgolf 1.3 headerf << endl;
578     headerf << " static void progress( int nEventsTotal, int nEventsChain ){" << endl;
579     headerf << " int period = 1000;" << endl;
580     headerf << " if(nEventsTotal%1000 == 0) {" << endl;
581     headerf << " // xterm magic from L. Vacavant and A. Cerri" << endl;
582     headerf << " if (isatty(1)) {" << endl;
583     headerf << " if( ( nEventsChain - nEventsTotal ) > period ){" << endl;
584     headerf << " float frac = (float)nEventsTotal/(nEventsChain*0.01);" << endl;
585     headerf << " printf(\"\\015\\033[32m ---> \\033[1m\\033[31m%4.1f%%\"" << endl;
586     headerf << " \"\\033[0m\\033[32m <---\\033[0m\\015\", frac);" << endl;
587     headerf << " fflush(stdout);" << endl;
588     headerf << " }" << endl;
589     headerf << " else {" << endl;
590     headerf << " printf(\"\\015\\033[32m ---> \\033[1m\\033[31m%4.1f%%\"" << endl;
591     headerf << " \"\\033[0m\\033[32m <---\\033[0m\\015\", 100.);" << endl;
592     headerf << " cout << endl;" << endl;
593     headerf << " }" << endl;
594     headerf << " }" << endl;
595     headerf << " }" << endl;
596     headerf << " }" << endl;
597     headerf << " " << endl;
598 fgolf 1.2
599 fgolf 1.3 headerf << "};" << endl << endl;
600 fgolf 1.1
601 fgolf 1.3 headerf << "#ifndef __CINT__" << endl;
602     headerf << "extern " << Classname << " cms2;" << endl;
603     headerf << "#endif" << endl << endl;
604    
605     // Create namespace that can be used to access the extern'd cms2
606     // object methods without having to type cms2. everywhere.
607     // Does not include cms2.Init and cms2.GetEntry because I think
608     // it is healthy to leave those methods as they are
609     headerf << "namespace tas {" << endl;
610     implf << "namespace tas {" << endl;
611     for (Int_t i = 0; i< aliasarray->GetSize(); i++) {
612     TString aliasname(aliasarray->At(i)->GetName());
613     // TBranch *branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
614     TBranch *branch = 0;
615     if (have_aliases)
616     branch = ev->GetBranch(ev->GetAlias(aliasname.Data()));
617     else
618     branch = (TBranch*)aliasarray->At(i);
619    
620     TString classname = branch->GetClassName();
621     TString title = branch->GetTitle();
622     if ( classname.Contains("vector") ) {
623     if(classname.Contains("edm::Wrapper") ) {
624     classname = classname(0,classname.Length()-2);
625     classname.ReplaceAll("edm::Wrapper<","");
626     }
627     headerf << "\t" << classname << " &" << aliasname << "()";
628     implf << "\t" << classname << " &" << aliasname << "()";
629     } else {
630     if(classname.Contains("edm::Wrapper<") ) {
631     classname = classname(0,classname.Length()-1);
632     classname.ReplaceAll("edm::Wrapper<","");
633     }
634     if(classname != "" ) {
635     headerf << "\t" << classname << " &" << aliasname << "()";
636     implf << "\t" << classname << " &" << aliasname << "()";
637     } else {
638     if(title.EndsWith("/i")){
639     headerf << "\tunsigned int &" << aliasname << "()";
640     implf << "\tunsigned int &" << aliasname << "()";
641     }
642     if(title.EndsWith("/F")){
643     headerf << "\tfloat &" << aliasname << "()";
644     implf << "\tfloat &" << aliasname << "()";
645     }
646     if(title.EndsWith("/I")){
647     headerf << "\tint &" << aliasname << "()";
648     implf << "\tint &" << aliasname << "()";
649     }
650     if(title.EndsWith("/O")){
651     headerf << "\tbool &" << aliasname << "()";
652     implf << "\tbool &" << aliasname << "()";
653     }
654     }
655     }
656     headerf << ";" << endl;
657     implf << " { return cms2." << aliasname << "(); }" << endl;
658     }
659     if(haveHLTInfo) {
660     //functions to return whether or not trigger fired - HLT
661     headerf << "\t" << "bool passHLTTrigger(TString trigName);" << endl;
662     implf << "\t" << "bool passHLTTrigger(TString trigName) { return cms2.passHLTTrigger(trigName); }" << endl;
663     }//if(haveHLTInfo)
664     if(haveHLT8E29Info) {
665     //functions to return whether or not trigger fired - HLT
666     headerf << "\t" << "bool passHLT8E29Trigger(TString trigName);" << endl;
667     implf << "\t" << "bool passHLT8E29Trigger(TString trigName) { return cms2.passHLT8E29Trigger(trigName); }" << endl;
668     }//if(haveHLT8E29Info)
669     if(haveL1Info) {
670     //functions to return whether or not trigger fired - L1
671     headerf << "\t" << "bool passL1Trigger(TString trigName);" << endl;
672     implf << "\t" << "bool passL1Trigger(TString trigName) { return cms2.passL1Trigger(trigName); }" << endl;
673     }//if(haveL1Info)
674 fgolf 1.2
675 fgolf 1.1 }
676    
677     //-------------------------------------------------------------------------------------------------
678     void makeSrcFile(std::string Classname, std::string branchNamesFile) {
679    
680 fgolf 1.3 // TTree *ev = (TTree*)f->Get("Events");
681 fgolf 1.1
682 fgolf 1.3 codef << "// Usage:" << endl;
683     codef << "// > root -b doAll.C" << endl;
684     codef << "" << endl;
685     codef << "// C++" << endl;
686     codef << "#include <iostream>" << endl;
687     codef << "#include <vector>" << endl;
688     codef << "" << endl;
689     codef << "// ROOT" << endl;
690     codef << "#include \"TBenchmark.h\"" << endl;
691     codef << "#include \"TChain.h\"" << endl;
692     codef << "#include \"TDirectory.h\"" << endl;
693     codef << "#include \"TFile.h\"" << endl;
694     codef << "#include \"TROOT.h\"" << endl;
695     codef << "#include \"TTreeCache.h\"" << endl;
696     codef << "" << endl;
697     codef << "// CMS2" << endl;
698     codef << "#include \"" + Classname+".cc\"" << endl;
699     if(branchNamesFile!="")
700     codef << "#include \"branches.h\"" << endl;
701     codef << "" << endl;
702     codef << "using namespace std;" << endl;
703     codef << "using namespace tas;" << endl;
704     codef << endl;
705     codef << "int ScanChain( TChain* chain, bool fast = true, int nEvents = -1, string skimFilePrefix = \"test\") {" << endl;
706     codef << "" << endl;
707     codef << " // Benchmark" << endl;
708     codef << " TBenchmark *bmark = new TBenchmark();" << endl;
709     codef << " bmark->Start(\"benchmark\");" << endl;
710     codef << "" << endl;
711     codef << " // Example Histograms" << endl;
712     codef << " TDirectory *rootdir = gDirectory->GetDirectory(\"Rint:\");" << endl;
713     codef << " TH1F *samplehisto = new TH1F(\"samplehisto\", \"Example histogram\", 200,0,200);" << endl;
714     codef << " samplehisto->SetDirectory(rootdir);" << endl;
715     codef << "" << endl;
716     codef << " // Loop over events to Analyze" << endl;
717     codef << " unsigned int nEventsTotal = 0;" << endl;
718     codef << " unsigned int nEventsChain = chain->GetEntries();" << endl;
719     codef << " if( nEvents >= 0 ) nEventsChain = nEvents;" << endl;
720     if(branchNamesFile!="")
721     codef << " InitSkimmedTree(skimFilePrefix);" << endl;
722     codef << " TObjArray *listOfFiles = chain->GetListOfFiles();" << endl;
723     codef << " TIter fileIter(listOfFiles);" << endl;
724     codef << " TFile *currentFile = 0;" << endl;
725     codef << "" << endl;
726     codef << " // File Loop" << endl;
727     codef << " while ( (currentFile = (TFile*)fileIter.Next()) ) {" << endl;
728     codef << "" << endl;
729     codef << " // Get File Content" << endl;
730     codef << " TFile *file = new TFile( currentFile->GetTitle() );" << endl;
731     codef << " TTree *tree = (TTree*)file->Get(\"Events\");" << endl;
732     codef << " if(fast) TTreeCache::SetLearnEntries(10);" << endl;
733     codef << " if(fast) tree->SetCacheSize(128*1024*1024);" << endl;
734     codef << " cms2.Init(tree);" << endl;
735     codef << " " << endl;
736     codef << " // Loop over Events in current file" << endl;
737     codef << " if( nEventsTotal >= nEventsChain ) continue;" << endl;
738     codef << " unsigned int nEventsTree = tree->GetEntriesFast();" << endl;
739     codef << " for( unsigned int event = 0; event < nEventsTree; ++event) {" << endl;
740     codef << " " << endl;
741     codef << " // Get Event Content" << endl;
742     codef << " if( nEventsTotal >= nEventsChain ) continue;" << endl;
743     codef << " if(fast) tree->LoadTree(event);" << endl;
744     codef << " cms2.GetEntry(event);" << endl;
745     codef << " ++nEventsTotal;" << endl;
746     codef << " " << endl;
747     codef << " // Progress" << endl;
748     codef << " CMS2::progress( nEventsTotal, nEventsChain );" << endl << endl;
749     codef << " // Analysis Code" << endl << endl;
750     codef << " }" << endl;
751     codef << " " << endl;
752     codef << " // Clean Up" << endl;
753     codef << " delete tree;" << endl;
754     codef << " file->Close();" << endl;
755     codef << " delete file;" << endl;
756     codef << " }" << endl;
757     codef << " if ( nEventsChain != nEventsTotal ) {" << endl;
758     codef << " cout << Form( \"ERROR: number of events from files (\%d) is not equal to total number of events (\%d)\", nEventsChain, nEventsTotal ) << endl;" << endl;
759     codef << " }" << endl;
760     if(branchNamesFile!="") {
761     codef << " outFile_->cd();" << endl;
762     codef << " outTree_->Write();" << endl;
763     codef << " outFile_->Close();" << endl;
764     }
765     codef << " " << endl;
766     codef << " // Example Histograms" << endl;
767     codef << " samplehisto->Draw();" << endl;
768     codef << " " << endl;
769     codef << " // return" << endl;
770     codef << " bmark->Stop(\"benchmark\");" << endl;
771     codef << " cout << endl;" << endl;
772     codef << " cout << nEventsTotal << \" Events Processed\" << endl;" << endl;
773     codef << " cout << \"------------------------------\" << endl;" << endl;
774     codef << " cout << \"CPU Time:\t\" << Form( \"\%.01f\", bmark->GetCpuTime(\"benchmark\") ) << endl;" << endl;
775     codef << " cout << \"Real Time:\t\" << Form( \"\%.01f\", bmark->GetRealTime(\"benchmark\") ) << endl;" << endl;
776     codef << " cout << endl;" << endl;
777     codef << " delete bmark;" << endl;
778     codef << " return 0;" << endl;
779     codef << "}" << endl;
780 fgolf 1.1
781     }
782    
783    
784     //-------------------------------------------------------------------------------------------------
785     void makeBranchFile(std::string branchNamesFile) {
786    
787 fgolf 1.3 ifstream branchesF(branchNamesFile.c_str());
788     vector<TString> v_datatypes;
789     vector<TString> v_varNames;
790     while(!branchesF.eof()) {
791     string temp;
792     getline(branchesF, temp);
793     TString line(temp);
794     // do not use commented lines
795     if(line.BeginsWith("//"))
796     continue;
797     vector<TString> v_line;
798     TIter objIt((TObjArray*)line.Tokenize(" "));
799     while(TObject *obj = (TObject*)objIt.Next()) {
800     if(obj==NULL)
801     continue;
802     v_line.push_back(obj->GetName());
803     }
804    
805     if(v_line.size() == 0)
806     continue;
807     TString varName;
808     //loop over v_line until you get to the first element thats not a space
809     for(vector<TString>::iterator it = v_line.begin();
810     it != v_line.end(); it++) {
811     if( *it != " " ) {
812     varName = *it;
813     }
814     }
815 fgolf 1.1
816 fgolf 1.3 v_varNames.push_back(varName.Strip()); //paranoid....strips trailing spaces
817     TString datatype("");
818     for(unsigned int i = 0; i < v_line.size()-1; i++) {
819     TString temp2 = v_line[i];
820     if(temp2.Contains("vector") && !temp2.Contains("std::")) temp2.ReplaceAll("vector", "std::vector");
821     if(temp2.Contains("LorentzVector") && !temp2.Contains("ROOT::Math::LorentzVector")) temp2.ReplaceAll("LorentzVector", "ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> >");
822     temp2.ReplaceAll(">>", "> >");
823     temp2.ReplaceAll(">>>", "> > >");
824     if(i!=0) datatype = datatype+" " + temp2;
825     else datatype = datatype+temp2;
826     }
827     v_datatypes.push_back(datatype);
828 fgolf 1.1
829 fgolf 1.3 }
830     branchfile.open("branches.h");
831     branchfile << "#ifndef BRANCHES_H" << endl << "#define BRANCHES_H" << endl;
832     branchfile << "#include <vector>" << endl;
833     branchfile << "#include \"TFile.h\"" << endl;
834     branchfile << "#include \"TTree.h\"" << endl << endl << endl << endl;
835    
836     for(unsigned int i = 0; i < v_datatypes.size(); i++) {
837     TString temp2(v_varNames.at(i));
838     if(v_datatypes.at(i).Contains("vector") || v_datatypes.at(i).Contains("LorentzVector")) {
839     branchfile << v_datatypes.at(i) << " *" << temp2.ReplaceAll("_","")+"_;" << endl;
840     continue;
841     }
842     branchfile << v_datatypes.at(i) << " " << temp2.ReplaceAll("_","")+"_;" << endl;
843     }
844    
845    
846     branchfile << "TFile *outFile_;" << endl;
847     branchfile << "TTree *outTree_;" << endl;
848    
849     //now declare the branches and set aliases in the InitSkimmedTree function
850     branchfile << "void InitSkimmedTree(std::string skimFilePrefix=\"\") {\n\n";
851     branchfile << " if(skimFilePrefix != \"\")" << endl;
852     branchfile << " outFile_ = TFile::Open(string(skimFilePrefix + \"_skimmednTuple.root\").c_str(),\"RECREATE\");\n";
853     branchfile << " else outFile_ = TFile::Open(\"skimmednTuple.root\", \"RECREATE\");\n";
854     branchfile << " outFile_->cd();" << endl;
855     branchfile << " outTree_ = new TTree(\"Events\", \"\");\n\n";
856     branchfile << " //book the branches\n";
857     for(unsigned int i = 0; i < v_datatypes.size(); i++) {
858     TString varName = v_varNames[i];
859     varName = varName.ReplaceAll("_", "") + "_";
860     TString varType = v_datatypes[i];
861     if(varType.BeginsWith("std::vector")
862     || varType.BeginsWith("ROOT::Math") ) {
863     TString prefix = "";
864     if(varType.BeginsWith("std::vector<float>") )
865     prefix = "floats";
866     if(varType.BeginsWith("std::vector<int>") )
867     prefix = "ints";
868     if(varType.BeginsWith("std::vector<unsigned int>") )
869     prefix = "uints";
870     if(varType.BeginsWith("ROOT::Math::LorentzVector<") )
871     prefix = "floatROOTMathPxPyPzE4DROOTMathLorentzVector";
872     if(varType.BeginsWith("std::vector<ROOT::Math::LorentzVector<") )
873     prefix = "floatROOTMathPxPyPzE4DROOTMathLorentzVectors";
874     if(varType.Contains("std::vector<std::vector<ROOT::Math::LorentzVector<") )
875     prefix = "floatROOTMathPxPyPzE4DROOTMathLorentzVectorss";
876     branchfile << " outTree_->Branch(\"" << prefix + "_" +varName << "\", \""
877     << varType << "\", &" << varName << ");" << endl;
878     branchfile << " outTree_->SetAlias(\"" << v_varNames[i] << "\", "
879     << "\"" << prefix+"_"+varName << "\");" << endl;
880     continue;
881     }
882     if(varType=="float" || varType == "Float_t") {
883     branchfile << " outTree_->Branch(\"" << varName << "\", &" << varName;
884     branchfile << ", \"" << varName + "/F\");" << endl;
885     branchfile << " outTree_->SetAlias(\"" << v_varNames[i] << "\", "
886     << "\"" << varName << "\");" << endl;
887     continue;
888     }
889     if(varType=="unsigned int" || varType == "UInt_t") {
890     branchfile << " outTree_->Branch(\"" << varName << "\", &" << varName;
891     branchfile << ", \"" << varName + "/i\");" << endl;
892     branchfile << " outTree_->SetAlias(\"" << v_varNames[i] << "\", "
893     << "\"" << varName << "\");" << endl;
894     continue;
895     }
896     if(varType=="int" || varType == "Int_t") {
897     branchfile << " outTree_->Branch(\"" << varName << "\", &" << varName;
898     branchfile << ", \"" << varName + "/I\");" << endl;
899     branchfile << " outTree_->SetAlias(\"" << v_varNames[i] << "\", "
900     << "\"" << varName << "\");" << endl;
901     continue;
902     }
903 fgolf 1.1 }
904 fgolf 1.3 branchfile << "} " << endl;
905     branchfile << "#endif" << endl;
906 fgolf 1.1
907 fgolf 1.3 branchfile.close();
908 fgolf 1.1 }
909    
910    
911     void makeDriverFile(std::string fname) {
912    
913 fgolf 1.3 ofstream driverF;
914     driverF.open("doAll.C");
915 fgolf 1.1
916 fgolf 1.3 driverF << "{" << endl << endl;
917     driverF << " gROOT->ProcessLine(\".L ScanChain.C+\");" << endl << endl;
918     driverF << " TChain *ch = new TChain(\"Events\"); " << endl;
919     driverF << " ch->Add(\"" + fname + "\");" << endl;
920     driverF << " ScanChain(ch); " << endl;
921     driverF << "}";
922     driverF.close();
923 fgolf 1.1
924    
925     }