Exemplo n.º 1
0
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")
Exemplo n.º 2
0
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")
Exemplo n.º 3
0
class runBRAINSCutInputSpec(CommandLineInputSpec):
    subject = traits.Str(argstr='%s',
                         desc="subject",
                         exists=True,
                         mandatory=True,
                         position=0)
    imageMap = traits.List(argstr='%s',
                           type="traits.Str",
                           sep=":",
                           desc="imageMap",
                           exists=True,
                           mandatory=True,
                           position=1)
    atlasMap = traits.List(argstr='%s',
                           type="traits.Str",
                           sep=":",
                           desc="atlasMap",
                           exists=True,
                           mandatory=True,
                           position=2)
    regions = traits.List(argstr='%s',
                          type="traits.Str",
                          sep=",",
                          desc="regions",
                          exists=True,
                          mandatory=True,
                          position=3)
    probabilityMap = traits.List(argstr='%s',
                                 type="traits.Str",
                                 sep=":",
                                 desc="probabilityMap",
                                 exists=True,
                                 mandatory=True,
                                 position=4)
    xmlFile = traits.Str(argstr='%s',
                         desc="xmlFile",
                         exists=True,
                         mandatory=True,
                         position=5)
    outputDir = traits.Directory(argstr='%s',
                                 desc="outputDir",
                                 exists=True,
                                 mandatory=True,
                                 position=6)
    outputList = traits.List(argstr='%s',
                             type="traits.File",
                             sep=",",
                             desc="OutputAverageOfPassiveImages",
                             exists=True,
                             mandatory=True,
                             position=7)
class itkBinaryImageMorphologyInputSpec(CommandLineInputSpec):
    inFilename = File(argstr='%s',
                      desc="inFilename",
                      exists=True,
                      mandatory=True,
                      position=0)
    fileMode = traits.Str(argstr='%s',
                          desc="fileMode",
                          exists=True,
                          mandatory=True,
                          position=1)
    var1 = traits.String(argstr='%s',
                         desc="var1",
                         exists=True,
                         mandatory=True,
                         position=2)
    var2 = traits.String(argstr='%s',
                         desc="var2",
                         exists=True,
                         mandatory=True,
                         position=3)
    radius = traits.List(argstr='%s',
                         type="traits.Float",
                         sep=",",
                         desc="radius",
                         exists=True,
                         mandatory=True,
                         position=4)
    outFilename = traits.Str(argstr='%s',
                             desc="outFilename",
                             exists=True,
                             mandatory=True,
                             position=5)
Exemplo n.º 5
0
class ScalarTalairachMeasuresInputSpec(CommandLineInputSpec):
    ScalarFileList = traits.List(argstr='%s',
                                 type="traits.File",
                                 sep=":",
                                 desc="ScalarFileList",
                                 exists=True,
                                 mandatory=True,
                                 position=0)
    BrainMaskFile = traits.List(argstr='%s',
                                type="traits.File",
                                sep=",",
                                desc="PassiveImagesToClip",
                                exists=True,
                                mandatory=True,
                                position=1)
    ClassImageFile = File(argstr='%s',
                          desc="ClassImageFile",
                          exists=True,
                          mandatory=True,
                          position=2)
    TalairachBounds = File(argstr='%s',
                           desc="TalairachBounds",
                           exists=True,
                           mandatory=True,
                           position=3)
    TalairachDir = traits.Directory(argstr='%s',
                                    desc="TalairachDir",
                                    exists=True,
                                    mandatory=True,
                                    position=4)
    PatientId = traits.Str(argstr='%s',
                           desc="PatientId",
                           exists=True,
                           mandatory=True,
                           position=5)
    ScanId = traits.Str(argstr='%s',
                        desc="ScanId",
                        exists=True,
                        mandatory=True,
                        position=6)
    ResultDir = traits.Directory(argstr='%s',
                                 desc="ResultDir",
                                 exists=True,
                                 mandatory=True,
                                 position=7)
Exemplo n.º 6
0
class Platform(traits.HasTraits):
    ID = traits.Int
    berths = traits.List(traits.Instance(Berth))
    track_segment = traits.Instance(TrackSegment)

    def __init__(self, ID, track_segment):
        traits.HasTraits.__init__(self)
        self.ID = ID
        self.berths = []
        self.track_segment = track_segment
Exemplo n.º 7
0
class BRAINSClassPlugsInputSpec(CommandLineInputSpec):
    t1Volume = File(exists="True", argstr="--t1Volume %s")
    t2Volume = File(exists="True", argstr="--t2Volume %s")
    pdVolume = File(exists="True", argstr="--pdVolume %s")
    searchVolume = File(exists="True", argstr="--searchVolume %s")
    gmPlugs = traits.Either(traits.Bool, File, argstr="--gmPlugs %s")
    wmPlugs = traits.Either(traits.Bool, File, argstr="--wmPlugs %s")
    csfPlugs = traits.Either(traits.Bool, File, argstr="--csfPlugs %s")
    plugClassNames = traits.List("traits.Str",
                                 sep=",",
                                 argstr="--plugClassNames %s")
    t1ClassMeans = traits.List("traits.Float",
                               sep=",",
                               argstr="--t1ClassMeans %f")
    t2ClassMeans = traits.List("traits.Float",
                               sep=",",
                               argstr="--t2ClassMeans %f")
    pdClassMeans = traits.List("traits.Float",
                               sep=",",
                               argstr="--pdClassMeans %f")
    randomSeed = traits.Int(argstr="--randomSeed %d")
    numberOfPlugs = traits.Int(argstr="--numberOfPlugs %d")
    coverage = traits.Float(argstr="--coverage %f")
    permissiveness = traits.Float(argstr="--permissiveness %f")
    meanOutlier = traits.Float(argstr="--meanOutlier %f")
    varOutlier = traits.Float(argstr="--varOutlier %f")
    plugSize = traits.Float(argstr="--plugSize %f")
    partitions = traits.List("traits.Int", sep=",", argstr="--partitions %d")
    numberOfClassPlugs = traits.List("traits.Int",
                                     sep=",",
                                     argstr="--numberOfClassPlugs %d")
    bloodMode = traits.Enum("Manual", "Top", "Bottom", argstr="--bloodMode %s")
    bloodImage = traits.Enum("T1", "T2", "PD", argstr="--bloodImage %s")
    vbPlugs = File(exists="True", argstr="--vbPlugs %s")
Exemplo n.º 8
0
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")
Exemplo n.º 9
0
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
Exemplo n.º 10
0
    class figure(TConfig):
        figsize = T.List(T.Float, [8, 6], maxlen=2, minlen=2)
        dpi = T.Float(80)
        facecolor = T.Trait('0.75', mplT.ColorHandler())
        edgecolor = T.Trait('white', mplT.ColorHandler())

        class subplot(TConfig):
            """The figure subplot parameters.  All dimensions are fraction
            of the figure width or height"""
            left = T.Float(0.125)
            right = T.Float(0.9)
            bottom = T.Float(0.1)
            top = T.Float(0.9)
            wspace = T.Float(0.2)
            hspace = T.Float(0.2)
