#include <mrcio.h>
Inheritance diagram for EMAN::MrcIO:
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 |
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.
|
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 };
|
|
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 };
|
|
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 }
|
|
Definition at line 61 of file mrcio.cpp. References mrcfile.
|
|
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 }
|
|
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 }
|
|
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 }
|
|
Read CTF data from this image.
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 }
|
|
Definition at line 1018 of file mrcio.cpp. References NUM_4BYTES_AFTER_MAP, NUM_4BYTES_PRE_MAP, and EMAN::ByteOrder::swap_bytes(). 01019 { 01020 ByteOrder::swap_bytes((int *) &mrch, NUM_4BYTES_PRE_MAP); 01021 ByteOrder::swap_bytes((int *) &mrch.machinestamp, NUM_4BYTES_AFTER_MAP); 01022 }
|
|
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 }
|
|
|
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 }
|
|
Write CTF data to this image.
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 }
|
|
Definition at line 139 of file mrcio.h. Referenced by read_ctf(), and write_ctf(). |
|
|
|
Definition at line 144 of file mrcio.h. Referenced by update_stat(), and write_ctf(). |
|
Definition at line 153 of file mrcio.h. Referenced by MrcIO(). |
|
Definition at line 151 of file mrcio.h. Referenced by MrcIO(). |
|
Definition at line 152 of file mrcio.h. Referenced by MrcIO(). |
|
Definition at line 150 of file mrcio.h. Referenced by MrcIO(). |
|
|
|
Definition at line 146 of file mrcio.h. Referenced by update_stat(), write_ctf(), and ~MrcIO(). |
|
Definition at line 147 of file mrcio.h. Referenced by MrcIO(). |
|
|
|
|