/** * \file ImageHeader.h * \brief Header for EM images * Copyright 2007-8 Sali Lab. All rights reserved. * Adapted with permission from Xmip 2.2 */ #ifndef _IMPEM_IMAGE_HEADER_H #define _IMPEM_IMAGE_HEADER_H // #include "EM_config.h" #include #include #include IMPEM_BEGIN_NAMESPACE //! Header for Spider images. IMP-EM is designed to be compatible with it /** \ingroup helper */ typedef struct { float fNslice; // NUMBER OF SLICES (PLANES) IN VOLUME // (=1 FOR AN IMAGE) FOR NEW LONG LABEL // FORMAT THE VALUE OF NSLICE STORED IN // THE FILE IS NEGATIVE. float fNrow; // NUMBER OF ROWS PER SLICE (Y) float fNrec; // TOTAL NUMBER OF RECORDS (SEE NOTE #3). float fNlabel; // AUXILIARY NUMBER TO COMPUTE TOTAL NUMBER OF RECS float fIform; // FILE TYPE SPECIFIER. // +3 FOR A 3-D FILE (FLOAT) // +1 FOR A 2-D IMAGE (FLOAT) // -1 FOR A 2-D FOURIER TRANSFORM // -3 FOR A 3-D FOURIER TRANSFORM // -5 FOR A NEW 2-D FOURIER TRANSFORM // -7 FOR A NEW 3-D FOURIER TRANSFORM // +8 FOR A 2-D EIGHT BIT IMAGE FILE // +9 FOR A 2-D INT IMAGE FILE // 10 FOR A 3-D INT IMAGE FILE // 11 FOR A 2-D EIGHT BIT COLOR IMAGE FILE float fImami; // MAXIMUM/MINIMUM FLAG. IS SET AT 0 WHEN THE // FILE IS CREATED, AND AT 1 WHEN THE MAXIMUM AND // MINIMUM HAVE BEEN COMPUTED, AND HAVE BEEN STORED // INTO THIS LABEL RECORD (SEE FOLLOWING WORDS) float fFmax; // MAXIMUM VALUE float fFmin; // MINIMUM VALUE float fAv; // AVERAGE VALUE float fSig; // STANDARD DEVIATION. A VALUE OF -1. INDICATES // THAT SIG HAS NOT BEEN COMPUTED PREVIOUSLY. float fIhist; // FLAG INDICATING IF THE HISTOGRAM HAS BE // COMPUTED. NOT USED IN 3D FILES! float fNcol; // NUMBER OF PIXELS PER LINE (Columns X) float fLabrec; // NUMBER OF LABEL RECORDS IN FILE HEADER float fIangle; // FLAG THAT TILT ANGLES HAVE BEEN FILLED float fPhi; // EULER: ROTATIONAL ANGLE float fTheta; // EULER: TILT ANGLE float fPsi; // EULER: PSI = TILT ANGLE float fXoff; // X TRANSLATION float fYoff; // Y TRANSLATION float fZoff; // Z TRANSLATION float fScale; // SCALE float fLabbyt; // TOTAL NUMBER OF BYTES IN LABEL float fLenbyt; // RECORD LENGTH IN BYTES char fNada[24]; // this is a spider incongruence float fFlag; // THAT ANGLES ARE SET. 1 = ONE ADDITIONAL // ROTATION IS PRESENT, 2 = ADDITIONAL ROTATION // THAT PRECEEDS THE ROTATION THAT WAS STORED IN // 15 FOR DETAILS SEE MANUAL CHAPTER VOCEUL.MAN float fPhi1; float fTheta1; float fPsi1; float fPhi2; float fTheta2; float fPsi2; double fGeo_matrix[3][3]; // x9 = 72 bytes: Geometric info float fAngle1; // angle info float fr1; float fr2; // lift up cosine mask parameters /** Fraga 23/05/97 For Radon transforms **/ float RTflag; // 1=RT, 2=FFT(RT) float Astart; float Aend; float Ainc; float Rsigma; // 4*7 = 28 bytes float Tstart; float Tend; float Tinc; // 4*3 = 12, 12+28 = 40B /** Sjors Scheres 17/12/04 **/ float Weight; // For Maximum-Likelihood refinement (currently not used) float Flip; // 0=no flipping operation (false), 1=flipping (true) (not used) char fNada2[576]; // empty 700-76-40=624-40-8= 576 bytes char szIDat[12]; // LOGICAL * 1 ARRAY DIMENSIONED 10, CONTAINING /*215-216*/ char szITim[8]; // LOGICAL * 1 ARRAY DIMENSIONED 8, CONTAINING // THE TIME OF CREATION (8 CHARS) char szITit[160]; // LOGICAL * 1 ARRAY DIMENSIONED 160 } SpiderHeader; /** Class to deal with the header of IMP-EM images. (Compatible with Xmipp and Spider formats) */ class IMPEMEXPORT ImageHeader { public: //! Types of initialization of ImageHeader typedef enum { IMG_BYTE = 0, IMG_IMPEM = 1, IMG_INT = 9, /*IMG_SHORT = , IMG_UCHAR = ,*/ VOL_BYTE = 2, VOL_IMPEM = 3, VOL_INT = 10 , /*VOL_SHORT = , VOL_UCHAR =, */ IMG_FOURIER = -1, VOL_FOURIER = -3} InitMode; // Constructors ImageHeader(InitMode im = IMG_BYTE) { clear(); im_ = im; } //! Output operator friend std::ostream& operator<<(std::ostream& out, const headerXmipp& I); //! Prints a reduced set of information (debugging purposes) void print_hard(std::ostream& out) const; //! Reads a 2D image file // \note reversed is only used in case that the type_check is skipped int read(const String filename, bool skip_type_check= false, bool force_reversed= false, bool skip_extra_checkings= false); //! Writes a 2D image file void write(const String &filename, bool force_reversed = false); //! Get type of header InitMode& get_header_type() { return im_; } //! Get type of header InitMode get_header_type() const { return im_; } //! Clear header data (set all header to zero ) void clear(); //! Sets a consistent header void set_header(); //! Interaction with data bool reversed() const { return reversed_; } //! Interaction with data bool& reversed() { return reversed_; } //! set dimensions of the image in the header void set_dimensions(float Ydim, float Xdim); //! get dimensions of the image void get_dimensions(float& Ydim, float& Xdim) const; //! get header size int get_header_size() const { return (int) header_.fNcol *(int) header_.fLabrec * sizeof(float); } //! Get Y dimension float& get_Ydim() { return header_.fNrow; } //! Get Y dimension int get_iYdim() const { return (int) header_.fNrow; } //! Get X dimension float& get_Xdim() { return header_.fNcol; } //! Get X dimension int get_iXdim() const { return (int) header_.fNcol; } float& get_Slices() { return header_.fNslice; } float get_Slices() const { return header_.fNslice; } int get_iSlices() const { return (int) header_.fNslice; } int get_iZdim() const { return (int) header_.fNslice; } //! Rotation Angle float get_old_rot() const { return header_.fAngle1; } float& get_old_rot() { return header_.fAngle1; } float get_Scale() const { return header_.fScale; } float& get_Scale() { return header_.fScale; } //! For Maximum-Likelihood refinement (for compatibility: not currently used) float get_Flip() const { return header_.Flip; } float& get_Flip() { return header_.Flip; } float get_Weight() const { return header_.Weight; } float& get_Weight() { return header_.Weight; } float get_fNrec() const { return header_.fNrec; } float& get_fNrec() { return header_.fNrec; } float get_fNlabel() const { return header_.fNlabel; } float& get_fNlabel() { return header_.fNlabel; } float get_fIform() const { return header_.fIform; } float& get_fIform() { return header_.fIform; } float get_fImami() const { return header_.fImami; } float& get_fImami() { return header_.fImami; } float get_fFmax() const { return header_.fFmax; } float& get_fFmax() { return header_.fFmax; } float get_fFmin() const { return header_.fFmin; } float& get_fFmin() { return header_.fFmin; } float get_fAv() const { return header_.fAv; } float& get_fAv() { return header_.fAv; } float get_fSig() const { return header_.fSig; } float& get_fSig() { return header_.fSig; } float get_fIhist() const { return header_.fIhist; } float& get_fIhist() { return header_.fIhist; } float get_fLabrec() const { return header_.fLabrec; } float& get_fLabrec() { return header_.fLabrec; } float get_fIangle() const { return header_.fIangle; } float& get_fIangle() { return header_.fIangle; } float get_fXoff() const { return header_.fXoff; } float& get_fXoff() { return header_.fXoff; } float get_fYoff() const { return header_.fYoff; } float& get_fYoff() { return header_.fYoff; } float get_fZoff() const { return header_.fZoff; } float& get_fZoff() { return header_.fZoff; } float get_fLabbyt() const { return header_.fLabbyt; } float& get_fLabbyt() { return header_.fLabbyt; } float get_fLenbyt() const { return header_.fLenbyt; } float& get_fLenbyt() { return header_.fLenbyt; } Matrix2D< double > fGeo_matrix(); // Origin offsets void set_originOffsets(float Xoff, float Yoff); void get_originOffsets(float& Xoff, float& Yoff) const; // Euler angles void set_eulerAngles(float Phi, float Theta, float Psi); void set_eulerAngles1(float Phi1, float Theta1, float Psi1); void set_eulerAngles2(float Phi2, float Theta2, float Psi2); //! Clears fFlag flag. /** The number of triads of Euler angles stored in the header (up to three) is stored here. set_eulerAngles2 makes fFlag=2, set_eulerAngles1 makes fFlag=max(fFlag, 1), set_eulerAngles does not change fFlag */ void clear_fFlag_flag() { header_.fFlag = 0.f; } template void get_euler_angles(T& Phi, T& Theta, T& Psi) const { Phi = (T) header_.fPhi; Theta = (T) header_.fTheta; Psi = (T) header_.fPsi; } template void get_euler_angles1(T& Phi1, T& Theta1, T& Psi1) const { Phi1 = (T) header_.fPhi1; Theta1 = (T) header_.fTheta1; Psi1 = (T) header_.fPsi1; } template void get_euler_angles2(T& Phi2, T& Theta2, T& Psi2) const { Phi2 = (T) header_.fPhi2; Theta2 = (T) header_.fTheta2; Psi2 = (T) header_.fPsi2; } float& get_Phi() { header_.fIangle = 1; return header_.fPhi; } float get_Phi() const { return header_.fPhi; } float& get_Theta() { header_.fIangle = 1; return header_.fTheta; } float get_Theta() const { return header_.fTheta; } float& get_Psi() { header_.fIangle = 1; return header_.fPsi; } float get_Psi() const { return header_.fPsi; } float& get_Phi1() { header_.fFlag = 1.f; return header_.fPhi1; } float get_Phi1() const { return header_.fPhi1; } float& get_Theta1() { header_.fFlag = 1.f; return header_.fTheta1; } float get_Theta1() const { return header_.fTheta1; } float& get_Psi1() { header_.fFlag = 1.f; return header_.fPsi1; } float get_Psi1() const { return header_.fPsi1; } float& get_Phi2() { header_.fFlag = 2.f; return header_.fPhi2; } float get_Phi2() const { return header_.fPhi2; } float& get_Theta2() { header_.fFlag = 2.f; return header_.fTheta2; } float get_Theta2() const { return header_.fTheta2; } float& get_Psi2() { header_.fFlag = 2.f; return header_.fPsi2; } float get_Psi2() const { return header_.fPsi2; } float is_flag_set(void) { return(header_.fFlag); } // Date and Time char* get_date() const; char* get_time() const; void set_date(); void set_time(); // Title char* get_title() const; //! Set title of image in the header void set_title(String newName); protected: SpiderHeader header_; InitMode im_; bool reversed_; } IMPEM_END_NAMESPACE #endif