Exemplo n.º 11
0
class Platform(traits.HasTraits):
    berths = traits.List(traits.Instance(Berth))
    track_segment = traits.Instance('pyprt.sim.layout.TrackSegment')
    berth_length = traits.CFloat
    unloading = traits.CBool
    loading = traits.CBool

    def __init__(self, berths, track_segment, berth_length, unloading, loading):
        traits.HasTraits.__init__(self)
        self.berths = berths
        self.track_segment = track_segment
        self.berth_length = berth_length
        self.unloading = unloading
        self.loading = loading

    def advance(self, prev_platform):
        """Vehicles 'bubble' forward one slot. There is no 'accordian' effect
        -- all vehicles at the platform move synchronously. Does not advance
        sim time. Moves a vehicle from the front berth of prev_platform into the
        rear berth of self if there is room.
        prev_platform may be None.
        """
        if len(self.berths) >= 2:
            for i in xrange(len(self.berths) - 1):
                # Lead berth is empty, the following berth has a non-busy vehicle
                if self.berths[i].is_empty() and \
                      not self.berths[i+1].is_empty() and \
                      not self.berths[i+1].is_busy():
                    # swap the berths' vehicle
                    self.berths[i+1].vehicle.bump_forward(self.berth_length)
                    self.berths[i].vehicle, self.berths[i+1].vehicle = \
                            self.berths[i+1].vehicle, self.berths[i].vehicle

        if self.berths[-1].is_empty() and prev_platform != None:
            prev_front_berth = prev_platform.berths[0]
            if not prev_front_berth.is_empty() and not prev_front_berth.is_busy():
                prev_front_berth.vehicle.bump_forward(self.berth_length)
                self.berths[-1].vehicle, prev_front_berth.vehicle = \
                       prev_front_berth.vehicle, self.berths[-1].vehicle

    def is_empty(self):
        """True if no berths are occupied."""
        empty = True
        for berth in self.berths:
            if not berth.is_empty():
                empty = False
                break
        return empty
Exemplo n.º 12
0
class Berth(Sim.Process, traits.HasTraits):
    label = traits.Str
    platform_index = traits.Int
    station_id = traits.Int
    vehicle = traits.Instance('pyprt.sim.vehicle.BaseVehicle', None)

    _busy = traits.Bool
    _unload = traits.Bool
    _load = traits.Bool
    _msg_id = traits.Int
    _pax = traits.List(traits.Instance('pyprt.sim.events.Passenger'))

    traits_view =  ui.View(ui.HGroup(ui.Item(name='vehicle',
                                             editor = ui.TextEditor()),
                                     ui.Item('busy')))

    def __init__(self, label, station_id, vehicle, **tr):
        Sim.Process.__init__(self, name=label)
        traits.HasTraits.__init__(self, **tr)
        self.label = label
        self.station_id = station_id
        self.vehicle = vehicle

        # Control flags/settings for the run loop
        self._busy = False
        self._unload = False
        self._load   = False
        self._msg_id = api.NONE_ID
        self._pax = []

    def __str__(self):
        return str( (self.label, str(self.vehicle), str(self._busy)) )

    def is_empty(self):
        """Returns True if the berth is not occupied by a vehicle."""
        return False if self.vehicle else True

    def unload(self, msg_id, passengers):
        self._unload = True
        self._msg_id = msg_id
        self._pax = passengers
        if self.passive:
            Sim.reactivate(self, prior=True)

    def load(self, msg_id, passengers):
        self._load = True
        self._msg_id = msg_id
        self._pax = passengers
        if self.passive:
            Sim.reactivate(self, prior=True)

    def is_busy(self):
        return self._busy

    def run(self):
        station = common.stations[self.station_id]
        while True:
            # Unloading
            if self._unload:
                for pax in reversed(self.vehicle.passengers):
                    self._unload = False
                    self._busy = True
                    yield Sim.hold, self, pax.unload_delay
                    del self.vehicle.passengers[-1] # pax that left vehicle
                    pax.loc = self.station
                    pax.trip_end = Sim.now()
                    if self.station_id == pax.dest_station.ID:
                        pax.trip_success = True
                        common.delivered_pax.add(pax)
                        logging.info("T=%4.3f %s delivered to %s by %s. Unloaded in berth %s",
                                      Sim.now(), pax, self.station_id, self.vehicle, self.label)

                self._busy = False

                if station.passive():
                    Sim.reactivate(station, prior = True)

            # Loading
            elif self._load:
                for pax in self._pax:
                    self._load = False
                    self._busy = True
                    s_notify = api.SimNotifyPassengerLoadStart()
                    s_notify.vID = self.vehicle.ID
                    s_notify.sID = self.station_id
                    s_notify.pID = pax.ID
                    common.interface.send(api.SIM_NOTIFY_PASSENGER_LOAD_START,
                                          s_notify)
                    yield Sim.hold, self, pax.load_delay
                    self.vehicle.passengers.append(pax)
                    pax.trip_boarded = Sim.now()
                    pax.loc = self.vehicle
                    logging.info("T=%4.3f %s loaded into %s at station %s",
                                 Sim.now(), pax, self.vehicle, self.station_id)
                    e_notify = api.SimNotifyPassengerLoadEnd()
                    e_notify.vID = self.vehicle.ID
                    e_notify.sID = self.station_id
                    e_notify.pID = pax.ID
                    common.interface.send(api.SIM_NOTIFY_PASSENGER_LOAD_END,
                                          e_notify)
                    # If using the LOBBY policy, notify that passenger load command
                    # has completed.
                    if self._load_msgID:
                        cmd_notify = api.SimCompletePassengerLoadVehicle()
                        cmd_notify.msgID = self._msgID
                        cmd_notify.vID = self.vehicle.ID
                        cmd_notify.sID = self.station_id
                        cmd_notify.pID = pax.ID
                        common.interface.send(api.SIM_COMPLETE_PASSENGER_LOAD_VEHICLE,
                                          cmd_notify)
                        self._load_msgID = None

                self._busy = False
                if station.passive():
                    Sim.reactivate(station, prior = True)

            else:
                assert not self._busy
                yield Sim.passivate, self
Exemplo n.º 13
0
class runBRAINSCutOutputSpec(TraitedSpec):
    outputDir = traits.Directory(desc="outputDir", exists=True)
    outputList = traits.List(type="traits.File",
                             sep=",",
                             desc="OutputAverageOfPassiveImages",
                             exists=True)
Exemplo n.º 14
0
	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")
	radiusVN4 = traits.Float( argstr = "--rVN4 %f")
	debug = traits.Bool( argstr = "--debug ")
	verbose = traits.Bool( argstr = "--verbose ")
	writeBranded2DImage = traits.Either(traits.Bool, File, argstr = "--writeBranded2DImage %s")
