Line data Source code
1 : //////////////////////////////////////////////////////////////////////////
2 : // Matt.Dobbs@Cern.CH, November 2000, refer to:
3 : // M. Dobbs and J.B. Hansen, "The HepMC C++ Monte Carlo Event Record for
4 : // High Energy Physics", Computer Physics Communications (to be published).
5 : //
6 : // Container for the Weights associated with an event or vertex.
7 : // Basically just an interface to STL vector with extra map-like attributes
8 : //////////////////////////////////////////////////////////////////////////
9 :
10 : #include <iostream>
11 : #include <iomanip>
12 : #include <sstream>
13 : #include <vector>
14 : #include <string>
15 : #include <map>
16 : #include <stdexcept>
17 :
18 : #include "HepMC/WeightContainer.h"
19 :
20 : namespace HepMC {
21 :
22 : WeightContainer::WeightContainer( size_type n, double value )
23 0 : : m_weights(n,value), m_names()
24 0 : { set_default_names(n); }
25 :
26 : WeightContainer::WeightContainer( const std::vector<double>& wgts )
27 0 : : m_weights(wgts), m_names()
28 0 : { set_default_names(size()); }
29 :
30 : void WeightContainer::set_default_names( size_type n )
31 : {
32 : // internal program used by the constructors
33 0 : std::ostringstream name;
34 0 : for ( size_type count = 0; count<n; ++count )
35 : {
36 0 : name.str(std::string());
37 0 : name << count;
38 0 : m_names[name.str()] = count;
39 : }
40 0 : }
41 :
42 : void WeightContainer::push_back( const double& value)
43 : {
44 0 : size_type count = m_weights.size();
45 0 : m_weights.push_back(value);
46 0 : std::ostringstream name;
47 0 : name << count;
48 0 : m_names[name.str()] = count;
49 0 : }
50 :
51 : void WeightContainer::pop_back()
52 : {
53 : // this needs to remove the last entry in the vector
54 : // and ALSO the associated map entry
55 0 : size_type vit = size() - 1;
56 0 : for ( map_iterator m = m_names.begin(); m != m_names.end(); ++m )
57 : {
58 0 : if( m->second == vit ) {
59 0 : m_names.erase(m->first);
60 0 : continue;
61 : }
62 : }
63 0 : m_weights.pop_back();
64 0 : }
65 :
66 : double& WeightContainer::operator[]( const std::string& s )
67 : {
68 0 : const_map_iterator m = m_names.find(s);
69 0 : if( m != m_names.end() ) {
70 0 : return m_weights[m->second];
71 : }
72 : // doesn't exist - have to create it
73 0 : size_type count = m_weights.size();
74 0 : m_weights.push_back(0);
75 0 : m_names[s] = count;
76 0 : return m_weights.back();
77 0 : }
78 :
79 :
80 : const double& WeightContainer::operator[]( const std::string& s ) const
81 : {
82 0 : const_map_iterator m = m_names.find(s);
83 0 : if( m != m_names.end() ) {
84 0 : return m_weights[m->second];
85 : }
86 : // doesn't exist and we cannot create it
87 : // note that std::map does not support this (const) operator
88 : // throw an appropriate error, we choose the error thrown by std::vector
89 0 : throw std::out_of_range("const WeightContainer::operator[] ERROR: string "+s+" not found in WeightContainer" );
90 0 : }
91 :
92 : bool WeightContainer::operator==( const WeightContainer & other ) const
93 : {
94 0 : if( size() != other.size() ) { return false; }
95 0 : if( m_names != other.m_names ) { return false; }
96 0 : if( m_weights != other.m_weights ) { return false; }
97 0 : return true;
98 0 : }
99 :
100 : bool WeightContainer::operator!=( const WeightContainer & other ) const
101 : {
102 0 : return !(*this == other );
103 : }
104 :
105 : bool WeightContainer::has_key( const std::string& s ) const
106 : {
107 : // look up the name in the map
108 0 : return m_names.find(s) != m_names.end();
109 : }
110 :
111 : void WeightContainer::print( std::ostream& ostr ) const
112 : {
113 : // print a name, weight pair
114 0 : for ( const_map_iterator m = map_begin(); m != map_end(); ++m )
115 : {
116 0 : ostr << "(" << m->first << "," << m_weights[m->second] << ") ";
117 : }
118 0 : ostr << std::endl;
119 0 : }
120 :
121 : void WeightContainer::write( std::ostream& ostr ) const
122 : {
123 : size_type count = 0;
124 0 : for ( const_iterator w = begin(); w != end(); ++w )
125 : {
126 0 : std::string name;
127 0 : for ( const_map_iterator m = map_begin(); m != map_end(); ++m )
128 : {
129 0 : if( m->second == count ) name = m->first;
130 : }
131 0 : ostr << "Weight " << std::setw(4) << count
132 0 : << " with name " << std::setw(10) << name
133 0 : << " is " << *w << std::endl;
134 0 : ++count;
135 0 : }
136 0 : }
137 :
138 : } // HepMC
139 :
|