JHUGen MELA  v2.4.1
Matrix element calculations as used in JHUGen. MELA is an important tool that was used for the Higgs boson discovery and for precise measurements of its structure and interactions. Please see the website https://spin.pha.jhu.edu/ and papers cited there for more details, and kindly cite those papers when using this code.
getResolution.c
Go to the documentation of this file.
1 #include <iostream>
2 #include <fstream>
3 #include <iomanip>
4 #include <utility>
5 #include <algorithm>
6 #include <cmath>
7 #include <cassert>
8 #include <string>
9 #include <vector>
10 #include <fstream>
11 #include <cstdlib>
12 #include <unordered_map>
13 #include "TROOT.h"
14 #include "TMath.h"
15 #include "TLorentzVector.h"
16 #include "TLorentzRotation.h"
17 #include "TFile.h"
18 #include "TTree.h"
19 #include "TChain.h"
20 #include "TString.h"
21 #include "TF1.h"
22 #include "TSpline.h"
23 #include "TCanvas.h"
24 #include "TH1F.h"
25 #include "TH2F.h"
26 #include "TH3F.h"
27 #include "TProfile.h"
28 #include "TGraphErrors.h"
29 #include "TRandom.h"
30 #include "RooGenericPdf.h"
31 #include "RooProdPdf.h"
32 #include "RooNumIntConfig.h"
33 #include "RooRealIntegral.h"
34 #include "RooPlot.h"
35 #include "RooDataSet.h"
36 #include "RooRandom.h"
37 #include "Mela.h"
38 #include "MELALinearInterpFunc.h"
39 #include "MELANCSplineFactory_1D.h"
40 #include "MELANCSplineFactory_2D.h"
41 
42 
43 using namespace std;
44 using namespace RooFit;
45 
46 
47 TString inputdir_7TeV = "/work-zfs/lhc/ianderso/hep/CJLST/140519/PRODFSR";
48 TString inputdir_8TeV = "/work-zfs/lhc/ianderso/hep/CJLST/140519b/PRODFSR_8TeV";
49 TString inputdir_13TeV = "root://lxcms03//data3/Higgs/170222";
50 
51 struct SimpleEntry{
52  int id;
53  float trueval;
54  float recoval;
55  float recotrackval;
56  float weight;
57 
58  SimpleEntry() : id(0), trueval(0), recoval(0), recotrackval(0), weight(0) {}
59  SimpleEntry(int id_, float trueval_, float recoval_, float recotrackval_=0, float weight_=1) : id(id_), trueval(trueval_), recoval(recoval_), recotrackval(recotrackval_), weight(weight_) {}
60 
61  bool operator != (const SimpleEntry& other)const{ return trueval!=other.trueval; }
62  bool operator == (const SimpleEntry& other)const{ return trueval==other.trueval; }
63  bool operator > (const SimpleEntry& other)const{ return trueval>other.trueval; }
64  bool operator >= (const SimpleEntry& other)const{ return trueval>=other.trueval; }
65  bool operator < (const SimpleEntry& other)const{ return trueval<other.trueval; }
66  bool operator <= (const SimpleEntry& other)const{ return trueval<=other.trueval; }
67 };
68 
69 template<typename T> void appendVector(std::vector<T>& a, std::vector<T>& b){ a.insert(a.end(), b.begin(), b.end()); }
70 
71 template<typename T> void addByLowest(std::vector<T>& valArray, T val, bool unique){
72  bool inserted = false;
73  for (typename std::vector<T>::iterator it = valArray.begin(); it<valArray.end(); it++){
74  if (*it>val || (!unique && *it==val)){
75  inserted=true;
76  valArray.insert(it, val);
77  break;
78  }
79  }
80  if (!inserted) valArray.push_back(val);
81 }
82 
83 template<typename T, typename U> void addByLowest(std::vector<std::pair<T, U>>& valArray, T val, U index){
84  bool inserted = false;
85  for (typename std::vector<std::pair<T, U>>::iterator it = valArray.begin(); it<valArray.end(); it++){
86  if ((*it).first>=val){
87  inserted=true;
88  if ((*it).second!=index) valArray.insert(it, std::pair<T, U>(val, index));
89  break;
90  }
91  }
92  if (!inserted) valArray.push_back(std::pair<T, U>(val, index));
93 }
94 
95 template<typename T, typename U> void addByLowest(std::vector<std::pair<T, U>>& valArray, std::vector<std::pair<T, U>>& inArray, bool consecutive=false, bool inputordered=false){
96  if (consecutive){
97  bool inserted = false;
98  typename std::vector<std::pair<T, U>>::iterator inbegin = inArray.begin();
99  typename std::vector<std::pair<T, U>>::iterator inend = inArray.end();
100  for (typename std::vector<std::pair<T, U>>::iterator it = valArray.begin(); it<valArray.end(); it++){
101  if ((*it).first>=(*inbegin).first){
102  inserted=true;
103  if ((*it).second!=(*inbegin).second) valArray.insert(it, inbegin, inend);
104  break;
105  }
106  }
107  if (!inserted) appendVector<pair<T, U>>(valArray, inArray);
108  }
109  else if (!inputordered){
110  for (typename std::vector<std::pair<T, U>>::iterator init = inArray.begin(); init<inArray.end(); init++){
111  bool inserted = false;
112  for (typename std::vector<std::pair<T, U>>::iterator it = valArray.begin(); it<valArray.end(); it++){
113  if ((*it).first>=(*init).first){
114  inserted=true;
115  if ((*it).second!=(*init).second) valArray.insert(it, *init);
116  break;
117  }
118  }
119  if (!inserted) valArray.push_back(*init);
120  }
121  }
122  else if (inArray.size()>0){
123  typename std::vector<std::pair<T, U>>::iterator infirst = inArray.begin();
124  typename std::vector<std::pair<T, U>>::iterator inlast = inArray.end()-1;
125  typename std::vector<std::pair<T, U>>::iterator valfirst = valArray.begin();
126  typename std::vector<std::pair<T, U>>::iterator vallast = valArray.end()-1;
127  while ((*valfirst).first<(*infirst).first) valfirst++;
128  while ((*vallast).first>=(*inlast).first) vallast--;
129  vallast++;
130  inlast++;
131 
132  for (typename std::vector<std::pair<T, U>>::iterator init = infirst; init<inlast; init++){
133  bool inserted = false;
134  for (typename std::vector<std::pair<T, U>>::iterator it = valfirst; it<vallast; it++){
135  if ((*it).first>=(*init).first){
136  inserted=true;
137  if ((*it).second!=(*init).second) valArray.insert(it, *init);
138  break;
139  }
140  }
141  if (!inserted) valArray.insert(vallast, *init);
142  }
143  }
144 }
145 
146 template<typename T> bool checkListVariable(const vector<T>& list, const T& var){
147  for (unsigned int v=0; v<list.size(); v++){
148  if (list.at(v)==var) return true; // Look for exact match
149  }
150  return false;
151 }
152 
153 void splitOption(const string rawoption, string& wish, string& value, char delimiter){
154  size_t posEq = rawoption.find(delimiter);
155  if (posEq!=string::npos){
156  wish=rawoption;
157  value=rawoption.substr(posEq+1);
158  wish.erase(wish.begin()+posEq, wish.end());
159  }
160  else{
161  wish="";
162  value=rawoption;
163  }
164 }
165 void splitOptionRecursive(const string rawoption, vector<string>& splitoptions, char delimiter){
166  string suboption=rawoption, result=rawoption;
167  string remnant;
168  while (result!=""){
169  splitOption(suboption, result, remnant, delimiter);
170  if (result!="" && !checkListVariable(splitoptions, result)) splitoptions.push_back(result);
171  suboption = remnant;
172  }
173  if (remnant!="") splitoptions.push_back(remnant);
174 }
175 
176 struct ExtBin{
177  double binlow;
178  double binhigh;
179 
180  vector<SimpleEntry> collection;
181 
183  collection.push_back(evt);
184  }
185  void addEvent(int ev, float trueval, float recoval, float recotrackval=0, float weight=1){
186  SimpleEntry tmp(ev, trueval, recoval, recotrackval, weight);
187  collection.push_back(tmp);
188  }
189  void sortByRecoMinusTrueVals(vector<pair<float, int>>& res){
190  res.clear();
191  for (unsigned int ev=0; ev<collection.size(); ev++){
192  float val = collection.at(ev).recoval/collection.at(ev).trueval-1.;
193  addByLowest<float, int>(res, val, ev);
194  }
195  }
196  void sortByRecoVals(vector<pair<float, int>>& res){
197  res.clear();
198  for (unsigned int ev=0; ev<collection.size(); ev++) addByLowest<float, int>(res, collection.at(ev).recoval, ev);
199  }
200  void sift(double threshold=0.998, bool use_recominustrue=false){
201  if (collection.size()==0) return;
202 
203  vector<int> take_out;
204  vector<pair<float, int>> theEntries;
205  if (!use_recominustrue) sortByRecoVals(theEntries);
206  else sortByRecoMinusTrueVals(theEntries);
207  for (unsigned int im=0; im<2; im++){
208  int at99p8ev = std::floor((float(theEntries.size()))*threshold);
209  int bin=theEntries.size()-1;
210  while (bin>at99p8ev){
211  if (
212  theEntries.at(at99p8ev).first*2.<theEntries.at(bin).first
213  ) addByLowest<int>(take_out, theEntries.at(bin).second, true);
214  bin--;
215  }
216  }
217  for (int bin=take_out.size()-1; bin>=0; bin--){
218  int t_ev = take_out.at(bin);
219  cout << "Attempting to discard event at position " << t_ev << endl;
220  if (t_ev>=(int)collection.size()) cerr << "Collection size " << collection.size() << " >= " << t_ev << endl;
221  else{
222  cout << "Discarding event " << collection.at(t_ev).id << " at position " << t_ev << endl;
223  vector<SimpleEntry>::iterator it;
224  it=collection.begin()+t_ev; collection.erase(it);
225  }
226  }
227  }
228  void adjustWeights(float refth=-1){
229  if (collection.size()==0) return;
230 
231  vector<pair<float, int>> weight_entry;
232  for (unsigned int ev=0; ev<collection.size(); ev++) addByLowest<float, int>(weight_entry, collection.at(ev).weight, ev);
233  int bin=weight_entry.size()-1;
234 
235  int at99p0ev = (float(weight_entry.size()))*0.99;
236  if (at99p0ev==(int)weight_entry.size()) at99p0ev--;
237  float threshold = weight_entry.at(at99p0ev).first;
238  while (bin>at99p0ev){
239  if (
240  threshold*2.<weight_entry.at(bin).first
241  ){
242  if (weight_entry.at(bin).first==0.) cerr << "Weight=0!" << endl;
243  collection.at(weight_entry.at(bin).second).weight = pow(threshold, 2)/weight_entry.at(bin).first;
244  cout << "Adjusting weight for event " << bin << endl;
245  }
246  bin--;
247  }
248  float sum[2]={ 0 };
249  for (unsigned int ev=0; ev<collection.size(); ev++){
250  sum[0] += collection.at(ev).weight;
251  sum[1] += 1;
252  }
253  if (sum[0]==0. || sum[1]==0.) cerr << "sum[0]=" << sum[0] << " or sum[1]=" << sum[1] << " is invalid." << endl;
254  for (unsigned int ev=0; ev<collection.size(); ev++) collection.at(ev).weight *= sum[1]/sum[0];
255  if (refth>0.){
256  for (unsigned int ev=0; ev<collection.size(); ev++){
257  if (collection.at(ev).weight<=refth) continue;
258  collection.at(ev).weight = pow(refth, 2)/collection.at(ev).weight;
259  }
260  }
261  }
262  void mergeBin(const ExtBin& other){ for (unsigned int ev=0; ev<other.collection.size(); ev++) collection.push_back(other.collection.at(ev)); }
263 };
264 
265 float findPoleMass(TString samplename){
266  float mass = -1;
267  string strtmp = samplename.Data();
268  std::size_t extpos = strtmp.find(".root");
269  if (extpos!=string::npos) strtmp.erase(extpos, 5);
270  vector<string> strsplit;
271  splitOptionRecursive(strtmp, strsplit, 'H');
272  if (strsplit.size()>1){
273  string strmass = strsplit.at(1);
274  strsplit.clear();
275  splitOptionRecursive(strmass, strsplit, '_');
276  strmass = strsplit.at(0);
277  mass = std::stod(strmass);
278  }
279  return mass;
280 }
281 TTree* findTree(vector<TTree*> treeList, int evid){
282  int ev = evid;
283  for (unsigned int t=0; t<treeList.size(); t++){
284  TTree* tree = treeList.at(t);
285  int nevts = tree->GetEntries();
286  if (ev<nevts) return tree;
287  else ev -= nevts;
288  if (ev<0) cerr << "findTree::ERROR: Could not find the event " << evid << endl;
289  }
290  return 0;
291 }
292 void getEntry(vector<TTree*> treeList, int evid){
293  int ev = evid;
294  for (unsigned int t=0; t<treeList.size(); t++){
295  TTree* tree = treeList.at(t);
296  int nevts = tree->GetEntries();
297  if (ev<nevts){ tree->GetEntry(ev); break; }
298  else ev -= nevts;
299  if (ev<0) cerr << "findTree::ERROR: Could not find the event " << evid << endl;
300  }
301 }
302 
303 vector<TString> constructSamplesList(TString strsample, float sqrts){
304  vector<TString> samples;
305  if (strsample=="JJVBF"){
306  if (sqrts<10.){
307  samples.push_back("HZZ4lTree_VBFH116.root");
308  samples.push_back("HZZ4lTree_VBFH117.root");
309  samples.push_back("HZZ4lTree_VBFH118.root");
310  samples.push_back("HZZ4lTree_VBFH119.root");
311  samples.push_back("HZZ4lTree_VBFH120.root");
312  samples.push_back("HZZ4lTree_VBFH121.root");
313  samples.push_back("HZZ4lTree_VBFH122.root");
314  samples.push_back("HZZ4lTree_VBFH123.root");
315  samples.push_back("HZZ4lTree_VBFH124.root");
316  samples.push_back("HZZ4lTree_VBFH125.root");
317  samples.push_back("HZZ4lTree_VBFH126.root");
318  samples.push_back("HZZ4lTree_VBFH127.root");
319  samples.push_back("HZZ4lTree_VBFH128.root");
320  samples.push_back("HZZ4lTree_VBFH129.root");
321  samples.push_back("HZZ4lTree_VBFH130.root");
322  samples.push_back("HZZ4lTree_VBFH135.root");
323  samples.push_back("HZZ4lTree_VBFH140.root");
324  samples.push_back("HZZ4lTree_VBFH145.root");
325  samples.push_back("HZZ4lTree_VBFH150.root");
326  samples.push_back("HZZ4lTree_VBFH160.root");
327  samples.push_back("HZZ4lTree_VBFH170.root");
328  samples.push_back("HZZ4lTree_VBFH180.root");
329  samples.push_back("HZZ4lTree_VBFH190.root");
330  samples.push_back("HZZ4lTree_powheg15VBFH200.root");
331  samples.push_back("HZZ4lTree_powheg15VBFH225.root");
332  samples.push_back("HZZ4lTree_powheg15VBFH250.root");
333  samples.push_back("HZZ4lTree_powheg15VBFH275.root");
334  samples.push_back("HZZ4lTree_powheg15VBFH300.root");
335  samples.push_back("HZZ4lTree_powheg15VBFH350.root");
336  samples.push_back("HZZ4lTree_powheg15VBFH400.root");
337  samples.push_back("HZZ4lTree_powheg15VBFH450.root");
338  samples.push_back("HZZ4lTree_powheg15VBFH500.root");
339  samples.push_back("HZZ4lTree_powheg15VBFH550.root");
340  samples.push_back("HZZ4lTree_powheg15VBFH600.root");
341  samples.push_back("HZZ4lTree_powheg15VBFH650.root");
342  samples.push_back("HZZ4lTree_powheg15VBFH700.root");
343  samples.push_back("HZZ4lTree_powheg15VBFH750.root");
344  samples.push_back("HZZ4lTree_powheg15VBFH800.root");
345  samples.push_back("HZZ4lTree_powheg15VBFH850.root");
346  samples.push_back("HZZ4lTree_powheg15VBFH900.root");
347  samples.push_back("HZZ4lTree_powheg15VBFH950.root");
348  samples.push_back("HZZ4lTree_powheg15VBFH1000.root");
349  }
350  else{
351  samples.push_back("VBFH115");
352  samples.push_back("VBFH120");
353  samples.push_back("VBFH124");
354  samples.push_back("VBFH125");
355  samples.push_back("VBFH126");
356  samples.push_back("VBFH130");
357  samples.push_back("VBFH135");
358  samples.push_back("VBFH140");
359  samples.push_back("VBFH150");
360  samples.push_back("VBFH155");
361  samples.push_back("VBFH160");
362  samples.push_back("VBFH165");
363  samples.push_back("VBFH170");
364  samples.push_back("VBFH175");
365  samples.push_back("VBFH180");
366  samples.push_back("VBFH190");
367  samples.push_back("VBFH210");
368  samples.push_back("VBFH230");
369  samples.push_back("VBFH250");
370  samples.push_back("VBFH270");
371  samples.push_back("VBFH300");
372  samples.push_back("VBFH350");
373  samples.push_back("VBFH450");
374  samples.push_back("VBFH500");
375  samples.push_back("VBFH550");
376  samples.push_back("VBFH600");
377  samples.push_back("VBFH700");
378  samples.push_back("VBFH750");
379  samples.push_back("VBFH800");
380  samples.push_back("VBFH900");
381  samples.push_back("VBFH1000");
382  samples.push_back("VBFH2000");
383  samples.push_back("VBFH2500");
384  samples.push_back("VBFH3000");
385  }
386  }
387  else if (strsample=="WH"){
388  if (sqrts<10.){
389  samples.push_back("HZZ4lTree_WH110.root");
390  samples.push_back("HZZ4lTree_WH115.root");
391  samples.push_back("HZZ4lTree_WH120.root");
392  samples.push_back("HZZ4lTree_WH125.root");
393  samples.push_back("HZZ4lTree_WH126.root");
394  samples.push_back("HZZ4lTree_WH130.root");
395  samples.push_back("HZZ4lTree_WH140.root");
396  samples.push_back("HZZ4lTree_WH150.root");
397  samples.push_back("HZZ4lTree_WH160.root");
398  samples.push_back("HZZ4lTree_WH180.root");
399  samples.push_back("HZZ4lTree_WH200.root");
400  }
401  else{
402  samples.push_back("WminusH115");
403  samples.push_back("WminusH120");
404  samples.push_back("WminusH124");
405  samples.push_back("WminusH125");
406  samples.push_back("WminusH126");
407  samples.push_back("WminusH130");
408  samples.push_back("WminusH135");
409  samples.push_back("WminusH140");
410  samples.push_back("WminusH145");
411  samples.push_back("WminusH150");
412  samples.push_back("WminusH155");
413  samples.push_back("WminusH160");
414  samples.push_back("WminusH165");
415  samples.push_back("WminusH170");
416  samples.push_back("WminusH175");
417  samples.push_back("WminusH180");
418  samples.push_back("WminusH190");
419  samples.push_back("WminusH200");
420  samples.push_back("WminusH210");
421  samples.push_back("WminusH230");
422  samples.push_back("WplusH115");
423  samples.push_back("WplusH120");
424  samples.push_back("WplusH124");
425  samples.push_back("WplusH125");
426  samples.push_back("WplusH126");
427  samples.push_back("WplusH130");
428  samples.push_back("WplusH135");
429  samples.push_back("WplusH140");
430  samples.push_back("WplusH145");
431  samples.push_back("WplusH150");
432  samples.push_back("WplusH155");
433  samples.push_back("WplusH160");
434  samples.push_back("WplusH165");
435  samples.push_back("WplusH170");
436  samples.push_back("WplusH175");
437  samples.push_back("WplusH180");
438  samples.push_back("WplusH190");
439  samples.push_back("WplusH200");
440  samples.push_back("WplusH210");
441  samples.push_back("WplusH230");
442  }
443  }
444  else if (strsample=="ZH"){
445  if (sqrts<10.){
446  samples.push_back("HZZ4lTree_ZH110.root");
447  samples.push_back("HZZ4lTree_ZH115.root");
448  samples.push_back("HZZ4lTree_ZH120.root");
449  samples.push_back("HZZ4lTree_ZH125.root");
450  samples.push_back("HZZ4lTree_ZH126.root");
451  samples.push_back("HZZ4lTree_ZH130.root");
452  samples.push_back("HZZ4lTree_ZH140.root");
453  samples.push_back("HZZ4lTree_ZH150.root");
454  samples.push_back("HZZ4lTree_ZH160.root");
455  samples.push_back("HZZ4lTree_ZH180.root");
456  samples.push_back("HZZ4lTree_ZH200.root");
457  }
458  else{
459  samples.push_back("ZH115");
460  samples.push_back("ZH120");
461  samples.push_back("ZH124");
462  samples.push_back("ZH125");
463  samples.push_back("ZH126");
464  samples.push_back("ZH130");
465  samples.push_back("ZH135");
466  samples.push_back("ZH140");
467  samples.push_back("ZH145");
468  samples.push_back("ZH150");
469  samples.push_back("ZH155");
470  samples.push_back("ZH160");
471  samples.push_back("ZH165");
472  samples.push_back("ZH170");
473  samples.push_back("ZH175");
474  samples.push_back("ZH180");
475  samples.push_back("ZH190");
476  samples.push_back("ZH200");
477  //samples.push_back("ZH210");
478  //samples.push_back("ZH230");
479  }
480  }
481  else if (strsample=="JJQCD"){
482  if (sqrts<10.){
483  samples.push_back("HZZ4lTree_minloH90.root");
484  samples.push_back("HZZ4lTree_minloH95.root");
485  samples.push_back("HZZ4lTree_minloH100.root");
486  samples.push_back("HZZ4lTree_minloH105.root");
487  samples.push_back("HZZ4lTree_minloH110.root");
488  samples.push_back("HZZ4lTree_minloH115.root");
489  samples.push_back("HZZ4lTree_minloH120.root");
490  samples.push_back("HZZ4lTree_minloH124.root");
491  samples.push_back("HZZ4lTree_minloH125.root");
492  samples.push_back("HZZ4lTree_minloH126.root");
493  samples.push_back("HZZ4lTree_minloH130.root");
494  samples.push_back("HZZ4lTree_minloH135.root");
495  samples.push_back("HZZ4lTree_minloH140.root");
496  samples.push_back("HZZ4lTree_minloH145.root");
497  samples.push_back("HZZ4lTree_minloH150.root");
498  samples.push_back("HZZ4lTree_minloH155.root");
499  samples.push_back("HZZ4lTree_minloH160.root");
500  samples.push_back("HZZ4lTree_minloH170.root");
501  samples.push_back("HZZ4lTree_minloH180.root");
502  samples.push_back("HZZ4lTree_minloH190.root");
503  samples.push_back("HZZ4lTree_minloH200.root");
504  samples.push_back("HZZ4lTree_minloH250.root");
505  samples.push_back("HZZ4lTree_minloH300.root");
506  samples.push_back("HZZ4lTree_minloH350.root");
507  samples.push_back("HZZ4lTree_minloH400.root");
508  samples.push_back("HZZ4lTree_minloH450.root");
509  samples.push_back("HZZ4lTree_minloH500.root");
510  samples.push_back("HZZ4lTree_minloH550.root");
511  samples.push_back("HZZ4lTree_minloH600.root");
512  samples.push_back("HZZ4lTree_minloH650.root");
513  samples.push_back("HZZ4lTree_minloH700.root");
514  samples.push_back("HZZ4lTree_minloH750.root");
515  samples.push_back("HZZ4lTree_minloH800.root");
516  samples.push_back("HZZ4lTree_minloH850.root");
517  samples.push_back("HZZ4lTree_minloH900.root");
518  samples.push_back("HZZ4lTree_minloH950.root");
519  samples.push_back("HZZ4lTree_minloH1000.root");
520  }
521  else{
522  samples.push_back("ggH115");
523  samples.push_back("ggH120");
524  samples.push_back("ggH124");
525  samples.push_back("ggH125");
526  samples.push_back("ggH126");
527  samples.push_back("ggH130");
528  samples.push_back("ggH135");
529  samples.push_back("ggH145");
530  samples.push_back("ggH150");
531  samples.push_back("ggH155");
532  samples.push_back("ggH160");
533  samples.push_back("ggH165");
534  samples.push_back("ggH170");
535  samples.push_back("ggH175");
536  samples.push_back("ggH180");
537  samples.push_back("ggH190");
538  samples.push_back("ggH200");
539  samples.push_back("ggH210");
540  samples.push_back("ggH230");
541  samples.push_back("ggH250");
542  samples.push_back("ggH270");
543  samples.push_back("ggH300");
544  samples.push_back("ggH350");
545  samples.push_back("ggH400");
546  samples.push_back("ggH450");
547  samples.push_back("ggH500");
548  samples.push_back("ggH550");
549  samples.push_back("ggH600");
550  samples.push_back("ggH700");
551  samples.push_back("ggH750");
552  samples.push_back("ggH800");
553  samples.push_back("ggH900");
554  samples.push_back("ggH1000");
555  samples.push_back("ggH1500");
556  samples.push_back("ggH2000");
557  samples.push_back("ggH2500");
558  samples.push_back("ggH3000");
559  }
560  }
561  else if (strsample=="gg_Sig_JHUGen"){
562  if (sqrts<10.){
563  samples.push_back("HZZ4lTree_jhuGenV4-H91.2.root");
564  samples.push_back("HZZ4lTree_powheg15jhuGenV3-0PMH125.6.root");
565  }
566  else{
567  }
568  }
569  else if (strsample=="gg_Sig_MCFM"){
570  if (sqrts<10.){
571  samples.push_back("HZZ4lTree_ggTo4mu_SMH-MCFM67_H125.6.root");
572  samples.push_back("HZZ4lTree_ggTo4e_SMH-MCFM67_H125.6.root");
573  samples.push_back("HZZ4lTree_ggTo2e2mu_SMH-MCFM67_H125.6.root");
574  }
575  else{
576  samples.push_back("ggTo4mu_0PMH125_MCFM701");
577  samples.push_back("ggTo4e_0PMH125_MCFM701");
578  samples.push_back("ggTo2e2mu_0PMH125_MCFM701");
579  samples.push_back("ggTo2e2tau_0PMH125_MCFM701");
580  samples.push_back("ggTo2mu2tau_0PMH125_MCFM701");
581  samples.push_back("ggTo4tau_0PMH125_MCFM701");
582  }
583  }
584  else if (strsample=="gg_Bkg_MCFM"){
585  if (sqrts<10.){
586  samples.push_back("HZZ4lTree_ggTo2e2mu_Contin-MCFM67.root");
587  samples.push_back("HZZ4lTree_ggTo4mu_Contin-MCFM67.root");
588  samples.push_back("HZZ4lTree_ggTo4e_Contin-MCFM67.root");
589  }
590  else{
591  samples.push_back("ggTo4mu_Contin_MCFM701");
592  samples.push_back("ggTo4e_Contin_MCFM701");
593  samples.push_back("ggTo2e2mu_Contin_MCFM701");
594  samples.push_back("ggTo2e2tau_Contin_MCFM701");
595  samples.push_back("ggTo2mu2tau_Contin_MCFM701");
596  samples.push_back("ggTo4tau_Contin_MCFM701");
597  }
598  }
599  else if (strsample=="gg_Sig_ggVV"){
600  if (sqrts<10.){
601  samples.push_back("HZZ4lTree_ggTo2l2l_H125.6.root");
602  samples.push_back("HZZ4lTree_ggTo4l_H125.6.root");
603  }
604  else{
605  }
606  }
607  else if (strsample=="gg_Bkg_ggVV"){
608  if (sqrts<10.){
609  samples.push_back("HZZ4lTree_ggTo4l_Continuum.root");
610  samples.push_back("HZZ4lTree_ggZZ4l.root");
611  samples.push_back("HZZ4lTree_ggTo2l2l_Continuum.root");
612  samples.push_back("HZZ4lTree_ggZZ2l2l.root");
613  }
614  else{
615  }
616  }
617  else if (strsample=="VV_Sig_MCFM"){
618  if (sqrts<10.){
619  }
620  else{
621  samples.push_back("VBFTo2e2muJJ_0PMH125_phantom128");
622  samples.push_back("VBFTo4muJJ_0PMH125_phantom128");
623  samples.push_back("VBFTo4eJJ_0PMH125_phantom128");
624  }
625  }
626  else if (strsample=="VV_Bkg_MCFM"){
627  if (sqrts<10.){
628  }
629  else{
630  samples.push_back("VBFTo2e2muJJ_Contin_phantom128");
631  samples.push_back("VBFTo4muJJ_Contin_phantom128");
632  samples.push_back("VBFTo4eJJ_Contin_phantom128");
633  }
634  }
635  else if (strsample=="qq_Bkg"){
636  if (sqrts<10.){
637  samples.push_back("HZZ4lTree_ZZTo2e2mu.root");
638  samples.push_back("HZZ4lTree_ZZTo2e2tau.root");
639  samples.push_back("HZZ4lTree_ZZTo2mu2tau.root");
640  samples.push_back("HZZ4lTree_ZZTo4mu.root");
641  samples.push_back("HZZ4lTree_ZZTo4e.root");
642  samples.push_back("HZZ4lTree_ZZTo4tau.root");
643  samples.push_back("HZZ4lTree_ZZ95-160To2e2mu.root");
644  samples.push_back("HZZ4lTree_ZZ95-160To2e2tau.root");
645  samples.push_back("HZZ4lTree_ZZ95-160To2mu2tau.root");
646  samples.push_back("HZZ4lTree_ZZ95-160To4mu.root");
647  samples.push_back("HZZ4lTree_ZZ95-160To4e.root");
648  samples.push_back("HZZ4lTree_ZZ95-160To4tau.root");
649  }
650  else{
651  samples.push_back("ZZTo4l");
652  samples.push_back("ZZTo4l_ext");
653  }
654  }
655  return samples;
656 }
657 
658 TGraphErrors* makeGraphFromTH1(TH1* hx, TH1* hy, TString name){
659  if (hx->GetNbinsX()!=hy->GetNbinsX()){
660  cerr << "Number of bins for x coordinate != those for y" << endl;
661  assert(0);
662  }
663  unsigned int nbins = hx->GetNbinsX();
664  double* xexyey[4];
665  for (unsigned int ix=0; ix<4; ix++) xexyey[ix] = new double[nbins];
666  for (unsigned int bin=0; bin<nbins; bin++){
667  xexyey[0][bin] = hx->GetBinContent(bin+1);
668  xexyey[1][bin] = hx->GetBinError(bin+1);
669 
670  cout << "Bin " << bin << " x-center: " << xexyey[0][bin] << " +- " << xexyey[1][bin] << endl;
671  xexyey[2][bin] = hy->GetBinContent(bin+1);
672  xexyey[3][bin] = hy->GetBinError(bin+1);
673  }
674  TGraphErrors* tg = new TGraphErrors(nbins, xexyey[0], xexyey[2], xexyey[1], xexyey[3]);
675  tg->SetName(name);
676  for (unsigned int ix=0; ix<4; ix++) delete[] xexyey[ix];
677  return tg;
678 }
679 
680 template<typename T> TGraph* makeGraphFromPair(vector<pair<T,T>> points, TString name){
681  if (points.size()==0) return 0;
682  unsigned int nbins = points.size();
683  double* xy[2];
684  for (unsigned int ix=0; ix<2; ix++) xy[ix] = new double[nbins];
685  for (unsigned int bin=0; bin<nbins; bin++){
686  xy[0][bin] = points[bin].first;
687  xy[1][bin] = points[bin].second;
688  }
689  TGraph* tg = new TGraph(nbins, xy[0], xy[1]);
690  tg->SetName(name);
691  for (unsigned int ix=0; ix<2; ix++) delete[] xy[ix];
692  return tg;
693 }
694 
695 // Return A, B, C for A + B*x + C*x**2
696 vector<double> solveQuadratic(vector<pair<double, double>> xy){
697  vector<double> res;
698  if (xy.size()==3){
699  double& x1 = xy[0].first;
700  double& x2 = xy[1].first;
701  double& x3 = xy[2].first;
702  double det = pow(x1, 2)*(x3-x2) + pow(x2, 2)*(x1-x3) + pow(x3, 2)*(x2-x1);
703  double Ainv[3][3]={
704  { x2*x3*(x3-x2), x1*x3*(x1-x3), x1*x2*(x2-x1) },
705  { (x2-x3)*(x2+x3), (x3-x1)*(x3+x1), (x1-x2)*(x1+x2) },
706  { -(x2-x3), -(x3-x1), -(x1-x2) }
707  };
708  for (unsigned int i=0; i<3; i++){
709  double sum=0;
710  for (unsigned int j=0; j<3; j++) sum += Ainv[i][j]/det*xy[j].second;
711  res.push_back(sum);
712  }
713  }
714  return res;
715 }
716 // Return A, B, C for A*exp(-(x-B)**2/(2*C))
717 vector<double> solveGaussian(vector<pair<double, double>> xy){
718  vector<double> res;
719  if (xy.size()==3){
720  vector<pair<double, double>> xlny;
721  for(auto ipair : xy) xlny.push_back(pair<double, double>(ipair.first, log(ipair.second)));
722  vector<double> qc = solveQuadratic(xlny);
723 
724  double A = exp(qc[0]-pow(qc[1], 2)/qc[2]);
725  double B = -qc[1]*0.5/qc[2];
726  double C = -0.5/qc[2];
727  res.push_back(A);
728  res.push_back(B);
729  res.push_back(C);
730  }
731  return res;
732 }
733 
734 void addPoint(TGraph*& tg, double x, double y){
735  TString strname = tg->GetName();
736  TString strtitle = tg->GetTitle();
737  TString strxtitle = tg->GetXaxis()->GetTitle();
738  TString strytitle = tg->GetYaxis()->GetTitle();
739 
740  bool hasErrors = false;
741 
742  vector<double> xarray;
743  vector<double> yarray;
744  xarray.push_back(x);
745  yarray.push_back(y);
746  for (int ip=0; ip<tg->GetN(); ip++){
747  if (tg->GetX()[ip]!=x){
748  xarray.push_back(tg->GetX()[ip]);
749  yarray.push_back(tg->GetY()[ip]);
750  }
751  }
752  vector<pair<double, int>> xorder;
753  for (unsigned int ip=0; ip<xarray.size(); ip++) addByLowest<double, int>(xorder, xarray.at(ip), ip);
754 
755  double* xynew[2];
756  for (unsigned int i=0; i<2; i++) xynew[i] = new double[xorder.size()];
757  for (unsigned int ip=0; ip<xarray.size(); ip++){
758  unsigned int pos = xorder[ip].second;
759  xynew[0][ip] = xarray[pos];
760  xynew[1][ip] = yarray[pos];
761  }
762 
763  delete tg;
764 
765  tg = new TGraph(xorder.size(), xynew[0], xynew[1]);
766  tg->SetName(strname);
767  tg->SetTitle(strtitle);
768  tg->GetXaxis()->SetTitle(strxtitle);
769  tg->GetYaxis()->SetTitle(strytitle);
770  for (unsigned int i=0; i<2; i++) delete[] xynew[i];
771 }
772 void addPoint(TGraphErrors*& tg, double x, double y, double ex, double ey){
773  TString strname = tg->GetName();
774  TString strtitle = tg->GetTitle();
775  TString strxtitle = tg->GetXaxis()->GetTitle();
776  TString strytitle = tg->GetYaxis()->GetTitle();
777 
778  vector<double> xarray;
779  vector<double> yarray;
780  vector<double> exarray;
781  vector<double> eyarray;
782  xarray.push_back(x);
783  yarray.push_back(y);
784  exarray.push_back(ex);
785  eyarray.push_back(ey);
786  for (int ip=0; ip<tg->GetN(); ip++){
787  if (tg->GetX()[ip]!=x){
788  xarray.push_back(tg->GetX()[ip]);
789  yarray.push_back(tg->GetY()[ip]);
790  exarray.push_back(tg->GetEX()[ip]);
791  eyarray.push_back(tg->GetEY()[ip]);
792  }
793  }
794  vector<pair<double, int>> xorder;
795  for (unsigned int ip=0; ip<xarray.size(); ip++) addByLowest<double, int>(xorder, xarray.at(ip), ip);
796 
797  double* xynew[4];
798  for (unsigned int i=0; i<4; i++) xynew[i] = new double[xorder.size()];
799  for (unsigned int ip=0; ip<xarray.size(); ip++){
800  unsigned int pos = xorder[ip].second;
801  xynew[0][ip] = xarray[pos];
802  xynew[1][ip] = yarray[pos];
803  xynew[2][ip] = exarray[pos];
804  xynew[3][ip] = eyarray[pos];
805  }
806 
807  delete tg;
808 
809  tg = new TGraphErrors(xorder.size(), xynew[0], xynew[1], xynew[2], xynew[3]);
810  tg->SetName(strname);
811  tg->SetTitle(strtitle);
812  tg->GetXaxis()->SetTitle(strxtitle);
813  tg->GetYaxis()->SetTitle(strytitle);
814  for (unsigned int i=0; i<4; i++) delete[] xynew[i];
815 }
816 
817 
818 /* SPECIFIC COMMENT: NONE */
819 void getResolution_mH_signal(float sqrts, TString strprod){
820  TString TREE_NAME;
821  const bool writeFinalTree=false;
822  const TString strTrueBranch = "GenHMass";
823  const TString strRecoBranch = "ZZMass";
824 
825  short Z1Flav, Z2Flav;
826  float varTrue, varReco;
827 
828  vector<SimpleEntry> index[3];
829  TString strchannel[3]={ "4mu", "4e", "2mu2e" };
830 
831  vector<TString> dumappend;
832  vector<TString> strSamples;
833  if (strprod=="gg"){
834  dumappend = constructSamplesList("JJQCD", sqrts);
835  appendVector<TString>(strSamples, dumappend);
836  appendVector<TString>(strSamples, dumappend);
837  dumappend = constructSamplesList("gg_Sig_JHUGen", sqrts);
838  }
839  else if (strprod=="VBF"){
840  dumappend = constructSamplesList("JJVBF", sqrts);
841  appendVector<TString>(strSamples, dumappend);
842  }
843  else if (strprod=="ZH"){
844  dumappend = constructSamplesList("ZH", sqrts);
845  appendVector<TString>(strSamples, dumappend);
846  }
847  else if (strprod=="WH"){
848  dumappend = constructSamplesList("WH", sqrts);
849  appendVector<TString>(strSamples, dumappend);
850  }
851  else{
852  cerr << "Production " << strprod << " is unknown." << endl;
853  assert(0);
854  }
855 
856  TFile* foutput = TFile::Open(Form("resolution_m4l_truem4l_%s.root", strprod.Data()), "recreate");
857 
858  vector<TFile*> finputList;
859  vector<TTree*> treeList;
860  int nEntries=0;
861  TString cinput_main;
862 
863  if (sqrts<13){
864  TREE_NAME = "SelectedTree";
865  if (sqrts==8.)cinput_main = inputdir_8TeV;
866  else cinput_main = inputdir_7TeV;
867 
868  for (int is=0; is<(int)strSamples.size(); is++){
869  for (unsigned int ic=0; ic<3; ic++){
870  TString cinput = Form("%s/%s/%s", cinput_main.Data(), strchannel[ic].Data(), (strSamples[is]).Data());
871  TFile* finput = TFile::Open(cinput, "read");
872  cout << "Opening file " << cinput << "..." << endl;
873  TTree* tree=0;
874  if (finput!=0){
875  if (finput->IsOpen() && !finput->IsZombie()){
876  cout << cinput << " opened. Extracting tree " << TREE_NAME << "..." << endl;
877  tree = (TTree*)finput->Get(TREE_NAME);
878  if (tree!=0){
879  cout << TREE_NAME << " is found." << endl;
880  tree->SetBranchStatus("*", 0);
881  tree->SetBranchStatus(strTrueBranch, 1); tree->SetBranchAddress(strTrueBranch, &varTrue);
882  tree->SetBranchStatus(strRecoBranch, 1); tree->SetBranchAddress(strRecoBranch, &varReco);
883  tree->SetBranchStatus("Z1ids", 1); tree->SetBranchAddress("Z1ids", &Z1Flav);
884  tree->SetBranchStatus("Z2ids", 1); tree->SetBranchAddress("Z2ids", &Z2Flav);
885  nEntries += tree->GetEntries();
886  treeList.push_back(tree);
887  finputList.push_back(finput);
888  }
889  else finput->Close();
890  }
891  else if (finput->IsOpen()) finput->Close();
892  }
893  }
894  }
895 
896  }
897  else /*if (sqrts==13.)*/{
898  TREE_NAME = "ZZTree/candTree";
899  cinput_main = inputdir_13TeV;
900  //for (int is=0; is<2; is++){
901  for (int is=0; is<(int)strSamples.size(); is++){
902  TString cinput = Form("%s/%s/ZZ4lAnalysis.root", cinput_main.Data(), (strSamples[is]).Data());
903  TFile* finput = TFile::Open(cinput, "read");
904  cout << "Opening file " << cinput << "..." << endl;
905  TTree* tree=0;
906  if (finput!=0){
907  if (finput->IsOpen() && !finput->IsZombie()){
908  cout << cinput << " opened. Extracting tree " << TREE_NAME << "..." << endl;
909  tree = (TTree*)finput->Get(TREE_NAME);
910  if (tree!=0){
911  cout << TREE_NAME << " is found." << endl;
912  tree->SetBranchStatus("*", 0);
913  tree->SetBranchStatus(strTrueBranch, 1); tree->SetBranchAddress(strTrueBranch, &varTrue);
914  tree->SetBranchStatus(strRecoBranch, 1); tree->SetBranchAddress(strRecoBranch, &varReco);
915  tree->SetBranchStatus("Z1Flav", 1); tree->SetBranchAddress("Z1Flav", &Z1Flav);
916  tree->SetBranchStatus("Z2Flav", 1); tree->SetBranchAddress("Z2Flav", &Z2Flav);
917  nEntries += tree->GetEntries();
918  treeList.push_back(tree);
919  finputList.push_back(finput);
920  }
921  else finput->Close();
922  }
923  else if (finput->IsOpen()) finput->Close();
924  }
925  }
926  }
927 
928  cout << "NEntries = " << nEntries << " over " << treeList.size() << " trees." << endl;
929 
930  unsigned ev_acc=0;
931  for (int ev=0; ev<nEntries; ev++){
932  getEntry(treeList, ev);
933  bool doProcess=
934  (
935  Z1Flav*Z2Flav==pow(13, 4)
936  ||
937  Z1Flav*Z2Flav==pow(11, 4)
938  ||
939  Z1Flav*Z2Flav==pow(11*13, 2)
940  )
941  ;
942  if (!doProcess) continue;
943  if (ev_acc%10000==0) cout << "Pre-processing event " << ev << endl;
944  unsigned int ic = (Z1Flav*Z2Flav==pow(13, 4))*0 + (Z1Flav*Z2Flav==pow(11, 4))*1 + (Z1Flav*Z2Flav==pow(11*13, 2))*2;
945  SimpleEntry theEntry(ev, varTrue, varReco, 0, 1);
946  addByLowest(index[ic], theEntry, false);
947  ev_acc++;
948  }
949  cout << "Number of valid entries: " << ev_acc << endl;
950 
951  for (unsigned int ic=0; ic<3; ic++){
952  float firstVal=index[ic].at(0).trueval;
953  float lastVal=index[ic].at(index[ic].size()-1).trueval;
954  float infimum = (float)((int)firstVal); infimum -= (float)(((int)infimum)%10);
955  float supremum = (float)((int)(lastVal+0.5)); supremum += (float)(10-((int)supremum)%10);
956  cout << "Nentries = " << nEntries << " | truth = " << firstVal << " - " << lastVal << "(" << infimum << ", " << supremum << ")" << endl;
957 
958  float divisor=95000;
959  int nbins = index[ic].size()/divisor;
960  const int nbins_th=10/*50*/;
961  while (nbins<nbins_th){
962  if (divisor>1000) divisor -= 1000;
963  else if (divisor>100) divisor -= 100;
964  else break;
965  nbins=index[ic].size()/divisor;
966  }
967  cout << "nbins=" << nbins << endl;
968  if (nbins<3) cerr << "Not enough bins!" << endl;
969  vector<ExtBin> binList;
970  float* binning = new float[nbins+1];
971  binning[0]=infimum;
972  binning[nbins]=supremum;
973  int ev_stepsize = index[ic].size()/nbins;
974  cout << "Event step size: " << ev_stepsize << endl;
975  cout << "Boundary (" << 0 << ") = " << binning[0] << endl;
976  for (int ix=1; ix<nbins; ix++){
977  binning[ix]=(index[ic][ix*ev_stepsize-1].trueval+index[ic][ix*ev_stepsize].trueval)*0.5;
978  ExtBin tmpbin;
979  tmpbin.binlow = binning[ix-1]; tmpbin.binhigh = binning[ix];
980  for (int bin=0; bin<ev_stepsize; bin++){ tmpbin.addEvent(index[ic][(ix-1)*ev_stepsize+bin]); }
981  binList.push_back(tmpbin);
982  cout << "Boundary (" << ix << ")= " << binning[ix] << " [event " << index[ic][ix*ev_stepsize].id << ", step " << ix*ev_stepsize << "]" << endl;
983  }
984  ExtBin tmpbin;
985  tmpbin.binlow = binning[nbins-1]; tmpbin.binhigh = binning[nbins];
986  for (unsigned int bin=(nbins-1)*ev_stepsize; bin<index[ic].size(); bin++){ tmpbin.addEvent(index[ic][bin]); }
987  binList.push_back(tmpbin);
988  cout << "Boundary (" << nbins << ") = " << binning[nbins] << endl;
989  cout << "Bin list has the following bins:" << endl;
990  for (unsigned int ib=0; ib<binList.size(); ib++){
991  cout << ib << " / " << binList.size() << ": [" << binList.at(ib).binlow << "," << binList.at(ib).binhigh << "]" << endl;
992  }
993 
994  foutput->cd();
995 
996  TProfile* hvar = new TProfile(Form("varTrue_%s", strchannel[ic].Data()), "", nbins, binning); hvar->Sumw2();
997  TProfile* havg_varReco = new TProfile(Form("avg_varReco_%s", strchannel[ic].Data()), "", nbins, binning); havg_varReco->Sumw2();
998  TH2F* hvarTrue_varReco = new TH2F(Form("varTrue_varReco_%s", strchannel[ic].Data()), "", nbins, binning, nbins, binning); hvarTrue_varReco->Sumw2();
999 
1000  TTree* newtree=0;
1001  if (writeFinalTree){
1002  newtree = new TTree(Form("FinalTree_%s", strchannel[ic].Data()), "");
1003  newtree->Branch("varTrue", &varTrue);
1004  newtree->Branch("varReco", &varReco);
1005  }
1006 
1007  unsigned int ctr=0;
1008  for (unsigned int bin=0; bin<binList.size(); bin++){
1009  cout << "Bin " << bin << " is now being scrutinized..." << endl;
1010 
1011  //binList.at(bin).sift();
1012  binList.at(bin).adjustWeights();
1013 
1014  vector<pair<float, int>> recominustruevals_entries;
1015  binList.at(bin).sortByRecoMinusTrueVals(recominustruevals_entries);
1016  vector<float> recominustruevalbounds;
1017  unsigned int nrecototal = recominustruevals_entries.size();
1018  unsigned int nrecobins = 10;
1019  unsigned int recoinc = nrecototal / nrecobins;
1020  float minval = std::floor(recominustruevals_entries.at(0).first);
1021  float maxval = std::ceil(recominustruevals_entries.at(nrecototal-1).first);
1022  recominustruevalbounds.push_back(minval);
1023  for (unsigned int i=1; i<nrecobins; i++){
1024  float a = recominustruevals_entries.at(i*recoinc).first;
1025  float b = recominustruevals_entries.at(i*recoinc-1).first;
1026  recominustruevalbounds.push_back((a+b)*0.5);
1027  }
1028  recominustruevalbounds.push_back(maxval);
1029  cout << "Bin " << bin << " has the following reco-true boundaries:";
1030  for (unsigned int j=0; j<recominustruevalbounds.size(); j++) cout << " " << recominustruevalbounds.at(j);
1031  cout << endl;
1032 
1033  foutput->cd();
1034  TH1F* h_RecoMinusTrueVals = new TH1F(Form("RecoMinusTrueVal_%s_Bin%i", strchannel[ic].Data(), bin), "", nrecobins, recominustruevalbounds.data()); h_RecoMinusTrueVals->Sumw2();
1035  TProfile* p_RecoMinusTrueVals = new TProfile(Form("avg_RecoMinusTrueVal_%s_Bin%i", strchannel[ic].Data(), bin), "", nrecobins, recominustruevalbounds.data()); p_RecoMinusTrueVals->Sumw2();
1036  for (unsigned int i=0; i<nrecototal; i++){
1037  float& val = recominustruevals_entries.at(i).first;
1038  int& ev = recominustruevals_entries.at(i).second;
1039  float& weight = binList.at(bin).collection.at(ev).weight;
1040  if (weight==0.) cerr << "Weight is 0!" << endl;
1041  else if (isnan(weight) || isinf(weight)) cerr << "Weight " << weight << " is nan or inf" << endl;
1042  if (isnan(val) || isinf(val)) cerr << "Value " << val << " is nan or inf" << endl;
1043  h_RecoMinusTrueVals->Fill(val, weight);
1044  p_RecoMinusTrueVals->Fill(val, val, weight);
1045  }
1046  const TAxis* axis = h_RecoMinusTrueVals->GetXaxis();
1047  for (int bin=1; bin<=h_RecoMinusTrueVals->GetNbinsX(); bin++){
1048  float width = axis->GetBinWidth(bin);
1049  h_RecoMinusTrueVals->SetBinContent(bin, h_RecoMinusTrueVals->GetBinContent(bin)/width);
1050  h_RecoMinusTrueVals->SetBinError(bin, h_RecoMinusTrueVals->GetBinError(bin)/width);
1051  }
1052  foutput->WriteTObject(h_RecoMinusTrueVals);
1053  foutput->WriteTObject(p_RecoMinusTrueVals);
1054  delete p_RecoMinusTrueVals;
1055  delete h_RecoMinusTrueVals;
1056 
1057  for (unsigned int ev=0; ev<binList.at(bin).collection.size(); ev++){
1058  varTrue = binList.at(bin).collection.at(ev).trueval;
1059  varReco = binList.at(bin).collection.at(ev).recoval;
1060  havg_varReco->Fill(varTrue, varReco);
1061  hvar->Fill(varTrue, varTrue);
1062  hvarTrue_varReco->Fill(varTrue, varReco);
1063  if (writeFinalTree) newtree->Fill();
1064  }
1065  }
1066 
1067  TGraphErrors* tg = makeGraphFromTH1(hvar, havg_varReco, Form("tg_%s", havg_varReco->GetName()));
1068  foutput->WriteTObject(tg);
1069  delete tg;
1070 
1071  for (int ix=0; ix<=hvarTrue_varReco->GetNbinsX()+1; ix++){
1072  double integral = hvarTrue_varReco->Integral(ix, ix, 0, hvarTrue_varReco->GetNbinsY()+1);
1073  if (integral!=0.){
1074  for (int iy=0; iy<=hvarTrue_varReco->GetNbinsY()+1; iy++){
1075  double bincontent = hvarTrue_varReco->GetBinContent(ix, iy);
1076  double binerror = hvarTrue_varReco->GetBinError(ix, iy);
1077  bincontent /= integral;
1078  binerror /= integral; // I know this is wrong.
1079  hvarTrue_varReco->SetBinContent(ix, iy, bincontent);
1080  hvarTrue_varReco->SetBinError(ix, iy, binerror);
1081  }
1082  }
1083  }
1084  foutput->WriteTObject(hvarTrue_varReco);
1085  foutput->WriteTObject(havg_varReco);
1086  foutput->WriteTObject(hvar);
1087  if (writeFinalTree){
1088  foutput->WriteTObject(newtree);
1089  delete newtree;
1090  }
1091  delete hvarTrue_varReco;
1092  delete havg_varReco;
1093  delete hvar;
1094  delete[] binning;
1095  }
1096  for (unsigned int f=0; f<finputList.size(); f++) finputList.at(f)->Close();
1097  foutput->Close();
1098 }
1099 
1100 /*
1101 SPECIFIC COMMENT:
1102 - Final product is reco. BW(mJJ), so if division/multiplication is needed, divide by 2*mJJ.
1103 - BW is already convoluted. For future use, added also the transfer functions to output.
1104 */
1105 void getResolution_mJJ(float sqrts, TString strprod, bool debug=false){
1106  if (sqrts<13) assert(0);
1107 
1108  Mela mela(sqrts, 125);
1109 
1110  TString TREE_NAME = "ZZTree/candTree";
1111  TString COUNTERS_NAME = "ZZTree/Counters";
1112  const bool writeFinalTree = false && debug;
1113 
1114  short Z1Flav, Z2Flav, njets;
1115  float varTrue, varReco, ZZMass, weight;
1116  typedef float T;
1117 
1118  std::vector<T>* LepPt=0;
1119  std::vector<T>* LepEta=0;
1120  std::vector<T>* LepPhi=0;
1121  std::vector<short>* LepLepId=0;
1122  std::vector<T>* JetPt=0;
1123  std::vector<T>* JetEta=0;
1124  std::vector<T>* JetPhi=0;
1125  std::vector<T>* JetMass=0;
1126 
1127  std::vector<T>* LHEMotherPz=0;
1128  std::vector<T>* LHEMotherE=0;
1129  std::vector<short>* LHEMotherId=0;
1130  std::vector<T>* LHEDaughterPt=0;
1131  std::vector<T>* LHEDaughterEta=0;
1132  std::vector<T>* LHEDaughterPhi=0;
1133  std::vector<T>* LHEDaughterMass=0;
1134  std::vector<short>* LHEDaughterId=0;
1135  std::vector<T>* LHEAssociatedParticlePt=0;
1136  std::vector<T>* LHEAssociatedParticleEta=0;
1137  std::vector<T>* LHEAssociatedParticlePhi=0;
1138  std::vector<T>* LHEAssociatedParticleMass=0;
1139  std::vector<short>* LHEAssociatedParticleId=0;
1140 
1141  float xsec=1, overallEventWeight=1;
1142 
1143  vector<SimpleEntry> index;
1144  TString strchannel[3]={ "4mu", "4e", "2mu2e" };
1145 
1146  vector<TString> dumappend;
1147  vector<TString> strSamples;
1148  if (strprod=="gg"){
1149  dumappend = constructSamplesList("JJQCD", sqrts);
1150  appendVector<TString>(strSamples, dumappend);
1151  dumappend = constructSamplesList("gg_Sig_JHUGen", sqrts);
1152  }
1153  else if (strprod=="VBF"){
1154  dumappend = constructSamplesList("JJVBF", sqrts);
1155  appendVector<TString>(strSamples, dumappend);
1156  }
1157  else if (strprod=="ZH"){
1158  dumappend = constructSamplesList("ZH", sqrts);
1159  appendVector<TString>(strSamples, dumappend);
1160  }
1161  else if (strprod=="WH"){
1162  dumappend = constructSamplesList("WH", sqrts);
1163  appendVector<TString>(strSamples, dumappend);
1164  }
1165  else if (strprod=="JJEW"){
1166  dumappend = constructSamplesList("JJVBF", sqrts);
1167  appendVector<TString>(strSamples, dumappend);
1168  dumappend = constructSamplesList("ZH", sqrts);
1169  appendVector<TString>(strSamples, dumappend);
1170  dumappend = constructSamplesList("WH", sqrts);
1171  appendVector<TString>(strSamples, dumappend);
1172  }
1173  else{
1174  cerr << "Production " << strprod << " is unknown." << endl;
1175  assert(0);
1176  }
1177 
1178  TFile* foutput = TFile::Open(Form("resolution_mJJ_recoVStrue_%s_%.0fTeV.root", strprod.Data(), sqrts), "recreate"); // Y vs X
1179 
1180  vector<TFile*> finputList;
1181  vector<TTree*> treeList;
1182  int nEntries=0;
1183  TString cinput_main;
1184 
1185  unordered_map<TTree*, pair<float, float>> nGenMap;
1186  unordered_map<TTree*, float> mass_map;
1187  unordered_map<float, vector<TTree*>> mass_sample_map;
1188 
1189  if (sqrts<13){
1190  TREE_NAME = "SelectedTree";
1191  if (sqrts==8.)cinput_main = inputdir_8TeV;
1192  else cinput_main = inputdir_7TeV;
1193 
1194  for (int is=0; is<(int)strSamples.size(); is++){
1195  for (unsigned int ic=0; ic<3; ic++){
1196  TString cinput = Form("%s/%s/%s", cinput_main.Data(), strchannel[ic].Data(), (strSamples[is]).Data());
1197  TFile* finput = TFile::Open(cinput, "read");
1198  cout << "Opening file " << cinput << "..." << endl;
1199  TTree* tree=0;
1200  if (finput!=0){
1201  if (finput->IsOpen() && !finput->IsZombie()){
1202  cout << cinput << " opened. Extracting tree " << TREE_NAME << "..." << endl;
1203  tree = (TTree*)finput->Get(TREE_NAME);
1204  if (tree!=0){
1205  cout << TREE_NAME << " is found." << endl;
1206  tree->SetBranchStatus("*", 0);
1207  tree->SetBranchStatus("MC_weight", 1); tree->SetBranchAddress("MC_weight", &overallEventWeight);
1208  tree->SetBranchStatus("ZZMass", 1); tree->SetBranchAddress("ZZMass", &ZZMass);
1209  tree->SetBranchStatus("NJets30", 1); tree->SetBranchAddress("nCleanedJetsPt30", &njets);
1210  tree->SetBranchStatus("JetPt", 1); tree->SetBranchAddress("JetPt", &JetPt);
1211  tree->SetBranchStatus("JetEta", 1); tree->SetBranchAddress("JetEta", &JetEta);
1212  tree->SetBranchStatus("JetPhi", 1); tree->SetBranchAddress("JetPhi", &JetPhi);
1213  tree->SetBranchStatus("JetMass", 1); tree->SetBranchAddress("JetMass", &JetMass);
1214 
1215  TH1F* htmp = (TH1F*)finput->Get(COUNTERS_NAME);
1216  pair<float, float> nsum(1, 1); // MC_weight already divides by number of generated events
1217  nGenMap[tree]=nsum;
1218 
1219  nEntries += tree->GetEntries();
1220  treeList.push_back(tree);
1221  finputList.push_back(finput);
1222 
1223  float polemass = findPoleMass(strSamples[is]);
1224  cout << "Pole mass = " << polemass << endl;
1225  mass_map[tree]=polemass;
1226  if (mass_sample_map.find(polemass)==mass_sample_map.end()){
1227  cout << "Inserting new pole mass sample array" << endl;
1228  vector<TTree*> dumarr;
1229  mass_sample_map[polemass] = dumarr;
1230  }
1231  mass_sample_map[polemass].push_back(tree);
1232  }
1233  else finput->Close();
1234  }
1235  else if (finput->IsOpen()) finput->Close();
1236  }
1237  }
1238  }
1239 
1240  }
1241  else /*if (sqrts==13.)*/{
1242  TREE_NAME = "ZZTree/candTree";
1243  cinput_main = inputdir_13TeV;
1244  //for (int is=0; is<2; is++){
1245  for (int is=0; is<(int)strSamples.size(); is++){
1246  TString cinput = Form("%s/%s/ZZ4lAnalysis.root", cinput_main.Data(), (strSamples[is]).Data());
1247  cout << "Opening file " << cinput << "..." << endl;
1248  TFile* finput = TFile::Open(cinput, "read");
1249  cout << "File open attempt passed." << endl;
1250  TTree* tree=0;
1251  if (finput!=0){
1252  if (finput->IsOpen() && !finput->IsZombie()){
1253  cout << cinput << " opened. Extracting tree " << TREE_NAME << "..." << endl;
1254  tree = (TTree*)finput->Get(TREE_NAME);
1255  if (tree!=0){
1256  cout << TREE_NAME << " is found." << endl;
1257  tree->SetBranchStatus("*", 0);
1258  tree->SetBranchStatus("xsec", 1); tree->SetBranchAddress("xsec", &xsec);
1259  tree->SetBranchStatus("overallEventWeight", 1); tree->SetBranchAddress("overallEventWeight", &overallEventWeight);
1260  tree->SetBranchStatus("ZZMass", 1); tree->SetBranchAddress("ZZMass", &ZZMass);
1261 
1262  tree->SetBranchStatus("LepPt", 1); tree->SetBranchAddress("LepPt", &LepPt);
1263  tree->SetBranchStatus("LepEta", 1); tree->SetBranchAddress("LepEta", &LepEta);
1264  tree->SetBranchStatus("LepPhi", 1); tree->SetBranchAddress("LepPhi", &LepPhi);
1265  tree->SetBranchStatus("LepLepId", 1); tree->SetBranchAddress("LepLepId", &LepLepId);
1266 
1267  tree->SetBranchStatus("nCleanedJetsPt30", 1); tree->SetBranchAddress("nCleanedJetsPt30", &njets);
1268  tree->SetBranchStatus("JetPt", 1); tree->SetBranchAddress("JetPt", &JetPt);
1269  tree->SetBranchStatus("JetEta", 1); tree->SetBranchAddress("JetEta", &JetEta);
1270  tree->SetBranchStatus("JetPhi", 1); tree->SetBranchAddress("JetPhi", &JetPhi);
1271  tree->SetBranchStatus("JetMass", 1); tree->SetBranchAddress("JetMass", &JetMass);
1272 
1273  tree->SetBranchStatus("LHEMotherPz", 1); tree->SetBranchAddress("LHEMotherPz", &LHEMotherPz);
1274  tree->SetBranchStatus("LHEMotherE", 1); tree->SetBranchAddress("LHEMotherE", &LHEMotherE);
1275  tree->SetBranchStatus("LHEMotherId", 1); tree->SetBranchAddress("LHEMotherId", &LHEMotherId);
1276 
1277  tree->SetBranchStatus("LHEDaughterPt", 1); tree->SetBranchAddress("LHEDaughterPt", &LHEDaughterPt);
1278  tree->SetBranchStatus("LHEDaughterEta", 1); tree->SetBranchAddress("LHEDaughterEta", &LHEDaughterEta);
1279  tree->SetBranchStatus("LHEDaughterPhi", 1); tree->SetBranchAddress("LHEDaughterPhi", &LHEDaughterPhi);
1280  tree->SetBranchStatus("LHEDaughterMass", 1); tree->SetBranchAddress("LHEDaughterMass", &LHEDaughterMass);
1281  tree->SetBranchStatus("LHEDaughterId", 1); tree->SetBranchAddress("LHEDaughterId", &LHEDaughterId);
1282 
1283  tree->SetBranchStatus("LHEAssociatedParticlePt", 1); tree->SetBranchAddress("LHEAssociatedParticlePt", &LHEAssociatedParticlePt);
1284  tree->SetBranchStatus("LHEAssociatedParticleEta", 1); tree->SetBranchAddress("LHEAssociatedParticleEta", &LHEAssociatedParticleEta);
1285  tree->SetBranchStatus("LHEAssociatedParticlePhi", 1); tree->SetBranchAddress("LHEAssociatedParticlePhi", &LHEAssociatedParticlePhi);
1286  tree->SetBranchStatus("LHEAssociatedParticleMass", 1); tree->SetBranchAddress("LHEAssociatedParticleMass", &LHEAssociatedParticleMass);
1287  tree->SetBranchStatus("LHEAssociatedParticleId", 1); tree->SetBranchAddress("LHEAssociatedParticleId", &LHEAssociatedParticleId);
1288 
1289  tree->GetEntry(0);
1290  cout << "Cross section = " << xsec << endl;
1291 
1292  TH1F* htmp = (TH1F*)finput->Get(COUNTERS_NAME);
1293  pair<float, float> nsum(htmp->GetBinContent(1), htmp->GetBinContent(40)); // Add PU reweighting
1294  nGenMap[tree]=nsum;
1295 
1296  nEntries += tree->GetEntries();
1297  treeList.push_back(tree);
1298  finputList.push_back(finput);
1299 
1300  float polemass = findPoleMass(strSamples[is]);
1301  cout << "Pole mass = " << polemass << endl;
1302  mass_map[tree]=polemass;
1303  if (mass_sample_map.find(polemass)==mass_sample_map.end()){
1304  cout << "Inserting new pole mass sample array" << endl;
1305  vector<TTree*> dumarr;
1306  mass_sample_map[polemass] = dumarr;
1307  }
1308  mass_sample_map[polemass].push_back(tree);
1309  }
1310  else finput->Close();
1311  }
1312  else if (finput->IsOpen()) finput->Close();
1313  }
1314  }
1315  }
1316 
1317  for (auto it = mass_sample_map.begin(); it != mass_sample_map.end(); ++it){
1318  float sum_ngen=0;
1319  float sum_xsec=0;
1320  for (unsigned int ix=0; ix<it->second.size(); ix++){
1321  it->second.at(ix)->GetEntry(0);
1322  sum_ngen += nGenMap[it->second.at(ix)].first;
1323  sum_xsec += xsec;
1324  }
1325  float overallWeight = sum_ngen/sum_xsec;
1326  for (unsigned int ix=0; ix<it->second.size(); ix++){
1327  cout << "Sum Hep MC weights in tree " << ix << " / " << it->second.size() << " was " << nGenMap[it->second.at(ix)].second << " over " << nGenMap[it->second.at(ix)].first << " total gen. events." << endl;
1328  nGenMap[it->second.at(ix)].first = overallWeight/nGenMap[it->second.at(ix)].second;
1329  cout << "Event scale for tree " << ix << " / " << it->second.size() << " at pole mass " << it->first << " = " << nGenMap[it->second.at(ix)].first << endl;
1330  }
1331  }
1332 
1333  cout << "NEntries = " << nEntries << " over " << treeList.size() << " trees." << endl;
1334 
1335  foutput->cd();
1336  TTree* newtree=0;
1337  if (writeFinalTree){
1338  newtree = new TTree("FinalTree", "");
1339  newtree->Branch("varTrue", &varTrue);
1340  newtree->Branch("varReco", &varReco);
1341  newtree->Branch("ZZMass", &ZZMass);
1342  newtree->Branch("weight", &weight);
1343  }
1344 
1345  unsigned ev_acc=0;
1346  for (int ev=0; ev<nEntries; ev++){
1347  getEntry(treeList, ev);
1348  bool doProcess=
1349  njets>=2 && LHEAssociatedParticlePt->size()>=2 && LepPt->size()==4
1350  ;
1351  if (!doProcess) continue;
1352  TTree* tree = findTree(treeList, ev);
1353  weight = nGenMap[tree].first*xsec*overallEventWeight;
1354 
1355  vector<MELAParticle*> partList;
1356 
1357  // Reconstruct true associated jet information
1358  vector<MELAParticle*> ttot, tg, tq, tothers;
1359  for (unsigned int i=0; i<LHEAssociatedParticlePt->size(); i++){
1360  int id = LHEAssociatedParticleId->at(i);
1361  TLorentzVector tmp(0, 0, 0, 0);
1362  tmp.SetPtEtaPhiM(
1363  LHEAssociatedParticlePt->at(i),
1364  LHEAssociatedParticleEta->at(i),
1365  LHEAssociatedParticlePhi->at(i),
1366  LHEAssociatedParticleMass->at(i)
1367  );
1368 
1369  MELAParticle* part = new MELAParticle(id, tmp);
1370  if (PDGHelpers::isAQuark(id)) tq.push_back(part);
1371  else if (PDGHelpers::isAGluon(id)) tg.push_back(part);
1372  else tothers.push_back(part);
1373  partList.push_back(part);
1374  }
1375 
1376  // Reconstruct reco daughter information
1377  vector<MELAParticle*> daus;
1378  TLorentzVector pSumDaus(0, 0, 0, 0);
1379  int Z1Z2id=1;
1380  for (unsigned int i=0; i<LepPt->size(); i++){
1381  int id = LepLepId->at(i);
1382  float mass=0;
1383  if (std::abs(id)==11) mass = PDGHelpers::m_el;
1384  else if (std::abs(id)==13) mass = PDGHelpers::m_mu;
1385  else if (std::abs(id)==15) mass = PDGHelpers::m_tau;
1386  TLorentzVector tmp(0, 0, 0, 0);
1387  tmp.SetPtEtaPhiM(
1388  LepPt->at(i),
1389  LepEta->at(i),
1390  LepPhi->at(i),
1391  mass
1392  );
1393  MELAParticle* part = new MELAParticle(id, tmp);
1394  daus.push_back(part);
1395  pSumDaus = pSumDaus + tmp;
1396  Z1Z2id *= id;
1397  partList.push_back(part);
1398  }
1399 
1400  // Reconstruct true daughter information, swap true daughters with associated true quarks and leptons if needed
1401  vector<MELACandidate*> candList;
1402  MELACandidate* theCand=0; float minDM=9e9;
1403 
1404  vector<MELAParticle*> tdaus;
1405  TLorentzVector pSumTrueDaus(0, 0, 0, 0);
1406  int tZ1Z2id=1;
1407  vector<MELAParticle*> tdaus_split[2][2];
1408  for (unsigned int i=0; i<LHEDaughterPt->size(); i++){
1409  int id = LHEDaughterId->at(i);
1410  TLorentzVector tmp(0, 0, 0, 0);
1411  tmp.SetPtEtaPhiM(
1412  LHEDaughterPt->at(i),
1413  LHEDaughterEta->at(i),
1414  LHEDaughterPhi->at(i),
1415  LHEDaughterMass->at(i)
1416  );
1417  MELAParticle* part = new MELAParticle(id, tmp);
1418  tdaus.push_back(part);
1419  int ipart=-1;
1420  int jdau=-1;
1421  if (part->id>0) ipart=0;
1422  else ipart=1;
1423  if (std::abs(id)==11) jdau=0;
1424  else if (std::abs(id)==13) jdau=1;
1425  if (ipart>=0 && jdau>=0) tdaus_split[jdau][ipart].push_back(part);
1426  if (PDGHelpers::isAQuark(std::abs(id))) tq.push_back(part);
1427  partList.push_back(part);
1428  }
1429 
1430  for (auto it=tothers.begin(); it<tothers.end(); it++){
1431  MELAParticle* part = *it;
1432  int ipart=-1;
1433  int jdau=-1;
1434  if (part->id>0) ipart=0;
1435  else ipart=1;
1436  if (std::abs(part->id)==11) jdau=0;
1437  else if (std::abs(part->id)==13) jdau=1;
1438  if (ipart>=0 && jdau>=0) tdaus_split[jdau][ipart].push_back(part);
1439  }
1440 
1441  //cout << "Begin tmpV construction" << endl;
1442  std::vector<MELAParticle*> tmpVhandle;
1443  for (int c=0; c<2; c++){
1444  for (unsigned int i=0; i<tdaus_split[c][0].size(); i++){
1445  for (unsigned int j=0; j<tdaus_split[c][1].size(); j++){
1446  TLorentzVector pV = tdaus_split[c][0].at(i)->p4+tdaus_split[c][1].at(j)->p4;
1447  MELAParticle* V = new MELAParticle(23, pV);
1448  V->addDaughter(tdaus_split[c][0].at(i));
1449  V->addDaughter(tdaus_split[c][1].at(j));
1450  tmpVhandle.push_back(V);
1451  }
1452  }
1453  }
1454  //cout << "Begin candList construction" << endl;
1455  for (unsigned int i=0; i<tmpVhandle.size(); i++){
1456  for (unsigned int j=i+1; j<tmpVhandle.size(); j++){
1457  MELAParticle* Vi1 = tmpVhandle.at(i)->getDaughter(0);
1458  MELAParticle* Vi2 = tmpVhandle.at(i)->getDaughter(1);
1459  MELAParticle* Vj1 = tmpVhandle.at(j)->getDaughter(0);
1460  MELAParticle* Vj2 = tmpVhandle.at(j)->getDaughter(1);
1461  if (Vi1==Vj1 || (Vi2==Vj2 && Vi2 != 0)) continue;
1462 
1463  TLorentzVector pH(0, 0, 0, 0);
1464  if (Vi1!=0) pH = pH + Vi1->p4;
1465  if (Vi2!=0) pH = pH + Vi2->p4;
1466  if (Vj1!=0) pH = pH + Vj1->p4;
1467  if (Vj2!=0) pH = pH + Vj2->p4;
1468  MELACandidate* cand = new MELACandidate(25, pH, true);
1469 
1470  if (Vi1!=0) cand->addDaughter(Vi1);
1471  if (Vi2!=0) cand->addDaughter(Vi2);
1472  if (Vj1!=0) cand->addDaughter(Vj1);
1473  if (Vj2!=0) cand->addDaughter(Vj2);
1474 
1477  cand->sortDaughters();
1478  PDGHelpers::setCandidateDecayMode(defaultHDecayMode);
1479  candList.push_back(cand);
1480  }
1481  }
1482  //cout << "Delete tmpVs" << endl;
1483  for (unsigned int i=0; i<tmpVhandle.size(); i++) delete tmpVhandle.at(i);
1484  //cout << "Choose best cand out of " << candList.size() << " cands" << endl;
1485  for (unsigned int icand=0; icand<candList.size(); icand++){
1486  MELACandidate* cand = candList.at(icand);
1487  float DM = fabs(cand->m()-ZZMass);
1488  if (minDM>DM){
1489  minDM=DM;
1490  theCand=cand;
1491  }
1492  }
1493  /*
1494  if (theCand==0){
1495  cout << "Best cand dne. True daughters are " << endl;
1496  for (unsigned int i=0; i<tdaus.size(); i++) cout << " - " << tdaus.at(i)->id << " " << tdaus.at(i)->p4.X() << " " << tdaus.at(i)->p4.Y() << " " << tdaus.at(i)->p4.Z() << " " << tdaus.at(i)->p4.T() << endl;
1497  cout << "Others:" << endl;
1498  for (unsigned int i=0; i<tothers.size(); i++) cout << " - " << tothers.at(i)->id << " " << tothers.at(i)->p4.X() << " " << tothers.at(i)->p4.Y() << " " << tothers.at(i)->p4.Z() << " " << tothers.at(i)->p4.T() << endl;
1499  }
1500  */
1501  if (theCand!=0){ for (int idau=0; idau<theCand->getNDaughters(); idau++) tZ1Z2id *= theCand->getDaughter(idau)->id; }
1502  if (tq.size()+tg.size()<2 || Z1Z2id!=tZ1Z2id || theCand==0){
1503  for (unsigned int icand=0; icand<candList.size(); icand++) delete candList.at(icand);
1504  for (unsigned int i=0; i<partList.size(); i++) delete partList.at(i);
1505  continue;
1506  }
1507  for (int idau=0; idau<theCand->getNDaughters(); idau++) pSumTrueDaus += theCand->getDaughter(idau)->p4;
1508 
1509  TVector3 boostTrueDaus = pSumTrueDaus.BoostVector();
1510  TVector3 boostDaus = pSumDaus.BoostVector();
1511 
1512  // True mothers
1513  vector<MELAParticle*> tmothers;
1514  for (unsigned int i=0; i<LHEMotherPz->size(); i++){
1515  int id = LHEMotherId->at(i);
1516  TLorentzVector tmp(0, 0, LHEMotherPz->at(i), LHEMotherE->at(i));
1517  MELAParticle* part = new MELAParticle(id, tmp);
1518  tmothers.push_back(part);
1519  partList.push_back(part);
1520  }
1521 
1522  vector<MELAParticle*> jets;
1523  for (unsigned int i=0; i<(unsigned int)min(2, (int)JetPt->size()); i++){
1524  int id = 0;
1525  TLorentzVector tmp(0, 0, 0, 0);
1526  tmp.SetPtEtaPhiM(
1527  JetPt->at(i),
1528  JetEta->at(i),
1529  JetPhi->at(i),
1530  JetMass->at(i)
1531  );
1532  MELAParticle* part = new MELAParticle(id, tmp);
1533  jets.push_back(part);
1534  partList.push_back(part);
1535  }
1536 
1537  for (unsigned int i=0; i<daus.size(); i++){ daus.at(i)->p4.Boost(-boostDaus); daus.at(i)->p4.Boost(boostTrueDaus); }
1538  for (unsigned int i=0; i<jets.size(); i++){ jets.at(i)->p4.Boost(-boostDaus); jets.at(i)->p4.Boost(boostTrueDaus); }
1539  varReco = (jets.at(0)->p4 + jets.at(1)->p4).M();
1540 
1541  if (ev_acc%10000==0) cout << "Pre-processing event " << ev << endl;
1542 
1543  for (unsigned int i=0; i<tg.size(); i++){
1544  int jfound=-1; float dRmin=9e10;
1545  MELAParticle* gluon = tg.at(i);
1546 
1547  for (unsigned int j=0; j<tq.size(); j++){
1548  MELAParticle* quark = tq.at(j);
1549  float dR = 1./fabs(quark->dot(gluon));
1550  if (dRmin>dR){
1551  dRmin=dR;
1552  jfound=j;
1553  }
1554  }
1555  for (unsigned int j=0; j<tmothers.size(); j++){
1556  MELAParticle* quark = tmothers.at(j);
1557  if (!PDGHelpers::isAQuark(quark->id)) continue;
1558  float dR = 1./fabs(quark->dot(gluon));
1559  if (dRmin>dR){
1560  dRmin=dR;
1561  jfound=-1;
1562  }
1563  }
1564 
1565  if (jfound>=0){
1566  int& id = tq.at(jfound)->id;
1567  TLorentzVector mom = tq.at(jfound)->p4 + gluon->p4;
1568  MELAParticle* composite = new MELAParticle(id, mom);
1569  composite->addDaughter(tq.at(jfound));
1570  composite->addDaughter(gluon);
1571  ttot.push_back(composite);
1572  partList.push_back(composite);
1573  }
1574  }
1575 
1576  TLorentzVector sum(0, 0, 0, 0);
1577  vector<MELAParticle*> matchedpartons;
1578  for (unsigned int ijet=0; ijet<2; ijet++){
1579  MELAParticle* jet = jets.at(ijet);
1580  MELAParticle* matched=0; float dRmin=9e9;
1581 
1582  // First check Q+G
1583  for (unsigned int i=0; i<ttot.size(); i++){
1584  MELAParticle* part = ttot.at(i);
1585  bool unmatched=true;
1586  for (unsigned int im=0; im<matchedpartons.size(); im++){
1587  if (
1588  matchedpartons.at(im)==part
1589  ||
1590  matchedpartons.at(im)==part->getDaughter(0)
1591  ||
1592  matchedpartons.at(im)==part->getDaughter(1)
1593  ){
1594  unmatched=false; break;
1595  }
1596  }
1597  if (!unmatched) continue;
1598  float dR = part->deltaR(jet);
1599  if (dRmin>dR){
1600  dRmin=dR;
1601  matched = part;
1602  }
1603  }
1604  // Check individual Q
1605  for (unsigned int i=0; i<tq.size(); i++){
1606  MELAParticle* part = tq.at(i);
1607  bool unmatched=true;
1608  for (unsigned int im=0; im<matchedpartons.size(); im++){
1609  if (matchedpartons.at(im)==part) unmatched=false;
1610  for (int idau=0; idau<matchedpartons.at(im)->getNDaughters(); idau++){
1611  if (matchedpartons.at(im)->getDaughter(idau)==part){ unmatched=false; break; }
1612  }
1613  if (!unmatched) break;
1614  }
1615  if (!unmatched) continue;
1616  float dR = part->deltaR(jet);
1617  if (dRmin>dR){
1618  dRmin=dR;
1619  matched = part;
1620  }
1621  }
1622  // Check individual G
1623  for (unsigned int i=0; i<tg.size(); i++){
1624  MELAParticle* part = tg.at(i);
1625  bool unmatched=true;
1626  for (unsigned int im=0; im<matchedpartons.size(); im++){
1627  if (matchedpartons.at(im)==part) unmatched=false;
1628  for (int idau=0; idau<matchedpartons.at(im)->getNDaughters(); idau++){
1629  if (matchedpartons.at(im)->getDaughter(idau)==part){ unmatched=false; break; }
1630  }
1631  if (!unmatched) break;
1632  }
1633  if (!unmatched) continue;
1634  float dR = part->deltaR(jet);
1635  if (dRmin>dR){
1636  dRmin=dR;
1637  matched = part;
1638  }
1639  }
1640 
1641  if (matched!=0){
1642  sum = sum + matched->p4;
1643  matchedpartons.push_back(matched);
1644  }
1645  }
1646 
1647  varTrue = sum.M();
1648 
1649  if (varTrue<0. || ev_acc%100000==0/* || varReco/varTrue<0.4 || varReco/varTrue>1./0.4*/){
1650  cout << "True mJJ = " << varTrue << ", reco mJJ = " << varReco << ". Event info:" << endl;
1651  cout << "- Best cand mass = " << pSumTrueDaus.M() << " vs. reco mass = " << ZZMass << endl;
1652  cout << " - Reco jets:" << endl;
1653  for (unsigned int i=0; i<jets.size(); i++) cout << " - " << jets.at(i)->p4.X() << " " << jets.at(i)->p4.Y() << " " << jets.at(i)->p4.Z() << " " << jets.at(i)->p4.T() << endl;
1654  cout << " - " << " - Matched truth:" << endl;
1655  for (unsigned int i=0; i<matchedpartons.size(); i++) cout << " - " << matchedpartons.at(i)->id << " " << matchedpartons.at(i)->p4.X() << " " << matchedpartons.at(i)->p4.Y() << " " << matchedpartons.at(i)->p4.Z() << " " << matchedpartons.at(i)->p4.T() << endl;
1656  cout << " - " << " - True partons:" << endl;
1657  for (unsigned int i=0; i<tg.size(); i++) cout << " - " << tg.at(i)->id << " " << tg.at(i)->p4.X() << " " << tg.at(i)->p4.Y() << " " << tg.at(i)->p4.Z() << " " << tg.at(i)->p4.T() << endl;
1658  for (unsigned int i=0; i<tq.size(); i++) cout << " - " << tq.at(i)->id << " " << tq.at(i)->p4.X() << " " << tq.at(i)->p4.Y() << " " << tq.at(i)->p4.Z() << " " << tq.at(i)->p4.T() << endl;
1659  cout << " - " << " - Merged partons:" << endl;
1660  for (unsigned int i=0; i<ttot.size(); i++){
1661  cout << " - " << ttot.at(i)->id << " " << ttot.at(i)->p4.X() << " " << ttot.at(i)->p4.Y() << " " << ttot.at(i)->p4.Z() << " " << ttot.at(i)->p4.T() << endl;
1662  for (int j=0; j<ttot.at(i)->getNDaughters(); j++)cout << " ---Dau" << j+1 << ": " << ttot.at(i)->getDaughter(j)->id << " " << ttot.at(i)->getDaughter(j)->p4.X() << " " << ttot.at(i)->getDaughter(j)->p4.Y() << " " << ttot.at(i)->getDaughter(j)->p4.Z() << " " << ttot.at(i)->getDaughter(j)->p4.T() << endl;
1663  }
1664  cout << " - " << " - Other true asssociated:" << endl;
1665  for (unsigned int i=0; i<tothers.size(); i++) cout << " - " << tothers.at(i)->id << " " << tothers.at(i)->p4.X() << " " << tothers.at(i)->p4.Y() << " " << tothers.at(i)->p4.Z() << " " << tothers.at(i)->p4.T() << endl;
1666  cout << "True candidate summary:" << endl;
1668  }
1669 
1670  for (unsigned int icand=0; icand<candList.size(); icand++) delete candList.at(icand);
1671  for (unsigned int i=0; i<partList.size(); i++) delete partList.at(i);
1672 
1673  SimpleEntry theEntry(ev, varTrue, varReco, ZZMass, weight);
1674  addByLowest(index, theEntry, false);
1675 
1676  ev_acc++;
1677  }
1678  cout << "Number of valid entries: " << ev_acc << endl;
1679 
1680  float firstVal=index.at(0).trueval;
1681  float lastVal=index.at(index.size()-1).trueval;
1682  float infimum = std::floor(firstVal);
1683  float supremum = std::ceil(lastVal);
1684  cout << "Nentries = " << nEntries << " | truth = " << firstVal << " - " << lastVal << "(" << infimum << ", " << supremum << ")" << endl;
1685 
1686  float divisor=20000;
1687  int nbins = index.size()/divisor;
1688  const int nbins_th=10/*50*/;
1689  while (nbins<nbins_th){
1690  if (divisor>1000) divisor -= 1000;
1691  else if (divisor>100) divisor -= 100;
1692  else break;
1693  nbins=index.size()/divisor;
1694  }
1695  cout << "nbins=" << nbins << endl;
1696  if (nbins<3) cerr << "Not enough bins!" << endl;
1697  vector<ExtBin> binList;
1698  float* binning = new float[nbins+1];
1699  binning[0]=infimum;
1700  binning[nbins]=supremum;
1701  int ev_stepsize = index.size()/nbins;
1702  cout << "Event step size: " << ev_stepsize << endl;
1703  cout << "Boundary (" << 0 << ") = " << binning[0] << endl;
1704  for (int ix=1; ix<nbins; ix++){
1705  binning[ix]=(index[ix*ev_stepsize-1].trueval+index[ix*ev_stepsize].trueval)*0.5;
1706  ExtBin tmpbin;
1707  tmpbin.binlow = binning[ix-1]; tmpbin.binhigh = binning[ix];
1708  for (int bin=0; bin<ev_stepsize; bin++){ tmpbin.addEvent(index[(ix-1)*ev_stepsize+bin]); }
1709  binList.push_back(tmpbin);
1710  cout << "Boundary (" << ix << ")= " << binning[ix] << " [event " << index[ix*ev_stepsize].id << ", step " << ix*ev_stepsize << "]" << endl;
1711  }
1712  ExtBin tmpbin;
1713  tmpbin.binlow = binning[nbins-1]; tmpbin.binhigh = binning[nbins];
1714  for (unsigned int bin=(nbins-1)*ev_stepsize; bin<index.size(); bin++){ tmpbin.addEvent(index[bin]); }
1715  binList.push_back(tmpbin);
1716  cout << "Boundary (" << nbins << ") = " << binning[nbins] << endl;
1717  cout << "Bin list has the following bins:" << endl;
1718  for (unsigned int ib=0; ib<binList.size(); ib++){
1719  cout << ib << " / " << binList.size() << ": [" << binList.at(ib).binlow << "," << binList.at(ib).binhigh << "]" << endl;
1720  }
1721 
1722  foutput->cd();
1723 
1724  TProfile* hvar = new TProfile("varTrue", "", nbins, binning); hvar->Sumw2();
1725  TProfile* havg_varReco = new TProfile("avg_varReco", "", nbins, binning); havg_varReco->Sumw2();
1726  TH2F* hvarTrue_varReco = new TH2F("varTrue_varReco", "", nbins, binning, nbins, binning); hvarTrue_varReco->Sumw2();
1727 
1728  vector<TGraphErrors*> tglist;
1729 
1730  unsigned int ctr=0;
1731  for (unsigned int bin=0; bin<binList.size(); bin++){
1732  cout << "Bin " << bin << " is now being scrutinized..." << endl;
1733 
1734  binList.at(bin).sift(0.99, true);
1735  binList.at(bin).adjustWeights();
1736 
1737  for (unsigned int ev=0; ev<binList.at(bin).collection.size(); ev++){
1738  varTrue = binList.at(bin).collection.at(ev).trueval;
1739  varReco = binList.at(bin).collection.at(ev).recoval;
1740  ZZMass = binList.at(bin).collection.at(ev).recotrackval;
1741  weight = binList.at(bin).collection.at(ev).weight;
1742  havg_varReco->Fill(varTrue, varReco, weight);
1743  hvar->Fill(varTrue, varTrue, weight);
1744  hvarTrue_varReco->Fill(varTrue, varReco, weight);
1745  if (writeFinalTree) newtree->Fill();
1746  }
1747 
1748  float avgbin_varTrue = hvar->GetBinContent(bin+1);
1749 
1750  vector<pair<float, int>> recominustruevals_entries;
1751  binList.at(bin).sortByRecoMinusTrueVals(recominustruevals_entries);
1752  vector<float> recominustruevalbounds;
1753  unsigned int nrecototal = recominustruevals_entries.size();
1754  for (unsigned int ev=0; ev<nrecototal; ev++) recominustruevals_entries.at(ev).first = (recominustruevals_entries.at(ev).first+1.)*avgbin_varTrue;
1755 
1756  float recodivisor=1600;
1757  unsigned int nrecobins = nrecototal/recodivisor;
1758  const unsigned int nrecobins_th=12;
1759  while (nrecobins<nrecobins_th){
1760  if (recodivisor>100) recodivisor -= 100;
1761  else if (recodivisor>10) recodivisor -= 10;
1762  else break;
1763  nrecobins = nrecototal/recodivisor;
1764  }
1765  unsigned int recoinc = nrecototal / nrecobins;
1766  float minval = min(float(0), std::floor(recominustruevals_entries.at(0).first));
1767  float maxval = max(std::ceil(recominustruevals_entries.at(nrecototal-1).first), float(sqrts*1000.));
1768  recominustruevalbounds.push_back(minval);
1769  for (unsigned int i=1; i<nrecobins; i++){
1770  float a = recominustruevals_entries.at(i*recoinc).first;
1771  float b = recominustruevals_entries.at(i*recoinc-1).first;
1772  recominustruevalbounds.push_back((a+b)*0.5);
1773  }
1774  recominustruevalbounds.push_back(maxval);
1775  cout << "Bin " << bin << " has the following reco-true boundaries:";
1776  for (unsigned int j=0; j<recominustruevalbounds.size(); j++) cout << " " << recominustruevalbounds.at(j);
1777  cout << endl;
1778 
1779  foutput->cd();
1780 
1781  TH1F* h_RecoMinusTrueVals = new TH1F(Form("RecoMinusTrueVal_Bin%i", bin), "", nrecobins, recominustruevalbounds.data()); h_RecoMinusTrueVals->Sumw2();
1782  TProfile* p_RecoMinusTrueVals = new TProfile(Form("avg_RecoMinusTrueVal_Bin%i", bin), "", nrecobins, recominustruevalbounds.data()); p_RecoMinusTrueVals->Sumw2();
1783  for (unsigned int i=0; i<nrecototal; i++){
1784  float& val = recominustruevals_entries.at(i).first;
1785  int& ev = recominustruevals_entries.at(i).second;
1786  float& weight = binList.at(bin).collection.at(ev).weight;
1787  if (weight==0.) cerr << "Weight is 0!" << endl;
1788  else if (isnan(weight) || isinf(weight)) cerr << "Weight " << weight << " is nan or inf" << endl;
1789  if (isnan(val) || isinf(val)) cerr << "Value " << val << " is nan or inf" << endl;
1790  h_RecoMinusTrueVals->Fill(val, weight);
1791  p_RecoMinusTrueVals->Fill(val, val, weight);
1792  }
1793  const TAxis* axis = h_RecoMinusTrueVals->GetXaxis();
1794  for (int bin=1; bin<=h_RecoMinusTrueVals->GetNbinsX(); bin++){
1795  float width = axis->GetBinWidth(bin);
1796  h_RecoMinusTrueVals->SetBinContent(bin, h_RecoMinusTrueVals->GetBinContent(bin)/width);
1797  h_RecoMinusTrueVals->SetBinError(bin, h_RecoMinusTrueVals->GetBinError(bin)/width);
1798  }
1799  if (debug){
1800  foutput->WriteTObject(h_RecoMinusTrueVals);
1801  foutput->WriteTObject(p_RecoMinusTrueVals);
1802  }
1803 
1804  TGraphErrors* tgbin = makeGraphFromTH1(p_RecoMinusTrueVals, h_RecoMinusTrueVals, Form("tg_%s", h_RecoMinusTrueVals->GetName()));
1805  tgbin->SetTitle(Form("<m^{true}_{JJ}> = %.3f #pm %.3f GeV, <m^{reco}_{JJ}> = %.3f #pm %.3f GeV", hvar->GetBinContent(bin+1), hvar->GetBinError(bin+1), havg_varReco->GetBinContent(bin+1), havg_varReco->GetBinError(bin+1)));
1806  tgbin->GetYaxis()->SetTitle("Sum of weights");
1807  tgbin->GetXaxis()->SetTitle("m^{reco}_{JJ} / m^{true}_{JJ} - 1");
1808  cout << "Adding point (0,1)" << endl;
1809  addPoint(tgbin, 0, 1, 0, 0);
1810  for (int ip=0; ip<tgbin->GetN(); ip++) tgbin->GetY()[ip] = log(tgbin->GetY()[ip]);
1811 
1812  double dfirst, dlast;
1813  dfirst = (tgbin->GetY()[1]-tgbin->GetY()[0])/(tgbin->GetX()[1]-tgbin->GetX()[0]);
1814  dlast = (0-tgbin->GetY()[tgbin->GetN()-1])/(maxval-tgbin->GetX()[tgbin->GetN()-1]);
1815  TSpline3* sp_tgbin = new TSpline3("sp_tgbin", tgbin, "b1e1", dfirst, dlast);
1816  unsigned int ninsert;
1817  vector<double> xcoord;
1818  for (int ip=0; ip<tgbin->GetN(); ip++) xcoord.push_back(tgbin->GetX()[ip]);
1819  /*
1820  for (unsigned int ip=0; ip<xcoord.size()-1; ip++){
1821  const double xwidth = (xcoord[ip+1] - xcoord[ip])/((double)(ninsert+1));
1822  for (unsigned int j=1; j<=ninsert; j++){
1823  double xtmp = xwidth*j+xcoord[ip];
1824  double ytmp = sp_tgbin->Eval(xtmp);
1825  addPoint(tgbin, xtmp, ytmp, 0, 0);
1826  }
1827  }
1828  */
1829  unsigned int binzero=0;
1830  for (unsigned int ip=0; ip<xcoord.size()-1; ip++){
1831  if (xcoord[ip]<avgbin_varTrue && xcoord[ip+1]>=avgbin_varTrue){
1832  binzero = ip;
1833  break;
1834  }
1835  }
1836  for (unsigned int ip=0; ip<xcoord.size()-1; ip++){
1837  if (ip==binzero || ip==binzero+1 || ip==(xcoord.size()-2)) ninsert=9;
1838  else if (ip<binzero) ninsert=5;
1839  else ninsert=2;
1840  delete sp_tgbin;
1841  sp_tgbin = new TSpline3("sp_tgbin", tgbin, "b1e1", dfirst, dlast);
1842  const double xwidth = (xcoord[ip+1] - xcoord[ip])/((double)(ninsert+1));
1843  for (unsigned int j=1; j<=ninsert; j++){
1844  double xtmp = xwidth*j+xcoord[ip];
1845  double ytmp = sp_tgbin->Eval(xtmp);
1846  cout << "Inserting (x,y) = ( " << xtmp << " , " << ytmp << " )" << endl;
1847  addPoint(tgbin, xtmp, ytmp, 0, 0);
1848  }
1849  }
1850 
1851  for (int ip=0; ip<tgbin->GetN(); ip++) tgbin->GetY()[ip] = exp(tgbin->GetY()[ip]);
1852  delete sp_tgbin;
1853  //dfirst = (tgbin->GetY()[1]-tgbin->GetY()[0])/(tgbin->GetX()[1]-tgbin->GetX()[0]);
1854  dlast = (tgbin->GetY()[tgbin->GetN()-1]-tgbin->GetY()[tgbin->GetN()-2])/(tgbin->GetX()[tgbin->GetN()-1]-tgbin->GetX()[tgbin->GetN()-2]);
1855  float tgxmax = tgbin->GetX()[tgbin->GetN()-1];
1856  float tgyatxmax = tgbin->GetY()[tgbin->GetN()-1];
1857  float tgyatinf = tgyatxmax*0.001;
1858  float tgZeroPoint = (tgyatinf-tgyatxmax)/dlast + tgxmax;
1859  float tgLastPoint = min(tgZeroPoint, (float)(sqrts*1000.));
1860  ninsert=2;
1861  for (unsigned int j=1; j<=ninsert; j++){
1862  const double xwidth = (tgLastPoint-tgxmax)/((double)ninsert);
1863  double xtmp = tgxmax+xwidth*j;
1864  double ytmp = tgyatxmax + dlast*(xtmp-tgxmax);
1865  if (j==ninsert){
1866  xtmp += xwidth;
1867  xtmp = min(xtmp, (double)(sqrts*1000.));
1868  cout << "Inserting (x,y) = ( " << xtmp << " , " << ytmp << " )" << endl;
1869  addPoint(tgbin, xtmp, ytmp, 0, 0);
1870  for (unsigned int k=0; k<1; k++){
1871  if (xtmp+xwidth<=sqrts*1000.){
1872  xtmp += xwidth;
1873  cout << "Inserting (x,y) = ( " << xtmp << " , " << ytmp << " )" << endl;
1874  addPoint(tgbin, xtmp, ytmp, 0, 0);
1875  }
1876  }
1877  tgLastPoint=xtmp;
1878  }
1879  else{
1880  cout << "Inserting (x,y) = ( " << xtmp << " , " << ytmp << " )" << endl;
1881  addPoint(tgbin, xtmp, ytmp, 0, 0);
1882  }
1883  }
1884  ninsert=3;
1885  for (unsigned int j=1; j<=ninsert; j++){
1886  const double xwidth = (sqrts*1000.-tgLastPoint)/((double)ninsert);
1887  double xtmp = tgLastPoint+xwidth*j;
1888  double ytmp = tgyatinf;
1889  cout << "Inserting (x,y) = ( " << xtmp << " , " << ytmp << " )" << endl;
1890  addPoint(tgbin, xtmp, ytmp, 0, 0);
1891  }
1892  tgbin->SetMarkerStyle(20);
1893  tgbin->SetMarkerSize(1.2);
1894  tgbin->SetLineColor(kBlack);
1895  tgbin->SetLineWidth(2);
1896 
1897  RooRealVar* reco_minus_true_var = new RooRealVar("plotVar", "", minval, maxval);
1898  reco_minus_true_var->setBins((int)(maxval-minval));
1899  MELANCSplineFactory_1D* fac_sp = new MELANCSplineFactory_1D(*reco_minus_true_var, Form("Bin%i", bin));
1900  fac_sp->setPoints(tgbin);
1901  MELANCSplineCore* spPDF_bin = fac_sp->getFunc();
1902  double ymin=9e9, ymax=-9e9;
1903  //for (int ip=0; ip<tgbin->GetN(); ip++){
1904  // reco_minus_true_var->setVal(tgbin->GetX()[ip]);
1905  // cout << "Spline value at " << reco_minus_true_var->getVal() << " = " << spPDF_bin->getVal() << " =? " << tgbin->GetY()[ip] << endl;
1906  //}
1907  RooRealIntegral* pdf_int = new RooRealIntegral("pdf_int", "", *spPDF_bin, RooArgSet(*reco_minus_true_var));
1908  //double pdfintval = 1;
1909  double pdfintval = pdf_int->getVal();
1910  cout << "PDF integral: " << pdfintval << endl;
1911  cout << "Sum of weights: " << h_RecoMinusTrueVals->Integral("width") << endl;
1912  double riemannintval=0;
1913  for (int ip=0; ip<tgbin->GetN(); ip++){
1914  tgbin->GetY()[ip] /= pdfintval;
1915  tgbin->GetEY()[ip] /= pdfintval;
1916  ymin = min(ymin, tgbin->GetY()[ip]);
1917  ymax = max(ymax, tgbin->GetY()[ip]);
1918 
1919  if (ip!=tgbin->GetN()-1) riemannintval += (tgbin->GetY()[ip]+tgbin->GetY()[ip-1])*(tgbin->GetX()[ip]-tgbin->GetX()[ip-1])*0.5;
1920  }
1921  cout << "Post-normalization Riemann integral: " << riemannintval << endl;
1922  delete pdf_int;
1923  fac_sp->setPoints(tgbin);
1924  spPDF_bin = fac_sp->getFunc();
1925  //spPDF_bin->doFloor(false);
1926  //cout << "Analytical integral of spline: " << spPDF_bin->analyticalIntegral(2) << endl;
1927  pdf_int = new RooRealIntegral("pdf_int", "", *spPDF_bin, RooArgSet(*reco_minus_true_var));
1928  //cout << "Post-normalization PDF integral: " << pdf_int->getVal() << endl;
1929  spPDF_bin->forceNumInt(true);
1930  delete pdf_int;
1931  pdf_int = new RooRealIntegral("pdf_int", "", *spPDF_bin, RooArgSet(*reco_minus_true_var));
1932  //cout << "Post-normalization PDF numerical integral: " << pdf_int->getVal() << endl;
1933  delete pdf_int;
1934 
1935  RooPlot* plot_bin = reco_minus_true_var->frame();
1936  cout << "Frame created for [" << reco_minus_true_var->getMin() << " , " << reco_minus_true_var->getMax() << " , " << reco_minus_true_var->getBins() << "]" << endl;
1937  plot_bin->GetXaxis()->CenterTitle();
1938  plot_bin->GetYaxis()->SetTitleOffset(1.2);
1939  plot_bin->GetYaxis()->CenterTitle();
1940  plot_bin->GetXaxis()->SetTitle(tgbin->GetXaxis()->GetTitle());
1941  plot_bin->GetYaxis()->SetTitle(tgbin->GetYaxis()->GetTitle());
1942  plot_bin->SetTitle(tgbin->GetTitle()); tgbin->SetTitle("");
1943  //spPDF_bin->setVerbosity(MELANCSplineCore::kVerbose);
1944  spPDF_bin->plotOn(plot_bin, LineColor(kRed), LineWidth(2), LineStyle(1));
1945  plot_bin->GetYaxis()->SetRangeUser(ymin, ymax*1.2);
1946  plot_bin->GetXaxis()->SetNdivisions(-505);
1947 
1948  TCanvas* canvas = new TCanvas(Form("c_%s", h_RecoMinusTrueVals->GetName()), "", 800, 800);
1949  plot_bin->Draw();
1950  tgbin->Draw("e1psame");
1951  canvas->Modified();
1952  canvas->Update();
1953  if (debug) foutput->WriteTObject(canvas);
1954  canvas->Close();
1955 
1956  delete plot_bin;
1957 
1958  reco_minus_true_var->setRange(-1, reco_minus_true_var->getMax()/avgbin_varTrue-1.);
1959  for (int ip=0; ip<tgbin->GetN(); ip++){
1960  tgbin->GetY()[ip] *= avgbin_varTrue;
1961  tgbin->GetEY()[ip] *= avgbin_varTrue;
1962  tgbin->GetX()[ip] = tgbin->GetX()[ip]/avgbin_varTrue-1.;
1963  tgbin->GetEX()[ip] /= avgbin_varTrue;
1964  }
1965  tglist.push_back(tgbin);
1966 
1967  delete fac_sp;
1968  delete reco_minus_true_var;
1969  delete p_RecoMinusTrueVals;
1970  delete h_RecoMinusTrueVals;
1971  }
1972 
1973  RooArgList splineList;
1974  vector<MELALinearInterpFunc::T> truthList;
1975  vector<MELANCSplineFactory_1D*> facList;
1976 
1977  RooRealVar finalX("true", "", 0.1, sqrts*1000.);
1978  finalX.setBins((int)(finalX.getMax()-finalX.getMin())/50);
1979  RooRealVar finalY("reco", "", finalX.getMin(), finalX.getMax());
1980  finalY.setBins(finalX.getBins());
1981  RooFormulaVar finalYoverX("RecoOverTrueVar", "@1/max(0.1, @0)-1.", RooArgList(finalX, finalY));
1982 
1983  for (int is=-1; is<=int(tglist.size()); is++){
1984  TGraph* tg;
1986  if (is>=0 && is<int(tglist.size())){
1987  tval = hvar->GetBinContent(is+1);
1988  tg = (TGraphErrors*)tglist[is]->Clone(Form("tg_bin%i", is+1));
1989  }
1990  else if (is==-1){
1991  tval=finalX.getMin();
1992  tg = (TGraphErrors*)tglist[is+1]->Clone(Form("tg_bin%i", is+1));
1993  }
1994  else{
1995  tval = finalX.getMax();
1996  tg = (TGraphErrors*)tglist[is-1]->Clone(Form("tg_bin%i", is+1));
1997 
1998  TSpline3 sptmp("sptmp", tg, "b2e2", 0, 0);
1999  double* xy[2];
2000  int n = 1; // Point at exactly 0
2001  for (int ip=0; ip<tg->GetN(); ip++){ if (tg->GetX()[ip]<0.) n++; }
2002  for (unsigned int i=0; i<2; i++) xy[i]=new double[n];
2003  for (int ip=0; ip<n; ip++){
2004  if (ip==n-1){ xy[0][ip]=0; xy[1][ip]=sptmp.Eval(xy[0][ip]); }
2005  else{ xy[0][ip]=tg->GetX()[ip]; xy[1][ip]=tg->GetY()[ip]; }
2006  }
2007  delete tg;
2008  tg = new TGraph(n, xy[0], xy[1]);
2009  tg->SetName(Form("tg_bin%i", is+1));
2010 
2011  for (unsigned int i=0; i<2; i++) delete[] xy[i];
2012  }
2013  tg->SetName(Form("tg_bin%i", is+1));
2014  tg->SetTitle(Form("Truth at %.2f", tval));
2015  tg->GetXaxis()->SetTitle("Reco/Truth-1");
2016  tg->GetYaxis()->SetTitle("Probability");
2017 
2018  MELANCSplineFactory_1D* fac_tmp = new MELANCSplineFactory_1D(finalYoverX, Form("tmp1DFactory_bin%i", is+1));
2019  fac_tmp->setPoints(tg);
2020  MELANCSpline_1D_fast* functmp = fac_tmp->getFunc();
2021  functmp->setRangeValidity(tg->GetX()[0], tg->GetX()[tg->GetN()-1]);
2022 
2023  finalX.setVal(tval);
2024  RooRealIntegral sp_int = RooRealIntegral("pdftmp_int", "", *functmp, RooArgSet(finalY));
2025  double pdftmpintval = sp_int.getVal();
2026  cout << "Bin " << is+1 << " at truth = " << tval << " renormalized by 1/" << pdftmpintval << endl;
2027  for (int ip=0; ip<tg->GetN(); ip++){ tg->GetY()[ip] /= pdftmpintval; }
2028  fac_tmp->setPoints(tg);
2029  functmp = fac_tmp->getFunc();
2030  functmp->setRangeValidity(tg->GetX()[0], tg->GetX()[tg->GetN()-1]);
2031  MELAFuncPdf* pdftmp = fac_tmp->getPDF();
2032 
2033  splineList.add(*pdftmp);
2034  truthList.push_back(tval);
2035  facList.push_back(fac_tmp);
2036 
2037  foutput->WriteTObject(tg);
2038  delete tg;
2039  }
2040 
2041  MELALinearInterpFunc* theFunc = new MELALinearInterpFunc("linearFunc", "", finalX, truthList, splineList);
2042  theFunc->setRangeValidity(finalX.getMin(), finalX.getMax());
2043  MELAFuncPdf* thePdf = new MELAFuncPdf("linearPdf", "", *theFunc);
2044  TCanvas* canvas;
2045  {
2046  finalX.setRange(35, 535);
2047  finalY.setRange(35, 535);
2048  finalX.setBins(finalX.getMax()-finalX.getMin());
2049  finalY.setBins(finalY.getMax()-finalY.getMin());
2050  TH2F* h_frm = new TH2F("hFinalResolution", "", finalX.getBins(), finalX.getMin(), finalX.getMax(), finalY.getBins(), finalY.getMin(), finalY.getMax());
2051  for (int ix=1; ix<=h_frm->GetNbinsX(); ix++){
2052  double xval = h_frm->GetXaxis()->GetBinCenter(ix);
2053  finalX.setVal(xval);
2054  for (int iy=1; iy<=h_frm->GetNbinsY(); iy++){
2055  double yval = h_frm->GetYaxis()->GetBinCenter(iy);
2056  finalY.setVal(yval);
2057  h_frm->SetBinContent(ix, iy, thePdf->getVal());
2058  }
2059  }
2060  h_frm->SetStats(0);
2061  h_frm->GetXaxis()->SetTitle("True m_{JJ} (GeV)");
2062  h_frm->GetYaxis()->SetTitle("Reco. m_{JJ} (GeV)");
2063  h_frm->SetTitle(TString("m_{JJ} resolution for ")+strprod);
2064  canvas = new TCanvas(TString("cFinalResolution")+strprod, "", 800, 800);
2065  h_frm->Draw("colz");
2066  canvas->Modified();
2067  canvas->Update();
2068  canvas->SaveAs(Form("%s%s", canvas->GetName(), ".pdf"));
2069  canvas->Close();
2070  if (debug) foutput->WriteTObject(h_frm);
2071  delete h_frm;
2072  }
2073 
2074  if (strprod=="WH" || strprod=="ZH"){
2075  RooRealVar* mV = new RooRealVar("mV", "", 0, 1000.*sqrts);
2076  RooRealVar* GaV = new RooRealVar("GaV", "", 0, 1000.*sqrts);
2077  if (strprod=="ZH"){
2078  mV->setVal(mela.getPrimaryMass(23));
2079  GaV->setVal(mela.getPrimaryWidth(23));
2080  }
2081  else{
2082  mV->setVal(mela.getPrimaryMass(24));
2083  GaV->setVal(mela.getPrimaryWidth(24));
2084  }
2085  mV->setConstant(true);
2086  GaV->setConstant(true);
2087  cout << "Constructing a BW on top of the resolution. mV = " << mV->getVal() << ", GammaV = " << GaV->getVal() << endl;
2088 
2089  // First sample the true BW
2090  RooGenericPdf* trueBW = new RooGenericPdf("trueBW", "2.*@0/(pow(pow(@0,2)-pow(@1,2),2) + pow(@1*@2,2))", RooArgList(finalX, *mV, *GaV));
2091  vector<float> samplePointsList;
2092 
2093  vector<pair<double, double>> generateRanges;
2094  vector<pair<int, int>> generateReqStep;
2095  generateRanges.push_back(pair<double, double>(0.2, 64.9)); generateReqStep.push_back(pair<int, int>(100, 20));
2096  generateRanges.push_back(pair<double, double>(65., mV->getVal()-0.05)); generateReqStep.push_back(pair<int, int>(100, 10));
2097  generateRanges.push_back(pair<double, double>(mV->getVal()+0.05, 120.)); generateReqStep.push_back(pair<int, int>(100, 10));
2098  generateRanges.push_back(pair<double, double>(120.1, 200.)); generateReqStep.push_back(pair<int, int>(25, 40));
2099  generateRanges.push_back(pair<double, double>(200.1, 600.)); generateReqStep.push_back(pair<int, int>(25, 40));
2100  generateRanges.push_back(pair<double, double>(600.1, 1500.)); generateReqStep.push_back(pair<int, int>(25, 40));
2101  generateRanges.push_back(pair<double, double>(1500.1, 4000.)); generateReqStep.push_back(pair<int, int>(25, 40));
2102  generateRanges.push_back(pair<double, double>(4000.1, 1000.*sqrts-0.1)); generateReqStep.push_back(pair<int, int>(50, 20));
2103  for (unsigned int ig=0; ig<generateRanges.size(); ig++){
2104  int& nrequested = generateReqStep[ig].first;
2105  int& nstep = generateReqStep[ig].second;
2106  double& rmin = generateRanges[ig].first;
2107  double& rmax = generateRanges[ig].second;
2108  finalX.setRange(rmin, rmax);
2109  RooDataSet* dsSamplePoints = trueBW->generate(finalX, nrequested*nstep);
2110  vector<float> tmpList;
2111  for (int ev=0; ev<dsSamplePoints->numEntries(); ev++){
2112  float val = dynamic_cast<RooAbsReal*>(dsSamplePoints->get(ev)->find(finalX))->getVal();
2113  addByLowest(tmpList, val, true);
2114  }
2115  delete dsSamplePoints;
2116  for (int ev=0; ev<(int)tmpList.size(); ev+=nstep) samplePointsList.push_back(tmpList.at(ev));
2117  }
2118  finalX.setRange(0.1, 1000.*sqrts);
2119  finalY.setRange(0.1, 1000.*sqrts);
2120  addByLowest(samplePointsList, float(finalX.getMin()), true);
2121  addByLowest(samplePointsList, float(finalX.getMax()), true);
2122 
2123  vector<pair<double, double>> idealBWpoints;
2124  for (unsigned int ev=0; ev<samplePointsList.size(); ev++){
2125  finalX.setVal(samplePointsList[ev]);
2126  idealBWpoints.push_back(pair<double, double>(finalX.getVal(), trueBW->getVal()));
2127  cout << "Sampled point " << idealBWpoints.at(ev).first << " , " << idealBWpoints.at(ev).second << " from ideal BW." << endl;
2128  }
2129  vector<pair<double, double>> recoBWpoints;
2130  typedef MELANCSplineCore::T stype;
2131  for (unsigned int ev=0; ev<samplePointsList.size(); ev++){
2132  double recoval = samplePointsList[ev];
2133  finalY.setVal(recoval);
2134 
2135  vector<pair<stype, stype>> idealBWconvpoints;
2136  for (unsigned int ip=0; ip<idealBWpoints.size(); ip++){
2137  double& trueval = idealBWpoints.at(ip).first;
2138  finalX.setVal(trueval);
2139  double resoval = thePdf->getVal();
2140  idealBWconvpoints.push_back(pair<stype, stype>((stype)trueval, (stype)(idealBWpoints.at(ip).second*resoval)));
2141  }
2142  MELANCSplineFactory_1D truespline(finalX, "tmp");
2143  truespline.setPoints(idealBWconvpoints);
2144  double recobwval = truespline.getPDF()->analyticalIntegral(2);
2145  recoBWpoints.push_back(pair<double, double>(recoval, recobwval));
2146 
2147  cout << "Conv. ideal BW integral at reco = " << recoval << " : " << recobwval << endl;
2148 
2149  /*
2150  TGraph* tg_idealBWconv = makeGraphFromPair(idealBWconvpoints, Form("tg_idealBWconv_%i", ev));
2151  tg_idealBWconv->SetTitle(Form("Conv. ideal BW at reco = %.5f", recoval));
2152  tg_idealBWconv->SetDrawOption("pl");
2153  tg_idealBWconv->GetXaxis()->SetRangeUser(0.1, 250.);
2154  foutput->WriteTObject(tg_idealBWconv);
2155  delete tg_idealBWconv;
2156  */
2157  }
2158  TGraph* tg_recoBW = makeGraphFromPair(recoBWpoints, "tg_recoBW");
2159  TGraph* tg_idealBW = makeGraphFromPair(idealBWpoints, "tg_idealBW");
2160 
2161  tg_recoBW->SetMarkerStyle(20);
2162  tg_recoBW->SetMarkerSize(1.2);
2163  tg_recoBW->SetMarkerColor(kRed);
2164  tg_recoBW->SetLineColor(kRed);
2165  tg_recoBW->GetXaxis()->SetRangeUser(0.1, 250.);
2166  tg_recoBW->GetXaxis()->SetTitle("m_{JJ} (GeV)");
2167  tg_recoBW->GetYaxis()->SetTitle("BW (GeV^{-3})");
2168  tg_recoBW->SetTitle(TString("Reco. BW for ")+strprod);
2169  tg_idealBW->SetMarkerStyle(21);
2170  tg_idealBW->SetMarkerSize(0.8);
2171  tg_idealBW->SetMarkerColor(kBlack);
2172  tg_idealBW->SetLineColor(kBlack);
2173  tg_idealBW->GetXaxis()->SetRangeUser(0.1, 250.);
2174  tg_idealBW->GetXaxis()->SetTitle("m_{JJ} (GeV)");
2175  tg_idealBW->GetYaxis()->SetTitle("BW (GeV^{-3})");
2176  tg_idealBW->SetTitle(TString("True BW for ")+strprod);
2177  foutput->WriteTObject(tg_idealBW);
2178  foutput->WriteTObject(tg_recoBW);
2179 
2180  canvas = new TCanvas(TString("cFinalBWComparison_")+strprod, "", 800, 800);
2181  tg_idealBW->SetTitle(TString("BW for ")+strprod);
2182  tg_recoBW->SetTitle("");
2183  tg_idealBW->Draw("acp");
2184  tg_recoBW->Draw("cpsame");
2185  canvas->Modified();
2186  canvas->Update();
2187  canvas->SaveAs(Form("%s%s", canvas->GetName(), ".pdf"));
2188  canvas->Close();
2189 
2190  delete tg_idealBW;
2191  delete tg_recoBW;
2192 
2193  delete trueBW;
2194  delete GaV;
2195  delete mV;
2196  }
2197  delete thePdf;
2198  delete theFunc;
2199 
2200  for (unsigned int is=0; is<facList.size(); is++) delete facList.at(is);
2201  for (unsigned int is=0; is<tglist.size(); is++) delete tglist.at(is);
2202 
2203  TGraphErrors* tg_avg_varReco = makeGraphFromTH1(hvar, havg_varReco, Form("tg_%s", havg_varReco->GetName()));
2204  foutput->WriteTObject(tg_avg_varReco);
2205  delete tg_avg_varReco;
2206 
2207  for (int ix=0; ix<=hvarTrue_varReco->GetNbinsX()+1; ix++){
2208  double integral = hvarTrue_varReco->Integral(ix, ix, 0, hvarTrue_varReco->GetNbinsY()+1);
2209  if (integral!=0.){
2210  for (int iy=0; iy<=hvarTrue_varReco->GetNbinsY()+1; iy++){
2211  double bincontent = hvarTrue_varReco->GetBinContent(ix, iy);
2212  double binerror = hvarTrue_varReco->GetBinError(ix, iy);
2213  bincontent /= integral;
2214  binerror /= integral; // I know this is wrong, but I don't care about the errors that much.
2215  hvarTrue_varReco->SetBinContent(ix, iy, bincontent);
2216  hvarTrue_varReco->SetBinError(ix, iy, binerror);
2217  }
2218  }
2219  }
2220  if (debug){
2221  foutput->WriteTObject(hvar);
2222  foutput->WriteTObject(havg_varReco);
2223  foutput->WriteTObject(hvarTrue_varReco);
2224  if (writeFinalTree) foutput->WriteTObject(newtree);
2225  }
2226  if (writeFinalTree) delete newtree;
2227  delete hvarTrue_varReco;
2228  delete havg_varReco;
2229  delete hvar;
2230  delete[] binning;
2231 
2232  for (unsigned int f=0; f<finputList.size(); f++) finputList.at(f)->Close();
2233  foutput->Close();
2234 }
2235 
2236 void test(){
2237  vector<pair<MELANCSplineCore::T, MELANCSplineCore::T>> pList;
2238  MELANCSplineCore::T xrange[2]={ 0, 2 };
2239  const int n = 11;
2240  for (int i=0; i<n; i++){
2241  MELANCSplineCore::T x = (xrange[1]-xrange[0])/((MELANCSplineCore::T)(n-1))*((MELANCSplineCore::T)i)+xrange[0];
2242  MELANCSplineCore::T y = 1./(xrange[1]-xrange[0]);
2243  pList.push_back(pair<MELANCSplineCore::T, MELANCSplineCore::T>(x, y));
2244  }
2245  RooRealVar var("var", "", xrange[0], xrange[1]);
2246  var.setBins(2);
2247  MELANCSplineFactory_1D fac_sp(var, "tmp");
2248  fac_sp.setPoints(pList);
2249  MELANCSplineCore* sp = fac_sp.getFunc();
2250 
2251  RooRealIntegral* sp_int = new RooRealIntegral("sp_int", "", *sp, RooArgSet(var));
2252  double spintval = sp_int->getVal();
2253  cout << "PDF int: " << spintval << endl;
2254  delete sp_int;
2255 
2256  RooPlot* plot = var.frame();
2257  plot->GetXaxis()->CenterTitle();
2258  plot->GetYaxis()->SetTitleOffset(1.2);
2259  plot->GetYaxis()->CenterTitle();
2260  sp->plotOn(plot, LineColor(kRed), LineWidth(2), LineStyle(1));
2261  plot->GetXaxis()->SetNdivisions(510);
2262  TCanvas* canvas = new TCanvas("ctest", "", 800, 800);
2263  plot->Draw();
2264  canvas->Modified();
2265  canvas->Update();
2266  canvas->SaveAs("test.pdf");
2267  canvas->Close();
2268  delete plot;
2269 }
ExtBin::collection
vector< SimpleEntry > collection
Definition: getResolution.c:180
PDGHelpers::HDecayMode
TVar::CandidateDecayMode HDecayMode
Definition: PDGHelpers.cc:11
value
pymela::gHIGGS_KAPPA value("gHIGGS_KAPPA_TILDE", pymela::gHIGGS_KAPPA_TILDE) .value("SIZE_HQQ"
MELAParticle::getDaughter
MELAParticle * getDaughter(int index) const
Definition: MELAParticle.cc:68
constructSamplesList
vector< TString > constructSamplesList(TString strsample, float sqrts)
Definition: getResolution.c:303
MELANCSplineCore::T
Float_t T
Definition: MELANCSplineCore.h:18
findTree
TTree * findTree(vector< TTree * > treeList, int evid)
Definition: getResolution.c:281
ExtBin::binlow
double binlow
Definition: calcC_lintolog.c:112
splitOptionRecursive
void splitOptionRecursive(const string rawoption, vector< string > &splitoptions, char delimiter)
Definition: getResolution.c:165
mela
Definition: mela.py:1
TVar::CandidateDecay_ZZ
@ CandidateDecay_ZZ
Definition: TVar.hh:41
MELAParticle::getNDaughters
int getNDaughters() const
Definition: MELAParticle.h:50
MELALinearInterpFunc::setRangeValidity
void setRangeValidity(const T valmin, const T valmax)
Definition: MELALinearInterpFunc.cc:306
splitOption
void splitOption(const string rawoption, string &wish, string &value, char delimiter)
Definition: getResolution.c:153
PDGHelpers::m_el
const double m_el
Definition: PDGHelpers.h:18
MELANCSplineFactory_1D.h
inputdir_7TeV
TString inputdir_7TeV
Definition: getResolution.c:47
TVar::CandidateDecayMode
CandidateDecayMode
Definition: TVar.hh:37
ExtBin::addEvent
void addEvent(int ev, float trueval, float recoval, float recotrackval=0, float weight=1)
Definition: getResolution.c:185
makeGraphFromPair
TGraph * makeGraphFromPair(vector< pair< T, T >> points, TString name)
Definition: getResolution.c:680
test
void test()
Definition: getResolution.c:2236
MELANCSplineFactory_1D
Definition: MELANCSplineFactory_1D.h:12
TUtil::PrintCandidateSummary
void PrintCandidateSummary(MELACandidate *cand)
Definition: TUtil.cc:8590
getResolution_mJJ
void getResolution_mJJ(float sqrts, TString strprod, bool debug=false)
Definition: getResolution.c:1105
findPoleMass
float findPoleMass(TString samplename)
Definition: getResolution.c:265
modparameters::second
real(8), parameter, public second
Definition: mod_Parameters.F90:105
modmisc::isnan
logical function isnan(x)
Definition: mod_Misc.F90:380
PDGHelpers::isAQuark
bool isAQuark(const int id)
Definition: PDGHelpers.cc:35
SimpleEntry::weight
float weight
Definition: getResolution.c:56
ExtBin::mergeBin
void mergeBin(const ExtBin &other)
Definition: getResolution.c:262
inputdir_8TeV
TString inputdir_8TeV
Definition: getResolution.c:48
ExtBin::addEvent
void addEvent(SimpleEntry evt)
Definition: getResolution.c:182
dd_global::rmax
integer rmax
Definition: DD_global.F90:12
addPoint
void addPoint(TGraph *&tg, double x, double y)
Definition: getResolution.c:734
MELAParticle::m
double m() const
Definition: MELAParticle.h:66
MELANCSpline_1D_fast
Definition: MELANCSpline_1D_fast.h:12
MELAParticle::p4
TLorentzVector p4
Definition: MELAParticle.h:18
modparameters::ev
real(8), parameter, public ev
Definition: mod_Parameters.F90:97
getResolution_mH_signal
void getResolution_mH_signal(float sqrts, TString strprod)
Definition: getResolution.c:819
testME_all.int
int
Definition: testME_all.py:13
SimpleEntry
Definition: getResolution.c:51
SimpleEntry::id
int id
Definition: getResolution.c:52
ExtBin::sift
void sift(double threshold=0.998, bool use_recominustrue=false)
Definition: getResolution.c:200
MELAParticle::deltaR
double deltaR(const TLorentzVector &v) const
Definition: MELAParticle.h:82
appendVector
void appendVector(std::vector< T > &a, std::vector< T > &b)
Definition: getResolution.c:69
inputdir_13TeV
TString inputdir_13TeV
Definition: getResolution.c:49
MELAParticle
Definition: MELAParticle.h:13
PDGHelpers::setCandidateDecayMode
void setCandidateDecayMode(TVar::CandidateDecayMode mode)
Definition: PDGHelpers.cc:232
MELANCSplineCore
Definition: MELANCSplineCore.h:16
MELALinearInterpFunc.h
getEntry
void getEntry(vector< TTree * > treeList, int evid)
Definition: getResolution.c:292
MELALinearInterpFunc::T
Float_t T
Definition: MELALinearInterpFunc.h:15
solveQuadratic
vector< double > solveQuadratic(vector< pair< double, double >> xy)
Definition: getResolution.c:696
makeGraphFromTH1
TGraphErrors * makeGraphFromTH1(TH1 *hx, TH1 *hy, TString name)
Definition: getResolution.c:658
ExtBin::sortByRecoVals
void sortByRecoVals(vector< pair< float, int >> &res)
Definition: getResolution.c:196
MELAFuncPdf::analyticalIntegral
Double_t analyticalIntegral(Int_t code, const char *rangeName=0) const
Definition: MELAFuncPdf.h:27
dd_global::cout
integer cout
Definition: DD_global.F90:21
Mela
Definition: Mela.h:48
solveGaussian
vector< double > solveGaussian(vector< pair< double, double >> xy)
Definition: getResolution.c:717
ExtBin::addEvent
void addEvent(float mass, float me, float me2, float weight=1)
Definition: calcC_lintolog.c:120
MELAFuncPdf
Definition: MELAFuncPdf.h:7
Mela.h
This is the "MELA" object that interfaces with the Fortran code in both MCFM-JHUGen and pure JHUGen.
addByLowest
void addByLowest(std::vector< T > &valArray, T val, bool unique)
Definition: getResolution.c:71
ExtBin
Definition: calcC_lintolog.c:111
SimpleEntry::SimpleEntry
SimpleEntry(int id_, float trueval_, float recoval_, float recotrackval_=0, float weight_=1)
Definition: getResolution.c:59
PDGHelpers::isAGluon
bool isAGluon(const int id)
Definition: PDGHelpers.cc:58
ExtBin::binhigh
double binhigh
Definition: calcC_lintolog.c:113
ExtBin::adjustWeights
void adjustWeights(float refth=-1)
Definition: getResolution.c:228
MELANCSplineFactory_1D::setPoints
void setPoints(TTree *tree)
Definition: MELANCSplineFactory_1D.cc:21
PDGHelpers::m_mu
const double m_mu
Definition: PDGHelpers.h:19
MELANCSplineFactory_1D::getFunc
MELANCSpline_1D_fast * getFunc()
Definition: MELANCSplineFactory_1D.h:36
SimpleEntry::SimpleEntry
SimpleEntry()
Definition: getResolution.c:58
MELANCSpline_1D_fast::setRangeValidity
void setRangeValidity(const T valmin, const T valmax, const Int_t whichDirection=0)
Definition: MELANCSpline_1D_fast.cc:213
MELACandidate::sortDaughters
void sortDaughters()
Definition: MELACandidate.cc:117
MELACandidate
Definition: MELACandidate.h:7
SimpleEntry::recotrackval
float recotrackval
Definition: getResolution.c:55
MELAParticle::dot
double dot(const TLorentzVector &v) const
Definition: MELAParticle.h:76
ExtBin::sortByRecoMinusTrueVals
void sortByRecoMinusTrueVals(vector< pair< float, int >> &res)
Definition: getResolution.c:189
globalc::f
double complex, dimension(2) f
Definition: reductionC.F90:50
sqrts
double sqrts
Definition: TMCFM.hh:290
MELAParticle::id
int id
Definition: MELAParticle.h:17
checkListVariable
bool checkListVariable(const vector< T > &list, const T &var)
Definition: getResolution.c:146
MELALinearInterpFunc
Definition: MELALinearInterpFunc.h:13
MELANCSplineFactory_1D::getPDF
MELAFuncPdf * getPDF()
Definition: MELANCSplineFactory_1D.h:37
SimpleEntry::recoval
float recoval
Definition: getResolution.c:54
MELANCSplineFactory_2D.h
SimpleEntry::trueval
float trueval
Definition: getResolution.c:53
PDGHelpers::m_tau
const double m_tau
Definition: PDGHelpers.h:20
MELAParticle::addDaughter
void addDaughter(MELAParticle *myParticle)
Definition: MELAParticle.cc:63