示例#1
0
def test_progress_bar_as_generator():
    sum = 0
    for x in console.ProgressBar(range(50)):
        sum += x
    assert sum == 1225

    sum = 0
    for x in console.ProgressBar(50):
        sum += x
    assert sum == 1225
示例#2
0
def main(date, auto_confirm=False):
    db = PanMongo()

    seq_ids = db.observations.distinct(
        'sequence_id', {'date': {'$gte': Time(date).datetime}})
    imgs = [record['data']['file_path'] for record in db.observations.find(
        {'sequence_id': {'$in': seq_ids}}, {'data.file_path': 1})]

    dirs = set([img[0:img.rindex('/') - 1].replace('/var/panoptes/images/fields/', '')
                for img in imgs])

    if auto_confirm is False:
        print("Found the following dirs for {}:".format(date))
        pprint(dirs)
        if input("Proceed (Y/n): ") == 'n':
            return

    for d in console.ProgressBar(dirs):
        run_cmd = ['gsutil', '-mq', 'cp', '-r', '/var/panoptes/images/fields/{}/*.fz'.format(d),
                   'gs://panoptes-survey/PAN001/{}/'.format(d)]

        try:
            completed_process = subprocess.run(run_cmd, stdout=subprocess.PIPE)

            if completed_process.returncode != 0:
                print("Problem uploading")
                print(completed_process.stdout)
        except Exception as e:
            print("Problem uploading: {}".format(e))
def MakeRoundBeam(incube, outfile=None, overwrite=True):
    '''
    This takes a FITS file or a SpectralCube and outputs

    Parameters
    ----------
    filename : `string` or `SpectralCube`
       Input spectral cube

    Returns
    -------
    cube : `SpectralCube`

    '''
    if isinstance(incube, str):
        cube = SpectralCube.read(incube)

    if isinstance(incube, VaryingResolutionSpectralCube):
        cube = incube

    if not isinstance(cube, VaryingResolutionSpectralCube):
        warnings.warn("No information about multiple beams")
        return (None)

    beams = cube.beams
    major_axes = np.array([bm.major.to(u.deg).value for bm in beams])
    target_beamsize = np.array(major_axes.max())
    target_beam = Beam(major=target_beamsize * u.deg,
                       minor=target_beamsize * u.deg,
                       pa=0.0 * u.deg)
    print("Target beam is : {}".format(target_beam))

    # Let's assume square pixels
    pixsize = cube.wcs.pixel_scale_matrix[1, 1]
    fwhm2sigma = np.sqrt(8 * np.log(2))

    output = np.zeros(cube.shape)

    with console.ProgressBar(cube.shape[0]) as bar:

        for ii, plane in enumerate(cube.filled_data[:]):
            this_beam = beams[ii]
            conv_beam = target_beam - this_beam

            majpix = conv_beam.major.value / pixsize / fwhm2sigma
            minpix = conv_beam.minor.value / pixsize / fwhm2sigma

            output[ii, :, :] = ftconvolve(plane,
                                          major=majpix,
                                          minor=minpix,
                                          angle=conv_beam.pa.value)

            bar.update()

    hdr = copy.copy(cube.header)
    hdr['CASAMBM'] = False
    hdr['BMAJ'] = float(target_beam.major.value)
    hdr['BMIN'] = float(target_beam.major.value)
    hdr['BPA'] = 0.0
    outcube = SpectralCube(output, cube.wcs, header=hdr)
    if outfile:
        outcube.write(outfile, overwrite=overwrite)
        return None
    return (outcube)
