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

EMAN::MrcIO Class Reference

MRC file = header + data (nx x ny x nz). More...

#include <mrcio.h>

Inheritance diagram for EMAN::MrcIO:

Inheritance graph
[legend]
Collaboration diagram for EMAN::MrcIO:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 MrcIO (const string &filename, IOMode rw_mode=READ_ONLY)
 ~MrcIO ()
int read_ctf (Ctf &ctf, int image_index=0)
 Read CTF data from this image.
void write_ctf (const Ctf &ctf, int image_index=0)
 Write CTF data to this image.

Static Public Member Functions

bool is_valid (const void *first_block, off_t file_size=0)
int get_mode_size (int mm)
int to_em_datatype (int mrcmode)
int to_mrcmode (int em_datatype, int is_complex)

Public Attributes

 DEFINE_IMAGEIO_FUNC

Private Types

enum  MrcMode {
  MRC_UCHAR = 0, MRC_SHORT, MRC_FLOAT, MRC_SHORT_COMPLEX,
  MRC_FLOAT_COMPLEX, MRC_USHORT = 6, MRC_UCHAR3 = 16, MRC_UNKNOWN
}
enum  { MRC_NUM_LABELS = 10, MRC_LABEL_SIZE = 80, NUM_4BYTES_PRE_MAP = 52, NUM_4BYTES_AFTER_MAP = 3 }

Private Member Functions

void swap_header (MrcHeader &mrch)
void update_stat (void *data)
 This is a utility function used to calculate new min/max/mean/sigma when write MRC file as 16 bit or 8 bit.

Static Private Member Functions

int generate_machine_stamp ()
 generate the machine stamp used in MRC image format.

Private Attributes

string filename
IOMode rw_mode
FILE * mrcfile
MrcHeader mrch
int mode_size
int is_ri
bool is_big_endian
bool is_new_file
bool initialized

Static Private Attributes

const char * CTF_MAGIC = "!-"
const char * SHORT_CTF_MAGIC = "!$"

Detailed Description

MRC file = header + data (nx x ny x nz).

A MRC image file stores 1D, 2D or 3D image. The image's dimensions and pixel type are defined in the header.

Definition at line 48 of file mrcio.h.


Member Enumeration Documentation

anonymous enum [private]
 

Enumeration values:
MRC_NUM_LABELS 
MRC_LABEL_SIZE 
NUM_4BYTES_PRE_MAP 
NUM_4BYTES_AFTER_MAP 

Definition at line 76 of file mrcio.h.

00076                      {
00077                         MRC_NUM_LABELS = 10,
00078                         MRC_LABEL_SIZE = 80,
00079                         NUM_4BYTES_PRE_MAP = 52,
00080                         NUM_4BYTES_AFTER_MAP = 3
00081                 };

enum EMAN::MrcIO::MrcMode [private]
 

Enumeration values:
MRC_UCHAR 
MRC_SHORT 
MRC_FLOAT 
MRC_SHORT_COMPLEX 
MRC_FLOAT_COMPLEX 
MRC_USHORT 
MRC_UCHAR3 
MRC_UNKNOWN 

Definition at line 65 of file mrcio.h.

Referenced by to_mrcmode().

00065                              {
00066                         MRC_UCHAR = 0,
00067                         MRC_SHORT,
00068                         MRC_FLOAT,
00069                         MRC_SHORT_COMPLEX,
00070                         MRC_FLOAT_COMPLEX,
00071                         MRC_USHORT = 6,         //non-standard
00072                         MRC_UCHAR3 = 16,        //unsigned char * 3, for rgb data, non-standard
00073                         MRC_UNKNOWN
00074                 };


Constructor & Destructor Documentation

MrcIO::MrcIO const string &  filename,
IOMode  rw_mode = READ_ONLY
[explicit]
 

Definition at line 51 of file mrcio.cpp.

References initialized, is_big_endian, EMAN::ByteOrder::is_host_big_endian(), is_new_file, is_ri, and mrch.

00052 :       filename(mrc_filename), rw_mode(rw), mrcfile(0), mode_size(0)
00053 {
00054         memset(&mrch, 0, sizeof(MrcHeader));
00055         is_ri = 0;
00056         is_big_endian = ByteOrder::is_host_big_endian();
00057         is_new_file = false;
00058         initialized = false;
00059 }

