class CutflowDecision: def __init__(self, cutflow): if isinstance(cutflow, CutflowDecision): self._cutflow = OrderedDict(cutflow._cutflow) else: self._cutflow = OrderedDict(cutflow) #just need functions and flags for this for key in self._cutflow.keys(): self._cutflow[key] = self._cutflow[key][:2] + [False] #print self._cutflow def __getitem__(self, idx): return self._cutflow[idx][-1] def __call__(self, event, index=-1): #print 'object index:',index for item in self._cutflow.itervalues(): args = [] for arg in item[1]: argv = getattr(event, arg) if index > -1 and not isinstance(argv, (int, float, bool, long)): args.append(argv[index]) else: args.append(argv) #print index, item[1], args #print 'calling %s with values:'%(item[0]),args item[-1] = bool(item[0](*tuple(args))) def __nonzero__(self): for item in self._cutflow.itervalues(): if not item[-1]: return False return True #take the modulus of the current value of the cut def __mod__(self, cuts): for key, item in self._cutflow.iteritems(): if key not in cuts and not item[-1]: return False return True #cuts is a list of names or an ordereddict def __sub__(self, cuts): cutflow = [] if isinstance(cuts, (list, OrderedDict)): for key in self._cutflow.keys(): if key not in cuts: cutflow.append([key, [self._cutflow[key]]]) return CutflowDecision(cutflow) #cuts is a list as mentioned in the class comment or an ordered dict def __add__(self, cuts): cutflow = OrderDict(self._cutflow) if isinstance(cuts, (list, OrderedDict)): cutflow += OrderedDict(cuts) return CutflowDecision(cutflow)
class CutflowDecision: def __init__(self,cutflow): if isinstance(cutflow,CutflowDecision): self._cutflow = OrderedDict(cutflow._cutflow) else: self._cutflow = OrderedDict(cutflow) #just need functions and flags for this for key in self._cutflow.keys(): self._cutflow[key] = self._cutflow[key][:2] + [False] #print self._cutflow def __getitem__(self,idx): return self._cutflow[idx][-1] def __call__(self,event,index=-1): #print 'object index:',index for item in self._cutflow.itervalues(): args = [] for arg in item[1]: argv = getattr(event,arg) if index > -1 and not isinstance(argv,(int,float,bool,long)): args.append(argv[index]) else: args.append(argv) #print index, item[1], args #print 'calling %s with values:'%(item[0]),args item[-1] = bool(item[0](*tuple(args))) def __nonzero__(self): for item in self._cutflow.itervalues(): if not item[-1]: return False return True #take the modulus of the current value of the cut def __mod__(self,cuts): for key,item in self._cutflow.iteritems(): if key not in cuts and not item[-1]: return False return True #cuts is a list of names or an ordereddict def __sub__(self,cuts): cutflow = [] if isinstance(cuts,(list,OrderedDict)): for key in self._cutflow.keys(): if key not in cuts: cutflow.append([key,[self._cutflow[key]]]) return CutflowDecision(cutflow) #cuts is a list as mentioned in the class comment or an ordered dict def __add__(self,cuts): cutflow = OrderDict(self._cutflow) if isinstance(cuts,(list,OrderedDict)): cutflow += OrderedDict(cuts) return CutflowDecision(cutflow)
class TFCheckBox(widgetState,QWidget): def __init__(self,widget,label = None, displayLabel= True, setChecked=False, orientation='vertical',callback = None, **kwargs): kwargs.setdefault('includeInReports', True) kwargs.setdefault('sizePolicy', QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)) QWidget.__init__(self,widget) widgetState.__init__(self,widget,label,**kwargs) self.controlArea.layout().addWidget(self) self.box = widgetBox(self.controlArea,orientation=orientation) self.controlArea.layout().setAlignment(Qt.AlignTop | Qt.AlignLeft) self.box.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)) # if orientation=='vertical': # self.box.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, # QSizePolicy.MinimumExpanding)) # else: # self.box.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding, # QSizePolicy.Preferred)) self.label = label self.items = OrderedDict() self.buttons = QButtonGroup(self.box) self.buttons.setExclusive(False) self.addButton('TRUE', label) if callback: QObject.connect(self.buttons, SIGNAL('buttonClicked(int)'), callback) if setChecked: self.setChecked('TRUE') def addButton(self,id, text): """Internal function that adds the TRUE button. Please use the checkBox widget if you want to do this""" self.items[id] = text w = QCheckBox(text) self.buttons.addButton(w,self.items.keys().index(id)) self.box.layout().addWidget(w) def setSizePolicy(self, h,w): # self.controlArea.setSizePolicy(h,w) # QWidget.setSizePolicy(self,h,w) self.box.setSizePolicy(h,w) def setChecked(self,ids): for i in self.buttons.buttons(): id = self.buttons.id(i) if unicode(self.items.keys()[id]) in ids: i.setChecked(True) else: i.setChecked(False) def checked(self): """Returns a string of either TRUE if checked or FALSE if not checked. Formatted for direct addition into an R string call.""" if 'TRUE' in self.getCheckedIds(): return 'TRUE' else: return 'FALSE' def getChecked(self): return self.getCheckedItems().values() # checked = [] # for i in self.buttons.buttons(): # if i.isChecked(): checked.append(unicode(i.text())) # return checked def getCheckedIds(self): return self.getCheckedItems().keys() # checked = [] # for i in self.buttons.buttons(): # if i.isChecked(): checked.append(self.items.keys()[i.id()]) # return checked def getCheckedItems(self): checked = {} for i in self.buttons.buttons(): id = self.buttons.id(i) if i.isChecked(): checked[self.items.keys()[id]] = self.items[self.items.keys()[id]] return checked def getUnchecked(self): unChecked = [] for i in self.buttons.buttons(): if not i.isChecked(): unChecked.append(unicode(i.text())) return unChecked def buttonAt(self,ind): return unicode(self.buttons.button(ind).text()) def getSettings(self): #print _('radioButtons getSettings') + self.getChecked() r = {'items':self.items, 'checked': self.getCheckedIds()} return r def loadSettings(self,data): #print _('radioButtons loadSettings') + data #self.addButtons(data['items']) self.setChecked(data['checked']) def getReportText(self, fileDir): selected = self.getChecked() if len(selected): text='Checked: ' + ', '.join(selected) else: text= _('Nothing Checked') r = {self.widgetName:{'includeInReports': self.includeInReports, 'text': text}} # print '@@@@@@@@@@@@@@@@@@@@@@@', r #t = 'The following items were checked in %s:\n\n%s\n\n' % (self.label, self.getChecked()) return r
class taskdef(object): def __init__( self, name ): if re.search( '[^0-9a-zA-Z_\.]', name ): # dot for namespace syntax (NOT USED). # regex [\w] allows spaces. raise DefinitionError, "ERROR: Illegal task name: " + name self.name = name self.type = 'free' self.job_submit_method = None self.job_submission_shell = None self.job_submit_command_template = None self.job_submit_log_directory = None self.job_submit_share_directory = None self.job_submit_work_directory = None self.manual_messaging = False self.modifiers = [] self.asyncid_pattern = None self.cycling = False self.is_coldstart = False self.remote_host = None self.owner = None self.remote_shell_template = None self.remote_cylc_directory = None self.remote_suite_directory = None self.remote_log_directory = None self.reset_timer = False self.event_handlers = {} self.timeouts = {} self.resurrectable = False self.intercycle = False self.cyclers = [] self.logfiles = [] self.description = ['Task description has not been completed' ] self.follow_on_task = None self.clocktriggered_offset = None # triggers[0,6] = [ A, B:1, C(T-6), ... ] self.triggers = OrderedDict() # cond[6,18] = [ '(A & B)|C', 'C | D | E', ... ] self.cond_triggers = OrderedDict() self.outputs = [] # list of explicit internal outputs; change to # OrderedDict() if need to vary per cycle. self.loose_prerequisites = [] # asynchronous tasks self.command = None self.retry_delays = deque() self.precommand = None self.postcommand = None self.initial_scripting = None self.enviro_scripting = None self.ssh_messaging = False self.environment = OrderedDict() # var = value self.directives = OrderedDict() # var = value self.namespace_hierarchy = [] self.sim_mode_run_length = None self.fail_in_sim_mode = False def add_trigger( self, trigger, cycler ): if cycler not in self.triggers: self.triggers[ cycler ] = [] self.triggers[cycler].append(trigger) def add_conditional_trigger( self, triggers, exp, cycler ): if cycler not in self.cond_triggers: self.cond_triggers[ cycler ] = [] self.cond_triggers[ cycler ].append( [triggers,exp] ) def add_to_valid_cycles( self, cyclr ): if len( self.cyclers ) == 0: self.cyclers = [cyclr] else: self.cyclers.append( cyclr ) def time_trans( self, strng, hours=False ): # Time unit translation. # THIS IS NOT CURRENTLY USED, but may be useful in the future. # translate a time of the form: # x sec, y min, z hr # into float MINUTES or HOURS, if not re.search( '^\s*(.*)\s*min\s*$', strng ) and \ not re.search( '^\s*(.*)\s*sec\s*$', strng ) and \ not re.search( '^\s*(.*)\s*hr\s*$', strng ): print >> sys.stderr, "ERROR: missing time unit on " + strng sys.exit(1) m = re.search( '^\s*(.*)\s*min\s*$', strng ) if m: [ mins ] = m.groups() if hours: return str( float( mins / 60.0 ) ) else: return str( float(mins) ) m = re.search( '^\s*(.*)\s*sec\s*$', strng ) if m: [ secs ] = m.groups() if hours: return str( float(secs)/3600.0 ) else: return str( float(secs)/60.0 ) m = re.search( '^\s*(.*)\s*hr\s*$', strng ) if m: [ hrs ] = m.groups() if hours: #return str( float(hrs) ) return float(hrs) else: #return str( float(hrs)*60.0 ) return float(hrs)*60.0 def get_task_class( self ): # return a task proxy class definition, to be used for # instantiating objects of this particular task class. base_types = [] for foo in self.modifiers + [self.type]: # __import__() keyword args were introduced in Python 2.5 #mod = __import__( 'cylc.task_types.' + foo, fromlist=[foo] ) mod = __import__( 'cylc.task_types.' + foo, globals(), locals(), [foo] ) base_types.append( getattr( mod, foo ) ) tclass = type( self.name, tuple( base_types), dict()) tclass.name = self.name # TO DO: NOT NEEDED, USED class.__name__ tclass.instance_count = 0 tclass.upward_instance_count = 0 tclass.description = self.description tclass.elapsed_times = [] tclass.mean_total_elapsed_time = None tclass.event_handlers = self.event_handlers tclass.timeouts = self.timeouts tclass.reset_timer =self.reset_timer tclass.resurrectable = self.resurrectable tclass.remote_host = self.remote_host tclass.owner = self.owner tclass.remote_shell_template = self.remote_shell_template tclass.remote_cylc_directory = self.remote_cylc_directory tclass.remote_suite_directory = self.remote_suite_directory tclass.remote_log_directory = self.remote_log_directory tclass.job_submit_method = self.job_submit_method tclass.job_submission_shell = self.job_submission_shell tclass.job_submit_command_template = self.job_submit_command_template tclass.job_submit_log_directory = self.job_submit_log_directory tclass.job_submit_share_directory = self.job_submit_share_directory tclass.job_submit_work_directory = self.job_submit_work_directory tclass.manual_messaging = self.manual_messaging tclass.intercycle = self.intercycle tclass.follow_on = self.follow_on_task tclass.namespace_hierarchy = self.namespace_hierarchy def tclass_add_prerequisites( sself, startup, cycler, tag ): # NOTE: Task objects hold all triggers defined for the task # in all cycling graph sections in this data structure: # self.triggers[cycler] = [list of triggers for this cycler] # The list of triggers associated with cyclerX will only be # used by a particular task if the task's cycle time is a # valid member of cyclerX's sequence of cycle times. # 1) non-conditional triggers pp = plain_prerequisites( sself.id ) sp = plain_prerequisites( sself.id ) lp = loose_prerequisites( sself.id ) for cyc in self.triggers: for trig in self.triggers[ cyc ]: if trig.startup and not startup: continue if trig.cycling and not cyc.valid( ct(sself.tag) ): # This trigger is not used in current cycle. # (see NOTE just above) ##DEBUGGING: ##print >> sys.stderr, sself.name + ': this trigger not used for', sself.tag + ':' ##print >> sys.stderr, ' ', trig.get(sself.tag, cyc) continue # NOTE that if we need to check validity of async # tags, async tasks can appear in cycling sections # in which case cyc.valid( at(sself.tag)) will fail. if trig.async_repeating: lp.add( trig.get( tag, cycler )) else: if trig.suicide: sp.add( trig.get( tag, cycler )) else: pp.add( trig.get( tag, cycler )) sself.prerequisites.add_requisites( pp ) sself.prerequisites.add_requisites( lp ) sself.suicide_prerequisites.add_requisites( sp ) # 2) conditional triggers for cyc in self.cond_triggers.keys(): for ctrig, exp in self.cond_triggers[ cyc ]: foo = ctrig.keys()[0] if ctrig[foo].startup and not startup: continue if ctrig[foo].cycling and not cyc.valid( ct(sself.tag)): # This trigger is not valid for current cycle. # (see NOTE just above) ##DEBUGGING: ##print >> sys.stderr, sself.name + ': this trigger not used for', sself.tag + ':' ##print >> sys.stderr, ' ', trig.get(sself.tag, cyc) continue # NOTE that if we need to check validity of async # tags, async tasks can appear in cycling sections # in which case cyc.valid( at(sself.tag)) will fail. cp = conditional_prerequisites( sself.id ) for label in ctrig: trig = ctrig[label] cp.add( trig.get( tag, cycler ), label ) cp.set_condition( exp ) if ctrig[foo].suicide: sself.suicide_prerequisites.add_requisites( cp ) else: sself.prerequisites.add_requisites( cp ) tclass.add_prerequisites = tclass_add_prerequisites # class init function def tclass_init( sself, start_tag, initial_state, stop_c_time=None, startup=False ): sself.cycon = container.cycon( self.cyclers ) if self.cycling: # and startup: # adjust only needed at start-up but it does not hurt to # do it every time as after the first adjust we're already # on-cycle. sself.tag = sself.cycon.initial_adjust_up( start_tag ) else: sself.tag = start_tag sself.c_time = sself.tag sself.id = sself.name + '%' + sself.tag sself.asyncid_pattern = self.asyncid_pattern sself.initial_scripting = self.initial_scripting sself.enviro_scripting = self.enviro_scripting sself.ssh_messaging = self.ssh_messaging sself.command = self.command sself.sim_mode_run_length = self.sim_mode_run_length sself.fail_in_sim_mode = self.fail_in_sim_mode # deepcopy retry delays: the deque gets pop()'ed in the task # proxy objects, which is no good if all instances of the # same task class reference the original deque! sself.retry_delays = deepcopy(self.retry_delays) sself.precommand = self.precommand sself.postcommand = self.postcommand if 'clocktriggered' in self.modifiers: sself.real_time_delay = float( self.clocktriggered_offset ) # prerequisites sself.prerequisites = prerequisites() sself.suicide_prerequisites = prerequisites() sself.add_prerequisites( startup, sself.cycon, sself.tag ) sself.logfiles = logfiles() for lfile in self.logfiles: sself.logfiles.add_path( lfile ) # outputs sself.outputs = outputs( sself.id ) for outp in self.outputs: msg = outp.get( sself.tag ) if not sself.outputs.exists( msg ): sself.outputs.add( msg ) sself.outputs.register() sself.env_vars = OrderedDict() for var in self.environment: val = self.environment[ var ] sself.env_vars[ var ] = val sself.directives = OrderedDict() for var in self.directives: val = self.directives[ var ] sself.directives[ var ] = val if 'catchup_clocktriggered' in self.modifiers: catchup_clocktriggered.__init__( sself ) if stop_c_time: # cycling tasks with a final cycle time set super( sself.__class__, sself ).__init__( initial_state, stop_c_time ) else: # TO DO: TEMPORARY HACK FOR ASYNC sself.stop_c_time = '99991231230000' super( sself.__class__, sself ).__init__( initial_state ) sself.reconfigure_me = False sself.is_coldstart = self.is_coldstart tclass.__init__ = tclass_init return tclass
class MagnetWrapper(DeviceWrapper): def connect(self, nodeName, cxn): print 'Connect: %s' % nodeName self.cxn = cxn self.ctxt = self.cxn.context() self.nodeName = nodeName # state variables of this object self.status = 'Missing Devices' self.setCurrent = Value(NaN, 'A') self.voltageLimit = VOLTAGE_LIMIT_DEFAULT self.temperatureOverride = False # if True, ignore temperature checks self.sensingMode = True # devices we must link to self.devs = OrderedDict() self.devs[POWER] = { 'server': None, 'values': [NaN] * len(POWER_SETTINGS), 'status': 'not initialized', 'settings': POWER_SETTINGS, 'extras': ['output'] } self.devs[DMM] = { 'server': None, 'values': [NaN] * len(DMM_SETTINGS), 'status': 'not initialized', 'settings': DMM_SETTINGS, 'gpib address': 24, 'init funcs': ['configure_voltage'] } self.devs[DC] = { 'server': None, 'values': [NaN] * len(DC_SETTINGS), 'status': 'not initialized', 'settings': DC_SETTINGS, 'extras': [ 'output', 'persistent_switch_mode', 'persistent_switch_time_elapsed' ] } self.devs[TEMPERATURE] = { 'server': None, 'values': [NaN] * len(TEMPERATURE_SETTINGS), 'status': 'not initialized', 'settings': TEMPERATURE_SETTINGS, 'flatten': True, 'pickOneValue': 1 } self.devs[DMM2] = { 'server': None, 'values': [NaN] * len(DMM2_SETTINGS), 'status': 'not initialized', 'settings': DMM2_SETTINGS, 'gpib address': 27, } # Persistent Switch self.psHeated = None # T/F for switch heated or not self.psCurrent = NaN * A # current when switch was cooled/closed self.psTime = 0 # time since switch state was last changed self.psRequestedState = None # None=leave as is, T = heated, F = cooled self.psStatus = 'Not started' # DV logging stuff self.dv = None self.dvName = None self.dvRecordDelay = 5 # record every X seconds self.dvLastTimeRecorded = 0 self.dvStatus = 'Not started' # the main loop stuff self.timeInterval = 0.2 self.loop = LoopingCall(self.mainLoop) self.loopDone = self.loop.start(self.timeInterval, now=True) print 'loop started' @inlineCallbacks def shutdown(self): self.loop.stop() yield self.loopDone @inlineCallbacks def mainLoop(self): #print 'loop executing' # do our updates asynch defers = [self.doDevice(dev) for dev in self.devs.keys()] for defer in defers: yield defer # do we have all devices? if not ('OK' == self.devs[POWER]['status'] and 'OK' == self.devs[DMM]['status'] and 'OK' == self.devs[DC]['status'] and 'OK' == self.devs[TEMPERATURE]['status']): # if not, update status, do nothing self.status = 'Missing Devices' else: # if so, do stuff # check the temperature if self.checkTemperature(): try: # if we don't have a current setpoint, set it to the setpoint of the power supply if math.isnan(self.setCurrent ) and self.devs[POWER]['status'] == 'OK': self.current(self.devs[POWER]['values'][0]) # see about a mag #yield self.doMagCycle() self.doMagCycle() self.status = 'OK' except Exception as e: print "Exception in main loop: %s" % str(e) else: # we are over temperature # shut down the magnet if it's running if self.devs[POWER]['status'] == 'OK' and abs( self.devs[POWER]['values'][0]) > CURRENT_RESOLUTION: self.devs[POWER]['server'].shut_off( context=self.devs[POWER]['context']) self.current(0 * A) self.status = 'Over Temperature' try: # record data self.doDataVault() except Exception as e: print "Exception in data vault" try: # persistent switch self.doPersistentSwitch() except Exception as e: print "Exception in persistent switch" @inlineCallbacks def doDevice(self, dev): # do we need a server? if so, connect to it if not self.devs[dev]['server'] and SERVERS[dev] in self.cxn.servers: self.devs[dev]['server'] = self.cxn[SERVERS[dev]] self.devs[dev]['context'] = self.devs[dev]['server'].context() # do we have a server? if so, get our data if self.devs[dev]['server']: # build packet out of requested settings p = self.devs[dev]['server'].packet() for s in self.devs[dev]['settings']: p[s](key=s) if 'extras' in self.devs[dev].keys(): for s in self.devs[dev]['extras']: p[s](key=s) try: # try to get our data ans = yield p.send(context=self.devs[dev]['context']) self.devs[dev]['values'] = [ ans[s] for s in self.devs[dev]['settings'] ] # couple of special cases if 'flatten' in self.devs[dev].keys(): self.devs[dev]['values'] = [ item for sublist in self.devs[dev]['values'] for item in sublist ] if 'pickOneValue' in self.devs[dev].keys(): self.devs[dev]['values'] = [ self.devs[dev]['values'][self.devs[dev] ['pickOneValue']] ] if 'pickSubset' in self.devs[dev].keys(): self.devs[dev]['values'] = [ self.devs[dev]['values'][x] for x in self.devs[dev]['pickSubset'] ] if 'extras' in self.devs[dev].keys(): self.devs[dev]['extraValues'] = [ ans[s] for s in self.devs[dev]['extras'] ] self.devs[dev]['status'] = 'OK' except Error as e: # catch labrad error (usually DeviceNotSelectedError) -- select our device if we have one self.devs[dev]['values'] = [NaN] * len( self.devs[dev]['settings']) if 'DeviceNotSelectedError' in e.msg or 'NoDevicesAvailableError' in e.msg: devs = yield self.devs[dev]['server'].list_devices( context=self.devs[dev]['context']) found = False for d in devs: if 'gpib address' in self.devs[dev].keys(): #print d[1] if not d[1].endswith( str(self.devs[dev]['gpib address'])): continue if self.nodeName.upper() in d[1].upper(): found = True yield self.devs[dev]['server'].select_device( d[0], context=self.devs[dev]['context']) if 'init funcs' in self.devs[dev].keys(): for i_f in self.devs[dev]['init funcs']: print "calling %s" % i_f self.devs[dev]['server'][i_f]( context=self.devs[dev]['context']) self.devs[dev]['status'] = 'Found Device' if not found: self.devs[dev]['status'] = 'No Device' elif 'Target' in e.msg and 'unknown' in e.msg: # server has been turned off #print e.msg self.devs[dev]['server'] = None self.devs[dev]['status'] = 'No Server' else: print 'Unhandled error in main loop: %s' % e.msg self.devs[dev]['status'] = 'Other Error' else: self.devs[dev]['status'] = 'No Server' self.devs[dev]['values'] = [NaN] * len(self.devs[dev]['settings']) # @inlineCallbacks def doMagCycle(self): ''' Do a mag cycle if applicable. Here are the rules: -- Must have connection to all servers, below temperature. (status = OK) -- Must be below voltage limit. -- Current difference must be larger than the resolution limit. ''' if self.status != 'OK': return if self.psStatus.startswith('Cooled'): self.doMagCycleSwitchCooled() elif not self.psStatus.startswith('Heated'): return if self.devs[POWER]['extraValues'][0] == False: self.devs[POWER]['server'].voltage_mode( context=self.devs[POWER]['context']) self.devs[POWER]['server'].output( True, context=self.devs[POWER]['context']) # is the set current where we want it to be? if self.devs[POWER]['values'][1] < abs(self.setCurrent): self.devs[POWER]['server'].set_current( abs(self.setCurrent), context=self.devs[POWER]['context']) # if the supply setpoint is above the server setpoint # and the supply value is below the supply setpoint # then set the supply setpoint to max(supply value, server setpoint) # (prevents us from leaving the supply setpoint at some high number when magging down) print self.devs[POWER]['values'][1], self.setCurrent, self.devs[POWER][ 'values'][0] if self.devs[POWER]['values'][1] > abs( self.setCurrent) + CURRENT_RESOLUTION: if abs(self.devs[POWER]['values'] [0]) < self.devs[POWER]['values'][1]: newcurr = max( abs(self.devs[POWER]['values'][0]) + CURRENT_RESOLUTION * 100, abs(self.setCurrent)) self.devs[POWER]['server'].set_current( newcurr, context=self.devs[POWER]['context']) ## first, sensing mode if self.sensingMode: # have we reached the target? if abs(self.devs[POWER]['values'][0] - self.setCurrent) < CURRENT_RESOLUTION: self.devs[POWER]['server'].set_voltage( 0, context=self.devs[POWER]['context']) # do we go up or down? elif self.setCurrent < self.devs[POWER]['values'][0]: self.devs[POWER]['server'].set_voltage( -1 * abs(self.voltageLimit), context=self.devs[POWER]['context']) elif self.setCurrent > self.devs[POWER]['values'][0]: self.devs[POWER]['server'].set_voltage( 1 * abs(self.voltageLimit), context=self.devs[POWER]['context']) ### now, old mode ("manual sensing") else: # have we reached the target? if abs(self.devs[POWER]['values'][0] - self.setCurrent) < CURRENT_RESOLUTION: # set the voltage so that the magnet voltage is zero newvolt = self.devs[POWER]['values'][2] - self.devs[DMM][ 'values'][0] self.devs[POWER]['server'].set_voltage( newvolt, context=self.devs[POWER]['context']) print 'done magging! %s' % newvolt return # is the magnet voltage below the limit? if self.setCurrent < self.devs[POWER]['values'][0] and self.devs[ DMM]['values'][0] > -self.voltageLimit: newvolt = self.devs[POWER]['values'][2] - VOLTAGE_STEP print "mag step -> %s" % newvolt self.devs[POWER]['server'].set_voltage( newvolt, context=self.devs[POWER]['context']) elif self.setCurrent > self.devs[POWER]['values'][0] and self.devs[ DMM]['values'][0] < self.voltageLimit: newvolt = self.devs[POWER]['values'][2] + VOLTAGE_STEP print "mag step -> %s" % newvolt self.devs[POWER]['server'].set_voltage( newvolt, context=self.devs[POWER]['context']) def doMagCycleSwitchCooled(self): ''' this is called when the persistent switch is cold. ''' if abs(self.devs[POWER]['values'][0] - self.setCurrent) < CURRENT_RESOLUTION * 5: if abs(self.setCurrent) < CURRENT_RESOLUTION: self.devs[POWER]['server'].output( False, context=self.devs[POWER]['context']) return if self.setCurrent < self.devs[POWER]['values'][0]: newvolt = self.devs[POWER]['values'][2] - VOLTAGE_STEP self.devs[POWER]['server'].set_voltage( newvolt, context=self.devs[POWER]['context']) else: newVolt = self.devs[POWER]['values'][2] + VOLTAGE_STEP self.devs[POWER]['server'].set_voltage( newvolt, context=self.devs[POWER]['context']) def doPersistentSwitch(self): ''' Handle the persistent switch. ''' # make sure we have the server/device if self.devs[DC]['status'] != 'OK': self.psStatus = 'No server/device' return # is DC supply in PS mode? if not self.devs[DC]['extraValues'][1]: # asynch send message to put in PS Mode self.devs[DC]['server'].persistent_switch_mode( True, context=self.devs[DC]['context']) self.psStatus = 'Setting PS mode on device.' return self.psHeated = self.devs[DC]['extraValues'][0] self.psTime = self.devs[DC]['extraValues'][2] # Logic: # if desired state == None, set desired state = current state # if desired state == None or desired state == current state == heated, do nothing # if desired state == cooled and current state == cooled, # if time > required time, mag to zero # if desired state == cooled and current state == heated, # if current value is at setpoint, turn off switch heating, record current value # if desired state == heated and current state == cooled, # if current value is not at recorded value, mag to recorded value # if current value is at recorded value, heat switch if self.psRequestedState is None: self.psRequestedState = self.psHeated if not self.psRequestedState: self.psCurrent = self.setCurrent if self.psRequestedState is True and self.psHeated is True: if self.psTime < PS_COOLING_TIME: self.psStatus = 'Waiting for heating' return else: self.psStatus = "Heated" return if self.psRequestedState is False and self.psHeated is False: if self.psTime > PS_COOLING_TIME and abs( self.setCurrent) > CURRENT_RESOLUTION: self.current(0) self.psStatus = 'Cooled; turning off power' return elif self.psTime > PS_COOLING_TIME and abs( self.devs[POWER]['values'][0]) >= CURRENT_RESOLUTION: self.psStatus = 'Cooled; powering down' return elif self.psTime > PS_COOLING_TIME and abs( self.devs[POWER]['values'][0]) < CURRENT_RESOLUTION: self.psStatus = 'Cooled; power off' return else: # waiting for switch to cool self.psStatus = 'Waiting for cooling' return if self.psRequestedState is False and self.psHeated is True: # check for current to be at setpoint if abs(self.setCurrent - self.devs[POWER]['values'][0]) < CURRENT_RESOLUTION: self.psCurrent = self.devs[POWER]['values'][0] self.devs[DC]['server'].output( False, context=self.devs[DC]['context']) # do the deed, asynch self.psStatus = 'Turned heater off' return else: self.psStatus = 'Heated; Waiting for current setpoint' return if self.psRequestedState is True and self.psHeated is False: # ramp to appropriate current self.current(self.psCurrent) if abs(self.psCurrent - self.devs[POWER]['values'][0]) < CURRENT_RESOLUTION * 5: # we're at the appropriate current self.devs[DC]['server'].output( True, context=self.devs[DC]['context']) self.psStatus = 'Turned heater on' return else: self.psStatus = 'Cooled; Powering up' return # if we made it here it's a programming error! self.psStatus = "Error in code!" def doDataVault(self): ''' Record data if the appropriate time has passed. If we need to create a new dataset, do it. No need to wait on the return, though. As we do this asynchronously there is a slight danger of one of the add data packets arriving ahead of the create dataset packets, but in a practical sense this should never happen with the multi-second delay we normally use.''' # time, status check if (self.status != 'OK' and self.status != 'Over Temperature' ) or time.time() - self.dvLastTimeRecorded < self.dvRecordDelay: return self.dvLastTimeRecorded = t = time.time() # server check if self.dv is None and 'Data Vault' in self.cxn.servers: self.dv = self.cxn.data_vault elif self.dv is None: self.dvStatus = 'Data Vault server not found.' return # get together our data data = [t, self.magnetCurrent(), self.current()] for x in self.devs.keys(): data += self.devs[x]['values'] p = self.dv.packet(context=self.ctxt) # dataset check if not self.dvName: self.dvName = 'Magnet Controller Log - %s - %s' % ( self.nodeName, time.strftime("%Y-%m-%d %H:%M")) self.dvNew = True p.cd(DATA_PATH, True) p.new(self.dvName, ['time [s]'], [ 'Current (Magnet) [A]', 'Current (Setpoint) [A]', 'Current (Power Supply) [A]', 'Current (Power Supply Setpoint) [A]', 'Voltage (Power Supply) [V]', 'Voltage (Power Supply Setpoint) [V]', 'Voltage (Magnet) [V]', 'Current (Heater) [A]', 'Voltage (Heater) [V]', 'Temperature (4K) [K]', 'Current (DMM2) [A]' ]) p.add_parameters( ('Start Time (str)', time.strftime("%Y-%m-%d %H:%M")), ('Start Time (int)', time.time())) # add the data p.add(data) d = p.send(context=self.ctxt) d.addCallback(self.handleDVCreateCallback) d.addErrback(self.handleDVError) self.dvStatus = 'Logging' def handleDVCreateCallback(self, response): ''' called after dataset is created. just to get the correct name, really. ''' if self.dvNew: self.dvName = response.new[1] self.dvNew = False def handleDVError(self, failure): ''' this is an errback added to the call to the data vault. if it gets called (i.e. there is an exception in the DV call), we assume that we need to create a data set. ''' print 'dv error!' failure.trap(Error) print failure self.dvName = None self.dv = None self.dvStatus = 'Creating new dataset' def checkTemperature(self): ''' Checks that the magnet temperature is safe. ''' try: #print self.devs[TEMPERATURE]['values'][0] good = self.temperatureOverride or self.devs[TEMPERATURE][ 'values'][0] < TEMP_LIMIT return good except Exception as e: print "Exception in checkTemperature: %s" % e return False def current(self, current=None): ''' change the current setpoint. ''' if current is None: return self.setCurrent if not isinstance(current, Value): current = Value(float(current), 'A') self.setCurrent = current.inUnitsOf('A') self.setCurrent = max(-CURRENT_LIMIT, min(CURRENT_LIMIT, self.setCurrent)) return self.setCurrent def magnetCurrent(self): ''' Get the magnet current. This is either the power supply current (if the heater is on) or the remembered current if we're in persistent mode. ''' if self.psHeated is False: return self.psCurrent else: #return (self.devs[DMM2]['values'][0] / DMM2_RESISTANCE).inUnitsOf("A") return self.devs[POWER]['values'][0] def getStatus(self): ''' returns all the statuses ''' return [self.status, self.dvStatus, self.psStatus ] + [self.devs[dev]['status'] for dev in self.devs.keys()] def getValues(self): ''' returns all the applicable values of this magnet controller. ''' # a little hackish because we only return the 4K temperature r = [self.magnetCurrent(), self.current()] for dev in self.devs.keys(): r += self.devs[dev]['values'] r.insert(7, self.voltageLimit) return r #return self.devs[POWER]['values'] + self.devs[DMM]['values'] + self.devs[DC]['values'] + [self.devs[TEMPERATURE]['values'][1]] def persistentSwitch(self, newState): ''' sets/gets the desired state of the switch. True = heated = open (leave it this way when magging) False = cooled = closed (for steady field) Note that the process of opening/closing the switch is an involved one. ''' if newState is not None: self.psRequestedState = bool(newState) return self.psRequestedState def psSetCurrent(self, newCurrent): if newCurrent is not None: if not isinstance(newCurrent, Value): newCurrent = Value(float(newCurrent), 'A') self.psCurrent = newCurrent.inUnitsOf('A') self.psCurrent = max(-CURRENT_LIMIT, min(CURRENT_LIMIT, self.psCurrent)) return self.psCurrent
class radioButtons(widgetState,QWidget): def __init__(self,widget,label=None, displayLabel=True, includeInReports=True, buttons=None,toolTips = None, setChecked = None, orientation='vertical',callback = None, **args): QWidget.__init__(self,widget) widgetState.__init__(self,widget,label,includeInReports,**args) self.controlArea.layout().setAlignment(Qt.AlignTop | Qt.AlignLeft) self.label = label if displayLabel: self.box = groupBox(self.controlArea,label=label,orientation=orientation) self.controlArea.layout().addWidget(self.box) else: self.box = widgetBox(self.controlArea,orientation=orientation) # if orientation=='vertical': # self.box.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, # QSizePolicy.MinimumExpanding)) # else: # self.box.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding, # QSizePolicy.Preferred)) self.items = OrderedDict() self.buttons = QButtonGroup(self.box) if buttons: self.addButtons(buttons) # for i,b in zip(range(len(buttons)),buttons): # w = QRadioButton(b) # if toolTips: # w.setToolTip(toolTips[i]) # self.buttons.addButton(w) # self.box.layout().addWidget(w) if callback: QObject.connect(self.buttons, SIGNAL('buttonClicked(int)'), callback) if setChecked: self.setChecked(setChecked) def addButtons(self,buttons): if type(buttons) in [dict,OrderedDict]: for k,v in buttons.items(): self.addButton(k,v) elif type(buttons) in [list]: if len(buttons) > 0 and type(buttons[0]) is tuple: for k,v in buttons: self.addButton(k,v) else: for v in buttons: self.addButton(v,v) # redRLog.log(redRLog.REDRCORE,redRLog.DEBUG,_('In radioButtons should not use list')) else: raise Exception(_('In radioButtons, addButtons takes a list, dict or OrderedDict')) def addButton(self,id, text,toolTip=None): self.items[id] = text w = QRadioButton(text) if toolTip: w.setToolTip(toolTip) self.buttons.addButton(w,self.items.keys().index(id)) self.box.layout().addWidget(w) def setChecked(self,id): buttons = self.buttons.buttons() try: self.buttons.button(self.items.keys().index(id)).setChecked(True) except: pass # for i in self.buttons.buttons(): # if i.text() == id: i.setChecked(True) # else: i.setChecked(False) def getCheckedItem(self): buttonId = self.buttons.checkedId() if buttonId == -1:return return {self.items.keys()[buttonId]: self.items[self.items.keys()[buttonId]]} def getChecked(self): buttonId = self.buttons.checkedId() if buttonId == -1:return return self.items[self.items.keys()[buttonId]] # if button == 0 or button == None or button.isEnabled()==False: return 0 # else: return unicode(button.text()) def getCheckedId(self): buttonId = self.buttons.checkedId() if buttonId == -1:return return self.items.keys()[buttonId] def setSizePolicy(self, h,w): # self.controlArea.setSizePolicy(h,w) # QWidget.setSizePolicy(self,h,w) self.box.setSizePolicy(h,w) def disable(self,buttons): for i in self.buttons.buttons(): if i.text() in buttons: i.setDisabled(True) def enable(self,buttons): for i in self.buttons.buttons(): if i.text() in buttons: i.setEnabled(True) def getSettings(self): #print _('radioButtons getSettings') + self.getChecked() r = {'items':self.items, 'checked': self.getCheckedId()} return r def loadSettings(self,data): #print _('radioButtons loadSettings') + data #self.addButtons(data['items']) self.setChecked(data['checked']) def getReportText(self, fileDir): r = {self.widgetName:{'includeInReports': self.includeInReports, 'text': self.getChecked()}} return r
class checkBox(widgetState, QWidget): def __init__(self, widget, label=None, displayLabel=True, includeInReports=True, buttons=None, toolTips=None, setChecked=None, orientation='vertical', callback=None): if toolTips and len(toolTips) != len(buttons): raise RuntimeError( _('Number of buttons and toolTips must be equal')) QWidget.__init__(self, widget) widgetState.__init__(self, widget, label, includeInReports) self.controlArea.layout().setAlignment(Qt.AlignTop | Qt.AlignLeft) self.controlArea.layout().addWidget(self) if displayLabel: self.box = groupBox(self.controlArea, label=label, orientation=orientation) # self.layout().addWidget(self.box) else: self.box = widgetBox(self.controlArea, orientation=orientation) # if orientation=='vertical': # self.box.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, # QSizePolicy.MinimumExpanding)) # else: # self.box.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding, # QSizePolicy.Preferred)) self.label = label self.items = OrderedDict() self.buttons = QButtonGroup(self.box) self.buttons.setExclusive(False) if buttons: self.addButtons(buttons) # if buttons: # for i,b in zip(range(len(buttons)),buttons): # w = QCheckBox(b,self.box) # if toolTips: # w.setToolTip(toolTips[i]) # self.buttons.addButton(w,i) # self.box.layout().addWidget(w) if callback: QObject.connect(self.buttons, SIGNAL('buttonClicked(int)'), callback) if setChecked: self.setChecked(setChecked) def addButtons(self, buttons): if type(buttons) in [dict, OrderedDict]: for k, v in buttons.items(): self.addButton(k, v) elif type(buttons) in [list]: if len(buttons) > 0 and type(buttons[0]) is tuple: for k, v in buttons: self.addButton(k, v) else: for v in buttons: self.addButton(v, v) # redRLog.log(redRLog.REDRCORE,redRLog.DEBUG,_('In radioButtons should not use list')) else: raise Exception( _('In radioButtons, addButtons takes a list, dict or OrderedDict' )) def addButton(self, id, text, toolTip=None): self.items[id] = text w = QCheckBox(text) if toolTip: w.setToolTip(toolTip) self.buttons.addButton(w, self.items.keys().index(id)) self.box.layout().addWidget(w) def setSizePolicy(self, h, w): # self.controlArea.setSizePolicy(h,w) # QWidget.setSizePolicy(self,h,w) self.box.setSizePolicy(h, w) def setChecked(self, ids): for i in self.buttons.buttons(): id = self.buttons.id(i) if unicode(self.items.keys()[id]) in ids: i.setChecked(True) else: i.setChecked(False) def checkAll(self): for i in self.buttons.buttons(): i.setChecked(True) def uncheckAll(self): for i in self.buttons.buttons(): i.setChecked(False) def getChecked(self): return self.getCheckedItems().values() # checked = [] # for i in self.buttons.buttons(): # if i.isChecked(): checked.append(unicode(i.text())) # return checked def getCheckedIds(self): return self.getCheckedItems().keys() # checked = [] # for i in self.buttons.buttons(): # if i.isChecked(): checked.append(self.items.keys()[i.id()]) # return checked def getCheckedItems(self): checked = {} for i in self.buttons.buttons(): id = self.buttons.id(i) if i.isChecked(): checked[self.items.keys()[id]] = self.items[self.items.keys() [id]] return checked def getUnchecked(self): unChecked = [] for i in self.buttons.buttons(): if not i.isChecked(): unChecked.append(unicode(i.text())) return unChecked def buttonAt(self, ind): return unicode(self.buttons.button(ind).text()) def getSettings(self): #print _('radioButtons getSettings') + self.getChecked() r = {'items': self.items, 'checked': self.getCheckedIds()} return r def loadSettings(self, data): #print _('radioButtons loadSettings') + data #self.addButtons(data['items']) self.setChecked(data['checked']) def getReportText(self, fileDir): selected = self.getChecked() if len(selected): text = 'Checked: ' + ', '.join(selected) else: text = _('Nothing Checked') r = { self.widgetName: { 'includeInReports': self.includeInReports, 'text': text } } # print '@@@@@@@@@@@@@@@@@@@@@@@', r #t = 'The following items were checked in %s:\n\n%s\n\n' % (self.label, self.getChecked()) return r
SANS1878["sans1878_MetadataStandardVersion"] = "//gmd:metadataStandardVersion/gco:CharacterString/text()" SANS1878["sans1878_MetadataLanguage"] = "//gmd:identificationInfo/gmd:MD_DataIdentification/gmd:language/gco:CharacterString/text()" SANS1878["sans1878_MetadataCharacterSet"] = "//gmd:identificationInfo/gmd:MD_DataIdentification/gmd:characterSet/gmd:MD_CharacterSetCode/@codeListValue" SANS1878["sans1878_MetadataTimeStamp"] = "//gmd:dateStamp/gco:DateTime/text()" SANS1878["sans1878_MetadataPointOfContactIndividualName"] = "//gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:individualName/gco:CharacterString/text()" SANS1878["sans1878_MetadataPointOfContactOrganizationName"] = "//gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:organisationName/gco:CharacterString/text()" SANS1878["sans1878_MetadataPointOfContactPositionName"] = "//gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:positionName/gco:CharacterString/text()" SANS1878["sans1878_MetadataPointOfContactRole"] = "//gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:role/gmd:CI_RoleCode/@codeListValue" ISO19115 = OrderedDict() ISO19115p2 = OrderedDict() ISO19139 = OrderedDict() # generate iso xpath dicts from sans dict for k in SANS1878.keys(): ISO19115[k.replace("sans1878_","iso19115_")] = SANS1878[k] ISO19115p2[k.replace("sans1878_","iso19115p2_")] = SANS1878[k] ISO19139[k.replace("sans1878_","iso19139_")] = SANS1878[k] EML = OrderedDict() EML["eml_Title"] = "//dataset[1]/title[1]/text()" EML["eml_DataOwnerSalutation"] = "//dataset[1]/creator[1]/individualName[1]/salutation[1]/text()" EML["eml_DataOwnerGivenName"] = "//dataset[1]/creator[1]/individualName[1]/givenName[1]/text()" EML["eml_DataOwnerSurname"] = "//dataset[1]/creator[1]/individualName[1]/surName[1]/text()" EML["eml_DataOwnerOrganization"] = "//dataset[1]/creator[1]/organizationName[1]/text()" EML["eml_Abstract"] = "//dataset[1]/abstract[1]/para[1]/text()" EML["eml_Keywords"] = "//dataset[1]/keywordSet[1]/keyword[1]/text()" EML["eml_WestBoundingCoordinate"] = "//dataset[1]/coverage[1]/geographicCoverage[1]/boundingCoordinates[1]/westBoundingCoordinate[1]/text()" EML["eml_EastBoundingCoordinate"] = "//dataset[1]/coverage[1]/geographicCoverage[1]/boundingCoordinates[1]/eastBoundingCoordinate[1]/text()" EML["eml_NorthBoundingCoordinate"] = "//dataset[1]/coverage[1]/geographicCoverage[1]/boundingCoordinates[1]/northBoundingCoordinate[1]/text()"
class radioButtons(widgetState,QWidget): def __init__(self,widget,label=None, displayLabel=True, buttons=None,toolTips = None, setChecked = None, orientation='vertical',callback = None,**kwargs): kwargs.setdefault('includeInReports', True) kwargs.setdefault('sizePolicy', QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)) QWidget.__init__(self,widget) widgetState.__init__(self,widget,label,**kwargs) self.label = label if displayLabel: self.box = groupBox(self.controlArea,label=label,orientation=orientation) self.controlArea.layout().addWidget(self.box) else: self.box = widgetBox(self.controlArea,orientation=orientation) self.controlArea.layout().setAlignment(Qt.AlignTop | Qt.AlignLeft) self.box.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)) # if orientation=='vertical': # self.box.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, # QSizePolicy.MinimumExpanding)) # else: # self.box.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding, # QSizePolicy.Preferred)) self.items = OrderedDict() self.buttons = QButtonGroup(self.box) if buttons: self.addButtons(buttons) # for i,b in zip(range(len(buttons)),buttons): # w = QRadioButton(b) # if toolTips: # w.setToolTip(toolTips[i]) # self.buttons.addButton(w) # self.box.layout().addWidget(w) if callback: QObject.connect(self.buttons, SIGNAL('buttonClicked(int)'), callback) if setChecked: self.setChecked(setChecked) def addButtons(self,buttons): if type(buttons) in [dict,OrderedDict]: for k,v in buttons.items(): self.addButton(k,v) elif type(buttons) in [list]: if len(buttons) > 0 and type(buttons[0]) is tuple: for k,v in buttons: self.addButton(k,v) else: for v in buttons: self.addButton(v,v) # redRLog.log(redRLog.REDRCORE,redRLog.DEBUG,_('In radioButtons should not use list')) else: raise Exception(_('In radioButtons, addButtons takes a list, dict or OrderedDict')) def addButton(self,id, text,toolTip=None): self.items[id] = text w = QRadioButton(text) if toolTip: w.setToolTip(toolTip) self.buttons.addButton(w,self.items.keys().index(id)) self.box.layout().addWidget(w) def setChecked(self,id): buttons = self.buttons.buttons() try: self.buttons.button(self.items.keys().index(id)).setChecked(True) except: pass # for i in self.buttons.buttons(): # if i.text() == id: i.setChecked(True) # else: i.setChecked(False) def getCheckedItem(self): buttonId = self.buttons.checkedId() if buttonId == -1:return return {self.items.keys()[buttonId]: self.items[self.items.keys()[buttonId]]} def getChecked(self): buttonId = self.buttons.checkedId() if buttonId == -1:return return self.items[self.items.keys()[buttonId]] # if button == 0 or button == None or button.isEnabled()==False: return 0 # else: return unicode(button.text()) def getCheckedId(self): buttonId = self.buttons.checkedId() if buttonId == -1:return return self.items.keys()[buttonId] def setSizePolicy(self, h,w): # self.controlArea.setSizePolicy(h,w) # QWidget.setSizePolicy(self,h,w) self.box.setSizePolicy(h,w) def disable(self,buttons): for i in self.buttons.buttons(): if i.text() in buttons: i.setDisabled(True) def enable(self,buttons): for i in self.buttons.buttons(): if i.text() in buttons: i.setEnabled(True) def getSettings(self): #print _('radioButtons getSettings') + self.getChecked() r = {'items':self.items, 'checked': self.getCheckedId(), 'visible':self.box.isVisible()} return r def loadSettings(self,data): #print _('radioButtons loadSettings') + data #self.addButtons(data['items']) self.setChecked(data['checked']) def getReportText(self, fileDir): r = {self.widgetName:{'includeInReports': self.includeInReports, 'text': self.getChecked()}} return r
SANS1878["sans1878_MetadataTimeStamp"] = "//gmd:dateStamp/gco:DateTime/text()" SANS1878[ "sans1878_MetadataPointOfContactIndividualName"] = "//gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:individualName/gco:CharacterString/text()" SANS1878[ "sans1878_MetadataPointOfContactOrganizationName"] = "//gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:organisationName/gco:CharacterString/text()" SANS1878[ "sans1878_MetadataPointOfContactPositionName"] = "//gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:positionName/gco:CharacterString/text()" SANS1878[ "sans1878_MetadataPointOfContactRole"] = "//gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:role/gmd:CI_RoleCode/@codeListValue" ISO19115 = OrderedDict() ISO19115p2 = OrderedDict() ISO19139 = OrderedDict() # generate iso xpath dicts from sans dict for k in SANS1878.keys(): ISO19115[k.replace("sans1878_", "iso19115_")] = SANS1878[k] ISO19115p2[k.replace("sans1878_", "iso19115p2_")] = SANS1878[k] ISO19139[k.replace("sans1878_", "iso19139_")] = SANS1878[k] EML = OrderedDict() EML["eml_Title"] = "//dataset[1]/title[1]/text()" EML["eml_DataOwnerSalutation"] = "//dataset[1]/creator[1]/individualName[1]/salutation[1]/text()" EML["eml_DataOwnerGivenName"] = "//dataset[1]/creator[1]/individualName[1]/givenName[1]/text()" EML["eml_DataOwnerSurname"] = "//dataset[1]/creator[1]/individualName[1]/surName[1]/text()" EML["eml_DataOwnerOrganization"] = "//dataset[1]/creator[1]/organizationName[1]/text()" EML["eml_Abstract"] = "//dataset[1]/abstract[1]/para[1]/text()" EML["eml_Keywords"] = "//dataset[1]/keywordSet[1]/keyword[1]/text()" EML["eml_WestBoundingCoordinate"] = "//dataset[1]/coverage[1]/geographicCoverage[1]/boundingCoordinates[1]/westBoundingCoordinate[1]/text()" EML["eml_EastBoundingCoordinate"] = "//dataset[1]/coverage[1]/geographicCoverage[1]/boundingCoordinates[1]/eastBoundingCoordinate[1]/text()" EML["eml_NorthBoundingCoordinate"] = "//dataset[1]/coverage[1]/geographicCoverage[1]/boundingCoordinates[1]/northBoundingCoordinate[1]/text()"
class shotdata: def __init__(self, user, part, rootpath): self.version = '0.02' self.part = part self.user = user self.rootpath = rootpath self.workingdir = rootpath self.software = softwareinfo.softwareinfo self.use = 'houdini' self.renderdir = 'render' self.structfile = '.showinfo' self.lastrundir = '' self.lastruntask = '' self.lastrunfile = '' self.items=[] self.log = '' self.showlog=True self.initStruct() # struct def initStruct(self): self.struct = OrderedDict([ ('root', self.rootpath), ('show' , ''), ('work' , 'work'), # ------------------------------------------------- # these levels could deleted depends on show struct ('seq' , ''), ('scene', ''), ('shot' , ''), # ------------------------------------------------- ('run', 'scenes'), ('task' , ''), ('rev' , '') ]) self.head = 'root' self.showStruct = set(['seq', 'scene', 'shot']) self.bypassStruct = ['work','run'] self.printStruct = ['show', 'seq', 'scene', 'shot', 'task', 'rev'] # update def update(self): ''' update working directory and item list. ''' head = self.head #self.writeLog(head) if head == 'root': self.initStruct() if head == 'show': self.updateShow() self.updateDir() self.updateItems() def updateShow(self): ''' reads '.showinfo' file in the show directory, checking it's structure, then delete unused level. ''' structfile = ospath.join(self.rootpath, self.struct['show'], '.showinfo') self.writeLog("{} imported".format(structfile)) with open(structfile) as f: read = f.readline() self.writeLog("reset struct to {}".format(read)) readStruct = set(read.strip('\n').split('/')) delStruct = self.showStruct - readStruct if delStruct: self.writeLog("{} will be deleted".format(" ,".join(delStruct))) else: self.writeLog("Nothing will be deleted") for level in delStruct: del self.struct[level] def updateDir(self): ''' Tasks and revs are not a dir, so we have to set our last dir ''' struct = self.struct dirindex = min(self.currentHeadIndex(), struct.keys().index('run')) workingdir = ospath.join(*struct.values()[:dirindex+1]) print(workingdir) if os.path.isdir(workingdir): self.workingdir = workingdir else: raise ValueError("Cannot find working directory : {0}".format(workingdir)) def updateItems(self): ''' update items (files and directories) in current directory''' items = os.listdir(self.workingdir) items = self.itemculling(items) if self.currentHeadIndex() <= self.headIndex('shot'): items = self.directories(items) elif self.head == 'run': items = self.tasks(items) self.struct['task']=items elif self.head == 'task': items = self.revs(items, self.struct['task']) else: raise KeyError('head is in a danger area! : {0}'.format(head)) self.items = items # print def printMessage(self): filebox.clearScreen() print('='*75) print('Shot Manager V{version}'.format(version=self.version).center(75)) print('user : {0}, part : {1}'.format(self.user, self.part).rjust(75)) print('='*75) print('{0}'.format(self.workingdir).rjust(75)) for s, v in self.struct.items()[self.headIndex('show'):self.currentHeadIndex()+1]: if s not in self.bypassStruct: print('{0: >8} : {1}'.format(s.upper(), v)) print('<{0}>'.format(self.nextHead().upper())) items = [' : '.join(['{0: >4}'.format(idx+1),val]) for idx,val in enumerate(self.items)] print('\n'.join(items)) print('-'*75) if self.showlog and self.log: print(self.log) print('-'*75) print('>>>'), def printHelp(self): filebox.clearScreen() print print('-'*75) print('HELP') print('-'*75) print('go inside : (num)') print('go up one level : (..)') print('go to the top : (/)') print print('new item : (new)') print('ex - (new sc01) or (new task1)') print print('open directory : (o) or (open)') print print('change software : (use)') print('if you want to change to maya : (use maya)') print('if you want to change to max : (use max)') print('if you want to change to houdini : (use houdini)') print('-'*75) print print('>>> Enter to close help.'), raw_input() # action def action(self, userInput): u = userInput.strip().lower() # strip and force change to lower string if (not u) or (u in ['help', '/?', '/help']): self.printHelp() elif u in ['q', 'quit', 'exit']: sys.exit('Bye!') elif u in ['o', 'open']: self.opendir() elif u.startswith('use '): change, sw = u.split(' ') self.changesoftware(sw) elif u.startswith('part '): self.part = u.split()[1] elif u.startswith('user '): self.user = u.split()[1] elif u.startswith('del '): item = u.split()[1] self.delete(item) elif u.startswith('omit '): item = u.split()[1] self.omit(item) elif u.startswith('new '): names = u.split()[1:] for n in names: print(n) self.new(n) elif u.startswith('log '): if u.split()[1] == 'on': self.logOn() elif u.split()[1] == 'off': self.logOff() else: self.writeLog("you can do 'log on' or 'log off'") elif u=='`': self.runLastTask() elif u=='~': self.runLastFile() elif u == '.': pass # Copy directory path to the clipboard else: # Throw any other input to move(), so they can handle it self.move(u) # cull def itemculling(self, items): '''Any directory or file starts with . or _ will not display''' culls = [i for i in items if not (i.startswith('.') or i.startswith('_'))] return culls def directories(self, items): '''It takes current path's items, then only return directories''' dirs = sorted([i for i in items if ospath.isdir(ospath.join(self.workingdir,i))]) return dirs def tasks(self, items): ''' check the software we are using, then throw files for other software ''' files = [i for i in items if ospath.isfile(ospath.join(self.workingdir,i))] validFiles = [] # matched file for software user currently use. exts = self.software[self.use]['read'] for e in exts: validFiles += [f for f in files if e in f] rest = re.compile('[-_.]?v?\d*[.]\w+$') tasksAndOthers = [rest.sub('', i) for i in validFiles] tasksAndOthers = sorted(list(set(tasksAndOthers))) shotpath = self.fileprepath() tasks = [t[len(shotpath)+1:] for t in tasksAndOthers if t.startswith(shotpath)] return tasks def revs(self, items, task): revs = [i for i in items if i.startswith(task)] revs = sorted(list(set(revs))) revs.reverse() return revs # head - "head" means "Current Level" def headIndex(self, head): return self.struct.keys().index(head) def currentHeadIndex(self): return self.headIndex(self.head) def headShift(self, shift): self.head = self.struct.keys()[self.currentHeadIndex()+shift] def currentHead(self): return self.struct.keys()[self.currentHeadIndex()] def nextHead(self, head=None): try: return self.struct.keys()[self.currentHeadIndex()+1] except IndexError: return None def prevHead(self, head=None): try: return self.struct.keys()[self.currentHeadIndex()-1] except IndexError: return None def setHeadData(self, data): self.struct[self.head]=data def clearHeadData(self): self.struct[self.head]='' # move def move(self, inputstring): lowerinput = inputstring.lower() loweritems = [i.lower() for i in self.items] if inputstring == '..': self.up() elif inputstring == '/': self.top() elif inputstring.isdigit(): select = int(inputstring)-1 if 0 <= select < len(self.items): self.down(self.items[select]) else: self.writeLog('invalid number : {0}'.format(inputstring)) elif lowerinput in loweritems: i = loweritems.index(lowerinput) self.down(self.items[i]) else: self.writeLog('invalid input : {0}'.format(inputstring)) def top(self): self.head = 'root' #self.initStruct() def up(self): struct = self.struct if self.head in self.bypassStruct: while self.head in self.bypassStruct: self.headShift(-1) self.clearHeadData() if self.head != 'root': self.headShift(-1) def down(self, dest): struct = self.struct if self.nextHead() == 'task': self.runTask(self.workingdir, dest) elif self.nextHead() == 'rev': self.runRev(dest) else: self.headShift(1) self.setHeadData(dest) self.update() # there are chances to skip update, so force update while self.nextHead() in self.bypassStruct: self.headShift(1) print(self.head) # run def runTask(self, dir, task): flist = os.listdir(dir) shot = self.fileprepath() flist = sorted([f for f in flist if f.startswith(shot+'.'+task)]) flist.reverse() lastf = flist[0] lastfpath = ospath.join(self.workingdir, lastf) self.lastrundir = dir self.lastruntask = task self.lastrunfile = lastfpath os.system('{0} {1}'.format(self.software[self.use]['execute'], lastfpath)) def runFile(self, file): print(self.use, self.software[self.use]) os.system('{0} {1}'.format(self.software[self.use]['execute'], file)) def runLastTask(self): if self.lastrundir and self.lastruntask: self.runTask(self.lastrundir, self.lastruntask) else: self.writeLog('Could not find last task! Maybe its your first time to use this program... or not? :)') def runLastFile(self): if self.lastrunfile: self.runFile(self.lastrunfile) # new def new(self, name): nexthead = self.nextHead() if nexthead in ['show']: self.newshow(name) elif nexthead in ['seq', 'scene']: self.newdir(name) elif nexthead in ['shot']: self.newshot(name) elif nexthead in ['task', 'rev']: self.newtask(name) def newdir(self, dirname): nd = ospath.join(self.workingdir, dirname) os.mkdir(nd) def newshow(self, showname): ''' this will make show struct directories and info (.showinfo) file''' A, B, C = 'seq/scene/shot', 'scene/shot', 'shot' print('choose one of these types') print('1. show/' + A) print('2. show/' + B) print('3. show/' + C) userinput = raw_input() if userinput not in ['1', '2', '3']: self.log+='intput invalid, please type 1-3' return else: showtype = [A, B, C][int(userinput)-1] showpath = ospath.join(self.workingdir, showname) os.mkdir(showpath) maketree.make('show', showpath) self.log+=showtype self.log+=showpath self.makeShowInfoFile(showtype, showpath) def makeShowInfoFile(self, showtype, showpath): showfile = ospath.join(showpath, '.showinfo') with open(showfile, 'w') as f: f.write(showtype) def newshot(self, shot): path = ospath.join(self.workingdir, shot) os.mkdir(path) maketree.make('shot', path) def newtask(self, taskname): struct = self.struct structname = self.structname structpath = self.structpath filename = '.'.join([self.fileprepath(), taskname, 'v101', self.software[self.use]['write']]) filepath = ospath.join(self.workingdir, filename) shotpath = self.shotpath() renderpath = self.renderpath() startf, endf, fps = 1, 240, 24.0 initscript = self.software[self.use]['initscript'].format( show=structname('show'), seq=structname('seq'), scene=structname('scene'), shot=structname('shot'), task=taskname, showpath = structpath('show'), seqpath=structpath('seq'), scenepath=structpath('scene'), taskpath=structpath('run'), shotpath=shotpath, renderpath=renderpath, filepath=filepath, fps=24, start=(startf-1)/fps, end=endf/fps ) scriptfile = ospath.join(self.workingdir, '.temp_init') with open(scriptfile, 'w') as f: f.write(initscript) command = self.software[self.use]['batch'] + ' ' + scriptfile # command = self.software[self.use]['batch'].format(filepath=filepath) + ' ' + scriptfile self.writeLog("running setup script.. : {}".format(command)) os.system(command) os.remove(scriptfile) self.runFile(filepath) # other actions def opendir(self): dir = self.workingdir os.system('thunar {dir}'.format(dir=dir)) def changesoftware(self, sw): if sw in self.software: self.use = sw # self.struct['software'] = self.software[self.use]['dir'] else: print("there isn't such a software") def delete(self, item): ''' Move items to '_deleted' directory ''' itempath = ospath.join(self.workingdir, item) filebox.incBackup(itempath, backupdirname ='_deleted', move=True) def omit(self, item): ''' Move items to '_omitted' directory ''' itempath = ospath.join(self.workingdir, item) filebox.incBackup(itempath, backupdirname ='_omitted', move=True) def writeLog(self, comment): if self.log: self.log+='\n' self.log+="{}".format(comment) def clearLog(self): self.log='' def logOn(self): self.showlog=True def logOff(self): self.showlog=False # utility def structname(self, structname): try: return self.struct[structname] except KeyError: return '' def structpath(self, structname): struct = self.struct try: idx = struct.keys().index(structname) except ValueError: return '' paths = struct.values()[:idx+1] structpath = [] for p in paths: structpath.append(p) # print(structpath) return('/'.join(structpath)) def fileprepath(self): prepath = [] struct = self.struct showidx, shotidx = struct.keys().index('show'), struct.keys().index('shot') paths = struct.values()[showidx : shotidx+1] for p in paths: if not p in self.bypassStruct: prepath.append(p) return('_'.join(prepath)) def shotpath(self): return self.workingdir.replace(self.software[self.use]['dir'], '').rstrip('/') def renderpath(self): return ospath.join(self.shotpath(), self.renderdir) def printHierachy(self): hierachy = [] for i in self.printStruct: if i in self.struct: hierachy.append((i, self.struct[i])) return hierachy
class listBox(QListWidget,widgetState): def __init__(self, widget, value=None, label=None, displayLabel=True, orientation='vertical', selectionMode=QAbstractItemView.SingleSelection, enableDragDrop = 0, dragDropCallback = None, dataValidityCallback = None, sizeHint = None, callback=None, items = None, *args, **kwargs): kwargs.setdefault('includeInReports', True) kwargs.setdefault('sizePolicy', QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)) widgetState.__init__(self,widget,label,**kwargs) QListWidget.__init__(self, *args) self.label = label self.widget = self.controlArea if displayLabel: self.hb = groupBox(self.controlArea,label=label,orientation=orientation) else: self.hb = widgetBox(self.controlArea,orientation=orientation) self.hb.layout().addWidget(self) self.ogValue = value self.ogLabels = label self.enableDragDrop = enableDragDrop self.dragDopCallback = dragDropCallback self.dataValidityCallback = dataValidityCallback self.defaultSizeHint = QSize(150,100) self.setSelectionMode(selectionMode) if enableDragDrop: self.setDragEnabled(1) self.setAcceptDrops(1) self.setDropIndicatorShown(1) #self.setDragDropMode(QAbstractItemView.DragDrop) self.dragStartPosition = 0 self.listItems = OrderedDict() if items: self.addItems(items) if callback: QObject.connect(self, SIGNAL('itemClicked(QListWidgetItem*)'), callback) def getItems(self): """Returns an OrderedDict of the items (key, value) in the listBox, this can be treated as a dict also.""" return self.listItems def addItem(self,id,item): QListWidget.addItem(self,item) self.listItems[id] = item def addItems(self,items): progressBar = startProgressBar('Setting List Items', '', len(items)) progress = 0 if type(items) in [dict,OrderedDict]: for k,v in items.items(): self.addItem(k,v) progress += 1 progressBar.setValue(progress) elif type(items) in [list]: progressBar = startProgressBar('Setting List Items', '', len(items)) if len(items) > 0 and type(items[0]) is tuple: for k,v in items: self.addItem(k,v) progress += 1 progressBar.setValue(progress) else: for v in items: self.addItem(v,v) progress += 1 progressBar.setValue(progress) # redRLog.log(redRLog.REDRCORE,redRLog.DEBUG,_('In listBox should not use list')) else: progressBar.hide() raise Exception(_('In listBox, addItems takes a list, dict or OrderedDict')) progressBar.hide() def setSelectedIds(self,ids): """Sets a list of ids (ids) to be selected.""" if ids == None: return progressBar = startProgressBar('Setting Selected Items', '', len(ids)) progress = 0 for x in ids: try: self.item(self.listItems.keys().index(x)).setSelected(True) except: pass progress += 1 progressBar.setValue(progress) def update(self, items): """Clears the list, adds new items, and sets any selected items in the old list to being selected in the new list (if they exist of course).""" current = self.selectedIds() self.clear() self.addItems(items) self.setSelectedIds(current) def clear(self): """Clears the list""" QListWidget.clear(self) self.listItems = OrderedDict() def invertSelection(self): for i in range(self.count()): if self.isItemSelected(self.item(i)): self.item(i).setSelected(False) else: self.item(i).setSelected(True) def selectionCount(self): return len(self.selectedIndexes()) def currentSelection(self): """Returns a list of selected values (the text in the list)""" return self.selectedItems().values() def selectedItems(self): """Returns a dict of selected items.""" items = {} for x in self.selectedIndexes(): items[self.listItems.keys()[x.row()]] = self.listItems.values()[x.row()] return items def selectedIds(self): """Returns a list of selected ids""" ids = [] for x in self.selectedIndexes(): ids.append(self.listItems.keys()[x.row()]) return ids #def setSelectedIds(self, ids): #if ids == None: return #for i in range(self.count()): #if self.listItems.keys()[i] in ids: #self.item(i).setSelect(True) def sizeHint(self): return self.defaultSizeHint def startDrag(self, supportedActions): if not self.enableDragDrop: return drag = QDrag(self) mime = QMimeData() if not self.ogValue: selectedItems = [i for i in range(self.count()) if self.item(i).isSelected()] else: selectedItems = getdeepattr(self.widget, self.ogValue, default = []) mime.setText(unicode(selectedItems)) mime.source = self drag.setMimeData(mime) drag.start(Qt.MoveAction) def dragEnterEvent(self, ev): if not self.enableDragDrop: return if self.dataValidityCallback: return self.dataValidityCallback(ev) if ev.mimeData().hasText(): ev.accept() else: ev.ignore() def dragMoveEvent(self, ev): if not self.enableDragDrop: return if self.dataValidityCallback: return self.dataValidityCallback(ev) if ev.mimeData().hasText(): ev.setDropAction(Qt.MoveAction) ev.accept() else: ev.ignore() def dropEvent(self, ev): if not self.enableDragDrop: return if ev.mimeData().hasText(): item = self.itemAt(ev.pos()) if item: index = self.indexFromItem(item).row() else: index = self.count() source = ev.mimeData().source selectedItemIndices = eval(unicode(ev.mimeData().text())) if self.ogLabels != None and self.ogValue != None: allSourceItems = getdeepattr(source.widget, source.ogLabels, default = []) selectedItems = [allSourceItems[i] for i in selectedItemIndices] allDestItems = getdeepattr(self.widget, self.ogLabels, default = []) if source != self: setattr(source.widget, source.ogLabels, [item for item in allSourceItems if item not in selectedItems]) # TODO: optimize this code. use the fact that the selectedItemIndices is a sorted list setattr(self.widget, self.ogLabels, allDestItems[:index] + selectedItems + allDestItems[index:]) setattr(source.widget, source.ogValue, []) # clear selection in the source widget else: items = [item for item in allSourceItems if item not in selectedItems] if index < len(allDestItems): while index > 0 and index in getdeepattr(self.widget, self.ogValue, default = []): # if we are dropping items on a selected item, we have to select some previous unselected item as the drop target index -= 1 destItem = allDestItems[index] index = items.index(destItem) else: index = max(0, index - len(selectedItems)) setattr(self.widget, self.ogLabels, items[:index] + selectedItems + items[index:]) setattr(self.widget, self.ogValue, range(index, index+len(selectedItems))) else: # if we don't have variables ogValue and ogLabel if source != self: self.insertItems(source.selectedItems()) for index in selectedItemIndices[::-1]: source.takeItem(index) else: if index < self.count(): while index > 0 and self.item(index).isSelected(): # if we are dropping items on a selected item, we have to select some previous unselected item as the drop target index -= 1 items = [source.item(i) for i in selectedItemIndices] for ind in selectedItemIndices[::-1]: source.takeItem(ind) if ind <= index: index-= 1 for item in items[::-1]: self.insertItem(index, item) self.clearSelection() for i in range(index, index+len(items)): self.item(i).setSelected(1) if self.dragDopCallback: # call the callback self.dragDopCallback() ev.setDropAction(Qt.MoveAction) ev.accept() ## whatever all of this does we need to execute the function to update the items self.updateRedRItems() else: ev.ignore() def updateRedRItems(self): """Updates the items in the list to a new order.""" ## we go through all of the items and remake the items OrderedDict newDict = OrderedDict() for r in range(self.count()): t = unicode(self.item(r).text()) # get the text of the item if t not in self.listItems.values(): newDict[t] = t else: for i, ov in self.listItems.items(): if ov == t: newDict[i] = ov self.listItems = newDict def getSettings(self): #print 'saving list box' r = {'items':self.listItems, 'selected':self.selectedIds()} #print r return r def loadSettings(self,data): self.clear() self.addItems(data.get('items', [])) self.setSelectedIds(data.get('selected', None)) def getReportText(self, fileDir): items = self.getItems() selected = self.currentSelection() new = [] for x in items: if x in selected: new.append([_('Selected'), x]) else: new.append([_('Not Selected'),x]) #print new text = redRReports.createTable(new,columnNames=[_('Selection'),_('Option')]) # if text != '': # text += '\nSelected text has * in front' r = {self.widgetName:{'includeInReports': self.includeInReports, 'text': text}} return r
class MagnetWrapper(DeviceWrapper): def connect(self, nodeName, cxn): print 'Connect: %s' % nodeName self.cxn = cxn self.ctxt = self.cxn.context() self.nodeName = nodeName # state variables of this object self.status = 'Missing Devices' self.setCurrent = Value(NaN, 'A') self.voltageLimit = VOLTAGE_LIMIT_DEFAULT self.temperatureOverride = False # if True, ignore temperature checks self.sensingMode = True # devices we must link to self.devs = OrderedDict() self.devs[POWER] = {'server' : None, 'values': [NaN] * len(POWER_SETTINGS), 'status': 'not initialized', 'settings': POWER_SETTINGS, 'extras': ['output']} self.devs[DMM] = {'server' : None, 'values': [NaN] * len(DMM_SETTINGS), 'status': 'not initialized', 'settings': DMM_SETTINGS, 'gpib address': 24, 'init funcs': ['configure_voltage']} self.devs[DC] = {'server' : None, 'values': [NaN] * len(DC_SETTINGS), 'status': 'not initialized', 'settings': DC_SETTINGS, 'extras': ['output', 'persistent_switch_mode', 'persistent_switch_time_elapsed']} self.devs[TEMPERATURE] = {'server': None, 'values': [NaN] * len(TEMPERATURE_SETTINGS), 'status': 'not initialized', 'settings': TEMPERATURE_SETTINGS, 'flatten': True, 'pickOneValue': 1} self.devs[DMM2] = {'server': None, 'values': [NaN] * len(DMM2_SETTINGS), 'status': 'not initialized', 'settings': DMM2_SETTINGS, 'gpib address': 27,} # Persistent Switch self.psHeated = None # T/F for switch heated or not self.psCurrent = NaN * A # current when switch was cooled/closed self.psTime = 0 # time since switch state was last changed self.psRequestedState = None # None=leave as is, T = heated, F = cooled self.psStatus = 'Not started' # DV logging stuff self.dv = None self.dvName = None self.dvRecordDelay = 5 # record every X seconds self.dvLastTimeRecorded = 0 self.dvStatus = 'Not started' # the main loop stuff self.timeInterval = 0.2 self.loop = LoopingCall(self.mainLoop) self.loopDone = self.loop.start(self.timeInterval, now=True) print 'loop started' @inlineCallbacks def shutdown(self): self.loop.stop() yield self.loopDone @inlineCallbacks def mainLoop(self): #print 'loop executing' # do our updates asynch defers = [self.doDevice(dev) for dev in self.devs.keys()] for defer in defers: yield defer # do we have all devices? if not('OK' == self.devs[POWER]['status'] and 'OK' == self.devs[DMM]['status'] and 'OK' == self.devs[DC]['status'] and 'OK' == self.devs[TEMPERATURE]['status']): # if not, update status, do nothing self.status = 'Missing Devices' else: # if so, do stuff # check the temperature if self.checkTemperature(): try: # if we don't have a current setpoint, set it to the setpoint of the power supply if math.isnan(self.setCurrent) and self.devs[POWER]['status'] == 'OK': self.current(self.devs[POWER]['values'][0]) # see about a mag #yield self.doMagCycle() self.doMagCycle() self.status = 'OK' except Exception as e: print "Exception in main loop: %s" % str(e) else: # we are over temperature # shut down the magnet if it's running if self.devs[POWER]['status'] == 'OK' and abs(self.devs[POWER]['values'][0]) > CURRENT_RESOLUTION: self.devs[POWER]['server'].shut_off(context=self.devs[POWER]['context']) self.current(0*A) self.status = 'Over Temperature' try: # record data self.doDataVault() except Exception as e: print "Exception in data vault" try: # persistent switch self.doPersistentSwitch() except Exception as e: print "Exception in persistent switch" @inlineCallbacks def doDevice(self, dev): # do we need a server? if so, connect to it if not self.devs[dev]['server'] and SERVERS[dev] in self.cxn.servers: self.devs[dev]['server'] = self.cxn[SERVERS[dev]] self.devs[dev]['context'] = self.devs[dev]['server'].context() # do we have a server? if so, get our data if self.devs[dev]['server']: # build packet out of requested settings p = self.devs[dev]['server'].packet() for s in self.devs[dev]['settings']: p[s](key=s) if 'extras' in self.devs[dev].keys(): for s in self.devs[dev]['extras']: p[s](key=s) try: # try to get our data ans = yield p.send(context = self.devs[dev]['context']) self.devs[dev]['values'] = [ans[s] for s in self.devs[dev]['settings']] # couple of special cases if 'flatten' in self.devs[dev].keys(): self.devs[dev]['values'] = [item for sublist in self.devs[dev]['values'] for item in sublist] if 'pickOneValue' in self.devs[dev].keys(): self.devs[dev]['values'] = [self.devs[dev]['values'][self.devs[dev]['pickOneValue']]] if 'pickSubset' in self.devs[dev].keys(): self.devs[dev]['values'] = [self.devs[dev]['values'][x] for x in self.devs[dev]['pickSubset']] if 'extras' in self.devs[dev].keys(): self.devs[dev]['extraValues'] = [ans[s] for s in self.devs[dev]['extras']] self.devs[dev]['status'] = 'OK' except Error as e: # catch labrad error (usually DeviceNotSelectedError) -- select our device if we have one self.devs[dev]['values'] = [NaN] * len(self.devs[dev]['settings']) if 'DeviceNotSelectedError' in e.msg or 'NoDevicesAvailableError' in e.msg: devs = yield self.devs[dev]['server'].list_devices(context = self.devs[dev]['context']) found = False for d in devs: if 'gpib address' in self.devs[dev].keys(): #print d[1] if not d[1].endswith(str(self.devs[dev]['gpib address'])): continue if self.nodeName.upper() in d[1].upper(): found = True yield self.devs[dev]['server'].select_device(d[0], context = self.devs[dev]['context']) if 'init funcs' in self.devs[dev].keys(): for i_f in self.devs[dev]['init funcs']: print "calling %s" % i_f self.devs[dev]['server'][i_f](context=self.devs[dev]['context']) self.devs[dev]['status'] = 'Found Device' if not found: self.devs[dev]['status'] = 'No Device' elif 'Target' in e.msg and 'unknown' in e.msg: # server has been turned off #print e.msg self.devs[dev]['server'] = None self.devs[dev]['status'] = 'No Server' else: print 'Unhandled error in main loop: %s' % e.msg self.devs[dev]['status'] = 'Other Error' else: self.devs[dev]['status'] = 'No Server' self.devs[dev]['values'] = [NaN] * len(self.devs[dev]['settings']) # @inlineCallbacks def doMagCycle(self): ''' Do a mag cycle if applicable. Here are the rules: -- Must have connection to all servers, below temperature. (status = OK) -- Must be below voltage limit. -- Current difference must be larger than the resolution limit. ''' if self.status != 'OK': return if self.psStatus.startswith('Cooled'): self.doMagCycleSwitchCooled() elif not self.psStatus.startswith('Heated'): return if self.devs[POWER]['extraValues'][0] == False: self.devs[POWER]['server'].voltage_mode(context=self.devs[POWER]['context']) self.devs[POWER]['server'].output(True, context=self.devs[POWER]['context']) # is the set current where we want it to be? if self.devs[POWER]['values'][1] < abs(self.setCurrent): self.devs[POWER]['server'].set_current(abs(self.setCurrent), context=self.devs[POWER]['context']) # if the supply setpoint is above the server setpoint # and the supply value is below the supply setpoint # then set the supply setpoint to max(supply value, server setpoint) # (prevents us from leaving the supply setpoint at some high number when magging down) print self.devs[POWER]['values'][1], self.setCurrent, self.devs[POWER]['values'][0] if self.devs[POWER]['values'][1] > abs(self.setCurrent) + CURRENT_RESOLUTION: if abs(self.devs[POWER]['values'][0]) < self.devs[POWER]['values'][1]: newcurr = max(abs(self.devs[POWER]['values'][0])+ CURRENT_RESOLUTION*100, abs(self.setCurrent)) self.devs[POWER]['server'].set_current(newcurr, context=self.devs[POWER]['context']) ## first, sensing mode if self.sensingMode: # have we reached the target? if abs(self.devs[POWER]['values'][0] - self.setCurrent) < CURRENT_RESOLUTION: self.devs[POWER]['server'].set_voltage(0, context=self.devs[POWER]['context']) # do we go up or down? elif self.setCurrent < self.devs[POWER]['values'][0]: self.devs[POWER]['server'].set_voltage(-1 * abs(self.voltageLimit), context=self.devs[POWER]['context']) elif self.setCurrent > self.devs[POWER]['values'][0]: self.devs[POWER]['server'].set_voltage( 1 * abs(self.voltageLimit), context=self.devs[POWER]['context']) ### now, old mode ("manual sensing") else: # have we reached the target? if abs(self.devs[POWER]['values'][0] - self.setCurrent) < CURRENT_RESOLUTION: # set the voltage so that the magnet voltage is zero newvolt = self.devs[POWER]['values'][2] - self.devs[DMM]['values'][0] self.devs[POWER]['server'].set_voltage(newvolt, context=self.devs[POWER]['context']) print 'done magging! %s' % newvolt return # is the magnet voltage below the limit? if self.setCurrent < self.devs[POWER]['values'][0] and self.devs[DMM]['values'][0] > -self.voltageLimit: newvolt = self.devs[POWER]['values'][2] - VOLTAGE_STEP print "mag step -> %s" % newvolt self.devs[POWER]['server'].set_voltage(newvolt, context=self.devs[POWER]['context']) elif self.setCurrent > self.devs[POWER]['values'][0] and self.devs[DMM]['values'][0] < self.voltageLimit: newvolt = self.devs[POWER]['values'][2] + VOLTAGE_STEP print "mag step -> %s" % newvolt self.devs[POWER]['server'].set_voltage(newvolt, context=self.devs[POWER]['context']) def doMagCycleSwitchCooled(self): ''' this is called when the persistent switch is cold. ''' if abs(self.devs[POWER]['values'][0] - self.setCurrent) < CURRENT_RESOLUTION * 5: if abs(self.setCurrent) < CURRENT_RESOLUTION: self.devs[POWER]['server'].output(False, context=self.devs[POWER]['context']) return if self.setCurrent < self.devs[POWER]['values'][0]: newvolt = self.devs[POWER]['values'][2] - VOLTAGE_STEP self.devs[POWER]['server'].set_voltage(newvolt, context=self.devs[POWER]['context']) else: newVolt = self.devs[POWER]['values'][2] + VOLTAGE_STEP self.devs[POWER]['server'].set_voltage(newvolt, context=self.devs[POWER]['context']) def doPersistentSwitch(self): ''' Handle the persistent switch. ''' # make sure we have the server/device if self.devs[DC]['status'] != 'OK': self.psStatus = 'No server/device' return # is DC supply in PS mode? if not self.devs[DC]['extraValues'][1]: # asynch send message to put in PS Mode self.devs[DC]['server'].persistent_switch_mode(True, context=self.devs[DC]['context']) self.psStatus = 'Setting PS mode on device.' return self.psHeated = self.devs[DC]['extraValues'][0] self.psTime = self.devs[DC]['extraValues'][2] # Logic: # if desired state == None, set desired state = current state # if desired state == None or desired state == current state == heated, do nothing # if desired state == cooled and current state == cooled, # if time > required time, mag to zero # if desired state == cooled and current state == heated, # if current value is at setpoint, turn off switch heating, record current value # if desired state == heated and current state == cooled, # if current value is not at recorded value, mag to recorded value # if current value is at recorded value, heat switch if self.psRequestedState is None: self.psRequestedState = self.psHeated if not self.psRequestedState: self.psCurrent = self.setCurrent if self.psRequestedState is True and self.psHeated is True: if self.psTime < PS_COOLING_TIME: self.psStatus = 'Waiting for heating' return else: self.psStatus = "Heated" return if self.psRequestedState is False and self.psHeated is False: if self.psTime > PS_COOLING_TIME and abs(self.setCurrent) > CURRENT_RESOLUTION: self.current(0) self.psStatus = 'Cooled; turning off power' return elif self.psTime > PS_COOLING_TIME and abs(self.devs[POWER]['values'][0]) >= CURRENT_RESOLUTION: self.psStatus = 'Cooled; powering down' return elif self.psTime > PS_COOLING_TIME and abs(self.devs[POWER]['values'][0]) < CURRENT_RESOLUTION: self.psStatus = 'Cooled; power off' return else: # waiting for switch to cool self.psStatus = 'Waiting for cooling' return if self.psRequestedState is False and self.psHeated is True: # check for current to be at setpoint if abs(self.setCurrent - self.devs[POWER]['values'][0]) < CURRENT_RESOLUTION: self.psCurrent = self.devs[POWER]['values'][0] self.devs[DC]['server'].output(False, context=self.devs[DC]['context']) # do the deed, asynch self.psStatus = 'Turned heater off' return else: self.psStatus = 'Heated; Waiting for current setpoint' return if self.psRequestedState is True and self.psHeated is False: # ramp to appropriate current self.current(self.psCurrent) if abs(self.psCurrent - self.devs[POWER]['values'][0]) < CURRENT_RESOLUTION * 5: # we're at the appropriate current self.devs[DC]['server'].output(True, context=self.devs[DC]['context']) self.psStatus = 'Turned heater on' return else: self.psStatus = 'Cooled; Powering up' return # if we made it here it's a programming error! self.psStatus = "Error in code!" def doDataVault(self): ''' Record data if the appropriate time has passed. If we need to create a new dataset, do it. No need to wait on the return, though. As we do this asynchronously there is a slight danger of one of the add data packets arriving ahead of the create dataset packets, but in a practical sense this should never happen with the multi-second delay we normally use.''' # time, status check if (self.status != 'OK' and self.status != 'Over Temperature') or time.time() - self.dvLastTimeRecorded < self.dvRecordDelay: return self.dvLastTimeRecorded = t = time.time() # server check if self.dv is None and 'Data Vault' in self.cxn.servers: self.dv = self.cxn.data_vault elif self.dv is None: self.dvStatus = 'Data Vault server not found.' return # get together our data data = [t, self.magnetCurrent(), self.current()] for x in self.devs.keys(): data += self.devs[x]['values'] p = self.dv.packet(context=self.ctxt) # dataset check if not self.dvName: self.dvName = 'Magnet Controller Log - %s - %s' % (self.nodeName, time.strftime("%Y-%m-%d %H:%M")) self.dvNew = True p.cd(DATA_PATH, True) p.new(self.dvName, ['time [s]'], ['Current (Magnet) [A]', 'Current (Setpoint) [A]', 'Current (Power Supply) [A]', 'Current (Power Supply Setpoint) [A]', 'Voltage (Power Supply) [V]', 'Voltage (Power Supply Setpoint) [V]', 'Voltage (Magnet) [V]', 'Current (Heater) [A]', 'Voltage (Heater) [V]', 'Temperature (4K) [K]', 'Current (DMM2) [A]']) p.add_parameters(('Start Time (str)', time.strftime("%Y-%m-%d %H:%M")), ('Start Time (int)', time.time())) # add the data p.add(data) d = p.send(context=self.ctxt) d.addCallback(self.handleDVCreateCallback) d.addErrback(self.handleDVError) self.dvStatus = 'Logging' def handleDVCreateCallback(self, response): ''' called after dataset is created. just to get the correct name, really. ''' if self.dvNew: self.dvName = response.new[1] self.dvNew = False def handleDVError(self, failure): ''' this is an errback added to the call to the data vault. if it gets called (i.e. there is an exception in the DV call), we assume that we need to create a data set. ''' print 'dv error!' failure.trap(Error) print failure self.dvName = None self.dv = None self.dvStatus = 'Creating new dataset' def checkTemperature(self): ''' Checks that the magnet temperature is safe. ''' try: #print self.devs[TEMPERATURE]['values'][0] good = self.temperatureOverride or self.devs[TEMPERATURE]['values'][0] < TEMP_LIMIT return good except Exception as e: print "Exception in checkTemperature: %s" % e return False def current(self, current=None): ''' change the current setpoint. ''' if current is None: return self.setCurrent if not isinstance(current, Value): current = Value(float(current), 'A') self.setCurrent = current.inUnitsOf('A') self.setCurrent = max(-CURRENT_LIMIT, min(CURRENT_LIMIT, self.setCurrent)) return self.setCurrent def magnetCurrent(self): ''' Get the magnet current. This is either the power supply current (if the heater is on) or the remembered current if we're in persistent mode. ''' if self.psHeated is False: return self.psCurrent else: #return (self.devs[DMM2]['values'][0] / DMM2_RESISTANCE).inUnitsOf("A") return self.devs[POWER]['values'][0] def getStatus(self): ''' returns all the statuses ''' return [self.status, self.dvStatus, self.psStatus] + [self.devs[dev]['status'] for dev in self.devs.keys()] def getValues(self): ''' returns all the applicable values of this magnet controller. ''' # a little hackish because we only return the 4K temperature r = [self.magnetCurrent(), self.current()] for dev in self.devs.keys(): r += self.devs[dev]['values'] r.insert(7, self.voltageLimit) return r #return self.devs[POWER]['values'] + self.devs[DMM]['values'] + self.devs[DC]['values'] + [self.devs[TEMPERATURE]['values'][1]] def persistentSwitch(self, newState): ''' sets/gets the desired state of the switch. True = heated = open (leave it this way when magging) False = cooled = closed (for steady field) Note that the process of opening/closing the switch is an involved one. ''' if newState is not None: self.psRequestedState = bool(newState) return self.psRequestedState def psSetCurrent(self, newCurrent): if newCurrent is not None: if not isinstance(newCurrent, Value): newCurrent = Value(float(newCurrent), 'A') self.psCurrent = newCurrent.inUnitsOf('A') self.psCurrent = max(-CURRENT_LIMIT, min(CURRENT_LIMIT, self.psCurrent)) return self.psCurrent
class comboBox(QComboBox,widgetState): def __init__(self,widget,label=None, displayLabel=True, items=None, editable=False, orientation='horizontal',callback = None,**kwargs): kwargs.setdefault('includeInReports', True) kwargs.setdefault('sizePolicy', QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)) widgetState.__init__(self,widget,label,**kwargs) QComboBox.__init__(self,self.controlArea) if displayLabel: self.hb = widgetBox(self.controlArea,orientation=orientation) lb = widgetLabel(self.hb, label) self.hb.layout().addWidget(self) self.hasLabel = True self.hb.layout().setAlignment(lb,Qt.AlignRight) lb.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) else: self.controlArea.layout().addWidget(self) self.hasLabel = False self.label = label self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred) self.items = OrderedDict() self.setEditable(editable) if items: self.addItems(items) if callback: QObject.connect(self, SIGNAL('activated(int)'), callback) def getSettings(self): """Standard getSettings""" r = {'items':self.items, 'current':self.currentIndex()} return r def loadSettings(self,data): """Standard loadSettings""" # print _('in comboBox load') # print data self.update(data.get('items', [])) if data.get('current', None) != None: self.setCurrentIndex(data['current']) def currentId(self): """Returns the current ID""" try: return self.items.keys()[self.currentIndex()] except: return None def currentItem(self): """Returns the current key value pair""" return {self.items.keys()[self.currentIndex()]:self.items.values()[self.currentIndex()]} def setCurrentId(self,id): """Sets the current ID, the ID's value will apear in the comboBox""" try: self.setCurrentIndex(self.items.keys().index(id)) except: pass def addItems(self,items): """Adds items to the comboBox, new items will appear after old ones""" if type(items) in [dict,OrderedDict]: for k,v in items.items(): self.addItem(k,v) elif type(items) in [list]: if len(items) > 0 and type(items[0]) is tuple: for k,v in items: self.addItem(k,v) else: for v in items: self.addItem(v,v) # redRLog.log(redRLog.REDRCORE,redRLog.DEBUG,_('In listBox should not use list')) else: raise Exception(_('In comboBox, addItems takes a list, dict or OrderedDict')) def update(self, items): """Clears the comboBox and adds new items, sets the current ID to the previously selected ID if found in the items""" current = self.currentId() self.clear() self.addItems(items) self.setCurrentId(current) def clear(self): """Removes all items from the comboBox""" QComboBox.clear(self) self.items = OrderedDict() def addItem(self,id,item): """Adds a single item""" QComboBox.addItem(self,item) self.items[id] = item def getReportText(self, fileDir): """Standard getReportText""" r = {self.widgetName:{'includeInReports': self.includeInReports, 'text': self.currentText()}} #return '%s set to %s' % (self.label, self.currentText()) return r
class comboBox(QComboBox, widgetState): def __init__(self, widget, label=None, displayLabel=True, includeInReports=True, items=None, editable=False, orientation='horizontal', callback=None): widgetState.__init__(self, widget, label, includeInReports) QComboBox.__init__(self, self.controlArea) if displayLabel: self.hb = widgetBox(self.controlArea, orientation=orientation) widgetLabel(self.hb, label) self.hb.layout().addWidget(self) self.hasLabel = True else: self.controlArea.layout().addWidget(self) self.hasLabel = False self.label = label self.items = OrderedDict() self.setEditable(editable) if items: self.addItems(items) if callback: QObject.connect(self, SIGNAL('activated(int)'), callback) def getSettings(self): r = {'items': self.items, 'current': self.currentIndex()} return r def loadSettings(self, data): # print _('in comboBox load') # print data self.addItems(data['items']) self.setCurrentIndex(data['current']) def currentId(self): try: return self.items.keys()[self.currentIndex()] except: return None def currentItem(self): return { self.items.keys()[self.currentIndex()]: self.items.values()[self.currentIndex()] } def setCurrentId(self, id): try: self.setCurrentIndex(self.items.keys().index(id)) except: pass def addItems(self, items): if type(items) in [dict, OrderedDict]: for k, v in items.items(): self.addItem(k, v) elif type(items) in [list]: if len(items) > 0 and type(items[0]) is tuple: for k, v in items: self.addItem(k, v) else: for v in items: self.addItem(v, v) # redRLog.log(redRLog.REDRCORE,redRLog.DEBUG,_('In listBox should not use list')) else: raise Exception( _('In comboBox, addItems takes a list, dict or OrderedDict')) def update(self, items): current = self.currentId() self.clear() self.addItems(items) self.setCurrentId(current) def clear(self): QComboBox.clear(self) self.items = OrderedDict() def addItem(self, id, item): QComboBox.addItem(self, item) self.items[id] = item def getReportText(self, fileDir): r = { self.widgetName: { 'includeInReports': self.includeInReports, 'text': self.currentText() } } #return '%s set to %s' % (self.label, self.currentText()) return r
class checkBox(widgetState,QWidget): def __init__(self,widget,label = None, displayLabel= True, buttons = None,toolTips = None, setChecked=None, orientation='vertical',callback = None, **kwargs): kwargs.setdefault('includeInReports', True) kwargs.setdefault('sizePolicy', QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)) """Constructor, common parameters will be widget, label, buttons (a list or list-tuple of key values for buttons), toolTips (a list of toolTips for the buttons), and setChecked (a list of keys to check from the buttons)""" if toolTips and len(toolTips) != len(buttons): raise RuntimeError(_('Number of buttons and toolTips must be equal')) QWidget.__init__(self,widget) widgetState.__init__(self,widget,label,**kwargs) self.controlArea.layout().addWidget(self) if displayLabel: self.box = groupBox(self.controlArea,label=label,orientation=orientation) # self.layout().addWidget(self.box) else: self.box = widgetBox(self.controlArea,orientation=orientation) self.controlArea.layout().setAlignment(Qt.AlignTop | Qt.AlignLeft) self.box.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)) # if orientation=='vertical': # self.box.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, # QSizePolicy.MinimumExpanding)) # else: # self.box.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding, # QSizePolicy.Preferred)) self.label = label self.items = OrderedDict() self.buttons = QButtonGroup(self.box) self.buttons.setExclusive(False) if buttons: self.addButtons(buttons) if callback: QObject.connect(self.buttons, SIGNAL('buttonClicked(int)'), callback) if setChecked: self.setChecked(setChecked) def addButtons(self,buttons): """Internal function to add buttons. Can be called by end developer but should be extensively tested to ensure the desired functionality""" if type(buttons) in [dict,OrderedDict]: for k,v in buttons.items(): self.addButton(k,v) elif type(buttons) in [list]: if len(buttons) > 0 and type(buttons[0]) is tuple: for k,v in buttons: self.addButton(k,v) else: for v in buttons: self.addButton(v,v) # redRLog.log(redRLog.REDRCORE,redRLog.DEBUG,_('In radioButtons should not use list')) else: raise Exception(_('In radioButtons, addButtons takes a list, dict or OrderedDict')) def addButton(self,id, text,toolTip=None): """Internal function called by addButtons""" self.items[id] = text w = QCheckBox(text) if toolTip: w.setToolTip(toolTip) self.buttons.addButton(w,self.items.keys().index(id)) self.box.layout().addWidget(w) def setSizePolicy(self, h,w): # self.controlArea.setSizePolicy(h,w) # QWidget.setSizePolicy(self,h,w) self.box.setSizePolicy(h,w) def setChecked(self,ids,logical = True): """Sets the keys listed in ids to checked""" for i in self.buttons.buttons(): id = self.buttons.id(i) if unicode(self.items.keys()[id]) in ids: i.setChecked(logical) else: i.setChecked(not logical) def checkAll(self): """Checks all of the buttons""" for i in self.buttons.buttons(): i.setChecked(True) def uncheckAll(self): """Unchecks all of the buttons""" for i in self.buttons.buttons(): i.setChecked(False) def clear(self): """Removes all buttons from the widget. Should be called before an end developer calls addButtons""" self.items = {} for i in self.buttons.buttons(): self.buttons.removeButton(i) def getChecked(self): """Returns a list of checked button's labels""" return self.getCheckedItems().values() def getCheckedIds(self): """Returns a list of checked button's IDs""" return self.getCheckedItems().keys() def getCheckedItems(self): """Returns a dict of checked keys and labels""" checked = {} for i in self.buttons.buttons(): id = self.buttons.id(i) if i.isChecked(): checked[self.items.keys()[id]] = self.items[self.items.keys()[id]] return checked def getUncheckedItems(self): """Returns a dict of unchecked keys and labels""" checked = {} for i in self.buttons.buttons(): id = self.buttons.id(i) if not i.isChecked(): checked[self.items.keys()[id]] = self.items[self.items.keys()[id]] return checked def getUnchecked(self): """Same as getChecked but reversed""" return self.getUncheckedItems.values() def getUncheckedIds(self): """Same as getCheckedIds but reversed""" return self.getUncheckedItems.keys() def buttonAt(self,ind): """Returns the button at a given index""" return unicode(self.buttons.button(ind).text()) def getSettings(self): """Called by :mod:`widgetSettings` to get settings""" #print _('radioButtons getSettings') + self.getChecked() r = {'items':self.items, 'checked': self.getCheckedIds()} return r def loadSettings(self,data): """Called by :mod:`widgetSettings` to set settings""" #print _('radioButtons loadSettings') + data #self.addButtons(data['items']) self.setChecked(data['checked']) def getReportText(self, fileDir): """Returns report text for report generator""" selected = self.getChecked() if len(selected): text='Checked: ' + ', '.join(selected) else: text= _('Nothing Checked') r = {self.widgetName:{'includeInReports': self.includeInReports, 'text': text}} return r
class listBox(QListWidget, widgetState): def __init__(self, widget, value=None, label=None, displayLabel=True, includeInReports=True, orientation='vertical', selectionMode=QAbstractItemView.SingleSelection, enableDragDrop=0, dragDropCallback=None, dataValidityCallback=None, sizeHint=None, callback=None, toolTip=None, items=None, *args): widgetState.__init__(self, widget, label, includeInReports) QListWidget.__init__(self, *args) self.label = label self.widget = self.controlArea if displayLabel: self.hb = groupBox(self.controlArea, label=label, orientation=orientation) else: self.hb = widgetBox(self.controlArea, orientation=orientation) self.hb.layout().addWidget(self) self.ogValue = value self.ogLabels = label self.enableDragDrop = enableDragDrop self.dragDopCallback = dragDropCallback self.dataValidityCallback = dataValidityCallback if not sizeHint: self.defaultSizeHint = QSize(150, 100) else: self.defaultSizeHint = sizeHint self.setSelectionMode(selectionMode) if enableDragDrop: self.setDragEnabled(1) self.setAcceptDrops(1) self.setDropIndicatorShown(1) #self.setDragDropMode(QAbstractItemView.DragDrop) self.dragStartPosition = 0 if toolTip: self.setToolTip(toolTip) self.listItems = OrderedDict() if items: self.addItems(items) if callback: QObject.connect(self, SIGNAL('itemClicked(QListWidgetItem*)'), callback) def getItems(self): return self.listItems def addItem(self, id, item): QListWidget.addItem(self, item) self.listItems[id] = item def addItems(self, items): if type(items) in [dict, OrderedDict]: for k, v in items.items(): self.addItem(k, v) elif type(items) in [list]: if len(items) > 0 and type(items[0]) is tuple: for k, v in items: self.addItem(k, v) else: for v in items: self.addItem(v, v) # redRLog.log(redRLog.REDRCORE,redRLog.DEBUG,_('In listBox should not use list')) else: raise Exception( _('In listBox, addItems takes a list, dict or OrderedDict')) def setSelectedIds(self, ids): for x in ids: try: self.item(self.listItems.keys().index(x)).setSelected(True) except: pass def update(self, items): current = self.selectedIds() self.clear() self.addItems(items) self.setSelectedIds(current) def clear(self): QListWidget.clear(self) self.items = OrderedDict() def invertSelection(self): for i in range(self.count()): if self.isItemSelected(self.item(i)): self.item(i).setSelected(False) else: self.item(i).setSelected(True) def selectionCount(self): return len(self.selectedIndexes()) def currentSelection(self): return self.selectedItems().values() def selectedItems(self): items = {} for x in self.selectedIndexes(): items[self.listItems.keys()[x.row()]] = self.listItems.values()[ x.row()] return items def selectedIds(self): ids = [] for x in self.selectedIndexes(): ids.append(self.listItems.keys()[x.row()]) return ids def sizeHint(self): return self.defaultSizeHint def startDrag(self, supportedActions): if not self.enableDragDrop: return drag = QDrag(self) mime = QMimeData() if not self.ogValue: selectedItems = [ i for i in range(self.count()) if self.item(i).isSelected() ] else: selectedItems = getdeepattr(self.widget, self.ogValue, default=[]) mime.setText(unicode(selectedItems)) mime.source = self drag.setMimeData(mime) drag.start(Qt.MoveAction) def dragEnterEvent(self, ev): if not self.enableDragDrop: return if self.dataValidityCallback: return self.dataValidityCallback(ev) if ev.mimeData().hasText(): ev.accept() else: ev.ignore() def dragMoveEvent(self, ev): if not self.enableDragDrop: return if self.dataValidityCallback: return self.dataValidityCallback(ev) if ev.mimeData().hasText(): ev.setDropAction(Qt.MoveAction) ev.accept() else: ev.ignore() def dropEvent(self, ev): if not self.enableDragDrop: return if ev.mimeData().hasText(): item = self.itemAt(ev.pos()) if item: index = self.indexFromItem(item).row() else: index = self.count() source = ev.mimeData().source selectedItemIndices = eval(unicode(ev.mimeData().text())) if self.ogLabels != None and self.ogValue != None: allSourceItems = getdeepattr(source.widget, source.ogLabels, default=[]) selectedItems = [ allSourceItems[i] for i in selectedItemIndices ] allDestItems = getdeepattr(self.widget, self.ogLabels, default=[]) if source != self: setattr( source.widget, source.ogLabels, [ item for item in allSourceItems if item not in selectedItems ] ) # TODO: optimize this code. use the fact that the selectedItemIndices is a sorted list setattr( self.widget, self.ogLabels, allDestItems[:index] + selectedItems + allDestItems[index:]) setattr(source.widget, source.ogValue, []) # clear selection in the source widget else: items = [ item for item in allSourceItems if item not in selectedItems ] if index < len(allDestItems): while index > 0 and index in getdeepattr( self.widget, self.ogValue, default=[] ): # if we are dropping items on a selected item, we have to select some previous unselected item as the drop target index -= 1 destItem = allDestItems[index] index = items.index(destItem) else: index = max(0, index - len(selectedItems)) setattr(self.widget, self.ogLabels, items[:index] + selectedItems + items[index:]) setattr(self.widget, self.ogValue, range(index, index + len(selectedItems))) else: # if we don't have variables ogValue and ogLabel if source != self: self.insertItems(source.selectedItems()) for index in selectedItemIndices[::-1]: source.takeItem(index) else: if index < self.count(): while index > 0 and self.item(index).isSelected( ): # if we are dropping items on a selected item, we have to select some previous unselected item as the drop target index -= 1 items = [source.item(i) for i in selectedItemIndices] for ind in selectedItemIndices[::-1]: source.takeItem(ind) if ind <= index: index -= 1 for item in items[::-1]: self.insertItem(index, item) self.clearSelection() for i in range(index, index + len(items)): self.item(i).setSelected(1) if self.dragDopCallback: # call the callback self.dragDopCallback() ev.setDropAction(Qt.MoveAction) ev.accept() ## whatever all of this does we need to execute the function to update the items self.updateRedRItems() else: ev.ignore() def updateRedRItems(self): ## we go through all of the items and remake the items OrderedDict newDict = OrderedDict() for r in range(self.count()): t = unicode(self.itemAt(r).text()) # get the text of the item if t not in self.listItems.values(): newDict[t] = t else: for i, ov in self.listItems.items(): if ov == t: newDict[i] = ov self.listItems = newDict def getSettings(self): print 'saving list box' r = {'items': self.items, 'selected': self.selectedIds()} print r return r def loadSettings(self, data): print _('loading list box') print data self.clear() self.addItems(data['items']) self.setSelectedIds(data['selected']) def getReportText(self, fileDir): items = self.getItems() selected = self.currentSelection() new = [] for x in items: if x in selected: new.append([_('Selected'), x]) else: new.append([_('Not Selected'), x]) #print new text = redRReports.createTable( new, columnNames=[_('Selection'), _('Option')]) # if text != '': # text += '\nSelected text has * in front' r = { self.widgetName: { 'includeInReports': self.includeInReports, 'text': text } } return r