Exemplo n.º 15
0
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
Exemplo n.º 16
0
class AxesManager(t.HasTraits):
    axes = t.List(DataAxis)
    _slicing_axes = t.List()
    _non_slicing_axes = t.List()
    _step = t.Int(1)

    def __init__(self, axes_list):
        super(AxesManager, self).__init__()
        ncoord = len(axes_list)
        self.axes = [None] * ncoord
        for axis_dict in axes_list:
            self.axes[axis_dict['index_in_array']] = DataAxis(**axis_dict)
        slices = [i.slice_bool for i in self.axes if hasattr(i, 'slice_bool')]
        # set_view is called only if there is no current view
        if not slices or np.all(np.array(slices) == False):
            self.set_view()
        self.set_signal_dimension()
        self.on_trait_change(self.set_signal_dimension, 'axes.slice')
        self.on_trait_change(self.set_signal_dimension, 'axes.index')

    def set_signal_dimension(self):
        getitem_tuple = []
        indexes = []
        values = []
        self._slicing_axes = []
        self._non_slicing_axes = []
        for axis in self.axes:
            if axis.slice is None:
                getitem_tuple.append(axis.index)
                indexes.append(axis.index)
                values.append(axis.value)
                self._non_slicing_axes.append(axis)
            else:
                getitem_tuple.append(axis.slice)
                self._slicing_axes.append(axis)
        self._getitem_tuple = getitem_tuple
        self._indexes = np.array(indexes)
        self._values = np.array(values)
        self.signal_dimension = len(self._slicing_axes)
        self.navigation_dimension = len(self._non_slicing_axes)
        self.navigation_shape = [axis.size for axis in self._non_slicing_axes]

    def set_not_slicing_indexes(self, nsi):
        for index, axis in zip(nsi, self.axes):
            axis.index = index

    def set_view(self, view='hyperspectrum'):
        """view : 'hyperspectrum' or 'image' """
        tl = [False] * len(self.axes)
        if view == 'hyperspectrum':
            # We limit the signal_dimension to 1 to get a spectrum
            tl[0] = True
        elif view == 'image':
            tl[:2] = True, True

        for axis in self.axes:
            axis.slice_bool = tl.pop()

    def set_slicing_axes(self, slicing_axes):
        '''Easily choose which axes are slicing

        Parameters
        ----------

        slicing_axes: tuple of ints
            A list of the axis indexes that we want to slice

        '''
        for axis in self.axes:
            if axis.index_in_array in slicing_axes:
                axis.slice_bool = True
            else:
                axis.slice_bool = False

    def connect(self, f):
        for axis in self.axes:
            if axis.slice is None:
                axis.on_trait_change(f, 'index')

    def disconnect(self, f):
        for axis in self.axes:
            if axis.slice is None:
                axis.on_trait_change(f, 'index', remove=True)

    def key_navigator(self, event):
        if len(self._non_slicing_axes) not in (1, 2): return
        x = self._non_slicing_axes[-1]

        if event.key == "right" or event.key == "6":
            x.index += self._step
        elif event.key == "left" or event.key == "4":
            x.index -= self._step
        elif event.key == "pageup":
            self._step += 1
        elif event.key == "pagedown":
            if self._step > 1:
                self._step -= 1
        if len(self._non_slicing_axes) == 2:
            y = self._non_slicing_axes[-2]
            if event.key == "up" or event.key == "8":
                y.index -= self._step
            elif event.key == "down" or event.key == "2":
                y.index += self._step

    def edit_axes_traits(self):
        for axis in self.axes:
            axis.edit_traits()

    def copy(self):
        return (copy.copy(self))

    def deepcopy(self):
        return (copy.deepcopy(self))

    def __deepcopy__(self, *args):
        return AxesManager(self._get_axes_dicts())

    def _get_axes_dicts(self):
        axes_dicts = []
        for axis in self.axes:
            axes_dicts.append(axis.get_axis_dictionary())
        return axes_dicts

    def _get_slicing_axes_dicts(self):
        axes_dicts = []
        i = 0
        for axis in self._slicing_axes:
            axes_dicts.append(axis.get_axis_dictionary())
            axes_dicts[-1]['index_in_array'] = i
            i += 1
        return axes_dicts

    def _get_non_slicing_axes_dicts(self):
        axes_dicts = []
        i = 0
        for axis in self._non_slicing_axes:
            axes_dicts.append(axis.get_axis_dictionary())
            axes_dicts[-1]['index_in_array'] = i
            i += 1
        return axes_dicts

    traits_view = tui.View(tui.Item('axes', style='custom'))
Exemplo n.º 17
0
 class formatter(TConfig):
     limits = T.List(T.Float, [-7, 7], minlen=2, maxlen=2)
Exemplo n.º 18
0
class Station(traits.HasTraits):
    platforms = traits.List(traits.Instance(Platform))
    track_segments = traits.Set(traits.Instance(TrackSegment))

    # Passengers waiting at the station.
    _passengers = traits.List(traits.Instance(Passenger))

    traits_view = ui.View(
        ui.VGroup(
            ui.Group(
                ui.Label('Waiting Passengers'),
                ##                                ui.Item(name='_passengers',
                ##                                        show_label = False,
                ##                                        editor=Passenger.table_editor
                ##                                        ),
                show_border=True)),
        title='Station',  # was: self.label
        #                       scrollable = True,
        resizable=True,
        height=700,
        width=470,
        handler=NoWritebackOnCloseHandler())

    table_editor = ui.TableEditor(
        columns=[
            ui_tc.ObjectColumn(name='ID', label='ID', tooltip='Station ID'),
            ui_tc.ObjectColumn(name='label',
                               label='Label',
                               tooltip='Non-unique identifier'),
            ui_tc.ExpressionColumn(
                label='Current Pax',
                format='%d',
                expression='len(object._passengers)',
                tooltip='Number of passengers currently at station.')
            # TODO: The rest...
        ],
        deletable=False,
        editable=False,
        sortable=True,
        sort_model=False,
        auto_size=True,
        orientation='vertical',
        show_toolbar=True,
        reorderable=False,
        rows=15,
        row_factory=traits.This)

    def __init__(self, ID, label, track_segments, storage_entrance_delay,
                 storage_exit_delay, storage_dict):

        traits.HasTraits.__init__(self)
        self.ID = ID
        self.label = label
        self.platforms = []
        self.track_segments = track_segments
        self.storage_entrance_delay = storage_entrance_delay
        self.storage_exit_delay = storage_exit_delay

        # Keyed by the VehicleModel name (string) with FIFO queues as the values.
        self._storage_dict = storage_dict

        self._pax_arrivals_count = 0
        self._pax_departures_count = 0
        self._pax_times = [(Sim.now(), len(self._passengers))
                           ]  # elements are (time, num_pax)
        self._all_passengers = []

    def __str__(self):
        if self.label:
            return self.label
        else:
            return str(self.ID)

    def __hash__(self):
        return hash(self.ID)

    def __eq__(self, other):
        if not isinstance(other, Station):
            return False
        else:
            return self.ID == other.ID

    def __ne__(self, other):
        if not isinstance(other, Station):
            return True
        else:
            return self.ID != other.ID

    def __cmp__(self, other):
        return cmp(self.ID, other.ID)

    def startup(self):
        """Activates all the berths"""
        for platform in self.platforms:
            for berth in platform.berths:
                Sim.activate(berth, berth.run())

    def add_passenger(self, pax):
        """Add a passenger to this station."""
        assert pax not in self._passengers
        self._passengers.append(pax)
        self._all_passengers.append(pax)
        self._pax_times.append((Sim.now(), len(self._passengers)))

    def remove_passenger(self, pax):
        """Remove a passenger from this station, such as when they load into a
        vehicle, or when they storm off in disgust..."""
        self._passengers.remove(pax)
        self._pax_times.append((Sim.now(), len(self._passengers)))

    def get_num_passengers(self):
        return len(self._passengers)

    num_passengers = property(get_num_passengers)

    def get_stored_vehicle_count(self, vehicle_model):
        sv_count = 0
        store = self._storage_dict[vehicle_model]
        sv_count += store.get_stored_vehicle_count()
        return sv_count

    def all_pax_wait_times(self):
        """Returns a list of wait times for all passengers, not just the current ones."""
        times = []
        for pax in self._all_passengers:
            for start, end, loc in pax._wait_times:
                if loc is self:
                    if end is None:
                        times.append(Sim.now() - start)
                    else:
                        times.append(end - start)
        return times

    def curr_pax_wait_times(self):
        """Returns a list of wait times for passengers currently waiting in the
        station."""
        times = []
        for pax in self._passengers:
            for start, end, loc in pax._wait_times:
                if loc is self:
                    if end is None:
                        times.append(Sim.now() - start)
                    else:
                        times.append(end - start)
        return times

    def get_min_all_pax_wait(self):
        try:
            return min(self.all_pax_wait_times())
        except ValueError:  # Empty sequence
            assert len(self.all_pax_wait_times()) == 0
            return 0

    min_all_pax_wait = property(get_min_all_pax_wait)

    def get_mean_all_pax_wait(self):
        try:
            wait_times = self.all_pax_wait_times()
            return sum(wait_times) / len(wait_times)
        except ZeroDivisionError:
            return 0

    mean_all_pax_wait = property(get_mean_all_pax_wait)

    def get_max_all_pax_wait(self):
        try:
            return max(self.all_pax_wait_times())
        except ValueError:  # Empty sequence
            return 0

    max_all_pax_wait = property(get_max_all_pax_wait)

    def get_min_curr_pax_wait(self):
        try:
            return min(self.curr_pax_wait_times())
        except ValueError:  # Empty sequence
            assert len(self.curr_pax_wait_times()) == 0
            return 0

    min_curr_pax_wait = property(get_min_curr_pax_wait)

    def get_mean_curr_pax_wait(self):
        try:
            wait_times = self.curr_pax_wait_times()
            return sum(wait_times) / len(wait_times)
        except ZeroDivisionError:
            return 0

    mean_curr_pax_wait = property(get_mean_curr_pax_wait)

    def get_max_curr_pax_wait(self):
        try:
            return max(self.curr_pax_wait_times())
        except ValueError:  # Empty sequence
            return 0

    max_curr_pax_wait = property(get_max_curr_pax_wait)
