ChessAnalysisPipeline 0.0.5__py3-none-any.whl → 0.0.6__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.

Potentially problematic release.


This version of ChessAnalysisPipeline might be problematic. Click here for more details.

Files changed (41) hide show
  1. CHAP/TaskManager.py +214 -0
  2. CHAP/common/models/integration.py +392 -249
  3. CHAP/common/models/map.py +350 -198
  4. CHAP/common/processor.py +227 -189
  5. CHAP/common/reader.py +52 -39
  6. CHAP/common/utils/fit.py +1197 -991
  7. CHAP/common/utils/general.py +629 -372
  8. CHAP/common/utils/material.py +158 -121
  9. CHAP/common/utils/scanparsers.py +735 -339
  10. CHAP/common/writer.py +31 -25
  11. CHAP/edd/models.py +63 -49
  12. CHAP/edd/processor.py +130 -109
  13. CHAP/edd/reader.py +1 -1
  14. CHAP/edd/writer.py +1 -1
  15. CHAP/inference/processor.py +35 -28
  16. CHAP/inference/reader.py +1 -1
  17. CHAP/inference/writer.py +1 -1
  18. CHAP/pipeline.py +14 -28
  19. CHAP/processor.py +44 -75
  20. CHAP/reader.py +49 -40
  21. CHAP/runner.py +73 -32
  22. CHAP/saxswaxs/processor.py +1 -1
  23. CHAP/saxswaxs/reader.py +1 -1
  24. CHAP/saxswaxs/writer.py +1 -1
  25. CHAP/server.py +130 -0
  26. CHAP/sin2psi/processor.py +1 -1
  27. CHAP/sin2psi/reader.py +1 -1
  28. CHAP/sin2psi/writer.py +1 -1
  29. CHAP/tomo/__init__.py +1 -4
  30. CHAP/tomo/models.py +53 -31
  31. CHAP/tomo/processor.py +1326 -900
  32. CHAP/tomo/reader.py +4 -2
  33. CHAP/tomo/writer.py +4 -2
  34. CHAP/writer.py +47 -41
  35. {ChessAnalysisPipeline-0.0.5.dist-info → ChessAnalysisPipeline-0.0.6.dist-info}/METADATA +1 -1
  36. ChessAnalysisPipeline-0.0.6.dist-info/RECORD +52 -0
  37. ChessAnalysisPipeline-0.0.5.dist-info/RECORD +0 -50
  38. {ChessAnalysisPipeline-0.0.5.dist-info → ChessAnalysisPipeline-0.0.6.dist-info}/LICENSE +0 -0
  39. {ChessAnalysisPipeline-0.0.5.dist-info → ChessAnalysisPipeline-0.0.6.dist-info}/WHEEL +0 -0
  40. {ChessAnalysisPipeline-0.0.5.dist-info → ChessAnalysisPipeline-0.0.6.dist-info}/entry_points.txt +0 -0
  41. {ChessAnalysisPipeline-0.0.5.dist-info → ChessAnalysisPipeline-0.0.6.dist-info}/top_level.txt +0 -0
@@ -1,92 +1,103 @@
1
1
  #!/usr/bin/env python3
2
-
3
2
  # -*- coding: utf-8 -*-
3
+ #pylint: disable=
4
4
  """
5
- Created on Fri May 27 12:21:25 2022
6
-
7
- @author: rv43
5
+ File : general.py
6
+ Author : Rolf Verberg <rolfverberg AT gmail dot com>
7
+ Description: Module defining the Material class
8
8
  """
9
9
 
10
- import logging
10
+ # System modules
11
+ from logging import getLogger
12
+ from os import path
11
13
 
12
- import os
14
+ # Third party modules
13
15
  import numpy as np
14
16
  try:
15
- import xrayutilities as xu
16
- have_xu = True
17
- except:
18
- have_xu = False
19
- pass
17
+ from xrayutilities import materials
18
+ from xrayutilities import simpack
19
+ HAVE_XU = True
20
+ except ImportError:
21
+ HAVE_XU = False
20
22
  try:
21
23
  from hexrd import material
22
- have_hexrd = True
23
- except:
24
- have_hexrd = False
25
- pass
26
- if have_hexrd:
24
+ HAVE_HEXRD = True
25
+ except ImportError:
26
+ HAVE_HEXRD = False
27
+ if HAVE_HEXRD:
27
28
  try:
28
29
  from hexrd.valunits import valWUnit
