def _test():
    pixels = np.vectorize(pixelsImpacted)
    mag = np.arange(0, 19., 1) + 0.4
    rs = pixels(mag)
    for m, val in zip(mag, rs):
        print m, val

    print '\n\n\n0 mag'
    n = stellarNumberCounts.bahcallSoneira(1, 0, 20, stellarNumberCounts.integratedCountsVband())
    print 'objects    perCCD      areaLoss'
    print n, n * 49.6 / 3600 , n * pixelsImpacted(1) * 49.6 / 3600 / (4096 * 4132.) * 100.

    print '\n10 mag'
    n = stellarNumberCounts.bahcallSoneira(10, 0, 20, stellarNumberCounts.integratedCountsVband())
    print 'objects    perCCD      areaLoss'
    print n, n * 49.6 / 3600 , n * pixelsImpacted(10) * 49.6 / 3600 / (4096 * 4132.) * 100.

    print '\n18 mag'
    n = stellarNumberCounts.bahcallSoneira(18, 0, 20, stellarNumberCounts.integratedCountsVband())
    print 'objects    perCCD      areaLoss'
    print n, n * 49.6 / 3600 , n * pixelsImpacted(18) * 49.6 / 3600 / (4096 * 4132.) * 100.

    for m in mag:
        n = stellarNumberCounts.bahcallSoneira(m, 0, 20, stellarNumberCounts.integratedCountsVband())
        print m, n * 49.6 / 3600
def _test():
    pixels = np.vectorize(pixelsImpacted)
    mag = np.arange(0, 19., 1) + 0.4
    rs = pixels(mag)
    for m, val in zip(mag, rs):
        print m, val

    print '\n\n\n0 mag'
    n = stellarNumberCounts.bahcallSoneira(
        1, 0, 20, stellarNumberCounts.integratedCountsVband())
    print 'objects    perCCD      areaLoss'
    print n, n * 49.6 / 3600, n * pixelsImpacted(1) * 49.6 / 3600 / (
        4096 * 4132.) * 100.

    print '\n10 mag'
    n = stellarNumberCounts.bahcallSoneira(
        10, 0, 20, stellarNumberCounts.integratedCountsVband())
    print 'objects    perCCD      areaLoss'
    print n, n * 49.6 / 3600, n * pixelsImpacted(10) * 49.6 / 3600 / (
        4096 * 4132.) * 100.

    print '\n18 mag'
    n = stellarNumberCounts.bahcallSoneira(
        18, 0, 20, stellarNumberCounts.integratedCountsVband())
    print 'objects    perCCD      areaLoss'
    print n, n * 49.6 / 3600, n * pixelsImpacted(18) * 49.6 / 3600 / (
        4096 * 4132.) * 100.

    for m in mag:
        n = stellarNumberCounts.bahcallSoneira(
            m, 0, 20, stellarNumberCounts.integratedCountsVband())
        print m, n * 49.6 / 3600
