EMAN2
Classes | Public Member Functions | Static Public Member Functions | Public Attributes | Protected Types | Protected Member Functions | Protected Attributes
EMAN::SpiderIO Class Reference

SPIDER: (System for Processing Image Data from Electron microscopy and Related fields) is an image processing system for electron microscopy. More...

#include <spiderio.h>

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

List of all members.

Classes

struct  SpiderHeader

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
SpiderHeaderfirst_h
SpiderHeadercur_h
bool is_big_endian
bool initialized
bool is_new_file

Detailed Description

SPIDER: (System for Processing Image Data from Electron microscopy and Related fields) is an image processing system for electron microscopy.

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.


Member Enumeration Documentation

anonymous enum [protected]
Enumerator:
SINGLE_IMAGE_HEADER 
OVERALL_STACK_HEADER 
NUM_FLOATS_IN_HEADER 

Definition at line 195 of file spiderio.h.

enum EMAN::SpiderIO::SpiderType [protected]
Enumerator:
IMAGE_2D 
IMAGE_3D 
IMAGE_2D_FFT_ODD 
IMAGE_2D_FFT_EVEN 
IMAGE_3D_FFT_ODD 
IMAGE_3D_FFT_EVEN 

Definition at line 185 of file spiderio.h.


Constructor & Destructor Documentation

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.

{
        if (spider_file) {
                fclose(spider_file);
                spider_file = 0;
        }

        if (first_h) {
                free(first_h);
                first_h = 0;
        }

        if (cur_h) {
                free(cur_h);
                cur_h = 0;
        }
}

Member Function Documentation

int SpiderIO::get_nimg ( ) [virtual]

get the number of images in this stacked SPIDER image

Returns:
the number of images

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.

{
        init();
        if (!first_h) {
                Assert(is_new_file);
                return 0;
        }
        else if (first_h->istack > 0) {                                         //image stack
                return static_cast < int >(first_h->maxim);
        }
        else if (first_h->istack == SINGLE_IMAGE_HEADER) {      //single 2D/3D image
                return 1;
        }
        else {                                                                                          //complex image
                throw ImageFormatException("complex spider image not supported.");
        }
}
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.

{ return false; }
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().

{
        ENTERFUNC;
        bool result = false;

        if (first_block) {
                const float *data = static_cast < const float *>(first_block);
                float nslice = data[0];
                float nrow = data[1];
                float iform = data[4];
                float nsam = data[11];
                float labrec = data[12];        //NO. of records in file header
                float labbyt = data[21];        //total NO. of bytes in header
                float lenbyt = data[22];        //record length in bytes
                float istack = data[23];

                bool big_endian = ByteOrder::is_float_big_endian(nslice);
                if (big_endian != ByteOrder::is_host_big_endian()) {
                        ByteOrder::swap_bytes(&nslice);
                        ByteOrder::swap_bytes(&nrow);
                        ByteOrder::swap_bytes(&iform);
                        ByteOrder::swap_bytes(&nsam);
                        ByteOrder::swap_bytes(&labrec);
                        ByteOrder::swap_bytes(&labbyt);
                        ByteOrder::swap_bytes(&lenbyt);
                        ByteOrder::swap_bytes(&istack);
                }

                if( int(nslice) != nslice || int(nrow) != nrow
                                || int(iform) != iform || int(nsam) != nsam
                                || int(labrec) != labrec || int(labbyt) != labbyt
                                || int(lenbyt) != lenbyt ) {
                        result =  false;
                }
                else {
                        //now we expect this header to be an overall header for SPIDER
                        if( int(istack) > 0 ) {
                                result = true; //istack>0 for overall header, istack<0 for indexed stack of image
                        }
                }

                int ilabrec = static_cast<int>(labrec);
                int ilabbyt = static_cast<int>(labbyt);
                int ilenbyt = static_cast<int>(lenbyt);
                if( ilabbyt != ilabrec * ilenbyt ) {
                        result = false;
                }
        }

        EXITFUNC;
        return result;
}
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

Parameters:
first_blockthe pointer to first block of the file
Returns:
boolean result of the check, true for valid stacked SPIDER image

Reimplemented in EMAN::SingleSpiderIO.

Definition at line 111 of file spiderio.cpp.

References is_valid().

{
        return SpiderIO::is_valid(first_block);
}
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().

{
        if (!is_new_file && (is_big_endian != ByteOrder::is_host_big_endian())) {
                return true;
        }
        return false;
}
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().

{
        if (data && need_swap()) {
                ByteOrder::swap_bytes(data, size);
        }
}
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().

{
        if (header && need_swap()) {
                ByteOrder::swap_bytes((float *) header, NUM_FLOATS_IN_HEADER);
        }
}
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

Parameters:
datathe data block to be written
areathe data region we want to write
hpthe SpiderHeader pointer all header info will write to
offsetthe offset in the spider_file
img_indexthe image index inthe stack, it's 0-indexed
max_nimgmax image number in a stack
use_host_endianuse host machine's endian, set to false will swap the byte order
Exceptions:
ImageWriteException
Returns:
0 for success

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

