from ._private.exceptions import *
from ._private.forms import digest_to_form
from ._private.parsers import digest_parser
from .forms import dict_translate_quantity
import ast
from typing import Optional
def _find_closing_bracket_position(string):
stack = 0
for i, char in enumerate(string):
if char == '[':
stack += 1
elif char == ']':
stack -= 1
if stack == 0:
return i
raise ValueError # If there is no closing bracket
def _find_closing_parenthesis_position(string):
stack = 0
for i, char in enumerate(string):
if char == '(':
stack += 1
elif char == ')':
stack -= 1
if stack == 0:
return i
raise ValueError # If there is no closing parenthesis
def _parse_with_pint(string: str):
""" Parses a string and returns a pint quantity.
Parameters
----------
string : str
A string quantity.
Returns
-------
pint.quantity
A pint quantity.
"""
# Check if it's a non scalar quantity
if string.startswith('['):
end_list = _find_closing_bracket_position(string)
value_string = string[:(end_list+1)]
unit_string = string[(end_list+1):]
return ast.literal_eval(value_string)*dict_translate_quantity['string']['pint'](unit_string)
elif string.startswith('('):
end_list = _find_closing_parenthesis_position(string)
value_string = string[:(end_list+1)]
unit_string = string[(end_list+1):]
return ast.literal_eval(value_string)*dict_translate_quantity['string']['pint'](unit_string)
else:
return dict_translate_quantity['string']['pint'](string)
[docs]
def parse(string: str, parser: Optional[str]=None, to_form: Optional[str]=None):
""" Parses a string and returns a quantity.
Parameters
----------
string : str
A string quantity.
parser : str
The parser that will be used.
to_form; str, optional
The form of the quantity. Can be pint, openmm.unit or
string.
Returns
-------
QuantityLike
A quantity.
"""
if not isinstance(string, str):
raise BadCallError('string')
parser = digest_parser(parser)
to_form = digest_to_form(to_form)
if parser == 'pint':
if to_form == 'pint':
return _parse_with_pint(string)
elif to_form == 'openmm.unit':
pint_quantity = _parse_with_pint(string)
return dict_translate_quantity['pint']['openmm.unit'](pint_quantity)
elif to_form == 'string':
pint_quantity = _parse_with_pint(string)
return dict_translate_quantity['pint']['string'](pint_quantity)
elif to_form == 'unyt':
pint_quantity = _parse_with_pint(string)
return dict_translate_quantity['pint']['unyt'](pint_quantity)
else:
raise NotImplementedParsingError(parser, to_form)
elif parser == 'openmm.unit':
raise LibraryWithoutParserError('openmm.unit')
elif parser == 'unyt':
raise LibraryWithoutParserError("unyt")
else:
raise NotImplementedParsingError(parser, to_form)