OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
PeakFinder.cpp
Go to the documentation of this file.
1//
2// Class PeakFinder
3// Find peaks of radial profile.
4// It computes a histogram based on the radial distribution of the particle
5// bunch. After that all peaks of the histogram are searched.
6// The radii are written in ASCII format to a file.
7// This class is used for the cyclotron probe element.
8//
9// Copyright (c) 2017 - 2021, Matthias Frey, Jochem Snuverink, Paul Scherrer Institut, Villigen PSI,
10// Switzerland All rights reserved
11//
12// This file is part of OPAL.
13//
14// OPAL is free software: you can redistribute it and/or modify
15// it under the terms of the GNU General Public License as published by
16// the Free Software Foundation, either version 3 of the License, or
17// (at your option) any later version.
18//
19// You should have received a copy of the GNU General Public License
20// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
21//
23
25
26#include "Utility/IpplInfo.h"
27
28#include <algorithm>
29#include <cmath>
30#include <iterator>
31
32extern Inform* gmsg;
33
34PeakFinder::PeakFinder(std::string outfn, double min, double max, double binWidth, bool singlemode)
35 : outputName_m(outfn),
36 binWidth_m(binWidth),
37 min_m(min),
38 max_m(max),
39 turn_m(0),
40 peakRadius_m(0.0),
41 registered_m(0),
42 singlemode_m(singlemode),
43 first_m(true),
44 finished_m(false) {
45 if (min_m > max_m) {
46 std::swap(min_m, max_m);
47 }
48 // calculate bins, round up so that histogram is large enough (add one for safety)
49 nBins_m = static_cast<unsigned int>(std::ceil((max_m - min_m) / binWidth_m)) + 1;
50}
51
53 double radius = std::hypot(R(0), R(1));
54 radius_m.push_back(radius);
55
56 peakRadius_m += radius;
58}
59
60void PeakFinder::evaluate(const int& turn) {
61 if (first_m) {
62 turn_m = turn;
63 first_m = false;
64 }
65
66 if (turn_m != turn) {
67 finished_m = true;
68 }
69
70 bool globFinished = false;
71
72 if (!singlemode_m)
73 ippl::Comm->allreduce(finished_m, globFinished, 1, std::logical_and<bool>());
74 else
75 globFinished = finished_m;
76
77 if (globFinished) {
78 this->computeCentroid_m();
79
80 turn_m = turn;
81
82 // reset
83 peakRadius_m = 0.0;
84 registered_m = 0;
85 finished_m = false;
86 }
87}
88
91
92 // last turn is not yet computed
93 this->computeCentroid_m();
94
95 if (!peaks_m.empty()) {
96 // only rank 0 will go in here
97
98 fileName_m = outputName_m + std::string(".peaks");
100
101 hist_m = outputName_m + std::string(".hist");
103
104 *gmsg << level2 << "Save '" << fileName_m << "' and '" << hist_m << "'" << endl;
105
106 if (OpalData::getInstance()->inRestartRun())
107 this->append_m();
108 else
109 this->open_m();
110
111 this->saveASCII_m();
112 this->close_m();
113 }
114
115 radius_m.clear();
116 globHist_m.clear();
117}
118
120 double globPeakRadius = 0.0;
121 int globRegister = 0;
122
123 if (!singlemode_m) {
124 ippl::Comm->reduce(peakRadius_m, globPeakRadius, 1, std::plus<double>());
125 ippl::Comm->reduce(registered_m, globRegister, 1, std::plus<int>());
126 } else {
127 globPeakRadius = peakRadius_m;
128 globRegister = registered_m;
129 }
130
131 if (ippl::Comm->rank() == 0) {
132 if (globRegister > 0)
133 peaks_m.push_back(globPeakRadius / double(globRegister));
134 }
135}
136
138 /*
139 * create local histograms
140 */
141
142 globHist_m.resize(nBins_m);
143 container_t locHist(nBins_m, 0.0);
144
145 double invBinWidth = 1.0 / binWidth_m;
146 for (container_t::iterator it = radius_m.begin(); it != radius_m.end(); ++it) {
147 int bin = static_cast<int>(std::abs(*it - min_m) * invBinWidth);
148 if (bin < 0 || (unsigned int)bin >= nBins_m)
149 continue; // Probe might save particles outside its boundary
150 ++locHist[bin];
151 }
152
153 /*
154 * create global histograms
155 */
156 if (!singlemode_m) {
157 reduce(locHist.data(), globHist_m.data(), locHist.size(), std::plus<double>());
158 } else {
159 globHist_m.swap(locHist);
160 }
161}
162
164 os_m.open(fileName_m.c_str(), std::ios::out);
165 hos_m.open(hist_m.c_str(), std::ios::out);
166}
167
169 os_m.open(fileName_m.c_str(), std::ios::app);
170 hos_m.open(hist_m.c_str(), std::ios::app);
171}
172
174 os_m.close();
175 hos_m.close();
176}
177
179 os_m << "# Peak Radii (mm)" << std::endl;
180 for (auto& radius : peaks_m)
181 os_m << radius << std::endl;
182
183 hos_m << "# Histogram bin counts (min, max, nbins, binsize) " << min_m << " mm " << max_m
184 << " mm " << nBins_m << " " << binWidth_m << " mm" << std::endl;
185 for (auto binCount : globHist_m)
186 hos_m << binCount << std::endl;
187}
Inform * gmsg
Definition changes.cpp:7
ippl::Vector< T, Dim > Vector_t
void checkAndAddOutputFileName(const std::string &outfn)
checks the output file names of all items to avoid duplicates
Definition OpalData.cpp:691
static OpalData * getInstance()
Definition OpalData.cpp:195
void addParticle(const Vector_t< double, 3 > &R)
std::vector< double > container_t
Definition PeakFinder.h:34
void open_m()
Open output file.
std::list< double > peaks_m
Definition PeakFinder.h:103
std::ofstream hos_m
used to write out the histrogram
Definition PeakFinder.h:87
PeakFinder()=delete
std::ofstream os_m
used to write out the data
Definition PeakFinder.h:84
double binWidth_m
Bin width in mm.
Definition PeakFinder.h:96
double peakRadius_m
Definition PeakFinder.h:101
container_t globHist_m
global histogram values
Definition PeakFinder.h:75
bool singlemode_m
Definition PeakFinder.h:104
void save()
container_t radius_m
Definition PeakFinder.h:73
bool finished_m
Definition PeakFinder.h:106
void createHistogram_m()
void computeCentroid_m()
double min_m
histogram size
Definition PeakFinder.h:98
unsigned int nBins_m
Number of bins.
Definition PeakFinder.h:94
std::string outputName_m
Element/probe name, for name output file.
Definition PeakFinder.h:90
void append_m()
Open output file in append mode.
std::string hist_m
histogram filename with extension (.hist)
Definition PeakFinder.h:81
std::string fileName_m
filename with extension (.peaks)
Definition PeakFinder.h:78
int registered_m
Definition PeakFinder.h:102
void evaluate(const int &turn)
void saveASCII_m()
Write to output file.
double max_m
Definition PeakFinder.h:98
void close_m()
Close output file.