1 /*
2      cmap_accessor.c: get and set map header information
3      Copyright (C) 2001  CCLRC, Charles Ballard
4 
5      This library is free software: you can redistribute it and/or
6      modify it under the terms of the GNU Lesser General Public License
7      version 3, modified in accordance with the provisions of the
8      license to address the requirements of UK law.
9 
10      You should have received a copy of the modified GNU Lesser General
11      Public License along with this library.  If not, copies may be
12      downloaded from http://www.ccp4.ac.uk/ccp4license.php
13 
14      This program 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
17      GNU Lesser General Public License for more details.
18 */
19 #include <math.h>
20 #include "cmaplib.h"
21 #include "cmap_errno.h"
22 
23 /* accessors */
24 
25 /*! Get the cell parameters
26  \param mfile (const CMMFile *)
27  \param cell (float *) contains the cell parameter on exit (dim 6) */
ccp4_cmap_get_cell(const CMMFile * mfile,float * cell)28 void ccp4_cmap_get_cell(const CMMFile *mfile, float *cell)
29 {
30   cell[0] = mfile->cell[0];
31   cell[1] = mfile->cell[1];
32   cell[2] = mfile->cell[2];
33   cell[3] = mfile->cell[3];
34   cell[4] = mfile->cell[4];
35   cell[5] = mfile->cell[5];
36 }
37 
38 /*! Set the cell parameters.
39   Only allowed when file is opened in write mode.
40  \param mfile (CMMFile *)
41  \param cell (const float *) the cell parameters */
ccp4_cmap_set_cell(CMMFile * mfile,const float * cell)42 void ccp4_cmap_set_cell(CMMFile *mfile, const float *cell)
43 {
44   if (ccp4_file_is_write(mfile->stream)) {
45     mfile->cell[0] = cell[0];
46     mfile->cell[1] = cell[1];
47     mfile->cell[2] = cell[2];
48     mfile->cell[3] = cell[3];
49     mfile->cell[4] = cell[4];
50     mfile->cell[5] = cell[5];
51   }
52 }
53 
54 /*! Get the grid for the complete cell (X,Y,Z) ordering
55  \param mfile (const CMMFile *)
56  \param grid (int *) contains the grid dimension on exit (dim 3) */
ccp4_cmap_get_grid(const CMMFile * mfile,int * grid)57 void ccp4_cmap_get_grid(const CMMFile *mfile, int *grid)
58 {
59   grid[0] = mfile->cell_grid[0];
60   grid[1] = mfile->cell_grid[1];
61   grid[2] = mfile->cell_grid[2];
62 }
63 
64 /*! Set the cell grid dimension.
65   Only allowed when file is opened in write mode.
66  \param mfile (CMMFile *)
67  \param grid (const int *) the cell grid dimension (X,Y,Z) */
ccp4_cmap_set_grid(CMMFile * mfile,const int * grid)68 void ccp4_cmap_set_grid(CMMFile *mfile, const int *grid)
69 {
70   if (ccp4_file_is_write(mfile->stream)) {
71     mfile->cell_grid[0] = grid[0];
72     mfile->cell_grid[1] = grid[1];
73     mfile->cell_grid[2] = grid[2];
74   }
75 }
76 
77 /*! Get the stored map origin (rows,sections,columns)
78  \param mfile (const CMMFile *)
79  \param origin (int *) contains the origin on exit (dim 3) */
ccp4_cmap_get_origin(const CMMFile * mfile,int * origin)80 void ccp4_cmap_get_origin(const CMMFile *mfile, int *origin)
81 {
82   origin[0] = mfile->origin[0];
83   origin[1] = mfile->origin[1];
84   origin[2] = mfile->origin[2];
85 }
86 
87 /*! Set the stored map origin (rows,sections,columns)
88   Only allowed when file is opened in write mode.
89  \param mfile (CMMFile *)
90  \param origin (const int *) the origin */
ccp4_cmap_set_origin(CMMFile * mfile,const int * origin)91 void ccp4_cmap_set_origin(CMMFile *mfile, const int *origin)
92 {
93   if (ccp4_file_is_write(mfile->stream)) {
94     mfile->origin[0] = origin[0];
95     mfile->origin[1] = origin[1];
96     mfile->origin[2] = origin[2];
97   }
98 }
99 
100 /*! Get the stored map axes order (rows,sections,columns)
101  where 1=X, 2=Y, 3=Z
102  \param mfile (const CMMFile *)
103  \param axes_order (float *) contains the ordering on exit (dim 3) */
ccp4_cmap_get_order(const CMMFile * mfile,int * axes_order)104 void ccp4_cmap_get_order(const CMMFile *mfile, int *axes_order)
105 {
106   axes_order[0] = mfile->axes_order[0];
107   axes_order[1] = mfile->axes_order[1];
108   axes_order[2] = mfile->axes_order[2];
109 }
110 
111 /*! Set the stored map axes order (rows,sections,columns)
112  where 1=X, 2=Y, 3=Z.
113  Only allowed when file is opened in write mode.
114  \param mfile (CMMFile *)
115  \param axes_order (const float *) the axes ordering */
ccp4_cmap_set_order(CMMFile * mfile,const int * axes_order)116 void ccp4_cmap_set_order(CMMFile *mfile, const int *axes_order)
117 {
118   if (ccp4_file_is_write(mfile->stream)) {
119     mfile->axes_order[0] = axes_order[0];
120     mfile->axes_order[1] = axes_order[1];
121     mfile->axes_order[2] = axes_order[2];
122   }
123 }
124 
125 /*! Get the stored map dimension (rows,sections,columns)
126  \param mfile (const CMMFile *)
127  \param map_dim (int *) contains the map dimension on exit (dim 3) */
ccp4_cmap_get_dim(const CMMFile * mfile,int * map_dim)128 void ccp4_cmap_get_dim(const CMMFile *mfile, int *map_dim)
129 {
130   map_dim[0] = mfile->map_dim[0];
131   map_dim[1] = mfile->map_dim[1];
132   map_dim[2] = mfile->map_dim[2];
133 }
134 
135 /*! Set the stored map dimension (rows,sections,columns)
136  Only allowed when file is opened in write mode before any data
137  is written.
138  Note: the row dimension will be overridden during writing
139  \param mfile (CMMFile *)
140  \param map_dim (const int *) the map dimension */
ccp4_cmap_set_dim(CMMFile * mfile,const int * map_dim)141 void ccp4_cmap_set_dim(CMMFile *mfile, const int *map_dim)
142 {
143   if (ccp4_file_is_write(mfile->stream) && !mfile->data.number) {
144     mfile->map_dim[0] = map_dim[0];
145     mfile->map_dim[1] = map_dim[1];
146     mfile->map_dim[2] = map_dim[2];
147     mfile->data.section_size = map_dim[0]*map_dim[1]*
148       ccp4_file_itemsize(mfile->stream);
149     mfile->data.block_size = mfile->data.section_size +
150                              mfile->data.header_size;
151   }
152 }
153 /*! Return the spacegroup listed in the map header.
154  This is overriden by the symops.
155  \param mfile (CMMFile *)
156  \return spacegroup number */
ccp4_cmap_get_spacegroup(const CMMFile * mfile)157 int ccp4_cmap_get_spacegroup(const CMMFile *mfile)
158 {
159   return mfile->spacegroup;
160 }
161 
162 /*! Set the spacegroup listed in the map header.
163  Only allowed when file is opened in write mode.
164  \param mfile (CMMFile *)
165  \param spacegroup (int) spacegroup number */
ccp4_cmap_set_spacegroup(CMMFile * mfile,int spacegroup)166 void ccp4_cmap_set_spacegroup(CMMFile *mfile, int spacegroup)
167 {
168   if (ccp4_file_is_write(mfile->stream))
169     mfile->spacegroup = spacegroup;
170 }
171 
172 /*! Return the datamode
173   \param mfile (const CMMFile *)
174   \return datamode */
ccp4_cmap_get_datamode(const CMMFile * mfile)175 unsigned int ccp4_cmap_get_datamode(const CMMFile *mfile)
176 {
177   return mfile->data_mode;
178 }
179 
180 /*! Set the datamode.
181   This is only allowed if the file is opened in write mode, and
182   no data has been written.
183   \param mfile (CMMFile *)
184   \param datamode (unsigned int) major mode of map */
ccp4_cmap_set_datamode(CMMFile * mfile,unsigned int datamode)185 void ccp4_cmap_set_datamode(CMMFile *mfile, unsigned int datamode)
186 {
187   if (ccp4_file_is_write(mfile->stream) && !mfile->data.number &&
188       datamode <= 6 && datamode != 5) {
189     mfile->data_mode = datamode;
190     ccp4_file_setmode(mfile->stream, datamode);
191     mfile->data.section_size = mfile->map_dim[0]*mfile->map_dim[1]*
192       ccp4_file_itemsize(mfile->stream);
193     mfile->data.block_size = mfile->data.section_size +
194                              mfile->data.header_size;
195   }
196 }
197 
198 /*! Get the map statistics, including maximum, minimum, mean and standard
199   deviation.  This is only meaningful for datamode FLOAT32.
200   \param mfile (const CMMFile *)
201   \param min (float *)
202   \param max (float *)
203   \param mean (double *)
204   \param rms (double *) */
ccp4_cmap_get_mapstats(const CMMFile * mfile,float * min,float * max,double * mean,double * rms)205 void ccp4_cmap_get_mapstats(const CMMFile *mfile, float *min, float* max,
206                            double *mean, double *rms)
207 {
208   double f1,f2,f3;
209   *min = mfile->stats.min;
210   *max = mfile->stats.max;
211   if (ccp4_file_is_write(mfile->stream)  && mfile->close_mode == 0) {
212     f1 = (mfile->stats.total != 0) ? mfile->stats.mean / mfile->stats.total : 0;
213     f2 = (mfile->stats.total != 0) ? mfile->stats.rms / mfile->stats.total : 0;
214     f3 = f2 - f1*f1;
215     *rms = (f3 > 0) ? sqrt(f3) : 0;
216     *mean = f1 - (double) mfile->stats.offset;
217   } else {
218     *mean = mfile->stats.mean;
219     *rms = mfile->stats.rms;
220   }
221 }
222 
223 /*! Set the map statistics, including maximum, minimum, mean and standard
224   deviation.  This is only meaningful for datamode FLOAT32 and the file
225   open in write mode.
226   \param mfile (CMMFile *)
227   \param min (float)
228   \param max (float)
229   \param mean (double)
230   \param rms (double) */
ccp4_cmap_set_mapstats(CMMFile * mfile,const float min,const float max,const double mean,const double rms)231 void ccp4_cmap_set_mapstats(CMMFile *mfile, const float min, const float max,
232                            const double mean, const double rms)
233 {
234   if (ccp4_file_is_write(mfile->stream)) {
235     mfile->stats.min = min;
236     mfile->stats.max = max;
237     mfile->stats.mean = mean;
238     mfile->stats.rms = rms;
239   }
240 }
241 
242 /*! Set the local header size (in bytes)
243   \param mfile (CMMFile *)
244   \param size (size_t) header size associated with each section (in bytes) */
ccp4_cmap_set_local_header(CMMFile * mfile,size_t size)245 void ccp4_cmap_set_local_header(CMMFile *mfile, size_t size)
246 {
247   if (ccp4_file_is_write(mfile->stream) && mfile->data.number == 0) {
248     mfile->data.header_size = size;
249     mfile->data.block_size = mfile->data.section_size + mfile->data.header_size;
250   }
251   return;
252 }
253 
254 /*! Return the local header size
255  \param mfile (CMMFile *)
256  \return header size associated with each section (in bytes) */
ccp4_cmap_get_local_header(CMMFile * mfile)257 size_t ccp4_cmap_get_local_header(CMMFile *mfile)
258 {
259   return mfile->data.header_size;
260 }
261 
262