Source code for pyspextools.model.user

#!/usr/bin/env python

"""This is a module containing the necessary methods to
develop an executable for use with the SPEX user model.
"""

# Stuff to import for compatibility between python 2 and 3
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from builtins import int
from builtins import open
from builtins import str
from future import standard_library

from builtins import object

import sys
import math
import numpy

standard_library.install_aliases()


[docs]class User: """Class structure to contain the input and output parameters of the user function. :ivar npar: Numper of model input parameters from SPEX. :vartype npar: int :ivar par: Array containing the parameter values from SPEX (length npar). :vartype par: numpy.ndarray :ivar neg: Number of bins in the input energy grid from SPEX. :vartype neg: int :ivar egb: Upper boundaries of the energy bins (length neg). :vartype egb: numpy.ndarray :ivar eg: Bin centroids of the energy bins (length neg). :vartype eg: numpy.ndarray :ivar deg: Bin widths of the energy bins (length deg). :vartype deg: numpy.ndarray :ivar sener: Spectrum or transmission (e.g. in ph/s/bin) :vartype sener: numpy.ndarray :ivar wener: If Delta E = average photon energy within the bin (keV) minus the bin centroid then wener = sener * Delta E :vartype wener: numpy.ndarray :ivar fprm: Input file name from command line. :vartype fprm: str :ivar fspc: Output file name from command line. :vartype fspc: str """ def __init__(self): """Read the input file names from command line. Then read in the input parameters and energy grid from the SPEX provided input file.""" # Input parameters: self.npar = 0 # Number of input parameters from SPEX self.par = numpy.array([], dtype=float) # Array containing the parameter values from SPEX (length npar) self.neg = 0 # Number of bins in the input energy grid from SPEX self.egb = numpy.array([], dtype=float) # Upper boundaries of the energy bins (length neg) self.eg = numpy.array([], dtype=float) # Bin centroids of the energy bins (length neg) self.deg = numpy.array([], dtype=float) # Bin widths of the energy bins (length deg) # Output parameters: self.sener = numpy.array([], dtype=float) # Spectrum or transmission (e.g. in ph/s/bin) self.wener = numpy.array([], dtype=float) # If Delta E = average photon energy within the bin (keV) minus # the bin centroid then wener = sener * Delta E # Filenames: self.fprm = '' # Input file name self.fspc = '' # Output file name self.read_prm()
[docs] def read_prm(self): """Read the parameter file that SPEX creates at the beginning of the model evaluation. This is done automatically when the User class is initialised.""" try: self.fprm = sys.argv[1] except IndexError: print( "Error: Cannot read input filename from command line.\n Please only use this module in an executable.") sys.exit(1) try: self.fspc = sys.argv[2] except IndexError: print( "Error: Cannot read output filename from command line.\n Please only use this module in an executable.") sys.exit(1) # Open input file try: f = open(self.fprm, 'r') except IOError: print("Error: Input file does not exist...") sys.exit(1) # Read the number of parameters self.npar = int(f.readline()) # Allocate an array containing the parameters self.par = numpy.zeros(self.npar, dtype=float) # Read parameters into the array for the parameters spar = [] for _ in numpy.arange(math.ceil(self.npar / 5)): spar.append(str(f.readline()).split()) # Flatten list spar = sum(spar, []) for i in numpy.arange(self.npar): self.par[i] = float(spar[i]) # Read the number of model grid bins self.neg = int(f.readline()) # Allocate an array for the energy bin boundary egb, bin center eg, and delta e, deg self.egb = numpy.zeros(self.neg) self.eg = numpy.zeros(self.neg) self.deg = numpy.zeros(self.neg) # Read the energy grid from the input file for i in numpy.arange(self.neg): row = str(f.readline()).split() self.egb[i] = float(row[0]) self.eg[i] = float(row[1]) self.deg[i] = float(row[2]) # Close the file f.close() # Set size of sener and wener arrays self.sener = numpy.zeros(self.neg, dtype=float) self.wener = numpy.zeros(self.neg, dtype=float)
[docs] def write_spc(self): """Write the calculated spectrum to the output file for SPEX. Make sure that the sener and wener arrays are initialized and filled with a spectrum before calling this function.""" # Do some checks on the sener and wener arrays that should be set. if len(self.sener) == 0: print("Error: sener array not initialized yet.") sys.exit(1) if len(self.sener) != self.neg: print("Error: sener array has an incorrect size.") sys.exit(1) if len(self.wener) == 0: print("Error: wener array not initialized yet.") sys.exit(1) if len(self.wener) != self.neg: print("Error: wener array has an incorrect size.") sys.exit(1) # Open the output file try: f = open(self.fspc, 'w') except IOError: print("Error: unable to open output file.") sys.exit(1) # Write the number of model bins to the output file f.write(str(self.neg) + '\n') # Write the sener and wener columns to the output file for i in numpy.arange(self.neg): f.write(str(self.sener[i]) + ' ' + str(self.wener[i]) + '\n') # Close the file f.close() return