OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
ProbeHistReader.cpp
Go to the documentation of this file.
1//
2// Class ProbeHistReader
3// Implements a parser and value extractor for hist files (*.hist).
4// It is for example used together with the septum objective.
5// A histogram file is generated by the OPAL probe element.
6//
7// Copyright (c) 2019, Matthias Frey, Paul Scherrer Institut, Villigen PSI, Switzerland
8// All rights reserved
9//
10// Implemented as part of the PhD thesis
11// "Precise Simulations of Multibunches in High Intensity Cyclotrons"
12//
13// This file is part of OPAL.
14//
15// OPAL is free software: you can redistribute it and/or modify
16// it under the terms of the GNU General Public License as published by
17// the Free Software Foundation, either version 3 of the License, or
18// (at your option) any later version.
19//
20// You should have received a copy of the GNU General Public License
21// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
22//
23#include <iterator>
24#include <regex>
25
26#include "ProbeHistReader.h"
28
30 : filename_m(filename)
31 , rmin_m(0.0)
32 , binwidth_m(0.0)
33 , bincount_m(0)
34{ }
35
36
38
39 std::ifstream histfile;
40
41 histfile.open(filename_m.c_str(), std::ios::in);
42
43 if (!histfile) {
44 throw OptPilotException("ProbeHistReader::parseFile()",
45 "Error opening file " + filename_m);
46 }
47
48 parseHeader(histfile);
49
50 std::istream_iterator<size_t> it(histfile);
51 while ( it != std::istream_iterator<size_t>() ) {
52 bincount_m.push_back(*it);
53 ++it;
54 }
55
56 histfile.close();
57
58 if (histfile.is_open()) {
59 throw OptPilotException("ProbeHistReader::parseFile()",
60 "Error closing file " + filename_m);
61 }
62}
63
64
65size_t ProbeHistReader::minimum(double lower, double upper) {
66 size_t lidx = (lower - rmin_m) / binwidth_m;
67 size_t uidx = (upper - rmin_m) / binwidth_m;
68
69 if (lidx >= uidx) {
70 throw OptPilotException("ProbeHistReader::minimum()",
71 "Lower index >= upper index: " + std::to_string(lidx) +
72 " >= " + std::to_string(uidx));
73 }
74
75 if (uidx >= bincount_m.size()) {
76 throw OptPilotException("ProbeHistReader::minimum()",
77 "Index >= number of bins: " + std::to_string(uidx) +
78 " >= " + std::to_string(bincount_m.size()));
79 }
80
82 std::advance(beg, lidx);
83
85 std::advance(end, uidx);
86
87 container_t::iterator result = std::min_element(beg, end);
88
89 if (result == bincount_m.end()) {
90 throw OptPilotException("ProbeHistReader::minimum()",
91 "No minimum between " + std::to_string(lower) +
92 " and " + std::to_string(upper) + " found.");
93 }
94
95 return double(*result);
96}
97
98
99void ProbeHistReader::parseHeader(std::ifstream& ifs) {
100 std::string header;
101 std::getline(ifs, header);
102
103 if (header.find("# Histogram bin counts") == std::string::npos) {
104 throw OptPilotException("ProbeHistReader::parseHeader()",
105 "Error reading file " + filename_m);
106 }
107
108 const std::regex re("\\.*\\) (.*) mm (.*) mm (.*) (.*) mm");
109 std::smatch match;
110 std::regex_search(header, match, re);
111
112 if ( match.size() != 5 ) {
113 throw OptPilotException("ProbeHistReader::parseHeader()",
114 "Error parsing header of file " + filename_m);
115 }
116
117 rmin_m = getValue<double>(match[1].str());
118 double rmax = getValue<double>(match[2].str());
119 size_t nbins = getValue<size_t>(match[3].str());
120 binwidth_m = getValue<double>(match[4].str());
121
122 if ( rmin_m >= rmax ) {
123 throw OptPilotException("ProbeHistReader::parseHeader()",
124 "Not a valid histogram file " + filename_m);
125 }
126
127 bincount_m.reserve(nbins);
128}
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
MMatrix< double > re(MMatrix< m_complex > mc)
Definition: MMatrix.cpp:378
std::string::iterator iterator
Definition: MSLang.h:16
size_t minimum(double lower, double upper)
std::string filename_m
Histogram file.
ProbeHistReader(std::string filename)
void parseHeader(std::ifstream &ifs)
container_t bincount_m