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