Source code for G2pwd_xye

# -*- coding: utf-8 -*-
########### SVN repository information ###################
# $Date: 2024-04-16 08:03:40 -0500 (Tue, 16 Apr 2024) $
# $Author: vondreele $
# $Revision: 5777 $
# $URL: https://subversion.xray.aps.anl.gov/pyGSAS/trunk/imports/G2pwd_xye.py $
# $Id: G2pwd_xye.py 5777 2024-04-16 13:03:40Z vondreele $
########### SVN repository information ###################
'''
'''

from __future__ import division, print_function
import os.path as ospath
import numpy as np
import GSASIIobj as G2obj
import GSASIIpath

asind = lambda x: 180.*np.arcsin(x)/np.pi

GSASIIpath.SetVersionNumber("$Revision: 5777 $")
[docs] class xye_ReaderClass(G2obj.ImportPowderData): 'Routines to import powder data from a .xye/.chi file' def __init__(self): super(self.__class__,self).__init__( # fancy way to self-reference extensionlist=('.xye','.qye','.chi','.qchi',), strictExtension=False, formatName = 'Topas xye or 2th Fit2D chi', longFormatName = 'Topas .xye/.qye or 2th Fit2D .chi/.qchi powder data file' ) self.scriptable = True # Validate the contents -- make sure we only have valid lines
[docs] def ContentsValidator(self, filename): '''Look through the file for expected types of lines in a valid Topas Fit2D or BNL/pyFAI file. Alas the latter two formats are somewhat in conflict. ''' gotCcomment = False self.minimalHeader = False # indicates a .chi file from BNL's pyFAI # which has less header info than from Fit2D begin = True self.GSAS = False self.Chi = False Qchi = False self.Wave = None fp = open(filename,'r') if '.chi' in filename: self.Chi = True if '.qchi' in filename: Qchi = True if2theta = False ifQ = False for i,S in enumerate(fp): if not S: # may not start with a blank line break if i > 1000: break if begin: if self.Chi or Qchi: if i < 4: if '2-theta' in S.lower(): if2theta = True elif 'chi_2theta' in S.lower(): # probably pyFAI w/o data type, assume 2theta if2theta = True self.minimalHeader = True elif 'q ' in S.lower(): ifQ = True wave = '' wave = S.split()[1:] if wave: try: self.Wave = float(wave[0]) except: pass if not self.Wave: self.errors = 'No wavelength in a Q chi file' fp.close() return False continue else: begin = False else: if2theta = True if i == 0 and 'xydata' in S.lower(): continue # fullprof header if gotCcomment and S.find('*/') > -1: begin = False continue if S.strip().startswith('/*'): gotCcomment = True continue if S[0] in ["'",'#','!']: if 'q' in S and not self.Wave: wave = S.split()[1] if wave: try: self.Wave = float(wave) except: self.Wave = 1.0 #special for POWGEN 1A-2A frame "pink" CW data continue #ignore comments, if any elif S.startswith('TITLE'): continue else: begin = False # valid line to read? #vals = S.split() if ifQ: pass elif not if2theta: self.errors = 'Not a 2-theta chi file' fp.close() return False vals = S.replace(',',' ').replace(';',' ').split() if len(vals) == 2 or len(vals) == 3: continue else: self.errors = 'Unexpected information in line: '+str(i+1) if all([ord(c) < 128 and ord(c) != 0 for c in str(S)]): # show only if ASCII self.errors += ' '+str(S) else: self.errors += ' (binary)' fp.close() return False fp.close() return True # no errors encountered
[docs] def Reader(self,filename, ParentFrame=None, **unused): 'Read a Topas file' x = [] y = [] w = [] gotCcomment = False begin = True fp = open(filename,'r') for i,S in enumerate(fp): self.errors = 'Error reading line: '+str(i+1) # or a block of comments delimited by /* and */ # or (GSAS style) each line can begin with '#' # or WinPLOTR style, a '!' if begin: if self.Chi: if self.minimalHeader and S.strip().startswith('#') and i < 6: self.comments.append(S[:-1]) continue elif self.minimalHeader: begin = False elif i < 4: continue else: begin = False else: if gotCcomment and S.find('*/') > -1: self.comments.append(S[:-1]) begin = False continue if S.strip().startswith('/*'): self.comments.append(S[:-1]) gotCcomment = True continue if S[0] in ["'",'#','!']: self.comments.append(S[:-1]) continue #ignore comments, if any elif i == 0 and 'xydata' in S.lower(): continue # fullprof header elif S.startswith('TITLE'): self.comments = [S] continue else: begin = False # valid line to read #vals = S.split() vals = S.replace(',',' ').replace(';',' ').split() if len(vals) < 2: print ('Line '+str(i+1)+' cannot be read:\n\t'+S) continue try: x.append(float(vals[0])) f = float(vals[1]) if f <= 0.0: y.append(0.0) w.append(0.0) elif len(vals) == 3: y.append(float(vals[1])) w.append(1.0/float(vals[2])**2) else: y.append(float(vals[1])) w.append(1.0/float(vals[1])) except ValueError: msg = 'Error parsing number in line '+str(i+1) if GSASIIpath.GetConfigValue('debug'): print (msg) print (S.strip()) break except: msg = 'Error in line '+str(i+1) if GSASIIpath.GetConfigValue('debug'): print (msg) print (S.strip()) break N = len(x) x = np.array(x) y = np.nan_to_num(np.array(y)) w = np.nan_to_num(np.array(w)) if self.Wave: #for q data val = self.Wave/(4.*np.pi/x) x = 2.0*asind(val) y *= 100. w /= 100**2 self.powderdata = [ x, # x-axis values y, # powder pattern intensities w, # 1/sig(intensity)^2 values (weights) np.zeros(N), # calc. intensities (zero) np.zeros(N), # calc. background (zero) np.zeros(N), # obs-calc profiles ] self.powderentry[0] = filename #self.powderentry[1] = pos # bank offset (N/A here) #self.powderentry[2] = 1 # xye file only has one bank self.idstring = ospath.basename(filename) # scan comments for temperature Temperature = 300 for S in self.comments: if 'temp' in S.lower().split('=')[0]: try: Temperature = float(S.split('=')[1]) except: pass self.Sample['Temperature'] = Temperature fp.close() return True