Xmipp  v3.23.11-Nereus
rwTIA.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_memory.h"
29 #include "xmipp_funcs.h"
30 #include "metadata_static.h"
31 
32 #define TIASIZE 30 // Size of the TIA header without pDATA_OFFSET
33 
36 
40 struct TIAhead
41 {
42  short int endianess;
43  short int SeriesID;
44  short int SeriesVersion;
46  int TagTypeID;
51  int * pDATA_OFFSET;
52 };
53 
54 #define TIAdataSIZE 50 // Size of the TIA data header to be read
55 
60 {
61  double CalibrationOffsetX; //CalibrationOffsetX
62  double PIXEL_WIDTH; //CalibrationDeltaX
63  int CalibrationElementX; //CalibrationElementX
64  double CalibrationOffsetY; //CalibrationOffsetY
65  double PIXEL_HEIGHT; //CalibrationDeltaY
66  int CalibrationElementY; //CalibrationElementY
67  short int DATA_TYPE; //DataType
68  int IMAGE_WIDTH; //ArraySizeX
69  int IMAGE_HEIGHT; //ArraySizeY
70  short int DATA_TYPE_SIZE;
71  std::string DATA_TYPE_SIZE_STRING;
72  bool isSigned;
73 };
74 
75 // I/O prototypes
79 int ImageBase::readTIA(int select_img,bool isStack)
80 {
81  TIAhead * header = new TIAhead;
82 
83  xmippFREAD(&header->endianess, sizeof(short int), 1, fimg, swap );
84 
85  // Set Endianess
86  if (header->endianess == 18761)
87  swap = 0;
88  else
89  swap = 1;
90  if (IsBigEndian())
91  swap = !swap;
92 
93  xmippFREAD(&header->SeriesID, sizeof(short int), 1, fimg, swap );
94  xmippFREAD(&header->SeriesVersion, sizeof(short int), 1, fimg, swap);
95  xmippFREAD(&header->DATA_TYPE_ID, sizeof(int), 1, fimg, swap);
96  xmippFREAD(&header->TagTypeID, sizeof(int), 1, fimg, swap );
97  xmippFREAD(&header->TotalNumberElements, sizeof(int), 1, fimg, swap );
98  xmippFREAD(&header->NUMBER_IMAGES, sizeof(int), 1, fimg, swap );
99  xmippFREAD(&header->OFFSET_ARRAY_OFFSET, sizeof(int), 1, fimg, swap );
100  xmippFREAD(&header->numberdimensions, sizeof(int), 1, fimg, swap );
101 
102  // Check data type
103  if (header->DATA_TYPE_ID != 16674)
104  REPORT_ERROR(ERR_TYPE_INCORRECT, "ERROR: readTIA only processes images in real space");
105 
106  fseek(fimg, header->OFFSET_ARRAY_OFFSET, SEEK_SET);
107  header->pDATA_OFFSET = (int *) askMemory(header->NUMBER_IMAGES * sizeof(int));
108  xmippFREAD(header->pDATA_OFFSET, sizeof(int), header->NUMBER_IMAGES, fimg, swap);
109 
110  TIAdataHead* dataHeaders = new TIAdataHead [header->NUMBER_IMAGES];
111 
112  // Read all the image headers
113  for (int i = 0; i < header->NUMBER_IMAGES; i++)
114  {
115  fseek(fimg, header->pDATA_OFFSET[i], SEEK_SET);
116  xmippFREAD(&(dataHeaders[i].CalibrationOffsetX), sizeof(double), 1, fimg, swap);
117  xmippFREAD(&dataHeaders[i].PIXEL_WIDTH, sizeof(double), 1, fimg, swap);
118  xmippFREAD(&dataHeaders[i].CalibrationElementX, sizeof(int), 1, fimg, swap);
119  xmippFREAD(&dataHeaders[i].CalibrationOffsetY, sizeof(double), 1, fimg, swap);
120  xmippFREAD(&dataHeaders[i].PIXEL_HEIGHT, sizeof(double), 1, fimg, swap);
121  xmippFREAD(&dataHeaders[i].CalibrationElementY, sizeof(int), 1, fimg, swap);
122  xmippFREAD(&dataHeaders[i].DATA_TYPE, sizeof(short int), 1, fimg, swap);
123  xmippFREAD(&dataHeaders[i].IMAGE_WIDTH, sizeof(int), 1, fimg, swap);
124  xmippFREAD(&dataHeaders[i].IMAGE_HEIGHT, sizeof(int), 1, fimg, swap);
125  }
126 
127  int _xDim,_yDim;
128  size_t _nDim;
129 
130  size_t imgStart = IMG_INDEX(select_img);
131  size_t imgEnd = (select_img != ALL_IMAGES) ? imgStart + 1 : header->NUMBER_IMAGES;
132 
133  if (select_img > header->NUMBER_IMAGES)
134  REPORT_ERROR(ERR_INDEX_OUTOFBOUNDS, formatString("readTIA: Image number %lu exceeds stack size %lu", select_img, header->NUMBER_IMAGES));
135  else if (select_img == ALL_IMAGES)
136  {
137  for (int i = 1; i < header->NUMBER_IMAGES; i++) // Check images dimensions. Need to be the same
138  {
139  if (dataHeaders[0].IMAGE_HEIGHT != dataHeaders[i].IMAGE_HEIGHT || \
140  dataHeaders[0].IMAGE_WIDTH != dataHeaders[i].IMAGE_WIDTH || \
141  dataHeaders[0].DATA_TYPE != dataHeaders[i].DATA_TYPE)
142  REPORT_ERROR(ERR_IMG_NOREAD, "readTIA: images in TIA file with different dimensions and data types are not supported");
143  }
144  _xDim = dataHeaders[0].IMAGE_WIDTH;
145  _yDim = dataHeaders[0].IMAGE_HEIGHT;
146  _nDim = (size_t) header->NUMBER_IMAGES;
147  }
148  else
149  {
150  _xDim = dataHeaders[imgStart].IMAGE_WIDTH;
151  _yDim = dataHeaders[imgStart].IMAGE_HEIGHT;
152  _nDim = 1;
153  }
154 
155  // Map the parameters
156  setDimensions(_xDim, _yDim, 1, _nDim);
157 
158  DataType datatype;
159  // dataHeaders[0].isSigned = false;
160  int tiaDT;
161  tiaDT = dataHeaders[imgStart].DATA_TYPE;
162  offset = header->pDATA_OFFSET[imgStart] + TIAdataSIZE;
163 
164  switch ( tiaDT )
165  {
166  case 1:
167  datatype = DT_UChar;
168  break;
169  case 2:
170  datatype = DT_UShort;
171  // datatype = DT_Short;
172  break;
173  case 3:
174  datatype = DT_UInt;
175  break;
176  case 4:
177  datatype = DT_SChar;
178  break;
179  case 5:
180  datatype = DT_Short;
181  // dataHeaders[0].isSigned = true;
182  break;
183  case 6:
184  datatype = DT_Int;
185  break;
186  case 7:
187  datatype = DT_Float;
188  break;
189  case 8:
190  datatype = DT_Double;
191  break;
192  case 9:
193  datatype = DT_CFloat;
194  break;
195  case 10:
196  datatype = DT_CDouble;
197  break;
198  default:
199  datatype = DT_Unknown;
200  (void)datatype; // to suppress dead assignment warning
201  break;
202  }
203 
204  MDMainHeader.setValue(MDL_SAMPLINGRATE_X,(double)dataHeaders[0].PIXEL_WIDTH);
205  MDMainHeader.setValue(MDL_SAMPLINGRATE_Y,(double)dataHeaders[0].PIXEL_HEIGHT);
206  MDMainHeader.setValue(MDL_DATATYPE,(int)datatype);
207 
208  if (dataMode == HEADER || (dataMode == _HEADER_ALL && _nDim > 1)) // Stop reading if not necessary
209  {
210  delete header;
211  delete[] dataHeaders;
212  return 0;
213  }
214 
215  MD.clear();
216  for (size_t i = 0; i < imgEnd-imgStart; i++)
217  MD.push_back(std::unique_ptr<MDRowVec>(new MDRowVec(MDL::emptyHeaderVec())));
218 
219  double aux;
220  for ( size_t i = 0; i < imgEnd - imgStart; ++i )
221  {
222  if (dataMode == _HEADER_ALL || dataMode == _DATA_ALL)
223  {
224  if(MDMainHeader.getValue(MDL_SAMPLINGRATE_X,aux))
225  {
226  MD[i]->setValue(MDL_SHIFT_X, dataHeaders[i].CalibrationOffsetX/aux);
227  aux = ROUND(dataHeaders[i].CalibrationElementX - \
228  dataHeaders[i].CalibrationOffsetX/aux - _xDim/2);
229  MD[i]->setValue(MDL_ORIGIN_X, aux);
230  }
231  if(MDMainHeader.getValue(MDL_SAMPLINGRATE_Y,aux))
232  {
233  MD[i]->setValue(MDL_SHIFT_Y, dataHeaders[i].CalibrationOffsetY/aux);
234  aux = ROUND(dataHeaders[i].CalibrationElementY - \
235  dataHeaders[i].CalibrationOffsetY/aux -_yDim/2);
236  MD[i]->setValue(MDL_ORIGIN_Y, aux);
237  }
238  }
239  }
240 
241  delete header;
242  delete[] dataHeaders;
243 
244  if( dataMode < DATA )
245  return 0;
246 
247  size_t pad = TIAdataSIZE;
248  readData(fimg, select_img, datatype, pad);
249 
250  return(0);
251 }
252 
253 int ImageBase::writeTIA(int img_select, bool isStack, int mode)
254 {
255  REPORT_ERROR(ERR_IMG_NOWRITE, "ERROR: writeTIA is not implemented.");
256 }
257 
Index out of bounds.
Definition: xmipp_error.h:132
int writeTIA(int img_select, bool isStack=false, int mode=WRITE_OVERWRITE)
Definition: rwTIA.cpp:253
double PIXEL_HEIGHT
Definition: rwTIA.cpp:65
sampling rate in A/pixel (double)
sampling rate in A/pixel (double)
bool IsBigEndian(void)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
int * pDATA_OFFSET
Definition: rwTIA.cpp:51
Shift for the image in the X axis (double)
if read from file original image datatype, this is an struct defined in image
short int DATA_TYPE
Definition: rwTIA.cpp:67
Cannot read image from file.
Definition: xmipp_error.h:128
auxiliary label to be used as an index (long)
int DATA_TYPE_ID
Definition: rwTIA.cpp:45
short int DATA_TYPE_SIZE
Definition: rwTIA.cpp:70
Cannot write image to file.
Definition: xmipp_error.h:129
#define i
double CalibrationOffsetX
Definition: rwTIA.cpp:61
double PIXEL_WIDTH
Definition: rwTIA.cpp:62
short int endianess
Definition: rwTIA.cpp:42
int IMAGE_WIDTH
Definition: rwTIA.cpp:68
int readTIA(int img_select, bool isStack=false)
Definition: rwTIA.cpp:79
if(fabs(c[*nmax+ *nmax *c_dim1])==0.e0)
Origin for the image in the Y axis (double)
int TotalNumberElements
Definition: rwTIA.cpp:47
bool isSigned
Definition: rwTIA.cpp:72
int TagTypeID
Definition: rwTIA.cpp:46
char * askMemory(size_t memsize)
#define ROUND(x)
Definition: xmipp_macros.h:210
std::string DATA_TYPE_SIZE_STRING
Definition: rwTIA.cpp:71
static MDRowVec emptyHeaderVec()
DataType
void mode
size_t xmippFREAD(void *dest, size_t size, size_t nitems, FILE *&fp, bool reverse)
double CalibrationOffsetY
Definition: rwTIA.cpp:64
int CalibrationElementX
Definition: rwTIA.cpp:63
int IMAGE_HEIGHT
Definition: rwTIA.cpp:69
#define ALL_IMAGES
String formatString(const char *format,...)
int OFFSET_ARRAY_OFFSET
Definition: rwTIA.cpp:49
#define IMG_INDEX(select_img)
#define TIAdataSIZE
Definition: rwTIA.cpp:54
short int SeriesID
Definition: rwTIA.cpp:43
Shift for the image in the Y axis (double)
Incorrect type received.
Definition: xmipp_error.h:190
int CalibrationElementY
Definition: rwTIA.cpp:66
short int SeriesVersion
Definition: rwTIA.cpp:44
int numberdimensions
Definition: rwTIA.cpp:50
int NUMBER_IMAGES
Definition: rwTIA.cpp:48