[Insight-developers] Progress reporting revisited

Luis Ibanez luis . ibanez at kitware . com
Fri, 23 May 2003 10:04:36 -0400


Hi Kurt,

You are right, we probably will have to do a full review of the
filters in the same way that the code coverage is being done.

The ProgressReporter was designed to work fine in multi-threaded
filters but... wasn't tested much. So, it is certainly possible
that you just identified a bug on it.


Could you please log a bug in GNAT for the progress reporter ?
(assign it to me)


I agree with you in that progress reporting is fundamental for
integrating ITK with real applications. We have hit exactly the
same issues with the VolView plugins.


    Luis


---------------------
Kurt Augustine wrote:
> We have integrated a number of filters in Analyze and incorporated progress
> reporting windows that also allow the user to cancel the process if desired.
> While the filtering process itself seems to work correctly in all cases, the
> same cannot be said for the progress reporting.  This, of course, is not a
> new issue but I thought I would give specifics in the hope that they can be
> fixed.  The assumption here is that we should be able to handle all progress
> reporting the same, regardless of the filter.  Here is what we did:
> 
> We instantiate a filter, say ZeroCrossingBasedEdgeDetection and then
> instantiate a class we designed called FilterObserver, with the filter as
> the only parameter.
> 
> typename itk::DanielssonDistanceMapImageFilter<itk::Image<T, 3 >,
> itk::Image<T, 3 > >::Pointer myFilter =
> itk::DanielssonDistanceMapImageFilter<itk::Image<T, 3 >, itk::Image<T, 3 >
> 
>>::New();
> 
> FilterObserver watch(myFilter);
>    ...
>    ...
> myFilter->Update();
>    ...
> 
> 
> Here is FilterObserver:
> FilterObserver::FilterObserver(itk::ProcessObject* o)
>   {
>   m_Process = o;
>   itk::SimpleMemberCommand<FilterObserver>::Pointer startFilterCommand;
>   itk::SimpleMemberCommand<FilterObserver>::Pointer endFilterCommand;
>   itk::SimpleMemberCommand<FilterObserver>::Pointer progressFilterCommand;
> 
>   startFilterCommand =    itk::SimpleMemberCommand<FilterObserver>::New();
>   endFilterCommand =      itk::SimpleMemberCommand<FilterObserver>::New();
>   progressFilterCommand = itk::SimpleMemberCommand<FilterObserver>::New();
> 
>   startFilterCommand->SetCallbackFunction(this,
> &FilterObserver::StartFilter);
>   endFilterCommand->SetCallbackFunction(this, &FilterObserver::EndFilter);
>   progressFilterCommand->SetCallbackFunction(this,
> &FilterObserver::ShowProgress);
>   m_Process->AddObserver(itk::StartEvent(), startFilterCommand);
>   m_Process->AddObserver(itk::EndEvent(), endFilterCommand);
>   m_Process->AddObserver(itk::ProgressEvent(), progressFilterCommand);
>   }
> 
> void FilterObserver::ShowProgress()
>   {
>     if(!someProgressReporterFunction((int)(m_Process->GetProgress()*100)))
>     {
> 	    m_Process->AbortGenerateDataOn(); // clean up and return
> 	    return;
>     }
> 
>   }
> void FilterObserver::StartFilter()
>   {
> 		someProgressReporterFunction(0);
>   }
> 
> void FilterObserver::EndFilter()
>   {
> 		someProgressReporterFunction(100);
>   }
> 
> Where "someProgressReporterFunction(int percent)" can be some function that
> reports progress to the user.
> 
> Now, this approach works well for some filters, namely:
> itkBinaryMinMaxCurvatureFlowImageFilter
> itkBinomialBlurImageFilter
> itkCurvatureAnisotropicDiffusionImageFilter
> itkCurvatureFlowImageFilter
> itkDanielssonDistanceMapImageFilter
> itkGradientAnisotropicDiffusionImageFilter
> itkGradientMagnitudeImageFilter
> itkMinMaxCurvatureFlowImageFilter
> 
> While others it does not work for:
> itkBSplineDecompositionImageFilter
> itkDerivativeImageFilter
> itkDiscreteGaussianImageFilter
> itkGradientMagnitudeRecursiveGaussianImageFilter
> itkZeroCrossingBasedEdgeDetectionImageFilter
> 
> Some interesting notes that may help in determining problems:  It appears
> that only two of the filters from the first list use the ProgressReporter
> class and make calls to CompletedPixel().  Most of the rest from the first
> list are derived from itkFiniteDiferenceImageFilter, which simply makes
> calls to InvokeEvent, specifically this->InvokeEvent(IterationEvent())
> followed by this->InvokeEvent(ProgressEvent()).
> 
> Three out of the five that do NOT work implement the ProgressReporter class
> and are multithreaded.  
> 
> So, in general,  it appears that ProgressReporter may have problems with
> multithreaded filters (although, one multithreaded case, namely
> itkGradientMagnitudeImageFilter appears to work fine).  
> 
> Bottom line, ITK filters do not implement progress reporting in a consistent
> manner and the chosen report mechanisms do not function at all in some
> cases.  As application developers, we obviously need to provide interfaces
> that work in a consistent manner.  Therefore, we turn to the filter
> developers to help fix the progress reporting bugs (Bill's "code coverage
> list" will maybe help identify who).  There certainly may be additional
> filters beyond those listed that have the same problem.  We realize this may
> seem like a low priority item on some developers' lists but these fixes are
> essential to the successful integration of ITK with end-user applications.
> 
> Perhaps we can discuss this briefly in the tcon tomorrow.
> 
> Thanks (and sorry for the long message) ... Kurt
> _______________________________________________
> Insight-developers mailing list
> Insight-developers at public . kitware . com
> http://public . kitware . com/mailman/listinfo/insight-developers
>