44SpiderIO::SpiderIO(
const string & fname,
IOMode rw)
47 is_big_endian(
ByteOrder::is_host_big_endian())
80 first_h =
static_cast < SpiderHeader *
>(calloc(1,
sizeof(SpiderHeader)));
82 if (fread(
first_h,
sizeof(SpiderHeader), 1,
file) != 1) {
117 const float *data =
static_cast < const float *
>(first_block);
118 float nslice = data[0];
119 float nrow = data[1];
120 float iform = data[4];
121 float nsam = data[11];
122 float labrec = data[12];
123 float labbyt = data[21];
124 float lenbyt = data[22];
125 float istack = data[23];
139 if(
int(nslice) != nslice ||
int(nrow) != nrow
140 ||
int(iform) != iform ||
int(nsam) != nsam
141 ||
int(labrec) != labrec ||
int(labbyt) != labbyt
142 ||
int(lenbyt) != lenbyt ) {
147 if(
int(istack) > 0 ) {
152 int ilabrec =
static_cast<int>(labrec);
153 int ilabbyt =
static_cast<int>(labbyt);
154 int ilenbyt =
static_cast<int>(lenbyt);
155 if( ilabbyt != ilabrec * ilenbyt ) {
170 bool is_read_overall_header =
false;
171 if (image_index == -1) {
172 is_read_overall_header =
true;
185 int overall_headlen = 0;
187 if (!is_read_overall_header) {
192 if(image_index != 0) {
194 sprintf(desc,
"For a single image, index must be 0. Your image index = %d.", image_index);
203 size_t single_image_size = (size_t) (
first_h->
headlen + size *
sizeof(
float));
204 size_t offset = overall_headlen + single_image_size * image_index;
206 SpiderHeader *cur_image_hed;
211 cur_image_hed =
static_cast < SpiderHeader *
>(calloc(1,
sizeof(SpiderHeader)));
214 if (fread(cur_image_hed,
sizeof(SpiderHeader), 1,
file) != 1) {
216 sprintf(desc,
"read spider header with image_index = %d failed", image_index);
225 sprintf(desc,
"%dth image size %dx%dx%d != overall size %dx%dx%d",
226 image_index, (
int)cur_image_hed->nsam, (
int)cur_image_hed->nrow,
227 (
int)cur_image_hed->nslice,
234 int xlen = 0, ylen = 0, zlen = 0;
236 &ylen, (
int) cur_image_hed->nslice, &zlen);
244 if(cur_image_hed->mmvalid == 1) {
245 dict[
"minimum"] = cur_image_hed->min;
246 dict[
"maximum"] = cur_image_hed->max;
247 dict[
"mean"] = cur_image_hed->mean;
248 dict[
"sigma"] = cur_image_hed->sigma;
251 dict[
"SPIDER.nslice"] = (int) cur_image_hed->nslice;
252 dict[
"SPIDER.type"] = (
int) cur_image_hed->type;
254 dict[
"SPIDER.irec"] = cur_image_hed->irec;
256 dict[
"SPIDER.angvalid"] = (int)cur_image_hed->angvalid;
257 if((
int)dict[
"SPIDER.angvalid"] != 0) {
258 dict[
"SPIDER.phi"] = cur_image_hed->phi;
259 dict[
"SPIDER.theta"] = cur_image_hed->theta;
260 dict[
"SPIDER.gamma"] = cur_image_hed->gamma;
263 dict[
"SPIDER.headrec"] = (int) cur_image_hed->headrec;
264 dict[
"SPIDER.headlen"] = (
int) cur_image_hed->headlen;
265 dict[
"SPIDER.reclen"] = (int) cur_image_hed->reclen;
267 dict[
"SPIDER.dx"] = cur_image_hed->dx;
268 dict[
"SPIDER.dy"] = cur_image_hed->dy;
269 dict[
"SPIDER.dz"] = cur_image_hed->dz;
271 dict[
"SPIDER.istack"] = (
int) cur_image_hed->istack;
272 if((
int)dict[
"SPIDER.istack"] > 0) {
273 dict[
"SPIDER.maxim"] = (int)cur_image_hed->maxim;
275 dict[
"SPIDER.imgnum"] = (int)cur_image_hed->imgnum;
277 dict[
"SPIDER.Kangle"] = (
int)cur_image_hed->Kangle;
278 if((
int)dict[
"SPIDER.Kangle"] == 1) {
279 dict[
"SPIDER.phi1"] = cur_image_hed->phi1;
280 dict[
"SPIDER.theta1"] = cur_image_hed->theta1;
281 dict[
"SPIDER.psi1"] = cur_image_hed->psi1;
283 else if((
int)dict[
"SPIDER.Kangle"] == 2) {
284 dict[
"SPIDER.phi1"] = cur_image_hed->phi1;
285 dict[
"SPIDER.theta1"] = cur_image_hed->theta1;
286 dict[
"SPIDER.psi1"] = cur_image_hed->psi1;
287 dict[
"SPIDER.phi2"] = cur_image_hed->phi2;
288 dict[
"SPIDER.theta2"] = cur_image_hed->theta2;
289 dict[
"SPIDER.psi2"] = cur_image_hed->psi2;
292 dict[
"SPIDER.date"] = string(cur_image_hed->date).substr(0, 11);
293 dict[
"SPIDER.time"] = string(cur_image_hed->time).substr(0, 8);
295 dict[
"SPIDER.title"] = string(cur_image_hed->title);
297 if(cur_image_hed->scale>0) {
298 dict[
"SPIDER.scale"] = cur_image_hed->scale;
300 dic.
put(
"type",
"spider");
301 dic.
put(
"phi", cur_image_hed->phi);
302 dic.
put(
"theta", cur_image_hed->theta);
303 dic.
put(
"psi", cur_image_hed->gamma);
304 dic.
put(
"tx", cur_image_hed->dx);
305 dic.
put(
"ty", cur_image_hed->dy);
306 dic.
put(
"tz", cur_image_hed->dz);
307 dic.
put(
"scale", cur_image_hed->scale);
310 dict[
"xform.projection"] = trans;
313 dict[
"xform.align3d"] = trans;
315 if(trans) {
delete trans; trans=0;}
364 sprintf(desc,
"%dth image size %dx%dx%d != overall size %dx%dx%d",
365 image_index, (
int)dict[
"nx"], (
int)dict[
"ny"], (
int)dict[
"nz"],
376 size_t single_image_size = (int) (
first_h->
headlen + size *
sizeof(
float));
378 if(image_index == -1) {
383 offset = (int)
first_h->
headlen + single_image_size * image_index;
401 SpiderHeader *& hp,
int ISTACK,
int MAXIM,
int IMGNUM,
bool use_host_endian)
418 size_t record_size = nx *
sizeof(float);
419 size_t num_records = (header_size % record_size) == 0 ? header_size / record_size : header_size / record_size + 1;
420 size_t header_length = num_records * record_size;
423 hp =
static_cast < SpiderHeader *
>(calloc(1, header_size));
428 hp->
istack = (float)ISTACK;
430 hp->
nsam = (float)nx;
431 hp->
nrow = (float)ny;
433 hp->
max = dict[
"maximum"];
434 hp->
min = dict[
"minimum"];
435 hp->
mean = dict[
"mean"];
436 hp->
sigma = dict[
"sigma"];
439 if(nz<=1 && dict.
has_key(
"xform.projection")) {
441 Transform * t = dict[
"xform.projection"];
444 hp->
theta = d[
"theta"];
445 hp->
gamma = d[
"psi"];
449 hp->
scale = d[
"scale"];
450 if(t) {
delete t; t=0;}
452 else if(nz>1 && dict.
has_key(
"xform.align3d")) {
457 hp->
theta = d[
"theta"];
458 hp->
gamma = d[
"psi"];
462 hp->
scale = d[
"scale"];
463 if(t) {
delete t; t=0;}
475 hp->
reclen = (float)record_size;
476 hp->
headrec = (float)num_records;
477 hp->
headlen = (float)header_length;
480 hp->
maxim = (float)MAXIM;
482 hp->
irec = (float)(num_records + ny*nz);
484 hp->
imgnum = (float)IMGNUM;
488 struct tm * ttt = localtime(&tod);
491 strftime(ctime, 9,
"%H:%M:%S", ttt);
493 strftime(cdate, 12,
"%d-%b-%Y", ttt);
496 if(dict.
has_key(
"SPIDER.title")) {
497 string title =
static_cast<string>(dict[
"SPIDER.title"]);
503 if(use_host_endian) {
504 if (fwrite(hp, header_size, 1,
file) != 1) {
511 if (fwrite(hp2, header_size, 1,
file) != 1) {
514 if(hp2) {
delete hp2; hp2=0;}
517 size_t pad_size = header_length - header_size;
518 char *pad =
static_cast < char *
>(calloc(pad_size, 1));
519 fwrite(pad, pad_size, 1,
file);
540 int overall_headlen = 0;
545 if(image_index != 0) {
547 sprintf(desc,
"For single image, index must be 0. Your image index = %d.", image_index);
553 size_t single_image_size =
static_cast < size_t > (
first_h->
headlen + size *
sizeof(float));
554 off_t offset = overall_headlen + single_image_size * image_index;
565 unsigned int nz =
static_cast < unsigned int >(
first_h->
nslice);
568 if (fread(data, sec_size, nz,
file) != nz) {
569 LOGERR(
"Incomplete SPIDER data read");
574 int xlen = 0, ylen = 0, zlen = 0;
578 int data_size = xlen * ylen * zlen;
599 size_t single_image_size = (int) (
first_h->
headlen + size *
sizeof(
float));
617 size_t offset,
int img_index,
int max_nimg,
bool use_host_endian)
634 if(!use_host_endian) {
ByteOrder defines functions to work on big/little endian byte orders.
static bool is_host_big_endian()
static void swap_bytes(T *data, size_t n=1)
swap the byte order of data with 'n' T-type elements.
static bool is_float_big_endian(float small_number)
given a small floating number, return whether the number is in big endian or not.
Dict is a dictionary to store <string, EMObject> pair.
void put(const string &key, EMObject val)
Put the value/key pair into the dictionary probably better to just use operator[].
bool has_key(const string &key) const
Ask the Dictionary if it as a particular key.
static void process_region_io(void *cdata, FILE *file, int rw_mode, int image_index, size_t mode_size, int nx, int ny, int nz=1, const Region *area=0, bool need_flip=false, ImageType imgtype=IMAGE_UNKNOWN, int pre_row=0, int post_row=0)
Process image region IO.
EMDataType
Image pixel data type used in EMAN.
static void get_region_dims(const Region *area, int nx, int *area_x, int ny, int *area_y, int nz=1, int *area_z=0)
Get a region's dimensions.
FloatSize is used to describe a 1D, 2D or 3D rectangular size in floating numbers.
ImageIO classes are designed for reading/writing various electron micrography image formats,...
void check_region(const Region *area, const FloatSize &max_size, bool is_new_file=false, bool inbounds_only=true)
Validate image I/O region.
virtual void flush()=0
Flush the IO buffer.
virtual int write_header(const Dict &dict, int image_index=0, const Region *area=0, EMUtil::EMDataType filestoragetype=EMUtil::EM_FLOAT, bool use_host_endian=true)=0
Write a header to an image.
virtual int write_data(float *data, int image_index=0, const Region *area=0, EMUtil::EMDataType filestoragetype=EMUtil::EM_FLOAT, bool use_host_endian=true)=0
Write data to an image.
virtual bool is_complex_mode()=0
Is this an complex image or not.
virtual int read_header(Dict &dict, int image_index=0, const Region *area=0, bool is_3d=false)=0
Read the header from an image.
FILE * sfopen(const string &filename, IOMode mode, bool *is_new=0, bool overwrite=false)
Run fopen safely.
void check_read_access(int image_index)
Validate 'image_index' in file reading.
virtual int read_data(float *data, int image_index=0, const Region *area=0, bool is_3d=false)=0
Read the data from an image.
virtual void init()=0
Do some initialization before doing the read/write.
void check_write_access(IOMode rw_mode, int image_index, int max_nimg=0)
Validate rw_mode and image_index in file writing.
void become_host_endian(T *data, size_t n=1)
Convert data of this image into host endian format.
virtual bool is_image_big_endian()=0
Is this image in big endian or not.
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
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
int get_nimg()
get the number of images in this stacked SPIDER image
virtual bool is_valid_spider(const void *first_block)
check the data block to see if it represents valid stacked SPIDER image file header
void swap_header(SpiderHeader *header)
void swap_data(float *data, size_t nitems)
static bool is_valid(const void *first_block)
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
static bool is_file_exist(const string &filename)
check whether a file exists or not
#define Assert(s)
Define Assert() function that is effective only when -DDEBUG is used.
EMData * copy() const
This file is a part of "emdata.h", to use functions in this file, you should "#include "emdata....
#define ImageReadException(filename, desc)
#define ImageFormatException(desc)
#define ImageWriteException(imagename, desc)
int portable_fseek(FILE *fp, off_t offset, int whence)