def areaImpacted(magnitudes=np.arange(0, 20., 1.), offset=0.5, star=False):
    """

    """
    s = 0.1

    Nvconst = stellarNumberCounts.integratedCountsVband()

    print '\n mag     b       l       stars      CCD        area'
    for b in [20, 25, 30, 50, 90]:
        for l in [0, 90, 180]:
            area = 0
            prev = 0
            for ml in magnitudes:
                m = s * math.ceil(float(ml + offset) / s)
                n = stellarNumberCounts.bahcallSoneira(m, l, b, Nvconst)
                n -= prev  #subtract the number of stars in the previous bin

                ccd = n * 49.6 / 3600
                covering = pixelsImpacted(m, star=star)
                area += (ccd * covering) / (4096 * 4132.) * 100.

                prev = n  #store the number of stars in the current bin

                if area > 100:
                    area = 100.

            txt = '%.1f     %2d     %3d     %.2f        %.1f        %.3f' % (
                m, b, l, n, ccd, area)
            print txt

            if b == 90:
                #no need to do more than once... l is irrelevant
                break

    print '\n\n\nIntegrated Area Loss:'
    blow = 20
    bhigh = 90
    llow = 0
    lhigh = 180
    bnum = 71
    lnum = 181

    prev = 0
    for i, ml in enumerate(magnitudes):
        m = s * math.ceil(float(ml + offset) / s)
        l, b, counts = stellarNumberCounts.skyNumbers(m, blow, bhigh, llow,
                                                      lhigh, bnum, lnum)

        counts -= prev
        prev = counts.copy()

        #average
        stars = np.mean(counts)

        ccd = stars * 49.6 / 3600
        covering = pixelsImpacted(m, star=star)
        area = (ccd * covering) / (4096 * 4132.) * 100.

        if area > 100:
            area = 100.

        print 'magnitude = %.1f, average = %.5f, max = %.5f' % (ml, stars,
                                                                np.max(counts))
        print '%i stars per square degree will mean %i stars per CCD and thus an area loss of %.4f per cent' % \
              (stars, ccd, area)

        if i < 1:
            z = counts * covering / (
                4096 * 4132. * (4096 * 0.1 * 4132 * 0.1 / 60. / 60.)) * 100.
        else:
            z += counts * covering / (
                4096 * 4132. * (4096 * 0.1 * 4132 * 0.1 / 60. / 60.)) * 100.

    msk = z > 100
    z[msk] = 100.

    _areaLossPlot(m, b, l, z, blow, bhigh, llow, lhigh, bnum, lnum,
                  'Masking of Saturated Pixels From All Stars', 'AreaLoss')
def _numberOfStarsAreaLoss(log,
                           magnitudelimits,
                           title,
                           offset=0.5,
                           covering=2550):
    """
    Calculates the area loss for given magnitude limit at a few galactic coordinates and
    integrated over an observing region.
    """
    Nvconst = stellarNumberCounts.integratedCountsVband()

    txt = '\n\n\nNumber of stars:'
    print txt
    log.info(txt)
    s = 0.1

    for ml in magnitudelimits:
        print '\nmag     b     l    stars    CCD    area'
        for b in [20, 25, 30, 50, 90]:
            for l in [0, 90, 180]:
                m = s * math.ceil(float(ml + offset) / s)
                n = stellarNumberCounts.bahcallSoneira(
                    m, l, b, Nvconst) * 1.15  #15 error in the counts
                ccd = n * 49.6 / 3600
                area = (ccd * covering) / (4096 * 4132.) * 100.

                if area > 100:
                    area = 100.
                #print 'At l=%i, b=%i, there are about %i stars in a square degree brighter than %.1f' % (l, b, n, m)
                #print '%i stars per square degree will mean %i stars per CCD and thus an area loss of %.2f per cent' % \
                #      (n, ccd, area)

                txt = '%.1f   %2d   %3d   %.1f    %.1f    %.2f' % (m, b, l, n,
                                                                   ccd, area)
                print txt
                log.info(txt)

                if b == 90:
                    #no need to do more than once... l is irrelevant
                    break

    txt = '\n\n\nIntegrated Area Loss:'
    print txt
    log.info(txt)
    blow = 20
    bhigh = 90
    llow = 0
    lhigh = 180
    bnum = 71
    lnum = 181

    for ml in magnitudelimits:
        m = s * math.ceil(float(ml + offset) / s)
        l, b, counts = stellarNumberCounts.skyNumbers(m, blow, bhigh, llow,
                                                      lhigh, bnum, lnum)
        counts *= 1.15  #15 error in the counts
        stars = np.mean(counts)
        ccd = stars * 49.6 / 3600
        area = (ccd * covering) / (4096 * 4132.) * 100.

        if area > 100:
            area = 100.

        txt = '%i stars per square degree will mean %i stars per CCD and thus an area loss of %.2f per cent' % \
              (stars, ccd, area)

        print txt
        log.info(txt)

        z = counts * covering / (4096 * 4132. *
                                 (4096 * 0.1 * 4132 * 0.1 / 60. / 60.)) * 100.
        msk = z > 100
        z[msk] = 100.

        _areaLossPlot(m, b, l, z, blow, bhigh, llow, lhigh, bnum, lnum, title,
                      'AreaLoss')
