{"id":34086424,"url":"https://github.com/jorisparet/partycls","last_synced_at":"2026-03-17T22:37:17.904Z","repository":{"id":47240272,"uuid":"376583561","full_name":"jorisparet/partycls","owner":"jorisparet","description":"Unsupervised learning of structure in systems of interacting particles.","archived":false,"fork":false,"pushed_at":"2023-11-13T17:01:18.000Z","size":29315,"stargazers_count":13,"open_issues_count":1,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-02-06T11:23:05.556Z","etag":null,"topics":["clustering","machine-learning","molecular-dynamics","physics","python"],"latest_commit_sha":null,"homepage":"https://www.jorisparet.com/partycls/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jorisparet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"docs/support.rst","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-06-13T15:57:24.000Z","updated_at":"2026-01-24T07:53:47.000Z","dependencies_parsed_at":"2023-11-13T18:35:12.085Z","dependency_job_id":null,"html_url":"https://github.com/jorisparet/partycls","commit_stats":{"total_commits":484,"total_committers":4,"mean_commits":121.0,"dds":"0.11363636363636365","last_synced_commit":"e7bb63d47e49b49203f03457d89bb4ac6ec050e4"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/jorisparet/partycls","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorisparet%2Fpartycls","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorisparet%2Fpartycls/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorisparet%2Fpartycls/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorisparet%2Fpartycls/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jorisparet","download_url":"https://codeload.github.com/jorisparet/partycls/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorisparet%2Fpartycls/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30633473,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-17T17:32:55.572Z","status":"ssl_error","status_checked_at":"2026-03-17T17:32:38.732Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clustering","machine-learning","molecular-dynamics","physics","python"],"created_at":"2025-12-14T13:27:52.413Z","updated_at":"2026-03-17T22:37:17.896Z","avatar_url":"https://github.com/jorisparet.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/jorisparet/partycls\"\u003e\u003cimg src=\"https://github.com/jorisparet/partycls/blob/master/logo/logo.svg\" width=\"250\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n[![pypi](https://img.shields.io/pypi/v/partycls.svg)](https://pypi.python.org/pypi/partycls/)\n[![version](https://img.shields.io/badge/python-3.6+-blue.svg)](https://pypi.python.org/pypi/partycls/)\n[![license](https://img.shields.io/pypi/l/partycls.svg)](https://en.wikipedia.org/wiki/GNU_General_Public_License)\n[![DOI](https://joss.theoj.org/papers/10.21105/joss.03723/status.svg)](https://doi.org/10.21105/joss.03723)\n[![build](https://github.com/jorisparet/partycls/actions/workflows/build-test.yml/badge.svg)](https://github.com/jorisparet/partycls/actions/workflows/build-test.yml)\n![coverage](https://img.shields.io/badge/coverage-89%25-green)\n  \n**partycls** is a Python package for cluster analysis of systems of interacting particles. By grouping particles that share similar structural or dynamical properties, partycls enables rapid and unsupervised exploration of the system's relevant features. It provides descriptors suitable for applications in condensed matter physics, such as structural analysis of disordered or partially ordered materials, and integrates the necessary tools of unsupervised learning into a streamlined workflow.\n\nHomepage\n--------\n\nFor more details and tutorials, visit the homepage at: https://www.jorisparet.com/partycls\n\nQuick start\n-----------\n\nThis quick example shows how to use partycls to identify grain boundaries in a polycrystalline system. The system configuration is stored in a [XYZ](https://en.wikipedia.org/wiki/XYZ_file_format) trajectory file with a single frame. We use the local distribution of bond angles around each particle as a structural descriptor and perform a clustering using the [K-Means](https://en.wikipedia.org/wiki/K-means_clustering) algorithm.\n\n```python\nfrom partycls import Trajectory, Workflow\n\ntraj = Trajectory('grains.xyz')\nwf = Workflow(traj, descriptor='ba', clustering='kmeans')\nwf.run()\ntraj[0].show(color='label', backend='ovito')\n```\n\n![](https://raw.githubusercontent.com/jorisparet/partycls/master/data/snapshots/grains_labels.png)\n\nThe results are also written to a set of files including a labeled trajectory file and additional information on the clustering results. The whole workflow can be tuned and customized, check out the [tutorials](https://www.jorisparet.com/partycls/tutorials) to see how and for further examples.\n\nThanks to a flexible system of filters, partycls makes it easy to restrict the analysis to a given subset of particles based on arbitrary particle properties. Say we have a binary mixture composed of particles with types A and B, and we are only interested in analyzing the bond angles of B particles in a vertical slice:\n\n```python\nfrom partycls import Trajectory\nfrom partycls.descriptors import BondAngleDescriptor\n\ntraj = Trajectory('trajectory.xyz')\nD = BondAngleDescriptor(traj)\nD.add_filter(\"species == 'B'\")\nD.add_filter(\"x \u003e 0.0\")\nD.add_filter(\"x \u003c 1.0\")\nD.compute()\n\n# Angular correlations for the selected particles\nprint(D.features)\n```\n\nWe can then perform a clustering based on these structural features and ask for 3 clusters:\n\n```python\nfrom partycls import KMeans\n\nclustering = KMeans(n_clusters=3)\nclustering.fit(D.features)\nprint('Cluster membership of the particles', clustering.labels)\n```\n\nMain features\n-------------\n\n### Trajectory formats\n\npartycls accepts several trajectory formats (including custom ones) either through its built-in trajectory reader or via third-party packages, such as [MDTraj](www.mdtraj.org) and [atooms](https://framagit.org/atooms/atooms). The code is currently optimized for small and medium system sizes (of order 10⁴ particles). Multiple trajectory frames can be analyzed to extend the structural dataset.\n\n### Structural descriptors\n\npartycls implements various structural descriptors: \n\n* [Radial descriptor](https://www.jorisparet.com/partycls/tutorials/descriptors/gr.html)\n* [Tetrahedral descriptor](https://www.jorisparet.com/partycls/tutorials/descriptors/tetra.html)\n* [Bond-angle descriptor](https://www.jorisparet.com/partycls/tutorials/descriptors/ba.html)\n* [Smoothed bond-angle descriptor](https://www.jorisparet.com/partycls/tutorials/descriptors/sba.html)\n* [Bond-orientational descriptor](https://www.jorisparet.com/partycls/tutorials/descriptors/bo.html)\n* [Smoothed bond-orientational descriptor](https://www.jorisparet.com/partycls/tutorials/descriptors/sbo.html)\n* [Locally averaged bond-orientational descriptor](https://www.jorisparet.com/partycls/tutorials/descriptors/labo.html)\n* [Radial bond-orientational descriptor](https://www.jorisparet.com/partycls/tutorials/descriptors/rbo.html)\n* [Compactness descriptor](https://www.jorisparet.com/partycls/tutorials/descriptors/compact.html)\n* [Coordination descriptor](https://www.jorisparet.com/partycls/tutorials/descriptors/coord.html)\n\n### Machine learning\n\npartycls performs feature scaling, dimensionality reduction and cluster analysis using the [scikit-learn](https://scikit-learn.org) package and additional built-in algorithms.\n\nDependencies\n------------\n\npartycls relies on several external packages, most of which only provide additional features and are not necessarily required.\n\n### Required\n\n* Fortran compiler (*e.g.* [gfortran](https://gcc.gnu.org/wiki/GFortran))\n* [NumPy](https://pypi.org/project/numpy/)\n* [scikit-learn](https://scikit-learn.org)\n\n### Optional\n\n* [MDTraj](https://www.mdtraj.org) (additional trajectory formats)\n* [atooms](https://framagit.org/atooms/atooms) (additional trajectory formats)\n* [DScribe](https://singroup.github.io/dscribe) (additional descriptors)\n* [Matplotlib](https://matplotlib.org/) (visualization)\n* [OVITO](https://ovito.org/) \u003c 3.7.0 (visualization)\n* [Py3DMol](https://github.com/avirshup/py3dmol) (interactive 3D visualization)\n* [pyvoro](https://github.com/joe-jordan/pyvoro) or its [memory-optimized fork](https://framagit.org/coslo/pyvoro) for large systems (Voronoi neighbors and tessellation)\n* [tqdm](https://tqdm.github.io/) (progress bars)\n\nDocumentation\n-------------\n\nCheck the [tutorials](https://www.jorisparet.com/partycls/tutorials) to see various examples and detailed instructions on how to run the code, as well as an in-depth presentation of the built-in structural descriptors.\n\nFor a more detailed documentation, you can check the [API](https://www.jorisparet.com/partycls/api).\n\nInstallation\n------------\n\n### From PyPI\n\nThe latest stable release is available on [PyPI](https://pypi.org/project/partycls/). Install it with `pip`:\n\n```bash\npip install partycls\n```\n\n### From source \n\nTo install the latest development version from source, clone the source code from the official [GitHub repository](https://github.com/jorisparet/partycls) and install it with:\n\n```bash\ngit clone https://github.com/jorisparet/partycls.git\ncd partycls\nmake install\n```\n\nRun the tests using:\n\n```bash\nmake test\n```\n\nor manually compile the Fortran sources and run the tests:\n\n```bash\ncd partycls/\nf2py -c -m neighbors_wrap neighbors.f90\ncd descriptor/\nf2py -c -m realspace_wrap realspace.f90\ncd ../../\npytest tests/\n```\n\nSupport and contribution\n------------------------\n\nIf you wish to contribute or report an issue, feel free to [contact us](mailto:joris.paret@gmail.com) or to use the [issue tracker](https://github.com/jorisparet/partycls/issues) and [pull requests](https://github.com/jorisparet/partycls/pulls) from the [code repository](https://github.com/jorisparet/partycls).\n\nWe largely follow the [GitHub flow](https://guides.github.com/introduction/flow/) to integrate community contributions. In essence:\n1. Fork the repository.\n2. Create a feature branch from `master`.\n3. Unleash your creativity.\n4. Run the tests.\n5. Open a pull request.\n\nWe also welcome contributions from other platforms, such as GitLab instances. Just let us know where to find your feature branch.\n\nCiting partycls\n---------------\n\nIf you use partycls in a scientific publication, please consider citing the following article:\n\n*[partycls: A Python package for structural clustering](https://joss.theoj.org/papers/10.21105/joss.03723). Paret et al., (2021). Journal of Open Source Software, 6(67), 3723*\n\nBibtex entry:\n```\n@article{Paret2021,\n  doi = {10.21105/joss.03723},\n  url = {https://doi.org/10.21105/joss.03723},\n  year = {2021},\n  publisher = {The Open Journal},\n  volume = {6},\n  number = {67},\n  pages = {3723},\n  author = {Joris Paret and Daniele Coslovich},\n  title = {partycls: A Python package for structural clustering},\n  journal = {Journal of Open Source Software}\n}\n```\n\nAuthors\n-------\n\n[Joris Paret](https://www.jorisparet.com/)\n\n[Daniele Coslovich](https://www.units.it/daniele.coslovich/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjorisparet%2Fpartycls","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjorisparet%2Fpartycls","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjorisparet%2Fpartycls/lists"}