[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
>