void PoldiIndexKnownCompounds::assignCrystalStructureParameters(
    PoldiPeakCollection_sptr &indexedPeaks,
    const PoldiPeakCollection_sptr &phasePeaks) const {

    indexedPeaks->setPointGroup(phasePeaks->pointGroup());
    indexedPeaks->setUnitCell(phasePeaks->unitCell());
}
/** Execute the algorithm.
   */
void PoldiCreatePeaksFromCell::exec() {
  // Get all user input regarding the unit cell
  SpaceGroup_const_sptr spaceGroup = getSpaceGroup(getProperty("SpaceGroup"));
  PointGroup_sptr pointGroup =
      PointGroupFactory::Instance().createPointGroupFromSpaceGroup(spaceGroup);
  UnitCell unitCell = getConstrainedUnitCell(getUnitCellFromProperties(),
                                             pointGroup->crystalSystem(),
                                             pointGroup->getCoordinateSystem());

  g_log.information() << "Constrained unit cell is: " << unitCellToStr(unitCell)
                      << '\n';

  CompositeBraggScatterer_sptr scatterers = CompositeBraggScatterer::create(
      IsotropicAtomBraggScattererParser(getProperty("Atoms"))());

  // Create a CrystalStructure-object for use with PoldiPeakCollection
  CrystalStructure crystalStructure(unitCell, spaceGroup, scatterers);

  double dMin = getProperty("LatticeSpacingMin");
  double dMax = getDMaxValue(unitCell);

  // Create PoldiPeakCollection using given parameters, set output workspace
  PoldiPeakCollection_sptr peaks =
      boost::make_shared<PoldiPeakCollection>(crystalStructure, dMin, dMax);

  setProperty("OutputWorkspace", peaks->asTableWorkspace());
}
/** Creates a vector of IndexCandidatePair-objects.
 *
 *  This function iterates through all peaks in the measured
 *PoldiPeakCollection, getting possible indexing candidates
 *  for each peak (see PoldiIndexKnownCompounds::getIndexCandidatePairs). If no
 *candidates are found it means that
 *  there are no reflections with similar d-spacings from the known compounds,
 *so it is treated as an unindexed peak.
 *  Otherwise, all candidates for this peak are appended to the list of existing
 *candidate pairs.
 *
 *  @param measured :: Measured peaks.
 *  @param knownCompoundPeaks :: Collections of expected peaks.
 *  @return Vector of index candidates.
 */
std::vector<IndexCandidatePair>
PoldiIndexKnownCompounds::getAllIndexCandidatePairs(
    const PoldiPeakCollection_sptr &measured,
    const std::vector<PoldiPeakCollection_sptr> &knownCompoundPeaks) {
    std::vector<IndexCandidatePair> candidates;

    size_t peakCount = measured->peakCount();
    for (size_t i = 0; i < peakCount; ++i) {
        PoldiPeak_sptr currentPeak = measured->peak(i);

        std::vector<IndexCandidatePair> currentCandidates =
            getIndexCandidatePairs(currentPeak, knownCompoundPeaks);

        if (currentCandidates.empty()) {
            collectUnindexedPeak(currentPeak);
        } else {
            candidates.insert(candidates.end(), currentCandidates.begin(),
                              currentCandidates.end());
        }

        g_log.information() << "    Peak at d="
                            << static_cast<double>(currentPeak->d()) << " has "
                            << currentCandidates.size() << " candidates."
                            << std::endl;
    }

    return candidates;
}
Exemple #4
0
/**
 * Returns a Poldi2DFunction that encapsulates individual peaks
 *
 * This function takes all peaks from the supplied peak collection and
 * generates an IPeakFunction of the type given in the name parameter, wraps
 * them in a Poldi2DFunction and returns it.
 *
 * @param profileFunctionName :: Profile function name.
 * @param peakCollection :: Peak collection with peaks to be used in the fit.
 * @return :: A Poldi2DFunction with peak profile functions.
 */
