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