Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
PoPI_database.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 <stdio.h>
11#include <stdexcept>
12
13#include "PoPI.hpp"
14
15#define PoPI_gaugeBosonsChars "gaugeBosons"
16#define PoPI_leptonsChars "leptons"
17#define PoPI_baryonsChars "baryons"
18#define PoPI_unorthodoxesChars "unorthodoxes"
19
20#define MsgSize (8 * 1024)
21#ifdef _WIN32
22#define __func__ __FUNCTION__
23#endif
24
25namespace PoPI {
26
27static void parseAliases( HAPI::Node const &a_node, Database *a_DB );
28
29/*! \class Database
30 * The main class for storing **PoPs** data.
31 */
32
33/* *********************************************************************************************************//**
34 * Database constructor for an initial empty **PoPs** database.
35 ***********************************************************************************************************/
36
38 m_gaugeBosons( PoPI_gaugeBosonsChars ),
39 m_leptons( PoPI_leptonsChars ),
40 m_baryons( PoPI_baryonsChars ),
41 m_chemicalElements( PoPI_chemicalElementsChars ),
42 m_unorthodoxes( PoPI_unorthodoxesChars ) {
43
44}
45
46/* *********************************************************************************************************//**
47 * Database constructor for a **PoPs** database with data read from the file *a_fileName*.
48 *
49 * @param a_fileName [in] The **PoPs** file to read in.
50 ***********************************************************************************************************/
51
52Database::Database( std::string const &a_fileName ) :
53 m_gaugeBosons( PoPI_gaugeBosonsChars ),
54 m_leptons( PoPI_leptonsChars ),
55 m_baryons( PoPI_baryonsChars ),
56 m_chemicalElements( PoPI_chemicalElementsChars ),
57 m_unorthodoxes( PoPI_unorthodoxesChars ) {
58
59 addFile( a_fileName, false );
60}
61
62/* *********************************************************************************************************//**
63 * Database constructor for a **PoPs** database with data read from a **HAPI::Node** instance. This method is mainly
64 * for internal use.
65 *
66 * @param a_database [in] A **HAPI::Node** instance containing the data to parse.
67 ***********************************************************************************************************/
68
69Database::Database( HAPI::Node const &a_database ) :
70 m_gaugeBosons( PoPI_gaugeBosonsChars ),
71 m_leptons( PoPI_leptonsChars ),
72 m_baryons( PoPI_baryonsChars ),
73 m_chemicalElements( PoPI_chemicalElementsChars ),
74 m_unorthodoxes( PoPI_unorthodoxesChars ) {
75
76 addDatabase( a_database, false );
77}
78
79/* *********************************************************************************************************//**
80 * Adds the contents of the file *a_fileName* to *this*.
81 *
82 * @param a_fileName [in] The **PoPs** file to get data from.
83 * @param a_warnIfDuplicate [in] This argument is currently not used.
84 ***********************************************************************************************************/
85
86void Database::addFile( std::string const &a_fileName, bool a_warnIfDuplicate ) {
87
88 addFile( a_fileName.c_str( ), a_warnIfDuplicate );
89}
90
91/* *********************************************************************************************************//**
92 * Adds the contents of the file *a_fileName* to *this*.
93 *
94 * @param a_fileName [in] The **PoPs** file to get data from.
95 * @param a_warnIfDuplicate [in] This argument is currently not used.
96 ***********************************************************************************************************/
97
98void Database::addFile( char const *a_fileName, bool a_warnIfDuplicate ) {
99
100 HAPI::File *doc = new HAPI::PugiXMLFile( a_fileName, "Database::addFile" );
101 HAPI::Node database = doc->first_child( );
102 addDatabase( database, a_warnIfDuplicate );
103 delete doc;
104}
105
106/* *********************************************************************************************************//**
107 * Adds the contents of the *a_string* to *this*. *a_string* must be an XML string
108 * starting with an **PoPs** XML node (i.e., element).
109 *
110 * @param a_string [in] A *std::string* instance of **PoPs** data in an XML format.
111 * @param a_warnIfDuplicate [in] This argument is currently not used.
112 ***********************************************************************************************************/
113
114void Database::addDatabase( std::string const &a_string, bool a_warnIfDuplicate ) {
115
116 // a_string must contain a complete & well-formed XML document
118
119 pugi::xml_parse_result result = doc.load_string( a_string.c_str( ) );
120 if( result.status != pugi::status_ok ) {
121 char Msg[MsgSize+1];
122
123 snprintf( Msg, MsgSize, "ERROR: in file '%s' in method '%s': %s.", __FILE__, __func__, result.description( ) );
124 throw Exception( Msg );
125 }
126
127 HAPI::PugiXMLNode *database_internal = new HAPI::PugiXMLNode(doc.first_child( ));
128 HAPI::Node database(database_internal);
129 addDatabase( database, a_warnIfDuplicate );
130}
131
132/* *********************************************************************************************************//**
133 * Adds the contents of *a_database* to *this*. The top node of *a_database* must be a valid **PoPs** node.
134 *
135 * @param a_database [in] The **HAPI::Node** node to be added to *this*.
136 * @param a_warnIfDuplicate [in] This argument is currently not used.
137 ***********************************************************************************************************/
138
139void Database::addDatabase( HAPI::Node const &a_database, LUPI_maybeUnused bool a_warnIfDuplicate ) {
140
141 if( a_database.name( ) != PoPI_PoPsChars ) throw Exception( "Node '" + a_database.name( ) + "' is not a 'PoPs' node." );
142
144 if( !supportedFormat( formatVersion ) ) throw Exception( "Invalid format '" + formatVersion.format( ) + " in file " + a_database.name( ) + "." );
145 if( m_formatVersion.format( ) == "" ) m_formatVersion = formatVersion;
146
147 if( m_name == "" ) m_name = a_database.attribute( PoPI_nameChars ).value( );
148 if( m_version == "" ) m_version = a_database.attribute( PoPI_versionChars ).value( );
149
150 for( HAPI::Node child = a_database.first_child( ); !child.empty( ); child.to_next_sibling( ) ) {
151 std::string s_name( child.name( ) );
152
153 if( s_name == PoPI_gaugeBosonsChars ) {
154 m_gaugeBosons.appendFromParentNode( child, this, this ); }
155 else if( s_name == PoPI_leptonsChars ) {
156 m_leptons.appendFromParentNode( child, this, this ); }
157 else if( s_name == PoPI_baryonsChars ) {
158 m_baryons.appendFromParentNode( child, this, this ); }
159 else if( s_name == PoPI_chemicalElementsChars ) {
160 m_chemicalElements.appendFromParentNode( child, this, this ); }
161 else if( s_name == PoPI_unorthodoxesChars ) {
162 m_unorthodoxes.appendFromParentNode( child, this, this ); }
163 else if( s_name == PoPI_aliasesChars ) {
164 parseAliases( child, this ); }
165 else {
166 }
167 }
168
169 std::vector<Alias *> unresolvedAliases2;
170 for( std::vector<Alias *>::iterator iter = m_unresolvedAliases.begin( ); iter != m_unresolvedAliases.end( ); ++iter ) {
171 auto pidIter = m_idsMap.find( (*iter)->pid( ) ); // Locate pid.
172
173 if( pidIter == m_idsMap.end( ) ) {
174 unresolvedAliases2.push_back( *iter ); }
175 else {
176 (*iter)->setPidIndex( pidIter->second );
177 }
178 }
179 m_unresolvedAliases.clear( );
180 for( auto iter = unresolvedAliases2.begin( ); iter != unresolvedAliases2.end( ); ++iter ) {
181 m_unresolvedAliases.push_back( *iter );
182 }
183}
184
185/* *********************************************************************************************************//**
186 * For internal use only. This method parses a **PoPs** *aliases* node.
187 *
188 * @param a_node [in] The **HAPI::Node** node to be parsed.
189 * @param a_DB [in] The **PoPI::Database** to add the alias data to.
190 ***********************************************************************************************************/
191
192static void parseAliases( HAPI::Node const &a_node, Database *a_DB ) {
193
194 for( HAPI::Node child = a_node.first_child( ); !child.empty( ); child.to_next_sibling( ) ) {
195 std::string name = child.name( );
196 Alias *alias = nullptr;
197
198 if( name == PoPI_aliasChars ) {
199 alias = new Alias( child, a_DB ); }
200 else if( name == PoPI_metaStableChars ) {
201 alias = new MetaStable( child, a_DB ); }
202 else if( name == PoPI_particleChars ) { // Needed for GNDS 1.10.
203 alias = new Alias( child, a_DB ); }
204 else {
205 throw Exception( "Node '" + name + "' not supported as a child node of PoPs/aliases." );
206 }
207 a_DB->addAlias( alias );
208 }
209}
210
211/* *********************************************************************************************************//**
212 * Destructor for a **PoPI::Database** instance.
213 ***********************************************************************************************************/
214
216
217 for( std::vector<Alias *>::iterator iter = m_aliases.begin( ); iter != m_aliases.end( ); ++iter ) delete *iter;
218}
219
220/* *********************************************************************************************************//**
221 * This method returns the list of ids for the aliases with unresolved pids.
222 *
223 * @return A std::vector<std::string> of the ids of the aliases with unresolved pids.
224 ***********************************************************************************************************/
225
226std::vector<std::string> Database::unresolvedAliasIds( ) const {
227
228 std::vector<std::string> ids;
229
230 for( std::vector<Alias *>::const_iterator iter = m_unresolvedAliases.begin( ); iter != m_unresolvedAliases.end( ); ++iter ) {
231 ids.push_back( (*iter)->ID( ) );
232 }
233
234 return( ids );
235}
236
237/* *********************************************************************************************************//**
238 * Internally, **PoPI::Database** stores a unique integer (called an index) for each particle in *this*. This method returns the
239 * the index for the specified particle.
240 *
241 * @param a_id [in] The **PoPs** id for the specified particle.
242 *
243 * @return The internal index for the specified particle.
244 ***********************************************************************************************************/
245
246std::size_t Database::operator[]( std::string const &a_id ) const {
247
248 auto iter = m_idsMap.find( a_id );
249 if( iter == m_idsMap.end( ) ) {
250 std::string errorMessage( "particle '" + a_id + "' not in database -3." );
251 throw Exception( errorMessage );
252 }
253
254 return( iter->second );
255}
256
257/* *********************************************************************************************************//**
258 * Returns **true** if the specified index is value and **false** otherwise. This is, if a particle exists within
259 * *this* with index *a_index*.
260 *
261 * @param a_index [in] A particle index to test.
262 *
263 * @return **true** is the specified index is valid and **false** otherwise.
264 ***********************************************************************************************************/
265
266bool Database::exists( std::size_t a_index ) const {
267
268 if( a_index >= m_list.size( ) ) return( false );
269 return( true );
270}
271
272/* *********************************************************************************************************//**
273 * Returns **true** if the specified id exists within *this* and **false** otherwise.
274 *
275 * @param a_id [in] A particle id to test.
276 *
277 * @return **true** is the specified id exists in *this* and **false** otherwise.
278 ***********************************************************************************************************/
279
280bool Database::exists( std::string const &a_id ) const {
281
282 auto iter = m_idsMap.find( a_id );
283 return( iter != m_idsMap.end( ) );
284}
285
286/* *********************************************************************************************************//**
287 * Returns **true** if the specified intid exists within *this* and **false** otherwise.
288 *
289 * @param a_intid [in] A particle's intidd to test.
290 *
291 * @return **true** is the specified intid exists in *this* and **false** otherwise.
292 ***********************************************************************************************************/
293
294bool Database::existsIntid( int a_intid ) const {
295
296 return( m_intidsMap.find( a_intid ) != m_intidsMap.end( ) );
297}
298
299/* *********************************************************************************************************//**
300 * Returns a std::vector of std::string's of all aliases in *this* that resolve to *a_id*.
301 *
302 * @param a_id [in] A particle's id whose.
303 *
304 * @return Vector of alias ids.
305 ***********************************************************************************************************/
306
307std::vector<std::string> Database::aliasReferences( std::string const &a_id ) {
308
309 std::vector<std::string> ids;
310
311 for( auto aliasIter = m_aliases.begin( ); aliasIter != m_aliases.end( ); ++aliasIter ) {
312 if( final( (*aliasIter)->pid( ) ) == a_id ) ids.push_back( (*aliasIter)->ID( ) );
313 }
314
315 return( ids );
316}
317
318/* *********************************************************************************************************//**
319 * This method resolves aliases to return an actual particle specified by *a_id*. That is, if *a_id* is an alias,
320 * then its referenced particle is returned. However, if *a_returnAtMetaStableAlias* is **true** and a meta-stable
321 * is found while resolving *a_id*, then the meta-stable id will be returned.
322 *
323 * @param a_id [in] A particle's id whose resolved particle id is requested.
324 * @param a_returnAtMetaStableAlias [in] If **true**, the resolving will stop if a meta-stable is found.
325 *
326 * @return The revolved id for *a_id*.
327 ***********************************************************************************************************/
328
329std::string Database::final( std::string const &a_id, bool a_returnAtMetaStableAlias ) const {
330
331 std::size_t index( final( (*this)[a_id], a_returnAtMetaStableAlias ) );
332
333 return( m_list[index]->ID( ) );
334}
335
336/* *********************************************************************************************************//**
337 * This method resolves aliases to return an actual particle specified by *a_index*. That is, if *a_index* is an alias,
338 * then its referenced particle is returned. However, if *a_returnAtMetaStableAlias* is **true** and a meta-stable
339 * is found while resolving *a_index*, the then meta-stable index will be returned.
340 *
341 * @param a_index [in] A particle's index whose resolved particle index is requested.
342 * @param a_returnAtMetaStableAlias [in] If **true**, the resolving will stop if a meta-stable is found.
343 *
344 * @return The revolved index for *a_index*.
345 ***********************************************************************************************************/
346
347std::size_t Database::final( std::size_t a_index, bool a_returnAtMetaStableAlias ) const {
348
349 while( isAlias( a_index ) ) {
350 if( a_returnAtMetaStableAlias && isMetaStableAlias( a_index ) ) break;
351 a_index = ((Alias *) m_list[a_index])->pidIndex( );
352 }
353 return( a_index );
354}
355
356/* *********************************************************************************************************//**
357 * This method returns the chemical element symbol for *a_id* if it is a PoPs id for a chemicalElement, isotope, nuclide,
358 * or nucleus object. Otherwise, it returns an empty string. The PoPs id *a_id* must be in *this*.
359 *
360 * @param a_id [in] A particle's id whose chemical element symbol is requested.
361 *
362 * @return The string for the chemical element symbol.
363 ***********************************************************************************************************/
364
365std::string Database::chemicalElementSymbol( std::string const &a_id ) const {
366
367 std::string symbol1;
368 Base const *base = nullptr;
369
370 auto iter = m_idsMap.find( a_id );
371 if( iter != m_idsMap.end( ) ) {
372 std::string finalId = final( a_id );
373 iter = m_idsMap.find( finalId );
374 base = m_list[iter->second]; }
375 else {
376 auto iter2 = m_symbolMap.find( a_id );
377 if( iter2 != m_symbolMap.end( ) ) base = m_symbolList[iter2->second];
378 }
379
380 if( base != nullptr ) {
381 if( base->isNucleus( ) ) base = static_cast<Nucleus const *>( base )->nuclide( );
382 if( base->isNuclide( ) ) base = static_cast<Nuclide const *>( base )->isotope( );
383 if( base->isIsotope( ) ) base = static_cast<Isotope const *>( base )->chemicalElement( );
384 if( base->isChemicalElement( ) ) symbol1 = base->ID( );
385 }
386
387 return( symbol1 );
388}
389
390/* *********************************************************************************************************//**
391 * This method returns the isotope symbol for *a_id* if it is a PoPs id for an isotope, nuclide,
392 * or nucleus object. Otherwise, it returns an empty string. The PoPs id *a_id* must be in *this*.
393 *
394 * @param a_id [in] A particle's id whose isotope symbol is requested.
395 *
396 * @return The string for the isopte symbol.
397 ***********************************************************************************************************/
398
399std::string Database::isotopeSymbol( std::string const &a_id ) const {
400
401 std::string symbol1;
402 Base const *base = nullptr;
403
404 auto iter = m_idsMap.find( a_id );
405 if( iter != m_idsMap.end( ) ) {
406 std::string finalId = final( a_id );
407 iter = m_idsMap.find( finalId );
408 base = m_list[iter->second]; }
409 else {
410 auto iter2 = m_symbolMap.find( a_id );
411 if( iter2 != m_symbolMap.end( ) ) base = m_symbolList[iter2->second];
412 }
413
414 if( base != nullptr ) {
415 if( base->isNucleus( ) ) base = static_cast<Nucleus const *>( base )->nuclide( );
416 if( base->isNuclide( ) ) base = static_cast<Nuclide const *>( base )->isotope( );
417 if( base->isIsotope( ) ) symbol1 = base->ID( );
418 }
419
420 return( symbol1 );
421}
422
423/* *********************************************************************************************************//**
424 * Returns the intid for particle *a_id* or -1 if *a_id* is not in *this*.
425 *
426 * @param a_id [in] A particle's id whose intid is requested.
427 *
428 * @return The intid for *a_id* or -1 if *a_id* not in *this*.
429 ***********************************************************************************************************/
430
431int Database::intid( std::string const &a_id ) const {
432
433 int intid2 = -1;
434
435 if( exists( a_id ) ) {
436 Base const &base = get<Base const>( a_id );
437 intid2 = base.intid( );
438 }
439
440 return( intid2 );
441}
442
443/* *********************************************************************************************************//**
444 * Returns the intid for particle with index *a_index* or -1 if *a_index* is not in *this*.
445 *
446 * @param a_index [in] A particle's index whose index is requested.
447 *
448 * @return The intid for *a_index* or -1 if *a_index* not in *this*.
449 ***********************************************************************************************************/
450
451int Database::intid( std::size_t a_index ) const {
452
453 int intid2 = -1;
454
455 if( exists( a_index ) ) {
456 Base const &base = get<Base const>( a_index );
457
458 if( base.isParticle( ) ) {
459 IDBase const &idBase = static_cast<IDBase const &>( base );
460 intid2 = idBase.intid( );
461 }
462 }
463
464 return( intid2 );
465}
466
467/* *********************************************************************************************************//**
468 * Returns the index for particle with intid *a_intid* or -1 if *a_intid* is not in *this*.
469 *
470 * @param a_index [in] A particle's index whose index is requested.
471 *
472 * @return The intid for *a_index* or -1 if *a_index* not in *this*.
473 ***********************************************************************************************************/
474
475std::size_t Database::indexFromIntid( int a_intid ) const {
476
477 auto iter = m_intidsMap.find( a_intid );
478 if( iter == m_intidsMap.end( ) ) {
479 throw Exception( "Intid " + LUPI::Misc::argumentsToString( "%d", a_intid ) + " not in pops" );
480 }
481
482 return( iter->second );
483}
484
485/* *********************************************************************************************************//**
486 * This method adds a **PoPI::Base** instance to *this* and returns the unique index for it.
487 *
488 * @param a_item [in] The **PoPI::Base** instance to add to *this*.
489 *
490 * @return The index for the added **PoPI::Base** instance.
491 ***********************************************************************************************************/
492
493std::size_t Database::add( Base *a_item ) {
494
495 std::size_t index = m_list.size( );
496
497 m_idsMap[a_item->ID( )] = index;
498 m_list.push_back( a_item );
499 a_item->setIndex( index );
500
501 if( a_item->intid( ) > 0 ) m_intidsMap[a_item->intid( )] = index;
502
503 if( a_item->isAlias( ) ) m_unresolvedAliases.push_back( (Alias *) a_item );
504 return( index );
505}
506
507/* *********************************************************************************************************//**
508 * This method adds a **PoPI::SymbolBase** instance to *this* and returns the unique index for it.
509 *
510 * @param a_item [in] The **PoPI::SymbolBase** instance to add to *this*.
511 *
512 * @return The index for the added **PoPI::SymbolBase** instance.
513 ***********************************************************************************************************/
514
515
516std::size_t Database::addSymbol( SymbolBase *a_item ) {
517
518 if( a_item->Class( ) == Particle_class::chemicalElement ) return( this->add( a_item ) );
519
520 std::size_t index = m_symbolList.size( );
521
522 m_symbolMap[a_item->symbol( )] = index;
523 m_symbolList.push_back( a_item );
524 a_item->setIndex( index );
525
526 return( index );
527}
528
529/* *********************************************************************************************************//**
530 * This method calculates nuclide gamma branching infomation and adds it to *a_nuclideGammaBranchStateInfos*.
531 *
532 * @param a_nuclideGammaBranchStateInfos [in] The **NuclideGammaBranchStateInfos** instance to added nuclide gamma branching infomation to.
533 * @param a_pops2 A second PoPs used for storing GRIN added particles.
534 * @param a_extraGammaBranchStates Any additional nuclide needed by GRIN. Currently, one the capture residual.
535 ***********************************************************************************************************/
536
538 std::vector<std::string> &a_extraGammaBranchStates ) const {
539
540
541 calculateNuclideGammaBranchStateInfos2( a_nuclideGammaBranchStateInfos );
542 if( a_pops2 != nullptr ) {
543 a_pops2->calculateNuclideGammaBranchStateInfos2( a_nuclideGammaBranchStateInfos );
544 for( auto iter = a_extraGammaBranchStates.begin( ); iter != a_extraGammaBranchStates.end( ); ++iter ) {
545 PoPI::Nuclide const &nuclide = a_pops2->get<PoPI::Nuclide>( *iter );
546 nuclide.calculateNuclideGammaBranchStateInfos( *a_pops2, a_nuclideGammaBranchStateInfos, true );
547 }
548 }
549
550 std::vector<NuclideGammaBranchStateInfo *> &nuclideGammaBranchStateInfos = a_nuclideGammaBranchStateInfos.nuclideGammaBranchStateInfos( );
551 for( std::size_t i1 = 0; i1 < nuclideGammaBranchStateInfos.size( ); ++i1 ) {
552 NuclideGammaBranchStateInfo *nuclideGammaBranchStateInfo = nuclideGammaBranchStateInfos[i1];
553
554 nuclideGammaBranchStateInfo->calculateDerivedData( a_nuclideGammaBranchStateInfos );
555 }
556}
557
558/* *********************************************************************************************************//**
559 * This method calculates nuclide gamma branching infomation and adds it to *a_nuclideGammaBranchStateInfos*.
560 *
561 * @param a_nuclideGammaBranchStateInfos [in] The **NuclideGammaBranchStateInfos** instance to added nuclide gamma branching infomation to.
562 ***********************************************************************************************************/
563
565
566 for( std::size_t i1 = 0; i1 < m_chemicalElements.size( ); ++i1 ) {
567 ChemicalElement const &chemicalElement = m_chemicalElements[i1];
568
569 chemicalElement.calculateNuclideGammaBranchStateInfos( *this, a_nuclideGammaBranchStateInfos );
570 }
571}
572
573/* *********************************************************************************************************//**
574 * This method returns the mass of the particle/alias with id *a_id*.
575 * Currently, *a_unit* is ignored and the mass is returned in unit of amu.
576 *
577 * @param a_id [in] The PoPs id of the particle/alias.file to write *this* to.
578 * @param a_unit [in] The unit of the returned mass.
579 ***********************************************************************************************************/
580
581double Database::massValue( std::string const &a_id, std::string const &a_unit ) const {
582
583 Particle const &particle2 = particle( final( a_id ) );
584
585 return( particle2.massValue( a_unit ) );
586}
587
588/* *********************************************************************************************************//**
589 * Writes an **XML** version of *this* to the file *a_fileName*.
590 *
591 * @param a_fileName [in] The file to write *this* to.
592 ***********************************************************************************************************/
593
594void Database::saveAs( std::string const &a_fileName ) const {
595
596 std::string indent1( "" );
597 std::vector<std::string> XMLList;
598
599 XMLList.push_back( "<?xml version=\"1.0\"?>" );
600 toXMLList( XMLList, indent1 );
601
602 std::ofstream fileio;
603 fileio.open( a_fileName.c_str( ) );
604 for( std::vector<std::string>::iterator iter = XMLList.begin( ); iter != XMLList.end( ); ++iter ) {
605 fileio << *iter << std::endl;
606 }
607 fileio.close( );
608}
609
610/* *********************************************************************************************************//**
611 * Adds the contents of *this* to *a_XMLList* where each item in *a_XMLList* is one line (without linefeeds) to output as an XML representation of *this*.
612 *
613 * @param a_XMLList [in] The list to add an XML output representation of *this* to.
614 * @param a_indent1 [in] The amount of indentation to added to each line added to *a_XMLList*.
615 ***********************************************************************************************************/
616
617void Database::toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const {
618
619 std::string indent2 = a_indent1 + " ";
620 std::string indent3 = indent2 + " ";
621
622 std::string header1 = a_indent1 + "<PoPs name=\"" + m_name + "\" version=\"" + m_version + "\" format=\"" + m_formatVersion.format( ) + "\">";
623 a_XMLList.push_back( std::move( header1 ) );
624
625 if( m_aliases.size( ) > 0 ) {
626 std::string header2 = indent2 + "<" + PoPI_aliasesChars + ">";
627 a_XMLList.push_back( std::move( header2 ) );
628 for( std::vector<Alias *>::const_iterator iter = m_aliases.begin( ); iter != m_aliases.end( ); ++iter )
629 (*iter)->toXMLList( a_XMLList, indent3 );
630 appendXMLEnd( a_XMLList, PoPI_aliasesChars );
631 }
632 m_gaugeBosons.toXMLList( a_XMLList, indent2 );
633 m_leptons.toXMLList( a_XMLList, indent2 );
634 m_baryons.toXMLList( a_XMLList, indent2 );
635 m_unorthodoxes.toXMLList( a_XMLList, indent2 );
636 m_chemicalElements.toXMLList( a_XMLList, indent2 );
637
638 appendXMLEnd( a_XMLList, PoPI_PoPsChars );
639}
640
641/* *********************************************************************************************************//**
642 * Prints a brief outline of the contents of *this*.
643 *
644 * @param a_printIndices [in] If **true**, each particles index is also printed.
645 ***********************************************************************************************************/
646
647void Database::print( bool a_printIndices ) {
648
649 for( auto iter = m_idsMap.begin( ); iter != m_idsMap.end( ); ++iter ) {
650 std::string label( iter->first );
651 std::size_t index = iter->second;
652 Base *item = m_list[index];
653 std::string is_alias( "" );
654 std::string mass( "" );
655
656 if( item->isAlias( ) ) {
657 is_alias = " is an alias (final is label = '";
658 std::size_t finalIndex = final( index );
659 IDBase const &myfinal = get<IDBase>( finalIndex );
660 is_alias += std::string( myfinal.ID( ) );
661 is_alias += std::string( "')" ); }
662 else if( item->isParticle( ) ) {
663 Particle *particle = (Particle *) item;
664
665 try {
666 double dmass = particle->massValue( "amu" );
667 mass = LUPI::Misc::argumentsToString( " mass = %e amu", dmass ); }
668 catch (...) {
669 mass = " particle has no mass data.";
670 }
671 }
672
673 std::cout << iter->first << " (" << item->ID( ) << ") --> ";
674 if( a_printIndices ) std::cout << index << " (" << item->index( ) << ")";
675 std::cout << is_alias << mass << std::endl;
676 }
677}
678
679}
#define LUPI_maybeUnused
#define PoPI_versionChars
Definition PoPI.hpp:94
#define PoPI_particleChars
Definition PoPI.hpp:97
#define PoPI_nameChars
Definition PoPI.hpp:93
#define PoPI_PoPsChars
Definition PoPI.hpp:37
#define PoPI_formatChars
Definition PoPI.hpp:89
#define PoPI_aliasesChars
Definition PoPI.hpp:52
#define PoPI_aliasChars
Definition PoPI.hpp:95
#define PoPI_chemicalElementsChars
Definition PoPI.hpp:41
#define PoPI_metaStableChars
Definition PoPI.hpp:96
#define PoPI_unorthodoxesChars
#define PoPI_baryonsChars
#define PoPI_gaugeBosonsChars
#define PoPI_leptonsChars
#define MsgSize
std::string const value() const
Definition HAPI.hpp:137
virtual Node first_child()=0
std::string name() const
Definition HAPI_Node.cc:136
bool empty() const
Definition HAPI_Node.cc:150
Node first_child() const
Definition HAPI_Node.cc:82
Attribute attribute(const char *a_name) const
Definition HAPI.hpp:176
std::string const & format() const
Definition LUPI.hpp:74
bool isAlias(void) const
Definition PoPI.hpp:658
void setIndex(std::size_t a_index)
Definition PoPI.hpp:654
std::size_t index(void) const
Definition PoPI.hpp:653
Particle_class Class(void) const
Definition PoPI.hpp:656
bool isChemicalElement() const
Definition PoPI.hpp:670
int intid() const
Definition PoPI.hpp:655
bool isNucleus() const
Definition PoPI.hpp:667
bool isNuclide() const
Definition PoPI.hpp:668
bool isIsotope() const
Definition PoPI.hpp:669
virtual bool isParticle() const
Definition PoPI.hpp:657
std::string const & ID(void) const
Definition PoPI.hpp:652
void calculateNuclideGammaBranchStateInfos(PoPI::Database const &a_pops, NuclideGammaBranchStateInfos &a_nuclideGammaBranchStateInfos) const
std::vector< std::string > aliasReferences(std::string const &a_id)
std::string isotopeSymbol(std::string const &a_id) const
bool existsIntid(int a_intid) const
std::size_t addSymbol(SymbolBase *a_item)
LUPI::FormatVersion const & formatVersion(void) const
Definition PoPI.hpp:1157
void toXMLList(std::vector< std::string > &a_XMLList, std::string const &a_indent1) const
void addFile(char const *a_fileName, bool a_warnIfDuplicate)
double massValue(std::string const &a_id, std::string const &a_unit) const
void print(bool a_printIndices)
std::size_t operator[](std::string const &a_id) const
T const & get(std::string const &a_id) const
std::string final(std::string const &a_id, bool a_returnAtMetaStableAlias=false) const
bool exists(std::string const &a_id) const
void addDatabase(std::string const &a_string, bool a_warnIfDuplicate)
bool isMetaStableAlias(std::string const &a_id) const
Definition PoPI.hpp:1196
void calculateNuclideGammaBranchStateInfos2(NuclideGammaBranchStateInfos &a_nuclideGammaBranchStateInfos) const
Particle const & particle(std::string const &a_id) const
Definition PoPI.hpp:1178
void saveAs(std::string const &a_fileName) const
IDBase const & idBase(std::string const &a_id) const
Definition PoPI.hpp:1180
std::string chemicalElementSymbol(std::string const &a_id) const
std::size_t indexFromIntid(int a_intid) const
std::vector< std::string > unresolvedAliasIds() const
int intid(std::string const &a_id) const
bool isAlias(std::string const &a_id) const
Definition PoPI.hpp:1194
std::size_t add(Base *a_item)
void calculateNuclideGammaBranchStateInfos(NuclideGammaBranchStateInfos &a_nuclideGammaBranchStateInfos, Database const *a_pops2, std::vector< std::string > &a_extraGammaBranchStates) const
void calculateDerivedData(NuclideGammaBranchStateInfos &a_nuclideGammaBranchStateInfos)
std::vector< NuclideGammaBranchStateInfo * > & nuclideGammaBranchStateInfos()
Definition PoPI.hpp:625
void calculateNuclideGammaBranchStateInfos(PoPI::Database const &a_pops, NuclideGammaBranchStateInfos &a_nuclideGammaBranchStateInfos, bool a_alwaysAdd=false) const
virtual double massValue(char const *a_unit) const
std::string const & symbol() const
Definition PoPI.hpp:712
xml_parse_result load_string(const char_t *contents, unsigned int options=parse_default)
Definition pugixml.cc:7319
xml_node first_child() const
Definition pugixml.cc:5749
const char * name(G4int ptype)
std::string argumentsToString(char const *a_format,...)
Definition LUPI_misc.cc:305
Definition PoPI.hpp:28
bool supportedFormat(LUPI::FormatVersion const &a_formatVersion)
Definition PoPI_misc.cc:39
void appendXMLEnd(std::vector< std::string > &a_XMLList, std::string const &a_label)
Definition PoPI_misc.cc:53
@ status_ok
Definition pugixml.hpp:982
const char * description() const
Definition pugixml.cc:7037
xml_parse_status status
Definition pugixml.hpp:1010