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.5 by grimes, Tue Jun 18 10:18:23 2013 UTC vs.
Revision 1.11 by grimes, Wed Jul 24 11:48:55 2013 UTC

# Line 5 | Line 5
5   #include <sstream>
6   #include <iostream>
7   #include "l1menu/ITrigger.h"
8 <
9 < namespace // Use the unnamed namespace for things only used in this file
10 < {
11 <        /// ASCII codes of characters that are considered whitespace (space, tab, carriage return, line feed).
12 <    const char* whitespace="\x20\x09\x0D\x0A";
13 <
14 <    /** @brief Converts the entire string to a float or throws an exception. */
15 <    float convertStringToFloat( const std::string& string )
16 <    {
17 <        float returnValue;
18 <        std::stringstream stringConverter( string );
19 <        stringConverter >> returnValue;
20 <        if( stringConverter.fail() || !stringConverter.eof() ) throw std::runtime_error( "Unable to convert \""+string+"\" to a float" );
21 <        return returnValue;
22 <    }
23 <
24 <    /** @brief Splits a string into individual parts delimited by whitespace. */
25 <    std::vector<std::string> splitByWhitespace( const std::string& stringToSplit )
26 <    {
27 <        std::vector<std::string> returnValue;
28 <
29 <        size_t currentPosition=0;
30 <        size_t nextDelimeter=0;
31 <        do
32 <        {
33 <            // Skip over any leading whitespace
34 <            size_t nextElementStart=stringToSplit.find_first_not_of( whitespace, currentPosition );
35 <            if( nextElementStart!=std::string::npos ) currentPosition=nextElementStart;
36 <
37 <            // Find the next whitespace and subtract everything up to that point
38 <            nextDelimeter=stringToSplit.find_first_of( whitespace, currentPosition );
39 <            std::string element=stringToSplit.substr( currentPosition, nextDelimeter-currentPosition );
40 <            returnValue.push_back(element);
41 <
42 <            // skip over any trailing whitespace
43 <            nextElementStart=stringToSplit.find_first_not_of( whitespace, nextDelimeter );
44 <            if( nextElementStart!=std::string::npos ) currentPosition=nextElementStart;
45 <            else nextDelimeter=std::string::npos;
46 <
47 <        } while( nextDelimeter!=std::string::npos );
48 <
49 <        return returnValue;
50 <    }
51 <
52 <    /** @brief Converts a value in absolute eta to the calorimeter region. */
53 <    float convertEtaCutToRegionCut( float etaCut )
54 <    {
55 <        return 0;
56 <    }
57 <
58 <    /** @brief Converts a value in calorimeter region to absolute eta. */
59 <    float convertRegionCutToEtaCut( float regionCut )
60 <    {
61 <        return 0;
62 <    }
63 < } // end of the unnamed namespace
64 <
8 > #include "l1menu/tools/tools.h"
9 > #include "l1menu/tools/stringManipulation.h"
10  
11   l1menu::TriggerMenu::TriggerMenu() : triggerTable_( l1menu::TriggerTable::instance() )
12   {
# Line 149 | 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 175 | 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 210 | 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] );
219 <                        if( prescale!=0 )
220 <                        {
221 <                                std::string triggerName=tableColumns[0];
175 >                        addTriggerFromOldFormat( tableColumns );
176  
223                                try
224                                {
225                                        //std::cout << "Added trigger \"" << tableColumns[0] << "\"" << std::endl;
226                                        l1menu::ITrigger& newTrigger=addTrigger( triggerName ); // Try and create a trigger with the name supplied
227
228                                        // Try and set all of the relevant parameters. I know not all triggers have these parameters
229                                        // so wrap in individual try/catch blocks.
230                                        try{ newTrigger.parameter("threshold1")=::convertStringToFloat( tableColumns[3] ); }
231                                        catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
232
233                                        try{ newTrigger.parameter("threshold2")=::convertStringToFloat( tableColumns[4] ); }
234                                        catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
235
236                                        try{ newTrigger.parameter("threshold3")=::convertStringToFloat( tableColumns[5] ); }
237                                        catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
238
239                                        try{ newTrigger.parameter("threshold4")=::convertStringToFloat( tableColumns[6] ); }
240                                        catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
241
242                                        float etaOrRegionCut=::convertStringToFloat( tableColumns[7] );
243                                        // For most triggers, I can just try and set both the etaCut and regionCut parameters
244                                        // with this value. If it doesn't have either of the parameters just catch the exception
245                                        // and nothing will happen. Some cross triggers however have both, and need to set them
246                                        // both from this value which requires a conversion. Most cross triggers expect this
247                                        // value to be the regionCut, except for L1_SingleMu_CJet which expects it as the etaCut.
248                                        if( triggerName=="L1_SingleMu_CJet" )
249                                        {
250                                                newTrigger.parameter("etaCut")=etaOrRegionCut;
251                                                newTrigger.parameter("regionCut")=convertEtaCutToRegionCut( etaOrRegionCut );
252                                        }
253                                        else if( triggerName=="L1_SingleIsoEG_CJet" )
254                                        {
255                                                newTrigger.parameter("etaCut")=etaOrRegionCut;
256                                                newTrigger.parameter("regionCut")=convertEtaCutToRegionCut( etaOrRegionCut );
257                                        }
258                                        else
259                                        {
260                                                // Any remaining triggers should only have one of these parameters and won't
261                                                // need conversion. I'll just try and set them both, not a problem if one fails.
262                                                try{ newTrigger.parameter("etaCut")=etaOrRegionCut; }
263                                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
264
265                                                try{ newTrigger.parameter("regionCut")=etaOrRegionCut; }
266                                                catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
267                                        }
268
269                                        try{ newTrigger.parameter("muonQuality")=::convertStringToFloat( tableColumns[8] ); }
270                                        catch( std::exception& error ) { } // Do nothing, just try and convert the other parameters
271
272                                } // end of "if able to add trigger"
273                                catch( std::exception& error )
274                                {
275                                        std::cerr << "Unable to add trigger \"" << tableColumns[0] << "\" because: " << error.what() << std::endl;
276                                }
277                        } // end of "if( prescale!=0 )"
177                  } // end of try block
178                  catch( std::runtime_error& exception )
179                  {
# Line 282 | 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