A set of functions and analysis classes for solvation structure analysis

Overview

SolvationAnalysis

Powered by NumFOCUS Powered by MDAnalysis GitHub Actions Status TravisCI codecov docs


The macroscopic behavior of a liquid is determined by its microscopic structure. For ionic systems, like batteries and many enzymes, the solvation environment surrounding ions is especially important. By studying the solvation of interesting materials, scientists can better understand, engineer, and design new technologies. The aim of this project is to implement a robust and cohesive set of methods for solvation analysis that would be widely useful in both biomolecular and battery electrolyte simulations. The core of the solvation module will be a set of functions for easily working with ionic solvation shells. Building from that core functionality, the module will implement several analysis methods for analyzing ion pairing, ion speciation, residence times, and shell association and dissociation.

Main development by @orioncohen, with mentorship from @richardjgowers, @IAlibay, and @hmacdope.

Acknowledgements

Project based on the Computational Molecular Science Python Cookiecutter version 1.5.

Comments
  • analysis functions

    analysis functions

    Description

    This PR will establish the analysis functions for the solvation module. Linked to issues #11, #21, and #28.

    Todos

    Notable points that this PR has either accomplished or will accomplish.

    • [x] create ion speciation class
    • [x] create coordination number class
    • [x] create solvation god class
    • [x] update documentation
    • [x] finalize data structure
    • [x] complete implementation
    • [x] finalize in-line documentation

    Status

    • [x] Ready to go
    core high-priority 
    opened by orionarcher 34
  • Parse RDF's and find minima

    Parse RDF's and find minima

    Description

    Provide a brief description of the PR's purpose here.

    Todos

    • [x] add test data
    • [x] functionality to interpolate rdfs
    • [x] functionality to find minima
    • [x] refine minima finding
    • [x] solidify unit testing

    Status

    • [x] Ready to go
    core testing high-priority 
    opened by orionarcher 20
  • Basic testing with Pytest

    Basic testing with Pytest

    Description

    Set up basic testing for current implemented functions.

    Todos

    Notable points that this PR has either accomplished or will accomplish.

    • [x] get_radial_shell testing
    • [x] get_closest_n_mol testing
    • [x] slightly rework get_closest_n_mol signature

    Status

    • [x] Ready to go
    core testing 
    opened by orionarcher 17
  • tutorials

    tutorials

    Description

    Create a convenient tutorial for users to learn solvation_analysis

    Todos

    Notable points that this PR has either accomplished or will accomplish.

    • [x] jupyter tutorial for users
    • [x] set up jupyter edit requests

    Status

    • [x] Ready to go
    documentation high-priority 
    opened by orionarcher 12
  • Decide hierarchy of analysis classes/methods

    Decide hierarchy of analysis classes/methods

    Some of our proposed functionality follows on directly from other functionality and some does not.

    This means we need to discuss how to compartmentalise functionality into classes and methods many of which will subclass analysis base.

    I thought I would make this issue as an open discussion area for how we want to compartmentalise /hierarchicalize our functionality. I think the best way to proceed is if @orioncohen can lay out how he sees it and then @richardjgowers @IAlibay and any @MDAnalysis/gsoc-mentors can weigh in. We may also need to meet to discuss this. :)

    question core high-priority 
    opened by hmacdope 11
  • add visualization tutorial

    add visualization tutorial

    Description

    Since nglview is causing issues and I don't want to get bogged down before the release, I wanted to put this in a separate thread.

    Todos

    Notable points that this PR has either accomplished or will accomplish.

    • [x] tutorial introduction
    • [x] fix nglview issues
    • [x] finish tutorial

    Questions

    • [x] Why is nglview showing too many bonds on molecules?

    Status

    • [x] Ready to go
    bug documentation enhancement 
    opened by orionarcher 10
  • Initial functions for solvation selection + documentation + testing

    Initial functions for solvation selection + documentation + testing

    Description

    Implements basic functionality for solvation selection. Currently implements get_atom_group, get_n_shells, get_closest_n_mol, and get_radial_shell. Addresses issue #5

    Todos

    Notable points that this PR has either accomplished or will accomplish.

    • [x] implement basic functionality for solvation selection
    • [x] documentation for functions
    • [x] unit tests for basic functionality

    Questions

    • [x] what doc style should be used?

    Status

    • [x] ready to go
    opened by orionarcher 10
  • Support for multi atom solutes

    Support for multi atom solutes

    Description

    This PR was split off from PR #70 to better separate quality-of-life changes from API changes. See that PR for some history and discussion.

    This is intended to be a major PR to handle multi-atom solutes. It relates to issues #47, #66, and #58.

    I would like to propose the following outline of new functionality. In this description, I will focus on the outward facing API. I'll use the somewhat trivial case of water as an example.

    1. Solution will be renamed to Solute. All references to solute in the current documentation will be renamed to solvated atom or solvated atoms. I think this better captures what the Solute class really is, especially as we expand to multi-atom Solutes.

    2. The default initializer for Solute will take only a single atom per residue. It will not support multiple identical atoms on a residue. This will be handled by the more general case. As a result, instantiating a Solute for a single atom remains the same.

    water = u.select_atoms(...)
    water_O = u.select_atoms(...)
    water_O_solute = Solute(water_O, {"water": water})
    
    1. Additional initializers will be added to instantiate a Solute, these will support multi-atom solutes.

    The first will allow the user to stitch together multiple solutes to create a new solute.

    water_H1 = u.select_atoms(...)
    water_H2 = u.select_atoms(...)
    solute_O = Solute(water_O, {"water": water})
    solute_H1 = Solute(water_H1, {"water": water})
    solute_H2 = Solute(water_H2, {"water": water})
    
    multi_atom_solute = Solute.from_solutes([solute_O, solute_H1, solute_H2])  # maybe this should be a dict?
    

    The second will allow users to simply instantiate a solute from an entire residue (or part of a residue). There may be technical challenges here so this behavior is not guaranteed.

    multi_atom_solute = Solute.from_residue(water, {"water": water})
    
    1. To support this, the solvation_data dataframe will have two additional columns added, a "residue" column and a "solute_name" column. All analysis classes will be refactored to operate on the "residue" column rather than the "solvated_atom" column. This will make no difference for single-atom solutes but will allow the analysis classes to generalize easily. I'm not completely sure the "solute_name" column is necessary, but it would be convenient to have.

    2. When a multi-atom solute is created all of the solvation_data dataframes from each constituent single-atom solute will be merged together. The "residue" column will group together solvated atoms on the same residue such that the analysis classes can operate on the whole solute. The API for accessing the residence classes will be identical.

    multi_atom_solute.coordination_number["water"]   # valid property
    
    1. We will retain all of the single atom Solutes as a property of the multi-atom Solute. This would amount to a rough doubling of the memory footprint, but it would make follow up analysis easier. I'm a bit torn here and there may be a better way.
    >>> print(water.atoms)  # what should this be called?
    >>> [solute_O, solute_H1, solute_H2]  # maybe this should be a dict?
    

    For a single atom solute the atoms list would still be present but the data within would be identical to the solvation_data of the solute itself. Single atom solutes are now just a special case of multi-atom solutes.

    water_O_solute.atoms[0].solvation_data = water_O_solute.solvation_data
    

    I'm sure there are many things I am not considering that will come up later, but as a start, I think this plan will allow the package to be generalized with maximum code reuse. I'd love feedback or suggestions on any aspect of the outline above.

    Todos

    Notable points that this PR has either accomplished or will accomplish.

    • [x] make solutions composable so that multi-atom solutes can be constructed systematically
    • [x] put guardrails in place to prevent misuse
    • [ ] bare minimum rewrite of the documentation

    Status

    • [ ] Ready to go
    enhancement core 
    opened by orionarcher 8
  • Residence times and solute-solvent network calculations

    Residence times and solute-solvent network calculations

    Description

    This PR adds an analysis module to calculate residence times and an analysis module to calculate solute-solvent networks.

    Todos

    Notable points that this PR has either accomplished or will accomplish.

    • [x] Residence module
    • [x] Change exponential fit in residence time calculations to 1/e decay point
    • [x] Networking module
    • [x] Residence testing
    • [x] Networking testing
    • [x] Residence documentation
    • [x] Networking documentation
    • [x] Add diluent_composition analysis to Pairing class
    • [x] Add module selection kwarg to Solution
    • [x] Add from_solution class method to all analysis classes
    • [x] Residence and Networking tutorial
    • [x] add citations for Networking and Residence codes
    • [x] improve documentation for Residence time
      • [x] specify caveats and difference between both implementations

    Status

    The PR is nearly finished, the main outstanding issues are improved documentation, citations and tutorials.

    enhancement 
    opened by orionarcher 8
  • Formalize Roadmap in Projects tab

    Formalize Roadmap in Projects tab

    We should decide on a model for a release schedule, Do we wish to match the MDA core idea and do quarterly (@IAlibay is that right?) releases? Or do we just want to do with major functionality change, ie at your discretion @orioncohen?

    If people want updated functionality and bugfixes, they can always clone the current main branch and install with pip install -e .

    Raising issue as food for thought.

    release 
    opened by hmacdope 8
  • Enhancements to support composable Solutions and self-solvating solutes

    Enhancements to support composable Solutions and self-solvating solutes

    UPDATE:

    This PR now implements a number of quality of life changes and solves issue #31. The proposed multi-atom solute changes will be implemented in another PR. See PR #72 for the new changes!

    Todos

    Notable points that this PR has either accomplished or will accomplish.

    • [x] add new testing data with a multi-atom solute
    • [x] remove foolish internal numbering scheme of solvated_atoms
    • [x] allow solutes to also act as solvents
    • [x] replace all column name strings with variables stored in a column_names.py file

    Status

    • [x] Ready to go

    Description

    This is intended to be a major PR to handle multi-atom solutes. It relates to issues #47, #31, #66, and #58.

    I would like to propose the following outline of new functionality. In this description, I will focus on the outward facing API. I'll use the somewhat trivial case of water as an example.

    1. Solution will be renamed to Solute. All references to solute in the current documentation will be renamed to solvated atom or solvated atoms. I think this better captures what the Solute class really is, especially as we expand to multi-atom Solutes.

    2. The default initializer for Solute will take only a single atom per residue. It will not support multiple identical atoms on a residue. This will be handled by the more general case. As a result, instantiating a Solute for a single atom remains the same. (note that I have already fixed the case with self-solvation identified in issue #31)

    water = u.select_atoms(...)
    water_O = u.select_atoms(...)
    water_O_solute = Solute(water_O, {"water": water})
    
    1. Additional initializers will be added to instantiate a Solute, these will support multi-atom solutes.

    The first will allow the user to stitch together multiple solutes to create a new solute.

    water_H1 = u.select_atoms(...)
    water_H2 = u.select_atoms(...)
    solute_O = Solute(water_O, {"water": water})
    solute_H1 = Solute(water_H1, {"water": water})
    solute_H2 = Solute(water_H2, {"water": water})
    
    multi_atom_solute = Solute.from_solutes([solute_O, solute_H1, solute_H2])  # maybe this should be a dict?
    

    The second will allow users to simply instantiate a solute from an entire residue (or part of a residue). There may be technical challenges here so this behavior is not guaranteed.

    multi_atom_solute = Solute.from_residue(water, {"water": water})
    
    1. To support this, the solvation_data dataframe will have two additional columns added, a "residue" column and a "solute_name" column. All analysis classes will be refactored to operate on the "residue" column rather than the "solvated_atom" column. This will make no difference for single-atom solutes but will allow the analysis classes to generalize easily. I'm not completely sure the "solute_name" column is necessary, but it would be convenient to have.

    2. When a multi-atom solute is created all of the solvation_data dataframes from each constituent single-atom solute will be merged together. The "residue" column will group together solvated atoms on the same residue such that the analysis classes can operate on the whole solute. The API for accessing the residence classes will be identical.

    multi_atom_solute.coordination_number["water"]   # valid property
    
    1. We will retain all of the single atom Solutes as a property of the multi-atom Solute. This would amount to a rough doubling of the memory footprint, but it would make follow up analysis easier. I'm a bit torn here and there may be a better way.
    >>> print(water.atoms)  # what should this be called?
    >>> [solute_O, solute_H1, solute_H2]  # maybe this should be a dict?
    

    For a single atom solute the atoms list would still be present but the data within would be identical to the solvation_data of the solute itself. Single atom solutes are now just a special case of multi-atom solutes.

    water_O_solute.atoms[0].solvation_data = water_O_solute.solvation_data
    

    I'm sure there are many things I am not considering that will come up later, but as a start, I think this plan will allow the package to be generalized with maximum code reuse. I'd love feedback or suggestions on any aspect of the outline above.

    Todos

    Notable points that this PR has either accomplished or will accomplish.

    • [x] add new testing data with a multi-atom solute
    • [x] remove foolish internal numbering scheme of solvated_atoms
    • [x] allow solutes to also act as solvents
    • [x] replace all column name strings with variables stored in a column_names.py file
    • [ ] make solutions composable so that multi-atom solutes can be constructed systematically
    • [ ] put guardrails in place to prevent misuse

    Status

    • [ ] Ready to go
    enhancement core high-priority 
    opened by orionarcher 7
  • Concatenation Issue for Residence Time Calculation

    Concatenation Issue for Residence Time Calculation

    I am using Residence.from_solute(solute) to calculate the residence time between trimers' N and water' O. It always reports the same concatenation issue which seems to be caused by the calculation of auto-covariance (Fig 1). However, when I calculate the residence time between anion and water, there isn't this problem. I add the solvation_data of anion solution (Fig 2) and trimer solution for your reference (Fig 3).

    Screen Shot 2022-12-05 at 15 58 01 Screen Shot 2022-12-05 at 15 58 21Fig 1 Screen Shot 2022-12-05 at 15 53 21 Fig 2

    Screen Shot 2022-12-05 at 15 52 53Fig 3

    opened by SophiaRuan 0
  • Styling and consistency of documentation could be improved

    Styling and consistency of documentation could be improved

    This is split off from PR #78 to address two points the consistency and formatting of the documentation.

    Todos:

    • [ ] closely read over all documentation for errors
    • [ ] make sure all syntax and code styling is consistent
    • [ ] enhance aesthetic styling of documentation
    documentation 
    opened by orionarcher 0
  • Work towards MDAKit integration

    Work towards MDAKit integration

    Now that MDAKits are live to roll we should work towards registering solvation-analysis as an MDAKit!

    See the blog post for more info.

    @orionarcher I would be interested to know if you would prefer to just go for it or wait for 0.2.0 (and some conda packages).

    AFAIK solvation-analysis already meets all the requirements listed in the white paper.

    opened by hmacdope 2
  • Solvation plots

    Solvation plots

    Description

    Provide a brief description of the PR's purpose here.

    Todos

    Notable points that this PR has either accomplished or will accomplish.

    • [ ] TODO 1

    Questions

    • [ ] Question1

    Status

    • [ ] Ready to go
    opened by laurlee 1
  • Create a `save_data` method for solution

    Create a `save_data` method for solution

    This method should dump the core solvation statistics to python dict. It will not contain enough information to reconstitute the Solution.

    Brought up in issue #52.

    opened by orionarcher 0
Releases(v0.1.4)
  • v0.1.4(Jun 28, 2022)

  • v0.1.3(Mar 17, 2022)

  • v0.1.2-beta(Sep 23, 2021)

    New functionality:

    • co-occurrence matrix calculation and plotting
    • identify types of coordinating atoms
    • find percentage of free solvent

    Bug fixes:

    • all AtomGroup.ids and ResidueGroup.resids changed to AtomGroup.ix and ResidueGroup.resindices
    Source code(tar.gz)
    Source code(zip)
  • v0.1.2(Sep 23, 2021)

    New functionality:

    • co-occurrence matrix calculation and plotting
    • identify types of coordinating atoms
    • find percentage of free solvent

    Bug fixes:

    • all AtomGroup.ids and ResidueGroup.resids changed to AtomGroup.ix and ResidueGroup.resindices
    Source code(tar.gz)
    Source code(zip)
  • v0.1.1-alpha(Aug 19, 2021)

  • v0.1.1(Aug 19, 2021)

Owner
MDAnalysis
MDAnalysis is an object-oriented Python library to analyze molecular dynamics trajectories.
MDAnalysis
Universal data analysis tools for atmospheric sciences

U_analysis Universal data analysis tools for atmospheric sciences Script written in python 3. This file defines multiple functions that can be used fo

Luis Ackermann 1 Oct 10, 2021
PandaPy has the speed of NumPy and the usability of Pandas 10x to 50x faster (by @firmai)

PandaPy "I came across PandaPy last week and have already used it in my current project. It is a fascinating Python library with a lot of potential to

Derek Snow 527 Jan 02, 2023
PyNHD is a part of HyRiver software stack that is designed to aid in watershed analysis through web services.

A part of HyRiver software stack that provides access to NHD+ V2 data through NLDI and WaterData web services

Taher Chegini 23 Dec 14, 2022
Collections of pydantic models

pydantic-collections The pydantic-collections package provides BaseCollectionModel class that allows you to manipulate collections of pydantic models

Roman Snegirev 20 Dec 26, 2022
talkbox is a scikit for signal/speech processing, to extend scipy capabilities in that domain.

talkbox is a scikit for signal/speech processing, to extend scipy capabilities in that domain.

David Cournapeau 76 Nov 30, 2022
Gathering data of likes on Tinder within the past 7 days

tinder_likes_data Gathering data of Likes Sent on Tinder within the past 7 days. Versions November 25th, 2021 - Functionality to get the name and age

Alex Carter 12 Jan 05, 2023
Shot notebooks resuming the main functions of GeoPandas

Shot notebooks resuming the main functions of GeoPandas, 2 notebooks written as Exercises to apply these functions.

1 Jan 12, 2022
A 2-dimensional physics engine written in Cairo

A 2-dimensional physics engine written in Cairo

Topology 38 Nov 16, 2022
A powerful data analysis package based on mathematical step functions. Strongly aligned with pandas.

The leading use-case for the staircase package is for the creation and analysis of step functions. Pretty exciting huh. But don't hit the close button

48 Dec 21, 2022
Finds, downloads, parses, and standardizes public bikeshare data into a standard pandas dataframe format

Finds, downloads, parses, and standardizes public bikeshare data into a standard pandas dataframe format.

Brady Law 2 Dec 01, 2021
HyperSpy is an open source Python library for the interactive analysis of multidimensional datasets

HyperSpy is an open source Python library for the interactive analysis of multidimensional datasets that can be described as multidimensional arrays o

HyperSpy 411 Dec 27, 2022
Single machine, multiple cards training; mix-precision training; DALI data loader.

Template Script Category Description Category script comparison script train.py, loader.py for single-machine-multiple-cards training train_DP.py, tra

2 Jun 27, 2022
Fast, flexible and easy to use probabilistic modelling in Python.

Please consider citing the JMLR-MLOSS Manuscript if you've used pomegranate in your academic work! pomegranate is a package for building probabilistic

Jacob Schreiber 3k Jan 02, 2023
Accurately separate the TLD from the registered domain and subdomains of a URL, using the Public Suffix List.

tldextract Python Module tldextract accurately separates the gTLD or ccTLD (generic or country code top-level domain) from the registered domain and s

John Kurkowski 1.6k Jan 03, 2023
PyClustering is a Python, C++ data mining library.

pyclustering is a Python, C++ data mining library (clustering algorithm, oscillatory networks, neural networks). The library provides Python and C++ implementations (C++ pyclustering library) of each

Andrei Novikov 1k Jan 05, 2023
OpenARB is an open source program aiming to emulate a free market while encouraging players to participate in arbitrage in order to increase working capital.

Overview OpenARB is an open source program aiming to emulate a free market while encouraging players to participate in arbitrage in order to increase

Tom 3 Feb 12, 2022
ASOUL直播间弹幕抓取&&数据分析

ASOUL直播间弹幕抓取&&数据分析(更新中) 这些文件用于爬取ASOUL直播间的弹幕(其他直播间也可以)和其他信息,以及简单的数据分析生成。

159 Dec 10, 2022
EOD Historical Data Python Library (Unofficial)

EOD Historical Data Python Library (Unofficial) https://eodhistoricaldata.com Installation python3 -m pip install eodhistoricaldata Note Demo API key

Michael Whittle 20 Dec 22, 2022
collect training and calibration data for gaze tracking

Collect Training and Calibration Data for Gaze Tracking This tool allows collecting gaze data necessary for personal calibration or training of eye-tr

Pascal 5 Dec 17, 2022
Projects that implement various aspects of Data Engineering.

DATAWAREHOUSE ON AWS The purpose of this project is to build a datawarehouse to accomodate data of active user activity for music streaming applicatio

2 Oct 14, 2021