| Bsoft 2.0.5 Bernard's software package

model_select.cpp
Go to the documentation of this file.
1
9 #include "rwmodel.h"
10 #include "model_poly.h"
11 #include "model_views.h"
12 #include "model_compare.h"
13 #include "model_util.h"
14 #include "rwimg.h"
15 #include "qsort_functions.h"
16 #include "linked_list.h"
17 #include "utilities.h"
18
19 // Declaration of global variables
20 extern int verbose; // Level of output to the screen
21
36 long model_select(Bmodel* model, Bstring& selstr)
37 {
38 long n(0);
39 Bmodel* mp;
40 Bcomponent* comp;
41 Bcomptype* type;
42 Blink* link;
43
44 Bstring mod_id;
45 Bstring mod_type_id;
46 Bstring comp_id;
47 Bstring comp_type_id;
48 Bstring* list, *one;
49
50 if ( verbose & VERB_DEBUG )
51 cout << "DEBUG model_select: selstr=" << selstr << endl;
52
53 if ( selstr[0] == '#' ) {
54 if ( selstr.contains("@") ) {
55 mod_id = selstr.substr(1, selstr.index('@')-1);
56 comp_id = selstr.post('@');
57 } else if ( selstr.contains("%") ) {
58 mod_id = selstr.substr(1, selstr.index('%')-1);
59 comp_type_id = selstr.post('%');
60 } else {
61 mod_id = selstr.substr(1, selstr.length());
62 }
63 } else if ( selstr[0] == '^' ) {
64 if ( selstr.contains("@") ) {
65 mod_type_id = selstr.substr(1, selstr.index('@')-1);
66 comp_id = selstr.post('@');
67 } else if ( selstr.contains("%") ) {
68 mod_type_id = selstr.substr(1, selstr.index('%')-1);
69 comp_type_id = selstr.post('%');
70 } else {
71 mod_type_id = selstr.substr(1, selstr.length());
72 }
73 } else if ( selstr[0] == '@' ) {
74 comp_id = selstr.substr(1, selstr.length());
75 } else if ( selstr[0] == '%' ) {
76 comp_type_id = selstr.substr(1, selstr.length());
77 }
78
79 if ( verbose ) {
80 cout << "Selection identifiers:" << endl;
81 if ( mod_id.length() )
82 cout << "Model: " << mod_id << endl;
83 if ( mod_type_id.length() )
84 cout << "Model type: " << mod_type_id << endl;
85 if ( comp_id.length() )
86 cout << "Component: " << comp_id << endl;
87 if ( comp_type_id.length() )
88 cout << "Component type: " << comp_type_id << endl;
89 cout << endl;
90 }
91
92 if ( mod_id == "." || mod_type_id == "." ) {
93 for ( mp = model; mp; mp = mp->next ) mp->sel = 1;
94 } else {
95 if ( mod_id.length() ) {
96 list = mod_id.split(",");
97 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
98 for ( one = list; one && mp->id != *one; one = one->next ) ;
99 if ( !one ) mp->sel = 0;
100 }
101 string_kill(list);
102 }
103 if ( mod_type_id.length() ) {
104 list = mod_type_id.split(",");
105 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
106 for ( one = list; one && mp->type_id != *one; one = one->next ) ;
107 if ( !one ) mp->sel = 0;
108 }
109 string_kill(list);
110 }
111 }
112
113 if ( comp_type_id == "." ) {
114 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
115 for ( type = mp->type; type; type = type->next ) type->sel = 1;
116 for ( comp = mp->comp; comp; comp = comp->next ) comp->sel = 1;
117 }
118 } else if ( comp_type_id.length() ) {
119 list = comp_type_id.split(",");
120 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
121 for ( type = mp->type; type; type = type->next ) if ( type->sel ) {
122 for ( one = list; one && type->id != *one; one = one->next ) ;
123 if ( !one ) type->sel = 0;
124 }
125 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
126 comp->sel = comp->type->sel;
127 // for ( one = list; one && comp->type->id != *one; one = one->next ) ;
128 // if ( !one ) comp->sel = 0;
129 }
130 }
131 string_kill(list);
132 }
133
134 if ( comp_id == "." ) {
135 for ( mp = model; mp; mp = mp->next ) if ( mp->sel )
136 for ( comp = mp->comp; comp; comp = comp->next ) comp->sel = 1;
137 } else if ( comp_id.length() ) {
138 list = comp_id.split(",");
139 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
140 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
141 for ( one = list; one && comp->id != *one; one = one->next ) ;
142 if ( !one ) comp->sel = 0;
143 }
144 }
145 string_kill(list);
146 }
147
148 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
149 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) n++;
150 for ( link = mp->link; link; link = link->next )
151 if ( link->comp[0]->sel && link->comp[1]->sel ) link->sel = 1;
152 }
153
154 return n;
155 }
156
163 long model_select(Bmodel* model, long number)
164 {
165 long nsel(0), ntot(0);
166 Bmodel* mp = NULL;
167 Bcomponent* comp;
168
169 if ( verbose )
170 cout << "Selecting components with selection number " << number << endl;
171
172 for ( mp = model; mp; mp = mp->next )
173 for ( comp = mp->comp; comp; comp = comp->next ) ntot++;
174
175 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
176 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel ) {
177 if ( comp->sel != number ) comp->sel = 0;
178 nsel += ( comp->sel > 0 );
179 }
180 }
181
182 if ( verbose )
183 cout << "Number of components selected: " << nsel << " (" << nsel*100.0/ntot << " %)" << endl << endl;
184
185 return nsel;
186 }
187
193 long model_select_all(Bmodel* model)
194 {
195 long nsel(0);
196 Bmodel* mp = NULL;
197
198 for ( nsel=0, mp = model; mp; mp = mp->next, nsel++ ) mp->sel = 1;
199
200 return nsel;
201 }
202
208 long model_select_unknowns(Bmodel* model)
209 {
210 long nsel(0);
211 Bmodel* mp;
212
213 for ( nsel=0, mp = model; mp; mp = mp->next ) {
214 mp->sel = 0;
215 if ( mp->type_id.length() < 1 ) {
216 mp->sel = 1;
217 nsel++;
218 }
219 }
220
221 return nsel;
222 }
223
232 long model_reset_selection(Bmodel* model)
233 {
234 long nsel(0);
235 Bcomptype* type;
236 Bcomponent* comp;
237 Blink* link;
238 Bpolygon* poly;
239
240 if ( verbose & VERB_FULL )
241 cout << "Model " << model->id << ": reset selection" << endl;
242
243 model->sel = 1;
244 for ( type = model->type; type; type = type->next )
245 type->sel = 1;
246 for ( comp = model->comp; comp; comp = comp->next, nsel++ )
247 comp->sel = 1;
248 for ( link = model->link; link; link = link->next )
249 link->sel = 1;
250 for ( poly = model->poly; poly; poly = poly->next )
251 poly->sel = 1;
252
253 return nsel;
254 }
255
261 long model_unset_selection(Bmodel* model)
262 {
263 int nsel(0);
264 Bcomptype* type;
265 Bcomponent* comp;
266 Blink* link;
267 Bpolygon* poly;
268
269 for ( type = model->type; type; type = type->next )
270 type->sel = 0;
271 for ( comp = model->comp; comp; comp = comp->next, nsel++ )
272 comp->sel = 0;
273 for ( link = model->link; link; link = link->next )
274 link->sel = 0;
275 for ( poly = model->poly; poly; poly = poly->next )
276 poly->sel = 0;
277
278 return nsel;
279 }
280
286 long model_invert_selection(Bmodel* model)
287 {
288 int nsel(0);
289 Bcomponent* comp;
290
291 for ( comp = model->comp; comp; comp = comp->next, nsel++ )
292 if ( comp->sel ) comp->sel = 0;
293 else {
294 comp->sel = 1;
295 nsel++;
296 }
297
298 return nsel;
299 }
300
312 long model_select_sets(Bmodel* model, int size, int flag)
313 {
314 if ( !model || size <= 0 ) return 0;
315
316 long nsel(0), count(0), number(0), ntot(0);
317
318 Bmodel* mp;
319 Bcomponent* comp;
320
321 if ( verbose & VERB_LABEL )
322 cout << "Generating sets of " << size << " components each" << endl;
323
324 for ( nsel=0, mp = model; mp; mp = mp->next ) {
325 if ( flag && count ) {
326 count = 0;
327 number++;
328 }
329 for ( comp = mp->comp; comp; comp = comp->next, ntot++ ) {
330 if ( comp->sel > 0 ) {
331 if ( count >= size ) {
332 number++;
333 count = 0;
334 }
335 if ( number < 1 ) number = 1;
336 comp->sel = number;
337 count++;
338 nsel++;
339 }
340 }
341 }
342
343 if ( verbose & VERB_LABEL ) {
344 cout << "Number of sets generated: " << number << endl;
345 cout << "Number of components selected: " << nsel << " (" << nsel*100.0/ntot << " %)" << endl << endl;
346 }
347
348 return nsel;
349 }
350
351
359 long model_select_number_of_components(Bmodel* model, int ncomp_min, int ncomp_max)
360 {
361 if ( ncomp_min < 1 ) return 0;
362 if ( ncomp_min > ncomp_max ) ncomp_max = ncomp_min;
363
364 long n, nsel(0);
365 Bmodel* mp;
366 Bcomponent* comp;
367
368 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
369 for ( n=0, comp = mp->comp; comp; comp = comp->next ) n++;
370 if ( n >= ncomp_min && n <= ncomp_max ) {
371 mp->sel = 1;
372 nsel++;
373 } else mp->sel = 0;
374 }
375
376 if ( verbose & VERB_PROCESS )
377 cout << "Models with " << ncomp_min << " to " << ncomp_max << " components selected: " << nsel << endl << endl;
378
379 return nsel;
380 }
381
397 long model_select_closed(Bmodel* model, int closure_rule, int val_order)
398 {
399 long n(0), i;
400 Bmodel* mp;
401 Bcomponent* comp;
402 Bpolygon* poly;
403
404 if ( closure_rule == 2 && !model->poly ) model_poly_generate(model);
405
406 if ( verbose ) {
407 cout << "Selecting models based on fixed ";
408 if ( closure_rule == 1 ) cout << "valency of " << val_order << endl << endl;
409 else cout << "polygon order of " << val_order << endl << endl;
410 }
411
412 for ( mp = model; mp; mp = mp->next ) {
413 if ( !mp->comp ) mp->sel = 0;
414 if ( closure_rule == 1 ) {
415 for ( comp = mp->comp; comp && mp->sel; comp = comp->next ) {
416 for ( i=0; i<MAXLINK && comp->link[i]; i++ ) ;
417 if ( val_order ) {
418 if ( i != val_order ) mp->sel = 0;
419 } else {
420 val_order = i;
421 }
422 }
423 } else if ( closure_rule == 2 ) {
424 for ( poly = mp->poly; poly && mp->sel; poly = poly->next ) {
425 for ( i=0; i<MAXLINK && poly->comp[i]; i++ ) ;
426 if ( val_order ) {
427 if ( i != val_order ) mp->sel = 0;
428 } else {
429 val_order = i;
430 }
431 }
432 }
433 if ( mp->sel ) n++;
434 }
435
436 return n;
437 }
438
448 long model_select_fullerene(Bmodel* model)
449 {
450 long n(0);
451 Bmodel* mp;
452 Bpolygon* poly;
453
454 if ( !model->poly ) model_poly_generate(model);
455
456 if ( verbose )
457 cout << "Selecting fullerene models" << endl << endl;
458
459 for ( mp = model; mp; mp = mp->next ) {
460 for ( poly = mp->poly; poly && mp->sel; poly = poly->next )
461 if ( poly->number < 5 || poly->number > 6 ) mp->sel = 0;
462 if ( mp->sel ) n++;
463 }
464
465 return n;
466 }
467
477 long model_select_non_fullerene(Bmodel* model)
478 {
479 long n(0);
480 Bmodel* mp;
481 Bpolygon* poly;
482
483 if ( !model->poly ) model_poly_generate(model);
484
485 if ( verbose )
486 cout << "Selecting non-fullerene models" << endl << endl;
487
488 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
489 mp->sel = 0;
490 for ( poly = mp->poly; poly && mp->sel == 0; poly = poly->next )
491 if ( poly->number < 5 || poly->number > 6 ) mp->sel = 1;
492 if ( mp->sel ) n++;
493 }
494
495 return n;
496 }
497
508 long model_select_valence(Bmodel* model, int valence)
509 {
510 long n(0), v;
511 Bmodel* mp;
512 Bcomponent* comp;
513
514 if ( verbose )
515 cout << "Selecting components with valency " << valence << endl << endl;
516
517 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
518 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
519 comp->sel = 0;
520 for ( v=0; v<MAXLINK && comp->link[v]; v++ ) ;
521 if ( v == valence ) comp->sel = 1;
522 }
523 n++;
524 }
525
526 return n;
527 }
528
535 long model_select_polygons(Bmodel* model, int order)
536 {
537 if ( order < 1 ) return 0;
538
539 if ( !model->poly ) model_poly_generate(model);
540
541 long i;
542 Bmodel* mp;
543 Bcomponent* comp;
544 Bpolygon* poly;
545
546 if ( verbose )
547 cout << "Selecting polygons with order " << order << endl << endl;
548
549 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
550 for ( comp = mp->comp; comp; comp = comp->next ) comp->sel = 0;
551 for ( poly = mp->poly; poly; poly = poly->next ) if ( poly->number == order ) {
552 for ( i=0; i<MAXLINK && poly->comp[i]; i++ )
553 poly->comp[i]->sel = 1;
554 }
555 }
556
557 return 0;
558 }
559
566 long model_select_first(Bmodel* model, int first)
567 {
568 long n, nsel(0);
569 Bmodel* mp;
570 Bcomponent* comp;
571
572 for ( n=0, mp = model; mp; mp = mp->next ) {
573 for ( comp = mp->comp; comp; comp = comp->next, n++ ) {
574 if ( comp->sel > 0 && n < first ) {
575 comp->sel = 1;
576 nsel++;
577 } else comp->sel = 0;
578 }
579 }
580
581 return nsel;
582 }
583
590 long model_select_in_mask(Bmodel* model, Bimage* pmask)
591 {
592 long nsel(0), ntot(0);
593 Bmodel* mp;
594 Bcomponent* comp;
595 Vector3<double> loc;
596
597 if ( verbose )
598 cout << "Deselecting components outside mask " << pmask->file_name() << endl;
599
600 for ( ntot=0, mp = model; mp; mp = mp->next ) {
601 for ( comp = mp->comp; comp; comp = comp->next, ntot++ ) {
602 loc = comp->loc/pmask->sampling() + pmask->image->origin();
603 // cout << comp->id << tab << loc << tab << pmask->get(0, loc) << endl;
604 if ( pmask->get(0, loc) < 0.5 ) comp->sel = 0;
605 else nsel += (comp->sel > 0);
606 }
607 }
608
609 if ( verbose )
610 cout << "Number of components selected: " << nsel << " (" << nsel*100.0/ntot << " %)" << endl << endl;
611
612 return nsel;
613 }
614
623 long model_delete(Bmodel** model)
624 {
625 long nmod(0), ncomp(0), nlink(0), nmdel(0), ncdel(0), nldel(0);
626 Bmodel* mp_prev;
627 Bmodel* mp;
628 Bcomponent* comp;
629 Bcomponent* comp_prev;
630 Blink* link;
631 Blink* link_prev;
632
633 if ( verbose )
634 cout << "Deleting models and model elements" << endl << endl;
635
636 for ( mp = mp_prev = *model; mp; ) {
637 if ( mp->sel < 0 ) {
638 // if ( verbose & VERB_PROCESS )
639 // cout << "Model: " << mp->id << endl;
640 if ( mp == *model ) {
641 mp_prev = *model = mp->next;
642 mp->next = NULL;
643 model_kill(mp);
644 mp = mp_prev;
645 } else {
646 mp_prev->next = mp->next;
647 mp->next = NULL;
648 model_kill(mp);
649 mp = mp_prev->next;
650 }
651 nmdel++;
652 } else {
653 mp_prev = mp;
654 mp = mp->next;
655 nmod++;
656 }
657 }
658
659 for ( mp = *model; mp; mp = mp->next ) {
660 // if ( verbose & VERB_PROCESS )
661 // cout << "Model: " << mp->id << endl;
662 for ( link = link_prev = mp->link; link; ) {
663 if ( link->sel < 0 || link->comp[0]->sel < 0 || link->comp[1]->sel < 0 ) {
664 if ( link == mp->link ) {
665 link_prev = mp->link = link->next;
666 delete link;
667 link = link_prev->next;
668 } else {
669 link_prev->next = link->next;
670 delete link;
671 link = link_prev->next;
672 }
673 nldel++;
674 } else {
675 link_prev = link;
676 link = link->next;
677 nlink++;
678 }
679 }
680 for ( comp = comp_prev = mp->comp; comp; ) {
681 if ( comp->sel < 0 ) {
682 if ( comp == mp->comp ) {
683 comp_prev = mp->comp = comp->next;
684 component_kill(comp);
685 comp = comp_prev;
686 } else {
687 comp_prev->next = comp->next;
688 component_kill(comp);
689 comp = comp_prev->next;
690 }
691 ncdel++;
692 } else {
693 comp_prev = comp;
694 comp = comp->next;
695 ncomp++;
696 }
697 }
698 }
699
700 nmod += nmdel;
701 ncomp += ncdel;
702 nlink += nldel;
703
704 if ( verbose & VERB_PROCESS ) {
705 if ( nmod ) cout << "Number of models deleted: " << nmdel << " (" << nmdel*100.0/nmod << " %)" << endl;
706 if ( ncomp ) cout << "Number of components deleted: " << ncdel << " (" << ncdel*100.0/ncomp << " %)" << endl;
707 if ( nlink ) cout << "Number of links deleted: " << nldel << " (" << nldel*100.0/nlink << " %)" << endl;
708 cout << endl;
709 }
710
711 return ncomp - ncdel;
712 }
713
720 long model_delete_comp_type(Bmodel* model, Bstring& comptype)
721 {
722 long n(0);
723 Bmodel* mp;
724 Bcomponent* comp, *comp_prev;
725 Bcomptype* ct, *ctp;
726 Blink* link;
727
728 for ( mp = model; mp; mp = mp->next ) {
729 ct = model_get_type(mp, comptype);
730 for ( link = mp->link; link; ) {
731 if ( link->comp[0]->type == ct || link->comp[1]->type == ct )
732 link = (Blink *) remove_item((char **)&mp->link, (char *)link, sizeof(Blink));
733 else
734 link = link->next;
735 }
736 for ( comp = comp_prev = mp->comp; comp; ) {
737 if ( comp->type == ct ) {
738 if ( comp == mp->comp ) {
739 comp_prev = mp->comp = comp->next;
740 component_kill(comp);
741 comp = comp_prev;
742 } else {
743 comp_prev->next = comp->next;
744 component_kill(comp);
745 comp = comp_prev->next;
746 }
747 } else {
748 comp_prev = comp;
749 comp = comp->next;
750 n++;
751 }
752 }
753 for ( ct = ctp = mp->type; ct; ) {
754 if ( verbose & VERB_DEBUG )
755 cout << "DEBUG model_delete_comp_type: type=" << ct->id << endl;
756 if ( ct->id == comptype ) {
757 if ( ct == mp->type ) {
758 ctp = mp->type = ct->next;
759 comp_type_kill(ct);
760 ct = ctp;
761 } else {
762 ctp->next = ct->next;
763 comp_type_kill(ct);
764 ct = ctp->next;
765 }
766 } else {
767 ctp = ct;
768 ct = ct->next;
769 }
770 }
771 }
772
773 return n;
774 }
775
781 long model_delete_non_selected(Bmodel** model)
782 {
783 long nmod(0), ncomp(0), nlink(0), nmdel(0), ncdel(0), nldel(0);
784 Bmodel* mp_prev;
785 Bmodel* mp;
786 Bcomponent* comp;
787 Bcomponent* comp_prev;
788 Blink* link;
789 Blink* link_prev;
790
791 if ( verbose & VERB_PROCESS )
792 cout << "Deleting non-selected components" << endl;
793
794 for ( mp = mp_prev = *model; mp; ) {
795 if ( verbose & VERB_PROCESS )
796 cout << "Model: " << mp->id << endl;
797 if ( mp->sel < 1 ) {
798 if ( mp == *model ) {
799 mp_prev = *model = mp->next;
800 mp->next = NULL;
801 model_kill(mp);
802 mp = mp_prev;
803 } else {
804 mp_prev->next = mp->next;
805 mp->next = NULL;
806 model_kill(mp);
807 mp = mp_prev->next;
808 }
809 nmdel++;
810 } else {
811 for ( link = link_prev = mp->link; link; ) {
812 if ( link->sel < 1 || link->comp[0]->sel < 1 || link->comp[1]->sel < 1 ) {
813 link = (Blink *) remove_item((char **)&link_prev, (char *)link, sizeof(Blink));
814 if ( link_prev == link ) mp->link = link;
815 nldel++;
816 } else {
817 link_prev = link;
818 link = link->next;
819 nlink++;
820 }
821 }
822 for ( comp = comp_prev = mp->comp; comp; ) {
823 if ( comp->sel < 1 ) {
824 if ( comp == mp->comp ) {
825 comp_prev = mp->comp = comp->next;
826 component_kill(comp);
827 comp = comp_prev;
828 } else {
829 comp_prev->next = comp->next;
830 component_kill(comp);
831 comp = comp_prev->next;
832 }
833 ncdel++;
834 } else {
835 comp_prev = comp;
836 comp = comp->next;
837 ncomp++;
838 }
839 }
840 mp_prev = mp;
841 mp = mp->next;
842 nmod++;
843 }
844 }
845
846 model_count_component_types(*model);
847
848 nmod += nmdel;
849 ncomp += ncdel;
850 nlink += nldel;
851
852 if ( verbose & VERB_PROCESS ) {
853 if ( nmod ) cout << "Number of models deleted: " << nmdel << " (" << nmdel*100.0/nmod << " %)" << endl;
854 if ( ncomp ) cout << "Number of components deleted: " << ncdel << " (" << ncdel*100.0/ncomp << " %)" << endl;
855 if ( nlink ) cout << "Number of links deleted: " << nldel << " (" << nldel*100.0/nlink << " %)" << endl;
856 cout << endl;
857 }
858
859 return ncomp - ncdel;
860 }
861
870 long model_selection_stats(Bmodel* model)
871 {
872 if ( verbose & VERB_DEBUG )
873 cout << "DEBUG model_selection_stats: " << model->id << endl;
874
875 long i, h;
876 long nmod(0), ncomp(0), nlink(0), npoly(0);
877 long nmods(0), ncomps(0), nlinks(0), npolys(0);
878 long n, nmt(0), nct(0), nv[1000];
879 int val[MAXLINK];
880 double fomavg(0), fomstd(0), fmin(1e30), fmax(-1e30);
881 Vector3<double> cmin(1e10, 1e10, 1e10), cmax(-1e10, -1e10, -1e10), com;
882 Bmodel* mp = NULL;
883 Bcomponent* comp = NULL;
884 Bcomptype* type = NULL;
885 Blink* link = NULL;
886 Bpolygon* poly = NULL;
887 Bstring* modtypelist = NULL;
888 Bstring* modtype = NULL;
889 Bstring* comptypelist = NULL;
890 Bstring* comptype = NULL;
891 Bstring* temptype = NULL;
892 Bstring* typefilelist = NULL;
893 Bstring* typefile = NULL;
894
895 for ( i=0; i<MAXLINK; i++ ) val[i] = 0;
896 for ( i=0; i<1000; i++ ) nv[i] = 0;
897
898 for ( mp = model; mp; mp = mp->next, nmod++ ) {
899 for ( comp = mp->comp; comp; comp = comp->next ) ncomp++;
900 for ( link = mp->link; link; link = link->next ) nlink++;
901 for ( poly = mp->poly; poly; poly = poly->next ) npoly++;
902 }
903
904 if ( verbose & VERB_DEBUG )
905 cout << "DEBUG model_selection_stats: nmod=" << nmod << " ncomp=" << ncomp
906 << " nlink=" << nlink << " npoly=" << npoly << endl;
907
908 // Compile temporary lists of model and component types
909 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
910 nmods++;
911 if ( mp->type_id.length() < 1 ) mp->type_id = "Unknown";
912 for ( temptype = modtypelist; temptype && *temptype != mp->type_id; temptype = temptype->next ) ;
913 if ( !temptype ) {
914 modtype = string_add(&modtype, mp->type_id);
915 if ( !modtypelist ) modtypelist = modtype;
916 nmt += 3;
917 }
918 for ( type = mp->type; type; type = type->next ) {
919 for ( temptype = comptypelist; temptype && *temptype != type->id; temptype = temptype->next ) ;
920 if ( !temptype ) {
921 comptype = string_add(&comptype, type->id);
922 if ( !comptypelist ) comptypelist = comptype;
923 typefile = string_add(&typefile, type->fmod);
924 if ( !typefilelist ) typefilelist = typefile;
925 nct++;
926 }
927 }
928 }
929
930 if ( verbose & VERB_DEBUG )
931 cout << "DEBUG model_selection_stats: nmods=" << nmods << " nmt=" << nmt << " nct=" << nct << endl;
932
933 if ( nmods < 1 ) {
934 cerr << "No models selected!" << endl << endl;
935 return 0;
936 }
937
938 if ( nmt < 3 ) nmt = 3;
939 if ( nct < 1 ) nct = 1;
940
941 // Sort the temporary lists
942 if ( modtypelist ) string_sort(modtypelist, 0, 1);
943 if ( comptypelist ) string_sort(comptypelist, 0, 1);
944
945 // Rearrange associated file names
946 for ( temptype = comptypelist, typefile = typefilelist; temptype && typefile; temptype = temptype->next, typefile = typefile->next ) {
947 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
948 for ( type = mp->type; type && *temptype != type->id; type = type->next ) ;
949 if ( type ) *typefile = type->fmod;
950 }
951 }
952
953 int* nvert = new int[nmt];
954 int* nmodtype = new int[nmt];
955 double* modfom = new double[nmt];
956 int* ncomptype = new int[nct];
957 double* compfom = new double[nct];
958
959 for ( i=0; i<nmt; i++ ) modfom[i] = nvert[i] = nmodtype[i] = 0;
960 for ( i=0; i<nct; i++ ) compfom[i] = ncomptype[i] = 0;
961
962 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
963 if ( verbose & VERB_DEBUG )
964 cout << "DEBUG model_selection_stats: model id=" << mp->id << endl;
965 for ( n=0, comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) n++;
966 if ( n < 1000 ) nv[n]++;
967 for ( i=0, temptype = modtypelist; temptype && *temptype != mp->type_id; temptype = temptype->next, i+=3 ) ;
968 i += mp->hand + 1;
969 if ( i < nmt ) {
970 nvert[i] = n;
971 nmodtype[i]++;
972 modfom[i] += mp->fom;
973 }
974 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
975 if ( verbose & VERB_DEBUG )
976 cout << "DEBUG model_selection_stats: component id=" << comp->id << " ncomps=" << ncomps << endl;
977 for ( i=0, temptype = comptypelist; temptype && *temptype != comp->type->id; temptype = temptype->next, i++ ) ;
978 if ( i < nct ) {
979 ncomptype[i]++;
980 compfom[i] += comp->fom;
981 }
982 com += comp->loc;
983 cmin = cmin.min(comp->loc);
984 cmax = cmax.max(comp->loc);
985 if ( fmin > comp->fom ) fmin = comp->fom;
986 if ( fmax < comp->fom ) fmax = comp->fom;
987 fomavg += comp->fom;
988 fomstd += comp->fom*comp->fom;
989 ncomps++;
990 for ( i=0; i<MAXLINK && comp->link[i]; i++ ) ;
991 if ( i < MAXLINK ) val[i]++;
992 }
993 for ( link = mp->link; link; link = link->next )
994 if ( link->sel ) nlinks++;
995 for ( poly = mp->poly; poly; poly = poly->next )
996 if ( poly->sel ) npolys++;
997 }
998
999 if ( ncomps ) {
1000 com /= ncomps;
1001 fomavg /= ncomps;
1002 fomstd = fomstd/ncomps - fomavg*fomavg;
1003 if ( fomstd > 0 ) fomstd = sqrt(fomstd);
1004 else fomstd = 0;
1005 }
1006
1007 if ( verbose ) {
1008 cout << "Models: " << nmod << " (" << nmods << ")" << endl;
1009 cout << "Components: " << ncomp << " (" << ncomps << ")" << endl;
1010 cout << "Links: " << nlink << " (" << nlinks << ")" << endl;
1011 cout << "Polygons: " << npoly << " (" << npolys << ")" << endl << endl;
1012 if ( ncomps ) {
1013 cout << "Center-of-mass: " << com << endl;
1014 cout << "Coordinate minima: " << cmin << endl;
1015 cout << "Coordinate maxima: " << cmax << endl;
1016 cout << "Selected FOM minimum & maximum: " << fmin << " " << fmax << endl;
1017 cout << "Selected FOM average & stdev: " << fomavg << " " << fomstd << endl << endl;
1018 }
1019 cout << "Model sizes:\nVert\tCount" << endl;
1020 for ( i=n=0; i<1000; i++ ) if ( nv[i] ) {
1021 cout << i << tab << nv[i] << endl;
1022 n += nv[i];
1023 }
1024 cout << "Total\t" << n << endl << endl;
1025 cout << "Model types:\nType\tVert\tHand\tCount\tFOM" << endl;
1026 for ( i=0, modtype = modtypelist; i<nmt && modtype; modtype = modtype->next, i+=3 )
1027 for ( h=i; h<i+3; h++ )
1028 if ( nmodtype[h] ) cout << *modtype << tab << nvert[h] << tab
1029 << h%3 - 1 << tab << nmodtype[h] << tab << modfom[h]/nmodtype[h] << endl;
1030 cout << endl;
1031 cout << "Component types:\nType\tHand\tCount\tFOM\tFile" << endl;
1032 for ( i=0, comptype = comptypelist, typefile = typefilelist;
1033 i<nct && comptype && typefile; comptype = comptype->next, typefile = typefile->next, i++ ) {
1034 if ( ncomptype[i] ) compfom[i] /= ncomptype[i];
1035 cout << *comptype << tab << component_hand(*comptype) << tab <<
1036 ncomptype[i] << tab << compfom[i] << tab << *typefile << endl;
1037 }
1038 cout << endl;
1039 cout << "Valence\tCount" << endl;
1040 for ( i=0; i<MAXLINK; i++ ) if ( val[i] ) cout << i << tab << val[i] << endl;
1041 cout << endl;
1042 }
1043
1044 string_kill(modtypelist);
1045 string_kill(comptypelist);
1046 string_kill(typefilelist);
1047 delete[] nvert;
1048 delete[] nmodtype;
1049 delete[] modfom;
1050 delete[] ncomptype;
1051 delete[] compfom;
1052
1053 return ncomps;
1054 }
1055
1063 long model_type_from_selection(Bmodel* model, Bstring* comp_type, Bstring& filename)
1064 {
1065 long i, nname, nselnum, ntype;
1066 Bmodel* mp = NULL;
1067 Bcomponent* comp = NULL;
1068 Bcomptype* ct = NULL;
1069 Bstring* ct_name;
1070 Bstring base = model->type->id;
1071 Bstring id;
1072
1073 for ( nname = 0, ct_name = comp_type; ct_name; ct_name = ct_name->next )
1074 if ( ct_name->length() > 0 ) nname++;
1075
1076 for ( ntype = 0, mp = model; mp; mp = mp->next ) {
1077 for ( i=0, ct = mp->type; ct; ct = ct->next ) i++;
1078 if ( ntype < i ) ntype = i;
1079 }
1080
1081 for ( nselnum = 0, mp = model; mp; mp = mp->next )
1082 for ( comp = mp->comp; comp; comp = comp->next )
1083 if ( nselnum < comp->sel ) nselnum = comp->sel;
1084
1085 if ( verbose )
1086 cout << "Creating %d component types" << nselnum << endl << endl;
1087
1088 if ( ntype != nselnum ) {
1089 if ( nname == nselnum ) {
1090 for ( mp = model; mp; mp = mp->next ) {
1091 comp_type_list_kill(mp->type);
1092 mp->type = NULL;
1093 if ( verbose & VERB_FULL )
1094 cout << "Model: " << mp->id << endl;
1095 for ( i=0, ct_name = comp_type; i<nselnum && ct_name; i++, ct_name = ct_name->next ) {
1096 if ( filename.length() )
1097 ct = model_add_type_by_id_and_filename(mp, *ct_name, filename, 0);
1098 else
1099 ct = model_add_type_by_id(mp, *ct_name);
1100 if ( verbose & VERB_FULL )
1101 cout << "\tType: " << ct->id << endl;
1102 }
1103 }
1104 } else {
1105 if ( comp_type && comp_type->length() ) base = *comp_type;
1106 for ( mp = model; mp; mp = mp->next ) {
1107 comp_type_list_kill(mp->type);
1108 mp->type = NULL;
1109 if ( verbose & VERB_FULL )
1110 cout << "Model: " << mp->id << endl;
1111 for ( i=0; i<nselnum; i++ ) {
1112 id = base + Bstring(i+1, "%03d");
1113 if ( filename.length() )
1114 ct = model_add_type_by_id_and_filename(mp, id, filename, 0);
1115 else
1116 ct = model_add_type_by_id(mp, id);
1117 if ( verbose & VERB_FULL )
1118 cout << "\tType: " << ct->id << endl;
1119 }
1120 }
1121 }
1122 } else if ( nname == ntype ) {
1123 for ( mp = model; mp; mp = mp->next )
1124 for ( ct = mp->type, ct_name = comp_type; ct && ct_name; ct = ct->next, ct_name = ct_name->next )
1125 ct->id = *ct_name;
1126 }
1127
1128 for ( mp = model; mp; mp = mp->next )
1129 for ( i=0, ct = mp->type; ct; ct = ct->next, i++ ) {
1130 ct->fmod = filename;
1131 ct->num = i;
1132 }
1133
1134 for ( mp = model; mp; mp = mp->next ) {
1135 for ( comp = mp->comp; comp; comp = comp->next ) {
1136 for ( i=1, ct = mp->type; i<nselnum && i<comp->sel && ct; i++, ct = ct->next ) ;
1137 if ( ct ) comp->type = ct;
1138 }
1139 }
1140
1141 return nselnum;
1142 }
1143
1154 long model_fom_deselect(Bmodel* model, double fom_cutoff)
1155 {
1156 long nsel(0);
1157 Bmodel* mp = NULL;
1158 Bcomponent* comp = NULL;
1159
1160 for ( nsel=0, mp = model; mp; mp = mp->next ) if ( mp->sel ) {
1161 for ( comp = mp->comp; comp; comp = comp->next ) {
1162 if ( comp->fom < fom_cutoff ) comp->sel = 0;
1163 if ( comp->sel > 0 ) nsel++;
1164 }
1165 }
1166
1167 return nsel;
1168 }
1169
1180 long model_fom_max_fraction_deselect(Bmodel* model, double fom_fraction)
1181 {
1182 if ( fom_fraction > 1 ) fom_fraction = 0.5;
1183
1184 long nsel(0);
1185 double fom_max = 1e-6, fom_cut;
1186 Bmodel* mp = NULL;
1187 Bcomponent* comp = NULL;
1188
1189 for ( nsel=0, mp = model; mp; mp = mp->next ) if ( mp->sel )
1190 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 )
1191 if ( fom_max < comp->fom ) fom_max = comp->fom;
1192
1193 fom_cut = fom_fraction*fom_max;
1194
1195 for ( nsel=0, mp = model; mp; mp = mp->next ) if ( mp->sel ) {
1196 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1197 if ( comp->fom < fom_cut ) comp->sel = 0;
1198 if ( comp->sel > 0 ) nsel++;
1199 }
1200 }
1201
1202 return nsel;
1203 }
1204
1215 long models_radius_deselect(Bmodel* model, double minrad, double maxrad)
1216 {
1217 if ( maxrad < 1e-3 ) maxrad = 1e30;
1218
1219 long nsel(0), ntot(0);
1220 double len;
1221 Bmodel* mp = NULL;
1222 Bcomponent* comp = NULL;
1223
1224 if ( verbose )
1225 cout << "Deselecting components outside " << minrad << " - " << maxrad << " A" << endl;
1226
1227 for ( ntot=0, mp = model; mp; mp = mp->next )
1228 for ( comp = mp->comp; comp; comp = comp->next ) ntot++;
1229
1230 for ( nsel=0, mp = model; mp; mp = mp->next ) if ( mp->sel ) {
1231 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1232 len = comp->loc.length();
1233 if ( len < minrad || len > maxrad ) comp->sel = -1;
1234 if ( comp->sel > 0 ) nsel++;
1235 }
1236 }
1237
1238 if ( verbose )
1239 cout << "Number of components selected: " << nsel << " (" << nsel*100.0/ntot << " %)" << endl << endl;
1240
1241 return nsel;
1242 }
1243
1254 long model_fom_histogram(Bmodel* model, double fom_step)
1255 {
1256 if ( fom_step < 0.001 ) fom_step = 0.001;
1257
1258 long n;
1259 double fmin = 1e30, fmax = -1e30, pc;
1260 Bmodel* mp = NULL;
1261 Bcomponent* comp = NULL;
1262
1263 for ( n=0, mp = model; mp; mp = mp->next ) if ( mp->sel ) {
1264 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1265 if ( comp->fom < fmin ) fmin = comp->fom;
1266 if ( comp->fom > fmax ) fmax = comp->fom;
1267 n++;
1268 }
1269 }
1270
1271 int i, sum, nhc(0), nh = (int) ((fmax - fmin)/fom_step + 1);
1272 int* hist = new int[nh];
1273 for ( i=0; i<nh; i++ ) hist[i] = 0;
1274
1275 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
1276 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1277 i = (int) ((comp->fom - fmin)/fom_step);
1278 if ( i >= 0 && i < nh ) {
1279 hist[i]++;
1280 nhc++;
1281 }
1282 }
1283 }
1284
1285 cout << "FOM histogram:\nBin\tValue\tCount\tSum\t%" << endl;
1286 for ( i=0, sum=0; i<nh; i++ ) {
1287 sum += hist[i];
1288 pc = sum*100.0/n;
1289 cout << i << tab << (i+0.5)*fom_step + fmin << tab << hist[i] << tab << sum << tab << pc << endl;
1290 }
1291 cout << endl;
1292
1293 delete[] hist;
1294
1295 return n;
1296 }
1297
1307 long model_fom_ranking(Bmodel* model, int nrank)
1308 {
1309 if ( nrank < 2 ) nrank = 2;
1310
1311 long i, n(0), nsel;
1312 Bmodel* mp = NULL;
1313 Bcomponent* comp = NULL;
1314 Bcomptype* ct = NULL, *ctp;
1315 Bstring ct_id;
1316
1317 if ( verbose )
1318 cout << "Ranking selection into %d levels" << nrank << endl << endl;
1319
1320 model_count_component_types(model);
1321
1322 for ( nsel=0, mp = model; mp; mp = mp->next ) if ( mp->sel )
1323 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) nsel++;
1324
1325 int_float* rank = new int_float[nsel];
1326
1327 for ( nsel=0, mp = model; mp; mp = mp->next ) if ( mp->sel ) {
1328 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1329 rank[nsel].i = nsel;
1330 rank[nsel].f = comp->fom;
1331 nsel++;
1332 }
1333 }
1334
1335 qsort((void *) rank, nsel, sizeof(int_float),
1336 (int (*)(const void *, const void *)) QsortLargeToSmallIntFloat);
1337
1338 int* sel = new int[nsel];
1339 for ( i=0; i<nsel; i++ ) sel[i] = 0;
1340
1341 for ( i=0; i<nsel; i++ ) {
1342 n = nrank - (i*nrank)/nsel;
1343 sel[rank[i].i] = n;
1344 }
1345
1346 for ( nsel=0, mp = model; mp; mp = mp->next ) if ( mp->sel ) {
1347 if ( verbose & VERB_DEBUG )
1348 cout << "DEBUG model_fom_ranking: model=" << mp->id << " map=" << mp->fmap << endl;
1349 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1350 comp->sel = sel[nsel];
1351 ct = comp->type;
1352 ct->count--;
1353 ct_id = ct->id + Bstring(comp->sel, "%03d");
1354 comp->type = model_add_type_by_id_and_filename(mp, ct_id, ct->fmod, ct->num);
1355 comp->type->sel = comp->sel;
1356 comp->type->count++;
1357 comp->type->mass = ct->mass;
1358 nsel++;
1359 }
1360 for ( ct = ctp = mp->type; ct; ) {
1361 if ( verbose & VERB_DEBUG )
1362 cout << "DEBUG model_fom_ranking: type=" << ct->id << " num=" << ct->count << endl;
1363 if ( ct->count < 1 ) {
1364 if ( ct == mp->type ) {
1365 ctp = mp->type = ct->next;
1366 comp_type_kill(ct);
1367 ct = ctp;
1368 } else {
1369 ctp->next = ct->next;
1370 comp_type_kill(ct);
1371 ct = ctp->next;
1372 }
1373 } else {
1374 ctp = ct;
1375 ct = ct->next;
1376 }
1377 }
1378 }
1379
1380 delete[] sel;
1381 delete[] rank;
1382
1383 return n;
1384 }
1385
1396 long model_delete_overlapped_components(Bmodel** model, double distance)
1397 {
1398 Bmodel* mp;
1399 Bcomponent *comp1, *comp2;
1400
1401 for ( mp = *model; mp; mp = mp->next ) if ( mp->sel ) {
1402 for ( comp1 = mp->comp; comp1->next; comp1 = comp1->next ) if ( comp1->sel ) {
1403 for ( comp2 = comp1->next; comp2; comp2 = comp2->next ) if ( comp2->sel ) {
1404 if ( comp1->loc.distance(comp2->loc) < distance )
1405 comp2->sel = 0;
1406 }
1407 }
1408 }
1409
1410 model_delete_non_selected(model);
1411
1412 return 0;
1413 }
1414
1425 long model_average_overlapped_components(Bmodel* model, double distance)
1426 {
1427 Matrix dm = model_distance_matrix(model, 0);
1428
1429 if ( verbose ) {
1430 cout << "Consolidating components:" << endl;
1431 cout << "Distance criterion: " << distance << endl;
1432 cout << "Number of components: " << dm.rows() << endl << endl;
1433 }
1434
1435 long n, i, j;
1436 Bcomponent* comp;
1437 Bcomponent* comp2;
1438
1439 for ( i=0, comp = model->comp; comp; comp = comp->next, i++ ) if ( comp->sel ) {
1440 n = 1;
1441 for ( j=0, comp2 = model->comp; comp2; comp2 = comp2->next, j++ ) if ( i != j ) {
1442 if ( dm[i][j] < distance ) {
1443 comp->loc += comp2->loc;
1444 comp->fom += comp2->fom;
1445 n++;
1446 comp2->sel = 0;
1447 }
1448 }
1449 if ( n > 1 ) {
1450 comp->loc /= n;
1451 comp->fom /= n;
1452 }
1453 }
1454
1455 return model_delete_non_selected(&model);
1456 }
1457
1458
1468 long model_prune_simple(Bmodel* model, double mindist)
1469 {
1470 long n, ns, ndel(0);
1471 Bmodel* mp;
1472 Bcomponent* comp;
1473 Bcomponent* comp2;
1474
1475 for ( n=ns=0, comp = model->comp; comp; comp = comp->next, n++ ) if ( comp->sel > 0 ) ns++;
1476
1477 if ( verbose ) {
1478 cout << "Pruning a set of solutions based on distance:" << endl;
1479 cout << "Number of components: " << n << endl;
1480 cout << "Number selected: " << ns << endl;
1481 cout << "Overlap distance: " << mindist << endl << endl;
1482 }
1483
1484 for ( ndel=0, mp = model; mp; mp = mp->next ) if ( mp->sel ) {
1485 for ( comp = mp->comp; comp->next; comp = comp->next ) if ( comp->sel > 0 ) {
1486 for ( comp2 = comp->next; comp2; comp2 = comp2->next ) if ( comp2->sel > 0 ) {
1487 if ( comp->loc.distance(comp2->loc) < mindist ) {
1488 comp2->sel = -1;
1489 ndel++;
1490 }
1491 }
1492 }
1493 }
1494
1495 if ( verbose )
1496 cout << "Number of components deleted: " << ndel << " (" << ndel*100.0/n << " %)" << endl;
1497
1498 model_delete(&model);
1499
1500 return n - ndel;
1501 }
1502
1518 long model_prune_fom(Bmodel* model, double distance)
1519 {
1520 int h, i, j, k, n, ns, nsel, imax;
1521 double fom_max, fom;
1522 Bcomponent* comp = NULL;
1523 Bcomponent* comp2 = NULL;
1524
1525 for ( n=ns=0, comp = model->comp; comp; comp = comp->next, n++ ) if ( comp->sel > 0 ) ns++;
1526
1527 if ( verbose ) {
1528 cout << "Pruning a set of solutions based on distance and FOM:" << endl;
1529 cout << "Number of components: " << n << endl;
1530 cout << "Number selected: " << ns << endl;
1531 cout << "Overlap distance: " << distance << endl << endl;
1532 }
1533
1534 int* sol = new int[ns];
1535 char* a = new char[ns*ns];
1536 double* f = new double[ns];
1537
1538 for ( i=0; i<ns; i++ ) f[i] = sol[i] = 0;
1539 for ( i=0; i<ns*ns; i++ ) a[i] = 0;
1540
1541 // Sets up the adjacency matrix
1542 for ( i=k=0, comp = model->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1543 for ( comp2 = model->comp; comp2; comp2 = comp2->next ) if ( comp2->sel > 0 ) {
1544 if ( comp != comp2 )
1545 if ( comp->loc.distance(comp2->loc) < distance ) a[k] = 1;
1546 k++;
1547 }
1548 f[i] = comp->fom;
1549 i++;
1550 }
1551
1552 // Successively find the highest FOM and set deletion tag for all others too close
1553 for ( h=0, imax = 0; h<ns && imax > -1; h++ ) {
1554 for ( i=0, imax = -1, fom_max = -1; i<ns; i++ ) {
1555 if ( fom_max < f[i] ) {
1556 fom_max = f[i];
1557 imax = i;
1558 }
1559 }
1560 if ( imax > -1 ) {
1561 sol[imax] = 1; // Tag for keeping
1562 f[imax] = -1;
1563 i = imax*ns;
1564 for ( j=0; j<ns; j++ ) if ( a[i+j] ) {
1565 f[j] = -1;
1566 sol[j] = -1; // Tag for deletion
1567 }
1568 }
1569 }
1570
1571 for ( i=nsel=0, fom=0, comp = model->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1572 comp->sel = sol[i++];
1573 if ( comp->sel > 0 ) {
1574 nsel++;
1575 fom += comp->fom;
1576 }
1577 }
1578
1579 if ( nsel ) fom /= nsel;
1580
1581 if ( verbose ) {
1582 cout << "Components selected:" << endl;
1583 cout << "ID\tType\tFOM\tDist" << endl;
1584 for ( comp = model->comp; comp; comp = comp->next ) if ( comp->sel > 0 )
1585 cout << comp->id << tab << comp->type->id << tab << comp->fom << tab << comp->loc.length() << endl;
1586 cout << "Number selected: " << nsel << " (" << nsel*100.0/n << " )" << endl;
1587 cout << "Average FOM: " << fom << endl << endl;
1588 }
1589
1590 delete[] sol;
1591 delete[] a;
1592 delete[] f;
1593
1594 model_delete(&model);
1595
1596 return nsel;
1597 }
1598
1610 long model_prune_similar(Bmodel* model)
1611 {
1612 long i, j, n, ns, c(0);
1613 double a;
1614 Bcomponent* comp = NULL;
1615 Bcomponent* comp1 = NULL;
1616
1617 Matrix dmat = model_distance_matrix(model, 1);
1618
1619 for ( n=0, comp = model->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1620 comp->view[3] = angle_set_negPI_to_PI(comp->view.angle());
1621 comp->sel = -1;
1622 n++;
1623 }
1624
1625 for ( i=0, comp = model->comp; comp->next; comp = comp->next ) if ( comp->sel > 0 ) {
1626 for ( j=i+1, comp1 = comp->next; comp1; comp1 = comp1->next ) if ( comp1->sel > 0 ) {
1627 if ( dmat[i][j] < 0.1 ) {
1628 if ( comp->sel < 1 ) comp->sel = ++c;
1629 comp1->sel = comp->sel;
1630 }
1631 j++;
1632 }
1633 i++;
1634 }
1635
1636 if ( verbose ) {
1637 cout << "Number of clusters: " << c << endl;
1638 cout << "Averaging similar components:" << endl << endl;
1639 }
1640
1641 for ( ns=0, comp = model->comp; comp; comp = comp->next )
1642 if ( ns < comp->sel ) ns = comp->sel;
1643
1644 for ( i=1; i<=ns; i++ ) {
1645 for ( n=0, comp = model->comp; comp; comp = comp->next ) if ( comp->sel == i ) {
1646 if ( n ) {
1647 comp->sel = -1;
1648 comp1->loc += comp->loc;
1649 comp1->view[0] += comp->view[0];
1650 comp1->view[1] += comp->view[1];
1651 comp1->view[2] += comp->view[2];
1652 a = comp1->view.angle()/n;
1653 comp1->view[3] += a + angle_set_negPI_to_PI(comp->view.angle() - a);
1654 } else {
1655 comp1 = comp; // First component
1656 }
1657 n++;
1658 }
1659 if ( n ) {
1660 comp1->loc /= n;
1661 comp1->view[0] /= n;
1662 comp1->view[1] /= n;
1663 comp1->view[2] /= n;
1664 comp1->view[3] /= n;
1665 comp1->view.normalize();
1666 }
1667 }
1668
1669 model_delete(&model);
1670
1671 return ns;
1672 }
1673
1674
1675 Bimage* model_composite_map(Bmodel* model, Vector3<int> size,
1676 Vector3<double> origin, Vector3<double> sampling)
1677 {
1678 if ( sampling[0] <= 0) sampling = sampling.max(1);
1679
1680 long i;
1681 double v, t;
1682 Vector3<double> loc, start, end;
1683 Bmodel* mp = model;
1684 Bcomponent* comp;
1685
1686 Bimage* p = new Bimage(Float, TSimple, size[0], size[1], size[2], 1);
1687 if ( origin[0] == 0 && origin[1] == 0 && origin[2] == 0 )
1688 origin = p->size()/2;
1689 p->origin(origin);
1690 p->sampling(sampling);
1691
1692 long datasize = p->data_size();
1693
1694 if ( verbose ) {
1695 cout << "Assembling a model map:" << endl;
1696 cout << "Size: " << p->size() << endl;
1697 cout << "Origin: " << p->image->origin() << endl;
1698 cout << "Sampling: " << p->sampling() << " A/voxel" << endl;
1699 }
1700
1701 // for ( mp = model; mp; mp = mp->next ) {
1702 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1703 loc[0] = (long) (comp->loc[0]/p->sampling()[0] + p->image->origin()[0] + 0.5);
1704 loc[1] = (long) (comp->loc[1]/p->sampling()[1] + p->image->origin()[1] + 0.5);
1705 loc[2] = (long) (comp->loc[2]/p->sampling()[2] + p->image->origin()[2] + 0.5);
1706 p->sphere(loc, comp->radius/p->sampling()[0], 0, FILL_USER, 1);
1707 }
1708 // }
1709
1710 // Calculate the mask volume
1711 for ( i=0, v=t=0; i<datasize; i++ ) {
1712 if ( (*p)[i] > 0.5 ) v += 1;
1713 t += (*p)[i];
1714 }
1715
1716 if ( verbose ) {
1717 cout << "Assembled map volume: " << v * sampling.volume() << " A3" << endl;
1718 cout << "Assembled map integral: " << t * sampling.volume() << endl;
1719 cout << "Integral volume ratio: " << t/v << endl << endl;
1720 }
1721
1722 return p;
1723 }
1724
1725 long comp_select_one(Bcomponent* comp, long i, long n, double* ovm)
1726 {
1727 long j, k;
1728 Bcomponent* comp2 = comp;
1729
1730 cout << i << ":";
1731
1732 for ( j=i+1, k=i*n+j, comp = comp->next; j<n && comp; j++, k++, comp = comp->next ) if ( comp->sel > 0 ) {
1733 if ( ovm[k] > 0 ) comp->sel = 0;
1734 else comp_select_one(comp, j, n, ovm);
1735 }
1736
1737 for ( j=0; comp2; j++, comp2 = comp2->next ) cout << " " << j+1 << ":" << comp2->sel;
1738 cout << endl;
1739
1740 return 0;
1741 }
1742
1743
1744 double* model_overlap_matrix(Bmodel* model, double distance)
1745 {
1746 long n, i, j;
1747 double d;
1748 Bmodel* mp = model;
1749 Bcomponent* comp;
1750 Bcomponent* comp2;
1751
1752 // for ( n=0, mp = model; mp; mp = mp->next ) if ( mp->sel )
1753 // for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) n++;
1754
1755 for ( n=0, comp = mp->comp; comp; comp = comp->next ) n++;
1756
1757 if ( verbose ) {
1758 cout << "Calculating an overlap matrix:" << endl;
1759 cout << "Distance criterion: " << distance << endl;
1760 cout << "Number of components: " << n << endl << endl;
1761 }
1762
1763 double* ovm = new double[n*n];
1764 for ( i=0; i<n*n; i++ ) ovm[i] = 0;
1765
1766
1767 // for ( i=0, mp = model; mp; mp = mp->next ) if ( mp->sel ) {
1768 for ( i=0, comp = mp->comp; comp->next; comp = comp->next, i++ ) {
1769 for ( j=i+1, comp2 = comp->next; comp2; comp2 = comp2->next, j++ ) {
1770 d = comp->loc.distance(comp2->loc)/distance;
1771 if ( d < 2 ) {
1772 ovm[i*n+j] = ovm[j*n+i] = 1 - (d/4)*(3-d*d/4);
1773 }
1774 }
1775 }
1776 // }
1777
1778 for ( i=0; i<n; i++ ) {
1779 for ( j=0; j<n; j++ )
1780 cout << tab << ovm[i*n+j];
1781 cout << endl;
1782 }
1783
1784 comp_select_one(model->comp, 0, n, ovm);
1785
1786 return ovm;
1787 }
1788
1789
1805 long model_prune_fit(Bmodel* model, double distance)
1806 {
1807 long n, ns, nsel(0);
1808 // double fom(0);
1809 Vector3<double> min, max;
1810 Vector3<double> sampling(5,5,5);
1811 Bcomponent* comp = NULL;
1812 // Bcomponent* comp1 = NULL;
1813
1814 for ( n=ns=0, comp = model->comp; comp; comp = comp->next, n++ ) if ( comp->sel > 0 ) {
1815 comp->radius = distance;
1816 min = min.min(comp->loc);
1817 max = max.max(comp->loc);
1818 comp->view[3] = angle_set_negPI_to_PI(comp->view.angle());
1819 ns++;
1820 }
1821 max = max.max(-min);
1822 max += 2*distance;
1823 max = max/sampling;
1824
1825 Vector3<int> size((int) (2*max[0]), (int) (2*max[1]), (int) (2*max[2]));
1826 Vector3<double> origin = max;
1827 Bimage* p = model_composite_map(model, size, origin, sampling);
1828
1829 // fom = 1/p->FOM_maximum();
1830
1831 write_img("ass.map", p, 0);
1832
1833 delete p;
1834
1835
1836 // double* ovm = model_overlap_matrix(model, distance);
1837 // delete[] ovm;
1838 /*
1839 for ( i=0; i<10 && fom < 0.9; i++ ) {
1840 // Change selection
1841 // Calculate new FOM
1842 p = model_composite_map(model, size, origin, sampling);
1843 fom = 1/p->FOM_maximum();
1844 delete p;
1845 }
1846 */
1847 /*
1848 int h, i, j, k, n, ns, nsel, imax;
1849 double fom_max, fom;
1850 Bcomponent* comp = NULL;
1851 Bcomponent* comp2 = NULL;
1852
1853 for ( n=ns=0, comp = model->comp; comp; comp = comp->next, n++ ) if ( comp->sel > 0 ) ns++;
1854
1855 if ( verbose ) {
1856 cout << "Pruning a set of solutions based on distance and FOM:" << endl;
1857 cout << "Number of components: %d\n", n);
1858 cout << "Number selected: %d\n", ns);
1859 cout << "Overlap distance: %g\n\n", distance);
1860 }
1861
1862 int* sol = new int[ns];
1863 char* a = new char[ns*ns];
1864 double* f = new double[ns];
1865
1866 for ( i=0; i<ns; i++ ) f[i] = sol[i] = 0;
1867 for ( i=0; i<ns*ns; i++ ) a[i] = 0;
1868
1869 // Sets up the adjacency matrix
1870 for ( i=k=0, comp = model->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1871 for ( comp2 = model->comp; comp2; comp2 = comp2->next ) if ( comp2->sel ) {
1872 if ( comp->loc.distance(comp2->loc) < distance ) a[k] = 1;
1873 // cout << " %d", a[k]);
1874 k++;
1875 }
1876 // cout << endl;
1877 f[i] = comp->fom;
1878 i++;
1879 }
1880
1881 for ( h=0; h<ns && imax > -1; h++ ) {
1882 for ( i=0, imax = -1, fom_max = -1; i<ns; i++ ) {
1883 if ( fom_max < f[i] ) {
1884 fom_max = f[i];
1885 imax = i;
1886 }
1887 }
1888 if ( imax > -1 ) {
1889 sol[imax] = 1;
1890 f[imax] = -1;
1891 i = imax*ns;
1892 for ( j=0; j<ns; j++ ) if ( a[i+j] ) f[j] = -1;
1893 }
1894 }
1895
1896 for ( i=nsel=0, fom=0, comp = model->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1897 comp->sel = sol[i++];
1898 if ( comp->sel > 0 ) {
1899 nsel++;
1900 fom += comp->fom;
1901 }
1902 }
1903
1904 if ( nsel ) fom /= nsel;
1905
1906 if ( verbose ) {
1907 cout << "Components selected:" << endl;
1908 cout << "Number\tID\tType\tFOM" << endl;
1909 for ( i=0, comp = model->comp; comp; comp = comp->next, i++ ) if ( comp->sel > 0 )
1910 cout << "%d\t%s\t%s\t%g\n", i+1, comp->id.c_str(), comp->type.c_str(), comp->fom);
1911 cout << "Number selected: %d (%g %%)\n", nsel, nsel*100.0/n);
1912 cout << "Average FOM: %g\n\n", fom);
1913 }
1914
1915 delete[] sol;
1916 delete[] a;
1917 delete[] f;
1918 */
1919 return nsel;
1920 }
1921
1936 long model_prune_large(Bmodel* model, double sampling)
1937 {
1938 if ( !model->comp ) return -1;
1939
1940 long i, ii, x, y, z, xx, yy, zz, imax, n, ng, np, nsel, vol;
1941 double dmax;
1942 Vector3<double> min = model->comp->loc;
1943 Vector3<double> max = model->comp->loc;
1944 Vector3<int> size;
1945 Bcomponent* comp = NULL;
1946
1947 for ( n=nsel=0, comp = model->comp; comp; comp = comp->next, n++ ) if ( comp->sel > 0 ) nsel++;
1948
1949 if ( verbose ) {
1950 cout << "Pruning a set of solutions based on grid sampling and FOM:" << endl;
1951 cout << "Number of components: " << n << endl;
1952 cout << "Number selected: " << nsel << endl;
1953 cout << "Grid sampling: " << sampling << endl;
1954 }
1955
1956 for ( comp = model->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1957 min = min.min(comp->loc);
1958 max = max.max(comp->loc);
1959 }
1960 min -= 2*sampling;
1961 max += 2*sampling;
1962 for ( i=0; i<3; i++ ) size[i] = (int) ((max[i] - min[i])/sampling);
1963 vol = (long) size.volume();
1964
1965 double* grid = new double[vol];
1966 double* peak = new double[vol];
1967 for ( i=0; i<vol; i++ ) grid[i] = peak[i] = 0;
1968
1969 if ( verbose )
1970 cout << "Grid volume: " << vol << endl << endl;
1971
1972 // Set up grid with maxima
1973 for ( comp = model->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
1974 x = (long) ((comp->loc[0] - min[0])/sampling);
1975 y = (long) ((comp->loc[1] - min[1])/sampling);
1976 z = (long) ((comp->loc[2] - min[2])/sampling);
1977 i = (z*size[1] + y)*size[0] + x;
1978 if ( i >= vol ) cerr << "Volume exceeded: " << i << endl;
1979 if ( grid[i] < comp->fom ) grid[i] = comp->fom;
1980 }
1981
1982 if ( verbose & VERB_FULL )
1983 cout << "Find peaks in grid" << endl;
1984
1985 // Find peaks within a 3x3x3 kernel
1986 for ( ng=np=0, z=1; z<size[2]-1; z++ ) {
1987 for ( y=1; y<size[1]-1; y++ ) {
1988 for ( x=1; x<size[0]-1; x++ ) {
1989 i = (z*size[1] + y)*size[0] + x;
1990 if ( grid[i] > 0 ) {
1991 imax = i;
1992 dmax = 0;
1993 for ( zz=z-1; zz<=z+1; zz++ ) {
1994 for ( yy=y-1; yy<=y+1; yy++ ) {
1995 for ( xx=x-1; xx<=x+1; xx++ ) {
1996 ii = (zz*size[1] + yy)*size[0] + xx;
1997 if ( dmax < grid[ii] ) {
1998 dmax = grid[ii];
1999 imax = ii;
2000 }
2001 }
2002 }
2003 }
2004 if ( imax == i ) {
2005 peak[i] = grid[i];
2006 np++;
2007 }
2008 ng++;
2009 }
2010 }
2011 }
2012 }
2013
2014 if ( verbose & VERB_FULL )
2015 cout << "Find components associated with peaks" << endl;
2016
2017 // Find models associated with peaks and select those
2018 for ( nsel=0, comp = model->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
2019 x = (long) ((comp->loc[0] - min[0])/sampling);
2020 y = (long) ((comp->loc[1] - min[1])/sampling);
2021 z = (long) ((comp->loc[2] - min[2])/sampling);
2022 i = (z*size[1] + y)*size[0] + x;
2023 if ( i >= vol ) cerr << "Volume exceeded: " << i << endl;
2024 comp->sel = -1;
2025 if ( peak[i] > 0 ) if ( fabs(peak[i] - comp->fom) < 1e-10 ) {
2026 comp->sel = 1;
2027 nsel++;
2028 }
2029 }
2030
2031 if ( verbose ) {
2032 cout << "Points placed on grid: " << ng << endl;
2033 cout << "Peaks: " << np << endl;
2034 cout << "Components selected: " << nsel << endl << endl;
2035 }
2036
2037 delete[] grid;
2038 delete[] peak;
2039
2040 model_delete(&model);
2041
2042 return nsel;
2043 }
2044
2056 long model_find_overlap(Bmodel* model, Bstring& reffile, double distance)
2057 {
2058 Bmodel* modref = read_model(reffile);
2059
2060 int nsel(0);
2061 Bmodel* mp;
2062 Bmodel* mpr;
2063 Bcomponent* comp;
2064 Bcomponent* compr;
2065
2066 if ( verbose ) {
2067 cout << "Deselecting components:" << endl;
2068 cout << "Reference model: " << reffile << endl;
2069 cout << "Distance criterion: " << distance << endl;
2070 }
2071
2072 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
2073 for ( comp = mp->comp; comp; comp = comp->next ) if ( comp->sel > 0 ) {
2074 for ( mpr = modref; mpr && comp->sel; mpr = mpr->next ) {
2075 for ( compr = mpr->comp; compr && comp->sel; compr = compr->next ) {
2076 if ( comp->loc.distance(compr->loc) < distance ) comp->sel = 0;
2077 }
2078 }
2079 if ( comp->sel > 0 ) nsel++;
2080 }
2081 }
2082
2083 model_kill(modref);
2084
2085 if ( verbose )
2086 cout << "Number of components retained: " << nsel << endl << endl;
2087
2088 return nsel;
2089 }
2090
distance
double distance(vector< T1 > &v1, vector< T2 > &v2)
Definition: Vector3.h:536
MAXLINK
#define MAXLINK
Definition: rwmodel.h:14
Bcomponent::id
Bstring id
Definition: rwmodel.h:53
qsort_functions.h
Header file for utility functions for use in qsort calls.
string_add
Bstring * string_add(Bstring **list, const char *string)
Adds a string to a linked list.
Definition: Bstring.cpp:705
Bcomponent::type
Bcomptype * type
Definition: rwmodel.h:54
Blink
Definition: rwmodel.h:82
Bstring::post
Bstring post(char c)
Definition: Bstring.cpp:394
Bmodel::id
Bstring id
Definition: rwmodel.h:121
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
Matrix::rows
long rows()
Definition: Matrix.h:153
model_prune_fit
long model_prune_fit(Bmodel *model, double distance)
Deselects components based on overlap distance and the FOM.
Definition: model_select.cpp:1805
model_views.h
Library routines used for analysing model component views.
model_count_component_types
int model_count_component_types(Bmodel *model)
Counts the number of components for each type.
Definition: rwmodel.cpp:568
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Bmodel::poly
Bpolygon * poly
Definition: rwmodel.h:134
Vector3::length
double length()
Definition: Vector3.h:222
Bstring::substr
Bstring substr(long start, long len)
Definition: Bstring.cpp:324
model_fom_deselect
long model_fom_deselect(Bmodel *model, double fom_cutoff)
Deselects components based on the FOM.
Definition: model_select.cpp:1154
model_select_non_fullerene
long model_select_non_fullerene(Bmodel *model)
Selects non-fullerene type models.
Definition: model_select.cpp:477
utilities.h
Header file for general utilities.
model_fom_ranking
long model_fom_ranking(Bmodel *model, int nrank)
Ranks components based on the FOM.
Definition: model_select.cpp:1307
model_util.h
Library routines used for model processing.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
model_select_fullerene
long model_select_fullerene(Bmodel *model)
Selects fullerene type models.
Definition: model_select.cpp:448
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
component_hand
int component_hand(Bstring &s)
Determines the hand of a component.
Definition: model_views.cpp:466
Bpolygon::comp
Bcomponent * comp[MAXLINK]
Definition: rwmodel.h:105
Bpolygon
Definition: rwmodel.h:102
Blink::sel
int sel
Definition: rwmodel.h:90
model_prune_similar
long model_prune_similar(Bmodel *model)
Averages similar components and reduces redundancy.
Definition: model_select.cpp:1610
Bstring::length
long length() const
Definition: Bstring.cpp:263
model_composite_map
Bimage * model_composite_map(Bmodel *model, Vector3< int > size, Vector3< double > origin, Vector3< double > sampling)
Definition: model_select.cpp:1675
QsortLargeToSmallIntFloat
int QsortLargeToSmallIntFloat(const void *x, const void *y)
Utility function for sorting int float pairs in qsort.
Definition: qsort_functions.cpp:89
Bcomptype::mass
float mass
Definition: rwmodel.h:32
Bmodel::sel
int sel
Definition: rwmodel.h:129
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
model_select
long model_select(Bmodel *model, Bstring &selstr)
Selects models, components and component types.
Definition: model_select.cpp:36
model_type_from_selection
long model_type_from_selection(Bmodel *model, Bstring *comp_type, Bstring &filename)
Converts selection numbers to different types.
Definition: model_select.cpp:1063
model_invert_selection
long model_invert_selection(Bmodel *model)
Inverts the selection of all components.
Definition: model_select.cpp:286
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
Bcomptype::sel
int sel
Definition: rwmodel.h:34
model_prune_large
long model_prune_large(Bmodel *model, double sampling)
Deselects components based on overlap distance and the FOM.
Definition: model_select.cpp:1936
Blink::comp
Bcomponent * comp[2]
Definition: rwmodel.h:84
Vector3::distance
double distance(const Vector3 &v)
Definition: Vector3.h:227
model_find_overlap
long model_find_overlap(Bmodel *model, Bstring &reffile, double distance)
Finds the components that overlap with the reference.
Definition: model_select.cpp:2056
model_select_unknowns
long model_select_unknowns(Bmodel *model)
Resets the selection to all unknown models.
Definition: model_select.cpp:208
TSimple
Definition: Bimage.h:58
Float
Definition: utilities.h:157
model_get_type
Bcomptype * model_get_type(Bmodel *model, Bstring &id)
Return the type corresponding to an identifier.
Definition: rwmodel.cpp:491
Vector3::max
Type max()
Definition: Vector3.h:175
Bmodel::hand
int hand
Definition: rwmodel.h:123
int_float::f
float f
Definition: qsort_functions.h:12
Bpolygon::number
int number
Definition: rwmodel.h:104
Bimage
General image parameter class.
Definition: Bimage.h:163
model_overlap_matrix
double * model_overlap_matrix(Bmodel *model, double distance)
Definition: model_select.cpp:1744
Bstring::contains
bool contains(const Bstring &s)
Definition: Bstring.cpp:584
linked_list.h
Header file for generalized linked list functions.
model_kill
int model_kill(Bmodel *model)
Deallocates all memory in the list.
Definition: rwmodel.cpp:1124
base
string base(string &filename)
Definition: string_util.cpp:28
model_select_sets
long model_select_sets(Bmodel *model, int size, int flag)
Selects sets of components, each set with the same size.
Definition: model_select.cpp:312
Bcomponent::view
View view
Definition: rwmodel.h:59
Blink::next
Blink * next
Definition: rwmodel.h:83
comp_type_list_kill
int comp_type_list_kill(Bcomptype *type)
Deallocates memory for a list of component types.
Definition: rwmodel.cpp:926
Bcomponent::fom
float fom
Definition: rwmodel.h:65
model_selection_stats
long model_selection_stats(Bmodel *model)
Calculates selection statistics.
Definition: model_select.cpp:870
model_fom_max_fraction_deselect
long model_fom_max_fraction_deselect(Bmodel *model, double fom_fraction)
Deselects components based on the FOM relative to the maximum FOM.
Definition: model_select.cpp:1180
Bstring::next
Bstring * next
Definition: Bstring.h:31
Bmodel::type
Bcomptype * type
Definition: rwmodel.h:131
Bimage::sphere
int sphere(Vector3< double > center, double radius, double width=0, int fill_type=0, double fill=0)
Fills a sphere within an image with a uniform value.
Definition: Bimage_edit.cpp:438
Bmodel::type_id
Bstring type_id
Definition: rwmodel.h:122
model_add_type_by_id_and_filename
Bcomptype * model_add_type_by_id_and_filename(Bmodel *model, Bstring &id, Bstring &filename, int num)
Add a type to a model if the type with the given id and file name does not exist already.
Definition: rwmodel.cpp:465
model_select_first
long model_select_first(Bmodel *model, int first)
Selects the first number of components.
Definition: model_select.cpp:566
model_delete
long model_delete(Bmodel **model)
Deletes tagged models, components and links.
Definition: model_select.cpp:623
model_unset_selection
long model_unset_selection(Bmodel *model)
Unsets the selection to all components but not models.
Definition: model_select.cpp:261
Bpolygon::next
Bpolygon * next
Definition: rwmodel.h:103
model_select_closed
long model_select_closed(Bmodel *model, int closure_rule, int val_order)
Determines if a polyhedron is closed given a rule.
Definition: model_select.cpp:397
write_img
int write_img(const char *filename, Bimage *p, int compression)
General driver function to write multiple image formats.
Definition: rwimg.cpp:280
model_poly_generate
int model_poly_generate(Bmodel *model)
Generates polygons based on a vertex network.
Definition: model_poly.cpp:145
int_float
Definition: qsort_functions.h:12
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
View::normalize
double normalize()
Definition: View.h:106
FILL_USER
#define FILL_USER
Definition: utilities.h:172
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
remove_item
char * remove_item(char **list, char *item, unsigned long size)
Finds the given item and deletes it from the linked list.
Definition: linked_list.cpp:114
model_average_overlapped_components
long model_average_overlapped_components(Bmodel *model, double distance)
Averages components within a distance.
Definition: model_select.cpp:1425
model_poly.h
Functions to manipulate polyhedral coordinate files.
Bimage::get
double get(long nn, long xx, long yy, long zz, long cc=0)
Returns the data value at the given coordinates.
Definition: Bimage.cpp:937
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
read_model
Bmodel * read_model(Bstring &filename)
Definition: rwmodel.cpp:28
component_kill
int component_kill(Bcomponent *comp)
Deallocates memory for one component.
Definition: rwmodel.cpp:877
Bmodel::fom
float fom
Definition: rwmodel.h:128
Matrix
Definition: Matrix.h:21
model_prune_fom
long model_prune_fom(Bmodel *model, double distance)
Deselects components based on overlap distance and the FOM.
Definition: model_select.cpp:1518
Bstring
Definition: Bstring.h:29
model_delete_overlapped_components
long model_delete_overlapped_components(Bmodel **model, double distance)
Deletes components that are too close to others.
Definition: model_select.cpp:1396
Bcomponent::link
Bcomponent * link[MAXLINK]
Definition: rwmodel.h:55
Bmodel::link
Blink * link
Definition: rwmodel.h:133
model_select_valence
long model_select_valence(Bmodel *model, int valence)
Selects fullerene type models.
Definition: model_select.cpp:508
Bmodel::fmap
Bstring fmap
Definition: rwmodel.h:125
Bcomptype::num
int num
Definition: rwmodel.h:30
model_fom_histogram
long model_fom_histogram(Bmodel *model, double fom_step)
Selects components based on the FOM.
Definition: model_select.cpp:1254
Bcomponent::next
Bcomponent * next
Definition: rwmodel.h:52
rwmodel.h
Header file for reading and writing atomic model files.
model_select_polygons
long model_select_polygons(Bmodel *model, int order)
Selects model polygons with a given order.
Definition: model_select.cpp:535
Bcomptype::id
Bstring id
Definition: rwmodel.h:27
Vector3< double >
model_select_all
long model_select_all(Bmodel *model)
Resets the selection to all models.
Definition: model_select.cpp:193
View::angle
double angle()
Definition: View.h:95
comp_select_one
long comp_select_one(Bcomponent *comp, long i, long n, double *ovm)
Definition: model_select.cpp:1725
Vector3::min
Type min()
Definition: Vector3.h:169
model_delete_comp_type
long model_delete_comp_type(Bmodel *model, Bstring &comptype)
Deletes components based on their types.
Definition: model_select.cpp:720
model_prune_simple
long model_prune_simple(Bmodel *model, double mindist)
Prunes overlapping components based on a distance criterion.
Definition: model_select.cpp:1468
Bmodel
Definition: rwmodel.h:119
rwimg.h
Header file for 2D and 3D image I/O.
verbose
int verbose
int_float::i
int i
Definition: qsort_functions.h:12
Bcomptype
Definition: rwmodel.h:25
model_reset_selection
long model_reset_selection(Bmodel *model)
Resets the selection to all components.
Definition: model_select.cpp:232
model_select_number_of_components
long model_select_number_of_components(Bmodel *model, int ncomp_min, int ncomp_max)
Selects models within a range of the number of components.
Definition: model_select.cpp:359
Bmodel::comp
Bcomponent * comp
Definition: rwmodel.h:132
Bstring::index
long index(const char c)
Definition: Bstring.h:101
Vector3::volume
double volume()
Definition: Vector3.h:235
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
models_radius_deselect
long models_radius_deselect(Bmodel *model, double minrad, double maxrad)
Deselects components based on the distance from the origin.
Definition: model_select.cpp:1215
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:106
Bcomponent::loc
Vector3< float > loc
Definition: rwmodel.h:58
model_compare.h
Functions to compare models and components.
model_distance_matrix
Matrix model_distance_matrix(Bmodel *model, int view_flag)
Calculates the distance matrix for a model.
Definition: model_compare.cpp:189
string_sort
int string_sort(Bstring *slist, int descending, int value)
Sorts a list of strings in ascending (descending) lexical or value order.
Definition: Bstring.cpp:875
Bimage::data_size
long data_size()
Definition: Bimage.h:255
Bcomptype::count
int count
Definition: rwmodel.h:31
model_select_in_mask
long model_select_in_mask(Bmodel *model, Bimage *pmask)
Selects components within a mask.
Definition: model_select.cpp:590
comp_type_kill
int comp_type_kill(Bcomptype *type)
Deallocates memory for one component type.
Definition: rwmodel.cpp:912
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
Bstring::split
Bstring * split()
Definition: Bstring.cpp:597
Bpolygon::sel
int sel
Definition: rwmodel.h:109
string_kill
int string_kill(Bstring *list)
Kills a string linked list.
Definition: Bstring.cpp:760
Bcomptype::next
Bcomptype * next
Definition: rwmodel.h:26
Bcomponent
Definition: rwmodel.h:51