File: IRISApplication.h

package info (click to toggle)
itksnap 3.6.0-5
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 22,132 kB
  • sloc: cpp: 91,089; ansic: 1,994; sh: 327; makefile: 16
file content (763 lines) | stat: -rw-r--r-- 25,101 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
/*=========================================================================

  Program:   ITK-SNAP
  Module:    $RCSfile: IRISApplication.h,v $
  Language:  C++
  Date:      $Date: 2009/08/26 01:10:20 $
  Version:   $Revision: 1.18 $
  Copyright (c) 2007 Paul A. Yushkevich
  
  This file is part of ITK-SNAP 

  ITK-SNAP is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.

  -----

  Copyright (c) 2003 Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information. 

=========================================================================*/

#ifndef __IRISApplication_h_
#define __IRISApplication_h_

#include "ImageWrapperTraits.h"
#include "ImageCoordinateTransform.h"
#include "IRISDisplayGeometry.h"
#include "itkImageRegion.h"
#include "itkExceptionObject.h"
#include "GlobalState.h"
#include "ColorLabelTable.h"
#include "itkCommand.h"
#include "SystemInterface.h"
#include "UndoDataManager.h"
#include "SNAPEvents.h"

// #include "itkImage.h"

// Forward reference to the classes pointed at
class GenericImageData;
class IRISException;
class IRISImageData;
class SNAPImageData;
class MeshExportSettings;
class GuidedNativeImageIO;
class ThresholdSettings;
class EdgePreprocessingSettings;
class AbstractSlicePreviewFilterWrapper;
class UnsupervisedClustering;
class ImageWrapperBase;
class MeshManager;
class AbstractLoadImageDelegate;
class AbstractSaveImageDelegate;
class IRISWarningList;
class GaussianMixtureModel;
struct IRISDisplayGeometry;
class LabelUseHistory;
class ImageAnnotationData;

template <class TPixel, class TLabel, int VDim> class RandomForestClassifier;
template <class TPixel, class TLabel, int VDim> class RFClassificationEngine;

template <class TTraits> class PresetManager;
class ColorMapPresetTraits;
typedef PresetManager<ColorMapPresetTraits> ColorMapPresetManager;

template <class TFilterConfigTraits> class SlicePreviewFilterWrapper;
class SmoothBinaryThresholdFilterConfigTraits;
class EdgePreprocessingFilterConfigTraits;
class GMMPreprocessingFilterConfigTraits;
class RFPreprocessingFilterConfigTraits;
template <typename TIn, typename TOut> class SmoothBinaryThresholdImageFilter;
template <typename TIn, typename TOut> class EdgePreprocessingImageFilter;
template <typename TIn, typename TVIn, typename TOut> class GMMClassifyImageFilter;


namespace itk {
  template <class TPixel, unsigned int VDimension> class Image;
  template <class TPixel, unsigned int VDimension> class VectorImage;
  template <class TParametersValueType> class TransformBaseTemplate;
}


/**
 * \class IRISApplication
 * \brief This class encapsulates the highest level login of SNAP and IRIS.
 *
 * TODO: Organize the interaction between this class, IRISImageData and SNAPImageData
 * in a more intuitive way.  
 *
 * 'RAI' codes used by this class:
 * The code is a string that describes the transform from image space to patient 
 * coordinate system as three letters from RLAPIS.  For instance, PSR
 * means that the image origin is at the posterior-superior-right corner
 * of the image coordinate system and that the x axis maps to A-P axis, 
 * y to I-S and x to R-L.
 *
 * \sa IRISImageData
 * \sa SNAPImageData
 */
class IRISApplication : public itk::Object
{
public:

  irisITKObjectMacro(IRISApplication, itk::Object)

  // Typedefs
  typedef itk::ImageRegion<3> RegionType;
  typedef itk::Size<3> SizeType;

  // The internal representation of anatomical images
  typedef itk::VectorImage<GreyType, 3> AnatomyImageType;

  //typedef RLEImage<LabelType> LabelImageType;
  //avoid duplicating definition of LabelImageType, like this:
  typedef LabelImageWrapperTraits::ImageType LabelImageType;

