Changeset 1168 for trunk/GSASIIIO.py


Ignore:
Timestamp:
Dec 16, 2013 10:43:01 AM (8 years ago)
Author:
toby
Message:

update imports to provide error messages

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIIO.py

    r1165 r1168  
    10621062        }
    10631063    return phaseData
    1064    
    1065 def ReadEXPPhase(G2frame,filename):
    1066     '''Read a phase from a GSAS .EXP file.
    1067     Called in the GSAS phase import routine (see imports/G2phase.py)
    1068     '''
    1069     shModels = ['cylindrical','none','shear - 2/m','rolling - mmm']
    1070     textureData = {'Order':0,'Model':'cylindrical','Sample omega':[False,0.0],
    1071         'Sample chi':[False,0.0],'Sample phi':[False,0.0],'SH Coeff':[False,{}],
    1072         'SHShow':False,'PFhkl':[0,0,1],'PFxyz':[0,0,1],'PlotType':'Pole figure'}
    1073     shNcof = 0
    1074     file = open(filename, 'Ur')
    1075     S = 1
    1076     Expr = [{},{},{},{},{},{},{},{},{}]
    1077     while S:
    1078         S = file.readline()
    1079         if 'EXPR NPHAS' in S[:12]:
    1080             Num = S[12:-1].count('0')
    1081             NPhas = S[12:-1].split()
    1082         if 'CRS' in S[:3]:
    1083             N = int(S[3:4])-1
    1084             Expr[N][S[:12]] = S[12:-1]
    1085     file.close()
    1086     PNames = []
    1087     for n,N in enumerate(NPhas):
    1088         if N != '0':
    1089             result = n
    1090             key = 'CRS'+str(n+1)+'    PNAM'
    1091             PNames.append(Expr[n][key])
    1092     if Num < 8:
    1093         dlg = wx.SingleChoiceDialog(G2frame, 'Which phase to read?', 'Read phase data', PNames, wx.CHOICEDLG_STYLE)
    1094         try:
    1095             if dlg.ShowModal() == wx.ID_OK:
    1096                 result = dlg.GetSelection()
    1097         finally:
    1098             dlg.Destroy()       
    1099     EXPphase = Expr[result]
    1100     keyList = EXPphase.keys()
    1101     keyList.sort()
    1102     SGData = {}
    1103     if NPhas[result] == '1':
    1104         Ptype = 'nuclear'
    1105     elif NPhas[result] in ['2','3']:
    1106         Ptype = 'magnetic'
    1107     elif NPhas[result] == '4':
    1108         Ptype = 'macromolecular'
    1109     elif NPhas[result] == '10':
    1110         Ptype = 'Pawley'
    1111     for key in keyList:
    1112         if 'PNAM' in key:
    1113            PhaseName = EXPphase[key].strip()
    1114         elif 'ABC   ' in key:
    1115             abc = [float(EXPphase[key][:10]),float(EXPphase[key][10:20]),float(EXPphase[key][20:30])]                       
    1116         elif 'ANGLES' in key:
    1117             angles = [float(EXPphase[key][:10]),float(EXPphase[key][10:20]),float(EXPphase[key][20:30])]                                               
    1118         elif 'SG SYM' in key:
    1119             SpGrp = EXPphase[key][:15].strip()
    1120             E,SGData = G2spc.SpcGroup(SpGrp)
    1121             if E:
    1122                 E,SGData = G2spc.SpcGroup('P 1') # unlikely to need this
    1123         elif 'OD    ' in key:
    1124             SHdata = EXPphase[key].split() # may not have all 9 values
    1125             SHvals = 9*[0]
    1126             for i in range(9):
    1127                 try:
    1128                     float(SHdata[i])
    1129                     SHvals[i] = SHdata[i]
    1130                 except:
    1131                     pass
    1132             textureData['Order'] = int(SHvals[0])
    1133             textureData['Model'] = shModels[int(SHvals[2])]
    1134             textureData['Sample omega'] = [False,float(SHvals[6])]
    1135             textureData['Sample chi'] = [False,float(SHvals[7])]
    1136             textureData['Sample phi'] = [False,float(SHvals[8])]
    1137             shNcof = int(SHvals[1])
    1138     Atoms = []
    1139     if Ptype == 'nuclear':
    1140         for key in keyList:
    1141             if 'AT' in key:
    1142                 if key[11:] == 'A':
    1143                     S = EXPphase[key]
    1144                 elif key[11:] == 'B':
    1145                     S += EXPphase[key]
    1146                     Atom = [S[50:58].strip(),S[:10].strip().capitalize(),'',
    1147                         float(S[10:20]),float(S[20:30]),float(S[30:40]),
    1148                         float(S[40:50]),'',int(S[60:62]),S[130:131]]
    1149                     if Atom[9] == 'I':
    1150                         Atom += [float(S[68:78]),0.,0.,0.,0.,0.,0.]
    1151                     elif Atom[9] == 'A':
    1152                         Atom += [0.0,float(S[68:78]),float(S[78:88]),
    1153                             float(S[88:98]),float(S[98:108]),
    1154                             float(S[108:118]),float(S[118:128])]
    1155                     XYZ = Atom[3:6]
    1156                     Atom[7],Atom[8] = G2spc.SytSym(XYZ,SGData)
    1157                     Atom.append(ran.randint(0,sys.maxint))
    1158                     Atoms.append(Atom)
    1159     elif Ptype == 'macromolecular':
    1160         for key in keyList:
    1161             if 'AT' in key[6:8]:
    1162                 S = EXPphase[key]
    1163                 Atom = [S[56:60],S[50:54].strip().upper(),S[54:56],
    1164                     S[46:51].strip(),S[:8].strip().capitalize(),'',
    1165                     float(S[16:24]),float(S[24:32]),float(S[32:40]),
    1166                     float(S[8:16]),'1',1,'I',float(S[40:46]),0,0,0,0,0,0]
    1167                 XYZ = Atom[6:9]
    1168                 Atom[10],Atom[11] = G2spc.SytSym(XYZ,SGData)
    1169                 Atom.append(ran.randint(0,sys.maxint))
    1170                 Atoms.append(Atom)
    1171     Volume = G2lat.calc_V(G2lat.cell2A(abc+angles))
    1172     if shNcof:
    1173         shCoef = {}
    1174         nRec = [i+1 for i in range((shNcof-1)/6+1)]
    1175         for irec in nRec:
    1176             ODkey = keyList[0][:6]+'OD'+'%3dA'%(irec)
    1177             indx = EXPphase[ODkey].split()
    1178             ODkey = ODkey[:-1]+'B'
    1179             vals = EXPphase[ODkey].split()
    1180             for i,val in enumerate(vals):
    1181                 key = 'C(%s,%s,%s)'%(indx[3*i],indx[3*i+1],indx[3*i+2])
    1182                 shCoef[key] = float(val)
    1183         textureData['SH Coeff'] = [False,shCoef]
    1184        
    1185     Phase = SetNewPhase(Name=PhaseName,SGData=SGData,cell=abc+angles+[Volume,])
    1186     general = Phase['General']
    1187     general['Type'] = Ptype
    1188     if general['Type'] =='macromolecular':
    1189         general['AtomPtrs'] = [6,4,10,12]
    1190     else:
    1191         general['AtomPtrs'] = [3,1,7,9]   
    1192     general['SH Texture'] = textureData
    1193     Phase['Atoms'] = Atoms
    1194     return Phase
    11951064       
    1196 def ReadPDBPhase(filename):
    1197     '''Read a phase from a PDB file.
    1198     Called in the PDB phase import routine (see imports/G2phase.py)
    1199     '''
    1200     EightPiSq = 8.*math.pi**2
    1201     file = open(filename, 'Ur')
    1202     Phase = {}
    1203     Title = ''
    1204     Compnd = ''
    1205     Atoms = []
    1206     A = np.zeros(shape=(3,3))
    1207     S = file.readline()
    1208     while S:
    1209         Atom = []
    1210         if 'TITLE' in S[:5]:
    1211             Title = S[10:72].strip()
    1212             S = file.readline()
    1213         elif 'COMPND    ' in S[:10]:
    1214             Compnd = S[10:72].strip()
    1215             S = file.readline()
    1216         elif 'CRYST' in S[:5]:
    1217             abc = S[7:34].split()
    1218             angles = S[34:55].split()
    1219             cell=[float(abc[0]),float(abc[1]),float(abc[2]),
    1220                 float(angles[0]),float(angles[1]),float(angles[2])]
    1221             Volume = G2lat.calc_V(G2lat.cell2A(cell))
    1222             AA,AB = G2lat.cell2AB(cell)
    1223             SpGrp = S[55:65]
    1224             E,SGData = G2spc.SpcGroup(SpGrp)
    1225             # space group processing failed, try to look up name in table
    1226             if E:
    1227                 SpGrpNorm = G2spc.StandardizeSpcName(SpGrp)
    1228                 if SpGrpNorm:
    1229                     E,SGData = G2spc.SpcGroup(SpGrpNorm)
    1230             while E:
    1231                 print G2spc.SGErrors(E)
    1232                 dlg = wx.TextEntryDialog(None,
    1233                     SpGrp[:-1]+' is invalid \nN.B.: make sure spaces separate axial fields in symbol',
    1234                     'ERROR in space group symbol','',style=wx.OK)
    1235                 if dlg.ShowModal() == wx.ID_OK:
    1236                     SpGrp = dlg.GetValue()
    1237                     E,SGData = G2spc.SpcGroup(SpGrp)
    1238                 else:
    1239                     return None
    1240                 dlg.Destroy()               
    1241             SGlines = G2spc.SGPrint(SGData)
    1242             for line in SGlines: print line
    1243             S = file.readline()
    1244         elif 'SCALE' in S[:5]:
    1245             V = (S[10:41].split())
    1246             A[int(S[5])-1] = [float(V[0]),float(V[1]),float(V[2])]
    1247             S = file.readline()
    1248         elif 'ATOM' in S[:4] or 'HETATM' in S[:6]:
    1249             XYZ = [float(S[31:39]),float(S[39:47]),float(S[47:55])]
    1250             XYZ = np.inner(AB,XYZ)
    1251             XYZ = np.where(abs(XYZ)<0.00001,0,XYZ)
    1252             SytSym,Mult = G2spc.SytSym(XYZ,SGData)
    1253             Uiso = float(S[61:67])/EightPiSq
    1254             Type = S[12:14].lower()
    1255             if Type[0] in '123456789':
    1256                 Type = Type[1:]
    1257             Atom = [S[22:27].strip(),S[17:20].upper(),S[20:22],
    1258                 S[12:17].strip(),Type.strip().capitalize(),'',XYZ[0],XYZ[1],XYZ[2],
    1259                 float(S[55:61]),SytSym,Mult,'I',Uiso,0,0,0,0,0,0]
    1260             S = file.readline()
    1261             if 'ANISOU' in S[:6]:
    1262                 Uij = S[30:72].split()
    1263                 Uij = [float(Uij[0])/10000.,float(Uij[1])/10000.,float(Uij[2])/10000.,
    1264                     float(Uij[3])/10000.,float(Uij[4])/10000.,float(Uij[5])/10000.]
    1265                 Atom = Atom[:14]+Uij
    1266                 Atom[12] = 'A'
    1267                 S = file.readline()
    1268             Atom.append(ran.randint(0,sys.maxint))
    1269             Atoms.append(Atom)
    1270         else:           
    1271             S = file.readline()
    1272     file.close()
    1273     if Title:
    1274         PhaseName = Title
    1275     elif Compnd:
    1276         PhaseName = Compnd
    1277     else:
    1278         PhaseName = 'None'
    1279     Phase = SetNewPhase(Name=PhaseName,SGData=SGData,cell=cell+[Volume,])
    1280     Phase['General']['Type'] = 'macromolecular'
    1281     Phase['General']['AtomPtrs'] = [6,4,10,12]
    1282     Phase['Atoms'] = Atoms
    1283     return Phase
    1284 
    12851065class MultipleChoicesDialog(wx.Dialog):
    12861066    '''A dialog that offers a series of choices, each with a
     
    14751255class ImportBaseclass(object):
    14761256    '''Defines a base class for the reading of input files (diffraction
    1477     data, coordinates,...
     1257    data, coordinates,...). See :ref:`Writing a Import Routine<Import_routines>`
     1258    for an explanation on how to use a subclass of this class.
    14781259    '''
     1260    class ImportException(Exception):
     1261        '''Defines an Exception that is used when an import routine hits an expected error,
     1262        usually in .Reader.
     1263
     1264        Good practice is that the Reader should define a value in self.errors that
     1265        tells the user some information about what is wrong with their file.         
     1266        '''
     1267        pass
     1268
    14791269    def __init__(self,
    14801270                 formatName,
     
    14961286        # the extension matches one in the extensionlist
    14971287        self.strictExtension = strictExtension
     1288        self.errors = ''
    14981289        self.warnings = ''
    14991290        # used for readers that will use multiple passes to read
     
    15721363    def ShowBusy(self):
    15731364        wx.BeginBusyCursor()
     1365        wx.Yield() # make it happen now!
    15741366
    15751367    def DoneBusy(self):
    15761368        wx.EndBusyCursor()
     1369        wx.Yield() # make it happen now!
    15771370       
    15781371#    def Reader(self, filename, filepointer, ParentFrame=None, **unused):
    1579 #        '''This method must be supplied in the child class
    1580 #        it will read the file
     1372#        '''This method must be supplied in the child class to read the file.
     1373#        if the read fails either return False or raise an Exception
     1374#        preferably of type ImportException.
    15811375#        '''
     1376#        #start reading
     1377#        raise ImportException("Error occurred while...")
     1378#        self.errors += "Hint for user on why the error occur
     1379#        return False # if an error occurs
    15821380#        return True # if read OK
    1583 #        return False # if an error occurs
    15841381
    15851382    def ExtensionValidator(self, filename):
     
    16081405        return True
    16091406
     1407    def CIFValidator(self, filepointer):
     1408        '''A :meth:`ContentsValidator` for use to validate CIF files.
     1409        '''
     1410        for i,l in enumerate(filepointer):
     1411            if i >= 1000: return True
     1412            '''Encountered only blank lines or comments in first 1000
     1413            lines. This is unlikely, but assume it is CIF anyway, since we are
     1414            even less likely to find a file with nothing but hashes and
     1415            blank lines'''
     1416            line = l.strip()
     1417            if len(line) == 0: # ignore blank lines
     1418                continue
     1419            elif line.startswith('#'): # ignore comments
     1420                continue
     1421            elif line.startswith('data_'): # on the right track, accept this file
     1422                return True
     1423            else: # found something invalid
     1424                self.errors = 'line '+str(i+1)+' contains unexpected data:\n'
     1425                self.errors += '  '+str(l)
     1426                self.errors += '  Note: a CIF should only have blank lines or comments before'
     1427                self.errors += '        a data_ statement begins a block.'
     1428                return False
     1429
    16101430class ImportPhase(ImportBaseclass):
    16111431    '''Defines a base class for the reading of files with coordinates
    16121432
    16131433    Objects constructed that subclass this (in import/G2phase_*.py) will be used
    1614     in :meth:`GSASII.GSASII.OnImportPhase`
     1434    in :meth:`GSASII.GSASII.OnImportPhase`.
     1435    See :ref:`Writing a Import Routine<Import_Routines>`
     1436    for an explanation on how to use this class.
     1437
    16151438    '''
    16161439    def __init__(self,formatName,longFormatName=None,extensionlist=[],
     
    16321455class ImportStructFactor(ImportBaseclass):
    16331456    '''Defines a base class for the reading of files with tables
    1634     of structure factors
    1635 
    1636     Note that the default controls are stored in self.Controls and the
    1637     default instrument parameters are stored in self.Parameters.
    1638     These can be changed, but any changes will be the defaults for all
    1639     subsequent uses of the :class:`ImportStructFactor` derived classes
    1640     until :meth:`InitControls` and :meth:`InitParameters` are
    1641     called. Probably better to use :meth:`UpdateControls` and
    1642     :meth:`UpdateControls` (adding new args if needed) to change
    1643     values.
     1457    of structure factors.
     1458
     1459    Structure factors are read with a call to :meth:`GSASII.GSASII.OnImportSfact`
     1460    which in turn calls :meth:`GSASII.GSASII.OnImportGeneric`, which calls
     1461    methods :meth:`ExtensionValidator`, :meth:`ContentsValidator` and
     1462    :meth:`Reader`.
     1463
     1464    See :ref:`Writing a Import Routine<Import_Routines>`
     1465    for an explanation on how to use import classes in general. The specifics
     1466    for reading a structure factor histogram require that
     1467    the ``Reader()`` routine in the import
     1468    class need to do only a few things: It
     1469    should load :attr:`RefDict` item ``'RefList'`` with the reflection list,
     1470    and set :attr:`Parameters` with the instrument parameters
     1471    (initialized with :meth:`InitParameters` and set with :meth:`UpdateParameters`).
     1472    Also, set :attr:`Controls`,
     1473    which specifies how the histogram is plotted
     1474    (initialized with :meth:`InitControls` and set with :meth:`UpdateControls`).
    16441475    '''
    16451476    def __init__(self,formatName,longFormatName=None,extensionlist=[],
     
    16491480
    16501481        # define contents of Structure Factor entry
     1482        self.Parameters = []
     1483        'self.Parameters is a list with two dicts for data parameter settings'
    16511484        self.InitParameters()
    1652         self.InitControls()
     1485        self.Controls = {}
     1486        'self.Controls is a dict with plotting controls'
     1487        self.InitControls() # initialize the above
    16531488        self.RefDict = {'RefList':[],'FF':[]}
     1489        '''self.RefDict is a dict containing the reflection information, as read from the file.
     1490        Item 'RefList' contains the reflection information. See the
     1491        :ref:`Single Crystal Reflection Data Structure<XtalRefl_table>`
     1492        for the contents of each row. Dict element 'FF'
     1493        contains the form factor values for each element type; if this entry
     1494        is left as initialized (an empty list) it will be initialized as needed later.
     1495        '''
    16541496       
    16551497    def InitControls(self):
     
    16741516                            'Lam':[Lambda,Lambda]
    16751517                            }, {}]
     1518        'Parameters is a list with two dicts for data parameter settings'
    16761519
    16771520    def UpdateParameters(self,Type=None,Wave=None):
     
    17151558######################################################################
    17161559class ImportPowderData(ImportBaseclass):
    1717     '''Defines a base class for the reading of files with powder data
     1560    '''Defines a base class for the reading of files with powder data.
     1561    See :ref:`Writing a Import Routine<Import_Routines>`
     1562    for an explanation on how to use this class.
    17181563    '''
    17191564    # define some default instrument parameter files
Note: See TracChangeset for help on using the changeset viewer.