Xmipp  v3.23.11-Nereus
rwPIF.cpp
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 #include "xmipp_image_base.h"
27 #include "xmipp_error.h"
28 #include "xmipp_funcs.h"
29 #include "metadata_static.h"
30 
31 #define PIFHEADERSIZE sizeof(PIFDataHeader) // size of EM file header
32 
33 int ImageBase::readPIF(size_t select_img)
34 {
35  PIFMainHeader mainHeader;
36  if ( fread( &mainHeader, PIFHEADERSIZE, 1, fimg ) != 1 )
37  REPORT_ERROR(ERR_IO_NOREAD, formatString("rwPIF: cannot read Spider main header from file %s"
38  ". Error message: %s", filename.c_str() ,strerror(errno)));
39 
40  // Check Machine endianness
41  bool isLE = IsLittleEndian();
42 
43  // Determine byte order and swap bytes if from different-endian machine
44  swap = (isLE == mainHeader.endianNess);
45 
46  if (swap)
47  swapPage((char *) &mainHeader, PIFHEADERSIZE, DT_Int);
48 
49 
51  switch (mainHeader.mode)
52  {
53  case 0:
54  datatype = DT_SChar;
55  break;
56  case 1:
57  case 7: // Actually it's floatint*2, but it isn't moved to float
58  datatype = DT_Short;
59  break;
60  case 2:
61  case 46: // This case is not documented, but I think this is floatInt*4
62  datatype = DT_Int; // We aren't moving to float actually
63  break;
64  case 3:
65  case 8: // Actually it's complex floatint*2, but it isn't moved to float
66  datatype = DT_CShort;
67  break;
68  case 4:
69  datatype = DT_CInt; // We aren't moving to float actually
70  break;
71  case 9:
72  datatype = DT_Float;
73  break;
74  case 10:
75  datatype = DT_CFloat;
76  break;
77  case 97:
78  REPORT_ERROR(ERR_NOT_IMPLEMENTED, "readPIF: Reading from colormap datatype file not implemented.\n"
79  "If you're interested in this feature, please contact us at xmipp@cnb.csic.es \n"
80  "and send us an example image file to help implementing.");
81  break;
82  default:
83  REPORT_ERROR(ERR_NOT_IMPLEMENTED, formatString("readPIF: Reading from datatype code %d file not implemented.\n"
84  "If you're interested in this feature, please contact us at xmipp@cnb.csic.es \n"
85  "and send us an example image file to help implementing.", mainHeader.mode));
86  break;
87  }
88  MDMainHeader.setValue(MDL_DATATYPE,(int)datatype);
89 
90 
91  // Check selected image
92  if (select_img > (size_t)mainHeader.numImages)
93  REPORT_ERROR(ERR_INDEX_OUTOFBOUNDS, formatString("readPIF (%s): Image number %lu exceeds stack size %lu" ,filename.c_str(),select_img, mainHeader.numImages));
94 
95  // Setting image dimensions
96  ArrayDim aDim;
97 
98  aDim.ndim = (select_img == ALL_IMAGES)? mainHeader.numImages : 1;
99  aDim.zdim = mainHeader.nz;
100  aDim.ydim = mainHeader.ny;
101  aDim.xdim = mainHeader.nx;
102 
103  replaceNsize = aDim.ndim;
104 
105  setDimensions(aDim);
106 
107 
108  size_t imgStart = IMG_INDEX(select_img);
109  size_t datatypeSize = gettypesize(datatype);
110  offset = PIFHEADERSIZE*2;// + (aDimFile.zyxdim*datatypeSize + PIFHEADERSIZE)*imgStart;
111 
112  if (dataMode == HEADER || (dataMode == _HEADER_ALL && aDim.ndim > 1)) // Stop reading if not necessary
113  return 0;
114 
115  size_t imgEnd = (select_img != ALL_IMAGES) ? imgStart + 1 : aDim.ndim;
116 
117  size_t imageSize = PIFHEADERSIZE + aDimFile.zyxdim*datatypeSize;
118  size_t pad = PIFHEADERSIZE;
119  size_t headerOffset = PIFHEADERSIZE;
120 
121  MD.clear();
122  for (size_t i = 0; i < imgEnd-imgStart; i++)
123  MD.push_back(std::unique_ptr<MDRowVec>(new MDRowVec(MDL::emptyHeaderVec())));
124 
125  PIFDataHeader dataHeader;
126 
127  for (size_t n = 0, i = imgStart; i < imgEnd; ++i, ++n )
128  {
129  if (fseek( fimg, headerOffset + i*imageSize, SEEK_SET ) != 0)//fseek return 0 on success
130  REPORT_ERROR(ERR_IO, formatString("rwPIF: error seeking %lu to read image %lu", headerOffset, i));
131 
132  if ( fread( &dataHeader, PIFHEADERSIZE, 1, fimg ) != 1 )
133  REPORT_ERROR(ERR_IO_NOREAD, formatString("rwPIF: cannot read PIF image %lu header", i));
134 
135  if ( swap )
136  swapPage((char *) &dataHeader, PIFHEADERSIZE, DT_Int);
137 
138  if (dataMode == _HEADER_ALL || dataMode == _DATA_ALL)
139  {
140  MD[n]->setValue(MDL_ORIGIN_X, (double)dataHeader.nxstart);
141  MD[n]->setValue(MDL_ORIGIN_Y, (double)dataHeader.nystart);
142  MD[n]->setValue(MDL_ORIGIN_Z, (double)dataHeader.nzstart);
143  MD[n]->setValue(MDL_ANGLE_ROT, (double)dataHeader.alpha);
144  MD[n]->setValue(MDL_ANGLE_TILT, (double)dataHeader.beta);
145  MD[n]->setValue(MDL_ANGLE_PSI, (double)dataHeader.gamma);
146  MD[n]->setValue(MDL_SAMPLINGRATE_X, (double)dataHeader.xlength/aDim.xdim);
147  MD[n]->setValue(MDL_SAMPLINGRATE_Y, (double)dataHeader.ylength/aDim.ydim);
148  MD[n]->setValue(MDL_SAMPLINGRATE_Z, (double)dataHeader.zlength/aDim.zdim);
149  }
150  }
151 
152  if (dataMode < DATA) // Don't read data if not necessary but read the header
153  return 0;
154 
155  //offset should point to the begin of the data
156  readData(fimg, select_img, datatype, pad );
157 
158  return(0);
159 }
160 
161 int ImageBase::writePIF(size_t select_img, bool isStack, int mode)
162 {
163  REPORT_ERROR(ERR_IO_NOWRITE, "ERROR: writePIF is not implemented.");
164  return(-1);
165 }
Index out of bounds.
Definition: xmipp_error.h:132
Rotation angle of an image (double,degrees)
Case or algorithm not implemented yet.
Definition: xmipp_error.h:177
sampling rate in A/pixel (double)
size_t xdim
sampling rate in A/pixel (double)
DataMode dataMode
sampling rate in A/pixel (double)
bool IsLittleEndian(void)
ArrayDim aDimFile
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
virtual void readData(FILE *fimg, size_t select_img, DataType datatype, size_t pad)=0
Tilting angle of an image (double,degrees)
Couldn&#39;t write to file.
Definition: xmipp_error.h:140
void setValue(const MDObject &object) override
void swapPage(char *page, size_t pageNrElements, DataType datatype, int swap=1)
std::vector< std::unique_ptr< MDRow > > MD
Special label to be used when gathering MDs in MpiMetadataPrograms.
if read from file original image datatype, this is an struct defined in image
Input/Output general error.
Definition: xmipp_error.h:134
auxiliary label to be used as an index (long)
#define i
size_t zdim
int readPIF(size_t select_img)
Definition: rwPIF.cpp:33
Origin for the image in the Y axis (double)
size_t zyxdim
int writePIF(size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE)
Definition: rwPIF.cpp:161
virtual void setDimensions(int Xdim, int Ydim, int Zdim, size_t Ndim)=0
Couldn&#39;t read from file.
Definition: xmipp_error.h:139
static MDRowVec emptyHeaderVec()
DataType
void mode
#define PIFHEADERSIZE
Definition: rwPIF.cpp:31
MDRowVec MDMainHeader
size_t ndim
DataType datatype() const
#define ALL_IMAGES
String formatString(const char *format,...)
#define IMG_INDEX(select_img)
size_t ydim
Origin for the image in the Z axis (double)
FileName filename
size_t replaceNsize
int * n
size_t gettypesize(DataType type)
Returns memory size of datatype.