| Bsoft 2.0.5 Bernard's software package

model_shell.cpp
Go to the documentation of this file.
1
9 #include "model_create.h"
10 #include "model_shell.h"
11 #include "model_color.h"
12 #include "model_util.h"
13 #include "model_transform.h"
14 #include "model_select.h"
15 #include "random_numbers.h"
16 #include "utilities.h"
17
18 // Declaration of global variables
19 extern int verbose; // Level of output to the screen
20
32 long model_add_shell(Bmodel* model, double add_distance, Bstring& nutype)
33 {
34 if ( !model ) return -1;
35 if ( !model->comp ) return 0;
36
37 Bcomptype* ct = model_add_type_by_id(model, nutype);
38
39 long i, ncomp;
40 Vector3<double> vv;
41 Bcomponent* comp;
42 Bcomponent* comp_new = NULL;
43 Bcomponent* comp_list = NULL;
44
45 for ( i=0, comp = model->comp; comp; comp = comp->next )
46 if ( i < comp->id.integer() ) i = comp->id.integer();
47
48 for ( ncomp=0, comp = model->comp; comp; comp = comp->next ) if ( comp->sel ) {
49 comp_new = component_add(&comp_new, comp->id);
50 if ( !comp_list ) comp_list = comp_new;
51 component_copy(comp, comp_new);
52 comp_new->id = Bstring(++i, "%d");
53 comp_new->type = ct;
54 vv = Vector3<double>(comp->view[0], comp->view[1], comp->view[2]);
55 comp_new->loc += vv * add_distance;
56 ncomp++;
57 }
58
59 for ( comp = model->comp; comp->next; comp = comp->next ) ;
60 if ( comp ) comp->next = comp_list;
61
62 if ( verbose ) {
63 cout << "Generated new shell" << endl;
64 cout << "New type: " << nutype << endl;
65 cout << "Distance added: " << add_distance << " A" << endl;
66 cout << "Components: " << ncomp << endl << endl;
67 }
68
69 return ncomp;
70 }
71
85 int model_adjust_shell_to_guide(Bmodel* model, Bmodel* gmod, double fraction, int curv_flag)
86 {
87 if ( fraction < 1e-3 || fraction > 1 ) fraction = 1;
88
89 int n;
90 double d;
91 Vector3<double> center;
92 Bcomponent* comp = NULL;
93 Bcomponent* gcomp = NULL;
94
95 // Calculate the center of the vertices in the guide model
96 for ( n=0, gcomp = gmod->comp; gcomp; gcomp = gcomp->next, n++ )
97 center += gcomp->loc;
98
99 if ( n ) center /= n;
100
101 if ( verbose ) {
102 cout << "Adjusting the model " << model->id << " to the guide polyhedron " << gmod->id << endl;
103 cout << "Fraction: " << fraction << endl;
104 cout << "Guide model center: " << center << endl << endl;
105 }
106
107 if ( model->fmap.length() < 1 && gmod->fmap.length() ) model->fmap = gmod->fmap;
108
109 // Calculate the component vectors in the guide model
110 for ( gcomp = gmod->comp; gcomp; gcomp = gcomp->next )
111 gcomp->vec = gcomp->loc;
112 // gcomp->vec = gcomp->loc - center;
113
114 for ( comp = model->comp; comp; comp = comp->next ) {
115 d = fraction * model_inside_outside(comp->loc, gmod, curv_flag, 0);
116 if ( !isfinite(d) ) cerr << "d not finite: " << d << endl;
117 d += comp->loc.normalize();
118 comp->loc *= d;
119 // comp->loc += center;
120 }
121
122 return 0;
123 }
124
139 Bmodel* model_components_to_shells(Bmodel* model, double distance, Bstring& nutype, int twod)
140 {
141 if ( !model ) return NULL;
142 if ( !model->comp ) return NULL;
143
144 if ( distance > 1.5*model->comp->radius ) distance = 1.5*model->comp->radius;
145 if ( nutype.length() < 1 ) nutype = "VER";
146
147 if ( verbose ) {
148 cout << "Generating new shell models from components:" << endl;
149 cout << "Number of components: " << model_component_count(model) << endl;
150 cout << "New type: " << nutype << endl;
151 cout << "Distance between components: " << distance << " A" << endl;
152 if ( twod ) cout << "Generating plane models" << endl;
153 }
154
155 long ncomp(0);
156 Bmodel* mp = NULL;
157 Bmodel* numod = NULL;
158 Bmodel* numod_list = NULL;
159 Bcomponent* comp = NULL;
160
161 for ( mp = model; mp; mp = mp->next ) {
162 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel ) {
163 if ( twod )
164 numod = model_create_circle(comp->radius, 0, distance);
165 else
166 numod = model_create_shell(0, comp->radius, distance);
167 numod = model_add(&numod_list, numod);
168 numod->id = mp->id + "_" + comp->id;
169 model_set_type(numod, nutype);
170 model_set_component_radius(numod, distance/2);
171 model_shift(numod, comp->loc);
172 numod->fmap = mp->fmap;
173 numod->img_num = mp->img_num;
174 model_color_uniformly(numod, comp->color);
175 ncomp += model_component_count(numod);
176 }
177 }
178
179 if ( verbose )
180 cout << "New components: " << ncomp << endl << endl;
181
182 return numod_list;
183 }
184
194 double model_sphericity(Bmodel* model)
195 {
196 if ( !model ) return 0;
197 if ( !model->sel ) return 0;
198
199 int ncomp;
200 double d, sph = 0, da = 0, ds = 0;
201
202 Vector3<double> com = model_center_of_mass(model);
203
204 Bcomponent* comp;
205
206 for ( ncomp=0, comp = model->comp; comp; comp = comp->next, ncomp++ ) {
207 d = (comp->loc - com).length();
208 da += d;
209 ds += d*d;
210 }
211
212 if ( ncomp ) {
213 da /= ncomp;
214 ds = ds/ncomp - da*da;
215 if ( ds > 0 ) sph = 1 - sqrt(ds)/da;
216 }
217
218 if ( verbose & VERB_PROCESS )
219 cout << "Sphericity: " << sph << endl << endl;
220
221 return sph;
222 }
223
234 double model_ellipsoidicity(Bmodel* model)
235 {
236 if ( !model ) return 0;
237 if ( !model->sel ) return 0;
238
239 int i, ncomp;
240 double d, ell = 0;
241 Vector3<double> c, c1, axis[3];
242 Vector3<double> alen = model_principal_axes(model, axis);
243
244 for ( i=0; i<3; i++ ) axis[i].normalize();
245
246 Vector3<double> com = model_center_of_mass(model);
247
248 Bcomponent* comp;
249
250 for ( ncomp=0, comp = model->comp; comp; comp = comp->next, ncomp++ ) {
251 c = comp->loc - com;
252 for ( i=0; i<3; i++ ) c1[i] = c.scalar(axis[i]);
253 c1 /= alen;
254 d = 1 - c1.length2();
255 ell += d*d;
256 }
257
258 ell = sqrt(1 - ell/ncomp);
259
260 if ( verbose & VERB_PROCESS )
261 cout << "Ellipsoidicity: " << ell << endl << endl;
262
263 return ell;
264 }
265
279 int model_curvature(Bmodel* model)
280 {
281 int i, ncomp;
282 double amax;
283 Bmodel* mp;
284 Bcomponent* comp;
285 Blink* link;
286
287 if ( verbose )
288 cout << "Calculating curvature" << endl << endl;
289
290 if ( verbose & VERB_PROCESS )
291 cout << "Model\tAverage\tMaximum" << endl;
292 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
293 mp->fom = 0;
294 amax = 0;
295 for ( comp = mp->comp; comp; comp = comp->next ) comp->fom = 0;
296 for ( link = mp->link; link; link = link->next ) {
297 link->fom = link->comp[0]->view.angle(link->comp[1]->view);
298 link->comp[0]->fom += link->fom;
299 link->comp[1]->fom += link->fom;
300 if ( amax < link->fom ) amax = link->fom;
301 }
302 for ( ncomp=0, comp = mp->comp; comp; comp = comp->next, ncomp++ ) {
303 for ( i=0; i<MAXLINK && comp->link[i]; i++ ) ;
304 if ( i ) comp->fom /= i;
305 mp->fom += comp->fom;
306 }
307 if ( ncomp ) mp->fom /= ncomp;
308 if ( verbose & VERB_PROCESS )
309 cout << mp->id << tab << mp->fom*180.0/M_PI << tab << amax*180.0/M_PI << endl;
310 mp->fom = amax;
311 }
312
313 return 0;
314 }
315
341 double model_inside_outside_fast(Vector3<double> vec, Bmodel* model, int curv_flag)
342 {
343 int i, ib, j;
344 double testangle, d, angle[3] = {10,10,10};
345 Vector3<double> tvec[3], vec3(vec[0], vec[1], vec[2]);
346 Matrix mat(3,3);
347 vector<double> w(3);
348 Bcomponent* comp;
349
350 double vec_len = vec3.normalize();
351
352 // Find the closest three vertices
353 for ( ib = 0, comp = model->comp; comp && ib < 3; comp = comp->next ) {
354 testangle = 0;
355 for ( i=ib=0; i<3; i++ ) if ( testangle < angle[i] ) { // Find the biggest angle
356 testangle = angle[i];
357 ib = i;
358 }
359 testangle = vec3.angle(comp->vec);
360 if ( testangle < 1e-30 ) {
361 return comp->vec.length() - vec_len;
362 }
363 if ( angle[ib] > testangle ) { // Test to replace the biggest angle
364 angle[ib] = testangle;
365 tvec[ib] = comp->vec;
366 }
367 }
368
369 for ( i=0; i<3; i++ ) {
370 for ( j=0; j<3; j++ )
371 mat[i][j] = tvec[j][i];
372 w[i] = vec3[i];
373 }
374
375 // double det = mat.LU_decomposition(w);
376 double det = mat.singular_value_decomposition(w);
377 if ( det < -1e20 ) {
378 cerr << "Error in model_inside_outside_fast: vec=" << vec << " det=" << det << endl;
379 cerr << mat << endl;
380 return 0;
381 }
382
383 if ( w[0]<0 || w[1]<0 || w[2]<0 )
384 if ( verbose & VERB_DEBUG )
385 cerr << "Warning: Negative weights: " <<
386 w[0] << " " << w[1] << " " << w[2] << " " << vec << endl;
387
388 // for ( i=0, d=0; i<3; i++ ) if ( w[i] > 0 ) d += w[i]; else w[i] = 0;
389 for ( i=0, d=0; i<3; i++ ) d += w[i];
390
391 if ( curv_flag ) {
392 if ( d ) for ( i=0; i<3; i++ ) w[i] /= d;
393 for ( i=0, d=0; i<3; i++ ) d += w[i] * tvec[i].length();
394 } else if ( d ) {
395 d = 1/d;
396 }
397
398 return d - vec_len;
399 }
400
401 double model_inside_outside(Vector3<double> vec, Bmodel* model, int curv_flag, int fast)
402 {
403 if ( fast ) return model_inside_outside_fast(vec, model, curv_flag);
404
405 int i, j, iw, ib;
406 double a, d, dmin = 1e30;
407 // double w[3], wb[3] = {0,0,0};
408 vector<double> w(3), wb(3,0);
409 Matrix mat(3,3);
410 Vector3<double> tvec[3], bvec[3], vec3(vec[0], vec[1], vec[2]);
411 Bcomponent* comp1;
412 Bcomponent* comp2;
413 Bcomponent* comp3;
414
415 double vec_len = vec3.normalize();
416
417 if ( !isfinite(vec_len) )
418 cerr << "Vector not finite: " << vec << " length=" << vec_len << endl;
419
420 for ( ib = 0, a = M_PI/16; ib < 3 && a < M_PI + 0.1; a *= 2 ) {
421 for ( comp1 = model->comp; comp1; comp1 = comp1->next ) {
422 tvec[0] = comp1->vec;
423 if ( vec3.angle(tvec[0]) < a ) {
424 for ( comp2 = comp1->next; comp2; comp2 = comp2->next ) {
425 tvec[1] = comp2->vec;
426 if ( vec3.angle(tvec[1]) < a ) {
427 for ( comp3 = comp2->next; comp3; comp3 = comp3->next ) {
428 tvec[2] = comp3->vec;
429 if ( vec3.angle(tvec[2]) < a ) {
430 for ( i=0; i<3; i++ ) {
431 // cout << tvec[i] << endl;
432 for ( j=0; j<3; j++ )
433 mat[i][j] = tvec[j][i];
434 w[i] = vec3[i];
435 }
436 if ( mat.check_for_singularity() < 1 ) {
437 mat.LU_decomposition(w);
438 for ( i=iw=0; i<3; i++ ) if ( w[i] >= 0 ) iw++;
439 if ( iw == 3 ) {
440 for ( i=0, d=0; i<3; i++ ) d += w[i];
441 if ( d > 1e-20 && isfinite(d) ) {
442 if ( dmin > d ) {
443 dmin = d;
444 for ( i=0; i<3; i++ ) {
445 wb[i] = w[i];
446 bvec[i] = tvec[i];
447 }
448 ib = iw;
449 }
450 }
451 }
452 }
453 }
454 }
455 }
456 }
457 }
458 }
459 }
460
461 if ( !isfinite(wb[0]) || !isfinite(wb[1]) || !isfinite(wb[2]) )
462 cerr << "Warning: Non-finite weights: " << wb[0] << " " << wb[1] << " " << wb[2] << endl;
463
464 if ( wb[0]<0 || wb[1]<0 || wb[2]<0 )
465 cerr << "Warning: Negative weights: " << wb[0] << " " << wb[1] << " " << wb[2] << endl;
466
467 for ( i=0, d=0; i<3; i++ ) d += wb[i];
468
469 if ( curv_flag ) {
470 if ( d ) for ( i=0; i<3; i++ ) wb[i] /= d;
471 for ( i=0, d=0; i<3; i++ ) d += wb[i] * bvec[i].length();
472 } else if ( d ) {
473 d = 1/d;
474 } else cout << "Distance = " << d << endl;
475
476 if ( !isfinite(d) )
477 cerr << "Weights and distance: " << wb[0] << " " << wb[1] << " " << wb[2] << " " << d << endl;
478
479 return d - vec_len;
480 }
481
482
483
distance
double distance(vector< T1 > &v1, vector< T2 > &v2)
Definition: Vector3.h:536
Bmodel::img_num
int img_num
Definition: rwmodel.h:127
MAXLINK
#define MAXLINK
Definition: rwmodel.h:14
Bcomponent::id
Bstring id
Definition: rwmodel.h:53
model_set_component_radius
long model_set_component_radius(Bmodel *model, double comprad)
Set the display radius for all components to a specific value.
Definition: rwmodel.cpp:1264
Bcomponent::type
Bcomptype * type
Definition: rwmodel.h:54
model_create.h
Library routines used for model creation.
Vector3::normalize
double normalize()
Definition: Vector3.h:236
Blink
Definition: rwmodel.h:82
Bmodel::id
Bstring id
Definition: rwmodel.h:121
Vector3::length
double length()
Definition: Vector3.h:222
model_create_shell
Bmodel * model_create_shell(long number, double radius, double distance)
Creates a sphere point model.
Definition: model_create.cpp:472
utilities.h
Header file for general utilities.
model_sphericity
double model_sphericity(Bmodel *model)
Calculates how close the model is to a spherical shape.
Definition: model_shell.cpp:194
model_util.h
Library routines used for model processing.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
model_shell.h
Library routines used for shell model processing.
Matrix::check_for_singularity
int check_for_singularity()
Definition: Matrix.h:188
model_component_count
int model_component_count(Bmodel *model)
Counts the total number of components.
Definition: rwmodel.cpp:635
Bstring::length
long length() const
Definition: Bstring.cpp:263
component_add
Bcomponent * component_add(Bcomponent **comp, Bstring &id)
Adds a component to a linked list.
Definition: rwmodel.cpp:267
Bmodel::sel
int sel
Definition: rwmodel.h:129
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
model_components_to_shells
Bmodel * model_components_to_shells(Bmodel *model, double distance, Bstring &nutype, int twod)
Generates a new set of models by vonverting each component to a shell model.
Definition: model_shell.cpp:139
Blink::comp
Bcomponent * comp[2]
Definition: rwmodel.h:84
Matrix::singular_value_decomposition
double singular_value_decomposition()
Singular value decomposition of a matrix .
Definition: matrix.cpp:177
model_color.h
Functions to color models.
Matrix::LU_decomposition
double LU_decomposition()
Matrix inversion by LU decomposition.
Definition: matrix.cpp:78
M_PI
#define M_PI
Definition: utilities.h:59
isfinite
bool isfinite(complex< T > &value)
Bcomponent::view
View view
Definition: rwmodel.h:59
Blink::next
Blink * next
Definition: rwmodel.h:83
Bcomponent::fom
float fom
Definition: rwmodel.h:65
Vector3::scalar
double scalar(const Vector3 &v) const
Definition: Vector3.h:247
model_shift
long model_shift(Bmodel *model, Vector3< double > shift)
Shifts a model.
Definition: model_transform.cpp:43
model_ellipsoidicity
double model_ellipsoidicity(Bmodel *model)
Calculates how close the model is to an ellipsoid shape.
Definition: model_shell.cpp:234
Vector3::angle
double angle(Vector3< T2 > &v)
Definition: Vector3.h:257
model_inside_outside_fast
double model_inside_outside_fast(Vector3< double > vec, Bmodel *model, int curv_flag)
Determines if a vector is inside or outside model boundaries.
Definition: model_shell.cpp:341
length
double length(vector< T > v)
Definition: Vector3.h:528
Vector3::length2
double length2()
Definition: Vector3.h:221
model_add_shell
long model_add_shell(Bmodel *model, double add_distance, Bstring &nutype)
Adds a shell to a model using selected components.
Definition: model_shell.cpp:32
Bmodel::next
Bmodel * next
Definition: rwmodel.h:120
Bcomponent::sel
int sel
Definition: rwmodel.h:66
model_add_type_by_id
Bcomptype * model_add_type_by_id(Bmodel *model, Bstring &id)
Add a type to a model if the identifier does not exist already.
Definition: rwmodel.cpp:411
Bcomponent::radius
float radius
Definition: rwmodel.h:62
model
Bmodel * model
Definition: bshow.cpp:32
Bmodel::fom
float fom
Definition: rwmodel.h:128
random_numbers.h
Header file for functions for creating random images.
Matrix
Definition: Matrix.h:21
Bstring
Definition: Bstring.h:29
verbose
int verbose
Bcomponent::link
Bcomponent * link[MAXLINK]
Definition: rwmodel.h:55
Bmodel::link
Blink * link
Definition: rwmodel.h:133
Bmodel::fmap
Bstring fmap
Definition: rwmodel.h:125
model_principal_axes
Vector3< double > model_principal_axes(Bmodel *model, Vector3< double > *eigenvec)
Calculates the principal axes of a model.
Definition: model_util.cpp:534
model_add
Bmodel * model_add(Bmodel **model, Bstring &id)
Adds a model to a linked list.
Definition: rwmodel.cpp:178
Bcomponent::vec
Vector3< float > vec
Definition: rwmodel.h:60
Bcomponent::next
Bcomponent * next
Definition: rwmodel.h:52
model_inside_outside
double model_inside_outside(Vector3< double > vec, Bmodel *model, int curv_flag, int fast)
Definition: model_shell.cpp:401
Vector3< double >
View::angle
double angle()
Definition: View.h:95
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
model_adjust_shell_to_guide
int model_adjust_shell_to_guide(Bmodel *model, Bmodel *gmod, double fraction, int curv_flag)
Adjusts a shell model to the faces of a polyhedral guide model.
Definition: model_shell.cpp:85
model_color_uniformly
int model_color_uniformly(Bmodel *model, RGBA< float > color)
Colors model components uniformly.
Definition: model_color.cpp:29
Bcomptype
Definition: rwmodel.h:25
model_center_of_mass
Vector3< double > model_center_of_mass(Bmodel *model)
Definition: model_util.cpp:475
model_set_type
int model_set_type(Bmodel *model, Bstring &set_type)
Reset the component types.
Definition: rwmodel.cpp:516
Bmodel::comp
Bcomponent * comp
Definition: rwmodel.h:132
model_curvature
int model_curvature(Bmodel *model)
Calculates the curvature associated with each link.
Definition: model_shell.cpp:279
model_select.h
Header file for reading and writing atomic model files.
Bcomponent::loc
Vector3< float > loc
Definition: rwmodel.h:58
Blink::fom
float fom
Definition: rwmodel.h:89
model_transform.h
Library routines used for model transformation.
Bcomponent::color
RGBA< float > color
Definition: rwmodel.h:63
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
model_create_circle
Bmodel * model_create_circle(double radius, double z, double distance)
Creates a circle with the given radius, height, and component separation.
Definition: model_create.cpp:897
Bcomponent
Definition: rwmodel.h:51