EMAN2
fitsio.cpp
Go to the documentation of this file.
1/*
2 * Author: Steven Ludtke, 04/10/2003 (sludtke@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 <cstring>
33#include "fitsio.h"
34#include "portable_fileio.h"
35#include "geometry.h"
36#include "util.h"
37#include "ctf.h"
38
39using namespace EMAN;
40
41FitsIO::FitsIO(const string & fname, IOMode rw)
42: ImageIO(fname, rw)
43{
45 is_new_file = false;
46}
47
49{
50 if (file) {
51 fclose(file);
52 file = 0;
53 }
54}
55
56void FitsIO::init()
57{
59
60 if (initialized) {
61 return;
62 }
63
64 initialized = true;
66
68}
69
70
72{
73 init();
74 return is_big_endian;
75}
76
77bool FitsIO::is_valid(const void *first_block, off_t)
78{
80
81 if (!first_block) {
82 return false;
83 }
84
85 if (strncmp("SIMPLE ",(const char *)first_block,8)==0) return true;
86
88 return false;
89}
90
91int FitsIO::read_header(Dict & dict, int image_index, const Region * area, bool )
92{
94
95// dict["apix_x"] = mrch.xlen / (mrch.nx - 1);
96// dict["apix_y"] = mrch.ylen / (mrch.ny - 1);
97 //single image format, index can only be zero
98 if(image_index == -1) {
99 image_index = 0;
100 }
101
102 if(image_index != 0) {
103 throw ImageReadException(filename, "no stack allowed for MRC image. For take 2D slice out of 3D image, read the 3D image first, then use get_clip().");
104 }
105 init();
106
107 if (area) throw ImageReadException(filename,"Area reading not supported for FITS format");
108
109 dict["nx"]=1;
110 dict["ny"]=1;
111 dict["nz"]=1;
112
113 char s[81],lbl[9],val[80];
114// int dim=0;
115 s[80]=0;
116 rewind(file);
117 size_t nr;
118 for (nr = fread(s,80,1,file); strncmp("END",s,3); nr = fread(s,80,1,file)) {
119 nr = nr;
120 sscanf(s,"%8s = %[^/]",lbl,val);
121// printf("%s,%s\n",lbl,val);
122 if (strncmp("SIMPLE ",s,8)==0) continue;
123 else if (strncmp("END ",s,8)==0) break;
124// else if (strncmp("BITPIX ",s,8)==0)
125// else if (strncmp("NAXIS ",s,8)==0) dim=atoi(val);
126 else if (strncmp("NAXIS",s,5)==0) {
127 if (s[5]=='1') dict["nx"]=atoi(val);
128 if (s[5]=='2') dict["ny"]=atoi(val);
129 if (s[5]=='3') dict["nz"]=atoi(val);
130 }
131 else {
132 dict[(string)"FITS."+lbl]=val;
133 }
134 }
135
136 dstart=((ftell(file)-1)/2880+1)*2880;
137
138 int xlen = 0, ylen = 0, zlen = 0;
139 dtype=atoi(dict["FITS.BITPIX"]);
140 EMUtil::get_region_dims(area, dict["nx"], &xlen, dict["ny"], &ylen, dict["nz"], &zlen);
141
142 dict["nx"] = nx=xlen;
143 dict["ny"] = ny=ylen;
144 dict["nz"] = nz=zlen;
145
146 EXITFUNC;
147 return 0;
148}
149
150int FitsIO::write_header(const Dict &, int, const Region*, EMUtil::EMDataType, bool)
151{
152 ENTERFUNC;
153// check_write_access(rw_mode, image_index, 1);
154 LOGWARN("FITS write is not supported.");
155 EXITFUNC;
156 return 0;
157}
158
159int FitsIO::read_data(float *rdata, int image_index, const Region *, bool )
160{
161 ENTERFUNC;
162 size_t i;
163 size_t nr;
164 size_t size = (size_t)nx*ny*nz;
165
166 //single image format, index can only be zero
167 image_index = 0;
168 check_read_access(image_index, rdata);
169
170 portable_fseek(file, dstart, SEEK_SET);
171 unsigned char *cdata=(unsigned char *)rdata;
172 short *sdata=(short *)rdata;
173 int *idata=(int *)rdata;
174 double *ddata;
175
176 switch (dtype) {
177 case 8:
178 nr = fread(cdata,nx,ny*nz,file); nr++;
179 for (i=size-1; i<size; i--) rdata[i]=cdata[i];
180 break;
181 case 16:
182 nr = fread(cdata,nx,ny*nz*2,file); nr++;
183 if (!ByteOrder::is_host_big_endian()) ByteOrder::swap_bytes((short*) sdata, size);
184 for (i=size-1; i<size; i--) rdata[i]=sdata[i];
185 break;
186 case 32:
187 nr = fread(cdata,nx,ny*nz*4,file); nr++;
189 for (i=0; i<size; i++) rdata[i]=static_cast<float>(idata[i]);
190 break;
191 case -32:
192 nr = fread(cdata,nx*4,ny*nz,file); nr++;
194 break;
195 case -64:
196 ddata=(double *)malloc(size*8);
197 nr = fread(ddata,nx,ny*nz*8,file); nr++;
198 if (!ByteOrder::is_host_big_endian()) ByteOrder::swap_bytes((double*) ddata, size);
199 for (i=0; i<size; i++) rdata[i]=static_cast<float>(ddata[i]);
200 free(ddata);
201 break;
202 }
203
204 EXITFUNC;
205 return 0;
206}
207
208int FitsIO::write_data(float *data, int image_index, const Region*,
209 EMUtil::EMDataType, bool)
210{
211 ENTERFUNC;
212
213 check_write_access(rw_mode, image_index, 1, data);
214// check_region(area, FloatSize(mrch.nx, mrch.ny, mrch.nz), is_new_file);
215
216
217 EXITFUNC;
218 return 0;
219}
220
221
223{
224 init();
225 return false;
226}
227
228void FitsIO::flush()
229{
230 fflush(file);
231}
232
234{
235 ENTERFUNC;
236 init();
237 EXITFUNC;
238 return 0;
239}
240
241void FitsIO::write_ctf(const Ctf &, int)
242{
243 ENTERFUNC;
244 init();
245
246 EXITFUNC;
247}
#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
Ctf is the base class for all CTF model.
Definition: ctf.h:60
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 get_region_dims(const Region *area, int nx, int *area_x, int ny, int *area_y, int nz=1, int *area_z=0)
Get a region's dimensions.
Definition: emutil.cpp:860
bool is_big_endian
Definition: fitsio.h:61
static bool is_valid(const void *first_block, off_t file_size=0)
Definition: fitsio.cpp:77
int nx
Definition: fitsio.h:65
int ny
Definition: fitsio.h:65
int nz
Definition: fitsio.h:65
int read_ctf(Ctf &ctf, int image_index=0)
Read CTF data from this image.
Definition: fitsio.cpp:233
int dstart
Definition: fitsio.h:63
void write_ctf(const Ctf &ctf, int image_index=0)
Write CTF data to this image.
Definition: fitsio.cpp:241
bool is_new_file
Definition: fitsio.h:62
int dtype
Definition: fitsio.h:64
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
void check_read_access(int image_index)
Validate 'image_index' in file reading.
Definition: imageio.cpp:95
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.
void check_write_access(IOMode rw_mode, int image_index, int max_nimg=0)
Validate rw_mode and image_index in file writing.
Definition: imageio.cpp:113
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
#define ImageReadException(filename, desc)
Definition: exception.h:204
#define LOGWARN
Definition: log.h:53
#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)