ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitHzz4l/Angles/src/fillBdtTree.cc
Revision: 1.1
Committed: Tue Oct 23 10:10:07 2012 UTC (12 years, 6 months ago) by dkralph
Content type: text/plain
Branch: MAIN
Log Message:
finally ci'ing all dkralph's changes

File Contents

# User Rev Content
1 dkralph 1.1 #include <iostream>
2     #include <assert.h>
3     #include <stdio.h>
4     #include <stdlib.h>
5     #include <getopt.h>
6     #include <string.h>
7     #include <utility>
8     #include <map>
9     #include <boost/regex.hpp>
10    
11     #include "TFile.h"
12     #include "TChain.h"
13     #include "TList.h"
14     #include "TRegexp.h"
15     #include "TTree.h"
16     #include "TBranch.h"
17    
18     #include "ZZMatrixElement/MELA/interface/Mela.h"
19    
20     #include "TMVA/Reader.h"
21     #include "TMVA/Tools.h"
22     #include "TMVA/Config.h"
23     #include "TMVA/MethodBDT.h"
24    
25     #include "KinematicsStruct.h"
26     #include "AngleTuple.h"
27     #include "filestuff.h"
28     #include "Angles.h"
29     #include "WeightStruct.h"
30     #include "SampleWeight.h"
31     #include "varkeepter.h"
32    
33     #ifndef CMSSW_BASE
34     #define CMSSW_BASE "../../"
35     #endif
36    
37     using namespace std;
38    
39     class CtrlFlags
40     {
41     public :
42     CtrlFlags():inputfile(""),
43     inputtree("zznt"),
44     weightfile(""),
45     output("test.root"),
46     mH_lo(-1),
47     mH_hi(-1),
48     wL(0),
49     wH(0),
50     varstring(""),
51     makeMela(false),
52     multiclass(false),
53     flattree(false),
54     multisigs(false),
55     era(-1),
56     withPtY(false)
57     { };
58     ~CtrlFlags() {};
59     void dump();
60    
61     string inputfile;
62     string inputtree;
63     string weightfile;
64     string output;
65     float mH_lo,mH_hi;
66     float wL,wH;
67     TString varstring;
68     bool makeMela;
69     bool multiclass;
70     bool flattree;
71     bool multisigs;
72     int era;
73     bool withPtY;
74     };
75     void CtrlFlags::dump()
76     {
77     cout << "inputfile : " << inputfile << endl;
78     cout << "inputtree : " << inputtree << endl;
79     cout << "weightfile : " << weightfile << endl;
80     cout << "output : " << output << endl;
81     cout << "mH_lo : " << mH_lo << endl;
82     cout << "mH_hi : " << mH_hi << endl;
83     cout << "wL : " << wL << endl;
84     cout << "wH : " << wH << endl;
85     cout << "varstring : " << varstring << endl;
86     cout << "makeMela : " << makeMela << endl;
87     cout << "multiclass : " << multiclass << endl;
88     cout << "flattree : " << flattree << endl;
89     cout << "multisigs : " << multisigs << endl;
90     cout << "withPtY : " << withPtY << endl;
91     assert(era==2011 || era==2012);
92     cout << "era : " << era << endl;
93     }
94    
95     void parse_args( int, char**, CtrlFlags & );
96     void setFracs(float mH, float mH_lo, float mH_hi, float &wgt_lo, float &wgt_hi);
97     // void setMelaVals(varkeepter *melaOutput, filestuff *fs, TString cls, Mela *mela);
98     void setZzntVals(CtrlFlags &flags, varkeepter *flatoutput, filestuff *fs, TString cls, TMVA::Reader *reader=0, Mela *mela=0, TMVA::Reader *spinReader=0);
99     double getWeight(TH1F *hist, float val);
100     void setPtWgtHists(TString cls, TString fname, Long_t mH, TFile *wgtFile);
101     TH1F *hLoWgts,*hHiWgts;
102    
103     //------------------------------------------------------------
104     int main(int argc, char ** argv)
105     //------------------------------------------------------------
106     {
107    
108     CtrlFlags flags;
109     parse_args( argc, argv, flags);
110     flags.dump();
111     assert(flags.varstring!="");
112     assert(fopen(flags.weightfile.c_str(), "r") || flags.makeMela);
113    
114     TFile *pt4lWgts = TFile::Open("data/pt4l/pt4l_weights.root");
115    
116     TString cmsswpath(CMSSW_BASE + TString("/src"));
117     string xspath = (string(cmsswpath)+"/MitPhysics/data/xs.dat");
118     SimpleTable xstab(xspath.c_str());
119    
120     //
121     // setup input
122     //
123    
124     cout << "flags: ----------------------------------------------------------------------------------------" << endl;
125     cout << "inputfile: " << flags.inputfile << endl;
126     cout << "output: " << flags.output << endl;
127    
128     TString spinWeightFile("");//ntupledir;
129     vector<TString> classes,fileNames;
130     vector<double> fileFracs,fileMasses;
131     vector<TFile*> inFiles;
132     vector<TTree*> inTrees;
133     ifstream ifs(flags.inputfile.c_str());
134     assert(ifs.is_open());
135     string line;
136     while(getline(ifs,line)) {
137     if(line[0]=='#') continue;
138     stringstream ss(line);
139     if(line[0]=='^') {
140     TString dummy;
141     // if(TString(line).Contains("^ntupledir")) ss >> dummy >> ntupledir;
142     if(TString(line).Contains("^spinWeightFile")) { ss >> dummy >> spinWeightFile; cout << "spinWeightFile: " << spinWeightFile << endl; }
143     continue;
144     }
145    
146     TString cls,fname;
147     double frac,fileMass;
148     ss >> cls >> frac >> fname >> fileMass;
149     assert(cls=="gfH" || cls=="qqH" || cls=="qqZZ" || cls=="ggZZ" || cls=="lljj" || cls=="data");
150     classes.push_back(cls);
151     fileNames.push_back(/*ntupledir+"/"+*/fname);
152     fileFracs.push_back(frac);
153     fileMasses.push_back(fileMass);
154     inFiles.push_back(TFile::Open(fname));
155     assert(inFiles.back()->IsOpen());
156     inTrees.push_back((TTree*)inFiles.back()->Get(flags.inputtree.c_str()));
157     assert(inTrees.back());
158     cout << " pushing back: " << cls << " " << setw(12) << frac << " " << fname << " " << fileMass << endl;
159     }
160     ifs.close();
161    
162     // mass cut based on weightfile name ...
163     float mH = 120;
164     boost::regex expression2(".*_mH(.*)_.*");
165     boost::cmatch match2;
166     if(boost::regex_match(flags.weightfile.c_str(), match2, expression2))
167     mH = std::strtof(match2[1].first,NULL);
168    
169     // assert(flags.wL>=0 && flags.wL < 1000 && flags.wH >= 0 && flags.wH < 1000);
170     char cutstr[512];
171     sprintf(cutstr, "m4l>%.3f&&m4l<%.3f", flags.wL, flags.wH);
172     cout << "mH: " << setw(8) << mH
173     << " wL: " << setw(8) << flags.wL
174     << " wH: " << setw(8) << flags.wH
175     << " mH_lo: " << setw(8) << flags.mH_lo
176     << " mH_hi: " << setw(8) << flags.mH_hi
177     << endl;
178    
179     float frac_lo=1,frac_hi=1;
180     map<double,double> mH_fracs;
181     mH_fracs[-1] = 1; // this means zz
182     if(flags.mH_lo != 0) {
183     setFracs(mH, flags.mH_lo, flags.mH_hi, frac_lo, frac_hi);
184     mH_fracs[flags.mH_lo] = frac_lo;
185     mH_fracs[flags.mH_hi] = frac_hi;
186     }
187     mH_fracs[mH] = 1;
188    
189     unsigned nMin=9999999;
190     vector<double> passFracs;
191     for(unsigned ifile=0; ifile<fileNames.size(); ifile++) {
192     cout << classes[ifile] << ": "
193     << setw(8) << inTrees[ifile]->GetEntries(cutstr) << " / " << setw(8) << inTrees[ifile]->GetEntries() << " events pass cut in file: " << fileNames[ifile] << endl;
194     int nEntriesWithCut = inTrees[ifile]->GetEntries(cutstr);
195     if(nEntriesWithCut < nMin) nMin = nEntriesWithCut;
196     passFracs.push_back( double(nEntriesWithCut)/inTrees[ifile]->GetEntries() );
197     }
198    
199     cout << "twice the min number of entries over all the files, 2*nMin: " << 2*nMin << endl;
200    
201     TString tmpfname(flags.output);
202     tmpfname.ReplaceAll("/","-");
203     tmpfname = "/tmp/"+tmpfname+"-tmpfile.root";
204     TFile tmpfile(tmpfname,"recreate");
205     vector<TTree*> TreeCopies; // copies of the input trees, but with only the number of events we want
206     TList *treeList = new TList;
207     vector<long> nActuallyAdded,nActuallyAddedCumulative;
208     cout << "making tree copies: " << endl;
209     for(unsigned ifile=0; ifile<fileNames.size(); ifile++) {
210     if(mH_fracs.find(fileMasses[ifile]) == mH_fracs.end())
211     cout << "ERROR: filemasses[ifile]: " << fileMasses[ifile] << endl;
212     assert(mH_fracs.find(fileMasses[ifile]) != mH_fracs.end());
213     double fracThisFile,nTarget;
214     long nToRequest;
215     if(fileFracs[ifile] == 1) { // use all of this sample (eg for background)
216     fracThisFile = 1;
217     nTarget = passFracs[ifile]*inTrees[ifile]->GetEntries();
218     nToRequest = 1000000000; // use default value for TTree::CopyTree(): all of 'em
219     } else {
220     if(fileFracs[ifile] == -1)
221     fracThisFile = mH_fracs[fileMasses[ifile]]; // get fraction for this sample from function
222     else
223     fracThisFile = fileFracs[ifile]; // get fraction for this sample from txt file
224     nTarget = 2*fracThisFile*nMin;
225     nToRequest = nTarget / passFracs[ifile];
226     }
227     cout << " adding " << setw(12) << nTarget << " from file " << fileNames[ifile]
228     << ", which means asking for: " << nToRequest << endl;
229     TreeCopies.push_back(inTrees[ifile]->CopyTree(cutstr,"",nToRequest));
230    
231     long nCumulative=0;
232     for(unsigned j=0; j<nActuallyAdded.size(); j++) nCumulative += nActuallyAdded[j];
233     nActuallyAddedCumulative.push_back(nCumulative);
234     nActuallyAdded.push_back(long(TreeCopies.back()->GetEntries()));
235     cout << "actually added : " << nActuallyAdded.back() << ", cumulative: " << nActuallyAddedCumulative.back() << endl;
236    
237     treeList->Add(TreeCopies.back());
238     }
239    
240     TTree * t_tmp = TTree::MergeTrees(treeList);
241     tmpfile.Write();
242     tmpfile.Close();
243    
244     //
245     // setup output
246     //
247     filestuff fs(tmpfname,tmpfname,"",classes[0]=="data");
248     float f_bdt;
249     TBranch *br_bdt=0;
250     varkeepter *flatoutput=0;
251     // if(flags.makeMela) {
252     // flatoutput = new varkeepter("Angles/data/melavars.txt","w",flags.output.c_str(),42,"zznt");
253     // } else if(flags.flattree) {
254     TString varfname("zzntvars");
255     if(flags.multisigs) varfname += "-multisigs";
256     flatoutput = new varkeepter("Angles/data/"+varfname+".txt","w",flags.output.c_str(),42,"zznt");
257     // } else {
258     // fs.makeOutputFile(flags.output.c_str(),false); // don't make the fo tree
259     // br_bdt = fs.outtuple->getTree()->Branch("BDT", &f_bdt);
260     // }
261    
262     //
263     // setup TMVA
264     //
265     float reduced_mZ1, reduced_mZ2;
266     float reduced_zzdotz1, reduced_zzdotz2;
267     float reduced_ZZpt, reduced_Z1pt, reduced_Z2pt;
268    
269     map<string,bool> varmap;
270     char * dovar = strtok(const_cast<char *>(flags.varstring.Data()), ":");
271     if( dovar != NULL ) varmap[string(dovar)]=true;
272     while( (dovar = strtok(NULL, ":")) != NULL ) {
273     varmap[string(dovar)]=true;
274     }
275    
276     TMVA::Reader *reader=0,*spinReader=0;
277     Mela *mela=0;
278     if(!flags.makeMela) {
279     reader = new TMVA::Reader( "V" );
280     if(varmap[string("costheta1")]) reader->AddVariable( "costheta1", &fs.angles->costheta1);
281     if(varmap[string("costheta2")]) reader->AddVariable( "costheta2", &fs.angles->costheta2);
282     if(varmap[string("costhetastar")]) reader->AddVariable( "costhetastar", &fs.angles->costhetastar);
283     if(varmap[string("Phi")]) reader->AddVariable( "Phi", &fs.angles->Phi);
284     if(varmap[string("Phi1")]) reader->AddVariable( "Phi1", &fs.angles->Phi1);
285     if(varmap[string("mZ1")]) reader->AddVariable( "mZ1", &reduced_mZ1);
286     if(varmap[string("mZ2")]) reader->AddVariable( "mZ2", &reduced_mZ2);
287     if(varmap[string("pt4l")]) reader->AddVariable( "ZZpt/m4l", &reduced_ZZpt);
288     if(varmap[string("zzdotz1")]) reader->AddVariable( "ZZdotZ1/(m4l*mZ1)", &reduced_zzdotz1 );
289     if(varmap[string("zzdotz2")]) reader->AddVariable( "ZZdotZ2/(m4l*mZ2)", &reduced_zzdotz2 );
290     if(varmap[string("dphi1")]) reader->AddVariable( "ZZptCosDphiZ1pt", &fs.kine->ZZptZ1ptCosDphi );
291     if(varmap[string("dphi2")]) reader->AddVariable( "ZZptCosDphiZ2pt", &fs.kine->ZZptZ2ptCosDphi );
292     if(varmap[string("Z1pt")]) reader->AddVariable( "Z1pt/m4l", &reduced_Z1pt );
293     if(varmap[string("Z2pt")]) reader->AddVariable( "Z2pt/m4l", &reduced_Z2pt );
294     if(varmap[string("y4l")]) reader->AddVariable( "ZZy", &fs.kine->ZZy);
295     if(varmap[string("m4l")]) reader->AddVariable( "m4l", &fs.kine->m4l);
296     else reader->AddSpectator("m4l", &fs.kine->m4l);
297     reader->BookMVA("BDTG", flags.weightfile.c_str());
298     if(spinWeightFile != "") {
299     spinReader = new TMVA::Reader( "V" );
300     if(varmap[string("costheta1")]) spinReader->AddVariable( "costheta1", &fs.angles->costheta1);
301     if(varmap[string("costheta2")]) spinReader->AddVariable( "costheta2", &fs.angles->costheta2);
302     if(varmap[string("costhetastar")]) spinReader->AddVariable( "costhetastar", &fs.angles->costhetastar);
303     if(varmap[string("Phi")]) spinReader->AddVariable( "Phi", &fs.angles->Phi);
304     if(varmap[string("Phi1")]) spinReader->AddVariable( "Phi1", &fs.angles->Phi1);
305     if(varmap[string("mZ1")]) spinReader->AddVariable( "mZ1", &reduced_mZ1);
306     if(varmap[string("mZ2")]) spinReader->AddVariable( "mZ2", &reduced_mZ2);
307     if(varmap[string("pt4l")]) spinReader->AddVariable( "ZZpt/m4l", &reduced_ZZpt);
308     if(varmap[string("zzdotz1")]) spinReader->AddVariable( "ZZdotZ1/(m4l*mZ1)", &reduced_zzdotz1 );
309     if(varmap[string("zzdotz2")]) spinReader->AddVariable( "ZZdotZ2/(m4l*mZ2)", &reduced_zzdotz2 );
310     if(varmap[string("dphi1")]) spinReader->AddVariable( "ZZptCosDphiZ1pt", &fs.kine->ZZptZ1ptCosDphi );
311     if(varmap[string("dphi2")]) spinReader->AddVariable( "ZZptCosDphiZ2pt", &fs.kine->ZZptZ2ptCosDphi );
312     if(varmap[string("Z1pt")]) spinReader->AddVariable( "Z1pt/m4l", &reduced_Z1pt );
313     if(varmap[string("Z2pt")]) spinReader->AddVariable( "Z2pt/m4l", &reduced_Z2pt );
314     if(varmap[string("y4l")]) spinReader->AddVariable( "ZZy", &fs.kine->ZZy);
315     if(varmap[string("m4l")]) spinReader->AddVariable( "m4l", &fs.kine->m4l);
316     else spinReader->AddSpectator("m4l", &fs.kine->m4l);
317     spinReader->BookMVA("BDTG", spinWeightFile);
318     }
319     } else {
320     // mela = new Mela::Mela(bool usePowhegTemplate=false, int LHCsqrts=8);
321     mela = new Mela(false, flags.era==2011 ? 7 : 8);
322     }
323    
324     //
325     // evaluate
326     //
327     vector<unsigned> runv,evtv; // for removing duplicate events
328     int ifile=-1;
329     int nent=fs.get_zz_chain()->GetEntries();
330     cout << "beginning tree from mass " << mH << "(" << flags.wL << "," << flags.wH << ") with " << nent << " entries" << endl;
331     for( int i=0; i<nent; i++ ) {
332     if( !(i%5000) ) cerr << "processed: " << i << "/" << nent << endl;
333     fs.getentry(i,"","zznt");
334    
335     if(classes[0]=="data") { // the rest of the classes better be data as well...
336     bool isDuplic=false;
337     for(unsigned ievt=0; ievt<evtv.size(); ievt++) {
338     if((fs.info->run == runv[ievt]) && (fs.info->evt == evtv[ievt])) {
339     isDuplic = true;
340     break;
341     }
342     }
343     if(isDuplic) {
344     cout << " skipping duplicate event: " << fs.info->run << " " << fs.info->evt << endl;
345     continue;
346     }
347     }
348     runv.push_back(fs.info->run);
349     evtv.push_back(fs.info->evt);
350    
351     if(ifile+1 < (int)nActuallyAddedCumulative.size() && i >= nActuallyAddedCumulative[ifile+1]) {
352     ifile++;
353     cout << " ientry: " << i << ", switching file to (" << classes[ifile] << "): " << fileMasses[ifile]
354     << " so weight multiplies by: " << ((classes[ifile]=="gfH" || classes[ifile]=="qqH") ? mH_fracs[fileMasses[ifile]] : 1) << endl;
355     if(classes[ifile]=="gfH" || classes[ifile]=="qqZZ")
356     setPtWgtHists(classes[ifile],fileNames[ifile],mH,pt4lWgts);
357     }
358    
359     if( fs.kine->m4l>flags.wH || fs.kine->m4l<flags.wL ) { cout << "ERROR! shouldn't be here (already applied the cut): " << fs.kine->m4l << endl; continue; }
360    
361     reduced_mZ1 = fs.kine->mZ1;//fs.kine->m4l;
362     reduced_mZ2 = fs.kine->mZ2;///fs.kine->m4l;
363     reduced_ZZpt = fs.kine->ZZpt/fs.kine->m4l;
364     reduced_Z1pt = fs.kine->Z1pt/fs.kine->m4l;
365     reduced_Z2pt = fs.kine->Z2pt/fs.kine->m4l;
366     reduced_zzdotz1 = fs.kine->ZZdotZ1/(fs.kine->m4l*fs.kine->mZ1);
367     reduced_zzdotz2 = fs.kine->ZZdotZ2/(fs.kine->m4l*fs.kine->mZ2);
368    
369     // if(!flags.makeMela) {
370     // f_bdt = flags.multiclass ? (reader->EvaluateMulticlass("BDTG"))[0] : reader->EvaluateMVA("BDTG");
371     // fs.angles->bdt = f_bdt;
372     // }
373    
374     if(classes[ifile]=="gfH" || classes[ifile]=="qqH")
375     fs.weights->w *= mH_fracs[fileMasses[ifile]];
376    
377     if(!flags.makeMela && !flags.flattree) { // shouldn't ever use this at the point
378     fs.outtuple->Fill();
379     } else {
380     // if(flags.makeMela) setMelaVals(flatoutput, &fs, classes[ifile], mela);
381     // if(flags.flattree)
382     setZzntVals(flags, flatoutput, &fs, classes[ifile], reader, mela, spinReader);
383     flatoutput->fill();
384     }
385     }
386    
387     if(!flags.makeMela && !flags.flattree) {
388     fs.outtuple->getTree()->Print();
389     fs.outtuple->WriteClose();
390     } else {
391     flatoutput->gettree()->Print();
392     flatoutput->writeclose();
393     }
394     }
395     //----------------------------------------------------------
396     void parse_args( int argc, char** argv, CtrlFlags &flags )
397     //----------------------------------------------------------
398     {
399     int c;
400     int digit_optind = 0;
401    
402     while (1) {
403     int this_option_optind = optind ? optind : 1;
404     int option_index = 0;
405     static struct option long_options[] = {
406     {"inputfile", 1, 0, 'a'},
407     {"inputtree", 1, 0, 'b'},
408     {"weightfile", 1, 0, 'c'},
409     {"output", 1, 0, 'd'},
410     {"mH_lo", 1, 0, 'e'},
411     {"mH_hi", 1, 0, 'f'},
412     {"wL", 1, 0, 'g'},
413     {"wH", 1, 0, 'h'},
414     {"varstring", 1, 0, 'i'},
415     {"makeMela", 0, 0, 'j'},
416     {"multiclass", 0, 0, 'k'},
417     {"flattree", 0, 0, 'l'},
418     {"multisigs", 0, 0, 'm'},
419     {"era", 1, 0, 'n'},
420     {"withPtY", 0, 0, 'o'},
421     {0, 0, 0, 0}
422     };
423    
424     c = getopt_long (argc, argv, "a:e",
425     long_options, &option_index);
426     if (c == -1)
427     break;
428    
429     switch (c) {
430     case 0:
431     printf ("option %s", long_options[option_index].name);
432     if (optarg)
433     printf (" with arg %s", optarg);
434     printf ("\n");
435     break;
436    
437     case 'a':
438     flags.inputfile = std::string(optarg);
439     break;
440     case 'b':
441     flags.inputtree = std::string(optarg);
442     break;
443     case 'c':
444     flags.weightfile = std::string(optarg);
445     break;
446     case 'd':
447     flags.output = std::string(optarg);
448     break;
449     case 'e':
450     flags.mH_lo = strtof(optarg,NULL);
451     break;
452     case 'f':
453     flags.mH_hi = strtof(optarg,NULL);
454     break;
455     case 'g':
456     flags.wL = strtof(optarg,NULL);
457     break;
458     case 'h':
459     flags.wH = strtof(optarg,NULL);
460     break;
461     case 'i':
462     flags.varstring = TString(optarg);
463     break;
464     case 'j':
465     flags.makeMela = true;
466     break;
467     case 'k':
468     flags.multiclass = true;
469     break;
470     case 'l':
471     flags.flattree = true;
472     break;
473     case 'm':
474     flags.multisigs = true;
475     break;
476     case 'n':
477     flags.era = atoi(optarg);
478     assert(flags.era==2011 || flags.era==2012);
479     break;
480     case 'o':
481     flags.withPtY = true;
482     break;
483     case '2':
484     if (digit_optind != 0 && digit_optind != this_option_optind)
485     printf ("digits occur in two different argv-elements.\n");
486     digit_optind = this_option_optind;
487     printf ("option %c\n", c);
488     break;
489    
490     case '?':
491     break;
492    
493     default:
494     printf ("?? getopt returned character code 0%o ??\n", c);
495     }
496     }
497    
498     if( flags.inputfile.empty() ) {
499     cerr << "please specify an inputfile with --inputfile " << endl;
500     exit(1);
501     }
502    
503     if (optind < argc) {
504     printf ("non-option ARGV-elements: ");
505     while (optind < argc)
506     printf ("%s ", argv[optind++]);
507     printf ("\n");
508     }
509     }
510     //----------------------------------------------------------------------------------------
511     void setFracs(float mH, float mH_lo, float mH_hi, float &frac_lo, float &frac_hi)
512     {
513     assert(mH_lo<=mH && mH_hi>=mH && mH_lo>0 && mH_hi>0);
514     double delta = mH_hi - mH_lo;
515     frac_lo = (mH_hi - mH)/delta;
516     frac_hi = (mH - mH_lo)/delta;
517     }
518     //----------------------------------------------------------------------------------------
519     void setZzntVals(CtrlFlags &flags, varkeepter *flatoutput, filestuff *fs, TString cls, TMVA::Reader *reader, Mela *mela, TMVA::Reader *spinReader)
520     {
521     flatoutput->setval("run", (UInt_t)fs->info->run);
522     flatoutput->setval("evt", (UInt_t)fs->info->evt);
523     flatoutput->setval("channel", (UInt_t)fs->kine->channel);
524     flatoutput->setval("ZZpt", (Double_t)fs->kine->ZZpt);
525     flatoutput->setval("m4l", (Double_t)fs->kine->m4l);
526     flatoutput->setval("w", (Double_t)fs->weights->w);
527     flatoutput->setval("won", (Double_t)fs->weights->won);
528     flatoutput->setval("woff", (Double_t)fs->weights->woff);
529     flatoutput->setval("npuw", (Double_t)fs->weights->npuw);
530     if(cls=="qqZZ" || cls=="gfH") {
531     assert(fs->get_zz_chain()->FindBranch("geninfo"));
532     flatoutput->setval("pt4lDown", (Double_t)getWeight(hLoWgts,fs->gen->pt_zz));
533     cout << "setting pt4lDown to: " << flatoutput->getval("pt4lDown") << endl;
534     flatoutput->setval("pt4lUp", (Double_t)getWeight(hHiWgts,fs->gen->pt_zz));
535     cout << "setting pt4lUp to: " << flatoutput->getval("pt4lUp") << endl;
536     }
537     if(flags.multisigs) {
538     assert(spinReader);
539     flatoutput->setval("SpinBDT", (Float_t)spinReader->EvaluateMVA("BDTG"));
540     }
541     if(flags.makeMela) {
542     assert(mela);
543     TLorentzVector Z1_lept1, Z1_lept2, Z2_lept1, Z2_lept2;
544     KinematicsStruct kine(*(fs->kine));
545    
546     Z1_lept1.SetPtEtaPhiM( kine.l1pt, kine.l1eta, kine.l1phi, abs(kine.l1type)==13 ? 105.658369e-3 : 0.51099892e-3);
547     Z1_lept2.SetPtEtaPhiM( kine.l2pt, kine.l2eta, kine.l2phi, abs(kine.l2type)==13 ? 105.658369e-3 : 0.51099892e-3);
548     Z2_lept1.SetPtEtaPhiM( kine.l3pt, kine.l3eta, kine.l3phi, abs(kine.l3type)==13 ? 105.658369e-3 : 0.51099892e-3);
549     Z2_lept2.SetPtEtaPhiM( kine.l4pt, kine.l4eta, kine.l4phi, abs(kine.l4type)==13 ? 105.658369e-3 : 0.51099892e-3);
550    
551     // NOTE: it's p.d.g. ID, so opposite sign to the charge
552     int Z1_lept1Id(-1*kine.l1q*kine.l1type),Z1_lept2Id(-1*kine.l2q*kine.l2type),Z2_lept1Id(-1*kine.l3q*kine.l3type),Z2_lept2Id(-1*kine.l4q*kine.l4type);
553     float costhetastar,costheta1,costheta2,phi,phistar1,kd,psig,pbkg;
554     // cout
555     // << setw(12) << Z1_lept1.Pt() << setw(12) << Z1_lept1.Eta() << setw(12) << Z1_lept1.Phi() << setw(12) << Z1_lept1.M() << setw(12) << Z1_lept1Id << endl
556     // << setw(12) << Z1_lept2.Pt() << setw(12) << Z1_lept2.Eta() << setw(12) << Z1_lept2.Phi() << setw(12) << Z1_lept2.M() << setw(12) << Z1_lept2Id << endl
557     // << setw(12) << Z2_lept1.Pt() << setw(12) << Z2_lept1.Eta() << setw(12) << Z2_lept1.Phi() << setw(12) << Z2_lept1.M() << setw(12) << Z2_lept1Id << endl
558     // << setw(12) << Z2_lept2.Pt() << setw(12) << Z2_lept2.Eta() << setw(12) << Z2_lept2.Phi() << setw(12) << Z2_lept2.M() << setw(12) << Z2_lept2Id << endl;
559     mela->computeKD(Z1_lept1, Z1_lept1Id, Z1_lept2, Z1_lept2Id, Z2_lept1, Z2_lept1Id, Z2_lept2, Z2_lept2Id,
560     costhetastar, costheta1, costheta2, phi, phistar1, kd, psig, pbkg, flags.withPtY, flags.withPtY);
561    
562     flatoutput->setval("melaLD", (Float_t)kd);
563     } else {
564     assert(reader);
565     flatoutput->setval("BDT", (Float_t)(flags.multiclass ? (reader->EvaluateMulticlass("BDTG"))[0] : reader->EvaluateMVA("BDTG")));
566     }
567     }
568     //----------------------------------------------------------------------------------------
569     double getWeight(TH1F *hist, float val)
570     {
571     int bin = hist->FindBin(val);
572     // return 1 for out-of-bounds
573     if(bin<1 || bin>hist->GetNbinsX())
574     return 1;
575     return hist->GetBinContent(bin);
576     }
577     //----------------------------------------------------------------------------------------
578     TString findClosestPtWgts(TFile *wgtFile, int mH)
579     {
580     Long_t closestMass(-1);
581     TString closestMassStr;
582     TList *keys = wgtFile->GetListOfKeys();
583     for(unsigned ikey=0; ikey<keys->GetEntries(); ikey++) {
584     TString name(keys->At(ikey)->GetName());
585     cout << " name: " << name << endl;
586     TString tmpName(name(TRegexp("h[0-9][0-9]*zz4l")));
587     cout << " tmpName: " << tmpName << endl;
588     TString massStr(tmpName(TRegexp("[0-9][0-9]*")));
589     cout << " massStr: " << massStr << endl;
590     int mass = atoi(massStr);
591     if(mass<100 || mass > 1200) continue;
592     cout << " mass: " << mass << endl;
593     if(abs(mass - mH) < abs(closestMass - mH)) {
594     closestMass = mass;
595     closestMassStr = massStr;
596     }
597     }
598    
599     cout << "using closest mass of: " << closestMassStr << endl;
600     return closestMassStr;
601     }
602     //----------------------------------------------------------------------------------------
603     void setPtWgtHists(TString cls, TString fname, Long_t mH, TFile *wgtFile)
604     {
605     assert(wgtFile->IsOpen());
606    
607     TString procStr;
608     if(cls=="gfH") {
609     procStr = TString("h")+mH+"zz4l";
610     } else if(cls=="qqZZ") {
611     if(fname.Contains("zz4e")) procStr = "zz4e";
612     if(fname.Contains("zz4m")) procStr = "zz4m";
613     if(fname.Contains("zz2e2m")) procStr = "zz2e2m";
614     } else assert(0);
615     assert(procStr!="");
616    
617     TH1F *htest = (TH1F*)wgtFile->Get("LoWgts_"+procStr);
618     TString closestMass;
619     if(!htest) {
620     closestMass = findClosestPtWgts(wgtFile, mH);
621     stringstream ss;
622     ss << mH;
623     TString mHstr(ss.str());
624     procStr.ReplaceAll(mHstr,closestMass);
625     cout << "hist name replaced with: " << procStr << endl;
626     }
627    
628     hLoWgts = (TH1F*)wgtFile->Get("LoWgts_"+procStr); assert(hLoWgts);
629     hHiWgts = (TH1F*)wgtFile->Get("HiWgts_"+procStr); assert(hHiWgts);
630     }