OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
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, Switzerland
10// 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 "Message/GlobalComm.h"
27#include "Utility/IpplInfo.h"
28
29#include <algorithm>
30#include <cmath>
31#include <iterator>
32
33extern Inform* gmsg;
34
35PeakFinder::PeakFinder(std::string outfn, double min,
36 double max, double binWidth, bool singlemode)
37 : outputName_m(outfn)
38 , binWidth_m(binWidth)
39 , min_m(min)
40 , max_m(max)
41 , turn_m(0)
42 , peakRadius_m(0.0)
43 , registered_m(0)
44 , singlemode_m(singlemode)
45 , first_m(true)
46 , finished_m(false)
47{
48 if (min_m > max_m) {
49 std::swap(min_m, max_m);
50 }
51 // calculate bins, round up so that histogram is large enough (add one for safety)
52 nBins_m = static_cast<unsigned int>(std::ceil(( max_m - min_m ) / binWidth_m)) + 1;
53}
54
55
57
58 double radius = std::hypot(R(0),R(1));
59 radius_m.push_back(radius);
60
61 peakRadius_m += radius;
63}
64
65
66void PeakFinder::evaluate(const int& turn) {
67
68 if ( first_m ) {
69 turn_m = turn;
70 first_m = false;
71 }
72
73 if ( turn_m != turn ) {
74 finished_m = true;
75 }
76
77 bool globFinished = false;
78
79 if ( !singlemode_m )
80 allreduce(finished_m, globFinished, 1, std::logical_and<bool>());
81 else
82 globFinished = finished_m;
83
84 if ( globFinished ) {
85
86 this->computeCentroid_m();
87
88 turn_m = turn;
89
90 // reset
91 peakRadius_m = 0.0;
92 registered_m = 0;
93 finished_m = false;
94 }
95}
96
97
99
101
102 // last turn is not yet computed
103 this->computeCentroid_m();
104
105 if ( !peaks_m.empty() ) {
106 // only rank 0 will go in here
107
108 fileName_m = outputName_m + std::string(".peaks");
110
111 hist_m = outputName_m + std::string(".hist");
113
114 *gmsg << level2 << "Save '" << fileName_m << "' and '" << hist_m << "'" << endl;
115
116 if (OpalData::getInstance()->inRestartRun())
117 this->append_m();
118 else
119 this->open_m();
120
121 this->saveASCII_m();
122 this->close_m();
123 }
124
125 radius_m.clear();
126 globHist_m.clear();
127}
128
129
131 double globPeakRadius = 0.0;
132 int globRegister = 0;
133
134 //FIXME inefficient
135 if ( !singlemode_m ) {
136 reduce(peakRadius_m, globPeakRadius, 1, std::plus<double>());
137 reduce(registered_m, globRegister, 1, std::plus<int>());
138 } else {
139 globPeakRadius = peakRadius_m;
140 globRegister = registered_m;
141 }
142
143 if ( Ippl::myNode() == 0 ) {
144 if ( globRegister > 0 )
145 peaks_m.push_back(globPeakRadius / double(globRegister));
146 }
147}
148
150 /*
151 * create local histograms
152 */
153
154 globHist_m.resize(nBins_m);
155 container_t locHist(nBins_m,0.0);
156
157 double invBinWidth = 1.0 / binWidth_m;
158 for(container_t::iterator it = radius_m.begin(); it != radius_m.end(); ++it) {
159 int bin = static_cast<int>(std::abs(*it - min_m ) * invBinWidth);
160 if (bin < 0 || (unsigned int)bin >= nBins_m) continue; // Probe might save particles outside its boundary
161 ++locHist[bin];
162 }
163
164 /*
165 * create global histograms
166 */
167 if ( !singlemode_m ) {
168 reduce(&(locHist[0]), &(locHist[0]) + locHist.size(),
169 &(globHist_m[0]), OpAddAssign());
170 } else {
171 globHist_m.swap(locHist);
172 }
173
174// reduce(locHist.data(), globHist_m.data(), locHist.size(), std::plus<double>());
175}
176
177
179 os_m.open(fileName_m.c_str(), std::ios::out);
180 hos_m.open(hist_m.c_str(), std::ios::out);
181}
182
183
185 os_m.open(fileName_m.c_str(), std::ios::app);
186 hos_m.open(hist_m.c_str(), std::ios::app);
187}
188
189
191 os_m.close();
192 hos_m.close();
193}
194
195
197 os_m << "# Peak Radii (mm)" << std::endl;
198 for (auto &radius : peaks_m)
199 os_m << radius << std::endl;
200
201 hos_m << "# Histogram bin counts (min, max, nbins, binsize) "
202 << min_m << " mm "
203 << max_m << " mm "
204 << nBins_m << " "
205 << binWidth_m << " mm" << std::endl;
206 for (auto binCount : globHist_m)
207 hos_m << binCount << std::endl;
208}
Inform * gmsg
Definition: Main.cpp:61
void allreduce(const T *input, T *output, int count, Op op)
Definition: GlobalComm.hpp:510
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
Definition: GlobalComm.hpp:55
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
PETE_TUTree< FnCeil, typename T::PETE_Expr_t > ceil(const PETE_Expr< T > &l)
Definition: PETE.h:728
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
Inform & level2(Inform &inf)
Definition: Inform.cpp:46
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
std::string::iterator iterator
Definition: MSLang.h:16
void checkAndAddOutputFileName(const std::string &outfn)
checks the output file names of all items to avoid duplicates
Definition: OpalData.cpp:675
static OpalData * getInstance()
Definition: OpalData.cpp:196
std::vector< double > container_t
Definition: PeakFinder.h:35
void open_m()
Open output file.
Definition: PeakFinder.cpp:178
std::list< double > peaks_m
Definition: PeakFinder.h:106
std::ofstream hos_m
used to write out the histrogram
Definition: PeakFinder.h:90
PeakFinder()=delete
std::ofstream os_m
used to write out the data
Definition: PeakFinder.h:87
double binWidth_m
Bin width in mm.
Definition: PeakFinder.h:99
double peakRadius_m
Definition: PeakFinder.h:104
container_t globHist_m
global histogram values
Definition: PeakFinder.h:78
bool singlemode_m
Definition: PeakFinder.h:107
void save()
Definition: PeakFinder.cpp:98
container_t radius_m
Definition: PeakFinder.h:76
bool finished_m
Definition: PeakFinder.h:109
void createHistogram_m()
Definition: PeakFinder.cpp:149
void computeCentroid_m()
Definition: PeakFinder.cpp:130
double min_m
histogram size
Definition: PeakFinder.h:101
unsigned int nBins_m
Number of bins.
Definition: PeakFinder.h:97
std::string outputName_m
Element/probe name, for name output file.
Definition: PeakFinder.h:93
void append_m()
Open output file in append mode.
Definition: PeakFinder.cpp:184
std::string hist_m
histogram filename with extension (.hist)
Definition: PeakFinder.h:84
std::string fileName_m
filename with extension (.peaks)
Definition: PeakFinder.h:81
bool first_m
Definition: PeakFinder.h:108
int registered_m
Definition: PeakFinder.h:105
void evaluate(const int &turn)
Definition: PeakFinder.cpp:66
void saveASCII_m()
Write to output file.
Definition: PeakFinder.cpp:196
void addParticle(const Vector_t &R)
Definition: PeakFinder.cpp:56
double max_m
Definition: PeakFinder.h:101
void close_m()
Close output file.
Definition: PeakFinder.cpp:190
Definition: Inform.h:42
static int myNode()
Definition: IpplInfo.cpp:691