ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/grimes/L1Menu/src/TriggerRatePlot.cpp
Revision: 1.5
Committed: Fri Jun 28 14:30:09 2013 UTC (11 years, 10 months ago) by grimes
Branch: MAIN
Changes since 1.4: +33 -4 lines
Log Message:
Added ICachedTrigger to speed up processing

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
13 l1menu::TriggerRatePlot::TriggerRatePlot( const l1menu::ITrigger& trigger, std::unique_ptr<TH1> pHistogram, const std::string versusParameter )
14 : pHistogram_( std::move(pHistogram) ), versusParameter_(versusParameter), histogramOwnedByMe_(true)
15 {
16 // Take a copy of the trigger
17 l1menu::TriggerTable& table=l1menu::TriggerTable::instance();
18 pTrigger_=table.copyTrigger( trigger );
19
20 // Make sure the versusParameter_ supplied is valid. If it's not then this call will
21 // throw an exception.
22 pParameter_=&pTrigger_->parameter(versusParameter_);
23
24 // I want to make a note of the other parameters set for the trigger. As far as I know TH1
25 // has no way of adding annotations so I'll tag it on the end of the title.
26 std::stringstream description;
27 description << pTrigger_->name() << " rate versus " << versusParameter;
28
29 // Loop over all of the parameters and add their values to the description
30 std::vector<std::string> parameterNames=pTrigger_->parameterNames();
31 description << " [v" << pTrigger_->version();
32 if( parameterNames.size()>1 ) description << ",";
33 for( std::vector<std::string>::const_iterator iName=parameterNames.begin(); iName!=parameterNames.end(); ++iName )
34 {
35 if( *iName==versusParameter ) continue; // Don't bother adding the parameter I'm plotting against
36 description << *iName << "=" << pTrigger_->parameter(*iName);
37 if( iName+1!=parameterNames.end() ) description << ","; // Add delimeter between parameter names
38 }
39 description << "]";
40
41 pHistogram_->SetTitle( description.str().c_str() );
42
43 }
44
45 l1menu::TriggerRatePlot::TriggerRatePlot( l1menu::TriggerRatePlot&& otherTriggerRatePlot ) noexcept
46 : pTrigger_( std::move(otherTriggerRatePlot.pTrigger_) ), pHistogram_( std::move(otherTriggerRatePlot.pHistogram_) ),
47 versusParameter_( std::move(otherTriggerRatePlot.versusParameter_) ), pParameter_(otherTriggerRatePlot.pParameter_),
48 histogramOwnedByMe_(histogramOwnedByMe_)
49 {
50 // No operation besides the initaliser list
51 }
52
53 l1menu::TriggerRatePlot& l1menu::TriggerRatePlot::operator=( l1menu::TriggerRatePlot&& otherTriggerRatePlot ) noexcept
54 {
55 // Free up whatever was there before
56 pTrigger_.reset();
57 if( histogramOwnedByMe_ ) pHistogram_.reset();
58 else pHistogram_.release();
59
60 // Then copy from the other object
61 pTrigger_=std::move(otherTriggerRatePlot.pTrigger_);
62 pHistogram_=std::move(otherTriggerRatePlot.pHistogram_);
63 versusParameter_=std::move(otherTriggerRatePlot.versusParameter_);
64 pParameter_=otherTriggerRatePlot.pParameter_;
65 histogramOwnedByMe_=otherTriggerRatePlot.histogramOwnedByMe_;
66
67 return *this;
68 }
69
70 l1menu::TriggerRatePlot::~TriggerRatePlot()
71 {
72 // If the flag has been set telling me that this instance doesn't own the histogram,
73 // then I need to tell the unique_ptr not to delete it.
74 if( !histogramOwnedByMe_ )
75 {
76 pHistogram_.release();
77 }
78 }
79
80 void l1menu::TriggerRatePlot::addEvent( const l1menu::L1TriggerDPGEvent& event )
81 {
82 // loop over all of the bins in the histogram, and see if the trigger passes
83 // for the value at the center of the bin.
84 for( int binNumber=1; binNumber<pHistogram_->GetNbinsX(); ++binNumber )
85 {
86 (*pParameter_)=pHistogram_->GetBinCenter(binNumber);
87 if( pTrigger_->apply( event ) )
88 {
89 pHistogram_->Fill( (*pParameter_), event.weight() );
90 }
91 // could put an "else break" in here, but I don't know if triggers
92 // will run their thresholds the other way. E.g. a trigger could require
93 // a minimum amount of energy in the event, in which case the higher
94 // bins will pass.
95 }
96 }
97
98 void l1menu::TriggerRatePlot::addSample( const l1menu::ISample& sample )
99 {
100 float weightPerEvent=sample.eventRate()/sample.sumOfWeights();
101
102 // Create a cached trigger, which depending on the concrete type of the ISample
103 // may or may not significantly increase the speed at which this next loop happens.
104 std::unique_ptr<l1menu::ICachedTrigger> pCachedTrigger=sample.createCachedTrigger( *pTrigger_ );
105
106 for( size_t eventNumber=0; eventNumber<sample.numberOfEvents(); ++eventNumber )
107 {
108 const l1menu::IEvent& event=sample.getEvent( eventNumber );
109
110 for( int binNumber=1; binNumber<pHistogram_->GetNbinsX(); ++binNumber )
111 {
112 (*pParameter_)=pHistogram_->GetBinCenter(binNumber);
113 if( pCachedTrigger->apply(event) ) // If the event passes the trigger
114 {
115 pHistogram_->Fill( (*pParameter_), event.weight()*weightPerEvent );
116 }
117 // could put an "else break" in here, but I don't know if triggers will
118 // run their thresholds the other way. E.g. a trigger could require
119 // a minimum amount of energy in the event, in which case the higher
120 // bins will pass.
121 } // end of loop over histogram bins
122 } // end of loop over events
123 }
124
125 const l1menu::ITrigger& l1menu::TriggerRatePlot::getTrigger() const
126 {
127 return *pTrigger_;
128 }
129
130 void l1menu::TriggerRatePlot::initiateForReducedSample( const l1menu::ReducedMenuSample& sample )
131 {
132 pTrigger_->initiateForReducedSample( sample );
133 }
134
135 void l1menu::TriggerRatePlot::addEvent( const l1menu::ReducedEvent& event )
136 {
137 // Basically exactly the same as for the l1menu::L1TriggerDPGEvent version. I
138 // should probably template this.
139 for( int binNumber=1; binNumber<pHistogram_->GetNbinsX(); ++binNumber )
140 {
141 (*pParameter_)=pHistogram_->GetBinCenter(binNumber);
142 if( pTrigger_->apply( event ) )
143 {
144 pHistogram_->Fill( (*pParameter_), event.weight() );
145 }
146 }
147
148 }
149
150 TH1* l1menu::TriggerRatePlot::getPlot()
151 {
152 return pHistogram_.get();
153 }
154
155 TH1* l1menu::TriggerRatePlot::relinquishOwnershipOfPlot()
156 {
157 // Rather than call release() on the unique_ptr, I'll set a flag so that I know
158 // to release() in the destructor instead. This way it's possible to relinquish
159 // ownership but still perform operations on the histograms.
160 histogramOwnedByMe_=false;
161 return pHistogram_.get();
162 }