| Bsoft 2.0.5 Bernard's software package

rwCCP4.cpp
Go to the documentation of this file.
1
9 #include "rwCCP4.h"
10 #include "UnitCell.h"
11 #include "file_util.h"
12 #include "utilities.h"
13
14 #ifndef NOSYMOP
15 #include "rwsymop.h"
16 #endif
17
18 // Declaration of global variables
19 extern int verbose; // Level of output to the screen
20
34 int set_CCP4_machine_stamp(char* machine_stamp)
35 {
36 switch ( systype(0) ) {
37 case BigIEEE:
38 machine_stamp[0] = machine_stamp[1] = 17;
39 break;
40 case LittleIEEE:
41 machine_stamp[0] = 68;
42 machine_stamp[1] = 65;
43 break;
44 case LittleVAX:
45 machine_stamp[0] = 34;
46 machine_stamp[1] = 65;
47 break;
48 default:
49 break;
50 }
51
52 return 0;
53 }
54
81 int readCCP4(Bimage* p, int readdata)
82 {
83 ifstream* fimg = new ifstream(p->file_name());
84 if ( fimg->fail() ) return -1;
85
86 if ( verbose & VERB_DEBUG )
87 cout << "DEBUG readCCP4: File opened" << endl;
88
89 CCP4head* header = new CCP4head;
90
91 fimg->read((char *)header, CCP4SIZE);
92 if ( fimg->fail() ) return -2;
93
94 // Determine byte order and swap bytes if from little-endian machine
95 unsigned char* b = (unsigned char *) header;
96 long i, sb(0);
97 if ( abs(header->mode) > SWAPTRIG || abs(header->mapc) > SWAPTRIG ) {
98 if ( verbose & VERB_PROCESS )
99 cerr << "Warning: Swapping header byte order for 4-byte types" << endl;
100 sb = 1;
101 long extent = CCP4SIZE - 800; // exclude labels from swapping
102 for ( i=0; i<extent; i+=4 )
103 if ( i < 208 || i > 212 ) swapbytes(b+i, 4);
104 }
105
106 if ( header->nx < 1 || header->ny < 1 || header->nz < 1 || header->mode < 0 ) {
107 cerr << "Error readCCP4: The file " << p->file_name() << " is not a valid CCP4 image!" << endl;
108 fimg->close();
109 return -3;
110 }
111
112 // Convert VAX floating point types if necessary
113 // Machine stamp for vax is: 34 65 00 00
114 if ( ( header->machst[0] == 34 ) || ( header->amin > header->amax ) ) {
115 if ( verbose & VERB_PROCESS )
116 cerr << "Warning: Converting VAX floating point" << endl;
117 for ( i=40; i<64; i+=4 ) // Unit cell parameters
118 vax2ieee(b+i, sb);
119 for ( i=76; i<88; i+=4 ) // Min, max, mean
120 vax2ieee(b+i, sb);
121 for ( i=100; i<204; i+=4 ) // Skew matrix and extra
122 vax2ieee(b+i, sb);
123 vax2ieee(b+216, sb); // RMS
124 }
125
126 // Map the parameters
127 if ( strncmp(header->map, "STK ", 4) == 0 ) {
128 p->images(header->nz);
129 p->size(header->nx, header->ny, 1);
130 } else {
131 p->images(1);
132 p->size(header->nx, header->ny, header->nz);
133 }
134 p->channels(1);
135 switch ( header->mode ) {
136 case 0: p->data_type(SCharacter); break;
137 case 1: p->data_type(Short); break;
138 case 2: p->data_type(Float); break;
139 case 3: p->data_type(Short); p->compound_type(TComplex); p->channels(2); break;
140 case 4: p->data_type(Float); p->compound_type(TComplex); p->channels(2); break;
141 default: p->data_type(SCharacter); break;
142 }
143 p->data_offset(CCP4SIZE + header->nsymbt);
144 if ( header->mode > 2 ) {
145 fimg->seekg(0, ios::end);
146 if ( (double) fimg->tellg() > p->data_offset() + 0.8*p->alloc_size() )
147 p->sizeX(2*(p->sizeX() - 1));
148 if ( header->mx%2 == 1 ) p->sizeX(p->sizeX() + 1); // Quick fix for odd x-size maps
149 fimg->clear();
150 fimg->seekg(0, ios::beg);
151 }
152 p->minimum(header->amin);
153 p->maximum(header->amax);
154 p->average(header->amean);
155 p->standard_deviation(header->arms);
156
157 if ( header->mx && header->my && header->mz )
158 p->sampling(header->a/header->mx, header->b/header->my, header->c/header->mz);
159 p->space_group(header->ispg);
160 UnitCell uc(header->a, header->b, header->c, header->alpha, header->beta, header->gamma);
161 uc.degrees_to_radians();
162 p->unit_cell(uc);
163 p->label(header->labels);
164
165 // Allocating the single sub-image and setting its origin
166 p->origin(-header->nxStart, -header->nyStart, -header->nzStart);
167
168 delete header;
169
170 if ( verbose & VERB_DEBUG )
171 cout << "DEBUG rwCCP4: Header setup done" << endl;
172
173 long readsize = p->alloc_size();
174 unsigned char* data = NULL;
175
176 if ( readdata ) {
177 p->data_alloc();
178 if ( p->compound_type() == TSimple ) {
179 fread_large(p->data_pointer(), readsize, p->data_offset(), fimg);
180 if ( sb ) swapbytes(readsize, p->data_pointer(), p->data_type_size());
181 } else {
182 readsize = p->channels()*(p->sizeX()/2+1)*p->sizeY()*p->sizeZ()*p->data_type_size();
183 data = new unsigned char[readsize];
184 fread_large(data, readsize, p->data_offset(), fimg);
185 if ( sb ) swapbytes(readsize, data, p->data_type_size());
186 // img_unpack_transform(p, data, CentHerm);
187 p->unpack_transform(data, CentHerm);
188 delete[] data;
189 }
190 }
191
192 fimg->close();
193 delete fimg;
194
195 if ( verbose & VERB_DEBUG )
196 cout << "DEBUG rwCCP4: Data read" << endl;
197
198 return 0;
199 }
200
207 int writeCCP4(Bimage* p)
208 {
209 if ( verbose & VERB_DEBUG )
210 cout << "DEBUG rwCCP4: Writing CCP4 file" << endl;
211
212 p->color_to_simple();
213
214 // if ( p->compound_type() == TComplex ) p->change_type(Float);
215
216 switch ( p->data_type() ) {
217 case Bit: case UCharacter: case SCharacter:
218 if ( p->compound_type() == TComplex ) p->change_type(Short);
219 else p->change_type(SCharacter); break;
220 case UShort: case Short:
221 p->change_type(Short); break;
222 default:
223 p->change_type(Float); break;
224 }
225
226 if ( verbose & VERB_DEBUG )
227 cout << "DEBUG rwCCP4: data type = " << p->data_type() << endl;
228
229 CCP4head* header = new CCP4head;
230 memset(header, 0, sizeof(CCP4head));
231
232 UnitCell uc = p->unit_cell();
233
234 // Map the parameters
235 set_CCP4_machine_stamp(header->machst);
236 header->nx = p->sizeX();
237 header->ny = p->sizeY();
238 if ( p->sizeZ() > 1 || p->images() == 1 ) {
239 strncpy(header->map, "MAP ", 4);
240 header->nz = p->sizeZ();
241 } else {
242 strncpy(header->map, "STK ", 4);
243 header->nz = p->images();
244 }
245 if ( p->compound_type() == TComplex ) header->nx = p->sizeX()/2 + 1; // If a transform, physical storage is nx/2 + 1
246 switch ( p->data_type() ) {
247 case SCharacter: header->mode = 0; break;
248 case Short: header->mode = 1; if ( p->compound_type() == TComplex ) header->mode = 3; break;
249 case Float: header->mode = 2; if ( p->compound_type() == TComplex ) header->mode = 4; break;
250 default: header->mode = 0; break;
251 }
252 if ( p->image->origin()[0] >= 0 )
253 header->nxStart = (int) -(p->image->origin()[0] + 0.5);
254 else
255 header->nxStart = (int) -(p->image->origin()[0] - 0.5);
256 if ( p->image->origin()[1] >= 0 )
257 header->nyStart = (int) -(p->image->origin()[1] + 0.5);
258 else
259 header->nyStart = (int) -(p->image->origin()[1] - 0.5);
260 if ( p->image->origin()[2] >= 0 )
261 header->nzStart = (int) -(p->image->origin()[2] + 0.5);
262 else
263 header->nzStart = (int) -(p->image->origin()[2] - 0.5);
264 header->mx = (int) (uc.a()/p->sampling()[0] + 0.5);
265 header->my = (int) (uc.b()/p->sampling()[1] + 0.5);
266 header->mz = (int) (uc.c()/p->sampling()[2] + 0.5);
267 header->mapc = 1;
268 header->mapr = 2;
269 header->maps = 3;
270 header->amin = p->minimum();
271 header->amax = p->maximum();
272 header->amean = p->average();
273 header->arms = p->standard_deviation();
274 // cout << "Unitcell %g %g %g\n", uc.a(), uc.b(), uc.c());
275 header->a = uc.a();
276 header->b = uc.b();
277 header->c = uc.c();
278
279 // This is a band-aid to overcome the limitations of the image format
280 if ( fabs(header->a - p->sampling()[0]*header->mx) > 0.001 || fabs(header->b - p->sampling()[1]*header->my) > 0.001 ||
281 fabs(header->c - p->sampling()[2]*header->mz) > 0.001 ) {
282 header->a = p->sampling()[0]*header->mx;
283 header->b = p->sampling()[1]*header->my;
284 header->c = p->sampling()[2]*header->mz;
285 if ( verbose & VERB_FULL )
286 cerr << "Warning: Resetting the unit cell to: " << header->a << "," << header->b << "," << header->c << endl;
287 }
288
289 long i,j,k;
290 Matrix3 frac_mat = uc.skew_matrix();
291 header->alpha = uc.alpha()*180/M_PI;
292 header->beta = uc.beta()*180/M_PI;
293 header->gamma = uc.gamma()*180/M_PI;
294 for ( i=k=0; i<3; i++ ) for ( j=0; j<3; j++, k++ ) header->skwmat[k] = frac_mat[i][j];
295 // for ( i=0; i<3; i++ ) header->skwtrn[i] = frac_mat[i+9];
296 header->ispg = p->space_group();
297
298 if ( verbose & VERB_DEBUG )
299 cout << "DEBUG rwCCP4: Writing labels" << endl;
300
301 header->nlabl = 10;
302 strncpy(header->labels, p->label().c_str(), 799);
303 header->labels[799] = 0;
304
305 if ( verbose & VERB_DEBUG ) {
306 cout << "DEBUG rwCCP4: nlabl = " << header->nlabl << endl;
307 for ( i=0; i<header->nlabl; i++ )
308 if ( header->labels[i*80] ) cout << &header->labels[i*80] << endl;
309 }
310
311 int nsym(0);
312 Bstring temp;
313 char* symop = NULL;
314
315 #ifndef NOSYMOP
316 if ( p->space_group() > 0 ) symop = read_symop(temp, p->space_group(), nsym);
317 #endif
318
319 header->nsymbt = nsym*80;
320
321 if ( verbose & VERB_DEBUG )
322 cout << "DEBUG rwCCP4: nsymbt = " << header->nsymbt << endl;
323
324 p->data_offset(CCP4SIZE + header->nsymbt);
325
326 long datatypesize = p->channels()*p->data_type_size();
327 long datasize = (long)header->nx*header->ny*header->nz*datatypesize;
328
329 if ( verbose & VERB_DEBUG )
330 cout << "DEBUG rwCCP4: offset=" << p->data_offset() << " typesize=" << datatypesize << " datasize=" << datasize << endl;
331
332 unsigned char* data = NULL;
333
334 ofstream fimg(p->file_name());
335 if ( fimg.fail() ) return -1;
336
337 fimg.write((char *)header, CCP4SIZE);
338
339 if ( header->nsymbt ) fimg.write((char *)symop, header->nsymbt);
340
341 if ( p->data_pointer() ) {
342 if ( p->compound_type() < TComplex ) {
343 fimg.write((char *)p->data_pointer(), datasize);
344 } else {
345 data = new unsigned char[datasize];
346 p->pack_transform(data, CentHerm);
347 fimg.write((char *)data, datasize);
348 delete[] data;
349 }
350 }
351
352 fimg.close();
353
354 if ( symop ) delete[] symop;
355 delete header;
356
357 if ( verbose & VERB_DEBUG )
358 cout << "DEBUG rwCCP4: Done writing" << endl;
359
360 return 0;
361 }
362
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
SWAPTRIG
#define SWAPTRIG
Definition: rwimg.h:16
CCP4head::nx
int nx
Definition: rwCCP4.h:16
UnitCell
Definition: UnitCell.h:22
CCP4head::mz
int mz
Definition: rwCCP4.h:25
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
LittleIEEE
Definition: utilities.h:131
BigIEEE
Definition: utilities.h:129
UnitCell::gamma
void gamma(double d)
Definition: UnitCell.h:41
Bimage::data_type_size
long data_type_size() const
Returns the size of the datatype in bytes.
Definition: Bimage.cpp:1585
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
CCP4head::ny
int ny
Definition: rwCCP4.h:17
UnitCell::beta
void beta(double d)
Definition: UnitCell.h:40
CCP4head::nlabl
int nlabl
Definition: rwCCP4.h:47
LittleVAX
Definition: utilities.h:133
Matrix3
Definition: Matrix3.h:17
rwsymop.h
Header file for reading and writing symmetry operators.
CCP4SIZE
#define CCP4SIZE
Definition: rwCCP4.h:13
CCP4head::maps
int maps
Definition: rwCCP4.h:34
SCharacter
Definition: utilities.h:150
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
UnitCell::a
void a(double d)
Definition: UnitCell.h:36
readCCP4
int readCCP4(Bimage *p, int readdata)
Reading a CCP4 map image file format.
Definition: rwCCP4.cpp:81
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
TComplex
Definition: Bimage.h:59
CCP4head::arms
float arms
Definition: rwCCP4.h:46
Bimage::pack_transform
int pack_transform(unsigned char *data, FourierType tf)
Definition: Bimage.cpp:2422
CCP4head::alpha
float alpha
Definition: rwCCP4.h:29
CCP4head::labels
char labels[800]
Definition: rwCCP4.h:48
CCP4head::mode
int mode
Definition: rwCCP4.h:19
CCP4head::skwmat
float skwmat[9]
Definition: rwCCP4.h:41
TSimple
Definition: Bimage.h:58
Float
Definition: utilities.h:157
Bimage
General image parameter class.
Definition: Bimage.h:163
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:256
M_PI
#define M_PI
Definition: utilities.h:59
Bimage::maximum
double maximum()
Definition: Bimage.h:535
CCP4head
Definition: rwCCP4.h:15
CentHerm
Definition: Bimage.h:44
Bimage::label
void label(string s)
Definition: Bimage.h:235
vax2ieee
void vax2ieee(unsigned char *v, int sb)
Converts VAX floating point format to IEEE floating point format.
Definition: utilities.cpp:548
rwCCP4.h
Header file for reading and writing CCP4 files.
CCP4head::nz
int nz
Definition: rwCCP4.h:18
CCP4head::gamma
float gamma
Definition: rwCCP4.h:31
CCP4head::nzStart
int nzStart
Definition: rwCCP4.h:22
Bimage::unit_cell
void unit_cell(UnitCell uc)
Definition: Bimage.h:601
UnitCell::b
void b(double d)
Definition: UnitCell.h:37
sb
int sb(0)
CCP4head::mx
int mx
Definition: rwCCP4.h:23
CCP4head::mapr
int mapr
Definition: rwCCP4.h:33
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
CCP4head::nxStart
int nxStart
Definition: rwCCP4.h:20
file_util.h
Header file for file checking functions.
Bimage::data_offset
long data_offset()
Definition: Bimage.h:265
CCP4head::amax
float amax
Definition: rwCCP4.h:36
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
CCP4head::mapc
int mapc
Definition: rwCCP4.h:32
Bimage::channels
long channels()
Definition: Bimage.h:371
CCP4head::c
float c
Definition: rwCCP4.h:28
swapbytes
void swapbytes(unsigned char *v, size_t n)
Swaps bytes.
Definition: utilities.cpp:504
Bimage::unpack_transform
int unpack_transform(unsigned char *data, FourierType tf)
Definition: Bimage.cpp:2337
CCP4head::amean
float amean
Definition: rwCCP4.h:37
Bimage::standard_deviation
double standard_deviation()
Definition: Bimage.h:537
Bimage::space_group
long space_group()
Definition: Bimage.h:591
CCP4head::b
float b
Definition: rwCCP4.h:27
CCP4head::amin
float amin
Definition: rwCCP4.h:35
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
UnitCell::alpha
void alpha(double d)
Definition: UnitCell.h:39
CCP4head::nsymbt
int nsymbt
Definition: rwCCP4.h:39
UCharacter
Definition: utilities.h:149
Bstring
Definition: Bstring.h:29
CCP4head::beta
float beta
Definition: rwCCP4.h:30
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
CCP4head::map
char map[4]
Definition: rwCCP4.h:44
Bit
Definition: utilities.h:148
UnitCell::degrees_to_radians
void degrees_to_radians()
Definition: UnitCell.h:54
CCP4head::nyStart
int nyStart
Definition: rwCCP4.h:21
CCP4head::machst
char machst[4]
Definition: rwCCP4.h:45
fread_large
int fread_large(unsigned char *aptr, size_t pagesize, size_t offset, ifstream *fimg)
Reads blocks of memeory no larger than 1Gb.
Definition: file_util.cpp:347
UnitCell.h
Header file for unit cell functions.
Bimage::alloc_size
long alloc_size() const
Definition: Bimage.h:252
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
CCP4head::my
int my
Definition: rwCCP4.h:24
UnitCell::skew_matrix
Matrix3 skew_matrix()
Calculates the skew matrix from the unit cell parameters.
Definition: UnitCell.cpp:26
Bimage::average
double average(long cc, double xf, double yf, double zf, long nn, double iscale)
Averages in 3D when scaling is less than 1.
Definition: Bimage.cpp:1349
Bimage::color_to_simple
void color_to_simple()
A color image is converted to a simple image.
Definition: Bimage_color.cpp:94
Short
Definition: utilities.h:152
read_symop
char * read_symop(Bstring &filename, int spacegroup, int &nsym)
Reading crystallographic symmetry operators.
Definition: rwsymop.cpp:59
UShort
Definition: utilities.h:151
Bimage::images
long images()
Definition: Bimage.h:491
CCP4head::ispg
int ispg
Definition: rwCCP4.h:38
set_CCP4_machine_stamp
int set_CCP4_machine_stamp(char *machine_stamp)
Setting a CCP4 style machine stamp.
Definition: rwCCP4.cpp:34
systype
SysType systype(int show)
Finds the system type - mostly just for byte order.
Definition: utilities.cpp:144
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::sizeY
void sizeY(long ny)
Definition: Bimage.h:378
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
verbose
int verbose
Bimage::minimum
double minimum()
Definition: Bimage.h:534
UnitCell::c
void c(double d)
Definition: UnitCell.h:38
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
writeCCP4
int writeCCP4(Bimage *p)
Writing a CCP4 map image file format.
Definition: rwCCP4.cpp:207
CCP4head::a
float a
Definition: rwCCP4.h:26