Exemplo n.º 19
0
class SummaryReport(Report):
    """Summary statistics for all sections."""

    _lines = traits.List(traits.Str)
    _text = traits.Str

    def __init__(self):
        super(SummaryReport, self).__init__(title="Summary")

    def update(self, pax_report, vehicle_report, station_report, power_report):
        """Returns a list of strings containing summary info."""
        assert isinstance(pax_report, PaxReport)
        assert isinstance(vehicle_report, VehicleReport)
        assert isinstance(station_report, StationReport)
        assert isinstance(power_report, PowerReport)

        KM_TO_MILES = 0.621371192
        lines = []

        lines.append("Minutes Simulated:\t %.1f" % (Sim.now()/60.))
        lines.append("")

        # Passenger summary statistics
        if common.passengers: # some passengers were simulated
            pax_list = common.passengers.values()

            success_rate = sum(1 for p in pax_list if p.trip_success)/len(pax_list) * 100
            lines.append("Passenger Statistics")
            lines.append("Number of Passengers:  %d" % len(pax_list))

            min_t, max_t, sum_t = 0, 0, 0
            for p in pax_list:
                t = p.wait_time
                if t < min_t:
                    min_t = t
                if t > max_t:
                    max_t = t
                sum_t += t
            lines.append("Wait times (Min/Mean/Max):\t%s\t%s\t%s" % \
                           (sec_to_hms(min_t),
                            sec_to_hms(sum_t/len(pax_list)),
                            sec_to_hms(max_t)))

            min_t, max_t, sum_t = 0, 0, 0
            for p in pax_list:
                t = p.walk_time
                if t < min_t:
                    min_t = t
                if t > max_t:
                    max_t = t
                sum_t += t
            lines.append("Walk times (Min/Mean/Max):\t%s\t%s\t%s" % \
                           (sec_to_hms(min_t),
                            sec_to_hms(sum_t/len(pax_list)),
                            sec_to_hms(max_t)))

            min_t, max_t, sum_t = 0, 0, 0
            for p in pax_list:
                t = p.ride_time
                if t < min_t:
                    min_t = t
                if t > max_t:
                    max_t = t
                sum_t += t
            lines.append("Ride times (Min/Mean/Max):\t%s\t%s\t%s" % \
                           (sec_to_hms(min_t),
                            sec_to_hms(sum_t/len(pax_list)),
                            sec_to_hms(max_t)))

            min_t, max_t, sum_t = 0, 0, 0
            for p in pax_list:
                t = p.total_time
                if t < min_t:
                    min_t = t
                if t > max_t:
                    max_t = t
                sum_t += t
            lines.append("Total times (Min/Mean/Max):\t%s\t%s\t%s" % \
                           (sec_to_hms(min_t),
                            sec_to_hms(sum_t/len(pax_list)),
                            sec_to_hms(max_t)))
            lines.append("%% Trip success:\t%5d" % success_rate)
            lines.append("")

        else:
            lines.append("No passengers simulated.")
            lines.append("")

        # Vehicle summary statistics
        distances = [v.get_dist_travelled() for v in common.vehicle_list]
        operational_times = [v.get_operational_time() for v in common.vehicle_list]
        nonempty_distances = [v.get_nonempty_dist() for v in common.vehicle_list]
        nonempty_times = [v.get_nonempty_time() for v in common.vehicle_list]
        pax_distances = [v.get_pax_dist() for v in common.vehicle_list]
        pax_counts = [v.total_pax for v in common.vehicle_list]

        total_dist = sum(distances)
        total_km = total_dist/1000.
        total_miles = total_km * KM_TO_MILES
        total_nonempty_dist = sum(nonempty_distances)
        total_nonempty_km = total_nonempty_dist/1000.
        total_nonempty_miles = total_nonempty_km * KM_TO_MILES
        total_pax_dist = sum(pax_distances)
        total_pax_km = total_pax_dist/1000.
        total_pax_miles = total_pax_km * KM_TO_MILES
        total_time = sum(operational_times) # seconds
        total_time_hours = total_time/3600.
        total_nonempty_time = sum(nonempty_times) # seconds
        total_nonempty_time_hours = total_nonempty_time/3600.

        mean_km = total_km/len(common.vehicle_list)
        mean_miles = mean_km * KM_TO_MILES
        max_km = max(distances)/1000.
        max_miles = max_km * KM_TO_MILES
        min_km = min(distances)/1000.
        min_miles = min_km * KM_TO_MILES

        try:
            mean_vel_kph = total_km/total_time_hours
            mean_vel_mph = total_miles/total_time_hours
        except ZeroDivisionError:
            mean_vel_kph = 0
            mean_vel_mph = 0

        try:
            mean_pax_vel_kph = total_nonempty_km/total_nonempty_time_hours
            mean_pax_vel_mph = total_nonempty_miles/total_nonempty_time_hours
        except ZeroDivisionError:
            mean_pax_vel_kph = 0
            mean_pax_vel_mph = 0

        total_pax = sum(pax_counts)
        min_pax = min(pax_counts)
        mean_pax = total_pax/len(common.vehicle_list)
        max_pax = max(pax_counts)

        lines.append("Vehicle statistics")
        lines.append("Number of Vehicles:\t%d" % len(common.vehicle_list))
        lines.append("Total vehicle km travelled:\t%10.3f\t(%.3f miles)" % (total_km, total_miles))
        lines.append("Vehicle km travelled (Min/Mean/Max):\t%9.3f\t%9.3f\t%9.3f" % (min_km, mean_km, max_km))
        lines.append("Vehicle miles travelled (Min/Mean/Max):\t%9.3f\t%9.3f\t%9.3f" % (min_miles, mean_miles, max_miles))
        lines.append("Mean velocity:\t%10d km/hr\t(%d mph)" % (mean_vel_kph, mean_vel_mph))
        lines.append("Mean velocity w/ passengers:\t%10d km/hr\t(%d mph)" % (mean_pax_vel_kph, mean_pax_vel_mph))
        lines.append("Total passengers carried:\t%10d" % total_pax)
        lines.append("Pax carried per vehicle (Min/Mean/Max):\t%9d\t%9.3f\t%9d" % (min_pax, mean_pax, max_pax))
        lines.append("Passenger km travelled: %.1f\t(%.1f miles)" % (total_pax_km, total_pax_miles))
        lines.append("")

        # Station summary statistics
        lines.append("Station statistics")
        lines.append("Number of stations:\t%d" % len(common.station_list))
        lines.append("")

        # Power summary statistics
        try:
            lines.append("Power statistics")
            total_energy = power_report.plot_data.get_data('total_energy').get_data()[-1]
            lines.append("Total Energy:\t%.1f KW-hrs" % total_energy)
            lines.append("Energy/Distance:\t%.1f Watt-hrs/km\t (%.1f Watt-hrs/mile)" \
                         % ((total_energy*1000.)/total_km, (total_energy*1000.)/total_miles))
        except (IndexError, ZeroDivisionError):
            pass

        self._lines = lines
        self._text = self.LINE_DELIMETER.join(self._lines)

    def __str__(self):
        return self._text
