Example #1
0
def random_redshift_array(
        log,
        sampleNumber,
        lowerRedshiftLimit,
        upperRedshiftLimit,
        redshiftResolution,
        pathToOutputPlotDirectory,
        plot=False):
    """
    *Generate a NumPy array of random distances given a sample number and distance limit*

    **Key Arguments:**
        - ``log`` -- logger
        - ``sampleNumber`` -- the sample number, i.e. array size
        - ``lowerRedshiftLimit`` -- the lower redshift limit of the volume to be included
        - ``upperRedshiftLimit`` -- the upper redshift limit of the volume to be included
        - ``redshiftResolution`` -- the resolution of the redshift distribution
        - ``pathToOutputPlotDirectory`` -- path to the output directory (provided by the user)
        - ``plot`` -- generate plot?

    **Return:**
        - ``redshiftArray`` -- an array of random redshifts within the volume limit
    """
    ################ > IMPORTS ################
    ## STANDARD LIB ##
    ## THIRD PARTY ##
    import matplotlib.pyplot as plt
    import numpy as np
    import numpy.random as npr
    ## LOCAL APPLICATION ##
    import dryxPython.astrotools as da

    redshiftDistribution = np.arange(
        0., upperRedshiftLimit, redshiftResolution)
    closestNumber = lambda n, l: min(l, key=lambda x: abs(x - n))

    # GIVEN THE REDSHIFT LIMIT - DETERMINE THE VOLUME LIMIT
    distanceDictionary = da.convert_redshift_to_distance(upperRedshiftLimit)
    upperMpcLimit = distanceDictionary["dl_mpc"]
    upperVolumeLimit = (4. / 3.) * np.pi * upperMpcLimit ** 3

    if lowerRedshiftLimit == 0.:
        lowerVolumeLimit = 0.
    else:
        distanceDictionary = da.convert_redshift_to_distance(
            lowerRedshiftLimit)
        lowerMpcLimit = distanceDictionary["dl_mpc"]
        lowerVolumeLimit = (4. / 3.) * np.pi * lowerMpcLimit ** 3

    volumeShell = upperVolumeLimit - lowerVolumeLimit

    # GENERATE A LIST OF RANDOM DISTANCES
    redshiftList = []
    for i in range(sampleNumber):
        randomVolume = lowerVolumeLimit + npr.random() * volumeShell
        randomDistance = (randomVolume * (3. / 4.) / np.pi) ** (1. / 3.)
        randomRedshift = da.convert_mpc_to_redshift(randomDistance)
        randomRedshift = closestNumber(randomRedshift, redshiftDistribution)
        # log.debug('randomDistance %s' % (randomDistance,))
        redshiftList.append(randomRedshift)

    redshiftArray = np.array(redshiftList)
    # log.info('redshiftArray %s' % (redshiftArray,))

    if plot:
        # FORCE SQUARE FIGURE AND SQUARE AXES LOOKS BETTER FOR POLAR
        fig = plt.figure(
            num=None,
            figsize=(8, 8),
            dpi=None,
            facecolor=None,
            edgecolor=None,
            frameon=True)

        ax = fig.add_axes(
            [0.1, 0.1, 0.8, 0.8],
            polar=True)

        thetaList = []
        twoPi = 2. * np.pi
        for i in range(sampleNumber):
            thetaList.append(twoPi * npr.random())
        thetaArray = np.array(thetaList)

        plt.scatter(
            thetaArray,
            redshiftArray,
            s=10,
            c='b',
            marker='o',
            cmap=None,
            norm=None,
            vmin=None,
            vmax=None,
            alpha=None,
            linewidths=None,
            edgecolor='w',
            verts=None,
            hold=None)

        title = "SN Redshift Distribution"
        plt.title(title)
        fileName = pathToOutputPlotDirectory + title.replace(" ", "_") + ".png"
        plt.savefig(fileName)
        plt.clf()  # clear figure

    return redshiftArray