示例#4
0
def griddata(pixPerBeam=3.0,
             templateHeader=None,
             gridFunction=jincGrid,
             rootdir='/lustre/pipeline/scratch/GAS/',
             region='NGC1333',
             dirname='NGC1333_NH3_11',
             startChannel=762, endChannel=3584,
             doBaseline=True,
             baselineRegion=[slice(762, 1024, 1), slice(3072, 3584, 1)],
             blorder=1,
             Sessions=None,
             file_extension=None,
             rebase=False, **kwargs):

    if not Sessions:
        filelist = glob.glob(rootdir + '/' + region + '/' + dirname + '/*fits')
        if not file_extension:
            file_extension = '_all'
        history_message = 'Gridding of data using all sessions'
    else:
        filelist = []
        for scan_i in Sessions:
                filelist.extend(glob.glob(rootdir + '/' + region +
                                          '/' + dirname + '/*_sess' +
                                          str(scan_i) + '.fits'))
        if isinstance(Sessions, list):
            if not file_extension:
                file_extension = '_sess{0}-sess{1}'.format(Sessions[0],
                                                           Sessions[-1])
            if (Sessions[-1] + 1. - Sessions[0]) / len(Sessions) == 1.0:
                history_message = 'Gridding of data using sessions' \
                    'between {0} and {1}'.format(Sessions[0], Sessions[-1])
            else:
                history_message = 'Gridding of data using sessions: '
                for scan_i in Sessions:
                    history_message += '{0}, '.format(scan_i)
        else:
            if not file_extension:
                file_extension = '_sess{0}'.format(Sessions)
            history_message = 'Gridding of data using session'\
                '{0}'.format(Sessions)

    if len(filelist) == 0:
        warnings.warn('There are no FITS files to process '
                      'in ' + rootdir + '/' + region + '/' + dirname)
        return
    # check that every file in the filelist is valid
    # If not then remove it and send warning message
    for file_i in filelist:
        try:
            fits.open(file_i)
        except:
            warnings.warn('file {0} is corrupted'.format(file_i))
            filelist.remove(file_i)
    # pull a test structure
    s = fits.getdata(filelist[0])

    c = 299792458.
    nu0 = s[0]['RESTFREQ']

    Data_Unit = s[0]['TUNIT7']
    beamSize = 1.22 * (c / nu0 / 100.0) * 180 / np.pi  # in degrees

    naxis3 = len(s[0]['DATA'][startChannel:endChannel])

    # Default behavior is to park the object velocity at
    # the center channel in the VRAD-LSR frame

    crval3 = s[0]['RESTFREQ'] * (1 - s[0]['VELOCITY'] / c)
    crpix3 = s[0]['CRPIX1'] - startChannel
    ctype3 = s[0]['CTYPE1']
    cdelt3 = s[0]['CDELT1']

    w = wcs.WCS(naxis=3)

    w.wcs.restfrq = nu0
    w.wcs.radesys = s[0]['RADESYS']
    w.wcs.equinox = s[0]['EQUINOX']
    # We are forcing this conversion to make nice cubes.
    w.wcs.specsys = 'LSRK'
    w.wcs.ssysobs = 'TOPOCENT'

    if templateHeader is None:
        wcsdict = autoHeader(filelist, beamSize=beamSize,
                             pixPerBeam=pixPerBeam)
        w.wcs.crpix = [wcsdict['CRPIX1'], wcsdict['CRPIX2'], crpix3]
        w.wcs.cdelt = np.array([wcsdict['CDELT1'], wcsdict['CDELT2'], cdelt3])
        w.wcs.crval = [wcsdict['CRVAL1'], wcsdict['CRVAL2'], crval3]
        w.wcs.ctype = [wcsdict['CTYPE1'], wcsdict['CTYPE2'], ctype3]
        naxis2 = wcsdict['NAXIS2']
        naxis1 = wcsdict['NAXIS1']
    else:
        w.wcs.crpix = [templateHeader['CRPIX1'],
                       templateHeader['CRPIX2'], crpix3]
        w.wcs.cdelt = np.array([templateHeader['CDELT1'],
                                templateHeader['CDELT2'], cdelt3])
        w.wcs.crval = [templateHeader['CRVAL1'],
                       templateHeader['CRVAL2'], crval3]
        w.wcs.ctype = [templateHeader['CTYPE1'],
                       templateHeader['CTYPE2'], ctype3]
        naxis2 = templateHeader['NAXIS2']
        naxis1 = templateHeader['NAXIS1']
    outCube = np.zeros((int(naxis3), int(naxis2), int(naxis1)))
    outWts = np.zeros((int(naxis2), int(naxis1)))

    xmat, ymat = np.meshgrid(np.arange(naxis1), np.arange(naxis2),
                             indexing='ij')
    xmat = xmat.reshape(xmat.size)
    ymat = ymat.reshape(ymat.size)
    xmat = xmat.astype(np.int)
    ymat = ymat.astype(np.int)

    ctr = 0
    for thisfile in filelist:
        ctr += 1
        s = fits.open(thisfile)
        print("Now processing {0}".format(thisfile))
        print("This is file {0} of {1}".format(ctr, len(filelist)))

        nuindex = np.arange(len(s[1].data['DATA'][0]))

        for spectrum in console.ProgressBar((s[1].data)):
            # Generate Baseline regions
            baselineIndex = np.concatenate([nuindex[ss]
                                            for ss in baselineRegion])

            specData = spectrum['DATA']
            # baseline fit
            if doBaseline & np.all(np.isfinite(specData)):
                specData = baselineSpectrum(specData, order=blorder,
                                            baselineIndex=baselineIndex)

            # This part takes the TOPOCENTRIC frequency that is at
            # CRPIX1 (i.e., CRVAL1) and calculates the what frequency
            # that would have in the LSRK frame with freqShiftValue.
            # This then compares to the desired frequency CRVAL3.

            DeltaNu = freqShiftValue(spectrum['CRVAL1'],
                                     -spectrum['VFRAME']) - crval3
            DeltaChan = DeltaNu / cdelt3
            specData = channelShift(specData, -DeltaChan)
            outslice = (specData)[startChannel:endChannel]
            spectrum_wt = np.isfinite(outslice).astype(np.float)
            outslice = np.nan_to_num(outslice)
            xpoints, ypoints, zpoints = w.wcs_world2pix(spectrum['CRVAL2'],
                                                        spectrum['CRVAL3'],
                                                        spectrum['CRVAL1'], 0)
            tsys = spectrum['TSYS']
            if (tsys > 10) and (xpoints > 0) and (xpoints < naxis1) \
                    and (ypoints > 0) and (ypoints < naxis2):
                pixelWeight, Index = gridFunction(xmat, ymat,
                                                  xpoints, ypoints,
                                                  pixPerBeam=pixPerBeam)
                vector = np.outer(outslice * spectrum_wt,
                                  pixelWeight / tsys**2)
                wts = pixelWeight / tsys**2
                outCube[:, ymat[Index], xmat[Index]] += vector
                outWts[ymat[Index], xmat[Index]] += wts
        # Temporarily do a file write for every batch of scans.
        outWtsTemp = np.copy(outWts)
        outWtsTemp.shape = (1,) + outWtsTemp.shape
        outCubeTemp = np.copy(outCube)
        outCubeTemp /= outWtsTemp

        hdr = fits.Header(w.to_header())
        hdr = addHeader_nonStd(hdr, beamSize, Data_Unit)
        #
        hdu = fits.PrimaryHDU(outCubeTemp, header=hdr)
        hdu.writeto(dirname + file_extension + '.fits', clobber=True)

    outWts.shape = (1,) + outWts.shape
    outCube /= outWts

    # Create basic fits header from WCS structure
    hdr = fits.Header(w.to_header())
    # Add non standard fits keyword
    hdr = addHeader_nonStd(hdr, beamSize, Data_Unit)
    # Adds history message
    hdr.add_history(history_message)
    hdr.add_history('Using GAS pipeline version {0}'.format(__version__))
    hdu = fits.PrimaryHDU(outCube, header=hdr)
    hdu.writeto(dirname + file_extension + '.fits', clobber=True)

    w2 = w.dropaxis(2)
    hdr2 = fits.Header(w2.to_header())
    hdu2 = fits.PrimaryHDU(outWts, header=hdr2)
    hdu2.writeto(dirname + file_extension + '_wts.fits', clobber=True)

    if rebase:
        if 'NH3_11' in dirname:
            baseline.rebaseline(dirname + file_extension + '.fits',
                                windowFunction=baseline.ammoniaWindow,
                                line='oneone', **kwargs)

        if 'NH3_22' in dirname:
            winfunc = baseline.ammoniaWindow
            baseline.rebaseline(dirname + file_extension + '.fits',
                                windowFunction=baseline.ammoniaWindow,
                                line='twotwo', **kwargs)

        if 'NH3_33' in dirname:
            baseline.rebaseline(dirname + file_extension + '.fits',
                                winfunc = baseline.ammoniaWindow,
                                line='threethree', **kwargs)
        else:
            baseline.rebaseline(dirname + file_extension + '.fits',
                                windowFunction=baseline.tightWindow, 
                                **kwargs)
def test_zero_progress_bar():
    with console.ProgressBar(0) as bar:
        pass
def test_progress_bar2():
    for x in console.ProgressBar(range(50)):
        pass
def test_progress_bar():
    # This stuff is hard to test, at least smoke test it
    with console.ProgressBar(50) as bar:
        for i in range(50):
            bar.update()
示例#8
0
def rebaseline(filename,
               blorder=3,
               baselineRegion=[slice(0, 800, 1),
                               slice(-800, 0, 1)],
               windowFunction=None,
               blankBaseline=False,
               flagSpike=True,
               v0=None,
               VlsrByCoord=None,
               verbose=False,
               **kwargs):
    """
    Rebaseline a data cube using robust regression of Legendre polynomials.

    Parameters
    ----------
    filename : string
        FITS filename of the data cube
    blorder : int
        Order of the polynomial to fit to the data
    baselineRegion : list
        List of slices defining the default region of the spectrum, in
        channels, to be used for the baseline fitting.
    windowFunction : function
        Name of function to be used that will accept spectrum data, and
        velocity axis and will return a binary mask of the channels to be used
        in the  baseline fitting.  Extra **kwargs are passed to windowFunction
        to do with as it must.
    blankBaseline : boolean
        Blank the baseline region on a per-spectrum basis

    Returns
    -------
    Nothing.  A new FITS file is written out with the suffix 'rebaseN' where N
    is the baseline order

    """
    cube = SpectralCube.read(filename)
    originalUnit = cube.spectral_axis.unit
    cube = cube.with_spectral_unit(u.km / u.s, velocity_convention='radio')
    spaxis = cube.spectral_axis.to(u.km / u.s).value

    goodposition = np.isfinite(cube.apply_numpy_function(np.max, axis=0))
    y, x = np.where(goodposition)
    outcube = np.zeros(cube.shape) * np.nan
    RegionName = (filename.split('/'))[-1]
    RegionName = (RegionName.split('_'))[0]
    nuindex = np.arange(cube.shape[0])
    runmin = nuindex[-1]
    runmax = nuindex[0]
    if verbose:
        pb = console.ProgressBar(len(y))
    for thisy, thisx in zip(y, x):
        spectrum = cube[:, thisy, thisx].value

        if v0 is not None:
            baselineIndex = windowFunction(spectrum, spaxis, v0=v0, **kwargs)
        elif hasattr(windowFunction, '__call__') and \
                hasattr(VlsrByCoord, '__call__'):
            _, Dec, RA = cube.world[0, thisy, thisx]
            # This determines a v0 appropriate for the region
            v0 = VlsrByCoord(RA.value, Dec.value, RegionName, **kwargs)
            baselineIndex = windowFunction(spectrum, spaxis, v0=v0, **kwargs)
        else:
            baselineIndex = np.zeros_like(spectrum, dtype=np.bool)
            for ss in baselineRegion:
                baselineIndex[ss] = True

        runmin = np.min([nuindex[baselineIndex].min(), runmin])
        runmax = np.max([nuindex[baselineIndex].max(), runmax])

        # Use channel-to-channel difference as the noise value.
        if flagSpike:
            jumps = (spectrum - np.roll(spectrum, -1))
            noise = mad1d(jumps) * 2**(-0.5)
            baselineIndex *= (np.abs(jumps) < 5 * noise)
            noise = mad1d(
                (spectrum - np.roll(spectrum, -2))[baselineIndex]) * 2**(-0.5)
        else:
            noise = mad1d(
                (spectrum - np.roll(spectrum, -2))[baselineIndex]) * 2**(-0.5)

        if blankBaseline:
            spectrum = robustBaseline(spectrum,
                                      baselineIndex,
                                      blorder=blorder,
                                      noiserms=noise)
            spectrum[baselineIndex] = np.nan
            outcube[:, thisy, thisx] = spectrum
        else:
            outcube[:, thisy, thisx] = robustBaseline(spectrum,
                                                      baselineIndex,
                                                      blorder=blorder,
                                                      noiserms=noise)
        if verbose:
            pb.update()
    outsc = SpectralCube(outcube,
                         cube.wcs,
                         header=cube.header,
                         meta={'BUNIT': cube.header['BUNIT']})
    outsc = outsc[runmin:runmax, :, :]  # cut beyond baseline edges

    # Return to original spectral unit
    outsc = outsc.with_spectral_unit(originalUnit)
    outsc.write(filename.replace('.fits', '_rebase{0}.fits'.format(blorder)),
                overwrite=True)
