#include <spiderio.h>


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 | |
| 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.
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 };
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 };
| EMAN::SpiderIO::SpiderIO | ( | const string & | filename, | |
| IOMode | rw_mode = READ_ONLY | |||
| ) | [explicit] |
| 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 }
| 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 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.
| int SpiderIO::get_nimg | ( | ) | [virtual] |
get the number of images in this stacked SPIDER image
Reimplemented from EMAN::ImageIO.
Definition at line 679 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.
00680 { 00681 init(); 00682 if (!first_h) { 00683 Assert(is_new_file); 00684 return 0; 00685 } 00686 else if (first_h->istack > 0) { //image stack 00687 return static_cast < int >(first_h->maxim); 00688 } 00689 else if (first_h->istack == SINGLE_IMAGE_HEADER) { //single 2D/3D image 00690 return 1; 00691 } 00692 else { //complex image 00693 throw ImageFormatException("complex spider image not supported."); 00694 } 00695 }
| 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 401 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::Transform::get_params(), 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().
00403 { 00404 ENTERFUNC; 00405 00406 check_write_access(rw_mode, image_index); 00407 00408 if (area) { 00409 check_region(area, FloatSize(hp->nsam, hp->nrow, hp->nslice), is_new_file); 00410 EXITFUNC; 00411 return 0; 00412 } 00413 00414 int nx = dict["nx"]; 00415 int ny = dict["ny"]; 00416 int nz = dict["nz"]; 00417 00418 size_t header_size = sizeof(SpiderHeader); 00419 size_t record_size = nx * sizeof(float); 00420 size_t num_records = (header_size % record_size) == 0 ? header_size / record_size : header_size / record_size + 1; 00421 size_t header_length = num_records * record_size; 00422 00423 if (!hp) { 00424 hp = static_cast < SpiderHeader * >(calloc(1, header_size)); 00425 } 00426 00427 hp->angvalid = 0; 00428 hp->scale = 1.0; 00429 hp->istack = (float)ISTACK; 00430 hp->nslice = (float)nz; 00431 hp->nsam = (float)nx; 00432 hp->nrow = (float)ny; 00433 00434 hp->max = dict["maximum"]; 00435 hp->min = dict["minimum"]; 00436 hp->mean = dict["mean"]; 00437 hp->sigma = dict["sigma"]; 00438 hp->mmvalid = 1; 00439 00440 if(nz<=1 && dict.has_key("xform.projection")) { 00441 hp->angvalid = 1; 00442 Transform * t = dict["xform.projection"]; 00443 Dict d = t->get_params("spider"); 00444 hp->phi = d["phi"]; 00445 hp->theta = d["theta"]; 00446 hp->gamma = d["psi"]; 00447 hp->dx = d["tx"]; 00448 hp->dy = d["ty"]; 00449 hp->dz = d["tz"]; 00450 hp->scale = d["scale"]; 00451 if(t) {delete t; t=0;} 00452 } 00453 else if(nz>1 && dict.has_key("xform.align3d")) { 00454 hp->angvalid = 1; 00455 Transform * t = dict["xform.align3d"]; 00456 Dict d = t->get_params("spider"); 00457 hp->phi = d["phi"]; 00458 hp->theta = d["theta"]; 00459 hp->gamma = d["psi"]; 00460 hp->dx = d["tx"]; 00461 hp->dy = d["ty"]; 00462 hp->dz = d["tz"]; 00463 hp->scale = d["scale"]; 00464 if(t) {delete t; t=0;} 00465 } 00466 00467 if(nz == 1) { 00468 hp->type = IMAGE_2D; 00469 } 00470 else { 00471 hp->type = IMAGE_3D; 00472 } 00473 00474 // complex image file not supported in EMAN2 00475 00476 hp->reclen = (float)record_size; 00477 hp->headrec = (float)num_records; 00478 hp->headlen = (float)header_length; 00479 00480 if(ISTACK == OVERALL_STACK_HEADER) { 00481 hp->maxim = (float)MAXIM; 00482 } 00483 hp->irec = (float)(num_records + ny*nz); 00484 00485 hp->imgnum = (float)IMGNUM; 00486 00487 time_t tod; 00488 time(&tod); 00489 struct tm * ttt = localtime(&tod); 00490 char ctime[9]; 00491 char cdate[12]; 00492 strftime(ctime, 9, "%H:%M:%S", ttt); 00493 std::copy(&ctime[0], &ctime[8], hp->time); 00494 strftime(cdate, 12, "%d-%b-%Y", ttt); 00495 std::copy(&cdate[0], &cdate[11], hp->date); 00496 00497 if(dict.has_key("SPIDER.title")) { 00498 string title = static_cast<string>(dict["SPIDER.title"]); 00499 std::copy(&(title[0]), &(title[title.length()]), hp->title); 00500 } 00501 00502 portable_fseek(spider_file, offset, SEEK_SET); 00503 00504 if(use_host_endian) { 00505 if (fwrite(hp, header_size, 1, spider_file) != 1) { 00506 throw ImageWriteException(filename, "write spider header failed"); 00507 } 00508 } 00509 else { //swap byte order 00510 SpiderHeader * hp2 = new SpiderHeader(*hp); 00511 ByteOrder::swap_bytes((float *) hp2, NUM_FLOATS_IN_HEADER); 00512 if (fwrite(hp2, header_size, 1, spider_file) != 1) { 00513 throw ImageWriteException(filename, "write spider header failed"); 00514 } 00515 if(hp2) {delete hp2; hp2=0;} 00516 } 00517 00518 size_t pad_size = header_length - header_size; 00519 char *pad = static_cast < char *>(calloc(pad_size, 1)); 00520 fwrite(pad, pad_size, 1, spider_file); 00521 if( pad ) 00522 { 00523 free(pad); 00524 pad = 0; 00525 } 00526 00527 EXITFUNC; 00528 return 0; 00529 }
| 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 617 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().
00619 { 00620 ENTERFUNC; 00621 00622 check_write_access(rw_mode, img_index, max_nimg, data); 00623 00624 if (area) { 00625 check_region(area, FloatSize(hp->nsam, hp->nrow, hp->nslice), is_new_file); 00626 } 00627 00628 if (!hp) { 00629 throw ImageWriteException(filename, "NULL image header"); 00630 } 00631 00632 portable_fseek(spider_file, offset, SEEK_SET); 00633 00634 int size = (int)(hp->nsam * hp->nrow * hp->nslice); 00635 if(!use_host_endian) { 00636 ByteOrder::swap_bytes(data, size); 00637 } 00638 00639 // remove the stuff in #if 0 ... #endif if the following works. 00640 EMUtil::process_region_io(data, spider_file, WRITE_ONLY,0, sizeof(float), 00641 (int) hp->nsam, (int) hp->nrow, 00642 (int) hp->nslice, area); 00643 00644 EXITFUNC; 00645 return 0; 00646 }
| 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 697 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().
00698 { 00699 if (!is_new_file && (is_big_endian != ByteOrder::is_host_big_endian())) { 00700 return true; 00701 } 00702 return false; 00703 }
| void SpiderIO::swap_data | ( | float * | data, | |
| size_t | nitems | |||
| ) | [protected] |
Definition at line 648 of file spiderio.cpp.
References need_swap(), and EMAN::ByteOrder::swap_bytes().
00649 { 00650 if (data && need_swap()) { 00651 ByteOrder::swap_bytes(data, size); 00652 } 00653 }
| void SpiderIO::swap_header | ( | SpiderHeader * | header | ) | [protected] |
Definition at line 655 of file spiderio.cpp.
References need_swap(), NUM_FLOATS_IN_HEADER, and EMAN::ByteOrder::swap_bytes().
00656 { 00657 if (header && need_swap()) { 00658 ByteOrder::swap_bytes((float *) header, NUM_FLOATS_IN_HEADER); 00659 } 00660 }
Definition at line 81 of file spiderio.h.
string EMAN::SpiderIO::filename [protected] |
Definition at line 245 of file spiderio.h.
Referenced by 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().
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().
SpiderHeader* EMAN::SpiderIO::cur_h [protected] |
bool EMAN::SpiderIO::is_big_endian [protected] |
bool EMAN::SpiderIO::initialized [protected] |
Definition at line 253 of file spiderio.h.
bool EMAN::SpiderIO::is_new_file [protected] |
Definition at line 254 of file spiderio.h.
Referenced by get_nimg(), need_swap(), write_single_data(), and write_single_header().
1.5.6