Poldi2DFunction_sptr PoldiFitPeaks2D::getFunctionIndividualPeaks(
    std::string profileFunctionName,
    const PoldiPeakCollection_sptr &peakCollection) const {
  auto mdFunction = boost::make_shared<Poldi2DFunction>();

  for (size_t i = 0; i < peakCollection->peakCount(); ++i) {
    PoldiPeak_sptr peak = peakCollection->peak(i);

    boost::shared_ptr<PoldiSpectrumDomainFunction> peakFunction =
        boost::dynamic_pointer_cast<PoldiSpectrumDomainFunction>(
            FunctionFactory::Instance().createFunction(
                "PoldiSpectrumDomainFunction"));

    if (!peakFunction) {
      throw std::invalid_argument(
          "Cannot process null pointer poldi function.");
    }

    peakFunction->setDecoratedFunction(profileFunctionName);

    IPeakFunction_sptr wrappedProfile =
        boost::dynamic_pointer_cast<IPeakFunction>(
            peakFunction->getProfileFunction());

    if (wrappedProfile) {
      wrappedProfile->setCentre(peak->d());
      wrappedProfile->setFwhm(peak->fwhm(PoldiPeak::AbsoluteD));
      wrappedProfile->setIntensity(peak->intensity());
    }

    mdFunction->addFunction(peakFunction);
  }

  return mdFunction;
}
std::vector<RefinedRange_sptr> PoldiFitPeaks1D2::getRefinedRanges(
    const PoldiPeakCollection_sptr &peaks) const {
  std::vector<RefinedRange_sptr> ranges;
  for (size_t i = 0; i < peaks->peakCount(); ++i) {
    ranges.push_back(
        boost::make_shared<RefinedRange>(peaks->peak(i), m_fwhmMultiples));
  }

  return ranges;
}
Exemple #6
0
/**
 * Returns a Poldi2DFunction that encapsulates a PawleyFunction
 *
 * This function creates a PawleyFunction using the supplied profile function
 * name and the crystal system as well as initial cell from the input
 * properties of the algorithm and wraps it in a Poldi2DFunction.
 *
 * The cell is refined using LatticeFunction to get better starting values.
 *
 * Because the peak intensities are integral at this step but PawleyFunction
 * expects peak heights, a profile function is created and
 * setIntensity/height-methods are used to convert.
 *
 * @param profileFunctionName :: Profile function name for PawleyFunction.
 * @param peakCollection :: Peak collection with peaks to be used in the fit.
 * @return :: A Poldi2DFunction with a PawleyFunction.
 */
Poldi2DFunction_sptr PoldiFitPeaks2D::getFunctionPawley(
    std::string profileFunctionName,
    const PoldiPeakCollection_sptr &peakCollection) {
  auto mdFunction = boost::make_shared<Poldi2DFunction>();

  boost::shared_ptr<PoldiSpectrumPawleyFunction> poldiPawleyFunction =
      boost::dynamic_pointer_cast<PoldiSpectrumPawleyFunction>(
          FunctionFactory::Instance().createFunction(
              "PoldiSpectrumPawleyFunction"));

  if (!poldiPawleyFunction) {
    throw std::invalid_argument("Could not create pawley function.");
  }

  poldiPawleyFunction->setDecoratedFunction("PawleyFunction");

  IPawleyFunction_sptr pawleyFunction =
      poldiPawleyFunction->getPawleyFunction();
  pawleyFunction->setProfileFunction(profileFunctionName);

  // Extract crystal system from peak collection
  PointGroup_sptr pointGroup = peakCollection->pointGroup();
  if (!pointGroup) {
    throw std::invalid_argument("Can not initialize pawley function properly - "
                                "peaks do not have point group.");
  }

  std::string latticeSystem = getLatticeSystemFromPointGroup(pointGroup);
  pawleyFunction->setLatticeSystem(latticeSystem);

  UnitCell cell = peakCollection->unitCell();
  // Extract unit cell from peak collection
  pawleyFunction->setUnitCell(getRefinedStartingCell(
      unitCellToStr(cell), latticeSystem, peakCollection));

  IPeakFunction_sptr pFun = boost::dynamic_pointer_cast<IPeakFunction>(
      FunctionFactory::Instance().createFunction(profileFunctionName));

  for (size_t i = 0; i < peakCollection->peakCount(); ++i) {
    PoldiPeak_sptr peak = peakCollection->peak(i);

    pFun->setCentre(peak->d());
    pFun->setFwhm(peak->fwhm(PoldiPeak::AbsoluteD));
    pFun->setIntensity(peak->intensity());

    pawleyFunction->addPeak(peak->hkl().asV3D(),
                            peak->fwhm(PoldiPeak::AbsoluteD), pFun->height());
  }

  pawleyFunction->fix(pawleyFunction->parameterIndex("f0.ZeroShift"));
  mdFunction->addFunction(poldiPawleyFunction);

  return mdFunction;
}
/// 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);
    }
}
/** Scales the intensities of all peaks in the collection by the supplied
 *scattering contribution
 *
 *  This method scales intensities of peaks contained in the supplied
 *PoldiPeakCollection
 *  (if it's a null-pointer, the method throws an std::invalid_argument
 *exception). The original
 *  intensity is multiplied by the contribution factor.
 *
 *  @param peakCollection :: PoldiPeakCollection with expected peaks of one
 *phase.
 *  @param contribution :: Scattering contribution of that material.
 */
