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

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