Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

emdata_io.cpp

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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 //                      if(attr_dict.has_key("ctf")) {
00086 //                              flags |= EMDATA_HASCTFF;
00087 //                      }
00088 //                      else {
00089 //                              flags &= ~EMDATA_HASCTFF;
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(); // This could be avoided in favor of setting only the regions that were not read to to zero... but tedious
00103                                 } // else the dimensions of the file being read match those of this
00104                                 else {
00105                                         set_size(nx, ny, nz);
00106                                 }
00107 
00108                                 // If GPU features are enabled there is  danger that rdata will
00109                                 // not be allocated, but set_size takes care of this, so this
00110                                 // should be safe.
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         //set "nx", "ny", "nz" and "changecount" in attr_dict, since they are taken out of attribute dictionary
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                 /* Let each image format decide how to deal with negative image_index*/
00193 //              if (img_index < 0) {
00194 //                      img_index = imageio->get_nimg();
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;; //default 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         //PNG image already do cleaning in write_data function.
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 

Generated on Thu Nov 17 12:43:44 2011 for EMAN2 by  doxygen 1.3.9.1