orto 1.11.3__py3-none-any.whl → 1.13.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.
- orto/__version__.py +1 -1
- orto/cli.py +567 -260
- orto/data.py +129 -3
- orto/extractor.py +81 -12
- orto/plotter.py +161 -111
- orto/utils.py +43 -1
- {orto-1.11.3.dist-info → orto-1.13.0.dist-info}/METADATA +3 -3
- orto-1.13.0.dist-info/RECORD +17 -0
- orto-1.11.3.dist-info/RECORD +0 -17
- {orto-1.11.3.dist-info → orto-1.13.0.dist-info}/WHEEL +0 -0
- {orto-1.11.3.dist-info → orto-1.13.0.dist-info}/entry_points.txt +0 -0
- {orto-1.11.3.dist-info → orto-1.13.0.dist-info}/licenses/LICENSE +0 -0
- {orto-1.11.3.dist-info → orto-1.13.0.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,69 +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
305
|
Matplotlib Figure object
|
|
282
306
|
plt.Axes
|
|
283
|
-
Matplotlib Axis object for plot
|
|
284
|
-
'''
|
|
307
|
+
Matplotlib Axis object for main plot
|
|
308
|
+
'''
|
|
285
309
|
|
|
286
|
-
|
|
287
|
-
fig, ax = plt.subplots(1, 1, figsize=(5, 4), num=window_title)
|
|
310
|
+
save_name = pathlib.Path(save_name)
|
|
288
311
|
|
|
289
|
-
if
|
|
290
|
-
|
|
291
|
-
|
|
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
|
+
)
|
|
292
322
|
else:
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
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)
|
|
305
349
|
|
|
306
350
|
ax.set_xlabel('$T$ (K)')
|
|
307
|
-
ax.set_ylabel(
|
|
351
|
+
ax.set_ylabel(r'$\chi T\,\mathregular{cm^3\,K\,mol^{-1}}$')
|
|
308
352
|
|
|
309
353
|
ax.xaxis.set_minor_locator(AutoMinorLocator())
|
|
310
354
|
ax.yaxis.set_minor_locator(AutoMinorLocator())
|
|
@@ -313,6 +357,15 @@ def plot_chit(chit: ArrayLike, temps: ArrayLike, fields: ArrayLike = None,
|
|
|
313
357
|
|
|
314
358
|
if save:
|
|
315
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
|
+
)
|
|
316
369
|
|
|
317
370
|
if show:
|
|
318
371
|
plt.show()
|
|
@@ -322,7 +375,7 @@ def plot_chit(chit: ArrayLike, temps: ArrayLike, fields: ArrayLike = None,
|
|
|
322
375
|
|
|
323
376
|
def plot_ir(wavenumbers: ArrayLike, linear_absorbance: ArrayLike,
|
|
324
377
|
lineshape: str = 'lorentzian', linewidth: float = 10.,
|
|
325
|
-
|
|
378
|
+
xlim: list[float] = [None, None],
|
|
326
379
|
save: bool = False, save_name: str = 'ir.png', show: bool = False,
|
|
327
380
|
window_title: str = 'Infrared spectrum'):
|
|
328
381
|
'''
|
|
@@ -338,7 +391,7 @@ def plot_ir(wavenumbers: ArrayLike, linear_absorbance: ArrayLike,
|
|
|
338
391
|
Lineshape function to use for each transition/signal
|
|
339
392
|
linewidth: float
|
|
340
393
|
Linewidth used in lineshape [cm^-1]
|
|
341
|
-
|
|
394
|
+
xlim: list[float], default [None, None]
|
|
342
395
|
Minimum and maximum x-values to plot [cm^-1]
|
|
343
396
|
save: bool, default False
|
|
344
397
|
If True, plot is saved to save_name
|
|
@@ -357,8 +410,8 @@ def plot_ir(wavenumbers: ArrayLike, linear_absorbance: ArrayLike,
|
|
|
357
410
|
'lorentzian': ut.lorentzian
|
|
358
411
|
}
|
|
359
412
|
|
|
360
|
-
if None not in
|
|
361
|
-
x_range = np.linspace(
|
|
413
|
+
if None not in xlim:
|
|
414
|
+
x_range = np.linspace(xlim[0], xlim[1], 100000)
|
|
362
415
|
else:
|
|
363
416
|
x_range = np.linspace(0, np.max(wavenumbers) * 1.1, 100000)
|
|
364
417
|
|
|
@@ -398,8 +451,8 @@ def plot_ir(wavenumbers: ArrayLike, linear_absorbance: ArrayLike,
|
|
|
398
451
|
|
|
399
452
|
def plot_raman(wavenumbers: ArrayLike, intensities: ArrayLike,
|
|
400
453
|
lineshape: str = 'gaussian', linewidth: float = 10.,
|
|
401
|
-
|
|
402
|
-
abs_type: str = 'absorption',
|
|
454
|
+
xlim: list[float] = 0., x_unit: str = 'wavenumber',
|
|
455
|
+
abs_type: str = 'absorption', ylim: list[float] = 'auto',
|
|
403
456
|
save: bool = False, save_name: str = 'raman.png',
|
|
404
457
|
show: bool = False,
|
|
405
458
|
window_title: str = 'Raman spectrum'):
|
|
@@ -461,7 +514,9 @@ def plot_ailft_orb_energies(energies: ArrayLike, labels: ArrayLike = None,
|
|
|
461
514
|
Matplotlib Axis object for plot
|
|
462
515
|
'''
|
|
463
516
|
|
|
464
|
-
|
|
517
|
+
width = 3.5
|
|
518
|
+
width_cm = width * 2.54
|
|
519
|
+
fig, ax = plt.subplots(1, 1, figsize=(width, width), num=window_title)
|
|
465
520
|
ax.yaxis.set_minor_locator(AutoMinorLocator())
|
|
466
521
|
|
|
467
522
|
if groups is not None:
|
|
@@ -492,27 +547,21 @@ def plot_ailft_orb_energies(energies: ArrayLike, labels: ArrayLike = None,
|
|
|
492
547
|
if len(occupations) != len(energies):
|
|
493
548
|
raise ValueError('Number of occupation numbers does not match number of states') # noqa
|
|
494
549
|
|
|
495
|
-
# Make spin up and spin down arrow markers
|
|
496
|
-
spup = mpl.markers.MarkerStyle(marker=r'$\leftharpoondown$')
|
|
497
|
-
spup._transform = spup.get_transform().rotate_deg(-90)
|
|
498
|
-
|
|
499
|
-
spdown = mpl.markers.MarkerStyle(marker=r'$\leftharpoondown$')
|
|
500
|
-
spdown._transform = spdown.get_transform().rotate_deg(90)
|
|
501
|
-
|
|
502
550
|
# Plot each marker
|
|
551
|
+
_fd = {'size': 20, 'family': 'DejaVu Sans'}
|
|
552
|
+
va = 'center_baseline'
|
|
503
553
|
for occ, en, xval in zip(occupations, energies, xvals):
|
|
504
|
-
lx = xval -
|
|
505
|
-
rx = xval + 1 / 10
|
|
554
|
+
lx = xval - 3 / 40
|
|
506
555
|
# Up and down
|
|
507
556
|
if occ == 2:
|
|
508
|
-
ax.
|
|
509
|
-
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)
|
|
510
559
|
# up
|
|
511
560
|
elif occ == 1:
|
|
512
|
-
ax.
|
|
561
|
+
ax.text(lx, en, s='↿', color='k', fontdict=_fd, va=va)
|
|
513
562
|
# down
|
|
514
563
|
elif occ == -1:
|
|
515
|
-
ax.
|
|
564
|
+
ax.text(lx, en, s='⇂', color='k', fontdict=_fd, va=va)
|
|
516
565
|
|
|
517
566
|
if labels is not None:
|
|
518
567
|
for xval, energy, label in zip(xvals, energies, labels):
|
|
@@ -542,6 +591,7 @@ def plot_ailft_orb_energies(energies: ArrayLike, labels: ArrayLike = None,
|
|
|
542
591
|
plt.savefig(save_name, dpi=500)
|
|
543
592
|
if verbose:
|
|
544
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
|
|
545
595
|
|
|
546
596
|
if show:
|
|
547
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.0
|
|
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=622hD3qJqhv4C6pyrO23lfTGvr4puThdOJtb-JpmMHU,23
|
|
3
|
+
orto/cli.py,sha256=cSyvFDnYdhLMlN-Zkj7C1hCy0D2GjZE7ZX_tBhlK-5I,106680
|
|
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.0.dist-info/licenses/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
13
|
+
orto-1.13.0.dist-info/METADATA,sha256=NZ_n3XXebJeNwk_DzcArAHVWXPA-7YxhD7Wmm6qgXPI,1185
|
|
14
|
+
orto-1.13.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
+
orto-1.13.0.dist-info/entry_points.txt,sha256=HXenCglMp_03JkN34pK2phkjXK9CFcXTGHKv5QaVY8I,39
|
|
16
|
+
orto-1.13.0.dist-info/top_level.txt,sha256=hQ-z28gTN_FZ2B5Kiwxr_9cUTcCoib9W5HjbkceDXw4,5
|
|
17
|
+
orto-1.13.0.dist-info/RECORD,,
|
orto-1.11.3.dist-info/RECORD
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
orto/__init__.py,sha256=IedlltYr3qYZxChNUdz62qogXA9Pos_MUvXdGXqAa0E,41
|
|
2
|
-
orto/__version__.py,sha256=THrG-1R9YPsmG71dG92J0I-Q0gQc4IIZkVmLr89Tots,23
|
|
3
|
-
orto/cli.py,sha256=tKYxSTYM-D3j4KWPQzhujmNiOkQ2h3IcksbHT7ZuU18,98249
|
|
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=qnoVkyrmmvzX5LZGfFmwa7rOGrL9N5A5s-c5qGwW5i0,18296
|
|
11
|
-
orto/utils.py,sha256=GcMZ9uebOSnkPQT_U5O0X49LUtTu8YpXZxEsNKgXNTY,9838
|
|
12
|
-
orto-1.11.3.dist-info/licenses/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
13
|
-
orto-1.11.3.dist-info/METADATA,sha256=OuDWmj0Uq5wFpw74fPdrqQn66Wao8j7r0mx-OpOiBb0,1185
|
|
14
|
-
orto-1.11.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
-
orto-1.11.3.dist-info/entry_points.txt,sha256=HXenCglMp_03JkN34pK2phkjXK9CFcXTGHKv5QaVY8I,39
|
|
16
|
-
orto-1.11.3.dist-info/top_level.txt,sha256=hQ-z28gTN_FZ2B5Kiwxr_9cUTcCoib9W5HjbkceDXw4,5
|
|
17
|
-
orto-1.11.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|