  typedef itk::Image<short ,3> SpeedImageType;
  typedef itk::Command CommandType;

  // A drawing performed on a slice
  typedef itk::Image<unsigned char, 2> SliceBinaryImageType;

  // Bubble array
  typedef std::vector<Bubble> BubbleArray;

  // Structure for listing DICOM series ids (SeriesId/LayerId pair)
  struct DicomSeriesDescriptor
  {
    std::string series_id;
    std::string series_desc;
    std::string dimensions;
    unsigned long layer_uid;  // links back to the loaded layer
  };

  typedef std::list<DicomSeriesDescriptor> DicomSeriesListing;
  typedef std::map<std::string, DicomSeriesListing> DicomSeriesTree;

  // Classifier stuff
  typedef RFClassificationEngine<GreyType, LabelType, 3> RFEngine;
  typedef RandomForestClassifier<GreyType, LabelType, 3> RFClassifier;

  // Declare events fired by this object
  FIRES(CursorUpdateEvent)
  FIRES(MainImageDimensionsChangeEvent)
  FIRES(MainImagePoseChangeEvent)
  FIRES(LayerChangeEvent)
  FIRES(SegmentationChangeEvent)
  FIRES(SpeedImageChangedEvent)
  FIRES(DisplayToAnatomyCoordinateMappingChangeEvent)


  /**
   * Get image data related to IRIS operations
   */
  irisGetMacro(IRISImageData,IRISImageData *);

  /**
   * Get image data related to SNAP operations
   */
  irisGetMacro(SNAPImageData,SNAPImageData *);

  /**
   * Get the image data currently used
   */
  irisGetMacro(CurrentImageData,GenericImageData *);

  /**
   * Enter the IRIS mode
   */    
  void SetCurrentImageDataToIRIS();

  /**
   * Enter the SNAP mode
   */
  void SetCurrentImageDataToSNAP();

  /**
    Whether we are currently in active contour mode or not
    */
  bool IsSnakeModeActive() const;

  /**
   * Whether there is currently a valid level set function
   */
  bool IsSnakeModeLevelSetActive() const;

  /**
   * Load an image using a delegate object. The delegate specializes the behavior
   * of this class to different layer roles (main image, overlay). The warnings
   * generated in the course of the IO operation are stored in the passed in
   * warning list object;
   *
   * By default the IO hints are obtained from the association files, i.e. by
   * looking up the hints associated with fname in the user's application data
   * directory. But it is also possible to provide a pointer to the ioHints, i.e.,
   * if the image is being as part of loading a workspace.
   */
  ImageWrapperBase* LoadImageViaDelegate(const char *fname,
                                         AbstractLoadImageDelegate *del,
                                         IRISWarningList &wl,
                                         Registry *ioHints = NULL);

  /**
   * List available additional DICOM series that can be loaded given the currently
   * loaded DICOM images. This creates a listing of 'sibling' DICOM series Ids,
   * grouped by the directory of the DICOM data
   */
  DicomSeriesTree ListAvailableSiblingDicomSeries();

  /**
   * Load another dicom series via delegate. This is similar to LoadImageViaDelegate
   * but the input is a SeriesId assumed to be in the same DICOM directory as the
   * main image
   */
  void LoadAnotherDicomSeriesViaDelegate(unsigned long reference_layer_id,
                                         const char *series_id,
                                         AbstractLoadImageDelegate *del,
                                         IRISWarningList &wl);

  /**
   * Assign a nickname to an image layer based on its DICOM metadata. For now this
   * implementation uses just the "Series Description" field.
   */
  void AssignNicknameFromDicomMetadata(ImageWrapperBase *layer);

  /**
   * Load an image for a particular role using the default delegate for this role.
   * This convenience method is currently implemented for MAIN, OVERLAY and LABEL
   * image types. This method loads the associated settings and metadata for the
   * image either from the user's image associations directory (default) or from
   * the provided Registry object.
   */
  void LoadImage(const char *fname, LayerRole role,
                 IRISWarningList &wl,
                 Registry *meta_data_reg = NULL,
                 Registry *io_hints_reg = NULL);

