示例#1
0
/** 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;
}
示例#2
0
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));
}
示例#3
0
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)));
  }
}
示例#4
0
/** 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;
}
示例#5
0
/// 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;
    }
  }
}
示例#8
0
/** 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);
    }
}
示例#10
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);
}
示例#11
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;
}
示例#12
0
PoldiPeak_sptr PoldiPeak::create(MillerIndices hkl, double dValue) {
  return PoldiPeak_sptr(new PoldiPeak(
      UncertainValue(dValue), UncertainValue(0.0), UncertainValue(0.0), hkl));
}
示例#13
0
PoldiPeak_sptr PoldiPeak::create(double qValue, double intensity) {
  return PoldiPeak::create(UncertainValue(qValue), UncertainValue(intensity));
}
示例#14
0
PoldiPeak_sptr PoldiPeak::create(double qValue) {
  return PoldiPeak::create(UncertainValue(qValue));
}