00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifdef EM_HDF5
00037
00038
00039
00040 #include "hdfio2.h"
00041 #include "geometry.h"
00042 #include "ctf.h"
00043 #include "emassert.h"
00044 #include "transform.h"
00045 #include "ctf.h"
00046 #include <iostream>
00047 #include <cstring>
00048
00049 #ifndef WIN32
00050 #include <sys/param.h>
00051 #else
00052 #define MAXPATHLEN (MAX_PATH * 4)
00053 #endif //WIN32
00054
00055 using namespace EMAN;
00056
00057 static const int ATTR_NAME_LEN = 128;
00058
00059 HdfIO2::HdfIO2(const string & hdf_filename, IOMode rw)
00060 : file(-1), group(-1), filename(hdf_filename),
00061 rw_mode(rw), initialized(false)
00062 {
00063 accprop=H5Pcreate(H5P_FILE_ACCESS);
00064
00065
00066 H5Pset_fapl_sec2( accprop );
00067
00068
00069
00070
00071 hsize_t dims=1;
00072 simple_space=H5Screate_simple(1,&dims,NULL);
00073 }
00074
00075 HdfIO2::~HdfIO2()
00076 {
00077 H5Sclose(simple_space);
00078 H5Pclose(accprop);
00079 if (group >= 0) {
00080 H5Gclose(group);
00081 }
00082 if (file >= 0) {
00083 H5Fflush(file,H5F_SCOPE_GLOBAL);
00084 H5Fclose(file);
00085 }
00086 #ifdef DEBUGHDF
00087 printf("HDf close\n");
00088 #endif
00089 }
00090
00091
00092
00093 EMObject HdfIO2::read_attr(hid_t attr) {
00094 hid_t type = H5Aget_type(attr);
00095 hid_t spc = H5Aget_space(attr);
00096 H5T_class_t cls = H5Tget_class(type);
00097 size_t sz = H5Tget_size(type);
00098 hssize_t pts = H5Sget_simple_extent_npoints(spc);
00099
00100 EMObject ret(0);
00101 char c;
00102 int i;
00103
00104 float f,*fa;
00105 int * ia;
00106
00107 double d;
00108 char *s;
00109 vector <float> fv((size_t)pts);
00110 vector <int> iv((size_t)pts);
00111
00112
00113 float *matrix;
00114 Transform* t;
00115 Ctf* ctf;
00116
00117
00118 switch (cls) {
00119 case H5T_INTEGER:
00120 if(sz==1) {
00121 H5Aread(attr,H5T_NATIVE_CHAR,&c);
00122 bool b = false;
00123 if(c=='T') {
00124 b = true;
00125 }
00126 else if(c=='F') {
00127 b = false;
00128 }
00129 ret = EMObject(b);
00130 }
00131 else if(sz==4) {
00132 if(pts==1) {
00133 H5Aread(attr,H5T_NATIVE_INT,&i);
00134 ret=EMObject(i);
00135 }
00136 else {
00137 ia=(int *)malloc((size_t)pts*sizeof(int));
00138 H5Aread(attr,H5T_NATIVE_INT,ia);
00139 for (i=0; i<pts; i++) iv[i]=ia[i];
00140 free(ia);
00141 ret=EMObject(iv);
00142 }
00143 }
00144 break;
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 case H5T_FLOAT:
00159 if (sz==4) {
00160 if (pts==1) {
00161 H5Aread(attr,H5T_NATIVE_FLOAT,&f);
00162 ret=EMObject(f);
00163 }
00164 else {
00165 fa=(float *)malloc((size_t)pts*sizeof(float));
00166 H5Aread(attr,H5T_NATIVE_FLOAT,fa);
00167 for (i=0; i<pts; i++) fv[i]=fa[i];
00168 free(fa);
00169 ret=EMObject(fv);
00170 }
00171 }
00172 else if (sz==8) {
00173 H5Aread(attr,H5T_NATIVE_DOUBLE,&d);
00174 ret=EMObject(d);
00175 }
00176 break;
00177 case H5T_STRING:
00178 s=(char *)malloc(sz+1);
00179 H5Aread(attr,type,s);
00180
00181 if(s[0] == 'O' && isdigit(s[1])) {
00182 ctf = new EMAN1Ctf();
00183 ctf->from_string(string(s));
00184 ret = EMObject(ctf);
00185 delete ctf;
00186 }
00187 else if(s[0] == 'E' && isdigit(s[1])) {
00188 ctf = new EMAN2Ctf();
00189 ctf->from_string(string(s));
00190 ret = EMObject(ctf);
00191 delete ctf;
00192 }
00193 else {
00194 ret=EMObject(s);
00195 }
00196 free(s);
00197 break;
00198 case H5T_COMPOUND:
00199 matrix = (float*)malloc(12*sizeof(float));
00200 H5Aread(attr, type, matrix);
00201
00202 t = new Transform(matrix);
00203 ret = EMObject(t);
00204 free(matrix);
00205 delete t; t=0;
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 break;
00220 default:
00221 LOGERR("Unhandled HDF5 metadata %d", cls);
00222 }
00223
00224 H5Sclose(spc);
00225 H5Tclose(type);
00226
00227 return ret;
00228 }
00229
00230
00231
00232 int HdfIO2::write_attr(hid_t loc,const char *name,EMObject obj) {
00233 hid_t type=0;
00234 hid_t spc=0;
00235 hsize_t dims=1;
00236 vector <float> fv;
00237 vector <int> iv;
00238 switch(obj.get_type())
00239 {
00240 case EMObject::BOOL:
00241 type=H5Tcopy(H5T_NATIVE_CHAR);
00242 spc=H5Scopy(simple_space);
00243 break;
00244 case EMObject::INT:
00245 type=H5Tcopy(H5T_NATIVE_INT);
00246 spc=H5Scopy(simple_space);
00247 break;
00248 case EMObject::UNSIGNEDINT:
00249 type=H5Tcopy(H5T_NATIVE_UINT);
00250 spc=H5Scopy(simple_space);
00251 break;
00252 case EMObject::FLOAT:
00253 type=H5Tcopy(H5T_NATIVE_FLOAT);
00254 spc=H5Scopy(simple_space);
00255 break;
00256 case EMObject::DOUBLE:
00257 type=H5Tcopy(H5T_NATIVE_DOUBLE);
00258 spc=H5Scopy(simple_space);
00259 break;
00260 case EMObject::STRING:
00261 case EMObject::CTF:
00262 type=H5Tcopy(H5T_C_S1);
00263 H5Tset_size(type,strlen((const char *)obj)+1);
00264 spc=H5Screate(H5S_SCALAR);
00265 break;
00266 case EMObject::FLOATARRAY:
00267 type=H5Tcopy(H5T_NATIVE_FLOAT);
00268 fv=obj;
00269 dims=fv.size();
00270 spc=H5Screate_simple(1,&dims,NULL);
00271 break;
00272 case EMObject::INTARRAY:
00273 type=H5Tcopy(H5T_NATIVE_INT);
00274 iv=obj;
00275 dims=iv.size();
00276 spc=H5Screate_simple(1,&dims,NULL);
00277 break;
00278 case EMObject::TRANSFORM:
00279 type = H5Tcreate(H5T_COMPOUND, 12 * sizeof(float));
00280 H5Tinsert(type, "00", 0, H5T_NATIVE_FLOAT);
00281 H5Tinsert(type, "01", 1*sizeof(float), H5T_NATIVE_FLOAT);
00282 H5Tinsert(type, "02", 2*sizeof(float), H5T_NATIVE_FLOAT);
00283 H5Tinsert(type, "03", 3*sizeof(float), H5T_NATIVE_FLOAT);
00284 H5Tinsert(type, "10", 4*sizeof(float), H5T_NATIVE_FLOAT);
00285 H5Tinsert(type, "11", 5*sizeof(float), H5T_NATIVE_FLOAT);
00286 H5Tinsert(type, "12", 6*sizeof(float), H5T_NATIVE_FLOAT);
00287 H5Tinsert(type, "13", 7*sizeof(float), H5T_NATIVE_FLOAT);
00288 H5Tinsert(type, "20", 8*sizeof(float), H5T_NATIVE_FLOAT);
00289 H5Tinsert(type, "21", 9*sizeof(float), H5T_NATIVE_FLOAT);
00290 H5Tinsert(type, "22", 10*sizeof(float), H5T_NATIVE_FLOAT);
00291 H5Tinsert(type, "23", 11*sizeof(float), H5T_NATIVE_FLOAT);
00292 H5Tpack(type);
00293
00294 dims = 1;
00295 spc = H5Screate_simple(1, &dims, NULL);
00296 break;
00297 case EMObject::STRINGARRAY:
00298 case EMObject::EMDATA:
00299 case EMObject::XYDATA:
00300 case EMObject::FLOAT_POINTER:
00301 case EMObject::INT_POINTER:
00302 case EMObject::VOID_POINTER:
00303 return -1;
00304 break;
00305 case EMObject::UNKNOWN:
00306 break;
00307 }
00308
00309
00310
00311 if( H5Adelete(loc,name) < 0 ) {
00312 #ifdef DEBUGHDF
00313 LOGERR("Attribute %s deletion error in write_attr().\n", name);
00314 #endif
00315 }
00316 else {
00317 #ifdef DEBUGHDF
00318 printf("delete attribute %s successfully in write_attr().\n", name);
00319 #endif
00320 }
00321 hid_t attr = H5Acreate(loc,name,type,spc,H5P_DEFAULT);
00322
00323 bool b;
00324 char c;
00325 int i;
00326 float f,*fa;
00327 int * ia;
00328 unsigned int ui;
00329 double d;
00330 const char *s;
00331 Transform * tp;
00332 switch(obj.get_type()) {
00333 case EMObject::BOOL:
00334 b = (bool)obj;
00335 if(b) {
00336 c = 'T';
00337 } else {
00338 c = 'F';
00339 }
00340 H5Awrite(attr,type,&c);
00341 break;
00342 case EMObject::INT:
00343 i=(int)obj;
00344 H5Awrite(attr,type,&i);
00345 break;
00346 case EMObject::UNSIGNEDINT:
00347 ui=(unsigned int)obj;
00348 H5Awrite(attr,type,&ui);
00349 break;
00350 case EMObject::FLOAT:
00351 f=(float)obj;
00352 H5Awrite(attr,type,&f);
00353 break;
00354 case EMObject::DOUBLE:
00355 d=(double)obj;
00356 H5Awrite(attr,type,&d);
00357 break;
00358 case EMObject::STRING:
00359 case EMObject::CTF:
00360 s=(const char *)obj;
00361 H5Awrite(attr,type,s);
00362 break;
00363 case EMObject::FLOATARRAY:
00364 fa=(float *)malloc(fv.size()*sizeof(float));
00365 for (ui=0; ui<fv.size(); ui++) fa[ui]=fv[ui];
00366 H5Awrite(attr,type,fa);
00367 free(fa);
00368 break;
00369 case EMObject::INTARRAY:
00370 ia=(int *)malloc(iv.size()*sizeof(int));
00371 for (ui=0; ui<iv.size(); ui++) ia[ui]=iv[ui];
00372 H5Awrite(attr,type,ia);
00373 free(ia);
00374 break;
00375 case EMObject::TRANSFORM:
00376 {
00377 tp = (Transform *)obj;
00378 fa = (float *)malloc(12*sizeof(float));
00379 int r, c, k=0;
00380 for(r=0; r<3; ++r) {
00381 for(c=0; c<4; ++c) {
00382 fa[k] = tp->at(r,c);
00383 ++k;
00384 }
00385 }
00386 H5Awrite(attr,type,fa);
00387 free(fa);
00388 }
00389 break;
00390
00391
00392
00393
00394
00395 default:
00396 LOGERR("Unhandled HDF5 metadata '%s'", name);
00397
00398 }
00399
00400 herr_t ret1 = H5Tclose(type);
00401 herr_t ret2 = H5Sclose(spc);
00402 herr_t ret3 = H5Aclose(attr);
00403 if(ret1>=0 && ret2>=0 && ret3>=0) {
00404 return 0;
00405 }
00406 else {
00407 LOGERR("close error in write_attr()\n");
00408 return -1;
00409 }
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 void HdfIO2::init()
00421 {
00422 ENTERFUNC;
00423 if (initialized) {
00424 return;
00425 }
00426 #ifdef DEBUGHDF
00427 printf("init\n");
00428 #endif
00429
00430 H5Eset_auto(0, 0);
00431
00432 if (rw_mode == READ_ONLY) {
00433 file = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, accprop);
00434 if (file<0) throw FileAccessException(filename);
00435 }
00436 else {
00437 file = H5Fopen(filename.c_str(), H5F_ACC_RDWR, accprop);
00438 if (file < 0) {
00439 file = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, accprop);
00440 if (file < 0) {
00441 throw FileAccessException(filename);
00442 }
00443 else {
00444 #ifdef DEBUGHDF
00445 printf("File truncated or new file created\n");
00446 #endif
00447 }
00448 }
00449 }
00450
00451 group=H5Gopen(file,"/MDF/images");
00452 if (group<0) {
00453 if (rw_mode == READ_ONLY) throw ImageReadException(filename,"HDF5 file has no image data (no /MDF group)");
00454 group=H5Gcreate(file,"/MDF",64);
00455 if (group<0) throw ImageWriteException(filename,"Unable to add image group (/MDF) to HDF5 file");
00456 H5Gclose(group);
00457 group=H5Gcreate(file,"/MDF/images",4096);
00458 if (group<0) throw ImageWriteException(filename,"Unable to add image group (/MDF/images) to HDF5 file");
00459 write_attr(group,"imageid_max",EMObject(-1));
00460 }
00461 initialized = true;
00462 EXITFUNC;
00463 }
00464
00465
00466
00467 int HdfIO2::init_test()
00468 {
00469 ENTERFUNC;
00470 if (initialized) {
00471 return 1;
00472 }
00473 #ifdef DEBUGHDF
00474 printf("init_test\n");
00475 #endif
00476
00477 H5Eset_auto(0, 0);
00478
00479 hid_t fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5Pcreate(H5P_FILE_ACCESS));
00480 hid_t groupid = H5Gopen(fileid, "/");
00481 hid_t attid = H5Aopen_name(groupid, "num_dataset");
00482
00483 if (attid < 0) {
00484 H5Gclose(groupid);
00485 H5Fclose(fileid);
00486 init();
00487 EXITFUNC;
00488 return 0;
00489 }
00490 else {
00491 H5Aclose(attid);
00492 H5Gclose(groupid);
00493 H5Fclose(fileid);
00494 EXITFUNC;
00495 return -1;
00496 }
00497 }
00498
00499 bool HdfIO2::is_valid(const void *first_block)
00500 {
00501 ENTERFUNC;
00502
00503 if (first_block) {
00504 char signature[8] = { 137,72,68,70,13,10,26,10 };
00505 if (strncmp((const char *)first_block,signature,8)==0) return true;
00506
00507
00508 return false;
00509 }
00510 EXITFUNC;
00511 return false;
00512 }
00513
00514
00515 int HdfIO2::read_header(Dict & dict, int image_index, const Region * area, bool)
00516 {
00517 ENTERFUNC;
00518 init();
00519 #ifdef DEBUGHDF
00520 printf("read_head %d\n", image_index);
00521 #endif
00522 int i;
00523
00524 char ipath[50];
00525 sprintf(ipath,"/MDF/images/%d", image_index);
00526 hid_t igrp=H5Gopen(file, ipath);
00527
00528 int nattr=H5Aget_num_attrs(igrp);
00529
00530 char name[ATTR_NAME_LEN];
00531 for (i=0; i<nattr; i++) {
00532 hid_t attr=H5Aopen_idx(igrp, i);
00533 H5Aget_name(attr,127,name);
00534 if (strncmp(name,"EMAN.", 5)!=0) {
00535 H5Aclose(attr);
00536 continue;
00537 }
00538 EMObject val=read_attr(attr);
00539 dict[name+5]=val;
00540 H5Aclose(attr);
00541 }
00542
00543 if(dict.has_key("ctf")) {
00544 string ctfString = (string)dict["ctf"];
00545 if(ctfString.substr(0, 1) == "O") {
00546 Ctf * ctf_ = new EMAN1Ctf();
00547 ctf_->from_string(ctfString);
00548 dict.erase("ctf");
00549 dict["ctf"] = ctf_;
00550 delete ctf_;
00551 }
00552 else if(ctfString.substr(0, 1) == "E") {
00553 Ctf * ctf_ = new EMAN2Ctf();
00554 ctf_->from_string(ctfString);
00555 dict.erase("ctf");
00556 dict["ctf"] = ctf_;
00557 delete ctf_;
00558 }
00559 }
00560
00561 if(area) {
00562 check_region(area, IntSize(dict["nx"], dict["ny"], dict["nz"]), false, false);
00563
00564 dict["nx"] = area->get_width();
00565 dict["ny"] = area->get_height();
00566 dict["nz"] = area->get_depth();
00567
00568 if( dict.has_key("apix_x") && dict.has_key("apix_y") && dict.has_key("apix_z") )
00569 {
00570 if( dict.has_key("origin_x") && dict.has_key("origin_y") && dict.has_key("origin_z") )
00571 {
00572 float xorigin = dict["origin_x"];
00573 float yorigin = dict["origin_y"];
00574 float zorigin = dict["origin_z"];
00575
00576 float apix_x = dict["apix_x"];
00577 float apix_y = dict["apix_y"];
00578 float apix_z = dict["apix_z"];
00579
00580 dict["origin_x"] = xorigin + apix_x * area->origin[0];
00581 dict["origin_y"] = yorigin + apix_y * area->origin[1];
00582 dict["origin_z"] = zorigin + apix_z * area->origin[2];
00583 }
00584 }
00585 }
00586
00587 H5Gclose(igrp);
00588 EXITFUNC;
00589 return 0;
00590 }
00591
00592
00593
00594
00595 int HdfIO2::erase_header(int image_index)
00596 {
00597 ENTERFUNC;
00598
00599 if(image_index < 0) return 0;
00600
00601 init();
00602 #ifdef DEBUGHDF
00603 printf("erase_head %d\n",image_index);
00604 #endif
00605 int i;
00606
00607 char ipath[50];
00608 sprintf(ipath,"/MDF/images/%d", image_index);
00609 hid_t igrp=H5Gopen(file, ipath);
00610
00611 int nattr=H5Aget_num_attrs(igrp);
00612
00613 char name[ATTR_NAME_LEN];
00614 for (i=0; i<nattr; i++) {
00615 hid_t attr = H5Aopen_idx(igrp, 0);
00616 H5Aget_name(attr,127,name);
00617 H5Aclose(attr);
00618 if( H5Adelete(igrp,name) < 0 ) {
00619 LOGERR("attribute %s deletion error in erase_header().\n", name);
00620 }
00621 }
00622
00623 H5Gclose(igrp);
00624 EXITFUNC;
00625 return 0;
00626 }
00627
00628
00629 int HdfIO2::read_data(float *data, int image_index, const Region *area, bool)
00630 {
00631 ENTERFUNC;
00632 #ifdef DEBUGHDF
00633 printf("read_data %d\n",image_index);
00634 #endif
00635
00636 char ipath[50];
00637 sprintf(ipath,"/MDF/images/%d/image",image_index);
00638 hid_t ds=H5Dopen(file,ipath);
00639 if (ds<0) throw ImageWriteException(filename,"Image does not exist");
00640 hid_t spc=H5Dget_space(ds);
00641
00642 hsize_t nx = 1, ny = 1, nz = 1;
00643 hsize_t dims_out[3];
00644 hsize_t rank = H5Sget_simple_extent_ndims(spc);
00645
00646 H5Sget_simple_extent_dims(spc, dims_out, NULL);
00647 if(rank == 1) {
00648 nx = dims_out[0];
00649 ny = 1;
00650 nz = 1;
00651 }
00652 else if(rank == 2) {
00653 nx = dims_out[1];
00654 ny = dims_out[0];
00655 nz = 1;
00656 }
00657 else if(rank == 3) {
00658 nx = dims_out[2];
00659 ny = dims_out[1];
00660 nz = dims_out[0];
00661 }
00662
00663 if (area) {
00664 hid_t memoryspace = 0;
00665
00666
00667 int x0 = 0, y0 = 0, z0 = 0;
00668 int x1 = 0, y1 = 0, z1 = 0;
00669 int nx1 = 1, ny1 = 1, nz1 = 1;
00670 if(rank == 3) {
00671 hsize_t doffset[3];
00672 doffset[2] = (hsize_t)(area->x_origin() < 0 ? 0 : area->x_origin());
00673 doffset[1] = (hsize_t)(area->y_origin() < 0 ? 0 : area->y_origin());
00674 doffset[0] = (hsize_t)(area->z_origin() < 0 ? 0 : area->z_origin());
00675 x0 = (int)doffset[0];
00676 y0 = (int)doffset[1];
00677 z0 = (int)doffset[2];
00678
00679 z1 = (int)(area->x_origin() + area->get_width());
00680 z1 = (int)(z1 > static_cast<int>(nx) ? nx : z1);
00681
00682 y1 = (int)(area->y_origin() + area->get_height());
00683 y1 = (int)(y1 > static_cast<int>(ny) ? ny : y1);
00684 if(y1 <= 0) {
00685 y1 = 1;
00686 }
00687
00688 x1 = (int)(area->z_origin() + area->get_depth());
00689 x1 = (int)(x1 > static_cast<int>(nz) ? nz : x1);
00690 if(x1 <= 0) {
00691 x1 = 1;
00692 }
00693
00694 if(x1 < x0 || y1< y0 || z1 < z0) return 0;
00695
00696 hsize_t dcount[3];
00697 dcount[0] = x1 - doffset[0];
00698 dcount[1] = y1 - doffset[1];
00699 dcount[2] = z1 - doffset[2];
00700
00701 H5Sselect_hyperslab (spc, H5S_SELECT_SET, (const hsize_t*)doffset, NULL, (const hsize_t*)dcount, NULL);
00702
00703
00704 hsize_t dims[3];
00705 dims[0] = dcount[2]?dcount[2]:1;
00706 dims[1] = dcount[1]?dcount[1]:1;
00707 dims[2] = dcount[0]?dcount[0]:1;
00708 nx1 = (int)dims[0];
00709 ny1 = (int)dims[1];
00710 nz1 = (int)dims[2];
00711
00712 memoryspace = H5Screate_simple(3, dims, NULL);
00713 }
00714 else if(rank == 2) {
00715 hsize_t doffset[2];
00716 doffset[1] = (hsize_t)(area->x_origin() < 0 ? 0 : area->x_origin());
00717 doffset[0] = (hsize_t)(area->y_origin() < 0 ? 0 : area->y_origin());
00718 x0 = (int)doffset[0];
00719 y0 = (int)doffset[1];
00720 z0 = 1;
00721
00722 y1 = (int)(area->x_origin() + area->get_width());
00723 y1 = (int)(y1 > static_cast<int>(nx) ? nx : y1);
00724
00725 x1 = (int)(area->y_origin() + area->get_height());
00726 x1 = (int)(x1 > static_cast<int>(ny) ? ny : x1);
00727 if(x1 <= 0) {
00728 x1 = 1;
00729 }
00730
00731 z1 = 1;
00732
00733 if(x1 < x0 || y1< y0) return 0;
00734
00735 hsize_t dcount[2];
00736 dcount[0] = x1 - doffset[0];
00737 dcount[1] = y1 - doffset[1];
00738
00739 H5Sselect_none(spc);
00740 H5Sselect_hyperslab (spc, H5S_SELECT_SET, (const hsize_t*)doffset, NULL, (const hsize_t*)dcount, NULL);
00741
00742
00743 hsize_t dims[2];
00744 dims[0] = (hsize_t)(dcount[1]?dcount[1]:1);
00745 dims[1] = (hsize_t)(dcount[0]?dcount[0]:1);
00746 nx1 = (int)dims[0];
00747 ny1 = (int)dims[1];
00748 nz1 = 1;
00749
00750 memoryspace = H5Screate_simple(2, dims, NULL);
00751 }
00752
00753 if( (area->x_origin()>=0) && (area->y_origin()>=0) && (area->z_origin()>=0) && ((hsize_t)(area->x_origin() + area->get_width())<=nx) && ((hsize_t)(area->y_origin() + area->get_height())<=ny) && ((hsize_t)(area->z_origin() + area->get_depth())<=nz) ){
00754 H5Dread(ds,H5T_NATIVE_FLOAT,memoryspace,spc,H5P_DEFAULT,data);
00755 }
00756 else {
00757
00758
00759
00760
00761
00762 float * subdata = new float[nx1*ny1*nz1];
00763
00764
00765 H5Dread(ds,H5T_NATIVE_FLOAT,memoryspace,spc,H5P_DEFAULT,subdata);
00766
00767 int xd0=0, yd0=0, zd0=0;
00768 size_t clipped_row_size = 0;
00769 if(rank == 3) {
00770 xd0 = (int) (area->x_origin() < 0 ? -area->x_origin() : 0);
00771 yd0 = (int) (area->y_origin() < 0 ? -area->y_origin() : 0);
00772 zd0 = (int) (area->z_origin() < 0 ? -area->z_origin() : 0);
00773 clipped_row_size = (z1-z0)* sizeof(float);
00774 }
00775 else if(rank == 2) {
00776 xd0 = (int) (area->x_origin() < 0 ? -area->x_origin() : 0);
00777 yd0 = (int) (area->y_origin() < 0 ? -area->y_origin() : 0);
00778 clipped_row_size = (y1-y0)* sizeof(float);
00779 }
00780
00781 int src_secsize = nx1 * ny1;
00782 int dst_secsize = (int)(area->get_width())*(int)(area->get_height());
00783
00784 float * src = subdata;
00785 float * dst = data + zd0*dst_secsize + yd0*(int)(area->get_width()) + xd0;
00786
00787 int src_gap = src_secsize - (y1-y0) * nx1;
00788 int dst_gap = dst_secsize - (y1-y0) * (int)(area->get_width());
00789
00790 for(int i = 0; i<nz1; ++i) {
00791 for(int j = 0; j<ny1; ++j) {
00792 EMUtil::em_memcpy(dst, src, clipped_row_size);
00793
00794 src += nx1;
00795 dst += (int)(area->get_width());
00796 }
00797 src += src_gap;
00798 dst += dst_gap;
00799 }
00800
00801 delete [] subdata;
00802 }
00803 H5Sclose(memoryspace);
00804 } else {
00805 H5Dread(ds,H5T_NATIVE_FLOAT,spc,spc,H5P_DEFAULT,data);
00806 }
00807
00808 H5Sclose(spc);
00809 H5Dclose(ds);
00810 EXITFUNC;
00811 return 0;
00812 }
00813
00814
00815
00816
00817 int HdfIO2::write_header(const Dict & dict, int image_index, const Region* area,
00818 EMUtil::EMDataType, bool)
00819 {
00820 #ifdef DEBUGHDF
00821 printf("write_head %d\n",image_index);
00822 #endif
00823 ENTERFUNC;
00824 init();
00825
00826 if(image_index<0) {
00827 image_index = get_nimg();
00828 }
00829
00830
00831
00832 hid_t attr=H5Aopen_name(group,"imageid_max");
00833 int nimg = read_attr(attr);
00834 H5Aclose(attr);
00835
00836 unsigned int i;
00837 if (image_index<0) image_index=nimg+1;
00838 if (image_index>nimg) {
00839 write_attr(group,(const char *)"imageid_max",EMObject(image_index));
00840 }
00841
00842
00843 char ipath[50];
00844 sprintf(ipath,"/MDF/images/%d",image_index);
00845 hid_t igrp=H5Gopen(file,ipath);
00846
00847 if (igrp<0) {
00848
00849 igrp=H5Gcreate(file,ipath,64);
00850 if (igrp<0) throw ImageWriteException(filename,"Unable to add /MDF/images/# to HDF5 file");
00851
00852 sprintf(ipath,"/MDF/images/%d/image",image_index);
00853
00854 hid_t space;
00855 hid_t ds;
00856 if ((int)dict["nz"]==1) {
00857 hsize_t dims[2]= { (int)dict["ny"],(int)dict["nx"] };
00858 space=H5Screate_simple(2,dims,NULL);
00859 }
00860 else {
00861 hsize_t dims[3]= { (int)dict["nz"],(int)dict["ny"],(int)dict["nx"] };
00862 space=H5Screate_simple(3,dims,NULL);
00863 }
00864 ds=H5Dcreate(file,ipath, H5T_NATIVE_FLOAT, space, H5P_DEFAULT );
00865 H5Dclose(ds);
00866 H5Sclose(space);
00867 }
00868
00869
00870 else {
00871 int nattr=H5Aget_num_attrs(igrp);
00872 char name[ATTR_NAME_LEN];
00873 Dict dict2;
00874 for (int i=0; i<nattr; i++) {
00875 hid_t attr=H5Aopen_idx(igrp, i);
00876 H5Aget_name(attr,127,name);
00877 if (strncmp(name,"EMAN.", 5)!=0) {
00878 H5Aclose(attr);
00879 continue;
00880 }
00881 EMObject val=read_attr(attr);
00882 dict2[name+5]=val;
00883 H5Aclose(attr);
00884 }
00885
00886 erase_header(image_index);
00887
00888 if((int)dict["nx"]!=(int)dict2["nx"]
00889 || (int)dict["ny"]!=(int)dict2["ny"]
00890 || (int)dict["nz"]!=(int)dict2["nz"]) {
00891 sprintf(ipath,"/MDF/images/%d/image",image_index);
00892 H5Gunlink(igrp, ipath);
00893
00894
00895 hid_t space;
00896 hid_t ds;
00897 if ((int)dict["nz"]==1) {
00898 hsize_t dims[2]= { (int)dict["ny"],(int)dict["nx"] };
00899 space=H5Screate_simple(2,dims,NULL);
00900 }
00901 else {
00902 hsize_t dims[3]= { (int)dict["nz"],(int)dict["ny"],(int)dict["nx"] };
00903 space=H5Screate_simple(3,dims,NULL);
00904 }
00905 ds=H5Dcreate(file,ipath, H5T_NATIVE_FLOAT, space, H5P_DEFAULT );
00906 H5Dclose(ds);
00907 H5Sclose(space);
00908 }
00909 }
00910
00911 if(area) {
00912 check_region(area, IntSize(dict["nx"], dict["ny"], dict["nz"]), false, true);
00913 }
00914
00915
00916 vector <string> keys=dict.keys();
00917
00918 for (i=0; i<keys.size(); i++) {
00919 string s("EMAN.");
00920 s+=keys[i];
00921 write_attr(igrp,s.c_str(),dict[keys[i]]);
00922 }
00923
00924 H5Gclose(igrp);
00925 EXITFUNC;
00926 return 0;
00927 }
00928
00929
00930 int HdfIO2::write_data(float *data, int image_index, const Region* area,
00931 EMUtil::EMDataType dt, bool)
00932 {
00933 ENTERFUNC;
00934
00935 #ifdef DEBUGHDF
00936 printf("write_data %d\n",image_index);
00937 #endif
00938 if (dt!=EMUtil::EM_FLOAT) throw ImageWriteException(filename,"HDF5 write only supports float format");
00939
00940 if (image_index<0) {
00941 hid_t attr=H5Aopen_name(group,"imageid_max");
00942 image_index = read_attr(attr);
00943 H5Aclose(attr);
00944 }
00945
00946 char ipath[50];
00947 sprintf(ipath,"/MDF/images/%d/image",image_index);
00948 hid_t ds=H5Dopen(file,ipath);
00949 if (ds<0) throw ImageWriteException(filename,"Image dataset does not exist");
00950
00951 hid_t spc=H5Dget_space(ds);
00952 if(area) {
00953 hsize_t doffset[3];
00954 doffset[0] = (hsize_t)(area->x_origin());
00955 doffset[1] = (hsize_t)(area->y_origin());
00956 doffset[2] = (hsize_t)(area->z_origin());
00957
00958 hsize_t dcount[3];
00959 dcount[0] = (hsize_t)(area->get_width());
00960 dcount[1] = (hsize_t)(area->get_height()?area->get_height():1);
00961 dcount[2] = (hsize_t)(area->get_depth()?area->get_depth():1);
00962
00963 H5Sselect_hyperslab(spc, H5S_SELECT_SET, (const hsize_t*)doffset, NULL, (const hsize_t*)dcount, NULL);
00964
00965
00966 hsize_t dims[3];
00967 dims[0] = (hsize_t)(area->get_width());
00968 dims[1] = (hsize_t)(area->get_height()?area->get_height():1);
00969 dims[2] = (hsize_t)(area->get_depth()?area->get_depth():1);
00970
00971 hid_t memoryspace = H5Screate_simple(3, dims, NULL);
00972 H5Dwrite(ds, H5T_NATIVE_FLOAT, memoryspace, spc, H5P_DEFAULT, data);
00973 H5Sclose(memoryspace);
00974 }
00975 else {
00976 H5Dwrite(ds,H5T_NATIVE_FLOAT,spc,spc,H5P_DEFAULT,data);
00977 }
00978
00979 H5Sclose(spc);
00980 H5Dclose(ds);
00981 EXITFUNC;
00982 return 0;
00983 }
00984
00985 int HdfIO2::get_nimg()
00986 {
00987 init();
00988 hid_t attr=H5Aopen_name(group,"imageid_max");
00989 int n = read_attr(attr);
00990 H5Aclose(attr);
00991
00992 return n+1;
00993 }
00994
00995 void HdfIO2::flush()
00996 {
00997 return;
00998 }
00999
01000 bool HdfIO2::is_complex_mode()
01001 {
01002 return false;
01003 }
01004
01005
01006 bool HdfIO2::is_image_big_endian()
01007 {
01008 return true;
01009 }
01010
01011
01012
01013 #endif //EM_HDF5