//
//
/*!

  \file
  \ingroup ImageProcessor  
  \brief Declaration of class stir::SeparableCartesianMetzImageFilter
    
  \author Sanida Mustafovic
  \author Kris Thielemans
      
*/
/*
    Copyright (C) 2000- 2009, Hammersmith Imanet
    This file is part of STIR.

    This file is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 of the License, or
    (at your option) any later version.

    This file is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    See STIR/LICENSE.txt for details
*/

#ifndef __stir_SeparableCartesianMetzImageFilter_H__
#define __stir_SeparableCartesianMetzImageFilter_H__


#include "stir/SeparableMetzArrayFilter.h"
#include "stir/RegisteredParsingObject.h"
#include "stir/DataProcessor.h"
#include "stir/DiscretisedDensity.h"


START_NAMESPACE_STIR

// TODO!! remove define

#define num_dimensions 3

/*!
  \ingroup ImageProcessor  
  \brief A class in the DataProcessor hierarchy that implements Metz
  filtering (which includes Gaussian filtering).
  
  As it is derived from RegisteredParsingObject, it implements all the 
  necessary things to parse parameter files etc.

  The discretised densities that will be filtered are supposed to be on a 
  Cartesian grid. The filtering operation is then performed as 3 separate
  1d filters in every direction.

  \warning This class is currently restricted to 3d. This is mainly because of
  the difficulty to give sensible names to the parameters used for parsing
  in n dimensions.

  \see SeparableMetzArrayFilter for what a Metz filter is
 */

template <typename elemT>
class SeparableCartesianMetzImageFilter : 
  public 
    RegisteredParsingObject<
        SeparableCartesianMetzImageFilter<elemT>,
        DataProcessor<DiscretisedDensity<3,elemT> >,
        DataProcessor<DiscretisedDensity<3,elemT> >
    >
{
 private:
  typedef
    RegisteredParsingObject<
              SeparableCartesianMetzImageFilter<elemT>,
              DataProcessor<DiscretisedDensity<3,elemT> >,
              DataProcessor<DiscretisedDensity<3,elemT> >
	       >
    base_type;
public:
  static const char * const registered_name; 
  
  //! Default constructor
  SeparableCartesianMetzImageFilter();
  
  // Construct metz filter given parameters 
  //SeparableCartesianMetzImageFilter(const double fwhm_x,const double fwhm_y, const double fwhm_z,const int metz_power_x,const int metz_power_y, const int metz_power_z);
  
  //Succeeded consistency_check( const DiscretisedDensity<num_dimensions,elemT>& image) const;  
  
  
  VectorWithOffset<float> get_metz_fwhms() const;
  VectorWithOffset<float> get_metz_powers() const;
  //! Maximum number of elements in the kernels
  /*! -1 means unrestricted*/
  VectorWithOffset<int> get_max_kernel_sizes() const;  
  
private:
  
  VectorWithOffset<float> fwhms;
  VectorWithOffset<float> metz_powers;
  VectorWithOffset<int> max_kernel_sizes;  
  
  SeparableMetzArrayFilter<num_dimensions,elemT> metz_filter;

  virtual void set_defaults();
  virtual void initialise_keymap();
  
  Succeeded virtual_set_up(const DiscretisedDensity<num_dimensions,elemT>& image);
  // new
  void  virtual_apply(DiscretisedDensity<num_dimensions,elemT>& out_density, const DiscretisedDensity<num_dimensions,elemT>& in_density) const;
  void  virtual_apply(DiscretisedDensity<num_dimensions,elemT>& density) const ;
  
};

#undef num_dimensions

END_NAMESPACE_STIR

#endif