29
- except:
30
- have_hexrd = False
31
- pass
30
+ except ImportError:
31
+ HAVE_HEXRD = False
32
+
33
+ POEDER_INTENSITY_CUTOFF = 1.e-8
34
+
35
+ logger = getLogger(__name__)
32
36
 
33
- powder_intensity_cutoff = 1.e-8
34
37
 
35
38
  class Material:
36
- """Base class for materials in an sin2psi or EDD analysis.
37
- Right now it assumes a single material
38
- extend its ability to do differently when test data is available
39
39
  """
40
-
41
- def __init__(self, material_name=None, material_file=None, sgnum=None,
42
- lattice_parameters_angstroms=None, atoms=None, pos=None, enrgy=None):
40
+ Base class for materials in an sin2psi or EDD analysis. Right now
41
+ it assumes a single material, extend its ability to do differently
42
+ when test data is available
43
+ """
44
+ def __init__(
45
+ self, material_name=None, material_file=None, sgnum=None,
46
+ lattice_parameters_angstroms=None, atoms=None, pos=None,
47
+ enrgy=None):
48
+ """Initialize Material."""
43
49
  self._enrgy = enrgy
44
50
  self._materials = []
45
51
  self._ds_min = []
46
52
  self._ds_unique = None
47
53
  self._hkls_unique = None
48
54
  if material_name is not None:
49
- self.add_material(material_name, material_file, sgnum, lattice_parameters_angstroms,
50
- atoms, pos)
55
+ self.add_material(
56
+ material_name, material_file, sgnum,
57
+ lattice_parameters_angstroms, atoms, pos)
51
58
 
52
- @property
53
- #FIX passing arguments to a property isn't correct?
54
59
  def lattice_parameters(self, index=0):
55
- """Convert from internal nm units to angstrom
56
- """
60
+ """Convert from internal nm units to angstrom."""
57
61
  matl = self._materials[index]
58
- if isinstance(matl, xu.materials.material.Crystal):
62
+ if isinstance(matl, materials.material.Crystal):
59
63
  return [matl.a, matl.b, matl.c]
60
- elif isinstance(matl, material.Material):
61
- return [l.getVal("angstrom") for l in self._materials[index].latticeParameters[0:3]]
62
- else:
63
- raise ValueError('Illegal material class type')
64
- return None
64
+ if isinstance(matl, material.Material):
65
+ return [
66
+ lpars.getVal('angstrom')
67
+ for lpars in self._materials[index].latticeParameters[0:3]]
68
+ raise ValueError('Illegal material class type')
65
69
 
66
- @property
67
70
  def ds_unique(self, tth_tol=None, tth_max=None, round_sig=8):
71
+ """Return the unique lattice spacings."""
68
72
  if self._ds_unique is None:
69
- self.get_unique_ds(tth_tol, tth_max, round_sig)
73
+ self.get_ds_unique(tth_tol, tth_max, round_sig)
70
74
  return self._ds_unique
71
75
 
72
- @property
73
76
  def hkls_unique(self, tth_tol=None, tth_max=None, round_sig=8):
77
+ """Return the unique HKLs."""
74
78
  if self._hkls_unique is None:
75
- self.get_unique_ds(tth_tol, tth_max, round_sig)
79
+ self.get_ds_unique(tth_tol, tth_max, round_sig)
76
80
  return self._hkls_unique
77
81
 
78
- def add_material(self, material_name, material_file=None, sgnum=None,
79
- lattice_parameters_angstroms=None, atoms=None, pos=None, dmin_angstroms=0.6):
82
+ def add_material(
83
+ self, material_name, material_file=None, sgnum=None,
84
+ lattice_parameters_angstroms=None, atoms=None, pos=None,
85
+ dmin_angstroms=0.6):
86
+ """Add a material."""
80
87
  # At this point only for a single material
81
- # Unique energies works for more, but fitting with different materials is not implemented
88
+ # Unique energies works for more, but fitting with different
89
+ # materials is not implemented
82
90
  if len(self._materials) == 1:
83
- exit('Multiple materials not implemented yet')
91
+ raise ValueError('Multiple materials not implemented yet')
84
92
  self._ds_min.append(dmin_angstroms)
85
- self._materials.append(Material.make_material(material_name, material_file, sgnum,
93
+ self._materials.append(
94
+ Material.make_material(
95
+ material_name, material_file, sgnum,
86
96
  lattice_parameters_angstroms, atoms, pos, dmin_angstroms))
87
97
 
88
- def get_unique_ds(self, tth_tol=None, tth_max=None, round_sig=8):
89
- """Get the list of unique lattice spacings from material HKLs
98
+ def get_ds_unique(self, tth_tol=None, tth_max=None, round_sig=8):
99
+ """
100
+ Get the list of unique lattice spacings from material HKLs.
90
101
 
91
102
  Parameters
92
103
  ----------
@@ -96,136 +107,162 @@ class Material:
96
107
 
97
108
  Returns
98
109
  -------
99
- hkls : list of hkl's corresponding to the unique lattice spacings
100
- ds : list of the unique lattice spacings
110
+ hkls: list of hkl's corresponding to the unique lattice spacings
111
+ ds: list of the unique lattice spacings
101
112
  """
