ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/grimes/L1Menu/src/TriggerTable.cpp
Revision: 1.3
Committed: Tue Jun 4 08:17:37 2013 UTC (11 years, 11 months ago) by grimes
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +0 -4 lines
Log Message:
Multiple changes. Implemented all required triggers, removed the ones not needed and changed some names.

File Contents

# Content
1 #include "l1menu/TriggerTable.h"
2
3 #include "l1menu/ITrigger.h"
4
5 #include <sstream>
6 #include <stdexcept>
7
8 //
9 // Declare the pimple class
10 //
11 namespace l1menu
12 {
13 class TriggerTablePrivateMembers
14 {
15 public:
16 struct TriggerRegistryEntry
17 {
18 l1menu::TriggerTable::TriggerDetails details;
19 std::unique_ptr<l1menu::ITrigger> (*creationFunctionPointer)();
20 };
21 struct SuggestedBinning
22 {
23 unsigned int numberOfBins;
24 float lowerEdge;
25 float upperEdge;
26 };
27 std::vector<TriggerRegistryEntry> registeredTriggers;
28 std::map<std::string,std::map<std::string,SuggestedBinning> > suggestedBinning_;
29 const SuggestedBinning& getSuggestedBinning( const std::string& triggerName, const std::string& parameterName );
30 };
31
32 } // end of namespace l1menu
33
34 const l1menu::TriggerTablePrivateMembers::SuggestedBinning& l1menu::TriggerTablePrivateMembers::getSuggestedBinning( const std::string& triggerName, const std::string& parameterName )
35 {
36 const auto& iTriggerFindResult=suggestedBinning_.find(triggerName);
37 if( iTriggerFindResult==suggestedBinning_.end() )
38 {
39 throw std::runtime_error( "Trigger \""+triggerName+"\" has no suggested binning registered." );
40 }
41
42 const auto& iParameterFindResult=iTriggerFindResult->second.find(parameterName);
43 if( iParameterFindResult==iTriggerFindResult->second.end() )
44 {
45 throw std::runtime_error( "Trigger \""+triggerName+"\" has no suggested binning registered for parameter \""+parameterName+"\"." );
46 }
47
48 return iParameterFindResult->second;
49 }
50
51 l1menu::TriggerTable& l1menu::TriggerTable::instance()
52 {
53 static TriggerTable onlyInstance;
54 return onlyInstance;
55 }
56
57 l1menu::TriggerTable::TriggerTable() : pImple_( new l1menu::TriggerTablePrivateMembers )
58 {
59 // No operation. Only declared so that it can be declared private.
60 }
61
62 l1menu::TriggerTable::~TriggerTable()
63 {
64 // No operation. Only declared so that it can be declared private.
65 }
66
67 bool l1menu::TriggerTable::TriggerDetails::operator==( const l1menu::TriggerTable::TriggerDetails& otherTriggerDetails ) const
68 {
69 return name==otherTriggerDetails.name && version==otherTriggerDetails.version;
70 }
71
72 std::unique_ptr<l1menu::ITrigger> l1menu::TriggerTable::getTrigger( const std::string& name ) const
73 {
74 // std::cout << "Looking for latest version of " << name << std::endl;
75
76 std::unique_ptr<l1menu::ITrigger> returnValue;
77 unsigned int highestVersionNumber=0; // The highest version of the trigger encountered in the list so far
78
79 for( std::vector<TriggerTablePrivateMembers::TriggerRegistryEntry>::const_iterator iRegistryEntry=pImple_->registeredTriggers.begin(); iRegistryEntry!=pImple_->registeredTriggers.end(); ++iRegistryEntry )
80 {
81 if( iRegistryEntry->details.name==name && iRegistryEntry->details.version>=highestVersionNumber )
82 {
83 returnValue=(*iRegistryEntry->creationFunctionPointer)();
84 highestVersionNumber=iRegistryEntry->details.version;
85 }
86 }
87
88 return returnValue;
89 }
90
91 std::unique_ptr<l1menu::ITrigger> l1menu::TriggerTable::getTrigger( const std::string& name, unsigned int version ) const
92 {
93 TriggerDetails requestedTriggerDetails{ name, version };
94
95 // Delegate to the other overload
96 return getTrigger( requestedTriggerDetails );
97 }
98
99 std::unique_ptr<l1menu::ITrigger> l1menu::TriggerTable::getTrigger( const TriggerDetails& details ) const
100 {
101 // std::cout << "Looking for version " << details.version << " of " << details.name << std::endl;
102
103 for( std::vector<TriggerTablePrivateMembers::TriggerRegistryEntry>::const_iterator iRegistryEntry=pImple_->registeredTriggers.begin(); iRegistryEntry!=pImple_->registeredTriggers.end(); ++iRegistryEntry )
104 {
105 if( iRegistryEntry->details==details )
106 {
107 return (*iRegistryEntry->creationFunctionPointer)();
108 }
109 }
110
111 // If program flow has reached this point then there are no triggers registered that
112 // match the criteria. Return an empty pointer.
113 return std::unique_ptr<l1menu::ITrigger>();
114 }
115
116 std::unique_ptr<l1menu::ITrigger> l1menu::TriggerTable::copyTrigger( const l1menu::ITrigger& triggerToCopy ) const
117 {
118 // First create a trigger with the matching name and version
119 std::unique_ptr<l1menu::ITrigger> newTrigger=getTrigger( triggerToCopy.name(), triggerToCopy.version() );
120
121 if( newTrigger.get()==NULL ) throw std::runtime_error( "Unable to copy trigger "+triggerToCopy.name() );
122
123 //
124 // Now copy all of the parameters over.
125 //
126 // Get the parameter names
127 std::vector<std::string> parameterNames=triggerToCopy.parameterNames();
128 // Then run through and copy the value of each one
129 for( std::vector<std::string>::const_iterator iName=parameterNames.begin(); iName!=parameterNames.end(); ++iName )
130 {
131 newTrigger->parameter(*iName)=triggerToCopy.parameter(*iName);
132 }
133
134 return newTrigger;
135 }
136
137 std::vector<l1menu::TriggerTable::TriggerDetails> l1menu::TriggerTable::listTriggers() const
138 {
139 std::vector<TriggerDetails> returnValue;
140
141 // Copy the relevant parts from the registered triggers into the return value
142 for( std::vector<TriggerTablePrivateMembers::TriggerRegistryEntry>::const_iterator iRegistryEntry=pImple_->registeredTriggers.begin(); iRegistryEntry!=pImple_->registeredTriggers.end(); ++iRegistryEntry )
143 {
144 returnValue.push_back( iRegistryEntry->details );
145 }
146
147 return returnValue;
148 }
149
150 void l1menu::TriggerTable::registerTrigger( const std::string& name, unsigned int version, std::unique_ptr<l1menu::ITrigger> (*creationFunctionPointer)() )
151 {
152 TriggerDetails newTriggerDetails{ name, version };
153
154 // First make sure there is not a trigger with the same name and version already registered
155 for( std::vector<TriggerTablePrivateMembers::TriggerRegistryEntry>::const_iterator iRegistryEntry=pImple_->registeredTriggers.begin(); iRegistryEntry!=pImple_->registeredTriggers.end(); ++iRegistryEntry )
156 {
157 if( iRegistryEntry->details==newTriggerDetails )
158 {
159 std::stringstream errorMessage;
160 errorMessage << "A trigger called \"" << newTriggerDetails.name << "\" with version " << newTriggerDetails.version << " has already been registered in the trigger table.";
161 throw std::logic_error( errorMessage.str() );
162 }
163 }
164
165 // If program flow has reached this point then there are no triggers with the same name
166 // and version already registered, so it's okay to add the trigger as requested.
167 pImple_->registeredTriggers.push_back( TriggerTablePrivateMembers::TriggerRegistryEntry{newTriggerDetails,creationFunctionPointer} );
168 }
169
170 void l1menu::TriggerTable::registerSuggestedBinning( const std::string& triggerName, const std::string& parameterName, unsigned int numberOfBins, float lowerEdge, float upperEdge )
171 {
172 pImple_->suggestedBinning_[triggerName][parameterName]={ numberOfBins, lowerEdge, upperEdge };
173 }
174
175 unsigned int l1menu::TriggerTable::getSuggestedNumberOfBins( const std::string& triggerName, const std::string& parameterName ) const
176 {
177 try
178 {
179 return pImple_->getSuggestedBinning( triggerName, parameterName ).numberOfBins;
180 }
181 catch( std::runtime_error& error )
182 {
183 throw std::runtime_error( std::string("TriggerTable::getSuggestedNumberOfBins - ")+error.what() );
184 }
185 }
186
187 float l1menu::TriggerTable::getSuggestedLowerEdge( const std::string& triggerName, const std::string& parameterName ) const
188 {
189 try
190 {
191 return pImple_->getSuggestedBinning( triggerName, parameterName ).lowerEdge;
192 }
193 catch( std::runtime_error& error )
194 {
195 throw std::runtime_error( std::string("TriggerTable::getSuggestedLowerEdge - ")+error.what() );
196 }
197 }
198
199 float l1menu::TriggerTable::getSuggestedUpperEdge( const std::string& triggerName, const std::string& parameterName ) const
200 {
201 try
202 {
203 return pImple_->getSuggestedBinning( triggerName, parameterName ).upperEdge;
204 }
205 catch( std::runtime_error& error )
206 {
207 throw std::runtime_error( std::string("TriggerTable::getSuggestedUpperEdge - ")+error.what() );
208 }
209 }