26 from cscripts
import calutils
34 Creates a calibration database entry for an IACT observation.
36 The creation of a calibration database entry is useful for performing
37 simulations for current Imaging Air Cherenkov Telescopes (IACTs).
38 The class takes an observation definition XML file as input and uses
39 one observation to create a calibration database entry. By default
40 the first observation will be used, but the user can specify the
41 index of any observation using the hidden "index" parameter.
50 self._init_csobservation(self.__class__.__name__, ctools.__version__, argv)
56 self.
_outfile = gammalib.GFilename(
'irf_file.fits')
70 Get parameters from parfile
73 ValueError, IndexError, & RuntimeError.
77 if self.obs().is_empty():
78 self.obs(gammalib.GObservations(self[
'inobs'].filename()))
81 if self.obs().is_empty():
82 raise ValueError(
'No or empty observation provided for '
86 index = self[
'index'].integer()
89 if index < 0
or index >= self.obs().size():
90 raise IndexError(
'Parameter "index=%d" outside the validity '
91 'range [0,%d].' % (index, self.obs().size()))
97 if not self._observation.classname() ==
'GCTAObservation':
98 raise RuntimeError(
'Input observation not of type '
103 if not self._observation.response().classname() ==
'GCTAResponseIrf':
104 raise RuntimeError(
'Response of input observation not of '
105 'type "GCTAResponseIrf".')
110 self.
_caldb = self[
'caldb'].string()
112 self.
_caldb = self._observation.instrument().lower()
115 self.
_outfile = self[
'outfile'].filename()
122 self[
'rootdir'].string()
125 self._log_parameters(gammalib.TERSE)
132 Creates an IRF FITS file
135 self._log_header2(gammalib.TERSE,
'Creating IRF file')
138 rsp = self._observation.response()
141 fname_aeff = rsp.aeff().filename()
142 fname_psf = rsp.psf().filename()
143 fname_edisp = rsp.edisp().filename()
144 fname_bkg = rsp.background().filename()
147 self._log_header3(gammalib.NORMAL,
'IRF input files')
148 self._log_value(gammalib.NORMAL,
'Effective area', fname_aeff.url())
149 self._log_value(gammalib.NORMAL,
'Point spread function', fname_psf.url())
150 self._log_value(gammalib.NORMAL,
'Energy dispersion', fname_edisp.url())
151 self._log_value(gammalib.NORMAL,
'Background rate', fname_bkg.url())
154 fits_aeff = gammalib.GFits(fname_aeff)
155 fits_psf = gammalib.GFits(fname_psf)
156 fits_edisp = gammalib.GFits(fname_edisp)
157 fits_bkg = gammalib.GFits(fname_bkg)
160 ext_aeff = fname_aeff.extname(
"EFFECTIVE AREA")
161 ext_psf = fname_psf.extname(
"POINT SPREAD FUNCTION")
162 ext_edisp = fname_edisp.extname(
"ENERGY DISPERSION")
163 ext_bkg = fname_bkg.extname(
"BACKGROUND")
166 fits = gammalib.GFits()
169 fits.append(fits_aeff[ext_aeff])
170 fits.append(fits_psf[ext_psf])
171 fits.append(fits_edisp[ext_edisp])
172 fits.append(fits_bkg[ext_bkg])
175 if self._logNormal():
178 if self._logExplicit():
179 self._log(str(fits[ext_aeff].header()))
181 self._log(str(fits[ext_psf].header()))
183 self._log(str(fits[ext_edisp].header()))
185 self._log(str(fits[ext_bkg].header()))
193 Creates an IRF index FITS file
196 self._log_header2(gammalib.TERSE,
'Creating database index file')
199 indx_file = self.
_base_dir +
'/caldb.indx'
202 cif = gammalib.GFits(indx_file,
True)
205 if cif.contains(
'CIF'):
206 table = cif.table(
'CIF')
212 table = cif.append(calutils.create_cif_table())
217 for caldir
in table[
'CAL_DIR']:
227 row_index = table.nrows()
235 row = i + row_index-4
238 now = str(datetime.datetime.now())
239 today, time = now.split()
242 table[
'TELESCOP'][row] = self.
_mission
243 table[
'INSTRUME'][row] = self.
_caldb
244 table[
'DETNAM'][row] =
'NONE'
245 table[
'FILTER'][row] =
'NONE'
246 table[
'CAL_DEV'][row] =
'ONLINE'
247 table[
'CAL_CLAS'][row] =
'BCF'
248 table[
'CAL_DTYP'][row] =
'DATA'
249 table[
'CAL_VSD'][row] = today
250 table[
'CAL_VST'][row] = time.split(
'.')[0]
251 table[
'REF_TIME'][row] = 51544.0
252 table[
'CAL_QUAL'][row] = 0
253 table[
'CAL_CBD'][row] =
'NAME('+self[
'irf'].string()+
')'
254 table[
'CAL_DATE'][row] = today.replace(
'-',
'/')[2:]
255 table[
'CAL_DIR'][row] = self.
_cal_dir
256 table[
'CAL_FILE'][row] = self.
_outfile
260 table[
'CAL_CNAM'][row] =
'EFF_AREA'
261 table[
'CAL_DESC'][row] = self.
_caldb+
' effective area'
265 table[
'CAL_CNAM'][row] =
'RPSF'
266 table[
'CAL_DESC'][row] = self.
_caldb+
' point spread function'
270 table[
'CAL_CNAM'][row] =
'EDISP'
271 table[
'CAL_DESC'][row] = self.
_caldb+
' energy dispersion'
275 table[
'CAL_CNAM'][row] =
'BKG'
276 table[
'CAL_DESC'][row] = self.
_caldb+
' background'
279 if self._logNormal():
280 self._log(str(table))
282 if self._logExplicit():
283 self._log(str(table.header()))
291 Make CALDB directories
294 self._log_header2(gammalib.TERSE,
'Creating directory structure')
297 caldb = gammalib.GCaldb(self[
'rootdir'].string())
301 self.
_cal_dir +=
'/'+self._mission.lower()
302 self.
_cal_dir +=
'/'+self._caldb.lower()
303 self.
_cal_dir +=
'/bcf/'+self[
'irf'].string()
306 self.
_base_dir = caldb.rootdir() +
'/data'
307 self.
_base_dir +=
'/'+self._mission.lower()
308 self.
_base_dir +=
'/'+self._caldb.lower()
314 self._log_value(gammalib.NORMAL,
'Calibration directory', self.
_cal_dir)
315 self._log_value(gammalib.NORMAL,
'Base directory', self.
_base_dir)
316 if not os.path.isdir(self.
_rsp_dir):
317 name =
'IRF directory'
319 name =
'IRF directory (existing)'
320 self._log_value(gammalib.NORMAL, name, self.
_rsp_dir)
323 if not os.path.isdir(self.
_rsp_dir):
339 self._log_header1(gammalib.TERSE,
'Creating CALDB entry')
355 Save calibration database FITS file
358 self._log_header1(gammalib.TERSE,
'Save calibration database')
364 self._log_value(gammalib.NORMAL,
'CALDB index file',
365 self._caldb_inx.filename().url())
366 self._log_value(gammalib.NORMAL,
'Response file', filename)
369 self._caldb_inx.save(self._clobber())
372 self._irf_fits.saveto(filename, self._clobber())
375 self._stamp(filename)
384 if __name__ ==
'__main__':