MrcIO::~MrcIO  ) 
 

Definition at line 61 of file mrcio.cpp.

References mrcfile.

00062 {
00063         if (mrcfile) {
00064                 fclose(mrcfile);
00065                 mrcfile = 0;
00066         }
00067 }


Member Function Documentation

int MrcIO::generate_machine_stamp  )  [static, private]
 

generate the machine stamp used in MRC image format.

Definition at line 1000 of file mrcio.cpp.

References EMAN::ByteOrder::is_host_big_endian().

01001 {
01002         int stamp = 0;
01003         char *p = (char *) (&stamp);
01004 
01005         if (ByteOrder::is_host_big_endian()) {
01006                 p[0] = 0x11;
01007                 p[1] = 0x11;
01008                 p[2] = 0;
01009                 p[3] = 0;
01010         }
01011         else {
01012                 p[0] = 0x44;
01013                 p[1] = 0x41;
01014                 p[2] = 0;
01015                 p[3] = 0;
01016         }
01017         return stamp;
01018 }

int MrcIO::get_mode_size int  mm  )  [static]
 

Definition at line 893 of file mrcio.cpp.

References MRC_FLOAT, MRC_FLOAT_COMPLEX, MRC_SHORT, MRC_SHORT_COMPLEX, MRC_UCHAR, and MRC_USHORT.

Referenced by is_valid().

00894 {
00895         MrcIO::MrcMode m = static_cast < MrcMode > (mm);
00896 
00897         int msize = 0;
00898         switch (m) {
00899         case MRC_UCHAR:
00900                 msize = sizeof(char);
00901                 break;
00902         case MRC_SHORT:
00903         case MRC_USHORT:
00904         case MRC_SHORT_COMPLEX:
00905                 msize = sizeof(short);
00906                 break;
00907         case MRC_FLOAT:
00908         case MRC_FLOAT_COMPLEX:
00909                 msize = sizeof(float);
00910                 break;
00911         default:
00912                 msize = 0;
00913         }
00914 
00915         return msize;
00916 }

bool MrcIO::is_valid const void *  first_block,
off_t  file_size = 0
[static]
 

Definition at line 130 of file mrcio.cpp.

References data, get_mode_size(), EMAN::ByteOrder::is_data_big_endian(), EMAN::ByteOrder::is_host_big_endian(), LOGWARN, MRC_SHORT_COMPLEX, MRC_UCHAR, nx, ny, and EMAN::ByteOrder::swap_bytes().

Referenced by EMAN::EMUtil::fast_get_image_type(), and EMAN::EMUtil::get_image_type().

00131 {
00132         ENTERFUNC;
00133 
00134         if (!first_block) {
00135                 return false;
00136         }
00137 
00138         const int *data = static_cast < const int *>(first_block);
00139         int nx = data[0];
00140         int ny = data[1];
00141         int nz = data[2];
00142         int mrcmode = data[3];
00143         int nsymbt = data[23];  //this field specify the extra bytes for symmetry information
00144 
00145         bool data_big_endian = ByteOrder::is_data_big_endian(&nz);
00146 
00147         if (data_big_endian != ByteOrder::is_host_big_endian()) {
00148                 ByteOrder::swap_bytes(&nx);
00149                 ByteOrder::swap_bytes(&ny);
00150                 ByteOrder::swap_bytes(&nz);
00151                 ByteOrder::swap_bytes(&mrcmode);
00152                 ByteOrder::swap_bytes(&nsymbt);
00153         }
00154 
00155         if (mrcmode == MRC_SHORT_COMPLEX || mrcmode == MRC_FLOAT_COMPLEX) {
00156                 nx *= 2;
00157         }
00158 
00159         const int max_dim = 1 << 20;
00160 
00161         if ((mrcmode >= MRC_UCHAR && mrcmode < MRC_UNKNOWN) &&
00162                 (nx > 1 && nx < max_dim) && (ny > 0 && ny < max_dim) && (nz > 0 && nz < max_dim)) {
00163 //#ifndef SPIDERMRC // Spider MRC files don't satisfy the following test
00164                 if (file_size > 0) {
00165                         off_t file_size1 = (off_t)nx * (off_t)ny * (off_t)nz * (off_t)get_mode_size(mrcmode) + (off_t)sizeof(MrcHeader) + nsymbt;
00166                         if (file_size == file_size1) {
00167                                 return true;
00168                         }
00169 //                      return false;
00170                         LOGWARN("image size check fails, still try to read it...");     //when size doesn't match, print error message instead of make it fail
00171                 }
00172                 else {
00173                         return true;
00174                 }
00175 //#endif // SPIDERMRC
00176                 return true;
00177         }
00178         EXITFUNC;
00179         return false;
00180 }

