def __getAccessor__(self):
        """ This reads in the input unwrapped file from Snaphu and Connected Components """

        # Snaphu Unwrapped Phase
        inphase = IML.mmapFromISCE(self.inpFile, logging)
        if len(inphase.bands) == 1:
            self.inpAcc = inphase.bands[0]
        else:
            self.inpAcc = inphase.bands[1]

        # Connected Component
        inConnComp = IML.mmapFromISCE(self.ccFile, logging)
        if len(inConnComp.bands) == 1:
            # Gdal dependency for computing proximity
            self.__createGDALHDR__(inConnComp.name, inConnComp.width,
                                   inConnComp.length)
            self.cc_ds = gdal.Open(inConnComp.name, GA_ReadOnly)
            self.ccband = self.cc_ds.GetRasterBand(1)
            self.conncompAcc = self.ccband.ReadAsArray()
        else:
            raise Exception(
                "Connected Component Input File has 2 bands: Expected only one"
            )

        return
Example #2
0
    def __getAccessor__(self):
        """ This reads in the input unwrapped file from Snaphu and Connected Components """

        # Snaphu Unwrapped Phase
        inphase = IML.mmapFromISCE(self.inpFile, logging)
        if len(inphase.bands) == 1:
            self.inpAcc = inphase.bands[0]
            self.inpAmp = False  # D. Bekaert track if two-band file or not
        else:
            self.inpAcc = inphase.bands[1]
            self.inpAmp = True
            self.outFile_final = self.outFile
            self.outFile = self.outFile + "_temp"

        # Connected Component
        inConnComp = IML.mmapFromISCE(self.ccFile, logging)
        if len(inConnComp.bands) == 1:
            # --D. Bekaert
            # problem with using .hdr files see next item. Below is no longer needed
            # Gdal dependency for computing proximity
            # self.__createGDALHDR__(inConnComp.name, inConnComp.width, inConnComp.length)
            # --Done

            # --D. Bekaert - make sure gdal is using the vrt file to load the data.
            # i.e. gdal will default to envi headers first, for which the convention is filename.dat => filename.hdr.
            # for the connected component this load the wrong header: topophase.unw.conncomp => topophase.unw.hdr
            # force therefore to use the vrt file instead.
            inConnComp_filename, inConnComp_ext = os.path.splitext(
                inConnComp.name)
            # fix the file to be .vrt
            if inConnComp_ext != '.vrt':
                if inConnComp_ext != '.conncomp' and inConnComp_ext != '.geo':
                    inConnComp.name = inConnComp_filename + ".vrt"
                else:
                    inConnComp.name = inConnComp.name + ".vrt"
            if not os.path.isfile(inConnComp.name):
                raise Exception("Connected Component vrt file does not exist")
            print("GDAL using " + inConnComp.name)
            # --Done
            self.cc_ds = gdal.Open(inConnComp.name, GA_ReadOnly)
            self.ccband = self.cc_ds.GetRasterBand(1)
            self.conncompAcc = self.ccband.ReadAsArray()
        else:
            raise Exception(
                "Connected Component Input File has 2 bands: Expected only one"
            )

        return
Example #3
0
def makeOnePlot(filename, pos):
    '''
    Make plots.
    '''
    import matplotlib.pyplot as plt
    from imageMath import IML

    win = 100
    mm = IML.mmapFromISCE(filename, logging)
    data = mm.bands[0]

    nl, npix = data.shape

    pos = np.array(pos)

    miny = np.clip(np.min(pos[:,1])-win, 0 , nl-1)
    maxy = np.clip(np.max(pos[:,1])+win, 0 , nl-1)
    minx = np.clip(np.min(pos[:,2])-win, 0, npix-1)
    maxx = np.clip(np.max(pos[:,2])+win, 0, npix-1)

    box = np.power(np.abs(data[int(miny):int(maxy), int(minx):int(maxx)]), 0.4)

    plt.figure('CR analysis')

    plt.imshow(box, cmap=plt.cm.gray)
    plt.colorbar()
