64
64
the one to be used next for recycling.
66
66
from __future__ import division, with_statement
70
70
# In this module we bring together scopes, settings and calculations.
71
71
# Most of the classes are 'Defns' with their superclasses in scope.py.
72
72
# These supply a makeCells() method which instantiates 'Cell'
73
73
# classes from calculation.py
75
from calculation import EvaluatedCell, OptPar, LogOptPar, ConstCell, \
78
from scope import _NonLeafDefn, _LeafDefn, _Defn, _ParameterController
80
from setting import Var, ConstVal
75
from .calculation import EvaluatedCell, OptPar, LogOptPar, ConstCell
76
from .scope import _NonLeafDefn, _LeafDefn, _Defn, ParameterController
77
from .setting import Var, ConstVal
82
79
from cogent.util.dict_array import DictArrayTemplate
83
80
from cogent.maths.stats.distribution import chdtri
84
81
from cogent.util import parallel
86
LOG = logging.getLogger('cogent')
88
83
__author__ = "Peter Maxwell"
89
84
__copyright__ = "Copyright 2007-2009, The Cogent Project"
90
85
__credits__ = ["Peter Maxwell", "Gavin Huttley"]
91
86
__license__ = "GPL"
93
88
__maintainer__ = "Peter Maxwell"
94
89
__email__ = "pm67nz@gmail.com"
95
90
__status__ = "Production"
97
def theOneItemIn(items):
98
assert len(items) == 1, items
102
class ParameterController(_ParameterController):
104
def assignAll(self, par_name, scope_spec=None, value=None,
105
lower=None, upper=None, const=None, independent=None):
107
PC = self.defn_for[par_name]
108
if not isinstance(PC, _LeafDefn):
109
args = ' and '.join(['"%s"' % a.name for a in PC.args])
110
msg = '"%s" is not settable as it is derived from %s.' % (
112
raise ValueError(msg)
115
const = PC.const_by_default
117
for scope in PC.interpretScopes(
118
independent=independent, **(scope_spec or {})):
120
values = PC.getAllDefaultValues(scope)
124
s_value = sum(values) / len(values)
126
if not numpy.all(value==s_value):
127
LOG.warning("Used mean of '%s' values" % par_name)
130
s_value = PC.unwrapValue(value)
132
setting = ConstVal(s_value)
134
(s_lower, s_upper) = PC.getCurrentBounds(scope)
135
if lower is not None: s_lower = lower
136
if upper is not None: s_upper = upper
137
setting = Var((s_lower, s_value, s_upper))
138
settings.append((scope, setting))
142
def measureEvalsPerSecond(self):
143
return self.makeCalculator().measureEvalsPerSecond()
145
def setupParallelContext(self, parallel_split=None):
146
comm = parallel.getCommunicator()
147
cpu_count = comm.Get_size()
148
if parallel_split is None:
149
parallel_split = cpu_count
150
with parallel.mpi_split(parallel_split) as parallel_context:
151
self.remaining_parallel_context = parallel.getCommunicator()
152
if 'parallel_context' in self.defn_for:
154
'parallel_context', value=parallel_context, const=True)
155
self.overall_parallel_context = comm
157
def makeCalculator(self, calculatorClass=None, variable=None, **kw):
160
for defn in self.defns:
162
(newcells, outputs) = defn.makeCells(input_soup, variable)
163
cells.extend(newcells)
164
input_soup[id(defn)] = outputs
165
if calculatorClass is None:
166
calculatorClass = Calculator
167
kw['overall_parallel_context'] = self.overall_parallel_context
168
kw['remaining_parallel_context'] = self.remaining_parallel_context
169
return calculatorClass(cells, input_soup, **kw)
171
def updateFromCalculator(self, calc):
173
for defn in self.defn_for.values():
174
if isinstance(defn, _LeafDefn):
175
defn.updateFromCalculator(calc)
179
def getNumFreeParams(self):
180
return sum(defn.getNumFreeParams() for defn in self.defns if isinstance(defn, _LeafDefn))
183
93
class CalculationDefn(_NonLeafDefn):
184
94
"""Defn for a derived value. In most cases use CalcDefn instead