Example #1
0
std::string StackLocation::format() const
{
    std::stringstream ret;

    ret << "[";
    if (isNull()) {
        ret << "NULL";
    } else {
        if (isStackMemory()) {
            if (isRegisterHeight()) {
                ret << _off << ", " << _reg.name();
            }
            else {
                ret << _off << ", size " << _size;
            }
        } else {
            ret << _reg.name() << ", size " << _size;
        }
        ret << ", is " << StackAccess::printStackAccessType(_type);
        ret << ", valid = " << printRanges(_valid);
    }
    ret << "]";

    return ret.str();
}
Example #2
0
int 
itest8(int flag)
{
  int n=0;
  MsgStr errMsg;
  ValueVector ranges;
  size_t nRanges;
  htmSqlInterface htm(6);
  char domain[100] = "DOMAIN 6 1 2 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0";

  /* Example of domain */
  nRanges = htm.domain(domain,ranges);
  if(htm.err())
    cout << htm.error() << endl;
  else
    printRanges(domain, nRanges,ranges,flag);

  n = (nRanges != 2);
  return showtest("iTest8 (domain#1)",n,flag);
}
Example #3
0
int 
itest9(int flag)
{
  int n=0;
  MsgStr errMsg;
  ValueVector ranges;
  size_t nRanges;
  htmSqlInterface htm(6);

  char domain[100] ="DOMAIN 1 2 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0";

  /* Generic interface */
  nRanges = htm.intersect2(domain, ranges);
  if(htm.err())
    cout << htm.error() << endl;
  else
    printRanges(domain, nRanges,ranges,flag);
		
  n = (nRanges != 2);
  return showtest("iTest9 (domain#2)",n,flag);
}
Example #4
0
int 
itest6(int flag)
{
  int n=0;
  MsgStr errMsg;
  ValueVector ranges;
  size_t nRanges;
  htmSqlInterface htm(6);
  char hull[100]	 = "J2000 6 41.4 47.9 41.2.47.9 41.0 47.5 41.4 48";

  /* Example of convex hull */

  nRanges = htm.convexHull(hull,ranges);
  if(htm.err())
    cout << htm.error() << endl;
  else
    printRanges(hull,nRanges,ranges,flag);

  n = (nRanges != 9);
  return showtest("iTest6 (cHull#1)",n,flag);
}
Example #5
0
int 
itest5(int flag)
{
  int n=0;
  MsgStr errMsg;
  ValueVector ranges;
  size_t nRanges;
  htmSqlInterface htm(6);
  char circle[100] = "J2000 6 41.4 47.9 2.0";

  /* Generic interface */

  strcpy(circle,"CIRCLE J2000 6 41.4 47.9 20");
  nRanges = htm.intersect2(circle, ranges);
  if(htm.err())
    cout << htm.error() << endl;
  else {
    printRanges(circle,nRanges,ranges,flag);
  }

  n = (nRanges != 4);
  return showtest("iTest5 (circle#3)",n,flag);
}
Example #6
0
int 
itest4(int flag)
{
  int n=0;
  MsgStr errMsg;
  ValueVector ranges;
  size_t nRanges;
  htmSqlInterface htm(6);
  char circle[100] = "J2000 6 41.4 47.9 8.0";

  /* 2nd Example of circle region */

  nRanges = htm.circleRegion(circle,ranges);

  if(htm.err())
    cout << htm.error() << endl;
  else {
    printRanges(circle,nRanges,ranges,flag);
  }

  n = (nRanges != 2);
  return showtest("iTest4 (circle#2)",n,flag);
}
Example #7
0
int 
itest7(int flag)
{
  int n=0;
  MsgStr errMsg;
  ValueVector ranges;
  size_t nRanges;
  htmSqlInterface htm(6);
  char hull[100] = "CONVEX J2000 1 1 -1 1 -1 -1 1 -1"; // counterclockwise
  //	char hull[100] = "CONVEX J2000 1 1 1 -1 -1 -1 -1 1"; // clockwise
  //	char hull[100] = "CONVEX J2000 1 1 -1 -1 -1 1 1 -1"; // diag + cw
  //	char hull[100] = "CONVEX J2000 1 1 -1 -1 1 -1 -1 1"; // diag+ccw

  /* Generic interface */
  nRanges = htm.intersect2(hull, ranges);
  if(htm.err())
    cout << htm.error() << endl;
  else
    printRanges(hull,nRanges,ranges,flag);

  n = (nRanges != 9);
  n = 0;
  return showtest("iTest7 (cHull#2)",n,flag);
}
Example #8
0
int 
itest3(int flag)
{
  int n=0;

  MsgStr errMsg;
  ValueVector ranges;
  size_t nRanges;
  htmSqlInterface htm(6);
  char circle[100] = "J2000 6 41.4 47.9 2.0";

  /* 1st Example of circle region */

  errMsg = htm.circleRegionDiagnostic(circle);

  if(errMsg.empty()) {
    nRanges = htm.circleRegion(circle,ranges);
    printRanges(circle,nRanges,ranges,flag);
  } else
    cout << errMsg;

  n = (nRanges != 2);
  return showtest("iTest3 (circle#1)",n,flag);
}
//------------------------------------------------------------------------
//
//   build          Build the list of non-overlapping character ranges
//                  from the Unicode Sets.
//
//------------------------------------------------------------------------
void RBBISetBuilder::build() {
    RBBINode        *usetNode;
    RangeDescriptor *rlRange;

    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "usets")) {printSets();}

    //
    //  Initialize the process by creating a single range encompassing all characters
    //  that is in no sets.
    //
    fRangeList                = new RangeDescriptor(*fStatus); // will check for status here
    fRangeList->fStartChar    = 0;
    fRangeList->fEndChar      = 0x10ffff;

    if (U_FAILURE(*fStatus)) {
        return;
    }

    //
    //  Find the set of non-overlapping ranges of characters
    //
    int  ni;
    for (ni=0; ; ni++) {        // Loop over each of the UnicodeSets encountered in the input rules
        usetNode = (RBBINode *)this->fRB->fUSetNodes->elementAt(ni);
        if (usetNode==NULL) {
            break;
        }

        UnicodeSet      *inputSet             = usetNode->fInputSet;
        int32_t          inputSetRangeCount   = inputSet->getRangeCount();
        int              inputSetRangeIndex   = 0;
                         rlRange              = fRangeList;

        for (;;) {
            if (inputSetRangeIndex >= inputSetRangeCount) {
                break;
            }
            UChar32      inputSetRangeBegin  = inputSet->getRangeStart(inputSetRangeIndex);
            UChar32      inputSetRangeEnd    = inputSet->getRangeEnd(inputSetRangeIndex);

            // skip over ranges from the range list that are completely
            //   below the current range from the input unicode set.
            while (rlRange->fEndChar < inputSetRangeBegin) {
                rlRange = rlRange->fNext;
            }

            // If the start of the range from the range list is before with
            //   the start of the range from the unicode set, split the range list range
            //   in two, with one part being before (wholly outside of) the unicode set
            //   and the other containing the rest.
            //   Then continue the loop; the post-split current range will then be skipped
            //     over
            if (rlRange->fStartChar < inputSetRangeBegin) {
                rlRange->split(inputSetRangeBegin, *fStatus);
                if (U_FAILURE(*fStatus)) {
                    return;
                }
                continue;
            }

            // Same thing at the end of the ranges...
            // If the end of the range from the range list doesn't coincide with
            //   the end of the range from the unicode set, split the range list
            //   range in two.  The first part of the split range will be
            //   wholly inside the Unicode set.
            if (rlRange->fEndChar > inputSetRangeEnd) {
                rlRange->split(inputSetRangeEnd+1, *fStatus);
                if (U_FAILURE(*fStatus)) {
                    return;
                }
            }

            // The current rlRange is now entirely within the UnicodeSet range.
            // Add this unicode set to the list of sets for this rlRange
            if (rlRange->fIncludesSets->indexOf(usetNode) == -1) {
                rlRange->fIncludesSets->addElement(usetNode, *fStatus);
                if (U_FAILURE(*fStatus)) {
                    return;
                }
            }

            // Advance over ranges that we are finished with.
            if (inputSetRangeEnd == rlRange->fEndChar) {
                inputSetRangeIndex++;
            }
            rlRange = rlRange->fNext;
        }
    }

    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "range")) { printRanges();}

    //
    //  Group the above ranges, with each group consisting of one or more
    //    ranges that are in exactly the same set of original UnicodeSets.
    //    The groups are numbered, and these group numbers are the set of
    //    input symbols recognized by the run-time state machine.
    //
    //    Numbering: # 0  (state table column 0) is unused.
    //               # 1  is reserved - table column 1 is for end-of-input
    //               # 2  is reserved - table column 2 is for beginning-in-input
    //               # 3  is the first range list.
    //
    RangeDescriptor *rlSearchRange;
    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
        for (rlSearchRange=fRangeList; rlSearchRange != rlRange; rlSearchRange=rlSearchRange->fNext) {
            if (rlRange->fIncludesSets->equals(*rlSearchRange->fIncludesSets)) {
                rlRange->fNum = rlSearchRange->fNum;
                break;
            }
        }
        if (rlRange->fNum == 0) {
            fGroupCount ++;
            rlRange->fNum = fGroupCount+2; 
            rlRange->setDictionaryFlag();
            addValToSets(rlRange->fIncludesSets, fGroupCount+2);
        }
    }

    // Handle input sets that contain the special string {eof}.
    //   Column 1 of the state table is reserved for EOF on input.
    //   Column 2 is reserved for before-the-start-input.
    //            (This column can be optimized away later if there are no rule
    //             references to {bof}.)
    //   Add this column value (1 or 2) to the equivalent expression
    //     subtree for each UnicodeSet that contains the string {eof}
    //   Because {bof} and {eof} are not a characters in the normal sense,
    //   they doesn't affect the computation of ranges or TRIE.
    static const UChar eofUString[] = {0x65, 0x6f, 0x66, 0};
    static const UChar bofUString[] = {0x62, 0x6f, 0x66, 0};

    UnicodeString eofString(eofUString);
    UnicodeString bofString(bofUString);
    for (ni=0; ; ni++) {        // Loop over each of the UnicodeSets encountered in the input rules
        usetNode = (RBBINode *)this->fRB->fUSetNodes->elementAt(ni);
        if (usetNode==NULL) {
            break;
        }
        UnicodeSet      *inputSet = usetNode->fInputSet;
        if (inputSet->contains(eofString)) {
            addValToSet(usetNode, 1);
        }
        if (inputSet->contains(bofString)) {
            addValToSet(usetNode, 2);
            fSawBOF = TRUE;
        }
    }


    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "rgroup")) {printRangeGroups();}
    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "esets")) {printSets();}

    //
    // Build the Trie table for mapping UChar32 values to the corresponding
    //   range group number
    //
    fTrie = utrie_open(NULL,    //  Pre-existing trie to be filled in
                      NULL,    //  Data array  (utrie will allocate one)
                      100000,  //  Max Data Length
                      0,       //  Initial value for all code points
                      0,       //  Lead surrogate unit value
                      TRUE);   //  Keep Latin 1 in separately


    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
        utrie_setRange32(fTrie, rlRange->fStartChar, rlRange->fEndChar+1, rlRange->fNum, TRUE);
    }
}
Example #10
0
//------------------------------------------------------------------------
//
//   build          Build the list of non-overlapping character ranges
//                  from the Unicode Sets.
//
//------------------------------------------------------------------------
void RBBISetBuilder::build() {
    RBBINode        *usetNode;
    RangeDescriptor *rlRange;

    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "usets")) {
        printSets();
    }

    //
    //  Initialize the process by creating a single range encompassing all characters
    //  that is in no sets.
    //
    fRangeList                = new RangeDescriptor(*fStatus); // will check for status here
    fRangeList->fStartChar    = 0;
    fRangeList->fEndChar      = 0x10ffff;

    if (U_FAILURE(*fStatus)) {
        return;
    }

    //
    //  Find the set of non-overlapping ranges of characters
    //
    int  ni;
    for (ni=0; ; ni++) {
        usetNode = (RBBINode *)this->fRB->fUSetNodes->elementAt(ni);
        if (usetNode==NULL) {
            break;
        }

        UnicodeSet      *inputSet             = usetNode->fInputSet;
        int32_t          inputSetRangeCount   = inputSet->getRangeCount();
        int              inputSetRangeIndex   = 0;
        rlRange              = fRangeList;

        for (;;) {
            if (inputSetRangeIndex >= inputSetRangeCount) {
                break;
            }
            UChar32      inputSetRangeBegin  = inputSet->getRangeStart(inputSetRangeIndex);
            UChar32      inputSetRangeEnd    = inputSet->getRangeEnd(inputSetRangeIndex);

            // skip over ranges from the range list that are completely
            //   below the current range from the input unicode set.
            while (rlRange->fEndChar < inputSetRangeBegin) {
                rlRange = rlRange->fNext;
            }

            // If the start of the range from the range list is before with
            //   the start of the range from the unicode set, split the range list range
            //   in two, with one part being before (wholly outside of) the unicode set
            //   and the other containing the rest.
            //   Then continue the loop; the post-split current range will then be skipped
            //     over
            if (rlRange->fStartChar < inputSetRangeBegin) {
                rlRange->split(inputSetRangeBegin, *fStatus);
                if (U_FAILURE(*fStatus)) {
                    return;
                }
                continue;
            }

            // Same thing at the end of the ranges...
            // If the end of the range from the range list doesn't coincide with
            //   the end of the range from the unicode set, split the range list
            //   range in two.  The first part of the split range will be
            //   wholly inside the Unicode set.
            if (rlRange->fEndChar > inputSetRangeEnd) {
                rlRange->split(inputSetRangeEnd+1, *fStatus);
                if (U_FAILURE(*fStatus)) {
                    return;
                }
            }

            // The current rlRange is now entirely within the UnicodeSet range.
            // Add this unicode set to the list of sets for this rlRange
            if (rlRange->fIncludesSets->indexOf(usetNode) == -1) {
                rlRange->fIncludesSets->addElement(usetNode, *fStatus);
                if (U_FAILURE(*fStatus)) {
                    return;
                }
            }

            // Advance over ranges that we are finished with.
            if (inputSetRangeEnd == rlRange->fEndChar) {
                inputSetRangeIndex++;
            }
            rlRange = rlRange->fNext;
        }
    }

    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "range")) {
        printRanges();
    }

    //
    //  Group the above ranges, with each group consisting of one or more
    //    ranges that are in exactly the same set of original UnicodeSets.
    //    The groups are numbered, and these group numbers are the set of
    //    input symbols recognized by the run-time state machine.
    //
    RangeDescriptor *rlSearchRange;
    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
        for (rlSearchRange=fRangeList; rlSearchRange != rlRange; rlSearchRange=rlSearchRange->fNext) {
            if (rlRange->fIncludesSets->equals(*rlSearchRange->fIncludesSets)) {
                rlRange->fNum = rlSearchRange->fNum;
                break;
            }
        }
        if (rlRange->fNum == 0) {
            fGroupCount ++;
            rlRange->fNum = fGroupCount;
            rlRange->setDictionaryFlag();
            addValToSets(rlRange->fIncludesSets, fGroupCount);
        }
    }

    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "rgroup")) {
        printRangeGroups();
    }
    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "esets")) {
        printSets();
    }

    //
    // Build the Trie table for mapping UChar32 values to the corresponding
    //   range group number
    //
    fTrie = utrie_open(NULL,    //  Pre-existing trie to be filled in
                       NULL,    //  Data array  (utrie will allocate one)
                       100000,  //  Max Data Length
                       0,       //  Initial value for all code points
                       0,       //  Lead surrogate unit value
                       TRUE);   //  Keep Latin 1 in separately


    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
        utrie_setRange32(fTrie, rlRange->fStartChar, rlRange->fEndChar+1, rlRange->fNum, TRUE);
    }
}
Example #11
0
void simplePlot2D(){
	
	///gROOT->ProcessLine(".x paperStyle.C");
	
	gStyle->SetCanvasDefH(600); //Height of canvas
	gStyle->SetCanvasDefW(640); //Width of canvas
	gStyle->SetCanvasDefX(0);   //POsition on screen
	gStyle->SetCanvasDefY(0);

	gStyle->SetPadLeftMargin(0.125);//0.16);
	gStyle->SetPadRightMargin(0.165);//0.02);
	gStyle->SetPadTopMargin(0.085);//0.02);
	gStyle->SetPadBottomMargin(0.12);//0.02);

	  // For g axis titles:
	gStyle->SetTitleColor(1, "XYZ");
	gStyle->SetTitleFont(42, "XYZ");
	gStyle->SetTitleSize(0.045, "Z");
	gStyle->SetTitleSize(0.055, "XY");
	gStyle->SetTitleXOffset(1.0);//0.9);
	gStyle->SetTitleYOffset(1.12); // => 1.15 if exponents

	// For g axis labels:
	gStyle->SetLabelColor(1, "XYZ");
	gStyle->SetLabelFont(42, "XYZ");
	gStyle->SetLabelOffset(0.007, "XYZ");
	gStyle->SetLabelSize(0.04, "XYZ");

	// Legends
	gStyle->SetLegendBorderSize(0);
	gStyle->SetLegendFillColor(kWhite);
	gStyle->SetLegendFont(42);

	gStyle->SetOptStat(0);
	//gStyle->SetPalette(51);

        /* 
	// Fewer colors, one band per 0.1 
	// *************************************************************
	 int ncontours = 10; 
	 double stops[6]   = {0.0 , .2,   .4,   .6,    .8,    1};  
	 double blue[6]    = {1.0 ,  1,    1,    1,     1,    1}; 
	 double green[6]   = {0.1,  0.3,  0.5,  0.72,   0.82, 1}; 
	 double red [6]    = {0.1,  0.2,  0.24, 0.45,   0.7,  1}; 
	 
	 int npoints = 6; 
	 TColor::CreateGradientColorTable(npoints, stops, red, green, blue, ncontours); 
	 gStyle->SetNumberContours(ncontours); 
	//gStyle->SetPalette(kCherry);
	// *************************************************************
	*/

	// *************************************************************
	 int ncontours = 15; 
	 double stops[5]   = {0.0 ,  .1,   .25    , .5     , 1    };  
	 double blue[5]    = {1.0 ,  1.  , 1  , 1     , 1.00   }; 
	 double green[5]   = {0.25 , 0.3 ,   0.5  , 0.75    , 1.00   }; 
	 double red [5]    = {0.1,  0.15 ,   0.4 , 0.6     , 1.00   }; 
	 
	 int npoints = 5; 
	 TColor::CreateGradientColorTable(npoints, stops, red, green, blue, ncontours); 
	 gStyle->SetNumberContours(ncontours); 
	// *************************************************************

	TFile *fi = TFile::Open("allpoints.root");
	TTree *tree = (TTree*)fi->Get("limit");



	TH2D expected(grKappa(tree,-1));
	TH2D dummyK("dummyK","dummy",1,KVMIN,KVMAX,1,KFMIN,KFMAX);
	dummyK.SetTitle("");
	dummyK.GetZaxis()->SetTitleOffset(1.2);
	dummyK.GetYaxis()->SetTitle("#it{#kappa}_{F}");
	dummyK.GetXaxis()->SetTitle("#it{#kappa}_{V}");
	//dummyK.GetXaxis()->SetRangeUser(KVMIN,KVMAX);
	//dummyK.GetYaxis()->SetRangeUser(KFMIN,KFMAX);
	dummyK.GetZaxis()->SetTitle("B(H #rightarrow inv.) - 95% CL upper limit");
	//dummyK.GetXaxis()->SetLimits(KVMIN,KVMAX);
	//dummyK.GetYaxis()->SetLimits(KFMIN,KFMAX);
	//dummyK.SetMaximum(0.8);
	//dummyK.SetMinimum(0.1);
	
	TCanvas *can = new TCanvas("cc","c",800,720);
	can->cd();
	
	//expected.GetXaxis()->SetRangeUser(KVMIN,KVMAX);
	//expected.GetYaxis()->SetRangeUser(KFMIN,KFMAX);

	TFile *flhc = TFile::Open("scan2d_kappa_V_kappa_F_exp.root");
	TGraph *grlhc_68 = (TGraph*) flhc->Get("graph68_comb_0");
	TGraph *grlhc_95 = (TGraph*) flhc->Get("graph95_comb_0");
	TGraph *grlhc_bf = (TGraph*) flhc->Get("comb_best");
	grlhc_68->SetLineColor(kWhite);
        grlhc_95->SetLineColor(kWhite);
	grlhc_bf->SetMarkerStyle(34);
	grlhc_bf->SetMarkerSize(1.8);
	grlhc_bf->SetMarkerColor(kWhite);

	grlhc_68->SetLineWidth(2);
        grlhc_95->SetLineWidth(2);
        grlhc_95->SetLineStyle(2);

	TH2D *histocomb = (TH2D*)flhc->Get("comb_hist_processed");
	
	double xmin =expected.GetXaxis()->GetXmin();
	double xmax =expected.GetXaxis()->GetXmax();
	double ymin =expected.GetYaxis()->GetXmin();
	double ymax =expected.GetYaxis()->GetXmax();
	TLine SMH(KVMIN,1,KVMAX,1);
	TLine SMV(1,KFMIN,1,KFMAX);
//	TLine SMH(xmin,1,xmax,1);
//	TLine SMV(1,ymin,1,ymax);
	SMH.SetLineColor(2);
	SMH.SetLineStyle(2);
	SMV.SetLineColor(2);
	SMV.SetLineStyle(2);

	//dummyK.Draw("AXIS");
	expected.Draw("colz");
	grlhc_68->Draw("Lsame");
        grlhc_95->Draw("Lsame");
        grlhc_bf->Draw("Psame");

	SMH.Draw("L");
	SMV.Draw("L");
	decorate(can,expected);

	printRanges(&expected,histocomb);

	can->SaveAs("couplings_limits.pdf");
	TFile *fiMU = TFile::Open("allpoints_mu.root");
	TTree *treeMU = (TTree*)fiMU->Get("limit");
	TH2D expectedmu(grMu(treeMU,-1));
	TH2D dummyMu("dummyMu","dummy",1,MUVMIN,MUVMAX,1,MUFMIN,MUFMAX);
	dummyMu.SetTitle("");
	dummyMu.GetZaxis()->SetTitleOffset(1.2);
	dummyMu.GetYaxis()->SetTitle("#it{#mu}_{ggH}");
	dummyMu.GetXaxis()->SetTitle("#it{#mu}_{qqH,VH}");
	dummyMu.GetZaxis()->SetTitle("B(H #rightarrow inv.) - 95% CL upper limit");
	//dummyMu.GetXaxis()->SetRangeUser(MUVMIN,MUVMAX);
	//dummyMu.GetYaxis()->SetRangeUser(MUFMIN,MUFMAX);
	//dummyMu.GetXaxis()->SetLimits(MUVMIN,MUVMAX);
	//dummyMu.GetYaxis()->SetLimits(MUFMIN,MUFMAX);
	//dummyMu.SetMaximum(0.8);
	//dummyMu.SetMinimum(0.1);
	//expectedmu.GetXaxis()->SetRangeUser(KVMIN,KVMAX);
	//expectedmu.GetYaxis()->SetRangeUser(KFMIN,KFMAX);

	xmin =expectedmu.GetXaxis()->GetXmin();
	xmax =expectedmu.GetXaxis()->GetXmax();
	ymin =expectedmu.GetYaxis()->GetXmin();
	ymax =expectedmu.GetYaxis()->GetXmax();

	TLine SM2H(MUVMIN,1,MUVMAX,1);
	TLine SM2V(1,MUFMIN,1,MUFMAX);
	//TLine SM2H(xmin,1,xmax,1);
	//TLine SM2V(1,ymin,1,ymax);
	SM2H.SetLineColor(2);
	SM2H.SetLineStyle(2);
	SM2V.SetLineColor(2);
	SM2V.SetLineStyle(2);

	//dummyMu.Draw("axis");
	expectedmu.Draw("colz");

	TH2D *expectedmuCont = (TH2D*)expectedmu.Clone(); 
	//expectedmuCont->SetName("contours");
	//expectedmuCont->SetContour(15);
	//expectedmuCont->Draw("cont2 same");
	SM2H.Draw("L");
	SM2V.Draw("L");
	decorate(can,expectedmu,false);

	can->SaveAs("mu_limits.pdf");
}
/** @brief Combine given list of instruments to one instrument.
 *
 * Takes a list of @a instruments as argument and combines them to one single
 * new @a output instrument. For this task, it will create a dimension of type
 * given by @a mainDimension in the new instrument and copies the source
 * instruments to those dimension zones.
 *
 * @param instruments - (input) list of instruments that shall be combined,
 *                      they will only be read, so they will be left untouched
 * @param gig - (input/output) .gig file where the new combined instrument shall
 *              be created
 * @param output - (output) on success this pointer will be set to the new
 *                 instrument being created
 * @param mainDimension - the dimension that shall be used to combine the
 *                        instruments
 * @throw RIFF::Exception on any kinds of errors
 */
