reaxkit 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. reaxkit/__init__.py +0 -0
  2. reaxkit/analysis/__init__.py +0 -0
  3. reaxkit/analysis/composed/RDF_analyzer.py +560 -0
  4. reaxkit/analysis/composed/__init__.py +0 -0
  5. reaxkit/analysis/composed/connectivity_analyzer.py +706 -0
  6. reaxkit/analysis/composed/coordination_analyzer.py +144 -0
  7. reaxkit/analysis/composed/electrostatics_analyzer.py +687 -0
  8. reaxkit/analysis/per_file/__init__.py +0 -0
  9. reaxkit/analysis/per_file/control_analyzer.py +165 -0
  10. reaxkit/analysis/per_file/eregime_analyzer.py +108 -0
  11. reaxkit/analysis/per_file/ffield_analyzer.py +305 -0
  12. reaxkit/analysis/per_file/fort13_analyzer.py +79 -0
  13. reaxkit/analysis/per_file/fort57_analyzer.py +106 -0
  14. reaxkit/analysis/per_file/fort73_analyzer.py +61 -0
  15. reaxkit/analysis/per_file/fort74_analyzer.py +65 -0
  16. reaxkit/analysis/per_file/fort76_analyzer.py +191 -0
  17. reaxkit/analysis/per_file/fort78_analyzer.py +154 -0
  18. reaxkit/analysis/per_file/fort79_analyzer.py +83 -0
  19. reaxkit/analysis/per_file/fort7_analyzer.py +393 -0
  20. reaxkit/analysis/per_file/fort99_analyzer.py +411 -0
  21. reaxkit/analysis/per_file/molfra_analyzer.py +359 -0
  22. reaxkit/analysis/per_file/params_analyzer.py +258 -0
  23. reaxkit/analysis/per_file/summary_analyzer.py +84 -0
  24. reaxkit/analysis/per_file/trainset_analyzer.py +84 -0
  25. reaxkit/analysis/per_file/vels_analyzer.py +95 -0
  26. reaxkit/analysis/per_file/xmolout_analyzer.py +528 -0
  27. reaxkit/cli.py +181 -0
  28. reaxkit/count_loc.py +276 -0
  29. reaxkit/data/alias.yaml +89 -0
  30. reaxkit/data/constants.yaml +27 -0
  31. reaxkit/data/reaxff_input_files_contents.yaml +186 -0
  32. reaxkit/data/reaxff_output_files_contents.yaml +301 -0
  33. reaxkit/data/units.yaml +38 -0
  34. reaxkit/help/__init__.py +0 -0
  35. reaxkit/help/help_index_loader.py +531 -0
  36. reaxkit/help/introspection_utils.py +131 -0
  37. reaxkit/io/__init__.py +0 -0
  38. reaxkit/io/base_handler.py +165 -0
  39. reaxkit/io/generators/__init__.py +0 -0
  40. reaxkit/io/generators/control_generator.py +123 -0
  41. reaxkit/io/generators/eregime_generator.py +341 -0
  42. reaxkit/io/generators/geo_generator.py +967 -0
  43. reaxkit/io/generators/trainset_generator.py +1758 -0
  44. reaxkit/io/generators/tregime_generator.py +113 -0
  45. reaxkit/io/generators/vregime_generator.py +164 -0
  46. reaxkit/io/generators/xmolout_generator.py +304 -0
  47. reaxkit/io/handlers/__init__.py +0 -0
  48. reaxkit/io/handlers/control_handler.py +209 -0
  49. reaxkit/io/handlers/eregime_handler.py +122 -0
  50. reaxkit/io/handlers/ffield_handler.py +812 -0
  51. reaxkit/io/handlers/fort13_handler.py +123 -0
  52. reaxkit/io/handlers/fort57_handler.py +143 -0
  53. reaxkit/io/handlers/fort73_handler.py +145 -0
  54. reaxkit/io/handlers/fort74_handler.py +155 -0
  55. reaxkit/io/handlers/fort76_handler.py +195 -0
  56. reaxkit/io/handlers/fort78_handler.py +142 -0
  57. reaxkit/io/handlers/fort79_handler.py +227 -0
  58. reaxkit/io/handlers/fort7_handler.py +264 -0
  59. reaxkit/io/handlers/fort99_handler.py +128 -0
  60. reaxkit/io/handlers/geo_handler.py +224 -0
  61. reaxkit/io/handlers/molfra_handler.py +184 -0
  62. reaxkit/io/handlers/params_handler.py +137 -0
  63. reaxkit/io/handlers/summary_handler.py +135 -0
  64. reaxkit/io/handlers/trainset_handler.py +658 -0
  65. reaxkit/io/handlers/vels_handler.py +293 -0
  66. reaxkit/io/handlers/xmolout_handler.py +174 -0
  67. reaxkit/utils/__init__.py +0 -0
  68. reaxkit/utils/alias.py +219 -0
  69. reaxkit/utils/cache.py +77 -0
  70. reaxkit/utils/constants.py +75 -0
  71. reaxkit/utils/equation_of_states.py +96 -0
  72. reaxkit/utils/exceptions.py +27 -0
  73. reaxkit/utils/frame_utils.py +175 -0
  74. reaxkit/utils/log.py +43 -0
  75. reaxkit/utils/media/__init__.py +0 -0
  76. reaxkit/utils/media/convert.py +90 -0
  77. reaxkit/utils/media/make_video.py +91 -0
  78. reaxkit/utils/media/plotter.py +812 -0
  79. reaxkit/utils/numerical/__init__.py +0 -0
  80. reaxkit/utils/numerical/extrema_finder.py +96 -0
  81. reaxkit/utils/numerical/moving_average.py +103 -0
  82. reaxkit/utils/numerical/numerical_calcs.py +75 -0
  83. reaxkit/utils/numerical/signal_ops.py +135 -0
  84. reaxkit/utils/path.py +55 -0
  85. reaxkit/utils/units.py +104 -0
  86. reaxkit/webui/__init__.py +0 -0
  87. reaxkit/webui/app.py +0 -0
  88. reaxkit/webui/components.py +0 -0
  89. reaxkit/webui/layouts.py +0 -0
  90. reaxkit/webui/utils.py +0 -0
  91. reaxkit/workflows/__init__.py +0 -0
  92. reaxkit/workflows/composed/__init__.py +0 -0
  93. reaxkit/workflows/composed/coordination_workflow.py +393 -0
  94. reaxkit/workflows/composed/electrostatics_workflow.py +587 -0
  95. reaxkit/workflows/composed/xmolout_fort7_workflow.py +343 -0
  96. reaxkit/workflows/meta/__init__.py +0 -0
  97. reaxkit/workflows/meta/help_workflow.py +136 -0
  98. reaxkit/workflows/meta/introspection_workflow.py +235 -0
  99. reaxkit/workflows/meta/make_video_workflow.py +61 -0
  100. reaxkit/workflows/meta/plotter_workflow.py +601 -0
  101. reaxkit/workflows/per_file/__init__.py +0 -0
  102. reaxkit/workflows/per_file/control_workflow.py +110 -0
  103. reaxkit/workflows/per_file/eregime_workflow.py +267 -0
  104. reaxkit/workflows/per_file/ffield_workflow.py +390 -0
  105. reaxkit/workflows/per_file/fort13_workflow.py +86 -0
  106. reaxkit/workflows/per_file/fort57_workflow.py +137 -0
  107. reaxkit/workflows/per_file/fort73_workflow.py +151 -0
  108. reaxkit/workflows/per_file/fort74_workflow.py +88 -0
  109. reaxkit/workflows/per_file/fort76_workflow.py +188 -0
  110. reaxkit/workflows/per_file/fort78_workflow.py +135 -0
  111. reaxkit/workflows/per_file/fort79_workflow.py +314 -0
  112. reaxkit/workflows/per_file/fort7_workflow.py +592 -0
  113. reaxkit/workflows/per_file/fort83_workflow.py +60 -0
  114. reaxkit/workflows/per_file/fort99_workflow.py +223 -0
  115. reaxkit/workflows/per_file/geo_workflow.py +554 -0
  116. reaxkit/workflows/per_file/molfra_workflow.py +577 -0
  117. reaxkit/workflows/per_file/params_workflow.py +135 -0
  118. reaxkit/workflows/per_file/summary_workflow.py +161 -0
  119. reaxkit/workflows/per_file/trainset_workflow.py +356 -0
  120. reaxkit/workflows/per_file/tregime_workflow.py +79 -0
  121. reaxkit/workflows/per_file/vels_workflow.py +309 -0
  122. reaxkit/workflows/per_file/vregime_workflow.py +75 -0
  123. reaxkit/workflows/per_file/xmolout_workflow.py +678 -0
  124. reaxkit-1.0.0.dist-info/METADATA +128 -0
  125. reaxkit-1.0.0.dist-info/RECORD +130 -0
  126. reaxkit-1.0.0.dist-info/WHEEL +5 -0
  127. reaxkit-1.0.0.dist-info/entry_points.txt +2 -0
  128. reaxkit-1.0.0.dist-info/licenses/AUTHORS.md +20 -0
  129. reaxkit-1.0.0.dist-info/licenses/LICENSE +21 -0
  130. reaxkit-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,393 @@
