EMAN2
situsio.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 "situsio.h"
33#include "portable_fileio.h"
34#include "util.h"
35
36using namespace EMAN;
37
38const int SitusIO::SITUS_HEADER_LINES=2;
39const int SitusIO::FLOAT_SIZE = 12;
40const int SitusIO::NFLOAT_PER_LINE = 10;
41const char * SitusIO::OUTFORMAT = "%12.6f";
42const int SitusIO::LINE_LENGTH = 1024;
43
44SitusIO::SitusIO(const string & fname, IOMode rw) :
45 ImageIO(fname, rw),
46 is_new_file(false),
47 apix(0.0f), origx(0.0f), origy(0.0f), origz(0.0f),
48 nx(0), ny(0), nz(0)
49{
50}
51
53{
54 if (file) {
55 fclose(file);
56 file = 0;
57 }
58}
59
60void SitusIO::init()
61{
63 if (initialized) {
64 return;
65 }
66
67 initialized = true;
69
70 if (!is_new_file) {
71 char first_block[1024];
72 fread(&first_block, sizeof(char), sizeof(first_block), file);
73 if (!is_valid(&first_block)) {
74 throw ImageReadException(filename, "invalid SITUS file");
75 }
76
77 char * buf = (char *)first_block;
78 string line1 = Util::get_line_from_string(&buf);
79
80 sscanf(line1.c_str(), "%f %f %f %f %d %d %d", &apix, &origx, &origy, &origz, &nx, &ny, &nz);
81 }
82
84}
85
86int SitusIO::read_data(float* data, int image_index, const EMAN::Region*, bool)
87{
89
90 image_index = 0; //single image format
91
92 portable_fseek(file, 0, SEEK_SET);
93 EMUtil::jump_lines(file, SITUS_HEADER_LINES); //skip header lines
94
95 int number_lines = nx*ny*nz / NFLOAT_PER_LINE + 1;
96
97 size_t index = 0; //linear index for image data array
98 int nitems_in_line = 0;
99 for (int i=0; i<number_lines; ++i) {
100 char line[LINE_LENGTH];
101 if (!fgets(line, sizeof(line), file)) {
102 printf("read situs file failed\n");
103 }
104
105 nitems_in_line = (int) (strlen(line) / FLOAT_SIZE);
106 char * pline = line;
107 for (int j=0; j<nitems_in_line; ++j) {
108 sscanf(pline, "%f", &data[index]);
109 pline += FLOAT_SIZE;
110 ++index;
111 }
112 }
113
114 EXITFUNC;
115 return 0;
116}
117
118int SitusIO::read_header(EMAN::Dict& dict, int, const EMAN::Region*, bool)
119{
120 ENTERFUNC;
121 init();
122
123 dict["nx"] = nx;
124 dict["ny"] = ny;
125 dict["nz"] = nz;
126
127 dict["apix_x"] = apix;
128 dict["apix_y"] = apix;
129 dict["apix_z"] = apix;
130
131 dict["origin_x"] = origx;
132 dict["origin_y"] = origy;
133 dict["origin_z"] = origz;
134
135 EXITFUNC;
136 return 0;
137}
138
140{
141 ENTERFUNC;
142 init();
143
144 apix = (float)dict["apix_x"];
145 origx = (float)dict["origin_x"];
146 origy = (float)dict["origin_y"];
147 origz = (float)dict["origin_z"];
148 nx = (int)dict["nx"];
149 ny = (int)dict["ny"];
150 nz = (int)dict["nz"];
151
152 char headerline[LINE_LENGTH];
153 sprintf(headerline, "%.6f %.6f %.6f %.6f %d %d %d", apix, origx, origy, origz, nx, ny, nz);
154
155 if(!fputs(headerline, file)) {
156 printf("Write situs header failed\n");
157 }
158
159 if(!fputs("\n\n", file)) {
160 printf("Write situs header failed\n");
161 }
162
163 EXITFUNC;
164 return 0;
165}
166
167int SitusIO::write_data(float* data, int, const EMAN::Region*, EMAN::EMUtil::EMDataType, bool)
168{
169 ENTERFUNC;
170
171 for (size_t index=0; index<(size_t)nx*ny*nz; ++index) {
172 fprintf(file, OUTFORMAT, data[index]);
173 if((index+1)%NFLOAT_PER_LINE == 0) {
174 fputs("\n", file);
175 }
176 }
177
178 EXITFUNC;
179 return 0;
180}
181
182bool SitusIO::is_valid(const void *first_block)
183{
184 ENTERFUNC;
185 if (!first_block) {
186 return false;
187 }
188
189 char *buf = (char *)(first_block);
190 string line1 = Util::get_line_from_string(&buf);
191
192 if(line1.size()==0) return false;
193
194 float apix, origx, origy, origz;
195 int nx, ny, nz, missing;
196
197 // We're looking for exactly 7
198 if(sscanf(line1.c_str(), "%f %f %f %f %d %d %d %d", &apix, &origx, &origy, &origz, &nx, &ny, &nz,&missing) != 7) return false;
199
200 if(apix<0.01 || apix>100) return false;
201 if(nx<=0 || ny<0 || nz<0) return false;
202
203 EXITFUNC;
204 return true;
205}
206
207void SitusIO::flush()
208{
209 fflush(file);
210}
211
213{
215}
216
218{
219 return false;
220}
static bool is_host_big_endian()
Definition: byteorder.cpp:40
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
static void jump_lines(FILE *file, int nlines)
Definition: emutil.cpp:1493
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.
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
Definition: geometry.h:497
static const int SITUS_HEADER_LINES
Definition: situsio.h:64
float origx
Definition: situsio.h:61
float origy
Definition: situsio.h:61
static bool is_valid(const void *first_block)
Definition: situsio.cpp:182
static const int LINE_LENGTH
Definition: situsio.h:68
float apix
Definition: situsio.h:61
static const char * OUTFORMAT
Definition: situsio.h:67
static const int NFLOAT_PER_LINE
Definition: situsio.h:66
bool is_new_file
Definition: situsio.h:59
float origz
Definition: situsio.h:61
static const int FLOAT_SIZE
Definition: situsio.h:65
static string get_line_from_string(char **str)
Extract a single line from a multi-line string.
Definition: util.cpp:322
#define ImageReadException(filename, desc)
Definition: exception.h:204
#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)