Changeset 3288
- Timestamp:
- Feb 16, 2018 3:22:26 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/GSASIIdataGUI.py
r3285 r3288 2677 2677 self.ifX20 = True #use M20 /= (1+X20) in powder indexing, etc. 2678 2678 self.HKL = [] 2679 self.Lines = [] 2679 self.Lines = [] # lines used for data limits & excluded regions 2680 self.MagLines = [] # lines used for plot magnification 2680 2681 self.itemPicked = None 2681 2682 self.Interpolate = 'nearest' … … 6475 6476 textureData = General['SH Texture'] 6476 6477 if textureData['Order']: 6477 SHtextureSig = {}6478 # SHtextureSig = {} 6478 6479 for name in ['omega','chi','phi']: 6479 6480 aname = pfx+'SH '+name … … 6493 6494 key = pfx+'PWLref:'+str(i) 6494 6495 refl[ik] = parmDict[key] 6495 if key in sigDict: 6496 refl[ik+1] = sigDict[key]6497 else:6498 refl[ik+1] = 06496 # if key in sigDict: #TODO: error here sigDict not defined. What was intended 6497 # refl[ik+1] = sigDict[key] 6498 # else: 6499 # refl[ik+1] = 0 6499 6500 continue 6500 6501 General['Mass'] = 0. … … 7242 7243 ''' 7243 7244 G2pdG.CopySelectedHistItems(G2frame) 7244 7245 7246 def OnAddMag(event): 7247 'Respond to the request to create a magnification region' 7248 if not data[0]['Magnification']: data[0]['Magnification'] = [[None,1.0]] 7249 data[0]['Magnification'] += [[(data[1][0][0]+data[1][0][-1])/2,2.]] 7250 wx.CallAfter(UpdatePWHKPlot,G2frame,kind,G2frame.PatternId) 7251 def OnDelMag(event): 7252 'Respond to the request to delete a magnification region' 7253 del data[0]['Magnification'][event.EventObject.row] 7254 if len(data[0]['Magnification']) == 1: data[0]['Magnification'] = [] 7255 wx.CallAfter(UpdatePWHKPlot,G2frame,kind,G2frame.PatternId) 7256 def OnEditMag(**args): 7257 'Update to show edits to mag factors in window and plot' 7258 wx.CallAfter(UpdatePWHKPlot,G2frame,kind,G2frame.PatternId) 7259 7260 # Start of UpdatePWHKPlot 7245 7261 data = G2frame.GPXtree.GetItemPyData(item) 7246 7262 #G2frame.SetLabel(G2frame.GetLabel().split('||')[0]+' || '+G2frame.GPXtree.GetItemText(item)) … … 7334 7350 u' Unweighted phase residuals RF\u00b2: %.3f%%, RF: %.3f%% on %d reflections '% \ 7335 7351 (data[0][pfx+'Rf^2'],data[0][pfx+'Rf'],data[0][value]))) 7336 7337 7352 7353 # Draw edit box for Magnification factors/positions 7354 if kind == 'PWDR': 7355 if 'Magnification' not in data[0]: 7356 data[0]['Magnification'] = [] 7357 mainSizer.Add((-1,10)) 7358 lenmag = len(data[0]['Magnification']) 7359 data[0]['Magnification'].sort(key=lambda x: x[0]) 7360 if lenmag > 1: 7361 panel = wx.StaticBox(G2frame.dataWindow, wx.ID_ANY, 'Magnification regions', 7362 style=wx.ALIGN_CENTER) 7363 mSizer = wx.StaticBoxSizer(panel,wx.VERTICAL) 7364 magSizer = wx.FlexGridSizer(lenmag+1,3,0,0) 7365 Name = G2frame.GPXtree.GetItemText(G2frame.PatternId) 7366 Inst = G2frame.GPXtree.GetItemPyData(GetGPXtreeItemId(G2frame, 7367 G2frame.PatternId,'Instrument Parameters')) 7368 if 'C' in Inst[0]['Type'][0]: 7369 magSizer.Add(wx.StaticText(panel,-1,'2Theta' 7370 ),1,wx.ALIGN_CENTER,1) 7371 else: 7372 magSizer.Add(wx.StaticText(panel,-1,'TOF' 7373 ),1,wx.ALIGN_CENTER,1) 7374 magSizer.Add(wx.StaticText(panel,-1,'Magnification\nfactor', 7375 style=wx.ALIGN_CENTRE_HORIZONTAL),1,wx.ALIGN_CENTER,1) 7376 magSizer.Add(wx.StaticText(panel,-1,'Delete\nbutton', 7377 style=wx.ALIGN_CENTRE_HORIZONTAL 7378 ),1,wx.ALIGN_CENTER,1) 7379 magSizer.Add(wx.StaticText(panel,-1,'(start)'),1,wx.ALIGN_CENTER,1) 7380 edit = G2G.ValidatedTxtCtrl(panel,data[0]['Magnification'][0],1, 7381 nDig=(7,2), 7382 min=0.01,max=1000., 7383 OnLeave=OnEditMag,size=(65,-1)) 7384 magSizer.Add(edit,1,wx.ALIGN_CENTER,5) 7385 magSizer.Add((1,1)) 7386 for i in range(1,lenmag): 7387 edit = G2G.ValidatedTxtCtrl(panel,data[0]['Magnification'][i],0, 7388 nDig=(10,3), 7389 min=data[1][0][0],max=data[1][0][-1], 7390 OnLeave=OnEditMag) 7391 magSizer.Add(edit) 7392 edit = G2G.ValidatedTxtCtrl(panel,data[0]['Magnification'][i],1, 7393 nDig=(7,2), 7394 min=0.01,max=1000., 7395 OnLeave=OnEditMag,size=(65,-1)) 7396 magSizer.Add(edit,1,wx.ALIGN_CENTER,5) 7397 delmag = wx.Button(panel,wx.ID_ANY,label='Del',size=(40,-1)) 7398 delmag.Bind(wx.EVT_BUTTON,OnDelMag) 7399 delmag.row = i 7400 magSizer.Add(delmag,1,wx.ALIGN_CENTER,5) 7401 mSizer.Add(magSizer) 7402 else: 7403 panel = G2frame.dataWindow 7404 mSizer = wx.BoxSizer(wx.VERTICAL) 7405 addmag = wx.Button(panel,wx.ID_ANY,label='Add a magnification region') 7406 addmag.Bind(wx.EVT_BUTTON,OnAddMag) 7407 mSizer.Add(addmag,1,wx.ALIGN_CENTER,1) 7408 mainSizer.Add(mSizer) 7409 7338 7410 G2frame.GPXtree.SetItemPyData(item,data) 7339 7411 G2frame.PatternId = item -
trunk/GSASIIplot.py
r3286 r3288 550 550 'Shrink X','Expand Y','Shrink Y'): 551 551 arrows[direc] = wx.NewId() 552 552 553 def __init__(self,plotCanvas): 553 554 '''Adds additional icons to toolbar''' 555 # try to remove a button from the bar 556 POS_CONFIG_SPLTS_BTN = 6 # position of button to remove 557 try: 558 self.toolitems = self.toolitems[:POS_CONFIG_SPLTS_BTN]+self.toolitems[POS_CONFIG_SPLTS_BTN+1:] 559 deleted = True 560 except: 561 deleted = False 554 562 Toolbar.__init__(self,plotCanvas) 555 563 G2path = os.path.split(os.path.abspath(__file__))[0] 564 self.updateActions = None # defines a call to be made as part of plot updates 556 565 self.plotCanvas = plotCanvas 557 POSITION_OF_CONFIGURE_SUBPLOTS_BTN = 6 # remove one button, nos. start at 1!558 self.DeleteToolByPos(POSITION_OF_CONFIGURE_SUBPLOTS_BTN) #doesn't work in miniconda566 # 2nd try to remove a button from the bar 567 if not deleted: self.DeleteToolByPos(POS_CONFIG_SPLTS_BTN) #doesn't work in some wxpython versions 559 568 self.parent = self.GetParent() 560 569 key = os.path.join(G2path,'key.ico') … … 586 595 button = self.AddSimpleTool(self.arrows[direc],_load_bitmap(icon),direc,'Zoom: '+direc) 587 596 wx.EVT_TOOL.Bind(self,self.arrows[direc],button.GetId(),self.OnArrow) 588 597 598 def _update_view(self): 599 '''Overrides the post-buttonbar update action to invoke a redraw; needed for plot magnification 600 ''' 601 if self.updateActions: 602 wx.CallAfter(*self.updateActions) 603 Toolbar._update_view(self) 604 589 605 def OnArrow(self,event): 590 606 'reposition limits to scan or zoom by button press' … … 633 649 self.parent.toolbar.draw() 634 650 # self.parent.toolbar.push_current() 651 if self.updateActions: 652 wx.CallAfter(*self.updateActions) 635 653 636 654 def OnHelp(self,event): … … 646 664 parent = self.GetParent() 647 665 if parent.Choice: 648 dlg = wx.SingleChoiceDialog(parent,'Select','Key press',list(parent.Choice)) 666 # remove the 1st entry in list if key press 667 if 'key press' in parent.Choice[0].lower(): 668 choices = list(parent.Choice[1:]) 669 else: 670 choices = list(parent.Choice) 671 dlg = wx.SingleChoiceDialog(parent,'Select a keyboard command', 672 'Key press list',choices) 649 673 if dlg.ShowModal() == wx.ID_OK: 650 674 sel = dlg.GetSelection() 651 event.key = parent.Choice[sel][0]675 event.key = choices[sel][0] 652 676 if event.key != ' ': 653 677 parent.keyPress(event) … … 655 679 dlg.Destroy() 656 680 G2G.G2MessageBox(self.TopLevelParent, 657 'Use this command from the keyboard',681 'Use this command only from the keyboard', 658 682 'Key not in menu') 659 683 return … … 1527 1551 G2frame.plotStyle['qPlot'] = False 1528 1552 G2frame.plotStyle['dPlot'] = False 1529 # elif event.key == 'a' and 'PWDR' in plottype and G2frame.SinglePlot and not ( 1530 # G2frame.logPlot or G2frame.plotStyle['sqrtPlot'] or G2frame.Contour): 1531 # xpos = event.xdata 1532 # if xpos is None: return #avoid out of frame mouse position 1533 # ypos = event.ydata 1534 # print('event',xpos) 1553 elif event.key == 'a' and 'PWDR' in plottype and G2frame.SinglePlot and not ( 1554 G2frame.logPlot or G2frame.plotStyle['sqrtPlot'] or G2frame.Contour): 1555 # add a magnification region 1556 try: 1557 xpos = event.xdata 1558 if xpos is None: return #avoid out of frame mouse position 1559 if 'Magnification' not in Pattern[0]: 1560 Pattern[0]['Magnification'] = [] 1561 try: 1562 if G2frame.plotStyle['qPlot']: 1563 xpos = G2lat.Dsp2pos(Parms,2.0*np.pi/xpos) 1564 elif G2frame.plotStyle['dPlot']: 1565 xpos = G2lat.Dsp2pos(Parms,xpos) 1566 except ValueError: 1567 return 1568 except AttributeError: # invoked when this is called from dialog rather than key press 1569 xpos = (Pattern[1][0][-1]+Pattern[1][0][0])/2 # set to middle of pattern 1570 if not Pattern[0]['Magnification']: 1571 Pattern[0]['Magnification'] = [[None,1.]] 1572 Pattern[0]['Magnification'] += [[xpos,2.]] 1573 wx.CallAfter(G2gd.UpdatePWHKPlot,G2frame,plottype,G2frame.PatternId) 1574 return 1535 1575 elif event.key == 'q': 1536 1576 newPlot = True … … 1806 1846 ypos = pick.get_ydata() 1807 1847 ind = event.ind 1808 xy = list(zip(np.take(xpos,ind),np.take(ypos,ind)) )[0]1848 xy = list(zip(np.take(xpos,ind),np.take(ypos,ind))[0]) 1809 1849 # convert from plot units 1810 1850 if G2frame.plotStyle['qPlot']: #qplot - convert back to 2-theta … … 1890 1930 Page.diffOffset = Pattern[0]['delOffset'] 1891 1931 G2frame.cid = Page.canvas.mpl_connect('motion_notify_event', OnDragDiffCurve) 1932 elif G2frame.itemPicked in G2frame.MagLines: # drag of magnification marker 1933 pick.set_dashes((1,4)) # set line as dotted sparse 1934 Page.canvas.draw() # refresh without dotted line & save bitmap 1935 savedplot = Page.canvas.copy_from_bbox(Page.figure.gca().bbox) 1936 G2frame.cid = Page.canvas.mpl_connect('motion_notify_event', OnDragLine) 1937 pick.set_dashes((1,1)) # back to dotted 1892 1938 else: # pick of plot tick mark (is anything else possible?) 1893 1939 pick = str(G2frame.itemPicked).split('(',1)[1][:-1] … … 1957 2003 if G2frame.GPXtree.GetItemText(PickId) == 'Background' and event.xdata: 1958 2004 if Page.toolbar._active: # prevent ops. if a toolbar zoom button pressed 2005 # after any mouse release event (could be a zoom), redraw magnification lines 2006 if magLineList: wx.CallAfter(PlotPatterns,G2frame,plotType=plottype) 1959 2007 return 1960 2008 # Background page, deal with fixed background points … … 1969 2017 # unit conversions 1970 2018 xy = [event.xdata,event.ydata] 1971 if G2frame.plotStyle['qPlot']: #qplot - convert back to 2-theta 1972 xy[0] = G2lat.Dsp2pos(Parms,2*np.pi/xy[0]) 1973 elif G2frame.plotStyle['dPlot']: #dplot - convert back to 2-theta 1974 xy[0] = G2lat.Dsp2pos(Parms,xy[0]) 2019 try: 2020 if G2frame.plotStyle['qPlot']: #qplot - convert back to 2-theta 2021 xy[0] = G2lat.Dsp2pos(Parms,2*np.pi/xy[0]) 2022 elif G2frame.plotStyle['dPlot']: #dplot - convert back to 2-theta 2023 xy[0] = G2lat.Dsp2pos(Parms,xy[0]) 2024 except: 2025 return 1975 2026 if G2frame.plotStyle['sqrtPlot']: 1976 2027 xy[1] = xy[1]**2 … … 1991 2042 return 1992 2043 1993 if G2frame.itemPicked is None: return 2044 if G2frame.itemPicked is None: 2045 # after any mouse release event (could be a zoom), redraw magnification lines 2046 if magLineList: wx.CallAfter(PlotPatterns,G2frame,plotType=plottype) 2047 return 1994 2048 if DifLine[0] is G2frame.itemPicked: # respond to dragging of the difference curve 1995 2049 data = G2frame.GPXtree.GetItemPyData(PickId) … … 1998 2052 G2frame.itemPicked = None 1999 2053 wx.CallAfter(PlotPatterns,G2frame,plotType=plottype) 2054 return 2055 elif G2frame.itemPicked in G2frame.MagLines: # drag of magnification marker 2056 xpos = event.xdata 2057 try: 2058 if G2frame.plotStyle['qPlot']: #qplot - convert back to 2-theta 2059 xpos = G2lat.Dsp2pos(Parms,2*np.pi/xpos) 2060 elif G2frame.plotStyle['dPlot']: #dplot - convert back to 2-theta 2061 xpos = G2lat.Dsp2pos(Parms,xpos) 2062 except: 2063 return 2064 magIndex = G2frame.MagLines.index(G2frame.itemPicked) 2065 data = G2frame.GPXtree.GetItemPyData(PickId) 2066 data[0]['Magnification'][magIndex][0] = xpos 2067 wx.CallAfter(G2gd.UpdatePWHKPlot,G2frame,plottype,G2frame.PatternId) 2000 2068 return 2001 2069 Parms,Parms2 = G2frame.GPXtree.GetItemPyData(G2gd.GetGPXtreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters')) … … 2155 2223 'd: offset down','l: offset left','r: offset right','u: offset up','o: reset offset', 2156 2224 'q: toggle S(q) plot','m: toggle multidata plot','w: toggle (Io-Ic)/sig plot','+: no selection') 2157 # if 'PWDR' in plottype and G2frame.SinglePlot and not ( 2158 # G2frame.logPlot or G2frame.plotStyle['sqrtPlot'] or G2frame.Contour): 2159 # Page.Choice = Page.Choice + (' a: set multiplier -- only from keyboard',) 2225 if 'PWDR' in plottype and G2frame.SinglePlot and not ( 2226 G2frame.logPlot or G2frame.plotStyle['sqrtPlot'] or G2frame.Contour): 2227 Page.Choice = Page.Choice + ('a: add magnification region',) 2228 magLineList = [] # null value indicates no magnification 2229 Page.toolbar.updateActions = None # no update actions 2160 2230 G2frame.cid = None 2161 2231 Page.keyPress = OnPlotKeyPress … … 2218 2288 if G2frame.logPlot: 2219 2289 Title = 'log('+Title+')' 2220 Plot.set_title(Title)2290 #Plot.set_title(Title) # show title only w/o magnification 2221 2291 if G2frame.plotStyle['qPlot'] or plottype in ['SASD','REFD'] and not G2frame.Contour: 2222 2292 Plot.set_xlabel(r'$Q, \AA^{-1}$',fontsize=16) … … 2270 2340 LimitId = 0 2271 2341 if Pattern[1] is None: continue # skip over uncomputed simulations 2272 # xye = ma.array(ma.getdata(Pattern[1]))2273 2342 xye = np.array(ma.getdata(Pattern[1])) 2274 2343 bxye = G2pdG.GetFileBackground(G2frame,xye,Pattern) … … 2288 2357 if not lenX: 2289 2358 lenX = len(X) 2359 # show plot magnification factors 2360 magMarkers = [] 2361 multArray = np.ones_like(Pattern[1][0]) 2362 if 'PWDR' in plottype and G2frame.SinglePlot and not ( 2363 G2frame.logPlot or G2frame.plotStyle['sqrtPlot'] or G2frame.Contour): 2364 magLineList = data[0].get('Magnification',[]) 2365 if ('C' in ParmList[0]['Type'][0] and G2frame.plotStyle['dPlot'] 2366 ) or ('T' in ParmList[0]['Type'][0] and G2frame.plotStyle['qPlot'] 2367 ): # reversed regions relative to data order 2368 tcorner = 1 2369 tpos = 1.0 2370 halign = 'right' 2371 else: 2372 tcorner = 0 2373 tpos = 1.0 2374 halign = 'left' 2375 ml0 = None 2376 for x,m in magLineList: 2377 ml = m 2378 if int(m) == m: 2379 ml = int(m) 2380 if x is None: 2381 magMarkers.append(None) 2382 multArray *= m 2383 ml0 = ml 2384 continue 2385 multArray[Pattern[1][0]>x] = m 2386 if G2frame.plotStyle['qPlot']: 2387 x = 2.*np.pi/G2lat.Pos2dsp(Parms,x) 2388 elif G2frame.plotStyle['dPlot']: 2389 x = G2lat.Pos2dsp(Parms,x) 2390 # is range in displayed range (defined after newplot)? 2391 if not newPlot: 2392 (xmin,xmax),ylim = G2frame.xylim 2393 if x < xmin: 2394 ml0 = ml 2395 continue 2396 if x > xmax: 2397 continue 2398 magMarkers.append(Plot.axvline(x,color='0.5',dashes=(1,1),picker=2.)) 2399 Plot.annotate("x{}".format(ml), xy=(x, tpos), xycoords=("data", "axes fraction"), 2400 verticalalignment='bottom',horizontalalignment=halign) 2401 if ml0: 2402 Plot.annotate("x{}".format(ml0), xy=(tcorner, tpos), xycoords="axes fraction", 2403 verticalalignment='bottom',horizontalalignment=halign) 2404 Page.toolbar.updateActions = (PlotPatterns,G2frame) 2405 multArray = ma.getdata(multArray) 2290 2406 if 'PWDR' in plottype: 2291 2407 if G2frame.plotStyle['sqrtPlot']: … … 2293 2409 Y = np.where(xye[1]+bxye>=0.,np.sqrt(xye[1]+bxye),-np.sqrt(-xye[1]-bxye)) 2294 2410 np.seterr(invalid=olderr['invalid']) 2411 elif 'PWDR' in plottype and G2frame.SinglePlot and not ( 2412 G2frame.logPlot or G2frame.plotStyle['sqrtPlot'] or G2frame.Contour): 2413 Y = xye[1]*multArray+bxye+offsetY*N*Ymax/100.0 2295 2414 else: 2296 2415 Y = xye[1]+bxye+offsetY*N*Ymax/100.0 … … 2345 2464 np.seterr(invalid=olderr['invalid']) 2346 2465 else: 2347 Z = xye[3]+offsetY*N*Ymax/100.0 2466 if 'PWDR' in plottype and G2frame.SinglePlot and not ( 2467 G2frame.logPlot or G2frame.plotStyle['sqrtPlot'] or G2frame.Contour): 2468 Z = xye[3]*multArray+offsetY*N*Ymax/100.0 2469 else: 2470 Z = xye[3]+offsetY*N*Ymax/100.0 2348 2471 if 'PWDR' in plottype: 2349 2472 if G2frame.plotStyle['sqrtPlot']: … … 2352 2475 np.seterr(invalid=olderr['invalid']) 2353 2476 D = np.where(xye[5],(Y-Z),0.)-Pattern[0]['delOffset'] 2477 elif 'PWDR' in plottype and G2frame.SinglePlot and not ( 2478 G2frame.logPlot or G2frame.plotStyle['sqrtPlot'] or G2frame.Contour): 2479 W = xye[4]*multArray+offsetY*N*Ymax/100.0 2480 D = multArray*xye[5]-Pattern[0]['delOffset'] #powder background 2354 2481 else: 2355 2482 W = xye[4]+offsetY*N*Ymax/100.0 … … 2477 2604 # axcb = mpl.colorbar.ColorbarBase(N) 2478 2605 # axcb.set_label('PDF number') 2606 if not magLineList: 2607 Plot.set_title(Title) 2479 2608 2480 2609 if PickId and not G2frame.Contour: … … 2537 2666 else: 2538 2667 G2frame.Lines = Lines 2668 G2frame.MagLines = magMarkers 2539 2669 if PickId and G2frame.GPXtree.GetItemText(PickId) == 'Background': 2540 2670 # plot fixed background points … … 3021 3151 Xb = [0.,peaks['Limits'][1]] 3022 3152 Yb = [0.,Xb[1]*peaks['Background'][1][1]] 3023 Plot.plot(Xb,Yb,color='k',dashes=(5,5)) 3153 Plot.plot(Xb,Yb,color='k',dashes=(5,5)) 3024 3154 # elif G2frame.Legend: 3025 3155 # Plot.legend(loc='best') … … 6114 6244 SetMapPeaksText(mapPeaks) 6115 6245 elif key in ['M',]and generalData['Modulated']: #make a movie file 6116 import imageio 6246 try: 6247 import imageio 6248 except ImportError: 6249 G2G.G2MessageBox(G2frame, 6250 'This command requires the Python imageio package to be installed', 6251 'missing package') 6252 return 6117 6253 from PIL import Image as Im 6118 6254 Fname = generalData['Name']+'.gif' -
trunk/docs/source/index.rst
r3270 r3288 44 44 * PyOpenGL (http://pyopengl.sourceforge.net/documentation). Note: a copy of this is distributed with GSAS-II (at present) and will be installed if the Python setuptools package is present. 45 45 46 Twopackages are used by some parts of the code, but are not46 Several packages are used by some parts of the code, but are not 47 47 required. If these packages are not present warning messages may be 48 generated but the vast bulk of GSAS-II will function normally.48 generated when needed, but the vast bulk of GSAS-II will function normally. 49 49 50 50 * PIL (http://www.pythonware.com/products/pil/) or Pillow (https://pillow.readthedocs.org). This is used to save 51 51 and read certain types of images. 52 * h5py is the HDF5 support package. This is (not surprisingly) required 53 to import images from HDF5 files. If this library is not present, 52 * h5py is the HDF5 interface and hdf5 is the support package. These 53 packages are (not surprisingly) required 54 to import images from HDF5 files. If these libraries are not present, 54 55 the HDF5 importer(s) will not appear in the import menu and a 55 56 warning message appears on GSAS-II startup. 56 57 * When using Anaconda we also encourage installation of the subversion58 (svn) package. This is a separate package from Python and is used by59 GSAS-II to download updates to our code. It can also be installed60 separately.57 * imageio is used to make movies. 58 * svn: When using Anaconda we also encourage installation of the 59 svn (subversion) conda package. This is not actually part of Python 60 and can be installed directly into your system's configuration. It is used by 61 GSAS-II to download updates to our code. 61 62 62 63 Note that the packages listed above are not distributed as part of the Python standard … … 67 68 We do some testing using the older Enthought Python Distribution 68 69 (EPD); this is known to have some problems with reading CIFs and 69 encourage updating .70 encourage updating from that.
Note: See TracChangeset
for help on using the changeset viewer.