Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add cv data with offset #155

Merged
merged 1 commit into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions chem_spectra/controller/helper/share.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def extract_params(request):
# simulatenmr = bool(request.form.get('simulatenmr', default=False))
simulatenmr = request.form.get('simulatenmr', default=False) == 'true'
waveLength = request.form.get('wave_length', default=None)
axesUnits = request.form.get('axes_units', default=None)
cyclicvolta = request.form.get('cyclic_volta', default=None)
jcamp_idx = parse_int(request.form.get('jcamp_idx', default=0), 0)
list_file_names = request.form.getlist('list_file_names[]')
Expand All @@ -125,6 +126,7 @@ def extract_params(request):
'cyclic_volta': cyclicvolta,
'jcamp_idx': jcamp_idx,
'list_file_names': list_file_names,
'axesUnits': axesUnits,
}
has_params = (
params.get('peaks_str') or
Expand Down
2 changes: 1 addition & 1 deletion chem_spectra/controller/transform_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ def combine_images():
list_files.append(file_container)

params = extract_params(request)
transform_model = TraModel(None, params=params, multiple_files=list_files)
transform_model = TraModel(None, params=params, multiple_files=list_files)
tf_combine = transform_model.tf_combine(list_file_names=params['list_file_names'])
if (not tf_combine):
abort(400)
Expand Down
81 changes: 51 additions & 30 deletions chem_spectra/lib/composer/ni.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
extrac_dic, calc_npoints, BaseComposer
)
from chem_spectra.lib.shared.calc import ( # noqa: E402
calc_mpy_center, calc_ks, get_curve_endpoint, cal_slope, cal_xyIntegration
calc_mpy_center, calc_ks, get_curve_endpoint, cal_slope, cal_xyIntegration,
)


Expand Down Expand Up @@ -141,6 +141,8 @@ def __gen_cyclic_voltammetry_data_peaks(self):
content = ['##$CSCYCLICVOLTAMMETRYDATA=\n']
if self.core.is_cyclic_volta:
listMaxMinPeaks = self.core.max_min_peaks_table
cyclicvolta_data = self.core.params['cyclicvolta']
current_jcamp_idx = self.core.params['jcamp_idx']
if self.core.params['list_max_min_peaks'] is not None:
listMaxMinPeaks = self.core.params['list_max_min_peaks']

Expand All @@ -152,36 +154,44 @@ def __gen_cyclic_voltammetry_data_peaks(self):
y_pecker = self.core.ys[idx]

for peak in listMaxMinPeaks:
max_peak, min_peak = peak['max'], peak['min']
max_peak, min_peak = None, None
if 'max' in peak:
max_peak = peak['max']
if 'min' in peak:
min_peak = peak['min']
x_max_peak, y_max_peak = self.__get_xy_of_peak(max_peak)
x_min_peak, y_min_peak = self.__get_xy_of_peak(min_peak)

if (x_max_peak == '' and x_min_peak == ''):
x_pecker = ''
if 'pecker' in peak and peak['pecker'] is not None:
pecker = peak['pecker']
x_pecker = pecker['x']
y_pecker = pecker['y']
x_pecker = f"{float(x_pecker)}"

if (x_max_peak == '' and x_min_peak == '' and x_pecker == ''):
# ignore if missing both max and min peak
continue

if (x_max_peak == '' or x_min_peak == ''):
delta = ''
else:
delta = abs(x_max_peak - x_min_peak)

x_pecker = ''

# calculate ratio
if (y_min_peak == '' or y_max_peak == ''):
ratio = ''
else:
if 'pecker' in peak and peak['pecker'] is not None:
pecker = peak['pecker']
x_pecker = pecker['x']
y_pecker = pecker['y']
first_expr = abs(y_min_peak) / abs(y_max_peak)
second_expr = 0.485 * abs(y_pecker) / abs(y_max_peak)
ratio = first_expr + second_expr + 0.086
if (y_pecker) == 0:
y_pecker = ''