Example #2
0
def convert_lightcurves_to_observered_frame(
        log,
        snLightCurves,
        rawLightCurveDict,
        redshiftArray,
        snTypesArray,
        peakMagnitudesArray,
        hostExtinctionArray,
        kCorrectionArray,
        galacticExtinctionArray,
        restFrameFilter,
        pathToOutputDirectory,
        pathToOutputPlotDirectory,
        polyOrder,
        plot=True):
    """
    *Given all the randomly generated parameters of the survey, generate a dictionary of lightcurves for each object (one lightcurve per filter)*

    **Key Arguments:**
        - ``log`` -- logger
        - ``snLightCurves`` -- the sn lightcurve dictionary (with explosion / extinction dates)
        - ``rawLightCurveDict`` -- dictionary of the raw lightcurves (all peaking at mag = 0)
        - ``redshiftArray`` -- array of random redshifts,
        - ``snTypesArray`` --  array of random sn types,
        - ``peakMagnitudesArray`` --  array of random peak mags,
        - ``kCorrectionArray`` -- array of k-corrections,
        - ``hostExtinctionArray`` --  array of random host extinctions,
        - ``galacticExtinctionArray`` --  array of random galactic extinctions,
        - ``restFrameFilter`` -- the observed frame filter with which to calculate k-crrections with
        - ``pathToOutputDirectory`` -- path to the output directory (provided by the user)
        - ``pathToOutputPlotDirectory`` -- path to the output plot directory
        - ``polyOrder`` -- order of the polynomial used to fit the lightcurve
        - ``plot`` -- generate plots?

    **Return:**
        - None
    """
    ################ > IMPORTS ################
    ## STANDARD LIB ##
    ## THIRD PARTY ##
    import numpy as np
    import matplotlib.pyplot as plt
    import math
    import yaml
    ## LOCAL APPLICATION ##
    import dryxPython.astrotools as da
    import dryxPython.plotting as dp

    ################ >ACTION(S) ################
    filters = ['g', 'r', 'i', 'z']
    fileName = pathToOutputDirectory + "transient_light_curves.yaml"
    stream = file(fileName, 'r')
    generatedLCs = yaml.load(stream)
    models = generatedLCs.keys()
    ebvConverters = {'g': 3.793, 'r': 2.751, 'i': 2.086, 'z': 1.479}
    stepNum = 0

    ###########################################################
    # STEP 1 - CONVERT RAW LIGHTCURVES TO ABSOLUTE MAG CURVES #
    ###########################################################
    stepNum += 1
    stepStr = "%02d" % stepNum
    # CONVERT PEAK MAGS TO POLYNOMIALS
    peakMagPolyList = []
    for item in peakMagnitudesArray:
        thisPoly = np.poly1d([item, ])
        peakMagPolyList.append(thisPoly)

    # CONVERT RAW LIGHTCURVES TO ABSOLUTE MAG CURVES
    absLightCurveList = []
    exampleDictionary = {}

    for item in range(len(snTypesArray)):
        thisModel = snTypesArray[item]
        # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']
        log.debug('thisModel, restFrameFilter: %s, %s' %
                  (thisModel, restFrameFilter,))
        explosionDay = rawLightCurveDict[thisModel][
            restFrameFilter]['Explosion Day Relative to Peak']
        endOfLightcurveDay = snLightCurves[thisModel][
            'End of lightcurve relative to peak']
        log.warning(
            'explosionDay, endOfLightcurveDay for absolute Light Curve: %s, %s' %
            (explosionDay, endOfLightcurveDay))
        absLightCurve = rawLightCurveDict[thisModel][
            restFrameFilter]['poly'] + peakMagPolyList[item]
        absLightCurve = np.poly1d(absLightCurve)
        absLightCurveList.append(absLightCurve)
        exampleDictionary['SN %02d @ z = %04.3f' %
                          (item, redshiftArray[item])] = absLightCurve
    if plot:
        dp.plot_polynomial(
            log,
            title="Absoulte Magnitude Lightcurves - random sample",
            polynomialDict=exampleDictionary,
            orginalDataDictionary=False,
            pathToOutputPlotsFolder=pathToOutputPlotDirectory,
            xRange=[explosionDay, endOfLightcurveDay],
            xlabel="Days Relative to Peak (Rest Frame)",
            ylabel="Absolute Magnitude",
            xAxisLimits=False,
            yAxisLimits=False,
            yAxisInvert=True,
            prependNum=stepNum)

    ################################################################
    # STEP 2 - CONVERT ABSOLUTE LIGHTCURVES TO APPARENT MAG CURVES #
    ################################################################
    stepNum += 1
    stepStr = "%02d" % stepNum
    # CONVERT DISTANCE MOD TO POLYNOMIALS
    distanceModPolyList = []
    for item in redshiftArray:
        log.debug('redshift: %s' % (item,))
        if item == 0.0:
            item = 0.01
        distanceDictionary = da.convert_redshift_to_distance(item)
        distanceMpc = distanceDictionary["dl_mpc"]
        distanceModulus = distanceDictionary["dmod"]
        # log.debug('distanceMpc %s' % (distanceMpc,))
        # log.info('redshift %s = distanceModulus %s' % (item, distanceModulus,))
        thisPoly = np.poly1d([distanceModulus, ])
        distanceModPolyList.append(thisPoly)

    # CONVERT ABSOLUTE LIGHTCURVES TO APPARENT MAG CURVES
    apparentLightCurveList = []
    for item in range(len(snTypesArray)):
        thisModel = snTypesArray[item]
        # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']
        explosionDay = rawLightCurveDict[thisModel][
            restFrameFilter]['Explosion Day Relative to Peak']
        endOfLightcurveDay = snLightCurves[thisModel][
            'End of lightcurve relative to peak']
        log.info(
            'explosionDay, endOfLightcurveDay for apparent Light Curve: %s, %s' %
            (explosionDay, endOfLightcurveDay))
        apparentLightCurve = absLightCurveList[
            item] + distanceModPolyList[item]
        # log.debug('apparentLightCurve %s' % (apparentLightCurve,))
        apparentLightCurve = np.poly1d(apparentLightCurve)
        apparentLightCurveList.append(apparentLightCurve)
        exampleDictionary['SN %02d @ z = %04.3f' %
                          (item, redshiftArray[item])] = apparentLightCurve
        #log.info('absLightCurveDictionary %s' % (absLightCurveDictionary,))
    if plot:
        dp.plot_polynomial(
            log,
            title="Pre-KCorrection Apparent Magnitude Lightcurves - random sample",
            polynomialDict=exampleDictionary,
            orginalDataDictionary=False,
            pathToOutputPlotsFolder=pathToOutputPlotDirectory,
            xRange=[explosionDay, endOfLightcurveDay],
            xlabel="Days Relative to Peak (Rest Frame)",
            ylabel="Apparent Magnitude",
            xAxisLimits=False,
            yAxisLimits=False,
            yAxisInvert=True,
            prependNum=stepNum)

    ###########################################################
    # STEP 3 - (UN) K-CORRECT THE APPARENT LIGHTCURVES        #
    ###########################################################
    stepNum += 1
    stepStr = "%02d" % stepNum
    # (UN) K-CORRECT THE APPARENT LIGHTCURVES
    kCorApparentLightCurveList = []
    for i in range(len(apparentLightCurveList)):
        thisModel = snTypesArray[i]
        # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']
        explosionDay = rawLightCurveDict[thisModel][
            restFrameFilter]['Explosion Day Relative to Peak']
        endOfLightcurveDay = snLightCurves[thisModel][
            'End of lightcurve relative to peak']
        log.info(
            'explosionDay, endOfLightcurveDay for unkcor apparent Light Curve: %s, %s' %
            (explosionDay, endOfLightcurveDay))
        kCorDict = kCorrectionArray[i]
        lcDict = {}
        plotLcDict = {}
        for ffilter, poly in kCorDict.iteritems():
            if poly is None:
                kcorLightCurve = None
            else:
                kcorLightCurve = apparentLightCurveList[i] - poly
                plotLcDict[ffilter] = kcorLightCurve
            lcDict[ffilter] = kcorLightCurve
            if plot:
                dp.plot_polynomial(
                    log,
                    title="K(un)corrected Apparent Magnitude Lightcurves - SN Number %s" % (
                        i),
                    polynomialDict=plotLcDict,
                    orginalDataDictionary=False,
                    pathToOutputPlotsFolder=pathToOutputPlotDirectory,
                    xRange=[explosionDay, endOfLightcurveDay],
                    xlabel="Days Relative to Peak (Rest Frame)",
                    ylabel="Apparent Magnitude",
                    xAxisLimits=False,
                    yAxisLimits=False,
                    yAxisInvert=True,
                    prependNum=stepNum)

        kCorApparentLightCurveList.append(lcDict)

    ###########################################################
    # STEP 4 - INCLUDE GALACTIC EXTINCTION IN LIGHTCURVES     #
    ###########################################################
    stepNum += 1
    stepStr = "%02d" % stepNum
    # INCLUDE GALACTIC EXTINCTION
    # CONVERT EXT TO POLYNOMIALS
    galExtPolyList = []
    for ext in galacticExtinctionArray:
        extDict = {}
        for ffilter in filters:
            thisExt = ext * ebvConverters[ffilter]
            # log.info('ext %s, filter %s' % (thisExt, ffilter))
            thisPoly = np.poly1d([thisExt, ])
            extDict[ffilter] = thisPoly
        galExtPolyList.append(extDict)

    # INCLUDE GALAXTIC EXTINTION IN LIGHTCURVES
    galExtLightCurveList = []
    for item in range(len(kCorApparentLightCurveList)):
        thisModel = snTypesArray[item]
        # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']
        explosionDay = rawLightCurveDict[thisModel][
            restFrameFilter]['Explosion Day Relative to Peak']
        endOfLightcurveDay = snLightCurves[thisModel][
            'End of lightcurve relative to peak']
        log.info(
            'explosionDay, endOfLightcurveDay for galatic extinction corr Frame Light Curve: %s, %s' %
            (explosionDay, endOfLightcurveDay))
        lcDict = {}
        plotLcDict = {}
        for ffilter in filters:
            if kCorApparentLightCurveList[item][ffilter] is not None:
                galExtLightCurve = kCorApparentLightCurveList[
                    item][ffilter] + galExtPolyList[item][ffilter]
                # log.debug('apparentLightCurve %s' % (apparentLightCurve,))
                galExtPoly = np.poly1d(galExtLightCurve)
                plotLcDict[ffilter] = galExtPoly
            else:
                galExtPoly = None
            lcDict[ffilter] = galExtPoly
        if plot:
            dp.plot_polynomial(
                log,
                title="Galactic Extinction Corrected Lightcurves - SN Number %s" % (
                    item),
                polynomialDict=plotLcDict,
                orginalDataDictionary=False,
                pathToOutputPlotsFolder=pathToOutputPlotDirectory,
                xRange=[explosionDay, endOfLightcurveDay],
                xlabel="Days Relative to Peak (Rest Frame)",
                ylabel="Apparent Magnitude",
                xAxisLimits=False,
                yAxisLimits=False,
                yAxisInvert=True,
                prependNum=stepNum)

        galExtLightCurveList.append(lcDict)

    ###########################################################
    # STEP 5 - TIME-DILATE LIGHTCURVES                        #
    ###########################################################
    stepNum += 1
    stepStr = "%02d" % stepNum
    observedFrameLightCurveInfo = []
    peakAppMagList = []
    for item in range(len(redshiftArray)):
        timeDilation = 1. + redshiftArray[item]
        thisModel = snTypesArray[item]
        # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']*timeDilation
        explosionDay = rawLightCurveDict[thisModel][restFrameFilter][
            'Explosion Day Relative to Peak'] * timeDilation
        endOfLightcurveDay = snLightCurves[thisModel][
            'End of lightcurve relative to peak'] * timeDilation
        log.info(
            'explosionDay, endOfLightcurveDay for observed time dil Frame Light Curve: %s, %s' %
            (explosionDay, endOfLightcurveDay))
        polyDict = {}
        lcPolyDict = {}
        peakMagDict = {}
        floatPeakMagDict = {}

        for ffilter in filters:
            if galExtLightCurveList[item][ffilter] is not None:
                xList = []
                yList = []
                for x in range(int(explosionDay), int(endOfLightcurveDay)):
                    xList.append(x * timeDilation)
                    y = galExtLightCurveList[item][ffilter](x)
                    yList.append(y)

                x = np.array(xList)
                y = np.array(yList)
                thisPoly = np.polyfit(x, y, polyOrder)
                flatPoly = np.poly1d(thisPoly)
                peakMag = flatPoly(0)
                floatPeakMag = float(peakMag)
                polyDict[ffilter] = flatPoly
                peakMagDict[ffilter] = peakMag
                floatPeakMagDict[ffilter] = floatPeakMag
                lcPolyDict[ffilter] = flatPoly
            else:
                polyDict[ffilter] = None
                peakMagDict[ffilter] = None
                floatPeakMagDict[ffilter] = None

        if plot:
            dp.plot_polynomial(
                log,
                title="Observed Lightcurves - SN Number %s" % (item, ),
                polynomialDict=lcPolyDict,
                orginalDataDictionary=False,
                pathToOutputPlotsFolder=pathToOutputPlotDirectory,
                xRange=[explosionDay, endOfLightcurveDay],
                xlabel="Days Relative to Peak (Observed Frame)",
                ylabel="Apparent Magnitude",
                xAxisLimits=False,
                yAxisLimits=False,
                yAxisInvert=True,
                prependNum=stepNum,
                legend=True)

        thisData = {
            'lightCurves': polyDict,
            'peakMags': peakMagDict,
            'explosionDay': explosionDay,
            'endOfLightcurveDay': endOfLightcurveDay}
        # log.info('peakMagDict %s' % (peakMagDict,))
        observedFrameLightCurveInfo.append(thisData)
        peakAppMagList.append(floatPeakMagDict)

    return observedFrameLightCurveInfo, peakAppMagList