void PoldiIndexKnownCompounds::scaleIntensityEstimates(
    const PoldiPeakCollection_sptr &peakCollection, double contribution) const {
    if (!peakCollection) {
        throw std::invalid_argument(
            "Cannot assign intensities to invalid PoldiPeakCollection.");
    }

    size_t peakCount = peakCollection->peakCount();

    for (size_t i = 0; i < peakCount; ++i) {
        PoldiPeak_sptr peak = peakCollection->peak(i);

        peak->setIntensity(peak->intensity() * contribution);
    }
}
TableWorkspace_sptr PoldiPeakSummary::getSummaryTable(
    const PoldiPeakCollection_sptr &peakCollection) const {
  if (!peakCollection) {
    throw std::invalid_argument(
        "Cannot create summary of a null PoldiPeakCollection.");
  }

  TableWorkspace_sptr peakResultWorkspace = getInitializedResultWorkspace();

  for (size_t i = 0; i < peakCollection->peakCount(); ++i) {
    storePeakSummary(peakResultWorkspace->appendRow(), peakCollection->peak(i));
  }

  return peakResultWorkspace;
}
size_t PoldiIndexKnownCompounds::getMaximumIntensityPeakIndex(
    const PoldiPeakCollection_sptr &peakCollection) const {
    double maxInt = 0.0;
    size_t maxIndex = 0;

    for (size_t i = 0; i < peakCollection->peakCount(); ++i) {
        PoldiPeak_sptr currentPeak = peakCollection->peak(i);
        double currentInt = currentPeak->intensity();
        if (currentInt > maxInt) {
            maxInt = currentInt;
            maxIndex = i;
        }
    }

    return maxIndex;
}
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;
}
Exemple #12
0
/// Assign Miller indices from one peak collection to another.
void PoldiFitPeaks2D::assignMillerIndices(const PoldiPeakCollection_sptr &from,
                                          PoldiPeakCollection_sptr &to) const {
  if (!from || !to) {
    throw std::invalid_argument("Cannot process invalid peak collections.");
  }

  if (from->peakCount() != to->peakCount()) {
    throw std::runtime_error(
        "Cannot assign indices if number of peaks does not match.");
  }

  for (size_t i = 0; i < from->peakCount(); ++i) {
    PoldiPeak_sptr fromPeak = from->peak(i);
    PoldiPeak_sptr toPeak = to->peak(i);

    toPeak->setHKL(fromPeak->hkl());
  }
}
PoldiPeakCollection_sptr
PoldiFitPeaks1D2::fitPeaks(const PoldiPeakCollection_sptr &peaks) {
  g_log.information() << "Peaks to fit: " << peaks->peakCount() << std::endl;

  std::vector<RefinedRange_sptr> rawRanges = getRefinedRanges(peaks);
  std::vector<RefinedRange_sptr> reducedRanges = getReducedRanges(rawRanges);

  g_log.information() << "Ranges used for fitting: " << reducedRanges.size()
                      << std::endl;

  Workspace2D_sptr dataWorkspace = getProperty("InputWorkspace");
  m_fitplots->removeAll();

  for (size_t i = 0; i < reducedRanges.size(); ++i) {
    RefinedRange_sptr currentRange = reducedRanges[i];
    int nMin = getBestChebyshevPolynomialDegree(dataWorkspace, currentRange);

    if (nMin > -1) {
      IAlgorithm_sptr fit = getFitAlgorithm(dataWorkspace, currentRange, nMin);
      fit->execute();

      IFunction_sptr fitFunction = fit->getProperty("Function");
      CompositeFunction_sptr composite =
          boost::dynamic_pointer_cast<CompositeFunction>(fitFunction);

      if (!composite) {
        throw std::runtime_error("Not a composite function!");
      }

      std::vector<PoldiPeak_sptr> peaks = currentRange->getPeaks();
      for (size_t i = 0; i < peaks.size(); ++i) {
        setValuesFromProfileFunction(peaks[i], composite->getFunction(i));
        MatrixWorkspace_sptr fpg = fit->getProperty("OutputWorkspace");
        m_fitplots->addWorkspace(fpg);
      }
    }
  }

  return getReducedPeakCollection(peaks);
}
Exemple #14
0
/**
 * 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);
}
Exemple #15
0
/**
 * 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;
}
/** Execute the algorithm.
   */
