void backgroundEstimation::ImportMTTailCorrectionFromTemplateFitMethod()
{
    Table SFR_table = Table("../MTtailCorrection/results/SF_MTtail.tab");
    //Table SFR_table = Table("../MTtailCorrection/signalContamination/"+string(SIGNAL_CONTAMINATION_INPUT)+"/SF_MTtail.tab");

    // Remove low/medium/highDM suffix in label for BDT's
    string signalRegionLabel_ = signalRegionLabel;
    if (findSubstring(signalRegionLabel_,"BDT"))
    {
        size_t pos;
        pos = signalRegionLabel_.find("_low");
        if (pos != string::npos) signalRegionLabel_ = signalRegionLabel_.substr(0,pos);
        pos = signalRegionLabel_.find("_med");
        if (pos != string::npos) signalRegionLabel_ = signalRegionLabel_.substr(0,pos);
        pos = signalRegionLabel_.find("_high");
        if (pos != string::npos) signalRegionLabel_ = signalRegionLabel_.substr(0,pos);
    }

    SF_MTtail_Wjets = SFR_table.Get("SFR_Wjets",signalRegionLabel_);
    SF_MTtail_1ltop = SFR_table.Get("SFR_1ltop",signalRegionLabel_);

    // Fix for signal contamination crazy values : we assume that SFR_1ltop is >= 1.
    // We keep the same relative uncertainty
    if (SF_MTtail_1ltop.value() < 1) { SF_MTtail_1ltop = Figure(1.0,SF_MTtail_1ltop.value() / SF_MTtail_1ltop.error()); }

    if (SF_MTtail_Wjets_variation) SF_MTtail_Wjets.keepVariation(SF_MTtail_Wjets_variation,"noNegativeValue");
    if (SF_MTtail_1ltop_variation) SF_MTtail_1ltop.keepVariation(SF_MTtail_1ltop_variation,"noNegativeValue");
}
Ejemplo n.º 2
0
/**
 * @brief Constructor specifying an axes subplot spec and optional parent.
 * An Axes with the given subplot specification is created on construction
 * See
 * https://matplotlib.org/2.2.3/api/_as_gen/matplotlib.figure.Figure.html?highlight=add_subplot#matplotlib.figure.Figure.add_subplot
 * @param subplotspec A matplotlib subplot spec defined as a 3-digit integer
 * @param facecolor String denoting the figure's facecolor
 * @param parent The owning parent widget
 */
