-
Notifications
You must be signed in to change notification settings - Fork 11
Adding recipes and logger module #105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
42 commits
Select commit
Hold shift + click to select a range
7a6b97d
Added recipoe for simple descriptors calculation.
matteobecchi 80bc4a0
Added recipe on PCA.
matteobecchi 237baa9
Added recipe for TICA.
matteobecchi 64b0eb5
Added recipe for tSOAP.
matteobecchi a7b1aad
Code improved; added function to compute or load soap in utilities.
matteobecchi a8cbf3e
Some improvements in docs.
matteobecchi 5d92f87
Improved code readibility.
matteobecchi 10f3960
WIP on the third recipe.
matteobecchi 8a6c354
WIP for info_gain recipe.
matteobecchi 91f6450
Logging class implemented.
matteobecchi 05d6fdc
Added logging to Trj class.
matteobecchi 27d0e81
Added deeptime dependecies.
matteobecchi aee3046
Logging added to Insight methods.
matteobecchi 2b3ead3
Added pytests for logging.
matteobecchi b34f93b
deeptime dependecies is now automatically installed.
matteobecchi e2395a9
deeptime dependecies is now automatically installed.
matteobecchi d470bf8
Explicitly saing 'is not None' for file paths.
matteobecchi e929dfe
Using standard dictionary for logging args in method calls.
matteobecchi ff2c3bb
Logging added to the ClusterInsight classes.
matteobecchi aba2279
Error raising added to logging.
matteobecchi e597fb4
WIP on third recipe.
matteobecchi 818fe54
Adding a page of documentation for dynsight.trajectory.
matteobecchi 93bf483
WIP on the third recipe.
matteobecchi 9963146
v1 of third recipe working; cleaned file names.
matteobecchi a674388
Added info_plot function to third recipe.
matteobecchi bf2bbb4
Minor adjustments.
matteobecchi 9c2778f
Dataset changed for maningful results.
matteobecchi 14b21dd
Added description of fig.
matteobecchi e0e197c
Added Trj.n_atoms, Trj.n_frames.
matteobecchi 7de8040
Added warnings on directories.
matteobecchi d710b02
Minor improvements.
matteobecchi af0b828
All the imports at the top.
matteobecchi 14886f9
Solving typos.
matteobecchi dd284c4
Minor improvements.
matteobecchi d08fc47
Improved code explanation.
matteobecchi 51724ad
Improved code explanation.
matteobecchi 6f3e647
Added how to get started section in docs.
matteobecchi 82a1e6f
Solving mypy problems.
matteobecchi e545635
Added downloadable script from recipes.
matteobecchi 1a439e8
Removing useless mypy stuff.
matteobecchi d41e46f
Solving mypy issue.
matteobecchi 36f52f2
Solving mypy issue for real.
matteobecchi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| """Copyable code for the recipes.""" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| """Copiable code from Recipe #1.""" | ||
|
|
||
| from pathlib import Path | ||
|
|
||
| from dynsight.trajectory import Trj | ||
|
|
||
|
|
||
| def main() -> None: | ||
| """Code from the Recipe #1.""" | ||
| # Loading an example trajectory | ||
| files_path = Path("../tests/systems/") | ||
| trj = Trj.init_from_xtc( | ||
| traj_file=files_path / "balls_7_nvt.xtc", | ||
| topo_file=files_path / "balls_7_nvt.gro", | ||
| ) | ||
|
|
||
| _ = trj.get_soap( | ||
| r_cut=2.0, # cutoff radius for neighbors list | ||
| n_max=4, # n_max SOAP parameter | ||
| l_max=4, # l_max SOAP parameter | ||
| selection="all", # compute on a selection of particles | ||
| centers="all", # compute for a selection of centers | ||
| respect_pbc=False, # consider PBC | ||
| n_core=1, # use multiprocessing to speed up calculations | ||
| ) | ||
|
|
||
| # Loading an example trajectory | ||
| files_path = Path("../tests/systems/") | ||
| trj = Trj.init_from_xtc( | ||
| traj_file=files_path / "balls_7_nvt.xtc", | ||
| topo_file=files_path / "balls_7_nvt.gro", | ||
| ) | ||
|
|
||
| # Computing number of neighbors from scratch | ||
| neigcounts, n_neig = trj.get_coord_number( | ||
| r_cut=2.0, # cutoff radius for neighbors list | ||
| selection="all", # compute on a selection of particles | ||
| neigcounts=None, # it will be computed and returned | ||
| ) | ||
|
|
||
| # Now for LENS we already have neigcounts | ||
| _, lens = trj.get_lens( | ||
| r_cut=2.0, # cutoff radius for neighbors list | ||
| selection="all", # compute on a selection of particles | ||
| neigcounts=neigcounts, # no need to compute it again | ||
| ) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,179 @@ | ||
| """Copiable code from Recipe #3.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from pathlib import Path | ||
| from typing import TYPE_CHECKING | ||
|
|
||
| if TYPE_CHECKING: | ||
| from numpy.typing import NDArray | ||
|
|
||
| import matplotlib.pyplot as plt | ||
| import numpy as np | ||
|
|
||
| import dynsight | ||
|
|
||
|
|
||
| def info_gain_with_onion( | ||
| delta_t_list: NDArray[np.int64] | list[int], | ||
| data: NDArray[np.float64], | ||
| n_bins: int = 40, | ||
| ) -> tuple[ | ||
| NDArray[np.int64], | ||
| NDArray[np.float64], | ||
| NDArray[np.float64], | ||
| NDArray[np.float64], | ||
| float, | ||
| ]: | ||
| """Performs full information gain analysis with Onion clustering.""" | ||
| data_range = (np.min(data), np.max(data)) | ||
|
|
||
| n_clusters = np.zeros(len(delta_t_list), dtype=int) | ||
| clusters_frac = [] | ||
| info_gain = np.zeros(len(delta_t_list)) | ||
| clusters_entr = [] | ||
|
|
||
| for i, delta_t in enumerate(delta_t_list): | ||
| state_list, labels = dynsight.onion.onion_uni_smooth( | ||
| data, | ||
| delta_t=delta_t, | ||
| ) | ||
|
|
||
| n_clusters[i] = len(state_list) | ||
| tmp_frac = [0.0] + [state.perc for state in state_list] | ||
| tmp_frac[0] = 1.0 - np.sum(tmp_frac) | ||
| clusters_frac.append(tmp_frac) | ||
|
|
||
| flat_data = data.flatten() | ||
| flat_labels = labels.flatten() | ||
| info_gain[i], _, h_0, _ = dynsight.analysis.compute_entropy_gain( | ||
| flat_data, | ||
| flat_labels, | ||
| n_bins=n_bins, | ||
| ) | ||
|
|
||
| tmp_entr = [] | ||
| label_list = np.unique(labels) | ||
| if label_list[0] != -1: | ||
| tmp_entr.append(-1.0) | ||
|
|
||
| for _, lab in enumerate(label_list): | ||
| mask = labels == lab | ||
| selected_points = data[mask] | ||
| tmp_entr.append( | ||
| dynsight.analysis.compute_shannon( | ||
| selected_points, | ||
| data_range, | ||
| n_bins=n_bins, | ||
| ) | ||
| ) | ||
| clusters_entr.append(tmp_entr) | ||
|
|
||
| max_n_envs = np.max([len(elem) for elem in clusters_entr]) | ||
| for i, elem in enumerate(clusters_entr): | ||
| while len(elem) < max_n_envs: | ||
| elem.append(-1.0) | ||
| clusters_frac[i].append(0.0) | ||
|
|
||
| cl_frac = np.array(clusters_frac, dtype=float) | ||
| cl_entr = np.array(clusters_entr) | ||
|
|
||
| return n_clusters, cl_frac, info_gain, cl_entr, h_0 | ||
|
|
||
|
|
||
| def plot_info_results( | ||
| delta_t_list: NDArray[np.int64] | list[int], | ||
| cl_frac: NDArray[np.float64], | ||
| cl_entr: NDArray[np.float64], | ||
| h_0: float, | ||
| file_path: Path, | ||
| ) -> None: | ||
| """Plot information gain as a function of ∆t.""" | ||
| frac = cl_frac.T | ||
| entr = cl_entr.T | ||
| s_list = [] | ||
| for i, st_fr in enumerate(frac): | ||
| s_list.append(st_fr * entr[i]) | ||
| s_cumul = [s_list[0]] | ||
| for _, tmp_s in enumerate(s_list[1:]): | ||
| s_cumul.append(s_cumul[-1] + tmp_s) | ||
|
|
||
| fig, ax = plt.subplots() | ||
|
|
||
| i_0 = (1 - h_0) * np.ones(len(delta_t_list)) | ||
| ax.plot(delta_t_list, i_0, ls="--", c="black", marker="") # I_0 | ||
| ax.fill_between( | ||
| delta_t_list, | ||
| 1, | ||
| 1 - s_cumul[0], | ||
| alpha=0.5, | ||
| ) | ||
| for i, tmp_s in enumerate(s_cumul[1:]): | ||
| ax.fill_between( | ||
| delta_t_list, | ||
| 1 - s_cumul[i], | ||
| 1 - tmp_s, | ||
| alpha=0.5, | ||
| ) | ||
| ax.fill_between( | ||
| delta_t_list, | ||
| 1 - s_cumul[-1], | ||
| 1 - h_0, | ||
| color="gainsboro", | ||
| ) | ||
| ax.plot( | ||
| delta_t_list, | ||
| 1 - s_cumul[-1], | ||
| c="black", | ||
| marker="", | ||
| ) # I_clust | ||
|
|
||
| ax.set_ylim(0.0, 1.0) | ||
| ax.set_xlabel(r"Time resolution $\Delta t$") | ||
| ax.set_ylabel(r"Information $I$") | ||
| ax.set_xscale("log") | ||
|
|
||
| fig.savefig(file_path, dpi=600) | ||
| plt.close() | ||
|
|
||
|
|
||
| def main() -> None: | ||
| """Copiable code from Recipe #3.""" | ||
| rng = np.random.default_rng(1234) | ||
|
|
||
| n_atoms = 10 | ||
| num_blocks = 10 | ||
| block_size = 100 | ||
| sigma = 0.1 | ||
|
|
||
| # Generate the array | ||
| tmp_data = [ | ||
| np.concatenate( | ||
| [ | ||
| rng.normal(loc=(i % 2), scale=sigma, size=block_size) | ||
| for i in range(num_blocks) | ||
| ] | ||
| ) | ||
| for _ in range(n_atoms) | ||
| ] | ||
| data = np.array(tmp_data) | ||
|
|
||
| _, n_frames = data.shape | ||
| delta_t_list = np.unique(np.geomspace(2, n_frames, 10, dtype=int)) | ||
|
|
||
| n_cl, cl_frac, info_gain, cl_entr, h_0 = info_gain_with_onion( | ||
| delta_t_list, | ||
| data, | ||
| ) | ||
|
|
||
| plot_info_results( | ||
| delta_t_list, | ||
| cl_frac, | ||
| cl_entr, | ||
| h_0, | ||
| Path("./source/_static/info_plot.png"), | ||
| ) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.