ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/grimes/L1Menu/src/TriggerTable.cpp
Revision: 1.2
Committed: Tue May 28 23:14:04 2013 UTC (11 years, 11 months ago) by grimes
Branch: MAIN
Changes since 1.1: +114 -15 lines
Log Message:
Numerous changes

File Contents

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