ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/grimes/L1Menu/src/ReducedMenuSample.cpp
(Generate patch)

Comparing UserCode/grimes/L1Menu/src/ReducedMenuSample.cpp (file contents):
Revision 1.9 by grimes, Sat Jun 8 09:31:25 2013 UTC vs.
Revision 1.12 by grimes, Mon Jun 24 17:09:05 2013 UTC

# Line 9 | Line 9
9   #include "l1menu/MenuSample.h"
10   #include "l1menu/TriggerMenu.h"
11   #include "l1menu/ITrigger.h"
12 < #include "l1menu/tools.h"
12 > #include "l1menu/IMenuRate.h"
13 > #include "l1menu/ITriggerRate.h"
14 > #include "l1menu/tools/tools.h"
15   #include "protobuf/l1menu.pb.h"
16   #include <google/protobuf/io/zero_copy_stream_impl.h>
17   #include <google/protobuf/io/gzip_stream.h>
# Line 38 | Line 40 | namespace // unnamed namespace
40          private:
41                  int fileDescriptor_;
42          };
43 +
44 +        class MenuRateImplementation;
45 +
46 +        class TriggerRateImplementation : public l1menu::ITriggerRate
47 +        {
48 +        public:
49 +                TriggerRateImplementation( const l1menu::ITrigger& trigger, float fraction, const MenuRateImplementation& menuRate );
50 +                TriggerRateImplementation& operator=( TriggerRateImplementation&& otherTriggerRate ); // Move assignment
51 +                virtual ~TriggerRateImplementation();
52 +
53 +                // Methods required by the l1menu::ITriggerRate interface
54 +                virtual const l1menu::ITrigger& trigger() const;
55 +                virtual float fraction() const;
56 +                virtual float rate() const;
57 +        protected:
58 +                std::unique_ptr<l1menu::ITrigger> pTrigger_;
59 +                float fraction_;
60 +                const MenuRateImplementation& menuRate_;
61 +        };
62 +
63 +        class MenuRateImplementation : public l1menu::IMenuRate
64 +        {
65 +        public:
66 +                void setTotalFraction( float fraction ) { totalFraction_=fraction; }
67 +                void setScaling( float scaling ) { scaling_=scaling; }
68 +                float scaling() const { return scaling_; }
69 +                void addTriggerRate( const l1menu::ITrigger& trigger, float fraction ) { triggerRates_.push_back( std::move(TriggerRateImplementation(trigger,fraction,*this)) ); }
70 +                // Methods required by the l1menu::IMenuRate interface
71 +                virtual float totalFraction() const { return totalFraction_; }
72 +                virtual float totalRate() const { return totalFraction_*scaling_; }
73 +                virtual const std::vector<const l1menu::ITriggerRate*>& triggerRates() const
74 +                {
75 +                        // If the sizes are the same I'll assume nothing has changed and the references
76 +                        // are still valid. I don't expect this method to be called until the triggerRates_
77 +                        // vector is complete anyway.
78 +                        if( triggerRates_.size()!=baseClassReferences_.size() )
79 +                        {
80 +                                baseClassReferences_.clear();
81 +                                for( const auto& triggerRate : triggerRates_ )
82 +                                {
83 +                                        baseClassReferences_.push_back( &triggerRate );
84 +                                }
85 +                        }
86 +
87 +                        return baseClassReferences_;
88 +                }
89 +
90 +        protected:
91 +                float totalFraction_;
92 +                float scaling_;
93 +                std::vector<TriggerRateImplementation> triggerRates_;
94 +                mutable std::vector<const l1menu::ITriggerRate*> baseClassReferences_;
95 +        };
96 +
97 +        TriggerRateImplementation::TriggerRateImplementation( const l1menu::ITrigger& trigger, float fraction, const MenuRateImplementation& menuRate )
98 +                : fraction_(fraction), menuRate_(menuRate)
99 +        {
100 +                pTrigger_=std::move( l1menu::TriggerTable::instance().copyTrigger(trigger) );
101 +        }
102 +        TriggerRateImplementation& TriggerRateImplementation::operator=( TriggerRateImplementation&& otherTriggerRate )
103 +        {
104 +                pTrigger_=std::move( otherTriggerRate.pTrigger_ );
105 +                fraction_=otherTriggerRate.fraction_;
106 +                // I can't change the menuRate_ reference, but that should already be set to the right one anyway.
107 +                return *this;
108 +        }
109 +        TriggerRateImplementation::~TriggerRateImplementation() {}
110 +        const l1menu::ITrigger& TriggerRateImplementation::trigger() const { return *pTrigger_; }
111 +        float TriggerRateImplementation::fraction() const { return fraction_; }
112 +        float TriggerRateImplementation::rate() const { return fraction_*menuRate_.scaling(); }
113 +
114   }
115  
116   namespace l1menu
# Line 56 | Line 129 | namespace l1menu
129                  ReducedMenuSamplePrivateMembers( const std::string& filename );
130                  void copyMenuToProtobufSample();
131                  ::ReducedEventImplementation event;
132 <                const l1menu::TriggerMenu& triggerMenu;
132 >                const l1menu::TriggerMenu& triggerMenu; // External const access to mutableTriggerMenu_
133 >                float eventRate;
134                  l1menuprotobuf::SampleHeader protobufSampleHeader;
135                  // Protobuf doesn't implement move semantics so I'll use pointers
136                  std::vector<std::unique_ptr<l1menuprotobuf::Run> > protobufRuns;
# Line 71 | Line 145 | namespace l1menu
145   }
146  
147   l1menu::ReducedMenuSamplePrivateMembers::ReducedMenuSamplePrivateMembers( const l1menu::TriggerMenu& newTriggerMenu )
148 <        : mutableTriggerMenu_( newTriggerMenu ), triggerMenu( mutableTriggerMenu_ )
148 >        : mutableTriggerMenu_( newTriggerMenu ), triggerMenu( mutableTriggerMenu_ ), eventRate(1)
149   {
150          GOOGLE_PROTOBUF_VERIFY_VERSION;
151  
# Line 99 | Line 173 | l1menu::ReducedMenuSamplePrivateMembers:
173  
174                  // Make a note of the names of the parameters that are recorded for each event. For this
175                  // I'm just recording the parameters that refer to the thresholds.
176 <                const auto thresholdNames=l1menu::getThresholdNames(trigger);
176 >                const auto thresholdNames=l1menu::tools::getThresholdNames(trigger);
177                  for( const auto& thresholdName : thresholdNames ) pProtobufTrigger->add_varying_parameter(thresholdName);
178  
179          } // end of loop over triggers
# Line 120 | Line 194 | l1menu::ReducedMenuSamplePrivateMembers:
194          if( fileDescriptor==0 ) throw std::runtime_error( "ReducedMenuSample initialise from file - couldn't open file" );
195          ::UnixFileSentry fileSentry( fileDescriptor ); // Use this as an exception safe way of closing the input file
196          google::protobuf::io::FileInputStream fileInput( fileDescriptor );
197 +
198 +        // First read the magic number at the start of the file and make sure it
199 +        // matches what I expect. This is uncompressed so I'll wrap it in a block
200 +        // to make sure the CodedInputStream is destructed before creating a new
201 +        // one with gzip input.
202 +        {
203 +                google::protobuf::io::CodedInputStream codedInput( &fileInput );
204 +
205 +                // As a read buffer, I'll create a string the correct size (filled with an arbitrary
206 +                // character) and read straight into that.
207 +                std::string readMagicNumber;
208 +                if( !codedInput.ReadString( &readMagicNumber, FILE_FORMAT_MAGIC_NUMBER.size() ) ) throw std::runtime_error( "ReducedMenuSample initialise from file - error reading magic number" );
209 +                if( readMagicNumber!=FILE_FORMAT_MAGIC_NUMBER ) throw std::runtime_error( "ReducedMenuSample - tried to initialise with a file that is not the correct format" );
210 +
211 +                google::protobuf::uint32 fileformatVersion;
212 +                if( !codedInput.ReadVarint32( &fileformatVersion ) ) throw std::runtime_error( "ReducedMenuSample initialise from file - error reading file format version" );
213 +                // So far I only have (and ever expect to have) one version of the file
214 +                // format, imaginatively versioned "1". You never know though...
215 +                if( fileformatVersion>1 ) std::cerr << "Warning: Attempting to read a ReducedMenuSample with version " << fileformatVersion << " with code that only knows up to version 1." << std::endl;
216 +        }
217 +
218          google::protobuf::io::GzipInputStream gzipInput( &fileInput );
219          google::protobuf::io::CodedInputStream codedInput( &gzipInput );
220  
# Line 129 | Line 224 | l1menu::ReducedMenuSamplePrivateMembers:
224          size_t totalBytesLimit=67108864;
225          codedInput.SetTotalBytesLimit( totalBytesLimit, -1 );
226  
132        // First read the magic number at the start of the file and make sure it
133        // matches what I expect. As a read buffer, I'll create a string the correct
134        // size (filled with an arbitrary character) and read straight into that.
135        std::string readMagicNumber;
136        if( !codedInput.ReadString( &readMagicNumber, FILE_FORMAT_MAGIC_NUMBER.size() ) ) throw std::runtime_error( "ReducedMenuSample initialise from file - error reading magic number" );
137        if( readMagicNumber!=FILE_FORMAT_MAGIC_NUMBER ) throw std::runtime_error( "ReducedMenuSample - tried to initialise with a file that is not the correct format" );
138
139        google::protobuf::uint32 fileformatVersion;
140        if( !codedInput.ReadVarint32( &fileformatVersion ) ) throw std::runtime_error( "ReducedMenuSample initialise from file - error reading file format version" );
141        // So far I only have (and ever expect to have) one version of the file
142        // format, imaginatively versioned "1". You never know though...
143        if( fileformatVersion>1 ) std::cerr << "Warning: Attempting to read a ReducedMenuSample with version " << fileformatVersion << " with code that only knows up to version 1." << std::endl;
144
227          google::protobuf::uint64 messageSize;
228  
229          // Read the size of the header message
# Line 245 | Line 327 | void l1menu::ReducedMenuSample::addSampl
327                  for( size_t triggerNumber=0; triggerNumber<pImple_->triggerMenu.numberOfTriggers(); ++triggerNumber )
328                  {
329                          std::unique_ptr<l1menu::ITrigger> pTrigger=pImple_->triggerMenu.getTriggerCopy(triggerNumber);
330 <                        std::vector<std::string> thresholdNames=getThresholdNames(*pTrigger);
330 >                        std::vector<std::string> thresholdNames=l1menu::tools::getThresholdNames(*pTrigger);
331  
332                          try
333                          {
334 <                                setTriggerThresholdsAsTightAsPossible( event, *pTrigger, 0.001 );
334 >                                l1menu::tools::setTriggerThresholdsAsTightAsPossible( event, *pTrigger, 0.001 );
335                                  // Set all of the parameters to match the thresholds in the trigger
336                                  for( const auto& thresholdName : thresholdNames )
337                                  {
# Line 284 | Line 366 | void l1menu::ReducedMenuSample::saveToFi
366  
367          // Setup the protobuf file handlers
368          google::protobuf::io::FileOutputStream fileOutput( fileDescriptor );
369 +
370 +        // I want the magic number and file format identifier uncompressed, so
371 +        // I'll write those before switching to using gzipped output.
372 +        { // Block to make sure codedOutput is destructed before the gzip version is created
373 +                google::protobuf::io::CodedOutputStream codedOutput( &fileOutput );
374 +
375 +                // Write a magic number at the start of all files
376 +                codedOutput.WriteString( pImple_->FILE_FORMAT_MAGIC_NUMBER );
377 +                // Write an integer that specifies what version of the file format I'm using. I
378 +                // have no intention of changing the format but I might as well keep the option
379 +                // open.
380 +                codedOutput.WriteVarint32( 1 );
381 +        }
382 +
383          google::protobuf::io::GzipOutputStream gzipOutput( &fileOutput );
384          google::protobuf::io::CodedOutputStream codedOutput( &gzipOutput );
385  
290        // Write a magic number at the start of all files
291        codedOutput.WriteString( pImple_->FILE_FORMAT_MAGIC_NUMBER );
292        // Write an integer that specifies what version of the file format I'm using. I
293        // have no intention of changing the format but I might as well keep the option
294        // open.
295        codedOutput.WriteVarint32( 1 );
296
386          // Write the size of the header message into the file...
387          codedOutput.WriteVarint64( pImple_->protobufSampleHeader.ByteSize() );
388          // ...and then write the header
# Line 362 | Line 451 | bool l1menu::ReducedMenuSample::contains
451                  // eta cuts or whatever.
452                  // I don't care if the thresholds don't match because that's what's stored in the
453                  // ReducedMenuSample.
454 <                std::vector<std::string> parameterNames=getNonThresholdParameterNames( trigger );
454 >                std::vector<std::string> parameterNames=l1menu::tools::getNonThresholdParameterNames( trigger );
455                  bool allParametersMatch=true;
456                  for( const auto& parameterName : parameterNames )
457                  {
# Line 408 | Line 497 | const std::map<std::string,size_t> l1men
497                  // ReducedMenuSample.
498                  if( triggerWasFound ) // Trigger can still fail, but no point doing this check if it already has
499                  {
500 <                        std::vector<std::string> parameterNames=getNonThresholdParameterNames( trigger );
500 >                        std::vector<std::string> parameterNames=l1menu::tools::getNonThresholdParameterNames( trigger );
501                          for( const auto& parameterName : parameterNames )
502                          {
503                                  if( trigger.parameter(parameterName)!=triggerInMenu.parameter(parameterName) ) triggerWasFound=false;
504                          }
505                  }
506  
507 <                std::vector<std::string> thresholdNames=l1menu::getThresholdNames(triggerInMenu);
507 >                std::vector<std::string> thresholdNames=l1menu::tools::getThresholdNames(triggerInMenu);
508                  if( triggerWasFound )
509                  {
510                          for( const auto& thresholdName : thresholdNames )
# Line 432 | Line 521 | const std::map<std::string,size_t> l1men
521          // (I guess - it would be a pretty pointless trigger though). To indicate the
522          // difference between that and a trigger that wasn't found I'll respectively
523          // return the empty vector or throw an exception.
524 <        if( !triggerWasFound ) throw std::runtime_error( "l1menu::ReducedMenuSample::getTriggerParameterIdentifiers() called for a trigger that was not used to create the sample" );
524 >        if( !triggerWasFound ) throw std::runtime_error( "l1menu::ReducedMenuSample::getTriggerParameterIdentifiers() called for a trigger that was not used to create the sample - "+trigger.name() );
525  
526          return returnValue;
527   }
528 +
529 + float l1menu::ReducedMenuSample::eventRate() const
530 + {
531 +        return pImple_->eventRate;
532 + }
533 +
534 + void l1menu::ReducedMenuSample::setEventRate( float rate ) const
535 + {
536 +        pImple_->eventRate=rate;
537 + }
538 +
539 + std::unique_ptr<const l1menu::IMenuRate> l1menu::ReducedMenuSample::rate( const l1menu::TriggerMenu& menu ) const
540 + {
541 +        // TODO make sure the TriggerMenu is valid for this sample
542 +
543 +        // I need a non-const menu, so make a copy
544 +        l1menu::TriggerMenu mutableMenu( menu );
545 +
546 +        // The number of events that pass each trigger
547 +        std::vector<size_t> numberOfEventsPassed( menu.numberOfTriggers() );
548 +        float numberOfEventsPassingAnyTrigger;
549 +
550 +        for( size_t triggerNumber=0; triggerNumber<menu.numberOfTriggers(); ++triggerNumber )
551 +        {
552 +                mutableMenu.getTrigger( triggerNumber ).initiateForReducedSample( *this );
553 +        }
554 +
555 +        for( size_t eventNumber=0; eventNumber<numberOfEvents(); ++eventNumber )
556 +        {
557 +                const l1menu::IReducedEvent& event=getEvent(eventNumber);
558 +                bool anyTriggerPassed=false;
559 +
560 +                for( size_t triggerNumber=0; triggerNumber<menu.numberOfTriggers(); ++triggerNumber )
561 +                {
562 +                        if( mutableMenu.getTrigger( triggerNumber ).apply( event ) )
563 +                        {
564 +                                // If the event passes the trigger, increment the counter
565 +                                ++numberOfEventsPassed[triggerNumber];
566 +                                anyTriggerPassed=true;
567 +                        }
568 +                }
569 +
570 +                if( anyTriggerPassed ) ++numberOfEventsPassingAnyTrigger;
571 +        }
572 +
573 +        ::MenuRateImplementation* pRates=new ::MenuRateImplementation;
574 +        pRates->setScaling( pImple_->eventRate );
575 +        // This is the value I want to return, but I still need access to the extended attributes of the subclass
576 +        std::unique_ptr<const l1menu::IMenuRate> pReturnValue( pRates );
577 +
578 +        pRates->setTotalFraction( static_cast<float>(numberOfEventsPassingAnyTrigger)/static_cast<float>(numberOfEvents()) );
579 +
580 +        for( size_t triggerNumber=0; triggerNumber<numberOfEventsPassed.size(); ++triggerNumber )
581 +        {
582 +                float fraction=static_cast<float>(numberOfEventsPassed[triggerNumber])/static_cast<float>(numberOfEvents());
583 +                pRates->addTriggerRate( mutableMenu.getTrigger(triggerNumber), fraction );
584 +        }
585 +
586 +        return pReturnValue;
587 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines