reciprocalspaceship 1.0.2__tar.gz → 1.0.4__tar.gz
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.
Potentially problematic release.
This version of reciprocalspaceship might be problematic. Click here for more details.
- {reciprocalspaceship-1.0.2/reciprocalspaceship.egg-info → reciprocalspaceship-1.0.4}/PKG-INFO +43 -3
- reciprocalspaceship-1.0.4/reciprocalspaceship/VERSION +1 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/__init__.py +9 -2
- reciprocalspaceship-1.0.4/reciprocalspaceship/commandline/cifdump.py +115 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/commandline/mtzdump.py +7 -3
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/dataset.py +75 -24
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/decorators.py +6 -2
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/dtypes/internals.py +1 -1
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/io/__init__.py +1 -0
- reciprocalspaceship-1.0.4/reciprocalspaceship/io/common.py +48 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/io/crystfel.py +17 -26
- reciprocalspaceship-1.0.4/reciprocalspaceship/io/dials.py +330 -0
- reciprocalspaceship-1.0.4/reciprocalspaceship/io/dials_mpi.py +44 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/io/mtz.py +4 -5
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/io/precognition.py +2 -2
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/utils/cell.py +1 -1
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/utils/grid.py +2 -1
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/utils/structurefactors.py +1 -1
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4/reciprocalspaceship.egg-info}/PKG-INFO +43 -3
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship.egg-info/SOURCES.txt +5 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship.egg-info/entry_points.txt +1 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship.egg-info/requires.txt +3 -2
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/setup.py +4 -2
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/tests/test_dataset.py +89 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/tests/test_dataset_grid.py +2 -2
- reciprocalspaceship-1.0.4/tests/test_dataset_signatures.py +53 -0
- reciprocalspaceship-1.0.2/reciprocalspaceship/VERSION +0 -1
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/LICENSE +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/MANIFEST.in +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/README.md +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/algorithms/__init__.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/algorithms/intensity.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/algorithms/merge.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/algorithms/scale_merged_intensities.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/commandline/__init__.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/concat.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/dataseries.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/dtypes/__init__.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/dtypes/base.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/dtypes/floating.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/dtypes/inference.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/dtypes/integer.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/dtypes/summarize.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/io/ccp4map.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/io/csv.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/io/pickle.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/stats/__init__.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/stats/completeness.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/utils/__init__.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/utils/asu.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/utils/binning.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/utils/math.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/utils/phases.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/utils/rfree.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/utils/stats.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/utils/symmetry.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/utils/units.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship.egg-info/dependency_links.txt +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship.egg-info/top_level.txt +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/setup.cfg +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/tests/__init__.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/tests/conftest.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/tests/test_dataseries.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/tests/test_dataset_anomalous.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/tests/test_dataset_binning.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/tests/test_dataset_index.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/tests/test_dataset_preserve_attributes.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/tests/test_dataset_symops.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/tests/test_decorators.py +0 -0
- {reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/tests/test_summarize_mtz_dtypes.py +0 -0
{reciprocalspaceship-1.0.2/reciprocalspaceship.egg-info → reciprocalspaceship-1.0.4}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: reciprocalspaceship
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: Tools for exploring reciprocal space
|
|
5
5
|
Home-page: https://rs-station.github.io/reciprocalspaceship/
|
|
6
6
|
Author: Kevin M. Dalton, Jack B. Greisman
|
|
@@ -18,9 +18,49 @@ Classifier: Topic :: Scientific/Engineering :: Physics
|
|
|
18
18
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
19
|
Classifier: Programming Language :: Python
|
|
20
20
|
Requires-Python: >=3.9
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: gemmi<=0.7.1,>=0.7.0
|
|
23
|
+
Requires-Dist: pandas<=2.2.3,>=2.2.2
|
|
24
|
+
Requires-Dist: numpy
|
|
25
|
+
Requires-Dist: scipy
|
|
26
|
+
Requires-Dist: ipython
|
|
27
|
+
Requires-Dist: msgpack
|
|
21
28
|
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-xdist; extra == "dev"
|
|
32
|
+
Requires-Dist: ray; extra == "dev"
|
|
33
|
+
Requires-Dist: sphinx; extra == "dev"
|
|
34
|
+
Requires-Dist: sphinx_rtd_theme; extra == "dev"
|
|
35
|
+
Requires-Dist: nbsphinx; extra == "dev"
|
|
36
|
+
Requires-Dist: sphinx-design; extra == "dev"
|
|
37
|
+
Requires-Dist: sphinxcontrib-autoprogram; extra == "dev"
|
|
38
|
+
Requires-Dist: autodocsumm; extra == "dev"
|
|
39
|
+
Requires-Dist: jupyter; extra == "dev"
|
|
40
|
+
Requires-Dist: tqdm; extra == "dev"
|
|
41
|
+
Requires-Dist: matplotlib; extra == "dev"
|
|
42
|
+
Requires-Dist: seaborn; extra == "dev"
|
|
43
|
+
Requires-Dist: celluloid; extra == "dev"
|
|
44
|
+
Requires-Dist: scikit-image; extra == "dev"
|
|
22
45
|
Provides-Extra: examples
|
|
23
|
-
|
|
46
|
+
Requires-Dist: jupyter; extra == "examples"
|
|
47
|
+
Requires-Dist: tqdm; extra == "examples"
|
|
48
|
+
Requires-Dist: matplotlib; extra == "examples"
|
|
49
|
+
Requires-Dist: seaborn; extra == "examples"
|
|
50
|
+
Requires-Dist: celluloid; extra == "examples"
|
|
51
|
+
Requires-Dist: scikit-image; extra == "examples"
|
|
52
|
+
Dynamic: author
|
|
53
|
+
Dynamic: author-email
|
|
54
|
+
Dynamic: classifier
|
|
55
|
+
Dynamic: description
|
|
56
|
+
Dynamic: home-page
|
|
57
|
+
Dynamic: license
|
|
58
|
+
Dynamic: license-file
|
|
59
|
+
Dynamic: project-url
|
|
60
|
+
Dynamic: provides-extra
|
|
61
|
+
Dynamic: requires-dist
|
|
62
|
+
Dynamic: requires-python
|
|
63
|
+
Dynamic: summary
|
|
24
64
|
|
|
25
65
|
|
|
26
66
|
``reciprocalspaceship`` provides a ``pandas``-style interface for
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.4
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
# Version number for reciprocalspaceship
|
|
2
2
|
def getVersionNumber():
|
|
3
|
-
|
|
3
|
+
version = None
|
|
4
|
+
try:
|
|
5
|
+
from setuptools.version import metadata
|
|
6
|
+
|
|
7
|
+
version = metadata.version("reciprocalspaceship")
|
|
8
|
+
except ImportError:
|
|
9
|
+
from setuptools.version import pkg_resources
|
|
10
|
+
|
|
11
|
+
version = pkg_resources.require("reciprocalspaceship")[0].version
|
|
4
12
|
|
|
5
|
-
version = pkg_resources.require("reciprocalspaceship")[0].version
|
|
6
13
|
return version
|
|
7
14
|
|
|
8
15
|
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
Summarize the contents of a CIF file.
|
|
4
|
+
|
|
5
|
+
Examples
|
|
6
|
+
--------
|
|
7
|
+
In order to summarize contents of file.cif::
|
|
8
|
+
|
|
9
|
+
> rs.cifdump file.cif
|
|
10
|
+
|
|
11
|
+
If you would like to interactively inspect file.cif in an IPython
|
|
12
|
+
shell, use the "--embed" argument::
|
|
13
|
+
|
|
14
|
+
> rs.cifdump file.cif --embed
|
|
15
|
+
|
|
16
|
+
If multiple CIF files are listed, they will be summarized sequentially,
|
|
17
|
+
and can be accessed in an IPython shell as a dictionary called `cifs`::
|
|
18
|
+
|
|
19
|
+
> rs.cifdump file1.cif file2.cif file3.cif --embed
|
|
20
|
+
|
|
21
|
+
Usage Details
|
|
22
|
+
-------------
|
|
23
|
+
"""
|
|
24
|
+
import argparse
|
|
25
|
+
|
|
26
|
+
import pandas as pd
|
|
27
|
+
|
|
28
|
+
import reciprocalspaceship as rs
|
|
29
|
+
|
|
30
|
+
# If matplotlib is available, use pylab to setup IPython environment
|
|
31
|
+
try:
|
|
32
|
+
from pylab import *
|
|
33
|
+
except:
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def parse_arguments():
|
|
38
|
+
"""Parse commandline arguments"""
|
|
39
|
+
|
|
40
|
+
parser = argparse.ArgumentParser(
|
|
41
|
+
formatter_class=argparse.RawTextHelpFormatter, description=__doc__
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# Required arguments
|
|
45
|
+
parser.add_argument("cif", nargs="+", help="CIF file(s) to summarize")
|
|
46
|
+
|
|
47
|
+
# Optional arguments
|
|
48
|
+
parser.add_argument(
|
|
49
|
+
"--embed",
|
|
50
|
+
action="store_true",
|
|
51
|
+
help=(
|
|
52
|
+
"CIF file(s) will be summarized, and an IPython " "shell will be started"
|
|
53
|
+
),
|
|
54
|
+
)
|
|
55
|
+
parser.add_argument(
|
|
56
|
+
"-p",
|
|
57
|
+
"--precision",
|
|
58
|
+
type=int,
|
|
59
|
+
default=3,
|
|
60
|
+
help="Number of significant digits to output for floats",
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
return parser
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def summarize(cif, precision):
|
|
67
|
+
"""Summarize contents of CIF file"""
|
|
68
|
+
with pd.option_context("display.precision", precision):
|
|
69
|
+
print(f"Spacegroup: {cif.spacegroup.short_name()}")
|
|
70
|
+
print(f"Extended Hermann-Mauguin name: {cif.spacegroup.xhm()}")
|
|
71
|
+
print(
|
|
72
|
+
(
|
|
73
|
+
f"Unit cell dimensions: {cif.cell.a:.3f} {cif.cell.b:.3f} {cif.cell.c:.3f} "
|
|
74
|
+
f"{cif.cell.alpha:.3f} {cif.cell.beta:.3f} {cif.cell.gamma:.3f}"
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
print(f"\ncif.head():\n\n{cif.head()}")
|
|
78
|
+
print(f"\ncif.describe():\n\n{cif.describe()}")
|
|
79
|
+
print(f"\ncif.dtypes:\n\n{cif.dtypes}")
|
|
80
|
+
return
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def main():
|
|
84
|
+
# Parse commandline arguments
|
|
85
|
+
parser = parse_arguments()
|
|
86
|
+
args = parser.parse_args()
|
|
87
|
+
|
|
88
|
+
if len(args.cif) == 1:
|
|
89
|
+
cif = rs.read_cif(args.cif[0])
|
|
90
|
+
summarize(cif, args.precision)
|
|
91
|
+
else:
|
|
92
|
+
cifs = dict(zip(args.cif, map(rs.read_cif, args.cif)))
|
|
93
|
+
for key, value in cifs.items():
|
|
94
|
+
print(f"CIF file: {key}\n")
|
|
95
|
+
summarize(value, args.precision)
|
|
96
|
+
print(f"{'-'*50}")
|
|
97
|
+
|
|
98
|
+
# Begin IPython shell
|
|
99
|
+
if args.embed:
|
|
100
|
+
from IPython import embed
|
|
101
|
+
|
|
102
|
+
bold = "\033[1m"
|
|
103
|
+
end = "\033[0m"
|
|
104
|
+
if "cifs" in locals():
|
|
105
|
+
header = f"rs.DataSets stored in {bold}cifs{end} dictionary"
|
|
106
|
+
else:
|
|
107
|
+
header = f"rs.DataSet stored as {bold}cif{end}"
|
|
108
|
+
print()
|
|
109
|
+
embed(colors="neutral", header=header)
|
|
110
|
+
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
if __name__ == "__main__":
|
|
115
|
+
parser = main()
|
{reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/commandline/mtzdump.py
RENAMED
|
@@ -74,9 +74,13 @@ def summarize(mtz, precision):
|
|
|
74
74
|
f"{mtz.cell.alpha:.3f} {mtz.cell.beta:.3f} {mtz.cell.gamma:.3f}"
|
|
75
75
|
)
|
|
76
76
|
)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
if mtz.cell is not None:
|
|
78
|
+
dHKL = mtz.compute_dHKL().dHKL
|
|
79
|
+
print(f"Resolution range: {dHKL.max():.3f} - {dHKL.min():.3f} Å")
|
|
80
|
+
with pd.option_context("display.max_rows", None):
|
|
81
|
+
print(f"\nmtz.head():\n\n{mtz.head()}")
|
|
82
|
+
print(f"\nmtz.describe().T:\n\n{mtz.describe().T}")
|
|
83
|
+
print(f"\nmtz.dtypes:\n\n{mtz.dtypes}")
|
|
80
84
|
return
|
|
81
85
|
|
|
82
86
|
|
|
@@ -43,6 +43,23 @@ class DataSet(pd.DataFrame):
|
|
|
43
43
|
and attributes, please see the `Pandas.DataFrame documentation`_.
|
|
44
44
|
|
|
45
45
|
.. _Pandas.DataFrame documentation: https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html
|
|
46
|
+
|
|
47
|
+
Attributes
|
|
48
|
+
----------
|
|
49
|
+
acentrics : rs.DataSet
|
|
50
|
+
Access only the acentric reflections in this dataset
|
|
51
|
+
cell : gemmi.UnitCell
|
|
52
|
+
The unit cell
|
|
53
|
+
centrics : rs.DataSet
|
|
54
|
+
Access only the centric reflections in this dataset
|
|
55
|
+
hkls : ndarray, shape=(n_reflections, 3)
|
|
56
|
+
Miller indices in DataSet.
|
|
57
|
+
merged : bool
|
|
58
|
+
Whether this is a merged dataset or unmerged
|
|
59
|
+
spacegroup : gemmi.SpaceGroup
|
|
60
|
+
The space group
|
|
61
|
+
reindexing_ops : list
|
|
62
|
+
Possible reindexing ops consistent with the cell and spacegroup
|
|
46
63
|
"""
|
|
47
64
|
|
|
48
65
|
_metadata = ["_spacegroup", "_cell", "_index_dtypes", "_merged"]
|
|
@@ -131,6 +148,38 @@ class DataSet(pd.DataFrame):
|
|
|
131
148
|
def merged(self, val):
|
|
132
149
|
self._merged = val
|
|
133
150
|
|
|
151
|
+
@property
|
|
152
|
+
@range_indexed
|
|
153
|
+
def hkls(self):
|
|
154
|
+
"""Miller indices"""
|
|
155
|
+
hkl = self[["H", "K", "L"]].to_numpy(dtype=np.int32)
|
|
156
|
+
return hkl
|
|
157
|
+
|
|
158
|
+
def get_hkls(self):
|
|
159
|
+
"""Get the Miller indices of the dataset."""
|
|
160
|
+
return self.hkls
|
|
161
|
+
|
|
162
|
+
@hkls.setter
|
|
163
|
+
@range_indexed
|
|
164
|
+
def hkls(self, hkls):
|
|
165
|
+
if isinstance(hkls, DataSet):
|
|
166
|
+
"""Convert to numpy if hkls is a dataset"""
|
|
167
|
+
hkls = hkls.hkls
|
|
168
|
+
if isinstance(hkls, np.ndarray):
|
|
169
|
+
h, k, l = hkls[..., 0], hkls[..., 1], hkls[..., 2]
|
|
170
|
+
else:
|
|
171
|
+
"""Try coercing to numpy"""
|
|
172
|
+
try:
|
|
173
|
+
hkls = np.array(hkls)
|
|
174
|
+
h, k, l = hkls[..., 0], hkls[..., 1], hkls[..., 2]
|
|
175
|
+
except:
|
|
176
|
+
raise ValueError(
|
|
177
|
+
"Unable to convert hkls to a suitable type. Please ensure hkls is a numpy array or rs.DataSet"
|
|
178
|
+
)
|
|
179
|
+
self["H"] = DataSeries(h, index=self.index, dtype="H")
|
|
180
|
+
self["K"] = DataSeries(k, index=self.index, dtype="H")
|
|
181
|
+
self["L"] = DataSeries(l, index=self.index, dtype="H")
|
|
182
|
+
|
|
134
183
|
@property
|
|
135
184
|
def centrics(self):
|
|
136
185
|
"""Access centric reflections in DataSet"""
|
|
@@ -258,7 +307,14 @@ class DataSet(pd.DataFrame):
|
|
|
258
307
|
)
|
|
259
308
|
|
|
260
309
|
def reset_index(
|
|
261
|
-
self,
|
|
310
|
+
self,
|
|
311
|
+
level=None,
|
|
312
|
+
drop=False,
|
|
313
|
+
inplace=False,
|
|
314
|
+
col_level=0,
|
|
315
|
+
col_fill="",
|
|
316
|
+
allow_duplicates=lib.no_default,
|
|
317
|
+
names=None,
|
|
262
318
|
):
|
|
263
319
|
"""
|
|
264
320
|
Reset the index or a specific level of a MultiIndex.
|
|
@@ -281,6 +337,12 @@ class DataSet(pd.DataFrame):
|
|
|
281
337
|
col_fill : object
|
|
282
338
|
If the columns have multiple levels, determines how the other
|
|
283
339
|
levels are named. If None then the index name is repeated.
|
|
340
|
+
allow_duplicates : bool
|
|
341
|
+
Allow duplicate column labels to be created.
|
|
342
|
+
names : int, str, tuple, list
|
|
343
|
+
Using the given string, rename the DataSet column which contains the
|
|
344
|
+
index data. If the DataSet has a MultiIndex, this has to be a list or
|
|
345
|
+
tuple with length equal to the number of levels.
|
|
284
346
|
|
|
285
347
|
Returns
|
|
286
348
|
-------
|
|
@@ -317,6 +379,8 @@ class DataSet(pd.DataFrame):
|
|
|
317
379
|
inplace=inplace,
|
|
318
380
|
col_level=col_level,
|
|
319
381
|
col_fill=col_fill,
|
|
382
|
+
allow_duplicates=allow_duplicates,
|
|
383
|
+
names=names,
|
|
320
384
|
)
|
|
321
385
|
_handle_cached_dtypes(self, columns, drop)
|
|
322
386
|
return
|
|
@@ -327,6 +391,8 @@ class DataSet(pd.DataFrame):
|
|
|
327
391
|
inplace=inplace,
|
|
328
392
|
col_level=col_level,
|
|
329
393
|
col_fill=col_fill,
|
|
394
|
+
allow_duplicates=allow_duplicates,
|
|
395
|
+
names=names,
|
|
330
396
|
)
|
|
331
397
|
dataset._index_dtypes = dataset._index_dtypes.copy()
|
|
332
398
|
dataset = _handle_cached_dtypes(dataset, columns, drop)
|
|
@@ -406,6 +472,7 @@ class DataSet(pd.DataFrame):
|
|
|
406
472
|
"""
|
|
407
473
|
return cls(gemmiMtz)
|
|
408
474
|
|
|
475
|
+
@range_indexed
|
|
409
476
|
def to_gemmi(
|
|
410
477
|
self,
|
|
411
478
|
skip_problem_mtztypes=False,
|
|
@@ -575,6 +642,7 @@ class DataSet(pd.DataFrame):
|
|
|
575
642
|
result = super().join(*args, **kwargs)
|
|
576
643
|
return result.__finalize__(self)
|
|
577
644
|
|
|
645
|
+
@range_indexed
|
|
578
646
|
def write_mtz(
|
|
579
647
|
self,
|
|
580
648
|
mtzfile,
|
|
@@ -1158,7 +1226,7 @@ class DataSet(pd.DataFrame):
|
|
|
1158
1226
|
|
|
1159
1227
|
return result
|
|
1160
1228
|
|
|
1161
|
-
def is_isomorphous(self, other, cell_threshold=0.
|
|
1229
|
+
def is_isomorphous(self, other, cell_threshold=0.5):
|
|
1162
1230
|
"""
|
|
1163
1231
|
Determine whether DataSet is isomorphous to another DataSet. This
|
|
1164
1232
|
method confirms isomorphism by ensuring the spacegroups are equivalent,
|
|
@@ -1195,7 +1263,8 @@ class DataSet(pd.DataFrame):
|
|
|
1195
1263
|
for param in params:
|
|
1196
1264
|
param1 = self.cell.__getattribute__(param)
|
|
1197
1265
|
param2 = other.cell.__getattribute__(param)
|
|
1198
|
-
|
|
1266
|
+
diff = 200.0 * np.abs(param1 - param2) / (param1 + param2)
|
|
1267
|
+
if diff > cell_threshold:
|
|
1199
1268
|
return False
|
|
1200
1269
|
|
|
1201
1270
|
return True
|
|
@@ -1565,24 +1634,6 @@ class DataSet(pd.DataFrame):
|
|
|
1565
1634
|
warnings.simplefilter("always")
|
|
1566
1635
|
warnings.warn(message, DeprecationWarning)
|
|
1567
1636
|
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
ds = self.loc[:, [key]]
|
|
1572
|
-
|
|
1573
|
-
if gridsize is None:
|
|
1574
|
-
gridsize = self.get_reciprocal_grid_size(dmin=dmin, sample_rate=sample_rate)
|
|
1575
|
-
|
|
1576
|
-
# Set up P1 unit cell
|
|
1577
|
-
p1 = ds.expand_to_p1()
|
|
1578
|
-
p1 = p1.expand_anomalous()
|
|
1579
|
-
|
|
1580
|
-
# Get data and indices
|
|
1581
|
-
data = p1[key].to_numpy()
|
|
1582
|
-
H = p1.get_hkls()
|
|
1583
|
-
|
|
1584
|
-
# Populate grid
|
|
1585
|
-
grid = np.zeros(gridsize, dtype=data.dtype)
|
|
1586
|
-
grid[H[:, 0], H[:, 1], H[:, 2]] = data
|
|
1587
|
-
|
|
1588
|
-
return grid
|
|
1637
|
+
return self.to_reciprocal_grid(
|
|
1638
|
+
key, sample_rate=sample_rate, dmin=dmin, grid_size=gridsize
|
|
1639
|
+
)
|
|
@@ -4,6 +4,8 @@ from inspect import signature
|
|
|
4
4
|
import gemmi
|
|
5
5
|
import numpy as np
|
|
6
6
|
|
|
7
|
+
import reciprocalspaceship as rs
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
def inplace(f):
|
|
9
11
|
"""
|
|
@@ -46,9 +48,11 @@ def range_indexed(f):
|
|
|
46
48
|
names = ds.index.names
|
|
47
49
|
ds = ds._index_from_names([None], inplace=True)
|
|
48
50
|
result = f(ds, *args, **kwargs)
|
|
49
|
-
result = result._index_from_names(names, inplace=True)
|
|
50
51
|
ds = ds._index_from_names(names, inplace=True)
|
|
51
|
-
|
|
52
|
+
if isinstance(result, rs.DataSet):
|
|
53
|
+
result = result._index_from_names(names, inplace=True)
|
|
54
|
+
result = result.__finalize__(ds)
|
|
55
|
+
return result
|
|
52
56
|
|
|
53
57
|
return wrapped
|
|
54
58
|
|
{reciprocalspaceship-1.0.2 → reciprocalspaceship-1.0.4}/reciprocalspaceship/dtypes/internals.py
RENAMED
|
@@ -1359,7 +1359,7 @@ class NumericArray(BaseMaskedArray):
|
|
|
1359
1359
|
|
|
1360
1360
|
@wraps(libmissing.is_numeric_na)
|
|
1361
1361
|
def is_numeric_na(values):
|
|
1362
|
-
allowed_dtypes = ("float32", "int32")
|
|
1362
|
+
allowed_dtypes = ("float64", "float32", "int32")
|
|
1363
1363
|
if isinstance(values, np.ndarray) and values.dtype in allowed_dtypes:
|
|
1364
1364
|
return np.isnan(values)
|
|
1365
1365
|
return libmissing.is_numeric_na(values)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from reciprocalspaceship.io.ccp4map import write_ccp4_map
|
|
2
2
|
from reciprocalspaceship.io.crystfel import read_crystfel
|
|
3
3
|
from reciprocalspaceship.io.csv import read_csv
|
|
4
|
+
from reciprocalspaceship.io.dials import print_refl_info, read_dials_stills
|
|
4
5
|
from reciprocalspaceship.io.mtz import (
|
|
5
6
|
from_gemmi,
|
|
6
7
|
read_cif,
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import warnings
|
|
3
|
+
from contextlib import contextmanager
|
|
4
|
+
from importlib.util import find_spec
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def set_ray_loglevel(level):
|
|
8
|
+
logger = logging.getLogger("ray")
|
|
9
|
+
logger.setLevel(level)
|
|
10
|
+
for handler in logger.handlers:
|
|
11
|
+
handler.setLevel(level)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def check_for_ray():
|
|
15
|
+
has_ray = True
|
|
16
|
+
if find_spec("ray") is None:
|
|
17
|
+
has_ray = False
|
|
18
|
+
|
|
19
|
+
message = (
|
|
20
|
+
"ray (https://www.ray.io/) is not available..." "Falling back to serial."
|
|
21
|
+
)
|
|
22
|
+
warnings.warn(message, ImportWarning)
|
|
23
|
+
return has_ray
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def check_for_mpi():
|
|
27
|
+
try:
|
|
28
|
+
from mpi4py import MPI
|
|
29
|
+
|
|
30
|
+
return True
|
|
31
|
+
except Exception as err:
|
|
32
|
+
message = (
|
|
33
|
+
f"Failed `from mpi4py import MPI` with {err}. Falling back to serial mode."
|
|
34
|
+
)
|
|
35
|
+
warnings.warn(message, ImportWarning)
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@contextmanager
|
|
40
|
+
def ray_context(log_level="DEBUG", **ray_kwargs):
|
|
41
|
+
import ray
|
|
42
|
+
|
|
43
|
+
set_ray_loglevel(log_level)
|
|
44
|
+
ray.init(**ray_kwargs)
|
|
45
|
+
try:
|
|
46
|
+
yield ray
|
|
47
|
+
finally:
|
|
48
|
+
ray.shutdown()
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import mmap
|
|
2
2
|
import re
|
|
3
|
-
from contextlib import contextmanager
|
|
4
|
-
from importlib.util import find_spec
|
|
5
3
|
from typing import Union
|
|
6
4
|
|
|
7
5
|
import gemmi
|
|
8
6
|
import numpy as np
|
|
9
7
|
|
|
10
8
|
from reciprocalspaceship import DataSet, concat
|
|
9
|
+
from reciprocalspaceship.io.common import check_for_ray, ray_context
|
|
11
10
|
from reciprocalspaceship.utils import angle_between, eV2Angstroms
|
|
12
11
|
|
|
13
12
|
# See Rupp Table 5-2
|
|
@@ -60,17 +59,6 @@ _block_markers = {
|
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
|
|
63
|
-
@contextmanager
|
|
64
|
-
def ray_context(**ray_kwargs):
|
|
65
|
-
import ray
|
|
66
|
-
|
|
67
|
-
ray.init(**ray_kwargs)
|
|
68
|
-
try:
|
|
69
|
-
yield ray
|
|
70
|
-
finally:
|
|
71
|
-
ray.shutdown()
|
|
72
|
-
|
|
73
|
-
|
|
74
62
|
class StreamLoader(object):
|
|
75
63
|
"""
|
|
76
64
|
An object that loads stream files into rs.DataSet objects in parallel.
|
|
@@ -304,15 +292,7 @@ class StreamLoader(object):
|
|
|
304
292
|
|
|
305
293
|
# Check whether ray is available
|
|
306
294
|
if use_ray:
|
|
307
|
-
|
|
308
|
-
use_ray = False
|
|
309
|
-
import warnings
|
|
310
|
-
|
|
311
|
-
message = (
|
|
312
|
-
"ray (https://www.ray.io/) is not available..."
|
|
313
|
-
"Falling back to serial stream file parser."
|
|
314
|
-
)
|
|
315
|
-
warnings.warn(message, ImportWarning)
|
|
295
|
+
use_ray = check_for_ray()
|
|
316
296
|
|
|
317
297
|
with open(self.filename, "r") as f:
|
|
318
298
|
memfile = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
|
|
@@ -507,10 +487,9 @@ def read_crystfel(
|
|
|
507
487
|
The type of byte-encoding (optional, 'utf-8').
|
|
508
488
|
columns : list (optional)
|
|
509
489
|
Optionally specify the columns of the output by a list of strings.
|
|
510
|
-
The default list is:
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
See `rs.io.crystfel.StreamLoader().available_column_names` for a list of available column names.
|
|
490
|
+
The default list is: [ "H", "K", "L", "I", "SigI", "BATCH", "s1x", "s1y", "s1z", "ewald_offset", "angular_ewald_offset", "XDET", "YDET" ]
|
|
491
|
+
See `rs.io.crystfel.StreamLoader().available_column_names` for a list of available
|
|
492
|
+
column names and *Notes* for a description of the returned columns
|
|
514
493
|
parallel : bool (optional)
|
|
515
494
|
Read the stream file in parallel using [ray.io](https://docs.ray.io) if it is available.
|
|
516
495
|
num_cpus : int (optional)
|
|
@@ -524,6 +503,18 @@ def read_crystfel(
|
|
|
524
503
|
Returns
|
|
525
504
|
--------
|
|
526
505
|
rs.DataSet
|
|
506
|
+
|
|
507
|
+
Notes
|
|
508
|
+
-----
|
|
509
|
+
The following columns are included in the returned DataSet object:
|
|
510
|
+
|
|
511
|
+
- H, K, L: Miller indices of each reflection
|
|
512
|
+
- I, SigI: Intensity and associated uncertainty
|
|
513
|
+
- BATCH: Image number
|
|
514
|
+
- s1x, s1y, s1z: scattered beam wavevector which points from the sample to the bragg peak
|
|
515
|
+
- ewald_offset: the distance in cartesian space (1/angstroms) between the observed reflection and the ewald sphere
|
|
516
|
+
- angular_ewald_offset: the distance in polar coordinates (degrees) between the observed reflection and the ewald sphere
|
|
517
|
+
- XDET, YDET: Internal detector panel coordinates
|
|
527
518
|
"""
|
|
528
519
|
if not streamfile.endswith(".stream"):
|
|
529
520
|
raise ValueError("Stream file should end with .stream")
|