コード例 #1
0
class Sector33SpecDataSource(SpecXMLDrivenDataSource):
    '''
    Class to load data from spec file and configuration xml files from 
    for the way that data is collected at sector 33.
    :members
    '''


    def __init__(self, 
                 projectDir, 
                 projectName, 
                 projectExtension,
                 instConfigFile, 
                 detConfigFile, 
                 **kwargs):
        '''
        Constructor
        :param projectDir: Directory holding the project file to open
        :param projectName: First part of file name for the project
        :param projectExt: File extension for the project file.
        :param instConfigFile: Full path to Instrument configuration file.
        :param detConfigFile: Full path to the detector configuration file
        :param kwargs: Assorted keyword arguments

        :rtype: Sector33SpecDataSource
        '''
        super(Sector33SpecDataSource, self).__init__(projectDir, 
                                                     projectName, 
                                                     projectExtension,
                                                     instConfigFile, 
                                                     detConfigFile, 
                                                     **kwargs)
        
    def _calc_eulerian_from_kappa(self, primaryAngles=None, 
                                  referenceAngles = None):
        """
        Calculate the eulerian sample angles from the kappa stage angles.
        :param primaryAngles:  list of sample axis numbers to be handled by 
        the conversion
        :param referenceAngles: list of reference angles to be used in angle 
        conversion
        """

        keta = np.deg2rad(referenceAngles[:,0])
        kappa = np.deg2rad(referenceAngles[:,1])
        kphi = np.deg2rad(referenceAngles[:,2])
        kappaParam = self.instConfig.getSampleAngleMappingParameter('kappa')
        
        try:
            if kappaParam != None:
                self.kalpha = np.deg2rad(float(kappaParam))
            else:
                self.kalpha = np.deg2rad(50.000)
            kappaInvertedParam = \
                self.instConfig.getSampleAngleMappingParameter('kappaInverted')
            if kappaInvertedParam != None:
                self.kappa_inverted = self.to_bool(kappaInvertedParam)
            else:
                self.kappa_inverted = False
        except Exception as ex:
            raise RSMap3DException("Error trying to get parameter for " + \
                                "sampleAngleMappingFunction " + \
                                "_calc_eulerian_from_kappa in inst config " + \
                                "file\n" + \
                                str(ex))
        
        _t1 = np.arctan(np.tan(kappa / 2.0) * np.cos(self.kalpha))
        if self.kappa_inverted:
            eta = np.rad2deg(keta + _t1)
            phi = np.rad2deg(kphi + _t1)
        else:
            eta = np.rad2deg(keta - _t1)
            phi = np.rad2deg(kphi - _t1)
        chi = 2.0 * np.rad2deg(np.arcsin(np.sin(kappa / 2.0) * \
                               np.sin(self.kalpha)))
        
        return eta, chi, phi

    def _calc_replace_angle_values(self , primaryAngles=None,
                                   referenceAngles=None):
        '''
        Fix a situation were some constant angle values have been 
        recorded incorrectly and need to be fixed.
        :param primaryAngles:  list of sample axis numbers to be handled by 
        the conversion
        :param referenceAngles: list of reference angles to be used in angle 
        conversion
        '''
        logger.info( "Running " + __name__)
        angles = []
        logger.debug("referenceAngles " + str(referenceAngles))
        mappingAngles = self.instConfig.getSampleAngleMappingReferenceAngles()
        
        logger.debug( "mappingAngles" + str(mappingAngles))
        for ii in range(len(referenceAngles)):
            replaceVal = \
                float(self.instConfig.getSampleAngleMappingReferenceAngleAttrib( \
                                              number= str(mappingAngles[ii]), \
                                              attribName='replaceValue'))
            logger.debug( "primary Angles" + str(referenceAngles))
            angles.append(replaceVal* np.ones(len(referenceAngles[:,ii]),))
            logger.debug("Angles" + str( angles))
        return angles
        
    def fixGeoAngles(self, scan, angles):
        '''
         Fix the angles using a user selected function.
        :param scan: scan to set the angles for
        :param angles: Array of angles to set for this scan  
        '''
        logger.debug( "starting " + __name__)
        needToCorrect = False
        refAngleNames = self.instConfig.getSampleAngleMappingReferenceAngles()
        for refAngleName in refAngleNames:
            alwaysFix = self.instConfig.getSampleAngleMappingAlwaysFix()
            if refAngleName in scan.L or alwaysFix:
                needToCorrect = True
                
        if needToCorrect:
            logger.debug( __name__ + ": Fixing angles")
            refAngles = self.getScanAngles(scan, refAngleNames)
            primaryAngles = self.instConfig.getSampleAngleMappingPrimaryAngles()
            functionName = self.instConfig.getSampleAngleMappingFunctionName()
            functionModuleName = self.instConfig.getSampleAngleMappingFunctionModule()
            logger.debug("sampleMappingFunction moduleName %s" % functionModuleName) 
           #Call a defined method to calculate angles from the reference angles.
            moduleSource = self
            if functionModuleName != None:
                functionModule = importlib.import_module(functionModuleName)
                logger.debug("dir(functionModule)" % dir(functionModule))
                moduleSource = functionModule
            method = getattr(moduleSource, functionName)
            fixedAngles = method(primaryAngles=primaryAngles, 
                                   referenceAngles=refAngles)
            logger.debug ("fixed Angles: " + str(fixedAngles))
            for i in range(len(primaryAngles)):
                logger.debug ("Fixing primaryAngles: %d " % primaryAngles[i])
                angles[:,primaryAngles[i]-1] = fixedAngles[i]
         
    def getGeoAngles(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.
        """
#        scan = self.sd[scanNo]
        geoAngles = self.getScanAngles(scan, angleNames)
        if not (self.instConfig.getSampleAngleMappingFunctionName() == ""):
            tb = None
            try:
                self.fixGeoAngles(scan, geoAngles)
            except Exception as ex:
                tb = traceback.format_exc()
                raise RSMap3DException("Handling exception in getGeoAngles." + \
                                       "\n" + \
                                       str(ex) + \
                                       "\n" + \
                                       str(tb))
        logger.debug("getGeoAngles:\n" + str(geoAngles))
        return geoAngles
    
    def getUBMatrix(self, scan):
        """
        Read UB matrix from the #G3 line from the spec file. 
        """
        try:
            g3 = scan.G["G3"].strip().split()
            g3 = np.array(list(map(float, g3)))
            ub = g3.reshape(-1,3)
            logger.debug("ub " +str(ub))
            return ub
        except:
            logger.error("Unable to read UB Matrix from G3")
            logger.error( '-'*60)
            traceback.print_exc(file=sys.stdout)
            logger.error('-'*60)
            
            
    def hotpixelkill(self, areaData):
        """
        function to remove hot pixels from CCD frames
        ADD REMOVE VALUES IF NEEDED!
        :param areaData: area detector data
        """
        
        for pixel in self.getBadPixels():
            badLoc = pixel.getBadLocation()
            replaceLoc = pixel.getReplacementLocation()
            areaData[badLoc[0],badLoc[1]] = \
                areaData[replaceLoc[0],replaceLoc[1]]
        
        return areaData

    def loadSource(self, mapHKL=False):
        '''
        This method does the work of loading data from the files.  This has been
        split off from the constructor to allow this to be threaded and later 
        canceled.
        :param mapHKL: boolean to mark if the data should be mapped to HKL
        '''
        # Load up the instrument configuration file
        self.loadInstrumentXMLConfig()
        #Load up the detector configuration file
        self.loadDetectorXMLConfig()

        self.specFile = os.path.join(self.projectDir, self.projectName + \
                                     self.projectExt)
        imageDir = os.path.join(self.projectDir, \
                                IMAGE_DIR_MERGE_STR % self.projectName)
        self.imageFileTmp = os.path.join(imageDir, \
                                TIFF_FILE_MERGE_STR % 
                                (self.projectName))
        # if needed load up the bad pixel file.
        if not (self.badPixelFile is None):
            
            badPixelFile = PilatusBadPixelFile(self.badPixelFile)
            self.badPixels = badPixelFile.getBadPixels()
             
        # id needed load the flat field file
        if not (self.flatFieldFile is None):
            self.flatFieldData = np.array(Image.open(self.flatFieldFile)).T
        # Load scan information from the spec file
        try:
            self.sd = SpecDataFile(self.specFile)
            self.mapHKL = mapHKL
            maxScan = int(self.sd.getMaxScanNumber())
            logger.debug("Number of Scans" +  str(maxScan))
            if self.scans  is None:
                self.scans = range(1, maxScan+1)
            imagePath = os.path.join(self.projectDir, 
                            IMAGE_DIR_MERGE_STR % self.projectName)
            
            self.imageBounds = {}
            self.imageToBeUsed = {}
            self.availableScans = []
            self.incidentEnergy = {}
            self.ubMatrix = {}
            self.scanType = {}
            self.progress = 0
            self.progressInc = 1
            # Zero the progress bar at the beginning.
            if self.progressUpdater is not None:
                self.progressUpdater(self.progress, self.progressMax)
            for scan in self.scans:
                if (self.cancelLoad):
                    self.cancelLoad = False
                    raise LoadCanceledException(CANCEL_STR)
                
                else:
                    if (os.path.exists(os.path.join(imagePath, \
                                            SCAN_NUMBER_MERGE_STR % scan))):
                        try:
                            curScan = self.sd.scans[str(scan)]
                            self.scanType[scan] = \
                                self.sd.scans[str(scan)].scanCmd.split()[0]
                            angles = self.getGeoAngles(curScan, self.angleNames)
                            self.availableScans.append(scan)
                            if self.mapHKL==True:
                                self.ubMatrix[scan] = self.getUBMatrix(curScan)
                                if self.ubMatrix[scan] is None:
                                    raise Sector33SpecFileException("UB matrix " + \
                                                                    "not found.")
                            else:
                                self.ubMatrix[scan] = None
                            self.incidentEnergy[scan] = 12398.4 /float(curScan.G['G4'].split()[3])
                            _start_time = time.time()
                            self.imageBounds[scan] = \
                                self.findImageQs(angles, \
                                                 self.ubMatrix[scan], \
                                                 self.incidentEnergy[scan])
                            if self.progressUpdater is not None:
                                self.progressUpdater(self.progress, self.progressMax)
                            logger.info (('Elapsed time for Finding qs for scan %d: ' +
                                   '%.3f seconds') % \
                                   (scan, (time.time() - _start_time)))
                        except ScanDataMissingException:
                            logger.error( "Scan " + str(scan) + " has no data")
                    #Make sure to show 100% completion
            if self.progressUpdater is not None:
                self.progressUpdater(self.progressMax, self.progressMax)
        except IOError:
            raise IOError( "Cannot open file " + str(self.specFile))
        if len(self.getAvailableScans()) == 0:
            raise ScanDataMissingException("Could not find scan data for " + \
                                           "input file \n" + self.specFile + \
                                           "\nOne possible reason for this " + \
                                           "is that the image files are " + \
                                           "missing.  Images are assumed " + \
                                           "to be in " + \
                                           os.path.join(self.projectDir, 
                                        IMAGE_DIR_MERGE_STR % self.projectName))

        self.availableScanTypes = set(self.scanType.values())

        
    
    def to_bool(self, value):
        """
        Note this method found in answer to:
        http://stackoverflow.com/questions/715417/converting-from-a-string-to-boolean-in-python
        Converts 'something' to boolean. Raises exception if it gets a string 
        it doesn't handle.
        Case is ignored for strings. These string values are handled:
          True: 'True', "1", "TRue", "yes", "y", "t"
          False: "", "0", "faLse", "no", "n", "f"
        Non-string values are passed to bool.
        """
        if type(value) == type(''):
            if value.lower() in ("yes", "y", "true",  "t", "1"):
                return True
            if value.lower() in ("no",  "n", "false", "f", "0", ""):
                return False
            raise Exception('Invalid value for boolean conversion: ' + value)
        return bool(value)

    def rawmap(self,scans, angdelta=[0,0,0,0,0],
            adframes=None, mask = None):
        """
        read ad frames and and convert them in reciprocal space
        angular coordinates are taken from the spec file
        or read from the edf file header when no scan number is given (scannr=None)
        """
        
        if mask is None:
            mask_was_none = True
            #mask = [True] * len(self.getImageToBeUsed()[scans[0]])
        else:
            mask_was_none = False
        #sd = spec.SpecDataFile(self.specFile)
        intensity = np.array([])
        
        # fourc goniometer in fourc coordinates
        # convention for coordinate system:
        # x: upwards;
        # y: along the incident beam;
        # z: "outboard" (makes coordinate system right-handed).
        # QConversion will set up the goniometer geometry.
        # So the first argument describes the sample rotations, the second the
        # detector rotations and the third the primary beam direction.
        qconv = xu.experiment.QConversion(self.getSampleCircleDirections(), \
                                    self.getDetectorCircleDirections(), \
                                    self.getPrimaryBeamDirection())
    
        # define experimental class for angle conversion
        #
        # ipdir: inplane reference direction (ipdir points into the primary beam
        #        direction at zero angles)
        # ndir:  surface normal of your sample (ndir points in a direction
        #        perpendicular to the primary beam and the innermost detector
        #        rotation axis)
        en = self.getIncidentEnergy()
        hxrd = xu.HXRD(self.getInplaneReferenceDirection(), \
                       self.getSampleSurfaceNormalDirection(), \
                       en=en[self.getAvailableScans()[0]], \
                       qconv=qconv)

        
        # initialize area detector properties
        if (self.getDetectorPixelWidth() != None ) and \
            (self.getDistanceToDetector() != None):
            hxrd.Ang2Q.init_area(self.getDetectorPixelDirection1(), \
                self.getDetectorPixelDirection2(), \
                cch1=self.getDetectorCenterChannel()[0], \
                cch2=self.getDetectorCenterChannel()[1], \
                Nch1=self.getDetectorDimensions()[0], \
                Nch2=self.getDetectorDimensions()[1], \
                pwidth1=self.getDetectorPixelWidth()[0], \
                pwidth2=self.getDetectorPixelWidth()[1], \
                distance=self.getDistanceToDetector(), \
                Nav=self.getNumPixelsToAverage(), \
                roi=self.getDetectorROI()) 
        else:
            hxrd.Ang2Q.init_area(self.getDetectorPixelDirection1(), \
                self.getDetectorPixelDirection2(), \
                cch1=self.getDetectorCenterChannel()[0], \
                cch2=self.getDetectorCenterChannel()[1], \
                Nch1=self.getDetectorDimensions()[0], \
                Nch2=self.getDetectorDimensions()[1], \
                chpdeg1=self.getDetectorChannelsPerDegree()[0], \
                chpdeg2=self.getDetectorChannelsPerDegree()[1], \
                Nav=self.getNumPixelsToAverage(), 
                roi=self.getDetectorROI()) 
            
        angleNames = self.getAngles()
        scanAngle = {}
        for i in range(len(angleNames)):
            scanAngle[i] = np.array([])
    
        offset = 0
        imageToBeUsed = self.getImageToBeUsed()
        monitorName = self.getMonitorName()
        monitorScaleFactor = self.getMonitorScaleFactor()
        filterName = self.getFilterName()
        filterScaleFactor = self.getFilterScaleFactor()
        for scannr in scans:
            if self.haltMap:
                raise ProcessCanceledException("Process Canceled")
            scan = self.sd.scans[str(scannr)]
            angles = self.getGeoAngles(scan, angleNames)
            scanAngle1 = {}
            scanAngle2 = {}
            for i in range(len(angleNames)):
                scanAngle1[i] = angles[:,i]
                scanAngle2[i] = []
            if monitorName != None:
                monitor_data = scan.data.get(monitorName)
                if monitor_data is None:
                    raise IOError("Did not find Monitor source '" + \
                                  monitorName + \
                                  "' in the Spec file.  Make sure " + \
                                  "monitorName is correct in the " + \
                                  "instrument Config file")
            if filterName != None:
                filter_data = scan.data.get(filterName)
                if filter_data is None:
                    raise IOError("Did not find filter source '" + \
                                  filterName + \
                                  "' in the Spec file.  Make sure " + \
                                  "filterName is correct in the " + \
                                  "instrument Config file")
            # read in the image data
            arrayInitializedForScan = False
            foundIndex = 0
            
            if mask_was_none:
                mask = [True] * len(self.getImageToBeUsed()[scannr])            
            
            for ind in range(len(scan.data[list(scan.data.keys())[0]])):
                if imageToBeUsed[scannr][ind] and mask[ind]:    
                    # read tif image
                    im = Image.open(self.imageFileTmp % (scannr, scannr, ind))
                    img = np.array(im.getdata()).reshape(im.size[1],im.size[0]).T
                    img = self.hotpixelkill(img)
                    ff_data = self.getFlatFieldData()
                    if not (ff_data is None):
                        img = img * ff_data
                    # reduce data siz
                    img2 = xu.blockAverage2D(img, 
                                            self.getNumPixelsToAverage()[0], \
                                            self.getNumPixelsToAverage()[1], \
                                            roi=self.getDetectorROI())

                    # apply intensity corrections
                    if monitorName != None:
                        img2 = img2 / monitor_data[ind] * monitorScaleFactor
                    if filterName != None:
                        img2 = img2 / filter_data[ind] * filterScaleFactor

                    # initialize data array
                    if not arrayInitializedForScan:
                        imagesToProcess = [imageToBeUsed[scannr][i] and mask[i] for i in range(len(imageToBeUsed[scannr]))]
                        if not intensity.shape[0]:
                            intensity = np.zeros((np.count_nonzero(imagesToProcess),) + img2.shape)
                            arrayInitializedForScan = True
                        else: 
                            offset = intensity.shape[0]
                            intensity = np.concatenate(
                                (intensity,
                                (np.zeros((np.count_nonzero(imagesToProcess),) + img2.shape))),
                                axis=0)
                            arrayInitializedForScan = True
                    # add data to intensity array
                    intensity[foundIndex+offset,:,:] = img2
                    for i in range(len(angleNames)):
#                         logger.debug("appending angles to angle2 " + 
#                                      str(scanAngle1[i][ind]))
                        scanAngle2[i].append(scanAngle1[i][ind])
                    foundIndex += 1
            if len(scanAngle2[0]) > 0:
                for i in range(len(angleNames)):
                    scanAngle[i] = \
                        np.concatenate((scanAngle[i], np.array(scanAngle2[i])), \
                                          axis=0)
        # transform scan angles to reciprocal space coordinates for all detector pixels
        angleList = []
        for i in range(len(angleNames)):
            angleList.append(scanAngle[i])
        if self.ubMatrix[scans[0]] is None:
            qx, qy, qz = hxrd.Ang2Q.area(*angleList,  \
                            roi=self.getDetectorROI(), 
                            Nav=self.getNumPixelsToAverage())
        else:
            qx, qy, qz = hxrd.Ang2Q.area(*angleList, \
                            roi=self.getDetectorROI(), 
                            Nav=self.getNumPixelsToAverage(), \
                            UB = self.ubMatrix[scans[0]])
            

        # apply selected transform
        qxTrans, qyTrans, qzTrans = \
            self.transform.do3DTransform(qx, qy, qz)

    
        return qxTrans, qyTrans, qzTrans, intensity
コード例 #2
0
ファイル: readspec.py プロジェクト: ericdill/nexpy
class ImportDialog(BaseImportDialog):
    """Dialog to import SPEC Scans"""

    def __init__(self, parent=None):

        super(ImportDialog, self).__init__(parent)

        self.accepted = False
        from nexpy.gui.consoleapp import _mainwindow

        self.default_directory = _mainwindow.default_directory
        self.import_file = None  # must set in self.get_data()
        self.spec = None

        # progress bar is updated via calls to pdate_progress()
        self.progress_bar = QtGui.QProgressBar()
        self.progress_bar.setVisible(False)

        status_layout = QtGui.QHBoxLayout()
        status_layout.addWidget(self.progress_bar)
        status_layout.addStretch()
        status_layout.addWidget(self.close_buttons())

        self.layout = QtGui.QVBoxLayout()
        self.layout.addLayout(self.filebox())
        self.layout.addLayout(self.scanbox())
        self.layout.addLayout(status_layout)
        self.setLayout(self.layout)

        self.setWindowTitle("Import " + str(filetype))

    def scanbox(self):
        """create widgets for specifying scan range to import"""
        scanminlabel = QtGui.QLabel("Min. Scan")
        self.scanmin = QtGui.QLineEdit()
        self.scanmin.setFixedWidth(100)
        self.scanmin.setAlignment(QtCore.Qt.AlignRight)
        scanmaxlabel = QtGui.QLabel("Max. Scan")
        self.scanmax = QtGui.QLineEdit()
        self.scanmax.setFixedWidth(100)
        self.scanmax.setAlignment(QtCore.Qt.AlignRight)

        scanbox = QtGui.QHBoxLayout()
        scanbox.addWidget(scanminlabel)
        scanbox.addWidget(self.scanmin)
        scanbox.addWidget(scanmaxlabel)
        scanbox.addWidget(self.scanmax)
        return scanbox

    def choose_file(self):
        """
        Opens file dialog, set file text box to the chosen path
        """
        from spec2nexus.spec import SpecDataFile

        dirname = self.get_default_directory(self.filename.text())
        filename = getOpenFileName(self, "Open file", dirname)
        if os.path.exists(filename):
            self.filename.setText(str(filename))
            self.spec = SpecDataFile(self.get_filename())
            self.set_default_directory(os.path.dirname(filename))
            scan_min = self.spec.getMinScanNumber()
            self.scanmin.setText(str(scan_min))
            scan_max = self.spec.getMaxScanNumber()
            self.scanmax.setText(str(scan_max))

    def get_data(self):
        """read the data and return either :class:`NXroot` or :class:`NXentry`"""
        self.import_file = self.get_filename()
        if not os.path.exists(self.import_file):
            return None
        if self.spec is None:
            return None
        scan_min = int(self.scanmin.text())
        scan_max = int(self.scanmax.text())
        all_scans = self.spec.getScanNumbers()
        scans = [s for s in all_scans if scan_min <= s <= scan_max]
        self.spec.progress_bar = self.progress_bar
        self.spec.update_progress = self.update_progress
        return Parser(self.spec).toTree(scans)
コード例 #3
0
class XPCSSpecDataSource(SpecXMLDrivenDataSource):
    def __init__(self, projectDir, projectName, projectExtension,
                 instConfigFile, detConfigFile, **kwargs):

        self.pathToReplace = None
        self.replacePathWith = None
        if kwargs[PATH_TO_REPLACE] != None:
            self.pathToReplace = kwargs[PATH_TO_REPLACE]
            logger.debug("pathToReplace: %s" % self.pathToReplace)

        if kwargs[REPLACE_PATH_WITH] != None:
            self.replacePathWith = kwargs[REPLACE_PATH_WITH]
            logger.debug("replacePathWith: %s" % self.replacePathWith)
        del kwargs[PATH_TO_REPLACE]
        del kwargs[REPLACE_PATH_WITH]

        super(XPCSSpecDataSource,
              self).__init__(projectDir, projectName, projectExtension,
                             instConfigFile, detConfigFile, **kwargs)
        #         self.immDataFile = immDataFile
        logger.debug(METHOD_ENTER_STR)
        self.cancelLoad = False
        logger.debug(METHOD_EXIT_STR)

    def getGeoAngles(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.
        """
        #        scan = self.sd[scanNo]
        geoAngles = self.getScanAngles(scan, angleNames)
        return geoAngles

    def getUBMatrix(self, scan):
        """
        Read UB matrix from the #G3 line from the spec file. 
        """
        try:
            g3 = scan.G["G3"].strip().split()
            g3 = np.array(list(map(float, g3)))
            ub = g3.reshape(-1, 3)
            logger.debug("ub " + str(ub))
            return ub
        except:
            logger.error("Unable to read UB Matrix from G3")
            logger.error('-' * 60)
            traceback.print_exc(file=sys.stdout)
            logger.error('-' * 60)

    def imagesBeforeScan(self, scanNo):
        numImages = 0
        scan = self.sd.scans[str(scanNo)]
        numImages = int(scan.data["img_n"][0])

        return numImages

    def imagesInScan(self, scanNo):
        scan = self.sd.scans[str(scanNo)]
        numImages = len(scan.data_lines)
        return numImages

    def loadSource(self, mapHKL=False):
        logger.debug(METHOD_ENTER_STR)
        #Load up the instrument config XML file
        self.loadInstrumentXMLConfig()
        #Load up the detector configuration file
        self.loadDetectorXMLConfig()
        #         lastScan = None

        self.specFile = os.path.join(self.projectDir, self.projectName + \
                                     self.projectExt)
        try:
            self.sd = SpecDataFile(self.specFile)
            self.mapHKL = mapHKL
            maxScan = int(self.sd.getMaxScanNumber())
            logger.debug("%s scans" % str(maxScan))
            if self.scans is None:
                self.scans = range(1, maxScan + 1)
            imagePath = os.path.join(self.projectDir,
                                     IMAGE_DIR_MERGE_STR % self.projectName)

            self.imageBounds = {}
            self.imageToBeUsed = {}
            self.availableScans = []
            self.incidentEnergy = {}
            self.ubMatrix = {}
            self.scanType = {}
            self.scanDataFile = {}
            self.immDataFileName = {}
            self.progress = 0
            self.progressInc = 1
            self.isCcdScan = {}
            self.dataFilePrefix = {}
            self.containsDark = {}
            self.numberOfDarks = {}
            self.containsRoi = {}
            self.roi = {}
            self.repeatsPoints = {}
            self.numberOfRepeatPoints = {}
            # Zero the progress bar at the beginning.
            if self.progressUpdater is not None:
                self.progressUpdater(self.progress, self.progressMax)
            for scan in self.scans:
                if (self.cancelLoad):
                    self.cancelLoad = False
                    raise LoadCanceledException(CANCEL_STR)

                else:
                    #                     if (os.path.exists(os.path.join(imagePath, \
                    #                                             SCAN_NUMBER_MERGE_STR % scan))):
                    curScan = self.sd.scans[str(scan)]
                    curScan.interpret()
                    logger.debug("scan: %s" % scan)
                    #                     if int(scan) > 1:
                    #                         lastScan = self.sd.scans[str(int(scan)-1)]
                    #                         lastScan.interpret()
                    #                         logger.debug("dir(lastScan) = %s" % dir(lastScan) )
                    #                         logger.debug("lastScan.CCD %s" % lastScan.CCD)
                    try:
                        angles = self.getGeoAngles(curScan, self.angleNames)
                        self.availableScans.append(scan)
                        self.scanType[scan] = \
                            self.sd.scans[str(scan)].scanCmd.split()[0]
                        logger.debug("Scan %s scanType %s" %
                                     (scan, self.scanType[scan]))
                        if self.scanType[scan] == 'xpcsscan':
                            #print dir(self.sd)
                            d = curScan.data
                            h = curScan.header
                            dataFile = curScan.XPCS['batch_name'][0]
                            self.immDataFileName[scan] = dataFile
                            logger.debug("curScan.XPCS %s" % curScan.XPCS)
                            if not (dataFile in self.scanDataFile.keys()):
                                self.scanDataFile[dataFile] = {}
                                numImagesInScan = self.imagesInScan(scan)
                                self.scanDataFile[dataFile][scan] = \
                                    range(0, numImagesInScan)
                                self.scanDataFile[dataFile]['maxIndexImage'] = \
                                    numImagesInScan
                                logger.debug( "scanDataFile for " + \
                                    str(dataFile) + " at scan " + str(scan) + \
                                    " " + str(self.scanDataFile[dataFile][scan]))
                            else:
                                startingImage = \
                                    self.scanDataFile[dataFile]['maxIndexImage']
                                numImagesInScan = self.imagesInScan(scan)
                                self.scanDataFile[dataFile][scan] = \
                                    range(startingImage, \
                                          startingImage + numImagesInScan)
                                self.scanDataFile[dataFile]['maxIndexImage'] = \
                                    startingImage + numImagesInScan
                                logger.debug( "scanDataFile for " + str(dataFile) + \
                                    " at scan " + str(scan) + " " + \
                                    str(self.scanDataFile[dataFile][scan] ))

                            logger.debug("dataFile %s" % dataFile)

                        elif curScan.CCD != None and \
                            'ccdscan' in curScan.CCD.keys():
                            # this is a ccdscan where the defining #CCD lines
                            # were above the #S lines in spec file
                            #TODO
                            d = curScan.data
                            h = curScan.header
                            ccdPart = curScan.CCD
                            COUNTER_ROI_STR = 'counter_roi'
                            REPEAT_POINTS_STR = 'repeats_per_point'

                            self.isCcdScan[scan] = True
                            self.dataFilePrefix[scan] = ccdPart['image_dir'][0]
                            #If the data has moved from the original location
                            # then we need to change the prefixPath
                            if (self.pathToReplace != None) and \
                                (self.replacePathWith !=None):
                                self.dataFilePrefix[scan] = self.dataFilePrefix[scan].\
                                    replace(self.pathToReplace, \
                                            self.replacePathWith)
                            self.containsDark[scan] = DARK_STR in ccdPart.keys(
                            )
                            self.numberOfDarks[scan] = int(
                                ccdPart[DARK_STR][0])
                            self.containsRoi[
                                scan] = COUNTER_ROI_STR in ccdPart.keys()
                            self.roi[scan] = map(int, ccdPart[COUNTER_ROI_STR])
                            self.repeatsPoints[
                                scan] = REPEAT_POINTS_STR in ccdPart.keys()
                            self.numberOfRepeatPoints[scan] = ccdPart[
                                REPEAT_POINTS_STR]

                            logger.debug("isCcdScan[%s] %s" %
                                         (scan, self.isCcdScan[scan]))
                            logger.debug("dataFilePrefix[%s] %s" %
                                         (scan, self.dataFilePrefix[scan]))
                            if self.containsDark[scan]:
                                logger.debug("containsDark[%s] %s" %
                                             (scan, self.containsDark[scan]))
                            logger.debug("numberOfDarks[%s] %s" %
                                         (scan, self.numberOfDarks[scan]))
                            logger.debug("containsRoi[%s] %s" %
                                         (scan, self.containsRoi[scan]))
                            if self.containsRoi[scan]:
                                self.detectorROI = self.roi[scan]
                                self.detectorROI[0] = self.roi[scan][0]
                                self.detectorROI[
                                    1] = self.roi[scan][0] + self.roi[scan][1]
                                self.detectorROI[2] = self.roi[scan][2]
                                self.detectorROI[
                                    3] = self.roi[scan][2] + self.roi[scan][3]
                                logger.debug("roi[%s] %s" %
                                             (scan, self.roi[scan]))
                            logger.debug("repeatsPoints[%s] %s" %
                                         (scan, self.repeatsPoints[scan]))
                            if self.repeatsPoints[scan]:
                                logger.debug(
                                    "numberOfRepeatPoints[%s] %s" %
                                    (scan, self.numberOfRepeatPoints[scan]))

                        if self.mapHKL == True:
                            self.ubMatrix[scan] = self.getUBMatrix(curScan)
                            if self.ubMatrix[scan] is None:
                                raise Sector33SpecFileException("UB matrix " + \
                                                                "not found.")
                        else:
                            self.ubMatrix[scan] = None
                        self.incidentEnergy[scan] = \
                            12398.4 /float(curScan.G['G4'].split()[3])
                        _start_time = time.time()
                        self.imageBounds[scan] = \
                            self.findImageQs(angles, \
                                             self.ubMatrix[scan], \
                                             self.incidentEnergy[scan])
                        if self.progressUpdater is not None:
                            self.progressUpdater(self.progress,
                                                 self.progressMax)
                        logger.debug (('Elapsed time for Finding qs for scan %d: ' +
                               '%.3f seconds') % \
                               (scan, (time.time() - _start_time)))
                        #Make sure to show 100% completion
                    except ScanDataMissingException:
                        logger.debug("scan %s" % scan)
            if self.progressUpdater is not None:
                self.progressUpdater(self.progressMax, self.progressMax)
        except IOError:
            raise IOError("Cannot open file " + str(self.specFile))
#         if len(self.getAvailableScans()) == 0:
#             raise ScanDataMissingException("Could not find scan data for " + \
#                                            "input file \n" + self.specFile + \
#                                            "\nOne possible reason for this " + \
#                                            "is that the image files are " + \
#                                            "missing.  Images are assumed " + \
#                                            "to be in " + \
#                                            os.path.join(self.projectDir,
#                                         IMAGE_DIR_MERGE_STR % self.projectName))
#Load config information from the imm file
        self.availableScanTypes = set(self.scanType.values())
        logger.debug(METHOD_EXIT_STR)

    def rawmap(self, scans, mask=None):

        if mask is None:
            mask_was_none = True
            #mask = [True] * len(self.getImageToBeUsed()[scans[0]])
        else:
            mask_was_none = False

        intensity = np.array([])

        # fourc goniometer in fourc coordinates
        # convention for coordinate system:
        # x: upwards;
        # y: along the incident beam;
        # z: "outboard" (makes coordinate system right-handed).
        # QConversion will set up the goniometer geometry.
        # So the first argument describes the sample rotations, the second the
        # detector rotations and the third the primary beam direction.
        qconv = xu.experiment.QConversion(self.getSampleCircleDirections(), \
                                    self.getDetectorCircleDirections(), \
                                    self.getPrimaryBeamDirection())

        # define experimental class for angle conversion
        #
        # ipdir: inplane reference direction (ipdir points into the primary beam
        #        direction at zero angles)
        # ndir:  surface normal of your sample (ndir points in a direction
        #        perpendicular to the primary beam and the innermost detector
        #        rotation axis)
        en = self.getIncidentEnergy()
        hxrd = xu.HXRD(self.getInplaneReferenceDirection(), \
                       self.getSampleSurfaceNormalDirection(), \
                       en=en[self.getAvailableScans()[0]], \
                       qconv=qconv)

        if (self.getDetectorPixelWidth() != None ) and \
            (self.getDistanceToDetector() != None):
            hxrd.Ang2Q.init_area(self.getDetectorPixelDirection1(), \
                self.getDetectorPixelDirection2(), \
                cch1=self.getDetectorCenterChannel()[0], \
                cch2=self.getDetectorCenterChannel()[1], \
                Nch1=self.getDetectorDimensions()[0], \
                Nch2=self.getDetectorDimensions()[0], \
                pwidth1=self.getDetectorPixelWidth()[0], \
                pwidth2=self.getDetectorPixelWidth()[1], \
                distance=self.getDistanceToDetector(), \
                Nav=self.getNumPixelsToAverage(), \
                roi=self.getDetectorROI())
        else:
            hxrd.Ang2Q.init_area(self.getDetectorPixelDirection1(), \
                self.getDetectorPixelDirection2(), \
                cch1=self.getDetectorCenterChannel()[0], \
                cch2=self.getDetectorCenterChannel()[1], \
                Nch1=self.getDetectorDimensions()[0], \
                Nch2=self.getDetectorDimensions()[0], \
                chpdeg1=self.getDetectorChannelsPerDegree()[0], \
                chpdeg2=self.getDetectorChannelsPerDegree()[1], \
                Nav=self.getNumPixelsToAverage(),
                roi=self.getDetectorROI())

        angleNames = self.getAngles()
        scanAngle = {}
        for i in range(len(angleNames)):
            scanAngle[i] = np.array([])

        imageToBeUsed = self.getImageToBeUsed()
        #get startIndex and length for each image in the immFile
        imageDir = os.path.join(self.projectDir, IMAGES_STR)
        self.progressMax = len(self.scans) * 100
        self.progressInc = 1.0 * 100.0
        self.progress = 0
        for scannr in scans:
            curScan = self.sd.scans[str(scannr)]
            curScan.interpret()
            logger.debug("scan: %s" % scannr)
            #             if int(scannr) > 1:
            #                 lastScan = self.sd.scans[str(int(scannr)-1)]
            #                 lastScan.interpret()
            #                 logger.debug("dir(lastScan) = %s" % dir(curS) )
            #                 logger.debug("lastScan.CCD %s" % lastScan.CCD)
            if curScan.CCD != None and \
                'ccdscan' in curScan.CCD.keys():
                darkImage = None
                darksToSkip = 1
                if self.containsDark[scannr]:
                    numDarks = self.numberOfDarks[scannr]
                    namePrefix = self.dataFilePrefix[scannr]
                    darkName = namePrefix + DARK_STR + \
                            ("_00001-%.5d" % numDarks) + \
                            IMM_STR[1:]
                    try:
                        fp = open(darkName, 'rb')
                        numImagesInFile = getNumberOfImages(fp)
                        fp.close()
                        if numImagesInFile < numDarks:
                            raise RSMap3DException("dark file %s contains " + \
                                                   "only %d images.  Spec " + \
                                                   "file says there should " + \
                                                   "be %d" % \
                                                   (darkName, \
                                                    numImagesInFile, \
                                                    numDarks))
                        imageStartIndex, dlen = \
                            GetStartPositions(darkName, numDarks)
                        images = OpenMultiImm(darkName, darksToSkip -1, \
                                              numDarks - darksToSkip,
                                              imageStartIndex, dlen)
                        darkImage = np.average(images, axis=0)

                    except Exception as ex:
                        logger.exception(ex)
                    # End reading dark Images
                    # start reading sample images
                    numScanPoints = len(curScan.data_lines)
                    angles = self.getGeoAngles(curScan, angleNames)
                    scanAngle1 = {}
                    scanAngle2 = {}
                    for i in range(len(angleNames)):
                        scanAngle1[i] = angles[:, i]
                        scanAngle2[i] = []
                    arrayInitializedForScan = False
                    if mask_was_none:
                        mask = True * len(self.getImageToBeUsed()[scannr])
                    mask1 = np.array(mask)
                    logger.debug("mask1.shape %s" % str(mask1.shape))
                    indexesToProcess = (np.where(mask1 == True))[0]
                    logger.debug("indexesToProcess.shape %s" %
                                 str(indexesToProcess.shape))
                    logger.debug("indexesToProcess %s" % str(indexesToProcess))

                    foundIndex = 0
                    minorProgressInc = self.progressInc / indexesToProcess.shape[
                        0]
                    minorProgress = self.progress
                    for scanno in indexesToProcess:
                        if self.progressUpdater is not None:
                            self.progressUpdater(minorProgress,
                                                 self.progressMax)
                        minorProgress += minorProgressInc
                        fileName = namePrefix + \
                                "%d_%.5d-%.5d" % (scanno, 1,1) + \
                                IMM_STR[1:]
                        logger.debug("Reading filename %s fileName" % fileName)
                        imageStartIndex, dlen = GetStartPositions(fileName, \
                                                                  1)
                        # read single image from file with one image
                        startImage = 0
                        numImages = 1
                        image = OpenMultiImm(fileName, startImage, \
                                             numImages,
                                             imageStartIndex, dlen)[0]
                        if not arrayInitializedForScan:
                            if not intensity.shape[0]:
                                offset = 0
                                intensity = np.zeros((
                                    indexesToProcess.shape[0], ) + image.shape)
                                arrayInitializedForScan = True
                            else:
                                offset = intensity.shape[0]
                                intensity = np.concatenate((intensity, \
                                                            (np.zeros((indexesToProcess.shape[0],) + image.shape))), \
                                                           axis=0)
                        logger.debug("foundIndex %s" % foundIndex)
                        logger.debug(" instensity.shape %s" %
                                     str(intensity.shape))
                        logger.debug("image.shape %s" % str(image.shape))
                        if self.containsDark[scannr]:
                            intensity[foundIndex +
                                      offset, :, :] = image - darkImage
                        else:
                            intensity[foundIndex +
                                      offset, :, :] = image - darkImage

                        for i in range(len(angleNames)):
                            scanAngle2[i].append(scanAngle1[i][scanno])
                        foundIndex += 1
                    if len(scanAngle2[0]) > 0:
                        for i in range(len(angleNames)):

                            scanAngle[i] = np.concatenate(
                                (scanAngle[i], np.array(scanAngle2[i])),
                                axis=0)

            else:
                immDataFile = self.immDataFileName[scannr]
                dataDir = os.path.join(imageDir, immDataFile)
                fullFileName = (glob.glob(os.path.join(
                    dataDir,
                    IMM_STR))[0]).replace('\\', '\\\\').replace('/', '\\\\')
                fullFileName = (glob.glob(os.path.join(dataDir, IMM_STR))[0])
                imageStartIndex = []
                dlen = []
                try:
                    fp = open(fullFileName, "rb")
                    numImages = getNumberOfImages(fp)
                    fp.close()
                    imageStartIndex, dlen = GetStartPositions(fullFileName, \
                                                              numImages)
                    fp = open(fullFileName, "rb")
                    header = readHeader(
                        fp, imageStartIndex[self.scanDataFile[immDataFile]
                                            [scannr][0]])
                    self.detectorROI = [
                        header['row_beg'], header['row_end'],
                        header['col_beg'], header['col_end']
                    ]
                except IOError as ex:
                    logger.error(
                        "Problem opening IMM file to get the start indexes" +
                        str(ex))
                finally:
                    fp.close()
                if self.haltMap:
                    raise ProcessCanceledException("Process Canceled")
                scan = self.sd.scans[str(scannr)]
                angles = self.getGeoAngles(scan, angleNames)
                scanAngle1 = {}
                scanAngle2 = {}
                for i in range(len(angleNames)):
                    scanAngle1[i] = angles[:, i]
                    scanAngle2[i] = []
                arrayInitializedForScan = False
                foundIndex = 0
                if mask_was_none:
                    mask = True * len(self.getImageToBeUsed()[scannr])

                imagesToSkip = \
                    self.imagesBeforeScan(scannr)
                imagesInScan = \
                    self.imagesInScan(scannr)
                mask1 = np.array(mask)
                indexesToProcess = (np.where(mask1 == True))[0]
                startIndex = indexesToProcess[0]
                numberToProcess = len(indexesToProcess)

                images = OpenMultiImm(fullFileName, \
                                      imagesToSkip + startIndex - 1,
                                      numberToProcess,
                                      imageStartIndex,
                                      dlen)
                minorProgressInc = self.progressInc / indexesToProcess.shape[0]
                minorProgress = self.progress
                for ind in indexesToProcess:
                    if self.progressUpdater is not None:
                        self.progressUpdater(minorProgress, self.progressMax)
                    minorProgress += minorProgressInc
                    if imageToBeUsed[scannr][ind] and mask[ind]:
                        img = images[ind - startIndex, :, :]
                        img2 = img

                        #initialize data Array
                        if not arrayInitializedForScan:
                            imagesToProcess = [imageToBeUsed[scannr][i] and mask[i] \
                                               for i in range(len(imageToBeUsed[scannr]))]
                            if not intensity.shape[0]:
                                offset = 0
                                intensity = np.zeros(
                                    (np.count_nonzero(imagesToProcess), ) +
                                    img2.shape)
                                arrayInitializedForScan = True
                            else:
                                offset = intensity.shape[0]
                                intensity = np.concatenate(
                                    (intensity, (np.zeros(
                                        (np.count_nonzero(imagesToProcess), ) +
                                        img2.shape))),
                                    axis=0)
                        #add data to intensity array
                        intensity[foundIndex + offset, :, :] = img2
                        for i in range(len(angleNames)):
                            scanAngle2[i].append(scanAngle1[i][ind])

                        foundIndex += 1

                if len(scanAngle2[0]) > 0:
                    for i in range(len(angleNames)):
                        scanAngle[i] = \
                            np.concatenate((scanAngle[i], np.array(scanAngle2[i])), \
                                        axis=0)
            self.progress += self.progressInc
            if self.progressUpdater is not None:
                self.progressUpdater(self.progress, self.progressMax)

        # transform scan angles to reciprocal space coordinates for all detector
        # pixels
        angleList = []
        for i in range(len(angleNames)):
            angleList.append(scanAngle[i])
        if self.ubMatrix[scans[0]] is None:
            qx, qy, qz  = hxrd.Ang2Q.area( *angleList, \
                                           roi = self.getDetectorROI(),
                                           Nav=self.getNumPixelsToAverage())
        else:
            qx, qy, qz = hxrd.Ang2Q.area( *angleList, \
                                          roi=self.getDetectorROI(), \
                                          Nav=self.getNumPixelsToAverage(),
                                          UB=self.ubMatrix[scans[0]])

        # apply selected transform
        qxTrans, qyTrans, qzTrans = \
            self.transform.do3DTransform(qx, qy, qz)

        logger.debug(
            "Shape of qxTrans %s, qyTrans %s, qzTrans %s, intensity %s" %
            (str(qxTrans.shape), str(qyTrans.shape), str(
                qzTrans.shape), str(intensity.shape)))
        return qxTrans, qyTrans, qzTrans, intensity

    def rawmapSingle(self, scan):
        intensity = np.array([])
        # fourc goniometer in fourc coordinates
        # convention for coordinate system:
        # x: upwards;
        # y: along the incident beam;
        # z: "outboard" (makes coordinate system right-handed).
        # QConversion will set up the goniometer geometry.
        # So the first argument describes the sample rotations, the second the
        # detector rotations and the third the primary beam direction.
        qconv = xu.experiment.QConversion(self.getSampleCircleDirections(), \
                                    self.getDetectorCircleDirections(), \
                                    self.getPrimaryBeamDirection())

        # define experimental class for angle conversion
        #
        # ipdir: inplane reference direction (ipdir points into the primary beam
        #        direction at zero angles)
        # ndir:  surface normal of your sample (ndir points in a direction
        #        perpendicular to the primary beam and the innermost detector
        #        rotation axis)
        en = self.getIncidentEnergy()
        hxrd = xu.HXRD(self.getInplaneReferenceDirection(), \
                       self.getSampleSurfaceNormalDirection(), \
                       en=en[self.getAvailableScans()[0]], \
                       qconv=qconv)

        if (self.getDetectorPixelWidth() != None ) and \
            (self.getDistanceToDetector() != None):
            hxrd.Ang2Q.init_area(self.getDetectorPixelDirection1(), \
                self.getDetectorPixelDirection2(), \
                cch1=self.getDetectorCenterChannel()[0], \
                cch2=self.getDetectorCenterChannel()[1], \
                Nch1=self.getDetectorDimensions()[0], \
                Nch2=self.getDetectorDimensions()[0], \
                pwidth1=self.getDetectorPixelWidth()[0], \
                pwidth2=self.getDetectorPixelWidth()[1], \
                distance=self.getDistanceToDetector(), \
                Nav=self.getNumPixelsToAverage(), \
                roi=self.getDetectorROI())
        else:
            hxrd.Ang2Q.init_area(self.getDetectorPixelDirection1(), \
                self.getDetectorPixelDirection2(), \
                cch1=self.getDetectorCenterChannel()[0], \
                cch2=self.getDetectorCenterChannel()[1], \
                Nch1=self.getDetectorDimensions()[0], \
                Nch2=self.getDetectorDimensions()[0], \
                chpdeg1=self.getDetectorChannelsPerDegree()[0], \
                chpdeg2=self.getDetectorChannelsPerDegree()[1], \
                Nav=self.getNumPixelsToAverage(),
                roi=self.getDetectorROI())

        # Setup list of angles to produce transform
        angleNames = self.getAngles()
        scanAngle = {}
        for i in range(len(angleNames)):
            scanAngle[i] = np.array([])
        logger.debug("scan %s" % scan)
        angles = self.getGeoAngles(self.sd.scans[str(scan)], angleNames)
        angles = np.array([
            angles[0],
        ])
        logger.debug("angles %s" % angles)

        for i in range(len(angleNames)):
            scanAngle[i] = np.concatenate((scanAngle[i], np.array(angles[:,i])), \
                            axis=0)
        # transform scan angles to reciprocal space coordinates for all detector
        # pixels
        angleList = []
        for i in range(len(angleNames)):
            angleList.append(scanAngle[i])

        if self.ubMatrix[scan] is None:
            qx, qy, qz  = hxrd.Ang2Q.area( *angleList, \
                                           roi = self.getDetectorROI(),
                                           Nav=self.getNumPixelsToAverage())
        else:
            qx, qy, qz = hxrd.Ang2Q.area( *angleList, \
                                          roi=self.getDetectorROI(), \
                                          Nav=self.getNumPixelsToAverage(),
                                          UB=self.ubMatrix[scan])

        # apply selected transform
        qxTrans, qyTrans, qzTrans = \
            self.transform.do3DTransform(qx, qy, qz)

        return qxTrans, qyTrans, qzTrans
コード例 #4
0
class ImportDialog(BaseImportDialog):
    """Dialog to import SPEC Scans"""
    def __init__(self, parent=None):

        super(ImportDialog, self).__init__(parent)

        self.accepted = False
        from nexpy.gui.consoleapp import _mainwindow
        self.default_directory = _mainwindow.default_directory
        self.import_file = None  # must set in self.get_data()
        self.spec = None

        # progress bar is updated via calls to pdate_progress()
        self.progress_bar = QtGui.QProgressBar()
        self.progress_bar.setVisible(False)

        status_layout = QtGui.QHBoxLayout()
        status_layout.addWidget(self.progress_bar)
        status_layout.addStretch()
        status_layout.addWidget(self.close_buttons())

        self.layout = QtGui.QVBoxLayout()
        self.layout.addLayout(self.filebox())
        self.layout.addLayout(self.scanbox())
        self.layout.addLayout(status_layout)
        self.setLayout(self.layout)

        self.setWindowTitle("Import " + str(filetype))

    def scanbox(self):
        '''create widgets for specifying scan range to import'''
        scanminlabel = QtGui.QLabel("Min. Scan")
        self.scanmin = QtGui.QLineEdit()
        self.scanmin.setFixedWidth(100)
        self.scanmin.setAlignment(QtCore.Qt.AlignRight)
        scanmaxlabel = QtGui.QLabel("Max. Scan")
        self.scanmax = QtGui.QLineEdit()
        self.scanmax.setFixedWidth(100)
        self.scanmax.setAlignment(QtCore.Qt.AlignRight)

        scanbox = QtGui.QHBoxLayout()
        scanbox.addWidget(scanminlabel)
        scanbox.addWidget(self.scanmin)
        scanbox.addWidget(scanmaxlabel)
        scanbox.addWidget(self.scanmax)
        return scanbox

    def choose_file(self):
        '''
        Opens file dialog, set file text box to the chosen path
        '''
        from spec2nexus.spec import SpecDataFile

        dirname = self.get_default_directory(self.filename.text())
        filename = getOpenFileName(self, 'Open file', dirname)
        if os.path.exists(filename):
            self.filename.setText(str(filename))
            self.spec = SpecDataFile(self.get_filename())
            self.set_default_directory(os.path.dirname(filename))
            scan_min = self.spec.getMinScanNumber()
            self.scanmin.setText(str(scan_min))
            scan_max = self.spec.getMaxScanNumber()
            self.scanmax.setText(str(scan_max))

    def get_data(self):
        '''read the data and return either :class:`NXroot` or :class:`NXentry`'''
        self.import_file = self.get_filename()
        if not os.path.exists(self.import_file):
            return None
        if self.spec is None:
            return None
        scan_min = int(self.scanmin.text())
        scan_max = int(self.scanmax.text())
        all_scans = self.spec.getScanNumbers()
        scans = [s for s in all_scans if scan_min <= s <= scan_max]
        self.spec.progress_bar = self.progress_bar
        self.spec.update_progress = self.update_progress
        return Parser(self.spec).toTree(scans)
コード例 #5
0
class ReadSpec():
    """Loads spec file and gets appropriate information from it for a certain image.
    """

    def __init__(self, parent=None):
        self.mon = []
        self.mainWindow = parent
        self.detectorDialog = DetectorDialog(self)

    def loadSpec(self, specFile, directory):
        """This method loads the spec file and creates the widgets on the control QDockWidget.
        """
        self.chambers = []
        self.specFile = SpecDataFile(specFile)
        self.specHeader = SpecDataFileHeader(specFile)
        self.scans = self.specFile.scans
        self.scan = str(int(os.path.basename(directory)))
        self.specFileOpened = True

        self.maxScans = self.specFile.getMaxScanNumber()

        # Gets possible normalizer values
        for key in self.scans[self.scan].data.keys():
            if key.find("Ion_Ch_") == 0:
                self.chambers.append(key)

        self.chambers.sort()
        self.MonDialog()
        self.mainWindow.controlDockWidget.close()
        self.mainWindow.ControlDockWidget()

    def MonDialog(self):
        """Dialog produce for the user to select the mon value.
        """
        self.monDialog = QDialog(self.mainWindow)
        dialogBox = QVBoxLayout()
        buttonLayout = QHBoxLayout()
        vBox = QVBoxLayout()

        groupBox = QGroupBox("Mon")
        self.buttonGroup = QButtonGroup(groupBox)

        for norm in self.chambers:
            chamberRB = QRadioButton(norm)
            self.buttonGroup.addButton(chamberRB, int(norm[-1]))
            vBox.addWidget(chamberRB)

        groupBox.setLayout(vBox)

        ok = QPushButton("Ok")

        ok.clicked.connect(self.SetMon)

        buttonLayout.addStretch(1)
        buttonLayout.addWidget(ok)

        dialogBox.addWidget(groupBox)
        dialogBox.addLayout(buttonLayout)

        self.monDialog.setWindowTitle("Select chamber")
        self.monDialog.setLayout(dialogBox)
        self.monDialog.resize(250, 250)
        self.monDialog.exec_()

    def SetMon(self):
        """Sets the mon.
        """
        if self.buttonGroup != -1:
            self.monDialog.close()
            for cham in self.chambers:
                if cham.endswith(str(self.buttonGroup.checkedId())):
                    self.mon = self.scans[str(self.scan)].data[cham]

    def DataControlLabels(self):
        """Gets the appropriate labels for the spec file info display in the control's QDockWidget.
        """
        controls = []
        for key in self.scans[self.scan].L:
            if key == 'L':
                controls.append(key)
                break
            else:
                controls.append(key)

        return controls

    def setSpecData(self):
        """Sets the spec data into the self.specInfoValue.
        """
        try:
            self.specInfoValue = []

            for n in self.specInfo:
                if n == "E":
                    self.specInfoValue.append(self.getEnergy())
                elif n == "MON":
                    self.specInfoValue.append(self.mon)
                elif n == "Trans":
                    self.specInfoValue.append(self.scans[self.scan].data["transm"])
                else:
                    self.specInfoValue.append(self.scans[self.scan].data[str(n)])
        except:
            QMessageBox.warning(self.mainWindow, "Warning", "Error loading the values from the spec. Please make sure "
                                                     "they follow the appropriate format.")


    def getSpecData(self, i):
        """Gets the appropriate spec value for the selected image.
        """
        try:
            specValue = []

            for n in self.specInfoValue:
                if isinstance(n, list):
                    specValue.append(n[i])
                else:
                    specValue.append(n)

            j = 0
            for n in specValue:
                self.specInfoBoxes[j].setText(str(n))
                j += 1
        except IndexError:
            QMessageBox.warning(self.mainWindow, "Error", 'Please make sure you have the correct spec file, and/or have have the '
                                           'images folder named properly with the scan number.')

    def SpecDataInfo(self):
        """Creates the labels and text boxes for the spec info display in the Controls QDockWidget.
        """
        self.specInfo = []
        self.specInfoLabels = []
        self.specInfoBoxes = []
        self.specInfoLayout = []

        self.specInfo = self.DataControlLabels()
        self.specInfo.append("E")
        self.specInfo.append("MON")
        self.specInfo.append("Trans")

        for s in self.specInfo:
            label = QLabel(str(s), alignment=Qt.AlignCenter)
            textBox = QLineEdit()
            textBox.setReadOnly(True)
            textBox.setMaximumWidth(50)
            self.specInfoLabels.append(label)
            self.specInfoBoxes.append(textBox)
        j = 0
        vBoxLayout = QVBoxLayout()
        while j < len(self.specInfo):
            if len(self.specInfo) - j >= 3:
                s = 0
                hBox = QHBoxLayout()
                while s < 3:
                    hBox.addWidget(self.specInfoLabels[j])
                    hBox.addWidget(self.specInfoBoxes[j])
                    j += 1
                    s += 1
                vBoxLayout.addLayout(hBox)
            else:
                hBox1 = QHBoxLayout()
                while len(self.specInfo) - j > 0:
                    hBox1.addWidget(self.specInfoLabels[j])
                    hBox1.addWidget(self.specInfoBoxes[j])
                    j += 1
                hBox1.addStretch(1)
                vBoxLayout.addLayout(hBox1)
        self.setSpecData()

        return vBoxLayout

    def getEnergy(self):
        """Gets the energy from the spec file.
        """
        data = self.scans[str(self.scan)].raw
        UE = data.split("#UE")
        ue = UE[1].split(" ")
        energy = ue[1]
        return float(energy) * 1000

    def getUBMatrix(self):
        """Read UB matrix from the #G3 line from the spec file.
        :return: 2D array, with 1D arrays size 3
        """
        try:
            g3 = self.scans[self.scan].G["G3"].strip().split()
            g3 = np.array(map(float, g3))
            ub = g3.reshape(-1, 3)
            return ub

        except:
            print ("Unable to read the UB Matrix from G3.")

    def getListSpecDataForAngles(self):
        """Gets the eta, chi and phi from the spec file.
        :return: returns eta, chi and phi
        """
        angleListInfo = []
        angles = self.detectorDialog.getAngles()
        for angle in angles:
            try:
                angleListInfo.append(self.specFile.scans[self.scan].data[angle])
            except KeyError:
                try:
                    motorValue = self.motorSpecInfoDic[angle]
                    angList = np.full((self.totalScans, 1), float(motorValue), dtype=float)
                    angleListInfo.append(angList)
                except:
                    print ("Make sure there's reference of the angles provided in the spec file..")
        return angleListInfo

    def getSpecHeaderO(self, specFile):
        """Gets the values for the spec motors/angles input by the user.
        :param specFile:
        :return: Dictionary with spec anlge and value
        """
        self.totalScans = 0
        self.motorSpecInfoDic = {}
        buf = open(specFile, 'r').read()
        buf.replace('\r\n', '\n').replace('\r', '\n')

        lines = buf.splitlines()

        for line in lines:
            if line.startswith("#O0"):
                lineO = line
                break

        O = lineO.split()
        O.pop(0)
        lineP = self.specFile.scans[self.scan].P[0]
        P = lineP.split()

        if len(O) != len(P):
            raise Exception ("Please make sure the spec file contains matching information in the header #O0 and under"
                             " the scan #P0.\n\n" "#O0: " + O + "\n#P0: " + P)
        else:
            for i in xrange(len(P)):
                self.motorSpecInfoDic.update({O[i]: P[i]})

        try:
            s = self.scans[self.scan].S.split()
            self.totalScans = int(s[len(s)-2])
        except:
            pass
            # Make the user input the total scans.


    def rawMap(self):
        """Gets the hkl for each image in the scan
        :return:
        """
        #  Some stuff to add for the future:
        #       - Doing the data in chunks if the data is too big
        try:
            intensity = np.array([])
            angleList = self.getListSpecDataForAngles()
            qconv = xu.experiment.QConversion(self.detectorDialog.getSampleCircleDirections(),
                                              self.detectorDialog.getDetectorCircleDirections(),
                                              self.detectorDialog.getPrimaryBeamDirection())

            offset = 0
            scan = self.scans[self.scan]

            en = self.getEnergy()
            hxrd = xu.HXRD(self.detectorDialog.getInplaneReferenceDirection(),
                           self.detectorDialog.getSampleSurfaceNormalDirection(),
                           en=en,
                           qconv=qconv)

            hxrd.Ang2Q.init_area(self.detectorDialog.getDetectorPixelDirection1(),
                                 self.detectorDialog.getDetectorPixelDirection2(),
                                 cch1=self.detectorDialog.getDetectorCenterChannel()[0],
                                 cch2=self.detectorDialog.getDetectorCenterChannel()[1],
                                 Nch1=self.detectorDialog.getDetectorDimensions()[0],
                                 Nch2=self.detectorDialog.getDetectorDimensions()[1],
                                 pwidth1=self.detectorDialog.getDetectorPixelWidth()[0],
                                 pwidth2=self.detectorDialog.getDetectorPixelWidth()[1],
                                 distance=self.detectorDialog.getDistanceToDetector(),
                                 Nav=self.detectorDialog.getNumPixelsToAverage(),
                                 roi=self.detectorDialog.getDetectorROI())

            arrayInitializedForScan = False
            """
            foundIndex = 0
            for ind in xrange(len(scan.data[scan.data.keys()[0]])):
                im = Image.open(self.mainWindow.fileList[ind])
                img = np.array(im.getdata()).reshape(im.size[1], im.size[0]).T

                img2 = xu.blockAverage2D(img,
                                         self.detectorDialog.getNumPixelsToAverage()[0],
                                         self.detectorDialog.getNumPixelsToAverage()[1],
                                         roi=self.detectorDialog.getDetectorROI())"""

            h, k, l = hxrd.Ang2Q.area(*angleList,
                                roi=self.detectorDialog.getDetectorROI(),
                                Nav=self.detectorDialog.getNumPixelsToAverage(),
                                UB = self.getUBMatrix())
            print 'H'
            print h
            print 'k'
            print k
            print 'L'
            print l
            print l[:, 0]
            plt.imshow(l[120])
            plt.colorbar()
            plt.show()
            print l.shape
        except Exception as ex:
            QMessageBox.warning(self.mainWindow, "Error",
                                "Something went wrong while getting the rawmap. \n\n Exception: " + str(ex))