示例#1
0
    async def rank_slash(self, ctx: SlashContext, expression: str):
        await ctx.defer()
        expression = expression.strip()
        author = ctx.author
        author_id = hashlib.pbkdf2_hmac(hash_name,
                                        str(author.id).encode(), salt,
                                        iterations).hex()
        guild_id = ctx.guild.id

        tracking_cog = get_tracking_cog(self.bot)
        db = tracking_cog.tracked_guilds[guild_id]

        with db:
            with db.bind_ctx([Message]):
                rank_query = fn.rank().over(
                    order_by=[fn.COUNT(Message.message_id).desc()])

                subq = (Message.select(
                    Message.author_id, rank_query.alias("rank")).where(
                        Message.content.contains(expression)).group_by(
                            Message.author_id))

                # Here we use a plain Select() to create our query.
                query = (Select(columns=[subq.c.rank]).from_(subq).where(
                    subq.c.author_id == author_id).bind(db)
                         )  # We must bind() it to the database.

                rank = query.scalar()

        if rank is None:
            result = f"Vous n'avez jamais employé l'expression *{expression}*."
        elif rank == 1:
            result = f"🥇 Vous êtes le membre ayant le plus employé l'expression *{expression}*."
        elif rank == 2:
            result = f"🥈 Vous êtes le 2ème membre à avoir le plus employé l'expression *{expression}*."
        elif rank == 3:
            result = f"🥉 Vous êtes le 3ème membre à avoir le plus employé l'expression *{expression}*."
        else:
            result = f"Vous êtes le **{rank}ème** membre à avoir le plus employé l'expression *{expression}*."

        await ctx.send(result)
