Skip to content

Commit

Permalink
Refs #10702. PoldiFitPeaks2D handles multiple phases
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Wedel committed Apr 23, 2015
1 parent 351424c commit 1f6f4e9
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 24 deletions.
18 changes: 15 additions & 3 deletions Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h
Expand Up @@ -71,6 +71,7 @@ class MANTID_SINQ_DLL PoldiFitPeaks2D : public API::Algorithm {
size_t parameterOffset, size_t nParams) const;

std::vector<PoldiPeakCollection_sptr> getPeakCollectionsFromInput() const;

protected:
Poldi2DFunction_sptr getFunctionIndividualPeaks(
std::string profileFunctionName,
Expand All @@ -94,10 +95,16 @@ class MANTID_SINQ_DLL PoldiFitPeaks2D : public API::Algorithm {

PoldiPeakCollection_sptr
getPeakCollection(const DataObjects::TableWorkspace_sptr &peakTable) const;

PoldiPeakCollection_sptr getIntegratedPeakCollection(
const PoldiPeakCollection_sptr &rawPeakCollection) const;

PoldiPeakCollection_sptr getNormalizedPeakCollection(
const PoldiPeakCollection_sptr &peakCollection) const;

std::vector<PoldiPeakCollection_sptr> getNormalizedPeakCollections(
const std::vector<PoldiPeakCollection_sptr> &peakCollections) const;

PoldiPeakCollection_sptr
getCountPeakCollection(const PoldiPeakCollection_sptr &peakCollection) const;

Expand All @@ -106,13 +113,18 @@ class MANTID_SINQ_DLL PoldiFitPeaks2D : public API::Algorithm {

PoldiPeakCollection_sptr
getPeakCollectionFromFunction(const API::IFunction_sptr &fitFunction);

std::vector<PoldiPeakCollection_sptr>
getCountPeakCollections(const API::IFunction_sptr &fitFunction);

Poldi2DFunction_sptr
getFunctionFromPeakCollection(const PoldiPeakCollection_sptr &peakCollection);
void addBackgroundTerms(Poldi2DFunction_sptr poldi2DFunction) const;

API::IAlgorithm_sptr
calculateSpectrum(const PoldiPeakCollection_sptr &peakCollection,
const API::MatrixWorkspace_sptr &matrixWorkspace);
API::IAlgorithm_sptr calculateSpectrum(
const std::vector<PoldiPeakCollection_sptr> &peakCollections,
const API::MatrixWorkspace_sptr &matrixWorkspace);

API::MatrixWorkspace_sptr
getWorkspace(const API::IAlgorithm_sptr &fitAlgorithm) const;
API::IFunction_sptr
Expand Down
140 changes: 119 additions & 21 deletions Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp
Expand Up @@ -124,11 +124,11 @@ void PoldiFitPeaks2D::init() {
declareProperty("LambdaMax", 5.0,
"Maximum wavelength for 1D spectrum calculation");

declareProperty(new WorkspaceProperty<TableWorkspace>(
"RefinedPoldiPeakWorkspace", "", Direction::Output),
declareProperty(new WorkspaceProperty<Workspace>("RefinedPoldiPeakWorkspace",
"", Direction::Output),
"Table workspace with fitted peaks.");

declareProperty(new WorkspaceProperty<ITableWorkspace>(
declareProperty(new WorkspaceProperty<Workspace>(
"RefinedCellParameters", "", Direction::Output, PropertyMode::Optional));
}

Expand Down Expand Up @@ -342,6 +342,48 @@ PoldiPeakCollection_sptr PoldiFitPeaks2D::getPeakCollectionFromFunction(
return normalizedPeaks;
}

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 (std::invalid_argument) {
// not a Poldi2DFunction - skip (the background functions)
}

offset += nLocalParams;
}

return countPeakCollections;
}

/**
* Returns a Poldi2DFunction that encapsulates individual peaks
*
Expand Down Expand Up @@ -620,30 +662,65 @@ void PoldiFitPeaks2D::exec() {
}
}

IAlgorithm_sptr fitAlgorithm = calculateSpectrum(peakCollections.front(), ws);
IAlgorithm_sptr fitAlgorithm = calculateSpectrum(peakCollections, ws);

IFunction_sptr fitFunction = getFunction(fitAlgorithm);

MatrixWorkspace_sptr outWs1D = get1DSpectrum(fitFunction, ws);

PoldiPeakCollection_sptr normalizedPeaks =
getPeakCollectionFromFunction(fitFunction);
PoldiPeakCollection_sptr integralPeaks =
getCountPeakCollection(normalizedPeaks);
std::vector<PoldiPeakCollection_sptr> integralPeaks =
getCountPeakCollections(fitFunction);

assignMillerIndices(peakCollections.front(), integralPeaks);
assignMillerIndices(peakCollections.front(), integralPeaks.front());

setProperty("OutputWorkspace", getWorkspace(fitAlgorithm));
setProperty("RefinedPoldiPeakWorkspace", integralPeaks->asTableWorkspace());

if (integralPeaks.size() == 1) {
setProperty("RefinedPoldiPeakWorkspace",
integralPeaks.front()->asTableWorkspace());
} else {
WorkspaceGroup_sptr peaksGroup = boost::make_shared<WorkspaceGroup>();

for (auto pc = integralPeaks.begin(); pc != integralPeaks.end(); ++pc) {
peaksGroup->addWorkspace((*pc)->asTableWorkspace());
}

setProperty("RefinedPoldiPeakWorkspace", peaksGroup);
}

setProperty("Calculated1DSpectrum", outWs1D);

bool isPawleyFit = getProperty("PawleyFit");
if (isPawleyFit) {
ITableWorkspace_sptr cellParameters = getRefinedCellParameters(fitFunction);
Poldi2DFunction_sptr poldi2DFunction =
boost::dynamic_pointer_cast<Poldi2DFunction>(fitFunction);

std::vector<ITableWorkspace_sptr> cells;

if (poldi2DFunction) {
for (size_t i = 0; i < poldi2DFunction->nFunctions(); ++i) {
try {
ITableWorkspace_sptr cell =
getRefinedCellParameters(poldi2DFunction->getFunction(i));
cells.push_back(cell);
}
catch (std::invalid_argument) {
// do nothing
}
}

if (cells.size() == 1) {
setProperty("RefinedCellParameters", cells.front());
} else {
WorkspaceGroup_sptr cellsGroup = boost::make_shared<WorkspaceGroup>();

for (auto it = cells.begin(); it != cells.end(); ++it) {
cellsGroup->addWorkspace(*it);
}

setProperty("RefinedCellParameters", cellsGroup);
}

if (cellParameters->rowCount() > 0) {
setProperty("RefinedCellParameters",
getRefinedCellParameters(fitFunction));
} else {
g_log.warning() << "Warning: Cell parameter table is empty.";
}
Expand Down Expand Up @@ -694,16 +771,22 @@ void PoldiFitPeaks2D::addBackgroundTerms(Poldi2DFunction_sptr poldi2DFunction)
* @return Instance of Fit-algorithm, after execution
*/
IAlgorithm_sptr PoldiFitPeaks2D::calculateSpectrum(
const PoldiPeakCollection_sptr &peakCollection,
const std::vector<PoldiPeakCollection_sptr> &peakCollections,
const MatrixWorkspace_sptr &matrixWorkspace) {
PoldiPeakCollection_sptr integratedPeaks =
getIntegratedPeakCollection(peakCollection);
PoldiPeakCollection_sptr normalizedPeakCollection =
getNormalizedPeakCollection(integratedPeaks);

Poldi2DFunction_sptr mdFunction =
getFunctionFromPeakCollection(normalizedPeakCollection);
std::vector<PoldiPeakCollection_sptr> normalizedPeakCollections =
getNormalizedPeakCollections(peakCollections);

// Create a Poldi2DFunction that collects all sub-functions
Poldi2DFunction_sptr mdFunction(new Poldi2DFunction);

// Add one Poldi2DFunction for each peak collection
for (auto pc = normalizedPeakCollections.begin();
pc != normalizedPeakCollections.end(); ++pc) {
mdFunction->addFunction(getFunctionFromPeakCollection(*pc));
}

// And finally background terms
addBackgroundTerms(mdFunction);

IAlgorithm_sptr fit = createChildAlgorithm("Fit", -1, -1, true);
Expand Down Expand Up @@ -1054,6 +1137,21 @@ PoldiPeakCollection_sptr PoldiFitPeaks2D::getNormalizedPeakCollection(
return normalizedPeakCollection;
}

std::vector<PoldiPeakCollection_sptr>
PoldiFitPeaks2D::getNormalizedPeakCollections(
const std::vector<PoldiPeakCollection_sptr> &peakCollections) const {
std::vector<PoldiPeakCollection_sptr> normalizedPeakCollections;

for (auto pc = peakCollections.begin(); pc != peakCollections.end(); ++pc) {
PoldiPeakCollection_sptr integratedPeakCollection =
getIntegratedPeakCollection(*pc);
normalizedPeakCollections.push_back(
getNormalizedPeakCollection(integratedPeakCollection));
}

return normalizedPeakCollections;
}

/**
* Converts normalized peak intensities to count based integral intensities
*
Expand Down

0 comments on commit 1f6f4e9

Please sign in to comment.