| Bsoft 2.0.5 Bernard's software package

molecule_to_map.cpp
Go to the documentation of this file.
1
9 #include "molecule_to_map.h"
10 #include "Complex.h"
11 #include "UnitCell.h"
12 #include "linked_list.h"
13 #include "utilities.h"
14 #include <fstream>
15
16 // Declaration of global variables
17 extern int verbose; // Level of output to the screen
18
19 // Constants
20 #define MAXSID 1024 // Maximum grid sidelength
21 #define MAXSCAT 100 // Maximum number of atomic scattering data points
22 #define MAXRAD 100 // Maximum radial points at 0.1 A/point for calculating atomic potential curves
23
24 // Internal function prototypes
25 int mol_to_image(Bmolgroup* molgroup, Bimage* p, Batomtype* atompar,
26 double resolution, double Bfactor, int wrap, int gextype);
27 int mol_to_structure_factors(Bmolgroup* molgroup, Bimage* p,
28 Batomtype* atompar, double resolution, int wrap, double Bfactor);
29
53 Bimage* img_from_molecule(Bmolgroup* molgroup, Vector3<double> origin,
54 Vector3<long> size, Vector3<double> sampling, double resolution, double Bfactor,
55 int wrap, int gextype, int spacegroup, UnitCell unit_cell)
56 {
57 Batomtype* atompar = NULL;
58 Bstring paramfile;
59 if ( gextype) atompar = get_atom_properties(paramfile);
60
61 if ( sampling.volume() < 1e-6 )
62 sampling[0] = sampling[1] = sampling[2] = 1;
63 else
64 sampling = sampling.max(0.01);
65
66 if ( resolution < sampling[0] ) resolution = sampling[0];
67 if ( resolution < 0.01 ) resolution = 2*sampling[0];
68
69 if ( size[0] < 1 ) size[0] = (long) ((molgroup->max[0] + 3*resolution)/sampling[0] + origin[0]);
70 if ( size[1] < 1 ) size[1] = (long) ((molgroup->max[1] + 3*resolution)/sampling[1] + origin[1]);
71 if ( size[2] < 1 ) size[2] = (long) ((molgroup->max[2] + 3*resolution)/sampling[2] + origin[2]);
72 size = size.min(MAXSID);
73 size = size.max(1);
74
75 if ( verbose & VERB_DEBUG )
76 cout << "DEBUG img_sf_from_molecule: size = " << size << endl;
77
78 Bimage* p = new Bimage(Float, TSimple, size, 1);
79 p->unit_cell(unit_cell);
80 p->origin(origin);
81 p->sampling(sampling);
82 p->space_group(spacegroup);
83
84 int side = (long) floor((3.0/2.0)*resolution/p->sampling()[0]+1);
85 if ( side > MAXSID ) side = MAXSID;
86
87 if ( verbose & VERB_PROCESS ) {
88 if ( gextype ) cout << "Calculating atomic potential:" << endl;
89 else cout << "Calculating density by simple gaussian expansion:" << endl;
90 cout << "Dimensions: " << p->size() << " voxels" << endl;
91 cout << "Origin: " << p->image->origin() << endl;
92 cout << "Sampling: " << p->sampling() << " A/voxel" << endl;
93 if ( !gextype )
94 cout << "Resolution: " << resolution << " A" << endl;
95 cout << "Global B-factor: " << Bfactor << " A2" << endl;
96 cout << "Wrap: " << wrap << endl;
97 } else if ( verbose & VERB_LABEL )
98 cout << "Calculating density" << endl << endl;
99
100 mol_to_image(molgroup, p, atompar, resolution, Bfactor, wrap, gextype);
101
102 if ( gextype) kill_list((char *) atompar, sizeof(Batomtype));
103
104 p->statistics();
105
106 return p;
107 }
108
109 /*
110 @brief Calculates a 3D density map from a set of atomic coordinates.
111 @param *molgroup set of molecules with atomic coordinates.
112 @param *p image structure for the new map.
113 @param *atompar atom type parameters.
114 @param resolution resolution (angstrom).
115 @param Bfactor global B-factor to use, if 0, use individual atom B-factors
116 @param wrap wrapping flag.
117 @param gextype type of gaussian used: 0 = single, 1 = atomic potential
118 @return int 0.
119
120 A 3D map is calculated from atomic coordinates by placing a gaussian
121 sphere at each set of atomic coordinates. The resolution is set as
122 twice the sigma coefficient of the gaussian function. The amplitude
123 of the gaussian function is set so that the total density calculated
124 equals the atomic mass. The resultant map therefore has the density
125 units of Dalton/voxel.
126 The content and statistics of the new image is not checked.
127
128 **/
129 int mol_to_image(Bmolgroup* molgroup, Bimage* p, Batomtype* atompar,
130 double resolution, double Bfactor, int wrap, int gextype)
131 {
132 long h, i, j, irad, nsig, t;
133 long x, y, z, ix, iy, iz;
134 Vector3<int> lo, hi;
135 Vector3<double> cgrid;
136 double sigma, sigma2, avgsig, dx, dy, dz, dist2;
137 double sigma2_global = resolution*resolution/4 + Bfactor/(8*M_PI*M_PI);
138 double interval = p->sizeX()*p->sampling()[0]*0.5/MAXRAD; // Sampling for radial potential curve calculations
139 if ( interval > 0.1 ) interval = 0.1;
140 double sam2 = p->sampling()[0]*p->sampling()[0];
141 double voxel_size = p->sampling().volume();
142 double thisamp, thisdens, thisatom, summass(0), totmass(0);
143 long side = (long) floor((3.0/2.0)*resolution/p->sampling()[0]+1);
144 if ( side > MAXSID ) side = MAXSID;
145 if ( gextype ) {
146 side = (long) (MAXRAD*interval/p->sampling()[0] - 1);
147 if ( side*p->sampling()[0] > 5 ) side = (long) (5/p->sampling()[0] + 1);
148 }
149 if ( side > p->sizeX() ) side = p->sizeX();
150 double radius2 = side*side*sam2;
151
152 if ( verbose & VERB_PROCESS )
153 cout << "Cube edge length: " << 2*side+1 << " voxels" << endl;
154
155 Bmolecule* mol;
156 Bresidue* res;
157 Batom* atom;
158
159 double* apot = NULL;
160 if ( atompar ) apot = get_potential_curves(atompar, interval);
161
162 nsig = 0;
163 avgsig = 0;
164 for ( h=0, mol = molgroup->mol; mol; mol = mol->next ) if ( mol->sel ) {
165 h++;
166 for( res = mol->res; res; res = res->next ) {
167 for ( atom = res->atom; atom; atom = atom->next ) {
168 cgrid[0] = atom->coord[0]/p->sampling()[0] + p->image->origin()[0];
169 cgrid[1] = atom->coord[1]/p->sampling()[1] + p->image->origin()[1];
170 cgrid[2] = atom->coord[2]/p->sampling()[2] + p->image->origin()[2];
171 lo[0] = (long) (cgrid[0] + 0.5 - side);
172 hi[0] = (long) (cgrid[0] + 0.5 + side);
173 lo[1] = (long) (cgrid[1] + 0.5 - side);
174 hi[1] = (long) (cgrid[1] + 0.5 + side);
175 lo[2] = (long) (cgrid[2] + 0.5 - side);
176 hi[2] = (long) (cgrid[2] + 0.5 + side);
177 if ( !wrap ) {
178 if ( lo[0] < 0 ) lo[0] = 0;
179 if ( lo[1] < 0 ) lo[1] = 0;
180 if ( lo[2] < 0 ) lo[2] = 0;
181 if ( hi[0] > (long)p->sizeX() - 1 ) hi[0] = p->sizeX() - 1;
182 if ( hi[1] > (long)p->sizeY() - 1 ) hi[1] = p->sizeY() - 1;
183 if ( hi[2] > (long)p->sizeZ() - 1 ) hi[2] = p->sizeZ() - 1;
184 }
185 if ( Bfactor > 0 ) sigma2 = sigma2_global;
186 else sigma2 = sigma2_global + atom->b/(8*M_PI*M_PI); // B-factors
187 if ( sigma2 < 0.01 ) sigma2 = 0.01;
188 sigma = sqrt(sigma2);
189 nsig++;
190 avgsig += sigma;
191 if ( verbose & VERB_DEBUG )
192 cout << atom->coord << " " << atom->type << " " << atom->mass << endl;
193 thisatom = 0;
194 thisamp = atom->mass*voxel_size/(sqrt(TWOPI*sigma2)*TWOPI*sigma2);
195 sigma2 = -1.0/(2.0*sigma2);
196 ix = (long) (cgrid[0] + 0.5);
197 iy = (long) (cgrid[1] + 0.5);
198 iz = (long) (cgrid[2] + 0.5);
199 i = p->index(0, ix, iy, iz, 0);
200 for ( z=lo[2]; z<=hi[2]; z++ ) {
201 dz = (cgrid[2] - z)*(cgrid[2] - z)*sam2;
202 for ( y=lo[1]; y<=hi[1]; y++ ) {
203 dy = (cgrid[1] - y)*(cgrid[1] - y)*sam2;
204 for ( x=lo[0]; x<=hi[0]; x++ ) {
205 dx = (cgrid[0] - x)*(cgrid[0] - x)*sam2;
206 dist2 = dx + dy + dz;
207 if ( dist2 <= radius2 ) {
208 ix = x;
209 iy = y;
210 iz = z;
211 if ( wrap ) {
212 while ( ix < 0 ) ix += p->sizeX(); /* This wraps the density */
213 while ( iy < 0 ) iy += p->sizeY();
214 while ( iz < 0 ) iz += p->sizeZ();
215 while ( ix >= p->sizeX() ) ix -= p->sizeX();
216 while ( iy >= p->sizeY() ) iy -= p->sizeY();
217 while ( iz >= p->sizeZ() ) iz -= p->sizeZ();
218 }
219 j = p->index(ix, iy, iz);
220 thisdens = 0;
221 if ( gextype ) {
222 t = atom->tnum;
223 if ( j == i ) {
224 thisdens = apot[t*MAXRAD];
225 } else {
226 irad = (long) (sqrt(dist2)/interval + 0.5);
227 if ( irad < MAXRAD ) thisdens = apot[t*MAXRAD+irad];
228 }
229 } else {
230 thisdens = thisamp*exp(dist2*sigma2);
231 }
232 p->add(j, thisdens);
233 thisatom += thisdens;
234 }
235 }
236 }
237 }
238 totmass += thisatom;
239 summass += atom->mass;
240 }
241 }
242 if ( verbose & VERB_TIME )
243 cout << "Molecules done: " << h+1 << "\r" << flush;
244 }
245
246 double scale = POTPREFAC;
247 if ( p->sizeX() > 1 ) scale *= p->sampling()[0];
248 if ( p->sizeY() > 1 ) scale *= p->sampling()[1];
249 if ( p->sizeZ() > 1 ) scale *= p->sampling()[2];
250
251 if ( gextype ) {
252 p->rescale(scale, 0);
253 totmass *= scale;
254 }
255
256 if ( verbose & VERB_PROCESS ) {
257 cout << "Average sigma: " << avgsig/nsig << " A" << endl;
258 cout << "Total mass (sum): " << summass << " Da" << endl;
259 cout << "Total mass (density): " << totmass << " Da" << endl;
260 cout << " Ratio: " << totmass/summass << endl;
261 cout << "Total volume: " << totmass/RHO << " A3" << endl << endl;
262 }
263
264 if ( apot ) delete[] apot;
265
266 return 0;
267 }
268
277 int compare_mol_map(Bmolgroup* molgroup, Bimage* pcalc, Bimage* p)
278 {
279 Bmolecule* mol;
280 Bresidue* res;
281 Batom* atom;
282
283 long j, natom(0);
284 long x, y, z;
285 double min = 1e30, max = -1e30, Qavg(0), Qsd(0);
286 double scale = (pcalc->maximum() - pcalc->minimum())/(p->maximum() - p->minimum());
287
288 for ( mol = molgroup->mol; mol; mol = mol->next ) {
289 for( res = mol->res; res; res = res->next ) {
290 for ( atom = res->atom; atom; atom = atom->next ) {
291 x = (long) floor(atom->coord[0]/pcalc->sampling()[0] + pcalc->image->origin()[0] + 0.5);
292 y = (long) floor(atom->coord[1]/pcalc->sampling()[1] + pcalc->image->origin()[1] + 0.5);
293 z = (long) floor(atom->coord[2]/pcalc->sampling()[2] + pcalc->image->origin()[2] + 0.5);
294 while ( x < 0 ) x += pcalc->sizeX();
295 while ( x >= pcalc->sizeX() ) x -= pcalc->sizeX();
296 while ( y < 0 ) y += pcalc->sizeY();
297 while ( y >= pcalc->sizeY() ) y -= pcalc->sizeY();
298 while ( z < 0 ) z += pcalc->sizeZ();
299 while ( z >= pcalc->sizeZ() ) z -= pcalc->sizeZ();
300 j = pcalc->index(x, y, z);
301 if ( (*pcalc)[j] ) atom->q = scale*(*p)[j]/(*pcalc)[j];
302 if ( atom->q > 1 ) atom->q = 1;
303 if ( min > atom->q ) min = atom->q;
304 if ( max < atom->q ) max = atom->q;
305 Qavg += atom->q;
306 Qsd += atom->q*atom->q;
307 atom->b = atom->q;
308 natom++;
309 }
310 }
311 }
312 Qavg /= natom;
313 Qsd = sqrt(Qsd/natom - Qavg*Qavg);
314
315 if ( verbose & VERB_PROCESS ) {
316 cout << "Comparison of molecule " << mol->id << " with map " << p->file_name() << endl;
317 cout << "Origin (original): " << p->image->origin() << endl;
318 cout << "Origin (calculated): " << pcalc->image->origin() << endl;
319 cout << "Scale: " << scale << endl;
320 cout << "Min & max: " << min << " " << max << endl;
321 cout << "Average and standard deviation: " << Qavg << " " << Qsd << endl << endl;
322 } else {
323 cout << "Comparison of molecule " << mol->id << " with map " << p->file_name() << endl;
324 cout << "Average and standard deviation: " << Qavg << " " << Qsd << endl << endl;
325 }
326
327 return 0;
328 }
329
355 Bimage* img_sf_from_molecule(Bmolgroup* molgroup,
356 Vector3<double> origin, Vector3<long> size, Vector3<double> sampling, double resolution,
357 int spacegroup, UnitCell unit_cell, int wrap, double Bfactor, Bstring& paramfile)
358 {
359 Batomtype* atompar = get_atom_properties(paramfile);
360
361 if ( sampling.volume() < 1e-6 )
362 sampling[0] = sampling[1] = sampling[2] = 1;
363 else
364 sampling = sampling.max(0.01);
365
366 if ( resolution < sampling[0] ) resolution = sampling[0];
367 if ( resolution < 0.01 ) resolution = 2*sampling[0];
368
369 if ( size[0] < 1 ) size[0] = (long) ((molgroup->max[0] - molgroup->min[0])/sampling[0]);
370 if ( size[1] < 1 ) size[1] = (long) ((molgroup->max[1] - molgroup->min[1])/sampling[1]);
371 if ( size[2] < 1 ) size[2] = (long) ((molgroup->max[2] - molgroup->min[2])/sampling[2]);
372 size = size.min(MAXSID);
373 size = size.max(1);
374
375 if ( verbose & VERB_DEBUG )
376 cout << "DEBUG img_sf_from_molecule: size = " << size << endl;
377
378 Bimage* p = new Bimage(Float, TComplex, size, 1);
379 p->unit_cell(unit_cell);
380 p->origin(origin);
381 p->sampling(sampling);
382 p->fourier_type(Standard);
383 p->space_group(spacegroup);
384
385 double smax = 2.0/p->real_size().length();
386 if ( resolution > 0.01 ) smax = 1.0/resolution;
387
388 if ( ( verbose & VERB_LABEL ) || ( verbose & VERB_PROCESS ) )
389 cout << "Calculating structure factors from atomic coordinates" << endl;
390
391 if ( verbose & VERB_PROCESS ) {
392 cout << "Size: " << p->size() << " voxels" << endl;
393 cout << "Origin: " << p->image->origin() << endl;
394 cout << "Sampling: " << p->sampling() << " A/voxel" << endl;
395 cout << "Resolution: " << resolution << " A" << endl;
396 cout << "Reciprocal resolution: " << smax << " /A" << endl;
397 }
398
399 mol_to_structure_factors(molgroup, p, atompar, resolution, wrap, Bfactor);
400
401 atom_type_kill(atompar);
402
403 p->statistics();
404
405 return p;
406 }
407
408 double one_sf(Bmolgroup* molgroup, Bimage* p, long i, double s, double scale, double* scat)
409 {
410 if ( s <= 0 ) return 0;
411
412 long x, y, z;
413 long h, k, l, t, si;
414 double fraction, fraction1, f, phi;
415 Bmolecule* mol;
416 Bresidue* res;
417 Batom* atom;
418 Complex<float> temp;
419
420 p->coordinates(i, x, y, z);
421 if ( x < (p->sizeX() + 1)/2 ) h = x; else h = (long)x - p->sizeX();
422 if ( y < (p->sizeY() + 1)/2 ) k = y; else k = (long)y - p->sizeY();
423 if ( z < (p->sizeZ() + 1)/2 ) l = z; else l = (long)z - p->sizeZ();
424
425 si = (long) s;
426 fraction = s - si;
427 fraction1 = 1 - fraction;
428
429 for ( mol = molgroup->mol; mol; mol = mol->next ) {
430 for( res = mol->res; res; res = res->next ) {
431 for ( atom = res->atom; atom; atom = atom->next )
432 if ( atom->sel ) {
433 t = atom->tnum*MAXSCAT + si;
434 f = atom->q*(fraction1*scat[t] + fraction*scat[t+1]);
435 phi = MIN2PI*(h*atom->vel[0] +
436 k*atom->vel[1] + l*atom->vel[2]);
437 temp = Complex<float>(cos(phi), sin(phi));
438 p->set(i, p->complex(i) + f*temp);
439 }
440 }
441 }
442
443 p->set(i, p->complex(i) * scale);
444
445 if ( verbose & VERB_DEBUG )
446 cout << "DEBUG mol_to_structure_factors: " << x << " " << y << " " << z << " " <<
447 (p->complex(i)).real() << " " << (p->complex(i)).imag() << endl;
448
449 return 0;
450 }
451
452 /*
453 @brief Calculates a 3D set of structure factors from a set of atomic coordinates.
454 @param *molgroup set of molecules with atomic coordinates.
455 @param *p image structure for the new structure factors.
456 @param *atompar atom type parameters.
457 @param resolution resolution (angstrom).
458 @param wrap 0=cut atoms outside box, 1=wrap coordinates within unit cell.
459 @param Bfactor constant for decay curve.
460 @return int 0.
461
462 All structure factors within a given resolution are calculated from
463 all the selected atomic coordinates. The coordinates are fractionalized
464 to fit into the given size box. If the size of the box is not given,
465 it defaults to:
466 x_size = (max(x_coor) - min(x_coor)) / x_sampling
467 The atomic scattering profiles are read from the STAR database as the
468 amplitudes and B-factors of reciprocal space gaussians. For each profile,
469 a lookup table is calculated to speed up further calculations.
470 The content and statistics of the new image is not checked.
471
472 **/
473 int mol_to_structure_factors(Bmolgroup* molgroup, Bimage* p,
474 Batomtype* atompar, double resolution, int wrap, double Bfactor)
475 {
476 long nscat;
477 long i, j, h, k, l, x, y, z, yi, zi, n, t, nmax;
478 long nmol(0), natom(0);
479 double s, smax, sx, sy, sz;
480 Bmolecule* mol;
481 Bresidue* res;
482 Batom* atom;
483 Batomtype* at;
484
485 // Set the resolution limit
486 smax = 1;
487 if ( resolution ) smax = 1.0/resolution;
488 resolution = 1.0/smax;
489
490 double recip_interval = 1.1*smax/MAXSCAT;
491 double inv_recip_int = 1/recip_interval;
492 Vector3<double> ori = p->sampling()*p->image->origin();
493 Vector3<double> fcoor;
494
495 // Convert to fractional coordinates
496 UnitCell unit_cell = p->unit_cell();
497 unit_cell.a(p->real_size()[0]);
498 unit_cell.b(p->real_size()[1]);
499 unit_cell.c(p->real_size()[2]);
500 p->unit_cell(unit_cell);
501 Matrix3 frac_mat = unit_cell.skew_matrix();
502
503 double* scat = get_scattering_curves(atompar, Bfactor, recip_interval, nscat);
504
505 for ( nmol = 0, mol = molgroup->mol; mol; mol = mol->next ) if ( mol->sel ) {
506 nmol++;
507 for( res = mol->res; res; res = res->next ) {
508 for ( atom = res->atom; atom; atom = atom->next, natom++ ) {
509 atom->tnum = -1;
510 for ( t=0, at = atompar; at && atom->tnum < 0; at = at->next, t++ )
511 if ( strncmp(atom->el, at->el, 2) == 0 )
512 atom->tnum = t;
513 if ( atom->tnum < 0 ) atom->sel = 0;
514 if ( verbose & VERB_DEBUG )
515 cout << "DEBUG mol_to_structure_factors: Atom = " << atom->el << endl;
516 fcoor = atom->coord + ori;
517 atom->vel = frac_mat * fcoor;
518 if ( wrap == 1 ) {
519 while ( atom->vel[0] < 0 ) atom->vel[0] += 1;
520 while ( atom->vel[1] < 0 ) atom->vel[1] += 1;
521 while ( atom->vel[2] < 0 ) atom->vel[2] += 1;
522 while ( atom->vel[0] > 1 ) atom->vel[0] -= 1;
523 while ( atom->vel[1] > 1 ) atom->vel[1] -= 1;
524 while ( atom->vel[2] > 1 ) atom->vel[2] -= 1;
525 } else if ( wrap > 1 ) {
526 if ( atom->vel[0] < 0 ) atom->sel = 0;
527 if ( atom->vel[1] < 0 ) atom->sel = 0;
528 if ( atom->vel[0] > 1 ) atom->sel = 0;
529 if ( atom->vel[1] > 1 ) atom->sel = 0;
530 while ( atom->vel[2] < 0 ) atom->vel[2] += 1;
531 while ( atom->vel[2] > 1 ) atom->vel[2] -= 1;
532 } else {
533 if ( atom->vel[0] < 0 ) atom->sel = 0;
534 if ( atom->vel[1] < 0 ) atom->sel = 0;
535 if ( atom->vel[2] < 0 ) atom->sel = 0;
536 if ( atom->vel[0] > 1 ) atom->sel = 0;
537 if ( atom->vel[1] > 1 ) atom->sel = 0;
538 if ( atom->vel[2] > 1 ) atom->sel = 0;
539 }
540 if ( verbose & VERB_DEBUG )
541 cout << "DEBUG mol_to_structure_factors: "
542 << atom->el << " " << atom->vel << endl;
543 }
544 }
545 }
546
547 if ( verbose & VERB_PROCESS ) {
548 cout << "Molecules and atoms: " << nmol << " " << natom << endl;
549 cout << "Unit cell: " <<
550 unit_cell.a() << " " << unit_cell.b() << " " << unit_cell.c() << " " <<
551 unit_cell.alpha()*180/M_PI << " " << unit_cell.beta()*180/M_PI << " " << unit_cell.gamma()*180/M_PI << endl;
552 cout << "Fractionalization matrix: " << endl << frac_mat << endl;
553 }
554
555 // Calculate the structure factors
556 // Default space group = 1
557 // Estimate the number of structure factors from the spherical volume or circular area
558 n = 0;
559 nmax = (long) ((4.0*M_PI/3.0)*smax*smax*smax/(frac_mat[0][0]*frac_mat[1][1]*frac_mat[2][2]));
560 if ( p->sizeZ() < 2 )
561 nmax = (long) (M_PI*smax*smax/(frac_mat[0][0]*frac_mat[1][1]));
562 // Factor required to calculate the estimated completion from the number of
563 // structure factors already calculated
564 // pfac = 100.0/(nmax/2 + M_PI*smax*smax/(2*frac_mat[1][1]*frac_mat[2][2]));
565 // if ( p->sizeZ() < 2 )
566 // pfac = 100.0/(nmax/2 + smax/frac_mat[1][1]);
567 if ( verbose & VERB_PROCESS )
568 cout << "Reflections estimated: " << nmax << endl;
569
570 // Scaled by the potential prefactor K divided by the volume
571 double scale = POTPREFAC/p->size().volume();
572 if ( p->sizeX() > 1 ) scale /= p->sampling()[0];
573 if ( p->sizeY() > 1 ) scale /= p->sampling()[1];
574 if ( p->sizeZ() > 1 ) scale /= p->sampling()[2];
575
576 if ( verbose & VERB_DEBUG )
577 cout << "DEBUG mol_to_structure_factors: scale = " << scale << endl;
578
579 long imgsize = (long) p->size().volume();
580 long hx = p->sizeX()/2, hy = p->sizeY()/2, hz = p->sizeZ()/2;
581 long hx1 = (p->sizeX()+1)/2, hy1 = (p->sizeY()+1)/2, hz1 = (p->sizeZ()+1)/2;
582 Complex<float> temp;
583
584 p->next = new Bimage(Float, TSimple, p->size(), p->images());
585 float* fom = (float *) p->next->data_pointer();
586
587 // Set up FOM block with s values
588 for ( l=-hz; l<hz1; l++ ) {
589 z = ( l < 0 ) ? l + p->sizeZ() : l;
590 sz = l*frac_mat[2][2];
591 sz *= sz;
592 for ( k=-hy; k<hy1; k++ ) {
593 y = ( k < 0 ) ? k + p->sizeY() : k;
594 sy = k*frac_mat[1][1];
595 sy *= sy;
596 for ( h=-hx; h<=0; h++ ) {
597 x = ( h < 0 ) ? h + p->sizeX() : h;
598 sx = h*frac_mat[0][0];
599 sx *= sx;
600 s = sqrt(sx + sy + sz);
601 if ( s < smax ) {
602 i = p->index(x, y, z);
603 s *= inv_recip_int;
604 fom[i] = s;
605 n++;
606 }
607 }
608 }
609 }
610
611 fom[0] = 1e-10; // Make F0 non-zero
612
613 #ifdef HAVE_GCD
614 dispatch_apply(imgsize, dispatch_get_global_queue(0, 0), ^(size_t i){
615 if ( fom[i] ) one_sf(molgroup, p, i, fom[i], scale, scat);
616 });
617 #else
618 #pragma omp parallel for
619 for ( i=0; i<imgsize; i++ ) if ( fom[i] )
620 one_sf(molgroup, p, i, fom[i], scale, scat);
621 #endif
622
623 // cout << "first half done" << endl;
624
625 // Fill in the second half from the first
626 for ( l=-hz; l<hz1; l++ ) {
627 z = ( l < 0 ) ? l + p->sizeZ() : l;
628 zi = ( z == 0 ) ? 0 : p->sizeZ() - z;
629 sz = l*frac_mat[2][2];
630 sz *= sz;
631 for ( k=-hy; k<hy1; k++ ) {
632 y = ( k < 0 ) ? k + p->sizeY() : k;
633 yi = ( y == 0 ) ? 0 : p->sizeY() - y;
634 sy = k*frac_mat[1][1];
635 sy *= sy;
636 for ( h=1; h<hx1; h++ ) {
637 sx = h*frac_mat[0][0];
638 sx *= sx;
639 s = sqrt(sx + sy + sz);
640 if ( s < smax ) {
641 i = p->index(p->sizeX() - h, yi, zi);
642 j = p->index(h, y, z);
643 p->set(j, (p->complex(i)).conj());
644 n++;
645 }
646 }
647 }
648 }
649
650 if ( verbose & VERB_PROCESS )
651 cout << "Reflections calculated: " << n << endl << endl;
652
653 delete[] scat;
654
655 return 0;
656 }
657
658 double* get_potential_curves(Batomtype* atompar, double interval)
659 {
660 long i, j, n, t;
661 double interval2 = -4*M_PI*M_PI*interval*interval, prefac, expfac;
662 Batomtype* at;
663
664 // Get the atomic properties
665 for ( n=0, at = atompar; at; at = at->next, n++ ) ;
666
667 // Calculate the atomic scattering profiles
668 if ( verbose & VERB_DEBUG )
669 cout << "DEBUG get_potential_curves: n=" << n << " interval=" << interval << endl;
670
671 double* apot = new double[MAXRAD*n];
672 for ( i=0; i<MAXRAD*n; i++ ) apot[i] = 0;
673
674 for ( t=0, at = atompar; at; at = at->next, t++ ) {
675 apot[t*MAXRAD] = at->sfc;
676 for ( j=0; j<5; j++ ) {
677 prefac = M_PI*sqrt(M_PI)*at->sfa[j]/(at->sfb[j]*sqrt(at->sfb[j]));
678 expfac = interval2/at->sfb[j];
679 for ( i=0; i<MAXRAD; i++ )
680 apot[t*MAXRAD+i] += prefac*exp(expfac*i*i);
681 }
682 }
683
684 if ( verbose & VERB_FULL ) {
685 cout << "Scattering coefficients:" << endl;
686 for ( at = atompar; at; at = at->next )
687 cout << tab << at->el << "(" << at->z << ")";
688 cout << endl;
689 for ( j=0; j<5; j++ ) {
690 cout << "a" << j+1;
691 for ( at = atompar; at; at = at->next )
692 cout << tab << at->sfa[j];
693 cout << endl;
694 }
695 for ( j=0; j<5; j++ ) {
696 cout << "b" << j+1;
697 for ( at = atompar; at; at = at->next )
698 cout << tab << at->sfb[j];
699 cout << endl;
700 }
701 cout << "c";
702 for ( at = atompar; at; at = at->next )
703 cout << tab << at->sfc;
704 cout << endl << "Atomic radial potential curves:" << endl << "s";
705 for ( at = atompar; at; at = at->next )
706 cout << tab << at->el << "(" << at->z << ")";
707 cout << endl;
708 for ( i=0; i<MAXRAD; i++ ) {
709 cout << i*interval;
710 for ( t=0, at = atompar; at; at = at->next, t++ )
711 cout << tab << apot[t*MAXRAD+i];
712 cout << endl;
713 }
714 cout << endl;
715 }
716
717 return apot;
718 }
719
720 double* get_scattering_curves(Batomtype* atompar, double Bfactor,
721 double recip_interval, long& nscat)
722 {
723 long i, j, n, t;
724 double s2, fact = -Bfactor/4;
725 Batomtype* at;
726
727 if ( recip_interval < 1e-10 ) {
728 cerr << "Error: Reciprocal space interval not defined!" << endl;
729 return NULL;
730 }
731
732 double recip_int2 = recip_interval*recip_interval/4;
733
734 // Get the atomic properties
735 for ( n=0, at = atompar; at; at = at->next, n++ ) ;
736
737 // Calculate the atomic scattering profiles
738 if ( verbose & VERB_DEBUG )
739 cout << "DEBUG get_scattering_curves: nscat = " << n << endl;
740
741 double* scat = new double[MAXSCAT*n];
742 for ( i=0; i<MAXSCAT*n; i++ ) scat[i] = 0;
743
744 for ( i=0; i<MAXSCAT; i++ ) {
745 s2 = i*i*recip_int2;
746 for ( t=0, at = atompar; at; at = at->next, t++ ) {
747 scat[t*MAXSCAT+i] = at->sfc;
748 for ( j=0; j<5; j++ )
749 scat[t*MAXSCAT+i] += at->sfa[j]*exp(-at->sfb[j]*s2);
750 scat[t*MAXSCAT+i] *= exp(fact*s2);
751 }
752 }
753
754 if ( verbose & VERB_FULL ) {
755 cout << "Scattering coefficients:" << endl;
756 for ( at = atompar; at; at = at->next )
757 cout << tab << at->el << "(" << at->z << ")";
758 cout << endl;
759 for ( j=0; j<5; j++ ) {
760 cout << "a" << j+1;
761 for ( at = atompar; at; at = at->next )
762 cout << tab << at->sfa[j];
763 cout << endl;
764 }
765 for ( j=0; j<5; j++ ) {
766 cout << "b" << j+1;
767 for ( at = atompar; at; at = at->next )
768 cout << tab << at->sfb[j];
769 cout << endl;
770 }
771 cout << "c";
772 for ( at = atompar; at; at = at->next )
773 cout << tab << at->sfc;
774 cout << endl << "Scattering curves:" << endl << "s";
775 for ( at = atompar; at; at = at->next )
776 cout << tab << at->el << "(" << at->z << ")";
777 cout << endl;
778 for ( i=0; i<MAXSCAT; i++ ) {
779 s2 = i*i*recip_int2;
780 cout << sqrt(s2);
781 for ( t=0, at = atompar; at; at = at->next, t++ )
782 cout << tab << scat[t*MAXSCAT+i];
783 cout << endl;
784 }
785 cout << endl;
786 }
787
788 nscat = n;
789
790 return scat;
791 }
792
803 int write_scattering_curves(Bstring& paramfile, Bstring& outfile, Bstring& selection)
804 {
805
806 long i, j, nscat;
807 double s2;
808 double recip_interval = 1.0/MAXSCAT;
809 double recip_int2 = recip_interval*recip_interval/4;
810
811 Batomtype* at;
812 Batomtype* atompar = get_atom_properties(paramfile);
813
814 double* scat = get_scattering_curves(atompar, 0, recip_interval, nscat);
815
816 char elsel[1024], *aptr;
817 if ( selection.length() ) strcpy(elsel, selection.c_str());
818 else for ( at = atompar, aptr = elsel; at; aptr += strlen(at->el), at = at->next )
819 strcpy(aptr, at->el);
820
821 ofstream fd(outfile.c_str());
822 if ( fd.fail() ) return -1;
823
824 if ( verbose ) {
825 cout << "Writing scattering curves to: " << outfile << endl;
826 cout << "Elemental selection: " << elsel << endl << endl;
827 }
828
829 fd << "Scattering coefficients:" << endl;
830 for ( at = atompar; at; at = at->next )
831 if ( strstr(elsel, at->el) )
832 fd << tab << at->el << "(" << at->z << ")";
833 fd << endl;
834 for ( j=0; j<5; j++ ) {
835 fd << "a" << j+1;
836 for ( at = atompar; at; at = at->next )
837 if ( strstr(elsel, at->el) )
838 fd << tab << at->sfa[j];
839 fd << endl;
840 }
841 for ( j=0; j<5; j++ ) {
842 fd << "b" << j+1;
843 for ( at = atompar; at; at = at->next )
844 if ( strstr(elsel, at->el) )
845 fd << tab << at->sfb[j];
846 fd << endl;
847 }
848 fd << "c";
849 for ( at = atompar; at; at = at->next )
850 if ( strstr(elsel, at->el) )
851 fd << tab << at->sfc;
852 fd << endl;
853
854 fd << "Scattering curves:" << endl << "s";
855 for ( at = atompar; at; at = at->next )
856 if ( strstr(elsel, at->el) )
857 fd << tab << at->el << "(" << at->z << ")";
858 fd << endl;
859 for ( i=0; i<MAXSCAT; i++ ) {
860 s2 = i*i*recip_int2;
861 fd << sqrt(s2);
862 for ( j=0, at = atompar; at; at = at->next, j++ )
863 if ( strstr(elsel, at->el) )
864 fd << tab << scat[j*MAXSCAT+i];
865 fd << endl;
866 }
867 fd << endl;
868
869 fd.close();
870
871 delete[] scat;
872 kill_list((char *) atompar, sizeof(Batomtype));
873
874 return 0;
875 }
876
Bmolecule::id
Bstring id
Definition: rwmolecule.h:110
UnitCell
Definition: UnitCell.h:22
Bmolgroup::mol
Bmolecule * mol
Definition: rwmolecule.h:189
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Vector3::length
double length()
Definition: Vector3.h:222
Bimage::add
void add(long j, double v)
Definition: Bimage.h:308
molecule_to_map.h
Header file for functions to calculate a 3D map from atomic coordinates.
UnitCell::gamma
void gamma(double d)
Definition: UnitCell.h:41
utilities.h
Header file for general utilities.
get_atom_properties
Batomtype * get_atom_properties(Bstring &filename)
Reading atomic properties from parameter files.
Definition: rwatomprop.cpp:47
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
mol_to_image
int mol_to_image(Bmolgroup *molgroup, Bimage *p, Batomtype *atompar, double resolution, double Bfactor, int wrap, int gextype)
Definition: molecule_to_map.cpp:129
Batomtype::next
Batomtype * next
Definition: rwatomprop.h:20
Bmolecule::res
Bresidue * res
Definition: rwmolecule.h:122
UnitCell::beta
void beta(double d)
Definition: UnitCell.h:40
kill_list
long kill_list(char *list, unsigned long size)
Frees all the items in a linked list.
Definition: linked_list.cpp:214
img_sf_from_molecule
Bimage * img_sf_from_molecule(Bmolgroup *molgroup, Vector3< double > origin, Vector3< long > size, Vector3< double > sampling, double resolution, int spacegroup, UnitCell unit_cell, int wrap, double Bfactor, Bstring &paramfile)
Calculates a 3D set of structure factors from a set of atomic coordinates.
Definition: molecule_to_map.cpp:355
Bimage::index
long index(long nx, long ny) const
Definition: Bimage.h:383
Complex.h
Class for complex numbers.
Matrix3
Definition: Matrix3.h:17
Bstring::length
long length() const
Definition: Bstring.cpp:263
Bimage::complex
Complex< double > complex(long j)
Returns a complex value at the given index.
Definition: Bimage.cpp:1005
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
UnitCell::a
void a(double d)
Definition: UnitCell.h:36
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
TComplex
Definition: Bimage.h:59
Batomtype::sfb
float sfb[5]
Definition: rwatomprop.h:30
Batomtype::sfc
float sfc
Definition: rwatomprop.h:31
Batom::q
double q
Definition: rwmolecule.h:31
TSimple
Definition: Bimage.h:58
Batom::sel
int sel
Definition: rwmolecule.h:34
Float
Definition: utilities.h:157
Bimage::rescale
int rescale(double scale, double shift)
Rescales the image data with a given multiplier and offset.
Definition: Bimage_rescale.cpp:27
Batom::type
char type[8]
Definition: rwmolecule.h:28
Vector3::max
Type max()
Definition: Vector3.h:175
Bimage
General image parameter class.
Definition: Bimage.h:163
Bimage::real_size
Vector3< double > real_size()
Definition: Bimage.h:487
M_PI
#define M_PI
Definition: utilities.h:59
linked_list.h
Header file for generalized linked list functions.
Bmolgroup
Definition: rwmolecule.h:170
get_potential_curves
double * get_potential_curves(Batomtype *atompar, double interval)
Definition: molecule_to_map.cpp:658
Bimage::maximum
double maximum()
Definition: Bimage.h:535
Bimage::statistics
long statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
Batomtype
Definition: rwatomprop.h:19
VERB_TIME
#define VERB_TIME
Definition: utilities.h:110
Standard
Definition: Bimage.h:41
Bimage::unit_cell
void unit_cell(UnitCell uc)
Definition: Bimage.h:601
UnitCell::b
void b(double d)
Definition: UnitCell.h:37
Bmolecule::next
Bmolecule * next
Definition: rwmolecule.h:108
one_sf
double one_sf(Bmolgroup *molgroup, Bimage *p, long i, double s, double scale, double *scat)
Definition: molecule_to_map.cpp:408
POTPREFAC
#define POTPREFAC
Definition: molecule_to_map.h:14
MAXSID
#define MAXSID
Definition: molecule_to_map.cpp:20
Batom::b
double b
Definition: rwmolecule.h:31
Bmolgroup::max
Vector3< double > max
Definition: rwmolecule.h:183
Batomtype::z
int z
Definition: rwatomprop.h:21
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bresidue::atom
Batom * atom
Definition: rwmolecule.h:54
Bstring::c_str
const char * c_str()
Definition: Bstring.h:70
Bmolecule
Definition: rwmolecule.h:107
Bimage::space_group
long space_group()
Definition: Bimage.h:591
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
Bimage::next
Bimage * next
Definition: Bimage.h:165
Bresidue::next
Bresidue * next
Definition: rwmolecule.h:50
Complex
Definition: Complex.h:23
Bresidue
Definition: rwmolecule.h:49
MIN2PI
#define MIN2PI
Definition: utilities.h:71
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
UnitCell::alpha
void alpha(double d)
Definition: UnitCell.h:39
Bstring
Definition: Bstring.h:29
MAXSCAT
#define MAXSCAT
Definition: molecule_to_map.cpp:21
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
Batom
Definition: rwmolecule.h:24
Batomtype::el
char el[4]
Definition: rwatomprop.h:22
UnitCell.h
Header file for unit cell functions.
Bmolecule::sel
int sel
Definition: rwmolecule.h:120
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
Batomtype::sfa
float sfa[5]
Definition: rwatomprop.h:29
Vector3< double >
UnitCell::skew_matrix
Matrix3 skew_matrix()
Calculates the skew matrix from the unit cell parameters.
Definition: UnitCell.cpp:26
RHO
#define RHO
Definition: utilities.h:91
Vector3::min
Type min()
Definition: Vector3.h:169
get_scattering_curves
double * get_scattering_curves(Batomtype *atompar, double Bfactor, double recip_interval, long &nscat)
Definition: molecule_to_map.cpp:720
Batom::coord
Vector3< double > coord
Definition: rwmolecule.h:30
verbose
int verbose
Batom::el
char el[4]
Definition: rwmolecule.h:27
Bmolgroup::min
Vector3< double > min
Definition: rwmolecule.h:182
mol_to_structure_factors
int mol_to_structure_factors(Bmolgroup *molgroup, Bimage *p, Batomtype *atompar, double resolution, int wrap, double Bfactor)
Definition: molecule_to_map.cpp:473
Bimage::images
long images()
Definition: Bimage.h:491
Bimage::coordinates
void coordinates(long i, long &nx, long &ny, long &nz)
Definition: Bimage.h:416
MAXRAD
#define MAXRAD
Definition: molecule_to_map.cpp:22
Batom::tnum
int tnum
Definition: rwmolecule.h:29
Vector3::volume
double volume()
Definition: Vector3.h:235
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::sizeY
void sizeY(long ny)
Definition: Bimage.h:378
write_scattering_curves
int write_scattering_curves(Bstring &paramfile, Bstring &outfile, Bstring &selection)
Calculates and writes atomic scattering profiles to a file.
Definition: molecule_to_map.cpp:803
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:106
compare_mol_map
int compare_mol_map(Bmolgroup *molgroup, Bimage *pcalc, Bimage *p)
Compares reference and calculated maps and calculates an occupancy for every atom in the molecule set...
Definition: molecule_to_map.cpp:277
Bimage::minimum
double minimum()
Definition: Bimage.h:534
Batom::next
Batom * next
Definition: rwmolecule.h:25
Batom::mass
double mass
Definition: rwmolecule.h:32
TWOPI
#define TWOPI
Definition: utilities.h:68
img_from_molecule
Bimage * img_from_molecule(Bmolgroup *molgroup, Vector3< double > origin, Vector3< long > size, Vector3< double > sampling, double resolution, double Bfactor, int wrap, int gextype, int spacegroup, UnitCell unit_cell)
Calculates a 3D density map from a set of atomic coordinates.
Definition: molecule_to_map.cpp:53
Bimage::fourier_type
FourierType fourier_type()
Definition: Bimage.h:367
Batom::vel
Vector3< double > vel
Definition: rwmolecule.h:35
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
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
atom_type_kill
int atom_type_kill(Batomtype *atype)
Destroys an atom type.
Definition: rwatomprop.cpp:177