2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2019,2021, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
35 /*! \libinternal \file
37 * Implement mrc/ccp4-file metadata.
39 * \author Christian Blau <cblau@gwdg.de>
42 * \ingroup module_fileio
44 #ifndef GMX_FILEIO_MRCDENSITYMAPHEADER_H
45 #define GMX_FILEIO_MRCDENSITYMAPHEADER_H
50 #include "gromacs/math/coordinatetransformation.h"
51 #include "gromacs/math/vectypes.h"
52 #include "gromacs/mdspan/extensions.h"
57 /*! \brief Space group in three dimensions.
59 * Currently only "no symmetry" is supported, the complete enum class would hold
62 * Table 12.3.4.1 Standard space-group symbols, pages 824-831,
63 * International Tables for Crystallography, Volume A, fifth edition
65 enum class SpaceGroup : int32_t
67 P1 = 1, //!< no symmetry
70 /*! \brief The type of density data stored in an mrc file.
72 * "EMDB Map Distribution Format Description Version 1.01 (c) emdatabank.org 2014"
73 * Modes 0-4 are defined by the standard.
74 * NOTE only mode 2 is currently implemented and used.
76 enum class MrcDataMode : int32_t
78 uInt8 = 0, //!< compressed data mode, 8 bits, signed byte (range -128 to 127, ISO/IEC 10967)
79 int16 = 1, //!< 16 bits, signed integer (range -32768 to 32767, ISO/IEC 10967)
80 float32 = 2, //!< 32 bits, floating point number (IEEE 754)
81 complexInt32 = 3, //!< 32 bits, complex signed integers (ISO/IEC 10967)
82 complexFloat64 = 4, //!< 64 bits, complex floating point numbers (IEEE 754)
86 * \brief Statistics about mrc data arrays.
88 struct MrcDataStatistics
90 float min_ = 0.; //!< Minimum data value scales values in (currently unsupported) compressed data mode.
91 float max_ = 0.; //!< Maximum data value scales values in (currently unsupported) compressed data mode.
92 float mean_ = 0.; //!< mean of the data
93 float rms_ = 0.; //!< rms of the data
97 * \brief Skew matrix and translation.
99 * "EMDB Map Distribution Format Description Version 1.01 (c) emdatabank.org 2014"
101 struct MrcDensitySkewData
103 bool valid_ = false; //!< True if skew matrix is stored.
104 std::array<float, DIM* DIM> matrix_ = {}; //!< Skew matrix for crystallographic unit cell in Ångström
105 std::array<float, DIM> translation_ = {}; //!< Translation of crystallographic unit cell in Ångström
109 * \brief Crystallographic labels for mrc data.
111 struct CrystallographicLabels
113 static constexpr int c_labelSize = 80; //!< Length of crystallographic labels is eighty.
114 //! Number of used crystallographic labels, 0 for imagestacks, 1 for emdb data
115 int32_t numUsedLabels_ = 0;
117 //! Crystallographic labels or "::::EMDataBank.org::::EMD-1234::::" for EMDB entries
118 std::array<std::array<unsigned char, c_labelSize>, 10> labels_ = {};
122 * \brief A container for the data in mrc density map file formats.
124 * Mrc files are a widely used file format in crystallography and cryo electron
125 * microscopy to represent volumetric data. Covers ccp4, map and imod.
127 * For a detailed description see
128 * "EMDB Map Distribution Format Description Version 1.01 (c) emdatabank.org 2014"
130 struct MrcDensityMapHeader
133 //! Space group of stored data.
134 SpaceGroup spaceGroup_ = SpaceGroup::P1;
135 //! Data mode, currently only mode 2 is supported
136 MrcDataMode dataMode_ = MrcDataMode::float32;
137 //! Identifies file format, expected to be "MAP "
138 std::array<unsigned char, 4> formatIdentifier_ = { { 'M', 'A', 'P', ' ' } };
139 //! 15 unspecified float numbers
140 std::array<float, 15> userDefinedFloat_ = {};
142 //! Labels for crystallographic data
143 CrystallographicLabels labels_ = {};
145 //! Length of the crystallographic unit cell in Ångström
146 std::array<float, DIM> cellLength_ = { { 1., 1., 1. } };
147 //! crystallographic unit cell angles
148 std::array<float, DIM> cellAngles_ = { { 90., 90., 90. } };
150 //! Data axis order with columns varying the fastest, and sections the slowest.
151 std::array<int32_t, DIM> columnRowSectionToXyz_ = { { 0, 1, 2 } };
153 std::array<int32_t, DIM> numColumnRowSection_ = {}; //!< Column, row and section count
154 std::array<int32_t, DIM> columnRowSectionStart_ = {}; //!< Start of values in grid
155 std::array<int32_t, DIM> extent_ = {}; //!< The number of grid points in the crystall cell
157 //! Statistics about the data stored in the file.
158 MrcDataStatistics dataStatistics_ = {};
159 //! Data to perform crystallographic unit cell skewing
160 MrcDensitySkewData skewData_ = {};
161 //! Extended header with symmetry tables
162 std::vector<unsigned char> extendedHeader_ = {};
165 /*! \brief Return the number of density data items that are expected
166 * to follow this header.
167 * \throws InternalError if the number of data items cannot be determined
168 * \returns the number of voxels
170 size_t numberOfExpectedDataItems(const MrcDensityMapHeader& header);
172 /*! \brief Extract the transformation into lattice coordinates.
173 * \note Transformation into lattice coordinates is not treated uniformly
174 * in different implementations for the mrc format,e.g., vmd, pymol and
175 * chimera have different conventions. Following the vmd implementation here.
177 * In determining the density origin coordinates, explicit ORIGIN records
178 * (also called origin2k) in the user defined floats 13 - 15, corresponding to
179 * words 50,51 and 52 in the mrc header, precedence over ColumnRowSectionStart.
180 * Only if above values are zero, using the column, row and section start to
181 * determine the translation vector.
183 * \param[in] header from which the coordinate transformation is to be extracted
184 * \returns a functor that transforms real space coordinates into the lattice
186 TranslateAndScale getCoordinateTransformationToLattice(const MrcDensityMapHeader& header);
188 /*! \brief Extract the extents of the density data
189 * \param[in] header from which the extents are to be extracted
190 * \returns density data extents in three dimensions.
192 dynamicExtents3D getDynamicExtents3D(const MrcDensityMapHeader& header);
194 /*! \brief Checks if the values in the header are sane.
196 * Checks extents and numbers of columns, rows and sections, as well as unit
197 * cell angles for positivity and to be within bounds.
199 * Bounds are set generously not to hamper future creative uses of mrc files.
201 * \returns true if all header values are within resonable albeit generous bounds
203 bool mrcHeaderIsSane(const MrcDensityMapHeader& header);
206 #endif /* end of include guard: GMX_FILEIO_MRCDENSITYMAPHEADER_H */