def bleedthrough_traits_view(self): return View(HGroup(Item('channel', style = 'readonly'), Item('file', show_label = False), show_labels = False), handler = self)
class NMR(Pulsed): mwA_frequency = Range(low=1, high=20e9, value=2.87405e+09, desc='microwave A frequency', label='MW frequency [Hz]', mode='text', auto_set=False, enter_set=True) mwA_power = Range(low=-100., high=25., value=-19, desc='microwave A power', label='MW power [dBm]', mode='text', auto_set=False, enter_set=True) t_pi_A = Range(low=1., high=100000., value=1040., desc='length of pi pulse of MW A[ns]', label='pi [ns]', mode='text', auto_set=False, enter_set=True) mwB_frequency = Range(low=1, high=20e9, value=2.880965e9, desc='microwave B frequency', label='MW frequency [Hz]', mode='text', auto_set=False, enter_set=True) mwB_power = Range(low=-100., high=25., value=-19, desc='microwave B power', label='MW power [dBm]', mode='text', auto_set=False, enter_set=True) t_pi_B = Range(low=1., high=100000., value=1020., desc='length of pi pulse of MW B[ns]', label='pi [ns]', mode='text', auto_set=False, enter_set=True) rf_power = Range(low=-130., high=25., value=-20, desc='RF power', label='RF power [dBm]', mode='text', auto_set=False, enter_set=True) rf_begin = Range(low=1, high=200e6, value=2.4e6, desc='Start Frequency [Hz]', label='RF Begin [Hz]', mode='text', auto_set=False, enter_set=True) rf_end = Range(low=1, high=200e6, value=2.7e6, desc='Stop Frequency [Hz]', label='RF End [Hz]', mode='text', auto_set=False, enter_set=True) rf_delta = Range(low=1e-3, high=200e6, value=2.0e3, desc='frequency step [Hz]', label='Delta [Hz]', mode='text', auto_set=False, enter_set=True) rf_t_pi = Range(low=1., high=1.e7, value=1.e6, desc='length of pi pulse of RF[ns]', label='RF pi [ns]', mode='text', auto_set=False, enter_set=True) # ESR: """ rf_begin = Range(low=1, high=10e9, value=2.8e9, desc='Start Frequency [Hz]', label='RF Begin [Hz]') rf_end = Range(low=1, high=10e9, value=2.9e9, desc='Stop Frequency [Hz]', label='RF End [Hz]') rf_delta = Range(low=1e-3, high=10e9, value=1e6, desc='frequency step [Hz]', label='Delta [Hz]') """ laser = Range(low=1., high=1.0e7, value=3000., desc='laser [ns]', label='laser [ns]', mode='text', auto_set=False, enter_set=True) wait = Range(low=1., high=1.0e7, value=2.0e6, desc='wait [ns]', label='wait [ns]', mode='text', auto_set=False, enter_set=True) seconds_per_point = Range(low=0.1, high=10., value=0.5, desc='Seconds per point', label='Seconds per point', mode='text', auto_set=False, enter_set=True) sweeps_per_point = Int() run_time = Float(value=0.0) frequencies = Array(value=np.array((0., 1.))) def generate_sequence(self): # ESR: #return 100*[ (['laser','aom'], self.laser), ([],self.wait), (['mw'], self.mw_t_pi), (['sequence'], 10) ] return 100 * [(['laser', 'aom'], self.laser), ([], self.wait), (['mw_b'], self.t_pi_B), (['rf'], self.rf_t_pi), ([], 500), (['aom'], self.laser), ([], self.wait), (['mw'], self.t_pi_A), (['rf'], self.rf_t_pi), ([], 500), (['mw'], self.t_pi_A), (['sequence'], 10)] def apply_parameters(self): """Apply the current parameters and decide whether to keep previous data.""" frequencies = np.arange(self.rf_begin, self.rf_end + self.rf_delta, self.rf_delta) n_bins = int(self.record_length / self.bin_width) time_bins = self.bin_width * np.arange(n_bins) sequence = self.generate_sequence() if not ( self.keep_data and sequence == self.sequence and np.all(time_bins == self.time_bins) and np.all(frequencies == self.frequencies) ): # if the sequence and time_bins are the same as previous, keep existing data self.count_data = np.zeros((len(frequencies), n_bins)) self.run_time = 0.0 self.frequencies = frequencies self.sequence = sequence self.time_bins = time_bins self.n_bins = n_bins # ESR: #self.sweeps_per_point = int(self.seconds_per_point * 1e9 / (self.laser+self.wait+self.mw_t_pi)) self.sweeps_per_point = int( np.max((1, int(self.seconds_per_point * 1e9 / (self.laser * 2 + self.wait * 2 + 2 * self.t_pi_A + self.t_pi_B + 2 * self.rf_t_pi + 1000.0))))) self.keep_data = True # when job manager stops and starts the job, data should be kept. Only new submission should clear data. def _run(self): """Acquire data.""" try: # try to run the acquisition from start_up to shut_down self.state = 'run' self.apply_parameters() ha.PulseGenerator().Night() ha.Microwave().setOutput(self.mwA_power, self.mwA_frequency) ha.MicrowaveD().setOutput(self.mwB_power, self.mwB_frequency) tagger = ha.TimeTagger.Pulsed(self.n_bins, int(np.round(self.bin_width * 1000)), 1, 0, 2, 3) tagger.setMaxCounts(self.sweeps_per_point) ha.PulseGenerator().Sequence(self.sequence) ha.RFSource().setMode() while True: if self.thread.stop_request.isSet(): break t_start = time.time() for i, fi in enumerate(self.frequencies): # ESR: #ha.Microwave().setOutput(self.mw_power,fi) ha.RFSource().setOutput(self.rf_power, fi) tagger.clear() while not tagger.ready(): time.sleep(1.1 * self.seconds_per_point) self.count_data[i, :] += tagger.getData()[0] self.trait_property_changed('count_data', self.count_data) self.run_time += time.time() - t_start del tagger ha.PulseGenerator().Light() ha.Microwave().setOutput(None, self.mwA_frequency) ha.MicrowaveD().setOutput(None, self.mwB_frequency) ha.RFSource().setOutput(None, self.rf_begin) finally: # if anything fails, recover self.state = 'idle' ha.PulseGenerator().Light() get_set_items = Pulsed.get_set_items + [ 'mwA_frequency', 'mwA_power', 't_pi_A', 'mwB_frequency', 'mwB_power', 't_pi_B', 'rf_power', 'rf_begin', 'rf_end', 'rf_delta', 'rf_t_pi', 'laser', 'wait', 'seconds_per_point', 'frequencies', 'count_data', 'sequence' ] traits_view = View( VGroup( HGroup( Item('submit_button', show_label=False), Item('remove_button', show_label=False), Item('resubmit_button', show_label=False), Item('priority', width=-40), Item('state', style='readonly'), Item('run_time', style='readonly'), ), Tabbed( VGroup(HGroup( Item('mwA_power', width=-40), Item('mwA_frequency', width=-80, editor=TextEditor(auto_set=False, enter_set=True, evaluate=float, format_func=lambda x: '%e' % x)), Item('t_pi_A', width=-80), ), HGroup( Item('mwB_power', width=-40), Item('mwB_frequency', width=-80, editor=TextEditor( auto_set=False, enter_set=True, evaluate=float, format_func=lambda x: '%e' % x)), Item('t_pi_B', width=-80), ), HGroup( Item('rf_power', width=-40), Item('rf_begin', width=-80, editor=TextEditor( auto_set=False, enter_set=True, evaluate=float, format_func=lambda x: '%e' % x)), Item('rf_end', width=-80, editor=TextEditor( auto_set=False, enter_set=True, evaluate=float, format_func=lambda x: '%e' % x)), Item('rf_delta', width=-80, editor=TextEditor( auto_set=False, enter_set=True, evaluate=float, format_func=lambda x: '%e' % x)), Item('rf_t_pi', width=-80), ), label='parameter'), VGroup(HGroup( Item('laser', width=-80, enabled_when='state == "idle"'), Item('wait', width=-80, enabled_when='state == "idle"'), Item('record_length', width=-80, enabled_when='state == "idle"'), Item('bin_width', width=-80, enabled_when='state == "idle"'), ), HGroup( Item('seconds_per_point', width=-120, enabled_when='state == "idle"'), Item('sweeps_per_point', width=-120, style='readonly'), ), label='settings'), ), ), title='NMR, use frequencies to fit', )
def traits_view(self): v = View(UItem('container', editor=ComponentEditor()), resizable=True, handler=self.handler_klass) return v
class Controller(HasTraits): # A reference to the plot viewer object # Some parameters controller the random signal that will be generated distribution_type = Enum("normal") mean = Float(0.0) stddev = Float(1.0) # The max number of data points to accumulate and show in the plot max_num_points = Int(100) # The number of data points we have received; we need to keep track of # this in order to generate the correct x axis data series. num_ticks = Int(0) # private reference to the random number generator. this syntax # just means that self._generator should be initialized to # random.normal, which is a random number function, and in the future # it can be set to any callable object. _generator = Trait(np.random.normal, Callable) view = View(Group('distribution_type', 'mean', 'stddev', 'max_num_points', orientation="vertical"), buttons=["OK", "Cancel"]) def timer_tick(self, *args): """ Callback function that should get called based on a timer tick. This will generate a new random data point and set it on the `.data` array of our viewer object. """ # Generate a new number and increment the tick count # x, y, z=accel.read() # ADXL345 address, 0x53(83) # Select bandwidth rate register, 0x2C(44) # 0x0A(10) Normal mode, Output data rate = 100 Hz bus.write_byte_data(0x53, 0x2C, 0x0A) # ADXL345 address, 0x53(83) # Select power control register, 0x2D(45) # 0x08(08) Auto Sleep disable bus.write_byte_data(0x53, 0x2D, 0x08) # ADXL345 address, 0x53(83) # Select data format register, 0x31(49) # 0x08(08) Self test disabled, 4-wire interface # Full resolution, Range = +/-2g bus.write_byte_data(0x53, 0x31, 0x08) # time.sleep(0.5) # ADXL345 address, 0x53(83) # Read data back from 0x32(50), 2 bytes # X-Axis LSB, X-Axis MSB data0 = bus.read_byte_data(0x53, 0x32) data1 = bus.read_byte_data(0x53, 0x33) # Convert the data to 10-bits xAccl = ((data1 & 0x03) * 256) + data0 if xAccl > 511: xAccl -= 1024 # ADXL345 address, 0x53(83) # Read data back from 0x34(52), 2 bytes # Y-Axis LSB, Y-Axis MSB data0 = bus.read_byte_data(0x53, 0x34) data1 = bus.read_byte_data(0x53, 0x35) # Convert the data to 10-bits yAccl = ((data1 & 0x03) * 256) + data0 if yAccl > 511: yAccl -= 1024 # ADXL345 address, 0x53(83) # Read data back from 0x36(54), 2 bytes # Z-Axis LSB, Z-Axis MSB data0 = bus.read_byte_data(0x53, 0x36) data1 = bus.read_byte_data(0x53, 0x37) # Convert the data to 10-bits zAccl = ((data1 & 0x03) * 256) + data0 if zAccl > 511: zAccl -= 1024 # Output data to screen # print "Acceleration in X-Axis : %d" %xAccl # print "Acceleration in Y-Axis : %d" %yAccl # print "Acceleration in Z-Axis : %d" %zAccl new_val = xAccl self.num_ticks += 1 # grab the existing data, truncate it, and append the new point. # This isn't the most efficient thing in the world but it works. cur_data = self.viewer.data new_data = np.hstack((cur_data[-self.max_num_points + 1:], [new_val])) new_index = np.arange(self.num_ticks - len(new_data) + 1, self.num_ticks + 0.01) self.viewer.index = new_index self.viewer.data = new_data return def _distribution_type_changed(self): # This listens for a change in the type of distribution to use. while True: # Read the X, Y, Z axis acceleration values and print them. x, y, z = accel.read() print('X={0}, Y={1}, Z={2}'.format(x, y, z)) # Wait half a second and repeat. time.sleep(0.1) self._generator = x
class J2(YieldFaceCPP): ''' Current version by Jakub (16.09.2008) ''' sigma_y = Float(100.) cronecker_delta = array([1., 1., 0.]) P = diag([1., 1., 2.]) def get_f_trial(self, xi_trial, q_1): xi_v = (xi_trial[0] + xi_trial[1]) / 3. s_xi = xi_trial - dot(xi_v, self.cronecker_delta) J_2 = 0.5 * dot(dot(s_xi, self.P), s_xi) f_trial = J_2 - 1. / 3 * (self.sigma_y + q_1)**2 # print "YF f_trial",f_trial return f_trial def get_diff1s(self, epsilon_n1, E, nu, sctx): diff1s = zeros(3) epsilon_p = sctx.mats_state_array[:3] q_1 = sctx.mats_state_array[3] q_2 = sctx.mats_state_array[4:] t1 = 1.0 - nu t2 = E * t1 t4 = 1 / (1.0 + nu) t7 = 1 / (1.0 - 2.0 * nu) t8 = t4 * t7 t9 = epsilon_n1[0] - epsilon_p[0] t11 = t2 * t8 * t9 t13 = E * t4 t14 = t7 * nu t15 = epsilon_n1[1] - epsilon_p[1] t17 = t13 * t14 * t15 t21 = t13 * t14 * t9 t24 = t2 * t8 * t15 diff1s[0] = 5.0 / 9.0 * t11 + 5.0 / 9.0 * t17 - 5.0 / 9.0 * \ q_2[0] - 4.0 / 9.0 * t21 - 4.0 / 9.0 * t24 + 4.0 / 9.0 * q_2[1] diff1s[1] = -4.0 / 9.0 * t11 - 4.0 / 9.0 * t17 + 4.0 / 9.0 * \ q_2[0] + 5.0 / 9.0 * t21 + 5.0 / 9.0 * t24 - 5.0 / 9.0 * q_2[1] diff1s[2] = t2 * t4 / t1 * \ (epsilon_n1[2] - epsilon_p[2]) - 2.0 * q_2[2] return diff1s def get_diff1q(self, epsilon_n1, E, nu, sctx): diff1q = zeros(4) epsilon_p = sctx.mats_state_array[:3] q_1 = sctx.mats_state_array[3] q_2 = sctx.mats_state_array[4:] t2 = 1.0 - nu t3 = E * t2 t5 = 1 / (1.0 + nu) t8 = 1 / (1.0 - 2.0 * nu) t9 = t5 * t8 t10 = epsilon_n1[0] - epsilon_p[0] t12 = t3 * t9 * t10 t14 = E * t5 t15 = t8 * nu t16 = epsilon_n1[1] - epsilon_p[1] t18 = t14 * t15 * t16 t22 = t14 * t15 * t10 t25 = t3 * t9 * t16 diff1q[0] = -2.0 / 3.0 * self.sigma_y - 2.0 / 3.0 * q_1 diff1q[1] = -5.0 / 9.0 * t12 - 5.0 / 9.0 * t18 + 5.0 / 9.0 * \ q_2[0] + 4.0 / 9.0 * t22 + 4.0 / 9.0 * t25 - 4.0 / 9.0 * q_2[1] diff1q[2] = 4.0 / 9.0 * t12 + 4.0 / 9.0 * t18 - 4.0 / 9.0 * \ q_2[0] - 5.0 / 9.0 * t22 - 5.0 / 9.0 * t25 + 5.0 / 9.0 * q_2[1] diff1q[3] = -t3 * t5 / t2 * \ (epsilon_n1[2] - epsilon_p[2]) + 2.0 * q_2[2] return diff1q def get_diff2ss(self, epsilon_n1, E, nu, sctx): diff2ss = zeros([3, 3]) diff2ss[0, 0] = 5.0 / 9.0 diff2ss[0, 1] = -4.0 / 9.0 diff2ss[1, 0] = -4.0 / 9.0 diff2ss[1, 1] = 5.0 / 9.0 diff2ss[2, 2] = 2.0 return diff2ss def get_diff2sq(self, epsilon_n1, E, nu, sctx): diff2sq = zeros([3, 4]) diff2sq[0, 1] = -5.0 / 9.0 diff2sq[0, 2] = 4.0 / 9.0 diff2sq[1, 1] = 4.0 / 9.0 diff2sq[1, 2] = -5.0 / 9.0 diff2sq[2, 3] = -2.0 return diff2sq def get_diff2qq(self, epsilon_n1, E, nu, sctx): diff2qq = zeros([4, 4]) diff2qq[0, 0] = -2.0 / 3.0 diff2qq[1, 1] = 5.0 / 9.0 diff2qq[1, 2] = -4.0 / 9.0 diff2qq[2, 1] = -4.0 / 9.0 diff2qq[2, 2] = 5.0 / 9.0 diff2qq[3, 3] = 2.0 return diff2qq view_traits = View(Item('sigma_y'))
def _get_edit_view(self): g1 = HGroup(Item('name', editor=EnumEditor(name='names')), Item('equilibration_time', label='Eq. Time')) v = View(VGroup(g1, show_border=True)) return v
class SetEditorDemo(HasTraits): """Defines the SetEditor demo class.""" # Define a trait each for four SetEditor variants: unord_nma_set = List( editor=SetEditor( values=['kumquats', 'pomegranates', 'kiwi'], left_column_title='Available Fruit', right_column_title='Exotic Fruit Bowl', can_move_all=False, ) ) unord_ma_set = List( editor=SetEditor( values=['kumquats', 'pomegranates', 'kiwi'], left_column_title='Available Fruit', right_column_title='Exotic Fruit Bowl', ) ) ord_nma_set = List( editor=SetEditor( values=['apples', 'berries', 'cantaloupe'], left_column_title='Available Fruit', right_column_title='Fruit Bowl', ordered=True, can_move_all=False, ) ) ord_ma_set = List( editor=SetEditor( values=['apples', 'berries', 'cantaloupe'], left_column_title='Available Fruit', right_column_title='Fruit Bowl', ordered=True, ) ) # SetEditor display, unordered, no move-all buttons: no_nma_group = Group( Item('unord_nma_set', style='simple'), label='Unord I', show_labels=False, ) # SetEditor display, unordered, move-all buttons: no_ma_group = Group( Item('unord_ma_set', style='simple'), label='Unord II', show_labels=False, ) # SetEditor display, ordered, no move-all buttons: o_nma_group = Group( Item('ord_nma_set', style='simple'), label='Ord I', show_labels=False ) # SetEditor display, ordered, move-all buttons: o_ma_group = Group( Item('ord_ma_set', style='simple'), label='Ord II', show_labels=False ) # The view includes one group per data type. These will be displayed # on separate tabbed panels: traits_view = View( no_nma_group, no_ma_group, o_nma_group, o_ma_group, title='SetEditor', buttons=['OK'], )
class HeadViewController(HasTraits): """Set head views for the given coordinate system. Parameters ---------- system : 'RAS' | 'ALS' | 'ARI' Coordinate system described as initials for directions associated with the x, y, and z axes. Relevant terms are: Anterior, Right, Left, Superior, Inferior. """ system = Enum("RAS", "ALS", "ARI", desc="Coordinate system: directions of " "the x, y, and z axis.") right = Button() front = Button() left = Button() top = Button() interaction = Enum('Trackball', 'Terrain') scale = Float(0.16) scene = Instance(MlabSceneModel) view = View(VGrid('0', 'top', '0', Item('scale', label='Scale', show_label=True), 'right', 'front', 'left', 'interaction', show_labels=False, columns=4)) @on_trait_change('scene.activated') def _init_view(self): self.scene.parallel_projection = True self._trackball_interactor = None # apparently scene,activated happens several times if self.scene.renderer: self.sync_trait('scale', self.scene.camera, 'parallel_scale') # and apparently this does not happen by default: self.on_trait_change(self.scene.render, 'scale') @on_trait_change('interaction') def on_set_interaction(self, _, interaction): if self.scene is None: return if interaction == 'Terrain': # Ensure we're in the correct orientatino for the # InteractorStyleTerrain to have the correct "up" if self._trackball_interactor is None: self._trackball_interactor = \ self.scene.interactor.interactor_style self.on_set_view('front', '') self.scene.mlab.draw() self.scene.interactor.interactor_style = \ tvtk.InteractorStyleTerrain() self.on_set_view('front', '') self.scene.mlab.draw() else: # interaction == 'trackball' self.scene.interactor.interactor_style = self._trackball_interactor @on_trait_change('top,left,right,front') def on_set_view(self, view, _): if self.scene is None: return system = self.system kwargs = dict(ALS=dict(front=(0, 90, -90), left=(90, 90, 180), right=(-90, 90, 0), top=(0, 0, -90)), RAS=dict(front=(90., 90., 180), left=(180, 90, 90), right=(0., 90, 270), top=(90, 0, 180)), ARI=dict(front=(0, 90, 90), left=(-90, 90, 180), right=(90, 90, 0), top=(0, 180, 90))) if system not in kwargs: raise ValueError("Invalid system: %r" % system) if view not in kwargs[system]: raise ValueError("Invalid view: %r" % view) kwargs = dict(zip(('azimuth', 'elevation', 'roll'), kwargs[system][view])) with SilenceStdout(): self.scene.mlab.view(distance=None, reset_roll=True, figure=self.scene.mayavi_scene, **kwargs)
# configure_traits_view_group.py -- Sample code to demonstrate # configure_traits() #--[Imports]-------------------------------------------------------------- from __future__ import absolute_import from traits.api import HasTraits, Str, Int from traitsui.api import View, Item, Group import traitsui #--[Code]----------------------------------------------------------------- class SimpleEmployee(HasTraits): first_name = Str last_name = Str department = Str employee_number = Str salary = Int view1 = View( Group(Item(name='first_name'), Item(name='last_name'), Item(name='department'), label='Personnel profile', show_border=True)) sam = SimpleEmployee() sam.configure_traits(view=view1)
class MATS3DMicroplaneDamageJir(MATSXDMicroplaneDamageFatigueJir): # implements(IMATSEval) #----------------------------------------------- # number of microplanes - currently fixed for 3D #----------------------------------------------- n_mp = Constant(28) #----------------------------------------------- # get the normal vectors of the microplanes #----------------------------------------------- _MPN = Property(depends_on='n_mp') @cached_property def _get__MPN(self): # microplane normals: return array([[.577350259, .577350259, .577350259], [.577350259, .577350259, -.577350259], [.577350259, -.577350259, .577350259], [.577350259, -.577350259, -.577350259], [.935113132, .250562787, .250562787], [.935113132, .250562787, -.250562787], [.935113132, -.250562787, .250562787], [.935113132, -.250562787, -.250562787], [.250562787, .935113132, .250562787], [.250562787, .935113132, -.250562787], [.250562787, -.935113132, .250562787], [.250562787, -.935113132, -.250562787], [.250562787, .250562787, .935113132], [.250562787, .250562787, -.935113132], [.250562787, -.250562787, .935113132], [.250562787, -.250562787, -.935113132], [.186156720, .694746614, .694746614], [.186156720, .694746614, -.694746614], [.186156720, -.694746614, .694746614], [.186156720, -.694746614, -.694746614], [.694746614, .186156720, .694746614], [.694746614, .186156720, -.694746614], [.694746614, -.186156720, .694746614], [.694746614, -.186156720, -.694746614], [.694746614, .694746614, .186156720], [.694746614, .694746614, -.186156720], [.694746614, -.694746614, .186156720], [.694746614, -.694746614, -.186156720]]) #------------------------------------- # get the weights of the microplanes #------------------------------------- _MPW = Property(depends_on='n_mp') @cached_property def _get__MPW(self): # Note that the values in the array must be multiplied by 6 (cf. [Baz05])! # The sum of of the array equals 0.5. (cf. [BazLuz04])) # The values are given for an Gaussian integration over the unit # hemisphere. return array([ .0160714276, .0160714276, .0160714276, .0160714276, .0204744730, .0204744730, .0204744730, .0204744730, .0204744730, .0204744730, .0204744730, .0204744730, .0204744730, .0204744730, .0204744730, .0204744730, .0158350505, .0158350505, .0158350505, .0158350505, .0158350505, .0158350505, .0158350505, .0158350505, .0158350505, .0158350505, .0158350505, .0158350505 ]) * 6.0 #------------------------------------------------------------------------- # Cached elasticity tensors #------------------------------------------------------------------------- elasticity_tensors = Property( depends_on='E, nu, dimensionality, stress_state') @cached_property def _get_elasticity_tensors(self): ''' Intialize the fourth order elasticity tensor for 3D or 2D plane strain or 2D plane stress ''' # ---------------------------------------------------------------------------- # Lame constants calculated from E and nu # ---------------------------------------------------------------------------- # first Lame paramter la = self.E * self.nu / ((1 + self.nu) * (1 - 2 * self.nu)) # second Lame parameter (shear modulus) mu = self.E / (2 + 2 * self.nu) # ----------------------------------------------------------------------------------------------------- # Get the fourth order elasticity and compliance tensors for the 3D-case # ----------------------------------------------------------------------------------------------------- # construct the elasticity tensor (using Numpy - einsum function) delta = identity(3) D_ijkl = (einsum(',ij,kl->ijkl', la, delta, delta) + einsum(',ik,jl->ijkl', mu, delta, delta) + einsum(',il,jk->ijkl', mu, delta, delta)) return D_ijkl #------------------------------------------------------------------------- # Dock-based view with its own id #------------------------------------------------------------------------- traits_view = View(Include('polar_fn_group'), dock='tab', id='ibvpy.mats.mats3D.mats_3D_cmdm.MATS3D_cmdm', kind='modal', resizable=True, scrollable=True, width=0.6, height=0.8, buttons=['OK', 'Cancel'])
class PointObject(Object): """Represent a group of individual points in a mayavi scene.""" label = Bool(False, enabled_when='visible') text3d = List glyph = Instance(Glyph) resolution = Int(8) view = View(HGroup(Item('visible', show_label=False), Item('color', show_label=False), Item('opacity'))) def __init__(self, view='points', *args, **kwargs): """Init. Parameters ---------- view : 'points' | 'cloud' Whether the view options should be tailored to individual points or a point cloud. """ self._view = view super(PointObject, self).__init__(*args, **kwargs) def default_traits_view(self): # noqa: D102 color = Item('color', show_label=False) scale = Item('point_scale', label='Size') if self._view == 'points': visible = Item('visible', label='Show', show_label=True) view = View(HGroup(visible, color, scale, 'label')) elif self._view == 'cloud': visible = Item('visible', show_label=False) view = View(HGroup(visible, color, scale)) else: raise ValueError("PointObject(view = %r)" % self._view) return view @on_trait_change('label') def _show_labels(self, show): _toggle_mlab_render(self, False) while self.text3d: text = self.text3d.pop() text.remove() if show: fig = self.scene.mayavi_scene for i, pt in enumerate(np.array(self.src.data.points)): x, y, z = pt t = text3d(x, y, z, ' %i' % i, scale=.01, color=self.color, figure=fig) self.text3d.append(t) _toggle_mlab_render(self, True) @on_trait_change('visible') def _on_hide(self): if not self.visible: self.label = False @on_trait_change('scene.activated') def _plot_points(self): """Add the points to the mayavi pipeline""" if self.scene is None: return if hasattr(self.glyph, 'remove'): self.glyph.remove() if hasattr(self.src, 'remove'): self.src.remove() _toggle_mlab_render(self, False) x, y, z = self.points.T fig = self.scene.mayavi_scene scatter = pipeline.scalar_scatter(x, y, z, fig=fig) if not scatter.running: # this can occur sometimes during testing w/ui.dispose() return # fig.scene.engine.current_object is scatter glyph = pipeline.glyph(scatter, color=self.color, figure=fig, scale_factor=self.point_scale, opacity=1., resolution=self.resolution) glyph.actor.property.backface_culling = True self.src = scatter self.glyph = glyph self.sync_trait('point_scale', self.glyph.glyph.glyph, 'scale_factor') self.sync_trait('color', self.glyph.actor.property, mutual=False) self.sync_trait('visible', self.glyph) self.sync_trait('opacity', self.glyph.actor.property) self.on_trait_change(self._update_points, 'points') _toggle_mlab_render(self, True) # self.scene.camera.parallel_scale = _scale def _resolution_changed(self, new): if not self.glyph: return self.glyph.glyph.glyph_source.glyph_source.phi_resolution = new self.glyph.glyph.glyph_source.glyph_source.theta_resolution = new
class SourceWidget(Component): # The version of this class. Used for persistence. __version__ = 0 # The actual poly data source widget. widget = Instance(tvtk.ThreeDWidget, record=True) # Specifies the updation mode of the poly_data attribute. There # are three modes: 1) 'interactive' -- the poly_data attribute is # updated as the widget is interacted with, 2) 'semi-interactive' # -- poly_data attribute is updated when the traits of the widget # change and when the widget interaction is complete, 3) # 'non-interactive' -- poly_data is updated only explicitly at # users request by calling `object.update_poly_data`. update_mode = Trait( 'interactive', TraitPrefixList(['interactive', 'semi-interactive', 'non-interactive']), desc='the speed at which the poly data is updated') # A list of predefined glyph sources that can be used. widget_list = List(tvtk.Object, record=False) # The poly data that the widget manages. poly_data = Instance(tvtk.PolyData, args=()) ######################################## # Private traits. _first = Bool(True) _busy = Bool(False) _unpickling = Bool(False) _bounds = List ######################################## # View related traits. view = View( Group( Item(name='widget', style='custom', resizable=True, editor=InstanceEditor(name='widget_list')), label='Source Widget', show_labels=False, ), resizable=True, ) ###################################################################### # `Base` interface ###################################################################### def __get_pure_state__(self): d = super(SourceWidget, self).__get_pure_state__() for attr in ('poly_data', '_unpickling', '_first', '_busy'): d.pop(attr, None) return d def __set_pure_state__(self, state): self._unpickling = True # First create all the allowed widgets in the widget_list attr. handle_children_state(self.widget_list, state.widget_list) # Now set their state. set_state(self, state, first=['widget_list'], ignore=['*']) # Set the widget attr depending on value saved. m = [x.__class__.__name__ for x in self.widget_list] w_c_name = state.widget.__metadata__['class_name'] w = self.widget = self.widget_list[m.index(w_c_name)] # Set the input. if len(self.inputs) > 0: self.configure_input(w, self.inputs[0].outputs[0]) # Fix for the point widget. if w_c_name == 'PointWidget': w.place_widget() # Set state of rest of the attributes ignoring the widget_list. set_state(self, state, ignore=['widget_list']) # Some widgets need some cajoling to get their setup right. w.update_traits() if w_c_name == 'PlaneWidget': w.origin = state.widget.origin w.normal = state.widget.normal w.center = state.widget.center w.update_placement() w.get_poly_data(self.poly_data) elif w_c_name == 'SphereWidget': # XXX: This hack is necessary because the sphere widget # does not update its poly data even when its ivars are # set (plus it does not have an update_placement method # which is a bug). So we force this by creating a similar # sphere source and copy its output. s = tvtk.SphereSource(center=w.center, radius=w.radius, theta_resolution=w.theta_resolution, phi_resolution=w.phi_resolution, lat_long_tessellation=True) s.update() self.poly_data.shallow_copy(s.output) else: w.get_poly_data(self.poly_data) self._unpickling = False # Set the widgets trait so that the widget is rendered if needed. self.widgets = [w] ###################################################################### # `Component` interface ###################################################################### def setup_pipeline(self): """Override this method so that it *creates* the tvtk pipeline. This method is invoked when the object is initialized via `__init__`. Note that at the time this method is called, the tvtk data pipeline will *not* yet be setup. So upstream data will not be available. The idea is that you simply create the basic objects and setup those parts of the pipeline not dependent on upstream sources and filters. You should also set the `actors` attribute up at this point. """ # Setup the glyphs. sources = [ tvtk.SphereWidget(theta_resolution=8, phi_resolution=6), tvtk.LineWidget(clamp_to_bounds=False), tvtk.PlaneWidget(), tvtk.PointWidget(outline=False, x_shadows=False, y_shadows=False, z_shadows=False), ] self.widget_list = sources # The 'widgets' trait is set in the '_widget_changed' handler. self.widget = sources[0] for s in sources: self._connect(s) def update_pipeline(self): """Override this method so that it *updates* the tvtk pipeline when data upstream is known to have changed. This method is invoked (automatically) when any of the inputs sends a `pipeline_changed` event. """ if len(self.inputs) == 0: return inp = self.inputs[0].outputs[0] w = self.widget self.configure_input(w, inp) dsh = DataSetHelper(self.inputs[0].outputs[0]) b = dsh.get_bounds() self._bounds = list(b) if self._first: w.place_widget(b) self._first = False # If the dataset is effectively 2D switch to using the line # widget since that works best. l = [(b[1] - b[0]), (b[3] - b[2]), (b[5] - b[4])] max_l = max(l) for i, x in enumerate(l): if x / max_l < 1.0e-6: w = self.widget = self.widget_list[1] w.clamp_to_bounds = True w.align = ['z_axis', 'z_axis', 'y_axis'][i] break # Set our output. w.get_poly_data(self.poly_data) self.outputs = [self.poly_data] self.pipeline_changed = True def update_data(self): """Override this method so that it flushes the vtk pipeline if that is necessary. This method is invoked (automatically) when any of the inputs sends a `data_changed` event. """ self.data_changed = True ###################################################################### # `SourceWidget` interface ###################################################################### def update_poly_data(self): self.widget.get_poly_data(self.poly_data) ###################################################################### # Non-public traits. ###################################################################### def _widget_changed(self, value): # If we are being unpickled do nothing. if self._unpickling: return if value not in self.widget_list: classes = [o.__class__ for o in self.widget_list] vc = value.__class__ self._connect(value) if vc in classes: self.widget_list[classes.index(vc)] = value else: self.widget_list.append(value) recorder = self.recorder if recorder is not None: idx = self.widget_list.index(value) name = recorder.get_script_id(self) lhs = '%s.widget' % name rhs = '%s.widget_list[%d]' % (name, idx) recorder.record('%s = %s' % (lhs, rhs)) if len(self.inputs) > 0: self.configure_input(value, self.inputs[0].outputs[0]) value.place_widget(self._bounds) value.on_trait_change(self.render) self.widgets = [value] def _update_mode_changed(self, value): if value in ['interactive', 'semi-interactive']: self.update_poly_data() self.render() def _on_interaction_event(self, obj, event): if (not self._busy) and (self.update_mode == 'interactive'): self._busy = True self.update_poly_data() self._busy = False def _on_widget_trait_changed(self): if (not self._busy) and (self.update_mode != 'non-interactive'): self._busy = True # This render call forces any changes to the trait to be # rendered only then will updating the poly data make # sense. self.render() self.update_poly_data() self._busy = False def _on_alignment_set(self): w = self.widget w.place_widget(self._bounds) w.update_traits() def _connect(self, obj): """Wires up all the event handlers.""" obj.add_observer('InteractionEvent', self._on_interaction_event) if isinstance(obj, tvtk.PlaneWidget): obj.on_trait_change(self._on_alignment_set, 'normal_to_x_axis') obj.on_trait_change(self._on_alignment_set, 'normal_to_y_axis') obj.on_trait_change(self._on_alignment_set, 'normal_to_z_axis') elif isinstance(obj, tvtk.LineWidget): obj.on_trait_change(self._on_alignment_set, 'align') # Setup the widgets colors. fg = (1, 1, 1) if self.scene is not None: fg = self.scene.foreground self._setup_widget_colors(obj, fg) obj.on_trait_change(self._on_widget_trait_changed) obj.on_trait_change(self.render) def _setup_widget_colors(self, widget, color): trait_names = widget.trait_names() props = [ x for x in trait_names if 'property' in x and 'selected' not in x ] sel_props = [ x for x in trait_names if 'property' in x and 'selected' in x ] for p in props: setattr(getattr(widget, p), 'color', color) setattr(getattr(widget, p), 'line_width', 2) for p in sel_props: # Set the selected color to 'red'. setattr(getattr(widget, p), 'color', (1, 0, 0)) setattr(getattr(widget, p), 'line_width', 2) self.render() def _foreground_changed_for_scene(self, old, new): # Change the default color for the actor. for w in self.widget_list: self._setup_widget_colors(w, new) self.render() def _scene_changed(self, old, new): super(SourceWidget, self)._scene_changed(old, new) self._foreground_changed_for_scene(None, new.foreground)
class DOTSListEval(TStepperEval): '''Domain with uniform FE-time-step-eval. ''' implements(ITStepperEval) sdomain = WeakRef('ibvpy.mesh.fe_domain.FEDomain') dots_list = List def new_cntl_var(self): return zeros(self.sdomain.n_dofs, float_) def new_resp_var(self): return zeros(self.sdomain.n_dofs, float_) K = Property @cached_property def _get_K(self): return SysMtxAssembly() F_int = Property(depends_on='sdomain.changed_structure') @cached_property def _get_F_int(self): n_dofs = self.sdomain.n_dofs return zeros(n_dofs, 'float_') def setup(self, sctx): print 'DEPRECATED CALL TO SETUP' def get_state_array_size(self): return 0 def apply_constraints(self, K): for dots_eval in self.dots_list: dots_eval.apply_constraints(K) def get_corr_pred(self, sctx, U, d_U, tn, tn1, *args, **kw): K = self.K K.reset() F_int = self.F_int F_int[:] = 0.0 U = self.tstepper.U_k d_U = self.tstepper.d_U for dots_eval in self.dots_list: K_mtx_arr = dots_eval.get_corr_pred(sctx, U, d_U, tn, tn1, self.F_int, *args, **kw) K.sys_mtx_arrays.append(K_mtx_arr) return self.F_int, self.K rte_dict = Property(Dict, depends_on='dots_list') @cached_property def _get_rte_dict(self): rte_dict = {} dots_rte_dicts = [] rte_keys = [] for dots_eval in self.dots_list: dots_rte_dict = {} for key, eval in dots_eval.rte_dict.items(): # add the mapping here # if key not in rte_keys: rte_keys.append(key) dots_rte_dict[key] = eval dots_rte_dicts.append(dots_rte_dict) # Get the union of all available rte keys for key in rte_keys: rte_list = [] for rte_dict in dots_rte_dicts: rte_list.append(rte_dict.get(key, None)) rte_dict[key] = tuple(rte_list) return rte_dict traits_view = View()
def translation_traits_view(self): return View(HGroup(Item('from_channel', style = 'readonly', show_label = False), Item('', label = '->'), Item('to_channel', style = 'readonly', show_label = False), Item('file', show_label = False)), handler = self)
class ModelView(HasTraits): model = Instance(Model) view = Instance(PlotUI) timer = Instance(Timer) timer_controller = Instance(TimerController, ()) edit_model = Button edit_view = Button animated = Bool(False) # Whether to animate colors on a bounce of each side: animate_left = Bool(False) animate_right = Bool(False) animate_top = Bool(False) animate_bottom = Bool(False) traits_view = View(UItem('@view'), HGroup( UItem('edit_model', enabled_when='not animated'), UItem('edit_view'), Item('animated'), Item('animate_left', enabled_when='animated', label='Change colors at: Left'), Item('animate_right', enabled_when='animated', label='Right'), Item('animate_top', enabled_when='animated', label='Top'), Item('animate_bottom', enabled_when='animated', label='Bottom'), spring), title="Function Inspector", resizable=True) @on_trait_change('model, view') def update_view(self): if self.model is not None and self.view is not None: self.view.update(self.model) def _edit_model_fired(self): self.model.configure_traits() def _edit_view_fired(self): self.view.configure_traits(view="plot_edit_view") def _model_changed(self): if self.view is not None: self.view.update(self.model) def _start_timer(self): # Start up the timer! We should do this only when the demo actually # starts and not when the demo object is created. # FIXME: close timer on exit. self.timer_controller.view = self.view self.timer_controller.model_view = self self.timer = Timer(40, self.timer_controller.onTimer) def edit_traits(self, *args, **kws): self._start_timer() return super(ModelView, self).edit_traits(*args, **kws) def configure_traits(self, *args, **kws): self._start_timer() return super(ModelView, self).configure_traits(*args, **kws)
class Viz2DPullOutFW(Viz2D): '''Plot adaptor for the pull-out simulator. ''' label = 'F-W' show_legend = Bool(True, auto_set=False, enter_set=True) def plot(self, ax, vot, *args, **kw): sim = self.vis2d.sim P_t, w_0_t, w_L_t = sim.hist['Pw'].Pw ymin, ymax = np.min(P_t), np.max(P_t) L_y = ymax - ymin ymax += 0.05 * L_y ymin -= 0.05 * L_y xmin, xmax = np.min(w_L_t), np.max(w_L_t) L_x = xmax - xmin xmax += 0.03 * L_x xmin -= 0.03 * L_x ax.plot(w_L_t, P_t, linewidth=2, color='black', alpha=0.4, label='P(w;x=L)') ax.plot(w_0_t, P_t, linewidth=1, color='magenta', alpha=0.4, label='P(w;x=0)') ax.set_ylim(ymin=ymin, ymax=ymax) ax.set_xlim(xmin=xmin, xmax=xmax) ax.set_ylabel('pull-out force P [N]') ax.set_xlabel('pull-out slip w [mm]') if self.show_legend: ax.legend(loc=4) self.plot_marker(ax, vot) def plot_marker(self, ax, vot): sim = self.vis2d.sim P_t, w_0_t, w_L_t = sim.hist['Pw'].Pw idx = sim.hist.get_time_idx(vot) P, w = P_t[idx], w_L_t[idx] ax.plot([w], [P], 'o', color='black', markersize=10) P, w = P_t[idx], w_0_t[idx] ax.plot([w], [P], 'o', color='magenta', markersize=10) show_data = Button() def _show_data_fired(self): P_t = self.vis2d.get_P_t() w_0, w_L = self.vis2d.get_w_t() data = np.vstack([w_0, w_L, P_t]).T show_data = DataSheet(data=data) show_data.edit_traits() def plot_tex(self, ax, vot, *args, **kw): self.plot(ax, vot, *args, **kw) traits_view = View(Item('name', style='readonly'), Item('show_legend'), Item('show_data'))
selected_cell = Tuple(Instance(ListItem), Str) selected_cells = List(Tuple(Instance(ListItem), Str)) selected_cell_index = Tuple(Int, Int) selected_cell_indices = List(Tuple(Int, Int)) class ObjectList(HasTraits): values = List(Instance(ListItem)) simple_view = View( Item( "values", show_label=False, editor=TableEditor(columns=[ ObjectColumn(name="value"), ObjectColumn(name="other_value"), ]), ), buttons=["OK"], ) filtered_view = View( Item( "values", show_label=False, editor=TableEditor( columns=[ ObjectColumn(name="value"), ObjectColumn(name="other_value"), ],
class PullOut2LayerSim(Simulator): node_name = 'pull out 2 layer simulation' tree_node_list = List([]) def _tree_node_list_default(self): return [ self.tline, self.loading_scenario, self.mats_eval1, self.cross_section1, self.mats_eval2, self.cross_section2, self.geometry ] def _update_node_list(self): self.tree_node_list = [ self.tline, self.loading_scenario, self.mats_eval1, self.cross_section1, self.mats_eval2, self.cross_section2, self.geometry, ] tree_view = View( Group(Item('mats_eval_type1', resizable=True, full_size=True), Item('mats_eval_type2', resizable=True, full_size=True), Item('control_variable', resizable=True, full_size=True), Item('w_max', resizable=True, full_size=True), Item('n_e_x', resizable=True, full_size=True), Item('fixed_boundary'), Group(Item('loading_scenario@', show_label=False), ))) #========================================================================= # Test setup parameters #========================================================================= loading_scenario = Instance(LoadingScenario, report=True, desc='object defining the loading scenario') def _loading_scenario_default(self): return LoadingScenario() cross_section1 = Instance(CrossSection, report=True, desc='1 cross section parameters') def _cross_section1_default(self): return CrossSection() cross_section2 = Instance(CrossSection, report=True, desc='2 cross section parameters') def _cross_section2_default(self): return CrossSection() geometry = Instance( Geometry, report=True, desc='geometry parameters of the boundary value problem') def _geometry_default(self): return Geometry() control_variable = Enum('u', 'f', auto_set=False, enter_set=True, BC=True) #========================================================================= # Discretization #========================================================================= n_e_x = Int(20, MESH=True, auto_set=False, enter_set=True, symbol='n_\mathrm{E}', unit='-', desc='number of finite elements along the embedded length') #========================================================================= # Algorithimc parameters #========================================================================= k_max = Int(400, unit='\mathrm{mm}', symbol='k_{\max}', desc='maximum number of iterations', ALG=True) tolerance = Float(1e-4, unit='-', symbol='\epsilon', desc='required accuracy', ALG=True) mats_eval_type1 = Trait('multilinear', { 'multilinear': MATSBondSlipMultiLinear, 'damage': MATSBondSlipD, 'elasto-plasticity': MATSBondSlipEP, 'damage-plasticity': MATSBondSlipDP, 'cumulative fatigue': MATSBondSlipFatigue }, MAT=True, desc='material model type') @on_trait_change('mats_eval_type1') def _set_mats_eval1(self): self.mats_eval = self.mats_eval_type1_() self._update_node_list() mats_eval1 = Instance(IMATSEval, report=True) '''Material model 1''' def _mats_eval1_default(self): return self.mats_eval_type_() mats_eval_type2 = Trait('multilinear', { 'multilinear': MATSBondSlipMultiLinear, 'damage': MATSBondSlipD, 'elasto-plasticity': MATSBondSlipEP, 'damage-plasticity': MATSBondSlipDP, 'cumulative fatigue': MATSBondSlipFatigue }, MAT=True, desc='material model type') @on_trait_change('mats_eval_type2') def _set_mats_eval2(self): self.mats_eval = self.mats_eval_type1_() self._update_node_list() mats_eval2 = Instance(IMATSEval, report=True) '''Material model 2''' def _mats_eval2_default(self): return self.mats_eval_type2_() #========================================================================= # Finite element type #========================================================================= fets_eval = Property(Instance(FETS1D52ULRH), depends_on='CS,MAT') '''Finite element time stepper implementing the corrector predictor operators at the element level''' @cached_property def _get_fets_eval(self): return FETS1D52ULRH(A_m=self.cross_section.A_m, P_b=self.cross_section.P_b, A_f=self.cross_section.A_f) dots_grid1 = Property(Instance(XDomainFEInterface1D), depends_on=itags_str) '''Discretization object. ''' @cached_property def _get_dots_grid1(self): geo = self.geometry return XDomainFEInterface1D(dim_u=2, coord_max=[geo.L_x], shape=[self.n_e_x], fets=self.fets_eval) fe_grid1 = Property def _get_fe_grid1(self): return self.dots_grid.mesh dots_grid2 = Property(Instance(XDomainFEInterface1D), depends_on=itags_str) '''Discretization object. ''' @cached_property def _get_dots_grid2(self): geo = self.geometry return XDomainFEInterface1D(dim_u=2, coord_max=[geo.L_x], shape=[self.n_e_x], fets=self.fets_eval) fe_grid2 = Property def _get_fe_grid2(self): return self.dots_grid.mesh domains = Property(depends_on=itags_str) @cached_property def _get_domains(self): return [ (self.dots_grid1, self.mats_eval1), (self.dots_grid2, self.mats_eval2), ] #========================================================================= # Boundary conditions #========================================================================= w_max = Float(1, BC=True, symbol='w_{\max}', unit='mm', desc='maximum pullout slip', auto_set=False, enter_set=True) u_f0_max = Property(depends_on='BC') @cached_property def _get_u_f0_max(self): return self.w_max def _set_u_f0_max(self, value): self.w_max = value fixed_boundary = Enum( 'non-loaded end (matrix)', 'loaded end (matrix)', 'non-loaded end (reinf)', 'clamped left', BC=True, desc= 'which side of the specimen is fixed [non-loaded end [matrix], loaded end [matrix], non-loaded end [reinf]]' ) fixed_dofs = Property(depends_on=itags_str) @cached_property def _get_fixed_dofs(self): if self.fixed_boundary == 'non-loaded end (matrix)': return [0] elif self.fixed_boundary == 'non-loaded end (reinf)': return [1] elif self.fixed_boundary == 'loaded end (matrix)': return [self.controlled_dof - 1] elif self.fixed_boundary == 'clamped left': return [0, 1] controlled_dof = Property(depends_on=itags_str) @cached_property def _get_controlled_dof(self): return 2 + 2 * self.n_e_x - 1 free_end_dof = Property(depends_on=itags_str) @cached_property def _get_free_end_dof(self): return 1 fixed_bc_list = Property(depends_on=itags_str) '''Foxed boundary condition''' @cached_property def _get_fixed_bc_list(self): return [ BCDof(node_name='fixed left end', var='u', dof=dof, value=0.0) for dof in self.fixed_dofs ] control_bc = Property(depends_on=itags_str) '''Control boundary condition - make it accessible directly for the visualization adapter as property ''' @cached_property def _get_control_bc(self): return BCDof(node_name='pull-out displacement', var=self.control_variable, dof=self.controlled_dof, value=self.w_max, time_function=self.loading_scenario) bc_link_dofs = Property(depends_on=itags_str) def _get_bc_link_dofs(self): return BCSlice(name='link_m', slice=self.fe_grid1[:, :], link_slice=self.fe_grid2[:, :], dims=[1], link_coeffs=[-1], value=0) bc = Property(depends_on=itags_str) @cached_property def _get_bc(self): return [self.control_bc, self.link_coeffs] + self.fixed_bc_list X_M = Property() def _get_X_M(self): state = self.tstep.fe_domain[0] return state.xdomain.x_Ema[..., 0].flatten() #========================================================================= # Getter functions @todo move to the PulloutStateRecord #========================================================================= def get_u_p(self, vot): '''Displacement field ''' idx = self.hist.get_time_idx(vot) U = self.hist.U_t[idx] state = self.tstep.fe_domain[0] dof_Epia = state.xdomain.o_Epia fets = state.xdomain.fets u_Epia = U[dof_Epia] N_mi = fets.N_mi u_Emap = np.einsum('mi,Epia->Emap', N_mi, u_Epia) return u_Emap.reshape(-1, 2) def get_eps_Ems(self, vot): '''Epsilon in the components''' state = self.tstep.fe_domain[0] idx = self.hist.get_time_idx(vot) U = self.hist.U_t[idx] return state.xdomain.map_U_to_field(U) def get_eps_p(self, vot): '''Epsilon in the components''' eps_Ems = self.get_eps_Ems(vot) return eps_Ems[..., (0, 2)].reshape(-1, 2) def get_s(self, vot): '''Slip between the two material phases''' eps_Ems = self.get_eps_Ems(vot) return eps_Ems[..., 1].flatten() def get_sig_Ems(self, vot): '''Get streses in the components ''' txdomain = self.tstep.fe_domain[0] idx = self.hist.get_time_idx(vot) U = self.hist.U_t[idx] t_n1 = self.hist.t[idx] eps_Ems = txdomain.xdomain.map_U_to_field(U) state_vars_t = self.tstep.hist.state_vars[idx] state_k = copy.deepcopy(state_vars_t) sig_Ems, _ = txdomain.tmodel.get_corr_pred(eps_Ems, t_n1, **state_k[0]) return sig_Ems def get_sig_p(self, vot): '''Epsilon in the components''' sig_Ems = self.get_sig_Ems(vot) return sig_Ems[..., (0, 2)].reshape(-1, 2) def get_sf(self, vot): '''Get the shear flow in the interface ''' sig_Ems = self.get_sig_Ems(vot) return sig_Ems[..., 1].flatten() def get_shear_integ(self): # d_ECid = self.get_d_ECid(vot) # s_Emd = np.einsum('Cim,ECid->Emd', self.tstepper.sN_Cim, d_ECid) # idx = self.tloop.get_time_idx(vot) # sf = self.tloop.sf_Em_record[idx] sf_t_Em = np.array(self.tloop.sf_Em_record) w_ip = self.fets_eval.ip_weights J_det = self.tstepper.J_det P_b = self.cross_section.P_b shear_integ = np.einsum('tEm,m,em->t', sf_t_Em, w_ip, J_det) * P_b return shear_integ def get_Pw_t(self): sim = self c_dof = sim.controlled_dof f_dof = sim.free_end_dof U_ti = sim.hist.U_t F_ti = sim.hist.F_t P = F_ti[:, c_dof] w_L = U_ti[:, c_dof] w_0 = U_ti[:, f_dof] return P, w_0, w_L #========================================================================= # Plot functions #========================================================================= def plot_u_p(self, ax, vot, label_m='matrix', label_f='reinf'): X_M = self.X_M L = self.geometry.L_x u_p = self.get_u_p(vot).T ax.plot(X_M, u_p[0], linewidth=2, color='blue', label=label_m) ax.fill_between(X_M, 0, u_p[0], facecolor='blue', alpha=0.2) ax.plot(X_M, u_p[1], linewidth=2, color='orange', label=label_f) ax.fill_between(X_M, 0, u_p[1], facecolor='orange', alpha=0.2) ax.plot([0, L], [0, 0], color='black') ax.set_ylabel('displacement') ax.set_xlabel('bond length') ax.legend(loc=2) return np.min(u_p), np.max(u_p) def plot_eps_p(self, ax, vot, label_m='matrix', label_f='reinf'): X_M = self.X_M L = self.geometry.L_x eps_p = self.get_eps_p(vot).T ax.plot(X_M, eps_p[0], linewidth=2, color='blue', label=label_m) ax.fill_between(X_M, 0, eps_p[0], facecolor='blue', alpha=0.2) ax.plot(X_M, eps_p[1], linewidth=2, color='orange', label=label_f) ax.fill_between(X_M, 0, eps_p[1], facecolor='orange', alpha=0.2) ax.plot([0, L], [0, 0], color='black') ax.set_ylabel('strain') ax.set_xlabel('bond length') return np.min(eps_p), np.max(eps_p) def plot_sig_p(self, ax, vot): X_M = self.X_M sig_p = self.get_sig_p(vot).T # A_m = self.cross_section.A_m # A_f = self.cross_section.A_f L = self.geometry.L_x F_m = sig_p[0] F_f = sig_p[1] ax.plot( X_M, F_m, linewidth=2, color='blue', ) ax.fill_between(X_M, 0, F_m, facecolor='blue', alpha=0.2) ax.plot(X_M, F_f, linewidth=2, color='orange') ax.fill_between(X_M, 0, F_f, facecolor='orange', alpha=0.2) ax.plot([0, L], [0, 0], color='black') ax.set_ylabel('stress [MPa]') ax.set_xlabel('bond length') F_min = min(np.min(F_m), np.min(F_f)) F_max = max(np.max(F_m), np.max(F_f)) return F_min, F_max def plot_s(self, ax, vot): X_J = self.X_M s = self.get_s(vot) ax.fill_between(X_J, 0, s, facecolor='lightcoral', alpha=0.3) ax.plot(X_J, s, linewidth=2, color='lightcoral') ax.set_ylabel('slip') ax.set_xlabel('bond length') return np.min(s), np.max(s) def plot_sf(self, ax, vot): X_J = self.X_M sf = self.get_sf(vot) ax.fill_between(X_J, 0, sf, facecolor='lightcoral', alpha=0.3) ax.plot(X_J, sf, linewidth=2, color='lightcoral') ax.set_ylabel('shear flow') ax.set_xlabel('bond length') return np.min(sf), np.max(sf) def plot_omega(self, ax, vot): X_J = self.X_J omega = self.get_omega(vot) ax.fill_between(X_J, 0, omega, facecolor='lightcoral', alpha=0.3) ax.plot(X_J, omega, linewidth=2, color='lightcoral', label='bond') ax.set_ylabel('damage') ax.set_xlabel('bond length') ax.legend(loc=2) return 0.0, 1.05 def plot_eps_s(self, ax, vot): eps_p = self.get_eps_p(vot).T s = self.get_s(vot) ax.plot(eps_p[1], s, linewidth=2, color='lightcoral') ax.set_ylabel('reinforcement strain') ax.set_xlabel('slip') def get_window(self): self.record['Pw'] = PulloutRecord() fw = Viz2DPullOutFW(name='pullout-curve', vis2d=self.hist['Pw']) u_p = Viz2DPullOutField(name='displacement along the bond', plot_fn='u_p', vis2d=self) eps_p = Viz2DPullOutField(name='strain along the bond', plot_fn='eps_p', vis2d=self) sig_p = Viz2DPullOutField(name='stress along the bond', plot_fn='sig_p', vis2d=self) s = Viz2DPullOutField(name='slip along the bond', plot_fn='s', vis2d=self) sf = Viz2DPullOutField(name='shear flow along the bond', plot_fn='sf', vis2d=self) energy = Viz2DEnergyPlot(name='energy', vis2d=self.hist['Pw']) dissipation = Viz2DEnergyReleasePlot(name='energy release', vis2d=self.hist['Pw']) w = BMCSWindow(sim=self) w.viz_sheet.viz2d_list.append(fw) w.viz_sheet.viz2d_list.append(u_p) w.viz_sheet.viz2d_list.append(eps_p) w.viz_sheet.viz2d_list.append(sig_p) w.viz_sheet.viz2d_list.append(s) w.viz_sheet.viz2d_list.append(sf) w.viz_sheet.viz2d_list.append(energy) w.viz_sheet.viz2d_list.append(dissipation) w.viz_sheet.monitor_chunk_size = 10 return w
class CombinationTable(HasTraits): row_set = List(Tuple()) col_set = List(Tuple()) rows = List(Row) cols = List() selected_row = Any() combination_updated = Event() def __init__(self, *args, **kwargs): super(CombinationTable, self).__init__(*args, **kwargs) self._generate_combinations() # FIXME: Implement automatic update of table based on # change to row and col set. But I need to implemnt this # and to preserv the selection already made. #@on_trait_change('row_set, col_set', post_init=True) #def _update_table(self, obj, name, new): # print("Name list changed") # self._generate_combinations() # self.update_names() def get_selected_combinations(self): combinations = [] for row in self.rows: for i, cn in enumerate(self.col_set): an = 'ck{0}'.format(i) if getattr(row, an): cmb = (row.nid, cn[0]) combinations.append(cmb) return combinations def update_names(self): for i in self.row_set: for row in self.rows: if row.nid == i[0]: row.name = i[1] for i,col in enumerate(self.col_set): self.cols[i+1].label = col[1] @on_trait_change('rows.ck+') def _selection_changed(self, obj, name, old, new): self.combination_updated = True def _generate_combinations(self): if not self.row_set: self.row_set.append(('a','')) self.rows = [] for row in self.row_set: ro = Row() ro.nid = row[0] ro.name = row[1] for i in range(len(self.col_set)): an = 'ck{0}'.format(i) setattr(ro, an, False) self.rows.append(ro) self._define_columns() def _define_columns(self): self.cols = [] oc = ObjectColumn(name='name', editable=False) self.cols.append(oc) for i, cn in enumerate(self.col_set): cc = CombCheck() cc.name = 'ck{0}'.format(i) cc.label = cn[1] self.cols.append(cc) traits_view = View( Item('rows', editor=table_editor, show_label=False), resizable=True, ) test_view = View( Item('rows', editor=table_editor, show_label=False), resizable=True, width=300, height=200, )
class MATS1D5PressureSensitive(MATS1D5Eval): ur'''Bond model for two phases interacting over an interface with zero thickness. The frictional resistance is governed by the current level of pressure using the cohesion :math:`c` and frictional angle :math`\phi`. Basic formulas The threshold level of frictional stress is prescribed by the Mohr-Coulomb rule: .. math:: \tau_\mathrm{fr}(\sigma) = \left( c + \sigma \; \tan{(\phi)} \right) H\left( \sigma - \frac{c}{\tan{(\phi)}}\right) :label: eq_MATS1D5PressureSensitive The deformation variables include interface opening :math:`w` and sliding :math:`s` related to the stress variables using the equations .. math:: \tau = G_s \cdot ( s - s^p ) .. math:: \sigma = \left( G_w^{(+)} H(w) + G_w^{(-)} H(-w) \right) \cdot w where - :math:`G_s` represents elastic shear stiffness, - :math:`G_w^{(+)}` is the adhesive stiffness for crack opening and - :math:`G_w^{(-)}` is the penetration (or penalty) stiffness to be set large. The elastic domain is given by the yield condition .. math:: f := \left| \tau \right| - \tau_\mathrm{fr}(\sigma) \leq 0 Thus, the Kuhn-Tucker condition must hold: .. math:: \dot{\gamma} \geq 0, \; f( \sigma, \tau ) \cdot \gamma \leq 0, \; \dot{\gamma} f(\sigma, \tau) = 0 where :math:`\gamma` represents the plastic multiplier. The flow rule for yielding slip is provided as .. math:: \dot{s}_p = \dot{\gamma} \; \mathrm{sign}(\tau) and the consistency condition (staying on the yield surface upon platic loading) .. math:: \dot{\gamma} \dot{f}(\sigma, \tau) = 0 Discrete form Using the midpoint rule Given the displacement increment .. math:: s_{n+1} = s_{n} + \Delta s_{n}, \; w_{n+1} = w_{n} + \Delta w_{n}, \; :label: eq_increment the elastic trial stresses are calculated as .. math:: \tau_{n+1}^{\mathrm{trial}} = G_s ( s_{n+1} - s_n^p ), \; \sigma_{n+1} = G_w ( w_{n+1} ) :label: eq_constitutive_law and the frictional threshold for the current transverse stresses .. math:: \tau^\mathrm{fr}_{n+1}(\sigma_{n+1}) = \left( c + \sigma_{n+1} \; \tan{(\phi)} \right) H\left( \sigma_{n+1} - \frac{c}{\tan{(\phi)}}\right) :label: eq_mohr_coulomb The trial consistency condition is obtained as .. math:: f_{n+1}^\mathrm{trial} = \left| \tau_{n+1}^\mathrm{trial} \right| - \tau^\mathrm{fr}_{n+1}(\sigma_{n+1}) :label: eq_discr_consistency If :math:`f^\mathrm{trial}_{n+1} \leq 0` then step is elastic. If :math:`f^\mathrm{trial}_{n+1} > 0 \Leftrightarrow f(\tau_{n+1}, \sigma_{n+1} ) = 0` The objective is to identify :math:`s^{p}_{n+1}, \Delta \gamma` satisfying this condition and the condition of consistency. To accomplish this task we first note that .. math:: \tau_{n+1}= G_s( s_{n+1} - s^p_{n+1} ) =G_s( s_{n+1} - s^p_{n}) - G_s( s^p_{n+1} - s^p_n ) Using Eq.:eq:`eq_midpoint` the shear stress can be related to trial state and the plastic (return mapping) multiplier :math:`\Delta \gamma` as .. math:: \tau_{n+1} = \tau^{\mathrm{trial}}_{n+1} - G_s( s^p_{n+1} - s^p_n ) = \tau^{\mathrm{trial}}_{n+1} - G_s \Delta \gamma \, \mathrm{sign}( \tau_{n+1} ). The other two incremental equation deliver the plastic slip and consistency condition. .. math:: s^{p}_{n+1} = s^p_n + \Delta \gamma \, \mathrm{sign}( \tau_{n+1} ) :label: eq_midpoint .. math:: f_{n+1} = \left| \tau_{n+1} \right| - \tau^{\mathrm{fr}}(\sigma_{n+1}) = 0 :label: eq_discr_consistency2 It can be shown that the direction of mapping given by :math:`\mathrm{sign}(\tau_{n+1})` is consistent with the trial state, i,e. :math:`\mathrm{sign}(\tau^{\mathrm{trial}}_{n+1})` and .. math:: \left| \tau_{n+1} \right| + \Delta \gamma G_s = \left| \tau^{\mathrm{trial}}_{n+1} \right| Finally, due to :math:`\Delta \gamma > 0` the discrete consistency condition (:eq:`eq_discr_consistency`) can be further expanded as .. math:: f_{n+1} = \left| \tau^{\mathrm{trial}}_{n+1} \right| - G_s \Delta \gamma- \tau^{\mathrm{fr}}( \sigma_{n+1} ) Hence .. math:: f_{n+1} = 0 \implies \Delta \gamma = \frac{ f^{\mathrm{trial}}_{n+1}}{ G_s } > 0 and .. math:: \tau_{n+1} &= \tau^{\mathrm{trial}}_{n+1} - \Delta \gamma G_s \, \mathrm{sign}( \tau_{n+1}^{\mathrm{trial}} ) \\ s^p_{n+1} &= s^p_n + \Delta \gamma \, \mathrm{sign}( \tau_{n+1}^{\mathrm{trial}} ) \\ ''' implements(IMATSEval) G_s = Float(1.0, input = True, enter_set = False, label = 'cohesion') G_w_open = Float(1.0, input = True, enter_set = False, label = 'cohesion') G_w_close = Float(1e+6, input = True, enter_set = False, label = 'cohesion') c = Float(0.0, input = True, enter_set = False, label = 'cohesion') phi = Float(0.1, input = True, enter_set = False, label = 'friction angle') #----------------------------------------------------------------------------------------------- # Submodels constituting the interface behavior #----------------------------------------------------------------------------------------------- traits_view = View(Item('c@'), Item('phi@'), Item('G_open@'), Item('G_slip@'), Item('G_penalty@'), resizable = True, scrollable = True, width = 0.8, height = 0.9, buttons = ['OK', 'Cancel']) #----------------------------------------------------------------------------------------------- # Setup for computation within a supplied spatial context #----------------------------------------------------------------------------------------------- def get_state_array_size(self): ''' Return the number of floats to be saved ''' return 1 #----------------------------------------------------------------------------------------------- # Evaluation - get the corrector and predictor #----------------------------------------------------------------------------------------------- def get_corr_pred(self, sctx, eps_app_eng, d_eps_app_eng, tn, tn1, *args, **kw): ''' Corrector predictor computation. @param eps_app_eng input variable - engineering strain ''' eps1, s, w, eps2 = eps_app_eng d_eps1, d_s, d_w, e_eps2 = eps_app_eng sig_app_eng = zeros_like(eps_app_eng) if sctx.update_state_on: slip_n = s - d_s slip_p_n = slip_n # get the plastic slip sctx.mats_state_array[0] = slip_p_n # @todo [rch] dirty - when called form response tracer if isinstance(d_eps_app_eng, int) and d_eps_app_eng == 0: d_eps_app_eng = zeros_like(eps_app_eng) s_n = s s_p_n = sctx.mats_state_array[0] f_separate = (Heaviside(w) * self.G_open + Heaviside(-w) * self.G_penalty) * w n = self.G_penalty tau_trial = self.G_slip * (s_n - s_p_n); f_trial = abs(tau_trial) - (f_separate + math.tan(self.phi)); if f_trial <= 1e-8: sig_n1[2] = tau_trial; D_n1[0, 0] = E; else: d_gamma = f_trial / (self.E + self.K_bar + self.H_bar); sig_n1[0] = sigma_trial - d_gamma * self.E * sign(xi_trial); D_n1[0, 0] = (self.E * (self.K_bar + self.H_bar)) / \ (self.E + self.K_bar + self.H_bar); sig_n1 = zeros((1,), dtype = 'float_') D_n1 = zeros((1, 1), dtype = 'float_') D_mtx = zeros((eps_app_eng.shape[0], eps_app_eng.shape[0]), dtype = 'float_') return sig_app_eng, D_mtx def get_sig1(self, sctx, eps_app_eng, *args, **kw): sig_eng, D_mtx = self.get_corr_pred(sctx, eps_app_eng, 0, 0, 0) return sig_eng[0:1] def get_sig2(self, sctx, eps_app_eng, *args, **kw): sig_eng, D_mtx = self.get_corr_pred(sctx, eps_app_eng, 0, 0, 0) return sig_eng[3:] def get_shear_flow(self, sctx, eps_app_eng, *args, **kw): sig_eng, D_mtx = self.get_corr_pred(sctx, eps_app_eng, 0, 0, 0) return sig_eng[1:2] def get_cohesive_stress(self, sctx, eps_app_eng, *args, **kw): sig_eng, D_mtx = self.get_corr_pred(sctx, eps_app_eng, 0, 0, 0) return sig_eng[2:3] rte_dict = Property def _get_rte_dict(self): rte_dict = {} ix_maps = [0, 1, 2, 3] for name, mats, ix_map, size, offset in \ zip(self._mats_names, self._mats_list, ix_maps, self._state_sizes, self._state_offsets): for key, v_eval in mats.rte_dict.items(): __call_v_eval = RTE1D5Bond(v_eval = v_eval, name = name + '_' + key, size = size, offset = offset, ix_map = ix_map) rte_dict[ name + '_' + key ] = __call_v_eval # sigma is also achievable through phase1_sig_app and phase_2_sig_app extra_rte_dict = {'sig1' : self.get_sig1, 'sig2' : self.get_sig2, 'shear_flow' : self.get_shear_flow, 'cohesive_stress' : self.get_cohesive_stress, } rte_dict.update(extra_rte_dict) return rte_dict #------------------------------------------------------------------------------------- # Methods required by the mats_explore tool #------------------------------------------------------------------------------------- def new_cntl_var(self): return zeros(4, 'float_') def new_resp_var(self): return zeros(4, 'float_')
class Person(HasTraits): first_name = Str() last_name = Str() age = Int() gender = Trait(None, 'M', 'F') name_view = View('first_name', 'last_name')
class ExpBT4PTRF(ExType): '''Experiment: Bending Test Four Point with RetroFitting beam ''' # label = Str('four point bending test') implements(IExType) file_ext = 'DAT' #-------------------------------------------------------------------- # register a change of the traits with metadata 'input' #-------------------------------------------------------------------- input_change = Event @on_trait_change('+input, ccs.input_change, +ironing_param') def _set_input_change(self): self.input_change = True #------------------------------------------------------------------------- # specify inputs: #------------------------------------------------------------------------- # effective length of the bending test specimen # (does not include the part at each side of the specimens that leaps over the support lines) # length = Float(3.30, unit='m', input=True, table_field=True, auto_set=False, enter_set=True) length_loadintroduction = Float(0.70, unit='m', input=True, table_field=True, auto_set=False, enter_set=True) width = Float(0.50, unit='m', input=True, table_field=True, auto_set=False, enter_set=True) thickness = Float(0.20, unit='m', input=True, table_field=True, auto_set=False, enter_set=True) # age of the concrete at the time of testing age = Int(28, unit='d', input=True, table_field=True, auto_set=False, enter_set=True) loading_rate = Float(1.0, unit='mm/min', input=True, table_field=True, auto_set=False, enter_set=True) gauge_length_horizontal = Float(0.40, unit='m', input=True, table_field=True, auto_set=False, enter_set=True) # additional own weight of the steel traverse and steel rolls used for # load introduction weight_load_introduction = Float(1.3, unit='kN', input=True, table_field=True, auto_set=False, enter_set=True) #-------------------------------------------------------------------------- # composite cross section #-------------------------------------------------------------------------- ccs = Instance(CompositeCrossSection) def _ccs_default(self): '''default settings' ''' # SFB 532 - demonstrator textil and concrete: fabric_layout_key = 'CAR-3300-SBR_BTZ2' concrete_mixture_key = 'Pagel_TF10' orientation_fn_key = 'all0' n_layers = 2 s_tex_z = 0.015 / (n_layers + 1) ccs = CompositeCrossSection(fabric_layup_list=[ plain_concrete(s_tex_z * 0.5), FabricLayUp(n_layers=n_layers, orientation_fn_key=orientation_fn_key, s_tex_z=s_tex_z, fabric_layout_key=fabric_layout_key), plain_concrete(s_tex_z * 0.5) ], concrete_mixture_key=concrete_mixture_key) return ccs #-------------------------------------------------------------------------- # Get properties of the composite #-------------------------------------------------------------------------- # E-modulus of the composite at the time of testing E_c = Property(Float, unit='MPa', depends_on='input_change', table_field=True) def _get_E_c(self): return self.ccs.get_E_c_time(self.age) # E-modulus of the composite after 28 days E_c28 = DelegatesTo('ccs', listenable=False) # reinforcement ration of the composite rho_c = DelegatesTo('ccs', listenable=False) #------------------------------------------------------------------------- # define processing #------------------------------------------------------------------------- # put this into the ironing procedure processor # jump_rtol = Float(0.9, auto_set=False, enter_set=True, ironing_param=True) data_array_ironed = Property( Array(float), depends_on='data_array, +ironing_param, +axis_selection') @cached_property def _get_data_array_ironed(self): '''remove the jumps in the displacement curves due to resetting the displacement gauges. ''' print '*** curve ironing activated ***' # each column from the data array corresponds to a measured parameter # e.g. displacement at a given point as function of time u = f(t)) # data_array_ironed = copy(self.data_array) for idx in range(self.data_array.shape[1]): # use ironing method only for columns of the displacement gauges. # # print 'self.names_and_units[0]',self.names_and_units[0] # print 'self.names_and_units',self.names_and_units if self.names_and_units[0][idx] in { 'WA_M1', 'WA_M2', 'WA_L', 'WA_R' }: # 1d-array corresponding to column in data_array data_arr = copy(data_array_ironed[:, idx]) # get the difference between each point and its successor jump_arr = data_arr[1:] - data_arr[0:-1] # get the range of the measured data data_arr_range = max(data_arr) - min(data_arr) # determine the relevant criteria for a jump # based on the data range and the specified tolerances: jump_crit = self.jump_rtol * data_arr_range # get the indexes in 'data_column' after which a # jump exceeds the defined tolerance criteria jump_idx = where(fabs(jump_arr) > jump_crit)[0] print 'number of jumps removed in data_arr_ironed for', self.names_and_units[ 0][idx], ': ', jump_idx.shape[0] print 'force', unique(around(-self.data_array[jump_idx, 1], 2)) # glue the curve at each jump together for jidx in jump_idx: # get the offsets at each jump of the curve shift = data_arr[jidx + 1] - data_arr[jidx] # shift all succeeding values by the calculated offset data_arr[jidx + 1:] -= shift data_array_ironed[:, idx] = data_arr[:] return data_array_ironed def process_source_data(self): '''read in the measured data from file and assign attributes after array processing. If necessary modify the assigned data, i.e. change the sign or specify an offset for the specific test setup. ''' print '*** process source data ***' super(ExpBT4PTRF, self).process_source_data() self._read_data_array() # curve ironing: # self.processed_data_array = self.data_array_ironed # set attributes: # self._set_array_attribs() # PEEKEL-measuring software: # convert units and change signs self.Kraft -= self.Kraft[0] self.Kraft *= -1 # add weight of load introduction to force print 'add weight of steel traverse to force' self.Kraft += self.weight_load_introduction print 'force at initial state ', self.weight_load_introduction # @todo: interpolate an initial deformation based on the initial force and the initial stiffness # measured in order to start the F-w-curve at the origin! # (reset displacement gauges by their initial values and change sign # in order to return a positive value for a displacement) # vertical displacements [mm]: self.WA_M1 -= self.WA_M1[0] self.WA_M1 *= -1 self.WA_M2 -= self.WA_M2[0] self.WA_M2 *= -1 self.WA_L -= self.WA_L[0] self.WA_L *= -1 self.WA_R -= self.WA_R[0] self.WA_R *= -1 # horizontal displacements at the bottom side of the bending specimen # [mm] self.WA_HR -= self.WA_HR[0] self.WA_HR *= -1 self.WA_HM -= self.WA_HM[0] self.WA_HM *= -1 self.WA_HL -= self.WA_HL[0] self.WA_HL *= -1 # optional additional displacement gauges for crack width measuring of # shear cracks self.Schub1 -= self.Schub1[0] self.Schub1 *= -1 self.Schub1 -= self.Schub1[0] self.Schub1 *= -1 # DMS for steel bars on vertical shear reinforcement self.VL2 -= self.VL2[0] self.VL2 *= -1 self.VL3 -= self.VL3[0] self.VL3 *= -1 self.VR2 -= self.VR2[0] self.VR2 *= -1 self.VR3 -= self.VR3[0] self.VR3 *= -1 # compressive strain at the upper side of the bending specimen at midspan [mm] # change unite from [nm/m], i.e. [10^(-6)*m / m], to [mm/m=permille] self.CM -= self.CM[0] self.CM /= 1000. self.CML -= self.CML[0] self.CML /= 1000. self.CMR -= self.CMR[0] self.CMR /= 1000. # DMS for longitudinal steel bars self.SL -= self.SL[0] self.SL /= 1000. self.SML -= self.SML[0] self.SML /= 1000. self.SR -= self.SR[0] self.SR /= 1000. self.SMR -= self.SMR[0] self.SMR /= 1000. self.SM1 -= self.SM1[0] self.SM1 /= 1000. self.SM2 -= self.SM2[0] self.SM2 /= 1000. # set attributes of displacement (original data before ironing): # WA_M1_orig = np.copy(self.WA_M1) self.add_trait("WA_M1_orig", Array(value=WA_M1_orig, transient=True)) WA_M2_orig = np.copy(self.WA_M2) self.add_trait("WA_M2_orig", Array(value=WA_M2_orig, transient=True)) WA_R_orig = np.copy(self.WA_R) self.add_trait("WA_R_orig", Array(value=WA_R_orig, transient=True)) WA_L_orig = np.copy(self.WA_L) self.add_trait("WA_L_orig", Array(value=WA_L_orig, transient=True)) K_bending_elast_c = Property(Array('float_'), depends_on='input_change') @cached_property def _get_K_bending_elast_c(self): '''calculate the analytical bending stiffness of the beam (4 point bending) relation between center deflection and 2 * load/2 in the thirdpoints (sum up to F) ''' # @todo: update formula to be calculated based on 'with',total 'length' and 'lenght_loadintroduction' t = self.thickness w = self.width L = self.length L_load = self.length_loadintroduction # coposite E-modulus # E_c = self.E_c # moment of inertia # I_yy = t**3 * w / 12. delta_11 = (L**3) / 56.348 / E_c / I_yy # [MN/m]=[kN/mm] bending stiffness with respect to a force applied at center of the beam # K_bending_elast_c = 1 / delta_11 # print 'K_bending_elast_c', K_bending_elast_c print 'K_bending_elast_c', K_bending_elast_c return K_bending_elast_c #------------------------------------------------------------------------- # plot templates #------------------------------------------------------------------------- plot_templates = { 'force / deflection (center)': '_plot_force_deflection_center', 'force / deflection (center) - original': '_plot_force_deflection_center_orig', 'force / deflection (thirdpoints)': '_plot_force_deflection_thirdpoints', 'strain (top/bottom) / force': '_plot_strain_top_bottom_force', 'displacement (ironed/original - center)': '_plot_ironed_orig_force_deflection_center', 'displacement (ironed/original - left)': '_plot_ironed_orig_force_deflection_left', 'displacement (ironed/original - right)': '_plot_ironed_orig_force_deflection_right', } default_plot_template = 'force / deflection (center)' # get only the ascending branch of the response curve # max_force_idx = Property(Int) def _get_max_force_idx(self): '''get the index of the maximum force''' # NOTE: processed data returns positive values for force and # displacement return argmax(self.Kraft) def _plot_force_deflection_center(self, axes, offset_w=0., color='black', linewidth=1., label=None): # get only the ascending branch of the response curve f_asc = self.Kraft[:self.max_force_idx + 1] w_asc_M1 = self.WA_M1[:self.max_force_idx + 1] w_asc_M2 = self.WA_M2[:self.max_force_idx + 1] w_asc_Mavg = (w_asc_M1 + w_asc_M2) / 2. # add curves # axes.plot(w_asc_Mavg, f_asc, linewidth=linewidth, label=label, color=color) # add axes labels # xkey = 'deflection [mm]' ykey = 'force [kN]' axes.set_xlabel('%s' % (xkey, )) axes.set_ylabel('%s' % (ykey, )) def _plot_force_deflection_center_orig(self, axes, offset_w=0., color='black', linewidth=1., label=None): '''plot the original data before jumps has been processed out ''' # get the ascending AND unloading branch of the response curve f = self.Kraft w_M1_orig = self.WA_M1_orig w_M2_orig = self.WA_M2_orig w_Mavg_orig = (w_M1_orig + w_M2_orig) / 2. # get only the ascending branch of the response curve f_asc = self.Kraft[:self.max_force_idx + 1] w_asc_M1_orig = self.WA_M1_orig[:self.max_force_idx + 1] w_asc_M2_orig = self.WA_M2_orig[:self.max_force_idx + 1] w_asc_Mavg_orig = (w_asc_M1_orig + w_asc_M2_orig) / 2. # add curves # # axes.plot(w_asc_Mavg_orig, f_asc, linewidth=linewidth, label=label, color=color) axes.plot(w_Mavg_orig, f, linewidth=linewidth, label=label, color=color) # add axes labels # xkey = 'deflection [mm]' ykey = 'force [kN]' axes.set_xlabel('%s' % (xkey, )) axes.set_ylabel('%s' % (ykey, )) def _plot_force_deflection_thirdpoints(self, axes): '''deflection at the third points (under the loading points) ''' # get only the ascending branch of the response curve f_asc = self.Kraft[:self.max_force_idx + 1] # displacement left w_l_asc = self.WA_L[:self.max_force_idx + 1] # displacement right w_r_asc = self.WA_R[:self.max_force_idx + 1] axes.plot(w_l_asc, f_asc, color='green', linewidth=1) axes.plot(w_r_asc, f_asc, color='green', linewidth=1) def _plot_strain_top_bottom_force(self, axes, color='black', linewidth=1., label=None): '''plot compressive strains at top and average tensile strains based on horizontal displacement gauges ''' # get only the ascending branch of the response curve f_asc = self.Kraft[:self.max_force_idx + 1] # compressive strains (top) [permile] eps_CM = self.CM[:self.max_force_idx + 1] eps_CMR = self.CMR[:self.max_force_idx + 1] eps_CML = self.CML[:self.max_force_idx + 1] # tensile strain (bottom) [permile]; eps_HL = self.WA_HL[:self.max_force_idx + 1] / \ self.gauge_length_horizontal eps_HM = self.WA_HM[:self.max_force_idx + 1] / \ self.gauge_length_horizontal eps_HR = self.WA_HR[:self.max_force_idx + 1] / \ self.gauge_length_horizontal # add curves # axes.plot(eps_CM, f_asc, linewidth=linewidth, label='compression: eps_CM', color='grey') axes.plot(eps_CMR, f_asc, linewidth=linewidth, label='compression: eps_CMR', color='grey') axes.plot(eps_CML, f_asc, linewidth=linewidth, label='compression: eps_CML', color='grey') axes.plot(eps_HL, f_asc, linewidth=linewidth, label='tension: eps_HL', color='k') axes.plot(eps_HM, f_asc, linewidth=linewidth, label='tension: eps_HM', color='k') axes.plot(eps_HR, f_asc, linewidth=linewidth, label='tension: eps_HR', color='k') # add axes labels # xkey = 'strain [1*e-3]' ykey = 'force [kN]' axes.set_xlabel('%s' % (xkey, )) axes.set_ylabel('%s' % (ykey, )) def _plot_avg_strain_bottom_force(self, axes, color='black', linewidth=1., label=None): '''plot compressive strains at top and average tensile strains based on horizontal displacement gauges ''' # get only the ascending branch of the response curve f_asc = self.Kraft # [:self.max_force_idx + 1] # tensile strain (bottom) [permile]; eps_HL = self.WA_HL / \ self.gauge_length_horizontal eps_HM = self.WA_HM / \ self.gauge_length_horizontal eps_HR = self.WA_HR / \ self.gauge_length_horizontal # add curves # # axes.plot(eps_HL, f_asc, linewidth=linewidth, # label= label + ' WA: HL', color='k') # axes.plot(eps_HM, f_asc, linewidth=linewidth, # label= label + ' WA: HM', color='g') axes.plot(eps_HR, f_asc, linewidth=linewidth, label=label + ' WA: HR', color='k') # add axes labels # xkey = 'strain [1*e-3]' ykey = 'force [kN]' axes.set_xlabel('%s' % (xkey, )) axes.set_ylabel('%s' % (ykey, )) def _plot_ironed_orig_force_deflection_center(self, axes): '''plot original displacement (center) as measured by the displacement gauge and compare with curve after data has been processed by ironing procedure ''' # get only the ascending branch of the response curve F_asc = self.Kraft[:self.max_force_idx + 1] w_ironed_asc = self.WA_M1[:self.max_force_idx + 1] w_orig_asc = self.WA_M1_orig[:self.max_force_idx + 1] # add curves # axes.plot(w_ironed_asc, F_asc, color='blue', linewidth=1.5) axes.plot(w_orig_asc, F_asc, color='grey', linewidth=1.5) # add axes labels # xkey = 'deflection (original data / ironed data) [mm]' ykey = 'force [kN]' axes.set_xlabel('%s' % (xkey, )) axes.set_ylabel('%s' % (ykey, )) def _plot_ironed_orig_force_deflection_left(self, axes): '''plot original displacement (left) as measured by the displacement gauge and compare with curve after data has been processed by ironing procedure ''' w_ironed = self.WA_L w_orig = self.WA_L_orig F = self.Kraft axes.plot(w_ironed, F) axes.plot(w_orig, F) xkey = 'deflection (original data / ironed data) [mm]' ykey = 'force [kN]' axes.set_xlabel('%s' % (xkey, )) axes.set_ylabel('%s' % (ykey, )) def _plot_ironed_orig_force_deflection_right(self, axes): '''plot original displacement (left) as measured by the displacement gauge and compare with curve after data has been processed by ironing procedure ''' w_ironed = self.WA_R w_orig = self.WA_R_orig F = self.Kraft axes.plot(w_ironed, F) axes.plot(w_orig, F) xkey = 'deflection (original data / ironed data) [mm]' ykey = 'force [kN]' axes.set_xlabel('%s' % (xkey, )) axes.set_ylabel('%s' % (ykey, )) #------------------------------------------------------------------------- # view #------------------------------------------------------------------------- traits_view = View(VGroup( Group(Item('length', format_str="%.3f"), Item('length_loadintroduction', format_str="%.3f"), Item('width', format_str="%.3f"), Item('thickness', format_str="%.3f"), label='geometry'), Group(Item('weight_load_introduction'), Item('loading_rate'), Item('gauge_length_horizontal'), Item('age'), label='loading rate and age'), Group(Item('jump_rtol', format_str="%.4f"), label='curve_ironing'), Group(Item('E_c', show_label=True, style='readonly', format_str="%.0f"), Item('ccs@', show_label=False), label='composite cross section')), scrollable=True, resizable=True, height=0.8, width=0.6)
def traits_view(self): v = View(UItem('component', editor=ComponentEditor())) return v
def traits_view(self): v = View(HGroup(Item('auto_title'), UItem('title', enabled_when='not auto_title'), icon_button_editor('options_button', 'cog'))) return v
"""This demo shows how to use Traits TreeEditors with PyTables to walk the heirarchy of an HDF5 file. This only picks out arrays and groups, but could easily be extended to other structures, like tables. In the demo, the path to the selected item is printed whenever the selection changes. In order to run, a path to an existing HDF5 database must be given at the bottom of this file. """ from traits.api import HasTraits, Str, List, Instance from traitsui.api import TreeEditor, TreeNode, View, Item, Group import tables as tb # View for objects that aren't edited no_view = View() # HDF5 Nodes in the tree class Hdf5ArrayNode(HasTraits): name = Str('<unknown>') path = Str('<unknown>') parent_path = Str('<unknown>') class Hdf5GroupNode(HasTraits): name = Str('<unknown>') path = Str('<unknown>') parent_path = Str('<unknown>') # Can't have recursive traits? Really? #groups = List( Hdf5GroupNode )
class PlotUI(HasTraits): # container for all plots container = Instance(HPlotContainer) # Plot components within this container: polyplot = Instance(ContourPolyPlot) lineplot = Instance(ContourLinePlot) cross_plot = Instance(Plot) cross_plot2 = Instance(Plot) colorbar = Instance(ColorBar) # plot data pd = Instance(ArrayPlotData) # view options num_levels = Int(15) colormap = Enum(colormaps) #Traits view definitions: traits_view = View(Group( UItem('container', editor=ComponentEditor(size=(800, 600)))), resizable=True) plot_edit_view = View(Group(Item('num_levels'), Item('colormap')), buttons=["OK", "Cancel"]) #--------------------------------------------------------------------------- # Private Traits #--------------------------------------------------------------------------- _image_index = Instance(GridDataSource) _image_value = Instance(ImageData) _cmap = Trait(default_colormaps.jet, Callable) #--------------------------------------------------------------------------- # Public View interface #--------------------------------------------------------------------------- def __init__(self, *args, **kwargs): super(PlotUI, self).__init__(*args, **kwargs) # FIXME: 'with' wrapping is temporary fix for infinite range in initial # color map, which can cause a distracting warning print. This 'with' # wrapping should be unnecessary after fix in color_mapper.py. with errstate(invalid='ignore'): self.create_plot() def create_plot(self): # Create the mapper, etc self._image_index = GridDataSource(array([]), array([]), sort_order=("ascending", "ascending")) image_index_range = DataRange2D(self._image_index) self._image_index.on_trait_change(self._metadata_changed, "metadata_changed") self._image_value = ImageData(data=array([]), value_depth=1) image_value_range = DataRange1D(self._image_value) # Create the contour plots self.polyplot = ContourPolyPlot(index=self._image_index, value=self._image_value, index_mapper=GridMapper(range= image_index_range), color_mapper=\ self._cmap(image_value_range), levels=self.num_levels) self.lineplot = ContourLinePlot( index=self._image_index, value=self._image_value, index_mapper=GridMapper(range=self.polyplot.index_mapper.range), levels=self.num_levels) # Add a left axis to the plot left = PlotAxis(orientation='left', title="y", mapper=self.polyplot.index_mapper._ymapper, component=self.polyplot) self.polyplot.overlays.append(left) # Add a bottom axis to the plot bottom = PlotAxis(orientation='bottom', title="x", mapper=self.polyplot.index_mapper._xmapper, component=self.polyplot) self.polyplot.overlays.append(bottom) # Add some tools to the plot self.polyplot.tools.append( PanTool(self.polyplot, constrain_key="shift")) self.polyplot.overlays.append( ZoomTool(component=self.polyplot, tool_mode="box", always_on=False)) self.polyplot.overlays.append( LineInspector(component=self.polyplot, axis='index_x', inspect_mode="indexed", write_metadata=True, is_listener=True, color="white")) self.polyplot.overlays.append( LineInspector(component=self.polyplot, axis='index_y', inspect_mode="indexed", write_metadata=True, color="white", is_listener=True)) # Add these two plots to one container contour_container = OverlayPlotContainer(padding=20, use_backbuffer=True, unified_draw=True) contour_container.add(self.polyplot) contour_container.add(self.lineplot) # Create a colorbar cbar_index_mapper = LinearMapper(range=image_value_range) self.colorbar = ColorBar(index_mapper=cbar_index_mapper, plot=self.polyplot, padding_top=self.polyplot.padding_top, padding_bottom=self.polyplot.padding_bottom, padding_right=40, resizable='v', width=30) self.pd = ArrayPlotData(line_index=array([]), line_value=array([]), scatter_index=array([]), scatter_value=array([]), scatter_color=array([])) self.cross_plot = Plot(self.pd, resizable="h") self.cross_plot.height = 100 self.cross_plot.padding = 20 self.cross_plot.plot(("line_index", "line_value"), line_style="dot") self.cross_plot.plot( ("scatter_index", "scatter_value", "scatter_color"), type="cmap_scatter", name="dot", color_mapper=self._cmap(image_value_range), marker="circle", marker_size=8) self.cross_plot.index_range = self.polyplot.index_range.x_range self.pd.set_data("line_index2", array([])) self.pd.set_data("line_value2", array([])) self.pd.set_data("scatter_index2", array([])) self.pd.set_data("scatter_value2", array([])) self.pd.set_data("scatter_color2", array([])) self.cross_plot2 = Plot(self.pd, width=140, orientation="v", resizable="v", padding=20, padding_bottom=160) self.cross_plot2.plot(("line_index2", "line_value2"), line_style="dot") self.cross_plot2.plot( ("scatter_index2", "scatter_value2", "scatter_color2"), type="cmap_scatter", name="dot", color_mapper=self._cmap(image_value_range), marker="circle", marker_size=8) self.cross_plot2.index_range = self.polyplot.index_range.y_range # Create a container and add components self.container = HPlotContainer(padding=40, fill_padding=True, bgcolor="white", use_backbuffer=False) inner_cont = VPlotContainer(padding=0, use_backbuffer=True) inner_cont.add(self.cross_plot) inner_cont.add(contour_container) self.container.add(self.colorbar) self.container.add(inner_cont) self.container.add(self.cross_plot2) def update(self, model): self.minz = model.minz self.maxz = model.maxz self.colorbar.index_mapper.range.low = self.minz self.colorbar.index_mapper.range.high = self.maxz self._image_index.set_data(model.xs, model.ys) self._image_value.data = model.zs self.pd.set_data("line_index", model.xs) self.pd.set_data("line_index2", model.ys) self.container.invalidate_draw() self.container.request_redraw() #--------------------------------------------------------------------------- # Event handlers #--------------------------------------------------------------------------- def _metadata_changed(self, old, new): """ This function takes out a cross section from the image data, based on the line inspector selections, and updates the line and scatter plots.""" self.cross_plot.value_range.low = self.minz self.cross_plot.value_range.high = self.maxz self.cross_plot2.value_range.low = self.minz self.cross_plot2.value_range.high = self.maxz if self._image_index.metadata.has_key("selections"): x_ndx, y_ndx = self._image_index.metadata["selections"] if y_ndx and x_ndx: self.pd.set_data("line_value", self._image_value.data[y_ndx, :]) self.pd.set_data("line_value2", self._image_value.data[:, x_ndx]) xdata, ydata = self._image_index.get_data() xdata, ydata = xdata.get_data(), ydata.get_data() self.pd.set_data("scatter_index", array([xdata[x_ndx]])) self.pd.set_data("scatter_index2", array([ydata[y_ndx]])) self.pd.set_data("scatter_value", array([self._image_value.data[y_ndx, x_ndx]])) self.pd.set_data("scatter_value2", array([self._image_value.data[y_ndx, x_ndx]])) self.pd.set_data("scatter_color", array([self._image_value.data[y_ndx, x_ndx]])) self.pd.set_data("scatter_color2", array([self._image_value.data[y_ndx, x_ndx]])) else: self.pd.set_data("scatter_value", array([])) self.pd.set_data("scatter_value2", array([])) self.pd.set_data("line_value", array([])) self.pd.set_data("line_value2", array([])) def _colormap_changed(self): self._cmap = default_colormaps.color_map_name_dict[self.colormap] if self.polyplot is not None: value_range = self.polyplot.color_mapper.range self.polyplot.color_mapper = self._cmap(value_range) value_range = self.cross_plot.color_mapper.range self.cross_plot.color_mapper = self._cmap(value_range) # FIXME: change when we decide how best to update plots using # the shared colormap in plot object self.cross_plot.plots["dot"][0].color_mapper = self._cmap( value_range) self.cross_plot2.plots["dot"][0].color_mapper = self._cmap( value_range) self.container.request_redraw() def _num_levels_changed(self): if self.num_levels > 3: self.polyplot.levels = self.num_levels self.lineplot.levels = self.num_levels
class TransformData(Filter): """Performs a linear transformation to input data using a tvtk.BoxWidget. This does not work with ImageData/StructuredPoints/RectilinearGrid. """ # The version of this class. Used for persistence. __version__ = 0 # The widget that we use to perform the transformation. widget = Instance(tvtk.ThreeDWidget, allow_none=False, record=True) # The filter we manage. filter = Instance(tvtk.Object, allow_none=False) # The transform. transform = Property # Update the data immediately or at the end of the interaction. update_mode = Trait('semi-interactive', TraitMap({'interactive':'InteractionEvent', 'semi-interactive': 'EndInteractionEvent'}), desc='speed at which the data should be updated') input_info = PipelineInfo(datasets=['poly_data', 'structured_grid', 'unstructured_grid'], attribute_types=['any'], attributes=['any']) output_info = PipelineInfo(datasets=['poly_data', 'structured_grid', 'unstructured_grid'], attribute_types=['any'], attributes=['any']) ######################################## # View related code. # Reset the transformation. reset = Button("Reset Transformation") view = View(Group(Group(Item('update_mode'), ), Group(Item('reset'), Item(name='widget', style='custom', resizable=True), show_labels=False ) ), resizable=True ) ######################################## # Private traits. _transform = Instance(tvtk.Transform, allow_none=False) _first = Bool(True) _observer_id = Int(-1) ###################################################################### # `object` interface. ###################################################################### def __get_pure_state__(self): d = super(TransformData, self).__get_pure_state__() for name in ('_first', '_observer_id'): d.pop(name, None) d['matrix'] = cPickle.dumps(self._transform.matrix) return d def __set_pure_state__(self, state): mat = state.pop('matrix') super(TransformData, self).__set_pure_state__(state) state_pickler.set_state(self, state) self._transform.set_matrix(cPickle.loads(mat)) self.widget.set_transform(self._transform) ###################################################################### # `Filter` interface. ###################################################################### def setup_pipeline(self): self._transform = tvtk.Transform() self.widget = tvtk.BoxWidget(place_factor=1.1) self.filter = tvtk.TransformFilter() super(TransformData, self).setup_pipeline() def update_pipeline(self): # Do nothing if there is no input. inputs = self.inputs if len(inputs) == 0: return inp = inputs[0].get_output_dataset() if inp.is_a('vtkImageData') or inp.is_a('vtkRectilinearGrid'): error('Transformation not supported for '\ 'ImageData/StructuredPoints/RectilinearGrid') return # Set the input for the widget and place it if this hasn't # been done before. w = self.widget self.configure_input_data(w, inp) if self._first: w.place_widget() self._first = False # By default we set the input to the first output of the first # input. fil = self.filter self.configure_connection(fil, inputs[0]) fil.transform = self._transform fil.update() self._set_outputs([fil]) def update_data(self): # Do nothing if there is no input. if len(self.inputs) == 0: return self.filter.update() # Propagate the data_changed event. self.data_changed = True ###################################################################### # Non-public interface. ###################################################################### def _get_transform(self): return self._transform def _on_interaction_event(self, obj, event): tfm = self._transform self.widget.get_transform(tfm) f = self.filter f.transform = tfm f.update() self.render() recorder = self.recorder if recorder is not None: state = {} state['elements'] = tfm.matrix.__getstate__()['elements'] name = recorder.get_script_id(self) recorder.record('%s.transform.matrix.__setstate__(%s)'\ %(name, state)) recorder.record('%s.widget.set_transform(%s.transform)'\ %(name, name)) recorder.record('%s.filter.update()'%name) def _widget_changed(self, old, new): if old is not None: old.on_trait_change(self.render, remove=True) old.remove_observer(self._observer_id) self.widgets.remove(old) new.on_trait_change(self.render) self._observer_id = new.add_observer(self.update_mode_, self._on_interaction_event) self.widgets.append(new) if len(self.inputs) > 0: self.configure_input(new, self.inputs[0].outputs[0]) def _filter_changed(self, old, new): if old is not None: old.on_trait_change(self.render, remove=True) new.on_trait_change(self.render) transform = self.transform if transform is not None: new.transform = transform if len(self.inputs) > 0: self.configure_connection(new, self.inputs[0]) self.outputs = [new] def _reset_fired(self): self._transform.identity() self.widget.place_widget() self.filter.update() self.render() def _update_mode_changed(self, old, new): w = self.widget if w is not None: w.remove_observer(self._observer_id) self._observer_id = w.add_observer(self.update_mode_, self._on_interaction_event) self.render()
class Model(HasTraits): #Traits view definitions: traits_view = View(Group( Item('function'), HGroup(Item('npts_x', label="Number X Points"), Item('npts_y', label="Number Y Points")), HGroup(Item('min_x', label="Min X value"), Item('max_x', label="Max X value")), HGroup(Item('min_y', label="Min Y value"), Item('max_y', label="Max Y value"))), buttons=["OK", "Cancel"]) function = Str("tanh(x**2+y)*cos(y)*jn(0,x+y*2)") npts_x = CInt(400) npts_y = CInt(200) min_x = CFloat(-2 * pi) max_x = CFloat(2 * pi) min_y = CFloat(-1.5 * pi) max_y = CFloat(1.5 * pi) xs = Array ys = Array zs = Array minz = Float maxz = Float model_changed = Event def __init__(self, *args, **kwargs): super(Model, self).__init__(*args, **kwargs) self.compute_model() def compute_model(self): # The xs and ys used for the image plot range need to be the # edges of the cells. self.xs = linspace(self.min_x, self.max_x, self.npts_x + 1) self.ys = linspace(self.min_y, self.max_y, self.npts_y + 1) # The grid of points at which we will evaluate the 2D function # is located at cell centers, so use halfsteps from the # min/max values (which are edges) xstep = (self.max_x - self.min_x) / self.npts_x #ystep = (self.max_y - self.min_y) / self.npts_y gridx = linspace(self.min_x + xstep / 2, self.max_x - xstep / 2, self.npts_x) gridy = linspace(self.min_y + xstep / 2, self.max_y - xstep / 2, self.npts_y) x, y = meshgrid(gridx, gridy) try: d = dict(x=x, y=y) exec "from scipy import *" in d exec "from scipy.special import *" in d self.zs = eval(self.function, d) self.minz = nanmin(self.zs) self.maxz = nanmax(self.zs) self.model_changed = True self._function = self.function except: self.set(function=self._function, trait_change_notify=False) def _anytrait_changed(self, name, value): if name in [ 'function', 'npts_x', 'npts_y', 'min_x', 'max_x', 'min_y', 'max_y' ]: self.compute_model()
values = List() button_enabled = Bool(True) traits_view = View( Item("play_button", style="simple"), Item("play_button", style="custom"), Item("play_button", style="readonly"), Item("play_button", style="text"), ) simple_view = View( UItem("play_button", editor=ButtonEditor(label_value="play_button_label")), Item("play_button_label"), resizable=True, ) custom_view = View( UItem("play_button", editor=ButtonEditor(label_value="play_button_label")), Item("play_button_label"), resizable=True, style="custom", ) @requires_toolkit([ToolkitName.qt, ToolkitName.wx]) class TestButtonEditor(BaseTestMixin, unittest.TestCase, UnittestTools):
class Workflow(HasStrictTraits): workflow = List(WorkflowItem) selected = Instance(WorkflowItem) version = Str modified = Bool debug = Bool # default_scale = util.ScaleEnum # a view for the entire workflow's list of operations operations_traits = View(Item('workflow', editor=VerticalNotebookEditor( view='operation_traits', page_name='.name', page_description='.friendly_id', page_icon='.icon', delete=True, page_deletable='.deletable', selected='selected', multiple_open=False), show_label=False), scrollable=True) # a view showing the selected workflow item's current view selected_view_traits = View(Item( 'selected', editor=InstanceEditor(view='current_view_traits'), style='custom', show_label=False), Spring(), Item('apply_calls', style='readonly', visible_when='debug'), Item('plot_calls', style='readonly', visible_when='debug'), kind='panel', scrollable=True) # the view for the center pane plot_view = View( Item('selected', editor=InstanceEditor(view='current_plot_view'), style='custom', show_label=False)) recv_thread = Instance(threading.Thread) send_thread = Instance(threading.Thread) log_thread = Instance(threading.Thread) remote_process_thread = Instance(threading.Thread) message_q = Instance(Queue, ()) # the Pipe connection object to pass to the matplotlib canvas child_matplotlib_conn = Any # count the number of times the remote process calls apply() or plot(). # useful for debugging apply_calls = Int(0) plot_calls = Int(0) def __init__(self, remote_connection, **kwargs): super(Workflow, self).__init__(**kwargs) child_workflow_conn, self.child_matplotlib_conn, log_q = remote_connection self.recv_thread = threading.Thread(target=self.recv_main, name="local workflow recv", args=[child_workflow_conn]) self.recv_thread.daemon = True self.recv_thread.start() self.send_thread = threading.Thread(target=self.send_main, name="local workflow send", args=[child_workflow_conn]) self.send_thread.daemon = True self.send_thread.start() self.log_thread = threading.Thread(target=self.log_main, name="log listener thread", args=[log_q]) self.log_thread.daemon = True self.log_thread.start() def recv_main(self, child_conn): while child_conn.poll(None): try: (msg, payload) = child_conn.recv() except EOFError: return logging.debug("LocalWorkflow.recv_main :: {}".format(msg)) try: if msg == Msg.UPDATE_WI: (idx, name, new) = payload wi = self.workflow[idx] if not wi.trait(name).status: raise RuntimeError( "Tried to set a local non-status wi trait") with wi.lock: wi.trait_set(**{name: new}) elif msg == Msg.UPDATE_OP: (idx, name, new) = payload wi = self.workflow[idx] if not wi.operation.trait(name).status: raise RuntimeError( "Tried to set a local non-status trait") with wi.lock: wi.operation.trait_set(**{name: new}) elif msg == Msg.UPDATE_VIEW: (idx, view_id, name, new) = payload wi = self.workflow[idx] view = next((x for x in wi.views if x.id == view_id)) if not view.trait(name).status: raise RuntimeError( "Tried to set a local non-status trait") with wi.lock: view.trait_set(**{name: new}) elif msg == Msg.APPLY_CALLED: self.apply_calls = payload elif msg == Msg.PLOT_CALLED: self.plot_calls = payload else: raise RuntimeError("Bad message from remote") except Exception: log_exception() def send_main(self, child_conn): try: while True: msg = self.message_q.get() child_conn.send(msg) except Exception: log_exception() def log_main(self, log_q): # from http://plumberjack.blogspot.com/2010/09/using-logging-with-multiprocessing.html while True: try: record = log_q.get() if record is None: # We send this as a sentinel to tell the listener to quit. break logger = logging.getLogger(record.name) logger.handle( record) # No level or filter logic applied - just do it! except (KeyboardInterrupt, SystemExit): raise except: print('Whoops! Problem:', file=sys.stderr) traceback.print_exc(file=sys.stderr) def shutdown_remote_process(self): self.message_q.put((Msg.SHUTDOWN, None)) @on_trait_change('workflow') def _on_new_workflow(self, obj, name, old, new): logging.debug("LocalWorkflow._on_new_workflow") self.selected = None # send the new workflow to the child process self.message_q.put((Msg.NEW_WORKFLOW, self.workflow)) @on_trait_change('workflow_items') def _on_workflow_add_remove_items(self, event): logging.debug( "LocalWorkflow._on_workflow_add_remove_items :: {}".format( (event.index, event.removed, event.added))) idx = event.index self.modified = True # remove deleted items from the linked list if event.removed: assert len(event.removed) == 1 removed = event.removed[0] if removed.previous_wi: removed.previous_wi.next_wi = removed.next_wi if removed.next_wi: removed.next_wi.previous_wi = removed.previous_wi self.message_q.put((Msg.REMOVE_ITEMS, idx)) if removed == self.selected: self.selected = None # add new items to the linked list if event.added: assert len(event.added) == 1 if idx > 0: # populate the new wi with metadata from the old one self.workflow[idx].channels = list(self.workflow[idx - 1].channels) self.workflow[idx].conditions = dict( self.workflow[idx - 1].conditions) self.workflow[idx].metadata = dict(self.workflow[idx - 1].metadata) self.workflow[idx].statistics = dict( self.workflow[idx - 1].statistics) self.workflow[idx - 1].next_wi = self.workflow[idx] self.workflow[idx].previous_wi = self.workflow[idx - 1] if idx < len(self.workflow) - 1: self.workflow[idx].next_wi = self.workflow[idx + 1] self.workflow[idx + 1].previous_wi = self.workflow[idx] self.message_q.put((Msg.ADD_ITEMS, (idx, event.added[0]))) @on_trait_change('selected') def _on_selected_changed(self, obj, name, old, new): logging.debug("LocalWorkflow._on_selected_changed :: {}".format( (obj, name, old, new))) if new is None: idx = -1 else: idx = self.workflow.index(new) self.message_q.put((Msg.SELECT, idx)) @on_trait_change('workflow:operation:+') def _operation_changed(self, obj, name, old, new): logging.debug("LocalWorkflow._operation_changed :: {}".format( (obj, name, old, new))) if not obj.trait(name).transient and not obj.trait(name).status: wi = next((x for x in self.workflow if x.operation == obj)) idx = self.workflow.index(wi) self.message_q.put((Msg.UPDATE_OP, (idx, name, new))) self.modified = True @on_trait_change('workflow:operation:changed') def _operation_changed_event(self, obj, _, new): logging.debug("LocalWorkflow._operation_changed_event:: {}".format( (obj, new))) (_, (name, new)) = new wi = next((x for x in self.workflow if x.operation == obj)) idx = self.workflow.index(wi) self.message_q.put((Msg.UPDATE_OP, (idx, name, new))) self.modified = True @on_trait_change('workflow:views:+') def _view_changed(self, obj, name, old, new): logging.debug("LocalWorkflow._view_changed :: {}".format( (obj, name, old, new))) if not obj.trait(name).transient and not obj.trait(name).status: wi = next((x for x in self.workflow if obj in x.views)) idx = self.workflow.index(wi) self.message_q.put((Msg.UPDATE_VIEW, (idx, obj.id, name, new))) self.modified = True @on_trait_change('workflow:views:changed') def _view_changed_event(self, obj, _, new): logging.debug("LocalWorkflow._view_changed_event:: {}".format( (obj, new))) (_, (_, name, new)) = new wi = next((x for x in self.workflow if obj in x.views)) idx = self.workflow.index(wi) self.message_q.put((Msg.UPDATE_VIEW, (idx, obj.id, name, new))) self.modified = True @on_trait_change('workflow:current_view') def _on_current_view_changed(self, obj, name, old, new): logging.debug("LocalWorkflow._on_current_view_changed :: {}".format( (obj, name, old, new))) idx = self.workflow.index(obj) view = obj.current_view self.message_q.put((Msg.CHANGE_CURRENT_VIEW, (idx, view))) @on_trait_change('workflow:current_plot') def _on_current_plot_changed(self, obj, name, old, new): logging.debug("LocalWorkflow._on_current_plot_changed :: {}".format( (obj, name, old, new))) idx = self.workflow.index(obj) plot = obj.current_plot self.message_q.put((Msg.CHANGE_CURRENT_PLOT, (idx, plot))) @on_trait_change('workflow:operation:do_estimate') def _on_estimate(self, obj, name, old, new): logging.debug("LocalWorkflow._on_estimate :: {}".format( (obj, name, old, new))) wi = next((x for x in self.workflow if x.operation == obj)) idx = self.workflow.index(wi) self.message_q.put((Msg.ESTIMATE, idx))