Skip to content

Commit 71efabd

Browse files
committed
fix(topspin): improve parsing of TopSpin parameter files with array support
rewrite the parameter parsing logic to properly handle array parameters declared with (start..end) syntax, fix comment line skipping, and add better value type conversion for both scalar and array values
1 parent 175e86b commit 71efabd

1 file changed

Lines changed: 66 additions & 19 deletions

File tree

‎nmrkit/io/formats/topspin.py‎

Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -166,27 +166,74 @@ def _parse_acqus_file(self, filepath: str) -> Dict[str, any]:
166166
params = {}
167167

168168
with open(filepath, "r") as f:
169-
content = f.read()
170-
171-
# Parse parameters using regex
172-
parameter_pattern = r"\$(\w+)=(.*)\n"
173-
matches = re.findall(parameter_pattern, content)
174-
175-
for key, value in matches:
176-
# Clean up value
177-
value = value.strip()
178-
179-
# Try to convert to appropriate type
180-
try:
181-
# Try integer first
182-
params[key] = int(value)
183-
except ValueError:
169+
lines = f.readlines()
170+
171+
i = 0
172+
while i < len(lines):
173+
line = lines[i].strip()
174+
175+
# Skip comment lines and non-parameter lines
176+
if not line.startswith("##$"):
177+
i += 1
178+
continue
179+
180+
# Parse parameter name and value
181+
match = re.match(r"##\$(\w+)=(.*)", line)
182+
if not match:
183+
i += 1
184+
continue
185+
186+
key = match.group(1)
187+
value = match.group(2).strip()
188+
189+
# Check if this is an array declaration (e.g., "(0..63)")
190+
array_match = re.match(r"\((\d+)\.\.(\d+)\)", value)
191+
if array_match:
192+
# This is an array, read subsequent lines for array values
193+
start_idx = int(array_match.group(1))
194+
end_idx = int(array_match.group(2))
195+
array_size = end_idx - start_idx + 1
196+
197+
array_values = []
198+
i += 1
199+
200+
# Read subsequent lines until we hit another parameter or run out of values
201+
while i < len(lines) and len(array_values) < array_size:
202+
next_line = lines[i].strip()
203+
if next_line.startswith("##"):
204+
break
205+
206+
# Parse space-separated values
207+
values = next_line.split()
208+
for val in values:
209+
if len(array_values) < array_size:
210+
# Try to convert to appropriate type
211+
try:
212+
array_values.append(int(val))
213+
except ValueError:
214+
try:
215+
array_values.append(float(val))
216+
except ValueError:
217+
array_values.append(val)
218+
i += 1
219+
220+
params[key] = array_values
221+
else:
222+
# Single value parameter
223+
# Clean up value (remove angle brackets for string values)
224+
if value.startswith("<") and value.endswith(">"):
225+
value = value[1:-1]
226+
227+
# Try to convert to appropriate type
184228
try:
185-
# Try float next
186-
params[key] = float(value)
229+
params[key] = int(value)
187230
except ValueError:
188-
# Leave as string if conversion fails
189-
params[key] = value
231+
try:
232+
params[key] = float(value)
233+
except ValueError:
234+
params[key] = value
235+
236+
i += 1
190237

191238
return params
192239

0 commit comments

Comments
 (0)