Skip to content

Commit 055adb3

Browse files
committed
Implement penalty fxn for negative SpinRB distributions & fix issues found in penaltyDeriv.
1 parent 0fae64b commit 055adb3

5 files changed

Lines changed: 188 additions & 30 deletions

File tree

GSASII/GSASIIobj.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
restraintNames = [['Bond','Bonds'],['Angle','Angles'],['Plane','Planes'],
3434
['Chiral','Volumes'],['Torsion','Torsions'],['Rama','Ramas'],
3535
['ChemComp','Sites'],['Texture','HKLs'],['Moments','Moments'],
36-
['General','General']]
36+
['General','General'],['SpinRB','SpinRBs']]
3737
'''Names of restraint keys for the restraint dict and the location of
3838
the restraints in each dict
3939
'''

GSASII/GSASIIphsGUI.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10138,9 +10138,6 @@ def OnSliceShell(event):
1013810138
RBObj['sliceSh'] = not RBObj['sliceSh']
1013910139
G2plt.PlotStructure(G2frame,data)
1014010140

10141-
def OnNegDen(event):
10142-
RBObj['noNeg'][0] = not RBObj['noNeg'][0]
10143-
1014410141
symchoice = ['53m','m3m','-43m','6/mmm','-6m2','-3m','3m','32','-3','3','4/mmm','-42m',
1014510142
'mmm','2/m','2','m','-1','1']
1014610143
RBObj['hide'] = RBObj.get('hide',[False for i in range(len(RBObj['atType']))])
@@ -10197,18 +10194,11 @@ def OnNegDen(event):
1019710194
plotLine.Add(fadeShell,0,WACV)
1019810195
plotLine.Add(sliceShell,0,WACV)
1019910196
plotLine.Add(addShell,0,WACV)
10200-
negDen = wx.CheckBox(RigidBodies,label='Use negative density penalty for all shells? Penalty: ')
10201-
negDen.SetValue(RBObj['noNeg'][0])
10202-
negDen.Bind(wx.EVT_CHECKBOX,OnNegDen)
10203-
secLine.Add(negDen,0,WACV)
10204-
secLine.Add(G2G.ValidatedTxtCtrl(RigidBodies,RBObj['noNeg'],1,nDig=(10,4),
10205-
xmin=0.,xmax=1.,typeHint=float),0,WACV)
1020610197
sprbSizer.Add(plotLine)
1020710198
G2G.HorizontalLine(sprbSizer,RigidBodies)
1020810199
sprbSizer.Add(topLine)
1020910200
sprbSizer.Add(secLine)
1021010201
sprbSizer.Add(SHsizer())
10211-
1021210202
return sprbSizer
1021310203

1021410204
def ResrbSizer(RBObj,resIndx):

GSASII/GSASIIrestrGUI.py

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ def OnAddRestraint(event):
206206
AddChemCompRestraint(restrData['ChemComp'])
207207
elif 'Texture' in G2frame.restrBook.GetPageText(page):
208208
AddTextureRestraint(restrData['Texture'])
209+
elif 'Spin RB' in G2frame.restrBook.GetPageText(page):
210+
AddSpinRBRestraint(restrData['SpinRB'])
209211
elif 'Moments' in G2frame.restrBook.GetPageText(page):
210212
AddMomentRestraint(restrData['Moments'])
211213
elif 'General' in G2frame.restrBook.GetPageText(page):
@@ -890,6 +892,19 @@ def AddMomentRestraint(momentRestData):
890892
print ('**** ERROR - not enough atoms for a average moment restraint - try again ****')
891893
UpdateMomentRestr(momentRestData)
892894

895+
def AddSpinRBRestraint(spinRestData):
896+
SpinRB = RBModels.get('Spin',[])
897+
indx = [item['Ids'][0] for item in SpinRB]
898+
Snames = G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,ct-1)
899+
dlg = G2G.G2MultiChoiceDialog(G2frame,'Select atoms for negative spin RB restraint in '+General['Name'],
900+
'Select atoms',Snames)
901+
if dlg.ShowModal() == wx.ID_OK:
902+
sels = dlg.GetSelections()
903+
for sel in sels:
904+
minspin = [indx[sel],0.01,False,1.0] #spin atom id, esd, unit flag, unit esd
905+
if minspin not in spinRestData['SpinRBs']:
906+
spinRestData['SpinRBs'].append(minspin)
907+
UpdateSpinRBRestr(spinRestData)
893908

894909
def AddTextureRestraint(textureRestData):
895910
dlg = wx.TextEntryDialog(G2frame,'Enter h k l for pole figure restraint','Enter HKL','')
@@ -2121,6 +2136,76 @@ def OnCellChange(event):
21212136
mainSizer.Add(wx.StaticText(TextureRestr,-1,'No texture restraints for this phase'),0,)
21222137
G2phsGUI.SetPhaseWindow(TextureRestr,mainSizer,Scroll=0)
21232138

