Xmipp  v3.23.11-Nereus
Classes | Functions
Collaboration diagram for Spider File format:

Classes

struct  SPIDERhead
 
struct  ImageBase::SPIDERhead
 

Functions

int readSPIDER (size_t select_img)
 
int readSPIDER (size_t start_img, size_t batch_size)
 
int writeSPIDER (size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE)
 
int ImageBase::readSPIDER (size_t select_img)
 
int ImageBase::readSPIDER (size_t start_img, size_t batch_size)
 
int ImageBase::writeSPIDER (size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE)
 

Detailed Description

Function Documentation

◆ readSPIDER() [1/4]

int readSPIDER ( size_t  select_img)

Spider Reader

◆ readSPIDER() [2/4]

int ImageBase::readSPIDER ( size_t  select_img)
protected

Spider Reader

Definition at line 292 of file rwSPIDER.cpp.

293 {
294 #undef DEBUG
295  // #define DEBUG
296 #ifdef DEBUG
297  printf("DEBUG readSPIDER: Reading Spider file\n");
298 #endif
299 #undef DEBUG
300 
301  if ( select_img == ALL_IMAGES ) {
302  return readSPIDER( 1, ALL_IMAGES );
303  }
304  return readSPIDER(select_img, 1);
305 
306 }
int readSPIDER(size_t select_img)
Definition: rwSPIDER.cpp:292
#define ALL_IMAGES

◆ readSPIDER() [3/4]

int readSPIDER ( size_t  start_img,
size_t  batch_size 
)

Spider Reader

◆ readSPIDER() [4/4]

int ImageBase::readSPIDER ( size_t  start_img,
size_t  batch_size 
)
protected

Spider Reader

Definition at line 144 of file rwSPIDER.cpp.

