Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
PoPI_misc.cc
Go to the documentation of this file.
1/*
2# <<BEGIN-copyright>>
3# Copyright 2019, Lawrence Livermore National Security, LLC.
4# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
5# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
6# SPDX-License-Identifier: MIT
7# <<END-copyright>>
8*/
9
10#include <limits.h>
11#include <sstream>
12#include <stdexcept>
13
14#include "PoPI.hpp"
15
16namespace PoPI {
17
18std::string const IDs::photon = "photon";
19std::string const IDs::electron = "e-";
20std::string const IDs::neutron = "n";
21std::string const IDs::proton = "p";
22std::string const IDs::familiarPhoton = "g";
23std::string const IDs::familiarDeuteron = "d";
24std::string const IDs::familiarTriton = "t";
25std::string const IDs::familiarHelion = "h";
26std::string const IDs::familiarAlpha = "a";
27std::string const IDs::FissionProductENDL99120 = "FissionProductENDL99120";
28std::string const IDs::FissionProductENDL99125 = "FissionProductENDL99125";
29std::string const IDs::anti = "_anti";
30
31/* *********************************************************************************************************//**
32 * Returns true if a_formatVersion is a format supported by **PoPI** and false otherwise;
33 *
34 * @param a_formatVersion [in] The format version to check if it is supported.
35 *
36 * @return **true** if format is supported by **PoPI** and **false** otherwise.
37 ***********************************************************************************************************/
38
39bool supportedFormat( LUPI::FormatVersion const &a_formatVersion ) {
40
41 if( a_formatVersion.format( ) == PoPI_formatVersion_0_1_Chars ) return( true );
42
43 return( a_formatVersion.supported( ) );
44}
45
46/* *********************************************************************************************************//**
47 * Added the XML end tag (e.g., "</tag>") with tag name *a_label* to the last srd::string in *a_XMLList*.
48 *
49 * @param a_XMLList [in] The list whose last item is emended with an XML end tag.
50 * @param a_label [in] The name of the end tag.
51 ***********************************************************************************************************/
52
53void appendXMLEnd( std::vector<std::string> &a_XMLList, std::string const &a_label ) {
54
55 std::string theEnd = "</" + a_label + ">";
56 std::vector<std::string>::iterator iter = a_XMLList.end( );
57 --iter;
58 *iter += theEnd;
59}
60
61/* *********************************************************************************************************//**
62 * This function returns the "special particle id" for the specified particle id (*a_id*). The id returned depends
63 * on the *a_mode* argument. Currently, for all *a_id*'s but for those listed in the following table, * *a_id* is
64 * returned. For an *a_id* in the following table, find the column that contains the specfied *a_id*, the id returned
65 * will be the id in that column whose row matches the specified *a_mode*.
66 *
67 | a_mode | ids -> |||||
68 | ------------ | ----- | ----- | ----- | ----- | ---- |
69 | familiar | p | d | t | h | a |
70 | nuclide | H1 | H2 | H3 | He3 | He4 |
71 | nucleus | h1 | h2 | h3 | he3 | he4 |
72 *
73 * @param a_mode [in] The mode which determines the returned id.
74 * @param a_id [in] The specified particle id.
75 *
76 * @return The special particle id.
77 ***********************************************************************************************************/
78
79std::string specialParticleID( SpecialParticleID_mode a_mode, std::string const &a_id ) {
80
81 static std::string firstChars( "pdthaH" );
82 std::size_t iid = 0;
83
84 if( a_id.size( ) > 3 ) return( a_id );
85
86 std::size_t index = firstChars.find( a_id[0] );
87
88 if( index == std::string::npos ) return( a_id );
89
90 if( a_id == "H" ) return( a_id ); // Special case to avoid test of id1[0] two lines later.
91 std::string id1( a_id );
92 if( id1[0] == 'H' ) id1[0] = 'h';
93
94 if( id1 == IDs::proton || id1 == "h1" ) {
95 iid = 1; }
96 else if( id1 == IDs::familiarDeuteron || id1 == "h2" ) {
97 iid = 2; }
98 else if( id1 == IDs::familiarTriton || id1 == "h3" ) {
99 iid = 3; }
100 else if( id1 == IDs::familiarHelion || id1 == "he3" ) {
101 iid = 4; }
102 else if( id1 == IDs::familiarAlpha || id1 == "he4" ) {
103 iid = 5;
104 }
105 if( iid == 0 ) return( a_id );
106
107 if( a_mode == SpecialParticleID_mode::familiar ) {
108 return( firstChars.substr( iid-1, 1 ) ); }
109 else {
110 if( iid == 1 ) {
111 id1 = "h1"; }
112 else if( iid == 2 ) {
113 id1 = "h2"; }
114 else if( iid == 3 ) {
115 id1 = "h3"; }
116 else if( iid == 4 ) {
117 id1 = "he3"; }
118 else {
119 id1 = "he4";
120 }
121 if( a_mode == SpecialParticleID_mode::nuclide ) id1[0] = 'H';
122 }
123 return( id1 );
124}
125
126/* *********************************************************************************************************//**
127 * Compares two particle ids and returns if they are the same particle. This methods using the name returned by the function
128 * **specialParticleID** with the same SpecialParticleID_mode for each particle id. Ergo, "H1" is the same as "H1", "p" or "h1".
129 *
130 * @return **true** if particles are the same and **false** otherwise.
131 ***********************************************************************************************************/
132
133bool compareSpecialParticleIDs( std::string const &a_id1, std::string const &a_id2 ) {
134
136}
137
138/* *********************************************************************************************************//**
139 * Returns the Z (i.e., the atomic number) for a nuclear type particle; otherwise, 0 is returned. Currently, non-0
140 * values are returned if *a_particle* is an isotope, nuclide or nucleus, or if it is a proton and *a_isNeutronProtonANucleon*
141 * is **true**. Note, this is not the charge of the particle but its atomic number. For example, the atomic number
142 * for an electron is 0 as it is not a nuclear type particle.
143 *
144 * @param a_particle [in] The PoPI::Base instance whose Z is returned.
145 * @param a_isNeutronProtonANucleon [in] If **true** a proton is treated as a nucleus.
146 *
147 * @return The Z of the particle
148 ***********************************************************************************************************/
149
150int particleZ( Base const &a_particle, bool a_isNeutronProtonANucleon ) {
151
152 int Z = 0;
153
154 if( a_particle.ID( ) == IDs::proton ) {
155 if( a_isNeutronProtonANucleon ) Z = 1; }
156 else if( a_particle.isNuclide( ) ) {
157 Nuclide const &particle = (Nuclide const &) a_particle;
158 Z = particle.Z( ); }
159 else if( a_particle.isNucleus( ) ) {
160 Nucleus const &particle = (Nucleus const &) a_particle;
161 Z = particle.Z( ); }
162 else if( a_particle.isChemicalElement( ) ) {
163 ChemicalElement const &object = (ChemicalElement const &) a_particle;
164 Z = object.Z( ); }
165 else if( a_particle.isIsotope( ) ) {
166 Isotope const &object = (Isotope const &) a_particle;
167 Z = object.Z( );
168 }
169
170 return( Z );
171}
172
173/* *********************************************************************************************************//**
174 * Uses the index *a_index* to look up the particle in *a_pops* and calls **particleZ** for that particle.
175 *
176 * @param a_pops [in] The PoPs database to look up the particle.
177 * @param a_index [in] The index of the particle in *a_pops* whose Z value is returned.
178 * @param a_isNeutronProtonANucleon [in] If **true** a proton is treated as a nucleus.
179 *
180 * @return The Z returned by **particleZ( Base const &, bool )**.
181 ***********************************************************************************************************/
182
183int particleZ( Database const &a_pops, std::size_t a_index, bool a_isNeutronProtonANucleon ) {
184
185 int Z = 0;
186 Base const &base( a_pops.get<Base>( a_pops.final( a_index ) ) );
187
188 if( base.isChemicalElement( ) ) {
189 SymbolBase const &object2( static_cast<SymbolBase const &>( base ) );
190 Z = particleZ( object2 ); }
191 else {
192 Particle const &particle( static_cast<Particle const &>( base ) );
193 Z = particleZ( particle, a_isNeutronProtonANucleon );
194 }
195
196 return( Z );
197}
198
199/* *********************************************************************************************************//**
200 * Uses the id *a_id* to look up the particle in *a_pops* and calls **particleZ** for that particle.
201 *
202 * @param a_pops [in] The PoPs database to look up the particle.
203 * @param a_id [in] The id of the particle in *a_pops* whose Z value is returned.
204 * @param a_isNeutronProtonANucleon [in] If **true** a proton is treated as a nucleus.
205 *
206 * @return The Z returned by **particleZ( Base const &, bool )**.
207 ***********************************************************************************************************/
208
209int particleZ( Database const &a_pops, std::string const &a_id, bool a_isNeutronProtonANucleon ) {
210
211 Base const &object( a_pops.get<Particle>( a_pops.final( a_id ) ) );
212
213 return( particleZ( object, a_isNeutronProtonANucleon ) );
214}
215
216/* *********************************************************************************************************//**
217 * Returns the A (i.e., atomic mass number) for a nuclear type particle; otherwise, 0 is returned. Currently, non-0
218 * values are returned if *a_particle* is an isotope, nuclide or nucleus, or if it is a neutron or a proton and
219 * *a_isNeutronProtonANucleon* is **true**.
220 *
221 * @param a_particle [in] The PoPI::Base instance whose Z is returned.
222 * @param a_isNeutronProtonANucleon [in] If **true** a proton is treated as a nucleus.
223 *
224 * @return The Z of the particle
225 ***********************************************************************************************************/
226
227int particleA( Base const &a_particle, bool a_isNeutronProtonANucleon ) {
228
229 int A = 0;
230
231 if( a_particle.ID( ) == IDs::neutron ) {
232 if( a_isNeutronProtonANucleon ) A = 1; }
233 else if( a_particle.ID( ) == IDs::proton ) {
234 if( a_isNeutronProtonANucleon ) A = 1; }
235 else if( a_particle.isNuclide( ) ) {
236 Nuclide const &particle = (Nuclide const &) a_particle;
237 A = particle.A( ); }
238 else if( a_particle.isNucleus( ) ) {
239 Nucleus const &particle = (Nucleus const &) a_particle;
240 A = particle.A( ); }
241 else if( a_particle.isIsotope( ) ) {
242 Isotope const &object = (Isotope const &) a_particle;
243 A = object.A( );
244 }
245
246 return( A );
247}
248
249/* *********************************************************************************************************//**
250 * Uses the index *a_index* to look up the particle in *a_pops* and calls **particleA** for that particle.
251 *
252 * @param a_pops [in] The PoPs database to look up the particle.
253 * @param a_index [in] The index of the particle in *a_pops* whose A value is returned.
254 * @param a_isNeutronProtonANucleon [in] If **true** a proton is treated as a nucleus.
255 *
256 * @return The A returned by **particleA( Base const &, bool )**.
257 ***********************************************************************************************************/
258
259int particleA( Database const &a_pops, std::size_t a_index, bool a_isNeutronProtonANucleon ) {
260
261 Base const &particle( a_pops.get<Base>( a_pops.final( a_index ) ) );
262
263 return( particleA( particle, a_isNeutronProtonANucleon ) );
264}
265
266/* *********************************************************************************************************//**
267 * Uses the id *a_id* to look up the particle in *a_pops* and calls **particleA** for that particle.
268 *
269 * @param a_pops [in] The PoPs database to look up the particle.
270 * @param a_id [in] The id of the particle in *a_pops* whose A value is returned.
271 * @param a_isNeutronProtonANucleon [in] If **true** a proton is treated as a nucleus.
272 *
273 * @return The A returned by **particleA( Base const &, bool )**.
274 ***********************************************************************************************************/
275
276int particleA( Database const &a_pops, std::string const &a_id, bool a_isNeutronProtonANucleon ) {
277
278 Base const &particle( a_pops.get<Base>( a_pops.final( a_id ) ) );
279
280 return( particleA( particle, a_isNeutronProtonANucleon ) );
281}
282
283/* *********************************************************************************************************//**
284 * Returns the ZA (i.e., 1000 * Z + A) for a nuclear type particle; otherwise, 0 is returned. Currently, non-0
285 * values are returned if *a_particle* is an isotope, nuclide or nucleus, or if it is a neutron or a proton
286 * and *a_isNeutronProtonANucleon* is **true**.
287 *
288 * @param a_particle [in] The PoPI::Base instance whose Z is returned.
289 * @param a_isNeutronProtonANucleon [in] If **true** a proton is treated as a nucleus.
290 *
291 * @return The Z of the particle
292 ***********************************************************************************************************/
293
294int particleZA( Base const &a_particle, bool a_isNeutronProtonANucleon ) {
295
296 int ZA = 0;
297
298 if( a_particle.ID( ) == IDs::neutron ) {
299 if( a_isNeutronProtonANucleon ) ZA = 1; }
300 else {
301 if( !a_particle.isChemicalElement( ) ) ZA = 1000 * particleZ( a_particle, a_isNeutronProtonANucleon ) + particleA( a_particle, a_isNeutronProtonANucleon );
302 }
303
304 return( ZA );
305}
306
307/* *********************************************************************************************************//**
308 * Uses the index *a_index* to look up the particle in *a_pops* and calls **particleZA** for that particle.
309 *
310 * @param a_pops [in] The PoPs database to look up the particle.
311 * @param a_index [in] The index of the particle in *a_pops* whose ZA value is returned.
312 * @param a_isNeutronProtonANucleon [in] If **true** a proton is treated as a nucleus.
313 *
314 * @return The ZA returned by **particleZA( Base const &, bool )**.
315 ***********************************************************************************************************/
316
317int particleZA( Database const &a_pops, std::size_t a_index, bool a_isNeutronProtonANucleon ) {
318
319 Base const &particle( a_pops.get<Base>( a_pops.final( a_index ) ) );
320
321 return( particleZA( particle, a_isNeutronProtonANucleon ) );
322}
323
324/* *********************************************************************************************************//**
325 * Uses the id *a_id* to look up the particle in *a_pops* and calls **particleZA** for that particle.
326 *
327 * @param a_pops [in] The PoPs database to look up the particle.
328 * @param a_id [in] The id of the particle in *a_pops* whose ZA value is returned.
329 * @param a_isNeutronProtonANucleon [in] If **true** a proton is treated as a nucleus.
330 *
331 * @return The ZA returned by **particleZA( Base const &, bool )**.
332 ***********************************************************************************************************/
333
334int particleZA( Database const &a_pops, std::string const &a_id, bool a_isNeutronProtonANucleon ) {
335
336 Base const &particle( a_pops.get<Base>( a_pops.final( a_id ) ) );
337
338 return( particleZA( particle, a_isNeutronProtonANucleon ) );
339}
340
341/* *********************************************************************************************************//**
342 * Returns the meta-stable index if *a_particle* is a PoPI::MetaStable alias; otherwise, 0 is returned.
343 *
344 * @param a_particle [in] The PoPI::Base instance whose meta-stable index is returned.
345 *
346 * @return The meta-stable index of the particle
347 ***********************************************************************************************************/
348
349int particleMetaStableIndex( Base const &a_particle ) {
350
351 int metaStableIndex = 0;
352
353 if( a_particle.isMetaStableAlias( ) ) {
354 MetaStable const &object = (MetaStable const &) a_particle;
355 metaStableIndex = object.metaStableIndex( );
356 }
357
358 return( metaStableIndex );
359}
360
361/* *********************************************************************************************************//**
362 * Returns the meta-stable index if *a_index* is a PoPI::MetaStable alias; otherwise, 0 is returned.
363 *
364 * @param a_pops [in] The PoPs database to look up the particle.
365 * @param a_index [in] The index of the particle in *a_pops* whose meta-stable index value is returned.
366 *
367 * @return The meta-stable index of the particle
368 ***********************************************************************************************************/
369
370int particleMetaStableIndex( Database const &a_pops, std::size_t a_index ) {
371
372 Base const &object( a_pops.get<Base>( a_pops.final( a_index ) ) );
373
374 return( particleMetaStableIndex( object ) );
375}
376
377/* *********************************************************************************************************//**
378 * Returns the meta-stable index if *a_id* is a PoPI::MetaStable alias; otherwise, 0 is returned.
379 *
380 * @param a_pops [in] The PoPs database to look up the particle.
381 * @param a_id [in] The id of the particle in *a_pops* whose meta-stable index value is returned.
382 *
383 * @return The meta-stable index of the particle
384 ***********************************************************************************************************/
385
386int particleMetaStableIndex( Database const &a_pops, std::string const &a_id ) {
387
388 Base const &object( a_pops.get<Base>( a_pops.final( a_id ) ) );
389
390 return( particleMetaStableIndex( object ) );
391}
392
393/* *********************************************************************************************************//**
394 * A physical quantity can be a double, integer, fraction (e.g, '3/7') or a string. For all but string,
395 * this functions returns a double representing the value of the physical quantity *a_physicalQuantity*.
396 * For string, a throw is executed.
397 *
398 * @param a_physicalQuantity [in] The physical quantity whose value is returend.
399 *
400 * @return A double value representing the physical quantity.
401 ***********************************************************************************************************/
402
403double getPhysicalQuantityAsDouble( PhysicalQuantity const &a_physicalQuantity ) {
404
405 double value = 0.0;
406
407 switch( a_physicalQuantity.Class( ) ) {
408 case PQ_class::Double :
409 case PQ_class::shell : {
410 PQ_double const &pq_double = static_cast<PQ_double const &>( a_physicalQuantity );
411 value = pq_double.value( ); }
412 break;
413 case PQ_class::integer : {
414 PQ_integer const &pq_integer = static_cast<PQ_integer const &>( a_physicalQuantity );
415 value = pq_integer.value( ); }
416 break;
417 default :
418 throw Exception( "Cannot convert physical quantitiy to a double." );
419 }
420
421 return( value );
422}
423
424/* *********************************************************************************************************//**
425 * If the suite *a_suite* as data, **getPhysicalQuantityAsDouble** is called on its first item; otherwise,
426 * a throw is executed. If *a_suite* is empty and *a_allowEmpty* is **true**, then *a_emptyValue* is returned.
427 *
428 * @param a_suite [in] The suite whose first item's value is returned as a double.
429 * @param a_allowEmpty [in] Determines act to follow when *a_suite* is empty.
430 * @param a_emptyValue [in] The value to return if *a_suite* is empty and *a_allowEmpty* is **true**.
431 *
432 * @return A double value representing the physical quantity.
433 ***********************************************************************************************************/
434
435double getPhysicalQuantityOfSuiteAsDouble( PQ_suite const &a_suite, bool a_allowEmpty, double a_emptyValue ) {
436
437 if( a_suite.size( ) == 0 ) {
438 if( a_allowEmpty ) return( a_emptyValue );
439 throw Exception( "No physical quantitiy in Suite." );
440 }
441
442 return( getPhysicalQuantityAsDouble( *a_suite[0] ) );
443}
444
445/* *********************************************************************************************************//**
446 * Breaks th components of a particles name into base, anti and quailier strings. Every id in GNDS PoPs can be of the
447 * form base["_anti"][qualifier] where both "_anti" and qualifier are optional. For example, an electron is represented
448 * as "e-" and an anti-electron (i.e., positron) "e-_anti". Qualifiers are endings imbedded by "{" and "}". For example,
449 * "H{1s1/2}" has the base "H" with quailifier "1s1/2" where the "{" and "}" have been stripped from the quailifier.
450 *
451 * @param a_id [in] The base id for *a_id*.
452 * @param a_anti [in] A std::string to be filled with "_anti" if particle is an anti-particle and an "" otherwise.
453 * @param a_qualifier [in] A pointer to a std::string that will be filled with the qualifer characters.
454 *
455 * @return The base id for the particle.
456 ***********************************************************************************************************/
457
458std::string baseAntiQualifierFromID( std::string const &a_id, std::string &a_anti, std::string *a_qualifier) {
459
460 std::size_t curlyBraketPosition = a_id.find( "{" );
461 std::string base = a_id.substr( 0, curlyBraketPosition );
462
463 a_anti = "";
464 if( a_qualifier != nullptr ) *a_qualifier = "";
465
466 if( curlyBraketPosition != std::string::npos ) {
467 if( a_id.back( ) != '}' ) throw Exception( "Invalid quaifier string in id '" + a_id + "'." );
468 base = a_id.substr( 0, curlyBraketPosition );
469 if( a_qualifier != nullptr ) {
470 *a_qualifier = a_id.substr( curlyBraketPosition + 1, a_id.size( ) - curlyBraketPosition - 2 );
471 } }
472 else if( a_id.find( "}" ) != std::string::npos ) {
473 throw Exception( "Invalid quaifier string in id '" + a_id + "'." );
474 }
475
476 std::size_t anti_position = base.find( IDs::anti );
477 if( anti_position != std::string::npos ) {
478 a_anti = base.substr( anti_position );
479 base = base.substr( 0, anti_position );
480 if( a_anti != IDs::anti ) throw Exception( "Invalid anti string in id '" + a_id + "'." );
481 }
482
483 return( base );
484}
485
486/*! \class Exception
487 * Exception class for all PoPI exceptions thrown by PoPI functions.
488 */
489
490/* *********************************************************************************************************//**
491 * @param a_message [in] The message that the function what() will return.
492 ***********************************************************************************************************/
493
494Exception::Exception( std::string const & a_message ) :
495 std::runtime_error( a_message ) {
496
497}
498
499}
const G4double A[17]
#define PoPI_formatVersion_0_1_Chars
Definition PoPI.hpp:33
std::string const & format() const
Definition LUPI.hpp:74
bool isChemicalElement() const
Definition PoPI.hpp:670
bool isNucleus() const
Definition PoPI.hpp:667
bool isNuclide() const
Definition PoPI.hpp:668
bool isIsotope() const
Definition PoPI.hpp:669
std::string const & ID(void) const
Definition PoPI.hpp:652
bool isMetaStableAlias(void) const
Definition PoPI.hpp:660
T const & get(std::string const &a_id) const
std::string final(std::string const &a_id, bool a_returnAtMetaStableAlias=false) const
Exception(std::string const &a_message)
Definition PoPI_misc.cc:494
int A(void) const
Definition PoPI.hpp:976
int Z(void) const
Definition PoPI.hpp:975
int A(void) const
int Z(void) const
double value(void) const
Definition PoPI.hpp:443
int value(void) const
Definition PoPI.hpp:465
PQ_class Class(void) const
Definition PoPI.hpp:416
Definition PoPI.hpp:28
double getPhysicalQuantityOfSuiteAsDouble(PQ_suite const &a_suite, bool a_allowEmpty=false, double a_emptyValue=0.0)
Definition PoPI_misc.cc:435
int particleA(Base const &a_particle, bool a_isNeutronProtonANucleon=false)
Definition PoPI_misc.cc:227
std::string specialParticleID(SpecialParticleID_mode a_mode, std::string const &a_id)
Definition PoPI_misc.cc:79
int particleMetaStableIndex(Base const &a_particle)
Definition PoPI_misc.cc:349
int particleZ(Base const &a_particle, bool a_isNeutronProtonANucleon=false)
Definition PoPI_misc.cc:150
double getPhysicalQuantityAsDouble(PhysicalQuantity const &a_physicalQuantity)
Definition PoPI_misc.cc:403
bool supportedFormat(LUPI::FormatVersion const &a_formatVersion)
Definition PoPI_misc.cc:39
int particleZA(Base const &a_particle, bool a_isNeutronProtonANucleon=false)
Definition PoPI_misc.cc:294
SpecialParticleID_mode
Definition PoPI.hpp:116
bool compareSpecialParticleIDs(std::string const &a_id1, std::string const &a_id2)
Definition PoPI_misc.cc:133
void appendXMLEnd(std::vector< std::string > &a_XMLList, std::string const &a_label)
Definition PoPI_misc.cc:53
std::string baseAntiQualifierFromID(std::string const &a_id, std::string &a_anti, std::string *a_qualifier=nullptr)
Definition PoPI_misc.cc:458
static std::string const anti
Definition PoPI.hpp:173
static std::string const photon
Definition PoPI.hpp:162
static std::string const familiarPhoton
Definition PoPI.hpp:166
static std::string const neutron
Definition PoPI.hpp:164
static std::string const FissionProductENDL99125
Definition PoPI.hpp:172
static std::string const familiarTriton
Definition PoPI.hpp:168
static std::string const FissionProductENDL99120
Definition PoPI.hpp:171
static std::string const familiarHelion
Definition PoPI.hpp:169
static std::string const proton
Definition PoPI.hpp:165
static std::string const familiarAlpha
Definition PoPI.hpp:170
static std::string const familiarDeuteron
Definition PoPI.hpp:167
static std::string const electron
Definition PoPI.hpp:163