void PoldiCreatePeaksFromCell::exec() {
  // Get all user input regarding the unit cell
  SpaceGroup_const_sptr spaceGroup = getSpaceGroup(getProperty("SpaceGroup"));
  PointGroup_sptr pointGroup =
      PointGroupFactory::Instance().createPointGroupFromSpaceGroupSymbol(
          spaceGroup->hmSymbol());
  UnitCell unitCell = getConstrainedUnitCell(getUnitCellFromProperties(),
                                             pointGroup->crystalSystem());
  CompositeBraggScatterer_sptr scatterers = getScatterers(getProperty("Atoms"));

  // Create a CrystalStructure-object for use with PoldiPeakCollection
  CrystalStructure_sptr crystalStructure =
      boost::make_shared<CrystalStructure>(unitCell, spaceGroup, scatterers);

  double dMin = getProperty("LatticeSpacingMin");
  double dMax = getDMaxValue(unitCell);

  // Create PoldiPeakCollection using given parameters, set output workspace
  PoldiPeakCollection_sptr peaks =
      boost::make_shared<PoldiPeakCollection>(crystalStructure, dMin, dMax);

  setProperty("OutputWorkspace", peaks->asTableWorkspace());
}
/// Uses PoldiIndexKnownCompounds::isCandidate to find all candidates for
/// supplied peak in the candidate peak collections.
std::vector<IndexCandidatePair>
PoldiIndexKnownCompounds::getIndexCandidatePairs(
    const PoldiPeak_sptr &peak,
    const std::vector<PoldiPeakCollection_sptr> &candidateCollections) const {
    std::vector<IndexCandidatePair> indexCandidates;

    for (size_t i = 0; i < candidateCollections.size(); ++i) {
        PoldiPeakCollection_sptr currentCandidateCollection =
            candidateCollections[i];

        size_t peakCount = currentCandidateCollection->peakCount();
        for (size_t p = 0; p < peakCount; ++p) {
            PoldiPeak_sptr currentCandidate = currentCandidateCollection->peak(p);

            if (isCandidate(peak, currentCandidate)) {
                indexCandidates.push_back(
                    IndexCandidatePair(peak, currentCandidate, i));
            }
        }
    }

    return indexCandidates;
}
void PoldiFitPeaks1D2::exec() {
  setPeakFunction(getProperty("PeakFunction"));

  // Number of points around the peak center to use for the fit
  m_fwhmMultiples = getProperty("FwhmMultiples");
  m_maxRelativeFwhm = getProperty("MaximumRelativeFwhm");

  // try to construct PoldiPeakCollection from provided TableWorkspace
  TableWorkspace_sptr poldiPeakTable = getProperty("PoldiPeakTable");
  m_peaks = getInitializedPeakCollection(poldiPeakTable);

  PoldiPeakCollection_sptr fittedPeaksNew = fitPeaks(m_peaks);
  PoldiPeakCollection_sptr fittedPeaksOld = m_peaks;

  int i = 0;
  while (fittedPeaksNew->peakCount() < fittedPeaksOld->peakCount() || i < 1) {
    fittedPeaksOld = fittedPeaksNew;
    fittedPeaksNew = fitPeaks(fittedPeaksOld);
    ++i;
  }

  setProperty("OutputWorkspace", fittedPeaksNew->asTableWorkspace());
  setProperty("FitPlotsWorkspace", m_fitplots);
}
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;
}
/** Execute the algorithm.
   */
