1
2 """Data structure to do some calculations on the results from
3 SpreadSheetData-methods metrics and compare that are organized in 2
4 dimensions"""
5
6 from PyFoam.Basics.TableData import TableData
7 from PyFoam.Error import error
8
9 from math import *
10
12 """Oranize statistics about data in 2D-Tables and do basic
13 calculations on it"""
14
15 - def __init__(self,metrics,
16 compare=None,
17 small=1e-10,
18 noStrings=False,
19 failureValue=None):
20 """
21 @param metrics: metrics of the data
22 @param compare: metrics of the comparsion with another data-set
23 @param small: the value that is considered to be close to 0
24 @param noStrings: only put numbers into the tables
25 @param failureValue: the value to use if an evaluation fails
26 """
27 self.__metrics=metrics
28 self.__compare=compare
29 self.small=small
30 self.noStrings=noStrings
31 self.failureValue=failureValue
32
34 """Return a tuple with the names of the rows and the
35 columns. Assumes that the names for the first data-set are
36 valid for all"""
37 colNames=self.__metrics.keys()
38 rowNames=self.__metrics[colNames[0]].keys()
39
40 return rowNames,colNames
41
43 """Create an empty table to fill the data in"""
44 r,c=self._getLabels()
45 return TableData(r,c)
46
48 """Extract data and fill it into a data-table
49 @param name: name of the entry that should be got
50 @param data: the dataset. If unset then self.__metrics is used"""
51 if data==None:
52 data=self.__metrics
53
54 tab=self._makeEmptyTable()
55 row,col=self._getLabels()
56 for r in row:
57 for c in col:
58 tab[(r,c)]=data[c][r][name]
59
60 return tab
61
63 "Valid data names"
64 row,col=self._getLabels()
65 return self.__metrics[col[0]][row[0]].keys()
66
68 """Get a separate Data2DStatistics with the compare-data (if
69 present)"""
70 if self.__compare==None:
71 error("No compare data present")
72 return Data2DStatistics(self.__compare)
73
76
77 - def func(self,func,val):
78 """Evaluate a function on the data
79 @param func: either a callable function or a string that evaluates to a callable
80 @param val: name of the data value to use"""
81 if callable(func):
82 f=func
83 elif type(func)==str:
84 f=eval(func)
85 if not callable(f):
86 error(func,"does not evaluate to a callable")
87 else:
88 error(func,"is neither callable nor a string")
89
90 tab=self._makeEmptyTable()
91
92 row,col=self._getLabels()
93 data=self[val]
94
95 for r in row:
96 for c in col:
97 tab[(r,c)]=f(data[(r,c)])
98
99 return tab
100
102 """Return a table with the ranges of the data"""
103 minD=self._extractTable("min")
104 maxD=self._extractTable("max")
105 tab=self._makeEmptyTable()
106
107 row,col=self._getLabels()
108 for r in row:
109 for c in col:
110 tab[(r,c)]=(minD[(r,c)],maxD[(r,c)])
111
112 return tab
113
115 """Return a table with the relative error"""
116 dataRange=self.range()
117 if self.__compare==None:
118 error("Need comparison data for relative error")
119
120 maxError=self._extractTable("max",self.__compare)
121 rErr=self._makeEmptyTable()
122
123 row,col=self._getLabels()
124 for r in row:
125 for c in col:
126 rng=(lambda r:r[1]-r[0])(dataRange[(r,c)])
127 mx=maxError[(r,c)]
128 if rng>self.small:
129 try:
130 rErr[(r,c)]=mx/rng
131 except TypeError,e:
132 rErr[(r,c)]=self.failureValue
133 if self.failureValue==None:
134 raise e
135 elif mx>self.small:
136 if self.noStrings:
137 rErr[(r,c)]=0.
138 else:
139 rErr[(r,c)]="constant (%g)" % mx
140 else:
141 if self.noStrings:
142 rErr[(r,c)]=0.
143 else:
144 rErr[(r,c)]="constant =="
145
146 return rErr
147