[811] | 1 | # -*- coding: utf-8 -*- |
---|
| 2 | #GSASIIconstrGUI - constraint GUI routines |
---|
| 3 | ########### SVN repository information ################### |
---|
| 4 | # $Date: 2012-12-05 15:38:26 -0600 (Wed, 05 Dec 2012) $ |
---|
| 5 | # $Author: vondreele $ |
---|
| 6 | # $Revision: 810 $ |
---|
| 7 | # $URL: https://subversion.xor.aps.anl.gov/pyGSAS/trunk/GSASIIconstrGUI.py $ |
---|
| 8 | # $Id: GSASIIconstrGUI.py 810 2012-12-05 21:38:26Z vondreele $ |
---|
| 9 | ########### SVN repository information ################### |
---|
[831] | 10 | import sys |
---|
[811] | 11 | import wx |
---|
[831] | 12 | import wx.grid as wg |
---|
[811] | 13 | import time |
---|
[831] | 14 | import random as ran |
---|
[811] | 15 | import numpy as np |
---|
| 16 | import numpy.ma as ma |
---|
| 17 | import os.path |
---|
| 18 | import GSASIIpath |
---|
| 19 | GSASIIpath.SetVersionNumber("$Revision: 810 $") |
---|
[831] | 20 | import GSASIIElem as G2elem |
---|
| 21 | import GSASIIElemGUI as G2elemGUI |
---|
[811] | 22 | import GSASIIstruct as G2str |
---|
| 23 | import GSASIImapvars as G2mv |
---|
| 24 | import GSASIIgrid as G2gd |
---|
[831] | 25 | import GSASIIplot as G2plt |
---|
| 26 | VERY_LIGHT_GREY = wx.Colour(235,235,235) |
---|
[811] | 27 | |
---|
[831] | 28 | class MultiIntegerDialog(wx.Dialog): |
---|
| 29 | |
---|
| 30 | def __init__(self,parent,title,prompts,values): |
---|
| 31 | wx.Dialog.__init__(self,parent,-1,title, |
---|
| 32 | pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE) |
---|
| 33 | self.panel = wx.Panel(self) #just a dummy - gets destroyed in Draw! |
---|
| 34 | self.values = values |
---|
| 35 | self.prompts = prompts |
---|
| 36 | self.Draw() |
---|
| 37 | |
---|
| 38 | def Draw(self): |
---|
| 39 | |
---|
| 40 | def OnValItem(event): |
---|
| 41 | Obj = event.GetEventObject() |
---|
| 42 | ind = Indx[Obj.GetId()] |
---|
| 43 | try: |
---|
| 44 | val = int(Obj.GetValue()) |
---|
| 45 | if val <= 0: |
---|
| 46 | raise ValueError |
---|
| 47 | except ValueError: |
---|
| 48 | val = self.values[ind] |
---|
| 49 | self.values[ind] = val |
---|
| 50 | Obj.SetValue('%d'%(val)) |
---|
| 51 | |
---|
| 52 | self.panel.Destroy() |
---|
| 53 | self.panel = wx.Panel(self) |
---|
| 54 | mainSizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 55 | Indx = {} |
---|
| 56 | for ival,[prompt,value] in enumerate(zip(self.prompts,self.values)): |
---|
| 57 | mainSizer.Add(wx.StaticText(self.panel,-1,prompt),0,wx.ALIGN_CENTER) |
---|
| 58 | valItem = wx.TextCtrl(self.panel,-1,value='%d'%(value),style=wx.TE_PROCESS_ENTER) |
---|
| 59 | mainSizer.Add(valItem,0,wx.ALIGN_CENTER) |
---|
| 60 | Indx[valItem.GetId()] = ival |
---|
| 61 | valItem.Bind(wx.EVT_TEXT_ENTER,OnValItem) |
---|
| 62 | valItem.Bind(wx.EVT_KILL_FOCUS,OnValItem) |
---|
| 63 | OkBtn = wx.Button(self.panel,-1,"Ok") |
---|
| 64 | OkBtn.Bind(wx.EVT_BUTTON, self.OnOk) |
---|
| 65 | CancelBtn = wx.Button(self.panel,-1,'Cancel') |
---|
| 66 | CancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel) |
---|
| 67 | btnSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 68 | btnSizer.Add((20,20),1) |
---|
| 69 | btnSizer.Add(OkBtn) |
---|
| 70 | btnSizer.Add(CancelBtn) |
---|
| 71 | btnSizer.Add((20,20),1) |
---|
| 72 | mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10) |
---|
| 73 | self.panel.SetSizer(mainSizer) |
---|
| 74 | self.panel.Fit() |
---|
| 75 | self.Fit() |
---|
| 76 | |
---|
| 77 | def GetValues(self): |
---|
| 78 | return self.values |
---|
| 79 | |
---|
| 80 | def OnOk(self,event): |
---|
| 81 | parent = self.GetParent() |
---|
| 82 | parent.Raise() |
---|
| 83 | self.EndModal(wx.ID_OK) |
---|
| 84 | |
---|
| 85 | def OnCancel(self,event): |
---|
| 86 | parent = self.GetParent() |
---|
| 87 | parent.Raise() |
---|
| 88 | self.EndModal(wx.ID_CANCEL) |
---|
| 89 | |
---|
[811] | 90 | ################################################################################ |
---|
| 91 | ##### Constraints |
---|
| 92 | ################################################################################ |
---|
| 93 | |
---|
| 94 | def UpdateConstraints(G2frame,data): |
---|
| 95 | '''Called when Constraints tree item is selected. |
---|
| 96 | Displays the constraints in the data window |
---|
| 97 | ''' |
---|
| 98 | if not data: |
---|
| 99 | data.update({'Hist':[],'HAP':[],'Phase':[]}) #empty dict - fill it |
---|
| 100 | Histograms,Phases = G2frame.GetUsedHistogramsAndPhasesfromTree() |
---|
| 101 | AtomDict = dict([Phases[phase]['pId'],Phases[phase]['Atoms']] for phase in Phases) |
---|
| 102 | Natoms,atomIndx,phaseVary,phaseDict,pawleyLookup,FFtable,BLtable = G2str.GetPhaseData(Phases,Print=False) |
---|
| 103 | phaseList = [] |
---|
| 104 | for item in phaseDict: |
---|
| 105 | if item.split(':')[2] not in ['Ax','Ay','Az','Amul','AI/A','Atype','SHorder']: |
---|
| 106 | phaseList.append(item) |
---|
| 107 | phaseList.sort() |
---|
| 108 | phaseAtNames = {} |
---|
| 109 | phaseAtTypes = {} |
---|
| 110 | TypeList = [] |
---|
| 111 | for item in phaseList: |
---|
| 112 | Split = item.split(':') |
---|
| 113 | if Split[2][:2] in ['AU','Af','dA']: |
---|
| 114 | Id = int(Split[0]) |
---|
| 115 | phaseAtNames[item] = AtomDict[Id][int(Split[3])][0] |
---|
| 116 | phaseAtTypes[item] = AtomDict[Id][int(Split[3])][1] |
---|
| 117 | if phaseAtTypes[item] not in TypeList: |
---|
| 118 | TypeList.append(phaseAtTypes[item]) |
---|
| 119 | else: |
---|
| 120 | phaseAtNames[item] = '' |
---|
| 121 | phaseAtTypes[item] = '' |
---|
| 122 | |
---|
| 123 | hapVary,hapDict,controlDict = G2str.GetHistogramPhaseData(Phases,Histograms,Print=False) |
---|
| 124 | hapList = hapDict.keys() |
---|
| 125 | hapList.sort() |
---|
| 126 | histVary,histDict,controlDict = G2str.GetHistogramData(Histograms,Print=False) |
---|
| 127 | histList = [] |
---|
| 128 | for item in histDict: |
---|
| 129 | if item.split(':')[2] not in ['Omega','Type','Chi','Phi','Azimuth','Gonio. radius','Lam1','Lam2','Back']: |
---|
| 130 | histList.append(item) |
---|
| 131 | histList.sort() |
---|
| 132 | Indx = {} |
---|
| 133 | scope = {} #filled out later |
---|
| 134 | G2frame.Page = [0,'phs'] |
---|
| 135 | |
---|
| 136 | def GetPHlegends(Phases,Histograms): |
---|
| 137 | plegend = '\n In p::name' |
---|
| 138 | hlegend = '\n In :h:name' |
---|
| 139 | phlegend = '\n In p:h:name' |
---|
| 140 | for phase in Phases: |
---|
| 141 | plegend += '\n p:: = '+str(Phases[phase]['pId'])+':: for '+phase |
---|
| 142 | count = 0 |
---|
| 143 | for histogram in Phases[phase]['Histograms']: |
---|
| 144 | if count < 3: |
---|
| 145 | phlegend += '\n p:h: = '+str(Phases[phase]['pId'])+':'+str(Histograms[histogram]['hId'])+': for '+phase+' in '+histogram |
---|
| 146 | else: |
---|
| 147 | phlegend += '\n ... etc.' |
---|
| 148 | break |
---|
| 149 | count += 1 |
---|
| 150 | count = 0 |
---|
| 151 | for histogram in Histograms: |
---|
| 152 | if count < 3: |
---|
| 153 | hlegend += '\n :h: = :'+str(Histograms[histogram]['hId'])+': for '+histogram |
---|
| 154 | else: |
---|
| 155 | hlegend += '\n ... etc.' |
---|
| 156 | break |
---|
| 157 | count += 1 |
---|
| 158 | return plegend,hlegend,phlegend |
---|
| 159 | |
---|
| 160 | def FindEquivVarb(name,nameList): |
---|
| 161 | outList = [] |
---|
| 162 | phlist = [] |
---|
| 163 | items = name.split(':') |
---|
| 164 | namelist = [items[2],] |
---|
| 165 | if 'dA' in name: |
---|
| 166 | namelist = ['dAx','dAy','dAz'] |
---|
| 167 | elif 'AU' in name: |
---|
| 168 | namelist = ['AUiso','AU11','AU22','AU33','AU12','AU13','AU23'] |
---|
| 169 | for item in nameList: |
---|
| 170 | keys = item.split(':') |
---|
| 171 | if keys[0] not in phlist: |
---|
| 172 | phlist.append(keys[0]) |
---|
| 173 | if keys[2] in namelist and item != name: |
---|
| 174 | outList.append(item) |
---|
| 175 | if items[1]: |
---|
| 176 | for key in phlist: |
---|
| 177 | outList.append(key+':all:'+items[2]) |
---|
| 178 | return outList |
---|
| 179 | |
---|
| 180 | def SelectVarbs(page,FrstVarb,varList,legend,constType): |
---|
| 181 | '''Select variables used in Constraints after one variable has |
---|
| 182 | been selected which determines the appropriate variables to be |
---|
| 183 | used here. Then creates the constraint and adds it to the |
---|
| 184 | constraints list. |
---|
| 185 | Called from OnAddEquivalence, OnAddFunction & OnAddConstraint |
---|
| 186 | ''' |
---|
| 187 | #future - add 'all:all:name', '0:all:name', etc. to the varList |
---|
| 188 | if page[1] == 'phs': |
---|
| 189 | atchoice = [item+' for '+phaseAtNames[item] for item in varList] |
---|
| 190 | atchoice += [FrstVarb+' for all'] |
---|
| 191 | atchoice += [FrstVarb+' for all '+atype for atype in TypeList] |
---|
| 192 | dlg = wx.MultiChoiceDialog(G2frame,'Select more variables:'+legend, |
---|
| 193 | 'Constrain '+FrstVarb+' and...',atchoice) |
---|
| 194 | else: |
---|
| 195 | dlg = wx.MultiChoiceDialog(G2frame,'Select more variables:'+legend, |
---|
| 196 | 'Constrain '+FrstVarb+' and...',varList) |
---|
| 197 | varbs = [FrstVarb,] |
---|
| 198 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 199 | sel = dlg.GetSelections() |
---|
| 200 | try: |
---|
| 201 | for x in sel: |
---|
| 202 | if ':all:' in varList[x]: #a histogram 'all' - supercedes any individual selection |
---|
| 203 | varbs = [FrstVarb,] |
---|
| 204 | items = varList[x].split(':') |
---|
| 205 | for item in varList: |
---|
[828] | 206 | if items[0] == item.split(':')[0] and ':all:' not in item: |
---|
[811] | 207 | varbs.append(item) |
---|
| 208 | break |
---|
| 209 | else: |
---|
| 210 | varbs.append(varList[x]) |
---|
| 211 | except IndexError: # one of the 'all' chosen - supercedes any individual selection |
---|
| 212 | varbs = [FrstVarb,] |
---|
| 213 | Atypes = [] |
---|
| 214 | for x in sel: |
---|
| 215 | item = atchoice[x] |
---|
| 216 | if 'all' in item: |
---|
| 217 | Atypes.append(item.split('all')[1].strip()) |
---|
| 218 | if '' in Atypes: |
---|
| 219 | varbs += varList |
---|
| 220 | else: |
---|
| 221 | for item in varList: |
---|
| 222 | if phaseAtTypes[item] in Atypes: |
---|
| 223 | varbs.append(item) |
---|
| 224 | dlg.Destroy() |
---|
| 225 | if len(varbs) > 1: |
---|
| 226 | if 'equivalence' in constType: |
---|
| 227 | constr = [[1.0,FrstVarb]] |
---|
| 228 | for item in varbs[1:]: |
---|
| 229 | constr += [[1.0,item]] |
---|
| 230 | return [constr+[None,None,'e']] # list of equivalent variables & mults |
---|
| 231 | elif 'function' in constType: |
---|
| 232 | constr = map(list,zip([1.0 for i in range(len(varbs))],varbs)) |
---|
| 233 | return [constr+[None,False,'f']] #just one constraint |
---|
| 234 | else: #'constraint' |
---|
| 235 | constr = map(list,zip([1.0 for i in range(len(varbs))],varbs)) |
---|
| 236 | return [constr+[1.0,None,'c']] #just one constraint - default sum to one |
---|
| 237 | return [] |
---|
| 238 | |
---|
| 239 | def CheckAddedConstraint(newcons): |
---|
| 240 | '''Check a new constraint that has just been input. |
---|
| 241 | If there is an error display a message and give the user a |
---|
| 242 | choice to keep or discard the last entry (why keep? -- they |
---|
| 243 | may want to delete something else or edit multipliers). |
---|
| 244 | Since the varylist is not available, no warning messages |
---|
| 245 | should be generated. |
---|
| 246 | Returns True if constraint should be added |
---|
| 247 | ''' |
---|
| 248 | allcons = [] |
---|
| 249 | for key in 'Hist','HAP','Phase': |
---|
| 250 | allcons += data[key] |
---|
| 251 | allcons += newcons |
---|
| 252 | if not len(allcons): return True |
---|
| 253 | G2mv.InitVars() |
---|
| 254 | constDictList,fixedList,ignored = G2str.ProcessConstraints(allcons) |
---|
| 255 | errmsg, warnmsg = G2mv.CheckConstraints('',constDictList,fixedList) |
---|
| 256 | if errmsg: |
---|
| 257 | res = G2frame.ErrorDialog('Constraint Error', |
---|
| 258 | 'Error with newly added constraint:\n'+errmsg+ |
---|
| 259 | '\n\nDiscard newly added constraint?',parent=G2frame.dataFrame, |
---|
| 260 | wtype=wx.YES_NO) |
---|
| 261 | return res != wx.ID_YES |
---|
| 262 | elif warnmsg: |
---|
| 263 | print 'Unexpected contraint warning:\n',warnmsg |
---|
| 264 | return True |
---|
| 265 | |
---|
| 266 | def CheckChangedConstraint(): |
---|
| 267 | '''Check all constraints after an edit has been made. |
---|
| 268 | If there is an error display a message and give the user a |
---|
| 269 | choice to keep or discard the last edit. |
---|
| 270 | Since the varylist is not available, no warning messages |
---|
| 271 | should be generated. |
---|
| 272 | Returns True if the edit should be retained |
---|
| 273 | ''' |
---|
| 274 | allcons = [] |
---|
| 275 | for key in 'Hist','HAP','Phase': |
---|
| 276 | allcons += data[key] |
---|
| 277 | if not len(allcons): return True |
---|
| 278 | G2mv.InitVars() |
---|
| 279 | constDictList,fixedList,ignored = G2str.ProcessConstraints(allcons) |
---|
| 280 | errmsg, warnmsg = G2mv.CheckConstraints('',constDictList,fixedList) |
---|
| 281 | if errmsg: |
---|
| 282 | res = G2frame.ErrorDialog('Constraint Error', |
---|
| 283 | 'Error after editing constraint:\n'+errmsg+ |
---|
| 284 | '\n\nDiscard last constraint edit?',parent=G2frame.dataFrame, |
---|
| 285 | wtype=wx.YES_NO) |
---|
| 286 | return res != wx.ID_YES |
---|
| 287 | elif warnmsg: |
---|
| 288 | print 'Unexpected contraint warning:\n',warnmsg |
---|
| 289 | return True |
---|
| 290 | |
---|
| 291 | def OnAddHold(event): |
---|
| 292 | '''add a Hold constraint''' |
---|
| 293 | for phase in Phases: |
---|
| 294 | Phase = Phases[phase] |
---|
| 295 | Atoms = Phase['Atoms'] |
---|
| 296 | constr = [] |
---|
| 297 | page = G2frame.Page |
---|
| 298 | choice = scope[page[1]] |
---|
| 299 | if page[1] == 'phs': |
---|
| 300 | atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]] |
---|
| 301 | dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],atchoice) |
---|
| 302 | else: |
---|
| 303 | dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],choice[2]) |
---|
| 304 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 305 | sel = dlg.GetSelection() |
---|
| 306 | FrstVarb = choice[2][sel] |
---|
| 307 | newcons = [[[0.0,FrstVarb],None,None,'h']] |
---|
| 308 | if CheckAddedConstraint(newcons): |
---|
| 309 | data[choice[3]] += newcons |
---|
| 310 | dlg.Destroy() |
---|
| 311 | choice[4]() |
---|
| 312 | |
---|
| 313 | def OnAddEquivalence(event): |
---|
| 314 | '''add an Equivalence constraint''' |
---|
| 315 | constr = [] |
---|
| 316 | page = G2frame.Page |
---|
| 317 | choice = scope[page[1]] |
---|
| 318 | if page[1] == 'phs': |
---|
| 319 | atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]] |
---|
| 320 | dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],atchoice) |
---|
| 321 | else: |
---|
| 322 | dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],choice[2]) |
---|
| 323 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 324 | sel = dlg.GetSelection() |
---|
| 325 | FrstVarb = choice[2][sel] |
---|
| 326 | moreVarb = FindEquivVarb(FrstVarb,choice[2]) |
---|
| 327 | newcons = SelectVarbs(page,FrstVarb,moreVarb,choice[1],'equivalence') |
---|
| 328 | if len(newcons) > 0: |
---|
| 329 | if CheckAddedConstraint(newcons): |
---|
| 330 | data[choice[3]] += newcons |
---|
| 331 | dlg.Destroy() |
---|
| 332 | choice[4]() |
---|
| 333 | |
---|
| 334 | def OnAddFunction(event): |
---|
| 335 | '''add a Function (new variable) constraint''' |
---|
| 336 | constr = [] |
---|
| 337 | page = G2frame.Page |
---|
| 338 | choice = scope[page[1]] |
---|
| 339 | if page[1] == 'phs': |
---|
| 340 | atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]] |
---|
| 341 | dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],atchoice) |
---|
| 342 | else: |
---|
| 343 | dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],choice[2]) |
---|
| 344 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 345 | sel = dlg.GetSelection() |
---|
| 346 | FrstVarb = choice[2][sel] |
---|
| 347 | moreVarb = FindEquivVarb(FrstVarb,choice[2]) |
---|
| 348 | newcons = SelectVarbs(page,FrstVarb,moreVarb,choice[1],'function') |
---|
| 349 | if len(newcons) > 0: |
---|
| 350 | if CheckAddedConstraint(newcons): |
---|
| 351 | data[choice[3]] += newcons |
---|
| 352 | dlg.Destroy() |
---|
| 353 | choice[4]() |
---|
| 354 | |
---|
| 355 | def OnAddConstraint(event): |
---|
| 356 | '''add a constraint equation to the constraints list''' |
---|
| 357 | constr = [] |
---|
| 358 | page = G2frame.Page |
---|
| 359 | choice = scope[page[1]] |
---|
| 360 | if page[1] == 'phs': |
---|
| 361 | atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]] |
---|
| 362 | dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],atchoice) |
---|
| 363 | else: |
---|
| 364 | dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],choice[2]) |
---|
| 365 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 366 | sel = dlg.GetSelection() |
---|
| 367 | FrstVarb = choice[2][sel] |
---|
| 368 | moreVarb = FindEquivVarb(FrstVarb,choice[2]) |
---|
| 369 | newcons = SelectVarbs(page,FrstVarb,moreVarb,choice[1],'constraint') |
---|
| 370 | if len(newcons) > 0: |
---|
| 371 | if CheckAddedConstraint(newcons): |
---|
| 372 | data[choice[3]] += newcons |
---|
| 373 | dlg.Destroy() |
---|
| 374 | choice[4]() |
---|
| 375 | |
---|
| 376 | def ConstSizer(name,pageDisplay): |
---|
| 377 | '''This creates a sizer displaying all of the constraints entered |
---|
| 378 | ''' |
---|
| 379 | constSizer = wx.FlexGridSizer(1,4,0,0) |
---|
| 380 | maxlen = 70 # characters before wrapping a constraint |
---|
| 381 | for Id,item in enumerate(data[name]): |
---|
| 382 | eqString = ['',] |
---|
| 383 | if item[-1] == 'h': |
---|
| 384 | constSizer.Add((5,5),0) # blank space for edit button |
---|
| 385 | typeString = ' FIXED ' |
---|
| 386 | eqString[-1] = item[0][1]+' ' |
---|
| 387 | elif isinstance(item[-1],str): |
---|
| 388 | constEdit = wx.Button(pageDisplay,-1,'Edit',style=wx.BU_EXACTFIT) |
---|
| 389 | constEdit.Bind(wx.EVT_BUTTON,OnConstEdit) |
---|
| 390 | constSizer.Add(constEdit) # edit button |
---|
| 391 | Indx[constEdit.GetId()] = [Id,name] |
---|
| 392 | if item[-1] == 'f': |
---|
| 393 | for term in item[:-3]: |
---|
| 394 | if len(eqString[-1]) > maxlen: |
---|
| 395 | eqString.append(' ') |
---|
| 396 | m = term[0] |
---|
| 397 | if eqString[-1] != '': |
---|
| 398 | if m >= 0: |
---|
| 399 | eqString[-1] += ' + ' |
---|
| 400 | else: |
---|
| 401 | eqString[-1] += ' - ' |
---|
| 402 | m = abs(m) |
---|
| 403 | eqString[-1] += '%.3f*%s '%(m,term[1]) |
---|
| 404 | typeString = ' NEWVAR ' |
---|
| 405 | eqString[-1] += ' = New Variable ' |
---|
| 406 | elif item[-1] == 'c': |
---|
| 407 | for term in item[:-3]: |
---|
| 408 | if len(eqString[-1]) > maxlen: |
---|
| 409 | eqString.append(' ') |
---|
| 410 | if eqString[-1] != '': |
---|
| 411 | if term[0] > 0: |
---|
| 412 | eqString[-1] += ' + ' |
---|
| 413 | else: |
---|
| 414 | eqString[-1] += ' - ' |
---|
| 415 | eqString[-1] += '%.3f*%s '%(abs(term[0]),term[1]) |
---|
| 416 | typeString = ' CONSTR ' |
---|
| 417 | eqString[-1] += ' = %.3f'%(item[-3])+' ' |
---|
| 418 | elif item[-1] == 'e': |
---|
| 419 | for term in item[:-3]: |
---|
| 420 | if term[0] == 0: term[0] = 1.0 |
---|
| 421 | if len(eqString[-1]) > maxlen: |
---|
| 422 | eqString.append(' ') |
---|
| 423 | if eqString[-1] == '': |
---|
| 424 | eqString[-1] += '%s '%(term[1]) |
---|
| 425 | first = term[0] |
---|
| 426 | else: |
---|
| 427 | eqString[-1] += ' = %.3f*%s '%(first/term[0],term[1]) |
---|
| 428 | typeString = ' EQUIV ' |
---|
| 429 | else: |
---|
| 430 | print 'Unexpected constraint',item |
---|
| 431 | else: |
---|
| 432 | print 'Removing old-style constraints' |
---|
| 433 | data[name] = [] |
---|
| 434 | return constSizer |
---|
| 435 | constDel = wx.Button(pageDisplay,-1,'Delete',style=wx.BU_EXACTFIT) |
---|
| 436 | constDel.Bind(wx.EVT_BUTTON,OnConstDel) |
---|
| 437 | Indx[constDel.GetId()] = [Id,name] |
---|
| 438 | constSizer.Add(constDel) # delete button |
---|
| 439 | constSizer.Add(wx.StaticText(pageDisplay,-1,typeString),0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 440 | EqSizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 441 | for s in eqString: |
---|
| 442 | EqSizer.Add(wx.StaticText(pageDisplay,-1,s),0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 443 | constSizer.Add(EqSizer,0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 444 | # if item[-1] == 'f': |
---|
| 445 | # constRef = wx.CheckBox(pageDisplay,-1,label=' Refine?') |
---|
| 446 | # constRef.SetValue(item[-2]) |
---|
| 447 | # constRef.Bind(wx.EVT_CHECKBOX,OnConstRef) |
---|
| 448 | # Indx[constRef.GetId()] = item |
---|
| 449 | # constSizer.Add(constRef) |
---|
| 450 | # else: |
---|
| 451 | # constSizer.Add((5,5),0) |
---|
| 452 | return constSizer |
---|
| 453 | |
---|
| 454 | # def OnConstRef(event): |
---|
| 455 | # Obj = event.GetEventObject() |
---|
| 456 | # Indx[Obj.GetId()][-2] = Obj.GetValue() |
---|
| 457 | |
---|
| 458 | def OnConstDel(event): |
---|
| 459 | Obj = event.GetEventObject() |
---|
| 460 | Id,name = Indx[Obj.GetId()] |
---|
| 461 | del(data[name][Id]) |
---|
| 462 | OnPageChanged(None) |
---|
| 463 | |
---|
| 464 | def OnConstEdit(event): |
---|
| 465 | '''Called to edit an individual contraint by the Edit button''' |
---|
| 466 | Obj = event.GetEventObject() |
---|
| 467 | Id,name = Indx[Obj.GetId()] |
---|
| 468 | sep = '*' |
---|
| 469 | if data[name][Id][-1] == 'f': |
---|
| 470 | items = data[name][Id][:-3]+[[],] |
---|
| 471 | constType = 'New Variable' |
---|
| 472 | lbl = 'Enter value for each term in constraint; sum = new variable' |
---|
| 473 | elif data[name][Id][-1] == 'c': |
---|
| 474 | items = data[name][Id][:-3]+[ |
---|
| 475 | [data[name][Id][-3],'fixed value ='],[]] |
---|
| 476 | constType = 'Constraint' |
---|
| 477 | lbl = 'Edit value for each term in constant constraint sum' |
---|
| 478 | elif data[name][Id][-1] == 'e': |
---|
| 479 | items = data[name][Id][:-3]+[[],] |
---|
| 480 | constType = 'Equivalence' |
---|
| 481 | lbl = 'The following terms are set to be equal:' |
---|
| 482 | sep = '/' |
---|
| 483 | else: |
---|
| 484 | return |
---|
| 485 | dlg = G2frame.ConstraintDialog(G2frame.dataFrame,constType,lbl,items,sep) |
---|
| 486 | try: |
---|
| 487 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 488 | prev = data[name][Id] |
---|
| 489 | result = dlg.GetData() |
---|
| 490 | if data[name][Id][-1] == 'c': |
---|
| 491 | data[name][Id][:-3] = result[:-2] |
---|
| 492 | data[name][Id][-3] = result[-2][0] |
---|
| 493 | else: |
---|
| 494 | data[name][Id][:-3] = result[:-1] |
---|
| 495 | if not CheckChangedConstraint(): |
---|
| 496 | data[name][Id] = prev |
---|
| 497 | except: |
---|
| 498 | import traceback |
---|
| 499 | print traceback.format_exc() |
---|
| 500 | finally: |
---|
| 501 | dlg.Destroy() |
---|
| 502 | OnPageChanged(None) |
---|
| 503 | |
---|
| 504 | def UpdateHAPConstr(): |
---|
| 505 | '''Responds to press on Histogram/Phase Constraints tab, |
---|
| 506 | shows constraints in data window''' |
---|
| 507 | HAPConstr.DestroyChildren() |
---|
| 508 | HAPDisplay = wx.Panel(HAPConstr) |
---|
| 509 | HAPSizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 510 | HAPSizer.Add((5,5),0) |
---|
| 511 | HAPSizer.Add(ConstSizer('HAP',HAPDisplay)) |
---|
| 512 | HAPDisplay.SetSizer(HAPSizer,True) |
---|
| 513 | Size = HAPSizer.GetMinSize() |
---|
| 514 | Size[0] += 40 |
---|
| 515 | Size[1] = max(Size[1],250) + 20 |
---|
| 516 | HAPDisplay.SetSize(Size) |
---|
| 517 | # scroll bar not working, at least not on Mac |
---|
| 518 | HAPConstr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) |
---|
| 519 | Size[1] = min(Size[1],250) |
---|
| 520 | G2frame.dataFrame.setSizePosLeft(Size) |
---|
| 521 | |
---|
| 522 | def UpdateHistConstr(): |
---|
| 523 | '''Responds to press on Histogram Constraints tab, |
---|
| 524 | shows constraints in data window''' |
---|
| 525 | HistConstr.DestroyChildren() |
---|
| 526 | HistDisplay = wx.Panel(HistConstr) |
---|
| 527 | HistSizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 528 | HistSizer.Add((5,5),0) |
---|
| 529 | HistSizer.Add(ConstSizer('Hist',HistDisplay)) |
---|
| 530 | HistDisplay.SetSizer(HistSizer,True) |
---|
| 531 | Size = HistSizer.GetMinSize() |
---|
| 532 | Size[0] += 40 |
---|
| 533 | Size[1] = max(Size[1],250) + 20 |
---|
| 534 | HistDisplay.SetSize(Size) |
---|
| 535 | HistConstr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) |
---|
| 536 | Size[1] = min(Size[1],250) |
---|
| 537 | G2frame.dataFrame.setSizePosLeft(Size) |
---|
| 538 | |
---|
| 539 | def UpdatePhaseConstr(): |
---|
| 540 | '''Responds to press on Phase Constraint tab, |
---|
| 541 | shows constraints in data window''' |
---|
| 542 | PhaseConstr.DestroyChildren() |
---|
| 543 | PhaseDisplay = wx.Panel(PhaseConstr) |
---|
| 544 | PhaseSizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 545 | PhaseSizer.Add((5,5),0) |
---|
| 546 | PhaseSizer.Add(ConstSizer('Phase',PhaseDisplay)) |
---|
| 547 | PhaseDisplay.SetSizer(PhaseSizer,True) |
---|
| 548 | Size = PhaseSizer.GetMinSize() |
---|
| 549 | Size[0] += 40 |
---|
| 550 | Size[1] = max(Size[1],250) + 20 |
---|
| 551 | PhaseDisplay.SetSize(Size) |
---|
| 552 | PhaseConstr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) |
---|
| 553 | Size[1] = min(Size[1],250) |
---|
| 554 | G2frame.dataFrame.setSizePosLeft(Size) |
---|
| 555 | |
---|
| 556 | def OnPageChanged(event): |
---|
| 557 | if event: #page change event! |
---|
| 558 | page = event.GetSelection() |
---|
| 559 | else: |
---|
| 560 | page = G2frame.dataDisplay.GetSelection() |
---|
| 561 | oldPage = G2frame.dataDisplay.ChangeSelection(page) |
---|
| 562 | text = G2frame.dataDisplay.GetPageText(page) |
---|
| 563 | if text == 'Histogram/Phase constraints': |
---|
| 564 | G2frame.Page = [page,'hap'] |
---|
| 565 | UpdateHAPConstr() |
---|
| 566 | elif text == 'Histogram constraints': |
---|
| 567 | G2frame.Page = [page,'hst'] |
---|
| 568 | UpdateHistConstr() |
---|
| 569 | elif text == 'Phase constraints': |
---|
| 570 | G2frame.Page = [page,'phs'] |
---|
| 571 | UpdatePhaseConstr() |
---|
| 572 | |
---|
| 573 | def SetStatusLine(text): |
---|
| 574 | Status.SetStatusText(text) |
---|
| 575 | |
---|
| 576 | plegend,hlegend,phlegend = GetPHlegends(Phases,Histograms) |
---|
| 577 | scope = {'hst':['Histogram contraints:',hlegend,histList,'Hist',UpdateHistConstr], |
---|
| 578 | 'hap':['Histogram * Phase contraints:',phlegend,hapList,'HAP',UpdateHAPConstr], |
---|
| 579 | 'phs':['Phase contraints:',plegend,phaseList,'Phase',UpdatePhaseConstr]} |
---|
| 580 | if G2frame.dataDisplay: |
---|
| 581 | G2frame.dataDisplay.Destroy() |
---|
| 582 | G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.ConstraintMenu) |
---|
| 583 | G2frame.dataFrame.SetLabel('Constraints') |
---|
| 584 | if not G2frame.dataFrame.GetStatusBar(): |
---|
| 585 | Status = G2frame.dataFrame.CreateStatusBar() |
---|
| 586 | SetStatusLine('') |
---|
| 587 | |
---|
| 588 | G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.ConstraintMenu) |
---|
| 589 | G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddConstraint, id=G2gd.wxID_CONSTRAINTADD) |
---|
| 590 | G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddFunction, id=G2gd.wxID_FUNCTADD) |
---|
| 591 | G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddEquivalence, id=G2gd.wxID_EQUIVADD) |
---|
| 592 | G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddHold, id=G2gd.wxID_HOLDADD) |
---|
| 593 | G2frame.dataDisplay = G2gd.GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize()) |
---|
| 594 | |
---|
| 595 | PhaseConstr = wx.ScrolledWindow(G2frame.dataDisplay) |
---|
| 596 | G2frame.dataDisplay.AddPage(PhaseConstr,'Phase constraints') |
---|
| 597 | HAPConstr = wx.ScrolledWindow(G2frame.dataDisplay) |
---|
| 598 | G2frame.dataDisplay.AddPage(HAPConstr,'Histogram/Phase constraints') |
---|
| 599 | HistConstr = wx.ScrolledWindow(G2frame.dataDisplay) |
---|
| 600 | G2frame.dataDisplay.AddPage(HistConstr,'Histogram constraints') |
---|
| 601 | UpdatePhaseConstr() |
---|
| 602 | |
---|
| 603 | G2frame.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged) |
---|
| 604 | # validate all the constrants -- should not see any errors here normally |
---|
| 605 | allcons = [] |
---|
| 606 | for key in 'Hist','HAP','Phase': |
---|
| 607 | allcons += data[key] |
---|
| 608 | if not len(allcons): return |
---|
| 609 | G2mv.InitVars() |
---|
| 610 | constDictList,fixedList,ignored = G2str.ProcessConstraints(allcons) |
---|
| 611 | errmsg, warnmsg = G2mv.CheckConstraints('',constDictList,fixedList) |
---|
| 612 | if errmsg: |
---|
| 613 | G2frame.ErrorDialog('Constraint Error','Error in constraints:\n'+errmsg, |
---|
| 614 | parent=G2frame.dataFrame) |
---|
| 615 | elif warnmsg: |
---|
| 616 | print 'Unexpected contraint warning:\n',warnmsg |
---|
[823] | 617 | |
---|
| 618 | ################################################################################ |
---|
| 619 | #### Rigid bodies |
---|
| 620 | ################################################################################ |
---|
| 621 | |
---|
| 622 | def UpdateRigidBodies(G2frame,data): |
---|
| 623 | '''Called when Rigid bodies tree item is selected. |
---|
| 624 | Displays the rigid bodies in the data window |
---|
| 625 | ''' |
---|
| 626 | if not data: |
---|
[859] | 627 | data.update({'Vector':{'AtInfo':{}},'Residue':{'AtInfo':{}}}) #empty dict - fill it |
---|
[831] | 628 | |
---|
[850] | 629 | global resList |
---|
[831] | 630 | Indx = {} |
---|
[850] | 631 | resList = [] |
---|
[860] | 632 | plotDefaults = {'oldxy':[0.,0.],'Quaternion':[0.,0.,0.,1.],'cameraPos':30.,'viewDir':[0,0,1],} |
---|
[823] | 633 | |
---|
| 634 | def OnPageChanged(event): |
---|
[850] | 635 | global resList |
---|
| 636 | resList = [] |
---|
[823] | 637 | if event: #page change event! |
---|
| 638 | page = event.GetSelection() |
---|
| 639 | else: |
---|
| 640 | page = G2frame.dataDisplay.GetSelection() |
---|
| 641 | oldPage = G2frame.dataDisplay.ChangeSelection(page) |
---|
| 642 | text = G2frame.dataDisplay.GetPageText(page) |
---|
| 643 | if text == 'Vector rigid bodies': |
---|
[840] | 644 | G2frame.dataFrame.RigidBodyMenu.Remove(0) #NB: wx.MenuBar.Replace gives error |
---|
| 645 | G2frame.dataFrame.RigidBodyMenu.Insert(0,G2frame.dataFrame.VectorRBEdit,title='Edit') |
---|
[823] | 646 | G2frame.Page = [page,'vrb'] |
---|
| 647 | UpdateVectorRB() |
---|
| 648 | elif text == 'Residue rigid bodies': |
---|
[840] | 649 | G2frame.dataFrame.RigidBodyMenu.Remove(0) |
---|
| 650 | G2frame.dataFrame.RigidBodyMenu.Insert(0,G2frame.dataFrame.ResidueRBMenu,title='Edit') |
---|
[823] | 651 | G2frame.Page = [page,'rrb'] |
---|
| 652 | UpdateResidueRB() |
---|
| 653 | elif text == 'Z-matrix rigid bodies': |
---|
[840] | 654 | G2frame.dataFrame.RigidBodyMenu.Remove(0) |
---|
| 655 | G2frame.dataFrame.RigidBodyMenu.Insert(0,G2frame.dataFrame.ZMatrixRBMenu,title='Edit') |
---|
[823] | 656 | G2frame.Page = [page,'zrb'] |
---|
| 657 | UpdateZMatrixRB() |
---|
[831] | 658 | |
---|
[835] | 659 | def getMacroFile(macName): |
---|
| 660 | defDir = os.path.join(os.path.split(__file__)[0],'GSASIImacros') |
---|
| 661 | dlg = wx.FileDialog(G2frame,message='Choose '+macName+' rigid body macro file', |
---|
| 662 | defaultDir=defDir,defaultFile="",wildcard="GSAS-II macro file (*.mac)|*.mac", |
---|
| 663 | style=wx.OPEN | wx.CHANGE_DIR) |
---|
| 664 | try: |
---|
| 665 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 666 | macfile = dlg.GetPath() |
---|
| 667 | macro = open(macfile,'Ur') |
---|
| 668 | head = macro.readline() |
---|
| 669 | if macName not in head: |
---|
| 670 | print head |
---|
| 671 | print '**** ERROR - wrong restraint macro file selected, try again ****' |
---|
| 672 | macro = [] |
---|
| 673 | else: # cancel was pressed |
---|
[837] | 674 | macro = [] |
---|
[835] | 675 | finally: |
---|
| 676 | dlg.Destroy() |
---|
| 677 | return macro #advanced past 1st line |
---|
| 678 | |
---|
[837] | 679 | def getTextFile(): |
---|
| 680 | defDir = os.path.join(os.path.split(__file__)[0],'GSASIImacros') |
---|
[851] | 681 | dlg = wx.FileDialog(G2frame,'Choose rigid body text file', '.', '', |
---|
| 682 | "GSAS-II text file (*.txt)|*.txt|XYZ file (*.xyz)|*.xyz|" |
---|
| 683 | "Sybyl mol2 file (*.mol2)|*.mol2|PDB file (*.pdb;*.ent)|*.pdb;*.ent", |
---|
| 684 | wx.OPEN | wx.CHANGE_DIR) |
---|
[837] | 685 | try: |
---|
| 686 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 687 | txtfile = dlg.GetPath() |
---|
[851] | 688 | ext = os.path.splitext(txtfile)[1] |
---|
[837] | 689 | text = open(txtfile,'Ur') |
---|
| 690 | else: # cancel was pressed |
---|
[851] | 691 | ext = '' |
---|
[837] | 692 | text = [] |
---|
| 693 | finally: |
---|
| 694 | dlg.Destroy() |
---|
[851] | 695 | if 'ent' in ext: |
---|
| 696 | ext = '.pdb' |
---|
| 697 | return text,ext.lower() |
---|
[837] | 698 | |
---|
[831] | 699 | def OnAddRigidBody(event): |
---|
| 700 | page = G2frame.dataDisplay.GetSelection() |
---|
| 701 | if 'Vector' in G2frame.dataDisplay.GetPageText(page): |
---|
| 702 | AddVectorRB() |
---|
| 703 | elif 'Residue' in G2frame.dataDisplay.GetPageText(page): |
---|
| 704 | AddResidueRB() |
---|
| 705 | |
---|
[837] | 706 | def OnImportRigidBody(event): |
---|
| 707 | page = G2frame.dataDisplay.GetSelection() |
---|
| 708 | if 'Vector' in G2frame.dataDisplay.GetPageText(page): |
---|
| 709 | pass |
---|
| 710 | elif 'Residue' in G2frame.dataDisplay.GetPageText(page): |
---|
| 711 | ImportResidueRB() |
---|
[850] | 712 | |
---|
[831] | 713 | def AddVectorRB(): |
---|
[835] | 714 | AtInfo = data['Vector']['AtInfo'] |
---|
[831] | 715 | dlg = MultiIntegerDialog(G2frame.dataDisplay,'New Rigid Body',['No. atoms','No. translations'],[1,1]) |
---|
| 716 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 717 | nAtoms,nTrans = dlg.GetValues() |
---|
| 718 | vectorRB = data['Vector'] |
---|
| 719 | rbId = ran.randint(0,sys.maxint) |
---|
| 720 | vecMag = [1.0 for i in range(nTrans)] |
---|
| 721 | vecRef = [False for i in range(nTrans)] |
---|
| 722 | vecVal = [np.zeros((nAtoms,3)) for j in range(nTrans)] |
---|
| 723 | rbTypes = ['C' for i in range(nAtoms)] |
---|
| 724 | Info = G2elem.GetAtomInfo('C') |
---|
[835] | 725 | AtInfo['C'] = [Info['Drad'],Info['Color']] |
---|
[851] | 726 | data['Vector'][rbId] = {'RBname':'UNKRB','VectMag':vecMag,'rbXYZ':np.zeros((nAtoms,3)), |
---|
[859] | 727 | 'rbRef':[0,1,2,False],'VectRef':vecRef,'rbTypes':rbTypes,'rbVect':vecVal,'useCount':0} |
---|
[831] | 728 | dlg.Destroy() |
---|
| 729 | UpdateVectorRB() |
---|
| 730 | |
---|
| 731 | def AddResidueRB(): |
---|
[835] | 732 | AtInfo = data['Residue']['AtInfo'] |
---|
| 733 | macro = getMacroFile('rigid body') |
---|
| 734 | if not macro: |
---|
| 735 | return |
---|
| 736 | macStr = macro.readline() |
---|
| 737 | while macStr: |
---|
| 738 | items = macStr.split() |
---|
| 739 | if 'I' == items[0]: |
---|
| 740 | rbId = ran.randint(0,sys.maxint) |
---|
| 741 | rbName = items[1] |
---|
| 742 | rbTypes = [] |
---|
| 743 | rbXYZ = [] |
---|
| 744 | rbSeq = [] |
---|
| 745 | atNames = [] |
---|
| 746 | nAtms,nSeq,nOrig,mRef,nRef = [int(items[i]) for i in [2,3,4,5,6]] |
---|
| 747 | for iAtm in range(nAtms): |
---|
| 748 | macStr = macro.readline().split() |
---|
| 749 | atName = macStr[0] |
---|
[836] | 750 | atType = macStr[1] |
---|
[835] | 751 | atNames.append(atName) |
---|
[836] | 752 | rbXYZ.append([float(macStr[i]) for i in [2,3,4]]) |
---|
| 753 | rbTypes.append(atType) |
---|
| 754 | if atType not in AtInfo: |
---|
| 755 | Info = G2elem.GetAtomInfo(atType) |
---|
| 756 | AtInfo[atType] = [Info['Drad'],Info['Color']] |
---|
[835] | 757 | rbXYZ = np.array(rbXYZ)-np.array(rbXYZ[nOrig-1]) |
---|
| 758 | for iSeq in range(nSeq): |
---|
| 759 | macStr = macro.readline().split() |
---|
| 760 | mSeq = int(macStr[0]) |
---|
| 761 | for jSeq in range(mSeq): |
---|
| 762 | macStr = macro.readline().split() |
---|
| 763 | iBeg = int(macStr[0])-1 |
---|
| 764 | iFin = int(macStr[1])-1 |
---|
[836] | 765 | angle = 0.0 |
---|
[835] | 766 | nMove = int(macStr[2]) |
---|
[836] | 767 | iMove = [int(macStr[i])-1 for i in range(3,nMove+3)] |
---|
[840] | 768 | rbSeq.append([iBeg,iFin,angle,iMove]) |
---|
[835] | 769 | data['Residue'][rbId] = {'RBname':rbName,'rbXYZ':rbXYZ,'rbTypes':rbTypes, |
---|
[852] | 770 | 'atNames':atNames,'rbRef':[nOrig-1,mRef-1,nRef-1,True],'rbSeq':rbSeq, |
---|
[849] | 771 | 'SelSeq':[0,0],'useCount':0} |
---|
[837] | 772 | print 'Rigid body '+rbName+' added' |
---|
[835] | 773 | macStr = macro.readline() |
---|
| 774 | macro.close() |
---|
[836] | 775 | UpdateResidueRB() |
---|
[831] | 776 | |
---|
[837] | 777 | def ImportResidueRB(): |
---|
| 778 | AtInfo = data['Residue']['AtInfo'] |
---|
[851] | 779 | text,ext = getTextFile() |
---|
[837] | 780 | if not text: |
---|
| 781 | return |
---|
| 782 | rbId = ran.randint(0,sys.maxint) |
---|
| 783 | rbTypes = [] |
---|
| 784 | rbXYZ = [] |
---|
| 785 | rbSeq = [] |
---|
| 786 | atNames = [] |
---|
| 787 | txtStr = text.readline() |
---|
[851] | 788 | if 'xyz' in ext: |
---|
| 789 | txtStr = text.readline() |
---|
| 790 | txtStr = text.readline() |
---|
| 791 | elif 'mol2' in ext: |
---|
| 792 | while 'ATOM' not in txtStr: |
---|
| 793 | txtStr = text.readline() |
---|
| 794 | txtStr = text.readline() |
---|
| 795 | elif 'pdb' in ext: |
---|
| 796 | while 'ATOM' not in txtStr[:6] and 'HETATM' not in txtStr[:6]: |
---|
| 797 | txtStr = text.readline() |
---|
| 798 | print txtStr |
---|
[837] | 799 | items = txtStr.split() |
---|
| 800 | while len(items): |
---|
[851] | 801 | if 'txt' in ext: |
---|
| 802 | atName = items[0] |
---|
| 803 | atType = items[1] |
---|
| 804 | rbXYZ.append([float(items[i]) for i in [2,3,4]]) |
---|
| 805 | elif 'xyz' in ext: |
---|
| 806 | atType = items[0] |
---|
| 807 | rbXYZ.append([float(items[i]) for i in [1,2,3]]) |
---|
| 808 | atName = atType+str(len(rbXYZ)) |
---|
| 809 | elif 'mol2' in ext: |
---|
| 810 | atType = items[1] |
---|
| 811 | atName = items[1]+items[0] |
---|
| 812 | rbXYZ.append([float(items[i]) for i in [2,3,4]]) |
---|
| 813 | elif 'pdb' in ext: |
---|
| 814 | atType = items[-1] |
---|
| 815 | atName = items[2] |
---|
| 816 | xyz = txtStr[30:55].split() |
---|
| 817 | rbXYZ.append([float(x) for x in xyz]) |
---|
[837] | 818 | atNames.append(atName) |
---|
| 819 | rbTypes.append(atType) |
---|
| 820 | if atType not in AtInfo: |
---|
| 821 | Info = G2elem.GetAtomInfo(atType) |
---|
| 822 | AtInfo[atType] = [Info['Drad'],Info['Color']] |
---|
| 823 | txtStr = text.readline() |
---|
[851] | 824 | if 'mol2' in ext and 'BOND' in txtStr: |
---|
| 825 | break |
---|
| 826 | if 'pdb' in ext and ('ATOM' not in txtStr[:6] and 'HETATM' not in txtStr[:6]): |
---|
| 827 | break |
---|
[837] | 828 | items = txtStr.split() |
---|
| 829 | rbXYZ = np.array(rbXYZ)-np.array(rbXYZ[0]) |
---|
| 830 | data['Residue'][rbId] = {'RBname':'UNKRB','rbXYZ':rbXYZ,'rbTypes':rbTypes, |
---|
[852] | 831 | 'atNames':atNames,'rbRef':[0,1,2,False],'rbSeq':[],'SelSeq':[0,0],'useCount':0} |
---|
[837] | 832 | print 'Rigid body UNKRB added' |
---|
| 833 | text.close() |
---|
| 834 | UpdateResidueRB() |
---|
| 835 | |
---|
[840] | 836 | def FindNeighbors(Orig,XYZ,atTypes,atNames,AtInfo): |
---|
| 837 | Radii = [] |
---|
| 838 | for Atype in atTypes: |
---|
| 839 | Radii.append(AtInfo[Atype][0]) |
---|
| 840 | Radii = np.array(Radii) |
---|
| 841 | Neigh = [] |
---|
| 842 | Dx = XYZ-XYZ[Orig] |
---|
| 843 | dist = np.sqrt(np.sum(Dx**2,axis=1)) |
---|
| 844 | sumR = Radii[Orig]+Radii |
---|
| 845 | IndB = ma.nonzero(ma.masked_greater(dist-0.85*sumR,0.)) |
---|
| 846 | for j in IndB[0]: |
---|
| 847 | if j != Orig: |
---|
| 848 | Neigh.append(atNames[j]) |
---|
| 849 | return Neigh |
---|
| 850 | |
---|
| 851 | def FindAllNeighbors(XYZ,atTypes,atNames,AtInfo): |
---|
| 852 | NeighDict = {} |
---|
| 853 | for iat,xyz in enumerate(atNames): |
---|
| 854 | NeighDict[atNames[iat]] = FindNeighbors(iat,XYZ,atTypes,atNames,AtInfo) |
---|
| 855 | return NeighDict |
---|
| 856 | |
---|
| 857 | def FindRiding(Orig,Pivot,NeighDict): |
---|
| 858 | riding = [Orig,Pivot] |
---|
| 859 | iAdd = 1 |
---|
| 860 | new = True |
---|
| 861 | while new: |
---|
| 862 | newAtms = NeighDict[riding[iAdd]] |
---|
| 863 | for At in newAtms: |
---|
| 864 | new = False |
---|
| 865 | if At not in riding: |
---|
| 866 | riding.append(At) |
---|
| 867 | new = True |
---|
| 868 | iAdd += 1 |
---|
| 869 | if iAdd < len(riding): |
---|
| 870 | new = True |
---|
| 871 | return riding[2:] |
---|
| 872 | |
---|
| 873 | def OnDefineTorsSeq(event): |
---|
| 874 | rbKeys = data['Residue'].keys() |
---|
| 875 | rbKeys.remove('AtInfo') |
---|
| 876 | rbNames = [data['Residue'][k]['RBname'] for k in rbKeys] |
---|
| 877 | rbIds = dict(zip(rbNames,rbKeys)) |
---|
| 878 | rbNames.sort() |
---|
| 879 | rbId = 0 |
---|
| 880 | if len(rbNames) > 1: |
---|
| 881 | dlg = wx.SingleChoiceDialog(G2frame,'Select rigid body for torsion sequence','Torsion sequence',rbNames) |
---|
| 882 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 883 | sel = dlg.GetSelection() |
---|
| 884 | rbId = rbIds[rbNames[sel]] |
---|
| 885 | rbData = data['Residue'][rbId] |
---|
| 886 | dlg.Destroy() |
---|
| 887 | else: |
---|
| 888 | rbId = rbIds[rbNames[0]] |
---|
| 889 | rbData = data['Residue'][rbId] |
---|
| 890 | if not len(rbData): |
---|
| 891 | return |
---|
| 892 | atNames = rbData['atNames'] |
---|
| 893 | AtInfo = data['Residue']['AtInfo'] |
---|
| 894 | atTypes = rbData['rbTypes'] |
---|
| 895 | XYZ = rbData['rbXYZ'] |
---|
| 896 | neighDict = FindAllNeighbors(XYZ,atTypes,atNames,AtInfo) |
---|
| 897 | TargList = [] |
---|
| 898 | dlg = wx.SingleChoiceDialog(G2frame,'Select origin atom for torsion sequence','Origin atom',rbData['atNames']) |
---|
| 899 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 900 | Orig = dlg.GetSelection() |
---|
| 901 | xyz = XYZ[Orig] |
---|
| 902 | TargList = neighDict[atNames[Orig]] |
---|
| 903 | dlg.Destroy() |
---|
| 904 | if not len(TargList): |
---|
| 905 | return |
---|
| 906 | dlg = wx.SingleChoiceDialog(G2frame,'Select pivot atom for torsion sequence','Pivot atom',TargList) |
---|
| 907 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 908 | Piv = atNames.index(TargList[dlg.GetSelection()]) |
---|
| 909 | riding = FindRiding(atNames[Orig],atNames[Piv],neighDict) |
---|
| 910 | Riding = [] |
---|
| 911 | for atm in riding: |
---|
| 912 | Riding.append(atNames.index(atm)) |
---|
| 913 | rbData['rbSeq'].append([Orig,Piv,0.0,Riding]) |
---|
| 914 | dlg.Destroy() |
---|
[848] | 915 | UpdateResidueRB() |
---|
| 916 | |
---|
[840] | 917 | |
---|
[852] | 918 | def UpdateVectorRB(Scroll=0): |
---|
[835] | 919 | AtInfo = data['Vector']['AtInfo'] |
---|
[852] | 920 | refChoice = {} |
---|
[831] | 921 | SetStatusLine(' You may use e.g. "sind(60)", "cos(60)", "c60" or "s60" for a vector entry') |
---|
| 922 | def rbNameSizer(rbId,rbData): |
---|
| 923 | |
---|
| 924 | def OnRBName(event): |
---|
| 925 | Obj = event.GetEventObject() |
---|
| 926 | rbId = Indx[Obj.GetId()] |
---|
| 927 | rbData['RBname'] = Obj.GetValue() |
---|
| 928 | |
---|
| 929 | def OnDelRB(event): |
---|
| 930 | Obj = event.GetEventObject() |
---|
| 931 | rbId = Indx[Obj.GetId()] |
---|
| 932 | del data['Vector'][rbId] |
---|
| 933 | wx.CallAfter(UpdateVectorRB) |
---|
| 934 | |
---|
| 935 | def OnPlotRB(event): |
---|
| 936 | Obj = event.GetEventObject() |
---|
| 937 | rbId = Indx[Obj.GetId()] |
---|
| 938 | Obj.SetValue(False) |
---|
[835] | 939 | G2plt.PlotRigidBody(G2frame,'Vector',AtInfo,rbData,plotDefaults) |
---|
[831] | 940 | |
---|
| 941 | nameSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 942 | nameSizer.Add(wx.StaticText(VectorRBDisplay,-1,'Rigid body name: '), |
---|
| 943 | 0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 944 | RBname = wx.TextCtrl(VectorRBDisplay,-1,rbData['RBname']) |
---|
| 945 | Indx[RBname.GetId()] = rbId |
---|
| 946 | RBname.Bind(wx.EVT_TEXT_ENTER,OnRBName) |
---|
| 947 | RBname.Bind(wx.EVT_KILL_FOCUS,OnRBName) |
---|
| 948 | nameSizer.Add(RBname,0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 949 | nameSizer.Add((5,0),) |
---|
| 950 | plotRB = wx.CheckBox(VectorRBDisplay,-1,'Plot?') |
---|
| 951 | Indx[plotRB.GetId()] = rbId |
---|
| 952 | plotRB.Bind(wx.EVT_CHECKBOX,OnPlotRB) |
---|
| 953 | nameSizer.Add(plotRB,0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 954 | nameSizer.Add((5,0),) |
---|
[849] | 955 | if not rbData['useCount']: |
---|
| 956 | delRB = wx.CheckBox(VectorRBDisplay,-1,'Delete?') |
---|
| 957 | Indx[delRB.GetId()] = rbId |
---|
| 958 | delRB.Bind(wx.EVT_CHECKBOX,OnDelRB) |
---|
| 959 | nameSizer.Add(delRB,0,wx.ALIGN_CENTER_VERTICAL) |
---|
[831] | 960 | return nameSizer |
---|
| 961 | |
---|
[852] | 962 | def rbRefAtmSizer(rbId,rbData): |
---|
| 963 | |
---|
| 964 | def OnRefSel(event): |
---|
| 965 | Obj = event.GetEventObject() |
---|
| 966 | iref = Indx[Obj.GetId()] |
---|
| 967 | sel = Obj.GetValue() |
---|
| 968 | rbData['rbRef'][iref] = atNames.index(sel) |
---|
[855] | 969 | FillRefChoice(rbId,rbData) |
---|
[852] | 970 | |
---|
| 971 | refAtmSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 972 | atNames = [name+str(i) for i,name in enumerate(rbData['rbTypes'])] |
---|
| 973 | rbRef = rbData.get('rbRef',[0,1,2,False]) |
---|
| 974 | rbData['rbRef'] = rbRef |
---|
| 975 | if rbData['useCount']: |
---|
| 976 | refAtmSizer.Add(wx.StaticText(VectorRBDisplay,-1, |
---|
| 977 | 'Orientation reference atoms A-B-C: %s, %s, %s'%(atNames[rbRef[0]], \ |
---|
| 978 | atNames[rbRef[1]],atNames[rbRef[2]])),0) |
---|
| 979 | else: |
---|
| 980 | refAtmSizer.Add(wx.StaticText(VectorRBDisplay,-1, |
---|
| 981 | 'Orientation reference atoms A-B-C: '),0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 982 | for i in range(3): |
---|
| 983 | choices = [atNames[j] for j in refChoice[rbId][i]] |
---|
| 984 | refSel = wx.ComboBox(VectorRBDisplay,-1,value='', |
---|
| 985 | choices=choices,style=wx.CB_READONLY|wx.CB_DROPDOWN) |
---|
| 986 | refSel.SetValue(atNames[rbRef[i]]) |
---|
| 987 | refSel.Bind(wx.EVT_COMBOBOX, OnRefSel) |
---|
| 988 | Indx[refSel.GetId()] = i |
---|
| 989 | refAtmSizer.Add(refSel,0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 990 | return refAtmSizer |
---|
| 991 | |
---|
[831] | 992 | def rbVectMag(rbId,imag,rbData): |
---|
| 993 | |
---|
| 994 | def OnRBVectorMag(event): |
---|
| 995 | Obj = event.GetEventObject() |
---|
| 996 | rbId,imag = Indx[Obj.GetId()] |
---|
| 997 | try: |
---|
| 998 | val = float(Obj.GetValue()) |
---|
| 999 | if val <= 0.: |
---|
| 1000 | raise ValueError |
---|
| 1001 | rbData['VectMag'][imag] = val |
---|
| 1002 | except ValueError: |
---|
| 1003 | pass |
---|
[859] | 1004 | Obj.SetValue('%8.4f'%(val)) |
---|
[852] | 1005 | wx.CallAfter(UpdateVectorRB,VectorRB.GetScrollPos(wx.VERTICAL)) |
---|
[835] | 1006 | G2plt.PlotRigidBody(G2frame,'Vector',AtInfo,data['Vector'][rbId],plotDefaults) |
---|
[831] | 1007 | |
---|
| 1008 | def OnRBVectorRef(event): |
---|
| 1009 | Obj = event.GetEventObject() |
---|
| 1010 | rbId,imag = Indx[Obj.GetId()] |
---|
| 1011 | rbData['VectRef'][imag] = Obj.GetValue() |
---|
| 1012 | |
---|
| 1013 | magSizer = wx.wx.BoxSizer(wx.HORIZONTAL) |
---|
| 1014 | magSizer.Add(wx.StaticText(VectorRBDisplay,-1,'Translation magnitude: '), |
---|
| 1015 | 0,wx.ALIGN_CENTER_VERTICAL) |
---|
[859] | 1016 | magValue = wx.TextCtrl(VectorRBDisplay,-1,'%8.4f'%(rbData['VectMag'][imag])) |
---|
[831] | 1017 | Indx[magValue.GetId()] = [rbId,imag] |
---|
| 1018 | magValue.Bind(wx.EVT_TEXT_ENTER,OnRBVectorMag) |
---|
| 1019 | magValue.Bind(wx.EVT_KILL_FOCUS,OnRBVectorMag) |
---|
| 1020 | magSizer.Add(magValue,0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 1021 | magSizer.Add((5,0),) |
---|
| 1022 | magref = wx.CheckBox(VectorRBDisplay,-1,label=' Refine?') |
---|
| 1023 | magref.SetValue(rbData['VectRef'][imag]) |
---|
| 1024 | magref.Bind(wx.EVT_CHECKBOX,OnRBVectorRef) |
---|
| 1025 | Indx[magref.GetId()] = [rbId,imag] |
---|
| 1026 | magSizer.Add(magref,0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 1027 | return magSizer |
---|
| 1028 | |
---|
| 1029 | def rbVectors(rbId,imag,mag,XYZ,rbData): |
---|
| 1030 | |
---|
| 1031 | def TypeSelect(event): |
---|
[859] | 1032 | Obj = event.GetEventObject() |
---|
[835] | 1033 | AtInfo = data['Vector']['AtInfo'] |
---|
[831] | 1034 | r,c = event.GetRow(),event.GetCol() |
---|
| 1035 | if vecGrid.GetColLabelValue(c) == 'Type': |
---|
| 1036 | PE = G2elemGUI.PickElement(G2frame,oneOnly=True) |
---|
| 1037 | if PE.ShowModal() == wx.ID_OK: |
---|
| 1038 | if PE.Elem != 'None': |
---|
| 1039 | El = PE.Elem.strip().lower().capitalize() |
---|
[835] | 1040 | if El not in AtInfo: |
---|
| 1041 | Info = G2elem.GetAtomInfo(El) |
---|
[842] | 1042 | AtInfo[El] = [Info['Drad'],Info['Color']] |
---|
[831] | 1043 | rbData['rbTypes'][r] = El |
---|
| 1044 | vecGrid.SetCellValue(r,c,El) |
---|
| 1045 | PE.Destroy() |
---|
[852] | 1046 | wx.CallAfter(UpdateVectorRB,VectorRB.GetScrollPos(wx.VERTICAL)) |
---|
[831] | 1047 | |
---|
| 1048 | def ChangeCell(event): |
---|
[859] | 1049 | Obj = event.GetEventObject() |
---|
[831] | 1050 | r,c = event.GetRow(),event.GetCol() |
---|
| 1051 | if r >= 0 and (0 <= c < 3): |
---|
| 1052 | try: |
---|
| 1053 | val = float(vecGrid.GetCellValue(r,c)) |
---|
| 1054 | rbData['rbVect'][imag][r][c] = val |
---|
| 1055 | except ValueError: |
---|
| 1056 | pass |
---|
[852] | 1057 | G2plt.PlotRigidBody(G2frame,'Vector',AtInfo,data['Vector'][rbId],plotDefaults) |
---|
| 1058 | wx.CallAfter(UpdateVectorRB,VectorRB.GetScrollPos(wx.VERTICAL)) |
---|
[831] | 1059 | |
---|
| 1060 | vecSizer = wx.BoxSizer() |
---|
| 1061 | Types = 3*[wg.GRID_VALUE_FLOAT+':10,5',]+[wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,5',] |
---|
| 1062 | colLabels = ['Vector x','Vector y','Vector z','Type','Cart x','Cart y','Cart z'] |
---|
| 1063 | table = [] |
---|
| 1064 | rowLabels = [] |
---|
| 1065 | for ivec,xyz in enumerate(rbData['rbVect'][imag]): |
---|
| 1066 | table.append(list(xyz)+[rbData['rbTypes'][ivec],]+list(XYZ[ivec])) |
---|
| 1067 | rowLabels.append(str(ivec)) |
---|
| 1068 | vecTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types) |
---|
| 1069 | vecGrid = G2gd.GSGrid(VectorRBDisplay) |
---|
| 1070 | vecGrid.SetTable(vecTable, True) |
---|
| 1071 | vecGrid.Bind(wg.EVT_GRID_CELL_CHANGE, ChangeCell) |
---|
[842] | 1072 | if not imag: |
---|
| 1073 | vecGrid.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, TypeSelect) |
---|
[831] | 1074 | attr = wx.grid.GridCellAttr() |
---|
[848] | 1075 | attr.SetEditor(G2gd.GridFractionEditor(vecGrid)) |
---|
[831] | 1076 | for c in range(3): |
---|
| 1077 | vecGrid.SetColAttr(c, attr) |
---|
| 1078 | for row in range(vecTable.GetNumberRows()): |
---|
[842] | 1079 | if imag: |
---|
| 1080 | vecGrid.SetCellStyle(row,3,VERY_LIGHT_GREY,True) |
---|
[831] | 1081 | for col in [4,5,6]: |
---|
| 1082 | vecGrid.SetCellStyle(row,col,VERY_LIGHT_GREY,True) |
---|
[836] | 1083 | vecGrid.SetMargins(0,0) |
---|
| 1084 | vecGrid.AutoSizeColumns(False) |
---|
[831] | 1085 | vecSizer.Add(vecGrid) |
---|
| 1086 | return vecSizer |
---|
| 1087 | |
---|
[852] | 1088 | def FillRefChoice(rbId,rbData): |
---|
| 1089 | choiceIds = [i for i in range(len(rbData['rbTypes']))] |
---|
| 1090 | |
---|
[855] | 1091 | rbRef = rbData.get('rbRef',[-1,-1,-1,False]) |
---|
[852] | 1092 | for i in range(3): |
---|
| 1093 | choiceIds.remove(rbRef[i]) |
---|
| 1094 | refChoice[rbId] = [choiceIds[:],choiceIds[:],choiceIds[:]] |
---|
| 1095 | for i in range(3): |
---|
| 1096 | refChoice[rbId][i].append(rbRef[i]) |
---|
| 1097 | refChoice[rbId][i].sort() |
---|
| 1098 | |
---|
[823] | 1099 | VectorRB.DestroyChildren() |
---|
| 1100 | VectorRBDisplay = wx.Panel(VectorRB) |
---|
| 1101 | VectorRBSizer = wx.BoxSizer(wx.VERTICAL) |
---|
[831] | 1102 | for rbId in data['Vector']: |
---|
[835] | 1103 | if rbId != 'AtInfo': |
---|
| 1104 | rbData = data['Vector'][rbId] |
---|
[852] | 1105 | FillRefChoice(rbId,rbData) |
---|
[835] | 1106 | VectorRBSizer.Add(rbNameSizer(rbId,rbData),0) |
---|
[852] | 1107 | VectorRBSizer.Add(rbRefAtmSizer(rbId,rbData),0) |
---|
[835] | 1108 | XYZ = np.array([[0.,0.,0.] for Ty in rbData['rbTypes']]) |
---|
| 1109 | for imag,mag in enumerate(rbData['VectMag']): |
---|
| 1110 | XYZ += mag*rbData['rbVect'][imag] |
---|
| 1111 | VectorRBSizer.Add(rbVectMag(rbId,imag,rbData),0) |
---|
| 1112 | VectorRBSizer.Add(rbVectors(rbId,imag,mag,XYZ,rbData),0) |
---|
[851] | 1113 | VectorRBSizer.Add((5,5),0) |
---|
| 1114 | data['Vector'][rbId]['rbXYZ'] = XYZ |
---|
[831] | 1115 | VectorRBSizer.Layout() |
---|
[823] | 1116 | VectorRBDisplay.SetSizer(VectorRBSizer,True) |
---|
| 1117 | Size = VectorRBSizer.GetMinSize() |
---|
| 1118 | Size[0] += 40 |
---|
[842] | 1119 | Size[1] = max(Size[1],450) + 20 |
---|
[823] | 1120 | VectorRBDisplay.SetSize(Size) |
---|
| 1121 | VectorRB.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) |
---|
[859] | 1122 | VectorRB.Scroll(0,Scroll) |
---|
[842] | 1123 | Size[1] = min(Size[1],450) |
---|
[823] | 1124 | G2frame.dataFrame.setSizePosLeft(Size) |
---|
| 1125 | |
---|
| 1126 | def UpdateResidueRB(): |
---|
[836] | 1127 | AtInfo = data['Residue']['AtInfo'] |
---|
[852] | 1128 | refChoice = {} |
---|
[855] | 1129 | RefObjs = [] |
---|
[836] | 1130 | |
---|
| 1131 | def rbNameSizer(rbId,rbData): |
---|
| 1132 | |
---|
| 1133 | def OnRBName(event): |
---|
| 1134 | Obj = event.GetEventObject() |
---|
| 1135 | rbId = Indx[Obj.GetId()] |
---|
| 1136 | rbData['RBname'] = Obj.GetValue() |
---|
| 1137 | |
---|
| 1138 | def OnDelRB(event): |
---|
| 1139 | Obj = event.GetEventObject() |
---|
| 1140 | rbId = Indx[Obj.GetId()] |
---|
| 1141 | del data['Residue'][rbId] |
---|
| 1142 | wx.CallAfter(UpdateResidueRB) |
---|
| 1143 | |
---|
| 1144 | def OnPlotRB(event): |
---|
| 1145 | Obj = event.GetEventObject() |
---|
| 1146 | rbId = Indx[Obj.GetId()] |
---|
| 1147 | Obj.SetValue(False) |
---|
| 1148 | G2plt.PlotRigidBody(G2frame,'Residue',AtInfo,rbData,plotDefaults) |
---|
| 1149 | |
---|
| 1150 | nameSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 1151 | nameSizer.Add(wx.StaticText(ResidueRBDisplay,-1,'Residue name: '), |
---|
| 1152 | 0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 1153 | RBname = wx.TextCtrl(ResidueRBDisplay,-1,rbData['RBname']) |
---|
| 1154 | Indx[RBname.GetId()] = rbId |
---|
| 1155 | RBname.Bind(wx.EVT_TEXT_ENTER,OnRBName) |
---|
| 1156 | RBname.Bind(wx.EVT_KILL_FOCUS,OnRBName) |
---|
| 1157 | nameSizer.Add(RBname,0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 1158 | nameSizer.Add((5,0),) |
---|
| 1159 | plotRB = wx.CheckBox(ResidueRBDisplay,-1,'Plot?') |
---|
| 1160 | Indx[plotRB.GetId()] = rbId |
---|
| 1161 | plotRB.Bind(wx.EVT_CHECKBOX,OnPlotRB) |
---|
| 1162 | nameSizer.Add(plotRB,0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 1163 | nameSizer.Add((5,0),) |
---|
[849] | 1164 | if not rbData['useCount']: |
---|
| 1165 | delRB = wx.CheckBox(ResidueRBDisplay,-1,'Delete?') |
---|
| 1166 | Indx[delRB.GetId()] = rbId |
---|
| 1167 | delRB.Bind(wx.EVT_CHECKBOX,OnDelRB) |
---|
| 1168 | nameSizer.Add(delRB,0,wx.ALIGN_CENTER_VERTICAL) |
---|
[836] | 1169 | return nameSizer |
---|
| 1170 | |
---|
[852] | 1171 | def rbResidues(rbId,rbData): |
---|
[836] | 1172 | |
---|
| 1173 | def TypeSelect(event): |
---|
| 1174 | AtInfo = data['Residue']['AtInfo'] |
---|
| 1175 | r,c = event.GetRow(),event.GetCol() |
---|
| 1176 | if vecGrid.GetColLabelValue(c) == 'Type': |
---|
| 1177 | PE = G2elemGUI.PickElement(G2frame,oneOnly=True) |
---|
| 1178 | if PE.ShowModal() == wx.ID_OK: |
---|
| 1179 | if PE.Elem != 'None': |
---|
| 1180 | El = PE.Elem.strip().lower().capitalize() |
---|
| 1181 | if El not in AtInfo: |
---|
| 1182 | Info = G2elem.GetAtomInfo(El) |
---|
| 1183 | AtInfo[El] = [Info['Drad']['Color']] |
---|
| 1184 | rbData['rbTypes'][r] = El |
---|
| 1185 | vecGrid.SetCellValue(r,c,El) |
---|
| 1186 | PE.Destroy() |
---|
| 1187 | |
---|
| 1188 | def ChangeCell(event): |
---|
| 1189 | r,c = event.GetRow(),event.GetCol() |
---|
| 1190 | if r >= 0 and (0 <= c < 3): |
---|
| 1191 | try: |
---|
| 1192 | val = float(vecGrid.GetCellValue(r,c)) |
---|
| 1193 | rbData['rbVect'][imag][r][c] = val |
---|
| 1194 | except ValueError: |
---|
| 1195 | pass |
---|
[850] | 1196 | |
---|
| 1197 | def RowSelect(event): |
---|
| 1198 | r,c = event.GetRow(),event.GetCol() |
---|
| 1199 | if c < 0: #only row clicks |
---|
| 1200 | for vecgrid in resList: |
---|
| 1201 | vecgrid.ClearSelection() |
---|
| 1202 | vecGrid.SelectRow(r,True) |
---|
[836] | 1203 | |
---|
[852] | 1204 | def OnRefSel(event): |
---|
| 1205 | Obj = event.GetEventObject() |
---|
[855] | 1206 | iref,res,jref = Indx[Obj.GetId()] |
---|
[852] | 1207 | sel = Obj.GetValue() |
---|
| 1208 | ind = atNames.index(sel) |
---|
| 1209 | rbData['rbRef'][iref] = ind |
---|
[855] | 1210 | FillRefChoice(rbId,rbData) |
---|
| 1211 | for i,ref in enumerate(RefObjs[jref]): |
---|
| 1212 | ref.SetItems([atNames[j] for j in refChoice[rbId][i]]) |
---|
| 1213 | ref.SetValue(atNames[rbData['rbRef'][i]]) |
---|
[852] | 1214 | if not iref: #origin change |
---|
| 1215 | rbXYZ = rbData['rbXYZ'] |
---|
| 1216 | rbXYZ -= rbXYZ[ind] |
---|
| 1217 | res.ClearSelection() |
---|
| 1218 | resTable = res.GetTable() |
---|
| 1219 | for r in range(res.GetNumberRows()): |
---|
| 1220 | row = resTable.GetRowValues(r) |
---|
| 1221 | row[2:4] = rbXYZ[r] |
---|
| 1222 | resTable.SetRowValues(r,row) |
---|
| 1223 | res.ForceRefresh() |
---|
| 1224 | G2plt.PlotRigidBody(G2frame,'Residue',AtInfo,rbData,plotDefaults) |
---|
| 1225 | |
---|
[836] | 1226 | Types = 2*[wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,5',] |
---|
| 1227 | colLabels = ['Name','Type','Cart x','Cart y','Cart z'] |
---|
| 1228 | table = [] |
---|
| 1229 | rowLabels = [] |
---|
| 1230 | for ivec,xyz in enumerate(rbData['rbXYZ']): |
---|
| 1231 | table.append([rbData['atNames'][ivec],]+[rbData['rbTypes'][ivec],]+list(xyz)) |
---|
| 1232 | rowLabels.append(str(ivec)) |
---|
| 1233 | vecTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types) |
---|
| 1234 | vecGrid = G2gd.GSGrid(ResidueRBDisplay) |
---|
[850] | 1235 | Indx[vecGrid.GetId()] = rbId |
---|
| 1236 | resList.append(vecGrid) |
---|
[836] | 1237 | vecGrid.SetTable(vecTable, True) |
---|
| 1238 | vecGrid.Bind(wg.EVT_GRID_CELL_CHANGE, ChangeCell) |
---|
| 1239 | vecGrid.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, TypeSelect) |
---|
[850] | 1240 | vecGrid.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect) |
---|
[836] | 1241 | attr = wx.grid.GridCellAttr() |
---|
[848] | 1242 | attr.SetEditor(G2gd.GridFractionEditor(vecGrid)) |
---|
[836] | 1243 | for c in range(3): |
---|
| 1244 | vecGrid.SetColAttr(c, attr) |
---|
| 1245 | for row in range(vecTable.GetNumberRows()): |
---|
[848] | 1246 | for col in range(5): |
---|
[836] | 1247 | vecGrid.SetCellStyle(row,col,VERY_LIGHT_GREY,True) |
---|
| 1248 | vecGrid.SetMargins(0,0) |
---|
| 1249 | vecGrid.AutoSizeColumns(False) |
---|
[852] | 1250 | vecSizer = wx.BoxSizer() |
---|
[836] | 1251 | vecSizer.Add(vecGrid) |
---|
| 1252 | |
---|
[852] | 1253 | refAtmSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 1254 | atNames = rbData['atNames'] |
---|
| 1255 | rbRef = rbData['rbRef'] |
---|
| 1256 | if rbData['rbRef'][3] or rbData['useCount']: |
---|
| 1257 | refAtmSizer.Add(wx.StaticText(ResidueRBDisplay,-1, |
---|
| 1258 | 'Orientation reference atoms A-B-C: %s, %s, %s'%(atNames[rbRef[0]], \ |
---|
| 1259 | atNames[rbRef[1]],atNames[rbRef[2]])),0) |
---|
| 1260 | else: |
---|
| 1261 | refAtmSizer.Add(wx.StaticText(ResidueRBDisplay,-1, |
---|
| 1262 | 'Orientation reference atoms A-B-C: '),0,wx.ALIGN_CENTER_VERTICAL) |
---|
[855] | 1263 | refObj = [0,0,0] |
---|
[852] | 1264 | for i in range(3): |
---|
| 1265 | choices = [atNames[j] for j in refChoice[rbId][i]] |
---|
| 1266 | refSel = wx.ComboBox(ResidueRBDisplay,-1,value='', |
---|
| 1267 | choices=choices,style=wx.CB_READONLY|wx.CB_DROPDOWN) |
---|
| 1268 | refSel.SetValue(atNames[rbRef[i]]) |
---|
| 1269 | refSel.Bind(wx.EVT_COMBOBOX, OnRefSel) |
---|
[855] | 1270 | Indx[refSel.GetId()] = [i,vecGrid,len(RefObjs)] |
---|
| 1271 | refObj[i] = refSel |
---|
[852] | 1272 | refAtmSizer.Add(refSel,0,wx.ALIGN_CENTER_VERTICAL) |
---|
[855] | 1273 | RefObjs.append(refObj) |
---|
[852] | 1274 | |
---|
| 1275 | mainSizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 1276 | mainSizer.Add(refAtmSizer) |
---|
| 1277 | mainSizer.Add(vecSizer) |
---|
| 1278 | return mainSizer |
---|
| 1279 | |
---|
[836] | 1280 | def SeqSizer(angSlide,rbId,iSeq,Seq,atNames): |
---|
| 1281 | |
---|
| 1282 | def ChangeAngle(event): |
---|
| 1283 | Obj = event.GetEventObject() |
---|
[854] | 1284 | rbId,Seq = Indx[Obj.GetId()][:2] |
---|
[840] | 1285 | val = Seq[2] |
---|
[836] | 1286 | try: |
---|
| 1287 | val = float(Obj.GetValue()) |
---|
[840] | 1288 | Seq[2] = val |
---|
[836] | 1289 | except ValueError: |
---|
| 1290 | pass |
---|
| 1291 | Obj.SetValue('%8.2f'%(val)) |
---|
| 1292 | G2plt.PlotRigidBody(G2frame,'Residue',AtInfo,data['Residue'][rbId],plotDefaults) |
---|
| 1293 | |
---|
| 1294 | def OnRadBtn(event): |
---|
| 1295 | Obj = event.GetEventObject() |
---|
[848] | 1296 | Seq,iSeq,angId = Indx[Obj.GetId()] |
---|
| 1297 | data['Residue'][rbId]['SelSeq'] = [iSeq,angId] |
---|
[840] | 1298 | angSlide.SetValue(int(100*Seq[2])) |
---|
[836] | 1299 | |
---|
| 1300 | seqSizer = wx.FlexGridSizer(0,4,2,2) |
---|
| 1301 | seqSizer.AddGrowableCol(3,0) |
---|
[840] | 1302 | iBeg,iFin,angle,iMove = Seq |
---|
| 1303 | ang = wx.TextCtrl(ResidueRBDisplay,-1,'%8.2f'%(angle),size=(50,20)) |
---|
| 1304 | if not iSeq: |
---|
| 1305 | radBt = wx.RadioButton(ResidueRBDisplay,-1,'',style=wx.RB_GROUP) |
---|
[848] | 1306 | data['Residue'][rbId]['SelSeq'] = [iSeq,ang.GetId()] |
---|
[840] | 1307 | else: |
---|
| 1308 | radBt = wx.RadioButton(ResidueRBDisplay,-1,'') |
---|
| 1309 | radBt.Bind(wx.EVT_RADIOBUTTON,OnRadBtn) |
---|
| 1310 | seqSizer.Add(radBt) |
---|
| 1311 | bond = wx.TextCtrl(ResidueRBDisplay,-1,'%s %s'%(atNames[iBeg],atNames[iFin]),size=(50,20)) |
---|
| 1312 | seqSizer.Add(bond,0,wx.ALIGN_CENTER_VERTICAL) |
---|
[848] | 1313 | Indx[radBt.GetId()] = [Seq,iSeq,ang.GetId()] |
---|
[854] | 1314 | Indx[ang.GetId()] = [rbId,Seq,ang] |
---|
[840] | 1315 | ang.Bind(wx.EVT_TEXT_ENTER,ChangeAngle) |
---|
| 1316 | ang.Bind(wx.EVT_KILL_FOCUS,ChangeAngle) |
---|
| 1317 | seqSizer.Add(ang,0,wx.ALIGN_CENTER_VERTICAL) |
---|
| 1318 | atms = '' |
---|
| 1319 | for i in iMove: |
---|
| 1320 | atms += ' %s,'%(atNames[i]) |
---|
| 1321 | moves = wx.TextCtrl(ResidueRBDisplay,-1,atms[:-1],size=(200,20)) |
---|
| 1322 | seqSizer.Add(moves,1,wx.ALIGN_CENTER_VERTICAL|wx.EXPAND|wx.RIGHT) |
---|
[836] | 1323 | return seqSizer |
---|
| 1324 | |
---|
| 1325 | def SlideSizer(): |
---|
| 1326 | |
---|
| 1327 | def OnSlider(event): |
---|
| 1328 | Obj = event.GetEventObject() |
---|
| 1329 | rbData = Indx[Obj.GetId()] |
---|
[848] | 1330 | iSeq,angId = rbData['SelSeq'] |
---|
[836] | 1331 | val = float(Obj.GetValue())/100. |
---|
[840] | 1332 | rbData['rbSeq'][iSeq][2] = val |
---|
[848] | 1333 | Indx[angId][2].SetValue('%8.2f'%(val)) |
---|
[836] | 1334 | G2plt.PlotRigidBody(G2frame,'Residue',AtInfo,rbData,plotDefaults) |
---|
| 1335 | |
---|
| 1336 | slideSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 1337 | slideSizer.Add(wx.StaticText(ResidueRBDisplay,-1,'Selected torsion angle:'),0) |
---|
[848] | 1338 | iSeq,angId = rbData['SelSeq'] |
---|
[836] | 1339 | angSlide = wx.Slider(ResidueRBDisplay,-1, |
---|
[840] | 1340 | int(100*rbData['rbSeq'][iSeq][2]),0,36000,size=(200,20), |
---|
[836] | 1341 | style=wx.SL_HORIZONTAL) |
---|
| 1342 | angSlide.Bind(wx.EVT_SLIDER, OnSlider) |
---|
| 1343 | Indx[angSlide.GetId()] = rbData |
---|
| 1344 | slideSizer.Add(angSlide,0) |
---|
[852] | 1345 | return slideSizer,angSlide |
---|
[836] | 1346 | |
---|
[852] | 1347 | def FillRefChoice(rbId,rbData): |
---|
| 1348 | choiceIds = [i for i in range(len(rbData['atNames']))] |
---|
| 1349 | for seq in rbData['rbSeq']: |
---|
| 1350 | for i in seq[3]: |
---|
[854] | 1351 | try: |
---|
| 1352 | choiceIds.remove(i) |
---|
| 1353 | except ValueError: |
---|
| 1354 | pass |
---|
[852] | 1355 | rbRef = rbData['rbRef'] |
---|
| 1356 | for i in range(3): |
---|
[854] | 1357 | try: |
---|
| 1358 | choiceIds.remove(rbRef[i]) |
---|
| 1359 | except ValueError: |
---|
| 1360 | pass |
---|
[852] | 1361 | refChoice[rbId] = [choiceIds[:],choiceIds[:],choiceIds[:]] |
---|
| 1362 | for i in range(3): |
---|
| 1363 | refChoice[rbId][i].append(rbRef[i]) |
---|
| 1364 | refChoice[rbId][i].sort() |
---|
| 1365 | |
---|
[823] | 1366 | ResidueRB.DestroyChildren() |
---|
| 1367 | ResidueRBDisplay = wx.Panel(ResidueRB) |
---|
| 1368 | ResidueRBSizer = wx.BoxSizer(wx.VERTICAL) |
---|
[836] | 1369 | rbKeys = data['Residue'].keys() |
---|
| 1370 | rbKeys.remove('AtInfo') |
---|
| 1371 | rbNames = [data['Residue'][k]['RBname'] for k in rbKeys] |
---|
| 1372 | rbIds = dict(zip(rbNames,rbKeys)) |
---|
| 1373 | rbNames.sort() |
---|
| 1374 | for name in rbNames: |
---|
| 1375 | rbId = rbIds[name] |
---|
| 1376 | rbData = data['Residue'][rbId] |
---|
[852] | 1377 | FillRefChoice(rbId,rbData) |
---|
[836] | 1378 | ResidueRBSizer.Add(rbNameSizer(rbId,rbData),0) |
---|
[852] | 1379 | ResidueRBSizer.Add(rbResidues(rbId,rbData),0) |
---|
[836] | 1380 | ResidueRBSizer.Add((5,5),0) |
---|
[837] | 1381 | if rbData['rbSeq']: |
---|
| 1382 | slideSizer,angSlide = SlideSizer() |
---|
[850] | 1383 | if len(rbData['rbSeq']): |
---|
| 1384 | ResidueRBSizer.Add(wx.StaticText(ResidueRBDisplay,-1, |
---|
| 1385 | 'Sel Bond Angle Riding atoms'), |
---|
| 1386 | 0,wx.ALIGN_CENTER_VERTICAL) |
---|
[836] | 1387 | for iSeq,Seq in enumerate(rbData['rbSeq']): |
---|
| 1388 | ResidueRBSizer.Add(SeqSizer(angSlide,rbId,iSeq,Seq,rbData['atNames'])) |
---|
[837] | 1389 | if rbData['rbSeq']: |
---|
| 1390 | ResidueRBSizer.Add(slideSizer,) |
---|
[848] | 1391 | ResidueRBSizer.Add(wx.StaticText(ResidueRBDisplay,-1,100*'-')) |
---|
| 1392 | |
---|
[836] | 1393 | ResidueRBSizer.Add((5,25),) |
---|
[831] | 1394 | ResidueRBSizer.Layout() |
---|
[823] | 1395 | ResidueRBDisplay.SetSizer(ResidueRBSizer,True) |
---|
| 1396 | Size = ResidueRBSizer.GetMinSize() |
---|
| 1397 | Size[0] += 40 |
---|
[852] | 1398 | Size[1] = max(Size[1],450) + 20 |
---|
[823] | 1399 | ResidueRBDisplay.SetSize(Size) |
---|
| 1400 | ResidueRB.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) |
---|
[840] | 1401 | Size[1] = min(600,Size[1]) |
---|
[823] | 1402 | G2frame.dataFrame.setSizePosLeft(Size) |
---|
| 1403 | |
---|
| 1404 | def SetStatusLine(text): |
---|
| 1405 | Status.SetStatusText(text) |
---|
| 1406 | |
---|
| 1407 | if G2frame.dataDisplay: |
---|
| 1408 | G2frame.dataDisplay.Destroy() |
---|
| 1409 | G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.RigidBodyMenu) |
---|
| 1410 | G2frame.dataFrame.SetLabel('Rigid bodies') |
---|
| 1411 | if not G2frame.dataFrame.GetStatusBar(): |
---|
| 1412 | Status = G2frame.dataFrame.CreateStatusBar() |
---|
| 1413 | SetStatusLine('') |
---|
| 1414 | |
---|
| 1415 | G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.RigidBodyMenu) |
---|
[831] | 1416 | G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddRigidBody, id=G2gd.wxID_RIGIDBODYADD) |
---|
[840] | 1417 | G2frame.dataFrame.Bind(wx.EVT_MENU, OnImportRigidBody, id=G2gd.wxID_RIGIDBODYIMPORT) |
---|
| 1418 | G2frame.dataFrame.Bind(wx.EVT_MENU, OnDefineTorsSeq, id=G2gd.wxID_RESIDUETORSSEQ) |
---|
[823] | 1419 | G2frame.dataDisplay = G2gd.GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize()) |
---|
[840] | 1420 | G2frame.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged) |
---|
[823] | 1421 | |
---|
| 1422 | VectorRB = wx.ScrolledWindow(G2frame.dataDisplay) |
---|
| 1423 | G2frame.dataDisplay.AddPage(VectorRB,'Vector rigid bodies') |
---|
| 1424 | ResidueRB = wx.ScrolledWindow(G2frame.dataDisplay) |
---|
| 1425 | G2frame.dataDisplay.AddPage(ResidueRB,'Residue rigid bodies') |
---|
| 1426 | UpdateVectorRB() |
---|
| 1427 | |
---|