class StochasticInteractorTestCase(unittest.TestCase): """ Unit testing for StochasticInteractor """ def setUp(self): code = "from blockcanvas.debug.my_operator import add\n"\ "c = add(a,b)" self.block = Block(code) # Context setup self.context = MultiContext(DataContext(name='Data'), {}) self.context['a'] = 1 self.context['b'] = 2 def test_attributes(self): """ Test if creation of attributes is working correctly. """ interactor = StochasticInteractor(context=self.context, block=self.block, distribution='constant', inputs=['b']) self.assertTrue(hasattr(interactor, interactor._input_prefix + 'b')) # Check if the attribute is correct attribute_b = getattr(interactor, interactor._input_prefix + 'b') distribution_b = attribute_b.distribution self.assertEqual(distribution_b.value, self.context['b']) desired = self.context['b'] * numpy.ones(attribute_b.samples) self.assertTrue((desired == distribution_b.values).all()) def test_create_shadows(self): """ Test if shadows are working correctly. """ raise nose.SkipTest("shadows not implemented") interactor = StochasticInteractor(context=self.context, block=self.block, distribution='uniform', inputs=['b']) # Change attributes attribute_b = getattr(interactor, interactor._input_prefix + 'b') distribution_b = attribute_b.distribution distribution_b.low = 20.0 distribution_b.high = 30.0 # Create shadows interactor._execute_button_changed() # Check if the shadows were created correctly. self.assertEqual(len(distribution_b.values), len(self.context.shadows)) # Check if the shadow context gives desired effects. self.block.execute(self.context.shadows[-1]) self.assertEqual(self.context.shadows[-1]['c'], self.context['a'] + self.context.shadows[-1]['b'])
def setUp(self): code = "from blockcanvas.debug.my_operator import add\n"\ "c = add(a,b)" self.block = Block(code) # Context setup self.context = MultiContext(DataContext(name='Data'), {}) self.context['a'] = 1 self.context['b'] = 2
class Interactor(HasPrivateTraits): 'Interacts with a computational model' #--------------------------------------------------------------------------- # Interactor interface: #--------------------------------------------------------------------------- # The persistence id associated with this interactor (empty string means # no persistence): id = Str # Whole block block = Any(Block('')) # Namespace in which block executes context = Any({}) # A dict to hold high and how bounds. Should be of the form {'input_var' : (low, high, format)} ranges = Dict # Subset of the block's inputs to display display_inputs = List(Str) # When block or context change _updated = Event # Cached restricted blocks that need to execute when an input is changed # (one for each of block.inputs) _blocks = Dict # List of actual inputs: _block_inputs = List # Does the interactor need to run any updates? _needs_update = Bool(False) #--------------------------------------------------------------------------- # Interactor interface: #--------------------------------------------------------------------------- def view_items(self): """ Returns the contents of the view based upon the current block. """ visible_inputs = self._block_inputs if visible_inputs is None: return [] # Only display requested inputs (if requested at all) if self.display_inputs != []: visible_inputs = set(visible_inputs) & set(self.display_inputs) items = [] for input in visible_inputs: if input != 'clear': if self.ranges.has_key(input): low, high, format = self.ranges[input] range = RangeEditor(high=high, low=low, format=format) else: range = RangeEditor() items.append( Item(name='var_' + input, label=input, _type='Range', editor=range)) return items #-- Trait Listeners -------------------------------------------------------- def _block_changed(self, old, new): # Get the old and new inputs: old_inputs = new_inputs = [] if old is not None: old_inputs = old.inputs if new is not None: new_inputs = new.inputs # Filter out inputs already bound to arrays in the current context: context = self.context if context is not None: new_inputs = [ input for input in new_inputs if not isinstance(context.get(input), ndarray) ] # Save the list of actual inputs: self._block_inputs = new_inputs # Update the trait definitions as needed: [ self.remove_trait('var_' + input) for input in old_inputs if input not in new_inputs ] [ self.add_trait('var_' + input, Any) for input in new_inputs if input not in old_inputs ] # Cache restricted blocks, one for each input: self._blocks = dict([(input, new.restrict(inputs=[input])) for input in new_inputs]) self._updated = True def _context_changed(self, old, new): self._updated = True def _anytrait_changed(self, name, old, new): if name[:4] == 'var_': name = name[4:] if (not self._no_block_update) and (self.block is not None): if isinstance(old, ArangeGenerator): old.on_trait_change(self._array_changed, 'array', remove=True) if isinstance(new, ArangeGenerator): new.on_trait_change(self._array_changed, 'array') new = new.array self.context[name] = new self._needs_update = True #print "Adding update func" def update_func(): if self._needs_update: self._blocks[name].execute(self.context) self._needs_update = False GUI.invoke_after(10, update_func) # try: # self._blocks[ name ].execute( self.context ) # except: # from traceback import print_exc # print_exc() def _array_changed(self, object, name, old, new): name = object.name[4:] self.context[name] = new try: self._blocks[name].execute(self.context) except: pass #-- Event Interface -------------------------------------------------------- def __updated_fired(self): 'When block or context change' # The block or context changed, so put them back in sync: # - Run the whole block once to initialize the intermediate variables # within the context # Be robust when block and context disagree: block, context = self.block, self.context if (block is not None) and (context is not None): ## Calculate the list of 'real' block inputs: #self._block_inputs = [ # input for input in block.inputs # if isinstance( context.get( input, 0 ), ValidTypes ) #] self._no_block_update = True #for input in block.inputs: for input in self._block_inputs: var_input = 'var_' + input try: value = context[input] setattr(self, var_input, value) except: context[input] = value = 0 setattr(self, var_input, value) self._no_block_update = False try: self.block.execute(context) except: pass # Remove unreferenced values from the data portion of the context: if 'clear' in block.inputs: try: names = context.keys() all = block.inputs + block.outputs for name in names: if name not in all: del context[name] except: pass #-- HasTraits Interface ---------------------------------------------------- def trait_view(self, name=None, view_element=None): 'Returns the View object for the specified name and view_element.' return View( Group(*self.view_items()), id='blockcanvas.numerical_modeling.ui.interactor.Interactor', title='Parametric Controls', width=400, height=200, buttons=menu.NoButtons, resizable=True, handler=InteractorHandler)
class StochasticInteractorTestCase(unittest.TestCase): """ Unit testing for StochasticInteractor """ def setUp(self): code = "from blockcanvas.debug.my_operator import add\n"\ "c = add(a,b)" self.block = Block(code) # Context setup self.context = MultiContext(DataContext(name='Data'), {}) self.context['a'] = 1 self.context['b'] = 2 def test_attributes(self): """ Test if creation of attributes is working correctly. """ interactor = StochasticInteractor(context = self.context, block = self.block, distribution = 'constant', inputs = ['b']) self.assertTrue(hasattr(interactor, interactor._input_prefix + 'b')) # Check if the attribute is correct attribute_b = getattr(interactor, interactor._input_prefix + 'b') distribution_b = attribute_b.distribution self.assertEqual(distribution_b.value, self.context['b']) desired = self.context['b']*numpy.ones(attribute_b.samples) self.assertTrue((desired == distribution_b.values).all()) def test_create_shadows(self): """ Test if shadows are working correctly. """ raise nose.SkipTest("shadows not implemented") interactor = StochasticInteractor(context = self.context, block = self.block, distribution = 'uniform', inputs = ['b']) # Change attributes attribute_b = getattr(interactor, interactor._input_prefix+'b') distribution_b = attribute_b.distribution distribution_b.low = 20.0 distribution_b.high = 30.0 # Create shadows interactor._execute_button_changed() # Check if the shadows were created correctly. self.assertEqual(len(distribution_b.values), len(self.context.shadows)) # Check if the shadow context gives desired effects. self.block.execute(self.context.shadows[-1]) self.assertEqual(self.context.shadows[-1]['c'], self.context['a']+self.context.shadows[-1]['b'])
dist_val = stochastic_item.distribution value_list = [] for attr_name in attr_dict[self.distribution]: value_list.append(getattr(dist_val, attr_name)) range_dict[input_name] = tuple(value_list) return range_dict # Test if __name__ == '__main__': from blockcanvas.numerical_modeling.workflow.api import Block from codetools.contexts.api import DataContext, MultiContext code = "from blockcanvas.debug.my_operator import add, mul\n"\ "c = add(a,b)\n"\ "d = mul(c,2)\n"\ "e = mul(z,3)\n"\ "f = add(d,e)" block = Block(code) context = MultiContext(DataContext(name='Data'), {}) context['a'] = 35 context['b'] = 33 context['z'] = 30 interactor = StochasticInteractor(context=context, block=block, inputs=['b','z'], distribution='gaussian') interactor.edit_traits(kind='livemodal') ### EOF ------------------------------------------------------------------------
class Displayer(HasTraits): """ Displays the results of a computational model. """ #--------------------------------------------------------------------------- # Displayer interface: #--------------------------------------------------------------------------- # The persistence id associated with this displayer (empty string means no # persistence): id = Str # The whole block: block = Any(Block('')) # The namespace in which the block executes: context = Instance(ANumericContext) # Subset of the block's outputs to display display_outputs = List(Str) # Event fired when the block or context changes: _updated = Event #--------------------------------------------------------------------------- # Displayer interface: #--------------------------------------------------------------------------- def view_items(self): """ Returns the contents of the view based upon the current block. """ return [ Item(name='var_' + output, label=output, style='readonly', editor=TextEditor()) for output in self.block.outputs if output in self.display_outputs or self.display_outputs == [] ] #-- Trait Event Handlers --------------------------------------------------- def _block_changed(self, old, new): # Remove the old outputs: if old is not None: [self.remove_trait('var_' + output) for output in old.outputs] # Add the new inputs: if new is not None: [self.add_trait('var_' + output, Any) for output in new.outputs] self._updated = True def _context_changed(self, old, new): self._updated = True def _context_modified_changed_for_context(self, event): if len(event.removed) > 0: block = self.block if block is not None: context = self.context outputs = block.outputs for name in event.removed: if name in outputs: self._set_var(name, context[name]) #-- Event Interface -------------------------------------------------------- def __updated_fired(self): """ Handles the 'block' or 'context' being changed. """ # The block or context changed, so put them back in sync: # - Run the whole block once to initialize the intermediate variables # within the context. # Be robust when block and context disagree: block, context = self.block, self.context if (block is not None) and (context is not None): for output in block.outputs: try: value = context[output] except: context[output] = value = 0.0 self._set_var(output, value) #-- Private Methods -------------------------------------------------------- def _set_var(self, name, value): """ Set a 'legal' value for the specified output variable. """ try: n = len(value) except: n = 0 max_len = 10 if isinstance(value, basestring): max_len = 80 if n > max_len: value = '%s[%d]' % (value.__class__.__name__, n) setattr(self, 'var_' + name, value) #--------------------------------------------------------------------------- # HasTraits interface: #--------------------------------------------------------------------------- def trait_view(self, name=None, view_element=None): return View(Group(*self.view_items()), id='blockcanvas.numerical_modeling.ui.displayer.Displayer', width=250, buttons=menu.NoButtons, resizable=True, handler=DisplayerHandler)