//------------------------------------------------------------------------------ std::pair<float,float> PlotAlignmentValidation::fitGauss(TH1 *hist,int color) { //1. fits a Gauss function to the inner range of abs(2 rms) //2. repeates the Gauss fit in a 2 sigma range around mean of first fit //returns mean and sigma from fit in micron std::pair<float,float> fitResult(9999., 9999.); if (!hist || hist->GetEntries() < 20) return fitResult; float mean = hist->GetMean(); float sigma = hist->GetRMS(); TF1 func("tmp", "gaus", mean - 2.*sigma, mean + 2.*sigma); func.SetLineColor(color); func.SetLineStyle(2); if (0 == hist->Fit(&func,"QNR")) { // N: do not blow up file by storing fit! mean = func.GetParameter(1); sigma = func.GetParameter(2); // second fit: three sigma of first fit around mean of first fit func.SetRange(mean - 2.*sigma, mean + 2.*sigma); // I: integral gives more correct results if binning is too wide // L: Likelihood can treat empty bins correctly (if hist not weighted...) if (0 == hist->Fit(&func, "Q0ILR")) { if (hist->GetFunction(func.GetName())) { // Take care that it is later on drawn: //hist->GetFunction(func.GetName())->ResetBit(TF1::kNotDraw); } fitResult.first = func.GetParameter(1)*10000;//convert from cm to micron fitResult.second = func.GetParameter(2)*10000;//convert from cm to micron } } return fitResult; }
ASMFitResult ASMModel::fit(const cv::Mat& img, int verbose) { ASMFitResult fitResult(this); // Step 2: Ensure it is a grayscale image Mat grayImg; if (img.channels() == 3){ cv::cvtColor(img, grayImg, CV_BGR2GRAY); } else grayImg = img; // Step 3: Resize each face image Mat resizedImg; // Resize the image to proper size double ratio; ratio = sqrt( double(40000) / (grayImg.rows * grayImg.cols)); cv::resize(grayImg, resizedImg, Size(grayImg.cols*ratio, grayImg.rows*ratio)); ModelImage curSearch; curSearch.setShapeInfo( &shapeInfo ); curSearch.loadTrainImage(resizedImg); fitResult.params = Mat_<double>::zeros(nShapeParams, 1); ShapeVec &sv = curSearch.shapeVec; ShapeVec shape_old; projectParamToShape(fitResult.params, sv); SimilarityTrans st = sv.getShapeTransformFitingSize(resizedImg.size(), searchScaleRatio, searchInitXOffset, searchInitYOffset); fitResult.transformation = st; curSearch.buildFromShapeVec(st); pyramidLevel = 2; int k=localFeatureRad; ns=4; // sum of offsets of current iteration. int totalOffset; if (verbose >= ASM_FIT_VERBOSE_AT_LEVEL) curSearch.show(); // Update each point vector< Point_< int > > V; for (int l=this->pyramidLevel; l>=0; l--){ if (verbose >= ASM_FIT_VERBOSE_AT_LEVEL) printf("Level %d\n", l); Mat_<double> img=curSearch.getDerivImage(l); // printf("Image size: %dx%d\n", img.cols, img.rows); // at most 5 iterations for each level int runT; double avgMov; for (runT=0; runT<10; runT++){ // Backup current shape shape_old.fromPointList(curSearch.points); totalOffset = 0; vector< Point_< int > > bestEP(nMarkPoints); for (int i=0; i<this->nMarkPoints; i++){ if (verbose >= ASM_FIT_VERBOSE_AT_POINT) printf("Dealing point %d...\n", i); Mat_< double > nrmV(2*k+1, 1); double curBest=-1, ct; int bestI = 0; double absSum; for (int e=ns; e>=-ns; e--){ curSearch.getPointsOnNorm(i, k, l, V, 2*searchStepAreaRatio, e); absSum = 0; for (int j=-k;j<=k;j++){ nrmV(j+k, 0) = img(V[j+k]); absSum += fabs(nrmV(j+k, 0)); } nrmV *= 1/absSum; ct = cv::Mahalanobis(nrmV, this->meanG[l][i], this->iCovarG[l][i]); // printf("absSum: %lf, ct: %lf\n", absSum, ct); if (verbose >= ASM_FIT_VERBOSE_AT_POINT) curSearch.show(l, i, true, e); if (ct<curBest || curBest<0){ curBest = ct; bestI = e; bestEP[i] = V[k]; } } // printf("best e: %d\n", bestI); // bestEP[i] = V[bestI+(ns+k)]; totalOffset += abs(bestI); if (verbose >= ASM_FIT_VERBOSE_AT_POINT) curSearch.show(l, i, true, bestI); } for (int i=0;i<nMarkPoints;i++){ curSearch.points[i] = bestEP[i]; curSearch.points[i].x <<= l; if (l>0) curSearch.points[i].x += (1<<(l-1)); curSearch.points[i].y <<= l; if (l>0) curSearch.points[i].y += (1<<(l-1)); } curSearch.shapeVec.fromPointList(curSearch.points); if (verbose >= ASM_FIT_VERBOSE_AT_ITERATION) curSearch.show(l); // Project to PCA model and then back //findParamForShape(curSearch.shapeVec, fitResult); findParamForShapeBTSM(curSearch.shapeVec, shape_old, fitResult, fitResult, l); pcaPyr[l].backProject(fitResult.params, sv); // Reconstruct new shape curSearch.buildFromShapeVec(fitResult.transformation); avgMov = (double)totalOffset/nMarkPoints; if (verbose >= ASM_FIT_VERBOSE_AT_ITERATION){ printf("Iter %d: Average offset: %.3f\n", runT+1, avgMov); curSearch.show(l); } if (avgMov < 1.3){ runT++; break; } } if (verbose == ASM_FIT_VERBOSE_AT_LEVEL){ printf("%d iterations. average offset for last iter: %.3f\n", runT, avgMov); curSearch.show(l); } } SimilarityTrans s2; s2.a = 1/ratio; fitResult.transformation = s2 * fitResult.transformation; return fitResult; }
bool fitCharmoniaMassModel( RooWorkspace& myws, // Local Workspace const RooWorkspace& inputWorkspace, // Workspace with all the input RooDatasets struct KinCuts& cut, // Variable containing all kinematic cuts map<string, string>& parIni, // Variable containing all initial parameters struct InputOpt& opt, // Variable with run information (kept for legacy purpose) string outputDir, // Path to output directory // Select the type of datasets to fit string DSTAG, // Specifies the type of datasets: i.e, DATA, MCJPSINP, ... bool isPbPb = false, // isPbPb = false for pp, true for PbPb bool importDS = true, // Select if the dataset is imported in the local workspace // Select the type of object to fit bool incJpsi = true, // Includes Jpsi model bool incPsi2S = true, // Includes Psi(2S) model bool incBkg = true, // Includes Background model // Select the fitting options bool doFit = true, // Flag to indicate if we want to perform the fit bool cutCtau = false, // Apply prompt ctau cuts bool doConstrFit = false, // Do constrained fit bool doSimulFit = false, // Do simultaneous fit bool wantPureSMC = false, // Flag to indicate if we want to fit pure signal MC const char* applyCorr ="", // Flag to indicate if we want corrected dataset and which correction uint loadFitResult = false, // Load previous fit results string inputFitDir = "", // Location of the fit results int numCores = 2, // Number of cores used for fitting // Select the drawing options bool setLogScale = true, // Draw plot with log scale bool incSS = false, // Include Same Sign data bool zoomPsi = false, // Zoom Psi(2S) peak on extra pad double binWidth = 0.05, // Bin width used for plotting bool getMeanPT = false // Compute the mean PT (NEED TO FIX) ) { if (DSTAG.find("_")!=std::string::npos) DSTAG.erase(DSTAG.find("_")); // Check if input dataset is MC bool isMC = false; if (DSTAG.find("MC")!=std::string::npos) { if (incJpsi && incPsi2S) { cout << "[ERROR] We can only fit one type of signal using MC" << endl; return false; } isMC = true; } wantPureSMC = (isMC && wantPureSMC); bool cutSideBand = (incBkg && (!incPsi2S && !incJpsi)); bool applyWeight_Corr = ( strcmp(applyCorr,"") ); // Define the mass range setMassCutParameters(cut, incJpsi, incPsi2S, isMC); parIni["invMassNorm"] = Form("RooFormulaVar::%s('( -1.0 + 2.0*( @0 - @1 )/( @2 - @1) )', {%s, mMin[%.6f], mMax[%.6f]})", "invMassNorm", "invMass", cut.dMuon.M.Min, cut.dMuon.M.Max ); // Apply the ctau cuts to reject non-prompt charmonia if (cutCtau) { setCtauCuts(cut, isPbPb); } string COLL = (isPbPb ? "PbPb" : "PP" ); string plotLabelPbPb, plotLabelPP; if (doSimulFit || !isPbPb) { // Set models based on initial parameters struct OniaModel model; if (!setMassModel(model, parIni, false, incJpsi, incPsi2S, incBkg)) { return false; } // Import the local datasets double numEntries = 1000000; string label = ((DSTAG.find("PP")!=std::string::npos) ? DSTAG.c_str() : Form("%s_%s", DSTAG.c_str(), "PP")); if (wantPureSMC) label += "_NoBkg"; if (applyWeight_Corr) label += Form("_%s",applyCorr); string dsName = Form("dOS_%s", label.c_str()); if (importDS) { if ( !(myws.data(dsName.c_str())) ) { int importID = importDataset(myws, inputWorkspace, cut, label, cutSideBand); if (importID<0) { return false; } else if (importID==0) { doFit = false; } } numEntries = myws.data(dsName.c_str())->sumEntries(); if (numEntries<=0) { doFit = false; } } else if (doFit && !(myws.data(dsName.c_str()))) { cout << "[ERROR] No local dataset was found to perform the fit!" << endl; return false; } if (myws.data(dsName.c_str())) numEntries = myws.data(dsName.c_str())->sumEntries(); // Set global parameters setMassGlobalParameterRange(myws, parIni, cut, incJpsi, incPsi2S, incBkg, wantPureSMC); // Build the Fit Model if (!buildCharmoniaMassModel(myws, model.PP, parIni, false, doConstrFit, doSimulFit, incBkg, incJpsi, incPsi2S, numEntries)) { return false; } // Define plot names if (incJpsi) { plotLabelPP += Form("_Jpsi_%s", parIni["Model_Jpsi_PP"].c_str()); } if (incPsi2S) { plotLabelPP += Form("_Psi2S_%s", parIni["Model_Psi2S_PP"].c_str()); } if (incBkg) { plotLabelPP += Form("_Bkg_%s", parIni["Model_Bkg_PP"].c_str()); } if (wantPureSMC) plotLabelPP +="_NoBkg"; if (applyWeight_Corr) plotLabelPP +=Form("_%s",applyCorr); } if (doSimulFit || isPbPb) { // Set models based on initial parameters struct OniaModel model; if (!setMassModel(model, parIni, true, incJpsi, incPsi2S, incBkg)) { return false; } // Import the local datasets double numEntries = 1000000; string label = ((DSTAG.find("PbPb")!=std::string::npos) ? DSTAG.c_str() : Form("%s_%s", DSTAG.c_str(), "PbPb")); if (wantPureSMC) label += "_NoBkg"; if (applyWeight_Corr) label += Form("_%s",applyCorr); string dsName = Form("dOS_%s", label.c_str()); if (importDS) { if ( !(myws.data(dsName.c_str())) ) { int importID = importDataset(myws, inputWorkspace, cut, label, cutSideBand); if (importID<0) { return false; } else if (importID==0) { doFit = false; } } numEntries = myws.data(dsName.c_str())->sumEntries(); if (numEntries<=0) { doFit = false; } } else if (doFit && !(myws.data(dsName.c_str()))) { cout << "[ERROR] No local dataset was found to perform the fit!" << endl; return false; } if (myws.data(dsName.c_str())) numEntries = myws.data(dsName.c_str())->sumEntries(); // Set global parameters setMassGlobalParameterRange(myws, parIni, cut, incJpsi, incPsi2S, incBkg, wantPureSMC); // Build the Fit Model if (!buildCharmoniaMassModel(myws, model.PbPb, parIni, true, doConstrFit, doSimulFit, incBkg, incJpsi, incPsi2S, numEntries)) { return false; } // Define plot names if (incJpsi) { plotLabelPbPb += Form("_Jpsi_%s", parIni["Model_Jpsi_PbPb"].c_str()); } if (incPsi2S) { plotLabelPbPb += Form("_Psi2S_%s", parIni["Model_Psi2S_PbPb"].c_str()); } if (incBkg) { plotLabelPbPb += Form("_Bkg_%s", parIni["Model_Bkg_PbPb"].c_str()); } if (wantPureSMC) plotLabelPbPb += "_NoBkg"; if (applyWeight_Corr) plotLabelPbPb += Form("_%s",applyCorr); } if (doSimulFit) { // Create the combided datasets RooCategory* sample = new RooCategory("sample","sample"); sample->defineType("PbPb"); sample->defineType("PP"); RooDataSet* combData = new RooDataSet("combData","combined data", *myws.var("invMass"), Index(*sample), Import("PbPb", *((RooDataSet*)myws.data("dOS_DATA_PbPb"))), Import("PP", *((RooDataSet*)myws.data("dOS_DATA_PP"))) ); myws.import(*sample); // Create the combided models RooSimultaneous* simPdf = new RooSimultaneous("simPdf", "simultaneous pdf", *sample); simPdf->addPdf(*myws.pdf("pdfMASS_Tot_PbPb"), "PbPb"); simPdf->addPdf(*myws.pdf("pdfMASS_Tot_PP"), "PP"); myws.import(*simPdf); // check if we have already done this fit. If yes, do nothing and return true. string FileName = ""; setMassFileName(FileName, (inputFitDir=="" ? outputDir : inputFitDir), DSTAG, (plotLabelPP + plotLabelPbPb), cut, isPbPb, cutSideBand, doSimulFit); if (gSystem->AccessPathName(FileName.c_str()) && inputFitDir!="") { cout << "[WARNING] User Input File : " << FileName << " was not found!" << endl; if (loadFitResult) return false; setMassFileName(FileName, outputDir, DSTAG, (plotLabelPP + plotLabelPbPb), cut, isPbPb, cutSideBand, doSimulFit); } bool found = true; bool skipFit = !doFit; RooArgSet *newpars = myws.pdf("simPdf")->getParameters(*(myws.var("invMass"))); myws.saveSnapshot("simPdf_parIni", *newpars, kTRUE); found = found && isFitAlreadyFound(newpars, FileName, "simPdf"); if (loadFitResult) { if ( loadPreviousFitResult(myws, FileName, DSTAG, false, (!isMC && !cutSideBand && loadFitResult==1), loadFitResult==1) ) { skipFit = true; } else { skipFit = false; } if ( loadPreviousFitResult(myws, FileName, DSTAG, true, (!isMC && !cutSideBand && loadFitResult==1), loadFitResult==1) ) { skipFit = true; } else { skipFit = false; } if (skipFit) { cout << "[INFO] This simultaneous mass fit was already done, so I'll load the fit results." << endl; } myws.saveSnapshot("simPdf_parLoad", *newpars, kTRUE); } else if (found) { cout << "[INFO] This simultaneous mass fit was already done, so I'll just go to the next one." << endl; return true; } // Do the simultaneous fit if (skipFit==false) { RooFitResult* fitResult = simPdf->fitTo(*combData, Offset(kTRUE), Extended(kTRUE), NumCPU(numCores), Range("MassWindow"), Save()); //, Minimizer("Minuit2","Migrad") fitResult->Print("v"); myws.import(*fitResult, "fitResult_simPdf"); // Create the output files int nBins = min(int( round((cut.dMuon.M.Max - cut.dMuon.M.Min)/binWidth) ), 1000); drawMassPlot(myws, outputDir, opt, cut, parIni, plotLabelPP, DSTAG, false, incJpsi, incPsi2S, incBkg, cutCtau, doSimulFit, false, setLogScale, incSS, zoomPsi, nBins, getMeanPT); drawMassPlot(myws, outputDir, opt, cut, parIni, plotLabelPbPb, DSTAG, true, incJpsi, incPsi2S, incBkg, cutCtau, doSimulFit, false, setLogScale, incSS, zoomPsi, nBins, getMeanPT); // Save the results string FileName = ""; setMassFileName(FileName, outputDir, DSTAG, (plotLabelPP + plotLabelPbPb), cut, isPbPb, cutSideBand, doSimulFit); myws.saveSnapshot("simPdf_parFit", *newpars, kTRUE); saveWorkSpace(myws, Form("%smass%s/%s/result", outputDir.c_str(), (cutSideBand?"SB":""), DSTAG.c_str()), FileName); // Delete the objects used during the simultaneous fit delete sample; delete combData; delete simPdf; } } else { // Define pdf and plot names string pdfName = Form("pdfMASS_Tot_%s", COLL.c_str()); string plotLabel = (isPbPb ? plotLabelPbPb : plotLabelPP); // Import the local datasets string label = ((DSTAG.find(COLL.c_str())!=std::string::npos) ? DSTAG.c_str() : Form("%s_%s", DSTAG.c_str(), COLL.c_str())); if (wantPureSMC) label += "_NoBkg"; if (applyWeight_Corr) label += Form("_%s",applyCorr); string dsName = Form("dOS_%s", label.c_str()); // check if we have already done this fit. If yes, do nothing and return true. string FileName = ""; setMassFileName(FileName, (inputFitDir=="" ? outputDir : inputFitDir), DSTAG, plotLabel, cut, isPbPb, cutSideBand); if (gSystem->AccessPathName(FileName.c_str()) && inputFitDir!="") { cout << "[WARNING] User Input File : " << FileName << " was not found!" << endl; if (loadFitResult) return false; setMassFileName(FileName, outputDir, DSTAG, plotLabel, cut, isPbPb, cutSideBand); } bool found = true; bool skipFit = !doFit; RooArgSet *newpars = myws.pdf(pdfName.c_str())->getParameters(*(myws.var("invMass"))); found = found && isFitAlreadyFound(newpars, FileName, pdfName.c_str()); if (loadFitResult) { if ( loadPreviousFitResult(myws, FileName, DSTAG, isPbPb, (!isMC && !cutSideBand && loadFitResult==1), loadFitResult==1) ) { skipFit = true; } else { skipFit = false; } if (skipFit) { cout << "[INFO] This mass fit was already done, so I'll load the fit results." << endl; } myws.saveSnapshot(Form("%s_parLoad", pdfName.c_str()), *newpars, kTRUE); } else if (found) { cout << "[INFO] This mass fit was already done, so I'll just go to the next one." << endl; return true; } // Fit the Datasets if (skipFit==false) { bool isWeighted = myws.data(dsName.c_str())->isWeighted(); RooFitResult* fitResult(0x0); if (doConstrFit) { cout << "[INFO] Performing constrained fit" << endl; if (isPbPb) { cout << "[INFO] Constrained variables: alpha, n, ratio of sigmas" << endl; fitResult = myws.pdf(pdfName.c_str())->fitTo(*myws.data(dsName.c_str()), Extended(kTRUE), SumW2Error(isWeighted), Range(cutSideBand ? parIni["BkgMassRange_FULL_Label"].c_str() : "MassWindow"), ExternalConstraints(RooArgSet(*(myws.pdf("sigmaAlphaConstr")),*(myws.pdf("sigmaNConstr")),*(myws.pdf("sigmaRSigmaConstr")))), NumCPU(numCores), Save()); } else { cout << "[INFO] Constrained variables: alpha, n, ratio of sigmas" << endl; fitResult = myws.pdf(pdfName.c_str())->fitTo(*myws.data(dsName.c_str()), Extended(kTRUE), SumW2Error(isWeighted), Range(cutSideBand ? parIni["BkgMassRange_FULL_Label"].c_str() : "MassWindow"), ExternalConstraints(RooArgSet(*(myws.pdf("sigmaAlphaConstr")),*(myws.pdf("sigmaNConstr")))), NumCPU(numCores), Save()); } } else { fitResult = myws.pdf(pdfName.c_str())->fitTo(*myws.data(dsName.c_str()), Extended(kTRUE), SumW2Error(isWeighted), Range(cutSideBand ? parIni["BkgMassRange_FULL_Label"].c_str() : "MassWindow"), NumCPU(numCores), Save()); } fitResult->Print("v"); myws.import(*fitResult, Form("fitResult_%s", pdfName.c_str())); // Create the output files int nBins = min(int( round((cut.dMuon.M.Max - cut.dMuon.M.Min)/binWidth) ), 1000); drawMassPlot(myws, outputDir, opt, cut, parIni, plotLabel, DSTAG, isPbPb, incJpsi, incPsi2S, incBkg, cutCtau, doSimulFit, wantPureSMC, setLogScale, incSS, zoomPsi, nBins, getMeanPT); // Save the results string FileName = ""; setMassFileName(FileName, outputDir, DSTAG, plotLabel, cut, isPbPb, cutSideBand); myws.saveSnapshot(Form("%s_parFit", pdfName.c_str()), *newpars, kTRUE); saveWorkSpace(myws, Form("%smass%s/%s/result", outputDir.c_str(), (cutSideBand?"SB":""), DSTAG.c_str()), FileName); } } return true; };