Beispiel #1
0
    def getSpectrum(self, grism, extconf, path):

        fluxs, fvars, waves, chi2s = [], [], [], []
        with h5table.H5Table(grism.dataset, 'ddt', path=path) as h5:
            for detname, detimg in grism:
                # open the detector
                h5det = h5[detname]
                detconf = extconf[detname]

                # read the images
                sci, scihdr = grism.readfits(detconf.sciext, detconf.extver)
                unc, unchdr = grism.readfits(detconf.uncext, detconf.extver)
                dqa, dqahdr = grism.readfits(detconf.dqaext, detconf.extver)

                # load the beamsy
                for beam, beamconf in detconf:
                    h5beam = h5det[beam]
                    beamconf = detconf[beam]

                    # read the table
                    ddt = h5table.DDT(self.segid)
                    ddt.readH5(h5beam)

                    # apply flat, pam, etc. to sci/unc

                    # fit the sky
                    sky, box = self.fitSky(sci, unc, dqa, ddt)

                    # clean the sky
                    cln = self.cleanSky(sky)
                    sci[box] -= cln
                    del cln, sky

                    # fit the object
                    vals = self.fitSource(sci, unc, dqa, ddt, beamconf)

                    # clean up
                    del sci, unc, dqa

                    # output the results
                    fluxs.extend(vals[0])
                    fvars.extend(vals[1])
                    waves.extend(vals[2])
                    chi2s.extend(vals[3])
                    del vals  # more cleaning

        return fluxs, fvars, waves, chi2s
Beispiel #2
0
    def maskBeams(self,flt,mskconf,path):

        masks={}
        if len(mskconf.beams)!=0:
            print("[info]Making beam mask for: {}".format(flt.filename))
            with h5table.H5Table(flt.dataset,path=path,suffix='omt') as h5:
                
                # loop over detectors
                for detname,detimg in flt:
                    h5det=h5[detname]              # get the group
                    detconf=mskconf[detname]       # grism config
                    mask=np.ones(detimg.naxis,dtype=np.bool)
                    for beam,beamconf in detconf:

                        h5beam=h5det[beam]
                        for segid in h5beam:
                            xyg=h5beam[segid][:]
                            xg,yg=indices.one2two(xyg,detimg.naxis)
                            mask[yg,xg]=False
                    masks[detname]=mask
        return masks
