Skip to content

Commit e96e2eb

Browse files
authored
Merge pull request #191 from transientskp/Fix_188
Closes #188
2 parents 2bfff3e + 8aeeecb commit e96e2eb

1 file changed

Lines changed: 94 additions & 87 deletions

File tree

sourcefinder/measure.py

Lines changed: 94 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -165,57 +165,61 @@ def moments(data, fudge_max_pix_factor, beam, beamsize, threshold=0):
165165

166166
rounded_barycenter = int(round(xbar)), int(round(ybar))
167167
# basevalue and basepos will be needed for "tweaked moments".
168+
in_source_island = False
168169
try:
169170
if not data.mask[rounded_barycenter]:
170-
basepos = rounded_barycenter
171-
else:
172-
basepos = maxpos
171+
in_source_island = True
173172
except IndexError:
174-
basepos = maxpos
173+
# rounded_barycenter is not part of the island.
174+
pass
175175
except AttributeError:
176176
# If the island is not masked at all, we can safely set basepos to
177177
# the rounded barycenter position.
178+
in_source_island = True
179+
180+
if in_source_island:
178181
basepos = rounded_barycenter
179-
basevalue = data[basepos]
180-
181-
if np.sign(threshold) == np.sign(basevalue):
182-
# Implementation of "tweaked moments", equation 2.67 from
183-
# Spreeuw's thesis. In that formula the "base position" was the
184-
# maximum pixel position, though. Here that is the rounded
185-
# barycenter position, unless it's masked. If it's masked, it
186-
# will be the maximum pixel position.
187-
deltax, deltay = xbar - basepos[0], ybar - basepos[1]
182+
basevalue = data[basepos]
188183

189-
epsilon = np.log(2.0) * (
190-
(np.cos(theta) * deltax + np.sin(theta) * deltay) ** 2
191-
+ (np.cos(theta) * deltay - np.sin(theta) * deltax) ** 2
192-
* semiminor_tmp
193-
/ semimajor_tmp
194-
)
184+
if np.sign(threshold) == np.sign(basevalue):
185+
# Implementation of "tweaked moments", equation 2.67 from
186+
# Spreeuw's thesis. In that formula the "base position" was the
187+
# maximum pixel position, though. Here that is the rounded
188+
# barycenter position, unless it's masked or not part of the island.
189+
# In those cases no "tweaked moments" extrapolation will be
190+
# applied, and we revert to data.max() * fudge_max_pix.
191+
deltax, deltay = xbar - basepos[0], ybar - basepos[1]
192+
193+
epsilon = np.log(2.0) * (
194+
(np.cos(theta) * deltax + np.sin(theta) * deltay) ** 2
195+
+ (np.cos(theta) * deltay - np.sin(theta) * deltax) ** 2
196+
* semiminor_tmp
197+
/ semimajor_tmp
198+
)
195199

196-
# Set limits for the root finder similar to the bounds for
197-
# Gaussian fits.
198-
if basevalue > 0:
199-
low_bound = 0.5 * basevalue
200-
upp_bound = 1.5 * basevalue
201-
else:
202-
low_bound = 1.5 * basevalue
203-
upp_bound = 0.5 * basevalue
204-
205-
# The number of iterations used for the root finder is also
206-
# returned, but not used here.
207-
peak, _ = newton_raphson_root_finder(
208-
find_true_peak,
209-
basevalue,
210-
low_bound,
211-
upp_bound,
212-
1e-8,
213-
100,
214-
threshold,
215-
epsilon,
216-
semiminor_tmp,
217-
basevalue,
218-
)
200+
# Set limits for the root finder similar to the bounds for
201+
# Gaussian fits.
202+
if basevalue > 0:
203+
low_bound = 0.5 * basevalue
204+
upp_bound = 2.0 * basevalue
205+
else:
206+
low_bound = 2.0 * basevalue
207+
upp_bound = 0.5 * basevalue
208+
209+
# The number of iterations used for the root finder is also
210+
# returned, but not used here.
211+
peak, _ = newton_raphson_root_finder(
212+
find_true_peak,
213+
basevalue,
214+
low_bound,
215+
upp_bound,
216+
1e-8,
217+
100,
218+
threshold,
219+
epsilon,
220+
semiminor_tmp,
221+
basevalue,
222+
)
219223

