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

# User Rev Content
1 grimes 1.1 #include "l1menu/TriggerRatePlot.h"
2    
3     #include "l1menu/ITrigger.h"
4 grimes 1.5 #include "l1menu/ICachedTrigger.h"
5     #include "l1menu/L1TriggerDPGEvent.h"
6 grimes 1.1 #include "l1menu/IEvent.h"
7     #include "l1menu/TriggerTable.h"
8 grimes 1.2 #include "l1menu/ReducedMenuSample.h"
9 grimes 1.5 #include "l1menu/ReducedEvent.h"
10 grimes 1.1 #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 grimes 1.2 pParameter_=&pTrigger_->parameter(versusParameter_);
23 grimes 1.1
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 grimes 1.2 versusParameter_( std::move(otherTriggerRatePlot.versusParameter_) ), pParameter_(otherTriggerRatePlot.pParameter_),
48     histogramOwnedByMe_(histogramOwnedByMe_)
49 grimes 1.1 {
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 grimes 1.2 pParameter_=otherTriggerRatePlot.pParameter_;
65     histogramOwnedByMe_=otherTriggerRatePlot.histogramOwnedByMe_;
66 grimes 1.1
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 grimes 1.5 void l1menu::TriggerRatePlot::addEvent( const l1menu::L1TriggerDPGEvent& event )
81 grimes 1.1 {
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 grimes 1.2 (*pParameter_)=pHistogram_->GetBinCenter(binNumber);
87 grimes 1.1 if( pTrigger_->apply( event ) )
88     {
89 grimes 1.2 pHistogram_->Fill( (*pParameter_), event.weight() );
90 grimes 1.1 }
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 grimes 1.5 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 grimes 1.3 const l1menu::ITrigger& l1menu::TriggerRatePlot::getTrigger() const
126     {
127     return *pTrigger_;
128     }
129    
130 grimes 1.2 void l1menu::TriggerRatePlot::initiateForReducedSample( const l1menu::ReducedMenuSample& sample )
131     {
132     pTrigger_->initiateForReducedSample( sample );
133     }
134    
135 grimes 1.5 void l1menu::TriggerRatePlot::addEvent( const l1menu::ReducedEvent& event )
136 grimes 1.2 {
137 grimes 1.5 // Basically exactly the same as for the l1menu::L1TriggerDPGEvent version. I
138 grimes 1.2 // 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 grimes 1.1 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     }