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

Classes

struct  MRCheadold
 
struct  MRChead
 

Functions

int readMRC (size_t select_img, bool isStack=false)
 
int writeMRC (size_t select_img, bool isStack=false, int mode=WRITE_OVERWRITE, const String &bitDepth="", CastWriteMode castMode=CW_CAST)
 
int ImageBase::readMRC (size_t select_img, bool isStack=false)
 
int ImageBase::writeMRC (size_t select_img, bool isStack=false, int mode=WRITE_OVERWRITE, const String &bitDepth="", CastWriteMode castMode=CW_CAST)
 

Detailed Description

Function Documentation

◆ readMRC() [1/2]

int readMRC ( size_t  select_img,
bool  isStack = false 
)

MRC Reader

◆ readMRC() [2/2]

int ImageBase::readMRC ( size_t  select_img,
bool  isStack = false 
)
protected

MRC Reader

Definition at line 352 of file rwMRC.cpp.

353 {
354 #undef DEBUG
355  //#define DEBUG
356 #ifdef DEBUG
357  printf("DEBUG readMRC: Reading MRC file\n");
358 #endif
359 
360  if (select_img == ALL_IMAGES) {
361  return readMRC(1, ALL_IMAGES, isStack);
362  }
363  return readMRC(select_img, 1, isStack);
364 }
int readMRC(size_t select_img, bool isStack=false)
Definition: rwMRC.cpp:352
#define ALL_IMAGES

◆ writeMRC() [1/2]

int writeMRC ( size_t  select_img,
bool  isStack = false,
int  mode = WRITE_OVERWRITE,
const String bitDepth = "",
CastWriteMode  castMode = CW_CAST 
)

MRC Writer

◆ writeMRC() [2/2]

int ImageBase::writeMRC ( size_t  select_img,
bool  isStack = false,
int  mode = WRITE_OVERWRITE,
const String bitDepth = "",
CastWriteMode  castMode = CW_CAST 
)
protected

MRC Writer

header->a,b,c info is related to sampling rate, so it is only written when writing header, so it is initialized to number of voxels to avoid a mistaken value. If sampling is provided a, b and c are overwritten bellow

Definition at line 369 of file rwMRC.cpp.