Example #5
0
def CatalogueBachallSoneira(magnitudeLimit=28, b=25, l=0,
                            sqdeg=0.496, xmax=26000, ymax=29000,
                            types=np.arange(17, 103), output='catalogue.dat'):
    """
    Generate an object catalogue with random positions using the Bachall and Soneira stellar model.
    Includes also galaxies.

    :param magnitudeLimit: limiting magnitude in V-band
    :type magnitudeLimit: int
    :param b: galactic longitude
    :type b: int
    :param l: galactic latitude
    :type l: int
    :param sqdeg: number of square degrees to cover
    :type sqdeg: float
    :param xmax: highest pixel value to use for the random positions in x
    :type xmax: int
    :param ymax: highest pixel value to use for the random positions in y
    :type ymax: int
    :param types: a list of galaxy types corresponding to the postage stamp images
    :type types: list
    :param output: name of the output file
    :type output: str

    :return: None
    """
    #stars
    Nvconst = stellarNumberCounts.integratedCountsVband()

    n = stellarNumberCounts.bahcallSoneira(magnitudeLimit, l, b, Nvconst)  #per square degree

    nstars = int(n * sqdeg)

    print '%i stars brighter than %i mag_V in %f square degrees at b=%i and l=%i' % (nstars, magnitudeLimit, sqdeg, b, l)

    xcoords = np.random.random(nstars) * xmax
    ycoords = np.random.random(nstars) * ymax

    stcounts = []
    stmags = np.linspace(3.5, 30, num=15)
    for m in stmags:
        tmp = stellarNumberCounts.bahcallSoneira(m, l, b, Nvconst)
        stcounts.append(tmp)
    stcounts = np.asarray(stcounts)
    #fit a function and generate finer sample
    z = np.polyfit(stmags, np.log10(stcounts), 4)
    p = np.poly1d(z)
    starmags = np.arange(1, 30.2, 0.2)
    starcounts = 10**p(starmags)
    cpdf = (starcounts - np.min(starcounts))/ (np.max(starcounts) - np.min(starcounts))

    mag = drawFromCumulativeDistributionFunction(cpdf, starmags, nstars)

    fh = open(output, 'w')
    fh.write('#   1 X                Object position along x                                    [pixel]\n')
    fh.write('#   2 Y                Object position along y                                    [pixel]\n')
    fh.write('#   3 MAG              Object magnitude                                           [AB]\n')
    fh.write('#   4 TYPE             Object type                                                [0=star, others=FITS]\n')
    fh.write('#   5 ORIENTATION      Objects orientation                                        [deg]\n')

    for x, y, m in zip(xcoords, ycoords, mag):
        fh.write('%f %f %f %i %f \n' % (x, y, m, 0, 0.0))

    #galaxies
    d = np.loadtxt('data/cdf_galaxies.dat', usecols=(0, 1))
    gmags = d[:, 0]
    gcounts = d[:, 1]
    nums = int(np.max(gcounts) * sqdeg)

    print '%i galaxies' % nums

    z = np.polyfit(gmags, np.log10(gcounts), 4)
    p = np.poly1d(z)
    galaxymags = np.arange(10.0, 30.2, 0.2)
    galaxycounts = 10**p(galaxymags)
    plotDistributionFunction(gmags, gcounts, galaxymags, galaxycounts, 'GalaxyDist.pdf')
    cumulative = (galaxycounts - np.min(galaxycounts))/ (np.max(galaxycounts) - np.min(galaxycounts))

    xc = np.random.random(nums) * xmax
    yc = np.random.random(nums) * ymax
    theta = np.random.random(nums) * 360.0
    typ = np.random.random_integers(low=np.min(types), high=np.max(types), size=nums)
    mag = drawFromCumulativeDistributionFunction(cumulative, galaxymags, nums)

    for x, y, m, t, ang in zip(xc, yc, mag, typ, theta):
        if t < 1:
            fh.write('%f %f %f %i %f \n' % (x, y, m, t, 0.0))
        else:
            fh.write('%f %f %f %i %f \n' % (x, y, m, t, ang))

    fh.close()

    plotCatalog(output)