示例#2
0
    def build_query(self, version_id, query_region=None):

        c = Catalog.alias()
        ls = Legacy_Survey_DR8.alias()
        c2ls = CatalogToLegacy_Survey_DR8.alias()
        s2020 = BHM_eFEDS_Veto.alias()
        sV = SDSSV_BOSS_SPALL.alias()

        xx = EROSITASupersetClusters.alias()
        x = (xx.select(
            fn.rank().over(partition_by=[xx.ero_detuid],
                           order_by=[xx.xmatch_metric.desc()]).alias('x_rank'),
            xx.ero_detuid.alias('ero_detuid'),
            xx.ls_id.alias('ls_id'),
            xx.target_has_spec.alias('target_has_spec'),
        ).where(
            (xx.ero_version == self.parameters['ero_version']),
            (xx.xmatch_method == self.parameters['xmatch_method']),
            (xx.xmatch_version == self.parameters['xmatch_version']),
            (xx.opt_cat == self.parameters['opt_cat']),
            (xx.xmatch_metric > self.parameters['xmatch_metric_min']),
            (xx.ero_det_like > self.parameters['det_like_min']),
        ).alias('x'))

        instrument = peewee.Value(self.instrument)
        inertial = peewee.Value(self.inertial).cast('bool')

        fibertotflux_r_max = AB2nMgy(self.parameters['fibertotmag_r_min'])
        fibertotflux_r_min = AB2nMgy(self.parameters['fibertotmag_r_max'])
        fibertotflux_z_max = AB2nMgy(self.parameters['fibertotmag_z_min'])
        fibertotflux_z_min = AB2nMgy(self.parameters['fibertotmag_z_max'])

        fibertotflux_r_min_for_cadence1 = AB2nMgy(
            self.parameters['fibertotmag_r_for_cadence1'])
        fibertotflux_z_min_for_cadence1 = AB2nMgy(
            self.parameters['fibertotmag_z_for_cadence1'])
        fibertotflux_r_min_for_cadence2 = AB2nMgy(
            self.parameters['fibertotmag_r_for_cadence2'])
        gaia_g_max_for_cadence1 = self.parameters['gaia_g_max_for_cadence1']
        gaia_rp_max_for_cadence1 = self.parameters['gaia_rp_max_for_cadence1']

        # flux30 = AB2nMgy(30.00)
        # match_radius_spectro = self.parameters['spec_join_radius'] / 3600.0

        # #########################################################################
        # prepare the spectroscopy catalogues

        match_radius_spectro = self.parameters['spec_join_radius'] / 3600.0
        spec_sn_thresh = self.parameters['spec_sn_thresh']
        spec_z_err_thresh = self.parameters['spec_z_err_thresh']

        # SDSS DR16
        c2s16 = CatalogToSDSS_DR16_SpecObj.alias()
        ss16 = SDSS_DR16_SpecObj.alias()
        s16 = (ss16.select(ss16.specobjid.alias('specobjid'), ).where(
            ss16.snmedian >= spec_sn_thresh,
            ss16.zwarning == 0,
            ss16.zerr <= spec_z_err_thresh,
            ss16.zerr > 0.0,
            ss16.scienceprimary > 0,
        ).alias('s16'))

        # SDSS-IV/eFEDS March2020
        c2s2020 = CatalogToBHM_eFEDS_Veto.alias()
        ss2020 = BHM_eFEDS_Veto.alias()
        s2020 = (ss2020.select(ss2020.pk.alias('pk'), ).where(
            ss2020.sn_median_all >= spec_sn_thresh,
            ss2020.zwarning == 0,
            ss2020.z_err <= spec_z_err_thresh,
            ss2020.z_err > 0.0,
        ).alias('s2020'))

        # SDSS-V spAll
        ssV = SDSSV_BOSS_SPALL.alias()
        sV = (ssV.select(
            ssV.specobjid.alias('specobjid'),
            ssV.plug_ra.alias('plug_ra'),
            ssV.plug_dec.alias('plug_dec'),
        ).where(
            ssV.sn_median_all >= spec_sn_thresh,
            ssV.zwarning == 0,
            ssV.z_err <= spec_z_err_thresh,
            ssV.z_err > 0.0,
            ssV.specprimary > 0,
        ).alias('sV'))

        # SDSS-V plateholes - only consider plateholes that
        # were drilled+shipped but that were not yet observed
        ssph = SDSSV_Plateholes.alias()
        ssphm = SDSSV_Plateholes_Meta.alias()
        ssconf = SDSSV_BOSS_Conflist.alias()
        sph = (ssph.select(
            ssph.pkey.alias('pkey'),
            ssph.target_ra.alias('target_ra'),
            ssph.target_dec.alias('target_dec'),
        ).join(ssphm, on=(ssph.yanny_uid == ssphm.yanny_uid)).join(
            ssconf, JOIN.LEFT_OUTER, on=(ssphm.plateid == ssconf.plate)).where(
                (ssph.holetype == 'BOSS_SHARED'),
                (ssph.sourcetype == 'SCI') | (ssph.sourcetype == 'STA'),
                ssphm.isvalid > 0,
                ssconf.plate.is_null(),
            ).alias('sph'))

        # priority is determined by target rank within cluster
        # start with a priority floor value (per carton)
        # then increment if any conditions are met:

        priority = peewee.Case(None, (
            (x.c.x_rank == 1, self.parameters['priority_floor_bcg']),
            (x.c.x_rank > 1, self.parameters['priority_floor_member'] +
             fn.least(self.parameters['priority_levels'] - 2, x.c.x_rank - 2)),
        ), None)

        value = peewee.Case(None, (
            (x.c.x_rank == 1, self.parameters['value_bcg']),
            (x.c.x_rank > 1, self.parameters['value_member']),
        ), None).cast('float')

        # choose cadence based on fiber magnitude in r-band
        cadence1 = self.parameters['cadence1']
        cadence2 = self.parameters['cadence2']
        cadence3 = self.parameters['cadence3']
        cadence4 = 'unknown_cadence'  # catch failures
        cadence = peewee.Case(None, (
            (((ls.fibertotflux_r > fibertotflux_r_min_for_cadence1) |
              (ls.fibertotflux_z > fibertotflux_z_min_for_cadence1) |
              (ls.gaia_phot_g_mean_mag.between(0.1, gaia_g_max_for_cadence1)) |
              (ls.gaia_phot_rp_mean_mag.between(
                  0.1, gaia_rp_max_for_cadence1))), cadence1),
            (ls.fibertotflux_r > fibertotflux_r_min_for_cadence2, cadence2),
            (ls.fibertotflux_r <= fibertotflux_r_min_for_cadence2, cadence3),
        ), cadence4)

        # compute transformed SDSS mags for pointlike and extended sources uniformly
        # transform the legacysurvey grz into sdss psfmag griz

        # extract coeffs from fit logs via:
        # awk 'BEGIN {print("coeffs = {")} /POLYFIT/{ if($3~/sdss_psfmag/){pe="p"} else if ($3~/sdss_fiber2mag/){pe="e"} else{pe="error"}; printf("\"%s%d_%s\": %s,\n", substr($3,length($3)), $8, pe, $10)} END {print("}")}'  bhm_spiders_clusters_lsdr8/lsdr8_fibermag_to_sdss_fiber2mag_?_results.log   # noqa
        coeffs = {
            "g2_e": -0.897719,
            "g1_e": 2.298300,
            "g0_e": -1.019299,
            "i2_e": -0.950114,
            "i1_e": 0.981972,
            "i0_e": -0.261645,
            "r2_e": -0.201741,
            "r1_e": 0.697128,
            "r0_e": -0.120926,
            "z2_e": -1.424312,
            "z1_e": 2.415301,
            "z0_e": -0.677163,
        }

        nMgy_min = 1e-3  # equiv to AB=30
        # extended - start from ls8 fiberfluxes
        g0_e = (
            22.5 -
            2.5 * peewee.fn.log(peewee.fn.greatest(nMgy_min, ls.fiberflux_g)))
        r0_e = (
            22.5 -
            2.5 * peewee.fn.log(peewee.fn.greatest(nMgy_min, ls.fiberflux_r)))
        z0_e = (
            22.5 -
            2.5 * peewee.fn.log(peewee.fn.greatest(nMgy_min, ls.fiberflux_z)))
        g_r_e = (-2.5 * peewee.fn.log(
            peewee.fn.greatest(nMgy_min, ls.fiberflux_g) /
            peewee.fn.greatest(nMgy_min, ls.fiberflux_r)))
        r_z_e = (-2.5 * peewee.fn.log(
            peewee.fn.greatest(nMgy_min, ls.fiberflux_r) /
            peewee.fn.greatest(nMgy_min, ls.fiberflux_z)))

        g_e = (g0_e + coeffs['g0_e'] + coeffs['g1_e'] * g_r_e +
               coeffs['g2_e'] * g_r_e * g_r_e)
        r_e = (r0_e + coeffs['r0_e'] + coeffs['r1_e'] * g_r_e +
               coeffs['r2_e'] * g_r_e * g_r_e)
        i_e = (r0_e + coeffs['i0_e'] + coeffs['i1_e'] * r_z_e +
               coeffs['i2_e'] * r_z_e * r_z_e)
        z_e = (z0_e + coeffs['z0_e'] + coeffs['z1_e'] * r_z_e +
               coeffs['z2_e'] * r_z_e * r_z_e)

        # validity checks
        valid = (g0_e.between(0.1, 29.9) & r0_e.between(0.1, 29.9)
                 & z0_e.between(0.1, 29.9))

        opt_prov = peewee.Case(None, ((valid, 'sdss_fiber2mag_from_lsdr8'), ),
                               'undefined')
        magnitude_g = peewee.Case(None, ((valid, g_e), ), 'NaN')
        magnitude_r = peewee.Case(None, ((valid, r_e), ), 'NaN')
        magnitude_i = peewee.Case(None, ((valid, i_e), ), 'NaN')
        magnitude_z = peewee.Case(None, ((valid, z_e), ), 'NaN')
        magnitude_gaia_g = peewee.Case(None, ((ls.gaia_phot_g_mean_mag.between(
            0.1, 29.9), ls.gaia_phot_g_mean_mag), ), 'NaN')
        magnitude_gaia_bp = peewee.Case(
            None, ((ls.gaia_phot_bp_mean_mag.between(
                0.1, 29.9), ls.gaia_phot_bp_mean_mag), ), 'NaN')
        magnitude_gaia_rp = peewee.Case(
            None, ((ls.gaia_phot_rp_mean_mag.between(
                0.1, 29.9), ls.gaia_phot_rp_mean_mag), ), 'NaN')

        # # We want to switch between psfmags and fibertotmags depending on
        # # ls.type parameter (PSF or extended)
        # # For 'PSF' targets, we use psfmags, but for extended sources use fiber2mags
        # opt_prov = peewee.Case(
        #     ls.type,
        #     (('PSF', 'ls_psfmag'),),
        #     'ls_fibertotmag')
        #
        # magnitude_g = peewee.Case(
        #     ls.type,
        #     (('PSF', (22.5 - 2.5 * fn.log10(fn.greatest(flux30, ls.flux_g))).cast('float')),),
        #     (22.5 - 2.5 * fn.log10(fn.greatest(flux30, ls.fibertotflux_g))).cast('float'))
        #
        # magnitude_r = peewee.Case(
        #     ls.type,
        #     (('PSF', (22.5 - 2.5 * fn.log10(fn.greatest(flux30, ls.flux_r))).cast('float')),),
        #     (22.5 - 2.5 * fn.log10(fn.greatest(flux30, ls.fibertotflux_r))).cast('float'))
        #
        # magnitude_z = peewee.Case(
        #     ls.type,
        #     (('PSF', (22.5 - 2.5 * fn.log10(fn.greatest(flux30, ls.flux_z))).cast('float')),),
        #     (22.5 - 2.5 * fn.log10(fn.greatest(flux30, ls.fibertotflux_z))).cast('float'))
        #
        # magnitude_i = peewee.Case(
        #     ls.type,
        #     (('PSF',
        #       (22.5 - 2.5 * fn.log10(
        #           fn.greatest(flux30, 0.5 * (ls.flux_r + ls.flux_z)))).cast('float')),),
        #     (22.5 - 2.5 * fn.log10(
        #         fn.greatest(flux30, 0.5 * (ls.fibertotflux_r +
        #                                    ls.fibertotflux_z)))).cast('float'))

        spec_sn_thresh = self.parameters['spec_sn_thresh']
        spec_z_err_thresh = self.parameters['spec_z_err_thresh']

        query = (
            c.select(
                c.catalogid.alias('catalogid'),
                ls.ls_id.alias('ls_id'),  # extra
                x.c.ero_detuid.cast('text').alias('ero_detuid'),  # extra
                c.ra.alias('ra'),  # extra
                c.dec.alias('dec'),  # extra
                priority.alias('priority'),
                value.alias('value'),
                cadence.alias('cadence'),
                instrument.alias('instrument'),
                opt_prov.alias('optical_prov'),
                magnitude_g.alias('g'),
                magnitude_r.alias('r'),
                magnitude_i.alias('i'),
                magnitude_z.alias('z'),
                magnitude_gaia_g.alias('gaia_g'),
                magnitude_gaia_bp.alias('bp'),
                magnitude_gaia_rp.alias('rp'),
                inertial.alias('inertial'),
                g0_e.alias('ls8_fibermag_g'),  # extra
                r0_e.alias('ls8_fibermag_r'),  # extra
                z0_e.alias('ls8_fibermag_z'),  # extra
            ).join(c2ls).join(ls).join(x, on=(ls.ls_id == x.c.ls_id))
            # start joining the spectroscopy
            .switch(c).join(c2s16, JOIN.LEFT_OUTER).join(
                s16,
                JOIN.LEFT_OUTER,
                on=((c2s16.target_id == s16.c.specobjid) &
                    (c2s16.version_id == version_id))).switch(c).join(
                        c2s2020, JOIN.LEFT_OUTER).join(
                            s2020,
                            JOIN.LEFT_OUTER,
                            on=((c2s2020.target_id == s2020.c.pk) &
                                (c2s2020.version_id == version_id))).join(
                                    sV,
                                    JOIN.LEFT_OUTER,
                                    on=(fn.q3c_join(
                                        sV.c.plug_ra, sV.c.plug_dec, c.ra,
                                        c.dec, match_radius_spectro))).join(
                                            sph,
                                            JOIN.LEFT_OUTER,
                                            on=(fn.q3c_join(
                                                sph.c.target_ra,
                                                sph.c.target_dec, c.ra, c.dec,
                                                match_radius_spectro)))
            # finished joining the spectroscopy
            .where(c.version_id == version_id, c2ls.version_id == version_id,
                   c2ls.best >> True).where(
                       s16.c.specobjid.is_null(
                           True),  # all of these must be satisfied
                       s2020.c.pk.is_null(True),
                       sV.c.specobjid.is_null(True),
                       sph.c.pkey.is_null(True),
                   ).where(
                       ((ls.fibertotflux_r.between(fibertotflux_r_min,
                                                   fibertotflux_r_max)) |
                        (ls.fibertotflux_z.between(fibertotflux_z_min,
                                                   fibertotflux_z_max))),
                       (x.c.target_has_spec == 0),
                       # gaia safety checks to avoid bad ls photometry
                       ~(ls.gaia_phot_g_mean_mag.between(
                           0.1, self.parameters['gaia_g_mag_limit'])),
                       ~(ls.gaia_phot_rp_mean_mag.between(
                           0.1, self.parameters['gaia_rp_mag_limit'])),
                   ))

        if query_region:
            query = query.where(
                peewee.fn.q3c_radial_query(c.ra, c.dec, query_region[0],
                                           query_region[1], query_region[2]))

        return query