2139+
def UpdateSpinRBRestr(spinRestData):
2140+
2141+
def OnDeleteRestraint(event):
2142+
rows = GetSelectedRows(SpinRBs,'delete',G2frame)
2143+
G2frame.GetStatusBar().SetStatusText('',1)
2144+
if not rows:
2145+
G2frame.GetStatusBar().SetStatusText('First select restraints to be deleted',1)
2146+
return
2147+
rows.sort()
2148+
rows.reverse()
2149+
for row in rows:
2150+
spinRestData['SpinRBs'].remove(spinRestData['SpinRBs'][row])
2151+
wx.CallAfter(UpdateSpinRBRestr,spinRestData)
2152+
2153+
def OnCellChange(event):
2154+
r,c = event.GetRow(),event.GetCol()
2155+
try:
2156+
if c in [1,3]: #esds
2157+
new = float(spinRBTable.GetValue(r,c))
2158+
if new < -1. or new > 2.:
2159+
raise ValueError
2160+
else:
2161+
new = spinRBTable.GetValue(r,c)
2162+
spinRestData['SpinRBs'][r][c] = new
2163+
except ValueError:
2164+
pass
2165+
wx.CallAfter(UpdateSpinRBRestr,spinRestData)
2166+
2167+
try:
2168+
if SpinRBRestr.GetSizer(): SpinRBRestr.GetSizer().Clear(True)
2169+
except:
2170+
pass
2171+
mainSizer = wx.BoxSizer(wx.VERTICAL)
2172+
mainSizer.Add((5,5),0)
2173+
mainSizer.Add(WtBox(SpinRBRestr,spinRestData),0)
2174+
mainSizer.Add(wx.StaticText(SpinRBRestr,-1,
2175+
'NB: The spin RB restraints suppress negative spin RB densities for the selected atoms\n'
2176+
' "unit esd" gives a bias toward a flatter spin RB density'),0)
2177+
mainSizer.Add((5,5),0)
2178+
2179+
for i in (G2G.wxID_RESTDELETE,G2G.wxID_RESRCHANGEVAL,G2G.wxID_RESTCHANGEESD):
2180+
G2frame.dataWindow.RestraintEdit.Enable(id=i,enable=False)
2181+
if len(spinRestData['SpinRBs']):
2182+
table = []
2183+
rowLabels = []
2184+
Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_FLOAT+':10,2',
2185+
wg.GRID_VALUE_BOOL,wg.GRID_VALUE_FLOAT+':10,2']
2186+
colLabels = ['atom','neg esd','use unit?','unit esd']
2187+
for i,[atomid,esd1,ifesd2,esd2] in enumerate(spinRestData['SpinRBs']):
2188+
table.append(['%s'%G2mth.GetAtomItemsById(Atoms,AtLookUp,atomid,ct-1)[0],esd1,ifesd2,esd2])
2189+
rowLabels.append(str(i))
2190+
spinRBTable = G2G.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
2191+
SpinRBs = G2G.GSGrid(SpinRBRestr)
2192+
SpinRBs.SetTable(spinRBTable, True)
2193+
SpinRBs.AutoSizeColumns(False)
2194+
for r in range(len(spinRestData['SpinRBs'])):
2195+
SpinRBs.SetReadOnly(r,0,True)
2196+
SpinRBs.SetCellStyle(r,0,VERY_LIGHT_GREY,True)
2197+
if not spinRBTable.GetValue(r,2):
2198+
SpinRBs.SetReadOnly(r,3,True)
2199+
SpinRBs.SetCellStyle(r,3,VERY_LIGHT_GREY,True)
2200+
SpinRBs.SetCellTextColour(r,3,VERY_LIGHT_GREY)
2201+
SpinRBs.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK,OnRowSelect)
2202+
SpinRBs.Bind(wg.EVT_GRID_CELL_CHANGED, OnCellChange)
2203+
G2frame.dataWindow.RestraintEdit.Enable(id=G2G.wxID_RESTDELETE,enable=True)
2204+
G2frame.Bind(wx.EVT_MENU, OnDeleteRestraint, id=G2G.wxID_RESTDELETE)
2205+
mainSizer.Add(SpinRBs)
2206+
else:
2207+
mainSizer.Add(wx.StaticText(SpinRBRestr,-1,'No spin RB restraints for this phase'),0,)
2208+
G2phsGUI.SetPhaseWindow(SpinRBRestr,mainSizer,Scroll=0)
21242209

