def Exporter(self, event=None): '''Export a set of powder data as a text file ''' # the export process starts here self.InitExport(event) # load all of the tree into a set of dicts self.loadTree() if self.ExportSelect( # set export parameters AskFile='default' # base name on the GPX file name ): return self.OpenFile() hist = self.histnam[ 0] # there should only be one histogram, in any case take the 1st histblk = self.Histograms[hist] hfmt = 5 * "{:12s} " digitList = 2 * ((13, 3), ) + ((13, 5), ) + 2 * ((13, 3), ) self.Write(hfmt.format("x", "y_obs", "weight", "y_calc", "y_bkg")) for vallist in zip( histblk['Data'][0], histblk['Data'][1], histblk['Data'][2], histblk['Data'][3], histblk['Data'][4], #histblk['Data'][5], ): strg = '' for val, digits in zip(vallist, digitList): strg += G2py3.FormatPadValue(val, digits) self.Write(strg) self.CloseFile() print(str(hist) + ' written to file ' + str(self.fullpath))
def Writer(self,TreeName,filename=None,prmname=''): '''Write a single PWDR entry to a FXYE file ''' histblk = self.Histograms[TreeName] self.OpenFile(filename) self.Write(TreeName[5:]) if prmname: self.Write('Instrument parameter file:'+os.path.split(prmname)[1]) x = np.array(histblk['Data'][0]) if 'T' in histblk['Instrument Parameters'][0]['Type'][0]: cw = np.diff(x) x[:-1] += cw else: x *= 100. # convert weights to sigmas; use largest weight as minimum esd s = np.sqrt(np.maximum(0.,np.array(histblk['Data'][2]))) s[s==0] = np.max(s) s = 1./s self.Write('BANK 1 %d %d CONS %.2f %.2f 0 0 FXYE' % ( len(x),len(x),x[0],(x[1]-x[0]) )) # for X,Y,S in zip(x,histblk['Data'][1],s): # self.Write("{:15.6g} {:15.6g} {:15.6g}".format(X,Y,S)) for XYS in zip(x,histblk['Data'][1],s): line = '' for val in XYS: line += G2py3.FormatPadValue(val,(15,6)) self.Write(line) self.CloseFile()
def Writer(self, TreeName, filename=None): self.OpenFile(filename) histblk = self.Histograms[TreeName] if len(self.Histograms[TreeName]['Models']['Size']['Distribution']): self.Write('"Size Distribution"') Distr = np.array( self.Histograms[TreeName]['Models']['Size']['Distribution']) WriteList(self, ("bin_pos", "bin_width", "bin_value")) digitList = 2 * ((13, 3), ) + ((13, 4, 'g'), ) for bindata in Distr.T: line = "" for val, digits in zip(bindata, digitList): if line: line += ',' line += G2py3.FormatValue(val, digits) self.Write(line) self.Write('"Small angle data"') Parms = self.Histograms[TreeName]['Instrument Parameters'][0] for parm in Parms: if parm in [ 'Type', 'Source', ]: line = '"Instparm: %s","%s"' % (parm, Parms[parm][0]) elif parm in [ 'Lam', ]: line = '"Instparm: %s",%10.6f' % (parm, Parms[parm][1]) else: line = '"Instparm: %s",%10.2f' % (parm, Parms[parm][1]) self.Write(line) WriteList(self, ("q", "y_obs", "y_sig", "y_calc", "y_bkg")) digitList = 5 * ((13, 5, 'g'), ) for vallist in zip( histblk['Data'][0], histblk['Data'][1], 1. / np.sqrt(histblk['Data'][2]), histblk['Data'][3], histblk['Data'][4], ): line = "" for val, digits in zip(vallist, digitList): if line: line += ',' line += G2py3.FormatValue(val, digits) self.Write(line) self.CloseFile()
def Writer(self, TreeName, filename=None): #print filename self.OpenFile(filename) histblk = self.Histograms[TreeName] Parms = self.Histograms[TreeName]['Instrument Parameters'][0] for parm in Parms: if parm in [ 'Type', 'Source', ]: line = '"Instparm: %s","%s"' % (parm, Parms[parm][0]) elif parm in [ 'Lam', 'Zero', ]: line = '"Instparm: %s",%10.6f' % (parm, Parms[parm][1]) else: line = '"Instparm: %s",%10.2f' % (parm, Parms[parm][1]) self.Write(line) Samp = self.Histograms[TreeName]['Sample Parameters'] for samp in Samp: if samp in ['InstrName', 'Type']: line = '"Samparm: %s",%s' % (samp, Samp[samp]) elif samp in [ 'Azimuth', 'Chi', 'Gonio. radius', 'Omega', 'Phi', 'Pressure', 'Temperature', 'Time' ]: line = '"Samparm: %s",%10.2f' % (samp, Samp[samp]) elif samp in [ 'DisplaceX', 'DisplaceY', 'Scale', 'Shift', 'SurfRoughA', 'SurfRoughB', 'Transparency' ]: line = '"Samparm: %s",%10.2f' % (samp, Samp[samp][0]) else: continue self.Write(line) WriteList(self, ("x", "y_obs", "weight", "y_calc", "y_bkg", "Q")) digitList = 2 * ((13, 3), ) + ((13, 5), ) + 3 * ((13, 3), ) for vallist in zip( histblk['Data'][0], histblk['Data'][1], histblk['Data'][2], histblk['Data'][3], histblk['Data'][4], #histblk['Data'][5], 2 * np.pi / G2lat.Pos2dsp(Parms, histblk['Data'][0])): line = "" for val, digits in zip(vallist, digitList): if line: line += ',' line += G2py3.FormatValue(val, digits) self.Write(line) self.CloseFile()
def Exporter(self, event=None): '''Export one or more sets of powder data as FXYE file(s) ''' # the export process starts here self.InitExport(event) # load all of the tree into a set of dicts self.loadTree() if self.ExportSelect( # set export parameters AskFile='single' # get a file name/directory to save in ): return filenamelist = [] for hist in self.histnam: if len(self.histnam) > 1: # multiple files: create a unique name from the histogram fileroot = G2obj.MakeUniqueLabel(self.MakePWDRfilename(hist), filenamelist) # create an instrument parameter file self.filename = os.path.join(self.dirname, fileroot + self.extension) else: # use the supplied name, but force the extension self.filename = os.path.splitext( self.filename)[0] + self.extension histblk = self.Histograms[hist] prmname = self.WriteInstFile(hist, histblk['Instrument Parameters'][0]) self.OpenFile() self.Write(hist[5:]) self.Write('Instrument parameter file:' + os.path.split(prmname)[1]) x = 100 * np.array(histblk['Data'][0]) # convert weights to sigmas; use largest weight as minimum esd s = np.sqrt(np.maximum(0., np.array(histblk['Data'][2]))) s[s == 0] = np.max(s) s = 1. / s self.Write('BANK 1 %d %d CONS %.2f %.2f 0 0 FXYE' % (len(x), len(x), x[0], (x[1] - x[0]))) # for X,Y,S in zip(x,histblk['Data'][1],s): # self.Write("{:15.6g} {:15.6g} {:15.6g}".format(X,Y,S)) for XYS in zip(x, histblk['Data'][1], s): line = '' for val in XYS: line += G2py3.FormatPadValue(val, (15, 6)) self.Write(line) self.CloseFile() print('Histogram ' + str(hist) + ' written to file ' + str(self.fullpath))
def Writer(self,TreeName,filename=None): self.OpenFile(filename) histblk = self.Histograms[TreeName] self.Write('/*') #The ugly c comment delimiter used in topas! self.Write('# '+TreeName[5:]) #evidently this by itself fails in topas self.Write('*/') x = np.array(histblk['Data'][0]) # convert weights to sigmas; use largest weight as minimum esd s = np.sqrt(np.maximum(0.,np.array(histblk['Data'][2]))) s[s==0] = np.max(s) s = 1./s for XYS in zip(x,histblk['Data'][1],s): line = '' for val in XYS: line += G2py3.FormatPadValue(val,(15,6)) self.Write(line) self.CloseFile()
def Exporter(self, event=None): '''Export one or more sets of powder data as XYE file(s) ''' # the export process starts here self.InitExport(event) # load all of the tree into a set of dicts self.loadTree() if self.ExportSelect( # set export parameters AskFile='single' # get a file name/directory to save in ): return filenamelist = [] for hist in self.histnam: if len(self.histnam) > 1: # multiple files: create a unique name from the histogram fileroot = G2obj.MakeUniqueLabel(self.MakePWDRfilename(hist), filenamelist) # create an instrument parameter file self.filename = os.path.join(self.dirname, fileroot + self.extension) else: # use the supplied name, but force the extension self.filename = os.path.splitext( self.filename)[0] + self.extension self.OpenFile() histblk = self.Histograms[hist] self.Write('/*') #The ugly c comment delimiter used in topas! self.Write('# ' + hist[5:]) #evidently this by itself fails in topas self.Write('*/') x = np.array(histblk['Data'][0]) # convert weights to sigmas; use largest weight as minimum esd s = np.sqrt(np.maximum(0., np.array(histblk['Data'][2]))) s[s == 0] = np.max(s) s = 1. / s for XYS in zip(x, histblk['Data'][1], s): line = '' for val in XYS: line += G2py3.FormatPadValue(val, (15, 6)) self.Write(line) self.CloseFile() print('Histogram ' + str(hist) + ' written to file ' + str(self.fullpath))
def Writer(self,TreeName,filename=None): self.OpenFile(filename) histblk = self.Histograms[TreeName] hfmt = 5*"{:12s} " digitList = 2*((13,3),) + ((13,5),) + 2*((13,3),) self.Write(hfmt.format("x","y_obs","weight","y_calc","y_bkg")) for vallist in zip(histblk['Data'][0], histblk['Data'][1], histblk['Data'][2], histblk['Data'][3], histblk['Data'][4], #histblk['Data'][5], ): strg = '' for val,digits in zip(vallist,digitList): strg += G2py3.FormatPadValue(val,digits) self.Write(strg) self.CloseFile()
def Exporter(self, event=None): '''Export a set of powder data as a single csv file ''' # the export process starts here self.InitExport(event) # load all of the tree into a set of dicts self.loadTree() if self.ExportSelect( # set export parameters AskFile='ask' # only one file is ever written ): return csvData = [] headList = [ "x", ] digitList = [] self.filename = os.path.join( self.dirname, os.path.splitext(self.filename)[0] + self.extension) for ihst, hist in enumerate(self.histnam): histblk = self.Histograms[hist] headList.append('y_obs_' + G2obj.StripUnicode(hist[5:].replace(' ', '_'))) if not ihst: digitList = [ (13, 3), ] csvData.append(histblk['Data'][0]) digitList += [ (13, 3), ] csvData.append(histblk['Data'][1]) print('Histogram ' + hist + ' added to file...') self.OpenFile() WriteList(self, headList) for vallist in np.array(csvData).T: line = "" for val, digits in zip(vallist, digitList): if line: line += ',' line += G2py3.FormatValue(val, digits) self.Write(line) self.CloseFile() print('...file ' + self.fullpath + ' written')
def Repaint(self,exprObj): 'Redisplay the variables and continue the validation' self.ShowVars() # show widgets to set vars msg = self.CheckVars() if msg: self.setEvalResult(msg) return exprObj.LoadExpression( self.expr, self.exprVarLst, self.varSelect, self.varName, self.varValue, self.varRefflag, ) try: calcobj = G2obj.ExpressionCalcObj(exprObj) calcobj.SetupCalc(self.parmDict) val = calcobj.EvalExpression() except Exception as msg: self.setEvalResult("Error in evaluation: "+str(msg)) return if not np.isfinite(val): self.setEvalResult("Expression value is infinite or out-of-bounds") return s = G2py3.FormatSigFigs(val).rstrip('0') depVal = "" if self.depVarDict: if not self.dependentVar: self.setEvalResult("A dependent variable must be selected.") return depVal = '; Variable "' + self.dependentVar + '" = ' + str( self.depVarDict.get(self.dependentVar,'?') ) self.setEvalResult("Expression evaluates to: "+str(s)+depVal) self.OKbtn.Enable() if self.ExtraBtn: self.ExtraBtn.Enable()
def Repaint(self, exprObj): 'Redisplay the variables and continue the validation' # create widgets to associate vars with labels and/or show messages self.varSizer.Clear(True) self.errbox = wxscroll.ScrolledPanel(self, style=wx.HSCROLL) self.errbox.SetMinSize((100, 130)) self.varSizer.Add(self.errbox, 0, wx.ALL | wx.EXPAND, 1) self.varbox = wxscroll.ScrolledPanel(self, style=wx.HSCROLL) self.varSizer.Add(self.varbox, 1, wx.ALL | wx.EXPAND, 1) Siz = wx.BoxSizer(wx.VERTICAL) Siz.Add( wx.StaticText(self.varbox, wx.ID_ANY, 'Assignment of variables to labels:'), 0, wx.EXPAND | wx.ALIGN_CENTER, 0) GridSiz = wx.FlexGridSizer(0, 5, 2, 2) GridSiz.Add( wx.StaticText(self.varbox, wx.ID_ANY, 'label', style=wx.CENTER), 0, wx.ALIGN_CENTER) lbls = ('varib. type\nselection', 'variable\nname', 'value') choices = ['Free', 'Phase', 'Hist./Phase', 'Hist.', 'Global'] if self.fit: lbls += ('refine\nflag', ) else: lbls += ('', ) choices[0] = '' for i in range(1, len(choices)): # remove empty menus from choice list if not len(self.parmLists[i]): choices[i] = '' self.AllowedChoices = [i for i in range(len(choices)) if choices[i]] for lbl in lbls: w = wx.StaticText(self.varbox, wx.ID_ANY, lbl, style=wx.CENTER) w.SetMinSize((80, -1)) GridSiz.Add(w, 0, wx.ALIGN_CENTER) # show input for each var in expression. for v in self.exprVarLst: # label GridSiz.Add(wx.StaticText(self.varbox, wx.ID_ANY, v), 0, wx.ALIGN_CENTER, 0) # assignment type ch = wx.Choice(self.varbox, wx.ID_ANY, choices=[choices[i] for i in self.AllowedChoices]) GridSiz.Add(ch, 0, wx.ALIGN_LEFT, 0) if v in self.varSelect and self.varSelect.get( v) in self.AllowedChoices: i = self.AllowedChoices.index(self.varSelect[v]) ch.SetSelection(i) else: ch.SetSelection(wx.NOT_FOUND) ch.label = v ch.Bind(wx.EVT_CHOICE, self.OnChoice) # var name/var assignment if self.varSelect.get(v) is None: GridSiz.Add((-1, -1), 0, wx.ALIGN_LEFT | wx.EXPAND, 0) elif self.varSelect.get(v) == 0: wid = G2G.ValidatedTxtCtrl(self.varbox, self.varName, v, size=(50, -1)) GridSiz.Add(wid, 0, wx.ALIGN_LEFT | wx.EXPAND, 0) else: wid = wx.StaticText(self.varbox, wx.ID_ANY, self.varName[v]) GridSiz.Add(wid, 0, wx.ALIGN_LEFT, 0) # value if self.varSelect.get(v) is None: GridSiz.Add((-1, -1), 0, wx.ALIGN_RIGHT | wx.EXPAND, 0) elif self.varSelect.get(v) == 0: wid = G2G.ValidatedTxtCtrl(self.varbox, self.varValue, v, size=(75, -1)) GridSiz.Add(wid, 0, wx.ALIGN_LEFT | wx.EXPAND, 0) wid.Bind(wx.EVT_CHAR, self.OnChar) else: var = self.varName[v] if var in self.parmDict: val = self.parmDict[var] s = G2py3.FormatSigFigs(val).rstrip('0') elif '*' in var: vs = G2obj.LookupWildCard(var, self.parmDict.keys()) s = '(' + str(len(vs)) + ' values)' else: s = '?' wid = wx.StaticText(self.varbox, wx.ID_ANY, s) GridSiz.Add(wid, 0, wx.ALIGN_LEFT, 0) # show a refine flag for Free Vars only if self.varSelect.get(v) == 0 and self.fit: self.varRefflag[v] = self.varRefflag.get(v, True) wid = G2G.G2CheckBox(self.varbox, '', self.varRefflag, v) GridSiz.Add(wid, 0, wx.ALIGN_LEFT | wx.EXPAND, 0) else: wid = (-1, -1) GridSiz.Add(wid, 0, wx.ALIGN_LEFT | wx.EXPAND, 0) Siz.Add(GridSiz) self.varbox.SetSizer(Siz, True) # evaluate the expression, displaying errors or the expression value try: msg = self.CheckVars() if msg: self.setEvalResult(msg) return exprObj.LoadExpression( self.expr, self.exprVarLst, self.varSelect, self.varName, self.varValue, self.varRefflag, ) try: calcobj = G2obj.ExpressionCalcObj(exprObj) calcobj.SetupCalc(self.parmDict) val = calcobj.EvalExpression() except Exception as msg: self.setEvalResult("Error in evaluation: " + str(msg)) return if not np.isfinite(val): self.setEvalResult( "Expression value is infinite or out-of-bounds") return s = G2py3.FormatSigFigs(val).rstrip('0') depVal = "" if self.depVarDict: if not self.dependentVar: self.setEvalResult( "A dependent variable must be selected.") return depVal = '; Variable "' + self.dependentVar + '" = ' + str( self.depVarDict.get(self.dependentVar, '?')) self.setEvalResult("Expression evaluates to: " + str(s) + depVal) self.OKbtn.Enable() if self.ExtraBtn: self.ExtraBtn.Enable() finally: xwid, yhgt = Siz.Fit(self.varbox) self.varbox.SetMinSize((xwid, 130)) self.varbox.SetAutoLayout(1) self.varbox.SetupScrolling() self.varbox.Refresh() self.Layout() self.SendSizeEvent() # force repaint
def ShowVars(self): # create widgets to associate vars with labels and/or show messages self.varSizer.Clear(True) self.errbox = wxscroll.ScrolledPanel(self,style=wx.HSCROLL) self.errbox.SetMinSize((100,130)) self.varSizer.Add(self.errbox,0,wx.ALL|wx.EXPAND,1) self.varbox = wxscroll.ScrolledPanel(self,style=wx.HSCROLL) self.varSizer.Add(self.varbox,1,wx.ALL|wx.EXPAND,1) Siz = wx.BoxSizer(wx.VERTICAL) Siz.Add( wx.StaticText(self.varbox,wx.ID_ANY, 'Assignment of variables to labels:'), 0,wx.EXPAND|wx.ALIGN_CENTER,0) GridSiz = wx.FlexGridSizer(0,5,2,2) GridSiz.Add( wx.StaticText(self.varbox,wx.ID_ANY,'label',style=wx.CENTER), 0,wx.ALIGN_CENTER) lbls = ('varib. type\nselection','variable\nname','value') choices = ['Free','Phase','Hist./Phase','Hist.','Global'] if self.fit: lbls += ('refine\nflag',) else: lbls += ('',) choices[0] = '' for i in range(1,len(choices)): # remove empty menus from choice list if not len(self.parmLists[i]): choices[i] = '' self.AllowedChoices = [i for i in range(len(choices)) if choices[i]] for lbl in lbls: w = wx.StaticText(self.varbox,wx.ID_ANY,lbl,style=wx.CENTER) w.SetMinSize((80,-1)) GridSiz.Add(w,0,wx.ALIGN_CENTER) # show input for each var in expression. for v in self.exprVarLst: # label GridSiz.Add(wx.StaticText(self.varbox,wx.ID_ANY,v),0,wx.ALIGN_CENTER,0) # assignment type ch = wx.Choice( self.varbox, wx.ID_ANY, choices = [choices[i] for i in self.AllowedChoices] ) GridSiz.Add(ch,0,wx.ALIGN_LEFT,0) if v in self.varSelect and self.varSelect.get(v) in self.AllowedChoices: i = self.AllowedChoices.index(self.varSelect[v]) ch.SetSelection(i) else: ch.SetSelection(wx.NOT_FOUND) ch.label = v ch.Bind(wx.EVT_CHOICE,self.OnChoice) # var name/var assignment if self.varSelect.get(v) is None: GridSiz.Add((-1,-1),0,wx.ALIGN_LEFT|wx.EXPAND,0) elif self.varSelect.get(v) == 0: wid = G2G.ValidatedTxtCtrl(self.varbox,self.varName,v, #OnLeave=self.OnTxtLeave, size=(50,-1)) GridSiz.Add(wid,0,wx.ALIGN_LEFT|wx.EXPAND,0) else: wid = wx.StaticText(self.varbox,wx.ID_ANY,self.varName[v]) GridSiz.Add(wid,0,wx.ALIGN_LEFT,0) # value if self.varSelect.get(v) is None: GridSiz.Add((-1,-1),0,wx.ALIGN_RIGHT|wx.EXPAND,0) elif self.varSelect.get(v) == 0: wid = G2G.ValidatedTxtCtrl(self.varbox,self.varValue,v, #OnLeave=self.OnTxtLeave, size=(75,-1)) GridSiz.Add(wid,0,wx.ALIGN_LEFT|wx.EXPAND,0) wid.Bind(wx.EVT_CHAR,self.OnChar) else: var = self.varName[v] if '*' in var: #[self.parmDict[v] for v in LookupWildCard(var,self.parmDict.keys())] #print self.varValue[v] vs = G2obj.LookupWildCard(var,self.parmDict.keys()) s = '('+str(len(vs))+' values)' elif var in self.parmDict: val = self.parmDict[var] s = G2py3.FormatSigFigs(val).rstrip('0') else: s = '?' wid = wx.StaticText(self.varbox,wx.ID_ANY,s) GridSiz.Add(wid,0,wx.ALIGN_LEFT,0) # show a refine flag for Free Vars only if self.varSelect.get(v) == 0 and self.fit: self.varRefflag[v] = self.varRefflag.get(v,True) wid = G2G.G2CheckBox(self.varbox,'',self.varRefflag,v) GridSiz.Add(wid,0,wx.ALIGN_LEFT|wx.EXPAND,0) else: wid = (-1,-1) GridSiz.Add(wid,0,wx.ALIGN_LEFT|wx.EXPAND,0) Siz.Add(GridSiz) self.varbox.SetSizer(Siz,True) xwid,yhgt = Siz.Fit(self.varbox) self.varbox.SetMinSize((xwid,130)) self.varbox.SetAutoLayout(1) self.varbox.SetupScrolling() self.varbox.Refresh() self.Layout() #self.mainsizer.Fit(self) self.SendSizeEvent() # force repaint return
def ISODISTORT_proc(self,blk,atomlbllist,ranIdlookup): 'Process ISODISTORT items to create constraints etc.' varLookup = {'dx':'dAx','dy':'dAy','dz':'dAz','do':'Afrac'} 'Maps ISODISTORT parm names to GSAS-II names' #---------------------------------------------------------------------- # read in the ISODISTORT displacement modes #---------------------------------------------------------------------- self.Constraints = [] explaination = {} if blk.get('_iso_displacivemode_label'): modelist = [] shortmodelist = [] for lbl in blk.get('_iso_displacivemode_label'): modelist.append(lbl) # assume lbl is of form SSSSS[x,y,z]AAAA(a,b,...)BBBBB # where SSSSS is the parent spacegroup, [x,y,z] is a location regexp = re.match(r'.*?\[.*?\](.*?)\(.*?\)(.*)',lbl) # this extracts the AAAAA and BBBBB parts of the string if regexp: lbl = regexp.expand(r'\1\2') # parse succeeded, make a short version G2obj.MakeUniqueLabel(lbl,shortmodelist) # make unique and add to list # read in the coordinate offset variables names and map them to G2 names/objects coordVarLbl = [] G2varLbl = [] G2varObj = [] error = False for lbl in blk.get('_iso_deltacoordinate_label'): coordVarLbl.append(lbl) if '_' in lbl: albl = lbl[:lbl.rfind('_')] vlbl = lbl[lbl.rfind('_')+1:] else: self.warnings += ' ERROR: _iso_deltacoordinate_label not parsed: '+lbl error = True continue if albl not in atomlbllist: self.warnings += ' ERROR: _iso_deltacoordinate_label atom not found: '+lbl error = True continue else: anum = atomlbllist.index(albl) var = varLookup.get(vlbl) if not var: self.warnings += ' ERROR: _iso_deltacoordinate_label variable not found: '+lbl error = True continue G2varLbl.append('::'+var+':'+str(anum)) # variable name, less phase ID G2varObj.append(G2obj.G2VarObj( (self.Phase['ranId'],None,var,ranIdlookup[albl]) )) if error: raise Exception,"Error decoding variable labels" if len(G2varObj) != len(modelist): print "non-square input" raise Exception,"Rank of _iso_displacivemode != _iso_deltacoordinate" error = False ParentCoordinates = {} for lbl,exp in zip( blk.get('_iso_coordinate_label'), blk.get('_iso_coordinate_formula'), ): if '_' in lbl: albl = lbl[:lbl.rfind('_')] vlbl = lbl[lbl.rfind('_')+1:] else: self.warnings += ' ERROR: _iso_coordinate_label not parsed: '+lbl error = True continue if vlbl not in 'xyz' or len(vlbl) != 1: self.warnings += ' ERROR: _iso_coordinate_label coordinate not parsed: '+lbl error = True continue i = 'xyz'.index(vlbl) if not ParentCoordinates.get(albl): ParentCoordinates[albl] = [None,None,None] if '+' in exp: val = exp.split('+')[0].strip() val = G2p3.FormulaEval(val) if val is None: self.warnings += ' ERROR: _iso_coordinate_formula coordinate not interpreted: '+lbl error = True continue ParentCoordinates[albl][i] = val else: ParentCoordinates[albl][i] = G2p3.FormulaEval(exp) if error: print self.warnings raise Exception,"Error decoding variable labels" # get mapping of modes to atomic coordinate displacements displacivemodematrix = np.zeros((len(G2varObj),len(G2varObj))) for row,col,val in zip( blk.get('_iso_displacivemodematrix_row'), blk.get('_iso_displacivemodematrix_col'), blk.get('_iso_displacivemodematrix_value'),): displacivemodematrix[int(row)-1,int(col)-1] = float(val) # Invert to get mapping of atom displacements to modes displacivemodeInvmatrix = np.linalg.inv(displacivemodematrix) # create the constraints for i,row in enumerate(displacivemodeInvmatrix): constraint = [] for j,(lbl,k) in enumerate(zip(coordVarLbl,row)): if k == 0: continue constraint.append([k,G2varObj[j]]) constraint += [shortmodelist[i],False,'f'] self.Constraints.append(constraint) #---------------------------------------------------------------------- # save the ISODISTORT info for "mode analysis" if 'ISODISTORT' not in self.Phase: self.Phase['ISODISTORT'] = {} self.Phase['ISODISTORT'].update({ 'IsoModeList' : modelist, 'G2ModeList' : shortmodelist, 'IsoVarList' : coordVarLbl, 'G2VarList' : G2varObj, 'ParentStructure' : ParentCoordinates, 'Var2ModeMatrix' : displacivemodeInvmatrix, 'Mode2VarMatrix' : displacivemodematrix, }) # make explaination dictionary for mode,shortmode in zip(modelist,shortmodelist): explaination[shortmode] = "ISODISTORT full name "+str(mode) #---------------------------------------------------------------------- # now read in the ISODISTORT occupancy modes #---------------------------------------------------------------------- if blk.get('_iso_occupancymode_label'): modelist = [] shortmodelist = [] for lbl in blk.get('_iso_occupancymode_label'): modelist.append(lbl) # assume lbl is of form SSSSS[x,y,z]AAAA(a,b,...)BBBBB # where SSSSS is the parent spacegroup, [x,y,z] is a location regexp = re.match(r'.*?\[.*?\](.*?)\(.*?\)(.*)',lbl) # this extracts the AAAAA and BBBBB parts of the string if regexp: lbl = regexp.expand(r'\1\2') # parse succeeded, make a short version lbl = lbl.replace('order','o') G2obj.MakeUniqueLabel(lbl,shortmodelist) # make unique and add to list # read in the coordinate offset variables names and map them to G2 names/objects occVarLbl = [] G2varLbl = [] G2varObj = [] error = False for lbl in blk.get('_iso_deltaoccupancy_label'): occVarLbl.append(lbl) if '_' in lbl: albl = lbl[:lbl.rfind('_')] vlbl = lbl[lbl.rfind('_')+1:] else: self.warnings += ' ERROR: _iso_deltaoccupancy_label not parsed: '+lbl error = True continue if albl not in atomlbllist: self.warnings += ' ERROR: _iso_deltaoccupancy_label atom not found: '+lbl error = True continue else: anum = atomlbllist.index(albl) var = varLookup.get(vlbl) if not var: self.warnings += ' ERROR: _iso_deltaoccupancy_label variable not found: '+lbl error = True continue G2varLbl.append('::'+var+':'+str(anum)) # variable name, less phase ID G2varObj.append(G2obj.G2VarObj( (self.Phase['ranId'],None,var,ranIdlookup[albl]) )) if error: raise Exception,"Error decoding variable labels" if len(G2varObj) != len(modelist): print "non-square input" raise Exception,"Rank of _iso_occupancymode != _iso_deltaoccupancy" error = False ParentCoordinates = {} for lbl,exp in zip( blk.get('_iso_occupancy_label'), blk.get('_iso_occupancy_formula'), ): if '_' in lbl: albl = lbl[:lbl.rfind('_')] vlbl = lbl[lbl.rfind('_')+1:] else: self.warnings += ' ERROR: _iso_occupancy_label not parsed: '+lbl error = True continue if vlbl != 'occ': self.warnings += ' ERROR: _iso_occupancy_label coordinate not parsed: '+lbl error = True continue if '+' in exp: val = exp.split('+')[0].strip() val = G2p3.FormulaEval(val) if val is None: self.warnings += ' ERROR: _iso_occupancy_formula coordinate not interpreted: '+lbl error = True continue ParentCoordinates[albl] = val if error: raise Exception,"Error decoding occupancy labels" # get mapping of modes to atomic coordinate displacements occupancymodematrix = np.zeros((len(G2varObj),len(G2varObj))) for row,col,val in zip( blk.get('_iso_occupancymodematrix_row'), blk.get('_iso_occupancymodematrix_col'), blk.get('_iso_occupancymodematrix_value'),): occupancymodematrix[int(row)-1,int(col)-1] = float(val) # Invert to get mapping of atom displacements to modes occupancymodeInvmatrix = np.linalg.inv(occupancymodematrix) # create the constraints for i,row in enumerate(occupancymodeInvmatrix): constraint = [] for j,(lbl,k) in enumerate(zip(occVarLbl,row)): if k == 0: continue constraint.append([k,G2varObj[j]]) constraint += [shortmodelist[i],False,'f'] self.Constraints.append(constraint) #---------------------------------------------------------------------- # save the ISODISTORT info for "mode analysis" if 'ISODISTORT' not in self.Phase: self.Phase['ISODISTORT'] = {} self.Phase['ISODISTORT'].update({ 'OccModeList' : modelist, 'G2OccModeList' : shortmodelist, 'OccVarList' : occVarLbl, 'G2OccVarList' : G2varObj, 'BaseOcc' : ParentCoordinates, 'Var2OccMatrix' : occupancymodeInvmatrix, 'Occ2VarMatrix' : occupancymodematrix, }) # make explaination dictionary for mode,shortmode in zip(modelist,shortmodelist): explaination[shortmode] = "ISODISTORT full name "+str(mode) #---------------------------------------------------------------------- # done with read #---------------------------------------------------------------------- if explaination: self.Constraints.append(explaination)