  /**
   * Create a delegate for saving an image interactively or non-interactively
   * via a wizard.
   */
  SmartPtr<AbstractSaveImageDelegate> CreateSaveDelegateForLayer(
      ImageWrapperBase *layer, LayerRole role);

  /** 
   * Update the main image in IRIS. The first parameter is the IO object that
   * has the image data loaded, and the second parameter is an optional pointer
   * to a registry from which to read the metadata. If not provided, metadata
   * will be read from the 'image association' files automatically generated
   * as images are closed.
   */
  void UpdateIRISMainImage(GuidedNativeImageIO *nativeIO, Registry *metadata = NULL);

  /**
   * Add an overlay image into IRIS.
   */
  void AddIRISOverlayImage(GuidedNativeImageIO *nativeIO, Registry *metadata = NULL);

  /**
   * Add a 'derived' overlay, i.e., an overlay generated using image processing from one
   * of the existing image layers
   */
  void AddDerivedOverlayImage(const ImageWrapperBase *sourceLayer,
                              ImageWrapperBase *overlay,
                              bool inherit_colormap);

  /**
   * Remove a specific overlay
   */
  void UnloadOverlay(ImageWrapperBase *ovl);

  /**
   * Remove all overlays
   */
  void UnloadAllOverlays();

  /**
   * Unload the main image layer
   */
  void UnloadMainImage();

  /**
   * Move layers (overlay for now) up and down in the list, changing their
   * display order
   */
  void ChangeOverlayPosition(ImageWrapperBase *overlay, int dir);

  /**
   * Quit the application. This responds to the quit action in the main application.
   * This unloads all layers. Additionally, when the application is in snake mode,
   * it first cancels snake mode
   */
  void Quit();

  /** 
   * Update the IRIS image data with an external segmentation image (e.g., 
   * loaded from a file).
   */
  void UpdateIRISSegmentationImage(GuidedNativeImageIO *io);

  /**
   * Update the SNAP image data with an external segmentation image (e.g.,
   * loaded from a file).
   *
   * TODO: this should probably change when we allow multiple concurrent segmentation
   * images to be used in SNAP mode.
   */
  void UpdateSNAPSegmentationImage(GuidedNativeImageIO *io);


  /** 
   * Clear the IRIS segmentation image
   */
  void ResetIRISSegmentationImage();

  /**
   * Clear the SNAP segmentation image (active during pre-segmentation)
   */
  void ResetSNAPSegmentationImage();

  /**
   * Update the SNAP image data with an external speed image (e.g., 
   * loaded from a file).
   */
  void UpdateSNAPSpeedImage(SpeedImageType *newSpeedImage, SnakeType snakeMode);
  
  /**
   * Initialize SNAP Image data using region of interest extents, and a new
   * voxel size.
   */
  void InitializeSNAPImageData(const SNAPSegmentationROISettings &roi,
                               CommandType *progressCommand = NULL);

  /**
    Enter given preprocessing mode. This activates the pipeline that can be
    used to provide automatic on-the-fly preview of the preprocessing result
    as the user moves the cursor or changes preprocessing parameters. When
    preprocessing is done, or before switching to a new preprocessing mode,
    call this method with PREPROCESS_NONE to disconnect the pipeline.
    */
  void EnterPreprocessingMode(PreprocessingMode mode);

  /**
    Uses the current preprocessing mode to compute the entire extents of the
    speed image. This also sets the SpeedValid flag in GlobalState to true
    */
  void ApplyCurrentPreprocessingModeToSpeedVolume(itk::Command *progress = 0);

  /**
    Get the current preprocessing mode
    */
  PreprocessingMode GetPreprocessingMode() const;

  /**
    Get a pointer to the object that handles the preview pipeline for the
    current preprocessing mode. This object can be used to toggle preview
    and to execute the preprocessing filter. Returns NULL if the mode is
    PREPROCESS_NONE
    */
  AbstractSlicePreviewFilterWrapper *GetPreprocessingFilterPreviewer(
      PreprocessingMode mode);

  /**
    Get a reference to the bubble array
    */
  BubbleArray &GetBubbleArray();