{
        ENTERFUNC;

        check_write_access(rw_mode, img_index, max_nimg, data);

        if (area) {
                check_region(area, FloatSize(hp->nsam, hp->nrow, hp->nslice), is_new_file);
        }

        if (!hp) {
                throw ImageWriteException(filename, "NULL image header");
        }

        portable_fseek(spider_file, offset, SEEK_SET);

        int size = (int)(hp->nsam * hp->nrow * hp->nslice);
        if(!use_host_endian) {
                ByteOrder::swap_bytes(data, size);
        }

        // remove the stuff in #if 0 ... #endif if the following works.
        EMUtil::process_region_io(data, spider_file, WRITE_ONLY,0, sizeof(float),
                                                          (int) hp->nsam, (int) hp->nrow,
                                                          (int) hp->nslice, area);

        EXITFUNC;
        return 0;
}
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

Parameters:
dictthe dictionary contain header information
areathe region we want to write
image_indexthe image index inthe stack, it's 0-indexed
offsetthe offset in the spider_file
hpthe SpiderHeader pointer all header info will write to, then the content of hp will write to spider file
ISTACKthe istack field for SPIDER's header, 0 for dingle image, 2 for stacked image
MAXIMmaxim field for header, only used for overall header
IMGNUMimgnum for header, only used for stacked image header
use_host_endianuse host machine's endian, set to false will swap the byte order
Exceptions:
ImageWriteException
Returns:
0 for sucess

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

{
        ENTERFUNC;

        check_write_access(rw_mode, image_index);

        if (area) {
                check_region(area, FloatSize(hp->nsam, hp->nrow, hp->nslice), is_new_file);
                EXITFUNC;
                return 0;
        }

        int nx = dict["nx"];
        int ny = dict["ny"];
        int nz = dict["nz"];

        size_t header_size = sizeof(SpiderHeader);
        size_t record_size = nx * sizeof(float);
    size_t num_records = (header_size % record_size) == 0 ? header_size / record_size : header_size / record_size + 1;
        size_t header_length = num_records * record_size;

        if (!hp) {
                hp = static_cast < SpiderHeader * >(calloc(1, header_size));
        }

        hp->angvalid = 0;
        hp->scale = 1.0;
        hp->istack = (float)ISTACK;
        hp->nslice = (float)nz;
        hp->nsam = (float)nx;
        hp->nrow = (float)ny;

        hp->max = dict["maximum"];
        hp->min = dict["minimum"];
        hp->mean = dict["mean"];
        hp->sigma = dict["sigma"];
        hp->mmvalid = 1;

        if(nz<=1 && dict.has_key("xform.projection")) {
                hp->angvalid = 1;
                Transform * t = dict["xform.projection"];
                Dict d = t->get_params("spider");
                hp->phi = d["phi"];
                hp->theta = d["theta"];
                hp->gamma = d["psi"];
                hp->dx = d["tx"];
                hp->dy = d["ty"];
                hp->dz = d["tz"];
                hp->scale = d["scale"];
                if(t) {delete t; t=0;}
        }
        else if(nz>1 && dict.has_key("xform.align3d")) {
                hp->angvalid = 1;
                Transform * t = dict["xform.align3d"];
                Dict d = t->get_params("spider");
                hp->phi = d["phi"];
                hp->theta = d["theta"];
                hp->gamma = d["psi"];
                hp->dx = d["tx"];
                hp->dy = d["ty"];
                hp->dz = d["tz"];
                hp->scale = d["scale"];
                if(t) {delete t; t=0;}
        }

        if(nz == 1) {
                hp->type = IMAGE_2D;
        }
        else {
                hp->type = IMAGE_3D;
        }

// complex image file not supported in EMAN2

        hp->reclen = (float)record_size;
        hp->headrec = (float)num_records;
        hp->headlen = (float)header_length;

        if(ISTACK == OVERALL_STACK_HEADER) {
                hp->maxim = (float)MAXIM;
        }
        hp->irec = (float)(num_records + ny*nz);

        hp->imgnum = (float)IMGNUM;

        time_t tod;
        time(&tod);
        struct tm * ttt = localtime(&tod);
        char ctime[9];
        char cdate[12];
        strftime(ctime, 9, "%H:%M:%S", ttt);
        std::copy(&ctime[0], &ctime[8], hp->time);
        strftime(cdate, 12, "%d-%b-%Y", ttt);
        std::copy(&cdate[0], &cdate[11], hp->date);

        if(dict.has_key("SPIDER.title")) {
                string title = static_cast<string>(dict["SPIDER.title"]);
                std::copy(&(title[0]), &(title[title.length()]), hp->title);
        }

        portable_fseek(spider_file, offset, SEEK_SET);

        if(use_host_endian) {
                if (fwrite(hp, header_size, 1, spider_file) != 1) {
                        throw ImageWriteException(filename, "write spider header failed");
                }
        }
        else {  //swap byte order
                SpiderHeader * hp2 = new SpiderHeader(*hp);
                ByteOrder::swap_bytes((float *) hp2, NUM_FLOATS_IN_HEADER);
                if (fwrite(hp2, header_size, 1, spider_file) != 1) {
                        throw ImageWriteException(filename, "write spider header failed");
                }
                if(hp2) {delete hp2; hp2=0;}
        }

        size_t pad_size = header_length - header_size;
        char *pad = static_cast < char *>(calloc(pad_size, 1));
        fwrite(pad, pad_size, 1, spider_file);
        if( pad )
        {
                free(pad);
                pad = 0;
        }

        EXITFUNC;
        return 0;
}

Member Data Documentation

Definition at line 250 of file spiderio.h.

Referenced by ~SpiderIO().

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

bool EMAN::SpiderIO::initialized [protected]

Definition at line 253 of file spiderio.h.

Definition at line 252 of file spiderio.h.

Referenced by need_swap().

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

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


The documentation for this class was generated from the following files: