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

Generated on Thu Dec 9 13:45:45 2010 for EMAN2 by  doxygen 1.3.9.1