Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

gatan2io.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 "gatan2io.h"
00037 #include "geometry.h"
00038 #include "portable_fileio.h"
00039 #include <cstring>
00040 
00041 using namespace EMAN;
00042 
00043 Gatan2IO::Gatan2IO(const string & file, IOMode rw)
00044 :       filename(file), rw_mode(rw), gatan2_file(0), initialized(false)
00045 {
00046         is_big_endian = ByteOrder::is_host_big_endian();
00047         memset(&gatanh, 0, sizeof(Gatan2Header));
00048 }
00049 
00050 Gatan2IO::~Gatan2IO()
00051 {
00052         if (gatan2_file) {
00053                 fclose(gatan2_file);
00054                 gatan2_file = 0;
00055         }
00056 }
00057 
00058 void Gatan2IO::init()
00059 {
00060         ENTERFUNC;
00061         
00062         if (initialized) {
00063                 return;
00064         }
00065         
00066         initialized = true;
00067 
00068         bool is_new_file = false;
00069         gatan2_file = sfopen(filename, rw_mode, &is_new_file);
00070 
00071         if (!is_new_file) {
00072                 if (fread(&gatanh, sizeof(Gatan2Header), 1, gatan2_file) != 1) {
00073                         throw ImageReadException(filename, "Gatan2 Header");
00074                 }
00075 
00076                 if (!is_valid(&gatanh)) {
00077                         throw ImageReadException(filename, "invalid Gatan2 file");
00078                 }
00079 
00080                 is_big_endian = ByteOrder::is_data_big_endian(&gatanh.len);
00081                 become_host_endian((short *) &gatanh, sizeof(Gatan2Header) / sizeof(short));
00082         }
00083         EXITFUNC;
00084 }
00085 
00086 bool Gatan2IO::is_valid(const void *first_block)
00087 {
00088         ENTERFUNC;
00089         bool result = false;
00090         
00091         if (!first_block) {
00092                 result = false;
00093         }
00094         else {
00095                 const short *data = static_cast < const short *>(first_block);
00096                 short len = data[5];
00097                 short type = data[6];
00098 
00099                 bool data_big_endian = ByteOrder::is_data_big_endian(&len);
00100 
00101                 if (data_big_endian != ByteOrder::is_host_big_endian()) {
00102                         ByteOrder::swap_bytes(&len);
00103                         ByteOrder::swap_bytes(&type);
00104                 }
00105 
00106                 int double_size = sizeof(double);
00107                 if (len > 0 && len <= double_size && type > 0 && type <= GATAN2_INVALID) {
00108                         result = true;
00109                 }
00110         }
00111         EXITFUNC;
00112         return result;
00113 }
00114 
00115 int Gatan2IO::read_header(Dict & dict, int image_index, const Region * area, bool)
00116 {
00117         ENTERFUNC;
00118         //single image format, index can only be zero
00119         if(image_index == -1) {
00120                 image_index = 0;
00121         }
00122 
00123         if(image_index != 0) {
00124                 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().");
00125         }
00126 
00127         init();
00128         
00129         if (is_complex_mode()) {
00130                 throw ImageReadException(filename, "Cannot read complex Gatan2 files");
00131         }
00132         else {
00133                 check_region(area, IntSize(gatanh.nx, gatanh.ny));
00134 
00135                 int xlen = 0, ylen = 0;
00136                 EMUtil::get_region_dims(area, gatanh.nx, &xlen, gatanh.ny, &ylen);
00137                                 
00138                 dict["nx"] = xlen;
00139                 dict["ny"] = ylen;
00140                 dict["nz"] = 1;
00141                 dict["datatype"] = to_em_datatype(gatanh.type); 
00142         }
00143         
00144         EXITFUNC;
00145         return 0;
00146 }
00147 
00148 int Gatan2IO::write_header(const Dict &, int, const Region* , EMUtil::EMDataType, bool)
00149 {
00150         ENTERFUNC;
00151         LOGWARN("Gatan2 write is not supported.");
00152         EXITFUNC;
00153         return 1;
00154 }
00155 
00156 int Gatan2IO::read_data(float *data, int image_index, const Region * area, bool )
00157 {
00158         ENTERFUNC;
00159         //single image format, index can only be zero
00160         image_index = 0;
00161         check_read_access(image_index, data);
00162 
00163         if (is_complex_mode()) {
00164                 throw ImageReadException(filename, "Cannot read complex Gatan2 files");
00165         }
00166         
00167         check_region(area, IntSize(gatanh.nx, gatanh.ny));
00168         
00169         portable_fseek(gatan2_file, sizeof(Gatan2Header), SEEK_SET);
00170 
00171 #if 0
00172         if (fread(data, gatanh.nx * gatanh.len, gatanh.ny, gatan2_file) != (unsigned int) gatanh.ny) {
00173                 LOGDEBUG("Data read incomplete in Gatan file '%s'", filename.c_str());
00174                 return 1;
00175         }
00176 #endif
00177 
00178         int size = gatanh.nx * gatanh.ny;
00179         short *sdata = (short *) data;
00180         unsigned char *cdata = (unsigned char *) data;
00181         int *ldata = (int *) data;
00182 
00183         EMUtil::process_region_io(cdata, gatan2_file, READ_ONLY, image_index, gatanh.len,
00184                                                           gatanh.nx, gatanh.ny, 1, area);
00185 
00186         switch (gatanh.type) {
00187         case GATAN2_SHORT:
00188                 become_host_endian((short *) data, size);
00189                 for (int i = size - 1; i >= 0; i--) {
00190                         data[i] = static_cast < float >(sdata[i]);
00191                 }
00192                 break;
00193         case GATAN2_FLOAT:
00194                 become_host_endian(data, size);
00195                 break;
00196         case GATAN2_CHAR:
00197                 for (int i = size - 1; i >= 0; i--) {
00198                         data[i] = static_cast < float >(cdata[i]);
00199                 }
00200                 break;
00201         case GATAN2_INT:
00202                 become_host_endian((int *) data, size);
00203                 for (int i = size - 1; i >= 0; i--) {
00204                         data[i] = static_cast < float >(ldata[i]);
00205                 }
00206                 break;
00207         default:
00208                 throw ImageReadException(filename, "unsupported Gatan2 data type");
00209         }
00210         EXITFUNC;
00211         return 0;
00212 }
00213 
00214 int Gatan2IO::write_data(float *, int, const Region*, EMUtil::EMDataType, bool)
00215 {
00216         ENTERFUNC;
00217         LOGWARN("Gatan2 write is not supported.");
00218         EXITFUNC;
00219         return 1;
00220 }
00221 
00222 void Gatan2IO::flush()
00223 {
00224 }
00225 
00226 bool Gatan2IO::is_complex_mode()
00227 {
00228         init();
00229         if (gatanh.type == GATAN2_COMPLEX || gatanh.type == GATAN2_PACKED_COMPLEX) {
00230                 return true;
00231         }
00232         return false;
00233 }
00234 
00235 bool Gatan2IO::is_image_big_endian()
00236 {
00237         init();
00238         return is_big_endian;
00239 }
00240 
00241 
00242 
00243 int Gatan2IO::to_em_datatype(int gatan_type)
00244 {
00245         switch (gatan_type) {
00246         case GATAN2_SHORT:
00247                 return EMUtil::EM_SHORT;
00248 
00249         case GATAN2_FLOAT:
00250                 return EMUtil::EM_FLOAT;
00251 
00252         case GATAN2_CHAR:
00253                 return EMUtil::EM_CHAR;
00254 
00255         case GATAN2_INT:
00256                 return EMUtil::EM_INT;
00257         }
00258 
00259         return EMUtil::EM_UNKNOWN;
00260 }

Generated on Tue Jun 11 13:40:38 2013 for EMAN2 by  doxygen 1.3.9.1