EMAN2
omapio.cpp
Go to the documentation of this file.
1/*
2 * Author: Grant Tang, 06/07/2011 (gtang@bcm.edu)
3 * Copyright (c) 2000-2006 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 "omapio.h"
33#include "portable_fileio.h"
34
35using namespace EMAN;
36
37OmapIO::OmapIO(const string & fname, IOMode rw) :
38 ImageIO(fname, rw),
39 is_big_endian(false), is_new_file(false)
40{
41 memset(&omaph, 0, sizeof(OmapHeader));
43}
44
46{
47 if (file) {
48 fclose(file);
49 file = 0;
50 }
51}
52
53void OmapIO::init()
54{
56
57 if (initialized) {
58 return;
59 }
60
61 initialized = true;
63
64 char record[512]; //record size 512 bytes
65
66 if (!is_new_file) {
67 if (fread(record, 512, 1, file) != 1) {
68 throw ImageReadException(filename, "OMAP header");
69 }
70
71 for(int i=0; i<512; i++) {
72 if(!isprint(record[i])) {
73 portable_fseek(file, 0, SEEK_SET);
74 break;
75 }
76
77 if(record[i] == '\0') break;
78 }
79
80 if (fread(&omaph, sizeof(OmapHeader), 1, file) != 1) {
81 throw ImageReadException(filename, "OMAP header");
82 }
83
84 if (!is_valid(&omaph)) {
85 throw ImageReadException(filename, "invalid OMAP");
86 }
87
88 if(!ByteOrder::is_host_big_endian()) { //omap first record is always big endian
89 ByteOrder::swap_bytes((short *) &omaph, 256); //each record 512 bytes, 256 short intergers
90 }
91 }
92
94}
95
96int OmapIO::read_header(EMAN::Dict& dict, int, EMAN::Region const*, bool)
97{
99 init();
100
101 dict["OMAP.xstart"] = (int)omaph.xstart;
102 dict["OMAP.ystart"] = (int)omaph.ystart;
103 dict["OMAP.zstart"] = (int)omaph.zstart;
104 dict["nx"] = (int)omaph.nx;
105 dict["ny"] = (int)omaph.ny;
106 dict["nz"] = (int)omaph.nz;
107 dict["apix_x"] = (int)omaph.apix_x;
108 dict["apix_y"] = (int)omaph.apix_y;
109 dict["apix_z"] = (int)omaph.apix_z;
110 dict["OMAP.cellA"] = (int)(omaph.header10/omaph.scale);
111 dict["OMAP.cellB"] = (int)(omaph.header11/omaph.scale);
112 dict["OMAP.cellC"] = (int)(omaph.header12/omaph.scale);
113 dict["alpha"] = (int)(omaph.alpha/omaph.scale);
114 dict["beta"] = (int)(omaph.beta/omaph.scale);
115 dict["gamma"] = (int)(omaph.gamma/omaph.scale);
116 dict["OMAP.iprod"] = (int)omaph.iprod;
117 dict["OMAP.iplus"] = (int)omaph.iplus;
118 dict["OMAP.scale"] = (int)omaph.scale?omaph.scale:100;
119 dict["OMAP.scale2"] = (int)omaph.scale2?omaph.scale2:100;
120
121 float prod = (float)(omaph.iprod/(int)dict["OMAP.scale2"]);
122 float plus = (float)omaph.iplus;
123
124 dict["OMAP.min"] = (omaph.imin - plus)/prod;
125 dict["OMAP.imax"] = (omaph.imax - plus)/prod;
126 dict["OMAP.sigma"] = (omaph.isigma - plus)/prod;
127 dict["OMAP.mean"] = (omaph.imean - plus)/prod;
128
129 if((float)dict["OMAP.sigma"] < 0.001f || (float)dict["OMAP.sigma"] > 10.0f) {
130 std::cout << "Warning : Suspect value of sigma : " << (float)dict["OMAP.sigma"] << std::endl;
131 dict["OMAP.sigma"] = 0; //flag bad sigma
132 }
133
134 EXITFUNC;
135 return 0;
136}
137
138int OmapIO::read_data(float *rdata, int, EMAN::Region const*, bool)
139{
140 ENTERFUNC;
141// std::cout << "file pointer location = " << ftell(omapfile) << std::endl;
142
143 // cubes in each direction
144 int inx = omaph.nx/8;
145 int iny = omaph.ny/8;
146 int inz = omaph.nz/8;
147
148 //include partial cube
149 if(omaph.nx%8 > 0) ++inx;
150 if(omaph.ny%8 > 0) ++iny;
151 if(omaph.nz%8 > 0) ++inz;
152
153 // How much element of last cube to read ?
154 int xtraX = omaph.nx%8;
155 int xtraY = omaph.ny%8;
156 int xtraZ = omaph.nz%8;
157
158// std::cout << "Total records = " << inx*iny*inz << std::endl;
159
160 float prod = (float)omaph.iprod/omaph.scale2?omaph.scale2:100;
161 float plus = omaph.iplus;
162 float pixel = 0.0f;
163 unsigned char record[512];
164 for (int k=0; k < inz; k++) {
165 for (int j=0; j < iny; j++) {
166 for (int i=0; i < inx; i++) {
167 if (fread(record, 512, 1, file) != 1) {
168 throw ImageReadException(filename, "OMAP data");
169 }
170
171 //swap bytes for little endian
172 bool byteswap = false;
174 byteswap = true;
175 }
176 if(byteswap) {
177 for (int ii=0; ii < 511; ii+=2) {
178 char tempchar = record[ii];
179 record[ii] = record[ii+1];
180 record[ii+1] = tempchar;
181 }
182 }
183
184 int cubieSizeX = 8;
185 int cubieSizeY = 8;
186 int cubieSizeZ = 8;
187
188 //for partial cube
189 if (xtraX > 0) if (i == inx-1) cubieSizeX = xtraX;
190 if (xtraY > 0) if (j == iny-1) cubieSizeY = xtraY;
191 if (xtraZ > 0) if (k == inz-1) cubieSizeZ = xtraZ;
192
193 for (int n=0; n < cubieSizeZ; n++) {
194 for (int m=0; m < cubieSizeY; m++) {
195 for (int l=0; l < cubieSizeX; l++) {
196 unsigned char sboxLMN = record[8*8*n+8*m+l];
197
198 pixel = ((float)sboxLMN - plus)/prod;
199
200 int pt3 = k*8 + n;
201 int pt2 = j*8 + m;
202 int pt1 = i*8 + l;
203
204 rdata[pt3*omaph.nx*omaph.ny + pt2*omaph.nx + pt1] = (pixel-plus)/prod;
205 if(omaph.isigma>0) rdata[pt3*omaph.nx*omaph.ny + pt2*omaph.nx + pt1] /= (float)omaph.isigma;
206 }
207 }
208 }
209
210 }
211 }
212 }
213
214 EXITFUNC;
215 return 0;
216}
217
219{
220 ENTERFUNC;
221
222 throw ImageWriteException("N/A", "No writing for Omap images");
223
224 EXITFUNC;
225 return 0;
226}
227
228int OmapIO::write_data(float*, int, EMAN::Region const*, EMAN::EMUtil::EMDataType, bool)
229{
230 ENTERFUNC;
231
232 EXITFUNC;
233 return 0;
234}
235
236bool OmapIO::is_valid(const void *first_block, off_t file_size)
237{
238 ENTERFUNC;
239
240 if (!first_block) {
241 return false;
242 }
243
244 const short *data = static_cast < const short *>(first_block);
245 short xstart = data[0];
246 short ystart = data[1];
247 short zstart = data[2];
248 short nx = data[3];
249 short ny = data[4];
250 short nz = data[5];
251 short const_value = data[18];
252
254 ByteOrder::swap_bytes(&xstart);
255 ByteOrder::swap_bytes(&ystart);
256 ByteOrder::swap_bytes(&zstart);
260 ByteOrder::swap_bytes(&const_value);
261 }
262
263 if(const_value != 100) return false;
264 if(nx<=0 || ny<=0 || nz<=0 || nx>10000 || ny>10000 || nz>10000) return false;
265
266 EXITFUNC;
267 return true;
268}
269
271{
272 return true;
273}
274
276{
277 return false;
278}
279
280void OmapIO::flush()
281{
282 fflush(file);
283}
#define rdata(i)
Definition: analyzer.cpp:592
static bool is_host_big_endian()
Definition: byteorder.cpp:40
static void swap_bytes(T *data, size_t n=1)
swap the byte order of data with 'n' T-type elements.
Definition: byteorder.h:131
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
ImageIO classes are designed for reading/writing various electron micrography image formats,...
Definition: imageio.h:127
IOMode rw_mode
Definition: imageio.h:353
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.
bool initialized
Definition: imageio.h:355
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.
FILE * sfopen(const string &filename, IOMode mode, bool *is_new=0, bool overwrite=false)
Run fopen safely.
Definition: imageio.cpp:135
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.
FILE * file
Definition: imageio.h:354
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.
OmapHeader omaph
Definition: omapio.h:92
static bool is_valid(const void *first_block, off_t file_size=0)
Definition: omapio.cpp:236
bool is_big_endian
Definition: omapio.h:94
bool is_new_file
Definition: omapio.h:95
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
Definition: geometry.h:497
#define ImageReadException(filename, desc)
Definition: exception.h:204
#define ImageWriteException(imagename, desc)
Definition: exception.h:223
#define ENTERFUNC
Definition: log.h:48
#define EXITFUNC
Definition: log.h:49
E2Exception class.
Definition: aligner.h:40
int portable_fseek(FILE *fp, off_t offset, int whence)
The data in the header is composed of 256 short integers.
Definition: omapio.h:63