*Given a list of the snSurveyDiscoveryTimes calculate the discovery/non-discovery ratio for a given redshift range*

    **Key Arguments:**
        - ``log`` -- logger
        - ``surveyCadenceSettings`` -- the cadence settings for the survey
        - ``snSurveyDiscoveryTimes`` -- the discovery times of the SN relative to the survey year
        - ``redshifts`` -- redshifts of the sne
        - ``peakAppMagList`` -- list of the SN peak magnitude in each filter
        - ``snCampaignLengthList`` -- a list of campaign lengths in each filter
        - ``extraSurveyConstraints`` -- some extra survey constraints
        - ``zmin`` -- minimum redshift in the range
        - ``zmax`` -- maximum redshift in the range

    **Return:**
        - None

def calculate_fraction_of_sn_discovered(
        log,
        surveyCadenceSettings,
        snSurveyDiscoveryTimes,
        redshifts,
        peakAppMagList,
        snCampaignLengthList,
        extraSurveyConstraints,
        zmin,
        zmax):
    """
    *Given a list of the snSurveyDiscoveryTimes calculate the discovery/non-discovery ratio for a given redshift range*

    **Key Arguments:**
        - ``log`` -- logger
        - ``surveyCadenceSettings`` -- the cadence settings for the survey
        - ``snSurveyDiscoveryTimes`` -- the discovery times of the SN relative to the survey year
        - ``redshifts`` -- redshifts of the sne
        - ``peakAppMagList`` -- list of the SN peak magnitude in each filter
        - ``snCampaignLengthList`` -- a list of campaign lengths in each filter
        - ``extraSurveyConstraints`` -- some extra survey constraints
        - ``zmin`` -- minimum redshift in the range
        - ``zmax`` -- maximum redshift in the range

    **Return:**
        - None
    """
    ################ > IMPORTS ################
    ## STANDARD LIB ##
    ## THIRD PARTY ##
    ## LOCAL APPLICATION ##

    ################ >ACTION(S) ################
    filters = ['g', 'r', 'i', 'z']
    faintMagLimit = extraSurveyConstraints['Faint-Limit of Peak Magnitude']
    lunarMonth = 29.3
    surveyYear = 12. * lunarMonth
    observableFraction = surveyCadenceSettings["Observable Fraction of Year"]

    discovered = []
    tooFaint = []
    shortCampaign = []
    discoveredRedshift = []
    tooFaintRedshift = []
    notDiscoveredRedshift = []
    shortCampaignRedshift = []
    #log.info('len(redshifts) %s' % (len(redshifts),))
    dataDictionary = {}
    for item in range(len(redshifts)):
        if redshifts[item] > zmax or redshifts[item] <= zmin:
            continue
        if snSurveyDiscoveryTimes[item]['any'] is True:
            discoveryDayList = []
            faintDayList = []
            shortCampaignDayList = []
            for ffilter in filters:
                if snSurveyDiscoveryTimes[item][ffilter]:
                    if peakAppMagList[item][ffilter] < faintMagLimit:
                        if (snCampaignLengthList[item]['max'] < extraSurveyConstraints['Observable for at least ? number of days']):
                            shortCampaignDayList.append(
                                snSurveyDiscoveryTimes[item][ffilter])
                        else:
                            if (surveyYear * observableFraction - snSurveyDiscoveryTimes[item][ffilter]) > extraSurveyConstraints['Observable for at least ? number of days']:
                                discoveryDayList.append(
                                    snSurveyDiscoveryTimes[item][ffilter])
                            # elif ((surveyYear*observableFraction -
                            # snSurveyDiscoveryTimes[item][ffilter]) <
                            # snSurveyDiscoveryTimes[item][ffilter] <
                            # surveyYear*observableFraction):
                            elif (snCampaignLengthList[item][ffilter] - (surveyYear - snSurveyDiscoveryTimes[item][ffilter])) > extraSurveyConstraints['Observable for at least ? number of days']:
                                lcTail = snCampaignLengthList[item][
                                    ffilter] - (surveyYear - snSurveyDiscoveryTimes[item][ffilter])
                                discoveryDayList.append(
                                    snSurveyDiscoveryTimes[item][ffilter])
                            else:
                                shortCampaignDayList.append(
                                    snSurveyDiscoveryTimes[item][ffilter])
                                # log.info('item: %s. ffilter %s. too short due to going behind sun, discovery day %s, camp length %s' % (item, ffilter, snSurveyDiscoveryTimes[item][ffilter], snCampaignLengthList[item][ffilter]))
                    else:
                        faintDayList.append(
                            snSurveyDiscoveryTimes[item][ffilter])

            if len(discoveryDayList) > 0:
                discovered.append(min(discoveryDayList))
                discoveredRedshift.append(redshifts[item])
            elif len(shortCampaignDayList) > 0:
                shortCampaign.append(min(shortCampaignDayList))
                shortCampaignRedshift.append(redshifts[item])
            else:
                tooFaint.append(min(faintDayList))
                tooFaintRedshift.append(redshifts[item])
        else:
            notDiscoveredRedshift.append(redshifts[item])

    if len(notDiscoveredRedshift) > 0:
        dataDictionary["Undiscovered"] = notDiscoveredRedshift
    if len(tooFaintRedshift) > 0:
        dataDictionary[
            "Detected - too faint to constrain as transient"] = tooFaintRedshift
    if len(discoveredRedshift) > 0:
        dataDictionary["Discovered"] = discoveredRedshift
    if len(shortCampaignRedshift) > 0:
        dataDictionary[
            "Detected - campaign to short to constrain as transient"] = shortCampaignRedshift

    totalWithinVolume = float(len(discoveredRedshift) + len(
        notDiscoveredRedshift) + len(tooFaintRedshift) + len(shortCampaignRedshift))

    if len(discoveredRedshift) == 0:
        discoveryFraction = 0.
    else:
        discoveryFraction = float(len(discoveredRedshift)) / totalWithinVolume
    if len(tooFaintRedshift) == 0:
        tooFaintFraction = 0.
    else:
        tooFaintFraction = float(len(tooFaintRedshift)) / totalWithinVolume
    if len(shortCampaignRedshift) == 0:
        shortCampaignFraction = 0.
    else:
        shortCampaignFraction = float(
            len(shortCampaignRedshift)) / totalWithinVolume
    # log.info('len(discoveredRedshift) %s' % (len(discoveredRedshift),))
    # log.info('len(notDiscoveredRedshift) %s' % (len(notDiscoveredRedshift),))
    # log.info('discoveryFraction %s' % (discoveryFraction,))

    return discoveryFraction, tooFaintFraction, shortCampaignFraction