102
113
  hkls = np.empty((0,3))
103
114
  ds = np.empty((0))
104
- ids = np.empty((0))
105
- for i,m in enumerate(self._materials):
115
+ ds_index = np.empty((0))
116
+ for i, m in enumerate(self._materials):
106
117
  material_class_valid = False
107
- if have_xu:
108
- if isinstance(m, xu.materials.material.Crystal):
109
- powder = xu.simpack.PowderDiffraction(m, en=self._enrgy)
110
- hklsi = [hkl for hkl in powder.data if powder.data[hkl]['active']]
111
- dsi = [m.planeDistance(hkl) for hkl in powder.data if powder.data[hkl]['active']]
112
- mask = [True if d > self._ds_min[i] else False for d in dsi]
118
+ if HAVE_XU:
119
+ if isinstance(m, materials.material.Crystal):
120
+ powder = simpack.PowderDiffraction(m, en=self._enrgy)
121
+ hklsi = [hkl for hkl in powder.data
122
+ if powder.data[hkl]['active']]
123
+ ds_i = [m.planeDistance(hkl) for hkl in powder.data
124
+ if powder.data[hkl]['active']]
125
+ mask = [d > self._ds_min[i] for d in ds_i]
113
126
  hkls = np.vstack((hkls, np.array(hklsi)[mask,:]))
114
- dsi = np.array(dsi)[mask]
127
+ ds_i = np.array(ds_i)[mask]
115
128
  material_class_valid = True
116
- if have_hexrd:
129
+ if HAVE_HEXRD:
117
130
  if isinstance(m, material.Material):
118
- pd = m.planeData
131
+ plane_data = m.planeData
119
132
  if tth_tol is not None:
120
- pd.tThWidth = np.radians(tth_tol)
133
+ plane_data.tThWidth = np.radians(tth_tol)
121
134
  if tth_max is not None:
122
- pd.exclusions = None
123
- pd.tThMax = np.radians(tth_max)
124
- hkls = np.vstack((hkls, pd.hkls.T))
125
- dsi = pd.getPlaneSpacings()
135
+ plane_data.exclusions = None
136
+ plane_data.tThMax = np.radians(tth_max)
137
+ hkls = np.vstack((hkls, plane_data.hkls.T))
138
+ ds_i = plane_data.getPlaneSpacings()
126
139
  material_class_valid = True
127
140
  if not material_class_valid:
128
141
  raise ValueError('Illegal material class type')
129
- ds = np.hstack((ds, dsi))
130
- ids = np.hstack((ids, i*np.ones(len(dsi))))
142
+ ds = np.hstack((ds, ds_i))
143
+ ds_index = np.hstack((ds_index, i*np.ones(len(ds_i))))
131
144
 
132
145
  # Sort lattice spacings in reverse order (use -)
133
- ds_unique, ids_unique, _ = np.unique(-ds.round(round_sig), return_index=True,
134
- return_counts=True)
146
+ ds_unique, ds_index_unique, _ = np.unique(
147
+ -ds.round(round_sig), return_index=True, return_counts=True)
135
148
  ds_unique = np.abs(ds_unique)
136
149
 
137
150
  # Limit the list to unique lattice spacings
138
- self._hkls_unique = hkls[ids_unique,:].astype(int)
139
- self._ds_unique = ds[ids_unique]
140
- hkl_list = np.vstack((np.arange(self._ds_unique.shape[0]), ids[ids_unique],
141
- self._hkls_unique.T, self._ds_unique)).T
142
- logging.info("Unique d's:")
151
+ self._hkls_unique = hkls[ds_index_unique,:].astype(int)
152
+ self._ds_unique = ds[ds_index_unique]
153
+ hkl_list = np.vstack(
154
+ (np.arange(self._ds_unique.shape[0]), ds_index[ds_index_unique],
155
+ self._hkls_unique.T, self._ds_unique)).T
156
+ logger.info("Unique d's:")
143
157
  for hkl in hkl_list:
