Esempio n. 1
0
def low_res_mode(cube, head, wavels):
    '''Function to convolve spectral dimension of cube for low resolution, R~500
    mode of HARMONI, covering wavelength range of 0.8-2.45 um.
    Because low resolution mode has variable resolution, convolution is performed
    in pixel space and cube is returned in pixel space.

    Inputs:

        cube: datacube
        head: datacube header
        wavels: wavelength array [um]

    Outputs:
        scaled_cube: rebinned datacube
        head: updated header file
        new_wavels: new wavelength array for datacube [um]
        delta_lambda: New resolution [um]
        lamb_per_pix: pixel dispersion [um/pixel]
        outR: output Resolving power
    '''

    # - Load pixel wavelength resolution data
    # - Calculate pixel wavelength bins according to input cube resolution and resolution data
    # - cut datacube down in wavelength range if larger than full low res range
    # - if cube shorter than full low res range, process the full wavelength range of cube
    # - bin spectrum up in pixel space
    # - 10x hypersample and convolve with Gaussian LSF in pixel space
    # - resample back to normal sampling in pixel space
    # - Return cube in pixel space, along with header, (irregular) wavelength array, (irregular) delta_lambda array, and
    #(irregular) pixel dispersion array which will be half of each delta_lambda value
    # - output cube, updated header, new wavels, delta_lambda (NEED TO CHECK HOW TO RETURN THIS AS THIS IS USED BY BACKGROUND FUNCTION), lamb_per_pix

    #Load data
    #dat = n.genfromtxt(r500_path+'HARMONI_R500_mode_data.txt', delimiter=',')
    dat = n.genfromtxt(os.path.join(r500_path, 'HARMONI_R500_mode_data.txt'),
                       delimiter=',')
    dellam = dat[:, 0] / dat[:, 1]

    #Ignore spectral dimension if input cube is coarser spectral resolution than output
    if head['SPECRES'] > dat[:, 2].any():
        print 'Input spectral resolution coarser than output.'
        print 'Ignoring spectral dimension.'
        return cube, head, wavels, head['SPECRES'], head['CDELT3']
    else:
        convres = n.sqrt(dat[:, 2]**2 - head['SPECRES']**2)

    outputres = si.interp1d(dat[:, 0], dat[:, 2])
    rinterp = si.interp1d(dat[:, 0], convres)

    #Create new finely sampled wavelength array (0.8-2.46 um) for pixel summation
    newlam = n.arange(0.8, 2.46, dat[0, 2] / 100.)
    newres = rinterp(newlam)
    newrs = newlam / newres
    rpower = si.interp1d(newlam, newrs)
    dlam = si.interp1d(newlam, newres)

    lams = []
    dlams = []

    lam = newlam[0]
    dl = dlam(lam)
    lams.append(lam)
    dlams.append(dl)
    try:
        for i in xrange(2000):
            lam = nr(lam, lam + dl / 2., rpower(lam + dl / 2.))
            lams.append(lam)
            dlams.append(dlam(lam))
            dl = dlam(lam)
    except ValueError:
        print 'Pixel wavelength values determined'

    lams = n.array(lams)
    dlams = n.array(dlams)

    #Find relationship between wavelength and pixel no.
    wavetopix = n.column_stack((range(len(lams)), lams))
    wtpinterp = si.interp1d(wavetopix[:, 0], wavetopix[:, 1])
    #Nyquist sample pixels (2 pixels per lambda)
    nyqpix = n.linspace(wavetopix[0, 0], wavetopix[-1, 0],
                        2 * len(wavetopix[:, 0]))
    wavetonyqpix = n.column_stack((nyqpix, wtpinterp(nyqpix)))
    wtnpinterp = si.interp1d(wavetonyqpix[:, 0], wavetonyqpix[:, 1])

    #Put datacube flux into photon units
    if head['FUNITS'] == 'erg/s/cm2/A/arcsec2' or head[
            'FUNITS'] == 'J/s/m2/A/arcsec2':
        cube *= (head['CDELT3'] * 10000.)
    else:
        cube *= head['CDELT3']

    #Interpolate datacube onto regular pixel grid (irregular wavelength grid) with 10x hypersampling
    if wavels[0] < wavetonyqpix[0, 1] and wavels[-1] > wavetonyqpix[
            -1, 1]:  #cube wavelength range larger than low res mode
        print 'Cube wavelength range larger than low res mode'
        start = 0
        end = -1
        incube_interp = si.interp1d(wavels, cube, axis=0)
        hpix = n.linspace(wavetonyqpix[0, 0], wavetonyqpix[-1, 0],
                          len(wavetonyqpix) * 10.)
    elif wavels[0] > wavetonyqpix[0, 1] and wavels[-1] < wavetonyqpix[
            -1, 1]:  #cube wavelength range inside low res mode
        print 'Cube wavelength range inside low res mode range'
        incube_interp = si.interp1d(wavels, cube, axis=0)
        start = n.where(wavetonyqpix[:, 1] > wavels[0])[0][0]
        end = n.where(wavetonyqpix[:, 1] > wavels[-1])[0][0] - 1
        hpix = n.linspace(wavetonyqpix[start, 0], wavetonyqpix[end, 0],
                          len(wavetonyqpix[start:end, 0]) * 10.)
    elif wavels[0] > wavetonyqpix[
            0,
            1]:  #cube short wavelength longer than low res mode shortest wavelength
        print 'Cube shortest wavelength larger than low res mode'
        incube_interp = si.interp1d(wavels, cube, axis=0)
        start = n.where(wavetonyqpix[:, 1] > wavels[0])[0][0]
        end = -1
        hpix = n.linspace(wavetonyqpix[start, 0], wavetonyqpix[-1, 0],
                          len(wavetonyqpix[start:, 0]) * 10.)
    elif wavels[-1] < wavetonyqpix[
            -1,
            1]:  #cube longest wavelength shorter than low res mode longest wavelength
        print 'Cube longest wavelength shorter than low res mode'
        incube_interp = si.interp1d(wavels, cube, axis=0)
        start = 0
        end = n.where(wavetonyqpix[:, 1] > wavels[-1])[0][0] - 1
        hpix = n.linspace(wavetonyqpix[0, 0], wavetonyqpix[end, 0],
                          len(wavetonyqpix[:end, 0]) * 10.)
    else:
        raise ValueError('Wavelength error!!!')

    hpixlams = wtnpinterp(hpix)
    hpixcube = incube_interp(hpixlams)

    #Convolve with Gaussian of 2 pix FWHM (hypersampled to 20 hpix FWHM)
    #hgauss = lr_Gauss(2/float(2.*n.sqrt(2.*n.log(2))), 0.1, pix_space=True)
    hgauss = Gauss(2 / float(2. * n.sqrt(2. * n.log(2))), 0.1)
    convcube = convolve1d(hpixcube, hgauss[:, 1], axis=0)

    #Resample back onto normal pixel grid
    hconvcube_interp = si.interp1d(hpix, convcube, axis=0)
    convcube = hconvcube_interp(wavetonyqpix[start:end, 0])

    #final cube
    final_cube = convcube

    #Ensure flux conservation (simplified method)
    print 'Input cube sum = ', n.sum(hpixcube) * n.diff(hpix)[0]
    target = n.sum(hpixcube) * n.diff(hpix)[0]
    current = n.sum(final_cube) * n.diff(wavetonyqpix[start:end, 0])[0]
    fac = current / target
    final_cube = n.divide(final_cube, fac)
    print 'Output cube sum = ', n.sum(final_cube) * n.diff(
        wavetonyqpix[start:end, 0])[0]

    #Output wavelength values
    final_lams = wavetonyqpix[start:end, 1]

    #Output spectral sampling
    out_samp = outputres(final_lams) / 2.
    out_samp.shape = (len(out_samp), 1, 1)

    #Put datacube flux back into photons/wavelength units
    if head['FUNITS'] == 'erg/s/cm2/A/arcsec2' or head[
            'FUNITS'] == 'J/s/m2/A/arcsec2':
        final_cube /= (out_samp * 10000.)
    else:
        final_cube /= out_samp

    #Update header
    head.update('CTYPE3', 'NL WAVELENGTH', 'Non-linear wavelength')
    head.update('CRVAL3', final_lams[0])
    head.update('NAXIS3', len(final_lams))
    del head['CDELT3']

    outR = 500
    #Return final cube, updated header, new wavelengths, column_stack of (pixel no. & pixel wavelength values), lambda_per_pixel_array
    return final_cube, head, final_lams, wavetonyqpix[
        start:end, :], out_samp, outR
