예제 #1
0
//------------------------------------------------------------------------------
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
};