IMP  2.0.1
The Integrative Modeling Platform
SpiderImageReaderWriter.h
Go to the documentation of this file.
1 /**
2  * \file SpiderImageReaderWriter.h
3  * \brief Management of Images in Spider format
4  * Copyright 2007-2013 IMP Inventors. All rights reserved.
5 */
6 
7 #ifndef IMPEM2D_SPIDER_IMAGE_READER_WRITER_H
8 #define IMPEM2D_SPIDER_IMAGE_READER_WRITER_H
9 
10 #include "IMP/em2d/em2d_config.h"
13 #include "IMP/em/ImageHeader.h"
15 #include <IMP/algebra/utility.h>
16 #include <IMP/algebra/endian.h>
17 #include <IMP/exception.h>
18 #include <IMP/log.h>
19 #include <typeinfo>
20 #include <complex>
21 #include <string>
22 #include <cstdio>
23 #include <iostream>
24 #include <fstream>
25 #include <cstring>
26 
27 IMPEM2D_BEGIN_NAMESPACE
28 
29 //! Class to read and write EM images in Spider format. They are stored in
30 //! the header and data passed as arguments
31 class SpiderImageReaderWriter: public ImageReaderWriter
32 {
33 public:
34  String filename_;
35  bool skip_type_check_;
36  bool force_reversed_;
37  bool skip_extra_checkings_;
38 
39  //! Empty constructor. It does not force reversed header and does not
40  //! skip any of the tests
41  /*!
42  * \note reversed is only used in case that the type_check is skipped
43  */
45  skip_type_check_=false;
46  force_reversed_=false;
47  skip_extra_checkings_=false;
48  }
49 
50  //! Full constructor.
51  /*!
52  * \param[in] filename file to read
53  * \param[in] skip_type_check if true, the check for type of image is skipped
54  * \param[in] force_reversed if true, the reverse mode is enforced
55  * for reading and writting
56  * \param[in] skip_extra_checkings if true, the most stringent
57  * tests for consistency of images are skipped when reading
58  */
59  SpiderImageReaderWriter(const String &filename,bool skip_type_check,
60  bool force_reversed,bool skip_extra_checkings) {
61  filename_=filename;
62  skip_type_check_=skip_type_check;
63  force_reversed_=force_reversed;
64  skip_extra_checkings_=skip_extra_checkings;
65  }
66 
67 
68  void read(const String &filename,em::ImageHeader& header,
69  cv::Mat &data) const {
70  this->read_from_floats(filename, header,data);
71  }
72 
73  void write(const String &filename, em::ImageHeader& header,
74  const cv::Mat &data) const {
75  this->write_to_floats(filename, header,data);
76  }
77 
78  void read_from_ints(const String &, em::ImageHeader&, cv::Mat &) const {
79  }
80 
81  void write_to_ints(const String &, em::ImageHeader&, const cv::Mat &) const {
82  }
83 
84  //! Reads an image file in Spider format and stores the content
85  //! int the header and data parameters
86  /*!
87  \param[in] filename file to read
88  \param[in] header header to store the info
89  \param[in] data a matrix to store the grid of data of the image
90  */
91  void read_from_floats(const String &filename,
92  em::ImageHeader &header,cv::Mat &data) const {
93  IMP_LOG_VERBOSE("reading with SpiderImageReaderWriter" << std::endl);
94  std::ifstream in;
95  in.open(filename.c_str(), std::ios::in | std::ios::binary);
96  if (in.fail() || in.bad()) {
97  IMP_THROW("Error reading from Spider Image " << filename,IOException);
98  }
99  //! The header format is already in Spider format, just read it
100  bool success=header.read(in,skip_type_check_,force_reversed_,
101  skip_extra_checkings_);
102  if (!success) {
103  IMP_THROW("Error reading header from Spider Image "
104  << filename,IOException);
105  }
106  IMP_LOG_VERBOSE("Header of image " << filename << std::endl
107  << header << std::endl);
108  // Adjust size of the matrix according to the header
109  unsigned int rows = (int)header.get_number_of_rows();
110  unsigned int cols = (int)header.get_number_of_columns();
111  data.create(rows,cols,CV_64FC1);
112  // Read with casting
113  float aux;
114  for (cvDoubleMatIterator it=data.begin<double>();
115  it!=data.end<double>();++it) {
116  if (!(force_reversed_ ^ algebra::get_is_big_endian())) {
117  in.read(reinterpret_cast< char* >(&aux), sizeof(float));
118  } else {
119  algebra::reversed_read(reinterpret_cast< char* >(&aux),
120  sizeof(float),1,in,true);
121  }
122  (*it) = static_cast<double>(aux);
123  }
124  in.close();
125  }
126 
127 
128  //! Writes an EM image in Spider format
129  /*!
130  * \param[in] filename file to write
131  * \param[in] header header with the image info
132  * \param[in] data a matrix with the grid of data of the image
133  */
134  void write_to_floats(const String &filename,
135  em::ImageHeader& header,
136  const cv::Mat &data) const {
137  std::ofstream out;
138  out.open(filename.c_str(), std::ios::out | std::ios::binary);
139  //! The image header is already in Spider format, just write it
140  header.write(out, force_reversed_ ^ algebra::get_is_big_endian());
141 
142  float aux;
143  for (cvDoubleConstMatIterator it=data.begin<double>();
144  it!=data.end<double>();++it) {
145  aux = (float)(*it);
146  if (!(force_reversed_ ^ algebra::get_is_big_endian())) {
147  out.write(reinterpret_cast< char* >(&aux), sizeof(float));
148  } else {
149  algebra::reversed_write(reinterpret_cast< char* >(&aux),
150  sizeof(float),1,out,true);
151  }
152  }
153  out.close();
154  }
155 
157  { out << "SpiderImageReaderWriter"; }, {});
158 };
159 
160 
161 
162 
163 IMPEM2D_END_NAMESPACE
164 
165 #endif /* IMPEM2D_SPIDER_IMAGE_READER_WRITER_H */