Beispiel #3
0
def makeODTs(grism,sources,grismconf,path,remake,nsub):
    # create the table
    tab=h5table.H5Table(grism.dataset,TTYPE,path=path)
    
    # remake the table?
    #if not (remake or not os.path.isfile(tab.filename)):
    #    return tab.filename

    if remake:
        if os.path.isfile(tab.filename):
            os.remove(tab.filename)
        else:
            return tab.filename
    
    # pixel based ------------------------------
    dx=np.array([0,0,1,1])            # HARDCODE
    dy=np.array([0,1,1,0])            # HARDCODE
    #-------------------------------------------

    with tab as h5:

        # add some stuff to that header
        h5utils.writeAttr(h5,'segmap',sources.segmap)
        h5utils.writeAttr(h5,'nsource',np.uint16(len(sources)))
        h5utils.writeAttr(h5,'detimage',sources.obsdata.detImage)
        h5utils.writeAttr(h5,'detband',sources.obsdata.detName)
        h5utils.writeAttr(h5,'maglimit',np.float32(sources.maglimit))
        

        
        # process each detector
        for det,detconf in grismconf:
            #detgrp=detGroup(h5,det,detconf)
            detgrp=h5.require_group(det)
            
            # get the center of the detector
            xc,yc=detconf.naxis/2.
            
            # get this grism image
            thisGrism=grism[det]

            # the pixel area of this detector
            detpixelarea=thisGrism.pixelarea

            for beam,beamconf in detconf:
                beamgrp=detgrp.require_group(beam)
                if remake:
                    sourcesDone=[]
                else:
                    sourcesDone=list(beamgrp.keys())
                
                #if beam in detgrp:
                #    beamgrp=detgrp[beam]
                #    sourcesDone=list(beamgrp.keys())
                #else:
                #    beamgrp=detgrp.create_group(beam)
                #    sourcesDone=[]

                # compute the set difference
                #segids=[src.name for src in sources]
                #done=list(beamgrp.keys())
                #toDo=segids-done

                    
                # get the ODT wavelenegths.  NOTE: This are *NOT* the
                # same as the extraction wavelengths due to NSUB.
                # here using center of detector.  Could improve this by
                # putting inside loop on sources and take (xc,yc)
                # from the source.  This is just faster and doesn't
                # seem to be a problem just yet
                wav=beamconf.wavelengths(xc,yc,nsub)  
                dwav=wav[1]-wav[0]

                # put some stuff in the table
                h5utils.writeAttr(beamgrp,'wav0',np.float32(wav[0]))
                h5utils.writeAttr(beamgrp,'wav1',np.float32(wav[-1]))
                h5utils.writeAttr(beamgrp,'dwav',np.float32(dwav))

                # process each source
                for segid,src in sources:
                    if src.name not in sourcesDone:  # only process new sources
                        
                        # compute ratio of pixel area between
                        # the FLT and the source
                        pixrat=detpixelarea/src.pixelarea

                        # make an ODT
                        odt=h5table.ODT(src.segid,wav=wav)

                        # process each pixel in the source
                        for xd,yd,wd in src:
                            # convert the corners of the direct image to the
                            # corresponding grism image
                            xg,yg=src.xy2xy(xd+dx,yd+dy,thisGrism)

                            # disperse those corners
                            xyg,lam,val=beamconf.specDrizzle(xg,yg,wav)
                            if len(xyg)!=0:
                                
                                # create the PDT
                                pix=(int(xd-src.ltv[0]),int(yd-src.ltv[1]))
                                pdt=h5table.PDT(pix)
                                pdt.extend(xyg,lam,val)
                                
                                # scale the PDT by:
                                # 1. direct image weight (wd),
                                # 2. ratio of pixel areas between seg & FLT
                                # 3. wavelength sampling (trapezoidal rule)
                                pdt*=(wd*pixrat*dwav)

                                # append the PDT
                                odt.extend(pdt)

                        # if ODT is valid, then write it!
                        if len(odt)!=0:
                            xyc=np.float32(src.xyc-src.ltv)
                            
                            if TTYPE=='ODT':
                                odt.writeH5(beamgrp,RA=src.adc[0],\
                                            Dec=src.adc[1],\
                                            xc=xyc[0],yc=xyc[1],\
                                            mag=np.float32(src.mag),\
                                            area=np.float32(src.area),\
                                            npix=np.uint32(src.npix))
                            elif TTYPE=='DDT':
                                ddt=odt.decimate(thisGrism.npix)
                                ddt.writeH5(beamgrp,RA=src.adc[0],\
                                            Dec=src.adc[1],\
                                            xc=xyc[0],yc=xyc[1],\
                                            mag=np.float32(src.mag),\
                                            area=np.float32(src.area),\
                                            npix=np.uint32(src.npix))
                            else:
                                raise NotImplementedError("invalid table type")
                                        
                            
    return tab.filename
Beispiel #4
0
def makeOMTs(flt,sources,grismconf,path,remake,nsub):
    print("[info]Making the OMTs")
    # create the table
    tab=h5table.H5Table(flt.dataset,'omt',path=path)

    # remake the table?
    if remake and os.path.isfile(tab.filename):
        os.remove(tab.filename)

    with tab as h5:

        # add some stuff to that header
        h5utils.writeAttr(h5,'segmap',sources.segmap)
        h5utils.writeAttr(h5,'nsource',np.uint16(len(sources)))
        h5utils.writeAttr(h5,'detimage',sources.obsdata.detImage)
        h5utils.writeAttr(h5,'detband',sources.obsdata.detName)
        h5utils.writeAttr(h5,'maglimit',np.float32(sources.maglimit))


        for det,detconf in grismconf:

            detgrp=h5.require_group(det)

            #if det in h5:
            #    detgrp=h5[det]
            #else:
            #    detgrp=h5.create_group(det)

            # get the center of the detector
            xc,yc=detconf.naxis/2.
            thisGrism=flt[det]
                
            for beam,beamconf in detconf:
                beamgrp=detgrp.require_group(beam)
                if remake:
                    sourcesDone=[]
                else:
                    sourcesDone=list(beamgrp.keys())
                    
                    
                #if beam in detgrp:
                #    beamgrp=detgrp[beam]
                #    sourcesDone=list(beamgrp.keys())
                #else:
                #    beamgrp=detgrp.create_group(beam)
                #    sourcesDone=[]
                    
                wav=beamconf.wavelengths(xc,yc,1)      # force nsub=1

                # add some stuff to table
                h5utils.writeAttr(beamgrp,'wav0',np.float32(wav[0]))
                h5utils.writeAttr(beamgrp,'wav1',np.float32(wav[-1]))
                h5utils.writeAttr(beamgrp,'dwav',np.float32(wav[1]-wav[0]))

                # process each source
                for segid,src in sources:
                    if src.name not in sourcesDone:
                        
                        xd,yd=src.convexHull
                        xg,yg=src.xy2xy(xd,yd,thisGrism)
                        xyg,lam,val=beamconf.specDrizzle(xg,yg,wav)
                        if len(xyg)!=0:
                            omt=h5table.OMT(segid)
                            xyg=indices.unique(np.array(xyg))
                            omt.extend(xyg)
                            omt.writeH5(beamgrp,RA=src.adc[0],\
                                        Dec=src.adc[1],\
                                        xc=xyc[0],yc=xyc[1],\
                                        mag=np.float32(src.mag),\
                                        area=np.float32(src.area),\
                                        npix=np.uint32(src.npix))
                            #omt.writeH5(beamgrp)
    return tab.filename
