Changeset 2516


Ignore:
Timestamp:
Nov 6, 2016 10:18:52 PM (5 years ago)
Author:
toby
Message:

revise import to not assume Bank 1 with multibank instparm files; deal with unicode problem in CIF files; improve atoms use of selection from menu; add Pawley menu variable selection (plenty more to do)

Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASII.py

    r2509 r2516  
    10071007        Found = False
    10081008        il = 0
     1009        if bank is None: # no bank was specified in the input file, is more than one present in file?
     1010            banklist = set([])
     1011            for S in instLines:
     1012                if S[0] == '#' and 'Bank' in S:
     1013                    banklist.add(int(S.split(':')[0].split()[1]))
     1014            if len(banklist) > 1: # yes, the user must make a selection
     1015                choices = [str(i) for i in banklist]
     1016                bank = int(G2G.ItemSelector(choices,self.G2frame,multiple=False))
     1017            else:
     1018                bank = 1
     1019            rd.powderentry[2] = bank
    10091020        while il < len(instLines):
    10101021            S = instLines[il]
     
    10981109        if ibanks == 1: # there is only one bank here, return it
    10991110            rd.instbank = 1
     1111            rd.powderentry[2] = 1
    11001112            return Iparm
    1101         if 'PNT' in hType:
    1102             rd.instbank = bank
    1103         elif ibanks != databanks:
     1113#        if 'PNT' in hType:  # not sure what this is about
     1114#            rd.instbank = bank
     1115#        elif ibanks != databanks or bank is None:
     1116        if (ibanks != databanks and databanks != 1) or bank is None:
    11041117            # number of banks in data and prm file not not agree, need a
    11051118            # choice from a human here
     
    11071120            for i in range(1,1+ibanks):
    11081121                choices.append('Bank '+str(i))
    1109             bank = rd.BlockSelector(
     1122            bank = 1 + rd.BlockSelector(
    11101123                choices, self,
    11111124                title='Select an instrument parameter bank for '+
     
    11391152
    11401153        :returns: a list of two dicts, the first containing instrument parameters
    1141           and the second used for TOf lookup tables for profile coeff.
     1154          and the second used for TOF lookup tables for profile coeff.
    11421155
    11431156        '''
  • trunk/GSASIIctrls.py

    r2513 r2516  
    305305      the :attr:`OnLeave` function. Defaults to ``{}``
    306306
     307    :param bool ASCIIonly: if set as True will remove unicode characters from
     308      strings
     309
    307310    :param (other): other optional keyword parameters for the
    308311      wx.TextCtrl widget such as size or style may be specified.
     
    311314    def __init__(self,parent,loc,key,nDig=None,notBlank=True,min=None,max=None,
    312315                 OKcontrol=None,OnLeave=None,typeHint=None,
    313                  CIFinput=False, OnLeaveArgs={}, **kw):
     316                 CIFinput=False, OnLeaveArgs={}, ASCIIonly=False, **kw):
    314317        # save passed values needed outside __init__
    315318        self.result = loc
     
    321324        self.CIFinput = CIFinput
    322325        self.notBlank = notBlank
     326        self.ASCIIonly = ASCIIonly
    323327        self.type = str
    324328        # initialization
     
    429433                wx.TextCtrl.SetValue(self,str(G2py3.FormatSigFigs(val)).rstrip('0'))
    430434        else:
    431             if show: wx.TextCtrl.SetValue(self,str(val))
     435            if self.ASCIIonly:
     436                s = ''
     437                for c in val:
     438                    if ord(c) < 128: s += c
     439                if val != s:
     440                    val = s
     441                    show = True
     442            if show:
     443                try:
     444                    wx.TextCtrl.SetValue(self,str(val))
     445                except:
     446                    wx.TextCtrl.SetValue(self,val)
    432447            self.ShowStringValidity() # test if valid input
    433448            return
     
    10011016def CallScrolledMultiEditor(parent,dictlst,elemlst,prelbl=[],postlbl=[],
    10021017                 title='Edit items',header='',size=(300,250),
    1003                              CopyButton=False, **kw):
     1018                             CopyButton=False, ASCIIonly=False, **kw):
    10041019    '''Shell routine to call a ScrolledMultiEditor dialog. See
    10051020    :class:`ScrolledMultiEditor` for parameter definitions.
     
    10111026    dlg = ScrolledMultiEditor(parent,dictlst,elemlst,prelbl,postlbl,
    10121027                              title,header,size,
    1013                               CopyButton, **kw)
     1028                              CopyButton, ASCIIonly, **kw)
    10141029    if dlg.ShowModal() == wx.ID_OK:
    10151030        dlg.Destroy()
     
    10591074    :param bool CopyButton: if True adds a small button that copies the
    10601075      value for the current row to all fields below (default is False)
     1076     
     1077    :param bool ASCIIonly: if set as True will remove unicode characters from
     1078      strings
    10611079     
    10621080    :param list minvals: optional list of minimum values for validation
     
    11011119    def __init__(self,parent,dictlst,elemlst,prelbl=[],postlbl=[],
    11021120                 title='Edit items',header='',size=(300,250),
    1103                  CopyButton=False,
     1121                 CopyButton=False, ASCIIonly=False,
    11041122                 minvals=[],maxvals=[],sizevals=[],
    11051123                 checkdictlst=[], checkelemlst=[], checklabel=""):
     
    11611179                subSizer.Add(but)
    11621180            # create the validated TextCrtl, store it and add it to the sizer
    1163             ctrl = ValidatedTxtCtrl(panel,d,k,OKcontrol=self.ControlOKButton,
     1181            ctrl = ValidatedTxtCtrl(panel,d,k,OKcontrol=self.ControlOKButton,ASCIIonly=ASCIIonly,
    11641182                                    **kargs)
    11651183            self.ValidatedControlsList.append(ctrl)
  • trunk/GSASIIgrid.py

    r2512 r2516  
    6565] = [wx.NewId() for item in range(10)]
    6666
    67 [ wxID_ATOMSEDITADD, wxID_ATOMSEDITINSERT, wxID_ATOMSEDITDELETE, wxID_ATOMSREFINE,
     67[ wxID_ATOMSEDITADD, wxID_ATOMSEDITINSERT, wxID_ATOMSEDITDELETE,
    6868    wxID_ATOMSMODIFY, wxID_ATOMSTRANSFORM, wxID_ATOMSVIEWADD, wxID_ATOMVIEWINSERT,
    6969    wxID_RELOADDRAWATOMS,wxID_ATOMSDISAGL,wxID_ATOMMOVE,wxID_MAKEMOLECULE,
    7070    wxID_ASSIGNATMS2RB,wxID_ATOMSPDISAGL, wxID_ISODISP,wxID_ADDHATOM,wxID_UPDATEHATOM,
    7171    wxID_WAVEVARY,wxID_ATOMSROTATE, wxID_ATOMSDENSITY,
    72 ] = [wx.NewId() for item in range(20)]
     72    wxID_ATOMSSETALL, wxID_ATOMSSETSEL,
     73] = [wx.NewId() for item in range(21)]
    7374
    7475[ wxID_DRAWATOMSTYLE, wxID_DRAWATOMLABEL, wxID_DRAWATOMCOLOR, wxID_DRAWATOMRESETCOLOR,
     
    9091] = [wx.NewId() for item in range(4)]
    9192
    92 [ wxID_PAWLEYLOAD, wxID_PAWLEYESTIMATE, wxID_PAWLEYUPDATE,
    93 ] = [wx.NewId() for item in range(3)]
     93[ wxID_PAWLEYLOAD, wxID_PAWLEYESTIMATE, wxID_PAWLEYUPDATE, wxID_PAWLEYSELALL, wxID_PAWLEYSELNONE,
     94  wxID_PAWLEYSELTOGGLE,
     95] = [wx.NewId() for item in range(6)]
    9496
    9597[ wxID_IMCALIBRATE,wxID_IMRECALIBRATE,wxID_IMINTEGRATE, wxID_IMCLEARCALIB,wxID_IMRECALIBALL, 
     
    22292231        self.AtomsMenu.Append(menu=self.AtomEdit, title='Edit Atoms')
    22302232        self.AtomsMenu.Append(menu=self.AtomCompute, title='Compute')
     2233        submenu = wx.Menu()
     2234        self.AtomEdit.AppendMenu(wx.ID_ANY, 'Atoms selection...', submenu,
     2235            help='Set/Act on selected atoms')
     2236        submenu.Append(wxID_ATOMSSETSEL,
     2237            help='Set refinement flags for selected atoms',
     2238            kind=wx.ITEM_NORMAL,
     2239            text='Refine selected')
     2240        submenu.Append(id=wxID_ATOMSMODIFY, kind=wx.ITEM_NORMAL,text='Modify parameters',
     2241            help='Modify parameters values for all selected atoms')
     2242        submenu.Append(id=wxID_ATOMSEDITINSERT, kind=wx.ITEM_NORMAL,text='Insert atom',
     2243            help='Inserts an H atom before all selected atoms')
     2244        submenu.Append(id=wxID_ADDHATOM, kind=wx.ITEM_NORMAL,text='Calc H atoms',
     2245            help='Insert H atoms in expected bonding positions for selected atoms')
     2246        submenu.Append(id=wxID_ATOMSEDITDELETE, kind=wx.ITEM_NORMAL,text='Delete atom',
     2247            help='Delete selected atoms')
     2248        submenu.Append(id=wxID_ATOMSTRANSFORM, kind=wx.ITEM_NORMAL,text='Transform atoms',
     2249            help='Symmetry transform selected atoms')
     2250#        self.AtomEdit.Append(id=wxID_ATOMSROTATE, kind=wx.ITEM_NORMAL,text='Rotate atoms',
     2251#            help='Select atoms to rotate first')
     2252        submenu.Append(wxID_ATOMSSETALL,
     2253            help='Set refinement flags for all atoms',
     2254            kind=wx.ITEM_NORMAL,
     2255            text='Select All')
     2256       
    22312257        self.AtomEdit.Append(id=wxID_ATOMSEDITADD, kind=wx.ITEM_NORMAL,text='Append atom',
    22322258            help='Appended as an H atom')
    22332259        self.AtomEdit.Append(id=wxID_ATOMSVIEWADD, kind=wx.ITEM_NORMAL,text='Append view point',
    22342260            help='Appended as an H atom')
    2235         self.AtomEdit.Append(id=wxID_ATOMSEDITINSERT, kind=wx.ITEM_NORMAL,text='Insert atom',
    2236             help='Select atom row to insert before; inserted as an H atom')
    22372261        self.AtomEdit.Append(id=wxID_ATOMVIEWINSERT, kind=wx.ITEM_NORMAL,text='Insert view point',
    22382262            help='Select atom row to insert before; inserted as an H atom')
    2239         self.AtomEdit.Append(id=wxID_ADDHATOM, kind=wx.ITEM_NORMAL,text='Insert H atoms',
    2240             help='Insert H atoms in standard positions bonded to selected atoms')
    22412263        self.AtomEdit.Append(id=wxID_UPDATEHATOM, kind=wx.ITEM_NORMAL,text='Update H atoms',
    22422264            help='Update H atoms in standard positions')
    2243         self.AtomEdit.Append(id=wxID_ATOMMOVE, kind=wx.ITEM_NORMAL,text='Move atom to view point',
    2244             help='Select single atom to move')
    2245         self.AtomEdit.Append(id=wxID_ATOMSEDITDELETE, kind=wx.ITEM_NORMAL,text='Delete atom',
    2246             help='Select atoms to delete first')
    2247         self.AtomEdit.Append(id=wxID_ATOMSREFINE, kind=wx.ITEM_NORMAL,text='Set atom refinement flags',
    2248             help='Select atoms to refine first')
    2249         self.AtomEdit.Append(id=wxID_ATOMSMODIFY, kind=wx.ITEM_NORMAL,text='Modify atom parameters',
    2250             help='Select atoms to modify first')
    2251         self.AtomEdit.Append(id=wxID_ATOMSTRANSFORM, kind=wx.ITEM_NORMAL,text='Transform atoms',
    2252             help='Select atoms to transform first')
    2253 #        self.AtomEdit.Append(id=wxID_ATOMSROTATE, kind=wx.ITEM_NORMAL,text='Rotate atoms',
    2254 #            help='Select atoms to rotate first')
     2265        self.AtomEdit.Append(id=wxID_ATOMMOVE, kind=wx.ITEM_NORMAL,text='Move selected atom to view point',
     2266            help='Select a single atom to be moved to view point in plot')
    22552267        self.AtomEdit.Append(id=wxID_MAKEMOLECULE, kind=wx.ITEM_NORMAL,text='Assemble molecule',
    2256             help='Assemble molecule from scatterd atom positions')
     2268            help='Select a single atom to assemble as a molecule from scattered atom positions')
    22572269        self.AtomEdit.Append(id=wxID_RELOADDRAWATOMS, kind=wx.ITEM_NORMAL,text='Reload draw atoms',
    22582270            help='Reload atom drawing list')
     
    24122424            help='Estimate initial Pawley intensities')
    24132425        self.PawleyEdit.Append(id=wxID_PAWLEYUPDATE, kind=wx.ITEM_NORMAL,text='Pawley update',
    2414             help='Update negative Pawley intensities with -0.5*Fobs and turn off refinemnt')
     2426            help='Update negative Pawley intensities with -0.5*Fobs and turn off refinement')
     2427        self.PawleyEdit.Append(id=wxID_PAWLEYSELALL, kind=wx.ITEM_NORMAL,text='Select all',
     2428            help='Select all reflections to be refined')
     2429        self.PawleyEdit.Append(id=wxID_PAWLEYSELNONE, kind=wx.ITEM_NORMAL,text='Select none',
     2430            help='Set flag for all reflections for no refinement')
     2431        self.PawleyEdit.Append(id=wxID_PAWLEYSELTOGGLE, kind=wx.ITEM_NORMAL,text='Toggle Selection',
     2432            help='Toggle Selection flag for all reflections to opposite setting')
    24152433        self.PostfillDataMenu()
    24162434           
  • trunk/GSASIIphsGUI.py

    r2512 r2516  
     1        #indx = Atoms.GetSelectedRows()
    12# -*- coding: utf-8 -*-
    23#GSASII - phase data display routines
     
    856857                except ValueError:
    857858                    pass
    858                 pawlNegWt.SetValue("%.4f"%(generalData['Pawley neg wt']))          #reset in case of error               
     859                pawlNegWt.SetValue("%.4f"%(generalData['Pawley neg wt']))          #reset in case of error
    859860
    860861            pawleySizer = wx.BoxSizer(wx.HORIZONTAL)
     
    18141815                    rbAtmDict[id] += 'U'           
    18151816        # exclList will be 'x' or 'xu' if TLS used in RB
    1816         Items = [G2gd.wxID_ATOMSEDITINSERT,G2gd.wxID_ATOMSEDITDELETE,G2gd.wxID_ATOMSREFINE,
     1817        Items = [G2gd.wxID_ATOMSEDITINSERT,G2gd.wxID_ATOMSEDITDELETE,
    18171818            G2gd.wxID_ATOMSMODIFY,G2gd.wxID_ATOMSTRANSFORM,G2gd.wxID_MAKEMOLECULE,
    18181819            G2gd.wxID_ATOMVIEWINSERT,G2gd.wxID_ATOMMOVE,G2gd.wxID_ADDHATOM]
     
    19191920
    19201921    def OnAtomInsert(event):
    1921         indx = Atoms.GetSelectedRows()
    1922         if indx:
    1923             AtomInsert(indx[0],0,0,0)
    1924             FillAtomsGrid(Atoms)
    1925             event.StopPropagation()
    1926             data['Drawing']['Atoms'] = []
    1927             UpdateDrawAtoms()
    1928             G2plt.PlotStructure(G2frame,data)
     1922        '''Inserts a new atom into list immediately before every selected atom
     1923        '''
     1924        indx = GetSelectedAtoms()
     1925        for a in reversed(sorted(indx)):
     1926            AtomInsert(a,0,0,0)
     1927        event.StopPropagation()
     1928        FillAtomsGrid(Atoms)
     1929        data['Drawing']['Atoms'] = []
     1930        UpdateDrawAtoms()
     1931        G2plt.PlotStructure(G2frame,data)
    19291932       
    19301933    def OnAtomViewInsert(event):
     
    19371940       
    19381941    def OnHydAtomAdd(event):
    1939         indx = Atoms.GetSelectedRows()
    1940         if indx:
    1941             DisAglCtls = {}
    1942             generalData = data['General']
    1943             if 'DisAglCtls' in generalData:
    1944                 DisAglCtls = generalData['DisAglCtls']
    1945                 if 'H' not in DisAglCtls['AtomTypes']:
    1946                     DisAglCtls['AtomTypes'].append('H')
    1947                     DisAglCtls['AngleRadii'].append(0.5)
    1948                     DisAglCtls['BondRadii'].append(0.5)
    1949             dlg = G2gd.DisAglDialog(G2frame,DisAglCtls,generalData,Reset=False)
    1950             if dlg.ShowModal() == wx.ID_OK:
    1951                 DisAglCtls = dlg.GetData()
    1952             else:
    1953                 dlg.Destroy()
    1954                 return
     1942        '''Adds H atoms to fill out coordination sphere for selected atoms
     1943        '''
     1944        indx = GetSelectedAtoms()
     1945        if not indx: return
     1946        DisAglCtls = {}
     1947        generalData = data['General']
     1948        if 'DisAglCtls' in generalData:
     1949            DisAglCtls = generalData['DisAglCtls']
     1950            if 'H' not in DisAglCtls['AtomTypes']:
     1951                DisAglCtls['AtomTypes'].append('H')
     1952                DisAglCtls['AngleRadii'].append(0.5)
     1953                DisAglCtls['BondRadii'].append(0.5)
     1954        dlg = G2gd.DisAglDialog(G2frame,DisAglCtls,generalData,Reset=False)
     1955        if dlg.ShowModal() == wx.ID_OK:
     1956            DisAglCtls = dlg.GetData()
     1957        else:
    19551958            dlg.Destroy()
    1956             generalData['DisAglCtls'] = DisAglCtls
    1957             cx,ct,cs,cia = generalData['AtomPtrs']
    1958             atomData = data['Atoms']
    1959             AtNames = [atom[ct-1] for atom in atomData]
    1960             AtLookUp = G2mth.FillAtomLookUp(atomData,cia+8)
    1961             Neigh = []
    1962             AddHydIds = []
    1963             for ind in indx:
    1964                 atom = atomData[ind]
    1965                 if atom[ct] not in ['C','N','O']:
    1966                     continue
    1967                 neigh = [atom[ct-1],G2mth.FindNeighbors(data,atom[ct-1],AtNames),0]
    1968                 if len(neigh[1][0]) > 3 or (atom[ct] == 'O' and len(neigh[1][0]) > 1):
    1969                     continue
    1970                 nH = 1      #for O atom
    1971                 if atom[ct] in ['C','N']:
    1972                     nH = 4-len(neigh[1][0])
    1973                 bonds = {item[0]:item[1:] for item in neigh[1][0]}
    1974                 nextName = ''
    1975                 if len(bonds) == 1:
    1976                     nextName = bonds.keys()[0]
    1977                 for bond in bonds:
    1978                     if 'C' in atom[ct]:
    1979                         if 'C' in bond and bonds[bond][0] < 1.42:
    1980                             nH -= 1
    1981                             break
    1982                         elif 'O' in bond and bonds[bond][0] < 1.3:
    1983                             nH -= 1
    1984                             break
    1985                     elif 'O' in atom[ct] and 'C' in bonds and bonds[bond][0] < 1.3:
     1959            return
     1960        dlg.Destroy()
     1961        generalData['DisAglCtls'] = DisAglCtls
     1962        cx,ct,cs,cia = generalData['AtomPtrs']
     1963        atomData = data['Atoms']
     1964        AtNames = [atom[ct-1] for atom in atomData]
     1965        AtLookUp = G2mth.FillAtomLookUp(atomData,cia+8)
     1966        Neigh = []
     1967        AddHydIds = []
     1968        for ind in indx:
     1969            atom = atomData[ind]
     1970            if atom[ct] not in ['C','N','O']:
     1971                continue
     1972            neigh = [atom[ct-1],G2mth.FindNeighbors(data,atom[ct-1],AtNames),0]
     1973            if len(neigh[1][0]) > 3 or (atom[ct] == 'O' and len(neigh[1][0]) > 1):
     1974                continue
     1975            nH = 1      #for O atom
     1976            if atom[ct] in ['C','N']:
     1977                nH = 4-len(neigh[1][0])
     1978            bonds = {item[0]:item[1:] for item in neigh[1][0]}
     1979            nextName = ''
     1980            if len(bonds) == 1:
     1981                nextName = bonds.keys()[0]
     1982            for bond in bonds:
     1983                if 'C' in atom[ct]:
     1984                    if 'C' in bond and bonds[bond][0] < 1.42:
    19861985                        nH -= 1
    19871986                        break
    1988                 nextneigh = []
    1989                 if nextName:
    1990                     nextneigh = G2mth.FindNeighbors(data,nextName,AtNames,notName=neigh[0])
    1991                     if nextneigh[0]:
    1992                         neigh[1][1].append(nextneigh[1][1][0])
    1993                 neigh[2] = max(0,nH)  #set expected no. H's needed
    1994                 if len(neigh[1][0]):
    1995                     AddHydIds.append(neigh[1][1])
    1996                     Neigh.append(neigh)
    1997             if Neigh:
    1998                 letters = ['A','B','C']
    1999                 HydIds = {}
    2000                 mapError = False
    2001                 dlg = G2gd.AddHatomDialog(G2frame,Neigh,data)
    2002                 if dlg.ShowModal() == wx.ID_OK:
    2003                     Nat = len(atomData)
    2004                     Neigh = dlg.GetData()
    2005                     mapData = generalData['Map']
    2006                     for ineigh,neigh in enumerate(Neigh):
    2007                         AddHydIds[ineigh].append(neigh[2])
    2008                         loc = AtLookUp[AddHydIds[ineigh][0]]+1
    2009                         if 'O' in neigh[0] and (not len(mapData['rho']) or not 'delt-F' in mapData['MapType']):
    2010                             mapError = True
    2011                             continue                           
    2012                         Hxyz,HU = G2mth.AddHydrogens(AtLookUp,generalData,atomData,AddHydIds[ineigh])
    2013                         for iX,X in enumerate(Hxyz):
    2014                             AtomInsert(loc+iX,X[0],X[1],X[2],'H','H%s'%(neigh[0][1:]+letters[iX]))
    2015                             data['Atoms'][loc+iX][cia+1] = HU[iX]
    2016                             Id = data['Atoms'][loc+iX][cia+8]
    2017                             HydIds[Id] = [iX,AddHydIds[ineigh]]
    2018                             Nat += 1
    2019                             AtLookUp = G2mth.FillAtomLookUp(atomData,cia+8)
    2020                 if mapError:
    2021                     G2frame.ErrorDialog('Add H atom error','Adding O-H atoms requires delt-F map')
    2022                 SetupGeneral()
    2023                 data['General']['HydIds'].update(HydIds)
    2024                 G2frame.dataFrame.AtomEdit.Enable(G2gd.wxID_UPDATEHATOM,True)
    2025                 data['Drawing']['Atoms'] = []
    2026                 UpdateDrawAtoms()
    2027                 FillAtomsGrid(Atoms)
    2028                 dlg.Destroy()
    2029                 G2plt.PlotStructure(G2frame,data)
    2030             else:
    2031                 wx.MessageBox('No candidates found',caption='Add H atom Error',style=wx.ICON_EXCLAMATION)
     1987                    elif 'O' in bond and bonds[bond][0] < 1.3:
     1988                        nH -= 1
     1989                        break
     1990                elif 'O' in atom[ct] and 'C' in bonds and bonds[bond][0] < 1.3:
     1991                    nH -= 1
     1992                    break
     1993            nextneigh = []
     1994            if nextName:
     1995                nextneigh = G2mth.FindNeighbors(data,nextName,AtNames,notName=neigh[0])
     1996                if nextneigh[0]:
     1997                    neigh[1][1].append(nextneigh[1][1][0])
     1998            neigh[2] = max(0,nH)  #set expected no. H's needed
     1999            if len(neigh[1][0]):
     2000                AddHydIds.append(neigh[1][1])
     2001                Neigh.append(neigh)
     2002        if Neigh:
     2003            letters = ['A','B','C']
     2004            HydIds = {}
     2005            mapError = False
     2006            dlg = G2gd.AddHatomDialog(G2frame,Neigh,data)
     2007            if dlg.ShowModal() == wx.ID_OK:
     2008                Nat = len(atomData)
     2009                Neigh = dlg.GetData()
     2010                mapData = generalData['Map']
     2011                for ineigh,neigh in enumerate(Neigh):
     2012                    AddHydIds[ineigh].append(neigh[2])
     2013                    loc = AtLookUp[AddHydIds[ineigh][0]]+1
     2014                    if 'O' in neigh[0] and (not len(mapData['rho']) or not 'delt-F' in mapData['MapType']):
     2015                        mapError = True
     2016                        continue                           
     2017                    Hxyz,HU = G2mth.AddHydrogens(AtLookUp,generalData,atomData,AddHydIds[ineigh])
     2018                    for iX,X in enumerate(Hxyz):
     2019                        AtomInsert(loc+iX,X[0],X[1],X[2],'H','H%s'%(neigh[0][1:]+letters[iX]))
     2020                        data['Atoms'][loc+iX][cia+1] = HU[iX]
     2021                        Id = data['Atoms'][loc+iX][cia+8]
     2022                        HydIds[Id] = [iX,AddHydIds[ineigh]]
     2023                        Nat += 1
     2024                        AtLookUp = G2mth.FillAtomLookUp(atomData,cia+8)
     2025            if mapError:
     2026                G2frame.ErrorDialog('Add H atom error','Adding O-H atoms requires delt-F map')
     2027            SetupGeneral()
     2028            data['General']['HydIds'].update(HydIds)
     2029            G2frame.dataFrame.AtomEdit.Enable(G2gd.wxID_UPDATEHATOM,True)
     2030            data['Drawing']['Atoms'] = []
     2031            UpdateDrawAtoms()
     2032            FillAtomsGrid(Atoms)
     2033            dlg.Destroy()
     2034            G2plt.PlotStructure(G2frame,data)
     2035        else:
     2036            wx.MessageBox('No candidates found',caption='Add H atom Error',style=wx.ICON_EXCLAMATION)
    20322037               
    20332038    def OnHydAtomUpdate(event):
     
    20672072        cx = colLabels.index('x')
    20682073        ci = colLabels.index('I/A')
    2069         indx = Atoms.GetSelectedRows()
     2074        indx = GetSelectedAtoms()
    20702075        if len(indx) != 1:
    20712076            G2frame.ErrorDialog('Atom move error','Only one atom can be moved')
     
    21552160        HydIds = data['General']['HydIds']
    21562161        ci = colLabels.index('I/A')
    2157         indx = Atoms.GetSelectedRows()
     2162        indx = GetSelectedAtoms()
    21582163        IDs = []
     2164        if not indx: return
     2165        atomData = data['Atoms']
     2166        indx.reverse()
     2167        for ind in indx:
     2168            atom = atomData[ind]
     2169            if atom[ci+8] in rbAtmDict:
     2170                G2frame.dataFrame.SetStatusText('**** ERROR - atom is in a rigid body and can not be deleted ****')
     2171            else:
     2172                if atom[ci+8] in HydIds:    #remove Hs from Hatom update dict
     2173                    del HydIds[atom[ci+8]]
     2174                IDs.append(atom[ci+8])
     2175                del atomData[ind]
     2176        if 'Atoms' in data['Drawing']:
     2177            Atoms.ClearSelection()
     2178            DrawAtomsDeleteByIDs(IDs)
     2179            data['Drawing']['Atoms'] = []
     2180            UpdateDrawAtoms()
     2181            wx.CallAfter(FillAtomsGrid,Atoms)
     2182            G2plt.PlotStructure(G2frame,data)
     2183        SetupGeneral()
     2184        if not len(HydIds):
     2185            G2frame.dataFrame.AtomEdit.Enable(G2gd.wxID_UPDATEHATOM,False)
     2186        event.StopPropagation()
     2187
     2188    def GetSelectedAtoms():
     2189        '''Get all atoms that are selected by row or by having any cell selected.
     2190        produce an error message if no atoms are selected.
     2191        '''
     2192        indx = list(set([row for row,col in Atoms.GetSelectedCells()]+Atoms.GetSelectedRows()))
    21592193        if indx:
    2160             atomData = data['Atoms']
    2161             indx.reverse()
    2162             for ind in indx:
    2163                 atom = atomData[ind]
    2164                 if atom[ci+8] in rbAtmDict:
    2165                     G2frame.dataFrame.SetStatusText('**** ERROR - atom is in a rigid body and can not be deleted ****')
    2166                 else:
    2167                     if atom[ci+8] in HydIds:    #remove Hs from Hatom update dict
    2168                         del HydIds[atom[ci+8]]
    2169                     IDs.append(atom[ci+8])
    2170                     del atomData[ind]
    2171             if 'Atoms' in data['Drawing']:
    2172                 Atoms.ClearSelection()
    2173                 DrawAtomsDeleteByIDs(IDs)
    2174                 data['Drawing']['Atoms'] = []
    2175                 UpdateDrawAtoms()
    2176                 wx.CallAfter(FillAtomsGrid,Atoms)
    2177                 G2plt.PlotStructure(G2frame,data)
    2178             SetupGeneral()
    2179             if not len(HydIds):
    2180                 G2frame.dataFrame.AtomEdit.Enable(G2gd.wxID_UPDATEHATOM,False)
    2181         event.StopPropagation()
    2182 
     2194            return indx
     2195        else:
     2196            G2G.G2MessageBox(G2frame,'Warning: no atoms were selected','Nothing selected')
     2197       
    21832198    def AtomRefine(event):
    21842199        colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
    21852200        c = colLabels.index('refine')
    2186         indx = Atoms.GetSelectedRows()
    2187         if indx:
    2188             atomData = data['Atoms']
    2189             generalData = data['General']
    2190             Type = generalData['Type']
     2201        indx = GetSelectedAtoms()
     2202        if not indx: return
     2203        atomData = data['Atoms']
     2204        generalData = data['General']
     2205        Type = generalData['Type']
     2206        if Type in ['nuclear','macromolecular','faulted',]:
    21912207            choice = ['F - site fraction','X - coordinates','U - thermal parameters']
    2192             dlg = wx.MultiChoiceDialog(G2frame,'Select','Refinement controls',choice)
     2208        elif Type in ['magnetic',]:
     2209            choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment']
     2210        dlg = wx.MultiChoiceDialog(G2frame,'Select','Refinement controls',choice)
     2211        if dlg.ShowModal() == wx.ID_OK:
     2212            sel = dlg.GetSelections()
     2213            parms = ''
     2214            for x in sel:
     2215                parms += choice[x][0]
     2216            for r in indx:
     2217                if not Atoms.IsReadOnly(r,c):
     2218                    atomData[r][c] = parms
     2219            Atoms.ForceRefresh()
     2220        dlg.Destroy()
     2221
     2222    def AtomModify(event):
     2223        indx = GetSelectedAtoms()
     2224        if not indx: return
     2225        atomData = data['Atoms']
     2226        generalData = data['General']
     2227        colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
     2228        ci = colLabels.index('I/A')
     2229        choices = ['Type','Name','x','y','z','frac','I/A','Uiso']
     2230        if generalData['Type'] == 'magnetic':
     2231            choices += ['Mx','My','Mz',]
     2232        dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom parameter',choices)
     2233        parm = ''
     2234        if dlg.ShowModal() == wx.ID_OK:
     2235            sel = dlg.GetSelection()
     2236            parm = choices[sel]
     2237            cid = colLabels.index(parm)
     2238        dlg.Destroy()
     2239        if parm in ['Type']:
     2240            dlg = G2elemGUI.PickElement(G2frame)
    21932241            if dlg.ShowModal() == wx.ID_OK:
    2194                 sel = dlg.GetSelections()
    2195                 parms = ''
    2196                 for x in sel:
    2197                     parms += choice[x][0]
    2198                 for r in indx:
    2199                     if not Atoms.IsReadOnly(r,c):
    2200                         atomData[r][c] = parms
    2201                 Atoms.ForceRefresh()
     2242                if dlg.Elem not in ['None']:
     2243                    El = dlg.Elem.strip()
     2244                    for r in indx:                       
     2245                        if not Atoms.IsReadOnly(r,cid):
     2246                            atomData[r][cid] = El
     2247                            if len(El) in [2,4]:
     2248                                atomData[r][cid-1] = El[:2]+'%d'%(r+1)
     2249                            else:
     2250                                atomData[r][cid-1] = El[:1]+'%d'%(r+1)
     2251                    SetupGeneral()
     2252                    if 'Atoms' in data['Drawing']:
     2253                        for r in indx:
     2254                            ID = atomData[r][ci+8]
     2255                            DrawAtomsReplaceByID(data['Drawing'],ci+8,atomData[r],ID)
     2256                FillAtomsGrid(Atoms)
    22022257            dlg.Destroy()
    2203 
    2204     def AtomModify(event):
    2205         indx = Atoms.GetSelectedRows()
    2206         if indx:
    2207             atomData = data['Atoms']
    2208             generalData = data['General']
    2209             colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
    2210             ci = colLabels.index('I/A')
    2211             choices = ['Type','Name','x','y','z','frac','I/A','Uiso']
    2212             if generalData['Type'] == 'magnetic':
    2213                 choices += ['Mx','My','Mz',]
    2214             dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom parameter',choices)
    2215             parm = ''
     2258        elif parm in ['Name',]:
     2259            dlg = wx.MessageDialog(G2frame,'Do you really want to rename the selected atoms?','Rename',
     2260                wx.YES_NO | wx.ICON_QUESTION)
     2261            try:
     2262                result = dlg.ShowModal()
     2263                if result == wx.ID_YES:
     2264                    for r in indx:
     2265                        if not Atoms.IsReadOnly(r,cid+1):
     2266                            El = atomData[r][cid+1]
     2267                            if len(El) in [2,4]:
     2268                                atomData[r][cid] = El[:2]+'%d'%(r+1)
     2269                            else:
     2270                                atomData[r][cid] = El[:1]+'%d'%(r+1)
     2271                FillAtomsGrid(Atoms)
     2272            finally:
     2273                dlg.Destroy()
     2274
     2275        elif parm in ['I/A']:
     2276            choices = ['Isotropic','Anisotropic']
     2277            dlg = wx.SingleChoiceDialog(G2frame,'Select','Thermal parameter model',choices)
    22162278            if dlg.ShowModal() == wx.ID_OK:
    22172279                sel = dlg.GetSelection()
    2218                 parm = choices[sel]
    2219                 cid = colLabels.index(parm)
     2280                parm = choices[sel][0]
     2281                for r in indx:                       
     2282                    if not Atoms.IsReadOnly(r,cid):
     2283                        atomData[r][cid] = parm
     2284                FillAtomsGrid(Atoms)
    22202285            dlg.Destroy()
    2221             if parm in ['Type']:
    2222                 dlg = G2elemGUI.PickElement(G2frame)
    2223                 if dlg.ShowModal() == wx.ID_OK:
    2224                     if dlg.Elem not in ['None']:
    2225                         El = dlg.Elem.strip()
    2226                         for r in indx:                       
    2227                             if not Atoms.IsReadOnly(r,cid):
    2228                                 atomData[r][cid] = El
    2229                                 if len(El) in [2,4]:
    2230                                     atomData[r][cid-1] = El[:2]+'%d'%(r+1)
    2231                                 else:
    2232                                     atomData[r][cid-1] = El[:1]+'%d'%(r+1)
    2233                         SetupGeneral()
    2234                         if 'Atoms' in data['Drawing']:
    2235                             for r in indx:
    2236                                 ID = atomData[r][ci+8]
    2237                                 DrawAtomsReplaceByID(data['Drawing'],ci+8,atomData[r],ID)
    2238                     FillAtomsGrid(Atoms)
    2239                 dlg.Destroy()
    2240             elif parm in ['Name',]:
    2241                 dlg = wx.MessageDialog(G2frame,'Do you really want to rename the selected atoms?','Rename',
    2242                     wx.YES_NO | wx.ICON_QUESTION)
    2243                 try:
    2244                     result = dlg.ShowModal()
    2245                     if result == wx.ID_YES:
    2246                         for r in indx:
    2247                             if not Atoms.IsReadOnly(r,cid+1):
    2248                                 El = atomData[r][cid+1]
    2249                                 if len(El) in [2,4]:
    2250                                     atomData[r][cid] = El[:2]+'%d'%(r+1)
    2251                                 else:
    2252                                     atomData[r][cid] = El[:1]+'%d'%(r+1)
    2253                     FillAtomsGrid(Atoms)
    2254                 finally:
    2255                     dlg.Destroy()
    2256                    
    2257             elif parm in ['I/A']:
    2258                 choices = ['Isotropic','Anisotropic']
    2259                 dlg = wx.SingleChoiceDialog(G2frame,'Select','Thermal parameter model',choices)
    2260                 if dlg.ShowModal() == wx.ID_OK:
    2261                     sel = dlg.GetSelection()
    2262                     parm = choices[sel][0]
    2263                     for r in indx:                       
    2264                         if not Atoms.IsReadOnly(r,cid):
    2265                             atomData[r][cid] = parm
    2266                     FillAtomsGrid(Atoms)
    2267                 dlg.Destroy()
    2268             elif parm in ['frac','Uiso']:
    2269                 limits = [0.,1.]
    2270                 val = 1.0
    2271                 if  parm in ['Uiso']:
    2272                     limits = [0.,0.25]
    2273                     val = 0.01
    2274                 dlg = G2G.SingleFloatDialog(G2frame,'New value','Enter new value for '+parm,val,limits)
    2275                 if dlg.ShowModal() == wx.ID_OK:
    2276                     parm = dlg.GetValue()
    2277                     for r in indx:                       
    2278                         if not Atoms.IsReadOnly(r,cid):
    2279                             atomData[r][cid] = parm
    2280                     SetupGeneral()
    2281                     FillAtomsGrid(Atoms)
    2282                 dlg.Destroy()
    2283             elif parm in ['x','y','z']:
    2284                 limits = [-1.,1.]
    2285                 val = 0.
    2286                 dlg = G2G.SingleFloatDialog(G2frame,'Atom shift','Enter shift for '+parm,val,limits)
    2287                 if dlg.ShowModal() == wx.ID_OK:
    2288                     parm = dlg.GetValue()
    2289                     for r in indx:                       
    2290                         if not Atoms.IsReadOnly(r,cid):
    2291                             atomData[r][cid] += parm
    2292                     SetupGeneral()
    2293                     FillAtomsGrid(Atoms)
    2294                 dlg.Destroy()
    2295             elif parm in ['Mx','My','Mz',]:
    2296                 limits = [-10.,10.]
    2297                 val = 0.
    2298                 dlg = G2G.SingleFloatDialog(G2frame,'Atom moment','Enter new value for '+parm,val,limits)
    2299                 if dlg.ShowModal() == wx.ID_OK:
    2300                     parm = dlg.GetValue()
    2301                     for r in indx:                       
    2302                         if not Atoms.IsReadOnly(r,cid):
    2303                             atomData[r][cid] = parm
    2304                     SetupGeneral()
    2305                     FillAtomsGrid(Atoms)
    2306                 dlg.Destroy()
    2307                
    2308             data['Drawing']['Atoms'] = []
    2309             UpdateDrawAtoms()
    2310             G2plt.PlotStructure(G2frame,data)
     2286        elif parm in ['frac','Uiso']:
     2287            limits = [0.,1.]
     2288            val = 1.0
     2289            if  parm in ['Uiso']:
     2290                limits = [0.,0.25]
     2291                val = 0.01
     2292            dlg = G2G.SingleFloatDialog(G2frame,'New value','Enter new value for '+parm,val,limits)
     2293            if dlg.ShowModal() == wx.ID_OK:
     2294                parm = dlg.GetValue()
     2295                for r in indx:                       
     2296                    if not Atoms.IsReadOnly(r,cid):
     2297                        atomData[r][cid] = parm
     2298                SetupGeneral()
     2299                FillAtomsGrid(Atoms)
     2300            dlg.Destroy()
     2301        elif parm in ['x','y','z']:
     2302            limits = [-1.,1.]
     2303            val = 0.
     2304            dlg = G2G.SingleFloatDialog(G2frame,'Atom shift','Enter shift for '+parm,val,limits)
     2305            if dlg.ShowModal() == wx.ID_OK:
     2306                parm = dlg.GetValue()
     2307                for r in indx:                       
     2308                    if not Atoms.IsReadOnly(r,cid):
     2309                        atomData[r][cid] += parm
     2310                SetupGeneral()
     2311                FillAtomsGrid(Atoms)
     2312            dlg.Destroy()
     2313        elif parm in ['Mx','My','Mz',]:
     2314            limits = [-10.,10.]
     2315            val = 0.
     2316            dlg = G2G.SingleFloatDialog(G2frame,'Atom moment','Enter new value for '+parm,val,limits)
     2317            if dlg.ShowModal() == wx.ID_OK:
     2318                parm = dlg.GetValue()
     2319                for r in indx:                       
     2320                    if not Atoms.IsReadOnly(r,cid):
     2321                        atomData[r][cid] = parm
     2322                SetupGeneral()
     2323                FillAtomsGrid(Atoms)
     2324            dlg.Destroy()
     2325
     2326        data['Drawing']['Atoms'] = []
     2327        UpdateDrawAtoms()
     2328        G2plt.PlotStructure(G2frame,data)
     2329
     2330    def AtomTransform(event):
     2331        indx = GetSelectedAtoms()
     2332        if not indx: return
     2333        generalData = data['General']
     2334        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
     2335        SpnFlp = generalData['SGData'].get('SpnFlp',[])
     2336        colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
     2337        cx = colLabels.index('x')
     2338        cuia = colLabels.index('I/A')
     2339        cuij = colLabels.index('U11')
     2340        css = colLabels.index('site sym')
     2341        cmx = 0
     2342        if 'Mx' in colLabels:
     2343            cmx = colLabels.index('Mx')
     2344        atomData = data['Atoms']
     2345        SGData = generalData['SGData']
     2346        dlg = G2gd.SymOpDialog(G2frame,SGData,True,True)
     2347        New = False
     2348        try:
     2349            if dlg.ShowModal() == wx.ID_OK:
     2350                Inv,Cent,Opr,Cell,New,Force = dlg.GetSelection()
     2351                Cell = np.array(Cell)
     2352                cent = SGData['SGCen'][Cent]
     2353                M,T = SGData['SGOps'][Opr]
     2354                for ind in indx:
     2355                    XYZ = np.array(atomData[ind][cx:cx+3])
     2356                    XYZ = np.inner(M,XYZ)+T
     2357                    if Inv:
     2358                        XYZ = -XYZ
     2359                    XYZ = XYZ+cent+Cell
     2360                    if Force:
     2361                        XYZ,cell = G2spc.MoveToUnitCell(XYZ)
     2362                        Cell += cell
     2363                    if New:
     2364                        atom = copy.copy(atomData[ind])
     2365                    else:
     2366                        atom = atomData[ind]
     2367                    atom[cx:cx+3] = XYZ
     2368                    atom[css:css+2] = G2spc.SytSym(XYZ,SGData)[:2]
     2369                    OprNum = ((Opr+1)+100*Cent)*(1-2*Inv)
     2370                    if atom[cuia] == 'A':
     2371                        Uij = atom[cuij:cuij+6]
     2372                        U = G2spc.Uij2U(Uij)
     2373                        U = np.inner(np.inner(M,U),M)
     2374                        Uij = G2spc.U2Uij(U)
     2375                        atom[cuij:cuij+6] = Uij
     2376                    if cmx:
     2377                        opNum = G2spc.GetOpNum(OprNum,SGData)
     2378                        mom = np.inner(np.array(atom[cmx:cmx+3]),Bmat)
     2379                        atom[cmx:cmx+3] = np.inner(np.inner(mom,M),Amat)*nl.det(M)*SpnFlp[opNum-1]
     2380                    if New:
     2381                        atomData.append(atom)
     2382        finally:
     2383            dlg.Destroy()
     2384        Atoms.ClearSelection()
     2385        if New:
     2386            FillAtomsGrid(Atoms)
    23112387        else:
    2312             print "select one or more rows of atoms"
    2313             G2frame.ErrorDialog('Select atom',"select one or more atoms then redo")
    2314 
    2315     def AtomTransform(event):
    2316         indx = Atoms.GetSelectedRows()
    2317         if indx:
    2318             generalData = data['General']
    2319             Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
    2320             SpnFlp = generalData['SGData'].get('SpnFlp',[])
    2321             colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
    2322             cx = colLabels.index('x')
    2323             cuia = colLabels.index('I/A')
    2324             cuij = colLabels.index('U11')
    2325             css = colLabels.index('site sym')
    2326             cmx = 0
    2327             if 'Mx' in colLabels:
    2328                 cmx = colLabels.index('Mx')
    2329             atomData = data['Atoms']
    2330             SGData = generalData['SGData']
    2331             dlg = G2gd.SymOpDialog(G2frame,SGData,True,True)
    2332             New = False
    2333             try:
    2334                 if dlg.ShowModal() == wx.ID_OK:
    2335                     Inv,Cent,Opr,Cell,New,Force = dlg.GetSelection()
    2336                     Cell = np.array(Cell)
    2337                     cent = SGData['SGCen'][Cent]
    2338                     M,T = SGData['SGOps'][Opr]
    2339                     for ind in indx:
    2340                         XYZ = np.array(atomData[ind][cx:cx+3])
    2341                         XYZ = np.inner(M,XYZ)+T
    2342                         if Inv:
    2343                             XYZ = -XYZ
    2344                         XYZ = XYZ+cent+Cell
    2345                         if Force:
    2346                             XYZ,cell = G2spc.MoveToUnitCell(XYZ)
    2347                             Cell += cell
    2348                         if New:
    2349                             atom = copy.copy(atomData[ind])
    2350                         else:
    2351                             atom = atomData[ind]
    2352                         atom[cx:cx+3] = XYZ
    2353                         atom[css:css+2] = G2spc.SytSym(XYZ,SGData)[:2]
    2354                         OprNum = ((Opr+1)+100*Cent)*(1-2*Inv)
    2355                         if atom[cuia] == 'A':
    2356                             Uij = atom[cuij:cuij+6]
    2357                             U = G2spc.Uij2U(Uij)
    2358                             U = np.inner(np.inner(M,U),M)
    2359                             Uij = G2spc.U2Uij(U)
    2360                             atom[cuij:cuij+6] = Uij
    2361                         if cmx:
    2362                             opNum = G2spc.GetOpNum(OprNum,SGData)
    2363                             mom = np.inner(np.array(atom[cmx:cmx+3]),Bmat)
    2364                             atom[cmx:cmx+3] = np.inner(np.inner(mom,M),Amat)*nl.det(M)*SpnFlp[opNum-1]
    2365                         if New:
    2366                             atomData.append(atom)
    2367             finally:
    2368                 dlg.Destroy()
    2369             Atoms.ClearSelection()
    2370             if New:
    2371                 FillAtomsGrid(Atoms)
    2372             else:
    2373                 Atoms.ForceRefresh()
    2374             data['Drawing']['Atoms'] = []
    2375             UpdateDrawAtoms()
    2376             G2plt.PlotStructure(G2frame,data)
    2377         else:
    2378             print "select one or more rows of atoms"
    2379             G2frame.ErrorDialog('Select atom',"select one or more atoms then redo")
     2388            Atoms.ForceRefresh()
     2389        data['Drawing']['Atoms'] = []
     2390        UpdateDrawAtoms()
     2391        G2plt.PlotStructure(G2frame,data)
    23802392           
    23812393    def AtomRotate(event):
    2382         '''
    2383         Currently not used - Bind commented out below
     2394        '''Currently not used - Bind commented out below
    23842395        '''
    23852396        Units = {'':np.zeros(3),
     
    23882399            'yz':np.array([[0,i,j] for i in range(3) for j in range(3)])-np.array([1,1,0]),
    23892400            'xyz':np.array([[i,j,k] for i in range(3) for j in range(3) for k in range(3)])-np.array([1,1,1])}
    2390         indx = Atoms.GetSelectedRows()
     2401        indx = GetSelectedAtoms()
    23912402        if indx:
    23922403            generalData = data['General']
     
    24322443               
    24332444    def MakeMolecule(event):     
    2434         indx = Atoms.GetSelectedRows()
     2445        indx = GetSelectedAtoms()
    24352446        Oxyz = []
    24362447        xyz = []
     
    24692480        print(msg)
    24702481        G2G.G2MessageBox(G2frame.dataFrame,msg,'Density')
    2471          
     2482
     2483    def OnSetAll(event):
     2484        'set refinement flags for all atoms in table'
     2485        for row in range(Atoms.GetNumberRows()):
     2486            Atoms.SelectRow(row,True)
     2487   
    24722488    def OnDistAnglePrt(event):
    24732489        'save distances and angles to a file'   
     
    24782494    def OnDistAngle(event,fp=None):
    24792495        'Compute distances and angles'   
    2480         indx = Atoms.GetSelectedRows()
     2496        indx = GetSelectedAtoms()
    24812497        Oxyz = []
    24822498        xyz = []
     
    73637379            wx.EndBusyCursor()
    73647380        wx.CallAfter(FillPawleyReflectionsGrid)
     7381    def OnPawleySelAll(event):
     7382        refcol = [G2frame.PawleyRefl.GetColLabelValue(c) for c in range(G2frame.PawleyRefl.GetNumberCols())].index('refine')
     7383        for r in range(G2frame.PawleyRefl.GetNumberRows()):
     7384            G2frame.PawleyRefl.GetTable().SetValue(r,refcol,True)
     7385        G2frame.PawleyRefl.ForceRefresh()
     7386    def OnPawleySelNone(event):
     7387        refcol = [G2frame.PawleyRefl.GetColLabelValue(c) for c in range(G2frame.PawleyRefl.GetNumberCols())].index('refine')
     7388        for r in range(G2frame.PawleyRefl.GetNumberRows()):
     7389            G2frame.PawleyRefl.GetTable().SetValue(r,refcol,False)
     7390        G2frame.PawleyRefl.ForceRefresh()
     7391    def OnPawleyToggle(event):
     7392        raise Exception       
     7393
     7394        refcol = [G2frame.PawleyRefl.GetColLabelValue(c) for c in range(G2frame.PawleyRefl.GetNumberCols())].index('refine')
     7395        for r in range(G2frame.PawleyRefl.GetNumberRows()):
     7396            G2frame.PawleyRefl.GetTable().SetValue(
     7397                r,refcol,
     7398                not G2frame.PawleyRefl.GetTable().GetValueAsBool(r,refcol))
     7399        G2frame.PawleyRefl.ForceRefresh()
    73657400                           
    73667401################################################################################
     
    78857920        # Atoms
    78867921        FillSelectPageMenu(TabSelectionIdDict, G2frame.dataFrame.AtomsMenu)
     7922        G2frame.dataFrame.Bind(wx.EVT_MENU, OnSetAll, id=G2gd.wxID_ATOMSSETALL)
     7923        G2frame.dataFrame.Bind(wx.EVT_MENU, AtomRefine, id=G2gd.wxID_ATOMSSETSEL)
     7924        G2frame.dataFrame.Bind(wx.EVT_MENU, AtomModify, id=G2gd.wxID_ATOMSMODIFY)
     7925        G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomInsert, id=G2gd.wxID_ATOMSEDITINSERT)
     7926        G2frame.dataFrame.Bind(wx.EVT_MENU, OnHydAtomAdd, id=G2gd.wxID_ADDHATOM)
     7927        G2frame.dataFrame.Bind(wx.EVT_MENU, AtomDelete, id=G2gd.wxID_ATOMSEDITDELETE)
     7928        G2frame.dataFrame.Bind(wx.EVT_MENU, AtomTransform, id=G2gd.wxID_ATOMSTRANSFORM)
     7929#        G2frame.dataFrame.Bind(wx.EVT_MENU, AtomRotate, id=G2gd.wxID_ATOMSROTATE)
     7930       
    78877931        G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomAdd, id=G2gd.wxID_ATOMSEDITADD)
    78887932        G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomViewAdd, id=G2gd.wxID_ATOMSVIEWADD)
    7889         G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomInsert, id=G2gd.wxID_ATOMSEDITINSERT)
    78907933        G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomViewInsert, id=G2gd.wxID_ATOMVIEWINSERT)
    7891         G2frame.dataFrame.Bind(wx.EVT_MENU, OnHydAtomAdd, id=G2gd.wxID_ADDHATOM)
    78927934        G2frame.dataFrame.Bind(wx.EVT_MENU, OnHydAtomUpdate, id=G2gd.wxID_UPDATEHATOM)
    78937935        G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomMove, id=G2gd.wxID_ATOMMOVE)
    7894         G2frame.dataFrame.Bind(wx.EVT_MENU, AtomDelete, id=G2gd.wxID_ATOMSEDITDELETE)
    7895         G2frame.dataFrame.Bind(wx.EVT_MENU, AtomRefine, id=G2gd.wxID_ATOMSREFINE)
    7896         G2frame.dataFrame.Bind(wx.EVT_MENU, AtomModify, id=G2gd.wxID_ATOMSMODIFY)
    7897         G2frame.dataFrame.Bind(wx.EVT_MENU, AtomTransform, id=G2gd.wxID_ATOMSTRANSFORM)
    7898 #        G2frame.dataFrame.Bind(wx.EVT_MENU, AtomRotate, id=G2gd.wxID_ATOMSROTATE)
    78997936        G2frame.dataFrame.Bind(wx.EVT_MENU, MakeMolecule, id=G2gd.wxID_MAKEMOLECULE)
    79007937        G2frame.dataFrame.Bind(wx.EVT_MENU, OnReloadDrawAtoms, id=G2gd.wxID_RELOADDRAWATOMS)
     
    79778014        G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyEstimate, id=G2gd.wxID_PAWLEYESTIMATE)
    79788015        G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyUpdate, id=G2gd.wxID_PAWLEYUPDATE)
     8016        G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleySelAll, id=G2gd.wxID_PAWLEYSELALL)
     8017        G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleySelNone, id=G2gd.wxID_PAWLEYSELNONE)
     8018        G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyToggle, id=G2gd.wxID_PAWLEYSELTOGGLE)
    79798019       
    79808020    # UpdatePhaseData execution starts here
  • trunk/exports/G2export_CIF.py

    r2449 r2516  
    3434import GSASIIIO as G2IO
    3535import GSASIIgrid as G2gd
    36 import GSASIIctrls as G2ctrls
     36import GSASIIctrls as G2G
    3737import GSASIIstrIO as G2stIO
    3838import GSASIImath as G2mth
     
    5656        self.CIFname = ''
    5757
     58    def ValidateAscii(self,checklist):
     59        '''Validate items as ASCII'''
     60        msg = ''
     61        for lbl,val in checklist:
     62            if not all(ord(c) < 128 for c in val):
     63                if msg: msg += '\n'
     64                msg += lbl + " contains unicode characters: " + val
     65        if msg:
     66            G2G.G2MessageBox(self.G2frame,
     67                             'Error: CIFs can contain only ASCII characters. Please change item(s) below:\n\n'+msg,
     68                             'Unicode not valid for CIF')
     69            return True
     70                     
    5871    def _Exporter(self,event=None,phaseOnly=None,histOnly=None):
    5972        '''Basic code to export a CIF. Export can be full or simple, as set by
     
    6578            '''Write CIF data items to the file. Formats values as needed.
    6679            Also used without a value for loops, comments, loop headers, etc.
    67             '''           
     80            '''
     81            if all(ord(c) < 128 for c in value) and all(ord(c) < 128 for c in name):
     82                pass
     83            else:
     84                print('Warning: unicode stripped from CIF item with name='+name+' value='+value)
     85                s = ''
     86                for c in name:
     87                    if ord(c) < 128:
     88                        s += c
     89                    else:
     90                        s += '.'
     91                name = s
     92                s = ''
     93                for c in value:
     94                    if ord(c) < 128:
     95                        s += c
     96                    else:
     97                        s += '.'
     98                value = s
     99                print('...changed to name='+name+' value='+value)
     100               
    68101            if value:
    69102                if "\n" in value or len(value)> 70:
     
    13031336                if instrname is None:
    13041337                    d['InstrName'] = ''
    1305             return G2ctrls.CallScrolledMultiEditor(
     1338            return G2G.CallScrolledMultiEditor(
    13061339                self.G2frame,dictlist,keylist,
    13071340                prelbl=range(1,len(dictlist)+1),
     
    13091342                title='Instrument names',
    13101343                header="Edit instrument names. Note that a non-blank\nname is required for all histograms",
    1311                 CopyButton=True)
     1344                CopyButton=True,ASCIIonly=True)
    13121345           
    13131346        def EditRanges(event):
     
    15911624        # make sure required information is present
    15921625        self.CIFdate = dt.datetime.strftime(dt.datetime.now(),"%Y-%m-%dT%H:%M")
    1593         if not self.CIFname: # Get a name for the CIF. If not defined, use the GPX name (save if that is needed).
     1626        if not self.CIFname: # Get a name for the CIF. If not defined, use the GPX name (save, if that is needed).
    15941627            if not self.G2frame.GSASprojectfile:
    15951628                self.G2frame.OnFileSaveas(None)
     
    15991632                )[0]
    16001633            self.CIFname = self.CIFname.replace(' ','')
    1601         # get CIF author name -- required for full CIFs
     1634        # replace non-ASCII characters in CIFname with dots
     1635        s = ''
     1636        for c in self.CIFname:
     1637            if ord(c) < 128:
     1638                s += c
     1639            else:
     1640                s += '.'
     1641        self.CIFname = s
     1642        # load saved CIF author name
    16021643        try:
    16031644            self.author = self.OverallParms['Controls'].get("Author",'').strip()
    16041645        except KeyError:
    16051646            pass
    1606         if phaseOnly:
     1647        #=================================================================
     1648        # write quick CIFs
     1649        #=================================================================
     1650        if phaseOnly: #====Phase only CIF ================================
    16071651            print('Writing CIF output to file '+str(self.filename))
    16081652            self.OpenFile()
    16091653            oneblock = True
    16101654            self.quickmode = True
    1611             #====Phase only CIF ====================================================
    16121655            self.Write(' ')
    16131656            self.Write(70*'#')
     
    16181661            self.CloseFile()
    16191662            return
    1620         elif histOnly:
     1663        elif histOnly: #====Histogram only CIF ================================
    16211664            print('Writing CIF output to file '+str(self.filename))
    16221665            self.OpenFile()
     
    16621705            return
    16631706        #===============================================================================
    1664         # the normal export process starts here
     1707        # the export process for a full CIF starts here
    16651708        #===============================================================================
    1666         # get the project file name
    1667         self.CIFname = os.path.splitext(
    1668             os.path.split(self.G2frame.GSASprojectfile)[1]
    1669             )[0]
    16701709        self.InitExport(event)
    16711710        # load all of the tree into a set of dicts
     
    16881727               'Project does not contain any data or phases. Are they interconnected?')
    16891728           return
    1690         if not self.author:
    1691             if not EditAuthor(): return
    1692         # test for quick CIF mode or no data
    1693         self.quickmode = False
     1729        self.quickmode = False # full CIF
    16941730        phasenam = None # include all phases
    1695         # Project export: will this require a multiblock CIF?
     1731        # Will this require a multiblock CIF?
    16961732        if len(self.Phases) > 1:
    16971733            oneblock = False
     
    17811817                    instnam = histblk["Instrument Parameters"][0]['InstrName']
    17821818                    break # ignore all but 1st data histogram
    1783         # give the user a chance to edit all defaults
     1819        # give the user a window to edit CIF contents
     1820        if not self.author:
     1821            if not EditAuthor(): return
     1822        self.ValidateAscii([('Author name',self.author),]) # check for ASCII strings where needed, warn on problems
    17841823        self.cifdefs = wx.Dialog(
    17851824            self.G2frame,
     
    17871826        EditCIFDefaults()
    17881827        self.cifdefs.CenterOnParent()
    1789         val = self.cifdefs.ShowModal()
     1828        if self.cifdefs.ShowModal() != wx.ID_OK:
     1829            self.cifdefs.Destroy()
     1830            return
     1831        while self.ValidateAscii([('Author name',self.author),
     1832                                  ]): # validate a few things as ASCII
     1833            if self.cifdefs.ShowModal() != wx.ID_OK:
     1834                self.cifdefs.Destroy()
     1835                return
    17901836        self.cifdefs.Destroy()
    1791         if val != wx.ID_OK:
    1792             return
    17931837        #======================================================================
    17941838        # Start writing the CIF - single block
     
    17961840        print('Writing CIF output to file '+str(self.filename)+"...")
    17971841        self.OpenFile()
     1842        # test code ***************************************************************************************************
     1843        WriteCIFitem('data_'+'\xc3\x81vila')
     1844        # test code ***************************************************************************************************
    17981845        if self.currentExportType == 'single' or self.currentExportType == 'powder':
    17991846            #======Data only CIF (powder/xtal) ====================================
     
    25712618                    if rng[0]: mn = hint(rng[0])
    25722619                    if rng[1]: mx = hint(rng[1])
    2573                     ent = G2ctrls.ValidatedTxtCtrl(
     2620                    ent = G2G.ValidatedTxtCtrl(
    25742621                        self,dct,item,typeHint=hint,min=mn,max=mx,
    2575                         CIFinput=True,
     2622                        CIFinput=True,ASCIIonly=True,
    25762623                        OKcontrol=self.ControlOKButton)
    25772624                    self.ValidatedControlsList.append(ent)
    25782625                    return ent
    25792626        rw1 = rw.ResizeWidget(self)
    2580         ent = G2ctrls.ValidatedTxtCtrl(
     2627        ent = G2G.ValidatedTxtCtrl(
    25812628            rw1,dct,item,size=(100, 20),
    25822629            style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER,
    2583             CIFinput=True,
     2630            CIFinput=True,ASCIIonly=True,
    25842631            OKcontrol=self.ControlOKButton)
    25852632        self.ValidatedControlsList.append(ent)
  • trunk/imports/G2pwd_BrukerRAW.py

    r2408 r2516  
    6363        self.comments = []
    6464        self.repeat = True
     65        self.powderentry[0] = filename
    6566        File = open(filename,'rb')
    6667        if 'ver. 1' in self.formatName:
  • trunk/imports/G2pwd_CIF.py

    r2347 r2516  
    341341        self.powderentry[0] = filename
    342342        #self.powderentry[1] = pos # bank offset (N/A here)
    343         self.powderentry[2] = 1 # xye file only has one bank
     343        #self.powderentry[2] = 1 # xye file only has one bank
    344344        self.idstring = os.path.basename(filename) + ': ' + blk
    345345        if cf[blk].get('_diffrn_radiation_probe'):
  • trunk/imports/G2pwd_FP.py

    r2465 r2516  
    146146            self.powderentry[0] = filename
    147147            #self.powderentry[1] = pos # bank offset (N/A here)
    148             self.powderentry[2] = 1 # xye file only has one bank
     148            #self.powderentry[2] = 1 # xye file only has one bank
    149149            self.idstring = ospath.basename(filename)
    150150            # scan comments for temperature
  • trunk/imports/G2pwd_csv.py

    r2463 r2516  
    9898            self.powderentry[0] = filename
    9999            #self.powderentry[1] = pos # bank offset (N/A here)
    100             self.powderentry[2] = 1 # xye file only has one bank
     100            #self.powderentry[2] = 1 # xye file only has one bank
    101101            self.idstring = ospath.basename(filename)
    102102            # scan comments for temperature
  • trunk/imports/G2pwd_fxye.py

    r2341 r2516  
    338338                    ParentFrame=ParentFrame,
    339339                    title='Select Bank(s) to read from the list below',
    340                     size=(600,100),
     340                    size=(600,300),
    341341                    header='Dataset Selector')
    342             if len(self.selections) == 0: return False
     342            if len(self.selections) == 0:
     343                self.errors = 'No banks selected'
     344                return False
    343345            selblk = self.selections[0] # select first in list
    344346            if len(self.selections) > 1: # prepare to loop through again
  • trunk/imports/G2pwd_rigaku.py

    r2456 r2516  
    122122            ]
    123123        self.powderentry[0] = filename
    124         self.powderentry[2] = 1 # xye file only has one bank
     124        #self.powderentry[2] = 1 # xye file only has one bank
    125125        self.idstring = os.path.basename(filename)
    126126        return True
  • trunk/imports/G2pwd_xye.py

    r2480 r2516  
    131131            self.powderentry[0] = filename
    132132            #self.powderentry[1] = pos # bank offset (N/A here)
    133             self.powderentry[2] = 1 # xye file only has one bank
     133            #self.powderentry[2] = 1 # xye file only has one bank
    134134            self.idstring = ospath.basename(filename)
    135135            # scan comments for temperature
Note: See TracChangeset for help on using the changeset viewer.