orto 1.12.0__py3-none-any.whl → 1.13.1__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.
- orto/__version__.py +1 -1
- orto/cli.py +378 -249
- orto/data.py +129 -3
- orto/extractor.py +81 -12
- orto/plotter.py +163 -118
- orto/utils.py +43 -1
- {orto-1.12.0.dist-info → orto-1.13.1.dist-info}/METADATA +3 -3
- orto-1.13.1.dist-info/RECORD +17 -0
- orto-1.12.0.dist-info/RECORD +0 -17
- {orto-1.12.0.dist-info → orto-1.13.1.dist-info}/WHEEL +0 -0
- {orto-1.12.0.dist-info → orto-1.13.1.dist-info}/entry_points.txt +0 -0
- {orto-1.12.0.dist-info → orto-1.13.1.dist-info}/licenses/LICENSE +0 -0
- {orto-1.12.0.dist-info → orto-1.13.1.dist-info}/top_level.txt +0 -0
orto/plotter.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import matplotlib.pyplot as plt
|
|
2
|
-
import matplotlib as mpl
|
|
3
2
|
from matplotlib.ticker import AutoMinorLocator
|
|
4
3
|
import numpy as np
|
|
5
4
|
from numpy.typing import ArrayLike
|
|
@@ -10,11 +9,50 @@ from . import utils as ut
|
|
|
10
9
|
from . import data
|
|
11
10
|
|
|
12
11
|
|
|
12
|
+
def set_axlims(ax: plt.Axes, type: str, limits: list[float | str]) -> None:
|
|
13
|
+
'''
|
|
14
|
+
Sets axis limits of specified axis given a set of limit\n
|
|
15
|
+
values or string 'auto'
|
|
16
|
+
'''
|
|
17
|
+
|
|
18
|
+
if type == 'y':
|
|
19
|
+
gmethod = ax.get_ylim
|
|
20
|
+
smethod = ax.set_ylim
|
|
21
|
+
elif type == 'x':
|
|
22
|
+
gmethod = ax.get_xlim
|
|
23
|
+
smethod = ax.set_xlim
|
|
24
|
+
else:
|
|
25
|
+
raise ValueError(f'Unknown axis type {type}')
|
|
26
|
+
|
|
27
|
+
_limits = limits.copy()
|
|
28
|
+
if _limits[0] != _limits[1]:
|
|
29
|
+
# Lower limit either auto or specified
|
|
30
|
+
if isinstance(_limits[0], str):
|
|
31
|
+
if _limits[0] == 'auto':
|
|
32
|
+
_limits[0] = gmethod()[0]
|
|
33
|
+
elif ut.is_floatable(_limits[0]):
|
|
34
|
+
_limits[0] = float(_limits[0])
|
|
35
|
+
else:
|
|
36
|
+
raise ValueError(f'Invalid {type} limit value: {_limits[0]}')
|
|
37
|
+
# Upper limit either auto or specified
|
|
38
|
+
if isinstance(_limits[1], str):
|
|
39
|
+
if _limits[1] == 'auto':
|
|
40
|
+
_limits[1] = gmethod()[1]
|
|
41
|
+
elif ut.is_floatable(_limits[1]):
|
|
42
|
+
_limits[1] = float(_limits[1])
|
|
43
|
+
else:
|
|
44
|
+
raise ValueError(f'Invalid {type} limit value: {_limits[1]}')
|
|
45
|
+
# Set values
|
|
46
|
+
smethod([_limits[0], _limits[1]])
|
|
47
|
+
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
|
|
13
51
|
def plot_absorption_spectrum(abs_data: data.AbsorptionData,
|
|
14
52
|
linecolor: str = 'black',
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
53
|
+
stickcolor: str = 'black',
|
|
54
|
+
xlim: list[float] = ['auto', 'auto'],
|
|
55
|
+
ylim: list[float] = [0., 'auto'],
|
|
18
56
|
x_shift: float = 0.,
|
|
19
57
|
normalise: bool = False,
|
|
20
58
|
osc_style: str = 'separate',
|
|
@@ -26,7 +64,7 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
|
|
|
26
64
|
window_title: str = 'Absorption Spectrum',
|
|
27
65
|
legend: bool = True) -> tuple[plt.Figure, plt.Axes, plt.Axes | None]: # noqa
|
|
28
66
|
'''
|
|
29
|
-
Plots absorption spectrum from AbsorptionSpectrum object.\n
|
|
67
|
+
Plots an absorption spectrum from AbsorptionSpectrum object.\n
|
|
30
68
|
|
|
31
69
|
Parameters
|
|
32
70
|
----------
|
|
@@ -34,11 +72,11 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
|
|
|
34
72
|
Data object containing absorption data and spectrum
|
|
35
73
|
linecolor: str, default 'black'
|
|
36
74
|
Color of the continuous spectrum line
|
|
37
|
-
|
|
75
|
+
stickcolor: str, default 'black'
|
|
38
76
|
Color of the oscillator strength sticks
|
|
39
|
-
|
|
77
|
+
xlim: list[float], default ['auto', 'auto']
|
|
40
78
|
Minimum and maximum x-values to plot
|
|
41
|
-
|
|
79
|
+
ylim: list[float | str], default [0., 'auto']
|
|
42
80
|
Minimum and maximum y-values to plot
|
|
43
81
|
normalise: bool, default False
|
|
44
82
|
If True, normalise the absorption spectrum to the maximum value.
|
|
@@ -61,7 +99,7 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
|
|
|
61
99
|
If True, plot is shown on screen
|
|
62
100
|
verbose: bool, default True
|
|
63
101
|
If True, plot file location is written to terminal
|
|
64
|
-
window_title: str, default '
|
|
102
|
+
window_title: str, default 'Absorption Spectrum'
|
|
65
103
|
Title of figure window, not of plot
|
|
66
104
|
legend: bool, default True
|
|
67
105
|
If True, a legend is added to the plot
|
|
@@ -95,27 +133,11 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
|
|
|
95
133
|
if oax is None and osc_style == 'separate':
|
|
96
134
|
oax = ax.twinx()
|
|
97
135
|
|
|
98
|
-
if not isinstance(
|
|
99
|
-
raise ValueError('`
|
|
136
|
+
if not isinstance(xlim, list):
|
|
137
|
+
raise ValueError('`xlim` must be a list of values')
|
|
100
138
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if x_lim[0] == 'auto':
|
|
104
|
-
x_lim[0] = ax.get_ylim()[0]
|
|
105
|
-
elif ut.is_floatable(x_lim[0]):
|
|
106
|
-
x_lim[0] = float(x_lim[0])
|
|
107
|
-
else:
|
|
108
|
-
raise ValueError(f'Invalid x_lim[0] value: {x_lim[0]}')
|
|
109
|
-
if isinstance(x_lim[1], str):
|
|
110
|
-
if x_lim[1] == 'auto':
|
|
111
|
-
x_lim[1] = ax.get_ylim()[1]
|
|
112
|
-
elif ut.is_floatable(x_lim[1]):
|
|
113
|
-
x_lim[1] = float(x_lim[1])
|
|
114
|
-
else:
|
|
115
|
-
raise ValueError(f'Invalid x_lim[1] value: {x_lim[1]}')
|
|
116
|
-
|
|
117
|
-
# Set limits and range of continuous variable
|
|
118
|
-
# ax.set_xlim([x_lim[0], x_lim[1]])
|
|
139
|
+
# Set x limits if specified
|
|
140
|
+
set_axlims(ax, 'x', xlim)
|
|
119
141
|
|
|
120
142
|
# Normalisation of spectrum
|
|
121
143
|
if normalise:
|
|
@@ -165,7 +187,7 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
|
|
|
165
187
|
_osc,
|
|
166
188
|
basefmt=' ',
|
|
167
189
|
markerfmt=' ',
|
|
168
|
-
linefmt=
|
|
190
|
+
linefmt=stickcolor
|
|
169
191
|
)
|
|
170
192
|
plt.setp(stemlines, 'linewidth', 1.1)
|
|
171
193
|
oax.yaxis.set_minor_locator(AutoMinorLocator())
|
|
@@ -180,7 +202,7 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
|
|
|
180
202
|
abs_data.osc_strengths/np.max(abs_data.osc_strengths) * np.max(_y_values), # noqa
|
|
181
203
|
basefmt=' ',
|
|
182
204
|
markerfmt=' ',
|
|
183
|
-
linefmt=
|
|
205
|
+
linefmt=stickcolor
|
|
184
206
|
)
|
|
185
207
|
oax.set_yticks([])
|
|
186
208
|
oax.spines['right'].set_visible(False)
|
|
@@ -197,22 +219,7 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
|
|
|
197
219
|
ax.spines['top'].set_visible(False)
|
|
198
220
|
|
|
199
221
|
# Set y limits if specified
|
|
200
|
-
|
|
201
|
-
if _y_lim[0] != _y_lim[1]:
|
|
202
|
-
# Lower limit either auto or specified
|
|
203
|
-
if isinstance(_y_lim[0], str):
|
|
204
|
-
if _y_lim[0] == 'auto':
|
|
205
|
-
_y_lim[0] = ax.get_ylim()[0]
|
|
206
|
-
else:
|
|
207
|
-
_y_lim[0] = float(_y_lim[0])
|
|
208
|
-
# Upper limit either auto or specified
|
|
209
|
-
if isinstance(_y_lim[1], str):
|
|
210
|
-
if _y_lim[1] == 'auto':
|
|
211
|
-
_y_lim[1] = ax.get_ylim()[1]
|
|
212
|
-
else:
|
|
213
|
-
_y_lim[1] = float(_y_lim[1])
|
|
214
|
-
# Set values
|
|
215
|
-
ax.set_ylim([_y_lim[0], _y_lim[1]])
|
|
222
|
+
set_axlims(ax, 'y', ylim)
|
|
216
223
|
|
|
217
224
|
ax.xaxis.set_minor_locator(AutoMinorLocator())
|
|
218
225
|
ax.yaxis.set_minor_locator(AutoMinorLocator())
|
|
@@ -242,74 +249,106 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
|
|
|
242
249
|
return fig, ax, oax
|
|
243
250
|
|
|
244
251
|
|
|
245
|
-
def
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
252
|
+
def plot_susceptibility(susc_data: data.SuscseptibilityData,
|
|
253
|
+
y_style: str = 'XT',
|
|
254
|
+
label: str = None,
|
|
255
|
+
linecolor: str = 'black',
|
|
256
|
+
xlim: list[float] = ['auto', 'auto'],
|
|
257
|
+
ylim: list[float] = [0., 'auto'],
|
|
258
|
+
fig: plt.Figure = None, ax: plt.Axes = None,
|
|
259
|
+
save: bool = False,
|
|
260
|
+
save_name: str = 'magnetic_susceptibility.png',
|
|
261
|
+
show: bool = False,
|
|
262
|
+
verbose: bool = True,
|
|
263
|
+
window_title: str = 'Magnetic Susceptibility',
|
|
264
|
+
legend: bool = True) -> tuple[plt.Figure, plt.Axes]:
|
|
265
|
+
'''
|
|
266
|
+
Plots magnetic susceptibility data from SusceptibilityData object
|
|
258
267
|
|
|
259
268
|
Parameters
|
|
260
269
|
----------
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
+
susc_data: data.SusceptibilityData
|
|
271
|
+
Data object containing susceptibility data
|
|
272
|
+
y_style: str, default 'XT'
|
|
273
|
+
Quanity to plot on y axis, one of\n
|
|
274
|
+
'XT': chi*T\n
|
|
275
|
+
'X': chi\n
|
|
276
|
+
'1/X': 1/chi
|
|
277
|
+
label: str
|
|
278
|
+
Label for this trace used in legend
|
|
279
|
+
linecolor: str, default 'black'
|
|
280
|
+
Color of the data line
|
|
281
|
+
xlim: list[float], default ['auto', 'auto']
|
|
282
|
+
Minimum and maximum x-values to plot
|
|
283
|
+
ylim: list[float | str], default [0., 'auto']
|
|
284
|
+
Minimum and maximum y-values to plot
|
|
285
|
+
fig: plt.Figure | None, optional
|
|
286
|
+
If provided, uses this Figure object for plotting
|
|
287
|
+
ax: plt.Axes | None, optional
|
|
288
|
+
If provided, plots data to this axis
|
|
270
289
|
save: bool, default False
|
|
271
290
|
If True, plot is saved to save_name
|
|
272
|
-
save_name: str, default '
|
|
291
|
+
save_name: str | pathlib.Path, default 'magnetic_susceptibility.png'
|
|
273
292
|
If save is True, plot is saved to this location/filename
|
|
274
293
|
show: bool, default False
|
|
275
294
|
If True, plot is shown on screen
|
|
276
|
-
|
|
295
|
+
verbose: bool, default True
|
|
296
|
+
If True, plot file location is written to terminal
|
|
297
|
+
window_title: str, default 'Magnetic Susceptibility'
|
|
277
298
|
Title of figure window, not of plot
|
|
299
|
+
legend: bool, default True
|
|
300
|
+
If True, a legend is added to the plot
|
|
301
|
+
|
|
278
302
|
Returns
|
|
279
303
|
-------
|
|
280
304
|
plt.Figure
|
|
281
|
-
Matplotlib Figure
|
|
305
|
+
Matplotlib Figure object
|
|
282
306
|
plt.Axes
|
|
283
|
-
Matplotlib Axis object for plot
|
|
284
|
-
'''
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
fig, ax = plt.subplots(
|
|
288
|
-
1,
|
|
289
|
-
1,
|
|
290
|
-
figsize=(4 * (1 + np.sqrt(5))/2, 4),
|
|
291
|
-
num=window_title
|
|
292
|
-
)
|
|
307
|
+
Matplotlib Axis object for main plot
|
|
308
|
+
'''
|
|
309
|
+
|
|
310
|
+
save_name = pathlib.Path(save_name)
|
|
293
311
|
|
|
294
|
-
if
|
|
295
|
-
|
|
296
|
-
|
|
312
|
+
if fig is None or ax is None:
|
|
313
|
+
width = 4
|
|
314
|
+
width_cm = 10.4
|
|
315
|
+
golden = (1 + np.sqrt(5))/2
|
|
316
|
+
fig, ax = plt.subplots(
|
|
317
|
+
1,
|
|
318
|
+
1,
|
|
319
|
+
num=window_title,
|
|
320
|
+
figsize=(width, width / golden)
|
|
321
|
+
)
|
|
297
322
|
else:
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
323
|
+
width = fig.get_size_inches()[0]
|
|
324
|
+
width_cm = width * 2.54
|
|
325
|
+
|
|
326
|
+
if y_style == 'XT':
|
|
327
|
+
y_data = susc_data.chis * susc_data.temperatures
|
|
328
|
+
elif y_style == 'X':
|
|
329
|
+
y_data = susc_data.chis
|
|
330
|
+
elif y_style == '1/X':
|
|
331
|
+
y_data = 1 / susc_data.chis
|
|
332
|
+
else:
|
|
333
|
+
raise ValueError(f'Unknown y_style {y_style}')
|
|
334
|
+
|
|
335
|
+
if label is None:
|
|
336
|
+
label = f'Calculated ($H$ = {susc_data.field:.1f} Oe)'
|
|
337
|
+
|
|
338
|
+
ax.plot(
|
|
339
|
+
susc_data.temperatures,
|
|
340
|
+
y_data,
|
|
341
|
+
label=label,
|
|
342
|
+
lw=1.5,
|
|
343
|
+
color=linecolor
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
# Set x and y limits
|
|
347
|
+
set_axlims(ax, 'x', xlim)
|
|
348
|
+
set_axlims(ax, 'y', ylim)
|
|
310
349
|
|
|
311
350
|
ax.set_xlabel('$T$ (K)')
|
|
312
|
-
ax.set_ylabel(
|
|
351
|
+
ax.set_ylabel(r'$\chi T\,\mathregular{cm^3\,K\,mol^{-1}}$')
|
|
313
352
|
|
|
314
353
|
ax.xaxis.set_minor_locator(AutoMinorLocator())
|
|
315
354
|
ax.yaxis.set_minor_locator(AutoMinorLocator())
|
|
@@ -318,6 +357,15 @@ def plot_chit(chit: ArrayLike, temps: ArrayLike, fields: ArrayLike = None,
|
|
|
318
357
|
|
|
319
358
|
if save:
|
|
320
359
|
plt.savefig(save_name, dpi=500)
|
|
360
|
+
if verbose:
|
|
361
|
+
ut.cprint(
|
|
362
|
+
f'\nSpectrum saved to\n {save_name}',
|
|
363
|
+
'cyan'
|
|
364
|
+
)
|
|
365
|
+
ut.cprint(
|
|
366
|
+
f'Use width={width:.1f} in. or {width_cm:.1f} cm',
|
|
367
|
+
'cyan'
|
|
368
|
+
)
|
|
321
369
|
|
|
322
370
|
if show:
|
|
323
371
|
plt.show()
|
|
@@ -327,7 +375,7 @@ def plot_chit(chit: ArrayLike, temps: ArrayLike, fields: ArrayLike = None,
|
|
|
327
375
|
|
|
328
376
|
def plot_ir(wavenumbers: ArrayLike, linear_absorbance: ArrayLike,
|
|
329
377
|
lineshape: str = 'lorentzian', linewidth: float = 10.,
|
|
330
|
-
|
|
378
|
+
xlim: list[float] = [None, None],
|
|
331
379
|
save: bool = False, save_name: str = 'ir.png', show: bool = False,
|
|
332
380
|
window_title: str = 'Infrared spectrum'):
|
|
333
381
|
'''
|
|
@@ -343,7 +391,7 @@ def plot_ir(wavenumbers: ArrayLike, linear_absorbance: ArrayLike,
|
|
|
343
391
|
Lineshape function to use for each transition/signal
|
|
344
392
|
linewidth: float
|
|
345
393
|
Linewidth used in lineshape [cm^-1]
|
|
346
|
-
|
|
394
|
+
xlim: list[float], default [None, None]
|
|
347
395
|
Minimum and maximum x-values to plot [cm^-1]
|
|
348
396
|
save: bool, default False
|
|
349
397
|
If True, plot is saved to save_name
|
|
@@ -362,8 +410,8 @@ def plot_ir(wavenumbers: ArrayLike, linear_absorbance: ArrayLike,
|
|
|
362
410
|
'lorentzian': ut.lorentzian
|
|
363
411
|
}
|
|
364
412
|
|
|
365
|
-
if None not in
|
|
366
|
-
x_range = np.linspace(
|
|
413
|
+
if None not in xlim:
|
|
414
|
+
x_range = np.linspace(xlim[0], xlim[1], 100000)
|
|
367
415
|
else:
|
|
368
416
|
x_range = np.linspace(0, np.max(wavenumbers) * 1.1, 100000)
|
|
369
417
|
|
|
@@ -403,8 +451,8 @@ def plot_ir(wavenumbers: ArrayLike, linear_absorbance: ArrayLike,
|
|
|
403
451
|
|
|
404
452
|
def plot_raman(wavenumbers: ArrayLike, intensities: ArrayLike,
|
|
405
453
|
lineshape: str = 'gaussian', linewidth: float = 10.,
|
|
406
|
-
|
|
407
|
-
abs_type: str = 'absorption',
|
|
454
|
+
xlim: list[float] = 0., x_unit: str = 'wavenumber',
|
|
455
|
+
abs_type: str = 'absorption', ylim: list[float] = 'auto',
|
|
408
456
|
save: bool = False, save_name: str = 'raman.png',
|
|
409
457
|
show: bool = False,
|
|
410
458
|
window_title: str = 'Raman spectrum'):
|
|
@@ -466,7 +514,9 @@ def plot_ailft_orb_energies(energies: ArrayLike, labels: ArrayLike = None,
|
|
|
466
514
|
Matplotlib Axis object for plot
|
|
467
515
|
'''
|
|
468
516
|
|
|
469
|
-
|
|
517
|
+
width = 3.5
|
|
518
|
+
width_cm = width * 2.54
|
|
519
|
+
fig, ax = plt.subplots(1, 1, figsize=(width, width), num=window_title)
|
|
470
520
|
ax.yaxis.set_minor_locator(AutoMinorLocator())
|
|
471
521
|
|
|
472
522
|
if groups is not None:
|
|
@@ -497,27 +547,21 @@ def plot_ailft_orb_energies(energies: ArrayLike, labels: ArrayLike = None,
|
|
|
497
547
|
if len(occupations) != len(energies):
|
|
498
548
|
raise ValueError('Number of occupation numbers does not match number of states') # noqa
|
|
499
549
|
|
|
500
|
-
# Make spin up and spin down arrow markers
|
|
501
|
-
spup = mpl.markers.MarkerStyle(marker=r'$\leftharpoondown$')
|
|
502
|
-
spup._transform = spup.get_transform().rotate_deg(-90)
|
|
503
|
-
|
|
504
|
-
spdown = mpl.markers.MarkerStyle(marker=r'$\leftharpoondown$')
|
|
505
|
-
spdown._transform = spdown.get_transform().rotate_deg(90)
|
|
506
|
-
|
|
507
550
|
# Plot each marker
|
|
551
|
+
_fd = {'size': 20, 'family': 'DejaVu Sans'}
|
|
552
|
+
va = 'center_baseline'
|
|
508
553
|
for occ, en, xval in zip(occupations, energies, xvals):
|
|
509
|
-
lx = xval -
|
|
510
|
-
rx = xval + 1 / 10
|
|
554
|
+
lx = xval - 3 / 40
|
|
511
555
|
# Up and down
|
|
512
556
|
if occ == 2:
|
|
513
|
-
ax.
|
|
514
|
-
ax.
|
|
557
|
+
ax.text(lx, en, s='↿', color='k', fontdict=_fd, va=va)
|
|
558
|
+
ax.text(lx + 1 / 40, en, s='⇂', color='k', fontdict=_fd, va=va)
|
|
515
559
|
# up
|
|
516
560
|
elif occ == 1:
|
|
517
|
-
ax.
|
|
561
|
+
ax.text(lx, en, s='↿', color='k', fontdict=_fd, va=va)
|
|
518
562
|
# down
|
|
519
563
|
elif occ == -1:
|
|
520
|
-
ax.
|
|
564
|
+
ax.text(lx, en, s='⇂', color='k', fontdict=_fd, va=va)
|
|
521
565
|
|
|
522
566
|
if labels is not None:
|
|
523
567
|
for xval, energy, label in zip(xvals, energies, labels):
|
|
@@ -547,6 +591,7 @@ def plot_ailft_orb_energies(energies: ArrayLike, labels: ArrayLike = None,
|
|
|
547
591
|
plt.savefig(save_name, dpi=500)
|
|
548
592
|
if verbose:
|
|
549
593
|
ut.cprint(f'\nAI-LFT orbitals saved to\n{save_name}', 'cyan')
|
|
594
|
+
ut.cprint(f'Use width={width:.1f} in. or {width_cm:.1f} cm', 'cyan') # noqa
|
|
550
595
|
|
|
551
596
|
if show:
|
|
552
597
|
plt.show()
|
orto/utils.py
CHANGED
|
@@ -2,6 +2,9 @@ import sys
|
|
|
2
2
|
import os
|
|
3
3
|
from numpy.typing import ArrayLike, NDArray
|
|
4
4
|
import numpy as np
|
|
5
|
+
from docx.oxml import OxmlElement
|
|
6
|
+
from docx.oxml.ns import qn
|
|
7
|
+
from docx.table import _Cell
|
|
5
8
|
|
|
6
9
|
|
|
7
10
|
def red_exit(string):
|
|
@@ -411,9 +414,48 @@ def is_floatable(string: str) -> bool:
|
|
|
411
414
|
bool
|
|
412
415
|
True if string can be converted to float, False otherwise
|
|
413
416
|
'''
|
|
414
|
-
|
|
415
417
|
try:
|
|
416
418
|
float(string)
|
|
417
419
|
return True
|
|
418
420
|
except ValueError:
|
|
419
421
|
return False
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
def set_cell_border(cell: _Cell, **kwargs):
|
|
425
|
+
"""
|
|
426
|
+
Set cell`s border
|
|
427
|
+
Usage:
|
|
428
|
+
|
|
429
|
+
set_cell_border(
|
|
430
|
+
cell,
|
|
431
|
+
top={"sz": 12, "val": "single", "color": "#FF0000", "space": "0"},
|
|
432
|
+
bottom={"sz": 12, "color": "#00FF00", "val": "single"},
|
|
433
|
+
start={"sz": 24, "val": "dashed", "shadow": "true"},
|
|
434
|
+
end={"sz": 12, "val": "dashed"},
|
|
435
|
+
)
|
|
436
|
+
"""
|
|
437
|
+
tc = cell._tc
|
|
438
|
+
tcPr = tc.get_or_add_tcPr()
|
|
439
|
+
|
|
440
|
+
# check for tag existence, if none found, then create one
|
|
441
|
+
tcBorders = tcPr.first_child_found_in("w:tcBorders")
|
|
442
|
+
if tcBorders is None:
|
|
443
|
+
tcBorders = OxmlElement('w:tcBorders')
|
|
444
|
+
tcPr.append(tcBorders)
|
|
445
|
+
|
|
446
|
+
# list over all available tags
|
|
447
|
+
for edge in ('start', 'top', 'end', 'bottom', 'insideH', 'insideV'):
|
|
448
|
+
edge_data = kwargs.get(edge)
|
|
449
|
+
if edge_data:
|
|
450
|
+
tag = 'w:{}'.format(edge)
|
|
451
|
+
|
|
452
|
+
# check for tag existence, if none found, then create one
|
|
453
|
+
element = tcBorders.find(qn(tag))
|
|
454
|
+
if element is None:
|
|
455
|
+
element = OxmlElement(tag)
|
|
456
|
+
tcBorders.append(element)
|
|
457
|
+
|
|
458
|
+
# looks like order of attributes is important
|
|
459
|
+
for key in ["sz", "val", "color", "space", "shadow"]:
|
|
460
|
+
if key in edge_data:
|
|
461
|
+
element.set(qn('w:{}'.format(key)), str(edge_data[key]))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: orto
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.13.1
|
|
4
4
|
Summary: A package to make life easier when performing Orca calculations.
|
|
5
5
|
Home-page: https://orto.kragskow.group
|
|
6
6
|
Author: Jon Kragskow
|
|
@@ -16,10 +16,10 @@ License-File: LICENSE
|
|
|
16
16
|
Requires-Dist: numpy>=2.1.2
|
|
17
17
|
Requires-Dist: xyz_py>=5.19.2
|
|
18
18
|
Requires-Dist: matplotlib>=3.9.2
|
|
19
|
-
Requires-Dist: extto>=1.0
|
|
19
|
+
Requires-Dist: extto>=1.1.0
|
|
20
20
|
Requires-Dist: pandas>=2.2.3
|
|
21
21
|
Requires-Dist: subto>=0.1.1
|
|
22
|
-
Requires-Dist: python-docx>=1.
|
|
22
|
+
Requires-Dist: python-docx>=1.2.0
|
|
23
23
|
Dynamic: author
|
|
24
24
|
Dynamic: author-email
|
|
25
25
|
Dynamic: classifier
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
orto/__init__.py,sha256=IedlltYr3qYZxChNUdz62qogXA9Pos_MUvXdGXqAa0E,41
|
|
2
|
+
orto/__version__.py,sha256=AWOJJXuaKFwrwxYimWHjFlOhtOJuGrGuiJ0JN7ehebE,23
|
|
3
|
+
orto/cli.py,sha256=gBc8sSq9L3FXoYEyYxFQRMCCGtTEaVaGjePXOAnLM8Y,106677
|
|
4
|
+
orto/constants.py,sha256=anxaiTykO8Q_CXliR7zuOAdnXZrQ2-C4ndaviyl7kGc,419
|
|
5
|
+
orto/data.py,sha256=uHxgL-RIwQD61ZsrJPbrS0NBPDb3qIeLSbnpjlsPmiI,18225
|
|
6
|
+
orto/exceptions.py,sha256=D7oNeAEGeJNt5thzt6PaCn5FY6JcbJOWUE1N1LVhhuE,159
|
|
7
|
+
orto/extractor.py,sha256=nhrtzaeJtuU_SkMm201Z1ZqgHYnlsNfHxVOfVhs5plU,87484
|
|
8
|
+
orto/input.py,sha256=uUQV6A-8D0GZpRoY1rKK_aUPmk9kVVTnMzTHuisP5t4,11888
|
|
9
|
+
orto/job.py,sha256=tDiz9omFwinoYJamgz66MZez0Ee9HMhuCIAeHMhXRF8,5916
|
|
10
|
+
orto/plotter.py,sha256=gw1oSPilWvUO__CjIq8gP9a8_Xq0078VE9porOPvhCc,19661
|
|
11
|
+
orto/utils.py,sha256=2vMUQa_QPi7RbBdZN9EUara6A58GLZkJb9TfMTbBroU,11259
|
|
12
|
+
orto-1.13.1.dist-info/licenses/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
13
|
+
orto-1.13.1.dist-info/METADATA,sha256=k71QOiH_in85mH8YKiMRgSr2XTG_6O5ROqkHqxosiQ0,1185
|
|
14
|
+
orto-1.13.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
+
orto-1.13.1.dist-info/entry_points.txt,sha256=HXenCglMp_03JkN34pK2phkjXK9CFcXTGHKv5QaVY8I,39
|
|
16
|
+
orto-1.13.1.dist-info/top_level.txt,sha256=hQ-z28gTN_FZ2B5Kiwxr_9cUTcCoib9W5HjbkceDXw4,5
|
|
17
|
+
orto-1.13.1.dist-info/RECORD,,
|
orto-1.12.0.dist-info/RECORD
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
orto/__init__.py,sha256=IedlltYr3qYZxChNUdz62qogXA9Pos_MUvXdGXqAa0E,41
|
|
2
|
-
orto/__version__.py,sha256=68GNJTQv5qIW_NND-ON34BeDlaBPM89Dp34LgcTS2k8,23
|
|
3
|
-
orto/cli.py,sha256=s8w4_aQoT6PaEc8XR3kCb-nC0X9M_WAucKa693lc0BM,102887
|
|
4
|
-
orto/constants.py,sha256=anxaiTykO8Q_CXliR7zuOAdnXZrQ2-C4ndaviyl7kGc,419
|
|
5
|
-
orto/data.py,sha256=qs0UsCMOHqhsXYSCT8Kcmq988jQSMuGW4ZceelON0fo,14739
|
|
6
|
-
orto/exceptions.py,sha256=D7oNeAEGeJNt5thzt6PaCn5FY6JcbJOWUE1N1LVhhuE,159
|
|
7
|
-
orto/extractor.py,sha256=GKCFU7oSawYCYjOizER8e6HSp4bOsyqOxYcTPQHwdjM,84923
|
|
8
|
-
orto/input.py,sha256=uUQV6A-8D0GZpRoY1rKK_aUPmk9kVVTnMzTHuisP5t4,11888
|
|
9
|
-
orto/job.py,sha256=tDiz9omFwinoYJamgz66MZez0Ee9HMhuCIAeHMhXRF8,5916
|
|
10
|
-
orto/plotter.py,sha256=0capLbweVGiSoYVPavfymLBlVB-kC7_RaBeflgjkgyA,18360
|
|
11
|
-
orto/utils.py,sha256=GcMZ9uebOSnkPQT_U5O0X49LUtTu8YpXZxEsNKgXNTY,9838
|
|
12
|
-
orto-1.12.0.dist-info/licenses/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
13
|
-
orto-1.12.0.dist-info/METADATA,sha256=3Wb6CSI1zEmE47QyGPojokCCK5dYJ5F3ODRXpVZ-xxE,1185
|
|
14
|
-
orto-1.12.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
-
orto-1.12.0.dist-info/entry_points.txt,sha256=HXenCglMp_03JkN34pK2phkjXK9CFcXTGHKv5QaVY8I,39
|
|
16
|
-
orto-1.12.0.dist-info/top_level.txt,sha256=hQ-z28gTN_FZ2B5Kiwxr_9cUTcCoib9W5HjbkceDXw4,5
|
|
17
|
-
orto-1.12.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|