Hey Mohm and Tommy,
Sorry for invading in the thread here and maybe I am a bit late to the party but I have exactly implemented such a search in a package called MDVContainment. Altough it seems like a different problem to classify inside and outside it actually heavily relies on percolation theory. In other words anything which ends up to be non-percolating is contained in something which is (in a binary partitioning of density). This percolative property of the connected components is stored in a graph in my algorithm and is called the rank of the component. A rank of 0 is non-peroclative, a rank higher than 0 indicates the amount of orthogonal dimensions in which it is percolative.
Some demonstration code below on how to do it, the output will be a list of percolative atomgroups. WE can also get the percolations dict which says which compnent label is percolative or not. Components which are in the selection are positive and components which are not are negative integeres in the percolations dict.
## Example for obtaining percolative densities in periodic MD data in an efficient manner using MDVContainment (Bart Bruininks).
# pip install MDAnalysis
import MDAnalysis as mda
# git -clone https://github.com/BartBruininks/mdvcontainment; pip install -e .
import mdvcontainment as mdvc
# A simple periodic bilayer in xy (percolating the space)
universe = mda.Universe('/media/windows/Users/Bart/projects/test_systems/bilayer_chol_dry/eq_dry.gro')
selection = universe.select_atoms('not resname W WF ION') # place MDA selection here
# Run the containment analysis
containment = mdvc.Containers(selection, resolution=1)
# Obtain the ranks, the rank indicates the amount of orthogonal dimensions
# the component is percolating. Therefore a rank 0 indicates
# no percolation and any non-zero rank is percolating.
segment_ranks = containment.data['all_ranks']
segments2components_map = containment.data['combined_relabel_dict']
percolations = {}
for segments, rank in segment_ranks.items():
if rank > 0:
percolations[segments2components_map[segments]] = 'Percolative'
else:
percolations[segments2components_map[segments]] = 'Non-percolative'
# You can get the atomgroup (point cloud object) for every percolative component
percolative_atomgroups = []
for candidate in percolations:
if percolations[candidate] == 'Percolative':
percolative_atomgroups.append(containment.get_atomgroup_from_components([candidate]))
# The empty space is also perculating!
print(percolative_atomgroups)
#r_containment.plot()
Cheers,
Bart
Op dinsdag 2 mei 2023 om 18:02:34 UTC+2 schreef Tommy Waltmann: