Xmipp  v3.23.11-Nereus
xmipp_image_base.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Authors: Joaquin Oton (joton@cnb.csic.es)
3  *
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #ifndef CORE_IMAGE_BASE_H_
27 #define CORE_IMAGE_BASE_H_
28 
29 #include <memory>
30 #include <array>
31 
33 #include "xmipp_datatype.h"
36 #include "xmipp_filename.h"
38 
39 #include <H5Ipublic.h>
40 
41 template<typename T>
42 class Matrix2D;
43 template<typename T>
44 class Image;
45 struct tiff;
46 typedef struct tiff TIFF;
48 class MetaData;
49 
50 /* Minimum size of a TIFF file to be mapped to a tempfile in case of mapping from
51  * image file is required
52  */
53 const size_t tiff_map_min_size = 0x12000000;
54 
57 
59 
62 typedef enum
63 {
64  NoTransform = 0, // No transform
65  Standard = 1, // Standard transform: origin = (0,0,0)
66  Centered = 2, // Centered transform: origin = (nx/2,ny/2,nz/2)
67  Hermitian = 3, // Hermitian half: origin = (0,0,0)
68  CentHerm = 4 // Centered hermitian: origin = (0,ny/2,nz/2)
70 
74 typedef enum
75 {
76  WRITE_READONLY, //only can read the file
77  WRITE_OVERWRITE, //forget about the old file and overwrite it
78  WRITE_REPLACE, //replace a particular object by another
79  WRITE_APPEND, //append and object at the end of a stack, so far can not append stacks
80  WRITE_LAST_LABEL // **** NOTE ****: Do keep this label always at the end
81  // it is here for looping purposes
83 
88 typedef enum
89 {
90  _NONE = -2, // Nothing to do. Used by ImageGeneric to check the right datatype to be used
91  HEADER = -1, //Don't read image data, only info from main header(datatype and dimensions)
92  _HEADER_ALL = 0, //Read complete header(main and geo), useful for header_extract and header_assign
93  DATA = 1, //Read image data and main header, geometrical transformations will be ignored
94  _DATA_ALL = 2 //Read data with complete header(the use of this option is not recommended, all Xmipp
95  // programs should read and write geo info through metadatas
96 }DataMode;
97 
98 /* Cast Write mode
99  * This enum defines the cast writing behavior
100  */
101 typedef enum
102 {
103  // prefix needed so extract_image_enums.py script can create the equivalent class for Java
104  CW_CAST, //Only cast the data type
105  CW_CONVERT, //Convert the data from one type to another
106  CW_ADJUST, //Adjust the histogram to fill the gray level range
107  CW_LAST_LABEL // **** NOTE ****: Do keep this label always at the end
108  // it is here for looping purposes
115 {
116  FILE* fimg; // Image File handler
117  FILE* fhed; // Image File header handler
118  TIFF* tif; // TIFF Image file handler
119  hid_t fhdf5; // HDF5 File handler
120  FileName fileName; // Image file name
121  FileName headName; // Header file name
122  FileName ext_name; // Filename extension
123  bool exist; // Shows if the file exists. Equal 0 means file does not exist or not stack.
124  int mode; // Opening mode behavior
125 };
127 struct ImageInfo
128 {
129  FileName filename;
130  size_t offset;
131  DataType datatype;
132  bool swap;
133  ArrayDim adim;
134 };
137 {
139  DataMode datamode;
140  size_t select_img;
141  bool wrap;
144  {
145  only_apply_shifts = false;
146  datamode = DATA;
147  select_img = ALL_IMAGES;
148  wrap = xmipp_transformation::WRAP;
149  }
150 };
153 
156 
168 #define VOLMATRIX(V) ((V).data)
169 
181 #define IMGMATRIX(I) ((I).data)
182 
186 #define IMGPIXEL(I, i, j) A2D_ELEM(((I).data), (i), (j))
187 
200 #define DIRECT_IMGPIXEL(I, i, j) DIRECT_A2D_ELEM(((I).data), (i), (j))
201 
214 #define VOLVOXEL(V, k, i, j) A3D_ELEM(((V).data), (k), (i), (j))
215 
228 #define DIRECT_VOLVOXEL(I, k, i, j) DIRECT_A3D_ELEM(((I).data), (k), (i), (j))
229 
234 #define SWAPTRIG 16776960
235 
236 
239 {
240 public:
241  MultidimArrayBase * mdaBase; // Pointer to data from Image<template T> casted as MultidimArrayBase
242  std::vector<std::unique_ptr<MDRow>> MD; // data for each subimage, always non-null data present, pointer is here
243  // to allow storing MDVec / MDSql
244  MDRowVec MDMainHeader; // data for the file
245 
246 protected:
247  FileName filename; // File name
248  FileName tempFilename; // Temporary filename
249  FileName dataFName; // Data File name without flags
250  FILE* fimg; // Image File handler
251  FILE* fhed; // Image File header handler
252  TIFF* tif; // TIFF Image file hander
253  hid_t fhdf5; // HDF5 File handler
254  ImageFHandler* hFile; // Image File handler information structure
255  ArrayDim aDimFile; // Image header file information structure (original info from file)
256  DataMode dataMode; // Flag to force select what will be read/write from image files
257  size_t offset; // Data offset
258  int swap; // Perform byte swapping upon reading
259  int swapWrite; // Perform byte swapping upon writing
260  std::array<int,4> axisOrder; // Order of the axis (tipically 0,1,2,3)
261  TransformType transform; // Transform type
262  size_t replaceNsize; // Stack size in the replace case
263  bool _exists; // does target file exists? // equal 0 if not exists or not a stack
264  bool mmapOnRead; // Mapping when reading from file
265  bool mmapOnWrite; // Mapping when writing to file
266  int mFd; // Handle the file in reading method and mmap
267  size_t mappedSize; // Size of the mapped file
268  size_t mappedOffset; // Offset for the mapped file
269  size_t virtualOffset; // MDA Offset when movePointerTo is used
270 
271  static constexpr std::array<int,4> defaultAxisOrder = {0,1,2,3}; // Default axis order
272 
273 public:
274 
277  void init();
278 
281  void copy(const ImageBase& other);
282 
285  virtual void clear()=0;
286 
288  void clearHeader();
289 
291  virtual bool isComplexT() const=0;
292 
294  bool isComplex() const
295  {
296  return !(transform==NoTransform);
297  }
298 
300  virtual ~ImageBase();
301 
305  bool isImage(const FileName &name);
306 
309  inline bool isMapped()
310  {
311  return (mmapOnRead || mmapOnWrite);
312  }
313 
318  bool isRealImage(const FileName &name)
319  {
320  return (isImage(name) && !isComplex());
321  }
322 
327  bool isComplexImage(const FileName &name)
328  {
329  return (isImage(name) && isComplex());
330  }
331 
333  void rename (const FileName &name)
334  {
335  filename = name;
336  }
337 
344  void mapFile2Write(size_t Xdim, size_t Ydim, size_t Zdim, const FileName &_filename,
345  bool createTempFile = false, size_t select_img = APPEND_IMAGE,
346  bool isStack = false, int mode = WRITE_OVERWRITE);
347 
361  int read(const FileName &name, DataMode datamode = DATA, size_t select_img = ALL_IMAGES,
362  bool mapData = false, int mode = WRITE_READONLY);
363 
368  int readBatch(const FileName &name, size_t start_img, size_t batch_size, DataMode datamode = DATA, bool mapData = false, int mode = WRITE_READONLY);
369 
374  int readRange(const FileName &name, size_t start_img, size_t end_img, DataMode datamode = DATA, bool mapData = false, int mode = WRITE_READONLY);
375 
385  int readApplyGeo(const FileName &name, const MDRow &row,
386  const ApplyGeoParams &params = DefaultApplyGeoParams);
387 
389  int readApplyGeo(const FileName &name, const MetaData &md, size_t objId,
390  const ApplyGeoParams &params = DefaultApplyGeoParams);
391 
393  int readApplyGeo(const MetaData &md, size_t objId,
394  const ApplyGeoParams &params = DefaultApplyGeoParams);
395 
397  void applyGeo(const MetaData &md, size_t objId,
398  const ApplyGeoParams &params = DefaultApplyGeoParams);
399 
403  void setGeo(const MDRow &row, size_t n=0);
404 
405  /* Read an image with a lower resolution as a preview image.
406  * If Zdim parameter is not passed, then all slices are rescaled.
407  * If Ydim is not passed, then Ydim is rescaled same factor as Xdim.
408  */
409 
410  /* Read image mapped from file */
411  int readMapped(const FileName &name, size_t select_img = ALL_IMAGES, int mode = WRITE_READONLY);
412 
413  /* Initially try to read normally, but if there is a memory allocation problem, then
414  * try to read from the mapped file.*/
415  int readOrReadMapped(const FileName &name, size_t select_img = ALL_IMAGES, int mode = WRITE_READONLY);
416 
417  /* Read a thumb/preview image version from file with other dimensions than image originals'.
418  * It is also possible to select an specific image from stack or slice from volume.
419  * This function is intended for previews of great image files as the image is not copy to memory.
420  */
421  virtual int readPreview(const FileName &name, size_t Xdim, size_t Ydim=0, int select_slice = CENTRAL_SLICE, size_t select_img = FIRST_IMAGE) = 0;
422 
427  virtual void getPreview(ImageBase *imgOut, size_t Xdim, size_t Ydim=0, int select_slice = CENTRAL_SLICE, size_t select_img = FIRST_IMAGE) = 0;
428 
434  int readOrReadPreview(const FileName &name, size_t Xdim, size_t Ydim, int select_slice = CENTRAL_SLICE, size_t select_img = FIRST_IMAGE, bool mapData = false);
435 
441  void write(const FileName &name="", size_t select_img = ALL_IMAGES, bool isStack=false,
442  int mode=WRITE_OVERWRITE,CastWriteMode castMode = CW_CAST, int _swapWrite = 0);
443 
466  virtual void movePointerTo(int select_slice = ALL_SLICES, size_t select_img = ALL_IMAGES) = 0;
467 
468  /* Return the datatype of the current image object */
469  virtual DataType myT() const = 0;
470 
472  virtual bool checkMmapT(DataType datatype)=0;
473 
479  virtual void writePageAsDatatype(FILE * fimg, DataType datatype, size_t datasize_n )=0;
480 
484  void swapPage(char * page, size_t pageNrElements, DataType datatype, int swap = 1);
485 
486  /* Force the swapping of the endianness of the file when writing, except for the case
487  * when appending or modifying the file.
488  */
489  void swapOnWrite()
490  {
491  swapWrite = true;
492  }
493 
500  const FileName & name() const
501  {
502  return filename;
503  }
504 
510  void getDimensions(size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim) const;
514  {
515  aDim = aDimFile;
516  }
518  {
519  return aDimFile;
520  }
521 
524  void getInfo(ImageInfo &imgInfo) const;
525 
528  void getInfo(const FileName &name, ImageInfo &imgInfo);
529 
532  virtual size_t getSize() const = 0;
533 
536  void getOffsetAndSwap(size_t &_offset, int &_swap) const
537  {
538  _offset = offset;
539  _swap = swap;
540  }
541 
544  int getSwap() const
545  {
546  return swap;
547  }
548 
551  MDRow& getGeometry(const size_t n = 0)
552  {
553  return *MD[n];
554  }
555 
558  void initGeometry(const size_t n = 0);
559 
560  /* Check if the label is in the individual header
561  */
563  {
564  return (!MD.empty() && MD[0]->containsLabel(label));
565  }
566 
567  /* Check if the label is in the main header */
568  bool mainContainsLabel(MDLabel label) const
569  {
570  return MDMainHeader.containsLabel(label);
571  }
572 
579  double rot(const size_t n = 0) const;
580 
587  double tilt(const size_t n = 0) const;
588 
595  double psi(const size_t n = 0) const;
596 
603  double Xoff(const size_t n = 0) const;
604 
611  double Yoff(const size_t n = 0) const;
612 
619  double Zoff(const size_t n = 0) const;
620 
627  double weight(const size_t n = 0) const;
628 
635  double scale(const size_t n = 0) const;
636 
643  bool flip(const size_t n = 0) const;
644 
653  DataType datatype() const;
654 
661  double samplingRateX() const;
662 
664  virtual void setDimensions(int Xdim, int Ydim, int Zdim, size_t Ndim) = 0;
665  virtual void setDimensions(ArrayDim &aDim);
666 
667 
671  {
672  aDimFile = aDim;
673  }
676  void setName(const FileName &_filename)
677  {
678  filename = _filename;
679  }
680 
684  {
685  dataMode = mode;
686  }
687 
690  void setEulerAngles(double rot, double tilt, double psi,
691  const size_t n = 0);
692 
695  void getEulerAngles(double &rot, double &tilt, double &psi,
696  const size_t n = 0) const;
697 
699  void setRot(double rot, const size_t n = 0)
700  {
701  MD[n]->setValue(MDL_ANGLE_ROT, rot);
702  }
703 
705  void setTilt(double tilt, const size_t n = 0)
706  {
707  MD[n]->setValue(MDL_ANGLE_TILT, tilt);
708  }
709 
711  void setPsi(double psi, const size_t n = 0)
712  {
713  MD[n]->setValue(MDL_ANGLE_PSI, psi);
714  }
715 
718  void setShifts(double xoff, double yoff, double zoff = 0.,
719  const size_t n = 0);
720 
723  void getShifts(double &xoff, double &yoff, double &zoff,
724  const size_t n = 0) const;
725 
728  void setXoff(double xoff, const size_t n = 0)
729  {
730  MD[n]->setValue(MDL_SHIFT_X, xoff);
731  }
732 
735  void setYoff(double yoff, const size_t n = 0)
736  {
737  MD[n]->setValue(MDL_SHIFT_Y, yoff);
738  }
739 
742  void setZoff(double zoff, const size_t n = 0)
743  {
744  MD[n]->setValue(MDL_SHIFT_Z, zoff);
745  }
746 
749  void setScale(double scale, const size_t n = 0)
750  {
751  MD[n]->setValue(MDL_SCALE, scale);
752  }
753 
756  void getScale(double &scale, const size_t n = 0)
757  {
758  MD[n]->getValue(MDL_SCALE, scale);
759  }
760 
763  void setFlip(bool flip, const size_t n = 0)
764  {
765  MD[n]->setValue(MDL_FLIP, flip);
766  }
767 
770  void setWeight(double weight, const size_t n = 0)
771  {
772  MD[n]->setValue(MDL_WEIGHT, weight);
773  }
774 
777  virtual void getTransformationMatrix(Matrix2D<double> &A,
778  bool only_apply_shifts = false,
779  const size_t n = 0)=0;
780 
783  virtual void sumWithFile(const FileName &fn)=0;
784 
788  virtual void mirrorY() =0;
791  virtual void selfApplyGeometry(int SplineDegree, bool wrap, bool only_apply_shifts)=0;
792 
793 
794 protected:
795 
799  // Functions belonging to this topic are commented in rw*.h
802 #include "rwDM3.h"
803 #include "rwDM4.h"
804 #include "rwIMAGIC.h"
805 #include "rwMRC.h"
806 #include "rwINF.h"
807 #include "rwRAW.h"
808 #include "rwSPIDER.h"
809 #include "rwSPE.h"
810 #include "rwTIA.h"
811 #include "rwJPEG.h"
812 #include "rwTIFF.h"
813 #include "rwEM.h"
814 #include "rwPIF.h"
815 #include "rwHDF5.h"
816 #include "rwEER.h"
817 
819 
823  ImageFHandler* openFile(const FileName &name, int mode = WRITE_READONLY) const;
824 
828  void closeFile(ImageFHandler* hFile = NULL) const;
829 
831  virtual void applyGeo(const MDRow &row, bool only_apply_shifts = false, bool wrap = xmipp_transformation::WRAP) = 0;
832 
835  int _read(const FileName &name, ImageFHandler* hFile, DataMode datamode = DATA, size_t select_img = ALL_IMAGES,
836  bool mapData = false);
837 
838  int _readBatch(const FileName &name, ImageFHandler* hFile, size_t start_img, size_t batch_size, DataMode datamode = DATA,
839  bool mapData = false);
840 
843  void _write(const FileName &name, ImageFHandler* hFile, size_t select_img = ALL_IMAGES,
844  bool isStack=false, int mode=WRITE_OVERWRITE,CastWriteMode castMode = CW_CAST);
845 
848  virtual void readData(FILE* fimg, size_t select_img, DataType datatype, size_t pad) = 0;
849 
852  virtual void readData4bit(FILE* fimg, size_t select_img, DataType datatype, size_t pad) = 0;
853 
856  virtual void writeData(FILE* fimg, size_t offset, DataType wDType, size_t datasize_n,
857  CastWriteMode castMode=CW_CAST) = 0;
858 
859  virtual void setPage2T(size_t offset, char * page, DataType datatype, size_t pageSize ) = 0;
860  virtual void getPageFromT(size_t offset, char * page, DataType datatype, size_t pageSize ) = 0;
861  virtual void getCastConvertPageFromT(size_t offset, char * page, DataType datatype, size_t pageSize, double min0, double max0, CastWriteMode castMode=CW_CONVERT) const = 0;
862 
865  virtual void mmapFile() = 0;
866 
869  virtual void munmapFile() = 0;
870 
873  void setDatatype(DataType datatype);
874 
876  friend std::ostream& operator<<(std::ostream& o, const ImageBase& I);
877 private:
878  // Auxiliary image used for special write case
879  Image<char> *m_auxI;
880 };
882 #endif /* IMAGE_BASE_H_ */
void selfApplyGeometry(int Splinedegree, MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside)
void setRot(double rot, const size_t n=0)
Rotation angle of an image (double,degrees)
std::array< int, 4 > axisOrder
void setScale(double scale, const size_t n=0)
MDRow & getGeometry(const size_t n=0)
struct tiff TIFF
DataMode dataMode
ArrayDim aDimFile
void write(std::ostream &os, const datablock &db)
Definition: cif2pdb.cpp:3747
size_t mappedOffset
int getSwap() const
TransformType
bool mainContainsLabel(MDLabel label) const
FileName tempFilename
FileName dataFName
Tilting angle of an image (double,degrees)
Shift for the image in the X axis (double)
std::vector< std::unique_ptr< MDRow > > MD
ImageFHandler * hFile
ArrayDim getDimensions()
Special label to be used when gathering MDs in MpiMetadataPrograms.
const FileName & name() const
bool isComplex() const
TransformType transform
bool containsLabel(MDLabel label) const override
size_t virtualOffset
void setPsi(double psi, const size_t n=0)
std::ostream & operator<<(std::ostream &os, const Message &sb)
#define APPEND_IMAGE
void getScale(double &scale, const size_t n=0)
void setZoff(double zoff, const size_t n=0)
DataMode
const ApplyGeoParams DefaultApplyGeoParams
Definition: mask.h:36
void setYoff(double yoff, const size_t n=0)
void setADimFile(ArrayDim aDim)
bool isComplexImage(const FileName &name)
void swapOnWrite()
const size_t tiff_map_min_size
void setFlip(bool flip, const size_t n=0)
Flip the image? (bool)
DataType
scaling factor for an image or volume (double)
Image base class.
void setDataMode(DataMode mode)
void rename(const FileName &name)
#define CENTRAL_SLICE
MDRowVec MDMainHeader
bool individualContainsLabel(MDLabel label) const
size_t mappedSize
WriteMode
void setXoff(double xoff, const size_t n=0)
void setTilt(double tilt, const size_t n=0)
double psi(const double x)
void setName(const FileName &_filename)
#define ALL_IMAGES
Shift for the image in the Z axis (double)
bool isRealImage(const FileName &name)
#define FIRST_IMAGE
FileName filename
CastWriteMode
Shift for the image in the Y axis (double)
void setWeight(double weight, const size_t n=0)
file read(std::istream &is)
Definition: pdb2cif.cpp:6200
#define ALL_SLICES
size_t replaceNsize
MultidimArrayBase * mdaBase
int * n
MDLabel
void getDimensions(ArrayDim &aDim)
bool isImage(const FileName &name)
< Score 4 for volumes
void getOffsetAndSwap(size_t &_offset, int &_swap) const