CompositeCluster.cpp 4.97 KB
Newer Older
1
#include "MantidCrystal/CompositeCluster.h"
Campbell, Stuart's avatar
Campbell, Stuart committed
2
#include <stdexcept>
3

4
5
6
7
8
9
10
11
12
namespace {
/**
 * Helper comparitor for finding IClusters based on an input label.
 */
class Comparitor {
private:
  size_t m_label;

public:
13
  explicit Comparitor(const size_t &label) : m_label(label) {}
14
15
16
17
18
  bool operator()(
      const boost::shared_ptr<Mantid::Crystal::ICluster> &pCluster) const {
    return pCluster->containsLabel(m_label);
  }
};
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
namespace Mantid {
namespace Crystal {

//----------------------------------------------------------------------------------------------
/** Constructor
 */
CompositeCluster::CompositeCluster() {}

//----------------------------------------------------------------------------------------------
/** Destructor
 */
CompositeCluster::~CompositeCluster() {}

/**
 * Integrate the composite cluster.
 * @param ws : Workspace to integrate
 * @return Integrated signal and error sq values.
 */
ICluster::ClusterIntegratedValues CompositeCluster::integrate(
    boost::shared_ptr<const Mantid::API::IMDHistoWorkspace> ws) const {

  double errorIntSQ = 0;
  double sigInt = 0;
  // Integrate owned clusters and add those results too.
  for (size_t i = 0; i < m_ownedClusters.size(); ++i) {
    auto integratedValues = m_ownedClusters[i]->integrate(ws);
    sigInt += integratedValues.get<0>();
    errorIntSQ += integratedValues.get<1>();
  }
  return ClusterIntegratedValues(sigInt, errorIntSQ);
}
52

53
54
55
56
57
58
59
60
61
62
/**
 * Write to an output histo workspace.
 * @param ws
 */
void CompositeCluster::writeTo(
    boost::shared_ptr<Mantid::API::IMDHistoWorkspace> ws) const {
  for (size_t i = 0; i < m_ownedClusters.size(); ++i) {
    m_ownedClusters[i]->writeTo(ws);
  }
}
63

64
65
66
67
68
69
70
71
72
73
74
75
76
/**
 * Get the label.
 * @return Current label.
 */
size_t CompositeCluster::getLabel() const {
  findMinimum();
  if (!m_label.is_initialized()) {
    throw std::runtime_error(
        "No child IClusters. CompositeCluster::getLabel() is not supported.");
  } else {
    return m_label.get(); // Assumes all are uniform.
  }
}
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/**
 * Get the original label. Doesn't make sense for composites, so wired through
 * to getLabel()
 * @return getLabel()
 */
size_t CompositeCluster::getOriginalLabel() const { return getLabel(); }

/**
 * Get the size of the composite. This is the total size of all owned clusters.
 * @return total size.
 */
size_t CompositeCluster::size() const {
  size_t size = 0;
  for (size_t i = 0; i < m_ownedClusters.size(); ++i) {
    size += m_ownedClusters[i]->size();
  }
  return size;
}
96

97
98
99
100
/// Add an index. This method does not apply to composite clusters.
void CompositeCluster::addIndex(const size_t &) {
  throw std::runtime_error("addIndex not implemented on CompositeCluster");
}
Owen Arnold's avatar
Owen Arnold committed
101

102
103
104
105
106
107
108
109
110
111
112
/**
 * Find the minimum label in the composite
 */
void CompositeCluster::findMinimum() const {
  if (!m_ownedClusters.empty()) {
    ICluster *minCluster = m_ownedClusters.front().get();
    size_t minLabel = minCluster->getLabel();
    for (size_t i = 1; i < m_ownedClusters.size(); ++i) {
      size_t temp = m_ownedClusters[i]->getLabel();
      if (temp < minLabel) {
        minLabel = temp;
113
114
      }
    }
115
116
117
    m_label = minLabel;
  }
}
118

119
120
121
122
/**
 * Convert the disjointSet to a uniform minimum value
 * @param disjointSet : DisjointSets to adapt.
 */
123
124
void CompositeCluster::toUniformMinimum(
    std::vector<DisjointElement> &disjointSet) {
125
126
127
128
129
130
131
132
  if (!m_ownedClusters.empty()) {
    ICluster *minCluster = m_ownedClusters.front().get();
    size_t minLabel = minCluster->getLabel();
    for (size_t i = 1; i < m_ownedClusters.size(); ++i) {
      size_t temp = m_ownedClusters[i]->getLabel();
      if (temp < minLabel) {
        minLabel = temp;
        minCluster = m_ownedClusters[i].get();
Owen Arnold's avatar
Owen Arnold committed
133
134
      }
    }
135
    m_label = minLabel;
Owen Arnold's avatar
Owen Arnold committed
136

137
138
139
    for (size_t i = 0; i < m_ownedClusters.size(); ++i) {
      m_ownedClusters[i]->setRootCluster(minCluster);
      m_ownedClusters[i]->toUniformMinimum(disjointSet);
140
    }
141
142
  }
}
143

144
145
146
147
148
149
150
/**
 * Get any representative index from this cluster
 * @return : Representative index.
 */
size_t CompositeCluster::getRepresentitiveIndex() const {
  return this->m_ownedClusters.front()->getRepresentitiveIndex();
}
Owen Arnold's avatar
Owen Arnold committed
151

152
153
154
155
156
157
158
159
160
/**
 * Set the root cluster
 * @param root : Root cluster to use
 */
void CompositeCluster::setRootCluster(ICluster const *root) {
  for (size_t i = 0; i < m_ownedClusters.size(); ++i) {
    m_ownedClusters[i]->setRootCluster(root);
  }
}
Owen Arnold's avatar
Owen Arnold committed
161

162
163
164
165
166
167
168
169
170
171
/**
 * Add other IClusters to own.
 * @param toOwn : Item to own
 */
void CompositeCluster::add(boost::shared_ptr<ICluster> &toOwn) {
  if (toOwn->size() > 0) // Do not add empty clusters.
  {
    m_ownedClusters.push_back(toOwn);
  }
}
172

173
174
175
176
177
178
179
180
181
182
183
/**
 * Does this cluster contain the label of the argument.
 * @param label : Label id to find
 * @return True only if that label is contained.
 */
bool CompositeCluster::containsLabel(const size_t &label) const {
  Comparitor comparitor(label);
  return m_ownedClusters.end() != std::find_if(m_ownedClusters.begin(),
                                               m_ownedClusters.end(),
                                               comparitor);
}
Owen Arnold's avatar
Owen Arnold committed
184

185
} // namespace Crystal
186
} // namespace Mantid