示例#3
0
    def build_query(self, version_id, query_region=None):

        c = Catalog.alias()
        ps = Panstarrs1.alias()
        c2ps = CatalogToPanstarrs1.alias(
        )  # only exists after v0.5 cross-match
        # s2020 = BHM_eFEDS_Veto.alias()
        # sV = SDSSV_BOSS_SPALL.alias()

        xx = EROSITASupersetClusters.alias()
        x = (xx.select(
            fn.rank().over(partition_by=[xx.ero_detuid],
                           order_by=[xx.xmatch_metric.desc()]).alias('x_rank'),
            xx.ero_detuid.alias('ero_detuid'),
            xx.ps1_dr2_id.alias('ps1_dr2_id'),
            xx.target_has_spec.alias('target_has_spec'),
        ).where(
            (xx.ero_version == self.parameters['ero_version']),
            (xx.xmatch_method == self.parameters['xmatch_method']),
            (xx.xmatch_version == self.parameters['xmatch_version']),
            (xx.opt_cat == self.parameters['opt_cat']),
            (xx.xmatch_metric > self.parameters['xmatch_metric_min']),
            (xx.ero_det_like > self.parameters['det_like_min']),
        ).alias('x'))

        instrument = peewee.Value(self.instrument)
        inertial = peewee.Value(self.inertial).cast('bool')

        r_psf_flux_max = AB2Jy(self.parameters['r_psf_mag_min'])
        i_psf_flux_max = AB2Jy(self.parameters['i_psf_mag_min'])
        z_psf_flux_max = AB2Jy(self.parameters['z_psf_mag_min'])
        r_psf_flux_min_for_cadence1 = AB2Jy(
            self.parameters['r_psf_mag_max_for_cadence1'])
        i_psf_flux_min_for_cadence1 = AB2Jy(
            self.parameters['i_psf_mag_max_for_cadence1'])
        z_psf_flux_min_for_cadence1 = AB2Jy(
            self.parameters['z_psf_mag_max_for_cadence1'])
        r_psf_flux_min_for_cadence2 = AB2Jy(
            self.parameters['r_psf_mag_max_for_cadence2'])
        i_psf_flux_min_for_cadence2 = AB2Jy(
            self.parameters['i_psf_mag_max_for_cadence2'])
        z_psf_flux_min_for_cadence2 = AB2Jy(
            self.parameters['z_psf_mag_max_for_cadence2'])

        # match_radius_spectro = self.parameters['spec_join_radius'] / 3600.0

        # #########################################################################
        # prepare the spectroscopy catalogues

        match_radius_spectro = self.parameters['spec_join_radius'] / 3600.0
        spec_sn_thresh = self.parameters['spec_sn_thresh']
        spec_z_err_thresh = self.parameters['spec_z_err_thresh']

        # SDSS DR16
        c2s16 = CatalogToSDSS_DR16_SpecObj.alias()
        ss16 = SDSS_DR16_SpecObj.alias()
        s16 = (ss16.select(ss16.specobjid.alias('specobjid'), ).where(
            ss16.snmedian >= spec_sn_thresh,
            ss16.zwarning == 0,
            ss16.zerr <= spec_z_err_thresh,
            ss16.zerr > 0.0,
            ss16.scienceprimary > 0,
        ).alias('s16'))

        # SDSS-IV/eFEDS March2020
        c2s2020 = CatalogToBHM_eFEDS_Veto.alias()
        ss2020 = BHM_eFEDS_Veto.alias()
        s2020 = (ss2020.select(ss2020.pk.alias('pk'), ).where(
            ss2020.sn_median_all >= spec_sn_thresh,
            ss2020.zwarning == 0,
            ss2020.z_err <= spec_z_err_thresh,
            ss2020.z_err > 0.0,
        ).alias('s2020'))

        # SDSS-V spAll
        ssV = SDSSV_BOSS_SPALL.alias()
        sV = (ssV.select(
            ssV.specobjid.alias('specobjid'),
            ssV.plug_ra.alias('plug_ra'),
            ssV.plug_dec.alias('plug_dec'),
        ).where(
            ssV.sn_median_all >= spec_sn_thresh,
            ssV.zwarning == 0,
            ssV.z_err <= spec_z_err_thresh,
            ssV.z_err > 0.0,
            ssV.specprimary > 0,
        ).alias('sV'))

        # SDSS-V plateholes - only consider plateholes that
        # were drilled+shipped but that were not yet observed
        ssph = SDSSV_Plateholes.alias()
        ssphm = SDSSV_Plateholes_Meta.alias()
        ssconf = SDSSV_BOSS_Conflist.alias()
        sph = (ssph.select(
            ssph.pkey.alias('pkey'),
            ssph.target_ra.alias('target_ra'),
            ssph.target_dec.alias('target_dec'),
        ).join(ssphm, on=(ssph.yanny_uid == ssphm.yanny_uid)).join(
            ssconf, JOIN.LEFT_OUTER, on=(ssphm.plateid == ssconf.plate)).where(
                (ssph.holetype == 'BOSS_SHARED'),
                (ssph.sourcetype == 'SCI') | (ssph.sourcetype == 'STA'),
                ssphm.isvalid > 0,
                ssconf.plate.is_null(),
            ).alias('sph'))

        # priority is determined by target rank within cluster
        # start with a priority floor value (per carton)
        # then increment if any conditions are met:

        priority = peewee.Case(None, (
            (x.c.x_rank == 1, self.parameters['priority_floor_bcg']),
            (x.c.x_rank > 1, self.parameters['priority_floor_member'] +
             fn.least(self.parameters['priority_levels'] - 2, x.c.x_rank - 2)),
        ), None)

        value = peewee.Case(None, (
            (x.c.x_rank == 1, self.parameters['value_bcg']),
            (x.c.x_rank > 1, self.parameters['value_member']),
        ), None)

        # choose cadence based on psf_flux magnitude in panstarrs1 g,r,i-bands
        cadence1 = self.parameters['cadence1']
        cadence2 = self.parameters['cadence2']
        cadence3 = self.parameters['cadence3']
        cadence4 = 'unknown_cadence'
        cadence = peewee.Case(None, (
            ((ps.r_stk_psf_flux > r_psf_flux_min_for_cadence1) |
             (ps.i_stk_psf_flux > i_psf_flux_min_for_cadence1) |
             (ps.z_stk_psf_flux > z_psf_flux_min_for_cadence1), cadence1),
            ((ps.r_stk_psf_flux > r_psf_flux_min_for_cadence2) |
             (ps.i_stk_psf_flux > i_psf_flux_min_for_cadence2) |
             (ps.z_stk_psf_flux > z_psf_flux_min_for_cadence2), cadence2),
            ((ps.r_stk_psf_flux <= r_psf_flux_min_for_cadence2) &
             (ps.i_stk_psf_flux <= i_psf_flux_min_for_cadence2) &
             (ps.z_stk_psf_flux <= z_psf_flux_min_for_cadence2), cadence3),
        ), cadence4)

        # compute transformed SDSS mags for all sources uniformly
        # transform the panstarrs1-dr2 griz into sdss psfmag griz

        # extract coeffs from fit logs via:
        # awk 'BEGIN {print("coeffs = {")} /POLYFIT/{ if($3~/sdss_psfmag/){pe="p"} else if ($3~/sdss_fiber2mag/){pe="e"} else{pe="error"}; printf("\"%s%d_%s\": %s,\n", substr($3,length($3)), $8, pe, $10)} END {print("}")}'  bhm_spiders_clusters_ps1dr2/ps1dr2_stk_psf_to_sdss_fiber2mag_?_results.log  # noqa
        coeffs = {
            "g2_e": -0.353294,
            "g1_e": 0.699658,
            "g0_e": 0.581569,
            "i2_e": -0.446208,
            "i1_e": 0.776628,
            "i0_e": 0.421538,
            "r2_e": -0.123243,
            "r1_e": 0.401786,
            "r0_e": 0.422531,
            "z2_e": -0.488437,
            "z1_e": 0.595132,
            "z0_e": 0.439771,
        }

        Jy_min = AB2Jy(30.00)

        # start from ps1dr2 stk psf fluxes
        g0 = (
            8.9 -
            2.5 * peewee.fn.log(peewee.fn.greatest(Jy_min, ps.g_stk_psf_flux)))
        r0 = (
            8.9 -
            2.5 * peewee.fn.log(peewee.fn.greatest(Jy_min, ps.r_stk_psf_flux)))
        i0 = (
            8.9 -
            2.5 * peewee.fn.log(peewee.fn.greatest(Jy_min, ps.i_stk_psf_flux)))
        z0 = (
            8.9 -
            2.5 * peewee.fn.log(peewee.fn.greatest(Jy_min, ps.z_stk_psf_flux)))
        g_r = g0 - r0
        r_i = r0 - i0
        i_z = i0 - z0

        # use single set of transform coeffs
        g_e = (g0 + coeffs['g0_e'] + coeffs['g1_e'] * g_r +
               coeffs['g2_e'] * g_r * g_r)
        r_e = (r0 + coeffs['r0_e'] + coeffs['r1_e'] * g_r +
               coeffs['r2_e'] * g_r * g_r)
        i_e = (i0 + coeffs['i0_e'] + coeffs['i1_e'] * r_i +
               coeffs['i2_e'] * r_i * r_i)
        z_e = (z0 + coeffs['z0_e'] + coeffs['z1_e'] * i_z +
               coeffs['z2_e'] * i_z * i_z)

        # validity checks
        valid = (g0.between(0.1, 29.9) & r0.between(0.1, 29.9)
                 & i0.between(0.1, 29.9) & z0.between(0.1, 29.9))

        opt_prov = peewee.Case(None, ((valid, 'sdss_fiber2mag_from_ps1dr2'), ),
                               'undefined')
        magnitude_g = peewee.Case(None, ((valid, g_e), ), 'NaN')
        magnitude_r = peewee.Case(None, ((valid, r_e), ), 'NaN')
        magnitude_i = peewee.Case(None, ((valid, i_e), ), 'NaN')
        magnitude_z = peewee.Case(None, ((valid, z_e), ), 'NaN')

        # # We want to switch between psfmags and fibertotmags depending on
        # # ps.flags EXT+EXT_ALT (i.e. extended sources)
        # # For non-extended targets, we use psfmags, but for extended sources use apermag
        # flux30 = AB2Jy(30.00)
        # ps1_ext_flags = 8388608 + 16777216
        # ps1_good_stack_flag = 134217728
        # opt_prov = peewee.Case(
        #     ps.flags.bin_and(ps1_ext_flags),
        #     ((0, 'ps_psfmag'),),
        #     'ps_apermag')
        #
        # magnitude_g = peewee.Case(
        #     ps.flags.bin_and(ps1_ext_flags),
        #     ((0, (8.9 - 2.5 * fn.log10(fn.greatest(flux30, ps.g_stk_psf_flux))).cast('float')),),
        #     (8.9 - 2.5 * fn.log10(fn.greatest(flux30, ps.g_stk_aper_flux))).cast('float'))
        #
        # magnitude_r = peewee.Case(
        #     ps.flags.bin_and(ps1_ext_flags),
        #     ((0, (8.9 - 2.5 * fn.log10(fn.greatest(flux30, ps.r_stk_psf_flux))).cast('float')),),
        #     (8.9 - 2.5 * fn.log10(fn.greatest(flux30, ps.r_stk_aper_flux))).cast('float'))
        #
        # magnitude_i = peewee.Case(
        #     ps.flags.bin_and(ps1_ext_flags),
        #     ((0, (8.9 - 2.5 * fn.log10(fn.greatest(flux30, ps.i_stk_psf_flux))).cast('float')),),
        #     (8.9 - 2.5 * fn.log10(fn.greatest(flux30, ps.i_stk_aper_flux))).cast('float'))
        #
        # magnitude_z = peewee.Case(
        #     ps.flags.bin_and(ps1_ext_flags),
        #     ((0, (8.9 - 2.5 * fn.log10(fn.greatest(flux30, ps.z_stk_psf_flux))).cast('float')),),
        #     (8.9 - 2.5 * fn.log10(fn.greatest(flux30, ps.z_stk_aper_flux))).cast('float'))

        # these control matching to spectroscopy
        match_radius_spectro = self.parameters['spec_join_radius'] / 3600.0
        spec_sn_thresh = self.parameters['spec_sn_thresh']
        spec_z_err_thresh = self.parameters['spec_z_err_thresh']

        # this controls use of bad panstarrs photometry
        ps1_good_stack_flag = 134217728

        query = (
            c.select(
                c.catalogid.alias('catalogid'),
                ps.catid_objid.alias('ps1_catid_objid'),  # extra
                x.c.ero_detuid.cast('text').alias('ero_detuid'),  # extra
                c.ra.alias('ra'),  # extra
                c.dec.alias('dec'),  # extra
                priority.alias('priority'),
                value.cast('float').alias('value'),
                cadence.alias('cadence'),
                instrument.alias('instrument'),
                opt_prov.alias('optical_prov'),
                magnitude_g.alias('g'),
                magnitude_r.alias('r'),
                magnitude_i.alias('i'),
                magnitude_z.alias('z'),
                (ps.flags.bin_and(ps1_good_stack_flag) >
                 0).cast('bool').alias('ps1_good_stack_flag'),  # extra
                inertial.alias('inertial'),
            ).join(c2ps).join(ps).join(x,
                                       on=(ps.catid_objid == x.c.ps1_dr2_id))
            # start joining the spectroscopy
            .switch(c).join(c2s16, JOIN.LEFT_OUTER).join(
                s16,
                JOIN.LEFT_OUTER,
                on=((c2s16.target_id == s16.c.specobjid) &
                    (c2s16.version_id == version_id))).switch(c).join(
                        c2s2020, JOIN.LEFT_OUTER).join(
                            s2020,
                            JOIN.LEFT_OUTER,
                            on=((c2s2020.target_id == s2020.c.pk) &
                                (c2s2020.version_id == version_id))).join(
                                    sV,
                                    JOIN.LEFT_OUTER,
                                    on=(fn.q3c_join(
                                        sV.c.plug_ra, sV.c.plug_dec, c.ra,
                                        c.dec, match_radius_spectro))).join(
                                            sph,
                                            JOIN.LEFT_OUTER,
                                            on=(fn.q3c_join(
                                                sph.c.target_ra,
                                                sph.c.target_dec, c.ra, c.dec,
                                                match_radius_spectro)))
            # finished joining the spectroscopy
            .where(c.version_id == version_id, c2ps.version_id == version_id,
                   c2ps.best >> True).where(
                       s16.c.specobjid.is_null(
                           True),  # all of these must be satisfied
                       s2020.c.pk.is_null(True),
                       sV.c.specobjid.is_null(True),
                       sph.c.pkey.is_null(True),
                   ).
            where(
                (x.c.target_has_spec == 0),
                (ps.r_stk_psf_flux < r_psf_flux_max),
                (ps.i_stk_psf_flux < i_psf_flux_max),
                (ps.z_stk_psf_flux < z_psf_flux_max),
                (ps.r_stk_psf_flux !=
                 'NaN'),  # TODO check this is correct test via peewee
                (ps.i_stk_psf_flux != 'NaN'),
                (ps.z_stk_psf_flux != 'NaN'),
                # TODO - check panstarrs photometry quality ??
                # (ps.flags.bin_and(ps1_good_stack_flag) > 0),
                # TODO gaia safety checks to avoid bad ls photometry???
            ).order_by(x.c.ps1_dr2_id, x.c.x_rank.asc()).distinct([
                x.c.ps1_dr2_id,
            ])  # avoid duplicate entries
        )

        if query_region:
            query = query.where(
                peewee.fn.q3c_radial_query(c.ra, c.dec, query_region[0],
                                           query_region[1], query_region[2]))

        return query