示例#9
0
def griddata(pixPerBeam=3.0,
             templateHeader=None,
             gridFunction=jincGrid,
             rootdir='/lustre/pipeline/scratch/GAS/',
             region='NGC1333',
             dirname='NGC1333_NH3_11',
             startChannel=1024,
             endChannel=3072,
             doBaseline=True,
             baselineRegion=[slice(512, 1024, 1),
                             slice(3072, 3584, 1)]):

    filelist = glob.glob(rootdir + '/' + region + '/' + dirname + '/*fits')
    #pull a test structure
    s = fits.getdata(filelist[0])

    c = 299792458.
    nu0 = s[0]['RESTFREQ']

    Data_Unit = s[0]['TUNIT7']
    beamSize = 1.22 * (c / nu0 / 100.0) * 180 / np.pi  # in degrees

    naxis3 = len(s[0]['DATA'][startChannel:endChannel])
    nuindex = np.arange(len(s[0]['DATA']))
    baselineIndex = np.concatenate([nuindex[ss] for ss in baselineRegion])
    nuslice = (range(naxis3))[startChannel:endChannel]

    # Default behavior is to park the object velocity at the center channel in the VRAD-LSR frame
    crval3 = s[0]['RESTFREQ'] * (1 - s[0]['VELOCITY'] / c)
    crpix3 = s[0]['CRPIX1'] - startChannel
    ctype3 = s[0]['CTYPE1']
    cdelt3 = s[0]['CDELT1']

    w = wcs.WCS(naxis=3)

    w.wcs.restfrq = nu0
    w.wcs.radesys = s[0]['RADESYS']
    w.wcs.equinox = s[0]['EQUINOX']
    w.wcs.specsys = 'LSRK'  # We are forcing this conversion to make nice cubes.
    w.wcs.ssysobs = 'TOPOCENT'

    if templateHeader is None:
        wcsdict = autoHeader(filelist,
                             beamSize=beamSize,
                             pixPerBeam=pixPerBeam)
        w.wcs.crpix = [wcsdict['CRPIX1'], wcsdict['CRPIX2'], crpix3]
        w.wcs.cdelt = np.array([wcsdict['CDELT1'], wcsdict['CDELT2'], cdelt3])
        w.wcs.crval = [wcsdict['CRVAL1'], wcsdict['CRVAL2'], crval3]
        w.wcs.ctype = [wcsdict['CTYPE1'], wcsdict['CTYPE2'], ctype3]
        naxis2 = wcsdict['NAXIS2']
        naxis1 = wcsdict['NAXIS1']
    else:
        w.wcs.crpix = [
            templateHeader['CRPIX1'], templateHeader['CRPIX2'], crpix3
        ]
        w.wcs.cdelt = np.array(
            [templateHeader['CDELT1'], templateHeader['CDELT2'], cdelt3])
        w.wcs.crval = [
            templateHeader['CRVAL1'], templateHeader['CRVAL2'], crval3
        ]
        w.wcs.ctype = [
            templateHeader['CTYPE1'], templateHeader['CTYPE2'], ctype3
        ]
        naxis2 = templateHeader['NAXIS2']
        naxis1 = templateHeader['NAXIS1']
    outCube = np.zeros((naxis3, naxis2, naxis1))
    outWts = np.zeros((naxis2, naxis1))

    xmat, ymat = np.meshgrid(np.arange(naxis1),
                             np.arange(naxis2),
                             indexing='ij')
    xmat = xmat.reshape(xmat.size)
    ymat = ymat.reshape(ymat.size)
    xmat = xmat.astype(np.int)
    ymat = ymat.astype(np.int)

    ctr = 0
    for thisfile in filelist:
        ctr += 1
        s = fits.open(thisfile)
        print("Now processing {0}".format(thisfile))
        print("This is file {0} of {1}".format(ctr, len(filelist)))
        for spectrum in console.ProgressBar((s[1].data)):  #pre-processing
            specData = spectrum['DATA']
            #baseline fit
            if doBaseline:
                specData = baselineSpectrum(specData,
                                            order=1,
                                            baselineIndex=baselineIndex)

            # This part takes the TOPOCENTRIC frequency that is at
            # CRPIX1 (i.e., CRVAL1) and calculates the what frequency
            # that would have in the LSRK frame with freqShiftValue.
            # This then compares to the desired frequency CRVAL3.

            DeltaNu = freqShiftValue(spectrum['CRVAL1'],
                                     -spectrum['VFRAME']) - crval3
            DeltaChan = DeltaNu / cdelt3
            specData = channelShift(specData, -DeltaChan)
            outslice = (specData)[startChannel:endChannel]
            spectrum_wt = np.isfinite(outslice).astype(np.float)
            outslice = np.nan_to_num(outslice)
            xpoints, ypoints, zpoints = w.wcs_world2pix(
                spectrum['CRVAL2'], spectrum['CRVAL3'], spectrum['CRVAL1'], 0)
            tsys = spectrum['TSYS']
            if (tsys>10) and (xpoints > 0) and (xpoints < naxis1) \
                    and (ypoints >0) and (ypoints < naxis2):
                pixelWeight, Index = gridFunction(xmat,
                                                  ymat,
                                                  xpoints,
                                                  ypoints,
                                                  pixPerBeam=pixPerBeam)
                vector = np.outer(outslice * spectrum_wt,
                                  pixelWeight / tsys**2)
                vector_wts = np.outer(spectrum_wt, pixelWeight / tsys**2)
                wts = pixelWeight / tsys**2
                outCube[:, ymat[Index], xmat[Index]] += vector
                outWts[ymat[Index], xmat[Index]] += wts
