From ac448fd7d2e45706566469a08b61da2f1b96b44f Mon Sep 17 00:00:00 2001 From: JoshVStaden Date: Mon, 29 Jul 2019 14:47:02 +0200 Subject: [PATCH 1/6] Added support for Shapelet models. --- Tigger/Models/Formats/ASCII.py | 11 ++++++++++- Tigger/Models/ModelClasses.py | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Tigger/Models/Formats/ASCII.py b/Tigger/Models/Formats/ASCII.py index ff8cdb0..72d8a74 100644 --- a/Tigger/Models/Formats/ASCII.py +++ b/Tigger/Models/Formats/ASCII.py @@ -202,9 +202,12 @@ def getval(num, scale=1): polpa_field, polpa_scale = format.get('pol_pa_rad', None), 1 # fields for extent parameters extent_fields = [get_ang_field(x, ANGULAR_UNITS) for x in ('emaj', 'emin', 'pa')] + shapelet_fields = [get_ang_field(x, ANGULAR_UNITS) for x in ('sbetal', 'sbetam')] # all three must be present, else ignore if any([x[0] is None for x in extent_fields]): extent_fields = None + if any([x[0] is None for x in shapelet_fields]): + shapelet_fields = None # fields for reference freq and RM and SpI freq0_field = format.get('freq0', None) rm_field, rm_err_field = get_field('rm') @@ -307,16 +310,22 @@ def getval(num, scale=1): if any([x is not None for x in spi_err]): spectrum.spi_err = spi_err # see if we have extent parameters - ex = ey = pa = 0 + ex = ey = pa = beta_l = beta_m = shapelet_coeffs_l = shapelet_coeffs_m = 0 if extent_fields: ex, ey, pa = [(getval(x[0], x[1]) or 0) for x in extent_fields] extent_errors = [getval(x[2], x[3]) for x in extent_fields] + elif shapelet_fields: + (scoeffsl_field, _), (scoeffsm_field, _) = get_field("scoeffsl"), get_field("scoeffsm") + beta_l, beta_m = [(getval(s[0]) or 0) for s in shapelet_fields] + shapelet_coeffs_l, shapelet_coeffs_m = getval(scoeffsl_field), getval(scoeffsm_field) # form up shape object if (ex or ey) and max(ex, ey) >= min_extent: shape = ModelClasses.Gaussian(ex, ey, pa) for ifield, field in enumerate(['ex', 'ey', 'pa']): if extent_errors[ifield] is not None: shape.setAttribute(field + "_err", extent_errors[ifield]) + if (beta_l or beta_m or shapelet_coeffs_l or shapelet_coeffs_m): + shape = ModelClasses.Shapelet(beta_l, beta_m, shapelet_coeffs_l, shapelet_coeffs_m) else: shape = None # get tags diff --git a/Tigger/Models/ModelClasses.py b/Tigger/Models/ModelClasses.py index a2b04bd..f116259 100644 --- a/Tigger/Models/ModelClasses.py +++ b/Tigger/Models/ModelClasses.py @@ -442,6 +442,21 @@ def strDescErr(self, delimiters=('"', "x", "@", "deg"), **kw): err[0] * DEG * 3600, delimiters[0], delimiters[1], err[1] * DEG * 3600, delimiters[0], delimiters[2], round(err[2] * DEG), delimiters[3]) +class Shapelet(Shape): + typecode = "Sha" + + mandatory_attrs = ["sbetal", "sbetam", "scoeffsl", "scoeffsm"] + optional_attrs = dict(ex_err=None, ey_err=None, pa_err=None) + + def getShape(self): + return self.ex, self.ey, self.pa + + def getShapeErr(self): + err = [getattr(self, a + '_err', None) for a in self.mandatory_attrs] + if all([a is None for a in err]): + return None + return tuple(err) + class FITSImage(Shape): typecode = "FITS" From 775127e13edba6512ee761cf8572e7525b9c64a2 Mon Sep 17 00:00:00 2001 From: JoshVStaden Date: Fri, 2 Aug 2019 09:34:28 +0200 Subject: [PATCH 2/6] Changed shapelet coeffs field to read in a single list as a triangle. --- Tigger/Models/Formats/ASCII.py | 33 ++++++++++++++++++++++++++++++--- Tigger/Models/ModelClasses.py | 2 +- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/Tigger/Models/Formats/ASCII.py b/Tigger/Models/Formats/ASCII.py index 72d8a74..b447069 100644 --- a/Tigger/Models/Formats/ASCII.py +++ b/Tigger/Models/Formats/ASCII.py @@ -139,6 +139,19 @@ def get_ang_field(name, units=ANGULAR_UNITS): def getval(num, scale=1): return None if (num is None or len(fields) <= num) else float(fields[num]) * scale + def getval_list(num, scale=1): + return None if (num is None or len(fields) <= num) else [float(x) * scale for x in fields[num].split(',')] + + def triangular_index(val): + print("IN TRIANGULAR INDEX") + n = 1 + x = n + print("n, x", n, x) + while x < val: + n += 1 + x += n + return n + # now process file line-by-line linenum = 0 format_str = '' @@ -315,9 +328,23 @@ def getval(num, scale=1): ex, ey, pa = [(getval(x[0], x[1]) or 0) for x in extent_fields] extent_errors = [getval(x[2], x[3]) for x in extent_fields] elif shapelet_fields: - (scoeffsl_field, _), (scoeffsm_field, _) = get_field("scoeffsl"), get_field("scoeffsm") + (scoeffs_field, _) = get_field("shapelet_coeffs") beta_l, beta_m = [(getval(s[0]) or 0) for s in shapelet_fields] - shapelet_coeffs_l, shapelet_coeffs_m = getval(scoeffsl_field), getval(scoeffsm_field) + shapelet_coeffs_list = [float(x) for x in fields[scoeffs_field].split(',')] #getval_list(scoeffs_field) + + list_len = triangular_index(len(shapelet_coeffs_list)) + shapelet_coeffs = [[0.0 for _ in range(list_len)] for _ in range(list_len)] + max_val = 1 + i_ind = 0 + j_ind = 0 + for val in shapelet_coeffs_list: + shapelet_coeffs[i_ind][j_ind] = val + i_ind -= 1 + j_ind += 1 + if i_ind < 0: + i_ind = max_val + j_ind = 0 + max_val += 1 # form up shape object if (ex or ey) and max(ex, ey) >= min_extent: shape = ModelClasses.Gaussian(ex, ey, pa) @@ -325,7 +352,7 @@ def getval(num, scale=1): if extent_errors[ifield] is not None: shape.setAttribute(field + "_err", extent_errors[ifield]) if (beta_l or beta_m or shapelet_coeffs_l or shapelet_coeffs_m): - shape = ModelClasses.Shapelet(beta_l, beta_m, shapelet_coeffs_l, shapelet_coeffs_m) + shape = ModelClasses.Shapelet(beta_l, beta_m, shapelet_coeffs) else: shape = None # get tags diff --git a/Tigger/Models/ModelClasses.py b/Tigger/Models/ModelClasses.py index f116259..4f6dea6 100644 --- a/Tigger/Models/ModelClasses.py +++ b/Tigger/Models/ModelClasses.py @@ -445,7 +445,7 @@ def strDescErr(self, delimiters=('"', "x", "@", "deg"), **kw): class Shapelet(Shape): typecode = "Sha" - mandatory_attrs = ["sbetal", "sbetam", "scoeffsl", "scoeffsm"] + mandatory_attrs = ["sbetal", "sbetam", "shapelet_coeffs"] optional_attrs = dict(ex_err=None, ey_err=None, pa_err=None) def getShape(self): From 0965723c92340a59d8002bdfa11d751f9771dcd7 Mon Sep 17 00:00:00 2001 From: JoshVStaden Date: Mon, 5 Aug 2019 08:09:43 +0200 Subject: [PATCH 3/6] Replaced triangular_index with np.tril_indices --- Tigger/Models/Formats/ASCII.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/Tigger/Models/Formats/ASCII.py b/Tigger/Models/Formats/ASCII.py index b447069..de07b39 100644 --- a/Tigger/Models/Formats/ASCII.py +++ b/Tigger/Models/Formats/ASCII.py @@ -34,6 +34,7 @@ from Tigger.Models import ModelClasses from Tigger.Models import SkyModel from Tigger.Models.Formats import dprint, dprintf +import numpy as np DefaultDMSFormat = dict(name=0, ra_h=1, ra_m=2, ra_s=3, dec_d=4, dec_m=5, dec_s=6, @@ -141,16 +142,6 @@ def getval(num, scale=1): def getval_list(num, scale=1): return None if (num is None or len(fields) <= num) else [float(x) * scale for x in fields[num].split(',')] - - def triangular_index(val): - print("IN TRIANGULAR INDEX") - n = 1 - x = n - print("n, x", n, x) - while x < val: - n += 1 - x += n - return n # now process file line-by-line linenum = 0 @@ -332,7 +323,7 @@ def triangular_index(val): beta_l, beta_m = [(getval(s[0]) or 0) for s in shapelet_fields] shapelet_coeffs_list = [float(x) for x in fields[scoeffs_field].split(',')] #getval_list(scoeffs_field) - list_len = triangular_index(len(shapelet_coeffs_list)) + list_len = np.max(np.tril_indices(len(shapelet_coeffs_list))) shapelet_coeffs = [[0.0 for _ in range(list_len)] for _ in range(list_len)] max_val = 1 i_ind = 0 From 4161e46af01d9a10a564900735a5c3450bffd851 Mon Sep 17 00:00:00 2001 From: JoshVStaden Date: Thu, 8 Aug 2019 08:42:52 +0200 Subject: [PATCH 4/6] Changes to shapelet coefficient parsing. --- Tigger/Models/Formats/ASCII.py | 44 ++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/Tigger/Models/Formats/ASCII.py b/Tigger/Models/Formats/ASCII.py index de07b39..d180c26 100644 --- a/Tigger/Models/Formats/ASCII.py +++ b/Tigger/Models/Formats/ASCII.py @@ -142,6 +142,14 @@ def getval(num, scale=1): def getval_list(num, scale=1): return None if (num is None or len(fields) <= num) else [float(x) * scale for x in fields[num].split(',')] + + def upper_triangle_len(val): + n = 1 + x = n + while x < val: + n += 1 + x += n + return n # now process file line-by-line linenum = 0 @@ -321,21 +329,27 @@ def getval_list(num, scale=1): elif shapelet_fields: (scoeffs_field, _) = get_field("shapelet_coeffs") beta_l, beta_m = [(getval(s[0]) or 0) for s in shapelet_fields] - shapelet_coeffs_list = [float(x) for x in fields[scoeffs_field].split(',')] #getval_list(scoeffs_field) - - list_len = np.max(np.tril_indices(len(shapelet_coeffs_list))) - shapelet_coeffs = [[0.0 for _ in range(list_len)] for _ in range(list_len)] - max_val = 1 - i_ind = 0 - j_ind = 0 - for val in shapelet_coeffs_list: - shapelet_coeffs[i_ind][j_ind] = val - i_ind -= 1 - j_ind += 1 - if i_ind < 0: - i_ind = max_val - j_ind = 0 - max_val += 1 + scoeffs = fields[scoeffs_field] + shapelet_coeffs_list = None + shapelet_coeffs = None + if ',' in scoeffs: + shapelet_coeffs_list = [float(x) for x in scoeffs.split(',')] #getval_list(scoeffs_field) + sl_len = len(shapelet_coeffs_list) + list_len = upper_triangle_len(sl_len) + shapelet_coeffs = [[0.0 for _ in range(list_len)] for _ in range(list_len)] + max_val = 1 + i_ind = 0 + j_ind = 0 + for val in shapelet_coeffs_list: + shapelet_coeffs[i_ind][j_ind] = val + i_ind -= 1 + j_ind += 1 + if i_ind < 0: + i_ind = max_val + j_ind = 0 + max_val += 1 + else: + shapelet_coeffs = [[float(scoeffs)]] # form up shape object if (ex or ey) and max(ex, ey) >= min_extent: shape = ModelClasses.Gaussian(ex, ey, pa) From d2ad42f551c3be37ff4067da24230d6b6db9371f Mon Sep 17 00:00:00 2001 From: JoshVStaden Date: Wed, 4 Mar 2020 09:51:09 +0200 Subject: [PATCH 5/6] Fix bugs in ASCII.py. --- Tigger/Models/Formats/ASCII.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tigger/Models/Formats/ASCII.py b/Tigger/Models/Formats/ASCII.py index d180c26..5f0948a 100644 --- a/Tigger/Models/Formats/ASCII.py +++ b/Tigger/Models/Formats/ASCII.py @@ -356,7 +356,7 @@ def upper_triangle_len(val): for ifield, field in enumerate(['ex', 'ey', 'pa']): if extent_errors[ifield] is not None: shape.setAttribute(field + "_err", extent_errors[ifield]) - if (beta_l or beta_m or shapelet_coeffs_l or shapelet_coeffs_m): + elif (beta_l or beta_m or shapelet_coeffs_l or shapelet_coeffs_m): shape = ModelClasses.Shapelet(beta_l, beta_m, shapelet_coeffs) else: shape = None From 59f1f34a89347919a0ebadf8b7489a57447269d9 Mon Sep 17 00:00:00 2001 From: JoshVStaden Date: Wed, 4 Mar 2020 15:28:18 +0200 Subject: [PATCH 6/6] Changed shapelet format to be expressed in terms of ex and ey. --- Tigger/Models/Formats/ASCII.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Tigger/Models/Formats/ASCII.py b/Tigger/Models/Formats/ASCII.py index 5f0948a..3db4417 100644 --- a/Tigger/Models/Formats/ASCII.py +++ b/Tigger/Models/Formats/ASCII.py @@ -214,12 +214,10 @@ def upper_triangle_len(val): polpa_field, polpa_scale = format.get('pol_pa_rad', None), 1 # fields for extent parameters extent_fields = [get_ang_field(x, ANGULAR_UNITS) for x in ('emaj', 'emin', 'pa')] - shapelet_fields = [get_ang_field(x, ANGULAR_UNITS) for x in ('sbetal', 'sbetam')] - # all three must be present, else ignore - if any([x[0] is None for x in extent_fields]): + shape_field = get_field("shapelet_coeffs")#[get_ang_field(x, ANGULAR_UNITS) for x in ('sbetal', 'sbetam')] + # all three must be present, else ignore. The pa field can be None, if there is a shapelet_coeffs field + if any([x[0] is None for x in extent_fields]) and (any([x[0] is None for x in extent_fields[:2]]) or shape_field[0] is None ): extent_fields = None - if any([x[0] is None for x in shapelet_fields]): - shapelet_fields = None # fields for reference freq and RM and SpI freq0_field = format.get('freq0', None) rm_field, rm_err_field = get_field('rm') @@ -323,12 +321,12 @@ def upper_triangle_len(val): spectrum.spi_err = spi_err # see if we have extent parameters ex = ey = pa = beta_l = beta_m = shapelet_coeffs_l = shapelet_coeffs_m = 0 - if extent_fields: + if extent_fields and shape_field[0] is None: ex, ey, pa = [(getval(x[0], x[1]) or 0) for x in extent_fields] extent_errors = [getval(x[2], x[3]) for x in extent_fields] - elif shapelet_fields: - (scoeffs_field, _) = get_field("shapelet_coeffs") - beta_l, beta_m = [(getval(s[0]) or 0) for s in shapelet_fields] + elif extent_fields and shape_field: + scoeffs_field = shape_field[0] + beta_l, beta_m = [((getval(s[0], s[1]) * np.sqrt(2)) or 0) for s in extent_fields[:2]] scoeffs = fields[scoeffs_field] shapelet_coeffs_list = None shapelet_coeffs = None @@ -351,7 +349,7 @@ def upper_triangle_len(val): else: shapelet_coeffs = [[float(scoeffs)]] # form up shape object - if (ex or ey) and max(ex, ey) >= min_extent: + if (ex or ey) and max(ex, ey) >= min_extent and not (beta_l or beta_m): shape = ModelClasses.Gaussian(ex, ey, pa) for ifield, field in enumerate(['ex', 'ey', 'pa']): if extent_errors[ifield] is not None: