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

imagicio2.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 "imagicio.h"
00038 #include "portable_fileio.h"
00039 #include "util.h"
00040 #include "geometry.h"
00041 #include "ctf.h"
00042 #include "emassert.h"
00043 #include "transform.h"
00044 
00045 #ifdef _WIN32
00046         #include <ctime>
00047 #endif  //_WIN32
00048 
00049 using namespace EMAN;
00050 
00051 const char *ImagicIO::HED_EXT = "hed";
00052 const char *ImagicIO::IMG_EXT = "img";
00053 const char *ImagicIO::REAL_TYPE_MAGIC = "REAL";
00054 const char *ImagicIO::CTF_MAGIC = "!-";
00055 
00056 ImagicIO2::ImagicIO2(string file, IOMode rw)
00057 :       filename(file), rw_mode(rw), hed_file(0), img_file(0), initialized(false)
00058 {
00059         hed_filename = Util::change_filename_ext(filename, HED_EXT);
00060         img_filename = Util::change_filename_ext(filename, IMG_EXT);
00061 
00062         is_big_endian = ByteOrder::is_host_big_endian();
00063         is_new_hed = false;
00064         is_new_img = false;
00065         memset(&imagich, 0, sizeof(Imagic4D));
00066         imagich.count = -1;
00067         datatype = IMAGIC_UNKNOWN_TYPE;
00068         nz = 0;
00069 }
00070 
00071 ImagicIO2::~ImagicIO2()
00072 {
00073         if (hed_file) {
00074                 fclose(hed_file);
00075                 hed_file = 0;
00076         }
00077 
00078         if (img_file) {
00079                 fclose(img_file);
00080                 img_file = 0;
00081         }
00082 }
00083 
00084 void ImagicIO2::init()
00085 {
00086         ENTERFUNC;
00087 
00088         if (initialized) {
00089                 return;
00090         }
00091 
00092         initialized = true;
00093 
00094         is_new_hed = false;
00095         is_new_img = false;
00096 
00097         hed_file = sfopen(hed_filename, rw_mode, &is_new_hed);
00098         img_file = sfopen(img_filename, rw_mode, &is_new_img);
00099 
00100         if (is_new_hed != is_new_img) {
00101                 LOGWARN("IMAGIC header file and data file should both exist or both not exist");
00102         }
00103 
00104         if (!is_new_hed) {
00105                 if (fread(&imagich, sizeof(ImagicHeader), 1, hed_file) != 1) {
00106                         throw ImageReadException(hed_filename, "IMAGIC header");
00107                 }
00108 
00109                 if (!is_valid(&imagich)) {
00110                         throw ImageReadException(hed_filename, "invalid IMAGIC file");
00111                 }
00112 
00113                 datatype = get_datatype_from_name(imagich.type);
00114 
00115                 if (datatype != IMAGIC_USHORT && datatype != IMAGIC_FLOAT) {
00116                         LOGERR("unsupported imagic data type: %s", imagich.type);
00117                         throw ImageReadException(hed_filename, "unsupported imagic data type");
00118                 }
00119 
00120                 is_big_endian = ByteOrder::is_data_big_endian(&imagich.ny);
00121                 make_header_host_endian(imagich);
00122                 rewind(hed_file);
00123         }
00124         EXITFUNC;
00125 }
00126 
00127 bool ImagicIO2::is_valid(const void *first_block)
00128 {
00129         ENTERFUNC;
00130 
00131         if (!first_block) {
00132                 return false;
00133         }
00134 
00135         const int *data = static_cast < const int *>(first_block);
00136         int count = data[1];
00137         int headrec = data[3];
00138         int month = data[4];
00139         int hour = data[7];
00140         int nx = data[13];
00141         int ny = data[12];
00142         int realtype = data[68];
00143         
00144         bool data_big_endian = ByteOrder::is_data_big_endian(&headrec);
00145 
00146         if (data_big_endian != ByteOrder::is_host_big_endian()) {
00147                 ByteOrder::swap_bytes(&count);
00148                 ByteOrder::swap_bytes(&headrec);
00149                 ByteOrder::swap_bytes(&month);
00150                 ByteOrder::swap_bytes(&hour);
00151                 ByteOrder::swap_bytes(&nx);
00152                 ByteOrder::swap_bytes(&ny);
00153                 ByteOrder::swap_bytes(&realtype);
00154         }
00155 
00156         const int max_dim = 1 << 20;
00157         bool result = false;
00158 
00159         // this field realtype is unique to new Imagic-5 format
00160         if(realtype != VAX_VMS && realtype != LINUX_WINDOWS && realtype != SGI_IBM) {
00161                 EXITFUNC;
00162                 return result;
00163         }
00164         
00165         if (headrec == 1 &&
00166                 count >= 0 && count < max_dim &&
00167                 nx > 0 && nx < max_dim &&
00168                 ny > 0 && ny < max_dim && 
00169                 month >= 0 && month <=12 && 
00170                 hour >= 0 && hour <= 24) {
00171                 result = true;
00172         }
00173 
00174         EXITFUNC;
00175         return result;
00176 }
00177 
00178 int ImagicIO2::read_header(Dict & dict, int image_index, const Region * area, bool)
00179 {
00180         ENTERFUNC;
00181 
00182         check_read_access(image_index);
00183 
00184         int nimg = 1;
00185 
00186         Imagic4D hed;
00187         if (image_index == 0) {
00188                 hed = imagich;
00189         }
00190         else {
00191                 memset(&hed, 0, sizeof(Imagic4D));
00192                 portable_fseek(hed_file, sizeof(Imagic5H) * image_index, SEEK_SET);
00193                 fread(&hed, sizeof(Imagic4D), 1, hed_file);
00194                 make_header_host_endian(hed);
00195         }
00196         check_region(area, FloatSize(hed.nx, hed.ny, nimg), is_new_hed, false);
00197 
00198     datatype = get_datatype_from_name(imagich.type);
00199 
00200         int xlen = 0, ylen = 0, zlen = 0;
00201         EMUtil::get_region_dims(area, hed.nx, &xlen, hed.ny, &ylen, hed.izlp, &zlen);
00202 
00203         dict["nx"] = xlen;
00204         dict["ny"] = ylen;
00205         dict["nz"] = zlen;
00206 
00207         dict["IMAGIC.imgnum"] = hed.imgnum;
00208         dict["IMAGIC.count"] = hed.count;
00209         dict["IMAGIC.error"] = hed.error;
00210         
00211         dict["IMAGIC.month"] = hed.month;
00212         dict["IMAGIC.day"] = hed.mday;
00213         dict["IMAGIC.year"] = hed.year;
00214         dict["IMAGIC.hour"] = hed.hour;
00215         dict["IMAGIC.minute"] = hed.minute;
00216         dict["IMAGIC.sec"] = hed.sec;
00217 
00218         dict["IMAGIC.reals"] = hed.reals;
00219         dict["IMAGIC.izold"] = hed.izold;
00220         
00221         dict["datatype"] = to_em_datatype(hed.type);
00222 
00223         dict["IMAGIC.ixold"] = hed.ixold;
00224         dict["IMAGIC.iyold"] = hed.iyold;
00225         
00226         dict["mean"] = hed.avdens;
00227         dict["sigma"] = hed.sigma;
00228         dict["variance"] = hed.varia;
00229         dict["IMAGIC.oldav"] = hed.oldav;
00230         dict["maximum"] = hed.max;
00231         dict["minimum"] = hed.min;
00232         
00233         dict["IMAGIC.cellx"] = hed.cellx;
00234         dict["IMAGIC.celly"] = hed.celly;
00235         dict["IMAGIC.cellz"] = hed.cellz;
00236         dict["IMAGIC.cell_alpha"] = hed.clpha; 
00237         dict["IMAGIC.cell_beta"] = hed.cbeta;
00238         dict["IMAGIC.cell_gamma"] = hed.cgamma;
00239 
00240         dict["IMAGIC.label"] = hed.label; 
00241         dict["IMAGIC.mapc"] = hed.mapc;
00242         dict["IMAGIC.mapr"] = hed.mapr;
00243         dict["IMAGIC.maps"] = hed.maps;
00244         
00245         dict["IMAGIC.ispg"] = hed.ispg;
00246         dict["IMAGIC.nxstart"] = hed.nxstart;
00247         dict["IMAGIC.nystart"] = hed.nystart;
00248         dict["IMAGIC.nzstart"] = hed.nzstart;
00249         
00250         dict["IMAGIC.nxintv"] = hed.nxintv;
00251         dict["IMAGIC.nyintv"] = hed.nyintv;
00252         dict["IMAGIC.nzintv"] = hed.nzintv;
00253         
00254         dict["IMAGIC.i4lp"] = hed.i4lp; //number of 3D volumes in 4D data
00255         
00256         
00257         char tmp[5] = { hed.type[0],hed.type[1],hed.type[2],hed.type[3],0 };
00258         dict["IMAGIC.type"] = tmp;
00259         
00260 
00261         dict["IMAGIC.oldav"] = hed.oldav;
00262         
00263         dict["ptcl_repr"] = hed.mrc2;                   // raw images represented by this image
00264 
00265         dict["orientation_convention"] = "EMAN";
00266     const float alt = hed.mrc1[1]*180.0f/M_PI;
00267     const float az = hed.mrc1[2]*180.0f/M_PI;
00268     const float phi = hed.mrc1[0]*180.0f/M_PI;
00269         dict["euler_alt"] = alt;
00270         dict["euler_az"] = az;
00271         dict["euler_phi"] = phi;
00272         Transform *trans = new Transform();
00273         trans->set_rotation(Dict("type", "eman", "alt", alt, "az", az, "phi", phi));
00274         if( hed.count==0 ) {
00275                 dict["xform.projection"] = trans;
00276         }
00277         else {
00278                 dict["xform.projection"] = trans;
00279                 dict["xform.align3d"] = trans;
00280         }
00281         Ctf * ctf_ = read_ctf(hed);
00282         if( ctf_ != 0) {
00283                 dict["ctf"] = ctf_;
00284         }
00285         if(trans) {delete trans; trans=0;}
00286         if(ctf_) {delete ctf_; ctf_=0;}
00287         EXITFUNC;
00288         return 0;
00289 }
00290 
00291 ImagicIO2::DataType ImagicIO2::get_datatype_from_name(const char *name)
00292 {
00293         DataType t = IMAGIC_UNKNOWN_TYPE;
00294 
00295         if (strncmp(name, "PACK",4) == 0) {
00296                 t = IMAGIC_CHAR;
00297         }
00298         else if (strncmp(name, "INTG",4) == 0) {
00299                 t = IMAGIC_SHORT;
00300         }
00301         else if (strncmp(name, REAL_TYPE_MAGIC,4) == 0) {
00302                 t = IMAGIC_FLOAT;
00303         }
00304         else if (strncmp(name, "COMP",4) == 0) {
00305                 t = IMAGIC_FLOAT_COMPLEX;
00306         }
00307         else if (strncmp(name, "RECO",4) == 0) {
00308                 t = IMAGIC_FFT_FLOAT_COMPLEX;
00309         }
00310         return t;
00311 }
00312 
00313 int ImagicIO2::to_em_datatype(DataType t)
00314 {
00315         switch (t) {
00316         case IMAGIC_CHAR:
00317                 return EMUtil::EM_CHAR;
00318         case IMAGIC_SHORT:
00319                 return EMUtil::EM_SHORT;
00320         case IMAGIC_FLOAT:
00321                 return EMUtil::EM_FLOAT;
00322         case IMAGIC_FLOAT_COMPLEX:
00323         case IMAGIC_FFT_FLOAT_COMPLEX:
00324                 return EMUtil::EM_FLOAT_COMPLEX;
00325         default:
00326                 break;
00327         }
00328 
00329         return EMUtil::EM_UNKNOWN;
00330 }
00331 
00332 Ctf * ImagicIO2::read_ctf(const Imagic5H& hed) const
00333 {
00334         ENTERFUNC;
00335 
00336         Ctf * ctf_ = 0;
00337         size_t n = strlen(CTF_MAGIC);
00338 
00339         if (strncmp(imagich.label, CTF_MAGIC, n) == 0) {
00340                 ctf_ = new EMAN1Ctf();
00341                 string header_label(hed.label);
00342                 // Note: this block was making things crash because it assumed the following if statement
00343                 // was true - I added the if statement (d.woolford)
00344                 if (header_label.size() > 2) {
00345                         string sctf = "O" + header_label.substr(2);
00346                         ctf_->from_string(sctf);
00347                 }
00348         }
00349 
00350         EXITFUNC;
00351         return ctf_;
00352 }
00353 
00354 void ImagicIO2::write_ctf(const Ctf * const ctf, int image_index)
00355 {
00356         ENTERFUNC;
00357         init();
00358 
00359         size_t n = strlen(CTF_MAGIC);
00360         strcpy(imagich.label, CTF_MAGIC);
00361         string ctf_ = ctf->to_string().substr(1);
00362         strncpy(&imagich.label[n], ctf_.c_str(), sizeof(imagich.label) - n);
00363 
00364         rewind(hed_file);
00365         if (fwrite(&imagich, sizeof(ImagicHeader), 1, hed_file) != 1) {
00366                 throw ImageWriteException(hed_filename, "Imagic Header");
00367         }
00368 
00369         EXITFUNC;
00370 }

Generated on Mon Jul 19 13:03:44 2010 for EMAN2 by  doxygen 1.4.4