emutil.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 "all_imageio.h"
00037 #include "portable_fileio.h"
00038 #include "emcache.h"
00039 #include "emdata.h"
00040 #include "ctf.h"
00041 #include "emassert.h"
00042 #include "exception.h"
00043 
00044 #include <boost/shared_ptr.hpp>
00045 using boost::shared_ptr;
00046 
00047 #ifdef WIN32
00048         #include <windows.h>
00049         #define MAXPATHLEN (MAX_PATH*4)
00050 #else
00051         #include <sys/param.h>
00052 #endif  //WIN32
00053 
00054 //#ifdef EMAN2_USING_CUDA_MALLOC
00055 //#include "cuda/cuda_util.h"
00056 //#endif
00057 
00058 using namespace EMAN;
00059 
00060 static const int ATTR_NAME_LEN = 128;
00061 
00062 EMUtil::ImageType EMUtil::get_image_ext_type(const string & file_ext)
00063 {
00064         ENTERFUNC;
00065         static bool initialized = false;
00066         static map < string, ImageType > imagetypes;
00067 
00068         if (!initialized) {
00069                 imagetypes["rec"] = IMAGE_MRC;
00070                 imagetypes["mrc"] = IMAGE_MRC;
00071                 imagetypes["MRC"] = IMAGE_MRC;
00072                 imagetypes["ali"] = IMAGE_MRC;
00073 
00074                 imagetypes["tnf"] = IMAGE_MRC;
00075                 imagetypes["TNF"] = IMAGE_MRC;
00076 
00077                 imagetypes["ccp4"] = IMAGE_MRC;
00078                 imagetypes["map"] = IMAGE_MRC;
00079 
00080                 imagetypes["dm3"] = IMAGE_DM3;
00081                 imagetypes["DM3"] = IMAGE_DM3;
00082 
00083                 imagetypes["spi"] = IMAGE_SPIDER;
00084                 imagetypes["SPI"] = IMAGE_SPIDER;
00085 
00086                 imagetypes["spider"] = IMAGE_SPIDER;
00087                 imagetypes["SPIDER"] = IMAGE_SPIDER;
00088 
00089                 imagetypes["spidersingle"] = IMAGE_SINGLE_SPIDER;
00090                 imagetypes["SPIDERSINGLE"] = IMAGE_SINGLE_SPIDER;
00091 
00092                 imagetypes["singlespider"] = IMAGE_SINGLE_SPIDER;
00093                 imagetypes["SINGLESPIDER"] = IMAGE_SINGLE_SPIDER;
00094 
00095                 imagetypes["img"] = IMAGE_IMAGIC;
00096                 imagetypes["IMG"] = IMAGE_IMAGIC;
00097 
00098                 imagetypes["hed"] = IMAGE_IMAGIC;
00099                 imagetypes["HED"] = IMAGE_IMAGIC;
00100 
00101                 imagetypes["imagic"] = IMAGE_IMAGIC;
00102                 imagetypes["IMAGIC"] = IMAGE_IMAGIC;
00103 
00104                 imagetypes["pgm"] = IMAGE_PGM;
00105                 imagetypes["PGM"] = IMAGE_PGM;
00106 
00107                 imagetypes["lst"] = IMAGE_LST;
00108                 imagetypes["LST"] = IMAGE_LST;
00109 
00110                 imagetypes["lsx"] = IMAGE_LSTFAST;      // but .lst or another extension would also be ok
00111                 imagetypes["LSX"] = IMAGE_LSTFAST;
00112 
00113                 imagetypes["pif"] = IMAGE_PIF;
00114                 imagetypes["PIF"] = IMAGE_PIF;
00115 
00116                 imagetypes["png"] = IMAGE_PNG;
00117                 imagetypes["PNG"] = IMAGE_PNG;
00118 
00119                 imagetypes["h5"] = IMAGE_HDF;
00120                 imagetypes["H5"] = IMAGE_HDF;
00121 
00122                 imagetypes["hd5"] = IMAGE_HDF;
00123                 imagetypes["HD5"] = IMAGE_HDF;
00124 
00125                 imagetypes["hdf"] = IMAGE_HDF;
00126                 imagetypes["HDF"] = IMAGE_HDF;
00127 
00128                 imagetypes["tif"] = IMAGE_TIFF;
00129                 imagetypes["TIF"] = IMAGE_TIFF;
00130 
00131                 imagetypes["tiff"] = IMAGE_TIFF;
00132                 imagetypes["TIFF"] = IMAGE_TIFF;
00133 
00134                 imagetypes["fts"] = IMAGE_FITS;
00135                 imagetypes["FTS"] = IMAGE_FITS;
00136 
00137                 imagetypes["vtk"] = IMAGE_VTK;
00138                 imagetypes["VTK"] = IMAGE_VTK;
00139 
00140                 imagetypes["hdr"] = IMAGE_SAL;
00141                 imagetypes["HDR"] = IMAGE_SAL;
00142 
00143                 imagetypes["sal"] = IMAGE_SAL;
00144                 imagetypes["SAL"] = IMAGE_SAL;
00145 
00146                 imagetypes["map"] = IMAGE_ICOS;
00147                 imagetypes["MAP"] = IMAGE_ICOS;
00148 
00149                 imagetypes["icos"] = IMAGE_ICOS;
00150                 imagetypes["ICOS"] = IMAGE_ICOS;
00151 
00152                 imagetypes["am"] = IMAGE_AMIRA;
00153                 imagetypes["AM"] = IMAGE_AMIRA;
00154 
00155                 imagetypes["amira"] = IMAGE_AMIRA;
00156                 imagetypes["AMIRA"] = IMAGE_AMIRA;
00157 
00158                 imagetypes["emim"] = IMAGE_EMIM;
00159                 imagetypes["EMIM"] = IMAGE_EMIM;
00160 
00161                 imagetypes["xplor"] = IMAGE_XPLOR;
00162                 imagetypes["XPLOR"] = IMAGE_XPLOR;
00163 
00164                 imagetypes["em"] = IMAGE_EM;
00165                 imagetypes["EM"] = IMAGE_EM;
00166 
00167                 imagetypes["dm2"] = IMAGE_GATAN2;
00168                 imagetypes["DM2"] = IMAGE_GATAN2;
00169 
00170                 imagetypes["v4l"] = IMAGE_V4L;
00171                 imagetypes["V4L"] = IMAGE_V4L;
00172 
00173                 imagetypes["jpg"] = IMAGE_JPEG;
00174                 imagetypes["JPG"] = IMAGE_JPEG;
00175                 imagetypes["jpeg"] = IMAGE_JPEG;
00176                 imagetypes["JPEG"] = IMAGE_JPEG;
00177 
00178                 imagetypes["df3"] = IMAGE_DF3;
00179                 imagetypes["DF3"] = IMAGE_DF3;
00180 
00181                 initialized = true;
00182         }
00183 
00184         ImageType result = IMAGE_UNKNOWN;
00185 
00186         if (imagetypes.find(file_ext) != imagetypes.end()) {
00187                 result = imagetypes[file_ext];
00188         }
00189 
00190         EXITFUNC;
00191         return result;
00192 }
00193 
00194 
00195 
00196 bool EMUtil::is_valid_filename(const string & filename) {
00197         ImageType type = get_image_ext_type(Util::get_filename_ext(filename));
00198         return (type != IMAGE_UNKNOWN);
00199 }
00200 
00201 EMUtil::ImageType EMUtil::fast_get_image_type(const string & filename,
00202                                                                                           const void *first_block,
00203                                                                                           off_t file_size)
00204 {
00205         ENTERFUNC;
00206         Assert(filename != "");
00207         Assert(first_block != 0);
00208         Assert(file_size > 0);
00209 
00210 #ifdef ENABLE_V4L2
00211         if (filename.compare(0,5,"/dev/")==0) return IMAGE_V4L;
00212 #endif
00213 
00214         string ext = Util::get_filename_ext(filename);
00215         if (ext == "") {
00216                 return IMAGE_UNKNOWN;
00217         }
00218         ImageType image_type = get_image_ext_type(ext);
00219 
00220         switch (image_type) {
00221         case IMAGE_MRC:
00222                 if (MrcIO::is_valid(first_block, file_size)) {
00223                         return IMAGE_MRC;
00224                 }
00225                 break;
00226         case IMAGE_DM3:
00227                 if (DM3IO::is_valid(first_block)) {
00228                         return IMAGE_DM3;
00229                 }
00230                 break;
00231 #ifdef EM_HDF5
00232         case IMAGE_HDF:
00233                 if (HdfIO2::is_valid(first_block)) {
00234                         return IMAGE_HDF;
00235                 }
00236                 break;
00237 #endif
00238         case IMAGE_LST:
00239                 if (LstIO::is_valid(first_block)) {
00240                         return IMAGE_LST;
00241                 }
00242                 break;
00243         case IMAGE_LSTFAST:
00244                 if (LstFastIO::is_valid(first_block)) {
00245                         return IMAGE_LSTFAST;
00246                 }
00247                 break;
00248 #ifdef EM_TIFF
00249         case IMAGE_TIFF:
00250                 if (TiffIO::is_valid(first_block)) {
00251                         return IMAGE_TIFF;
00252                 }
00253                 break;
00254 #endif
00255         case IMAGE_SPIDER:
00256                 if (SpiderIO::is_valid(first_block)) {
00257                         return IMAGE_SPIDER;
00258                 }
00259                 break;
00260         case IMAGE_SINGLE_SPIDER:
00261                 if (SingleSpiderIO::is_valid(first_block)) {
00262                         return IMAGE_SINGLE_SPIDER;
00263                 }
00264                 break;
00265         case IMAGE_PIF:
00266                 if (PifIO::is_valid(first_block)) {
00267                         return IMAGE_PIF;
00268                 }
00269                 break;
00270 #ifdef EM_PNG
00271         case IMAGE_PNG:
00272                 if (PngIO::is_valid(first_block)) {
00273                         return IMAGE_PNG;
00274                 }
00275                 break;
00276 #endif
00277         case IMAGE_VTK:
00278                 if (VtkIO::is_valid(first_block)) {
00279                         return IMAGE_VTK;
00280                 }
00281                 break;
00282         case IMAGE_PGM:
00283                 if (PgmIO::is_valid(first_block)) {
00284                         return IMAGE_PGM;
00285                 }
00286                 break;
00287         case IMAGE_ICOS:
00288                 if (IcosIO::is_valid(first_block)) {
00289                         return IMAGE_ICOS;
00290                 }
00291                 break;
00292         case IMAGE_SAL:
00293                 if (SalIO::is_valid(first_block)) {
00294                         return IMAGE_SAL;
00295                 }
00296                 break;
00297         case IMAGE_AMIRA:
00298                 if (AmiraIO::is_valid(first_block)) {
00299                         return IMAGE_AMIRA;
00300                 }
00301                 break;
00302         case IMAGE_XPLOR:
00303                 if (XplorIO::is_valid(first_block)) {
00304                         return IMAGE_XPLOR;
00305                 }
00306                 break;
00307         case IMAGE_GATAN2:
00308                 if (Gatan2IO::is_valid(first_block)) {
00309                         return IMAGE_GATAN2;
00310                 }
00311                 break;
00312         case IMAGE_EM:
00313                 if (EmIO::is_valid(first_block, file_size)) {
00314                         return IMAGE_EM;
00315                 }
00316                 break;
00317         case IMAGE_DF3:
00318                 if (EmIO::is_valid(first_block, file_size)) {
00319                         return IMAGE_DF3;
00320                 }
00321                 break;
00322         case IMAGE_IMAGIC:
00323                 if (ImagicIO::is_valid(first_block)) {
00324                         return IMAGE_IMAGIC;
00325                 }
00326                 break;
00327         default:
00328                 return IMAGE_UNKNOWN;
00329         }
00330         EXITFUNC;
00331         return IMAGE_UNKNOWN;
00332 }
00333 
00334 
00335 EMUtil::ImageType EMUtil::get_image_type(const string & in_filename)
00336 {
00337         ENTERFUNC;
00338         Assert(in_filename != "");
00339 
00340 #ifdef ENABLE_V4L2
00341         if (in_filename.compare(0,5,"/dev/")==0) return IMAGE_V4L;
00342 #endif
00343 
00344         string filename = in_filename;
00345 
00346         string old_ext = Util::get_filename_ext(filename);
00347         if (old_ext == ImagicIO::IMG_EXT) {
00348                 filename = Util::change_filename_ext(filename, ImagicIO::HED_EXT);
00349         }
00350 
00351         FILE *in = fopen(filename.c_str(), "rb");
00352         if (!in) {
00353                 throw FileAccessException(filename);
00354         }
00355 
00356         char first_block[1024];
00357         size_t n = fread(first_block, sizeof(char), sizeof(first_block), in);
00358         portable_fseek(in, 0, SEEK_END);
00359         off_t file_size = portable_ftell(in);
00360 
00361         if (n == 0) {
00362                 LOGERR("file '%s' is an empty file", filename.c_str());
00363                 fclose(in);
00364                 return IMAGE_UNKNOWN;
00365         }
00366         fclose(in);
00367 
00368         ImageType image_type = fast_get_image_type(filename, first_block, file_size);
00369         if (image_type != IMAGE_UNKNOWN) {
00370                 return image_type;
00371         }
00372 
00373         if (SpiderIO::is_valid(first_block)) {
00374                 image_type = IMAGE_SPIDER;
00375         }
00376         else if (SingleSpiderIO::is_valid(first_block)) {
00377                 image_type = IMAGE_SINGLE_SPIDER;
00378         }
00379         else if (MrcIO::is_valid(first_block, file_size)) {
00380                 image_type = IMAGE_MRC;
00381         }
00382         else if (DM3IO::is_valid(first_block)) {
00383                 image_type = IMAGE_DM3;
00384         }
00385 #ifdef EM_HDF5
00386         else if (HdfIO2::is_valid(first_block)) {
00387                 image_type = IMAGE_HDF;
00388         }
00389 #endif
00390         else if (LstIO::is_valid(first_block)) {
00391                 image_type = IMAGE_LST;
00392         }
00393         else if (LstFastIO::is_valid(first_block)) {
00394                 image_type = IMAGE_LSTFAST;
00395         }
00396 #ifdef EM_TIFF
00397         else if (TiffIO::is_valid(first_block)) {
00398                 image_type = IMAGE_TIFF;
00399         }
00400 #endif
00401         else if (PifIO::is_valid(first_block)) {
00402                 image_type = IMAGE_PIF;
00403         }
00404 #ifdef EM_PNG
00405         else if (PngIO::is_valid(first_block)) {
00406                 image_type = IMAGE_PNG;
00407         }
00408 #endif
00409         else if (VtkIO::is_valid(first_block)) {
00410                 image_type = IMAGE_VTK;
00411         }
00412         else if (PgmIO::is_valid(first_block)) {
00413                 image_type = IMAGE_PGM;
00414         }
00415         else if (IcosIO::is_valid(first_block)) {
00416                 image_type = IMAGE_ICOS;
00417         }
00418         else if (SalIO::is_valid(first_block)) {
00419                 image_type = IMAGE_SAL;
00420         }
00421         else if (AmiraIO::is_valid(first_block)) {
00422                 image_type = IMAGE_AMIRA;
00423         }
00424         else if (XplorIO::is_valid(first_block)) {
00425                 image_type = IMAGE_XPLOR;
00426         }
00427         else if (Gatan2IO::is_valid(first_block)) {
00428                 image_type = IMAGE_GATAN2;
00429         }
00430         else if (FitsIO::is_valid(first_block)) {
00431                 image_type = IMAGE_FITS;
00432         }
00433         else if (EmIO::is_valid(first_block, file_size)) {
00434                 image_type = IMAGE_EM;
00435         }
00436         else if (ImagicIO::is_valid(first_block)) {
00437                 image_type = IMAGE_IMAGIC;
00438         }
00439         else if (Df3IO::is_valid(first_block)) {
00440                 image_type = IMAGE_DF3;
00441         }
00442         else {
00443                 //LOGERR("I don't know this image's type: '%s'", filename.c_str());
00444                 throw ImageFormatException("invalid image type");
00445         }
00446 
00447         EXITFUNC;
00448         return image_type;
00449 }
00450 
00451 
00452 int EMUtil::get_image_count(const string & filename)
00453 {
00454         ENTERFUNC;
00455         Assert(filename != "");
00456 
00457         int nimg = 0;
00458         ImageIO *imageio = get_imageio(filename, ImageIO::READ_ONLY);
00459 
00460         if (imageio) {
00461                 nimg = imageio->get_nimg();
00462         }
00463 #ifndef IMAGEIO_CACHE
00464         if( imageio )
00465         {
00466                 delete imageio;
00467                 imageio = 0;
00468         }
00469 #endif
00470         EXITFUNC;
00471         return nimg;
00472 }
00473 
00474 
00475 ImageIO *EMUtil::get_imageio(const string & filename, int rw,
00476                                                          ImageType image_type)
00477 {
00478         ENTERFUNC;
00479         Assert(filename != "");
00480         Assert(rw == ImageIO::READ_ONLY ||
00481                    rw == ImageIO::READ_WRITE ||
00482                    rw == ImageIO::WRITE_ONLY);
00483 
00484         ImageIO *imageio = 0;
00485 #ifdef IMAGEIO_CACHE
00486         imageio = GlobalCache::instance()->get_imageio(filename, rw);
00487         if (imageio) {
00488                 return imageio;
00489         }
00490 #endif
00491 
00492         ImageIO::IOMode rw_mode = static_cast < ImageIO::IOMode > (rw);
00493 
00494         if (image_type == IMAGE_UNKNOWN) {
00495                 if(rw == ImageIO::WRITE_ONLY || rw == ImageIO::READ_WRITE) {
00496                         throw ImageFormatException("writing to this image format not supported.");
00497                 }
00498 
00499                 image_type = get_image_type(filename);
00500         }
00501 
00502         switch (image_type) {
00503 #ifdef ENABLE_V4L2
00504         case IMAGE_V4L:
00505                 imageio = new V4L2IO(filename, rw_mode);
00506                 break;
00507 #endif
00508         case IMAGE_MRC:
00509                 imageio = new MrcIO(filename, rw_mode);
00510                 break;
00511         case IMAGE_IMAGIC:
00512                 imageio = new ImagicIO2(filename, rw_mode);
00513                 if (rw_mode==ImageIO::READ_ONLY && ((ImagicIO2 *)imageio)->init_test()==-1 ) {
00514                         delete imageio;
00515                         imageio = new ImagicIO(filename, rw_mode);
00516                 }
00517                 break;
00518         case IMAGE_DM3:
00519                 imageio = new DM3IO(filename, rw_mode);
00520                 break;
00521 #ifdef EM_TIFF
00522         case IMAGE_TIFF:
00523                 imageio = new TiffIO(filename, rw_mode);
00524                 break;
00525 #endif
00526 #ifdef EM_HDF5
00527         case IMAGE_HDF:
00528                 imageio = new HdfIO2(filename, rw_mode);
00529                 if (((HdfIO2 *)imageio)->init_test()==-1) {
00530                         delete imageio;
00531                         imageio = new HdfIO(filename, rw_mode);
00532                 }
00533                 break;
00534 #endif
00535         case IMAGE_LST:
00536                 imageio = new LstIO(filename, rw_mode);
00537                 break;
00538         case IMAGE_LSTFAST:
00539                 imageio = new LstFastIO(filename, rw_mode);
00540                 break;
00541         case IMAGE_PIF:
00542                 imageio = new PifIO(filename, rw_mode);
00543                 break;
00544         case IMAGE_VTK:
00545                 imageio = new VtkIO(filename, rw_mode);
00546                 break;
00547         case IMAGE_SPIDER:
00548                 imageio = new SpiderIO(filename, rw_mode);
00549                 break;
00550         case IMAGE_SINGLE_SPIDER:
00551                 imageio = new SingleSpiderIO(filename, rw_mode);
00552                 break;
00553         case IMAGE_PGM:
00554                 imageio = new PgmIO(filename, rw_mode);
00555                 break;
00556 #ifdef EM_JPEG
00557         case IMAGE_JPEG:
00558                 imageio = new JpegIO(filename,rw_mode);
00559                 break;
00560 #endif
00561         case IMAGE_ICOS:
00562                 imageio = new IcosIO(filename, rw_mode);
00563                 break;
00564 #ifdef EM_PNG
00565         case IMAGE_PNG:
00566                 imageio = new PngIO(filename, rw_mode);
00567                 break;
00568 #endif
00569         case IMAGE_SAL:
00570                 imageio = new SalIO(filename, rw_mode);
00571                 break;
00572         case IMAGE_AMIRA:
00573                 imageio = new AmiraIO(filename, rw_mode);
00574                 break;
00575         case IMAGE_GATAN2:
00576                 imageio = new Gatan2IO(filename, rw_mode);
00577                 break;
00578         case IMAGE_EM:
00579                 imageio = new EmIO(filename, rw_mode);
00580                 break;
00581         case IMAGE_XPLOR:
00582                 imageio = new XplorIO(filename, rw_mode);
00583                 break;
00584         case IMAGE_FITS:
00585                 imageio = new FitsIO(filename, rw_mode);
00586                 break;
00587         case IMAGE_DF3:
00588                 imageio = new Df3IO(filename, rw_mode);
00589                 break;
00590         default:
00591                 break;
00592         }
00593 #ifdef IMAGEIO_CACHE
00594         GlobalCache::instance()->add_imageio(filename, rw, imageio);
00595 #endif
00596         EXITFUNC;
00597         return imageio;
00598 }
00599 
00600 
00601 
00602 const char *EMUtil::get_imagetype_name(ImageType t)
00603 {
00604         switch (t) {
00605         case IMAGE_V4L:
00606                 return "V4L2";
00607                 break;
00608         case IMAGE_MRC:
00609                 return "MRC";
00610                 break;
00611         case IMAGE_SPIDER:
00612                 return "SPIDER";
00613                 break;
00614         case IMAGE_SINGLE_SPIDER:
00615                 return "Single-SPIDER";
00616                 break;
00617         case IMAGE_IMAGIC:
00618                 return "IMAGIC";
00619                 break;
00620         case IMAGE_PGM:
00621                 return "PGM";
00622                 break;
00623         case IMAGE_LST:
00624                 return "LST";
00625                 break;
00626         case IMAGE_LSTFAST:
00627                 return "Fast LST";
00628                 break;
00629         case IMAGE_PIF:
00630                 return "PIF";
00631                 break;
00632         case IMAGE_PNG:
00633                 return "PNG";
00634                 break;
00635         case IMAGE_HDF:
00636                 return "HDF5";
00637                 break;
00638         case IMAGE_DM3:
00639                 return "GatanDM3";
00640                 break;
00641         case IMAGE_TIFF:
00642                 return "TIFF";
00643                 break;
00644         case IMAGE_VTK:
00645                 return "VTK";
00646                 break;
00647         case IMAGE_SAL:
00648                 return "HDR";
00649                 break;
00650         case IMAGE_ICOS:
00651                 return "ICOS_MAP";
00652                 break;
00653         case IMAGE_EMIM:
00654                 return "EMIM";
00655                 break;
00656         case IMAGE_GATAN2:
00657                 return "GatanDM2";
00658                 break;
00659         case IMAGE_JPEG:
00660                 return "JPEG";
00661                 break;
00662         case IMAGE_AMIRA:
00663                 return "AmiraMesh";
00664                 break;
00665         case IMAGE_XPLOR:
00666                 return "XPLOR";
00667                 break;
00668         case IMAGE_EM:
00669                 return "EM";
00670                 break;
00671         case IMAGE_FITS:
00672                 return "FITS";
00673                 break;
00674         case IMAGE_DF3:
00675                 return "DF3";
00676                 break;
00677         case IMAGE_UNKNOWN:
00678                 return "unknown";
00679         }
00680         return "unknown";
00681 }
00682 
00683 const char *EMUtil::get_datatype_string(EMDataType type)
00684 {
00685         switch (type) {
00686         case EM_CHAR:
00687                 return "CHAR";
00688         case EM_UCHAR:
00689                 return "UNSIGNED CHAR";
00690         case EM_SHORT:
00691                 return "SHORT";
00692         case EM_USHORT:
00693                 return "UNSIGNED SHORT";
00694         case EM_INT:
00695                 return "INT";
00696         case EM_UINT:
00697                 return "UNSIGNED INT";
00698         case EM_FLOAT:
00699                 return "FLOAT";
00700         case EM_DOUBLE:
00701                 return "DOUBLE";
00702         case EM_SHORT_COMPLEX:
00703                 return "SHORT_COMPLEX";
00704         case EM_USHORT_COMPLEX:
00705                 return "USHORT_COMPLEX";
00706         case EM_FLOAT_COMPLEX:
00707                 return "FLOAT_COMPLEX";
00708         case EM_UNKNOWN:
00709                 return "UNKNOWN";
00710         }
00711         return "UNKNOWN";
00712 }
00713 
00714 void EMUtil::get_region_dims(const Region * area, int nx, int *area_x,
00715                                                          int ny, int *area_y, int nz, int *area_z)
00716 {
00717         Assert(area_x);
00718         Assert(area_y);
00719 
00720         if (!area) {
00721                 *area_x = nx;
00722                 *area_y = ny;
00723                 if (area_z) {
00724                         *area_z = nz;
00725                 }
00726         }
00727         else {
00728                 Vec3i size = area->get_size();
00729                 *area_x = size[0];
00730                 *area_y = size[1];
00731 
00732                 if (area_z) {
00733                         if (area->get_ndim() > 2 && nz > 1) {
00734                                 *area_z = size[2];
00735                         }
00736                         else {
00737                                 *area_z = 1;
00738                         }
00739                 }
00740 
00741         }
00742 }
00743 
00744 void EMUtil::get_region_origins(const Region * area, int *p_x0, int *p_y0, int *p_z0,
00745                                                                 int nz, int image_index)
00746 {
00747         Assert(p_x0);
00748         Assert(p_y0);
00749 
00750         if (area) {
00751                 *p_x0 = static_cast < int >(area->origin[0]);
00752                 *p_y0 = static_cast < int >(area->origin[1]);
00753 
00754                 if (p_z0 && nz > 1 && area->get_ndim() > 2) {
00755                         *p_z0 = static_cast < int >(area->origin[2]);
00756                 }
00757         }
00758         else {
00759                 *p_x0 = 0;
00760                 *p_y0 = 0;
00761                 if (p_z0) {
00762                         *p_z0 = nz > 1 ? 0 : image_index;
00763                 }
00764         }
00765 }
00766 
00767 
00768 void EMUtil::process_region_io(void *vdata, FILE * file,
00769                                                            int rw_mode, int image_index,
00770                                                            size_t mode_size, int nx, int ny, int nz,
00771                                                            const Region * area, bool need_flip,
00772                                                            ImageType imgtype, int pre_row, int post_row)
00773 {
00774         Assert(vdata != 0);
00775         Assert(file != 0);
00776         Assert(rw_mode == ImageIO::READ_ONLY ||
00777                    rw_mode == ImageIO::READ_WRITE ||
00778                    rw_mode == ImageIO::WRITE_ONLY);
00779 
00780         if (mode_size == 0) throw UnexpectedBehaviorException("The mode size was 0?");
00781 
00782         unsigned char * cdata = (unsigned char *)vdata;
00783 
00784         int dx0 = 0; // data x0
00785         int dy0 = 0; // data y0
00786         int dz0 = 0; // data z0
00787 
00788         int fx0 = 0; // file x0
00789         int fy0 = 0; // file y0
00790         int fz0 = nz > 1 ? 0 : image_index; // file z0
00791 
00792 
00793         int xlen = 0;
00794         int ylen = 0;
00795         int zlen = 0;
00796         get_region_dims(area, nx, &xlen, ny, &ylen, nz, &zlen);
00797 
00798         if (area) { // Accommodate for all boundary overlaps of the region
00799 
00800                 Vec3i origin = area->get_origin();
00801 
00802 
00803                 fx0 = origin[0]; dx0 = origin[0];
00804                 fy0 = origin[1]; dy0 = origin[1];
00805                 if (nz > 1 && area->get_ndim() > 2) {
00806                         fz0 = origin[2]; dz0 = origin[2];
00807                 }
00808 
00809                 if (need_flip) {
00810                         Vec3i size = area->get_size();
00811                         fy0 = ny-(origin[1]+size[1]);
00812                 }
00813 
00814                 if (fx0 < 0) {
00815                         dx0 *= -1;
00816                         xlen = xlen + fx0; // because there are less reads
00817                         fx0 = 0;
00818                 }else {
00819                         dx0 = 0;
00820                         //fx0 *= -1;
00821                 }
00822                 if (fy0 < 0) {
00823                         dy0 *= -1;
00824                         ylen = ylen + fy0; // because there are less reads
00825                         fy0 = 0;
00826                 }else {
00827                         if (need_flip){
00828                                 dy0*=-1;
00829                         }
00830                         else dy0 = 0;
00831                         //fy0 *= -1;
00832                 }
00833                 if (fz0 < 0) {
00834                         dz0 *= -1;
00835                         zlen = zlen + fz0; // because there are less reads
00836                         fz0 = 0;
00837                 }else {
00838                         dz0 = 0;
00839                         //fz0 *= -1;
00840                 }
00841 
00842                 if ((fx0 + xlen)> nx) xlen = nx-fx0;
00843                 if ((fy0 + ylen)> ny) ylen = ny-fy0;
00844                 if ((fz0 + zlen)> nz) zlen = nz-fz0;
00845                 if ( xlen <= 0 || ylen <= 0 || zlen <= 0 ) return; // This is fine the region was entirely outside the image
00846         }
00847 
00848         if ( xlen <= 0 ) {
00849                 cout << "Xlen was too small " << xlen << endl;
00850                 return;
00851         }
00852 
00853         Vec3i size;
00854         if (area != 0) size = area->get_size();
00855         else size = Vec3d(nx,ny,nz);
00856 
00857         //size_t area_sec_size = xlen * ylen * mode_size;
00858         size_t memory_sec_size = size[0] * size[1] * mode_size;
00859         size_t img_row_size = nx * mode_size + pre_row + post_row;
00860         size_t area_row_size = xlen * mode_size;
00861         size_t memory_row_size = size[0] * mode_size;
00862 
00863         if ( area_row_size <= 0 ) {
00864                 cout << "Xlen was too small " << xlen << " mode_size " << mode_size << endl;
00865                 return;
00866         }
00867 
00868         size_t x_pre_gap = fx0 * mode_size;
00869         size_t x_post_gap = (nx - fx0 - xlen) * mode_size;
00870 
00871         size_t y_pre_gap = fy0 * img_row_size;
00872         size_t y_post_gap = (ny - fy0 - ylen) * img_row_size;
00873 
00874         portable_fseek(file, img_row_size * ny * fz0, SEEK_CUR);
00875 
00876         float nxlendata[1];
00877         int floatsize = (int) sizeof(float);
00878         nxlendata[0] = (float)(nx * floatsize);
00879 
00880         for (int k = dz0; k < (dz0+zlen); k++) {
00881                 if (y_pre_gap > 0) {
00882                         portable_fseek(file, y_pre_gap, SEEK_CUR);
00883                 }
00884                 //long k2 = k * area_sec_size;
00885                 long k2 = k*memory_sec_size;
00886 
00887                 for (int j = dy0; j < (dy0+ylen); j++) {
00888                         if (pre_row > 0) {
00889                                 if (imgtype == IMAGE_ICOS && rw_mode != ImageIO::READ_ONLY && !area) {
00890                                         fwrite(nxlendata, floatsize, 1, file);
00891                                 }
00892                                 else {
00893                                         portable_fseek(file, pre_row, SEEK_CUR);
00894                                 }
00895                         }
00896 
00897                         if (x_pre_gap > 0) {
00898                                 portable_fseek(file, x_pre_gap, SEEK_CUR);
00899                         }
00900 
00901                         int jj = j;
00902                         if (need_flip) {
00903                                 jj = (dy0+ylen) - 1 - j;
00904                                 if (dy0 > 0 ) { // region considerations add complications in the flipping scenario (imagic format)
00905                                         jj += dy0;
00906                                 }
00907                         }
00908 
00909                         if (rw_mode == ImageIO::READ_ONLY) {
00910                                 if (fread(&cdata[k2 + jj * memory_row_size+dx0*mode_size],
00911                                                   area_row_size, 1, file) != 1) {
00912                                         cout << jj << " " << k2 << " " << memory_row_size << " " << dx0 << " " << mode_size << " " << area_row_size << " " << cdata << "done" << endl;
00913                                         throw ImageReadException("", "incomplete data read");
00914                                 }
00915                         }
00916                         else {
00917                                 if (fwrite(&cdata[k2 + jj * memory_row_size+dx0*mode_size],
00918                                                    area_row_size, 1, file) != 1) {
00919                                         throw ImageWriteException("", "incomplete data write");
00920                                 }
00921                         }
00922 
00923                         if (x_post_gap > 0) {
00924                                 portable_fseek(file, x_post_gap, SEEK_CUR);
00925                         }
00926 
00927                         if (post_row > 0) {
00928                                 if (imgtype == IMAGE_ICOS && rw_mode != ImageIO::READ_ONLY && !area) {
00929                                         fwrite(nxlendata, floatsize, 1, file);
00930                                 }
00931                                 else {
00932                                         portable_fseek(file, post_row, SEEK_CUR);
00933                                 }
00934                         }
00935                 }
00936 
00937                 if (y_post_gap > 0) {
00938                         portable_fseek(file, y_post_gap, SEEK_CUR);
00939                 }
00940         }
00941 }
00942 
00943 
00944 void EMUtil::dump_dict(const Dict & dict)
00945 {
00946         vector < string > keys = dict.keys();
00947         vector < EMObject > values = dict.values();
00948 
00949         for (unsigned int i = 0; i < keys.size(); i++) {
00950                 EMObject obj = values[i];
00951                 if( !obj.is_null() ) {
00952                         string val = obj.to_str();
00953 
00954                         if (keys[i] == "datatype") {
00955                                 val = get_datatype_string((EMDataType) (int) obj);
00956                         }
00957 
00958                         fprintf(stdout, "%25s\t%s\n", keys[i].c_str(), val.c_str());
00959                 }
00960         }
00961 }
00962 
00963 
00964 bool EMUtil::is_same_size(const EMData * const em1, const EMData * const em2)
00965 {
00966         if (em1->get_xsize() == em2->get_xsize() &&
00967                 em1->get_ysize() == em2->get_ysize() &&
00968                 em1->get_zsize() == em2->get_zsize()) {
00969                 return true;
00970         }
00971         return false;
00972 }
00973 
00974 bool EMUtil::is_complex_type(EMDataType datatype)
00975 {
00976         if (datatype == EM_SHORT_COMPLEX ||
00977                 datatype == EM_USHORT_COMPLEX ||
00978                 datatype == EM_FLOAT_COMPLEX) {
00979                 return true;
00980         }
00981         return false;
00982 }
00983 
00984 
00985 EMData *EMUtil::vertical_acf(const EMData * image, int maxdy)
00986 {
00987         if (!image) {
00988                 throw NullPointerException("NULL Image");
00989         }
00990 
00991         EMData *ret = new EMData();
00992         int nx = image->get_xsize();
00993         int ny = image->get_ysize();
00994 
00995         if (maxdy <= 1) {
00996                 maxdy = ny / 8;
00997         }
00998 
00999         ret->set_size(nx, maxdy, 1);
01000 
01001         float *data = image->get_data();
01002         float *ret_data = ret->get_data();
01003 
01004         for (int x = 0; x < nx; x++) {
01005                 for (int y = 0; y < maxdy; y++) {
01006                         float dot = 0;
01007                         for (int yy = maxdy; yy < ny - maxdy; yy++) {
01008                                 dot += data[x + (yy + y) * nx] * data[x + (yy - y) * nx];
01009                         }
01010                         ret_data[x + y * nx] = dot;
01011                 }
01012         }
01013 
01014         ret->update();
01015 
01016         return ret;
01017 }
01018 
01019 
01020 
01021 EMData *EMUtil::make_image_median(const vector < EMData * >&image_list)
01022 {
01023         if (image_list.size() == 0) {
01024                 return 0;
01025         }
01026 
01027         EMData *image0 = image_list[0];
01028         int image0_nx = image0->get_xsize();
01029         int image0_ny = image0->get_ysize();
01030         int image0_nz = image0->get_zsize();
01031         size_t size = (size_t)image0_nx * image0_ny * image0_nz;
01032 
01033         EMData *result = new EMData();
01034 
01035         result->set_size(image0_nx, image0_ny, image0_nz);
01036 
01037         float *dest = result->get_data();
01038         int nitems = static_cast < int >(image_list.size());
01039         float *srt = new float[nitems];
01040         float **src = new float *[nitems];
01041 
01042         for (int i = 0; i < nitems; i++) {
01043                 src[i] = image_list[i]->get_data();
01044         }
01045 
01046         for (size_t i = 0; i < size; ++i) {
01047                 for (int j = 0; j < nitems; j++) {
01048                         srt[j] = src[j][i];
01049                 }
01050 
01051                 for (int j = 0; j < nitems; j++) {
01052                         for (int k = j + 1; k < nitems; k++) {
01053                                 if (srt[j] < srt[k]) {
01054                                         float v = srt[j];
01055                                         srt[j] = srt[k];
01056                                         srt[k] = v;
01057                                 }
01058                         }
01059                 }
01060 
01061                 int l = nitems / 2;
01062                 if (nitems < 3) {
01063                         dest[i] = srt[l];
01064                 }
01065                 else {
01066                         dest[i] = (srt[l] + srt[l + 1] + srt[l - 1]) / 3.0f;
01067                 }
01068         }
01069 
01070         if( srt )
01071         {
01072                 delete[]srt;
01073                 srt = 0;
01074         }
01075         if( src )
01076         {
01077                 delete[]src;
01078                 src = 0;
01079         }
01080 
01081         result->update();
01082 
01083         return result;
01084 }
01085 
01086 bool EMUtil::is_same_ctf(const EMData * image1, const EMData * image2)
01087 {
01088         if (!image1) {
01089                 throw NullPointerException("image1 is NULL");
01090         }
01091         if (!image2) {
01092                 throw NullPointerException("image2 is NULL");
01093         }
01094 
01095         Ctf *ctf1 = image1->get_ctf();
01096         Ctf *ctf2 = image2->get_ctf();
01097 
01098         if ((!ctf1 && !ctf2) && (image1->has_ctff() == false && image2->has_ctff() == false)) {
01099                 return true;
01100         }
01101 
01102         if (ctf1 && ctf2) {
01103                 bool result = ctf1->equal(ctf2);
01104                 delete ctf1;
01105                 ctf1 = 0;
01106                 delete ctf2;
01107                 ctf2 = 0;
01108 
01109                 return result;
01110         }
01111         return false;
01112 }
01113 
01114 static int imgscore_cmp(const void *imgscore1, const void *imgscore2)
01115 {
01116         Assert(imgscore1 != 0);
01117         Assert(imgscore2 != 0);
01118 
01119         float c = ((ImageScore *)imgscore1)->score - ((ImageScore *)imgscore2)->score;
01120         if (c<0) {
01121                 return 1;
01122         }
01123         else if (c>0) {
01124                 return -1;
01125         }
01126         return 0;
01127 }
01128 
01129 ImageSort::ImageSort(int nn)
01130 {
01131         Assert(nn > 0);
01132         n = nn;
01133         image_scores = new ImageScore[n];
01134 }
01135 
01136 ImageSort::~ImageSort()
01137 {
01138         if( image_scores )
01139         {
01140                 delete [] image_scores;
01141                 image_scores = 0;
01142         }
01143 }
01144 
01145 void ImageSort::sort()
01146 {
01147         qsort(image_scores, n, sizeof(ImageScore), imgscore_cmp);
01148 
01149 }
01150 
01151 void ImageSort::set(int i, float score)
01152 {
01153         Assert(i >= 0);
01154         image_scores[i] = ImageScore(i, score);
01155 }
01156 
01157 int ImageSort::get_index(int i) const
01158 {
01159         Assert(i >= 0);
01160         return image_scores[i].index;
01161 }
01162 
01163 
01164 float ImageSort::get_score(int i) const
01165 {
01166         Assert(i >= 0);
01167         return image_scores[i].score;
01168 }
01169 
01170 
01171 int ImageSort::size() const
01172 {
01173         return n;
01174 }
01175 
01176 
01177 void EMUtil::process_ascii_region_io(float *data, FILE * file, int rw_mode,
01178                                                                          int , size_t mode_size, int nx, int ny, int nz,
01179                                                                          const Region * area, bool has_index_line,
01180                                                                          int nitems_per_line, const char *outformat)
01181 {
01182         Assert(data != 0);
01183         Assert(file != 0);
01184         Assert(rw_mode == ImageIO::READ_ONLY ||
01185                    rw_mode == ImageIO::READ_WRITE ||
01186                    rw_mode == ImageIO::WRITE_ONLY);
01187 
01188         int xlen = 0, ylen = 0, zlen = 0;
01189         get_region_dims(area, nx, &xlen, ny, &ylen, nz, &zlen);
01190 
01191         int x0 = 0;
01192         int y0 = 0;
01193         int z0 = 0;
01194 
01195         if (area) {
01196                 x0 = (int)area->origin[0];
01197                 y0 = (int)area->origin[1];
01198                 z0 = (int)area->origin[2];
01199         }
01200 
01201         int nlines_per_sec = (nx *ny) / nitems_per_line;
01202         int nitems_last_line = (nx * ny) % nitems_per_line;
01203         if (nitems_last_line != 0) {
01204                 nlines_per_sec++;
01205         }
01206 
01207         if (has_index_line) {
01208                 nlines_per_sec++;
01209         }
01210 
01211         if (z0 > 0) {
01212                 jump_lines(file, z0 * nlines_per_sec);
01213         }
01214 
01215 
01216         int nlines_pre_sec = (y0 * nx + x0) / nitems_per_line;
01217         int gap_nitems = nx - xlen;
01218         int ti = 0;
01219         int rlines = 0;
01220 
01221         for (int k = 0; k < zlen; k++) {
01222                 EMUtil::jump_lines(file, nlines_pre_sec+1);
01223 
01224                 int head_nitems = (y0 * nx + x0) % nitems_per_line;
01225                 int tail_nitems = 0;
01226                 bool is_head_read = false;
01227 
01228                 for (int j = 0; j < ylen; j++) {
01229 
01230                         if (head_nitems > 0 && !is_head_read) {
01231                                 EMUtil::process_numbers_io(file, rw_mode, nitems_per_line, mode_size,
01232                                                                                    nitems_per_line-head_nitems,
01233                                                                                    nitems_per_line-1, data, &ti, outformat);
01234                                 rlines++;
01235                         }
01236 
01237                         EMUtil::process_lines_io(file, rw_mode, nitems_per_line,
01238                                                                          mode_size, (xlen - head_nitems),
01239                                                                          data, &ti, outformat);
01240 
01241                         rlines += ((xlen - head_nitems)/nitems_per_line);
01242 
01243                         tail_nitems = (xlen - head_nitems) % nitems_per_line;
01244 
01245                         if ((gap_nitems + tail_nitems) > 0) {
01246                                 head_nitems = nitems_per_line -
01247                                         (gap_nitems + tail_nitems) % nitems_per_line;
01248                         }
01249                         else {
01250                                 head_nitems = 0;
01251                         }
01252 
01253                         is_head_read = false;
01254 
01255                         if (tail_nitems > 0) {
01256                                 if ((gap_nitems < (nitems_per_line-tail_nitems)) &&
01257                                         (j != (ylen-1))) {
01258                                         EMUtil::exclude_numbers_io(file, rw_mode, nitems_per_line,
01259                                                                                            mode_size, tail_nitems,
01260                                                                                            tail_nitems+gap_nitems-1, data, &ti, outformat);
01261                                         is_head_read = true;
01262                                         rlines++;
01263                                 }
01264                                 else {
01265                                         EMUtil::process_numbers_io(file, rw_mode, nitems_per_line, mode_size,
01266                                                                                            0, tail_nitems-1, data, &ti, outformat);
01267                                         rlines++;
01268                                 }
01269                         }
01270 
01271                         if (gap_nitems > (nitems_per_line-tail_nitems)) {
01272                                 int gap_nlines = (gap_nitems - (nitems_per_line-tail_nitems)) /
01273                                         nitems_per_line;
01274                                 if (gap_nlines > 0 && j != (ylen-1)) {
01275                                         EMUtil::jump_lines(file, gap_nlines);
01276                                 }
01277                         }
01278                 }
01279 
01280                 int ytail_nitems = (ny-ylen-y0) * nx + (nx-xlen-x0) - (nitems_per_line-tail_nitems);
01281                 EMUtil::jump_lines_by_items(file, ytail_nitems, nitems_per_line);
01282         }
01283 }
01284 
01285 
01286 void EMUtil::jump_lines_by_items(FILE * file, int nitems, int nitems_per_line)
01287 {
01288         Assert(file);
01289         Assert(nitems_per_line > 0);
01290 
01291         if (nitems <= 0) {
01292                 return;
01293         }
01294 
01295         int nlines = nitems / nitems_per_line;
01296         if ((nitems % nitems_per_line) != 0) {
01297                 nlines++;
01298         }
01299         if (nlines > 0) {
01300                 jump_lines(file, nlines);
01301         }
01302 }
01303 
01304 
01305 void EMUtil::jump_lines(FILE * file, int nlines)
01306 {
01307         Assert(file);
01308 
01309         if (nlines > 0) {
01310                 char line[MAXPATHLEN];
01311                 for (int l = 0; l < nlines; l++) {
01312                         if (!fgets(line, sizeof(line), file)) {
01313                                 Assert("read xplor file failed");
01314                         }
01315                 }
01316         }
01317 }
01318 
01319 void EMUtil::process_numbers_io(FILE * file, int rw_mode,
01320                                                                 int nitems_per_line, size_t mode_size, int start,
01321                                                                 int end, float *data, int *p_i, const char * outformat)
01322 {
01323         Assert(file);
01324         Assert(start >= 0);
01325         Assert(start <= end);
01326         Assert(end <= nitems_per_line);
01327         Assert(data);
01328         Assert(p_i);
01329         Assert(outformat);
01330 
01331         char line[MAXPATHLEN];
01332 
01333         if (rw_mode == ImageIO::READ_ONLY) {
01334                 if (!fgets(line, sizeof(line), file)) {
01335                         Assert("read xplor file failed");
01336                 }
01337 
01338                 int nitems_in_line = (int) (strlen(line) / mode_size);
01339                 Assert(end <= nitems_in_line);
01340                 vector<float> d(nitems_in_line);
01341                 char * pline = line;
01342 
01343                 for (int i = 0; i < nitems_in_line; i++) {
01344                         sscanf(pline, "%f", &d[i]);
01345                         pline += (int)mode_size;
01346                 }
01347 
01348 
01349                 for (int i = start; i <= end; i++) {
01350                         data[*p_i] = d[i];
01351                         (*p_i)++;
01352                 }
01353         }
01354         else {
01355                 portable_fseek(file, mode_size * start, SEEK_CUR);
01356                 for (int i = start; i <= end; i++) {
01357                         fprintf(file, outformat, data[*p_i]);
01358                         (*p_i)++;
01359                 }
01360 
01361                 portable_fseek(file, mode_size * (nitems_per_line - end-1)+1, SEEK_CUR);
01362         }
01363 }
01364 
01365 
01366 void EMUtil::exclude_numbers_io(FILE * file, int rw_mode,
01367                                                                 int nitems_per_line, size_t mode_size, int start,
01368                                                                 int end, float * data, int *p_i, const char * outformat)
01369 {
01370         Assert(file);
01371         Assert(mode_size > 0);
01372         Assert(start >= 0);
01373         Assert(end <= nitems_per_line);
01374         Assert(data);
01375         Assert(p_i);
01376         Assert(outformat);
01377 
01378         char line[MAXPATHLEN];
01379 
01380         if (rw_mode == ImageIO::READ_ONLY) {
01381 
01382                 if (!fgets(line, sizeof(line), file)) {
01383                         Assert("read xplor file failed");
01384                 }
01385 
01386                 int nitems_in_line =  (int) (strlen(line) / mode_size);
01387                 Assert(end <= nitems_in_line);
01388 
01389                 vector<float> d(nitems_in_line);
01390                 char *pline = line;
01391 
01392                 for (int i = 0; i < nitems_in_line; i++) {
01393                         sscanf(pline, "%f", &d[i]);
01394                         pline = pline + (int)mode_size;
01395                 }
01396 
01397 
01398                 for (int i = 0; i < start; i++) {
01399                         data[*p_i] = d[i];
01400                         (*p_i)++;
01401                 }
01402 
01403                 for (int i = end+1; i < nitems_in_line; i++) {
01404                         data[*p_i] = d[i];
01405                         (*p_i)++;
01406                 }
01407         }
01408         else {
01409                 for (int i = 0; i < start; i++) {
01410                         fprintf(file, outformat, data[*p_i]);
01411                         (*p_i)++;
01412                 }
01413 
01414                 portable_fseek(file, (end-start+1) * mode_size, SEEK_CUR);
01415 
01416                 for (int i = end+1; i < nitems_per_line; i++) {
01417                         fprintf(file, outformat, data[*p_i]);
01418                         (*p_i)++;
01419                 }
01420                 portable_fseek(file, 1, SEEK_CUR);
01421         }
01422 }
01423 
01424 void EMUtil::process_lines_io(FILE * file, int rw_mode,
01425                                                           int nitems_per_line, size_t mode_size,
01426                                                           int nitems, float *data, int *p_i,
01427                                                           const char * outformat)
01428 {
01429         Assert(file);
01430         Assert(data);
01431         Assert(p_i);
01432 
01433         if (nitems > 0) {
01434                 int nlines = nitems / nitems_per_line;
01435                 for (int i = 0; i < nlines; i++) {
01436                         EMUtil::process_numbers_io(file, rw_mode, nitems_per_line, mode_size, 0,
01437                                                                            nitems_per_line-1, data, p_i, outformat);
01438                 }
01439         }
01440 }
01441 
01442 vector<string> EMUtil::get_euler_names(const string & euler_type)
01443 {
01444     vector<string> v;
01445     string b = "euler_";
01446 
01447     if (euler_type == "EMAN") {
01448         v.push_back(b + "alt");
01449         v.push_back(b + "az");
01450         v.push_back(b + "phi");
01451     }
01452     else if (euler_type == "MRC") {
01453         v.push_back(b + "theta");
01454         v.push_back(b + "phi");
01455         v.push_back(b + "omega");
01456     }
01457     else if (euler_type == "IMAGIC") {
01458         v.push_back(b + "alpha");
01459         v.push_back(b + "beta");
01460         v.push_back(b + "gamma");
01461     }
01462     else if (euler_type == "SPIDER") {
01463         v.push_back(b + "phi");
01464         v.push_back(b + "theta");
01465         v.push_back(b + "gamma");
01466     }
01467     else if (euler_type == "SPIN" ||
01468              euler_type == "SGIROT") {
01469         v.push_back(b + "q");
01470         v.push_back(b + "n1");
01471         v.push_back(b + "n2");
01472         v.push_back(b + "n3");
01473     }
01474 
01475     else if (euler_type == "QUATERNION") {
01476         v.push_back(b + "e0");
01477         v.push_back(b + "e1");
01478         v.push_back(b + "e2");
01479         v.push_back(b + "e3");
01480     }
01481 
01482     return v;
01483 }
01484 
01485 
01486 vector<EMObject> EMUtil::get_all_attributes(const string & file_name, const string & attr_name)
01487 {
01488         vector<EMObject> v;
01489 
01490         Assert(file_name != "");
01491         Assert(attr_name != "");
01492 
01493         vector< shared_ptr<EMData> > vpImg = EMData::read_images(file_name, vector<int>(), true);
01494         vector< shared_ptr<EMData> >::const_iterator iter;
01495         for(iter = vpImg.begin(); iter!=vpImg.end(); ++iter) {
01496                 v.push_back((*iter)->get_attr_default(attr_name));
01497         }
01498 
01499         return v;
01500 }
01501 
01502 void EMUtil::getRenderMinMax(float * data, const int nx, const int ny, float& rendermin, float& rendermax, const int nz)
01503 {
01504 #ifdef _WIN32
01505         if (rendermax<=rendermin || _isnan(rendermin) || _isnan(rendermax)) {
01506 #else
01507         if (rendermax<=rendermin || std::isnan(rendermin) || std::isnan(rendermax)) {
01508 #endif
01509                 float m=0.0f,s=0.0f;
01510 
01511                 size_t size = (size_t)nx*ny*nz;
01512                 float min=data[0],max=data[0];
01513 
01514                 for (size_t i=0; i<size; ++i) { m+=data[i]; s+=data[i]*data[i]; min=data[i]<min?data[i]:min; max=data[i]>max?data[i]:max; }
01515                 m/=(float)(size);
01516                 s=sqrt(s/(float)(size)-m*m);
01517 #ifdef _WIN32
01518                 if (s<=0 || _isnan(s)) s=1.0;   // this means all data values are the same
01519 #else
01520                 if (s<=0 || std::isnan(s)) s=1.0;       // this means all data values are the same
01521 #endif  //_WIN32
01522                 rendermin=m-s*5.0f;
01523                 rendermax=m+s*5.0f;
01524                 if (rendermin<=min) rendermin=min;
01525                 if (rendermax>=max) rendermax=max;
01526         }
01527 }
01528 
01529 #ifdef EM_HDF5
01530 EMObject EMUtil::read_hdf_attribute(const string & filename, const string & key, int image_index)
01531 {
01532         ImageType image_type = get_image_type(filename);
01533         if(image_type != IMAGE_HDF) {
01534                 throw ImageFormatException("This function only applies to HDF5 file.");
01535         }
01536 
01537         HdfIO2* imageio = new HdfIO2(filename, ImageIO::READ_ONLY);
01538         imageio->init();
01539 
01540         // Each image is in a group for later expansion. Open the group
01541         hid_t file = imageio->get_fileid();
01542         char ipath[50];
01543         sprintf(ipath,"/MDF/images/%d",image_index);
01544         hid_t igrp=H5Gopen(file,ipath);
01545 
01546         if (igrp<0) {   //group not existed
01547                 throw _NotExistingObjectException(string(ipath));
01548         }
01549 
01550         string s("EMAN.");
01551         s += key;
01552         hid_t attr = H5Aopen_name(igrp, s.c_str());
01553         EMObject emobj = imageio->read_attr(attr);
01554 
01555         H5Aclose(attr);
01556         H5Gclose(igrp);
01557         delete imageio;
01558 
01559         return emobj;
01560 }
01561 
01562 int EMUtil::write_hdf_attribute(const string & filename, const string & key, EMObject value, int image_index)
01563 {
01564         ImageType image_type = get_image_type(filename);
01565         if(image_type != IMAGE_HDF) {
01566                 throw ImageFormatException("This function only applies to HDF5 file.");
01567         }
01568 
01569         HdfIO2* imageio = new HdfIO2(filename, ImageIO::WRITE_ONLY);
01570         imageio->init();
01571 
01572         // Each image is in a group for later expansion. Open the group
01573         hid_t file = imageio->get_fileid();
01574         char ipath[50];
01575         sprintf(ipath,"/MDF/images/%d",image_index);
01576         hid_t igrp=H5Gopen(file,ipath);
01577 
01578         if (igrp<0) {   //group not existed
01579                 throw _NotExistingObjectException(string(ipath));
01580         }
01581 
01582         string s("EMAN.");
01583         s += key;
01584         int ret = imageio->write_attr(igrp, s.c_str(), value);
01585 
01586         H5Gclose(igrp);
01587         delete imageio;
01588 
01589         return ret;
01590 }
01591 
01592 int EMUtil::delete_hdf_attribute(const string & filename, const string & key, int image_index)
01593 {
01594         ImageType image_type = get_image_type(filename);
01595         if(image_type != IMAGE_HDF) {
01596                 throw ImageFormatException("This function only applies to HDF5 file.");
01597         }
01598 
01599         HdfIO2* imageio = new HdfIO2(filename, ImageIO::READ_WRITE);
01600         imageio->init();
01601 
01602         // Each image is in a group for later expansion. Open the group
01603         hid_t file = imageio->get_fileid();
01604         char ipath[50];
01605         sprintf(ipath,"/MDF/images/%d",image_index);
01606         hid_t igrp=H5Gopen(file,ipath);
01607 
01608         if (igrp<0) {   //group not existed
01609                 throw _NotExistingObjectException(string(ipath));
01610         }
01611 
01612         string s("EMAN.");
01613         s += key;
01614         herr_t ret = H5Adelete(igrp, s.c_str());
01615 
01616         H5Gclose(igrp);
01617         delete imageio;
01618 
01619         if(ret >= 0) return 0;
01620         else return -1;
01621 }
01622 #endif  //EM_HDF5

Generated on Mon May 2 13:26:52 2011 for EMAN2 by  doxygen 1.4.7