Example #3
0
def convert_lightcurves_to_observered_frame(
        log,
        snLightCurves,
        rawLightCurveDict,
        redshiftArray,
        snTypesArray,
        peakMagnitudesArray,
        hostExtinctionArray,
        kCorrectionArray,
        galacticExtinctionArray,
        restFrameFilter,
        pathToOutputDirectory,
        pathToOutputPlotDirectory,
        polyOrder,
        plot=True):
    """
    *Given all the randomly generated parameters of the survey, generate a dictionary of lightcurves for each object (one lightcurve per filter)*

    **Key Arguments:**
        - ``log`` -- logger
        - ``snLightCurves`` -- the sn lightcurve dictionary (with explosion / extinction dates)
        - ``rawLightCurveDict`` -- dictionary of the raw lightcurves (all peaking at mag = 0)
        - ``redshiftArray`` -- array of random redshifts,
        - ``snTypesArray`` --  array of random sn types,
        - ``peakMagnitudesArray`` --  array of random peak mags,
        - ``kCorrectionArray`` -- array of k-corrections,
        - ``hostExtinctionArray`` --  array of random host extinctions,
        - ``galacticExtinctionArray`` --  array of random galactic extinctions,
        - ``restFrameFilter`` -- the observed frame filter with which to calculate k-corrections with
        - ``pathToOutputDirectory`` -- path to the output directory (provided by the user)
        - ``pathToOutputPlotDirectory`` -- path to the output plot directory
        - ``polyOrder`` -- order of the polynomial used to fit the lightcurve
        - ``plot`` -- generate plots?

    **Return:**
        - None
    """
    ################ > IMPORTS ################
    ## STANDARD LIB ##
    ## THIRD PARTY ##
    import numpy as np
    import matplotlib.pyplot as plt
    import math
    import yaml
    ## LOCAL APPLICATION ##
    import dryxPython.astrotools as da
    import dryxPython.plotting as dp

    ################ >ACTION(S) ################
    filters = ['g', 'r', 'i', 'z']
    fileName = pathToOutputDirectory + "/transient_light_curves.yaml"
    stream = file(fileName, 'r')
    generatedLCs = yaml.load(stream)
    models = generatedLCs.keys()
    ebvConverters = {'g': 3.793, 'r': 2.751, 'i': 2.086, 'z': 1.479}
    stepNum = 0

    ###########################################################
    # STEP 1 - CONVERT RAW LIGHTCURVES TO ABSOLUTE MAG CURVES #
    ###########################################################
    stepNum += 1
    stepStr = "%02d" % stepNum
    # CONVERT PEAK MAGS TO POLYNOMIALS
    peakMagPolyList = []
    for item in peakMagnitudesArray:
        thisPoly = np.poly1d([item, ])
        peakMagPolyList.append(thisPoly)

    # CONVERT RAW LIGHTCURVES TO ABSOLUTE MAG CURVES
    absLightCurveList = []
    exampleDictionary = {}

    for item in range(len(snTypesArray)):
        thisModel = snTypesArray[item]
        # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']
        log.debug('thisModel, restFrameFilter: %s, %s' %
                  (thisModel, restFrameFilter,))
        explosionDay = rawLightCurveDict[thisModel][
            restFrameFilter]['Explosion Day Relative to Peak']
        endOfLightcurveDay = snLightCurves[thisModel][
            'End of lightcurve relative to peak']
        log.info(
            'explosionDay, endOfLightcurveDay for absolute Light Curve: %s, %s' %
            (explosionDay, endOfLightcurveDay))
        absLightCurve = rawLightCurveDict[thisModel][
            restFrameFilter]['poly'] + peakMagPolyList[item]
        absLightCurve = np.poly1d(absLightCurve)
        absLightCurveList.append(absLightCurve)
        exampleDictionary['SN %02d @ z = %04.3f' %
                          (item, redshiftArray[item])] = absLightCurve
    if plot:
        plot_polynomial(
            log,
            title="Absoulte Magnitude Lightcurves - random sample",
            polynomialDict=exampleDictionary,
            orginalDataDictionary=False,
            pathToOutputPlotsFolder=pathToOutputPlotDirectory,
            xRange=[explosionDay, endOfLightcurveDay],
            xlabel="Days Relative to Peak (Rest Frame)",
            ylabel="Absolute Magnitude",
            xAxisLimits=False,
            yAxisLimits=False,
            yAxisInvert=True,
            prependNum=stepNum)

    ################################################################
    # STEP 2 - CONVERT ABSOLUTE LIGHTCURVES TO APPARENT MAG CURVES #
    ################################################################
    stepNum += 1
    stepStr = "%02d" % stepNum
    # CONVERT DISTANCE MOD TO POLYNOMIALS
    distanceModPolyList = []
    for item in redshiftArray:
        log.debug('redshift: %s' % (item,))
        if item == 0.0:
            item = 0.01
        distanceDictionary = da.convert_redshift_to_distance(item)
        distanceMpc = distanceDictionary["dl_mpc"]
        distanceModulus = distanceDictionary["dmod"]
        # log.debug('distanceMpc %s' % (distanceMpc,))
        # log.info('redshift %s = distanceModulus %s' % (item, distanceModulus,))
        thisPoly = np.poly1d([distanceModulus, ])
        distanceModPolyList.append(thisPoly)

    # CONVERT ABSOLUTE LIGHTCURVES TO APPARENT MAG CURVES
    apparentLightCurveList = []
    for item in range(len(snTypesArray)):
        thisModel = snTypesArray[item]
        # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']
        explosionDay = rawLightCurveDict[thisModel][
            restFrameFilter]['Explosion Day Relative to Peak']
        endOfLightcurveDay = snLightCurves[thisModel][
            'End of lightcurve relative to peak']
        log.info(
            'explosionDay, endOfLightcurveDay for apparent Light Curve: %s, %s' %
            (explosionDay, endOfLightcurveDay))
        apparentLightCurve = absLightCurveList[
            item] + distanceModPolyList[item]
        # log.debug('apparentLightCurve %s' % (apparentLightCurve,))
        apparentLightCurve = np.poly1d(apparentLightCurve)
        apparentLightCurveList.append(apparentLightCurve)
        exampleDictionary['SN %02d @ z = %04.3f' %
                          (item, redshiftArray[item])] = apparentLightCurve
        #log.info('absLightCurveDictionary %s' % (absLightCurveDictionary,))
    if plot:
        plot_polynomial(
            log,
            title="Pre-KCorrection Apparent Magnitude Lightcurves - random sample",
            polynomialDict=exampleDictionary,
            orginalDataDictionary=False,
            pathToOutputPlotsFolder=pathToOutputPlotDirectory,
            xRange=[explosionDay, endOfLightcurveDay],
            xlabel="Days Relative to Peak (Rest Frame)",
            ylabel="Apparent Magnitude",
            xAxisLimits=False,
            yAxisLimits=False,
            yAxisInvert=True,
            prependNum=stepNum)

    ###########################################################
    # STEP 3 - (UN) K-CORRECT THE APPARENT LIGHTCURVES        #
    ###########################################################
    stepNum += 1
    stepStr = "%02d" % stepNum
    # (UN) K-CORRECT THE APPARENT LIGHTCURVES
    kCorApparentLightCurveList = []
    for i in range(len(apparentLightCurveList)):
        thisModel = snTypesArray[i]
        # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']
        explosionDay = rawLightCurveDict[thisModel][
            restFrameFilter]['Explosion Day Relative to Peak']
        endOfLightcurveDay = snLightCurves[thisModel][
            'End of lightcurve relative to peak']
        log.info(
            'explosionDay, endOfLightcurveDay for unkcor apparent Light Curve: %s, %s' %
            (explosionDay, endOfLightcurveDay))
        kCorDict = kCorrectionArray[i]
        lcDict = {}
        plotLcDict = {}
        for ffilter, poly in kCorDict.iteritems():
            if poly is None:
                kcorLightCurve = None
            else:
                kcorLightCurve = apparentLightCurveList[i] - poly
                plotLcDict[ffilter] = kcorLightCurve
            lcDict[ffilter] = kcorLightCurve
            if plot:
                plot_polynomial(
                    log,
                    title="K(un)corrected Apparent Magnitude Lightcurves - SN Number %s" % (
                        i),
                    polynomialDict=plotLcDict,
                    orginalDataDictionary=False,
                    pathToOutputPlotsFolder=pathToOutputPlotDirectory,
                    xRange=[explosionDay, endOfLightcurveDay],
                    xlabel="Days Relative to Peak (Rest Frame)",
                    ylabel="Apparent Magnitude",
                    xAxisLimits=False,
                    yAxisLimits=False,
                    yAxisInvert=True,
                    prependNum=stepNum)

        kCorApparentLightCurveList.append(lcDict)

    ###########################################################
    # STEP 4 - INCLUDE GALACTIC EXTINCTION IN LIGHTCURVES     #
    ###########################################################
    stepNum += 1
    stepStr = "%02d" % stepNum
    # INCLUDE GALACTIC EXTINCTION
    # CONVERT EXT TO POLYNOMIALS
    galExtPolyList = []
    for ext in galacticExtinctionArray:
        extDict = {}
        for ffilter in filters:
            thisExt = ext * ebvConverters[ffilter]
            # log.info('ext %s, filter %s' % (thisExt, ffilter))
            thisPoly = np.poly1d([thisExt, ])
            extDict[ffilter] = thisPoly
        galExtPolyList.append(extDict)

    # INCLUDE GALAXTIC EXTINTION IN LIGHTCURVES
    galExtLightCurveList = []
    for item in range(len(kCorApparentLightCurveList)):
        thisModel = snTypesArray[item]
        # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']
        explosionDay = rawLightCurveDict[thisModel][
            restFrameFilter]['Explosion Day Relative to Peak']
        endOfLightcurveDay = snLightCurves[thisModel][
            'End of lightcurve relative to peak']
        log.info(
            'explosionDay, endOfLightcurveDay for galatic extinction corr Frame Light Curve: %s, %s' %
            (explosionDay, endOfLightcurveDay))
        lcDict = {}
        plotLcDict = {}
        for ffilter in filters:
            if kCorApparentLightCurveList[item][ffilter] is not None:
                galExtLightCurve = kCorApparentLightCurveList[
                    item][ffilter] + galExtPolyList[item][ffilter]
                # log.debug('apparentLightCurve %s' % (apparentLightCurve,))
                galExtPoly = np.poly1d(galExtLightCurve)
                plotLcDict[ffilter] = galExtPoly
            else:
                galExtPoly = None
            lcDict[ffilter] = galExtPoly
        if plot:
            plot_polynomial(
                log,
                title="Galactic Extinction Corrected Lightcurves - SN Number %s" % (
                    item),
                polynomialDict=plotLcDict,
                orginalDataDictionary=False,
                pathToOutputPlotsFolder=pathToOutputPlotDirectory,
                xRange=[explosionDay, endOfLightcurveDay],
                xlabel="Days Relative to Peak (Rest Frame)",
                ylabel="Apparent Magnitude",
                xAxisLimits=False,
                yAxisLimits=False,
                yAxisInvert=True,
                prependNum=stepNum)

        galExtLightCurveList.append(lcDict)

    ###########################################################
    # STEP 5 - TIME-DILATE LIGHTCURVES                        #
    ###########################################################
    stepNum += 1
    stepStr = "%02d" % stepNum
    observedFrameLightCurveInfo = []
    peakAppMagList = []
    for item in range(len(redshiftArray)):
        timeDilation = 1. + redshiftArray[item]
        thisModel = snTypesArray[item]
        # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']*timeDilation
        explosionDay = rawLightCurveDict[thisModel][restFrameFilter][
            'Explosion Day Relative to Peak'] * timeDilation
        endOfLightcurveDay = snLightCurves[thisModel][
            'End of lightcurve relative to peak'] * timeDilation
        log.info(
            'explosionDay, endOfLightcurveDay for observed time dil Frame Light Curve: %s, %s' %
            (explosionDay, endOfLightcurveDay))
        polyDict = {}
        lcPolyDict = {}
        peakMagDict = {}
        floatPeakMagDict = {}

        for ffilter in filters:
            if galExtLightCurveList[item][ffilter] is not None:
                xList = []
                yList = []
                for x in range(int(explosionDay), int(endOfLightcurveDay)):
                    xList.append(x * timeDilation)
                    y = galExtLightCurveList[item][ffilter](x)
                    yList.append(y)

                x = np.array(xList)
                y = np.array(yList)
                thisPoly = np.polyfit(x, y, polyOrder)
                flatPoly = np.poly1d(thisPoly)
                peakMag = flatPoly(0)
                floatPeakMag = float(peakMag)
                polyDict[ffilter] = flatPoly
                peakMagDict[ffilter] = peakMag
                floatPeakMagDict[ffilter] = floatPeakMag
                lcPolyDict[ffilter] = flatPoly
            else:
                polyDict[ffilter] = None
                peakMagDict[ffilter] = None
                floatPeakMagDict[ffilter] = None

        if plot:
            plot_polynomial(
                log,
                title="Observed Lightcurves - SN Number %s" % (item, ),
                polynomialDict=lcPolyDict,
                orginalDataDictionary=False,
                pathToOutputPlotsFolder=pathToOutputPlotDirectory,
                xRange=[explosionDay, endOfLightcurveDay],
                xlabel="Days Relative to Peak (Observed Frame)",
                ylabel="Apparent Magnitude",
                xAxisLimits=False,
                yAxisLimits=False,
                yAxisInvert=True,
                prependNum=stepNum,
                legend=True)

        thisData = {
            'lightCurves': polyDict,
            'peakMags': peakMagDict,
            'explosionDay': explosionDay,
            'endOfLightcurveDay': endOfLightcurveDay}
        # log.info('peakMagDict %s' % (peakMagDict,))
        observedFrameLightCurveInfo.append(thisData)
        peakAppMagList.append(floatPeakMagDict)

    return observedFrameLightCurveInfo, peakAppMagList
