Esempio n. 1
0
def build_atmos(atmocmp=None,
                X=1.0,
                t0=(3.9 / 100.0),
                t1=(0.02 / 100.0),
                t2=(-0.03 / 100.0),
                alpha=-1.7,
                mol=0.96,
                BP=782,
                O3=0.9,
                H2O=0.9,
                doPlot=False):
    if atmocmp == None:
        atmocmp = atmoComp()
    # examples
    # max atmo = build_atmos(atmocmp, X=X, t0=5.6/100.0, alpha=-1.8, O3=1.5, H2O=1.3)
    # min atmo = build_atmos(atmocmp, X=X, t0=0.2/100.0, alpha=-0.5, O3=0.6, H2O=0.5)
    # 30p atmo = build_atmos(atmocmp, X=2.5, t0=(0.8/100), alpha=-1.0, O3=0.9, H2O=0.8)
    # 30p atmo = build_atmos(atmocmp, X=2.5, t0=(2.4/100.0), alpha=-1.4, O3=1.17, H2O=1.04)
    # 10p/30 atmo = build_atmos(atmocmp, X=X, t0=(0.8/100.0), alpha=-1.0, O3=0.9, H2O=0.8)
    # 10p/30 atmo = build_atmos(atmocmp, X=X, t0=(1.3/100.0), alpha=-1.13, O3=0.99, H2O=1.04)
    atmocmp.setCoefficients(t0=t0,
                            t1=t1,
                            t2=t2,
                            alpha=alpha,
                            mol=mol,
                            BP=BP,
                            O3=O3,
                            H2O=H2O)
    atmocmp.buildAtmos(secz=X, doPlot=doPlot)
    atmos_bp = Bandpass(wavelen=atmocmp.wavelen, sb=atmocmp.trans_total)
    return atmocmp, atmos_bp
Esempio n. 2
0
def read_filtersonly(shift_perc=None, flist=filterlist):
    # read the filter throughput curves only (called from read_hardware as well)
    # apply a shift of +shift_perc/100 * eff_wavelength to the wavelengths of the filter.
    filterdir = os.getenv("LSST_THROUGHPUTS_DEFAULT")
    filters = {}
    for f in flist:
        filters[f] = Bandpass()
        filters[f].readThroughput(
            os.path.join(filterdir, "filter_" + f + ".dat"))
        effwavelenphi, effwavelensb = filters[f].calcEffWavelen()
        if shift_perc != None:
            shift = effwavelensb * shift_perc / 100.0
            print f, shift
            filters[f].wavelen = filters[f].wavelen + shift
            filters[f].resampleBandpass()
    return filters
Esempio n. 3
0
 def combine_throughputs(self, radius=0):
     """Combine base throughput curves from atmosphere/mirrors/lenses/detector with shifted filter
     throughput curves at a particular radius. Calls shift_filter to shift the filter. """
     # Combine throughputs from base and from the filters (at a particular radius) to make a full
     #  throughput curve.
     # Check to see if overall (complete) bandpass dictionary exists.
     try:
         self.bp
     except:
         self.bp = {}
     # Set up a dictionary for this radius, unless it already exists (in which case, we're done).
     try:
         self.bp[radius][self.filterlist[0]]
         return
     except:
         self.bp[radius] = {}
     # Calculate combined throughput curves at this radius.
     for f in self.filterlist:
         self.bp[radius][f] = Bandpass()
         # Shift filter to appropriate values at this radius.
         fwavelen, fsb = self.shift_filter(f, radius)
         # Note that multiplyThroughputs will resample fwavelen/fsb onto the same grid as base.
         wavelen, sb = self.base.multiplyThroughputs(fwavelen, fsb)
         # Set bp[r][f].
         self.bp[radius][f].setBandpass(wavelen, sb)
         self.bp[radius][f].sbTophi()
     return
Esempio n. 4
0
def combine_throughputs(atmos, sys, flist=None):
    # Set up the total throughput for this system bandpass
    total = {}
    if flist == None:
        flist = sys.keys()
    for f in flist:
        wavelen, sb = sys[f].multiplyThroughputs(atmos.wavelen, atmos.sb)
        total[f] = Bandpass(wavelen, sb)
        total[f].sbTophi()
    return total
Esempio n. 5
0
def read_hardware(shift_perc=None, flist=filterlist):
    # read system (hardware) transmission, return dictionary of system hardware (keyed to filter)
    filterdir = os.getenv("LSST_THROUGHPUTS_DEFAULT")
    hardware = ("detector.dat", "m1.dat", "m2.dat", "m3.dat", "lens1.dat",
                "lens2.dat", "lens3.dat")
    # Read in the standard components, but potentially shift the filter by shift_perc percent.
    filters = read_filtersonly(shift_perc=shift_perc, flist=flist)
    sys = {}
    for f in flist:
        sys[f] = Bandpass()
        # put together the standard component list
        tlist = []
        for t in hardware:
            tlist.append(os.path.join(filterdir, t))
        # read in the standard components, combine into sys
        sys[f].readThroughputList(tlist)
        # multiply by the filter throughput for final hardware throughput (no atmosphere)
        sys[f].wavelen, sys[f].sb = sys[f].multiplyThroughputs(
            filters[f].wavelen, filters[f].sb)
    return sys