int MrcIO::read_ctf Ctf ctf,
int  image_index = 0
[virtual]
 

Read CTF data from this image.

Parameters:
ctf Used to store the CTF data.
image_index The index of the image to read.
Returns:
0 if OK; 1 if error.

Reimplemented from EMAN::ImageIO.

Definition at line 858 of file mrcio.cpp.

References CTF_MAGIC, EMAN::Ctf::from_string(), EMAN::ImageIO::init(), EMAN::MrcIO::MrcHeader::labels, and mrch.

00859 {
00860         ENTERFUNC;
00861         init();
00862         size_t n = strlen(CTF_MAGIC);
00863 
00864         int err = 1;
00865         if (strncmp(&mrch.labels[0][0], CTF_MAGIC, n) == 0) {
00866                 err = ctf.from_string(string(&mrch.labels[0][n]));
00867         }
00868         EXITFUNC;
00869         return err;
00870 }

void MrcIO::swap_header MrcHeader mrch  )  [private]
 

Definition at line 1020 of file mrcio.cpp.

References NUM_4BYTES_AFTER_MAP, NUM_4BYTES_PRE_MAP, and EMAN::ByteOrder::swap_bytes().

01021 {
01022         ByteOrder::swap_bytes((int *) &mrch, NUM_4BYTES_PRE_MAP);
01023         ByteOrder::swap_bytes((int *) &mrch.machinestamp, NUM_4BYTES_AFTER_MAP);
01024 }

int MrcIO::to_em_datatype int  mrcmode  )  [static]
 

Definition at line 918 of file mrcio.cpp.

References MRC_FLOAT, MRC_FLOAT_COMPLEX, MRC_SHORT, MRC_SHORT_COMPLEX, MRC_UCHAR, and MRC_USHORT.

00919 {
00920         EMUtil::EMDataType e = EMUtil::EM_UNKNOWN;
00921 
00922         switch (m) {
00923         case MRC_UCHAR:
00924                 e = EMUtil::EM_UCHAR;
00925                 break;
00926         case MRC_SHORT:
00927                 e = EMUtil::EM_SHORT;
00928                 break;
00929         case MRC_USHORT:
00930                 e = EMUtil::EM_USHORT;
00931                 break;
00932         case MRC_SHORT_COMPLEX:
00933                 e = EMUtil::EM_SHORT_COMPLEX;
00934                 break;
00935         case MRC_FLOAT:
00936                 e = EMUtil::EM_FLOAT;
00937                 break;
00938         case MRC_FLOAT_COMPLEX:
00939                 e = EMUtil::EM_FLOAT_COMPLEX;
00940                 break;
00941         default:
00942                 e = EMUtil::EM_UNKNOWN;
00943         }
00944         return e;
00945 }

int MrcIO::to_mrcmode int  em_datatype,
int  is_complex
[static]
 

Definition at line 948 of file mrcio.cpp.

References MrcMode.

00949 {
00950         MrcMode m = MRC_UNKNOWN;
00951         EMUtil::EMDataType em_type = static_cast < EMUtil::EMDataType > (e);
00952 
00953         switch (em_type) {
00954         case EMUtil::EM_UCHAR:
00955                 m = MRC_UCHAR;
00956                 break;
00957         case EMUtil::EM_USHORT:
00958                 if (is_complex) {
00959                         m = MRC_SHORT_COMPLEX;
00960                 }
00961                 else {
00962                         m = MRC_USHORT;
00963                 }
00964                 break;
00965         case EMUtil::EM_SHORT:
00966                 if (is_complex) {
00967                         m = MRC_SHORT_COMPLEX;
00968                 }
00969                 else {
00970                         m = MRC_SHORT;
00971                 }
00972                 break;
00973         case EMUtil::EM_SHORT_COMPLEX:
00974         case EMUtil::EM_USHORT_COMPLEX:
00975                 m = MRC_SHORT_COMPLEX;
00976                 break;
00977         case EMUtil::EM_CHAR:
00978         case EMUtil::EM_INT:
00979         case EMUtil::EM_UINT:
00980         case EMUtil::EM_FLOAT:
00981                 if (is_complex) {
00982                         m = MRC_FLOAT_COMPLEX;
00983                 }
00984                 else {
00985                         m = MRC_FLOAT;
00986                 }
00987                 break;
00988         case EMUtil::EM_FLOAT_COMPLEX:
00989                 m = MRC_FLOAT_COMPLEX;
00990                 break;
00991         default:
00992                 m = MRC_FLOAT;
00993         }
00994 
00995         return m;
00996 }

