/** Fit instrument parameters by non Monte Carlo algorithm
    * Requirement:  m_positionFunc should have the best fit result;
   */
  double RefinePowderInstrumentParameters2::execFitParametersNonMC()
  {
    // 1. Set up constraints
    setFunctionParameterFitSetups(m_positionFunc, m_profileParameters);

    // 2. Fit function
    // FIXME powerfit should be a user option before freezing this algorithm
    bool powerfit = false;
    double chi2 = fitFunction(m_positionFunc, m_dataWS, m_wsIndex, powerfit);

    // 2. Summary
    stringstream sumss;
    sumss << "Non-Monte Carlo Results:  Best Chi^2 = " << chi2;
    g_log.notice(sumss.str());

    return chi2;
  }
示例#2
0
bool PluginFit::load(const QString& pluginName)
{
	if (!QFile::exists (pluginName)){
		QMessageBox::critical((ApplicationWindow *)parent(), tr("MantidPlot - File not found"),
				tr("Plugin file: <p><b> %1 </b> <p>not found. Operation aborted!").arg(pluginName));
		return false;
	}

	QLibrary lib(pluginName);
	lib.setAutoUnload(false);

	d_fsimplex = (fit_function_simplex) lib.resolve( "function_d" );
	if (!d_fsimplex){
		QMessageBox::critical((ApplicationWindow *)parent(), tr("MantidPlot - Plugin Error"),
				tr("The plugin does not implement a %1 method necessary for simplex fitting.").arg("function_d"));
		return false;
	}

	d_f = (fit_function) lib.resolve( "function_f" );
	if (!d_f){
		QMessageBox::critical((ApplicationWindow *)parent(), tr("MantidPlot - Plugin Error"),
				tr("The plugin does not implement a %1 method necessary for Levenberg-Marquardt fitting.").arg("function_f"));
		return false;
	}

	d_df = (fit_function_df) lib.resolve( "function_df" );
	if (!d_df){
		QMessageBox::critical((ApplicationWindow *)parent(), tr("MantidPlot - Plugin Error"),
				tr("The plugin does not implement a %1 method necessary for Levenberg-Marquardt fitting.").arg("function_df"));
		return false;
	}

	d_fdf = (fit_function_fdf) lib.resolve( "function_fdf" );
	if (!d_fdf){
		QMessageBox::critical((ApplicationWindow *)parent(), tr("MantidPlot - Plugin Error"),
				tr("The plugin does not implement a %1 method necessary for Levenberg-Marquardt fitting.").arg("function_fdf"));
		return false;
	}

	f_eval = (fitFunctionEval) lib.resolve("function_eval");
	if (!f_eval)
		return false;

	typedef char* (*fitFunc)();
	fitFunc fitFunction = (fitFunc) lib.resolve("parameters");
	if (fitFunction){
		d_param_names = QString(fitFunction()).split(",", QString::SkipEmptyParts);
		d_p = (int)d_param_names.count();
        initWorkspace(d_p);
	} else
		return false;

	fitFunc fitExplain = (fitFunc) lib.resolve("explanations");
	if (fitExplain)
		d_param_explain = QString(fitExplain()).split(",", QString::SkipEmptyParts);
	else
		for (int i=0; i<d_p; i++)
			d_param_explain << "";

	fitFunction = (fitFunc) lib.resolve( "name" );
	setObjectName(QString(fitFunction()));

	fitFunction = (fitFunc) lib.resolve( "function" );
	if (fitFunction)
		d_formula = QString(fitFunction());
	else
		return false;

	return true;
}
void fit(TH1* histogram, double xMin, double xMax, double massValue, std::vector<fitParameterType>& fitParameter)
{
  // create fit variable
  TAxis* xAxis = histogram->GetXaxis();
  if ( xMin < 0. ) xMin = xAxis->GetXmin(); 
  if ( xMax < 0. ) xMax = xAxis->GetXmax(); 
  std::string fitVariableName = Form("%s_fitVariable", histogram->GetName());
  RooRealVar fitVariable(fitVariableName.data(), fitVariableName.data(), xMin, xMax);
   
  // convert histogram to RooFit format
  std::string histogramName_data = Form("%s_data", histogram->GetName());
  RooDataHist histogram_data(histogramName_data.data(), histogramName_data.data(), fitVariable, histogram, 1.0);

  // create product of linear * Heaviside * Gaussian Error function
  std::string svFitLineShapeName_slope = Form("%s_svFitLineShape_slope", histogram->GetName());
  RooRealVar svFitLineShape_slope(svFitLineShapeName_slope.data(), svFitLineShapeName_slope.data(), 2./(massValue*massValue), 0., 1.);
  std::string svFitLineShapeName_offset = Form("%s_svFitLineShape_offset", histogram->GetName());
  RooRealVar svFitLineShape_offset(svFitLineShapeName_offset.data(), svFitLineShapeName_offset.data(), 0., -1., +1.);

  std::string heavisideName_threshold = Form("%s_heaviside_threshold", histogram->GetName());
  RooRealVar heaviside_threshold(heavisideName_threshold.data(), heavisideName_threshold.data(), 0.2*massValue, 1.e-2*massValue, 0.5*massValue);

  std::string sculptingName_bias = Form("%s_sculpting_bias", histogram->GetName());
  RooRealVar sculpting_bias(sculptingName_bias.data(), sculptingName_bias.data(), 0.25*massValue, 0.*massValue, 0.9*massValue);
  std::string sculptingName_width = Form("%s_sculpting_width", histogram->GetName());
  RooRealVar sculpting_width(sculptingName_width.data(), sculptingName_width.data(), 0.1*massValue, 1.e-2*massValue, 1.0*massValue);

  std::string svFitLineShapeName = Form("%s_svFitLineShape", histogram->GetName());
  std::string svFitLineShapeFormula = "(@0*@1 + @2)*0.5*(1.0 + TMath::Sign(+1, @0 - @3))*0.5*(1.0 + TMath::Erf((@0 - @4)/@5))";
  RooArgList svFitLineShapeArgs(fitVariable, 
				svFitLineShape_slope,
				svFitLineShape_offset,
				heaviside_threshold,
				sculpting_bias,
				sculpting_width);
  RooGenericPdf svFitLineShape(svFitLineShapeName.data(), svFitLineShapeName.data(), svFitLineShapeFormula.data(), svFitLineShapeArgs);

  // create Gaussian 
  std::string gaussianName_mean = Form("%s_gaussian_mean", histogram->GetName());
  RooConstVar gaussian_mean(gaussianName_mean.data(), gaussianName_mean.data(), 0.);
  std::string gaussianName_sigma = Form("%s_gaussian_sigma", histogram->GetName());
  RooRealVar gaussian_sigma(gaussianName_sigma.data(), gaussianName_sigma.data(), 0.2*massValue, 1.e-2*massValue, 0.5*massValue);
  std::string gaussianName = Form("%s_gaussian", histogram->GetName());
  RooGaussian gaussian(gaussianName.data(), gaussianName.data(), fitVariable, gaussian_mean, gaussian_sigma);

  // numerically convolute both PDFs using fast Fourier transform
  std::string fitFunctionName = Form("%s_fitFunction", histogram->GetName());
  RooFFTConvPdf fitFunction(fitFunctionName.data(), fitFunctionName.data(), fitVariable, svFitLineShape, gaussian);

  // fit histogram
  fitFunction.fitTo(histogram_data);

  // save fit parameter
  fitParameter.resize(6);
  fitParameter[0] = fitParameterType(&svFitLineShape_slope);
  fitParameter[1] = fitParameterType(&svFitLineShape_offset);
  fitParameter[2] = fitParameterType(&gaussian_sigma);
  fitParameter[3] = fitParameterType(&heaviside_threshold);
  fitParameter[4] = fitParameterType(&sculpting_bias);
  fitParameter[5] = fitParameterType(&sculpting_width);

  // create control plot
  std::string frameTitle = Form("%s_frame", histogram->GetName());
  RooPlot* frame = fitVariable.frame(RooFit::Title(frameTitle.data()));
  histogram_data.plotOn(frame);
  fitFunction.plotOn(frame, RooFit::LineColor(kRed));
  
  std::string canvasName = Form("%s_canvas", histogram->GetName());
  TCanvas* canvas = new TCanvas(canvasName.data(), canvasName.data(), 800, 600);
  gPad->SetLeftMargin(0.15); 
  frame->GetYaxis()->SetTitleOffset(1.4);
  frame->Draw();
    
  std::string outputFileName_plot = Form("svFitPerformance_%s_fit", histogram->GetName());
  canvas->Print(std::string(outputFileName_plot).append(".eps").data());
  canvas->Print(std::string(outputFileName_plot).append(".png").data());
  canvas->Print(std::string(outputFileName_plot).append(".pdf").data());
  
  delete canvas;
}