@@ -127,17 +127,10 @@ class Compound(object):
127
127
compound is the root of the containment hierarchy.
128
128
referrers : set
129
129
Other compounds that reference this part with labels.
130
- rigid_id : int, default=None
131
- The ID of the rigid body that this Compound belongs to. Only Particles
132
- (the bottom of the containment hierarchy) can have integer values for
133
- `rigid_id`. Compounds containing rigid particles will always have
134
- `rigid_id == None`. See also `contains_rigid`.
135
130
boundingbox : mb.Box
136
131
The bounds (xmin, xmax, ymin, ymax, zmin, zmax) of particles in Compound
137
132
center
138
- contains_rigid
139
133
mass
140
- max_rigid_id
141
134
n_particles
142
135
n_bonds
143
136
root
@@ -183,10 +176,6 @@ def __init__(
183
176
184
177
self .port_particle = port_particle
185
178
186
- self ._rigid_id = None
187
- self ._contains_rigid = False
188
- self ._check_if_contains_rigid_bodies = False
189
-
190
179
self .element = element
191
180
if mass and float (mass ) < 0.0 :
192
181
raise ValueError ("Cannot set a Compound mass value less than zero" )
@@ -583,230 +572,6 @@ def charge(self, value):
583
572
"not at the bottom of the containment hierarchy."
584
573
)
585
574
586
- @property
587
- def rigid_id (self ):
588
- """Get the rigid_id of the Compound."""
589
- return self ._rigid_id
590
-
591
- @rigid_id .setter
592
- def rigid_id (self , value ):
593
- if self ._contains_only_ports ():
594
- self ._rigid_id = value
595
- for ancestor in self .ancestors ():
596
- ancestor ._check_if_contains_rigid_bodies = True
597
- else :
598
- raise AttributeError (
599
- "rigid_id is immutable for Compounds that are "
600
- "not at the bottom of the containment hierarchy."
601
- )
602
-
603
- @property
604
- def contains_rigid (self ):
605
- """Return True if the Compound contains rigid bodies.
606
-
607
- If the Compound contains any particle with a rigid_id != None
608
- then contains_rigid will return True. If the Compound has no
609
- children (i.e. the Compound resides at the bottom of the containment
610
- hierarchy) then contains_rigid will return False.
611
-
612
- Returns
613
- -------
614
- bool,
615
- True if the Compound contains any particle with a rigid_id != None
616
-
617
- Notes
618
- -----
619
- The private variable '_check_if_contains_rigid_bodies' is used to help
620
- cache the status of 'contains_rigid'.
621
- If '_check_if_contains_rigid_bodies' is False, then the rigid body
622
- containment of the Compound has not changed, and the particle tree is
623
- not traversed, boosting performance.
624
- """
625
- if self ._check_if_contains_rigid_bodies :
626
- self ._check_if_contains_rigid_bodies = False
627
- if any (p .rigid_id is not None for p in self ._particles ()):
628
- self ._contains_rigid = True
629
- else :
630
- self ._contains_rigid = False
631
- return self ._contains_rigid
632
-
633
- @property
634
- def max_rigid_id (self ):
635
- """Return the maximum rigid body ID contained in the Compound.
636
-
637
- This is usually used by compound.root to determine the maximum
638
- rigid_id in the containment hierarchy.
639
-
640
- Returns
641
- -------
642
- int or None
643
- The maximum rigid body ID contained in the Compound. If no
644
- rigid body IDs are found, None is returned
645
- """
646
- try :
647
- return max (
648
- [p .rigid_id for p in self .particles () if p .rigid_id is not None ]
649
- )
650
- except ValueError :
651
- return
652
-
653
- def rigid_particles (self , rigid_id = None ):
654
- """Generate all particles in rigid bodies.
655
-
656
- If a rigid_id is specified, then this function will only yield particles
657
- with a matching rigid_id.
658
-
659
- Parameters
660
- ----------
661
- rigid_id : int, optional
662
- Include only particles with this rigid body ID
663
-
664
- Yields
665
- ------
666
- mb.Compound
667
- The next particle with a rigid_id that is not None, or the next
668
- particle with a matching rigid_id if specified
669
- """
670
- for particle in self .particles ():
671
- if rigid_id is not None :
672
- if particle .rigid_id == rigid_id :
673
- yield particle
674
- else :
675
- if particle .rigid_id is not None :
676
- yield particle
677
-
678
- def label_rigid_bodies (self , discrete_bodies = None , rigid_particles = None ):
679
- """Designate which Compounds should be treated as rigid bodies.
680
-
681
- If no arguments are provided, this function will treat the compound
682
- as a single rigid body by providing all particles in `self` with the
683
- same rigid_id. If `discrete_bodies` is not None, each instance of
684
- a Compound with a name found in `discrete_bodies` will be treated as a
685
- unique rigid body. If `rigid_particles` is not None, only Particles
686
- (Compounds at the bottom of the containment hierarchy) matching this
687
- name will be considered part of the rigid body.
688
-
689
- Parameters
690
- ----------
691
- discrete_bodies : str or list of str, optional, default=None
692
- Name(s) of Compound instances to be treated as unique rigid bodies.
693
- Compound instances matching this (these) name(s) will be provided
694
- with unique rigid_ids
695
- rigid_particles : str or list of str, optional, default=None
696
- Name(s) of Compound instances at the bottom of the containment
697
- hierarchy (Particles) to be included in rigid bodies. Only Particles
698
- matching this (these) name(s) will have their rigid_ids altered to
699
- match the rigid body number.
700
-
701
- Examples
702
- --------
703
- Creating a rigid benzene
704
-
705
- >>> import mbuild as mb
706
- >>> from mbuild.utils.io import get_fn
707
- >>> benzene = mb.load(get_fn('benzene.mol2'))
708
- >>> benzene.label_rigid_bodies()
709
-
710
- Creating a semi-rigid benzene, where only the carbons are treated as
711
- a rigid body
712
-
713
- >>> import mbuild as mb
714
- >>> from mbuild.utils.io import get_fn
715
- >>> benzene = mb.load(get_fn('benzene.mol2'))
716
- >>> benzene.label_rigid_bodies(rigid_particles='C')
717
-
718
- Create a box of rigid benzenes, where each benzene has a unique rigid
719
- body ID.
720
-
721
- >>> import mbuild as mb
722
- >>> from mbuild.utils.io import get_fn
723
- >>> benzene = mb.load(get_fn('benzene.mol2'))
724
- >>> benzene.name = 'Benzene'
725
- >>> filled = mb.fill_box(benzene,
726
- ... n_compounds=10,
727
- ... box=[0, 0, 0, 4, 4, 4])
728
- >>> filled.label_rigid_bodies(distinct_bodies='Benzene')
729
-
730
- Create a box of semi-rigid benzenes, where each benzene has a unique
731
- rigid body ID and only the carbon portion is treated as rigid.
732
-
733
- >>> import mbuild as mb
734
- >>> from mbuild.utils.io import get_fn
735
- >>> benzene = mb.load(get_fn('benzene.mol2'))
736
- >>> benzene.name = 'Benzene'
737
- >>> filled = mb.fill_box(benzene,
738
- ... n_compounds=10,
739
- ... box=[0, 0, 0, 4, 4, 4])
740
- >>> filled.label_rigid_bodies(distinct_bodies='Benzene',
741
- ... rigid_particles='C')
742
- """
743
- if discrete_bodies is not None :
744
- if isinstance (discrete_bodies , str ):
745
- discrete_bodies = [discrete_bodies ]
746
- if rigid_particles is not None :
747
- if isinstance (rigid_particles , str ):
748
- rigid_particles = [rigid_particles ]
749
-
750
- if self .root .max_rigid_id is not None :
751
- rigid_id = self .root .max_rigid_id + 1
752
- warn (
753
- f"{ rigid_id } rigid bodies already exist. Incrementing 'rigid_id'"
754
- f"starting from { rigid_id } ."
755
- )
756
- else :
757
- rigid_id = 0
758
-
759
- for successor in self .successors ():
760
- if discrete_bodies and successor .name not in discrete_bodies :
761
- continue
762
- for particle in successor .particles ():
763
- if rigid_particles and particle .name not in rigid_particles :
764
- continue
765
- particle .rigid_id = rigid_id
766
- if discrete_bodies :
767
- rigid_id += 1
768
-
769
- def unlabel_rigid_bodies (self ):
770
- """Remove all rigid body labels from the Compound."""
771
- self ._check_if_contains_rigid_bodies = True
772
- for child in self .children :
773
- child ._check_if_contains_rigid_bodies = True
774
- for particle in self .particles ():
775
- particle .rigid_id = None
776
-
777
- def _increment_rigid_ids (self , increment ):
778
- """Increment the rigid_id of all rigid Particles in a Compound.
779
-
780
- Adds `increment` to the rigid_id of all Particles in `self` that
781
- already have an integer rigid_id.
782
- """
783
- for particle in self .particles ():
784
- if particle .rigid_id is not None :
785
- particle .rigid_id += increment
786
-
787
- def _reorder_rigid_ids (self ):
788
- """Reorder rigid body IDs ensuring consecutiveness.
789
-
790
- Primarily used internally to ensure consecutive rigid_ids following
791
- removal of a Compound.
792
- """
793
- max_rigid = self .max_rigid_id
794
- unique_rigid_ids = sorted (
795
- set ([p .rigid_id for p in self .rigid_particles ()])
796
- )
797
- n_unique_rigid = len (unique_rigid_ids )
798
- if max_rigid and n_unique_rigid != max_rigid + 1 :
799
- missing_rigid_id = (
800
- unique_rigid_ids [- 1 ] * (unique_rigid_ids [- 1 ] + 1 )
801
- ) / 2 - sum (unique_rigid_ids )
802
- for successor in self .successors ():
803
- if successor .rigid_id is not None :
804
- if successor .rigid_id > missing_rigid_id :
805
- successor .rigid_id -= 1
806
- if self .rigid_id :
807
- if self .rigid_id > missing_rigid_id :
808
- self .rigid_id -= 1
809
-
810
575
def add (
811
576
self ,
812
577
new_child ,
@@ -815,7 +580,6 @@ def add(
815
580
replace = False ,
816
581
inherit_periodicity = None ,
817
582
inherit_box = False ,
818
- reset_rigid_ids = True ,
819
583
check_box_size = True ,
820
584
):
821
585
"""Add a part to the Compound.
@@ -840,11 +604,6 @@ def add(
840
604
Compound being added
841
605
inherit_box: bool, optional, default=False
842
606
Replace the box of self with the box of the Compound being added
843
- reset_rigid_ids : bool, optional, default=True
844
- If the Compound to be added contains rigid bodies, reset the
845
- rigid_ids such that values remain distinct from rigid_ids
846
- already present in `self`. Can be set to False if attempting
847
- to add Compounds to an existing rigid body.
848
607
check_box_size : bool, optional, default=True
849
608
Checks and warns if compound box is smaller than its bounding box after adding new_child.
850
609
"""
@@ -894,15 +653,10 @@ def add(
894
653
self .add (
895
654
child ,
896
655
label = label_list [i ],
897
- reset_rigid_ids = reset_rigid_ids ,
898
656
check_box_size = False ,
899
657
)
900
658
else :
901
- self .add (
902
- child ,
903
- reset_rigid_ids = reset_rigid_ids ,
904
- check_box_size = False ,
905
- )
659
+ self .add (child , check_box_size = False )
906
660
907
661
return
908
662
@@ -919,13 +673,6 @@ def add(
919
673
)
920
674
self ._mass = 0
921
675
922
- if new_child .contains_rigid or new_child .rigid_id is not None :
923
- if self .contains_rigid and reset_rigid_ids :
924
- new_child ._increment_rigid_ids (increment = self .max_rigid_id + 1 )
925
- self ._check_if_contains_rigid_bodies = True
926
- if self .rigid_id is not None :
927
- self .rigid_id = None
928
-
929
676
# Create children and labels on the first add operation
930
677
if self .children is None :
931
678
self .children = list ()
@@ -1067,7 +814,7 @@ def _check_if_empty(child):
1067
814
for particle in particles_to_remove :
1068
815
_check_if_empty (particle )
1069
816
1070
- # Fix rigid_ids and remove obj from bondgraph
817
+ # Remove obj from bondgraph
1071
818
for removed_part in to_remove :
1072
819
self ._remove (removed_part )
1073
820
@@ -1077,11 +824,6 @@ def _check_if_empty(child):
1077
824
removed_part .parent .children .remove (removed_part )
1078
825
self ._remove_references (removed_part )
1079
826
1080
- # Check and reorder rigid id
1081
- for _ in particles_to_remove :
1082
- if self .contains_rigid :
1083
- self .root ._reorder_rigid_ids ()
1084
-
1085
827
# Remove ghost ports
1086
828
self ._prune_ghost_ports ()
1087
829
@@ -1148,10 +890,7 @@ def _prune_ghost_ports(self):
1148
890
self ._remove_references (port )
1149
891
1150
892
def _remove (self , removed_part ):
1151
- """Worker for remove(). Fixes rigid IDs and removes bonds."""
1152
- if removed_part .rigid_id is not None :
1153
- for ancestor in removed_part .ancestors ():
1154
- ancestor ._check_if_contains_rigid_bodies = True
893
+ """Worker for remove(). Removes bonds."""
1155
894
if self .root .bond_graph .has_node (removed_part ):
1156
895
for neighbor in nx .neighbors (
1157
896
self .root .bond_graph .copy (), removed_part
@@ -3600,12 +3339,7 @@ def _clone(self, clone_of=None, root_container=None):
3600
3339
newone ._pos = deepcopy (self ._pos )
3601
3340
newone .port_particle = deepcopy (self .port_particle )
3602
3341
newone ._box = deepcopy (self ._box )
3603
- newone ._check_if_contains_rigid_bodies = deepcopy (
3604
- self ._check_if_contains_rigid_bodies
3605
- )
3606
3342
newone ._periodicity = deepcopy (self ._periodicity )
3607
- newone ._contains_rigid = deepcopy (self ._contains_rigid )
3608
- newone ._rigid_id = deepcopy (self ._rigid_id )
3609
3343
newone ._charge = deepcopy (self ._charge )
3610
3344
newone ._mass = deepcopy (self ._mass )
3611
3345
if hasattr (self , "index" ):
0 commit comments