/** Select background points via a given background function */ void ProcessBackground::selectFromGivenFunction() { // Process properties BackgroundFunction_sptr bkgdfunc = createBackgroundFunction(m_bkgdType); TableWorkspace_sptr bkgdtablews = getProperty("BackgroundTableWorkspace"); // Set up background function from table size_t numrows = bkgdtablews->rowCount(); map<string, double> parmap; for (size_t i = 0; i < numrows; ++i) { TableRow row = bkgdtablews->getRow(i); string parname; double parvalue; row >> parname >> parvalue; if (parname[0] == 'A') parmap.emplace(parname, parvalue); } int bkgdorder = static_cast<int>(parmap.size() - 1); // A0 - A(n) total n+1 parameters bkgdfunc->setAttributeValue("n", bkgdorder); for (auto &mit : parmap) { string parname = mit.first; double parvalue = mit.second; bkgdfunc->setParameter(parname, parvalue); } // Filter out m_outputWS = filterForBackground(bkgdfunc); return; }
/** Select background points via a given background function */ void ProcessBackground::execSelectBkgdPoints2() { // Process properties BackgroundFunction_sptr bkgdfunc = createBackgroundFunction(m_bkgdType); TableWorkspace_sptr bkgdtablews = getProperty("BackgroundTableWorkspace"); // Set up background function from table size_t numrows = bkgdtablews->rowCount(); map<string, double> parmap; for (size_t i = 0; i < numrows; ++i) { TableRow row = bkgdtablews->getRow(i); string parname; double parvalue; row >> parname >> parvalue; if (parname[0] == 'A') parmap.insert(make_pair(parname, parvalue)); } int bkgdorder = static_cast<int>(parmap.size()-1); // A0 - A(n) total n+1 parameters bkgdfunc->setAttributeValue("n", bkgdorder); for (map<string, double>::iterator mit = parmap.begin(); mit != parmap.end(); ++mit) { string parname = mit->first; double parvalue = mit->second; bkgdfunc->setParameter(parname, parvalue); } // Filter out m_outputWS = filterForBackground(bkgdfunc); return; }
/** Fit background function */ void ProcessBackground::fitBackgroundFunction(std::string bkgdfunctiontype) { // Get background type and create bakground function BackgroundFunction_sptr bkgdfunction = createBackgroundFunction(bkgdfunctiontype); int bkgdorder = getProperty("OutputBackgroundOrder"); bkgdfunction->setAttributeValue("n", bkgdorder); if (bkgdfunctiontype == "Chebyshev") { double xmin = m_outputWS->readX(0).front(); double xmax = m_outputWS->readX(0).back(); g_log.information() << "Chebyshev Fit range: " << xmin << ", " << xmax << "\n"; bkgdfunction->setAttributeValue("StartX", xmin); bkgdfunction->setAttributeValue("EndX", xmax); } g_log.information() << "Fit selected background " << bkgdfunctiontype << " to data workspace with " << m_outputWS->getNumberHistograms() << " spectra." << "\n"; // Fit input (a few) background pionts to get initial guess API::IAlgorithm_sptr fit; try { fit = this->createChildAlgorithm("Fit", 0.9, 1.0, true); } catch (Exception::NotFoundError &) { g_log.error() << "Requires CurveFitting library." << std::endl; throw; } g_log.information() << "Fitting background function: " << bkgdfunction->asString() << "\n"; double startx = m_lowerBound; double endx = m_upperBound; fit->setProperty("Function", boost::dynamic_pointer_cast<API::IFunction>(bkgdfunction)); fit->setProperty("InputWorkspace", m_outputWS); fit->setProperty("WorkspaceIndex", 0); fit->setProperty("MaxIterations", 500); fit->setProperty("StartX", startx); fit->setProperty("EndX", endx); fit->setProperty("Minimizer", "Levenberg-MarquardtMD"); fit->setProperty("CostFunction", "Least squares"); fit->executeAsChildAlg(); // Get fit status and chi^2 std::string fitStatus = fit->getProperty("OutputStatus"); bool allowedfailure = (fitStatus.find("cannot") < fitStatus.size()) && (fitStatus.find("tolerance") < fitStatus.size()); if (fitStatus.compare("success") != 0 && !allowedfailure) { g_log.error() << "ProcessBackground: Fit Status = " << fitStatus << ". Not to update fit result" << std::endl; throw std::runtime_error("Bad Fit"); } const double chi2 = fit->getProperty("OutputChi2overDoF"); g_log.information() << "Fit background: Fit Status = " << fitStatus << ", chi2 = " << chi2 << "\n"; // Get out the parameter names API::IFunction_sptr funcout = fit->getProperty("Function"); TableWorkspace_sptr outbkgdparws = boost::make_shared<TableWorkspace>(); outbkgdparws->addColumn("str", "Name"); outbkgdparws->addColumn("double", "Value"); TableRow typerow = outbkgdparws->appendRow(); typerow << bkgdfunctiontype << 0.; vector<string> parnames = funcout->getParameterNames(); size_t nparam = funcout->nParams(); for (size_t i = 0; i < nparam; ++i) { TableRow newrow = outbkgdparws->appendRow(); newrow << parnames[i] << funcout->getParameter(i); } TableRow chi2row = outbkgdparws->appendRow(); chi2row << "Chi-square" << chi2; g_log.information() << "Set table workspace (#row = " << outbkgdparws->rowCount() << ") to OutputBackgroundParameterTable. " << "\n"; setProperty("OutputBackgroundParameterWorkspace", outbkgdparws); // Set output workspace const MantidVec &vecX = m_outputWS->readX(0); const MantidVec &vecY = m_outputWS->readY(0); FunctionDomain1DVector domain(vecX); FunctionValues values(domain); funcout->function(domain, values); MantidVec &dataModel = m_outputWS->dataY(1); MantidVec &dataDiff = m_outputWS->dataY(2); for (size_t i = 0; i < dataModel.size(); ++i) { dataModel[i] = values[i]; dataDiff[i] = vecY[i] - dataModel[i]; } return; }
/** Filter non-background data points out and create a background workspace */ Workspace2D_sptr ProcessBackground::filterForBackground(BackgroundFunction_sptr bkgdfunction) { double posnoisetolerance = getProperty("NoiseTolerance"); double negnoisetolerance = getProperty("NegativeNoiseTolerance"); if (isEmpty(negnoisetolerance)) negnoisetolerance = posnoisetolerance; // Calcualte theoretical values const std::vector<double> x = m_dataWS->readX(m_wsIndex); API::FunctionDomain1DVector domain(x); API::FunctionValues values(domain); bkgdfunction->function(domain, values); g_log.information() << "Function used to select background points : " << bkgdfunction->asString() << "\n"; // Optional output string userbkgdwsname = getPropertyValue("UserBackgroundWorkspace"); if (userbkgdwsname.size() == 0) throw runtime_error("In mode SelectBackgroundPoints, " "UserBackgroundWorkspace must be given!"); size_t sizex = domain.size(); size_t sizey = values.size(); MatrixWorkspace_sptr visualws = boost::dynamic_pointer_cast<MatrixWorkspace>( WorkspaceFactory::Instance().create("Workspace2D", 4, sizex, sizey)); for (size_t i = 0; i < sizex; ++i) { for (size_t j = 0; j < 4; ++j) { visualws->dataX(j)[i] = domain[i]; } } for (size_t i = 0; i < sizey; ++i) { visualws->dataY(0)[i] = values[i]; visualws->dataY(1)[i] = m_dataWS->readY(m_wsIndex)[i] - values[i]; visualws->dataY(2)[i] = posnoisetolerance; visualws->dataY(3)[i] = -negnoisetolerance; } setProperty("UserBackgroundWorkspace", visualws); // Filter for background std::vector<double> vecx, vecy, vece; for (size_t i = 0; i < domain.size(); ++i) { // double y = m_dataWS->readY(m_wsIndex)[i]; // double theoryy = values[i]; y-theoryy double purey = visualws->readY(1)[i]; if (purey < posnoisetolerance && purey > -negnoisetolerance) { // Selected double x = domain[i]; double y = m_dataWS->readY(m_wsIndex)[i]; double e = m_dataWS->readE(m_wsIndex)[i]; vecx.push_back(x); vecy.push_back(y); vece.push_back(e); } } g_log.information() << "Found " << vecx.size() << " background points out of " << m_dataWS->readX(m_wsIndex).size() << " total data points. " << "\n"; // Build new workspace for OutputWorkspace size_t nspec = 3; Workspace2D_sptr outws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( API::WorkspaceFactory::Instance().create("Workspace2D", nspec, vecx.size(), vecy.size())); for (size_t i = 0; i < vecx.size(); ++i) { for (size_t j = 0; j < nspec; ++j) outws->dataX(j)[i] = vecx[i]; outws->dataY(0)[i] = vecy[i]; outws->dataE(0)[i] = vece[i]; } return outws; }
/** Select background automatically */ DataObjects::Workspace2D_sptr ProcessBackground::autoBackgroundSelection(Workspace2D_sptr bkgdWS) { // Get background type and create bakground function BackgroundFunction_sptr bkgdfunction = createBackgroundFunction(m_bkgdType); int bkgdorder = getProperty("BackgroundOrder"); if (bkgdorder == 0) g_log.warning("(Input) background function order is 0. It might not be " "able to give a good estimation."); bkgdfunction->setAttributeValue("n", bkgdorder); bkgdfunction->initialize(); g_log.information() << "Input background points has " << bkgdWS->readX(0).size() << " data points for fit " << bkgdorder << "-th order " << bkgdfunction->name() << " (background) function" << bkgdfunction->asString() << "\n"; // Fit input (a few) background pionts to get initial guess API::IAlgorithm_sptr fit; try { fit = this->createChildAlgorithm("Fit", 0.0, 0.2, true); } catch (Exception::NotFoundError &) { g_log.error() << "Requires CurveFitting library." << std::endl; throw; } double startx = m_lowerBound; double endx = m_upperBound; fit->setProperty("Function", boost::dynamic_pointer_cast<API::IFunction>(bkgdfunction)); fit->setProperty("InputWorkspace", bkgdWS); fit->setProperty("WorkspaceIndex", 0); fit->setProperty("MaxIterations", 500); fit->setProperty("StartX", startx); fit->setProperty("EndX", endx); fit->setProperty("Minimizer", "Levenberg-Marquardt"); fit->setProperty("CostFunction", "Least squares"); fit->executeAsChildAlg(); // Get fit result // a) Status std::string fitStatus = fit->getProperty("OutputStatus"); bool allowedfailure = (fitStatus.find("cannot") < fitStatus.size()) && (fitStatus.find("tolerance") < fitStatus.size()); if (fitStatus.compare("success") != 0 && !allowedfailure) { g_log.error() << "ProcessBackground: Fit Status = " << fitStatus << ". Not to update fit result" << std::endl; throw std::runtime_error("Bad Fit"); } // b) check that chi2 got better const double chi2 = fit->getProperty("OutputChi2overDoF"); g_log.information() << "Fit background: Fit Status = " << fitStatus << ", chi2 = " << chi2 << "\n"; // Filter and construct for the output workspace Workspace2D_sptr outws = filterForBackground(bkgdfunction); return outws; } // END OF FUNCTION
/** Select background automatically */ DataObjects::Workspace2D_sptr ProcessBackground::autoBackgroundSelection(Workspace2D_sptr bkgdWS) { // Get background type and create bakground function BackgroundFunction_sptr bkgdfunction = createBackgroundFunction(m_bkgdType); int bkgdorder = getProperty("BackgroundOrder"); bkgdfunction->setAttributeValue("n", bkgdorder); g_log.debug() << "DBx622 Background Workspace has " << bkgdWS->readX(0).size() << " data points." << std::endl; // Fit input (a few) background pionts to get initial guess API::IAlgorithm_sptr fit; try { fit = this->createChildAlgorithm("Fit", 0.0, 0.2, true); } catch (Exception::NotFoundError &) { g_log.error() << "Requires CurveFitting library." << std::endl; throw; } double startx = m_lowerBound; double endx = m_upperBound; fit->setProperty("Function", boost::dynamic_pointer_cast<API::IFunction>(bkgdfunction)); fit->setProperty("InputWorkspace", bkgdWS); fit->setProperty("WorkspaceIndex", 0); fit->setProperty("MaxIterations", 500); fit->setProperty("StartX", startx); fit->setProperty("EndX", endx); fit->setProperty("Minimizer", "Levenberg-Marquardt"); fit->setProperty("CostFunction", "Least squares"); fit->executeAsChildAlg(); // Get fit result // a) Status std::string fitStatus = fit->getProperty("OutputStatus"); bool allowedfailure = (fitStatus.find("cannot") < fitStatus.size()) && (fitStatus.find("tolerance") < fitStatus.size()); if (fitStatus.compare("success") != 0 && !allowedfailure) { g_log.error() << "ProcessBackground: Fit Status = " << fitStatus << ". Not to update fit result" << std::endl; throw std::runtime_error("Bad Fit"); } // b) check that chi2 got better const double chi2 = fit->getProperty("OutputChi2overDoF"); g_log.information() << "Fit background: Fit Status = " << fitStatus << ", chi2 = " << chi2 << "\n"; // c) get out the parameter names API::IFunction_sptr func = fit->getProperty("Function"); /* Comment out as not being used std::vector<std::string> parnames = func->getParameterNames(); std::map<std::string, double> parvalues; for (size_t iname = 0; iname < parnames.size(); ++iname) { double value = func->getParameter(parnames[iname]); parvalues.insert(std::make_pair(parnames[iname], value)); } DataObject::Workspace2D_const_sptr theorybackground = AnalysisDataService::Instance().retrieve(wsname); */ // Filter and construct for the output workspace Workspace2D_sptr outws = filterForBackground(bkgdfunction); return outws; } // END OF FUNCTION