Beispiel #5
0
    def loadFLT(self,flt,sources,extconf,mskconf,grismFF,pb,path):

        # output stuff
        i = []
        j = []
        aij = []
        
        # make mask for this FLT
        masks=self.maskBeams(flt,mskconf,path)
        import pickle,os,psutil      
        pid = os.getpid()
        py = psutil.Process(pid)
        # open the H5Table
        with h5table.H5Table(flt.dataset,self.TTYPE,path=path) as h5:
            #if __RAM__:
            #    print("start loadFLT:",py.memory_info()[0]/1024/1024/1024)
            # loop over detectors
            for detname,detimg in flt:
                h5det=h5[detname]              # get the group
                detconf=extconf[detname]     # grism config

                # save this for easy access later
                self.npix=detimg.npix
                
                # read the images
                sci,scihdr=flt.readfits(detconf.sciext,detconf.extver)
                unc,unchdr=flt.readfits(detconf.uncext,detconf.extver)
                dqa,dqahdr=flt.readfits(detconf.dqaext,detconf.extver)
                xyg=[]         # a container

                # make a good pixel mask
                gpx=(dqa == 0) & (unc > 0)
                if len(masks)!=0:
                    gpx &= masks[detname]
                del dqa,dqahdr,unchdr      # don't need these anymore
                
                #if __RAM__:
                #    print("calling loadBeams:",py.memory_info()[0]/1024/1024/1024)
                # call a load beam
                data=self.loadBeams(h5det,detconf,detimg,unc,gpx,sources,\
                                    grismFF)
                self.imgindex+=1
                #if __RAM__:
                #    print("back from loadBeams:",py.memory_info()[0]/1024/1024/1024)

                # collect the results
                if len(data[3])!=0:
                    # collect the matrix terms
                    # i.extend(data[0])
                    # j.extend(data[1])
                    # aij.extend(data[2])

                    #i = np.hstack((i,data[0]))
                    #j = np.hstack((j,data[1]))
                    #aij = np.hstack((aij,data[2]))
                    i.append(data[0])
                    j.append(data[1])
                    aij.append(data[2])

                    # compute pixel (x,y) pairs
                    xyg=indices.unique(np.array(data[3]))

                    # the following line was encapsulated in unqiify
                    # (written by R Ryan), but needs to be explicitly
                    # put in for the differences with the way unique was
                    # implemented (could put sort flag in indices.unique)
                    xyg=np.sort(xyg)
                    
                    xg,yg=indices.one2two(xyg,detimg.naxis)
                    xg=xg.astype(int)
                    yg=yg.astype(int)
                    bi=sci[yg,xg]/unc[yg,xg]
                    del xg,yg     # clean up memory usage
                    
                    
                    # check for bad values in bi
                    g=np.where(np.isinf(bi))[0]
                    if len(g)!=0:
                        print('[warn]Infinite values in bi; is UNC image ok?')
                        print(bi[g])
                        raise RuntimeError("Infinite values. aborting.")

                    # like IDL's push
                    #self.bi.extend(bi)
                    self.bi = np.hstack((self.bi,bi))
                    del bi    # again, every little bit helps
                    
                # save the memory usage
                del data
        i = np.hstack(i)
        j = np.hstack(j)
        aij = np.hstack(aij)
        #if __RAM__:
        #    print("done with loadBeams:",py.memory_info()[0]/1024/1024/1024)

        return i,j,aij