Example #4
0
def random_redshift_array(
        log,
        sampleNumber,
        lowerRedshiftLimit,
        upperRedshiftLimit,
        redshiftResolution,
        pathToOutputPlotDirectory,
        plot=False):
    """
    *Generate a NumPy array of random distances given a sample number and distance limit*

    **Key Arguments:**
        - ``log`` -- logger
        - ``sampleNumber`` -- the sample number, i.e. array size
        - ``lowerRedshiftLimit`` -- the lower redshift limit of the volume to be included
        - ``upperRedshiftLimit`` -- the upper redshift limit of the volume to be included
        - ``redshiftResolution`` -- the resolution of the redshift distribution
        - ``pathToOutputPlotDirectory`` -- path to the output directory (provided by the user)
        - ``plot`` -- generate plot?

    **Return:**
        - ``redshiftArray`` -- an array of random redshifts within the volume limit
    """
    ################ > IMPORTS ################
    ## STANDARD LIB ##
    ## THIRD PARTY ##
    import matplotlib.pyplot as plt
    import numpy as np
    import numpy.random as npr
    ## LOCAL APPLICATION ##
    import dryxPython.astrotools as da

    redshiftDistribution = np.arange(
        0., upperRedshiftLimit, redshiftResolution)
    closestNumber = lambda n, l: min(l, key=lambda x: abs(x - n))

    # GIVEN THE REDSHIFT LIMIT - DETERMINE THE VOLUME LIMIT
    distanceDictionary = da.convert_redshift_to_distance(upperRedshiftLimit)
    upperMpcLimit = distanceDictionary["dl_mpc"]
    upperVolumeLimit = (4. / 3.) * np.pi * upperMpcLimit ** 3

    if lowerRedshiftLimit == 0.:
        lowerVolumeLimit = 0.
    else:
        distanceDictionary = da.convert_redshift_to_distance(
            lowerRedshiftLimit)
        lowerMpcLimit = distanceDictionary["dl_mpc"]
        lowerVolumeLimit = (4. / 3.) * np.pi * lowerMpcLimit ** 3

    volumeShell = upperVolumeLimit - lowerVolumeLimit

    # GENERATE A LIST OF RANDOM DISTANCES
    redshiftList = []
    for i in range(sampleNumber):
        randomVolume = lowerVolumeLimit + npr.random() * volumeShell
        randomDistance = (randomVolume * (3. / 4.) / np.pi) ** (1. / 3.)
        randomRedshift = da.convert_mpc_to_redshift(randomDistance)
        randomRedshift = closestNumber(randomRedshift, redshiftDistribution)
        # log.debug('randomDistance %s' % (randomDistance,))
        redshiftList.append(randomRedshift)

    redshiftArray = np.array(redshiftList)
    # log.info('redshiftArray %s' % (redshiftArray,))

    if plot:
        # FORCE SQUARE FIGURE AND SQUARE AXES LOOKS BETTER FOR POLAR
        fig = plt.figure(
            num=None,
            figsize=(8, 8),
            dpi=None,
            facecolor=None,
            edgecolor=None,
            frameon=True)

        ax = fig.add_axes(
            [0.1, 0.1, 0.8, 0.8],
            polar=True)

        thetaList = []
        twoPi = 2. * np.pi
        for i in range(sampleNumber):
            thetaList.append(twoPi * npr.random())
        thetaArray = np.array(thetaList)

        plt.scatter(
            thetaArray,
            redshiftArray,
            s=10,
            c='b',
            marker='o',
            cmap=None,
            norm=None,
            vmin=None,
            vmax=None,
            alpha=None,
            linewidths=None,
            edgecolor='w',
            verts=None,
            hold=None)

        title = "SN Redshift Distribution"
        plt.title(title)
        fileName = pathToOutputPlotDirectory + title.replace(" ", "_") + ".png"
        plt.savefig(fileName)
        plt.clf()  # clear figure

    return redshiftArray
