ReflectionGenerator.cpp 5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "MantidGeometry/Crystal/ReflectionGenerator.h"
#include "MantidGeometry/Crystal/BasicHKLFilters.h"
#include "MantidGeometry/Crystal/StructureFactorCalculatorSummation.h"
#include "MantidGeometry/Crystal/HKLGenerator.h"

namespace Mantid {
namespace Geometry {

using namespace Kernel;

/// Small helper functor to calculate d-Values from a unit cell.
class LatticeSpacingCalculator {
public:
14
  explicit LatticeSpacingCalculator(const UnitCell &cell) : m_cell(cell) {}
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

  double operator()(const V3D &hkl) { return m_cell.d(hkl); }

private:
  UnitCell m_cell;
};

/// Constructor
ReflectionGenerator::ReflectionGenerator(
    const CrystalStructure &crystalStructure,
    ReflectionConditionFilter defaultFilter)
    : m_crystalStructure(crystalStructure),
      m_sfCalculator(StructureFactorCalculatorFactory::create<
          StructureFactorCalculatorSummation>(m_crystalStructure)),
      m_defaultHKLFilter(getReflectionConditionFilter(defaultFilter)) {}

/// Returns the internally stored crystal structure
const CrystalStructure &ReflectionGenerator::getCrystalStructure() const {
  return m_crystalStructure;
}

/// Returns a DRangeFilter from the supplied d-limits and the internally stored
/// cell.
HKLFilter_const_sptr ReflectionGenerator::getDRangeFilter(double dMin,
                                                          double dMax) const {
  return boost::make_shared<const HKLFilterDRange>(m_crystalStructure.cell(),
                                                   dMin, dMax);
}

/// Returns a reflection condition HKLFilter based on the supplied enum.
HKLFilter_const_sptr ReflectionGenerator::getReflectionConditionFilter(
    ReflectionConditionFilter filter) {
  switch (filter) {
  case ReflectionConditionFilter::Centering:
    return boost::make_shared<const HKLFilterCentering>(
        m_crystalStructure.centering());
    break;
  case ReflectionConditionFilter::SpaceGroup:
    return boost::make_shared<const HKLFilterSpaceGroup>(
        m_crystalStructure.spaceGroup());
    break;
  case ReflectionConditionFilter::StructureFactor:
    return boost::make_shared<const HKLFilterStructureFactor>(m_sfCalculator);
  default:
    return HKLFilter_const_sptr();
  }
}

/// Returns a list of HKLs within the specified d-limits using the default
/// reflection condition filter.
std::vector<V3D> ReflectionGenerator::getHKLs(double dMin, double dMax) const {
  return getHKLs(dMin, dMax, m_defaultHKLFilter);
}

/// Returns a list of HKLs within the specified d-limits using the specified
/// filter. If the pointer is null, it's ignored.
std::vector<Kernel::V3D> ReflectionGenerator::getHKLs(
    double dMin, double dMax,
    HKLFilter_const_sptr reflectionConditionFilter) const {
  HKLGenerator generator(m_crystalStructure.cell(), dMin);

  HKLFilter_const_sptr filter = getDRangeFilter(dMin, dMax);
  if (reflectionConditionFilter) {
    filter = filter & reflectionConditionFilter;
  }

  std::vector<V3D> hkls;
  hkls.reserve(generator.size());

  std::remove_copy_if(generator.begin(), generator.end(),
                      std::back_inserter(hkls), (~filter)->fn());
  return hkls;
}

/// Returns a list of symetrically independent HKLs within the specified
/// d-limits using the default reflection condition filter.
std::vector<V3D> ReflectionGenerator::getUniqueHKLs(double dMin,
                                                    double dMax) const {
  return getUniqueHKLs(dMin, dMax, m_defaultHKLFilter);
}

/// Returns a list of symetrically independent HKLs within the specified
/// d-limits using the specified reflection condition filter.
std::vector<V3D> ReflectionGenerator::getUniqueHKLs(
    double dMin, double dMax,
    HKLFilter_const_sptr reflectionConditionFilter) const {
  HKLGenerator generator(m_crystalStructure.cell(), dMin);

  HKLFilter_const_sptr filter = getDRangeFilter(dMin, dMax);
  if (reflectionConditionFilter) {
    filter = filter & reflectionConditionFilter;
  }

  std::vector<V3D> hkls;
  hkls.reserve(generator.size());

  PointGroup_sptr pg = m_crystalStructure.spaceGroup()->getPointGroup();

  for (auto hkl = generator.begin(); hkl != generator.end(); ++hkl) {
    if (filter->isAllowed(*hkl)) {
      hkls.push_back(pg->getReflectionFamily(*hkl));
    }
  }

  std::sort(hkls.begin(), hkls.end());
  hkls.erase(std::unique(hkls.begin(), hkls.end()), hkls.end());

  return hkls;
}

/// Returns a list of d-values that correspond to the supplied hkl list, using
/// the unit cell of the stored crystal structure.
std::vector<double>
ReflectionGenerator::getDValues(const std::vector<V3D> &hkls) const {
  std::vector<double> dValues;
  dValues.reserve(hkls.size());

  std::transform(hkls.begin(), hkls.end(), std::back_inserter(dValues),
                 LatticeSpacingCalculator(m_crystalStructure.cell()));

  return dValues;
}

/// Returns a list of squared structure factor amplitudes corresponding to the
/// supplied list of HKLs.
std::vector<double>
ReflectionGenerator::getFsSquared(const std::vector<V3D> &hkls) const {
  return m_sfCalculator->getFsSquared(hkls);
}

} // namespace Geometry
} // namespace Mantid