Source code for opatio.convert.opal

import numpy as np
import re
from opatio import OPAT
import os

[docs] def get_OPAL_I_log_R() -> np.ndarray: """ Generate the target log(R) values for OPAL type I files. Returns ------- np.ndarray Array of log(R) values ranging from -8.0 to 1.0 with a step of 0.5. Examples -------- >>> logR = get_OPAL_I_log_R() >>> print(logR) [-8. -7.5 -7. ... 0.5 1. ] """ targetLogR = np.arange(-8.0, 1.5, 0.5) return targetLogR
[docs] def get_OPAL_I_log_T() -> np.ndarray: """ Generate the target log(T) values for OPAL type I files. The spacing is non-uniform and is divided into three sections: - Section A: 3.75 to 6.0 with a step of 0.05 - Section B: 6.0 to 8.1 with a step of 0.1 - Section C: 8.1 to 8.8 with a step of 0.2 Returns ------- np.ndarray Array of log(T) values. Examples -------- >>> logT = get_OPAL_I_log_T() >>> print(logT[:5]) [3.75 3.8 3.85 3.9 3.95] """ targetLogT_A = np.arange(3.75, 6.0, 0.05) targetLogT_B = np.arange(6.0, 8.1, 0.1) targetLogT_C = np.arange(8.1, 8.8, 0.2) targetLogT = np.concatenate(( targetLogT_A, targetLogT_B, targetLogT_C ), axis=None) return targetLogT
[docs] def parse_OPAL_I(path: str) -> np.ndarray: """ Parse OPAL type I data from a file. Parameters ---------- path : str Path to the OPAL I file. Returns ------- tuple A tuple containing: - logR (np.ndarray): Array of log(R) values. - logT (np.ndarray): Array of log(T) values. - p (np.ndarray): Parsed intensity data. Raises ------ ValueError If the file does not contain the expected table structure. Examples -------- >>> logR, logT, p = parse_OPAL_I("path/to/opal_file.txt") >>> print(logR.shape, logT.shape, p.shape) (19,) (81,) (n_tables, 81, 19) """ with open(path) as f: contents = f.read().split('\n') sIndex = contents.index('************************************ Tables ************************************') ident = re.compile(r"TABLE\s+#(?:\s+)?\d+\s+\d+\s+X=\d\.\d+\s+Y=\d\.\d+\s+Z=\d\.\d+(?:\s+)?dX1=\d\.\d+\s+dX2=\d\.\d+") I = filter(lambda x: bool(re.match(ident, x[1])) and x[0] > sIndex+1, enumerate(contents)) I = list(I) parsedTables = list(map(lambda x: [[float(z) for z in y.split()[1:]] for y in x], map(lambda x: contents[x[0]+6:x[0]+76], I))) paddedParsed = [list(map(lambda x: np.pad(x, (0, 19-len(x)), mode='constant', constant_values=(1,np.nan)), j)) for j in parsedTables] p = np.array(paddedParsed) return get_OPAL_I_log_R(), get_OPAL_I_log_T(), p
[docs] def load_opat1_as_opat(path: str) -> OPAT: compFind = re.compile(r"TABLE #\s*(\d+)\s+\d+\s+X=(\d\.\d+)\s+Y=(\d\.\d+)\s+Z=(\d\.\d+).+\n") with open(path, 'r') as f: contents = f.read() compMap = dict() matches = re.finditer(compFind, contents) for match in matches: e = match.groups() compMap[int(e[0]) - 1] = (float(e[1]), float(e[2]), float(e[3])) logR, logT, I = parse_OPAL_I(path) # Create the OPAT object opat = OPAT() opat.set_comment(f"Converted from OPAL I {path}") opat.set_source(path) for table, (tabID, (X, Y, Z)) in zip(I, compMap.items()): tab2Add = table.copy() tab2Add[tab2Add == 9.999] = np.nan opat.add_table( (X, Z), "data", logR, logT, tab2Add, columnName="logR", rowName="logT", ) return opat
[docs] def OPALI_2_OPAT(inPath: str, outPath: str, saveAsASCII: bool = False) -> None: """ Convert OPAL type I files to OPAT format. Parameters ---------- inPath : str Path to the input OPAL type I file. outPath : str Path to save the converted OPAT file. saveAsASCII : bool, optional If True, also save the OPAT file as an ASCII file (default is False). Returns ------- None Examples -------- >>> OPALI_2_OPAT("path/to/opal_file.txt", "path/to/output.opat") >>> OPALI_2_OPAT("path/to/opal_file.txt", "path/to/output.opat", saveAsASCII=True) """ opat = load_opat1_as_opat(inPath) # Save the OPAT file opat.save(outPath) if saveAsASCII: opat.save_as_ascii(os.path.splitext(outPath)[0] + ".dat")