Example #5
0
def determine_sn_rate(
        log,
        lightCurveDiscoveryTimes,
        snSurveyDiscoveryTimes,
        redshifts,
        surveyCadenceSettings,
        surveyArea,
        CCSNRateFraction,
        transientToCCSNRateFraction,
        peakAppMagList,
        snCampaignLengthList,
        extraSurveyConstraints,
        pathToOutputPlotFolder,
        lowerRedshiftLimit=0.01,
        upperRedshiftLimit=1.0,
        redshiftResolution=0.1
):
    """
    *Plot the SFR History as a function of redshift*

    **Key Arguments:**
        - ``log`` -- logger
        - ``lightCurveDiscoveryTimes`` -- the lightcurve discovery times of the SN
        - ``snSurveyDiscoveryTimes`` -- the supernova discovery times relative to the survey year
        - ``redshifts`` -- the redshifts of the SN
        - ``surveyArea`` -- the area of the survey considered in square degree
        - ``surveyCadenceSettings`` -- the cadence settings for the survey
        - ``CCSNRateFraction`` -- the fraction of the IMF attributed to the progenitors of CCSN
        - ``transientToCCSNRateFraction`` -- the ratio of the transient rate to the rate of CCSNe
        - ``peakAppMagList`` -- a list of the peak magnitudes for each SN in each filter
        - ``snCampaignLengthList`` -- a list of campaign lengths in each filter
        - ``extraSurveyConstraints`` -- some extra survey constraints
        - ``pathToOutputPlotDirectory`` -- path to add plots to
        - ``lowerRedshiftLimit`` -- the lower redshist limit out to which to determine the rate
        - ``upperRedshiftLimit`` -- the redshist limit out to which to determine the rate
        - ``redshiftResolution`` -- the redshist resolution ued to determine the rate

    **Return:**
        - ``imageLink`` -- MD link to the output plot
        - ``totalRate`` -- the final transient rate calculated
    """
    ################ > IMPORTS ################
    ## STANDARD LIB ##
    ## THIRD PARTY ##
    import numpy as np
    ## LOCAL APPLICATION ##
    import dryxPython.astrotools as da
    import dryxPython.plotting as dp

    ################ >ACTION(S) ################
    filters = ['g', 'r', 'i', 'z']

    sdssArea = 5713.
    sdssSFRupperRedshiftLimit = 0.033
    sdssSFR = 14787.21
    # CCSNRateFraction = 0.007
    # transientToCCSNRateFraction = 1./10000.
    transientRateFraction = float(
        CCSNRateFraction) * float(transientToCCSNRateFraction)

    anchor = redshiftResolution / sdssSFRupperRedshiftLimit
    normaiseSFR = sdssSFR * anchor**3
    areaRatio = surveyArea / sdssArea
    #log.info('normaiseSFR %s' % (normaiseSFR,))

    anchorVolume = da.convert_redshift_to_distance(redshiftResolution)[
        'dl_mpc']**3
    #log.info('anchorVolume %s' % (anchorVolume,))
    xRange = [lowerRedshiftLimit, upperRedshiftLimit, redshiftResolution]

    multiplier = int(1 / redshiftResolution)
    redshiftResolution = int(redshiftResolution * multiplier)
    upperRedshiftLimit = int(upperRedshiftLimit * multiplier)

    shelltransientRateDensityList = []
    shellRedshiftList = []
    discoveryRedshiftList = []
    discoveryFractionList = []
    tooFaintRedshiftList = []
    tooFaintFractionList = []
    shortCampaignRedshiftList = []
    shortCampaignFractionList = []
    transientShellRateList = []
    tooFaintShellRateList = []
    shortCampaignShellRateList = []

    count = 0
    for shellRedshift in np.arange(lowerRedshiftLimit, upperRedshiftLimit, redshiftResolution):
        count += 1
        shellRedshift = float(shellRedshift) / float(multiplier)
        shellWidth = float(redshiftResolution) / float(multiplier)
        shellMiddle = shellRedshift - shellWidth / 2.
        shellRedshiftBottom = shellRedshift - shellWidth
        log.debug('%s. shellRedshift %s' % (count, shellRedshift,))
        log.debug('%s. shellWidth %s' % (count, shellWidth,))
        log.debug('%s. shellMiddle %s' % (count, shellMiddle,))
        log.debug('%s. shellRedshiftBottom %s' % (count, shellRedshiftBottom,))

        SFH = (1. + shellMiddle)**2.5
        if shellRedshift == 0.:
            shellVolume = 9.
        elif shellRedshift > shellWidth:
            shellVolume = da.convert_redshift_to_distance(shellRedshift)[
                'dl_mpc']**3 - da.convert_redshift_to_distance(shellRedshift - shellWidth)['dl_mpc']**3
        else:
            shellVolume = da.convert_redshift_to_distance(shellRedshift)[
                'dl_mpc']**3
        shellSFRDensity = (SFH / anchor) * normaiseSFR * \
            (shellVolume / anchorVolume)
        shelltransientRateDensity = shellSFRDensity * transientRateFraction
        shelltransientRateDensity = shelltransientRateDensity * areaRatio
        timeDilation = 1. / (1. + shellMiddle)
        shelltransientRateDensity = shelltransientRateDensity * timeDilation

        log.debug('shelltransientRateDensity %s' %
                  (shelltransientRateDensity,))
        shelltransientRateDensityList.append(shelltransientRateDensity)
        shellRedshiftList.append(shellMiddle)

        discoveryFraction, tooFaintFraction, shortCampaignFraction = calculate_fraction_of_sn_discovered(
            log, surveyCadenceSettings, snSurveyDiscoveryTimes, redshifts, peakAppMagList, snCampaignLengthList, extraSurveyConstraints, shellRedshiftBottom, shellRedshift)
        # if discoveryFraction != 0.:
        discoveryRedshiftList.append(shellMiddle)
        discoveryFractionList.append(discoveryFraction)
        log.debug('shell redshift %s, discoveryFraction %s' %
                  (shellMiddle, discoveryFraction))
        # if tooFaintFraction != 0.:
        tooFaintRedshiftList.append(shellMiddle)
        tooFaintFractionList.append(tooFaintFraction)
        # if shortCampaignFraction != 0.:
        shortCampaignRedshiftList.append(shellMiddle)
        shortCampaignFractionList.append(shortCampaignFraction)

        transientShellRate = discoveryFraction * shelltransientRateDensity
        tooFaintShellRate = tooFaintFraction * shelltransientRateDensity
        shortCampaignShellRate = shortCampaignFraction * shelltransientRateDensity
        transientShellRateList.append(transientShellRate)
        tooFaintShellRateList.append(tooFaintShellRate)
        shortCampaignShellRateList.append(shortCampaignShellRate)

    discoveryRedshiftListArray = np.array(discoveryRedshiftList)
    discoveryFractionListArray = np.array(discoveryFractionList)
    tooFaintRedshiftListArray = np.array(tooFaintRedshiftList)
    tooFaintFractionListArray = np.array(tooFaintFractionList)
    shortCampaignRedshiftListArray = np.array(shortCampaignRedshiftList)
    shortCampaignFractionListArray = np.array(shortCampaignFractionList)
    polynomialDict = {}
    orginalDataDictionary = {}
    pleasePlot = False
    if len(discoveryRedshiftListArray) > 0:
        pleasePlot = True
        thisPoly = np.polyfit(discoveryRedshiftListArray,
                              discoveryFractionListArray, 12)
        discoveryRateCurve = np.poly1d(thisPoly)
        # polynomialDict["Discovery Rate"] = discoveryRateCurve
        orginalDataDictionary["Discovery Rate"] = [
            discoveryRedshiftListArray, discoveryFractionListArray]
    else:
        discoveryRateCurve = False
    if len(tooFaintRedshiftListArray) > 0:
        pleasePlot = True
        thisPoly = np.polyfit(tooFaintRedshiftListArray,
                              tooFaintFractionListArray, 12)
        tooFaintRateCurve = np.poly1d(thisPoly)
        #polynomialDict["Detected - too faint to constrain as transient"] = tooFaintRateCurve
        orginalDataDictionary["Detected - too faint to constrain as transient"] = [
            tooFaintRedshiftListArray, tooFaintFractionListArray]
    else:
        tooFaintRateCurve = False
    if len(shortCampaignRedshiftListArray) > 0:
        pleasePlot = True
        thisPoly = np.polyfit(shortCampaignRedshiftListArray,
                              shortCampaignFractionListArray, 12)
        shortCampaignRateCurve = np.poly1d(thisPoly)
        #polynomialDict["Detected - campaign to short to constrain as transient"] = shortCampaignRateCurve
        orginalDataDictionary["Detected - campaign to short to constrain as transient"] = [
            shortCampaignRedshiftListArray, shortCampaignFractionListArray]
    else:
        shortCampaignRateCurve = False

    if pleasePlot:

        imageLink = plot_polynomial(
            log,
            title='PS1-transient Survey - Precentage of transient Detected',
            polynomialDict=polynomialDict,
            orginalDataDictionary=orginalDataDictionary,
            pathToOutputPlotsFolder=pathToOutputPlotFolder,
            xRange=xRange,
            xlabel=False,
            ylabel=False,
            xAxisLimits=False,
            yAxisLimits=[-0.05, 1.05],
            yAxisInvert=False,
            prependNum=False,
            legend=True)
    else:
        imageLink = ""

    shelltransientRateDensityArray = np.array(shelltransientRateDensityList)
    shellRedshiftArray = np.array(shellRedshiftList)
    log.debug('shellRedshiftArray %s' % (shellRedshiftArray,))
    log.debug('shelltransientRateDensityArray %s' %
              (shelltransientRateDensityArray,))
    thisPoly = np.polyfit(shellRedshiftArray,
                          shelltransientRateDensityArray, 3)
    transientRateCurve = np.poly1d(thisPoly)
    # log.info('flat %s' % (flatPoly,))
    polynomialDict = {"transient Rate": transientRateCurve}
    orginalDataDictionary = {"transient Rate": [
        shellRedshiftArray, shelltransientRateDensityArray]}
    imageLink = plot_polynomial(
        log,
        title='PS1 MDF transient Rate Density',
        polynomialDict=polynomialDict,
        orginalDataDictionary=orginalDataDictionary,
        pathToOutputPlotsFolder=pathToOutputPlotFolder,
        xRange=xRange,
        xlabel=False,
        ylabel=False,
        xAxisLimits=False,
        yAxisLimits=False,
        yAxisInvert=False,
        prependNum=False)

    polynomialDict = {}
    orginalDataDictionary = {}
    pleasePlot = False
    if discoveryRateCurve:
        pleasePlot = True
        discoveredtransientCurve = transientRateCurve * discoveryRateCurve
        discoveredtransientCurve = np.poly1d(discoveredtransientCurve)
        #polynomialDict['Discovered transient Rate'] = discoveredtransientCurve
        orginalDataDictionary['Discovered transient Rate'] = [
            shellRedshiftArray, shelltransientRateDensityArray * discoveryFractionListArray]
    if tooFaintRateCurve:
        pleasePlot = True
        tooFainttransientCurve = transientRateCurve * tooFaintRateCurve
        tooFainttransientCurve = np.poly1d(tooFainttransientCurve)
        #polynomialDict["Detected - too faint to constrain as transient"] = tooFainttransientCurve
        orginalDataDictionary["Detected - too faint to constrain as transient"] = [
            shellRedshiftArray, shelltransientRateDensityArray * tooFaintFractionListArray]
    if shortCampaignRateCurve:
        pleasePlot = True
        shortCampaigntransientCurve = transientRateCurve * shortCampaignRateCurve
        shortCampaigntransientCurve = np.poly1d(shortCampaigntransientCurve)
        #polynomialDict["Detected - campaign to short to constrain as transient"] = shortCampaigntransientCurve
        orginalDataDictionary["Detected - campaign to short to constrain as transient"] = [
            shellRedshiftArray, shelltransientRateDensityArray * shortCampaignFractionListArray]

    maxInList = max(redshifts) * 1.1

    if pleasePlot:
        imageLink = plot_polynomial(
            log,
            title='PS1-transient Survey - Relative Detected Rates',
            polynomialDict=polynomialDict,
            orginalDataDictionary=orginalDataDictionary,
            pathToOutputPlotsFolder=pathToOutputPlotFolder,
            xRange=[0.01, maxInList, 0.01],
            xlabel=False,
            ylabel=False,
            xAxisLimits=False,
            yAxisLimits=[-0.05, 3.5],
            yAxisInvert=False,
            prependNum=False,
            legend=True)
    else:
        imageLink = ""

    log.debug('transientShellRateList: %s' % (transientShellRateList,))

    totalRate = 0.
    for item in transientShellRateList:
        totalRate += item

    tooFaintRate = 0.
    for item in tooFaintShellRateList:
        tooFaintRate += item

    shortCampaignRate = 0.
    for item in shortCampaignShellRateList:
        shortCampaignRate += item

    totalRate = "%1.0f" % (totalRate,)
    tooFaintRate = "%1.0f" % (tooFaintRate,)
    shortCampaignRate = "%1.0f" % (shortCampaignRate,)
    return imageLink, totalRate, tooFaintRate, shortCampaignRate