1
+ """
2
+ fort.7 analysis utilities.
3
+
4
+ This module provides functions for extracting atom-level and iteration-level
5
+ features from a parsed ReaxFF ``fort.7`` file, as well as higher-level
6
+ coordination analysis when combined with ``xmolout``.
7
+
8
+ Typical use cases include:
9
+
10
+ - extracting per-atom quantities such as partial charges or bond-order sums
11
+ - extracting per-iteration (summary) quantities from the simulation table
12
+ - classifying atomic coordination (under / proper / over) across frames
13
+ """
14
+
15
+
16
+ from __future__ import annotations
17
+ import re
18
+ import pandas as pd
19
+ from collections.abc import Mapping
20
+
21
+ from reaxkit.utils.frame_utils import resolve_indices
22
+ from typing import Iterable, List, Sequence, Union
23
+ from reaxkit.io.handlers.xmolout_handler import XmoloutHandler
24
+ from reaxkit.analysis.composed.coordination_analyzer import (
25
+ classify_coordination_for_frame,
26
+ status_label,
27
+ )
28
+
29
+ Indexish = Union[int, Iterable[int], None]
30
+
31
+ # --------------------------- frame/column helpers ---------------------------
32
+ def _resolve_columns(
33
+ df_example: pd.DataFrame,
34
+ columns: Union[str, Sequence[str]],
35
+ regex: bool = False,
36
+ must_exist: bool = True,
37
+ ) -> List[str]:
38
+ """
39
+ Map requested column name(s) or regex pattern(s) to real DataFrame columns.
40
+ """
41
+ if isinstance(columns, str):
42
+ columns = [columns]
43
+
44
+ resolved: List[str] = []
45
+ cols = list(df_example.columns)
46
+
47
+ for spec in columns:
48
+ if regex:
49
+ pat = re.compile(spec)
50
+ matches = [c for c in cols if pat.search(c)]
51
+ resolved.extend(matches)
52
+ else:
53
+ if spec in cols:
54
+ resolved.append(spec)
55
+ elif not must_exist:
56
+ # skip silently
57
+ pass
58
+ else:
59
+ raise KeyError(f"Column '{spec}' not found. Example columns: {cols[:10]} ...")
60
+
61
+ # de-dup preserving order
62
+ out, seen = [], set()
63
+ for c in resolved:
64
+ if c not in seen:
65
+ out.append(c)
66
+ seen.add(c)
67
+
68
+ if must_exist and not out:
69
+ raise KeyError("No columns matched the request.")
70
+ return out
71
+
72
+
73
+ # --------------------------- atom-level features ---------------------------
74
+
75
+ def get_fort7_data_per_atom(
76
+ handler,
77
+ columns: Union[str, Sequence[str]],
78
+ frames: Indexish = None,
79
+ iterations: Indexish = None,
80
+ regex: bool = False,
81
+ add_index_cols: bool = True,
82
+ ) -> pd.DataFrame:
83
+ """Extract per-atom feature columns across selected frames.
84
+
85
+ Works on
86
+ --------
87
+ Fort7Handler — ``fort.7``
88
+
89
+ Parameters
90
+ ----------
91
+ handler : Fort7Handler
92
+ Parsed ``fort.7`` handler.
93
+ columns : str or sequence of str
94
+ Atom-level column name(s) to extract (e.g. ``partial_charge``,
95
+ ``sum_BOs``). Regex patterns are allowed if ``regex=True``.
96
+ frames : int or iterable of int, optional
97
+ Frame indices to include.
98
+ iterations : int or iterable of int, optional
99
+ Iteration numbers to include.
100
+ regex : bool, default=False
101
+ Whether ``columns`` should be interpreted as regular expressions.
102
+ add_index_cols : bool, default=True
103
+ If True, include ``frame_idx``, ``iter``, and ``atom_idx`` columns.
104
+
105
+ Returns
106
+ -------
107
+ pandas.DataFrame
108
+ Tidy table with one row per atom per frame, including requested
109
+ feature columns and index metadata.
110
+
111
+ Examples
112
+ --------
113
+ >>> df = get_fort7_data_per_atom(f7, "partial_charge", frames=0)
114
+ >>> df = get_fort7_data_per_atom(f7, r"^atom_cnn\\d+$", regex=True)
115
+ """
116
+ sim_df = handler.dataframe()
117
+ idx_list = resolve_indices(handler, frames, iterations)
118
+
119
+ out_frames = []
120
+ for fi in idx_list:
121
+ atoms = handler._frames[fi]
122
+ cols = _resolve_columns(atoms, columns, regex=regex, must_exist=True)
123
+ part = atoms[cols].copy()
124
+ if add_index_cols:
125
+ part.insert(0, "atom_idx", range(len(part)))
126
+ part.insert(0, "iter", int(sim_df.iloc[fi]["iter"]))
127
+ part.insert(0, "frame_idx", fi)
128
+ out_frames.append(part)
129
+
130
+ if not out_frames:
131
+ return pd.DataFrame(columns=(["frame_idx", "iter", "atom_idx"] if add_index_cols else []) + (columns if isinstance(columns, list) else [columns]))
132
+ return pd.concat(out_frames, ignore_index=True)
133
+
134
+
135
+ # ------------------------- iter-level features -------------------------
136
+
137
+ def get_fort7_data_summaries(
138
+ handler,
139
+ columns: Union[str, Sequence[str]],
140
+ frames: Indexish = None,
141
+ iterations: Indexish = None,
142
+ regex: bool = False,
143
+ add_index_cols: bool = True,
144
+ ) -> pd.DataFrame:
145
+ """Extract per-iteration (summary) feature columns from a ``fort.7`` file.
146
+
147
+ Works on
148
+ --------
149
+ Fort7Handler — ``fort.7``
150
+
151
+ Parameters
152
+ ----------
153
+ handler : Fort7Handler
154
+ Parsed ``fort.7`` handler.
155
+ columns : str or sequence of str
156
+ Summary-level column name(s) to extract.
157
+ frames : int or iterable of int, optional
158
+ Frame indices to include.
159
+ iterations : int or iterable of int, optional
160
+ Iteration numbers to include.
161
+ regex : bool, default=False
162
+ Whether ``columns`` should be interpreted as regular expressions.
163
+ add_index_cols : bool, default=True
164
+ If True, include ``frame_idx`` and ``iter`` columns.
165
+
166
+ Returns
167
+ -------
168
+ pandas.DataFrame
169
+ Table with one row per selected frame containing summary quantities.
170
+
171
+ Examples
172
+ --------
173
+ >>> df = get_fort7_data_summaries(f7, ["num_bonds", "total_BO"])
174
+ >>> df = get_fort7_data_summaries(f7, r"^total_.*$", regex=True)
175
+ """
176
+ sim_df = handler.dataframe()
177
+ idx_list = resolve_indices(handler, frames, iterations)
178
+
179
+ if len(sim_df) == 0:
180
+ return pd.DataFrame()
181
+
182
+ cols = _resolve_columns(sim_df, columns, regex=regex, must_exist=True)
183
+ part = sim_df.iloc[idx_list][cols].reset_index(drop=True)
184
+
185
+ if add_index_cols and "iter" not in part.columns:
186
+ # Provide iter + frame_idx for context if the user didn't request iter
187
+ meta_df = sim_df.loc[idx_list, ["iter"]].reset_index(drop=True)
188
+ meta_df.insert(0, "frame_idx", idx_list)
189
+ part = pd.concat([meta_df, part], axis=1)
190
+ elif add_index_cols and "iter" in part.columns:
191
+ part.insert(0, "frame_idx", idx_list)
192
+
193
+ return part
194
+
195
+
196
+ # ---------------------------- convenience slices ----------------------------
197
+
198
+ def get_partial_charges_conv_fnc(
199
+ handler,
200
+ frames: Indexish = None,
201
+ iterations: Indexish = None,
202
+ ) -> pd.DataFrame:
203
+ """
204
+ Convenience function to extract per-atom partial charges across selected frames.
205
+
206
+ Works on
207
+ --------
208
+ Fort7Handler — ``fort.7``
209
+
210
+ Parameters
211
+ ----------
212
+ handler : Fort7Handler
213
+ Parsed ``fort.7`` handler.
214
+ frames, iterations
215
+ Frame indices or iteration numbers to include.
216
+
217
+ Returns
218
+ -------
219
+ pandas.DataFrame
220
+ Per-atom partial charges with frame and atom indices.
221
+
222
+ Examples
223
+ --------
224
+ >>> df = get_partial_charges_conv_fnc(f7, frames=0)
225
+ """
226
+ return get_fort7_data_per_atom(handler, "partial_charge", frames=frames, iterations=iterations)
227
+
228
+
229
+ def get_all_atoms_cnn_conv_fnc(
230
+ handler,
231
+ frames: Indexish = None,
232
+ iterations: Indexish = None,
233
+ ) -> pd.DataFrame:
234
+ """
235
+ Convenience function to extract all ``atom_cnn*`` connectivity columns across selected frames.
236
+
237
+ Works on
238
+ --------
239
+ Fort7Handler — ``fort.7``
240
+
241
+ Parameters
242
+ ----------
243
+ handler : Fort7Handler
244
+ Parsed ``fort.7`` handler.
245
+ frames, iterations
246
+ Frame indices or iteration numbers to include.
247
+
248
+ Returns
249
+ -------
250
+ pandas.DataFrame
251
+ Per-atom connectivity values with frame and atom indices.
252
+
253
+ Examples
254
+ --------
255
+ >>> df = get_all_atoms_cnn_conv_fnc(f7)
256
+ """
257
+ return get_fort7_data_per_atom(handler, r"^atom_cnn\d+$", frames=frames, iterations=iterations, regex=True)
258
+
259
+ def get_sum_bos_conv_fnc(
260
+ handler,
261
+ frames: Indexish = None,
262
+ iterations: Indexish = None,
263
+ ) -> pd.DataFrame:
264
+ """
265
+ Convenience function to extract per-atom total bond order (``sum_BOs``) across selected frames.
266
+
267
+ Works on
268
+ --------
269
+ Fort7Handler — ``fort.7``
270
+
271
+ Parameters
272
+ ----------
273
+ handler : Fort7Handler
274
+ Parsed ``fort.7`` handler.
275
+ frames, iterations
276
+ Frame indices or iteration numbers to include.
277
+
278
+ Returns
279
+ -------
280
+ pandas.DataFrame
281
+ Tidy table with columns: ``frame_idx``, ``iter``, ``atom_idx``,
282
+ and ``sum_BOs``.
283
+
284
+ Examples
285
+ --------
286
+ >>> df = get_sum_bos_conv_fnc(f7)
287
+ """
288
+ return get_fort7_data_per_atom(
289
+ handler,
290
+ columns="sum_BOs",
291
+ frames=frames,
292
+ iterations=iterations,
293
+ regex=False,
294
+ add_index_cols=True,
295
+ )
296
+
297
+
298
+ # --- Coordination classification using features_atom("sum_BOs") --------------
299
+ def per_atom_coordination_status_over_frames(
300
+ f7_handler,
301
+ xh: XmoloutHandler,
302
+ *,
303
+ valences: Mapping[str, float],
304
+ threshold: float = 0.9,
305
+ frames: Indexish = None,
306
+ iterations: Indexish = None,
307
+ require_all_valences: bool = True,
308
+ ) -> pd.DataFrame:
309
+ """Classify atomic coordination status across frames using bond-order sums.
310
+
311
+ Works on
312
+ --------
313
+ Fort7Handler + XmoloutHandler — ``fort.7`` + ``xmolout``
314
+
315
+ Parameters
316
+ ----------
317
+ f7_handler : Fort7Handler
318
+ Parsed ``fort.7`` handler providing bond-order information.
319
+ xh : XmoloutHandler
320
+ Parsed ``xmolout`` handler providing atom types per frame.
321
+ valences : mapping of str to float
322
+ Reference valence values for each atom type.
323
+ threshold : float, default=0.9
324
+ Tolerance window for under/over-coordination classification.
325
+ frames, iterations
326
+ Frame indices or iteration numbers to include.
327
+ require_all_valences : bool, default=True
328
+ If True, raise an error when a valence is missing for any atom type.
329
+
330
+ Returns
331
+ -------
332
+ pandas.DataFrame
333
+ One row per atom per frame with columns including:
334
+ ``frame_index``, ``iter``, ``atom_id``, ``atom_type``,
335
+ ``sum_BOs``, ``valence``, ``delta``, ``status``, ``status_label``.
336
+
337
+ Examples
338
+ --------
339
+ >>> df = per_atom_coordination_status_over_frames(
340
+ ... f7, xh, valences={"C": 4.0, "H": 1.0}
341
+ ... )
342
+ """
343
+ # Pull sum_BOs in tidy form (frame_idx, iter, atom_idx, sum_BOs)
344
+ df_sum = get_sum_bos_conv_fnc(f7_handler, frames=frames, iterations=iterations)
345
+ if df_sum.empty:
346
+ return pd.DataFrame(columns=[
347
+ "frame_index","iter","atom_id","atom_type","sum_BOs",
348
+ "valence","delta","status","status_label"
349
+ ])
350
+
351
+ # Group by frame and classify
352
+ rows = []
353
+ for fi, g in df_sum.groupby("frame_idx", sort=True):
354
+ g = g.sort_values("atom_idx")
355
+ sum_vals = g["sum_BOs"].to_numpy(dtype=float)
356
+
357
+ # Atom types for this frame come from xmolout
358
+ fr = xh.frame(int(fi))
359
+ atom_types = fr["atom_types"]
360
+ if len(sum_vals) != len(atom_types):
361
+ raise ValueError(
362
+ f"Length mismatch at frame {fi}: sum_BOs({len(sum_vals)}) vs atom_types({len(atom_types)})"
363
+ )
364
+
365
+ per_atom = classify_coordination_for_frame(
366
+ sum_bos=sum_vals,
367
+ atom_types=atom_types,
368
+ valences=valences,
369
+ threshold=threshold,
370
+ require_all_valences=require_all_valences,
371
+ )
372
+
373
+ # Attach frame metadata
374
+ iter = int(g["iter"].iloc[0]) if "iter" in g.columns else int(fi)
375
+ per_atom.insert(0, "iter", iter)
376
+ per_atom.insert(0, "frame_index", int(fi))
377
+
378
+ # Friendly label
379
+ per_atom["status_label"] = status_label(per_atom["status"])
380
+
381
+ rows.append(per_atom)
382
+
383
+ out = pd.concat(rows, ignore_index=True)
384
+ out = out.sort_values(["frame_index", "atom_id"], kind="mergesort").reset_index(drop=True)
385
+ return out
386
+
387
+
388
+
389
+
390
+
391
+
392
+
393
+