ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/grimes/L1Menu/src/TriggerMenu.cpp
(Generate patch)

Comparing UserCode/grimes/L1Menu/src/TriggerMenu.cpp (file contents):
Revision 1.8 by grimes, Mon Jun 24 16:25:26 2013 UTC vs.
Revision 1.11 by grimes, Wed Jul 24 11:48:55 2013 UTC

# Line 6 | Line 6
6   #include <iostream>
7   #include "l1menu/ITrigger.h"
8   #include "l1menu/tools/tools.h"
9 <
10 < namespace // Use the unnamed namespace for things only used in this file
11 < {
12 <        /// ASCII codes of characters that are considered whitespace (space, tab, carriage return, line feed).
13 <    const char* whitespace="\x20\x09\x0D\x0A";
14 <
15 <    /** @brief Converts the entire string to a float or throws an exception. */
16 <    float convertStringToFloat( const std::string& string )
17 <    {
18 <        float returnValue;
19 <        std::stringstream stringConverter( string );
20 <        stringConverter >> returnValue;
21 <        if( stringConverter.fail() || !stringConverter.eof() ) throw std::runtime_error( "Unable to convert \""+string+"\" to a float" );
22 <        return returnValue;
23 <    }
24 <
25 <    /** @brief Splits a string into individual parts delimited by whitespace. */
26 <    std::vector<std::string> splitByWhitespace( const std::string& stringToSplit )
27 <    {
28 <        std::vector<std::string> returnValue;
29 <
30 <        size_t currentPosition=0;
31 <        size_t nextDelimeter=0;
32 <        do
33 <        {
34 <            // Skip over any leading whitespace
35 <            size_t nextElementStart=stringToSplit.find_first_not_of( whitespace, currentPosition );
36 <            if( nextElementStart!=std::string::npos ) currentPosition=nextElementStart;
37 <
38 <            // Find the next whitespace and subtract everything up to that point
39 <            nextDelimeter=stringToSplit.find_first_of( whitespace, currentPosition );
40 <            std::string element=stringToSplit.substr( currentPosition, nextDelimeter-currentPosition );
41 <            returnValue.push_back(element);
42 <
43 <            // skip over any trailing whitespace
44 <            nextElementStart=stringToSplit.find_first_not_of( whitespace, nextDelimeter );
45 <            if( nextElementStart!=std::string::npos ) currentPosition=nextElementStart;
46 <            else nextDelimeter=std::string::npos;
47 <
48 <        } while( nextDelimeter!=std::string::npos );
49 <
50 <        return returnValue;
51 <    }
52 <
53 < } // end of the unnamed namespace
54 <
9 > #include "l1menu/tools/stringManipulation.h"
10  
11   l1menu::TriggerMenu::TriggerMenu() : triggerTable_( l1menu::TriggerTable::instance() )
12   {
# Line 139 | Line 94 | l1menu::ITrigger& l1menu::TriggerMenu::a
94          return *triggers_.back();
95   }
96  
97 + l1menu::ITrigger& l1menu::TriggerMenu::addTrigger( const l1menu::ITrigger& triggerToCopy )
98 + {
99 +        std::unique_ptr<l1menu::ITrigger> pNewTrigger=triggerTable_.copyTrigger( triggerToCopy );
100 +        if( pNewTrigger.get()==NULL ) throw std::range_error( "Trigger requested that does not exist" );
101 +
102 +        triggers_.push_back( std::move(pNewTrigger) );
103 +
104 +        // Make sure triggerResults_ is always the same size as triggers_
105 +        triggerResults_.resize( triggers_.size() );
106 +        return *triggers_.back();
107 + }
108 +
109   size_t l1menu::TriggerMenu::numberOfTriggers() const
110   {
111          return triggers_.size();
# Line 165 | Line 132 | std::unique_ptr<l1menu::ITrigger> l1menu
132          return triggerTable_.copyTrigger(*triggers_[position]);
133   }
134  
135 < bool l1menu::TriggerMenu::apply( const l1menu::IEvent& event ) const
135 > bool l1menu::TriggerMenu::apply( const l1menu::L1TriggerDPGEvent& event ) const
136   {
137          bool atLeastOneTriggerHasFired=false;
138  
# Line 200 | Line 167 | void l1menu::TriggerMenu::loadMenuInOldF
167                          file.getline( buffer, bufferSize );
168  
169                          // split the line by whitespace into columns
170 <                        std::vector<std::string> tableColumns=::splitByWhitespace( buffer );
170 >                        std::vector<std::string> tableColumns=l1menu::tools::splitByWhitespace( buffer );
171  
172                          if( tableColumns.size()==1 && tableColumns[0].empty() ) continue; // Allow blank lines without giving a warning
173                          if( tableColumns.size()!=12 ) throw std::runtime_error( "The line does not have the correct number of columns" );
174  
175 <                        float prescale=::convertStringToFloat( tableColumns[2] );
209 <                        if( prescale!=0 )
210 <                        {
211 <                                std::string triggerName=tableColumns[0];
175 >                        addTriggerFromOldFormat( tableColumns );
176  
213                                try
214                                {
215                                        //std::cout << "Added trigger \"" << tableColumns[0] << "\"" << std::endl;
216                                        l1menu::ITrigger& newTrigger=addTrigger( triggerName ); // Try and create a trigger with the name supplied
217
218                                        // Different triggers will have different numbers of thresholds, and even different names. E.g. Single triggers
219                                        // will have "threshold1" whereas a cross trigger will have "leg1threshold1", "leg2threshold1" etcetera. This
220                                        // utility function will get the threshold names in the correct order.
221                                        const auto& thresholdNames=l1menu::tools::getThresholdNames(newTrigger);
222                                        if( thresholdNames.size()>1 ) newTrigger.parameter(thresholdNames[0])=::convertStringToFloat( tableColumns[3] );
223                                        if( thresholdNames.size()>2 ) newTrigger.parameter(thresholdNames[1])=::convertStringToFloat( tableColumns[4] );
224                                        if( thresholdNames.size()>3 ) newTrigger.parameter(thresholdNames[2])=::convertStringToFloat( tableColumns[5] );
225                                        if( thresholdNames.size()>4 ) newTrigger.parameter(thresholdNames[3])=::convertStringToFloat( tableColumns[6] );
226
227                                        float etaOrRegionCut=::convertStringToFloat( tableColumns[7] );
228                                        // For most triggers, I can just try and set both the etaCut and regionCut parameters
229                                        // with this value. If it doesn't have either of the parameters just catch the exception
230                                        // and nothing will happen. Some cross triggers however have both, and need to set them
231                                        // both from this value which requires a conversion. Most cross triggers expect this
232                                        // value to be the regionCut, except for L1_SingleMu_CJet which expects it as the etaCut.
233                                        if( triggerName=="L1_SingleMu_CJet" )
234                                        {
235                                                newTrigger.parameter("leg1etaCut")=etaOrRegionCut;
236                                                newTrigger.parameter("leg2regionCut")=l1menu::tools::convertEtaCutToRegionCut( etaOrRegionCut );
237                                        }
238                                        else if( triggerName=="L1_isoMu_EG" )
239                                        {
240                                                newTrigger.parameter("leg1etaCut")=l1menu::tools::convertRegionCutToEtaCut( etaOrRegionCut );
241                                                newTrigger.parameter("leg2regionCut")=etaOrRegionCut;
242                                        }
243                                        else if( triggerName=="L1_isoEG_Mu" )
244                                        {
245                                                newTrigger.parameter("leg1regionCut")=etaOrRegionCut;
246                                                newTrigger.parameter("leg2etaCut")=l1menu::tools::convertRegionCutToEtaCut( etaOrRegionCut );
247                                        }
248                                        else if( triggerName=="L1_isoMu_Tau" )
249                                        {
250                                                newTrigger.parameter("leg1etaCut")=l1menu::tools::convertRegionCutToEtaCut( etaOrRegionCut );
251                                                newTrigger.parameter("leg2regionCut")=etaOrRegionCut;
252                                        }
253                                        else
254                                        {
255                                                // Any remaining triggers should only have one of these parameters and won't
256                                                // need conversion. I'll just try and set them both, not a problem if one fails.
257                                                // The cross triggers will have e.g. "leg1" prefixed to the parameter name so I'll
258                                                // also try for those.
259                                                try{ newTrigger.parameter("etaCut")=etaOrRegionCut; }
260                                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
261
262                                                try{ newTrigger.parameter("regionCut")=etaOrRegionCut; }
263                                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
264
265                                                try{ newTrigger.parameter("leg1etaCut")=etaOrRegionCut; }
266                                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
267
268                                                try{ newTrigger.parameter("leg1regionCut")=etaOrRegionCut; }
269                                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
270
271                                                try{ newTrigger.parameter("leg2etaCut")=etaOrRegionCut; }
272                                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
273
274                                                try{ newTrigger.parameter("leg2regionCut")=etaOrRegionCut; }
275                                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
276                                        }
277
278                                        // The trigger may or may not have a muon quality cut. I also don't know if its name
279                                        // is prefixed with e.g. "leg1". I'll try setting all combinations, but wrap individually
280                                        // in a try block so that it doesn't matter if it fails.
281                                        try{ newTrigger.parameter("muonQuality")=::convertStringToFloat( tableColumns[8] ); }
282                                        catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
283
284                                        try{ newTrigger.parameter("leg1muonQuality")=::convertStringToFloat( tableColumns[8] ); }
285                                        catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
286
287                                        try{ newTrigger.parameter("leg2muonQuality")=::convertStringToFloat( tableColumns[8] ); }
288                                        catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
289
290                                } // end of try block
291                                catch( std::exception& error )
292                                {
293                                        std::cerr << "Unable to add trigger \"" << tableColumns[0] << "\" because: " << error.what() << std::endl;
294                                }
295                        } // end of "if( prescale!=0 )"
177                  } // end of try block
178                  catch( std::runtime_error& exception )
179                  {
# Line 300 | Line 181 | void l1menu::TriggerMenu::loadMenuInOldF
181                  }
182          }
183   }
184 +
185 + bool l1menu::TriggerMenu::addTriggerFromOldFormat( const std::vector<std::string>& columns )
186 + {
187 +        bool successful=false;
188 +
189 +        if( columns.size()<9 ) throw std::runtime_error( "There are not enough columns" );
190 +
191 +        float prescale=l1menu::tools::convertStringToFloat( columns[2] );
192 +        if( prescale!=0 )
193 +        {
194 +                std::string triggerName=columns[0];
195 +
196 +                try
197 +                {
198 +                        //std::cout << "Added trigger \"" << columns[0] << "\"" << std::endl;
199 +                        l1menu::ITrigger& newTrigger=addTrigger( triggerName ); // Try and create a trigger with the name supplied
200 +                        successful=true;
201 +
202 +                        // Different triggers will have different numbers of thresholds, and even different names. E.g. Single triggers
203 +                        // will have "threshold1" whereas a cross trigger will have "leg1threshold1", "leg2threshold1" etcetera. This
204 +                        // utility function will get the threshold names in the correct order.
205 +                        const auto& thresholdNames=l1menu::tools::getThresholdNames(newTrigger);
206 +                        if( thresholdNames.size()>=1 ) newTrigger.parameter(thresholdNames[0])=l1menu::tools::convertStringToFloat( columns[3] );
207 +                        if( thresholdNames.size()>=2 ) newTrigger.parameter(thresholdNames[1])=l1menu::tools::convertStringToFloat( columns[4] );
208 +                        if( thresholdNames.size()>=3 ) newTrigger.parameter(thresholdNames[2])=l1menu::tools::convertStringToFloat( columns[5] );
209 +                        if( thresholdNames.size()>=4 ) newTrigger.parameter(thresholdNames[3])=l1menu::tools::convertStringToFloat( columns[6] );
210 +
211 +                        float etaOrRegionCut=l1menu::tools::convertStringToFloat( columns[7] );
212 +                        // For most triggers, I can just try and set both the etaCut and regionCut parameters
213 +                        // with this value. If it doesn't have either of the parameters just catch the exception
214 +                        // and nothing will happen. Some cross triggers however have both, and need to set them
215 +                        // both from this value which requires a conversion. Most cross triggers expect this
216 +                        // value to be the regionCut, except for L1_SingleMu_CJet which expects it as the etaCut.
217 +                        if( triggerName=="L1_SingleMu_CJet" )
218 +                        {
219 +                                newTrigger.parameter("leg1etaCut")=etaOrRegionCut;
220 +                                newTrigger.parameter("leg2regionCut")=l1menu::tools::convertEtaCutToRegionCut( etaOrRegionCut );
221 +                        }
222 +                        else if( triggerName=="L1_isoMu_EG" )
223 +                        {
224 +                                newTrigger.parameter("leg1etaCut")=l1menu::tools::convertRegionCutToEtaCut( etaOrRegionCut );
225 +                                newTrigger.parameter("leg2regionCut")=etaOrRegionCut;
226 +                        }
227 +                        else if( triggerName=="L1_isoEG_Mu" )
228 +                        {
229 +                                newTrigger.parameter("leg1regionCut")=etaOrRegionCut;
230 +                                newTrigger.parameter("leg2etaCut")=l1menu::tools::convertRegionCutToEtaCut( etaOrRegionCut );
231 +                        }
232 +                        else if( triggerName=="L1_isoMu_Tau" )
233 +                        {
234 +                                newTrigger.parameter("leg1etaCut")=l1menu::tools::convertRegionCutToEtaCut( etaOrRegionCut );
235 +                                newTrigger.parameter("leg2regionCut")=etaOrRegionCut;
236 +                        }
237 +                        else
238 +                        {
239 +                                // Any remaining triggers should only have one of these parameters and won't
240 +                                // need conversion. I'll just try and set them both, not a problem if one fails.
241 +                                // The cross triggers will have e.g. "leg1" prefixed to the parameter name so I'll
242 +                                // also try for those.
243 +                                try{ newTrigger.parameter("etaCut")=etaOrRegionCut; }
244 +                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
245 +
246 +                                try{ newTrigger.parameter("regionCut")=etaOrRegionCut; }
247 +                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
248 +
249 +                                try{ newTrigger.parameter("leg1etaCut")=etaOrRegionCut; }
250 +                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
251 +
252 +                                try{ newTrigger.parameter("leg1regionCut")=etaOrRegionCut; }
253 +                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
254 +
255 +                                try{ newTrigger.parameter("leg2etaCut")=etaOrRegionCut; }
256 +                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
257 +
258 +                                try{ newTrigger.parameter("leg2regionCut")=etaOrRegionCut; }
259 +                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
260 +                        }
261 +
262 +                        // The trigger may or may not have a muon quality cut. I also don't know if its name
263 +                        // is prefixed with e.g. "leg1". I'll try setting all combinations, but wrap individually
264 +                        // in a try block so that it doesn't matter if it fails.
265 +                        try{ newTrigger.parameter("muonQuality")=l1menu::tools::convertStringToFloat( columns[8] ); }
266 +                        catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
267 +
268 +                        try{ newTrigger.parameter("leg1muonQuality")=l1menu::tools::convertStringToFloat( columns[8] ); }
269 +                        catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
270 +
271 +                        try{ newTrigger.parameter("leg2muonQuality")=l1menu::tools::convertStringToFloat( columns[8] ); }
272 +                        catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
273 +
274 +                } // end of try block
275 +                catch( std::exception& error )
276 +                {
277 +                        std::cerr << "Unable to add trigger \"" << columns[0] << "\" because: " << error.what() << std::endl;
278 +                }
279 +        } // end of "if( prescale!=0 )"
280 +
281 +        return successful;
282 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines