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

static bool is_valid (const void *first_block, off_t file_size=0)
static int get_mode_size (int mm)
static int to_em_datatype (int mrcmode)
static 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

static 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

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

Classes

struct  MrcHeader

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]
 

Enumerator:
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]
 

Enumerator:
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.

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 998 of file mrcio.cpp.

References EMAN::ByteOrder::is_host_big_endian().

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

int MrcIO::get_mode_size int  mm  )  [static]
 

Definition at line 891 of file mrcio.cpp.

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

Referenced by is_valid().

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

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

Definition at line 130 of file mrcio.cpp.

References data, ENTERFUNC, EXITFUNC, get_mode_size(), EMAN::ByteOrder::is_data_big_endian(), EMAN::ByteOrder::is_host_big_endian(), MRC_FLOAT_COMPLEX, MRC_SHORT_COMPLEX, MRC_UCHAR, MRC_UNKNOWN, 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         }
00153 
00154         if (mrcmode == MRC_SHORT_COMPLEX || mrcmode == MRC_FLOAT_COMPLEX) {
00155                 nx *= 2;
00156         }
00157 
00158         const int max_dim = 1 << 20;
00159 
00160         if ((mrcmode >= MRC_UCHAR && mrcmode < MRC_UNKNOWN) &&
00161                 (nx > 1 && nx < max_dim) && (ny > 0 && ny < max_dim) && (nz > 0 && nz < max_dim)) {
00162 #ifndef SPIDERMRC // Spider MRC files don't satisfy the following test
00163                 if (file_size > 0) {
00164                         off_t file_size1 = (off_t)nx * (off_t)ny * (off_t)nz * (off_t)get_mode_size(mrcmode) + (off_t)sizeof(MrcHeader) + nsymbt;
00165                         if (file_size == file_size1) {
00166                                 return true;
00167                         }
00168                         return false;
00169                 }
00170                 else {
00171                         return true;
00172                 }
00173 #endif // SPIDERMRC
00174                 return true;
00175         }
00176         EXITFUNC;
00177         return false;
00178 }

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 856 of file mrcio.cpp.

References CTF_MAGIC, ENTERFUNC, EXITFUNC, EMAN::Ctf::from_string(), and EMAN::ImageIO::init().

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

void MrcIO::swap_header MrcHeader mrch  )  [private]
 

Definition at line 1018 of file mrcio.cpp.

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

int MrcIO::to_em_datatype int  mrcmode  )  [static]
 

Definition at line 916 of file mrcio.cpp.

References EMAN::EMUtil::EM_FLOAT, EMAN::EMUtil::EM_FLOAT_COMPLEX, EMAN::EMUtil::EM_SHORT, EMAN::EMUtil::EM_SHORT_COMPLEX, EMAN::EMUtil::EM_UCHAR, EMAN::EMUtil::EM_UNKNOWN, EMAN::EMUtil::EM_USHORT, MRC_FLOAT, MRC_FLOAT_COMPLEX, MRC_SHORT, MRC_SHORT_COMPLEX, MRC_UCHAR, and MRC_USHORT.

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

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

Definition at line 946 of file mrcio.cpp.

References EMAN::EMUtil::EM_CHAR, EMAN::EMUtil::EM_FLOAT, EMAN::EMUtil::EM_FLOAT_COMPLEX, EMAN::EMUtil::EM_INT, EMAN::EMUtil::EM_SHORT, EMAN::EMUtil::EM_SHORT_COMPLEX, EMAN::EMUtil::EM_UCHAR, EMAN::EMUtil::EM_UINT, EMAN::EMUtil::EM_USHORT, EMAN::EMUtil::EM_USHORT_COMPLEX, MRC_FLOAT, MRC_FLOAT_COMPLEX, MRC_SHORT, MRC_SHORT_COMPLEX, MRC_UCHAR, MRC_UNKNOWN, and MRC_USHORT.

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

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 733 of file mrcio.cpp.

References filename, ImageWriteException, InvalidCallException, max, min, MRC_SHORT, MRC_SHORT_COMPLEX, MRC_UCHAR, MRC_USHORT, mrcfile, portable_fseek(), sqrt(), and v.

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

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 870 of file mrcio.cpp.

References CTF_MAGIC, ENTERFUNC, EXITFUNC, filename, ImageWriteException, EMAN::ImageIO::init(), mrcfile, and EMAN::Ctf::to_string().

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


Member Data Documentation

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

Definition at line 139 of file mrcio.h.

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().

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 140 of file mrcio.h.


The documentation for this class was generated from the following files:
Generated on Mon Jul 19 13:06:13 2010 for EMAN2 by  doxygen 1.4.4