Example #6
0
def starCatalogueBachallSoneira(magnitudeLimit=28, b=30, l=0, sqdeg=0.496,
                                xmax=26000, ymax=29000, output='starsOnly.dat'):
    """
    Generate an object catalogue with random positions using the Bachall and Soneira stellar model.

    For a full focal plane the default values should be fine. A full focal plane covers about 0.496 square degrees
    and in x and y pixels:
    5*(4096 + (1.643*1000/12.)) + 4096 and
    5*(4132 + (8.116*1000/12.)) + 4132, respectively.

    :param magnitudeLimit: limiting magnitude in V-band
    :type magnitudeLimit: int
    :param b: galactic longitude
    :type b: int
    :param l: galactic latitude
    :type l: int
    :param sqdeg: number of square degrees to cover
    :type sqdeg: float
    :param xmax: highest pixel value to use for the random positions in x
    :type xmax: int
    :param ymax: highest pixel value to use for the random positions in y
    :type ymax: int

    :return: None
    """
    Nvconst = stellarNumberCounts.integratedCountsVband()

    n = stellarNumberCounts.bahcallSoneira(magnitudeLimit, l, b, Nvconst)  #per square degree

    nstars = int(n * sqdeg)

    print '%i stars brighter than %i mag_V in %f square degrees at b=%i and l=%i' % (nstars, magnitudeLimit, sqdeg, b, l)

    xcoords = np.random.random(nstars) * xmax
    ycoords = np.random.random(nstars) * ymax

    stcounts = []
    stmags = np.linspace(3.5, 30, num=15)
    for m in stmags:
        tmp = stellarNumberCounts.bahcallSoneira(m, l, b, Nvconst)
        stcounts.append(tmp)
    stcounts = np.asarray(stcounts)
    #fit a function and generate finer sample
    z = np.polyfit(stmags, np.log10(stcounts), 4)
    p = np.poly1d(z)
    starmags = np.arange(1, 30.2, 0.2)
    starcounts = 10**p(starmags)
    cpdf = (starcounts - np.min(starcounts))/ (np.max(starcounts) - np.min(starcounts))

    mag = drawFromCumulativeDistributionFunction(cpdf, starmags, nstars)

    fh = open(output, 'w')
    fh.write('#   1 X                Object position along x                                    [pixel]\n')
    fh.write('#   2 Y                Object position along y                                    [pixel]\n')
    fh.write('#   3 MAG              Object magnitude                                           [AB]\n')
    fh.write('#   4 TYPE             Object type                                                [0=star, others=FITS]\n')
    fh.write('#   5 ORIENTATION      Objects orientation                                        [deg]\n')

    for x, y, m in zip(xcoords, ycoords, mag):
        fh.write('%f %f %f %i %f \n' % (x, y, m, 0, 0.0))
    fh.close()

    plotCatalog(output)
