CSU-IR-Web / ir_process.py
Hsqcsu's picture
Update ir_process.py
351c0a7 verified
Raw History Blame Contribute Delete
3.75 kB
import numpy as np
from scipy.interpolate import CubicSpline
def _resample_and_pad_spectrum(wavenumbers, intensities):
x = np.array(wavenumbers, dtype=float)
y = np.array(intensities, dtype=float)
valid_mask = (~np.isnan(x)) & (~np.isnan(y)) & (y != 0)
x = x[valid_mask]
y = y[valid_mask]
if len(x) < 4:
return None
if np.nanmax(x) < 100.0:
x = 10000.0 / x
_, unique_indices = np.unique(x, return_index=True)
x = x[unique_indices]
y = y[unique_indices]
sort_idx = np.argsort(x)
x = x[sort_idx]
y = y[sort_idx]
min_x, max_x = x[0], x[-1]
start = max(min_x, 500.0)
end = min(max_x, 4000.0)
if start >= end:
return None
mask = (x >= start) & (x <= end)
x_crop = x[mask]
y_crop = y[mask]
if len(x_crop) < 4:
return None
start_int = int(np.ceil(start))
end_int = int(np.floor(end))
x_temp = np.arange(start_int, end_int + 1, 1.0)
x_temp = np.clip(x_temp, x_crop[0], x_crop[-1])
cs_crop = CubicSpline(x_crop, y_crop, extrapolate=True)
y_temp = cs_crop(x_temp)
x_full = np.arange(500, 4001, 1.0)
y_full = np.zeros_like(x_full)
idx_start = start_int - 500
idx_end = end_int - 500
y_full[idx_start:idx_end + 1] = y_temp
if idx_start > 0:
y_full[:idx_start] = y_temp[0]
if idx_end < 3500:
y_full[idx_end + 1:] = y_temp[-1]
x_target = np.linspace(500.0, 4000.0, 3500)
cs_full = CubicSpline(x_full, y_full, extrapolate=True)
return cs_full(x_target)
def preprocess_csv_spectra_higer_500(wavenumbers, transmittances, method='cubic'):
try:
t = np.array(transmittances, dtype=float)
if np.nanmax(t) > 1.5:
t = t / 100.0
t = np.clip(t, 1e-4, 1.0)
abs_raw = -np.log10(t)
processed_y = _resample_and_pad_spectrum(wavenumbers, abs_raw)
if processed_y is None:
return None
min_val = np.min(processed_y)
max_val = np.max(processed_y)
if max_val > min_val:
normalized = (processed_y - min_val) / (max_val - min_val)
else:
normalized = np.zeros_like(processed_y)
if np.any(np.isnan(normalized)):
return None
return normalized
except Exception:
return None
def preprocess_csv_spectra_lower_than_500(wavenumbers, transmittances, method='cubic'):
return preprocess_csv_spectra_higer_500(wavenumbers, transmittances, method=method)
def preprocess_jdx_spectra_higer_500(wavenumbers, intensities, method='cubic'):
try:
processed_y = _resample_and_pad_spectrum(wavenumbers, intensities)
if processed_y is None:
return None
min_val = np.min(processed_y)
max_val = np.max(processed_y)
if max_val > min_val:
norm_spec = (processed_y - min_val) / (max_val - min_val)
else:
norm_spec = np.zeros_like(processed_y)
spec_median = np.median(norm_spec)
if spec_median > 0.45:
spec_clipped = np.clip(norm_spec, 1e-4, 1.0)
abs_spec = -np.log10(spec_clipped)
min_val_abs = np.min(abs_spec)
max_val_abs = np.max(abs_spec)
if max_val_abs > min_val_abs:
final_spec = (abs_spec - min_val_abs) / (max_val_abs - min_val_abs)
else:
final_spec = np.zeros_like(abs_spec)
else:
final_spec = norm_spec
if np.any(np.isnan(final_spec)):
return None
return final_spec
except Exception:
return None
def preprocess_jdx_spectra_lower_500(wavenumbers, intensities, method='cubic'):
return preprocess_jdx_spectra_higer_500(wavenumbers, intensities, method=method)