# Temporarily do a file write for every batch of scans.
        outWtsTemp = np.copy(outWts)
        outWtsTemp.shape = (1, ) + outWtsTemp.shape
        outCubeTemp = np.copy(outCube)
        outCubeTemp /= outWtsTemp

        hdr = fits.Header(w.to_header())
        hdr = addHeader_nonStd(hdr, beamSize, Data_Unit)
        #
        hdu = fits.PrimaryHDU(outCubeTemp, header=hdr)
        hdu.writeto(dirname + '.fits', clobber=True)

    outWts.shape = (1, ) + outWts.shape
    outCube /= outWts

    # Create basic fits header from WCS structure
    hdr = fits.Header(w.to_header())
    # Add non standard fits keyword
    hdr = addHeader_nonStd(hdr, beamSize, Data_Unit)
    #
    hdu = fits.PrimaryHDU(outCube, header=hdr)
    hdu.writeto(dirname + '.fits', clobber=True)

    w2 = w.dropaxis(2)
    hdr2 = fits.Header(w2.to_header())
    hdu2 = fits.PrimaryHDU(outWts, header=hdr2)
    hdu2.writeto(dirname + '_wts.fits', clobber=True)
示例#10
0
def griddata(filelist,
             pixPerBeam=3.5,
             templateHeader=None,
             gridFunction=jincGrid,
             startChannel=1024,
             endChannel=3072,
             doBaseline=True,
             baselineRegion=None,
             blorder=1,
             rebase=None,
             rebaseorder=None,
             beamSize=None,
             OnlineDoppler=True,
             flagRMS=False,
             flagRipple=False,
             flagSpike=False,
             blankSpike=False,
             plotTimeSeries=False,
             rmsThresh=1.25,
             spikeThresh=10,
             projection='TAN',
             plotsubdir='',
             outdir=None,
             outname=None,
             dtype=np.float64,
             flagSpatialOutlier=False,
             gainDict=None,
             **kwargs):
    """Gridding code for GBT spectral scan data produced by pipeline.
    
    Parameters
    ----------
    filelist : list
        List of FITS files to be gridded into an output

    Keywords
    --------
    pixPerBeam : float
        Number of pixels per beam FWHM

    templateHeader : `Header` object
        Template header used for spatial pixel grid.

    gridFunction : function 
        Gridding function to be used.  The default `jincGrid` is a
        tapered circular Bessel function.  The function has call
        signature of func(xPixelCentre, yPixelCenter, xData, yData,
        pixPerBeam)

    startChannel : int
        Starting channel for spectrum within the original spectral data.

    endChannel : int
        End channel for spectrum within the original spectral data

    doBaseline : bool
        Setting to True (default) performs per-scan baseline corrections.

    baselineRegion : `numpy.slice` or list of `numpy.slice`
        Regions in the original pixel data used for fitting the baseline.

    blorder : int
        Order of baseline.  Defaults to 1 (linear)

    rebase : bool
        Setting to True (default is False) performs per-pixel
        rebaselining of the resulting cube.

    beamSize : float
        Telescope beam size at this frequency measured in degrees.

    OnlineDopper : bool
        Setting to True (default) assumes that the Doppler corrections
        in the data are corrected during a telescope scan.  Setting to
        False assumes that the Doppler correction is updated at the
        end of a scan and linearly interpolates between scan ends.
        
    flagRMS : bool
        Setting to True (default = False) flags spectra with rms
        values >rmsThresh x higher than prediction from the radiometer
        formula.  This rms determination assumes that channels are not
        strongly correlated

    rmsThresh : float
        Threshold for scan flagging based on rms.  Default = 1.5

    flagRipple : bool
        Setting to True (default = False) flags spectra with structure
        in the line that is 2x higher than the rms prediction of the
        radiometer formula.  Note that these estimators are outlier
        robust.

    flagSpike : bool
        Setting to True (default = False) flags regions in spectra 
        that show jumps of > 5 times the typical pixel to pixel fluctuation.

    blankSpike : bool
        Setting to True sets spikes to zero to avoid corrupting data
        before frequency shifting.

    plotTimeSeries : bool
        Create scan vs frequency plot to inspect raw scan data.  This
        saves a PNG file to the output directory.

    plotsubdir : str
        Subdirectory for timeseries plots.  Defaults to same directory as imaging.

    outdir : str
        Output directory name.  Defaults to current working directory.

    outname : str
        Output directory file name.  Defaults to object name in the
        original spectra.

    flagSpatialOutlier : bool
        Setting to True will remove scans with positions far outside the 
        bounding box of the regular scan pattern. Used to catch instances
        where the encoder records erroneous positions. 

    gainDict : dict 
        Dictionary that has a tuple of feed and polarization numbers
        as keys and returns the gain values for that feed.
    
    Returns
    -------
    None

    """

    eulerFlag = False
    print("Starting Gridding")
    if outdir is None:
        outdir = os.getcwd()

    if baselineRegion is None:
        baselineRegion = [slice(1024, 1536, 1), slice(2560, 3072, 1)]

    if len(filelist) == 0:
        warnings.warn('There are no FITS files to process ')
        return
    # check that every file in the filelist is valid
    # If not then remove it and send warning message
    for file_i in filelist:
        try:
            fits.open(file_i)
        except:
            warnings.warn('file {0} is corrupted'.format(file_i))
            filelist.remove(file_i)

    # pull a test structure
    hdulist = fits.open(filelist[0])
    s = hdulist[1].data

    # Constants block
    sqrt2 = np.sqrt(2)
    mad2rms = 1.4826
    prefac = mad2rms / sqrt2
    c = 299792458.

    nu0 = s[0]['RESTFREQ']
    Data_Unit = s[0]['TUNIT7']

    if outname is None:
        outname = s[0]['OBJECT']

    # New Beam size measurements use 1.18 vs. 1.22 based on GBT Memo 296.

    if beamSize is None:
        beamSize = 1.18 * (c / nu0 / 100.0) * 180 / np.pi  # in degrees
    naxis3 = len(s[0]['DATA'][startChannel:endChannel])

    # Default behavior is to park the object velocity at
    # the center channel in the VRAD-LSR frame

    crval3 = s[0]['RESTFREQ'] * (1 - s[0]['VELOCITY'] / c)
    crpix3 = s[0]['CRPIX1'] - startChannel
    ctype3 = s[0]['CTYPE1']
    cdelt3 = s[0]['CDELT1']

    w = wcs.WCS(naxis=3)

    w.wcs.restfrq = nu0
    # We are forcing this conversion to make nice cubes.
    w.wcs.specsys = 'LSRK'
    w.wcs.ssysobs = 'TOPOCENT'

    if templateHeader is None:
        wcsdict = autoHeader(filelist,
                             beamSize=beamSize,
                             pixPerBeam=pixPerBeam,
                             projection=projection)
        w.wcs.crpix = [wcsdict['CRPIX1'], wcsdict['CRPIX2'], crpix3]
        w.wcs.cdelt = np.array([wcsdict['CDELT1'], wcsdict['CDELT2'], cdelt3])
        w.wcs.crval = [wcsdict['CRVAL1'], wcsdict['CRVAL2'], crval3]
        w.wcs.ctype = [wcsdict['CTYPE1'], wcsdict['CTYPE2'], ctype3]
        naxis2 = wcsdict['NAXIS2']
        naxis1 = wcsdict['NAXIS1']
        w.wcs.radesys = s[0]['RADESYS']
        w.wcs.equinox = s[0]['EQUINOX']

    else:
        w.wcs.crpix = [
            templateHeader['CRPIX1'], templateHeader['CRPIX2'], crpix3
        ]
        w.wcs.cdelt = np.array(
            [templateHeader['CDELT1'], templateHeader['CDELT2'], cdelt3])
        w.wcs.crval = [
            templateHeader['CRVAL1'], templateHeader['CRVAL2'], crval3
        ]
        w.wcs.ctype = [
            templateHeader['CTYPE1'], templateHeader['CTYPE2'], ctype3
        ]
        naxis2 = templateHeader['NAXIS2']
        naxis1 = templateHeader['NAXIS1']
        w.wcs.radesys = templateHeader['RADESYS']
        w.wcs.equinox = templateHeader['EQUINOX']
        pixPerBeam = np.abs(beamSize / w.pixel_scale_matrix[1, 1])
        if pixPerBeam < 3.5:
            warnings.warn('Template header requests {0}'.format(pixPerBeam) +
                          ' pixels per beam.')
        if (((w.wcs.ctype[0]).split('-'))[0] !=
            ((s[0]['CTYPE1']).split('-'))[0]):
            warnings.warn('Spectral data not in same frame as template header')
            eulerFlag = True

    outCube = np.zeros((int(naxis3), int(naxis2), int(naxis1)), dtype=dtype)
    outWts = np.zeros((int(naxis2), int(naxis1)), dtype=dtype)

    xmat, ymat = np.meshgrid(np.arange(naxis1),
                             np.arange(naxis2),
                             indexing='ij')
    xmat = xmat.reshape(xmat.size)
    ymat = ymat.reshape(ymat.size)
    xmat = xmat.astype(np.int)
    ymat = ymat.astype(np.int)

    ctr = 0

    for thisfile in filelist:
        ctr += 1
        s = fits.open(thisfile)
        if flagSpatialOutlier:
            # Remove outliers in Lat/Lon space
            f = np.where(is_outlier(s[1].data['CRVAL2'], thresh=1.5) != True)
            s[1].data = s[1].data[f]
            f = np.where(is_outlier(s[1].data['CRVAL3'], thresh=1.5) != True)
            s[1].data = s[1].data[f]
        print("Now processing {0}".format(thisfile))
        print("This is file {0} of {1}".format(ctr, len(filelist)))
        if len(s[1].data) == 0:
            warnings.warn("Corrupted file: {0}".format(thisfile))
            continue
        nuindex = np.arange(len(s[1].data['DATA'][0]))

        if not OnlineDoppler:
            vframe = VframeInterpolator(s[1].data)
        else:
            vframe = s[1].data['VFRAME']
        flagct = 0
        if eulerFlag:
            if 'GLON' in s[1].data['CTYPE2'][0]:
                inframe = 'galactic'
            elif 'RA' in s[1].data['CTYPE2'][0]:
                inframe = 'fk5'
            else:
                raise NotImplementedError
            if 'GLON' in w.wcs.ctype[0]:
                outframe = 'galactic'
            elif 'RA' in w.wcs.ctype[0]:
                outframe = 'fk5'
            else:
                raise NotImplementedError

            coords = SkyCoord(s[1].data['CRVAL2'],
                              s[1].data['CRVAL3'],
                              unit=(u.deg, u.deg),
                              frame=inframe)
            coords_xform = coords.transform_to(outframe)
            if outframe == 'fk5':
                longCoord = coords_xform.ra.deg
                latCoord = coords_xform.dec.deg
            elif outframe == 'galactic':
                longCoord = coords_xform.l.deg
                latCoord = coords_xform.b.deg
        else:
            longCoord = s[1].data['CRVAL2']
            latCoord = s[1].data['CRVAL3']

        if plotTimeSeries:
            vmin = np.nanpercentile(s[1].data['DATA'], 15)
            vmed = np.nanpercentile(s[1].data['DATA'], 50)
            vmax = np.nanpercentile(s[1].data['DATA'], 85)
            fig = plt.figure(figsize=(8.0, 6.5))
            ax = fig.add_subplot(111)
            im = ax.imshow(s[1].data['DATA'],
                           interpolation='nearest',
                           cmap='PuOr',
                           vmin=(4 * vmin - 3 * vmed),
                           vmax=4 * vmax - 3 * vmed)
            outscans = np.zeros_like(s[1].data['DATA'] + np.nan)
            ax.set_xlabel('Channel')
            ax.set_title((thisfile.split('/'))[-1])
            ax.set_ylabel('Scan')
            cb = fig.colorbar(im)
            cb.set_label('Intensity (K)')
            thisroot = (thisfile.split('/'))[-1]
            plt.savefig(outdir + '/' + plotsubdir + '/' +
                        thisroot.replace('fits', 'png'))
            plt.close()
            plt.clf()

        for idx, spectrum in enumerate(console.ProgressBar((s[1].data))):
            # Generate Baseline regions
            baselineIndex = np.concatenate(
                [nuindex[ss] for ss in baselineRegion])

            specData = spectrum['DATA']
            if gainDict:
                try:
                    feedwt = 1.0 / gainDict[(str(spectrum['FDNUM']).strip(),
                                             str(spectrum['PLNUM']).strip())]
                except KeyError:
                    continue
            else:
                feedwt = 1.0
            if spectrum['OBJECT'] == 'VANE' or spectrum['OBJECT'] == 'SKY':
                continue
            # baseline fit
            if blankSpike:
                jumps = (specData - np.roll(specData, -1))
                noise = mad1d(jumps) * 2**(-0.5)
                spikemask = (np.abs(jumps) < spikeThresh * noise)
                spikemask = spikemask * np.roll(spikemask, 1)
                specData[~spikemask] = 0.0

            if doBaseline & np.all(np.isfinite(specData)):
                specData = baselineSpectrum(specData,
                                            order=blorder,
                                            baselineIndex=baselineIndex)

            # This part takes the TOPOCENTRIC frequency that is at
            # CRPIX1 (i.e., CRVAL1) and calculates the what frequency
            # that would have in the LSRK frame with freqShiftValue.
            # This then compares to the desired frequency CRVAL3.

            DeltaNu = freqShiftValue(spectrum['CRVAL1'], -vframe[idx]) - crval3

            DeltaChan = DeltaNu / cdelt3
            specData = channelShift(specData, -DeltaChan)

            outslice = (specData)[startChannel:endChannel]
            spectrum_wt = np.isfinite(outslice).astype(np.float) * feedwt
            outslice = np.nan_to_num(outslice)
            xpoints, ypoints, zpoints = w.wcs_world2pix(
                longCoord[idx], latCoord[idx], spectrum['CRVAL1'], 0)
            tsys = spectrum['TSYS']

            if flagRMS:
                radiometer_rms = tsys / np.sqrt(
                    np.abs(spectrum['CDELT1']) * spectrum['EXPOSURE'])
                scan_rms = prefac * np.median(
                    np.abs(outslice[0:-2] - outslice[2:]))

                if scan_rms > rmsThresh * radiometer_rms:
                    tsys = 0  # Blank spectrum

            if flagRipple:
                scan_rms = prefac * np.median(
                    np.abs(outslice[0:-2] - outslice[2:]))
                ripple = prefac * sqrt2 * np.median(np.abs(outslice))

                if ripple > 2 * scan_rms:
                    tsys = 0  # Blank spectrum
            if tsys == 0:
                flagct += 1
            if (tsys > 10) and (xpoints > 0) and (xpoints < naxis1) \
                    and (ypoints > 0) and (ypoints < naxis2):
                if plotTimeSeries:
                    outscans[idx, startChannel:endChannel] = outslice
                pixelWeight, Index = gridFunction(xmat, ymat, xpoints, ypoints,
                                                  pixPerBeam)
                vector = np.outer(outslice * spectrum_wt,
                                  pixelWeight / tsys**2)
                wts = pixelWeight / tsys**2
                outCube[:, ymat[Index], xmat[Index]] += vector
                outWts[ymat[Index], xmat[Index]] += wts
        print("Percentage of flagged scans: {0:4.2f}".format(100 * flagct /
                                                             float(idx)))
        if plotTimeSeries:
            vmin = np.nanpercentile(outscans, 15)
            vmed = np.nanpercentile(outscans, 50)
            vmax = np.nanpercentile(outscans, 85)
            fig = plt.figure(figsize=(8.0, 6.5))
            ax = fig.add_subplot(111)
            im = ax.imshow(outscans,
                           interpolation='nearest',
                           cmap='PuOr',
                           vmin=(4 * vmin - 3 * vmed),
                           vmax=4 * vmax - 3 * vmed)
            outscans = np.zeros_like(s[1].data['DATA'] + np.nan)
            ax.set_xlabel('Channel')
            ax.set_title((thisfile.split('/'))[-1])
            ax.set_ylabel('Scan')
            cb = fig.colorbar(im)
            cb.set_label('Intensity (K)')
            thisroot = (thisfile.split('/'))[-1]
            plt.savefig(outdir + '/' + plotsubdir + '/' +
                        thisroot.replace('fits', 'flagged.png'))
            plt.close()
            plt.clf()

        # Temporarily do a file write for every batch of scans.
        outWtsTemp = np.copy(outWts)
        outWtsTemp.shape = (1, ) + outWtsTemp.shape
        outCubeTemp = np.copy(outCube)
        outCubeTemp /= outWtsTemp
        hdr = fits.Header(w.to_header())

        hdr = addHeader_nonStd(hdr, beamSize, s[1].data)
        #
        hdu = fits.PrimaryHDU(outCubeTemp, header=hdr)
        hdu.writeto(outdir + '/' + outname + '.fits', overwrite=True)

    outWts.shape = (1, ) + outWts.shape
    outCube /= outWts

    # Create basic fits header from WCS structure
    hdr = fits.Header(w.to_header())
    # Add non standard fits keyword
    hdr = addHeader_nonStd(hdr, beamSize, s[1].data[0])
    # Adds history message
    # try:
    #    hdr.add_history(history_message)
    # except UnboundLocalError:
    #    pass
    hdr.add_history('Using GBTPIPE gridder version {0}'.format(__version__))
    hdu = fits.PrimaryHDU(outCube, header=hdr)
    hdu.writeto(outdir + '/' + outname + '.fits', overwrite=True)

    w2 = w.dropaxis(2)
    hdr2 = fits.Header(w2.to_header())
    hdu2 = fits.PrimaryHDU(outWts, header=hdr2)
    hdu2.writeto(outdir + '/' + outname + '_wts.fits', overwrite=True)

    if rebase:
        if rebaseorder is None:
            rebaseorder = blorder
        if 'NH3_11' in outname:
            Baseline.rebaseline(outdir + '/' + outname + '.fits',
                                windowFunction=Baseline.ammoniaWindow,
                                line='oneone',
                                blorder=rebaseorder,
                                **kwargs)

        elif 'NH3_22' in outname:
            Baseline.rebaseline(outdir + '/' + outname + '.fits',
                                windowFunction=Baseline.ammoniaWindow,
                                line='twotwo',
                                blorder=rebaseorder,
                                **kwargs)

        elif 'NH3_33' in outname:
            Baseline.rebaseline(outdir + '/' + outname + '.fits',
                                winfunc=Baseline.ammoniaWindow,
                                blorder=rebaseorder,
                                line='threethree',
                                **kwargs)
        else:
            Baseline.rebaseline(outdir + '/' + outname + '.fits',
                                blorder=rebaseorder,
                                windowFunction=Baseline.tightWindow,
                                **kwargs)
