Skip to content

Commit a11ff84

Browse files
committed
Added very basic peak finder - not very good, just an example for now
1 parent 0214d7b commit a11ff84

File tree

4 files changed

+82
-15
lines changed

4 files changed

+82
-15
lines changed

examples/realspectrum.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,27 @@
1111
pkd.io.from_csv(hist_raw, filename)
1212
energies, counts = hist_raw.X, hist_raw.Y
1313

14-
# smooth it
15-
smoother = pkd.core.MovingAverageSmoother(3)
16-
smoother2 = pkd.core.SavitzkyGolaySmoother(3)
17-
counts1 = smoother.go(counts)
18-
hist_smoothed1 = pkd.core.SpectrumEnergyBased(energies, counts1)
19-
counts2 = smoother2.go(counts)
20-
hist_smoothed2 = pkd.core.SpectrumEnergyBased(energies, counts2)
21-
2214
# estimate and then remove background
2315
ITERS = range(1, 21)
2416
# forward windowing
25-
background_forw = hist_smoothed1.estimateBackground(ITERS)
17+
background_forw = hist_raw.estimateBackground(ITERS)
2618
# backward windowing
27-
background_back = hist_smoothed1.estimateBackground(list(reversed(ITERS)))
28-
hist_smoothed1.removeBackground(ITERS)
29-
snippedCounts = hist_smoothed1.Y
19+
background_back = hist_raw.estimateBackground(list(reversed(ITERS)))
20+
hist_raw.removeBackground(ITERS)
21+
snippedCounts = hist_raw.Y
22+
23+
# process manager
24+
pm = pkd.core.SimpleProcessManager()
25+
26+
# smooth
27+
sg = pkd.core.SavitzkyGolaySmoother(31)
28+
pm.append(sg)
29+
30+
# peak finding
31+
pm.append(pkd.core.MovingAveragePeakFinder(400))
32+
33+
# process
34+
processed_counts = pm.run(snippedCounts)
3035

3136
# function to plot histogram
3237
def getplotvalues(x,y):
@@ -47,11 +52,11 @@ def getplotvalues(x,y):
4752
import matplotlib.pyplot as plt
4853

4954
f = plt.figure(figsize=(10,7))
50-
plt.semilogy(*getplotvalues(energies, counts1), 'k', linewidth=0.8, alpha=0.5, label="smoothed1")
51-
plt.semilogy(*getplotvalues(energies, counts2), 'k--', linewidth=0.8, alpha=1.0, label="smoothed2")
55+
plt.semilogy(*getplotvalues(energies, counts), 'k', linewidth=0.8, alpha=0.5, label="raw")
56+
plt.semilogy(*getplotvalues(energies, processed_counts), 'r', linewidth=2.0, alpha=0.8, label="processed")
5257
# plt.semilogy(*getplotvalues(energies, snippedCounts), 'r', linewidth=0.4, alpha=0.5, label="no background")
5358
plt.semilogy(*getplotvalues(energies, background_forw), 'g', linewidth=1.0, alpha=0.8, label="background - forwards")
54-
plt.semilogy(*getplotvalues(energies, background_back), 'r', linewidth=1.0, alpha=0.8, label="background - backwards")
59+
plt.semilogy(*getplotvalues(energies, background_back), 'c', linewidth=1.0, alpha=0.8, label="background - backwards")
5560
plt.ylim(bottom=0.5, top=1e4)
5661
plt.xlabel("Energy (eV)", fontsize=24)
5762
plt.ylabel("Counts", fontsize=24)

include/core.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@
1818
#include "core/process.hpp"
1919
#include "core/smoothing.hpp"
2020
#include "core/spectral.hpp"
21+
#include "core/peaking.hpp"
2122

2223
#endif //CORE_HPP

include/core/peaking.hpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
////////////////////////////////////////////////////////////////////
2+
// //
3+
// Copyright (c) 2019-20, UK Atomic Energy Authority (UKAEA) //
4+
// //
5+
////////////////////////////////////////////////////////////////////
6+
7+
/*!
8+
@file
9+
Defines peak finding functions to be applied to numerical array
10+
11+
@copyright UK Atomic Energy Authority (UKAEA) - 2019-20
12+
*/
13+
#ifndef CORE_PEAKING_HPP
14+
#define CORE_PEAKING_HPP
15+
16+
#include <cmath>
17+
#include <memory>
18+
19+
#include "common.hpp"
20+
#include "core/numerical.hpp"
21+
#include "core/process.hpp"
22+
#include "core/smoothing.hpp"
23+
24+
PEAKINGDUCK_NAMESPACE_START(peakingduck)
25+
PEAKINGDUCK_NAMESPACE_START(core)
26+
27+
/*!
28+
@brief Simple moving average peak finding
29+
*/
30+
template<typename T=DefaultType, int Size=ArrayTypeDynamic>
31+
struct MovingAveragePeakFinder : public IProcess<T, Size>
32+
{
33+
34+
explicit MovingAveragePeakFinder(int windowsize)
35+
{
36+
_movingAverageSmoother = std::make_shared<MovingAverageSmoother<T,Size>>(windowsize);
37+
}
38+
39+
NumericalData<T, Size>
40+
go(const NumericalData<T, Size>& data) const override final
41+
{
42+
NumericalData<T, Size> smoothed = data - _movingAverageSmoother->go(data);
43+
for(int i=0;i<data.size();++i)
44+
smoothed[i] = smoothed[i] > 0 ? smoothed[i] : 0.0;
45+
return smoothed;
46+
};
47+
48+
private:
49+
std::shared_ptr<IProcess<T,Size>> _movingAverageSmoother;
50+
};
51+
52+
53+
PEAKINGDUCK_NAMESPACE_END
54+
PEAKINGDUCK_NAMESPACE_END
55+
56+
#endif // CORE_PEAKING_HPP

py/peakingduck.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,11 @@ PYBIND11_MODULE(PEAKINGDUCK, m) {
263263
py::class_<WeightedMovingAverageSmootherPyType, IProcessPyType, std::shared_ptr<WeightedMovingAverageSmootherPyType>>(m_core, "WeightedMovingAverageSmoother")
264264
.def(py::init<int>());
265265

266+
// peak finding objects
267+
using MovingAveragePeakFinderPyType = core::MovingAveragePeakFinder<NumericalDataCoreType,core::ArrayTypeDynamic>;
268+
py::class_<MovingAveragePeakFinderPyType, IProcessPyType, std::shared_ptr<MovingAveragePeakFinderPyType>>(m_core, "MovingAveragePeakFinder")
269+
.def(py::init<int>());
270+
266271
// histogram objects
267272
using HistPyType = core::Histogram<double,double>;
268273
using HistChannelPyType = core::Histogram<int,double>;

0 commit comments

Comments
 (0)