aimsalgo  5.1.2
Neuroimaging image processing
iirfilter.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 #ifndef AIMS_SIGNALFILTER_IIRFILTER_H
35 #define AIMS_SIGNALFILTER_IIRFILTER_H
36 
39 #include <vector>
40 
41 namespace aims {
42 
43  //==========================================================================
44  //
45  // BASE CLASS FOR INFINITE IMPULSE RESPONSE FILTER
46  //
47  //==========================================================================
58  {
59  public:
60 
61  //------------------------------------------------------------------------
63  //------------------------------------------------------------------------
66  IIRFilterBase( const IIRFilterBase & other );
67  virtual ~IIRFilterBase();
70 
71  //------------------------------------------------------------------------
73  //------------------------------------------------------------------------
79  template <typename T>
84  carto::VolumeRef<double> execute( carto::VolumeRef<double> & in, bool inplace = false ) const;
86  virtual void filter1d( const carto::VolumeRef<double> in,
87  carto::VolumeRef<double> out, int dir = -1 ) const = 0;
89 
90  //------------------------------------------------------------------------
92  //------------------------------------------------------------------------
96  virtual const std::vector<bool> & directions() const;
97  virtual void setDirections( const std::vector<bool> & dir );
98  virtual void setDirections( bool dirx, bool diry, bool dirz, bool dirt );
99  virtual void setDirectionX( bool dirx );
100  virtual void setDirectionY( bool diry );
101  virtual void setDirectionZ( bool dirz );
102  virtual void setDirectionT( bool dirt );
107  virtual const FilterType::Boundary & boundary() const;
108  virtual void setBoundary( const FilterType::Boundary & boundary );
111  virtual void setVerbose( int verbose = 1 );
113  virtual void setQuiet();
115 
116 
117  protected:
118  //------------------------------------------------------------------------
120  //------------------------------------------------------------------------
124  virtual void filter( carto::VolumeRef<double> vol ) const;
126  virtual void filter1d( carto::VolumeRef<double> vol, int dir = -1,
130  virtual double & at( carto::VolumeRef<double> & vector, long k, int dir ) const;
132  virtual const double & at( const carto::VolumeRef<double> & vector, long k, int dir ) const;
139  virtual double at( const carto::VolumeRef<double> & vector, long k,
140  int dir, long fullsize, int binf ) const;
142  virtual long mirrorCoeff( long i, long size ) const;
144  virtual long selectCoeff( long i, long fullsize, int binf ) const;
146  virtual long computeK0( double pole, double tolerance = -1. ) const;
148 
149  int _verbose;
150  std::vector<bool> _dir;
153  };
154 
155 // Yael - April 15, 2016
156 // I'm commenting out this class for now because the initialization
157 // strategy is currently false. I guess there must be a right way to do this
158 // but I don't have the time and do not need this class for now.
159 // I leave it in case it is of interest someday.
160 #if 0
161  //==========================================================================
162  //
163  // CAUSAL INFINITE IMPULSE RESPONSE FILTER
164  //
165  //==========================================================================
167  class CausalIIRFilter: public IIRFilterBase
168  {
169  public:
170  //------------------------------------------------------------------------
172  //------------------------------------------------------------------------
181  CausalIIRFilter( const std::vector<double> & num_coeffs = std::vector<double>(),
182  const std::vector<double> & den_coeffs = std::vector<double>(),
183  double b0 = 1. );
184  CausalIIRFilter( const CausalIIRFilter & other );
185  virtual ~CausalIIRFilter();
186  CausalIIRFilter & operator=( const CausalIIRFilter & other );
188 
189  //------------------------------------------------------------------------
191  //------------------------------------------------------------------------
193  virtual void filter1d( const carto::VolumeRef<double> in,
194  carto::VolumeRef<double> out, int dir = -1 ) const;
196 
197  //------------------------------------------------------------------------
199  //------------------------------------------------------------------------
201  const double & b0() const;
202  const std::vector<double> & numCoeffs() const;
203  const std::vector<double> & denCoeffs() const;
204  void setB0( const double & gain );
205  void setNumCoeff( const double & coeff );
206  void setNumCoeffs( const std::vector<double> & coeff );
207  void setDenCoeff( const double & coeff );
208  void setDenCoeffs( const std::vector<double> & coeff );
210 
211  protected:
212  //------------------------------------------------------------------------
214  //------------------------------------------------------------------------
216  double recursiveHelper( const carto::VolumeRef<double> in,
217  long k, int dir, long fullsize, int binf ) const;
219 
220  double _b0;
221  std::vector<double> _num_coeff;
222  std::vector<double> _den_coeff;
223  };
224 
225  //==========================================================================
226  //
227  // ALL POLE CAUSAL INFINITE IMPULSE RESPONSE FILTER
228  //
229  //==========================================================================
231  class CausalAllPoleIIRFilter: public IIRFilterBase
232  {
233  public:
234  //------------------------------------------------------------------------
236  //------------------------------------------------------------------------
245  CausalAllPoleIIRFilter( const std::vector<double> & coeffs = std::vector<double>(),
246  double gain = 1., bool is_pole = false );
249  CausalAllPoleIIRFilter( double coeff, double gain = 1., bool is_pole = false );
250  CausalAllPoleIIRFilter( const CausalAllPoleIIRFilter & other );
251  virtual ~CausalAllPoleIIRFilter();
252  CausalAllPoleIIRFilter & operator=( const CausalAllPoleIIRFilter & other );
254 
255  //------------------------------------------------------------------------
257  //------------------------------------------------------------------------
259  virtual void filter1d( const carto::VolumeRef<double> in,
260  carto::VolumeRef<double> out, int dir = -1 ) const;
262 
263  //------------------------------------------------------------------------
265  //------------------------------------------------------------------------
267  const double & gain() const;
268  const std::vector<double> & poles() const;
269  const std::vector<double> & coeffs() const;
270  void setGain( const double & gain );
271  void setPole( const double & pole, bool is_pole = true );
272  void setPoles( const std::vector<double> & pole, bool is_pole = true );
273  void setCoeff( const double & coeff, bool is_pole = false );
274  void setCoeffs( const std::vector<double> & coeff, bool is_pole = false );
276 
277  protected:
278  //------------------------------------------------------------------------
280  //------------------------------------------------------------------------
282  void computeK0();
284 
285  double _gain;
286  std::vector<double> _coeff;
287  std::vector<long> _k0;
288  bool _is_pole;
289  };
290 #endif
291 
292  //==========================================================================
293  //
294  // SINGLE POLE CAUSAL INFINITE IMPULSE RESPONSE FILTER
295  //
296  //==========================================================================
302  {
303  public:
304  //------------------------------------------------------------------------
306  //------------------------------------------------------------------------
308  CausalSinglePoleIIRFilter( double pole = 0., double gain = 1. );
313 
314  //------------------------------------------------------------------------
316  //------------------------------------------------------------------------
318  virtual void filter1d( const carto::VolumeRef<double> in,
319  carto::VolumeRef<double> out, int dir = -1 ) const;
321 
322  //------------------------------------------------------------------------
324  //------------------------------------------------------------------------
326  const double & gain() const;
327  const double & pole() const;
328  void setPole( const double & pole );
329  void setGain( const double & gain );
331 
332  protected:
333  //------------------------------------------------------------------------
335  //------------------------------------------------------------------------
337  void computeK0();
339 
340  double _gain;
341  double _pole;
342  long _k0;
343  };
344 
345 
346 // Yael - April 15, 2016
347 // Same as the CausalFilter class. I think this one is accurate, but it needs
348 // CausalFilter to work, so it will wait.
349 #if 0
350  //==========================================================================
351  //
352  // WARPER FOR ANTICAUSAL FILTERS
353  //
354  //==========================================================================
357  template <typename CausalFilter>
358  class AntiCausalWarperIIRFilter: public CausalFilter
359  {
360  public:
361  //------------------------------------------------------------------------
363  //------------------------------------------------------------------------
365  explicit AntiCausalWarperIIRFilter( const CausalFilter & other = CausalFilter() );
366  AntiCausalWarperIIRFilter( const AntiCausalWarperIIRFilter & other );
367  virtual ~AntiCausalWarperIIRFilter();
368  AntiCausalWarperIIRFilter & operator=( const AntiCausalWarperIIRFilter & other );
370 
371  protected:
372  //------------------------------------------------------------------------
374  //------------------------------------------------------------------------
376  virtual double & at( carto::VolumeRef<double> & vector, long k, int dir ) const;
377  virtual const double & at( const carto::VolumeRef<double> & vector, long k, int dir ) const;
378  virtual double at( const carto::VolumeRef<double> & vector, long k,
379  int dir, long fullsize, int binf ) const;
381  };
382 
383  //--------------------------------------------------------------------------
384  // Typedefs
385  //--------------------------------------------------------------------------
386  typedef AntiCausalWarperIIRFilter<CausalIIRFilter> AntiCausalIIRFilter;
387  typedef AntiCausalWarperIIRFilter<CausalAllPoleIIRFilter> AntiCausalAllPoleIIRFilter;
388  typedef AntiCausalWarperIIRFilter<CausalSinglePoleIIRFilter> AntiCausalSinglePoleIIRFilter;
389 #endif
390 
391  //==========================================================================
392  //
393  // SYMMETRIC ALL-POLE INFINITE IMPULSE RESPONSE FILTER
394  //
395  //==========================================================================
418  {
419  public:
420  //------------------------------------------------------------------------
422  //------------------------------------------------------------------------
424  SymAllPoleIIRFilter( const double gain = 0.,
425  const std::vector<double> & poles = std::vector<double>() );
430 
431  //------------------------------------------------------------------------
433  //------------------------------------------------------------------------
435  virtual void filter1d( const carto::VolumeRef<double> in,
437  int dir = -1 ) const;
439 
440  //------------------------------------------------------------------------
442  //------------------------------------------------------------------------
444  const double & gain() const;
445  const std::vector<double> & poles() const;
446  void setPoles( const std::vector<double> & poles );
447  void addPole( const double & pole );
449  void setGain( const double & gain );
454  void setModePreciseGain( bool precise = true );
456 
457  protected:
458  //------------------------------------------------------------------------
460  //------------------------------------------------------------------------
462  void computeK0();
465 
466  std::vector<double> _poles;
467  std::vector<long> _k0;
468  double _gain;
469  double _precisegain;
470  bool _precise;
471  };
472 
473 } // namespace aims
474 
475 #endif // AIMS_SIGNALFILTER_IIRFILTER_H
Special case of Infinite Impulse Response filter.
Definition: iirfilter.h:302
const double & pole() const
CausalSinglePoleIIRFilter & operator=(const CausalSinglePoleIIRFilter &other)
virtual void filter1d(const carto::VolumeRef< double > in, carto::VolumeRef< double > out, int dir=-1) const
Execution.
void setPole(const double &pole)
void setGain(const double &gain)
CausalSinglePoleIIRFilter(const CausalSinglePoleIIRFilter &other)
const double & gain() const
Parameters.
CausalSinglePoleIIRFilter(double pole=0., double gain=1.)
Constructor / Destructor / Copy.
Base class for separable infinite impulse response filters.
Definition: iirfilter.h:58
virtual ~IIRFilterBase()
virtual long computeK0(double pole, double tolerance=-1.) const
compute K0 so that pole^K0 < precision
FilterType::CopyType _copy
Definition: iirfilter.h:152
virtual void filter1d(carto::VolumeRef< double > vol, int dir=-1, carto::VolumeRef< double > tmp=carto::VolumeRef< double >((carto::Volume< double > *) 0)) const
redirection for in place fitlering
virtual void filter1d(const carto::VolumeRef< double > in, carto::VolumeRef< double > out, int dir=-1) const =0
Actual 1d filter that should be implemented by derived classes.
virtual void setDirections(const std::vector< bool > &dir)
virtual void filter(carto::VolumeRef< double > vol) const
Helpers.
carto::VolumeRef< double > execute(carto::VolumeRef< double > &in, bool inplace=false) const
IIRFilterBase(const IIRFilterBase &other)
virtual double & at(carto::VolumeRef< double > &vector, long k, int dir) const
Fast access : k must be in [0, size-1].
virtual const std::vector< bool > & directions() const
Parameters.
virtual void setDirectionT(bool dirt)
default: false
virtual const FilterType::Boundary & boundary() const
Because the filter is infinite, the signal must be extended outisde the image domain.
std::vector< bool > _dir
Definition: iirfilter.h:150
virtual void setBoundary(const FilterType::Boundary &boundary)
virtual const double & at(const carto::VolumeRef< double > &vector, long k, int dir) const
Fast access : k must be in [0, size-1].
virtual long mirrorCoeff(long i, long size) const
If i is outside [0, size-1], it is mirrored to fall inside.
virtual void setDirectionY(bool diry)
default: true
virtual long selectCoeff(long i, long fullsize, int binf) const
If i is outside [binf, fullsize-1], it is mirrored to fall inside.
FilterType::Boundary _boundary
Definition: iirfilter.h:151
virtual void setQuiet()
Set verbosity level to 0 -> Remove all possible traces.
IIRFilterBase()
Constructor / Destructor / Copy.
carto::VolumeRef< double > execute(const carto::VolumeRef< T > &in) const
Execution.
IIRFilterBase & operator=(const IIRFilterBase &other)
virtual double at(const carto::VolumeRef< double > &vector, long k, int dir, long fullsize, int binf) const
Mirror access : k can be outside [0, size - 1].
virtual void setDirectionZ(bool dirz)
default: true
virtual void setDirectionX(bool dirx)
default: true
virtual void setDirections(bool dirx, bool diry, bool dirz, bool dirt)
virtual void setVerbose(int verbose=1)
Verbosity level.
Symmetric, all-pole, infinite impulse response Filter.
Definition: iirfilter.h:418
void setGain(const double &gain)
Relative to Unser & al, gain = c0.
const std::vector< double > & poles() const
std::vector< double > _poles
Definition: iirfilter.h:466
SymAllPoleIIRFilter(const double gain=0., const std::vector< double > &poles=std::vector< double >())
Constructor / Destructor / Copy.
std::vector< long > _k0
Definition: iirfilter.h:467
void addPole(const double &pole)
SymAllPoleIIRFilter(const SymAllPoleIIRFilter &other)
virtual void filter1d(const carto::VolumeRef< double > in, carto::VolumeRef< double > out, int dir=-1) const
Execution.
void setPoles(const std::vector< double > &poles)
SymAllPoleIIRFilter & operator=(const SymAllPoleIIRFilter &other)
void computeK0()
Helpers.
const double & gain() const
Parameters.
void setModePreciseGain(bool precise=true)
If this mode is activated, provided gain should be c * prod(-poles).
const T & at(const carto::VolumeRef< T > &vol, long px, long py, long pz, long pt, const Point4dl &fullsize, const Point4dl &binf)