Source code for PyMca5.PyMcaPhysics.xrf.XRFMC.XRFMCHelper

#/*##########################################################################
#
# The PyMca X-Ray Fluorescence Toolkit
#
# Copyright (c) 2004-2016 European Synchrotron Radiation Facility
#
# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
# the ESRF by the Software group.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
#############################################################################*/
__author__ = "V.A. Sole - ESRF Data Analysis"
__contact__ = "sole@esrf.fr"
__license__ = "MIT"
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
import sys
import os
import tempfile
import subprocess
import time
import shutil
from PyMca5.PyMcaIO import ConfigDict
from . import XMSOParser

getXMSOFileFluorescenceInformation =\
                        XMSOParser.getXMSOFileFluorescenceInformation

XMIMSIM_PYMCA = None
if sys.platform == "win32":
    try:
        # try to get the installation directory from the registry
        if sys.version < '3.0':
            import _winreg as winreg
        else:
            import winreg
        HKLM = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
        try:
            # 32 bit
            softwareKey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "Software\XMI-MSIM")
        except:
            try:
                # 64 bit
                softwareKey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "Software\Wow6432Node\XMI-MSIM")
            except:
                # XMI-MSIM not installed ...
                softwareKey = None
        if softwareKey is not None:
            subKeyName = "InstallationDirectory"
            value = winreg.QueryValueEx(softwareKey, subKeyName)
            pathToExecutable = os.path.join(value[0], "bin", "xmimsim-pymca.exe")
            if not os.path.exists(pathToExecutable):
                pathToExecutable = None
            XMIMSIM_PYMCA = pathToExecutable
    except:
        # this cannot afford failing
        pass
else:
    try:
        testDirectories = ["/Applications", "/usr/local/bin", "/usr/bin", os.getcwd()]
        #look in the user PATH
        path = os.getenv('PATH')
        if path is not None:
            testDirectories += path.split(":")
        scriptName = "xmimsim-pymca"
        if sys.platform == "darwin":
            scriptName = os.path.join("XMI-MSIM.app",
                                      "Contents",
                                      "Resources",
                                       scriptName)
        for dirName in testDirectories:
            pathToExecutable = os.path.join(dirName, scriptName)
            if not os.path.exists(pathToExecutable):
                pathToExecutable = None
            else:
                break
        XMIMSIM_PYMCA = pathToExecutable
    except:
        # this cannot afford failing
        pass

