Medical Imaging Interaction Toolkit  2026.06.00
Medical Imaging Interaction Toolkit
mitkNonBlockingAlgorithm.h
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #ifndef mitkNonBlockingAlgorithm_h
14 #define mitkNonBlockingAlgorithm_h
15 
17 #include <itkImage.h>
18 #include <itkMacro.h>
19 #include <itkObjectFactory.h>
20 
21 #include <mitkCommon.h>
22 #include <mitkDataStorage.h>
23 #include <mitkProperties.h>
24 #include <mitkPropertyList.h>
26 #include <mitkWeakPointer.h>
27 
28 #include <mitkImage.h>
29 #include <mitkSurface.h>
30 
31 #include <mutex>
32 #include <stdexcept>
33 #include <string>
34 
38 #define mitkAlgorithmNewMacro(classname) \
39  \
40 static Pointer \
41  New(void) \
42  { \
43  classname *rawPtr = new classname(); \
44  Pointer smartPtr = rawPtr; \
45  rawPtr->UnRegister(); \
46  rawPtr->Initialize(); \
47  return smartPtr; \
48  \
49 } \
50  \
51 virtual::itk::LightObject::Pointer \
52  CreateAnother(void) const override \
53  \
54 { \
55  Pointer smartPtr = classname::New(); \
56  ::itk::LightObject::Pointer lightPtr = smartPtr.GetPointer(); \
57  smartPtr->Initialize(this); \
58  return lightPtr; \
59  \
60 }
61 
62 namespace mitk
63 {
87  {
88  public:
90 
95  void SetDataStorage(DataStorage &storage);
96 
102 
103  // parameter setting
104 
111  template <typename T>
112  void SetParameter(const char *parameter, const T &value)
113  {
114  // MITK_INFO << "SetParameter(" << parameter << ") " << typeid(T).name() << std::endl;
115  // m_ParameterListMutex->Lock();
116  m_Parameters->SetProperty(parameter, GenericProperty<T>::New(value));
117  // m_ParameterListMutex->Unlock();
118  }
119 
126  template <typename T>
127  void SetPointerParameter(const char *parameter, const itk::SmartPointer<T> &value)
128  {
129  // MITK_INFO << this << "->SetParameter smartpointer(" << parameter << ") " << typeid(itk::SmartPointer<T>).name()
130  // << std::endl;
131  m_ParameterListMutex.lock();
132  m_Parameters->SetProperty(parameter, SmartPointerProperty::New(value.GetPointer()));
133  m_ParameterListMutex.unlock();
134  }
135  // virtual void SetParameter( const char*, mitk::BaseProperty* ); // for "number of iterations", ...
136  // create some property observing to inform algorithm object about changes
137  // perhaps some TriggerParameter(string) macro that creates an observer for changes in a specific property like
138  // "2ndPoint" for LineAlgorithms
139 
148  void SetPointerParameter(const char *parameter, BaseData *value);
149 
160  template <typename TPixel, unsigned int VImageDimension>
161  void SetItkImageAsMITKImagePointerParameter(const char *parameter, itk::Image<TPixel, VImageDimension> *itkImage)
162  {
163  // MITK_INFO << "SetParameter ITK image(" << parameter << ") " << typeid(itk::Image<TPixel,
164  // VImageDimension>).name() << std::endl;
165  // create an MITK image for that
166  mitk::Image::Pointer mitkImage = mitk::Image::New();
167  mitkImage = ImportItkImage(itkImage);
168  SetPointerParameter(parameter, mitkImage);
169  }
170 
181  template <typename TPixel, unsigned int VImageDimension>
182  void SetItkImageAsMITKImagePointerParameter(const char *parameter,
183  const itk::SmartPointer<itk::Image<TPixel, VImageDimension>> &itkImage)
184  {
185  // MITK_INFO << "SetParameter ITK image(" << parameter << ") " << typeid(itk::SmartPointer<itk::Image<TPixel,
186  // VImageDimension> >).name() << std::endl;
187  // create an MITK image for that
188  mitk::Image::Pointer mitkImage = mitk::Image::New();
189  mitkImage = ImportItkImage(itkImage);
190  SetPointerParameter(parameter, mitkImage);
191  }
192 
200  template <typename T>
201  void GetParameter(const char *parameter, T &value) const
202  {
203  // MITK_INFO << "GetParameter normal(" << parameter << ") " << typeid(T).name() << std::endl;
204  // m_ParameterListMutex->Lock();
205  BaseProperty *p = m_Parameters->GetProperty(parameter);
206  GenericProperty<T> *gp = dynamic_cast<GenericProperty<T> *>(p);
207  if (gp)
208  {
209  value = gp->GetValue();
210  // m_ParameterListMutex->Unlock();
211  return;
212  }
213  // m_ParameterListMutex->Unlock();
214 
215  std::string error("There is no parameter \"");
216  error += parameter;
217  error += '"';
218  throw std::invalid_argument(error);
219  }
220 
228  template <typename T>
229  void GetPointerParameter(const char *parameter, itk::SmartPointer<T> &value) const
230  {
231  // MITK_INFO << this << "->GetParameter smartpointer(" << parameter << ") " << typeid(itk::SmartPointer<T>).name()
232  // << std::endl;
233  // m_ParameterListMutex->Lock();
234  BaseProperty *p = m_Parameters->GetProperty(parameter);
235  if (p)
236  {
237  SmartPointerProperty *spp = dynamic_cast<SmartPointerProperty *>(p);
238  if (spp)
239  {
240  T *t = dynamic_cast<T *>(spp->GetSmartPointer().GetPointer());
241  value = t;
242  // m_ParameterListMutex->Unlock();
243  return;
244  }
245  }
246  // m_ParameterListMutex->Unlock();
247 
248  std::string error("There is no parameter \"");
249  error += parameter;
250  error += '"';
251  throw std::invalid_argument(error);
252  }
253 
259  virtual void Reset();
260 
269 
276 
281 
289  void TriggerParameterModified(const itk::EventObject & event);
290 
295  void ThreadedUpdateSuccessful(const itk::EventObject & event);
296 
301  void ThreadedUpdateFailed(const itk::EventObject & event);
302 
303  protected:
304  NonBlockingAlgorithm(); // use smart pointers
306 
307  void DefineTriggerParameter(const char *);
308  void UnDefineTriggerParameter(const char *);
309 
310  virtual void Initialize(const NonBlockingAlgorithm *other = nullptr);
311  virtual bool ReadyToRun();
312 
313  virtual bool ThreadedUpdateFunction(); // will be called from a thread after calling StartAlgorithm
314  virtual void ThreadedUpdateSuccessful(); // will be called after the ThreadedUpdateFunction() returned
315  virtual void ThreadedUpdateFailed(); // will when ThreadedUpdateFunction() returns false
316 
317  PropertyList::Pointer m_Parameters;
318 
320 
321  private:
322  static void StaticNonBlockingAlgorithmThread(NonBlockingAlgorithm* algorithm);
323 
324  typedef std::map<std::string, unsigned long> MapTypeStringUInt;
325 
326  MapTypeStringUInt m_TriggerPropertyConnections;
327 
328  std::mutex m_ParameterListMutex;
329 
330  int m_UpdateRequests;
331  std::thread m_Thread;
332 
333  bool m_KillRequest;
334  };
335 
336 } // namespace
337 
339 
340 #endif
#define MITKALGORITHMSEXT_EXPORT
Base class of all data objects.
Definition: mitkBaseData.h:60
Abstract base class for properties.
Abstract data management class that organizes DataNode objects in a directed acyclic graph.
Template class for generating properties for simple value types (int, float, bool,...
virtual T GetValue() const
Get the property value.
static Pointer New()
Base class for algorithms that can run in a background thread.
void ThreadedUpdateFailed(const itk::EventObject &event)
GUI-thread callback when the threaded update fails.
void GetParameter(const char *parameter, T &value) const
Get a parameter of any normal (value) type.
virtual void Reset()
Reset the algorithm to its initial state.
WeakPointer< DataStorage > m_DataStorage
virtual void ThreadedUpdateSuccessful()
void SetItkImageAsMITKImagePointerParameter(const char *parameter, const itk::SmartPointer< itk::Image< TPixel, VImageDimension >> &itkImage)
Set an ITK image as a MITK Image parameter (smart pointer version).
virtual void Initialize(const NonBlockingAlgorithm *other=nullptr)
void DefineTriggerParameter(const char *)
void StartAlgorithm()
Start the algorithm asynchronously in a background thread.
void SetPointerParameter(const char *parameter, BaseData *value)
Set a parameter that holds a BaseData pointer (Image, Surface, etc.).
void TriggerParameterModified(const itk::EventObject &event)
Callback invoked when a trigger parameter is modified.
void GetPointerParameter(const char *parameter, itk::SmartPointer< T > &value) const
Get a parameter that holds a smart pointer.
virtual void ThreadedUpdateFailed()
void StartBlockingAlgorithm()
Start the algorithm and block until it completes.
void StopAlgorithm()
Wait for the running algorithm thread to finish.
DataStorage * GetDataStorage()
Get the DataStorage associated with this algorithm.
virtual bool ThreadedUpdateFunction()
void SetPointerParameter(const char *parameter, const itk::SmartPointer< T > &value)
Set a parameter that holds a smart pointer.
void UnDefineTriggerParameter(const char *)
void SetParameter(const char *parameter, const T &value)
Set a parameter of any normal (value) type.
void SetDataStorage(DataStorage &storage)
Set the DataStorage for this algorithm.
void ThreadedUpdateSuccessful(const itk::EventObject &event)
GUI-thread callback when the threaded update succeeds.
mitkClassMacroItkParent(NonBlockingAlgorithm, itk::Object)
void SetItkImageAsMITKImagePointerParameter(const char *parameter, itk::Image< TPixel, VImageDimension > *itkImage)
Set an ITK image as a MITK Image parameter (raw pointer version).
Property containing a smart pointer to an itk::Object.
itk::Object::Pointer GetSmartPointer() const
Get the stored smart pointer.
A weak pointer that observes an itk::Object without preventing its deletion.
Image::Pointer ImportItkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, const BaseGeometry *geometry=nullptr, bool update=true)
Import an itk::Image (with a specific type) as an mitk::Image.
Declares commonly used GenericProperty specializations for MITK.
Find image slices visible on a given plane.