fitsio.cpp

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00033  *
00034  * */
00035 
00036 #include <cstring>
00037 #include "fitsio.h"
00038 #include "portable_fileio.h"
00039 #include "geometry.h"
00040 #include "util.h"
00041 #include "ctf.h"
00042 
00043 using namespace EMAN;
00044 
00045 FitsIO::FitsIO(const string & fits_filename, IOMode rw)
00046 :       filename(fits_filename), rw_mode(rw)
00047 {
00048         is_big_endian = ByteOrder::is_host_big_endian();
00049         is_new_file = false;
00050         initialized = false;
00051         fitsfile=0;
00052 }
00053 
00054 FitsIO::~FitsIO()
00055 {
00056         if (fitsfile) {
00057                 fclose(fitsfile);
00058                 fitsfile = 0;
00059         }
00060 }
00061 
00062 void FitsIO::init()
00063 {
00064         ENTERFUNC;
00065 
00066         if (initialized) {
00067                 return;
00068         }
00069 
00070         initialized = true;
00071         fitsfile = sfopen(filename, rw_mode, &is_new_file);
00072 
00073         EXITFUNC;
00074 }
00075 
00076 
00077 bool FitsIO::is_image_big_endian()
00078 {
00079         init();
00080         return is_big_endian;
00081 }
00082 
00083 bool FitsIO::is_valid(const void *first_block, off_t)
00084 {
00085         ENTERFUNC;
00086 
00087         if (!first_block) {
00088                 return false;
00089         }
00090 
00091         if (strncmp("SIMPLE  ",(const char *)first_block,8)==0) return true;
00092 
00093         EXITFUNC;
00094         return false;
00095 }
00096 
00097 int FitsIO::read_header(Dict & dict, int image_index, const Region * area, bool )
00098 {
00099         ENTERFUNC;
00100 
00101 //      dict["apix_x"] = mrch.xlen / (mrch.nx - 1);
00102 //      dict["apix_y"] = mrch.ylen / (mrch.ny - 1);
00103         //single image format, index can only be zero
00104         if(image_index == -1) {
00105                 image_index = 0;
00106         }
00107 
00108         if(image_index != 0) {
00109                 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().");
00110         }
00111         init();
00112 
00113         if (area) throw ImageReadException(filename,"Area reading not supported for FITS format");
00114 
00115         dict["nx"]=1;
00116         dict["ny"]=1;
00117         dict["nz"]=1;
00118 
00119         char s[81],lbl[9],val[80];
00120         int dim=0;
00121         s[80]=0;
00122         rewind(fitsfile);
00123         for (fread(s,80,1,fitsfile); strncmp("END",s,3); fread(s,80,1,fitsfile)) {
00124                 sscanf(s,"%8s = %[^/]",lbl,val);
00125 //              printf("%s,%s\n",lbl,val);
00126                 if (strncmp("SIMPLE  ",s,8)==0) continue;
00127                 else if (strncmp("END     ",s,8)==0) break;
00128 //              else if (strncmp("BITPIX  ",s,8)==0)
00129                 else if (strncmp("NAXIS   ",s,8)==0) dim=atoi(val);
00130                 else if (strncmp("NAXIS",s,5)==0) {
00131                         if (s[5]=='1') dict["nx"]=atoi(val);
00132                         if (s[5]=='2') dict["ny"]=atoi(val);
00133                         if (s[5]=='3') dict["nz"]=atoi(val);
00134                 }
00135                 else {
00136                         dict[(string)"FITS."+lbl]=val;
00137                 }
00138         }
00139 
00140         dstart=((ftell(fitsfile)-1)/2880+1)*2880;
00141 
00142         int xlen = 0, ylen = 0, zlen = 0;
00143         dtype=atoi(dict["FITS.BITPIX"]);
00144         EMUtil::get_region_dims(area, dict["nx"], &xlen, dict["ny"], &ylen, dict["nz"], &zlen);
00145 
00146         dict["nx"] = nx=xlen;
00147         dict["ny"] = ny=ylen;
00148         dict["nz"] = nz=zlen;
00149 
00150         EXITFUNC;
00151         return 0;
00152 }
00153 
00154 int FitsIO::write_header(const Dict & , int image_index, const Region*,
00155                                                 EMUtil::EMDataType, bool)
00156 {
00157         ENTERFUNC;
00158 //      check_write_access(rw_mode, image_index, 1);
00159         LOGWARN("FITS write is not supported.");
00160         EXITFUNC;
00161         return 0;
00162 }
00163 
00164 int FitsIO::read_data(float *rdata, int image_index, const Region *, bool )
00165 {
00166         ENTERFUNC;
00167         size_t i;
00168         size_t size = nx*ny*nz;
00169 
00170         //single image format, index can only be zero
00171         image_index = 0;
00172         check_read_access(image_index, rdata);
00173 
00174         portable_fseek(fitsfile, dstart, SEEK_SET);
00175         char *cdata=(char *)rdata;
00176         short *sdata=(short *)rdata;
00177         int *idata=(int *)rdata;
00178         double *ddata;
00179 
00180         switch (dtype) {
00181         case 8:
00182                 fread(cdata,nx,ny*nz,fitsfile);
00183                 for (i=size-1; i>=0; i--) rdata[i]=cdata[i];
00184                 break;
00185         case 16:
00186                 fread(cdata,nx,ny*nz*2,fitsfile);
00187                 if (!ByteOrder::is_host_big_endian()) ByteOrder::swap_bytes((short*) sdata, size);
00188                 for (i=size-1; i>=0; i--) rdata[i]=sdata[i];
00189                 break;
00190         case 32:
00191                 fread(cdata,nx,ny*nz*4,fitsfile);
00192                 if (!ByteOrder::is_host_big_endian()) ByteOrder::swap_bytes((int*) rdata, size);
00193                 for (i=0; i<size; i++) rdata[i]=static_cast<float>(idata[i]);
00194                 break;
00195         case -32:
00196                 fread(cdata,nx*4,ny*nz,fitsfile);
00197                 if (!ByteOrder::is_host_big_endian()) ByteOrder::swap_bytes((float*) rdata, size);
00198                 break;
00199         case -64:
00200                 ddata=(double *)malloc(size*8);
00201                 fread(ddata,nx,ny*nz*8,fitsfile);
00202                 if (!ByteOrder::is_host_big_endian()) ByteOrder::swap_bytes((double*) ddata, size);
00203                 for (i=0; i<size; i++) rdata[i]=static_cast<float>(ddata[i]);
00204                 free(ddata);
00205                 break;
00206         }
00207 
00208         EXITFUNC;
00209         return 0;
00210 }
00211 
00212 int FitsIO::write_data(float *data, int image_index, const Region*,
00213                                           EMUtil::EMDataType, bool)
00214 {
00215         ENTERFUNC;
00216 
00217         check_write_access(rw_mode, image_index, 1, data);
00218 //      check_region(area, FloatSize(mrch.nx, mrch.ny, mrch.nz), is_new_file);
00219 
00220 
00221         EXITFUNC;
00222         return 0;
00223 }
00224 
00225 
00226 bool FitsIO::is_complex_mode()
00227 {
00228         init();
00229         return false;
00230 }
00231 
00232 void FitsIO::flush()
00233 {
00234         fflush(fitsfile);
00235 }
00236 
00237 int FitsIO::read_ctf(Ctf &, int)
00238 {
00239         ENTERFUNC;
00240         init();
00241         EXITFUNC;
00242         return 0;
00243 }
00244 
00245 void FitsIO::write_ctf(const Ctf &, int)
00246 {
00247         ENTERFUNC;
00248         init();
00249 
00250         EXITFUNC;
00251 }

Generated on Tue May 25 17:13:32 2010 for EMAN2 by  doxygen 1.4.7