/** * 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; }