Esempio n. 6
0
 def read_base_throughputs(self,
                           throughputsDir=None,
                           filterlist=('u', 'g', 'r', 'i', 'z', 'y4')):
     """Read base throughput curves from throughputsDir (if None, uses throughputs package default).
     Saves filter throughput curves separately from atmosphere/mirrors/lenses/detector, to enable shifting."""
     self.filterlist = filterlist
     # Read the basic default throughput curves (except for filters).
     if throughputsDir == None:
         throughputsDir = os.getenv('LSST_THROUGHPUTS_DEFAULT')
     components = ('atmos.dat', 'm1.dat', 'm2.dat', 'm3.dat', 'lens1.dat',
                   'lens2.dat', 'lens3.dat', 'detector.dat')
     self.base = Bandpass()
     self.base.readThroughputList(componentList=components,
                                  rootDir=throughputsDir)
     self.base_filters = {}
     for f in self.filterlist:
         self.base_filters[f] = Bandpass()
         # Read the basic filter throughput curve.
         self.base_filters[f].readThroughput(
             os.path.join(throughputsDir, 'filter_' + f + '.dat'))
     print '# Read base throughput curves from %s' % (throughputsDir)
     return
Esempio n. 7
0
def read_stdatmo(override_filename=None):
    # read the standard atmosphere bandpass file, precomputed by MODTRAN & DaveBurke.
    # this is closely equivalent to atmos_12.dat
    atmosdir = os.getenv("LSST_THROUGHPUTS_ATMOS")
    atmos_bp = Bandpass()
    if override_filename == None:
        atmos_bp.readThroughput(os.path.join(atmosdir, "atmos_std.dat"))
    else:
        atmos_bp.readThroughput(os.path.join(atmosdir, override_filename))
    return atmos_bp
def read_atmospheres(atmStrip, rootDir, atmtype):
    tmp = os.listdir(rootDir)
    atmfiles = []
    atmKeys = []
    for t in tmp:
        if t.startswith('am1.2') and t.endswith('.plt'):
            atmfiles.append(t)
            if (atmtype == 'aerosol') | (atmtype == 'ozone'):
                atmKeys.append(
                    float(t.split('_')[2].strip(atmStrip).strip('.plt')))
            else:
                atmKeys.append(
                    float(t.split('_')[1].strip(atmStrip).strip('.plt')))
    atmKeys = numpy.array(atmKeys)
    atmDict = {}
    for k, filename in zip(atmKeys, atmfiles):
        atmDict[k] = Bandpass()
        atmDict[k].readThroughput(os.path.join(rootDir, filename))
    return atmDict, atmKeys
Esempio n. 9
0
 def read_throughputs(self,
                      throughputsDir=None,
                      filterlist=('u', 'g', 'r', 'i', 'z', 'y'),
                      rootName='total_',
                      suffixName='.dat'):
     """Read total throughputs curves for filterlist from throughputsDir, with rootnames 'rootName' (suffix='suffixName').  """
     # Set throughputsDir if not given.
     if throughputsDir == None:
         throughputsDir = os.getenv('LSST_THROUGHPUTS_DEFAULT')
     self.filterlist = filterlist
     # Read in total throughputs curves, save in dictionary 'basebp'.
     self.basebp = {}
     for f in filterlist:
         self.basebp[f] = Bandpass()
         self.basebp[f].readThroughput(os.path.join(
             throughputsDir, rootName + f + suffixName),
                                       wavelen_step=self.wavelen_step)
         self.basebp[f].sbTophi()
     return
