1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_FreeFormTransformationIntegrationMethod_H
21 #define MIRTK_FreeFormTransformationIntegrationMethod_H
22 
23 #include "mirtk/String.h"
24 
25 
26 namespace mirtk {
27 
28 
29 // ---------------------------------------------------------------------------
30 /// Enumeration of implemented numerical integration methods
31 enum FFDIntegrationMethod
32 {
33   FFDIM_Unknown = 0,                                                   // keep at begin
34   FFDIM_RKE1,   FFDIM_RKE2,   FFDIM_RKH2,  FFDIM_RK4,                  // explicit RK
35   FFDIM_RKEH12, FFDIM_RKBS23, FFDIM_RKF45, FFDIM_RKDP45, FFDIM_RKCK45, // embedded RK
36   FFDIM_SS, FFDIM_FastSS,                                              // scaling and squaring
37   FFDIM_Last                                                           // keep at end
38 };
39 
40 typedef FFDIntegrationMethod FFDIM;
41 
42 // ---------------------------------------------------------------------------
43 /// Convert FFD integration method enumeration value to string
44 template <>
ToString(const FFDIM & m,int w,char c,bool left)45 inline string ToString(const FFDIM &m, int w, char c, bool left)
46 {
47   const char *str;
48   switch (m) {
49     case FFDIM_SS:     str = "SS";      break;
50     case FFDIM_FastSS: str = "FastSS";  break;
51     case FFDIM_RKE1:   str = "RKE1";    break;
52     case FFDIM_RKE2:   str = "RKE2";    break;
53     case FFDIM_RKH2:   str = "RKH2";    break;
54     case FFDIM_RK4:    str = "RK4";     break;
55     case FFDIM_RKEH12: str = "RKEH12";  break;
56     case FFDIM_RKBS23: str = "RKBS23";  break;
57     case FFDIM_RKF45:  str = "RKF45";   break;
58     case FFDIM_RKDP45: str = "RKDP45";  break;
59     case FFDIM_RKCK45: str = "RKCK45";  break;
60     default:           str = "Unknown"; break;
61   }
62   return ToString(str, w, c, left);
63 }
64 
65 // ---------------------------------------------------------------------------
66 /// Convert FFD integration method string to enumeration value
67 template <>
FromString(const char * str,FFDIM & value)68 inline bool FromString(const char *str, FFDIM &value)
69 {
70   // Aliases of methods
71   const string lstr = ToLower(str);
72   if      (lstr == "scalingandsquaring")        value = FFDIM_SS;
73   else if (lstr == "scaling and squaring")      value = FFDIM_SS;
74   else if (lstr == "fastscalingandsquaring")    value = FFDIM_FastSS;
75   else if (lstr == "fast scaling and squaring") value = FFDIM_FastSS;
76   else if (lstr == "euler")                     value = FFDIM_RKE1;
77   else if (lstr == "forwardeuler")              value = FFDIM_RKE1;
78   else if (lstr == "forward euler")             value = FFDIM_RKE1;
79   else if (lstr == "fwdeuler")                  value = FFDIM_RKE1;
80   else if (lstr == "modifiedeuler")             value = FFDIM_RKE2;
81   else if (lstr == "modified euler")            value = FFDIM_RKE2;
82   else if (lstr == "modeuler")                  value = FFDIM_RKE2;
83   else if (lstr == "heun")                      value = FFDIM_RKH2;
84   else if (lstr == "improvedeuler")             value = FFDIM_RKH2;
85   else if (lstr == "improved euler")            value = FFDIM_RKH2;
86   else if (lstr == "impeuler")                  value = FFDIM_RKH2;
87   else if (lstr == "rk1")                       value = FFDIM_RKE1;
88   else if (lstr == "rk2")                       value = FFDIM_RKH2;
89   else if (lstr == "rk12")                      value = FFDIM_RKEH12;
90   else if (lstr == "rk23")                      value = FFDIM_RKBS23;
91   else if (lstr == "rk45")                      value = FFDIM_RKCK45;
92   else                                          value = FFDIM_Unknown;
93   // Default names
94   if (value == FFDIM_Unknown) {
95     value = static_cast<FFDIM>(FFDIM_Last - 1);
96     while (value != FFDIM_Unknown) {
97       if (iequal(ToString(value).c_str(), str)) break;
98       value = static_cast<FFDIM>(value - 1);
99     }
100   }
101   // Return whether conversion was successful
102   return (value != FFDIM_Unknown);
103 }
104 
105 
106 } // namespace mirtk
107 
108 #endif // MIRTK_FreeFormTransformationIntegrationMethod_H
109