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

Generated on Sat Nov 21 02:19:15 2009 for EMAN2 by  doxygen 1.5.6