Skip to content

Commit d318da1

Browse files
committed
Merge remote-tracking branch 'origin/master' into develop
2 parents 5d577ac + 102d031 commit d318da1

18 files changed

+768
-294
lines changed

GSASII/GSASIIconstrGUI.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from . import GSASIIlattice as G2lat
2727
from . import GSASIIdataGUI as G2gd
2828
from . import GSASIIctrlGUI as G2G
29-
from . import GSASIIfiles as G2fl
29+
from . import GSASIIfiles as G2fil
3030
from . import GSASIIplot as G2plt
3131
from . import GSASIIobj as G2obj
3232
from . import GSASIIspc as G2spc
@@ -2756,7 +2756,7 @@ def MakeVectorBody(name=''):
27562756
rd.ReInitialize()
27572757
rd.errors = ""
27582758
if not rd.ContentsValidator(filename): # Report error
2759-
G2fl.G2Print("Warning: File {} has a validation error".format(filename))
2759+
G2fil.G2Print("Warning: File {} has a validation error".format(filename))
27602760
return
27612761
if len(rd.selections) > 1:
27622762
print("File {} has {} phases. This is unexpected."
@@ -2767,7 +2767,7 @@ def MakeVectorBody(name=''):
27672767
try:
27682768
rd.Reader(filename)
27692769
except Exception as msg:
2770-
G2fl.G2Print("Warning: read of file {} failed\n{}".format(
2770+
G2fil.G2Print("Warning: read of file {} failed\n{}".format(
27712771
filename,rd.errors))
27722772
if GSASIIpath.GetConfigValue('debug'):
27732773
print(msg)
@@ -4141,14 +4141,14 @@ def _onClose(event):
41414141
subSizer2.Add((-1,-1))
41424142
subSizer1.Add(wx.StaticText(panel1,wx.ID_ANY,str(lbl)))
41434143
try:
4144-
value = G2fl.FormatSigFigs(delocc)
4144+
value = G2fil.FormatSigFigs(delocc)
41454145
except TypeError:
41464146
value = str(delocc)
41474147
subSizer1.Add(wx.StaticText(panel1,wx.ID_ANY,value),0,wx.ALIGN_RIGHT)
41484148
#subSizer.Add((10,-1))
41494149
subSizer2.Add(wx.StaticText(panel2,wx.ID_ANY,str(var)))
41504150
try:
4151-
value = G2fl.FormatSigFigs(val/norm)
4151+
value = G2fil.FormatSigFigs(val/norm)
41524152
if 'varyList' in covdata:
41534153
if str(G2mode) in covdata['varyList']:
41544154
sig = covdata['sig'][covdata['varyList'].index(str(G2mode))]

GSASII/GSASIIctrlGUI.py

Lines changed: 152 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9518,7 +9518,144 @@ def gitSelectBranch(event):
95189518
G2fil.openInNewTerm(project)
95199519
print ('exiting GSAS-II')
95209520
sys.exit()
9521+
9522+
def gitSwitch2DevBranch(event):
9523+
'''This is "patch" code to switch from the master branch
9524+
to the develop (eventually to be renamed main) branch.
9525+
Complication here is that the GSASII.py file gets renamed
9526+
to G2.py so "shortcuts" need to be re-created to reference that.
9527+
9528+
This is not yet "plumbed" into the current code, but it has been
9529+
tested with Windows and Mac. At some point this will be made part of the
9530+
update process in the master branch, but this routine is not needed in
9531+
the develop (or eventially main) branch.
9532+
'''
9533+
G2frame = wx.App.GetMainTopWindow()
9534+
gitInst = GSASIIpath.HowIsG2Installed()
9535+
if not gitInst.startswith('github-rev'):
9536+
G2MessageBox(G2frame,
9537+
'Unable to switch branches unless GSAS-II has been installed from GitHub; installed as: '+gitInst,
9538+
'Not a git install')
9539+
return
9540+
if not os.path.exists(GSASIIpath.path2GSAS2):
9541+
print(f'Warning: Directory {GSASIIpath.path2GSAS2} not found')
9542+
return
9543+
if os.path.exists(os.path.join(GSASIIpath.path2GSAS2,'..','.git')):
9544+
path2repo = os.path.join(path2GSAS2,'..') # expected location
9545+
elif os.path.exists(os.path.join(GSASIIpath.path2GSAS2,'.git')):
9546+
path2repo = GSASIIpath.path2GSAS2
9547+
else:
9548+
print(f'Warning: Repository {path2GSAS2} not found')
9549+
return
9550+
try:
9551+
g2repo = GSASIIpath.openGitRepo(path2repo)
9552+
except Exception as msg:
9553+
print(f'Warning: Failed to open repository. Error: {msg}')
9554+
return
9555+
if g2repo.is_dirty() or g2repo.index.diff("HEAD"): # changed or staged files
9556+
G2MessageBox(G2frame,
9557+
'You have local changes. They must be reset, committed or stashed before switching branches',
9558+
'Local changes')
9559+
return
9560+
if g2repo.head.is_detached:
9561+
G2MessageBox(G2frame,
9562+
'You have a old previous version loaded; you must be on a branch head to switching branches',
9563+
'Detached head')
9564+
return
9565+
if g2repo.active_branch.name != "master":
9566+
G2MessageBox(G2frame,
9567+
f'You are on the {g2repo.active_branch.name} branch. This can only be run from master.',
9568+
'Not on master')
9569+
return
9570+
9571+
# make sure that branches are accessible & get updates
9572+
print('getting updates...',end='')
9573+
g2repo.git.remote('set-branches','origin','*')
9574+
print('..',end='')
9575+
g2repo.git.fetch()
9576+
print('.done')
9577+
branchlist = [i.strip() for i in g2repo.git.branch('-r').split('\n') if '->' not in i]
9578+
choices = [i for i in [os.path.split(i)[1] for i in branchlist] if i != g2repo.active_branch.name]
9579+
b = "develop"
9580+
if b not in choices:
9581+
G2MessageBox(G2frame,
9582+
f'You are on the {g2repo.active_branch.name!r} branch, but branch {b!r} was not found.',
9583+
f'No {b} branch')
9584+
return
9585+
msg = f'''Confirm switching from git branch {g2repo.active_branch.name!r} to {b!r}.
9586+
9587+
If confirmed here, GSAS-II will restart.
9588+
9589+
Do you want to save your project before restarting?
9590+
Select "Yes" to save, "No" to skip the save, or "Cancel"
9591+
to discontinue the restart process.
9592+
9593+
If "Yes", GSAS-II will reopen the project after the update.
9594+
9595+
The switch will be made unless Cancel is pressed.'''
9596+
dlg = wx.MessageDialog(G2frame, msg, 'Confirm branch switch?',
9597+
wx.YES_NO|wx.CANCEL|wx.YES_DEFAULT|wx.CENTRE|wx.ICON_QUESTION)
9598+
ans = dlg.ShowModal()
9599+
dlg.Destroy()
9600+
if ans == wx.ID_CANCEL:
9601+
return
9602+
elif ans == wx.ID_YES:
9603+
ans = G2frame.OnFileSave(None)
9604+
if not ans: return
9605+
project = os.path.abspath(G2frame.GSASprojectfile)
9606+
print(f"Restarting GSAS-II with project file {project!r}")
9607+
else:
9608+
print("Restarting GSAS-II without a project file ")
9609+
project = None
9610+
# I hope that it is possible to do a checkout on Windows
9611+
# (source files are not locked). If this is not the case
9612+
# then another approach will be needed, where a .bat file is used
9613+
# or GSASIIpath is used, as is the case for updates
9614+
a = g2repo.git.checkout(b)
9615+
if 'Your branch is behind' in a:
9616+
print('updating local copy of branch')
9617+
print(g2repo.git.pull())
9618+
# post-install stuff (following gitstrap.py)
9619+
print(f'Byte-compiling all .py files in {GSASIIpath.path2GSAS2!r}... ',end='')
9620+
import compileall
9621+
compileall.compile_dir(GSASIIpath.path2GSAS2,quiet=True)
9622+
print('done')
9623+
#
9624+
print('start system-specific install')
9625+
for k,s in {'win':"makeBat.py", 'darwin':"makeMacApp.py",
9626+
'linux':"makeLinux.py"}.items():
9627+
if sys.platform.startswith(k):
9628+
script = os.path.join(GSASIIpath.path2GSAS2,'install',s)
9629+
if not os.path.exists(script):
9630+
print(f'Platform-specific script {script!r} not found')
9631+
script = ''
9632+
break
9633+
else:
9634+
print(f'Unknown platform {sys.platform}')
9635+
# on a Mac, make an applescript
9636+
if script and sys.platform.startswith('darwin'):
9637+
print(f'running {script}')
9638+
import subprocess
9639+
out = subprocess.run([sys.executable,script],cwd=GSASIIpath.path2GSAS2)
9640+
# On windows make a batch file with hard-coded paths to Python and GSAS-II
9641+
elif script and sys.platform.startswith('win'):
9642+
script = os.path.normpath(os.path.join(GSASIIpath.path2GSAS2,'install',s))
9643+
print(f'running {script!r}')
9644+
import subprocess
9645+
out = subprocess.run([sys.executable,script],cwd=GSASIIpath.path2GSAS2)
9646+
# On linux, make a desktop icon with hard-coded paths to Python and GSAS-II
9647+
elif script:
9648+
sys.argv = [script]
9649+
print(f'running {sys.argv[0]}')
9650+
with open(sys.argv[0]) as source_file:
9651+
exec(source_file.read())
9652+
9653+
print('system-specific install done')
95219654

9655+
G2fil.openInNewTerm(project)
9656+
print ('exiting GSAS-II')
9657+
sys.exit()
9658+
95229659
#===========================================================================
95239660
# Importer GUI stuff
95249661
def ImportMsg(parent,msgs):
@@ -9577,25 +9714,34 @@ def SelectPkgInstall(event):
95779714
if sel is None: return
95789715
if not any(sel): return
95799716
pkgs = [choices[i][0] for i,f in enumerate(sel) if f]
9717+
wx.BeginBusyCursor()
9718+
pdlg = wx.ProgressDialog('Updating','Installing Python packages; this can take a while',
9719+
parent=G2frame)
95809720
if GSASIIpath.condaTest():
95819721
patch_condarc()
95829722
if not GSASIIpath.condaTest(True):
95839723
GSASIIpath.addCondaPkg()
95849724
err = GSASIIpath.condaInstall(pkgs)
95859725
if err:
95869726
print(f'Error from conda: {err}')
9727+
wx.EndBusyCursor()
9728+
pdlg.Destroy()
95879729
return
95889730
else:
95899731
err = GSASIIpath.pipInstall(pkgs)
95909732
if err:
95919733
print(f'Error from pip: {err}')
9734+
wx.EndBusyCursor()
9735+
pdlg.Destroy()
95929736
return
9593-
msg = '''You must restart GSAS-II to access the importer(s)
9594-
requiring the installed package(s).
9595-
9596-
Select "Yes" to save, "No" to skip the save, or "Cancel"
9597-
to discontinue the restart process and continue GSAS-II
9598-
without the importer(s).
9737+
wx.EndBusyCursor()
9738+
pdlg.Destroy()
9739+
msg = '''You must restart GSAS-II to access the importer(s)
9740+
requiring the package(s) just installed.
9741+
9742+
Select "Yes" to save and restart, "No" to restart without
9743+
the save, or "Cancel" to discontinue the restart process
9744+
and continue use of GSAS-II without the importer(s).
95999745
96009746
If "Yes", GSAS-II will reopen the project after the update.
96019747
'''

GSASII/GSASIIdataGUI.py

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3006,10 +3006,7 @@ def __init__(self, parent):
30063006
GSASIIpath.GetConfigValue('Starting_directory'))
30073007
arg = sys.argv
30083008
if len(arg) > 1 and arg[1]:
3009-
try:
3010-
self.GSASprojectfile = os.path.splitext(arg[1])[0]+u'.gpx'
3011-
except:
3012-
self.GSASprojectfile = os.path.splitext(arg[1])[0]+'.gpx'
3009+
self.GSASprojectfile = os.path.splitext(arg[1])[0]+'.gpx'
30133010
self.dirname = os.path.abspath(os.path.dirname(arg[1]))
30143011
if self.dirname:
30153012
self.GSASprojectfile = os.path.split(self.GSASprojectfile)[1]
@@ -5473,6 +5470,7 @@ def OnRefine(self,event):
54735470
try:
54745471
if dlg2.ShowModal() == wx.ID_OK:
54755472
self.reloadFromGPX(rtext,Rvals)
5473+
G2IO.LogCellChanges(self)
54765474
if refPlotUpdate:
54775475
refPlotUpdate({},restore=True)
54785476
refPlotUpdate = None
@@ -6964,7 +6962,7 @@ def _makemenu(): # routine to create menu when first used
69646962
# IMG / Masks
69656963
G2G.Define_wxId('wxID_MASKCOPY', 'wxID_MASKSAVE', 'wxID_MASKLOAD', 'wxID_NEWMASKSPOT', 'wxID_NEWMASKARC', 'wxID_NEWMASKRING',
69666964
'wxID_NEWMASKFRAME', 'wxID_NEWMASKPOLY','wxID_NEWMASKXLINE','wxID_NEWMASKYLINE','wxID_MASKLOADNOT',
6967-
'wxID_FINDSPOTS', 'wxID_AUTOFINDSPOTS', 'wxID_DELETESPOTS',)
6965+
'wxID_FINDSPOTS', 'wxID_AUTOFINDSPOTS', 'wxID_DELETESPOTS','wxID_MASKCOPYSELECTED')
69686966
def _makemenu(): # routine to create menu when first used
69696967
self.MaskMenu = wx.MenuBar()
69706968
self.PrefillDataMenu(self.MaskMenu)
@@ -6973,6 +6971,7 @@ def _makemenu(): # routine to create menu when first used
69736971
submenu = wx.Menu()
69746972
self.MaskEdit.AppendSubMenu( submenu,'Create new','')
69756973
self.MaskEdit.Append(G2G.wxID_MASKCOPY,'Copy mask','Copy mask to other images')
6974+
self.MaskEdit.Append(G2G.wxID_MASKCOPYSELECTED,'Copy Selected','Copy selected masks to other images')
69766975
self.MaskEdit.Append(G2G.wxID_MASKSAVE,'Save mask','Save mask to file')
69776976
self.MaskEdit.Append(G2G.wxID_MASKLOADNOT,'Load mask','Load mask from file; ignoring threshold')
69786977
self.MaskEdit.Append(G2G.wxID_MASKLOAD,'Load mask w/threshold','Load mask from file keeping the threshold value')
@@ -7408,6 +7407,11 @@ def OnAddNotebook(event):
74087407
data.append(f'[CM] {dlg.GetValue().strip()}')
74097408
dlg.Destroy()
74107409
wx.CallAfter(UpdateNotebook,G2frame,data)
7410+
def OnSaveNotebook(event):
7411+
filename = os.path.splitext(G2frame.GSASprojectfile)[0]+'_notebook.txt'
7412+
filename = os.path.join(G2frame.dirname,filename)
7413+
open(filename,'w').write(textBox.GetText())
7414+
print(f'Notebook contents written into {filename}')
74117415
def onPlotNotebook():
74127416
'Locate R values from the Notebook and plot them'
74137417
NBinfo['plotLbl']
@@ -7439,11 +7443,11 @@ def onPlotNotebook():
74397443
filterLbls = ['all',
74407444
'Timestamps','Refinement results','Variables',
74417445
'Comments','Charge flip','Fourier','Peak fit',
7442-
'Constraints','Restraints','Rigid Bodies']
7446+
'Constraints','Restraints','Rigid Bodies','Cell params']
74437447
filterPrefix = ['',
74447448
'TS', 'REF','VARS',
74457449
'CM', 'CF', 'FM', 'PF',
7446-
'CNSTR','RSTR','RB']
7450+
'CNSTR','RSTR','RB','CEL']
74477451
cId = GetGPXtreeItemId(G2frame,G2frame.root, 'Controls')
74487452
if cId:
74497453
controls = G2frame.GPXtree.GetItemPyData(cId)
@@ -7469,7 +7473,7 @@ def onPlotNotebook():
74697473
botSizer.Clear(True)
74707474
parent = G2frame.dataWindow.bottomPanel
74717475
botSizer.Add((20,-1))
7472-
controls['Notebook']['order'] = controls['Notebook'].get('order',False)
7476+
controls['Notebook']['order'] = controls['Notebook'].get('order',True)
74737477
botSizer.Add(wx.StaticText(parent,wx.ID_ANY,' order: '),0,WACV)
74747478
botSizer.Add(G2G.EnumSelector(parent,controls['Notebook'],
74757479
'order',['oldest-1st','newest-1st'],[False,True],
@@ -7489,9 +7493,12 @@ def onPlotNotebook():
74897493
botSizer.Add((20,-1))
74907494
botSizer.Add(fBtn,0,WACV)
74917495
botSizer.Add((20,-1),1,wx.EXPAND,1)
7496+
Btn = wx.Button(parent,label='Save')
7497+
botSizer.Add(Btn,0,WACV)
7498+
Btn.Bind(wx.EVT_BUTTON,OnSaveNotebook)
74927499
import wx.stc as stc
7493-
text = stc.StyledTextCtrl(G2frame.dataWindow,wx.ID_ANY)
7494-
text.SetScrollWidthTracking(True) # does not seem to do anything
7500+
textBox = stc.StyledTextCtrl(G2frame.dataWindow,wx.ID_ANY)
7501+
textBox.SetScrollWidthTracking(True) # does not seem to do anything
74957502
if controls['Notebook']['order']:
74967503
# reverse entries in blocks, so that lines stay after their timestamp
74977504
order = []
@@ -7525,22 +7532,22 @@ def onPlotNotebook():
75257532
show = True
75267533
if show:
75277534
if prefix == 'TS':
7528-
if not first: text.AppendText("\n")
7529-
text.AppendText(line.strip())
7535+
if not first: textBox.AppendText("\n")
7536+
textBox.AppendText(line.strip())
75307537
elif prefix and (controls['Notebook']['filterSel'][0]
75317538
or controls['Notebook']['filterSel'][1]):
75327539
# indent all but timestamps
75337540
for l in line.strip().split('\n'):
7534-
if not first: text.AppendText("\n")
7535-
text.AppendText(' '+l.strip())
7541+
if not first: textBox.AppendText("\n")
7542+
textBox.AppendText(' '+l.strip())
75367543
first = False
75377544
else:
7538-
if not first: text.AppendText("\n")
7539-
text.AppendText(line.strip())
7545+
if not first: textBox.AppendText("\n")
7546+
textBox.AppendText(line.strip())
75407547
first = False
75417548
bigSizer = wx.BoxSizer(wx.VERTICAL)
7542-
bigSizer.Add(text,1,wx.EXPAND)
7543-
text.SetReadOnly(True)
7549+
bigSizer.Add(textBox,1,wx.EXPAND)
7550+
textBox.SetReadOnly(True)
75447551
bigSizer.Layout()
75457552
bigSizer.FitInside(G2frame.dataWindow)
75467553
G2frame.dataWindow.SetSizer(bigSizer)

GSASII/GSASIIimage.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import math
99
import time
1010
import copy
11-
import sys
1211
import numpy as np
1312
import numpy.linalg as nl
1413
import numpy.ma as ma
@@ -1472,7 +1471,6 @@ def MakeUseMask(data,masks,blkSize=128):
14721471
return useMask
14731472

14741473
def MakeGainMap(image,Ix,Iy,data,blkSize=128):
1475-
import scipy.ndimage.filters as sdif
14761474
Iy /= npcosd(Ix[:-1]) #undo parallax
14771475
Iy *= (1000./data['distance'])**2 #undo r^2 effect
14781476
Iy /= np.array(G2pwd.Polarization(data['PolaVal'][0],Ix[:-1],0.)[0]) #undo polarization
@@ -1493,8 +1491,7 @@ def MakeGainMap(image,Ix,Iy,data,blkSize=128):
14931491
TA = Make2ThetaAzimuthMap(data,(iBeg,iFin),(jBeg,jFin)) #2-theta & azimuth arrays & create position mask
14941492
Ipix = IyInt(TA[0])
14951493
GainMap[iBeg:iFin,jBeg:jFin] = image[iBeg:iFin,jBeg:jFin]/(Ipix*TA[3])
1496-
GainMap = np.nan_to_num(GainMap,1.0)
1497-
GainMap = sdif.gaussian_filter(GainMap,3.,order=0)
1494+
GainMap /= np.nanmedian(GainMap)
14981495
return 1./GainMap
14991496

15001497
def AzimuthIntegrate(image,data,masks,ringId,blkSize=1024):

0 commit comments

Comments
 (0)