#include <spiderio.h>
Inheritance diagram for EMAN::SpiderIO:
Public Member Functions | |
SpiderIO (const string &filename, IOMode rw_mode=READ_ONLY) | |
~SpiderIO () | |
bool | is_single_image_format () const |
Is this image format only storing 1 image or not. | |
int | get_nimg () |
get the number of images in this stacked SPIDER image | |
Static Public Member Functions | |
static bool | is_valid (const void *first_block) |
Public Attributes | |
DEFINE_IMAGEIO_FUNC | |
Protected Types | |
IMAGE_2D = 1 | |
IMAGE_3D = 3 | |
IMAGE_2D_FFT_ODD = -11 | |
IMAGE_2D_FFT_EVEN = -12 | |
IMAGE_3D_FFT_ODD = -21 | |
IMAGE_3D_FFT_EVEN = -22 | |
SINGLE_IMAGE_HEADER = 0 | |
OVERALL_STACK_HEADER = 2 | |
NUM_FLOATS_IN_HEADER = 211 | |
enum | SpiderType { IMAGE_2D = 1, IMAGE_3D = 3, IMAGE_2D_FFT_ODD = -11, IMAGE_2D_FFT_EVEN = -12, IMAGE_3D_FFT_ODD = -21, IMAGE_3D_FFT_EVEN = -22 } |
enum | { SINGLE_IMAGE_HEADER = 0, OVERALL_STACK_HEADER = 2, NUM_FLOATS_IN_HEADER = 211 } |
Protected Member Functions | |
int | write_single_header (const Dict &dict, const Region *area, int image_index, size_t offset, SpiderHeader *&hp, int ISTACK, int MAXIM=1, int IMGNUM=1, bool use_host_endian=true) |
write a SPIDER header to spider_file | |
int | write_single_data (float *data, const Region *area, SpiderHeader *&hp, size_t offset, int img_index, int max_nimg, bool use_host_endian=true) |
write a single image data | |
virtual bool | is_valid_spider (const void *first_block) |
check the data block to see if it represents valid stacked SPIDER image file header | |
bool | need_swap () const |
void | swap_data (float *data, size_t nitems) |
void | swap_header (SpiderHeader *header) |
Protected Attributes | |
string | filename |
IOMode | rw_mode |
FILE * | spider_file |
SpiderHeader * | first_h |
SpiderHeader * | cur_h |
bool | is_big_endian |
bool | initialized |
bool | is_new_file |
Classes | |
struct | SpiderHeader |
SpiderIO reads/writes images used in spider format. (reference: http://www.wadsworth.org/spider_doc/spider/docs/index.html)
A single image = header + data.
header-length = ( ceiling(1024/(nx*4)) * (nx*4) ) where nx is the number of pixels per row. The data is (nx * ny * nslice) of floating numbers, where ny is number of rows per slice. nslice is number of slices.
There are 2 spider image formats:
if there is only 1 image in the file, it can be overwritten by a different-size image.
Record: In spider terminology, each row is called a record.
Note: To read the overall image header in a stacked spider file, use image_index = -1.
Definition at line 75 of file spiderio.h.
anonymous enum [protected] |
Definition at line 195 of file spiderio.h.
00196 { 00197 SINGLE_IMAGE_HEADER = 0, 00198 OVERALL_STACK_HEADER = 2, 00199 NUM_FLOATS_IN_HEADER = 211 00200 };
enum EMAN::SpiderIO::SpiderType [protected] |
Definition at line 185 of file spiderio.h.
00186 { 00187 IMAGE_2D = 1, 00188 IMAGE_3D = 3, 00189 IMAGE_2D_FFT_ODD = -11, 00190 IMAGE_2D_FFT_EVEN = -12, 00191 IMAGE_3D_FFT_ODD = -21, 00192 IMAGE_3D_FFT_EVEN = -22 00193 };
SpiderIO::SpiderIO | ( | const string & | filename, | |
IOMode | rw_mode = READ_ONLY | |||
) | [explicit] |
Definition at line 48 of file spiderio.cpp.
References filename, EMAN::Util::is_file_exist(), and is_new_file.
00049 : filename(spider_filename), rw_mode(rw), 00050 spider_file(0), first_h(0), cur_h(0), 00051 is_big_endian(ByteOrder::is_host_big_endian()), 00052 initialized(false) 00053 { 00054 is_new_file = !Util::is_file_exist(filename); 00055 }
SpiderIO::~SpiderIO | ( | ) |
Definition at line 57 of file spiderio.cpp.
References cur_h, first_h, and spider_file.
00058 { 00059 if (spider_file) { 00060 fclose(spider_file); 00061 spider_file = 0; 00062 } 00063 00064 if (first_h) { 00065 free(first_h); 00066 first_h = 0; 00067 } 00068 00069 if (cur_h) { 00070 free(cur_h); 00071 cur_h = 0; 00072 } 00073 }
int SpiderIO::get_nimg | ( | ) | [virtual] |
get the number of images in this stacked SPIDER image
Reimplemented from EMAN::ImageIO.
Definition at line 683 of file spiderio.cpp.
References Assert, first_h, ImageFormatException, EMAN::ImageIO::init(), is_new_file, EMAN::SpiderIO::SpiderHeader::istack, EMAN::SpiderIO::SpiderHeader::maxim, and SINGLE_IMAGE_HEADER.
00684 { 00685 init(); 00686 if (!first_h) { 00687 Assert(is_new_file); 00688 return 0; 00689 } 00690 else if (first_h->istack > 0) { //image stack 00691 return static_cast < int >(first_h->maxim); 00692 } 00693 else if (first_h->istack == SINGLE_IMAGE_HEADER) { //single 2D/3D image 00694 return 1; 00695 } 00696 else { //complex image 00697 throw ImageFormatException("complex spider image not supported."); 00698 } 00699 }
bool EMAN::SpiderIO::is_single_image_format | ( | ) | const [inline, virtual] |
Is this image format only storing 1 image or not.
Some image formats like MRC only store 1 image in a file, so this function returns 'true' for them. Other image formats like IMAGIC/HDF5 may store mutliple images, so this function returns 'false' for them.
Reimplemented from EMAN::ImageIO.
Reimplemented in EMAN::SingleSpiderIO.
Definition at line 84 of file spiderio.h.
bool SpiderIO::is_valid | ( | const void * | first_block | ) | [static] |
Reimplemented in EMAN::SingleSpiderIO.
Definition at line 116 of file spiderio.cpp.
References data, ENTERFUNC, EXITFUNC, EMAN::ByteOrder::is_float_big_endian(), EMAN::ByteOrder::is_host_big_endian(), and EMAN::ByteOrder::swap_bytes().
Referenced by EMAN::EMUtil::fast_get_image_type(), EMAN::EMUtil::get_image_type(), and is_valid_spider().
00117 { 00118 ENTERFUNC; 00119 bool result = false; 00120 00121 if (first_block) { 00122 const float *data = static_cast < const float *>(first_block); 00123 float nslice = data[0]; 00124 float nrow = data[1]; 00125 float iform = data[4]; 00126 float nsam = data[11]; 00127 float labrec = data[12]; //NO. of records in file header 00128 float labbyt = data[21]; //total NO. of bytes in header 00129 float lenbyt = data[22]; //record length in bytes 00130 float istack = data[23]; 00131 00132 bool big_endian = ByteOrder::is_float_big_endian(nslice); 00133 if (big_endian != ByteOrder::is_host_big_endian()) { 00134 ByteOrder::swap_bytes(&nslice); 00135 ByteOrder::swap_bytes(&nrow); 00136 ByteOrder::swap_bytes(&iform); 00137 ByteOrder::swap_bytes(&nsam); 00138 ByteOrder::swap_bytes(&labrec); 00139 ByteOrder::swap_bytes(&labbyt); 00140 ByteOrder::swap_bytes(&lenbyt); 00141 ByteOrder::swap_bytes(&istack); 00142 } 00143 00144 if( int(nslice) != nslice || int(nrow) != nrow 00145 || int(iform) != iform || int(nsam) != nsam 00146 || int(labrec) != labrec || int(labbyt) != labbyt 00147 || int(lenbyt) != lenbyt ) { 00148 result = false; 00149 } 00150 else { 00151 //now we expect this header to be an overall header for SPIDER 00152 if( int(istack) > 0 ) { 00153 result = true; //istack>0 for overall header, istack<0 for indexed stack of image 00154 } 00155 } 00156 00157 int ilabrec = static_cast<int>(labrec); 00158 int ilabbyt = static_cast<int>(labbyt); 00159 int ilenbyt = static_cast<int>(lenbyt); 00160 if( ilabbyt != ilabrec * ilenbyt ) { 00161 result = false; 00162 } 00163 } 00164 00165 EXITFUNC; 00166 return result; 00167 }
bool SpiderIO::is_valid_spider | ( | const void * | first_block | ) | [protected, virtual] |
check the data block to see if it represents valid stacked SPIDER image file header
first_block | the pointer to first block of the file |
Reimplemented in EMAN::SingleSpiderIO.
Definition at line 111 of file spiderio.cpp.
References is_valid().
00112 { 00113 return SpiderIO::is_valid(first_block); 00114 }
bool SpiderIO::need_swap | ( | ) | const [protected] |
Definition at line 701 of file spiderio.cpp.
References is_big_endian, EMAN::ByteOrder::is_host_big_endian(), and is_new_file.
Referenced by swap_data(), and swap_header().
00702 { 00703 if (!is_new_file && (is_big_endian != ByteOrder::is_host_big_endian())) { 00704 return true; 00705 } 00706 return false; 00707 }
void SpiderIO::swap_data | ( | float * | data, | |
size_t | nitems | |||
) | [protected] |
Definition at line 652 of file spiderio.cpp.
References need_swap(), and EMAN::ByteOrder::swap_bytes().
00653 { 00654 if (data && need_swap()) { 00655 ByteOrder::swap_bytes(data, size); 00656 } 00657 }
void SpiderIO::swap_header | ( | SpiderHeader * | header | ) | [protected] |
Definition at line 659 of file spiderio.cpp.
References need_swap(), NUM_FLOATS_IN_HEADER, and EMAN::ByteOrder::swap_bytes().
00660 { 00661 if (header && need_swap()) { 00662 ByteOrder::swap_bytes((float *) header, NUM_FLOATS_IN_HEADER); 00663 } 00664 }
int SpiderIO::write_single_data | ( | float * | data, | |
const Region * | area, | |||
SpiderHeader *& | hp, | |||
size_t | offset, | |||
int | img_index, | |||
int | max_nimg, | |||
bool | use_host_endian = true | |||
) | [protected] |
write a single image data
data | the data block to be written | |
area | the data region we want to write | |
hp | the SpiderHeader pointer all header info will write to | |
offset | the offset in the spider_file | |
img_index | the image index inthe stack, it's 0-indexed | |
max_nimg | max image number in a stack | |
use_host_endian | use host machine's endian, set to false will swap the byte order |
ImageWriteException |
Definition at line 621 of file spiderio.cpp.
References EMAN::ImageIO::check_region(), EMAN::ImageIO::check_write_access(), ENTERFUNC, EXITFUNC, filename, ImageWriteException, is_new_file, EMAN::SpiderIO::SpiderHeader::nrow, EMAN::SpiderIO::SpiderHeader::nsam, EMAN::SpiderIO::SpiderHeader::nslice, portable_fseek(), EMAN::EMUtil::process_region_io(), rw_mode, spider_file, EMAN::ByteOrder::swap_bytes(), and EMAN::ImageIO::WRITE_ONLY.
Referenced by EMAN::SingleSpiderIO::write_data().
00623 { 00624 ENTERFUNC; 00625 00626 check_write_access(rw_mode, img_index, max_nimg, data); 00627 00628 if (area) { 00629 check_region(area, FloatSize(hp->nsam, hp->nrow, hp->nslice), is_new_file); 00630 } 00631 00632 if (!hp) { 00633 throw ImageWriteException(filename, "NULL image header"); 00634 } 00635 00636 portable_fseek(spider_file, offset, SEEK_SET); 00637 00638 int size = (int)(hp->nsam * hp->nrow * hp->nslice); 00639 if(!use_host_endian) { 00640 ByteOrder::swap_bytes(data, size); 00641 } 00642 00643 // remove the stuff in #if 0 ... #endif if the following works. 00644 EMUtil::process_region_io(data, spider_file, WRITE_ONLY,0, sizeof(float), 00645 (int) hp->nsam, (int) hp->nrow, 00646 (int) hp->nslice, area); 00647 00648 EXITFUNC; 00649 return 0; 00650 }
int SpiderIO::write_single_header | ( | const Dict & | dict, | |
const Region * | area, | |||
int | image_index, | |||
size_t | offset, | |||
SpiderHeader *& | hp, | |||
int | ISTACK, | |||
int | MAXIM = 1 , |
|||
int | IMGNUM = 1 , |
|||
bool | use_host_endian = true | |||
) | [protected] |
write a SPIDER header to spider_file
dict | the dictionary contain header information | |
area | the region we want to write | |
image_index | the image index inthe stack, it's 0-indexed | |
offset | the offset in the spider_file | |
hp | the SpiderHeader pointer all header info will write to, then the content of hp will write to spider file | |
ISTACK | the istack field for SPIDER's header, 0 for dingle image, 2 for stacked image | |
MAXIM | maxim field for header, only used for overall header | |
IMGNUM | imgnum for header, only used for stacked image header | |
use_host_endian | use host machine's endian, set to false will swap the byte order |
ImageWriteException |
Definition at line 405 of file spiderio.cpp.
References EMAN::SpiderIO::SpiderHeader::angvalid, EMAN::ImageIO::check_region(), EMAN::ImageIO::check_write_access(), copy(), EMAN::SpiderIO::SpiderHeader::date, EMAN::SpiderIO::SpiderHeader::dx, EMAN::SpiderIO::SpiderHeader::dy, EMAN::SpiderIO::SpiderHeader::dz, ENTERFUNC, EXITFUNC, filename, EMAN::SpiderIO::SpiderHeader::gamma, EMAN::Dict::has_key(), EMAN::SpiderIO::SpiderHeader::headlen, EMAN::SpiderIO::SpiderHeader::headrec, IMAGE_2D, IMAGE_3D, ImageWriteException, EMAN::SpiderIO::SpiderHeader::imgnum, EMAN::SpiderIO::SpiderHeader::irec, is_new_file, EMAN::SpiderIO::SpiderHeader::istack, EMAN::SpiderIO::SpiderHeader::max, EMAN::SpiderIO::SpiderHeader::maxim, EMAN::SpiderIO::SpiderHeader::mean, EMAN::SpiderIO::SpiderHeader::min, EMAN::SpiderIO::SpiderHeader::mmvalid, EMAN::SpiderIO::SpiderHeader::nrow, EMAN::SpiderIO::SpiderHeader::nsam, EMAN::SpiderIO::SpiderHeader::nslice, NUM_FLOATS_IN_HEADER, nx, ny, OVERALL_STACK_HEADER, pad(), EMAN::SpiderIO::SpiderHeader::phi, portable_fseek(), EMAN::SpiderIO::SpiderHeader::reclen, rw_mode, EMAN::SpiderIO::SpiderHeader::scale, EMAN::SpiderIO::SpiderHeader::sigma, spider_file, EMAN::ByteOrder::swap_bytes(), t, EMAN::SpiderIO::SpiderHeader::theta, EMAN::SpiderIO::SpiderHeader::time, EMAN::SpiderIO::SpiderHeader::title, and EMAN::SpiderIO::SpiderHeader::type.
Referenced by EMAN::SingleSpiderIO::write_header().
00407 { 00408 ENTERFUNC; 00409 00410 check_write_access(rw_mode, image_index); 00411 00412 if (area) { 00413 check_region(area, FloatSize(hp->nsam, hp->nrow, hp->nslice), is_new_file); 00414 EXITFUNC; 00415 return 0; 00416 } 00417 00418 int nx = dict["nx"]; 00419 int ny = dict["ny"]; 00420 int nz = dict["nz"]; 00421 00422 size_t header_size = sizeof(SpiderHeader); 00423 size_t record_size = nx * sizeof(float); 00424 size_t num_records = (header_size % record_size) == 0 ? header_size / record_size : header_size / record_size + 1; 00425 size_t header_length = num_records * record_size; 00426 00427 if (!hp) { 00428 hp = static_cast < SpiderHeader * >(calloc(1, header_size)); 00429 } 00430 00431 hp->angvalid = 0; 00432 hp->scale = 1.0; 00433 hp->istack = (float)ISTACK; 00434 hp->nslice = (float)nz; 00435 hp->nsam = (float)nx; 00436 hp->nrow = (float)ny; 00437 00438 hp->max = dict["maximum"]; 00439 hp->min = dict["minimum"]; 00440 hp->mean = dict["mean"]; 00441 hp->sigma = dict["sigma"]; 00442 hp->mmvalid = 1; 00443 00444 if(nz<=1 && dict.has_key("xform.projection")) { 00445 hp->angvalid = 1; 00446 Transform * t = dict["xform.projection"]; 00447 Dict d = t->get_params("spider"); 00448 hp->phi = d["phi"]; 00449 hp->theta = d["theta"]; 00450 hp->gamma = d["psi"]; 00451 hp->dx = d["tx"]; 00452 hp->dy = d["ty"]; 00453 hp->dz = d["tz"]; 00454 hp->scale = d["scale"]; 00455 if(t) {delete t; t=0;} 00456 } 00457 else if(nz>1 && dict.has_key("xform.align3d")) { 00458 hp->angvalid = 1; 00459 Transform * t = dict["xform.align3d"]; 00460 Dict d = t->get_params("spider"); 00461 hp->phi = d["phi"]; 00462 hp->theta = d["theta"]; 00463 hp->gamma = d["psi"]; 00464 hp->dx = d["tx"]; 00465 hp->dy = d["ty"]; 00466 hp->dz = d["tz"]; 00467 hp->scale = d["scale"]; 00468 if(t) {delete t; t=0;} 00469 } 00470 00471 if(nz == 1) { 00472 hp->type = IMAGE_2D; 00473 } 00474 else { 00475 hp->type = IMAGE_3D; 00476 } 00477 00478 // complex image file not supported in EMAN2 00479 00480 hp->reclen = (float)record_size; 00481 hp->headrec = (float)num_records; 00482 hp->headlen = (float)header_length; 00483 00484 if(ISTACK == OVERALL_STACK_HEADER) { 00485 hp->maxim = (float)MAXIM; 00486 } 00487 hp->irec = (float)(num_records + ny*nz); 00488 00489 hp->imgnum = (float)IMGNUM; 00490 00491 time_t tod; 00492 time(&tod); 00493 struct tm * ttt = localtime(&tod); 00494 char ctime[9]; 00495 char cdate[12]; 00496 strftime(ctime, 9, "%H:%M:%S", ttt); 00497 std::copy(&ctime[0], &ctime[8], hp->time); 00498 strftime(cdate, 12, "%d-%b-%Y", ttt); 00499 std::copy(&cdate[0], &cdate[11], hp->date); 00500 00501 if(dict.has_key("SPIDER.title")) { 00502 string title = static_cast<string>(dict["SPIDER.title"]); 00503 std::copy(&(title[0]), &(title[title.length()]), hp->title); 00504 } 00505 00506 portable_fseek(spider_file, offset, SEEK_SET); 00507 00508 if(use_host_endian) { 00509 if (fwrite(hp, header_size, 1, spider_file) != 1) { 00510 throw ImageWriteException(filename, "write spider header failed"); 00511 } 00512 } 00513 else { //swap byte order 00514 SpiderHeader * hp2 = new SpiderHeader(*hp); 00515 ByteOrder::swap_bytes((float *) hp2, NUM_FLOATS_IN_HEADER); 00516 if (fwrite(hp2, header_size, 1, spider_file) != 1) { 00517 throw ImageWriteException(filename, "write spider header failed"); 00518 } 00519 if(hp2) {delete hp2; hp2=0;} 00520 } 00521 00522 size_t pad_size = header_length - header_size; 00523 char *pad = static_cast < char *>(calloc(pad_size, 1)); 00524 fwrite(pad, pad_size, 1, spider_file); 00525 if( pad ) 00526 { 00527 free(pad); 00528 pad = 0; 00529 } 00530 00531 EXITFUNC; 00532 return 0; 00533 }
SpiderHeader* EMAN::SpiderIO::cur_h [protected] |
Definition at line 81 of file spiderio.h.
string EMAN::SpiderIO::filename [protected] |
Definition at line 245 of file spiderio.h.
Referenced by SpiderIO(), write_single_data(), and write_single_header().
SpiderHeader* EMAN::SpiderIO::first_h [protected] |
Definition at line 249 of file spiderio.h.
Referenced by get_nimg(), EMAN::SingleSpiderIO::write_data(), EMAN::SingleSpiderIO::write_header(), and ~SpiderIO().
bool EMAN::SpiderIO::initialized [protected] |
Definition at line 253 of file spiderio.h.
bool EMAN::SpiderIO::is_big_endian [protected] |
bool EMAN::SpiderIO::is_new_file [protected] |
Definition at line 254 of file spiderio.h.
Referenced by get_nimg(), need_swap(), SpiderIO(), write_single_data(), and write_single_header().
IOMode EMAN::SpiderIO::rw_mode [protected] |
Definition at line 246 of file spiderio.h.
Referenced by write_single_data(), and write_single_header().
FILE* EMAN::SpiderIO::spider_file [protected] |
Definition at line 248 of file spiderio.h.
Referenced by write_single_data(), write_single_header(), and ~SpiderIO().