Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1import numpy as np 

2import astropy.units as u 

3 

4from lsst.faro.utils.filtermatches import filterMatches 

5 

6__all__ = ("photRepeat", "calcPhotRepeat") 

7 

8 

9def photRepeat(matchedCatalog, nMinPhotRepeat=50, **filterargs): 

10 """Measure the photometric repeatability of a set of observations. 

11 

12 Parameters 

13 ---------- 

14 matchedCatalog : `lsst.afw.table.base.Catalog` 

15 `~lsst.afw.table.base.Catalog` object as created by 

16 `~lsst.afw.table.multiMatch` matching of sources from multiple visits. 

17 nMinPhotRepeat : `int` 

18 Minimum number of sources required to return a measurement. 

19 **filterargs 

20 Additional arguments to pass to `filterMatches` for catalog filtering. 

21 

22 Returns 

23 ------- 

24 photo_resid_meas : `dict` 

25 Photometric repeatability statistics and related quantities as measured 

26 by `calcPhotRepeat`. Returns NaN values if there are fewer than 

27 nMinPhotRepeat sources in the matched catalog. 

28 """ 

29 filteredCat = filterMatches(matchedCatalog, **filterargs) 

30 magKey = filteredCat.schema.find('slot_PsfFlux_mag').key 

31 

32 # Require at least nMinPhotRepeat objects to calculate the repeatability: 

33 if filteredCat.count > nMinPhotRepeat: 

34 phot_resid_meas = calcPhotRepeat(filteredCat, magKey) 

35 # Check that the number of stars with >2 visits is >nMinPhotRepeat: 

36 okcount = (phot_resid_meas['count'] > 2) 

37 if np.sum(okcount) > nMinPhotRepeat: 

38 return phot_resid_meas 

39 else: 

40 return {'nomeas': np.nan*u.mmag} 

41 else: 

42 return {'nomeas': np.nan*u.mmag} 

43 

44 

45def calcPhotRepeat(matches, magKey): 

46 """Calculate the photometric repeatability of a set of measurements. 

47 

48 Parameters 

49 ---------- 

50 matches : `lsst.afw.table.GroupView` 

51 `~lsst.afw.table.GroupView` of sources matched between visits using 

52 MultiMatch, as provided by `lsst.faro.utils.matcher.match_catalogs`. 

53 magKey : `lsst.afw.table` schema key 

54 Magnitude column key in the ``GroupView``. 

55 E.g., ``magKey = allMatches.schema.find("slot_ModelFlux_mag").key`` 

56 where ``allMatches`` is the result of `lsst.afw.table.MultiMatch.finish()`. 

57 

58 Returns 

59 ------- 

60 statistics : `dict` 

61 Repeatability statistics and ancillary quantities calculated from the 

62 input ``GroupView`` matched catalog. Fields are: 

63 - ``count``: array of number of nonzero magnitude measurements for each 

64 input source. 

65 - ``magMean``: `~astropy.unit.Quantity` array of mean magnitudes, in mag, 

66 for each input source. 

67 - ``rms``: `~astropy.unit.Quantity` array of RMS photometric repeatability 

68 about the mean, in mmag, for each input source. 

69 - ``repeatability``: scalar `~astropy.unit.Quantity` of the median ``rms``. 

70 This is calculated using all sources with more than 2 magnitude 

71 measurements, and reported in mmag. 

72 - ``magResid``: `~astropy.unit.Quantity` array for each input source, 

73 containing the magnitude residuals, in mmag, with respect to ``magMean``. 

74 """ 

75 matches_rms = (matches.aggregate(np.nanstd, field=magKey)*u.mag).to(u.mmag) 

76 matches_count = matches.aggregate(np.count_nonzero, field=magKey) 

77 matches_mean = matches.aggregate(np.mean, field=magKey)*u.mag 

78 magResid = [] 

79 for gp in matches.groups: 

80 magResid.append(((gp[magKey]-np.mean(gp[magKey]))*(u.mag)).to(u.mmag)) 

81 magResid = np.array(magResid, dtype='object') 

82 okrms = (matches_count > 2) 

83 if np.sum(okrms) > 0: 

84 return {'count': matches_count, 'magMean': matches_mean, 'rms': matches_rms, 

85 'repeatability': np.median(matches_rms[okrms]), 'magResid': magResid} 

86 else: 

87 return {'count': 0, 'magMean': np.nan*u.mag, 'rms': np.nan*u.mmag, 

88 'repeatability': np.nan*u.mmag, 'magDiffs': 0*u.mmag}