def __init__(self, scope, target=None, writer=None, auxList=None, keyTextPattern=None): self.sigTraceDone = util.Signal() self.sigNewTextResponse = util.Signal() self.currentTrace = 0 self.maxtraces = 1 self.key = [0] self.textin = [0] self.textout = [0] self.target = target self.scope = scope self.writer = writer self.auxList = auxList self.keyTextPattern = keyTextPattern self.keyTextPattern.setTarget(target) self.keyTextPattern.initPair() if self.auxList is not None: for aux in auxList: if aux: aux.captureInit()
def __init__(self, scope, target=None, writer=None, aux=None, keyTextPattern=None): # TODO: use project objects instead of writers? self.sigTraceDone = util.Signal() self.sigNewTextResponse = util.Signal() self.currentTrace = 0 self.maxtraces = 0 self.key = [0] self.textin = [0] self.textout = [0] self._target = target self._scope = scope self._writer = writer self._aux_dict = aux self._pattern = keyTextPattern self._pattern.setTarget(target) self._pattern.initPair(self.maxtraces) if self._aux_dict is not None: for func in self._aux_dict['before_capture']: func(self._scope, self._target, self._writer)
def __init__(self): self.sigFilenameChanged = util.Signal() self.sigStatusChanged = util.Signal() self.dirty = util.Observable(True) self.settingsDict = {'Project Name':"Untitled", 'Project File Version':"1.00", 'Project Author':"Unknown"} self.datadirectory = "" self.config = ConfigObjProj(callback=self.configObjChanged) self._traceManager = TraceManager().register() self._traceManager.dirty.connect(self.__dirtyCallback) self.setFilename(ProjectFormat.untitledFileName) if __debug__: logging.debug('Created: ' + str(self))
def __init__(self, prog_name="ChipWhisperer", prog_ver=""): self.valid_traces = None self._trace_format = None self.params = Parameter(name="Project Settings", type="group") self.params.addChildren([ { 'name': 'Trace Format', 'type': 'list', 'values': self.valid_traces, 'get': self.get_trace_format, 'set': self.set_trace_format }, ]) #self.findParam("Trace Format").setValue(TraceContainerNative(project=self), addToList=True) self._trace_format = TraceContainerNative(project=self) #self.traceParam = Parameter(name="Trace Settings", type='group', addLoadSave=True).register() #self.params.getChild('Trace Format').stealDynamicParameters(self.traceParam) self.sigFilenameChanged = util.Signal() self.sigStatusChanged = util.Signal() self.dirty = util.Observable(True) self.settingsDict = { 'Project Name': "Untitled", 'Project File Version': "1.00", 'Project Author': "Unknown" } self.datadirectory = "" self.config = ConfigObjProj(callback=self.configObjChanged) self._traceManager = TraceManager().register() self._traceManager.dirty.connect(self.__dirtyCallback) self.setFilename(Project.untitledFileName) self.setProgramName(prog_name) self.setProgramVersion(prog_ver) self._segments = Segments(self) self._traces = Traces(self) self._keys = IndividualIterable(self._traceManager.get_known_key, self._traceManager.num_traces) self._textins = IndividualIterable(self._traceManager.get_textin, self._traceManager.num_traces) self._textouts = IndividualIterable(self._traceManager.get_textout, self._traceManager.num_traces) self._waves = IndividualIterable(self._traceManager.get_trace, self._traceManager.num_traces) if __debug__: logging.debug('Created: ' + str(self))
def __init__(self): logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO) CWCoreAPI.instance = self self.sigNewProject = util.Signal() self.sigConnectStatus = util.Signal() self.sigAttackChanged = util.Signal() self.sigNewInputData = util.Signal() self.sigNewTextResponse = util.Signal() self.sigTraceDone = util.Signal() self.sigCampaignStart = util.Signal() self.sigCampaignDone = util.Signal() self.executingScripts = util.Observable(False) self.valid_scopes = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.scopes", True, True) self.valid_targets = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.targets", True, True) self.valid_traces = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.common.traces", True, True) self.valid_aux = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.auxiliary", True, True) self.valid_acqPatterns = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.acq_patterns", True, False) self.settings = Settings() # Initialize default values self._project = self._scope = self._target = self._traceFormat = self._acqPattern = self._attack = None self._acqPattern = self.valid_acqPatterns["Basic"] self._auxList = AuxList() self._numTraces = 50 self._numTraceSets = 1 # Storage for last key/plaintext/ciphertext self._lastKey = None self._lastTextin = None self._lastTextout = None self._lastExpected = None self.params = Parameter(name='Generic Settings', type='group', addLoadSave=True).register() self.params.addChildren([ {'name':'Scope Module', 'key':'scopeMod', 'type':'list', 'values':self.valid_scopes, 'get':self.getScope, 'set':self.setScope}, {'name':'Target Module', 'key':'targetMod', 'type':'list', 'values':self.valid_targets, 'get':self.getTarget, 'set':self.setTarget}, {'name':'Acquisition Settings', 'type':'group', 'children':[ {'name':'Number of Traces', 'type':'int', 'limits':(1, 1E9), 'get':self.getNumTraces, 'set':self.setNumTraces, 'linked':['Traces per Set']}, {'name':'Number of Sets', 'type':'int', 'limits':(1, 1E6), 'get':self.getNumTraceSets, 'set':self.setNumTraceSets, 'linked':['Traces per Set'], 'tip': 'Break acquisition into N sets, ' 'which may cause data to be saved more frequently. The default capture driver requires that NTraces/NSets is small enough to avoid running out of system memory ' 'as each segment is buffered into RAM before being written to disk.'}, {'name':'Traces per Set', 'type':'int', 'readonly':True, 'get':self.tracesPerSet}, {'name':'Key/Text Pattern', 'type':'list', 'values':self.valid_acqPatterns, 'get':self.getAcqPattern, 'set':self.setAcqPattern}, ]}, ]) self.scopeParam = Parameter(name="Scope Settings", type='group', addLoadSave=True).register() self.params.getChild('Scope Module').stealDynamicParameters(self.scopeParam) self.targetParam = Parameter(name="Target Settings", type='group', addLoadSave=True).register() self.params.getChild('Target Module').stealDynamicParameters(self.targetParam) # Aux settings self.auxParam = self._auxList.getParams().register() # Note: Project settings are set up in setProject() self.newProject()
def __init__(self, psClass=None): self.ps = psClass self.dataUpdated = util.Signal() chlist = {} for t in self.ps.CHANNELS: if self.ps.CHANNELS[t] < self.ps.CHANNELS['MaxChannels']: chlist[t] = self.ps.CHANNELS[t] # Rebuild channel range as string + api value chRange = util.DictType() for key in sorted(self.ps.CHANNEL_RANGE): chRange[ key['rangeStr'] ] = key['rangeV'] self.getParams().addChildren([ {'name':'Trace Measurement', 'key':'trace', 'type':'group', 'children':[ {'name':'Source', 'key':'tracesource', 'type':'list', 'values':chlist, 'value':0, 'action':self.updateCurrentSettings}, {'name':'Probe Att.', 'key':'traceprobe', 'type':'list', 'values':{'1:1':1, '1:10':10}, 'value':1, 'action':self.updateCurrentSettings}, {'name':'Coupling', 'key':'tracecouple', 'type':'list', 'values':self.ps.CHANNEL_COUPLINGS, 'value':0, 'action':self.updateCurrentSettings}, {'name':'Y-Range', 'key':'traceyrange', 'type':'list', 'values':chRange, 'value':1.0, 'action':self.updateCurrentSettings}, ]}, {'name':'Trigger', 'key':'trig', 'type':'group', 'children':[ {'name':'Source', 'key':'trigsource', 'type':'list', 'values':chlist, 'value':1, 'action':self.updateCurrentSettings}, {'name':'Probe Att.', 'key':'trigprobe', 'type':'list', 'values':{'1:1':1, '1:10':10}, 'value':10, 'action':self.updateCurrentSettings}, {'name':'Coupling', 'key':'trigcouple', 'type':'list', 'values':self.ps.CHANNEL_COUPLINGS, 'value':1, 'action':self.updateCurrentSettings}, {'name':'Y-Range', 'key':'trigrange', 'type':'list', 'values':chRange, 'value':5.0, 'action':self.updateCurrentSettings}, {'name':'Trigger Direction', 'key':'trigtype', 'type':'list', 'values':self.ps.THRESHOLD_TYPE, 'value':self.ps.THRESHOLD_TYPE["Rising"], 'action':self.updateCurrentSettings}, {'name':'Trigger Level', 'key':'triglevel', 'type':'float', 'step':1E-2, 'siPrefix':True, 'suffix':'V', 'limits':(-5, 5), 'value':0.5, 'action':self.updateCurrentSettings}, ]}, {'name':'Sample Rate', 'key':'samplerate', 'type':'int', 'step':1E6, 'limits':(10000, 5E9), 'value':100E6, 'action':self.updateSampleRateFreq, 'siPrefix':True, 'suffix': 'S/s'}, {'name':'Sample Length', 'key':'samplelength', 'type':'int', 'step':250, 'limits':(1, 500E6), 'value':500, 'action':self.updateSampleRateFreq}, {'name':'Sample Offset', 'key':'sampleoffset', 'type':'int', 'step':1000, 'limits':(0, 100E6), 'value':0, 'action':self.updateSampleRateFreq}, ])
def __init__(self, numSubKeys, permPerSubkey, model=None): self.sigParametersChanged = util.Signal() self.numSubKeys = numSubKeys self.permPerSubkey = permPerSubkey self.numRoundKeys = 0 self.model = model self.getParams().addChildren([ { 'name': 'Hardware Model', 'type': 'list', 'values': self.hwModels, 'get': self.getHwModel, 'set': self.setHwModel }, { 'name': 'Number of SubKeys', 'type': 'int', 'get': self.getNumSubKeys, 'readonly': True }, { 'name': 'Number of Permutations', 'type': 'int', 'get': self.getPermPerSubkey, 'readonly': True }, ])
def __init__(self): self.maxSubKeys = 32 AutoScript.__init__(self) self.useAbs = True #TODO: Where to get this from? self.numsubkeys = 16 self.allPointsSame = True self.startPoint = [0]*self.numsubkeys self.endPoint = [0]*self.numsubkeys self.traceMax = 0 self.traceLimitsChanged = util.Signal() self.setupTraceParam() self.setupPointsParam() self.getParams().addChildren([ {'name':'Hardware Model', 'type':'group', 'children':[ {'name':'Crypto Algorithm', 'key':'hw_algo', 'type':'list', 'values':{'AES-128 (8-bit)':models_AES128_8bit}, 'value':models_AES128_8bit, 'action':self.updateScript}, {'name':'Leakage Model', 'key':'hw_leak', 'type':'list', 'values':models_AES128_8bit.leakagemodels, 'value':'LEAK_HW_SBOXOUT_FIRSTROUND', 'action':self.updateScript}, ]}, {'name':'Take Absolute', 'type':'bool', 'get':self.getAbsoluteMode, 'set':self.setAbsoluteMode}, #TODO: Should be called from the AES module to figure out # of bytes {'name':'Attacked Bytes', 'type':'group', 'children': self.getByteList()}, ]) self.params.append(self.pointsParams) self.params.append(self.traceParams) self.updateBytesVisible()
def __init__(self, num): super(TuningParameter, self).__init__() self._name = 'Tuning Parameter %d' % num self.paramNum = num self.rangeComplete = util.Signal() self.nameChanged = util.Signal() self.tracesreqChanged = util.Signal() self.getParams().addChildren([ {'name':'Name', 'type':'str', 'key':'humanname', 'value':'Param #%d' % num, 'action':lambda p:self.nameChange(p.getValue())}, {'name':'Parameter Path', 'type':'str', 'key':'parampath', 'value':'[]', 'action':self.updateParams}, {'name':'Data Format', 'type':'list', 'key':'datatype', 'values':{'Int':int, 'Float':float}, 'value':int}, {'name':'Range', 'type':'range', 'key':'range', 'limits':(-1E6, 1E6), 'value':(0, 10), 'default':(0, 10), 'action':self.updateParams}, {'name':'Value', 'type':'float', 'key':'curval', 'value':1.0}, {'name':'Step', 'type':'float', 'key':'step', 'value':1.0, 'action':self.updateParams}, {'name':'Repeat', 'type':'int', 'key':'repeat', 'value':1, 'action':self.updateParams}, {'name':'Mode', 'type':'list', 'key':'mode', 'values':["Linear"], 'value':"Linear", 'action':self.updateParams}, ]) self.cnt = 0 self.updateParams()
def __init__(self): self.dataUpdated = util.Signal() self.offset = 0.5 self.ser = None self.sc = None self.parm_hwinfo = None self.parm_gain = None self.parm_trigger = None self.parm_clock = None self.datapoints = []
def __init__(self): self.visaInst = None self.dataUpdated = util.Signal() self.getParams().addChildren([ { 'name': 'X-Scale', 'key': 'xscale', 'type': 'list', 'values': self.xScales, 'value': self.xScales.keys()[0] }, { 'name': 'Y-Scale', 'key': 'yscale', 'type': 'list', 'values': self.yScales, 'value': self.yScales.keys()[0] }, { 'name': 'Y-Offset', 'key': 'yoffset', 'type': 'float', 'step': 1E-3, 'siPrefix': True, 'suffix': 'V', 'value': 0 }, { 'name': 'X-Offset', 'key': 'xoffset', 'type': 'float', 'step': 1E-6, 'siPrefix': True, 'suffix': 'S', 'value': 0 }, { 'name': 'Download Offset', 'key': 'xdisporigin', 'type': 'int', 'limits': (0, 1E9), 'value': 0 }, { 'name': 'Download Size', 'key': 'xdisprange', 'type': 'int', 'limits': (0, 1E9), 'value': 0 }, ])
def __init__(self, scope, target=None, writer=None, auxList=None, keyTextPattern=None): self.sigTraceDone = util.Signal() self.sigNewTextResponse = util.Signal() self.target = target self.scope = scope self.writer = writer self.auxList = auxList self.setKeyTextPattern(keyTextPattern) keyTextPattern.setTarget(target) self.maxtraces = 1 if self.auxList is not None: for aux in auxList: if aux: aux.captureInit()
def __init__(self): self.dataUpdated = util.Signal() self.offset = 0.5 self.ser = None self.sc = None self.parm_hwinfo = None self.parm_gain = None self.parm_trigger = None self.parm_clock = None self.datapoints = [] self.timerStatusRefresh = timer.Timer() self.timerStatusRefresh.timeout.connect(self.statusRefresh)
class ResultsBase(Parameterized): """ Base class for the output widgets: To be uses in conjunct with chipwhisperer.common.utils.analysissource/tracesource """ registeredObjects = util.DictType() sigRegisteredObjectsChanged = util.Signal() __classParameter = None __classes = None def getWidget(self): return None # @classmethod #TODO: Finish this method # def deregister(self, name): # if self.registeredObjects.pop(name, None): # self.sigRegisteredObjectsChanged.emit(None) @classmethod def getClasses(cls): if not cls.__classes: cls.__classes = getPluginsInDictFromPackage( "chipwhisperer.common.results", False, False) return cls.__classes @classmethod def getClassParameter(cls): if not cls.__classParameter: cls.__classParameter = Parameter(name="Results", type='group').register() return cls.__classParameter @classmethod def createNew(cls, className, instanceName=None): # To do it manually using the python console: # from chipwhisperer.common.results.base import ResultsBase # ResultsBase.createNew("Trace Output Plot", "Channel 2") if instanceName in cls.registeredObjects: raise Warning( "Result widget \"%s\" already exists, choose a different name" % instanceName) obj = cls.getClasses()[className](instanceName) cls.registeredObjects[obj.getName()] = obj cls.sigRegisteredObjectsChanged.emit(obj) cls.getClassParameter().append(obj.getParams()) return obj
def __init__(self, numSubKeys, permPerSubkey, model=None): self.sigParametersChanged = util.Signal() self.numSubKeys = numSubKeys self.permPerSubkey = permPerSubkey self.numRoundKeys = 0 self.model = model #Update interal models (if required) self._updateHwModel() if model.name in self.hwModels.keys(): if self.hwModels[model.name] != model: self.hwModels[str(model)] = model else: self.hwModels[model.name] = model self.getParams().addChildren([ {'name':'Hardware Model', 'type':'list', 'values':self.hwModels, 'get':self.getHwModel, 'set':self.setHwModel, 'addToList':True}, {'name':'Number of SubKeys', 'type':'int', 'get':self.getNumSubKeys, 'readonly':True}, {'name':'Number of Permutations', 'type':'int', 'get':self.getPermPerSubkey, 'readonly':True}, ])
def __init__(self, hasHardwareModel=True, hasMultipleRuns=True): self.hasHardwareModel = hasHardwareModel self.hasMultipleRuns = hasMultipleRuns self.maxSubKeys = 32 AutoScript.__init__(self) self.useAbs = True #TODO: Where to get this from? self.numsubkeys = 16 self.allPointsSame = True self.startPoint = [0]*self.numsubkeys self.endPoint = [0]*self.numsubkeys self.traceMax = 0 self.traceLimitsChanged = util.Signal() self.setupTraceParam() self.setupPointsParam() if self.hasHardwareModel: self.getParams().addChildren([ {'name':'Hardware Model', 'type':'group', 'children':[ {'name':'Crypto Algorithm', 'key':'hw_algo', 'type':'list', 'values':{'Keeloq':models_keeloq}, 'value':models_keeloq, 'action':self.updateScript}, {'name':'Leakage Model', 'key':'hw_leak', 'type':'list', 'values':models_keeloq.leakagemodels, 'value':"LEAK_HW_CIPHERTEXT_BIT", 'action':self.updateScript}, ]}, {'name':'Take Absolute', 'type':'bool', 'get':self.getAbsoluteMode, 'set':self.setAbsoluteMode}, # #TODO: Should be called from the AES module to figure out # of bytes # {'name':'Attacked Bytes', 'type':'group', 'children': self.getByteList()}, ]) #self.params.append(self.pointsParams) #self.params.append(self.traceParams) self.updateBytesVisible()
class Parameter(object): """ Basic unity of data (like an attribute of a class) that can accessed in a more uniform way (like using search) and displayed in the screen with advanced widgets if QT+PyQtGraph is supported. Each parameter has a name, a type, a value, and several other properties that modify the behavior. The value can be saved internally to the Parameter or externally, using get/set methods. An action function is called every time the value of the parameter changes. Supported types: "group" - A label with children "list" - A value to be selected between a set of allowed values "label" - Used in the description of Parameterized objects "str", "text" - A smaller and a larger textbox "bool" - A checkbox "action" - A button "int", "float" - A value to be selected between a min and max limit "range", "rangegraph" - An interval and an interval that can be selected using a graph widget (graphwidget option) "file" - A string type with a file dialog button "filelist" - Complex widged with a file list and mangement buttons to add/remove/edit/copy/set active. "color" - Opens a color seletion dialog "menu" - Hiden widget that inserts a new menu option Supported Attributes: "name", "type" - Mandatory attributes "key" - A nickname to make search easier "values" - Allowed set of values (list or dictionary type) "value" - Value saved internally "set", "get" - Value save externally "limits" - Range of allowed values "step" - Increment in SpinBoxes "linked" - Refreshes (calls set(get)) the values in the given list with other parameters "default" - Set the initial value (skips initialization when using set/get) "tip" - Description of the parameter "action" - Calls the provided method with the current paramenter as argument when the value is changed "visible" - Show/hides the parameter "children" - Insert other parameters to be accessed within the current parameter hierarchy "readonly" - Prevents the user of changing its value (it can be forced though) "help" - Text displayed when clicking the help button "graphwidget" - Reference to the graph widget when using parameters with type "rangegraph" 'siPrefix', 'suffix' - Adds prefix and sets the suffix text "psync" - Disable reverse synchronization when calling the set method directly (no decorator needed) "addLoadSave" - Adds load / save settings button to a group parameter ... Examples: self.getParams().addChildren([ {'name':'Redraw after Each', 'type':'bool', 'value':False}, {'name':'Trace Range', 'key':'tracerng', 'type':'range', 'limits':(0, 0), 'value':(0, 0)}, {'name':'Point Range', 'key':'pointrng', 'type':'rangegraph', 'limits':(0, 0), 'value':(0, 0), 'graphwidget':self}, {'name':'Redraw', 'type':'action', 'action':lambda _: self.plotInputTrace()}, {'name':'Y-Offset', 'key':'yoffset', 'type':'float', 'step':1E-3, 'siPrefix': True, 'suffix': 'V'}, {'name':'Update Mode', 'key':'updateMode', 'type':'list', 'values':{'Entire Table (Slow)':'all', 'PGE Only (faster)':'pge'}, 'get':self.getUpdateMode, 'set':self.setUpdateMode}, {'name':'Trace color', 'type':'color', 'value':"0F0", 'action':lambda p: self.setTraceColor(p.getValue())}, {'name':'Draw Type', 'type':'list', 'key':'drawtype', 'values':['Fastest', 'Normal', 'Detailed'], 'value':'Normal', 'help':"Draw Type Help"}, {'name':'CW Firmware Preferences','tip':'Configure ChipWhisperer FW Paths', 'type':"menu", "action":lambda _:self.getFwLoaderConfigGUI.show()}, # "default" means set() is NOT called during init, otherwise set WILL be called to set the default value (read from get()). Can be useful when don't want to read hardware at start-up {'name':'SAD Threshold', 'type':'int', 'limits':(0, 100000), 'default':0, 'set':self.setThreshold, 'get':self.getThreshold} {'name':'Acquisition Settings', 'type':'group', 'children':[ {'name':'Number of Traces', 'type':'int', 'limits':(1, 1E9), 'get':self.getNumTraces, 'set':self.setNumTraces, 'linked':['Traces per Set']}, {'name':'Number of Sets', 'type':'int', 'limits':(1, 1E6), 'get':self.getNumTraceSets, 'set':self.setNumTraceSets, 'linked':['Traces per Set'], 'tip': 'Break acquisition into N sets, ' 'which may cause data to be saved more frequently. The default capture driver requires that NTraces/NSets is small enough to avoid running out of system memory ' 'as each segment is buffered into RAM before being written to disk.'}, {'name':'Traces per Set', 'type':'int', 'readonly':True, 'get':self.tracesPerSet}, ]} ]) """ sigParametersChanged = util.Signal() registeredParameters = {} scriptingOutput = sys.stdout supportedTypes = [ "group", "list", "label", "str", 'text', "bool", "action", "int", "float", "rangegraph", "file", 'filelist', "range", "color", "menu" ] suppertedAttributes = { "name", "key", "type", "values", "value", "set", "get", "limits", "step", "linked", "default", "tip", "action", "visible", "children", "readonly", "graphwidget" } usePyQtGraph = False def __init__(self, parent=None, ignoreChildren=False, **opts): self.sigValueChanged = util.Signal() self.sigLimitsChanged = util.Signal() self.sigOptionsChanged = util.Signal() self.sigChildAdded = util.Signal() self.sigChildRemoved = util.Signal() self.previousValue = None self.parent = parent self.invalid = False self.opts = {"visible": True} self.opts.update(opts) if 'name' not in self.opts or not isinstance(self.opts['name'], basestring): raise Exception("Parameter must have a name.") name = self.opts["name"] if 'type' not in self.opts or not isinstance( self.opts['type'], basestring ) or self.opts['type'] not in Parameter.supportedTypes: raise Exception("Parameter \"%s\" must have a valid string type." % name) # for opt in opts: # if opt not in Parameter.suppertedAttributes: # raise Exception("Parameter \"%s\" has unknown attribute type: %s." % (name, opt)) if self.opts['type'] != 'group': if (('set' in self.opts) or ('get' in self.opts)) and ('value' in self.opts): raise Exception( "Use set/get or value, not both simultaneously in parameter \"%s\". If an action is needed, use the action option." % name) if not ('set' in self.opts or 'get' in self.opts or 'value' in self.opts or 'action' in self.opts or 'linked' in self.opts): raise Exception( "Useless parameter \"%s\" because no set/get/value/action/linked option is defined." % name) if 'set' in self.opts and (not ('get' in self.opts)): raise Exception( "Option set and get should be used together in parameter \"%s\"." % name) if 'get' in self.opts and (not 'set' in self.opts) and ( 'readonly' in self.opts) and self.opts['readonly'] == False: raise Exception( "Parameters \"%s\" has get and no set. Should be marked as readonly." % name) if self.opts.get("type", None) == "list": self.opts['limits'] = opts['values'] if 'set' in self.opts: self.sigValueChanged.connect(self.opts['set']) self.opts['set'] = None if 'get' in self.opts: self.opts['get'] = util.WeakMethod(self.opts['get']) if 'action' in self.opts: self.opts['action'] = util.WeakMethod(self.opts['action']) if "default" not in self.opts: self.opts["default"] = self.getValue() self.setValue(self.opts["default"], init=True) else: if 'addLoadSave' in self.opts and self.opts["addLoadSave"]: self.opts["addLoadSave"] = (self.load, self.save) self.childs = [] self.ignoredChildren = self.opts.pop("children", []) if Parameter.usePyQtGraph and self.opts["type"] != "menu": self.setupPyQtGraphParameter() self.keys = {} if ignoreChildren is False: self.addChildren(self.ignoredChildren) self.ignoredChildren = [] def getName(self): return self.opts["name"] def getType(self): return self.opts["type"] def getTip(self): return self.opts["tip"] def getAction(self): return self.opts["action"] def getOpts(self): return self.opts def getValue(self, default=None): """Return the internal or external value of the parameter""" val = self.opts.get("get", None) if val is None: return self.opts.get("value", default) else: return val() def getKeyFromValue(self, value): """Return the key used to set list type parameters""" if self.opts["type"] == "list": limits = self.opts["limits"] if isinstance(limits, dict): try: return limits.keys()[limits.values().index(value)] except ValueError: ValueError("Error: Value " + value + " is not valid in Parameter \"" + self.getName() + "\". Options are: " + str(limits)) return value def getValueKey(self): """Return the key used to set list type parameters""" return self.getKeyFromValue(self.getValue()) def addChildren(self, children): """Add a list of children to the current paramenter""" addedChildren = [] for child in children: addedChildren.append(Parameter(self, ignoreChildren=True, **child)) self.append(addedChildren[-1]) for child in addedChildren: # Prevent children being added out of order child.addChildren(child.ignoredChildren) child.ignoredChildren = [] def append(self, child): """Add one child""" if child is None: return if child.getName() in self.keys: self.keys[child.getName()].remove() self.keys[child.getName()] = child self.childs.append(child) if 'key' in child.getOpts(): self.keys[child.getOpts()["key"]] = child child.setParent(self) if child.opts["type"] != "menu": self.sigChildAdded.emit(child) self.sigParametersChanged.emit() def setValue(self, value, blockSignal=None, blockAction=False, init=False, ignoreReadonly=False, echo=True, addToList=False): """ Set the parameter value. External values are updated using signals. Arguments: ignoreReadonly - force readonly parameter to be updated. blockSignal - used to prevent already changed valued of being set again, causing infinite loops. blockAction - prevents action callback of being called. init - used internally to initialize the parameter. echo - enables/disables broadcasting the changes. addToList - add given value to list of valid values if not already present """ if not ignoreReadonly and not init and self.readonly(): raise ValueError( "Parameter \"%s\" is currently set to read only." % self.getName()) limits = self.opts.get("limits", None) type = self.opts["type"] if type == "group": return if addToList: newlimits = copy.copy(limits) newlimits[value.getName()] = value self.setLimits(newlimits) elif limits is not None and not self.invalid: if (type == "list" and ((isinstance(limits, dict) and value not in limits.values()) or \ (not isinstance(limits, dict) and value not in limits)) ) or \ (type == "bool" and value not in [True, False]) or \ ((type == "int" or type == "float") and (value < limits[0] or value > limits[1])) or \ (type == "rangegraph" and (value[1] - value[0] != -1) and ( value[0] < limits[0] or value[0] > limits[1] or value[1] < limits[0] or value[1] > limits[1])): if isinstance(limits, dict) and value in limits.keys(): value = limits[value] else: #raise ValueError("Value %s out of limits (%s) in parameter \"%s\"" % (str(value), str(limits), self.getName())) logging.error( "Value %s out of limits (%s) in parameter \"%s\"" % (str(value), str(limits), self.getName())) try: if blockSignal is not None: self.sigValueChanged.disconnect(blockSignal) if "value" in self.opts: self.opts["value"] = value if 'psync' in self.opts and self.opts['psync'] == False: self.sigValueChanged.emit(value) else: self.sigValueChanged.emit(value, blockSignal=self.setValue) finally: if blockSignal is not None: self.sigValueChanged.connect(blockSignal) if self.previousValue is not None and self.previousValue() is not None: self.previousValue().getParams().hide() if isinstance(value, Parameterized): value.getParams().show() self.previousValue = weakref.ref(value) if not init: if not blockAction: self.callAction() if isinstance(limits, dict): for k, v in limits.iteritems(): if v == value: value = k if echo and not self.opts.get("echooff", False) and not self.readonly(): path = self.getPath() if path is not None: print >> Parameter.scriptingOutput, str(path + [value]) + "," def callLinked(self): for name in self.opts.get("linked", []): linked = self.parent.getChild(name) if linked is not None: linked.sigValueChanged.emit(linked.getValue(), blockSignal=None) def callAction(self): act = self.opts.get("action", None) if act is not None: act(self) path = self.getPath() if path is not None: print >> Parameter.scriptingOutput, (str(path + [None]) + ",") self.callLinked() def setDefault(self, default): """Set the default value""" self.opts['default'] = default self.sigOptionsChanged.emit(default=default) def setLimits(self, limits): """Change the limits. Invalid interval limits are hidden.""" self.opts['limits'] = limits type = self.opts["type"] if (type == "int" or type == "float" or type == "rangegraph" or type == "range") and limits[0] > limits[1]: self.invalid = True self.sigOptionsChanged.emit(visible=False) else: self.invalid = False self.sigOptionsChanged.emit(visible=self.isVisible()) self.sigLimitsChanged.emit( limits.keys() if isinstance(limits, dict) else limits) def readonly(self): return self.opts.get('readonly', False) def setReadonly(self, readonly=True): self.opts["readonly"] = readonly self.sigOptionsChanged.emit(readonly=readonly) def hide(self): self.show(False) def show(self, show=True): self.opts['visible'] = show if not self.invalid: self.sigOptionsChanged.emit(visible=show) self.sigParametersChanged.emit() def isVisible(self): return self.opts['visible'] def remove(self): """Detaches the parameter from its parent""" if self.parent is None: return self.parent.removeChild(self) def delete(self): """Deletes itself (makes the GC job easier removing cicles). WARNING: Can't be called again!!!""" self.remove() for c in self.childs: c.delete() self.sigValueChanged.disconnectAll() self.sigLimitsChanged.disconnectAll() self.sigOptionsChanged.disconnectAll() self.sigChildAdded.disconnectAll() self.sigChildRemoved.disconnectAll() if Parameter.usePyQtGraph: # if hasattr(self._PyQtGraphParameter, "sigActivated"): # self._PyQtGraphParameter.sigActivated.disconnect() # self._PyQtGraphParameter.sigValueChanged.disconnect() self._PyQtGraphParameter = None self.deregister() self.previousValue = None self.opts.clear() def clearChildren(self): """Remove all children.""" for ch in self.childs: self.removeChild(ch) def removeChild(self, child): """Remove the specified child.""" if child is None: return self.keys.pop(child.getOpts()["name"]) try: self.keys.pop(child.getOpts()["key"]) except KeyError: pass if child.opts["type"] != "menu": self.sigChildRemoved.emit(child) self.childs.remove(child) child.parent = None self.sigParametersChanged.emit() def getChild(self, nameOrPath): """Return the paramenter child with the given name/path.""" if isinstance(nameOrPath, list) or isinstance(nameOrPath, tuple): item = self.keys.get(nameOrPath[0], None) if len(nameOrPath) == 1 or item is None: return item else: return item.getChild(nameOrPath[1:]) else: try: return self.keys[nameOrPath] except: raise KeyError( "Could not find parameter with key %s. Options are: %s" % (nameOrPath, str(self.keys))) def getPyQtGraphParameter(self): """Return the PyQtGraph Parameter if it exists.""" if hasattr(self, "_PyQtGraphParameter"): return self._PyQtGraphParameter return None def setupPyQtGraphParameter(self): """Creates a PyQtGraph Parameter and keeps it synchronized""" opts = {} opts.update(self.getOpts()) if "default" in self.opts: opts["value"] = opts["default"] if "limits" in self.opts and isinstance(self.opts["limits"], dict): opts['limits'] = opts['limits'].keys() opts["value"] = self.getKeyFromValue(opts["default"]) del opts['values'] self._PyQtGraphParameter = pyqtgraphParameter.create(**opts) if hasattr(self._PyQtGraphParameter, "sigActivated"): self._PyQtGraphParameter.sigActivated.connect(self.callAction) self.sigChildRemoved.connect(lambda c: self._PyQtGraphParameter. removeChild(c.getPyQtGraphParameter())) self.sigChildAdded.connect(lambda c: self._PyQtGraphParameter.addChild( c.getPyQtGraphParameter())) sigValueUpdatedAdapter = lambda _, v: self.setValue( v, sigSetValueAdapter) self._PyQtGraphParameter.sigValueChanged.connect( sigValueUpdatedAdapter) sigSetValueAdapter = lambda v, blockSignal=None: self._PyQtGraphParameter.setValue( self.getKeyFromValue(v), sigValueUpdatedAdapter) self.sigValueChanged.connect(sigSetValueAdapter) self.sigLimitsChanged.connect(self._PyQtGraphParameter.setLimits) self.sigOptionsChanged.connect(self._PyQtGraphParameter.setOpts) def setParent(self, parent): self.parent = parent def getRoot(self): """Return the root Parameter.""" return self if self.parent is None else self.parent.getRoot() def getPath(self): """Return the path to the root.""" if self in Parameter.registeredParameters.values(): path = [] elif self.parent is None: return None else: path = self.parent.getPath() if path is not None: path.append(self.opts["name"]) return path def stealDynamicParameters(self, parent): """In list type parameters, append each of the Parameterized objects to the parent argument.""" if self.opts.get("type", None) == "list" and isinstance( self.opts["values"], dict): for value in self.opts["values"].itervalues(): if isinstance(value, Parameterized): parent.append(value.getParams()) value.getParams().show(self.getValue() == value) def refreshAllParameters(self): """ Refreshes (calls set(get()) ) all the parameters in the hierarchy. In list type parameters, append each of the Parameterized objects to the parent, root or child hierarchy. """ if self.opts.get("type", None) == "list" and isinstance( self.opts["values"], dict): for value in self.opts["values"].itervalues(): if isinstance(value, Parameterized): mode = self.opts.get("childmode", None) if mode == "parent": self.parent.append(value.getParams()) value.getParams().hide() elif mode == "root": # Warning, this path is relative... can't call init more than once and sub-modules can't repeat name self.getRoot().append(value.getParams()) value.getParams().hide() elif mode == "child": self.append(value.getParams()) self.setValue(self.getValue(), init=True) for child in self.childs: child.refreshAllParameters() def init(self): self.refreshAllParameters() def _getAllParameters(self, type=None): ret = [] if self.isVisible(): if self.opts.get("type", None) == type or type == None: ret.append(self) for child in self.childs: ret.extend(child._getAllParameters(type)) return ret @classmethod def getAllParameters(cls, type=None): """Return a list with all parameters with a given type in the hierarchy.""" ret = [] for p in cls.registeredParameters.itervalues(): parameters = p._getAllParameters(type) [ret.append(param) for param in parameters if param not in ret] return ret def register(self): """Makes it accessible from the root when calling setParameter()""" Parameter.registeredParameters[self.getName()] = self return self def deregister(self): """Deregister a registered parameter. Ignores if it is already deregistered.""" Parameter.registeredParameters.pop(self.getName(), None) def toString(self, level, onlyVisibles=False): lastLevel = level ret = "" if self.getType() != "group" and self.getType( ) != "action" and self.getType() != "menu" and self.getType( ) != "label": if (onlyVisibles and self.isVisible()) or not (onlyVisibles or self.readonly()): ret += self.getName() + " = " + str(self.getValueKey()) + "\n" if not onlyVisibles or self.isVisible(): for child in self.childs: if lastLevel != level + 1: ret += ("[" * (level + 1)) + self.getName() + ( "]" * (level + 1)) + "\n" lastLevel = level + 1 try: txt, lastLevel = child.toString(lastLevel, onlyVisibles) ret += txt except: logging.info( 'Info: Could not read parameter %s. Ignoring it...' % str(child.getPath())) pass return ret, lastLevel def __str__(self): txt, _ = self.toString(0) return txt def save(self, fname, onlyVisibles=False): f = open(fname, 'w') txt, _ = self.toString(0, onlyVisibles=False) f.write(txt) @classmethod def saveRegistered(cls, fname, onlyVisibles=False): f = open(fname, 'w') for p in cls.registeredParameters.itervalues(): if 'addLoadSave' in p.opts and p.opts['addLoadSave'] is not False: txt, _ = p.toString(0, onlyVisibles) f.write(txt) def load(self, fname): f = open(fname, 'r') path = [] foundCorrectSection = False for lineNum, line in enumerate(f): level = 0 for p in range(0, len(line)): if line[p] == "[": level += 1 else: break if level != 0: path = path[0:level - 1] if level >= len(path): if level > len(path) + 1: raise Warning( 'Error reading file %s, line %d. Group hierarchy missing.' % (fname, lineNum)) path.append(line[level:-(level + 1)]) else: if path[0] != self.getName(): continue foundCorrectSection = True separator = line.find("=") value = line[separator + 1:-1].strip() param = path[1:] + [line[0:separator].strip()] child = self.getChild(param) if child is None: logging.warning( 'Parameter "%s" in line %d not found. Ignoring it.' % (str(param), lineNum)) continue if child.getType() == "int": value = int(value) elif child.getType() == "float": value = float(value) elif child.getType() == "menu" or child.getType( ) == "label" or child.getType() == "color": continue elif child.getType() == "str" or child.getType() == "text" or child.getType() == "action" or \ child.getType() == "file" or child.getType() == "filelist": pass elif child.getType() == "list" and isinstance( child.opts["limits"], dict): value = child.opts["limits"][value] elif value != "": try: value = eval(value) except: pass if not child.readonly(): child.setValue(value) else: if str(child.getValue()) != str(value): logging.info( 'Parameter %s in line %d is readonly and value being set is different than the current one.' % (child.getName(), lineNum)) if not foundCorrectSection: raise Warning('Could not found section "%s" in file: %s' % (self.getName(), fname)) @classmethod def findParameter(cls, path): """ Find a registered parameter based on a list (used for scripting). """ child = cls.registeredParameters.get(path[0], None) if child is None: raise KeyError("Parameter not found: %s" % str(path)) if len(path) > 1: return child.getChild(path[1:]) else: return child @classmethod def getParameter(cls, path): """Return the value of a registered parameter""" return cls.findParameter(path).getValueKey() @classmethod def setParameter(cls, parameter, echo=False, blockSignal=False): """ Sets a parameter based on a list (used for scripting). The first elements are the path and the last is the value. """ path = parameter[:-1] value = parameter[-1] child = cls.findParameter(path) if isinstance(child.getOpts().get("values", None), dict): try: value = child.getOpts()["values"][value] except KeyError: raise ValueError( "Invalid value '%s' for parameter '%s'.\nValid values: %s" % (value, str(parameter), child.getOpts()["values"].keys())) child.setValue(value, echo=echo)
def __init__(self, parent=None, ignoreChildren=False, **opts): self.sigValueChanged = util.Signal() self.sigLimitsChanged = util.Signal() self.sigOptionsChanged = util.Signal() self.sigChildAdded = util.Signal() self.sigChildRemoved = util.Signal() self.previousValue = None self.parent = parent self.invalid = False self.opts = {"visible": True} self.opts.update(opts) if 'name' not in self.opts or not isinstance(self.opts['name'], basestring): raise Exception("Parameter must have a name.") name = self.opts["name"] if 'type' not in self.opts or not isinstance( self.opts['type'], basestring ) or self.opts['type'] not in Parameter.supportedTypes: raise Exception("Parameter \"%s\" must have a valid string type." % name) # for opt in opts: # if opt not in Parameter.suppertedAttributes: # raise Exception("Parameter \"%s\" has unknown attribute type: %s." % (name, opt)) if self.opts['type'] != 'group': if (('set' in self.opts) or ('get' in self.opts)) and ('value' in self.opts): raise Exception( "Use set/get or value, not both simultaneously in parameter \"%s\". If an action is needed, use the action option." % name) if not ('set' in self.opts or 'get' in self.opts or 'value' in self.opts or 'action' in self.opts or 'linked' in self.opts): raise Exception( "Useless parameter \"%s\" because no set/get/value/action/linked option is defined." % name) if 'set' in self.opts and (not ('get' in self.opts)): raise Exception( "Option set and get should be used together in parameter \"%s\"." % name) if 'get' in self.opts and (not 'set' in self.opts) and ( 'readonly' in self.opts) and self.opts['readonly'] == False: raise Exception( "Parameters \"%s\" has get and no set. Should be marked as readonly." % name) if self.opts.get("type", None) == "list": self.opts['limits'] = opts['values'] if 'set' in self.opts: self.sigValueChanged.connect(self.opts['set']) self.opts['set'] = None if 'get' in self.opts: self.opts['get'] = util.WeakMethod(self.opts['get']) if 'action' in self.opts: self.opts['action'] = util.WeakMethod(self.opts['action']) if "default" not in self.opts: self.opts["default"] = self.getValue() self.setValue(self.opts["default"], init=True) else: if 'addLoadSave' in self.opts and self.opts["addLoadSave"]: self.opts["addLoadSave"] = (self.load, self.save) self.childs = [] self.ignoredChildren = self.opts.pop("children", []) if Parameter.usePyQtGraph and self.opts["type"] != "menu": self.setupPyQtGraphParameter() self.keys = {} if ignoreChildren is False: self.addChildren(self.ignoredChildren) self.ignoredChildren = []
def __init__(self, name="Unknown"): self.sigTracesChanged = util.Signal() self.name = name
def __init__(self): self.newTextLog = util.Signal()
def __init__(self): self.newTextLog = util.Signal() self._scope = None
def __init__(self): self.scriptsUpdated = util.Signal() self.runScriptFunction = util.Signal() self.autoScriptInit()
def __init__(self): self.newInputData = util.Signal() self.connectStatus = util.Observable(False) self.getParams().register()
class TraceSource(object): """ It has traces as output Keeps a dictionary with all the registered objets and emits a signal when a new one is added """ registeredObjects = util.DictType() registeredObjects["None"] = None sigRegisteredObjectsChanged = util.Signal() def __init__(self, name="Unknown"): self.sigTracesChanged = util.Signal() self.name = name self.uuid = str(uuid.uuid4()) def getTrace(self, n): """Return the trace with number n in the current TraceSource object""" return None def numPoints(self): return 0 def numTraces(self): return 0 def offset(self): return 0 def getSampleRate(self): """Return the Sample Rate used to generate the traces""" return 0 def getTextin(self, n): """Get text-in number n""" raise NotImplementedError def getTextout(self, n): """Get text-out number n""" raise NotImplementedError def getKnownKey(self, n=None): """Get known-key number n""" raise NotImplementedError def getSegmentList(self): """Return a list of segments.""" raise NotImplementedError def getAuxData(self, n, auxDic): """Return data about a segment""" raise NotImplementedError def getSegment(self, n): """Return the trace segment with the specified trace in the list with all enabled segments.""" raise NotImplementedError def register(self): """Register the current TraceSource object in a list and emit a signal to inform it was updated""" self.registeredObjects[self.name] = self self.sigRegisteredObjectsChanged.emit() return self def deregister(self): """Deregister the current TraceSource and emit a signal to inform this event""" try: #Only deregister if UUID matches (NB: don't use direct comparison in case later we adjust repr() ) if TraceSource.registeredObjects[self.name].uuid == self.uuid: if TraceSource.registeredObjects.pop(self.name, None): TraceSource.sigRegisteredObjectsChanged.emit() except KeyError: pass @classmethod def deregisterObject(cls, name, uuid = None): """Deregister the TraceSource and emit a signal to inform this event""" try: if (uuid is None) or (cls.registeredObjects[name].uuid == uuid): if cls.registeredObjects.pop(name, None): cls.sigRegisteredObjectsChanged.emit() except KeyError: pass
def __init__(self): self.sigAnalysisStarted = util.Signal() self.sigAnalysisUpdated = util.Signal() self.sigAnalysisDone = util.Signal()
def __init__(self, name="Unknown"): self.sigTracesChanged = util.Signal() self.name = name self.uuid = str(uuid.uuid4())
class TemplateBasic(AutoScript, PassiveTraceObserver): """ Template using Multivariate Stats (mean + covariance matrix) """ scriptsUpdated = util.Signal() def __init__(self): AutoScript.__init__(self) PassiveTraceObserver.__init__(self) self.getParams().getChild("Input").hide() def setProject(self, proj): self._project = proj def project(self): return self._project def generate(self, trange, poiList, partMethod, progressBar=None): """Generate templates for all partitions over entire trace range""" # Number of subkeys subkeys = len(poiList) numPartitions = partMethod.getNumPartitions() tstart = trange[0] tend = trange[1] templateTraces = [[[] for j in range(0, numPartitions)] for i in range(0, subkeys)] templateMeans = [ np.zeros((numPartitions, len(poiList[i]))) for i in range(0, subkeys) ] templateCovs = [ np.zeros((numPartitions, len(poiList[i]), len(poiList[i]))) for i in range(0, subkeys) ] # partData = generatePartitions(self, partitionClass=None, saveFile=False, loadFile=False, traces=None) # partData = partObj.loadPartitions(trange) if progressBar: progressBar.setText('Generating Trace Matrix:') progressBar.setMaximum(tend - tstart + subkeys) for tnum in range(tstart, tend): # partData = self.getTraceSource().getAuxData(tnum, self.partObject.attrDictPartition)["filedata"] pnum = partMethod.getPartitionNum(self.getTraceSource(), tnum) t = self.getTraceSource().getTrace(tnum) for bnum in range(0, subkeys): templateTraces[bnum][pnum[bnum]].append(t[poiList[bnum]]) if progressBar: progressBar.updateStatus(tnum - tstart) if progressBar.wasAborted(): return None if progressBar: progressBar.setText( 'Generating Trace Covariance and Mean Matrices:') for bnum in range(0, subkeys): for i in range(0, numPartitions): templateMeans[bnum][i] = np.mean(templateTraces[bnum][i], axis=0) cov = np.cov(templateTraces[bnum][i], rowvar=0) if __debug__: logging.debug('templateTraces[%d][%d] = %d' % (bnum, i, len(templateTraces[bnum][i]))) if len(templateTraces[bnum][i]) > 0: templateCovs[bnum][i] = cov else: logging.warning( 'Insufficient template data to generate covariance matrix for bnum=%d, partition=%d' % (bnum, i)) templateCovs[bnum][i] = np.zeros( (len(poiList[bnum]), len(poiList[bnum]))) if progressBar: progressBar.updateStatus(tend + bnum) if progressBar.wasAborted(): return None self.template = { "mean": templateMeans, "cov": templateCovs, "trange": (tstart, tend), "poi": poiList, "partitiontype": partMethod.__class__.__name__ } if progressBar: progressBar.close() return self.template