[Insight-developers] Is this right? -- beefed up GetOutput() doc

Miller, James V (Research) millerjv@crd.ge.com
Tue, 11 Feb 2003 15:00:21 -0500


See comments below

> -----Original Message-----
> From: Mark Foskey [mailto:mark_foskey@unc.edu]
> Sent: Tuesday, February 11, 2003 1:56 PM
> To: Miller, James V (Research)
> Subject: Re: [Insight-developers] Is this right? -- beefed up
> GetOutput() doc
> 
> 
> Miller, James V (Research) wrote:
> > Mark,
> > 
> > Your description is on the mark except the following...
> > 
> >     * (This pipelining method is preferred where feasible since it
> >     * permits more efficient use of memory and other resources.)
> >  
> > It turns out all the three examples in your description use the same
> > amount of memory and resources (within the size of the meta 
> data in an
> > image which is pretty darn small).
> 
> OK, but what about streaming?  To be more precise (which 
> maybe I needed 
> to do in the doc), I was under the impression that
> 
>    image = someFilter->GetOutput();
>    image->Update();
>    anotherFilter->SetInput( image );
>    anotherFilter->Update();
> 
> would perform worse than
> 
>    anotherFilter->SetInput( someFilter->GetOutput() );
>    anotherFilter->Update();
> 
> at least if streaming was going on.  But there are a lot of things I 
> don't know about streaming:

If the filters are not streaming data, then the penalty for multiple calls
to Update() is that the execution model must search up the pipeline to determine modified times and
define regions.  This penalty is very small in comparison 
to the time for a filter to execute.

If the filters can stream, then in the first case, everything above "someFilter"
will stream, then "anotherFilter" will operate on its output.  So in this case, things may not be as
efficient as it could be.  Note that streaming can be
controlled using the StreamingImageFilter, which you would normally place
at the end of your pipeline.  We have had discussions on have the image writers
implicitly use a StreamingImageFilter internally so that calling Write() or 
Update() on a filter would stream data.  Otherwise, the StreamingImageFilter 
must be used to force streaming.


> 
> * Is it implemented?  It is, isn't it?
> 
> * Does it happen automatically for large enough images, or do 
> programmers have to do something special?
> 
> * How is affected by choices such as the above code samples?
> 
> The Doxygen page on streaming
> 
>    http://www.itk.org/Doxygen/html/StreamingPage.html
> 
> is evocative but not helpful in answering these questions.

See the above.  The programmer must use a StreamingImageFilter to
force streaming to occur.  

> 
> > 
> > Perhaps this would be a good place to discuss how someone 
> can request
> > a particular portion of an image be updated.
> > 
> >    image = someFilter->GetOutput();
> >    image->SetRequestedRegion( someRegion );
> >    image->Update();
> > 
> 
> Yes.  I'll do that.  It may be worth explaining exactly what one gets 
> when one does this.  My understanding is that, after the above lines,
> 
> * image->GetRequestedRegion() returns someRegion
> * image->GetLargestPossibleRegion() returns the original LPR
> * image->GetBufferedRegion() returns a region no bigger than 
> someRegion, describing which image data is actually in memory.
> 
> Is this right?

GetLargestPossibleRegion() returns the largest possible region as of the 
last call to Update().  Another call to Update() could change the
LargestPossibleRegion (for instance if a user changes the ShrinkFactors
on an upstream ShrinkFilter, then the LargestPossibleRegion will change).

GetRequestedRegion() returns the region defining the last request (or the
request that you are in the process of making).

GetBufferedRegion() returns a region describing the size on an image in
memory.

For a valid image in the pipeline, 

RequestedRegion <= BufferedRegion <= LargestPossibleRegion

For an image that is about to be updated, where the user does

someFilter->GetOutput()->SetRequestedRegion(someRegion);
someFilter->Update();

there is no real relationship between the regions immediately after
the SetRequestedRegion() call and before the call to Update().  At that point
the user/pipeline is setting a request and until the pipeline executes 
the LargestPossibleRegion and BufferedRegion are inconsequential.  However, 
immediately after the call to Update(), the above relationship holds

RequestedRegion <= BufferedRegion <= LargestPossibleRegion





> 
> > 
> > 
> > 
> >>-----Original Message-----
> >>From: Mark Foskey [mailto:mark_foskey@unc.edu]
> >>Sent: Tuesday, February 11, 2003 11:26 AM
> >>To: insight-developers@public.kitware.com
> >>Subject: [Insight-developers] Is this right? -- beefed up 
> GetOutput()
> >>doc
> >>
> >>
> >>I needed to access some image information partway through a 
> pipeline, 
> >>and it took me a while to settle on the proper way to do that.  I 
> >>thought it would help clarify things if the GetOutput() 
> documentation 
> >>were more detailed.  I wrote up the following, but since the 
> >>dashboard 
> >>won't catch any factual errors, I thought I'd post this 
> >>before checking 
> >>it in.  (The fact that I feel the need to seek confirmation 
> >>argues that 
> >>the documentation would be useful.)
> >>
> >>The User's Guide was helpful in this, but I thought this 
> information 
> >>ought to be available from the doxygen docs as well.
> >>
> >>   /** Get the output data of this process object.  The 
> output of this
> >>    * function is not valid until an appropriate Update() method has
> >>    * been called, either explicitly or implicitly.  Both the filter
> >>    * itself and the image object have Update() methods, and both
> >>    * methods update the image data.  Here are three ways to use
> >>    * GetOutput() and make sure the image data is valid.  In these
> >>    * examples, \a image is a pointer to some Image object, and the
> >>    * particular ProcessObjects involved are filters.
> >>    *
> >>    * \code
> >>    *   anotherFilter->SetInput( someFilter->GetOutput() );
> >>    *   anotherFilter->Update();
> >>    * \endcode
> >>    * (This pipelining method is preferred where feasible since it
> >>    * permits more efficient use of memory and other resources.)
> >>    *
> >>    * \code
> >>    *   image = someFilter->GetOutput();
> >>    *   image->Update();
> >>    * \endcode
> >>    *
> >>    * \code
> >>    *   someFilter->Update();
> >>    *   image = someFilter->GetOutput();
> >>    * \endcode
> >>    * (In the above example, the two lines of code can be in
> >>    * either order.)
> >>    *
> >>    * Note that Update() is not called automatically except within a
> >>    * pipeline as in the first example.
> >>    */
> >>
> >>
> >>-- 
> >>Mark Foskey    (919) 843-5436  Computer-Aided Diagnosis and 
> >>Display Lab
> >>mark_foskey@unc.edu            Department of Radiology, CB 7515, UNC
> >>http://www.cs.unc.edu/~foskey  Chapel Hill, NC  27599-7515
> >>
> >>_______________________________________________
> >>Insight-developers mailing list
> >>Insight-developers@public.kitware.com
> >>http://public.kitware.com/mailman/listinfo/insight-developers
> >>
> > 
> > _______________________________________________
> > Insight-developers mailing list
> > Insight-developers@public.kitware.com
> > http://public.kitware.com/mailman/listinfo/insight-developers
> 
> 
> -- 
> Mark Foskey    (919) 843-5436  Computer-Aided Diagnosis and 
> Display Lab
> mark_foskey@unc.edu            Department of Radiology, CB 7515, UNC
> http://www.cs.unc.edu/~foskey  Chapel Hill, NC  27599-7515
>