示例#11
0
def cygriddata(filelist,
               cacheSpectra=False,
               pixPerBeam=3.5,
               templateHeader=None,
               gridFunction=gg.jincGrid,
               startChannel=1024,
               endChannel=3072,
               doBaseline=True,
               baselineRegion=None,
               blorder=1,
               rebase=None,
               rebaseorder=None,
               beamSize=None,
               OnlineDoppler=True,
               flagRMS=False,
               flagRipple=False,
               flagSpike=False,
               rmsThresh=1.25,
               spikeThresh=10,
               projection='TAN',
               outdir=None,
               outname=None,
               dtype='float64',
               **kwargs):
    """Gridding code for GBT spectral scan data produced by pipeline using CyGrid
    
    Parameters
    ----------
    filelist : list
        List of FITS files to be gridded into an output

    Keywords
    --------
    pixPerBeam : float
        Number of pixels per beam FWHM

    templateHeader : `Header` object
        Template header used for spatial pixel grid.

    gridFunction : function 
        Gridding function to be used.  The default `jincGrid` is a
        tapered circular Bessel function.  The function has call
        signature of func(xPixelCentre, yPixelCenter, xData, yData,
        pixPerBeam)

    startChannel : int
        Starting channel for spectrum within the original spectral data.

    endChannel : int
        End channel for spectrum within the original spectral data

    doBaseline : bool
        Setting to True (default) performs per-scan baseline corrections.

    baselineRegion : `numpy.slice` or list of `numpy.slice`
        Regions in the original pixel data used for fitting the baseline.

    blorder : int
        Order of baseline.  Defaults to 1 (linear)

    rebase : bool
        Setting to True (default is False) performs per-pixel
        rebaselining of the resulting cube.

    beamSize : float
        Telescope beam size at this frequency measured in degrees.

    OnlineDopper : bool
        Setting to True (default) assumes that the Doppler corrections
        in the data are corrected during a telescope scan.  Setting to
        False assumes that the Doppler correction is updated at the
        end of a scan and linearly interpolates between scan ends.
        
    flagRMS : bool
        Setting to True (default = False) flags spectra with rms
        values >rmsThresh x higher than prediction from the radiometer
        formula.  This rms determination assumes that channels are not
        strongly correlated

    rmsThresh : float
        Threshold for scan flagging based on rms.  Default = 1.5

    flagRipple : bool
        Setting to True (default = False) flags spectra with structure
        in the line that is 2x higher than the rms prediction of the
        radiometer formula.  Note that these estimators are outlier
        robust.

    flagSpike : bool
        Setting to True (default = False) flags regions in spectra 
        that show jumps of > 5 times the typical pixel to pixel fluctuation.

    outdir : str
        Output directory name.  Defaults to current working directory.

    outname : str
        Output directory file name.  Defaults to object name in the
        original spectra.

    Returns
    -------
    None

    """

    if outdir is None:
        outdir = os.getcwd()

    if baselineRegion is None:
        baselineRegion = [slice(1024, 1536, 1), slice(2560, 3072, 1)]

    if len(filelist) == 0:
        warnings.warn('There are no FITS files to process ')
        return
    # check that every file in the filelist is valid
    # If not then remove it and send warning message
    for file_i in filelist:
        try:
            fits.open(file_i)
        except:
            warnings.warn('file {0} is corrupted'.format(file_i))
            filelist.remove(file_i)

    # pull a test structure
    hdulist = fits.open(filelist[0])
    s = hdulist[1].data

    # Constants block
    sqrt2 = np.sqrt(2)
    mad2rms = 1.4826
    prefac = mad2rms / sqrt2
    c = 299792458.

    nu0 = s[0]['RESTFREQ']
    Data_Unit = s[0]['TUNIT7']

    if outname is None:
        outname = s[0]['OBJECT']

    # New Beam size measurements use 1.18 vs. 1.22 based on GBT Memo 296.

    if beamSize is None:
        beamSize = 1.18 * (c / nu0 / 100.0) * 180 / np.pi  # in degrees
    naxis3 = len(s[0]['DATA'][startChannel:endChannel])

    # Default behavior is to park the object velocity at
    # the center channel in the VRAD-LSR frame

    crval3 = s[0]['RESTFREQ'] * (1 - s[0]['VELOCITY'] / c)
    crpix3 = s[0]['CRPIX1'] - startChannel
    ctype3 = s[0]['CTYPE1']
    cdelt3 = s[0]['CDELT1']

    w = wcs.WCS(naxis=3)

    w.wcs.restfrq = nu0
    # We are forcing this conversion to make nice cubes.
    w.wcs.specsys = 'LSRK'
    w.wcs.ssysobs = 'TOPOCENT'

    if templateHeader is None:
        wcsdict = gg.autoHeader(filelist,
                                beamSize=beamSize,
                                pixPerBeam=pixPerBeam,
                                projection=projection)
        w.wcs.crpix = [wcsdict['CRPIX1'], wcsdict['CRPIX2'], crpix3]
        w.wcs.cdelt = np.array([wcsdict['CDELT1'], wcsdict['CDELT2'], cdelt3])
        w.wcs.crval = [wcsdict['CRVAL1'], wcsdict['CRVAL2'], crval3]
        w.wcs.ctype = [wcsdict['CTYPE1'], wcsdict['CTYPE2'], ctype3]
        naxis2 = wcsdict['NAXIS2']
        naxis1 = wcsdict['NAXIS1']
        w.wcs.radesys = s[0]['RADESYS']
        w.wcs.equinox = s[0]['EQUINOX']

    else:
        w.wcs.crpix = [
            templateHeader['CRPIX1'], templateHeader['CRPIX2'], crpix3
        ]
        w.wcs.cdelt = np.array(
            [templateHeader['CDELT1'], templateHeader['CDELT2'], cdelt3])
        w.wcs.crval = [
            templateHeader['CRVAL1'], templateHeader['CRVAL2'], crval3
        ]
        w.wcs.ctype = [
            templateHeader['CTYPE1'], templateHeader['CTYPE2'], ctype3
        ]
        naxis2 = templateHeader['NAXIS2']
        naxis1 = templateHeader['NAXIS1']
        w.wcs.radesys = templateHeader['RADESYS']
        w.wcs.equinox = templateHeader['EQUINOX']
        pixPerBeam = np.abs(beamSize / w.pixel_scale_matrix[1, 1])
        if pixPerBeam < 3.5:
            warnings.warn('Template header requests {0}'.format(pixPerBeam) +
                          ' pixels per beam.')
        if (((w.wcs.ctype[0]).split('-'))[0] !=
            ((s[0]['CTYPE1']).split('-'))[0]):
            warnings.warn('Spectral data not in same frame as template header')
            eulerFlag = True