Esempio n. 10
0
class FilterShift():
    def __init__(self,
                 throughputsDir=None,
                 filterlist=('u', 'g', 'r', 'i', 'z', 'y4'),
                 max_jitter=1.0):
        """Instantiate object and do a reasonable default setup ready for calculating magnitudes."""
        self.read_base_throughputs(throughputsDir, filterlist)
        self.setBandpasses(max_jitter=max_jitter)
        self.setPhiArray()
        return

    def read_base_throughputs(self,
                              throughputsDir=None,
                              filterlist=('u', 'g', 'r', 'i', 'z', 'y4')):
        """Read base throughput curves from throughputsDir (if None, uses throughputs package default).
        Saves filter throughput curves separately from atmosphere/mirrors/lenses/detector, to enable shifting."""
        self.filterlist = filterlist
        # Read the basic default throughput curves (except for filters).
        if throughputsDir == None:
            throughputsDir = os.getenv('LSST_THROUGHPUTS_DEFAULT')
        components = ('atmos.dat', 'm1.dat', 'm2.dat', 'm3.dat', 'lens1.dat',
                      'lens2.dat', 'lens3.dat', 'detector.dat')
        self.base = Bandpass()
        self.base.readThroughputList(componentList=components,
                                     rootDir=throughputsDir)
        self.base_filters = {}
        for f in self.filterlist:
            self.base_filters[f] = Bandpass()
            # Read the basic filter throughput curve.
            self.base_filters[f].readThroughput(
                os.path.join(throughputsDir, 'filter_' + f + '.dat'))
        print '# Read base throughput curves from %s' % (throughputsDir)
        return

    def combine_throughputs(self, radius=0):
        """Combine base throughput curves from atmosphere/mirrors/lenses/detector with shifted filter
        throughput curves at a particular radius. Calls shift_filter to shift the filter. """
        # Combine throughputs from base and from the filters (at a particular radius) to make a full
        #  throughput curve.
        # Check to see if overall (complete) bandpass dictionary exists.
        try:
            self.bp
        except:
            self.bp = {}
        # Set up a dictionary for this radius, unless it already exists (in which case, we're done).
        try:
            self.bp[radius][self.filterlist[0]]
            return
        except:
            self.bp[radius] = {}
        # Calculate combined throughput curves at this radius.
        for f in self.filterlist:
            self.bp[radius][f] = Bandpass()
            # Shift filter to appropriate values at this radius.
            fwavelen, fsb = self.shift_filter(f, radius)
            # Note that multiplyThroughputs will resample fwavelen/fsb onto the same grid as base.
            wavelen, sb = self.base.multiplyThroughputs(fwavelen, fsb)
            # Set bp[r][f].
            self.bp[radius][f].setBandpass(wavelen, sb)
            self.bp[radius][f].sbTophi()
        return

    def shift_filter(self, f, radius, scale=True):
        """Shift/stretch the filter red and blue edges by the desired amount, for this filter f
        and at radius 'radius', and return wavelen/sb. """
        # Calculate red and blue shifts at this radius (radius must be a single value).
        #   numpy.polyval(r_shift[f]) gives the shift % = (red50 - red50_center) / effsb * 100.0
        # and then this translates into an actual value to add to the red wavelengths as
        #    (%/100.*effsb) = red50 - red50_baseline.   (red50 = red50_baseline + shift/100.*effsb)
        # This will also be scaled up to LSST permitted shift values, if scale=True. (otherwise max shift <.5%).
        rshift = numpy.polyval(red_shift[f], radius)
        bshift = numpy.polyval(blue_shift[f], radius)
        if scale == True:
            rshift = rshift * shift_scale[f]
            bshift = bshift * shift_scale[f]
        # Because we have different shifts on blue/red edges, split at effsb and stretch each side.
        effsb = self.base_filters[f].calcEffWavelen()[1]
        wavelen = numpy.copy(self.base_filters[f].wavelen)
        # Shift the red side
        condition = (wavelen > effsb)
        wavelen[condition] = wavelen[condition] + rshift / 100.0 * effsb
        # Shift the blue side
        condition = (wavelen < effsb)
        wavelen[condition] = wavelen[condition] + bshift / 100.0 * effsb
        # Wavelen now represents the shifted bandpass (using the original throughput values, but 'stretched').
        return wavelen, self.base_filters[f].sb

    def setBandpasses(self,
                      max_jitter=1.0,
                      radius_min=RADIUS_MIN,
                      radius_max=RADIUS_MAX):
        """Set up Bandpass objects covering the radius range with steps of max_jitter, for each filter."""
        # We must compare mags for shifted (at radius 'r') bandpass and mags at the same radius but for a filter with a
        #  'jitter' in its position. The max jitter (assume = max error) is equivalent to looking at a radius +/- the max jitter amount.
        # Set these up for a series of radii, separated by max jitter amount.
        self.radii = numpy.arange(radius_min, radius_max + max_jitter,
                                  max_jitter)
        for r in self.radii:
            # Generate self.bp[r][f]
            self.combine_throughputs(r)
        return

    def setPhiArray(self):
        """After setting up Bandpass objects over radius range, generate phi arrays for use in manyMagCalc. """
        # Generate phiArrays  (one per filter, covering the whole radius range).
        self.phiarray = {}
        for f in self.filterlist:
            self.phiarray[f] = numpy.empty(
                (len(self.radii), len(self.base.wavelen)), dtype='float')
            # Go through radii and generate combined (with shifted filter) throughputs, add to phiArray.
            for i, r in enumerate(self.radii):
                self.phiarray[f][i] = self.bp[r][f].phi
        self.wavelen_step = self.base.wavelen[1] - self.base.wavelen[0]
        return

    def plotBandpasses(self):
        """Just to provide a sanity check and visual inspection of some of the shifted bandpasses. """
        import pylab
        r0 = self.radii[0]
        r1 = self.radii[len(self.radii) / 2]
        r2 = self.radii[len(self.radii) - 1]
        for f in self.filterlist:
            pylab.figure()
            pylab.plot(self.bp[r0][f].wavelen,
                       self.bp[r0][f].sb,
                       label='Center')
            pylab.plot(self.bp[r1][f].wavelen,
                       self.bp[r1][f].sb,
                       label='Middle')
            pylab.plot(self.bp[r2][f].wavelen, self.bp[r2][f].sb, label='Edge')
            pylab.xlabel('Wavelength (nm)')
            pylab.ylabel('Throughput (0-1)')
            pylab.title('Filter Shift for %s' % (f))
            pylab.legend(fontsize='smaller', fancybox=True)
        pylab.show()
        return

    def calc_mags(self, sed, f):
        """Calculate magnitudes for 'sed' in filter 'f', at over the radii set up in setPhiArray. 
        Returns mags at each radii, as well as dmags representing the max error due to filter jitter (=steps in radius array), 
         (equivalent to the max difference between +/- one step in mag). """
        # Make sure that sed's fnu exists and is on the same wavelength grid as the phiarray grid.
        r0 = self.radii[0]
        wavelen_match = self.base.wavelen
        if sed.needResample(wavelen_match=wavelen_match):
            sed.resampleSED(wavelen_match=wavelen_match)
        sed.flambdaTofnu()
        # Calculate the magnitudes for the bandpass as would be measured (i.e. @ radius, we're not including ghosting induced errors)
        #  and as might be the result with jitter. Assuming max error happens in the max jitter 'direction', this means looking at radii
        #  at values +/- jitter to look for the max difference in magnitude.
        mags = sed.manyMagCalc(self.phiarray[f], self.wavelen_step)
        # And the color-dependent differences in natural magnitudes.
        dmags_up = mags[:-1] - mags[1:]
        dmags_up = numpy.concatenate((dmags_up, [0]))
        dmags_down = mags[1:] - mags[:-1]
        dmags_down = numpy.concatenate(([0], dmags_down))
        # Return the value of the largest offset (absolute value) at each radius, in mmags.
        dmags = numpy.where(
            numpy.abs(dmags_up) > numpy.abs(dmags_down), dmags_up, dmags_down)
        dmags = dmags * 1000.0
        # yes, those steps above are a bit overkill/unnecessary ... but it does keep absolutely straight the radius/dmags relationship.
        return mags, dmags
