From 8d250ac361c7ab3ff51c64e1cd3b601fca9bba21 Mon Sep 17 00:00:00 2001 From: Jürgen Knödlseder Date: Fri, 20 Oct 2017 18:26:38 +0200 Subject: [PATCH] Remove code duplication is cslightcrv and csphasecrv --- cscripts/cslightcrv.py | 61 +++++++++++++++++-------------------------------------------- cscripts/csphasecrv.py | 37 +++++++++++-------------------------- cscripts/ioutils.py | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- sonar-project.properties | 2 +- 4 files changed, 116 insertions(+), 72 deletions(-) diff --git a/cscripts/cslightcrv.py b/cscripts/cslightcrv.py index a44861b..b032b00 100755 --- a/cscripts/cslightcrv.py +++ b/cscripts/cslightcrv.py @@ -22,6 +22,7 @@ import sys import gammalib import ctools from cscripts import obsutils +from cscripts import ioutils # ================ # @@ -281,52 +282,24 @@ class cslightcrv(ctools.cscript): table = gammalib.GFitsBinTable(nrows) table.extname('LIGHTCURVE') - # Append time columns "MJD" and "e_MJD" - mjd = gammalib.GFitsTableDoubleCol('MJD', nrows) - e_mjd = gammalib.GFitsTableDoubleCol('e_MJD', nrows) - mjd.unit('days') - e_mjd.unit('days') - for i, result in enumerate(results): - mjd[i] = result['mjd'] - e_mjd[i] = result['e_mjd'] - table.append(mjd) - table.append(e_mjd) - - # Create parameter columns - for par in self._obs.models()[self._srcname]: - if par.is_free(): - name = par.name() - e_name = 'e_'+par.name() - col = gammalib.GFitsTableDoubleCol(name, nrows) - e_col = gammalib.GFitsTableDoubleCol(e_name, nrows) - col.unit(par.unit()) - e_col.unit(par.unit()) - for i, result in enumerate(results): - col[i] = result['values'][name] - e_col[i] = result['values'][e_name] - table.append(col) - table.append(e_col) + # Append time columns + ioutils.append_result_column(table, results, 'MJD', 'days', 'mjd') + ioutils.append_result_column(table, results, 'e_MJD', 'days', 'e_mjd') + + # Append parameter columns + ioutils.append_model_par_column(table, self._obs.models()[self._srcname], + results) # Append Test Statistic column "TS" - ts = gammalib.GFitsTableDoubleCol('TS', nrows) - for i, result in enumerate(results): - ts[i] = result['ts'] - table.append(ts) - - # Append upper limit column "UpperLimit" - ul_diff = gammalib.GFitsTableDoubleCol('DiffUpperLimit', nrows) - ul_flux = gammalib.GFitsTableDoubleCol('FluxUpperLimit', nrows) - ul_eflux = gammalib.GFitsTableDoubleCol('EFluxUpperLimit', nrows) - ul_diff.unit('ph/cm2/s/MeV') - ul_flux.unit('ph/cm2/s') - ul_eflux.unit('erg/cm2/s') - for i, result in enumerate(results): - ul_diff[i] = result['ul_diff'] - ul_flux[i] = result['ul_flux'] - ul_eflux[i] = result['ul_eflux'] - table.append(ul_diff) - table.append(ul_flux) - table.append(ul_eflux) + ioutils.append_result_column(table, results, 'TS', '', 'ts') + + # Append upper limit columns + ioutils.append_result_column(table, results, 'DiffUpperLimit', + 'ph/cm2/s/MeV', 'ul_diff') + ioutils.append_result_column(table, results, 'FluxUpperLimit', + 'ph/cm2/s', 'ul_flux') + ioutils.append_result_column(table, results, 'EFluxUpperLimit', + 'erg/cm2/s', 'ul_eflux') # Return table return table diff --git a/cscripts/csphasecrv.py b/cscripts/csphasecrv.py index 967d3b2..7b3b3be 100755 --- a/cscripts/csphasecrv.py +++ b/cscripts/csphasecrv.py @@ -22,6 +22,7 @@ import sys import gammalib import ctools from cscripts import obsutils +from cscripts import ioutils # ================ # @@ -183,7 +184,7 @@ class csphasecrv(ctools.cscript): def _create_fits_table(self, results): """ - Creates FITS binary table containing light curve results + Creates FITS binary table containing phase curve results Parameters ---------- @@ -193,7 +194,7 @@ class csphasecrv(ctools.cscript): Returns ------- table : `~gammalib.GFitsBinTable` - FITS binary table containing light curve + FITS binary table containing phase curve """ # Determine number of rows in FITS table nrows = len(results) @@ -202,29 +203,13 @@ class csphasecrv(ctools.cscript): table = gammalib.GFitsBinTable(nrows) table.extname('PHASECURVE') - # Append phase columns "PHASE_MIN" and "PHASE_MAX" - phmin = gammalib.GFitsTableDoubleCol('PHASE_MIN', nrows) - phmax = gammalib.GFitsTableDoubleCol('PHASE_MAX', nrows) - for i, result in enumerate(results): - phmin[i] = result['phmin'] - phmax[i] = result['phmax'] - table.append(phmin) - table.append(phmax) + # Append phase columns + ioutils.append_result_column(table, results, 'PHASE_MIN', '', 'phmin') + ioutils.append_result_column(table, results, 'PHASE_MAX', '', 'phmax') - # Create parameter columns - for par in self._obs.models()[self._srcname]: - if par.is_free(): - name = par.name() - e_name = 'e_'+par.name() - col = gammalib.GFitsTableDoubleCol(name, nrows) - e_col = gammalib.GFitsTableDoubleCol(e_name, nrows) - col.unit(par.unit()) - e_col.unit(par.unit()) - for i, result in enumerate(results): - col[i] = result['values'][name] - e_col[i] = result['values'][e_name] - table.append(col) - table.append(e_col) + # Append parameter columns + ioutils.append_model_par_column(table, self._obs.models()[self._srcname], + results) # Return table return table @@ -401,7 +386,7 @@ class csphasecrv(ctools.cscript): # Create FITS file self._create_fits() - # Optionally publish light curve + # Optionally publish phase curve if self['publish'].boolean(): self.publish() @@ -433,7 +418,7 @@ class csphasecrv(ctools.cscript): # Write header self._log_header1(gammalib.TERSE, 'Publish phase curve') - # Continue only if light curve is valid + # Continue only if phase curve is valid if self._fits.contains('PHASECURVE'): # Set default name is user name is empty diff --git a/cscripts/ioutils.py b/cscripts/ioutils.py index 919d028..8dae0a6 100755 --- a/cscripts/ioutils.py +++ b/cscripts/ioutils.py @@ -1,7 +1,7 @@ # ========================================================================== # Utility functions for input and output # -# Copyright (C) 2016 Juergen Knoedlseder +# Copyright (C) 2016-2017 Juergen Knoedlseder # # 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 @@ -193,3 +193,89 @@ def get_args_options(options, usage): # Return arguments and options return args, options + + +# =========================================== # +# Append model parameter column to FITS table # +# =========================================== # +def append_result_column(table, results, name, unit, key): + """ + Append result column to FITS table + + Parameters + ---------- + table : `~gammalib.GFitsTable` + FITS table + results : list of dict + Parameter values + name : str + Column name + unit : str + Column unit + key : str + Result key + """ + # Determine number of rows in FITS table + nrows = len(results) + + # Allocate double precision column and set units + col = gammalib.GFitsTableDoubleCol(name, nrows) + col.unit(unit) + + # Fill results in columns + for i, result in enumerate(results): + col[i] = result[key] + + # Append column to table + table.append(col) + + # Return + return + + +# =========================================== # +# Append model parameter column to FITS table # +# =========================================== # +def append_model_par_column(table, model, results): + """ + Append model parameter column to FITS table + + Parameters + ---------- + table : `~gammalib.GFitsTable` + FITS table + model : `~gammalib.GModel` + Model + results : list of dict + Parameter values + """ + # Determine number of rows in FITS table + nrows = len(results) + + # Loop over all parameters in model + for par in model: + + # Append parameter column only if model parameter is free + if par.is_free(): + + # Set column names + name = par.name() + e_name = 'e_'+par.name() + + # Allocate double precision columns and set units + col = gammalib.GFitsTableDoubleCol(name, nrows) + e_col = gammalib.GFitsTableDoubleCol(e_name, nrows) + col.unit(par.unit()) + e_col.unit(par.unit()) + + # Fill results in columns + for i, result in enumerate(results): + col[i] = result['values'][name] + e_col[i] = result['values'][e_name] + + # Append columns to table + table.append(col) + table.append(e_col) + + # Return + return diff --git a/sonar-project.properties b/sonar-project.properties index 13d21e0..80943b4 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -21,7 +21,7 @@ sonar.cxx.missingIncludeWarnings=False # Exclusions sonar.exclusions=cscripts/tests/**,pyext/build/**,pyext/ctools/tools.py,pyext/ctools/*_wrap.cpp,pyext/ctools/tests/**,dev/**,doc/**,test/dev/** -sonar.coverage.exclusions=test/science_verification.py,test/test_examples.py +sonar.coverage.exclusions=test/science_verification.py,test/test_examples.py,pyext/setup.py sonar.cpd.exclusions=examples/**,test/**,pyext/ctools/tools.py # C++ configuration -- libgit2 0.21.4