Package dics :: Module filterwheel
[hide private]
[frames] | no frames]

Source Code for Module dics.filterwheel

  1  from mechanism import mechanism 
  2  import math 
  3  import ConfigParserRT 
  4   
5 -class filterwheel(mechanism):
6 """Class representing a 4 position filter-wheel type mechanism, 7 based on the generic mechanism class in mechanism.py. It adds 8 attributes for motor steps per rotation and preferred direction 9 of movement. There is optional position feedback checking from 10 grey code microswitches.""" 11 12 # Mapping between microswitch inputs and filter wheel position 13 statusDict = {4:0, 6:0.5, 2:1, 3:1.5, 7:2, 5:2.5, 1:3, 0:3.5} 14
15 - def __init__(self, names, cortex, icu_num, axis_num, \ 16 base_speed, max_speed, acceleration, deceleration, \ 17 position, steps_per_rev, direction, \ 18 name='filterwheel'):
19 """ 20 Initialiser for filterwheel class. 21 22 Arguments: 23 names: String containing a comma seperated list of 24 names for the filters. 25 cortex: String containing the name of the cortex based 26 ICU daisy chain instance that this mechanism is a 27 part of. 28 icuNum: Which ICU in the chain this mechanism is connected 29 to. 30 axisNum: Which axis of the ICU the mechansism is connected 31 to. 32 baseSpeed: Starting speed (steps/half steps per sec) 33 maxSpeed: Peak speed (steps/half steps per sec) 34 acceleration: Acceleration (steps/half steps per sec^2) 35 deceleration: Deceleration (steps/half steps per sec^2) 36 position: Initial position of the mechanism (steps) 37 steps_per_rev: Number of motor steps per revolution of the wheel 38 direction: +1 or -1, specifies the direction for rotation 39 name: Label used for logging purposes. 40 """ 41 # Pass the generic parameters to the base class 42 mechanism.__init__(self, cortex, icu_num, axis_num, \ 43 base_speed, max_speed, acceleration, deceleration, \ 44 position, name) 45 46 # Store the filterwheel specific parameters 47 self.names = names.split(',') 48 self.stepsPerRev = int(steps_per_rev) 49 direction = int(direction) 50 if direction > 0: 51 self.direction = +1 52 elif direction < 0: 53 self.direction = -1 54 else: 55 self.logger.critical('Invalid direction "%s" passed to __init__' \ 56 % direction) 57 self.logger.critical('Assuming direction = +1') 58 self.direction = +1
59
60 - def updateConfig(self, config):
61 """ 62 Should be called by the parent instrument object's destructor 63 to enable status information to be saved to file on exit. 64 65 Takes a ConfigParserRT.SafeConfigParser object as argument. 66 """ 67 self.logger.debug("updateConfig() called.") 68 if isinstance(config, ConfigParserRT.SafeConfigParser): 69 config.set(self.name, 'steps_per_rev', str(self.stepsPerRev)) 70 config.set(self.name, 'direction', str(self.direction)) 71 # Just call the base class method for the other params 72 mechanism.updateConfig(self, config) 73 else: 74 self.logger.critical("Invalid argument to updateConfig(%s)" \ 75 % repr(config)) 76 self.logger.critical("Unable to save status data")
77
78 - def setupWheel(self):
79 """ 80 Runs through an 'auto-fettling procedure'. 81 """ 82 self.logger.debug('setupWheel() called.') 83 OK = [False, False, False, False] 84 85 while not OK[0] or not OK[1] or not OK[2] or not OK[3]: 86 status = self.getStatus() 87 88 # If not at a filter position creep along until we find one. 89 if status % 1: 90 self.logger.debug('Position not found, searching...') 91 OK = [False, False, False, False] 92 search_count = 0 93 94 while status % 1: 95 if search_count > 1200: 96 self.logger.critical(\ 97 'Moved over 90 degrees without finding position!') 98 self.logger.critical('setupWheel() failed!') 99 return 100 self.moveBy(self.direction * 3) 101 search_count += 3 102 status = self.getStatus() 103 104 # Set the zero point. 105 self.setPosition(1200 * status * self.direction) 106 107 # Note current position as OK. 108 self.logger.debug('Located position %i.' % status) 109 OK[status] = True 110 # Move by 90 degrees to next position. 111 self.moveBy(self.direction * 1200) 112 113 self.logger.info('Filter wheel setup complete.')
114
115 - def getStatus(self):
116 """ 117 Returns 0, 1, 2 or 3 if the wheel in position, 0.5, 1.5, 2.5 or 3.5 118 if between positions. 119 """ 120 self.logger.debug('getStatus() called') 121 # First check is the icu is active. 122 if self.cortex.isActive(self.icuNum): 123 self.logger.warning('Attempt to getStatus() while active, ignored') 124 else: 125 self.cortex.setOutput(self.axisNum, self.icuNum) 126 status = self.statusDict[self.cortex.getInput(self.icuNum)] 127 self.cortex.setOutput(7, self.icuNum) 128 return status
129
130 - def goTo(self, filter):
131 """ 132 Moves the wheel to the correct position for the given filter number 133 (0, 1, 2 or 3) or filter name (pass a string) . 134 """ 135 self.logger.debug('goTo(%s) called' % filter) 136 if isinstance(filter, int) and filter in (0, 1, 2, 3): 137 self.moveTo(self.direction * self.stepsPerRev * filter / 4.0, \ 138 blocking = True) 139 status = self.getStatus() 140 if status == filter: 141 self.logger.info('goTo(%i) successful' % filter) 142 else: 143 self.logger.warning('goTo(%i) resulted in status %s' \ 144 % (filter, str(status))) 145 elif isinstance(filter, str) and filter in self.names: 146 number = self.names.index(filter) 147 self.moveTo(self.direction * self.stepsPerRev * number / 4.0, \ 148 blocking = True) 149 status = self.getStatus() 150 if status == number: 151 self.logger.info('goTo(%s) successful' % filter) 152 else: 153 self.logger.warning('goTo(%s) resulted in status %s' \ 154 % (filter, str(status))) 155 else: 156 self.logger.critical('Invalid argument to goTo(%s), ignored' \ 157 % filter)
158
159 - def moveBy(self, steps, blocking=True):
160 """ 161 Moves the filter wheel position by a given number of motor steps. 162 Modifies the move to ensure it's in the correct direction and 163 is of magnitude less than a full rotation. 164 """ 165 self.logger.debug('moveBy(%i, %i) called' % (steps, blocking)) 166 # Ensure the move is in the correct direction and of 167 # magnitude less than a full rotation 168 steps = int(math.fmod(steps, self.stepsPerRev)) 169 if steps * self.direction < 0: 170 steps = self.direction * (self.stepsPerRev - abs(steps)) 171 mechanism.moveBy(self, steps, blocking) 172 # Rationalise the new position. 173 self.position = int(math.fmod(self.position, self.stepsPerRev)) 174 if self.position < 0: 175 self.position = self.stepsPerRev - abs(self.position)
176
177 - def moveTo(self, position, blocking=True):
178 self.logger.debug('moveTo(%i, %i) called' % (position, blocking)) 179 self.moveBy(position - self.position, blocking)
180
181 - def setPosition(self, new_position=0):
182 self.logger.debug('setPosition(%i) called' % new_position) 183 # Rationalise the requested new_position 184 new_position = int(math.fmod(new_position, self.stepsPerRev)) 185 if new_position < 0: 186 new_position = self.stepsPerRev - abs(new_position) 187 self.position = new_position
188