#    plt.scatter(pos[:,2]-minx, pos[:,1]-miny, marker='+', c='b', s=200)
    plt.scatter(pos[:,2]-minx, pos[:,1]-miny, marker='o',
            facecolors='none', edgecolors='b', s=100)
    plt.title(os.path.basename(os.path.dirname(filename)))
    plt.show()
Example #4
0
def makePlot(filename, pos):
    '''
    Make plots.
    '''
    import matplotlib.pyplot as plt
    from imageMath import IML

    win = 8
    mm = IML.mmapFromISCE(filename, logging)
    data = mm.bands[0]

    plt.figure('CR analysis')

    for index, (num, line, pixel) in enumerate(pos):
        print(line, pixel)
        xx = np.int(pixel)
        yy = np.int(line)
        box = 10 * np.log10(np.abs(data[yy-win:yy+win, yy-win:yy+win]))

        plt.subplot(7,3,index+1)

        plt.imshow(box, cmap=plt.cm.gray)
        plt.colorbar()
        plt.scatter(pixel-xx+win, line-yy+win, marker='+', c='b')

    plt.show()
Example #5
0
def isce2vrt(inname):
    '''
    Create VRT for ISCE product.
    '''
    img, dataname, metaname = IML.loadImage(inname)
    img.renderVRT()
    return
Example #6
0
def isce2envi(inname):
    '''
    Create ENVI hdr for ISCSE product.
    '''
    img, dataname, metaname = IML.loadImage(inname)
    img.renderEnviHDR()

    return
Example #7
0
def loadProduct(filename):
    '''
    Load the product using Product Manager.
    '''
    import isce
    import logging
    from imageMath import IML

    IMG = IML.mmapFromISCE(filename, logging)
    img = IMG.bands[0]
    #    pdb.set_trace()
    return img
Example #8
0
def changeXmlName(xmlFile, xmlFileNew):
    import os
    import isce
    import isceobj
    from imageMath import IML

    #currently, only sure about supporting SLC xml file
    xmlFileNew = xmlFileNew.rstrip('.xml')
    img, dataName, metaName = IML.loadImage(xmlFile)
    img.filename = xmlFileNew
    #img.setAccessMode('READ')
    os.remove(xmlFile)
    img.renderHdr()
Example #9
0
def genRawImg(rawFile, iBias, qBias, rangeStart):
    raw = IML.mmapFromISCE(rawFile, logging)
    cj = np.complex64(1j)
    rawImg = []
    for i in range(len(raw.bands[0])):
        line = raw.bands[0][i, rangeStart::2] + cj * raw.bands[0][
            i, rangeStart + 1::2] - iBias - cj * qBias
        rawImg.append(line)
    rawImg = np.array(rawImg)

    rfat = []
    for i in range(len(rawImg)):
        line = np.fft.fftshift(np.fft.fft(rawImg[i]) / len(rawImg[i]))
        rfat.append(line)
    rfat = np.array(rfat)

    return rfat
