IMP logo
IMP Reference Guide  develop.98ef8da184,2024/04/23
The Integrative Modeling Platform
SpiderImageReaderWriter.h
Go to the documentation of this file.
1 /**
2  * \file IMP/em2d/SpiderImageReaderWriter.h
3  * \brief Management of Images in Spider format
4  * Copyright 2007-2022 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_macros.h>
19 #include <IMP/log.h>
20 #include <typeinfo>
21 #include <complex>
22 #include <string>
23 #include <cstdio>
24 #include <iostream>
25 #include <fstream>
26 #include <cstring>
27 
28 IMPEM2D_BEGIN_NAMESPACE
29 
30 //! Class to read and write EM images in Spider format. They are stored in
31 //! the header and data passed as arguments
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 writing
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  void read(const String &filename, em::ImageHeader &header,
68  cv::Mat &data) const override {
69  this->read_from_floats(filename, header, data);
70  }
71 
72  void write(const String &filename, em::ImageHeader &header,
73  const cv::Mat &data) const override {
74  this->write_to_floats(filename, header, data);
75  }
76 
77  void read_from_ints(const String &, em::ImageHeader &,
78  cv::Mat &) const override {}
79 
80  void write_to_ints(const String &, em::ImageHeader &,
81  const cv::Mat &) const override {}
82 
83  //! Reads an image file in Spider format and stores the content
84  //! int the header and data parameters
85  /*!
86  \param[in] filename file to read
87  \param[in] header header to store the info
88  \param[in] data a matrix to store the grid of data of the image
89  */
90  void read_from_floats(const String &filename, em::ImageHeader &header,
91  cv::Mat &data) const override {
92  IMP_LOG_VERBOSE("reading with SpiderImageReaderWriter" << std::endl);
93  std::ifstream in;
94  in.open(filename.c_str(), std::ios::in | std::ios::binary);
95  if (in.fail() || in.bad()) {
96  IMP_THROW("Error reading from Spider Image " << filename, IOException);
97  }
98  //! The header format is already in Spider format, just read it
99  bool success = header.read(in, skip_type_check_, force_reversed_,
100  skip_extra_checkings_);
101  if (!success) {
102  IMP_THROW("Error reading header from Spider Image " << filename,
103  IOException);
104  }
105  IMP_LOG_VERBOSE("Header of image " << filename << std::endl << header
106  << std::endl);
107  // Adjust size of the matrix according to the header
108  unsigned int rows = (int)header.get_number_of_rows();
109  unsigned int cols = (int)header.get_number_of_columns();
110  data.create(rows, cols, CV_64FC1);
111  // Read with casting
112  float aux;
113  for (cvDoubleMatIterator it = data.begin<double>();
114  it != data.end<double>(); ++it) {
115  if (!(force_reversed_ ^ algebra::get_is_big_endian())) {
116  in.read(reinterpret_cast<char *>(&aux), sizeof(float));
117  } else {
118  algebra::reversed_read(reinterpret_cast<char *>(&aux), sizeof(float), 1,
119  in, true);
120  }
121  (*it) = static_cast<double>(aux);
122  }
123  in.close();
124  }
125 
126  //! Writes an EM image in Spider format
127  /*!
128  * \param[in] filename file to write
129  * \param[in] header header with the image info
130  * \param[in] data a matrix with the grid of data of the image
131  */
132  void write_to_floats(const String &filename, em::ImageHeader &header,
133  const cv::Mat &data) const override {
134  std::ofstream out;
135  out.open(filename.c_str(), std::ios::out | std::ios::binary);
136  //! The image header is already in Spider format, just write it
137  header.write(out, force_reversed_ ^ algebra::get_is_big_endian());
138 
139  float aux;
140  for (cvDoubleConstMatIterator it = data.begin<double>();
141  it != data.end<double>(); ++it) {
142  aux = (float)(*it);
143  if (!(force_reversed_ ^ algebra::get_is_big_endian())) {
144  out.write(reinterpret_cast<char *>(&aux), sizeof(float));
145  } else {
146  algebra::reversed_write(reinterpret_cast<char *>(&aux), sizeof(float),
147  1, out, true);
148  }
149  }
150  out.close();
151  }
152 
154 };
155 
156 IMPEM2D_END_NAMESPACE
157 
158 #endif /* IMPEM2D_SPIDER_IMAGE_READER_WRITER_H */
bool get_is_big_endian()
Returns 1 if machine is big endian else 0.
Functions to convert between ImageHeader and DensityHeader Copyright 2007-2022 IMP Inventors...
Class to deal with the header of Electron Microscopy images in IMP.
Definition: ImageHeader.h:28
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Definition: object_macros.h:25
Virtual class for reader/writers of images.
void write_to_floats(const String &filename, em::ImageHeader &header, const cv::Mat &data) const override
Writes an EM image in Spider format.
SpiderImageReaderWriter(const String &filename, bool skip_type_check, bool force_reversed, bool skip_extra_checkings)
Full constructor.
Virtual class for reader/writers of images Copyright 2007-2022 IMP Inventors. All rights reserved...
Interface with OpenCV Copyright 2007-2022 IMP Inventors. All rights reserved.
void read_from_floats(const String &filename, em::ImageHeader &header, cv::Mat &data) const override
#define IMP_LOG_VERBOSE(expr)
Definition: log_macros.h:83
Exception definitions and assertions.
An input/output exception.
Definition: exception.h:173
void write(const String &filename, bool force_reversed=false)
Writes the header of a EM image.
Functions to deal with byte order.
Functions to deal with very common math operations.
Logging and error reporting support.
void reversed_read(void *dest, size_t size, size_t nitems, std::ifstream &f, bool reverse)
Reads from file in normal or reverse order.
#define IMP_THROW(message, exception_name)
Throw an exception with a message.
Definition: check_macros.h:50
int read(const String filename, bool skip_type_check=false, bool force_reversed=false, bool skip_extra_checkings=false)
Reads the header of a EM image.
void reversed_write(const void *src, size_t size, size_t nitems, std::ofstream &f, bool reverse=false)
Writes to a file in normal or reversed order.
Header for EM images. Compatible with Spider and Xmipp formats Copyright 2007-2022 IMP Inventors...
Logging and error reporting support.
std::string String
Basic string value.
Definition: types.h:43