suvtools 1.0.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.
- suvtools/__init__.py +14 -0
- suvtools/calc_area.py +24 -0
- suvtools/fit_gauss.py +60 -0
- suvtools/fit_lorentz.py +60 -0
- suvtools/load.py +82 -0
- suvtools/lock_peak.py +43 -0
- suvtools/norm_bg.py +27 -0
- suvtools/save_csv.py +77 -0
- suvtools-1.0.0.dist-info/LICENSE +20 -0
- suvtools-1.0.0.dist-info/METADATA +112 -0
- suvtools-1.0.0.dist-info/RECORD +12 -0
- suvtools-1.0.0.dist-info/WHEEL +4 -0
suvtools/__init__.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Program: SUV tools
|
|
5
|
+
Version: 20220214
|
|
6
|
+
@author: Pranab Das (GitHub: @pranabdas)
|
|
7
|
+
"""
|
|
8
|
+
from .load import load
|
|
9
|
+
from .fit_gauss import fit_gauss
|
|
10
|
+
from .fit_lorentz import fit_lorentz
|
|
11
|
+
from .save_csv import save_csv
|
|
12
|
+
from .norm_bg import norm_bg
|
|
13
|
+
from .lock_peak import lock_peak
|
|
14
|
+
from .calc_area import calc_area
|
suvtools/calc_area.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Program: Calculate area under the curve
|
|
5
|
+
Version: 20220214
|
|
6
|
+
@author: Pranab Das (GitHub: @pranabdas)
|
|
7
|
+
area = suv.calc_area(y, x, x_end=None, x_end=None)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def calc_area(y, x, x_start=None, x_end=None):
|
|
12
|
+
import numpy as np
|
|
13
|
+
|
|
14
|
+
if x_start:
|
|
15
|
+
start_index = np.argmin(abs(x - x_start))
|
|
16
|
+
else:
|
|
17
|
+
start_index = 0
|
|
18
|
+
|
|
19
|
+
if x_end:
|
|
20
|
+
end_index = np.argmin(abs(x - x_end))
|
|
21
|
+
else:
|
|
22
|
+
end_index = -1
|
|
23
|
+
|
|
24
|
+
return np.trapezoid(y[start_index:end_index], x[start_index:end_index])
|
suvtools/fit_gauss.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Program: Fit peaks with Gaussian distribution
|
|
5
|
+
Version: 20220214
|
|
6
|
+
@author: Pranab Das (GitHub: @pranabdas)
|
|
7
|
+
data = suv.fit_gauss(x, y, a=None, x0=None, sigma=None, xmin=None, xmax=None)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def fit_gauss(x, y, a=None, x0=None, sigma=None, xmin=None, xmax=None, num=1000):
|
|
12
|
+
import numpy as np
|
|
13
|
+
from scipy import optimize
|
|
14
|
+
|
|
15
|
+
def gauss(x, a, x0, sigma):
|
|
16
|
+
return a * np.exp(-((x - x0) ** 2) / (2 * sigma**2))
|
|
17
|
+
|
|
18
|
+
if xmin:
|
|
19
|
+
xmin = float(xmin)
|
|
20
|
+
xmin_id = np.argmin(abs(x - xmin))
|
|
21
|
+
x = x[xmin_id:]
|
|
22
|
+
y = y[xmin_id:]
|
|
23
|
+
else:
|
|
24
|
+
xmin = x[0]
|
|
25
|
+
|
|
26
|
+
if xmax:
|
|
27
|
+
xmax = float(xmax)
|
|
28
|
+
xmax_id = np.argmin(abs(x - xmax))
|
|
29
|
+
x = x[:xmax_id]
|
|
30
|
+
y = y[:xmax_id]
|
|
31
|
+
else:
|
|
32
|
+
xmax = x[-1]
|
|
33
|
+
|
|
34
|
+
if not a:
|
|
35
|
+
a = max(y)
|
|
36
|
+
|
|
37
|
+
if not x0:
|
|
38
|
+
x0 = x[np.argmax(y)]
|
|
39
|
+
|
|
40
|
+
if not sigma:
|
|
41
|
+
sigma = abs(x[-1] - x[0]) / 10
|
|
42
|
+
|
|
43
|
+
params, _ = optimize.curve_fit(gauss, x, y, p0=[a, x0, sigma])
|
|
44
|
+
|
|
45
|
+
print(
|
|
46
|
+
"\n#---- Gaussian fitting parameters ----#\na =",
|
|
47
|
+
params[0],
|
|
48
|
+
"\nx0 =",
|
|
49
|
+
params[1],
|
|
50
|
+
"\nsigma =",
|
|
51
|
+
params[2],
|
|
52
|
+
"\nFWHM =",
|
|
53
|
+
2.355 * params[2],
|
|
54
|
+
"\n#----------------------------------------#",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
fit_x = np.linspace(xmin, xmax, num)
|
|
58
|
+
fit_y = gauss(fit_x, params[0], params[1], params[2])
|
|
59
|
+
|
|
60
|
+
return fit_x, fit_y
|
suvtools/fit_lorentz.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Program: Fit peaks with Lorentzian distribution
|
|
5
|
+
Version: 20220214
|
|
6
|
+
@author: Pranab Das (GitHub: @pranabdas)
|
|
7
|
+
data = suv.fit_lorentz(x, y, a=None, x0=None, gamma=None, xmin=None, xmax=None)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def fit_lorentz(x, y, a=None, x0=None, gamma=None, xmin=None, xmax=None, num=1000):
|
|
12
|
+
import numpy as np
|
|
13
|
+
from scipy import optimize
|
|
14
|
+
|
|
15
|
+
def lorentz(x, a, x0, gamma):
|
|
16
|
+
return a * gamma**2 / (np.pi * gamma * ((x - x0) ** 2 + gamma**2))
|
|
17
|
+
|
|
18
|
+
if xmin:
|
|
19
|
+
xmin = float(xmin)
|
|
20
|
+
xmin_id = np.argmin(abs(x - xmin))
|
|
21
|
+
x = x[xmin_id:]
|
|
22
|
+
y = y[xmin_id:]
|
|
23
|
+
else:
|
|
24
|
+
xmin = x[0]
|
|
25
|
+
|
|
26
|
+
if xmax:
|
|
27
|
+
xmax = float(xmax)
|
|
28
|
+
xmax_id = np.argmin(abs(x - xmax))
|
|
29
|
+
x = x[:xmax_id]
|
|
30
|
+
y = y[:xmax_id]
|
|
31
|
+
else:
|
|
32
|
+
xmax = x[-1]
|
|
33
|
+
|
|
34
|
+
if not a:
|
|
35
|
+
a = max(y)
|
|
36
|
+
|
|
37
|
+
if not x0:
|
|
38
|
+
x0 = x[np.argmax(y)]
|
|
39
|
+
|
|
40
|
+
if not gamma:
|
|
41
|
+
gamma = abs(x[-1] - x[0]) / 10
|
|
42
|
+
|
|
43
|
+
params, _ = optimize.curve_fit(lorentz, x, y, p0=[a, x0, gamma])
|
|
44
|
+
|
|
45
|
+
print(
|
|
46
|
+
"\n#---- Lorentzian fitting parameters ----#\na =",
|
|
47
|
+
params[0],
|
|
48
|
+
"\nx0 =",
|
|
49
|
+
params[1],
|
|
50
|
+
"\ngamma =",
|
|
51
|
+
params[2],
|
|
52
|
+
"\nFWHM =",
|
|
53
|
+
2 * params[2],
|
|
54
|
+
"\n#---------------------------------------#",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
fit_x = np.linspace(xmin, xmax, num)
|
|
58
|
+
fit_y = lorentz(fit_x, params[0], params[1], params[2])
|
|
59
|
+
|
|
60
|
+
return fit_x, fit_y
|
suvtools/load.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Program: Load SUV data
|
|
5
|
+
Version: 20220214
|
|
6
|
+
@author: Pranab Das (GitHub: @pranabdas)
|
|
7
|
+
data = suv.load("data.txt", 12)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def load(filename, scan=None):
|
|
12
|
+
import numpy as np
|
|
13
|
+
import urllib.request
|
|
14
|
+
import itertools
|
|
15
|
+
|
|
16
|
+
if (filename[:7] == "http://") or (filename[:8] == "https://"):
|
|
17
|
+
web = True
|
|
18
|
+
else:
|
|
19
|
+
web = False
|
|
20
|
+
|
|
21
|
+
if web:
|
|
22
|
+
try:
|
|
23
|
+
headers = {"User-Agent": "Mozilla/5.0"}
|
|
24
|
+
req = urllib.request.Request(url=filename, headers=headers)
|
|
25
|
+
contents = urllib.request.urlopen(req).read().decode()
|
|
26
|
+
contents = contents.splitlines()
|
|
27
|
+
except:
|
|
28
|
+
print("Could not read url.")
|
|
29
|
+
|
|
30
|
+
else:
|
|
31
|
+
fid = open(filename, "r")
|
|
32
|
+
if fid.mode == "r":
|
|
33
|
+
contents = fid.read()
|
|
34
|
+
fid.close()
|
|
35
|
+
contents = contents.splitlines()
|
|
36
|
+
|
|
37
|
+
# remove empty lines
|
|
38
|
+
# contents = list(filter(None, contents))
|
|
39
|
+
|
|
40
|
+
# find scan id and corresponding line numbers
|
|
41
|
+
scan_id = []
|
|
42
|
+
line_id = []
|
|
43
|
+
|
|
44
|
+
for line in range(len(contents)):
|
|
45
|
+
line_content = contents[line].split(" ")
|
|
46
|
+
if line_content[0] == "#S":
|
|
47
|
+
scan_id.append(int(line_content[1]))
|
|
48
|
+
line_id.append(line)
|
|
49
|
+
|
|
50
|
+
scan_id = np.array(scan_id)
|
|
51
|
+
# Determine the lines to read for specific scan
|
|
52
|
+
# Default scan set to the last scan
|
|
53
|
+
if not scan:
|
|
54
|
+
scan = scan_id[-1]
|
|
55
|
+
|
|
56
|
+
# In case given scan does not exist in the file
|
|
57
|
+
if scan not in scan_id:
|
|
58
|
+
print("Error: scan not found!")
|
|
59
|
+
return
|
|
60
|
+
else:
|
|
61
|
+
line_start = line_id[np.where(scan_id == scan)[0][0]]
|
|
62
|
+
|
|
63
|
+
if scan == scan_id[-1]:
|
|
64
|
+
line_end = len(contents)
|
|
65
|
+
else:
|
|
66
|
+
line_end = line_id[np.where(scan_id == scan)[0][0] + 1] - 1
|
|
67
|
+
|
|
68
|
+
# Extract the column names
|
|
69
|
+
# for line in range(line_end-line_start):
|
|
70
|
+
# line_content = contents[line+line_start].split(' ')
|
|
71
|
+
# if line_content[0]=='#L':
|
|
72
|
+
# colnames=line_content
|
|
73
|
+
# colnames.pop(0)
|
|
74
|
+
# colnames = list(filter(None, colnames))
|
|
75
|
+
# break
|
|
76
|
+
|
|
77
|
+
# print("Scan #", scan, "loaded. Data columns are: \n", colnames)
|
|
78
|
+
|
|
79
|
+
lines_to_read = itertools.islice(open(filename), line_start, line_end)
|
|
80
|
+
filtered_lines = itertools.dropwhile(lambda x: x.strip()[0] == "#", lines_to_read)
|
|
81
|
+
|
|
82
|
+
return np.loadtxt(filtered_lines)
|
suvtools/lock_peak.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Program: Lock the peaks at same energy location
|
|
5
|
+
Version: 20220214
|
|
6
|
+
@author: Pranab Das (GitHub: @pranabdas)
|
|
7
|
+
data = suv.lock_peak(data, refdata, x1=None, x2=None, E_col=0, I_col=9, I0_col=4)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def lock_peak(data, refdata, x1=None, x2=None, E_col=0, I_col=9, I0_col=4):
|
|
12
|
+
import numpy as np
|
|
13
|
+
|
|
14
|
+
if data.shape != refdata.shape:
|
|
15
|
+
print("Error! Data and reference data must have same dimensions!")
|
|
16
|
+
return
|
|
17
|
+
|
|
18
|
+
if not x1:
|
|
19
|
+
x1 = refdata[0, E_col]
|
|
20
|
+
if not x2:
|
|
21
|
+
x2 = refdata[-1, E_col]
|
|
22
|
+
|
|
23
|
+
x1_id = np.argmin(abs(refdata[:, E_col] - x1))
|
|
24
|
+
x2_id = np.argmin(abs(refdata[:, E_col] - x2))
|
|
25
|
+
|
|
26
|
+
ref_peak_id = np.argmax(refdata[x1_id:x2_id, I_col] / refdata[x1_id:x2_id, I0_col])
|
|
27
|
+
|
|
28
|
+
peak_id = np.argmax(data[x1_id:x2_id, I_col] / data[x1_id:x2_id, I0_col])
|
|
29
|
+
|
|
30
|
+
diff_id = peak_id - ref_peak_id
|
|
31
|
+
|
|
32
|
+
if diff_id > 0:
|
|
33
|
+
for _ in range(diff_id):
|
|
34
|
+
data = np.delete(data, 0, 0)
|
|
35
|
+
data = np.vstack((data, data[-1, :]))
|
|
36
|
+
elif diff_id < 0:
|
|
37
|
+
for _ in range(abs(diff_id)):
|
|
38
|
+
data = np.delete(data, -1, 0)
|
|
39
|
+
data = np.vstack((data[0, :], data))
|
|
40
|
+
|
|
41
|
+
data[:, E_col] = refdata[:, E_col]
|
|
42
|
+
|
|
43
|
+
return data
|
suvtools/norm_bg.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Program: Subtracts linear background and normalizes the data
|
|
5
|
+
Version: 20240619
|
|
6
|
+
@author: Pranab Das (GitHub: @pranabdas)
|
|
7
|
+
normalized_intensity = suv.norm_bg(energy, intensity, x1, x2, x_norm_loc=None)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def norm_bg(energy, intensity, x1, x2, x_norm_loc=None):
|
|
12
|
+
import numpy as np
|
|
13
|
+
|
|
14
|
+
y1 = intensity[np.argmin(abs(energy - x1))]
|
|
15
|
+
y2 = intensity[np.argmin(abs(energy - x2))]
|
|
16
|
+
|
|
17
|
+
if x_norm_loc:
|
|
18
|
+
x_norm_loc = np.argmin(abs(energy - x_norm_loc))
|
|
19
|
+
else:
|
|
20
|
+
x_norm_loc = -1
|
|
21
|
+
|
|
22
|
+
m = (y2 - y1) / (x2 - x1) # slope
|
|
23
|
+
c = y1 - (m * x1) # intersection
|
|
24
|
+
|
|
25
|
+
bg = (m * energy) + c
|
|
26
|
+
intensity -= bg
|
|
27
|
+
return intensity / intensity[x_norm_loc]
|
suvtools/save_csv.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Program: Export SUV data in CSV format
|
|
5
|
+
Version: 20220214
|
|
6
|
+
@author: Pranab Das (GitHub: @pranabdas)
|
|
7
|
+
data = suv.save_csv(filename, csvname=None, scan=None)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def save_csv(filename, csvname=None, scan=None):
|
|
12
|
+
import numpy as np
|
|
13
|
+
import pandas as pd
|
|
14
|
+
import os
|
|
15
|
+
import warnings
|
|
16
|
+
|
|
17
|
+
fid = open(filename, "r")
|
|
18
|
+
contents = fid.read()
|
|
19
|
+
fid.close()
|
|
20
|
+
contents = contents.splitlines()
|
|
21
|
+
|
|
22
|
+
# find scan id and corresponding line numbers
|
|
23
|
+
scan_id = []
|
|
24
|
+
line_id = []
|
|
25
|
+
|
|
26
|
+
for line in range(len(contents)):
|
|
27
|
+
line_content = contents[line].split(" ")
|
|
28
|
+
if line_content[0] == "#S":
|
|
29
|
+
scan_id.append(int(line_content[1]))
|
|
30
|
+
line_id.append(line)
|
|
31
|
+
|
|
32
|
+
# determine the lines to read for specific scan
|
|
33
|
+
# default scan set to the last scan
|
|
34
|
+
if not scan:
|
|
35
|
+
scan = scan_id[-1]
|
|
36
|
+
|
|
37
|
+
# if given scan does not exist in the file
|
|
38
|
+
if scan not in scan_id:
|
|
39
|
+
print("Error! Scan not found!")
|
|
40
|
+
return
|
|
41
|
+
else:
|
|
42
|
+
line_start = line_id[scan - 1]
|
|
43
|
+
if scan == scan_id[-1]:
|
|
44
|
+
line_end = len(contents)
|
|
45
|
+
else:
|
|
46
|
+
line_end = line_id[scan] - 1
|
|
47
|
+
|
|
48
|
+
if not csvname:
|
|
49
|
+
csvname = filename + "_scan_" + str(scan) + ".csv"
|
|
50
|
+
|
|
51
|
+
if os.path.isfile(csvname):
|
|
52
|
+
if csvname[-4:] == ".csv":
|
|
53
|
+
csvname = csvname[:-4]
|
|
54
|
+
csvname = csvname + "_copy.csv"
|
|
55
|
+
|
|
56
|
+
# Extract the column names
|
|
57
|
+
for line in range(line_end - line_start):
|
|
58
|
+
line_content = contents[line + line_start].split(" ")
|
|
59
|
+
if line_content[0] == "#L":
|
|
60
|
+
colnames = line_content
|
|
61
|
+
colnames.pop(0)
|
|
62
|
+
colnames = list(filter(None, colnames))
|
|
63
|
+
|
|
64
|
+
# suppress numpy warning related to max_rows behavior
|
|
65
|
+
with warnings.catch_warnings():
|
|
66
|
+
warnings.filterwarnings(action="ignore")
|
|
67
|
+
data = np.loadtxt(
|
|
68
|
+
filename,
|
|
69
|
+
comments="#",
|
|
70
|
+
skiprows=(line_start - 1),
|
|
71
|
+
max_rows=(line_end - line_start),
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# convert to dataframe
|
|
75
|
+
data = pd.DataFrame(data, columns=colnames)
|
|
76
|
+
data.to_csv(csvname, index=False)
|
|
77
|
+
print("Saved data to file:", csvname)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020-Present Pranab Das (GitHub: @pranabdas)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
9
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
10
|
+
so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: suvtools
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python library for analyzing and visualizing SSLS SUV Beamline data.
|
|
5
|
+
Home-page: https://pranabdas.github.io/suvtools/
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: python,data-analysis,matplotlib,materials-science,surface-science,condensed-matter-physics,photoelectron-spectroscopy,arpes
|
|
8
|
+
Author: Pranab Das
|
|
9
|
+
Requires-Python: >=3.9,<4.0
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Requires-Dist: matplotlib (>=3.9.2,<4.0.0)
|
|
17
|
+
Requires-Dist: numpy (>=2.0.2,<3.0.0)
|
|
18
|
+
Requires-Dist: pandas (>=2.2.3,<3.0.0)
|
|
19
|
+
Requires-Dist: scipy (>=1.13.1,<2.0.0)
|
|
20
|
+
Project-URL: Documentation, https://pranabdas.github.io/suvtools/docs/
|
|
21
|
+
Project-URL: Repository, https://github.com/pranabdas/suvtools
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
<h1 align="center">SUV Tools</h1>
|
|
25
|
+
|
|
26
|
+
<p align="center">
|
|
27
|
+
<a href="https://github.com/pranabdas/suvtools/actions/workflows/python-tests.yml"><img src="https://github.com/pranabdas/suvtools/actions/workflows/python-tests.yml/badge.svg" alt="Python tests status"></a>
|
|
28
|
+
<a href="https://github.com/pranabdas/suvtools/actions/workflows/deploy-gh-pages.yml"><img src="https://github.com/pranabdas/suvtools/actions/workflows/deploy-gh-pages.yml/badge.svg" alt="Deploy gh-pages status"></a>
|
|
29
|
+
<a href="https://github.com/pranabdas/suvtools/blob/master/LICENSE"><img src="https://img.shields.io/github/license/sourcerer-io/hall-of-fame.svg?colorB=A31F34"></a>
|
|
30
|
+
<a href="https://github.com/pranabdas/suvtools/releases/latest"><img src="https://img.shields.io/github/v/release/pranabdas/suvtools.svg" alt="Latest Release"/></a>
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
Visit the project homepage <https://pranabdas.github.io/suvtools/>
|
|
35
|
+
|
|
36
|
+
## Quick start
|
|
37
|
+
|
|
38
|
+
Install latest stable release:
|
|
39
|
+
```console
|
|
40
|
+
pip3 install --upgrade suvtools
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Import suvtools into your project:
|
|
44
|
+
```python
|
|
45
|
+
import suvtools as suv
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Modules:**
|
|
49
|
+
|
|
50
|
+
- `suv.load("datafile.txt", scan=None)`: It will return a two dimensional array
|
|
51
|
+
with columns for various parameters. If the second argument, i.e., the scan
|
|
52
|
+
number is not specified, the code will read the last scan from the file.
|
|
53
|
+
|
|
54
|
+
- `suv.fit_gauss(x, y, a=None, x0=None, sigma=None, xmin=None, xmax=None, num=1000)`:
|
|
55
|
+
returns x, Gaussian fitted y values, and prints out relevant parameters. `xmin`
|
|
56
|
+
and `xmax` determines the range to fit. If `xmin` and `xmax` are not provided,
|
|
57
|
+
whole range is used. `num` determines the number of points returned in `x_fit`
|
|
58
|
+
and `y_fit`.
|
|
59
|
+
|
|
60
|
+
- `suv.fit_lorentz(x, y, a=None, x0=None, gamma=None, xmin=None, xmax=None, num=1000)`:
|
|
61
|
+
returns x, Lorentzian fitted y values, and prints out relevant parameters.
|
|
62
|
+
`xmin` and `xmax` determines the range to fit. If `xmin` and `xmax` are not
|
|
63
|
+
provided, whole range is used. `num` determines the number of points returned in
|
|
64
|
+
`x_fit` and `y_fit`.
|
|
65
|
+
|
|
66
|
+
- `suv.save_csv("datafile.txt", csvname=None, scan=None)`: saves scan to a csv
|
|
67
|
+
file. The file will be saved in the save directory as `datafile` with name
|
|
68
|
+
`datafile.csv` unless `csvname` is specified. Like the `load` module, if the
|
|
69
|
+
scan number is not specified, it will read the last scan from the file.
|
|
70
|
+
|
|
71
|
+
- `suv.norm_bg(energy, intensity, x1, x2, x_norm_loc=None)`:
|
|
72
|
+
Removes linear background, and normalizes the data. x1, x2 are energy values
|
|
73
|
+
that determines the slope of the background. By default the normalization done
|
|
74
|
+
at the tail point of the spectra. It can be changed to other point, enter the
|
|
75
|
+
corresponding energy value. The intention is to normalize at an energy value
|
|
76
|
+
away from the peaks/features of interest.
|
|
77
|
+
|
|
78
|
+
- `suv.lock_peak(data, refdata, x1=None, x2=None, E_col=0, I_col=9, I0_col=4)`:
|
|
79
|
+
Locks peak position with respect to the reference data. It locks the maximum of
|
|
80
|
+
intensity to the same energy; the range of peak search can be specified by input
|
|
81
|
+
`x1` and `x2`. If no bounds are given, it will find the maximum in the whole
|
|
82
|
+
data range.
|
|
83
|
+
|
|
84
|
+
- `suv.calc_area(y, x, x_start=None, x_end=None)`:
|
|
85
|
+
Calculates area under the curve for given `x` and `y` values. `x_start` and
|
|
86
|
+
`x_end` can be specified to set the limit of integration region, if not provided
|
|
87
|
+
whole range is integrated.
|
|
88
|
+
|
|
89
|
+
See the notebook for some example usage.
|
|
90
|
+
|
|
91
|
+
### Documentation development
|
|
92
|
+
|
|
93
|
+
```console
|
|
94
|
+
# install npm packages
|
|
95
|
+
npm install
|
|
96
|
+
|
|
97
|
+
# serve locally
|
|
98
|
+
npm start
|
|
99
|
+
|
|
100
|
+
# build
|
|
101
|
+
npm run build
|
|
102
|
+
|
|
103
|
+
# deploy to github
|
|
104
|
+
npm run gh-deploy
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Python tests
|
|
108
|
+
|
|
109
|
+
```console
|
|
110
|
+
python3 -m unittest discover tests
|
|
111
|
+
```
|
|
112
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
suvtools/__init__.py,sha256=lw2UVqAUdtPZ5mTjRQtjLXzyibbzFwgSTfkKtRVdIYw,352
|
|
2
|
+
suvtools/calc_area.py,sha256=A3PGWu3sPjVR3rVMvupBUeWf1rBaphXVQBMhoykTSJQ,549
|
|
3
|
+
suvtools/fit_gauss.py,sha256=MNdzeY4sGwQGCXPH5Uh6cYfYxJ4-DclvVGHs_eEec-s,1400
|
|
4
|
+
suvtools/fit_lorentz.py,sha256=Lp7LxXMDcif_9TaybB9CO2-9Rn3JoLmoh5Ksxy9s7QM,1423
|
|
5
|
+
suvtools/load.py,sha256=U3gs8SmDTBt77hNpSZSinmyqjPl8IXL8VSgzXbwOsE8,2358
|
|
6
|
+
suvtools/lock_peak.py,sha256=GcnSEtCzMze8y1QhU5SYPaMaRSEwV9873XuwoF5zMSo,1227
|
|
7
|
+
suvtools/norm_bg.py,sha256=nZtHi5GVKE3lMdvIRxgHgrJXy5Cv9O9pldLqTuKdCVU,714
|
|
8
|
+
suvtools/save_csv.py,sha256=PcS4BQa1CKksJSZcqWKOS-GDx18d1s9WbdG1T70vfpo,2167
|
|
9
|
+
suvtools-1.0.0.dist-info/LICENSE,sha256=nvsF0-R601iteeQ-U8lB30wwJ3Tvpv_SYT9Syx5ntsI,1096
|
|
10
|
+
suvtools-1.0.0.dist-info/METADATA,sha256=t0doE9yh0Bf21F7CxGUKRFYWTicinoheZX1MwlSIBa8,4562
|
|
11
|
+
suvtools-1.0.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
12
|
+
suvtools-1.0.0.dist-info/RECORD,,
|