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
🧪 Panel-Chemistry - exploratory data analysis and build powerful data and viz tools within the domain of Chemistry using Python and HoloViz Panel.

🧪📈 🐍. The purpose of the panel-chemistry project is to make it really easy for you to do DATA ANALYSIS and build powerful DATA AND VIZ APPLICATIONS within the domain of Chemistry using using Python a

Marc Skov Madsen 97 Dec 08, 2022
Karate Club: An API Oriented Open-source Python Framework for Unsupervised Learning on Graphs (CIKM 2020)

Karate Club is an unsupervised machine learning extension library for NetworkX. Please look at the Documentation, relevant Paper, Promo Video, and Ext

Benedek Rozemberczki 1.8k Jan 09, 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
A 2-dimensional physics engine written in Cairo

A 2-dimensional physics engine written in Cairo

Topology 38 Nov 16, 2022
Predictive Modeling & Analytics on Home Equity Line of Credit

Predictive Modeling & Analytics on Home Equity Line of Credit Data (Python) HMEQ Data Set In this assignment we will use Python to examine a data set

Dhaval Patel 1 Jan 09, 2022
A tool to compare differences between dataframes and create a differences report in Excel

similarpanda A module to check for differences between pandas Dataframes, and generate a report in Excel format. This is helpful in a workplace settin

Andre Pretorius 9 Sep 15, 2022
Tools for the analysis, simulation, and presentation of Lorentz TEM data.

ltempy ltempy is a set of tools for Lorentz TEM data analysis, simulation, and presentation. Features Single Image Transport of Intensity Equation (SI

McMorran Lab 1 Dec 26, 2022
Churn prediction with PySpark

It is expected to develop a machine learning model that can predict customers who will leave the company.

3 Aug 13, 2021
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
Analyze the Gravitational wave data stored at LIGO/VIRGO observatories

Gravitational-Wave-Analysis This project showcases how to analyze the Gravitational wave data stored at LIGO/VIRGO observatories, using Python program

1 Jan 23, 2022
A Pythonic introduction to methods for scaling your data science and machine learning work to larger datasets and larger models, using the tools and APIs you know and love from the PyData stack (such as numpy, pandas, and scikit-learn).

This tutorial's purpose is to introduce Pythonistas to methods for scaling their data science and machine learning work to larger datasets and larger models, using the tools and APIs they know and lo

Coiled 102 Nov 10, 2022
Display the behaviour of a realtime program with a scope or logic analyser.

1. A monitor for realtime MicroPython code This library provides a means of examining the behaviour of a running system. It was initially designed to

Peter Hinch 17 Dec 05, 2022
Elasticsearch tool for easily collecting and batch inserting Python data and pandas DataFrames

ElasticBatch Elasticsearch buffer for collecting and batch inserting Python data and pandas DataFrames Overview ElasticBatch makes it easy to efficien

Dan Kaslovsky 21 Mar 16, 2022
A pipeline that creates consensus sequences from a Nanopore reads. I

A pipeline that creates consensus sequences from a Nanopore reads. It clusters reads that are similar to each other and creates a consensus that is then identified using BLAST.

Ada Madejska 2 May 15, 2022
An Indexer that works out-of-the-box when you have less than 100K stored Documents

U100KIndexer An Indexer that works out-of-the-box when you have less than 100K stored Documents. U100K means under 100K. At 100K stored Documents with

Jina AI 7 Mar 15, 2022
Desafio proposto pela IGTI em seu bootcamp de Cloud Data Engineer

Desafio Modulo 4 - Cloud Data Engineer Bootcamp - IGTI Objetivos Criar infraestrutura como código Utuilizando um cluster Kubernetes na Azure Ingestão

Otacilio Filho 4 Jan 23, 2022
This is an analysis and prediction project for house prices in King County, USA based on certain features of the house

This is a project for analysis and estimation of House Prices in King County USA The .csv file contains the data of the house and the .ipynb file con

Amit Prakash 1 Jan 21, 2022
Python Practicum - prepare for your Data Science interview or get a refresher.

Python-Practicum Python Practicum - prepare for your Data Science interview or get a refresher. Data Data visualization using data on births from the

Jovan Trajceski 1 Jul 27, 2021
Intercepting proxy + analysis toolkit for Second Life compatible virtual worlds

Hippolyzer Hippolyzer is a revival of Linden Lab's PyOGP library targeting modern Python 3, with a focus on debugging issues in Second Life-compatible

Salad Dais 6 Sep 01, 2022
Option Pricing Calculator using the Binomial Pricing Method (No Libraries Required)

Binomial Option Pricing Calculator Option Pricing Calculator using the Binomial Pricing Method (No Libraries Required) Background A derivative is a fi

sammuhrai 1 Nov 29, 2021