Jpp 20.0.0-rc.2
the software that should make you happy
Loading...
Searching...
No Matches
JKM3Sim.cc
Go to the documentation of this file.
1#include <string>
2#include <iostream>
3#include <iomanip>
4#include <sstream>
5#include <fstream>
6#include <vector>
7#include <map>
8
9#include "JLang/JException.hh"
10#include "JMath/JConstants.hh"
12#include "JPhysics/KM3NeT.hh"
14
16#include "Jeep/JParser.hh"
17
18namespace {
19
21
22 struct JKM3Sim {
23
24 static constexpr const char* const detectorDepth_t = "detectorDepth";
25 static constexpr const char* const PPCKOV_t = "PPCKOV";
26 static constexpr const char* const RINDEX_WATER_t = "RINDEX_WATER";
27 static constexpr const char* const ABSORPTION_WATER_t = "ABSORPTION_WATER";
28 static constexpr const char* const RINDEX_GLASS_t = "RINDEX_GLASS";
29 static constexpr const char* const ABSORPTION_GLASS_t = "ABSORPTION_GLASS";
30 static constexpr const char* const RINDEX_GELL_t = "RINDEX_GELL";
31 static constexpr const char* const RINDEX_AIR_t = "RINDEX_AIR";
32 static constexpr const char* const ABSORPTION_AIR_t = "ABSORPTION_AIR";
33 static constexpr const char* const RINDEX_CATH_t = "RINDEX_CATH";
34 static constexpr const char* const ABSORPTION_CATH_t = "ABSORPTION_CATH";
35 static constexpr const char* const Q_EFF_t = "Q_EFF";
36 static constexpr const char* const MIE_WATER_t = "MIE_WATER";
37 static constexpr const char* const MIE_PARAM_t = "MIE_PARAM";
38 static constexpr const char* const COS_ANGLES_t = "COS_ANGLES";
39 static constexpr const char* const ANG_ACCEPT_t = "ANG_ACCEPT";
40
41 static constexpr const char* const END_t = "END";
42 static constexpr char SEPARATOR = '*';
43
44
45 /**
46 * Default constructor.
47 */
48 JKM3Sim()
49 {
50 using namespace JPP;
51
52 detectorDepth = 0.0;
53 mie_param = 0.0;
54 R = 4.7462; // PMT radius [cm]
55 A = PI*R*R; // PMT area [cm^2]
56 }
57
58
59 /**
60 * Type definition of value and unit.
61 */
63
64
65 /**
66 * Get value and unit.
67 *
68 * \param buffer input
69 * \return value and input
70 */
71 static inline pair_type parse(const std::string& buffer)
72 {
73 using namespace std;
74
75 const string::size_type pos = buffer.find(SEPARATOR);
76
77 if (pos != string::npos) {
78
79 double value;
80
81 istringstream(buffer.substr(0,pos)) >> value;
82
83 return make_pair(value, buffer.substr(pos+1));
84
85 } else {
86
87 THROW(JParseError, "Error parsing <" << buffer << ">.");
88 }
89 }
90
91
92 /**
93 * Read KM3Sim inputs from input strea.
94 *
95 * \param in input stream
96 * \param object KM3Sim inputs
97 * \return input stream
98 */
99 friend inline std::istream& operator>>(std::istream& in, JKM3Sim& object)
100 {
101 using namespace std;
102
103 for (string key; in >> key; ) {
104
105 string buffer[2];
106 size_t N;
107 double value;
108
109 if (key == detectorDepth_t) {
110
111 if (in >> buffer[0]) {
112 object.detectorDepth = parse(buffer[0]).first;
113 }
114
115 } else if (key == PPCKOV_t) {
116
117 if (in >> N) {
118 for (size_t i = 0; i != N; ++i) {
119 if (in >> buffer[0]) {
120 object.ppckov.push_back(parse(buffer[0]).first);
121 }
122 }
123 }
124
125 } else if (key == RINDEX_WATER_t) {
126
127 for (size_t i = 0; i != object.ppckov.size(); ++i) {
128 if (in >> value) {
129 object.rindex_water.push_back(value);
130 }
131 }
132
133 } else if (key == ABSORPTION_WATER_t) {
134
135 for (in >> buffer[0]; in >> buffer[0] >> buffer[1] && buffer[0] != END_t; ) {
136 object.absorption_water[parse(buffer[0]).first] = parse(buffer[1]).first;
137 }
138
139 } else if (key == MIE_WATER_t) {
140
141 for (size_t i = 0; i != object.ppckov.size(); ++i) {
142 if (in >> buffer[0]) {
143 object.mie_water.push_back(parse(buffer[0]).first);
144 }
145 }
146
147 } else if (key == Q_EFF_t) {
148
149 double QE;
150
151 in >> QE;
152
153 for (size_t i = 0; i != object.ppckov.size(); ++i) {
154 if (in >> value) {
155 object.q_eff.push_back(value*QE);
156 }
157 }
158
159 } else if (key == MIE_PARAM_t) {
160
161 in >> object.mie_param;
162
163 } else if (key == COS_ANGLES_t) {
164
165 if (in >> N) {
166 for (size_t i = 0; i != N; ++i) {
167 if (in >> value) {
168 object.cos_angles.push_back(value);
169 }
170 }
171 }
172
173 } else if (key == ANG_ACCEPT_t) {
174
175 for (size_t i = 0; i != object.cos_angles.size(); ++i) {
176 if (in >> value) {
177 object.ang_accept.push_back(value);
178 }
179 }
180 }
181 }
182
183 return in;
184 }
185
186
187 /**
188 * Write KM3Sim inputs to output strea.
189 *
190 * \param out output stream
191 * \param object KM3Sim inputs
192 * \return output stream
193 */
194 friend inline std::ostream& operator<<(std::ostream& out, const JKM3Sim& object)
195 {
196 using namespace std;
197 using namespace JPP;
198
199 out << detectorDepth_t << ' ' << object.detectorDepth << endl;
200 out << PPCKOV_t << ' ' << JEEPZ() << object.ppckov << endl;
201 out << RINDEX_WATER_t << ' ' << JEEPZ() << object.rindex_water << endl;
202 out << ABSORPTION_WATER_t << ' ' << JEEPZ() << object.absorption_water << endl;
203 out << MIE_WATER_t << ' ' << JEEPZ() << object.mie_water << endl;
204 out << Q_EFF_t << ' ' << JEEPZ() << object.q_eff << endl;
205 out << MIE_PARAM_t << ' ' << object.mie_param << endl;
206 out << COS_ANGLES_t << ' ' << JEEPZ() << object.cos_angles << endl;
207 out << ANG_ACCEPT_t << ' ' << JEEPZ() << object.ang_accept << endl;
208
209 return out;
210 }
211
212
213 double R; // PMT radius [cm]
214 double A; // PMT area [cm^2]
215
216 double detectorDepth;
217 std::vector<double> ppckov;
218 std::vector<double> rindex_water;
219 std::map<double, double> absorption_water;
221 std::vector<double> mie_water;
222 double mie_param;
223 std::vector<double> cos_angles;
224 std::vector<double> ang_accept;
225 };
226
227
228 /**
229 * Auxiliary data structure for map with default value.
230 */
231 struct map_type :
232 public std::map<std::string, double>
233 {
234 /**
235 * Constructor.
236 *
237 * \param value default value
238 */
239 map_type(const double value) :
240 value(value)
241 {}
242
243
244 /**
245 * Get value for given key.
246 *
247 * \param key key
248 * \return corresponding value if key is present; else default value
249 */
250 double get(const std::string key) const
251 {
252 const_iterator p = this->find(key);
253
254 if (p != this->end())
255 return p->second;
256 else
257 return value;
258 }
259
260 friend inline std::istream& operator>>(std::istream& in, map_type& object) { return JPP::readObject(in, static_cast<std::map<std::string, double>&>(object)); }
261 friend inline std::ostream& operator<<(std::ostream& out, const map_type& object) { return JPP::writeObject(out, static_cast<const std::map<std::string, double>&>(object)); }
262
263 const double value;
264 };
265}
266
267
268/**
269 */
270int main(int argc, char **argv)
271{
272 using namespace std;
273 using namespace JPP;
274
275 string inputFile;
276 map_type precision (0.0);
277 map_type correction(1.0);
278 int debug;
279
280 precision[JKM3Sim::RINDEX_WATER_t] = 1.0e-4;
281 precision[JKM3Sim::ABSORPTION_WATER_t] = 1.0e-4;
282 precision[JKM3Sim::MIE_WATER_t] = 0.2;
283 precision[JKM3Sim::ANG_ACCEPT_t] = 0.5;
284 precision[JKM3Sim::Q_EFF_t] = 0.01;
285
286 try {
287
288 JParser<> zap;
289
290 zap['f'] = make_field(inputFile);
291 zap['p'] = make_field(precision) = JPARSER::initialised();
292 zap['c'] = make_field(correction) = JPARSER::initialised();
293 zap['d'] = make_field(debug) = 1;
294
295 zap(argc, argv);
296 }
297 catch(const exception &error) {
298 FATAL(error.what() << endl);
299 }
300
301
302 JKM3Sim km3sim;
303
304 ifstream in(inputFile.c_str());
305
306 in >> km3sim;
307
308 in.close();
309
310 DEBUG(km3sim);
311
312 using namespace KM3NET;
313
314
315 {
316 /*
317 const double g = 9.80665; // [m/s^2]
318 const double P = detectorDepth * DENSITY_SEA_WATER * 1.0e-3 * g * 1.0e1; // [Atm]
319 */
320 const double P = 315.0; // [Atm]
321
322 DEBUG("Pressure " << P << " [Atm]" << endl);
323
324 const JDispersion dispersion(P);
325
326 for (size_t i = 0; i != km3sim.ppckov.size(); ++i) {
327
328 const double x = km3sim.ppckov[i];
329
330 ASSERT(fabs(km3sim.rindex_water[i] - dispersion.getIndexOfRefractionPhase(x) * correction.get(JKM3Sim::RINDEX_WATER_t)) <= precision.get(JKM3Sim::RINDEX_WATER_t),
331 "Test of index of refraction at " << FIXED(6,1) << x << ' ' << FIXED(7,4) << km3sim.rindex_water[i] << ' ' << FIXED(7,4) << dispersion.getIndexOfRefractionPhase(x) * correction.get(JKM3Sim::RINDEX_WATER_t));
332 }
333 }
334 {
335 for (const auto& i : km3sim.absorption_water) {
336 ASSERT(fabs(i.second - getAbsorptionLength(i.first) * correction.get(JKM3Sim::ABSORPTION_WATER_t)) <= precision.get(JKM3Sim::ABSORPTION_WATER_t),
337 "Test of absorption length at " << FIXED(6,1) << i.first << ' ' << FIXED(7,3) << i.second << ' ' << FIXED(7,3) << getAbsorptionLength(i.first) * correction.get(JKM3Sim::ABSORPTION_WATER_t));
338 }
339 }
340 {
341 for (size_t i = 0; i != km3sim.ppckov.size(); ++i) {
342
343 const double x = km3sim.ppckov[i];
344
345 ASSERT(fabs(km3sim.mie_water[i] - getScatteringLength(x) * correction.get(JKM3Sim::MIE_WATER_t)) <= precision.get(JKM3Sim::MIE_WATER_t),
346 "Test of scattering length at " << FIXED(6,1) << x << ' ' << FIXED(7,3) << km3sim.mie_water[i] << ' ' << FIXED(7,3) << getScatteringLength(x) * correction.get(JKM3Sim::MIE_WATER_t));
347 }
348 }
349 {
350 for (size_t i = 0; i != km3sim.ppckov.size(); ++i) {
351
352 const double x = km3sim.ppckov[i];
353
354 ASSERT(fabs(km3sim.q_eff[i] - getQE(x) * correction.get(JKM3Sim::Q_EFF_t)) <= precision.get(JKM3Sim::Q_EFF_t),
355 "Test of QE at " << FIXED(6,1) << x << ' ' << FIXED(7,4) << km3sim.q_eff[i] << ' ' << FIXED(7,4) << getQE(x) * correction.get(JKM3Sim::Q_EFF_t));
356 }
357 }
358 {
359 const double U = 1.0e4; // m^2 -> cm^2
360
361 for (size_t i = 0; i != km3sim.cos_angles.size(); ++i) {
362
363 const double x = km3sim.cos_angles[i];
364
365 ASSERT(fabs(km3sim.ang_accept[i]*km3sim.A - getPhotocathodeArea() * getAngularAcceptance(x) * U * correction.get(km3sim.ANG_ACCEPT_t)) <= precision.get(km3sim.ANG_ACCEPT_t),
366 "Test of PMT acceptance at " << FIXED(6,2) << x << ' ' << FIXED(9,5) << km3sim.ang_accept[i]*km3sim.A << ' ' << FIXED(9,5) << getPhotocathodeArea() * getAngularAcceptance(x) * U * correction.get(km3sim.ANG_ACCEPT_t));
367 }
368 }
369}
double getAngularAcceptance(const double x)
Angular acceptence of PMT.
Definition JDrawLED.cc:68
double getAbsorptionLength(const double lambda)
Definition JDrawPD0.cc:27
double getScatteringLength(const double lambda)
Definition JDrawPD0.cc:33
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
std::istream & operator>>(std::istream &in, JAANET::JHead &header)
Read header from input.
Definition JHead.hh:1850
int main(int argc, char **argv)
Definition JKM3Sim.cc:270
Mathematical constants.
#define DEBUG(A)
Message macros.
Definition JMessage.hh:62
#define ASSERT(A,...)
Assert macro.
Definition JMessage.hh:90
#define FATAL(A)
Definition JMessage.hh:67
int debug
debug level
Definition JSirene.cc:72
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
Physics constants.
Properties of KM3NeT PMT and deep-sea water.
Exception for parsing value.
Utility class to parse command line options.
Definition JParser.hh:1698
Implementation of dispersion for water in deep sea.
virtual double getIndexOfRefractionPhase(const double lambda) const
Index of refraction (phase velocity).
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)
std::ostream & writeObject(std::ostream &out, const T &object)
Stream output of object.
std::istream & readObject(std::istream &in, T &object)
Stream input of object.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
JWriter & operator<<(JWriter &out, const JDAQChronometer &chronometer)
Write DAQ chronometer to output.
std::map< int, range_type > map_type
JReader & operator>>(JReader &in, JDAQChronometer &chronometer)
Read DAQ chronometer from input.
Name space for KM3NeT.
Definition Jpp.hh:16
boost::property_tree::ptree parse(std::string str)
Definition configure.hh:24
Auxiliary data structure for floating point format specification.
Definition JManip.hh:448
Auxiliary data structure for streaming of STL containers.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition JParser.hh:68
Data structure for a pair of indices.