1 /*========================================================================= 2 * 3 * Copyright Insight Software Consortium 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0.txt 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 *=========================================================================*/ 18 #ifndef itkProgressAccumulator_h 19 #define itkProgressAccumulator_h 20 21 #include "itkCommand.h" 22 #include "itkProcessObject.h" 23 #include <vector> 24 25 namespace itk 26 { 27 /** 28 * \class ProgressAccumulator 29 * \brief Facilitates progress reporting for filters that wrap around 30 * multiple other filters. 31 * 32 * This object allows a mini-pipeline filters to easily keep track of the 33 * progress performed by the internal filters. 34 * See DiscreteGaussianImageFilter.hxx for an implementation example. 35 * 36 * \sa DiscreteGaussianImageFilter 37 * 38 * \ingroup ITKCommon 39 */ 40 class ITKCommon_EXPORT ProgressAccumulator:public Object 41 { 42 public: 43 /** Standard class type aliases. */ 44 using Self = ProgressAccumulator; 45 using Superclass = Object; 46 using Pointer = SmartPointer< Self >; 47 using ConstPointer = SmartPointer< const Self >; 48 49 /** Typedef for inputting filters */ 50 using GenericFilterType = ProcessObject; 51 using GenericFilterPointer = GenericFilterType::Pointer; 52 53 /** Standard New method. */ 54 itkNewMacro(Self); 55 56 /** Runtime information support. */ 57 itkTypeMacro(ProgressAccumulator, Object); 58 59 /** Get the total progress accumulated by this object */ 60 itkGetConstMacro(AccumulatedProgress, float); 61 62 /** Set the mini-pipeline filter */ 63 itkSetObjectMacro(MiniPipelineFilter, ProcessObject); 64 65 /** Set the mini-pipeline filter */ 66 itkGetModifiableObjectMacro(MiniPipelineFilter, ProcessObject); 67 68 /** 69 * Register a filter with the progress accumulator and specify the 70 * fraction of the overall progress associated with this filter. 71 * The sum of the weights for all filters that are registered should 72 * be 1. 73 * However, if streaming is used, the weight should be divided by the 74 * number of streams because each stream will reset the filter 75 * after capturing its progress. 76 * For example, if the desired weight of a filter is 0.4, but it is 77 * streamed into 4 streams, the weight should be 0.1. 78 * The ProgressAccumulator will then ensure that each of the 4 runs 79 * of this filter will add 0.1 to the filter's progress. 80 */ 81 void RegisterInternalFilter(GenericFilterType *filter, float weight); 82 83 /** 84 * Unregister all filters that have been registered with this object 85 */ 86 void UnregisterAllFilters(); 87 88 /** 89 * \deprecated 90 * Reset the progress accumulator. This method should not be necessary 91 * because this functionality is already present in the filter 92 * constructor. 93 */ 94 #if ! defined ( ITK_LEGACY_REMOVE ) 95 void ResetProgress(); 96 #endif 97 98 /** 99 * \deprecated 100 * Reset the filter progress but keep the accumulated progress. 101 * This method is deprecated because the ProgressAccumulator 102 * now internally checks if a filter has been restarted and updates 103 * the accumulated progress automatically. 104 * This method also used to have the unfortunate side effect of forcing 105 * filters to rerun even if their parameters and input had not changed. 106 * This is because it called SetProgress(0) on the filters, which 107 * triggered a ModifiedTime and thus caused the filters to rerun. 108 * To avoid this behavior, the implementation of this method is now empty. 109 */ 110 #if ! defined ( ITK_LEGACY_REMOVE ) 111 void ResetFilterProgressAndKeepAccumulatedProgress(); 112 #endif 113 114 protected: 115 ProgressAccumulator(); 116 ~ProgressAccumulator() override; 117 void PrintSelf(std::ostream & s, Indent indent) const override; 118 119 private: 120 /** Command for observing progress of pipeline filters */ 121 using CommandType = MemberCommand< Self >; 122 using CommandPointer = CommandType::Pointer; 123 124 /** Structure associated with each filter in the pipeline */ 125 struct FilterRecord { 126 // Pointer to the filter 127 GenericFilterPointer Filter; 128 129 // The weight of the filter in total progress of the mini-pipeline 130 float Weight; 131 132 // The tags for adding/removing observers to mini-pipeline filter 133 unsigned long ProgressObserverTag; 134 unsigned long StartObserverTag; 135 }; 136 137 /** A callback function that is called by the progressing filters */ 138 void ReportProgress(Object *object, const EventObject & event); 139 140 /** The client mini-pipeline filter */ 141 GenericFilterPointer m_MiniPipelineFilter; 142 143 /** An array of record structures */ 144 using FilterRecordVector = std::vector< struct FilterRecord >; 145 146 /** The total accumulated progress */ 147 float m_AccumulatedProgress; 148 149 /** The total accumulated progress for multiple runs of the mini-pipeline */ 150 float m_BaseAccumulatedProgress; 151 152 /** 153 * A list of progress proportions of the different filters in the 154 * pipeline 155 */ 156 FilterRecordVector m_FilterRecord; 157 158 /** The callback command */ 159 CommandPointer m_CallbackCommand; 160 }; 161 } // End namespace itk 162 163 #endif // itkProgressAccumulator_h_ 164