  /**
    Initialize the SNAP active contour evolution with the bubbles.
    */
  bool InitializeActiveContourPipeline();

  /**
   * Update IRIS image data with the segmentation contained in the SNAP image
   * data.
   */
  void UpdateIRISWithSnapImageData(CommandType *progressCommand = NULL);

  /**
   * Get the segmentation label data
   */
  irisGetMacro(ColorLabelTable, ColorLabelTable *)

  /**
   * Get the history of recently used color label combos
   */
  irisGetMacro(LabelUseHistory, LabelUseHistory *)

  /** Release the SNAP Image data */
  void ReleaseSNAPImageData();
  
  /** Update the display-anatomy mapping as an RAI code */
  void SetDisplayGeometry(const IRISDisplayGeometry &dispGeom);

  /** Get the current display-anatomy mapping */
  irisGetMacro(DisplayGeometry, const IRISDisplayGeometry &)

  /** Does the current image have oblique orientation? */
  bool IsImageOrientationOblique();

  /** Get the current image to anatomy RAI code */
  std::string GetImageToAnatomyRAI();

  /** Get the image axis for a given anatomical direction */
  int GetImageDirectionForAnatomicalDirection(
    AnatomicalDirection iAnat);

  /** Get the display window corresponding to an anatomical direction */
  int GetDisplayWindowForAnatomicalDirection(AnatomicalDirection iAnat) const;

  /** Get the anatomical direction in the i-th display window */
  AnatomicalDirection GetAnatomicalDirectionForDisplayWindow(int iWin) const;

  /**
   * Get the global state object
   */
  irisGetMacro(GlobalState, GlobalState *);

  /**
   * Get the system interface
   */
  irisGetMacro(SystemInterface, SystemInterface *);

  /**
   * Get the history manager
   */
  irisGetMacro(HistoryManager, HistoryManager *)

  /**
   * Set the current cursor position.  This will cause all the active image
   * wrappers to update their current slice numbers. By default, the method
   * does nothing if the passed in cursor position is the same as the current
   * cursor position. When force is true, the cursor position is set regardless.
   */
  void SetCursorPosition(const Vector3ui cursor, bool force = false);

  /**
   * Get the cursor position
   */
  Vector3ui GetCursorPosition() const;

  /**
   * Export the current slice of the image into a file
   */
  void ExportSlice(AnatomicalDirection iSliceAnatomy, const char *file);

  /** Export voxel statistis to a file */
  void ExportSegmentationStatistics(const char *file);

  /**
   * Export the 3D mesh to a file, using settings passed in the
   * MeshExportSettings structure.
   */
  void ExportSegmentationMesh(const MeshExportSettings &sets, itk::Command *cmd);

  /** 
   * This method is used to selectively override labels in a target 
   * segmentation image with the current drawing color.  It uses the 
   * current coverage mode to determine whether to override the pixel 
   * or to keep it */
  LabelType DrawOverLabel(LabelType iTarget);

  /**
   * Really simple replacement of one label with another. Returns the 
   * number of voxels changed.
   */
  size_t ReplaceLabel(LabelType drawing, LabelType drawover);

  /**
    Number of voxels of a given label in the segmentation.
    */
  size_t GetNumberOfVoxelsWithLabel(LabelType label);

  /*
   * Cut the segmentation using a plane and relabed the segmentation
   * on the side of that plane
   */
  int RelabelSegmentationWithCutPlane(
    const Vector3d &normal, double intercept);

  /**
   * Compute the intersection of the segmentation with a ray
   */
  int GetRayIntersectionWithSegmentation(const Vector3d &point, 
                     const Vector3d &ray, 
                     Vector3i &hit) const;



  /**
   * Check if there is an image currently loaded in SNAP.
   */
  bool IsMainImageLoaded() const;

  /**
    Load label descriptions from file
    */
  void LoadLabelDescriptions(const char *filename);

  /**
    Save label descriptions to file
    */
  void SaveLabelDescriptions(const char *filename);

  /** 
   * Clear all the undo points, e.g., after an operation that can not be
   * undone
   */
  void ClearUndoPoints();