144  {
145 #undef DEBUG
146  //#define DEBUG
147 #ifdef DEBUG
148  printf("DEBUG readSPIDER: Reading Spider file, start_img = %lu, batch_size = %lu\n", start_img, batch_size);
149 #endif
150 #undef DEBUG
151 
152  // SPIDERhead* header = new SPIDERhead;
153  std::unique_ptr<SPIDERhead> header( new SPIDERhead() );
154  if ( fread( header.get(), SPIDERSIZE, 1, fimg ) != 1 )
155  REPORT_ERROR(ERR_IO_NOREAD, formatString("rwSPIDER: cannot read Spider main header from file %s"
156  ". Error message: %s", filename.c_str() ,strerror(errno)));
157 
158  // Determine byte order and swap bytes if from different-endian machine
159  if ( (swap = (( fabs(header->nslice) > SWAPTRIG ) || ( fabs(header->iform) > 1000 ) ||
160  ( fabs(header->nslice) < 1 ))) )
161  swapPage((char *) header.get(), SPIDERSIZE - 180, DT_Float);
162 
163  if(header->labbyt != header->labrec*header->lenbyt)
164  REPORT_ERROR(ERR_IO_NOTFILE,formatString("Invalid Spider file: %s", filename.c_str()));
165 
166  offset = (size_t) header->labbyt;
168 
169  MDMainHeader.setValue(MDL_MIN,(double)header->fmin);
170  MDMainHeader.setValue(MDL_MAX,(double)header->fmax);
171  MDMainHeader.setValue(MDL_AVG,(double)header->av);
172  MDMainHeader.setValue(MDL_STDDEV,(double)header->sig);
173  MDMainHeader.setValue(MDL_SAMPLINGRATE_X,(double)header->scale);
174  MDMainHeader.setValue(MDL_SAMPLINGRATE_Y,(double)header->scale);
175  MDMainHeader.setValue(MDL_SAMPLINGRATE_Z,(double)header->scale);
177 
178  bool isStack = ( header->istack > 0 );
179  int _xDim,_yDim,_zDim;
180  size_t _nDim, _nDimSet;
181  _xDim = (int) header->nsam;
182  _yDim = (int) header->nrow;
183  _zDim = (int) header->nslice;
184  _nDim = (isStack)? (size_t)(header->maxim) : 1;
185 
186  if (_xDim < 1 || _yDim < 1 || _zDim < 1 || _nDim < 1)
187  REPORT_ERROR(ERR_IO_NOTFILE,formatString("Invalid Spider file: %s", filename.c_str()));
188 
189  replaceNsize = _nDim;
190 
191  /************
192  * BELLOW HERE DO NOT USE HEADER BUT LOCAL VARIABLES
193  */
194 
195  // Map the parameters, REad the whole object (-1) or a slide
196  // Only handle stacks of images not of volumes
197 
198  if(!isStack) {
199  _nDimSet = 1;
200  }
201  else if (batch_size == ALL_IMAGES) {
202  _nDimSet = _nDim - start_img + 1;
203  } else {
204  _nDimSet = std::min( start_img + batch_size - 1, _nDim ) - start_img + 1;
205  }
206 
207  setDimensions(_xDim, _yDim, _zDim, _nDimSet);
208 
209  //image is in stack? and set right initial and final image
210  const size_t header_size = offset;
211 
212  if ( isStack)
213  {
214  if ( start_img > _nDim )
215  REPORT_ERROR(ERR_INDEX_OUTOFBOUNDS, formatString("readSpider (%s): Image number %lu exceeds stack size %lu" ,filename.c_str(),start_img, _nDim));
216  offset += offset;
217  }
218 
219  if (dataMode == HEADER || (dataMode == _HEADER_ALL && _nDimSet > 1)) // Stop reading if not necessary
220  {
221  return 0;
222  }
223 
224  const size_t datasize_n = _xDim*_yDim*_zDim;
225  const size_t image_size = header_size + datasize_n*sizeof(float);
226  const size_t pad = (size_t) header->labbyt;
227  const size_t imgStart = IMG_INDEX(start_img);
228  const size_t imgEnd = start_img + _nDimSet - 1;
229  // printf( "start_img = %lu, batch_size = %lu, _nDim = %lu, _nDimSet = %lu, imgEnd = %lu\n", start_img, batch_size, _nDim, _nDimSet, imgEnd );
230  size_t img_seek = header_size + imgStart * image_size;
231 
232  MD.clear();
233  for (size_t i = 0; i < imgEnd-imgStart; i++)
234  MD.push_back(std::unique_ptr<MDRowVec>(new MDRowVec(MDL::emptyHeaderVec())));
235  double daux;
236 
237  //std::cerr << formatString("DEBUG_JM: header_size: %10lu, datasize_n: %10lu, image_size: %10lu, imgStart: %10lu, img_seek: %10lu",
238  // header_size, datasize_n, image_size, imgStart, img_seek) <<std::endl;
239 
240  for (size_t n = 0, i = imgStart; i < imgEnd; ++i, ++n, img_seek += image_size )
241  {
242  if (fseek( fimg, img_seek, SEEK_SET ) != 0)//fseek return 0 on success
243  REPORT_ERROR(ERR_IO, formatString("rwSPIDER: error seeking %lu for read image %lu", img_seek, i));
244 
245  // std::cerr << formatString("DEBUG_JM: rwSPIDER: seeking %lu for read image %lu", img_seek, i) <<std::endl;
246 
247  if(isStack)
248  {
249  if ( fread( header.get(), SPIDERSIZE, 1, fimg ) != 1 )
250  REPORT_ERROR(ERR_IO_NOREAD, formatString("rwSPIDER: cannot read Spider image %lu header", i));
251  if ( swap )
252  swapPage((char *) header.get(), SPIDERSIZE - 180, DT_Float);
253  }
254  if (dataMode == _HEADER_ALL || dataMode == _DATA_ALL)
255  {
256  daux = (double)header->xoff;
257  MD[n]->setValue(MDL_SHIFT_X, daux);
258  daux = (double)header->yoff;
259  MD[n]->setValue(MDL_SHIFT_Y, daux);
260  daux = (double)header->zoff;
261  MD[n]->setValue(MDL_SHIFT_Z, daux);
262  daux = (double)header->phi;
263  MD[n]->setValue(MDL_ANGLE_ROT, daux);
264  daux = (double)header->theta;
265  MD[n]->setValue(MDL_ANGLE_TILT, daux);
266  daux = (double)header->gamma;
267  MD[n]->setValue(MDL_ANGLE_PSI, daux);
268  daux = (double)header->weight;
269  MD[n]->setValue(MDL_WEIGHT, daux);
270  bool baux = (header->flip == 1);
271  MD[n]->setValue(MDL_FLIP, baux);
272  daux = (double) header->scale;
273  if (daux==0.)
274  daux=1.0;
275  MD[n]->setValue(MDL_SCALE, daux);
276  }
277  }
278 
279  if (dataMode < DATA) // Don't read data if not necessary but read the header
280  return 0;
281 
282 #ifdef DEBUG
283  std::cerr<<"DEBUG readSPIDER: header_size = "<<header_size<<" image_size = "<<image_size<<std::endl;
284  std::cerr<<"DEBUG readSPIDER: select_img= "<<select_img<<" n= "<<Ndim<<" pad = "<<pad<<std::endl;
285 #endif
286  //offset should point to the begin of the data
287  readData(fimg, start_img, datatype, pad );
288 
289  return 0;
290 }
Index out of bounds.
Definition: xmipp_error.h:132
tsne coefficients in 2D
Rotation angle of an image (double,degrees)
void min(Image< double > &op1, const Image< double > &op2)
#define SWAPTRIG
sampling rate in A/pixel (double)
sampling rate in A/pixel (double)
DataMode dataMode
sampling rate in A/pixel (double)
#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
Maximum value (double)
Tilting angle of an image (double,degrees)
void setValue(const MDObject &object) override
Shift for the image in the X axis (double)
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
#define i
Minimum value (double)
It is not a file.
Definition: xmipp_error.h:141
if(fabs(c[*nmax+ *nmax *c_dim1])==0.e0)
Flip the image? (bool)
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
scaling factor for an image or volume (double)
#define SPIDERSIZE
Definition: rwSPIDER.cpp:42
MDRowVec MDMainHeader
DataType datatype() const
#define ALL_IMAGES
String formatString(const char *format,...)
Shift for the image in the Z axis (double)
#define IMG_INDEX(select_img)
average value (double)
FileName filename
Shift for the image in the Y axis (double)
size_t replaceNsize
int * n
< Score 4 for volumes