void MrcIO::update_stat void *  data  )  [private]
 

This is a utility function used to calculate new min/max/mean/sigma when write MRC file as 16 bit or 8 bit.

It will write new set of min/max/mean/sigma to mrch. this function needs get the output data storage type from mrch.mode.

Definition at line 735 of file mrcio.cpp.

References EMAN::MrcIO::MrcHeader::amax, EMAN::MrcIO::MrcHeader::amean, EMAN::MrcIO::MrcHeader::amin, filename, ImageWriteException, InvalidCallException, max, min, EMAN::MrcIO::MrcHeader::mode, MRC_SHORT, mrcfile, mrch, EMAN::MrcIO::MrcHeader::nx, EMAN::MrcIO::MrcHeader::ny, EMAN::MrcIO::MrcHeader::nz, portable_fseek(), EMAN::MrcIO::MrcHeader::rms, sqrt(), and v.

00736 {
00737         size_t size =  mrch.nx * mrch.ny * mrch.nz;
00738         float v = 0.0f; //variable to hold pixel value
00739         double sum = 0.0;
00740         double square_sum = 0.0;
00741         double mean = 0.0;
00742         float min, max;
00743         
00744         unsigned char * cdata = 0;
00745         short * sdata = 0;
00746         unsigned short * usdata = 0;
00747         
00748         if (mrch.mode == MRC_UCHAR) {
00749                 max = 0.0f;
00750                 min = UCHAR_MAX;
00751                 cdata = (unsigned char *)data;
00752                 
00753                 for (size_t i = 0; i < size; ++i) {
00754                         v = (float)(cdata[i]);
00755 #ifdef _WIN32
00756                         max = _cpp_max(max,v);
00757                         min = _cpp_min(min,v);
00758 #else
00759                         max=std::max<float>(max,v);
00760                         min=std::min<float>(min,v);
00761 #endif  //_WIN32
00762                         
00763                         sum += v;
00764                         square_sum += v * v;
00765                 }
00766         }
00767         else if (mrch.mode == MRC_SHORT || mrch.mode == MRC_SHORT_COMPLEX) {
00768                 max = (float)SHRT_MIN;
00769                 min = (float)SHRT_MAX;
00770                 sdata = (short *)data;
00771                 
00772                 for (size_t i = 0; i < size; ++i) {
00773                         v = (float)(sdata[i]);
00774 #ifdef _WIN32
00775                         max = _cpp_max(max,v);
00776                         min = _cpp_min(min,v);
00777 #else
00778                         max=std::max<float>(max,v);
00779                         min=std::min<float>(min,v);
00780 #endif  //_WIN32
00781                         
00782                         sum += v;
00783                         square_sum += v * v;
00784                 }
00785         }
00786         else if (mrch.mode == MRC_USHORT) {
00787                 max = 0.0f;
00788                 min = (float)USHRT_MAX;
00789                 usdata = (unsigned short*)data;
00790                 
00791                 for (size_t i = 0; i < size; ++i) {
00792                         v = (float)(usdata[i]);
00793 #ifdef _WIN32
00794                         max = _cpp_max(max,v);
00795                         min = _cpp_min(min,v);
00796 #else
00797                         max=std::max<float>(max,v);
00798                         min=std::min<float>(min,v);
00799 #endif  //_WIN32
00800                         
00801                         sum += v;
00802                         square_sum += v * v;
00803                 }
00804         }
00805         else {
00806                 throw InvalidCallException("This function is used to write 8bit/16bit mrc file only.");
00807         }
00808         
00809         mean = sum/size;
00810 #ifdef _WIN32
00811         float sigma = (float)std::sqrt( _cpp_max(0.0,(square_sum - sum*sum / size)/(size-1)));
00812 #else
00813         float sigma = (float)std::sqrt(std::max<float>(0.0,(square_sum - sum*sum / size)/(size-1)));
00814 #endif  //_WIN32
00815 
00816         /*change mrch.amin/amax/amean.rms here*/
00817         mrch.amin = min;
00818         mrch.amax = max;
00819         mrch.amean = (float)mean;
00820         mrch.rms = sigma;
00821         
00822         MrcHeader mrch2 = mrch;
00823 
00824 //endian issue, can't get use_host_endian argument
00825 //      bool opposite_endian = false;
00826 
00827 //      if (!is_new_file) {
00828 //              if (is_big_endian != ByteOrder::is_host_big_endian()) {
00829 //                      opposite_endian = true;
00830 //              }
00831 //
00832 //              portable_fseek(mrcfile, 0, SEEK_SET);
00833 //      }
00834 //      
00835 //      if (opposite_endian || !use_host_endian) {
00836 //              swap_header(mrch2);
00837 //      }
00838 
00839         portable_fseek(mrcfile, 0, SEEK_SET);
00840         
00841         if (fwrite(&mrch2, sizeof(MrcHeader), 1, mrcfile) != 1) {
00842                 throw ImageWriteException(filename, "MRC header");
00843         }
00844         
00845         portable_fseek(mrcfile, sizeof(MrcHeader), SEEK_SET);
00846 }