144
- logging.info(f'{hkl[0]:4.0f} {hkl[1]:.0f} {hkl[2]:.0f} {hkl[3]:.0f} {hkl[4]:.0f} '+
145
- f'{hkl[5]:.6f}')
158
+ logger.info(
159
+ f'{hkl[0]:4.0f} {hkl[1]:.0f} {hkl[2]:.0f} {hkl[3]:.0f} '
160
+ f'{hkl[4]:.0f} {hkl[5]:.6f}')
146
161
 
147
162
  return self._hkls_unique, self._ds_unique
148
163
 
149
164
  @staticmethod
150
- def make_material(material_name, material_file=None, sgnum=None,
151
- lattice_parameters_angstroms=None, atoms=None, pos=None, dmin_angstroms=0.6):
152
- """ Use HeXRD to get material properties when a materials file is provided
153
- Use xrayutilities otherwise
165
+ def make_material(
166
+ material_name, material_file=None, sgnum=None,
167
+ lattice_parameters_angstroms=None, atoms=None, pos=None,
168
+ dmin_angstroms=0.6):
169
+ """
170
+ Use HeXRD to get material properties when a materials file is
171
+ provided. Use xrayutilities otherwise.
154
172
  """
155
173
  if not isinstance(material_name, str):
156
- raise ValueError(f'Illegal material_name: {material_name} {type(material_name)}')
174
+ raise ValueError(
175
+ f'Illegal material_name: {material_name} '
176
+ f'{type(material_name)}')
157
177
  if lattice_parameters_angstroms is not None:
158
178
  if material_file is not None:
159
- logging.warning('Overwrite lattice_parameters of material_file with input values '+
160
- f'({lattice_parameters_angstroms})')
179
+ logger.warning(
180
+ 'Overwrite lattice_parameters of material_file with input '
181
+ f'values ({lattice_parameters_angstroms})')
161
182
  if isinstance(lattice_parameters_angstroms, (int, float)):
162
183
  lattice_parameters = [lattice_parameters_angstroms]
163
- elif isinstance(lattice_parameters_angstroms, (tuple, list, np.ndarray)):
184
+ elif isinstance(
185
+ lattice_parameters_angstroms, (tuple, list, np.ndarray)):
164
186
  lattice_parameters = list(lattice_parameters_angstroms)
165
187
  else:
166
- raise ValueError(f'Illegal lattice_parameters_angstroms: '+
167
- f'{lattice_parameters_angstroms} {type(lattice_parameters_angstroms)}')
188
+ raise ValueError(
189
+ 'Illegal lattice_parameters_angstroms: '
190
+ f'{lattice_parameters_angstroms} '
191
+ f'{type(lattice_parameters_angstroms)}')
168
192
  if material_file is None:
169
193
  if not isinstance(sgnum, int):
170
194
  raise ValueError(f'Illegal sgnum: {sgnum} {type(sgnum)}')
171
- if sgnum is None or lattice_parameters_angstroms is None or pos is None:
172
- raise ValueError('Valid inputs for sgnum and lattice_parameters_angstroms and '+
173
- 'pos are required if materials file is not specified')
195
+ if (sgnum is None or lattice_parameters_angstroms is None
196
+ or pos is None):
197
+ raise ValueError(
198
+ 'Valid inputs for sgnum, lattice_parameters_angstroms and '
199
+ 'pos are required if materials file is not specified')
174
200
  if isinstance(pos, str):
175
201
  pos = [pos]
176
202
  use_xu = True
177
- if (np.array(pos).ndim == 1 and isinstance(pos[0], (int, float)) and
178
- np.array(pos).size == 3):
179
- if have_hexrd:
203
+ if (np.array(pos).ndim == 1 and isinstance(pos[0], (int, float))
204
+ and np.array(pos).size == 3):
205
+ if HAVE_HEXRD:
180
206
  pos = np.array([pos])
181
207
  use_xu = False
182
- elif (np.array(pos).ndim == 2 and np.array(pos).shape[0] > 0 and
183
- np.array(pos).shape[1] == 3):
184
- if have_hexrd:
208
+ elif (np.array(pos).ndim == 2 and np.array(pos).shape[0] > 0
209
+ and np.array(pos).shape[1] == 3):
210
+ if HAVE_HEXRD:
185
211
  pos = np.array(pos)
186
212
  use_xu = False
187
- elif not (np.array(pos).ndim == 1 and isinstance(pos[0], str) and
188
- np.array(pos).size > 0 and have_xu):
189
- raise ValueError(f'Illegal pos (have_xu = {have_xu}): {pos} {type(pos)}')
213
+ elif not (np.array(pos).ndim == 1 and isinstance(pos[0], str)
214
+ and np.array(pos).size > 0 and HAVE_XU):
215
+ raise ValueError(
216
+ f'Illegal pos (HAVE_XU = {HAVE_XU}): {pos} {type(pos)}')
190
217
  if use_xu:
191
218
  if atoms is None:
192
219
  atoms = [material_name]
193
- matl = xu.materials.Crystal(material_name, xu.materials.SGLattice(sgnum,
194
- *lattice_parameters, atoms=atoms, pos=[p for p in np.array(pos)]))
220
+ matl = materials.Crystal(
221
+ material_name,
222
+ materials.SGLattice(sgnum, *lattice_parameters,
223
+ atoms=atoms, pos=list(np.array(pos))))
195
224
  else:
196
225
  matl = material.Material(material_name)
197
226
  matl.sgnum = sgnum
198
227
  matl.atominfo = np.vstack((pos.T, np.ones(pos.shape[0]))).T
199
228
  matl.latticeParameters = lattice_parameters
200
- matl.dmin = valWUnit('lp', 'length', dmin_angstroms, 'angstrom')
229
+ matl.dmin = valWUnit(
230
+ 'lp', 'length', dmin_angstroms, 'angstrom')
201
231
  exclusions = matl.planeData.get_exclusions()
202
232
  powder_intensity = matl.planeData.powder_intensity
203
- exclusions = [True if exclusion or i >= len(powder_intensity) or
204
- powder_intensity[i] < powder_intensity_cutoff else False
205
- for i, exclusion in enumerate(exclusions)]
233
+ exclusions = [
234
+ exclusion or i >= len(powder_intensity)
235
+ or powder_intensity[i] < POEDER_INTENSITY_CUTOFF
236
+ for i, exclusion in enumerate(exclusions)]
206
237
  matl.planeData.set_exclusions(exclusions)
207
- logging.debug(f'powder_intensity = {matl.planeData.powder_intensity}')
208
- logging.debug(f'exclusions = {matl.planeData.exclusions}')
238
+ logger.debug(
239
+ f'powder_intensity = {matl.planeData.powder_intensity}')
240
+ logger.debug(f'exclusions = {matl.planeData.exclusions}')
209
241
  else:
210
- if not have_hexrd:
211
- raise ValueError('Illegal inputs: must provide detailed material info when '+
212
- 'hexrd package is unavailable')
242
+ if not HAVE_HEXRD:
243
+ raise ValueError(
244
+ 'Illegal inputs: must provide detailed material info when '
245
+ 'hexrd package is unavailable')
213
246
  if sgnum is not None:
214
- logging.warning('Ignore sgnum input when material_file is specified')
215
- if not (os.path.splitext(material_file)[1] in ('.h5', '.hdf5', '.xtal', '.cif')):
247
+ logger.warning(
248
+ 'Ignore sgnum input when material_file is specified')
249
+ if not (path.splitext(material_file)[1] in
250
+ ('.h5', '.hdf5', '.xtal', '.cif')):
216
251
  raise ValueError(f'Illegal material file {material_file}')
217
- matl = material.Material(material_name, material_file,
218
- dmin=valWUnit('lp', 'length', dmin_angstroms, 'angstrom'))
252
+ matl = material.Material(
253
+ material_name, material_file,
254
+ dmin=valWUnit('lp', 'length', dmin_angstroms, 'angstrom'))
219
255
  if lattice_parameters_angstroms is not None:
220
256
  matl.latticeParameters = lattice_parameters
221
257
  exclusions = matl.planeData.get_exclusions()
222
258
  powder_intensity = matl.planeData.powder_intensity
223
- exclusions = [True if exclusion or i >= len(powder_intensity) or
224
- powder_intensity[i] < powder_intensity_cutoff else False
225
- for i, exclusion in enumerate(exclusions)]
259
+ exclusions = [
260
+ exclusion or i >= len(powder_intensity)
261
+ or powder_intensity[i] < POEDER_INTENSITY_CUTOFF
262
+ for i, exclusion in enumerate(exclusions)]
226
263
  matl.planeData.set_exclusions(exclusions)
227
- logging.debug(f'powder_intensity = {matl.planeData.powder_intensity}')
228
- logging.debug(f'exclusions = {matl.planeData.exclusions}')
264
+ logger.debug(
265
+ f'powder_intensity = {matl.planeData.powder_intensity}')
266
+ logger.debug(f'exclusions = {matl.planeData.exclusions}')
229
267
 
230
268
  return matl
231
-