  /** Check whether undo is possible */
  bool IsUndoPossible();

  /** Check whether undo is possible */
  bool IsRedoPossible();

  /** Undo (revert to last stored undo point) */
  void Undo();

  /** Redo (undo the undo) */
  void Redo();

  /**
   * Reorient the main image (and all overlays) 
   */
  void ReorientImage(vnl_matrix_fixed<double, 3, 3> inDirection);

  /**
    Apply a binary drawing performed on an orthogonal slice to the
    main segmentation.
    */
  unsigned int UpdateSegmentationWithSliceDrawing(
      SliceBinaryImageType *drawing,
      const ImageCoordinateTransform *xfmSliceToImage,
      double zSlice,
      const std::string &undoTitle);

  /** Get the pointer to the settings used for threshold-based preprocessing */
  // irisGetMacro(ThresholdSettings, ThresholdSettings *)

  /** Get the pointer to the settings used for edge-based preprocessing */
  irisGetMacro(EdgePreprocessingSettings, EdgePreprocessingSettings *)

  /** Get the object used to drive the unsupervised clustering */
  irisGetMacro(ClusteringEngine, UnsupervisedClustering *)

  /** Get the object used to drive the supervised classification */
  irisGetMacro(ClassificationEngine, RFEngine *)

  /** Set the current snake mode. This method should be called instead of the
      method in GlobalState because when the snake mode is set, some changes
      are made to the image data (having to do with setting up the preview
      filters if they are available, and cleaning speed data) */
  void SetSnakeMode(SnakeType mode);

  /** Get the current snake mode (active contours must be active) */
  SnakeType GetSnakeMode() const;

  /** Get the object used to manage VTK mesh creation */
  irisGetMacro(MeshManager, MeshManager *)

  /** Get the preset manager for color maps */
  irisGetMacro(ColorMapPresetManager, ColorMapPresetManager *)

  // ----------------------- Project support ------------------------------

  /**
   * Save a project. This method requires that all the layers that can be
   * saved in the project have a filename. The project will be written to
   * the file in the Registry format. The name of the project will be stored.
   *
   * A project is reset (set to empty string) when a new main image is loaded.
   */
  void SaveProject(const std::string &proj_file);

  /**
   * Open an existing project.
   */
  void OpenProject(const std::string &proj_file, IRISWarningList &warn);

  /**
   * Check if the project has modified since the last time it was saved. This
   * is a bit tricky to keep track of, because the project includes both the
   * list of images and the parameters.
   */
  bool IsProjectUnsaved();

  /**
   * Check if a file constitutes a project. This needs to be done quickly,
   * and since the files passed in might be binary, loading the file in
   * memory is not an option
   */
  bool IsProjectFile(const char *filename);

  // --------------------- End project support ----------------------------

  // --------------------- Annotation support ----------------------------

  /**
   * Read annotations from file
   */
  void LoadAnnotations(const char *filename);

  /**
   * Save annotations to file
   */
  void SaveAnnotations(const char *filename);

  /**
   * Record the fact that the current active label and draw over label were used.
   * This is to maintain a history of commonly used labels.
   */
  void RecordCurrentLabelUse();

protected:

  IRISApplication();
  virtual ~IRISApplication();

  // Map cursor from one image data to another
  void TransferCursor(GenericImageData *source, GenericImageData *target);

  // Image data objects
  GenericImageData *m_CurrentImageData;
  SmartPtr<IRISImageData> m_IRISImageData;
  SmartPtr<SNAPImageData> m_SNAPImageData;

  // Color label data
  SmartPtr<ColorLabelTable> m_ColorLabelTable;

  // Label use history
  SmartPtr<LabelUseHistory> m_LabelUseHistory;

  // Global state object
  // TODO: Incorporate GlobalState into IRISApplication more nicely
  SmartPtr<GlobalState> m_GlobalState;

  // SystemInterface used to get things from the system
  SystemInterface *m_SystemInterface;

  // History manager
  HistoryManager *m_HistoryManager;

  // Coordinate mapping between display space and anatomical space
  IRISDisplayGeometry m_DisplayGeometry;