is_ref = peak.get('isRef', False)
is_ref_in_number = 1 if is_ref else 0
content.append(
'({x_max}, {y_max}, {x_min}, {y_min}, {ratio}, {delta}, {x_pecker}, {y_pecker})\n'.format(x_max=x_max_peak, y_max=y_max_peak, x_min=x_min_peak, y_min=y_min_peak, ratio=ratio, delta=delta, x_pecker=x_pecker, y_pecker=y_pecker) # noqa: E501
'({x_max}, {y_max}, {x_min}, {y_min}, {ratio}, {delta}, {x_pecker}, {y_pecker}, {is_ref})\n'.format(x_max=x_max_peak, y_max=y_max_peak, x_min=x_min_peak, y_min=y_min_peak, ratio=ratio, delta=delta, x_pecker=x_pecker, y_pecker=y_pecker, is_ref=is_ref_in_number) # noqa: E501
)

return content
Expand Down Expand Up @@ -256,6 +266,7 @@ def tf_img(self):
# PLOT data
plt.plot(self.core.xs, self.core.ys)
x_max, x_min = self.core.boundary['x']['max'], self.core.boundary['x']['min'] # noqa: E501

xlim_left, xlim_right = [x_min, x_max] if (self.core.is_tga or self.core.is_uv_vis or self.core.is_hplc_uv_vis or self.core.is_xrd or self.core.is_cyclic_volta or self.core.is_sec or self.core.is_cds or self.core.is_aif or self.core.is_emissions or self.core.is_dls_acf or self.core.is_dls_intensity) else [x_max, x_min] # noqa: E501
plt.xlim(xlim_left, xlim_right)
y_max, y_min = np.max(self.core.ys), np.min(self.core.ys)
Expand Down Expand Up @@ -296,7 +307,11 @@ def tf_img(self):
listMaxMinPeaks = self.core.params['list_max_min_peaks']

for peak in listMaxMinPeaks:
max_peak, min_peak = peak['max'], peak['min']
max_peak, min_peak = None, None
if 'max' in peak:
max_peak = peak['max']
if 'min' in peak:
min_peak = peak['min']
x_max_peak, y_max_peak = self.__get_xy_of_peak(max_peak)
x_min_peak, y_min_peak = self.__get_xy_of_peak(min_peak)

Expand Down Expand Up @@ -470,26 +485,26 @@ def tf_img(self):

def __prepare_metadata_info_for_csv(self, csv_writer: csv.DictWriter):
csv_writer.writerow({
'Max x': 'Measurement type',
'Max y': 'Cyclic Voltammetry',
'Ox E(V)': 'Measurement type',
'Red E(V)': 'Cyclic Voltammetry',
})
csv_writer.writerow({
'Max x': 'Measurement type ID',
'Ox E(V)': 'Measurement type ID',
})
csv_writer.writerow({
'Max x': 'Sample ID',
'Ox E(V)': 'Sample ID',
})
csv_writer.writerow({
'Max x': 'Analysis ID',
'Ox E(V)': 'Analysis ID',
})
csv_writer.writerow({
'Max x': 'Dataset ID',
'Ox E(V)': 'Dataset ID',
})
csv_writer.writerow({
'Max x': 'Dataset name',
'Ox E(V)': 'Dataset name',
})
csv_writer.writerow({
'Max x': 'Link to sample',
'Ox E(V)': 'Link to sample',
})
csv_writer.writerow({
})
Expand All @@ -507,8 +522,7 @@ def tf_csv(self):
listMaxMinPeaks = self.core.params['list_max_min_peaks']