Esempio n. 2
0
def spectral_res(datacube,
                 head,
                 grating,
                 wavels,
                 gratings,
                 spec_nyquist=True,
                 spec_samp=1.,
                 ignoreLSF=False):
    '''Function that takes input datacube and rebins it to the
    chosen spectral resolution. It convolves datacube along wavelength
    axis, interpolates all spaxels along wavelength axis then extracts
    pixel vales for each datacube wavelength channel. Function combines both
    spectral resolution choice and datacube chopping in wavelength axis.
    Option of bypassing spectral processing by setting band=='None' and
    spec_nyquist=True - this ignores wavelength dimension.

    Inputs:
        datacube: object datacube
        head: header file for object datacube
        grating: string representing chosen grating. Grating choice sets R and wavelength range
        wavels: wavelength array for datacube
        gratings: dictionary of grating parameters (lambda_min, lambda_max, R)
        spec_nyquist: Boolean - if True, 2 pixels per resolution element.
                              - if False, uses spec_samp value
        ignoreLSF: Boolean - ignore LSF convolution in spectral dimension

    Outputs:
        scaled_cube: rebinned datacube
        head: updated header file
        new_wavels: new wavelength array for datacube
        delta_lambda: New resolution [um]
        lamb_per_pix: pixel dispersion [um/pixel]
        resol: output R
    '''

    print 'Spectral resolution and wavelength range.'
    print 'Chosen grating: ', grating

    bandws = gratings[grating]

    z, y, x = datacube.shape

    if ignoreLSF == True:
        print 'Ignoring spectral dimension!'
        return datacube, head, wavels, head['SPECRES'], head['CDELT3'], 0
    if bandws == None and spec_nyquist == False:
        print 'Ignoring spectral dimension!'
        return datacube, head, wavels, head['SPECRES'], head['CDELT3'], 0
    elif bandws != None and spec_nyquist == True:
        #new_res = (bandws[0]+bandws[1])/(2.*bandws[2])
        new_res = bandws[2]
        lamb_per_pix = new_res / 2.
    elif bandws != None and spec_nyquist == False:
        #new_res = (bandws[0]+bandws[1])/(2.*bandws[2])
        new_res = bandws[2]
        lamb_per_pix = spec_samp / 10000.
    elif bandws == None and spec_nyquist == True:
        print 'Ignoring spectral dimension!'
        return datacube, head, wavels, head['SPECRES'], head['CDELT3'], 0
    else:
        print 'Ignoring spectral dimension!'
        return datacube, head, wavels, head['SPECRES'], head['CDELT3'], 0

    print 'Current resolution = %.5f microns' % head['SPECRES']
    print 'Current sampling = %.5f microns' % head['CDELT3']
    print 'New resolution = %.5f microns' % new_res
    print 'New sampling = %.5f microns' % lamb_per_pix

    if head['SPECRES'] >= new_res:
        print 'WARNING: Input spectral resolution is coarser (or equal) than chosen output!'
        #Chose whether to convolve with LSF or simply resample.
        condition = raw_input(
            'Do you want to convolve with Gaussian LSF of FWHM'
            ' given by band and chosen resolving power [y], or not [any other key]?: '
        )

        if condition == 'y':
            print 'Convolving with LSF'
            #Generate Gaussian LSF of FWHM = (bandws[0]+bandws[1])/(2.*R)
            sig = new_res / (2. * n.sqrt(2. * n.log(2.)))
            gauss_array = Gauss(sig, head['CDELT3'])
            #Convolve datacube array with Gaussian along wavelength axis
            datacube = convolve1d(datacube, gauss_array[:, 1], axis=0)

    else:
        print 'Input spectral resolution smaller than chosen output.'
        print 'Convolving with corresponding LSF.'
        #Generate Gaussian LSF of FWHM = sqrt(new_resolution**2-head['SPECRES']**2)
        sig = n.sqrt(new_res**2 -
                     head['SPECRES']**2) / (2. * n.sqrt(2. * n.log(2.)))
        gauss_array = Gauss(sig, head['CDELT3'])

        #Convolve datacube array with Gaussian along wavelength axis
        datacube = convolve1d(datacube, gauss_array[:, 1], axis=0)

