Changeset 469 for trunk/GSASII.py


Ignore:
Timestamp:
Feb 3, 2012 2:55:41 PM (11 years ago)
Author:
toby
Message:

rework phase import

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASII.py

    r468 r469  
    1717import time
    1818import copy
     19import glob
     20import imp
     21import inspect
    1922import numpy as np
    2023import scipy as sp
     
    7881] = [wx.NewId() for _init_coll_Data_Items in range(10)]
    7982
    80 [wxID_IMPORT, wxID_IMPORTPATTERN, wxID_IMPORTHKL, wxID_IMPORTPHASE,
    81 wxID_IMPORTCIF, wxID_IMPORTPDB, 
    82 ] = [wx.NewId() for _init_coll_Import_Items in range(6)]
     83[wxID_IMPORT, wxID_IMPORTPATTERN, wxID_IMPORTHKL
     84#, wxID_IMPORTPHASE,
     85#wxID_IMPORTCIF, wxID_IMPORTPDB, 
     86] = [wx.NewId() for _init_coll_Import_Items in range(3)]
    8387
    8488[wxID_EXPORT, wxID_EXPORTPATTERN, wxID_EXPORTHKL, wxID_EXPORTPHASE,
     
    165169        self.Bind(wx.EVT_MENU, self.OnSolve, id=wxID_SOLVE)
    166170       
     171    def _init_Import_Phase(self,parent):
     172        '''import all the G2importphase*.py files that are found in the
     173        path and configure the Import Phase menus accordingly
     174        '''
     175
     176        path2GSAS2 = os.path.dirname(os.path.realpath(__file__)) # location of this file
     177        pathlist = sys.path[:]
     178        if path2GSAS2 not in pathlist: pathlist.append(path2GSAS2)
     179        filelist = []
     180        for path in pathlist:
     181            for filename in glob.iglob(os.path.join(path, "G2importphase*.py")):
     182                filelist.append(filename)   
     183                #print 'found',filename
     184        filelist = sorted(list(set(filelist))) # remove duplicates
     185        self.ImportPhaseReaderlist = []
     186        for filename in filelist:
     187            path,rootname = os.path.split(filename)
     188            pkg = os.path.splitext(rootname)[0]
     189            try:
     190                fp = None
     191                fp, fppath,desc = imp.find_module(pkg,[path,])
     192                pkg = imp.load_module(pkg,fp,fppath,desc)
     193                for clss in inspect.getmembers(pkg): # find classes defined in package
     194                    if clss[0].startswith('_'): continue
     195                    if inspect.isclass(clss[1]):
     196                        # check if we have the required methods
     197                        for m in 'Reader','ExtensionValidator','ContentsValidator':
     198                            if not hasattr(clss[1],m): break
     199                            if not callable(getattr(clss[1],m)): break
     200                        else:
     201                            reader = clss[1]() # create a phase import instance
     202                            self.ImportPhaseReaderlist.append(reader)
     203            except AttributeError:
     204                print 'Import_Phase: Attribute Error',filename
     205                pass
     206            except ImportError:
     207                print 'Import_Phase: Error importing file',filename
     208                pass
     209            finally:
     210                if fp: fp.close()
     211        item = parent.Append(wx.ID_ANY, help='Import phase data',
     212                      kind=wx.ITEM_NORMAL,text='Import Phase (generic)...')
     213        self.Bind(wx.EVT_MENU, self.OnImportPhaseGeneric, id=item.GetId())
     214        submenu = wx.Menu()
     215        item = parent.AppendMenu(wx.ID_ANY, 'Import Phase (specific)',
     216                                 submenu,
     217                                 help='Import phase data')
     218        self.PhaseImportMenuId = {}
     219        for reader in self.ImportPhaseReaderlist:
     220            item = submenu.Append(wx.ID_ANY,
     221                                  help='Import specific format phase data',
     222                                  kind=wx.ITEM_NORMAL,
     223                                  text='Import Phase '+reader.formatName+'...')
     224            self.PhaseImportMenuId[item.GetId()] = reader
     225            self.Bind(wx.EVT_MENU, self.OnImportPhaseGeneric, id=item.GetId())
     226
     227    def OnImportPhaseGeneric(self,event):
     228        # find out which format was requested
     229        reader = self.PhaseImportMenuId.get(event.GetId())
     230        if reader is None:
     231            #print "use all formats"
     232            readerlist = self.ImportPhaseReaderlist
     233            choices = "any file (*.*)|*.*"
     234            extdict = {}
     235            # compile a list of allowed extensions
     236            for rd in readerlist:
     237                fmt = rd.formatName
     238                for extn in rd.extensionlist:
     239                    if not extdict.get(extn): extdict[extn] = []
     240                    extdict[extn] += [fmt,]
     241            for extn in sorted(extdict.keys(),
     242                               cmp=lambda x,y: cmp(x.lower(), y.lower())):
     243                fmt = ''
     244                for f in extdict[extn]:
     245                    if fmt != "": fmt += ', '
     246                    fmt += f
     247                choices += "|" + fmt + " file (*" + extn + ")|*" + extn
     248        else:
     249            readerlist = [reader,]
     250            # compile a list of allowed extensions
     251            choices = reader.formatName + " file ("
     252            w = ""
     253            for extn in reader.extensionlist:
     254                if w != "": w += ";"
     255                w += "*" + extn
     256            choices += w + ")|" + w
     257            if not reader.strictExtension:
     258                choices += "|any file (*.*)|*.*"
     259        # get the file
     260        dlg = wx.FileDialog(
     261            self, message="Choose phase input file",
     262            #defaultDir=os.getcwd(),
     263            defaultFile="",
     264            wildcard=choices,
     265            style=wx.OPEN | wx.CHANGE_DIR
     266            )
     267        try:
     268            if dlg.ShowModal() == wx.ID_OK:
     269                file = dlg.GetPath()
     270            else: # cancel was pressed
     271                return
     272        finally:
     273            dlg.Destroy()
     274        # set what formats are compatible with this file
     275        primaryReaders = []
     276        secondaryReaders = []
     277        for reader in readerlist:
     278            flag = reader.ExtensionValidator(file)
     279            if flag is None:
     280                secondaryReaders.append(reader)
     281            elif flag:
     282                primaryReaders.append(reader)
     283        if len(secondaryReaders) + len(primaryReaders) == 0:
     284            self.ErrorDialog('No matching format for file '+file,'No Format')
     285            return
     286       
     287        fp = None
     288        try:
     289            fp = open(file,'r')
     290            # try the file first with Readers that specify the
     291            # files extension and later with ones that allow it
     292            for rd in primaryReaders+secondaryReaders:
     293                if not rd.ContentsValidator(fp):
     294                    continue # rejected on cursory check
     295                #flag = rd.Reader(file,fp,self)
     296                try:
     297                    flag = rd.Reader(file,fp,self)
     298                except:
     299                    self.ErrorDialog('Error reading file '+file
     300                                     +' with format '+ rd.formatName,
     301                                     'Read Error')
     302                    continue
     303                if not flag: continue
     304                dlg = wx.TextEntryDialog( # allow editing of phase name
     305                    self, 'Enter the name for the new phase',
     306                    'Edit phase name', rd.Phase['General']['Name'],
     307                    style=wx.OK)
     308                #dlg.SetValue("Python is the best!")
     309                dlg.CenterOnParent()
     310                if dlg.ShowModal() == wx.ID_OK:
     311                    rd.Phase['General']['Name'] = dlg.GetValue()
     312                dlg.Destroy()
     313                PhaseName = rd.Phase['General']['Name']
     314                if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
     315                    sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
     316                else:
     317                    sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
     318                psub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
     319                self.PatternTree.SetItemPyData(psub,rd.Phase)
     320                self.PatternTree.Expand(self.root) # make sure phases are seen
     321                self.PatternTree.Expand(sub)
     322                self.PatternTree.Expand(psub)
     323                return # success
     324        except:
     325            self.ErrorDialog('Error on open of file '+file,'Open Error')
     326        finally:
     327            if fp: fp.close()
     328
     329        return
     330       
     331
    167332    def _init_coll_Import_Items(self,parent):
    168         self.ImportPhase = parent.Append(help='Import phase data from GSAS EXP file',
    169             id=wxID_IMPORTPHASE, kind=wx.ITEM_NORMAL,text='Import GSAS EXP Phase...')
    170         self.ImportPDB = parent.Append(help='Import phase data from PDB file',
    171             id=wxID_IMPORTPDB, kind=wx.ITEM_NORMAL,text='Import PDB Phase...')
    172         self.ImportCIF = parent.Append(help='Import phase data from cif file',id=wxID_IMPORTCIF, kind=wx.ITEM_NORMAL,
    173             text='Import CIF Phase...')
     333#        self.ImportPhase = parent.Append(help='Import phase data from GSAS EXP file',
     334#            id=wxID_IMPORTPHASE, kind=wx.ITEM_NORMAL,text='Import GSAS EXP Phase...')
     335#        self.ImportPDB = parent.Append(help='Import phase data from PDB file',
     336#            id=wxID_IMPORTPDB, kind=wx.ITEM_NORMAL,text='Import PDB Phase...')
     337#        self.ImportCIF = parent.Append(help='Import phase data from cif file',id=wxID_IMPORTCIF, kind=wx.ITEM_NORMAL,
     338#            text='Import CIF Phase...')
    174339        self.ImportPattern = parent.Append(help='',id=wxID_IMPORTPATTERN, kind=wx.ITEM_NORMAL,
    175340            text='Import Powder Pattern...')
    176341        self.ImportHKL = parent.Append(help='',id=wxID_IMPORTHKL, kind=wx.ITEM_NORMAL,
    177342            text='Import HKLs...')
    178         self.Bind(wx.EVT_MENU, self.OnImportPhase, id=wxID_IMPORTPHASE)
    179         self.Bind(wx.EVT_MENU, self.OnImportPDB, id=wxID_IMPORTPDB)
    180         self.Bind(wx.EVT_MENU, self.OnImportCIF, id=wxID_IMPORTCIF)
     343#        self.Bind(wx.EVT_MENU, self.OnImportPhase, id=wxID_IMPORTPHASE)
     344#        self.Bind(wx.EVT_MENU, self.OnImportPDB, id=wxID_IMPORTPDB)
     345#        self.Bind(wx.EVT_MENU, self.OnImportCIF, id=wxID_IMPORTCIF)
    181346        self.Bind(wx.EVT_MENU, self.OnImportPattern, id=wxID_IMPORTPATTERN)
    182347        self.Bind(wx.EVT_MENU, self.OnImportHKL, id=wxID_IMPORTHKL)
     
    220385        self._init_coll_Data_Items(self.Data)
    221386        self._init_coll_Calculate_Items(self.Calculate)
     387        self._init_Import_Phase(self.Import)
    222388        self._init_coll_Import_Items(self.Import)
    223389        self._init_coll_Export_Items(self.Export)
     
    11771343            dlg.Destroy()
    11781344       
     1345    ''' replaced -- delete soon
    11791346    def OnImportPhase(self,event):
    11801347        dlg = wx.FileDialog(self, 'Choose GSAS EXP file', '.', '',
     
    12151382       
    12161383    def OnImportCIF(self,event):
     1384        def ReadCIFPhase(filename):
     1385            import random as ran
     1386            import GSASIIlattice as G2lat
     1387            anisoNames = ['aniso_u_11','aniso_u_22','aniso_u_33','aniso_u_12','aniso_u_13','aniso_u_23']
     1388            file = open(filename, 'Ur')
     1389            Phase = {}
     1390            Title = ospath.split(filename)[-1]
     1391            print '\n Reading cif file: ',Title
     1392            Compnd = ''
     1393            Atoms = []
     1394            A = np.zeros(shape=(3,3))
     1395            S = file.readline()
     1396            while S:
     1397                if '_symmetry_space_group_name_H-M' in S:
     1398                    SpGrp = S.split("_symmetry_space_group_name_H-M")[1].strip().strip('"').strip("'")
     1399                    E,SGData = G2spc.SpcGroup(SpGrp)
     1400                    if E:
     1401                        print ' ERROR in space group symbol ',SpGrp,' in file ',filename
     1402                        print ' N.B.: make sure spaces separate axial fields in symbol'
     1403                        print G2spc.SGErrors(E)
     1404                        return None
     1405                    S = file.readline()
     1406                elif '_cell' in S:
     1407                    if '_cell_length_a' in S:
     1408                        a = S.split('_cell_length_a')[1].strip().strip('"').strip("'").split('(')[0]
     1409                    elif '_cell_length_b' in S:
     1410                        b = S.split('_cell_length_b')[1].strip().strip('"').strip("'").split('(')[0]
     1411                    elif '_cell_length_c' in S:
     1412                        c = S.split('_cell_length_c')[1].strip().strip('"').strip("'").split('(')[0]
     1413                    elif '_cell_angle_alpha' in S:
     1414                        alp = S.split('_cell_angle_alpha')[1].strip().strip('"').strip("'").split('(')[0]
     1415                    elif '_cell_angle_beta' in S:
     1416                        bet = S.split('_cell_angle_beta')[1].strip().strip('"').strip("'").split('(')[0]
     1417                    elif '_cell_angle_gamma' in S:
     1418                        gam = S.split('_cell_angle_gamma')[1].strip().strip('"').strip("'").split('(')[0]
     1419                    S = file.readline()
     1420                elif 'loop_' in S:
     1421                    labels = {}
     1422                    i = 0
     1423                    while S:
     1424                        S = file.readline()
     1425                        if '_atom_site' in S.strip()[:10]:
     1426                            labels[S.strip().split('_atom_site_')[1].lower()] = i
     1427                            i += 1
     1428                        else:
     1429                            break
     1430                    if labels:
     1431                        if 'aniso_label' not in labels:
     1432                            while S:
     1433                                atom = ['','','',0,0,0,1.0,'','','I',0.01,0,0,0,0,0,0]
     1434                                S.strip()
     1435                                if len(S.split()) != len(labels):
     1436                                    if 'loop_' in S:
     1437                                        break
     1438                                    S += file.readline().strip()
     1439                                data = S.split()
     1440                                if len(data) != len(labels):
     1441                                    break
     1442                                for key in labels:
     1443                                    if key == 'type_symbol':
     1444                                        atom[1] = data[labels[key]]
     1445                                    elif key == 'label':
     1446                                        atom[0] = data[labels[key]]
     1447                                    elif key == 'fract_x':
     1448                                        atom[3] = float(data[labels[key]].split('(')[0])
     1449                                    elif key == 'fract_y':
     1450                                        atom[4] = float(data[labels[key]].split('(')[0])
     1451                                    elif key == 'fract_z':
     1452                                        atom[5] = float(data[labels[key]].split('(')[0])
     1453                                    elif key == 'occupancy':
     1454                                        atom[6] = float(data[labels[key]].split('(')[0])
     1455                                    elif key == 'thermal_displace_type':
     1456                                        if data[labels[key]].lower() == 'uiso':
     1457                                            atom[9] = 'I'
     1458                                            atom[10] = float(data[labels['u_iso_or_equiv']].split('(')[0])
     1459                                        else:
     1460                                            atom[9] = 'A'
     1461                                            atom[10] = 0.0
     1462
     1463                                atom[7],atom[8] = G2spc.SytSym(atom[3:6],SGData)
     1464                                atom.append(ran.randint(0,sys.maxint))
     1465                                Atoms.append(atom)
     1466                                S = file.readline()
     1467                        else:
     1468                            while S:
     1469                                S.strip()
     1470                                data = S.split()
     1471                                if len(data) != len(labels):
     1472                                    break
     1473                                name = data[labels['aniso_label']]
     1474                                for atom in Atoms:
     1475                                    if name == atom[0]:
     1476                                        for i,uname in enumerate(anisoNames):
     1477                                            atom[i+11] = float(data[labels[uname]].split('(')[0])
     1478                                S = file.readline()
     1479
     1480                else:           
     1481                    S = file.readline()
     1482            file.close()
     1483            if Title:
     1484                PhaseName = Title
     1485            else:
     1486                PhaseName = 'None'
     1487            SGlines = G2spc.SGPrint(SGData)
     1488            for line in SGlines: print line
     1489            cell = [float(a),float(b),float(c),float(alp),float(bet),float(gam)]
     1490            Volume = G2lat.calc_V(G2lat.cell2A(cell))
     1491            Phase['General'] = {'Name':PhaseName,'Type':'nuclear','SGData':SGData,
     1492                'Cell':[False,]+cell+[Volume,]}
     1493            Phase['Atoms'] = Atoms
     1494            Phase['Drawing'] = {}
     1495            Phase['Histograms'] = {}
     1496
     1497            return Phase
     1498
    12171499        dlg = wx.FileDialog(self, 'Choose CIF file', '.', '',
    12181500            'CIF file (*.cif)|*.cif',wx.OPEN|wx.CHANGE_DIR)
     
    12201502            if dlg.ShowModal() == wx.ID_OK:
    12211503                CIFfile = dlg.GetPath()
    1222                 Phase = G2IO.ReadCIFPhase(CIFfile)
     1504                Phase = ReadCIFPhase(CIFfile)
    12231505        finally:
    12241506            dlg.Destroy()
     
    12301512                sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
    12311513            sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
    1232             self.PatternTree.SetItemPyData(sub,Phase)       
    1233        
     1514            self.PatternTree.SetItemPyData(sub,Phase)
     1515            print Phase
     1516'''
     1517
    12341518    def OnExportPatterns(self,event):
    12351519        names = ['All']
Note: See TracChangeset for help on using the changeset viewer.