[docs]def getScriptFile(pathToExecutable=None, args=None, name=None): if pathToExecutable is None: pathToExecutable = XMIMSIM_PYMCA if pathToExecutable is None: raise ValueError("Path to xmimsim-pymca needed") if not os.path.exists(pathToExecutable): raise IOError("xmimsim-pymca executable does not exist") if args is None: args = [] executable = os.path.basename(pathToExecutable) if not executable.startswith("xmimsim-pymca"): if sys.platform == "win32": raise ValueError("Path to xmimsim-pymca.exe needed") else: raise ValueError("Path to xmimsim-pymca needed") xmimsim_directory = os.path.dirname(pathToExecutable) if os.path.basename(xmimsim_directory).lower() == "bin": xmimsim_directory = os.path.dirname(xmimsim_directory) if sys.platform == "win32": binDir = os.path.join(xmimsim_directory, "bin") libDir = os.path.join(xmimsim_directory, "lib") gtk2Dir = os.path.join(xmimsim_directory, "GTK2") path = os.getenv("PATH") txt = "echo off\n" txt += "set PATH=%s;%s;%s;%s\n" % (binDir, libDir, gtk2Dir, os.getenv("PATH")) txt += "%s " % executable if len(args): for arg in args: txt += arg + " "; txt += "\n" else: txt += "%*" if name is None: handle, fullPath = tempfile.mkstemp(suffix=".bat", prefix="pymca", text=False) os.write(handle, txt) os.close(handle) else: fullPath = name if not fullPath.endswith(".bat"): fullPath = name + ".bat" if sys.version < '3.0': f = open(fullPath, "wb") else: f = open(fullPath, "w", newline='') f.write(txt) f.close() elif sys.platform == "darwin": #the bundle has everything needed txt = "#!/bin/bash\n" #this line is critical in order to avoid interference by the bundled PyMca txt += 'DYLD_LIBRARY_PATH=""\n' txt += "%s " % pathToExecutable if len(args): for arg in args: txt += arg + " "; txt += "\n" else: txt += "$*" if name is None: handle, fullPath = tempfile.mkstemp(suffix=".sh", prefix="pymca", text=False) os.write(handle, txt) os.close(handle) else: fullPath = name if not fullPath.endswith(".sh"): fullPath = name + ".sh" f = open(fullPath, "wb") f.write(txt) f.close() os.system("chmod +x %s" % fullPath) else: binDir = xmimsim_directory libDir = os.path.join(xmimsim_directory, "lib") path = os.getenv("PATH") txt = "#!/bin/bash\n" txt += "export PATH=%s:%s:%s\n" % (binDir, libDir, os.getenv("PATH")) txt += "%s " % executable if len(args): for arg in args: txt += arg + " "; txt += "\n" else: txt += "$*" if name is None: handle, fullPath = tempfile.mkstemp(suffix=".sh", prefix="pymca", text=False) os.write(handle, txt) os.close(handle) else: fullPath = name if not fullPath.endswith(".sh"): fullPath = name + ".sh" f = open(fullPath, "wb") f.write(txt) f.close() os.system("chmod +x %s" % fullPath) return fullPath
[docs]def getOutputFileNames(fitFile, outputDir=None): if outputDir is None: outputDir = os.path.dirname(fitFile) ddict = {} newFile = os.path.join(outputDir, os.path.basename(fitFile)) if newFile.lower().endswith(".fit"): rootName = newFile[:-4] elif newFile.lower().endswith(".cfg"): rootName = newFile[:-4] else: rootName = newFile scriptName = rootName + "_script" csvName = rootName + ".csv" speName = rootName + ".spe" xmsoName = rootName + ".xmso" if sys.platform == 'win32': scriptName = scriptName + ".bat" fitName = rootName + ".fit" ddict={} ddict['fit'] = rootName + ".fit" ddict['script'] = scriptName ddict['csv'] = csvName ddict['spe'] = speName ddict['xmso'] = xmsoName return ddict
[docs]def getXRFMCCorrectionFactors(fitConfiguration, xmimsim_pymca=None, verbose=False): outputDir=tempfile.mkdtemp(prefix="pymcaTmp") if 'result' in fitConfiguration: # we have to create a .fit file with the information ddict = ConfigDict.ConfigDict() ddict.update(fitConfiguration) else: # for the time being we have to build a "fit-like" file with the information import numpy from PyMca5.PyMca import ClassMcaTheory fitConfiguration['fit']['linearfitflag']=1 fitConfiguration['fit']['stripflag']=0 fitConfiguration['fit']['stripiterations']=0 xmin = fitConfiguration['fit']['xmin'] xmax = fitConfiguration['fit']['xmax'] #xdata = numpy.arange(xmin, xmax + 1) * 1.0 xdata = numpy.arange(0, xmax + 1) * 1.0 ydata = 0.0 + 0.1 * xdata mcaFit = ClassMcaTheory.McaTheory() mcaFit.configure(fitConfiguration) #a dummy time dummyTime = 1.0 if "concentrations" in fitConfiguration: dummyTime = fitConfiguration["concentrations"].get("time", dummyTime) mcaFit.setData(x=xdata, y=ydata, xmin=xmin, xmax=xmax, time=dummyTime) mcaFit.estimate() fitresult, result = mcaFit.startfit(digest=1) ddict=ConfigDict.ConfigDict() ddict['result'] = result ddict['xrfmc'] = fitConfiguration['xrfmc'] handle, fitFile = tempfile.mkstemp(suffix=".fit", prefix="pymca", dir=outputDir, text=False) os.close(handle) ddict.write(fitFile) ddict = None # we have the input file ready fileNamesDict = getOutputFileNames(fitFile, outputDir) scriptFile = getScriptFile(pathToExecutable=xmimsim_pymca, name=fileNamesDict['script']) xmsoName = fileNamesDict['xmso'] # basic parameters args = [scriptFile, "--enable-single-run", #"--set-threads=2", #"--verbose", #"--spe-file=%s" % speName, #"--csv-file=%s" % csvName, #"--enable-roi-normalization", #"--disable-roi-normalization", #default #"--enable-pile-up" #"--disable-pile-up" #default #"--enable-poisson", #"--disable-poisson", #default no noise #"--set-threads=2", #overwrite default maximum fitFile, xmsoName] if verbose: args.insert(2, "--verbose") process = subprocess.Popen(args, bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) while process.poll() is None: # process did not finish yet time.sleep(0.1) line = process.stdout.readline() if verbose: if len(line) > 1: print("OUTPUT = <%s>" % line[:-1]) returnCode = process.returncode line = process.stdout.readline() while len(line) > 1: if verbose: print("OUTPUT = %s" % line[:-1]) line = process.stdout.readline() if returnCode: text = "" line = process.stderr.readline() while len(line) > 1: text += line if verbose: print("ERROR = %s" % line[:-1]) line = process.stderr.readline() removeDirectory(outputDir) raise IOError("Program terminated with error code %d:\n%s" % (returnCode, text)) corrections = getXMSOFileFluorescenceInformation(xmsoName) xmsoName = None removeDirectory(outputDir) return corrections
[docs]def removeDirectory(dirName): if os.path.exists(dirName): if os.path.isdir(dirName): shutil.rmtree(dirName)
[docs]def start(fitFile, outputDir, xmimsim_pymca, parameters=None, verbose=True): args = XRFMCHelper.getBasicSubprocessCommand(fitFile, outputDir, xmimsim_pymca) if parameters is None: parameters = ["--enable-single-run", "--set-threads=2"] i = 0 for parameter in parameters: i += 1 args.insert(1, parameter) process = subprocess.Popen(args, bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) while process.poll() is None: # process did not finish yet time.sleep(0.1) line = process.stdout.readline() if verbose: if len(line) > 1: print("OUTPUT = <%s>" % line[:-1]) returnCode = process.returncode line = process.stdout.readline() while len(line) > 1: if verbose: print("OUTPUT = %s" % line[:-1]) line = process.stdout.readline() if returnCode: text = "" line = process.stderr.readline() while len(line) > 1: text += line if verbose: print("ERROR = %s" % line[:-1]) line = process.stderr.readline() raise IOError("Program terminated with error code %d:\n%s" % (returnCode, text))
[docs]def getBasicSubprocessCommand(fitFile, outputDir=None, xmimsim_pymca=None): ddict = getOutputFileNames(fitFile, outputDir) scriptFile = getScriptFile(pathToExecutable=xmimsim_pymca, name=ddict['script']) if ddict['fit'] != fitFile: if outputDir is None: # this should never happen raise ValueError("Inconsistent internal behaviour!") # recreate input in output directory new = ConfigDict.ConfigDict() new.read(fitFile) if os.path.exists(ddict['fit']): os.remove(ddict['fit']) new.write(ddict['fit']) new = None speName = ddict['spe'] csvName = ddict['csv'] newFitFile = ddict['fit'] xmsoName = ddict['xmsoName'] args = [scriptFile, #"--enable-single-run", "--verbose", "--spe-file=%s" % speName, "--csv-file=%s" % csvName, #"--enable-roi-normalization", #"--disable-roi-normalization", #default #"--enable-pile-up" #"--disable-pile-up" #default #"--enable-poisson", #"--disable-poisson", #default no noise #"--set-threads=2", #overwrite default maximum newFitFile, xmsoName] return args
[docs]def test(filename): fitConfig = ConfigDict.ConfigDict() fitConfig.read(filename) ddict = getXRFMCCorrectionFactors(fitConfig, verbose=True) fitConfig = None for element in ddict: for line in ddict[element]: if line == "z": #atomic number continue if line in ['K', 'Ka', 'Kb', 'L', 'L1', 'L2', 'L3', 'M']: correction1 = ddict[element][line]['correction_factor'][1] correctionn = ddict[element][line]['correction_factor'][-1] print("Element %s Line %s Correction 2 = %f Correction n = %f" %\ (element, line,correction1, correctionn))
if __name__ == "__main__": if len(sys.argv) > 1: test(sys.argv[1]) else: print("Usage:") print("python XRFMCHelper.py path_to_cfg_or_fit_file")