Exemplo n.º 20
0
class SplineExplorer(traits.HasTraits):
    """A simple UI to adjust the parameters and view the resulting splines."""

    v_min = traits.Float(0)
    v_max = traits.Float(15)
    a_min = traits.Float(-5)
    a_max = traits.Float(5)
    j_min = traits.Float(-2.5)
    j_max = traits.Float(2.5)
    mass = traits.Float(400)

    q_i = traits.Float
    v_i = traits.Float
    a_i = traits.Float
    t_i = traits.Float

    q_f = traits.Float(100)
    v_f = traits.Float(0)
    a_f = traits.Float(0)
    t_f = traits.Float(18)

    plot_names = traits.List(
        ["Position", "Jerk", "Velocity", "Power", "Acceleration"])
    active_plots = traits.List

    target_type = traits.Enum(('Position', 'Velocity', 'Acceleration', 'Time'))

    plot_container = traits.Instance(Container)
    recalculate = menu.Action(name="Recalculate", action="recalc")
    dump = menu.Action(name="Print", action="dump")
    save = menu.Action(name="Save", action="save")
    trait_view = ui.View(ui.HGroup(
        ui.VGroup(
            ui.Item(name='target_type', label='Target'),
            ui.VGroup(ui.Item(name='active_plots',
                              show_label=False,
                              editor=ui.CheckListEditor(cols=3,
                                                        name='plot_names'),
                              style='custom'),
                      label='Show Plots',
                      show_border=True),
            ui.VGroup(ui.Item(name='q_i', label='Position'),
                      ui.Item(name='v_i', label='Velocity'),
                      ui.Item(name='a_i', label='Acceleration'),
                      ui.Item(name='t_i', label='Time'),
                      label='Initial Conditions',
                      show_border=True),
            ui.VGroup(ui.Item(
                name='q_f',
                label='Position',
                enabled_when="target_type not in ('Velocity', 'Acceleration')"
            ),
                      ui.Item(name='v_f',
                              label='Velocity',
                              enabled_when="target_type != 'Acceleration'"),
                      ui.Item(name='a_f', label='Acceleration'),
                      ui.Item(name='t_f',
                              label='Time',
                              enabled_when="target_type == 'Time'"),
                      label='Final Conditions:',
                      show_border=True),
            ui.VGroup(ui.Item(name='v_min', label='Min Velocity'),
                      ui.Item(name='v_max', label='Max Velocity'),
                      ui.Item(name='a_min', label='Min Acceleration'),
                      ui.Item(name='a_max', label='Max Acceleration'),
                      ui.Item(name='j_min', label='Min Jerk'),
                      ui.Item(name='j_max', label='Max Jerk'),
                      ui.Item(name='mass', label='Vehicle Mass'),
                      label='Constraints',
                      show_border=True)),
        ui.Item('plot_container', editor=ComponentEditor(), show_label=False)),
                         title='Cubic Spline Explorer',
                         handler=SEButtonHandler(),
                         buttons=[recalculate, dump, save],
                         resizable=True,
                         width=1000)

    def __init__(self):
        super(SplineExplorer, self).__init__()
        self.active_plots = self.plot_names[:]
        self.active_plots.remove("Power")
        self.calc()

    def calc(self):
        try:
            self.solver = TrajectorySolver(self.v_max, self.a_max, self.j_max,
                                           self.v_min, self.a_min, self.j_min)
            self.initial = Knot(self.q_i, self.v_i, self.a_i, self.t_i)
            self.final = Knot(self.q_f, self.v_f, self.a_f, self.t_f)

            if self.target_type == 'Position':
                self.spline = self.solver.target_position(
                    self.initial, self.final)
            elif self.target_type == 'Velocity':
                self.spline = self.solver.target_velocity(
                    self.initial, self.final)
            elif self.target_type == 'Acceleration':
                self.spline = self.solver.target_acceleration(
                    self.initial, self.final)
            elif self.target_type == 'Time':
                self.spline = self.solver.target_time(self.initial, self.final)

            pos = vel = accel = jerk = power = False
            if "Position" in self.active_plots: pos = True
            if "Velocity" in self.active_plots: vel = True
            if "Acceleration" in self.active_plots: accel = True
            if "Jerk" in self.active_plots: jerk = True
            if "Power" in self.active_plots: power = True

            self.plotter = CSplinePlotter(self.spline,
                                          self.v_max,
                                          self.a_max,
                                          self.j_max,
                                          self.v_min,
                                          self.a_min,
                                          self.j_min,
                                          mass=self.mass,
                                          plot_pos=pos,
                                          plot_vel=vel,
                                          plot_accel=accel,
                                          plot_jerk=jerk,
                                          plot_power=power)
            self.plot_container = self.plotter.container
        except:
            self.initial = None
            self.final = None
            self.spline = None
            self.plot_container = Container()

    def display(self):
        self.configure_traits()

    def get_save_filename(self):
        """Get a filename from the user via a FileDialog. Returns the filename."""
        dialog = FileDialog(action="save as",
                            default_filename="spline_00",
                            wildcard="*.png")
        dialog.open()
        if dialog.return_code == OK:
            return dialog.path

    def save(self, path):
        """Save an image of the plot. Does not catch any exceptions."""
        # Create a graphics context of the right size
        win_size = self.plot_container.outer_bounds
        plot_gc = chaco.PlotGraphicsContext(win_size)
        #plot_gc.set_fill_color("transparent")
        # Place the plot component into it
        plot_gc.render_component(self.plot_container)

        # Save out to the user supplied filename
        plot_gc.save(path)

    def _active_plots_changed(self):
        self.calc()

    def _target_type_changed(self):
        self.calc()
