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
00085
00086
00087
00088
00089
00090
00091
00092 if (!nodata) {
00093
00094 if (region) {
00095 nx = (int)region->get_width();
00096 if (nx <= 0) nx = 1;
00097 ny = (int)region->get_height();
00098 if (ny <= 0) ny = 1;
00099 nz = (int)region->get_depth();
00100 if (nz <= 0) nz = 1;
00101 set_size(nx,ny,nz);
00102 to_zero();
00103 }
00104 else {
00105 set_size(nx, ny, nz);
00106 }
00107
00108
00109
00110
00111 int err = imageio->read_data(get_data(), img_index, region, is_3d);
00112 if (err) {
00113 throw ImageReadException(filename, "imageio read data failed");
00114 }
00115 else {
00116 update();
00117 }
00118 }
00119 else {
00120 if (rdata!=0) EMUtil::em_free(rdata);
00121 rdata=0;
00122 }
00123
00124 }
00125 }
00126
00127 #ifndef IMAGEIO_CACHE
00128 if( imageio )
00129 {
00130 delete imageio;
00131 imageio = 0;
00132 }
00133 #endif
00134 EXITFUNC;
00135 }
00136
00137 #include <sys/stat.h>
00138
00139 void EMData::write_image(const string & filename, int img_index,
00140 EMUtil::ImageType imgtype,
00141 bool header_only, const Region * region,
00142 EMUtil::EMDataType filestoragetype,
00143 bool use_host_endian)
00144 {
00145 ENTERFUNC;
00146
00147 struct stat fileinfo;
00148 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");
00149
00150 if (is_complex() && is_shuffled())
00151 fft_shuffle();
00152
00153 if (imgtype == EMUtil::IMAGE_UNKNOWN) {
00154 const char *ext = strrchr(filename.c_str(), '.');
00155 if (ext) {
00156 ext++;
00157 imgtype = EMUtil::get_image_ext_type(ext);
00158 }
00159 }
00160 ImageIO::IOMode rwmode = ImageIO::READ_WRITE;
00161
00162
00163 attr_dict["nx"] = nx;
00164 attr_dict["ny"] = ny;
00165 attr_dict["nz"] = nz;
00166 attr_dict["changecount"] = changecount;
00167
00168 if (Util::is_file_exist(filename)) {
00169 LOGVAR("file exists");
00170 if (!header_only && region == 0) {
00171 ImageIO * tmp_imageio = EMUtil::get_imageio(filename, ImageIO::READ_ONLY,
00172 imgtype);
00173 if (tmp_imageio->is_single_image_format()) {
00174 rwmode = ImageIO::WRITE_ONLY;
00175 }
00176 #ifndef IMAGEIO_CACHE
00177 if( tmp_imageio )
00178 {
00179 delete tmp_imageio;
00180 tmp_imageio = 0;
00181 }
00182 #endif
00183 }
00184 }
00185 LOGVAR("getimageio %d",rwmode);
00186 ImageIO *imageio = EMUtil::get_imageio(filename, rwmode, imgtype);
00187 if (!imageio) {
00188 throw ImageFormatException("cannot create an image io");
00189 }
00190 else {
00191 update_stat();
00192
00193
00194
00195
00196 LOGVAR("header write %d",img_index);
00197
00198 switch(filestoragetype) {
00199 case EMUtil::EM_UINT:
00200 attr_dict["datatype"] = (int)EMUtil::EM_UINT;
00201 break;
00202 case EMUtil::EM_USHORT:
00203 attr_dict["datatype"] = (int)EMUtil::EM_USHORT;
00204 break;
00205 case EMUtil::EM_SHORT:
00206 attr_dict["datatype"] = (int)EMUtil::EM_SHORT;
00207 break;
00208 case EMUtil::EM_CHAR:
00209 attr_dict["datatype"] = (int)EMUtil::EM_CHAR;
00210 break;
00211 case EMUtil::EM_UCHAR:
00212 attr_dict["datatype"] = (int)EMUtil::EM_UCHAR;
00213 break;
00214 default:
00215 attr_dict["datatype"] = (int)EMUtil::EM_FLOAT;;
00216 }
00217
00218 int err = imageio->write_header(attr_dict, img_index, region, filestoragetype,
00219 use_host_endian);
00220 if (err) {
00221 throw ImageWriteException(filename, "imageio write header failed");
00222 }
00223 else {
00224 if (!header_only) {
00225 if (imgtype == EMUtil::IMAGE_LST) {
00226 const char *reffile = attr_dict["LST.reffile"];
00227 if (strcmp(reffile, "") == 0) {
00228 reffile = path.c_str();
00229 }
00230 int refn = attr_dict["LST.refn"];
00231 if (refn < 0) {
00232 refn = pathnum;
00233 }
00234
00235 const char *comment = attr_dict["LST.comment"];
00236 char *lstdata = new char[1024];
00237 sprintf(lstdata, "%d\t%s", refn, reffile);
00238 if(strcmp(comment, "") != 0) {
00239 sprintf(lstdata+strlen(lstdata), "\t%s\n", comment);
00240 }
00241 else {
00242 strcat(lstdata, "\n");
00243 }
00244 err = imageio->write_data((float*)lstdata, img_index,
00245 region, filestoragetype, use_host_endian);
00246 if( lstdata )
00247 {
00248 delete [] lstdata;
00249 lstdata = 0;
00250 }
00251 }
00252 if (imgtype == EMUtil::IMAGE_LSTFAST) {
00253 const char *reffile = attr_dict["LST.reffile"];
00254 if (strcmp(reffile, "") == 0) {
00255 reffile = path.c_str();
00256 }
00257 int refn = attr_dict["LST.refn"];
00258 if (refn < 0) {
00259 refn = pathnum;
00260 }
00261
00262 const char *comment = attr_dict["LST.comment"];
00263 char *lstdata = new char[1024];
00264 sprintf(lstdata, "%d\t%s", refn, reffile);
00265 if(strcmp(comment, "") != 0) {
00266 sprintf(lstdata+strlen(lstdata), "\t%s\n", comment);
00267 }
00268 else {
00269 strcat(lstdata, "\n");
00270 }
00271 err = imageio->write_data((float*)lstdata, img_index,
00272 region, filestoragetype, use_host_endian);
00273 if( lstdata )
00274 {
00275 delete [] lstdata;
00276 lstdata = 0;
00277 }
00278 }
00279 else {
00280 err = imageio->write_data(get_data(), img_index, region, filestoragetype,
00281 use_host_endian);
00282 }
00283 if (err) {
00284 imageio->flush();
00285 throw ImageWriteException(filename, "imageio write data failed");
00286 }
00287 }
00288 }
00289 }
00290
00291 if (!(imgtype == EMUtil::IMAGE_PNG)) {
00292 imageio->flush();
00293 }
00294
00295 #ifndef IMAGEIO_CACHE
00296 if( imageio )
00297 {
00298 delete imageio;
00299 imageio = 0;
00300 }
00301 #endif
00302
00303
00304
00305 EXITFUNC;
00306 }
00307
00308
00309 void EMData::append_image(const string & filename,
00310 EMUtil::ImageType imgtype, bool header_only)
00311 {
00312 ENTERFUNC;
00313 write_image(filename, -1, imgtype, header_only, 0);
00314 EXITFUNC;
00315 }
00316
00317
00318 void EMData::write_lst(const string & filename, const string & reffile,
00319 int refn, const string & comment)
00320 {
00321 ENTERFUNC;
00322 attr_dict["LST.reffile"] = reffile;
00323 attr_dict["LST.refn"] = refn;
00324 attr_dict["LST.comment"] = comment;
00325 write_image(filename, -1, EMUtil::IMAGE_LST, false);
00326 EXITFUNC;
00327 }
00328
00329
00330 void EMData::print_image(const string str, ostream& out) {
00331 out << "Printing EMData object: " << str << std::endl;
00332 int nx = get_xsize();
00333 int ny = get_ysize();
00334 int nz = get_zsize();
00335 for (int iz = 0; iz < nz; iz++) {
00336 out << "(z = " << iz << " slice)" << std::endl;
00337 for (int ix = 0; ix < nx; ix++) {
00338 for (int iy = 0; iy < ny; iy++) {
00339 out << setiosflags(std::ios::fixed)
00340 << setiosflags(std::ios_base::scientific)
00341 << std::setw(12)
00342 << std::setprecision(5) << (*this)(ix,iy,iz) << " ";
00343 if (((iy+1) % 6) == 0) {
00344 out << std::endl << " ";
00345 }
00346 }
00347 out << std::endl;
00348 }
00349 }
00350 }
00351
00352 vector < shared_ptr<EMData> > EMData::read_images(const string & filename, vector < int >img_indices,
00353 bool header_only)
00354 {
00355 ENTERFUNC;
00356
00357 int total_img = EMUtil::get_image_count(filename);
00358 size_t num_img = img_indices.size();
00359
00360 for (size_t i = 0; i < num_img; i++) {
00361 if (img_indices[i] < 0 && img_indices[i] >= total_img) {
00362 throw OutofRangeException(0, total_img, img_indices[i], "image index");
00363 }
00364 }
00365
00366 size_t n = (num_img == 0 ? total_img : num_img);
00367
00368 vector< shared_ptr<EMData> > v;
00369 for (size_t j = 0; j < n; j++) {
00370 shared_ptr<EMData> d(new EMData());
00371 size_t k = (num_img == 0 ? j : img_indices[j]);
00372 try {
00373 d->read_image(filename, (int)k, header_only);
00374 }
00375 catch(E2Exception &e) {
00376 throw(e);
00377 }
00378 if ( d != 0 )
00379 {
00380 v.push_back(d);
00381 }
00382 else
00383 throw ImageReadException(filename, "imageio read data failed");
00384 }
00385
00386 EXITFUNC;
00387 return v;
00388 }
00389
00390
00391 vector < shared_ptr<EMData> >EMData::read_images_ext(const string & filename, int img_index_start,
00392 int img_index_end, bool header_only,
00393 const string & ext)
00394 {
00395 ENTERFUNC;
00396
00397 if (img_index_end < img_index_start) {
00398 throw InvalidValueException(img_index_end, "image index end < image index start");
00399 }
00400 string new_filename = filename;
00401 new_filename = new_filename.insert(new_filename.rfind("."), ext);
00402 int num_img = EMUtil::get_image_count(new_filename);
00403
00404 if (img_index_start < 0 || img_index_start >= num_img) {
00405 throw OutofRangeException(0, num_img-1, img_index_start, "image index start");
00406 }
00407
00408 if (img_index_end >= num_img) {
00409 img_index_end = num_img - 1;
00410 }
00411
00412 vector < shared_ptr<EMData> >v;
00413
00414 for (int i = img_index_start; i < img_index_end; i++) {
00415 shared_ptr<EMData> d(new EMData());
00416 try {
00417 d->read_image(new_filename, i, header_only);
00418 }
00419 catch(E2Exception &e) {
00420 throw(e);
00421 }
00422 v.push_back(d);
00423 }
00424 EXITFUNC;
00425 return v;
00426 }
00427