220224
if np.sign(threshold) == np.sign(peak):
221225
# The corrections below for the semi-major and semi-minor axes are
@@ -500,6 +504,7 @@ def moments_enhanced(
500504
rounded_barycenter = int(round(xbar)), int(round(ybar))
501505
mask = (posx == rounded_barycenter[0]) & (posy == rounded_barycenter[1])
502506
in_source_island = mask.any()
507+
503508
if in_source_island:
504509
# In this case the rounded barycenter position is in source_island.
505510
# Note that mask, from the way that posx and posy have been constructed,
@@ -520,8 +525,9 @@ def moments_enhanced(
520525
# Implementation of "tweaked moments", equation 2.66 from
521526
# Spreeuw's thesis. In that formula the "base position" was the
522527
# maximum pixel position, though. Here that is the rounded
523-
# barycenter position, unless it's masked. If it's masked, it
524-
# will be the maximum pixel position.
528+
# barycenter position, unless it's not part of the island. In that
529+
# case no "tweaked moments" extrapolation will be applied, and we
530+
# revert to source_island.max() * fudge_max_pix.
525531
exponent = np.log(2.0) * (
526532
((np.cos(theta) * deltax + np.sin(theta) * deltay) / smin) ** 2
527533
+ ((np.cos(theta) * deltay - np.sin(theta) * deltax) / smaj)
@@ -592,50 +598,51 @@ def moments_enhanced(
592598
else:
593599
theta -= math.pi / 2.0
594600

595-
if np.sign(threshold) == np.sign(basevalue) and in_source_island:
596-
# Implementation of "tweaked moments", equation 2.67 from
597-
# Spreeuw's thesis. In that formula the "base position" was the
598-
# maximum pixel position. Here that is the rounded
599-
# barycenter position, unless it's masked. If it's masked, it
600-
# will be the maximum pixel position.
601-
# The rounded barycenter position will buy us slightly more
602-
# stability (established by testing) than the maximum pixel
603-
# position.
604-
# The condition is a sanity check for maps other than Stokes I,
605-
# where the threshold can be negative. For Stokes I maps, which
606-
# will have positive thresholds, at least for all
607-
# non-pathological cases, this condition will always be true.
608-
609-
epsilon = np.log(2.0) * (
610-
(np.cos(theta) * deltax + np.sin(theta) * deltay) ** 2
611-
+ (np.cos(theta) * deltay - np.sin(theta) * deltax) ** 2
612-
* semiminor_tmp
613-
/ semimajor_tmp
614-
)
601+
if in_source_island:
602+
if np.sign(threshold) == np.sign(basevalue):
603+
# Implementation of "tweaked moments", equation 2.67 from
604+
# Spreeuw's thesis. In that formula the "base position" was the
605+
# maximum pixel position. Here that is the rounded
606+
# barycenter position, unless it's not part of the island. In
607+
# that case no "tweaked moments" extrapolation will be
608+
# applied, and we revert to source_island.max() *
609+
# fudge_max_pix.
610+
# The condition is a sanity check for maps other than Stokes I,
611+
# where the threshold can be negative. For Stokes I maps, which
612+
# will have positive thresholds, at least for all
613+
# non-pathological cases, this condition will always be true.
614+
615+
epsilon = np.log(2.0) * (
616+
(np.cos(theta) * deltax + np.sin(theta) * deltay) ** 2
617+
+ (np.cos(theta) * deltay - np.sin(theta) * deltax)
618+
** 2
619+
* semiminor_tmp
620+
/ semimajor_tmp
621+
)
615622

616-
# Set limits for the root finder similar to the bounds for
617-
# Gaussian fits.
618-
if basevalue > 0:
619-
low_bound = 0.5 * basevalue
620-
upp_bound = 2.0 * basevalue
621-
else:
622-
low_bound = 2.0 * basevalue
623-
upp_bound = 0.5 * basevalue
624-
625-
# The number of iterations used for the root finder is also
626-
# returned, but not used here.
627-
peak, _ = newton_raphson_root_finder(
628-
find_true_peak,
629-
basevalue,
630-
low_bound,
631-
upp_bound,
632-
1e-8,
633-
100,
634-
threshold,
635-
epsilon,
636-
semiminor_tmp,
637-
basevalue,
638-
)
623+
# Set limits for the root finder similar to the bounds for
624+
# Gaussian fits.
625+
if basevalue > 0:
626+
low_bound = 0.5 * basevalue
627+
upp_bound = 2.0 * basevalue
628+
else:
629+
low_bound = 2.0 * basevalue
630+
upp_bound = 0.5 * basevalue
631+
632+
# The number of iterations used for the root finder is also
633+
# returned, but not used here.
634+
peak, _ = newton_raphson_root_finder(
635+
find_true_peak,
636+
basevalue,
637+
low_bound,
638+
upp_bound,
639+
1e-8,
640+
100,
641+
threshold,
642+
epsilon,
643+
semiminor_tmp,
644+
basevalue,
645+
)
639646

640647
if np.sign(threshold) == np.sign(peak) and abs(peak) > abs(
641648
threshold

0 commit comments

Comments
 (0)