Exemplo n.º 21
0
class Station(traits.HasTraits):
    """TODO: Check documentation and update if necessary. OUT OF DATE!!!

    First pass implementation will use a simple interface. Rather than
    explicitly handling passengers queuing for vehicles, the controller may
    tell any passenger to board any vehicle that's at the platform.

    The layout for this Station implementation is serial. Upon entering the
    station, a vehicle enters an unloading platform. Once unloaded, the vehicle
    moves into a empty vehicle queue. Then the vehicle enters a loading
    platform. Finally, the frontmost vehicle of the loading platform may exit
    the station.

    In this version, there is no bypass track -- empty vehicles must pass
    through the loading platform to exit the station.

    The platforms consist of a number of berths. Each berth is a SimPy Process
    object, and the Station process serves to coordinate and direct the actions
    of the berths.

    It is assumed that the vehicle speed is kept low within the station, and
    that vehicles have a fixed time to advance a slot (where a slot is either
    a queue position, or a load/unload berth). That is, advancing five slots
    always takes 5 * v_adv_time. Transfering from the front of the unload
    platform to the rear of the empty queue also takes one v_adv_time. Ditto for
    transferring to the load platform.

    All vehicles in the station advance in synchronicity. A vehicle that is not
    ready to move at the beginning of a cycle is delayed from moving until the
    beginning of the next cycle, where cycle length is the v_adv_time.

    When a vehicle enters or leaves a station, there is a v_adv_time delay. If
    a vehicle is entering, the following timeline is used:
        0: SIM_NOTIFY_VEHICLE_ARRIVE (station) msg sent
        0 - v_adv_time: Vehicle 'fully' occupies rearmost berth of platform
                        Vehicle body moves into station and off of the track
        v_adv_time: Vehicle is completely off of track.
                    SIM_NOTIFY_VEHICLE_EXIT (edge) msg sent

    When a vehicle is launched from the station:
        0: CTRL_CMD_STATION_LAUNCH received
           SIM_NOTIFY_VEHICLE_ARRIVE (edge) msg sent
        0 - v_adv_time: Vehcicle 'fully' occupies launch berth
                        Vehicle body moves onto track
        v_adv_time: Vehicle is completely out of station
                    SIM_COMPLETE_STATION_LAUNCH msg sent

    The entry and launch of a vehicle happens asynchronously.

    TODO: Use berth length and station speed limit to determine v_adv_time?
    TODO: Test / Bugfix StationSummary msgs
    """

    platforms = traits.List(traits.Instance(Platform))
    track_segments = traits.List(traits.Instance('pyprt.sim.layout.TrackSegment'))

    # Passengers waiting at the station.
    passengers = traits.List(traits.Instance('pyprt.sim.events.Passenger'))

    def __init__(self, ID, label, platforms, track_segments, **tr):
#        Sim.Process.__init__(self, name=self.label)
        self.ID = ID
        self.label = label
#        self.policy = policy # vehicle loading policy: 'QUEUE' or 'LOBBY'
#        # TODO: Remove policy, and make it a choice of the external station controller

        self.platforms = platforms
        self.track_segments = track_segments

        self.totalDepartures = 0
        self.totalArrivals = 0
        self.totalCrashes = 0

        # Set to True by another process prior to interruption.
        self.launchFlag = False

        # boarding pairs. Key is the Vehicle instance, value is the
        # Passenger instance. Only used under LOBBY policy.
        self._boarding = dict()

        self.rdy_launch_sent = False
        self.unrdy_launch_sent = False
        self.rdy_load_sent = set()

        # Every station will have a slightly different view
        self.view = self.make_view()

    def startup(self):
        # upon station activation, activate berths
        for platform in self.platforms:
            for berth in platform.berths:
                Sim.activate(berth, berth.run())

##    def is_empty(self):
##        empty = True
##        for platform in self.platforms:
##            if not platform.is_empty():
##                empty = False
##                break
##        return empty

#    def accept(self, veh):
#        """Accept a vehicle into the station. Notifies the controller of the
#        event and reactivates Station (self) if necessary.
#        """
#        self.totalArrivals += 1
###        rear_berth = self.unload_platform[-1]
###        rb_vehicle = rear_berth.vehicle # save the current rear vehicle, if any
###
###        # take vehicle even if a crash or overshoot occurred. TEMP?
###        rear_berth.vehicle = veh
#        self.unload_platform[-1].vehicle = veh
#        logging.info("T=%4.3f %s accepted at %s. Speed: %s Pos: %s",
#                     Sim.now(), veh, self, veh.speed, veh.pos)
#        if self.passive():
#            Sim.reactivate(self, prior = True)
###        # Can only return one type of crash. Overshoot is considered to be
###        # the more serious one right now.
###        if veh.speed > self.max_speed:
###            self.totalCrashes += 1
###            print "CRASH T=%4.3f %s entered %s at too high of a speed: %f." %\
###                          (Sim.now(), veh, self, veh.speed)
###            logging.error("T=%4.3f %s entered %s at too high of a speed: %f.",
###                          Sim.now(), veh, self, veh.speed)
###            raise common.StationOvershootError
###        if rb_vehicle:
###            self.totalCrashes += 1
###            print "CRASH T=%4.3f %s entered %s without room to accept. Hit %s" %\
###                          (Sim.now(), veh, self, rb_vehicle)
###            logging.error("T=%4.3f %s entered %s without room to accept. Hit %s",
###                          Sim.now(), veh, self, rb_vehicle)
###            raise common.StationFullError

