newwave is hosted by Hepforge, IPPP Durham

New Wave - Noise Elimination With Wavelets At Vast Energies  0.1.0
code/include/NewWave/WaveletEvent.hh
Go to the documentation of this file.
00001 #ifndef NEWWAVE_WAVELET_EVENT_HH
00002 #define NEWWAVE_WAVELET_EVENT_HH
00003 
00004 #include "NewWave/WaveletBaseEvent.hh"
00005 #include "NewWave/PixelDefinition.hh"
00006 #include "NewWave/WaveletEngine.hh"
00007 #include "NewWave/Exceptions.hh"
00008 #include "NewWave/FrequencyBand.hh"
00009 #include "NewWave/Utils.hh"
00010 #include "NewWave/MomentumHelpers.hh"
00011 
00012 #include <map>
00013 #include <cmath>
00014 
00015 #include <iostream>
00016 
00017 namespace HepMC{
00018   class GenEvent;
00019 }
00020 
00021 namespace NewWave{
00022   
00023   using std::size_t;
00024   using std::map;
00025   using std::make_pair;
00026   
00028   template<typename T, typename momentum_type = Momentum<T> >
00029   class WaveletEvent : public WaveletBaseEvent{
00030     
00031   public:
00032     
00033     WaveletEvent(const T &particles,
00034                  const PixelDefinition &pixelDefn,
00035                  const WaveletEngine &engine): WaveletBaseEvent(),
00036     _pixelDefn(pixelDefn),
00037     _originalPixels(pixelDefn.makeEmptyPixelArray()),
00038     _engine(engine),
00039     _doInvert(true),
00040     _doParticles(true),
00041     _pileUpThreshold(0.),
00042     _doScale(true){
00043       
00044       _init(particles);
00045     }
00046     
00048 
00055     const WaveletCoefficients &coefficients()const{return _coefficients();}
00056     
00057     const FrequencyBands &frequencyBands()const{
00058       
00059       if(_frequencyBands.size() == _pixelDefn.nLevels() * _pixelDefn.nLevels()) return _frequencyBands;
00060       
00061       _frequencyBands.clear();
00062       _bandLookup.clear();
00063             
00064       for(const auto &c: _coefficients()){
00065         int hash = c.frequencyHash(_pixelDefn.nLevels());
00066         map<int, int>::const_iterator index = _bandLookup.find(hash);
00067         if(index==_bandLookup.end()){
00068           index = _bandLookup.insert(make_pair(hash, _frequencyBands.size())).first;
00069           _frequencyBands.push_back(FrequencyBand(c.yLevel(), c.phiLevel()));
00070         }
00071         
00072         _frequencyBands.at(index->second).addCoefficient(c);
00073       }
00074       
00075       return _frequencyBands;
00076     }
00077     
00078     const FrequencyBand &frequencyBand(const WaveletCoefficient &coeff)const{
00079       int hash = coeff.frequencyHash(_pixelDefn.nLevels());
00080       frequencyBands();
00081       map<int, int>::const_iterator index = _bandLookup.find(hash);
00082       if(index==_bandLookup.end()){
00083         throw InvalidFrequencyBand();
00084       }
00085       
00086       return _frequencyBands.at(index->second);
00087     }
00088     
00089     const PixelDefinition &pixelDefn()const{
00090       return _pixelDefn;
00091     }
00092     
00094 
00101     const PixelArray &pixels()const{
00102       
00103       if(!_doInvert) return _modifiedPixels;
00104       
00105       _modifiedPixels = _engine.inverseTransform(coefficients());
00106       _doInvert = false;
00107       return _modifiedPixels;
00108     }
00109     
00110     const PixelArray &originalPixels()const{
00111       return _originalPixels;
00112     }
00113     
00115 
00138     const T &particles()const{
00139       
00140       if(!_doInvert && !_doParticles) return _modifiedParticles;
00141       
00142       _ratio = pixels() / _originalPixels ;
00143       
00144       _modifiedParticles.clear();
00145       
00146       for(auto p: _originalParticles){
00147         size_t ybin   = _pixelDefn.yPixelIndex(momentum_type::rapidity(p));
00148         size_t phiBin = _pixelDefn.phiPixelIndex(momentum_type::phi(p));
00149         double ratio = _ratio.at(ybin).at(phiBin);
00150         
00151         momentum_type::update(_modifiedParticles, p, ratio, _pileUpThreshold, _doScale);
00152         
00153       }
00154       
00155       _doParticles = false;
00156       
00157       return _modifiedParticles;
00158     }
00159     
00160     
00162 
00171     void denoise(double noiseThreshold){
00172       
00173       filter([noiseThreshold](const WaveletCoefficient &c)->bool {return (fabs(c.value()) > noiseThreshold); });
00174       return;
00175     }
00176 
00178 
00197     void filter(const std::function<bool (const WaveletCoefficient&)> &select){
00198       
00199       for(WaveletCoefficient &coeff: _coefficients()){
00200         if(!select(coeff)){
00201           coeff.setValue(0.);
00202           _doInvert = true;
00203         }
00204       }
00205       return;
00206     }
00207     
00208     void scale(const std::function<double (const WaveletCoefficient&)> &scaler){
00209       for(WaveletCoefficient &coeff: _coefficients()){
00210         double s = scaler(coeff);
00211         coeff.setValue(s*coeff.value());
00212       }
00213       
00214       _doInvert = true;
00215       
00216       return;
00217     }
00218     
00219     
00220     void setPileUpThreshold(double threshold){
00221       if(threshold < 0.){
00222         throw PileUpThresholdException();
00223       }
00224       _pileUpThreshold = threshold;
00225       _doInvert = true;
00226       return;
00227     }
00228     
00230 
00239     void setScaleParticles(bool doScale){
00240       _doScale = doScale;
00241     }
00242     
00243   private:
00244     
00245     WaveletCoefficients &_coefficients()const{
00246       if(_coeffs.size() != 0) return _coeffs;
00247       _coeffs = _engine.transform(_originalPixels);
00248       for(auto &c: _coeffs){
00249         setEvent(c);
00250       }
00251       
00252       return _coeffs;
00253     }
00254     
00255     void _init(const T &input){
00256       
00257       for(auto p: input){
00258         if(_pixelDefn.covers(momentum_type::rapidity(p), momentum_type::phi(p))){
00259           _originalParticles.push_back(p);
00260           _addParticle(momentum_type::rapidity(p), momentum_type::phi(p), momentum_type::pT(p));
00261         }
00262       }
00263       
00264     }
00265     
00266     void _addParticle(double rapidity, double phi, double pT){
00267       size_t ybin   = _pixelDefn.yPixelIndex(rapidity);
00268       size_t phiBin = _pixelDefn.phiPixelIndex(phi);
00269       _originalPixels.at(ybin).at(phiBin) += pT;
00270       return;
00271     }
00272     
00273     HepMC::GenEvent *_genEvent()const;
00274     
00275     PixelDefinition _pixelDefn;
00276     
00277     mutable PixelArray _modifiedPixels;
00278     PixelArray _originalPixels;
00279     
00280     T _originalParticles;
00281     
00282     const WaveletEngine &_engine;
00283     
00284     mutable WaveletCoefficients _coeffs;
00285     
00286     mutable FrequencyBands _frequencyBands;
00287     mutable map<int, int> _bandLookup;
00288     
00289     mutable bool _doInvert;
00290     mutable bool _doParticles;
00291     
00292     double _pileUpThreshold;
00293     
00294     bool _doScale;
00295     
00296     mutable PixelArray _ratio;
00297     
00298     mutable T _modifiedParticles;
00299     
00300   };
00301   
00302   template<>
00303   HepMC::GenEvent* const &WaveletEvent<HepMC::GenEvent *>::particles()const;
00304   
00305   template<>
00306   void WaveletEvent<HepMC::GenEvent*>::_init(HepMC::GenEvent* const &input);
00307   
00308   
00309 }
00310 
00311 #endif