EMAN2
eerio.cpp
Go to the documentation of this file.
1/*
2 * Author: tunay.durmaz@bcm.edu, 08/20/2020
3 * Copyright (c) 2020- Baylor College of Medicine
4 *
5 * This software is issued under a joint BSD/GNU license. You may use the
6 * source code in this file under either license. However, note that the
7 * complete EMAN2 and SPARX software packages have some GPL dependencies,
8 * so you are responsible for compliance with the licenses of these packages
9 * if you opt to use BSD licensing. The warranty disclaimer below holds
10 * in either instance.
11 *
12 * This complete copyright notice must be included in any revised version of the
13 * source code. Additional authorship citations may be added, but existing
14 * author citations must be preserved.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 * */
31
32#include "eerio.h"
33
34#include <tiffio.h>
35#include <boost/property_tree/xml_parser.hpp>
36
37
38using boost::property_tree::ptree;
39using namespace EMAN;
40
41
42auto Decoder::operator()(unsigned int count, unsigned int sub_pix) const {
43 return std::make_pair(x(count, sub_pix), y(count, sub_pix));
44}
45
46typedef vector<pair<int, int>> COORDS;
47
48auto decode_eer_data(EerWord *data, Decoder &decoder) {
49 EerStream is((data));
50 EerRle rle;
51 EerSubPix sub_pix;
52
53 is >> rle >> sub_pix;
54 int count = rle;
55
56 COORDS coords;
57
58 while (count < decoder.camera_size * decoder.camera_size) {
59 coords.push_back(decoder(count, sub_pix));
60
61 is >> rle >> sub_pix;
62
63 count += rle+1;
64 }
65
66 return coords;
67}
68
69void TIFFOutputWarning(const char* module, const char* fmt, va_list ap)
70{
71#ifdef DEBUG
72 cout << module << ": ";
73 vprintf(fmt, ap);
74 cout << endl;
75#endif //DEBUG
76}
77
78string read_acquisition_metadata(TIFF *tiff) {
79 char *metadata_c = nullptr;
80 uint32_t count = 0;
81
82 TIFFSetDirectory(tiff, 0);
83 TIFFGetField(tiff, 65001, &count, &metadata_c);
84
85 return string(metadata_c, count);
86}
87
88string to_snake_case(const string &s) {
89 auto ret(s);
90 int sh = 0;
91 for(int i=0; i<s.size(); i++) {
92 if(isupper(s[i])) {
93 if(!isupper(s[i-1])) {
94 ret.insert(i + sh, "_");
95 sh++;
96 }
97 ret[i + sh] = ::tolower(s[i]);
98 }
99 }
100
101 return ret;
102}
103
104Dict parse_acquisition_data(string metadata) {
105 Dict dict;
106 std::istringstream ins(metadata);
107 ptree pt;
108
109 read_xml(ins, pt);
110
111 for(auto &v : pt.get_child("metadata")) {
112 auto xml_item_name = v.second.get_child("<xmlattr>.name").data();
113 auto xml_item_value = v.second.data();
114
115 auto key = "EER." + to_snake_case(xml_item_name);
116
117 dict[key] = xml_item_value;
118 }
119
120 return dict;
121}
122
123auto read_compression(TIFF *tiff) {
124 uint16_t compression = 0;
125
126 TIFFGetField(tiff, TIFFTAG_COMPRESSION, &compression);
127
128 return compression;
129}
130
131auto read_raw_data(TIFF *tiff) {
132 auto num_strips = TIFFNumberOfStrips(tiff);
133 vector<unsigned int> strip_sizes(num_strips);
134
135 for(size_t i=0; i<num_strips; ++i)
136 strip_sizes[i] = TIFFRawStripSize(tiff, i);
137
138 std::vector<unsigned char> data;
139
140 for(size_t i=0; i<num_strips; ++i) {
141 auto prev_size = data.size();
142 data.resize(prev_size + strip_sizes[i]);
143 TIFFReadRawStrip(tiff, i, data.data() + prev_size, strip_sizes[i]);
144 }
145
146 return data;
147}
148
149
150EerIO::EerIO(const string & fname, IOMode rw, Decoder &dec)
151: ImageIO(fname, rw), decoder(dec)
152{
153 TIFFSetWarningHandler(TIFFOutputWarning);
154
155 tiff_file = TIFFOpen(filename.c_str(), "r");
156
157 auto acquisition_metadata = read_acquisition_metadata(tiff_file);
158 acquisition_data_dict = parse_acquisition_data(acquisition_metadata);
159
160 for( ; TIFFReadDirectory(tiff_file); )
161 num_frames = TIFFCurrentDirectory(tiff_file) + 1;
162
163}
164
166{
167 TIFFClose(tiff_file);
168}
169
170void EerIO::init()
171{
172 ENTERFUNC;
173
174 EXITFUNC;
175}
176
178{
179 return num_frames;
180}
181
183{
184 return is_big_endian;
185}
186
187
188int EerIO::read_header(Dict & dict, int image_index, const Region * area, bool is_3d)
189{
190 TIFFSetDirectory(tiff_file, image_index);
191
192 int nx = 0;
193 int ny = 0;
194
195 TIFFGetField(tiff_file, TIFFTAG_IMAGEWIDTH, &nx);
196 TIFFGetField(tiff_file, TIFFTAG_IMAGELENGTH, &ny);
197
198 dict["nx"] = decoder.num_pix();
199 dict["ny"] = decoder.num_pix();
200 dict["nz"] = 1;
201
202 dict["EER.compression"] = read_compression(tiff_file);
203
204 for(auto &d : acquisition_data_dict)
205 dict[d.first] = d.second;
206
207 return 0;
208}
209
210
211int EerIO::write_header(const Dict & dict, int image_index, const Region* area,
212 EMUtil::EMDataType filestoragetype, bool use_host_endian)
213{
214 ENTERFUNC;
215
216 EXITFUNC;
217
218 return 0;
219}
220
221int EerIO::read_data(float *rdata, int image_index, const Region * area, bool)
222{
223 ENTERFUNC;
224
225 TIFFSetDirectory(tiff_file, image_index);
226
227 auto data = read_raw_data(tiff_file);
228
229 auto coords = decode_eer_data((EerWord *) data.data(), decoder);
230 for(auto &c : coords)
231 rdata[c.first + c.second * decoder.num_pix()] += 1;
232
233 EXITFUNC;
234
235 return 0;
236}
237
238int EerIO::write_data(float *data, int image_index, const Region* area,
239 EMUtil::EMDataType, bool use_host_endian)
240{
241 ENTERFUNC;
242
243 EXITFUNC;
244 return 0;
245}
246
247
249{
250 return false;
251}
252
253void EerIO::flush()
254{
255}
256
258{
259 return false;
260}
#define rdata(i)
Definition: analyzer.cpp:592
virtual unsigned int x(unsigned int count, unsigned int sub_pix) const =0
virtual unsigned int num_pix() const =0
const unsigned int camera_size
Definition: eerio.h:126
virtual unsigned int y(unsigned int count, unsigned int sub_pix) const =0
Dict is a dictionary to store <string, EMObject> pair.
Definition: emobject.h:385
EMDataType
Image pixel data type used in EMAN.
Definition: emutil.h:92
bool is_big_endian
Definition: eerio.h:193
bool is_single_image_format() const override
Is this image format only storing 1 image or not.
Definition: eerio.cpp:257
Decoder & decoder
Definition: eerio.h:198
size_t num_frames
Definition: eerio.h:195
TIFF * tiff_file
Definition: eerio.h:194
int get_nimg()
Return the number of images in this image file.
Definition: eerio.cpp:177
EerIO(const string &fname, IOMode rw_mode=READ_ONLY, Decoder &dec=decoder0x)
Definition: eerio.cpp:150
Dict acquisition_data_dict
Definition: eerio.h:196
ImageIO classes are designed for reading/writing various electron micrography image formats,...
Definition: imageio.h:127
string filename
Definition: imageio.h:352
virtual void flush()=0
Flush the IO buffer.
virtual int write_header(const Dict &dict, int image_index=0, const Region *area=0, EMUtil::EMDataType filestoragetype=EMUtil::EM_FLOAT, bool use_host_endian=true)=0
Write a header to an image.
virtual int write_data(float *data, int image_index=0, const Region *area=0, EMUtil::EMDataType filestoragetype=EMUtil::EM_FLOAT, bool use_host_endian=true)=0
Write data to an image.
virtual bool is_complex_mode()=0
Is this an complex image or not.
virtual int read_header(Dict &dict, int image_index=0, const Region *area=0, bool is_3d=false)=0
Read the header from an image.
virtual int read_data(float *data, int image_index=0, const Region *area=0, bool is_3d=false)=0
Read the data from an image.
virtual void init()=0
Do some initialization before doing the read/write.
virtual bool is_image_big_endian()=0
Is this image in big endian or not.
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
Definition: geometry.h:497
Dict parse_acquisition_data(string metadata)
Definition: eerio.cpp:104
void TIFFOutputWarning(const char *module, const char *fmt, va_list ap)
Definition: eerio.cpp:69
string read_acquisition_metadata(TIFF *tiff)
Definition: eerio.cpp:78
string to_snake_case(const string &s)
Definition: eerio.cpp:88
vector< pair< int, int > > COORDS
Definition: eerio.cpp:46
auto read_raw_data(TIFF *tiff)
Definition: eerio.cpp:131
auto read_compression(TIFF *tiff)
Definition: eerio.cpp:123
auto decode_eer_data(EerWord *data, Decoder &decoder)
Definition: eerio.cpp:48
float & operator()(const int ix, const int iy, const int iz) const
Overload operator() for array indexing.
Definition: emdata_core.h:727
#define ENTERFUNC
Definition: log.h:48
#define EXITFUNC
Definition: log.h:49
E2Exception class.
Definition: aligner.h:40
uint64_t EerWord
Definition: eerio.h:114