KWStyle - itkProcessObject.h
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkProcessObject.h.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:46 $
7   Version:   $Revision: 1.4 $
8
9   Copyright (c) Insight Software Consortium. All rights reserved.
10   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11
12   Portions of this code are covered under the VTK copyright.
13   See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.
14
15      This software is distributed WITHOUT ANY WARRANTY; without even 
16      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
17 IND *****PURPOSE.  See the above copyright notices for more information.
18
19 =========================================================================*/
20 #ifndef __itkProcessObject_h
21 #define __itkProcessObject_h
22
23 #include "itkObject.h"
24 #include "itkDataObject.h"
25 #include "itkMultiThreader.h"
26 #include "itkObjectFactory.h"
27 #include <vector>
28
29 namespace itk
30 {
31
32 /** \class ProcessObject
33  * \brief ProcessObject is the base class for all process objects (source,
34  *        filters, mappers) in the Insight data processing pipeline.
35  *
36  * ProcessObject is an abstract object that specifies behavior and
37  * interface of network process objects (sources, filters,
38  * mappers). Source objects are creators of visualization data;
39  * filters input, process, and output image data; and mappers
40  * transform data into another form (like transforming coordinates or
41  * writing data to a file).
42  *
43  * A major role of ProcessObject is to define the inputs and outputs
44  * of a filter. More than one input and/or output may exist for a given
45  * filter. Some classes (e.g., source objects or mapper objects) will
46  * not use inputs (the source) or outputs (mappers). In this case, the
47  * inputs or outputs is just ignored.
48  *
49  * ProcessObject invokes the following events: 
50  * Command::StartEvent, Command::EndEvent
51  * These are convenience events you can use for any purpose
52  * (e.g., debugging info, highlighting/notifying user interface, etc.) 
53  * See Command and LightObject for information on using AddObserver.
54  *
55  * Another event Command::ProgressEvent can be observed. Some filters invoke
56  * this event periodically during their execution (with the progress,
57  * parameter, the fraction of work done). The use is similar to that of
58  * StartEvent and EndEvent. Filters may also check their
59  * AbortGenerateData flag to determine whether to prematurally end their
60  * execution.
61  *
62  * An important feature of subclasses of ProcessObject is that it is
63  * possible to control the memory-management model (i.e., retain
64  * output versus delete output data). The ReleaseDataFlag enables the
65  * deletion of the output data once the downstream process object
66  * finishes processing the data (please see text). The
67  * ReleaseDataBeforeUpdateFlag enables the deletion of the
68  * ProcessObject's output data from a previous update if that output
69  * data is slated to be regenerated by the pipeline process.  Setting
70  * this flag can control peak memory usage during a subsequent
71  * pipeline update.  For a ProcessObject, the ReleaseDataFlag defaults
72  * to false and the ReleaseDataBeforeUpdateFlag defaults to true.
73  * Some subclasses of ProcessObject, for example ImageSource, use a
74  * default setting of false for the ReleaseDataBeforeUpdateFlag.
75  *
76  * Subclasses of ProcessObject may override 4 of the methods of this class
77  * to control how a given filter may interact with the pipeline (dataflow).
78  * These methods are: GenerateOutputInformation(),
79  * EnlargeOutputRequestedRegion(), GenerateInputRequestedRegion(), and
80  * GenerateOutputRequestedRegion(). By overriding these methods, a filter
81  * can deviate from the base assumptions of the pipeline execution model.
82  *
83  * \ingroup ITKSystemObjects
84  * \ingroup DataProcessing 
85  *       
86  */
87 class ITKCommon_EXPORT ProcessObject : public Object
88 {
89 public:
90   /** Standard class typedefs. */
91   typedef ProcessObject       Self;
92 TDA   typedef Object  Superclass;
93   typedef SmartPointer<Self>  Pointer;
94 TDA   typedef SmartPointer<const Self>  ConstPointer;
95   
96   /** Run-time type information (and related methods). */
97   itkTypeMacro(ProcessObject,Object);
98
99   /** Smart Pointer type to a DataObject. */
100   typedef DataObject::Pointer DataObjectPointer;
101
102   /** STL Array of SmartPointers to DataObjects */
103   typedef std::vector<DataObjectPointer> DataObjectPointerArray;
104
105   /** Return an array with all the inputs of this process object.
106    * This is useful for tracing back in the pipeline to construct
107    * graphs etc.  */
108   DataObjectPointerArray& GetInputs() 
109     {return m_Inputs;}
110
111   /** Get the size of the input vector.  This is merely the size of
112    * the input vector, not the number of inputs that have valid
113    * DataObject's assigned. Use GetNumberOfValidRequiredInputs() to
114    * determine how many inputs are non-null. */
115   std::vector<DataObjectPointer>::size_type GetNumberOfInputs() const
116     {return m_Inputs.size();}
117
118   /** Get the number of valid inputs.  This is the number of non-null
119    * entries in the input vector in the first NumberOfRequiredInputs
120    * slots. This method is used to determine whether the necessary
121    * required inputs have been set. Subclasses of ProcessObject may
122    * override this implementation if the required inputs are not
123    * the first slots in input vector.
124    */
125 LEN   virtual std::vector<DataObjectPointer>::size_type GetNumberOfValidRequiredInputs() const;
126   
127   /** Return an array with all the outputs of this process object.
128    * This is useful for tracing forward in the pipeline to contruct
129    * graphs etc.  */
130   DataObjectPointerArray& GetOutputs()
131     { return m_Outputs; }
132   std::vector<DataObjectPointer>::size_type GetNumberOfOutputs() const
133     {return m_Outputs.size();}
134       
135   /** Set the AbortGenerateData flag for the process object. Process objects
136    *  may handle premature termination of execution in different ways.  */
137   itkSetMacro(AbortGenerateData,bool);
138
139   /** Get the AbortGenerateData flag for the process object. Process objects
140    *  may handle premature termination of execution in different ways.  */
141   itkGetConstReferenceMacro(AbortGenerateData,bool);
142   
143   /** Turn on and off the AbortGenerateData flag. */
144   itkBooleanMacro(AbortGenerateData); 
145   
146   /** Set the execution progress of a process object. The progress is
147    * a floating number in [0,1] with 0 meaning no progress and 1 meaning
148    * the filter has completed execution.  The ProgressEvent is NOT
149    * invoked. */
150   itkSetClampMacro(Progress,float,0.0,1.0);
151
152   /** Get the execution progress of a process object. The progress is
153    * a floating number in [0,1] with 0 meaning no progress and 1 meaning
154    * the filter has completed execution. */
155   itkGetConstReferenceMacro(Progress,float);
156
157   /** Update the progress of the process object.
158    *
159    * Sets the Progress ivar to amount and invokes any observers for
160    * the ProgressEvent. The parameter amount should be in [0,1] and is
161    * the cumulative (not incremental) progress. */
162   void UpdateProgress(float amount);
163   
164   /** Bring this filter up-to-date. Update() checks modified times against
165    * last execution times, and re-executes objects if necessary. A side
166    * effect of this method is that the whole pipeline may execute
167    * in order to bring this filter up-to-date. This method updates the
168    * currently prescribed requested region.  If no requested region has
169    * been set on the output, then the requested region will be set to the
170    * largest possible region. Once the requested region is set, Update()
171    * will make sure the specified requested region is up-to-date. This
172    * is a confusing side effect to users who are just calling Update() on
173    * a filter.  A first call to Update() will cause the largest possible
174    * region to be updated.  A second call to Update() will update that
175    * same region.  If a modification to the upstream pipeline cause a
176    * filter to have a different largest possible region, this second
177    * call to Update() will not cause the output requested region to be
178    * reset to the new largest possible region.  Instead, the output requested
179    * region will be the same as the last time Update() was called. To have
180    * a filter always to produce its largest possible region, users should
181    * call UpdateLargestPossibleRegion() instead. */
182   virtual void Update();
183
184   /** Like Update(), but sets the output requested region to the
185    * largest possible region for the output.  This is the method users
186    * should call if they want the entire dataset to be processed.  If
187    * a user wants to update the same output region as a previous call
188    * to Update() or a previous call to UpdateLargestPossibleRegion(), 
189    * then they should call the method Update(). */
190   virtual void UpdateLargestPossibleRegion();
191
192   /** Update the information decribing the output data. This method
193    * transverses up the pipeline gathering modified time information.
194    * On the way back down the pipeline, this method calls
195    * GenerateOutputInformation() to set any necessary information
196    * about the output data objects.  For instance, a filter that
197    * shrinks an image will need to provide an implementation for
198    * GenerateOutputInformation() that changes the spacing of the
199    * pixels. Such filters should call their superclass' implementation
200    * of GenerateOutputInformation prior to changing the information
201    * values they need (i.e. GenerateOutputInformation() should call
202    * Superclass::GenerateOutputInformation() prior to changing the
203    * information. */
204   virtual void UpdateOutputInformation();
205
206   /** Send the requested region information back up the pipeline (to the
207    * filters that preceed this one). */
208   virtual void PropagateRequestedRegion(DataObject *output);
209
210   /** Actually generate new output  */
211   virtual void UpdateOutputData(DataObject *output);
212
213
214   /** Give the process object a chance to indictate that it will produce more
215    * output than it was requested to produce. For example, many imaging
216    * filters must compute the entire output at once or can only produce output
217    * in complete slices. Such filters cannot handle smaller requested regions.
218    * These filters must provide an implementation of this method, setting
219    * the output requested region to the size they will produce.  By default,
220 LEN    * a process object does not modify the size of the output requested region. */
221   virtual void EnlargeOutputRequestedRegion(DataObject *itkNotUsed(output)){};
222   
223
224   /** Reset the pipeline. If an exception is thrown during an Update(),
225    * the pipeline may be in an inconsistent state.  This method clears
226    * the internal state of the pipeline so Update() can be called. */
227   virtual void ResetPipeline();
228
229   /** Make a DataObject of the correct type to used as the specified
230    * output.  Every ProcessObject subclass must be able to create a
231    * DataObject that can be used as a specified output. This method
232    * is automatically called when DataObject::DisconnectPipeline() is
233    * called.  DataObject::DisconnectPipeline, disconnects a data object
234    * from being an output of its current source.  When the data object
235    * is disconnected, the ProcessObject needs to construct a replacement
236    * output data object so that the ProcessObject is in a valid state.
237    * So DataObject::DisconnectPipeline eventually calls
238    * ProcessObject::MakeOutput. Note that MakeOutput always returns a
239    * itkSmartPointer to a DataObject. ImageSource and MeshSource override
240    * this method to create the correct type of image and mesh respectively.
241    * If a filter has multiple outputs of different types, then that
242    * filter must provide an implementation of MakeOutput(). */
243   virtual DataObjectPointer MakeOutput(unsigned int idx);
244   
245   /** Turn on/off the flags to control whether the bulk data belonging
246    * to the outputs of this ProcessObject are released after being
247    * used by a downstream ProcessObject. Default value is off. Another
248    * options for controlling memory utilization is the
249    * ReleaseDataBeforeUpdateFlag. */
250   virtual void SetReleaseDataFlag(bool flag);
251   virtual bool GetReleaseDataFlag() const;
252   void ReleaseDataFlagOn() {this->SetReleaseDataFlag(true);}
253   void ReleaseDataFlagOff() {this->SetReleaseDataFlag(false);}
254
255   /** Turn on/off the flags to control whether the bulk data belonging
256    * to the outputs of this ProcessObject are released/reallocated
257    * during an Update().  In limited memory scenarios, a user may want
258    * to force the elements of a pipeline to release any bulk data that
259    * is going to be regenerated anyway during an Update() in order to
260    * control peak memory allocation. Note that this flag is different
261    * from the ReleaseDataFlag. ReleaseDataFlag manages the
262    * deallocation of a ProcessObject's bulk output data once that data
263    * has been consumed by a downstream ProcessObject.  The
264    * ReleaseDataBeforeUpdateFlag manages the deallocation/reallocation
265    * of bulk data during a pipeline update to control peak memory
266    * utilization. Default value is on. */
267   itkSetMacro(ReleaseDataBeforeUpdateFlag, bool);
268   itkGetConstReferenceMacro(ReleaseDataBeforeUpdateFlag, bool);
269   itkBooleanMacro(ReleaseDataBeforeUpdateFlag);
270    
271   
272   /** Get/Set the number of threads to create when executing. */
273   itkSetClampMacro( NumberOfThreads, int, 1, ITK_MAX_THREADS );
274   itkGetConstReferenceMacro( NumberOfThreads, int );
275   
276   /** Return the multithreader used by this class. */
277   MultiThreader * GetMultiThreader()
278     {return m_Threader;}
279
280   /** An opportunity to deallocate a ProcessObject's bulk data
281    *  storage. Some filters may wish to reuse existing bulk data
282    *  storage to avoid unnecessary deallocation/allocation
283    *  sequences. The default implementation calls Initialize() on each
284    *  output. DataObject::Initialize() frees its bulk data by default.
285    */
286   virtual void PrepareOutputs();
287
288 protected:
289   ProcessObject();
290   ~ProcessObject();
291   void PrintSelf(std::ostream& os, Indent indent) const;
292   
293   /** Protected methods for setting inputs.
294    * Subclasses make use of them for setting input. */
295   virtual void SetNthInput(unsigned int num, DataObject *input);
296   virtual void AddInput(DataObject *input);
297   virtual void RemoveInput(DataObject *input);
298   itkSetMacro(NumberOfRequiredInputs,unsigned int);
299   itkGetConstReferenceMacro(NumberOfRequiredInputs,unsigned int);
300   
301   /** Called to allocate the input array. Copies old inputs. */
302   void SetNumberOfInputs(unsigned int num);
303
304   /** Method used internally for getting an input. */
305   DataObject * GetInput(unsigned int idx);
306   const DataObject * GetInput(unsigned int idx) const;
307
308   /** Protected methods for setting outputs.
309    * Subclasses make use of them for getting output. */
310   virtual void SetNthOutput(unsigned int num, DataObject *output);
311   virtual void AddOutput(DataObject *output);
312   virtual void RemoveOutput(DataObject *output);
313   itkSetMacro(NumberOfRequiredOutputs,unsigned int);
314   itkGetConstReferenceMacro(NumberOfRequiredOutputs,unsigned int);
315
316   /** Called to allocate the output array.  Copies old outputs. */
317   void SetNumberOfOutputs(unsigned int num);
318
319   /** Method used internally for getting an output. */
320   DataObject * GetOutput(unsigned int idx);
321   const DataObject * GetOutput(unsigned int idx) const;
322
323   /** What is the input requested region that is required to produce the
324    * output requested region? By default, the largest possible region is
325    * always required but this is overridden in many subclasses. For instance,
326    * for an image processing filter where an output pixel is a simple function
327    * of an input pixel, the input requested region will be set to the output
328    * requested region.  For an image processing filter where an output pixel
329    * is a function of the pixels in a neighborhood of an input pixel, then
330    * the input requested region will need to be larger than the output
331    * requested region (to avoid introducing artificial boundary conditions).
332    * This function should never request an input region that is outside the
333    * the input largest possible region (i.e. implementations of this method
334    * should crop the input requested region at the boundaries of the input
335    * largest possible region). */
336   virtual void GenerateInputRequestedRegion();
337   
338   /** Given one output whose requested region has been set, how should
339    * the requested regions for the remaining outputs of the process object
340    * be set?  By default, all the outputs are set to the same requested
341    * region.  If a filter needs to produce different requested regions
342    * for each output, for instance an image processing filter producing
343    * several outputs at different resolutions, then that filter may
344    * override this method and set the requested regions appropriatedly.
345    *
346    * Note that a filter producing multiple outputs of different types is
347    * required to override this method.  The default implementation
348    * can only correctly handle multiple outputs of the same type. */
349   virtual void GenerateOutputRequestedRegion(DataObject *output);
350
351   /** Generate the information decribing the output data. The default 
352    * implementation of this method will copy information from the input to
353    * the output.  A filter may override this method if its output will have
354    * different information than its input.  For instance, a filter that 
355    * shrinks an image will need to provide an implementation for this 
356    * method that changes the spacing of the pixels. Such filters should call
357    * their superclass' implementation of this method prior to changing the
358    * information values they need (i.e. GenerateOutputInformation() should
359    * call Superclass::GenerateOutputInformation() prior to changing the
360    * information. */
361   virtual void GenerateOutputInformation();
362   
363   /** This method causes the filter to generate its output. */
364   virtual void GenerateData() {}
365
366   /** Called to allocate the input array.  Copies old inputs. */
367   /** Propagate a call to ResetPipeline() up the pipeline. Called only from
368    * DataObject. */
369   virtual void PropagateResetPipeline();
370
371   /** A filter may need to release its input's bulk data after it has
372    * finished calculating a new output. The filter may need to release
373    * the inputs because the user has turned on the ReleaseDataFlag or
374    * it may need to release the inputs because the filter is an "in
375    * place" filter and it has overwritten its input with its output
376    * data.  The implementation here simply checks the ReleaseDataFlag
377    * of the inputs.  InPlaceImageFilter overrides this method so
378    * release the input it has overwritten.
379    *
380    * \sa InPlaceImageFilter::ReleaseInputs()
381    */
382   virtual void ReleaseInputs();
383
384   /**
385    * Cache the state of any ReleaseDataFlag's on the inputs. While the
386    * filter is executing, we need to set the ReleaseDataFlag's on the
387    * inputs to false in case the current filter is implemented using a
388    * mini-pipeline (which will try to release the inputs).  After the
389    * filter finishes, we restore the state of the ReleaseDataFlag's
390    * before the call to ReleaseInputs().
391    */
392   virtual void CacheInputReleaseDataFlags();
393
394   /**
395    * Restore the cached input ReleaseDataFlags.
396    */
397   virtual void RestoreInputReleaseDataFlags();
398   
399   /** These ivars are made protected so filters like itkStreamingImageFilter
400    * can access them directly. */
401   
402   /** This flag indicates when the pipeline is executing.
403    * It prevents infinite recursion when pipelines have loops. */
404   bool m_Updating;
405
406   /** Time when GenerateOutputInformation was last called. */
407   TimeStamp m_OutputInformationMTime;
408
409 private:
410   ProcessObject(const Self&); //purposely not implemented
411   void operator=(const Self&); //purposely not implemented
412
413   /** An array of the inputs to the filter. */
414   std::vector<DataObjectPointer> m_Inputs;
415   unsigned int m_NumberOfRequiredInputs;
416
417   /** An array that caches the ReleaseDataFlags of the inputs */
418   std::vector<bool> m_CachedInputReleaseDataFlags;
419   
420   /** An array of the outputs to the filter. */
421   std::vector<DataObjectPointer> m_Outputs;
422   unsigned int m_NumberOfRequiredOutputs;
423   
424   /** These support the progress method and aborting filter execution. */
425   bool  m_AbortGenerateData;
426   float m_Progress;
427   
428   /** Support processing data in multiple threads. Used by subclasses
429    * (e.g., ImageSource). */
430   MultiThreader::Pointer m_Threader;
431   int m_NumberOfThreads;
432
433   /** Memory management ivars */
434   bool m_ReleaseDataBeforeUpdateFlag;
435   
436   /** Friends of ProcessObject */
437   friend class DataObject;
438 };
439
440 // end namespace itk
441
442 #endif
443
444 EOF

Generated by KWStyle 1.0b on Tuesday January,17 at 02:14:39PM
© Kitware Inc.