FigureCanvasQt::FigureCanvasQt(int subplotspec, QWidget *parent)
    : QWidget(parent), InstanceHolder(createPyCanvas(subplotspec), "draw"),
      m_figure(Figure(Python::Object(pyobj().attr("figure")))) {
  // Cannot use delegating constructor here as InstanceHolder needs to be
  // initialized before the axes can be created
  m_mplCanvas = initLayout(this);
}
float backgroundEstimation::ComputeSecondLeptonVetoUncertainty()
{
    Figure ttbar_2l_all                     = secondLeptonInAcceptanceYieldTable.Get("preveto_MTtail", "ttbar_2l");
    Figure ttbar_2l_withTrackInAcceptance   = secondLeptonInAcceptanceYieldTable.Get("singleTrack",         "ttbar_2l");
    Figure ttbar_2l_withHadrTauInAcceptance = secondLeptonInAcceptanceYieldTable.Get("hadronicTau",         "ttbar_2l");

    if (ttbar_2l_all.value() == 0) return 0.0;

    Figure fraction_track = ttbar_2l_withTrackInAcceptance   / ttbar_2l_all;
    Figure fraction_tau   = ttbar_2l_withHadrTauInAcceptance / ttbar_2l_all;

    if (fraction_track.value() < 0.02) fraction_track = Figure(0.02,0);
    if (fraction_tau.value()   < 0.02) fraction_tau   = Figure(0.02,0);

    float uncertainty = fraction_track.value() * ISOLATED_TRACK_VETO_UNCERTAINTY
                      + fraction_tau.value()   * TAU_VETO_UNCERTAINTY;

    return uncertainty;
}
Ejemplo n.º 4
0
/*
   Dibuja una lista de figuras en una imagen.

   Parámetros: 
      image	la imagen donde dibuja.
      list 	la lista de figuras que dibuja en la imagen.

*/
void drawList(IplImage* image, std::list<Figure> &list)
{
	std::list<Figure>::iterator pos;
	Figure temp = Figure(0,0,0);
	pos = list.begin();
	while(pos != list.end())
	{
			temp = *pos;
			temp.draw(image);
			pos++;
	}
}
void backgroundEstimation::FillPredictionTable()
{
    #ifdef USING_MT_TAIL_CORRECTION_FROM_TEMPLATE_FIT_METHOD
    Figure N1ltop_tail = rawYieldTable.Get("signalRegion_MTtail","1ltop"   ) * oneLepTopCrossSection_rescale;
    Figure Nwjets_tail = rawYieldTable.Get("signalRegion_MTtail","W+jets"  ) * WjetCrossSection_rescale;
    #else
    Figure N1ltop_peak = rawYieldTable.Get("signalRegion_MTpeak","1ltop"   );
    Figure Nwjets_peak = rawYieldTable.Get("signalRegion_MTpeak","W+jets"  ) * WjetCrossSection_rescale;
    #endif
    Figure N2ltop_tail = rawYieldTable.Get("signalRegion_MTtail","ttbar_2l") * ttll_CR4and5_rescale * ttll_nJets_rescale * ttll_2ndlepVeto_rescale;
    Figure Nrare_tail  = rawYieldTable.Get("signalRegion_MTtail","rare"    ) * rareCrossSection_rescale;

    // MC stat uncertainty
    #ifdef USING_MT_TAIL_CORRECTION_FROM_TEMPLATE_FIT_METHOD
    if (top1lStat_variation)   N1ltop_tail.keepVariation(top1lStat_variation,  "noNegativeValue");
    if (WjetsStat_variation)   Nwjets_tail.keepVariation(WjetsStat_variation,  "noNegativeValue");
    #else
    if (top1lStat_variation)   N1ltop_peak.keepVariation(top1lStat_variation,  "noNegativeValue");
    if (WjetsStat_variation)   Nwjets_peak.keepVariation(WjetsStat_variation,  "noNegativeValue");
    #endif
    if (ttbar2lStat_variation) N2ltop_tail.keepVariation(ttbar2lStat_variation,"noNegativeValue");
    if (rareStat_variation)    Nrare_tail .keepVariation(rareStat_variation,   "noNegativeValue");

    // To have cross section uncertainty in per-process prediction table
    #ifdef USING_MT_TAIL_CORRECTION_FROM_TEMPLATE_FIT_METHOD
    Nwjets_tail *= Figure(1.0, 0.5);
    #else
    Nwjets_peak *= Figure(1.0, 0.5);
    #endif
    Nrare_tail  *= Figure(1.0, 0.5);

    // To have the (temporary and arbitrary) numbers for tt->ll systematics in the per-process prediction table
    N2ltop_tail *= Figure(1.0,ttll_nJetsModelingUncertainty );
    N2ltop_tail *= Figure(1.0,ttll_CR4CR5ModelingUncertainty);
    N2ltop_tail *= Figure(1.0,ComputeSecondLeptonVetoUncertainty());

    // Prediction
    #ifdef USING_MT_TAIL_CORRECTION_FROM_TEMPLATE_FIT_METHOD
        Figure N1ltop_prediction  = N1ltop_tail  * SF_post * SF_MTtail_1ltop;
        Figure Nwjets_prediction  = Nwjets_tail  * SF_post * SF_MTtail_Wjets;
    #else
        Figure N1ltop_prediction  = N1ltop_peak  * SF_post * R_1ltop_mean;
        Figure Nwjets_prediction  = Nwjets_peak  * SF_post * R_Wjets_corrected;
    #endif
    Figure N2ltop_prediction  = N2ltop_tail  * SF_pre;
    Figure Nrare_prediction   = Nrare_tail;


    // Background sum
    Figure NSumBkg_prediction = N1ltop_prediction + N2ltop_prediction + Nwjets_prediction + Nrare_prediction;

    // Fill table
    predictionTable.Set("prediction","1ltop",    N1ltop_prediction  );
    predictionTable.Set("prediction","ttbar_2l", N2ltop_prediction  );
    predictionTable.Set("prediction","W+jets",   Nwjets_prediction  );
    predictionTable.Set("prediction","rare",     Nrare_prediction );
    predictionTable.Set("prediction","totalSM",  NSumBkg_prediction );
}
Ejemplo n.º 6
0
Figure find(int x, int y, std::list<Figure> &list)
{
		Figure temp = Figure(0,0,0);
		std::list<Figure>::iterator pos;
		pos = list.begin();
		while(pos != list.end())
		{
				temp = *pos;
				if(temp.selected(x,y))
				{
					list.erase(pos);
					return temp;
				}
				pos++;
		}
		temp.drawtype = '?';
		return temp;
}
void backgroundEstimation::ComputeMTTailToPeakRatioCorrectionMethod()
{
    Figure signalRegionPeak_1ltop    = rawYieldTable.Get("signalRegion_MTpeak","1ltop"   );
    Figure signalRegionPeak_ttbar_2l = rawYieldTable.Get("signalRegion_MTpeak","ttbar_2l");
    Figure signalRegionPeak_Wjets    = rawYieldTable.Get("signalRegion_MTpeak","W+jets"  ) * WjetCrossSection_rescale;
    Figure signalRegionPeak_rare     = rawYieldTable.Get("signalRegion_MTpeak","rare"    ) * rareCrossSection_rescale;
    Figure signalRegionPeak_data     = rawYieldTable.Get("signalRegion_MTpeak","data"    );

    Figure signalRegionTail_1ltop    = rawYieldTable.Get("signalRegion_MTtail","1ltop"   );
    Figure signalRegionTail_ttbar_2l = rawYieldTable.Get("signalRegion_MTtail","ttbar_2l");
    Figure signalRegionTail_Wjets    = rawYieldTable.Get("signalRegion_MTtail","W+jets"  ) * WjetCrossSection_rescale;
    Figure signalRegionTail_rare     = rawYieldTable.Get("signalRegion_MTtail","rare"    ) * rareCrossSection_rescale;
    Figure signalRegionTail_data     = rawYieldTable.Get("signalRegion_MTtail","data"    );

    Figure noBTagTail_1ltop          = rawYieldTable.Get("0btag_MTtail","1ltop"   );
    Figure noBTagTail_ttbar_2l       = rawYieldTable.Get("0btag_MTtail","ttbar_2l");
    Figure noBTagTail_Wjets          = rawYieldTable.Get("0btag_MTtail","W+jets"  ) * WjetCrossSection_rescale;
    Figure noBTagTail_rare           = rawYieldTable.Get("0btag_MTtail","rare"    ) * rareCrossSection_rescale;
    Figure noBTagTail_data           = rawYieldTable.Get("0btag_MTtail","data"    );

    R_Wjets_mc = (noBTagTail_Wjets + signalRegionTail_Wjets) / (noBTagPeak_Wjets + signalRegionPeak_Wjets);
    R_1ltop_mc = (noBTagTail_1ltop + signalRegionTail_1ltop) / (noBTagPeak_1ltop + signalRegionPeak_1ltop);

    SFR_all    = noBTagTail_data / ((noBTagTail_Wjets + noBTagTail_1ltop)*SF_0btag + noBTagTail_ttbar_2l + noBTagTail_rare);
    SFR_Wonly  = (noBTagTail_data - noBTagTail_1ltop*SF_0btag - noBTagTail_ttbar_2l - noBTagTail_rare) / (noBTagTail_Wjets*SF_0btag);

    SFR_Wjets_mean = Figure((SFR_all.value()+SFR_Wonly.value())/2.0 , (SFR_all.error() + SFR_Wonly.error())/2.0);

    if (SFR_Wjets_variation) SFR_W_mean.keepVariation(SFR_Wjets_variation,"noNegativeValue");

    R_Wjets_corrected  = R_Wjets_mc  * SFR_W_mean.value();
    R_1ltop_corrected = R_1ltop_mc * SFR_W_mean.value();

    // Old method :
    //  R_1ltop_mean = Figure((RW_corrected.value() + R_1ltop_corrected.value()) / 2.0, fabs(RW_corrected.value() - R_1ltop_corrected.value()) / 2.0);
    //
    // NB : We now take the ration R from MC without averaging
    //
    R_1ltop_mean = R_1ltop_corrected;

    if (tailToPeakRatio_1lTop_variation) R_1ltop_mean.keepVariation(tailToPeakRatio_1lTop_variation,"noNegativeValue");
}
Ejemplo n.º 8
0
int main()
{
	std::ifstream fin("04", std::ios_base::in);

	Coor size;
	fin >> size.ln >> size.col;
	fin.get();

	char ch;
	Figures figures;
	
	Coor start;
	for (int i = 0; i < size.ln; i++)
	{
		for (int j = 0; j < size.col; j++)
		{
			int val = 0;
			ch = fin.get();
			if (ch == '*')
			{
				start.ln = i + 1;
				start.col = j + 1;
			}
			else if (ch == 'K')
				val = -1;//конь
			else if (ch == 'B')
				val = -2;//слон
			else if (ch == 'R')
				val = -3;//ладья
			if (val)
				figures.push_back(Figure(i + 1, j + 1, val));
		}
		fin.get();
	}
	size.ln += 2;
	size.col += 2;

	int temp = Func(size, figures, start);
	std::ofstream fout("output.txt", std::ios_base::out | std::ios_base::trunc);
	fout << temp;
	return 0;
}
Ejemplo n.º 9
0
std::vector<Figure> extractFigures(PIX *original, PageRegions &pageRegions,
                                   DocumentStatistics &docStats, bool verbose,
                                   bool showSteps,
                                   std::vector<Figure> &errors) {
  BOXA *bodytext = pageRegions.bodytext;
  BOXA *graphics = pageRegions.graphics;
  BOXA *captions = pageRegions.getCaptionsBoxa();
  std::vector<Caption> unassigned_captions = pageRegions.captions;
  int total_captions = captions->n;

  PIXA *steps = showSteps ? pixaCreate(4) : NULL;

  // Add bodyText boxes to fill up the margin
  BOX *margin;
  BOX *foreground;
  pixClipToForeground(original, NULL, &foreground);
  BOX *extent;
  boxaGetExtent(graphics, NULL, NULL, &extent);
  margin = boxBoundingRegion(extent, foreground);
  boxDestroy(&extent);
  boxaGetExtent(bodytext, NULL, NULL, &extent);
  margin = boxBoundingRegion(margin, extent);
  boxDestroy(&extent);
  boxaGetExtent(pageRegions.other, NULL, NULL, &extent);
  margin = boxBoundingRegion(margin, extent);
  int x = margin->x - 2, y = margin->y - 2, h = margin->h + 4,
      w = margin->w + 4;
  x = std::max(x, 0);
  y = std::max(y, 0);
  h = std::min((int)original->h, h);
  w = std::min((int)original->w, w);
  boxDestroy(&margin);
  boxaAddBox(bodytext, boxCreate(0, 0, original->w, y), L_CLONE);
  boxaAddBox(bodytext, boxCreate(0, y + h, original->w, original->h - y - h),
             L_CLONE);
  boxaAddBox(bodytext, boxCreate(0, 0, x, original->h), L_CLONE);
  boxaAddBox(bodytext, boxCreate(x + w, 0, original->w - x - w, original->h),
             L_CLONE);

  // Add captions to body text
  boxaJoin(bodytext, captions, 0, captions->n);

  if (showSteps)
    pixaAddPix(steps, original, L_CLONE);

  // Generate proposed regions for each caption box
  double center = original->w / 2.0;
  BOXAA *allProposals = boxaaCreate(captions->n);
  BOXA *claimedImages = boxaCreate(captions->n);
  for (int i = 0; i < captions->n; i++) {
    BOX *captBox = boxaGetBox(captions, i, L_CLONE);
    BOXA *proposals = boxaCreate(4);
    for (int j = 0; j < bodytext->n; j++) {
      BOX *txtBox = boxaGetBox(bodytext, j, L_CLONE);
      BOX *proposal = NULL;
      int tolerance = 2;
      int horizontal = 0;
      int vertical = 0;

      boxAlignment(captBox, txtBox, tolerance, &horizontal, &vertical);
      if (vertical * horizontal != 0 or (vertical == 0 and horizontal == 0)) {
        continue;
      }

      if (vertical == 0) {
        if (horizontal == 1) {
          proposal = boxRelocateOneSide(NULL, captBox,
                                        txtBox->x + txtBox->w + 2, L_FROM_LEFT);
        } else if (horizontal == -1) {
          proposal =
              boxRelocateOneSide(NULL, captBox, txtBox->x - 2, L_FROM_RIGHT);
        }
        boxExpandUD(proposal, bodytext);
        if (horizontal == -1) {
          proposal->w -= captBox->w + 1;
          proposal->x = captBox->x + captBox->w + 1;
        } else if (horizontal == 1) {
          proposal->w -= captBox->w + 1;
        }
      } else {
        if (vertical == 1) {
          proposal = boxRelocateOneSide(NULL, captBox,
                                        txtBox->y + txtBox->h + 3, L_FROM_TOP);
        } else if (vertical == -1) {
          proposal =
              boxRelocateOneSide(NULL, captBox, txtBox->y - 3, L_FROM_BOT);
        }
        boxExpandLR(proposal, bodytext);
        if (vertical == -1) {
          proposal->h -= captBox->h + 1;
          proposal->y = captBox->y + captBox->h + 1;
        } else if (vertical == 1) {
          proposal->h -= captBox->h + 1;
        }
      }

      // For two columns document, captions that do not
      // cross the center should not have regions pass the center
      if (docStats.documentIsTwoColumn()) {
        if (captBox->x + captBox->w <= center and
            proposal->x + proposal->w > center) {
          boxRelocateOneSide(proposal, proposal, center - 1, L_FROM_RIGHT);
        } else if (captBox->x >= center and proposal->x < center) {
          boxRelocateOneSide(proposal, proposal, center + 1, L_FROM_LEFT);
        }
      }

      BOX *clippedProposal;
      pixClipBoxToForeground(original, proposal, NULL, &clippedProposal);
      if (clippedProposal != NULL and
          scoreBox(clippedProposal, pageRegions.captions.at(i).type, bodytext,
                   graphics, claimedImages, original) > 0) {
        boxaAddBox(proposals, clippedProposal, L_CLONE);
      }
    }

    if (proposals->n > 0) {
      boxaaAddBoxa(allProposals, proposals, L_CLONE);
    } else {
      // Give up on this caption
      int on_caption = i - (total_captions - unassigned_captions.size());
      errors.push_back(Figure(unassigned_captions.at(on_caption), NULL));
      unassigned_captions.erase(unassigned_captions.begin() + on_caption);
    }
  }
  std::vector<Figure> figures = std::vector<Figure>();
  if (unassigned_captions.size() == 0) {
    return figures;
  }

  // Now go through every possible assignment of captions
  // to proposals pick the highest scorign one
  int numConfigurations = 1;
  for (int i = 0; i < allProposals->n; ++i) {
    numConfigurations *= allProposals->boxa[i]->n;
  }

  if (verbose)
    printf("Found %d possible configurations\n", numConfigurations);

  BOXA *bestProposals = NULL;
  std::vector<bool> bestKeep;
  int bestFound = -1;
  double bestScore = -1;
  for (int onConfig = 0; onConfig < numConfigurations; ++onConfig) {

    // Gather the proposed regions based on the configuration number
    int configNum = onConfig;
    BOXA *proposals = boxaCreate(allProposals->n);
    std::vector<bool> keep;
    for (int i = 0; i < allProposals->n; ++i) {
      int numProposals = allProposals->boxa[i]->n;
      int selected = configNum % numProposals;
      configNum = configNum / numProposals;
      boxaAddBox(proposals, allProposals->boxa[i]->box[selected], L_COPY);
    }

    // Attempt to split any overlapping regions
    for (int i = 0; i < proposals->n; ++i) {
      for (int j = i; j < proposals->n; ++j) {
        BOX *p1 = proposals->box[i];
        BOX *p2 = proposals->box[j];
        int eq;
        boxEqual(p1, p2, &eq);
        if (not eq)
          continue;
        int vertical, horizontal;
        boxAlignment(unassigned_captions.at(i).boundingBox,
                     unassigned_captions.at(j).boundingBox, 2, &horizontal,
                     &vertical);
        if (vertical == 0 or horizontal != 0)
          continue;

        double split = splitBoxVertical(original, p1);
        if (split > 0) {
          BOX *topClipped;
          BOX *botClipped;
          BOX *top = boxRelocateOneSide(NULL, p1, split - 1, L_FROM_BOT);
          pixClipBoxToForeground(original, top, NULL, &topClipped);
          BOX *bot = boxRelocateOneSide(NULL, p1, split + 1, L_FROM_TOP);
          pixClipBoxToForeground(original, bot, NULL, &botClipped);
          if (vertical == -1) {
            proposals->box[i] = topClipped;
            proposals->box[j] = botClipped;
          } else {
            proposals->box[i] = botClipped;
            proposals->box[j] = topClipped;
          }
          if (verbose)
            printf("Split a region vertically\n");
        }
      }
    }

    if (showSteps) {
      pixaAddPix(steps, pixDrawBoxa(original, proposals, 4, 0xff000000),
                 L_CLONE);
    }

    // Score the proposals
    int numFound = 0;
    double totalScore = 0;
    for (int i = 0; i < proposals->n; ++i) {
      double score =
          scoreBox(proposals->box[i], pageRegions.captions.at(i).type, bodytext,
                   graphics, proposals, original);
      totalScore += score;
      if (score > 0) {
        numFound += 1;
        keep.push_back(true);
      } else {
        keep.push_back(false);
      }
    }

    // Switch in for the current best needed
    if (numFound > bestFound or
        (numFound == bestFound and totalScore > bestScore)) {
      bestFound = numFound;
      bestScore = totalScore;
      bestProposals = proposals;
      bestKeep = keep;
    }
  }

  if (showSteps) {
    BOX *clip;
    PIXA *show = pixaCreate(4);
    pixClipBoxToForeground(original, NULL, NULL, &clip);
    int pad = 10;
    clip->x -= 10;
    clip->y -= 10;
    clip->w += pad * 2;
    clip->h += pad * 2;
    for (int i = 0; i < steps->n; ++i) {
      pixaAddPix(show, pixClipRectangle(steps->pix[i], clip, NULL), L_CLONE);
    }
    pixDisplay(pixaDisplayTiled(pixaConvertTo32(show), 4000, 1, 30), 0, 0);
  }

  for (int i = 0; i < bestProposals->n; ++i) {
    if (bestKeep.at(i)) {
      BOX *imageBox = bestProposals->box[i];
      int pad = 2;
      imageBox->x -= pad;
      imageBox->y -= pad;
      imageBox->w += pad * 2;
      imageBox->h += pad * 2;
      figures.push_back(Figure(unassigned_captions.at(i), imageBox));
    } else {
      errors.push_back(Figure(unassigned_captions.at(i), NULL));
    }
  }
  return figures;
}
Ejemplo n.º 10
0
void on_mouse(int event, int x, int y, int flags, void* param)
{
	
	
	switch(event)
	{
		case CV_EVENT_LBUTTONUP://evento del boton cuando se suelta
			window.followmousemove = 0;
			if(figure.task != '9')
			{
				figure.lp.x=x;
				figure.lp.y=y;
			}	
			else
			{
				window.refresh();
				figure.task = '?';
			}
			if(figure.drawtype != '?' )
				list.push_back(figure);
			drawList(window.image, list);
							
			break;
		case CV_EVENT_LBUTTONDOWN://evento del boton cuando se presiona
			xx = x;
			yy = y;
			
			window.followmousemove = 1;
			
			if(variable[3] != 9 && variable[3]<50)
			{
				figure = Figure(variable[0],variable[1],variable[2]);
				figure.fp.x=x;
				figure.fp.y=y;
				figure.drawtype=variable[3];
			}
			else
			{
				figure = find(x,y,list);
				if(variable[4]==50 || variable[4]==75 || variable[4]==125 || variable[4]==150)
				{
					figure.setZoom((float)variable[4]/100);
					figure.task = '9';
				}
				if(variable[0]!=-1 && variable[1]!=-1 && variable[2]!=-1)
				{
					figure.setColor(variable[0],variable[1],variable[2]);
					figure.task = '9';
				}

				if(variable[3]==9)
					figure.task = '9';
			}
			break;
	}
	if(CV_EVENT_MOUSEMOVE==event && window.followmousemove == 1)//evento del boton en movimiento
	{	

		window.refresh();
		if(figure.task == '9')
		{
			figure.move(x-xx,y-yy);
			xx=x;
			yy=y;
		}
		else
		{
			figure.lp.x = x;
			figure.lp.y = y;
		}
		
		figure.draw(window.image);
		drawList(window.image, list);	
	}
}
Ejemplo n.º 11
0
#include"Window.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#include <unistd.h>
Window window= Window(480, 300);
Figure figure=Figure(0,0,0);
std::list<Figure> list;
int xx = 0;
int yy = 0;
int lastState = 1;
int currentState = 1;
int shmid = 0; 
int *variable = NULL;
key_t llave = 0;


