-
Notifications
You must be signed in to change notification settings - Fork 122
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement LoadFullprofFile. Refs #6750.
- Loading branch information
Showing
3 changed files
with
479 additions
and
0 deletions.
There are no files selected for viewing
315 changes: 315 additions & 0 deletions
315
Code/Mantid/Framework/PythonInterface/PythonAlgorithms/LoadFullprofFile.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,315 @@ | ||
"""*WIKI* | ||
This algorithm is to import Fullprof .irf file (peak parameters) and .hkl file (reflections) and | ||
record the information to TableWorkspaces, which serve as the inputs for algorithm LeBailFit. | ||
==== Format of Instrument parameter TableWorkspace ==== | ||
Instrument parameter TableWorkspace contains all the peak profile parameters imported from Fullprof .irf file. | ||
Presently these are the peak profiles supported | ||
* Thermal neutron back to back exponential convoluted with pseudo-voigt (profile No. 10 in Fullprof) | ||
Each row in TableWorkspace corresponds to one profile parameter. | ||
Columns include Name, Value, FitOrTie, Min, Max and StepSize. | ||
==== Format of reflection TableWorkspace ==== | ||
Each row of this workspace corresponds to one diffraction peak. | ||
The information contains the peak's Miller index and (local) peak profile parameters of this peak. | ||
For instance of a back-to-back exponential convoluted with Gaussian peak, | ||
the peak profile parameters include Alpha, Beta, Sigma, centre and height. | ||
== How to use algorithm with other algorithms == | ||
This algorithm is designed to work with other algorithms to do Le Bail fit. The introduction can be found in the wiki page of [[LeBailFit]]. | ||
*WIKI*""" | ||
from mantid.api import PythonAlgorithm, registerAlgorithm, ITableWorkspaceProperty, WorkspaceFactory, FileProperty, FileAction, MatrixWorkspaceProperty, WorkspaceProperty | ||
from mantid.kernel import Direction, StringListValidator | ||
|
||
import mantid.simpleapi as api | ||
|
||
_OUTPUTLEVEL = "NOOUTPUT" | ||
|
||
class LoadFullprofFile(PythonAlgorithm): | ||
""" Create the input TableWorkspaces for LeBail Fitting | ||
""" | ||
def category(self): | ||
""" | ||
""" | ||
return "Diffraction;Utility" | ||
|
||
def name(self): | ||
""" | ||
""" | ||
return "LoadFullprofFile" | ||
|
||
def PyInit(self): | ||
""" Declare properties | ||
""" | ||
self.setWikiSummary("""Load file generated by Fullprof.""") | ||
|
||
self.declareProperty(FileProperty("Filename","", FileAction.Load, ['.hkl', '.prf']), | ||
"Name of [http://www.ill.eu/sites/fullprof/ Fullprof] .hkl or .prf file.") | ||
|
||
#self.declareProperty("Bank", 1, "Bank ID for output if there are more than one bank in .irf file.") | ||
|
||
self.declareProperty(ITableWorkspaceProperty("PeakParameterWorkspace", "", Direction.Output), | ||
"Name of table workspace containing peak parameters from .hkl file.") | ||
|
||
self.declareProperty(MatrixWorkspaceProperty("OutputWorkspace", "", Direction.Output), | ||
"Name of data workspace containing the diffraction pattern in .prf file. ") | ||
|
||
return | ||
|
||
def PyExec(self): | ||
""" Main Execution Body | ||
""" | ||
# 1. Properties | ||
fpfilename = self.getPropertyValue("Filename") | ||
|
||
# 2. Import | ||
if fpfilename.lower().endswith(".hkl") is True: | ||
# (.hkl) file | ||
self._tableWS = self._loadFPHKLFile(fpfilename) | ||
self._dataWS = self._makeEmptyDataWorkspace() | ||
elif fpfilename.lower().endswith(".prf") is True: | ||
# (.prf) file | ||
self._tableWS, self._dataWS= self._loadFullprofPrfFile(fpfilename) | ||
else: | ||
raise NotImplementedError("File %s is neither .hkl nor .prf. It is not supported." % (fpfilename)) | ||
|
||
# 3. Export | ||
self.setProperty("PeakParameterWorkspace", self._tableWS) | ||
self.setProperty("OutputWorkspace", self._dataWS) | ||
|
||
return | ||
|
||
|
||
def _loadFPHKLFile(self, filename): | ||
""" Load Fullprof .hkl file to a TableWorkspace | ||
""" | ||
# 1. Import to a dictionary | ||
hkldict = self._importFullprofHKLFile(filename) | ||
|
||
# 2. Create workspace from dictionary | ||
peakws = self._createReflectionWorkspace(hkldict) | ||
|
||
return peakws | ||
|
||
|
||
def _importFullprofHKLFile(self, hklfilename): | ||
""" Import Fullprof's .hkl file | ||
""" | ||
import math | ||
# 1. Import file | ||
try: | ||
hklfile = open(hklfilename, "r") | ||
lines = hklfile.readlines() | ||
hklfile.close() | ||
except IOError: | ||
print "Error to open/read Fullprof .hkl file %s" % (hklfilename) | ||
raise IOError() | ||
|
||
# 2. Parse | ||
hkldict = {} | ||
for line in lines: | ||
# a) Clean & split | ||
line = line.strip() | ||
if len(line) == 0: | ||
continue | ||
terms = line.split() | ||
|
||
# b) parse | ||
if not terms[0].isdigit(): | ||
# Comment line | ||
continue | ||
|
||
h = int(terms[0]) | ||
k = int(terms[1]) | ||
l = int(terms[2]) | ||
if len(terms) >= 9: | ||
dsp = float(terms[3]) | ||
tof = float(terms[4]) | ||
alpha = float(terms[5]) | ||
beta = float(terms[6]) | ||
sigma2 = float(terms[7]) | ||
gamma2 = float(terms[8]) | ||
else: | ||
dsp = 0.0 | ||
tof = 0.0 | ||
alpha = 0.0 | ||
beta = 0.0 | ||
sigma2 = 0.0 | ||
gamma2 = 0.0 | ||
fwhm = 1.0 | ||
|
||
if len(terms) >= 13: | ||
fwhm = float(terms[12]) | ||
elif len(terms) >= 9: | ||
fwhm = math.sqrt(sigma2)*2.0 | ||
|
||
dkey = (h, k, l) | ||
|
||
if hkldict.has_key(dkey): | ||
if _OUTPUTLEVEL == "INFORMATION": | ||
print "Warning! Duplicate HKL %d, %d, %d" (h, k, l) | ||
continue | ||
|
||
if fwhm < 1.0E-5: | ||
# Peak width is too small/annihilated peak | ||
if _OUTPUTLEVEL == "INFORMATION": | ||
print "Peak (%d, %d, %d) has an unreasonable small FWHM. Peak does not exist. " % (h, k, l) | ||
continue | ||
|
||
hkldict[dkey] = {} | ||
hkldict[dkey]["dsp"] = dsp | ||
hkldict[dkey]["tof"] = tof | ||
hkldict[dkey]["alpha"] = alpha | ||
hkldict[dkey]["beta"] = beta | ||
hkldict[dkey]["sigma2"] = sigma2 | ||
hkldict[dkey]["gamma2"] = gamma2 | ||
hkldict[dkey]["FWHM"] = fwhm | ||
# ENDFOR: line | ||
|
||
print "Import Fullprof reflection file %s successfully. " % (hklfilename) | ||
|
||
return hkldict | ||
|
||
def _createReflectionWorkspace(self, hkldict): | ||
""" Create TableWorkspace containing reflections and etc. | ||
""" | ||
# 1. Set up columns | ||
tablews = WorkspaceFactory.createTable() | ||
|
||
tablews.addColumn("int", "H"); | ||
tablews.addColumn("int", "K"); | ||
tablews.addColumn("int", "L"); | ||
tablews.addColumn("double", "Alpha"); | ||
tablews.addColumn("double", "Beta"); | ||
tablews.addColumn("double", "Sigma2"); | ||
tablews.addColumn("double", "Gamma"); | ||
tablews.addColumn("double", "FWHM"); | ||
tablews.addColumn("double", "PeakHeight"); | ||
|
||
# 2. Add rows | ||
for hkl in sorted(hkldict.keys()): | ||
pardict = hkldict[hkl] | ||
tablews.addRow([hkl[0], hkl[1], hkl[2], pardict["alpha"], pardict["beta"], pardict["sigma2"], pardict["gamma2"], pardict["FWHM"], 1.0]) | ||
# ENDFOR | ||
|
||
return tablews | ||
|
||
|
||
def _loadFullprofPrfFile(self, prffilename): | ||
""" Load Fullprof .prf file | ||
""" | ||
# 1. Parse the file to dictionary | ||
infodict, data = self._parseFullprofPrfFile(prffilename) | ||
|
||
# 2. Export information to table file | ||
tablews = WorkspaceFactory.createTable() | ||
tablews.addColumn("str", "Name") | ||
tablews.addColumn("double", "Value") | ||
for parname in infodict.keys(): | ||
parvalue = infodict[parname] | ||
tablews.addRow([parname, parvalue]) | ||
|
||
# 3. Export the data workspace | ||
datasize = len(data) | ||
print "Data Size = ", datasize | ||
dataws = WorkspaceFactory.create("Workspace2D", 4, datasize, datasize) | ||
for i in xrange(datasize): | ||
for j in xrange(4): | ||
dataws.dataX(j)[i] = data[i][0] | ||
dataws.dataY(j)[i] = data[i][j+1] | ||
dataws.dataE(j)[i] = 1.0 | ||
|
||
return (tablews, dataws) | ||
|
||
|
||
def _parseFullprofPrfFile(self, filename): | ||
""" Parse Fullprof .prf file to a information dictionary and a data set (list of list) | ||
""" | ||
# 1. Import file | ||
try: | ||
pfile = open(filename, "r") | ||
except IOError: | ||
raise NotImplementedError("Unable to open .prf file %s" % (filename)) | ||
|
||
rawlines = pfile.readlines() | ||
lines = [] | ||
for l in rawlines: | ||
line = l.strip() | ||
if len(line) > 0: | ||
lines.append(line) | ||
|
||
infodict = {} | ||
dataset = [] | ||
|
||
# 2. Parse information line | ||
infoline = lines[0] | ||
if infoline.count("CELL:") == 1: | ||
terms = infoline.split("CELL:")[1].split() | ||
a = float(terms[0]) | ||
b = float(terms[1]) | ||
c = float(terms[2]) | ||
alpha = float(terms[3]) | ||
beta = float(terms[4]) | ||
gamma = float(terms[5]) | ||
infodict["A"] = float(a) | ||
infodict["B"] = float(b) | ||
infodict["C"] = float(c) | ||
infodict["Alpha"] = float(alpha) | ||
infodict["Beta"] = float(beta ) | ||
infodict["Gamma"] = float(gamma) | ||
#if infoline.count("SPGR:") == 1: | ||
# terms = infoline.split("SPGR:") | ||
# spacegroup = terms[1].strip() | ||
# infodict["SpaceGroup"] = spacegroup | ||
|
||
# 3. Parse data | ||
firstline = -1 | ||
for i in xrange(1, len(lines)): | ||
if lines[i].startswith("T.O.F"): | ||
firstline = i+1 | ||
break | ||
|
||
if firstline < 0: | ||
raise NotImplementedError("File format is incorrect. Unable to locate data title line") | ||
|
||
|
||
count = 0 | ||
for i in xrange(firstline, len(lines)): | ||
terms = lines[i].split() | ||
if len(terms) == 5 and lines[i].count(")") == 0: | ||
# it is a data line | ||
x = float(terms[0]) | ||
yobs = float(terms[1]) | ||
ycal = float(terms[2]) | ||
ydif = float(terms[3]) | ||
ybak = float(terms[4]) | ||
|
||
dataset.append([x, yobs, ycal, ydif, ybak]) | ||
count += 1 | ||
|
||
else: | ||
break | ||
# ENDFOR | ||
|
||
print "Data set counter = ", count | ||
|
||
return (infodict, dataset) | ||
|
||
|
||
def _makeEmptyDataWorkspace(self): | ||
""" Make an empty data workspace (Workspace2D) | ||
""" | ||
dataws = WorkspaceFactory.create("Workspace2D", 1, 1, 1) | ||
|
||
return dataws | ||
|
||
|
||
# Register algorithm with Mantid | ||
registerAlgorithm(LoadFullprofFile) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.