void MrcIO::write_ctf const Ctf ctf,
int  image_index = 0
[virtual]
 

Write CTF data to this image.

Parameters:
ctf Ctf instance storing the CTF data.
image_index The index of the image to write.
Returns:
0 if OK; 1 if error.

Reimplemented from EMAN::ImageIO.

Definition at line 872 of file mrcio.cpp.

References CTF_MAGIC, filename, ImageWriteException, EMAN::ImageIO::init(), EMAN::MrcIO::MrcHeader::labels, mrcfile, mrch, and EMAN::Ctf::to_string().

00873 {
00874         ENTERFUNC;
00875         init();
00876 
00877         string ctf_str = ctf.to_string();
00878         sprintf(&mrch.labels[0][0], "%s%s", CTF_MAGIC, ctf_str.c_str());
00879         rewind(mrcfile);
00880 
00881         if (fwrite(&mrch, sizeof(MrcHeader), 1, mrcfile) != 1) {
00882                 throw ImageWriteException(filename, "write CTF info to header failed");
00883         }
00884         EXITFUNC;
00885 }


Member Data Documentation

const char * MrcIO::CTF_MAGIC = "!-" [static, private]
 

Definition at line 48 of file mrcio.cpp.

Referenced by read_ctf(), and write_ctf().

EMAN::MrcIO::DEFINE_IMAGEIO_FUNC
 

Definition at line 54 of file mrcio.h.

string EMAN::MrcIO::filename [private]
 

Definition at line 144 of file mrcio.h.

Referenced by update_stat(), and write_ctf().

bool EMAN::MrcIO::initialized [private]
 

Definition at line 153 of file mrcio.h.

Referenced by MrcIO().

bool EMAN::MrcIO::is_big_endian [private]
 

Definition at line 151 of file mrcio.h.

Referenced by MrcIO().

bool EMAN::MrcIO::is_new_file [private]
 

Definition at line 152 of file mrcio.h.

Referenced by MrcIO().

int EMAN::MrcIO::is_ri [private]
 

Definition at line 150 of file mrcio.h.

Referenced by MrcIO().

int EMAN::MrcIO::mode_size [private]
 

Definition at line 148 of file mrcio.h.

FILE* EMAN::MrcIO::mrcfile [private]
 

Definition at line 146 of file mrcio.h.

Referenced by update_stat(), write_ctf(), and ~MrcIO().

MrcHeader EMAN::MrcIO::mrch [private]
 

Definition at line 147 of file mrcio.h.

Referenced by MrcIO(), read_ctf(), update_stat(), and write_ctf().

IOMode EMAN::MrcIO::rw_mode [private]
 

Definition at line 145 of file mrcio.h.

const char * MrcIO::SHORT_CTF_MAGIC = "!$" [static, private]
 

Definition at line 49 of file mrcio.cpp.


The documentation for this class was generated from the following files:
Generated on Thu Dec 9 13:47:31 2010 for EMAN2 by  doxygen 1.3.9.1