21252210
def UpdateGeneralRestr(generalRestData):
21262211
'''Display any generalized restraint expressions'''
@@ -2224,7 +2309,6 @@ def OnDelGenRestraint(event): #does this work??
22242309
GridSiz.Add(wx.StaticText(GeneralRestr,wx.ID_ANY,txt))
22252310
mainSizer.Add(GridSiz)
22262311
G2phsGUI.SetPhaseWindow(GeneralRestr,mainSizer,Scroll=0)
2227-
22282312

22292313
def OnPageChanged(event):
22302314
page = event.GetSelection()
@@ -2287,6 +2371,12 @@ def OnPageChanged(event):
22872371
G2frame.dataWindow.RestraintEdit.Enable(G2G.wxID_RESRCHANGEVAL,True)
22882372
textureRestData = restrData['Texture']
22892373
UpdateTextureRestr(textureRestData)
2374+
elif text == 'Spin RB':
2375+
G2gd.SetDataMenuBar(G2frame,G2frame.dataWindow.RestraintMenu)
2376+
G2frame.dataWindow.RestraintEdit.Enable(G2G.wxID_RESTRAINTADD,True)
2377+
G2frame.dataWindow.RestraintEdit.Enable(G2G.wxID_RESRCHANGEVAL,True)
2378+
spinRBRestData = restrData['SpinRB']
2379+
UpdateSpinRBRestr(spinRBRestData)
22902380
elif text == 'Moments':
22912381
G2gd.SetDataMenuBar(G2frame,G2frame.dataWindow.RestraintMenu)
22922382
G2frame.dataWindow.RestraintEdit.Enable(G2G.wxID_RESTRAINTADD,True)
@@ -2374,11 +2464,14 @@ def OnSelectPage(event):
23742464
restrData['Rama'] = {'wtFactor':1.0,'Coeff':{},'Ramas':[],'Use':True}
23752465
if 'Texture' not in restrData:
23762466
restrData['Texture'] = {'wtFactor':1.0,'HKLs':[],'Use':True}
2467+
if 'SpinRB' not in restrData:
2468+
restrData['SpinRB'] = {'wtFactor':1.0,'SpinRBs':[],'Use':True}
23772469
if 'ChemComp' not in restrData:
23782470
restrData['ChemComp'] = {'wtFactor':1.0,'Sites':[],'Use':True}
23792471
if 'General' not in restrData:
23802472
restrData['General'] = {'wtFactor':1.0,'General':[], 'Use':True}
23812473
General = phasedata['General']
2474+
RBModels = phasedata['RBModels']
23822475
if General['Type'] == 'magnetic' and 'Moments' not in restrData:
23832476
restrData['Moments'] = {'wtFactor':1.0,'Moments':[],'Use':True}
23842477
Cell = General['Cell'][1:7] #skip flag & volume
@@ -2476,6 +2569,12 @@ def OnSelectPage(event):
24762569
Pages.append(txt)
24772570

24782571
UpdateBondRestr(restrData['Bond'])
2572+
2573+
if 'Spin' in phasedata['RBModels'] and len(phasedata['RBModels']['Spin']):
2574+
txt = 'Spin RB'
2575+
SpinRBRestr = wx.ScrolledWindow(G2frame.restrBook)
2576+
G2frame.restrBook.AddPage(SpinRBRestr,txt)
2577+
Pages.append(txt)
24792578

24802579
G2frame.restrBook.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, OnPageChanged)
24812580

GSASII/GSASIIstrIO.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2147,11 +2147,13 @@ def PrintRestraints(cell,SGData,AtPtrs,Atoms,AtLookup,textureData,phaseRest,pFil
21472147
if num:
21482148
sum = np.sum(Z)
21492149
pFile.write (' %d %d %d %d %8.3f %8.3f %8d %s %8.3f\n'%(hkl[0],hkl[1],hkl[2],grid,esd1,sum,num,str(ifesd2),esd2))
2150+
elif name =='SpinRB':
2151+
continue
21502152
elif name == 'General':
21512153
pFile.write(' target sig obs expression variables \n')
21522154
for expObj,target,esd in itemRest[rest]:
21532155
val = '?'
2154-
calcobj = G2obj.ExpressionCalcObj(expObj)
2156+
#calcobj = G2obj.ExpressionCalcObj(expObj)
21552157
# need to get parmDict to evaluate the value
21562158
#calcobj.SetupCalc(parmDict)
21572159
#val = ' {:8.3g} '.format(calcobj.EvalExpression())
@@ -4330,6 +4332,7 @@ def WriteVecRBModel(RBModel,sigDict={},irb=None):
43304332

43314333
atmPattrn = re.compile("::A[xyz]:")
43324334
fmtSplit = re.compile('%([0-9]+)\\.([0-9]+)(.*)')
4335+
43334336
def fmtESD(varname,SigDict,fmtcode,ndig=None,ndec=None):
43344337
'''Format an uncertainty value as requested, but surround the
43354338
number by () if the parameter is set by an equivalence

0 commit comments

Comments
 (0)