#    def ctrl_loop(self):
#        # Startup Code
#        # upon station activation, activate berths
#        for platform in self.platforms:
#            for berth in platform.berths:
#                Sim.activate(berth, berth.run())
#
#        if self.is_empty():
#            yield Sim.passivate, self  # no vehicles, nothing to do.
#        self.next_heartbeat = Sim.now() + self.v_adv_time
#
#        # Main Loop
#        while True:
#            self.send_rdy_load(self.load_platform)
#            self.send_rdy_launch()
#
#            # Allow communication with controller (no time passes)
#            yield Sim.hold, self
#
#            self.unload_passengers(self.unload_platform)
#            self.load_passengers(self.load_platform)
#
#            self.send_rdy_load(self.load_platform)
#            self.send_rdy_launch()
#
#            # Slide everything forward one slot. Don't update positions until
#            # after the time cost is paid.
#            yield Sim.hold, self, self.next_heartbeat - Sim.now()
#
#            # Once the vehicle clears the exit berth, it interrupts the station
#            while self.interrupted():
#                assert self.interruptCause.ID is flb.vehicle.ID # vehicle is interruptCause
#                self.next_heartbeat = Sim.now() + self.interruptLeft
#                flb.vehicle = None
#                # If station is now empty, passivate
#                if self.is_empty():
#                    logging.info("T=%4.3f %s now empty, passivating.", Sim.now(), self)
#                    self.interruptReset()
#                    yield Sim.passivate, self
#                else:
#                    logging.info("T=%4.3f %s still contains a vehicle, staying active",
#                                 Sim.now(), self)
#                    t_left = self.interruptLeft
#                    self.interruptReset()
#                    yield Sim.hold, self, t_left
#
#            # Advance the front-most platform first, then work back.
#            for platform in self.platforms.reverse():
#                platform.advance()
#
#            self.next_heartbeat = Sim.now() + self.v_adv_time

    def add_passenger(self, pax):
        """Add a passenger to this station."""
        assert pax not in self.passengers
        self.passengers.append(pax)

##    def unload_passengers(self, platform):
##        packed = True
##        for b in platform:
##            # If there's a vehicle with a passenger in the berth, and it's
##            # not already unloading, and it's as far forward as it can go
##            # (packed), then unload.
##            if not b.vehicle:
##                packed = False
##            if b.vehicle and b.vehicle.passengers and not b.is_busy() and packed:
##                b._unload = True
##                Sim.reactivate(b, prior = True)

#    def send_rdy_load(self, platform):
#        packed = True
#        for b in platform:
#            v = b.vehicle
#            if not v:
#                packed = False
#            elif b.is_busy():
#                packed = True
#            elif packed and not v.passengers and not b.is_busy():
#                if v not in self._boarding and \
#                   v not in self.rdy_load_sent:
#                    self.rdy_load_sent.add(v)
#                    rl_msg = api.SimNotifyVehicleReadyLoad()
#                    rl_msg.vID = v.ID
#                    rl_msg.sID = self.ID
#                    common.interface.send(api.SIM_NOTIFY_VEHICLE_READY_LOAD,
#                                          rl_msg)

#    def load_passengers(self, platform):
#        """If under a LOBBY boarding policy, uses boarding information
#        previously provided by the board_passenger function to load passengers
#        into the appropriate vehicles, if available.
#
#        WARNING, TODO: LOBBY does not currently support multiple passengers
#        on one vehicle.
#
#        If under a QUEUE boarding policy, passengers are loaded on a first-come/
#        first-served basis. If frontmost passenger in queue is willing to share,
#        other passengers with the same destination (and also willing to share)
#        will board with the frontmost passenger. Time for loading and unloading
#        multiple passengers is the sum of the individual times.
#        """
#        if len(self.passengers) == 0:
#            return
#
#        packed = True
#        for b in platform:
#            # If there's an empty vehicle in the berth, and it's
#            # not already loading, and it's as far forward as it can go
#            # (packed), then check if there is a passenger associated with it.
#            # Load the passenger if there is.
#            v = b.vehicle
#            if not v:
#                packed = False
#            elif b.is_busy():
#                packed = True
#            elif v and not v.passengers and not b.is_busy() and packed:
#                if self.policy == 'LOBBY':
#                    try:
#                        pax, msgID = self._boarding[v]
#                        idx = self.passengers.index(pax)
#                        del self.passengers[idx]
#                        del self._boarding[v]
#                        b._load_msgID = msgID
#                    except KeyError: # No boarding info for that vehicle
#                        continue
#                elif self.policy == 'QUEUE':
#                    if self.passengers:
#                        pax = [self.passengers.pop(0)]
#                        if pax[0].will_share:
#                            share_list = [(idx, p) for idx, p in
#                                        enumerate(self.passengers) if
#                                        p.dest_station is pax[0].dest_station and
#                                        p.will_share]
#                            pax.extend([p for idx, p in share_list[:v.max_pax_capacity-1]])
#                            for idx, p in reversed(share_list[:v.max_pax_capacity-1]):
#                                del self.passengers[idx]
#
#                else:
#                    raise Exception, 'Unknown pax loading policy'
#
#                b.load(msg_id, pax)
#
#                self.rdy_load_sent.discard(v)

##    def board_passenger(self, vehicle, passenger, msgID):
##        """Tell a passenger which vehicle to board. Command is queued until
##        vehicle is ready. MsgID refers to the CtrlCmdPassengerBoardVehicle msg.
##
##        Passenger is required to be at the station already, vehicle is not.
##
##        For now, only one passenger may be told to board a vehicle. If
##        board_passenger is called twice for the same vehicle, the old
##        passenger will no longer board that vehicle.
##        """
##        self._boarding[vehicle] = (passenger, msgID)

##    def is_launchable(self, vehicle):
##        """Returns True if vehicle is launchable, otherwise returns false.
##        """
##        front_berth = self.load_platform[0]
##        if front_berth.vehicle and not front_berth.is_busy():
##            return True
##        else:
##            return False

#    def launch(self, vehicle, target_speed, max_accel, max_decel, max_jerk, msgID):
#        """Intended for use by other objects (e.g. a comm instance).
#        Immediately launches the vehicle if ready. Otherwise raises
#        a common.InvalidVehicleID exception.
#
#        Note that vehicle is a vehicle instance, not an ID.
#        """
#        if not self.is_launchable(vehicle):
#            raise common.InvalidVehicleID, vehicle.ID
#        front_berth = self.load_platform[0]
#        vehicle.set_speed(target_speed, max_accel, max_decel, max_jerk, 0)
#        self.totalDepartures += 1
#        self.rdy_launch_sent = False
#        self.unrdy_launch_sent = False
#        self.rdy_load_sent.discard(vehicle)
#        l_msg = api.SimCompleteStationLaunch()
#        l_msg.msgID = msgID
#        l_msg.vID = vehicle.ID
#        l_msg.sID = self.ID
#        common.interface.send(api.SIM_COMPLETE_STATION_LAUNCH, l_msg)
#        logging.info("T=%4.3f %s launched from berth %s of %s with pax %s",
#                     Sim.now(), vehicle, front_berth.ID, self,
#                     [pax.ID for pax in vehicle.passengers if pax])
#
#        if vehicle.passive():
#            Sim.reactivate(vehicle, prior = True)
#        else:
#            Sim.activate(vehicle, vehicle.ctrl_loop())

