1 |
# |
2 |
# Handler for processing dimensioned value inputs |
3 |
# |
4 |
|
5 |
import re |
6 |
import ascend |
7 |
|
8 |
# RE for units matching |
9 |
UNITS_RE = re.compile("([-+]?(\d+(\.\d*)?|\d*\.d+)([eE][-+]?\d+)?)\s*(.*)"); |
10 |
|
11 |
class InputError(Exception): |
12 |
def __init__(self,msg): |
13 |
self.msg = msg; |
14 |
def __str__(self): |
15 |
return "Input Error: %s" % self.msg; |
16 |
|
17 |
class RealAtomEntry: |
18 |
def __init__(self,instance,newtext): |
19 |
self.instance = instance; |
20 |
self.newtext = newtext; |
21 |
self.units = None; # the string value of the entered units |
22 |
self.value = None; |
23 |
|
24 |
def checkEntry(self): |
25 |
_instdim = self.instance.getDimensions(); |
26 |
_insttype = self.instance.getType() |
27 |
|
28 |
try: |
29 |
# match a float with option text afterwards, optionally separated by whitespace |
30 |
_match = re.match(UNITS_RE,self.newtext) |
31 |
if not _match: |
32 |
raise InputError("Not a valid value-and-optional-units") |
33 |
|
34 |
_val = _match.group(1) # the numerical part of the input |
35 |
self.units = _match.group(5) # the text entered for units |
36 |
#_val, _units = re.split("[ \t]+",newtext,2); |
37 |
except RuntimeError: |
38 |
raise InputError("Unable to split value and units") |
39 |
|
40 |
print "val = ",_val |
41 |
print "units = ",self.units |
42 |
|
43 |
# parse the units, throw an error if no good |
44 |
try: |
45 |
_val = float(_val) |
46 |
except RuntimeError: |
47 |
raise InputError("Unable to convert number part '%s' to float" % _val) |
48 |
|
49 |
# check the units |
50 |
if self.units.strip() == "": |
51 |
# if no units entered, assume the 'preferred' units |
52 |
_u = _insttype.getPreferredUnits() |
53 |
if _u == None: |
54 |
# no preferred units for this type, so assume default units |
55 |
_u = _instdim.getDefaultUnits() |
56 |
print "Assuming units '%s'" % _u.getName().toString() |
57 |
else: |
58 |
try: |
59 |
_u = ascend.Units(self.units) |
60 |
print "Parsed units '%s'" % self.units |
61 |
except RuntimeError: |
62 |
raise InputError("Unrecognisable units '%s'" % self.units) |
63 |
|
64 |
if _instdim != _u.getDimensions(): |
65 |
|
66 |
if _u.getDimensions().isDimensionless(): |
67 |
self.units = "[dimensionless]" |
68 |
|
69 |
_my_dims = _instdim.getDefaultUnits() |
70 |
if _instdim.isDimensionless(): |
71 |
_my_dims = "[dimensionless]" |
72 |
|
73 |
raise InputError("Incompatible units '%s' (must fit with '%s')" |
74 |
% (self.units, _my_dims.getName().toString()) ) |
75 |
|
76 |
_conv = float(_u.getConversion()) |
77 |
# self.reporter.reportNote("Converting: multiplying '%s %s' by factor %s to get SI units" % (_val, _units, _conv) ) |
78 |
self.value = _val * _conv; |
79 |
|
80 |
print "Setting '%s' to '%f'" % (self.instance.getName().toString(), self.value) |
81 |
|
82 |
def setValue(self): |
83 |
if self.instance.getType().isRefinedSolverVar(): |
84 |
# for solver vars, set the 'fixed' flag as well |
85 |
self.instance.setFixedValue(self.value) |
86 |
else: |
87 |
self.instance.setRealValue(self.value) |
88 |
|
89 |
def getValue(self): |
90 |
return self.value |
91 |
|
92 |
def exportPreferredUnits(self,prefs): |
93 |
_typename = str( self.instance.getType().getName() ) |
94 |
_dim = self.instance.getDimensions() |
95 |
|
96 |
if self.units.strip() != "" and not _dim.isDimensionless(): |
97 |
prefs.setPreferredUnits(_typename,_units); |
98 |
|
99 |
|