Example #10
0
def cropFrame(frame, limits, outname, israw=False):
    '''
    Crop the frame.

    Parameters to change:
    startingRange
    farRange
    sensingStart
    sensingStop
    sensingMid
    numberOfLines
    numberOfSamples
    dopplerVsPixel
    '''

    outframe = copy.deepcopy(frame)
    if not israw:
        img = isceobj.createImage()
        img.load(frame.image.filename + '.xml')
        outframe.image = img

    if israw:
        factor = 2
    else:
        factor = 1

    ####sensing start
    ymin = np.floor(
        (limits[0] - frame.sensingStart).total_seconds() * frame.PRF)
    print('Line start: ', ymin)
    ymin = np.int(np.clip(ymin, 0, frame.numberOfLines - 1))

    ####sensing stop
    ymax = np.ceil(
        (limits[1] - frame.sensingStart).total_seconds() * frame.PRF) + 1
    print('Line stop: ', ymax)
    ymax = np.int(np.clip(ymax, 1, frame.numberOfLines))

    print('Line limits: ', ymin, ymax)
    print('Original Line Limits: ', 0, frame.numberOfLines)

    if (ymax - ymin) <= 1:
        raise Exception('Azimuth limits appear to not overlap with the scene')

    outframe.sensingStart = frame.sensingStart + datetime.timedelta(
        seconds=ymin / frame.PRF)
    outframe.numberOfLines = ymax - ymin
    outframe.sensingStop = frame.sensingStop + datetime.timedelta(
        seconds=(ymax - 1) / frame.PRF)
    outframe.sensingMid = outframe.sensingStart + 0.5 * (outframe.sensingStop -
                                                         outframe.sensingStart)

    ####starting range
    xmin = np.floor(
        (limits[2] - frame.startingRange) / frame.instrument.rangePixelSize)
    print('Pixel start: ', xmin)
    xmin = np.int(np.clip(xmin, 0, (frame.image.width // factor) - 1))

    ####far range
    xmax = np.ceil((limits[3] - frame.startingRange) /
                   frame.instrument.rangePixelSize) + 1
    print('Pixel stop: ', xmax)

    xmax = np.int(np.clip(xmax, 1, frame.image.width // factor))

    print('Pixel limits: ', xmin, xmax)
    print('Original Pixel Limits: ', 0, frame.image.width // factor)

    if (xmax - xmin) <= 1:
        raise Exception('Range limits appear to not overlap with the scene')

    outframe.startingRange = frame.startingRange + xmin * frame.instrument.rangePixelSize
    outframe.numberOfSamples = (xmax - xmin) * factor
    outframe.setFarRange(frame.startingRange +
                         (xmax - xmin - 1) * frame.instrument.rangePixelSize)

    ####Adjust Doppler centroid coefficients
    coeff = frame._dopplerVsPixel
    rng = np.linspace(xmin, xmax, len(coeff) + 1)
    dops = np.polyval(coeff[::-1], rng)

    rng = rng - xmin  ###Adjust the start
    pol = np.polyfit(rng, dops, len(coeff) - 1)
    outframe._dopplerVsPixel = list(pol[::-1])

    ####Adjusting the image now
    ####Can potentially use israw to apply more logic but better to use new version
    if frame.image.xmin != 0:
        raise Exception(
            'Looks like you are still using an old version of ISCE. The new version completely strips out the header bytes. Please switch to the latest ...'
        )

    inname = frame.image.filename
    suffix = os.path.splitext(inname)[1]
    outdirname = os.path.dirname(outname)
    os.makedirs(outdirname, exist_ok=True)

    indata = IML.mmapFromISCE(inname, logging)
    indata.bands[0][ymin:ymax, xmin * factor:xmax * factor].tofile(outname)

    indata = None
    outframe.image.filename = outname
    outframe.image.width = outframe.numberOfSamples
    outframe.image.length = outframe.numberOfLines

    outframe.image.xmax = outframe.numberOfSamples
    outframe.image.coord1.coordSize = outframe.numberOfSamples
    outframe.image.coord1.coordEnd = outframe.numberOfSamples
    outframe.image.coord2.coordSize = outframe.numberOfLines
    outframe.image.coord2.coordEnd = outframe.numberOfLines

    outframe.image.renderHdr()

    return outframe
Example #11
0

if __name__ == '__main__':

    inps = cmdLineParse()

    print('################################################')
    print('Multilook Start!!!')
    print(time.strftime("%H:%M:%S"))

    nanval = 0.0

    # Read amp files in radar coordinates
    #    ampfile = "./interferogram/topophase.amp"
    ampfile = inps.ampname
    inty = IML.mmapFromISCE(ampfile, logging)
    inty1 = inty.bands[0].copy()
    inty2 = inty.bands[1].copy()
    inty1[inty1 == nanval] = np.NaN
    inty2[inty2 == nanval] = np.NaN

    width = inty1.shape[1]
    length = inty1.shape[0]

    # multi-look filtering amp file
    inty1 = np.power(inty1, 2)
    inty2 = np.power(inty2, 2)
    mask = np.ones((2, 2))
    INTY1 = cv2.filter2D(inty1, -1, mask,
                         borderType=cv2.BORDER_CONSTANT) / np.sum(mask)
    #    INTY1 = signal.convolve2d(inty1, mask, boundary='symm', mode='same')/mask.size
Example #12
0
def resampleOffset(maskedFiltOffset, geometryOffset, outName):
    '''
    Oversample offset and add.
    '''
    from imageMath import IML
    import logging

    resampledOffset = maskedFiltOffset + ".resampled"

    inimg = isceobj.createImage()
    inimg.load(geometryOffset + '.xml')
    length = inimg.getLength()
    width = inimg.getWidth()

    ###Currently making the assumption that top left of dense offsets and interfeorgrams are the same.
    ###This is not true for now. We need to update DenseOffsets to have the ability to have same top left
    ###As the input images. Once that is implemente, the math here should all be consistent.
    ###However, this is not too far off since the skip for doing dense offsets is generally large.
    ###The offset is not too large to worry about right now. If the skip is decreased, this could be an issue.

    print(
        'oversampling the filtered and masked offsets to the width and length:',
        width, ' ', length)
    cmd = 'gdal_translate -of ENVI -ot Float64  -outsize  ' + str(
        width) + ' ' + str(
            length) + ' ' + maskedFiltOffset + '.vrt ' + resampledOffset
    print(cmd)
    os.system(cmd)

    img = isceobj.createImage()
    img.setFilename(resampledOffset)
    img.setWidth(width)
    img.setLength(length)
    img.setAccessMode('READ')
    img.bands = 1
    img.dataType = 'DOUBLE'
    img.scheme = 'BIP'
    img.renderHdr()

    ###Adding the geometry offset and oversampled offset
    geomoff = IML.mmapFromISCE(geometryOffset, logging)
    osoff = IML.mmapFromISCE(resampledOffset, logging)

    fid = open(outName, 'w')

    for ll in range(length):
        val = geomoff.bands[0][ll, :] + osoff.bands[0][ll, :]
        val.tofile(fid)

    fid.close()

    img = isceobj.createImage()
    img.setFilename(outName)
    img.setWidth(width)
    img.setLength(length)
    img.setAccessMode('READ')
    img.bands = 1
    img.dataType = 'DOUBLE'
    img.scheme = 'BIP'
    img.renderHdr()

    return None
Example #13
0
    elif inps.fmt == 'vrt':

        if (inps.latvrt is None) or (inps.lonvrt is None):
            isce2vrt(inps.infile)

        else:
            #            latf = inps.latvrt + '.vrt'
            #            if not os.path.exists(latf):
            isce2vrt(inps.latvrt)

            #            lonf = inps.lonvrt + '.vrt'
            #            if not os.path.exists(lonf):
            isce2vrt(inps.lonvrt)

            latimg, dummy, dummy = IML.loadImage(inps.latvrt)
            latwid = latimg.getWidth()
            latlgt = latimg.getLength()
            if latimg.getBands() != 1:
                raise Exception('Latitude image should be single band')

            lonimg, dummy, dummy = IML.loadImage(inps.lonvrt)
            lonwid = lonimg.getWidth()
            lonlgt = lonimg.getLength()

            if lonimg.getBands() != 1:
                raise Exception('Longitude image should be single band')

            img = isceobj.createImage()
            img.load(inps.infile + '.xml')
            wid = img.getWidth()
Example #14
0
           m12=m12,
           m21=m21,
           m22=m22,
           t1=t1,
           t2=t2,
           rlks=inps.rlks,
           alks=inps.alks,
           rlks0=inps.rlks0,
           alks0=inps.alks0,
           format=formatx,
           method=methodx)

    rectInputFile = 'rect.in'
    with open(rectInputFile, 'w') as ff:
        ff.write(rectInput)

    #run fitoff here
    cmd = '$INSAR_ZERODOP_BIN/rect_with_looks {}'.format(rectInputFile)
    #print("{}".format(cmd))
    runCmd(cmd)

    #get xml file
    shutil.copy(inps.inimage + '.xml', inps.outimage + '.xml')
    #fix file name
    img, dataName, metaName = IML.loadImage(inps.outimage + '.xml')
    img.filename = inps.outimage
    #img.setAccessMode('READ')
    img.renderHdr()

#./rect.py -i 141018-141123_rg.off -o rect_141018-141123_rg.off -c ampsim_16rlks_16alks.aff -f real -r 16 -a 16
Example #15
0
    masterLength = getLength(inps.master + '.xml')
    slaveWidth = getWidth(inps.slave + '.xml')
    slaveLength = getLength(inps.slave + '.xml')

    with open(inps.slave + '.pck', 'rb') as fid:
        slaveFrame = pickle.load(fid)
    prf = slaveFrame.PRF

    #can get doppler centroid frequency information from frame now
    dop0 = slaveFrame.dopCoeff[0]
    dop1 = slaveFrame.dopCoeff[1]
    dop2 = slaveFrame.dopCoeff[2]
    dop3 = slaveFrame.dopCoeff[3]

    #get xml file for resampled SLC
    shutil.copy(inps.master + '.xml', inps.rslave + '.xml')
    #fix file name
    img, dataName, metaName = IML.loadImage(inps.rslave + '.xml')
    img.filename = inps.rslave
    #img.setAccessMode('READ')
    img.renderHdr()

    #run resamp
    cmd = "$INSAR_ZERODOP_BIN/resamp {} {} {} {} {} {} {} {} {} {} {} {} {}".format(
        inps.slave, inps.rslave, inps.rgoff, inps.azoff, masterWidth,
        masterLength, slaveWidth, slaveLength, prf, dop0, dop1, dop2, dop3)
    #print("{}".format(cmd))
    runCmd(cmd)

#./resample.py -m 20130927.slc -s 20141211.slc -r 20130927-20141211_rg.off -a 20130927-20141211_az.off -o 20141211_resamp.slc
    return inps


if __name__ == '__main__':
    '''
    Main driver.
    '''
    from imageMath import IML

    inps = cmdLineParse()

    if inps.infile.endswith('.xml'):
        inps.infile = os.path.splitext(inps.infile)[0]

    dirname = os.path.dirname(inps.infile)

    img, dataname, metaName = IML.loadImage(inps.infile)

    if inps.full:
        fname = os.path.abspath(
            os.path.join(dirname, os.path.basename(inps.infile)))
    elif inps.base:
        fname = os.path.basename(os.path.basename(inps.infile))
    else:
        raise Exception('Unknown state in {0}'.format(
            os.path.basename(__file__)))

    img.filename = fname
    img.setAccessMode('READ')
    img.renderHdr()
Example #17
0
def runCropOffsetGeo(self):
    '''
    Crops and resamples lat/lon/los/z images created by topsApp to the
    same grid as the offset field image.
    '''
    print('\n====================================')
    print('Cropping topo products to offset grid...')
    print('====================================')

    suffix = '.full'
    if (self.numberRangeLooks == 1) and (self.numberAzimuthLooks == 1):
        suffix = ''
    flist1b = ['lat.rdr' + suffix, 'lon.rdr' + suffix, 'z.rdr' + suffix]
    flist2b = [self._insar.mergedLosName + suffix]

    wend = (self.offset_width * self.skipwidth) + self.offset_left
    lend = (self.offset_length * self.skiphgt) + self.offset_top

    for filename in flist1b:
        print('\nCropping %s to %s ...\n' % (filename, filename + '.crop'))
        f = os.path.join(self._insar.mergedDirname, filename)
        outArr = []
        mmap = IML.mmapFromISCE(f, logging)
        '''
        for i in range(self.offset_top, mmap.length, self.skiphgt):
            outArr.append(mmap.bands[0][i][self.offset_left::self.skipwidth])
        '''
        for i in range(self.offset_top, lend, self.skiphgt):
            outArr.append(
                mmap.bands[0][i][self.offset_left:wend:self.skipwidth])

        outFile = os.path.join(self._insar.mergedDirname, filename + '.crop')
        outImg = isceobj.createImage()
        outImg.bands = 1
        outImg.scheme = 'BIP'
        outImg.dataType = 'DOUBLE'
        outImg.setWidth(len(outArr[0]))
        outImg.setLength(len(outArr))
        outImg.setFilename(outFile)
        with open(outFile, 'wb') as fid:
            for i in range(len(outArr)):
                np.array(outArr[i]).astype(np.double).tofile(
                    fid)  ### WAY easier to write to file like this
        outImg.renderHdr()
        print('Cropped %s' % (filename))

    for filename in flist2b:
        print('\nCropping %s to %s ...\n' % (filename, filename + '.crop'))
        f = os.path.join(self._insar.mergedDirname, filename)
        outArrCh1 = []
        outArrCh2 = []
        mmap = IML.mmapFromISCE(f, logging)
        '''
        for i in range(self.offset_top, mmap.length, self.skiphgt):
            outArrCh1.append(mmap.bands[0][i][self.offset_left::self.skipwidth])
            outArrCh2.append(mmap.bands[1][i][self.offset_left::self.skipwidth])
        '''
        for i in range(self.offset_top, lend, self.skiphgt):
            outArrCh1.append(
                mmap.bands[0][i][self.offset_left:wend:self.skipwidth])
            outArrCh2.append(
                mmap.bands[1][i][self.offset_left:wend:self.skipwidth])

        outFile = os.path.join(self._insar.mergedDirname, filename + '.crop')
        outImg = isceobj.createImage()
        outImg.bands = 2
        outImg.scheme = 'BIL'
        outImg.dataType = 'FLOAT'
        outImg.setWidth(len(outArrCh1[0]))
        outImg.setLength(len(outArrCh1))
        outImg.setFilename(outFile)
        with open(outFile, 'wb') as fid:
            for i in range(len(outArrCh1)):
                np.array(outArrCh1[i]).astype(np.float32).tofile(fid)
                np.array(outArrCh2[i]).astype(np.float32).tofile(fid)
        outImg.renderHdr()
        print('Cropped %s' % (filename))
Example #18
0
def main(argv):
    inps = cmdLineParse()

    ####Default names
    int_file = "filt_topophase.flat"
    cor_file = "phsig.cor"
    unw_file = "filt_topophase.unw"
    rdr_file = "los.rdr"

    if inps.geocoord:
        int_file += ".geo"
        cor_file += ".geo"
        unw_file += ".geo"
        rdr_file += ".geo"

    print(unw_file)
    ####Gather some basic information
    unw = IML.mmapFromISCE(unw_file, logging)
    shape = unw.bands[0].shape

    h5file = inps.outhe5

    ## OPEN HDF5 FILE ##
    f = h5py.File(h5file)
    hdfeos = f.create_group("HDFEOS")

    if inps.geocoord:
        ## CREATE GRIDS GROUP ##
        group = hdfeos.create_group("GRIDS")
    else:
        ## CREATE SWATHS GROUP ##
        group = hdfeos.create_group("SWATHS")

    insar = group.create_group("InSAR")
    data = group.create_group("Data Fields")

    ## CREATE UNWRAPPED INTERFEROGRAM ##
    dset = data.create_dataset(
        "UnwrappedInterferogram", data=unw.bands[1], shape=shape, chunks=(128, 128), compression="gzip"
    )
    dset.attrs["Title"] = "Unwrapped phase"
    dset.attrs["MissingValue"] = fzero
    dset.attrs["Units"] = "radians"
    dset.attrs["_FillValue"] = fzero
    unw = None

    #### CREATE COHERENCE ####
    cor = IML.mmapFromISCE(cor_file, logging)
    dset = data.create_dataset("Coherence", data=cor.bands[0], shape=shape, chunks=(128, 128), compression="gzip")
    dset.attrs["Title"] = "Phase Sigma Coherence"
    dset.attrs["MissingValue"] = fzero
    dset.attrs["Units"] = "None"
    dset.attrs["_FillValue"] = fzero
    cor = None

    #### CREATE WRAPPED INTERFEROGRAM
    wrap = IML.mmapFromISCE(int_file, logging)
    dset = data.create_dataset(
        "WrappedInterferogram", data=wrap.bands[0], shape=shape, chunks=(64, 64), compression="gzip"
    )
    dset.attrs["Title"] = "Wrapped interferogram"
    dset.attrs["MissingValue"] = czero
    dset.attrs["Units"] = "None"
    dset.attrs["_FillValue"] = czero
    wrap = None

    #### CREATE ILLUMINATION ANGLE
    ang = IML.mmapFromISCE(rdr_file, logging)
    dset = data.create_dataset("Illimunation", data=ang.bands[0], shape=shape, chunks=(128, 128), compression="gzip")
    dset.attrs["Title"] = "Illumination angle"
    dset.attrs[
        "Description"
    ] = "Vertical angle of the vector from target to sensor, w.r.t to the normal of the ellipse at the target"
    dset.attrs["MissingValue"] = fzero
    dset.attrs["Units"] = "degrees"
    dset.attrs["_FillValue"] = fzero

    #### CREATE AZIMUTH ANGLE
    dset = data.create_dataset("Azimuth", data=360.0 - ang.bands[1], shape=shape, chunks=(128, 128), compression="gzip")
    dset.attrs["Title"] = "Azimuth angle"
    dset.attrs[
        "Description"
    ] = "Angle of the vector from target to sensor, measured clockwise w.r.t North at the target"
    dset.attrs["MissingValue"] = fzero
    dset.attrs["Units"] = "degrees"
    dset.attrs["_FillValue"] = fzero
    ang = None

    ## WRITE ATTRIBUTES TO THE HDF ##
    if inps.geocoord:
        geoinfo = IML.getGeoInfo(unw_file)
        if geoinfo is None:
            raise Exception("No geocoding information found")

        north = geoinfo[0]
        south = geoinfo[0] + (shape[1] - 1) * geoinfo[2]
        west = geoinfo[1]
        east = geoinfo[1] + (shape[0] - 1) * geoinfo[3]

        insar.attrs["GCTPProjectionCode"] = np.zeros(1, dtype=np.int32)
        insar.attrs["GCTPSpheroidCode"] = str(12)
        insar.attrs["Projection"] = "Geographic"
        insar.attrs["GridOrigin"] = "Center"
        insar.attrs["GridSpacing"] = str((geoinfo[-1], geoinfo[-2]))
        insar.attrs["GridSpacingUnit"] = "deg"
        insar.attrs["GridSpan"] = str((west, east, north, south))
        insar.attrs["GridSpanUnit"] = "deg"
        insar.attrs["NumberOfLongitudesInGrid"] = np.array([shape[0]], dtype=np.int32)
        insar.attrs["NumberOfLatitudesInGrid"] = np.array([shape[1]], dtype=np.int32)

    f.close()