ctools 2.1.0.dev
Loading...
Searching...
No Matches
csmodelmerge.py
Go to the documentation of this file.
1#!/usr/bin/env python
2# ==========================================================================
3# Merge model definition XML files
4#
5# Copyright (C) 2015-2022 Michael Mayer
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20# ==========================================================================
21import os
22import sys
23import glob
24import gammalib
25import ctools
26
27
28# ================== #
29# csmodelmerge class #
30# ================== #
31class csmodelmerge(ctools.cscript):
32 """
33 Merge model definition XML files
34
35 An arbitrary number of model definition XML files will be merged into
36 a single model definition XML file.
37 """
38
39 # Constructor
40 def __init__(self, *argv):
41 """
42 Constructor.
43 """
44 # Initialise application by calling the base class constructor
45 self._init_cscript(self.__class__.__name__, ctools.__version__, argv)
46
47 # Initialise class members
48 self._files = None
49 self._models = gammalib.GModels()
50
51 # Return
52 return
53
54
55 # Private methods
56 def _get_parameters(self):
57 """
58 Get parameters from parfile
59 """
60 # Get input models string
61 inmodels = self['inmodels'].string()
62
63 # Handle ASCII files. If the file names given in the ASCII are
64 # relative filenames it is assumed that the filename is given
65 # relative to the location of the file.
66 if '@' == inmodels[0]:
67 filename = inmodels.replace('@','')
68 self._files = open(filename).read().splitlines()
69 dirname = os.path.dirname(filename)
70 files = []
71 for f in self._files:
72 if f[0] != '/':
73 fname = dirname + '/' + f
74 else:
75 fname = f
76 files.append(fname)
77 self._files = files
78
79 # Handle wild card strings
80 elif '*' in inmodels:
81 self._files = glob.glob(inmodels)
82
83 # Handle space separated list
84 elif ' ' in inmodels:
85 self._files = inmodels.split(' ')
86
87 # Handle semi-colon separated list
88 elif ';' in inmodels:
89 self._files = inmodels.split(';')
90
91 # Throw exception if input models cannot be decoded
92 else:
93 msg = 'Parameter "inmodels" must contain either an @ASCII '\
94 'file, a semi-colon-separated or whitespace-separated '\
95 'list of files or a wildcard string.'
96 raise RuntimeError(msg)
97
98 # Read ahead output filename
99 if self._read_ahead():
100 self['outmodel'].filename()
101
102 # Get clobber parameter
103 self._clobber = self['clobber'].boolean()
104
105 # Write input parameters into logger
106 self._log_parameters(gammalib.TERSE)
107
108 # Return
109 return
110
111
112 # Public methods
113 def process(self):
114 """
115 Process the script
116 """
117 # Get parameters
118 self._get_parameters()
119
120 # Write header
121 if self._logTerse():
122 self._log('\n')
123 self._log.header1('Merge models')
124
125 # Initialise model container
126 self._models = gammalib.GModels()
127
128 # Loop over model files
129 for f in self._files:
130
131 # Construct container from XML file
132 models = gammalib.GModels(f)
133
134 # Log number of models to add
135 nmodels = models.size()
136 if nmodels == 0:
137 name = 'Add no model from file'
138 elif nmodels == 1:
139 name = 'Add 1 model from file'
140 else:
141 name = 'Add %d models from file' % nmodels
142 self._log_value(gammalib.TERSE, name, f)
143
144 # Extend model container by adding all models in the model file
145 self._models.extend(models)
146
147 # Log total number of models
148 self._log_value(gammalib.TERSE, 'Models after merging',
149 self._models.size())
150
151 # Return
152 return
153
154 def save(self):
155 """
156 Save model definition XML file
157 """
158 # Write header
159 self._log_header1(gammalib.TERSE, 'Save models')
160
161 # Get output filename in case it was not read ahead
162 outmodel = self['outmodel'].filename()
163
164 # If file exists and clobber flag is false then raise an exception
165 if outmodel.exists() and not self._clobber:
166 msg = ('Cannot save "'+outmodel.url()+'": File already exists. '
167 'Use parameter clobber=yes to allow overwriting of files.')
168 raise RuntimeError(msg)
169
170 else:
171
172 # Log filename
173 self._log_value(gammalib.NORMAL, 'Model definition XML file',
174 outmodel.url())
175
176 # Save models
177 self._models.save(outmodel)
178
179 # Return
180 return
181
182
183# ======================== #
184# Main routine entry point #
185# ======================== #
186if __name__ == '__main__':
187
188 # Create instance of application
189 app = csmodelmerge(sys.argv)
190
191 # Execute application
192 app.execute()