Beispiel #1
0
void automatic(string var = "zllmass", string masspoint="500", string label="m_{ll}", bool set_logScale=false, float intLumi= 349.){
  //  gROOT->Reset();
  gROOT->SetStyle("Plain");

  enum selType{muChannel, elChannel};

  /*    START CUSTOMIZATION */

  //  string masspoint = "500";
  string output = masspoint +".txt";  
  //string label = "m_{ll} [GeV]";
  // string var = "zllmass";
  //  float intLumi = 349.;
  int rebin_fact = 2;
  // set log scale for plots
  // bool set_logScale = true;
  string lumi = "1 fb^{-1}";
  // set to true in order to set the range on the X axis
  bool custom = true;

  /*    END CUSTOMIZATION */

  if(custom){
    float rMin = 50.;
    float rMax = 150.;
}
  int ymax =20.;
  if(set_logScale) ymax = 1000.;
  string postfix  = "EdmNtp.root";
  ofstream f(output.c_str());
  float y_mu =200.;
  float y_el =200.;

  float x_mu = 50.;  
  float x_el = 50.;  
  int max = 100;
  int min = 800;
  float br_fact = 0.333;
  //float normFact = 1/1000;
  float normFact = intLumi/1000.;

  /* 250 */
  if(masspoint=="250"){
    int cut_value1=237;
    int cut_value2=260;
  }
  else if(masspoint=="300"){
    int cut_value1=280;
    int cut_value2=323;
  }
  else if(masspoint=="350"){
    int cut_value1=380;
    int cut_value2=330;
  }
  else if(masspoint=="4000"){
    int cut_value1=390;
    int cut_value2=460;
  }
  else if(masspoint=="450"){
    int cut_value1=420;
    int cut_value2=550;
  }
  else if(masspoint=="500"){
    int cut_value1=470;
    int cut_value2=1000;
  }
  
  vector<int> thisSel;
  thisSel.push_back(muChannel);
  thisSel.push_back(elChannel);

  // set selection type:
  //  selType this_selection = muChannel;
  // set rebin factor for histos


  // Set scale factors for lumi normalization
  float scaleZbb[]={0.00838281, 0.01604, 0.057394, 0.02507414};
  // right factors are those below, the previous ones are used just because a crash during the skim   
  //  float scaleZbb[]={0.00838281, 0.00812031, 0.057394, 0.02507414};
  float scaleZcc[]={0.0066633, 0.00883544, 0.05828496, 0.02760666};
  float scaleZjets_mu[]={1.6000847, 1.55144941, 1.060303407, 0.168596, 0.3089263, 0.11791534, 0.21228856, 0.15464988, 0.07783832, 0.15061466, 0.00185248, 0.00352303, 0.00567954, 0.01118749, 0.00511575, 0.00001615, 0.00007081, 0.00005568, 0.00004569, 0.00002192};
  float scaleZjets_el[]={0.0338, 0.098855, 0.1083411, 0.14836314,0.06671835, 0.00093808, 0.01061008, 0.02191539,0.020801, 0.0264994, 0.00001681, 0.00025568, 0.00072630,0.00135979, 0.00162018,0.00000036, 0.00000745, 0.00002377, 0.00003277, 0.00000393};
  float scaleZ0Jets =5.118;
  float scaleTT =0.0165;
  float scaleWZ =0.00863;
  float scaleZZ =0.002798;
  float scaleWW =0.0208;
  float scaleH400 =0.0005031;
  float scaleH450 =0.00032118;
  float scaleH350 = 0.00070501;
  float scaleH300 =0.00073510;
  float scaleH250 =0.00096653;
  float scaleH500 =0.00021778;

  float scaleFact250 =  scaleH250*normFact;
  float scaleFact300 =  scaleH300*normFact;
  float scaleFact350 =  scaleH350*normFact;
  float scaleFact400 =  scaleH400*normFact;
  float scaleFact450 =  scaleH450*normFact;
  float scaleFact500 =  scaleH500*normFact;
  
  float scaleFactZbb0 =  scaleZbb[1]*normFact;
  float scaleFactZbb1 =  scaleZbb[2]*normFact;
  float scaleFactZbb2 =  scaleZbb[3]*normFact;
  float scaleFactZbb3 =  scaleZbb[4]*normFact;

  float scaleFactZcc0 =  scaleZcc[0]*normFact;
  float scaleFactZcc1 =  scaleZcc[1]*normFact;
  float scaleFactZcc2 =  scaleZcc[2]*normFact;
  float scaleFactZcc3 =  scaleZcc[3]*normFact;

  float scaleFactZZ =  scaleZZ*normFact;
  float scaleFactWZ =  scaleWZ*normFact;
  float scaleFactTT =  scaleTT*normFact;
  float scaleFactWW =  scaleWW*normFact;
  
  float scaleFactZ0jet =  scaleZ0Jets*normFact*br_fact;

  float scaleFactZ1jet_mu =  scaleZjets_mu[0]*normFact*br_fact;
  float scaleFactZ2jet_mu =  scaleZjets_mu[1]*normFact*br_fact;
  float scaleFactZ3jet_mu =  scaleZjets_mu[2]*normFact*br_fact;
  float scaleFactZ4jet_mu =  scaleZjets_mu[3]*normFact*br_fact;
  float scaleFactZ5jet_mu =  scaleZjets_mu[4]*normFact*br_fact;

  float scaleFactZ1jet100_300_mu = scaleZjets_mu[5]*normFact*br_fact; 
  float scaleFactZ2jet100_300_mu = scaleZjets_mu[6]*normFact*br_fact; 
  float scaleFactZ3jet100_300_mu = scaleZjets_mu[7]*normFact*br_fact; 
  float scaleFactZ4jet100_300_mu = scaleZjets_mu[8]*normFact*br_fact; 
  float scaleFactZ5jet100_300_mu = scaleZjets_mu[9]*normFact*br_fact;

  float scaleFactZ1jet300_800_mu = scaleZjets_mu[10]*normFact*br_fact; 
  float scaleFactZ2jet300_800_mu = scaleZjets_mu[11]*normFact*br_fact; 
  float scaleFactZ3jet300_800_mu = scaleZjets_mu[12]*normFact*br_fact; 
  float scaleFactZ4jet300_800_mu = scaleZjets_mu[13]*normFact*br_fact; 
  float scaleFactZ5jet300_800_mu = scaleZjets_mu[14]*normFact*br_fact; 

  float scaleFactZ1jet800_1600_mu = scaleZjets_mu[15]*normFact*br_fact;
  float scaleFactZ2jet800_1600_mu = scaleZjets_mu[16]*normFact*br_fact;
  float scaleFactZ3jet800_1600_mu = scaleZjets_mu[17]*normFact*br_fact;
  float scaleFactZ4jet800_1600_mu = scaleZjets_mu[18]*normFact*br_fact;
  float scaleFactZ5jet800_1600_mu = scaleZjets_mu[19]*normFact*br_fact;


  float scaleFactZ1jet_el =  scaleZjets_el[0]*normFact*br_fact;
  float scaleFactZ2jet_el =  scaleZjets_el[1]*normFact*br_fact;
  float scaleFactZ3jet_el =  scaleZjets_el[2]*normFact*br_fact;
  float scaleFactZ4jet_el =  scaleZjets_el[3]*normFact*br_fact;
  float scaleFactZ5jet_el =  scaleZjets_el[4]*normFact*br_fact;

  float scaleFactZ1jet100_300_el = scaleZjets_el[5]*normFact*br_fact; 
  float scaleFactZ2jet100_300_el = scaleZjets_el[6]*normFact*br_fact; 
  float scaleFactZ3jet100_300_el = scaleZjets_el[7]*normFact*br_fact; 
  float scaleFactZ4jet100_300_el = scaleZjets_el[8]*normFact*br_fact; 
  float scaleFactZ5jet100_300_el = scaleZjets_el[9]*normFact*br_fact;

  float scaleFactZ1jet300_800_el = scaleZjets_el[10]*normFact*br_fact; 
  float scaleFactZ2jet300_800_el = scaleZjets_el[11]*normFact*br_fact; 
  float scaleFactZ3jet300_800_el = scaleZjets_el[12]*normFact*br_fact; 
  float scaleFactZ4jet300_800_el = scaleZjets_el[13]*normFact*br_fact; 
  float scaleFactZ5jet300_800_el = scaleZjets_el[14]*normFact*br_fact; 

  float scaleFactZ1jet800_1600_el = scaleZjets_el[15]*normFact*br_fact;
  float scaleFactZ2jet800_1600_el = scaleZjets_el[16]*normFact*br_fact;
  float scaleFactZ3jet800_1600_el = scaleZjets_el[17]*normFact*br_fact;
  float scaleFactZ4jet800_1600_el = scaleZjets_el[18]*normFact*br_fact;
  float scaleFactZ5jet800_1600_el = scaleZjets_el[19]*normFact*br_fact;


  for(int i=0; i<thisSel.size();++i){
    selType this_selection = thisSel[i];

    // INPUT DIR for the histo files
    string input_dir_base = "NoNorm_Mu/";
    if(this_selection == elChannel)
      input_dir_base = "NoNorm_El/";
    
    // OUTPUT DIR for the histo files
    string out_dir_base = "NoNorm_Mu/";
    if(this_selection == elChannel)
      out_dir_base = "NoNorm_El/";

    // OUTPUT .png file
    string name_eps = var+"_Lin_Mu.png";
    if(set_logScale) name_eps = var+"_Log_Mu.png";
    if(this_selection == elChannel){
      name_eps = var+"_Lin_El.png";
      if(set_logScale) name_eps = var+"_Log_El.png";    
    }


  // Print on the screen what selection you are applying
    if(this_selection == muChannel){
      cout << "####################### COMBINING MU HISTOS ##########################" << endl << endl;
      //     TLatex *t= new TLatex(x_mu,y_mu,"CMS Preliminary   ");
    }


    if(this_selection == elChannel){
      cout << "##################### COMBINING ELECTRON HISTOS ######################" << endl << endl;
      //TLatex *t= new TLatex(x_el,y_el,"CMS Preliminary");
    }
  
    //    t->SetTextFont(72);
    // t->SetTextSize(0.06);

    string create_out_dir = "mkdir "+out_dir_base;
    gSystem->Exec( create_out_dir.c_str() );
    
  /*h250*/

  /*h300*/
  string infile_name = input_dir_base+masspoint+postfix;
  TFile f_h500(infile_name.c_str());
  TH1F * var_h500_Raw = (TH1F*) f_h500.Get(var.c_str());
  TH1F * var_h500 = new TH1F(*var_h500_Raw);
  if(masspoint=="200") var_h500->Scale(scaleFact200);
  else if(masspoint=="250") var_h500->Scale(scaleFact250);
  else if(masspoint=="300") var_h500->Scale(scaleFact300);
  else if(masspoint=="350") var_h500->Scale(scaleFact350);
  else if(masspoint=="400") var_h500->Scale(scaleFact400);
  else if(masspoint=="450") var_h500->Scale(scaleFact450);
  else if(masspoint=="500") var_h500->Scale(scaleFact500);

  cout << "h500 raw entries" << var_h500_Raw->Integral() << endl;
  cout << "h500 1 fb entries" << var_h500->Integral() << endl;

  TH1F * var_All500 = new TH1F(*var_h500_Raw);
  var_All500->Reset();

  /*infile_name = input_dir_base+"h450VBF"+postfix;
  TFile f_h450vbf(infile_name.c_str());
  TH1F * var_h450VBF_Raw = (TH1F*) f_h450vbf.Get(var.c_str());

  TH1F * var_h450VBF = new TH1F(*var_h450VBF_Raw);
  var_h450VBF->Scale(scaleFactVBF450);
  cout << "h450VBF raw entries " << var_h450VBF_Raw->Integral() << endl;
  cout << "h450VBF 1 fb entries " << var_h450VBF->Integral() << endl;

  TH1F * var_h450 = new TH1F(*var_h450GF_Raw);
  var_h450->Add(var_h450GF,var_h450VBF);
  */
  cout << "---> h450ALL 1 fb entries " << var_h500->Integral() << endl;

  /*
  infile_name = input_dir_base+"data"+postfix;
  TFile f_data(infile_name.c_str());
  TH1F * var_data_Raw = (TH1F*) f_data.Get(var.c_str());

  TH1F * var_data = new TH1F(*var_data_Raw);
  cout << "data raw entries " << var_data_Raw->Integral() << endl;
  cout << "---> data "+lumi+" fb entries " << var_data->Integral() << endl;
  */


  infile_name = input_dir_base+"TT"+postfix;
  TFile f_tt(infile_name.c_str());
  TH1F * var_TT_Raw = (TH1F*) f_tt.Get(var.c_str());

  TH1F * var_TT = new TH1F(*var_TT_Raw);
  var_TT->Scale(scaleFactTT);
  cout << "TT raw entries " << var_TT_Raw->Integral() << endl;
  cout << "---> TT 1 fb entries " << var_TT->Integral() << endl;


  infile_name = input_dir_base+"ZZ"+postfix;
  TFile f_zz(infile_name.c_str());
  TH1F * var_ZZ_Raw = (TH1F*) f_zz.Get(var.c_str());
  TH1F * var_ZZ = new TH1F(*var_ZZ_Raw);
  var_ZZ->Scale(scaleFactZZ);
  cout << "ZZ raw entries " << var_ZZ_Raw->Integral() << endl;
  cout << "---> ZZ 1 fb entries " << var_ZZ->Integral() << endl;

  infile_name = input_dir_base+"WZ"+postfix;
  TFile f_wz(infile_name.c_str());
  TH1F * var_WZ_Raw = (TH1F*) f_wz.Get(var.c_str());
  TH1F * var_WZ = new TH1F(*var_WZ_Raw);
  var_WZ->Scale(scaleFactWZ);
  cout << "WZ raw entries " << var_WZ_Raw->Integral() << endl;
  cout << "---> WZ 1 fb entries " << var_WZ->Integral() << endl;

  infile_name = input_dir_base+"WW"+postfix;
  TFile f_ww(infile_name.c_str());
  TH1F * var_WW_Raw = (TH1F*) f_ww.Get(var.c_str());
  TH1F * var_WW = new TH1F(*var_WW_Raw);
  var_WW->Scale(scaleFactWW);
  cout << "WW raw entries " << var_WW_Raw->Integral() << endl;
  cout << "---> WW 1 fb entries " << var_WW->Integral() << endl;


  infile_name = input_dir_base+"ZBB0"+postfix;
  TFile f_zbb0(infile_name.c_str());
  TH1F * var_ZBB0_Raw = (TH1F*) f_zbb0.Get(var.c_str());
  TH1F * var_ZBB0 = new TH1F(*var_ZBB0_Raw);
  var_ZBB0->Scale(scaleFactZbb0);

  infile_name = input_dir_base+"ZBB1"+postfix;
  TFile f_zbb1(infile_name.c_str());
  TH1F * var_ZBB1_Raw = (TH1F*) f_zbb1.Get(var.c_str());
  TH1F * var_ZBB1 = new TH1F(*var_ZBB1_Raw);
  var_ZBB1->Scale(scaleFactZbb1);

  infile_name = input_dir_base+"ZBB2"+postfix;
  TFile f_zbb2(infile_name.c_str());
  TH1F * var_ZBB2_Raw = (TH1F*) f_zbb2.Get(var.c_str());
  TH1F * var_ZBB2 = new TH1F(*var_ZBB2_Raw);
  var_ZBB2->Scale(scaleFactZbb2);

  infile_name = input_dir_base+"ZBB3"+postfix;
  TFile f_zbb3(infile_name.c_str());
  TH1F * var_ZBB3_Raw = (TH1F*) f_zbb3.Get(var.c_str());
  TH1F * var_ZBB3 = new TH1F(*var_ZBB3_Raw);
  var_ZBB3->Scale(scaleFactZbb3);

  TH1F * var_ZBB = new TH1F(*var_ZBB0);
  var_ZBB->Add( var_ZBB1);
  var_ZBB->Add( var_ZBB2);
  var_ZBB->Add( var_ZBB3);

  cout << "---> ZBB 1 fb entries " << var_ZBB->Integral() << endl;

  infile_name = input_dir_base+"ZCC0"+postfix;
  TFile f_zcc0(infile_name.c_str());
  TH1F * var_ZCC0_Raw = (TH1F*) f_zcc0.Get(var.c_str());
  TH1F * var_ZCC0 = new TH1F(*var_ZCC0_Raw);
  var_ZCC0->Scale(scaleFactZcc0);

  infile_name = input_dir_base+"ZCC1"+postfix;
  TFile f_zcc1(infile_name.c_str());
  TH1F * var_ZCC1_Raw = (TH1F*) f_zcc1.Get(var.c_str());
  TH1F * var_ZCC1 = new TH1F(*var_ZCC1_Raw);
  var_ZCC1->Scale(scaleFactZcc1);

  infile_name = input_dir_base+"ZCC2"+postfix;
  TFile f_zcc2(infile_name.c_str());
  TH1F * var_ZCC2_Raw = (TH1F*) f_zcc2.Get(var.c_str());
  TH1F * var_ZCC2 = new TH1F(*var_ZCC2_Raw);
  var_ZCC2->Scale(scaleFactZcc2);

  infile_name = input_dir_base+"ZCC3"+postfix;
  TFile f_zcc3(infile_name.c_str());
  TH1F * var_ZCC3_Raw = (TH1F*) f_zcc3.Get(var.c_str());
  TH1F * var_ZCC3 = new TH1F(*var_ZCC3_Raw);
  var_ZCC3->Scale(scaleFactZcc3);

  TH1F * var_ZCC = new TH1F(*var_ZCC0);
  var_ZCC->Add(var_ZCC1);
  var_ZCC->Add(var_ZCC2);
  var_ZCC->Add(var_ZCC3);

  cout << "---> ZCC 1 fb entries " << var_ZCC->Integral() << endl;

  TH1F * var_ZBBZCC = new TH1F(*var_ZBB);
  var_ZBBZCC->Add(var_ZCC);
  cout << "---> ZBBZCC 1 fb entries " << var_ZBBZCC->Integral() << endl;


  infile_name = input_dir_base+"Z0Jets"+postfix;
  TFile f_z0jet(infile_name.c_str());
  TH1F * var_Z0JET_Raw = (TH1F*) f_z0jet.Get(var.c_str());
  TH1F * var_Z0JET = new TH1F(*var_Z0JET_Raw);
  cout<<"number events Z1Jet"<<endl;
  var_Z0JET->Scale(scaleFactZ0jet);
  

  infile_name = input_dir_base+"Z1Jets"+postfix;
  TFile f_z1jet(infile_name.c_str());
  TH1F * var_Z1JET_Raw = (TH1F*) f_z1jet.Get(var.c_str());
  TH1F * var_Z1JET = new TH1F(*var_Z1JET_Raw);

  if(this_selection == muChannel) var_Z1JET->Scale(scaleFactZ1jet_mu);
  if(this_selection == elChannel) var_Z1JET->Scale(scaleFactZ1jet_el);
  cout<<"number events Z1Jet "<<var_Z1JET->Integral()<<endl;


  infile_name = input_dir_base+"Z2Jets"+postfix;
  TFile f_z2jet(infile_name.c_str());
  TH1F * var_Z2JET_Raw = (TH1F*) f_z2jet.Get(var.c_str());
  TH1F * var_Z2JET = new TH1F(*var_Z2JET_Raw);
  if(this_selection == muChannel) var_Z2JET->Scale(scaleFactZ2jet_mu);
  if(this_selection == elChannel) var_Z2JET->Scale(scaleFactZ2jet_el);

  infile_name = input_dir_base+"Z3Jets"+postfix;
  TFile f_z3jet(infile_name.c_str());
  TH1F * var_Z3JET_Raw = (TH1F*) f_z3jet.Get(var.c_str());
  TH1F * var_Z3JET = new TH1F(*var_Z3JET_Raw);
  if(this_selection == muChannel) var_Z3JET->Scale(scaleFactZ3jet_mu);
  if(this_selection == elChannel) var_Z3JET->Scale(scaleFactZ3jet_el);

  infile_name = input_dir_base+"Z4Jets"+postfix;
  TFile f_z4jet(infile_name.c_str());
  TH1F * var_Z4JET_Raw = (TH1F*) f_z4jet.Get(var.c_str());
  TH1F * var_Z4JET = new TH1F(*var_Z4JET_Raw);
  if(this_selection == muChannel) var_Z4JET->Scale(scaleFactZ4jet_mu);
  if(this_selection == elChannel) var_Z4JET->Scale(scaleFactZ4jet_el);

  infile_name = input_dir_base+"Z5Jets"+postfix;
  TFile f_z5jet(infile_name.c_str());
  TH1F * var_Z5JET_Raw = (TH1F*) f_z5jet.Get(var.c_str());
  TH1F * var_Z5JET = new TH1F(*var_Z5JET_Raw);
  if(this_selection == muChannel) var_Z5JET->Scale(scaleFactZ5jet_mu);
  if(this_selection == elChannel) var_Z5JET->Scale(scaleFactZ5jet_el);


  infile_name = input_dir_base+"Z1Jets100_300"+postfix;
  TFile f_z1jet100_300(infile_name.c_str());
  TH1F * var_Z1JET100_300_Raw = (TH1F*) f_z1jet100_300.Get(var.c_str());
  TH1F * var_Z1JET100_300 = new TH1F(*var_Z1JET100_300_Raw);
  if(this_selection == muChannel) var_Z1JET100_300->Scale(scaleFactZ1jet100_300_mu);
  if(this_selection == elChannel) var_Z1JET100_300->Scale(scaleFactZ1jet100_300_el);
  cout<<"number events Z1Jet100_300 "<<var_Z1JET100_300->Integral()<<endl;

  infile_name = input_dir_base+"Z2Jets100_300"+postfix;
  TFile f_z2jet100_300(infile_name.c_str());
  TH1F * var_Z2JET100_300_Raw = (TH1F*) f_z2jet100_300.Get(var.c_str());
  TH1F * var_Z2JET100_300 = new TH1F(*var_Z2JET100_300_Raw);
  if(this_selection == muChannel) var_Z2JET100_300->Scale(scaleFactZ2jet100_300_mu);
  if(this_selection == elChannel) var_Z2JET100_300->Scale(scaleFactZ2jet100_300_el);

  infile_name = input_dir_base+"Z3Jets100_300"+postfix;
  TFile f_z3jet100_300(infile_name.c_str());
  TH1F * var_Z3JET100_300_Raw = (TH1F*) f_z3jet100_300.Get(var.c_str());
  TH1F * var_Z3JET100_300 = new TH1F(*var_Z3JET100_300_Raw);
  if(this_selection == muChannel) var_Z3JET100_300->Scale(scaleFactZ3jet100_300_mu);
  if(this_selection == elChannel) var_Z3JET100_300->Scale(scaleFactZ3jet100_300_el);

  infile_name = input_dir_base+"Z4Jets100_300"+postfix;
  TFile f_z4jet100_300(infile_name.c_str());
  TH1F * var_Z4JET100_300_Raw = (TH1F*) f_z4jet100_300.Get(var.c_str());
  TH1F * var_Z4JET100_300 = new TH1F(*var_Z4JET100_300_Raw);
  if(this_selection == muChannel) var_Z4JET100_300->Scale(scaleFactZ4jet100_300_mu);
  if(this_selection == elChannel) var_Z4JET100_300->Scale(scaleFactZ4jet100_300_el);

  infile_name = input_dir_base+"Z5Jets100_300"+postfix;
  TFile f_z5jet100_300(infile_name.c_str());
  TH1F * var_Z5JET100_300_Raw = (TH1F*) f_z5jet100_300.Get(var.c_str());
  TH1F * var_Z5JET100_300 = new TH1F(*var_Z5JET100_300_Raw);
  if(this_selection == muChannel) var_Z5JET100_300->Scale(scaleFactZ5jet100_300_mu);
  if(this_selection == elChannel) var_Z5JET100_300->Scale(scaleFactZ5jet100_300_el);

  infile_name = input_dir_base+"Z1Jets300_800"+postfix;
  TFile f_z1jet300_800(infile_name.c_str());
  TH1F * var_Z1JET300_800_Raw = (TH1F*) f_z1jet300_800.Get(var.c_str());
  TH1F * var_Z1JET300_800 = new TH1F(*var_Z1JET300_800_Raw);
  if(this_selection == muChannel) var_Z1JET300_800->Scale(scaleFactZ1jet300_800_mu);
  if(this_selection == elChannel) var_Z1JET300_800->Scale(scaleFactZ1jet300_800_el);
  cout<<"number events Z1Jet300_800 "<<var_Z1JET300_800->Integral()<<endl;

  infile_name = input_dir_base+"Z2Jets300_800"+postfix;
  TFile f_z2jet300_800(infile_name.c_str());
  TH1F * var_Z2JET300_800_Raw = (TH1F*) f_z2jet300_800.Get(var.c_str());
  TH1F * var_Z2JET300_800 = new TH1F(*var_Z2JET300_800_Raw);
  if(this_selection == muChannel) var_Z2JET300_800->Scale(scaleFactZ2jet300_800_mu);
  if(this_selection == elChannel) var_Z2JET300_800->Scale(scaleFactZ2jet300_800_el);

  infile_name = input_dir_base+"Z3Jets300_800"+postfix;
  TFile f_z3jet300_800(infile_name.c_str());
  TH1F * var_Z3JET300_800_Raw = (TH1F*) f_z3jet300_800.Get(var.c_str());
  TH1F * var_Z3JET300_800 = new TH1F(*var_Z3JET300_800_Raw);
  if(this_selection == muChannel) var_Z3JET300_800->Scale(scaleFactZ3jet300_800_mu);
  if(this_selection == elChannel) var_Z3JET300_800->Scale(scaleFactZ3jet300_800_el);

  infile_name = input_dir_base+"Z4Jets300_800"+postfix;
  TFile f_z4jet300_800(infile_name.c_str());
  TH1F * var_Z4JET300_800_Raw = (TH1F*) f_z4jet300_800.Get(var.c_str());
  TH1F * var_Z4JET300_800 = new TH1F(*var_Z4JET300_800_Raw);
  if(this_selection == muChannel) var_Z4JET300_800->Scale(scaleFactZ4jet300_800_mu);
  if(this_selection == elChannel) var_Z4JET300_800->Scale(scaleFactZ4jet300_800_el);

  infile_name = input_dir_base+"Z5Jets300_800"+postfix;
  TFile f_z5jet300_800(infile_name.c_str());
  TH1F * var_Z5JET300_800_Raw = (TH1F*) f_z5jet300_800.Get(var.c_str());
  TH1F * var_Z5JET300_800 = new TH1F(*var_Z5JET300_800_Raw);
  if(this_selection == muChannel) var_Z5JET300_800->Scale(scaleFactZ5jet300_800_mu);
  if(this_selection == elChannel) var_Z5JET300_800->Scale(scaleFactZ5jet300_800_el);


  infile_name = input_dir_base+"Z1Jets800_1600"+postfix;
  TFile f_z1jet800_1600(infile_name.c_str());
  TH1F * var_Z1JET800_1600_Raw = (TH1F*) f_z1jet800_1600.Get(var.c_str());
  TH1F * var_Z1JET800_1600 = new TH1F(*var_Z1JET800_1600_Raw);
  if(this_selection == muChannel)   var_Z1JET800_1600->Scale(scaleFactZ1jet800_1600_mu);
  if(this_selection == elChannel)   var_Z1JET800_1600->Scale(scaleFactZ1jet800_1600_el);
  cout<<"number events Z1Jet800_1600 "<<var_Z1JET800_1600->Integral()<<endl;

  infile_name = input_dir_base+"Z2Jets800_1600"+postfix;
  TFile f_z2jet800_1600(infile_name.c_str());
  TH1F * var_Z2JET800_1600_Raw = (TH1F*) f_z2jet800_1600.Get(var.c_str());
  TH1F * var_Z2JET800_1600 = new TH1F(*var_Z2JET800_1600_Raw);
  if(this_selection == muChannel)   var_Z2JET800_1600->Scale(scaleFactZ2jet800_1600_mu);
  if(this_selection == elChannel)   var_Z2JET800_1600->Scale(scaleFactZ2jet800_1600_el);

  infile_name = input_dir_base+"Z3Jets800_1600"+postfix;
  TFile f_z3jet800_1600(infile_name.c_str());
  TH1F * var_Z3JET800_1600_Raw = (TH1F*) f_z3jet800_1600.Get(var.c_str());
  TH1F * var_Z3JET800_1600 = new TH1F(*var_Z3JET800_1600_Raw);
  if(this_selection == muChannel)   var_Z3JET800_1600->Scale(scaleFactZ3jet800_1600_mu);
  if(this_selection == elChannel)   var_Z3JET800_1600->Scale(scaleFactZ3jet800_1600_el);

  infile_name = input_dir_base+"Z4Jets800_1600"+postfix;
  TFile f_z4jet800_1600(infile_name.c_str());
  TH1F * var_Z4JET800_1600_Raw = (TH1F*) f_z4jet800_1600.Get(var.c_str());
  TH1F * var_Z4JET800_1600 = new TH1F(*var_Z4JET800_1600_Raw);
  if(this_selection == muChannel)   var_Z4JET800_1600->Scale(scaleFactZ4jet800_1600_mu);
  if(this_selection == elChannel)   var_Z4JET800_1600->Scale(scaleFactZ4jet800_1600_el);

  infile_name = input_dir_base+"Z5Jets800_1600"+postfix;
  TFile f_z5jet800_1600(infile_name.c_str());
  TH1F * var_Z5JET800_1600_Raw = (TH1F*) f_z5jet800_1600.Get(var.c_str());
  TH1F * var_Z5JET800_1600 = new TH1F(*var_Z5JET800_1600_Raw);
  if(this_selection == muChannel)   var_Z5JET800_1600->Scale(scaleFactZ5jet800_1600_mu);
  if(this_selection == elChannel)   var_Z5JET800_1600->Scale(scaleFactZ5jet800_1600_el);

  TH1F * var_ZJET = new TH1F(*var_Z0JET);
    var_ZJET->Add( var_Z1JET);
  var_ZJET->Add( var_Z2JET);
  var_ZJET->Add( var_Z3JET);
  var_ZJET->Add( var_Z4JET);
  var_ZJET->Add( var_Z5JET);

  var_ZJET->Add( var_Z1JET100_300);
  var_ZJET->Add( var_Z2JET100_300);
  var_ZJET->Add( var_Z3JET100_300);
  var_ZJET->Add( var_Z4JET100_300);
  var_ZJET->Add( var_Z5JET100_300);

  var_ZJET->Add( var_Z1JET300_800);
  var_ZJET->Add( var_Z2JET300_800);
  var_ZJET->Add( var_Z3JET300_800);
  var_ZJET->Add( var_Z4JET300_800);
  var_ZJET->Add( var_Z5JET300_800);

  var_ZJET->Add( var_Z1JET800_1600);
  var_ZJET->Add( var_Z2JET800_1600);
  var_ZJET->Add( var_Z3JET800_1600);
  var_ZJET->Add( var_Z4JET800_1600);
  var_ZJET->Add( var_Z5JET800_1600);
  
  /*  var_ZJET->Add( var_Z1JET);
  var_ZJET->Add( var_Z1JET100_300);
  var_ZJET->Add( var_Z1JET300_800);
  var_ZJET->Add( var_Z1JET800_1600);
  */
  cout << "---> ZJet 1 fb entries after add" << var_ZJET->Integral() << endl;

  infile_name = input_dir_base+"MuRun2011A"+postfix;
  TFile f_dataMu(infile_name.c_str());
  TH1F * data_Mu = (TH1F*) f_dataMu.Get(var.c_str());
  infile_name = input_dir_base+"ElRun2011A"+postfix;
  TFile f_dataEl(infile_name.c_str());
  TH1F * data_El = (TH1F*) f_dataEl.Get(var.c_str());
  data_Mu->Add(data_El);
  cout<<"data"<<endl;

  // Eventually REBIN:
  if(rebin_fact > 1)
    {    
      //var_All250->Rebin(rebin_fact);
      //var_All300->Rebin(rebin_fact);
    var_All500->Rebin(rebin_fact);
    var_WW->Rebin(rebin_fact); 
    var_WZ->Rebin(rebin_fact); 
    var_TT->Rebin(rebin_fact); 
    var_ZCC->Rebin(rebin_fact); 
    var_ZBB->Rebin(rebin_fact); 
    var_ZJET->Rebin(rebin_fact); 
    var_ZZ->Rebin(rebin_fact); 
    //var_h250->Rebin(rebin_fact); 
    //var_h300->Rebin(rebin_fact); 
    var_h500->Rebin(rebin_fact); 
    data_Mu->Rebin(rebin_fact);
  }


  int n = var_h500->GetNbinsX();

  min = var_h500->GetXaxis()->GetXmin();
  max = var_h500->GetXaxis()->GetXmax();
  cout<<"min and max: "<<min<<" "<<max<<endl;
  cout<<"nBin: "<<n<<endl;
  float binsize = (max - min)/n;

  int bincut1 = (cut_value1 -min )/binsize +1;
  int bincut2 = (cut_value2 -min) /binsize +1;
  cout<<"bin cut "<<bincut1<<" --> "<<var_h500->GetBinCenter(bincut1)<<endl;
  cout<<"bin cut "<<bincut2<<" --> "<<var_h500->GetBinCenter(bincut2)<<endl;
 
  if(this_selection == elChannel)  f<<"Electron Channel "<<endl;
  if(this_selection == muChannel)  f<<"Muon Channel "<<endl;
  cout << "---> Higgs "<<masspoint<<" 1 fb entries in Signal region " << var_h500->Integral(bincut1,bincut2) << endl;
  cout << "---> ZJet 1 fb entries in Signal region " << var_ZJET->Integral(bincut1,bincut2) << endl;
  cout << "---> ZZ 1 fb entries in Signal region " << var_ZZ->Integral(bincut1,bincut2) << endl;
  cout << "---> WZ 1 fb entries in Signal region " << var_WZ->Integral(bincut1,bincut2) << endl;
  cout << "---> WW 1 fb entries in Signal region " << var_WW->Integral(bincut1,bincut2) << endl;
  cout << "---> Zbb 1 fb entries in Signal region " << var_ZBB->Integral(bincut1,bincut2) << endl;
  cout << "---> Zcc 1 fb entries in Signal region " << var_ZCC->Integral(bincut1,bincut2) << endl;
  cout << "---> TT 1 fb entries in Signal region " << var_TT->Integral(bincut1,bincut2) << endl;
 
  //  TH1F * S0 = new TH1F("S0","H mass",nbins,min,max);
  //  S0->SetMinimum(minimum);
  //  S0->SetMaximum(maximum);
  //  S0->SetTitle(var.c_str());

  // sum histos for stack plot
  TH1F * S1 = new TH1F(* var_WW);
  TH1F * S12 = new TH1F(* S1);
  //  TH1F * S12 = new TH1F(* var_TT);
  S12->Add(var_WZ);
  TH1F * S123 = new TH1F(* S12);
  //  TH1F * S12 = new TH1F(* var_TT);
  S123->Add(var_ZZ);
  TH1F * S1234 = new TH1F(* S123);
  //  TH1F * S123 = new TH1F(* var_ZBB);
  S1234->Add(var_TT);
  TH1F * S12345 = new TH1F(* S1234);
  //  TH1F * S123 = new TH1F(* var_ZBB);
  S12345->Add(var_ZBB);
  TH1F * S123456 = new TH1F(* S12345);
  //  TH1F * S1234 = new TH1F(* var_ZJET);
  S123456->Add(var_ZCC);
  TH1F * S1234567 = new TH1F(* S123456);
  //  TH1F * S12345 = new TH1F(* var_ZZ);
  S1234567->Add(var_ZJET);
  //  TH1F * S1234567 = new TH1F(* S123456);
  //  S1234567->Add(var_h250);

  //TH1F * S12345678 = new TH1F(* S123456);
  //  S12345678->Add(var_h500);

  TH1F * S12345678 = new TH1F(* S1234567);
  //  TH1F * S123456 = new TH1F(* var_h500);
  S12345678->Add(var_h500);


  // write data histo, stack histo and single histos into the output file

  TH1F *data = new TH1F("data","data", var_h500->GetNbinsX(), 100, 1000);
  data->SetName("data_obs");
  data->SetTitle("data_obs");

  
  if(this_selection == muChannel)  string outfile_name = out_dir_base+"Histo_"+masspoint+"_mu.root";
  if(this_selection == elChannel)  string outfile_name = out_dir_base+"Histo_"+masspoint+"_el.root";
  TFile outfile(outfile_name.c_str(), "RECREATE");
  //var_data->Write();

  data_Mu->SetMarkerStyle(22);
  data_Mu->Write();
  S12345678->SetName("data_obs");
  S12345678->Write();
  //  data->SetName("data_obs");
  var_WZ->SetName("WZtoany");
  var_WZ->Write();
  var_WW->SetName("WWtoany");
  var_WW->Write();
  var_TT->SetName("ttbar2L2Nu2B");
  var_TT->Write();
  var_ZBB->SetName("zbbbar");
  var_ZBB->Write();
  var_ZCC->SetName("zccbar");
  var_ZCC->Write();
  var_ZJET->SetName("zjets");
  var_ZJET->Write();
  var_ZZ->SetName("ZZtoany");
  var_ZZ->Write();
  //var_h250->Write();
  //var_h500->Write();
  var_h500->SetName("higgs");
  var_h500->Write();
  outfile.Close();



  // Draw stack plot into an .png file

  S12345678->SetStats(kFALSE);
  S1234567->SetStats(kFALSE);
  S123456->SetStats(kFALSE);
  S12345->SetStats(kFALSE);
  S1234->SetStats(kFALSE);
  S123->SetStats(kFALSE);
  S12->SetStats(kFALSE);
  S1->SetStats(kFALSE);

  S12345678->SetLineWidth(2);
  S1234567->SetLineWidth(2);
  S123456->SetLineWidth(2);
  S12345->SetLineWidth(2);
  S1234->SetLineWidth(2);
  S123->SetLineWidth(2);
  S12->SetLineWidth(2);
  S1->SetLineWidth(2);

  S1->SetFillColor(kYellow-7);
 //    S1->SetLineColor(kMagenta+4);
  S12->SetFillColor(kMagenta -3);
 //    S12->SetLineColor(kTeal+3);
  S123->SetFillColor(kTeal-5);
 //    S123->SetLineColor(kViolet+3);
  S1234->SetFillColor(kMagenta +3);
 //    S1234->SetLineColor(kPink-7);
  S12345->SetFillColor(kViolet+4);
 //    S12345->SetLineColor(kOrange+8);
  S123456->SetFillColor(kBlue-7);
  S1234567->SetFillColor(kOrange-2);
  S12345678->SetFillColor(kOrange+7);
  //  S123456->SetLineColor(kPink+3);


  //  TH1F * S1234567 = new TH1F(* S123456);
  //  S1234567->Add(h_svbf500);
  //  TH1F * S12345678 = new TH1F(* S1234567);
  //  S12345678->Add(h_svbf450);
 

  leg = new TLegend(.75,.75,1.0,1.0);
  leg->SetFillColor(0);
  leg->AddEntry(S1,"WW","f");
  leg->AddEntry(S12,"WZ","f");
  leg->AddEntry(S123,"ZZ","f");
  leg->AddEntry(S1234,"t #bar{t}","f");
  leg->AddEntry(S12345,"Zbb","f");
  leg->AddEntry(S123456,"Zcc","f");
  leg->AddEntry(S1234567,"ZJets","f");
  leg->AddEntry(S12345678,("H"+masspoint).c_str(),"f");
  //leg->AddEntry(S12345678,"H250 ","f");
  //leg->AddEntry(S12345678,"H500 ","f");
  //leg->AddEntry( var_data_Sumch,"data ","P");
  leg->AddEntry(data_Mu,"data ","P");

  float ymax_histosum = S12345678->GetMaximum();
  float ymax_data = data_Mu->GetMaximum();


  var_All500->SetMinimum(0.00001);
  if(ymax_histosum > ymax_data) var_All500->SetMaximum(ymax_histosum+ymax);
  else var_All500->SetMaximum(ymax_data+ymax);

  var_All500->SetTitle("");

  //  if(this_selection == muChannel)  var_All500->SetTitle("MuonChannel");
  //  if(this_selection == elChannel)  var_All500->SetTitle("ElectronChannel");


  if(this_selection == muChannel)  var_All500->GetXaxis()->SetTitle((label+" (#mu^{+} #mu^{-} channel)").c_str());
  if(this_selection == elChannel)  var_All500->GetXaxis()->SetTitle((label+" (e^{+} e^{-} channel)").c_str());

  float Xmin = var_h500->GetXaxis()->GetXmin();
  float Xmax = var_h500->GetXaxis()->GetXmax();

  float nEvts = (Xmax-Xmin)/n;
  cout<<"events"<<nEvts<<endl;
  //string Ylabel = "number of events/"+nEvts.str()+" GeV"
  var_All500->GetYaxis()->SetTitle(Form("number of events/ %.0f GeV",nEvts));
  if(custom) var_All500->GetXaxis()->SetRangeUser(rMin,rMax);
  //var_data->SetMarkerStyle(21);

  var_All500->Draw();
  S12345678->Draw("HISTsame");
  S1234567->Draw("HISTsame");
  S123456->Draw("HISTsame");
  S12345->Draw("HISTsame");
  S1234->Draw("HISTsame");
  S123->Draw("HISTsame");
  S12->Draw("HISTsame");
  S1->Draw("HISTsame");
  zllmass->Draw("HISTsame");
  data_Mu->Draw("*same");

  if(set_logScale){
    c1->SetLogy();
    var_All500->SetMinimum(1.);
  }
  leg->Draw("SAME");
  // t->Draw();


    TLatex latex;
    latex.SetNDC();
    latex.SetTextSize(0.04);

    latex.SetTextAlign(31); // align right
    //    latex.DrawLatex(0.65,0.90,"#sqrt{s} = 7 TeV");
    if (intLumi > 0.) {
      latex.SetTextAlign(31); // align right
      //      latex.DrawLatex(0.24,0.80,Form("#int #font[12]{L} dt = %.0f nb^{-1}",intLumi));
    }
    latex.SetTextAlign(11); // align left
    latex.DrawLatex(0.12, 0.92, "CMS preliminary 2011");
    latex.DrawLatex(0.45,0.92,Form("%.0f pb^{-1} at #sqrt{s} = 7 TeV",intLumi));

  c1->SaveAs(name_eps.c_str());


  }

}
Beispiel #2
0
void plot(string runPeriod = "A", string var = "zllmass",  string label="m_{ll}", int rebin_fact = 1, float ymax = 50., bool set_logScale=false, bool custom = false, bool drawSig = false, string masspoint="500", bool drawSigStack = false, float lowcut = 70., float upcut = 110.){

  //  gROOT->Reset();

  gROOT->ProcessLine(".L tdrstyle.C");
  setTDRStyle();
  gROOT->SetStyle("tdrStyle");

  //  gROOT->SetStyle("Plain");

  enum selType{muChannel, elChannel};

  string output = masspoint;  
  //  int rebin_fact = 1;
  // set log scale for plots
  string lumi = "1 fb^{-1}";
  // set to true in order to set the range on the X axis

  // lumi for datat taking periods
  const float lumiA = 2132.6;
  const float lumiB = 2508.0;
    
  if(custom && var == "zllmass"){
    float rMin = 60.;
    float rMax = 120.;
  }
  if(custom && var == "npv"){
    float rMin = -0.5;
    float rMax = 24.5;
  }
  if(set_logScale) ymax = 1000.;
  string postfix  = "EdmNtp.root";
  ofstream f(("reports/"+output+var+".txt").c_str());
  float y_mu =200.;
  float y_el =200.;

  float x_mu = 50.;  
  float x_el = 50.;  
  int max = 100;
  int min = 800;
  float br_fact = 0.333;
  //float normFact = 1/1000;

  float intLumi = 1000.0;
  if(runPeriod == "A")
    intLumi = lumiA;
  else if(runPeriod == "B")
    intLumi = lumiB;
  else if(runPeriod == "All")
    intLumi = lumiA+lumiB;
  else
    cout << "Period not existent!!! Normalization set to 1 fb-1" << endl;
    
  float normFact = intLumi/1000.;

  //  if(this_selection == muChannel) 
  //    normFact *= 47531./46514.;
  //  if(this_selection == elChannel) 
  //    normFact *= 43508./40853.;

  float cut_value1f = 0.94 * atof(masspoint.c_str());
  float cut_value2f = 1.10 * atof(masspoint.c_str());
  if( (var!="lljjmass") && (var!="lljjmass_1btag") && (var!="lljjmass_0btag") ){
    cut_value1f = lowcut;
    cut_value2f = upcut;
  }

  f << "s.r. = [" << cut_value1f <<", " << cut_value2f << "]" << endl;
  f << endl;
  f.precision(4);

  // counters to store e+mu final yields  
  double integralSignalCombined(0), allSignalCombined(0);
  double integralDYCombined(0), allDYCombined(0);
  double integralTTCombined(0), allTTCombined(0);
  double integralZZCombined(0), allZZCombined(0);
  double integralWZCombined(0), allWZCombined(0);
  double integralWWCombined(0), allWWCombined(0);
  double integralDataCombined(0), allDataCombined(0);
  
  vector<int> thisSel;
  thisSel.push_back(muChannel);
  thisSel.push_back(elChannel);

  float scaleDYJets = 0.0840179;
  float scaleTT =0.0165;
  float scaleWZ =0.00863;
  float scaleZZ =0.002798;
  float scaleWW =0.0208;
  float scaleH200 =0.00074280;
  float scaleH250 =0.00052212;
  float scaleH300 =0.00039763;
  float scaleH350 =0.00037046;
  float scaleH400 =0.00027725;
  float scaleH450 =0.00017129;
  float scaleH500 =0.00011800;

  float scaleFactDYJets = scaleDYJets*normFact;
  float scaleFactTT =  scaleTT*normFact;
  float scaleFactWZ =  scaleWZ*normFact;
  float scaleFactZZ =  scaleZZ*normFact;
  float scaleFactWW =  scaleWW*normFact;
  float scaleFact200 =  scaleH200*normFact;
  float scaleFact250 =  scaleH250*normFact;
  float scaleFact300 =  scaleH300*normFact;
  float scaleFact350 =  scaleH350*normFact;
  float scaleFact400 =  scaleH400*normFact;
  float scaleFact450 =  scaleH450*normFact;
  float scaleFact500 =  scaleH500*normFact;
  
  for(int i=0; i<thisSel.size();++i){
    selType this_selection = thisSel[i];

    // INPUT DIR for the histo files
    string input_dir_base = "NoNorm_Mu/";
    if(this_selection == elChannel)
      input_dir_base = "NoNorm_El/";
    
    // OUTPUT DIR for the histo files
    string out_dir_base = "histos_Mu/";
    if(this_selection == elChannel)
      out_dir_base = "histos_El/";

    // OUTPUT .png file
    string name = var+"_Lin_Mu.";
    if(set_logScale) name = var+"_Log_Mu.";
    if(this_selection == elChannel){
      name = var+"_Lin_El.";
      if(set_logScale) name= var+"_Log_El.";    
    }

    if(drawSigStack)
      name = masspoint+"_"+name;
      

  // Print on the screen what selection you are applying
    if(this_selection == muChannel){
      cout << "####################### COMBINING MU HISTOS ##########################" << endl << endl;
      //     TLatex *t= new TLatex(x_mu,y_mu,"CMS Preliminary   ");
    }


    if(this_selection == elChannel){
      cout << "##################### COMBINING ELECTRON HISTOS ######################" << endl << endl;
      //TLatex *t= new TLatex(x_el,y_el,"CMS Preliminary");
    }
  
    //    t->SetTextFont(72);
    // t->SetTextSize(0.06);

    string create_out_dir = "mkdir "+out_dir_base;
    gSystem->Exec( create_out_dir.c_str() );
    
  /*h250*/

    //    cout<<"get histos from file"<<endl;
  /*h300*/
  string infile_name = input_dir_base+masspoint+postfix;
  TFile f_h500(infile_name.c_str());
  TH1F * var_h500_Raw = (TH1F*) f_h500.Get(var.c_str());
  TH1F * var_h500 = new TH1F(*var_h500_Raw);
  if(masspoint=="200") var_h500->Scale(scaleFact200);
  else if(masspoint=="250") var_h500->Scale(scaleFact250);
  else if(masspoint=="300") var_h500->Scale(scaleFact300);
  else if(masspoint=="350") var_h500->Scale(scaleFact350);
  else if(masspoint=="400") var_h500->Scale(scaleFact400);
  else if(masspoint=="450") var_h500->Scale(scaleFact450);
  else if(masspoint=="500") var_h500->Scale(scaleFact500);

  TH1F * var_All500 = new TH1F(*var_h500_Raw);
  var_All500->Reset();

  infile_name = input_dir_base+"TT"+postfix;
  TFile f_tt(infile_name.c_str());
  TH1F * var_TT_Raw = (TH1F*) f_tt.Get(var.c_str());

  TH1F * var_TT = new TH1F(*var_TT_Raw);
  var_TT->Scale(scaleFactTT);
  //cout << "TT raw entries " << var_TT_Raw->Integral() << endl;
  //cout << "---> TT 1 fb entries " << var_TT->Integral() << endl;


  infile_name = input_dir_base+"ZZ"+postfix;
  TFile f_zz(infile_name.c_str());
  TH1F * var_ZZ_Raw = (TH1F*) f_zz.Get(var.c_str());
  TH1F * var_ZZ = new TH1F(*var_ZZ_Raw);
  var_ZZ->Scale(scaleFactZZ);
  //cout << "ZZ raw entries " << var_ZZ_Raw->Integral() << endl;
  //cout << "---> ZZ 1 fb entries " << var_ZZ->Integral() << endl;

  infile_name = input_dir_base+"WZ"+postfix;
  TFile f_wz(infile_name.c_str());
  TH1F * var_WZ_Raw = (TH1F*) f_wz.Get(var.c_str());
  TH1F * var_WZ = new TH1F(*var_WZ_Raw);
  var_WZ->Scale(scaleFactWZ);
  //cout << "WZ raw entries " << var_WZ_Raw->Integral() << endl;
  //cout << "---> WZ 1 fb entries " << var_WZ->Integral() << endl;

  infile_name = input_dir_base+"WW"+postfix;
  TFile f_ww(infile_name.c_str());
  TH1F * var_WW_Raw = (TH1F*) f_ww.Get(var.c_str());
  TH1F * var_WW = new TH1F(*var_WW_Raw);
  var_WW->Scale(scaleFactWW);
  //cout << "WW raw entries " << var_WW_Raw->Integral() << endl;
  //cout << "---> WW 1 fb entries " << var_WW->Integral() << endl;


  infile_name = input_dir_base+"DYJets_Summ11"+postfix;
  TFile f_dyjets(infile_name.c_str());
  TH1F * var_DYJets_Raw = (TH1F*) f_dyjets.Get(var.c_str());
  TH1F * var_DYJets = new TH1F(*var_DYJets_Raw);
  var_DYJets->Scale(scaleFactDYJets);

  if(this_selection == muChannel){
    infile_name = input_dir_base+"MuRun2011"+runPeriod+postfix;
  }
  if(this_selection == elChannel){
    infile_name = input_dir_base+"ElRun2011"+runPeriod+postfix;
  }
  TFile f_dataMu(infile_name.c_str());
  TH1F * data_Mu = (TH1F*) f_dataMu.Get(var.c_str());
  //  TFile f_dataEl(infile_name.c_str());
  //  TH1F * data_El = (TH1F*) f_dataEl.Get(var.c_str());
  //  data_Mu->Add(data_El);
  //  cout<<"data"<<endl;


  // getting integrals in signal region
  double integralSignal = integralInRange(var_h500, cut_value1f, cut_value2f);
  double integralDY = integralInRange(var_DYJets, cut_value1f, cut_value2f);
  double integralTT = integralInRange(var_TT, cut_value1f, cut_value2f);
  double integralZZ = integralInRange(var_ZZ, cut_value1f, cut_value2f);
  double integralWZ = integralInRange(var_WZ, cut_value1f, cut_value2f);
  double integralWW = integralInRange(var_WW, cut_value1f, cut_value2f);
  double integralBkg = integralDY + integralTT + integralZZ + integralWZ + integralWW;
  double integralData = integralInRange(data_Mu, cut_value1f, cut_value2f);

  double allSignal = var_h500->Integral();
  double allDY = var_DYJets->Integral();
  double allTT = var_TT->Integral();
  double allZZ = var_ZZ->Integral();
  double allWZ = var_WZ->Integral();
  double allWW = var_WW->Integral();
  double allBkg = allDY + allTT + allZZ + allWZ + allWW;
  double allData = data_Mu->Integral();

  integralSignalCombined += integralSignal;
  integralDYCombined += integralDY;
  integralTTCombined += integralTT;
  integralZZCombined += integralZZ;
  integralWZCombined += integralWZ;
  integralWWCombined += integralWW;
  integralDataCombined += integralData;
  allSignalCombined += allSignal;
  allDYCombined += allDY;
  allTTCombined += allTT;
  allZZCombined += allZZ;
  allWZCombined += allWZ;
  allWWCombined += allWW;
  allDataCombined += allData;

  cout.precision(5);
  cout << "Signal region = [" << cut_value1f <<", " << cut_value2f << "]" << endl;
  cout << "sample" << "\t" << "s.r." << "\t" << "all" << endl;
  cout << "DY" << "\t" << integralDY << "\t" << allDY << endl;
  cout << "TT" << "\t" << integralTT << "\t" << allTT << endl;
  cout << "ZZ" << "\t" << integralZZ << "\t" << allZZ << endl;
  cout << "WZ" << "\t" << integralWZ << "\t" << allWZ << endl;
  cout << "WW" << "\t" << integralWW << "\t" << allWW << endl;
  cout << "AllBkg" << "\t" << integralBkg << "\t" << allBkg << endl;
  cout << masspoint << "\t" << integralSignal << "\t" << allSignal << endl;
  cout << "data" << "\t" << integralData << "\t" << allData << endl;

  if(this_selection == elChannel)  f<<"Electron Channel, "<< intLumi << "pb-1" << endl;
  if(this_selection == muChannel)  f<<"Muon Channel, "<< intLumi << "pb-1" <<endl;        
  f << "\t" << "s.r." << "\t" << "all" << endl;
  f.precision(5);
  f << "DY" << "\t" << integralDY << "\t" << allDY << endl;
  f << "TT" << "\t" << integralTT << "\t" << allTT << endl;
  f << "ZZ" << "\t" << integralZZ << "\t" << allZZ << endl;
  f << "WZ" << "\t" << integralWZ << "\t" << allWZ << endl;
  f << "WW" << "\t" << integralWW << "\t" << allWW << endl;
  f << "AllBkg" << "\t" << integralBkg << "\t" << allBkg << endl;
  f << masspoint << "\t" << integralSignal << "\t" << allSignal << endl;
  f << "data" << "\t" << integralData << "\t" << allData << endl;
  f << endl;
  
  // Eventually REBIN:
  if(rebin_fact > 1){    
    //var_All250->Rebin(rebin_fact);
    //var_All300->Rebin(rebin_fact);
    var_All500->Rebin(rebin_fact);
    var_WW->Rebin(rebin_fact); 
    var_WZ->Rebin(rebin_fact); 
    var_TT->Rebin(rebin_fact); 
    //    var_ZCC->Rebin(rebin_fact); 
    //    var_ZBB->Rebin(rebin_fact); 
    //    var_ZJET->Rebin(rebin_fact); 
    var_ZZ->Rebin(rebin_fact); 
    var_DYJets->Rebin(rebin_fact);
    //var_h250->Rebin(rebin_fact); 
    //var_h300->Rebin(rebin_fact); 
    var_h500->Rebin(rebin_fact); 
    data_Mu->Rebin(rebin_fact);
  }


  int n = var_h500->GetNbinsX();
  min = var_h500->GetXaxis()->GetXmin();
  max = var_h500->GetXaxis()->GetXmax();
  //  cout<<"min and max: "<<min<<" "<<max<<endl;
  //    cout<<"nBin: "<<n<<endl;
  float binsize = (max - min)/n;
    
  //  int bincut1 = (cut_value1 -min )/binsize +1;
  //  int bincut2 = (cut_value2 -min) /binsize +1;
  //  cout<<"bin cut "<<bincut1<<" --> "<<var_h500->GetBinCenter(bincut1)<<endl;
  //  cout<<"bin cut "<<bincut2<<" --> "<<var_h500->GetBinCenter(bincut2)<<endl;
    
  //  TH1F * S0 = new TH1F("S0","H mass",nbins,min,max);
  //  S0->SetMinimum(minimum);
  //  S0->SetMaximum(maximum);
  //  S0->SetTitle(var.c_str());

  // sum histos for stack plot
  TH1F * S1 = new TH1F(* var_WW);
  TH1F * S12 = new TH1F(* S1);
  S12->Add(var_WZ);
  TH1F * S123 = new TH1F(* S12);
  S123->Add(var_ZZ);
  TH1F * S1234 = new TH1F(* S123);
  S1234->Add(var_TT);
  /*
    TH1F * S12345 = new TH1F(* S1234);
    S12345->Add(var_ZBB);
    TH1F * S123456 = new TH1F(* S12345);
    S123456->Add(var_ZJET);
  */
  TH1F * S12345 = new TH1F(* S1234);
  S12345->Add(var_DYJets);
  TH1F * S123456 = new TH1F(* S12345);
  //  var_h500->Scale(10);
  S123456->Add(var_h500);


  // write data histo, stack histo and single histos into the output file

  TH1F *data = new TH1F("data","data", var_h500->GetNbinsX(), 100, 1000);
  data->SetName("data_obs");
  data->SetTitle("data_obs");

  
  if(this_selection == muChannel)  string outfile_name = out_dir_base+"Histo_"+masspoint+"_mu.root";
  if(this_selection == elChannel)  string outfile_name = out_dir_base+"Histo_"+masspoint+"_el.root";
  TFile outfile(outfile_name.c_str(), "RECREATE");
  //var_data->Write();

  data_Mu->SetMarkerStyle(22);
  /*
  data_Mu->SetMarkerStyle(22);
  data_Mu->Write();
  S123456->SetName("data_obs");
  S123456->Write();
  //  data->SetName("data_obs");
  var_WZ->SetName("WZtoany");
  var_WZ->Write();
  var_WW->SetName("WWtoany");
  var_WW->Write();
  var_TT->SetName("ttbar2L2Nu2B");
  var_TT->Write();
  var_ZBB->SetName("zbbbar");
  var_ZBB->Write();
  var_ZCC->SetName("zccbar");
  var_ZCC->Write();
  var_ZJET->SetName("zjets");
  var_ZJET->Write();
  var_ZZ->SetName("ZZtoany");
  var_ZZ->Write();
  //var_h250->Write();
  //var_h500->Write();
  var_h500->SetName("higgs");
  var_h500->Write();
  outfile.Close();

  */

  // Draw stack plot into an .png file


  //  S1234567->SetStats(kFALSE);
  S123456->SetStats(kFALSE);
  S12345->SetStats(kFALSE);
  S1234->SetStats(kFALSE);
  S123->SetStats(kFALSE);
  S12->SetStats(kFALSE);
  S1->SetStats(kFALSE);


  //  S1234567->SetLineWidth(2);
  S123456->SetLineWidth(2);
  S12345->SetLineWidth(2);
  S1234->SetLineWidth(2);
  S123->SetLineWidth(2);
  S12->SetLineWidth(2);
  S1->SetLineWidth(2);

  S1->SetFillColor(kYellow-7);
 //    S1->SetLineColor(kMagenta+4);
  S12->SetFillColor(kMagenta -3);
 //    S12->SetLineColor(kTeal+3);
  S123->SetFillColor(kTeal-5);
 //    S123->SetLineColor(kViolet+3);
  S1234->SetFillColor(kMagenta +3);
 //    S1234->SetLineColor(kPink-7);
  //  S12345->SetFillColor(kViolet+4);
 //    S12345->SetLineColor(kOrange+8);
  S12345->SetFillColor(kOrange-2);
  S123456->SetFillColor(kOrange+7);
  //  S123456->SetLineColor(kPink+3);


  //  TH1F * S1234567 = new TH1F(* S123456);
  //  S1234567->Add(h_svbf500);
  //  TH1F * S12345678 = new TH1F(* S1234567);
  //  S12345678->Add(h_svbf450);
 
  //  pad1 = new TPad("pad","This is pad1",0.02,0.02,0.48,0.83,33);
  //  pad1->Draw();

  leg = new TLegend(.68,.67,0.94,0.94);
  leg->SetFillColor(0);
  leg->SetTextSize(0.040);
  leg->AddEntry(S1,"WW","f");
  leg->AddEntry(S12,"WZ","f");
  leg->AddEntry(S123,"ZZ","f");
  leg->AddEntry(S1234,"t #bar{t}","f");
  //  leg->AddEntry(S12345,"Zbb","f");
  leg->AddEntry(S12345,"DY Jets","f");
  //  leg->AddEntry(S123456,("H"+masspoint).c_str(),"f");
  //leg->AddEntry(S12345678,"H250 ","f");
  //leg->AddEntry(S12345678,"H500 ","f");
  //leg->AddEntry( var_data_Sumch,"data ","P");
  if(drawSig==true)  leg->AddEntry(var_h500,("H"+masspoint+" x 20").c_str(),"l");
  if(drawSigStack==true) leg->AddEntry(S123456,("H"+masspoint+"").c_str(),"f");
  leg->AddEntry(data_Mu,"data ","P");

  float ymax_histosum = S123456->GetMaximum();
  float ymax_data = data_Mu->GetMaximum();


  var_All500->SetMinimum(0.00001);
  if(ymax_histosum > ymax_data) var_All500->SetMaximum(ymax_histosum+ymax);
  else var_All500->SetMaximum(ymax_data+ymax);

  var_All500->SetTitle("");

  //  if(this_selection == muChannel)  var_All500->SetTitle("MuonChannel");
  //  if(this_selection == elChannel)  var_All500->SetTitle("ElectronChannel");


  if(this_selection == muChannel)  var_All500->GetXaxis()->SetTitle((label+" (#mu^{+} #mu^{-} channel)").c_str());
  if(this_selection == elChannel)  var_All500->GetXaxis()->SetTitle((label+" (e^{+} e^{-} channel)").c_str());

  float Xmin = var_h500->GetXaxis()->GetXmin();
  float Xmax = var_h500->GetXaxis()->GetXmax();

  float nEvts = (Xmax-Xmin)/n;

  //string Ylabel = "number of events/"+nEvts.str()+" GeV"

  var_All500->GetYaxis()->SetTitleOffset(1.5);
  var_All500->GetYaxis()->SetTitleSize(0.05);
  var_All500->GetYaxis()->SetLabelSize(0.045);
  var_All500->GetXaxis()->SetTitleSize(0.05);
  var_All500->GetXaxis()->SetLabelSize(0.040);

  var_All500->GetYaxis()->SetTitle(Form("number of events/ %.2f GeV",nEvts));
  //var_All500->GetYaxis()->SetTitle(Form("number of events/ %.2f ",nEvts));
  if(custom) var_All500->GetXaxis()->SetRangeUser(rMin,rMax);
  //var_data->SetMarkerStyle(21);

  var_h500->SetLineColor(kOrange+7);
  var_h500->SetLineWidth(3);
  //  var_h500->Scale(200);
  var_h500->Scale(20.);

  var_All500->Draw();
  //  S1234567->Draw("HISTsame");

  if(drawSigStack)  S123456->Draw("HISTsame");
  S12345->Draw("HISTsame");
  S1234->Draw("HISTsame");
  S123->Draw("HISTsame");
  S12->Draw("HISTsame");
  S1->Draw("HISTsame");
  if(drawSig==true)  var_h500->Draw("HISTsame");
  data_Mu->Draw("*same");


  if(set_logScale){
    c1->SetLogy();
    var_All500->SetMinimum(1.);
  }
  leg->Draw("SAME");
  // t->Draw();


  gPad->RedrawAxis();

  TLatex latex;
  latex.SetNDC();
  latex.SetTextSize(0.04);
  
  latex.SetTextAlign(31); // align right
  //    latex.DrawLatex(0.65,0.90,"#sqrt{s} = 7 TeV");
  if (intLumi > 0.) {
    latex.SetTextAlign(31); // align right
    //      latex.DrawLatex(0.24,0.80,Form("#int #font[12]{L} dt = %.0f nb^{-1}",intLumi));
  }
  latex.SetTextAlign(11); // align left
  latex.DrawLatex(0.17, 0.96, "CMS preliminary 2011");
  latex.DrawLatex(0.57,0.96,Form("%.0f pb^{-1} at #sqrt{s} = 7 TeV",intLumi));

  c1->SaveAs(("plots/"+name+"eps").c_str());
  c1->SaveAs(("plots/"+name+"png").c_str());
  
  }

  f<<"Total yields, "<< intLumi << "pb-1" << endl;
  f << "\t" << "s.r." << "\t" << "all" << endl;
  f << "DY" << "\t" << integralDYCombined << "\t" << allDYCombined << endl;
  f << "TT" << "\t" << integralTTCombined << "\t" << allTTCombined << endl;
  f << "ZZ" << "\t" << integralZZCombined << "\t" << allZZCombined << endl;
  f << "WZ" << "\t" << integralWZCombined << "\t" << allWZCombined << endl;
  f << "WW" << "\t" << integralWWCombined << "\t" << allWWCombined << endl;
  f << "AllBkg" << "\t" << integralDYCombined+integralTTCombined+integralZZCombined+integralWZCombined+integralWWCombined; 
  f  << "\t" << allDYCombined+allTTCombined+allZZCombined+allWZCombined+allWWCombined << endl;
  f << masspoint << "\t" << integralSignalCombined << "\t" << allSignalCombined << endl;
  f << "data" << "\t" << integralDataCombined << "\t" << allDataCombined << endl;

  f.close();
  gApplication->Terminate();
  
}
// Modified version of the all purpose routine L2Project specifically written
// for projecting the "time-averaged" flux function onto the basis function.
//
// This routine also returns the coefficients of the Lax Wendroff Flux
// Function when expanded with legendre basis functions, and therefore the
// basis expansions produced by this routine can be used for all of the
// Riemann solves.
//
// ---------------------------------------------------------------------
// Inputs should have the following sizes:   
//           TODO - document the inputs here
// ---------------------------------------------------------------------
void L2ProjectLxW_Unst( const int mterms,
        const double alpha, const double beta_dt, const double charlie_dt,
        const int istart, const int iend,               // Start-stop indices
        const int QuadOrder,
        const int BasisOrder_qin,
        const int BasisOrder_auxin,
        const int BasisOrder_fout,
        const mesh& Mesh, 
        const dTensor3* qin, const dTensor3* auxin,     // state vector
        dTensor3* F, dTensor3* G,                       // time-averaged Flux function
        void FluxFunc (const dTensor2& xpts, 
            const dTensor2& Q, const dTensor2& Aux, dTensor3& flux),
        void DFluxFunc (const dTensor2& xpts, 
            const dTensor2& Q, const dTensor2& aux, dTensor4& Dflux),
        void D2FluxFunc (const dTensor2& xpts, 
            const dTensor2& Q, const dTensor2& aux, dTensor5& D2flux) )
{    

    if( fabs( alpha ) < 1e-14 && fabs( beta_dt ) < 1e-14 && fabs( charlie_dt ) < 1e-14 )
    {
        F->setall(0.);
        G->setall(0.);
        return;
    }

    // starting and ending indices 
    const int   NumElems = Mesh.get_NumElems();
    assert_ge(istart,1);
    assert_le(iend,NumElems);

    // qin variable
    assert_eq(NumElems,qin->getsize(1));
    const int     meqn = qin->getsize(2);
    const int kmax_qin = qin->getsize(3);
    assert_eq(kmax_qin,(BasisOrder_qin*(BasisOrder_qin+1))/2);

    // auxin variable
    assert_eq(NumElems,auxin->getsize(1));
    const int       maux = auxin->getsize(2);
    const int kmax_auxin = auxin->getsize(3);
    assert_eq(kmax_auxin,(BasisOrder_auxin*(BasisOrder_auxin+1))/2);

    // fout variables
    assert_eq(NumElems,    F->getsize(1));
    const int mcomps_out = F->getsize(2);
    const int  kmax_fout = F->getsize(3);
    assert_eq(kmax_fout, (BasisOrder_fout*(BasisOrder_fout+1))/2 );

    // number of quadrature points
    assert_ge(QuadOrder, 1);
    assert_le(QuadOrder, 5);

    // Number of quadrature points
    int mpoints;
    switch( QuadOrder )
    {
        case 1:
            mpoints = 1;
            break;

        case 2:
            mpoints = 3;
            break;

        case 3:
            mpoints = 6;
            break;

        case 4:
            mpoints = 12;
            break;

        case 5:	     
            mpoints = 16;
            break;
    }

    const int kmax = iMax(iMax(kmax_qin, kmax_auxin), kmax_fout);
    dTensor2  phi(mpoints, kmax); // Legendre basis (orthogonal)
    dTensor2 spts(mpoints, 2);    // List of quadrature points
    dTensor1 wgts(mpoints);       // List of quadrature weights

    setQuadPoints_Unst( QuadOrder, wgts, spts );

    // ---------------------------------------------------------------------- //
    // Evaluate the basis functions at each point
    SetLegendreAtPoints_Unst(spts, phi);
    // ---------------------------------------------------------------------- //

    // ---------------------------------------------------------------------- //
    // First-order derivatives
    dTensor2 phi_xi (mpoints, kmax );
    dTensor2 phi_eta(mpoints, kmax );
    SetLegendreGrad_Unst( spts, phi_xi, phi_eta );
    // ---------------------------------------------------------------------- //

    // ---------------------------------------------------------------------- //
    // Second-order derivatives
    dTensor2 phi_xi2  (mpoints, kmax );
    dTensor2 phi_xieta(mpoints, kmax );
    dTensor2 phi_eta2 (mpoints, kmax );
    LegendreDiff2_Unst(spts, &phi_xi2, &phi_xieta, &phi_eta2 );
    // ---------------------------------------------------------------------- //

    // ------------------------------------------------------------- //
    // Loop over every grid cell indexed by user supplied parameters //
    // described by istart...iend, jstart...jend                     // 
    // ------------------------------------------------------------- //
#pragma omp parallel for
    for (int i=istart; i<=iend; i++)
    {

        // These need to be defined locally.  Each mesh element carries its
        // own change of basis matrix, so these need to be recomputed for
        // each element.  The canonical derivatives, phi_xi, and phi_eta can
        // be computed and shared for each element.

        // First-order derivatives
        dTensor2   phi_x(mpoints, kmax_fout);   //   x-derivative of Legendre basis (orthogonal)
        dTensor2   phi_y(mpoints, kmax_fout);   //   y-derivative of Legendre basis (orthogonal)

        // Second-order derivatives
        dTensor2   phi_xx(mpoints, kmax_fout);   //   xx-derivative of Legendre basis (orthogonal)
        dTensor2   phi_xy(mpoints, kmax_fout);   //   xy-derivative of Legendre basis (orthogonal)
        dTensor2   phi_yy(mpoints, kmax_fout);   //   yy-derivative of Legendre basis (orthogonal)

        //find center of current cell
        const int    i1 = Mesh.get_tnode(i,1);
        const int    i2 = Mesh.get_tnode(i,2);
        const int    i3 = Mesh.get_tnode(i,3);

        // Corners:
        const double x1 = Mesh.get_node(i1,1);
        const double y1 = Mesh.get_node(i1,2);
        const double x2 = Mesh.get_node(i2,1);
        const double y2 = Mesh.get_node(i2,2);
        const double x3 = Mesh.get_node(i3,1);
        const double y3 = Mesh.get_node(i3,2);

        // Center of current cell:
        const double xc = (x1+x2+x3)/3.0;
        const double yc = (y1+y2+y3)/3.0;

        // Variables that need to be written to, and therefore are 
        // created for each thread
        dTensor2 xpts   (mpoints, 2);
        dTensor2 qvals  (mpoints, meqn);
        dTensor2 auxvals(mpoints, maux);

        // local storage for Flux function its Jacobian, and the Hessian:
        dTensor3    fvals(mpoints,             meqn, 2);  // flux function (vector)
        dTensor4        A(mpoints,       meqn, meqn, 2);  // Jacobian of flux
        dTensor5        H(mpoints, meqn, meqn, meqn, 2);  // Hessian of flux

        // Compute q, aux and fvals at each Gaussian Quadrature point
        // for this current cell indexed by (i,j)
        // Save results into dTensor2 qvals, auxvals and fvals.
        for (int m=1; m<= mpoints; m++)
        {

            // convert phi_xi and phi_eta derivatives
            // to phi_x and phi_y derivatives through Jacobian
            //
            // Note that: 
            //
            //     pd_x = J11 pd_xi + J12 pd_eta and
            //     pd_y = J21 pd_xi + J22 pd_eta.
            //
            // Squaring these operators yields the second derivatives.
            for (int k=1; k<=kmax_fout; k++)
            {
                phi_x.set(m,k, Mesh.get_jmat(i,1,1)*phi_xi.get(m,k)
                             + Mesh.get_jmat(i,1,2)*phi_eta.get(m,k) );
                phi_y.set(m,k, Mesh.get_jmat(i,2,1)*phi_xi.get(m,k)
                             + Mesh.get_jmat(i,2,2)*phi_eta.get(m,k) );

                phi_xx.set(m,k, Mesh.get_jmat(i,1,1)*Mesh.get_jmat(i,1,1)*phi_xi2.get(m,k)
                              + Mesh.get_jmat(i,1,1)*Mesh.get_jmat(i,1,2)*phi_xieta.get(m,k)
                              + Mesh.get_jmat(i,1,2)*Mesh.get_jmat(i,1,2)*phi_eta2.get(m,k)
                           );

                phi_xy.set(m,k, Mesh.get_jmat(i,1,1)*Mesh.get_jmat(i,2,1)*phi_xi2.get(m,k)
                             +(Mesh.get_jmat(i,1,2)*Mesh.get_jmat(i,2,1)
                             + Mesh.get_jmat(i,1,1)*Mesh.get_jmat(i,2,2))*phi_xieta.get(m,k)
                             + Mesh.get_jmat(i,1,2)*Mesh.get_jmat(i,2,2)*phi_eta2.get(m,k)
                           );

                phi_yy.set(m,k, Mesh.get_jmat(i,2,1)*Mesh.get_jmat(i,2,1)*phi_xi2.get(m,k)
                              + Mesh.get_jmat(i,2,1)*Mesh.get_jmat(i,2,2)*phi_xieta.get(m,k)
                              + Mesh.get_jmat(i,2,2)*Mesh.get_jmat(i,2,2)*phi_eta2.get(m,k)
                           );
            }

            // point on the unit triangle
            const double s = spts.get(m,1);
            const double t = spts.get(m,2);

            // point on the physical triangle
            xpts.set(m,1, xc + (x2-x1)*s + (x3-x1)*t );
            xpts.set(m,2, yc + (y2-y1)*s + (y3-y1)*t );

            // Solution values (q) at each grid point
            for (int me=1; me<=meqn; me++)
            {
                qvals.set(m,me, 0.0 );
                for (int k=1; k<=kmax_qin; k++)
                {
                    qvals.set(m,me, qvals.get(m,me) 
                            + phi.get(m,k) * qin->get(i,me,k) );
                }
            }

            // Auxiliary values (aux) at each grid point
            for (int ma=1; ma<=maux; ma++)
            {
                auxvals.set(m,ma, 0.0 );
                for (int k=1; k<=kmax_auxin; k++)
                {
                    auxvals.set(m,ma, auxvals.get(m,ma) 
                            + phi.get(m,k) * auxin->get(i,ma,k) );
                }
            } 
        }

        // ----------------------------------------------------------------- //
        //
        // Part I:
        //
        // Project the flux function onto the basis 
        // functions.  This is the term of order O( 1 ) in the
        // "time-averaged" Taylor expansion of f and g.
        //
        // ----------------------------------------------------------------- //

        // Call user-supplied function to set fvals
        FluxFunc(xpts, qvals, auxvals, fvals);

        // Evaluate integral on current cell (project onto Legendre basis) 
        // using Gaussian Quadrature for the integration
        //
        // TODO - do we want to optimize this by looking into using transposes,
        // as has been done in the 2d/cart code? (5/14/2014) -DS
        for (int me=1; me<=mcomps_out; me++)		
        for (int k=1; k<=kmax; k++)
        {
            double tmp1 = 0.0;
            double tmp2 = 0.0;
            for (int mp=1; mp <= mpoints; mp++)
            {
                tmp1 += wgts.get(mp)*fvals.get(mp, me, 1)*phi.get(mp, k);
                tmp2 += wgts.get(mp)*fvals.get(mp, me, 2)*phi.get(mp, k);
            }
            F->set(i, me, k,  2.0*tmp1 );
            G->set(i, me, k,  2.0*tmp2 );
        }

        // ----------------------------------------------------------------- //
        //
        // Part II:
        //
        // Project the derivative of the flux function onto the basis 
        // functions.  This is the term of order O( \dt ) in the
        // "time-averaged" Taylor expansion of f and g.
        //
        // ----------------------------------------------------------------- //

        // ----------------------------------------------------------------- //
        // Compute pointwise values for fx+gy:
        //
        // We can't multiply fvals of f, and g,
        // by alpha, otherwise we compute the wrong derivative here!
        //
        dTensor2 fx_plus_gy( mpoints, meqn ); fx_plus_gy.setall(0.);
        for( int mp=1; mp <= mpoints; mp++ )
        for( int me=1; me <= meqn; me++ )
        {
            double tmp = 0.;
            for( int k=2; k <= kmax; k++ )                
            {
                tmp += F->get( i, me, k ) * phi_x.get( mp, k );
                tmp += G->get( i, me, k ) * phi_y.get( mp, k );
            }
            fx_plus_gy.set( mp, me, tmp );
        }

        // Call user-supplied Jacobian to set f'(q) and g'(q):
        DFluxFunc( xpts, qvals, auxvals, A );

        // place-holders for point values of
        // f'(q)( fx + gy ) and g'(q)( fx + gy ):
        dTensor2 dt_times_fdot( mpoints, meqn );
        dTensor2 dt_times_gdot( mpoints, meqn );

        // Compute point values for f'(q) * (fx+gy) and g'(q) * (fx+gy):
        for( int mp=1; mp <= mpoints; mp++ )
        for( int m1=1; m1 <= meqn; m1++ )
        {
            double tmp1 = 0.;
            double tmp2 = 0.;
            for( int m2=1; m2 <= meqn; m2++ )
            {
                tmp1 += A.get(mp, m1, m2, 1 ) * fx_plus_gy.get(mp, m2);
                tmp2 += A.get(mp, m1, m2, 2 ) * fx_plus_gy.get(mp, m2);
            }
            dt_times_fdot.set( mp, m1, -beta_dt*tmp1 );
            dt_times_gdot.set( mp, m1, -beta_dt*tmp2 );
        }

        // ---  Third-order terms --- //
        //
        // These are the terms that are O( \dt^2 ) in the "time-averaged"
        // flux function.
        dTensor2 f_tt( mpoints, meqn );   f_tt.setall(0.);
        dTensor2 g_tt( mpoints, meqn );   g_tt.setall(0.);
        if( mterms > 2 )
        {

            // Construct the Hessian at each (quadrature) point
            D2FluxFunc( xpts, qvals, auxvals, H );

            // Second-order derivative terms
            dTensor2 qx_vals (mpoints, meqn);   qx_vals.setall(0.);
            dTensor2 qy_vals (mpoints, meqn);   qy_vals.setall(0.);

            dTensor2 fxx_vals(mpoints, meqn);   fxx_vals.setall(0.);
            dTensor2 gxx_vals(mpoints, meqn);   gxx_vals.setall(0.);

            dTensor2 fxy_vals(mpoints, meqn);   fxy_vals.setall(0.);
            dTensor2 gxy_vals(mpoints, meqn);   gxy_vals.setall(0.);

            dTensor2 fyy_vals(mpoints, meqn);   fyy_vals.setall(0.);
            dTensor2 gyy_vals(mpoints, meqn);   gyy_vals.setall(0.);

            for( int m=1; m <= mpoints; m++ )
            for( int me=1; me <= meqn; me++ )
            {
                // Can start at k=1, because derivative of a constant is
                // zero.
                double tmp_qx = 0.;
                double tmp_qy = 0.;
                for( int  k=2; k <= kmax; k++   )
                {
                    tmp_qx += phi_x.get(m,k) * qin->get(i,me,k);
                    tmp_qy += phi_y.get(m,k) * qin->get(i,me,k);
                }
                qx_vals.set(m,me, tmp_qx );
                qy_vals.set(m,me, tmp_qy );

                // First non-zero terms start at third-order.
                for( int  k=4; k <= kmax; k++   )
                {
                    fxx_vals.set(m,me, fxx_vals.get(m,me) + phi_xx.get(m,k)*F->get(i,me,k) );
                    gxx_vals.set(m,me, gxx_vals.get(m,me) + phi_xx.get(m,k)*G->get(i,me,k) );

                    fxy_vals.set(m,me, fxy_vals.get(m,me) + phi_xy.get(m,k)*F->get(i,me,k) );
                    gxy_vals.set(m,me, gxy_vals.get(m,me) + phi_xy.get(m,k)*G->get(i,me,k) );

                    fyy_vals.set(m,me, fyy_vals.get(m,me) + phi_yy.get(m,k)*F->get(i,me,k) );
                    gyy_vals.set(m,me, gyy_vals.get(m,me) + phi_yy.get(m,k)*G->get(i,me,k) );
                }

            }

            // ----------------------------------- //
            // Part I: Compute (f_x + g_y)_{,t}
            // ----------------------------------- //

            // Compute terms that get multiplied by \pd2{ f }{ q } and \pd2{ g }{ q }.
            dTensor2 fx_plus_gy_t( mpoints, meqn );
            for( int  m = 1;  m <= mpoints; m++ )
            for( int me = 1; me <= meqn; me++   )
            {

                double tmp = 0.;

                // Terms that get multiplied by the Hessian:
                for( int m1=1; m1 <= meqn; m1++ )
                for( int m2=1; m2 <= meqn; m2++ )
                {

                    tmp += H.get(m,me,m1,m2,1)*qx_vals.get(m,m1)*fx_plus_gy.get(m,m2);
                    tmp += H.get(m,me,m1,m2,2)*qy_vals.get(m,m1)*fx_plus_gy.get(m,m2);
                }

                // Terms that get multiplied by f'(q) and g'(q):
                for( int m1=1; m1 <= meqn; m1++ )
                {

                    tmp += A.get(m,me,m1,1)*( fxx_vals.get(m,m1)+gxy_vals.get(m,m1) );
                    tmp += A.get(m,me,m1,2)*( fxy_vals.get(m,m1)+gyy_vals.get(m,m1) );
                }

                fx_plus_gy_t.set( m, me, tmp );
            }

            // ----------------------------------- //
            // Part II: Compute 
            //      f'(q) * fx_plus_gy_t and 
            //      g'(q) * fx_plus_gy_t
            // ----------------------------------- //

            // Add in the third term that gets multiplied by A:
            for( int m=1; m <= mpoints; m++ )
            for( int m1=1; m1 <= meqn; m1++ )
            {
                double tmp1 = 0.;
                double tmp2 = 0.;
                for( int m2=1; m2 <= meqn; m2++ )
                {
                    tmp1 += A.get(m,m1,m2,1)*fx_plus_gy_t.get(m,m2);
                    tmp2 += A.get(m,m1,m2,2)*fx_plus_gy_t.get(m,m2);
                }
                f_tt.set( m, m1, tmp1 );
                g_tt.set( m, m1, tmp2 );
            }

            // ----------------------------------------------- //
            // Part III: Add in contributions from
            //      f''(q) * (fx_plus_gy, fx_plus_gy ) and 
            //      g''(q) * (fx_plus_gy, fx_plus_gy ).
            // ----------------------------------------------- //
            for( int m =1; m <= mpoints; m++ )
            for( int me =1; me <= meqn; me++ )
            {
                double tmp1 = 0.;
                double tmp2 = 0.;

                // Terms that get multiplied by the Hessian:
                for( int m1=1; m1 <= meqn; m1++ )
                for( int m2=1; m2 <= meqn; m2++ )
                {
                    tmp1 += H.get(m,me,m1,m2,1)*fx_plus_gy.get(m,m1)*fx_plus_gy.get(m,m2);
                    tmp2 += H.get(m,me,m1,m2,2)*fx_plus_gy.get(m,m1)*fx_plus_gy.get(m,m2);
                }

                f_tt.set( m, me, f_tt.get(m,me) + tmp1 );
                g_tt.set( m, me, g_tt.get(m,me) + tmp2 );
            }

        } // End of computing "third"-order terms

        // ---------------------------------------------------------- //
        // 
        // Construct basis coefficients (integrate_on_current_cell)
        //
        // ---------------------------------------------------------- //
        for (int me=1; me<=mcomps_out; me++)		
        for (int k=1; k<=kmax; k++)
        {

            double tmp1 = 0.0;
            double tmp2 = 0.0;
            for (int mp=1; mp<=mpoints; mp++)
            {
                tmp1 += wgts.get(mp)*phi.get(mp,k)*(
                    dt_times_fdot.get(mp, me) + charlie_dt*f_tt.get(mp, me) );
                tmp2 += wgts.get(mp)*phi.get(mp,k)*(
                    dt_times_gdot.get(mp, me) + charlie_dt*g_tt.get(mp, me) );
            }
            F->set(i,me,k,  F->get(i,me,k) + 2.0*tmp1 );
            G->set(i,me,k,  G->get(i,me,k) + 2.0*tmp2 );

        }

    }

}