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 #include <iomanip>
00037
00038 #include "emdata.h"
00039 #include "all_imageio.h"
00040 #include "ctf.h"
00041
00042 #include <iostream>
00043 using std::cout;
00044 using std::endl;
00045
00046 #include <boost/shared_ptr.hpp>
00047 using boost::shared_ptr;
00048
00049 using namespace EMAN;
00050
00051 void EMData::read_image(const string & filename, int img_index, bool nodata,
00052 const Region * region, bool is_3d)
00053 {
00054 ENTERFUNC;
00055
00056 ImageIO *imageio = EMUtil::get_imageio(filename, ImageIO::READ_ONLY);
00057
00058 if (!imageio) {
00059 throw ImageFormatException("cannot create an image io");
00060 }
00061 else {
00062 int err = imageio->read_header(attr_dict, img_index, region, is_3d);
00063 if (err) {
00064 throw ImageReadException(filename, "imageio read header failed");
00065 }
00066 else {
00067 attr_dict["source_path"] = filename;
00068 attr_dict["source_n"] = img_index;
00069 if (imageio->is_complex_mode()) {
00070 set_complex(true);
00071 set_fftpad(true);
00072 }
00073 if (attr_dict.has_key("is_fftodd") && (int)attr_dict["is_fftodd"] == 1) {
00074 set_fftodd(true);
00075 }
00076 if ((int) attr_dict["is_complex_ri"] == 1) {
00077 set_ri(true);
00078 }
00079 save_byteorder_to_dict(imageio);
00080
00081 nx = attr_dict["nx"];
00082 ny = attr_dict["ny"];
00083 nz = attr_dict["nz"];
00084 attr_dict.erase("nx");
00085 attr_dict.erase("ny");
00086 attr_dict.erase("nz");
00087
00088 if (!nodata) {
00089
00090 if (region) {
00091 nx = (int)region->get_width();
00092 if (nx <= 0) nx = 1;
00093 ny = (int)region->get_height();
00094 if (ny <= 0) ny = 1;
00095 nz = (int)region->get_depth();
00096 if (nz <= 0) nz = 1;
00097 set_size(nx,ny,nz);
00098 to_zero();
00099 }
00100 else {
00101 set_size(nx, ny, nz);
00102 }
00103
00104
00105
00106
00107 int err = imageio->read_data(get_data(), img_index, region, is_3d);
00108 if (err) {
00109 throw ImageReadException(filename, "imageio read data failed");
00110 }
00111 else {
00112 update();
00113 }
00114 }
00115 else {
00116 if (rdata!=0) EMUtil::em_free(rdata);
00117 rdata=0;
00118 }
00119
00120 }
00121 }
00122
00123 #ifndef IMAGEIO_CACHE
00124 if( imageio )
00125 {
00126 delete imageio;
00127 imageio = 0;
00128 }
00129 #endif
00130 EXITFUNC;
00131 }
00132
00133 void EMData::read_binedimage(const string & filename, int img_index, int binfactor, bool fast, bool is_3d)
00134 {
00135 ENTERFUNC;
00136
00137 ImageIO *imageio = EMUtil::get_imageio(filename, ImageIO::READ_ONLY);
00138
00139 if (!imageio) {
00140 throw ImageFormatException("cannot create an image io");
00141 }
00142 else {
00143 int err = imageio->read_header(attr_dict, img_index, 0, is_3d);
00144 if (err) {
00145 throw ImageReadException(filename, "imageio read header failed");
00146 }
00147 else {
00148 attr_dict["source_path"] = filename;
00149 attr_dict["source_n"] = img_index;
00150 if (imageio->is_complex_mode()) {
00151 set_complex(true);
00152 set_fftpad(true);
00153 }
00154 if (attr_dict.has_key("is_fftodd") && (int)attr_dict["is_fftodd"] == 1) {
00155 set_fftodd(true);
00156 }
00157 if ((int) attr_dict["is_complex_ri"] == 1) {
00158 set_ri(true);
00159 }
00160 save_byteorder_to_dict(imageio);
00161
00162 int ori_nx = nx = attr_dict["nx"];
00163 int ori_ny = ny = attr_dict["ny"];
00164 int ori_nz = nz = attr_dict["nz"];
00165 attr_dict.erase("nx");
00166 attr_dict.erase("ny");
00167 attr_dict.erase("nz");
00168
00169
00170 set_size(nx/binfactor, ny/binfactor, nz/binfactor);
00171
00172
00173 EMData* tempdata = new EMData();
00174 size_t sizeofslice = nx*ny*sizeof(float);
00175
00176
00177 int zbin = binfactor;
00178 if(fast) zbin = 1;
00179
00180 float percent = 0.1f;
00181 for(int k = 0; k < ori_nz; k+=binfactor){
00182 if(k > ori_nz*percent){
00183 cout << float(k)/float(ori_nz) << "% Done!" << endl;
00184 percent+=0.1f;
00185 }
00186
00187 const Region* binregion = new Region(0,0,k,ori_nx,ori_ny,zbin);
00188 tempdata->read_image(filename, 0, false, binregion);
00189
00190 if (binfactor > 1) tempdata->process_inplace("math.meanshrink",Dict("n",binfactor));
00191 size_t offset = nx*ny*k/binfactor;
00192
00193 EMUtil::em_memcpy(get_data()+offset,tempdata->get_data(),sizeofslice);
00194 delete binregion;
00195 }
00196
00197 delete tempdata;
00198 update();
00199 }
00200 }
00201
00202 #ifndef IMAGEIO_CACHE
00203 if( imageio )
00204 {
00205 delete imageio;
00206 imageio = 0;
00207 }
00208 #endif
00209 EXITFUNC;
00210 }
00211
00212 #include <sys/stat.h>
00213
00214 void EMData::write_image(const string & filename, int img_index,
00215 EMUtil::ImageType imgtype,
00216 bool header_only, const Region * region,
00217 EMUtil::EMDataType filestoragetype,
00218 bool use_host_endian)
00219 {
00220 ENTERFUNC;
00221
00222 struct stat fileinfo;
00223 if ( region && stat(filename.c_str(),&fileinfo) != 0 ) throw UnexpectedBehaviorException("To write an image using a region the file must already exist and be the correct dimensions");
00224
00225 if (is_complex() && is_shuffled())
00226 fft_shuffle();
00227
00228 if (imgtype == EMUtil::IMAGE_UNKNOWN) {
00229 const char *ext = strrchr(filename.c_str(), '.');
00230 if (ext) {
00231 ext++;
00232 imgtype = EMUtil::get_image_ext_type(ext);
00233 }
00234 }
00235 ImageIO::IOMode rwmode = ImageIO::READ_WRITE;
00236
00237
00238 attr_dict["nx"] = nx;
00239 attr_dict["ny"] = ny;
00240 attr_dict["nz"] = nz;
00241 attr_dict["changecount"] = changecount;
00242
00243 if (Util::is_file_exist(filename)) {
00244 LOGVAR("file exists");
00245 if (!header_only && region == 0) {
00246 ImageIO * tmp_imageio = EMUtil::get_imageio(filename, ImageIO::READ_ONLY,
00247 imgtype);
00248 if (tmp_imageio->is_single_image_format()) {
00249 rwmode = ImageIO::WRITE_ONLY;
00250 }
00251 #ifndef IMAGEIO_CACHE
00252 if( tmp_imageio )
00253 {
00254 delete tmp_imageio;
00255 tmp_imageio = 0;
00256 }
00257 #endif
00258 }
00259 }
00260 LOGVAR("getimageio %d",rwmode);
00261 ImageIO *imageio = EMUtil::get_imageio(filename, rwmode, imgtype);
00262 if (!imageio) {
00263 throw ImageFormatException("cannot create an image io");
00264 }
00265 else {
00266 update_stat();
00267
00268
00269
00270
00271 LOGVAR("header write %d",img_index);
00272
00273 switch(filestoragetype) {
00274 case EMUtil::EM_UINT:
00275 attr_dict["datatype"] = (int)EMUtil::EM_UINT;
00276 break;
00277 case EMUtil::EM_USHORT:
00278 attr_dict["datatype"] = (int)EMUtil::EM_USHORT;
00279 break;
00280 case EMUtil::EM_SHORT:
00281 attr_dict["datatype"] = (int)EMUtil::EM_SHORT;
00282 break;
00283 case EMUtil::EM_CHAR:
00284 attr_dict["datatype"] = (int)EMUtil::EM_CHAR;
00285 break;
00286 case EMUtil::EM_UCHAR:
00287 attr_dict["datatype"] = (int)EMUtil::EM_UCHAR;
00288 break;
00289 default:
00290 attr_dict["datatype"] = (int)EMUtil::EM_FLOAT;;
00291 }
00292
00293 int err = imageio->write_header(attr_dict, img_index, region, filestoragetype,
00294 use_host_endian);
00295 if (err) {
00296 throw ImageWriteException(filename, "imageio write header failed");
00297 }
00298 else {
00299 if (!header_only) {
00300 if (imgtype == EMUtil::IMAGE_LST) {
00301 const char *reffile = attr_dict["LST.reffile"];
00302 if (strcmp(reffile, "") == 0) {
00303 reffile = path.c_str();
00304 }
00305 int refn = attr_dict["LST.refn"];
00306 if (refn < 0) {
00307 refn = pathnum;
00308 }
00309
00310 const char *comment = attr_dict["LST.comment"];
00311 char *lstdata = new char[1024];
00312 sprintf(lstdata, "%d\t%s", refn, reffile);
00313 if(strcmp(comment, "") != 0) {
00314 sprintf(lstdata+strlen(lstdata), "\t%s\n", comment);
00315 }
00316 else {
00317 strcat(lstdata, "\n");
00318 }
00319 err = imageio->write_data((float*)lstdata, img_index,
00320 region, filestoragetype, use_host_endian);
00321 if( lstdata )
00322 {
00323 delete [] lstdata;
00324 lstdata = 0;
00325 }
00326 }
00327 if (imgtype == EMUtil::IMAGE_LSTFAST) {
00328 const char *reffile = attr_dict["LST.reffile"];
00329 if (strcmp(reffile, "") == 0) {
00330 reffile = path.c_str();
00331 }
00332 int refn = attr_dict["LST.refn"];
00333 if (refn < 0) {
00334 refn = pathnum;
00335 }
00336
00337 const char *comment = attr_dict["LST.comment"];
00338 char *lstdata = new char[1024];
00339 sprintf(lstdata, "%d\t%s", refn, reffile);
00340 if(strcmp(comment, "") != 0) {
00341 sprintf(lstdata+strlen(lstdata), "\t%s\n", comment);
00342 }
00343 else {
00344 strcat(lstdata, "\n");
00345 }
00346 err = imageio->write_data((float*)lstdata, img_index,
00347 region, filestoragetype, use_host_endian);
00348 if( lstdata )
00349 {
00350 delete [] lstdata;
00351 lstdata = 0;
00352 }
00353 }
00354 else {
00355 err = imageio->write_data(get_data(), img_index, region, filestoragetype,
00356 use_host_endian);
00357 }
00358 if (err) {
00359 imageio->flush();
00360 throw ImageWriteException(filename, "imageio write data failed");
00361 }
00362 }
00363 }
00364 }
00365
00366 if (!(imgtype == EMUtil::IMAGE_PNG)) {
00367 imageio->flush();
00368 }
00369
00370 #ifndef IMAGEIO_CACHE
00371 if( imageio )
00372 {
00373 delete imageio;
00374 imageio = 0;
00375 }
00376 #endif
00377
00378
00379
00380 EXITFUNC;
00381 }
00382
00383
00384 void EMData::append_image(const string & filename,
00385 EMUtil::ImageType imgtype, bool header_only)
00386 {
00387 ENTERFUNC;
00388 write_image(filename, -1, imgtype, header_only, 0);
00389 EXITFUNC;
00390 }
00391
00392
00393 void EMData::write_lst(const string & filename, const string & reffile,
00394 int refn, const string & comment)
00395 {
00396 ENTERFUNC;
00397 attr_dict["LST.reffile"] = reffile;
00398 attr_dict["LST.refn"] = refn;
00399 attr_dict["LST.comment"] = comment;
00400 write_image(filename, -1, EMUtil::IMAGE_LST, false);
00401 EXITFUNC;
00402 }
00403
00404
00405 void EMData::print_image(const string str, ostream& out) {
00406 out << "Printing EMData object: " << str << std::endl;
00407 int nx = get_xsize();
00408 int ny = get_ysize();
00409 int nz = get_zsize();
00410 for (int iz = 0; iz < nz; iz++) {
00411 out << "(z = " << iz << " slice)" << std::endl;
00412 for (int ix = 0; ix < nx; ix++) {
00413 for (int iy = 0; iy < ny; iy++) {
00414 out << setiosflags(std::ios::fixed)
00415 << setiosflags(std::ios_base::scientific)
00416 << std::setw(12)
00417 << std::setprecision(5) << (*this)(ix,iy,iz) << " ";
00418 if (((iy+1) % 6) == 0) {
00419 out << std::endl << " ";
00420 }
00421 }
00422 out << std::endl;
00423 }
00424 }
00425 }
00426
00427 vector < shared_ptr<EMData> > EMData::read_images(const string & filename, vector < int >img_indices,
00428 bool header_only)
00429 {
00430 ENTERFUNC;
00431
00432 int total_img = EMUtil::get_image_count(filename);
00433 size_t num_img = img_indices.size();
00434
00435 for (size_t i = 0; i < num_img; i++) {
00436 if (img_indices[i] < 0 && img_indices[i] >= total_img) {
00437 throw OutofRangeException(0, total_img, img_indices[i], "image index");
00438 }
00439 }
00440
00441 size_t n = (num_img == 0 ? total_img : num_img);
00442
00443 vector< shared_ptr<EMData> > v;
00444 for (size_t j = 0; j < n; j++) {
00445 shared_ptr<EMData> d(new EMData());
00446 size_t k = (num_img == 0 ? j : img_indices[j]);
00447 try {
00448 d->read_image(filename, (int)k, header_only);
00449 }
00450 catch(E2Exception &e) {
00451 throw(e);
00452 }
00453 if ( d != 0 )
00454 {
00455 v.push_back(d);
00456 }
00457 else
00458 throw ImageReadException(filename, "imageio read data failed");
00459 }
00460
00461 EXITFUNC;
00462 return v;
00463 }
00464
00465
00466 vector < shared_ptr<EMData> >EMData::read_images_ext(const string & filename, int img_index_start,
00467 int img_index_end, bool header_only,
00468 const string & ext)
00469 {
00470 ENTERFUNC;
00471
00472 if (img_index_end < img_index_start) {
00473 throw InvalidValueException(img_index_end, "image index end < image index start");
00474 }
00475 string new_filename = filename;
00476 new_filename = new_filename.insert(new_filename.rfind("."), ext);
00477 int num_img = EMUtil::get_image_count(new_filename);
00478
00479 if (img_index_start < 0 || img_index_start >= num_img) {
00480 throw OutofRangeException(0, num_img-1, img_index_start, "image index start");
00481 }
00482
00483 if (img_index_end >= num_img) {
00484 img_index_end = num_img - 1;
00485 }
00486
00487 vector < shared_ptr<EMData> >v;
00488
00489 for (int i = img_index_start; i < img_index_end; i++) {
00490 shared_ptr<EMData> d(new EMData());
00491 try {
00492 d->read_image(new_filename, i, header_only);
00493 }
00494 catch(E2Exception &e) {
00495 throw(e);
00496 }
00497 v.push_back(d);
00498 }
00499 EXITFUNC;
00500 return v;
00501 }
00502