/** Creates PoldiPeak-objects from peak position iterators * * In this method, PoldiPeak objects are created from the raw peak position *data and the original x-data. Estimates for peak height and FWHM * provided along with the position. * * @param baseListStart :: Starting iterator of the vector which the peak *positions refer to. * @param peakPositions :: List with peakPositions. * @param xData :: Vector with x-values of the correlation spectrum. * @return Vector with PoldiPeak objects constructed from the raw peak position *data. */ std::vector<PoldiPeak_sptr> PoldiPeakSearch::getPeaks(const MantidVec::const_iterator &baseListStart, const MantidVec::const_iterator &baseListEnd, std::list<MantidVec::const_iterator> peakPositions, const MantidVec &xData, const Unit_sptr &unit) const { std::vector<PoldiPeak_sptr> peakData; peakData.reserve(peakPositions.size()); for (std::list<MantidVec::const_iterator>::const_iterator peak = peakPositions.begin(); peak != peakPositions.end(); ++peak) { size_t index = std::distance(baseListStart, *peak); double xDataD = getTransformedCenter(xData[index], unit); double fwhmEstimate = getFWHMEstimate(baseListStart, baseListEnd, *peak, xData); UncertainValue fwhm(fwhmEstimate / xData[index]); PoldiPeak_sptr newPeak = PoldiPeak::create( MillerIndices(), UncertainValue(xDataD), UncertainValue(**peak), fwhm); peakData.push_back(newPeak); } return peakData; }
void PoldiPeak::multiplyErrors(double factor) { setQ(UncertainValue(m_q.value(), m_q.error() * factor)); setFwhm( UncertainValue(m_fwhmRelative.value(), m_fwhmRelative.error() * factor), PoldiPeak::Relative); setIntensity( UncertainValue(m_intensity.value(), m_intensity.error() * factor)); }
void PoldiFitPeaks1D2::setValuesFromProfileFunction( PoldiPeak_sptr poldiPeak, const IFunction_sptr &fittedFunction) const { IPeakFunction_sptr peakFunction = boost::dynamic_pointer_cast<IPeakFunction>(fittedFunction); if (peakFunction) { poldiPeak->setIntensity( UncertainValue(peakFunction->height(), peakFunction->getError(0))); poldiPeak->setQ( UncertainValue(peakFunction->centre(), peakFunction->getError(1))); poldiPeak->setFwhm(UncertainValue(peakFunction->fwhm(), getFwhmWidthRelation(peakFunction) * peakFunction->getError(2))); } }
/** Creates PoldiPeak-objects from peak position iterators * * In this method, PoldiPeak objects are created from the raw peak position data and the original x-data. Estimates for peak height and FWHM * provided along with the position. * * @param baseListStart :: Starting iterator of the vector which the peak positions refer to. * @param peakPositions :: List with peakPositions. * @param xData :: Vector with x-values of the correlation spectrum. * @return Vector with PoldiPeak objects constructed from the raw peak position data. */ std::vector<PoldiPeak_sptr> PoldiPeakSearch::getPeaks(MantidVec::const_iterator baseListStart, std::list<MantidVec::const_iterator> peakPositions, const MantidVec &xData) const { std::vector<PoldiPeak_sptr> peakData; peakData.reserve(peakPositions.size()); for(std::list<MantidVec::const_iterator>::const_iterator peak = peakPositions.begin(); peak != peakPositions.end(); ++peak) { size_t index = std::distance(baseListStart, *peak); PoldiPeak_sptr newPeak = PoldiPeak::create(UncertainValue(xData[index]), UncertainValue(**peak)); double fwhmEstimate = getFWHMEstimate(baseListStart, *peak, xData); newPeak->setFwhm(UncertainValue(fwhmEstimate)); peakData.push_back(newPeak); } return peakData; }
/// Creates a PoldiPeak from the given profile function/hkl pair. PoldiPeak_sptr PoldiFitPeaks2D::getPeakFromPeakFunction(IPeakFunction_sptr profileFunction, const V3D &hkl) { // Use EstimatePeakErrors to calculate errors of FWHM and so on IAlgorithm_sptr errorAlg = createChildAlgorithm("EstimatePeakErrors"); errorAlg->setProperty( "Function", boost::dynamic_pointer_cast<IFunction>(profileFunction)); errorAlg->setPropertyValue("OutputWorkspace", "Errors"); errorAlg->execute(); double centre = profileFunction->centre(); double fwhmValue = profileFunction->fwhm(); ITableWorkspace_sptr errorTable = errorAlg->getProperty("OutputWorkspace"); double centreError = errorTable->cell<double>(0, 2); double fwhmError = errorTable->cell<double>(2, 2); UncertainValue d(centre, centreError); UncertainValue fwhm(fwhmValue, fwhmError); UncertainValue intensity; bool useIntegratedIntensities = getProperty("OutputIntegratedIntensities"); if (useIntegratedIntensities) { double integratedIntensity = profileFunction->intensity(); double integratedIntensityError = errorTable->cell<double>(3, 2); intensity = UncertainValue(integratedIntensity, integratedIntensityError); } else { double height = profileFunction->height(); double heightError = errorTable->cell<double>(1, 2); intensity = UncertainValue(height, heightError); } // Create peak with extracted parameters and supplied hkl PoldiPeak_sptr peak = PoldiPeak::create(MillerIndices(hkl), d, intensity, UncertainValue(1.0)); peak->setFwhm(fwhm, PoldiPeak::FwhmRelation::AbsoluteD); return peak; }
void PoldiPeakCollection::setPeaks(const std::vector<V3D> &hkls, const std::vector<double> &dValues, const std::vector<double> &fSquared) { if (hkls.size() != dValues.size()) { throw std::invalid_argument( "hkl-vector and d-vector do not have the same length."); } if (!m_pointGroup) { throw std::runtime_error("Cannot set peaks without point group."); } m_peaks.clear(); for (size_t i = 0; i < hkls.size(); ++i) { double multiplicity = static_cast<double>(m_pointGroup->getEquivalents(hkls[i]).size()); addPeak(PoldiPeak::create( MillerIndices(hkls[i]), UncertainValue(dValues[i]), UncertainValue(multiplicity * fSquared[i]), UncertainValue(0.0))); } }
void PoldiPeakCollection::constructFromTableWorkspace( const TableWorkspace_sptr &tableWorkspace) { if (checkColumns(tableWorkspace)) { size_t newPeakCount = tableWorkspace->rowCount(); m_peaks.resize(newPeakCount); recoverDataFromLog(tableWorkspace); for (size_t i = 0; i < newPeakCount; ++i) { TableRow nextRow = tableWorkspace->getRow(i); std::string hklString; double d, deltaD, q, deltaQ, intensity, deltaIntensity, fwhm, deltaFwhm; nextRow >> hklString >> d >> deltaD >> q >> deltaQ >> intensity >> deltaIntensity >> fwhm >> deltaFwhm; PoldiPeak_sptr peak = PoldiPeak::create( MillerIndicesIO::fromString(hklString), UncertainValue(d, deltaD), UncertainValue(intensity, deltaIntensity), UncertainValue(fwhm, deltaFwhm)); m_peaks[i] = peak; } } }
/** Computes a background estimation with an error * * This method computes an estimate of the average background along with its deviation. Since the background does not * follow a normal distribution and may contain outliers, instead of computing the average and standard deviation, * the median is used as location estimator and Sn is used as scale estimator. For details regarding the latter * refer to PoldiPeakSearch::getSn. * * @param peakPositions :: Peak positions. * @param correlationCounts :: Data from which the peak positions were extracted. * @return Background estimation with error. */ UncertainValue PoldiPeakSearch::getBackgroundWithSigma(std::list<MantidVec::const_iterator> peakPositions, const MantidVec &correlationCounts) const { MantidVec background = getBackground(peakPositions, correlationCounts); /* Instead of using Mean and Standard deviation, which are appropriate * for data originating from a normal distribution (which is not the case * for background of POLDI correlation spectra), the more robust measures * Median and Sn are used. */ std::sort(background.begin(), background.end()); double meanBackground = getMedianFromSortedVector(background.begin(), background.end()); double sigmaBackground = getSn(background.begin(), background.end()); return UncertainValue(meanBackground, sigmaBackground); }
/// Converts the given tolerance (interpreted as standard deviation of a normal /// probability distribution) to FWHM and assigns that to all peaks of the /// supplied collection. void PoldiIndexKnownCompounds::assignFwhmEstimates( const PoldiPeakCollection_sptr &peakCollection, double tolerance) const { if (!peakCollection) { throw std::invalid_argument( "Cannot assign intensities to invalid PoldiPeakCollection."); } size_t peakCount = peakCollection->peakCount(); double fwhm = sigmaToFwhm(tolerance); for (size_t i = 0; i < peakCount; ++i) { PoldiPeak_sptr peak = peakCollection->peak(i); peak->setFwhm(UncertainValue(fwhm), PoldiPeak::Relative); } }
/** * Tries to refine the initial cell using the supplied peaks * * This method tries to refine the initial unit cell using the indexed peaks * that are supplied in the PoldiPeakCollection. If there are unindexed peaks, * the cell will not be refined at all, instead the unmodified initial cell * is returned. * * @param initialCell :: String with the initial unit cell * @param crystalSystem :: Crystal system name * @param peakCollection :: Collection of bragg peaks, must be indexed * * @return String for refined unit cell */ std::string PoldiFitPeaks2D::getRefinedStartingCell( const std::string &initialCell, const std::string &latticeSystem, const PoldiPeakCollection_sptr &peakCollection) { Geometry::UnitCell cell = Geometry::strToUnitCell(initialCell); ILatticeFunction_sptr latticeFunction = boost::dynamic_pointer_cast<ILatticeFunction>( FunctionFactory::Instance().createFunction("LatticeFunction")); latticeFunction->setLatticeSystem(latticeSystem); latticeFunction->fix(latticeFunction->parameterIndex("ZeroShift")); latticeFunction->setUnitCell(cell); // Remove errors from d-values PoldiPeakCollection_sptr clone = peakCollection->clone(); for (size_t i = 0; i < clone->peakCount(); ++i) { PoldiPeak_sptr peak = clone->peak(i); // If there are unindexed peaks, don't refine, just return the initial cell if (peak->hkl() == MillerIndices()) { return initialCell; } peak->setD(UncertainValue(peak->d().value())); } TableWorkspace_sptr peakTable = clone->asTableWorkspace(); IAlgorithm_sptr fit = createChildAlgorithm("Fit"); fit->setProperty("Function", boost::static_pointer_cast<IFunction>(latticeFunction)); fit->setProperty("InputWorkspace", peakTable); fit->setProperty("CostFunction", "Unweighted least squares"); fit->execute(); Geometry::UnitCell refinedCell = latticeFunction->getUnitCell(); return Geometry::unitCellToStr(refinedCell); }
/** * Return peak collection with integrated peaks * * This method takes a PoldiPeakCollection where the intensity is represented * by the maximum. Then it takes the profile function stored in the peak * collection, which must be the name of a registered * IPeakFunction-implementation. The parameters height and fwhm are assigned, * centre is set to 0 to avoid problems with the parameter transformation for * the integration from -inf to inf. The profiles are integrated using * a PeakFunctionIntegrator to the precision of 1e-10. * * The original peak collection is not modified, a new instance is created. * * @param rawPeakCollection :: PoldiPeakCollection * @return PoldiPeakCollection with integrated intensities */ PoldiPeakCollection_sptr PoldiFitPeaks2D::getIntegratedPeakCollection( const PoldiPeakCollection_sptr &rawPeakCollection) const { if (!rawPeakCollection) { throw std::invalid_argument( "Cannot proceed with invalid PoldiPeakCollection."); } if (!isValidDeltaT(m_deltaT)) { throw std::invalid_argument("Cannot proceed with invalid time bin size."); } if (!m_timeTransformer) { throw std::invalid_argument( "Cannot proceed with invalid PoldiTimeTransformer."); } if (rawPeakCollection->intensityType() == PoldiPeakCollection::Integral) { /* Intensities are integral already - don't need to do anything, * except cloning the collection, to make behavior consistent, since * integrating also results in a new peak collection. */ return rawPeakCollection->clone(); } /* If no profile function is specified, it's not possible to get integrated * intensities at all and we try to use the one specified by the user * instead. */ std::string profileFunctionName = rawPeakCollection->getProfileFunctionName(); if (!rawPeakCollection->hasProfileFunctionName()) { profileFunctionName = getPropertyValue("PeakProfileFunction"); } std::vector<std::string> allowedProfiles = FunctionFactory::Instance().getFunctionNames<IPeakFunction>(); if (std::find(allowedProfiles.begin(), allowedProfiles.end(), profileFunctionName) == allowedProfiles.end()) { throw std::runtime_error( "Cannot integrate peak profiles with invalid profile function."); } PoldiPeakCollection_sptr integratedPeakCollection = boost::make_shared<PoldiPeakCollection>(PoldiPeakCollection::Integral); integratedPeakCollection->setProfileFunctionName(profileFunctionName); // Preserve unit cell, point group assignCrystalData(integratedPeakCollection, rawPeakCollection); for (size_t i = 0; i < rawPeakCollection->peakCount(); ++i) { PoldiPeak_sptr peak = rawPeakCollection->peak(i); IPeakFunction_sptr profileFunction = boost::dynamic_pointer_cast<IPeakFunction>( FunctionFactory::Instance().createFunction(profileFunctionName)); profileFunction->setHeight(peak->intensity()); profileFunction->setFwhm(peak->fwhm(PoldiPeak::AbsoluteD)); PoldiPeak_sptr integratedPeak = peak->clone(); integratedPeak->setIntensity(UncertainValue(profileFunction->intensity())); integratedPeakCollection->addPeak(integratedPeak); } return integratedPeakCollection; }
PoldiPeak_sptr PoldiPeak::create(MillerIndices hkl, double dValue) { return PoldiPeak_sptr(new PoldiPeak( UncertainValue(dValue), UncertainValue(0.0), UncertainValue(0.0), hkl)); }
PoldiPeak_sptr PoldiPeak::create(double qValue, double intensity) { return PoldiPeak::create(UncertainValue(qValue), UncertainValue(intensity)); }
PoldiPeak_sptr PoldiPeak::create(double qValue) { return PoldiPeak::create(UncertainValue(qValue)); }