| Bsoft 2.0.5 Bernard's software package

model_symmetry.cpp
Go to the documentation of this file.
1
9 #include "model_util.h"
10 #include "model_transform.h"
11 #include "model_select.h"
12 #include "model_compare.h"
13 #include "mol_transform.h"
14 #include "mol_compare.h"
15 #include "mol_util.h"
16 #include "symmetry.h"
17 #include "Matrix3.h"
18 #include "random_numbers.h"
19 #include "linked_list.h"
20 #include "utilities.h"
21
22 // Declaration of global variables
23 extern int verbose; // Level of output to the screen
24
34 long model_find_asymmetric_unit(Bmodel* model, Bstring& symmetry_string)
35 {
36 Bsymmetry* sym = init_point_group_symmetry(symmetry_string);
37
38 if ( !sym ) return -1;
39
40 if ( verbose )
41 cout << "Setting asymmetric unit for " << model->id << " to symmetry " << sym->label << endl;
42
43 long ncomp(0);
44 Bcomponent* comp;
45 View view, view_asu;
46
47 for ( comp = model->comp; comp; comp = comp->next, ncomp++ ) {
48 view = View(comp->loc[0], comp->loc[1], comp->loc[2], 0);
49 view_asu = find_asymmetric_unit_view(sym, view);
50 comp->view = view_asu;
51 comp->loc = view_asu.vector3() * comp->loc.length();
52 }
53
54 kill_symmetry(sym);
55
56 return ncomp;
57 }
58
71 long model_apply_point_group(Bmodel* model, Bstring& symmetry_string,
72 Vector3<double> origin, View ref_view, int flags)
73 {
74 if ( ! model->comp ) return 0;
75
76 Bsymmetry* sym = init_point_group_symmetry(symmetry_string);
77
78 long i, j, k;
79 long ncomp(0), nlink(0), id(0);
80 double distance(1e30), d;
81
82 int nunits(1);
83 for ( i=0; i<sym->n; i++ ) nunits *= sym->op[i].order;
84 if ( nunits < 2 ) {
85 kill_symmetry(sym);
86 return 0;
87 }
88
89 if ( ref_view.vector_size() < 1e-10 ) ref_view = View(0, 0, 1, 0);
90
91 Bcomponent* comp;
92 Bcomponent* new_comp = NULL;
93
94 for ( ncomp=1, comp = model->comp; comp->next; comp = comp->next, ncomp++ ) {
95 for ( new_comp = comp->next; new_comp; new_comp = new_comp->next ) {
96 d = comp->loc.distance(new_comp->loc);
97 if ( d < distance ) distance = d;
98 }
99 }
100 if ( ncomp < 2 ) distance = model->comp->loc.length();
101 distance /= 2;
102
103 if ( verbose & VERB_PROCESS ) {
104 cout << "Applying symmetry " << sym->label << ":" << endl;
105 cout << "Number of asymmetric units: " << nunits << endl;
106 cout << "Origin for symmetrization: " << origin << endl;
107 cout << "Reference symmetry axis: " << ref_view << endl;
108 cout << "Reference rotation angle: " << ref_view.angle()*180/M_PI << endl;
109 cout << "Overlap distance cutoff: " << distance << endl << endl;
110 } else if ( verbose & VERB_LABEL )
111 cout << endl << "Applying symmetry " << sym->label << endl << endl;
112
113 model->symmetry = sym->label;
114
115 Matrix3 ref_mat = ref_view.matrix();
116 Matrix3 mat(1), cmat;
117 Vector3<double> new_axis;
118
119 double clen;
120 Vector3<double> v;
121 Blink* link;
122 Blink* new_link = NULL;
123 Blink* link_start = NULL;
124
125
126 for ( comp = model->comp; comp; comp = comp->next ) {
127 if ( id < comp->id.integer() ) id = comp->id.integer();
128 if ( flags & 1 ) {
129 clen = comp->loc.length();
130 comp->view = View(comp->loc[0], comp->loc[1], comp->loc[2], 0);
131 comp->view = find_asymmetric_unit_view(sym, comp->view);
132 comp->loc = Vector3<double>(comp->view[0], comp->view[1], comp->view[2]);
133 comp->loc *= clen;
134 }
135 }
136
137 for ( nlink = 0, link = model->link; link; link = link->next ) nlink++;
138
139 for ( i=0; i<sym->n; i++ ) {
140 new_axis = ref_mat * sym->op[i].axis;
141 for ( j=1; j<sym->op[i].order; j++ ) {
142 mat = Matrix3(new_axis, j*TWOPI/sym->op[i].order);
143 mat *= ref_mat;
144 link_start = NULL;
145 for ( k=0, link = model->link; k<nlink; link = link->next, k++ ) {
146 // new_link = link_add(&link, link->comp[0], link->comp[1], link->length, link->radius);
147 new_link = (Blink *) add_item((char **) &link, sizeof(Blink));
148 if ( !link_start ) link_start = new_link;
149 new_link->comp[0] = link->comp[0];
150 new_link->comp[1] = link->comp[1];
151 new_link->length = link->length;
152 new_link->radius = link->radius;
153 new_link->color = link->color;
154 }
155 for ( k=0, comp = model->comp; k<ncomp; comp = comp->next, k++ ) {
156 new_comp = (Bcomponent *) add_item((char **) &comp, sizeof(Bcomponent));
157 // new_comp = component_add(&comp, id);
158 component_copy(comp, new_comp);
159 new_comp->id = Bstring(++id, "%ld");
160 v = comp->loc - origin;
161 new_comp->loc = (mat * v) + origin;
162 cmat = comp->view.matrix();
163 cmat = mat * cmat;
164 new_comp->view = View(cmat);
165 for ( link = link_start; link; link = link->next ) {
166 if ( link->comp[0] == comp ) link->comp[0] = new_comp;
167 if ( link->comp[1] == comp ) link->comp[1] = new_comp;
168 }
169 }
170 }
171 ncomp *= sym->op[i].order;
172 nlink *= sym->op[i].order;
173 }
174
175 kill_symmetry(sym);
176
177 ncomp = model_average_overlapped_components(model, distance);
178
179 return ncomp;
180 }
181
194 long models_apply_point_group(Bmodel* model, Bstring& symmetry_string,
195 Vector3<double> origin, View ref_view, int flags)
196 {
197 long ncomp(0);
198 Bmodel* mp;
199
200 for ( mp = model; mp; mp = mp->next )
201 ncomp += model_apply_point_group(mp, symmetry_string, origin, ref_view, flags);
202
203 return ncomp;
204 }
205
216 /*int model_symmetrize2(Bmodel* model, Bstring& symmetry_string)
217 {
218 Bsymmetry* sym = init_point_group_symmetry(symmetry_string);
219
220 int i, nunits(1);
221 for ( i=0; i<sym->n; i++ ) nunits *= sym->op[i].order;
222 if ( nunits < 2 ) {
223 kill_symmetry(sym);
224 return 0;
225 }
226
227 if ( verbose & VERB_PROCESS ) {
228 cout << endl << "Symmetrizing " << symmetry_string << ":" << endl;
229 cout << "Number of asymmetric units: " << nunits << endl << endl;
230 } else if ( verbose & VERB_LABEL )
231 cout << endl << "Symmetrizing " << symmetry_string << endl << endl;
232
233 long ncomp(0);
234 double clen, d, dmin, R(0);
235 Vector3<double> loc, locsym;
236 View* views, *v, comp_view;
237
238 Bcomponent* comp;
239 Bcomponent* compsym;
240 Bcomponent* compsel = NULL;
241
242
243 for ( comp = model->comp; comp; comp = comp->next ) {
244 comp->vec = 0;
245 comp->sel = 0;
246 }
247 for ( comp = model->comp; comp; comp = comp->next ) {
248 clen = comp->loc.length();
249 comp_view = View(comp->loc[0], comp->loc[1], comp->loc[2], 0);
250 views = symmetry_get_all_views(sym, comp_view);
251 for ( v = views; v; v = v->next ) {
252 loc = Vector3<double>(v->x(), v->y(), v->z());
253 loc *= clen;
254 for ( dmin = 1e30, compsym = model->comp; compsym; compsym = compsym->next ) {
255 d = loc.distance(compsym->loc);
256 if ( dmin > d ) {
257 dmin = d;
258 compsel = compsym;
259 }
260 }
261 compsel->vec += loc;
262 compsel->sel++;
263 R += dmin*dmin;
264 ncomp++;
265 }
266 }
267 for ( comp = model->comp; comp; comp = comp->next ) {
268 comp->loc = comp->vec/comp->sel;
269 comp->vec = 0;
270 }
271
272 R = sqrt(R/ncomp);
273
274 if ( verbose & VERB_PROCESS )
275 cout << "Symmetry deviation: " << R << " A" << endl << endl;
276
277 kill_symmetry(sym);
278
279 return ncomp;
280 }
281 */
282 long model_symmetrize(Bmodel* model, Bstring& symmetry_string)
283 {
284 Bsymmetry* sym = init_point_group_symmetry(symmetry_string);
285
286 int i, nunits(1);
287 for ( i=0; i<sym->n; i++ ) nunits *= sym->op[i].order;
288 if ( nunits < 2 ) {
289 kill_symmetry(sym);
290 return 0;
291 }
292
293 if ( verbose & VERB_PROCESS ) {
294 cout << endl << "Symmetrizing " << symmetry_string << ":" << endl;
295 cout << "Number of asymmetric units: " << nunits << endl << endl;
296 } else if ( verbose & VERB_LABEL )
297 cout << endl << "Symmetrizing " << symmetry_string << endl << endl;
298
299 long ncomp(0), nasu;
300 double tol(1e-4), d, dmin, R(0);
301 Vector3<double> loc;
302 View view, view_asu;
303
304 Bcomponent* comp;
305 Bcomponent* compasu;
306 Bcomponent* compsel = NULL;
307
308
309 for ( nasu=0, comp = model->comp; comp; comp = comp->next ) { // Select all components in the ASU
310 comp->sel = 0;
311 view = View(comp->loc[0], comp->loc[1], comp->loc[2], 0);
312 view_asu = find_asymmetric_unit_view(sym, view);
313 comp->vec = Vector3<double>(view_asu[0], view_asu[1], view_asu[2]);
314 if ( view.distance(view_asu) < tol ) {
315 comp->loc = comp->vec * comp->loc.length();
316 comp->sel = 1;
317 nasu++;
318 }
319 }
320
321 for ( comp = model->comp; comp; comp = comp->next ) if ( !comp->sel ) {
322 for ( dmin = 1e30, compasu = model->comp; compasu; compasu = compasu->next ) if ( compasu->sel ) {
323 d = comp->vec.distance(compasu->vec);
324 if ( dmin > d ) {
325 dmin = d;
326 compsel = compasu;
327 }
328 }
329 compsel->loc += comp->vec * comp->loc.length();
330 compsel->sel++;
331 dmin *= comp->loc.length();
332 R += dmin*dmin;
333 ncomp++;
334 }
335 if ( verbose & VERB_PROCESS ) {
336 cout << "Model: " << model->id << endl;
337 cout << "Asymmetric unit components: " << nasu << endl;
338 cout << "Comp\tCount" << endl;
339 }
340 for ( comp = model->comp; comp; comp = comp->next ) if ( comp->sel ) {
341 comp->loc /= comp->sel;
342 comp->vec = 0;
343 if ( verbose & VERB_PROCESS )
344 cout << comp->id << tab << comp->sel << endl;
345 }
346 if ( verbose & VERB_PROCESS )
347 cout << endl;
348
349 R = sqrt(R/ncomp);
350
351 if ( verbose & VERB_PROCESS )
352 cout << "Symmetry deviation: " << R << " A" << endl << endl;
353
354 kill_symmetry(sym);
355
356 model_delete_non_selected(&model);
357
358 Vector3<double> origin;
359 View ref_view;
360
361 model_apply_point_group(model, symmetry_string, origin, ref_view, 1);
362
363 return ncomp;
364 }
365
376 long model_symmetry_related(Bmodel* model, Bstring& symmetry_string)
377 {
378 Bsymmetry* sym = init_point_group_symmetry(symmetry_string);
379
380 View* v;
381 View ref(0,0,1,0);
382 View* views = symmetry_get_all_views(sym, ref);
383
384 long i(1), ncomp(model_component_count(model));
385 Bmodel* mp = model;
386
387 for ( v = views->next; v; v = v->next ) {
388 mp->next = model_copy(model);
389 mp = mp->next;
390 mp->id = model->id + Bstring(++i, "_%02d");
391 model_rotate(mp, *v);
392 }
393
394 ncomp *= i;
395
396 return ncomp;
397 }
distance
double distance(vector< T1 > &v1, vector< T2 > &v2)
Definition: Vector3.h:536
Bcomponent::id
Bstring id
Definition: rwmodel.h:53
model_symmetry_related
long model_symmetry_related(Bmodel *model, Bstring &symmetry_string)
Generates a list of symmetry-related models.
Definition: model_symmetry.cpp:376
Blink
Definition: rwmodel.h:82
Bmodel::id
Bstring id
Definition: rwmodel.h:121
Vector3::length
double length()
Definition: Vector3.h:222
View::next
View * next
Definition: View.h:28
Bsymmetry::n
int n
Definition: symmetry.h:42
symmetry.h
Header file for general symmetry functions.
utilities.h
Header file for general utilities.
Blink::color
RGBA< float > color
Definition: rwmodel.h:88
model_util.h
Library routines used for model processing.
model_symmetrize
long model_symmetrize(Bmodel *model, Bstring &symmetry_string)
Symmetrize a model.
Definition: model_symmetry.cpp:282
add_item
char * add_item(char **list, unsigned long size)
Adds an item to a linked list.
Definition: linked_list.cpp:26
model_component_count
int model_component_count(Bmodel *model)
Counts the total number of components.
Definition: rwmodel.cpp:635
Matrix3
Definition: Matrix3.h:17
mol_transform.h
Library routines used for atomic coordinate transformations.
kill_symmetry
int kill_symmetry(Bsymmetry *sym)
Deallocates a symmetry structure.
Definition: symmetry.cpp:207
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
Blink::comp
Bcomponent * comp[2]
Definition: rwmodel.h:84
Vector3::distance
double distance(const Vector3 &v)
Definition: Vector3.h:227
model_copy
Bmodel * model_copy(Bmodel *model)
Copies a model.
Definition: rwmodel.cpp:685
View::vector_size
double vector_size()
Definition: View.h:103
Matrix3.h
3x3 Matrix manipulation functions
mol_util.h
Library routines used for atomic coordinates.
M_PI
#define M_PI
Definition: utilities.h:59
linked_list.h
Header file for generalized linked list functions.
Blink::length
float length
Definition: rwmodel.h:86
Bcomponent::view
View view
Definition: rwmodel.h:59
Blink::next
Blink * next
Definition: rwmodel.h:83
Blink::radius
float radius
Definition: rwmodel.h:87
init_point_group_symmetry
Bsymmetry * init_point_group_symmetry(Bstring symmetry_string)
Sets up a symmetry structure from a string identifier.
Definition: symmetry.cpp:39
Bsymop::order
int order
Definition: symmetry.h:26
Bmodel::symmetry
Bstring symmetry
Definition: rwmodel.h:124
model_average_overlapped_components
long model_average_overlapped_components(Bmodel *model, double distance)
Averages components within a distance.
Definition: model_select.cpp:1425
View::vector3
Vector3< double > vector3()
Definition: View.h:126
model_rotate
long model_rotate(Bmodel *model, Matrix3 mat)
Rotates the model.
Definition: model_transform.cpp:238
Bmodel::next
Bmodel * next
Definition: rwmodel.h:120
Bsymmetry::label
Bstring label
Definition: symmetry.h:41
Bcomponent::sel
int sel
Definition: rwmodel.h:66
Bsymmetry
Definition: symmetry.h:38
model
Bmodel * model
Definition: bshow.cpp:32
models_apply_point_group
long models_apply_point_group(Bmodel *model, Bstring &symmetry_string, Vector3< double > origin, View ref_view, int flags)
Applying symmetry to model components.
Definition: model_symmetry.cpp:194
random_numbers.h
Header file for functions for creating random images.
Bstring
Definition: Bstring.h:29
model_delete_non_selected
long model_delete_non_selected(Bmodel **model)
Deletes selected components and associated links from the model.
Definition: model_select.cpp:781
View::matrix
Matrix3 matrix()
Definition: View.h:150
Bmodel::link
Blink * link
Definition: rwmodel.h:133
Bcomponent::vec
Vector3< float > vec
Definition: rwmodel.h:60
Bcomponent::next
Bcomponent * next
Definition: rwmodel.h:52
find_asymmetric_unit_view
View find_asymmetric_unit_view(Bsymmetry *sym, View theview)
Finds the corresponding view in the asymmetric unit.
Definition: symmetry.cpp:856
Vector3< double >
View::angle
double angle()
Definition: View.h:95
View
Definition: View.h:26
model_find_asymmetric_unit
long model_find_asymmetric_unit(Bmodel *model, Bstring &symmetry_string)
Set model component locations within the asymmetric unit.
Definition: model_symmetry.cpp:34
component_copy
int component_copy(Bcomponent *fromcomp, Bcomponent *tocomp)
Copies all elements from one component to another.
Definition: rwmodel.cpp:783
Bstring::integer
long integer()
Definition: Bstring.cpp:539
Bmodel
Definition: rwmodel.h:119
verbose
int verbose
Bsymmetry::op
Bsymop * op
Definition: symmetry.h:43
Bmodel::comp
Bcomponent * comp
Definition: rwmodel.h:132
View::distance
double distance(const View &view)
Definition: View.h:155
model_select.h
Header file for reading and writing atomic model files.
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:106
Bsymop::axis
Vector3< double > axis
Definition: symmetry.h:25
Bcomponent::loc
Vector3< float > loc
Definition: rwmodel.h:58
model_transform.h
Library routines used for model transformation.
model_compare.h
Functions to compare models and components.
TWOPI
#define TWOPI
Definition: utilities.h:68
model_apply_point_group
long model_apply_point_group(Bmodel *model, Bstring &symmetry_string, Vector3< double > origin, View ref_view, int flags)
Applying symmetry to model components.
Definition: model_symmetry.cpp:71
symmetry_get_all_views
View * symmetry_get_all_views(Bsymmetry *sym, View asu_view)
Get all symmetry-related views of one given view.
Definition: symmetry.cpp:448
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
mol_compare.h
Library routines used to compare sets of atomic coordinates.
Bcomponent
Definition: rwmodel.h:51