reciprocalspaceship 1.0.1__tar.gz → 1.0.2__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.

Files changed (67) hide show
  1. {reciprocalspaceship-1.0.1/reciprocalspaceship.egg-info → reciprocalspaceship-1.0.2}/PKG-INFO +2 -5
  2. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/README.md +1 -1
  3. reciprocalspaceship-1.0.2/reciprocalspaceship/VERSION +1 -0
  4. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/algorithms/scale_merged_intensities.py +8 -7
  5. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/dataset.py +5 -0
  6. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/decorators.py +2 -2
  7. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/dtypes/floating.py +24 -28
  8. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/dtypes/integer.py +38 -37
  9. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/dtypes/internals.py +243 -49
  10. reciprocalspaceship-1.0.2/reciprocalspaceship/io/crystfel.py +604 -0
  11. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/utils/__init__.py +6 -1
  12. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/utils/cell.py +5 -0
  13. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/utils/stats.py +5 -7
  14. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/utils/structurefactors.py +5 -0
  15. reciprocalspaceship-1.0.2/reciprocalspaceship/utils/units.py +19 -0
  16. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2/reciprocalspaceship.egg-info}/PKG-INFO +2 -5
  17. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship.egg-info/entry_points.txt +0 -1
  18. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship.egg-info/requires.txt +3 -2
  19. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/setup.py +4 -4
  20. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/tests/test_dataseries.py +1 -1
  21. reciprocalspaceship-1.0.1/reciprocalspaceship/VERSION +0 -1
  22. reciprocalspaceship-1.0.1/reciprocalspaceship/io/crystfel.py +0 -270
  23. reciprocalspaceship-1.0.1/reciprocalspaceship/utils/units.py +0 -9
  24. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/LICENSE +0 -0
  25. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/MANIFEST.in +0 -0
  26. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/__init__.py +0 -0
  27. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/algorithms/__init__.py +0 -0
  28. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/algorithms/intensity.py +0 -0
  29. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/algorithms/merge.py +0 -0
  30. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/commandline/__init__.py +0 -0
  31. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/commandline/mtzdump.py +0 -0
  32. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/concat.py +0 -0
  33. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/dataseries.py +0 -0
  34. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/dtypes/__init__.py +0 -0
  35. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/dtypes/base.py +0 -0
  36. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/dtypes/inference.py +0 -0
  37. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/dtypes/summarize.py +0 -0
  38. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/io/__init__.py +0 -0
  39. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/io/ccp4map.py +0 -0
  40. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/io/csv.py +0 -0
  41. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/io/mtz.py +0 -0
  42. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/io/pickle.py +0 -0
  43. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/io/precognition.py +0 -0
  44. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/stats/__init__.py +0 -0
  45. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/stats/completeness.py +0 -0
  46. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/utils/asu.py +0 -0
  47. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/utils/binning.py +0 -0
  48. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/utils/grid.py +0 -0
  49. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/utils/math.py +0 -0
  50. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/utils/phases.py +0 -0
  51. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/utils/rfree.py +0 -0
  52. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship/utils/symmetry.py +0 -0
  53. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship.egg-info/SOURCES.txt +0 -0
  54. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship.egg-info/dependency_links.txt +0 -0
  55. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/reciprocalspaceship.egg-info/top_level.txt +0 -0
  56. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/setup.cfg +0 -0
  57. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/tests/__init__.py +0 -0
  58. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/tests/conftest.py +0 -0
  59. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/tests/test_dataset.py +0 -0
  60. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/tests/test_dataset_anomalous.py +0 -0
  61. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/tests/test_dataset_binning.py +0 -0
  62. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/tests/test_dataset_grid.py +0 -0
  63. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/tests/test_dataset_index.py +0 -0
  64. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/tests/test_dataset_preserve_attributes.py +0 -0
  65. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/tests/test_dataset_symops.py +0 -0
  66. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/tests/test_decorators.py +0 -0
  67. {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.2}/tests/test_summarize_mtz_dtypes.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: reciprocalspaceship
3
- Version: 1.0.1
3
+ Version: 1.0.2
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
@@ -9,7 +9,6 @@ License: MIT
9
9
  Project-URL: Bug Tracker, https://github.com/rs-station/reciprocalspaceship/issues
