diff --git a/Core/Code/Testing/DICOMTesting/DICOMTesting.dox b/Core/Code/Testing/DICOMTesting/DICOMTesting.dox index 2847dbf68c..15aea78acd 100644 --- a/Core/Code/Testing/DICOMTesting/DICOMTesting.dox +++ b/Core/Code/Testing/DICOMTesting/DICOMTesting.dox @@ -1,145 +1,144 @@ /** \page DICOMTesting MITK DICOM testing \section DICOMTesting_introduction Introduction Reading DICOM data into mitk::Images is a complicated business since DICOM and MITK have very different ideas of images. DicomSeriesReader brings DICOM and MITK as close together as possible by offering methods to load DICOM CT and MR images into mitk::Images, optionally grouping slices to 3D+t images. Since there are so many possible sources for mistakes with any change to this loading process, testing the many -assumptions implemented in DicomSeriesReader is worthwhile. This document describes what kind of tests are implemented -and what how. +assumptions implemented in DicomSeriesReader is worthwhile. This document describes what and how theses kind of tests are implemented. \section DICOMTesting_problem Problem description The task of loading DICOM files into mitk::Images is a challenge because of major differences in the way that DICOM and MITK represent images: - DICOM images - are mostly stored as one slice per file - do not describe how they can be arraged into image stacks with orthogonal axis - sometimes they cannot be arranged in image stacks as described above (e.g. tilted gantry) - mitk::Image (at least its mature areas) - represents image stacks with orthogonal axis (nothing like a tilted gantry) - have a concept of a fourth dimension (time steps) Because image processing applications based on MITK still need a way to load DICOM images into -mitk::Image objects, MITK needs to put a lot of effort into building image stacks as best as it can. And this needs to be well tested. +mitk::Image objects, MITK needs a way to build image stacks and this needs to be well tested. For more background information, see David Clunie's most valuable posts on comp.protocols.dicom, e.g.: - http://groups.google.com/group/comp.protocols.dicom/browse_thread/thread/6db91972e161f0d4/6e0304ac264a6eb5 - http://groups.google.com/group/comp.protocols.dicom/browse_thread/thread/e9bd1497bea3e66b/187a7dc8810613d2 - http://groups.google.com/group/comp.protocols.dicom/browse_thread/thread/5d80bb0b7fafcb81/cf96119e3b024ed8 - http://groups.google.com/group/comp.protocols.dicom/browse_thread/thread/4568635e083a3fba/e2a8ceec23032601 \section DICOMTesting_testidea Test principle The general idea for DICOM loaing tests is to run a set of known DICOM files through DicomSeriesReader's methods GetSeries() and LoadDicomSeries() to generate mitk::Images. These images are then compared to expected image properties, such as the number of individual mitk::Images, positions, orientations, spacings, etc. Stored expectations look like this (should be self-explanatory): \verbatim -- Image 1 Pixeltype: s BitsPerPixel: 16 Dimension: 4 Dimensions: 64 64 6 1 Geometry: Matrix: 5.25 0 0 0 5.2468 0.139598 0 -0.183222 3.99757 Offset: -159.672 -309.974 -69.0122 Center: 0 0 0 Translation: -159.672 -309.974 -69.0122 Scale: 1 1 1 Origin: -159.672 -309.974 -69.0122 Spacing: 5.25 5.25 4 TimeBounds: 0 1 -- Image 2 Pixeltype: s BitsPerPixel: 16 Dimension: 4 Dimensions: 64 64 41 1 Geometry: Matrix: 5.25 0 0 0 5.25 0 0 0 4 Offset: -160.672 -311.672 -285 Center: 0 0 0 Translation: -160.672 -311.672 -285 Scale: 1 1 1 Origin: -160.672 -311.672 -285 Spacing: 5.25 5.25 4 TimeBounds: 0 1 \endverbatim \section DICOMTesting_implementation Implementation \section DICOMTesting_implementation_utils Test helpers (applications and classes) Application DumpDICOMMitkImage Takes a list of DICOM images, loads them using TestDICOMLoading, then dumps information about the resulting mitk::Images to standard output. This application is helpful when defining reference data for tests. Application VerifyDICOMMitkImageDump Takes a list of DICOM images and loads them using TestDICOMLoading. Takes a dump file as generated by DumpDICOMMitkImage, parses it and compares it to actually generated mitk::Images. This application is used to implement the majority of test cases. They all load images, then verify the expected result structure. Class TestDICOMLoading \section PageDICOMLoadingTests_testcaseimplementation Test case implementation Individual test cases are stored in the MITK-Data repository and constructed by Core/Code/Testing/DICOMTesting/Testing/CMakeLists.txt The CMake file parses given directories for subdirectories containing specific test cases. Each directory contains two files: - File "input": lists DICOM files that should be loaded for this test case - File "expected.dump": contains the image properties in the above mentioned dump format Each test case is translated into a CTest test which evaluates the return value of a call to VerifyDICOMMitkImageDump. \section PageDICOMLoadingTests_testcases Implemented test cases From test set TinyCTAbdomen (see description.txt in this directory for details on test images): - singleslice : just a single slice (should work and contain meaningful spacing) - two_slices : two slices, spacing should be calculated correctly - all : load a "normal" series as a single 3D block - 3D_and_T : load a small set of slices with multiple time-steps - diff_orientation : load a set of files containing two differently oriented image blocks - diff_orientation_gaps : load a set of files containing two differently oriented image blocks, each missing slices, so blocks must be split - diff_spacing : load a set of files containint two set of slices with different spacings - gap : load slices that cannot form a single 3D block, because single slices are missing - gaps : slices missing in differnt locations, so multiple splits needed - unsorted_gaps : as before, just file names are unsorted - single_negative_spacing : from reported bug related to single MR images with misleading spacing information - tilted_gantry : slice origins do not align along first slice normal (happens with tilted gantries) - interleaved : two volumes of slices with origins along the same line. The volumes' slices interleave in their border region. This test is meant to correctly sort apart the two blocks instead of generating many two-slices groups in the interleaved region. \section DICOMTesting_othertests Specific other tests This list is meant to provide an up-to-date list of all implemented DICOM loading tests. If you ever find this outdated, please update it or make the persons who invalidated the list update it. mitkDICOMTestingSanityTest_* These tests implement basic testing of the implemented helper classes. The tests use DicomSeriesReader to load a number of DICOM image. They verify: - DicomSeriesReader recognizes all input files as DICOM images - DicomSeriesReader generates a number of mitk::Images from the DICOM images - the number of mitk::Images matches a number given on the command line or CTest's add_test() - helper methods in class TestDICOMLoading make minimal sense (comparison of an image dump to itself must be valid) */ diff --git a/Documentation/Doxygen/DirectoryStructure.dox b/Documentation/Doxygen/DirectoryStructure.dox index 4262713cd4..d8924cf537 100644 --- a/Documentation/Doxygen/DirectoryStructure.dox +++ b/Documentation/Doxygen/DirectoryStructure.dox @@ -1,23 +1,23 @@ /** \page DirectoryStructurePage Directory Structure -There are eight directories on the top level, each containing several sub-directories that contain the implementation. Thus, as far as code is concerned, the depth of the directory structure is limited to two. Classes in a sub-directory may reference classes in other sub-directories on the same level and in sub-directories that have already been mentioned, when you the following list from top to bottom: +There are eight directories on the top level, each containing several sub-directories that contain the implementation. Thus, as far as code is concerned, the depth of the directory structure is limited to two. Classes in a sub-directory may reference classes in other sub-directories on the same level and in sub-directories that have already been mentioned, which are listed from top to bottom: \li \a DataStructures: contains sub-directories with data classes. Besides the actual data storage classes, the same sub-directory may contain functions inherently associated to the data storage class in the sense of object-oriented programming. For example a container class may include methods like \a add, \a remove, \a addSorted (add and keep the container sorted), and comparison operators. Classes in a directory may reference classes in other data-directories, but \em not in any of the other seven directories at the top level. \li \a Algorithms: contains sub-directories with algorithms, which may reference other algorithms and data-structures. \li \a Controllers: contains sub-directories with controllers. Controllers are invisible data management classes. An (non-exclusive!) example are controllers in the sense of the model-view-controller design-pattern. Controllers may reference other controllers, algorithms and data-structures. \li \a Rendering: contains sub-directories with rendering classes, e.g. mitk-mappers. Rendering classes may be graphics library dependent (e.g. OpenGL or vtk), but are GUI-toolkit independent (independent from Qt, FLTK, etc.). They produce output within a widget provided to them. Other classes within sub-directories of \a Rendering and all above mentioned directories my be referenced. \li \a Interactions: contains sub-directories with interaction classes, which may reference other interactions and all above mentioned directories. \li \a AppModule: contains sub-directories with classes creating a (part of a) GUI, which can be used within applications. This includes widgets and combinations of widgets and other AppModules. Classes in all directories except the \a Functionalities and \a Application directory may be referenced. \li \a Functionalities: contains sub-directories with functionalities. A functionality combines a main-widget area with a control widget area and an icon/menu-entry/description. Functionalities may include other functionalities. Classes in all directories except the \a Application directory may be referenced. \li \a Applications: Each directory includes the files required for at least one application. Classes in all directories may be referenced. In future, this directory may be moved to a separate cvs-repository. \section Directory Naming Conventions If the classes within a sub-directory are implemented according to the mechanisms or on basis of a toolkit, the name of the sub-directory should start with the acronym of the toolkit. For example, if a registration algorithm uses itk, a reasonable directory name is \a itkRegistration. The classes within the directory need not be in the namespace of the toolkit (as in the case of itk-using classes), but they may, as in the case of directories containing mitk-core-classes. Typical acronyms are \a mitk, \a itk, \a vtk, \a ip and \a Qmitk (following the Qt-Naming Guidelines). \section File Naming Conventions If a file contains a class that is within a namespace, the file name \em must begin with the namespace name, e.g. mitkImage.h and mitkImage.cpp contain the class mitk::Image. Namespace names are normally identical to toolkit acronyms. Consequently, name of the directory will begin with the acronym according to the previous section. \section Compilation Conventions Files created during compilation should be stored in a separate directory tree parallel to the source tree (e.g. \a mitkBinary). For mitk, cmake should be used. */