| Bsoft 2.0.5 Bernard's software package

rwSPIDER.cpp
Go to the documentation of this file.
1
9 #include "utilities.h"
10 #include "file_util.h"
11 #include "rwSPIDER.h"
12
13 // Declaration of global variables
14 extern int verbose; // Level of output to the screen
15
16 extern char* month[];
17
18 View view_from_spider_euler(SPIDERhead* header)
19 {
20 if ( verbose & VERB_DEBUG )
21 cout << "DEBUG view_from_spider_euler: "
22 << header->gamma << "," << header->theta << "," << header->phi << endl;
23
24 View view;
25
26 view[0] = cos(header->phi)*sin(header->theta);
27 view[1] = sin(header->phi)*sin(header->theta);
28 view[2] = cos(header->theta);
29 view[3] = angle_set_negPI_to_PI(header->gamma + header->phi);
30
31 if ( verbose & VERB_DEBUG )
32 cout << "DEBUG view_from_spider_euler: " << view << endl;
33
34 return view;
35 }
36
37 int spider_euler_from_view(SPIDERhead* header, View view)
38 {
39 if ( verbose & VERB_DEBUG )
40 cout << "DEBUG spider_euler_from_view: " << view << endl;
41
42 if ( acos(view[2]) > 1e-14 )
43 header->phi = atan2(view[1], view[0]);
44 header->theta = acos(view[2]);
45 header->gamma = view[3] - header->phi;
46 header->gamma = angle_set_negPI_to_PI(header->gamma);
47
48 if ( verbose & VERB_DEBUG )
49 cout << "DEBUG spider_euler_from_view: "
50 << header->gamma << "," << header->theta << "," << header->phi << endl;
51
52 return 0;
53 }
54
82 int readSPIDER(Bimage* p, int readdata, int img_select)
83 {
84 ifstream* fimg = new ifstream(p->file_name());
85 if ( fimg->fail() ) return -1;
86
87 SPIDERhead* header = new SPIDERhead;
88
89 fimg->read((char *)header, SPIDERSIZE);
90 if ( fimg->fail() ) return -2;
91
92 if ( verbose & VERB_DEBUG ) {
93 cout << "DEBUG readSPIDER: Spider header size = " << sizeof(SPIDERhead) << endl;
94 cout << "DEBUG readSPIDER: iform=" << header->iform << endl;
95 }
96
97 // Determine byte order and swap bytes if from different-endian machine
98 unsigned char* b = (unsigned char *) header;
99 int i, j, sb = 0;
100 int extent = SPIDERSIZE - 180; // exclude char bytes from swapping
101 if ( ( fabs(header->nslice) > SWAPTRIG ) || ( fabs(header->iform) > SWAPTRIG ) ||
102 ( fabs(header->nslice) < 1 ) ) {
103 if ( verbose & VERB_PROCESS )
104 cerr << "Warning: Swapping header byte order for 4-byte types" << endl;
105 sb = 1;
106 for ( i=0; i<extent; i+=4 ) swapbytes(b+i, 4);
107 }
108
109 if ( verbose & VERB_DEBUG )
110 cout << "DEBUG readSPIDER: nsam=" << header->nsam << " nrow=" << header->nrow
111 << " nslice=" << header->nslice << " istack=" << header->istack << endl;
112
113 // Map the parameters
114 p->size((long) header->nsam, (long) header->nrow, (long) header->nslice);
115 p->channels(1);
116 p->data_type(Float);
117
118 long xstore = p->sizeX();
119 if ( header->iform < 0 ) {
120 p->compound_type(TComplex);
121 p->channels(2);
122 xstore = (int) header->nsam/2;
123 if ( header->iform > -20 ) {
124 p->sizeX(p->sizeX() + (int) (10 + header->iform)); // 2D Fourier transform
125 } else {
126 p->sizeX(p->sizeX() + (int) (20 + header->iform)); // 3D Fourier transform
127 }
128 }
129
130 long nimg(1);
131 if ( header->istack > 0 ) nimg = header->maxim;
132
133 long imgstart(0);
134 long imgend(nimg - 1);
135 unsigned char* hend;
136
137 if ( img_select > -1 ) {
138 if ( img_select >= nimg ) img_select = nimg - 1;
139 imgstart = img_select;
140 imgend = img_select;
141 nimg = 1;
142 }
143
144 p->images(nimg);
145
146 p->page_size(p->size());
147 p->data_offset((long) header->labbyt);
148 p->minimum(header->fmin);
149 p->maximum(header->fmax);
150 p->average(header->av);
151 p->standard_deviation(header->sig);
152 p->sampling(header->scale, header->scale, header->scale);
153
154 tm* t = p->get_localtime();
155 sscanf(header->ctim, "%d:%d:%d", &t->tm_hour, &t->tm_min, &t->tm_sec);
156 sscanf(header->cdat, "%d", &t->tm_mday);
157 for ( i=0; i<12 && strncmp(&(header->cdat[3]),month[i],3); i++ ) ;
158 if ( i < 12 ) t->tm_mon = i;
159 sscanf(&(header->cdat[7]), "%d", &t->tm_year);
160 if ( t->tm_year < 70 ) t->tm_year += 100;
161 p->set_time(t);
162
163 p->label(header->ctit);
164
165 long header_size = p->data_offset();
166 long image_size = header_size + p->channels()*xstore*p->sizeY()*p->sizeZ()*p->data_type_size();
167
168 if ( verbose & VERB_DEBUG )
169 cout << "DEBUG readSPIDER: header_size=" << header_size << " image_size=" << image_size << endl;
170
171
172 p->origin(header->xoff, header->yoff, header->zoff);
173 p->image->minimum(header->fmin);
174 p->image->maximum(header->fmax);
175 p->image->average(header->av);
176 p->image->standard_deviation(header->sig);
177 p->image->view(view_from_spider_euler(header));
178
179 if ( verbose & VERB_DEBUG )
180 cout << "DEBUG readSPIDER: imgstart=" << imgstart << " imgend=" << imgend << endl;
181
182 if ( header->istack > 0 ) {
183 p->data_offset(p->data_offset() + header_size);
184 for ( i=imgstart, j=0; i<=imgend; i++, j++ ) {
185 fimg->seekg(header_size + i*image_size, ios::beg);
186 fimg->read((char *)header, SPIDERSIZE);
187 if ( fimg->fail() ) {
188 cerr << "Error: Reading image " << i+1 << " header failed!" << endl;
189 fimg->close();
190 delete fimg;
191 return -3;
192 }
193 hend = (unsigned char *) header + extent;
194 if ( sb ) for ( b = (unsigned char *) header; b<hend; b+=4 ) swapbytes(b, 4);
195 p->image[j].minimum(header->fmin);
196 p->image[j].maximum(header->fmax);
197 p->image[j].average(header->av);
198 p->image[j].standard_deviation(header->sig);
199 p->image[j].origin(header->xoff, header->yoff, header->zoff);
200 p->image[j].view(view_from_spider_euler(header));
201 }
202 }
203
204 delete header;
205
206 if ( verbose & VERB_DEBUG )
207 cout << "DEBUG readSPIDER: offset=" << p->data_offset() << endl;
208
209 long pagesize = p->channels()*xstore*p->sizeY()*p->sizeZ()*p->data_type_size();
210 long offset(p->data_offset() + imgstart*image_size);
211 unsigned char* data = NULL;
212
213 if ( readdata ) {
214 p->data_alloc();
215 if ( p->compound_type() == TSimple ) {
216 for ( i=imgstart, data=p->data_pointer(); i<=imgend; i++, data+=pagesize, offset+=image_size ) {
217 fread_large(data, pagesize, offset, fimg);
218 }
219 if ( sb ) swapbytes(p->alloc_size(), p->data_pointer(), p->data_type_size());
220 } else {
221 data = new unsigned char[pagesize];
222 for ( i=imgstart; i<=imgend; i++, offset+=image_size ) {
223 fread_large(data, pagesize, offset, fimg);
224 if ( sb ) swapbytes(pagesize, data, p->data_type_size());
225 p->unpack_transform(i-imgstart, data, Hermitian);
226 }
227 delete[] data;
228 }
229 }
230
231 fimg->close();
232 delete fimg;
233
234 return 0;
235 }
236
243 int writeSPIDER(Bimage* p)
244 {
245 p->color_to_simple();
246 p->change_type(Float);
247
248 if ( verbose & VERB_DEBUG )
249 cout << "DEBUG writeSPIDER: Writing Spider file" << endl;
250
251 float lenbyt = sizeof(float)*p->sizeX(); // Record length (in bytes)
252 float labrec = floor(SPIDERSIZE/lenbyt); // # header records
253 if ( fmod(SPIDERSIZE,lenbyt) != 0 ) labrec++;
254 float labbyt = labrec*lenbyt; // Size of header in bytes
255 p->data_offset((long) labbyt);
256
257 if ( verbose & VERB_DEBUG ) {
258 cout << "DEBUG writeSPIDER: Header size=" << sizeof(SPIDERhead) << " labbyt=" << labbyt << endl;
259 cout << "DEBUG writeSPIDER: labrec=" << labrec << " lenbyt=" << lenbyt << endl;
260 }
261
262 char* buf = new char[p->data_offset()];
263 SPIDERhead* header = (SPIDERhead *) buf;
264 memset(buf, 0, p->data_offset());
265
266 // Map the parameters
267 header->lenbyt = lenbyt; // Record length (in bytes)
268 header->labrec = labrec; // # header records
269 header->labbyt = labbyt; // Size of header in bytes
270 header->irec = labrec + floor((p->sizeX()*p->sizeY()*p->sizeZ()*sizeof(float))/lenbyt + 0.999999); // Total # records
271 header->nsam = p->sizeX();
272 header->nrow = p->sizeY();
273 header->nslice = p->sizeZ();
274 header->scale = p->sampling()[0]; // Note this ignores any anisotropy
275
276 // If a transform, then the physical storage in x is only half+1
277 long xstore = p->sizeX();
278 if ( p->compound_type() == TComplex ) {
279 xstore = p->sizeX()/2 + 1;
280 header->nsam = 2*xstore;
281 }
282
283 if ( verbose & VERB_DEBUG )
284 cout << "DEBUG writeSPIDER: Size: " << header->nsam << "," << header->nrow << "," << header->nslice << endl;
285
286 if ( p->sizeZ() < 2 ) {
287 if ( p->compound_type() == TSimple )
288 header->iform = 1; // 2D image
289 else
290 header->iform = -12 + (int)p->sizeX()%2; // 2D Fourier transform
291 } else {
292 if ( p->compound_type() == TSimple )
293 header->iform = 3; // 3D volume
294 else
295 header->iform = -22 + (int)p->sizeX()%2; // 3D Fourier transform
296 }
297 header->istack = 0;
298 header->imami = 1;
299 header->fmin = p->minimum();
300 header->fmax = p->maximum();
301 header->av = p->average();
302 header->sig = p->standard_deviation();
303
304 // For multi-image files
305 if ( p->images() > 1 ) {
306 header->istack = 2;
307 header->inuse = -1;
308 header->maxim = p->images();
309 }
310
311 header->xoff = p->image->origin()[0];
312 header->yoff = p->image->origin()[1];
313 header->zoff = p->image->origin()[2];
314
315 spider_euler_from_view(header, p->image->view());
316
317 tm* t = p->get_localtime();
318 char astring[12];
319 while ( t->tm_year > 100 ) t->tm_year -= 100;
320 // snprintf(header->ctim, 8, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec);
321 snprintf(astring, 12, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec);
322 // cout << "number of characters = %ld\n", strlen(header->ctim));
323 strncpy(header->ctim, astring, 8);
324 snprintf(header->cdat, 12, "%02d-%3s-%02d", t->tm_mday, month[t->tm_mon], t->tm_year);
325 strncpy(header->ctit, p->label().c_str(), 160);
326
327 if ( verbose & VERB_DEBUG ) {
328 cout << "DEBUG writeSPIDER: Date and time: " << header->cdat << " " << header->ctim << endl;
329 cout << "DEBUG writeSPIDER: Text label: " << header->ctit << endl;
330 }
331
332 long n;
333 long datatypesize = p->channels()*p->data_type_size();
334 long datasize = xstore*p->sizeY()*p->sizeZ()*datatypesize;
335
336 if ( verbose & VERB_DEBUG ) {
337 cout << "DEBUG writeSPIDER: type size=" << datatypesize << " data size=" << datasize << " offset=" << p->data_offset() << endl;
338 cout << "DEBUG writeSPIDER: file name=" << p->file_name() << endl;
339 }
340
341 unsigned char* data = NULL;
342 unsigned char* aptr = p->data_pointer();
343 if ( p->compound_type() == TComplex ) data = new unsigned char[datasize];
344
345 ofstream fimg(p->file_name());
346 if ( fimg.fail() ) return -1;
347
348 if ( verbose & VERB_DEBUG )
349 cout << "DEBUG writeSPIDER: file " << p->file_name() << " opened" << endl;
350
351 fimg.write((char *)header, p->data_offset());
352
353 if ( verbose & VERB_DEBUG )
354 cout << "DEBUG writeSPIDER: File header written" << endl;
355
356 if ( p->images() == 1 ) {
357 if ( p->compound_type() < TComplex ) {
358 fimg.write((char *)p->data_pointer(), datasize);
359 } else {
360 p->pack_transform(data, Hermitian);
361 fimg.write((char *)data, datasize);
362 }
363 } else {
364 header->istack = 0;
365 header->inuse = 0;
366 header->maxim = 0;
367 for ( n=0; n<p->images(); n++ ) {
368 if ( verbose & VERB_DEBUG )
369 cout << "DEBUG writeSPIDER: Writing image number " << n << endl;
370 header->imgnum = n + 1;
371 header->fmin = p->image[n].minimum();
372 header->fmax = p->image[n].maximum();
373 header->av = p->image[n].average();
374 header->sig = p->image[n].standard_deviation();
375 header->xoff = p->image[n].origin()[0];
376 header->yoff = p->image[n].origin()[1];
377 header->zoff = p->image[n].origin()[2];
378 spider_euler_from_view(header, p->image[n].view());
379 fimg.write((char *)header, p->data_offset());
380 if ( p->compound_type() < TComplex ) {
381 fimg.write((char *)aptr, datasize);
382 } else {
383 p->pack_transform(n, data, Hermitian);
384 fimg.write((char *)data, datasize);
385 }
386 aptr += datasize;
387 }
388 }
389
390 fimg.close();
391
392 if ( verbose & VERB_DEBUG )
393 cout << "DEBUG writeSPIDER: File written" << endl;
394
395 if ( data ) delete[] data;
396
397 delete[] buf;
398
399 return 0;
400 }
401
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
SPIDERhead::nrow
float nrow
Definition: rwSPIDER.h:17
SWAPTRIG
#define SWAPTRIG
Definition: rwimg.h:16
Bsub_image::view
void view(double x, double y, double z, double a)
Definition: Bimage.h:143
SPIDERhead::ctit
char ctit[160]
Definition: rwSPIDER.h:54
SPIDERhead::maxim
float maxim
Definition: rwSPIDER.h:41
SPIDERhead::lenbyt
float lenbyt
Definition: rwSPIDER.h:38
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
spider_euler_from_view
int spider_euler_from_view(SPIDERhead *header, View view)
Definition: rwSPIDER.cpp:37
SPIDERhead::cdat
char cdat[12]
Definition: rwSPIDER.h:52
SPIDERhead::irec
float irec
Definition: rwSPIDER.h:18
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
SPIDERhead::zoff
float zoff
Definition: rwSPIDER.h:35
angle_set_negPI_to_PI
double angle_set_negPI_to_PI(double angle)
Returns an angle between -PI and PI.
Definition: utilities.cpp:594
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
SPIDERhead::phi
float phi
Definition: rwSPIDER.h:30
SPIDERhead::yoff
float yoff
Definition: rwSPIDER.h:34
SPIDERhead::imami
float imami
Definition: rwSPIDER.h:21
writeSPIDER
int writeSPIDER(Bimage *p)
Writing a SPIDER image file format. A 3D image format used in electron microscopy.
Definition: rwSPIDER.cpp:243
SPIDERhead::nsam
float nsam
Definition: rwSPIDER.h:27
SPIDERhead::scale
float scale
Definition: rwSPIDER.h:36
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
SPIDERhead::fmax
float fmax
Definition: rwSPIDER.h:22
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
TComplex
Definition: Bimage.h:59
SPIDERhead::labbyt
float labbyt
Definition: rwSPIDER.h:37
Bimage::pack_transform
int pack_transform(unsigned char *data, FourierType tf)
Definition: Bimage.cpp:2422
SPIDERhead::sig
float sig
Definition: rwSPIDER.h:25
readSPIDER
int readSPIDER(Bimage *p, int readdata, int img_select)
Reading a SPIDER image file format.
Definition: rwSPIDER.cpp:82
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
verbose
int verbose
Bimage::maximum
double maximum()
Definition: Bimage.h:535
Bimage::label
void label(string s)
Definition: Bimage.h:235
SPIDERhead::nslice
float nslice
Definition: rwSPIDER.h:16
Bimage::set_time
void set_time(time_t t)
Definition: Bimage.h:249
sb
int sb(0)
SPIDERSIZE
#define SPIDERSIZE
Definition: rwSPIDER.h:13
SPIDERhead::iform
float iform
Definition: rwSPIDER.h:20
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
file_util.h
Header file for file checking functions.
Bsub_image::maximum
double maximum()
Definition: Bimage.h:114
Bimage::data_offset
long data_offset()
Definition: Bimage.h:265
Bimage::get_localtime
tm * get_localtime()
Definition: Bimage.h:245
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bimage::channels
long channels()
Definition: Bimage.h:371
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
Bimage::standard_deviation
double standard_deviation()
Definition: Bimage.h:537
SPIDERhead::fmin
float fmin
Definition: rwSPIDER.h:23
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
rwSPIDER.h
Header file for reading and writing SPIDER files.
SPIDERhead
Definition: rwSPIDER.h:15
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
view_from_spider_euler
View view_from_spider_euler(SPIDERhead *header)
Definition: rwSPIDER.cpp:18
Bsub_image::minimum
double minimum()
Definition: Bimage.h:113
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
SPIDERhead::av
float av
Definition: rwSPIDER.h:24
Bimage::alloc_size
long alloc_size() const
Definition: Bimage.h:252
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
SPIDERhead::theta
float theta
Definition: rwSPIDER.h:31
month
char * month[]
Definition: rwimg.cpp:55
View
Definition: View.h: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
SPIDERhead::istack
float istack
Definition: rwSPIDER.h:39
Bimage::color_to_simple
void color_to_simple()
A color image is converted to a simple image.
Definition: Bimage_color.cpp:94
SPIDERhead::gamma
float gamma
Definition: rwSPIDER.h:32
Bsub_image::average
double average()
Definition: Bimage.h:115
SPIDERhead::ctim
char ctim[8]
Definition: rwSPIDER.h:53
Bimage::page_size
Vector3< long > page_size()
Definition: Bimage.h:480
Bimage::images
long images()
Definition: Bimage.h:491
SPIDERhead::inuse
float inuse
Definition: rwSPIDER.h:40
Hermitian
Definition: Bimage.h:43
SPIDERhead::xoff
float xoff
Definition: rwSPIDER.h:33
Bimage::sizeY
void sizeY(long ny)
Definition: Bimage.h:378
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
Bimage::minimum
double minimum()
Definition: Bimage.h:534
Bsub_image::standard_deviation
double standard_deviation()
Definition: Bimage.h:116
SPIDERhead::labrec
float labrec
Definition: rwSPIDER.h:28
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563