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