Example #6
0
    def searchCatalogue(self, objectList, searchPara={}, searchName=""):
        """Cone Search wrapper to make it a little more user friendly"""

        from sherlock import conesearcher

        # EXTRACT PARAMETERS FROM ARGUMENTS & SETTINGS FILE
        if "physical radius kpc" in searchPara:
            physicalSearch = True
            searchName = searchName + " physical"
        else:
            physicalSearch = False
            searchName = searchName + " angular"
        radius = searchPara["angular radius arcsec"]
        catalogueName = searchPara["database table"]
        matchedType = searchPara["transient classification"]

        # VARIABLES
        matchedObjects = []
        matchSubset = []
        searchDone = True

        # FAINT STAR EXTRAS
        try:
            magColumn = searchPara["mag column"]
            faintLimit = searchPara["faint limit"]
        except:
            magColumn = False
            faintLimit = False

        for row in objectList:
            cs = conesearcher(
                log=self.log,
                ra=row['ra'],
                dec=row['dec'],
                radius=radius,
                colMaps=self.colMaps,
                tableName=catalogueName,
                queryType=2,
                dbConn=self.dbConn,
                settings=self.settings,
                physicalSearch=physicalSearch,
                transType=searchPara["transient classification"]
            )
            message, xmObjects = cs.get()

            # DID WE SEARCH THE CATALOGUES CORRECTLY?
            if message and (message.startswith('Error') or 'not recognised' in message):
                # SUCCESSFUL CONE SEARCHES SHOULD NOT RETURN AN ERROR MESSAGE,
                # OTHERWISE SOMETHING WENT WRONG.
                print "Database error - cone search unsuccessful.  Message was:"
                print "\t%s" % message
                searchDone = False

            if xmObjects:
                numberOfMatches = len(xmObjects)
                nearestSep = xmObjects[0][0]
                nearestCatRow = xmObjects[0][1]
                nearestCatId = nearestCatRow[
                    self.colMaps[catalogueName]["objectNameColName"]]

                # CALCULATE PHYSICAL PARAMETERS ... IF WE CAN
                for xm in xmObjects:
                    redshift = None
                    xmz = None
                    xmscale = None
                    xmdistance = None
                    xmdistanceModulus = None
                    xmmajoraxis = None
                    xmdirectdistance = None
                    xmdirectdistancescale = None
                    xmdirectdistanceModulus = None

                    # IF THERE'S A REDSHIFT, CALCULATE PHYSICAL PARAMETERS
                    if self.colMaps[catalogueName]["redshiftColName"]:
                        # THE CATALOGUE HAS A REDSHIFT COLUMN
                        redshift = xm[1][
                            self.colMaps[catalogueName]["redshiftColName"]]
                    if redshift and redshift > 0.0:
                        # CALCULATE DISTANCE MODULUS, ETC
                        redshiftInfo = dat.convert_redshift_to_distance(
                            z=redshift
                        )
                        if redshiftInfo:
                            xmz = redshiftInfo['z']
                            xmscale = redshiftInfo['da_scale']
                            xmdistance = redshiftInfo['dl_mpc']
                            xmdistanceModulus = redshiftInfo['dmod']
                    # ADD MAJOR AXIS VALUE
                    if "or within semi major axis" in searchPara and searchPara["or within semi major axis"] == True and self.colMaps[catalogueName]["semiMajorColName"] and xm[1][self.colMaps[catalogueName]["semiMajorColName"]]:
                        xmmajoraxis = xm[1][
                            self.colMaps[catalogueName]["semiMajorColName"]] * self.colMaps[catalogueName]["semiMajorToArcsec"]
                    # ADD DISTANCE VALUES
                    if self.colMaps[catalogueName]["distanceColName"] and xm[1][self.colMaps[catalogueName]["distanceColName"]]:
                        xmdirectdistance = xm[1][
                            self.colMaps[catalogueName]["distanceColName"]]
                        xmdirectdistancescale = xmdirectdistance / 206.264806
                        xmdirectdistanceModulus = 5 * \
                            math.log10(xmdirectdistance * 1e6) - 5
                    xm[1]['xmz'] = xmz
                    xm[1]['xmscale'] = xmscale
                    xm[1]['xmdistance'] = xmdistance
                    xm[1]['xmdistanceModulus'] = xmdistanceModulus
                    xm[1]['xmmajoraxis'] = xmmajoraxis
                    xm[1]['xmdirectdistance'] = xmdirectdistance
                    xm[1]['xmdirectdistancescale'] = xmdirectdistancescale
                    xm[1]['xmdirectdistanceModulus'] = xmdirectdistanceModulus

                # GRAB SOURCE TYPES
                for xm in xmObjects:
                    subType = None
                    # IF THERE'S A SUBTYPE - ADD IT
                    if self.colMaps[catalogueName]["subTypeColName"]:
                        # THE CATALOGUE HAS A REDSHIFT COLUMN
                        subType = xm[1][
                            self.colMaps[catalogueName]["subTypeColName"]]
                        if subType == "null":
                            subType = None

                    xm[1]['sourceSubType'] = subType
                    xm[1]['sourceType'] = self.colMaps[
                        catalogueName]["object_type"]
                    xm[1]["searchName"] = searchName
                    xm[1]["sourceRa"] = xm[1][
                        self.colMaps[catalogueName]["raColName"]]
                    xm[1]["sourceDec"] = xm[1][
                        self.colMaps[catalogueName]["decColName"]]
                    xm[1]["originalSearchRadius"] = radius

                matchedObjects.append(
                    [row, xmObjects, catalogueName, matchedType])

        # FAINT STAR CUTS
        if searchDone and matchedObjects and magColumn:
            faintStarMatches = []
            matchSubset = []
            for row in matchedObjects[0][1]:
                rMag = row[1][magColumn]
                if rMag and rMag > faintLimit:
                    matchSubset.append(row)
            if matchSubset:
                faintStarMatches.append(
                    [matchedObjects[0][0], matchSubset, matchedObjects[0][2], matchedObjects[0][3]])
            matchedObjects = faintStarMatches
        elif "tcs_view_star_sdss" in catalogueName:
            sdssStarMatches = []
            matchSubset = []
            if searchDone and matchedObjects:
                for row in matchedObjects[0][1]:
                    rMag = row[1]["petroMag_r"]
                    separation = row[0]
                    # Line passes through (x,y) = (2.5,18) and (19,13)
                    lineTwo = -((18 - 13) / (19 - 2.5)) * \
                        separation + 13 + 19 * ((18 - 13) / (19 - 2.5))
                    if rMag < 13.0:
                        matchSubset.append(row)
                    elif rMag >= 13.0 and rMag < 18.0:
                        if rMag < lineTwo:
                            matchSubset.append(row)
                    elif rMag >= 18.0 and separation < 2.5:
                        matchSubset.append(row)
            if matchSubset:
                sdssStarMatches.append(
                    [matchedObjects[0][0], matchSubset, matchedObjects[0][2], matchedObjects[0][3]])
            matchedObjects = sdssStarMatches

        if "match nearest source only" in searchPara and searchPara["match nearest source only"] == True and len(matchedObjects):
            matchedObjects = [[matchedObjects[0][0], [
                matchedObjects[0][1][0]], matchedObjects[0][2], matchedObjects[0][3]]]

        return searchDone, matchedObjects