  // Settings for the speed preprocessing. Still not sure this is the best
  // place to put this stuff!
  SmartPtr<EdgePreprocessingSettings> m_EdgePreprocessingSettings;

  // The last mixture model used for clustering. This is reused during repeated
  // calls to the active contour segmentation, as long as the layers haven't
  // been updated.
  SmartPtr<GaussianMixtureModel> m_LastUsedMixtureModel;

  // The threshold-based preview wrapper type
  typedef SlicePreviewFilterWrapper<SmoothBinaryThresholdFilterConfigTraits>
                                                   ThresholdPreviewWrapperType;

  // The edge-based preview wrapper type
  typedef SlicePreviewFilterWrapper<EdgePreprocessingFilterConfigTraits>
                                           EdgePreprocessingPreviewWrapperType;

  // The GMM preview wrapper type
  typedef SlicePreviewFilterWrapper<GMMPreprocessingFilterConfigTraits>
                                            GMMPreprocessingPreviewWrapperType;

  // The GMM preview wrapper type
  typedef SlicePreviewFilterWrapper<RFPreprocessingFilterConfigTraits>
                                            RFPreprocessingPreviewWrapperType;

  // The threshold-based wrapper
  SmartPtr<ThresholdPreviewWrapperType> m_ThresholdPreviewWrapper;

  // The edge-based wrapper
  SmartPtr<EdgePreprocessingPreviewWrapperType> m_EdgePreviewWrapper;

  // GMM-based preprocessing wrapper
  SmartPtr<GMMPreprocessingPreviewWrapperType> m_GMMPreviewWrapper;

  // Random forest preprocessing wrapper
  SmartPtr<RFPreprocessingPreviewWrapperType> m_RandomForestPreviewWrapper;

  // The EM classification object
  SmartPtr<UnsupervisedClustering> m_ClusteringEngine;

  // The Random Foreset classification object
  SmartPtr<RFEngine> m_ClassificationEngine;

  // The last classifier used for random forest segmentation. This is reused during
  // repeated calls to the active contour segmentation, as long as the layers haven't
  // been updated.
  SmartPtr<RFClassifier> m_LastUsedRFClassifier;

  // The number of components for the last used RF classifier
  int m_LastUsedRFClassifierComponents;

  // Mesh object (used to manage meshes)
  SmartPtr<MeshManager> m_MeshManager;

  // Color map preset manager
  SmartPtr<ColorMapPresetManager> m_ColorMapPresetManager;

  // The currently hooked up preprocessing filter preview wrapper
  PreprocessingMode m_PreprocessingMode;

  // Array of bubbles
  BubbleArray m_BubbleArray;

  // Save metadata for a layer to the associations file
  void SaveMetaDataAssociatedWithLayer(ImageWrapperBase *layer, int role,
                                       Registry *override = NULL);
  void LoadMetaDataAssociatedWithLayer(ImageWrapperBase *layer, int role,
                                       Registry *override = NULL);

  // Create layer-specific segmentation settings (threshold settings, e.g.)
  void CreateSegmentationSettings(ImageWrapperBase *wrapper, LayerRole role);

  // Helper functions for GMM mode enter/exit
  void EnterGMMPreprocessingMode();
  void LeaveGMMPreprocessingMode();

  // Helper functions for RF mode enter/exit
  void EnterRandomForestPreprocessingMode();
  void LeaveRandomForestPreprocessingMode();

  // ----------------------- Project support ------------------------------

  // Cached state of the project at the time of last open/save. Used to check
  // if the project has been modified.
  Registry m_LastSavedProjectState;

  // Internal method used by the project IO code
  void SaveProjectToRegistry(Registry &preg, const std::string proj_file_full);

  // Auto-adjust contrast of a layer on load
  void AutoContrastLayerOnLoad(ImageWrapperBase *layer);

  typedef ImageWrapperBase::ITKTransformType ITKTransformType;

  // Read transform from project registry
  SmartPtr<ITKTransformType> ReadTransform(Registry *reg, bool &is_identity);

  // Write transform to project registry
  void WriteTransform(Registry *reg, const ITKTransformType *transform);
};

#endif // __IRISApplication_h_