void PoldiIndexKnownCompounds::exec() {
    g_log.information() << "Starting POLDI peak indexing." << std::endl;

    DataObjects::TableWorkspace_sptr peakTableWorkspace =
        getProperty("InputWorkspace");

    PoldiPeakCollection_sptr unindexedPeaks =
        boost::make_shared<PoldiPeakCollection>(peakTableWorkspace);
    g_log.information() << "  Number of peaks: " << unindexedPeaks->peakCount()
                        << std::endl;

    std::vector<Workspace_sptr> workspaces =
        getWorkspaces(getProperty("CompoundWorkspaces"));
    std::vector<PoldiPeakCollection_sptr> peakCollections =
        getPeakCollections(workspaces);
    g_log.information() << "  Number of phases: " << peakCollections.size()
                        << std::endl;

    /* The procedure is much easier to formulate with some state stored in member
     * variables,
     * which are initialized either from user input or from some defaults.
     */
    setMeasuredPeaks(unindexedPeaks);
    setExpectedPhases(peakCollections);
    setExpectedPhaseNames(getWorkspaceNames(workspaces));

    initializeUnindexedPeaks();
    initializeIndexedPeaks(m_expectedPhases);

    /* For calculating scores in the indexing procedure, scattering contributions
     * are used.
     * The structure factors are scaled accordingly.
     */
    std::vector<double> contributions = getContributions(m_expectedPhases.size());
    std::vector<double> normalizedContributions =
        getNormalizedContributions(contributions);

    scaleIntensityEstimates(peakCollections, normalizedContributions);
    scaleToExperimentalValues(peakCollections, unindexedPeaks);

    // Tolerances on the other hand are handled as "FWHM".
    std::vector<double> tolerances = getTolerances(m_expectedPhases.size());
    assignFwhmEstimates(peakCollections, tolerances);

    // With all necessary state assigned, the indexing procedure can be executed
    indexPeaks(unindexedPeaks, peakCollections);

    g_log.information() << "  Unindexed peaks: " << m_unindexedPeaks->peakCount()
                        << std::endl;

    /* Finally, the peaks are put into separate workspaces, determined by
     * the phase they have been attributed to, plus unindexed peaks.
     */
    std::string inputWorkspaceName = getPropertyValue("InputWorkspace");
    WorkspaceGroup_sptr outputWorkspaces = boost::make_shared<WorkspaceGroup>();

    for (size_t i = 0; i < m_indexedPeaks.size(); ++i) {
        PoldiPeakCollection_sptr intensitySorted =
            getIntensitySortedPeakCollection(m_indexedPeaks[i]);

        assignCrystalStructureParameters(intensitySorted, m_expectedPhases[i]);

        ITableWorkspace_sptr tableWs = intensitySorted->asTableWorkspace();
        AnalysisDataService::Instance().addOrReplace(
            inputWorkspaceName + "_indexed_" + m_phaseNames[i], tableWs);

        outputWorkspaces->addWorkspace(tableWs);
    }

    ITableWorkspace_sptr unindexedTableWs = m_unindexedPeaks->asTableWorkspace();

    AnalysisDataService::Instance().addOrReplace(
        inputWorkspaceName + "_unindexed", unindexedTableWs);
    outputWorkspaces->addWorkspace(unindexedTableWs);

    setProperty("OutputWorkspace", outputWorkspaces);
}
Exemple #21
0
/// Copy crystal data from source to target collection to preserve during
/// integration etc.
void PoldiFitPeaks2D::assignCrystalData(
    PoldiPeakCollection_sptr &targetCollection,
    const PoldiPeakCollection_sptr &sourceCollection) const {
  targetCollection->setUnitCell(sourceCollection->unitCell());
  targetCollection->setPointGroup(sourceCollection->pointGroup());
}
Exemple #22
0
/**
 * 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;
}
double PoldiIndexKnownCompounds::getMaximumIntensity(
    const PoldiPeakCollection_sptr &peakCollection) const {
    size_t i = getMaximumIntensityPeakIndex(peakCollection);

    return peakCollection->peak(i)->intensity();
}
Exemple #24
0
/**
 * 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;
}