| Bsoft 2.0.5 Bernard's software package

model_views.cpp
Go to the documentation of this file.
1
9 #include "rwimg.h"
10 #include "model_views.h"
11 #include "model_util.h"
12 #include "model_neighbors.h"
13 #include "mol_compare.h"
14 #include "Matrix3.h"
15 #include "linked_list.h"
16 #include "utilities.h"
17
18 // Declaration of global variables
19 extern int verbose; // Level of output to the screen
20
29 View* views_from_model(Bmodel* model)
30 {
31 Bcomponent* comp;
32 View* view = NULL;
33 View* v = NULL;
34
35 for ( comp = model->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
36 v = (View *) add_item((char **) &v, sizeof(View));
37 if ( !view ) view = v;
38 *v = comp->view;
39 v->next = NULL;
40 }
41
42 return view;
43 }
44
53 View* views_from_models(Bmodel* model)
54 {
55 Bmodel* mp;
56 View* view = NULL;
57 View* v = NULL;
58 View* v2 = NULL;
59
60 for ( mp = model; mp; mp = mp->next ) {
61 v = views_from_model(mp);
62 if ( !view ) view = v2 = v;
63 else {
64 while ( v2->next ) v2 = v2->next;
65 v2->next = v;
66 }
67 }
68
69 return view;
70 }
71
81 long model_set_views(Bmodel* model, View view)
82 {
83 long nsel(0);
84 Bmodel* mp;
85 Bcomponent* comp;
86
87 if ( verbose )
88 cout << "Setting views" << endl << endl;
89
90 for ( mp = model; mp; mp = mp->next ) {
91 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
92 nsel++;
93 comp->view = view;
94 }
95 }
96
97 return nsel;
98 }
99
109 long model_invert_views(Bmodel* model)
110 {
111 long nsel(0);
112 Bmodel* mp = model;
113 Bcomponent* comp;
114
115 if ( verbose )
116 cout << "Inverting views" << endl << endl;
117
118 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
119 nsel++;
120 comp->view = comp->view.backward();
121 }
122
123 return nsel;
124 }
125
136 long model_find_views(Bmodel* model, Bstring& reffile, Bstring& paramfile)
137 {
138 Bcomponent* comp = NULL;
139 Transform t;
140 Bstring atom_select("all");
141
142 if ( !model->type ) {
143 cerr << "Error: No component types found!" << endl;
144 return -1;
145 }
146
147 long nsel(0);
148 Bmolgroup* molgroup = NULL;
149 Bmolgroup* ref_molgroup = read_molecule(reffile, atom_select, paramfile);
150
151 if ( verbose )
152 cout << "Molecule\tDist\t\t\tAxis\t\t\tAngle" << endl;
153 for ( comp = model->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
154 nsel++;
155 molgroup = read_molecule(comp->type->fmod, atom_select, paramfile);
156 t = molgroup_find_transformation(molgroup, ref_molgroup);
157 // comp->view = view_from_angle_and_axis3(t.angle, t.axis);
158 comp->view = View(t.angle, t.axis);
159 molgroup_kill(molgroup);
160 if ( verbose )
161 cout << comp->type->fmod << tab << comp->loc[0] << tab << comp->loc[1] << tab << comp->loc[2] << tab <<
162 comp->view[0] << tab << comp->view[1] << tab << comp->view[2] << tab << comp->view.angle()*180.0/M_PI << endl;
163 }
164
165 molgroup_kill(ref_molgroup);
166
167 return nsel;
168 }
169
170 /* The normal is defined as the average of all the rotation axes associated
171 with the angles between the links */
172 Vector3<double> component_normal(Bcomponent* comp)
173 {
174 Vector3<double> normal;
175
176 if ( !comp->link[1] ) return normal;
177
178 long i, j;
179 Vector3<double> v1, v2;
180
181 for ( i=1; comp->link[i]; i++ ) {
182 for ( j=0; j<i; j++ ) {
183 v1 = comp->link[i]->loc - comp->loc;
184 v2 = comp->link[j]->loc - comp->loc;
185 v1 = v1.cross(v2);
186 if ( comp->loc.angle(v1) > M_PI_2 ) v1 = -v1;
187 v1.normalize();
188 normal += v1;
189 }
190 }
191 if ( normal.length2() > 1e-10 ) normal.normalize();
192
193 return normal;
194 }
195
196 /* The view vector is the normal and the rotation angle is chosen such that
197 the first link falls in the xz plane when the component is rotated to the
198 standard view */
199 View component_view(Bcomponent* comp)
200 {
201 Vector3<double> w(comp->view[0], comp->view[1], comp->view[2]);
202
203 if ( comp->link[1] ) w = component_normal(comp);
204
205 if ( w.length2() < 0.1 ) w = comp->loc;
206
207 long i, im;
208 Vector3<double> v, u;
209 double a(0);
210 /*
211 for ( i=1, im=0, fm=comp->flag[0]; i<MAXLINK && comp->link[i]; i++ ) {
212 if ( fm == comp->flag[i] ) {
213 v = comp->loc.normal(comp->link[im]->loc, comp->link[i]->loc);
214 a = w.angle(v);
215 if ( a > M_PI_2 ) im = i;
216 } else if ( fm > comp->flag[i] ) {
217 fm = comp->flag[i];
218 im = i;
219 }
220 }
221 */
222
223 for ( i=1, im=0; i<MAXLINK && comp->link[i]; i++ ) {
224 if ( comp->flag[i] == 1 ) {
225 v = comp->loc.normal(comp->link[im]->loc, comp->link[i]->loc);
226 a = w.angle(v);
227 if ( a > M_PI_2 ) im = i;
228 }
229 }
230
231 if ( comp->flag[im] ) {
232 w.normalize();
233 u = comp->link[im]->loc - comp->loc;
234 u.normalize();
235 v = w.cross(u);
236 v.normalize();
237 u = v.cross(w);
238 a = angle_set_negPI_to_PI(atan2(w[1], w[0]) + atan2(v[2], -u[2]));
239 }
240
241 View view(w[0], w[1], w[2], a);
242
243 return view;
244 }
245
263 long model_calculate_views(Bmodel* model, Bstring& mode)
264 {
265 if ( mode.length() < 1 ) {
266 cerr << "Error: The view calculation mode must be specified!" << endl << endl;
267 bexit(-1);
268 }
269
270 if ( mode[0] == 'l' ) return model_calculate_local_views(model);
271
272 Bmodel* mp;
273 Bcomponent* comp;
274 Vector3<double> normal;
275 Vector3<double> origin;
276
277 long nsel(0);
278
279 if ( verbose & VERB_PROCESS )
280 cout << "Calculating views based on origin-component vectors" << endl << endl;
281
282 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
283 if ( mode[0] == 'c' )
284 origin = model_center_of_mass(model);
285 if ( verbose & VERB_DEBUG )
286 cout << "DEBUG model_calculate_views: origin=" << origin << endl;
287 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
288 normal = comp->loc - origin;
289 if ( verbose & VERB_DEBUG )
290 cout << "Old view: " << comp->view << endl;
291 comp->view = View(normal[0], normal[1], normal[2], 0);
292 if ( comp->link[0] ) comp->view = component_view(comp);
293 if ( verbose & VERB_DEBUG )
294 cout << "New view: " << comp->view << endl;
295 nsel++;
296 }
297 }
298
299 return nsel;
300 }
301
318 long model_calculate_local_views(Bmodel* model)
319 {
320 Bmodel* mp;
321 Bcomponent* comp;
322 Vector3<double> normal;
323
324 long nsel(0);
325 double offset(0);
326
327 if ( verbose & VERB_PROCESS )
328 cout << "Calculating views based on neighbors" << endl << endl;
329
330 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
331 model_set_neighbors(mp, 3);
332 for ( comp = mp->comp; comp; comp = comp->next ) {
333 normal = component_plane(comp->neighbor, offset);
334 if ( verbose & VERB_DEBUG )
335 cout << "Old view: " << comp->view << endl;
336 comp->view = View(normal[0], normal[1], normal[2], 0);
337 if ( comp->link[0] ) comp->view = component_view(comp);
338 if ( verbose & VERB_DEBUG )
339 cout << "New view: " << comp->view << endl;
340 if ( comp->sel > 0 ) nsel++;
341 }
342 }
343
344 return nsel;
345 }
346
359 long model_view_directions(Bmodel* model, int bin_width, int ref_flag)
360 {
361 long i, j, im, nsel(0);
362 Bmodel* mp;
363 Bcomponent* comp;
364 Bcomptype* comptype = model->type;
365
366 if ( !comptype ) {
367 cerr << "Error: No component types found!" << endl;
368 return -1;
369 }
370
371 for ( mp = model; mp; mp = mp->next )
372 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) nsel++;
373
374 // Vector3<double> com;
375 Vector3<double> vr(0,0,1), vc;
376 Matrix3 mat;
377 double max;
378 double d, da;
379
380 double width = (M_PI/180.0) * (int) (1800.0/nsel);
381 if ( bin_width ) width = bin_width * M_PI/180.0;
382
383 int bins = (int) (M_PI/width + 0.999);
384 int a3t[3] = {0,0,0};
385 int* a = new int[bins];
386 int* a3 = new int[3*bins];
387
388 for ( i=0; i<bins; i++ ) a[i] = 0;
389 for ( i=0; i<3*bins; i++ ) a3[i] = 0;
390
391 if ( verbose )
392 cout << "Model\tComp\tDist\tAngle\tvx\tvy\tvz" << endl;
393 for ( mp = model; mp; mp = mp->next ) {
394 // com = model_center_of_mass(mp);
395 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
396 // vr = comp->loc - com;
397 d = comp->loc.length();
398 if ( ref_flag ) vr = comp->loc;
399 vc = Vector3<double>(comp->view[0], comp->view[1], comp->view[2]);
400 da = vc.angle(vr);
401 i = (int) (da/width);
402 if ( i >= bins ) cout << "i too large: " << i << endl;
403 a[i]++;
404 for ( j=im=0, max = 0; j<3; j++ ) {
405 if ( max < fabs(comp->loc[j]) ) {
406 max = fabs(comp->loc[j]);
407 im = j;
408 }
409 }
410 a3[im*bins+i]++;
411 mat = comp->view.matrix();
412 mat = mat.transpose();
413 // cout << mat << endl;
414 comp->loc = mat * vr;
415 comp->loc.normalize();
416 comp->radius = 0.05;
417 if ( verbose )
418 cout << mp->id << tab << comp->id << tab << d << tab <<
419 da*180.0/M_PI << tab << comp->loc[0] << tab <<
420 comp->loc[1] << tab << comp->loc[2] << endl;
421 }
422 }
423
424 for ( i=0; i<bins; i++ )
425 for ( j=0; j<3; j++ ) a3t[j] += a3[j*bins+i];
426
427 if ( verbose ) {
428 cout << "\nHistogram:\nAngle\tCount\tExpect\tRatio" << endl;
429 for ( i=0; i<bins; i++ ) {
430 da = nsel*(cos(width*i) - cos(width*(i+1)))/2.0;
431 cout << (i+0.5)*width*180.0/M_PI << tab << a[i] << tab << da << tab << a[i]/da << endl;
432 }
433 cout << "\nHistogram for three directions of component locations:" << endl;
434 cout << "Angle\txCount\tyCount\tzCount\txRatio\tyRatio\tzRatio" << endl;
435 for ( i=0; i<bins; i++ ) {
436 da = (cos(width*i) - cos(width*(i+1)))/2.0;
437 cout << (i+0.5)*width*180.0/M_PI;
438 for ( j=0; j<3; j++ ) cout << tab << a3[j*bins+i];
439 for ( j=0; j<3; j++ ) cout << tab << a3[j*bins+i]/(a3t[j]*da);
440 cout << endl;
441 }
442 cout << "Total";
443 for ( j=0; j<3; j++ ) cout << tab << a3t[j];
444 cout << endl << endl;
445 }
446
447 delete[] a;
448 delete[] a3;
449
450 return nsel;
451 }
452
466 int component_hand(Bstring& s)
467 {
468 int h(0), len = s.length();
469 Bstring ss(s);
470 Bstring sh(s);
471
472 if ( len < 3 ) return (0);
473 else if ( len == 3 ) {
474 ss = ss.canonical(1);
475 sh = sh.swap(0,2);
476 sh = sh.canonical(1);
477 } else if ( len == 6 ) {
478 ss = ss.canonical(2);
479 sh = sh.swap(0,2);
480 sh = sh.swap(3,5);
481 sh = sh.canonical(2);
482 }
483
484 h = ss.compare(sh);
485
486 if ( h > 0 ) h = 1;
487 if ( h < 0 ) h = -1;
488
489 return h;
490 }
491
model_calculate_local_views
long model_calculate_local_views(Bmodel *model)
Calculates the views associated with each component based on neighbors.
Definition: model_views.cpp:318
MAXLINK
#define MAXLINK
Definition: rwmodel.h:14
Bcomponent::id
Bstring id
Definition: rwmodel.h:53
M_PI_2
#define M_PI_2
Definition: utilities.h:62
Vector3::cross
Vector3 cross(const Vector3 &v)
Definition: Vector3.h:250
Vector3::normal
Vector3 normal(Vector3 &v1, Vector3 &v2)
Definition: Vector3.h:267
Bcomponent::type
Bcomptype * type
Definition: rwmodel.h:54
component_hand
int component_hand(Bstring &s)
Determines the hand of a component.
Definition: model_views.cpp:466
Vector3::normalize
double normalize()
Definition: Vector3.h:236
Bmodel::id
Bstring id
Definition: rwmodel.h:121
model_views.h
Library routines used for analysing model component views.
Vector3::length
double length()
Definition: Vector3.h:222
View::next
View * next
Definition: View.h:28
views_from_model
View * views_from_model(Bmodel *model)
Returns a list of component views.
Definition: model_views.cpp:29
utilities.h
Header file for general utilities.
model_util.h
Library routines used for model processing.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
model_find_views
long model_find_views(Bmodel *model, Bstring &reffile, Bstring &paramfile)
Finds the molecule views with respect to a reference.
Definition: model_views.cpp:136
Bcomptype::fmod
Bstring fmod
Definition: rwmodel.h:29
angle_set_negPI_to_PI
double angle_set_negPI_to_PI(double angle)
Returns an angle between -PI and PI.
Definition: utilities.cpp:594
Transform::angle
double angle
Definition: Transform.h:29
Bcomponent::flag
int flag[MAXLINK]
Definition: rwmodel.h:57
add_item
char * add_item(char **list, unsigned long size)
Adds an item to a linked list.
Definition: linked_list.cpp:26
Matrix3
Definition: Matrix3.h:17
Bstring::length
long length() const
Definition: Bstring.cpp:263
Bmodel::sel
int sel
Definition: rwmodel.h:129
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
Bcomponent::neighbor
Bcomponent * neighbor[MAXLINK]
Definition: rwmodel.h:56
Matrix3.h
3x3 Matrix manipulation functions
model_set_views
long model_set_views(Bmodel *model, View view)
Sets views.
Definition: model_views.cpp:81
component_view
View component_view(Bcomponent *comp)
Definition: model_views.cpp:199
Transform
Definition: Transform.h:24
M_PI
#define M_PI
Definition: utilities.h:59
linked_list.h
Header file for generalized linked list functions.
model_view_directions
long model_view_directions(Bmodel *model, int bin_width, int ref_flag)
Analyzes view directions in a model.
Definition: model_views.cpp:359
Bmolgroup
Definition: rwmolecule.h:170
Bcomponent::view
View view
Definition: rwmodel.h:59
Bmodel::type
Bcomptype * type
Definition: rwmodel.h:131
Vector3::angle
double angle(Vector3< T2 > &v)
Definition: Vector3.h:257
Bstring::swap
Bstring swap(const long i, const long j)
Definition: Bstring.cpp:477
molgroup_kill
int molgroup_kill(Bmolgroup *molgroup)
Destroys a molecule group.
Definition: rwmolecule.cpp:374
View::backward
View backward()
Definition: View.h:115
verbose
int verbose
Bstring::canonical
Bstring canonical(int n)
Definition: Bstring.cpp:527
Vector3::length2
double length2()
Definition: Vector3.h:221
Bstring::compare
long compare(const Bstring &s)
Definition: Bstring.cpp:277
model_invert_views
long model_invert_views(Bmodel *model)
Invert views.
Definition: model_views.cpp:109
Bmodel::next
Bmodel * next
Definition: rwmodel.h:120
Bcomponent::sel
int sel
Definition: rwmodel.h:66
molgroup_find_transformation
Transform molgroup_find_transformation(Bmolgroup *molgroup1, Bmolgroup *molgroup2)
Determines the transformation between two groups of identical molecules.
Definition: mol_compare.cpp:51
Bcomponent::radius
float radius
Definition: rwmodel.h:62
views_from_models
View * views_from_models(Bmodel *model)
Returns a list of component views.
Definition: model_views.cpp:53
model
Bmodel * model
Definition: bshow.cpp:32
model_calculate_views
long model_calculate_views(Bmodel *model, Bstring &mode)
Calculates the views associated with each component.
Definition: model_views.cpp:263
component_plane
Vector3< double > component_plane(Bcomponent **comparray, double &offset)
Calculates a plane through an array of components.
Definition: model_util.cpp:933
Bstring
Definition: Bstring.h:29
View::matrix
Matrix3 matrix()
Definition: View.h:150
Bcomponent::link
Bcomponent * link[MAXLINK]
Definition: rwmodel.h:55
Matrix3::transpose
Matrix3 transpose() const
Definition: Matrix3.h:268
Bcomponent::next
Bcomponent * next
Definition: rwmodel.h:52
Vector3< double >
View::angle
double angle()
Definition: View.h:95
View
Definition: View.h:26
Bmodel
Definition: rwmodel.h:119
Transform::axis
Vector3< double > axis
Definition: Transform.h:28
rwimg.h
Header file for 2D and 3D image I/O.
model_neighbors.h
Functions to manipulate model component neighbors.
Bcomptype
Definition: rwmodel.h:25
model_center_of_mass
Vector3< double > model_center_of_mass(Bmodel *model)
Definition: model_util.cpp:475
Bmodel::comp
Bcomponent * comp
Definition: rwmodel.h:132
model_set_neighbors
int model_set_neighbors(Bmodel *model, int number)
Sets the desired number of components as neighbors for each component.
Definition: model_neighbors.cpp:28
Bcomponent::loc
Vector3< float > loc
Definition: rwmodel.h:58
bexit
int bexit(int value)
Exit function for cleanup and debugging.
Definition: utilities.cpp:273
component_normal
Vector3< double > component_normal(Bcomponent *comp)
Definition: model_views.cpp:172
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
mol_compare.h
Library routines used to compare sets of atomic coordinates.
read_molecule
Bmolgroup * read_molecule(const char *filename, const char *select, const char *paramfile)
The generalized function for reading molecular files.
Definition: rwmolecule.cpp:818
Bcomponent
Definition: rwmodel.h:51