示例#4
0
    def build_query(self, version_id, query_region=None):
        c = Catalog.alias()
        c2t = CatalogToBHM_RM_v0.alias()
        t = BHM_RM_v0_2.alias()
        stw = BHM_RM_Tweaks.alias()
        self.alias_c = c
        self.alias_t = t

        fieldlist = self.get_fieldlist()

        tw = (stw.select(
            stw.pkey.alias('pkey'),
            stw.ra.alias('ra'),
            stw.dec.alias('dec'),
            stw.rm_suitability.alias('rm_suitability'),
        ).where((stw.date_set == '30-Nov-2020')
                | (stw.date_set == '25-May-2021')))
        self.alias_tw = tw
        # #########################################################################
        # prepare the spectroscopy catalogues

        # SDSS-V spAll - select only objects we want to exclude on
        # the basis of their pipeline classifications
        # Currently this is only for secure STARs in the COSMOS field
        ssV = SDSSV_BOSS_SPALL.alias()
        sV = (
            ssV.select(
                ssV.specobjid.alias('specobjid'),
                ssV.plug_ra.alias('plug_ra'),
                ssV.plug_dec.alias('plug_dec'),
                fn.rank().over(partition_by=[ssV.catalogid],
                               order_by=[ssV.sn_median_all.desc()
                                         ]).alias('sn_rank'),
            ).where(
                ssV.programname.contains('RM'),
                ssV.firstcarton.contains('bhm_rm_'),
                ssV.class_ == 'STAR',
                ssV.zwarning == 0,
                ssV.sn_median_all > 2.0,
                # select only COSMOS plates
                ssV.plate << [15038, 15070, 15071, 15252, 15253, 15289
                              ]).alias('sV'))

        # SDSS-V plateholes - only consider plateholes that
        # were drilled+shipped and that have firstcarton ~ 'bhm_rm_'
        ssph = SDSSV_Plateholes.alias()
        ssphm = SDSSV_Plateholes_Meta.alias()
        sph = (ssph.select(
            ssph.pkey.alias('pkey'),
            ssph.target_ra.alias('target_ra'),
            ssph.target_dec.alias('target_dec'),
        ).join(ssphm, on=(ssph.yanny_uid == ssphm.yanny_uid)).where(
            ssph.holetype == 'BOSS_SHARED',
            ssph.sourcetype == 'SCI',
            ssph.firstcarton.contains('bhm_rm_'),
            ssphm.isvalid > 0,
        ).distinct([ssph.catalogid]).alias('sph'))

        # fold in tiers of magnitude-based priority
        priority_mag_step = 0.5
        priority_mag_bright = 17.0
        priority_mag_faint = 22.0
        priority_mag_bright_known_spec = 20.5
        priority_floor = self.parameters.get('priority', 10000)
        priority1 = peewee.Case(None, (
            ((t.mi <= priority_mag_bright), priority_floor + 0),
            (((self.name == 'bhm_rm_known_spec')
              & ~(t.field_name.contains('SDSS-RM')) &
              (t.mi <= priority_mag_bright_known_spec)), priority_floor + 0),
            ((t.mi <= priority_mag_faint), priority_floor + 5 *
             (1 + peewee.fn.floor(
                 (t.mi - priority_mag_bright) / priority_mag_step).cast('int'))
             ),
            ((t.mi > priority_mag_faint), priority_floor + 95),
        ), None)
        # # this secondary priority rule is based on whether this target was
        # # assigned a platehole during the SDSSV plate programme
        # # boost the priorities of those targets that were put onto plates
        # priority2 = peewee.Case(
        #     None,
        #     (
        #         (sph.c.pkey.is_null(False), -100),
        #         (sph.c.pkey.is_null(True), 0),
        #     ),
        #     None
        # )

        # this secondary priority rule boosts the priority of targets that
        # have rm_suitability >= 1 in the bhm_rm_tweaks table
        priority2 = peewee.Case(None, ((tw.c.rm_suitability >= 1, -100), ), 0)

        # combine the two priorities
        priority = priority1 + priority2

        # this just checks if this target was
        # assigned a platehole during the SDSSV plate programme
        # for information only - no action taken
        in_SDSSV_plates = peewee.Case(None,
                                      ((sph.c.pkey.is_null(False), True), ),
                                      False).cast('bool')

        value = peewee.Value(self.parameters.get('value', 1.0)).cast('float')
        instrument = peewee.Value(self.instrument)
        inertial = peewee.Value(self.inertial).cast('bool')
        match_radius_spectro = 1.0 / 3600.0

        # This is the scheme used in v0
        cadence_v0 = peewee.Case(
            None, ((t.field_name.contains('S-CVZ'), 'bhm_rm_lite5_100x8'), ),
            'bhm_rm_174x8')

        # this gives the new names for the same cadences assumed in v0
        cadence_v0p5 = peewee.Case(
            None, ((t.field_name.contains('S-CVZ'), 'dark_100x8'), ),
            'dark_174x8')

        # the following will replace old generic cadences when relevant table has been populated
        # TODO - replace when correct cadences are loaded
        cadence_v1p0 = peewee.Case(None, (
            (t.field_name.contains('SDSS-RM'), 'bhm_rm_sdss-rm'),
            (t.field_name.contains('COSMOS'), 'bhm_rm_cosmos'),
            (t.field_name.contains('XMM-LSS'), 'bhm_rm_xmm-lss'),
            (t.field_name.contains('S-CVZ'), 'bhm_rm_cvz-s'),
            (t.field_name.contains('CDFS'), 'bhm_rm_cdfs'),
            (t.field_name.contains('ELIAS-S1'), 'bhm_rm_elias-s1'),
        ), 'dark_174x8')

        # Photometric precedence: DES>PS1>SDSS(>Gaia)>NSC.
        opt_prov = peewee.Case(None, (
            (t.sdss == 1, 'sdss_psfmag'),
            (t.des == 1, 'psfmag'),
            (t.ps1 == 1, 'ps_psfmag'),
            (t.optical_survey == 'Gaia', 'other'),
            (t.nsc == 1, 'psfmag'),
        ), 'other')

        magnitude_g = peewee.Case(
            None,
            (
                ((t.sdss == 1) & (t.psfmag_sdss[1] > 0.0), t.psfmag_sdss[1]),
                ((t.des == 1) & (t.psfmag_des[0] > 0.0), t.psfmag_des[0]),
                ((t.ps1 == 1) & (t.psfmag_ps1[0] > 0.0), t.psfmag_ps1[0]),
                ((t.optical_survey == 'Gaia') & (t.mag_gaia[0] > 0.0),
                 t.mag_gaia[0]),  # just using gaia G for now
                ((t.nsc == 1) & (t.mag_nsc[0] > 0.0), t.mag_nsc[0]),
            ),
            99.9)  # should never get here
        magnitude_r = peewee.Case(None, (
            ((t.sdss == 1) & (t.psfmag_sdss[2] > 0.0), t.psfmag_sdss[2]),
            ((t.des == 1) & (t.psfmag_des[1] > 0.0), t.psfmag_des[1]),
            ((t.ps1 == 1) & (t.psfmag_ps1[1] > 0.0), t.psfmag_ps1[1]),
            ((t.nsc == 1) & (t.mag_nsc[1] > 0.0), t.mag_nsc[1]),
        ), 99.9)  # should never get here
        magnitude_i = peewee.Case(
            None,
            (
                ((t.sdss == 1) & (t.psfmag_sdss[3] > 0.0), t.psfmag_sdss[3]),
                ((t.des == 1) & (t.psfmag_des[2] > 0.0), t.psfmag_des[2]),
                ((t.ps1 == 1) & (t.psfmag_ps1[2] > 0.0), t.psfmag_ps1[2]),
                ((t.nsc == 1) & (t.mag_nsc[2] > 0.0), t.mag_nsc[2]),
                (t.mi > 0.0, t.mi),
                ((t.optical_survey == 'Gaia') & (t.mag_gaia[2] > 0.0),
                 t.mag_gaia[2]),  # just using gaia RP for now
            ),
            99.9)  # should never get here
        magnitude_z = peewee.Case(None, (
            ((t.sdss == 1) & (t.psfmag_sdss[4] > 0.0), t.psfmag_sdss[4]),
            ((t.des == 1) & (t.psfmag_des[3] > 0.0), t.psfmag_des[3]),
            ((t.ps1 == 1) & (t.psfmag_ps1[3] > 0.0), t.psfmag_ps1[3]),
            ((t.nsc == 1) & (t.mag_nsc[3] > 0.0), t.mag_nsc[3]),
        ), 99.9)  # should never get here

        query = (
            c.select(
                c.catalogid,
                c.ra,  # extra
                c.dec,  # extra
                t.field_name.alias('rm_field_name'),  # extra
                t.pk.alias('rm_pk'),  # extra
                instrument.alias('instrument'),
                priority.alias('priority'),
                priority1.alias('priority1'),
                priority2.alias('priority2'),
                value.alias('value'),
                cadence_v0p5.alias('cadence'),
                cadence_v0.alias('cadence_v0'),  # extra
                cadence_v0p5.alias('cadence_v0p5'),  # extra
                cadence_v1p0.alias('cadence_v1p0'),  # extra
                magnitude_g.alias('g'),
                magnitude_r.alias('r'),
                magnitude_i.alias('i'),
                magnitude_z.alias('z'),
                opt_prov.alias('optical_prov'),
                inertial.alias('inertial'),
                t.optical_survey.alias('optical_survey'),  # extra
                c2t.best.alias("c2t_best"),  # extra
                in_SDSSV_plates.alias('in_SDSSV_plates'),  # extra
                tw.c.rm_suitability.cast('int').alias(
                    'rm_suitability'),  # extra
            ).join(c2t)
            # An explicit join is needed because we are using c2t for Catalog_to_BHM_RM_v0
            # rather than a native c2t for Catalog_to_BHM_RM_v0_2
            .join(t, on=(c2t.target_id == t.pk)).where(
                c.version_id == version_id,
                c2t.version_id == version_id,
                # c2t.best >> True   # TODO check if this is dropping RM targets
                #                    # like it does for AQMES
            ).where(((t.mi >= self.parameters['mag_i_min'])
                     & (t.mi < self.parameters['mag_i_max'])) | (
                         # S-CVZ targets often have only Gaia photom
                         (t.field_name.contains('S-CVZ'))
                         & (t.mg >= self.parameters['mag_g_min_cvz_s'])
                         & (t.mg < self.parameters['mag_g_max_cvz_s']))).
            switch(c).join(
                tw,
                JOIN.LEFT_OUTER,
                on=(fn.q3c_join(
                    tw.c.ra, tw.c.dec, c.ra, c.dec,
                    match_radius_spectro))).join(
                        sV,
                        JOIN.LEFT_OUTER,
                        on=(
                            fn.q3c_join(sV.c.plug_ra, sV.c.plug_dec, c.ra,
                                        c.dec, match_radius_spectro) &
                            (sV.c.sn_rank == 1
                             )  # only consider the best spectrum per object
                        )).join(sph,
                                JOIN.LEFT_OUTER,
                                on=(fn.q3c_join(sph.c.target_ra,
                                                sph.c.target_dec, c.ra, c.dec,
                                                match_radius_spectro))).
            where(
                # Reject any objects where the highest SNR spectrum for
                # this target in sdssv_boss_spall is classified as STAR
                sV.c.specobjid.is_null(True),
                #
                # Reject any targets that are flagged as being unsuitable for RM in bhm_rm_tweaks
                # bhm_rm_tweaks.rm_suitability==0 means:
                # 'target is probably unsuitable for RM, do not observe in the future'
                (tw.c.pkey.is_null(True) |
                 (tw.c.rm_suitability != 0))).distinct(
                     [t.pk])  # avoid duplicates - trust the RM parent sample
            # - only needed if NOT using c2t.best = True condition
        )
        query = self.append_spatial_query(query, fieldlist)

        return query