IMP  2.0.1
The Integrative Modeling Platform
ImageHeader.h
Go to the documentation of this file.
1 /**
2  * \file IMP/em/ImageHeader.h
3  * \brief Header for EM images. Compatible with Spider and Xmipp formats
4  * Copyright 2007-2013 IMP Inventors. All rights reserved.
5 **/
6 
7 #ifndef IMPEM_IMAGE_HEADER_H
8 #define IMPEM_IMAGE_HEADER_H
9 
10 #include "IMP/em/em_config.h"
11 #include "IMP/em/SpiderHeader.h"
12 #include <IMP/algebra/Vector3D.h>
13 #include <IMP/algebra/Vector2D.h>
14 #include <IMP/algebra/utility.h>
15 #include <IMP/algebra/endian.h>
17 #include <cstdio>
18 #include <iostream>
19 #include <fstream>
20 #include <cstring>
21 
22 IMPEM_BEGIN_NAMESPACE
23 
24 //! Class to deal with the header of Electron Microsocopy images in IMP.
25 /*!
26  \note Compatible with SPIDER format
27 */
28 class IMPEMEXPORT ImageHeader
29 {
30 public:
31  //! Types of initialization of ImageHeader
32  typedef enum { IMG_BYTE = 0, IMG_IMPEM = 1,
33  IMG_INT = 9, /*IMG_SHORT = , IMG_UCHAR = ,*/
34  VOL_BYTE = 2, VOL_IMPEM = 3,
35  VOL_INT = 10 , /*VOL_SHORT = , VOL_UCHAR =, */
36  IMG_FOURIER = -1, VOL_FOURIER = -3
37  } img_type;
38 
39  ImageHeader() {
40  clear();
41  set_image_type((float)IMG_IMPEM );
42  }
43 
44  ImageHeader(img_type im) {
45  clear();
46  set_image_type((float)im );
47  }
48 
49  ImageHeader(float im) {
50  clear();
51  set_image_type(im);
52  }
53 
54  float get_image_type() const {
55  return spider_header_.fIform;
56  }
57 
58  //! Set the type of image
59  /**
60  \param[in] im type of image. Available values:
61  IMG_BYTE = 0, IMG_IMPEM = 1,IMG_INT = 9, VOL_BYTE = 2, VOL_IMPEM = 3,
62  VOL_INT = 10 , IMG_FOURIER = -1, VOL_FOURIER = -3
63  \note No check is done for correctness of the value
64  */
66  set_image_type((float)im);
67  }
68 
69  void set_image_type(float im) {
70  spider_header_.fIform=im;
71  }
72 
73  void do_show(std::ostream& out) const {
74  out << "Image type : ";
75  switch ((int) spider_header_.fIform) {
76  case IMG_BYTE:
77  out << "2D Byte image";
78  break;
79  case IMG_IMPEM:
80  out << "2D IMP EM image";
81  break;
82  case IMG_INT:
83  out << "2D INT image";
84  break;
85  case VOL_BYTE:
86  out << "3D Byte volume";
87  break;
88  case VOL_IMPEM:
89  out << "3D IMP EM volume";
90  break;
91  case VOL_INT:
92  out << "3D INT volume";
93  break;
94  case IMG_FOURIER:
95  out << "2D Fourier image";
96  break;
97  case VOL_FOURIER:
98  out << "3D Fourier volume";
99  break;
100  }
101  out << std::endl;
102  out << "Reversed : ";
103  if (reversed_) {
104  out << "TRUE" << std::endl;
105  } else {
106  out << "FALSE" << std::endl;
107  }
108  out << "dimensions (slices x rows x columns) : "
109  << get_number_of_slices() << " "
110  << get_number_of_rows() << " "
111  << get_number_of_columns() << std::endl;
112  out << "Origin (shift) : " << get_origin() << std::endl;
113  out << "Euler angles (Phi, Theta, Psi) (ZYZ convention): "
114  << get_euler_angles() << std::endl;
115  if ( spider_header_.fFlag == 1.0f || spider_header_.fFlag == 2.0f) {
116  out << "Euler angles (Phi1, Theta1, Psi1) (ZYZ convention): "
117  << get_euler_angles1() << std::endl;
118  }
119  if (spider_header_.fFlag == 2.0f) {
120  out << "Euler angles (Phi2, Theta2, Psi2) (ZYZ convention): "
121  << get_euler_angles1() << std::endl;
122  }
123 
124  out << "Date : " << get_date() << std::endl;
125  out << "Time : " << get_time() << std::endl;
126  out << "Title : " << get_title() << std::endl;
127  out << "Header size : " << get_spider_header_size() << std::endl;
128  out << "Weight : " << get_Weight() << std::endl;
129  }
130 
131  IMP_SHOWABLE_INLINE(ImageHeader, do_show(out));
132  //! Prints a reduced set of information (debugging purposes)
133  void print_hard(std::ostream& out) const;
134 
135  //! Shows only the projection parameters
136  inline void show_projection_params(std::ostream& out) const {
137  out << "(Phi,Theta,Psi) = ( " << spider_header_.fPhi << " , "
138  << spider_header_.fTheta << " , "
139  << spider_header_.fPsi << " ) "
140  << " (x,y) = ( " << spider_header_.fXoff << " , "
141  << spider_header_.fYoff << " ) " << std::endl;
142  }
143 
144  //! Reads the header of a EM image
145  // \note reversed is only used in case that the type_check is skipped
146  int read(const String filename, bool skip_type_check = false,
147  bool force_reversed = false, bool skip_extra_checkings = false);
148 
149  //! Reads the header of a EM image from an input file stream
150  bool read(std::ifstream& f, bool skip_type_check = false,
151  bool force_reversed = false, bool skip_extra_checkings = false);
152 
153  //! Writes the header of a EM image
154  void write(const String &filename, bool force_reversed = false);
155 
156  //! Writes the header of a EM image to an output file stream
157  void write(std::ofstream& f, bool force_reversed = false);
158 
159  //! Clear header data and sets a consistent header
160  void clear();
161 
162  //! Sets a consistent header
163  void set_header();
164 
165  //! Interaction with data
166  bool get_reversed() const {return reversed_; }
167  void set_reversed(bool value) { reversed_=value; }
168 
169  unsigned int get_number_of_slices() const {
170  return (unsigned int)spider_header_.fNslice;
171  }
172  void set_number_of_slices(unsigned int n) {
173  spider_header_.fNslice = (float)n;
174  }
175 
176  unsigned int get_number_of_rows() const {
177  return (unsigned int )spider_header_.fNrow;
178  }
179  void set_number_of_rows(unsigned int n) {
180  spider_header_.fNrow = (float)n;
181  }
182 
183  unsigned int get_number_of_columns() const {
184  return (unsigned int )spider_header_.fNcol;
185  }
186  void set_number_of_columns(unsigned int n) {
187  spider_header_.fNcol = (float)n;
188  }
189 
190  //! get rotation angle. (Xmipp compatibility)
191  float get_old_rot() const {
192  return spider_header_.fAngle1;
193  }
194 
195  //! set rotation angle. (Xmipp compatibility)
196  void set_old_rot(float value) {
197  spider_header_.fAngle1= value;
198  }
199 
200  //! get rotation angle. (Xmipp compatibility)
201  float get_fAngle1() const {
202  return spider_header_.fAngle1;
203  }
204 
205  //! set rotation angle. (Xmipp compatibility)
206  void set_fAngle1(float value) {
207  spider_header_.fAngle1= value;
208  }
209 
210  float get_Scale() const {
211  return spider_header_.fScale;
212  }
213 
214  void set_Scale(float value) {
215  spider_header_.fScale=value;
216  }
217 
218  /* For Maximum-Likelihood refinement (Xmipp compatibility:
219  not currently used)
220  */
221  float get_Flip() const { return spider_header_.Flip; }
222 
223  /* For Maximum-Likelihood refinement (Xmipp compatibility:
224  not currently used)
225  */
226  void set_Flip(float value) { spider_header_.Flip=value; }
227 
228  float get_Weight() const { return spider_header_.Weight; }
229  void set_Weight(float value) { spider_header_.Weight=value; }
230 
231  float get_fNrec() const { return spider_header_.fNrec; }
232  void set_fNrec(float value) { spider_header_.fNrec = value; }
233 
234  float get_fNlabel() const { return spider_header_.fNlabel; }
235  void set_fNlabel(float value) { spider_header_.fNlabel=value; }
236 
237  float get_fIform() const { return spider_header_.fIform; }
238  void set_fIform(float value) { spider_header_.fIform = value; }
239 
240  float get_fImami() const { return spider_header_.fImami; }
241  void set_fImami(float value) { spider_header_.fImami=value; }
242 
243  float get_fFmax() const { return spider_header_.fFmax; }
244  void set_fFmax(float value) { spider_header_.fFmax= value; }
245 
246  float get_fFmin() const { return spider_header_.fFmin; }
247  void set_fFmin(float value) { spider_header_.fFmin=value; }
248 
249  float get_fAv() const { return spider_header_.fAv; }
250  void set_fAv(float value) { spider_header_.fAv=value; }
251 
252  float get_fSig() const { return spider_header_.fSig; }
253  void set_fSig(float value) { spider_header_.fSig=value; }
254 
255  float get_fIhist() const { return spider_header_.fIhist; }
256  void set_fIhist(float value) { spider_header_.fIhist=value; }
257 
258  float get_fLabrec() const { return spider_header_.fLabrec; }
259  void set_fLabrec(float value) { spider_header_.fLabrec=value; }
260 
261  float get_fIangle() const { return spider_header_.fIangle; }
262  void set_fIangle(float value) { spider_header_.fIangle=value; }
263 
264  algebra::Vector3D get_origin() const {
265  return algebra::Vector3D(spider_header_.fXoff,
266  spider_header_.fYoff,
267  spider_header_.fZoff);
268  };
269 
270  void set_origin(const algebra::Vector3D &v) {
271  spider_header_.fXoff=v[0];
272  spider_header_.fYoff=v[1];
273  spider_header_.fZoff=v[2];
274  }
275 
276  void set_origin(const algebra::Vector2D &v) {
277  spider_header_.fXoff=(float)v[0];
278  spider_header_.fYoff=(float)v[1];
279  spider_header_.fZoff=(float)0.0;
280  }
281 
282  float get_object_pixel_size() const { return spider_header_.fScale; }
283  void set_object_pixel_size(float value) { spider_header_.fScale = value; }
284 
285  float get_fLabbyt() const { return spider_header_.fLabbyt; }
286  void set_fLabbyt(float value) { spider_header_.fLabbyt=value; }
287 
288  float get_fLenbyt() const { return spider_header_.fLenbyt; }
289  void set_fLenbyt(float value) { spider_header_.fLenbyt=value; }
290 
291  double get_fGeo_matrix(unsigned int i,unsigned int j) const;
292 
293  //! Gets the fFlag.
294  /** fFlag contains the number of triads of Euler angles stored
295  in the header (up to three).
296  set_euler_angles2 makes fFlag=2, set_euler_angles1 makes
297  fFlag=max(fFlag, 1), set_euler_angles does not change fFlag
298  */
299  float get_fFlag() const { return spider_header_.fFlag; }
300  void set_fFlag(float value) { spider_header_.fFlag = value; }
301 
302  algebra::Vector3D get_euler_angles() const {
303  return algebra::Vector3D(spider_header_.fPhi,
304  spider_header_.fTheta,
305  spider_header_.fPsi);
306  }
307 
308  algebra::Vector3D get_euler_angles1() const {
309  return algebra::Vector3D(spider_header_.fPhi1,
310  spider_header_.fTheta1,
311  spider_header_.fPsi1);
312  }
313 
314  algebra::Vector3D get_euler_angles2() const {
315  return algebra::Vector3D(spider_header_.fPhi2,
316  spider_header_.fTheta2,
317  spider_header_.fPsi2);
318  }
319 
320  void set_euler_angles(const algebra::Vector3D &euler) {
321  spider_header_.fIangle = 1;
322  spider_header_.fPhi = euler[0]; // z
323  spider_header_.fTheta = euler[1]; // y
324  spider_header_.fPsi = euler[2]; //z
325  }
326 
327  void set_euler_angles1(const algebra::Vector3D &euler) {
328  if (spider_header_.fFlag != 2.f){
329  spider_header_.fFlag = 1.f;
330  }
331  spider_header_.fPhi1 = euler[0]; // z
332  spider_header_.fTheta1 = euler[1]; // y
333  spider_header_.fPsi1 = euler[2]; //z
334  }
335 
336  void set_euler_angles2(const algebra::Vector3D &euler) {
337  spider_header_.fFlag = 2;
338  spider_header_.fPhi2 = euler[0]; // z
339  spider_header_.fTheta2 = euler[1]; // y
340  spider_header_.fPsi2 = euler[2]; //z
341  }
342 
343 
344 
345  bool is_normalized() const {
346  if(std::abs(get_fAv()) <1e-6 &&
347  std::abs(get_fSig()-1.0) < 1e-6) {
348  return true;
349  }
350  return false;
351  }
352 
353 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
354  // Date and Time
355  char* get_date() const;
356  char* get_time() const;
357 #endif
358  void set_date();
359  void set_time();
360 
361 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
362  // Title
363  char* get_title() const;
364 #endif
365 
366  //! Set title of image in the header
367  void set_title(String newName);
368 
369 private:
370 
371  //! get header size
372  int get_spider_header_size() const {
373  return (int) spider_header_.fNcol *
374  (int) spider_header_.fLabrec *
375  sizeof(float);
376  }
377 
378  // The header is directly in format Spider with a couple of additions
379  em::SpiderHeader spider_header_;
380  bool reversed_;
381 }; // ImageHeader
382 
383 IMPEM_END_NAMESPACE
384 
385 #endif /* IMPEM_IMAGE_HEADER_H */