#    outCube = np.zeros((int(naxis3), int(naxis2), int(naxis1)),dtype=dtype)
#   outWts = np.zeros((int(naxis2), int(naxis1)),dtype=dtype)

    xmat, ymat = np.meshgrid(np.arange(naxis1),
                             np.arange(naxis2),
                             indexing='ij')
    xmat = xmat.reshape(xmat.size)
    ymat = ymat.reshape(ymat.size)
    xmat = xmat.astype(np.int)
    ymat = ymat.astype(np.int)

    ctr = 0

    speclist = []
    lonlist = []
    latlist = []
    for thisfile in filelist:
        ctr += 1
        cachefile = thisfile.replace('.fits', '_speccache.npz')
        if cacheSpectra and os.path.isfile(cachefile):
            npzfile = np.load(cachefile)
            speclist += npzfile['speclist'].tolist()
            lonlist += npzfile['lonlist'].tolist()
            latlist += npzfile['latlist'].tolist()
        else:
            s = fits.open(thisfile)
            print("Now processing {0}".format(thisfile))
            print("This is file {0} of {1}".format(ctr, len(filelist)))

            nuindex = np.arange(len(s[1].data['DATA'][0]))

            if not OnlineDoppler:
                vframe = gg.VframeInterpolator(s[1].data)
            else:
                vframe = s[1].data['VFRAME']
            flagct = 0
            if eulerFlag:
                if 'GLON' in s[1].data['CTYPE2'][0]:
                    inframe = 'galactic'
                elif 'RA' in s[1].data['CTYPE2'][0]:
                    inframe = 'fk5'
                else:
                    raise NotImplementedError
                if 'GLON' in w.wcs.ctype[0]:
                    outframe = 'galactic'
                elif 'RA' in w.wcs.ctype[0]:
                    outframe = 'fk5'
                else:
                    raise NotImplementedError

                coords = SkyCoord(s[1].data['CRVAL2'],
                                  s[1].data['CRVAL3'],
                                  unit=(u.deg, u.deg),
                                  frame=inframe)
                coords_xform = coords.transform_to(outframe)
                if outframe == 'fk5':
                    longCoord = coords_xform.ra.deg
                    latCoord = coords_xform.dec.deg
                elif outframe == 'galactic':
                    longCoord = coords_xform.l.deg
                    latCoord = coords_xform.b.deg
            else:
                longCoord = s[1].data['CRVAL2'],
                latCoord = s[1].data['CRVAL3']
            lonlist += [longCoord]
            latlist += [latCoord]

            for idx, spectrum in enumerate(console.ProgressBar((s[1].data))):
                # Generate Baseline regions
                baselineIndex = np.concatenate(
                    [nuindex[ss] for ss in baselineRegion])

                specData = spectrum['DATA']

                # baseline fit
                if doBaseline & np.all(np.isfinite(specData)):
                    specData = gg.baselineSpectrum(specData,
                                                   order=blorder,
                                                   baselineIndex=baselineIndex)

                # This part takes the TOPOCENTRIC frequency that is at
                # CRPIX1 (i.e., CRVAL1) and calculates the what frequency
                # that would have in the LSRK frame with freqShiftValue.
                # This then compares to the desired frequency CRVAL3.

                DeltaNu = gg.freqShiftValue(spectrum['CRVAL1'],
                                            -vframe[idx]) - crval3
                DeltaChan = DeltaNu / cdelt3
                specData = gg.channelShift(specData, -DeltaChan)
                outslice = (specData)[startChannel:endChannel]
                spectrum_wt = np.isfinite(outslice).astype(np.float)
                outslice = np.nan_to_num(outslice)
                # xpoints, ypoints, zpoints = w.wcs_world2pix(longCoord[idx],
                #                                             latCoord[idx],
                #                                             spectrum['CRVAL1'], 0)
                tsys = spectrum['TSYS']

                if flagSpike:
                    jumps = (outslice - np.roll(outslice, -1))
                    noise = gg.mad1d(jumps) * 2**(-0.5)
                    spikemask = (np.abs(jumps) < spikeThresh * noise)
                    spikemask = spikemask * np.roll(spikemask, 1)
                    spectrum_wt *= spikemask
                if flagRMS:
                    radiometer_rms = tsys / np.sqrt(
                        np.abs(spectrum['CDELT1']) * spectrum['EXPOSURE'])
                    scan_rms = prefac * np.median(
                        np.abs(outslice[0:-2] - outslice[2:]))

                    if scan_rms > rmsThresh * radiometer_rms:
                        tsys = 0  # Blank spectrum

                if flagRipple:
                    scan_rms = prefac * np.median(
                        np.abs(outslice[0:-2] - outslice[2:]))
                    ripple = prefac * sqrt2 * np.median(np.abs(outslice))

                    if ripple > 2 * scan_rms:
                        tsys = 0  # Blank spectrum
                if tsys == 0:
                    flagct += 1
                speclist += [outslice]
                # if (tsys > 10) and (xpoints > 0) and (xpoints < naxis1) \
                #         and (ypoints > 0) and (ypoints < naxis2):
                #     pixelWeight, Index = gridFunction(xmat, ymat,
                #                                       xpoints, ypoints,
                #                                       pixPerBeam)
                #     vector = np.outer(outslice * spectrum_wt,
                #                       pixelWeight / tsys**2)
                #     wts = pixelWeight / tsys**2
                #     outCube[:, ymat[Index], xmat[Index]] += vector
                #     outWts[ymat[Index], xmat[Index]] += wts
            print("Percentage of flagged scans: {0:4.2f}".format(100 * flagct /
                                                                 float(idx)))
            # Temporarily do a file write for every batch of scans.
            if cacheSpectra:
                np.savez(thisfile.replace('.fits', '_speccache.npz'),
                         lonlist=lonlist,
                         latlist=latlist,
                         speclist=speclist)
    try:
        lonlist = np.squeeze(np.stack(lonlist))
        latlist = np.squeeze(np.stack(latlist))
        speclist = np.squeeze(np.stack(speclist))
    except ValueError:
        lonlist = np.squeeze(np.hstack(lonlist))
        latlist = np.squeeze(np.hstack(latlist))
        speclist = np.squeeze(np.stack(speclist))
    # DO THE GRIDDING
    hdr = w.to_header()
    hdr['NAXIS1'] = naxis1
    hdr['NAXIS2'] = naxis2
    hdr['NAXIS3'] = 10

    gridder = cygrid.WcsGrid(hdr)
    gridder.set_kernel('gauss1d', (beamSize / 2.355 / 2),
                       2 * (beamSize / 2.355), beamSize / 2 / 2.355)
    gridder.grid(lonlist, latlist, speclist, dtype=dtype)
    hdr = fits.Header(w.to_header())
    s = fits.open(thisfile)
    hdr = gg.addHeader_nonStd(hdr, beamSize, s[1].data[0])
    hdr.add_history('Using GBTPIPE gridder version {0}'.format(__version__))

    hdu = fits.PrimaryHDU(gridder.get_datacube(), header=hdr)
    hdu.writeto(outdir + '/' + outname + '.fits', clobber=True)

    # outWts.shape = (1,) + outWts.shape
    # outCube /= outWts

    # hdu = fits.PrimaryHDU(outCube, header=hdr)

    # w2 = w.dropaxis(2)
    # hdr2 = fits.Header(w2.to_header())
    # hdu2 = fits.PrimaryHDU(outWts, header=hdr2)
    # hdu2.writeto(outdir + '/' + outname + '_wts.fits', clobber=True)

    if rebase:
        if rebaseorder is None:
            rebaseorder = blorder
        if 'NH3_11' in outname:
            Baseline.rebaseline(outdir + '/' + outname + '.fits',
                                windowFunction=Baseline.ammoniaWindow,
                                line='oneone',
                                blorder=rebaseorder,
                                **kwargs)

        elif 'NH3_22' in outname:
            Baseline.rebaseline(outdir + '/' + outname + '.fits',
                                windowFunction=Baseline.ammoniaWindow,
                                line='twotwo',
                                blorder=rebaseorder,
                                **kwargs)

        elif 'NH3_33' in outname:
            Baseline.rebaseline(outdir + '/' + outname + '.fits',
                                winfunc=Baseline.ammoniaWindow,
                                blorder=rebaseorder,
                                line='threethree',
                                **kwargs)
        else:
            Baseline.rebaseline(outdir + '/' + outname + '.fits',
                                blorder=rebaseorder,
                                windowFunction=Baseline.tightWindow,
                                **kwargs)