def areaImpacted(magnitudes=np.arange(0, 20., 1.), offset=0.5, star=False):
    """

    """
    s = 0.1

    Nvconst = stellarNumberCounts.integratedCountsVband()

    print '\n mag     b       l       stars      CCD        area'
    for b in [20, 25, 30, 50, 90]:
        for l in [0, 90, 180]:
            area = 0
            prev = 0
            for ml in magnitudes:
                m = s * math.ceil(float(ml + offset) / s)
                n = stellarNumberCounts.bahcallSoneira(m, l, b, Nvconst)
                n -= prev #subtract the number of stars in the previous bin

                ccd = n * 49.6 / 3600
                covering = pixelsImpacted(m, star=star)
                area += (ccd * covering) / (4096 * 4132.) * 100.

                prev = n  #store the number of stars in the current bin

                if area > 100:
                    area = 100.


            txt = '%.1f     %2d     %3d     %.2f        %.1f        %.3f' % (m, b, l, n, ccd, area)
            print txt

            if b == 90:
                #no need to do more than once... l is irrelevant
                break

    print '\n\n\nIntegrated Area Loss:'
    blow=20
    bhigh=90
    llow=0
    lhigh=180
    bnum=71
    lnum=181

    prev = 0
    for i, ml in enumerate(magnitudes):
        m = s * math.ceil(float(ml + offset) / s)
        l, b, counts = stellarNumberCounts.skyNumbers(m, blow, bhigh, llow, lhigh, bnum, lnum)

        counts -= prev
        prev = counts.copy()

        #average
        stars = np.mean(counts)

        ccd = stars * 49.6 / 3600
        covering = pixelsImpacted(m, star=star)
        area = (ccd * covering) / (4096 * 4132.) * 100.

        if area > 100:
            area = 100.

        print 'magnitude = %.1f, average = %.5f, max = %.5f' % (ml, stars, np.max(counts))
        print '%i stars per square degree will mean %i stars per CCD and thus an area loss of %.4f per cent' % \
              (stars, ccd, area)

        if i < 1:
            z = counts * covering / (4096 * 4132. * (4096 * 0.1 * 4132 * 0.1 / 60. / 60.)) * 100.
        else:
            z += counts * covering / (4096 * 4132. * (4096 * 0.1 * 4132 * 0.1 / 60. / 60.)) * 100.

    msk = z > 100
    z[msk] = 100.

    _areaLossPlot(m, b, l, z, blow, bhigh, llow, lhigh, bnum, lnum,
                  'Masking of Saturated Pixels From All Stars', 'AreaLoss')
def _numberOfStarsAreaLoss(log, magnitudelimits, title, offset=0.5, covering=2550):
    """
    Calculates the area loss for given magnitude limit at a few galactic coordinates and
    integrated over an observing region.
    """
    Nvconst = stellarNumberCounts.integratedCountsVband()

    txt = '\n\n\nNumber of stars:'
    print txt
    log.info(txt)
    s = 0.1

    for ml in magnitudelimits:
        print '\nmag     b     l    stars    CCD    area'
        for b in [20, 25, 30, 50, 90]:
            for l in [0, 90, 180]:
                m = s * math.ceil(float(ml + offset) / s)
                n = stellarNumberCounts.bahcallSoneira(m, l, b, Nvconst) * 1.15  #15 error in the counts
                ccd = n * 49.6 / 3600
                area = (ccd * covering) / (4096 * 4132.) * 100.

                if area > 100:
                    area = 100.
                #print 'At l=%i, b=%i, there are about %i stars in a square degree brighter than %.1f' % (l, b, n, m)
                #print '%i stars per square degree will mean %i stars per CCD and thus an area loss of %.2f per cent' % \
                #      (n, ccd, area)

                txt = '%.1f   %2d   %3d   %.1f    %.1f    %.2f' % (m, b, l, n, ccd, area)
                print txt
                log.info(txt)

                if b == 90:
                    #no need to do more than once... l is irrelevant
                    break


    txt = '\n\n\nIntegrated Area Loss:'
    print txt
    log.info(txt)
    blow=20
    bhigh=90
    llow=0
    lhigh=180
    bnum=71
    lnum=181

    for ml in magnitudelimits:
        m = s * math.ceil(float(ml + offset) / s)
        l, b, counts = stellarNumberCounts.skyNumbers(m, blow, bhigh, llow, lhigh, bnum, lnum)
        counts *= 1.15 #15 error in the counts
        stars = np.mean(counts)
        ccd = stars * 49.6 / 3600
        area = (ccd * covering) / (4096 * 4132.) * 100.

        if area > 100:
            area = 100.

        txt = '%i stars per square degree will mean %i stars per CCD and thus an area loss of %.2f per cent' % \
              (stars, ccd, area)

        print txt
        log.info(txt)

        z = counts * covering / (4096 * 4132. * (4096 * 0.1 * 4132 * 0.1 / 60. / 60.)) * 100.
        msk = z > 100
        z[msk] = 100.

        _areaLossPlot(m, b, l, z, blow, bhigh, llow, lhigh, bnum, lnum, title, 'AreaLoss')