◆ writeSPIDER() [1/2]

int writeSPIDER ( size_t  select_img = ALL_IMAGES,
bool  isStack = false,
int  mode = WRITE_OVERWRITE 
)

Spider Writer

◆ writeSPIDER() [2/2]

int ImageBase::writeSPIDER ( size_t  select_img = ALL_IMAGES,
bool  isStack = false,
int  mode = WRITE_OVERWRITE 
)
protected

Spider Writer

Definition at line 320 of file rwSPIDER.cpp.

321 {
322 #undef DEBUG
323  //#define DEBUG
324 #ifdef DEBUG
325  printf("DEBUG writeSPIDER: Writing Spider file\n");
326  printf("DEBUG writeSPIDER: File %s\n", filename.c_str());
327 #endif
328 #undef DEBUG
329 
330  // Check datatype compatibility
331  DataType wDType = (isComplexT()) ? DT_CFloat : DT_Float;
332 
333  if (mmapOnWrite)
334  {
335  MDMainHeader.setValue(MDL_DATATYPE,(int) wDType);
336  if (!checkMmapT(wDType))
337  {
338  if (dataMode < DATA) // This means ImageGeneric wants to know which DataType must use in mapFile2Write
339  return 0;
340  else //Mapping is an extra. When not available, go on and do not report an error.
341  {
342  /* In this case we cannot map the file because required and feasible datatypes are
343  * not compatible. Then we denote to MapFile2Write the same incoming datatype to
344  * keep using this Image object as usual, without mapping on write.
345  */
346  mmapOnWrite = false;
347  dataMode = DATA;
349 
350  // In case Image size great then, at least, map the multidimarray
352  mdaBase->setMmap(true);
353 
354  // Allocate memory for image data (Assume xdim, ydim, zdim and ndim are already set
355  //if memory already allocated use it (no resize allowed)
357 
358  return 0;
359  }
360  }
361  else
362  dataMode = DATA;
363  }
364 
365  size_t Xdim, Ydim, Zdim, Ndim;
366  getDimensions(Xdim, Ydim, Zdim, Ndim);
367 
368  size_t datasize, datasize_n;
369  datasize_n = (size_t)Xdim*Ydim*Zdim;
370  datasize = datasize_n * gettypesize(wDType);
371 
372  // Filling the main header
373  float lenbyt = gettypesize(wDType)*Xdim; // Record length (in bytes)
374  float labrec = floor(SPIDERSIZE/lenbyt); // # header records
375  if ( fmod(SPIDERSIZE,lenbyt) != 0 )
376  labrec++;
377  float labbyt = labrec*lenbyt; // Size of header in bytes
378  offset = (size_t) labbyt;
379 
380  SPIDERhead* header = (SPIDERhead *) askMemory((int)labbyt*sizeof(char));
381 
382  // Map the parameters
383  header->lenbyt = lenbyt; // Record length (in bytes)
384  header->labrec = labrec; // # header records
385  header->labbyt = labbyt; // Size of header in bytes
386 
387  header->irec = labrec + floor((datasize_n*gettypesize(wDType))/lenbyt + 0.999999); // Total # records
388  header->nsam = Xdim;
389  header->nrow = Ydim;
390  header->nslice = Zdim;
391 
392  // If a transform, then the physical storage in x is only half+1
393  if ( transform == Hermitian )
394  {
395  size_t xstore = (size_t)(Xdim * 0.5 + 1);
396  header->nsam = 2*xstore;
397  }
398 
399  // #define DEBUG
400 #ifdef DEBUG
401  printf("DEBUG writeSPIDER: Size: %g %g %g %d %g\n",
402  header->nsam,
403  header->nrow,
404  header->nslice,
405  Ndim,
406  header->maxim);
407 #endif
408 #undef DEBUG
409 
410  if ( Zdim < 2 )
411  {
412  // 2D image or 2D Fourier transform
413  header->iform = ( transform == NoTransform ) ? 1 : -12 + (int)header->nsam%2;
414  }
415  else
416  {
417  // 3D volume or 3D Fourier transform
418  header->iform = ( transform == NoTransform )? 3 : -22 + (int)header->nsam%2;
419  }
420  double aux;
421  bool baux;
422  header->imami = 0;//never trust max/min
423 
424 
425  if (!MDMainHeader.empty())
426  {
427 #define SET_MAIN_HEADER_VALUE(field, label, aux) MDMainHeader.getValueOrDefault(label, aux, 0.); header->field = (float)aux
428  SET_MAIN_HEADER_VALUE(fmin, MDL_MIN, aux);
430  SET_MAIN_HEADER_VALUE(av, MDL_AVG, aux);
432  }
433 
434 
435  if (Ndim == 1 && mode != WRITE_APPEND && !isStack && !MD.empty())
436  {
437  if ((dataMode == _HEADER_ALL || dataMode == _DATA_ALL))
438  {
439 #define SET_HEADER_VALUE(field, label, aux) MD[0]->getValueOrDefault((label), (aux), 0.); header->field = (float)(aux)
440  SET_HEADER_VALUE(xoff, MDL_SHIFT_X, aux);
441  SET_HEADER_VALUE(yoff, MDL_SHIFT_Y, aux);
442  SET_HEADER_VALUE(zoff, MDL_SHIFT_Z, aux);
443  SET_HEADER_VALUE(phi, MDL_ANGLE_ROT, aux);
449  }
450  else
451  {
452  header->xoff = header->yoff = header->zoff =\
453  header->phi = header->theta = header->gamma = header->weight = 0.;
454  header->scale = 1.;
455  }
456  }
457 
458  //else end
459  // Set time and date
460  /*
461  time_t timer;
462  time ( &timer );
463  tm* t = localtime(&timer);
464  while ( t->tm_year > 100 )
465  t->tm_year -= 100;
466  sprintf(header->ctim, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec);
467  sprintf(header->cdat, "%02d-%02d-%02d", t->tm_mday, t->tm_mon, t->tm_year);
468  */
469 
470 #ifdef DEBUG
471 
472  printf("DEBUG writeSPIDER: Date and time: %s %s\n", header->cdat, header->ctim);
473  printf("DEBUG writeSPIDER: Text label: %s\n", header->ctit);
474  printf("DEBUG writeSPIDER: Header size: %g\n", header->labbyt);
475  printf("DEBUG writeSPIDER: Header records and record length: %g %g\n", header->labrec, header->lenbyt);
476  printf("DEBUG writeSPIDER: Data size: %ld\n", datasize);
477  printf("DEBUG writeSPIDER: Data offset: %ld\n", offset);
478  printf("DEBUG writeSPIDER: File %s\n", filename.c_str());
479 #endif
480 
481 
482  // Only write mainheader when new file or number of images in stack changed
483  bool writeMainHeaderReplace = false;
484  header->maxim = replaceNsize;
485  size_t imgStart = (mode == WRITE_APPEND)? replaceNsize : IMG_INDEX(select_img);
486  size_t newNsize = imgStart + Ndim;
487 
488  if (Ndim > 1 || mode == WRITE_APPEND || isStack)
489  {
490  header->istack = 2;
491  header->inuse = 1;
492 
493  if( mode == WRITE_APPEND )
494  {
495  writeMainHeaderReplace = true;
496  header->maxim += Ndim;
497  }
498  else if(newNsize > replaceNsize)
499  {
500  writeMainHeaderReplace = true;
501  header->maxim = newNsize;
502  }
503  }
504  else
505  {
506  header->istack = 0;
507  header->inuse = 0;
508  header->maxim = 1;
509  writeMainHeaderReplace=true;
510  }
511 
512  //locking the file
513  FileLock flock;
514  flock.lock(fimg);
515 
516  // Write main header
517  if( mode == WRITE_OVERWRITE ||
518  mode == WRITE_APPEND ||
519  writeMainHeaderReplace ||
520  newNsize > replaceNsize) //header must change
521  {
522  if ( swapWrite )
523  swapPage((char *) header, SPIDERSIZE - 180, DT_Float);
524  fwrite( header, offset, 1, fimg );
525  }
526 
527  // write single image if not stack
528  if ( Ndim == 1 && !isStack)
529  {
530  if (dataMode >= DATA) // Image is not written if only is modifying the header
531  {
532  if (mmapOnWrite)
533  {
534  mappedOffset = ftell(fimg);
535  mappedSize = mappedOffset + datasize;
536  fseek(fimg, datasize-1, SEEK_CUR);
537  fputc(0, fimg);
538  }
539  else
540  writeData(fimg, 0, wDType, datasize_n, CW_CAST);
541  }
542  }
543  else // Jump to the selected imgStart position
544  {
545  fseek( fimg,offset + (offset+datasize)*imgStart, SEEK_SET);
546 
547  //for ( size_t i=0; i<Ndim; i++ )
548  auto it = MD.begin();
549 
550  for (size_t i = 0; i < Ndim; ++it, ++i)
551  {
552  // Write the individual image header
553  if ( it != MD.end() && (dataMode == _HEADER_ALL || dataMode == _DATA_ALL))
554  {
555  SET_HEADER_VALUE(xoff, MDL_SHIFT_X, aux);
556  SET_HEADER_VALUE(yoff, MDL_SHIFT_Y, aux);
557  SET_HEADER_VALUE(zoff, MDL_SHIFT_Z, aux);
558  SET_HEADER_VALUE(phi, MDL_ANGLE_ROT, aux);
564  }
565  else
566  {
567  header->xoff = header->yoff = header->zoff =\
568  header->phi = header->theta = header->gamma = header->weight = 0.;
569  header->scale = 1.;
570  }
571  //do not need to unlock because we are in the overwrite case
572  if ( swapWrite )
573  swapPage((char *) header, SPIDERSIZE - 180, DT_Float);
574  fwrite( header, offset, 1, fimg );
575  if (dataMode >= DATA)
576  {
577  if (mmapOnWrite && Ndim == 1) // Can map one image at a time only
578  {
579  mappedOffset = ftell(fimg);
580  mappedSize = mappedOffset + datasize;
581  fseek(fimg, datasize-1, SEEK_CUR);
582  fputc(0, fimg);
583  }
584  else
585  writeData(fimg, i*datasize_n, wDType, datasize_n, CW_CAST);
586  }
587  else
588  fseek(fimg, datasize, SEEK_CUR);
589  }
590  }
591  //I guess I do not need to unlock since we are going to close the file
592  flock.unlock();
593 
594  if (mmapOnWrite)
595  mmapFile();
596 
597  freeMemory(header, (int)labbyt*sizeof(char));
598 
599  return(0);
600 }
float maxim
Definition: rwSPIDER.cpp:76
float imami
Definition: rwSPIDER.cpp:56
tsne coefficients in 2D
Rotation angle of an image (double,degrees)
#define SET_HEADER_VALUE(field, label, aux)
float lenbyt
Definition: rwSPIDER.cpp:73
float yoff
Definition: rwSPIDER.cpp:69
__host__ __device__ float2 floor(const float2 v)
DataMode dataMode
float labrec
Definition: rwSPIDER.cpp:63
float xoff
Definition: rwSPIDER.cpp:68
float labbyt
Definition: rwSPIDER.cpp:72
size_t mappedOffset
Maximum value (double)
virtual void coreAllocateReuse()=0
Tilting angle of an image (double,degrees)
void setValue(const MDObject &object) override
Shift for the image in the X axis (double)
void swapPage(char *page, size_t pageNrElements, DataType datatype, int swap=1)
std::vector< std::unique_ptr< MDRow > > MD
float scale
Definition: rwSPIDER.cpp:71
ArrayDim getDimensions()
Special label to be used when gathering MDs in MpiMetadataPrograms.
if read from file original image datatype, this is an struct defined in image
void unlock()
Unlock.
char ctim[8]
Definition: rwSPIDER.cpp:110
TransformType transform
double * gamma
double weight(const size_t n=0) const
float istack
Definition: rwSPIDER.cpp:74
#define i
float nslice
Definition: rwSPIDER.cpp:51
double theta
Minimum value (double)
int freeMemory(void *ptr, size_t memsize)
float weight
Definition: rwSPIDER.cpp:104
const size_t tiff_map_min_size
void setMmap(bool mmap)
Flip the image? (bool)
virtual bool checkMmapT(DataType datatype)=0
float nrow
Definition: rwSPIDER.cpp:52
float zoff
Definition: rwSPIDER.cpp:70
double scale(const size_t n=0) const
float iform
Definition: rwSPIDER.cpp:55
virtual bool isComplexT() const =0
char * askMemory(size_t memsize)
virtual void mmapFile()=0
DataType
scaling factor for an image or volume (double)
void mode
#define SET_MAIN_HEADER_VALUE(field, label, aux)
#define SPIDERSIZE
Definition: rwSPIDER.cpp:42
MDRowVec MDMainHeader
size_t mappedSize
void lock(int fileno=0)
Lock file.
float theta
Definition: rwSPIDER.cpp:66
virtual void writeData(FILE *fimg, size_t offset, DataType wDType, size_t datasize_n, CastWriteMode castMode=CW_CAST)=0
char ctit[160]
Definition: rwSPIDER.cpp:111
float inuse
Definition: rwSPIDER.cpp:75
float nsam
Definition: rwSPIDER.cpp:62
char cdat[12]
Definition: rwSPIDER.cpp:109
Shift for the image in the Z axis (double)
bool empty() const override
#define IMG_INDEX(select_img)
average value (double)
FileName filename
bool flip(const size_t n=0) const
Shift for the image in the Y axis (double)
float irec
Definition: rwSPIDER.cpp:53
virtual DataType myT() const =0
size_t replaceNsize
double fmax
MultidimArrayBase * mdaBase
float gamma
Definition: rwSPIDER.cpp:67
< Score 4 for volumes
size_t gettypesize(DataType type)
Returns memory size of datatype.