48 from fireworks
import Firework, Workflow, FWAction, FireTaskBase, ScriptTask
49 from fireworks.utilities.fw_serializers
import FWSerializable, \
50 recursive_serialize, recursive_deserialize, serialize_fw
51 import fireworks.utilities.fw_serializers
as fw_serializers
52 from fireworks.utilities.fw_utilities
import explicit_serialize
53 from fireworks.utilities.fw_serializers
import load_object
54 from collections
import defaultdict
55 from rpy2.robjects.packages
import importr
56 import rpy2.robjects
as robjects
57 import rpy2.rinterface
as rinterface
58 from rpy2.robjects.vectors
import FloatVector
59 from numpy
import array
60 from numpy.random
import choice, seed
61 from blessings
import Terminal
65 nlmrt = importr(
'nlmrt')
84 class InitialisationStrategy(defaultdict, FWSerializable):
87 def __init__(self, *args, **kwargs):
88 dict.__init__(self, *args, **kwargs)
95 raise NotImplementedError(
'newPoints not implemented!')
111 wf = model.exactTasks(p)
113 model.parameterFittingStrategy().
workflow(model),
118 elif not len(p)
and len(model.substituteModels):
120 for sm
in model.substituteModels:
122 sm.initialisationStrategy().
workflow(sm),
140 @recursive_deserialize
143 def from_dict(cls, m_dict):
148 return '<{}>:{}'.format(self.fw_name, dict(self))
159 class OutOfBoundsStrategy(defaultdict, FWSerializable):
162 def __init__(self, *args, **kwargs):
163 dict.__init__(self, *args, **kwargs)
168 raise NotImplementedError(
'newPoints not implemented!')
176 def workflow(self, model, **kwargs):
177 wf = model.exactTasks(self.newPoints(model, **kwargs))
179 model.parameterFittingStrategy().
workflow(model),
192 @recursive_deserialize
193 def from_dict(cls, m_dict):
198 return '<{}>:{}'.format(self.fw_name, dict(self))
203 class ImproveErrorStrategy(defaultdict, FWSerializable):
204 def __init__(self, *args, **kwargs):
205 dict.__init__(self, *args, **kwargs)
208 def workflow(self, model, **kwargs):
209 wf = model.exactTasks(self.newPoints(model))
211 model.parameterFittingStrategy().
workflow(model),
224 @recursive_deserialize
225 def from_dict(cls, m_dict):
230 return '<{}>:{}'.format(self.fw_name, dict(self))
235 class ParameterFittingStrategy(dict, FWSerializable):
236 def __init__(self, *args, **kwargs):
237 dict.__init__(self, *args, **kwargs)
241 def newPointsFWAction(self, model, **kwargs):
242 raise NotImplementedError(
'newPointsFWAction not implemented!')
248 ParameterFitting(surrogateModelId=model._id),
249 name=
'parameter fitting' 255 def errorTest(model, parameters, testIndices):
257 def fitData(testIndices):
262 cModel = modena.libmodena.modena_model_t(
264 parameters=list(parameters)
268 abs(i)
for i
in model.error(
270 idxGenerator=fitData(testPoint),
280 def __init__(self, *args, **kwargs):
284 def function(parameters):
286 def fitData(n, testPoint):
288 if i
not in testPoint:
292 cModel = modena.libmodena.modena_model_t(
294 parameters=list(parameters)
301 idxGenerator=fitData(model.nSamples, self.
testPoint),
315 @recursive_deserialize
316 def from_dict(cls, m_dict):
321 return '<{}>:{}'.format(self.fw_name, dict(self))
329 raise NotImplementedError(
'newPoints not implemented!')
332 def samplePoints(self, model, sampleRange, nPoints):
334 points = array(lhs.randomLHS(nPoints, len(sampleRange))).tolist()
341 (sr[key][
'max'] - sr[key][
'min']) * points[i][j]
342 for i
in xrange(nPoints)
343 ]
for j, key
in enumerate(sr)
353 def __init__(self, *args, **kwargs):
354 InitialisationStrategy.__init__(self, *args, **kwargs)
358 return self[
'initialPoints']
367 def __init__(self, *args, **kwargs):
368 InitialisationStrategy.__init__(self, *args, **kwargs)
372 return self[
'initialData']
377 et = load_object({
'_fw_name':
'{{modena.Strategy.InitialDataPoints}}'})
379 points = self.newPoints()
381 e = six.next(six.itervalues(points))
382 p = { k:[0]*len(points[k])
for k
in points }
383 for i
in xrange(len(e)):
385 p[k][i] = points[k][i]
389 t[
'indices'] = indices
390 t[
'modelId'] = self._id
392 wf = Workflow( [fw], name=
'initialising to dataset')
395 model.parameterFittingStrategy().
workflow(model),
414 def __init__(self, *args, **kwargs):
415 OutOfBoundsStrategy.__init__(self, *args, **kwargs)
418 def newPoints(self, model, **kwargs):
420 sampleRange, limitPoint = model.extendedRange(kwargs[
'outsidePoint'])
421 sp = self.samplePoints(model, sampleRange, self[
'nNewPoints']-1)
422 return { k: v + [limitPoint[k]]
for k, v
in sp.iteritems() }
429 def __init__(self, *args, **kwargs):
430 ImproveErrorStrategy.__init__(self, *args, **kwargs)
438 def newPoints(self, model):
443 'min': min(model.fitData[k]),
444 'max': max(model.fitData[k])
445 }
for k
in model.inputs.keys()
448 return self.samplePoints(model, sampleRange, self[
'nNewPoints'])
459 def __init__(self, *args, **kwargs):
470 ParameterFittingStrategy.__init__(self, *args, **kwargs)
473 def newPointsFWAction(self, model, **kwargs):
484 size=max(1, self[
'testDataPercentage']*model.nSamples),
492 def fitData(n, testIndices):
494 if i
not in testIndices:
498 cModel = modena.libmodena.modena_model_t(
500 parameters=list(parameters)
507 idxGenerator=fitData(model.nSamples, testIndices),
516 def errorTest(parameters):
518 def fitData(testIndices):
519 for i
in testIndices:
523 cModel = modena.libmodena.modena_model_t(
525 parameters=list(parameters)
529 abs(i)
for i
in model.error(
531 idxGenerator=fitData(testIndices),
538 new_parameters = model.parameters
539 if not len(new_parameters):
540 new_parameters = [
None] * len(model.surrogateFunction.parameters)
541 for k, v
in model.surrogateFunction.parameters.iteritems():
542 new_parameters[v.argPos] = (v.min + v.max)/2
545 R_par = FloatVector(new_parameters)
546 R_res = rinterface.rternalize(errorFit)
548 max_parameters = [
None]*len(new_parameters)
549 min_parameters = [
None]*len(new_parameters)
550 for k, v
in model.surrogateFunction.parameters.iteritems():
551 min_parameters[v.argPos] = v.min
552 max_parameters[v.argPos] = v.max
558 jacfn=rinterface.NULL,
559 trace=rinterface.FALSE,
560 lower=FloatVector(min_parameters),
561 upper=FloatVector(max_parameters),
562 maskidx=rinterface.NULL
568 nlfb_coeffs = nlfb[nlfb.names.index(
'coefficients')]
569 nlfb_ssqres = nlfb[nlfb.names.index(
'ssquares')]
570 new_parameters = list(nlfb_coeffs)
576 maxError = errorTest(new_parameters)
578 print 'Maximum Error = %s' % maxError
579 if maxError > self[
'maxError']:
581 'Parameters ' + term.red +
'not' + term.normal
582 +
' valid, adding samples.' 585 'current parameters = [%s]' %
', '.join(
586 '%g' % k
for k
in new_parameters
594 detours=self[
'improveErrorStrategy'].
workflow(model)
599 'old parameters = [%s]' %
', '.join(
600 '%g' % k
for k
in model.parameters
604 'new parameters = [%s]' %
', '.join(
605 '%g' % k
for k
in new_parameters
612 model.parameters = new_parameters
631 def __init__(self, *args, **kwargs):
644 ParameterFittingStrategy.__init__(self, *args, **kwargs)
647 def newPointsFWAction(self, model, **kwargs):
649 new_parameters = model.parameters
650 if not len(new_parameters):
651 new_parameters = [
None] * len(model.surrogateFunction.parameters)
652 for k, v
in model.surrogateFunction.parameters.iteritems():
653 new_parameters[v.argPos] = (v.min + v.max)/2
655 max_parameters = [
None]*len(new_parameters)
656 min_parameters = [
None]*len(new_parameters)
657 for k, v
in model.surrogateFunction.parameters.iteritems():
658 min_parameters[v.argPos] = v.min
659 max_parameters[v.argPos] = v.max
663 for i
in xrange(model.nSamples):
667 def errorTest(parameters):
669 def fitData(testIndices):
674 cModel = modena.libmodena.modena_model_t(
676 parameters=list(parameters)
680 abs(i)
for i
in model.error(
682 idxGenerator=fitData(testPoint),
691 def fitData(n, testPoint):
693 if i
not in testPoint:
697 cModel = modena.libmodena.modena_model_t(
699 parameters=list(parameters)
706 idxGenerator=fitData(model.nSamples, testPoint),
714 R_res = rinterface.rternalize(errorFit)
715 R_par = FloatVector(new_parameters)
721 jacfn=rinterface.NULL,
722 trace=rinterface.FALSE,
723 lower=FloatVector(min_parameters),
724 upper=FloatVector(max_parameters),
725 maskidx=rinterface.NULL
728 parameterError = errorTest(nlfb[nlfb.names.index(
'coefficients')])
729 if parameterError < maxError:
730 maxError = parameterError
731 new_parameters = list(nlfb[nlfb.names.index(
'coefficients')])
736 nlfb_coeffs = coeffs[nlfb.names.index(
'coefficients')]
737 nlfb_ssqres = coeffs[nlfb.names.index(
'ssquares')]
739 print 'Maximum Error = %s' % maxError
741 'old parameters = [%s]' %
', '.join(
742 '%g' % k
for k
in model.parameters
746 'new parameters = [%s]' %
', '.join(
747 '%g' % k
for k
in new_parameters
754 model.parameters = new_parameters
776 def __init__(self, *args, **kwargs):
777 FireTaskBase.__init__(self, *args, **kwargs)
779 if kwargs.has_key(
'surrogateModel'):
780 if isinstance(kwargs[
'surrogateModel'], modena.SurrogateModel):
781 self[
'surrogateModelId'] = kwargs[
'surrogateModel'][
'_id']
782 del self[
'surrogateModel']
785 def run_task(self, fw_spec):
787 print term.cyan +
'Performing initialisation' + term.normal
788 model = modena.SurrogateModel.load(self[
'surrogateModelId'])
790 detours=model.initialisationStrategy().
workflow(model)
794 traceback.print_exc()
795 return FWAction(defuse_workflow=
True)
807 def __init__(self, *args, **kwargs):
808 FireTaskBase.__init__(self, *args, **kwargs)
810 if kwargs.has_key(
'surrogateModel'):
811 if isinstance(kwargs[
'surrogateModel'], modena.SurrogateModel):
812 self[
'surrogateModelId'] = kwargs[
'surrogateModel'][
'_id']
813 del self[
'surrogateModel']
816 def run_task(self, fw_spec):
818 model = modena.SurrogateModel.load(self[
'surrogateModelId'])
821 +
'Performing parameter fitting for model %s' % model._id
824 model.updateFitDataFromFwSpec(fw_spec)
825 return model.parameterFittingStrategy().newPointsFWAction(model)
826 except Exception
as e:
828 traceback.print_exc()
829 return FWAction(defuse_workflow=
True)
848 def run_task(self, fw_spec):
849 return FWAction(mod_spec=[{
'_push': self[
'point']}])
856 class ParametersNotValid(Exception):
874 def executeAndCatchExceptions(self, op, text):
878 except OutOfBounds
as e:
882 +
'%s out-of-bounds, executing outOfBoundsStrategy for model %s' 889 wf = model.outOfBoundsStrategy().
workflow(
891 outsidePoint=model.outsidePoint
894 Workflow([Firework(self)], name=
'original task'),
899 except ParametersNotValid
as e:
903 +
'%s is not initialised, ' % text
904 +
'executing initialisationStrategy for model %s' % model._id
910 wf = model.initialisationStrategy().
workflow(model)
912 Workflow([Firework(self)], name=
'original task'),
921 def run_task(self, fw_spec):
925 +
'Performing exact simulation (microscopic code recipe) for model ' 934 +
'point = {%s}' %
', '.join(
935 '%s: %g' % (k, v)
for (k, v)
in p.iteritems()
940 model = modena.SurrogateModel.load(self[
'modelId'])
942 for m
in model.substituteModels:
943 self.executeAndCatchExceptions(
944 lambda: p.update(m.callModel(p)),
948 if not len(p) == len(oldP):
951 +
'values added by substitution = {%s}' %
', '.join(
952 '%s: %g' % (k, v)
for (k, v)
in p.iteritems()
958 self.executeAndCatchExceptions(
959 lambda: self.task(fw_spec),
962 return FWAction(mod_spec=[{
'_push': self[
'point']}])
964 except ModifyWorkflow
as e:
967 except Exception
as e:
968 print(term.red + e.args[0] + term.normal)
970 traceback.print_exc()
971 return FWAction(defuse_workflow=
True)
976 def handleReturnCode(self, returnCode):
980 print(term.red +
'return code = %i' % returnCode + term.normal)
982 if returnCode == 200:
990 model = modena.SurrogateModel.loadFailing()
993 'Exact task raised OutOfBounds signal, ' 994 +
'but failing model could not be determined',
998 'Exact task raised OutOfBounds signal',
1003 elif returnCode == 201:
1005 model = modena.SurrogateModel.loadFromModule()
1008 'Exact task raised LoadFromModule signal, ' 1009 +
'but failing model could not be determined',
1013 'Exact task raised LoadFromModule signal',
1018 elif returnCode == 202:
1020 model = modena.SurrogateModel.loadParametersNotValid()
1023 'Exact task raised ParametersNotValid, ' 1024 +
'but failing model could not be determined',
1028 'Exact task raised ParametersNotValid',
1033 elif returnCode > 0:
1035 'An unknow error occurred calling exact simulation',
1047 required_params = [
'script']
1052 def run_task(self, fw_spec):
1056 +
'Performing backward mapping simulation ' 1057 +
'(macroscopic code recipe)' 1060 self.executeAndCatchExceptions(
1061 lambda: self.task(fw_spec),
1064 print(term.green +
'Success - We are done' + term.normal)
1066 except ModifyWorkflow
as e:
1069 except Exception
as e:
1070 print(term.red + e.args[0] + term.normal)
1072 traceback.print_exc()
1073 return FWAction(defuse_workflow=
True)
1078 def task(self, fw_spec):
1080 self[
'defuse_bad_rc'] =
True 1083 ret = ScriptTask.run_task(self, fw_spec)
1084 self.handleReturnCode(ret.stored_data[
'returncode'])
Performs parameter fitting of a set of samples and returns the parameters that yield the smallest err...
Parent class for the initialisation strategies.
Class for extending the design space using stochastic sampling.
Class for initialisation of a surrogate model by fitting it to user-specified points.
A FireTask that performs parameter fitting.
Parameter fitting class, non-linear least squares regression.
Base class for strategies 'fixing' the error of a surrogate model.
A FireTask that starts a macroscopic code and catches its return code.
Parent class for the out of bounds strategies.
Empty initialisation strategy, used by Forward Mapping Models.
Base class for Sampling strategies (DoE).
A FireTask that performs the initialisation.
Design of experiments class, Monte Carlo sampling.
Pushes all "points" to the next firework.
Class initialising a SurrogateModel given a dataset of input-output relations.
Base Class for creating parameter fitting strategies.