diff --git a/Documentation/Doxygen/3-DeveloperManual/Concepts/GeometryOverview.dox b/Documentation/Doxygen/3-DeveloperManual/Concepts/GeometryOverview.dox index 9d1afa71e2..f7bbcb984b 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Concepts/GeometryOverview.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Concepts/GeometryOverview.dox @@ -1,131 +1,160 @@ -namespace mitk{ /** \page GeometryOverviewPage Geometry Overview \tableofcontents \section GeometryOverviewPage_Introduction Introduction to Geometries -Geometries are used to describe the geometrical properties of data objects in space and time.\n -To use the geometry classes in the right way you have to understand the three different coordinate types present in MITK:\n\n +Geometries are used to describe the geometrical properties of data objects in space and time. +To use the geometry classes in the right way you have to understand the three different coordinate types present in MITK: + \imageMacro{CoordinateTypes.png,"",16} -
The different coordinate types\n\n
\n - -# World coordinates: - - World coordinates are describing the actual spacial position of all MITK objects regarding a global coordinate system, normally specified by the imaging modality - - World coordinates are represented by mitk::Point3D objects. - - The geometry defines the offset, orientation, and scale of the considered data objects in reference to the world coordinate systems. - - World coordinates are always measured in mm - - If you are dealing with an image geometry, the origin of an image is pointing to the CENTER of the bottom-left-back voxel.\n - - If you are NOT dealing with an image geometry (no defined discrete Voxels), the origin is pointing to the bottom-left-back CORNER - - Index coordinates can be converted to world coordinates by calling BaseGeometry::IndexToWorld()\n\n + +\section GeometryOverviewPage_CoordTypes The different coordinate types + +\subsection GeometryOverviewPage_WorldCoord + +- World coordinates are describing the actual spacial position of all MITK objects regarding a global coordinate system, normally specified by the imaging modality +- World coordinates are represented by mitk::Point3D objects. +- The geometry defines the offset, orientation, and scale of the considered data objects in reference to the world coordinate systems. +- World coordinates are always measured in mm +- If you are dealing with an image geometry, the origin of an image is pointing to the CENTER of the bottom-left-back voxel. +- If you are NOT dealing with an image geometry (no defined discrete Voxels), the origin is pointing to the bottom-left-back CORNER +- Index coordinates can be converted to world coordinates by calling mitk::BaseGeometry::IndexToWorld() \imageMacro{worldcoordinateSystem.png,"",12} -
Corner-based coordinates\n\n
+ +\subsection GeometryOverviewPage_CornerCoord Corner-based coordinates + \imageMacro{WorldcoordinateSystemCenterBased.png,"",12} -
Center-based image-coordinates\n\n
\n - -# Continuous index coordinates: - - Dividing world coordinates through the pixel spacing and simultanously taking the offset into account leads to continuous index coordinates inside your dataobject.\n - So continuous coordinates can be float values! - - Continuous index coordinates are represented by mitk::Point3D objects. - - They can be obtained by calling BaseGeometry::WorldToIndex(), where &pt_mm is a point in worldcoordinates.\n - -# Index coordinate system: - - Index coordinates are discrete values that address voxels of a data object explicitly. - - Index coordinates are represented by itk::Index<3> objects. - - Basically they are continuous index coordinates which are rounded from half integer up. - - E.g. (0,0) specifies the very first pixel of a 2D image, (0,1) the pixel of the next column in the same row - - If you have world coordinates, they can be converted to discrete index coordinates by calling - BaseGeometry::WorldToIndex()\n\n + +\subsection GeometryOverviewPage_CenterCoord Center-based image-coordinates + +\subsubsection GeometryOverviewPage_CenterCoord_ContIdx Continuous index coordinates + +- Dividing world coordinates through the pixel spacing and simultanously taking the offset into account leads to continuous index coordinates inside your dataobject. So continuous coordinates can be float values! +- Continuous index coordinates are represented by mitk::Point3D objects. +- They can be obtained by calling mitk::BaseGeometry::WorldToIndex(), where &pt_mm is a point in worldcoordinates.\n + +\subsubsection GeometryOverviewPage_CenterCoord_Idx Index coordinate system + +- Index coordinates are discrete values that address voxels of a data object explicitly. +- Index coordinates are represented by itk::Index<3> objects. +- Basically they are continuous index coordinates which are rounded from half integer up. +- E.g. (0,0) specifies the very first pixel of a 2D image, (0,1) the pixel of the next column in the same row +- If you have world coordinates, they can be converted to discrete index coordinates by calling mitk::BaseGeometry::WorldToIndex()\n\n \section GeometryOverviewPage_PointsAndVector Difference between Points and Vectors -Like ITK, MITK differenciate between points and vectors. A point defines a position in a coordinate system while a -vector is the distance between two points. Therefore points and vectors behave different if a coordinate transformation -is applied. An offest in a coordinate transformation will affect a transformed point but not a vector. +Like ITK, MITK differenciate between points and vectors. +A point defines a position in a coordinate system while a vector is the distance between two points. +Therefore points and vectors behave different if a coordinate transformation is applied. +An offest in a coordinate transformation will affect a transformed point but not a vector. + +An Example: -An Example:\n If two systems are given, which differ by a offset of (1,0,0). The point A(2,2,2) in system one will correspont to point A'(3,2,2) in the second system. But a vector a(2,2,2) will correspond to the vector a'(2,2,2). - \section GeometryOverviewPage_Concept The Geometry Concept -As the superclass of all MITK geometries BaseGeometry holds: - - a spacial bounding box which is axes-parallel in index coordinates (often discrete indices of pixels), to be accessed by BaseGeometry::GetBoundingBox() - - a time related bounding box which holds the temporal validity of the considered data object in milliseconds (start and end time), to be accessed by BaseGeometry::GetTimeBounds().\n - The default for 3D geometries is minus infinity to plus infinity, meaning the object is always displayed independent of displayed time in MITK. - - position information in form of a Euclidean transform in respect to world coordinates (i.e. a linear transformation matrix and offset) to convert (discrete or continuous) index coordinates to world coordinates and vice versa,\n - to be accessed by BaseGeometry::GetIndexToWorldTransform()\n - See also: \ref GeometryOverviewPage_Introduction "Introduction to Geometries" - - Many other properties (e.g. origin, extent, ...) which can be found in the \ref BaseGeometry "class documentation" - - VERY IMPORTANT:\n A flag called isImageGeometry, which indicates whether the coordinates are center-based or not!\n - See also: \ref GeometryOverviewPage_Introduction "Introduction to Geometries" and \ref GeometryOverviewPage_Putting_Together "IMPORTANT: Putting it together for an Image"\n\n +As the superclass of all MITK geometries mitk::BaseGeometry holds: +- a spacial bounding box which is axes-parallel in index coordinates (often discrete indices of pixels), to be accessed by BaseGeometry::GetBoundingBox() +- a time related bounding box which holds the temporal validity of the considered data object in milliseconds (start and end time), to be accessed by BaseGeometry::GetTimeBounds(). The default for 3D geometries is minus infinity to plus infinity, meaning the object is always displayed independent of displayed time in MITK. +- position information in form of a Euclidean transform in respect to world coordinates (i.e. a linear transformation matrix and offset) to convert (discrete or continuous) index coordinates to world coordinates and vice versa, to be accessed by mitk::BaseGeometry::GetIndexToWorldTransform(). See also: \ref GeometryOverviewPage_Introduction "Introduction to Geometries" +- Many other properties (e.g. origin, extent, ...) which can be found in the mitk::BaseGeometry "class documentation" +- VERY IMPORTANT: A flag called \c isImageGeometry, which indicates whether the coordinates are center-based or not! See also: \ref GeometryOverviewPage_Introduction "Introduction to Geometries" and \ref GeometryOverviewPage_Putting_Together . IMPORTANT: Putting it together for an Image. -Every data object (sub-)class of BaseData has a TimeGeometry which is accessed by BaseData::GetTimeGeometry(). This TimeGeometry holds one or more BaseGeometry objects which describes the object at specific time points, e.g. provides conversion between world and index coordinates and contains bounding boxes covering the area in which the data are placed. There is the possibility of using different implementations of the abstract TimeGeometry class which may differ in how the time steps are saved and the times are calculated. +Every data object (sub-)class of BaseData has a mitk::TimeGeometry which is accessed by mitk::BaseData::GetTimeGeometry(). +This mitk::TimeGeometry holds one or more mitk::BaseGeometry objects which describes the object at specific time points, e.g. provides conversion between world and index coordinates and contains bounding boxes covering the area in which the data are placed. +There is the possibility of using different implementations of the abstract mitk::TimeGeometry class which may differ in how the time steps are saved and the times are calculated. -There are two ways to represent a time, either by a TimePointType or a TimeStepType. The first is similar to the continous index coordinates and defines a Time Point in milliseconds from timepoint zero. The second type is similar to index coordinates. These are discrete values which specify the number of the current time step going from 0 to GetNumberOfTimeSteps(). The conversion between a time point and a time step is done by calling the method TimeGeometry::TimeStepToTimePoint() or TimeGeometry::TimePointToTimeStep(). Note that the duration of a time step may differ from object to object, so in general it is better to calculate the corresponding time steps by using time points. Also the distance of the time steps does not need to be equidistant over time, it depends on the used TimeGeometry implementation. +There are two ways to represent a time, either by a mitk::TimePointType or a mitk::TimeStepType. +The first is similar to the continous index coordinates and defines a Time Point in milliseconds from timepoint zero. +The second type is similar to index coordinates. +These are discrete values which specify the number of the current time step going from 0 to GetNumberOfTimeSteps(). +The conversion between a time point and a time step is done by calling the method mitk::TimeGeometry::TimeStepToTimePoint() or mitk::TimeGeometry::TimePointToTimeStep(). +Note that the duration of a time step may differ from object to object, so in general it is better to calculate the corresponding time steps by using time points. +Also the distance of the time steps does not need to be equidistant over time, it depends on the used mitk::TimeGeometry implementation. -Each TimeGeometry has a bounding box covering the whole area in which the corresponding object is situated during all time steps. This bounding box may be accessed by calling TimeGeometry::GetBoundingBoxInWorld() and is always in world coordinates. The bounding box is calculated from all time steps, to manually start this calculation process call TimeGeometry::Update(). The bounding box is not updated if the getter is called. +Each mitk::TimeGeometry has a bounding box covering the whole area in which the corresponding object is situated during all time steps. +This bounding box may be accessed by calling mitk::TimeGeometry::GetBoundingBoxInWorld() and is always in world coordinates. +The bounding box is calculated from all time steps, to manually start this calculation process call mitk::TimeGeometry::Update(). +The bounding box is not updated if the getter is called. -The TimeGeometry does not provide a transformation of world coordinates into image coordinates since each time step may has a different transformation. If a conversion between image and world is needed, the BaseGeometry for a specific time step or time point must be fetched either by TimeGeometry::GetGeometryForTimeStep() or TimeGeometry::GetGeometryForTimePoint() and then the conversion is calculated by using this geometry. +The mitk::TimeGeometry does not provide a transformation of world coordinates into image coordinates since each time step may has a different transformation. +If a conversion between image and world is needed, the mitk::BaseGeometry for a specific time step or time point must be fetched either by mitk::TimeGeometry::GetGeometryForTimeStep() or mitk::TimeGeometry::GetGeometryForTimePoint() and then the conversion is calculated by using this geometry. -The TimeGeometry class is an abstract class therefore it is not possible to instantiate it. Instead a derived class must be used. Currently the only class that can be chosen is ProportionalTimeGeometry() which assumes that the time steps are ordered equidistant. To initialize an object with given geometries call ProportionalTimeGeometry::Initialize() with an existing BaseGeometry and the number of time steps. The given geometries will be copied and not referenced! +The mitk::TimeGeometry class is an abstract class therefore it is not possible to instantiate it. +Instead a derived class must be used. +Currently the only class that can be chosen is mitk::ProportionalTimeGeometry which assumes that the time steps are ordered equidistant. +To initialize an object with given geometries call mitk::ProportionalTimeGeometry::Initialize() with an existing BaseGeometry and the number of time steps. +The given geometries will be copied and not referenced! -Also, the BaseGeometry is an abstract class and derived classes must be used. The most simple implementation, i.e. the one to one implementation of the BaseGeometry class, is the class Geometry3D. +Also, the mitk::BaseGeometry is an abstract class and derived classes must be used. +The most simple implementation, i.e. the one to one implementation of the BaseGeometry class, is the class mitk::Geometry3D. -SlicedGeometry3D is a sub-class of BaseGeometry, which describes data objects consisting of slices, e.g., objects of type Image (or SlicedData, which is the super-class of Image). -Therefore, Image::GetTimeGeometry() will contain a list of SlicedGeometry3D instances. There is a special method SlicedData::GetSlicedGeometry(t) which directly returns\n -a SlicedGeometry3D to avoid the need of casting. +mitk::SlicedGeometry3D is a sub-class of mitk::BaseGeometry, which describes data objects consisting of slices, e.g., objects of type Image (or mitk::SlicedData, which is the super-class of mitk::Image). +Therefore, mitk::Image::GetTimeGeometry() will contain a list of mitk::SlicedGeometry3D instances. There is a special method mitk::SlicedData::GetSlicedGeometry(t) which directly returns a mitk::SlicedGeometry3D to avoid the need of casting. -The class SlicedGeometry3D contains a list of PlaneGeometry objects describing the slices in the image.We have here spatial steps from 0 to GetSlices(). -SlicedGeometry3D::InitializeEvenlySpaced (PlaneGeometry *planeGeometry, unsigned int slices) initializes a stack of slices with the same thickness, one starting at the position where the previous one ends. +The class mitk::SlicedGeometry3D contains a list of mitk::PlaneGeometry objects describing the slices in the image. +We have here spatial steps from 0 to GetSlices(). +mitk::SlicedGeometry3D::InitializeEvenlySpaced(PlaneGeometry *planeGeometry, unsigned int slices) initializes a stack of slices with the same thickness, one starting at the position where the previous one ends. -PlaneGeometry provides methods for working with 2D manifolds (i.e., simply spoken, an object that can be described using a 2D coordinate-system) in 3D space.\n -For example it allows mapping of a 3D point on the 2D manifold using PlaneGeometry::Map(). \n +mitk::PlaneGeometry provides methods for working with 2D manifolds (i.e., simply spoken, an object that can be described using a 2D coordinate-system) in 3D space. +For example it allows mapping of a 3D point on the 2D manifold using mitk::PlaneGeometry::Map(). -Finally there is the AbstractTransformGeometry which describes a 2D manifold in 3D space, defined by a vtkAbstractTransform. It is a abstract superclass for arbitrary user defined geometries.\n -An example is the ThinPlateSplineCurvedGeometry.\n +Finally there is the mitk::AbstractTransformGeometry which describes a 2D manifold in 3D space, defined by a vtkAbstractTransform. It is a abstract superclass for arbitrary user defined geometries. +An example is the mitk::ThinPlateSplineCurvedGeometry. -\subsection GeometryOverviewPage_Putting_Together IMPORTANT: Putting it together for an Image +\subsection GeometryOverviewPage_Putting_Together Putting it together for an Image -Please read this section accurately if you are working with Images! +Please read this section carefully if you are working with Images! The definition of the position of the corners of an image is different than the one of other data objects: -As mentioned in the previous section, world coordinates of data objects (e.g. surfaces ) usually specify the bottom left back corner of an object. +As mentioned in the previous section, world coordinates of data objects (e.g. surfaces) usually specify the bottom left back corner of an object. -In contrast to that a geometry of an Image is center-based, which means that the world coordinates of a voxel belonging to an image points to the center of that voxel. +In contrast to that, a geometry of an mitk::Image is center-based, which means that the world coordinates of a voxel belonging to an image points to the center of that voxel. E.g: \imageMacro{PixelCenterBased.png,"",6} -
Center-based voxel\n\n
+ +\subsection GeometryOverviewPage_CenterBasedVoxel Center-based voxel If the origin of e.g. a surface lies at (15,10,0) in world coordinates, the origin`s world coordinates for an image are internally calculated like the following: -
(15-0.5*X-Spacing\n - 10-0.5*Y-Spacing\n - 0-0.5*Z-Spacing)\n
+\code{.unparsed} +(15-0.5*X-Spacing + 10-0.5*Y-Spacing + 0-0.5*Z-Spacing) +\endcode If the image`s spacing is (x,y,z)=(1,1,3) then the corner coordinates are (14.5,9.5,-1.5). -If your geometry describes an image, the member variable isImageGeometry must be changed to true. This variable indicates also if your geometry is center-based or not.\n -The change can be done in two ways:\n - -# You are sure that your origin is already center-based. Whether because you adjusted it manually or you copied it from another image.\n - In that case, you can call the function setImageGeometry(true) or imageGeometryOn() to set the bool variable to true. - -# You created a new geometry, did not manually adjust the origin to be center-based and have the bool value isImageGeometry set to false (default).\n - In that case, call the function ChangeImageGeometryConsideringOriginOffset(true). It will adjust your origin automatically and set the bool flag to true.\n +If your geometry describes an image, the member variable \c isImageGeometry must be changed to true. +This variable indicates also if your geometry is center-based or not. + +The change can be done in two ways: +- You are sure that your origin is already center-based. Whether because you adjusted it manually or you copied it from another image. In that case, you can call the function \c setImageGeometry(true) or \c imageGeometryOn() to set the bool variable to true. +- You created a new geometry, did not manually adjust the origin to be center-based and have the bool value \c isImageGeometry set to false (default). In that case, call the function \c ChangeImageGeometryConsideringOriginOffset(true) . It will adjust your origin automatically and set the bool flag to true. -If you experience displaced contours, figures or other stuff, it is an indicator that you have not considered the origin offset mentioned above.\n\n +If you experience displaced contours, figures or other stuff, it is an indicator that you have not considered the origin offset mentioned above. -An image has a TimeGeometry, which contains one or more SlicedGeometry3D instances (one for each time step), all of which contain one or more instances of (sub-classes of) PlaneGeometry.\n -As a reminder: Geometry instances referring to images need a slightly different definition of corners, see BaseGeometry::SetImageGeometry. This is usualy automatically called by Image.\n\n +An image has a mitk::TimeGeometry, which contains one or more mitk::SlicedGeometry3D instances (one for each time step), all of which contain one or more instances of (sub-classes of) mitk::PlaneGeometry. + +As a reminder: Geometry instances referring to images need a slightly different definition of corners, see mitk::BaseGeometry::SetImageGeometry. +This is usualy automatically called by Image. \section GeometryOverviewPage_Connection Connection between MITK, ITK and VTK Geometries + \imageMacro{ITK_VTK_MITK_Geometries.png,"",10} -\n\n - - VTK transformation for rendering - - ITK transformation for calculations - - Both automatically updated when one is changed\n -Attention:Not automatically updated when changed hardcoded. Example: geometry->GetVtkMatrix()->Rotate(....) + +- VTK transformation for rendering +- ITK transformation for calculations +- Both automatically updated when one is changed + +Attention: Not automatically updated when changed hardcoded. Example: \c geometry->GetVtkMatrix()->Rotate(...) + */ -} diff --git a/Documentation/Doxygen/3-DeveloperManual/Concepts/Modularization.dox b/Documentation/Doxygen/3-DeveloperManual/Concepts/Modularization.dox index 58d0f02c4e..32fd931e28 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Concepts/Modularization.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Concepts/Modularization.dox @@ -1,44 +1,44 @@ /** \page ModularizationPage Modular MITK MITK has been designed to be modular and flexible, to facilitate reuse of existing code and functionality if possible. As such there are several levels of modularization which can be chosen when working with MITK, depending on the use case. \section ModularizationPageOverview Overview The general hierarchy of modularization runs micro service, module, view, plug-in, perspective and finally application. \subsection ModularizationPageMicroServices Micro Services A \ref MicroServices_Overview "micro service" is a reusable component provided by MITK modules. It can be accessed by other MITK modules or MITK plug-ins via its declared interface. \subsection ModularizationPageModules Modules Modules can be found in the MITK/Modules directory (with the exception of the core module in MITK/Core). Each module is a shared library that provides algorithms, data structures and similar code. Many modules are gui independent. A module is only build if it is required by other code, e.g. if a plug-ins is activated that requires it. \subsection ModularizationPageViews Views -One of the smallest units in the MITK application framework (\ref FurtherReading "Blueberry") is a \e view. A view is always part of a plug-in and provides one specific function, such as grouping all gui elements needed for providing segmentation algorithms or loading dicom images. Views usually contain any code which communicates with the user, performs input checking and similar, but no advanced algorithms. +One of the smallest units in the MITK application framework is a \e view. A view is always part of a plug-in and provides one specific function, such as grouping all gui elements needed for providing segmentation algorithms or loading dicom images. Views usually contain any code which communicates with the user, performs input checking and similar, but no advanced algorithms. \subsection ModularizationPagePlugInBundles Plugins The next smallest unit is a CTK Plug-in (the term \e Bundle is used interchangeably). They can be found in MITK/Plugins or MITK/BlueBerry/Bundles. Plugins can be individually switched on and off during the CMake configuration. A plugin usually represents a solution to a specific problem, such as segmentation or data management. As such they may provide any number of views and other contributions to the MITK application framework. If you want to create your own MITK plugin you find further information \ref NewPluginPage "here". \subsection ModularizationPagePerspectives Perspectives Perspectives represent a configuration for the MITK application framework (specifically, for the \e Workbench) needed for a specific workflow. They allow the arrangement of different views (contributed by different plug-ins) to reflect the usage scenario, such as a data loading view in the top right, a segmentation view to the right and a visualization view to the bottom right. A perspective is provided by arbitrary plug-ins as an extension (contribution) to the application framework. \subsection ModularizationPageApplications Applications A specific selection of plug-ins together with custom configuration data defines the functionality for an application. The application corresponds to an executable and enables very specific program behaviour and configuration. Example applications can be found in the MITK/Applications directory. \section ModularizationPageHowTo How to create your own application It is suggested to use the project generator provided by MITK unless one knows what one is doing. See \ref NewPluginWithProject "here" for more information. */ diff --git a/Documentation/Doxygen/3-DeveloperManual/Concepts/TestsGeneral.dox b/Documentation/Doxygen/3-DeveloperManual/Concepts/TestsGeneral.dox index e1481463fb..0c3174a87d 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Concepts/TestsGeneral.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Concepts/TestsGeneral.dox @@ -1,104 +1,104 @@ /** \page GeneralTests General: Tests in MITK \tableofcontents \section GeneralTestsIntroduction Testing in MITK The basic idea about unit testing is to write a test for every unit (e.g. function) of your software, which automatically checks if the code still returns the expected result for a defined input. The goal is to isolate units as much as possible, in order to be efficient with fixing errors. If this is performed on a low level, this is called unit testing. On higher levels, where various circumstances (such as configuration files, internet connection, hardware, or even input/output) may influence the outcome of the test, this is called integration testing. MITK uses CppUnit, which is a framework for efficient and fast test writing, to support developers in test coding. Furthermore MITK offers currently three types of tests: classic unit tests, rendering tests and interaction tests. Although our unit tests often involve data input (or output), we still consider them to be unit tests. \warning Most of our units tests have been written before adopting CppUnit and have not yet been updated. Therefore we do not recommend to look at a random test for an example of coding a test. This pages gives a general introduction to our test framework. Rendering tests are explained in more detail in the section \ref RenderingTests and interaction tests the section \ref InteractionTestingHowTo. The following sections will explain how to write your own tests with MITK and how to run them. \section GeneralTestsAdding Adding a test to your module Generally, functional code you want to test using unit tests will be located in a module. For an overview of the directory structure see \ref NewModulePageCreateFolder and how to add the files comprising your test compare \ref NewModulePageCreateTestingEnvironment \subsection GeneralTestsAddingFramework Test and test class/suite CppUnit and MITK distinguish between the term test class and test, which is important to understand. A test is simply a call of a single function and a comparison against a reference. The ideal way to write a test is: \code result = myGreatFunction(myParameter); ASSERT_EQUAL(result, reference); \endcode which is just 2 lines of code at the best. Sometimes objects and data may be initialized in a test, but usually this should be done in the setUp() method (see below). If possible, avoid multiple assertions in order to be efficient in error localization and for better readability. For instance, if you instantiate an object and test if its data is not NULL, this is already a complete test and you do not want to repeat this comparison in other tests. All tests check different things and just one at a time. Remember: The goal is to have isolated unit tests and avoid large, confusing tests which are hard to maintain. \note The reference should never be computed and ideally be a distinct and well defined (often hard coded) value. You don't care where you reference comes from, you just want to ensure that your test actually results in the reference value. A test class (also called suite) is a set of tests and often associated to a single functional class in MITK. A test class refers to a TestSuite in CppUnit. These terms are easily confused, so we suggest to use the term test suite for a collection of tests (which is often in a single file), and the term "test" for a single test (usually many per file). In order to create a test class you need to create a new class deriving from mitk::TestFixture. While a purist approach would be to create a new mitk::TestFixture for each method of your class (resulting in as many test source files as your class has methods), we usually follow a more pragmatic approach within MITK. In most cases we suggest having one test source file per class. If your class source file is called mitkGreatClass.cpp we suggest the name mitkGreatClassTest.cpp for your test source file. For very complex and long classes splitting this into several tests may be advisable. Additionally, rendering tests and interaction tests should always get their own test class/suite to mark them as obvious integration tests, because the goal is to isolate unit tests from integration tests. The dashboard for continuous integration will automatically show the results of a test suite and summarize the output. If you run your test manually (e.g. with ctest -VV), you will see the detailed output of all tests of the suite. In order to use CppUnit via MITK you will need to include the corresponding files and register your test: \code #include #include … MITK_TEST_SUITE_REGISTRATION(mitkImageEqual) \endcode \subsection GeneralTestsAddingHow How to structure your test -As mentioned before, all test suites derive from mitk::TestFixture. A suggested name for your test suite would be TestSuite. +As mentioned before, all test suites derive from mitk::TestFixture. A suggested name for your test suite would be \c \TestSuite . -You then create a suite and register your tests. A suggested naming convention for test methods is __. We suggest not to add the word test, because that is most likely the only thing the reader knows anyway about your test, as he is reading a test suite. +You then create a suite and register your tests. A suggested naming convention for test methods is \c \_\_\ . We suggest not to add the word test, because that is most likely the only thing the reader knows anyway about your test, as he is reading a test suite. An example: \code class mitkImageEqualTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkImageEqualTestSuite); MITK_TEST(Equal_CloneAndOriginal_ReturnsTrue); MITK_TEST(Equal_InputIsNull_ReturnsFalse); MITK_TEST(Equal_DifferentImageGeometry_ReturnsFalse); MITK_TEST(Equal_DifferentPixelTypes_ReturnsFalse); … CPPUNIT_TEST_SUITE_END(); … } \endcode You also may provide a setUp() and a tearDown() function. These will be called before/after each test and should be used to make sure that each test works independently and on freshly initialized members and memory to maximize isolation. That way you avoid only testing whether a function works after another function has already been called. See CppUnit documentation for more information. For an example test suite including tests see \ref GeneralTestsExample \section GeneralTestsRunning Running your test suite The build system of MITK generates a test driver which includes all test suites that have been added to the project. Alternatively you can run MITK test suites by using the program ctest. This is the way all MITK tests run on the continuous dart clients of MITK. The results of these runs can be found at http://cdash.mitk.org. If you use the test driver, you only need to start the executable. If you start it without parameters, it will then give you an overview of all tests which are included in this test driver and you can choose one by typing a number. Alternatively, you can give your test driver the name of your test suite as parameter. If you want to use ctest instead of the test driver you need to start a command line, go to the binary directory of MITK and call ctest. To avoid errors, check if your path variable contains all relevant paths to start MITK. \section GeneralTestsParameterInput Adding parameters to your test If possible, the setUp() method of the test suite should provide all necessary inputs for the respective tests. MITK provides several helper classes to generate synthetic test data, such as the mitk::ImageGenerator. If you have to load data from the hard disc for your test, you can use the method GetTestDataFilePath(string fileName). For an example of loading data from the MITK_DATA_DIR check the mitkIOUtilTestSuite. \section GeneralTestsPredefinedAssertions Predefined assertions MITK and CppUnit offer predefined assertions, i.e. helper methods which will help to compare your data against a certain reference. All basic types are covered by CppUnit assertions, such as CPPUNIT_ASSERT. For examples, please check the CppUnit documentation. MITK further offers comparison tools for floating point numbers, vectors, images, surfaces and point sets. A complete list of assertion macros is given in \ref MITKTestingAPI. An example to compare images: \code MITK_ASSERT_EQUAL(image, reference, "Checks if image is equal to a reference"); \endcode By default, the method uses an mitk::eps for floating point comparison, but this can be adapted. It can be necessary to write your own assertion for your own data meeting your special requirements. Recommended examples are all equal test suites for basic data types (mitkImageEqualTest, mitkSurfaceEqualTest and mitkPointSetEqualTest). \section GeneralTestsExample An example \include Examples/FirstSteps/NewModule/test/mitkExampleDataStructureTest.cpp \section GeneralTestsFurtherInfo Further information More examples can be found in the corresponding bugsquashing presentation. */ \section GeneralTestsDeprecatedOldTestingStyle Deprecated macros All tests with MITK_TEST_BEGIN(); and MITK_TEST_END(); use the deprecated old MITK testing style. If possible, they should be replaced with the new CppUnit style as explained before. Most of these test classes contain very unfortunate examples and should not be regarded as reference. diff --git a/Documentation/Doxygen/3-DeveloperManual/DeveloperManualPortal.dox b/Documentation/Doxygen/3-DeveloperManual/DeveloperManualPortal.dox index 425b916c4a..678ce379c8 100644 --- a/Documentation/Doxygen/3-DeveloperManual/DeveloperManualPortal.dox +++ b/Documentation/Doxygen/3-DeveloperManual/DeveloperManualPortal.dox @@ -1,33 +1,31 @@ /** \developersguidemainpage{DeveloperManualPortal} Developer Manual Development with MITK can happen under several conditions. Depending on whether you are using the Toolkit or the entire application, different sections may apply to you. In case you are unsure about what you need, please refer to \link Architecture The Architecture of MITK text\endlink. An extensive Introduction to MITK is available under \link StartingDevelopment Starting your MITK Development\endlink. Once you have made yourself familiar with MITK, you should have a look at the \link Concepts Development Concepts\endlink, as MITK implements a lot of high-level functionality. Knowing about these concepts will prevent you from reimplementing functionality. Once you start consuming more specific functionality, the \link MITKModuleManualsListPage Module Manual\endlink will be helpful to understand how a specific plugin works and what functionality it provides. -Finally, generated API-Documentation can be found \link DevelopmentAPI here\endlink. -
  • \subpage StartingDevelopment
    • \ref Architecture
    • \ref SettingUpMITK
    • \ref GettingToKnowMITK
    • \ref FirstSteps
    • \ref AboutTestingPage
  • \subpage Concepts
  • \subpage MITKModuleManualsListPage
  • \subpage DevelopmentApplication
    • \ref mitkExtPointsIndex
  • \subpage DeploymentPage
*/ diff --git a/Documentation/Doxygen/3-DeveloperManual/Starting/GettingToKnow/CMakeFAQ.dox b/Documentation/Doxygen/3-DeveloperManual/Starting/GettingToKnow/CMakeFAQ.dox index 7906c0733e..d6ec7bbcae 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Starting/GettingToKnow/CMakeFAQ.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Starting/GettingToKnow/CMakeFAQ.dox @@ -1,41 +1,41 @@ /** \page CMAKE_FAQ CMake FAQ \section CMAKE_FAQ_General A general comment MITK uses %CMake for configuration. If you want to develop either using MITK as a toolkit or by extending the capabilities of the applications provided by us, we recommend using %CMake for your own project too. While it might be possible to use MITK in conjunction with other options, such as QMake or setting up your own project manually it will invariably involve a lot of work and probably hacks as well. As we do have no experience with this, we will not be able to help you. Be prepared to do a lot of tweaking on by yourself. This guide does not try to give a general introduction to CMake, instead it tries to answer some basic questions that might arise for those new to %CMake, to help you get started on MITK. For a more comprehensive introduction on %CMake see here. We will assume in this guide, that the path to your source is /MITK/. \section CMAKE_FAQ_Question Basic Questions \subsection CMAKE_FAQ_Question_WhereGetIt Where do I get CMake and what version do I need? See \ref BuildInstructions_Prerequisites. \subsection CMAKE_FAQ_Question_NewPluginNothing I coded a new plugin for the Workbench and nothing happened. Why? -The correct way to create a new plugin is described in \ref NewPluginOnly. Do note that you need to move the source to the MITK/Plugins directory and you will have to add the plugin to the config file (most likely MITK/Plugins/Plugins.cmake). After that see \ref CMAKE_FAQ_Question_HowDoIActivatePlugin. +The correct way to create a new plugin is described in \ref NewPluginOnly. Do note that you need to move the source to the MITK/Plugins directory and you will have to add the plugin to the config file (most likely MITK/Plugins/Plugins.cmake). After that see \ref CMAKE_FAQ_Question_HowDoIActivatePlugin. \subsection CMAKE_FAQ_Question_HowDoIActivatePlugin I want to use a plugin, how do I activate it?
  1. Start %CMake
  2. Configure
  3. Set the variable MITK_BUILD_\ to TRUE
  4. Configure again
  5. Generate
  6. Start a build using your development environment
\subsection CMAKE_FAQ_Question_HowDoIActivateModule I want to use a module, how do I activate it? Modules are build automatically if a plugin that requires them is activated. See \ref CMAKE_FAQ_Question_HowDoIActivatePlugin. \subsection CMAKE_FAQ_Question_HowOwnToolkits MITK always downloads the toolkits, but I want to use my own. This is covered in \ref HowToNewProjectCustomizingMITKConfigure. \subsection CMAKE_FAQ_Question_HowOwnProjectMITK I want to use an MITK plugin in my own project but I can not find it. See \ref HowToNewProjectAddingMITKFunctionality. */ \ No newline at end of file diff --git a/Documentation/Doxygen/3-DeveloperManual/Starting/GettingToKnow/DirectoryStructure.dox b/Documentation/Doxygen/3-DeveloperManual/Starting/GettingToKnow/DirectoryStructure.dox index 4dda6a0e2b..51c9236973 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Starting/GettingToKnow/DirectoryStructure.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Starting/GettingToKnow/DirectoryStructure.dox @@ -1,70 +1,70 @@ /** \page DirectoryStructurePage Directory Structure To avoid clutter and ease the administration of the source code the MITK source code is structured into several subdirectories according to their function. This document aims at helping you finding what you want within this structure. \section DirectoryStructurePageOverview Overview The top level directories are the following: \li \ref DirectoryStructurePageApplications \li \ref DirectoryStructurePageCMake \li \ref DirectoryStructurePageCMakeExternals \li \ref DirectoryStructurePageDocumentation \li \ref DirectoryStructurePageExamples \li \ref DirectoryStructurePageLicenses \li \ref DirectoryStructurePageModules \li \ref DirectoryStructurePagePlugins \li \ref DirectoryStructurePageTemplates \li \ref DirectoryStructurePageUtilities \li \ref DirectoryStructurePageWrapping see the corresponding section for more information. \section DirectoryStructurePageTopLevelDirs The Top Level Directories \subsection DirectoryStructurePageApplications Applications -This directory contains the different applications. Each application has its own subfolder, including the necessary code, icons and other resources. For more information on applications see \ref ModularizationPageApplications or \ref ApplicationsPageApplications . +This directory contains the different applications. Each application has its own subfolder, including the necessary code, icons and other resources. For more information on applications see \ref ModularizationPageApplications . \subsection DirectoryStructurePageCMake CMake The %CMake directory contains %CMake files, macros and templates for the configuration of MITK as a project. \subsection DirectoryStructurePageCMakeExternals CMakeExternals This directory contains %CMake files for the configuration of other projects used by MITK. \subsection DirectoryStructurePageDocumentation Documentation The Documentation directory contains doxygen and other documentation as well as tutorials and examples. It includes basic end user manuals for the framework as well as developer documentation which does not depend on any additional modules. \subsection DirectoryStructurePageExamples Examples This directory contains example code used by the documentation in the Documentation directory. \subsection DirectoryStructurePageLicenses Licenses The Licenses directory contains various licenses used by MITK's dependencies. \subsection DirectoryStructurePageModules Modules This directory contains modules, which extend the capabilities of MITK. For the concept behind modules see \ref ModularizationPageModules . \subsection DirectoryStructurePagePlugins Plugins This directory contains plugins, which provide specific solutions. For further information see \ref ModularizationPagePlugInBundles . \subsection DirectoryStructurePageTemplates Templates This directory contains template files for recurring snippets like the copyright header for all source files. \subsection DirectoryStructurePageUtilities Utilities The Utilities directory contains self contained components, which are used by MITK, but not necessarily developed or maintained by the MITK team. \subsection DirectoryStructurePageWrapping Wrapping The Wrapping directory contains code necessary for the Python wrapping capabilities of MITK. */ diff --git a/Documentation/Doxygen/3-DeveloperManual/Starting/GettingToKnow/StyleGuideAndNotes.dox b/Documentation/Doxygen/3-DeveloperManual/Starting/GettingToKnow/StyleGuideAndNotes.dox index f06de7fe39..b8432d91e4 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Starting/GettingToKnow/StyleGuideAndNotes.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Starting/GettingToKnow/StyleGuideAndNotes.dox @@ -1,469 +1,467 @@ /** \page StyleGuideAndNotesPage The MITK Style Guide and Technical Notes \tableofcontents The following document is a description of the accepted coding style for the Medical Imaging Interaction Toolkit (MITK). Developers who wish to contribute code to MITK should read and adhere to the standards described here. \section StyleGuideAndNotesPage_NameConventions Naming Conventions \li Using case change to indicate separate words @code ImageFilter PixelType DataStorage NodePredicateProperty @endcode \li Underscores are not used e.g. Image_Filer, _Node \li Variable names should convey the meaning behind the code @code BoundingBox::Pointer boundingBox = BoundingBox::New(); @endcode \li Names are generally spelled out @code mitk::DataNode* node; @endcode \li Abbreviation are allowable when in common use e.g. ROI for Region of Interest \subsection StyleGuideAndNotesPage_NamingClasses Naming Classes \li Classes are named beginning with a capital letter \li Classes are named according to the following general rule: @code class name = @endcode \li Examples of concepts \n Accessor: Access and convert between types e.g. NullScalarAccessor \n Container: A container of objects such as points or images e.g. VectorContainer \n Filter: A class that participates in the data processing pipeline e.g. AddImageFilter \n Mapper: Transform data from one form into another e.g. ContourMapper2D \n Reader/Writer: A class that reads/writes a single data object e.g. VtkSurfaceReader \n \subsection StyleGuideAndNotesPage_NamingFiles Naming Files \li MITK classes like @a ExampleClass should be in namespace @a mitk and their corresponding files should be named @a mitkExampleClass.h/.cpp. @code mitk::DataStorage @endcode \li Qt specific MITK classes like @a QmitkListView should have the prefix Qmitk in their class names and their corresponding files should be named @a QmitkListView.h/.cpp. @code QmitkDataStorageComboBox @endcode \li Header Files ends with an .h and \li Implementation Files with an .cpp or .txx for a template class \subsection StyleGuideAndNotesPage_NamingMethodsandFunctions Naming Methods and Functions \li Functions and methods are named beginning with a capital letter \li Referring to class methods in code, an explicit this-> pointer should be used @code mitk::DataStorage::SetOfObjects::ConstPointer all = this->GetAll(); @endcode \subsection StyleGuideAndNotesPage_NamingSignalSlots Naming Signal/Slots Methods and Functions \li Slots are named according to the following general rule @code On[variable name who send the signal][signal](); @endcode \li Example @code connect( loadImagePushButton, SIGNAL( clicked(bool ) ), SLOT( OnLoadImagePushButtonClicked( bool ) ) ); void mitk::Image::OnLoadImagePushButtonClicked( bool ) { ... Do something ... } @endcode \li Signals are named according to the following general rule @code Signal[MethodName](); @endcode \li Example @code emit SignalFinishedSegmentation(); @endcode \subsection StyleGuideAndNotesPage_NamingClassDataMembers Naming Class Data Members \li Class data members are prefixed with m_ @code m_Volumes m_OffsetTable m_ImageMask @endcode \li An exception to this rule, Qt class Data members are not prefixed and begin with a lower-case letter @code loadImageButton closeImageAction @endcode \subsection StyleGuideAndNotesPage_NamingLocalVariables Naming Local Variables \li Local variables first letter is lower-case @code offset data slicesIt @endcode \subsection StyleGuideAndNotesPage_NamingQtVariables Naming Qt Variables \li GUI variables ends with name of used QT tool. @code QPushButton* loadImagePushButton; QAction* closeImageAction; QCheckBox* hideImageCheckBox; QRadioButton* binaryImageRadioButton; @endcode \subsection StyleGuideAndNotesPage_NamingTypedefs Naming Typedefs \li Typedefs must end in the word Type @code typedef TPixel PixelType; typedef itk::Image< TPixel, VImageDimension > ImageType; typedef std::list ImageListType; @endcode \section StyleGuideAndNotesPage_Pointer Pointer \subsection StyleGuideAndNotesPage_DeclarationofPointers Declaration of Pointers \li Position of * pointers are connected with the variable @code int *counter; @endcode \li Analog to references @code int &counter; @endcode \subsection StyleGuideAndNotesPage_SmartPointer SmartPointer \li SmartPointers must be used for classes that have itk::Object as a base class. \li Assignment of a just created instance to a normal pointer results in a crash, since the reference count is decreased immediately to zero and the object is destroyed. @code itk::Object::Pointer object = itk::Object::New(); @endcode \li Static declarations are also forbidden and result into an exception when the scope of the variable is left, because the destructor is called while the reference count is still greater than zero. \li Note that using smart pointers requires using real (normal) pointers when setting input. If you want to return a newly created smart pointer that is not also kept within the class (e.g., if you write a Clone method), you have to return a smart pointer on output (compare itkMacro.h). If the smart pointer is kept within the class, returning a real (normal) pointer is sufficient. \li Testing a SmartPointer against NULL is done with the IsNull() and Is- NotNull() methods. A simple ==NULL issues a warning. \section StyleGuideAndNotesPage_Namespace Namespace \li MITK classes should be in namespace @a mitk @code mitk::Image::Pointer mitk::ImageGenerator::MakeImage() { // already in namespace mitk here! Image::Pointer image = mitk::Image::New(); ImageDecorator::Pointer decorator = mitk::ImageDecorator::New(); d->Decorate( image ); return image; } @endcode \li Constants in MITK for mitk::Operation and mitk::Action are set in namespace, so don't forget to add prefix mitk:: @code switch (actionId) { case mitk::AcMOVESELECTED: ....Do something ... break; default: break; } @endcode \section StyleGuideAndNotesPage_CodeLayoutandIndentation Code Layout and Indentation \subsection StyleGuideAndNotesPage_GeneralLayout General Layout \li Each line of code should take no more than 120 characters. \li Use lots of whitespace to separate logical blocks of code, intermixed with comments \li DO NOT USE TABS. The standard indention is 2 spaces (see ITK Style Guide). Configure your editor accordingly. \li DO NOT USE trailing whitespaces \li Declaration of variables should be one declaration per line @code int sliceNumber; char* stringName; ImageType::Pointer image; @endcode \subsection StyleGuideAndNotesPage_ClassLayout Class Layout \li Copyright @code /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ @endcode \li Includes [A .. Z] @code #include "... .h" @endcode \li Namespace @code namespace mitk { @endcode DO NOT litter your header with "using namespace;"! \li Class (Template) @code template class ClassName : public ImageBase { @endcode \li Typedefs @code public: ....typedefs.... @endcode \li Methods @code public: ....methods.... protected: ....methods.... private: ....methods.... @endcode \li QT Signals @code signals: Signal...(); @endcode \li QT Slots @code public slots: On...(); protected slots: On...(); @endcode \li Data Member @code private/protected: ....class data members.... }; } #endif @endcode \section StyleGuideAndNotesPage_UseofBraces Use of Braces \li Used to delimit the scope of an if, for, while, switch. \li Braces are placed on a line by themselves: @code for ( unsigned int i = 0; i < 3; ++i ) { ... do something ... } @endcode or @code if ( condition ) { ... do something ... } else if ( other condition ) { ... do something ... } else { ... do something ... } @endcode \li You can choose to use braces on a line with a code block when the block consists of a single line: @code if ( condition ) { foo = 1; } else if ( condition2 ) { foo = 3; } else { return; } @endcode or @code for ( unsigned int i = 0; i < 3; ++i) { x[i] = 0.0; } @endcode \section StyleGuideAndNotesPage_IncludeGuards Include Guards -\li #inlcude guard is a particular construct used to avoid the problem of -double inclusion when dealing with the #include directive. +\li \#include guard is a particular construct used to avoid the problem of +double inclusion when dealing with the \#include directive. -\li Naming convention for #inlcude guards is: ClassName_h +\li Naming convention for \#include guards is: ClassName_h -\li Following example demonstrates a problem that can arise if #include guards +\li Following example demonstrates a problem that can arise if \#include guards are missing: Here, the file child.cpp has indirectly included two copies of the text in the header file grandfather.h. This causes a compilation error, since the structure type foo is apparently defined twice. @code grandfather.h struct foo { int m Member; }; father.h #include "grandfather.h" child.h #include "grandfather.h" #include "father.h" @endcode -\subsection StyleGuideAndNotesPage_Useofincludeguards Use of #include guards +\subsection StyleGuideAndNotesPage_Useofincludeguards Use of \#include guards \li Here, the first inclusion of grandfather.h causes the macro grandfather h to be defined. Then, when child.cpp includes grandfather.h the second time, -the #ifndef test fails, and the preprocessor skips down to the #endif, thus +the \#ifndef test fails, and the preprocessor skips down to the \#endif, thus avoiding the second definition of struct foo. The program compiles correctly. @code grandfather.h #ifndef grandfather h #define grandfather h struct foo { int m Member; }; father.h #include "grandfather.h" child.h #include "grandfather.h" #include "father.h" @endcode \section StyleGuideAndNotesPage_TechnicalNotes Some Technical Notes \li Use forward declarations in header files wherever possible. Only include those header files in a header file that are really necessary. Include the rest in the implementation file. \li For classes inheriting directly or indirectly from @a itk::LightObject (most of the MITK-classes do so), the class definition should include the mitkClassMacro. Additionally, if the class can be instantiated (normally the case, if the class is not abstract) and has @em only a constructor without parameters, the constructor should be declared protected and the @a itkFactorylessNewMacro should be used to create a @a New() method for instantiation. Here is an example: @code class ExampleClass : public SuperClassOfTheExampleClass { public: mitkClassMacro(ExampleClass, SuperClassOfTheExampleClass) itkFactorylessNewMacro(Self) [...] protected: ExampleClass(); virtual ~ExampleClass(); } @endcode \li Set- and Get-methods can be created with the macros @a itkSetObjectMacro(name,type) and @a itkGetObjectMacro(name,type), respectively, if the @a type is derived from @a itk::LightObject or @a itk::Object. There are also macros for other types, e.g., strings, see itkMacro.h. \li When using inner classes of a parent class which is templated, you have to use the keyword @a typename for gcc 3.x and standard compliance. For example, @a TreeChangeListener is an inner class of @a Tree, therefore use: @code class LinkedTree : public Tree { public: typedef typename LinkedTree::TreeChangeListener TreeChangeListener; [...] } @endcode Another example: @code typename std::vector::iterator pos = treeChangeListenerList.begin(); @endcode @a iterator is an inner class of @a vector. \li Constants in MITK for mitk::Operation and mitk::Action are set in namespace, so don't forget to add prefix @a mitk:: @code switch (actionId) { case mitk::AcMOVESELECTED: @endcode Prefixes for the constants are to be used like corresponding others. See file @a Interactions\\mitkBaseInteraction\\mitkInteractionConst.h for further details. \section StyleGuideAndNotesPage_AutomaticCodeFormatting Automatic Code Formatting We offer a .clang-format file, which can be used to automatically format code acceptably. -\include .clang-format - For an explanation of the different options check out http://clang.llvm.org/docs/ClangFormatStyleOptions.html */ diff --git a/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/HowToNewProject.dox b/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/HowToNewProject.dox index f7e9e689b4..cd5bd5e6f0 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/HowToNewProject.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/HowToNewProject.dox @@ -1,255 +1,255 @@ /** \page HowToNewProject Creating a new MITK project \tableofcontents This page is intended to give a comprehensive guide to setting up your own MITK based project. It will use the application framework provided by MITK and is probably the preferred way for most users. The first part of this document is a tutorial aimed at newcomers to MITK and possibly %CMake and tries to give as much help as possible on setting up your own project. If you are looking for more technical information about customizing MITK, the structure of the superbuild or packaging you might want to read the \ref HowToNewProjectAdvancedInformation. If you have set up your MITK project already and want to start developing you could take a look at \ref TutorialPage. \section HowToNewProjectGettingStarted Getting Started To bootstrap your project MITK offers two convenient options:
  1. Use the MITK Plugin Generator, a command line tool used to generate a customized MITK project and/or MITK plug-ins (available for download here).
  2. Use the MITK project template as an example project.
Both options will provide you with a project which contains a "superbuild" mechanism to automatically download, configure, and build MITK as a dependency of your own project. The MITK Plugin Generator generates code using the supplied command line arguments, whereas the MITK project template needs immediate modifications to customize it to your naming schemes. However, the project template will potentially contain more code demonstrating features of MITK. \note Using the MITK Plugin Generator is recommended for beginners. \section HowToNewProjectPrerequisites Prerequisites What ever option you choose, a MITK-based project needs essentially the same prerequisites as MITK itself. Please see \ref BuildInstructions_Prerequisites for details. \note If you use one of the two options above you will \b not \b need to build MITK yourself. This will be done automatically. \section HowToNewProjectCreatingSourceDir Preparing your source directory In order to start developing with MITK, you first have to set up the source directory for your project. \subsection HowToNewProjectSourceUsingGenerator Using the MITK Plugin Generator The usage of the Plugin Generator for creating a new project is described in \ref NewPluginWithProject, please have a look there. \subsection HowToNewProjectSourceUsingTemplate Using the MITK Project Template Download the project as a tarball or zipball and extract it to your desired source directory. -\note This is a \b template \b. You must modify it such that it fits the needs of +\note This is a template. You must modify it such that it fits the needs of your particular project. Especially you should do a global search and replace for the string "awesome" to rename the template application and plug-in. You may want to rename some files too. \section HowToNewProjectGeneratingCMake Generating your binary with CMake After you have set up your source directory you can proceed to generate your binary directory using %CMake. Depending on your operating system and preferences you might want to use "cmake-gui" or "ccmake" (shell). This document assumes you are using cmake-gui.
  1. Start "cmake-gui" and enter your source (e.g. "D:\AwesomeProject") and binary directory (e.g. "D:\AwesomeProject-superbuild").
  2. Upon first pressing "Configure" you will be prompted to select your generator. This determines what project files will be generated by %CMake. Set this to the development tool you are intending to use (e.g. "Visual Studio 2010 64Bit" or "linux makefiles".
  3. Press "Configure" until no new variables appear and then "Generate". Now all project files have been generated into your binary directory.
  4. Double-check that the right Qt version is used.
Now you are ready to compile your code. Depending on your choice of tool this will be done differently, we cover two possibilities here. \subsection HowToNewProjectCompilingLinuxMakefiles Compiling using linux makefiles
  1. In the shell, switch to your binary directory.
  2. type "make" and hit enter
\subsection HowToNewProjectCompilingVisualStudio Compiling using visual studio We assume your application is called "AwesomeApp" and your project "AwesomeProject" and your binary directory is "D:\AwesomeProject-superbuild\". Replace names and paths accordingly.
  1. Close %CMake and open "D:\AwesomeProject-superbuild\AwesomeProject-superbuild.sln". Your Visual Studio should appear and by pressing F7 you start the compilation. This will clone the MITK source code, build it, and then start building your own project.
  2. After the superbuild compilation has finished, close the superbuild solution file and start the build solution file "D:\AwesomeProject-superbuild\AwesomeProject-build\AwesomeProject.sln"
  3. Set the "AwesomeApp" project as start-up project (right click > "Set as StartUp Project") and press "F5" to start your MITK AwesomeApp.
\note Just opening AwesomeProject.sln from your explorer by double-cliking won`t allow you to start or debug your application because the required environment variables would be missing. Use the supplied batch files or set your PATH variable accordingly. \section HowToNewProjectAddingMITKFunctionality I want to use some MITK plugin but it is not available Due to the sheer number of MITK plugins not every plugin is activated by default. To activate a specific plugin (again replace paths as needed):
  1. Start "cmake-gui" and set the binary directory to "D:\AwesomeProject-superbuild\MITK-superbuild\MITK-build\", the source will adjust automatically and you will see new settings appear.
  2. Navigate to the plugin you want to use (e.g. "MITK_BUILD_org.mitk.gui.qt.segmentation") and tick the checkbox behind it
  3. Press "Configure" until no new variables appear and then "Generate".
  4. Build MITK using your development tool (as in \ref HowToNewProjectCompilingLinuxMakefiles or \ref HowToNewProjectCompilingVisualStudio only in the "D:\AwesomeProject-superbuild\MITK-superbuild\MITK-build\" directory )
  5. Start "cmake-gui" and set the binary directory to "D:\AwesomeProject-superbuild\AwesomeProject-build\", the source will adjust automatically and you will see new settings appear.
  6. Press "Configure" until no new variables appear and then "Generate".
  7. Build your project
  8. Start your application
\note If you want to use an application provided by MITK (e.g. MITK Workbench) you have to tick the appropriate checkbox as well (in this case MITK_BUILD_APP_Workbench) and build MITK. Do note, that this application will be located in the bin directory of the "D:\AwesomeProject-superbuild\MITK-superbuild\MITK-build\" folder. \section HowToNewProjectAdvancedInformation Information for advanced users \subsection HowToNewProjectCustomizingMITK Customizing MITK The %CMake scripts from the Plugin Generator of the project template provide some handy options which allow you to customize the MITK build used in your project. You can either inject an already build MITK to be used by your project or configure some MITK options directly in your project's superbuild configuration if MITK is going to be build inside your project. -\subsubsection HowToNewProjectCustomizingMITKInjectMITK Inject a MITK build +\subsubsection HowToNewProjectCustomizingMITKInjectMITK Inject a MITK build By setting the \b EXTERNAL_MITK_DIR \b variable in your project's superbuild %CMake configuration to a MITK build directory (containing the MITKConfig.cmake) you can skip the MITK build process. If MITK is the only external project in your project, you might want to disable the superbuild of your project completely (set _USE_SUPERBUILD to OFF or edit your CMakeLists.txt file to set it to OFF by default) and set the \b MITK_DIR \b %CMake variable to your MITK build directory. \subsubsection HowToNewProjectCustomizingMITKConfigure Configure the MITK superbuild If MITK is being build inside your project's superbuild process, you can enable the use of certain third-party libraries inside of MITK. The following variables control the MITK configuration:
  • \b MITK_USE_BLUEBERRY Enable the use of the BlueBerry application framework
  • \b MITK_USE_CTK Download, compile, and use CTK in MITK
  • \b MITK_USE_DCMTK Download, compile, and use DCMTK in MITK
  • \b MITK_USE_OpenCV Download, compile, and use OpenCV in MITK
  • \b MITK_USE_Python3 Download and compile 1CableSwig and enable Python wrapping in ITK, VTK, OpenCV, and MITK
  • \b MITK_USE_Qt5 Use the Qt 5 framework in MITK
You can also inject already build third-party libraries from inside your project's superbuild in the MITK superbuild by using any of the following %CMake variables:
  • \b MITK_CTK_DIR Reuse a CTK build directory in MITK.
  • \b MITK_CableSwig_DIR Reuse a 1CableSwig build directory in MITK.
  • \b MITK_DCMTK_DIR Reuse a DCMKT build directory in MITK.
  • \b MITK_GDCM_DIR Reuse a GDCM build directory in MITK.
  • \b MITK_ITK_DIR Reuse a ITK build directory in MITK.
  • \b MITK_OpenCV_DIR Reuse a OpenCV build directory in MITK.
  • \b MITK_VTK_DIR Reuse a VTK build directory in MITK.
If the corresponding \b MITK_USE_ \b option is set to on, the MITK superbuild will use the provided build directory instead of building the project itself. You can also control the source code location for MITK in your project's superbuild configuration by using the following %CMake variables:
  • \b MITK_SOURCE_DIR The path to the MITK source directory. If the value for this variable is non-empty, the variables below are ignored.
  • \b MITK_GIT_REPOSITORY The Git repository containing the MITK source code.
  • \b MITK_GIT_TAG The hash id, tag or branch name used for a checkout from MITK_GIT_REPOSITORY.
\subsubsection HowToNewProjectProjectStructure Project Structure If you are using the superbuild feature of the generated project (the default), you might want to familiarise yourself with the layout of your build tree. The top-level build directory which you specified in %CMake when configuring your project will contain all the required dependencies. Suppose we call our project MyProject and the build directory is "C:\MyProject-superbuild". Then the layout looks something like this: MyProjectLayout.png The top-level directory contains the source code and the build directories from the dependencies of your project. In the current case, the only dependency of MyProject is MITK, which in turn has downloaded and built its own dependencies (CTK, DCMTK, ITK, etc.). The "real" build tree for your project is located in MyProject-superbuild/MyProject-build, so point the %CMake-GUI to this build directory if you want to change the set of enabled plug-ins for example. Further, you should open the MyProject.sln solution file (for Visual Studio) or execute "make" in the MyProject-superbuild/MyProject-build/ directory. Only for the very first time or if you want to update and newly build the project's dependencies should you use the project files in the MyProject-superbuild directory directly. The same applies for the MyProject-superbuild/MITK-superbuild directory. This directory contains the MITK superbuild, nested inside your project's superbuild. If you want to change %CMake options for MITK, use the MyProject-superbuild/MITK-superbuild/MITK-build build directory. \imageMacro{HowToNewProject-MyProjectLayout.png,"Layout of MyProject",4.02} \subsubsection HowToNewProjectPackaging Packaging The project template and the generated projects by the Plugin Generator come with full packaging support. You can create deployable packages of your project for all supported operating systems my building the PACKAGE target. On Linux, this will create a tarball, on MacOS a .dmg file, and on Windows a zipball and an NSIS installer (if NSIS is installed and found). You can read more about deployment \ref DeploymentPage "here". */ diff --git a/Documentation/Doxygen/3-DeveloperManual/Starting/Starting.dox b/Documentation/Doxygen/3-DeveloperManual/Starting/Starting.dox index fb427a42ac..509cef90c3 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Starting/Starting.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Starting/Starting.dox @@ -1,40 +1,39 @@ /** \page StartingDevelopment Starting your MITK Development This introduction will acquaint you with the most important workflows to get you started with your MITK development. First, \ref Architecture will explain the differences between the application and the toolkit. \ref SettingUpMITK will get you started with a working environment for MITK development. \ref GettingToKnowMITK will walk you trough the folder structure, the module system, and plugin system. This chapter also contains an extensive tutorial on how to work with MITK. The \ref FirstSteps section will then show you how to extend MITK for your own project.
  • \subpage Architecture
  • \subpage SettingUpMITK
    • \ref SupportedPlatformsPage
    • \ref BuildInstructionsPage
    • \ref thirdpartylibs
    • -
    • \ref HowToNewProject
    • +
    • \ref HowToNewProject
  • \subpage GettingToKnowMITK
    • \ref DirectoryStructurePage
    • \ref TutorialPage
    • \ref CMAKE_FAQ
    • \ref StyleGuideAndNotesPage
    • \ref DocumentationGuide
    • \ref CodingPage
    • \ref KnownProblemsPage
  • \subpage FirstSteps
    • \ref NewPluginPage
    • \ref NewViewPage
    • \ref NewModulePage
    • -
    • \ref CMAKE_FAQ
    • -
    • \ref StatemachineEditor
    • +
    • \ref CMAKE_FAQ
  • \subpage AboutTestingPage
*/ diff --git a/Modules/Chart/documentation/mitkChart.dox b/Modules/Chart/documentation/mitkChart.dox index af69c4dc5e..a1a7e98a13 100644 --- a/Modules/Chart/documentation/mitkChart.dox +++ b/Modules/Chart/documentation/mitkChart.dox @@ -1,256 +1,256 @@ /** \page ChartModule Chart Module \tableofcontents \section ChartModule_brief Description The MITK chart module is able to show different types of charts in a widget with customizable labels. \imageMacro{complexExample.png,"Example chart",10} \subsection Chart_Technical Technical background The module uses the java script library plotly to display the chart in a QWebEngineView (that renders html/js content). For examples, please visit https://plot.ly/javascript/. \subsection Chart_GUI GUI \note Be sure that the dependency to the Chart Module is resolved in the CMakeLists.txt of the plugin: MODULE_DEPENDS MitkChart. Open the ui file of the plugin. Then add a widget (we always use the name chartWidget in the following) at the desired position. Change the class of the widget to a user-defined widget (right click → user defined classes, see http://doc.qt.io/qt-5/designer-using-custom-widgets.html). Set "QWidget" as base class. Set "QmitkChartWidget" as class name and "QmitkChartWidget.h" as include file. \imageMacro{userDefinedWidget.png,"User defined widget",10} \subsection Chart_data Data The most important functionality is to add data to the chartWidget. Either one dimensional or two dimensional data can be used. One-dimensional data has the same interval between values on the x-axis (and no x-axis values) while the two-dimensional data has arbitrary x-axis difference values (and given x-axis values). An example for one-dimensional data is the temperature for each month of a year: std::vector temperatureHD = {1.8, 3.1, 6.3, 10.2, 14.5, 17.4, 19.4, 18.9, 15.5, 11.2, 5.8, 2.6}. The first entry corresponds (implicitly) to the temperature in january, two second to the temperature in february the last entry to the temperature in december. Thus, the x values have same intervals. The given temperature values are defined as y-axis values. An example for two-dimensional data is the people living in a city in different years: std::map peopleHeidelberg={{1975, 129368 }, { 1985, 134724 },{ 1990, 136796 },{ 2010, 147312 }}. Thus, the x-values are given as their intervals are different (10 years, 5 years, 10 years). Each x value is connected to an y-value that represents the amount of people (1975 → 129368, 1985 → 134724, ...). Data is added by calling chartWidget->AddData1D(temperatureHD, "Heidelberg") or chartWidget->AddData2D(peopleHeidelberg, "Heidelberg"), where the second argument is a label for the data entry. \imageMacro{2DDataExample.png,"2D data example: Heidelberg has fewer entries and their x-range (years) is smaller than Freiburg",8} As the data labels are used as identifier, they have to be unique. This is checked. If non-unique entries are entered, they are made unique by adding numbers. Example: \code{.cpp} chartWidget->AddData1D(temperatureHD, "Heidelberg") chartWidget->AddData1D(temperatureOslo, "Heidelberg") \endcode will result in the labels "Heidelberg" and "Heidelberg0", whereas "Heidelberg0" refers to temperatureOslo. If you want to add more data, just call chartWidget->AddData1D(data, label, chartType) or chartWidget->AddData2D(data, label, chartType) as often as desired. Then, call chartWidget->Show(). The ranges of x- and y-axis are adjusted automatically. To delete single data entries, call chartWidget->RemoveData(label) and update the chart area with chartWidget->Show(). All data can be cleared by calling chartWidget->Clear(). \subsection Chart_type Chart type The default chart type is bar. To use a different type, you have to change it. Seven chart types are available:
  • bar
  • line
  • spline
  • pie
  • are
  • area_spline
  • scatter
See below examples of all types: \imageMacro{barChartTemperature.png,"Example bar chart",4} \imageMacro{lineChartTemperature.png,"Example line chart",4} \imageMacro{splineChartTemperature.png,"Example spline chart",4} \imageMacro{pieChartExample.png,"Example pie chart",4} \imageMacro{areaChartTemperature.png,"Example area chart",4} \imageMacro{areaSplineChartTemperature.png,"Example spline area chart",4} \imageMacro{scatterChartTemperature.png,"Example scatter chart",4} Call e.g. chartWidget->SetChartType(label, QmitkChartWidget::ChartType::line) for changing the chart type. Note that it is not directly displayed. To change the chart type for all data entries and display the result, call chartWidget->SetChartTypeForAllDataAndReload(QmitkChartWidget::ChartType::line). All chart types except pie chart can be also used mixed (different chart types in the same chart). Pie charts are handled differently. The input data sum is regarded as 100%. The values of all data entries are summed. Example: \code{.cpp} chartWidget->AddData1D({5}, "entry1", QmitkChartWidget::ChartType::pie); chartWidget->AddData1D({2}, "entry2", QmitkChartWidget::ChartType::pie); chartWidget->AddData1D({3}, "entry3", QmitkChartWidget::ChartType::pie); \endcode The pie chart has then entries of 50%, 20% and 30%. Calling chartWidget->AddData1D({5,2,3}, "entry", QmitkChartWidget::ChartType::pie) leads to a pie chart with one class having 100%. Calling \code{.cpp} chartWidget->AddData1D({2,2,1}, "entry1", QmitkChartWidget::ChartType::pie); chartWidget->AddData1D({1,1}, "entry2", QmitkChartWidget::ChartType::pie); chartWidget->AddData1D({3}, "entry3", QmitkChartWidget::ChartType::pie); \endcode leads to the first result again (50%, 20% and 30%) as entries are summed. \warning pie charts differ significantly from the other chart types. Be aware of the differences. \subsection Chart_labels Labels Four labels can be set to custom strings. These are
  • the data labels,
  • the x-axis label,
  • the y-axis label and
  • the title of the chart
Data labels provide the name for data legend entries ("Heidelberg" for our 1D data \ref{Chart_data} as it is the average temperature in Heidelberg) and are given by the second argument of AddData1D and AddData2D. They are also displayed in the legend. An example x-Axis and y-axis label would be month and temperature, respectively. The data label argument is mandatory. All other labels are optional and empty strings by default. chartWidget->SetXAxisLabel("month") and chartWidget->SetYAxisLabel("temperature") ensures the labeling of x- and y-Axis in the chart. No labels are defined as default. chartWidget->SetTitle("temperature chart") adds a title to the chart. \note The legend position (of data labels) can be set by chartWidget->SetLegendPosition(QmitkChartWidget::LegendPosition::bottom). \note To hide the legend, call chartWidget->SetShowLegend(false). \subsection Chart_show Displaying the chart Finally, the chart is displayed by calling chartWidget->Show(bool). If the optional parameter is set to true, a subchart is shown additionally. That's useful for ensuring the overview if the user wants to zoom in. \subsection Chart_dataAttributes Changing visualization attributes of data Besides the chart type, the following attributes of a data entry can be changed:
  • color,
  • linesyle and
  • data points shown
this is done by referencing the data entry by its label (e.g. "Heidelberg" above): chartWidget->SetColor("Heidelberg", "green"), chartWidget->SetColor("Heidelberg", "#FF4500"), chartWidget->SetLineStyle("Heidelberg", LineStyle::dashed) and chartWidget->SetShowDataPoints(false). \note SetShowDataPoints is a global attribute and valid for all data entries due to technical reasons. -Colors are chosen automatically by plotly if not given. However, if some data entries have given colors and some have not, same colors may appear for different data entries. Color can be given as strings (natural names like red or hexadecimal numbers like #FF0000. For color selection, the following reference is helpful: https://www.w3schools.com/cssref/css_colors.asp) +Colors are chosen automatically by plotly if not given. However, if some data entries have given colors and some have not, same colors may appear for different data entries. Color can be given as strings (natural names like red or hexadecimal numbers like \c \#FF0000 . For color selection, the following reference is helpful: https://www.w3schools.com/cssref/css_colors.asp) Line style only can be set if ChartType is QmitkChartWidget::ChartType::line. It is ignored otherwise. Also, if a non-existing label is given, the command is ignored. The default linestyle is LineStyle::solid. \section Chart_example Example \subsection Chart_exampleBarChart Bar chart To create and visualize a bar chart with two data sets, x/y-axis labels and data labels, the following code is used: \code{.cpp} std::vector temperatureHD = {1.8, 3.1, 6.3, 10.2, 14.5, 17.4, 19.4, 18.9, 15.5, 11.2, 5.8, 2.6}; std::vector temperatureOslo = {-4.3, -4, -0.2, 4.6, 10.8, 15.2, 16.4, 15.2, 10.8, 6.4, 0.7, -2.8}; chartWidget->AddData1D(temperatureHD, "Heidelberg", QmitkChartWidget::ChartType::bar); chartWidget->AddData1D(temperatureOslo, "Oslo", QmitkChartWidget::ChartType::bar); chartWidget->SetXAxisLabel("month"); chartWidget->SetYAxisLabel("temperature"); chartWidget->Show(); \endcode The order when AddData1D() is called influences the colors of the bars and the order of the shown data. The third argument of chartWidget->AddData1D() is superfluous and only for completeness as QmitkChartWidget::ChartType::bar is the default chart type. After Show() is called, the chart is visualized. The chart type for all data entries can be changed to spline and directly showed: \code{.cpp} chartWidget->SetChartTypeForAllDataAndReload(QmitkChartWidget::ChartType::spline); \endcode the equivalent code is: \code{.cpp} chartWidget->SetChartType("Heidelberg", QmitkChartWidget::ChartType::spline); chartWidget->SetChartType("Oslo", QmitkChartWidget::ChartType::spline); chartWidget->Show(); \endcode The temperature of another city can be added: \code{.cpp} std::vector temperatureRome = {8.1, 8.7, 8.7, 11.6, 18.8, 22.8, 25.4, 25.7, 21.4, 17.6, 12.6, 8.9}; chartWidget->AddData1D(temperatureRome, "Rome"); chartWidget->Show(true); \endcode As Show(true) is used, a subchart is shown. \subsection Chart_examplePieChart Pie chart -A pie chart (the same as in \ref Chart_type) can be generated with the following code: +A pie chart (the same as in \ref Chart_type ) can be generated with the following code: \code{.cpp} chartWidget->AddData1D({5}, "Heidelberg", QmitkChartWidget::ChartType::pie); chartWidget->AddData1D({3}, "Oslo", QmitkChartWidget::ChartType::pie); chartWidget->AddData1D({2}, "New York", QmitkChartWidget::ChartType::pie); chartWidget->Show(); \endcode \note Only one pie chart at a time can be displayed. \subsection Chart_exampleMixedChart Mixed chart -Chart types and attributes like colors and line styles can be mixed as seen in the code example below (example result is the chart in \ref ChartModule_brief): +Chart types and attributes like colors and line styles can be mixed as seen in the code example below (example result is the chart in \ref ChartModule_brief ): \code{.cpp} std::vector temperatureHD = {1.8, 3.1, 6.3, 10.2, 14.5, 17.4, 19.4, 18.9, 15.5, 11.2, 5.8, 2.6}; std::vector temperatureOslo = {-4.3, -4, -0.2, 4.6, 10.8, 15.2, 16.4, 15.2, 10.8, 6.4, 0.7, -2.8}; chartWidget->AddData1D(temperatureHD, "Heidelberg", QmitkChartWidget::ChartType::line); chartWidget->AddData1D(temperatureOslo, "Oslo", QmitkChartWidget::ChartType::area); chartWidget->SetColor("Heidelberg", "green"); chartWidget->SetColor("Oslo", "blue"); chartWidget->SetLineStyle("Heidelberg", QmitkChartWidget::LineStyle::dashed); chartWidget->SetXAxisLabel("month"); chartWidget->SetYAxisLabel("temperature"); chartWidget->Show(); \endcode \note Pie chart as chart type is an exception. Pie charts can't be displayed with other data entries having other chart types. \subsection Chart_exampleRemoveData Removing data Data also can be removed again (using the previous example \ref Chart_exampleMixedChart as base): \code{.cpp} chartWidget->RemoveData("Heidelberg"); chartWidget->Show(); \endcode Only the date entries labeled "Oslo" remain. Also all data can be removed: \code{.cpp} chartWidget->Clear(); chartWidget->Show(); \endcode The chart is empty now. \subsection Chart_example2DData Chart with 2D data -A line chart with two-dimensional data is the following example (the same as in \ref Chart_data): +A line chart with two-dimensional data is the following example (the same as in \ref Chart_data ): \code{.cpp} std::map peopleHD = { {1975, 129368 }, { 1985, 134724 },{ 1990, 136796 },{ 2010, 147312 } }; std::map peopleFreiburg = { { 1969, 165960 },{ 1973, 174997 },{ 1982, 178545 },{ 2001, 208294 },{ 2015, 222203 } }; chartWidget->AddData2D(peopleHD, "Heidelberg", QmitkChartWidget::ChartType::line); chartWidget->AddData2D(peopleFreiburg, "Freiburg", QmitkChartWidget::ChartType::line); chartWidget->SetXAxisLabel("year"); chartWidget->SetYAxisLabel("people"); chartWidget->Show(); \endcode Hence, 2D data is having the following assignment: year → people. In the vector peopleHD, four values are defined, in the vector peopleFreiburg, five values are defined. The defined years are different for Heidelberg (1975-2010) than for Freiburg (1969-2015). \warning mixing AddData2D and AddData1D in a chart is strongly discouraged. It will work, however the visualization may be odd due to implicit and explicit given x values. \subsection Chart_imageStatistics image statistics plugin -An example of the use of QmitkChartWidget in MITK can be found in the image statistics plugin (org.mitk.gui.qt.measurementtoolbox\QmitkImageStatisticsView). The chartWidget is named m_Controls->m_JSHistogram there. +An example of the use of QmitkChartWidget in MITK can be found in the image statistics plugin. The \c chartWidget is named \c m_Controls->m_JSHistogram there. */ diff --git a/Modules/PhotoacousticsAlgorithms/Documentation/doxygen/PAModule.dox b/Modules/PhotoacousticsAlgorithms/Documentation/doxygen/PAModule.dox index 2244e8e7c8..9cbcf6d54a 100644 --- a/Modules/PhotoacousticsAlgorithms/Documentation/doxygen/PAModule.dox +++ b/Modules/PhotoacousticsAlgorithms/Documentation/doxygen/PAModule.dox @@ -1,45 +1,45 @@ /** \page PAModulePage Photoacoustic Algorithms Module \tableofcontents \section PAModulePageOverview Overview The Photoacoustic Algorithms Module provides a set of filters for beamforming and post-processing of photoacoustic and ultrasound data. The main features are:
  • Management of all filters through a single class PhotoacousticImage
  • Beamforming of ultrasound and photoacoustic image data.
    • Beamforming using the DAS and DMAS Algorithms.
    • Optional real-time beamforming capabilities by the usage of openCL GPU computing
  • Post/Pre-Processing of any kind of images.
    • Crop Filter for removing artefacts in upper and lower edge of the image.
    • Multiple B-Mode Filter implementations with resampling and logarithmic filter.
    • Bandpass Filter
To use the GPU capabilities of this module, openCL needs to be activated in CMAKE. The custom build option "camiPhotoacousticsWorkstation" activates all needed CMAKE options, as well as openCL. To build the project using openCL, the openCL libraries provided by your graphic card vendor need to be installed. The GPU capabilies of this module have been only tested using nvidia hardware, but, as openCL has been also implemented by AMD, this should work on either one. (Those are included in the CUDA package for nvidia graphic card owners) The \link org_mitk_gui_qt_photoacoustics_imageprocessing Photoacoustic Imageprocessing plugin \endlink provides a GUI to access all of thePhotoacoustic Algorithms Module's filters. \section PAModuleClasses The Photoacoustic Algorithms Module's Classes
  • mitk::PhotoacousticImage: The class where all filters are managed.
  • mitk::BeamformingSettings: The class used by many filters for storing the configuration to be used when applying them.
  • Five filters are currently implemented in the Photoacoustic Algorithms module:
      -
    • mitk::PhotoacousticBModeFilter/mitk::PhotoacousticOCLBModeFilter: Two classes for the B-Mode filter on GPU and CPU. +
    • mitk::PhotoacousticBModeFilter: A class for the B-Mode filter on GPU and CPU.
    • Resampling Filter: A resampling filter for post-processing.
    • mitk::BeamformingFilter: A filter with a switch for GPU/CPU computation, to compute the beamformed image out of raw ultrasound/photoacoustic data.
    • Crop Filter: A filter for cropping artifacts on the upper and lower edges of the image.
    • Bandpass Filter: A Filter to filter image data in the fourier domain, using a tukey window to cut off low or high frequency parts of the image.
*/ \ No newline at end of file diff --git a/Modules/ToFHardware/Documentation/doxygen/GeneratingDeviceModules.dox b/Modules/ToFHardware/Documentation/doxygen/GeneratingDeviceModules.dox index 2a588198f6..a68f66ab75 100644 --- a/Modules/ToFHardware/Documentation/doxygen/GeneratingDeviceModules.dox +++ b/Modules/ToFHardware/Documentation/doxygen/GeneratingDeviceModules.dox @@ -1,90 +1,90 @@ /** \page GeneratingDeviceModulesPage How to generate ToF DeviceModules The ToF-DeviceModule-Tutorial will help you implementing a new ToF-Device easily. Using MicroServices for this purpose will be one of our main goals, too. If you do not know much about MicroServices, please take a look at: \ref MicroServices_Overview \section GeneratingDeviceModulsPageSec1 Generating a ToF-Device-Module in MITK In order to implement your own device, you need to code the following objects:
  • device (the device itself)
  • device factory (a singleton which produces instances of your device)
  • controller (connection to the Hardware-SDK)
  • Module Activator (Important for the MicroServices. This class ensures the automatic loading of the device.)
The following example shows how to implement a device, here we take the Kinect.
  1. Creating a Sub-Folder \n Following the Kinect-DeviceModule as a prototype, create a MODULENAME-Sub-Folder in your source directory. This MODULENAME-Folder is going to hold all the necessary files we will create in the next steps.
  2. Create the CMake Files for our new camera-model in the MODULENAME-Folder <
    • CMakeList.txt In this file, the module is generated via CMake commands. The module name is set, the necessary libraries will be searched here in order to link them with your module. For the Kinect, we chose OpenNI and need the XnCppWrapper.h. Your device must inherit from the mitkToFCameraDevice and consequently your module must depend on mitkToFHardware -> what is the reason for the DEPENDS mitkToFHardware -line. For autoloading your Module with mitkToFHardware, insert the following CMake Macro: AUTOLOAD_WITH mitkToFHardware . We usually add an option for the user to activate the device module, but this is not essential (refer to OPTION(MITK_USE_TOF_KINECT "Enable support for Kinect camera" OFF)). \n -> refer to CMakeList.text in the Kinect-Folder - \Warning The dll/so files are not automatically deleted. + Warning: The dll/so files are not automatically deleted. \n
    • files.cmake The files.cmake contains all the previously mentioned files (device, deviceFactory, controller, and ModuleActivator) \n -> refer to mitkKinectActivator.cpp
  3. Creating the Code Files in the MODULENAME-Folder
    • \a MODULENAMEController \n -> While referring to mitkKinectcontroller.cpp and the mitkKinectcontroller.h, take a good look at the definition of the MITK_KINECTMODULE_EXPORT-class in the .h file \n
    • \a MODULENAMEDevice Your device must inherit from ToFCameraDevice (e.g. class MITK_KINECTMODULE_EXPORT KinectDevice : public ToFCameraDevice) and consequently implement the methods of the ToFCameraDevice MicroService-Interface. (See ToFCameraDevice.h). Make sure to give your device a specific name in the method GetDeviceName(). All instances of your device will automatically be available in the view "ToFUtil", if you generate it via the factory. \n -> refer to mitkKinectDevice.cpp and the mitkKinectDevice.h. \n
    • \a MODULENAMEDeviceFactory Like the mitkToFCameraDevice, the mitkIToFDeviceFactory is a MicroService-Interface. The factory is meant for generation of devices of the same type. This concept allows for having multiple instances of the same camera connected. (Currently our GUI does not really support an actual connection of multiple devices, but the software framework, in principle, does.) Your factory must inherit from the mitkAbstractDeviceFactory, which provides some useful methods for device generation. Your factory instance should be registered as MicroService in order to be available in the view "ToF Device Generation". \n -> refer to mitkKinectDeviceFactory.cpp and the mitkKinectDeviceFactory.h \n
    • \a MODULENAMEActivator The load() method of this class will be called when the module is activated. If you would like to have an instance of your device registered as MicroService, you should call deviceFactory->ConnectToFDevice(); here. In addition, you can generate devices anywhere in your code via this method. The factory will automatically be available in the view "ToF Device Generation" if you register it like we do with the Kinect. TODO: Code example: \n ->refer to mitkKinectActivator.cpp and the mitkKinectActivator.h or the mitkPMDModuleActivator.cpp and the mitkPMDModuleActivator.h.
\n If you did everything correct, your Module should be implemented an executable MODULENAME-Project will be generated and a working device should show up in the ServiceListWidget in the Connection-Part of ToFUtil. Warning The dll/so files are not automatically deleted. After deactivating a device, please delete the concerning files in SUPERBUILDDIR/MITK-build/bin/mitkToFHardware/BUILDTYPE \section GeneratingDeviceModulsPageSec2 [OPTIONAL] Adding a Testing Sub-Directory If you have any Tests you want to include, a Testing-Subdirectory in the newly created MODULENAME-Folder should be created. In this Folder we are going to put a CMakeLists.txt and a files.cmake the first one will just consist \code MITK_CREATE_MODULE_TESTS() \endcode while the later one, the files.cmake holds Information about TestFiles you created and put in the Folder. E.g. for the Kinect: \code set(MODULE_TESTS mitkKinectControllerTest.cpp mitkKinectDeviceTest.cpp ) \endcode As before, feel free to take a look at one of the existing Modules and their Testing-Subfolder as the Kinect´s. If you managed to implement your Module properly, an executable MODULENAMETestDriver will be generated. */