46const char *ImagicIO2::HED_EXT =
"hed";
47const char *ImagicIO2::IMG_EXT =
"img";
48const char *ImagicIO2::REAL_TYPE_MAGIC =
"REAL";
49const char *ImagicIO2::CTF_MAGIC =
"!-";
51ImagicIO2::ImagicIO2(
const string & fname,
IOMode rw)
52:
ImageIO(fname, rw), hed_file(0), img_file(0)
96 LOGWARN(
"IMAGIC header file and data file should both exist or both not exist");
136 char first_block[1024];
137 size_t n = fread(first_block,
sizeof(
char),
sizeof(first_block), in);
146 const int *data =
reinterpret_cast <const int *
>(first_block);
149 int izold = data[11];
169 const int *data =
static_cast < const int *
>(first_block);
171 int headrec = data[3];
173 int minute = data[8];
174 int second = data[9];
175 int rsize = data[10];
179 int realtype = data[68];
194 const int max_dim = 1 << 20;
204 count >= 0 && count < max_dim &&
205 nx > 0 && nx < max_dim &&
206 ny > 0 && ny < max_dim &&
207 nz > 0 &&
nz < max_dim &&
208 hour >= 0 && hour < 24 &&
209 minute >=0 && minute <60 &&
210 second >=0 && second <60) {
225 if (image_index == 0) {
229 memset(&hed, 0,
sizeof(Imagic4D));
231 fread(&hed,
sizeof(Imagic4D), 1,
hed_file);
235 int nz = hed.izlp ? hed.izlp : 1;
240 int xlen = 0, ylen = 0, zlen = 0;
247 dict[
"IMAGIC.imgnum"] = hed.imgnum;
248 dict[
"IMAGIC.count"] = hed.count;
249 dict[
"IMAGIC.error"] = hed.error;
251 dict[
"IMAGIC.month"] = hed.month;
252 dict[
"IMAGIC.day"] = hed.mday;
253 dict[
"IMAGIC.year"] = hed.year;
254 dict[
"IMAGIC.hour"] = hed.hour;
255 dict[
"IMAGIC.minute"] = hed.minute;
256 dict[
"IMAGIC.sec"] = hed.sec;
258 dict[
"IMAGIC.rsize"] = hed.rsize;
259 dict[
"IMAGIC.izold"] = hed.izold;
262 dict[
"IMAGIC.type"] = hed.type+
'\0';
264 dict[
"IMAGIC.ixold"] = hed.ixold;
265 dict[
"IMAGIC.iyold"] = hed.iyold;
267 dict[
"mean"] = hed.avdens;
268 dict[
"sigma"] = hed.sigma;
270 dict[
"maximum"] = hed.densmax;
271 dict[
"minimum"] = hed.densmin;
273 dict[
"IMAGIC.complex"] = hed.complex;
274 dict[
"IMAGIC.defocus1"] = hed.defocus1;
275 dict[
"IMAGIC.defocus2"] = hed.defocus2;
276 dict[
"IMAGIC.defangle"] = hed.defangle;
277 dict[
"IMAGIC.sinostart"] = hed.sinostart;
278 dict[
"IMAGIC.sinoend"] = hed.sinoend;
280 dict[
"IMAGIC.label"] = hed.label+
'\0';
282 dict[
"IMAGIC.ccc3d"] = hed.ccc3d;
283 dict[
"IMAGIC.ref3d"] = hed.ref3d;
284 dict[
"IMAGIC.mident"] = hed.mident;
285 dict[
"IMAGIC.ezshift"] = hed.ezshift;
287 dict[
"IMAGIC.ealpha"] = hed.ealpha;
288 dict[
"IMAGIC.ebeta"] = hed.ebeta;
289 dict[
"IMAGIC.egamma"] = hed.egamma;
291 dict[
"IMAGIC.nalisum"] = hed.nalisum;
292 dict[
"IMAGIC.pgroup"] = hed.pgroup;
294 dict[
"IMAGIC.i4lp"] = hed.i4lp;
296 dict[
"IMAGIC.alpha"] = hed.alpha;
297 dict[
"IMAGIC.beta"] = hed.beta;
298 dict[
"IMAGIC.gamma"] = hed.gamma;
300 dict[
"IMAGIC.imavers"] = hed.imavers;
301 dict[
"IMAGIC.realtype"] = hed.realtype;
303 dict[
"IMAGIC.angle"] = hed.angle;
304 dict[
"IMAGIC.voltage"] = hed.voltage;
305 dict[
"IMAGIC.spaberr"] = hed.spaberr;
306 dict[
"IMAGIC.pcoher"] = hed.pcoher;
307 dict[
"IMAGIC.ccc"] = hed.ccc;
308 dict[
"IMAGIC.errar"] = hed.errar;
309 dict[
"IMAGIC.err3d"] = hed.err3d;
310 dict[
"IMAGIC.ref"] = hed.ref;
311 dict[
"IMAGIC.classno"] = hed.ref;
312 dict[
"IMAGIC.locold"] = hed.locold;
313 dict[
"IMAGIC.repqual"] = hed.repqual;
314 dict[
"IMAGIC.zshift"] = hed.zshift;
315 dict[
"IMAGIC.xshift"] = hed.xshift;
316 dict[
"IMAGIC.yshift"] = hed.yshift;
317 dict[
"IMAGIC.numcls"] = hed.numcls;
318 dict[
"IMAGIC.ovqual"] = hed.ovqual;
319 dict[
"IMAGIC.eangle"] = hed.eangle;
320 dict[
"IMAGIC.exshift"] = hed.exshift;
321 dict[
"IMAGIC.eyshift"] = hed.eyshift;
322 dict[
"IMAGIC.cmtotvar"] = hed.cmtotvar;
323 dict[
"IMAGIC.informat"] = hed.informat;
324 dict[
"IMAGIC.numeigen"] = hed.numeigen;
325 dict[
"IMAGIC.niactive"] = hed.niactive;
326 dict[
"apix_x"] = hed.resolx;
327 dict[
"apix_y"] = hed.resoly;
328 dict[
"apix_z"] = hed.resolz;
329 if(hed.errar==-1.0) {
330 dict[
"IMAGIC.fabosa1"] = hed.alpha2;
331 dict[
"IMAGIC.fabosa2"] = hed.beta2;
332 dict[
"IMAGIC.fabosa3"] = hed.gamma2;
335 dict[
"IMAGIC.alpha2"] = hed.alpha2;
336 dict[
"IMAGIC.beta2"] = hed.beta2;
337 dict[
"IMAGIC.gamma2"] = hed.gamma2;
339 dict[
"IMAGIC.nmetric"] = hed.nmetric;
340 dict[
"IMAGIC.actmsa"] = hed.actmsa;
342 vector<float> v_coosmsa(hed.coosmsa, hed.coosmsa+69);
343 dict[
"IMAGIC.coosmsa"] = v_coosmsa;
345 dict[
"IMAGIC.eigval"] = hed.coosmsa[19];
346 dict[
"IMAGIC.history"] = hed.history+
'\0';
348 dict[
"orientation_convention"] =
"IMAGIC";
349 const float alpha = hed.alpha;
350 const float beta = hed.beta;
351 const float gamma = hed.gamma;
352 dict[
"euler_alpha"] = alpha;
353 dict[
"euler_beta"] = beta;
354 dict[
"euler_gamma"] = gamma;
356 trans->
set_rotation(
Dict(
"type",
"imagic",
"alpha", alpha,
"beta", beta,
"gamma", gamma));
358 dict[
"xform.projection"] = trans;
361 dict[
"xform.projection"] = trans;
362 dict[
"xform.align3d"] = trans;
368 if(trans) {
delete trans; trans=0;}
369 if(ctf_) {
delete ctf_; ctf_=0;}
379 if (strncmp(name,
"PACK",4) == 0) {
382 else if (strncmp(name,
"INTG",4) == 0) {
388 else if (strncmp(name,
"COMP",4) == 0) {
391 else if (strncmp(name,
"RECO",4) == 0) {
425 string header_label(hed.
label);
428 if (header_label.size() > 2) {
429 string sctf =
"O" + header_label.substr(2);
445 string ctf_ = ctf->
to_string().substr(1);
449 ctf_ = ctf_.substr(0, 80);
452 string padded(80 - ctf_.size(),
' ');
453 ctf_ = ctf_ + padded;
508 sprintf(desc,
"new IMAGIC size %dx%dx%d is not equal to existing size %dx%dx%d",
525 memset(&new_hed, 0,
sizeof(Imagic4D));
527 time_t cur_time = time(0);
528 struct tm *tm = localtime(&cur_time);
533 new_hed.mday = tm->tm_mday;
534 new_hed.month = tm->tm_mon;
535 new_hed.year = tm->tm_year + 1900;
536 new_hed.hour = tm->tm_hour;
537 new_hed.minute = tm->tm_min;
538 new_hed.sec = tm->tm_sec;
540 size_t img_size = nx*ny*
nz;
541 if(img_size > (
size_t)INT_MAX) {
545 new_hed.rsize = (int)img_size;
553 new_hed.avdens = (float)dict[
"mean"];
554 new_hed.sigma = (float)dict[
"sigma"];
555 new_hed.densmax = (float)dict[
"maximum"];
556 new_hed.densmin = (float)dict[
"minimum"];
561 string new_label = dict.
has_key(
"IMAGIC.label") ? (string) dict[
"IMAGIC.label"] :
string(79,
' ');
562 sprintf(new_hed.label,
"%s", new_label.c_str() );
564 string new_history = dict.
has_key(
"IMAGIC.history") ? (string) dict[
"IMAGIC.history"] :
string(227,
' ');
565 new_history = new_history.substr(0, 228);
566 sprintf(new_hed.history,
"%s", new_history.c_str());
571 if(
nz<=1 && dict.
has_key(
"xform.projection")) {
572 t = dict[
"xform.projection"];
574 else if(
nz>1 && dict.
has_key(
"xform.align3d")) {
575 t = dict[
"xform.align3d"];
580 new_hed.alpha = d[
"alpha"];
581 new_hed.beta = d[
"beta"];
582 new_hed.gamma = d[
"gamma"];
587 if(dict.
has_key(
"euler_alpha")) new_hed.alpha = dict[
"euler_alpha"];
588 if(dict.
has_key(
"euler_beta")) new_hed.beta = dict[
"euler_beta"];
589 if(dict.
has_key(
"euler_gamma")) new_hed.gamma = dict[
"euler_gamma"];
594 new_hed.resolx = dict[
"apix_x"];
595 new_hed.resoly = dict[
"apix_y"];
596 new_hed.resolz = dict[
"apix_z"];
601 if (image_index>=0 && image_index<nimg) {
603 new_hed.imgnum=image_index+1;
606 fwrite(&new_hed,
sizeof(Imagic4D),1,
hed_file);
616 fwrite(&ifol,
sizeof(
int), 1,
hed_file);
618 fwrite(&nimg,
sizeof(
int), 1,
hed_file);
627 Ctf * ctf_ = dict[
"ctf"];
629 if(ctf_) {
delete ctf_; ctf_=0;}
642#elif defined __OPENVMS__
672 if (image_index == -1) {
681 if(!use_host_endian) {
707 size_t img_size = (size_t)nx*ny*
nz;
713 short *sdata = (
short *) data;
714 unsigned char *cdata = (
unsigned char *) data;
727 for (ptrdiff_t j = img_size - 1; j >= 0; --j) {
728 data[j] =
static_cast < float >(sdata[j]);
756 s =
sizeof(
unsigned char);
759 s =
sizeof(
unsigned short);
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_data_big_endian(const T *small_num_addr)
given a pointer to a reasonable small integer number, return whether the number is big endian or not.
Ctf is the base class for all CTF model.
virtual int from_string(const string &ctf)=0
virtual string to_string() const =0
Dict is a dictionary to store <string, EMObject> pair.
bool has_key(const string &key) const
Ask the Dictionary if it as a particular key.
EMAN1Ctf is the CTF model used in EMAN1.
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.
static const char * IMG_EXT
int get_nimg()
Get number of images in this file.
static bool is_valid(const void *first_block)
static const char * REAL_TYPE_MAGIC
@ IMAGIC_FFT_FLOAT_COMPLEX
void write_ctf(const Ctf *const ctf, int image_index=0)
Ctf * read_ctf(const Imagic4D &hed) const
the Ctf object is a EMAN1Ctf object.
static const char * HED_EXT
void make_header_host_endian(Imagic4D &hed) const
int generate_machine_stamp() const
int to_em_datatype(DataType t) const
static const char * CTF_MAGIC
void swap_header(Imagic4D &hed) const
size_t get_datatype_size(DataType t) const
DataType get_datatype_from_name(const char *name) const
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
static string change_filename_ext(const string &old_filename, const string &new_ext)
Change a file's extension and return the new filename.
#define Assert(s)
Define Assert() function that is effective only when -DDEBUG is used.
#define ImageReadException(filename, desc)
#define FileAccessException(filename)
#define ImageWriteException(imagename, desc)
int portable_fseek(FILE *fp, off_t offset, int whence)
IMAGIC-4D file format http://www.imagescience.de/formats/formats.htm.