/** Add a function * @param f :: A pointer to the added function * @return The function index */ size_t CompositeFunction::addFunction(IFunction_sptr f) { m_IFunction.insert(m_IFunction.end(), f->nParams(), m_functions.size()); m_functions.push_back(f); //?f->init(); if (m_paramOffsets.empty()) { m_paramOffsets.push_back(0); m_nParams = f->nParams(); } else { m_paramOffsets.push_back(m_nParams); m_nParams += f->nParams(); } return m_functions.size() - 1; }
/** * Initialize diagnosis table. */ void MuonSequentialFitDialog::initDiagnosisTable() { QStringList headerLabels; // Add two static columns headerLabels << "Run" << "Fit quality"; // Add remaining columns - one for every fit function parameter IFunction_sptr fitFunc = m_fitPropBrowser->getFittingFunction(); for(size_t i = 0; i < fitFunc->nParams(); i++) { QString paramName = QString::fromStdString( fitFunc->parameterName(i) ); headerLabels << paramName; headerLabels << paramName + "_Err"; } m_ui.diagnosisTable->setColumnCount( headerLabels.size() ); m_ui.diagnosisTable->setHorizontalHeaderLabels(headerLabels); // Make the table fill all the available space and columns be resized to fit contents m_ui.diagnosisTable->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents); // Make rows alternate bg colors for better user experience m_ui.diagnosisTable->setAlternatingRowColors(true); }
/** * Returns the shrared pointer to the function conataining a parameter * @param ref :: The reference * @return A function containing parameter pointed to by ref */ IFunction_sptr CompositeFunction::getContainingFunction(const ParameterReference &ref) const { for (size_t iFun = 0; iFun < nFunctions(); iFun++) { IFunction_sptr fun = getFunction(iFun); if (fun->getParameterIndex(ref) < fun->nParams()) { return fun; } } return IFunction_sptr(); }
/** Replace a function with a new one. The old function is deleted. * @param i :: The index of the function to replace * @param f :: A pointer to the new function */ void CompositeFunction::replaceFunction(size_t i, IFunction_sptr f) { if (i >= nFunctions()) { throw std::out_of_range("Function index (" + std::to_string(i) + ") out of range (" + std::to_string(nFunctions()) + ")."); } IFunction_sptr fun = getFunction(i); size_t np_old = fun->nParams(); size_t np_new = f->nParams(); // Modify function indeces: The new function may have different number of // parameters { auto itFun = std::find(m_IFunction.begin(), m_IFunction.end(), i); if (itFun != m_IFunction.end()) // functions must have at least 1 parameter { if (np_old > np_new) { m_IFunction.erase(itFun, itFun + np_old - np_new); } else if (np_old < np_new) { m_IFunction.insert(itFun, np_new - np_old, i); } } else if (np_new > 0) // it could happen if the old function is an empty // CompositeFunction { itFun = std::find_if(m_IFunction.begin(), m_IFunction.end(), std::bind2nd(std::greater<size_t>(), i)); m_IFunction.insert(itFun, np_new, i); } } size_t dnp = np_new - np_old; m_nParams += dnp; // Shift the parameter offsets down by the total number of i-th function's // params for (size_t j = i + 1; j < nFunctions(); j++) { m_paramOffsets[j] += dnp; } m_functions[i] = f; }
/** * Gets a list of parameters for a given fit function. * * @return List fo parameters */ QStringList JumpFit::getFunctionParameters(const QString &functionName) { QStringList parameters; IFunction_sptr func = FunctionFactory::Instance().createFunction(functionName.toStdString()); for (size_t i = 0; i < func->nParams(); i++) parameters << QString::fromStdString(func->parameterName(i)); return parameters; }
/// Returns a TableWorkspace with refined cell parameters and error. ITableWorkspace_sptr PoldiFitPeaks2D::getRefinedCellParameters( const IFunction_sptr &fitFunction) const { Poldi2DFunction_sptr poldi2DFunction = boost::dynamic_pointer_cast<Poldi2DFunction>(fitFunction); if (!poldi2DFunction || poldi2DFunction->nFunctions() < 1) { throw std::invalid_argument( "Cannot process function that is not a Poldi2DFunction."); } // Create a new table for lattice parameters ITableWorkspace_sptr latticeParameterTable = WorkspaceFactory::Instance().createTable(); latticeParameterTable->addColumn("str", "Parameter"); latticeParameterTable->addColumn("double", "Value"); latticeParameterTable->addColumn("double", "Error"); // The first function should be PoldiSpectrumPawleyFunction boost::shared_ptr<PoldiSpectrumPawleyFunction> poldiPawleyFunction = boost::dynamic_pointer_cast<PoldiSpectrumPawleyFunction>( poldi2DFunction->getFunction(0)); if (!poldiPawleyFunction) { throw std::invalid_argument("First function in Poldi2DFunction is not " "PoldiSpectrumPawleyFunction."); } // Get the actual PawleyFunction to extract parameters. IPawleyFunction_sptr pawleyFunction = boost::dynamic_pointer_cast<IPawleyFunction>( poldiPawleyFunction->getDecoratedFunction()); if (pawleyFunction) { CompositeFunction_sptr pawleyParts = boost::dynamic_pointer_cast<CompositeFunction>( pawleyFunction->getDecoratedFunction()); // The first function in PawleyFunction contains the parameters IFunction_sptr pawleyParameters = pawleyParts->getFunction(0); for (size_t i = 0; i < pawleyParameters->nParams(); ++i) { TableRow newRow = latticeParameterTable->appendRow(); newRow << pawleyParameters->parameterName(i) << pawleyParameters->getParameter(i) << pawleyParameters->getError(i); } } return latticeParameterTable; }
/** * Returns the index of parameter if the ref points to one of the member * function * @param ref :: A reference to a parameter * @return Parameter index or number of nParams() if parameter not found */ size_t CompositeFunction::getParameterIndex(const ParameterReference &ref) const { if (ref.getLocalFunction() == this && ref.getLocalIndex() < nParams()) { return ref.getLocalIndex(); } for (size_t iFun = 0; iFun < nFunctions(); iFun++) { IFunction_sptr fun = getFunction(iFun); size_t iLocalIndex = fun->getParameterIndex(ref); if (iLocalIndex < fun->nParams()) { return m_paramOffsets[iFun] + iLocalIndex; } } return nParams(); }
/** Remove a function * @param i :: The index of the function to remove */ void CompositeFunction::removeFunction(size_t i) { if (i >= nFunctions()) { throw std::out_of_range("Function index (" + std::to_string(i) + ") out of range (" + std::to_string(nFunctions()) + ")."); } IFunction_sptr fun = getFunction(i); // Reduction in parameters size_t dnp = fun->nParams(); for (size_t j = 0; j < nParams();) { ParameterTie *tie = getTie(j); if (tie && tie->findParametersOf(fun.get())) { removeTie(j); } else { j++; } } // Shift down the function indeces for parameters for (auto it = m_IFunction.begin(); it != m_IFunction.end();) { if (*it == i) { it = m_IFunction.erase(it); } else { if (*it > i) { *it -= 1; } ++it; } } m_nParams -= dnp; // Shift the parameter offsets down by the total number of i-th function's // params for (size_t j = i + 1; j < nFunctions(); j++) { m_paramOffsets[j] -= dnp; } m_paramOffsets.erase(m_paramOffsets.begin() + i); m_functions.erase(m_functions.begin() + i); }
/// Returns a vector of peak collections extracted from the function std::vector<PoldiPeakCollection_sptr> PoldiFitPeaks2D::getCountPeakCollections( const API::IFunction_sptr &fitFunction) { Poldi2DFunction_sptr poldiFunction = boost::dynamic_pointer_cast<Poldi2DFunction>(fitFunction); if (!poldiFunction) { throw std::runtime_error("Can only extract peaks from Poldi2DFunction."); } // Covariance matrix - needs to be assigned to the member functions for error // calculation boost::shared_ptr<const Kernel::DblMatrix> covarianceMatrix = poldiFunction->getCovarianceMatrix(); std::vector<PoldiPeakCollection_sptr> countPeakCollections; size_t offset = 0; for (size_t i = 0; i < poldiFunction->nFunctions(); ++i) { IFunction_sptr localFunction = poldiFunction->getFunction(i); size_t nLocalParams = localFunction->nParams(); // Assign local covariance matrix. boost::shared_ptr<Kernel::DblMatrix> localCov = getLocalCovarianceMatrix(covarianceMatrix, offset, nLocalParams); localFunction->setCovarianceMatrix(localCov); try { PoldiPeakCollection_sptr normalizedPeaks = getPeakCollectionFromFunction(localFunction); countPeakCollections.push_back(getCountPeakCollection(normalizedPeaks)); } catch (const std::invalid_argument &) { // not a Poldi2DFunction - skip (the background functions) } offset += nLocalParams; } return countPeakCollections; }
API::MatrixWorkspace_sptr CreateFloodWorkspace::removeBackground(API::MatrixWorkspace_sptr ws) { g_log.information() << "Remove background " << getPropertyValue(Prop::BACKGROUND) << '\n'; auto fitWS = transpose(ws); auto const &x = fitWS->x(0); // Define the fitting interval double startX = getProperty(Prop::START_X); double endX = getProperty(Prop::END_X); std::vector<double> excludeFromFit; if (isDefault(Prop::START_X)) { startX = x.front(); } else { excludeFromFit.push_back(x.front()); excludeFromFit.push_back(startX); } if (isDefault(Prop::END_X)) { endX = x.back(); } else { excludeFromFit.push_back(endX); excludeFromFit.push_back(x.back()); } // Exclude any bad detectors. for (auto i : m_excludedSpectra) { excludeFromFit.push_back(i); excludeFromFit.push_back(i); } std::string const function = getBackgroundFunction(); // Fit the data to determine unwanted background auto alg = createChildAlgorithm("Fit", 0.9, 0.99); alg->setProperty("Function", function); alg->setProperty("InputWorkspace", fitWS); alg->setProperty("WorkspaceIndex", 0); if (!excludeFromFit.empty()) { alg->setProperty("Exclude", excludeFromFit); } alg->setProperty("Output", "fit"); alg->execute(); IFunction_sptr func = alg->getProperty("Function"); g_log.information() << "Background function parameters:\n"; for (size_t i = 0; i < func->nParams(); ++i) { g_log.information() << " " << func->parameterName(i) << ": " << func->getParameter(i) << '\n'; } // Divide the workspace by the fitted curve to remove the background // and scale to values around 1 MatrixWorkspace_sptr bkgWS = alg->getProperty("OutputWorkspace"); auto const &bkg = bkgWS->y(1); auto const nHisto = static_cast<int>(ws->getNumberHistograms()); PARALLEL_FOR_IF(Kernel::threadSafe(*ws, *bkgWS)) for (int i = 0; i < nHisto; ++i) { PARALLEL_START_INTERUPT_REGION auto const xVal = x[i]; if (isExcludedSpectrum(xVal)) { ws->mutableY(i)[0] = VERY_BIG_VALUE; ws->mutableE(i)[0] = 0.0; } else if (xVal >= startX && xVal <= endX) { auto const background = bkg[i]; if (background <= 0.0) { throw std::runtime_error( "Background is expected to be positive, found value " + std::to_string(background) + " at spectrum with workspace index " + std::to_string(i)); } ws->mutableY(i)[0] /= background; ws->mutableE(i)[0] /= background; } else { ws->mutableY(i)[0] = 1.0; ws->mutableE(i)[0] = 0.0; } PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Remove the logs ws->setSharedRun(make_cow<Run>()); return ws; }