static void combineInstruments(std::vector<gig::Instrument*>& instruments, gig::File* gig, gig::Instrument*& output, gig::dimension_t mainDimension) {
    output = NULL;

    // divide the individual regions to (probably even smaller) groups of
    // regions, coping with the fact that the source regions of the instruments
    // might have quite different range sizes and start and end points
    RegionGroups groups = groupByRegionIntersections(instruments);
    #if DEBUG_COMBINE_INSTRUMENTS
    std::cout << std::endl << "New regions: " << std::flush;
    printRanges(groups);
    std::cout << std::endl;
    #endif

    if (groups.empty())
        throw gig::Exception(_("No regions found to create a new instrument with."));

    // create a new output instrument
    gig::Instrument* outInstr = gig->AddInstrument();
    outInstr->pInfo->Name = _("NEW COMBINATION");

    // Distinguishing in the following code block between 'horizontal' and
    // 'vertical' regions. The 'horizontal' ones are meant to be the key ranges
    // in the output instrument, while the 'vertical' regions are meant to be
    // the set of source regions that shall be layered to that 'horizontal'
    // region / key range. It is important to know, that the key ranges defined
    // in the 'horizontal' and 'vertical' regions might differ.

    // merge the instruments to the new output instrument
    for (RegionGroups::iterator itGroup = groups.begin();
         itGroup != groups.end(); ++itGroup) // iterate over 'horizontal' / target regions ...
    {
        gig::Region* outRgn = outInstr->AddRegion();
        outRgn->SetKeyRange(itGroup->first.low, itGroup->first.high);
        #if DEBUG_COMBINE_INSTRUMENTS
        printf("---> Start target region %d..%d\n", itGroup->first.low, itGroup->first.high);
        #endif

        // detect the total amount of zones required for the given main
        // dimension to build up this combi for current key range
        int iTotalZones = 0;
        for (RegionGroup::iterator itRgn = itGroup->second.begin();
             itRgn != itGroup->second.end(); ++itRgn)
        {
            gig::Region* inRgn = itRgn->second;
            gig::dimension_def_t* def = inRgn->GetDimensionDefinition(mainDimension);
            iTotalZones += (def) ? def->zones : 1;
        }
        #if DEBUG_COMBINE_INSTRUMENTS
        printf("Required total zones: %d, vertical regions: %d\n", iTotalZones, itGroup->second.size());
        #endif

        // create all required dimensions for this output region
        // (except the main dimension used for separating the individual
        // instruments, we create that particular dimension as next step)
        Dimensions dims = getDimensionsForRegionGroup(itGroup->second);
        // the given main dimension which is used to combine the instruments is
        // created separately after the next code block, and the main dimension
        // should not be part of dims here, because it also used for iterating
        // all dimensions zones, which would lead to this dimensions being
        // iterated twice
        dims.erase(mainDimension);
        {
            std::vector<gig::dimension_t> skipTheseDimensions; // used to prevent a misbehavior (i.e. crash) of the combine algorithm in case one of the source instruments has a dimension with only one zone, which is not standard conform

            for (Dimensions::iterator itDim = dims.begin();
                itDim != dims.end(); ++itDim)
            {
                gig::dimension_def_t def;
                def.dimension = itDim->first; // dimension type
                def.zones = itDim->second.size();
                def.bits = zoneCountToBits(def.zones);
                if (def.zones < 2) {
                    addWarning(
                        "Attempt to create dimension with type=0x%x with only "
                        "ONE zone (because at least one of the source "
                        "instruments seems to have such a velocity dimension "
                        "with only ONE zone, which is odd)! Skipping this "
                        "dimension for now.",
                        (int)itDim->first
                    );
                    skipTheseDimensions.push_back(itDim->first);
                    continue;
                }
                #if DEBUG_COMBINE_INSTRUMENTS
                std::cout << "Adding new regular dimension type=" << std::hex << (int)def.dimension << std::dec << ", zones=" << (int)def.zones << ", bits=" << (int)def.bits << " ... " << std::flush;
                #endif
                outRgn->AddDimension(&def);
                #if DEBUG_COMBINE_INSTRUMENTS
                std::cout << "OK" << std::endl << std::flush;
                #endif
            }
            // prevent the following dimensions to be processed further below
            // (since the respective dimension was not created above)
            for (int i = 0; i < skipTheseDimensions.size(); ++i)
                dims.erase(skipTheseDimensions[i]);
        }

        // create the main dimension (if necessary for current key range)
        if (iTotalZones > 1) {
            gig::dimension_def_t def;
            def.dimension = mainDimension; // dimension type
            def.zones = iTotalZones;
            def.bits = zoneCountToBits(def.zones);
            #if DEBUG_COMBINE_INSTRUMENTS
            std::cout << "Adding new main combi dimension type=" << std::hex << (int)def.dimension << std::dec << ", zones=" << (int)def.zones << ", bits=" << (int)def.bits << " ... " << std::flush;
            #endif
            outRgn->AddDimension(&def);
            #if DEBUG_COMBINE_INSTRUMENTS
            std::cout << "OK" << std::endl << std::flush;
            #endif
        } else {
            dims.erase(mainDimension);
        }

        // for the next task we need to have the current RegionGroup to be
        // sorted by instrument in the same sequence as the 'instruments' vector
        // argument passed to this function (because the std::map behind the
        // 'RegionGroup' type sorts by memory address instead, and that would
        // sometimes lead to the source instruments' region to be sorted into
        // the wrong target layer)
        OrderedRegionGroup currentGroup = sortRegionGroup(itGroup->second, instruments);

        // schedule copying the source dimension regions to the target dimension
        // regions
        CopyAssignSchedule schedule;
        int iDstMainBit = 0;
        for (OrderedRegionGroup::iterator itRgn = currentGroup.begin();
             itRgn != currentGroup.end(); ++itRgn) // iterate over 'vertical' / source regions ...
        {
            gig::Region* inRgn = itRgn->second;
            #if DEBUG_COMBINE_INSTRUMENTS
            printf("[source region of '%s']\n", inRgn->GetParent()->pInfo->Name.c_str());
            #endif

            // determine how many main dimension zones this input region requires
            gig::dimension_def_t* def = inRgn->GetDimensionDefinition(mainDimension);
            const int inRgnMainZones = (def) ? def->zones : 1;

            for (uint iSrcMainBit = 0; iSrcMainBit < inRgnMainZones; ++iSrcMainBit, ++iDstMainBit) {
                scheduleCopyDimensionRegions(
                    outRgn, inRgn, dims, mainDimension,
                    iDstMainBit, iSrcMainBit, &schedule
                );
            }
        }

        // finally copy the scheduled source -> target dimension regions
        for (uint i = 0; i < schedule.size(); ++i) {
            CopyAssignSchedEntry& e = schedule[i];

            // backup the target DimensionRegion's current dimension zones upper
            // limits (because the target DimensionRegion's upper limits are
            // already defined correctly since calling AddDimension(), and the
            // CopyAssign() call next, will overwrite those upper limits
            // unfortunately
            DimensionRegionUpperLimits dstUpperLimits = getDimensionRegionUpperLimits(e.dst);
            DimensionRegionUpperLimits srcUpperLimits = getDimensionRegionUpperLimits(e.src);

            // now actually copy over the current DimensionRegion
            const gig::Region* const origRgn = e.dst->GetParent(); // just for sanity check below
            e.dst->CopyAssign(e.src);
            assert(origRgn == e.dst->GetParent()); // if gigedit is crashing here, then you must update libgig (to at least SVN r2547, v3.3.0.svn10)

            // restore all original dimension zone upper limits except of the
            // velocity dimension, because the velocity dimension zone sizes are
            // allowed to differ for individual DimensionRegions in gig v3
            // format
            //
            // if the main dinension is the 'velocity' dimension, then skip
            // restoring the source's original velocity zone limits, because
            // dealing with merging that is not implemented yet
            // TODO: merge custom velocity splits if main dimension is the velocity dimension (for now equal sized velocity zones are used if mainDim is 'velocity')
            if (srcUpperLimits.count(gig::dimension_velocity) && mainDimension != gig::dimension_velocity) {
                if (!dstUpperLimits.count(gig::dimension_velocity)) {
                    addWarning("Source instrument seems to have a velocity dimension whereas new target instrument doesn't!");
                } else {
                    dstUpperLimits[gig::dimension_velocity] =
                        (e.velocityZone >= e.totalSrcVelocityZones)
                            ? 127 : srcUpperLimits[gig::dimension_velocity];
                }
            }
            restoreDimensionRegionUpperLimits(e.dst, dstUpperLimits);
        }
    }

    // success
    output = outInstr;
}