ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/grimes/L1Menu/src/TriggerRatePlot.cpp
Revision: 1.7
Committed: Tue Jul 2 23:30:37 2013 UTC (11 years, 10 months ago) by grimes
Branch: MAIN
Changes since 1.6: +15 -32 lines
Log Message:
Various changes to make interface conformance better, and dropping old unrequired methods

File Contents

# Content
1 #include "l1menu/TriggerRatePlot.h"
2
3 #include "l1menu/ITrigger.h"
4 #include "l1menu/ICachedTrigger.h"
5 #include "l1menu/L1TriggerDPGEvent.h"
6 #include "l1menu/IEvent.h"
7 #include "l1menu/TriggerTable.h"
8 #include "l1menu/ReducedMenuSample.h"
9 #include "l1menu/ReducedEvent.h"
10 #include <TH1F.h>
11 #include <sstream>
12 #include <algorithm>
13
14 #include <iostream>
15
16 l1menu::TriggerRatePlot::TriggerRatePlot( const l1menu::ITrigger& trigger, std::unique_ptr<TH1> pHistogram, const std::string& versusParameter, const std::vector<std::string> scaledParameters )
17 : pHistogram_( std::move(pHistogram) ), versusParameter_(versusParameter), histogramOwnedByMe_(true)
18 {
19 // Take a copy of the trigger
20 l1menu::TriggerTable& table=l1menu::TriggerTable::instance();
21 pTrigger_=table.copyTrigger( trigger );
22
23 // Make sure the versusParameter_ supplied is valid. If it's not then this call will
24 // throw an exception. Take a pointer to the parameter so I don't need to keep performing
25 // expensive string comparisons.
26 pParameter_=&pTrigger_->parameter(versusParameter_);
27
28 // If any parameters have been requested to be scaled along with the versusParameter, figure
29 // out what the scaling should be and take a note of pointers.
30 for( const auto& parameterToScale : scaledParameters )
31 {
32 if( parameterToScale!=versusParameter_ )
33 {
34 otherParameterScalings_.push_back( std::make_pair( &pTrigger_->parameter(parameterToScale), pTrigger_->parameter(parameterToScale)/(*pParameter_) ) );
35 }
36 }
37 // I want to make a note of the other parameters set for the trigger. As far as I know TH1
38 // has no way of adding annotations so I'll tag it on the end of the title.
39 std::stringstream description;
40 description << pTrigger_->name() << " rate versus " << versusParameter;
41
42 // Loop over all of the parameters and add their values to the description
43 std::vector<std::string> parameterNames=pTrigger_->parameterNames();
44 description << " [v" << pTrigger_->version();
45 if( parameterNames.size()>1 ) description << ",";
46 for( std::vector<std::string>::const_iterator iName=parameterNames.begin(); iName!=parameterNames.end(); ++iName )
47 {
48 if( *iName==versusParameter ) continue; // Don't bother adding the parameter I'm plotting against
49
50 // First check to see if this is one of the parameters that are being scaled
51 if( std::find(scaledParameters.begin(),scaledParameters.end(),*iName)==scaledParameters.end() )
52 {
53 // This parameter isn't being scaled, so write the absoulte value in the description
54 description << *iName << "=" << pTrigger_->parameter(*iName);
55 }
56 else
57 {
58 // This parameter is being scaled, so write what the scaling is in the description
59 description << *iName << "=x*" << pTrigger_->parameter(*iName)/(*pParameter_);
60 }
61
62 if( iName+1!=parameterNames.end() ) description << ","; // Add delimeter between parameter names
63 }
64 description << "]";
65
66 pHistogram_->SetTitle( description.str().c_str() );
67
68 }
69
70 l1menu::TriggerRatePlot::TriggerRatePlot( l1menu::TriggerRatePlot&& otherTriggerRatePlot ) noexcept
71 : pTrigger_( std::move(otherTriggerRatePlot.pTrigger_) ), pHistogram_( std::move(otherTriggerRatePlot.pHistogram_) ),
72 versusParameter_( std::move(otherTriggerRatePlot.versusParameter_) ), pParameter_(&pTrigger_->parameter(versusParameter_)),
73 otherParameterScalings_( std::move(otherTriggerRatePlot.otherParameterScalings_) ), histogramOwnedByMe_(histogramOwnedByMe_)
74 {
75 // No operation besides the initaliser list
76 }
77
78 l1menu::TriggerRatePlot& l1menu::TriggerRatePlot::operator=( l1menu::TriggerRatePlot&& otherTriggerRatePlot ) noexcept
79 {
80 // Free up whatever was there before
81 pTrigger_.reset();
82 if( histogramOwnedByMe_ ) pHistogram_.reset();
83 else pHistogram_.release();
84
85 // Then copy from the other object
86 pTrigger_=std::move(otherTriggerRatePlot.pTrigger_);
87 pHistogram_=std::move(otherTriggerRatePlot.pHistogram_);
88 versusParameter_=std::move(otherTriggerRatePlot.versusParameter_);
89 pParameter_=&pTrigger_->parameter(versusParameter_);
90 otherParameterScalings_=std::move(otherTriggerRatePlot.otherParameterScalings_);
91 histogramOwnedByMe_=otherTriggerRatePlot.histogramOwnedByMe_;
92
93 return *this;
94 }
95
96 l1menu::TriggerRatePlot::~TriggerRatePlot()
97 {
98 // If the flag has been set telling me that this instance doesn't own the histogram,
99 // then I need to tell the unique_ptr not to delete it.
100 if( !histogramOwnedByMe_ )
101 {
102 pHistogram_.release();
103 }
104 }
105
106 void l1menu::TriggerRatePlot::addEvent( const l1menu::IEvent& event )
107 {
108 const l1menu::ISample& sample=event.sample();
109 float weightPerEvent=sample.eventRate()/sample.sumOfWeights();
110
111 // For some implementations of ISample, it is significantly faster to
112 // create ICachedTriggers and then loop over those.
113 std::unique_ptr<l1menu::ICachedTrigger> pCachedTrigger=sample.createCachedTrigger( *pTrigger_ );
114
115 for( int binNumber=1; binNumber<pHistogram_->GetNbinsX(); ++binNumber )
116 {
117 (*pParameter_)=pHistogram_->GetBinCenter(binNumber);
118
119 // Scale accordingly any other parameters that should be scaled.
120 for( const auto& parameterScalingPair : otherParameterScalings_ ) *(parameterScalingPair.first)=parameterScalingPair.second*(*pParameter_);
121
122 if( pCachedTrigger->apply(event) )
123 {
124 pHistogram_->Fill( (*pParameter_), event.weight()*weightPerEvent );
125 }
126 else break;
127 // Not sure if this "else break" is a good idea. I don't know if triggers
128 // will run their thresholds the other way. E.g. a trigger could require
129 // a minimum amount of energy in the event, in which case the higher
130 // bins will pass.
131 }
132 }
133
134 void l1menu::TriggerRatePlot::addSample( const l1menu::ISample& sample )
135 {
136 float weightPerEvent=sample.eventRate()/sample.sumOfWeights();
137
138 // Create a cached trigger, which depending on the concrete type of the ISample
139 // may or may not significantly increase the speed at which this next loop happens.
140 std::unique_ptr<l1menu::ICachedTrigger> pCachedTrigger=sample.createCachedTrigger( *pTrigger_ );
141
142 for( size_t eventNumber=0; eventNumber<sample.numberOfEvents(); ++eventNumber )
143 {
144 const l1menu::IEvent& event=sample.getEvent( eventNumber );
145
146 for( int binNumber=1; binNumber<pHistogram_->GetNbinsX(); ++binNumber )
147 {
148 (*pParameter_)=pHistogram_->GetBinCenter(binNumber);
149
150 // Scale accordingly any other parameters that should be scaled.
151 for( const auto& parameterScalingPair : otherParameterScalings_ ) *(parameterScalingPair.first)=parameterScalingPair.second*(*pParameter_);
152
153 if( pCachedTrigger->apply(event) ) // If the event passes the trigger
154 {
155 pHistogram_->Fill( (*pParameter_), event.weight()*weightPerEvent );
156 }
157 else break;
158 // Not sure if this "else break" is a good idea. I don't know if triggers
159 // will run their thresholds the other way. E.g. a trigger could require
160 // a minimum amount of energy in the event, in which case the higher
161 // bins will pass.
162 } // end of loop over histogram bins
163 } // end of loop over events
164
165 }
166
167 const l1menu::ITrigger& l1menu::TriggerRatePlot::getTrigger() const
168 {
169 return *pTrigger_;
170 }
171
172 TH1* l1menu::TriggerRatePlot::getPlot()
173 {
174 return pHistogram_.get();
175 }
176
177 TH1* l1menu::TriggerRatePlot::relinquishOwnershipOfPlot()
178 {
179 // Rather than call release() on the unique_ptr, I'll set a flag so that I know
180 // to release() in the destructor instead. This way it's possible to relinquish
181 // ownership but still perform operations on the histograms.
182 histogramOwnedByMe_=false;
183 return pHistogram_.get();
184 }