class gtractFiberTrackingInputSpec(CommandLineInputSpec): inputTensorVolume = File( exists = "True",argstr = "--inputTensorVolume %s") inputAnisotropyVolume = File( exists = "True",argstr = "--inputAnisotropyVolume %s") inputStartingSeedsLabelMapVolume = File( exists = "True",argstr = "--inputStartingSeedsLabelMapVolume %s") startingSeedsLabel = traits.Int( argstr = "--startingSeedsLabel %d") inputEndingSeedsLabelMapVolume = File( exists = "True",argstr = "--inputEndingSeedsLabelMapVolume %s") endingSeedsLabel = traits.Int( argstr = "--endingSeedsLabel %d") inputTract = traits.Str( argstr = "--inputTract %s") outputTract = traits.Str( argstr = "--outputTract %s") writeXMLPolyDataFile = traits.Bool( argstr = "--writeXMLPolyDataFile ") trackingMethod = traits.Enum("Guided","Free","Streamline","GraphSearch", argstr = "--trackingMethod %s") guidedCurvatureThreshold = traits.Float( argstr = "--guidedCurvatureThreshold %f") maximumGuideDistance = traits.Float( argstr = "--maximumGuideDistance %f") seedThreshold = traits.Float( argstr = "--seedThreshold %f") trackingThreshold = traits.Float( argstr = "--trackingThreshold %f") curvatureThreshold = traits.Float( argstr = "--curvatureThreshold %f") branchingThreshold = traits.Float( argstr = "--branchingThreshold %f") maximumBranchPoints = traits.Int( argstr = "--maximumBranchPoints %d") useRandomWalk = traits.Bool( argstr = "--useRandomWalk ") randomSeed = traits.Int( argstr = "--randomSeed %d") branchingAngle = traits.Float( argstr = "--branchingAngle %f") minimumLength = traits.Float( argstr = "--minimumLength %f") maximumLength = traits.Float( argstr = "--maximumLength %f") stepSize = traits.Float( argstr = "--stepSize %f") useLoopDetection = traits.Bool( argstr = "--useLoopDetection ") useTend = traits.Bool( argstr = "--useTend ") tendF = traits.Float( argstr = "--tendF %f") tendG = traits.Float( argstr = "--tendG %f")
class compareTractInclusionInputSpec(CommandLineInputSpec): testFiber = traits.Str( argstr = "--testFiber %s") standardFiber = traits.Str( argstr = "--standardFiber %s") closeness = traits.Float( argstr = "--closeness %f") numberOfPoints = traits.Int( argstr = "--numberOfPoints %d") testForBijection = traits.Bool( argstr = "--testForBijection ") testForFiberCardinality = traits.Bool( argstr = "--testForFiberCardinality ") writeXMLPolyDataFile = traits.Bool( argstr = "--writeXMLPolyDataFile ")
class DicomToNrrdConverterInputSpec(CommandLineInputSpec): inputDicomDirectory = Directory( exists = "True",argstr = "--inputDicomDirectory %s") outputDirectory = traits.Either(traits.Bool, Directory, argstr = "--outputDirectory %s") outputVolume = traits.Str( argstr = "--outputVolume %s") smallGradientThreshold = traits.Float( argstr = "--smallGradientThreshold %f") writeProtocolGradientsFile = traits.Bool( argstr = "--writeProtocolGradientsFile ") useIdentityMeaseurementFrame = traits.Bool( argstr = "--useIdentityMeaseurementFrame ") useBMatrixGradientDirections = traits.Bool( argstr = "--useBMatrixGradientDirections ")
class BRAINSTalairachInputSpec(CommandLineInputSpec): AC = traits.List("traits.Float", sep=",", argstr="--AC %f") ACisIndex = traits.Bool(argstr="--ACisIndex ") PC = traits.List("traits.Float", sep=",", argstr="--PC %f") PCisIndex = traits.Bool(argstr="--PCisIndex ") SLA = traits.List("traits.Float", sep=",", argstr="--SLA %f") SLAisIndex = traits.Bool(argstr="--SLAisIndex ") IRP = traits.List("traits.Float", sep=",", argstr="--IRP %f") IRPisIndex = traits.Bool(argstr="--IRPisIndex ") inputVolume = File(exists="True", argstr="--inputVolume %s") outputBox = traits.Either(traits.Bool, File, argstr="--outputBox %s") outputGrid = traits.Either(traits.Bool, File, argstr="--outputGrid %s")
class N4ITKInputSpec(CommandLineInputSpec): inputImageName = File(exists="True", argstr="--inputimage %s") maskImageName = File(exists="True", argstr="--maskimage %s") outputImageName = traits.Either(traits.Bool, File, argstr="--outputimage %s") outputBiasFieldName = traits.Either(traits.Bool, File, argstr="--outputbiasfield %s") Force2D = traits.Bool(argstr="--force2D ") numberOfIterations = traits.List("traits.Int", sep=",", argstr="--iterations %d") convergenceThreshold = traits.Float(argstr="--convergencethreshold %f") initialMeshResolution = traits.List("traits.Float", sep=",", argstr="--meshresolution %f") splineDistance = traits.Float(argstr="--splinedistance %f") shrinkFactor = traits.Int(argstr="--shrinkfactor %d") bsplineOrder = traits.Int(argstr="--bsplineorder %d") weightImageName = File(exists="True", argstr="--weightimage %s") alpha = traits.Float(argstr="--bsplinealpha %f") beta = traits.Float(argstr="--bsplinebeta %f") histogramSharpening = traits.List("traits.Float", sep=",", argstr="--histogramsharpening %f") biasFieldFullWidthAtHalfMaximum = traits.Float( argstr="--biasFieldFullWidthAtHalfMaximum %f") weinerFilterNoise = traits.Float(argstr="--weinerFilterNoise %f") numberOfHistogramBins = traits.Int(argstr="--numberOfHistogramBins %d")
class BRAINSTalairachMaskInputSpec(CommandLineInputSpec): inputVolume = File(exists="True", argstr="--inputVolume %s") talairachParameters = File(exists="True", argstr="--talairachParameters %s") talairachBox = File(exists="True", argstr="--talairachBox %s") hemisphereMode = traits.Enum("left", "right", "both", argstr="--hemisphereMode %s") expand = traits.Bool(argstr="--expand ") outputVolume = traits.Either(traits.Bool, File, argstr="--outputVolume %s")
class BRAINSMeasureSurfaceInputSpec(CommandLineInputSpec): inputSurface = File( exists = "True",argstr = "--inputSurface %s") arrayName = traits.Str( argstr = "--arrayName %s") labels = traits.List("traits.Str", sep = ",",argstr = "--labelNames %s") subjectId = traits.Str( argstr = "--subjectId %s") scanId = traits.Str( argstr = "--scanId %s") writeCsvFile = traits.Bool( argstr = "--writeCsvFile ") writeXmlFile = traits.Bool( argstr = "--writeXmlFile ") csvFile = traits.Either(traits.Bool, File, argstr = "--csvFile %s") xmlFile = traits.Either(traits.Bool, File, argstr = "--xmlFile %s") testDepth = traits.Bool( argstr = "--testDepth ") totalDepthResults = traits.List("traits.Float", sep = ",",argstr = "--totalDepthResults %f") gyralDepthResults = traits.List("traits.Float", sep = ",",argstr = "--gyralDepthResults %f") sulcalDepthResults = traits.List("traits.Float", sep = ",",argstr = "--sulcalDepthResults %f") testArea = traits.Bool( argstr = "--testArea ") totalAreaResults = traits.List("traits.Float", sep = ",",argstr = "--totalAreaResults %f") gyralAreaResults = traits.List("traits.Float", sep = ",",argstr = "--gyralAreaResults %f") sulcalAreaResults = traits.List("traits.Float", sep = ",",argstr = "--sulcalAreaResults %f") testCurvature = traits.Bool( argstr = "--testCurvature ") totalCurvatureResults = traits.List("traits.Float", sep = ",",argstr = "--totalCurvatureResults %f") gyralCurvatureResults = traits.List("traits.Float", sep = ",",argstr = "--gyralCurvatureResults %f") sulcalCurvatureResults = traits.List("traits.Float", sep = ",",argstr = "--sulcalCurvatureResults %f")
class gtractFastMarchingTrackingInputSpec(CommandLineInputSpec): inputTensorVolume = File( exists = "True",argstr = "--inputTensorVolume %s") inputAnisotropyVolume = File( exists = "True",argstr = "--inputAnisotropyVolume %s") inputCostVolume = File( exists = "True",argstr = "--inputCostVolume %s") inputStartingSeedsLabelMapVolume = File( exists = "True",argstr = "--inputStartingSeedsLabelMapVolume %s") startingSeedsLabel = traits.Int( argstr = "--startingSeedsLabel %d") outputTract = traits.Str( argstr = "--outputTract %s") writeXMLPolyDataFile = traits.Bool( argstr = "--writeXMLPolyDataFile ") numberOfIterations = traits.Int( argstr = "--numberOfIterations %d") seedThreshold = traits.Float( argstr = "--seedThreshold %f") trackingThreshold = traits.Float( argstr = "--trackingThreshold %f") costStepSize = traits.Float( argstr = "--costStepSize %f") maximumStepSize = traits.Float( argstr = "--maximumStepSize %f") minimumStepSize = traits.Float( argstr = "--minimumStepSize %f")
class ColumnEditor(traits.HasTraits): """ Define the main column Editor class. Complex part is handled by get columns function below that defines the view and editor.""" columns = traits.List() numberOfColumns = traits.Int() selectAllButton = traits.Button('Select/Deselect All') selectDeselectBool = traits.Bool(True) def _selectAllButton_fired(self): if self.selectDeselectBool: self.columns = [] self.selectDeselectBool = not self.selectDeselectBool else: self.columns = range(0, self.numberOfColumns) self.selectDeselectBool = not self.selectDeselectBool
class IntRangeFeature(traits.HasTraits): """ Defines a feature that is settable by slider """ value = traits.Range('low','high','value_') value_ = traits.CInt(0.) low = traits.CInt(-10000.) high = traits.CInt(10000.) is_settable = traits.Bool(False) id = traits.Property(depends_on = 'name') index = traits.Int(0) name = 'gain' view = ui.View(ui.Item('value', show_label = False, style = 'custom')) def _get_id(self): return _SINGLE_VALUED_FEATURES.get(self.name)
class SortHandler(ui.Handler): column_clicked = traits.Any reverse_sort = traits.Bool(False) def _column_clicked_changed(self, event): """ Sort the functions based on the clicked column. Reverse the order of the sort each time the column is clicked. """ #### This is the list of the rows in the table. values = event.editor.value #### Reverse the sort order. self.reverse_sort = not self.reverse_sort # Sort by the clicked on column's field name and in the correct order. event.editor._update_visible = True # Workaround for a bug fields = [name for label, name in event.editor.adapter.columns] field = fields[event.column] values.sort(key=lambda x: getattr(x,field), reverse=self.reverse_sort)
class DeviceModelAnyVersion(DeviceModel): """Allow opening of device when firmware version does not match expectations This should only be done in special cases, such as to upgrade the firmware. """ ignore_version_mismatch = traits.Bool(True, transient=True)
class DeviceModel(traits.HasTraits): """Represent the trigger device in the host computer, and push any state We keep a local copy of the state of the device in memory on the host computer, and any state changes to the device to through this class, also allowing us to update our copy of the state. """ # Private runtime details _libusb_handle = traits.Any(None,transient=True) _lock = traits.Any(None,transient=True) # lock access to the handle real_device = traits.Bool(False,transient=True) # real USB device present FOSC = traits.Float(8000000.0,transient=True) ignore_version_mismatch = traits.Bool(False, transient=True) # A couple properties frames_per_second = RemoteFpsFloat frames_per_second_actual = traits.Property(depends_on='_t3_state') timer3_top = traits.Property(depends_on='_t3_state') # Timer 3 state: _t3_state = traits.Instance(DeviceTimer3State) # atomic updates # LEDs state _led_state = traits.Int led1 = traits.Property(depends_on='_led_state') led2 = traits.Property(depends_on='_led_state') led3 = traits.Property(depends_on='_led_state') led4 = traits.Property(depends_on='_led_state') # Event would be fine for these, but use Button to get nice editor reset_framecount_A = traits.Button reset_AIN_overflow = traits.Button do_single_frame_pulse = traits.Button ext_trig1 = traits.Button ext_trig2 = traits.Button ext_trig3 = traits.Button # Analog input state: _ain_state = traits.Instance(DeviceAnalogInState) # atomic updates Vcc = traits.Property(depends_on='_ain_state') AIN_running = traits.Property(depends_on='_ain_state') enabled_channels = traits.Property(depends_on='_ain_state') enabled_channel_names = traits.Property(depends_on='_ain_state') # The view: traits_view = View(Group( Group(Item('frames_per_second', label='frame rate', ), Item('frames_per_second_actual', show_label=False, style='readonly', ), orientation='horizontal',), Group(Item('ext_trig1',show_label=False), Item('ext_trig2',show_label=False), Item('ext_trig3',show_label=False), orientation='horizontal'), Item('_ain_state',show_label=False, style='custom'), Item('reset_AIN_overflow',show_label=False), )) def __init__(self,*a,**k): super(DeviceModel,self).__init__(*a,**k) self._t3_state = DeviceTimer3State() self._ain_state = DeviceAnalogInState(trigger_device=self) def __new__(cls,*args,**kwargs): """Set the transient object state This must be done outside of __init__, because instances can get created without calling __init__. In particular, when being loaded from a pickle. """ self = super(DeviceModel, cls).__new__(cls,*args,**kwargs) self._lock = threading.Lock() self._open_device() # force the USBKEY's state to our idea of its state self.__led_state_changed() self.__t3_state_changed() self.__ain_state_changed() self.reset_AIN_overflow = True # reset ain overflow #self.rand_pulse_enable() #self.rand_pulse_disable() #self.set_aout_values(300,250) return self def _set_led_mask(self,led_mask,value): if value: self._led_state = self._led_state | led_mask else: self._led_state = self._led_state & ~led_mask def __led_state_changed(self): buf = ctypes.create_string_buffer(2) buf[0] = chr(CAMTRIG_SET_LED_STATE) buf[1] = chr(self._led_state) self._send_buf(buf) @traits.cached_property def _get_led1(self): return bool(self._led_state & LEDS_LED1) def _set_led1(self,value): self._set_led_mask(LEDS_LED1,value) @traits.cached_property def _get_led2(self): return bool(self._led_state & LEDS_LED2) def _set_led2(self,value): self._set_led_mask(LEDS_LED2,value) @traits.cached_property def _get_led3(self): return bool(self._led_state & LEDS_LED3) def _set_led3(self,value): self._set_led_mask(LEDS_LED3,value) @traits.cached_property def _get_led4(self): return bool(self._led_state & LEDS_LED4) def _set_led4(self,value): self._set_led_mask(LEDS_LED4,value) @traits.cached_property def _get_Vcc(self): return self._ain_state.Vcc @traits.cached_property def _get_AIN_running(self): return self._ain_state.AIN_running @traits.cached_property def _get_enabled_channels(self): result = [] if self._ain_state.AIN0_enabled: result.append(0) if self._ain_state.AIN1_enabled: result.append(1) if self._ain_state.AIN2_enabled: result.append(2) if self._ain_state.AIN3_enabled: result.append(3) return result @traits.cached_property def _get_enabled_channel_names(self): result = [] if self._ain_state.AIN0_enabled: result.append(self._ain_state.AIN0_name) if self._ain_state.AIN1_enabled: result.append(self._ain_state.AIN1_name) if self._ain_state.AIN2_enabled: result.append(self._ain_state.AIN2_name) if self._ain_state.AIN3_enabled: result.append(self._ain_state.AIN3_name) return result @traits.cached_property def _get_timer3_top(self): return self._t3_state.timer3_top @traits.cached_property def _get_frames_per_second_actual(self): if self._t3_state.timer3_CS==0: return 0 return self.FOSC/self._t3_state.timer3_CS/self._t3_state.timer3_top def set_frames_per_second_approximate(self,value): """Set the framerate as close as possible to the desired value""" new_t3_state = DeviceTimer3State() if value==0: new_t3_state.timer3_CS=0 else: # For all possible clock select values CSs = np.array([1.0,8.0,64.0,256.0,1024.0]) # find the value of top that to gives the desired framerate best_top = np.clip(np.round(self.FOSC/CSs/value),0,2**16-1).astype(np.int) # and find the what the framerate would be at that top value best_rate = self.FOSC/CSs/best_top # and choose the best one. idx = np.argmin(abs(best_rate-value)) expected_rate = best_rate[idx] new_t3_state.timer3_CS = CSs[idx] new_t3_state.timer3_top = best_top[idx] ideal_ocr3a = 0.02 * new_t3_state.timer3_top # 2% duty cycle ocr3a = int(np.round(ideal_ocr3a)) if ocr3a==0: ocr3a=1 if ocr3a >= new_t3_state.timer3_top: ocr3a-=1 if ocr3a <= 0: raise ValueError('impossible combination for ocr3a') new_t3_state.ocr3a = ocr3a self._t3_state = new_t3_state # atomic update def get_framestamp(self,full_output=False): """Get the framestamp and the value of PORTC The framestamp includes fraction of IFI until next frame. The inter-frame counter counts up from 0 to self.timer3_top between frame ticks. """ if not self.real_device: now = time.time() if full_output: framecount = now//1 tcnt3 = now%1.0 results = now, framecount, tcnt3 else: results = now return results buf = ctypes.create_string_buffer(1) buf[0] = chr(CAMTRIG_GET_FRAMESTAMP_NOW) self._send_buf(buf) data = self._read_buf() if data is None: raise NoDataError('no data available from device') framecount = 0 for i in range(8): framecount += ord(data[i]) << (i*8) tcnt3 = ord(data[8]) + (ord(data[9]) << 8) frac = tcnt3/float(self._t3_state.timer3_top) if frac>1: print('In ttriger.DeviceModel.get_framestamp(): ' 'large fractional value in framestamp. resetting') frac=1 framestamp = framecount+frac # WBD #if full_output: # results = framestamp, framecount, tcnt3 #else: # results = framestamp pulse_width = ord(data[10]) if full_output: results = framestamp, pulse_width, framecount, tcnt3 else: results = framestamp, pulse_width return results def get_analog_input_buffer_rawLE(self): if not self.real_device: outbuf = np.array([],dtype='<u2') # unsigned 2 byte little endian return outbuf EP_LEN = 256 INPUT_BUFFER = ctypes.create_string_buffer(EP_LEN) bufs = [] got_bytes = False timeout = 50 # msec cnt = 0 # Count number of times endpoint has been read min_cnt = 2 # Minimum number of times end point should be read while 1: # keep pumping until no more data try: with self._lock: n_bytes = usb.bulk_read(self._libusb_handle, (ENDPOINT_DIR_IN|ANALOG_EPNUM), INPUT_BUFFER, timeout) except usb.USBNoDataAvailableError: break cnt += 1 n_elements = n_bytes//2 buf = np.fromstring(INPUT_BUFFER.raw,dtype='<u2') # unsigned 2 byte little endian buf = buf[:n_elements] bufs.append(buf) if (n_bytes < EP_LEN) and (cnt >= min_cnt): break # don't bother waiting for data to dribble in if len(bufs): outbuf = np.hstack(bufs) else: outbuf = np.array([],dtype='<u2') # unsigned 2 byte little endian return outbuf def __t3_state_changed(self): # A value was assigned to self._t3_state. # 1. Send its contents to device self._send_t3_state() # 2. Ensure updates to it also get sent to device if self._t3_state is None: return self._t3_state.on_trait_change(self._send_t3_state) def _send_t3_state(self): """ensure our concept of the device's state is correct by setting it""" t3 = self._t3_state # shorthand if t3 is None: return buf = ctypes.create_string_buffer(10) buf[0] = chr(CAMTRIG_NEW_TIMER3_DATA) buf[1] = chr(t3.ocr3a//0x100) buf[2] = chr(t3.ocr3a%0x100) buf[3] = chr(t3.ocr3b//0x100) buf[4] = chr(t3.ocr3b%0x100) buf[5] = chr(t3.ocr3c//0x100) buf[6] = chr(t3.ocr3c%0x100) buf[7] = chr(t3.timer3_top//0x100) # icr3a buf[8] = chr(t3.timer3_top%0x100) # icr3a buf[9] = chr(t3.timer3_CS_) self._send_buf(buf) def __ain_state_changed(self): # A value was assigned to self._ain_state. # 1. Send its contents to device self._send_ain_state() # 2. Ensure updates to it also get sent to device if self._ain_state is None: return self._ain_state.on_trait_change(self._send_ain_state) def _send_ain_state(self): """ensure our concept of the device's state is correct by setting it""" ain_state = self._ain_state # shorthand if ain_state is None: return if ain_state.AIN_running: # analog_cmd_flags channel_list = 0 if ain_state.AIN0_enabled: channel_list |= ENABLE_ADC_CHAN0 if ain_state.AIN1_enabled: channel_list |= ENABLE_ADC_CHAN1 if ain_state.AIN2_enabled: channel_list |= ENABLE_ADC_CHAN2 if ain_state.AIN3_enabled: channel_list |= ENABLE_ADC_CHAN3 analog_cmd_flags = ADC_START_STREAMING | channel_list analog_sample_bits = ain_state.adc_prescaler_ | (ain_state.downsample_bits<<3) else: analog_cmd_flags = ADC_STOP_STREAMING analog_sample_bits = 0 buf = ctypes.create_string_buffer(3) buf[0] = chr(CAMTRIG_AIN_SERVICE) buf[1] = chr(analog_cmd_flags) buf[2] = chr(analog_sample_bits) self._send_buf(buf) def enter_dfu_mode(self): buf = ctypes.create_string_buffer(1) buf[0] = chr(CAMTRIG_ENTER_DFU) self._send_buf(buf) def _do_single_frame_pulse_fired(self): buf = ctypes.create_string_buffer(1) buf[0] = chr(CAMTRIG_DO_TRIG_ONCE) self._send_buf(buf) def _ext_trig1_fired(self): buf = ctypes.create_string_buffer(2) buf[0] = chr(CAMTRIG_SET_EXT_TRIG) buf[1] = chr(EXT_TRIG1) self._send_buf(buf) def _ext_trig2_fired(self): buf = ctypes.create_string_buffer(2) buf[0] = chr(CAMTRIG_SET_EXT_TRIG) buf[1] = chr(EXT_TRIG2) self._send_buf(buf) def _ext_trig3_fired(self): buf = ctypes.create_string_buffer(2) buf[0] = chr(CAMTRIG_SET_EXT_TRIG) buf[1] = chr(EXT_TRIG3) self._send_buf(buf) def _reset_framecount_A_fired(self): buf = ctypes.create_string_buffer(1) buf[0] = chr(CAMTRIG_RESET_FRAMECOUNT_A) self._send_buf(buf) def _reset_AIN_overflow_fired(self): buf = ctypes.create_string_buffer(3) buf[0] = chr(CAMTRIG_AIN_SERVICE) buf[1] = chr(ADC_RESET_AIN) # 3rd byte doesn't matter self._send_buf(buf) # WBD - functions for enabling and disabling random pulses # -------------------------------------------------------- def rand_pulse_enable(self): buf = ctypes.create_string_buffer(2) buf[0] = chr(CAMTRIG_RAND_PULSE) buf[1] = chr(RAND_PULSE_ENABLE) self._send_buf(buf) def rand_pulse_disable(self): buf = ctypes.create_string_buffer(2) buf[0] = chr(CAMTRIG_RAND_PULSE) buf[1] = chr(RAND_PULSE_DISABLE) self._send_buf(buf) # WBD - function for setting analog output values # ------------------------------------------------------- def set_aout_values(self,val0, val1): buf = ctypes.create_string_buffer(5) buf[0] = chr(CAMTRIG_SET_AOUT) buf[1] = chr(val0//0x100) buf[2] = chr(val0%0x100) buf[3] = chr(val1//0x100) buf[4] = chr(val1%0x100) self._send_buf(buf) # WBD - get pulse width from frame count # ------------------------------------------------------- def get_width_from_framecnt(self,framecnt): buf = ctypes.create_string_buffer(5) buf[0] = chr(CAMTRIG_GET_PULSE_WIDTH) for i in range(1,5): buf[i] = chr((framecnt >> ((i-1)*8)) & 0b11111111) self._send_buf(buf) data = self._read_buf() val = ord(data[0]) return val # WBD - modified read_buf functions for multiple epnum in buffers # --------------------------------------------------------------- def _read_buf(self): if not self.real_device: return None buf = ctypes.create_string_buffer(16) timeout = 1000 epnum = (ENDPOINT_DIR_IN|CAMTRIG_EPNUM) with self._lock: try: val = usb.bulk_read(self._libusb_handle, epnum, buf, timeout) except usb.USBNoDataAvailableError: return None return buf # --------------------------------------------------------------- def _send_buf(self,buf): if not self.real_device: return with self._lock: val = usb.bulk_write(self._libusb_handle, 0x06, buf, 9999) def _open_device(self): require_trigger = int(os.environ.get('REQUIRE_TRIGGER','1')) if require_trigger: usb.init() if not usb.get_busses(): usb.find_busses() usb.find_devices() busses = usb.get_busses() found = False for bus in busses: for dev in bus.devices: debug('idVendor: 0x%04x idProduct: 0x%04x'% (dev.descriptor.idVendor,dev.descriptor.idProduct)) if (dev.descriptor.idVendor == 0x1781 and dev.descriptor.idProduct == 0x0BAF): found = True break if found: break if not found: raise RuntimeError("Cannot find device. (Perhaps run with " "environment variable REQUIRE_TRIGGER=0.)") else: self.real_device = False return with self._lock: self._libusb_handle = usb.open(dev) manufacturer = usb.get_string_simple(self._libusb_handle,dev.descriptor.iManufacturer) product = usb.get_string_simple(self._libusb_handle,dev.descriptor.iProduct) serial = usb.get_string_simple(self._libusb_handle,dev.descriptor.iSerialNumber) assert manufacturer == 'Strawman', 'Wrong manufacturer: %s'%manufacturer valid_product = 'Camera Trigger 1.0' if product == valid_product: self.FOSC = 8000000.0 elif product.startswith('Camera Trigger 1.01'): osc_re = r'Camera Trigger 1.01 \(F_CPU = (.*)\)\w*' match = re.search(osc_re,product) fosc_str = match.groups()[0] if fosc_str.endswith('UL'): fosc_str = fosc_str[:-2] self.FOSC = float(fosc_str) else: errmsg = 'Expected product "%s", but you have "%s"'%( valid_product,product) if self.ignore_version_mismatch: print 'WARNING:',errmsg self.FOSC = 8000000.0 print ' assuming FOSC=',self.FOSC else: raise ValueError(errmsg) interface_nr = 0 if hasattr(usb,'get_driver_np'): # non-portable libusb extension name = usb.get_driver_np(self._libusb_handle,interface_nr) if name != '': usb.detach_kernel_driver_np(self._libusb_handle,interface_nr) if dev.descriptor.bNumConfigurations > 1: debug("WARNING: more than one configuration, choosing first") config = dev.config[0] usb.set_configuration(self._libusb_handle, config.bConfigurationValue) usb.claim_interface(self._libusb_handle, interface_nr) self.real_device = True
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.maximumEnabled: 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 Berth(Sim.Process, traits.HasTraits): ID = traits.Int platform = traits.Instance('Platform') station = traits.Instance('Station') start_pos = traits.Float # The 'tail' end of the berth end_pos = traits.Float # The 'nose' end of the berth unloading = traits.Bool(False) loading = traits.Bool(False) storage_entrance = traits.Bool(False) storage_exit = traits.Bool(False) DISEMBARK = "DISEMBARK" EMBARK = "EMBARK" ENTER_STORAGE = "ENTER_STORAGE" EXIT_STORAGE = "EXIT_STORAGE" _action = traits.Enum(None, DISEMBARK, EMBARK, ENTER_STORAGE, EXIT_STORAGE) _error_continue = traits.Bool(False) ## traits_view = ui.View(ui.HGroup(ui.Item(name='vehicle', ## editor = ui.TextEditor()), ## ui.Item('busy'))) def __init__(self, ID, station, platform, start_pos, end_pos, unloading, loading, storage_entrance, storage_exit): Sim.Process.__init__(self, name='berth_' + str(ID)) traits.HasTraits.__init__(self) self.ID = ID self.station = station self.platform = platform self.start_pos = start_pos self.end_pos = end_pos self.unloading = unloading self.loading = loading self.storage_entrance = storage_entrance self.storage_exit = storage_exit # Record keeping for statistics ## self._occupied_times = [Sim.now(), self._vehicles[:]] # elements are (time, list_of_occupying_vehicle_refs) self._busy_times = [] # elements are: (time, busy_state) self._all_passengers = [ ] # record of all passengers, including those who have departed # Control flags/settings for the run loop self._busy = False # use the self._busy property to enable record gathering self._action = None self._fnc_args = None self._error_continue = False def __str__(self): return self.name ## def is_empty(self): ## """Returns True if the berth is not occupied by a vehicle.""" ## return False if self.vehicle else True def disembark(self, vehicle, passengers, cmd_msg, cmd_msg_id): """If ordering matters, note that passengers at the end of the list are serviced first.""" assert not self._busy self._action = Berth.DISEMBARK self._fnc_args = (vehicle, passengers, cmd_msg, cmd_msg_id) if self.passive: Sim.reactivate(self, prior=True) def embark(self, vehicle, passengers, cmd_msg, cmd_msg_id): """If ordering matters, note that passengers at the end of the list are serviced first.""" assert not self._busy self._action = Berth.EMBARK self._fnc_args = (vehicle, passengers, cmd_msg, cmd_msg_id) if self.passive: Sim.reactivate(self, prior=True) def enter_storage(self, vehicle, cmd_msg, cmd_msg_id): assert not self._busy self._action = Berth.ENTER_STORAGE self._fnc_args = (vehicle, cmd_msg, cmd_msg_id) if self.passive: Sim.reactivate(self, prior=True) def exit_storage(self, position, model_name, cmd_msg, cmd_msg_id): assert not self._busy self._action = Berth.EXIT_STORAGE self._fnc_args = (position, model_name, cmd_msg, cmd_msg_id) if self.passive: Sim.reactivate(self, prior=True) def get_busy(self): return self.__busy def set_busy(self, value): self._busy_times.append((Sim.now(), value)) self.__busy = value _busy = property(get_busy, set_busy) def is_busy(self): return self.__busy def run(self): """ The main loop for the Berth.""" # A Berth has four different tasks to accomplish but only one active loop. while True: try: if self._action is Berth.DISEMBARK: for disembark_delay in self._do_disembark(*self._fnc_args): yield Sim.hold, self, disembark_delay # Wait while passenger disembarks elif self._action is Berth.EMBARK: for embark_delay in self._do_embark(*self._fnc_args): yield Sim.hold, self, embark_delay elif self._action is Berth.ENTER_STORAGE: for enter_delay in self._do_enter_storage(*self._fnc_args): yield Sim.hold, self, enter_delay elif self._action is Berth.EXIT_STORAGE: for exit_delay in self._do_exit_storage(*self._fnc_args): yield Sim.hold, self, exit_delay except VehicleOutOfPositionError as err: nose_pos, tail_pos = err.vehicle.get_positions() logging.info( "T=%4.3f Vehicle not in berth for attempted %s. Vehicle: %s, Berth: %s, Platform: %s, Station: %s, DisembarkCmdId: %s, vNosePos: %s, vNoseLoc %s, vTailPos: %s, vTailLoc: %s, berth.start_pos: %s, berth.end_pos: %s", Sim.now(), self._action, err.vehicle.ID, self.ID, self.platform.ID, self.station.ID, err.msg_id, nose_pos, err.vehicle.loc, tail_pos, err.vehicle.tail_loc, self.start_pos, self.end_pos) error_msg = api.SimMsgBodyInvalidId() error_msg.id_type = api.VEHICLE error_msg.msgID = err.msg_id error_msg.ID = err.vehicle.ID common.interface.send(api.SIM_MSG_BODY_INVALID_ID, error_msg) self._busy = False except PassengerNotAvailableError as err: logging.info( "T=%4.3f Passenger not available for attempted %s. Vehicle: %s, Berth: %s, Platform: %s, Station: %s, DisembarkCmdId: %s, Passenger: %s", Sim.now(), self._action, err.vehicle.ID, self.ID, self.platform.ID, self.station.ID, err.msg_id, err.pax.ID) error_msg = api.SimMsgBodyInvalidId() error_msg.msgID = err.msg_id error_msg.id_type = api.PASSENGER error_msg.ID = err.pax.ID common.interface.send(api.SIM_MSG_BODY_INVALID_ID, error_msg) self._error_continue = True # process other passengers except VehicleFullError as err: logging.info( "T=%4.3f Action %s failed since vehicle is at max passenger capacity. Vehicle: %s, Berth: %s, Platform: %s, Station: %s, EmbarkCmdId: %s, Passenger: %s", Sim.now(), self._action, err.vehicle.ID, self.ID, self.platform.ID, self.station.ID, err.msg_id, err.pax.ID) error_msg = api.SimMsgBodyInvalidId() error_msg.msgID = err.msg_id error_msg.id_type = api.PASSENGER error_msg.ID = err.pax.ID common.interface.send(api.SIM_MSG_BODY_INVALID_ID, error_msg) self._error_continue = True # process other passengers if not self._error_continue: # Reset state self._action = None self._fnc_args = None assert not self._busy yield Sim.passivate, self else: # Go through the loop again self._error_continue = False def _do_disembark(self, vehicle, passengers, cmd_msg, cmd_msg_id): self._busy = True while passengers: pax = passengers.pop() self._do_disembark_pax_start(pax, vehicle, cmd_msg_id) yield pax.unload_delay # Wait while passenger disembarks self._do_disembark_pax_finish(pax, vehicle, cmd_msg_id) self._busy = False # Notify controller that all passenger disembarkments are done. cmd_complete = api.SimCompletePassengersDisembark() cmd_complete.msgID = cmd_msg_id cmd_complete.cmd.CopyFrom(cmd_msg) cmd_complete.time = Sim.now() common.interface.send(api.SIM_COMPLETE_PASSENGERS_DISEMBARK, cmd_complete) def _do_disembark_pax_start(self, pax, vehicle, cmd_msg_id): # Error if vehicle not parked in berth if not vehicle.is_parked_between(self.start_pos, self.end_pos, self.platform.track_segment): raise VehicleOutOfPositionError(vehicle, cmd_msg_id) # Error if pax not in the vehicle if pax not in vehicle.passengers: raise PassengerNotAvailableError(pax, vehicle, cmd_msg_id) # Notify controller that disembark of this passenger is starting start_msg = api.SimNotifyPassengerDisembarkStart() start_msg.vID = vehicle.ID start_msg.sID = self.station.ID start_msg.platformID = self.platform.ID start_msg.pID = pax.ID start_msg.berthID = self.ID start_msg.time = Sim.now() common.interface.send(api.SIM_NOTIFY_PASSENGER_DISEMBARK_START, start_msg) def _do_disembark_pax_finish(self, pax, vehicle, cmd_msg_id): # Error if vehicle is not still parked in berth if not vehicle.is_parked_between(self.start_pos, self.end_pos, self.platform.track_segment): raise VehicleOutOfPositionError(vehicle, cmd_msg_id) # Move the passenger from the vehicle to the station vehicle.disembark(pax) pax.loc = self.station # Note if the passenger has arrived at final dest (may not be # the case with non-PRT systems) if self.station.ID == pax.dest_station.ID: pax.trip_end = Sim.now() pax.trip_success = True common.delivered_pax.add(pax) self.station._pax_arrivals_count += 1 self.station._all_passengers.append(pax) logging.info( "T=%4.3f %s delivered to platform %s in %s by %s (%d out of %d), disembarked in berth %s", Sim.now(), pax, self.platform.ID, self.station.ID, vehicle.ID, vehicle.get_pax_count(), vehicle.max_pax_capacity, self.ID) else: self.station.add_passenger(pax) self.station._arrivals_count += 1 # Notify that disembark of this passenger is complete end_msg = api.SimNotifyPassengerDisembarkEnd() end_msg.vID = vehicle.ID end_msg.sID = self.station.ID end_msg.platformID = self.platform.ID end_msg.pID = pax.ID end_msg.berthID = self.ID end_msg.time = Sim.now() common.interface.send(api.SIM_NOTIFY_PASSENGER_DISEMBARK_END, end_msg) def _do_embark(self, vehicle, passengers, cmd_msg, cmd_msg_id): self._busy = True while passengers: pax = passengers.pop() self._do_embark_pax_start(pax, vehicle, cmd_msg_id) yield pax.load_delay self._do_embark_pax_finish(pax, vehicle, cmd_msg_id) self._busy = False # Notify controller that all passenger embarkments are done. cmd_complete = api.SimCompletePassengersEmbark() cmd_complete.msgID = cmd_msg_id cmd_complete.cmd.CopyFrom(cmd_msg) cmd_complete.time = Sim.now() common.interface.send(api.SIM_COMPLETE_PASSENGERS_EMBARK, cmd_complete) def _do_embark_pax_start(self, pax, vehicle, cmd_msg_id): # Error if vehicle not parked in berth if not vehicle.is_parked_between(self.start_pos, self.end_pos, self.platform.track_segment): raise VehicleOutOfPositionError(vehicle, cmd_msg_id) # Error if pax not at the station if pax not in self.station._passengers: raise PassengerNotAvailableError(pax, vehicle, cmd_msg_id) # Error if the vehicle is at full capacity if vehicle.get_pax_count() >= vehicle.max_pax_capacity: raise VehicleFullError(pax, vehicle, cmd_msg_id) # Notify controller that embark of this passenger is starting start_msg = api.SimNotifyPassengerEmbarkStart() start_msg.vID = vehicle.ID start_msg.sID = self.station.ID start_msg.platformID = self.platform.ID start_msg.pID = pax.ID start_msg.berthID = self.ID start_msg.time = Sim.now() common.interface.send(api.SIM_NOTIFY_PASSENGER_EMBARK_START, start_msg) def _do_embark_pax_finish(self, pax, vehicle, cmd_msg_id): # Error if vehicle is not still parked in berth if not vehicle.is_parked_between(self.start_pos, self.end_pos, self.platform.track_segment): raise VehicleOutOfPositionError(vehicle, cmd_msg_id) # Move passenger's location to the vehicle vehicle.embark(pax) pax.loc = vehicle self.station._pax_departures_count += 1 self.station.remove_passenger(pax) pax.trip_boarded = Sim.now() logging.info( "T=%4.3f %s loaded into Vehicle %s (%d out of %d) at station %s, platform %s, berth %s ", Sim.now(), pax, vehicle.ID, vehicle.get_pax_count(), vehicle.max_pax_capacity, self.station.ID, self.platform.ID, self.ID) # Notify that embark of this passenger is complete end_msg = api.SimNotifyPassengerEmbarkEnd() end_msg.vID = vehicle.ID end_msg.sID = self.station.ID end_msg.platformID = self.platform.ID end_msg.pID = pax.ID end_msg.berthID = self.ID end_msg.time = Sim.now() common.interface.send(api.SIM_NOTIFY_PASSENGER_EMBARK_END, end_msg) def _do_enter_storage(self, vehicle, cmd_msg, cmd_msg_id): if not vehicle.is_parked_between(self.start_pos, self.end_pos, self.platform.track_segment): raise VehicleOutOfPositionError(vehicle, cmd_msg_id) storage = self.station._storage_dict[vehicle.model_name] storage._reserve_slot() self._busy = True yield self.station.storage_entrance_delay if not vehicle.is_parked_between(self.start_pos, self.end_pos, self.platform.track_segment): raise VehicleOutOfPositionError(vehicle, cmd_msg_id) storage._store_vehicle(vehicle) self._busy = False # Notify controller that vehicle entering storage is done. cmd_complete = api.SimCompleteStorageEnter() cmd_complete.msgID = cmd_msg_id cmd_complete.cmd.CopyFrom(cmd_msg) cmd_complete.time = Sim.now() common.interface.send(api.SIM_COMPLETE_STORAGE_ENTER, cmd_complete) def _do_exit_storage(self, position, model_name, cmd_msg, cmd_msg_id): storage = self.station._storage_dict[model_name] storage._reserve_vehicle() self._busy = True yield self.station.storage_exit_delay vehicle = storage._request_vehicle(position, self.platform.track_segment) self._busy = False # Notify controller that vehicle exiting storage is done. cmd_complete = api.SimCompleteStorageExit() cmd_complete.msgID = cmd_msg_id cmd_complete.cmd.CopyFrom(cmd_msg) cmd_complete.time = Sim.now() vehicle.fill_VehicleStatus(cmd_complete.v_status) common.interface.send(api.SIM_COMPLETE_STORAGE_EXIT, cmd_complete) logging.info( "T=%4.3f Exit from Storage: Vehicle: %s, Berth: %s, Platform: %s, Station: %s", Sim.now(), vehicle.ID, self.ID, self.platform.ID, self.station.ID)
class BRAINSClassifyInputSpec(CommandLineInputSpec): t1Volume = File(exists="True", argstr="--t1Volume %s") t2Volume = File(exists="True", argstr="--t2Volume %s") pdVolume = File(exists="True", argstr="--pdVolume %s") gmPlugs = File(exists="True", argstr="--gmPlugs %s") wmPlugs = traits.Either(traits.Bool, File, argstr="--wmPlugs %s") csfPlugs = File(exists="True", argstr="--csfPlugs %s") bloodPlugs = File(exists="True", argstr="--bloodPlugs %s") BrainVolume = File(exists="True", argstr="--BrainVolume %s") classVolume = traits.Either(traits.Bool, File, argstr="--classVolume %s") grossTrim = traits.Float(argstr="--grossTrim %f") spatialTrim = traits.Float(argstr="--spatialTrim %f") x = traits.Bool(argstr="--x ") y = traits.Bool(argstr="--y ") z = traits.Bool(argstr="--z ") xx = traits.Bool(argstr="--xx ") yy = traits.Bool(argstr="--yy ") zz = traits.Bool(argstr="--zz ") xy = traits.Bool(argstr="--xy ") xz = traits.Bool(argstr="--xz ") yz = traits.Bool(argstr="--yz ") histogramEqualize = traits.Bool(argstr="--histogramEqualize ") generateSeperateImages = traits.Bool(argstr="--generateSeperateImages ") excludeVolume = File(exists="True", argstr="--excludeVolume %s")
class gtractResampleFibersInputSpec(CommandLineInputSpec): inputForwardDeformationFieldVolume = File( exists = "True",argstr = "--inputForwardDeformationFieldVolume %s") inputReverseDeformationFieldVolume = File( exists = "True",argstr = "--inputReverseDeformationFieldVolume %s") inputTract = traits.Str( argstr = "--inputTract %s") outputTract = traits.Str( argstr = "--outputTract %s") writeXMLPolyDataFile = traits.Bool( argstr = "--writeXMLPolyDataFile ")
class PipelineConfiguration(traits.HasTraits): # project settings project_dir = traits.Directory( exists=False, desc="data path to where the project is stored") # project metadata (for connectome file) project_metadata = traits.Dict( desc="project metadata to be stored in the connectome file") # DEPRECATED: this field is deprecated after version >1.0.2 generator = traits.Str() # parcellation scheme parcellation_scheme = traits.Enum("NativeFreesurfer", ["Lausanne2008", "NativeFreesurfer"], desc="used parcellation scheme") # choose between 'L' (linear) and 'N' (non-linear) and 'B' (bbregister) registration_mode = traits.Enum( "Linear", ["Linear", "Nonlinear", "BBregister"], desc="registration mode: linear or non-linear or bbregister") # choose between 'L' (linear) and 'B' (bbregister) rsfmri_registration_mode = traits.Enum( "Linear", ["Linear", "BBregister"], desc="registration mode: linear or bbregister") diffusion_imaging_model = traits.Enum("DSI", ["DSI", "DTI", "QBALL"]) # DSI nr_of_gradient_directions = traits.Str('515') nr_of_sampling_directions = traits.Str('181') odf_recon_param = traits.Str('-b0 1 -dsi -p 4 -sn 0') hardi_recon_param = traits.Str('-b0 1 -p 3 -sn 0') # DTI gradient_table_file = traits.File(exists=False) gradient_table = traits.Enum('siemens_64', [ 'custom', 'mgh_dti_006', 'mgh_dti_018', 'mgh_dti_030', 'mgh_dti_042', 'mgh_dti_060', 'mgh_dti_072', 'mgh_dti_090', 'mgh_dti_120', 'mgh_dti_144', 'siemens_06', 'siemens_12', 'siemens_20', 'siemens_256', 'siemens_30', 'siemens_64' ]) nr_of_b0 = traits.Str('1') max_b0_val = traits.Str('1000') dti_recon_param = traits.Str('') dtb_dtk2dir_param = traits.Str('') # tractography streamline_param = traits.Str('--angle 60 --seeds 32') # registration lin_reg_param = traits.Str('-usesqform -nosearch -dof 6 -cost mutualinfo') nlin_reg_bet_T2_param = traits.Str('-f 0.35 -g 0.15') nlin_reg_bet_b0_param = traits.Str('-f 0.2 -g 0.2') nlin_reg_fnirt_param = traits.Str( '--subsamp=8,4,2,2 --miter==5,5,5,5 --lambda=240,120,90,30 --splineorder=3 --applyinmask=0,0,1,1 --applyrefmask=0,0,1,1' ) bb_reg_param = traits.Str('--init-header --dti') # dicom converter do_convert_diffusion = traits.Bool(True) do_convert_T1 = traits.Bool(True) do_convert_T2 = traits.Bool(False) do_convert_fMRI = traits.Bool(False) # rsfmri rsfmri_lin_reg_param = traits.Str( '-usesqform -nosearch -dof 6 -cost mutualinfo') rsfmri_bb_reg_param = traits.Str('--init-header --dti') do_save_mat = traits.Bool(True) # DEPRECATED: subject_raw_glob_diffusion = traits.Str("*.*") subject_raw_glob_T1 = traits.Str("*.*") subject_raw_glob_T2 = traits.Str("*.*") extract_diffusion_metadata = traits.Bool(False) # subject subject_name = traits.Str() subject_timepoint = traits.Str() subject_workingdir = traits.Directory() subject_logger = None subject_metadata = [ KeyValue(key='description', value=''), KeyValue(key='', value=''), KeyValue(key='', value=''), KeyValue(key='', value=''), KeyValue(key='', value=''), KeyValue(key='', value=''), ] active_createfolder = traits.Bool(True) active_dicomconverter = traits.Bool(False) active_registration = traits.Bool(False) active_segmentation = traits.Bool(False) active_parcellation = traits.Bool(False) active_applyregistration = traits.Bool(False) active_reconstruction = traits.Bool(False) active_tractography = traits.Bool(False) active_fiberfilter = traits.Bool(False) active_connectome = traits.Bool(False) active_statistics = traits.Bool(False) active_rsfmri = traits.Bool(False) active_cffconverter = traits.Bool(False) skip_completed_stages = traits.Bool(False) # metadata creator = traits.Str() email = traits.Str() publisher = traits.Str() created = traits.Date() modified = traits.Date() license = traits.Str() # rights = traits.Str() reference = traits.Str() # relation = traits.Str() species = traits.Str('H**o sapiens') description = traits.Str() # segmentation recon_all_param = traits.Str('-all -no-isrunning') # parcellation custompar_nrroi = traits.Int() custompar_nodeinfo = traits.File() custompar_volumeparcell = traits.File() # fiber filtering apply_splinefilter = traits.Bool( True, desc='apply the spline filtering from diffusion toolkit') apply_fiberlength = traits.Bool(True, desc='apply cutoff to fiber lengths') fiber_cutoff_lower = traits.Float( 20.0, desc='cut fibers that are shorter in length than given length in mm') fiber_cutoff_upper = traits.Float( 500.0, desc='cut fibers that are longer in length than given length in mm') # measures connection_P0 = traits.Bool(False) connection_gfa = traits.Bool(False) connection_kurtosis = traits.Bool(False) connection_skewness = traits.Bool(False) connection_adc = traits.Bool(False) connection_fa = traits.Bool(False) # cff converter cff_fullnetworkpickle = traits.Bool( True, desc='stores the full network pickle generated by connectome creation') cff_cmatpickle = traits.Bool(True) cff_originalfibers = traits.Bool(True, desc='stores original fibers') cff_filteredfibers = traits.Bool(True, desc='stores filtered fibers') cff_finalfiberlabels = traits.Bool( True, desc='stores final fibers and their labelarrays') cff_fiberarr = traits.Bool(True) cff_rawdiffusion = traits.Bool(True) cff_scalars = traits.Bool(True) cff_rawT1 = traits.Bool(True) cff_rawT2 = traits.Bool(True) cff_roisegmentation = traits.Bool( True, desc='stores multi-resolution parcellation volumes') cff_surfaces = traits.Bool(True, desc='stores individually genertated surfaces') cff_surfacelabels = traits.Bool( True, desc='stores individually genertated surfaces') # do you want to do manual white matter mask correction? wm_handling = traits.Enum( 1, [1, 2, 3], desc="in what state should the freesurfer step be processed") # custom parcellation parcellation = traits.Dict( desc="provide the dictionary with your parcellation.") # start up fslview inspect_registration = traits.Bool( False, desc='start fslview to inspect the the registration results') fsloutputtype = traits.Enum('NIFTI', ['NIFTI']) # connectome creation compute_curvature = traits.Bool(False) # email notification, needs a local smtp server # sudo apt-get install postfix emailnotify = traits.ListStr( [], desc='the email address to send stage completion status message') freesurfer_home = traits.Directory(exists=False, desc="path to Freesurfer") fsl_home = traits.Directory(exists=False, desc="path to FSL") dtk_home = traits.Directory(exists=False, desc="path to diffusion toolkit") # This file stores descriptions of the inputs/outputs to each stage of the # CMP pipeline. It can be queried using the PipelineStatus python object pipeline_status_file = traits.Str("cmp.status") # Pipeline status object pipeline_status = pipeline_status.PipelineStatus() def _get_lausanne_parcellation(self, parcel="NativeFreesurfer"): if parcel == "Lausanne2008": return { 'scale33': { 'number_of_regions': 83, # contains name, url, color, freesurfer_label, etc. used for connection matrix 'node_information_graphml': op.join( self.get_lausanne_parcellation_path('resolution83'), 'resolution83.graphml'), # scalar node values on fsaverage? or atlas? 'surface_parcellation': None, # scalar node values in fsaverage volume? 'volume_parcellation': None, # the subdirectory name from where to copy parcellations, with hemispheric wildcard 'fs_label_subdir_name': 'regenerated_%s_36', # should we subtract the cortical rois for the white matter mask? 'subtract_from_wm_mask': 1, }, 'scale60': { 'number_of_regions': 129, 'node_information_graphml': op.join( self.get_lausanne_parcellation_path('resolution150'), 'resolution150.graphml'), 'surface_parcellation': None, 'volume_parcellation': None, 'fs_label_subdir_name': 'regenerated_%s_60', 'subtract_from_wm_mask': 1, }, 'scale125': { 'number_of_regions': 234, 'node_information_graphml': op.join( self.get_lausanne_parcellation_path('resolution258'), 'resolution258.graphml'), 'surface_parcellation': None, 'volume_parcellation': None, 'fs_label_subdir_name': 'regenerated_%s_125', 'subtract_from_wm_mask': 1, }, 'scale250': { 'number_of_regions': 463, 'node_information_graphml': op.join( self.get_lausanne_parcellation_path('resolution500'), 'resolution500.graphml'), 'surface_parcellation': None, 'volume_parcellation': None, 'fs_label_subdir_name': 'regenerated_%s_250', 'subtract_from_wm_mask': 1, }, 'scale500': { 'number_of_regions': 1015, 'node_information_graphml': op.join( self.get_lausanne_parcellation_path('resolution1015'), 'resolution1015.graphml'), 'surface_parcellation': None, 'volume_parcellation': None, 'fs_label_subdir_name': 'regenerated_%s_500', 'subtract_from_wm_mask': 1, }, } else: return { 'freesurferaparc': { 'number_of_regions': 83, # contains name, url, color, freesurfer_label, etc. used for connection matrix 'node_information_graphml': op.join( self.get_lausanne_parcellation_path('freesurferaparc'), 'resolution83.graphml'), # scalar node values on fsaverage? or atlas? 'surface_parcellation': None, # scalar node values in fsaverage volume? 'volume_parcellation': None, } } def __init__(self, **kwargs): # NOTE: In python 2.6, object.__init__ no longer accepts input # arguments. HasTraits does not define an __init__ and # therefore these args were being ignored. super(PipelineConfiguration, self).__init__(**kwargs) # the default parcellation provided self.parcellation = self._get_lausanne_parcellation( parcel="NativeFreesurfer") self.can_use_dipy = dipy_here # no email notify self.emailnotify = [] # default gradient table for DTI self.gradient_table_file = self.get_cmp_gradient_table('siemens_64') # try to discover paths from environment variables try: self.freesurfer_home = op.join(os.environ['FREESURFER_HOME']) self.fsl_home = op.join(os.environ['FSLDIR']) self.dtk_home = os.environ['DTDIR'] self.dtk_matrices = op.join(self.dtk_home, 'matrices') except KeyError: pass self.fsloutputtype = 'NIFTI' os.environ['FSLOUTPUTTYPE'] = self.fsloutputtype os.environ['FSLOUTPUTTYPE'] = 'NIFTI' def consistency_check(self): """ Provides a checking facility for configuration objects """ # project name not empty if not op.exists(self.project_dir): msg = 'Your project directory does not exist!' raise Exception(msg) # check metadata if self.creator == '': raise Exception('You need to enter creator metadata!') if self.publisher == '': raise Exception('You need to enter publisher metadata!') if self.email == '': raise Exception('You need to enter email of a contact person!') # check if software paths exists pas = { 'configuration.freesurfer_home': self.freesurfer_home, 'configuration.fsl_home': self.fsl_home, 'configuration.dtk_home': self.dtk_home, 'configuration.dtk_matrices': self.dtk_matrices } for k, p in pas.items(): if not op.exists(p): msg = 'Required software path for %s does not exists: %s' % (k, p) raise Exception(msg) if self.subject_workingdir == '': msg = 'No working directory defined for subject' raise Exception(msg) # else: # wdir = self.get_subj_dir() # if not op.exists(wdir): # msg = 'Working directory %s does not exists for subject' % (wdir) # raise Exception(msg) # else: # wdiff = op.join(self.get_raw_diffusion()) # print wdiff # if not op.exists(wdiff): # msg = 'Diffusion MRI subdirectory %s does not exists for the subject' % wdiff # raise Exception(msg) # wt1 = op.join(self.get_rawt1()) # if not op.exists(wt1): # msg = 'Structural MRI subdirectory %s T1 does not exist in RAWDATA' % wt1 # raise Exception(msg) def get_cmp_home(self): """ Return the cmp home path """ return op.dirname(__file__) def get_rawdata(self): """ Return raw data path for the subject """ return op.join(self.get_subj_dir(), 'RAWDATA') def get_log(self): """ Get subject log dir """ return op.join(self.get_subj_dir(), 'LOG') def get_logname(self, suffix='.log'): """ Get a generic name for the log and pickle files """ a = dt.datetime.now() return 'pipeline-%s-%02i%02i-%s-%s%s' % ( a.date().isoformat(), a.time().hour, a.time().minute, self.subject_name, self.subject_timepoint, suffix) def get_logger(self): """ Get the logger instance created """ if self.subject_logger is None: # setup logger for the subject self.subject_logger = \ getLog(os.path.join(self.get_log(), self.get_logname())) return self.subject_logger else: return self.subject_logger def get_rawglob(self, modality): """ DEPRECATED: Get the file name endings for modality """ if modality == 'diffusion': if not self.subject_raw_glob_diffusion == '': return self.subject_raw_glob_diffusion else: raise Exception('No raw_glob_diffusion defined for subject') elif modality == 'T1': if not self.subject_raw_glob_T1 == '': return self.subject_raw_glob_T1 else: raise Exception('No raw_glob_T1 defined for subject') elif modality == 'T2': if not self.subject_raw_glob_T2 == '': return self.subject_raw_glob_T2 else: raise Exception('No raw_glob_T2 defined for subject') def get_dicomfiles(self, modality): """ Get a list of dicom files for the requested modality. Tries to discover them automatically """ from glob import glob if modality == 'diffusion': pat = self.get_raw_diffusion() elif modality == 'T1': pat = self.get_rawt1() elif modality == 'T2': pat = self.get_rawt2() elif modality == 'fMRI': pat = self.get_rawrsfmri() # discover files with *.* and * difiles = sorted(glob(op.join(pat, '*.*')) + glob(op.join(pat, '*'))) # exclude potential .nii and .nii.gz files difiles = [ e for e in difiles if not e.endswith('.nii') and not e.endswith('.nii.gz') ] # check if no files and throw exception if len(difiles) == 0: raise Exception('Could not find any DICOM files in folder %s' % pat) return difiles def get_rawrsfmri(self): """ Get raw functional MRI path for subject """ return op.join(self.get_rawdata(), 'fMRI') def get_rawt1(self): """ Get raw structural MRI T1 path for subject """ return op.join(self.get_rawdata(), 'T1') def get_rawt2(self): """ Get raw structural MRI T2 path for subject """ return op.join(self.get_rawdata(), 'T2') def get_subj_dir(self): return self.subject_workingdir def get_raw_diffusion(self): """ Get the raw diffusion path for subject """ if self.diffusion_imaging_model == 'DSI': return op.join(self.get_subj_dir(), 'RAWDATA', 'DSI') elif self.diffusion_imaging_model == 'DTI': return op.join(self.get_subj_dir(), 'RAWDATA', 'DTI') elif self.diffusion_imaging_model == 'QBALL': return op.join(self.get_subj_dir(), 'RAWDATA', 'QBALL') def get_fs(self): """ Returns the subject root folder path for freesurfer files """ return op.join(self.get_subj_dir(), 'FREESURFER') def get_stats(self): """ Return statistic output path """ return op.join(self.get_subj_dir(), 'STATS') def get_cffdir(self): """ Returns path to store connectome file """ return op.join(self.get_cmp(), 'cff') def get_nifti(self): """ Returns the subject root folder path for nifti files """ return op.join(self.get_subj_dir(), 'NIFTI') def get_nifti_trafo(self): """ Returns the path to the subjects transformation / registration matrices """ return op.join(self.get_nifti(), 'transformations') def get_nifti_bbregister(self): """ Returns the path to the subjects transformation / registration matrices, bbregister mode """ return op.join(self.get_nifti(), 'bbregister') def get_diffusion_metadata(self): """ Diffusion metadata, i.e. where gradient_table.txt is stored """ return op.join(self.get_nifti(), 'diffusion_metadata') def get_nifti_wm_correction(self): """ Returns the path to the subjects wm_correction path """ return op.join(self.get_nifti(), 'wm_correction') def get_cmp(self): return op.join(self.get_subj_dir(), 'CMP') def get_cmp_rawdiff(self, ): return op.join(self.get_cmp(), 'raw_diffusion') def get_cmp_rawdiff_reconout(self): """ Returns the output path for diffusion reconstruction without prefix""" if self.diffusion_imaging_model == 'DSI': return op.join(self.get_cmp(), 'raw_diffusion', 'odf_0') elif self.diffusion_imaging_model == 'DTI': return op.join(self.get_cmp(), 'raw_diffusion', 'dti_0') elif self.diffusion_imaging_model == 'QBALL': return op.join(self.get_cmp(), 'raw_diffusion', 'qball_0') def get_cmp_rawdiff_resampled(self): return op.join(self.get_cmp_rawdiff(), '2x2x2') def get_cmp_fsout(self): return op.join(self.get_cmp(), 'fs_output') def get_cmp_fibers(self): return op.join(self.get_cmp(), 'fibers') def get_cmp_scalars(self): return op.join(self.get_cmp(), 'scalars') def get_cmp_matrices(self): return op.join(self.get_cmp_fibers(), 'matrices') def get_cmp_fmri(self): return op.join(self.get_cmp(), 'fMRI') def get_cmp_tracto_mask(self): return op.join(self.get_cmp_fsout(), 'HR') def get_cmp_tracto_mask_tob0(self): return op.join(self.get_cmp_fsout(), 'HR__registered-TO-b0') def get_custom_gradient_table(self): """ Returns the absolute path to the custom gradient table with optional b-values in the 4th row """ return self.gradient_table_file def get_cmp_gradient_table(self, name): """ Return default gradient tables shipped with CMP. These are mainly derived from Diffusion Toolkit """ cmp_path = op.dirname(__file__) return op.join(cmp_path, 'data', 'diffusion', 'gradient_tables', name + '.txt') def get_dtb_streamline_vecs_file(self, as_text=False): """ Returns the odf directions file used for DTB_streamline """ cmp_path = op.dirname(__file__) if as_text: return op.join(cmp_path, 'data', 'diffusion', 'odf_directions', '181_vecs.txt') else: return op.join(cmp_path, 'data', 'diffusion', 'odf_directions', '181_vecs.dat') # XXX def get_cmp_scalarfields(self): """ Returns a list with tuples with the scalar field name and the absolute path to its nifti file """ ret = [] if self.diffusion_imaging_model == 'DSI': # add gfa per default ret.append(('gfa', op.join(self.get_cmp_scalars(), 'dsi_gfa.nii.gz'))) # XXX: add adc per default elif self.diffusion_imaging_model == 'DTI': # nothing to add yet for DTI pass return ret def get_dtk_dsi_matrix(self): """ Returns the DSI matrix from Diffusion Toolkit The parameters have to be set in the configuration object with keys: 1. number of gradient directions : 'nr_of_gradient_directions' 2. number of sampling directions : 'nr_of_sampling_directions' Example ------- confobj.nr_of_gradient_directions = 515 confobj.nr_of_sampling_directions = 181 Returns matrix including absolute path to DSI_matrix_515x181.dat """ grad = self.nr_of_gradient_directions samp = self.nr_of_sampling_directions fpath = op.join(self.dtk_matrices, "DSI_matrix_%sx%s.dat" % (grad, samp)) if not op.exists(fpath): msg = "DSI matrix does not exists: %s" % fpath raise Exception(msg) return fpath def get_lausanne_atlas(self, name=None): """ Return the absolute path to the lausanne parcellation atlas for the resolution name """ cmp_path = op.dirname(__file__) provided_atlases = [ 'myatlas_36_rh.gcs', 'myatlasP1_16_rh.gcs', 'myatlasP17_28_rh.gcs', 'myatlasP29_36_rh.gcs', 'myatlas_60_rh.gcs', 'myatlas_125_rh.gcs', 'myatlas_250_rh.gcs', 'myatlas_36_lh.gcs', 'myatlasP1_16_lh.gcs', 'myatlasP17_28_lh.gcs', 'myatlasP29_36_lh.gcs', 'myatlas_60_lh.gcs', 'myatlas_125_lh.gcs', 'myatlas_250_lh.gcs' ] if name in provided_atlases: return op.join(cmp_path, 'data', 'colortable_and_gcs', 'my_atlas_gcs', name) else: msg = "Atlas %s does not exists" % name raise Exception(msg) def get_freeview_lut(self, name): """ Returns the Look-Up-Table as text file for a given parcellation scheme in a dictionary """ cmp_path = op.dirname(__file__) if name == "NativeFreesurfer": return { 'freesurferaparc': op.join(cmp_path, 'data', 'parcellation', 'nativefreesurfer', 'freesurferaparc', 'FreeSurferColorLUT_adapted.txt') } else: return "" def get_lausanne_parcellation_path(self, parcellationname): cmp_path = op.dirname(__file__) if self.parcellation_scheme == "Lausanne2008": allowed_default_parcel = [ 'resolution83', 'resolution150', 'resolution258', 'resolution500', 'resolution1015' ] if parcellationname in allowed_default_parcel: return op.join(cmp_path, 'data', 'parcellation', 'lausanne2008', parcellationname) else: msg = "Not a valid default parcellation name for the lausanne2008 parcellation scheme" raise Exception(msg) else: allowed_default_parcel = ['freesurferaparc'] if parcellationname in allowed_default_parcel: return op.join(cmp_path, 'data', 'parcellation', 'nativefreesurfer', parcellationname) else: msg = "Not a valid default parcellation name for the NativeFreesurfer parcellation scheme" raise Exception(msg) def get_cmp_binary_path(self): """ Returns the path to the binary files for the current platform and architecture """ if sys.platform == 'linux2': import platform as pf if '32' in pf.architecture()[0]: return op.join(op.dirname(__file__), "binary", "linux2", "bit32") elif '64' in pf.architecture()[0]: return op.join(op.dirname(__file__), "binary", "linux2", "bit64") else: raise ('No binary files compiled for your platform!') def get_pipeline_status_file(self): """Returns the absolute path of the pipeline status file""" return op.join(self.get_subj_dir(), self.pipeline_status_file) def init_pipeline_status(self): """Create the 'cmp.status'. The 'cmp.status' file contains information about the inputs/outputs of each pipeline stage""" status_file = op.join(self.get_subj_dir(), self.pipeline_status_file) self.pipeline_status.Pipeline.name = "cmp" self.pipeline_status.SaveToFile(status_file) def update_pipeline_status(self): """Update the pipeline status on disk with the current status in memory""" status_file = op.join(self.get_subj_dir(), self.pipeline_status_file) self.pipeline_status.SaveToFile(status_file)
class gtractCreateGuideFiberInputSpec(CommandLineInputSpec): inputFiber = traits.Str( argstr = "--inputFiber %s") numberOfPoints = traits.Int( argstr = "--numberOfPoints %d") outputFiber = traits.Str( argstr = "--outputFiber %s") writeXMLPolyDataFile = traits.Bool( argstr = "--writeXMLPolyDataFile ")
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") 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" ) autoGuessBool = 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)" ) autoDrawBool = traits.Bool( False, desc= "Once a fit is complete update the drawing of the fit or draw the fit for the first time" ) 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" ) 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") logDirectory = os.path.join("\\\\ursa", "AQOGroupFolder", "Experiment Humphry", "Data", "eagleLogs") latestSequence = os.path.join("\\\\ursa", "AQOGroupFolder", "Experiment Humphry", "Experiment Control And Software", "currentSequence", "latestSequence.xml") 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( False) #true when current data displayed has been fitted startX = traits.Int startY = traits.Int endX = traits.Int endY = traits.Int 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.Item("fitSubSpace", label="Fit Sub Space", resizable=True), 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.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("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("usePreviousFitValuesButton", show_label=False, resizable=True))) logGroup = traitsui.VGroup(traitsui.HGroup( traitsui.Item("logBool", resizable=True), traitsui.Item("chooseVariablesButtons", show_label=False, resizable=True)), traitsui.HGroup( traitsui.Item("logName", resizable=True)), 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) 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.debug("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 logFolder = os.path.join(self.logDirectory, 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) 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.xmlLogVariables 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.xmlLogVariables ] 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 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()
class DataAxis(t.HasTraits): name = t.Str() units = t.Str() scale = t.Float() offset = t.Float() size = t.Int() index_in_array = t.Int() 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) slice_bool = t.Bool(False) index = t.Range('low_index', 'high_index') axis = t.Array() def __init__(self, size, index_in_array, name='', scale=1., offset=0., units='undefined', slice_bool=False): 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.index_in_array = index_in_array self.update_axis() 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, 'slice_bool') self.on_trait_change(self.update_index_bounds, 'size') self.slice_bool = slice_bool def __repr__(self): if self.name is not None: return self.name + ' index: ' + str(self.index_in_array) 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) self.low_value, self.high_value = self.axis.min(), self.axis.max() # self.update_value() def _update_slice(self, value): if value is True: 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, 'index_in_array': self.index_in_array, 'slice_bool': self.slice_bool } return adict def update_value(self): self.value = self.axis[self.index] def value2index(self, value): """Return the closest index to the given value if between the limits, otherwise it will return either the upper or lower limits Parameters ---------- value : float Returns ------- int """ if value is None: return None else: index = int(round((value - self.offset) / \ self.scale)) if self.size > index >= 0: return index elif index < 0: messages.warning("The given value is below the axis limits") return 0 else: messages.warning("The given value is above the axis limits") return int(self.size - 1) def index2value(self, index): 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 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 traits_view = \ tui.View( tui.Group( tui.Group( tui.Item(name = 'name'), tui.Item(name = 'size', style = 'readonly'), tui.Item(name = 'index_in_array', style = 'readonly'), tui.Item(name = 'index'), tui.Item(name = 'value', style = 'readonly'), tui.Item(name = 'units'), tui.Item(name = 'slice_bool', label = 'slice'), show_border = True,), tui.Group( tui.Item(name = 'scale'), tui.Item(name = 'offset'), label = 'Calibration', show_border = True,), label = "Data Axis properties", show_border = True,), )
class DeviceAnalogInState(traits.HasTraits): """encapsulate all (relevant) analog input state on the device Making these variables a member of their own HasTraits class means that updates to the device can be treated in an atomic way. """ # Analog input state AIN0_enabled = traits.Bool(False) AIN0_name = traits.String("AIN0") AIN1_enabled = traits.Bool(False) AIN1_name = traits.String("AIN1") AIN2_enabled = traits.Bool(True) AIN2_name = traits.String("AIN2") AIN3_enabled = traits.Bool(False) AIN3_name = traits.String("AIN3") trigger_device = traits.Instance('DeviceModel',transient=True) adc_prescaler = traits.Trait(128.0,{ 128.0:0x07,64.0: 0x06, # According to Atmel's at90usb1287 manual, faster than this is # too fast to get good measurements with 8MHz crystal. ## '32': 0x05,'16': 0x04,'8': 0x03, ## '4': 0x02,'2': 0x00, # also 0x01 }) downsample_bits = traits.Range(low=0,high=2**5-1,value=0) AIN_running = traits.Bool(False) sample_rate_total = traits.Property(label='Sample rate (Hz), all channels', depends_on=['adc_prescaler', 'trigger_device', 'downsample_bits']) sample_rate_chan = traits.Property(label='each channel', depends_on=['sample_rate_total', 'AIN0_enabled','AIN1_enabled', 'AIN2_enabled','AIN3_enabled',]) # but useful when plotting/saving data Vcc = traits.Float(3.3) traits_view = View(Group(Group(Item('AIN_running'), Item( 'Vcc', tooltip=('This does not set Vcc on the AT90USBKEY. Use to record the ' 'value of Vcc. (default = 3.3V)')), orientation='horizontal'), Group(Item('AIN0_enabled',padding=0), Item('AIN0_name',padding=0), Item('AIN1_enabled',padding=0), Item('AIN1_name',padding=0), padding=0, orientation='horizontal'), Group(Item('AIN2_enabled',padding=0), Item('AIN2_name',padding=0), Item('AIN3_enabled',padding=0), Item('AIN3_name',padding=0), padding=0, orientation='horizontal'), Group(Item('adc_prescaler'), Item('downsample_bits'), orientation='horizontal'), Group(Item('sample_rate_total', #show_label=False, style='readonly', ), Item('sample_rate_chan', #show_label=False, style='readonly', ), orientation='horizontal'), )) @traits.cached_property def _get_sample_rate_total(self): if self.trigger_device is not None: input_frequency = self.trigger_device.FOSC/self.adc_prescaler else: input_frequency = 100*1e3 # fake value # from USBKEY datasheet: if input_frequency < 50*1e3: warnings.warn('ADC sample frequency is too slow to get good sampling') if input_frequency > 200*1e3: warnings.warn('ADC sample frequency is too fast to get good sampling') #print 'input_frequency %.1f (kHz)'%(input_frequency/1000.0,) clock_cycles_per_sample = 13.0 clock_adc = input_frequency/clock_cycles_per_sample downsample_factor = self.downsample_bits+1 downsampled_clock_adc = clock_adc/downsample_factor return downsampled_clock_adc @traits.cached_property def _get_sample_rate_chan(self): n_chan = sum(map(int,[self.AIN0_enabled,self.AIN1_enabled, self.AIN2_enabled,self.AIN3_enabled])) if n_chan == 0: return 0.0 rate = self.sample_rate_total/float(n_chan) return rate
class QuadMeshDecimationInputSpec(CommandLineInputSpec): inputSurface = traits.Str(argstr="--inputSurface %s") numberOfElements = traits.Int(argstr="--numberOfElements %d") topologyChange = traits.Bool(argstr="--topologyChange ") outputSurface = traits.Str(argstr="--outputSurface %s")
class QuadMeshSmoothingInputSpec(CommandLineInputSpec): inputSurface = traits.Str( argstr = "----inputSurface %s") numberOfIterations = traits.Int( argstr = "--numberOfIterations %d") relaxationFactor = traits.Float( argstr = "--relaxationFactor %f") delaunayConforming = traits.Bool( argstr = "----delaunayConforming ") outputSurface = traits.Str( argstr = "----outputSurface %s")
class LiveTimestampModeler(traits.HasTraits): _trigger_device = traits.Instance(ttrigger.DeviceModel) sync_interval = traits.Float(2.0) has_ever_synchronized = traits.Bool(False, transient=True) frame_offset_changed = traits.Event timestamps_framestamps = traits.Array(shape=(None, 2), dtype=np.float) timestamp_data = traits.Any() block_activity = traits.Bool(False, transient=True) synchronize = traits.Button(label='Synchronize') synchronizing_info = traits.Any(None) gain_offset_residuals = traits.Property( depends_on=['timestamps_framestamps']) residual_error = traits.Property(depends_on='gain_offset_residuals') gain = traits.Property(depends_on='gain_offset_residuals') offset = traits.Property(depends_on='gain_offset_residuals') frame_offsets = traits.Dict() last_frame = traits.Dict() view_time_model_plot = traits.Button traits_view = View( Group( Item( name='gain', style='readonly', editor=TextEditor(evaluate=float, format_func=myformat), ), Item( name='offset', style='readonly', editor=TextEditor(evaluate=float, format_func=myformat2), ), Item( name='residual_error', style='readonly', editor=TextEditor(evaluate=float, format_func=myformat), ), Item('synchronize', show_label=False), Item('view_time_model_plot', show_label=False), ), title='Timestamp modeler', ) def _block_activity_changed(self): if self.block_activity: print('Do not change frame rate or AIN parameters. ' 'Automatic prevention of doing ' 'so is not currently implemented.') else: print('You may change frame rate again') def _view_time_model_plot_fired(self): raise NotImplementedError('') def _synchronize_fired(self): if self.block_activity: print('Not synchronizing because activity is blocked. ' '(Perhaps because you are saving data now.') return orig_fps = self._trigger_device.frames_per_second_actual self._trigger_device.set_frames_per_second_approximate(0.0) self._trigger_device.reset_framecount_A = True # trigger reset event self.synchronizing_info = (time.time() + self.sync_interval + 0.1, orig_fps) @traits.cached_property def _get_gain(self): result = self.gain_offset_residuals if result is None: # not enought data return None gain, offset, residuals = result return gain @traits.cached_property def _get_offset(self): result = self.gain_offset_residuals if result is None: # not enought data return None gain, offset, residuals = result return offset @traits.cached_property def _get_residual_error(self): result = self.gain_offset_residuals if result is None: # not enought data return None gain, offset, residuals = result if residuals is None or len(residuals) == 0: # not enought data return None assert len(residuals) == 1 return residuals[0] @traits.cached_property def _get_gain_offset_residuals(self): if self.timestamps_framestamps is None: return None timestamps = self.timestamps_framestamps[:, 0] framestamps = self.timestamps_framestamps[:, 1] if len(timestamps) < 2: return None # like model_remote_to_local in flydra.analysis remote_timestamps = framestamps local_timestamps = timestamps a1 = remote_timestamps[:, np.newaxis] a2 = np.ones((len(remote_timestamps), 1)) A = np.hstack((a1, a2)) b = local_timestamps[:, np.newaxis] x, resids, rank, s = np.linalg.lstsq(A, b) gain = x[0, 0] offset = x[1, 0] return gain, offset, resids def set_trigger_device(self, device): self._trigger_device = device self._trigger_device.on_trait_event( self._on_trigger_device_reset_AIN_overflow_fired, name='reset_AIN_overflow') def _on_trigger_device_reset_AIN_overflow_fired(self): self.ain_overflowed = 0 def _get_now_framestamp(self, max_error_seconds=0.003, full_output=False): count = 0 while count <= 10: now1 = time.time() try: results = self._trigger_device.get_framestamp( full_output=full_output) except ttrigger.NoDataError: raise ImpreciseMeasurementError('no data available') now2 = time.time() if full_output: framestamp, framecount, tcnt = results else: framestamp = results count += 1 measurement_error = abs(now2 - now1) if framestamp % 1.0 < 0.1: warnings.warn('workaround of TCNT race condition on MCU...') continue if measurement_error < max_error_seconds: break time.sleep(0.01) # wait 10 msec before trying again if not measurement_error < max_error_seconds: raise ImpreciseMeasurementError( 'could not obtain low error measurement') if framestamp % 1.0 < 0.1: raise ImpreciseMeasurementError('workaround MCU bug') now = (now1 + now2) * 0.5 if full_output: results = now, framestamp, now1, now2, framecount, tcnt else: results = now, framestamp return results def clear_samples(self, call_update=True): self.timestamps_framestamps = np.empty((0, 2)) if call_update: self.update() def update(self, return_last_measurement_info=False): """call this function fairly often to pump information from the USB device""" if self.synchronizing_info is not None: done_time, orig_fps = self.synchronizing_info # suspended trigger pulses to re-synchronize if time.time() >= done_time: # we've waited the sync duration, restart self._trigger_device.set_frames_per_second_approximate( orig_fps) self.clear_samples(call_update=False) # avoid recursion self.synchronizing_info = None self.has_ever_synchronized = True results = self._get_now_framestamp( full_output=return_last_measurement_info) now, framestamp = results[:2] if return_last_measurement_info: start_timestamp, stop_timestamp, framecount, tcnt = results[2:] self.timestamps_framestamps = np.vstack( (self.timestamps_framestamps, [now, framestamp])) # If more than 100 samples, if len(self.timestamps_framestamps) > 100: # keep only the most recent 50. self.timestamps_framestamps = self.timestamps_framestamps[-50:] if return_last_measurement_info: return start_timestamp, stop_timestamp, framecount, tcnt def get_frame_offset(self, id_string): return self.frame_offsets[id_string] def register_frame(self, id_string, framenumber, frame_timestamp, full_output=False): """note that a frame happened and return start-of-frame time""" # This may get called from another thread (e.g. the realtime # image processing thread). # An important note about locking and thread safety: This code # relies on the Python interpreter to lock data structures # across threads. To do this internally, a lock would be made # for each variable in this instance and acquired before each # access. Because the data structures are simple Python # objects, I believe the operations are atomic and thus this # function is OK. # Don't trust camera drivers with giving a good timestamp. We # only use this to reset our framenumber-to-time data # gathering, anyway. frame_timestamp = time.time() if frame_timestamp is not None: last_frame_timestamp = self.last_frame.get(id_string, -np.inf) this_interval = frame_timestamp - last_frame_timestamp did_frame_offset_change = False if this_interval > self.sync_interval: if self.block_activity: print( 'changing frame offset is disallowed, but you attempted to do it. ignoring.' ) else: # re-synchronize camera # XXX need to figure out where frame offset of two comes from: self.frame_offsets[id_string] = framenumber - 2 did_frame_offset_change = True self.last_frame[id_string] = frame_timestamp if did_frame_offset_change: self.frame_offset_changed = True # fire any listeners result = self.gain_offset_residuals if result is None: # not enough data if full_output: results = None, None, did_frame_offset_change else: results = None return results gain, offset, residuals = result corrected_framenumber = framenumber - self.frame_offsets[id_string] trigger_timestamp = corrected_framenumber * gain + offset if full_output: results = trigger_timestamp, corrected_framenumber, did_frame_offset_change else: results = trigger_timestamp return results
class CameraUI(traits.HasTraits): """Camera settings defines basic camera settings """ camera_control = traits.Instance(Camera, transient = True) cameras = traits.List([_NO_CAMERAS],transient = True) camera = traits.Any(value = _NO_CAMERAS, desc = 'camera serial number', editor = ui.EnumEditor(name = 'cameras')) search = traits.Button(desc = 'camera search action') _is_initialized= traits.Bool(False, transient = True) play = traits.Button(desc = 'display preview action') stop = traits.Button(desc = 'close preview action') on_off = traits.Button('On/Off', desc = 'initiate/Uninitiate camera action') gain = create_range_feature('gain',desc = 'camera gain',transient = True) shutter = create_range_feature('shutter', desc = 'camera exposure time',transient = True) format = create_mapped_feature('format',_FORMAT, desc = 'image format',transient = True) roi = traits.Instance(ROI,transient = True) im_shape = traits.Property(depends_on = 'format.value,roi.values') im_dtype = traits.Property(depends_on = 'format.value') capture = traits.Button() save_button = traits.Button('Save as...') message = traits.Str(transient = True) view = ui.View(ui.Group(ui.HGroup(ui.Item('camera', springy = True), ui.Item('search', show_label = False, springy = True), ui.Item('on_off', show_label = False, springy = True), ui.Item('play', show_label = False, enabled_when = 'is_initialized', springy = True), ui.Item('stop', show_label = False, enabled_when = 'is_initialized', springy = True), ), ui.Group( ui.Item('gain', style = 'custom'), ui.Item('shutter', style = 'custom'), ui.Item('format', style = 'custom'), ui.Item('roi', style = 'custom'), ui.HGroup(ui.Item('capture',show_label = False), ui.Item('save_button',show_label = False)), enabled_when = 'is_initialized', ), ), resizable = True, statusbar = [ ui.StatusItem( name = 'message')], buttons = ['OK']) #default initialization def __init__(self, **kw): super(CameraUI, self).__init__(**kw) self.search_cameras() def _camera_control_default(self): return Camera() def _roi_default(self): return ROI() #@display_cls_error def _get_im_shape(self): top, left, width, height = self.roi.values shape = (height, width) try: colors = _COLORS[self.format.value] if colors > 1: shape += (colors,) except KeyError: raise NotImplementedError('Unsupported format') return shape #@display_cls_error def _get_im_dtype(self): try: return _DTYPE[self.format.value] except KeyError: raise NotImplementedError('Unsupported format') def _search_fired(self): self.search_cameras() #@display_cls_error def search_cameras(self): """ Finds cameras if any and selects first from list """ try: cameras = get_number_cameras() except Exception as e: cameras = [] raise e finally: if len(cameras) == 0: cameras = [_NO_CAMERAS] self.cameras = cameras self.camera = cameras[0] #@display_cls_error def _camera_changed(self): if self._is_initialized: self._is_initialized= False self.camera_control.close() self.message = 'Camera uninitialized' #@display_cls_error def init_camera(self): self._is_initialized= False if self.camera != _NO_CAMERAS: self.camera_control.init(self.camera) self.init_features() self._is_initialized= True self.message = 'Camera initialized' #@display_cls_error def _on_off_fired(self): if self._is_initialized: self._is_initialized= False self.camera_control.close() self.message = 'Camera uninitialized' else: self.init_camera() #@display_cls_error def init_features(self): """ Initializes all features to values given by the camera """ features = self.camera_control.get_camera_features() self._init_single_valued_features(features) self._init_roi(features) #@display_cls_error def _init_single_valued_features(self, features): """ Initializes all single valued features to camera values """ for name, id in list(_SINGLE_VALUED_FEATURES.items()): feature = getattr(self, name) feature.low, feature.high = features[id]['params'][0] feature.value = self.camera_control.get_feature(id)[0] #@display_cls_error def _init_roi(self, features): for i,name in enumerate(('top','left','width','height')): feature = getattr(self.roi, name) low, high = features[FEATURE_ROI]['params'][i] value = self.camera_control.get_feature(FEATURE_ROI)[i] try: feature.value = value finally: feature.low, feature.high = low, high @traits.on_trait_change('format.value') def _on_format_change(self, object, name, value): if self._is_initialized: self.camera_control.set_preview_state(STOP_PREVIEW) self.camera_control.set_stream_state(STOP_STREAM) self.set_feature(FEATURE_PIXEL_FORMAT, [value]) @traits.on_trait_change('gain.value,shutter.value') def _single_valued_feature_changed(self, object, name, value): if self._is_initialized: self.set_feature(object.id, [value]) #@display_cls_error def set_feature(self, id, values, flags = 2): self.camera_control.set_feature(id, values, flags = flags) @traits.on_trait_change('roi.values') def a_roi_feature_changed(self, object, name, value): if self._is_initialized: self.set_feature(FEATURE_ROI, value) try: self._is_initialized= False self.init_features() finally: self._is_initialized= True #@display_cls_error def _play_fired(self): self.camera_control.set_preview_state(STOP_PREVIEW) self.camera_control.set_stream_state(STOP_STREAM) self.camera_control.set_stream_state(START_STREAM) self.camera_control.set_preview_state(START_PREVIEW) #@display_cls_error def _stop_fired(self): self.camera_control.set_preview_state(STOP_PREVIEW) self.camera_control.set_stream_state(STOP_STREAM) self.error = '' #@display_cls_error def _format_changed(self, value): self.camera_control.set_preview_state(STOP_PREVIEW) self.camera_control.set_stream_state(STOP_STREAM) self.camera_control.set_feature(FEATURE_PIXEL_FORMAT, [value],2) #@display_cls_error def _capture_fired(self): self.camera_control.set_stream_state(STOP_STREAM) self.camera_control.set_stream_state(START_STREAM) im = self.capture_image() plt.imshow(im) plt.show() def capture_image(self): im = numpy.empty(shape = self.im_shape, dtype = self.im_dtype) self.camera_control.get_next_frame(im) return im.newbyteorder('>') def save_image(self, fname): """Captures image and saves to format guessed from filename extension""" im = self.capture_image() base, ext = os.path.splitext(fname) if ext == '.npy': numpy.save(fname, im) else: im = toimage(im) im.save(fname) def _save_button_fired(self): f = pyface.FileDialog(action = 'save as') #wildcard = self.filter) if f.open() == pyface.OK: self.save_image(f.path) def capture_HDR(self): pass def __del__(self): try: self.camera_control.set_preview_state(STOP_PREVIEW) self.camera_control.set_stream_state(STOP_STREAM) except: pass
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(FitVariable) 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") drawRequestButton = traits.Button("Draw Fit") autoFitBool = traits.Bool( False, desc= "Automatically perform this Fit with current settings whenever a new image is loaded" ) autoGuessBool = 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)" ) autoDrawBool = traits.Bool( False, desc= "Once a fit is complete update the drawing of the fit or draw the fit for the first time" ) logBool = traits.Bool( False, desc="Log the calculated and fitted values with a timestamp") logFile = traits.File(desc="file path of logFile") 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( False) #true when current data displayed has been fitted startX = traits.Int startY = traits.Int endX = traits.Int endY = traits.Int fittingStatus = traits.Str() fitThread = None physics = traits.Instance(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" fitSubSpaceGroup = traitsui.VGroup( traitsui.Item("fitSubSpace", label="Fit Sub Space"), traitsui.VGroup(traitsui.HGroup(traitsui.Item("startX"), traitsui.Item("startY")), traitsui.HGroup(traitsui.Item("endX"), traitsui.Item("endY")), 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.VGroup( traitsui.HGroup(traitsui.Item("autoFitBool"), traitsui.Item("performFitButton")), traitsui.HGroup(traitsui.Item("autoGuessBool"), traitsui.Item("getInitialParametersButton")), traitsui.HGroup(traitsui.Item("autoDrawBool"), traitsui.Item("drawRequestButton"))) logGroup = traitsui.HGroup(traitsui.Item("logBool"), traitsui.Item("logFile", visible_when="logBool"), label="Logging", show_border=True) actionsGroup = traitsui.VGroup(traitsui.Item("fittingStatus", style="readonly"), logGroup, buttons, label="Fit Actions", show_border=True) traits_view = traitsui.View( traitsui.VGroup(generalGroup, variablesGroup, derivedGroup, actionsGroup)) def __init__(self, **traitsDict): super(Fit, self).__init__(**traitsDict) self.startX = 0 self.startY = 0 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 _getCalculatedValues(self): """returns ordered list of initial values from variables List """ return [_.calculatedValue for _ in self.variablesList] def _log_fit(self): if self.logFile == "": logger.warning("no log file defined. Will not log") return 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"] columnNames = times + info + variables + calculated with open(self.logFile, 'a+') as logFile: writer = csv.writer(logFile) writer.writerow(columnNames) #column names already exist so... 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] data = times + info + variables + calculated with open(self.logFile, 'a+') as logFile: writer = csv.writer(logFile) writer.writerow(data) 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.debug("xs array sliced length %s " % (xs.shape)) logger.debug("ys array sliced length %s " % (ys.shape)) zs = self.zs[self.startY:self.endY, self.startX:self.endX] print zs print zs.shape logger.debug("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.debug("Dummy function should not be called directly") return def fitFunc(self, data, *p): """Function that we are trying to fit to. """ logger.error("Dummy function should not be called directly") return def _setCalculatedValues(self, calculated): """updates calculated values with calculated argument """ c = 0 for variable in self.variablesList: variable.calculatedValue = calculated[c] c += 1 def _setCalculatedValuesErrors(self, covarianceMatrix): """given the covariance matrix returned by scipy optimize fit convert this into stdeviation errors for parameters list and updated the stdevError attribute of variables""" logger.debug("covariance matrix -> %s " % covarianceMatrix) parameterErrors = scipy.sqrt(scipy.diag(covarianceMatrix)) logger.debug("parameterErrors -> %s " % parameterErrors) c = 0 for variable in self.variablesList: variable.stdevError = parameterErrors[c] c += 1 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 cannot kick off a new fit until it has finished!" ) return else: self.fitThread = FitThread() self.fitThread.fitReference = self 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 ([], []) p0 = self._getInitialValues() 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() positions = [scipy.tile(xs, len(ys)), scipy.repeat(ys, len(xs)) ] #for creating data necessary for gauss2D function params2D, cov2D = scipy.optimize.curve_fit(self.fitFunc, positions, scipy.ravel(zs), p0=p0) chi2 = scipy.sum( (scipy.ravel(zs) - self.fitFunc(positions, *params2D))**2 / self.fitFunc(positions, *params2D)) logger.debug("TEMPORARY ::: CHI^2 = %s " % chi2) else: #fit the whole array of data (slower) positions = [ scipy.tile(self.xs, len(self.ys)), scipy.repeat(self.ys, len(self.xs)) ] #for creating data necessary for gauss2D function #note that it is necessary to ravel zs as curve_fit expects a flattened array params2D, cov2D = scipy.optimize.curve_fit(self.fitFunc, positions, scipy.ravel(self.zs), p0=p0) return params2D, cov2D 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 _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)
inputEPCAModelMat = File( exists = "True",argstr = "--inputEPCAModelMat %s") inputEPCAModelTxt = File( exists = "True",argstr = "--inputEPCAModelTxt %s") inputVolume = File( exists = "True",argstr = "--inputVolume %s") outputVolume = traits.Either(traits.Bool, File, argstr = "--outputVolume %s") outputResampledVolume = traits.Either(traits.Bool, File, argstr = "--outputResampledVolume %s") outputTransform = traits.Either(traits.Bool, File, argstr = "--outputTransform %s") outputLandmarksInInputSpace = traits.Either(traits.Bool, File, argstr = "--outputLandmarksInInputSpace %s") outputLandmarksInACPCAlignedSpace = traits.Either(traits.Bool, File, argstr = "--outputLandmarksInACPCAlignedSpace %s") inputLandmarksPaired = File( exists = "True",argstr = "--inputLandmarksPaired %s") outputLandmarksPaired = traits.Either(traits.Bool, File, argstr = "--outputLandmarksPaired %s") outputMRML = traits.Either(traits.Bool, File, argstr = "--outputMRML %s") outputVerificationScript = traits.Either(traits.Bool, File, argstr = "--outputVerificationScript %s") mspQualityLevel = traits.Int( argstr = "--mspQualityLevel %d") otsuPercentileThreshold = traits.Float( argstr = "--otsuPercentileThreshold %f") acLowerBound = traits.Float( argstr = "--acLowerBound %f") cutOutHeadInOutputVolume = traits.Bool( argstr = "--cutOutHeadInOutputVolume ") outputUntransformedClippedVolume = traits.Either(traits.Bool, File, argstr = "--outputUntransformedClippedVolume %s") rescaleIntensities = traits.Bool( argstr = "--rescaleIntensities ") trimRescaledIntensities = traits.Float( argstr = "--trimRescaledIntensities %f") rescaleIntensitiesOutputRange = traits.List("traits.Int", sep = ",",argstr = "--rescaleIntensitiesOutputRange %d") backgroundFillValueString = traits.Str( argstr = "--BackgroundFillValue %s") interpolationMode = traits.Enum("NearestNeighbor","Linear","ResampleInPlace","BSpline","WindowedSinc", argstr = "--interpolationMode %s") forceACPoint = traits.List("traits.Float", sep = ",",argstr = "--forceACPoint %f") forcePCPoint = traits.List("traits.Float", sep = ",",argstr = "--forcePCPoint %f") forceVN4Point = traits.List("traits.Float", sep = ",",argstr = "--forceVN4Point %f") forceRPPoint = traits.List("traits.Float", sep = ",",argstr = "--forceRPPoint %f") inputLandmarksEMSP = File( exists = "True",argstr = "--inputLandmarksEMSP %s") forceHoughEyeDetectorReportFailure = traits.Bool( argstr = "--forceHoughEyeDetectorReportFailure ") radiusMPJ = traits.Float( argstr = "--rmpj %f") radiusAC = traits.Float( argstr = "--rac %f") radiusPC = traits.Float( argstr = "--rpc %f")
class EgertonPanel(t.HasTraits): define_background_window = t.Bool(False) bg_window_size_variation = t.Button() background_substracted_spectrum_name = t.Str('signal') extract_background = t.Button() define_signal_window = t.Bool(False) signal_window_size_variation = t.Button() signal_name = t.Str('signal') extract_signal = t.Button() view = tu.View(tu.Group( tu.Group('define_background_window', tu.Item('bg_window_size_variation', label = 'window size effect', show_label=False), tu.Item('background_substracted_spectrum_name'), tu.Item('extract_background', show_label=False), ), tu.Group('define_signal_window', tu.Item('signal_window_size_variation', label = 'window size effect', show_label=False), tu.Item('signal_name', show_label=True), tu.Item('extract_signal', show_label=False)),)) def __init__(self, SI): self.SI = SI # Background self.bg_span_selector = None self.pl = components.PowerLaw() self.bg_line = None self.bg_cube = None # Signal self.signal_span_selector = None self.signal_line = None self.signal_map = None self.map_ax = None def store_current_spectrum_bg_parameters(self, *args, **kwards): if self.define_background_window is False or \ self.bg_span_selector.range is None: return pars = utils.two_area_powerlaw_estimation( self.SI, *self.bg_span_selector.range,only_current_spectrum = True) self.pl.r.value = pars['r'] self.pl.A.value = pars['A'] if self.define_signal_window is True and \ self.signal_span_selector.range is not None: self.plot_signal_map() def _define_background_window_changed(self, old, new): if new is True: self.bg_span_selector = \ drawing.widgets.ModifiableSpanSelector( self.SI.hse.spectrum_plot.left_ax, onselect = self.store_current_spectrum_bg_parameters, onmove_callback = self.plot_bg_removed_spectrum) elif self.bg_span_selector is not None: if self.bg_line is not None: self.bg_span_selector.ax.lines.remove(self.bg_line) self.bg_line = None if self.signal_line is not None: self.bg_span_selector.ax.lines.remove(self.signal_line) self.signal_line = None self.bg_span_selector.turn_off() self.bg_span_selector = None def _bg_window_size_variation_fired(self): if self.define_background_window is False: return left = self.bg_span_selector.rect.get_x() right = left + self.bg_span_selector.rect.get_width() energy_window_dependency(self.SI, left, right, min_width = 10) def _extract_background_fired(self): if self.pl is None: return signal = self.SI() - self.pl.function(self.SI.energy_axis) i = self.SI.energy2index(self.bg_span_selector.range[1]) signal[:i] = 0. s = Spectrum({'calibration' : {'data_cube' : signal}}) s.get_calibration_from(self.SI) interactive_ns[self.background_substracted_spectrum_name] = s def _define_signal_window_changed(self, old, new): if new is True: self.signal_span_selector = \ drawing.widgets.ModifiableSpanSelector( self.SI.hse.spectrum_plot.left_ax, onselect = self.store_current_spectrum_bg_parameters, onmove_callback = self.plot_signal_map) self.signal_span_selector.rect.set_color('blue') elif self.signal_span_selector is not None: self.signal_span_selector.turn_off() self.signal_span_selector = None def plot_bg_removed_spectrum(self, *args, **kwards): if self.bg_span_selector.range is None: return self.store_current_spectrum_bg_parameters() ileft = self.SI.energy2index(self.bg_span_selector.range[0]) iright = self.SI.energy2index(self.bg_span_selector.range[1]) ea = self.SI.energy_axis[ileft:] if self.bg_line is not None: self.bg_span_selector.ax.lines.remove(self.bg_line) self.bg_span_selector.ax.lines.remove(self.signal_line) self.bg_line, = self.SI.hse.spectrum_plot.left_ax.plot( ea, self.pl.function(ea), color = 'black') self.signal_line, = self.SI.hse.spectrum_plot.left_ax.plot( self.SI.energy_axis[iright:], self.SI()[iright:] - self.pl.function(self.SI.energy_axis[iright:]), color = 'black') self.SI.hse.spectrum_plot.left_ax.figure.canvas.draw() def plot_signal_map(self, *args, **kwargs): if self.define_signal_window is True and \ self.signal_span_selector.range is not None: ileft = self.SI.energy2index(self.signal_span_selector.range[0]) iright = self.SI.energy2index(self.signal_span_selector.range[1]) signal_sp = self.SI.data_cube[ileft:iright,...].squeeze().copy() if self.define_background_window is True: pars = utils.two_area_powerlaw_estimation( self.SI, *self.bg_span_selector.range, only_current_spectrum = False) x = self.SI.energy_axis[ileft:iright, np.newaxis, np.newaxis] A = pars['A'][np.newaxis,...] r = pars['r'][np.newaxis,...] self.bg_sp = (A*x**(-r)).squeeze() signal_sp -= self.bg_sp self.signal_map = signal_sp.sum(0) if self.map_ax is None: f = plt.figure() self.map_ax = f.add_subplot(111) if len(self.signal_map.squeeze().shape) == 2: self.map = self.map_ax.imshow(self.signal_map.T, interpolation = 'nearest') else: self.map, = self.map_ax.plot(self.signal_map.squeeze()) if len(self.signal_map.squeeze().shape) == 2: self.map.set_data(self.signal_map.T) self.map.autoscale() else: self.map.set_ydata(self.signal_map.squeeze()) self.map_ax.figure.canvas.draw() def _extract_signal_fired(self): if self.signal_map is None: return if len(self.signal_map.squeeze().shape) == 2: s = Image( {'calibration' : {'data_cube' : self.signal_map.squeeze()}}) s.xscale = self.SI.xscale s.yscale = self.SI.yscale s.xunits = self.SI.xunits s.yunits = self.SI.yunits interactive_ns[self.signal_name] = s else: s = Spectrum( {'calibration' : {'data_cube' : self.signal_map.squeeze()}}) s.energyscale = self.SI.xscale s.energyunits = self.SI.xunits interactive_ns[self.signal_name] = s