with open(tf_csv.name, 'w', newline='', encoding='utf-8') as csvfile:
# fieldnames = ['Max', 'Min', 'I λ0', 'I ratio', 'Pecker']
fieldnames = ['Max x', 'Max y', 'Min x', 'Min y', 'Delta Ep', 'I lambda0', 'I ratio']
fieldnames = ['Ox E(V)', 'Ox I(A)', 'Red E(V)', 'Red I(A)', 'I lambda0(A)', 'I ratio', 'E1/2(V)', 'Delta Ep(mV)']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

self.__prepare_metadata_info_for_csv(writer)
Expand All @@ -523,7 +537,13 @@ def tf_csv(self):
y_pecker = self.core.ys[idx]

for peak in listMaxMinPeaks:
max_peak, min_peak = peak['max'], peak['min']
max_peak, min_peak, e12 = None, None, None
if 'max' in peak:
max_peak = peak['max']
if 'min' in peak:
min_peak = peak['min']
if 'e12' in peak:
e12 = peak['e12']
x_max_peak, y_max_peak = self.__get_xy_of_peak(max_peak)
x_min_peak, y_min_peak = self.__get_xy_of_peak(min_peak)

Expand All @@ -534,7 +554,7 @@ def tf_csv(self):
if (x_max_peak == '' or x_min_peak == ''):
delta = ''
else:
delta = abs(x_max_peak - x_min_peak)
delta = abs(x_max_peak - x_min_peak) * 1000

x_pecker = ''
# calculate ratio
Expand All @@ -552,13 +572,14 @@ def tf_csv(self):
y_pecker = ''

writer.writerow({
'Max x': '{x_max}'.format(x_max=x_max_peak),
'Max y': '{y_max}'.format(y_max=y_max_peak),
'Min x': '{x_min}'.format(x_min=x_min_peak),
'Min y': '{y_min}'.format(y_min=y_min_peak),
'Delta Ep': '{y_pecker}'.format(y_pecker=y_pecker),
'I lambda0': '{ratio}'.format(ratio=ratio),
'I ratio': '{delta}'.format(delta=delta)
'Ox E(V)': '{x_max}'.format(x_max=x_max_peak),
'Ox I(A)': '{y_max}'.format(y_max=y_max_peak),
'Red E(V)': '{x_min}'.format(x_min=x_min_peak),
'Red I(A)': '{y_min}'.format(y_min=y_min_peak),
'I lambda0(A)': '{y_pecker}'.format(y_pecker=y_pecker),
'I ratio': '{ratio}'.format(ratio=ratio),
'E1/2(V)': '{e12}'.format(e12=e12),
'Delta Ep(mV)': '{delta}'.format(delta=delta)
})
return tf_csv

Expand Down
27 changes: 26 additions & 1 deletion chem_spectra/lib/converter/jcamp/ni.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from scipy import signal

from chem_spectra.lib.converter.datatable import DatatableModel
from chem_spectra.lib.shared.calc import to_float
from chem_spectra.lib.shared.calc import (to_float, cal_cyclic_volta_shift_prev_offset_at_index)
from chem_spectra.lib.converter.jcamp.data_parse import make_ni_data_ys, make_ni_data_xs


Expand Down Expand Up @@ -54,6 +54,8 @@ def __init__(self, base):
self.x_unit = self.__set_x_unit()
self.ys = self.__read_ys()
self.xs = self.__read_xs(base)
self.__check_cylic_volta_shifted_info()

self.factor = self.__set_factor(base)
self.__set_first_last_xs()
self.clear = self.__refresh_solvent()
Expand Down Expand Up @@ -250,6 +252,14 @@ def __set_label(self):
target['y'] = 'TRANSMITTANCE'
if (self.is_xrd):
target['x'] = '2Theta'

if 'axesUnits' in self.params and self.params['axesUnits'] is not None:
axesUnits = self.params['axesUnits']
xUnit, yUnit = axesUnits['xUnit'], axesUnits['yUnit']
if xUnit != '':
target['x'] = xUnit
if yUnit != '':
target['y'] = yUnit

return target

Expand Down Expand Up @@ -302,6 +312,12 @@ def __set_factor(self, base):