/*
   Dibuja una lista de figuras en una imagen.

   Parámetros: 
      image	la imagen donde dibuja.
      list 	la lista de figuras que dibuja en la imagen.

*/
void drawList(IplImage* image, std::list<Figure> &list)
{
	std::list<Figure>::iterator pos;
int main()
{
    randomnessGenerator = new TRandom();

    system((string("mkdir -p ")+OUTPUT_FOLDER).c_str());

    // ###########################
    // # Prepare final SFR table #
    // ###########################

    vector<string> columns = { "SFR-1ltop", "SFR-Wjets" };

    vector<string> listAllSignalRegion = listCutAndCounts;

    vector<string> listRawRegion = listIndividualCuts;

    Table tableSFRToBeUsed(columns,listAllSignalRegion);
    Table tableRawSFR(columns,listRawRegion);
    
    columns.clear();
    columns = {"NormPeak_1ltop", "NormTail_1ltop", "SFR-1ltop", "NormPeak_Wjets", "NormTail_Wjets", "SFR-Wjets"};
    Table tableRawNormValues(columns,listRawRegion);

    // Create observables
    RooRealVar var(OBSERVABLE_FOR_FIT,OBSERVABLE_FOR_FIT,0,600) ;
    string varname(OBSERVABLE_FOR_FIT);

    FitSetup setup;
    FitResult res;
    string conditions;


    // ########################
    // #  _____        _____  #
    // # /  __ \ ___  /  __ \ #
    // # | /  \/( _ ) | /  \/ #
    // # | |    / _ \/\ |     #
    // # | \__/\ (_>  < \__/\ #
    // #  \____/\___/\/\____/ #
    // #                      #
    // ########################

    std::map<string,Figure> SFR_CC_1ltop_map;
    std::map<string,Figure> SFR_CC_Wjets_map;

    //Create histos
    TH1F h_SF_MTpeak_CC_1ltop ("h_SF_MTpeak_CC_1ltop",  "", listIndividualCuts_MTtail.size(), 0, listIndividualCuts_MTtail.size());
    TH1F h_SF_MTtail_CC_1ltop ("h_SF_MTtail_CC_1ltop",  "", listIndividualCuts_MTtail.size(), 0, listIndividualCuts_MTtail.size());
    TH1F h_SFR_CC_1ltop       ("h_SFR_CC_1ltop",        "", listIndividualCuts_MTtail.size(), 0, listIndividualCuts_MTtail.size());
    TH1F h_SF_MTpeak_CC_Wjets ("h_SF_MTpeak_CC_Wjets",  "", listIndividualCuts_MTtail.size(), 0, listIndividualCuts_MTtail.size());
    TH1F h_SF_MTtail_CC_Wjets ("h_SF_MTtail_CC_Wjets",  "", listIndividualCuts_MTtail.size(), 0, listIndividualCuts_MTtail.size());
    TH1F h_SFR_CC_Wjets       ("h_SFR_CC_Wjets",        "", listIndividualCuts_MTtail.size(), 0, listIndividualCuts_MTtail.size());

    for(unsigned int i=0;i<listIndividualCuts.size();i++)
    {
        cout<<"%%%%%%%%%%%%%%%%%% "<<listIndividualCuts_MTtail[i]<<endl;

        string label = listIndividualCuts[i];
        Figure SFR_1ltop;
        Figure SFR_Wjets;

        //MT tail
        setup.Reset();
        conditions="sigRegions_CC_tail";
        setup.region=listIndividualCuts_MTtail[i];
        setup.varname=varname;
        setup.varMin=0;
        setup.varMax=600;


	//test on Ndata
	
	/*
	vector<int> Ndata = {100,200,500,1000,5000,10000};
	//vector<int> Ndata = {100,200};//,500,1000,5000,10000};
	*/
	TFile* file = new TFile("closure.root","RECREATE");
	//for(unsigned int c=0;c<Ndata.size();c++){
	/*
	TString dirname;
	dirname+=Ndata[c];
	file->mkdir(dirname.Data());
	*/
	TH1F* h_tt1l_Pull = new TH1F("h_tt1l_Pull", "Pull distrib. SF_1ltop", 30, -3, 3);
	TH1F* h_Wjets_Pull = new TH1F("h_Wjets_Pull", "Pull distrib. SF_1ltop", 30, -3, 3);
	TH1F* h_tt1l_uncert = new TH1F("h_tt1l_uncert", "Uncertainty on  SF_1ltop", 100, 0, 5);
	TH1F* h_Wjets_uncert = new TH1F("h_Wjets_uncert", "Uncertainty on SF_1ltop", 100, 0, 1);
        
	//setup.Ndata = Ndata[c];

	for(int np = 0; np<5000; np++){
		res = doFit(setup,conditions);
        	Figure NormTail_1ltop(res.SF_1ltop.first,res.SF_1ltop.second);
      	        Figure NormTail_Wjets=Figure(res.SF_Wjets.first,res.SF_Wjets.second);
		cout<<NormTail_1ltop.Print()<<endl;
		cout<<NormTail_Wjets.Print()<<endl;
		h_tt1l_Pull->Fill((res.SF_1ltop.first-1)/res.SF_1ltop.second);
		h_Wjets_Pull->Fill((res.SF_Wjets.first-1)/res.SF_Wjets.second);
		h_tt1l_uncert->Fill(res.SF_1ltop.second/res.SF_1ltop.first);
		h_Wjets_uncert->Fill(res.SF_Wjets.second/res.SF_Wjets.first);
		//cout<<<<" "<<NormTail_Wjets<<endl;
		//tableRawNormValues.Set("NormTail_1ltop",listIndividualCuts[i],NormTail_1ltop);
		//tableRawNormValues.Set("NormTail_Wjets",listIndividualCuts[i],NormTail_Wjets);
        /*
	h_SF_MTtail_CC_1ltop.SetBinContent(i+1,res.SF_1ltop.first);
        h_SF_MTtail_CC_1ltop.SetBinError(i+1,res.SF_1ltop.second);
        h_SF_MTtail_CC_1ltop.GetXaxis()->SetBinLabel(i+1,label.c_str());
        h_SF_MTtail_CC_Wjets.SetBinContent(i+1,res.SF_Wjets.first);
        h_SF_MTtail_CC_Wjets.SetBinError(i+1,res.SF_Wjets.second);
        h_SF_MTtail_CC_Wjets.GetXaxis()->SetBinLabel(i+1,label.c_str());
	*/
	}
		//file->cd(dirname.Data());
		file->cd();
		h_tt1l_Pull->Write();
		h_Wjets_Pull->Write();
		h_tt1l_uncert->Write();
		h_Wjets_uncert->Write();
		file->cd();
	//}
    	file->Close();
    }

    //Save plots in roofile
    TFile fCR1_CC((string(OUTPUT_FOLDER)+"/results_CC.root").c_str(),"RECREATE");
    h_SF_MTpeak_CC_1ltop.Write();
    h_SF_MTpeak_CC_Wjets.Write();
    h_SF_MTtail_CC_1ltop.Write();
    h_SF_MTtail_CC_Wjets.Write();
    h_SFR_CC_1ltop.Write();
    h_SFR_CC_Wjets.Write();

    //---------------------------------------------
    // Results for C&C
    //---------------------------------------------
    initCutAndCountCuts();
    vector<string> cuts;

    for(unsigned int r=0;r<listCutAndCounts.size();r++)
    {
        cuts = listCutAndCounts_cuts[listCutAndCounts[r]];
        Figure SFR_CC_1ltop;
        Figure SFR_CC_Wjets;
        for(unsigned i=0;i<cuts.size();i++)
        {
            cout<<cuts[i]<<" "<<SFR_CC_1ltop_map[cuts[i]].Print()<<endl;
            if(i == 0) SFR_CC_1ltop = SFR_CC_1ltop_map[cuts[i]];
            else SFR_CC_1ltop = Figure(SFR_CC_1ltop.value(),
                                       sqrt(pow(SFR_CC_1ltop.error(),2)
                                           +pow(SFR_CC_1ltop.value()
                                                -SFR_CC_1ltop_map[cuts[i].c_str()].value(),2)
                                           ));

            if(i == 0) SFR_CC_Wjets = SFR_CC_Wjets_map[cuts[i]];
            else SFR_CC_Wjets = Figure(SFR_CC_Wjets.value(),
                                       sqrt(pow(SFR_CC_Wjets.error(),2)
                                           +pow(SFR_CC_Wjets.value()
                                               -SFR_CC_Wjets_map[cuts[i].c_str()].value(),2)
                                           ));
        }

        // Add 20% of uncertainty for fit itself (JES, MC stat. ...)
        SFR_CC_1ltop *= Figure(1.0,TEMPLATE_FIT_METHOD_UNCERTAINTY);
        SFR_CC_Wjets *= Figure(1.0,TEMPLATE_FIT_METHOD_UNCERTAINTY);

        tableSFRToBeUsed.Set("SFR-1ltop",listCutAndCounts[r],SFR_CC_1ltop);
        tableSFRToBeUsed.Set("SFR-Wjets",listCutAndCounts[r],SFR_CC_Wjets);
    }

    tableRawSFR.Print(string(OUTPUT_FOLDER)+"/rawSFR.tab"   ,4);
    tableRawNormValues.Print(string(OUTPUT_FOLDER)+"/rawNormValues.tab"   ,4);
    tableSFRToBeUsed.Print(string(OUTPUT_FOLDER)+"/SF_MTtail.tab",4);
    
    tableRawSFR.PrintLatex(string(OUTPUT_FOLDER)+"/SF_MTtail.tex",4);
}
int main (int argc, char *argv[])
{
    //loadBDTSignalRegions();

    if(argc == 2){
    	cout<<"load"<<endl;
	default_param2(topness2_param_);
	LoadParam2(string(argv[1]));
    }
    else{
    	cout<<"You shoul provide the name of the config file !"<<endl;
    	return -1;
    }
    printBoxedMessage("Starting tables generation");

    // ####################
    // ##   Init tools   ##
    // ####################

        // Create a sonic Screwdriver
        SonicScrewdriver screwdriver;
     
     
     // ##########################
     // ##   Create Variables   ##
     // ##########################
  
   
     vector<string> colTags = {"default","resMass", "aCM", "allTerms","allTermsBias"};
     vector<string> colLabels = {"default","reso mass", "aCM terms", "all terms", "id + bias"};
     vector<string> rowTags = {"purity"};
     vector<string> rowLabels = {"purity"};
     Table table_topness_purity(colTags,rowTags,colLabels,rowLabels);
     int n_tt2l_sel = 0;
     int n_tt2l_sel_matchable = 0;

     int n_topness_var = 5;
     vector< vector< int > > topness_purity;
     topness_purity.resize(n_topness_var);
     for(int i=0;i<n_topness_var;i++) topness_purity[i].resize(2);

     //tt2l_mc_info mcinfo;
     //tt2l_reso res;
    

     float d_met;
     float topness_def;
     float topness_m1; // change the resolution term for Invis.
     float topness_m2; // change the resolution term for aCM
     float topness_m3; // change the resolution term for all
     float topness_m4; // change the resolution term for all
     float topness_m5; // m3 + correct for MET bias
     float topness_m6; // m3 + correct for MET bias
     float topness_m7; // m3 + correct for MET bias
     float topness_m8; // m3 + correct for MET bias
     float topness_m9; // m3 + correct for MET bias
     float topness_m10; // m3 + correct for MET bias
     float topness_m11; // m3 + correct for MET bias
     float topness_m12; // m3 + correct for MET bias
     float topness_m13; // m3 + correct for MET bias

     screwdriver.AddVariable("MT2W",             "MT2W",                   "GeV",    40,0,400,       &(myEvent.MT2W),                   "");

     //screwdriver.AddVariable("lostLeptonEta",             "Eta of lost lepton",            "",    40, -6, 6,     &(res.lost_eta),                   "");

     // topness
     screwdriver.AddVariable("topness",             "topness - reference",            "",    80, -5, 15,     &(topness_def),                   "");
     /*
     screwdriver.AddVariable("topness_m12",          "topness - resolution modified",  "",    40, -20, 20,     &(topness_m12),                   "");
     screwdriver.AddVariable("topness_m13",          "topness - resolution modified",  "",    40, -20, 20,     &(topness_m13),                   "");
*/
//int index_b;	//
	//int index_bbar; //
//	vector<int> index_isr;



    // #########################################################
    // ##   Create ProcessClasses (and associated datasets)   ##
    // #########################################################
	
	screwdriver.AddProcessClass("ttbar_1l", "t#bar{t} #rightarrow l+jets",                             "background",kRed-7);
                screwdriver.AddDataset("ttbar-madgraph",                "ttbar_1l",  0, 0);


        screwdriver.AddProcessClass("ttbar_2l", "t#bar{t} #rightarrow l^{+}l^{-}", "background",kCyan-3);
///*	
	screwdriver.AddProcessClass("single_top", "single top",                             "background",kRed-5);
                screwdriver.AddDataset("singleTopbar_s",                "single_top",  0, 0);
                screwdriver.AddDataset("singleTopbar_t",                "single_top",  0, 0);
                screwdriver.AddDataset("singleTop_s",                "single_top",  0, 0);
                screwdriver.AddDataset("singleTop_t",                "single_top",  0, 0);
	 
        screwdriver.AddProcessClass("W+jets",   "W+jets",                          "background",kOrange-2);
            screwdriver.AddDataset("Wjets", "W+jets", 0, 0);
        screwdriver.AddProcessClass("VV",   "di-boson",                          "background",kOrange-3);
            //screwdriver.AddDataset("ZZ", "ZZ", 0, 0);
            screwdriver.AddDataset("WZ", "WZ", 0, 0);
       
       screwdriver.AddProcessClass("ttV",   "ttV",                          "background",kOrange-4);
            screwdriver.AddDataset("ttW", "ttV", 0, 0);
            screwdriver.AddDataset("ttZ", "ttV", 0, 0);
//	*/
	screwdriver.AddProcessClass("T2tt_850_100",   "T2tt_850_100",                          "signal",kGreen+2);
            screwdriver.AddDataset("T2tt_850_100", "T2tt_850_100", 0, 0);
	screwdriver.AddProcessClass("T2tt_650_100",   "T2tt_650_100",                          "signal",kGreen+3);
           screwdriver.AddDataset("T2tt_650_100", "T2tt_650_100", 0, 0);
       // screwdriver.AddProcessClass("T2tt_500_325",   "T2tt_500_325",                          "signal",kGreen+4);
         //   screwdriver.AddDataset("T2tt_500_325", "T2tt_500_325", 0, 0);


    // ##########################
    // ##    Create Regions    ##
    // ##########################

        //screwdriver.AddRegion("presel_MTpeak",          "Preselection (MT peak)",      &goesInMTpeak);
        //screwdriver.AddRegion("presel_MTtail",          "Preselection (MT peak)",      &goesInMTtail);
        screwdriver.AddRegion("baseline",          "Baseline selection",      &goesInBaselineSearchSR);
        screwdriver.AddRegion("baslineLargeDM",          "Baseline S.R.  - Large #DeltaM",      &goesInLargeDMSR);
        screwdriver.AddRegion("baselineSmallDM",          "Baseline S.R. - Small #DeltaM",      &goesInSmallDMSR);
        screwdriver.AddRegion("baseline2b",          "Baseline selection",      &goesInBaselineSearchSR2b);
        screwdriver.AddRegion("baselineSmallDM2b",          "Baseline S.R. - Small #DeltaM",      &goesInSmallDMSR2b);


    // ##########################
    // ##   Create Channels    ##
    // ##########################

        //screwdriver.AddChannel("singleLepton", "e/#mu-channels",  &goesInSingleLeptonChannel);
        //screwdriver.AddChannel("singleElec",   "e-channel",       &goesInSingleElecChannel  );
        //screwdriver.AddChannel("singleMuon",   "#mu-channel",     &goesInSingleMuonChannel  );
        screwdriver.AddChannel("allChannels",  "",                &goesInAnyChannel         );

  // ########################################
  // ##       Create histograms and        ##
  // ##  schedule type of plots to produce ##
  // ########################################

     // Create histograms
     screwdriver.Create1DHistos();
     
     // Create 2D histos
    
    
    // #########################################################

     // Schedule plots
     screwdriver.SchedulePlots("1DDataMCComparison");
     screwdriver.SchedulePlots("1DStack");
     screwdriver.SchedulePlots("1DSuperimposed");
     //screwdriver.SchedulePlots("2D");


     // Config plots

     screwdriver.SetGlobalStringOption("DataMCComparison",  "includeSignal",                    "stack");
     screwdriver.SetGlobalFloatOption ("DataMCComparison",  "factorSignal",                     1.0    );
     
     screwdriver.SetGlobalStringOption("1DStack",           "includeSignal",    "superimposed");
     screwdriver.SetGlobalFloatOption ("1DStack",           "factorSignal",     1.0    );

     screwdriver.SetGlobalStringOption("Plot", "infoTopRight", "CMS Preliminary");
     screwdriver.SetGlobalStringOption("Plot", "infoTopLeft",  "#sqrt{s} = 8 TeV, L = 10 fb^{-1}");

     screwdriver.SetGlobalBoolOption("Plot", "exportPdf", true);
     screwdriver.SetGlobalBoolOption("Plot", "exportEps", false);
     screwdriver.SetGlobalBoolOption("Plot", "exportPng", false);

    // ########################################
    // ##       Run over the datasets        ##
    // ########################################

        vector<string> datasetsList;
        screwdriver.GetDatasetList(&datasetsList);

        cout << "   > Reading datasets... " << endl;
        cout << endl;

        for (unsigned int d = 0 ; d < datasetsList.size() ; d++)
        {
            string currentDataset = datasetsList[d];
            string currentProcessClass = screwdriver.GetProcessClass(currentDataset);

            sampleName = currentDataset;
            sampleType = screwdriver.GetProcessClassType(currentProcessClass);

            // Open the tree
            string treePath = string(FOLDER_BABYTUPLES_SKIM)+currentDataset+".root";
            TFile f(treePath.c_str());
            TTree* theTree = (TTree*) f.Get("babyTuple");

	    //cout<<"v1"<<endl;
            InitializeBranchesForReading(theTree,&myEvent);
	    //cout<<"v2"<<endl;

        // ########################################
        // ##        Run over the events         ##
        // ########################################

            bool ttbarDatasetToBeSplitted = false;
            if (findSubstring(currentDataset,"ttbar")
            && (currentDataset != "ttbar_madgraph_1l")
            && (currentDataset != "ttbar_madgraph_2l"))
                ttbarDatasetToBeSplitted = true;

            int nEntries = theTree->GetEntries();
            //if(nEntries>10000000) nEntries = 10000000;
            //if(nEntries>5000000) nEntries = 5000000;
            //if(nEntries>500000) nEntries = 500000;
	    double tWL, tTL, tTM;
	    float sf_fracEvent = (float)nEntries/theTree->GetEntries();
	    for (int i = 0 ; i < nEntries ; i++)
            {
                if (i % (nEntries / 50) == 0) printProgressBar(i,nEntries,currentDataset);

		// Get the i-th entry
		ReadEvent(theTree,i,&myEvent);

                string currentProcessClass_ = currentProcessClass;
		float weight = getWeight(currentDataset,theTree->GetEntries(), sf_fracEvent);

		
		//Compute Delta MET
		d_met = myEvent.pfmet-myEvent.genMET;

		//Topness study
		bool is_tt2l = false;
		if(myEvent.ttbar_decay == 2){
			is_tt2l = true; 
			n_tt2l_sel++;
			if(myEvent.matched == true) n_tt2l_sel_matchable++;
		}
			
			#ifdef topness_computation

		        int index_b1 = -1;
			int index_b2 = -1;
			//cout<<topness_param_.use_cox_box<<endl;
			//cout<<topness_param_.aW<<endl;	
			//default_param(topness_param_);
			//DumpParam();

			topness_def = ComputeTopness(index_b1,index_b2, tWL, tTL, tTM);
			//cout<<"topness = "<<topness_def<<endl;
			if(TopnessMatched(index_b1, index_b2)) topness_purity[0][0]++;
			// changing the resolution terms
			/*
			// default computation
			// -- load default parameter s
			default_param(topness_param_);
			topness_def = ComputeTopness(index_b1,index_b2);
			if(TopnessMatched(index_b1, index_b2)) topness_purity[0][0]++;
			// changing the resolution terms
			default_param(topness_param_);
			topness_param_.aW = 40;
			topness_param_.aT = 50;
			
			topness_m1 = ComputeTopness(index_b1,index_b2);
			if(TopnessMatched(index_b1, index_b2)) topness_purity[0][1]++;			
			//
			default_param(topness_param_);
			topness_param_.aCM = 70;
			topness_param_.aCM_mean = 500;
			
			topness_m2 = ComputeTopness(index_b1,index_b2);
			if(TopnessMatched(index_b1, index_b2)) topness_purity[0][2]++;			
			
			//
			default_param(topness_param_);
			topness_param_.aW = 40;
			topness_param_.aT = 50;
			topness_param_.aCM = 200;
			topness_param_.aCM_mean = 650;
			
			topness_m3 = ComputeTopness(index_b1,index_b2);
			if(TopnessMatched(index_b1, index_b2)) topness_purity[0][3]++;			
			
			//
			default_param(topness_param_);
			topness_param_.aCM = 250;
			topness_param_.aCM_mean = 670;
			
			topness_m4 = ComputeTopness(index_b1,index_b2);
			if(TopnessMatched(index_b1, index_b2)) topness_purity[0][4]++;			
			
			
			//correct for MET bias
			topness_param_.aW = 40;
			topness_param_.aT = 50;
			topness_param_.aCM = 200;
			topness_param_.aCM_mean =670;
			topness_m7 = ComputeTopness(index_b1,index_b2);
			//if(TopnessMatched(index_b1, index_b2)) topness_purity[0][5]++;			
		
			//correct for MET bias
			//if(myEvent.pfmet>80) myEvent.pfmet = myEvent.pfmet - 50;
			default_param(topness_param_);
			topness_param_.aW = 80;
			topness_param_.aT = 100;
			topness_param_.aCM = 200;
			topness_param_.aCM_mean = 670;
			topness_m8 = ComputeTopness(index_b1,index_b2);
			//if(TopnessMatched(index_b1, index_b2)) topness_purity[0][5]++;			
			
			//correct for MET bias
			//if(myEvent.pfmet>80) myEvent.pfmet = myEvent.pfmet - 50;
			default_param(topness_param_);
			//topness_param_.aW = 80;
			//topness_param_.aT = 100;
			topness_param_.aCM = 65;
			topness_param_.aCM_mean = 650;
			topness_param_.use_cox_box = true;
			topness_m9 = ComputeTopness(index_b1,index_b2);
			//if(TopnessMatched(index_b1, index_b2)) topness_purity[0][5]++;		
			
			
			//correct for MET bias
			//if(myEvent.pfmet>80) myEvent.pfmet = myEvent.pfmet - 50;
			default_param(topness_param_);
			topness_param_.aW = 40;
			topness_param_.aT = 50;
			topness_param_.aCM = 65;
			topness_param_.aCM_mean = 650;
			topness_param_.use_cox_box = true;
			topness_m10 = ComputeTopness(index_b1,index_b2);
			
			
			//correct for MET bias
			//if(myEvent.pfmet>80) myEvent.pfmet = myEvent.pfmet - 50;
			default_param(topness_param_);
			topness_param_.aW = 40;
			topness_param_.aT = 50;
			topness_param_.aCM = 80;
			topness_param_.aCM_mean = 800;
			topness_param_.use_cox_box = true;
			topness_m11 = ComputeTopness(index_b1,index_b2);

			//correct for MET bias
			//if(myEvent.pfmet>80) myEvent.pfmet = myEvent.pfmet - 50;
			default_param(topness_param_);
			//topness_param_.aW = 40;
			//topness_param_.aT = 50;
			//topness_param_.aCM = 80;
			//topness_param_.aCM_mean = 800;
			//topness_param_.use_cox_box = true;
			topness_param_.usePtPz = true;
			topness_m12 = ComputeTopness(index_b1,index_b2);
*/
			//correct for MET bias
			//if(myEvent.pfmet>80) myEvent.pfmet = myEvent.pfmet - 50;
			/*
			default_param(topness_param_);
			topness_param_.aW = 40;
			topness_param_.aT = 50;
			//topness_param_.aCM = 80;
			//topness_param_.aCM_mean = 800;
			//topness_param_.use_cox_box = true;
			topness_param_.usePtPz = true;
			topness_m13 = ComputeTopness(index_b1,index_b2);
*/
/*

			//correct for MET bias
			//if(myEvent.pfmet>80) myEvent.pfmet = myEvent.pfmet - 50;
			default_param(topness_param_);
			topness_param_.aW = 40;
			topness_param_.aT = 50;
			topness_param_.aCM = 350;
			topness_param_.aCM_mean = 850;
			topness_m6 = ComputeTopness(index_b1,index_b2);
			//if(TopnessMatched(index_b1, index_b2, res)) topness_purity[0][5]++;			
			
			//correct for MET bias
			//cout<<myEvent.pfmet<<endl;
			//if(myEvent.pfmet>80) myEvent.pfmet = myEvent.pfmet - 50;
			if(myEvent.pfmet>80) myEvent.pfmet = myEvent.pfmet*0.70;// - 50;
			//cout<<myEvent.pfmet<<endl;
			default_param(topness_param_);
			topness_param_.aW = 40;
			topness_param_.aT = 50;
			topness_param_.aCM = 300;
			topness_param_.aCM_mean = 650;
			topness_m5 = ComputeTopness(index_b1,index_b2);
			//if(TopnessMatched(index_b1, index_b2, res)) topness_purity[0][5]++;			
			*/
			#endif
                
		// Split 1-lepton ttbar and 2-lepton ttbar
                //if (ttbarDatasetToBeSplitted && (myEvent.genlepsfromtop == 2))
                if (ttbarDatasetToBeSplitted && is_tt2l)
                    currentProcessClass_ = "ttbar_2l";
                
		screwdriver.AutoFillProcessClass(currentProcessClass_,weight);

            }
            printProgressBar(nEntries,nEntries,currentDataset);
            cout << endl;
            f.Close();

        }
  
  // ###################################
  // ##   Make plots and write them   ##
  // ###################################

  cout << endl;
  cout << "   > Making plots..." << endl;
  screwdriver.MakePlots();
  cout << "   > Saving plots..." << endl;

  //string output_dir = %./plots/"+string(argv[1])+"/pow2/";
  string output_dir = "./plots/"+string(argv[1])+"/comb3_4/";
  //string output_dir = "./plots/"+string(argv[1])+"/pow2/loopnonb_all/";
  //string output_dir = "./plots/topness2/"+string(argv[1])+"/";
  //screwdriver.WritePlots(string("./plots/plotsProducer/"));
  screwdriver.WritePlots(output_dir);

  printBoxedMessage("Plot generation completed");
        
  printBoxedMessage("Writing the table ... ");
 
 vector<string> regions  = { 
 	"presel_MTtail", "baseline", "baslineLargeDM", "baselineSmallDM"
				    //"presel_MTpeak", "presel_MTtail",
				    /*
				    "preveto_MTpeak",      "preveto_MTtail",
                                    "signalRegion_MTpeak", "signalRegion_MTtail",
                                    "0btag_MTpeak",        "0btag_MTtail",
                                    "reversedVeto_MTpeak", "reversedVeto_MTtail",
                                    "2leptons", "2leptons_MTpeak", "2leptons_MTtail",
                                  */};

  //string exportFile = "rawYieldTables/prediction.tab";
  //TableDataMC(&screwdriver,regions,"allChannels").Print(exportFile,4);

  // #############################
  // ##   Post-plotting tests   ##
  // #############################
  

  //Table topness - purity
  for(int i=0;i<n_topness_var;i++){
  	table_topness_purity.Set(0,i, Figure(topness_purity[i][0],sqrt(topness_purity[i][0]))/Figure(n_tt2l_sel,sqrt(n_tt2l_sel)));
  	table_topness_purity.Set(1,i, Figure(topness_purity[i][0],sqrt(topness_purity[i][0]))/Figure(n_tt2l_sel_matchable,sqrt(n_tt2l_sel_matchable)));
  }
  table_topness_purity.Print(output_dir+"purity.dat");

  printBoxedMessage("Program done.");
/*
 string region = "baseline";
 string channel = "allChannels";
 string var;
 var = "topness_m5";
 //loop over the backgroumd
 vector<string> processClassList;
 //GetProcessClassTagList()
 screwdriver.GetProcessClassTagList(&processClassList);
 TH1F* h_Eff_Bkg = 0;
 TH1F* h_Eff_Sig = 0;
 bool first = true;
 for(unsigned int i=0;i<processClassList.size();i++){
 	string proc = processClassList[i];
 	if(scredrive.GetProcessClassType(proc) == "background"){
 		TH1F* h = screewdriver.Get1DHistoClone(var , processClass, region, channel);
 		if(first){
			h_Eff_Bkg = (TH1F*) h->Clone("");
			first = false;
		}
		for(int i=1;i<h->GetNBinsX();i++){
			h_Eff_Bkgh->Integral(i,h->GetNBinsX()+1);
		}
	}
 }
 */
	return (0);
}
void backgroundEstimation::ComputePredictionWithSystematics()
{

    // Loop over the uncertainties
    for (unsigned int s = 0 ; s < systematicsTagList.size() ; s++)
    {
        ResetSystematics();
        string systematic = systematicsTagList[s];
        float uncertainty = 0.0;

        if (systematic == "total") continue;

        else if (systematic ==  "tt->ll_(CR4,CR5)")
        {
            // Determine the uncertainty from values stored in the table
	        ttll_CR4and5_rescale = 1-ttll_CR4CR5ModelingUncertainty; float yieldDown = ComputePrediction().value();
            ttll_CR4and5_rescale = 1+ttll_CR4CR5ModelingUncertainty; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        else if (systematic ==  "tt->ll_(nJets)")
        {
            ttll_nJets_rescale = 1-ttll_nJetsModelingUncertainty; float yieldDown = ComputePrediction().value();
            ttll_nJets_rescale = 1+ttll_nJetsModelingUncertainty; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        else if (systematic ==  "tt->ll_(veto)")
        {
            ttll_2ndlepVeto_rescale = 1-ComputeSecondLeptonVetoUncertainty(); float yieldDown = ComputePrediction().value();
            ttll_2ndlepVeto_rescale = 1+ComputeSecondLeptonVetoUncertainty(); float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        #ifdef USING_MT_TAIL_CORRECTION_FROM_TEMPLATE_FIT_METHOD
        else if (systematic == "1ltop_(cross_section)")
        {
            oneLepTopCrossSection_rescale = 0.9; float yieldDown = ComputePrediction().value();
            oneLepTopCrossSection_rescale = 1.1; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        #endif
        else if (systematic == "W+jets_(cross_section)")
        {
            WjetCrossSection_rescale = 0.5; float yieldDown = ComputePrediction().value();
            WjetCrossSection_rescale = 1.5; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        else if (systematic == "Rare_(cross_section)")
        {
            rareCrossSection_rescale = 0.5; float yieldDown = ComputePrediction().value();
            rareCrossSection_rescale = 1.5; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        #ifdef USING_MT_TAIL_CORRECTION_FROM_TEMPLATE_FIT_METHOD
        else if (systematic == "SF_MTtail_Wjets")
        {
            SF_MTtail_Wjets_variation = -1.0; float yieldDown = ComputePrediction().value();
            SF_MTtail_Wjets_variation =  1.0; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        else if (systematic == "SF_MTtail_1ltop")
        {
            SF_MTtail_1ltop_variation = -1.0; float yieldDown = ComputePrediction().value();
            SF_MTtail_1ltop_variation =  1.0; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        #else
        else if (systematic == "SFR_Wjets")
        {
            SFR_Wjets_variation = -1.0; float yieldDown = ComputePrediction().value();
            SFR_Wjets_variation =  1.0; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        else if (systematic == "1ltop_tailToPeak")
        {
            tailToPeakRatio_1lTop_variation = -1.0; float yieldDown = ComputePrediction().value();
            tailToPeakRatio_1lTop_variation =  1.0; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        #endif
        else if (systematic == "MTpeak")
        {
            MTpeakStat_variation = -1.0; float yieldDown = ComputePrediction().value();
            MTpeakStat_variation =  1.0; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        else if (systematic == "tt->ll_(MCstat)")
        {
            ttbar2lStat_variation = -1.0; float yieldDown = ComputePrediction().value();
            ttbar2lStat_variation =  1.0; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        else if (systematic == "1l_top_(MCstat)")
        {
            top1lStat_variation = -1.0; float yieldDown = ComputePrediction().value();
            top1lStat_variation =  1.0; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        else if (systematic == "W+jets_(MCstat)")
        {
            WjetsStat_variation = -1.0; float yieldDown = ComputePrediction().value();
            WjetsStat_variation =  1.0; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }
        else if (systematic == "rare_(MCstat)")
        {
            rareStat_variation = -1.0; float yieldDown = ComputePrediction().value();
            rareStat_variation =  1.0; float yieldUp   = ComputePrediction().value();
            uncertainty = fabs((yieldUp - yieldDown) / 2.0);
        }

        systematicsUncertainties.Set("absolute",systematic,Figure(uncertainty,0.0));
    }

    // Compute prediction for nominal case
    ResetSystematics();
    float yieldNominal = ComputePrediction().value();

    // Fill total uncertainty

    float totalUncertainty = 0.0;
    for (unsigned int s = 0 ; s < systematicsTagList.size() ; s++)
    {
        string systematic = systematicsTagList[s];
        float u = systematicsUncertainties.Get("absolute",systematic).value();
        totalUncertainty += u*u;
    }
    totalUncertainty = sqrt(totalUncertainty);
    systematicsUncertainties.Set("absolute","total",Figure(totalUncertainty,0.0));

    predictionTable.Set("prediction", "totalSM", Figure(yieldNominal, totalUncertainty));

    // Fill relative uncertainty from absolute

    for (unsigned int s = 0 ; s < systematicsTagList.size() ; s++)
    {
        string systematic = systematicsTagList[s];
        float relUncertainty = systematicsUncertainties.Get("absolute",systematic).value() / yieldNominal;
        if (yieldNominal == 0.0) relUncertainty = 0;
        systematicsUncertainties.Set("relative",systematic,Figure(relUncertainty,0.0));
    }

    // Fill scale factor table

    scaleFactorTable.Set("value","SF_pre",     SF_pre);
    scaleFactorTable.Set("value","SF_post",    SF_post);
    scaleFactorTable.Set("value","SF_0btag",   SF_0btag);
    scaleFactorTable.Set("value","SF_vetopeak",SF_vetopeak);
    #ifdef USING_MT_TAIL_CORRECTION_FROM_TEMPLATE_FIT_METHOD
    scaleFactorTable.Set("value","SF_MTtail_Wjets", SF_MTtail_Wjets);
    scaleFactorTable.Set("value","SF_MTtail_1ltop", SF_MTtail_1ltop);
    #else
    scaleFactorTable.Set("value","SFR_W+jets", SFR_Wjets_mean);
    scaleFactorTable.Set("value","R_W+jets",   R_Wjets_corrected);
    scaleFactorTable.Set("value","R_1ltop",    R_1ltop_mean);
    #endif
    scaleFactorTable.Print("scaleFactors/"+signalRegionLabel+".tab",4);

}