[Insight-developers] Preconditions / Exceptions / Code values

Luis Ibanez ibanez@cs.unc.edu
Tue, 19 Dec 2000 19:56:51 -0500 (EST)


Hi,

When mapping an image under a transformation it
is possible to be in the situation of asking
for a pixel that lies in a position outside the
image domain.

A similar case happens when using the ImageFunction
and LinearInterpolateFunction classes, as well as
the Image class itself.

In the case of a transform is hard to know in advance
which points will fall outside the image, so it seems
more appropiated to verify this condition, before
using a pixel value, and do that in a pixel by pixel
basis.

That means that a :

   TPixelType   GetPixel(  coordinates  );

kind of method could use one (or maybe other) of the 
following policies to ensure that pixels are valid:



1) Precondition

the class that maps the image can provide the following
methods 

 void  SetPoint(  const Point<dimension, double> & coordinates );
 bool  IsPointInside( void ) const;
 TPixelType  GetPixel( void ) const;

When a program needs to query values in the mapped image
the sequence of calls should be like:

    mapper->SetPoint( myInterestPoint );
    if(  mapper->IsPointInside() )
    {
      value = mapper->GetPixel();
      // inside the image, value is valid
    }
    else 
    {
      // outside the image,
      // do something else
    }
 
In this case, GetPixel() can only be called after verifying
that the coordinates fall inside the image under the mapping.
Is the responsibility of the programmer to call the precondition
"IsPointInside()" before calling "GetPixel()" method.

-----


2)  Exception

   The GetPixel() method could throw a particular exception
   when the coordinates are mapped outside the image:

   TPixelType  
   GetPixel( const Point<dimension,double> & coordinates ) 
                                           throws MapperException;
 

   This method will be used like


   try 
   {
     value = mapper->GetPixel( myInterestPoint );
   }
   catch( MapperException & e )
   {
     // coordinates are outside the image,
     // do something else  
   }
     

------

3)  Code Value

  In this case, GetPixel() method returns a particular
  value that can be considered an "error code" or an
  inert value that will not perturbe subsequent computations.

  The problem with this case is that we'll need a kind of
  neutral value defined in the traits of the pixel type.

  the program will do then:

  value = mapper->GetPixel( myInterestPoint );
  if( value == TPixelType::NeutralValue ) 
  {
    // value is invalid...do something else
  }


-----

Options (1) and (2) seems to be a much better choice than
option (3), which is plenty of oportunities to make error
propagate without being noticed.  Options (1) relies in 
the discipline of the programmer to use the precondition. 
Option (2) has the advantage that if the programmer forget... 
the abort provoked by the exception will clearly indicate 
that something is missing.


-------


What do you think should be the appropiated way of 
managing this situation ?


-------

BTW, LinearInterpolateFunction and ImageFunction are using
a pointer to double to pass the coordinates of a point,
like:

    Evaluate( double * ) 

It could be eventually more convenient to use an itkPoint,
which after all is designed to represent coordinates in space.
That will prevent Dimension errors. 

Maybe something like:

    Evaluate( const Point<dimension,double> & )

-----------------


Thanks


Luis