OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
OpalFilter.cpp
Go to the documentation of this file.
1//
2// Class OpalFilter
3// The class for the Filter Object.
4// A FILTER definition is used to define a filter which can be applied
5// to a 1D histogram in order to get rid of noise.
6//
7// Copyright (c) 2008 - 2022, Christof Metzger-Kraus
8// All rights reserved
9//
10// This file is part of OPAL.
11//
12// OPAL is free software: you can redistribute it and/or modify
13// it under the terms of the GNU General Public License as published by
14// the Free Software Foundation, either version 3 of the License, or
15// (at your option) any later version.
16//
17// You should have received a copy of the GNU General Public License
18// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
19//
21
25#include "Filters/Filters.h"
26#include "Physics/Physics.h"
28
29#include "Utility/IpplInfo.h"
30
31#include <cmath>
32#include <unordered_map>
33
34#define NPOINTS_DEFAULT 129
35#define NLEFT_DEFAULT 64
36#define NRIGHT_DEFAULT 64
37#define POLYORDER_DEFAULT 1
38
39extern Inform *gmsg;
40
41// The attributes of class OpalFilter.
42namespace {
43 enum {
44 TYPE, // The type of filter
45 NFREQ, // Number of frequencies in fixedFFTLowPass filter
46 THRESHOLD, // Relative threshold for amplitude of frequency in relativeFFTLowPass
47 NPOINTS, // Number of points in Savitzky-Golay filter
48 NLEFT, // Number of points to the left in S-G filter
49 NRIGHT, // Number of points to the right in S-G filter
50 POLYORDER, // Polynomial order in S-G Filter
51 SIZE
52 };
53}
54
56 Definition(SIZE, "FILTER",
57 "The \"FILTER\" statement defines a 1 dimensional filter to be "
58 "applied on histogram."),
59 filter_m(0) {
61 ("TYPE", "Specifies the type of filter.",
62 {"SAVITZKY-GOLAY", "FIXEDFFTLOWPASS", "RELATIVEFFTLOWPASS", "STENCIL"});
63
65 ("NFREQ", "Number of frequencies to use in fixedFFTLowPass filter", 9.);
66
67 itsAttr[THRESHOLD] = Attributes::makeReal
68 ("THRESHOLD", "Relative threshold for amplitude of frequencies in relativeFFTLowPass filter", 1.e-6);
69
71 ("NPOINTS", "Number of points in Savitzky-Golay filter", NPOINTS_DEFAULT);
72
74 ("NLEFT", "Number of points to the left in Savitzky-Golay filter", NLEFT_DEFAULT);
75
77 ("NRIGHT", "Number of points to the right in Savitzky-Golay filter", NRIGHT_DEFAULT);
78
79 itsAttr[POLYORDER] = Attributes::makeReal
80 ("POLYORDER", "Polynomial order for local fit-function in Savitzky-Golay filter", POLYORDER_DEFAULT);
81
83
84 OpalFilter* defFilter = clone("UNNAMED_FILTER");
85 defFilter->builtin = true;
86
87 try {
88 defFilter->update();
89 OpalData::getInstance()->define(defFilter);
90 } catch(...) {
91 delete defFilter;
92 }
93}
94
95
96OpalFilter::OpalFilter(const std::string& name, OpalFilter* parent):
97 Definition(name, parent),
98 filter_m(0)
99{}
100
101
103 if (filter_m)
104 delete filter_m;
105}
106
107
109 // Can replace only by another WAKE.
110 return dynamic_cast<OpalFilter*>(object) != 0;
111}
112
113
114OpalFilter *OpalFilter::clone(const std::string& name) {
115 return new OpalFilter(name, this);
116}
117
118
120 update();
121}
122
123
124OpalFilter* OpalFilter::find(const std::string& name) {
125 OpalFilter* filter = dynamic_cast<OpalFilter*>(OpalData::getInstance()->find(name));
126
127 if (filter == 0) {
128 throw OpalException("OpalFilter::find()",
129 "OpalFilter \"" + name + "\" not found.");
130 }
131 return filter;
132}
133
134
136 // Set default name.
137 if (getOpalName().empty()) setOpalName("UNNAMED_FILTER");
138}
139
140
142 if (filter_m == 0) {
143 *gmsg << "* ************* F I L T E R ************************************************************" << endl;
144 *gmsg << "OpalFilter::initOpalFilterfunction " << endl;
145 *gmsg << "* **********************************************************************************" << endl;
146
147 static const std::unordered_map<std::string, FilterType> stringFilterType_s = {
148 {"SAVITZKY-GOLAY", FilterType::SAVITZKYGOLAY},
149 {"FIXEDFFTLOWPASS", FilterType::FIXEDFFTLOWPASS},
150 {"RELATIVEFFTLOWPASS", FilterType::RELATIVEFFTLOWPASS},
151 {"STENCIL", FilterType::STENCIL}
152 };
153
154 FilterType type = stringFilterType_s.at(Attributes::getString(itsAttr[TYPE]));
155 switch (type) {
157 int num_points = (int)(Attributes::getReal(itsAttr[NPOINTS]));
158 int num_points_left = (int)(Attributes::getReal(itsAttr[NLEFT]));
159 int num_points_right = (int)(Attributes::getReal(itsAttr[NRIGHT]));
160 int polynomial_order = std::abs((int)(Attributes::getReal(itsAttr[POLYORDER])));
161
162 Inform svg("Savitzky-Golay: ");
163 if (num_points_left < 0) {
164 svg << "Number of points to the left negative; using default (" << NLEFT_DEFAULT << ");" << endl;
165 num_points_left = NLEFT_DEFAULT;
166 }
167 if (num_points_right < 0) {
168 svg << "Number of points to the right negative; using default (" << NRIGHT_DEFAULT << ");" << endl;
169 num_points_right = NRIGHT_DEFAULT;
170 }
171 if (num_points < num_points_left + num_points_right) {
172 svg << "Total number of points small than sum of the ones to the left and to the right plus 1; using default (NLEFT + NRIGHT + 1);" << endl;
173 num_points = num_points_left + num_points_right + 1;
174 }
175 if (polynomial_order > num_points_left + num_points_right) {
176 svg << "Polynomial order bigger than sum of points to the left and to the right; using default (NLEFT + NRIGHT);" << endl;
177 polynomial_order = num_points_left + num_points_right;
178 }
179
180 filter_m = new SavitzkyGolayFilter(num_points, num_points_left, num_points_right, polynomial_order);
181 break;
182 }
185 break;
186 }
189 break;
190 }
191 case FilterType::STENCIL: {
192 filter_m = new StencilFilter();
193 break;
194 }
195 default: {
196 filter_m = 0;
197 INFOMSG("No filter attached" << endl);
198 break;
199 }
200 }
201 }
202}
203
204void OpalFilter::print(std::ostream& os) const {
205 os << "* ************* F I L T E R ********************************************************\n"
206 << "* FILTER " << getOpalName() << '\n'
207 << "* TYPE " << Attributes::getString(itsAttr[TYPE]) << '\n'
208 << "* NFREQ " << Attributes::getReal(itsAttr[NFREQ]) << '\n'
209 << "* THRESHOLD " << Attributes::getReal(itsAttr[THRESHOLD]) << '\n'
210 << "* NPOINTS " << Attributes::getReal(itsAttr[NPOINTS]) << '\n'
211 << "* NLEFT " << Attributes::getReal(itsAttr[NLEFT]) << '\n'
212 << "* NRIGHT " << Attributes::getReal(itsAttr[NRIGHT]) << '\n'
213 << "* POLYORDER " << Attributes::getReal(itsAttr[POLYORDER]) << '\n'
214 << "* ********************************************************************************** " << std::endl;
215}
@ SIZE
Definition: IndexMap.cpp:174
#define NPOINTS_DEFAULT
Definition: OpalFilter.cpp:34
#define NRIGHT_DEFAULT
Definition: OpalFilter.cpp:36
#define NLEFT_DEFAULT
Definition: OpalFilter.cpp:35
#define POLYORDER_DEFAULT
Definition: OpalFilter.cpp:37
Inform * gmsg
Definition: Main.cpp:61
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define INFOMSG(msg)
Definition: IpplInfo.h:348
const std::string name
double getReal(const Attribute &attr)
Return real value.
Definition: Attributes.cpp:252
Attribute makePredefinedString(const std::string &name, const std::string &help, const std::initializer_list< std::string > &predefinedStrings)
Make predefined string attribute.
Definition: Attributes.cpp:409
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Definition: Attributes.cpp:240
std::string getString(const Attribute &attr)
Get string value.
Definition: Attributes.cpp:343
boost::function< boost::tuple< double, bool >(arguments_t)> type
Definition: function.hpp:21
The base class for all OPAL definitions.
Definition: Definition.h:30
The base class for all OPAL objects.
Definition: Object.h:48
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
Definition: Object.cpp:191
const std::string & getOpalName() const
Return object name.
Definition: Object.cpp:310
void setOpalName(const std::string &name)
Set object name.
Definition: Object.cpp:331
std::vector< Attribute > itsAttr
The object attributes.
Definition: Object.h:216
bool builtin
Built-in flag.
Definition: Object.h:233
Object * find(const std::string &name)
Find entry.
Definition: OpalData.cpp:566
static OpalData * getInstance()
Definition: OpalData.cpp:196
void define(Object *newObject)
Define a new object.
Definition: OpalData.cpp:489
The base class for all OPAL exceptions.
Definition: OpalException.h:28
void initOpalFilter()
Definition: OpalFilter.cpp:141
virtual void execute()
Check the OpalFilter data.
Definition: OpalFilter.cpp:119
virtual ~OpalFilter()
Definition: OpalFilter.cpp:102
static OpalFilter * find(const std::string &name)
Find named FILTER.
Definition: OpalFilter.cpp:124
Filter * filter_m
Definition: OpalFilter.h:61
virtual bool canReplaceBy(Object *object)
Test if replacement is allowed.
Definition: OpalFilter.cpp:108
virtual OpalFilter * clone(const std::string &name)
Make clone.
Definition: OpalFilter.cpp:114
virtual void update()
Update the OpalFilter data.
Definition: OpalFilter.cpp:135
OpalFilter()
Exemplar constructor.
Definition: OpalFilter.cpp:55
void print(std::ostream &os) const
Print the object.
Definition: OpalFilter.cpp:204
Definition: Inform.h:42