##    #New wavelength values from chosen photometric band (or ignore)
##    if bandws:
##        new_wavels = n.arange(bandws[0], bandws[1], lamb_per_pix)
##        new_wavels[-1] = bandws[1]
##        #Slice datacube down to size of new wavelength array
##        start = n.where(wavels < new_wavels[0])[0][-1]
##        end = n.where(wavels > new_wavels[-1])[0][0]
##        datacube = datacube[start:end+1,:,:]
##    elif not bandws:
##        new_wavels = n.arange(wavels[0], wavels[-1], lamb_per_pix)
##        new_wavels[-1] = wavels[-1]

#####
#Interpolate datacube onto regular pixel grid (irregular wavelength grid) with 10x hypersampling
    if wavels[0] <= bandws[0] and wavels[-1] >= bandws[
            1]:  #cube wavelength range larger than grating choice
        print 'Cube wavelength range larger than grating: chopping down to grating range'

        new_wavels = n.arange(bandws[0], bandws[1] + lamb_per_pix / 2.,
                              lamb_per_pix)
        new_wavels[-1] = bandws[1]
        start = n.where(wavels <= new_wavels[0])[0][-1]
        end = n.where(wavels >= new_wavels[-1])[0][0]
        #datacube = datacube[start:end+1,:,:]

    elif wavels[0] > bandws[0] and wavels[-1] < bandws[
            1]:  #cube wavelength range inside grating choice
        print 'Cube wavelength range inside grating range'

        new_wavels = n.arange(wavels[0], wavels[-1] + lamb_per_pix / 2.,
                              lamb_per_pix)
        new_wavels[-1] = wavels[-1]
        start = n.where(bandws[0] < wavels)[0][0]
        end = n.where(bandws[1] > wavels)[0][-1]
        #datacube = datacube[start:end+1,:,:]

    elif wavels[0] > bandws[
            0]:  #cube short wavelength longer than grating shortest wavelength
        print 'Cube shortest wavelength larger than grating'

        new_wavels = n.arange(wavels[0], bandws[1] + lamb_per_pix / 2.,
                              lamb_per_pix)
        new_wavels[-1] = bandws[1]
        start = n.where(bandws[0] < wavels)[0][0]
        end = n.where(bandws[1] > wavels)[0][-1]
        #datacube = datacube[start:end+1,:,:]

    elif wavels[-1] < bandws[
            1]:  #cube longest wavelength shorter than grating longest wavelength
        print 'Cube longest wavelength shorter than grating'

        new_wavels = n.arange(bandws[0], wavels[-1] + lamb_per_pix / 2.,
                              lamb_per_pix)
        new_wavels[-1] = wavels[-1]
        start = n.where(bandws[0] < wavels)[0][0]
        end = n.where(bandws[1] > wavels)[0][-1]
        #datacube = datacube[start:end+1,:,:]

    else:
        raise ValueError('Specres wavelength error!!!')

    #####

    new_cube = n.zeros((len(new_wavels), y, x), dtype=float)

    ###New 30-05-14
    #Put datacube flux into photon units
    if head['FUNITS'] == 'erg/s/cm2/A/arcsec2' or head[
            'FUNITS'] == 'J/s/m2/A/arcsec2':
        datacube *= (head['CDELT3'] * 10000.)
    else:
        datacube *= head['CDELT3']

    #print 'Datacube sum = ', datacube.sum()

    #Bin up in spectral dimension to new pixel sampling
    #Iterate over x-axis and use frebin function on 2D y-z arrays
    for i in xrange(x):
        new_cube[:, :, i] = frebin(datacube[start:end + 1, :, i],
                                   (y, len(new_wavels)), True)

    #print 'New cube sum = ', new_cube.sum()

    #Put datacube flux back into photons/wavelength units
    if head['FUNITS'] == 'erg/s/cm2/A/arcsec2' or head[
            'FUNITS'] == 'J/s/m2/A/arcsec2':
        new_cube /= (lamb_per_pix * 10000.)
    else:
        new_cube /= lamb_per_pix

    #Update header
    head['CRVAL3'] = new_wavels[0]
    head['CDELT3'] = (new_wavels[1] - new_wavels[0])
    head['NAXIS3'] = len(new_wavels)
    head['SPECRES'] = new_res

    resol = n.round(new_wavels[len(new_wavels) / 2] / bandws[2], 0)

    print 'Spectral resolution and wavelength range - done!'

    #Return new_datacube, new_wavels, updated_header
    return new_cube, head, new_wavels, new_res, lamb_per_pix, resol