示例#12
0
def residual_cube(cubename, fitfile=None, 
                  expand=20, writemodel=False, fileprefix=None,
                  filesuffix=None,
                  writeresidual=False, writechisq=True):
    """This function generates products for evaluating the goodness of
    fit for a cold_ammonia model.  Either a parameter cube name must
    be passed or the prefix/suffixes of the files.

    Parameters
    ----------

    cubename : str
        Name of the original data file
    
    Keywords
    --------
    fitfile : str
        Name of the parameter file produced by the cube fitter
    fileprefix : str
        Prefix of file name before the parameter name (e.g., for
        L1688_N_NH3_DR1_rebase3_flag.fits, this would be 'L1688_').
    filesufffix : str
        Prefix of file name before the parameter name (e.g., for
        L1688_N_NH3_DR1_rebase3_flag.fits, this would be
        '_DR1_rebase3_flag').
    expand : int
        Expands the region where the residual is evaluated by this
        many channels in the spectral dimension
    writemodel : bool
        Setting to True writes out a model cube of the ammonia fit
    writeresidual : bool
        Setting to True writes out a residual cube
    writechisq : bool
        Setting to True writes out a map of the reduced chi-squared
        goodness of fit.

    Returns
    -------
        None
    """
    try:
        if fitfile is None:
            tkin = fits.getdata(fileprefix + 'Tkin' + filesuffix + '.fits')
            tex = fits.getdata(fileprefix + 'Tex' + filesuffix + '.fits')
            sigma = fits.getdata(fileprefix + 'Sigma' + filesuffix + '.fits')
            column = fits.getdata(fileprefix + 'N_NH3' + filesuffix + '.fits')
            v0 = fits.getdata(fileprefix + 'Vlsr' + filesuffix + '.fits')
            fortho = np.zeros_like(v0)
        else:
            hdu = fits.open(fitfile)
            fitparams = hdu[0].data
            tkin = fitparams[0, :, :]
            tex = fitparams[1, :, :]
            column = fitparams[2, :, :]
            sigma = fitparams[3, :, :]
            v0 = fitparams[4, :, :]
            fortho = fitparams[5, :,:]
    except NameError:
        warnings.warn("Either fitfile or fileprefix/filesuffix"+
                      " must be specified")

    cube = SpectralCube.read(cubename)
    cube  = cube.with_spectral_unit(u.km/u.s,velocity_convention='radio')
    model = np.zeros(cube.shape)

    yy, xx = np.where(column>0)
    cube = cube.with_spectral_unit(u.Hz)
    spaxis = pyspeckit.spectrum.units.SpectroscopicAxis(cube.spectral_axis)
    for y, x in console.ProgressBar(zip(yy,xx)):
        fit = ammonia.cold_ammonia(spaxis, tkin[y, x], tex=tex[y, x], 
                                   ntot=column[y, x], width=sigma[y, x],
                                   xoff_v=v0[y, x], fortho=fortho[y, x])
        model[:, y, x] = fit

    mask = model > 0
    residual = cube.filled_data[:].value-model

    # This calculates chisq over the region where the fit is non-zero
    # plus a buffer of size set by the expand keyword.

    selem = np.ones(expand,dtype=np.bool)
    selem.shape += (1,1,)
    mask = nd.binary_dilation(mask, selem)
    mask = mask.astype(np.float)
    chisq = np.sum((residual * mask)**2, axis=0) / np.sum(mask, axis=0)

    # This produces a robust estimate of the RMS along every line of sight:
    diff = residual - np.roll(residual, 2, axis=0)
    rms = 1.4826 * np.nanmedian(np.abs(diff), axis=0) / 2**0.5

    chisq /= rms**2

    root = (cubename.split('.'))[0]
    if writechisq:
        hdu = fits.PrimaryHDU(chisq, cube.wcs.celestial.to_header())
        hdu.writeto(root+'_chisq.fits', clobber=True)
    if writeresidual:
        newcube = SpectralCube(residual,cube.wcs,header=cube.header)
        newcube.write(root+'_residual.fits', overwrite=True)
    if writemodel:
        model = SpectralCube(model, cube.wcs, header=cube.header)
        model.write(root + '_model.fits', overwrite=True)