Xmipp  v3.23.11-Nereus
rwEER.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Oier Lauzirika Zarrabeitia (olauzirika@cnb.csic.es)
4  * Martin Salinas Anton (martin.salinas@cnb.csic.es)
5  *
6  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21  * 02111-1307 USA
22  *
23  * All comments concerning this program package may be sent to the
24  * e-mail address 'xmipp@cnb.csic.es'
25  ***************************************************************************/
26 /***************************************************************************
27  *
28  * Author: "Sjors H.W. Scheres"
29  * MRC Laboratory of Molecular Biology
30  *
31  * This program is free software; you can redistribute it and/or modify
32  * it under the terms of the GNU General Public License as published by
33  * the Free Software Foundation; either version 2 of the License, or
34  * (at your option) any later version.
35  *
36  * This program is distributed in the hope that it will be useful,
37  * but WITHOUT ANY WARRANTY; without even the implied warranty of
38  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39  * GNU General Public License for more details.
40  *
41  * This complete copyright notice must be included in any revised version of the
42  * source code. Additional authorship citations may be added, but existing
43  * author citations must be preserved.
44  ***************************************************************************/
45 
46 #include <algorithm>
47 #include <string>
48 #include <tiffio.h>
49 #include <vector>
50 
51 #include "multidim_array.h"
52 #include "xmipp_error.h"
53 #include "xmipp_filename.h"
54 #include "xmipp_image_base.h"
55 #include "metadata_vec.h"
56 
57 #ifdef TIMING
58  #define RCTIC(label) (EERtimer.tic(label))
59  #define RCTOC(label) (EERtimer.toc(label))
60 
61  Timer EERtimer;
62  int TIMING_READ_EER = EERtimer.setNew("read EER");
63  int TIMING_BUILD_INDEX = EERtimer.setNew("build index");
64  int TIMING_UNPACK_RLE = EERtimer.setNew("unpack RLE");
65  int TIMING_RENDER_ELECTRONS = EERtimer.setNew("render electrons");
66 #else
67  #define RCTIC(label)
68  #define RCTOC(label)
69 #endif
70 
71 class EERRenderer {
72  private:
73 
74  FileName fn_movie;
75 
76  bool ready;
77  bool is_legacy;
78  bool is_7bit;
79  bool read_data;
80 
81  std::vector<long long> frame_starts, frame_sizes;
82  unsigned char* buf;
83 
84  static const char EER_FOOTER_OK[];
85  static const char EER_FOOTER_ERR[];
86  static const int EER_IMAGE_WIDTH, EER_IMAGE_HEIGHT, EER_IMAGE_PIXELS;
87  static const unsigned int EER_LEN_FOOTER;
88  static const uint16_t TIFF_COMPRESSION_EER8bit, TIFF_COMPRESSION_EER7bit;
89 
90  int eer_upsampling;
91  int nframes;
92  int preread_start, preread_end;
93  long long file_size;
94 
95  void readLegacy(FILE *fh)
96  {
97  /* Load everything first */
98  RCTIC(TIMING_READ_EER);
99  buf = (unsigned char*)malloc(file_size);
100  if (buf == NULL)
101  REPORT_ERROR(ERR_MEM_NOTENOUGH, "Failed to allocate the buffer.");
102  if (fread(buf, sizeof(char), file_size, fh) != file_size)
103  REPORT_ERROR(ERR_IO_SIZE, "EERRenderer::readLegacy: Failed to read the expected size from " + fn_movie);
104  RCTOC(TIMING_READ_EER);
105 
106  /* Build frame index */
107  RCTIC(TIMING_BUILD_INDEX);
108  long long pos = file_size;
109  while (pos > 0)
110  {
111  pos -= EER_LEN_FOOTER;
112  if (strncmp(EER_FOOTER_OK, (char*)buf + pos, EER_LEN_FOOTER) == 0)
113  {
114  pos -= 8;
115  long long frame_size = *(long long*)(buf + pos) * sizeof(long long);
116  pos -= frame_size;
117  frame_starts.push_back(pos);
118  frame_sizes.push_back(frame_size);
119  #ifdef DEBUG_EER
120  printf("Frame: LAST-%5d Start at: %08d Frame size: %lld\n", frame_starts.size(), pos, frame_size);
121  #endif
122  }
123  else // if (strncmp(EER_FOOTER_ERR, (char*)buf + pos, EER_LEN_FOOTER) == 0)
124  {
125  REPORT_ERROR(ERR_DOCFILE, "Broken frame in file " + fn_movie);
126  }
127  }
128  std::reverse(frame_starts.begin(), frame_starts.end());
129  std::reverse(frame_sizes.begin(), frame_sizes.end());
130  RCTOC(TIMING_BUILD_INDEX);
131 
132  nframes = frame_starts.size();
133  read_data = true;
134  }
135 
136  void lazyReadFrames()
137  {
138  #pragma omp critical(EERRenderer_lazyReadFrames)
139  {
140  if (!read_data) // cannot return from within omp critical
141  {
142  TIFF *ftiff = TIFFOpen(fn_movie.c_str(), "r");
143 
144  frame_starts.resize(nframes, 0);
145  frame_sizes.resize(nframes, 0);
146  buf = (unsigned char*)malloc(file_size); // This is big enough
147  if (buf == NULL)
148  REPORT_ERROR(ERR_MEM_NOTENOUGH, "Failed to allocate the buffer for " + fn_movie);
149  long long pos = 0;
150 
151  // Read everything
152  for (int frame = 0; frame < nframes; frame++)
153  {
154  if ((preread_start > 0 && frame < preread_start) ||
155  (preread_end > 0 && frame > preread_end))
156  continue;
157 
158  TIFFSetDirectory(ftiff, frame);
159  const int nstrips = TIFFNumberOfStrips(ftiff);
160  frame_starts[frame] = pos;
161 
162  for (int strip = 0; strip < nstrips; strip++)
163  {
164  const int strip_size = TIFFRawStripSize(ftiff, strip);
165  if (pos + strip_size >= file_size)
166  REPORT_ERROR(ERR_LOGIC_ERROR, "EER: buffer overflow when reading raw strips.");
167 
168  TIFFReadRawStrip(ftiff, strip, buf + pos, strip_size);
169  pos += strip_size;
170  frame_sizes[frame] += strip_size;
171  }
172  #ifdef DEBUG_EER
173  printf("EER in TIFF: Read frame %d from %s, nstrips = %d, current pos in buffer = %lld / %lld\n", frame, fn_movie.c_str(), nstrips, pos, file_size);
174  #endif
175  }
176 
177  TIFFClose(ftiff);
178 
179  read_data = true;
180  }
181  }
182  }
183 
184  template <typename T>
185  void render16K(MultidimArray<T> &image, std::vector<unsigned int> &positions, std::vector<unsigned char> &symbols, int n_electrons)
186  {
187  for (int i = 0; i < n_electrons; i++)
188  {
189  int x = ((positions[i] & 4095) << 2) | (symbols[i] & 3); // 4095 = 111111111111b, 3 = 00000011b
190  int y = ((positions[i] >> 12) << 2) | ((symbols[i] & 12) >> 2); // 4096 = 2^12, 12 = 00001100b
191  DIRECT_A2D_ELEM(image, y, x)++;
192  }
193  }
194 
195  template <typename T>
196  void render8K(MultidimArray<T> &image, std::vector<unsigned int> &positions, std::vector<unsigned char> &symbols, int n_electrons)
197  {
198  for (int i = 0; i < n_electrons; i++)
199  {
200  int x = ((positions[i] & 4095) << 1) | ((symbols[i] & 2) >> 1); // 4095 = 111111111111b, 2 = 00000010b
201  int y = ((positions[i] >> 12) << 1) | ((symbols[i] & 8) >> 3); // 4096 = 2^12, 8 = 00001000b
202  DIRECT_A2D_ELEM(image, y, x)++;
203  }
204  }
205 
206  template <typename T>
207  void render4K(MultidimArray<T> &image, std::vector<unsigned int> &positions, std::vector<unsigned char> &symbols, int n_electrons)
208  {
209  for (int i = 0; i < n_electrons; i++)
210  {
211  int x = positions[i] & 4095; // 4095 = 111111111111b
212  int y = positions[i] >> 12; // 4096 = 2^12
213  DIRECT_A2D_ELEM(image, y, x)++;
214  }
215  }
216 
217  static TIFFErrorHandler prevTIFFWarningHandler;
218 
219  public:
220 
222  {
223  ready = false;
224  read_data = false;
225  buf = NULL;
226  preread_start = -1;
227  preread_end = -1;
228  eer_upsampling = 2;
229  }
230 
232  {
233  if (buf != NULL)
234  free(buf);
235  }
236 
237  //TODO: Implement proper copy constructors. Currently, they are disabled to prevent memory corruption.
239  {
240  REPORT_ERROR(ERR_NOT_IMPLEMENTED, "Copy constructor for EERRenderer not implemented yet.");
241  }
242 
244  {
245  REPORT_ERROR(ERR_NOT_IMPLEMENTED, "Copy assignment operator for EERRenderer not implemented yet.");
246  }
247 
248  // Wrapper to the default TIFF warning handler to suppress EER private tag warnings
249  static void TIFFWarningHandler(const char* module, const char* fmt, va_list ap)
250  {
251  // Silence warnings for private tags
252  if (strcmp("Unknown field with tag %d (0x%x) encountered", fmt) == 0)
253  return;
254 
255  if (prevTIFFWarningHandler != NULL)
256  prevTIFFWarningHandler(module, fmt, ap);
257  }
258 
259  static void silenceTIFFWarnings()
260  {
261  if (prevTIFFWarningHandler == NULL)
262  {
263  // Thread safety issue:
264  // Calling this simultaneously is safe but
265  TIFFErrorHandler prev = TIFFSetWarningHandler(EERRenderer::TIFFWarningHandler);
266 
267  // we have to make sure prevTIFFWarningHandler does NOT become our own TIFFWarningHandler
268  // to avoid an infinite loop.
270  prevTIFFWarningHandler = prev;
271  }
272  }
273 
274  // 1-indexed
275  void setFramesOfInterest(int start, int end)
276  {
277  if (is_legacy)
278  return;
279 
280  if (read_data)
281  REPORT_ERROR(ERR_LOGIC_ERROR, "Logic error in EERRenderer::setFramesOfInterest(). This must be set before rendering.");
282  preread_start = start - 1;
283  preread_end = end - 1;
284  }
285 
286  void read(const FileName &_fn_movie, int eer_upsampling)
287  {
288  if (ready)
289  REPORT_ERROR(ERR_LOGIC_ERROR, "Logic error: you cannot recycle EERRenderer for multiple files (now)");
290 
291  if (eer_upsampling == 1 || eer_upsampling == 2 || eer_upsampling == 3)
292  this->eer_upsampling = eer_upsampling;
293  else
294  {
295  std::cerr << "EERRenderer::read: eer_upsampling = " << eer_upsampling << std::endl;
296  REPORT_ERROR(ERR_PARAM_INCORRECT, "EERRenderer::read: eer_upsampling must be 1, 2 or 3.");
297  }
298 
299  fn_movie = _fn_movie;
300 
301  // First of all, check the file size
302  FILE *fh = fopen(fn_movie.c_str(), "r");
303  if (fh == NULL)
304  REPORT_ERROR(ERR_IO_NOTOPEN, "Failed to open " + fn_movie);
305 
306  fseek(fh, 0, SEEK_END);
307  file_size = ftell(fh);
308  fseek(fh, 0, SEEK_SET);
309 
311 
312  // Try reading as TIFF
313  TIFF *ftiff = TIFFOpen(fn_movie.c_str(), "r");
314 
315  if (ftiff == NULL)
316  {
317  is_legacy = true;
318  is_7bit = false;
319  readLegacy(fh);
320  }
321  else
322  {
323  is_legacy = false;
324 
325  // Check width & size
326  int width, height;
327  uint16_t compression = 0;
328  TIFFGetField(ftiff, TIFFTAG_IMAGEWIDTH, &width);
329  TIFFGetField(ftiff, TIFFTAG_IMAGELENGTH, &height);
330  TIFFGetField(ftiff, TIFFTAG_COMPRESSION, &compression);
331 
332  #ifdef DEBUG_EER
333  printf("EER in TIFF: %s size = %ld, width = %d, height = %d, compression = %d\n", fn_movie.c_str(), file_size, width, height, compression);
334  #endif
335 
336  // TIA can write an EER file whose first page is a sum and compressoin == 1.
337  // This is not supported (yet). EPU never writes such movies.
338  if (compression == EERRenderer::TIFF_COMPRESSION_EER8bit)
339  is_7bit = false;
340  else if (compression == EERRenderer::TIFF_COMPRESSION_EER7bit)
341  is_7bit = true;
342  else
343  REPORT_ERROR(ERR_PARAM_INCORRECT, "Unknown compression scheme for EER " + integerToString(compression));
344 
345  if (width != EER_IMAGE_WIDTH || height != EER_IMAGE_HEIGHT)
346  REPORT_ERROR(ERR_PARAM_INCORRECT, "Currently we support only 4096x4096 pixel EER movies.");
347 
348  // Find the number of frames
349  nframes = TIFFNumberOfDirectories(ftiff);
350  TIFFClose(ftiff);
351  #ifdef DEBUG_EER
352  printf("EER in TIFF: %s nframes = %d\n", fn_movie.c_str(), nframes);
353  #endif
354  }
355 
356  fclose(fh);
357  ready = true;
358  }
359 
361  {
362  if (!ready)
363  REPORT_ERROR(ERR_LOGIC_ERROR, "EERRenderer::getNFrames called before ready.");
364 
365  return nframes;
366  }
367 
368  int getWidth()
369  {
370  if (!ready)
371  REPORT_ERROR(ERR_LOGIC_ERROR, "EERRenderer::getNFrames called before ready.");
372 
373  return EER_IMAGE_WIDTH << (eer_upsampling - 1);
374  }
375 
376  int getHeight()
377  {
378  if (!ready)
379  REPORT_ERROR(ERR_LOGIC_ERROR, "EERRenderer::getNFrames called before ready.");
380 
381  return EER_IMAGE_HEIGHT << (eer_upsampling - 1);
382  }
383 
384  // Frame indices are 1-indexed.
385  // image is cleared.
386  // This function is thread-safe (except for timing).
387  // It is caller's responsibility to make sure type T does not overflow.
388  template <typename T>
389  long long renderFrames(int frame_start, int frame_end, MultidimArray<T> &image)
390  {
391  if (!ready)
392  REPORT_ERROR(ERR_LOGIC_ERROR, "EERRenderer::renderNFrames called before ready.");
393 
394  lazyReadFrames();
395 
396  if (frame_start < 0 || frame_start >= getNFrames() ||
397  frame_end < frame_start || frame_end >= getNFrames())
398  {
399  std::cerr << "EERRenderer::renderFrames(frame_start = " << frame_start << ", frame_end = " << frame_end << "), NFrames = " << getNFrames() << std::endl;
400  REPORT_ERROR(ERR_PARAM_INCORRECT, "Invalid frame range was requested.");
401  }
402 
403  long long total_n_electron = 0;
404 
405  std::vector<unsigned int> positions;
406  std::vector<unsigned char> symbols;
407  image.initZeros(getHeight(), getWidth());
408 
409  for (int iframe = frame_start; iframe <= frame_end; iframe++)
410  {
411  RCTIC(TIMING_UNPACK_RLE);
412  if ((preread_start > 0 && iframe < preread_start) ||
413  (preread_end > 0 && iframe > preread_end))
414  {
415  std::cerr << "EERRenderer::renderFrames(frame_start = " << frame_start + 1 << ", frame_end = " << frame_end + 1<< "), NFrames = " << getNFrames() << " preread_start = " << preread_start + 1 << " prered_end = " << preread_end + 1<< std::endl;
416  REPORT_ERROR(ERR_LOGIC_ERROR, "Tried to render frames outside pre-read region");
417  }
418 
419  long long pos = frame_starts[iframe];
420  unsigned int n_pix = 0, n_electron = 0;
421  const int max_electrons = frame_sizes[iframe] * 2; // at 4 bits per electron (very permissive bound!)
422  if (positions.size() < max_electrons)
423  {
424  positions.resize(max_electrons);
425  symbols.resize(max_electrons);
426  }
427 
428  if (is_7bit)
429  {
430  unsigned int bit_pos = 0; // 4 K * 4 K * 11 bit << 2 ** 32
431  unsigned char p, s;
432 
433  while (true)
434  {
435  // Fetch 32 bits and unpack up to 2 chunks of 7 + 4 bits.
436  // This is faster than unpack 7 and 4 bits sequentially.
437  // Since the size of buf is larger than the actual size by the TIFF header size,
438  // it is always safe to read ahead.
439 
440  long long first_byte = pos + (bit_pos >> 3);
441  const unsigned int bit_offset_in_first_byte = bit_pos & 7; // 7 = 00000111 (same as % 8)
442  const unsigned int chunk = (*(unsigned int*)(buf + first_byte)) >> bit_offset_in_first_byte;
443 
444  p = (unsigned char)(chunk & 127); // 127 = 01111111
445  bit_pos += 7; // TODO: we can remove this for further speed.
446  n_pix += p;
447  if (n_pix >= EER_IMAGE_PIXELS) break;
448  if (p == 127) continue; // this should be rare.
449 
450  s = (unsigned char)((chunk >> 7) & 15) ^ 0x0A; // 15 = 00001111; See below for 0x0A
451  bit_pos += 4;
452  positions[n_electron] = n_pix;
453  symbols[n_electron] = s;
454  n_electron++;
455  n_pix++;
456 
457  p = (unsigned char)((chunk >> 11) & 127); // 127 = 01111111
458  bit_pos += 7;
459  n_pix += p;
460  if (n_pix >= EER_IMAGE_PIXELS) break;
461  if (p == 127) continue;
462 
463  s = (unsigned char)((chunk >> 18) & 15) ^ 0x0A; // 15 = 00001111; See below for 0x0A
464  bit_pos += 4;
465  positions[n_electron] = n_pix;
466  symbols[n_electron] = s;
467  n_electron++;
468  n_pix++;
469  }
470  }
471  else
472  {
473  // unpack every two symbols = 12 bit * 2 = 24 bit = 3 byte
474  // high <- |bbbbBBBB|BBBBaaaa|AAAAAAAA| -> low
475  // With SIMD intrinsics at the SSSE3 level, we can unpack 10 symbols (120 bits) simultaneously.
476  unsigned char p1, p2, s1, s2;
477 
478  const long long pos_limit = frame_starts[iframe] + frame_sizes[iframe];
479  // Because there is a footer, it is safe to go beyond the limit by two bytes.
480  while (pos < pos_limit)
481  {
482  // symbol is bit tricky. 0000YyXx; Y and X must be flipped.
483  p1 = buf[pos];
484  s1 = (buf[pos + 1] & 0x0F) ^ 0x0A; // 0x0F = 00001111, 0x0A = 00001010
485 
486  p2 = (buf[pos + 1] >> 4) | (buf[pos + 2] << 4);
487  s2 = (buf[pos + 2] >> 4) ^ 0x0A;
488 
489  // Note the order. Add p before checking the size and placing a new electron.
490  n_pix += p1;
491  if (n_pix >= EER_IMAGE_PIXELS) break;
492  if (p1 < 255)
493  {
494  positions[n_electron] = n_pix;
495  symbols[n_electron] = s1;
496  n_electron++;
497  n_pix++;
498  }
499 
500  n_pix += p2;
501  if (n_pix >= EER_IMAGE_PIXELS) break;
502  if (p2 < 255)
503  {
504  positions[n_electron] = n_pix;
505  symbols[n_electron] = s2;
506  n_electron++;
507  n_pix++;
508  }
509  #ifdef DEBUG_EER_DETAIL
510  printf("%d: %u %u, %u %u %d\n", pos, p1, s1, p2, s2, n_pix);
511  #endif
512  pos += 3;
513  }
514  }
515 
516  if (n_pix != EER_IMAGE_PIXELS)
517  {
518  std::cerr << "WARNING: The number of pixels is not right in " + fn_movie + " frame " + integerToString(iframe + 1) + ". Probably this frame is corrupted. This frame is skipped." << std::endl;
519  continue;
520  }
521 
522  RCTOC(TIMING_UNPACK_RLE);
523 
524  RCTIC(TIMING_RENDER_ELECTRONS);
525  if (eer_upsampling == 3)
526  render16K(image, positions, symbols, n_electron);
527  else if (eer_upsampling == 2)
528  render8K(image, positions, symbols, n_electron);
529  else if (eer_upsampling == 1)
530  render4K(image, positions, symbols, n_electron);
531  else
532  REPORT_ERROR(ERR_LOGIC_ERROR, "Invalid EER upsample");
533  RCTOC(TIMING_RENDER_ELECTRONS);
534 
535  total_n_electron += n_electron;
536  #ifdef DEBUG_EER
537  printf("Decoded %lld electrons / %d pixels from frame %5d.\n", n_electron, n_pix, iframe);
538  #endif
539  }
540  #ifdef DEBUG_EER
541  printf("Decoded %lld electrons in total.\n", total_n_electron);
542  #endif
543 
544  #ifdef TIMING
545  EERtimer.printTimes(false);
546  #endif
547 
548  return total_n_electron;
549  }
550 
551  static bool isEER(const FileName &fn_movie)
552  {
553  FileName ext = fn_movie.getExtension();
554  return (ext == "eer" || ext == "ecc");
555  }
556 };
557 
558 const char EERRenderer::EER_FOOTER_OK[] = "ThermoFisherECComprOK000";
559 const char EERRenderer::EER_FOOTER_ERR[] = "ThermoFisherECComprERR00";
560 const int EERRenderer::EER_IMAGE_WIDTH = 4096;
561 const int EERRenderer::EER_IMAGE_HEIGHT = 4096;
562 const int EERRenderer::EER_IMAGE_PIXELS = EERRenderer::EER_IMAGE_WIDTH * EERRenderer::EER_IMAGE_HEIGHT;
563 const unsigned int EERRenderer::EER_LEN_FOOTER = 24;
564 const uint16_t EERRenderer::TIFF_COMPRESSION_EER8bit = 65000;
565 const uint16_t EERRenderer::TIFF_COMPRESSION_EER7bit = 65001;
566 
567 TIFFErrorHandler EERRenderer::prevTIFFWarningHandler = NULL;
568 
569 int ImageBase::readEER(size_t select_img) {
570  int upsampling = 1;
571  StringVector info;
572  DataType datatype;
573  size_t found = filename.find_first_of("#");
574  FileName infolist = filename.substr(found + 1);
575  filename = filename.substr(0, found);
576  infolist.toLowercase();
577  splitString(infolist, ",", info, false);
578 
579  if (info.size() < 3)
580  REPORT_ERROR(ERR_ARG_MISSING, (String) "Cannot open file " + filename +
581  ". Not enough header arguments.");
582 
583  const int fractioning = std::atoi(info[0].c_str());
584  if (fractioning < 1)
585  {
586  REPORT_ERROR(ERR_PARAM_INCORRECT, "Incorrect fractioning value (must be greater than zero)");
587  }
588  if (select_img > fractioning) {
589  REPORT_ERROR(ERR_PARAM_INCORRECT, (String) "Incorrect frame number selected (" + std::to_string(select_img) + "). Number of frames is " + std::to_string(fractioning) + ".");
590  }
591 
592  int _xDim,_yDim,_zDim;
593  size_t _nDim;
594  if (info[1] == "4K")
595  {
596  _xDim = _yDim = 4096;
597  }
598  else if (info[1] == "8K")
599  {
600  _xDim = _yDim = 8192;
601  }
602  else {
603  REPORT_ERROR(ERR_PARAM_INCORRECT, "Incorrect output size. Valid sizes are: 4K, 8K.");
604  }
605 
606  _zDim = _nDim = 1;
607  setDimensions(_xDim, _yDim, _zDim, _nDim);
608  mdaBase->coreAllocateReuse();
609 
610  if(info[2] == "uint8")
611  datatype = DT_UChar;
612  else if (info[2] == "uint16")
613  datatype = DT_UShort;
614  else
615  REPORT_ERROR(ERR_PARAM_INCORRECT, "Incorrect output data type. Valid types are: uint8, uint16.");
616 
617  MDMainHeader.setValue(MDL_SAMPLINGRATE_X,(double) -1);
618  MDMainHeader.setValue(MDL_SAMPLINGRATE_Y,(double) -1);
619  MDMainHeader.setValue(MDL_DATATYPE,(int)datatype);
620 
621  MD.clear();
622  MD.push_back(std::unique_ptr<MDRowVec>(new MDRowVec(MDL::emptyHeaderVec())));
623 
624  if( dataMode < DATA )
625  return 0;
626 
627  EERRenderer renderer;
628  renderer.read(hFile->fileName, upsampling);
629 
630  MultidimArray<int> buffer(_yDim, _xDim);
631  const auto step = renderer.getNFrames() / fractioning;
632  const auto first = (select_img-1)*step;
633  const auto last = first + step - 1;
634  renderer.renderFrames(first, last, buffer);
635  setPage2T(
636  0UL, reinterpret_cast<char*>(MULTIDIM_ARRAY(buffer)),
637  DT_Int,
638  MULTIDIM_SIZE(buffer)
639  );
640 
641  return 0;
642 }
Argument missing.
Definition: xmipp_error.h:114
Parameter incorrect.
Definition: xmipp_error.h:181
static bool isEER(const FileName &fn_movie)
Definition: rwEER.cpp:551
Case or algorithm not implemented yet.
Definition: xmipp_error.h:177
sampling rate in A/pixel (double)
EERRenderer()
Definition: rwEER.cpp:221
static void silenceTIFFWarnings()
Definition: rwEER.cpp:259
long long renderFrames(int frame_start, int frame_end, MultidimArray< T > &image)
Definition: rwEER.cpp:389
sampling rate in A/pixel (double)
struct tiff TIFF
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define MULTIDIM_SIZE(v)
HBITMAP buffer
Definition: svm-toy.cpp:37
static double * y
EERRenderer(const EERRenderer &)
Definition: rwEER.cpp:238
int getHeight()
Definition: rwEER.cpp:376
void setFramesOfInterest(int start, int end)
Definition: rwEER.cpp:275
There is not enough memory for allocation.
Definition: xmipp_error.h:166
#define DIRECT_A2D_ELEM(v, i, j)
#define MULTIDIM_ARRAY(v)
~EERRenderer()
Definition: rwEER.cpp:231
if read from file original image datatype, this is an struct defined in image
String integerToString(int I, int _width, char fill_with)
std::vector< String > StringVector
Definition: xmipp_strings.h:35
doublereal * x
#define i
String getExtension() const
#define RCTOC(label)
Definition: rwEER.cpp:68
glob_log first
int splitString(const String &input, const String &delimiter, StringVector &results, bool includeEmpties)
static void TIFFWarningHandler(const char *module, const char *fmt, va_list ap)
Definition: rwEER.cpp:249
EERRenderer & operator=(const EERRenderer &)
Definition: rwEER.cpp:243
free((char *) ob)
void read(const FileName &_fn_movie, int eer_upsampling)
Definition: rwEER.cpp:286
int readEER(size_t select_img)
Definition: rwEER.cpp:569
static MDRowVec emptyHeaderVec()
DataType
FileName toLowercase() const
int getWidth()
Definition: rwEER.cpp:368
File cannot be open.
Definition: xmipp_error.h:137
Error in docfile format.
Definition: xmipp_error.h:122
std::string String
Definition: xmipp_strings.h:34
std::string to_string(bond_type bondType)
Definition: compound.cpp:43
Incorrect file size.
Definition: xmipp_error.h:145
void initZeros(const MultidimArray< T1 > &op)
int getNFrames()
Definition: rwEER.cpp:360
#define RCTIC(label)
Definition: rwEER.cpp:67
Some logical error in the pipeline.
Definition: xmipp_error.h:147