Changeset 5373 for trunk/GSASIIctrlGUI.py
- Timestamp:
- Nov 17, 2022 10:59:43 AM (7 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/GSASIIctrlGUI.py
r5371 r5373 109 109 CIF powder histogram imports only 110 110 :func:`PhaseSelector` Select a phase from a list (used for phase importers) 111 :class:`gpxFileSelector` File browser dialog for opening existing .gpx files 111 112 112 113 ================================ ================================================================= … … 180 181 import GSASIImath as G2mth 181 182 import GSASIIstrMain as G2stMn 183 import GSASIIIO as G2IO 182 184 import config_example 183 185 if sys.version_info[0] >= 3: … … 8492 8494 dlg.Show() 8493 8495 8496 ################################################################################ 8497 # GPX browser routines 8498 def skimGPX(fl): 8499 '''pull out fit information from a .gpx file quickly 8500 8501 :returns: dict with status info 8502 ''' 8503 if fl is None: return {} 8504 result = {} 8505 if not os.path.exists(fl): 8506 return {'error':'File does not exist!'} 8507 cnt = 0 8508 hist = 0 8509 fp = open(fl,'rb') 8510 result['last saved'] = time.ctime(os.stat(fl).st_mtime) 8511 try: 8512 while True: 8513 cnt += 1 8514 try: 8515 data = G2IO.cPickleLoad(fp) 8516 except EOFError: 8517 #print(cnt,'entries read') 8518 break 8519 if cnt > 50: # don't spend too long on this file, if big 8520 result['PWDR'] += 3*[' .'] 8521 break 8522 datum = data[0] 8523 if datum[0] == 'Notebook': 8524 result[datum[0]] = datum[1][-1] 8525 elif datum[0] == 'Covariance': 8526 d = datum[1]['Rvals'] 8527 result[datum[0]] = 'Overall: Rwp={:.2f}, GOF={:.1f}'.format( 8528 d.get('Rwp','?'),d.get('GOF','?')) 8529 if d.get('converged',False): 8530 result[datum[0]] += ' **Converged**' 8531 elif datum[0].startswith('PWDR'): 8532 if 'Residuals' not in datum[1][0]: continue 8533 if 'PWDR' not in result: result['PWDR'] = [] 8534 result['PWDR'].append( 8535 "hist #{}: wR={:.2f} ({:})".format( 8536 hist,datum[1][0]['Residuals'].get('wR','?'),datum[0])) 8537 hist += 1 8538 # elif datum[0].startswith('HKLF'): 8539 # pass 8540 # elif 'Controls' in datum[0]: 8541 # datum[0]['Seq Data'] 8542 elif datum[0] in ('Constraints','Restraints','Rigid bodies'): 8543 pass 8544 else: 8545 pass 8546 #GSASIIpath.IPyBreak_base() 8547 except Exception as msg: 8548 result['error'] = 'read error: '+str(msg) 8549 finally: 8550 fp.close() 8551 return result 8552 8553 class gpxFileSelector(wx.Dialog): 8554 '''Create a file selection widget for locating .gpx files as a modal 8555 dialog. Displays status information on selected files. After creating 8556 this use dlg.ShowModal() to wait for selection of a file. 8557 If dlg.ShowModal() returns wx.ID_OK, use dlg.Selection (multiple=False) 8558 to obtain the selected file or dlg.Selections (multiple=True) to 8559 obtain a list of multiple files. 8560 8561 :param wx.Frame parent: name of panel or frame that will be 8562 the parent to the dialog. Can be None. 8563 8564 :param path startdir: Specifies the initial directory that is 8565 opened when the window is initially opened. Default is '.' 8566 8567 :param bool multiple: if True, checkboxes are used to allow 8568 selection of multiple files. Default is False 8569 8570 ''' 8571 def __init__(self,parent,startdir='.',multiple=False,*args,**kwargs): 8572 import wx.lib.filebrowsebutton as wxfilebrowse 8573 import wx.richtext as wxrt 8574 self.timer = None 8575 self.delay = 1500 # time to wait before applying filter (1.5 sec) 8576 self.Selection = None 8577 self.Selections = [] 8578 self.startDir = startdir 8579 if startdir == '.': 8580 self.startDir = os.getcwd() 8581 self.multiple = multiple 8582 wx.Dialog.__init__(self, parent=parent, 8583 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) 8584 self.CenterOnParent() 8585 8586 topSizer = wx.BoxSizer(wx.VERTICAL) 8587 self.dirBtn = wxfilebrowse.DirBrowseButton(self,wx.ID_ANY, size=(650, -1), 8588 changeCallback = self.DirSelected, 8589 startDirectory = self.startDir 8590 ) 8591 topSizer.Add(self.dirBtn,0,wx.EXPAND,1) 8592 8593 subSiz = wx.BoxSizer(wx.HORIZONTAL) 8594 self.opt = {'useBak':False, 'sort':0, 'filter':'*'} 8595 chk = G2CheckBoxFrontLbl(self,' Include\n .bakXX?',self.opt,'useBak', 8596 OnChange=self.DirSelected) 8597 subSiz.Add(chk) 8598 subSiz.Add((10,-1),1,wx.EXPAND,1) 8599 subSiz.Add(wx.StaticText(self,wx.ID_ANY,' Sort by: '),0,wx.ALIGN_CENTER_VERTICAL,1) 8600 choices = ['age','name (alpha+case)','name (alpha)'] 8601 for w in G2RadioButtons(self,self.opt,'sort',choices, 8602 OnChange=self.DirSelected): 8603 subSiz.Add(w,0,wx.ALIGN_CENTER_VERTICAL,0) 8604 subSiz.Add((10,-1),1,wx.EXPAND,1) 8605 subSiz.Add(wx.StaticText(self,wx.ID_ANY,'Name \nFilter: '),0,wx.ALIGN_CENTER_VERTICAL,1) 8606 self.filterBox = ValidatedTxtCtrl(self, self.opt, 'filter', 8607 size=(80,-1), style=wx.TE_PROCESS_ENTER, 8608 OnLeave=self.DirSelected, notBlank=False) 8609 self.filterBox.Bind(wx.EVT_TEXT,self._startUpdateTimer) 8610 self.filterBox.Bind(wx.EVT_TEXT_ENTER,self.DirSelected) 8611 subSiz.Add(self.filterBox) 8612 subSiz.Add((2,-1)) 8613 8614 topSizer.Add(subSiz,0,wx.EXPAND,0) 8615 8616 mainPanel = wx.SplitterWindow(self, wx.ID_ANY, style=wx.SP_LIVE_UPDATE|wx.SP_3D) 8617 mainPanel.SetMinimumPaneSize(100) 8618 8619 if self.multiple: 8620 self.fileBox = wx.CheckListBox(mainPanel,wx.ID_ANY, size=(200, 200), 8621 style=wx.LB_SINGLE) 8622 self.fileBox.Bind(wx.EVT_CHECKLISTBOX,self.FileSelected) 8623 else: 8624 self.fileBox = wx.ListBox(mainPanel,wx.ID_ANY, size=(200, 200), 8625 style=wx.LB_SINGLE) 8626 self.fileBox.Bind(wx.EVT_LISTBOX,self.FileSelected) 8627 8628 self.rtc = wxrt.RichTextCtrl(mainPanel, style=wx.VSCROLL|wx.HSCROLL| 8629 wx.NO_BORDER|wx.richtext.RE_READONLY) 8630 mainPanel.SplitVertically(self.fileBox, self.rtc, 200) 8631 topSizer.Add(mainPanel,1,wx.EXPAND) 8632 8633 subSiz = wx.BoxSizer(wx.HORIZONTAL) 8634 subSiz.Add((-1,-1),1,wx.EXPAND,1) 8635 self.OKbtn = wx.Button(self, wx.ID_OK, label='Open') 8636 self.OKbtn.Enable(False) # A file must be selected 1st 8637 btn = wx.Button(self, wx.ID_CANCEL) 8638 subSiz.Add(self.OKbtn) 8639 subSiz.Add((5,-1)) 8640 subSiz.Add(btn) 8641 subSiz.Add((-1,-1),1,wx.EXPAND,1) 8642 topSizer.Add(subSiz,0,wx.EXPAND) 8643 self.SetSizer(topSizer) 8644 topSizer.Fit(self) 8645 self.dirBtn.SetValue(self.startDir) 8646 8647 def _startUpdateTimer(self,event): 8648 if self.timer: 8649 self.timer.Restart(self.delay) 8650 else: 8651 self.timer = wx.CallLater(self.delay,self.DirSelected) 8652 8653 def DirSelected(self,event=None,*args,**kwargs): 8654 '''Respond to a directory being selected. List files found in fileBox and 8655 clear any selections. Also clear any reference to a timer. 8656 ''' 8657 import re 8658 try: 8659 if self.timer: self.timer.Stop() 8660 except: 8661 pass 8662 self.timer = None 8663 self.fileBox.Clear() 8664 self.rtc.Clear() 8665 self.Selection = None 8666 self.Selections = [] 8667 self.OKbtn.Enable(False) 8668 glb = self.opt['filter'].strip() 8669 if not glb: 8670 glb = '*' 8671 elif not '*' in glb: 8672 glb = '*' + glb + '*' 8673 fullglob = os.path.join(self.dirBtn.GetValue(),glb+'.gpx') 8674 self.fl = glob.glob(fullglob) 8675 if self.opt['useBak']: 8676 self.sl = [(os.path.split(i)[1],os.stat(i).st_mtime,i) for i in self.fl] 8677 else: 8678 self.sl = [(os.path.split(i)[1],os.stat(i).st_mtime,i) for i in self.fl 8679 if not re.match(r'.*\.bak\d+\.gpx.*',i)] 8680 if self.opt['sort'] == 0: 8681 self.sl.sort(key=lambda x: x[1],reverse=True) 8682 elif self.opt['sort'] == 1: 8683 self.sl.sort(key=lambda x: x[0]) 8684 else: 8685 self.sl.sort(key=lambda x: x[0].lower()) 8686 items = [i[0]+' ('+self._fmtTimeStampDelta(i[1])+')' for i in self.sl] 8687 if items: 8688 self.fileBox.InsertItems(items,0) 8689 8690 def FileSelected(self,event): 8691 '''Respond to a file being selected (or checked in multiple mode) 8692 ''' 8693 if self.multiple: # disable Open when nothing is selected 8694 self.Selections = [] 8695 OK = False 8696 for i in self.fileBox.GetCheckedItems(): 8697 self.Selections.append(self.sl[i][2]) 8698 OK = True 8699 self.OKbtn.Enable(OK) 8700 else: 8701 self.OKbtn.Enable(True) 8702 self.Selection = self.sl[self.fileBox.GetSelection()][2] 8703 result = skimGPX(self.Selection) 8704 self.displayGPXrtc(result,self.Selection) 8705 8706 def displayGPXrtc(self,result,fwp): 8707 '''Show info about selected file in a RichText display''' 8708 self.rtc.Clear() 8709 if fwp is None: return 8710 self.rtc.Freeze() 8711 self.rtc.BeginSuppressUndo() 8712 self.rtc.BeginAlignment(wx.TEXT_ALIGNMENT_CENTER) 8713 self.rtc.BeginFontSize(14) 8714 self.rtc.BeginBold() 8715 self.rtc.WriteText(os.path.split(fwp)[1]) 8716 self.rtc.EndBold() 8717 self.rtc.Newline() 8718 self.rtc.EndFontSize() 8719 self.rtc.EndAlignment() 8720 self.rtc.WriteText('last saved on ') 8721 self.rtc.WriteText(result['last saved']) 8722 self.rtc.Newline() 8723 if 'Covariance' in result: 8724 self.rtc.BeginLeftIndent(0,40) 8725 self.rtc.WriteText(result['Covariance']) 8726 self.rtc.Newline() 8727 self.rtc.EndLeftIndent() 8728 if 'Notebook' in result: 8729 self.rtc.BeginLeftIndent(0,40) 8730 self.rtc.BeginItalic() 8731 self.rtc.WriteText('Last notebook entry: ') 8732 self.rtc.EndItalic() 8733 self.rtc.WriteText(result['Notebook']) 8734 self.rtc.Newline() 8735 self.rtc.EndLeftIndent() 8736 8737 if 'PWDR' in result: 8738 self.rtc.BeginParagraphSpacing(0,0) 8739 self.rtc.BeginLeftIndent(0) 8740 self.rtc.BeginBold() 8741 self.rtc.WriteText('Powder histograms:') 8742 self.rtc.EndBold() 8743 self.rtc.EndLeftIndent() 8744 self.rtc.Newline() 8745 self.rtc.BeginLeftIndent(40) 8746 for line in result['PWDR']: 8747 self.rtc.WriteText(line+'\n') 8748 self.rtc.EndLeftIndent() 8749 self.rtc.EndParagraphSpacing() 8750 8751 if 'error' in result: 8752 self.rtc.Newline() 8753 self.rtc.BeginBold() 8754 self.rtc.WriteText('Error encountered: ') 8755 self.rtc.EndBold() 8756 self.rtc.WriteText(result['error']) 8757 self.rtc.EndSuppressUndo() 8758 self.rtc.Thaw() 8759 8760 def _fmtTimeStampDelta(self,tm): 8761 'Show file age relative to now' 8762 delta = time.time() - tm 8763 if delta > 60*60*24*365: 8764 return "{:.2f} years".format(delta/(60*60*24*365)) 8765 elif delta > 60*60*24*7: 8766 return "{:.1f} weeks".format(delta/(60*60*24*7)) 8767 elif delta > 60*60*24: 8768 return "{:.1f} days".format(delta/(60*60*24)) 8769 elif delta > 60*60: 8770 return "{:.1f} hours".format(delta/(60*60)) 8771 else: 8772 return "{:.1f} minutes".format(delta/60) 8773 8774 8494 8775 if __name__ == '__main__': 8495 8776 app = wx.App()
Note: See TracChangeset
for help on using the changeset viewer.