10
10
  Project-URL: Documentation, https://rs-station.github.io/reciprocalspaceship/
11
11
  Project-URL: Source Code, https://github.com/rs-station/reciprocalspaceship
12
- Platform: UNKNOWN
13
12
  Classifier: Development Status :: 3 - Alpha
14
13
  Classifier: Intended Audience :: Developers
15
14
  Classifier: Intended Audience :: Science/Research
@@ -18,7 +17,7 @@ Classifier: Topic :: Scientific/Engineering :: Chemistry
18
17
  Classifier: Topic :: Scientific/Engineering :: Physics
19
18
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
19
  Classifier: Programming Language :: Python
21
- Requires-Python: >3.7
20
+ Requires-Python: >=3.9
22
21
  Provides-Extra: dev
23
22
  Provides-Extra: examples
24
23
  License-File: LICENSE
@@ -42,5 +41,3 @@ Features of this library include:
42
41
  use space groups, unit cell parameters, and crystallographic symmetry
43
42
  operations.
44
43
  - Support for reading and writing MTZ reflection files.
45
-
46
-
@@ -1,4 +1,4 @@
1
- # 1 /:rocket: = reciprocalspaceship
1
+ # 1 / 🚀 = reciprocalspaceship
2
2
  ![Build](https://github.com/rs-station/reciprocalspaceship/workflows/Build/badge.svg)
3
3
  [![Documentation](https://github.com/rs-station/reciprocalspaceship/workflows/Documentation/badge.svg)](https://rs-station.github.io/reciprocalspaceship)
4
4
  [![PyPI](https://img.shields.io/pypi/v/reciprocalspaceship?color=blue)](https://pypi.org/project/reciprocalspaceship/)
@@ -185,6 +185,7 @@ def scale_merged_intensities(
185
185
  mean_intensity_method="isotropic",
186
186
  bins=100,
187
187
  bw=2.0,
188
+ minimum_sigma=-np.inf,
188
189
  ):
189
190
  """
190
191
  Scales merged intensities using Bayesian statistics in order to
@@ -240,6 +241,9 @@ def scale_merged_intensities(
240
241
  parameter controls the distance that each reflection impacts in
241
242
  reciprocal space. Only affects output if mean_intensity_method is
242
243
  \"anisotropic\".
244
+ minimum_sigma : float
245
+ Minimum value imposed on Sigma (default: -np.inf, that is: no minimum).
246
+
243
247
 
244
248
  Returns
245
249
  -------
@@ -281,14 +285,11 @@ def scale_merged_intensities(
281
285
  I, Sig = ds[intensity_key].to_numpy(), ds[sigma_key].to_numpy()
282
286
  if mean_intensity_method == "isotropic":
283
287
  dHKL = ds["dHKL"].to_numpy(dtype=np.float64)
284
- Sigma = (
285
- mean_intensity_by_resolution(I / multiplicity, dHKL, bins) * multiplicity
286
- )
288
+ Sigma = mean_intensity_by_resolution(I / multiplicity, dHKL, bins)
287
289
  elif mean_intensity_method == "anisotropic":
288
- Sigma = (
289
- mean_intensity_by_miller_index(I / multiplicity, ds.get_hkls(), bw)
290
- * multiplicity
291
- )
290
+ Sigma = mean_intensity_by_miller_index(I / multiplicity, ds.get_hkls(), bw)
291
+ Sigma = np.clip(Sigma, a_min=minimum_sigma, a_max=np.inf)
292
+ Sigma = Sigma * multiplicity
292
293
 
293
294
  # Initialize outputs
294
295
  ds[outputI] = 0.0
@@ -1234,6 +1234,11 @@ class DataSet(pd.DataFrame):
1234
1234
  # Compute new HKLs and phase shifts
1235
1235
  hkls = dataset.get_hkls()
1236
1236
  compressed_hkls, inverse = np.unique(hkls, axis=0, return_inverse=True)
1237
+
1238
+ # The behavior of np.unique changed with v2.0. This block maintains v1 compatibility
1239
+ if inverse.shape[-1] == 1:
1240
+ inverse = inverse.squeeze(-1)
1241
+
1237
1242
  asu_hkls, isym, phi_coeff, phi_shift = hkl_to_asu(
1238
1243
  compressed_hkls, dataset.spacegroup, return_phase_shifts=True
1239
1244
  )
@@ -100,7 +100,7 @@ def spacegroupify(func=None, *sg_args):
100
100
  for arg in sg_args:
101
101
  if arg in bargs.arguments:
102
102
  bargs.arguments[arg] = _convert_spacegroup(bargs.arguments[arg])
103
- return f(**bargs.arguments)
103
+ return f(*bargs.args, **bargs.kwargs)
104
104
 
105
105
  return wrapped
106
106
 
@@ -155,7 +155,7 @@ def cellify(func=None, *cell_args):
155
155
  for arg in cell_args:
156
156
  if arg in bargs.arguments:
157
157
  bargs.arguments[arg] = _convert_unitcell(bargs.arguments[arg])
158
- return f(**bargs.arguments)
158
+ return f(*bargs.args, **bargs.kwargs)
159
159
 
160
160
  return wrapped
161
161
 
@@ -34,7 +34,6 @@ from __future__ import annotations
34
34
 
35
35
  import numpy as np
36
36
  from pandas._libs import lib
37
- from pandas._libs import missing as libmissing
38
37
  from pandas._typing import ArrayLike, DtypeObj
39
38
  from pandas.util._decorators import cache_readonly
40
39
 
@@ -45,6 +44,7 @@ except:
45
44
 
46
45
  from pandas import Float32Dtype, Float64Dtype
47
46
  from pandas.core.arrays import ExtensionArray
47
+ from pandas.core.dtypes.cast import np_find_common_type
48
48
  from pandas.core.dtypes.common import (
49
49
  is_bool_dtype,
50
50
  is_float,
@@ -58,7 +58,7 @@ from pandas.core.dtypes.dtypes import ExtensionDtype, register_extension_dtype
58
58
  from pandas.core.tools.numeric import to_numeric
59
59
 
60
60
  from reciprocalspaceship.dtypes.base import MTZDtype
61
- from reciprocalspaceship.dtypes.internals import NumericArray
61
+ from reciprocalspaceship.dtypes.internals import NumericArray, is_numeric_na
62
62
 
63
63
 
64
64
  class MTZFloat32Dtype(MTZDtype):
@@ -80,14 +80,14 @@ class MTZFloat32Dtype(MTZDtype):
80
80
  return self
81
81
  if not all(isinstance(t, MTZFloat32Dtype) for t in dtypes):
82
82
  return None
83
- np_dtype = np.find_common_type(
83
+ np_dtype = np_find_common_type(
84
84
  # error: Item "ExtensionDtype" of "Union[Any, ExtensionDtype]" has no
85
85
  # attribute "numpy_dtype"
86
86
  [t.numpy_dtype for t in dtypes], # type: ignore[union-attr]
87
87
  [],
88
88
  )
89
89
  if np.issubdtype(np_dtype, np.floating):
90
- return FLOAT_STR_TO_DTYPE[str(np_dtype)]
90
+ return Float32Dtype()
91
91
  return None
92
92
 
93
93
 
@@ -136,7 +136,11 @@ def coerce_to_array(
136
136
  mask = mask.copy()
137
137
  return values, mask
138
138
 
139
- values = np.array(values, copy=copy)
139
+ if copy:
140
+ values = np.array(values, copy=copy)
141
+ else:
142
+ values = np.asarray(values)
143
+
140
144
  if is_object_dtype(values.dtype):
141
145
  inferred_type = lib.infer_dtype(values, skipna=True)
142
146
  if inferred_type == "empty":
@@ -160,7 +164,7 @@ def coerce_to_array(
160
164
  raise TypeError("values must be a 1D list-like")
161
165
 
162
166
  if mask is None:
163
- mask = libmissing.is_numeric_na(values)
167
+ mask = is_numeric_na(values)
164
168
 
165
169
  else:
166
170
  assert len(mask) == len(values)
@@ -286,6 +290,20 @@ class MTZFloatArray(NumericArray):
286
290
  def _coerce_to_array(self, value) -> tuple[np.ndarray, np.ndarray]:
287
291
  return coerce_to_array(value, dtype=self.dtype)
288
292
 
293
+ def _maybe_mask_result(self, result, mask):
294
+ """
295
+ Parameters
296
+ ----------
297
+ result : array-like
298
+ mask : array-like bool
299
+ """
300
+ # if we have a float operand we are by-definition
301
+ # a float result
302
+ # or our op is a divide
303
+ if result.dtype.kind == "f":
304
+ return type(self)(result, mask, copy=False)
305
+ return super()._maybe_mask_result(result=result, mask=mask)
306
+
289
307
  def astype(self, dtype, copy: bool = True) -> ArrayLike:
290
308
  """
291
309
  Cast to a NumPy array or ExtensionArray with 'dtype'.
@@ -328,28 +346,6 @@ class MTZFloatArray(NumericArray):
328
346
  data = self.to_numpy(dtype=dtype, **kwargs) # type: ignore[arg-type]
329
347
  return astype_nansafe(data, dtype, copy=False)
330
348
 
331
- def _maybe_mask_result(self, result, mask, other, op_name: str):
332
- """
333
- Parameters
334
- ----------
335
- result : array-like
336
- mask : array-like bool
337
- other : scalar or array-like
338
- op_name : str
339
- """
340
- # if we have a float operand we are by-definition
341
- # a float result
342
- # or our op is a divide
343
- if (
344
- (is_float_dtype(other) or is_float(other))
345
- or (op_name in ["rtruediv", "truediv"])
346
- or (is_float_dtype(self.dtype) and is_numeric_dtype(result.dtype))
347
- ):
348
- return type(self)(result, mask, copy=False)
349
- return super()._maybe_mask_result(
350
- result=result, mask=mask, other=other, op_name=op_name
351
- )
352
-
353
349
  def _values_for_argsort(self) -> np.ndarray:
354
350
  return self._data
355
351
 
@@ -33,12 +33,12 @@
33
33
  from __future__ import annotations
34
34
 
35
35
  import numpy as np
36
- from pandas import Int32Dtype, Int64Dtype
36
+ from pandas import Float32Dtype, Int32Dtype, Int64Dtype
37
37
  from pandas._libs import lib
38
- from pandas._libs import missing as libmissing
39
38
  from pandas._typing import ArrayLike, Dtype, DtypeObj
40
39
  from pandas.core.arrays import ExtensionArray
41
40
  from pandas.core.dtypes.base import ExtensionDtype, register_extension_dtype
41
+ from pandas.core.dtypes.cast import np_find_common_type
42
42
  from pandas.core.dtypes.common import (
43
43
  is_bool_dtype,
44
44
  is_float_dtype,
@@ -51,7 +51,11 @@ from pandas.core.tools.numeric import to_numeric
51
51
  from pandas.util._decorators import cache_readonly
52
52
 
53
53
  from reciprocalspaceship.dtypes.base import MTZDtype
54
- from reciprocalspaceship.dtypes.internals import BaseMaskedDtype, NumericArray
54
+ from reciprocalspaceship.dtypes.internals import (
55
+ BaseMaskedDtype,
56
+ NumericArray,
57
+ is_numeric_na,
58
+ )
55
59
 
56
60
 
57
61
  class MTZInt32Dtype(MTZDtype):
@@ -88,25 +92,25 @@ class MTZInt32Dtype(MTZDtype):
88
92
  for t in dtypes
89
93
  ):
90
94
  return None
91
- np_dtype = np.find_common_type(
95
+ np_dtype = np_find_common_type(
92
96
  # error: List comprehension has incompatible type List[Union[Any,
93
97
  # dtype, ExtensionDtype]]; expected List[Union[dtype, None, type,
94
98
  # _SupportsDtype, str, Tuple[Any, Union[int, Sequence[int]]],
95
99
  # List[Any], _DtypeDict, Tuple[Any, Any]]]
96
100
  [
97
- t.numpy_dtype # type: ignore[misc]
98
- if isinstance(t, BaseMaskedDtype)
99
- else t
101
+ (
102
+ t.numpy_dtype # type: ignore[misc]
103
+ if isinstance(t, BaseMaskedDtype)
104
+ else t
105
+ )
100
106
  for t in dtypes
101
107
  ],
102
108
  [],
103
109
  )
104
110
  if np.issubdtype(np_dtype, np.integer):
105
- return INT_STR_TO_DTYPE[str(np_dtype)]
111
+ return Int32Dtype()
106
112
  elif np.issubdtype(np_dtype, np.floating):
107
- from pandas.core.arrays.floating import FLOAT_STR_TO_DTYPE
108
-
109
- return FLOAT_STR_TO_DTYPE[str(np_dtype)]
113
+ return Float32Dtype()
110
114
  return None
111
115
 
112
116
 
@@ -175,7 +179,11 @@ def coerce_to_array(
175
179
  mask = mask.copy()
176
180
  return values, mask
177
181
 
178
- values = np.array(values, copy=copy)
182
+ if copy:
183
+ values = np.array(values, copy=copy)
184
+ else:
185
+ values = np.asarray(values)
186
+
179
187
  inferred_type = None
180
188
  if is_object_dtype(values.dtype) or is_string_dtype(values.dtype):
181
189
  inferred_type = lib.infer_dtype(values, skipna=True)
@@ -202,7 +210,7 @@ def coerce_to_array(
202
210
  raise TypeError("values must be a 1D list-like")
203
211
 
204
212
  if mask is None:
205
- mask = libmissing.is_numeric_na(values)
213
+ mask = is_numeric_na(values)
206
214
  else:
207
215
  assert len(mask) == len(values)
208
216
 
@@ -227,7 +235,12 @@ def coerce_to_array(
227
235
  # a ValueError if the str cannot be parsed into an int
228
236
  values = values.astype(dtype, copy=copy)
229
237
  else:
230
- values = safe_cast(values, dtype, copy=False)
238
+ try:
239
+ values = safe_cast(values, dtype, copy=False)
240
+ except:
241
+ # certain outputs cannot be coerced to int32
242
+ dtype = np.dtype("float64")
243
+ values = safe_cast(values, dtype, copy=False)
231
244
 
232
245
  return values, mask
233
246
 
@@ -310,14 +323,6 @@ class MTZIntegerArray(NumericArray):
310
323
  def dtype(self) -> MTZInt32Dtype:
311
324
  return self._dtype
312
325
 
313
- def __init__(self, values: np.ndarray, mask: np.ndarray, copy: bool = False):
314
- if not (isinstance(values, np.ndarray) and values.dtype.kind in ["i", "u"]):
315
- raise TypeError(
316
- "values should be integer numpy array. Use "
317
- "the 'pd.array' function instead"
318
- )
319
- super().__init__(values, mask, copy=copy)
320
-
321
326
  @classmethod
322
327
  def _from_sequence(
323
328
  cls, scalars, *, dtype: Dtype | None = None, copy: bool = False
@@ -335,6 +340,17 @@ class MTZIntegerArray(NumericArray):
335
340
  def _coerce_to_array(self, value) -> tuple[np.ndarray, np.ndarray]:
336
341
  return coerce_to_array(value, dtype=self.dtype)
337
342
 
343
+ def _maybe_mask_result(self, result, mask):
344
+ """
345
+ Parameters
346
+ ----------
347
+ result : array-like
348
+ mask : array-like bool
349
+ """
350
+ if result.dtype.kind in "iu":
351
+ return type(self)(result, mask, copy=False)
352
+ return super()._maybe_mask_result(result=result, mask=mask)
353
+
338
354
  def astype(self, dtype, copy: bool = True) -> ArrayLike:
339
355
  """
340
356
  Cast to a NumPy array or ExtensionArray with 'dtype'.
@@ -375,21 +391,6 @@ class MTZIntegerArray(NumericArray):
375
391
 
376
392
  return self.to_numpy(dtype=dtype, na_value=na_value, copy=False)
377
393
 
378
- def _maybe_mask_result(self, result, mask, other, op_name: str):
379
- """
380
- Parameters
381
- ----------
382
- result : array-like
383
- mask : array-like bool
384
- other : scalar or array-like
385
- op_name : str
386
- """
387
- if is_integer_dtype(result):
388
- return type(self)(result, mask, copy=False)
389
- return super()._maybe_mask_result(
390
- result=result, mask=mask, other=other, op_name=op_name
391
- )
392
-
393
394
  def _values_for_argsort(self) -> np.ndarray:
394
395
  """
395
396
  Return values for sorting.