370 {
371  MRChead* header = (MRChead *) askMemory(sizeof(MRChead));
372 
373  // Cast T to datatype
374  DataType wDType,myTypeID = myT();
375 
376  if (bitDepth == "")
377  {
378  castMode = CW_CAST;
379  switch(myTypeID)
380  {
381  case DT_Double:
382  case DT_Float:
383  case DT_Int:
384  case DT_UInt:
385  wDType = DT_Float;
386  header->mode = 2;
387  break;
388  case DT_UShort:
389  wDType = DT_UShort;
390  header->mode = 6;
391  break;
392  case DT_Short:
393  wDType = DT_Short;
394  header->mode = 1;
395  break;
396  case DT_SChar:
397  castMode = CW_CONVERT;
398  /* no break */
399  case DT_UChar:
400  wDType = DT_UChar;
401  header->mode = 0;
402  break;
403  case DT_CFloat:
404  case DT_CDouble:
405  wDType = DT_CFloat;
406  header->mode = 4;
407  break;
408  case DT_HalfFloat:
409  wDType = DT_HalfFloat;
410  header->mode = 12;
411  break;
412  //case DT_UHalfByte:
413  default:
414  wDType = DT_Unknown;
415  (void)wDType; // to suppress dead assignment warning
416  REPORT_ERROR(ERR_TYPE_INCORRECT,(std::string)"ERROR: Unsupported data type by MRC format.");
417  }
418  }
419  else //Convert to other data type
420  {
421  // Default Value
422  wDType = (bitDepth == "default") ? DT_Float : datatypeRAW(bitDepth);
423 
424  switch (wDType)
425  {
426  case DT_Double:
427  case DT_Int:
428  case DT_UInt:
429  case DT_Float:
430  header->mode = 2;
431  break;
432  case DT_UChar:
433  header->mode = 0;
434  break;
435  case DT_UShort:
436  header->mode = 6;
437  break;
438  case DT_Short:
439  header->mode = 1;
440  break;
441  case DT_CFloat:
442  case DT_CDouble:
443  header->mode = 4;
444  break;
445  case DT_HalfFloat:
446  header->mode = 12;
447  break;
448  default:
449  REPORT_ERROR(ERR_TYPE_INCORRECT,"ERROR: incorrect MRC bits depth value.");
450  }
451  }
452 
453  if (mmapOnWrite)
454  {
455  MDMainHeader.setValue(MDL_DATATYPE,(int) wDType);
456  if (!checkMmapT(wDType))
457  {
458  if (dataMode < DATA && castMode == CW_CAST) // This means ImageGeneric wants to know which DataType must use in mapFile2Write
459  return 0;
460  else //Mapping is an extra. When not available, go on and do not report an error.
461  {
462  /* In this case we cannot map the file because required and feasible datatypes are
463  * not compatible. Then we denote to MapFile2Write the same incoming datatype to
464  * keep using this Image object as usual, without mapping on write.
465  */
466  mmapOnWrite = false;
467  dataMode = DATA;
468  MDMainHeader.setValue(MDL_DATATYPE,(int) myTypeID);
469 
470  // In case Image size great then, at least, map the multidimarray
472  mdaBase->setMmap(true);
473 
474  // Allocate memory for image data (Assume xdim, ydim, zdim and ndim are already set
475  //if memory already allocated use it (no resize allowed)
477 
478  return 0;
479  }
480  }
481  else
482  dataMode = DATA;
483  }
484 
485 
486  /*
487  if ( transform != NoTransform )
488  img_convert_fourier(p, CentHerm);
489  */
490 
491  // Map the parameters
492  strncpy(header->map, "MAP ", 4);
493  // FIXME TO BE DONE WITH rwCCP4!!
494  //set_CCP4_machine_stamp(header->machst);
495  char* machine_stamp;
496  machine_stamp = (char *)(header->machst);
497  if(IsLittleEndian())
498  {
499  machine_stamp[0] = 68;
500  machine_stamp[1] = 65;
501  }
502  else
503  {
504  machine_stamp[0] = machine_stamp[1] = 17;
505  }
506  // case LittleVAX:
507  // machine_stamp[0] = 34;
508  // machine_stamp[1] = 65;
509  // break;
510 
511  size_t Xdim, Ydim, Zdim, Ndim;
512  getDimensions(Xdim, Ydim, Zdim, Ndim);
513 
521  header->mx = header->nx = Xdim;
522  header->my = header->ny = Ydim;
523  header->mz = header->nz = Zdim;
524 
525  // Obtaining sampling rate for each dimension and calculating cube size
526  // By default sampling rate is 1.0 if no real value was found
527  double sampling;
529  header->a = (float)(Xdim * sampling);
531  header->b = (float)(Ydim * sampling);
533  header->c = (float)(Zdim * sampling);
534 
535  if ( transform == CentHerm )
536  header->nx = Xdim/2 + 1; // If a transform, physical storage is nx/2 + 1
537 
538  header->alpha = 90.;
539  header->beta = 90.;
540  header->gamma = 90.;
541 
542  // header->mx = 0;//(int) (ua/ux + 0.5);
543  // header->my = 0;//(int) (ub/uy + 0.5);
544  // header->mz = 0;//(int) (uc/uz + 0.5);
545  header->mapc = 1;
546  header->mapr = 2;
547  header->maps = 3;
548  double aux,aux2;
549 
550  // header->a = 0.;// ua;
551  // header->b = 0.;// ub;
552  // header->c = 0.;// uc;
553 
554  if (!MDMainHeader.empty())
555  {
556 #define SET_MAIN_HEADER_VALUE(field, label) MDMainHeader.getValueOrDefault(label, aux, 0.); header->field = (float)aux
561 
562  if ((dataMode == _HEADER_ALL || dataMode == _DATA_ALL))
563  {
564 #define SET_HEADER_SHIFT(field, label) MD[0]->getValueOrDefault(label, aux, 0.); header->field = -(int) round(aux)
565  SET_HEADER_SHIFT(nxStart, MDL_SHIFT_X);
566  SET_HEADER_SHIFT(nyStart, MDL_SHIFT_Y);
567  SET_HEADER_SHIFT(nzStart, MDL_SHIFT_Z);
568 #define SET_HEADER_ORIGIN(field, label1, label2) MD[0]->getValueOrDefault(label1, aux, 0.);MDMainHeader.getValueOrDefault(label2, aux2, 0.);\
569  header->field = (float) (aux * aux2)
570 
574 
575 #define SET_HEADER_CELL_DIM(field, label1, dimSize) MDMainHeader.getValueOrDefault(label1, aux, 0.);\
576  header->field = (float) (aux * dimSize)
577 
581  }
582  else
583  {
584  header->nxStart = header->nyStart = header->nzStart = 0;
585  header->xOrigin = header->yOrigin = header->zOrigin = 0;
586  }
587  }
588 
589  header->nsymbt = 0;
590  header->nlabl = 10; // or zero?
591  //strncpy(header->labels, p->label.c_str(), 799);
592 
593  offset = MRCSIZE + header->nsymbt;
594  size_t datasize, datasize_n;
595  datasize_n = Xdim*Ydim*Zdim;
596  datasize = datasize_n * gettypesize(wDType);
597 
598  //#define DEBUG
599 #ifdef DEBUG
600 
601  printf("DEBUG rwMRC: Offset = %ld, Datasize_n = %ld\n", offset, datasize_n);
602 #endif
603 
604  size_t imgStart = 0;
605 
606  if (Ndim > 1 || filename.contains(":mrcs")) // If format is forced through ":" flag suffix, then ignore the stack behavior in header
607  isStack = true;
608 
609  bool isVolStk = isStack && Zdim > 1;
610  size_t nDimHeader = Ndim;
611 
612  if (isStack)
613  {
614  imgStart = IMG_INDEX(select_img);
615 
616  if( mode == WRITE_APPEND )
617  {
618  imgStart = replaceNsize;
619  nDimHeader = replaceNsize + Ndim;
620  }
621  else if( mode == WRITE_REPLACE && select_img + Ndim - 1 > replaceNsize)
622  {
623  nDimHeader = select_img + Ndim - 1;
624  }
625  // else if (Ndim > replaceNsize)
626  // nDimHeader = Ndim;
627 
628 
629  if (isVolStk)
630  {
631  header->ispg = 401;
632  header->mz = Zdim;
633  header->nz = Zdim * nDimHeader;
634  }
635  else
636  {
637  header->ispg = 0;
638  header->nz = nDimHeader;
639  }
640  }
641  else // To set in the header that the file is a volume not a stack
642  header->ispg = (Zdim>1)? 1:0;
643 
644  //locking
645  FileLock flock;
646  flock.lock(fimg);
647 
648  // Write header when needed
649  if(!isStack || replaceNsize < nDimHeader)
650  {
651  if ( swapWrite )
652  swapPage((char *) header, MRCSIZE - 800, DT_Float);
653  fwrite( header, MRCSIZE, 1, fimg );
654  }
655  freeMemory(header, sizeof(MRChead) );
656 
657  // Jump to the selected imgStart position
658  fseek( fimg,offset + (datasize)*imgStart, SEEK_SET);
659 
660  size_t imgEnd = (isStack)? Ndim : 1;
661 
662  if (checkMmapT(wDType) && !mmapOnWrite && dataMode >= DATA) {
663  writeData(fimg, 0, wDType, datasize_n * imgEnd, castMode);
664  } else {
665  for ( size_t i = 0; i < imgEnd; i++ )
666  {
667  // If to also write the image data or jump its size
668  if (dataMode >= DATA)
669  {
670  if (mmapOnWrite && Ndim == 1) // Can map one image at a time only
671  {
672  mappedOffset = ftell(fimg);
673  mappedSize = mappedOffset + datasize;
674  fseek(fimg, datasize-1, SEEK_CUR);
675  fputc(0, fimg);
676  }
677  else
678  writeData(fimg, i*datasize_n, wDType, datasize_n, castMode);
679  }
680  else
681  fseek(fimg, datasize, SEEK_CUR);
682  }
683  }
684 
685 
686 
687  // Unlock the file
688  flock.unlock();
689 
690  if (mmapOnWrite)
691  mmapFile();
692 
693  return(0);
694 }
int32_t my
Definition: rwMRC.cpp:103
tsne coefficients in 2D
sampling rate in A/pixel (double)
#define SET_MAIN_HEADER_VALUE(field, label)
sampling rate in A/pixel (double)
DataMode dataMode
#define MRCSIZE
Definition: rwMRC.cpp:44
sampling rate in A/pixel (double)
bool IsLittleEndian(void)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
doublereal * c
size_t mappedOffset
int32_t nsymbt
Definition: rwMRC.cpp:120
int32_t mz
Definition: rwMRC.cpp:104
int32_t mx
Definition: rwMRC.cpp:102
Maximum value (double)
virtual void coreAllocateReuse()=0
float alpha
Definition: rwMRC.cpp:110
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)
const T & getValueOrDefault(MDLabel label, const T &def) const
char machst[4]
Definition: rwMRC.cpp:126
ArrayDim getDimensions()
float gamma
Definition: rwMRC.cpp:112
if read from file original image datatype, this is an struct defined in image
float zOrigin
Definition: rwMRC.cpp:124
void unlock()
Unlock.
int32_t mapc
Definition: rwMRC.cpp:113
#define SET_HEADER_ORIGIN(field, label1, label2)
float beta
Definition: rwMRC.cpp:111
TransformType transform
auxiliary label to be used as an index (long)
float yOrigin
Definition: rwMRC.cpp:123
#define i
Minimum value (double)
int32_t nz
Definition: rwMRC.cpp:97
doublereal * b
int32_t ny
Definition: rwMRC.cpp:96
#define SET_HEADER_CELL_DIM(field, label1, dimSize)
int32_t nxStart
Definition: rwMRC.cpp:99
float c
Definition: rwMRC.cpp:109
int freeMemory(void *ptr, size_t memsize)
Origin for the image in the Y axis (double)
const size_t tiff_map_min_size
int32_t mapr
Definition: rwMRC.cpp:114
int32_t nx
Definition: rwMRC.cpp:95
void setMmap(bool mmap)
virtual bool checkMmapT(DataType datatype)=0
int32_t ispg
Definition: rwMRC.cpp:119
#define sampling
float b
Definition: rwMRC.cpp:108
char * askMemory(size_t memsize)
virtual void mmapFile()=0
DataType
int32_t maps
Definition: rwMRC.cpp:115
void mode
bool contains(const String &str) const
char map[4]
Definition: rwMRC.cpp:125
int32_t nlabl
Definition: rwMRC.cpp:128
int32_t nzStart
Definition: rwMRC.cpp:101
int32_t nyStart
Definition: rwMRC.cpp:100
MDRowVec MDMainHeader
size_t mappedSize
void lock(int fileno=0)
Lock file.
float xOrigin
Definition: rwMRC.cpp:122
virtual void writeData(FILE *fimg, size_t offset, DataType wDType, size_t datasize_n, CastWriteMode castMode=CW_CAST)=0
#define SET_HEADER_SHIFT(field, label)
int32_t mode
Definition: rwMRC.cpp:98
Shift for the image in the Z axis (double)
bool empty() const override
#define IMG_INDEX(select_img)
Origin for the image in the Z axis (double)
average value (double)
FileName filename
Shift for the image in the Y axis (double)
virtual DataType myT() const =0
Incorrect type received.
Definition: xmipp_error.h:190
size_t replaceNsize
MultidimArrayBase * mdaBase
DataType datatypeRAW(String strDT)
Definition: rwRAW.cpp:31
float a
Definition: rwMRC.cpp:107
doublereal * a
size_t gettypesize(DataType type)
Returns memory size of datatype.