Skip to content

Commit 57019cf

Browse files
Merge branch 'main' of github.com:Autostronomy/AutoProf
2 parents 3fe00ce + 014bc97 commit 57019cf

1 file changed

Lines changed: 63 additions & 100 deletions

File tree

src/autoprof/pipeline_steps/Isophote_Extract.py

Lines changed: 63 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444

4545
__all__ = ("Isophote_Extract_Forced", "Isophote_Extract", "Isophote_Extract_Photutils")
4646

47+
4748
def _Generate_Profile(IMG, results, R, parameters, options):
4849

4950
# Create image array with background and mask applied
@@ -86,9 +87,7 @@ def _Generate_Profile(IMG, results, R, parameters, options):
8687
compare_interp = []
8788
for i in range(len(R)):
8889
if "ap_isoband_fixed" in options and options["ap_isoband_fixed"]:
89-
isobandwidth = (
90-
options["ap_isoband_width"] if "ap_isoband_width" in options else 0.5
91-
)
90+
isobandwidth = options["ap_isoband_width"] if "ap_isoband_width" in options else 0.5
9291
else:
9392
isobandwidth = R[i] * (
9493
options["ap_isoband_width"] if "ap_isoband_width" in options else 0.025
@@ -126,12 +125,10 @@ def _Generate_Profile(IMG, results, R, parameters, options):
126125
else 5
127126
),
128127
sigmaclip=options["ap_isoclip"] if "ap_isoclip" in options else False,
129-
sclip_iterations=options["ap_isoclip_iterations"]
130-
if "ap_isoclip_iterations" in options
131-
else 10,
132-
sclip_nsigma=options["ap_isoclip_nsigma"]
133-
if "ap_isoclip_nsigma" in options
134-
else 5,
128+
sclip_iterations=(
129+
options["ap_isoclip_iterations"] if "ap_isoclip_iterations" in options else 10
130+
),
131+
sclip_nsigma=options["ap_isoclip_nsigma"] if "ap_isoclip_nsigma" in options else 5,
135132
)
136133
else:
137134
isisophoteband = True
@@ -144,32 +141,21 @@ def _Generate_Profile(IMG, results, R, parameters, options):
144141
mask=mask,
145142
more=True,
146143
sigmaclip=options["ap_isoclip"] if "ap_isoclip" in options else False,
147-
sclip_iterations=options["ap_isoclip_iterations"]
148-
if "ap_isoclip_iterations" in options
149-
else 10,
150-
sclip_nsigma=options["ap_isoclip_nsigma"]
151-
if "ap_isoclip_nsigma" in options
152-
else 5,
144+
sclip_iterations=(
145+
options["ap_isoclip_iterations"] if "ap_isoclip_iterations" in options else 10
146+
),
147+
sclip_nsigma=options["ap_isoclip_nsigma"] if "ap_isoclip_nsigma" in options else 5,
153148
)
154-
isotot = np.sum(
155-
_iso_between(dat, 0, R[i], parameters[i], results["center"], mask=mask)
156-
)
149+
isotot = np.sum(_iso_between(dat, 0, R[i], parameters[i], results["center"], mask=mask))
157150
medflux = _average(
158151
isovals[0],
159-
options["ap_isoaverage_method"]
160-
if "ap_isoaverage_method" in options
161-
else "median",
152+
options["ap_isoaverage_method"] if "ap_isoaverage_method" in options else "median",
162153
)
163154
scatflux = _scatter(
164155
isovals[0],
165-
options["ap_isoaverage_method"]
166-
if "ap_isoaverage_method" in options
167-
else "median",
156+
options["ap_isoaverage_method"] if "ap_isoaverage_method" in options else "median",
168157
)
169-
if (
170-
"ap_iso_measurecoefs" in options
171-
and not options["ap_iso_measurecoefs"] is None
172-
):
158+
if "ap_iso_measurecoefs" in options and not options["ap_iso_measurecoefs"] is None:
173159
if (
174160
mask is None
175161
and (not "ap_isoclip" in options or not options["ap_isoclip"])
@@ -203,9 +189,7 @@ def _Generate_Profile(IMG, results, R, parameters, options):
203189
cogdirect.append(isotot)
204190
else:
205191
sb.append(
206-
flux_to_sb(medflux, options["ap_pixscale"], zeropoint)
207-
if medflux > 0
208-
else 99.999
192+
flux_to_sb(medflux, options["ap_pixscale"], zeropoint) if medflux > 0 else 99.999
209193
)
210194
sbE.append(
211195
(2.5 * scatflux / (np.sqrt(len(isovals[0])) * medflux * np.log(10)))
@@ -327,14 +311,10 @@ def _Generate_Profile(IMG, results, R, parameters, options):
327311
SBprof_data["ellip"] = list(parameters[p]["ellip"] for p in range(end_prof))
328312
SBprof_data["ellip_e"] = list(parameters[p]["ellip err"] for p in range(end_prof))
329313
SBprof_data["pa"] = list(parameters[p]["pa"] * 180 / np.pi for p in range(end_prof))
330-
SBprof_data["pa_e"] = list(
331-
parameters[p]["pa err"] * 180 / np.pi for p in range(end_prof)
332-
)
314+
SBprof_data["pa_e"] = list(parameters[p]["pa err"] * 180 / np.pi for p in range(end_prof))
333315
SBprof_data["pixels"] = list(pixels)
334316
SBprof_data["maskedpixels"] = list(maskedpixels)
335-
SBprof_data[
336-
"totflux_direct" if fluxunits == "intensity" else "totmag_direct"
337-
] = list(cogdirect)
317+
SBprof_data["totflux_direct" if fluxunits == "intensity" else "totmag_direct"] = list(cogdirect)
338318

339319
if "ap_iso_measurecoefs" in options and not options["ap_iso_measurecoefs"] is None:
340320
whichcoefs = [0] + list(options["ap_iso_measurecoefs"])
@@ -363,9 +343,7 @@ def _Generate_Profile(IMG, results, R, parameters, options):
363343
SBprof_data["C"] = list(p["C"] for p in parameters[:end_prof])
364344

365345
if "ap_doplot" in options and options["ap_doplot"]:
366-
Plot_Phase_Profile(
367-
np.array(SBprof_data["R"]), parameters[:end_prof], results, options
368-
)
346+
Plot_Phase_Profile(np.array(SBprof_data["R"]), parameters[:end_prof], results, options)
369347
if fluxunits == "intensity":
370348
Plot_I_Profile(
371349
dat,
@@ -406,7 +384,7 @@ def Isophote_Extract_Forced(IMG, results, options):
406384
ap_fluxunits : str, default "mag"
407385
units for outputted photometry. Can either be "mag" for log
408386
units, or "intensity" for linear units.
409-
387+
410388
ap_isoband_start : float, default 2
411389
The noise level at which to begin sampling a band of pixels to
412390
compute SB instead of sampling a line of pixels near the
@@ -483,7 +461,7 @@ def Isophote_Extract_Forced(IMG, results, options):
483461
Tuple with axes limits for the y-axis in the SB profile
484462
diagnostic plot. Be careful when using intensity units
485463
since this will change the ideal axis limits.
486-
464+
487465
ap_plot_sbprof_xlim : tuple, default None
488466
Tuple with axes limits for the x-axis in the SB profile
489467
diagnostic plot.
@@ -492,7 +470,7 @@ def Isophote_Extract_Forced(IMG, results, options):
492470
Float value by which to scale errorbars on the SB profile
493471
this makes them more visible in cases where the statistical
494472
errors are very small.
495-
473+
496474
Notes
497475
----------
498476
:References:
@@ -522,13 +500,23 @@ def Isophote_Extract_Forced(IMG, results, options):
522500
with open(options["ap_forcing_profile"], "r") as f:
523501
raw = f.readlines()
524502
for i, l in enumerate(raw):
525-
if l[0] != "#":
526-
readfrom = i
527-
break
503+
if len(l.strip()) == 0 or l[0] == "#":
504+
continue
505+
readfrom = i
506+
break
528507
header = list(h.strip() for h in raw[readfrom].split(","))
529508
force = dict((h, []) for h in header)
530-
for l in raw[readfrom + 2 :]:
531-
for d, h in zip(l.split(","), header):
509+
for l in raw[readfrom + 1 :]:
510+
if len(l) > 0 and l[0] == "#":
511+
continue # skip comments
512+
D = list(l.split(","))
513+
if len(D) != len(header):
514+
continue # Skip missmatched rows with header
515+
try:
516+
float(D[0].strip())
517+
except ValueError:
518+
continue # Skip non-numeric rows
519+
for d, h in zip(D, header):
532520
force[h].append(float(d.strip()))
533521

534522
force["pa"] = PA_shift_convention(np.array(force["pa"]), deg=True) * np.pi / 180
@@ -538,11 +526,7 @@ def Isophote_Extract_Forced(IMG, results, options):
538526
"ellip": force["ellip"][i],
539527
"pa": (
540528
force["pa"][i]
541-
+ (
542-
options["ap_forced_pa_shift"]
543-
if "ap_forced_pa_shift" in options
544-
else 0.0
545-
)
529+
+ (options["ap_forced_pa_shift"] if "ap_forced_pa_shift" in options else 0.0)
546530
)
547531
% np.pi,
548532
}
@@ -584,7 +568,7 @@ def Isophote_Extract(IMG, results, options):
584568
ap_fluxunits : str, default "mag"
585569
units for outputted photometry. Can either be "mag" for log
586570
units, or "intensity" for linear units.
587-
571+
588572
ap_samplegeometricscale : float, default 0.1
589573
growth scale for isophotes when sampling for the final output
590574
profile. Used when sampling geometrically. By default, each
@@ -691,16 +675,16 @@ def Isophote_Extract(IMG, results, options):
691675
Tuple with axes limits for the y-axis in the SB profile
692676
diagnostic plot. Be careful when using intensity units
693677
since this will change the ideal axis limits.
694-
678+
695679
ap_plot_sbprof_xlim : tuple, default None
696680
Tuple with axes limits for the x-axis in the SB profile
697681
diagnostic plot.
698-
682+
699683
ap_plot_sbprof_set_errscale : float, default None
700684
Float value by which to scale errorbars on the SB profile
701685
this makes them more visible in cases where the statistical
702686
errors are very small.
703-
687+
704688
Notes
705689
----------
706690
:References:
@@ -735,9 +719,11 @@ def Isophote_Extract(IMG, results, options):
735719

736720
# Radius values to evaluate isophotes
737721
R = [
738-
options["ap_sampleinitR"]
739-
if "ap_sampleinitR" in options
740-
else min(1.0, results["psf fwhm"] / 2)
722+
(
723+
options["ap_sampleinitR"]
724+
if "ap_sampleinitR" in options
725+
else min(1.0, results["psf fwhm"] / 2)
726+
)
741727
]
742728
while (
743729
(
@@ -746,10 +732,7 @@ def Isophote_Extract(IMG, results, options):
746732
)
747733
or (options["ap_extractfull"] if "ap_extractfull" in options else False)
748734
) and R[-1] < max(IMG.shape) / np.sqrt(2):
749-
if (
750-
"ap_samplestyle" in options
751-
and options["ap_samplestyle"] == "geometric-linear"
752-
):
735+
if "ap_samplestyle" in options and options["ap_samplestyle"] == "geometric-linear":
753736
if len(R) > 1 and abs(R[-1] - R[-2]) >= (
754737
options["ap_samplelinearscale"]
755738
if "ap_samplelinearscale" in options
@@ -797,24 +780,16 @@ def Isophote_Extract(IMG, results, options):
797780
)
798781
)
799782
R = np.array(R)
800-
logging.info(
801-
"%s: R complete in range [%.1f,%.1f]" % (options["ap_name"], R[0], R[-1])
802-
)
783+
logging.info("%s: R complete in range [%.1f,%.1f]" % (options["ap_name"], R[0], R[-1]))
803784

804785
# Interpolate profile values, when extrapolating just take last point
805-
tmp_pa_s = UnivariateSpline(
806-
results["fit R"], np.sin(2 * results["fit pa"]), ext=3, s=0
807-
)(R)
808-
tmp_pa_c = UnivariateSpline(
809-
results["fit R"], np.cos(2 * results["fit pa"]), ext=3, s=0
810-
)(R)
786+
tmp_pa_s = UnivariateSpline(results["fit R"], np.sin(2 * results["fit pa"]), ext=3, s=0)(R)
787+
tmp_pa_c = UnivariateSpline(results["fit R"], np.cos(2 * results["fit pa"]), ext=3, s=0)(R)
811788
E = _x_to_eps(
812-
UnivariateSpline(
813-
results["fit R"], _inv_x_to_eps(results["fit ellip"]), ext=3, s=0
814-
)(R)
789+
UnivariateSpline(results["fit R"], _inv_x_to_eps(results["fit ellip"]), ext=3, s=0)(R)
815790
)
816791
# np.arctan(tmp_pa_s / tmp_pa_c) + (np.pi * (tmp_pa_c < 0))
817-
PA = _x_to_pa(((np.arctan2(tmp_pa_s, tmp_pa_c)) % (2 * np.pi)) / 2)
792+
PA = _x_to_pa(((np.arctan2(tmp_pa_s, tmp_pa_c)) % (2 * np.pi)) / 2)
818793
parameters = list({"ellip": E[i], "pa": PA[i]} for i in range(len(R)))
819794

820795
if "fit Fmodes" in results:
@@ -857,16 +832,12 @@ def Isophote_Extract(IMG, results, options):
857832
and (not results["fit pa_err"] is None)
858833
):
859834
parameters[i]["ellip err"] = np.clip(
860-
UnivariateSpline(
861-
results["fit R"], results["fit ellip_err"], ext=3, s=0
862-
)(R[i]),
835+
UnivariateSpline(results["fit R"], results["fit ellip_err"], ext=3, s=0)(R[i]),
863836
a_min=1e-3,
864837
a_max=None,
865838
)
866839
parameters[i]["pa err"] = np.clip(
867-
UnivariateSpline(results["fit R"], results["fit pa_err"], ext=3, s=0)(
868-
R[i]
869-
),
840+
UnivariateSpline(results["fit R"], results["fit pa_err"], ext=3, s=0)(R[i]),
870841
a_min=1e-3,
871842
a_max=None,
872843
)
@@ -895,21 +866,21 @@ def Isophote_Extract_Photutils(IMG, results, options):
895866
ap_fluxunits : str, default "mag"
896867
units for outputted photometry. Can either be "mag" for log
897868
units, or "intensity" for linear units.
898-
869+
899870
ap_plot_sbprof_ylim : tuple, default None
900871
Tuple with axes limits for the y-axis in the SB profile
901872
diagnostic plot. Be careful when using intensity units
902873
since this will change the ideal axis limits.
903-
874+
904875
ap_plot_sbprof_xlim : tuple, default None
905876
Tuple with axes limits for the x-axis in the SB profile
906877
diagnostic plot.
907-
878+
908879
ap_plot_sbprof_set_errscale : float, default None
909880
Float value by which to scale errorbars on the SB profile
910881
this makes them more visible in cases where the statistical
911882
errors are very small.
912-
883+
913884
Notes
914885
----------
915886
:References:
@@ -1026,9 +997,7 @@ def Isophote_Extract_Photutils(IMG, results, options):
1026997
res = {}
1027998
dat = IMG - results["background"]
1028999
if not "fit R" in results and not "fit photutils isolist" in results:
1029-
logging.info(
1030-
"%s: photutils fitting and extracting image data" % options["ap_name"]
1031-
)
1000+
logging.info("%s: photutils fitting and extracting image data" % options["ap_name"])
10321001
geo = EllipseGeometry(
10331002
x0=results["center"]["x"],
10341003
y0=results["center"]["y"],
@@ -1042,8 +1011,7 @@ def Isophote_Extract_Photutils(IMG, results, options):
10421011
res.update(
10431012
{
10441013
"fit photutils isolist": isolist,
1045-
"auxfile fitlimit": "fit limit semi-major axis: %.2f pix"
1046-
% isolist.sma[-1],
1014+
"auxfile fitlimit": "fit limit semi-major axis: %.2f pix" % isolist.sma[-1],
10471015
}
10481016
)
10491017
elif not "fit photutils isolist" in results:
@@ -1069,8 +1037,7 @@ def Isophote_Extract_Photutils(IMG, results, options):
10691037
res.update(
10701038
{
10711039
"fit photutils isolist": isolist,
1072-
"auxfile fitlimit": "fit limit semi-major axis: %.2f pix"
1073-
% isolist.sma[-1],
1040+
"auxfile fitlimit": "fit limit semi-major axis: %.2f pix" % isolist.sma[-1],
10741041
}
10751042
)
10761043
else:
@@ -1093,9 +1060,7 @@ def Isophote_Extract_Photutils(IMG, results, options):
10931060
zeropoint,
10941061
)
10951062
)
1096-
SBprof_data["SB_e"].append(
1097-
2.5 * isolist.int_err[i] / (isolist.intens[i] * np.log(10))
1098-
)
1063+
SBprof_data["SB_e"].append(2.5 * isolist.int_err[i] / (isolist.intens[i] * np.log(10)))
10991064
SBprof_data["totmag"].append(flux_to_mag(isolist.tflux_e[i], zeropoint))
11001065
SBprof_data["totmag_e"].append(
11011066
2.5
@@ -1117,9 +1082,7 @@ def Isophote_Extract_Photutils(IMG, results, options):
11171082
for k in SBprof_data.keys():
11181083
if not np.isfinite(SBprof_data[k][-1]):
11191084
SBprof_data[k][-1] = 99.999
1120-
res.update(
1121-
{"prof header": params, "prof units": SBprof_units, "prof data": SBprof_data}
1122-
)
1085+
res.update({"prof header": params, "prof units": SBprof_units, "prof data": SBprof_data})
11231086

11241087
if "ap_doplot" in options and options["ap_doplot"]:
11251088
if fluxunits == "intensity":

0 commit comments

Comments
 (0)