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(); }
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); }
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); }
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); }
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); }
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); }
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); }
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); } }
//------------------------------------------------------------------------ // // 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); } }
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; }