Esempio n. 3
0
def low_res_spec(spec, wavetopix, transmission_spec=False):
    '''Function to take input spectrum (e.g. Skycalc transmission or emission spectrum)
    and return as observed by HARMONI R=500 mode.

    Inputs:

        spec: column stacked spectrum  (wavelength [um], flux)
        wavetopix: Column stacked Nyquist sampling pixels and pixel wavelength values for R=500 mode
        transmission_spec: Boolean. If True, do not multiply then divide by spectral sampling as not required.

    Outputs:

        outspec: Output spectrum (wavelength [um], flux)

    '''

    #dat = n.genfromtxt(r500_path+'HARMONI_R500_mode_data.txt', delimiter=',')
    dat = n.genfromtxt(os.path.join(r500_path, 'HARMONI_R500_mode_data.txt'),
                       delimiter=',')
    outputres = si.interp1d(dat[:, 0], dat[:, 2])

    #Put spectrum flux into photon units (except if transmission spectrum)
    if not transmission_spec:
        specflux = spec[:, 1] * (spec[1, 0] - spec[0, 0])
    elif transmission_spec:
        specflux = spec[:, 1]

    #Find relationship between wavelength and pixel no.
    wtnpinterp = si.interp1d(wavetopix[:, 0], wavetopix[:, 1])

    #Interpolate spectrum onto regular pixel grid (irregular wavelength grid) with 10x hypersampling
    if spec[0, 0] < wavetopix[0, 1] and spec[-1, 0] > wavetopix[
            -1, 1]:  #cube wavelength range larger than low res mode
        inspec_interp = si.interp1d(spec[:, 0], specflux)
        #        start = 0
        #        end = -1
        hpix = n.linspace(wavetopix[0, 0], wavetopix[-1, 0],
                          len(wavetopix) * 10.)
    elif spec[0, 0] > wavetopix[0, 1] and spec[-1, 0] < wavetopix[
            -1, 1]:  #cube wavelength range inside low res mode
        inspec_interp = si.interp1d(spec[:, 0], specflux)
        start = n.where(wavetopix[:, 1] > spec[0, 0])[0][0]
        end = n.where(wavetopix[:, 1] > spec[-1, 0])[0][0]
        hpix = n.linspace(wavetopix[start, 0], wavetopix[end, 0],
                          len(wavetopix[start:end, 0]) * 10.)
    elif spec[0, 0] > wavetopix[
            0,
            1]:  #cube short wavelength longer than low res mode shortest wavelength
        inspec_interp = si.interp1d(spec[:, 0], specflux)
        start = n.where(wavetopix[:, 1] > spec[0, 0])[0][0]
        #        end = -1
        hpix = n.linspace(wavetopix[start, 0], wavetopix[-1, 0],
                          len(wavetopix[start:, 0]) * 10.)
    elif spec[-1, 0] < wavetopix[
            -1,
            1]:  #cube longest wavelength shorter than low res mode longest wavelength
        inspec_interp = si.interp1d(spec[:, 0], specflux)
        #        start = 0
        end = n.where(wavetopix[:, 1] > spec[-1, 0])[0][0]
        hpix = n.linspace(wavetopix[0, 0], wavetopix[end, 0],
                          len(wavetopix[:end, 0]) * 10.)
    else:
        raise ValueError('Wavelength error!!!')