#    def send_rdy_launch(self):
#        flb = self.load_platform[0] # front loading berth
#        if flb.vehicle and flb.vehicle.passengers \
#                and not flb.is_busy() and not self.rdy_launch_sent:
#            self.rdy_launch_sent = True
#            rdy_launch_msg = api.SimNotifyStationReadyLaunch()
#            rdy_launch_msg.vID = flb.vehicle.ID
#            rdy_launch_msg.sID = self.ID
#            for pax in flb.vehicle.passengers:
#                rdy_launch_msg.pID.append(pax.ID)
#            common.interface.send(api.SIM_NOTIFY_STATION_READY_LAUNCH,
#                                  rdy_launch_msg)
#        elif flb.vehicle and flb.is_busy() and self.rdy_launch_sent \
#                 and not self.unrdy_launch_sent:
#            self.rdy_launch_sent = False
#            self.unrdy_launch_sent = True
#            urdy_launch_msg = api.SimNotifyStationUnreadyLaunch()
#            urdy_launch_msg.vID = flb.vehicle.ID
#            urdy_launch_msg.sID = self.ID
#            common.interface.send(api.SIM_NOTIFY_STATION_UNREADY_LAUNCH,
#                                  urdy_launch_msg)

#    def fill_StationStatus(self, s_status):
#        """Fills an api.StationStatus instance with current information."""
#        s_status.sID = self.ID
#        if self.label:
#            s_status.label = self.label
#
#        # TODO: Only support for one loading/unloading plat right now.
#        ulp_status = s_status.unloading_plat.add()
#        ulp_status.platID = 1
#        for idx, b in enumerate(self.unload_platform):
#            b_status = ulp_status.berths.add()
#            b_status.bID = idx + 1 # first ID is 1
#            b_status.vID = (b.vehicle.ID if b.vehicle else api.NONE_ID)
#            b_status.busy = b.is_busy()
#
#        lp_status = s_status.loading_plat.add()
#        lp_status.platID = 2
#        for idx, b in enumerate(self.load_platform):
#            b_status = lp_status.berths.add()
#            b_status.bID = idx + 1 # first ID is 1
#            b_status.vID = (b.vehicle.ID if b.vehicle else api.NONE_ID)
#            b_status.busy = b.is_busy()
#
#
#        for v in self.queue:
#            s_status.emptyQueue.append(v.ID if v else api.NONE_ID)
#
#        for p in self.passengers:
#            s_status.pID.append(p.ID)
#
#        s_status.v_adv_time = int(round(self.v_adv_time,3)*1000) # in millisec
#        if self.policy == 'QUEUE':
#            s_status.policy = api.QUEUE
#        elif self.policy == 'LOBBY':
#            s_status.policy = api.LOBBY
#        else:
#            raise Exception, "Unknown station policy"
#
#    def fill_StationSummary(self, s_sum):
#        """Fills an api.StationSummary instance with current information."""
#        s_sum.sID = self.ID
#        if self.label:
#            s_sum.label = self.label
#        # TODO: extend to multiple load platforms
#        flb = self.load_platform[0] # front loading berth
#        s_sum.loaded_ready_launch.append(flb.vehicle.ID if flb.vehicle
#                                         and flb.vehicle.passengers
#                                         and not flb.is_busy()
#                                         else 0)
#        # TODO: extend to multiple load platforms, and empty queue bypass
#        s_sum.unloaded_ready_launch.append(flb.vehicle.ID if flb.vehicle
#                                           and not flb.vehicle.passengers
#                                           and not flb.is_busy()
#                                           else 0)
#
#        for p in self.passengers:
#            s_sum.pID.append(p.ID) # passengers waiting at station
#
#        entry_berth = self.unload_platform[-1]
##
##        entering_v = None
##        if self.resource.activeQ[-1].pos <= self.berth_length
#
#        # entry berth is immediately available
#        if not entry_berth.vehicle:
#            s_sum.next_accept_time = int(round(Sim.now()*1000)) # s -> ms
#        # test if entry berth will be available after next heartbeat
#        else:
#            avail = False
#            # look from back to front
#            for b in reversed(self.unload_platform):
#                # if found a busy berth, it's non-deterministic
#                if b.is_busy():
#                    break
#                # if found an empty berth, then vehicles will slide forward.
#                elif not b.vehicle:
#                    avail = True
#                    break
#                else:
#                    continue
#
#            if avail:
#                s_sum.next_accept_time = int(round(self.next_heartbeat*1000)) # s -> ms
#            else:
#                s_sum.next_accept_time = -1 # non-determinstic
#
#        # vehicles_needed
#        v_avail = 0 # empty and unloading vehicles
#        for v in self.queue:
#            if v:
#                v_avail += 1
#        for b in self.unload_platform:
#            if b.vehicle:
#                v_avail += 1
#        v_needed = len(self.passengers)
#        s_sum.vehicles_needed = max(0, v_needed - v_avail)

    def __str__(self):
        return self.label

    def __hash__(self):
        return self.ID.__hash__()

    def make_view(self):
        """Make a traits view (popup window) for this station."""
        pax_table_editor = ui.TableEditor(
                            # Only the passenger data relevant when looking at a station.
                            columns = [ui_tc.ObjectColumn(name='label', label='Name'),
                                       ui_tc.ObjectColumn(name='_start_time'),
                                       ui_tc.ObjectColumn(name='dest_station', label='Destination'),
                                       ui_tc.ObjectColumn(name='wait_time', label='Waiting (sec)', format="%.2f"),
                                       ui_tc.ObjectColumn(name='will_share', label='Will Share'),
                                       ui_tc.ObjectColumn(name='load_delay', label='Time to Board (sec)')],
                                       # more...
                            deletable = True,
#                            sort_model = True,
                            auto_size = True,
                            orientation = 'vertical',
                            show_toolbar = True,
                            reorderable = True, # Does this affect the actual boarding order (think no...)
                            rows = 5,
                            row_factory = events.Passenger)


        groups = ui.VGroup(
                           ui.Group(
                                ui.Label('Waiting Passengers'),
                                ui.Item(name='passengers',
                                        show_label = False,
                                        editor=pax_table_editor
                                        ),
                                show_border = True),
#                           ui.Group(
#                                ui.Label('Load Platform'),
#                                ui.Item(name='load_platform',
#                                        show_label = False,
#                                        editor=ui.ListEditor(style='custom',
#                                                             rows=len(self.load_platform)),
#                                        style='readonly'),
#                                show_border = True
#                                ),
                           ui.Group(
                                ui.Label('Queue'),
                                ui.Item(name='queue',
                                        show_label=False,
                                        editor=ui.ListEditor(editor=ui.TextEditor()),
                                        style='readonly'),
                                show_border = True
#                                ),
#                           ui.Group(
#                                ui.Label('Unload Platform'),
#                                ui.Item(name='unload_platform',
#                                        show_label = False,
#                                        editor=ui.ListEditor(style='custom',
#                                                             rows=len(self.unload_platform)),
#                                        style='readonly',
#                                        ),
#                                show_border = True,
                                ))

        view = ui.View(groups,
                       title=self.label,
#                       scrollable = True,
                       resizable = True,
                       height = 700,
                       width = 470
                       )

        return view
Exemplo n.º 22
0
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()
Exemplo n.º 23
0
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)