-
Notifications
You must be signed in to change notification settings - Fork 122
/
SmoothNeighbours.h
149 lines (131 loc) · 4.65 KB
/
SmoothNeighbours.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
147
148
149
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2007 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#pragma once
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/Algorithm.h"
#include "MantidAlgorithms/DllConfig.h"
#include "MantidAlgorithms/WeightingStrategy.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidDataObjects/Workspace2D.h"
#include <boost/scoped_ptr.hpp>
namespace Mantid {
namespace Algorithms {
using SpectraDistanceMap = std::map<specnum_t, Mantid::Kernel::V3D>;
/*
Filters spectra detector list by radius.
*/
class MANTID_ALGORITHMS_DLL RadiusFilter {
public:
/**
Constructor
@param cutoff : radius cutoff for filtering
*/
RadiusFilter(double cutoff) : m_cutoff(cutoff) {
if (cutoff < 0) {
throw std::invalid_argument(
"RadiusFilter - Cannot have a negative cutoff.");
}
}
/**
Apply the filtering based on radius.
@param unfiltered : unfiltered spectra-distance map.
@return filtered spectra-distance map.
*/
SpectraDistanceMap apply(SpectraDistanceMap &unfiltered) const {
SpectraDistanceMap neighbSpectra;
double cutoff{m_cutoff};
std::copy_if(
unfiltered.begin(), unfiltered.end(),
std::inserter(neighbSpectra, neighbSpectra.end()),
[cutoff](
const std::pair<specnum_t, Mantid::Kernel::V3D> &spectraDistance) {
return spectraDistance.second.norm() <= cutoff;
});
return neighbSpectra;
}
private:
/// Radius cutoff.
double m_cutoff;
};
/** Smooth neighboring pixels.
@authors Janik Zikovsky, Vickie Lynch, SNS
@date Oct 2010
*/
class MANTID_ALGORITHMS_DLL SmoothNeighbours : public API::Algorithm {
public:
/// Default constructor
SmoothNeighbours();
/// Algorithm's name for identification overriding a virtual method
const std::string name() const override { return "SmoothNeighbours"; }
/// Summary of algorithms purpose
const std::string summary() const override {
return "Perform a moving-average smoothing by summing spectra of nearest "
"neighbours over the face of detectors.";
}
/// Algorithm's version for identification overriding a virtual method
int version() const override { return (1); }
const std::vector<std::string> seeAlso() const override {
return {"SmoothData"};
}
/// Algorithm's category for identification overriding a virtual method
const std::string category() const override {
return "Transforms\\Smoothing";
}
private:
// Overridden Algorithm methods
void init() override;
void exec() override;
void execWorkspace2D();
void execEvent(Mantid::DataObjects::EventWorkspace_sptr &ws);
void findNeighboursRectangular();
void findNeighboursUbiqutious();
/// Sets the weighting stragegy.
void setWeightingStrategy(const std::string &strategyName, double &cutOff);
/// Translate the entered radius into meters.
double translateToMeters(const std::string &radiusUnits,
const double &enteredRadius) const;
/// Build the instrument/detector setup in workspace
void setupNewInstrument(API::MatrixWorkspace &outws) const;
/// Build the instrument/detector setup in workspace
void spreadPixels(const API::MatrixWorkspace_sptr &outws);
/// Non rectangular detector group name
static const std::string NON_UNIFORM_GROUP;
/// Rectangular detector group name
static const std::string RECTANGULAR_GROUP;
/// Input workspace name
static const std::string INPUT_WORKSPACE;
/// Number to sum
int AdjX;
/// Number to sum
int AdjY;
/// Edge pixels to ignore
int Edge;
/// Radius to search nearest neighbours
double Radius;
/// Number of neighbours
int nNeighbours;
/// Weight the neighbours during summing
boost::scoped_ptr<WeightingStrategy> WeightedSum;
/// PreserveEvents
bool PreserveEvents;
/// expand by pixel IDs
bool expandSumAllPixels;
/// number of output workspace pixels
size_t outWI;
/// Input workspace
Mantid::API::MatrixWorkspace_sptr inWS;
/// Each neighbours is specified as a pair with workspace index, weight.
using weightedNeighbour = std::pair<size_t, double>;
/// Vector of list of neighbours (with weight) for each workspace index.
std::vector<std::vector<weightedNeighbour>> m_neighbours;
/// Progress reporter
std::unique_ptr<Mantid::API::Progress> m_progress = nullptr;
};
} // namespace Algorithms
} // namespace Mantid