Example #7
0
def determine_sn_rate(log,
                      lightCurveDiscoveryTimes,
                      snSurveyDiscoveryTimes,
                      redshifts,
                      surveyCadenceSettings,
                      surveyArea,
                      CCSNRateFraction,
                      transientToCCSNRateFraction,
                      peakAppMagList,
                      snCampaignLengthList,
                      extraSurveyConstraints,
                      pathToOutputPlotFolder,
                      lowerRedshiftLimit=0.01,
                      upperRedshiftLimit=1.0,
                      redshiftResolution=0.1):
    """
    *Plot the SFR History as a function of redshift*

    **Key Arguments:**
        - ``log`` -- logger
        - ``lightCurveDiscoveryTimes`` -- the lightcurve discovery times of the SN
        - ``snSurveyDiscoveryTimes`` -- the supernova discovery times relative to the survey year
        - ``redshifts`` -- the redshifts of the SN
        - ``surveyArea`` -- the area of the survey considered in square degree
        - ``surveyCadenceSettings`` -- the cadence settings for the survey
        - ``CCSNRateFraction`` -- the fraction of the IMF attributed to the progenitors of CCSN
        - ``transientToCCSNRateFraction`` -- the ratio of the transient rate to the rate of CCSNe
        - ``peakAppMagList`` -- a list of the peak magnitudes for each SN in each filter
        - ``snCampaignLengthList`` -- a list of campaign lengths in each filter
        - ``extraSurveyConstraints`` -- some extra survey constraints
        - ``pathToOutputPlotDirectory`` -- path to add plots to
        - ``lowerRedshiftLimit`` -- the lower redshist limit out to which to determine the rate
        - ``upperRedshiftLimit`` -- the redshist limit out to which to determine the rate
        - ``redshiftResolution`` -- the redshist resolution ued to determine the rate

    **Return:**
        - ``imageLink`` -- MD link to the output plot
        - ``totalRate`` -- the final transient rate calculated
    """
    ################ > IMPORTS ################
    ## STANDARD LIB ##
    ## THIRD PARTY ##
    import numpy as np
    ## LOCAL APPLICATION ##
    import dryxPython.astrotools as da
    import dryxPython.plotting as dp

    ################ >ACTION(S) ################
    filters = ['g', 'r', 'i', 'z']

    sdssArea = 5713.
    sdssSFRupperRedshiftLimit = 0.033
    sdssSFR = 14787.21
    # CCSNRateFraction = 0.007
    # transientToCCSNRateFraction = 1./10000.
    transientRateFraction = float(CCSNRateFraction) * float(
        transientToCCSNRateFraction)

    anchor = redshiftResolution / sdssSFRupperRedshiftLimit
    normaiseSFR = sdssSFR * anchor**3
    areaRatio = surveyArea / sdssArea
    #log.info('normaiseSFR %s' % (normaiseSFR,))

    anchorVolume = da.convert_redshift_to_distance(
        redshiftResolution)['dl_mpc']**3
    #log.info('anchorVolume %s' % (anchorVolume,))
    xRange = [lowerRedshiftLimit, upperRedshiftLimit, redshiftResolution]

    multiplier = int(1 / redshiftResolution)
    redshiftResolution = int(redshiftResolution * multiplier)
    upperRedshiftLimit = int(upperRedshiftLimit * multiplier)

    shelltransientRateDensityList = []
    shellRedshiftList = []
    discoveryRedshiftList = []
    discoveryFractionList = []
    tooFaintRedshiftList = []
    tooFaintFractionList = []
    shortCampaignRedshiftList = []
    shortCampaignFractionList = []
    transientShellRateList = []
    tooFaintShellRateList = []
    shortCampaignShellRateList = []

    count = 0
    for shellRedshift in np.arange(lowerRedshiftLimit, upperRedshiftLimit,
                                   redshiftResolution):
        count += 1
        shellRedshift = float(shellRedshift) / float(multiplier)
        shellWidth = float(redshiftResolution) / float(multiplier)
        shellMiddle = shellRedshift - shellWidth / 2.
        shellRedshiftBottom = shellRedshift - shellWidth
        log.debug('%s. shellRedshift %s' % (
            count,
            shellRedshift,
        ))
        log.debug('%s. shellWidth %s' % (
            count,
            shellWidth,
        ))
        log.debug('%s. shellMiddle %s' % (
            count,
            shellMiddle,
        ))
        log.debug('%s. shellRedshiftBottom %s' % (
            count,
            shellRedshiftBottom,
        ))

        SFH = (1. + shellMiddle)**2.5
        if shellRedshift == 0.:
            shellVolume = 9.
        elif shellRedshift > shellWidth:
            shellVolume = da.convert_redshift_to_distance(
                shellRedshift)['dl_mpc']**3 - da.convert_redshift_to_distance(
                    shellRedshift - shellWidth)['dl_mpc']**3
        else:
            shellVolume = da.convert_redshift_to_distance(
                shellRedshift)['dl_mpc']**3
        shellSFRDensity = (SFH / anchor) * normaiseSFR * \
            (shellVolume / anchorVolume)
        shelltransientRateDensity = shellSFRDensity * transientRateFraction
        shelltransientRateDensity = shelltransientRateDensity * areaRatio
        timeDilation = 1. / (1. + shellMiddle)
        shelltransientRateDensity = shelltransientRateDensity * timeDilation

        log.debug('shelltransientRateDensity %s' %
                  (shelltransientRateDensity, ))
        shelltransientRateDensityList.append(shelltransientRateDensity)
        shellRedshiftList.append(shellMiddle)

        discoveryFraction, tooFaintFraction, shortCampaignFraction = calculate_fraction_of_sn_discovered(
            log, surveyCadenceSettings, snSurveyDiscoveryTimes, redshifts,
            peakAppMagList, snCampaignLengthList, extraSurveyConstraints,
            shellRedshiftBottom, shellRedshift)
        # if discoveryFraction != 0.:
        discoveryRedshiftList.append(shellMiddle)
        discoveryFractionList.append(discoveryFraction)
        log.debug('shell redshift %s, discoveryFraction %s' %
                  (shellMiddle, discoveryFraction))
        # if tooFaintFraction != 0.:
        tooFaintRedshiftList.append(shellMiddle)
        tooFaintFractionList.append(tooFaintFraction)
        # if shortCampaignFraction != 0.:
        shortCampaignRedshiftList.append(shellMiddle)
        shortCampaignFractionList.append(shortCampaignFraction)

        transientShellRate = discoveryFraction * shelltransientRateDensity
        tooFaintShellRate = tooFaintFraction * shelltransientRateDensity
        shortCampaignShellRate = shortCampaignFraction * shelltransientRateDensity
        transientShellRateList.append(transientShellRate)
        tooFaintShellRateList.append(tooFaintShellRate)
        shortCampaignShellRateList.append(shortCampaignShellRate)

    discoveryRedshiftListArray = np.array(discoveryRedshiftList)
    discoveryFractionListArray = np.array(discoveryFractionList)
    tooFaintRedshiftListArray = np.array(tooFaintRedshiftList)
    tooFaintFractionListArray = np.array(tooFaintFractionList)
    shortCampaignRedshiftListArray = np.array(shortCampaignRedshiftList)
    shortCampaignFractionListArray = np.array(shortCampaignFractionList)
    polynomialDict = {}
    orginalDataDictionary = {}
    pleasePlot = False
    if len(discoveryRedshiftListArray) > 0:
        pleasePlot = True
        thisPoly = np.polyfit(discoveryRedshiftListArray,
                              discoveryFractionListArray, 12)
        discoveryRateCurve = np.poly1d(thisPoly)
        # polynomialDict["Discovery Rate"] = discoveryRateCurve
        orginalDataDictionary["Discovery Rate"] = [
            discoveryRedshiftListArray, discoveryFractionListArray
        ]
    else:
        discoveryRateCurve = False
    if len(tooFaintRedshiftListArray) > 0:
        pleasePlot = True
        thisPoly = np.polyfit(tooFaintRedshiftListArray,
                              tooFaintFractionListArray, 12)
        tooFaintRateCurve = np.poly1d(thisPoly)
        #polynomialDict["Detected - too faint to constrain as transient"] = tooFaintRateCurve
        orginalDataDictionary[
            "Detected - too faint to constrain as transient"] = [
                tooFaintRedshiftListArray, tooFaintFractionListArray
            ]
    else:
        tooFaintRateCurve = False
    if len(shortCampaignRedshiftListArray) > 0:
        pleasePlot = True
        thisPoly = np.polyfit(shortCampaignRedshiftListArray,
                              shortCampaignFractionListArray, 12)
        shortCampaignRateCurve = np.poly1d(thisPoly)
        #polynomialDict["Detected - campaign to short to constrain as transient"] = shortCampaignRateCurve
        orginalDataDictionary[
            "Detected - campaign to short to constrain as transient"] = [
                shortCampaignRedshiftListArray, shortCampaignFractionListArray
            ]
    else:
        shortCampaignRateCurve = False

    if pleasePlot:

        imageLink = plot_polynomial(
            log,
            title='PS1-transient Survey - Precentage of transient Detected',
            polynomialDict=polynomialDict,
            orginalDataDictionary=orginalDataDictionary,
            pathToOutputPlotsFolder=pathToOutputPlotFolder,
            xRange=xRange,
            xlabel=False,
            ylabel=False,
            xAxisLimits=False,
            yAxisLimits=[-0.05, 1.05],
            yAxisInvert=False,
            prependNum=False,
            legend=True)
    else:
        imageLink = ""

    shelltransientRateDensityArray = np.array(shelltransientRateDensityList)
    shellRedshiftArray = np.array(shellRedshiftList)
    log.debug('shellRedshiftArray %s' % (shellRedshiftArray, ))
    log.debug('shelltransientRateDensityArray %s' %
              (shelltransientRateDensityArray, ))
    thisPoly = np.polyfit(shellRedshiftArray, shelltransientRateDensityArray,
                          3)
    transientRateCurve = np.poly1d(thisPoly)
    # log.info('flat %s' % (flatPoly,))
    polynomialDict = {"transient Rate": transientRateCurve}
    orginalDataDictionary = {
        "transient Rate": [shellRedshiftArray, shelltransientRateDensityArray]
    }
    imageLink = plot_polynomial(log,
                                title='PS1 MDF transient Rate Density',
                                polynomialDict=polynomialDict,
                                orginalDataDictionary=orginalDataDictionary,
                                pathToOutputPlotsFolder=pathToOutputPlotFolder,
                                xRange=xRange,
                                xlabel=False,
                                ylabel=False,
                                xAxisLimits=False,
                                yAxisLimits=False,
                                yAxisInvert=False,
                                prependNum=False)

    polynomialDict = {}
    orginalDataDictionary = {}
    pleasePlot = False
    if discoveryRateCurve:
        pleasePlot = True
        discoveredtransientCurve = transientRateCurve * discoveryRateCurve
        discoveredtransientCurve = np.poly1d(discoveredtransientCurve)
        #polynomialDict['Discovered transient Rate'] = discoveredtransientCurve
        orginalDataDictionary['Discovered transient Rate'] = [
            shellRedshiftArray,
            shelltransientRateDensityArray * discoveryFractionListArray
        ]
    if tooFaintRateCurve:
        pleasePlot = True
        tooFainttransientCurve = transientRateCurve * tooFaintRateCurve
        tooFainttransientCurve = np.poly1d(tooFainttransientCurve)
        #polynomialDict["Detected - too faint to constrain as transient"] = tooFainttransientCurve
        orginalDataDictionary[
            "Detected - too faint to constrain as transient"] = [
                shellRedshiftArray,
                shelltransientRateDensityArray * tooFaintFractionListArray
            ]
    if shortCampaignRateCurve:
        pleasePlot = True
        shortCampaigntransientCurve = transientRateCurve * shortCampaignRateCurve
        shortCampaigntransientCurve = np.poly1d(shortCampaigntransientCurve)
        #polynomialDict["Detected - campaign to short to constrain as transient"] = shortCampaigntransientCurve
        orginalDataDictionary[
            "Detected - campaign to short to constrain as transient"] = [
                shellRedshiftArray,
                shelltransientRateDensityArray * shortCampaignFractionListArray
            ]

    maxInList = max(redshifts) * 1.1

    if pleasePlot:
        imageLink = plot_polynomial(
            log,
            title='PS1-transient Survey - Relative Detected Rates',
            polynomialDict=polynomialDict,
            orginalDataDictionary=orginalDataDictionary,
            pathToOutputPlotsFolder=pathToOutputPlotFolder,
            xRange=[0.01, maxInList, 0.01],
            xlabel=False,
            ylabel=False,
            xAxisLimits=False,
            yAxisLimits=[-0.05, 3.5],
            yAxisInvert=False,
            prependNum=False,
            legend=True)
    else:
        imageLink = ""

    log.debug('transientShellRateList: %s' % (transientShellRateList, ))

    totalRate = 0.
    for item in transientShellRateList:
        totalRate += item

    tooFaintRate = 0.
    for item in tooFaintShellRateList:
        tooFaintRate += item

    shortCampaignRate = 0.
    for item in shortCampaignShellRateList:
        shortCampaignRate += item

    totalRate = "%1.0f" % (totalRate, )
    tooFaintRate = "%1.0f" % (tooFaintRate, )
    shortCampaignRate = "%1.0f" % (shortCampaignRate, )
    return imageLink, totalRate, tooFaintRate, shortCampaignRate