48 #include <sys/param.h>
50 #define MAXPATHLEN (MAX_PATH * 4)
54const float INT8_min = -128.0f;
55const float INT16_min = -32768.0f;
58const float INT8_max = 127.0f;
59const float INT16_max = 32767.0f;
62const float UINT8_max = 255.0f;
63const float UINT16_max = 65535.0f;
70HdfIO2::HdfIO2(
const string & fname, IOMode rw)
71:
ImageIO(fname, rw), nx(1), ny(1), nz(1), is_exist(false),
73 rendermin(0.0), rendermax(0.0), renderbits(16), renderlevel(1)
76 accprop=H5Pcreate(H5P_FILE_ACCESS);
79 H5Pset_fapl_sec2( accprop );
81 H5Pset_cache(accprop, 0, 256, 1024*4096, 0.75);
91 simple_space=H5Screate_simple(1,&dims,NULL);
93 meta_attr_dict =
Dict();
98 H5Sclose(simple_space);
105 H5Fflush(file,H5F_SCOPE_GLOBAL);
110 printf(
"HDF: close\n");
116 EMObject HdfIO2::read_attr(hid_t attr) {
117 hid_t type = H5Aget_type(attr);
118 hid_t spc = H5Aget_space(attr);
119 H5T_class_t cls = H5Tget_class(type);
120 size_t sz = H5Tget_size(type);
121 hssize_t pts = H5Sget_simple_extent_npoints(spc);
130 vector <float> fv((
size_t)pts);
131 vector <int> iv((
size_t)pts);
140 H5Aread(attr,H5T_NATIVE_CHAR,&c);
145 H5Aread(attr,H5T_NATIVE_INT,&i);
149 ia=(
int *)malloc((
size_t)pts*
sizeof(int));
150 H5Aread(attr,H5T_NATIVE_INT,ia);
152 for (i=0; i<pts; i++) iv[i] = ia[i];
164 H5Aread(attr,H5T_NATIVE_FLOAT,&f);
169 fa = (
float *)malloc((
size_t)pts*
sizeof(float));
170 H5Aread(attr,H5T_NATIVE_FLOAT,fa);
172 for (i=0; i<pts; i++) fv[i] = fa[i];
180 H5Aread(attr,H5T_NATIVE_DOUBLE,&d);
187 s = (
char *)malloc(sz+1);
189 H5Aread(attr,type,s);
220 if ((s[0] ==
'O' && isdigit(s[1])) || (s[0] ==
'E' && isdigit(s[1]))) ret.force_CTF();
227 matrix = (
float*)malloc(12*
sizeof(
float));
228 H5Aread(attr, type, matrix);
237 LOGERR(
"Unhandled HDF5 metadata %d", cls);
248int HdfIO2::write_attr(hid_t loc,
const char *name,
EMObject obj) {
258 type=H5Tcopy(H5T_NATIVE_CHAR);
259 spc=H5Scopy(simple_space);
261 case EMObject::SHORT:
263 type=H5Tcopy(H5T_NATIVE_INT);
264 spc=H5Scopy(simple_space);
266 case EMObject::UNSIGNEDINT:
267 type=H5Tcopy(H5T_NATIVE_UINT);
268 spc=H5Scopy(simple_space);
270 case EMObject::FLOAT:
271 type=H5Tcopy(H5T_NATIVE_FLOAT);
272 spc=H5Scopy(simple_space);
274 case EMObject::DOUBLE:
275 type=H5Tcopy(H5T_NATIVE_DOUBLE);
276 spc=H5Scopy(simple_space);
278 case EMObject::STRING:
280 type=H5Tcopy(H5T_C_S1);
281 H5Tset_size(type,strlen((
const char *)obj)+1);
282 spc=H5Screate(H5S_SCALAR);
284 case EMObject::FLOATARRAY:
285 type=H5Tcopy(H5T_NATIVE_FLOAT);
288 spc=H5Screate_simple(1,&dims,NULL);
290 case EMObject::INTARRAY:
291 type=H5Tcopy(H5T_NATIVE_INT);
294 spc=H5Screate_simple(1,&dims,NULL);
296 case EMObject::TRANSFORM:
297 type = H5Tcreate(H5T_COMPOUND, 12 *
sizeof(
float));
298 H5Tinsert(type,
"00", 0, H5T_NATIVE_FLOAT);
299 H5Tinsert(type,
"01", 1*
sizeof(
float), H5T_NATIVE_FLOAT);
300 H5Tinsert(type,
"02", 2*
sizeof(
float), H5T_NATIVE_FLOAT);
301 H5Tinsert(type,
"03", 3*
sizeof(
float), H5T_NATIVE_FLOAT);
302 H5Tinsert(type,
"10", 4*
sizeof(
float), H5T_NATIVE_FLOAT);
303 H5Tinsert(type,
"11", 5*
sizeof(
float), H5T_NATIVE_FLOAT);
304 H5Tinsert(type,
"12", 6*
sizeof(
float), H5T_NATIVE_FLOAT);
305 H5Tinsert(type,
"13", 7*
sizeof(
float), H5T_NATIVE_FLOAT);
306 H5Tinsert(type,
"20", 8*
sizeof(
float), H5T_NATIVE_FLOAT);
307 H5Tinsert(type,
"21", 9*
sizeof(
float), H5T_NATIVE_FLOAT);
308 H5Tinsert(type,
"22", 10*
sizeof(
float), H5T_NATIVE_FLOAT);
309 H5Tinsert(type,
"23", 11*
sizeof(
float), H5T_NATIVE_FLOAT);
313 spc = H5Screate_simple(1, &dims, NULL);
315 case EMObject::TRANSFORMARRAY:
316 case EMObject::STRINGARRAY:
317 case EMObject::EMDATA:
318 case EMObject::XYDATA:
319 case EMObject::FLOAT_POINTER:
320 case EMObject::INT_POINTER:
321 case EMObject::VOID_POINTER:
324 case EMObject::UNKNOWN:
330 if (H5Adelete(loc,name) < 0) {
332 LOGERR(
"HDF: Attribute %s deletion error in write_attr().\n", name);
337 printf(
"HDF: delete attribute %s successfully in write_attr().\n", name);
341 hid_t attr = H5Acreate(loc,name,type,spc,H5P_DEFAULT);
360 H5Awrite(attr,type,&c);
362 case EMObject::SHORT:
365 H5Awrite(attr,type,&i);
369 H5Awrite(attr,type,&i);
371 case EMObject::UNSIGNEDINT:
372 ui=(
unsigned int)obj;
373 H5Awrite(attr,type,&ui);
375 case EMObject::FLOAT:
377 H5Awrite(attr,type,&f);
379 case EMObject::DOUBLE:
381 H5Awrite(attr,type,&d);
383 case EMObject::STRING:
386 H5Awrite(attr,type,s);
388 case EMObject::FLOATARRAY:
389 fa=(
float *)malloc(fv.size()*
sizeof(float));
390 for (ui=0; ui<fv.size(); ui++) fa[ui]=fv[ui];
391 H5Awrite(attr,type,fa);
394 case EMObject::INTARRAY:
395 ia=(
int *)malloc(iv.size()*
sizeof(int));
396 for (ui=0; ui<iv.size(); ui++) ia[ui]=iv[ui];
397 H5Awrite(attr,type,ia);
400 case EMObject::TRANSFORM:
403 fa = (
float *)malloc(12*
sizeof(
float));
406 for (r=0; r<3; ++r) {
407 for (c=0; c<4; ++c) {
413 H5Awrite(attr,type,fa);
423 LOGERR(
"Unhandled HDF5 metadata '%s'", name);
427 herr_t ret1 = H5Tclose(type);
428 herr_t ret2 = H5Sclose(spc);
429 herr_t ret3 = H5Aclose(attr);
431 if (ret1>=0 && ret2>=0 && ret3>=0) {
435 LOGERR(
"close error in write_attr()\n");
457 printf(
"HDF: init\n");
462 if (rw_mode == READ_ONLY) {
463 file = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, accprop);
467 file = H5Fopen(filename.c_str(), H5F_ACC_RDWR, accprop);
469 file = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, accprop);
475 printf(
"HDF: File truncated or new file created\n");
481 group=H5Gopen(file,
"/MDF/images");
483 if (rw_mode == READ_ONLY)
throw ImageReadException(filename,
"HDF5 file has no image data (no /MDF group)");
484 group=H5Gcreate(file,
"/MDF",64);
485 if (group<0)
throw ImageWriteException(filename,
"Unable to add image group (/MDF) to HDF5 file");
487 group=H5Gcreate(file,
"/MDF/images",4096);
488 if (group<0)
throw ImageWriteException(filename,
"Unable to add image group (/MDF/images) to HDF5 file");
489 write_attr(group,
"imageid_max",
EMObject(-1));
496 int nattr=H5Aget_num_attrs(group);
499 for (
int i=0; i<nattr; i++) {
501 hid_t attr=H5Aopen_by_idx(group,
".",H5_INDEX_CRT_ORDER,H5_ITER_NATIVE,i,H5P_DEFAULT,H5P_DEFAULT);
502 H5Aget_name(attr,127,name);
504 if (strcmp(name,
"imageid_max")!=0) {
506 meta_attr_dict[
"DDD."+string(name)]=val;
518int HdfIO2::init_test()
527 printf(
"HDF: init_test\n");
532 hid_t fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5Pcreate(H5P_FILE_ACCESS));
533 hid_t groupid = H5Gopen(fileid,
"/");
534 hid_t attid = H5Aopen_name(groupid,
"num_dataset");
552bool HdfIO2::is_valid(
const void *first_block)
557 char signature[8] = { char(137),char(72),char(68),char(70),char(13),char(10),char(26), char(10) };
558 if (strncmp((
const char *)first_block,signature,8)==0)
return true;
569herr_t h5_iter_attr_read( hid_t igrp,
const char *attr_name,
const H5A_info_t *ainfo,
void *user) {
570 hid_t attr=H5Aopen_by_name(igrp,
".",attr_name, H5P_DEFAULT, H5P_DEFAULT);
574 if (strncmp(attr_name,
"EMAN.",5)==0) {
577 EMObject val=HdfIO2::read_attr(attr);
578 (*dict)[attr_name+5]=val;
581 printf(
"HDF: Error reading HDF attribute %s\n",attr_name+5);
588herr_t h5_iter_attr_del( hid_t igrp,
const char *attr_name,
const H5A_info_t *ainfo,
void *user) {
589 hid_t attr=H5Adelete_by_name(igrp,
".",attr_name, H5P_DEFAULT);
596int HdfIO2::read_header(
Dict & dict,
int image_index,
const Region * area,
bool)
602 size_t meta_attr_size = meta_attr_dict.size();
604 if (meta_attr_size!=0) {
605 for (
size_t i=0; i<meta_attr_size; ++i) {
606 dict[meta_attr_dict.keys()[i]] = meta_attr_dict.
values()[i];
611 printf(
"HDF: read_head %d\n", image_index);
618 sprintf(ipath,
"/MDF/images/%d", image_index);
619 hid_t igrp=H5Gopen(file, ipath);
623 sprintf(msg,
"Image %d does not exist",image_index);
628 if (H5Aiterate2(igrp,H5_INDEX_NAME, H5_ITER_NATIVE, &n, &h5_iter_attr_read, &dict)) {
629 printf(
"Error on HDF5 iter attr\n");
657 dict[
"ctf"].force_CTF();
677 check_region(area,
IntSize(dict[
"nx"], dict[
"ny"], dict[
"nz"]),
false,
false);
687 float xorigin = dict[
"origin_x"];
688 float yorigin = dict[
"origin_y"];
689 float zorigin = dict[
"origin_z"];
691 float apix_x = dict[
"apix_x"];
692 float apix_y = dict[
"apix_y"];
693 float apix_z = dict[
"apix_z"];
695 dict[
"origin_x"] = xorigin + apix_x * area->
origin[0];
696 dict[
"origin_y"] = yorigin + apix_y * area->
origin[1];
697 dict[
"origin_z"] = zorigin + apix_z * area->
origin[2];
705 sprintf(ipath,
"/MDF/images/%d/image",image_index);
706 hid_t ds=H5Dopen(file,ipath);
710 hid_t dt = H5Dget_type(ds);
712 switch(H5Tget_size(dt)) {
714 dict[
"datatype"] = (int)EMUtil::EM_FLOAT;
717 dict[
"datatype"] = (int)EMUtil::EM_USHORT;
720 dict[
"datatype"] = (int)EMUtil::EM_UCHAR;
738int HdfIO2::erase_header(
int image_index)
742 if (image_index < 0)
return 0;
747 printf(
"HDF: erase_head %d\n",image_index);
754 sprintf(ipath,
"/MDF/images/%d", image_index);
755 hid_t igrp=H5Gopen(file, ipath);
759 if (H5Aiterate2(igrp,H5_INDEX_NAME, H5_ITER_NATIVE, &n, &h5_iter_attr_del, NULL)) {
760 printf(
"Error on HDF5 erase_header\n");
786int HdfIO2::read_data_8bit(
unsigned char *data,
int image_index,
const Region *area,
bool is_3d,
float minval,
float maxval) {
789 printf(
"HDF: read_data_8bit %d\n",image_index);
793 sprintf(ipath,
"/MDF/images/%d/image",image_index);
794 hid_t ds = H5Dopen(file,ipath);
798 hid_t spc=H5Dget_space(ds);
799 hid_t dt = H5Dget_type(ds);
802 hsize_t rank = H5Sget_simple_extent_ndims(spc);
804 H5Sget_simple_extent_dims(spc, dims_out, NULL);
811 else if (rank == 2) {
816 else if (rank == 3) {
823 hid_t memoryspace = 0;
826 int x0 = 0, y0 = 0, z0 = 0;
827 int x1 = 0, y1 = 0, z1 = 0;
828 int nx1 = 1, ny1 = 1, nz1 = 1;
837 x0 = (int)doffset[0];
838 y0 = (int)doffset[1];
839 z0 = (int)doffset[2];
842 z1 = (int)(z1 >
static_cast<int>(nx) ? nx : z1);
845 y1 = (int)(y1 >
static_cast<int>(ny) ? ny : y1);
853 x1 = (int)(x1 >
static_cast<int>(nz) ? nz : x1);
858 if (x1 < x0 || y1< y0 || z1 < z0)
return 0;
862 dcount[0] = x1 - doffset[0];
863 dcount[1] = y1 - doffset[1];
864 dcount[2] = z1 - doffset[2];
866 H5Sselect_hyperslab (spc, H5S_SELECT_SET, (
const hsize_t*)doffset, NULL,
867 (
const hsize_t*)dcount, NULL);
872 dims[0] = dcount[2]?dcount[2]:1;
873 dims[1] = dcount[1]?dcount[1]:1;
874 dims[2] = dcount[0]?dcount[0]:1;
880 memoryspace = H5Screate_simple(3, dims, NULL);
882 else if (rank == 2) {
888 x0 = (int)doffset[0];
889 y0 = (int)doffset[1];
893 y1 = (int)(y1 >
static_cast<int>(nx) ? nx : y1);
896 x1 = (int)(x1 >
static_cast<int>(ny) ? ny : x1);
904 if (x1 < x0 || y1< y0)
return 0;
907 dcount[0] = x1 - doffset[0];
908 dcount[1] = y1 - doffset[1];
911 H5Sselect_hyperslab (spc, H5S_SELECT_SET, (
const hsize_t*)doffset, NULL,
912 (
const hsize_t*)dcount, NULL);
917 dims[0] = (hsize_t)(dcount[1]?dcount[1]:1);
918 dims[1] = (hsize_t)(dcount[0]?dcount[0]:1);
924 memoryspace = H5Screate_simple(2, dims, NULL);
932 H5Dread(ds,H5T_NATIVE_FLOAT,memoryspace,spc,H5P_DEFAULT,data);
941 float * subdata =
new float[nx1*ny1*nz1];
943 H5Dread(ds,H5T_NATIVE_FLOAT,memoryspace,spc,H5P_DEFAULT,subdata);
945 int xd0=0, yd0=0, zd0=0;
946 size_t clipped_row_size = 0;
952 clipped_row_size = (z1-z0)*
sizeof(
float);
954 else if (rank == 2) {
957 clipped_row_size = (y1-y0)*
sizeof(
float);
960 int src_secsize = nx1 * ny1;
963 float * src = subdata;
964 unsigned char * dst = data + zd0*dst_secsize + yd0*(int)(area->
get_width()) + xd0;
966 int src_gap = src_secsize - (y1-y0) * nx1;
967 int dst_gap = dst_secsize - (y1-y0) * (
int)(area->
get_width());
969 for (
int i = 0; i<nz1; ++i) {
970 for (
int j = 0; j<ny1; ++j) {
971 EMUtil::em_memcpy(dst, src, clipped_row_size);
984 H5Sclose(memoryspace);
986 hsize_t size = (hsize_t)nx*ny*nz;
990 unsigned short *usdata = (
unsigned short *) data;
991 unsigned char *cdata = (
unsigned char *) data;
993 switch(H5Tget_size(dt)) {
995 H5Dread(ds,H5T_NATIVE_FLOAT,spc,spc,H5P_DEFAULT,data);
999 H5Dread(ds,H5T_NATIVE_USHORT,spc,spc,H5P_DEFAULT,usdata);
1001 for (i = 0; i < size; ++i) {
1003 data[j] =
static_cast < float >(usdata[j]);
1008 H5Dread(ds,H5T_NATIVE_UCHAR,spc,spc,H5P_DEFAULT,cdata);
1010 for (i = 0; i < size; ++i) {
1012 data[j] =
static_cast < float >(cdata[j]);
1033 printf(
"HDF: read_data %d\n",image_index);
1037 sprintf(ipath,
"/MDF/images/%d/image",image_index);
1038 hid_t ds = H5Dopen(file,ipath);
1042 hid_t spc=H5Dget_space(ds);
1043 hid_t dt = H5Dget_type(ds);
1045 hsize_t dims_out[3];
1046 hsize_t rank = H5Sget_simple_extent_ndims(spc);
1048 H5Sget_simple_extent_dims(spc, dims_out, NULL);
1055 else if (rank == 2) {
1060 else if (rank == 3) {
1065 hsize_t size = (hsize_t)nx*(hsize_t)ny*(hsize_t)nz;
1068 hid_t memoryspace = 0;
1071 int x0 = 0, y0 = 0, z0 = 0;
1072 int x1 = 0, y1 = 0, z1 = 0;
1073 int nx1 = 1, ny1 = 1, nz1 = 1;
1085 x0 = (int)doffset[0];
1086 y0 = (int)doffset[1];
1087 z0 = (int)doffset[2];
1090 z1 = (int)(z1 >
static_cast<int>(nx) ? nx : z1);
1093 y1 = (int)(y1 >
static_cast<int>(ny) ? ny : y1);
1101 x1 = (int)(x1 >
static_cast<int>(nz) ? nz : x1);
1106 if (x1 < x0 || y1< y0 || z1 < z0)
return 0;
1110 dcount[0] = x1 - doffset[0];
1111 dcount[1] = y1 - doffset[1];
1112 dcount[2] = z1 - doffset[2];
1114 H5Sselect_hyperslab (spc, H5S_SELECT_SET, (
const hsize_t*)doffset, NULL,
1115 (
const hsize_t*)dcount, NULL);
1120 dims[0] = dcount[2]?dcount[2]:1;
1121 dims[1] = dcount[1]?dcount[1]:1;
1122 dims[2] = dcount[0]?dcount[0]:1;
1128 memoryspace = H5Screate_simple(3, dims, NULL);
1130 else if (rank == 2) {
1136 x0 = (int)doffset[0];
1137 y0 = (int)doffset[1];
1141 y1 = (int)(y1 >
static_cast<int>(nx) ? nx : y1);
1144 x1 = (int)(x1 >
static_cast<int>(ny) ? ny : x1);
1152 if (x1 < x0 || y1< y0)
return 0;
1155 dcount[0] = x1 - doffset[0];
1156 dcount[1] = y1 - doffset[1];
1158 H5Sselect_none(spc);
1159 H5Sselect_hyperslab (spc, H5S_SELECT_SET, (
const hsize_t*)doffset, NULL,
1160 (
const hsize_t*)dcount, NULL);
1165 dims[0] = (hsize_t)(dcount[1]?dcount[1]:1);
1166 dims[1] = (hsize_t)(dcount[0]?dcount[0]:1);
1172 memoryspace = H5Screate_simple(2, dims, NULL);
1180 H5Dread(ds,H5T_NATIVE_FLOAT,memoryspace,spc,H5P_DEFAULT,data);
1189 float * subdata =
new float[nx1*ny1*nz1];
1191 H5Dread(ds,H5T_NATIVE_FLOAT,memoryspace,spc,H5P_DEFAULT,subdata);
1193 int xd0=0, yd0=0, zd0=0;
1194 size_t clipped_row_size = 0;
1200 clipped_row_size = (z1-z0)*
sizeof(
float);
1202 else if (rank == 2) {
1205 clipped_row_size = (y1-y0)*
sizeof(
float);
1208 int src_secsize = nx1 * ny1;
1211 float * src = subdata;
1212 float * dst = data + zd0*dst_secsize + yd0*(int)(area->
get_width()) + xd0;
1214 int src_gap = src_secsize - (y1-y0) * nx1;
1215 int dst_gap = dst_secsize - (y1-y0) * (
int)(area->
get_width());
1217 for (
int i = 0; i<nz1; ++i) {
1218 for (
int j = 0; j<ny1; ++j) {
1219 EMUtil::em_memcpy(dst, src, clipped_row_size);
1233 H5Sclose(memoryspace);
1235 hsize_t size = (hsize_t)nx*ny*nz;
1239 unsigned short *usdata = (
unsigned short *) data;
1240 unsigned char *cdata = (
unsigned char *) data;
1242 H5Dread(ds,H5T_NATIVE_FLOAT,spc,spc,H5P_DEFAULT,data);
1250 sprintf(ipath,
"/MDF/images/%d",image_index);
1251 hid_t igrp=H5Gopen(file,ipath);
1252 hid_t iattr=H5Aopen_name(igrp,
"EMAN.stored_renderbits");
1254 renderbits=(int)read_attr(iattr);
1258 iattr=H5Aopen_name(igrp,
"EMAN.stored_rendermax");
1260 rendermax=(float)read_attr(iattr);
1262 iattr=H5Aopen_name(igrp,
"EMAN.stored_rendermin");
1264 rendermin=(float)read_attr(iattr);
1266 float RUMAX = (1<<renderbits)-1.0f;
1267 for (
size_t i=0; i<size; i++) data[i]=(data[i]/RUMAX)*(rendermax-rendermin)+rendermin;
1281int HdfIO2::write_header(
const Dict & dict,
int image_index,
const Region* area,
1285 printf(
"HDF: write_head %d\n",image_index);
1292 nx = (int)dict[
"nx"];
1293 ny = (int)dict[
"ny"];
1294 nz = (int)dict[
"nz"];
1296 if (image_index<0) {
1297 image_index = get_nimg();
1302 hid_t attr=H5Aopen_name(group,
"imageid_max");
1303 int nimg = read_attr(attr);
1308 if (image_index < 0) image_index=nimg+1;
1310 if (image_index > nimg) {
1311 write_attr(group,(
const char *)
"imageid_max",
EMObject(image_index));
1316 sprintf(ipath,
"/MDF/images/%d",image_index);
1317 hid_t igrp=H5Gopen(file,ipath);
1322 igrp=H5Gcreate(file,ipath,64);
1324 if (igrp < 0)
throw ImageWriteException(filename,
"Unable to add /MDF/images/# to HDF5 file");
1334 if (H5Aiterate2(igrp,H5_INDEX_NAME, H5_ITER_NATIVE, &n, &h5_iter_attr_read, &dict2)) {
1335 printf(
"Error on HDF5 iter attr\n");
1353 if (!dict2.
has_key(
"datatype")) {
1354 dict2[
"datatype"] = (int)EMUtil::EM_FLOAT;
1358 check_region(area,
IntSize(dict2[
"nx"], dict2[
"ny"], dict2[
"nz"]),
false,
true);
1361 erase_header(image_index);
1366 if ((
int)dict[
"nx"]*(
int)dict[
"ny"]*(
int)dict[
"nz"] !=
1367 (
int)dict2[
"nx"]*(
int)dict2[
"ny"]*(
int)dict2[
"nz"] ||
1368 (
int)dict[
"datatype"] != (
int)dict2[
"datatype"] ||
1369 dict2.
has_key(
"render_compress_level") || (
int)dt==(
int)EMUtil::EM_COMPRESSED) {
1372 sprintf(ipath,
"/MDF/images/%d/image",image_index);
1374 H5Gunlink(igrp, ipath);
1381 vector <string> keys=dict.
keys();
1383 for (i=0; i<keys.size(); i++) {
1386 if (keys[i]==
string(
"stored_rendermin") || keys[i]==
string(
"stored_rendermax") || keys[i]==
string(
"stored_renderbits") ||
1387 keys[i]==
string(
"render_min") || keys[i]==
string(
"render_max") || keys[i]==
string(
"render_bits"))
continue;
1390 write_attr(igrp,s.c_str(),dict[keys[i]]);
1397 if (dict.
has_key(
"render_compress_level")) renderlevel=(float)dict[
"render_compress_level"];
1398 EMUtil::getRenderLimits(dict, rendermin, rendermax, renderbits);
1411 printf(
"HDF: write_data %d\n",image_index);
1414 if (image_index < 0) {
1415 hid_t attr=H5Aopen_name(group,
"imageid_max");
1416 image_index = read_attr(attr);
1424 sprintf(ipath,
"/MDF/images/%d/image", image_index);
1428 if (nz == 1 && ny == 1) {
1429 hsize_t dims[1]= { nx };
1430 spc=H5Screate_simple(1,dims,NULL);
1433 hsize_t dims[2]= { ny,nx };
1434 spc=H5Screate_simple(2,dims,NULL);
1437 hsize_t dims[3]= { nz, ny, nx };
1438 spc=H5Screate_simple(3,dims,NULL);
1444 case EMUtil::EM_FLOAT: hdt=H5T_NATIVE_FLOAT;
break;
1445 case EMUtil::EM_USHORT: hdt=H5T_NATIVE_USHORT;
break;
1446 case EMUtil::EM_UCHAR: hdt=H5T_NATIVE_UCHAR;
break;
1447 case EMUtil::EM_SHORT: hdt=H5T_NATIVE_SHORT;
break;
1448 case EMUtil::EM_CHAR: hdt=H5T_NATIVE_CHAR;
break;
1449 case EMUtil::EM_COMPRESSED:
1450 if (renderbits<=0) hdt=H5T_NATIVE_FLOAT;
1451 else if (renderbits<=8) hdt=H5T_NATIVE_UCHAR;
1452 else if (renderbits<=16) hdt=H5T_NATIVE_USHORT;
1453 else throw ImageWriteException(filename,
"Bit reduced compressed HDF5 files may not use more than 16 bits. For native float, set 0 bits.");
1459 if (nx==1 && dt==EMUtil::EM_COMPRESSED) {
1460 printf(
"Warning: HDF compressed mode not supported when nx=1\n");
1461 dt=EMUtil::EM_FLOAT;
1465 ds = H5Dopen(file,ipath);
1471 hid_t cpl=H5Dget_create_plist(ds);
1472 H5D_layout_t layout = H5Pget_layout(cpl);
1476 if ((layout==H5D_CHUNKED && dt!=EMUtil::EM_COMPRESSED) || (layout!=H5D_CHUNKED && dt==EMUtil::EM_COMPRESSED)) {
1479 throw ImageWriteException(filename,
"HDF ERROR: Trying to overwrite an image with compression mismatch");
1492 hid_t fdt = H5Dget_type(ds);
1494 if (!H5Tequal(fdt,dt)) {
1498 throw ImageWriteException(filename,
"HDF ERROR: Trying to overwrite an image with different data type");
1505 hid_t plist = H5Pcreate(H5P_DATASET_CREATE);
1506 if (dt==EMUtil::EM_COMPRESSED) {
1508 hsize_t cdims[2] = { ny>256?256:ny, nx>256?256:nx};
1509 H5Pset_chunk(plist,2,cdims);
1512 hsize_t cdims[3] = { 1, ny>256?256:ny, nx>256?256:nx};
1513 H5Pset_chunk(plist,3,cdims);
1517 H5Pset_deflate(plist, renderlevel);
1525 ds=H5Dcreate(file,ipath, hdt, spc, plist );
1530 hid_t spc_file = H5Dget_space(ds);
1531 rank = H5Sget_simple_extent_ndims(spc_file);
1543 hsize_t size = (hsize_t)nx*ny*nz;
1545 unsigned char *ucdata = NULL;
1546 unsigned short *usdata = NULL;
1548 short *sdata = NULL;
1550 EMUtil::getRenderMinMax(data, nx, ny, rendermin, rendermax, renderbits, nz);
1551 int rendertrunc = 0;
1556 float RUMAX = (1<<renderbits)-1.0f;
1557 float RSMIN = -(1<<(renderbits-1));
1558 float RSMAX = (1<<(renderbits-1))-1;
1563 hid_t filespace = H5Dget_space(ds);
1564 hid_t memoryspace = 0;
1577 herr_t err_no = H5Sselect_hyperslab(filespace, H5S_SELECT_SET,
1578 (
const hsize_t*)doffset, NULL, (
const hsize_t*)dcount, NULL);
1581 std::cerr <<
"H5Sselect_hyperslab error: " << err_no << std::endl;
1586 dims[0] = dcount[2]?dcount[2]:1;
1587 dims[1] = dcount[1]?dcount[1]:1;
1588 dims[2] = dcount[0]?dcount[0]:1;
1590 memoryspace = H5Screate_simple(rank, dims, NULL);
1592 else if (rank == 2) {
1601 herr_t err_no = H5Sselect_hyperslab(filespace, H5S_SELECT_SET,
1602 (
const hsize_t*)doffset, NULL, (
const hsize_t*)dcount, NULL);
1605 std::cerr <<
"H5Sselect_hyperslab error: " << err_no << std::endl;
1611 dims[0] = (hsize_t)(dcount[1]?dcount[1]:1);
1612 dims[1] = (hsize_t)(dcount[0]?dcount[0]:1);
1614 memoryspace = H5Screate_simple(rank, dims, NULL);
1617 std::cerr <<
"rank is wrong: " << rank << std::endl;
1622 case EMUtil::EM_FLOAT:
1623 err_no = H5Dwrite(ds, H5T_NATIVE_FLOAT, memoryspace, filespace, H5P_DEFAULT, data);
1626 std::cerr <<
"H5Dwrite error float: " << err_no << std::endl;
1630 case EMUtil::EM_SHORT:
1631 sdata =
new short[size];
1633 for (
size_t i = 0; i < size; ++i) {
1634 if (data[i] <= rendermin) {
1635 sdata[i] = (short)RSMIN;
1638 else if (data[i] >= rendermax) {
1639 sdata[i] = (short)RSMAX;
1643 sdata[i]=(short)roundf((data[i]-rendermin)/(rendermax-rendermin)*(RSMAX-RSMIN)+RSMIN);
1647 err_no = H5Dwrite(ds, H5T_NATIVE_SHORT, memoryspace, filespace, H5P_DEFAULT, sdata);
1650 std::cerr <<
"H5Dwrite error short: " << err_no << std::endl;
1653 if (sdata) {
delete [] sdata; sdata = NULL;}
1657 case EMUtil::EM_USHORT:
1658 usdata =
new unsigned short[size];
1660 for (
size_t i = 0; i < size; ++i) {
1661 if (data[i] <= rendermin) {
1665 else if (data[i] >= rendermax) {
1666 usdata[i] = (
unsigned short)RUMAX;
1670 usdata[i]=(
unsigned short)roundf((data[i]-rendermin)/(rendermax-rendermin)*RUMAX);
1674 err_no = H5Dwrite(ds, H5T_NATIVE_USHORT, memoryspace, filespace, H5P_DEFAULT, usdata);
1677 std::cerr <<
"H5Dwrite error ushort: " << err_no << std::endl;
1680 if (usdata) {
delete [] usdata; usdata = NULL;}
1684 case EMUtil::EM_CHAR:
1685 cdata =
new char[size];
1687 for (
size_t i = 0; i < size; ++i) {
1688 if (data[i] <= rendermin) {
1689 cdata[i] = (char) RSMIN;
1692 else if (data[i] >= rendermax){
1693 cdata[i] = (char) RSMAX;
1697 cdata[i]=(char)roundf((data[i]-rendermin)/(rendermax-rendermin)*(RSMAX-RSMIN)+RSMIN);
1701 err_no = H5Dwrite(ds, H5T_NATIVE_CHAR, memoryspace, filespace, H5P_DEFAULT, cdata);
1704 std::cerr <<
"H5Dwrite error char: " << err_no << std::endl;
1707 if (cdata) {
delete [] cdata; cdata = NULL;}
1711 case EMUtil::EM_UCHAR:
1712 ucdata =
new unsigned char[size];
1714 for (
size_t i = 0; i < size; ++i) {
1715 if (data[i] <= rendermin) {
1719 else if (data[i] >= rendermax){
1720 ucdata[i] = (
unsigned char)RUMAX;
1724 ucdata[i]=(
unsigned char)roundf((data[i]-rendermin)/(rendermax-rendermin)*RUMAX);
1728 err_no = H5Dwrite(ds, H5T_NATIVE_UCHAR, memoryspace, filespace, H5P_DEFAULT, ucdata);
1731 std::cerr <<
"H5Dwrite error uchar: " << err_no << std::endl;
1734 if (ucdata) {
delete [] ucdata; ucdata = NULL;}
1738 case EMUtil::EM_COMPRESSED:
1739 if (renderbits<=0) err_no = H5Dwrite(ds, H5T_NATIVE_FLOAT, memoryspace, filespace, H5P_DEFAULT, data);
1740 else if (renderbits<=8) {
1741 ucdata =
new unsigned char[size];
1743 for (
size_t i = 0; i < size; ++i) {
1744 if (data[i] <= rendermin) {
1748 else if (data[i] >= rendermax){
1749 ucdata[i] = (
unsigned char)RUMAX;
1753 ucdata[i]=(
unsigned char)roundf((data[i]-rendermin)/(rendermax-rendermin)*RUMAX);
1757 err_no = H5Dwrite(ds, H5T_NATIVE_UCHAR, memoryspace, filespace, H5P_DEFAULT, ucdata);
1759 if (ucdata) {
delete [] ucdata; ucdata = NULL;}
1762 usdata =
new unsigned short[size];
1764 for (
size_t i = 0; i < size; ++i) {
1765 if (data[i] <= rendermin) {
1769 else if (data[i] >= rendermax) {
1770 usdata[i] = (
unsigned short)RUMAX;
1774 usdata[i]=(
unsigned short)roundf((data[i]-rendermin)/(rendermax-rendermin)*RUMAX);
1778 err_no = H5Dwrite(ds, H5T_NATIVE_USHORT, memoryspace, filespace, H5P_DEFAULT, usdata);
1780 if (usdata) {
delete [] usdata; usdata = NULL;}
1784 std::cerr <<
"H5Dwrite error compressed: " << err_no << std::endl;
1788 throw ImageWriteException(filename,
"HDF5 does not support region writing for this data format");
1791 H5Sclose(filespace);
1792 H5Sclose(memoryspace);
1796 case EMUtil::EM_FLOAT:
1797 H5Dwrite(ds,H5T_NATIVE_FLOAT,spc,spc,H5P_DEFAULT,data);
1799 case EMUtil::EM_SHORT:
1800 sdata =
new short[size];
1802 for (
size_t i = 0; i < size; ++i) {
1803 if (data[i] <= rendermin) {
1804 sdata[i] = (short)RSMIN;
1807 else if (data[i] >= rendermax) {
1808 sdata[i] = (short)RSMAX;
1812 sdata[i]=(short)roundf((data[i]-rendermin)/(rendermax-rendermin)*(RSMAX-RSMIN)+RSMIN);
1816 H5Dwrite(ds,H5T_NATIVE_SHORT,spc,spc,H5P_DEFAULT,sdata);
1818 if (sdata) {
delete [] sdata; sdata = NULL;}
1822 case EMUtil::EM_USHORT:
1823 usdata =
new unsigned short[size];
1825 for (
size_t i = 0; i < size; ++i) {
1826 if (data[i] <= rendermin) {
1830 else if (data[i] >= rendermax) {
1831 usdata[i] = (
unsigned short)RUMAX;
1835 usdata[i]=(
unsigned short)roundf((data[i]-rendermin)/(rendermax-rendermin)*RUMAX);
1839 H5Dwrite(ds,H5T_NATIVE_USHORT,spc,spc,H5P_DEFAULT,usdata);
1841 if (usdata) {
delete [] usdata; usdata = NULL;}
1845 case EMUtil::EM_CHAR:
1846 cdata =
new char[size];
1848 for (
size_t i = 0; i < size; ++i) {
1849 if (data[i] <= rendermin) {
1850 cdata[i] = (char) RSMIN;
1853 else if (data[i] >= rendermax){
1854 cdata[i] = (char) RSMAX;
1858 cdata[i]=(char)roundf((data[i]-rendermin)/(rendermax-rendermin)*(RSMAX-RSMIN)+RSMIN);
1862 H5Dwrite(ds,H5T_NATIVE_CHAR,spc,spc,H5P_DEFAULT,cdata);
1864 if (cdata) {
delete [] cdata; cdata = NULL;}
1868 case EMUtil::EM_UCHAR:
1869 ucdata =
new unsigned char[size];
1871 for (
size_t i = 0; i < size; ++i) {
1872 if (data[i] <= rendermin) {
1876 else if (data[i] >= rendermax){
1877 ucdata[i] = (
unsigned char)RUMAX;
1881 ucdata[i]=(
unsigned char)roundf((data[i]-rendermin)/(rendermax-rendermin)*RUMAX);
1885 H5Dwrite(ds,H5T_NATIVE_UCHAR,spc,spc,H5P_DEFAULT,ucdata);
1887 if (ucdata) {
delete [] ucdata; ucdata = NULL;}
1891 case EMUtil::EM_COMPRESSED:
1893 if (renderbits<=0) err_no = H5Dwrite(ds,H5T_NATIVE_FLOAT,spc,spc,H5P_DEFAULT,data);
1894 else if (renderbits<=8) {
1895 ucdata =
new unsigned char[size];
1897 for (
size_t i = 0; i < size; ++i) {
1898 if (data[i] <= rendermin) {
1902 else if (data[i] >= rendermax) {
1903 ucdata[i] = (
unsigned char)RUMAX;
1907 ucdata[i]=(
unsigned char)roundf((data[i]-rendermin)/(rendermax-rendermin)*RUMAX);
1911 err_no = H5Dwrite(ds,H5T_NATIVE_UCHAR,spc,spc,H5P_DEFAULT,ucdata);
1913 if (ucdata) {
delete [] ucdata; ucdata = NULL;}
1916 usdata =
new unsigned short[size];
1918 for (
size_t i = 0; i < size; ++i) {
1919 if (data[i] <= rendermin) {
1923 else if (data[i] >= rendermax) {
1924 usdata[i] = (
unsigned short)RUMAX;
1928 usdata[i]=(
unsigned short)roundf((data[i]-rendermin)/(rendermax-rendermin)*RUMAX);
1932 err_no = H5Dwrite(ds,H5T_NATIVE_USHORT,spc,spc,H5P_DEFAULT,usdata);
1934 if (usdata) {
delete [] usdata; usdata = NULL;}
1938 printf(
"%d %f %f\n",renderbits,rendermin,rendermax);
1939 std::cerr <<
"H5Dwrite error compressed full: " << err_no << std::endl;
1952 sprintf(ipath,
"/MDF/images/%d",image_index);
1953 hid_t igrp=H5Gopen(file,ipath);
1954 write_attr(igrp,
"EMAN.stored_rendermin",
EMObject(rendermin));
1955 write_attr(igrp,
"EMAN.stored_rendermax",
EMObject(rendermax));
1956 write_attr(igrp,
"EMAN.stored_renderbits",
EMObject(renderbits));
1957 write_attr(igrp,
"EMAN.stored_truncated",
EMObject(rendertrunc));
1966int HdfIO2::get_nimg()
1969 hid_t attr=H5Aopen_name(group,
"imageid_max");
1970 int n = read_attr(attr);
1981bool HdfIO2::is_complex_mode()
1987bool HdfIO2::is_image_big_endian()
Ctf is the base class for all CTF model.
Dict is a dictionary to store <string, EMObject> pair.
vector< EMObject > values() const
Get a vector containing copies of each of the EMObjects in this dictionary.
bool has_key(const string &key) const
Ask the Dictionary if it as a particular key.
vector< string > keys() const
Get a vector containing all of the (string) keys in this dictionary.
EMObject is a wrapper class for types including int, float, double, etc as defined in ObjectType.
ObjectType get_type() const
Get the ObjectType This is an enumerated type first declared in the class EMObjectTypes.
EMDataType
Image pixel data type used in EMAN.
ImageIO classes are designed for reading/writing various electron micrography image formats,...
IntSize is used to describe a 1D, 2D or 3D rectangular size in integers.
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
float get_width() const
get the width
float y_origin() const
get the y element of the origin
float x_origin() const
get the x element of the origin
float get_depth() const
get the depth
float z_origin() const
get the z element of the origin
float get_height() const
get the height
static const int ATTR_NAME_LEN
#define ImageReadException(filename, desc)
#define FileAccessException(filename)
#define ImageWriteException(imagename, desc)