def getScanAngles(self, scan, angleNames): """ This function returns all of the geometry angles for the for the scan as a N-by-num_geo array, where N is the number of scan points and num_geo is the number of geometry motors. :param scan: scan from which to retrieve the angles :params angleNames: a list of names for the angles to be returned """ try: dataKeys = scan.data.keys() except IndexError as ie: logger.exception(str(ie) ) raise ie except Exception as ex: logger.exception(str(ex) + "at scan " + str(scan.scanNum)) raise ex if len(dataKeys) == 0: raise ScanDataMissingException("No Scan Data Found for scan " + scan.scanNum) geoAngles = np.zeros((len(scan.data[dataKeys[0]]), len(angleNames))) for i, name in enumerate(angleNames): v = scan.data.get(name) p = scan.positioner.get(name) if v != None: if len(v) == 1: v = np.ones(len(scan.data[scan.data.keys()[0]])) * v elif p != None: v = np.ones(len(scan.data[scan.data.keys()[0]])) * p else: raise InstConfigException("Could not find angle " + name + \ " in scan parameters") geoAngles[:,i] = v return geoAngles
def getSampleAngleMappingPrimaryAngles(self): ''' :return: The name of a function to be used in mapping ''' function = self.root.find(SAMPLE_ANGLE_MAP_FUNCTION) if function is None: raise InstConfigException("No Mapping function defined in " +\ "instrument config file") angles = [] primaryAngles = function.findall(PRIMARY_ANGLE) if primaryAngles is None: raise InstConfigException("No primaryAngle members in " + \ "sampleAngleMapFunction in instrument config") for angle in primaryAngles: angles.append(int(angle.attrib[AXIS_NUMBER])) angles.sort() return angles
def __init__(self, filename): ''' ''' self.root = None try: tree = ET.parse(filename) except IOError as ex: raise (InstConfigException("Bad Instrument Configuration File" + str(ex))) self.root = tree.getroot()
def getPrimaryBeamDirection(self): ''' :return: The direction of primary beam ''' direction = \ self.root.find(PRIMARY_BEAM_DIRECTION) if direction is None: raise InstConfigException("Missing primary beam direction " + \ "in instrument config file") return self._makeReferenceDirection(direction )
def getDetectorCircles(self): ''' :return: The detector children as and element list. If detector circles is not included in the file raise an InstConfigException ''' circles = self.root.find(DETECTOR_CIRCLES) if circles is None: raise InstConfigException("Instrument configuration has no " +\ "Detector Circles") return self.root.find(DETECTOR_CIRCLES).getchildren()
def getSampleAngleMappingReferenceAngles(self): ''' ''' function = self.root.find(SAMPLE_ANGLE_MAP_FUNCTION) if function is None: raise InstConfigException("No Mapping function defined in " + \ "instrument config file") angles = {} angleList = [] referenceAngles = function.findall(REFERENCE_ANGLE) if referenceAngles is None: raise InstConfigException("No referenceAngle members in " + \ "sampleAngleMapFunction in instrument config") for angle in referenceAngles: angles[int(angle.attrib[AXIS_NUMBER])] = \ angle.attrib[SPEC_MOTOR_NAME] for i in angles.keys(): angleList.append(angles[i]) return angleList
def getSampleSurfaceNormalDirection(self): ''' :return: The sample surface normal direction as a list of 3 numbers ''' direction = \ self.root.find(SAMPLE_SURFACE_NORMAL_DIRECTION) if direction is None: raise InstConfigException("Missing sample surface normal " + \ "direction in instrument config file") return self._makeReferenceDirection(direction )
def getInplaneReferenceDirection(self): ''' :return: The In-plane reference direction ''' direction = \ self.root.find(INPLANE_REFERENCE_DIRECTION) if direction is None: raise InstConfigException("Missing in-plane reference direction " + \ "in instrument config file") return self._makeReferenceDirection(direction )
def getSampleCircles(self): ''' :return: The sample children as and element list. If sample circles is not included in the file raise an InstConfigException ''' circles = self.root.find(SAMPLE_CIRCLES) if circles is None: raise InstConfigException("Instrument configuration has no Sample" + " Circles") return circles.getchildren()
def getCircleAxisNumber(self, circle): ''' :param circle: specifies the detector who's return value is requested :return: The axis number for the given circle ''' try: axisNumberStr = circle.attrib[AXIS_NUMBER] except KeyError: raise InstConfigException("Axis number is empty in \n" + \ ET.tostring(circle) + \ "\nIn the instrument config file") return int(axisNumberStr)
def _makeReferenceDirection(self, direction): ''' Create a list of reference directions from the XML :param direction: the XML representation of the circle ''' axes = direction.findall(REFERENCE_AXIS) if len(axes) != 3: raise InstConfigException("Axes not defined properly in \n" + \ ET.tostring(direction) + \ "\nin instrument config file") refAxis = {} for axis in axes: try: refAxis[int(axis.attrib[AXIS_NUMBER])] = int(axis.text) except ValueError: raise InstConfigException("Values and axis numbers in " + \ ET.tostring(direction) + \ " in instrument configuration file") return [refAxis[1], refAxis[2], refAxis[3]]
def getProjectionDirection(self): ''' :return: The direction to be used for constructing Stereographic projections. ''' direction = \ self.root.find(PROJECTION_DIRECTION) if direction is None: message = PROJECTION_DIRECTION + \ " was not found in the instrument config file" raise InstConfigException(message) return self._makeReferenceDirection(direction )
def getSampleAngleMappingAlwaysFix(self): function = self.root.find(SAMPLE_ANGLE_MAP_FUNCTION) if function is None: raise InstConfigException("No Mapping function defined in " + \ "instrument config file") alwaysFix = None try: alwaysFix = function.attrib[ALWAYS_FIX] if alwaysFix is None: return False except KeyError: alwaysFix = False return bool(alwaysFix)
def getSampleAngleMappingCalcOnScannedRef(self): ''' :return: true to run mapping function only when a reference angle is scanned ''' function = self.root.find(SAMPLE_ANGLE_MAP_FUNCTION) if function is None: raise InstConfigException("No Mapping function defined in " + \ "instrument config file") if function.attrib[CALC_ON_SCANNED_REF] is None: return False else: if function.attrib[CALC_ON_SCANNED_REF].lower() in \ ['true', '1', 'yes']: return True elif function.attrib[CALC_ON_SCANNED_REF].lower() in \ ['false', '0', 'no']: return False else: raise InstConfigException("Error reading value for " + \ "'calcOnScannedRef' from Instrument " + \ "Config : " + \ str(function.attrib[CALC_ON_SCANNED_REF]))
def getSampleAngleMappingReferenceAngleAttrib(self, \ number=None, \ attribName=None): attribValue = None function = self.root.find(SAMPLE_ANGLE_MAP_FUNCTION) if function is None: raise InstConfigException("No Mapping function defined in " +\ "instrument config file") refAngles = function.findall(REFERENCE_ANGLE) for angle in refAngles: if angle.attrib[SPEC_MOTOR_NAME] == str(number): attribValue = angle.attrib[attribName] if (attribValue is None): raise(AttributeError("Angle " + str(number) + " does not have a value for " + str(attribName))) return attribValue
def getSampleAngleMappingFunctionModule(self): ''' :return: The name of a function to be used in mapping ''' function = self.root.find(SAMPLE_ANGLE_MAP_FUNCTION) if function is None: raise InstConfigException("No Mapping function defined in " +\ "instrument config file") try: module = function.attrib[SAMPLE_ANGLE_MAP_MODULE] except KeyError: module = None if module != None and module != "": print ("Found Module %s" % module) return module else: return None
def getSampleAngleMappingParameter(self, name): ''' Return a named parameter to be used by the mapping function. This parameter is unique to the mapping function. This method returns a string parameter which must be properly cast by the mapping function. Mapping function needs to deal with error cases. None is returned if the named parameter is not defined. :param: name Name of the defined parameter :return: Parameter defined by the XML element 'name' ''' function = self.root.find(SAMPLE_ANGLE_MAP_FUNCTION) if function is None: raise InstConfigException("No Mapping function defined in " +\ "instrument config file") param = function.find(NAMESPACE + name) if param != None and param.text != "": return param.text else: return None
def _makeCircleNames(self, circles): ''' Create a list of circle names from the XML :param circles: the XML representation of the circles ''' data = [] for circle in circles: try: motorName = circle.attrib[SPEC_MOTOR_NAME] axisNumber = circle.attrib[AXIS_NUMBER] except KeyError: raise InstConfigException("missing axis number or " + \ "motorName in\n" + \ ET.tostring(circle) + \ "\nIn the instrument config file") data.append((int(axisNumber), \ motorName)) data.sort() names = [] for dataum in data: names.append(dataum[1]) return names
def _makeCircleDirections(self, circles): ''' Create a list of circle directions from the XML :param circles: the XML representation of the circles ''' data = [] for circle in circles: try: axisNum = circle.attrib[AXIS_NUMBER] directionAxis = circle.attrib[DIRECTION_AXIS] except KeyError: raise InstConfigException("missing axis number or " + \ "axis direction in\n" + \ ET.tostring(circle) + \ "\nIn the instrument config file") data.append((int(axisNum), \ directionAxis)) data.sort() directions = [] for dataum in data: directions.append(dataum[1]) return directions