size_t PawleyFunction::calculateFunctionValues( const API::IPeakFunction_sptr &peak, const API::FunctionDomain1D &domain, API::FunctionValues &localValues) const { size_t domainSize = domain.size(); const double *domainBegin = domain.getPointerAt(0); const double *domainEnd = domain.getPointerAt(domainSize); double centre = peak->centre(); double dx = m_peakRadius * peak->fwhm(); auto lb = std::lower_bound(domainBegin, domainEnd, centre - dx); auto ub = std::upper_bound(lb, domainEnd, centre + dx); size_t n = std::distance(lb, ub); if (n == 0) { throw std::invalid_argument("Null-domain"); } FunctionDomain1DView localDomain(lb, n); localValues.reset(localDomain); peak->functionLocal(localValues.getPointerToCalculated(0), localDomain.getPointerAt(0), n); return std::distance(domainBegin, lb); }
/** Generate peaks in the given output workspace * @param functionmap :: map to contain the list of functions with key as their spectra * @param dataWS :: output matrix workspace */ void GeneratePeaks::generatePeaks(const std::map<specid_t, std::vector<std::pair<double, API::IFunction_sptr> > >& functionmap, API::MatrixWorkspace_sptr dataWS) { // Calcualte function std::map<specid_t, std::vector<std::pair<double, API::IFunction_sptr> > >::const_iterator mapiter; for (mapiter = functionmap.begin(); mapiter != functionmap.end(); ++mapiter) { // Get spec id and translated to wsindex in the output workspace specid_t specid = mapiter->first; specid_t wsindex; if (m_newWSFromParent) wsindex = specid; else wsindex = m_SpectrumMap[specid]; const std::vector<std::pair<double, API::IFunction_sptr> >& vec_centrefunc = mapiter->second; size_t numpeaksinspec = mapiter->second.size(); for (size_t ipeak = 0; ipeak < numpeaksinspec; ++ipeak) { const std::pair<double, API::IFunction_sptr>& centrefunc = vec_centrefunc[ipeak]; // Determine boundary API::IPeakFunction_sptr thispeak = getPeakFunction(centrefunc.second); double centre = centrefunc.first; double fwhm = thispeak->fwhm(); // const MantidVec& X = dataWS->dataX(wsindex); double leftbound = centre - m_numPeakWidth*fwhm; if (ipeak > 0) { // Not left most peak. API::IPeakFunction_sptr leftPeak = getPeakFunction(vec_centrefunc[ipeak-1].second); double middle = 0.5*(centre + leftPeak->centre()); if (leftbound < middle) leftbound = middle; } std::vector<double>::const_iterator left = std::lower_bound(X.begin(), X.end(), leftbound); if (left == X.end()) left = X.begin(); double rightbound = centre + m_numPeakWidth*fwhm; if (ipeak != numpeaksinspec-1) { // Not the rightmost peak IPeakFunction_sptr rightPeak = getPeakFunction(vec_centrefunc[ipeak+1].second); double middle = 0.5*(centre + rightPeak->centre()); if (rightbound > middle) rightbound = middle; } std::vector<double>::const_iterator right = std::lower_bound(left + 1, X.end(), rightbound); // Build domain & function API::FunctionDomain1DVector domain(left, right); //dataWS->dataX(wsindex)); // Evaluate the function API::FunctionValues values(domain); centrefunc.second->function(domain, values); // Put to output std::size_t offset = (left-X.begin()); std::size_t numY = values.size(); for (std::size_t i = 0; i < numY; i ++) { dataWS->dataY(wsindex)[i + offset] += values[i]; } } // ENDFOR(ipeak) } return; }