ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/grimes/L1Menu/src/tools.cpp
Revision: 1.5
Committed: Mon Jun 24 14:47:40 2013 UTC (11 years, 10 months ago) by grimes
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +0 -0 lines
State: FILE REMOVED
Log Message:
Changes to the way trigger rates are returned

File Contents

# User Rev Content
1 grimes 1.1 #include "l1menu/tools.h"
2    
3     #include <sstream>
4     #include <exception>
5     #include <map>
6     #include <stdexcept>
7 grimes 1.2 #include <algorithm>
8 grimes 1.1 #include "l1menu/ITrigger.h"
9     #include "l1menu/IEvent.h"
10     #include "l1menu/TriggerTable.h"
11    
12     std::vector<std::string> l1menu::getThresholdNames( const l1menu::ITrigger& trigger )
13     {
14     std::vector<std::string> returnValue;
15    
16     //
17     // I don't know how many thresholds there are, so I'll try and get every possible one and catch
18     // the exception when I eventually hit a threshold that doesn't exist.
19     //
20    
21     std::stringstream stringConverter;
22     // I plan in the future to implement cross triggers with "leg1threshold1", "leg2threshold1" etcetera,
23     // so I'll loop over those possible prefixes.
24     for( size_t legNumber=0; true; ++legNumber ) // Loop continuously until the exception handler calls "break"
25     {
26     size_t thresholdNumber;
27     try
28     {
29     // Loop over all possible numbers of thresholds
30     for( thresholdNumber=1; true; ++thresholdNumber ) // Loop continuously until I hit an exception
31     {
32     stringConverter.str("");
33     if( legNumber!=0 ) stringConverter << "leg" << legNumber; // For triggers with only one leg I don't want to prefix anything.
34    
35     stringConverter << "threshold" << thresholdNumber;
36 grimes 1.3
37 grimes 1.1 trigger.parameter(stringConverter.str());
38     // If the threshold doesn't exist the statement above will throw an exception, so
39     // I've reached this far then the threshold name must exist.
40     returnValue.push_back( stringConverter.str() );
41     }
42    
43     }
44     catch( std::exception& error )
45     {
46     // If this exception is from the first threshold tried then the prefix (e.g. "leg1") does not
47     // exist, so I know I've finished. If it isn't from the first threshold then there could be
48     // other prefixes (e.g. "leg2") that have thresholds that can be modified, in which case I
49     // need to continue.
50 grimes 1.3 if( thresholdNumber==1 && legNumber!=0 ) break;
51 grimes 1.1 }
52     }
53    
54     return returnValue;
55     }
56    
57 grimes 1.2 std::vector<std::string> l1menu::getNonThresholdParameterNames( const l1menu::ITrigger& trigger )
58     {
59     std::vector<std::string> returnValue;
60    
61     // It'll be easier to get the threshold names and then copy
62     // everything that's not in there to the return value.
63     std::vector<std::string> allParameterNames=trigger.parameterNames();
64     std::vector<std::string> thresholdNames=getThresholdNames(trigger);
65    
66     for( const auto& parameterName : allParameterNames )
67     {
68     const auto& iFindResult=std::find( thresholdNames.begin(), thresholdNames.end(), parameterName );
69     // If the current parameter name isn't one of the thresholds add
70     // it the vector which I'm going to return.
71     if( iFindResult==thresholdNames.end() ) returnValue.push_back(parameterName);
72     }
73    
74     return returnValue;
75     }
76    
77 grimes 1.1 void l1menu::setTriggerThresholdsAsTightAsPossible( const l1menu::IEvent& event, l1menu::ITrigger& trigger, float tolerance )
78     {
79     std::vector<std::string> thresholdNames=l1menu::getThresholdNames( trigger );
80     std::map<std::string,float> tightestPossibleThresholds;
81    
82     // First set all of the thresholds to zero
83     for( const auto& thresholdName : thresholdNames ) trigger.parameter(thresholdName)=0;
84    
85     // Now run through each threshold at a time and figure out how low it can be and still
86     // pass the event.
87     for( const auto& thresholdName : thresholdNames )
88     {
89     // Note that this is a reference, so when this is changed the trigger is modified
90     float& threshold=trigger.parameter(thresholdName);
91    
92     float lowThreshold=0;
93     float highThreshold=500;
94     // See if an indication of the range of the trigger has been set
95     try // These calls will throw an exception if no suggestion has been set
96     {
97     lowThreshold=l1menu::TriggerTable::instance().getSuggestedLowerEdge( trigger.name(), thresholdName );
98     highThreshold=l1menu::TriggerTable::instance().getSuggestedUpperEdge( trigger.name(), thresholdName );
99 grimes 1.4 highThreshold*=5; // Make sure the high threshold is very high, to catch all tails
100 grimes 1.1 }
101     catch( std::exception& error ) { /* No indication set. Do nothing and just use the defaults I set previously. */ }
102    
103     threshold=lowThreshold;
104     bool lowTest=trigger.apply( event );
105    
106     threshold=highThreshold;
107     bool highTest=trigger.apply( event );
108    
109     if( lowTest==highTest ) std::runtime_error( "l1menu::setTriggerThresholdsAsTightAsPossible() - couldn't find a set of thresholds to pass the given event.");
110    
111     // Try and find the turn on point by bisection
112     while( highThreshold-lowThreshold > tolerance )
113     {
114     threshold=(highThreshold+lowThreshold)/2;
115     bool midTest=trigger.apply(event);
116    
117     if( lowTest==midTest && highTest!=midTest ) lowThreshold=threshold;
118     else if( highTest==midTest ) highThreshold=threshold;
119     else throw std::runtime_error( std::string("Something fucked up while testing ")+trigger.name() );
120     }
121    
122     // Record what this value was for the parameter named
123     tightestPossibleThresholds[thresholdName]=highThreshold;
124     // Then set back to zero ready to test the other thresholds
125     threshold=0;
126     }
127    
128     //
129     // Now that I've figured out what all of the thresholds need to be, run
130     // through and set the trigger up with these thresholds.
131     //
132     for( const auto& parameterValuePair : tightestPossibleThresholds )
133     {
134     trigger.parameter(parameterValuePair.first)=parameterValuePair.second;
135     }
136     }