/** * Converts normalized peak intensities to count based integral intensities * * This operation is the opposite of getNormalizedPeakCollection and is used * to convert the intensities back to integral intensities. * * @param peakCollection :: PoldiPeakCollection with normalized intensities * @return PoldiPeakCollection with integral intensities */ PoldiPeakCollection_sptr PoldiFitPeaks2D::getCountPeakCollection( const PoldiPeakCollection_sptr &peakCollection) const { if (!peakCollection) { throw std::invalid_argument( "Cannot proceed with invalid PoldiPeakCollection."); } if (!m_timeTransformer) { throw std::invalid_argument("Cannot proceed without PoldiTimeTransformer."); } PoldiPeakCollection_sptr countPeakCollection = boost::make_shared<PoldiPeakCollection>(PoldiPeakCollection::Integral); countPeakCollection->setProfileFunctionName( peakCollection->getProfileFunctionName()); // Get crystal data into new peak collection assignCrystalData(countPeakCollection, peakCollection); for (size_t i = 0; i < peakCollection->peakCount(); ++i) { PoldiPeak_sptr peak = peakCollection->peak(i); double calculatedIntensity = m_timeTransformer->calculatedTotalIntensity(peak->d()); PoldiPeak_sptr countPeak = peak->clone(); countPeak->setIntensity(peak->intensity() * calculatedIntensity); countPeakCollection->addPeak(countPeak); } return countPeakCollection; }
PoldiPeakCollection_sptr PoldiFitPeaks1D2::getReducedPeakCollection( const PoldiPeakCollection_sptr &peaks) const { PoldiPeakCollection_sptr reducedPeaks = boost::make_shared<PoldiPeakCollection>(); reducedPeaks->setProfileFunctionName(peaks->getProfileFunctionName()); for (size_t i = 0; i < peaks->peakCount(); ++i) { PoldiPeak_sptr currentPeak = peaks->peak(i); if (peakIsAcceptable(currentPeak)) { reducedPeaks->addPeak(currentPeak); } } return reducedPeaks; }
PoldiPeakCollection_sptr PoldiIndexKnownCompounds::getIntensitySortedPeakCollection( const PoldiPeakCollection_sptr &peaks) const { std::vector<PoldiPeak_sptr> peakVector(peaks->peaks()); std::sort(peakVector.begin(), peakVector.end(), boost::bind<bool>(&PoldiPeak::greaterThan, _1, _2, &PoldiPeak::intensity)); PoldiPeakCollection_sptr sortedPeaks = boost::make_shared<PoldiPeakCollection>(peaks->intensityType()); for (size_t i = 0; i < peakVector.size(); ++i) { sortedPeaks->addPeak(peakVector[i]->clone()); } return sortedPeaks; }
/** * Construct a PoldiPeakCollection from a Poldi2DFunction * * This method performs the opposite operation of *getFunctionFromPeakCollection. * It takes a function, checks if it's of the proper type and turns the * information into a PoldiPeakCollection. * * @param Poldi2DFunction with one PoldiSpectrumDomainFunction per peak * @return PoldiPeakCollection containing peaks with normalized intensities */ PoldiPeakCollection_sptr PoldiFitPeaks2D::getPeakCollectionFromFunction( const IFunction_sptr &fitFunction) { Poldi2DFunction_sptr poldi2DFunction = boost::dynamic_pointer_cast<Poldi2DFunction>(fitFunction); if (!poldi2DFunction) { throw std::invalid_argument( "Cannot process function that is not a Poldi2DFunction."); } PoldiPeakCollection_sptr normalizedPeaks = boost::make_shared<PoldiPeakCollection>(PoldiPeakCollection::Integral); boost::shared_ptr<const Kernel::DblMatrix> covarianceMatrix = poldi2DFunction->getCovarianceMatrix(); size_t offset = 0; for (size_t i = 0; i < poldi2DFunction->nFunctions(); ++i) { boost::shared_ptr<PoldiSpectrumPawleyFunction> poldiPawleyFunction = boost::dynamic_pointer_cast<PoldiSpectrumPawleyFunction>( poldi2DFunction->getFunction(i)); // If it's a Pawley function, there are several peaks in one function. if (poldiPawleyFunction) { IPawleyFunction_sptr pawleyFunction = poldiPawleyFunction->getPawleyFunction(); if (pawleyFunction) { CompositeFunction_sptr decoratedFunction = boost::dynamic_pointer_cast<CompositeFunction>( pawleyFunction->getDecoratedFunction()); offset = decoratedFunction->getFunction(0)->nParams(); for (size_t j = 0; j < pawleyFunction->getPeakCount(); ++j) { IPeakFunction_sptr profileFunction = pawleyFunction->getPeakFunction(j); size_t nLocalParams = profileFunction->nParams(); boost::shared_ptr<Kernel::DblMatrix> localCov = getLocalCovarianceMatrix(covarianceMatrix, offset, nLocalParams); profileFunction->setCovarianceMatrix(localCov); // Increment offset for next function offset += nLocalParams; V3D peakHKL = pawleyFunction->getPeakHKL(j); PoldiPeak_sptr peak = getPeakFromPeakFunction(profileFunction, peakHKL); normalizedPeaks->addPeak(peak); } } break; } // Otherwise, it's just one peak in this function. boost::shared_ptr<PoldiSpectrumDomainFunction> peakFunction = boost::dynamic_pointer_cast<PoldiSpectrumDomainFunction>( poldi2DFunction->getFunction(i)); if (peakFunction) { IPeakFunction_sptr profileFunction = boost::dynamic_pointer_cast<IPeakFunction>( peakFunction->getProfileFunction()); // Get local covariance matrix size_t nLocalParams = profileFunction->nParams(); boost::shared_ptr<Kernel::DblMatrix> localCov = getLocalCovarianceMatrix(covarianceMatrix, offset, nLocalParams); profileFunction->setCovarianceMatrix(localCov); // Increment offset for next function offset += nLocalParams; PoldiPeak_sptr peak = getPeakFromPeakFunction(profileFunction, V3D(0, 0, 0)); normalizedPeaks->addPeak(peak); } } return normalizedPeaks; }
/** * 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; }