##    inspec_interp = si.interp1d(spec[:,0], specflux)
##    hpix = n.linspace(wavetopix[0,0], wavetopix[-1,0], len(wavetopix)*10.)
    hpixlams = wtnpinterp(hpix)
    hpixspec = inspec_interp(hpixlams)

    #Convolve with Gaussian of 2 pix FWHM (hypersampled to 20 hpix FWHM)
    #hgauss = lr_Gauss(2/float(2.*n.sqrt(2.*n.log(2))), 0.1, pix_space=True)
    hgauss = Gauss(2 / float(2. * n.sqrt(2. * n.log(2))), 0.1)
    convspec = convolve1d(hpixspec, hgauss[:, 1])

    #Resample back onto normal pixel grid
    hconvspec_interp = si.interp1d(hpix, convspec)
    convspec = hconvspec_interp(wavetopix[:, 0])

    #final spectrum
    final_spec = n.column_stack((wavetopix[:, 1], convspec))
    #Output sampling
    out_samp = outputres(wavetopix[:, 1]) / 2.

    #Ensure flux conservation (simplified method)
    print 'Input spectrum sum = ', n.sum(hpixspec) * n.diff(hpix)[0]
    target = n.sum(hpixspec) * n.diff(hpix)[0]
    current = n.sum(final_spec[:, 1]) * n.diff(wavetopix[:, 0])[0]
    fac = current / target
    final_spec[:, 1] = n.divide(final_spec[:, 1], fac)
    print 'Output cube sum = ', n.sum(final_spec[:, 1]) * n.diff(
        wavetopix[:, 0])[0]

    #Put spectrum flux back into photons/wavelength units (except transmission spectrum)
    if not transmission_spec:
        final_spec[:, 1] /= out_samp

    #Return final spectrum
    return final_spec
