]> Creatis software - clitk.git/blob - common/clitkCommon.cxx
Add preserve studyUID in clitkImage2Dicom
[clitk.git] / common / clitkCommon.cxx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://www.centreleonberard.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18
19 #ifndef CLITKCOMMON_CXX
20 #define CLITKCOMMON_CXX
21
22 #include <itksys/SystemTools.hxx>
23
24 #ifdef _WIN32
25   #define _USE_MATH_DEFINES
26   #include <cmath>
27   const double M_PI = std::acos(-1.0);
28 #endif
29
30 // clitk include 
31 #include "clitkCommon.h"
32
33 // std include 
34 #include <fstream>
35 #include <iomanip>
36 #include <sstream>
37 #include <cerrno>
38
39 //------------------------------------------------------------------
40 // skip line which begin with a sharp '#'
41 void clitk::skipComment(std::istream & is)
42 {
43   char c;
44   char line[1024];
45   if (is.eof()) return;
46   is >> c ;
47   while (is && (c == '#')) {
48     is.getline (line, 1024);
49     is >> c;
50     if (is.eof()) return;
51   }
52   if (!(is.fail()) && c != '\n')
53     is.unget();
54 } ////
55 //------------------------------------------------------------------
56
57 //------------------------------------------------------------------
58 // linear (rough) conversion from Hounsfield Unit to density
59 double clitk::HU2density(double HU)
60 {
61   return (HU+1000.0)/1000.0;
62 } ////
63 //------------------------------------------------------------------
64
65 //------------------------------------------------------------------
66 // Return filename extension
67 std::string clitk::GetExtension(const std::string& filename)
68 {
69   // This assumes that the final '.' in a file name is the delimiter
70   // for the file's extension type
71   const std::string::size_type it = filename.find_last_of( "." );
72   // This determines the file's type by creating a new string
73   // who's value is the extension of the input filename
74   // eg. "myimage.gif" has an extension of "gif"
75   std::string fileExt( filename, it+1, filename.length() );
76   return( fileExt );
77 } ////
78 //------------------------------------------------------------------
79
80
81 //------------------------------------------------------------------
82 // Return filename splitting in 1 or 2 parts : directory name (if exists) & filename
83 std::vector<std::string> clitk::SplitFilename(const std::string& filename)
84 {
85   std::vector<std::string> dirname;
86   std::string path = itksys::SystemTools::GetFilenamePath(filename);
87   std::vector<std::string> pathComponents;
88   itksys::SystemTools::SplitPath(filename.c_str(), pathComponents);
89   std::string fileName = pathComponents.back();
90   if (path != "")
91     dirname.push_back(path);
92   dirname.push_back(fileName);
93   return( dirname );
94 } ////
95 //------------------------------------------------------------------
96
97
98 //------------------------------------------------------------------
99 // Display progression
100 void clitk::VerboseInProgress(const int nb, const int current, const int percentage)
101 {
102   static int previous = -1;
103   const int rounded = (100*current)/nb;
104   if (previous==rounded) return;
105   previous = rounded;
106
107   std::ostringstream oss;
108   oss << std::setw(4) << rounded << '%';
109
110   std::cout << oss.str() << std::flush;
111   for (unsigned int i=0; i<oss.str().length(); ++i)
112     std::cout << "\b" << std::flush;
113 }
114 //------------------------------------------------------------------
115
116 //------------------------------------------------------------------
117 // Display progression
118 void clitk::VerboseInProgressInPercentage(const int nb, const int current, const int percentage)
119 {
120   VerboseInProgress(nb, current, percentage);
121 }
122 //------------------------------------------------------------------
123
124 //------------------------------------------------------------------
125 // Convert a pixel type to another (downcast)
126 template<>
127 float clitk::PixelTypeDownCast(const double & x)
128 {
129   return (float)x;
130 }
131 //------------------------------------------------------------------
132
133 //------------------------------------------------------------------
134 // Convert a pixel type without casting
135 template<>
136 double clitk::PixelTypeDownCast(const double & x)
137 {
138   return x;
139 }
140 //------------------------------------------------------------------
141
142 //------------------------------------------------------------------
143 double clitk::rad2deg(const double anglerad)
144 {
145   return (anglerad/M_PI*180.0);
146 }
147 //------------------------------------------------------------------
148
149 //------------------------------------------------------------------
150 double clitk::deg2rad(const double angledeg)
151 {
152   return (angledeg*(M_PI/180.0));
153 }
154 //------------------------------------------------------------------
155
156 //------------------------------------------------------------------
157 int clitk::GetTypeSizeFromString(const std::string & type)
158 {
159 #define RETURN_SIZEOF_PIXEL(TYPENAME, TYPE)             \
160   if (type == #TYPENAME) return sizeof(TYPE);
161   RETURN_SIZEOF_PIXEL(char, char);
162   RETURN_SIZEOF_PIXEL(uchar, uchar);
163   RETURN_SIZEOF_PIXEL(unsigned char, uchar);
164   RETURN_SIZEOF_PIXEL(unsigned_char, uchar);
165   RETURN_SIZEOF_PIXEL(short, short);
166   RETURN_SIZEOF_PIXEL(ushort, ushort);
167   RETURN_SIZEOF_PIXEL(unsigned_short, ushort);
168   RETURN_SIZEOF_PIXEL(int, int);
169   RETURN_SIZEOF_PIXEL(uint, uint);
170   RETURN_SIZEOF_PIXEL(unsigned_int, uint);
171   RETURN_SIZEOF_PIXEL(float, float);
172   RETURN_SIZEOF_PIXEL(double, double);
173   return 0;
174 }
175 //------------------------------------------------------------------
176
177 //------------------------------------------------------------------
178 template<>
179 bool clitk::IsSameType<signed char>(std::string t)
180 {
181   if ((t==GetTypeAsString<signed char>()) || (t == "schar")) return true;
182   else return false;
183 }
184
185 template<>
186 bool clitk::IsSameType<char>(std::string t)
187 {
188   if ((t==GetTypeAsString<char>()) || (t == "char")) return true;
189   else return false;
190 }
191
192 template<>
193 bool clitk::IsSameType<unsigned char>(std::string t)
194 {
195   if ((t==GetTypeAsString<unsigned char>()) || (t == "uchar")) return true;
196   else return false;
197 }
198
199 template<>
200 bool clitk::IsSameType<unsigned short>(std::string t)
201 {
202   if ((t==GetTypeAsString<unsigned short>()) || (t == "ushort")) return true;
203   else return false;
204 }
205 //------------------------------------------------------------------
206
207 //------------------------------------------------------------------
208 void clitk::FindAndReplace(std::string & line,
209                            const std::string & tofind,
210                            const std::string & replacement)
211 {
212   int pos = line.find(tofind);
213   while (pos!= (int)std::string::npos) {
214     line.replace(pos, tofind.size(), replacement);
215     pos = line.find(tofind, pos+tofind.size()+1);
216   }
217 }
218 //------------------------------------------------------------------
219
220 //------------------------------------------------------------------
221 void clitk::FindAndReplace(std::string & line,
222                            const std::vector<std::string> & tofind,
223                            const std::vector<std::string> & toreplace)
224 {
225   for(unsigned int i=0; i<tofind.size(); i++) {
226     FindAndReplace(line, tofind[i], toreplace[i]);
227   }
228 }
229 //------------------------------------------------------------------
230
231 //------------------------------------------------------------------
232 void clitk::FindAndReplace(std::ifstream & in,
233                            const std::vector<std::string> & tofind,
234                            const std::vector<std::string> & toreplace,
235                            std::ofstream & out)
236 {
237   std::string line;
238   if (tofind.size() != toreplace.size()) {
239     std::cerr << "Error' tofind' is size=" << tofind.size() << std::endl;
240     std::cerr << "... while 'toreplace' is size=" << toreplace.size() << std::endl;
241     exit(0);
242   }
243   while (std::getline(in,line)) {
244     FindAndReplace(line, tofind, toreplace);
245     out << line << std::endl;
246   }
247 }
248 //------------------------------------------------------------------
249
250 //------------------------------------------------------------------
251 double clitk::ComputeEuclideanDistanceFromPointToPlane(const itk::ContinuousIndex<double, 3> point,
252     const itk::ContinuousIndex<double, 3> pointInPlane,
253     const itk::ContinuousIndex<double, 3> normalPlane)
254 {
255   // http://mathworld.wolfram.com/Plane.html
256   // http://mathworld.wolfram.com/Point-PlaneDistance.html
257   double a = normalPlane[0];
258   double b = normalPlane[1];
259   double c = normalPlane[2];
260   double x0 = pointInPlane[0];
261   double y0 = pointInPlane[1];
262   double z0 = pointInPlane[2];
263   double x = point[0];
264   double y = point[1];
265   double z = point[2];
266
267   double norm = sqrt(x0*x0 + y0*y0 + z0*z0);
268   DD(norm);
269   double d = -a*x0 - b*y0 - c*z0;
270   DD(d);
271   double distance = (a*x + b*y + c*z + d) / norm;
272
273   return distance;
274 }
275 //------------------------------------------------------------------
276
277 //--------------------------------------------------------------------
278 // Open a file for reading
279 void clitk::openFileForReading(std::ifstream & is, const std::string & filename)
280 {
281   is.open(filename.c_str(), std::ios::in | std::ios::binary);
282   if ( is.fail() ) {
283     clitkExceptionMacro("Could not open file for reading: " 
284                         << filename << ". Error is : <" 
285                         << strerror(errno) << ">");
286   }
287 }
288 //--------------------------------------------------------------------
289
290 //--------------------------------------------------------------------
291 // Open a file for writing
292 void clitk::openFileForWriting(std::ofstream & os, const std::string & filename)
293 {
294   os.open(filename.c_str(), std::ios::out);
295   if ( os.fail() ) {
296     clitkExceptionMacro("Could not open file for writing: " 
297                         << filename << ". Error is : <" 
298                         << strerror(errno) << ">");
299   }
300 }
301 //--------------------------------------------------------------------
302
303 //--------------------------------------------------------------------
304 double clitk::cotan(double i)
305 {
306   return(1.0 / tan(i));
307 }
308 double clitk::invcotan(double x)
309 {
310   //  http://mathworld.wolfram.com/InverseCotangent.html
311   double y;
312   if (x<0) {
313     y = -0.5*M_PI-atan(x);
314   } else {
315     y = 0.5*M_PI-atan(x);
316   }
317   return y;
318 }
319 //--------------------------------------------------------------------
320
321 //--------------------------------------------------------------------
322 std::streambuf * clitk_stdcerr_backup;
323 void clitk::disableStdCerr()
324 {
325   clitk_stdcerr_backup = std::cerr.rdbuf();
326   std::stringstream oss;
327   std::cerr.rdbuf( oss.rdbuf() );
328 }
329 //--------------------------------------------------------------------
330
331 //--------------------------------------------------------------------
332 void clitk::enableStdCerr()
333 {
334   std::cerr.rdbuf(clitk_stdcerr_backup);
335 }
336 //--------------------------------------------------------------------
337
338
339 //--------------------------------------------------------------------
340 void clitk::readDoubleFromFile(const std::string & filename, std::vector<double> & list)
341 {
342   std::ifstream is;
343   clitk::openFileForReading(is, filename);
344   list.clear();
345   while (is) {
346     clitk::skipComment(is);
347     double d;
348     is >> d;
349     if (is) list.push_back(d);
350   }
351 }
352 //--------------------------------------------------------------------
353
354
355 //--------------------------------------------------------------------
356 void clitk::PrintMemoryUsed()
357 {
358 #if defined(unix) || defined(__APPLE__)
359   rusage usage;  
360   getrusage(RUSAGE_SELF, &usage);
361   DD(usage.ru_maxrss);        /* maximum resident set size */ 
362   // DD(usage.ru_ixrss);         /* integral shared memory size */
363   // DD(usage.ru_idrss);         /* integral unshared data size */
364   // DD(usage.ru_isrss);         /* integral unshared stack size */
365 #endif
366 }
367 //--------------------------------------------------------------------
368
369
370 #endif /* end #define CLITKCOMMON_CXX */
371