Esempio n. 11
0
import pylab
from lsst.sims.catalogs.measures.photometry.Sed import Sed
from lsst.sims.catalogs.measures.photometry.Bandpass import Bandpass

# Find aerosol files
tmp = os.listdir('.')
ozonefiles = []
ozone = []
for t in tmp:
    if t.startswith('am1.2') and t.endswith('.plt'):
        ozonefiles.append(t)
        ozone.append(float(t.split('_')[2].strip('oz').strip('.plt')))

ozone = numpy.array(ozone)

# Read in aerosol files.
ozones = {}
for a in ozonefiles:
    print 'Reading %s' % (a)
    ozones[a] = Bandpass()
    ozones[a].readThroughput(a)
"""
# plot files
for a in ozonefiles:
    pylab.figure()
    pylab.plot(ozones[a].wavelen, ozones[a].sb)
    pylab.xlabel('Wavelength (nm)')
    pylab.ylabel('Transmission')
    pylab.savefig(a+'.png', format='png')
"""
Esempio n. 12
0
import pylab
from lsst.sims.catalogs.measures.photometry.Sed import Sed
from lsst.sims.catalogs.measures.photometry.Bandpass import Bandpass

# Find aerosol files
tmp = os.listdir('.')
aerosolfiles = []
aerosol_mult = []
for t in tmp:
    if t.startswith('am1.2') and t.endswith('.plt'):
        aerosolfiles.append(t)
        aerosol_mult.append(
            float(t.split('_')[2].strip('avis').strip('.plt')) / 10.0)

aerosol_mult = numpy.array(aerosol_mult)

# Read in aerosol files.
aerosols = {}
for a in aerosolfiles:
    print 'Reading %s' % (a)
    aerosols[a] = Bandpass()
    aerosols[a].readThroughput(a)

# plot files
for a in aerosolfiles:
    pylab.figure()
    pylab.plot(aerosols[a].wavelen, aerosols[a].sb)
    pylab.xlabel('Wavelength (nm)')
    pylab.ylabel('Transmission')
    pylab.savefig(a + '.png', format='png')