Beispiel #6
0
def simulateWorker(flt, conf, grismconf, grismflat, sources, overwrite=True):
    ''' helper function to facilitate multiprocessing '''

    path = conf['tables']['path']

    # make the output fits file
    hdul = fits.HDUList()

    # get the primary header from the FLT
    #hdr=flt.phdu
    hdr = fits.Header()

    # make a timestamp
    now = datetime.datetime.now()

    # update the PHDU for the output image
    hdr.append(('ORIGIN', 'pyLINEAR', 'how the file was created'), end=True)
    hdr.append(('VERSION', __version__, 'pyLINEAR version'), end=True)
    hdr.append(('DATE',now.strftime("%Y-%m-%d"),\
                'date this file was written (yyyy-mm-dd)'),end=True)

    hdr.add_blank(value='', after='DATE')
    hdr.add_blank(value='/ Observational Properties')
    hdr.add_blank(value='')
    hdr.append(('TELESCOP',grismconf.telescope,\
                'telescope used to "acquire" data'),end=True)
    hdr.append(('INSTRUME',grismconf.camera,\
                'instrument used to "acquire" data'),end=True)
    hdr.append(('DETECTOR', grismconf.instrument, 'detector in use'), end=True)
    hdr.append(('ROOTNAME',flt.dataset,'rootname of the observation set'),\
               end=True)
    hdr.append(('OBSTYPE','SPECTROSCOPIC',\
                'observation type - imaging or spectroscopic'),end=True)
    hdr.append(('FILTER',grismconf.grism,\
                'element selected from filter wheel'),end=True)

    hdr.add_blank(value='', after='FILTER')
    hdr.add_blank(value='/ Simulation Properties')
    hdr.add_blank(value='')
    hdr.append(('NSOURCE', len(sources), 'number of simulated sources'),
               end=True)
    hdr.append(('SEGMAP', sources.segmap, 'segmentation map'), end=True)
    hdr.append(('DETIMG', sources.obsdata.detImage, 'detection image'),
               end=True)

    hdr.add_blank(value='', after='DETIMG')
    hdr.add_blank(value='/ Noise Properties')
    hdr.add_blank(value='')
    hdr.append(('NOISE', conf['noise']['perform'], 'is noise added?'),
               end=True)
    if conf['noise']['perform']:
        hdr.append(('SKYRATE',conf['noise']['skyrate'],\
                    'sky count rate [e-/s]'),end=True)
        hdr.append(('EXPTIME',conf['noise']['exptime'],\
                    'exposure time [s]'),end=True)
        after = 'EXPTIME'
    else:
        after = 'NOISE'

    hdr.add_blank(value='', after=after)
    hdr.add_blank(value='/ YAML Input')
    hdr.add_blank(value='')
    hdr.add_blank(value='')

    for value in conf:
        hdr.add_comment(value=value)

    # put this in the FITS FILE
    hdul.append(fits.PrimaryHDU(header=hdr))

    # open the H5table
    with h5table.H5Table(flt.dataset, path=path, suffix=TTYPE) as h5:
        # loop over detectors within an FLT
        for detname, det in flt:

            detgrp = h5[detname]

            detconf = grismconf[detname]

            # get the EXTVER, which describes which detector this is
            extver = detconf.extver

            # create an empty array
            sci = np.zeros(np.flip(det.naxis, 0), dtype=SCITYPE)

            for beam, beamconf in detconf:
                beamgrp = detgrp[beam]

                for segid, src in sources:
                    if TTYPE == 'odt':
                        odt = h5table.ODT(segid)
                        odt.readH5(beamgrp)
                        ddt = odt.decimate()
                        del odt
                    elif TTYPE == 'ddt':
                        ddt = h5table.DDT(segid)
                        ddt.readH5(beamgrp)
                    else:
                        raise NotImplementedError("Invalid TTYPE")

                    if len(ddt) != 0:

                        # compute the (x,y) pair for each val in the DDT
                        xg, yg = indices.one2two(ddt.xyg, det.naxis)

                        # get scaling terms
                        s = beamconf.sensitivity(ddt.wav)
                        f = src.sed.interpolate(ddt.wav)
                        p = det.pixelArea(xg, yg)
                        ff = grismflat(xg, yg, ddt.wav, detname)

                        # scale the DDT
                        ddt *= (s * f * p * ff)
                        del s, f, p, ff

                        # sum over pixels
                        val, xyu = indices.decimate(ddt.xyg, ddt.val)
                        del ddt

                        # get unique coordinates
                        xg, yg = indices.one2two(xyu, det.naxis)
                        del xyu

                        # put flux in the image
                        sci[yg, xg] += val
                        del val

            # update the SCI image for noise and make an UNC image
            sci, unc = addNoise(conf['noise'], sci)

            # create a DQA image (set to all 0)
            dqa = np.full_like(sci, 0, dtype=DQATYPE)

            # the SCI image
            hdr = det.mkhdr(SCITYPE, extname=detconf.sciext, extver=extver)
            hdul.append(fits.ImageHDU(data=sci, header=hdr))

            # the UNC image
            hdr = det.mkhdr(UNCTYPE, extname=detconf.uncext, extver=extver)
            hdul.append(fits.ImageHDU(data=unc, header=hdr))

            # the DQA image
            hdr = det.mkhdr(DQATYPE, extname=detconf.dqaext, extver=extver)
            hdul.append(fits.ImageHDU(data=dqa, header=hdr))

    # output the file
    outfile = flt.filename
    print('writing simulated image {}'.format(outfile))
    hdul.writeto(outfile, overwrite=overwrite)

    # do we gzip?
    if conf['gzip']:
        gzip.gzip(outfile)
        outfile += '.gz'

    return outfile