Esempio n. 4
0
def spectral_res(datacube,
                 head,
                 R,
                 band,
                 wavels,
                 spec_nyquist=True,
                 spec_samp=1.):
    '''Function that takes input datacube and rebins it to the
    chosen spectral resolution. It convolves datacube along wavelength
    axis, interpolates all spaxels along wavelength axis then extracts
    pixel vales for each datacube wavelength channel. Function combines both
    spectral resolution choice and datacube chopping in wavelength axis.
    Option of bypassing spectral processing by setting band=='None' and
    spec_nyquist=True - this ignores wavelength dimension.

    Inputs:
        datacube: object datacube
        head: header file for object datacube
        R: spectral resolving power
        band: string representing wavelength band choice.
              Option of "None" which ignores photometric bands. 
        wavels: wavelength array for datacube
        spec_nyquist: Boolean - if True, 2 pixels per resolution element.
                              - if False, uses spec_samp value

    Outputs:
        scaled_cube: rebinned datacube
        head: updated header file
        new_wavels: new wavelength array for datacube
        delta_lambda: New resolution [um]
        lamb_per_pix: pixel dispersion [um/pixel]
    '''

    print 'Spectral resolution and wavelength range.'
    print 'Chosen resolution: ', R
    print 'Chosen band: ', band

    bands = {
        'V': (.47, .63),
        'R': (.63, .79),
        'Iz': (.82, 1.03),
        'J': (1.08, 1.36),
        'H': (1.46, 1.83),
        'K': (1.95, 2.45),
        'V+R': (.47, .81),
        'Iz+J': (.8, 1.36),
        'H+K': (1.45, 2.45),
        'V-high': (.53, .59),
        'R-high': (.61, .68),
        'z': (.82, .91),
        'J-high': (1.17, 1.29),
        'H-high': (1.545, 1.715),
        'K-high': (2.09, 2.32),
        'None': None
    }

    bandws = bands[band]

    z, y, x = datacube.shape

    if bandws == None and spec_nyquist == False:
        print 'Ignoring spectral dimension!'
        return datacube, head, wavels, head['SPECRES'], head['CDELT3']
    elif bandws != None and spec_nyquist == True:
        new_res = (bandws[0] + bandws[1]) / (2. * R)
        lamb_per_pix = new_res / 2.
    elif bandws != None and spec_nyquist == False:
        new_res = (bandws[0] + bandws[1]) / (2. * R)
        lamb_per_pix = spec_samp / 10000.
    elif bandws == None and spec_nyquist == True:
        #no convolution, just interpolate and read out new wavelengths
        #when sig=0, gauss returns [1.,1.] so convolution does nothing.
        #        new_res = head['SPECRES']
        new_res = (wavels[0] + wavels[-1]) / (2. * R)
        lamb_per_pix = new_res / 2.
    else:
        print 'Ignoring spectral dimension!'
        return datacube, head, wavels, head['SPECRES'], head['CDELT3']

    print 'Current resolution = %.5f microns' % head['SPECRES']
    print 'Current sampling = %.5f microns' % head['CDELT3']
    print 'New resolution = %.5f microns' % new_res
    print 'New sampling = %.5f microns' % lamb_per_pix

    if head['SPECRES'] >= new_res:
        print 'WARNING: Input spectral resolution is coarser (or equal) than chosen output!'
        #Chose whether to convolve with LSF or simply resample.
        condition = raw_input(
            'Do you want to convolve with Gaussian LSF of FWHM'
            ' given by band and chosen resolving power [y], or not [any other key]?: '
        )

        if condition == 'y':
            print 'Convolving with LSF'
            #Generate Gaussian LSF of FWHM = (bandws[0]+bandws[1])/(2.*R)
            sig = new_res / (2. * n.sqrt(2. * n.log(2.)))
            gauss_array = Gauss(sig, head['CDELT3'])
            #Convolve datacube array with Gaussian along wavelength axis
            datacube = convolve1d(datacube, gauss_array[:, 1], axis=0)

    else:
        print 'Input spectral resolution smaller than chosen output.'
        print 'Convolving with corresponding LSF.'
        #Generate Gaussian LSF of FWHM = sqrt(new_resolution**2-head['SPECRES']**2)
        sig = n.sqrt(new_res**2 -
                     head['SPECRES']**2) / (2. * n.sqrt(2. * n.log(2.)))
        gauss_array = Gauss(sig, head['CDELT3'])

        #Convolve datacube array with Gaussian along wavelength axis
        datacube = convolve1d(datacube, gauss_array[:, 1], axis=0)

    #New wavelength values from chosen photometric band (or ignore)
    if bandws:
        new_wavels = n.arange(bandws[0], bandws[1], lamb_per_pix)
        new_wavels[-1] = bandws[1]
        #Slice datacube down to size of new wavelength array
        start = n.where(wavels < new_wavels[0])[0][-1]
        end = n.where(wavels > new_wavels[-1])[0][0]
        datacube = datacube[start:end + 1, :, :]
    elif not bandws:
        new_wavels = n.arange(wavels[0], wavels[-1], lamb_per_pix)
        new_wavels[-1] = wavels[-1]

    new_cube = n.zeros((len(new_wavels), y, x), dtype=float)

    ###New 30-05-14
    #Put datacube flux into photon units
    if head['FUNITS'] == 'erg/s/cm2/A/arcsec2' or head[
            'FUNITS'] == 'J/s/m2/A/arcsec2':
        datacube *= (head['CDELT3'] * 10000.)
    else:
        datacube *= head['CDELT3']

    #print 'Datacube sum = ', datacube.sum()

    #Bin up in spectral dimension to new pixel sampling
    #Iterate over x-axis and use frebin function on 2D y-z arrays
    for i in xrange(x):
        new_cube[:, :, i] = frebin(datacube[:, :, i], (y, len(new_wavels)),
                                   True)

    #print 'New cube sum = ', new_cube.sum()

    #Put datacube flux back into photons/wavelength units
    if head['FUNITS'] == 'erg/s/cm2/A/arcsec2' or head[
            'FUNITS'] == 'J/s/m2/A/arcsec2':
        new_cube /= (lamb_per_pix * 10000.)
    else:
        new_cube /= lamb_per_pix

    #Update header
    head.update('CRVAL3', new_wavels[0])
    head.update('CDELT3', (new_wavels[1] - new_wavels[0]))
    head.update('NAXIS3', len(new_wavels))
    head.update('SPECRES', new_res)

    print 'Spectral resolution and wavelength range - done!'

    #Return new_datacube, new_wavels, updated_header
    return new_cube, head, new_wavels, new_res, lamb_per_pix