SYCL: Avoid using no_init read accessor in rocFFT
[alexxy/gromacs.git] / src / gromacs / fileio / mrcdensitymapheader.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
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.
8  *
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.
13  *
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.
18  *
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.
23  *
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.
31  *
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.
34  */
35 /*! \libinternal \file
36  * \brief
37  * Implement mrc/ccp4-file metadata.
38  *
39  * \author Christian Blau <cblau@gwdg.de>
40  *
41  * \inlibraryapi
42  * \ingroup module_fileio
43  */
44 #ifndef GMX_FILEIO_MRCDENSITYMAPHEADER_H
45 #define GMX_FILEIO_MRCDENSITYMAPHEADER_H
46
47 #include <array>
48 #include <vector>
49
50 #include "gromacs/math/coordinatetransformation.h"
51 #include "gromacs/math/vectypes.h"
52 #include "gromacs/mdspan/extensions.h"
53
54 namespace gmx
55 {
56
57 /*! \brief Space group in three dimensions.
58  *
59  * Currently only "no symmetry" is supported, the complete enum class would hold
60  * 230 symbols.
61  *
62  * Table 12.3.4.1 Standard space-group symbols, pages 824-831,
63  * International Tables for Crystallography, Volume A, fifth edition
64  */
65 enum class SpaceGroup : int32_t
66 {
67     P1 = 1, //!< no symmetry
68 };
69
70 /*! \brief The type of density data stored in an mrc file.
71  * As named in
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.
75  */
76 enum class MrcDataMode : int32_t
77 {
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)
83 };
84
85 /*! \libinternal
86  * \brief Statistics about mrc data arrays.
87  */
88 struct MrcDataStatistics
89 {
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
94 };
95
96 /*! \libinternal
97  * \brief Skew matrix and translation.
98  * As named in
99  * "EMDB Map Distribution Format Description Version 1.01 (c) emdatabank.org 2014"
100  */
101 struct MrcDensitySkewData
102 {
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
106 };
107
108 /*! \libinternal
109  * \brief Crystallographic labels for mrc data.
110  */
111 struct CrystallographicLabels
112 {
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;
116
117     //! Crystallographic labels or "::::EMDataBank.org::::EMD-1234::::" for EMDB entries
118     std::array<std::array<unsigned char, c_labelSize>, 10> labels_ = {};
119 };
120
121 /*! \libinternal
122  * \brief A container for the data in mrc density map file formats.
123  *
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.
126  *
127  * For a detailed description see
128  * "EMDB Map Distribution Format Description Version 1.01 (c) emdatabank.org 2014"
129  */
130 struct MrcDensityMapHeader
131 {
132
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_ = {};
141
142     //! Labels for crystallographic data
143     CrystallographicLabels labels_ = {};
144
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. } };
149
150     //! Data axis order with columns varying the fastest, and sections the slowest.
151     std::array<int32_t, DIM> columnRowSectionToXyz_ = { { 0, 1, 2 } };
152
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
156
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_ = {};
163 };
164
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
169  */
170 size_t numberOfExpectedDataItems(const MrcDensityMapHeader& header);
171
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.
176  *
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.
182  *
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
185  */
186 TranslateAndScale getCoordinateTransformationToLattice(const MrcDensityMapHeader& header);
187
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.
191  */
192 dynamicExtents3D getDynamicExtents3D(const MrcDensityMapHeader& header);
193
194 /*! \brief Checks if the values in the header are sane.
195  *
196  * Checks extents and numbers of columns, rows and sections, as well as unit
197  * cell angles for positivity and to be within bounds.
198  *
199  * Bounds are set generously not to hamper future creative uses of mrc files.
200  *
201  * \returns true if all header values are within resonable albeit generous bounds
202  */
203 bool mrcHeaderIsSane(const MrcDensityMapHeader& header);
204
205 } // namespace gmx
206 #endif /* end of include guard: GMX_FILEIO_MRCDENSITYMAPHEADER_H */