#!/usr/bin/env python # ========================================================================== # Merge model definition XML files # # Copyright (C) 2015-2018 Michael Mayer # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # ========================================================================== import os import sys import glob import gammalib import ctools # ================== # # csmodelmerge class # # ================== # class csmodelmerge(ctools.cscript): """ Merge model definition XML files An arbitrary number of model definition XML files will be merged into a single model definition XML file. """ # Constructor def __init__(self, *argv): """ Constructor. """ # Initialise application by calling the base class constructor self._init_cscript(self.__class__.__name__, ctools.__version__, argv) # Initialise class members self._files = None self._models = gammalib.GModels() # Return return # Private methods def _get_parameters(self): """ Get parameters from parfile """ # Get input models string inmodels = self['inmodels'].string() # Handle ASCII files. If the file names given in the ASCII are # relative filenames it is assumed that the filename is given # relative to the location of the file. if '@' == inmodels[0]: filename = inmodels.replace('@','') self._files = open(filename).read().splitlines() dirname = os.path.dirname(filename) files = [] for f in self._files: if f[0] != '/': fname = dirname + '/' + f else: fname = f files.append(fname) self._files = files # Handle wild card strings elif '*' in inmodels: self._files = glob.glob(inmodels) # Handle space separated list elif ' ' in inmodels: self._files = inmodels.split(' ') # Handle semi-colon separated list elif ';' in inmodels: self._files = inmodels.split(';') # Throw exception if input models cannot be decoded else: msg = 'Parameter "inmodels" must contain either an @ASCII '\ 'file, a semi-colon-separated or whitespace-separated '\ 'list of files or a wildcard string.' raise RuntimeError(msg) # Read ahead output filename if self._read_ahead(): self['outmodel'].filename() # Get clobber parameter self._clobber = self['clobber'].boolean() # Write input parameters into logger self._log_parameters(gammalib.TERSE) # Return return # Public methods def run(self): """ Run the script """ # Switch screen logging on in debug mode if self._logDebug(): self._log.cout(True) # Get parameters self._get_parameters() # Write header if self._logTerse(): self._log('\n') self._log.header1('Merge models') # Initialise model container self._models = gammalib.GModels() # Loop over model files for f in self._files: # Construct container from XML file models = gammalib.GModels(f) # Log number of models to add nmodels = models.size() if nmodels == 0: name = 'Add no model from file' elif nmodels == 1: name = 'Add 1 model from file' else: name = 'Add %d models from file' % nmodels self._log_value(gammalib.TERSE, name, f) # Extend model container by adding all models in the model file self._models.extend(models) # Log total number of models self._log_value(gammalib.TERSE, 'Models after merging', self._models.size()) # Return return def save(self): """ Save model definition XML file """ # Write header self._log_header1(gammalib.TERSE, 'Save models') # Get output filename in case it was not read ahead outmodel = self['outmodel'].filename() # If file exists and clobber flag is false then raise an exception if outmodel.exists() and not self._clobber: msg = ('Cannot save "'+outmodel.url()+'": File already exists. ' 'Use parameter clobber=yes to allow overwriting of files.') raise RuntimeError(msg) else: # Log filename self._log_value(gammalib.NORMAL, 'Model definition XML file', outmodel.url()) # Save models self._models.save(outmodel) # Return return # ======================== # # Main routine entry point # # ======================== # if __name__ == '__main__': # Create instance of application app = csmodelmerge(sys.argv) # Execute application app.execute()