Skip to content
Merged
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
29 changes: 21 additions & 8 deletions tools/Python/mcrun/mcrun.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from decimal import Decimal, InvalidOperation
from datetime import datetime
import multiprocessing
import re
from mccode import McStas, Process
from optimisation import Scanner, Scanner_split, LinearInterval, MultiInterval, Optimizer

Expand Down Expand Up @@ -131,7 +132,8 @@ def add_mcrun_adv_options(parser):
' 3) Any parameter given as "min:delta:max" is expanded into its '
' own explicit list of equidistant points and may be freely mixed '
' with other, explicitly-listed parameters '
' (e.g. a list of filenames) under -L.')
' (e.g. a list of filenames) under -L.'
' Commas within a list entry must be escaped as "\\,".')

add('-M', '--multi',
action='store_true',
Expand Down Expand Up @@ -536,18 +538,29 @@ def get_parameters(options):
if '=' in param:
key, value = param.split('=', 1)

# Only values made of numbers separated by ":" or "," are scan
# syntax. Other values, like NCrystal cfg-strings (e.g.
# "Ge_sg227.ncmat;dir1=@crys_hkl:5,1,1@lab:0,0,1"), are used as
# they are, except with -L, where they are lists separated by
# commas (commas within an entry must be escaped as "\,"):
numeric = all(is_decimal(p) for p in re.split('[:,]', value) if p)
if not numeric and not options.list:
# Earlier versions of mcrun ignored trailing commas (with a
# warning), so keep doing that to not break existing commands:
if value.endswith(','):
LOG.warning('Ignoring trailing comma(s) in parameter "%s"', key)
value = value.rstrip(',')
fixed_params[key] = value
continue

# "par=a:delta:b" - an equidistant scan specified by its bin
# width (delta) rather than an explicit point count: mcrun
# computes how many points are needed to cover [a, b] in steps
# of (approximately - see rounding below) delta, rather than
# the user needing to work out -N by hand. Checked before the
# comma-based interval parsing below, since a colon can never
# appear in a numeric value/list, so a colon anywhere in the
# value would otherwise unambiguously mean this syntax was
# intended - EXCEPT double-colon syntax from NCrystal-backed
# reflections="stdlib::ZnO_sg186_ZincOxide.ncmat;temp=300K"
# used in context of PowderN. Filter out from the start:
if ':' in value and '::' not in value:
# appear in a numeric value/list:
if ':' in value and numeric:
parts = value.split(':')
if len(parts) != 3:
raise OptionValueError(
Expand Down Expand Up @@ -598,7 +611,7 @@ def get_parameters(options):
key, intervals[key], delta, n_points)
continue

interval = value.split(',')
interval = [v.replace('\\,', ',') for v in re.split(r'(?<!\\),', value)]
# Protect against trailing (or doubled) commas (empty-string entries
n_before = len(interval)
interval = [v for v in interval if v != '']
Expand Down
Loading