Beispiel #7
0
def groupFLT(flt, sources, extconf, path, minarea=0.1):

    #print('loading the polygons for {}'.format(flt.dataset))

    # get the polygons for this FLT:
    with h5table.H5Table(flt.dataset, TTYPE, path=path) as h5:
        for detname, detimg in flt:
            h5det = h5[detname]
            detconf = extconf[detname]

            for beam, beamconf in detconf:
                h5beam = h5det[beam]

                ids = []
                polys = []

                for segid, src in sources:
                    # read the DDT
                    ddt = h5table.DDT(src.segid)
                    ddt.readH5(h5beam)
                    if len(ddt) != 0:

                        # collect the points accordingly
                        xyg = ddt.xyg.to_numpy
                        xyg = indices.unique(xyg)
                        x, y = indices.one2two(xyg, detimg.naxis)
                        del xyg

                        # get the vertices
                        xy = convexhull.vertices(x, y)

                        # reform to (x,y) pairs
                        xy = list(zip(*xy))

                        # make into a polygon from Shapely
                        poly = Polygon(xy)

                        # save the results
                        ids.append([segid])
                        polys.append(poly)
    # At this point, we've made shapely.Polygons out of a given DDT

    #print('grouping the polygons for {}'.format(flt.dataset))

    # group those sources with Shapely math
    data = list(zip(ids, polys))
    nnew = ndata = len(ids)
    if nnew == 0:
        #print('[warn]No objects to group for {}'.format(flt.dataset))
        return []

    while nnew != 0:
        groups = []

        while len(data) != 0:
            thisid, thispoly = data.pop(0)

            #ids=thisid
            for i, (testid, testpoly) in enumerate(data):
                inter = thispoly.intersection(testpoly)
                #inter=inter.area   # intersection area

                r1 = inter.area / testpoly.area
                r2 = inter.area / thispoly.area
                if r1 > minarea and r2 > minarea:
                    #if area>minarea:
                    data.pop(i)  # it was grouped, so remove it from the list

                    #print(r1,r2)
                    #print(inter.area,testpoly.area,thispoly.area)
                    #fig,ax=plt.subplots(1,1)
                    #ax.plot(*thispoly.exterior.xy, color='#6699cc', alpha=0.7,
                    #        linewidth=3, solid_capstyle='round', zorder=2)
                    #ax.plot(*testpoly.exterior.xy, color='#cccccc', alpha=0.7,
                    #        linewidth=3, solid_capstyle='round', zorder=2)
                    #ax.set_title('Polygon')
                    #plt.show()

                    # update the this
                    thispoly = thispoly.union(testpoly)
                    thisid.extend(testid)
                    #print(i,area,thisid)

            groups.append((thisid, thispoly))
        data = groups
        nnew = ndata - len(data)
        ndata = len(data)

    # get just the IDs
    groups = list(zip(*groups))[0]

    # return a list of sets
    ids = [set(group) for group in groups]
    #print(len(ids))

    return ids