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

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

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