orto 1.5.0__py3-none-any.whl → 1.6.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 +212 -43
- orto/constants.py +2 -0
- orto/data.py +351 -0
- orto/extractor.py +151 -10
- orto/plotter.py +124 -200
- orto/utils.py +123 -0
- {orto-1.5.0.dist-info → orto-1.6.0.dist-info}/METADATA +3 -1
- orto-1.6.0.dist-info/RECORD +17 -0
- orto-1.6.0.dist-info/licenses/LICENSE +165 -0
- orto-1.5.0.dist-info/RECORD +0 -15
- {orto-1.5.0.dist-info → orto-1.6.0.dist-info}/WHEEL +0 -0
- {orto-1.5.0.dist-info → orto-1.6.0.dist-info}/entry_points.txt +0 -0
- {orto-1.5.0.dist-info → orto-1.6.0.dist-info}/top_level.txt +0 -0
orto/plotter.py
CHANGED
|
@@ -2,117 +2,44 @@ import matplotlib.pyplot as plt
|
|
|
2
2
|
import matplotlib as mpl
|
|
3
3
|
from matplotlib.ticker import AutoMinorLocator
|
|
4
4
|
import numpy as np
|
|
5
|
-
from numpy.typing import ArrayLike
|
|
5
|
+
from numpy.typing import ArrayLike
|
|
6
6
|
import itertools
|
|
7
7
|
import pathlib
|
|
8
8
|
|
|
9
9
|
from . import utils as ut
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
area : float
|
|
29
|
-
Area of Gaussian function
|
|
30
|
-
|
|
31
|
-
Return
|
|
32
|
-
------
|
|
33
|
-
list[float]
|
|
34
|
-
g(p) at each value of p
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
c = fwhm / (2 * np.sqrt(2 * np.log(2)))
|
|
38
|
-
|
|
39
|
-
a = 1. / (c * np.sqrt(2 * np.pi))
|
|
40
|
-
|
|
41
|
-
gaus = a * np.exp(-(p - b)**2 / (2 * c**2))
|
|
42
|
-
|
|
43
|
-
gaus *= area
|
|
44
|
-
|
|
45
|
-
return gaus
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def lorentzian(p: ArrayLike, fwhm, p0, area) -> NDArray:
|
|
49
|
-
"""
|
|
50
|
-
Lotenztian L(p) with given peak position (b), fwhm, and area
|
|
51
|
-
|
|
52
|
-
L(p) = (0.5*area*fwhm/pi) * 1/((p-p0)**2 + (0.5*fwhm)**2)
|
|
53
|
-
|
|
54
|
-
Parameters
|
|
55
|
-
----------
|
|
56
|
-
p : array_like
|
|
57
|
-
Continuous variable
|
|
58
|
-
fwhm: float
|
|
59
|
-
Full Width at Half-Maximum
|
|
60
|
-
p0 : float
|
|
61
|
-
Peak position
|
|
62
|
-
area : float
|
|
63
|
-
Area of Lorentzian function
|
|
64
|
-
|
|
65
|
-
Return
|
|
66
|
-
------
|
|
67
|
-
list[float]
|
|
68
|
-
L(p) at each value of p
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
lor = 0.5 * fwhm / np.pi
|
|
72
|
-
lor *= 1. / ((p - p0)**2 + (0.5 * fwhm)**2)
|
|
73
|
-
|
|
74
|
-
lor *= area
|
|
75
|
-
|
|
76
|
-
return lor
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def plot_abs(x_values: ArrayLike, x_type: str, foscs: ArrayLike,
|
|
80
|
-
lineshape: str = 'gaussian', linewidth: float = 100.,
|
|
81
|
-
x_lim: list[float] = ['auto', 'auto'],
|
|
82
|
-
abs_type: str = 'napierian',
|
|
83
|
-
y_lim: list[float] = [0., 'auto'],
|
|
84
|
-
x_shift: float = 0., normalise: bool = False,
|
|
85
|
-
osc_style: str = 'separate', save: bool = False,
|
|
86
|
-
save_name: str = 'absorption_spectrum.png', show: bool = False,
|
|
87
|
-
verbose: bool = True,
|
|
88
|
-
window_title: str = 'Absorption Spectrum',
|
|
89
|
-
plot_type: str = 'absorption') -> tuple[plt.Figure, list[plt.Axes]]: # noqa
|
|
10
|
+
from . import data
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def plot_absorption_spectrum(abs_data: data.AbsorptionData,
|
|
14
|
+
linecolor: str = 'black',
|
|
15
|
+
stickcolour: str = 'black',
|
|
16
|
+
x_lim: list[float] = ['auto', 'auto'],
|
|
17
|
+
y_lim: list[float] = [0., 'auto'],
|
|
18
|
+
x_shift: float = 0.,
|
|
19
|
+
normalise: bool = False,
|
|
20
|
+
osc_style: str = 'separate',
|
|
21
|
+
fig: plt.Figure = None, ax: plt.Axes = None,
|
|
22
|
+
oax: plt.Axes = None, save: bool = False,
|
|
23
|
+
save_name: str = 'absorption_spectrum.png',
|
|
24
|
+
show: bool = False,
|
|
25
|
+
verbose: bool = True,
|
|
26
|
+
window_title: str = 'Absorption Spectrum',
|
|
27
|
+
legend: bool = True) -> tuple[plt.Figure, plt.Axes, plt.Axes | None]: # noqa
|
|
90
28
|
'''
|
|
91
|
-
Plots absorption spectrum
|
|
92
|
-
Spectrum is computed as a sum of Gaussian or Lorentzian lineshapes.\n
|
|
93
|
-
The x_values can be either wavenumbers [cm^-1], wavelengths [nm] or\n
|
|
94
|
-
energies [eV].\n
|
|
29
|
+
Plots absorption spectrum from AbsorptionSpectrum object.\n
|
|
95
30
|
|
|
96
31
|
Parameters
|
|
97
32
|
----------
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
foscs: array_like
|
|
105
|
-
Oscillator strength of each transition
|
|
106
|
-
lineshape: str {'gaussian', 'lorentzian'}
|
|
107
|
-
Lineshape function to use for each transition/signal
|
|
108
|
-
linewidth: float
|
|
109
|
-
Linewidth used in lineshape [cm^-1]
|
|
33
|
+
abs_data: data.AbsorptionData
|
|
34
|
+
Data object containing absorption data and spectrum
|
|
35
|
+
linecolor: str, default 'black'
|
|
36
|
+
Color of the continuous spectrum line
|
|
37
|
+
stickcolour: str, default 'black'
|
|
38
|
+
Color of the oscillator strength sticks
|
|
110
39
|
x_lim: list[float], default ['auto', 'auto']
|
|
111
|
-
Minimum and maximum x-values to plot
|
|
40
|
+
Minimum and maximum x-values to plot
|
|
112
41
|
y_lim: list[float | str], default [0., 'auto']
|
|
113
|
-
Minimum and maximum y-values to plot
|
|
114
|
-
abs_type: str {'napierian', 'logarithmic'}
|
|
115
|
-
Absorbance (and epsilon) type to use. Orca_mapspc uses napierian
|
|
42
|
+
Minimum and maximum y-values to plot
|
|
116
43
|
normalise: bool, default False
|
|
117
44
|
If True, normalise the absorption spectrum to the maximum value.
|
|
118
45
|
osc_style: str, default 'separate'
|
|
@@ -120,6 +47,12 @@ def plot_abs(x_values: ArrayLike, x_type: str, foscs: ArrayLike,
|
|
|
120
47
|
- 'separate': plots oscillator strengths as stems on separate axis
|
|
121
48
|
- 'combined': plots oscillator strengths on intensity axis
|
|
122
49
|
- 'off': does not plot oscillator strengths
|
|
50
|
+
fig: plt.Figure | None, optional
|
|
51
|
+
If provided, uses this Figure object for plotting
|
|
52
|
+
ax: plt.Axes | None, optional
|
|
53
|
+
If provided, uses this Axis object for plotting spectrum
|
|
54
|
+
oax: plt.Axes | None, optional
|
|
55
|
+
If provided, uses this Axis object for plotting oscillator strengths
|
|
123
56
|
save: bool, default False
|
|
124
57
|
If True, plot is saved to save_name
|
|
125
58
|
save_name: str | pathlib.Path, default 'absorption_spectrum.png'
|
|
@@ -130,9 +63,8 @@ def plot_abs(x_values: ArrayLike, x_type: str, foscs: ArrayLike,
|
|
|
130
63
|
If True, plot file location is written to terminal
|
|
131
64
|
window_title: str, default 'UV-Visible Absorption Spectrum'
|
|
132
65
|
Title of figure window, not of plot
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
66
|
+
legend: bool, default True
|
|
67
|
+
If True, a legend is added to the plot
|
|
136
68
|
Returns
|
|
137
69
|
-------
|
|
138
70
|
plt.Figure
|
|
@@ -141,20 +73,16 @@ def plot_abs(x_values: ArrayLike, x_type: str, foscs: ArrayLike,
|
|
|
141
73
|
Matplotlib Axis object for main plot followed by\n
|
|
142
74
|
Matplotlib Axis object for twinx oscillator strength axis
|
|
143
75
|
'''
|
|
144
|
-
|
|
145
76
|
save_name = pathlib.Path(save_name)
|
|
146
77
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if len(x_values) != len(foscs):
|
|
150
|
-
raise ValueError('x_values and foscs must have the same length')
|
|
78
|
+
if abs_data.spectrum is None:
|
|
79
|
+
raise ValueError('AbsorptionData object does not contain spectrum')
|
|
151
80
|
|
|
152
|
-
fig
|
|
81
|
+
if fig is None or ax is None:
|
|
82
|
+
fig, ax = plt.subplots(1, 1, num=window_title)
|
|
153
83
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
'lorentzian': lorentzian
|
|
157
|
-
}
|
|
84
|
+
if oax is None and osc_style == 'separate':
|
|
85
|
+
oax = ax.twinx()
|
|
158
86
|
|
|
159
87
|
if not isinstance(x_lim, list):
|
|
160
88
|
raise ValueError('`x_lim` must be a list of values')
|
|
@@ -163,137 +91,133 @@ def plot_abs(x_values: ArrayLike, x_type: str, foscs: ArrayLike,
|
|
|
163
91
|
if isinstance(x_lim[0], str):
|
|
164
92
|
if x_lim[0] == 'auto':
|
|
165
93
|
x_lim[0] = ax.get_ylim()[0]
|
|
166
|
-
|
|
94
|
+
elif ut.is_floatable(x_lim[0]):
|
|
167
95
|
x_lim[0] = float(x_lim[0])
|
|
96
|
+
else:
|
|
97
|
+
raise ValueError(f'Invalid x_lim[0] value: {x_lim[0]}')
|
|
168
98
|
if isinstance(x_lim[1], str):
|
|
169
99
|
if x_lim[1] == 'auto':
|
|
170
100
|
x_lim[1] = ax.get_ylim()[1]
|
|
171
|
-
|
|
101
|
+
elif ut.is_floatable(x_lim[1]):
|
|
172
102
|
x_lim[1] = float(x_lim[1])
|
|
173
|
-
|
|
174
|
-
|
|
103
|
+
else:
|
|
104
|
+
raise ValueError(f'Invalid x_lim[1] value: {x_lim[1]}')
|
|
175
105
|
|
|
176
106
|
# Set limits and range of continuous variable
|
|
177
|
-
ax.set_xlim([x_lim[0], x_lim[1]])
|
|
178
|
-
x_grid = np.linspace(x_lim[0], x_lim[1], 100000)
|
|
179
|
-
|
|
180
|
-
# Exclude values of x_values out of the range of x_lim
|
|
181
|
-
x_values = np.asarray(
|
|
182
|
-
[val for val in x_values if x_lim[0] <= val <= x_lim[1]]
|
|
183
|
-
)
|
|
184
|
-
# Exclude oscillator strengths for those values
|
|
185
|
-
foscs = np.asarray(
|
|
186
|
-
[
|
|
187
|
-
fosc
|
|
188
|
-
for val, fosc in zip(x_values, foscs)
|
|
189
|
-
if x_lim[0] <= val <= x_lim[1]]
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
# Conversion from oscillator strength to napierian integrated absorption
|
|
193
|
-
# coefficient
|
|
194
|
-
# This is the value of A for a harmonically oscillating electron
|
|
195
|
-
A_elec = 2.31E8
|
|
196
|
-
# convert to common log absorbance if desired
|
|
197
|
-
if abs_type == 'log':
|
|
198
|
-
A_elec /= np.log(10)
|
|
199
|
-
A_logs = [fosc * A_elec for fosc in foscs]
|
|
200
|
-
|
|
201
|
-
# Spectrum as sum of signals. Always computed in wavenumbers.
|
|
202
|
-
spectrum = np.sum([
|
|
203
|
-
ls_func[lineshape](x_grid, linewidth, x_value, A_log)
|
|
204
|
-
for x_value, A_log in zip(x_values, A_logs)
|
|
205
|
-
], axis=0)
|
|
107
|
+
# ax.set_xlim([x_lim[0], x_lim[1]])
|
|
206
108
|
|
|
109
|
+
# Normalisation of spectrum
|
|
207
110
|
if normalise:
|
|
208
111
|
# Normalise the spectrum to the maximum value
|
|
209
|
-
spectrum
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
plot_type.capitalize()
|
|
213
|
-
)
|
|
214
|
-
) # noqa
|
|
112
|
+
_y_values = abs_data.spectrum.y_values / np.max(abs_data.spectrum.y_values) # noqa
|
|
113
|
+
_osc = abs_data.osc_strengths / np.max(abs_data.osc_strengths)
|
|
114
|
+
ax.set_ylabel('Normalised Absorption')
|
|
215
115
|
else:
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
116
|
+
_y_values = abs_data.spectrum.y_values
|
|
117
|
+
_osc = abs_data.osc_strengths
|
|
118
|
+
ax.set_ylabel(abs_data.spectrum.y_label)
|
|
119
|
+
|
|
120
|
+
if abs_data.spectrum.x_label == 'Wavelength (nm)':
|
|
121
|
+
ax.invert_xaxis()
|
|
122
|
+
stick_x_values = [
|
|
123
|
+
wavelength + x_shift
|
|
124
|
+
for wavelength in abs_data.wavelengths
|
|
125
|
+
]
|
|
126
|
+
elif abs_data.spectrum.x_label == 'Energy (eV)':
|
|
127
|
+
stick_x_values = [
|
|
128
|
+
energy + x_shift
|
|
129
|
+
for energy in abs_data.energies
|
|
130
|
+
]
|
|
131
|
+
elif abs_data.spectrum.x_label == r'Wavenumber (cm$\mathregular{^{-1}}$)':
|
|
132
|
+
stick_x_values = [
|
|
133
|
+
wavenumber + x_shift
|
|
134
|
+
for wavenumber in abs_data.wavenumbers
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
x_values = abs_data.spectrum.x_grid + x_shift
|
|
230
138
|
|
|
231
139
|
# Main spectrum
|
|
232
|
-
ax.plot(
|
|
140
|
+
ax.plot(
|
|
141
|
+
x_values,
|
|
142
|
+
_y_values,
|
|
143
|
+
color=linecolor,
|
|
144
|
+
label=abs_data.spectrum.comment
|
|
145
|
+
)
|
|
233
146
|
|
|
234
147
|
if osc_style == 'separate':
|
|
235
|
-
fax = ax.twinx()
|
|
236
148
|
# Oscillator strength twin axis
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
149
|
+
oax.stem(
|
|
150
|
+
stick_x_values,
|
|
151
|
+
_osc,
|
|
152
|
+
basefmt=' ',
|
|
153
|
+
markerfmt=' ',
|
|
154
|
+
linefmt=stickcolour
|
|
155
|
+
)
|
|
156
|
+
oax.yaxis.set_minor_locator(AutoMinorLocator())
|
|
157
|
+
oax.set_ylabel(r'$f_\mathregular{osc}$')
|
|
158
|
+
oax.set_ylim([0., oax.get_ylim()[1]])
|
|
241
159
|
elif osc_style == 'combined':
|
|
242
|
-
fax = None
|
|
243
|
-
plt.subplots_adjust(right=0.2)
|
|
244
160
|
ax.stem(
|
|
245
|
-
|
|
246
|
-
|
|
161
|
+
stick_x_values,
|
|
162
|
+
abs_data.osc_strengths/np.max(abs_data.osc_strengths) * np.max(_y_values), # noqa
|
|
247
163
|
basefmt=' ',
|
|
248
|
-
markerfmt=' '
|
|
164
|
+
markerfmt=' ',
|
|
165
|
+
linefmt=stickcolour
|
|
249
166
|
)
|
|
167
|
+
oax.set_yticks([])
|
|
168
|
+
oax.spines['right'].set_visible(False)
|
|
169
|
+
oax.spines['top'].set_visible(False)
|
|
250
170
|
ax.spines['right'].set_visible(False)
|
|
251
171
|
ax.spines['top'].set_visible(False)
|
|
252
172
|
else:
|
|
253
|
-
fax = None
|
|
254
173
|
# No oscillator strength plot
|
|
255
174
|
plt.subplots_adjust(right=0.2)
|
|
175
|
+
oax.set_yticks([])
|
|
176
|
+
oax.spines['right'].set_visible(False)
|
|
177
|
+
oax.spines['top'].set_visible(False)
|
|
256
178
|
ax.spines['right'].set_visible(False)
|
|
257
179
|
ax.spines['top'].set_visible(False)
|
|
258
180
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
181
|
+
# Set y limits if specified
|
|
182
|
+
_y_lim = y_lim.copy()
|
|
183
|
+
if _y_lim[0] != _y_lim[1]:
|
|
184
|
+
# Lower limit either auto or specified
|
|
185
|
+
if isinstance(_y_lim[0], str):
|
|
186
|
+
if _y_lim[0] == 'auto':
|
|
187
|
+
_y_lim[0] = ax.get_ylim()[0]
|
|
263
188
|
else:
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
189
|
+
_y_lim[0] = float(_y_lim[0])
|
|
190
|
+
# Upper limit either auto or specified
|
|
191
|
+
if isinstance(_y_lim[1], str):
|
|
192
|
+
if _y_lim[1] == 'auto':
|
|
193
|
+
_y_lim[1] = ax.get_ylim()[1]
|
|
268
194
|
else:
|
|
269
|
-
|
|
270
|
-
|
|
195
|
+
_y_lim[1] = float(_y_lim[1])
|
|
196
|
+
# Set values
|
|
197
|
+
ax.set_ylim([_y_lim[0], _y_lim[1]])
|
|
271
198
|
|
|
272
199
|
ax.xaxis.set_minor_locator(AutoMinorLocator())
|
|
273
200
|
ax.yaxis.set_minor_locator(AutoMinorLocator())
|
|
274
201
|
|
|
275
|
-
|
|
276
|
-
'wavenumber': r'Wavenumber (cm$^\mathregular{-1}$)',
|
|
277
|
-
'wavelength': 'Wavelength (nm)',
|
|
278
|
-
'energy': r'Energy (eV)'
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
ax.set_xlabel(xtype_to_label[x_type.lower()])
|
|
202
|
+
ax.set_xlabel(abs_data.spectrum.x_label)
|
|
282
203
|
|
|
283
204
|
fig.tight_layout()
|
|
284
205
|
|
|
206
|
+
if legend:
|
|
207
|
+
ax.legend()
|
|
208
|
+
|
|
285
209
|
if save:
|
|
286
210
|
plt.savefig(save_name, dpi=500)
|
|
287
211
|
if verbose:
|
|
288
212
|
ut.cprint(
|
|
289
|
-
f'\
|
|
213
|
+
f'\nSpectrum saved to\n {save_name}',
|
|
290
214
|
'cyan'
|
|
291
215
|
)
|
|
292
216
|
|
|
293
217
|
if show:
|
|
294
218
|
plt.show()
|
|
295
219
|
|
|
296
|
-
return fig,
|
|
220
|
+
return fig, ax, oax
|
|
297
221
|
|
|
298
222
|
|
|
299
223
|
def wl_to_wn(wl: float) -> float:
|
|
@@ -407,8 +331,8 @@ def plot_ir(wavenumbers: ArrayLike, linear_absorbance: ArrayLike,
|
|
|
407
331
|
fig, ax = plt.subplots(1, 1, num=window_title)
|
|
408
332
|
|
|
409
333
|
ls_func = {
|
|
410
|
-
'gaussian': gaussian,
|
|
411
|
-
'lorentzian': lorentzian
|
|
334
|
+
'gaussian': ut.gaussian,
|
|
335
|
+
'lorentzian': ut.lorentzian
|
|
412
336
|
}
|
|
413
337
|
|
|
414
338
|
if None not in x_lim:
|
orto/utils.py
CHANGED
|
@@ -293,3 +293,126 @@ def orbname_to_mathmode(names: ArrayLike) -> NDArray:
|
|
|
293
293
|
])
|
|
294
294
|
|
|
295
295
|
return mmode
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def check_font_envvar() -> None:
|
|
299
|
+
'''
|
|
300
|
+
Checks if orto_fontname environment variable is set, and if so
|
|
301
|
+
sets matplotlib font to specified font
|
|
302
|
+
'''
|
|
303
|
+
|
|
304
|
+
import matplotlib.pyplot as plt
|
|
305
|
+
|
|
306
|
+
if os.getenv('orto_fontname'):
|
|
307
|
+
try:
|
|
308
|
+
plt.rcParams['font.family'] = os.getenv('orto_fontname')
|
|
309
|
+
except ValueError:
|
|
310
|
+
red_exit(
|
|
311
|
+
'Error setting font to {}'.format(
|
|
312
|
+
os.getenv('orto_fontname')
|
|
313
|
+
)
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
return
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def gaussian(p: ArrayLike, fwhm: float, b: float, area: float) -> NDArray:
|
|
320
|
+
"""
|
|
321
|
+
Gaussian g(p) with given peak position (b), fwhm, and area
|
|
322
|
+
|
|
323
|
+
g(p) = area/(c*sqrt(2pi)) * exp(-(p-b)**2/(2c**2))
|
|
324
|
+
|
|
325
|
+
c = fwhm/(2*np.sqrt(2*np.log(2)))
|
|
326
|
+
|
|
327
|
+
Parameters
|
|
328
|
+
----------
|
|
329
|
+
p : array_like
|
|
330
|
+
Continuous variable
|
|
331
|
+
fwhm: float
|
|
332
|
+
Full Width at Half-Maximum
|
|
333
|
+
b : float
|
|
334
|
+
Peak position
|
|
335
|
+
area : float
|
|
336
|
+
Area of Gaussian function
|
|
337
|
+
|
|
338
|
+
Return
|
|
339
|
+
------
|
|
340
|
+
list[float]
|
|
341
|
+
g(p) at each value of p
|
|
342
|
+
"""
|
|
343
|
+
|
|
344
|
+
c = fwhm / (2 * np.sqrt(2 * np.log(2)))
|
|
345
|
+
|
|
346
|
+
a = 1. / (c * np.sqrt(2 * np.pi))
|
|
347
|
+
|
|
348
|
+
gaus = a * np.exp(-(p - b)**2 / (2 * c**2))
|
|
349
|
+
|
|
350
|
+
gaus *= area
|
|
351
|
+
|
|
352
|
+
return gaus
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
def lorentzian(p: ArrayLike, fwhm, p0, area) -> NDArray:
|
|
356
|
+
"""
|
|
357
|
+
Lotenztian L(p) with given peak position (b), fwhm, and area
|
|
358
|
+
|
|
359
|
+
L(p) = (0.5*area*fwhm/pi) * 1/((p-p0)**2 + (0.5*fwhm)**2)
|
|
360
|
+
|
|
361
|
+
Parameters
|
|
362
|
+
----------
|
|
363
|
+
p : array_like
|
|
364
|
+
Continuous variable
|
|
365
|
+
fwhm: float
|
|
366
|
+
Full Width at Half-Maximum
|
|
367
|
+
p0 : float
|
|
368
|
+
Peak position
|
|
369
|
+
area : float
|
|
370
|
+
Area of Lorentzian function
|
|
371
|
+
|
|
372
|
+
Return
|
|
373
|
+
------
|
|
374
|
+
list[float]
|
|
375
|
+
L(p) at each value of p
|
|
376
|
+
"""
|
|
377
|
+
|
|
378
|
+
lor = 0.5 * fwhm / np.pi
|
|
379
|
+
lor *= 1. / ((p - p0)**2 + (0.5 * fwhm)**2)
|
|
380
|
+
|
|
381
|
+
lor *= area
|
|
382
|
+
|
|
383
|
+
return lor
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
def find_unique_substring(names):
|
|
387
|
+
'''
|
|
388
|
+
Finds unique substring in each name from list of names
|
|
389
|
+
'''
|
|
390
|
+
|
|
391
|
+
unique_names = []
|
|
392
|
+
for name in names:
|
|
393
|
+
for il, letter in enumerate(name):
|
|
394
|
+
if all(oname[il] != letter for oname in names if oname != name):
|
|
395
|
+
unique_names.append(name[il:])
|
|
396
|
+
break
|
|
397
|
+
return unique_names
|
|
398
|
+
|
|
399
|
+
def is_floatable(string: str) -> bool:
|
|
400
|
+
'''
|
|
401
|
+
Checks if string can be converted to float
|
|
402
|
+
|
|
403
|
+
Parameters
|
|
404
|
+
----------
|
|
405
|
+
string : str
|
|
406
|
+
String to check
|
|
407
|
+
|
|
408
|
+
Returns
|
|
409
|
+
-------
|
|
410
|
+
bool
|
|
411
|
+
True if string can be converted to float, False otherwise
|
|
412
|
+
'''
|
|
413
|
+
|
|
414
|
+
try:
|
|
415
|
+
float(string)
|
|
416
|
+
return True
|
|
417
|
+
except ValueError:
|
|
418
|
+
return False
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: orto
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.6.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
|
|
@@ -12,6 +12,7 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
13
|
Requires-Python: >=3.10
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
15
16
|
Requires-Dist: numpy>=2.1.2
|
|
16
17
|
Requires-Dist: xyz_py>=5.13.1
|
|
17
18
|
Requires-Dist: matplotlib>=3.9.2
|
|
@@ -25,6 +26,7 @@ Dynamic: classifier
|
|
|
25
26
|
Dynamic: description
|
|
26
27
|
Dynamic: description-content-type
|
|
27
28
|
Dynamic: home-page
|
|
29
|
+
Dynamic: license-file
|
|
28
30
|
Dynamic: project-url
|
|
29
31
|
Dynamic: requires-dist
|
|
30
32
|
Dynamic: requires-python
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
orto/__init__.py,sha256=IedlltYr3qYZxChNUdz62qogXA9Pos_MUvXdGXqAa0E,41
|
|
2
|
+
orto/__version__.py,sha256=bYN93DTWr8alkTnO3wj31CU5gqTshxIcsbXUcJcUAc8,22
|
|
3
|
+
orto/cli.py,sha256=AH9Cnfu21XGTs2ygLZGb8yxzJPe1gxxnF9qOsm_H1II,76491
|
|
4
|
+
orto/constants.py,sha256=anxaiTykO8Q_CXliR7zuOAdnXZrQ2-C4ndaviyl7kGc,419
|
|
5
|
+
orto/data.py,sha256=r6Ht1X0-FhjUbEAAi3a9F2R2_QG3QFElaAAcZNz4GRQ,11213
|
|
6
|
+
orto/exceptions.py,sha256=D7oNeAEGeJNt5thzt6PaCn5FY6JcbJOWUE1N1LVhhuE,159
|
|
7
|
+
orto/extractor.py,sha256=d2_pGQeIjK_JbsMINTawUgcO2vcPq0b9uQj9VKuI720,75953
|
|
8
|
+
orto/input.py,sha256=N8JbySSVEC_qmXZ7ppJsZ7Z1qel6PfalGYRtnX1hJ6U,9900
|
|
9
|
+
orto/job.py,sha256=SM0nlc_bqhhPvfuuykhMvaUnkwC3Gp-6RvYw_a0TyGc,5855
|
|
10
|
+
orto/plotter.py,sha256=-8Lgv-kDjw_wHZrDrQzQGT521gSZ3IJdIeLqzdQgflQ,17656
|
|
11
|
+
orto/utils.py,sha256=fghKZnrO1HTtOZPZRbNK6QTgUOXiIQ6NEFvesDSoY0o,9836
|
|
12
|
+
orto-1.6.0.dist-info/licenses/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
13
|
+
orto-1.6.0.dist-info/METADATA,sha256=zfjB9HzSeKgJKRlTqLMw2AmqspP1nyYAlJZDa_vS3kE,1184
|
|
14
|
+
orto-1.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
+
orto-1.6.0.dist-info/entry_points.txt,sha256=HXenCglMp_03JkN34pK2phkjXK9CFcXTGHKv5QaVY8I,39
|
|
16
|
+
orto-1.6.0.dist-info/top_level.txt,sha256=hQ-z28gTN_FZ2B5Kiwxr_9cUTcCoib9W5HjbkceDXw4,5
|
|
17
|
+
orto-1.6.0.dist-info/RECORD,,
|