Skip to content

Commit aa271e9

Browse files
authored
Code refactor, add new FILTER kw, fix small bugs (#163)
1 parent 0378af9 commit aa271e9

File tree

11 files changed

+169
-163
lines changed

11 files changed

+169
-163
lines changed

iop4admin/modeladmins/astrosource.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,8 @@ def remove_field_stars_from_panstarrs(self, request, queryset):
239239
main_src = queryset.first()
240240

241241
field_stars = main_src.calibrators.filter(name__startswith="PanSTARRS")
242+
n_field_stars = len(field_stars) # count before deletion
242243
field_stars.delete()
243-
logger.info(f"Removed {len(field_stars)} PanSTARRS field stars for {main_src.name}")
244+
logger.info(f"Removed {n_field_stars} PanSTARRS field stars for {main_src.name}")
244245

245-
messages.success(request, f"Removed {len(field_stars)} PanSTARRS field stars for {main_src.name}")
246+
messages.success(request, f"Removed {n_field_stars} PanSTARRS field stars for {main_src.name}")

iop4admin/modeladmins/reducedfit.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def exptime(self, obj):
6464
@admin.display(description='SRCS IN FIELD')
6565
def get_targets_in_field(self, obj):
6666

67-
cat_targets = list(obj.sources_in_field.filter(Q(srctype=SRCTYPES.BLAZAR) | Q(srctype=SRCTYPES.STAR)).values_list('name', flat=True))
67+
cat_targets = list(obj.sources_in_field.filter(is_calibrator=False).values_list('name', flat=True))
6868

6969
if len(cat_targets) > 0:
7070
return cat_targets
@@ -73,6 +73,8 @@ def get_targets_in_field(self, obj):
7373
kw_obj_val = obj.rawfit.header['OBJECT']
7474
except FileNotFoundError:
7575
return format_html(f"<i>rawfit not found</i>")
76+
except KeyError:
77+
return format_html(f"<i>no OBJECT keyword</i>")
7678

7779
guessed_target = AstroSource.objects.filter(Q(name__icontains=kw_obj_val) | Q(other_names__icontains=kw_obj_val)).values_list('name', flat=True)
7880

iop4lib/instruments/cafos.py

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from iop4lib.enums import *
1616
from .instrument import Instrument
1717
from iop4lib.telescopes import CAHAT220
18+
from iop4lib.utils import filter_zero_points, calibrate_photopolresult
1819

1920
# logging
2021
import logging
@@ -382,8 +383,7 @@ def compute_relative_polarimetry(cls, polarimetry_group):
382383
mag_zp_err = np.nan
383384
else:
384385
mag_zp = mag_known - mag_inst
385-
# mag_zp_err = math.sqrt(mag_known_err ** 2 + mag_inst_err ** 2)
386-
mag_zp_err = math.fabs(mag_inst_err) # do not add error on literature magnitude
386+
mag_zp_err = math.sqrt(mag_known_err ** 2 + mag_inst_err ** 2)
387387
else:
388388
mag_zp = None
389389
mag_zp_err = None
@@ -408,37 +408,16 @@ def compute_relative_polarimetry(cls, polarimetry_group):
408408
logger.error("No results could be computed for this group.")
409409
return
410410

411-
# 3. Get average zero point from zp of all calibrators in the group
412-
413-
calib_mag_zp_array = np.array([result.mag_zp or np.nan for result in photopolresult_L if result.astrosource.is_calibrator]) # else it fills with None also and the dtype becomes object
414-
calib_mag_zp_array = calib_mag_zp_array[~np.isnan(calib_mag_zp_array)]
415-
416-
calib_mag_zp_array_err = np.array([result.mag_zp_err or np.nan for result in photopolresult_L if result.astrosource.is_calibrator])
417-
calib_mag_zp_array_err = calib_mag_zp_array_err[~np.isnan(calib_mag_zp_array_err)]
418-
419-
if len(calib_mag_zp_array) == 0:
420-
logger.error(f"Can not compute magnitude during relative photo-polarimetry without any calibrators for this reduced fit.")
421-
422-
zp_avg = np.nanmean(calib_mag_zp_array)
423-
zp_std = np.nanstd(calib_mag_zp_array)
424-
425-
zp_err = np.sqrt(np.nansum(calib_mag_zp_array_err ** 2)) / len(calib_mag_zp_array_err)
426-
zp_err = math.sqrt(zp_err ** 2 + zp_std ** 2)
427-
428-
# 4. Compute the calibrated magnitudes for non-calibrators in the group using the averaged zero point
411+
# 3. Compute the calibrated magnitudes for non-calibrators in the group using the averaged zero point
429412

430413
for result in photopolresult_L:
431414

432415
if result.astrosource.is_calibrator:
433416
continue
434417

435-
result.mag_zp = zp_avg
436-
result.mag_zp_err = zp_err
437-
438-
result.mag = result.mag_inst + zp_avg
439-
result.mag_err = math.sqrt(result.mag_inst_err ** 2 + zp_err ** 2)
418+
logger.debug(f"calibrating {result}")
440419

441-
result.save()
420+
calibrate_photopolresult(result, photopolresult_L)
442421

443422
# 5. Save results
444423
for result in photopolresult_L:

iop4lib/instruments/dipol.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ def apply_masters(cls, reducedfit):
254254

255255

256256
@classmethod
257-
def get_header_hintobject(self, rawfit):
257+
def get_header_hintobject(self, rawfit: 'RawFit'):
258258
r""" Overriden for DIPOL, which are using the convention for the other_names field.
259259
260260
The regex used has been obtained from the notebook checking all keywords.
@@ -431,7 +431,7 @@ def build_wcs(cls, reducedfit: 'ReducedFit', summary_kwargs : dict = None, metho
431431
redf_phot = ReducedFit.objects.filter(instrument=reducedfit.instrument,
432432
sources_in_field__in=[reducedfit.header_hintobject],
433433
obsmode=OBSMODES.PHOTOMETRY,
434-
flags__has=ReducedFit.FLAGS.BUILT_REDUCED).first()
434+
flags__has=ReducedFit.FLAGS.BUILT_REDUCED).order_by('-juliandate').first()
435435
try:
436436
n_expected_simbad_sources = len(get_simbad_sources(reducedfit.header_hintobject.coord, radius=(reducedfit.width*cls.arcsec_per_pix*u.arcsec)))
437437
except Exception as e:
@@ -587,7 +587,7 @@ def _build_wcs_for_polarimetry_images_photo_quads(cls, redf: 'ReducedFit', summa
587587
redf_phot = ReducedFit.objects.filter(instrument=redf_pol.instrument,
588588
sources_in_field__in=[target_src],
589589
obsmode=OBSMODES.PHOTOMETRY,
590-
flags__has=ReducedFit.FLAGS.BUILT_REDUCED).first()
590+
flags__has=ReducedFit.FLAGS.BUILT_REDUCED).order_by('-juliandate').first()
591591

592592
if redf_phot is None:
593593
logger.error(f"No astro-calibrated photometry field found for {redf_pol}.")

iop4lib/instruments/instrument.py

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
# iop4lib imports
2323
from iop4lib.enums import *
24+
from iop4lib.utils import filter_zero_points, calibrate_photopolresult
2425

2526
# logging
2627
import logging
@@ -684,40 +685,9 @@ def compute_relative_photometry(cls, redf: 'ReducedFit') -> None:
684685
if result.astrosource.is_calibrator:
685686
continue
686687

687-
# 3.a Average the zero points
688+
logger.debug(f"{redf}: calibrating {result}")
688689

689-
# get all the computed photopolresults that calibrate this source
690-
calibrator_results_L = [r for r in photopolresult_L if r.astrosource.calibrates.filter(pk=result.astrosource.pk).exists()]
691-
692-
# Create an array with nan instead of None (this avoids the dtype becoming object)
693-
calib_mag_zp_array = np.array([result.mag_zp or np.nan for result in calibrator_results_L if result.astrosource.is_calibrator])
694-
calib_mag_zp_array = calib_mag_zp_array[~np.isnan(calib_mag_zp_array)]
695-
696-
calib_mag_zp_array_err = np.array([result.mag_zp_err or np.nan for result in calibrator_results_L if result.astrosource.is_calibrator])
697-
calib_mag_zp_array_err = calib_mag_zp_array_err[~np.isnan(calib_mag_zp_array_err)]
698-
699-
if len(calib_mag_zp_array) == 0:
700-
logger.error(f"{redf}: can not perform relative photometry on source {result.astrosource.name}, no calibrator zero-points found.")
701-
# [result.delete() for result in redf.photopolresults.all()]
702-
continue
703-
704-
zp_avg = np.nanmean(calib_mag_zp_array)
705-
zp_std = np.nanstd(calib_mag_zp_array)
706-
707-
zp_err = math.sqrt(np.sum(calib_mag_zp_array_err**2)) / len(calib_mag_zp_array_err)
708-
zp_err = math.sqrt(zp_std**2 + zp_err**2)
709-
710-
# 3.b Compute the calibrated magnitude
711-
712-
# save the zp (to be) used
713-
result.mag_zp = zp_avg
714-
result.mag_zp_err = zp_err
715-
716-
# compute the calibrated magnitude
717-
result.mag = zp_avg + result.mag_inst
718-
result.mag_err = math.sqrt(result.mag_inst_err**2 + zp_err**2)
719-
720-
result.save()
690+
calibrate_photopolresult(result, photopolresult_L)
721691

722692
# 5. Save the results
723693

@@ -731,7 +701,7 @@ def compute_relative_photometry(cls, redf: 'ReducedFit') -> None:
731701

732702

733703
@classmethod
734-
def estimate_common_apertures(cls, reducedfits, reductionmethod=None, fit_boxsize=None, search_boxsize=(90,90), fwhm_min=2, fwhm_max=50):
704+
def estimate_common_apertures(cls, reducedfits, reductionmethod=None, fit_boxsize=None, search_boxsize=(90,90), fwhm_min=2, fwhm_max=50, fwhm_default=3.5):
735705
r"""estimate an appropriate common aperture for a list of reduced fits.
736706
737707
It fits the target source profile in the fields and returns some multiples of the fwhm which are used as the aperture and as the inner and outer radius of the annulus for local bkg estimation).
@@ -771,11 +741,10 @@ def estimate_common_apertures(cls, reducedfits, reductionmethod=None, fit_boxsiz
771741
mean_fwhm = np.mean(fwhm_L)
772742
else:
773743
logger.error(f"Could not find an appropriate aperture for Reduced Fits {[redf.id for redf in reducedfits]}, using standard fwhm of 3.5px")
774-
mean_fwhm = 3.5
744+
mean_fwhm = fwhm_default
775745

776746
sigma = mean_fwhm / (2*np.sqrt(2*math.log(2)))
777-
r = sigma
778747

779-
return 6.0*r, 7.0*r, 15.0*r, {'mean_fwhm':mean_fwhm, 'sigma':sigma}
748+
return 3.0*sigma, 5.0*sigma, 9.0*sigma, {'mean_fwhm':mean_fwhm, 'sigma':sigma}
780749

781750

iop4lib/instruments/osn_cameras.py

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from iop4lib.enums import *
1717
from .instrument import Instrument
1818
from iop4lib.telescopes import OSNT090, OSNT150
19+
from iop4lib.utils import filter_zero_points, calibrate_photopolresult
1920

2021
# logging
2122
import logging
@@ -114,7 +115,7 @@ def classify_obsmode_rawfit(cls, rawfit):
114115
raise ValueError("Cannot classify obsmode if band is ERROR.")
115116

116117
if rawfit.band == BANDS.R:
117-
if rawfit.header['FILTER'] == "R":
118+
if rawfit.header['FILTER'] == "R" or rawfit.header['FILTER'] == "R Johnson":
118119
rawfit.obsmode = OBSMODES.PHOTOMETRY
119120
else:
120121
logger.debug("Band is R, but FILTER is not exactly R, for OSN this must mean it is polarimetry. Trying to extract angle from FILTER keyword.")
@@ -407,37 +408,16 @@ def compute_relative_polarimetry(cls, polarimetry_group):
407408
photopolresult_L.append(result)
408409

409410

410-
# 3. Get average zero point from zp of all calibrators in the group
411-
412-
calib_mag_zp_array = np.array([result.mag_zp or np.nan for result in photopolresult_L if result.astrosource.is_calibrator]) # else it fills with None also and the dtype becomes object
413-
calib_mag_zp_array = calib_mag_zp_array[~np.isnan(calib_mag_zp_array)]
414-
415-
calib_mag_zp_array_err = np.array([result.mag_zp_err or np.nan for result in photopolresult_L if result.astrosource.is_calibrator])
416-
calib_mag_zp_array_err = calib_mag_zp_array_err[~np.isnan(calib_mag_zp_array_err)]
417-
418-
if len(calib_mag_zp_array) == 0:
419-
logger.error(f"Can not compute magnitude during relative photo-polarimetry without any calibrators for this reduced fit.")
420-
421-
zp_avg = np.nanmean(calib_mag_zp_array)
422-
zp_std = np.nanstd(calib_mag_zp_array)
423-
424-
zp_err = np.sqrt(np.nansum(calib_mag_zp_array_err ** 2)) / len(calib_mag_zp_array_err)
425-
zp_err = math.sqrt(zp_err ** 2 + zp_std ** 2)
426-
427-
# 4. Compute the calibrated magnitudes for non-calibrators in the group using the averaged zero point
411+
# 3. Compute the calibrated magnitudes for non-calibrators in the group using the averaged zero point
428412

429413
for result in photopolresult_L:
430414

431415
if result.astrosource.is_calibrator:
432416
continue
433417

434-
result.mag_zp = zp_avg
435-
result.mag_zp_err = zp_err
436-
437-
result.mag = result.mag_inst + zp_avg
438-
result.mag_err = math.sqrt(result.mag_inst_err ** 2 + zp_err ** 2)
418+
logger.debug(f"calibrating {result}")
439419

440-
result.save()
420+
calibrate_photopolresult(result, photopolresult_L)
441421

442422
# 5. Save results
443423
for result in photopolresult_L:

iop4lib/iop4.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,20 @@ def process_astrosource(args):
104104
from iop4lib.db import ReducedFit, AstroSource, PhotoPolResult, Epoch
105105

106106
astrosource = AstroSource.objects.get(name=args.astrosource)
107+
107108
qs_all = ReducedFit.objects.filter(epoch__night__gte=args.date_start, epoch__night__lte=args.date_end)
108109

109110
logger.info(f"Found {qs_all.count()} reduced fits between {args.date_start} and {args.date_end}.")
110111

111-
# filter files that have identified this source (in sources_in_field) or have this source as header_hintobject
112-
113-
redfL = list()
114-
for redf in qs_all:
115-
if redf.sources_in_field.filter(name=args.astrosource).exists() or redf.header_hintobject == astrosource:
116-
redfL.append(redf)
112+
if args.only_sources_in_field:
113+
qs_all = qs_all.filter(sources_in_field__name=args.astrosource)
114+
redfL = list(qs_all)
115+
else:
116+
# filter files that have identified this source (in sources_in_field) or have this source as header_hintobject
117+
redfL = list()
118+
for redf in qs_all:
119+
if redf.sources_in_field.filter(name=args.astrosource).exists() or redf.header_hintobject == astrosource:
120+
redfL.append(redf)
117121

118122
qs_redf = ReducedFit.objects.filter(pk__in=[redf.pk for redf in redfL])
119123

@@ -128,6 +132,12 @@ def process_astrosource(args):
128132
redfL_failed = [redf for redf in redfL if redf.has_flag(ReducedFit.FLAGS.ERROR_ASTROMETRY)]
129133
Epoch.reduce_reducedfits(redfL_failed)
130134

135+
if args.check_sources_in_field_again:
136+
for reducedfit in redfL:
137+
sources_in_field = AstroSource.get_sources_in_field(fit=reducedfit)
138+
logger.debug(f"{reducedfit}: found {len(sources_in_field)} sources in field.")
139+
reducedfit.sources_in_field.set(sources_in_field, clear=True)
140+
131141
if args.recompute:
132142
qs_res = PhotoPolResult.objects.filter(reducedfits__in=redfL)
133143
n_res_before = qs_res.count()
@@ -359,6 +369,8 @@ def main():
359369
parser.add_argument('--astrosource', type=str, default=None, help='<Optional> Select files only of this source')
360370
parser.add_argument('--recompute', action='store_true', help='<Optional> Recompute photometry and polarimetry results')
361371
parser.add_argument('--retry-failed', action='store_true', help='<Optional> Retry failed reduced fits')
372+
parser.add_argument('--only-sources-in-field', action='store_true', help='<Optional> Only process files that have this source in sources_in_field')
373+
parser.add_argument('--check-sources-in-field-again', action='store_true', help='<Optional> Check sources_in_field again')
362374

363375
# other options
364376
parser.add_argument('--skip-remote-file-list', action='store_true', help='<Optional> Skip remote file list check')

iop4lib/iop4_night_summary.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,15 @@ <h2>Overview</h2>
9393

9494
<h2>Summary of results (band R only)</h2>
9595

96+
{% if sources_without_calibrators %}
97+
<p style="color:red;">
98+
Some sources do not have calibrators:
99+
{% for source in sources_without_calibrators %}
100+
{{ source.name }}{% if not forloop.last %}, {% endif %}
101+
{% endfor %}
102+
</p>
103+
{% endif %}
104+
96105
<p>Some of these plots might include the previous existing night for the source for comparison.</p>
97106

98107
{% for srcname, imgb64 in results_summary_images.items %}

iop4lib/iop4_night_summary.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ def gather_context(args):
7272

7373
sources = AstroSource.objects.exclude(is_calibrator=True).filter(photopolresults__epoch__night=args.date).distinct()
7474

75+
# check if some of these sources lack calibrators
76+
sources_without_calibrators = [source for source in sources if not source.calibrators.exists()]
77+
7578
if sources:
7679
instruments = [instrument.name for instrument in Instrument.get_known()]
7780
colors = [mplt.colormaps['tab10'](i) for i in range(len(instruments))]
@@ -160,6 +163,7 @@ def gather_context(args):
160163
context['epochs'] = epochs
161164
context['sources'] = sources
162165
context['results_summary_images'] = results_summary_images
166+
context['sources_without_calibrators'] = sources_without_calibrators
163167
context['args'] = args
164168

165169
return context

0 commit comments

Comments
 (0)