Changeset 2817 for trunk/GSASIIIO.py
- Timestamp:
- May 2, 2017 10:03:41 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/GSASIIIO.py ¶
r2777 r2817 223 223 mainsizer = wx.BoxSizer(wx.VERTICAL) 224 224 h,w = Image.shape[:2] 225 mainsizer.Add(wx.StaticText(dlg,wx.ID_ANY, 226 'File '+str(filename)+'\nImage size: '+str(h)+' x '+str(w)), 227 0,wx.ALIGN_LEFT|wx.ALL, 2) 225 mainsizer.Add(wx.StaticText(dlg,wx.ID_ANY,'File '+str(filename)+'\nImage size: '+str(h)+' x '+str(w)), 226 0,wx.ALIGN_LEFT|wx.ALL, 2) 228 227 229 228 vsizer = wx.BoxSizer(wx.HORIZONTAL) 230 229 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u'Wavelength (\xC5) '), 231 230 0,wx.ALIGN_LEFT|wx.ALL, 2) 232 231 wdgt = G2G.ValidatedTxtCtrl(dlg,Data,'wavelength') 233 232 vsizer.Add(wdgt) … … 236 235 vsizer = wx.BoxSizer(wx.HORIZONTAL) 237 236 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u'Pixel size (\xb5m). Width '), 238 237 0,wx.ALIGN_LEFT|wx.ALL, 2) 239 238 wdgt = G2G.ValidatedTxtCtrl(dlg,Data['pixelSize'],0, 240 239 size=(50,-1)) 241 240 vsizer.Add(wdgt) 242 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u' Height '), 243 wx.ALIGN_LEFT|wx.ALL, 2) 244 wdgt = G2G.ValidatedTxtCtrl(dlg,Data['pixelSize'],1, 245 size=(50,-1)) 241 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u' Height '),wx.ALIGN_LEFT|wx.ALL, 2) 242 wdgt = G2G.ValidatedTxtCtrl(dlg,Data['pixelSize'],1,size=(50,-1)) 246 243 vsizer.Add(wdgt) 247 244 mainsizer.Add(vsizer,0,wx.ALIGN_LEFT|wx.ALL, 2) … … 249 246 vsizer = wx.BoxSizer(wx.HORIZONTAL) 250 247 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u'Sample to detector (mm) '), 251 248 0,wx.ALIGN_LEFT|wx.ALL, 2) 252 249 wdgt = G2G.ValidatedTxtCtrl(dlg,Data,'distance') 253 250 vsizer.Add(wdgt) … … 256 253 vsizer = wx.BoxSizer(wx.HORIZONTAL) 257 254 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u'Beam center (pixels). X = '), 258 0,wx.ALIGN_LEFT|wx.ALL, 2) 259 wdgt = G2G.ValidatedTxtCtrl(dlg,Data['center'],0, 260 size=(75,-1)) 255 0,wx.ALIGN_LEFT|wx.ALL, 2) 256 wdgt = G2G.ValidatedTxtCtrl(dlg,Data['center'],0,size=(75,-1)) 261 257 vsizer.Add(wdgt) 262 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u' Y = '), 263 wx.ALIGN_LEFT|wx.ALL, 2) 264 wdgt = G2G.ValidatedTxtCtrl(dlg,Data['center'],1, 265 size=(75,-1)) 258 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u' Y = '),wx.ALIGN_LEFT|wx.ALL, 2) 259 wdgt = G2G.ValidatedTxtCtrl(dlg,Data['center'],1,size=(75,-1)) 266 260 vsizer.Add(wdgt) 267 261 mainsizer.Add(vsizer,0,wx.ALIGN_LEFT|wx.ALL, 2) … … 269 263 vsizer = wx.BoxSizer(wx.HORIZONTAL) 270 264 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u'Comments '), 271 265 0,wx.ALIGN_LEFT|wx.ALL, 2) 272 266 wdgt = G2G.ValidatedTxtCtrl(dlg,Comments,0,size=(250,-1)) 273 267 vsizer.Add(wdgt) … … 549 543 return 550 544 551 # should get moved to importer when ready to test552 def GetEdfData(filename,imageOnly=False):553 'Read European detector data edf file'554 if not imageOnly:555 print 'Read European detector data edf file: ',filename556 File = open(filename,'rb')557 fileSize = os.stat(filename).st_size558 head = File.read(3072)559 lines = head.split('\n')560 sizexy = [0,0]561 pixSize = [154,154] #Pixium4700?562 cent = [0,0]563 wave = 1.54187 #default <CuKa>564 dist = 1000.565 head = ['European detector data',]566 for line in lines:567 line = line.replace(';',' ').strip()568 fields = line.split()569 if 'Dim_1' in line:570 sizexy[0] = int(fields[2])571 elif 'Dim_2' in line:572 sizexy[1] = int(fields[2])573 elif 'DataType' in line:574 dType = fields[2]575 elif 'wavelength' in line:576 wave = float(fields[2])577 elif 'Size' in line:578 imSize = int(fields[2])579 # elif 'DataType' in lines:580 # dType = fields[2]581 elif 'pixel_size_x' in line:582 pixSize[0] = float(fields[2])583 elif 'pixel_size_y' in line:584 pixSize[1] = float(fields[2])585 elif 'beam_center_x' in line:586 cent[0] = float(fields[2])587 elif 'beam_center_y' in line:588 cent[1] = float(fields[2])589 elif 'refined_distance' in line:590 dist = float(fields[2])591 if line:592 head.append(line)593 else: #blank line at end of header594 break595 File.seek(fileSize-imSize)596 if dType == 'UnsignedShort':597 image = np.array(np.frombuffer(File.read(imSize),dtype=np.int16),dtype=np.int32)598 else:599 image = np.array(np.frombuffer(File.read(imSize),dtype=np.int32),dtype=np.int32)600 image = np.reshape(image,(sizexy[1],sizexy[0]))601 data = {'pixelSize':pixSize,'wavelength':wave,'distance':dist,'center':cent,'size':sizexy}602 Npix = sizexy[0]*sizexy[1]603 File.close()604 if imageOnly:605 return image606 else:607 return head,data,Npix,image608 609 # should get moved to importer when ready to test610 def GetRigaku(filename,imageOnly=False):611 'Read Rigaku R-Axis IV image file'612 import array as ar613 if not imageOnly:614 print 'Read Rigaku R-Axis IV file: ',filename615 File = open(filename,'rb')616 fileSize = os.stat(filename).st_size617 Npix = (fileSize-6000)/2618 File.read(6000)619 head = ['Rigaku R-Axis IV detector data',]620 image = np.array(ar.array('H',File.read(fileSize-6000)),dtype=np.int32)621 print fileSize,image.shape622 print head623 if Npix == 9000000:624 sizexy = [3000,3000]625 pixSize = [100.,100.]626 elif Npix == 2250000:627 sizexy = [1500,1500]628 pixSize = [200.,200.]629 else:630 sizexy = [6000,6000]631 pixSize = [50.,50.]632 image = np.reshape(image,(sizexy[1],sizexy[0]))633 data = {'pixelSize':pixSize,'wavelength':1.5428,'distance':250.0,'center':[150.,150.],'size':sizexy}634 File.close()635 if imageOnly:636 return image637 else:638 return head,data,Npix,image639 640 # should get moved to importer when ready to test641 def GetImgData(filename,imageOnly=False):642 'Read an ADSC image file'643 import array as ar644 if not imageOnly:645 print 'Read ADSC img file: ',filename646 File = open(filename,'rb')647 head = File.read(511)648 lines = head.split('\n')649 head = []650 center = [0,0]651 for line in lines[1:-2]:652 line = line.strip()[:-1]653 if line:654 if 'SIZE1' in line:655 size = int(line.split('=')[1])656 Npix = size*size657 elif 'WAVELENGTH' in line:658 wave = float(line.split('=')[1])659 elif 'BIN' in line:660 if line.split('=')[1] == '2x2':661 pixel=(102,102)662 else:663 pixel = (51,51)664 elif 'DISTANCE' in line:665 distance = float(line.split('=')[1])666 elif 'CENTER_X' in line:667 center[0] = float(line.split('=')[1])668 elif 'CENTER_Y' in line:669 center[1] = float(line.split('=')[1])670 head.append(line)671 data = {'pixelSize':pixel,'wavelength':wave,'distance':distance,'center':center,'size':[size,size]}672 image = []673 pos = 512674 File.seek(pos)675 image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)676 image = np.reshape(image,(size,size))677 # image = np.zeros(shape=(size,size),dtype=np.int32)678 # while row < size:679 # File.seek(pos)680 # line = ar.array('H',File.read(2*size))681 # image[row] = np.asarray(line)682 # row += 1683 # pos += 2*size684 File.close()685 if imageOnly:686 return image687 else:688 return lines[1:-2],data,Npix,image689 690 # should get moved to importer when ready to test691 def GetMAR345Data(filename,imageOnly=False):692 'Read a MAR-345 image plate image'693 try:694 import pack_f as pf695 except:696 msg = wx.MessageDialog(None, message="Unable to load the GSAS MAR image decompression, pack_f",697 caption="Import Error",698 style=wx.ICON_ERROR | wx.OK | wx.STAY_ON_TOP)699 msg.ShowModal()700 return None,None,None,None701 702 if not imageOnly:703 print 'Read Mar345 file: ',filename704 File = open(filename,'rb')705 head = File.read(4095)706 lines = head[128:].split('\n')707 head = []708 for line in lines:709 line = line.strip()710 if 'PIXEL' in line:711 values = line.split()712 pixel = (int(values[2]),int(values[4])) #in microns713 elif 'WAVELENGTH' in line:714 wave = float(line.split()[1])715 elif 'DISTANCE' in line:716 distance = float(line.split()[1]) #in mm717 if not distance:718 distance = 500.719 elif 'CENTER' in line:720 values = line.split()721 center = [float(values[2])/10.,float(values[4])/10.] #make in mm from pixels722 if line:723 head.append(line)724 data = {'pixelSize':pixel,'wavelength':wave,'distance':distance,'center':center}725 for line in head:726 if 'FORMAT' in line[0:6]:727 items = line.split()728 sizex = int(items[1])729 Npix = int(items[3])730 sizey = int(Npix/sizex)731 pos = 4096732 data['size'] = [sizex,sizey]733 File.seek(pos)734 line = File.read(8)735 while 'CCP4' not in line: #get past overflow list for now736 line = File.read(8)737 pos += 8738 pos += 37739 File.seek(pos)740 raw = File.read()741 File.close()742 image = np.zeros(shape=(sizex,sizey),dtype=np.int32)743 744 image = np.flipud(pf.pack_f(len(raw),raw,sizex,sizey,image).T) #transpose to get it right way around & flip745 if imageOnly:746 return image747 else:748 return head,data,Npix,image749 750 545 def ProjFileOpen(G2frame,showProvenance=True): 751 546 'Read a GSAS-II project file and load into the G2 data tree' … … 913 708 if nOcc: 914 709 Aname += '(%d)'%(nOcc) 915 Sample = G2 pdG.SetDefaultSample() #set as Debye-Scherrer710 Sample = G2obj.SetDefaultSample() #set as Debye-Scherrer 916 711 Sample['Gonio. radius'] = data['distance'] 917 712 Sample['Omega'] = data['GonioAngles'][0] … … 1116 911 grfile.close() 1117 912 print ' G(R) saved to: ',grfilename 1118 1119 1120 1121 913 1122 914 def PeakListSave(G2frame,file,peaks): … … 1155 947 print 'index peak list saved' 1156 948 1157 def SetNewPhase(Name='New Phase',SGData=None,cell=None,Super=None):1158 '''Create a new phase dict with default values for various parameters1159 1160 :param str Name: Name for new Phase1161 1162 :param dict SGData: space group data from :func:`GSASIIspc:SpcGroup`;1163 defaults to data for P 11164 1165 :param list cell: unit cell parameter list; defaults to1166 [1.0,1.0,1.0,90.,90,90.,1.]1167 1168 '''1169 if SGData is None: SGData = G2spc.SpcGroup('P 1')[1]1170 if cell is None: cell=[1.0,1.0,1.0,90.,90,90.,1.]1171 phaseData = {1172 'ranId':ran.randint(0,sys.maxint),1173 'General':{1174 'Name':Name,1175 'Type':'nuclear',1176 'Modulated':False,1177 'AtomPtrs':[3,1,7,9],1178 'SGData':SGData,1179 'Cell':[False,]+cell,1180 'Pawley dmin':1.0,1181 'Data plot type':'None',1182 'SH Texture':{1183 'Order':0,1184 'Model':'cylindrical',1185 'Sample omega':[False,0.0],1186 'Sample chi':[False,0.0],1187 'Sample phi':[False,0.0],1188 'SH Coeff':[False,{}],1189 'SHShow':False,1190 'PFhkl':[0,0,1],1191 'PFxyz':[0,0,1],1192 'PlotType':'Pole figure',1193 'Penalty':[['',],0.1,False,1.0]}},1194 'Atoms':[],1195 'Drawing':{},1196 'Histograms':{},1197 'Pawley ref':[],1198 'RBModels':{},1199 }1200 if Super and Super.get('Use',False):1201 phaseData['General'].update({'Modulated':True,'Super':True,'SuperSg':Super['ssSymb']})1202 phaseData['General']['SSGData'] = G2spc.SSpcGroup(SGData,Super['ssSymb'])1203 phaseData['General']['SuperVec'] = [Super['ModVec'],False,Super['maxH']]1204 1205 return phaseData1206 1207 949 class MultipleChoicesDialog(wx.Dialog): 1208 950 '''A dialog that offers a series of choices, each with a … … 1395 1137 # not used directly, only by subclassing 1396 1138 ###################################################################### 1397 try: 1398 E,SGData = G2spc.SpcGroup('P 1') # data structure for default space group 1399 except: # errors on doc build 1400 SGData = None 1401 P1SGData = SGData 1402 ###################################################################### 1403 class ImportBaseclass(object): 1404 '''Defines a base class for the reading of input files (diffraction 1405 data, coordinates,...). See :ref:`Writing a Import Routine<Import_routines>` 1406 for an explanation on how to use a subclass of this class. 1139 def BlockSelector(ChoiceList, ParentFrame=None,title='Select a block', 1140 size=None, header='Block Selector',useCancel=True): 1141 ''' Provide a wx dialog to select a block if the file contains more 1142 than one set of data and one must be selected 1407 1143 ''' 1408 class ImportException(Exception): 1409 '''Defines an Exception that is used when an import routine hits an expected error, 1410 usually in .Reader. 1411 1412 Good practice is that the Reader should define a value in self.errors that 1413 tells the user some information about what is wrong with their file. 1414 ''' 1415 pass 1144 if useCancel: 1145 dlg = wx.SingleChoiceDialog( 1146 ParentFrame,title, header,ChoiceList) 1147 else: 1148 dlg = wx.SingleChoiceDialog( 1149 ParentFrame,title, header,ChoiceList, 1150 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.OK|wx.CENTRE) 1151 if size: dlg.SetSize(size) 1152 dlg.CenterOnParent() 1153 if dlg.ShowModal() == wx.ID_OK: 1154 sel = dlg.GetSelection() 1155 return sel 1156 else: 1157 return None 1158 dlg.Destroy() 1159 1160 def MultipleBlockSelector(ChoiceList, ParentFrame=None, 1161 title='Select a block',size=None, header='Block Selector'): 1162 '''Provide a wx dialog to select a block of data if the 1163 file contains more than one set of data and one must be 1164 selected. 1165 1166 :returns: a list of the selected blocks 1167 ''' 1168 dlg = wx.MultiChoiceDialog(ParentFrame,title, header,ChoiceList+['Select all'], 1169 wx.CHOICEDLG_STYLE) 1170 dlg.CenterOnScreen() 1171 if size: dlg.SetSize(size) 1172 if dlg.ShowModal() == wx.ID_OK: 1173 sel = dlg.GetSelections() 1174 else: 1175 return [] 1176 dlg.Destroy() 1177 selected = [] 1178 if len(ChoiceList) in sel: 1179 return range(len(ChoiceList)) 1180 else: 1181 return sel 1182 return selected 1183 1184 def MultipleChoicesSelector(choicelist, headinglist, ParentFrame=None, **kwargs): 1185 '''A modal dialog that offers a series of choices, each with a title and a wx.Choice 1186 widget. Typical input: 1416 1187 1417 UseReader = True # in __init__ set value of self.UseReader to False to skip use of current importer 1418 def __init__(self,formatName,longFormatName=None, 1419 extensionlist=[],strictExtension=False,): 1420 self.formatName = formatName # short string naming file type 1421 if longFormatName: # longer string naming file type 1422 self.longFormatName = longFormatName 1423 else: 1424 self.longFormatName = formatName 1425 # define extensions that are allowed for the file type 1426 # for windows, remove any extensions that are duplicate, as case is ignored 1427 if sys.platform == 'windows' and extensionlist: 1428 extensionlist = list(set([s.lower() for s in extensionlist])) 1429 self.extensionlist = extensionlist 1430 # If strictExtension is True, the file will not be read, unless 1431 # the extension matches one in the extensionlist 1432 self.strictExtension = strictExtension 1433 self.errors = '' 1434 self.warnings = '' 1435 # used for readers that will use multiple passes to read 1436 # more than one data block 1437 self.repeat = False 1438 self.selections = [] 1439 self.repeatcount = 0 1440 self.readfilename = '?' 1441 #print 'created',self.__class__ 1442 1443 def ReInitialize(self): 1444 'Reinitialize the Reader to initial settings' 1445 self.errors = '' 1446 self.warnings = '' 1447 self.repeat = False 1448 self.repeatcount = 0 1449 self.readfilename = '?' 1450 1451 def BlockSelector(self, ChoiceList, ParentFrame=None,title='Select a block', 1452 size=None, header='Block Selector',useCancel=True): 1453 ''' Provide a wx dialog to select a block if the file contains more 1454 than one set of data and one must be selected 1455 ''' 1456 if useCancel: 1457 dlg = wx.SingleChoiceDialog( 1458 ParentFrame,title, header,ChoiceList) 1459 else: 1460 dlg = wx.SingleChoiceDialog( 1461 ParentFrame,title, header,ChoiceList, 1462 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.OK|wx.CENTRE) 1463 if size: dlg.SetSize(size) 1464 dlg.CenterOnParent() 1465 if dlg.ShowModal() == wx.ID_OK: 1466 sel = dlg.GetSelection() 1467 return sel 1468 else: 1469 return None 1470 dlg.Destroy() 1471 1472 def MultipleBlockSelector(self, ChoiceList, ParentFrame=None, 1473 title='Select a block',size=None, header='Block Selector'): 1474 '''Provide a wx dialog to select a block of data if the 1475 file contains more than one set of data and one must be 1476 selected. 1477 1478 :returns: a list of the selected blocks 1479 ''' 1480 dlg = wx.MultiChoiceDialog(ParentFrame,title, header,ChoiceList+['Select all'], 1481 wx.CHOICEDLG_STYLE) 1482 dlg.CenterOnScreen() 1483 if size: dlg.SetSize(size) 1484 if dlg.ShowModal() == wx.ID_OK: 1485 sel = dlg.GetSelections() 1486 else: 1487 return [] 1488 dlg.Destroy() 1489 selected = [] 1490 if len(ChoiceList) in sel: 1491 return range(len(ChoiceList)) 1492 else: 1493 return sel 1494 return selected 1495 1496 def MultipleChoicesDialog(self, choicelist, headinglist, ParentFrame=None, **kwargs): 1497 '''A modal dialog that offers a series of choices, each with a title and a wx.Choice 1498 widget. Typical input: 1499 1500 * choicelist=[ ('a','b','c'), ('test1','test2'),('no choice',)] 1501 1502 * headinglist = [ 'select a, b or c', 'select 1 of 2', 'No option here'] 1503 1504 optional keyword parameters are: head (window title) and title 1505 returns a list of selected indicies for each choice (or None) 1506 ''' 1507 result = None 1508 dlg = MultipleChoicesDialog(choicelist,headinglist, 1509 parent=ParentFrame, **kwargs) 1510 dlg.CenterOnParent() 1511 if dlg.ShowModal() == wx.ID_OK: 1512 result = dlg.chosen 1513 dlg.Destroy() 1514 return result 1515 1516 def ShowBusy(self): 1517 wx.BeginBusyCursor() 1188 * choicelist=[ ('a','b','c'), ('test1','test2'),('no choice',)] 1189 1190 * headinglist = [ 'select a, b or c', 'select 1 of 2', 'No option here'] 1191 1192 optional keyword parameters are: head (window title) and title 1193 returns a list of selected indicies for each choice (or None) 1194 ''' 1195 result = None 1196 dlg = MultipleChoicesDialog(choicelist,headinglist, 1197 parent=ParentFrame, **kwargs) 1198 dlg.CenterOnParent() 1199 if dlg.ShowModal() == wx.ID_OK: 1200 result = dlg.chosen 1201 dlg.Destroy() 1202 return result 1203 1204 def PhaseSelector(self, ChoiceList, ParentFrame=None, 1205 title='Select a phase', size=None,header='Phase Selector'): 1206 ''' Provide a wx dialog to select a phase if the file contains more 1207 than one phase 1208 ''' 1209 return BlockSelector(ChoiceList,ParentFrame,title, 1210 size,header) 1211 1212 def ShowBusy(): 1213 wx.BeginBusyCursor() 1518 1214 # wx.Yield() # make it happen now! 1519 1215 1520 def DoneBusy(self): 1521 wx.EndBusyCursor() 1522 wx.Yield() # make it happen now! 1523 1524 # def Reader(self, filename, filepointer, ParentFrame=None, **unused): 1525 # '''This method must be supplied in the child class to read the file. 1526 # if the read fails either return False or raise an Exception 1527 # preferably of type ImportException. 1528 # ''' 1529 # #start reading 1530 # raise ImportException("Error occurred while...") 1531 # self.errors += "Hint for user on why the error occur 1532 # return False # if an error occurs 1533 # return True # if read OK 1534 1535 def ExtensionValidator(self, filename): 1536 '''This methods checks if the file has the correct extension 1537 Return False if this filename will not be supported by this reader 1538 Return True if the extension matches the list supplied by the reader 1539 Return None if the reader allows un-registered extensions 1540 ''' 1541 if filename: 1542 ext = os.path.splitext(filename)[1] 1543 if sys.platform == 'windows': ext = ext.lower() 1544 if ext in self.extensionlist: return True 1545 if self.strictExtension: return False 1546 return None 1547 1548 def ContentsValidator(self, filepointer): 1549 '''This routine will attempt to determine if the file can be read 1550 with the current format. 1551 This will typically be overridden with a method that 1552 takes a quick scan of [some of] 1553 the file contents to do a "sanity" check if the file 1554 appears to match the selected format. 1555 Expected to be called via self.Validator() 1556 ''' 1557 #filepointer.seek(0) # rewind the file pointer 1558 return True 1559 1560 def CIFValidator(self, filepointer): 1561 '''A :meth:`ContentsValidator` for use to validate CIF files. 1562 ''' 1563 for i,l in enumerate(filepointer): 1564 if i >= 1000: return True 1565 '''Encountered only blank lines or comments in first 1000 1566 lines. This is unlikely, but assume it is CIF anyway, since we are 1567 even less likely to find a file with nothing but hashes and 1568 blank lines''' 1569 line = l.strip() 1570 if len(line) == 0: # ignore blank lines 1571 continue 1572 elif line.startswith('#'): # ignore comments 1573 continue 1574 elif line.startswith('data_'): # on the right track, accept this file 1575 return True 1576 else: # found something invalid 1577 self.errors = 'line '+str(i+1)+' contains unexpected data:\n' 1578 if all([ord(c) < 128 and ord(c) != 0 for c in str(l)]): # show only if ASCII 1579 self.errors += ' '+str(l) 1580 else: 1581 self.errors += ' (binary)' 1582 self.errors += '\n Note: a CIF should only have blank lines or comments before' 1583 self.errors += '\n a data_ statement begins a block.' 1584 return False 1585 1586 ###################################################################### 1587 class ImportPhase(ImportBaseclass): 1588 '''Defines a base class for the reading of files with coordinates 1589 1590 Objects constructed that subclass this (in import/G2phase_*.py etc.) will be used 1591 in :meth:`GSASII.GSASII.OnImportPhase`. 1592 See :ref:`Writing a Import Routine<Import_Routines>` 1593 for an explanation on how to use this class. 1594 1595 ''' 1596 def __init__(self,formatName,longFormatName=None,extensionlist=[], 1597 strictExtension=False,): 1598 # call parent __init__ 1599 ImportBaseclass.__init__(self,formatName,longFormatName, 1600 extensionlist,strictExtension) 1601 self.Phase = None # a phase must be created with G2IO.SetNewPhase in the Reader 1602 self.Constraints = None 1603 1604 def PhaseSelector(self, ChoiceList, ParentFrame=None, 1605 title='Select a phase', size=None,header='Phase Selector'): 1606 ''' Provide a wx dialog to select a phase if the file contains more 1607 than one phase 1608 ''' 1609 return self.BlockSelector(ChoiceList,ParentFrame,title, 1610 size,header) 1611 1612 ###################################################################### 1613 class ImportStructFactor(ImportBaseclass): 1614 '''Defines a base class for the reading of files with tables 1615 of structure factors. 1616 1617 Structure factors are read with a call to :meth:`GSASII.GSASII.OnImportSfact` 1618 which in turn calls :meth:`GSASII.GSASII.OnImportGeneric`, which calls 1619 methods :meth:`ExtensionValidator`, :meth:`ContentsValidator` and 1620 :meth:`Reader`. 1621 1622 See :ref:`Writing a Import Routine<Import_Routines>` 1623 for an explanation on how to use import classes in general. The specifics 1624 for reading a structure factor histogram require that 1625 the ``Reader()`` routine in the import 1626 class need to do only a few things: It 1627 should load :attr:`RefDict` item ``'RefList'`` with the reflection list, 1628 and set :attr:`Parameters` with the instrument parameters 1629 (initialized with :meth:`InitParameters` and set with :meth:`UpdateParameters`). 1630 ''' 1631 def __init__(self,formatName,longFormatName=None,extensionlist=[], 1632 strictExtension=False,): 1633 ImportBaseclass.__init__(self,formatName,longFormatName, 1634 extensionlist,strictExtension) 1635 1636 # define contents of Structure Factor entry 1637 self.Parameters = [] 1638 'self.Parameters is a list with two dicts for data parameter settings' 1639 self.InitParameters() 1640 self.RefDict = {'RefList':[],'FF':{},'Super':0} 1641 self.Banks = [] #for multi bank data (usually TOF) 1642 '''self.RefDict is a dict containing the reflection information, as read from the file. 1643 Item 'RefList' contains the reflection information. See the 1644 :ref:`Single Crystal Reflection Data Structure<XtalRefl_table>` 1645 for the contents of each row. Dict element 'FF' 1646 contains the form factor values for each element type; if this entry 1647 is left as initialized (an empty list) it will be initialized as needed later. 1648 ''' 1649 def ReInitialize(self): 1650 'Reinitialize the Reader to initial settings' 1651 ImportBaseclass.ReInitialize(self) 1652 self.InitParameters() 1653 self.Banks = [] #for multi bank data (usually TOF) 1654 self.RefDict = {'RefList':[],'FF':{},'Super':0} 1655 1656 def InitParameters(self): 1657 'initialize the instrument parameters structure' 1658 Lambda = 0.70926 1659 HistType = 'SXC' 1660 self.Parameters = [{'Type':[HistType,HistType], # create the structure 1661 'Lam':[Lambda,Lambda] 1662 }, {}] 1663 'Parameters is a list with two dicts for data parameter settings' 1664 1665 def UpdateParameters(self,Type=None,Wave=None): 1666 'Revise the instrument parameters' 1667 if Type is not None: 1668 self.Parameters[0]['Type'] = [Type,Type] 1669 if Wave is not None: 1670 self.Parameters[0]['Lam'] = [Wave,Wave] 1671 1672 ###################################################################### 1673 class ImportPowderData(ImportBaseclass): 1674 '''Defines a base class for the reading of files with powder data. 1675 1676 Objects constructed that subclass this (in import/G2pwd_*.py etc.) will be used 1677 in :meth:`GSASII.GSASII.OnImportPowder`. 1678 See :ref:`Writing a Import Routine<Import_Routines>` 1679 for an explanation on how to use this class. 1680 ''' 1681 def __init__(self,formatName,longFormatName=None, 1682 extensionlist=[],strictExtension=False,): 1683 ImportBaseclass.__init__(self,formatName,longFormatName, 1684 extensionlist,strictExtension) 1685 self.clockWd = None # used in TOF 1686 self.ReInitialize() 1687 1688 def ReInitialize(self): 1689 'Reinitialize the Reader to initial settings' 1690 ImportBaseclass.ReInitialize(self) 1691 self.powderentry = ['',None,None] # (filename,Pos,Bank) 1692 self.powderdata = [] # Powder dataset 1693 '''A powder data set is a list with items [x,y,w,yc,yb,yd]: 1694 np.array(x), # x-axis values 1695 np.array(y), # powder pattern intensities 1696 np.array(w), # 1/sig(intensity)^2 values (weights) 1697 np.array(yc), # calc. intensities (zero) 1698 np.array(yb), # calc. background (zero) 1699 np.array(yd), # obs-calc profiles 1700 ''' 1701 self.comments = [] 1702 self.idstring = '' 1703 self.Sample = G2pdG.SetDefaultSample() # default sample parameters 1704 self.Controls = {} # items to be placed in top-level Controls 1705 self.GSAS = None # used in TOF 1706 self.repeat_instparm = True # Should a parm file be 1707 # used for multiple histograms? 1708 self.instparm = None # name hint from file of instparm to use 1709 self.instfile = '' # full path name to instrument parameter file 1710 self.instbank = '' # inst parm bank number 1711 self.instmsg = '' # a label that gets printed to show 1712 # where instrument parameters are from 1713 self.numbanks = 1 1714 self.instdict = {} # place items here that will be transferred to the instrument parameters 1715 self.pwdparms = {} # place parameters that are transferred directly to the tree 1716 # here (typically from an existing GPX file) 1717 ###################################################################### 1718 class ImportSmallAngleData(ImportBaseclass): 1719 '''Defines a base class for the reading of files with small angle data. 1720 See :ref:`Writing a Import Routine<Import_Routines>` 1721 for an explanation on how to use this class. 1722 ''' 1723 def __init__(self,formatName,longFormatName=None,extensionlist=[], 1724 strictExtension=False,): 1725 1726 ImportBaseclass.__init__(self,formatName,longFormatName,extensionlist, 1727 strictExtension) 1728 self.ReInitialize() 1729 1730 def ReInitialize(self): 1731 'Reinitialize the Reader to initial settings' 1732 ImportBaseclass.ReInitialize(self) 1733 self.smallangleentry = ['',None,None] # (filename,Pos,Bank) 1734 self.smallangledata = [] # SASD dataset 1735 '''A small angle data set is a list with items [x,y,w,yc,yd]: 1736 np.array(x), # x-axis values 1737 np.array(y), # powder pattern intensities 1738 np.array(w), # 1/sig(intensity)^2 values (weights) 1739 np.array(yc), # calc. intensities (zero) 1740 np.array(yd), # obs-calc profiles 1741 np.array(yb), # preset bkg 1742 ''' 1743 self.comments = [] 1744 self.idstring = '' 1745 self.Sample = G2pdG.SetDefaultSample() 1746 self.GSAS = None # used in TOF 1747 self.clockWd = None # used in TOF 1748 self.numbanks = 1 1749 self.instdict = {} # place items here that will be transferred to the instrument parameters 1750 1751 ###################################################################### 1752 class ImportReflectometryData(ImportBaseclass): 1753 '''Defines a base class for the reading of files with reflectometry data. 1754 See :ref:`Writing a Import Routine<Import_Routines>` 1755 for an explanation on how to use this class. 1756 ''' 1757 def __init__(self,formatName,longFormatName=None,extensionlist=[], 1758 strictExtension=False,): 1759 1760 ImportBaseclass.__init__(self,formatName,longFormatName,extensionlist, 1761 strictExtension) 1762 self.ReInitialize() 1763 1764 def ReInitialize(self): 1765 'Reinitialize the Reader to initial settings' 1766 ImportBaseclass.ReInitialize(self) 1767 self.reflectometryentry = ['',None,None] # (filename,Pos,Bank) 1768 self.reflectometrydata = [] # SASD dataset 1769 '''A small angle data set is a list with items [x,y,w,yc,yd]: 1770 np.array(x), # x-axis values 1771 np.array(y), # powder pattern intensities 1772 np.array(w), # 1/sig(intensity)^2 values (weights) 1773 np.array(yc), # calc. intensities (zero) 1774 np.array(yd), # obs-calc profiles 1775 np.array(yb), # preset bkg 1776 ''' 1777 self.comments = [] 1778 self.idstring = '' 1779 self.Sample = G2pdG.SetDefaultSample() 1780 self.GSAS = None # used in TOF 1781 self.clockWd = None # used in TOF 1782 self.numbanks = 1 1783 self.instdict = {} # place items here that will be transferred to the instrument parameters 1784 1785 ###################################################################### 1786 class ImportPDFData(ImportBaseclass): 1787 '''Defines a base class for the reading of files with PDF G(R) data. 1788 See :ref:`Writing a Import Routine<Import_Routines>` 1789 for an explanation on how to use this class. 1790 ''' 1791 def __init__(self,formatName,longFormatName=None,extensionlist=[], 1792 strictExtension=False,): 1793 1794 ImportBaseclass.__init__(self,formatName,longFormatName,extensionlist, 1795 strictExtension) 1796 self.ReInitialize() 1797 1798 def ReInitialize(self): 1799 'Reinitialize the Reader to initial settings' 1800 ImportBaseclass.ReInitialize(self) 1801 self.pdfentry = ['',None,None] # (filename,Pos,Bank) 1802 self.pdfdata = [] # PDF G(R) dataset 1803 '''A pdf g(r) data set is a list with items [x,y]: 1804 np.array(x), # r-axis values 1805 np.array(y), # pdf g(r) 1806 ''' 1807 self.comments = [] 1808 self.idstring = '' 1809 self.numbanks = 1 1810 1811 ###################################################################### 1812 class ImportImage(ImportBaseclass): 1813 '''Defines a base class for the reading of images 1814 1815 Images are read in only these places: 1816 1817 * Initial reading is typically done from a menu item 1818 with a call to :meth:`GSASII.GSASII.OnImportImage` 1819 which in turn calls :meth:`GSASII.GSASII.OnImportGeneric`. That calls 1820 methods :meth:`ExtensionValidator`, :meth:`ContentsValidator` and 1821 :meth:`Reader`. This returns a list of reader objects for each read image. 1822 1823 * Images are read alternatively in :func:`GSASIIIO.ReadImages`, which puts image info 1824 directly into the data tree. 1825 1826 * Images are reloaded with :func:`GSASIIIO.GetImageData`. 1827 1828 .. _Image_import_routines: 1829 1830 When reading an image, the ``Reader()`` routine in the ImportImage class 1831 should set: 1832 1833 * :attr:`Comments`: a list of strings (str), 1834 * :attr:`Npix`: the number of pixels in the image (int), 1835 * :attr:`Image`: the actual image as a numpy array (np.array) 1836 * :attr:`Data`: a dict defining image parameters (dict). Within this dict the following 1837 data items are needed: 1838 1839 * 'pixelSize': size of each pixel in microns (such as ``[200,200]``. 1840 * 'wavelength': wavelength in Angstoms. 1841 * 'distance': distance of detector from sample in cm. 1842 * 'center': uncalibrated center of beam on detector (such as ``[204.8,204.8]``. 1843 * 'size': size of image (such as ``[2048,2048]``). 1844 * 'ImageTag': image number or other keyword used to retrieve image from 1845 a multi-image data file (defaults to ``1`` if not specified). 1846 * 'sumfile': holds sum image file name if a sum was produced from a multi image file 1847 1848 optional data items: 1849 1850 * :attr:`repeat`: set to True if there are additional images to 1851 read in the file, False otherwise 1852 * :attr:`repeatcount`: set to the number of the image. 1853 1854 Note that the above is initialized with :meth:`InitParameters`. 1855 (Also see :ref:`Writing a Import Routine<Import_Routines>` 1856 for an explanation on how to use import classes in general.) 1857 ''' 1858 def __init__(self,formatName,longFormatName=None,extensionlist=[], 1859 strictExtension=False,): 1860 ImportBaseclass.__init__(self,formatName,longFormatName, 1861 extensionlist,strictExtension) 1862 self.InitParameters() 1863 1864 def ReInitialize(self): 1865 'Reinitialize the Reader to initial settings -- not used at present' 1866 ImportBaseclass.ReInitialize(self) 1867 self.InitParameters() 1868 1869 def InitParameters(self): 1870 'initialize the instrument parameters structure' 1871 self.Comments = ['No comments'] 1872 self.Data = {} 1873 self.Npix = 0 1874 self.Image = None 1875 self.repeat = False 1876 self.repeatcount = 1 1877 self.sumfile = '' 1878 1879 def LoadImage(self,ParentFrame,imagefile,imagetag=None): 1880 '''Optionally, call this after reading in an image to load it into the tree. 1881 This saves time by preventing a reread of the same information. 1882 ''' 1883 if ParentFrame: 1884 ParentFrame.ImageZ = self.Image # store the image for plotting 1885 ParentFrame.oldImagefile = imagefile # save the name of the last image file read 1886 ParentFrame.oldImageTag = imagetag # save the tag of the last image file read 1887 1216 def DoneBusy(): 1217 wx.EndBusyCursor() 1218 wx.Yield() # make it happen now! 1888 1219 ###################################################################### 1889 1220 def striphist(var,insChar=''): … … 2787 2118 return Layer 2788 2119 2789 def ReadCIF(URLorFile):2790 '''Open a CIF, which may be specified as a file name or as a URL using PyCifRW2791 (from James Hester).2792 The open routine gets confused with DOS names that begin with a letter and colon2793 "C:\dir\" so this routine will try to open the passed name as a file and if that2794 fails, try it as a URL2795 2796 :param str URLorFile: string containing a URL or a file name. Code will try first2797 to open it as a file and then as a URL.2798 2799 :returns: a PyCifRW CIF object.2800 '''2801 import CifFile as cif # PyCifRW from James Hester2802 2803 # alternate approach:2804 #import urllib2805 #ciffile = 'file:'+urllib.pathname2url(filename)2806 2807 try:2808 fp = open(URLorFile,'r')2809 cf = cif.ReadCif(fp)2810 fp.close()2811 return cf2812 except IOError:2813 return cif.ReadCif(URLorFile)2814 2815 2120 if __name__ == '__main__': 2816 2121 import GSASII
Note: See TracChangeset
for help on using the changeset viewer.