class Viz2DForceDeflectionX(Viz2D): '''Plot adaptor for the pull-out simulator. ''' label = 'F-W' show_legend = tr.Bool(True, auto_set=False, enter_set=True) def plot(self, ax, vot, *args, **kw): P, W = self.vis2d.get_PW() ymin, ymax = np.min(P), np.max(P) L_y = ymax - ymin ymax += 0.05 * L_y ymin -= 0.05 * L_y xmin, xmax = np.min(W), np.max(W) L_x = xmax - xmin xmax += 0.03 * L_x xmin -= 0.03 * L_x ax.plot(W, P, linewidth=2, color='black', alpha=0.4, label='P(w;x=L)') ax.set_ylim(ymin=ymin, ymax=ymax) ax.set_xlim(xmin=xmin, xmax=xmax) ax.set_ylabel('Force P [N]') ax.set_xlabel('Deflection w [mm]') if self.show_legend: ax.legend(loc=4) self.plot_marker(ax, vot) def plot_marker(self, ax, vot): P, W = self.vis2d.get_PW() idx = self.vis2d.tloop.get_time_idx(vot) P, w = P[idx], W[idx] ax.plot([w], [P], 'o', color='black', markersize=10) def plot_tex(self, ax, vot, *args, **kw): self.plot(ax, vot, *args, **kw) traits_view = View( Item('name', style='readonly'), Item('show_legend'), )
class config(HasTraits): uuid = traits.Str(desc="UUID") desc = traits.Str(desc="Workflow Description") # Directories working_dir = Directory(mandatory=True, desc="Location of the Nipype working directory") sink_dir = Directory(os.path.abspath('.'), mandatory=True, desc="Location where the BIP will store the results") crash_dir = Directory(mandatory=False, desc="Location to store crash files") save_script_only = traits.Bool(False) # Execution run_using_plugin = Bool( False, usedefault=True, desc="True to run pipeline with plugin, False to run serially") plugin = traits.Enum("PBS", "MultiProc", "SGE", "Condor", usedefault=True, desc="plugin to use, if run_using_plugin=True") plugin_args = traits.Dict({"qsub_args": "-q many"}, usedefault=True, desc='Plugin arguments.') test_mode = Bool( False, mandatory=False, usedefault=True, desc='Affects whether where and if the workflow keeps its \ intermediary files. True to keep intermediary files. ' ) timeout = traits.Float(14.0) datagrabber = traits.Instance(Data, ()) use_advanced_options = Bool(False) advanced_options = traits.Code()
class config(BaseWorkflowConfig): uuid = traits.Str(desc="UUID") # Directories base_dir = Directory( os.path.abspath('.'), mandatory=True, desc='Base directory of data. (Should be subject-independent)') sink_dir = Directory(mandatory=True, desc="Location where the BIP will store the results") save_script_only = traits.Bool(False) datagrabber = traits.Instance(Data, ()) # Regression run_one_sample_T_test = traits.Bool(True) run_regression = traits.Bool() design_csv = traits.File(desc="design .csv file") reg_contrasts = traits.Code( desc= "function named reg_contrasts which takes in 0 args and returns contrasts" ) use_regressors = traits.Bool() estimation_method = traits.Enum('Classical', 'Bayesian', 'Bayesian2') include_intercept = traits.Bool(True) #Normalization norm_template = traits.File(desc='Template of files') use_mask = traits.Bool(False) mask_file = traits.File(desc='already binarized mask file to use') #Correction: p_threshold = traits.Float(0.05) height_threshold = traits.Float(0.05) min_cluster_size = traits.Int(25) # Advanced Options use_advanced_options = traits.Bool() advanced_script = traits.Code() # Buttons check_func_datagrabber = Button("Check")
class IntRangeEditor(EditorFactory): low = tr.Int(0) high = tr.Int(1) low_name = tr.Str high_name = tr.Str continuous_update = tr.Bool(False) def render(self): low = self.low high = self.high if self.low_name: self.low = getattr(self.model, str(self.low_name)) if self.high_name: self.high = getattr(self.model, str(self.high_name)) if self.n_steps_name: self.n_steps = getattr(self.model, str(self.n_steps_name)) return ipw.IntRangeSlider( description=self.label, value=self.value, min=low, max=high, tooltip=self.tooltip, disabled=self.disabled, style=style )
class Viz2DStrainInCrack(Viz2D): '''Plot adaptor for the pull-out simulator. ''' label = 'strain in crack' show_legend = tr.Bool(True, auto_set=False, enter_set=True) ax_sig = tr.Any def plot(self, ax, vot, *args, **kw): eps = self.vis2d.get_eps_t(vot) sig = self.vis2d.get_sig_t(vot) a_x = self.vis2d.get_a_x() ax.plot(eps, a_x, linewidth=3, color='red', alpha=0.4, label='P(w;x=L)') # ax.fill_betweenx(eps, 0, a_x, facecolor='orange', alpha=0.2) ax.set_xlabel('Strain [-]') ax.set_ylabel('Position [mm]') if self.ax_sig: self.ax_sig.clear() else: self.ax_sig = ax.twiny() self.ax_sig.set_xlabel('Stress [MPa]') self.ax_sig.plot(sig, a_x, linewidth=2, color='blue') self.ax_sig.fill_betweenx(a_x, sig, facecolor='blue', alpha=0.2) align_xaxis_np(ax, self.ax_sig) if self.show_legend: ax.legend(loc=4) traits_view = View( Item('name', style='readonly'), Item('show_legend'), )
class config(BaseWorkflowConfig): uuid = traits.Str(desc="UUID") # Directories base_dir = Directory( os.path.abspath('.'), mandatory=True, desc='Base directory of data. (Should be subject-independent)') sink_dir = Directory(mandatory=True, desc="Location where the BIP will store the results") surf_dir = Directory( desc="freesurfer directory. subject id's should be the same") save_script_only = traits.Bool(False) # DataGrabber datagrabber = traits.Instance(Data, ()) # segstats use_reg = traits.Bool(True) inverse_reg = traits.Bool(True) use_standard_label = traits.Bool( False, desc="use same label file for all subjects") label_file = traits.File() use_annotation = traits.Bool( False, desc= "use same annotation file for all subjects (will warp to subject space" ) use_subject_annotation = traits.Bool( False, desc="you need to change datragrabber to\ have outputs lh_annotation and rh_annotation" ) annot_space = traits.String("fsaverage5", desc="subject space of annot file") lh_annotation = traits.File() rh_annotation = traits.File() color_table_file = traits.Enum("Default", "Color_Table", "GCA_color_table", "None") color_file = traits.File() proj = traits.BaseTuple(("frac", 0, 1, 0.1), traits.Enum("abs", "frac"), traits.Float(), traits.Float(), traits.Float()) statname = traits.Str('segstats1', desc="description of the segstat")
class SpikesRemoval(SpanSelectorInSpectrum): interpolator_kind = t.Enum( 'Linear', 'Spline', default='Linear') threshold = t.Float() show_derivative_histogram = t.Button() spline_order = t.Range(1, 10, 3) interpolator = None default_spike_width = t.Int(5) index = t.Int(0) add_noise = t.Bool(True, desc="Add noise to the healed portion of the " "spectrum. Use the noise properties " "defined in metadata if present, otherwise " "it defaults to shot noise.") view = tu.View(tu.Group( tu.Group( tu.Item('show_derivative_histogram', show_label=False), 'threshold', show_border=True,), tu.Group( 'add_noise', 'interpolator_kind', 'default_spike_width', tu.Group( 'spline_order', visible_when='interpolator_kind == \'Spline\''), show_border=True, label='Advanced settings'), ), buttons=[OKButton, OurPreviousButton, OurFindButton, OurApplyButton, ], handler=SpikesRemovalHandler, title='Spikes removal tool') def __init__(self, signal, navigation_mask=None, signal_mask=None): super(SpikesRemoval, self).__init__(signal) self.interpolated_line = None self.coordinates = [coordinate for coordinate in signal.axes_manager._am_indices_generator() if (navigation_mask is None or not navigation_mask[coordinate[::-1]])] self.signal = signal self.line = signal._plot.signal_plot.ax_lines[0] self.ax = signal._plot.signal_plot.ax signal._plot.auto_update_plot = False if len(self.coordinates) > 1: signal.axes_manager.indices = self.coordinates[0] self.threshold = 400 self.index = 0 self.argmax = None self.derivmax = None self.kind = "linear" self._temp_mask = np.zeros(self.signal().shape, dtype='bool') self.signal_mask = signal_mask self.navigation_mask = navigation_mask md = self.signal.metadata from hyperspy.signal import Signal if "Signal.Noise_properties" in md: if "Signal.Noise_properties.variance" in md: self.noise_variance = md.Signal.Noise_properties.variance if isinstance(md.Signal.Noise_properties.variance, Signal): self.noise_type = "heteroscedastic" else: self.noise_type = "white" else: self.noise_type = "shot noise" def _threshold_changed(self, old, new): self.index = 0 self.update_plot() def _show_derivative_histogram_fired(self): self.signal._spikes_diagnosis(signal_mask=self.signal_mask, navigation_mask=self.navigation_mask) def detect_spike(self): derivative = np.diff(self.signal()) if self.signal_mask is not None: derivative[self.signal_mask[:-1]] = 0 if self.argmax is not None: left, right = self.get_interpolation_range() self._temp_mask[left:right] = True derivative[self._temp_mask[:-1]] = 0 if abs(derivative.max()) >= self.threshold: self.argmax = derivative.argmax() self.derivmax = abs(derivative.max()) return True else: return False def _reset_line(self): if self.interpolated_line is not None: self.interpolated_line.close() self.interpolated_line = None self.reset_span_selector() def find(self, back=False): self._reset_line() ncoordinates = len(self.coordinates) spike = self.detect_spike() while not spike and ( (self.index < ncoordinates - 1 and back is False) or (self.index > 0 and back is True)): if back is False: self.index += 1 else: self.index -= 1 spike = self.detect_spike() if spike is False: messages.information('End of dataset reached') self.index = 0 self._reset_line() return else: minimum = max(0, self.argmax - 50) maximum = min(len(self.signal()) - 1, self.argmax + 50) thresh_label = DerivativeTextParameters( text="$\mathsf{\delta}_\mathsf{max}=$", color="black") self.ax.legend([thresh_label], [repr(int(self.derivmax))], handler_map={ DerivativeTextParameters: DerivativeTextHandler()}, loc='best') self.ax.set_xlim( self.signal.axes_manager.signal_axes[0].index2value( minimum), self.signal.axes_manager.signal_axes[0].index2value( maximum)) self.update_plot() self.create_interpolation_line() def update_plot(self): if self.interpolated_line is not None: self.interpolated_line.close() self.interpolated_line = None self.reset_span_selector() self.update_spectrum_line() if len(self.coordinates) > 1: self.signal._plot.pointer._update_patch_position() def update_spectrum_line(self): self.line.auto_update = True self.line.update() self.line.auto_update = False def _index_changed(self, old, new): self.signal.axes_manager.indices = self.coordinates[new] self.argmax = None self._temp_mask[:] = False def on_disabling_span_selector(self): if self.interpolated_line is not None: self.interpolated_line.close() self.interpolated_line = None def _spline_order_changed(self, old, new): self.kind = self.spline_order self.span_selector_changed() def _add_noise_changed(self, old, new): self.span_selector_changed() def _interpolator_kind_changed(self, old, new): if new == 'linear': self.kind = new else: self.kind = self.spline_order self.span_selector_changed() def _ss_left_value_changed(self, old, new): self.span_selector_changed() def _ss_right_value_changed(self, old, new): self.span_selector_changed() def create_interpolation_line(self): self.interpolated_line = drawing.spectrum.SpectrumLine() self.interpolated_line.data_function = \ self.get_interpolated_spectrum self.interpolated_line.set_line_properties( color='blue', type='line') self.signal._plot.signal_plot.add_line(self.interpolated_line) self.interpolated_line.autoscale = False self.interpolated_line.plot() def get_interpolation_range(self): axis = self.signal.axes_manager.signal_axes[0] if self.ss_left_value == self.ss_right_value: left = self.argmax - self.default_spike_width right = self.argmax + self.default_spike_width else: left = axis.value2index(self.ss_left_value) right = axis.value2index(self.ss_right_value) # Clip to the axis dimensions nchannels = self.signal.axes_manager.signal_shape[0] left = left if left >= 0 else 0 right = right if right < nchannels else nchannels - 1 return left, right def get_interpolated_spectrum(self, axes_manager=None): data = self.signal().copy() axis = self.signal.axes_manager.signal_axes[0] left, right = self.get_interpolation_range() if self.kind == 'linear': pad = 1 else: pad = 10 ileft = left - pad iright = right + pad ileft = np.clip(ileft, 0, len(data)) iright = np.clip(iright, 0, len(data)) left = int(np.clip(left, 0, len(data))) right = int(np.clip(right, 0, len(data))) x = np.hstack((axis.axis[ileft:left], axis.axis[right:iright])) y = np.hstack((data[ileft:left], data[right:iright])) if ileft == 0: # Extrapolate to the left data[left:right] = data[right + 1] elif iright == (len(data) - 1): # Extrapolate to the right data[left:right] = data[left - 1] else: # Interpolate intp = sp.interpolate.interp1d(x, y, kind=self.kind) data[left:right] = intp(axis.axis[left:right]) # Add noise if self.add_noise is True: if self.noise_type == "white": data[left:right] += np.random.normal( scale=np.sqrt(self.noise_variance), size=right - left) elif self.noise_type == "heteroscedastic": noise_variance = self.noise_variance( axes_manager=self.signal.axes_manager)[left:right] noise = [np.random.normal(scale=np.sqrt(item)) for item in noise_variance] data[left:right] += noise else: data[left:right] = np.random.poisson( np.clip(data[left:right], 0, np.inf)) return data def span_selector_changed(self): if self.interpolated_line is None: return else: self.interpolated_line.update() def apply(self): self.signal()[:] = self.get_interpolated_spectrum() self.update_spectrum_line() self.interpolated_line.close() self.interpolated_line = None self.reset_span_selector() self.find()
class MATS1D5DPCum(MATSEval): node_name = 'Cumulative damage plasticity model' E_N = tr.Float(100, label='E_N', desc='Normal stiffness of the interface', MAT=True, enter_set=True, auto_set=False) E_T = tr.Float(100, label='E_T', desc='Shear modulus of the interface', MAT=True, enter_set=True, auto_set=False) gamma = tr.Float(40.0, label='gamma', desc='Kinematic Hardening Modulus', MAT=True, enter_set=True, auto_set=False) K = tr.Float(1, label='K', desc='Isotropic hardening modulus', MAT=True, enter_set=True, auto_set=False) c = tr.Float(1, Label='c', desc='Damage accumulation parameter', MAT=True, enter_set=True, auto_set=False) tau_bar = tr.Float(1, label='tau_bar', desc='Reversibility limit', MAT=True, enter_set=True, auto_set=False) state_var_shapes = dict(s_p=(), alpha=(), z=(), omega=(), kappa=()) uncoupled_dp = tr.Bool(False, MAT=True, label='Uncoupled d-p') s_0 = tr.Float(MAT=True, desc='Elastic strain/displacement limit') def __init__(self, *args, **kw): super(MATS1D5DPCum, self).__init__(*args, **kw) self._update_s0() @on_trait_change('tau_bar,E_T') def _update_s0(self): if not self.uncoupled_dp: if self.E_T == 0: self.s_0 = 0 else: self.s_0 = self.tau_bar / self.E_T self.omega_fn.s_0 = self.s_0 omega_fn_type = tr.Trait( 'FRP', dict(li=LiDamageFn, jirasek=JirasekDamageFn, abaqus=AbaqusDamageFn, FRP=FRPDamageFn, multilinear=MultilinearDamageFn), MAT=True, ) @on_trait_change('omega_fn_type') def _reset_omega_fn(self): print('resetting') self.omega_fn = self.omega_fn_type_(s_0=self.s_0) omega_fn = tr.Instance(IDamageFn, report=True) def _omega_fn_default(self): return MultilinearDamageFn() def omega(self, k): return self.omega_fn(k) def omega_derivative(self, k): return self.omega_fn.diff(k) def init(self, s_pi, alpha, z, omega, kappa): r''' Initialize the state variables. ''' s_pi[...] = 0 alpha[...] = 0 z[...] = 0 omega[...] = 0 kappa[...] = 0 algorithmic = tr.Bool(True) def get_corr_pred(self, u_r, t_n, s_p, alpha, z, omega, kappa): s = u_r[..., 0] w = u_r[..., 1] # For normal H_w_N = np.array(w <= 0.0, dtype=np.float_) E_alg_N = H_w_N * self.E_N sig_N = E_alg_N * w sig_pi_trial = self.E_T * (s - s_p) Z = self.K * z # for handling the negative values of isotropic hardening h_1 = self.tau_bar + Z pos_iso = h_1 > 1e-6 X = self.gamma * alpha # for handling the negative values of kinematic hardening (not yet) # h_2 = h * np.sign(sig_pi_trial - X) * \ # np.sign(sig_pi_trial) + X * np.sign(sig_pi_trial) #pos_kin = h_2 > 1e-6 f = np.fabs(sig_pi_trial - X) - h_1 * pos_iso I = f > 1e-6 # Return mapping delta_lamda_I = f[I] / (self.E_T + self.gamma + np.fabs(self.K)) # update all the state variables s_p[I] += delta_lamda_I * np.sign(sig_pi_trial[I] - X[I]) z[I] += delta_lamda_I alpha[I] += delta_lamda_I * np.sign(sig_pi_trial[I] - X[I]) kappa[...] = np.max(np.array([kappa, np.fabs(s)]), axis=0) omega[...] = self.omega(kappa) tau = (1 - omega) * self.E_T * (s - s_p) E_alg_T = (1 - omega) * self.E_T domega_ds = self.omega_derivative(kappa) # Consistent tangent operator E_alg_T[I] = -self.E_T / (self.E_T + self.K + self.gamma) \ * domega_ds[I] * self.E_T * (s[I] - s_p[I]) \ + (1 - omega[I]) * self.E_T * (self.K + self.gamma) / \ (self.E_T + self.K + self.gamma) sig = np.zeros_like(u_r) sig[..., 0] = tau sig[..., 1] = sig_N E_TN = np.einsum( 'abEm->Emab', np.array([[E_alg_T, np.zeros_like(E_alg_T)], [np.zeros_like(E_alg_N), E_alg_N]])) return sig, E_TN
class ImagePlotInspector(traits.HasTraits): #Traits view definitions: settingsGroup = traitsui.VGroup( traitsui.VGroup(traitsui.HGroup('autoRangeColor', 'colorMapRangeLow', 'colorMapRangeHigh'), traitsui.HGroup('horizontalAutoRange', 'horizontalLowerLimit', 'horizontalUpperLimit'), traitsui.HGroup('verticalAutoRange', 'verticalLowerLimit', 'verticalUpperLimit'), label="axis limits", show_border=True), traitsui.VGroup(traitsui.HGroup('object.model.scale', 'object.model.offset'), traitsui.HGroup( traitsui.Item('object.model.pixelsX', label="Pixels X"), traitsui.Item('object.model.pixelsY', label="Pixels Y")), traitsui.HGroup( traitsui.Item('object.model.ODCorrectionBool', label="Correct OD?"), traitsui.Item('object.model.ODSaturationValue', label="OD saturation value")), traitsui.HGroup( traitsui.Item('contourLevels', label="Contour Levels"), traitsui.Item('colormap', label="Colour Map")), traitsui.HGroup( traitsui.Item("cameraModel", label="Update Camera Settings to:")), label="advanced", show_border=True), label="settings") plotGroup = traitsui.Group( traitsui.Item('container', editor=ComponentEditor(size=(800, 600)), show_label=False)) mainPlotGroup = traitsui.HSplit(plotGroup, label="Image") traits_view = traitsui.View(settingsGroup, plotGroup, handler=EagleHandler, resizable=True) model = CameraImage() contourLevels = traits.Int(15) colormap = traits.Enum(colormaps.color_map_name_dict.keys()) autoRangeColor = traits.Bool(True) colorMapRangeLow = traits.Float colorMapRangeHigh = traits.Float horizontalAutoRange = traits.Bool(True) horizontalLowerLimit = traits.Float horizontalUpperLimit = traits.Float verticalAutoRange = traits.Bool(True) verticalLowerLimit = traits.Float verticalUpperLimit = traits.Float fixAspectRatioBool = traits.Bool(False) cameraModel = traits.Enum("Custom", "ALTA0", "ANDOR0", "ALTA1", "ANDOR1") #--------------------------------------------------------------------------- # Private Traits #--------------------------------------------------------------------------- _image_index = traits.Instance(chaco.GridDataSource) _image_value = traits.Instance(chaco.ImageData) _cmap = traits.Trait(colormaps.jet, traits.Callable) #--------------------------------------------------------------------------- # Public View interface #--------------------------------------------------------------------------- def __init__(self, *args, **kwargs): super(ImagePlotInspector, self).__init__(*args, **kwargs) #self.update(self.model) self.create_plot() #self._selectedFile_changed() logger.info("initialisation of experiment Eagle complete") def create_plot(self): # Create the mapper, etc self._image_index = chaco.GridDataSource(scipy.array([]), scipy.array([]), sort_order=("ascending", "ascending")) image_index_range = chaco.DataRange2D(self._image_index) self._image_index.on_trait_change(self._metadata_changed, "metadata_changed") self._image_value = chaco.ImageData(data=scipy.array([]), value_depth=1) image_value_range = chaco.DataRange1D(self._image_value) # Create the contour plots #self.polyplot = ContourPolyPlot(index=self._image_index, self.polyplot = chaco.CMapImagePlot( index=self._image_index, value=self._image_value, index_mapper=chaco.GridMapper(range=image_index_range), color_mapper=self._cmap(image_value_range)) # Add a left axis to the plot left = chaco.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 = chaco.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( tools.PanTool(self.polyplot, constrain_key="shift", drag_button="middle")) self.polyplot.overlays.append( tools.ZoomTool(component=self.polyplot, tool_mode="box", always_on=False)) self.lineInspectorX = clickableLineInspector.ClickableLineInspector( component=self.polyplot, axis='index_x', inspect_mode="indexed", write_metadata=True, is_listener=False, color="white") self.lineInspectorY = clickableLineInspector.ClickableLineInspector( component=self.polyplot, axis='index_y', inspect_mode="indexed", write_metadata=True, color="white", is_listener=False) self.polyplot.overlays.append(self.lineInspectorX) self.polyplot.overlays.append(self.lineInspectorY) self.boxSelection2D = boxSelection2D.BoxSelection2D( component=self.polyplot) self.polyplot.overlays.append(self.boxSelection2D) # Add these two plots to one container self.centralContainer = chaco.OverlayPlotContainer(padding=0, use_backbuffer=True, unified_draw=True) self.centralContainer.add(self.polyplot) # Create a colorbar cbar_index_mapper = chaco.LinearMapper(range=image_value_range) self.colorbar = chaco.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.plotData = chaco.ArrayPlotData( line_indexHorizontal=scipy.array([]), line_valueHorizontal=scipy.array([]), scatter_indexHorizontal=scipy.array([]), scatter_valueHorizontal=scipy.array([]), scatter_colorHorizontal=scipy.array([]), fitLine_indexHorizontal=scipy.array([]), fitLine_valueHorizontal=scipy.array([])) self.crossPlotHorizontal = chaco.Plot(self.plotData, resizable="h") self.crossPlotHorizontal.height = 100 self.crossPlotHorizontal.padding = 20 self.crossPlotHorizontal.plot( ("line_indexHorizontal", "line_valueHorizontal"), line_style="dot") self.crossPlotHorizontal.plot( ("scatter_indexHorizontal", "scatter_valueHorizontal", "scatter_colorHorizontal"), type="cmap_scatter", name="dot", color_mapper=self._cmap(image_value_range), marker="circle", marker_size=4) self.crossPlotHorizontal.index_range = self.polyplot.index_range.x_range self.plotData.set_data("line_indexVertical", scipy.array([])) self.plotData.set_data("line_valueVertical", scipy.array([])) self.plotData.set_data("scatter_indexVertical", scipy.array([])) self.plotData.set_data("scatter_valueVertical", scipy.array([])) self.plotData.set_data("scatter_colorVertical", scipy.array([])) self.plotData.set_data("fitLine_indexVertical", scipy.array([])) self.plotData.set_data("fitLine_valueVertical", scipy.array([])) self.crossPlotVertical = chaco.Plot(self.plotData, width=140, orientation="v", resizable="v", padding=20, padding_bottom=160) self.crossPlotVertical.plot( ("line_indexVertical", "line_valueVertical"), line_style="dot") self.crossPlotVertical.plot( ("scatter_indexVertical", "scatter_valueVertical", "scatter_colorVertical"), type="cmap_scatter", name="dot", color_mapper=self._cmap(image_value_range), marker="circle", marker_size=4) self.crossPlotVertical.index_range = self.polyplot.index_range.y_range # Create a container and add components self.container = chaco.HPlotContainer(padding=40, fill_padding=True, bgcolor="white", use_backbuffer=False) inner_cont = chaco.VPlotContainer(padding=40, use_backbuffer=True) inner_cont.add(self.crossPlotHorizontal) inner_cont.add(self.centralContainer) self.container.add(self.colorbar) self.container.add(inner_cont) self.container.add(self.crossPlotVertical) def update(self, model): print "updating" logger.info("updating plot") # if self.selectedFile=="": # logger.warning("selected file was empty. Will not attempt to update plot.") # return if self.autoRangeColor: self.colorbar.index_mapper.range.low = model.minZ self.colorbar.index_mapper.range.high = model.maxZ self._image_index.set_data(model.xs, model.ys) self._image_value.data = model.zs self.plotData.set_data("line_indexHorizontal", model.xs) self.plotData.set_data("line_indexVertical", model.ys) self.updatePlotLimits() self._image_index.metadata_changed = True 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.""" if self.horizontalAutoRange: self.crossPlotHorizontal.value_range.low = self.model.minZ self.crossPlotHorizontal.value_range.high = self.model.maxZ if self.verticalAutoRange: self.crossPlotVertical.value_range.low = self.model.minZ self.crossPlotVertical.value_range.high = self.model.maxZ if self._image_index.metadata.has_key("selections"): selections = self._image_index.metadata["selections"] if not selections: #selections is empty list return #don't need to do update lines as no mouse over screen. This happens at beginning of script x_ndx, y_ndx = selections if y_ndx and x_ndx: self.plotData.set_data("line_valueHorizontal", self._image_value.data[y_ndx, :]) self.plotData.set_data("line_valueVertical", self._image_value.data[:, x_ndx]) xdata, ydata = self._image_index.get_data() xdata, ydata = xdata.get_data(), ydata.get_data() self.plotData.set_data("scatter_indexHorizontal", scipy.array([xdata[x_ndx]])) self.plotData.set_data("scatter_indexVertical", scipy.array([ydata[y_ndx]])) self.plotData.set_data( "scatter_valueHorizontal", scipy.array([self._image_value.data[y_ndx, x_ndx]])) self.plotData.set_data( "scatter_valueVertical", scipy.array([self._image_value.data[y_ndx, x_ndx]])) self.plotData.set_data( "scatter_colorHorizontal", scipy.array([self._image_value.data[y_ndx, x_ndx]])) self.plotData.set_data( "scatter_colorVertical", scipy.array([self._image_value.data[y_ndx, x_ndx]])) else: self.plotData.set_data("scatter_valueHorizontal", scipy.array([])) self.plotData.set_data("scatter_valueVertical", scipy.array([])) self.plotData.set_data("line_valueHorizontal", scipy.array([])) self.plotData.set_data("line_valueVertical", scipy.array([])) self.plotData.set_data("fitLine_valueHorizontal", scipy.array([])) self.plotData.set_data("fitLine_valueVertical", scipy.array([])) def _colormap_changed(self): self._cmap = colormaps.color_map_name_dict[self.colormap] if hasattr(self, "polyplot"): value_range = self.polyplot.color_mapper.range self.polyplot.color_mapper = self._cmap(value_range) value_range = self.crossPlotHorizontal.color_mapper.range self.crossPlotHorizontal.color_mapper = self._cmap(value_range) # FIXME: change when we decide how best to update plots using # the shared colormap in plot object self.crossPlotHorizontal.plots["dot"][0].color_mapper = self._cmap( value_range) self.crossPlotVertical.plots["dot"][0].color_mapper = self._cmap( value_range) self.container.request_redraw() def _colorMapRangeLow_changed(self): self.colorbar.index_mapper.range.low = self.colorMapRangeLow def _colorMapRangeHigh_changed(self): self.colorbar.index_mapper.range.high = self.colorMapRangeHigh def _horizontalLowerLimit_changed(self): self.crossPlotHorizontal.value_range.low = self.horizontalLowerLimit def _horizontalUpperLimit_changed(self): self.crossPlotHorizontal.value_range.high = self.horizontalUpperLimit def _verticalLowerLimit_changed(self): self.crossPlotVertical.value_range.low = self.verticalLowerLimit def _verticalUpperLimit_changed(self): self.crossPlotVertical.value_range.high = self.verticalUpperLimit def _autoRange_changed(self): if self.autoRange: self.colorbar.index_mapper.range.low = self.minz self.colorbar.index_mapper.range.high = self.maxz def _num_levels_changed(self): if self.num_levels > 3: self.polyplot.levels = self.num_levels self.lineplot.levels = self.num_levels def _colorMapRangeLow_default(self): logger.debug("setting color map rangle low default") return self.model.minZ def _colorMapRangeHigh_default(self): return self.model.maxZ def _horizontalLowerLimit_default(self): return self.model.minZ def _horizontalUpperLimit_default(self): return self.model.maxZ def _verticalLowerLimit_default(self): return self.model.minZ def _verticalUpperLimit_default(self): return self.model.maxZ def _selectedFit_changed(self, selected): logger.debug("selected fit was changed") def _fixAspectRatioBool_changed(self): if self.fixAspectRatioBool: #using zoom range works but then when you reset zoom this function isn't called... # rangeObject = self.polyplot.index_mapper.range # xrangeValue = rangeObject.high[0]-rangeObject.low[0] # yrangeValue = rangeObject.high[1]-rangeObject.low[1] # logger.info("xrange = %s, yrange = %s " % (xrangeValue, yrangeValue)) # aspectRatioSquare = (xrangeValue)/(yrangeValue) # self.polyplot.aspect_ratio=aspectRatioSquare self.centralContainer.aspect_ratio = float( self.model.pixelsX) / float(self.model.pixelsY) #self.polyplot.aspect_ratio = self.model.pixelsX/self.model.pixelsY else: self.centralContainer.aspect_ratio = None #self.polyplot.aspect_ratio = None self.container.request_redraw() self.centralContainer.request_redraw() def updatePlotLimits(self): """just updates the values in the GUI """ if self.autoRangeColor: self.colorMapRangeLow = self.model.minZ self.colorMapRangeHigh = self.model.maxZ if self.horizontalAutoRange: self.horizontalLowerLimit = self.model.minZ self.horizontalUpperLimit = self.model.maxZ if self.verticalAutoRange: self.verticalLowerLimit = self.model.minZ self.verticalUpperLimit = self.model.maxZ def _selectedFile_changed(self): self.model.getImageData(self.selectedFile) if self.updatePhysicsBool: self.physics.updatePhysics() for fit in self.fitList: fit.fitted = False fit.fittingStatus = fit.notFittedForCurrentStatus if fit.autoFitBool: #we should automatically start fitting for this Fit fit._fit_routine( ) #starts a thread to perform the fit. auto guess and auto draw will be handled automatically self.update_view() #update log file plot if autorefresh is selected if self.logFilePlotObject.autoRefresh: try: self.logFilePlotObject.refreshPlot() except Exception as e: logger.error("failed to update log plot - %s...." % e.message) def _cameraModel_changed(self): """camera model enum can be used as a helper. It just sets all the relevant editable parameters to the correct values. e.g. pixels size, etc. cameras: "Andor Ixon 3838", "Apogee ALTA" """ logger.info("camera model changed") if self.cameraModel == "ANDOR0": self.model.pixelsX = 512 self.model.pixelsY = 512 self.physics.pixelSize = 16.0 self.physics.magnification = 2.0 self.searchString = "ANDOR0" elif self.cameraModel == "ALTA0": self.model.pixelsX = 768 self.model.pixelsY = 512 self.physics.pixelSize = 9.0 self.physics.magnification = 0.5 self.searchString = "ALTA0" elif self.cameraModel == "ALTA1": self.model.pixelsX = 768 self.model.pixelsY = 512 self.physics.pixelSize = 9.0 self.physics.magnification = 4.25 self.searchString = "ALTA1" elif self.cameraModel == "ANDOR1": self.model.pixelsX = 512 self.model.pixelsY = 512 self.physics.pixelSize = 16.0 self.physics.magnification = 2.0 self.searchString = "ANDOR1" else: logger.error("unrecognised camera model") self.refreshFitReferences() self.model.getImageData(self.selectedFile) def refreshFitReferences(self): """When aspects of the image change so that the fits need to have properties updated, it should be done by this function""" for fit in self.fitList: fit.endX = self.model.pixelsX fit.endY = self.model.pixelsY def _pixelsX_changed(self): """If pixelsX or pixelsY change, we must send the new arrays to the fit functions """ logger.info("pixels X Change detected") self.refreshFitReferences() self.update(self.model) self.model.getImageData(self.selectedFile) def _pixelsY_changed(self): """If pixelsX or pixelsY change, we must send the new arrays to the fit functions """ logger.info("pixels Y Change detected") self.refreshFitReferences() self.update(self.model) self.model.getImageData(self.selectedFile) @traits.on_trait_change('model') def update_view(self): if self.model is not None: self.update(self.model)
class MATS1D5DP2D(MATSEval): node_name = 'Pressure sensitive cumulative damage plasticity' E_N = tr.Float(30000, label='E_N', desc='Normal stiffness of the interface', MAT=True, enter_set=True, auto_set=False) E_T = tr.Float(12900, label='E_T', desc='Shear modulus of the interface', MAT=True, enter_set=True, auto_set=False) gamma = tr.Float(55.0, label='gamma', desc='Kinematic Hardening Modulus', MAT=True, enter_set=True, auto_set=False) K = tr.Float(11, label='K', desc='Isotropic hardening modulus', MAT=True, enter_set=True, auto_set=False) S_T = tr.Float(0.005, label='S_T', desc='Damage accumulation parameter', MAT=True, enter_set=True, auto_set=False) S_N = tr.Float(0.005, label='S_N', desc='Damage accumulation parameter', MAT=True, enter_set=True, auto_set=False) c_N = tr.Float(1, Label='c_N', desc='Damage accumulation parameter', MAT=True, enter_set=True, auto_set=False) c_T = tr.Float(1, Label='c_T', desc='Damage accumulation parameter', MAT=True, enter_set=True, auto_set=False) m = tr.Float(0.3, label='m', desc='Lateral Pressure Coefficient', MAT=True, enter_set=True, auto_set=False) sigma_o = tr.Float(4.2, label='sigma_o', desc='Reversibility limit', MAT=True, enter_set=True, auto_set=False) sig_t = tr.Float(5.0, label='sig_t', MAT=True, enter_set=True, auto_set=False) b = tr.Float(0.2, label='b', MAT=True, enter_set=True, auto_set=False) state_var_shapes = dict(ep_p_N=(), ep_pi_T=(), alpha=(), z=(), omega_T=(), omega_N=()) D_rs = tr.Property(depends_on='E_N,E_T') @tr.cached_property def _get_D_rs(self): print('recalculating D_rs') return np.array([[self.E_T, 0], [0, self.E_N]], dtype=np.float_) def init(self, ep_p_N, ep_pi_T, alpha, z, omega_T, omega_N): r''' Initialize the state variables. ''' ep_p_N[...] = 0 ep_pi_T[...] = 0 alpha[...] = 0 z[...] = 0 omega_T[...] = 0 omega_N[...] = 0 algorithmic = tr.Bool(True) def get_corr_pred(self, u_r, t_n, ep_p_N, ep_pi_T, alpha, z, omega_T, omega_N): ep_T = u_r[..., 0] ep_N = u_r[..., 1] print(ep_N) # eps_N_i = eps_N_arr[i] # eps_T_i = eps_T_arr[i] sig_N_i_eff_trial = self.E_N * (ep_N - ep_p_N) sig_T_i_eff_trial = self.E_T * (ep_T - ep_pi_T) #======================================================================= # sig_N = (1 - omega_N) * self.E_N * (ep_N - ep_p_N) # H_sig_eff_N = np.array(sig_eff_N >= 0.0, dtype=np.float_) #======================================================================= # sig_T = (1 - omega_T) * self.E_T * (ep_T - ep_pi_T) # '''CHECK PLEASE sig_T''' # For tangential # Y = 0.5 * self.E_T * (u_T - s_pi)**2 # sig_pi_trial = self.E_T * (ep_T - ep_pi_T) Z = self.K * z X = self.gamma * alpha f_trial = np.fabs(sig_T_i_eff_trial - self.gamma * alpha) - \ (self.sigma_o + self.K * z - self.m * sig_N_i_eff_trial) * (1.0 - np.heaviside((sig_N_i_eff_trial), 1) * ((sig_N_i_eff_trial) ** 2 / (self.sig_t) ** 2)) # Identify inelastic material points # @todo: consider the usage of np.where() # I = f > 1e-8 delta_lamda = np.zeros_like(ep_T) sig_N_eff = np.zeros_like(ep_T) if np.any(f_trial) > 1e-8: def f(vars): delta_lamda , sig_N_eff = vars N = (self.m + np.heaviside((sig_N_eff), 1) * ((-self.m * sig_N_eff ** 2) / (self.sig_t) ** 2 + \ (self.sigma_o + self.K * (z + delta_lamda) - self.m * sig_N_eff) * (2 * sig_N_eff / (self.sig_t) ** 2))) / (1. - omega_N) f1 = self.sigma_o + self.K * (z + delta_lamda) - self.m * sig_N_eff ft = 1.0 - np.heaviside(sig_N_eff, 1) * (sig_N_eff ** 2 / (self.sig_t) ** 2) f_lamda = np.fabs(sig_T_i_eff_trial - self.gamma * alpha) - delta_lamda * (self.E_T / (1. - omega_T) + self.gamma) - f1 * ft f_N = sig_N_eff - sig_N_i_eff_trial + delta_lamda * self.E_N * N return [f_lamda, f_N] #=================================================================== # for i in range(np.size(vars)): # sol = root[i](lambda vars: self.f(vars), method='lm', tol=1e-6) # x = sol.vars # print (x) #=================================================================== x0 = np.zeros_like(ep_T) def get_delta_lambda_sig_N_eff(): sol = root(lambda vars : f, x0 = x0 ,method='lm', tol=1e-6) return sol.x print (get_delta_lambda_sig_N_eff) # delta_lamda, sig_N_eff = vars ep_p_N += delta_lamda * (self.m - np.heaviside((sig_N_eff), 1) * ((self.m * sig_N_eff ** 2) / (self.sig_t) ** 2 - (self.sigma_o - self.m * sig_N_eff) * (2 * sig_N_eff / (self.sig_t) ** 2))) ep_pi_T += delta_lamda * np.sign(sig_T_i_eff_trial - self.gamma * alpha) / (1.0 - omega_T) z += delta_lamda alpha += delta_lamda * np.sign(sig_T_i_eff_trial - self.gamma * alpha) Y_N = 0.5 * self.E_N * (ep_N - ep_p_N) ** 2.0 Y_T = 0.5 * self.E_T * (ep_T - ep_pi_T) ** 2.0 omega_N += delta_lamda * (1 - omega_N) ** self.c_N * (Y_N / self.S_N + self.b * Y_T / self.S_T) * np.heaviside(ep_N, 1) omega_T += delta_lamda * (1 - omega_T) ** self.c_T * (Y_T / self.S_T + self.b * Y_N / self.S_N) sig_N_i = (1.0 - omega_N) * sig_N_eff sig_T_i = (1.0 - omega_T) * self.E_T * (ep_T - ep_pi_T) f = np.fabs(sig_T_i / (1 - omega_T) - self.gamma * alpha) - \ (self.sigma_o + self.K * z - self.m * sig_N_i / (1 - omega_N)) * (1.0 - np.heaviside((sig_N_i / (1 - omega_N)), 1) * ((sig_N_i / (1 - omega_N)) ** 2 / (self.sig_t) ** 2)) else: sig_N_i = (1 - omega_N) * sig_N_i_eff_trial sig_T_i = (1 - omega_T) * sig_T_i_eff_trial f = f_trial # Return mapping #======================================================================= # delta_lambda_I = ( # f[I] / (self.E_T / (1 - omega[I]) + self.gamma + self.K) # ) # # Update all state variables # s_pi[I] += (delta_lambda_I * # np.sign(tau_pi_trial[I] - X[I]) / (1 - omega[I])) # Y = 0.5 * self.E_T * (s - s_pi) ** 2 # omega[I] += ( # delta_lambda_I * # (1 - omega[I]) ** self.c * (Y[I] / self.S) ** self.r * (self.tau_bar / (self.tau_bar - self.m * sig_N[I])) # ) # sig_T[I] = (1 - omega[I]) * self.E_T * (s[I] - s_pi[I]) # alpha[I] += delta_lambda_I * np.sign(tau_pi_trial[I] - X[I]) # z[I] += delta_lambda_I #======================================================================= # Unloading stiffness E_alg_T = (1 - omega_T) * self.E_T E_alg_N = (1 - omega_N) * self.E_N # Consistent tangent operator #=============================================================================== # if False: # E_alg_T = ( # (1 - omega) * self.E_T - # (1 - omega) * self.E_T ** 2 / # (self.E_T + (self.gamma + self.K) * (1 - omega)) - # ((1 - omega) ** self.c * (self.E_T ** 2) * ((Y / self.S) ** self.r) # * np.sign(tau_pi_trial - X) * (s - s_pi)) / # ((self.E_T / (1 - omega)) + self.gamma + self.K) # ) # # # if False: # # print('DONT COME HERE') # E_alg_T = ( # (1 - omega) * self.E_T - # ((self.E_T ** 2 * (1 - omega)) / # (self.E_T + (self.gamma + self.K) * (1 - omega))) # - # ((1 - omega) ** self.c * # (Y / self.S) ** self.r * # self.E_T ** 2 * (s - s_pi) * self.tau_bar / # (self.tau_bar - self.m * sig_N) * np.sign(tau_pi_trial - X)) / # (self.E_T / (1 - omega) + self.gamma + self.K) # ) #=============================================================================== ep = np.zeros_like(u_r) ep[..., 0] = ep_T ep[..., 1] = ep_N E_TN = np.einsum('abEm->Emab', np.array( [ [E_alg_T, np.zeros_like(E_alg_T)], [np.zeros_like(E_alg_N), E_alg_N] ]) ) print('omega-T', omega_T) #print('omega-N', omega_N) # abc = open('sigNm0lp-100tan.txt', 'a+', newline='\n') # for e in range(len(sig_N)): # abc.write('%f ' % sig_N[e][0]) # abc.write('\n') # abc.close() # print('s_pi=', s_pi) return ep, E_TN def _get_var_dict(self): var_dict = super(MATS1D5DP2D, self)._get_var_dict() var_dict.update( slip=self.get_slip, s_el=self.get_s_el, shear=self.get_shear, omega_T=self.get_omega_T, omega_N=self.get_omega_N, ep_pi_T=self.get_ep_pi_T, alpha=self.get_alpha, z=self.get_z ) return var_dict def get_slip(self, u_r, tn1, **state): return self.get_eps(u_r, tn1)[..., 0] def get_shear(self, u_r, tn1, **state): return self.get_sig(u_r, tn1, **state)[..., 0] def get_omega_T(self, u_r, tn1, ep_pi_T, alpha, z, omega_T): return omega_T def get_omega_N(self, u_r, tn1, ep_p_N, omega_N): return omega_N def get_ep_pi_T(self, u_r, tn1, ep_pi_T, alpha, z, omega_T): return ep_pi_T def get_alpha(self, u_r, tn1, ep_pi_T, alpha, z, omega_T): return alpha def get_z(self, u_r, tn1, ep_pi_T, alpha, z, omega_T): return z def get_s_el(self, u_r, tn1, **state): ep_T = self.get_slip(u_r, tn1, **state) ep_pi_T = self.get_ep_pi_T(u_r, tn1, **state) ep_e_T = ep_T - ep_pi_T return ep_e_T # def get_sig_N(self, u_r, tn1, **state): # return self.get_sig(u_r, tn1, **state)[..., 1] tree_view = ui.View( ui.Item('E_N'), ui.Item('E_T'), ui.Item('gamma'), ui.Item('K'), ui.Item('S_T'), ui.Item('S_N'), ui.Item('c_T'), ui.Item('c_N'), ui.Item('m'), ui.Item('sigma_o'), ui.Item('sig_t'), ui.Item('b'), ui.Item('D_rs', style='readonly') ) traits_view = tree_view
class ADCChannel(traits.HasTraits): voltage = traits.Float(desc="The voltage of the channel") channelName = traits.Str(desc="Human defined name of channel") channelNumber = traits.Int( desc="channel number on box Can be integer from 0 to 7") channelMessage = traits.Str(desc="message to denote status of channel") criticalValue = traits.Float( desc="the value at which message will change and alarm will sound") plotScale = traits.Float( desc="scale factor to multiply voltage by on plot") logBool = traits.Bool(desc="if true data logged to a file") channelMessageHigh = "high" channelMessageLow = "low" statusHigh = traits.Bool(False) connection = None #It must be passed a connection in initialisation checkValueBool = traits.Bool(True) highIsGood = traits.Bool(True) highSoundFile = None lowSoundFile = None currentLocalTime = time.localtime() currentYear = currentLocalTime.tm_year currentMonth = currentLocalTime.tm_mon def _voltage_get(self): """Uses PyHWI connection to ADC server to return voltage """ #print "latest=%s" % self.connection.latestResults if self.channelNumber in self.connection.latestResults: return self.connection.latestResults[self.channelNumber] else: return -999 def check_status(self): """check if voltage is higher than critical value and change message """ if self.voltage > self.criticalValue and not self.statusHigh: #just went high self.statusHigh = True self.channelMessage = self.channelMessageHigh if ss is not None: if self.highSoundFile is not None: #specific high soundfile ss.playFile(os.path.join("sounds", self.highSoundFile), 1, 60.0) elif self.highIsGood: winsound.MessageBeep( winsound.MB_ICONASTERISK ) #high is good and we just went high so nice sound else: winsound.MessageBeep( winsound.MB_ICONHAND ) #high is bad and we just went high so bad sound elif self.voltage < self.criticalValue and self.statusHigh: #just went low self.statusHigh = False self.channelMessage = self.channelMessageLow if ss is not None: if self.lowSoundFile is not None: #specific high soundfile ss.playFile(os.path.join("sounds", self.lowSoundFile), 1, 60.0) if not self.highIsGood: winsound.MessageBeep( winsound.MB_ICONASTERISK ) #high is bad and we just went low so good sound else: winsound.MessageBeep( winsound.MB_ICONHAND ) #high is good and we just went low so bad sound def _voltage_changed(self): """whenever voltage is changed automatically update the status """ if self.checkValueBool: self.check_status() def _voltage_update(self): self.voltage = self._voltage_get() def format_function_voltage(value): """Format function for voltage """ if value == -999: return "Not in Use" else: return "%0.3f V" % (value) channelGroup = traitsui.VGroup( traitsui.HGroup( traitsui.Item('channelNumber', label="Channel Number", style="readonly", editor=traitsui.EnumEditor()), traitsui.Item('checkValueBool', label="Check Value")), traitsui.Item('channelName', label="Channel Name", style="readonly"), traitsui.Item('channelMessage', show_label=False, style="readonly", style_sheet='* { font-size: 16px; }'), traitsui.Item('voltage', show_label=False, style="readonly", format_func=format_function_voltage, style_sheet='* { font-size: 18px; }'), traitsui.Item('criticalValue', label="Critical Voltage", show_label=True, style_sheet='* { font-size: 8px; }'), traitsui.Item('plotScale', label="Plot Scale Factor", show_label=True, style_sheet='* { font-size: 8px; }'), show_border=True) def __init__(self, channelNumber, connection, **traitsDict): super(ADCChannel, self).__init__(**traitsDict) self.connection = connection self.channelNumber = channelNumber if self.channelName is "": self.channelName = "Channel %s" % channelNumber traits_view = traitsui.View(channelGroup)
class FlowOpFrame(ta.HasTraits): # key_list = range(1,21) # this_key = ta.Enum(key_list) output_file = ta.Str('') this_flow_time = ta.Str('t_f6.01') this_t_sum = ta.Str('ts63') this_parameter = ta.Str('A') do_chi = ta.Bool(True) do_chi_err = ta.Bool(True) Load = ta.Button() Show = ta.Button() Show_latex = ta.Button() Apply = ta.Button() # view = tua.View(tua.Item('output_file'), tua.Item('this_flow_time'), tua.Item('this_t_sum'), tua.Item('this_parameter'), tua.Item('do_chi'), tua.Item('do_chi_err', enabled_when='do_chi'), tua.Item('Load', show_label=False), tua.Item('Show', show_label=False), tua.Item('Show_latex', show_label=False), tua.Item('Apply', show_label=False), buttons=['OK'], resizable=True) # def _Load_fired(self): global xml_data if xml_data is None: raise EnvironmentError('plot data has not been loaded') # self.key_list = xml_data.plot_data.keys() self.output_file = xml_data['Results']['save_file'] def _Show_fired(self): global xml_data print(unparse(xml_data, pretty=True)) def _Show_latex_fired(self): global latex_data if latex_data is None: print('latex data not generated yet') else: print(latex_data) def _Apply_fired(self): global xml_data, latex_data this_data = xml_data['Results'] vall, ilist, chil, slist1, slist2 = [], [], [], [], [] if 'Chi_boot' not in list(this_data.keys()): print('Integrated FlowOp result not in keys') else: this_data = this_data['Chi_boot'] if self.this_flow_time not in list(this_data.keys()): print(self.this_flow_time, ' not in flow time keys ') print(list(this_data.keys())) return this_data = this_data[self.this_flow_time] if isinstance(this_data, dict) or isinstance( this_data, OrderedDict): vall.append( MakeValAndErr(this_data['Avg'], this_data['Std'], latex=True)) else: vall.append(this_data) chil.append('N.A.') ilist.append('chiint') this_data = xml_data['Results'] if 'Prop_Fit' not in list(this_data.keys()): print('Fits not in keys') print(list(this_data.keys())) return this_data = this_data['Prop_Fit'] if self.this_flow_time not in list(this_data.keys()): print(self.this_flow_time, ' not in flow time keys ') print(list(this_data.keys())) return this_data = this_data[self.this_flow_time] if self.this_t_sum not in list(this_data.keys()): print(self.this_t_sum, ' not in sum source time keys ') print(list(this_data.keys())) return this_data = this_data[self.this_t_sum] for ikey, idata in this_data.items(): this_p = self.this_parameter if this_p in list(idata.keys()): if isinstance(idata[this_p], dict) or isinstance( idata[this_p], OrderedDict): vall.append( MakeValAndErr(idata[this_p]['Avg'], idata[this_p]['Std'], latex=True)) else: vall.append(idata[this_p]) if 'Chi_pow_2_pdf' in list(idata.keys()): if isinstance(idata['Chi_pow_2_pdf'], dict) or isinstance( idata['Chi_pow_2_pdf'], OrderedDict): chil.append( MakeValAndErr(idata['Chi_pow_2_pdf']['Avg'], idata['Chi_pow_2_pdf']['Std'], latex=True)) else: chil.append(idata['Chi_pow_2_pdf']) ilist.append(ikey) leftval, rightval = list( map(float, ikey.replace('fitr', '').split('-'))) slist1.append(1 / rightval) slist2.append(leftval) dump, dump2, ilisttemp, valltemp, chiltemp = (list(x) for x in zip( *sorted(zip(slist1, slist2, ilist[1:], vall[1:], chil[1:])))) ilist = [ilist[0]] + ilisttemp vall = [vall[0]] + valltemp chil = [chil[0]] + chiltemp latex_data = pa.DataFrame(index=ilist) latex_data.loc[:, self.this_parameter + ' Avg'] = pa.Series(vall, index=ilist) if len(vall) == len(chil) and self.do_chi: latex_data.loc[:, self.this_parameter + ' chi2pdf'] = pa.Series( chil, index=ilist) with open(xml_data['Results']['save_file'], 'w') as f: format_output = FormatLatex(latex_data.to_latex(escape=False)) f.write(format_output)
class GCS(t.HasTraits): """ This is the ground control station GUI class. For usage, for example if telemetry radio is on COM8 and the GCS Pixhawk is on COM7: >>> gcs = GCS() >>> gcs.setup_uav_link("COM8") >>> gcs.poll_uav() >>> gcs.setup_gcs_link("COM7") >>> gcs.poll_gcs() >>> gcs.configure_traits() >>> gcs.close() """ # Connections dialect = t.Str("gcs_pixhawk") show_errors = t.Bool(True) # ON GCS: Outgoing mission_message = t.Enum(set_mission_mode.keys(), label="Mission Type") sweep_angle = t.Float(label="Angle (degrees)") sweep_alt_start = t.Float(label="Start Altitude (m)") sweep_alt_end = t.Float(label="End Altitude (m)") sweep_alt_step = t.Float(label="Number of Altitude Steps") mavlink_message = t.Enum(mavlink_msgs, label="Mavlink Message") mavlink_message_filt = t.Enum(mavlink_msgs_filt, label="Mavlink Message") mavlink_message_params = t.Str(label="params") mavlink_message_args = t.Str(', '.join( mavlink_msgs_attr[mavlink_msgs_filt[0]]['args'][1:]), label="Arguments") # ON GCS: Incoming # Tether tether_length = t.Float(t.Undefined, label='Length (m)') tether_tension = t.Float(t.Undefined, label='Tension (N)') tether_velocity = t.Float(t.Undefined, label="Velocity") # ON GCS: Incoming # GCS Pixhawk gcs_eph = t.Float(t.Undefined) gcs_epv = t.Float(t.Undefined) gcs_satellites_visible = t.Int(t.Undefined) gcs_fix_type = t.Int(t.Undefined) gcs_airspeed = t.Float(t.Undefined) gcs_groundspeed = t.Float(t.Undefined) gcs_heading = t.Float(t.Undefined) gcs_velocity = t.Array(shape=(3, )) # Location inputs gcs_alt = t.Float(t.Undefined) gcs_lat = t.Float(t.Undefined) gcs_lon = t.Float(t.Undefined) # Attitude inputs gcs_pitch = t.Float(t.Undefined) gcs_roll = t.Float(t.Undefined) gcs_yaw = t.Float(t.Undefined) gcs_pitchspeed = t.Float(t.Undefined) gcs_yawspeed = t.Float(t.Undefined) gcs_rollspeed = t.Float(t.Undefined) # Battery Inputs gcs_current = t.Float(t.Undefined) gcs_level = t.Float(t.Undefined) gcs_voltage = t.Float(t.Undefined) # GCS connectinos gcs = t.Any(t.Undefined) gcs_polling = t.Bool(False) gcs_msg_thread = t.Instance(threading.Thread) gcs_error = t.Int(0) gcs_port = t.Str(t.Undefined) gcs_baud = t.Int(t.Undefined) # ON DRONE: Incoming # Mission Status mission_status = t.Enum(mission_status.keys()) # Probe probe_u = t.Float(t.Undefined, label="u (m/s)") probe_v = t.Float(t.Undefined, label="v (m/s)") probe_w = t.Float(t.Undefined, label="w (m/s)") # Vehicle inputs uav_modename = t.Str(t.Undefined) uav_armed = t.Bool(t.Undefined) uav_eph = t.Float(t.Undefined) uav_epv = t.Float(t.Undefined) uav_satellites_visible = t.Int(t.Undefined) uav_fix_type = t.Int(t.Undefined) uav_airspeed = t.Float(t.Undefined) uav_groundspeed = t.Float(t.Undefined) uav_heading = t.Float(t.Undefined) uav_velocity = t.Array(shape=(3, )) # Location inputs uav_alt = t.Float(t.Undefined) uav_lat = t.Float(t.Undefined) uav_lon = t.Float(t.Undefined) # Attitude inputs uav_pitch = t.Float(t.Undefined) uav_roll = t.Float(t.Undefined) uav_yaw = t.Float(t.Undefined) uav_pitchspeed = t.Float(t.Undefined) uav_yawspeed = t.Float(t.Undefined) uav_rollspeed = t.Float(t.Undefined) # Battery Inputs uav_current = t.Float(t.Undefined) uav_level = t.Float(t.Undefined) uav_voltage = t.Float(t.Undefined) # Vehicle Connections uav = t.Any(t.Undefined) uav_polling = t.Bool(False) uav_msg_thread = t.Instance(threading.Thread) uav_error = t.Int(0) uav_port = t.Str(t.Undefined) uav_baud = t.Int(t.Undefined) # GCS connectinos gcs = t.Any(t.Undefined) gcs_polling = t.Bool(False) gcs_msg_thread = t.Instance(threading.Thread) gcs_error = t.Int(0) gcs_port = t.Str(t.Undefined) gcs_baud = t.Int(t.Undefined) # ui Buttons and display groups update_mission = t.Button("Update") send_mavlink_message = t.Button("Send") filtered = t.Bool(True) group_input = tui.Group( tui.Item(name="mission_status", enabled_when='False'), tui.Item(name="mission_message"), tui.Item(name="sweep_angle", visible_when='mission_message=="SCHEDULE_SWEEP"'), tui.Item(name="sweep_alt_start", visible_when='mission_message=="SCHEDULE_SWEEP"'), tui.Item(name="sweep_alt_end", visible_when='mission_message=="SCHEDULE_SWEEP"'), tui.Item(name="sweep_alt_step", visible_when='mission_message=="SCHEDULE_SWEEP"'), tui.Item(name="update_mission"), tui.Item("_"), tui.Item("filtered"), tui.Item("mavlink_message", visible_when='filtered==False'), tui.Item("mavlink_message_filt", visible_when='filtered'), tui.Item("mavlink_message_args", enabled_when='False', editor=tui.TextEditor(), height=-40), tui.Item("mavlink_message_params"), tui.Item("send_mavlink_message"), tui.Item("_"), tui.Item(name="tether_tension", enabled_when='False'), tui.Item(name="tether_length", enabled_when='False'), tui.Item(name="tether_velocity", enabled_when='False'), tui.Item("_"), orientation="vertical", show_border=True, label="On GCS") group_uav = tui.Group(tui.Item(name="uav_modename", enabled_when='False'), tui.Item(name="uav_airspeed", enabled_when='False'), tui.Item(name="uav_groundspeed", enabled_when='False'), tui.Item(name='uav_armed', enabled_when='False'), tui.Item(name='uav_alt', enabled_when='False'), tui.Item(name='uav_lat', enabled_when='False'), tui.Item(name='uav_lon', enabled_when='False'), tui.Item(name='uav_velocity', enabled_when='False'), tui.Item(name='uav_pitch', enabled_when='False'), tui.Item(name='uav_roll', enabled_when='False'), tui.Item(name='uav_yaw', enabled_when='False'), tui.Item(name='uav_current', enabled_when='False'), tui.Item(name='uav_level', enabled_when='False'), tui.Item(name='uav_voltage', enabled_when='False'), tui.Item("_"), tui.Item(name='probe_u', enabled_when='False'), tui.Item(name='probe_v', enabled_when='False'), tui.Item(name='probe_w', enabled_when='False'), orientation='vertical', show_border=True, label="Incoming") group_gcs = tui.Group(tui.Item(name="gcs_airspeed", enabled_when='False'), tui.Item(name="gcs_groundspeed", enabled_when='False'), tui.Item(name='gcs_alt', enabled_when='False'), tui.Item(name='gcs_lat', enabled_when='False'), tui.Item(name='gcs_lon', enabled_when='False'), tui.Item(name='gcs_velocity', enabled_when='False'), tui.Item(name='gcs_pitch', enabled_when='False'), tui.Item(name='gcs_roll', enabled_when='False'), tui.Item(name='gcs_yaw', enabled_when='False'), tui.Item(name='gcs_current', enabled_when='False'), tui.Item(name='gcs_level', enabled_when='False'), tui.Item(name='gcs_voltage', enabled_when='False'), orientation='vertical', show_border=True, label="GCS") traits_view = tui.View(tui.Group(group_input, group_uav, group_gcs, orientation='horizontal'), resizable=True) def _update_mission_fired(self): """ This will fire when the update_mission button is clicked In that case we send one of our custom MAVLINK messages, either set_mission_mode or schedule_sweep """ mode = set_mission_mode[self.mission_message] if mode >= 0: self.uav.mav.set_mission_mode_send(mode) else: self.uav.mav.schedule_sweep_send(self.sweep_angle, self.sweep_alt_start, self.sweep_alt_end, self.sweep_alt_step) def _mavlink_message_changed(self): """ This will fire when the dropdown is changed """ self.mavlink_message_args = ', '.join( mavlink_msgs_attr[self.mavlink_message]['args'][1:]) def _mavlink_message_filt_changed(self): """ This will fire when the filtered dropdown is changed """ self.mavlink_message_args = ', '.join( mavlink_msgs_attr[self.mavlink_message_filt]['args'][1:]) def _send_mavlink_message_fired(self): """ This will fire when the send_mavlink_message button is clicked In that case we pass on the mavlink message that the user is trying to send. """ func = mavlink_msgs_attr[self.mavlink_message]['name'] args = [float(m) for m in self.mavlink_message_params.split(',')] getattr(self.uav.mav, func)(*args) def setup_uav_link(self, uav_port, uav_baud=56700): """ This sets up the connection to the UAV. Parameters ----------- uav_port : str Serial port where UAV is connected (via telemetry radio) uav_baud: int, optional The baud rate. Default is 56700 """ mavutil.set_dialect(self.dialect) self.uav = mavutil.mavlink_connection(uav_port, uav_baud) self.uav_port = uav_port self.uav_baud = uav_baud def setup_gcs_link(self, gcs_port, gcs_baud=115200): """ This sets up the connection to the GCS Pixhawk. Parameters ----------- uav_port : str Serial port where GCS Pixhawk is connected (via usb cable) uav_baud: int, optional The baud rate. Default is 115200 """ mavutil.set_dialect(self.dialect) self.gcs = mavutil.mavlink_connection(gcs_port, gcs_baud) self.gcs_port = gcs_port self.gcs_baud = gcs_baud def poll_uav(self): """ This runs a new thread that listens for messages from the UAV and parses them for the GCS """ self.uav_polling = True def worker(): # Make sure we are connected m = self.uav m.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS, mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0) print("Waiting for heartbeat from %s" % m.address) self.uav.wait_heartbeat() print "Found Heardbeat, continuing" i = 0 while self.uav_polling: # print "uav_polling round", i i += 1 try: s = m.recv(16 * 1024) except Exception: time.sleep(0.1) # prevent a dead serial port from causing the CPU to spin. The user hitting enter will # cause it to try and reconnect if len(s) == 0: time.sleep(0.1) if 'windows' in platform.architecture()[-1].lower(): # strip nsh ansi codes s = s.replace("\033[K", "") if m.first_byte: m.auto_mavlink_version(s) msgs = m.mav.parse_buffer(s) if msgs: for msg in msgs: if getattr(m, '_timestamp', None) is None: m.post_message(msg) if msg.get_type() == "BAD_DATA": if self.show_errors: print "MAV error: %s" % msg self.uav_error += 1 else: self.parse_uav_msg(msg) print "uav_polling Stopped" self.uav_polling = False self.uav_msg_thread = threading.Thread(target=worker) self.uav_msg_thread.start() def poll_gcs(self): """ This runs a new thread that listens for messages from the GCS Pixhawk and parses them for the GCS, it also forwards relevant messages to the UAV """ self.gcs_polling = True def worker(): # Make sure we are connected m = self.gcs m.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS, mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0) print("Waiting for heartbeat from %s" % m.address) self.gcs.wait_heartbeat() print "Found Heardbeat, continuing" i = 0 while self.gcs_polling: # print "gcs_polling round", i i += 1 try: s = m.recv(16 * 1024) except Exception: time.sleep(0.1) # prevent a dead serial port from causing the CPU to spin. The user hitting enter will # cause it to try and reconnect if len(s) == 0: time.sleep(0.1) if 'windows' in platform.architecture()[-1].lower(): # strip nsh ansi codes s = s.replace("\033[K", "") if m.first_byte: m.auto_mavlink_version(s) msgs = m.mav.parse_buffer(s) if msgs: for msg in msgs: if getattr(m, '_timestamp', None) is None: m.post_message(msg) if msg.get_type() == "BAD_DATA": if self.show_errors: print "MAV error: %s" % msg self.gcs_error += 1 else: self.parsefwd_gcs_msg(msg) print "gcs_polling Stopped" self.gcs_polling = False self.gcs_msg_thread = threading.Thread(target=worker) self.gcs_msg_thread.start() def parse_uav_msg(self, m): """ This parses a message received from the UAV and stores the values in the class attributes so that the GUI will update """ # print "Parsing Message" typ = m.get_type() if typ == 'GLOBAL_POSITION_INT': (self.uav_lat, self.uav_lon) = (m.lat / 1.0e7, m.lon / 1.0e7) self.uav_velocity = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) elif typ == 'GPS_RAW': pass # better to just use global position int # (self.lat, self.lon) = (m.lat, m.lon) # self.__on_change('location') elif typ == 'GPS_RAW_INT': # (self.lat, self.lon) = (m.lat / 1.0e7, m.lon / 1.0e7) self.uav_eph = m.eph self.uav_epv = m.epv self.uav_satellites_visible = m.satellites_visible self.uav_fix_type = m.fix_type elif typ == "VFR_HUD": self.uav_heading = m.heading self.uav_alt = m.alt self.uav_airspeed = m.airspeed self.uav_groundspeed = m.groundspeed elif typ == "ATTITUDE": self.uav_pitch = m.pitch self.uav_yaw = m.yaw self.uav_roll = m.roll self.uav_pitchspeed = m.pitchspeed self.uav_yawspeed = m.yawspeed self.uav_rollspeed = m.rollspeed elif typ == "SYS_STATUS": self.uav_voltage = m.voltage_battery self.uav_current = m.current_battery self.uav_level = m.battery_remaining elif typ == "HEARTBEAT": pass # print "Parsing Message DONE" def fwd_msg_to_uav(self, m): """This forwards messages from the GCS Pixhawk to the UAV if there is a UAV connected""" if self.uav is not t.Undefined: self.uav.write(m.get_msgbuf()) def parsefwd_gcs_msg(self, m): """ This parses a message received from the GCS Pixhawk, stores the values in the class attributes so that the GUI will update, and forwards relevant messages to the UAV """ # print "Parsing Message" typ = m.get_type() if typ == 'GLOBAL_POSITION_INT': (self.gcs_lat, self.gcs_lon) = (m.lat / 1.0e7, m.lon / 1.0e7) self.gcs_velocity = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) # Forward message self.fwd_msg_to_uav(m) elif typ == 'GPS_RAW': # better to just use global position int # (self.lat, self.lon) = (m.lat, m.lon) # self.__on_change('location') # Forward message self.fwd_msg_to_uav(m) elif typ == 'GPS_RAW_INT': # (self.lat, self.lon) = (m.lat / 1.0e7, m.lon / 1.0e7) self.gcs_eph = m.eph self.gcs_epv = m.epv self.gcs_satellites_visible = m.satellites_visible self.gcs_fix_type = m.fix_type # Forward message self.fwd_msg_to_uav(m) elif typ == "VFR_HUD": self.gcs_heading = m.heading self.gcs_alt = m.alt self.gcs_airspeed = m.airspeed self.gcs_groundspeed = m.groundspeed # Forward message self.fwd_msg_to_uav(m) elif typ == "ATTITUDE": self.gcs_pitch = m.pitch self.gcs_yaw = m.yaw self.gcs_roll = m.roll self.gcs_pitchspeed = m.pitchspeed self.gcs_yawspeed = m.yawspeed self.gcs_rollspeed = m.rollspeed # Forward message self.fwd_msg_to_uav(m) elif typ == "SYS_STATUS": self.gcs_voltage = m.voltage_battery self.gcs_current = m.current_battery self.gcs_level = m.battery_remaining elif typ == "HEARTBEAT": # Forward message self.fwd_msg_to_uav(m) # print "Parsing Message DONE" def close(self, *args, **kwargs): """ This closes down the serial connections and stop the GUI polling """ print 'Closing down connection' try: self.uav_polling = False self.uav.close() except: pass try: self.gcs_polling = False self.gcs.close() except: pass
class Parameter(traits.HasTraits): """represents a lmfit variable in a fit. E.g. the standard deviation in a gaussian fit""" parameter = traits.Instance(lmfit.Parameter) name = traits.Str initialValue = traits.Float calculatedValue = traits.Float vary = traits.Bool(True) minimumEnable = traits.Bool(False) minimum = traits.Float maximumEnable = traits.Bool(False) maximum = traits.Float stdevError = traits.Float def __init__(self, **traitsDict): super(Parameter, self).__init__(**traitsDict) self.parameter = lmfit.Parameter(name=self.name) def _initialValue_changed(self): self.parameter.set(value=self.initialValue) def _vary_changed(self): self.parameter.set(vary=self.vary) def _minimum_changed(self): if self.minimumEnable: self.parameter.set(min=self.minimum) def _maximum_changed(self): if self.maximumEnable: self.parameter.set(max=self.maximum) traits_view = traitsui.View(traitsui.VGroup( traitsui.HGroup( traitsui.Item("vary", label="vary?", resizable=True), traitsui.Item("name", show_label=False, style="readonly", width=0.2, resizable=True), traitsui.Item("initialValue", label="initial", show_label=True, resizable=True), traitsui.Item("calculatedValue", label="calculated", show_label=True, format_str="%G", style="readonly", width=0.2, resizable=True), traitsui.Item("stdevError", show_label=False, format_str=u"\u00B1%G", style="readonly", resizable=True)), traitsui.HGroup( traitsui.Item("minimumEnable", label="min?", resizable=True), traitsui.Item("minimum", label="min", resizable=True, visible_when="minimumEnable"), traitsui.Item("maximumEnable", label="max?", resizable=True), traitsui.Item("maximum", label="max", resizable=True, visible_when="maximumEnable"))), kind="subpanel")
class SpikesRemoval(SpanSelectorInSignal1D): interpolator_kind = t.Enum( 'Linear', 'Spline', default='Linear', desc="the type of interpolation to use when\n" "replacing the signal where a spike has been replaced") threshold = t.Float(desc="the derivative magnitude threshold above\n" "which to find spikes") click_to_show_instructions = t.Button() show_derivative_histogram = t.Button() spline_order = t.Range(1, 10, 3, desc="the order of the spline used to\n" "connect the reconstructed data") interpolator = None default_spike_width = t.Int( 5, desc="the width over which to do the interpolation\n" "when removing a spike (this can be " "adjusted for each\nspike by clicking " "and dragging on the display during\n" "spike replacement)") index = t.Int(0) add_noise = t.Bool(True, desc="whether to add noise to the interpolated\nportion" "of the spectrum. The noise properties defined\n" "in the Signal metadata are used if present," "otherwise\nshot noise is used as a default") thisOKButton = tu.Action(name="OK", action="OK", tooltip="Close the spikes removal tool") thisApplyButton = tu.Action(name="Remove spike", action="apply", tooltip="Remove the current spike by " "interpolating\n" "with the specified settings (and find\n" "the next spike automatically)") thisFindButton = tu.Action( name="Find next", action="find", tooltip="Find the next (in terms of navigation\n" "dimensions) spike in the data.") thisPreviousButton = tu.Action(name="Find previous", action="back", tooltip="Find the previous (in terms of " "navigation\n" "dimensions) spike in the data.") view = tu.View( tu.Group( tu.Group( tu.Item( 'click_to_show_instructions', show_label=False, ), tu.Item('show_derivative_histogram', show_label=False, tooltip="To determine the appropriate threshold,\n" "plot the derivative magnitude histogram, \n" "and look for outliers at high magnitudes \n" "(which represent sudden spikes in the data)"), 'threshold', show_border=True, ), tu.Group('add_noise', 'interpolator_kind', 'default_spike_width', tu.Group('spline_order', enabled_when='interpolator_kind == \'Spline\''), show_border=True, label='Advanced settings'), ), buttons=[ thisOKButton, thisPreviousButton, thisFindButton, thisApplyButton, ], handler=SpikesRemovalHandler, title='Spikes removal tool', resizable=False, ) def __init__(self, signal, navigation_mask=None, signal_mask=None): super(SpikesRemoval, self).__init__(signal) self.interpolated_line = None self.coordinates = [ coordinate for coordinate in signal.axes_manager._am_indices_generator() if (navigation_mask is None or not navigation_mask[coordinate[::-1]]) ] self.signal = signal self.line = signal._plot.signal_plot.ax_lines[0] self.ax = signal._plot.signal_plot.ax signal._plot.auto_update_plot = False if len(self.coordinates) > 1: signal.axes_manager.indices = self.coordinates[0] self.threshold = 400 self.index = 0 self.argmax = None self.derivmax = None self.kind = "linear" self._temp_mask = np.zeros(self.signal().shape, dtype='bool') self.signal_mask = signal_mask self.navigation_mask = navigation_mask md = self.signal.metadata from hyperspy.signal import BaseSignal if "Signal.Noise_properties" in md: if "Signal.Noise_properties.variance" in md: self.noise_variance = md.Signal.Noise_properties.variance if isinstance(md.Signal.Noise_properties.variance, BaseSignal): self.noise_type = "heteroscedastic" else: self.noise_type = "white" else: self.noise_type = "shot noise" else: self.noise_type = "shot noise" def _threshold_changed(self, old, new): self.index = 0 self.update_plot() def _click_to_show_instructions_fired(self): m = information(None, "\nTo remove spikes from the data:\n\n" " 1. Click \"Show derivative histogram\" to " "determine at what magnitude the spikes are present.\n" " 2. Enter a suitable threshold (lower than the " "lowest magnitude outlier in the histogram) in the " "\"Threshold\" box, which will be the magnitude " "from which to search. \n" " 3. Click \"Find next\" to find the first spike.\n" " 4. If desired, the width and position of the " "boundaries used to replace the spike can be " "adjusted by clicking and dragging on the displayed " "plot.\n " " 5. View the spike (and the replacement data that " "will be added) and click \"Remove spike\" in order " "to alter the data as shown. The tool will " "automatically find the next spike to replace.\n" " 6. Repeat this process for each spike throughout " "the dataset, until the end of the dataset is " "reached.\n" " 7. Click \"OK\" when finished to close the spikes " "removal tool.\n\n" "Note: Various settings can be configured in " "the \"Advanced settings\" section. Hover the " "mouse over each parameter for a description of what " "it does." "\n", title="Instructions"), def _show_derivative_histogram_fired(self): self.signal._spikes_diagnosis(signal_mask=self.signal_mask, navigation_mask=self.navigation_mask) def detect_spike(self): derivative = np.diff(self.signal()) if self.signal_mask is not None: derivative[self.signal_mask[:-1]] = 0 if self.argmax is not None: left, right = self.get_interpolation_range() self._temp_mask[left:right] = True derivative[self._temp_mask[:-1]] = 0 if abs(derivative.max()) >= self.threshold: self.argmax = derivative.argmax() self.derivmax = abs(derivative.max()) return True else: return False def _reset_line(self): if self.interpolated_line is not None: self.interpolated_line.close() self.interpolated_line = None self.reset_span_selector() def find(self, back=False): self._reset_line() ncoordinates = len(self.coordinates) spike = self.detect_spike() while not spike and ((self.index < ncoordinates - 1 and back is False) or (self.index > 0 and back is True)): if back is False: self.index += 1 else: self.index -= 1 spike = self.detect_spike() if spike is False: messages.information('End of dataset reached') self.index = 0 self._reset_line() return else: minimum = max(0, self.argmax - 50) maximum = min(len(self.signal()) - 1, self.argmax + 50) thresh_label = DerivativeTextParameters( text="$\mathsf{\delta}_\mathsf{max}=$", color="black") self.ax.legend([thresh_label], [repr(int(self.derivmax))], handler_map={ DerivativeTextParameters: DerivativeTextHandler() }, loc='best') self.ax.set_xlim( self.signal.axes_manager.signal_axes[0].index2value(minimum), self.signal.axes_manager.signal_axes[0].index2value(maximum)) self.update_plot() self.create_interpolation_line() def update_plot(self): if self.interpolated_line is not None: self.interpolated_line.close() self.interpolated_line = None self.reset_span_selector() self.update_spectrum_line() if len(self.coordinates) > 1: self.signal._plot.pointer._update_patch_position() def update_spectrum_line(self): self.line.auto_update = True self.line.update() self.line.auto_update = False def _index_changed(self, old, new): self.signal.axes_manager.indices = self.coordinates[new] self.argmax = None self._temp_mask[:] = False def on_disabling_span_selector(self): if self.interpolated_line is not None: self.interpolated_line.close() self.interpolated_line = None def _spline_order_changed(self, old, new): self.kind = self.spline_order self.span_selector_changed() def _add_noise_changed(self, old, new): self.span_selector_changed() def _interpolator_kind_changed(self, old, new): if new == 'linear': self.kind = new else: self.kind = self.spline_order self.span_selector_changed() def _ss_left_value_changed(self, old, new): if not (np.isnan(self.ss_right_value) or np.isnan(self.ss_left_value)): self.span_selector_changed() def _ss_right_value_changed(self, old, new): if not (np.isnan(self.ss_right_value) or np.isnan(self.ss_left_value)): self.span_selector_changed() def create_interpolation_line(self): self.interpolated_line = drawing.signal1d.Signal1DLine() self.interpolated_line.data_function = self.get_interpolated_spectrum self.interpolated_line.set_line_properties(color='blue', type='line') self.signal._plot.signal_plot.add_line(self.interpolated_line) self.interpolated_line.autoscale = False self.interpolated_line.plot() def get_interpolation_range(self): axis = self.signal.axes_manager.signal_axes[0] if np.isnan(self.ss_left_value) or np.isnan(self.ss_right_value): left = self.argmax - self.default_spike_width right = self.argmax + self.default_spike_width else: left = axis.value2index(self.ss_left_value) right = axis.value2index(self.ss_right_value) # Clip to the axis dimensions nchannels = self.signal.axes_manager.signal_shape[0] left = left if left >= 0 else 0 right = right if right < nchannels else nchannels - 1 return left, right def get_interpolated_spectrum(self, axes_manager=None): data = self.signal().copy() axis = self.signal.axes_manager.signal_axes[0] left, right = self.get_interpolation_range() if self.kind == 'linear': pad = 1 else: pad = 10 ileft = left - pad iright = right + pad ileft = np.clip(ileft, 0, len(data)) iright = np.clip(iright, 0, len(data)) left = int(np.clip(left, 0, len(data))) right = int(np.clip(right, 0, len(data))) x = np.hstack((axis.axis[ileft:left], axis.axis[right:iright])) y = np.hstack((data[ileft:left], data[right:iright])) if ileft == 0: # Extrapolate to the left data[left:right] = data[right + 1] elif iright == (len(data) - 1): # Extrapolate to the right data[left:right] = data[left - 1] else: # Interpolate intp = sp.interpolate.interp1d(x, y, kind=self.kind) data[left:right] = intp(axis.axis[left:right]) # Add noise if self.add_noise is True: if self.noise_type == "white": data[left:right] += np.random.normal(scale=np.sqrt( self.noise_variance), size=right - left) elif self.noise_type == "heteroscedastic": noise_variance = self.noise_variance( axes_manager=self.signal.axes_manager)[left:right] noise = [ np.random.normal(scale=np.sqrt(item)) for item in noise_variance ] data[left:right] += noise else: data[left:right] = np.random.poisson( np.clip(data[left:right], 0, np.inf)) return data def span_selector_changed(self): if self.interpolated_line is None: return else: self.interpolated_line.update() def apply(self): self.signal()[:] = self.get_interpolated_spectrum() self.signal.events.data_changed.trigger(obj=self.signal) self.update_spectrum_line() self.interpolated_line.close() self.interpolated_line = None self.reset_span_selector() self.find()
class ComponentFit(SpanSelectorInSignal1D): only_current = t.Bool(True) iterpath = t.Enum( 'flyback', 'serpentine', default='serpentine', desc='Define the iterating pattern over the navigation space.') def __init__(self, model, component, signal_range=None, estimate_parameters=True, fit_independent=False, only_current=True, iterpath='flyback', **kwargs): if model.signal.axes_manager.signal_dimension != 1: raise SignalDimensionError( model.signal.axes_manager.signal_dimension, 1) self.signal = model.signal self.axis = self.signal.axes_manager.signal_axes[0] self.span_selector = None self.model = model self.component = component self.signal_range = signal_range self.estimate_parameters = estimate_parameters self.fit_independent = fit_independent self.fit_kwargs = kwargs self.only_current = only_current self.iterpath = iterpath if signal_range == "interactive": if (not hasattr(self.model, '_plot') or self.model._plot is None or not self.model._plot.is_active): self.model.plot() self.span_selector_switch(on=True) def _fit_fired(self): if (self.signal_range != "interactive" and self.signal_range is not None): self.model.set_signal_range(*self.signal_range) elif self.signal_range == "interactive": self.model.set_signal_range(self.ss_left_value, self.ss_right_value) # Backup "free state" of the parameters and fix all but those # of the chosen component if self.fit_independent: active_state = [] for component_ in self.model: active_state.append(component_.active) if component_ is not self.component: component_.active = False else: component_.active = True else: free_state = [] for component_ in self.model: for parameter in component_.parameters: free_state.append(parameter.free) if component_ is not self.component: parameter.free = False # Setting reasonable initial value for parameters through # the components estimate_parameters function (if it has one) only_current = self.only_current if self.estimate_parameters: if hasattr(self.component, 'estimate_parameters'): if self.signal_range == "interactive": self.component.estimate_parameters( self.signal, self.ss_left_value, self.ss_right_value, only_current=only_current) elif self.signal_range is not None: self.component.estimate_parameters( self.signal, self.signal_range[0], self.signal_range[1], only_current=only_current) if only_current: self.model.fit(**self.fit_kwargs) else: self.model.multifit(iterpath=self.iterpath, **self.fit_kwargs) # Restore the signal range if self.signal_range is not None: self.model.channel_switches = ( self.model.backup_channel_switches.copy()) self.model.update_plot() if self.fit_independent: for component_ in self.model: component_.active = active_state.pop(0) else: # Restore the "free state" of the components for component_ in self.model: for parameter in component_.parameters: parameter.free = free_state.pop(0) def apply(self): self._fit_fired()
class Pca(Model): """Represent the PCA model of a data set.""" ds = DataSet() settings = _traits.WeakRef() # List of variable names with zero variance in the data vector zero_variance = _traits.List() #checkbox bool for standardised results standardise = _traits.Bool(False) calc_n_pc = _traits.Int() min_pc = 2 # max_pc = _traits.Property() max_pc = 10 min_std = _traits.Float(0.001) def _get_res(self): '''Does the PCA calculation and gets the results This return an results object that holds copies of the various result data. Each result set i an DataSet containing all metadata necessary for presenting the result. ''' if self.settings.standardise: std_ds = True else: std_ds = False if std_ds and self._have_zero_std_var(): raise InComputeable('Matrix have variables with zero variance', self.zero_variance) pca = PCA(self.ds.values, numComp=self.settings.calc_n_pc, Xstand=std_ds, cvType=["loo"]) return self._pack_res(pca) def _have_zero_std_var(self): sv = self.ds.values.std(axis=0) dm = sv < self.min_std if _np.any(dm): vv = _np.array(self.ds.var_n) self.zero_variance = list(vv[_np.nonzero(dm)]) return True else: self.zero_variance = [] return False def _get_max_pc(self): return max((min(self.ds.n_objs, self.ds.n_vars, 12) - 2), self.min_pc) def _calc_n_pc_default(self): return self.max_pc def _pack_res(self, pca_obj): res = Result('PCA {0}'.format(self.ds.display_name)) # Scores mT = pca_obj.X_scores() res.scores = DataSet( mat=_pd.DataFrame( data=mT, index=self.ds.obj_n, columns=["PC-{0}".format(i+1) for i in range(mT.shape[1])], ), subs=self.ds.subs, display_name='Scores') # Loadings mP = pca_obj.X_loadings() res.loadings = DataSet( mat=_pd.DataFrame( data=mP, index=self.ds.var_n, columns=["PC-{0}".format(i+1) for i in range(mP.shape[1])], ), subs=self.ds.rsubs, display_name='Loadings') # Correlation loadings mCL = pca_obj.X_corrLoadings() res.corr_loadings = DataSet( mat=_pd.DataFrame( data=mCL, index=self.ds.var_n, columns=["PC-{0}".format(i+1) for i in range(mCL.shape[1])], ), display_name='Correlation loadings') # Explained variance cal = pca_obj.X_calExplVar() cum_cal = pca_obj.X_cumCalExplVar()[1:] val = pca_obj.X_valExplVar() cum_val = pca_obj.X_cumValExplVar()[1:] res.expl_var = DataSet( mat=_pd.DataFrame( data=[cal, cum_cal, val, cum_val], index=['calibrated', 'cumulative calibrated', 'validated', 'cumulative validated'], columns=["PC-{0}".format(i+1) for i in range(len(cal))], ), display_name='Explained variance') # Residuals E after each computed PC # Return a dictionary with arrays # I can put this into a Pandas Panel 3D structure resids = pca_obj.X_residuals() # predicted matrices Xhat from calibration after each computed PC. # FIXME: Is this X_predCal() # cal_pred_x = pca_obj.calPredX() #validated matrices Xhat from calibration after each computed PC. # val_pred_x = pca_obj.valPredX() # MSEE from cross validation after each computed PC. msee = pca_obj.X_MSEE() # MSEE from cross validation after each computed PC for each variable. ind_var_msee = pca_obj.X_MSEE_indVar() # MSECV from cross validation after each computed PC. msecv = pca_obj.X_MSECV() # MSECV from cross validation after each computed PC for each variable. ind_var_msecv = pca_obj.X_MSECV_indVar() return res
class DataAxis(t.HasTraits): name = t.Str() units = t.Str() scale = t.Float() offset = t.Float() size = t.CInt() low_value = t.Float() high_value = t.Float() value = t.Range('low_value', 'high_value') low_index = t.Int(0) high_index = t.Int() slice = t.Instance(slice) navigate = t.Bool(t.Undefined) index = t.Range('low_index', 'high_index') axis = t.Array() continuous_value = t.Bool(False) def __init__(self, size, index_in_array=None, name=t.Undefined, scale=1., offset=0., units=t.Undefined, navigate=t.Undefined): super(DataAxis, self).__init__() self.name = name self.units = units self.scale = scale self.offset = offset self.size = size self.high_index = self.size - 1 self.low_index = 0 self.index = 0 self.update_axis() self.navigate = navigate self.axes_manager = None self.on_trait_change(self.update_axis, ['scale', 'offset', 'size']) self.on_trait_change(self.update_value, 'index') self.on_trait_change(self.set_index_from_value, 'value') self.on_trait_change(self._update_slice, 'navigate') self.on_trait_change(self.update_index_bounds, 'size') # The slice must be updated even if the default value did not # change to correctly set its value. self._update_slice(self.navigate) @property def index_in_array(self): if self.axes_manager is not None: return self.axes_manager._axes.index(self) else: raise AttributeError( "This DataAxis does not belong to an AxesManager" " and therefore its index_in_array attribute " " is not defined") @property def index_in_axes_manager(self): if self.axes_manager is not None: return self.axes_manager._get_axes_in_natural_order().\ index(self) else: raise AttributeError( "This DataAxis does not belong to an AxesManager" " and therefore its index_in_array attribute " " is not defined") def _get_positive_index(self, index): if index < 0: index = self.size + index if index < 0: raise IndexError("index out of bounds") return index def _get_index(self, value): if isfloat(value): return self.value2index(value) else: return value def _get_array_slices(self, slice_): """Returns a slice to slice the corresponding data axis without changing the offset and scale of the DataAxis. Parameters ---------- slice_ : {float, int, slice} Returns ------- my_slice : slice """ v2i = self.value2index if isinstance(slice_, slice): start = slice_.start stop = slice_.stop step = slice_.step else: if isfloat(slice_): start = v2i(slice_) else: start = self._get_positive_index(slice_) stop = start + 1 step = None if isfloat(step): step = int(round(step / self.scale)) if isfloat(start): try: start = v2i(start) except ValueError: # The value is below the axis limits # we slice from the start. start = None if isfloat(stop): try: stop = v2i(stop) except ValueError: # The value is above the axes limits # we slice up to the end. stop = None if step == 0: raise ValueError("slice step cannot be zero") return slice(start, stop, step) def _slice_me(self, slice_): """Returns a slice to slice the corresponding data axis and change the offset and scale of the DataAxis acordingly. Parameters ---------- slice_ : {float, int, slice} Returns ------- my_slice : slice """ i2v = self.index2value my_slice = self._get_array_slices(slice_) start, stop, step = my_slice.start, my_slice.stop, my_slice.step if start is None: if step > 0 or step is None: start = 0 else: start = self.size - 1 self.offset = i2v(start) if step is not None: self.scale *= step return my_slice def _get_name(self): if self.name is t.Undefined: if self.axes_manager is None: name = "Unnamed" else: name = "Unnamed " + ordinal(self.index_in_axes_manager) else: name = self.name return name def __repr__(self): text = '<%s axis, size: %i' % (self._get_name(), self.size,) if self.navigate is True: text += ", index: %i" % self.index text += ">" return text.encode('utf8') def __str__(self): return self._get_name() + " axis" def connect(self, f, trait='value'): self.on_trait_change(f, trait) def disconnect(self, f, trait='value'): self.on_trait_change(f, trait, remove=True) def update_index_bounds(self): self.high_index = self.size - 1 def update_axis(self): self.axis = generate_axis(self.offset, self.scale, self.size) if len(self.axis) != 0: self.low_value, self.high_value = ( self.axis.min(), self.axis.max()) def _update_slice(self, value): if value is False: self.slice = slice(None) else: self.slice = None def get_axis_dictionary(self): adict = { 'name': self.name, 'scale': self.scale, 'offset': self.offset, 'size': self.size, 'units': self.units, 'navigate': self.navigate } return adict def copy(self): return DataAxis(**self.get_axis_dictionary()) def __copy__(self): return self.copy() def __deepcopy__(self, memo): cp = self.copy() return cp def update_value(self): self.value = self.axis[self.index] def value2index(self, value, rounding=round): """Return the closest index to the given value if between the limit. Parameters ---------- value : number or numpy array Returns ------- index : integer or numpy array Raises ------ ValueError if any value is out of the axis limits. """ if value is None: return None if isinstance(value, np.ndarray): if rounding is round: rounding = np.round elif rounding is math.ceil: rounding = np.ceil elif rounding is math.floor: rounding = np.floor index = rounding((value - self.offset) / self.scale) if isinstance(value, np.ndarray): index = index.astype(int) if np.all(self.size > index) and np.all(index >= 0): return index else: raise ValueError("A value is out of the axis limits") else: index = int(index) if self.size > index >= 0: return index else: raise ValueError("The value is out of the axis limits") def index2value(self, index): if isinstance(index, np.ndarray): return self.axis[index.ravel()].reshape(index.shape) else: return self.axis[index] def set_index_from_value(self, value): self.index = self.value2index(value) # If the value is above the limits we must correct the value if self.continuous_value is False: self.value = self.index2value(self.index) def calibrate(self, value_tuple, index_tuple, modify_calibration=True): scale = (value_tuple[1] - value_tuple[0]) /\ (index_tuple[1] - index_tuple[0]) offset = value_tuple[0] - scale * index_tuple[0] if modify_calibration is True: self.offset = offset self.scale = scale else: return offset, scale def value_range_to_indices(self, v1, v2): """Convert the given range to index range. When an out of the axis limits, the endpoint is used instead. Parameters ---------- v1, v2 : float The end points of the interval in the axis units. v2 must be greater than v1. """ if v1 > v2: raise ValueError("v2 must be greater than v1.") if v1 is not None and v1 > self.low_value and v1 <= self.high_value: i1 = self.value2index(v1) else: i1 = 0 if v2 is not None and v2 < self.high_value and v2 >= self.low_value: i2 = self.value2index(v2) else: i2 = self.size - 1 return i1, i2
class config(HasTraits): uuid = traits.Str(desc="UUID") # Directories working_dir = Directory(mandatory=True, desc="Location of the Nipype working directory") base_dir = Directory(os.path.abspath('.'),exists=True, desc='Base directory of data. (Should be subject-independent)') sink_dir = Directory(mandatory=True, desc="Location where the BIP will store the results") crash_dir = Directory(mandatory=False, desc="Location to store crash files") surf_dir = Directory(os.path.abspath('.'),mandatory=True, desc="Freesurfer subjects directory") # Execution run_using_plugin = Bool(False, usedefault=True, desc="True to run pipeline with plugin, False to run serially") plugin = traits.Enum("PBS", "MultiProc", "SGE", "Condor", usedefault=True, desc="plugin to use, if run_using_plugin=True") plugin_args = traits.Dict({"qsub_args": "-q many"}, usedefault=True, desc='Plugin arguments.') test_mode = Bool(False, mandatory=False, usedefault=True, desc='Affects whether where and if the workflow keeps its \ intermediary files. True to keep intermediary files. ') # Subjects datagrabber = traits.Instance(Data, ()) subjects = traits.List(traits.Str, mandatory=True, usedefault=True, desc="Subject id's. Note: These MUST match the subject id's in the \ Freesurfer directory. For simplicity, the subject id's should \ also match with the location of individual functional files.") func_template = traits.String('%s/cleaned_resting.nii.gz') reg_template = traits.String('%s/cleaned_resting_reg.dat') ref_template = traits.String('%s/cleaned_resting_ref.nii.gz') combine_surfaces = traits.Bool() # Target surface target_surf = traits.Enum('fsaverage4', 'fsaverage3', 'fsaverage5', 'fsaverage6', 'fsaverage', 'subject', desc='which average surface to map to') surface_fwhm = traits.List([5], traits.Float(), mandatory=True, usedefault=True, desc="How much to smooth on target surface") projection_stem = traits.Str('-projfrac-avg 0 1 0.1', desc='how to project data onto the surface') combine_surfaces = traits.Bool(desc=('compute correlation matrix across' 'both left and right surfaces')) # Saving output out_type = traits.Enum('mat', 'hdf5', desc='mat or hdf5') hdf5_package = traits.Enum('h5py', 'pytables', desc='which hdf5 package to use') # Advanced Options use_advanced_options = traits.Bool() advanced_script = traits.Code() # Atlas mapping surface_atlas = traits.Str('None', desc='Name of parcellation atlas') # Buttons check_func_datagrabber = Button("Check") def _check_func_datagrabber_fired(self): subs = self.subjects for s in subs: for template in [self.func_template, self.ref_template, self.reg_template]: check_path(os.path.join(self.base_dir, template % s)) check_path(os.path.join(self.surf_dir, s))
class TimeLoop(tr.HasStrictTraits): tline = tr.Instance(TLine) '''Time line object specifying the start, end, time step and current time ''' def _tline_default(self): return TLine(min=0.0, max=1.0, step=1.0) ts = tr.Instance(ITStepperEval) '''State object delivering the predictor and corrector ''' bc_mngr = tr.Instance(BCondMngr, ()) '''Boundary condition manager. ''' bc_list = tr.List([]) '''List of boundary conditions. ''' def _bc_list_changed(self): self.bc_mngr.bcond_list = self.bc_list step_tolerance = tr.Float(1e-8) '''Time step tolerance. ''' k_max = tr.Int(300) '''Maximum number of iterations. ''' tolerance = tr.Float(1e-3) '''Tolerance of the residuum norm. ''' t_n1 = tr.Float(0, input=True) '''Target time for the next increment. ''' t_n = tr.Float(0, input=True) '''Time of the last equilibrium state. ''' d_t = tr.Float(0, input=True) '''Current time increment size. ''' paused = tr.Bool(False) restart = tr.Bool(True) stop = tr.Bool(False) def init(self): self.stop = False if self.paused: self.paused = False return if self.restart: self.tline.val = 0 # self.setup() self.restart = False self.bc_mngr.setup(None) for rt in self.response_traces: rt.setup(self) algorithmic = tr.Bool(True) def eval(self): update_state = False K = SysMtxAssembly() self.bc_mngr.apply_essential(K) U_n = np.zeros((self.ts.mesh.n_dofs, ), dtype=np.float_) dU = np.copy(U_n) U_k = np.copy(U_n) F_ext = np.zeros_like(U_n) algorithmic = self.algorithmic pos_def = True while (self.t_n1 - self.tline.max) <= self.step_tolerance: print('current time %f' % self.t_n1, end=' ') self.d_t = self.tline.step k = 0 step_flag = 'predictor' while k < self.k_max: if self.stop: return U_n K.reset_mtx() K_arr, F_int, n_F_int = self.ts.get_corr_pred( U_k, dU, self.t_n, self.t_n1, update_state, algorithmic) if update_state: update_state = False K.sys_mtx_arrays.append(K_arr) F_ext[:] = 0.0 self.bc_mngr.apply(step_flag, None, K, F_ext, self.t_n, self.t_n1) R = F_ext - F_int K.apply_constraints(R) if n_F_int == 0.0: n_F_int = 1.0 norm = np.linalg.norm(R, ord=None) # / n_F_int if norm < self.tolerance: print('converged in %d iterations' % (k + 1)) update_state = True self.record_response(U_k, F_int, self.t_n1) break dU, pos_def = K.solve(check_pos_def=algorithmic) if algorithmic and not pos_def: algorithmic = False print('switched to secant') continue U_k += dU k += 1 step_flag = 'corrector' U_n = np.copy(U_k) self.t_n = self.t_n1 self.t_n1 = self.t_n + self.d_t self.tline.val = min(self.t_n, self.tline.max) return U_n write_dir = tr.Directory F_int_record = tr.List(tr.Array(np.float_)) U_record = tr.List(tr.Array(np.float_)) F_ext_record = tr.List(tr.Array(np.float_)) t_record = tr.List response_traces = tr.List() def record_response(self, U_k, F_int, t): self.F_int_record.append(np.copy(F_int)) self.U_record.append(np.copy(U_k)) self.t_record.append(self.t_n1) for rt in self.response_traces: rt.update(U_k, t) return def get_time_idx_arr(self, vot): '''Get the index corresponding to visual time ''' x = self.t_record idx = np.array(np.arange(len(x)), dtype=np.float_) t_idx = np.interp(vot, x, idx) return np.array(t_idx + 0.5, np.int_) def get_time_idx(self, vot): return int(self.get_time_idx_arr(vot))
class config(HasTraits): uuid = traits.Str(desc="UUID") # Directories working_dir = Directory(mandatory=True, desc="Location of the Nipype working directory") base_dir = Directory( os.path.abspath('.'), mandatory=True, desc='Base directory of data. (Should be subject-independent)') sink_dir = Directory(mandatory=True, desc="Location where the BIP will store the results") crash_dir = Directory(mandatory=False, desc="Location to store crash files") # Execution run_using_plugin = Bool( False, usedefault=True, desc="True to run pipeline with plugin, False to run serially") plugin = traits.Enum("PBS", "MultiProc", "SGE", "Condor", usedefault=True, desc="plugin to use, if run_using_plugin=True") plugin_args = traits.Dict({"qsub_args": "-q many"}, usedefault=True, desc='Plugin arguments.') test_mode = Bool( False, mandatory=False, usedefault=True, desc='Affects whether where and if the workflow keeps its \ intermediary files. True to keep intermediary files. ' ) timeout = traits.Float(14.0) # Subjects """ subjects = traits.List(traits.Str, mandatory=True, usedefault=True, desc="Subject id's. Note: These MUST match the subject id's in the \ Freesurfer directory. For simplicity, the subject id's should \ also match with the location of individual functional files.") fwhm=traits.List(traits.Float()) inputs_template = traits.String('%s/preproc/output/fwhm_%s/*.nii.gz') meanfunc_template = traits.String('%s/preproc/mean/*_mean.nii.gz') fsl_mat_template = traits.String('%s/preproc/bbreg/*.mat') unwarped_brain_template = traits.String('%s/smri/unwarped_brain/*.nii*') affine_transformation_template = traits.String('%s/smri/affine_transformation/*.nii*') warp_field_template = traits.String('%s/smri/warped_field/*.nii*')""" datagrabber = traits.Instance(Data, ()) #Normalization norm_template = traits.File(mandatory=True, desc='Template to warp to') do_segment = traits.Bool(True) surf_dir = traits.Directory() # Advanced Options use_advanced_options = traits.Bool() advanced_script = traits.Code() # Buttons check_func_datagrabber = Button("Check") def _check_func_datagrabber_fired(self): subs = self.subjects template = [ self.inputs_template, self.meanfunc_template, self.fsl_mat_template, self.unwarped_brain_template, self.affine_transformation_template, self.warp_field_template ] for s in subs: for t in template: try: temp = glob(os.path.join(self.base_dir, t % s)) except TypeError: temp = [] for f in self.fwhm: temp.append( glob(os.path.join(self.base_dir, t % (s, f)))) print temp
class config(HasTraits): uuid = traits.Str(desc="UUID") # Directories working_dir = Directory(mandatory=True, desc="Location of the Nipype working directory") base_dir = Directory( os.path.abspath('.'), mandatory=True, desc='Base directory of data. (Should be subject-independent)') sink_dir = Directory(mandatory=True, desc="Location where the BIP will store the results") crash_dir = Directory(mandatory=False, desc="Location to store crash files") surf_dir = Directory( desc="freesurfer directory. subject id's should be the same") # Execution run_using_plugin = Bool( False, usedefault=True, desc="True to run pipeline with plugin, False to run serially") plugin = traits.Enum("PBS", "MultiProc", "SGE", "Condor", usedefault=True, desc="plugin to use, if run_using_plugin=True") plugin_args = traits.Dict({"qsub_args": "-q many"}, usedefault=True, desc='Plugin arguments.') test_mode = Bool( False, mandatory=False, usedefault=True, desc='Affects whether where and if the workflow keeps its \ intermediary files. True to keep intermediary files. ' ) # Data subject_id = traits.String() contrast = traits.File() mask_contrast = traits.File() use_contrast_mask = traits.Bool(True) reg_file = traits.File() mean_image = traits.File() background_thresh = traits.Float(0.5) roi = traits.List( ['superiortemporal', 'bankssts'], traits.Enum('superiortemporal', 'bankssts', 'caudalanteriorcingulate', 'caudalmiddlefrontal', 'corpuscallosum', 'cuneus', 'entorhinal', 'fusiform', 'inferiorparietal', 'inferiortemporal', 'isthmuscingulate', 'lateraloccipital', 'lateralorbitofrontal', 'lingual', 'medialorbitofrontal', 'middletemporal', 'parahippocampal', 'paracentral', 'parsopercularis', 'parsorbitalis', 'parstriangularis', 'pericalcarine', 'postcentral', 'posteriorcingulate', 'precentral', 'precuneus', 'rostralanteriorcingulate', 'rostralmiddlefrontal', 'superiorfrontal', 'superiorparietal', 'supramarginal', 'frontalpole', 'temporalpole', 'transversetemporal', 'insula'), usedefault=True) #35 freesurfer regions, thresh = traits.Float(1.5)
class PlotFrame(ta.HasTraits): # key_list = range(1,21) # this_key = ta.Enum(key_list) output_file = ta.Str('') this_data_type = ta.Enum(['data', 'fit_parameters']) transpose_table = ta.Bool(False) include_chi = ta.Bool(True) fmt_latex = ta.Bool(True) Load = ta.Button() Show = ta.Button() Show_latex = ta.Button() Apply = ta.Button() # view = tua.View(tua.Item('output_file'), tua.Item('this_data_type'), tua.Item('transpose_table'), tua.Item('include_chi'), tua.Item('fmt_latex'), tua.Item('Load', show_label=False), tua.Item('Show', show_label=False), tua.Item('Show_latex', show_label=False), tua.Item('Apply', show_label=False), buttons=['OK'], resizable=True) # def _Load_fired(self): global xml_data if xml_data is None: raise EnvironmentError('plot data has not been loaded') # self.key_list = xml_data.plot_data.keys() self.output_file = xml_data['Results']['save_file'] def _Show_fired(self): global xml_data print(unparse(xml_data, pretty=True)) def _Show_latex_fired(self): global latex_data if latex_data is None: print('latex data not generated yet') else: print(latex_data.to_string()) def _Apply_fired(self): global xml_data, latex_data this_data = xml_data['Results'] table_data = pa.DataFrame() for cfg_key, cfg_data in this_data.items(): if cfg_key in [ 'window_size_x', 'window_size_y', 'Info', 'save_file' ]: continue this_data = pa.Series() if self.this_data_type in cfg_data.keys(): if self.this_data_type == 'fit_parameters' and self.include_chi \ and 'chi_pow_2_pdf' in cfg_data.keys(): this_data[r'$\chi^{2}_{pdf}$'] = '$' + MakeValAndErr( cfg_data['chi_pow_2_pdf']['Avg'], cfg_data['chi_pow_2_pdf']['Std'], Dec=2, latex=self.fmt_latex) + '$' for data_key, data_data in cfg_data[ self.this_data_type].items(): if isinstance(data_data, dict): this_data[data_key] = '$' + MakeValAndErr( data_data['Avg'], data_data['Std'], Dec=2, latex=self.fmt_latex) + '$' else: if isinstance(data_data, (list, tuple, np.ndarray)): if len(data_data) == 2: this_data[data_key] = '$' + MakeValAndErr( data_data[0], data_data[1], Dec=2, latex=self.fmt_latex) + '$' elif len(data_data) == 1: this_data[data_key] = f'${data_data[0]:.3f}$' else: this_data[data_key] = f'${data_data[0]:.3f}$' if len(this_data) > 0: table_data[cfg_key] = this_data latex_data = table_data if self.transpose_table: latex_data = latex_data.transpose() with open(xml_data['Results']['save_file'], 'w') as f: format_output = FormatLatex(latex_data.to_latex(escape=False)) f.write(format_output)
class CSVJoiner(tr.HasStrictTraits): open_csv_files = tr.Button csv_files = tr.List(CSVFile) num_of_first_lines_to_show = tr.Range(low=0, high=10**9, value=10, mode='spinner') num_of_last_lines_to_show = tr.Range(low=0, high=10**9, value=10, mode='spinner') selected = tr.Instance(CSVFile) join_csv_files = tr.Button accumulate_time = tr.Bool files_end_with_empty_line = tr.Bool(True) columns_headers = tr.List time_column = tr.Enum(values='columns_headers') progress = tr.Int def _join_csv_files_fired(self): output_file_path = self.get_output_file_path() with open(output_file_path, 'w') as outfile: for csv_file, i in zip(self.csv_files, range(len(self.csv_files))): current_line = 1 num_of_first_lines_to_skip = csv_file.first_lines_to_skip num_of_last_lines_to_skip = csv_file.last_lines_to_skip last_line_to_write = csv_file.get_lines_number( ) - num_of_last_lines_to_skip progress_of_a_file = 1.0 / len(self.csv_files) initial_progress = i / len(self.csv_files) with open(csv_file.path) as opened_csv_file: for line in opened_csv_file: if current_line > num_of_first_lines_to_skip and current_line <= last_line_to_write: outfile.write(line) self.progress = int( (initial_progress + progress_of_a_file * (current_line / last_line_to_write)) * 100) current_line += 1 if not self.files_end_with_empty_line: outfile.write('\n') self.progress = 100 dialog = MessageDialog(title='Finished!', message='Files joined successfully, see "' + output_file_path + '"') dialog.open() def get_output_file_path(self): file_path = self.csv_files[0].path file_path_without_ext = os.path.splitext(file_path)[0] file_ext = os.path.splitext(file_path)[1] return file_path_without_ext + '_joined' + file_ext def _accumulate_time_changed(self): pass # if self.csv_files == []: # return # np.array(pd.read_csv( # self.file_csv, delimiter=self.delimiter, decimal=self.decimal, # nrows=1, header=None # ) # )[0] # if self.accumulate_time: # class TimeColumnChooser(tr.HasTraits): # time_column = tr.Enum(values = 'columns_headers') # chooser = TimeColumnChooser() # chooser.configure_traits(kind='modal') def _num_of_first_lines_to_show_changed(self): for file in self.csv_files: file.num_of_first_lines_to_show = self.num_of_first_lines_to_show def _num_of_last_lines_to_show_changed(self): for file in self.csv_files: file.num_of_last_lines_to_show = self.num_of_last_lines_to_show def _open_csv_files_fired(self): extensions = ['*.csv', '*.txt'] # handle only one extension... wildcard = ';'.join(extensions) dialog = pf.FileDialog(title='Select csv files', action='open files', wildcard=wildcard, default_path=os.path.expanduser("~")) result = dialog.open() csv_files_paths = [] # Test if the user opened a file to avoid throwing an exception # if he doesn't if result == pf.OK: csv_files_paths = dialog.paths else: return self.csv_files = [] for file_path in csv_files_paths: csv_file = CSVFile( path=file_path, num_of_first_lines_to_show=self.num_of_first_lines_to_show, num_of_last_lines_to_show=self.num_of_last_lines_to_show, ) self.csv_files.append(csv_file) # ========================================================================= # Configuration of the view # ========================================================================= traits_view = ui.View( ui.VGroup( ui.UItem('open_csv_files', width=150), ui.HGroup(ui.Item('num_of_first_lines_to_show'), ui.spring), ui.HGroup(ui.Item('num_of_last_lines_to_show'), ui.spring), ui.HGroup( ui.Item('files_end_with_empty_line'), # ui.Item('accumulate_time', enabled_when='False'), ui.spring), ui.VGroup( ui.Item('csv_files', show_label=False, style='custom', editor=ui.ListEditor(use_notebook=True, deletable=False, selected='selected', export='DockWindowShell', page_name='.name'))), ui.HGroup( ui.UItem('join_csv_files', width=150), ui.UItem('progress', editor=ProgressEditor(min=0, max=100))), show_border=True), title='CSV files joiner', resizable=True, width=0.6, height=0.7)
class Fit(traits.HasTraits): name = traits.Str(desc="name of fit") function = traits.Str(desc="function we are fitting with all parameters") variablesList = traits.List(Parameter) calculatedParametersList = traits.List(CalculatedParameter) xs = None # will be a scipy array ys = None # will be a scipy array zs = None # will be a scipy array performFitButton = traits.Button("Perform Fit") getInitialParametersButton = traits.Button("Guess Initial Values") usePreviousFitValuesButton = traits.Button("Use Previous Fit") drawRequestButton = traits.Button("Draw Fit") setSizeButton = traits.Button("Set Initial Size") chooseVariablesButtons = traits.Button("choose logged variables") logAllVariables = traits.Bool(True) logLibrarianButton = traits.Button("librarian") logLastFitButton = traits.Button("log current fit") removeLastFitButton = traits.Button("remove last fit") autoFitBool = traits.Bool( False, desc= "Automatically perform this Fit with current settings whenever a new image is loaded" ) autoDrawBool = traits.Bool( True, desc= "Once a fit is complete update the drawing of the fit or draw the fit for the first time" ) autoGuessBool = traits.Bool(False, desc="Perform a new guess before fitting") autoSizeBool = traits.Bool( False, desc= "If TOF variable is read from latest XML and is equal to 0.11ms (or time set in Physics) then it will automatically update the physics sizex and sizey with the Sigma x and sigma y from the gaussian fit" ) autoPreviousBool = traits.Bool( False, desc= "Whenever a fit is completed replace the guess values with the calculated values (useful for increasing speed of the next fit)" ) logBool = traits.Bool( False, desc="Log the calculated and fitted values with a timestamp") logName = traits.String( desc="name of the scan - will be used in the folder name") logToNas = traits.Bool( True, desc="If true, log goes to Humphry-NAS instead of ursa") ## logDirectory = os.path.join("\\\\ursa","AQOGroupFolder","Experiment Humphry","Data","eagleLogs") logDirectory = os.path.join("G:", os.sep, "Experiment Humphry", "Data", "eagleLogs") logDirectoryNas = os.path.join("\\\\192.168.16.71", "Humphry", "Data", "eagleLogs") latestSequence = os.path.join("\\\\ursa", "AQOGroupFolder", "Experiment Humphry", "Experiment Control And Software", "currentSequence", "latestSequence.xml") conditionalFitBool = traits.Bool( False, desc= "If true, fit is only executed, if current sequence contains matching variable 'eagleID'" ) conditionalFitID = traits.Int(0) logFile = traits.File(desc="file path of logFile") logAnalyserBool = traits.Bool( False, desc="only use log analyser script when True") logAnalysers = [ ] #list containing full paths to each logAnalyser file to run logAnalyserDisplayString = traits.String( desc= "comma separated read only string that is a list of all logAnalyser python scripts to run. Use button to choose files" ) logAnalyserSelectButton = traits.Button("sel. analyser", image='@icons:function_node', style="toolbar") xmlLogVariables = [] imageInspectorReference = None #will be a reference to the image inspector fitting = traits.Bool(False) #true when performing fit fitted = traits.Bool( False) #true when current data displayed has been fitted fitSubSpace = traits.Bool(True) drawSubSpace = traits.Bool(True) startX = traits.Int(230) startY = traits.Int(230) endX = traits.Int(550) endY = traits.Int(430) fittingStatus = traits.Str() fitThread = None fitTimeLimit = traits.Float( 10.0, desc= "Time limit in seconds for fitting function. Only has an effect when fitTimeLimitBool is True" ) fitTimeLimitBool = traits.Bool( True, desc= "If True then fitting functions will be limited to time limit defined by fitTimeLimit " ) physics = traits.Instance( physicsProperties.physicsProperties.PhysicsProperties) #status strings notFittedForCurrentStatus = "Not Fitted for Current Image" fittedForCurrentImageStatus = "Fit Complete for Current Image" currentlyFittingStatus = "Currently Fitting..." failedFitStatus = "Failed to finish fit. See logger" timeExceededStatus = "Fit exceeded user time limit" lmfitModel = traits.Instance( lmfit.Model ) #reference to the lmfit model must be initialised in subclass mostRecentModelResult = None # updated to the most recent ModelResult object from lmfit when a fit thread is performed fitSubSpaceGroup = traitsui.VGroup( traitsui.HGroup( traitsui.Item("fitSubSpace", label="Fit Sub Space", resizable=True), traitsui.Item("drawSubSpace")), traitsui.VGroup(traitsui.HGroup( traitsui.Item("startX", resizable=True), traitsui.Item("startY", resizable=True)), traitsui.HGroup(traitsui.Item("endX", resizable=True), traitsui.Item("endY", resizable=True)), visible_when="fitSubSpace"), label="Fit Sub Space", show_border=True) generalGroup = traitsui.VGroup(traitsui.Item("name", label="Fit Name", style="readonly", resizable=True), traitsui.Item("function", label="Fit Function", style="readonly", resizable=True), fitSubSpaceGroup, label="Fit", show_border=True) variablesGroup = traitsui.VGroup(traitsui.Item( "variablesList", editor=traitsui.ListEditor(style="custom"), show_label=False, resizable=True), show_border=True, label="parameters") derivedGroup = traitsui.VGroup(traitsui.Item( "calculatedParametersList", editor=traitsui.ListEditor(style="custom"), show_label=False, resizable=True), show_border=True, label="derived values") buttons = traitsui.HGroup( traitsui.VGroup(traitsui.HGroup( traitsui.Item("autoFitBool", label="Auto fit?", resizable=True), traitsui.Item("performFitButton", show_label=False, resizable=True)), traitsui.HGroup( traitsui.Item("autoGuessBool", label="Auto guess?", resizable=True), traitsui.Item("getInitialParametersButton", show_label=False, resizable=True)), traitsui.HGroup( traitsui.Item("autoPreviousBool", label="Auto previous?", resizable=True), traitsui.Item("usePreviousFitValuesButton", show_label=False, resizable=True)), show_border=True), traitsui.VGroup(traitsui.HGroup( traitsui.Item("autoDrawBool", label="Auto draw?", resizable=True), traitsui.Item("drawRequestButton", show_label=False, resizable=True)), traitsui.HGroup( traitsui.Item("autoSizeBool", label="Auto size?", resizable=True), traitsui.Item("setSizeButton", show_label=False, resizable=True)), traitsui.HGroup( traitsui.Item("conditionalFitBool", label="Conditional Fit?", resizable=True), traitsui.Item("conditionalFitID", label="Fit ID", resizable=True)), show_border=True)) logGroup = traitsui.VGroup( traitsui.HGroup( traitsui.Item("logBool", resizable=True), traitsui.Item("logAllVariables", resizable=True), traitsui.Item("chooseVariablesButtons", show_label=False, resizable=True, enabled_when="not logAllVariables")), traitsui.HGroup(traitsui.Item("logName", resizable=True)), traitsui.HGroup(traitsui.Item("logToNas", resizable=True)), #changed traitsui.HGroup( traitsui.Item("removeLastFitButton", show_label=False, resizable=True), traitsui.Item("logLastFitButton", show_label=False, resizable=True)), traitsui.HGroup( traitsui.Item("logAnalyserBool", label="analyser?", resizable=True), traitsui.Item("logAnalyserDisplayString", show_label=False, style="readonly", resizable=True), traitsui.Item("logAnalyserSelectButton", show_label=False, resizable=True)), label="Logging", show_border=True) actionsGroup = traitsui.VGroup(traitsui.Item("fittingStatus", style="readonly", resizable=True), logGroup, buttons, label="Fit Actions", show_border=True) traits_view = traitsui.View(traitsui.VGroup(generalGroup, variablesGroup, derivedGroup, actionsGroup), kind="subpanel") def __init__(self, **traitsDict): super(Fit, self).__init__(**traitsDict) # self.startX = 0 # self.startY = 0 self.lmfitModel = lmfit.Model(self.fitFunc) # load config with open(configFile, 'r') as f: settings = json.load(f) if 'logAnalysers' in settings: self.logAnalysers = settings['logAnalysers'] self.logAnalyserDisplayString = str( [os.path.split(path)[1] for path in self.logAnalysers]) if 'logAnalyserBool' in settings: self.logAnalyserBool = settings['logAnalyserBool'] def _set_xs(self, xs): self.xs = xs def _set_ys(self, ys): self.ys = ys def _set_zs(self, zs): self.zs = zs def _fittingStatus_default(self): return self.notFittedForCurrentStatus def _getInitialValues(self): """returns ordered list of initial values from variables List """ return [_.initialValue for _ in self.variablesList] def _getParameters(self): """creates an lmfit parameters object based on the user input in variablesList """ return lmfit.Parameters( {_.name: _.parameter for _ in self.variablesList}) def _getCalculatedValues(self): """returns ordered list of fitted values from variables List """ return [_.calculatedValue for _ in self.variablesList] def _intelligentInitialValues(self): """If possible we can auto set the initial parameters to intelligent guesses user can always overwrite them """ self._setInitialValues(self._getIntelligentInitialValues()) def _get_subSpaceArrays(self): """returns the arrays of the selected sub space. If subspace is not activated then returns the full arrays""" if self.fitSubSpace: xs = self.xs[self.startX:self.endX] ys = self.ys[self.startY:self.endY] logger.info("xs array sliced length %s " % (xs.shape)) logger.info("ys array sliced length %s " % (ys.shape)) zs = self.zs[self.startY:self.endY, self.startX:self.endX] logger.info("zs sub space array %s,%s " % (zs.shape)) return xs, ys, zs else: return self.xs, self.ys, self.zs def _getIntelligentInitialValues(self): """If possible we can auto set the initial parameters to intelligent guesses user can always overwrite them """ logger.warning("Dummy function should not be called directly") return #in python this should be a pass statement. I.e. user has to overwrite this def fitFunc(self, data, *p): """Function that we are trying to fit to. """ logger.error("Dummy function should not be called directly") return #in python this should be a pass statement. I.e. user has to overwrite this def _setCalculatedValues(self, modelFitResult): """updates calculated values with calculated argument """ parametersResult = modelFitResult.params for variable in self.variablesList: variable.calculatedValue = parametersResult[variable.name].value def _setCalculatedValuesErrors(self, modelFitResult): """given the covariance matrix returned by scipy optimize fit convert this into stdeviation errors for parameters list and updated the stdevError attribute of variables""" parametersResult = modelFitResult.params for variable in self.variablesList: variable.stdevError = parametersResult[variable.name].stderr def _setInitialValues(self, guesses): """updates calculated values with calculated argument """ c = 0 for variable in self.variablesList: variable.initialValue = guesses[c] c += 1 def deriveCalculatedParameters(self): """Wrapper for subclass definition of deriving calculated parameters can put more general calls in here""" if self.fitted: self._deriveCalculatedParameters() def _deriveCalculatedParameters(self): """Should be implemented by subclass. should update all variables in calculate parameters list""" logger.error("Should only be called by subclass") return def _fit_routine(self): """This function performs the fit in an appropriate thread and updates necessary values when the fit has been performed""" self.fitting = True if self.fitThread and self.fitThread.isAlive(): logger.warning( "Fitting is already running. You should wait till this fit has timed out before a new thread is started...." ) #logger.warning("I will start a new fitting thread but your previous thread may finish at some undetermined time. you probably had bad starting conditions :( !") return self.fitThread = FitThread() #new fitting thread self.fitThread.fitReference = self self.fitThread.isCurrentFitThread = True # user can create multiple fit threads on a particular fit but only the latest one will have an effect in the GUI self.fitThread.start() self.fittingStatus = self.currentlyFittingStatus def _perform_fit(self): """Perform the fit using scipy optimise curve fit. We must supply x and y as one argument and zs as anothger. in the form xs: 0 1 2 0 1 2 0 ys: 0 0 0 1 1 1 2 zs: 1 5 6 1 9 8 2 Hence the use of repeat and tile in positions and unravel for zs initially xs,ys is a linspace array and zs is a 2d image array """ if self.xs is None or self.ys is None or self.zs is None: logger.warning( "attempted to fit data but had no data inside the Fit object. set xs,ys,zs first" ) return ([], []) params = self._getParameters() if self.fitSubSpace: #fit only the sub space #create xs, ys and zs which are appropriate slices of the arrays xs, ys, zs = self._get_subSpaceArrays() else: #fit the whole array of data (slower) xs, ys, zs = self.xs, self.ys, self.zs positions = scipy.array([ scipy.tile(xs, len(ys)), scipy.repeat(ys, len(xs)) ]) #for creating data necessary for gauss2D function if self.fitTimeLimitBool: modelFitResult = self.lmfitModel.fit(scipy.ravel(zs), positions=positions, params=params, iter_cb=self.getFitCallback( time.time())) else: #no iter callback modelFitResult = self.lmfitModel.fit(scipy.ravel(zs), positions=positions, params=params) return modelFitResult def getFitCallback(self, startTime): """returns the callback function that is called at every iteration of fit to check if it has been running too long""" def fitCallback(params, iter, resid, *args, **kws): """check the time and compare to start time """ if time.time() - startTime > self.fitTimeLimit: raise FitException("Fit time exceeded user limit") return fitCallback def _performFitButton_fired(self): self._fit_routine() def _getInitialParametersButton_fired(self): self._intelligentInitialValues() def _drawRequestButton_fired(self): """tells the imageInspector to try and draw this fit as an overlay contour plot""" self.imageInspectorReference.addFitPlot(self) def _setSizeButton_fired(self): """use the sigmaX and sigmaY from the current fit to overwrite the inTrapSizeX and inTrapSizeY parameters in the Physics Instance""" self.physics.inTrapSizeX = abs(self.sigmax.calculatedValue) self.physics.inTrapSizeY = abs(self.sigmay.calculatedValue) def _getFitFuncData(self): """if data has been fitted, this returns the zs data for the ideal fitted function using the calculated paramters""" positions = [ scipy.tile(self.xs, len(self.ys)), scipy.repeat(self.ys, len(self.xs)) ] #for creating data necessary for gauss2D function zsravelled = self.fitFunc(positions, *self._getCalculatedValues()) return zsravelled.reshape(self.zs.shape) def _logAnalyserSelectButton_fired(self): """open a fast file editor for selecting many files """ fileDialog = FileDialog(action="open files") fileDialog.open() if fileDialog.return_code == pyface.constant.OK: self.logAnalysers = fileDialog.paths logger.info("selected log analysers: %s " % self.logAnalysers) self.logAnalyserDisplayString = str( [os.path.split(path)[1] for path in self.logAnalysers]) def runSingleAnalyser(self, module): """runs the logAnalyser module calling the run function and returns the columnNames and values as a list""" exec("import logAnalysers.%s as currentAnalyser" % module) reload( currentAnalyser ) #in case it has changed..#could make this only when user requests #now the array also contains the raw image as this may be different to zs if you are using a processor if hasattr(self.imageInspectorReference, "rawImage"): rawImage = self.imageInspectorReference.rawImage else: rawImage = None return currentAnalyser.run([self.xs, self.ys, self.zs, rawImage], self.physics.variables, self.variablesList, self.calculatedParametersList) def runAnalyser(self): """ if logAnalyserBool is true we perform runAnalyser at the end of _log_fit runAnalyser checks that logAnalyser exists and is a python script with a valid run()function it then performs the run method and passes to the run function: -the image data as a numpy array -the xml variables dictionary -the fitted paramaters -the derived values""" for logAnalyser in self.logAnalysers: if not os.path.isfile(logAnalyser): logger.error( "attempted to runAnalyser but could not find the logAnalyser File: %s" % logAnalyser) return #these will contain the final column names and values finalColumns = [] finalValues = [] #iterate over each selected logAnalyser get the column names and values and add them to the master lists for logAnalyser in self.logAnalysers: directory, module = os.path.split(logAnalyser) module, ext = os.path.splitext(module) if ext != ".py": logger.error("file was not a python module. %s" % logAnalyser) else: columns, values = self.runSingleAnalyser(module) finalColumns.extend(columns) finalValues.extend(values) return finalColumns, finalValues def mostRecentModelFitReport(self): """returns the lmfit fit report of the most recent lmfit model results object""" if self.mostRecentModelResult is not None: return lmfit.fit_report(self.mostRecentModelResult) + "\n\n" else: return "No fit performed" def getCalculatedParameters(self): """useful for print returns tuple list of calculated parameter name and value """ return [(_.name, _.value) for _ in self.calculatedParametersList] def _log_fit(self): if self.logName == "": logger.warning("no log file defined. Will not log") return #generate folders if they don't exist if self.logToNas is not True: logFolder = os.path.join(self.logDirectory, self.logName) else: logFolder = os.path.join(self.logDirectoryNas, self.logName) if not os.path.isdir(logFolder): logger.info("creating a new log folder %s" % logFolder) os.mkdir(logFolder) imagesFolder = os.path.join(logFolder, "images") if not os.path.isdir(imagesFolder): logger.info("creating a new images Folder %s" % imagesFolder) os.mkdir(imagesFolder) commentsFile = os.path.join(logFolder, "comments.txt") if not os.path.exists(commentsFile): logger.info("creating a comments file %s" % commentsFile) open(commentsFile, "a+").close() #create a comments file in every folder! firstSequenceCopy = os.path.join(logFolder, "copyOfInitialSequence.ctr") if not os.path.exists(firstSequenceCopy): logger.info("creating a copy of the first sequence %s -> %s" % (self.latestSequence, firstSequenceCopy)) shutil.copy(self.latestSequence, firstSequenceCopy) if self.imageInspectorReference.model.imageMode == "process raw image": #if we are using a processor, save the details of the processor used to the log folder processorParamtersFile = os.path.join(logFolder, "processorOptions.txt") processorPythonScript = os.path.join(logFolder, "usedProcessor.py") #TODO! if not os.path.exists(processorParamtersFile): with open(processorParamtersFile, "a+") as processorParamsFile: string = str(self.imageInspectorReference.model. chosenProcessor) + "\n" string += str(self.imageInspectorReference.model.processor. optionsDict) processorParamsFile.write(string) logger.debug("finished all checks on log folder") #copy current image try: shutil.copy(self.imageInspectorReference.selectedFile, imagesFolder) if self.imageInspectorReference.selectedFile.endswith("_X2.tif"): shutil.copy( self.imageInspectorReference.selectedFile.replace( "_X2.tif", "_X1.tif"), imagesFolder) except IOError as e: logger.error("Could not copy image. Got IOError: %s " % e.message) except Exception as e: logger.error("Could not copy image. Got %s: %s " % (type(e), e.message)) raise e logger.info("copying current image") self.logFile = os.path.join(logFolder, self.logName + ".csv") #analyser logic if self.logAnalyserBool: #run the analyser script as requested logger.info( "log analyser bool enabled... will attempt to run analyser script" ) analyserResult = self.runAnalyser() logger.info("analyser result = %s " % list(analyserResult)) if analyserResult is None: analyserColumnNames = [] analyserValues = [] #analyser failed. continue as if nothing happened else: analyserColumnNames, analyserValues = analyserResult else: #no analyser enabled analyserColumnNames = [] analyserValues = [] if not os.path.exists(self.logFile): variables = [_.name for _ in self.variablesList] calculated = [_.name for _ in self.calculatedParametersList] times = ["datetime", "epoch seconds"] info = ["img file name"] xmlVariables = self.getXmlVariables() columnNames = times + info + variables + calculated + xmlVariables + analyserColumnNames with open( self.logFile, 'ab+' ) as logFile: # note use of binary file so that windows doesn't write too many /r writer = csv.writer(logFile) writer.writerow(columnNames) #column names already exist so... logger.debug("copying current image") variables = [_.calculatedValue for _ in self.variablesList] calculated = [_.value for _ in self.calculatedParametersList] now = time.time() #epoch seconds timeTuple = time.localtime(now) date = time.strftime("%Y-%m-%dT%H:%M:%S", timeTuple) times = [date, now] info = [self.imageInspectorReference.selectedFile] xmlVariables = [ self.physics.variables[varName] for varName in self.getXmlVariables() ] data = times + info + variables + calculated + xmlVariables + analyserValues with open(self.logFile, 'ab+') as logFile: writer = csv.writer(logFile) writer.writerow(data) def _logLastFitButton_fired(self): """logs the fit. User can use this for non automated logging. i.e. log particular fits""" self._log_fit() def _removeLastFitButton_fired(self): """removes the last line in the log file """ logFolder = os.path.join(self.logDirectory, self.logName) self.logFile = os.path.join(logFolder, self.logName + ".csv") if self.logFile == "": logger.warning("no log file defined. Will not log") return if not os.path.exists(self.logFile): logger.error( "cant remove a line from a log file that doesn't exist") with open(self.logFile, 'r') as logFile: lines = logFile.readlines() with open(self.logFile, 'wb') as logFile: logFile.writelines(lines[:-1]) def saveLastFit(self): """saves result of last fit to a txt/csv file. This can be useful for live analysis or for generating sequences based on result of last fit""" try: with open( self.imageInspectorReference.cameraModel + "-" + self.physics.species + "-" + "lastFit.csv", "wb") as lastFitFile: writer = csv.writer(lastFitFile) writer.writerow(["time", time.time()]) for variable in self.variablesList: writer.writerow([variable.name, variable.calculatedValue]) for variable in self.calculatedParametersList: writer.writerow([variable.name, variable.value]) except Exception as e: logger.error("failed to save last fit to text file. message %s " % e.message) def _chooseVariablesButtons_fired(self): self.xmlLogVariables = self.chooseVariables() def _usePreviousFitValuesButton_fired(self): """update the guess initial values with the value from the last fit """ logger.info( "use previous fit values button fired. loading previous initial values" ) self._setInitialValues(self._getCalculatedValues()) def getXmlVariables(self): if self.logAllVariables: return sorted(self.physics.variables.keys()) else: return self.xmlLogVariables def chooseVariables(self): """Opens a dialog asking user to select columns from a data File that has been selected. THese are then returned as a string suitable for Y cols input""" columns = self.physics.variables.keys() columns.sort() values = zip(range(0, len(columns)), columns) checklist_group = traitsui.Group( '10', # insert vertical space traitsui.Label('Select the additional variables you wish to log'), traitsui.UItem('columns', style='custom', editor=traitsui.CheckListEditor(values=values, cols=6)), traitsui.UItem('selectAllButton')) traits_view = traitsui.View(checklist_group, title='CheckListEditor', buttons=['OK'], resizable=True, kind='livemodal') col = ColumnEditor(numberOfColumns=len(columns)) try: col.columns = [ columns.index(varName) for varName in self.xmlLogVariables ] except Exception as e: logger.error( "couldn't selected correct variable names. Returning empty selection" ) logger.error("%s " % e.message) col.columns = [] col.edit_traits(view=traits_view) logger.debug("value of columns selected = %s ", col.columns) logger.debug("value of columns selected = %s ", [columns[i] for i in col.columns]) return [columns[i] for i in col.columns] def _logLibrarianButton_fired(self): """opens log librarian for current folder in logName box. """ logFolder = os.path.join(self.logDirectory, self.logName) if not os.path.isdir(logFolder): logger.error( "cant open librarian on a log that doesn't exist.... Could not find %s" % logFolder) return librarian = plotObjects.logLibrarian.Librarian(logFolder=logFolder) librarian.edit_traits() def _drawSubSpace_changed(self): newVisibility = self.drawSubSpace and self.fitSubSpace self.imageInspectorReference.ROIPolyPlot.visible = newVisibility self._startX_changed() # update ROI data for plot def _fitSubSpace_changed(self): self._drawSubSpace_changed() def _startX_changed(self): if self.imageInspectorReference is None: return # not yet initialized yet self.imageInspectorReference.ROIPolyPlot.index = chaco.ArrayDataSource( [self.startX, self.endX, self.endX, self.startX]) self.imageInspectorReference.ROIPolyPlot.value = chaco.ArrayDataSource( [self.startY, self.startY, self.endY, self.endY]) _endX_changed = _startX_changed _startY_changed = _startX_changed _endY_changed = _startX_changed
class config(HasTraits): uuid = traits.Str(desc="UUID") desc = traits.Str(desc='Workflow description') # Directories working_dir = Directory(mandatory=True, desc="Location of the Nipype working directory") base_dir = Directory(os.path.abspath('.'),mandatory=True, desc='Base directory of data. (Should be subject-independent)') sink_dir = Directory(os.path.abspath('.'),mandatory=True, desc="Location where the BIP will store the results") field_dir = Directory(desc="Base directory of field-map data (Should be subject-independent) \ Set this value to None if you don't want fieldmap distortion correction") crash_dir = Directory(mandatory=False, desc="Location to store crash files") json_sink = Directory(mandatory=False, desc= "Location to store json_files") surf_dir = Directory(mandatory=True, desc= "Freesurfer subjects directory") # Execution run_using_plugin = Bool(False, usedefault=True, desc="True to run pipeline with plugin, False to run serially") plugin = traits.Enum("PBS", "PBSGraph","MultiProc", "SGE", "Condor", usedefault=True, desc="plugin to use, if run_using_plugin=True") plugin_args = traits.Dict({"qsub_args": "-q many"}, usedefault=True, desc='Plugin arguments.') test_mode = Bool(False, mandatory=False, usedefault=True, desc='Affects whether where and if the workflow keeps its \ intermediary files. True to keep intermediary files. ') # Subjects subjects= traits.List(traits.Str, mandatory=True, usedefault=True, desc="Subject id's. Note: These MUST match the subject id's in the \ Freesurfer directory. For simplicity, the subject id's should \ also match with the location of individual functional files.") dwi_template = traits.String('%s/functional.nii.gz') bval_template = traits.String('%s/bval') bvec_template = traits.String('%s/fbvec') run_datagrabber_without_submitting = traits.Bool(desc="Run the datagrabber without \ submitting to the cluster") timepoints_to_remove = traits.Int(0,usedefault=True) # Fieldmap use_fieldmap = Bool(False, mandatory=False, usedefault=True, desc='True to include fieldmap distortion correction. Note: field_dir \ must be specified') magnitude_template = traits.String('%s/magnitude.nii.gz') phase_template = traits.String('%s/phase.nii.gz') TE_diff = traits.Float(desc='difference in B0 field map TEs') sigma = traits.Int(2, desc='2D spatial gaussing smoothing stdev (default = 2mm)') echospacing = traits.Float(desc="EPI echo spacing") # Bvecs do_rotate_bvecs = traits.Bool(True, usedefault=True) # Advanced Options use_advanced_options = traits.Bool() advanced_script = traits.Code() # Buttons check_func_datagrabber = Button("Check") check_field_datagrabber = Button("Check") def _check_func_datagrabber_fired(self): subs = self.subjects for s in subs: if not os.path.exists(os.path.join(self.base_dir,self.dwi_template % s)): print "ERROR", os.path.join(self.base_dir,self.dwi_template % s), "does NOT exist!" break else: print os.path.join(self.base_dir,self.dwi_template % s), "exists!" def _check_field_datagrabber_fired(self): subs = self.subjects for s in subs: if not os.path.exists(os.path.join(self.field_dir,self.magnitude_template % s)): print "ERROR:", os.path.join(self.field_dir,self.magnitude_template % s), "does NOT exist!" break else: print os.path.join(self.base_dir,self.magnitude_template % s), "exists!" if not os.path.exists(os.path.join(self.field_dir,self.phase_template % s)): print "ERROR:", os.path.join(self.field_dir,self.phase_template % s), "does NOT exist!" break else: print os.path.join(self.base_dir,self.phase_template % s), "exists!"
class config(HasTraits): uuid = traits.Str(desc="UUID") # Directories working_dir = Directory(mandatory=True, desc="Location of the Nipype working directory") base_dir = Directory( os.path.abspath('.'), mandatory=True, desc='Base directory of data. (Should be subject-independent)') sink_dir = Directory(mandatory=True, desc="Location where the BIP will store the results") crash_dir = Directory(mandatory=False, desc="Location to store crash files") surf_dir = Directory( desc="freesurfer directory. subject id's should be the same") # Execution run_using_plugin = Bool( False, usedefault=True, desc="True to run pipeline with plugin, False to run serially") plugin = traits.Enum("PBS", "MultiProc", "SGE", "Condor", usedefault=True, desc="plugin to use, if run_using_plugin=True") plugin_args = traits.Dict({"qsub_args": "-q many"}, usedefault=True, desc='Plugin arguments.') test_mode = Bool( False, mandatory=False, usedefault=True, desc='Affects whether where and if the workflow keeps its \ intermediary files. True to keep intermediary files. ' ) timeout = traits.Float(30.0) # DataGrabber datagrabber = traits.Instance(Data, ()) # segstats use_reg = traits.Bool(True) inverse_reg = traits.Bool(True) use_standard_label = traits.Bool( False, desc="use same label file for all subjects") label_file = traits.File() use_annotation = traits.Bool( False, desc= "use same annotation file for all subjects (will warp to subject space" ) use_subject_annotation = traits.Bool( False, desc="you need to change datragrabber to\ have outputs lh_annotation and rh_annotation" ) annot_space = traits.String("fsaverage5", desc="subject space of annot file") lh_annotation = traits.File() rh_annotation = traits.File() color_table_file = traits.Enum("Default", "Color_Table", "GCA_color_table", "None") color_file = traits.File() proj = traits.BaseTuple(("frac", 0, 1, 0.1), traits.Enum("abs", "frac"), traits.Float(), traits.Float(), traits.Float()) statname = traits.Str('segstats1', desc="description of the segstat")
class HCFT(tr.HasStrictTraits): """High-Cycle Fatigue Tool""" # ========================================================================= # Traits definitions # ========================================================================= # Assigning the view traits_view = hcft_window # CSV import decimal = tr.Enum(',', '.') delimiter = tr.Str(';') file_path = tr.File open_file_button = tr.Button('Open file') columns_headers = tr.List npy_folder_path = tr.Str file_name = tr.Str # CSV processing take_time_from_time_column = tr.Bool(True) records_per_second = tr.Float(100) time_column = tr.Enum(values='columns_headers') skip_first_rows = tr.Range(low=1, high=10**9, value=3, mode='spinner') add_columns_average = tr.Button columns_to_be_averaged = tr.List parse_csv_to_npy = tr.Button # Plotting x_axis = tr.Enum(values='columns_headers') y_axis = tr.Enum(values='columns_headers') x_axis_multiplier = tr.Enum(1, -1) y_axis_multiplier = tr.Enum(-1, 1) add_plot = tr.Button apply_filters = tr.Bool plot_settings_btn = tr.Button plot_settings = PlotSettings() plot_settings_active = tr.Bool normalize_cycles = tr.Bool smooth = tr.Bool plot_every_nth_point = tr.Range(low=1, high=1000000, mode='spinner') old_peak_force_before_cycles = tr.Float peak_force_before_cycles = tr.Float add_creep_plot = tr.Button(desc='Creep plot of X axis array') clear_plot = tr.Button force_column = tr.Enum(values='columns_headers') window_length = tr.Range(low=1, high=10**9 - 1, value=31, mode='spinner') polynomial_order = tr.Range(low=1, high=10**9, value=2, mode='spinner') activate_ascending_branch_smoothing = tr.Bool(False, label='Activate') generate_filtered_and_creep_npy = tr.Button force_max = tr.Float(100) force_min = tr.Float(40) min_cycle_force_range = tr.Float(50) cutting_method = tr.Enum('Define min cycle range(force difference)', 'Define Max, Min') log = tr.Str('') clear_log = tr.Button # ========================================================================= # Assigning default values # ========================================================================= ax = tr.Any figure = tr.Instance(mpl.figure.Figure) def _figure_default(self): figure = mpl.figure.Figure(facecolor='white') figure.set_tight_layout(True) self.create_axes(figure) return figure def create_axes(self, figure): self.ax = figure.add_subplot(1, 1, 1) # ========================================================================= # File management # ========================================================================= def _open_file_button_fired(self): try: self.reset() dialog = FileDialog(title='Select text file', action='open', default_path=self.file_path) result = dialog.open() # Test if the user opened a file to avoid throwing an exception if he doesn't if result == OK: self.file_path = dialog.path else: return # Populate headers list which fills the x-axis and y-axis with values automatically self.columns_headers = get_headers(self.file_path, decimal=self.decimal, delimiter=self.delimiter) # Saving file name and path and creating NPY folder dir_path = os.path.dirname(self.file_path) self.npy_folder_path = os.path.join(dir_path, 'NPY') if not os.path.exists(self.npy_folder_path): os.makedirs(self.npy_folder_path) self.file_name = os.path.splitext(os.path.basename( self.file_path))[0] self.import_data_json() except: self.log_exception() def _add_columns_average_fired(self): try: columns_average = ColumnsAverage() for name in self.columns_headers: columns_average.columns.append(Column(column_name=name)) # kind='modal' pauses the implementation until the window is closed columns_average.configure_traits(kind='modal') columns_to_be_averaged_temp = [] for i in columns_average.columns: if i.selected: columns_to_be_averaged_temp.append(i.column_name) if columns_to_be_averaged_temp: # If it's not empty self.columns_to_be_averaged.append(columns_to_be_averaged_temp) avg_file_suffix = self.get_suffix_for_columns_to_be_averaged( columns_to_be_averaged_temp) self.columns_headers.append(avg_file_suffix) except: self.log_exception() def _parse_csv_to_npy_fired(self): # Run method on different thread so GUI doesn't freeze # thread = Thread(target = threaded_function, function_args = (10,)) thread = Thread(target=self.parse_csv_to_npy_fired) thread.start() def parse_csv_to_npy_fired(self): try: self.print_custom('Parsing csv into npy files...') self.export_data_json() """ Exporting npy arrays of original columns """ for i in range( len(self.columns_headers) - len(self.columns_to_be_averaged)): column_name = self.columns_headers[i] # One could provide the path directly to pd.read_csv but in this way we insure that this works also if the # path to the file include chars like ü,ä # (with) makes sure the file stream is closed after using it with open(self.file_path, encoding='utf-8') as file_stream: column_array = np.array( pd.read_csv(file_stream, delimiter=self.delimiter, decimal=self.decimal, skiprows=self.skip_first_rows, usecols=[i])) # TODO detect column name before loading completely to skip loading if the following condition applies if column_name == self.time_column and self.take_time_from_time_column is False: column_array = np.arange( start=0.0, stop=len(column_array) / self.records_per_second, step=1.0 / self.records_per_second) np.save(self.get_npy_file_path(column_name), column_array) """ Exporting npy arrays of averaged columns """ for columns_names in self.columns_to_be_averaged: temp_array = np.zeros((1)) for column_name in columns_names: temp_array = temp_array + np.load( self.get_npy_file_path(column_name)).flatten() avg = temp_array / len(columns_names) np.save(self.get_average_npy_file_path(columns_names), avg) self.print_custom('Finished parsing csv into npy files.') except: self.log_exception() def get_npy_file_path(self, column_name): return os.path.join(self.npy_folder_path, self.file_name + '_' + column_name + '.npy') def get_filtered_npy_file_path(self, column_name): return os.path.join( self.npy_folder_path, self.file_name + '_' + column_name + '_filtered.npy') def get_max_npy_file_path(self, column_name): return os.path.join(self.npy_folder_path, self.file_name + '_' + column_name + '_max.npy') def get_min_npy_file_path(self, column_name): return os.path.join(self.npy_folder_path, self.file_name + '_' + column_name + '_min.npy') def get_average_npy_file_path(self, columns_names): avg_file_suffix = self.get_suffix_for_columns_to_be_averaged( columns_names) return os.path.join(self.npy_folder_path, self.file_name + '_' + avg_file_suffix + '.npy') def get_suffix_for_columns_to_be_averaged(self, columns_names): suffix_for_saved_file_name = 'avg_' + '_'.join(columns_names) return suffix_for_saved_file_name def export_data_json(self): # Output data MUST have exactly similar keys and variable names output_data = { 'take_time_from_time_column': self.take_time_from_time_column, 'time_column': self.time_column, 'records_per_second': self.records_per_second, 'skip_first_rows': self.skip_first_rows, 'columns_headers': self.columns_headers, 'columns_to_be_averaged': self.columns_to_be_averaged, 'x_axis': self.x_axis, 'y_axis': self.y_axis, 'x_axis_multiplier': self.x_axis_multiplier, 'y_axis_multiplier': self.y_axis_multiplier, 'force_column': self.force_column, 'window_length': self.window_length, 'polynomial_order': self.polynomial_order, 'peak_force_before_cycles': self.peak_force_before_cycles, 'cutting_method': self.cutting_method, 'force_max': self.force_max, 'force_min': self.force_min, 'min_cycle_force_range': self.min_cycle_force_range } with open(self.get_json_file_path(), 'w') as outfile: json.dump(output_data, outfile, sort_keys=True, indent=4) self.print_custom('.json data file exported successfully.') def import_data_json(self): json_path = self.get_json_file_path() if not os.path.isfile(json_path): return # class_vars is a list with class variables names # vars(self) & self.__dict__.items() didn't include some Trait variables like force_column = tr.Enum(values=.. class_vars = [ attr for attr in dir(self) if not attr.startswith("_") and not attr.startswith("__") ] with open(json_path) as infile: data_in = json.load(infile) for key_data, value_data in data_in.items(): for key_class in class_vars: if key_data == key_class: # Equivalent to: self.key_class = value_data setattr(self, key_class, value_data) break self.print_custom('.json data file imported successfully.') def get_json_file_path(self): return os.path.join(self.npy_folder_path, self.file_name + '.json') def _generate_filtered_and_creep_npy_fired(self): # Run method on different thread so GUI doesn't freeze # thread = Thread(target = threaded_function, function_args = (10,)) thread = Thread(target=self.generate_filtered_and_creep_npy_fired) thread.start() def generate_filtered_and_creep_npy_fired(self): try: self.export_data_json() if not self.npy_files_exist( self.get_npy_file_path(self.force_column)): return self.print_custom('Generating filtered and creep files...') # 1- Export filtered force force = np.load(self.get_npy_file_path( self.force_column)).flatten() peak_force_before_cycles_index = np.where( abs((force)) > abs(self.peak_force_before_cycles))[0][0] force_ascending = force[0:peak_force_before_cycles_index] force_rest = force[peak_force_before_cycles_index:] force_max_indices, force_min_indices = self.get_array_max_and_min_indices( force_rest) force_max_min_indices = np.concatenate( (force_min_indices, force_max_indices)) force_max_min_indices.sort() force_rest_filtered = force_rest[force_max_min_indices] force_filtered = np.concatenate( (force_ascending, force_rest_filtered)) np.save(self.get_filtered_npy_file_path(self.force_column), force_filtered) # 2- Export filtered displacements # Export displacements combining processed ascending branch and unprocessed min/max values self.export_filtered_displacements(force_max_min_indices, peak_force_before_cycles_index) # 3- Export creep for displacements # Cut unwanted max min values to get correct full cycles and remove false min/max values caused by noise self.export_displacements_creep(force_rest, force_max_indices, force_min_indices, peak_force_before_cycles_index) self.print_custom('Filtered and creep npy files are generated.') except: self.log_exception() def export_filtered_displacements(self, force_max_min_indices, peak_force_before_cycles_index): for i in range(len(self.columns_headers)): if self.columns_headers[ i] != self.force_column and self.columns_headers[ i] != self.time_column: disp = np.load(self.get_npy_file_path( self.columns_headers[i])).flatten() disp_ascending = disp[0:peak_force_before_cycles_index] disp_rest = disp[peak_force_before_cycles_index:] if self.activate_ascending_branch_smoothing: disp_ascending = savgol_filter( disp_ascending, window_length=self.window_length, polyorder=self.polynomial_order) disp_rest_filtered = disp_rest[force_max_min_indices] filtered_disp = np.concatenate( (disp_ascending, disp_rest_filtered)) np.save( self.get_filtered_npy_file_path(self.columns_headers[i]), filtered_disp) def export_displacements_creep(self, force_rest, force_max_indices, force_min_indices, peak_force_before_cycles_index): if self.cutting_method == "Define Max, Min": force_max_indices_cut, force_min_indices_cut = self.cut_indices_of_min_max_range( force_rest, force_max_indices, force_min_indices, self.force_max, self.force_min) elif self.cutting_method == "Define min cycle range(force difference)": force_max_indices_cut, force_min_indices_cut = self.cut_indices_of_defined_range( force_rest, force_max_indices, force_min_indices, self.min_cycle_force_range) self.print_custom("Cycles number= ", len(force_min_indices)) self.print_custom("Cycles number after cutting fake cycles = ", len(force_min_indices_cut)) for i in range(len(self.columns_headers)): if self.columns_headers[i] != self.time_column: array = np.load(self.get_npy_file_path( self.columns_headers[i])).flatten() array_rest = array[peak_force_before_cycles_index:] array_rest_maxima = array_rest[force_max_indices_cut] array_rest_minima = array_rest[force_min_indices_cut] np.save(self.get_max_npy_file_path(self.columns_headers[i]), array_rest_maxima) np.save(self.get_min_npy_file_path(self.columns_headers[i]), array_rest_minima) def get_array_max_and_min_indices(self, input_array): # Checking dominant sign positive_values_count = np.sum(np.array(input_array) >= 0) negative_values_count = input_array.size - positive_values_count # Getting max and min indices if positive_values_count > negative_values_count: force_max_indices = self.get_max_indices(input_array) force_min_indices = self.get_min_indices(input_array) else: force_max_indices = self.get_min_indices(input_array) force_min_indices = self.get_max_indices(input_array) return force_max_indices, force_min_indices def get_max_indices(self, a): # TODO try to vectorize this # This method doesn't qualify first and last elements as max max_indices = [] i = 1 while i < a.size - 1: previous_element = a[i - 1] # Skip repeated elements and record previous element value first_repeated_element = True while a[i] == a[i + 1] and i < a.size - 1: if first_repeated_element: previous_element = a[i - 1] first_repeated_element = False if i < a.size - 2: i += 1 else: break # Append value if it's a local max if a[i] > a[i + 1] and a[i] > previous_element: max_indices.append(i) i += 1 return np.array(max_indices) def get_min_indices(self, a): # TODO try to vectorize this # This method doesn't qualify first and last elements as min min_indices = [] i = 1 while i < a.size - 1: previous_element = a[i - 1] # Skip repeated elements and record previous element value first_repeated_element = True while a[i] == a[i + 1]: if first_repeated_element: previous_element = a[i - 1] first_repeated_element = False if i < a.size - 2: i += 1 else: break # Append value if it's a local min if a[i] < a[i + 1] and a[i] < previous_element: min_indices.append(i) i += 1 return np.array(min_indices) def cut_indices_of_min_max_range(self, array, max_indices, min_indices, range_upper_value, range_lower_value): # TODO try to vectorize this cut_max_indices = [] cut_min_indices = [] for max_index in max_indices: if abs(array[max_index]) > abs(range_upper_value): cut_max_indices.append(max_index) for min_index in min_indices: if abs(array[min_index]) < abs(range_lower_value): cut_min_indices.append(min_index) return cut_max_indices, cut_min_indices def cut_indices_of_defined_range(self, array, max_indices, min_indices, range_): # TODO try to vectorize this cut_max_indices = [] cut_min_indices = [] for max_index, min_index in zip(max_indices, min_indices): if abs(array[max_index] - array[min_index]) > range_: cut_max_indices.append(max_index) cut_min_indices.append(min_index) if max_indices.size > min_indices.size: cut_max_indices.append(max_indices[-1]) elif min_indices.size > max_indices.size: cut_min_indices.append(min_indices[-1]) return cut_max_indices, cut_min_indices def _activate_changed(self): if not self.activate_ascending_branch_smoothing: self.old_peak_force_before_cycles = self.peak_force_before_cycles self.peak_force_before_cycles = 0 else: self.peak_force_before_cycles = self.old_peak_force_before_cycles def _window_length_changed(self, new): if new <= self.polynomial_order: dialog = MessageDialog( title='Attention!', message='Window length must be bigger than polynomial order.') dialog.open() if new % 2 == 0 or new <= 0: dialog = MessageDialog( title='Attention!', message='Window length must be odd positive integer.') dialog.open() def _polynomial_order_changed(self, new): if new >= self.window_length: dialog = MessageDialog( title='Attention!', message='Polynomial order must be smaller than window length.') dialog.open() # ========================================================================= # Plotting # ========================================================================= data_changed = tr.Event def _plot_settings_btn_fired(self): try: self.plot_settings.configure_traits(kind='modal') except: self.log_exception() def npy_files_exist(self, path): if os.path.exists(path): return True else: self.print_custom( 'Please parse csv file to generate npy files first!') return False def filtered_and_creep_npy_files_exist(self, path): if os.path.exists(path): return True else: self.print_custom( 'Please generate filtered and creep npy files first!') return False def _add_plot_fired(self): # Run method on different thread so GUI doesn't freeze # thread = Thread(target = threaded_function, function_args = (10,)) thread = Thread(target=self.add_plot_fired) thread.start() def add_plot_fired(self): try: if self.apply_filters: if not self.filtered_and_creep_npy_files_exist( self.get_filtered_npy_file_path(self.x_axis)): return # TODO link this _filtered to the path creation function x_axis_name = self.x_axis + '_filtered' y_axis_name = self.y_axis + '_filtered' self.print_custom('Loading npy files...') # when mmap_mode!=None, the array will be loaded as 'numpy.memmap' # object which doesn't load the array to memory until it's # indexed x_axis_array = np.load(self.get_filtered_npy_file_path( self.x_axis), mmap_mode='r') y_axis_array = np.load(self.get_filtered_npy_file_path( self.y_axis), mmap_mode='r') else: if not self.npy_files_exist(self.get_npy_file_path( self.x_axis)): return x_axis_name = self.x_axis y_axis_name = self.y_axis self.print_custom('Loading npy files...') # when mmap_mode!=None, the array will be loaded as 'numpy.memmap' # object which doesn't load the array to memory until it's # indexed x_axis_array = np.load(self.get_npy_file_path(self.x_axis), mmap_mode='r') y_axis_array = np.load(self.get_npy_file_path(self.y_axis), mmap_mode='r') if self.plot_settings_active: print(self.plot_settings.num_of_first_rows_to_take) print( self.plot_settings.num_of_rows_to_skip_after_each_section) print(self.plot_settings.num_of_rows_in_each_section) print(np.size(x_axis_array)) indices = self.get_indices_array( np.size(x_axis_array), self.plot_settings.num_of_first_rows_to_take, self.plot_settings.num_of_rows_to_skip_after_each_section, self.plot_settings.num_of_rows_in_each_section) x_axis_array = self.x_axis_multiplier * x_axis_array[indices] y_axis_array = self.y_axis_multiplier * y_axis_array[indices] else: x_axis_array = self.x_axis_multiplier * x_axis_array y_axis_array = self.y_axis_multiplier * y_axis_array self.print_custom('Adding Plot...') mpl.rcParams['agg.path.chunksize'] = 10000 ax = self.ax ax.set_xlabel(x_axis_name) ax.set_ylabel(y_axis_name) ax.plot(x_axis_array, y_axis_array, linewidth=1.2, color=np.random.rand(3), label=self.file_name + ', ' + x_axis_name) ax.legend() self.data_changed = True self.print_custom('Finished adding plot.') except: self.log_exception() def _add_creep_plot_fired(self): # Run method on different thread so GUI doesn't freeze # thread = Thread(target = threaded_function, function_args = (10,)) thread = Thread(target=self.add_creep_plot_fired) thread.start() def add_creep_plot_fired(self): try: if not self.filtered_and_creep_npy_files_exist( self.get_max_npy_file_path(self.x_axis)): return self.print_custom('Loading npy files...') disp_max = self.x_axis_multiplier * np.load( self.get_max_npy_file_path(self.x_axis)) disp_min = self.x_axis_multiplier * np.load( self.get_min_npy_file_path(self.x_axis)) complete_cycles_number = disp_max.size self.print_custom('Adding creep-fatigue plot...') mpl.rcParams['agg.path.chunksize'] = 10000 ax = self.ax ax.set_xlabel('Cycles number') ax.set_ylabel(self.x_axis) if self.plot_every_nth_point > 1: disp_max = disp_max[0::self.plot_every_nth_point] disp_min = disp_min[0::self.plot_every_nth_point] if self.smooth: # Keeping the first item of the array and filtering the rest disp_max = np.concatenate( (np.array([disp_max[0]]), savgol_filter(disp_max[1:], window_length=self.window_length, polyorder=self.polynomial_order))) disp_min = np.concatenate( (np.array([disp_min[0]]), savgol_filter(disp_min[1:], window_length=self.window_length, polyorder=self.polynomial_order))) if self.normalize_cycles: ax.plot(np.linspace(0, 1., disp_max.size), disp_max, 'k', linewidth=1.2, color=np.random.rand(3), label='Max' + ', ' + self.file_name + ', ' + self.x_axis) ax.plot(np.linspace(0, 1., disp_min.size), disp_min, 'k', linewidth=1.2, color=np.random.rand(3), label='Min' + ', ' + self.file_name + ', ' + self.x_axis) else: ax.plot(np.linspace(0, complete_cycles_number, disp_max.size), disp_max, 'k', linewidth=1.2, color=np.random.rand(3), label='Max' + ', ' + self.file_name + ', ' + self.x_axis) ax.plot(np.linspace(0, complete_cycles_number, disp_min.size), disp_min, 'k', linewidth=1.2, color=np.random.rand(3), label='Min' + ', ' + self.file_name + ', ' + self.x_axis) ax.legend() self.data_changed = True self.print_custom('Finished adding creep-fatigue plot.') except: self.log_exception() def get_indices_array(self, array_size, first_rows, distance, num_of_rows_after_each_distance): result_1 = np.arange(first_rows) result_2 = np.arange(start=first_rows, stop=array_size, step=distance + num_of_rows_after_each_distance) result_2_updated = np.array([], dtype=np.int_) for result_2_value in result_2: data_slice = np.arange( result_2_value, result_2_value + num_of_rows_after_each_distance) result_2_updated = np.concatenate((result_2_updated, data_slice)) result = np.concatenate((result_1, result_2_updated)) return result def _clear_plot_fired(self): self.figure.clear() self.create_axes(self.figure) self.data_changed = True # ========================================================================= # Logging # ========================================================================= def print_custom(self, *input_args): print(*input_args) if self.log == '': self.log = ''.join(str(e) for e in list(input_args)) else: self.log = self.log + '\n' + \ ''.join(str(e) for e in list(input_args)) def log_exception(self): self.print_custom('SOMETHING WENT WRONG!') self.print_custom('--------- Error message: ---------') self.print_custom(traceback.format_exc()) self.print_custom('----------------------------------') def _clear_log_fired(self): self.log = '' # ========================================================================= # Other functions # ========================================================================= def reset(self): self.columns_to_be_averaged = [] self.log = ''
class BackgroundRemoval(SpanSelectorInSignal1D): background_type = t.Enum('Power Law', 'Gaussian', 'Offset', 'Polynomial', default='Power Law') polynomial_order = t.Range(1, 10) fast = t.Bool(True, desc=("Perform a fast (analytic, but possibly less accurate)" " estimation of the background. Otherwise use " "non-linear least squares.")) background_estimator = t.Instance(Component) bg_line_range = t.Enum('from_left_range', 'full', 'ss_range', default='full') hi = t.Int(0) view = tu.View( tu.Group( 'background_type', 'fast', tu.Group('polynomial_order', visible_when='background_type == \'Polynomial\''), ), buttons=[OKButton, CancelButton], handler=SpanSelectorInSignal1DHandler, title='Background removal tool', resizable=True, width=300, ) def __init__(self, signal): super(BackgroundRemoval, self).__init__(signal) self.set_background_estimator() self.bg_line = None def on_disabling_span_selector(self): if self.bg_line is not None: self.bg_line.close() self.bg_line = None def set_background_estimator(self): if self.background_type == 'Power Law': self.background_estimator = components1d.PowerLaw() self.bg_line_range = 'from_left_range' elif self.background_type == 'Gaussian': self.background_estimator = components1d.Gaussian() self.bg_line_range = 'full' elif self.background_type == 'Offset': self.background_estimator = components1d.Offset() self.bg_line_range = 'full' elif self.background_type == 'Polynomial': self.background_estimator = components1d.Polynomial( self.polynomial_order) self.bg_line_range = 'full' def _polynomial_order_changed(self, old, new): self.background_estimator = components1d.Polynomial(new) self.span_selector_changed() def _background_type_changed(self, old, new): self.set_background_estimator() self.span_selector_changed() def _ss_left_value_changed(self, old, new): if not (np.isnan(self.ss_right_value) or np.isnan(self.ss_left_value)): self.span_selector_changed() def _ss_right_value_changed(self, old, new): if not (np.isnan(self.ss_right_value) or np.isnan(self.ss_left_value)): self.span_selector_changed() def create_background_line(self): self.bg_line = drawing.signal1d.Signal1DLine() self.bg_line.data_function = self.bg_to_plot self.bg_line.set_line_properties(color='blue', type='line', scaley=False) self.signal._plot.signal_plot.add_line(self.bg_line) self.bg_line.autoscale = False self.bg_line.plot() def bg_to_plot(self, axes_manager=None, fill_with=np.nan): # First try to update the estimation self.background_estimator.estimate_parameters(self.signal, self.ss_left_value, self.ss_right_value, only_current=True) if self.bg_line_range == 'from_left_range': bg_array = np.zeros(self.axis.axis.shape) bg_array[:] = fill_with from_index = self.axis.value2index(self.ss_left_value) bg_array[from_index:] = self.background_estimator.function( self.axis.axis[from_index:]) to_return = bg_array elif self.bg_line_range == 'full': to_return = self.background_estimator.function(self.axis.axis) elif self.bg_line_range == 'ss_range': bg_array = np.zeros(self.axis.axis.shape) bg_array[:] = fill_with from_index = self.axis.value2index(self.ss_left_value) to_index = self.axis.value2index(self.ss_right_value) bg_array[from_index:] = self.background_estimator.function( self.axis.axis[from_index:to_index]) to_return = bg_array if self.signal.metadata.Signal.binned is True: to_return *= self.axis.scale return to_return def span_selector_changed(self): if self.ss_left_value is np.nan or self.ss_right_value is np.nan or\ self.ss_right_value <= self.ss_left_value: return if self.background_estimator is None: return if self.bg_line is None and \ self.background_estimator.estimate_parameters( self.signal, self.ss_left_value, self.ss_right_value, only_current=True) is True: self.create_background_line() else: self.bg_line.update() def apply(self): self.signal._plot.auto_update_plot = False new_spectra = self.signal._remove_background_cli( (self.ss_left_value, self.ss_right_value), self.background_estimator, fast=self.fast) self.signal.data = new_spectra.data self.signal._replot() self.signal._plot.auto_update_plot = True
class OdorControl(traited_plugin.HasTraits_FViewPlugin): enabled = traits.Bool(False) plugin_name = "Odor Control" last_update_time = traits.Float(-np.inf, transient=True) save_to_disk = traits.Bool(False, transient=True) log_filename_prefix = traits.String('odd_log_data_') log_filename = traits.File odd_filename = traits.File persistent_attr_names = traits.List(['odd_filename', 'log_filename']) deliver_odors = traits.Bool(False, transient=True) traits_view = View(Group(\ Item(name="deliver_odors"),\ Item(name='save_to_disk'),\ Item(name="odd_filename", editor=FileEditor(dialog_style="open")),\ Item(name="log_filename_prefix"),\ Item(name="log_filename", style="readonly"))) def __init__(self, *args, **kwargs): super(OdorControl, self).__init__(*args, **kwargs) print "Initialized odor control" self._list_of_timestamp_data = [] self.odors = [] self.last_trigger_timestamp = {} self.sending_odor = False self.total_delay = 0 self.has_started = False self.log_file = None self.worker = None self.context = zmq.Context(1) self.client = self.context.socket(zmq.REQ) self.client.connect(SERVER_ENDPOINT) self.poll = zmq.Poller() self.poll.register(self.client, zmq.POLLIN) print "Socket initialized on port 5556..." self.has_started = True # variables for current odor self.odor_name = "" self.odor = 0 self.stim = 0 self.delay = 0 def _save_to_disk_changed(self): print "Changing save to disk" if self.has_started: if self.save_to_disk: self.log_filename = self.log_filename_prefix + time.strftime( '%Y%m%d_%H%M%S') + ".txt" self.log_file = open(self.log_filename, 'w') print "Saving ", repr(self.log_filename), " to disk..." else: print "Closed", repr(self.log_filename) self.log_file.close() self.log_file = None self.log_filename = "" def _odd_filename_changed(self): print "Changing ODD filename" try: print "Using ODD file ", self.odd_filename self.odors = read_odd_file(self.odd_filename.encode('ascii')) except IOError: print "Couldn't open ODD file ", self.odd_filename def quit(self): pass if self.save_to_disk: self.log_file.close() if self.has_started and self.worker is not None: self.worker.join() def camera_starting_notification(self, cam_id, pixel_format=None, max_width=None, max_height=None): self.has_started = True pass def process_frame(self, cam_id, buf, buf_offset, timestamp, framenumber): draw_points = [] draw_linesegs = [] now = time.time() if self.deliver_odors: if not self.sending_odor: self.odor_name, self.odor, self.stim, self.delay = self.odors.pop( ) if self.save_to_disk: loginfo = "S %s %d %d %d %d %d %d\n" % ( self.odor_name, self.odor, self.stim, self.delay, framenumber, time.mktime(time.gmtime()), timestamp) self.log_file.write(loginfo) self.total_delay = self.stim + self.delay print "Sending odor ", self.odor_name, " with total delay ", self.total_delay self.worker = ODDControlWorker(self.odor, self.stim, self.delay, self.client, self.poll) self.worker.daemon = True self.worker.start() self.sending_odor = True self.last_update_time = time.time() else: if (now - self.last_update_time) > self.total_delay: print "Changing odor from ", self.odor_name self.worker.join() self.sending_odor = False if self.save_to_disk: loginfo = "R %s %d %d %d %d %d %d\n" % ( self.odor_name, self.odor, self.stim, self.delay, framenumber, time.mktime(time.gmtime()), timestamp) self.log_file.write(loginfo) if len(self.odors) == 0: self.deliver_odors = False # reload odors self.odors = read_odd_file( self.odd_filename.encode('ascii')) return draw_points, draw_linesegs