@@ -520,10 +520,17 @@ def compute_aperture_photometry(cls, redf, aperpix, r_in, r_out):
520520 from photutils .utils import calc_total_error
521521 from astropy .stats import SigmaClip
522522
523- bkg_box_size = redf .mdata .shape [0 ]// 10
523+ img = redf .mdata
524+
525+ # centroid_sources and fit_fwhm need bkg-substracted data
524526
527+ # opt 1) estimate bkg using more complex algs
528+ bkg_box_size = redf .mdata .shape [0 ]// 10
525529 bkg = get_bkg (redf .mdata , filter_size = 1 , box_size = bkg_box_size )
526- img = redf .mdata
530+ median = bkg .background_median
531+
532+ # opt 2) estimate bkg using simple sigma clip
533+ # mean, median, std = sigma_clipped_stats(img, sigma=3.0)
527534
528535 error = calc_total_error (img , bkg .background_rms , cls .gain_e_adu )
529536
@@ -544,17 +551,31 @@ def compute_aperture_photometry(cls, redf, aperpix, r_in, r_out):
544551 logger .warning (f"{ redf } : ({ pairs } ) image of { astrosource .name } is too close to the border, skipping aperture photometry." )
545552 continue
546553
554+ # # correct position using centroid
555+ # # choose a box size that is somewhat larger than the aperture
556+ # # in case of pairs, cap box size so that it is somewhat smaller than the distance between pairs
557+
558+ # box_size = math.ceil(1.6 * aperpix)//2 * 2 + 1
559+
560+ # if redf.has_pairs:
561+ # box_size_max = math.ceil(np.linalg.norm(Instrument.by_name(redf.instrument).disp_sign_mean))//2 * 2 - 1
562+ # box_size = min(box_size, box_size_max)
563+
547564 # correct position using centroid
548- # choose a box size that is somewhat larger than the aperture
549- # in case of pairs, cap box size that is somewhat smaller than the distance between pairs
565+ # choose a box size around 12.0 arcsec (0.4'' is excellent seeing)
566+ # in case of pairs, cap box size so that it is somewhat smaller than the distance between pairs
550567
551- box_size = math .ceil (1.6 * aperpix )// 2 * 2 + 1
568+ arcsec_px = redf .pixscale .to (u .arcsec / u .pix ).value
569+
570+ box_size = math .ceil ( ( 12 / arcsec_px ) ) // 2 * 2 + 1
571+
572+ logger .debug (f"{ box_size = } " )
552573
553574 if redf .has_pairs :
554- _box_size_max = math .ceil (np .linalg .norm (Instrument .by_name (redf .instrument ).disp_sign_mean ))// 2 * 2 - 1
555- box_size = min (box_size , _box_size_max )
575+ box_size_max = math .ceil (np .linalg .norm (Instrument .by_name (redf .instrument ).disp_sign_mean ))// 2 * 2 - 1
576+ box_size = min (box_size , box_size_max )
556577
557- centroid_px_pos = centroid_sources (img , xpos = wcs_px_pos [0 ], ypos = wcs_px_pos [1 ], box_size = box_size , centroid_func = centroid_2dg )
578+ centroid_px_pos = centroid_sources (img - median , xpos = wcs_px_pos [0 ], ypos = wcs_px_pos [1 ], box_size = box_size , centroid_func = centroid_2dg )
558579 centroid_px_pos = (centroid_px_pos [0 ][0 ], centroid_px_pos [1 ][0 ])
559580
560581 # check that the centroid position is within the borders of the image
@@ -580,14 +601,16 @@ def compute_aperture_photometry(cls, redf, aperpix, r_in, r_out):
580601 flux_counts = ap_stats .sum - annulus_stats .mean * ap_stats .sum_aper_area .value # TODO: check if i should use mean!
581602 flux_counts_err = ap_stats .sum_err
582603
583- apres = AperPhotResult .create (reducedfit = redf ,
584- astrosource = astrosource ,
585- aperpix = aperpix ,
586- r_in = r_in , r_out = r_out ,
587- x_px = centroid_px_pos [0 ], y_px = centroid_px_pos [1 ],
588- pairs = pairs ,
589- bkg_flux_counts = bkg_flux_counts , bkg_flux_counts_err = bkg_flux_counts_err ,
590- flux_counts = flux_counts , flux_counts_err = flux_counts_err )
604+ apres = AperPhotResult .create (
605+ reducedfit = redf ,
606+ astrosource = astrosource ,
607+ aperpix = aperpix ,
608+ r_in = r_in , r_out = r_out ,
609+ x_px = centroid_px_pos [0 ], y_px = centroid_px_pos [1 ],
610+ pairs = pairs ,
611+ bkg_flux_counts = bkg_flux_counts , bkg_flux_counts_err = bkg_flux_counts_err ,
612+ flux_counts = flux_counts , flux_counts_err = flux_counts_err ,
613+ )
591614
592615 apres_L .append (apres )
593616
@@ -709,8 +732,10 @@ def estimate_common_apertures(cls, reducedfits, reductionmethod=None, fit_boxsiz
709732 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).
710733 """
711734
712- from iop4lib .utils import fit_gaussian
713- from iop4lib .db import AstroSource
735+ from photutils .psf import fit_fwhm
736+ from iop4lib .utils .sourcedetection import get_bkg
737+
738+ # select the target source from the list of files (usually, there is only one)
714739
715740 astrosource_S = set .union (* [set (redf .sources_in_field .all ()) for redf in reducedfits ])
716741 target_L = [astrosource for astrosource in astrosource_S if not astrosource .is_calibrator ]
@@ -723,30 +748,78 @@ def estimate_common_apertures(cls, reducedfits, reductionmethod=None, fit_boxsiz
723748 target = astrosource_S .pop ()
724749 else :
725750 return np .nan , np .nan , np .nan , {'mean_fwhm' :np .nan , 'sigma' :np .nan }
751+
752+ logger .debug (f"{ target = } " )
753+
754+ # Iterate over each file, get the fwhm of the source
726755
727756 fwhm_L = list ()
728757
729758 for redf in reducedfits :
759+
730760 try :
731- gaussian = fit_gaussian (px_start = redf .wcs .world_to_pixel (target .coord ), redf = redf )
732- fwhm = (2 * np .sqrt (2 * math .log (2 ))) * np .sqrt (gaussian [0 ].x_stddev .value ** 2 + gaussian [0 ].y_stddev .value ** 2 )
733- if not (fwhm_min < fwhm < fwhm_max ):
734- logger .warning (f"ReducedFit { redf .id } { target .name } : fwhm = { fwhm } px, skipping this reduced fit" )
735- continue
736- logger .debug (f"ReducedFit { redf .id } [{ target .name } ] Gaussian FWHM: { fwhm :.1f} px" )
737- fwhm_L .append (fwhm )
761+
762+ img = redf .mdata
763+
764+ # centroid_sources and fit_fwhm need bkg-substracted data
765+
766+ # opt 1) estimate bkg using more complex algs
767+ bkg_box_size = redf .mdata .shape [0 ]// 10
768+ bkg = get_bkg (redf .mdata , filter_size = 1 , box_size = bkg_box_size )
769+ median = bkg .background_median
770+
771+ # opt 2) estimate bkg using simple sigma clip
772+ # mean, median, std = sigma_clipped_stats(img, sigma=3.0)
773+
774+ for pairs , wcs in (('O' , redf .wcs1 ), ('E' , redf .wcs2 )) if redf .has_pairs else (('O' ,redf .wcs ),):
775+
776+ wcs_px_pos = target .coord .to_pixel (wcs )
777+
778+ # correct position using centroid
779+ # choose a box size around 12.0 arcsec (0.4'' is excellent seeing)
780+ # in case of pairs, cap box size so that it is somewhat smaller than the distance between pairs
781+
782+ arcsec_px = redf .pixscale .to (u .arcsec / u .pix ).value
783+
784+ box_size = math .ceil ( ( 12 / arcsec_px ) ) // 2 * 2 + 1
785+
786+ logger .debug (f"{ box_size = } " )
787+
788+ if redf .has_pairs :
789+ box_size_max = math .ceil (np .linalg .norm (Instrument .by_name (redf .instrument ).disp_sign_mean ))// 2 * 2 - 1
790+ box_size = min (box_size , box_size_max )
791+
792+ centroid_px_pos = centroid_sources (img - median , xpos = wcs_px_pos [0 ], ypos = wcs_px_pos [1 ], box_size = box_size , centroid_func = centroid_2dg )
793+ centroid_px_pos = (centroid_px_pos [0 ][0 ], centroid_px_pos [1 ][0 ])
794+
795+ # log the difference between the WCS and the centroid
796+ wcs_diff = np .sqrt ((centroid_px_pos [0 ] - wcs_px_pos [0 ])** 2 + (centroid_px_pos [1 ] - wcs_px_pos [1 ])** 2 )
797+
798+ logger .debug (f"ReducedFit { redf .id } : { target .name } { pairs } : WCS centroid distance = { wcs_diff :.1f} px" )
799+
800+ fwhm = fit_fwhm (img - median , xypos = centroid_px_pos , fit_shape = 7 )[0 ]
801+
802+ if not (fwhm_min < fwhm < fwhm_max ):
803+ logger .warning (f"ReducedFit { redf .id } { target .name } : fwhm = { fwhm } px, skipping this reduced fit" )
804+ continue
805+
806+ logger .debug (f"ReducedFit { redf .id } [{ target .name } ] Gaussian FWHM: { fwhm } px" )
807+
808+ fwhm_L .append (fwhm )
809+
738810 except Exception as e :
739811 logger .warning (f"ReducedFit { redf .id } { target .name } : error in gaussian fit, skipping this reduced fit ({ e } )" )
740812 continue
741813
742814 if len (fwhm_L ) > 0 :
743815 mean_fwhm = np .mean (fwhm_L )
744816 else :
745- logger .error (f"Could not find an appropriate aperture for Reduced Fits { [redf .id for redf in reducedfits ]} , using standard fwhm of 3.5px " )
817+ logger .error (f"Could not find an appropriate aperture for Reduced Fits { [redf .id for redf in reducedfits ]} , using standard fwhm of { fwhm_default } px " )
746818 mean_fwhm = fwhm_default
747819
748820 sigma = mean_fwhm / (2 * np .sqrt (2 * math .log (2 )))
749821
822+
750823 return 3.0 * sigma , 5.0 * sigma , 9.0 * sigma , {'mean_fwhm' :mean_fwhm , 'sigma' :sigma }
751824
752825
0 commit comments