def __set_x_unit(self):
x_unit = None

if 'axesUnits' in self.params and self.params['axesUnits'] is not None:
axesUnits = self.params['axesUnits']
xUnit = axesUnits['xUnit']
if xUnit != '':
return xUnit

try: # jcamp version 6
units = self.dic['UNITS']
Expand Down Expand Up @@ -634,3 +650,12 @@ def __refresh_solvent(self):
def __set_first_last_xs(self):
self.first_x = self.xs[0]
self.last_x = self.xs[-1]

def __check_cylic_volta_shifted_info(self):
if self.is_cyclic_volta == False:
return

cyclicvolta_data = self.params['cyclicvolta']
current_jcamp_idx = self.params['jcamp_idx']
offset = cal_cyclic_volta_shift_prev_offset_at_index(cyclicvolta_data, current_jcamp_idx)
self.xs = np.array([x - offset for x in self.xs])
8 changes: 8 additions & 0 deletions chem_spectra/lib/converter/share.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ def parse_params(params):
'fname': '',
'waveLength': default_wavelength,
'list_max_min_peaks': None,
'cyclicvolta': None,
'jcamp_idx': 0,
'axesUnits': None,
}

select_x = params.get('select_x', None)
Expand All @@ -42,6 +45,8 @@ def parse_params(params):
fname = '.'.join(fname)
waveLength = params.get('waveLength')
waveLength = json.loads(waveLength) if waveLength else default_wavelength
axesUnits = params.get('axesUnits')
axesUnits = json.loads(axesUnits) if axesUnits else None

jcamp_idx = params.get('jcamp_idx', 0)
cyclicvolta = params.get('cyclic_volta')
Expand Down Expand Up @@ -75,6 +80,9 @@ def parse_params(params):
'fname': fname,
'waveLength': waveLength,
'list_max_min_peaks': listMaxMinPeaks,
'cyclicvolta': cyclicvolta,
'jcamp_idx': jcamp_idx,
'axesUnits': axesUnits,
}


Expand Down
57 changes: 57 additions & 0 deletions chem_spectra/lib/shared/calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,60 @@ def cal_area_multiplicity(xL, xU, data_xs, data_ys):
lower_value = Decimal(str(ks[iL]))

return float(abs(upper_value - lower_value))

def cal_cyclic_volta_shift_offset(cyclic_data):
if cyclic_data is None:
return []
if isinstance(cyclic_data, dict) == False:
return []
if 'spectraList' not in cyclic_data:
return []

spectra_list = cyclic_data['spectraList']
if isinstance(spectra_list, list) == False:
return []

list_offsets = []

for spectra in spectra_list:
offset = 0.0
analysed_data = spectra['list']
arr_has_ref_value = list(filter(lambda x: x['isRef'] == True, analysed_data))
if len(arr_has_ref_value) > 0:
shift = spectra['shift']
val = shift['val']
ref_value = arr_has_ref_value[0]
e12 = ref_value['e12']
offset = e12 - val
list_offsets.append(offset)

return list_offsets

def cal_cyclic_volta_shift_prev_offset_at_index(cyclic_data, index=0):
if cyclic_data is None:
return 0.0
if isinstance(cyclic_data, dict) == False:
return 0.0
if 'spectraList' not in cyclic_data:
return 0.0

spectra_list = cyclic_data['spectraList']
if isinstance(spectra_list, list) == False:
return 0.0
if len(spectra_list) < index:
return 0.0

offset = 0.0

if index == len(spectra_list):
return 0.0

spectra = spectra_list[index]
analysed_data = spectra['list']
arr_has_ref_value = list(filter(lambda x: ('isRef' in x and x['isRef'] == True), analysed_data))
if len(arr_has_ref_value) > 0:
shift = spectra['shift']
if 'prevValue' in shift:
offset = shift['prevValue']

return offset
Loading
Loading