def unwrap_tile(self): cmd = 'snaphu -f {config_file} -d {wrapped_file} {line_length} -o ' \ '{unwrapped_file} --tile {ytile} {xtile} 500 500 ' \ '--nproc {num_proc}'.format(config_file=self.config_file, wrapped_file=self.inp_wrapped, line_length=self.width, unwrapped_file=self.out_unwrapped, ytile=self.y_tile, xtile=self.x_tile, num_proc=self.num_tiles) print(cmd) p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = p.communicate() print(error) if 'ERROR' in error.decode('UTF-8') or 'Error' in error.decode('UTF-8'): # or len(error.decode('UTF-8'))>0: raise RuntimeError(error) if os.path.exists(self.out_unwrapped): IML.renderISCEXML(self.out_unwrapped, bands=2, nyy=self.length, nxx=self.width, datatype='float32', scheme='BIL') IML.renderISCEXML(self.conncomp, bands=1, nyy=self.length, nxx=self.width, datatype='BYTE', scheme='BIL') return
def create_demZero(dem, outdir): """ create DEM with zero elevation """ demImage = isceobj.createDemImage() demImage.load(dem + '.xml') zerodem_name = outdir + '/demzero.wgs84' immap = IML.memmap(zerodem_name, mode='write', nchannels=demImage.bands, nxx=demImage.coord1.coordSize, nyy=demImage.coord2.coordSize, scheme=demImage.scheme, dataType=demImage.toNumpyDataType()) IML.renderISCEXML(zerodem_name, demImage.bands, demImage.coord2.coordSize, demImage.coord1.coordSize, demImage.toNumpyDataType(), demImage.scheme, bbox=demImage.getsnwe()) demZero = isceobj.createDemImage() demZero.load(zerodem_name + '.xml') return demZero
def flattenWithOffsets(fname, offname, flatname, frame, rglooks): from isceobj.Util.ImageUtil import ImageLib as IML import logging ifg = IML.mmapFromISCE(fname, logging).bands[0] off = IML.mmapFromISCE(offname, logging).bands[0] lgt = min(ifg.shape[0], off.shape[0]) delr = 0.5 * SPEED_OF_LIGHT / frame.rangeSamplingRate wvl = frame.getInstrument().getRadarWavelength() factor = 4 * np.pi * delr * rglooks / wvl cJ = np.complex64(1.0j) fid = open(flatname, 'wb') for ii in range(lgt): data = ifg[ii] * np.exp(-cJ * factor * off[ii]) data.astype(np.complex64).tofile(fid) fid.close() img = isceobj.createIntImage() img.setFilename(flatname) img.setWidth(ifg.shape[1]) img.setAccessMode('READ') img.renderHdr() pass
def subset(inname, outname, sliceline, slicepix, virtual=False): '''Subset the input image to output image. ''' gdalmap = {'FLOAT': 'Float32', 'CFLOAT': 'CFloat32', 'DOUBLE' : 'Float64'} inimg = isceobj.createImage() inimg.load(inname + '.xml') inimg.filename = outname inwidth = inimg.width inlength = inimg.length outwidth = slicepix.stop - slicepix.start outlength = sliceline.stop - sliceline.start inimg.setWidth(outwidth) inimg.setLength(outlength) inimg.setAccessMode('READ') inimg.renderHdr() if not virtual: indata = IML.mmapFromISCE(inname, logging).bands[0] outdata = indata[sliceline, slicepix] outdata.tofile(outname) indata = None else: relpath = os.path.relpath(inname, os.path.dirname(outname)) rdict = {'outwidth' : outwidth, 'outlength' : outlength, 'inwidth' : inwidth, 'inlength' : inlength, 'xoffset' : slicepix.start, 'yoffset' : sliceline.start, 'dtype' : gdalmap[inimg.dataType.upper()], 'filename' : relpath + '.vrt'} tmpl = '''<VRTDataset rasterXSize="{outwidth}" rasterYSize="{outlength}"> <VRTRasterBand dataType="{dtype}" band="1"> <NoDataValue>0.0</NoDataValue> <SimpleSource> <SourceFilename relativeToVRT="1">{filename}</SourceFilename> <SourceBand>1</SourceBand> <SourceProperties RasterXSize="{inwidth}" RasterYSize="{inlength}" DataType="{dtype}"/> <SrcRect xOff="{xoffset}" yOff="{yoffset}" xSize="{outwidth}" ySize="{outlength}"/> <DstRect xOff="0" yOff="0" xSize="{outwidth}" ySize="{outlength}"/> </SimpleSource> </VRTRasterBand> </VRTDataset>''' with open(outname + '.vrt', 'w') as fid: fid.write(tmpl.format(**rdict)) return
def parseInputFile(varname, args): ''' Get the input string corresponding to given variable name. ''' inarg = varname.strip() ####Keyname corresponds to specific key = '--' + inarg if len(varname.strip()) > 1: raise IOError('Input variable names should be single characters.\n' + 'Invalid variable name: %s'%varname) if (inarg != inarg.lower()): raise IOError('Input variable names should be lower case. \n' + 'Invalud variable name: %s'%varname) #####Create a simple parser parser = IML.customArgumentParser(description='Parser for band math.', add_help=False) parser.add_argument(key, type=str, required=True, action='store', help='Input string for a particular variable.', dest='instr') try: infile, rest = parser.parse_known_args(args) except: raise SyntaxError('Input file : "%s" not defined on command line'%varname) return infile.instr, rest
def createCoherence(intfile, win=5): ''' Compute coherence using scipy convolve 2D. ''' corfile = os.path.splitext(intfile)[0] + '.cor' filt = np.ones((win, win)) / (1.0 * win * win) inimg = IML.mmapFromISCE(intfile + '.xml', logging) cJ = np.complex64(1.0j) angle = np.exp(cJ * np.angle(inimg.bands[0])) res = SS.convolve2d(angle, filt, mode='same') res[0:win - 1, :] = 0.0 res[-win + 1:, :] = 0.0 res[:, 0:win - 1] = 0.0 res[:, -win + 1:] = 0.0 res = np.abs(res) with open(corfile, 'wb') as f: res.astype(np.float32).tofile(f) img = isceobj.createImage() img.setFilename(corfile) img.setWidth(res.shape[1]) img.dataType = 'FLOAT' img.setAccessMode('READ') img.renderHdr() img.renderVRT() # img.createImage() # img.finalizeImage() return corfile
def createImage(self): ''' Create an image object to pass to C extension. ''' from isceobj.Util.ImageUtil import ImageLib as IML img = IML.loadImage(self.fileName)[0] if img.dataType.upper().startswith('C'): img.setCaster('read','CDOUBLE') else: img.setCaster('read', 'DOUBLE') self.image = img self.image.createImage()
def read(file, processor='ISCE', bands=None, dataType=None): ''' raeder based on GDAL. Args: * file -> File name to be read Kwargs: * processor -> the processor used for the InSAR processing. default: ISCE * bands -> a list of bands to be extracted. If not specified all bands will be extracted. * dataType -> if not specified, it will be extracted from the data itself Returns: * data : A numpy array with dimensions : number_of_bands * length * width ''' # generate ENVI hdr file and fix the file path in xml file = os.path.abspath(file) if processor == 'ISCE': img, dataname, metaname = IML.loadImage(file) img.filename = file img.setAccessMode('READ') img.renderHdr() dataset = gdal.Open(file, GA_ReadOnly) ###################################### # if the bands have not been specified, all bands will be extracted if bands is None: bands = range(1, dataset.RasterCount + 1) ###################################### # if dataType is not known let's get it from the data: if dataType is None: band = dataset.GetRasterBand(1) dataType = GDAL2NUMPY_DATATYPE[band.DataType] ###################################### # Form a numpy array of zeros with the the shape of (number of bands * length * width) and a given data type data = np.zeros((len(bands), dataset.RasterYSize, dataset.RasterXSize), dtype=dataType) ###################################### # Fill the array with the Raster bands idx = 0 for i in bands: band = dataset.GetRasterBand(i) data[idx, :, :] = band.ReadAsArray() idx += 1 dataset = None return data
def detailedHelp(): ''' Return the detailed help message. ''' msg = helpStr + '\n\n'+ \ 'Available Functions \n' + \ '********************\n' + \ str(IML.fnDict.keys()) + '\n\n' + \ 'Available Constants \n' + \ '********************\n' + \ str(IML.constDict.keys()) + '\n\n' + \ 'Available DataTypes -> numpy code mapping \n' + \ '***************************************** \n'+ \ IML.printNUMPYMap() + '\n' return msg
def imagePathXml(imageFile, fullPath=True): import os import isceobj from isceobj.Util.ImageUtil import ImageLib as IML img = IML.loadImage(imageFile)[0] dirname = os.path.dirname(imageFile) if fullPath: fname = os.path.abspath( os.path.join(dirname, os.path.basename(imageFile))) else: fname = os.path.basename(imageFile) img.filename = fname img.setAccessMode('READ') img.renderHdr()
def firstPassCommandLine(): ''' Take a first parse at command line parsing. Read only the basic required fields ''' #####Create the generic parser to get equation and output format first parser = argparse.ArgumentParser(description='ISCE Band math calculator.', formatter_class=IML.customArgparseFormatter) # help_parser = subparser.add_ parser.add_argument('-H','--hh', nargs=0, action=customArgparseAction, help='Display detailed help information.') parser.add_argument('-e','--eval', type=str, required=True, action='store', help='Expression to evaluate.', dest='equation') parser.add_argument('-o','--out', type=str, default=None, action='store', help='Name of the output file', dest='out') parser.add_argument('-s','--scheme',type=str, default='BSQ', action='store', help='Output file format.', dest='scheme') parser.add_argument('-t','--type', type=str, default='float', action='store', help='Output data type.', dest='dtype') parser.add_argument('-d','--debug', action='store_true', default=False, help='Print debugging statements', dest='debug') parser.add_argument('-n','--noxml', action='store_true', default=False, help='Do not create an ISCE XML file for the output.', dest='noxml') #######Parse equation and output format first args, files = parser.parse_known_args() #####Check the output scheme for errors if args.scheme.upper() not in ['BSQ', 'BIL', 'BIP']: raise IOError('Unknown output scheme: %s'%(args.scheme)) iMath['outScheme'] = args.scheme.upper() npType = IML.NUMPY_type(args.dtype) iMath['outType'] = npType return args, files
def subset_file(fname, subset_dict_input, out_file=None): """Subset file with Inputs: fname : str, path/name of file out_file : str, path/name of output file subset_dict : dict, subsut parameter, including the following items: subset_x : list of 2 int, subset in x direction, default=None subset_y : list of 2 int, subset in y direction, default=None subset_lat : list of 2 float, subset in lat direction, default=None subset_lon : list of 2 float, subset in lon direction, default=None fill_value : float, optional. filled value for area outside of data coverage. default=None None/not-existed to subset within data coverage only. tight : bool, tight subset or not, for lookup table file, i.e. geomap*.trans Outputs: out_file : str, path/name of output file; out_file = 'subset_'+fname, if fname is in current directory; out_file = fname, if fname is not in the current directory. """ # Input File Info atr = readfile.read_attribute(fname) width = int(atr['WIDTH']) length = int(atr['LENGTH']) k = atr['FILE_TYPE'] print('subset ' + k + ' file: ' + fname + ' ...') subset_dict = subset_dict_input.copy() # Read Subset Inputs into 4-tuple box in pixel and geo coord pix_box, geo_box = subset_input_dict2box(subset_dict, atr) coord = ut.coordinate(atr) # if fill_value exists and not None, subset data and fill assigned value for area out of its coverage. # otherwise, re-check subset to make sure it's within data coverage and initialize the matrix with np.nan outfill = False if 'fill_value' in subset_dict.keys() and subset_dict['fill_value']: outfill = True else: outfill = False if not outfill: pix_box = coord.check_box_within_data_coverage(pix_box) subset_dict['fill_value'] = np.nan geo_box = coord.box_pixel2geo(pix_box) data_box = (0, 0, width, length) print('data range in (x0,y0,x1,y1): {}'.format(data_box)) print('subset range in (x0,y0,x1,y1): {}'.format(pix_box)) print('data range in (W, N, E, S): {}'.format( coord.box_pixel2geo(data_box))) print('subset range in (W, N, E, S): {}'.format(geo_box)) if pix_box == data_box: print('Subset range == data coverage, no need to subset. Skip.') return fname # Calculate Subset/Overlap Index pix_box4data, pix_box4subset = get_box_overlap_index(data_box, pix_box) ########################### Data Read and Write ###################### # Output File Name if not out_file: if os.getcwd() == os.path.dirname(os.path.abspath(fname)): if 'tight' in subset_dict.keys() and subset_dict['tight']: out_file = '{}_tight{}'.format( os.path.splitext(fname)[0], os.path.splitext(fname)[1]) else: out_file = 'sub_' + os.path.basename(fname) else: out_file = os.path.basename(fname) print('writing >>> ' + out_file) # update metadata atr = attr.update_attribute4subset(atr, pix_box) # subset datasets one by one dsNames = readfile.get_dataset_list(fname) maxDigit = max([len(i) for i in dsNames]) ext = os.path.splitext(out_file)[1] if ext in ['.h5', '.he5']: # initiate the output file writefile.layout_hdf5(out_file, metadata=atr, ref_file=fname) # subset dataset one-by-one for dsName in dsNames: with h5py.File(fname, 'r') as fi: ds = fi[dsName] ds_shape = ds.shape ds_ndim = ds.ndim print('cropping {d} in {b} from {f} ...'.format( d=dsName, b=pix_box4data, f=os.path.basename(fname))) if ds_ndim == 2: # read data = ds[pix_box4data[1]:pix_box4data[3], pix_box4data[0]:pix_box4data[2]] # crop data_out = np.ones( (pix_box[3] - pix_box[1], pix_box[2] - pix_box[0]), data.dtype) * subset_dict['fill_value'] data_out[pix_box4subset[1]:pix_box4subset[3], pix_box4subset[0]:pix_box4subset[2]] = data data_out = np.array(data_out, dtype=data.dtype) # write block = [0, int(atr['LENGTH']), 0, int(atr['WIDTH'])] writefile.write_hdf5_block(out_file, data=data_out, datasetName=dsName, block=block, print_msg=True) if ds_ndim == 3: prog_bar = ptime.progressBar(maxValue=ds_shape[0]) for i in range(ds_shape[0]): # read data = ds[i, pix_box4data[1]:pix_box4data[3], pix_box4data[0]:pix_box4data[2]] # crop data_out = np.ones( (1, pix_box[3] - pix_box[1], pix_box[2] - pix_box[0]), data.dtype) * subset_dict['fill_value'] data_out[:, pix_box4subset[1]:pix_box4subset[3], pix_box4subset[0]:pix_box4subset[2]] = data # write block = [ i, i + 1, 0, int(atr['LENGTH']), 0, int(atr['WIDTH']) ] writefile.write_hdf5_block(out_file, data=data_out, datasetName=dsName, block=block, print_msg=False) prog_bar.update(i + 1, suffix='{}/{}'.format( i + 1, ds_shape[0])) prog_bar.close() print('finished writing to file: {}'.format(out_file)) else: # IO for binary files dsDict = dict() for dsName in dsNames: dsDict[dsName] = subset_dataset( fname, dsName, pix_box, pix_box4data, pix_box4subset, fill_value=subset_dict['fill_value']) writefile.write(dsDict, out_file=out_file, metadata=atr, ref_file=fname) # write extra metadata files for ISCE data files if os.path.isfile(fname + '.xml') or os.path.isfile(fname + '.aux.xml'): # write ISCE XML file dtype_gdal = readfile.NUMPY2GDAL_DATATYPE[atr['DATA_TYPE']] dtype_isce = readfile.GDAL2ISCE_DATATYPE[dtype_gdal] writefile.write_isce_xml(out_file, width=int(atr['WIDTH']), length=int(atr['LENGTH']), bands=len(dsDict.keys()), data_type=dtype_isce, scheme=atr['scheme'], image_type=atr['FILE_TYPE']) print(f'write file: {out_file}.xml') # write GDAL VRT file if os.path.isfile(fname + '.vrt'): from isceobj.Util.ImageUtil import ImageLib as IML img = IML.loadImage(out_file)[0] img.renderVRT() print(f'write file: {out_file}.vrt') return out_file
def estimateOffsetField(reference, secondary, inps=None): """Estimte offset field using PyCuAmpcor. Parameters: reference - str, path of the reference SLC file secondary - str, path of the secondary SLC file inps - Namespace, input configuration Returns: objOffset - PyCuAmpcor object geomDict - dict, geometry location info of the offset field """ # update file path in xml file if inps.fixImageXml: for fname in [reference, secondary]: fname = os.path.abspath(fname) img = IML.loadImage(fname)[0] img.filename = fname img.setAccessMode('READ') img.renderHdr() ###Loading the secondary image object sim = isceobj.createSlcImage() sim.load(secondary + '.xml') sim.setAccessMode('READ') sim.createImage() ###Loading the reference image object sar = isceobj.createSlcImage() sar.load(reference + '.xml') sar.setAccessMode('READ') sar.createImage() width = sar.getWidth() length = sar.getLength() # create a PyCuAmpcor instance objOffset = PyCuAmpcor() objOffset.algorithm = inps.algorithm objOffset.deviceID = inps.gpuid objOffset.nStreams = inps.nstreams #cudaStreams objOffset.derampMethod = inps.deramp print('deramp method (0 for magnitude, 1 for complex): ', objOffset.derampMethod) objOffset.referenceImageName = reference + '.vrt' objOffset.referenceImageHeight = length objOffset.referenceImageWidth = width objOffset.secondaryImageName = secondary + '.vrt' objOffset.secondaryImageHeight = length objOffset.secondaryImageWidth = width print("image length:", length) print("image width:", width) # if using gross offset, adjust the margin margin = max(inps.margin, abs(inps.azshift), abs(inps.rgshift)) # determine the number of windows down and across # that's also the size of the output offset field objOffset.numberWindowDown = inps.numWinDown if inps.numWinDown > 0 \ else (length-2*margin-2*inps.srchgt-inps.winhgt)//inps.skiphgt objOffset.numberWindowAcross = inps.numWinAcross if inps.numWinAcross > 0 \ else (width-2*margin-2*inps.srcwidth-inps.winwidth)//inps.skipwidth print('the number of windows: {} by {}'.format( objOffset.numberWindowDown, objOffset.numberWindowAcross)) # window size objOffset.windowSizeHeight = inps.winhgt objOffset.windowSizeWidth = inps.winwidth print('window size for cross-correlation: {} by {}'.format( objOffset.windowSizeHeight, objOffset.windowSizeWidth)) # search range objOffset.halfSearchRangeDown = inps.srchgt objOffset.halfSearchRangeAcross = inps.srcwidth print('initial search range: {} by {}'.format(inps.srchgt, inps.srcwidth)) # starting pixel objOffset.referenceStartPixelDownStatic = inps.startpixeldw if inps.startpixeldw != -1 \ else margin + objOffset.halfSearchRangeDown # use margin + halfSearchRange instead objOffset.referenceStartPixelAcrossStatic = inps.startpixelac if inps.startpixelac != -1 \ else margin + objOffset.halfSearchRangeAcross print('the first pixel in reference image is: ({}, {})'.format( objOffset.referenceStartPixelDownStatic, objOffset.referenceStartPixelAcrossStatic)) # skip size objOffset.skipSampleDown = inps.skiphgt objOffset.skipSampleAcross = inps.skipwidth print('search step: {} by {}'.format(inps.skiphgt, inps.skipwidth)) # oversample raw data (SLC) objOffset.rawDataOversamplingFactor = inps.raw_oversample # correlation surface objOffset.corrStatWindowSize = inps.corr_stat_win_size corr_win_size = 2 * inps.corr_srch_size * inps.raw_oversample objOffset.corrSurfaceZoomInWindow = corr_win_size print('correlation surface zoom-in window size:', corr_win_size) objOffset.corrSurfaceOverSamplingMethod = inps.corr_oversamplemethod objOffset.corrSurfaceOverSamplingFactor = inps.corr_oversample print('correlation surface oversampling factor:', inps.corr_oversample) # output filenames fbase = '{}{}'.format(inps.outprefix, inps.outsuffix) objOffset.offsetImageName = fbase + '.bip' objOffset.grossOffsetImageName = fbase + '_gross.bip' objOffset.snrImageName = fbase + '_snr.bip' objOffset.covImageName = fbase + '_cov.bip' print("offsetfield: ", objOffset.offsetImageName) print("gross offsetfield: ", objOffset.grossOffsetImageName) print("snr: ", objOffset.snrImageName) print("cov: ", objOffset.covImageName) # whether to include the gross offset in offsetImage objOffset.mergeGrossOffset = inps.merge_gross_offset try: offsetImageName = objOffset.offsetImageName.decode('utf8') grossOffsetImageName = objOffset.grossOffsetImageName.decode('utf8') snrImageName = objOffset.snrImageName.decode('utf8') covImageName = objOffset.covImageName.decode('utf8') except: offsetImageName = objOffset.offsetImageName grossOffsetImageName = objOffset.grossOffsetImageName snrImageName = objOffset.snrImageName covImageName = objOffset.covImageName # generic control objOffset.numberWindowDownInChunk = inps.numWinDownInChunk objOffset.numberWindowAcrossInChunk = inps.numWinAcrossInChunk objOffset.useMmap = inps.usemmap objOffset.mmapSize = inps.mmapsize # setup and check parameters objOffset.setupParams() ## Set Gross Offset ### if inps.gross == 0: # use static grossOffset print('Set constant grossOffset ({}, {})'.format( inps.azshift, inps.rgshift)) objOffset.setConstantGrossOffset(inps.azshift, inps.rgshift) else: # use varying offset print("Set varying grossOffset from file {}".format( inps.gross_offset_file)) grossOffset = np.fromfile(inps.gross_offset_file, dtype=np.int32) numberWindows = objOffset.numberWindowDown * objOffset.numberWindowAcross if grossOffset.size != 2 * numberWindows: print(( 'WARNING: The input gross offsets do not match the number of windows:' ' {} by {} in int32 type').format( objOffset.numberWindowDown, objOffset.numberWindowAcross)) return 0 grossOffset = grossOffset.reshape(numberWindows, 2) grossAzimuthOffset = grossOffset[:, 0] grossRangeOffset = grossOffset[:, 1] # enforce C-contiguous flag grossAzimuthOffset = grossAzimuthOffset.copy(order='C') grossRangeOffset = grossRangeOffset.copy(order='C') # set varying gross offset objOffset.setVaryingGrossOffset(grossAzimuthOffset, grossRangeOffset) # check objOffset.checkPixelInImageRange() # save output geometry location info geomDict = { 'x_start': objOffset.referenceStartPixelAcrossStatic + int(objOffset.windowSizeWidth / 2.), 'y_start': objOffset.referenceStartPixelDownStatic + int(objOffset.windowSizeHeight / 2.), 'x_step': objOffset.skipSampleAcross, 'y_step': objOffset.skipSampleDown, 'x_win_num': objOffset.numberWindowAcross, 'y_win_num': objOffset.numberWindowDown, } # check redo print('redo: ', inps.redo) if not inps.redo: offsetImageName = '{}{}.bip'.format(inps.outprefix, inps.outsuffix) if os.path.exists(offsetImageName): print( 'offset field file: {} exists and w/o redo, skip re-estimation.' .format(offsetImageName)) return objOffset, geomDict # Run the code print('Running PyCuAmpcor') objOffset.runAmpcor() print('Finished') sar.finalizeImage() sim.finalizeImage() # Finalize the results # offsetfield outImg = isceobj.createImage() outImg.setDataType('FLOAT') outImg.setFilename(offsetImageName) outImg.setBands(2) outImg.scheme = 'BIP' outImg.setWidth(objOffset.numberWindowAcross) outImg.setLength(objOffset.numberWindowDown) outImg.setAccessMode('read') outImg.renderHdr() # gross offsetfield outImg = isceobj.createImage() outImg.setDataType('FLOAT') outImg.setFilename(grossOffsetImageName) outImg.setBands(2) outImg.scheme = 'BIP' outImg.setWidth(objOffset.numberWindowAcross) outImg.setLength(objOffset.numberWindowDown) outImg.setAccessMode('read') outImg.renderHdr() # snr snrImg = isceobj.createImage() snrImg.setFilename(snrImageName) snrImg.setDataType('FLOAT') snrImg.setBands(1) snrImg.setWidth(objOffset.numberWindowAcross) snrImg.setLength(objOffset.numberWindowDown) snrImg.setAccessMode('read') snrImg.renderHdr() # cov covImg = isceobj.createImage() covImg.setFilename(covImageName) covImg.setDataType('FLOAT') covImg.setBands(3) covImg.scheme = 'BIP' covImg.setWidth(objOffset.numberWindowAcross) covImg.setLength(objOffset.numberWindowDown) covImg.setAccessMode('read') covImg.renderHdr() return objOffset, geomDict
def readIsce(self, dates, filesDir, igramName): ''' Read files from ISCE software. Args: * dates : Dates of the interferogram (list) * filesDir : Files directory (str) * igramName : Interferogram filename (str) ''' # Import ISCE stuff import isce import isceobj from isceobj.Util.ImageUtil import ImageLib as IML #------------------------------------------------- # READ IGRAM # Igram filenames (wrapped, unwrapped and corrected) ifgInt = '{}/{}_{}/{}.int'.format( filesDir, dates[0], dates[1], os.path.splitext(os.path.basename(igramName))[0]) ifgFile = '{}/{}_{}/{}'.format(filesDir, dates[0], dates[1], igramName) ifgFile_corrected = '{}_corrected{}'.format( os.path.splitext(ifgFile)[0], os.path.splitext(ifgFile)[1]) # Igram.unw xml infos imgIfgFile = isceobj.createImage() imgIfgFile.load(ifgFile + '.xml') bands = imgIfgFile.bands length = imgIfgFile.getLength() width = imgIfgFile.getWidth() scheme = imgIfgFile.scheme # Igram.int xml infos imgInt = isceobj.createImage() imgInt.load(ifgInt + '.xml') bandsInt = imgInt.bands schemeInt = imgInt.scheme datatypeInt = IML.NUMPY_type(imgInt.dataType) # Igram not yet corrected if not os.path.exists(ifgFile_corrected): # Read igram.unw data = IML.memmap(ifgFile, mode='readonly', nchannels=bands, nyy=length, nxx=width, scheme=scheme) # Create the corrected igram data_corrected = IML.memmap(ifgFile_corrected, mode='write', nchannels=bands, nyy=length, nxx=width, scheme=scheme) # Copy igram.unw in the new file data_corrected.bands[0][:, :] = data.bands[0][:, :] data_corrected.bands[1][:, :] = data.bands[1][:, :] # New xml infos data_correctedXml = isceobj.Image.createUnwImage() data_correctedXml.bands = 2 data_correctedXml.setWidth(width) data_correctedXml.setLength(length) data_correctedXml.setFilename(ifgFile_corrected) data_correctedXml.renderHdr() data_correctedXml.renderVRT() # Flag flag_corr = True # Igram already corrected, start from it else: # Read igram.unw already corrected data = IML.memmap(ifgFile_corrected, mode='readwrite', nchannels=bands, nyy=length, nxx=width, scheme=scheme) # Flag flag_corr = False # Read wrap igram where to compute misclosure data_int = IML.memmap(ifgInt, mode='readonly', nchannels=bandsInt, dataType=datatypeInt, nyy=length, nxx=width, scheme=schemeInt) #------------------------------------------------- # READ MASK # Initialize the mask mask = np.zeros((length, width)) #------------------------------------------------- # SAVE # Save things if flag_corr: self.phase = data_corrected.bands[1] else: self.phase = data.bands[1] self.phase_int = data_int.bands[0] self.dates = dates self.igramsDir = filesDir self.igramName = igramName self.width = width self.length = length self.ifgFile_corrected = ifgFile_corrected # Close files del data del data_int # All done return
'--base', action='store_true', help='Replace filename with basename to use in current directory') inps = parser.parse_args() return inps if __name__ == '__main__': ''' Main driver. ''' inps = cmdLineParse() if inps.infile.endswith('.xml'): inps.infile = os.path.splitext(inps.infile)[0] dirname = os.path.dirname(inps.infile) img = IML.loadImage(inps.infile)[0] if inps.full: fname = os.path.abspath( os.path.join(dirname, os.path.basename(inps.infile))) else: fname = os.path.basename(os.path.basename(inps.infile)) img.filename = fname img.setAccessMode('READ') img.renderHdr()
def mergeBursts(frame, fileList, outfile, method='top'): ''' Merge burst products into single file. Simple numpy based stitching ''' ###Check against metadata if frame.numberOfBursts != len(fileList): print('Warning : Number of burst products does not appear to match number of bursts in metadata') t0 = frame.bursts[0].sensingStart dt = frame.bursts[0].azimuthTimeInterval width = frame.bursts[0].numberOfSamples ####### tstart = frame.bursts[0].sensingStart tend = frame.bursts[-1].sensingStop nLines = int( np.round((tend - tstart).total_seconds() / dt)) + 1 print('Expected total nLines: ', nLines) img = isceobj.createImage() img.load( fileList[0] + '.xml') bands = img.bands scheme = img.scheme npType = IML.NUMPY_type(img.dataType) azMasterOff = [] for index in range(frame.numberOfBursts): burst = frame.bursts[index] soff = burst.sensingStart + datetime.timedelta(seconds = (burst.firstValidLine*dt)) start = int(np.round((soff - tstart).total_seconds() / dt)) end = start + burst.numValidLines azMasterOff.append([start,end]) print('Burst: ', index, [start,end]) if index == 0: linecount = start outMap = IML.memmap(outfile, mode='write', nchannels=bands, nxx=width, nyy=nLines, scheme=scheme, dataType=npType) for index in range(frame.numberOfBursts): curBurst = frame.bursts[index] curLimit = azMasterOff[index] curMap = IML.mmapFromISCE(fileList[index], logging) #####If middle burst if index > 0: topBurst = frame.bursts[index-1] topLimit = azMasterOff[index-1] topMap = IML.mmapFromISCE(fileList[index-1], logging) olap = topLimit[1] - curLimit[0] print("olap: ", olap) if olap <= 0: raise Exception('No Burst Overlap') for bb in range(bands): topData = topMap.bands[bb][topBurst.firstValidLine: topBurst.firstValidLine + topBurst.numValidLines,:] curData = curMap.bands[bb][curBurst.firstValidLine: curBurst.firstValidLine + curBurst.numValidLines,:] im1 = topData[-olap:,:] im2 = curData[:olap,:] if method=='avg': data = 0.5*(im1 + im2) elif method == 'top': data = im1 elif method == 'bot': data = im2 else: raise Exception('Method should be top/bot/avg') outMap.bands[bb][linecount:linecount+olap,:] = data tlim = olap else: tlim = 0 linecount += tlim if index != (frame.numberOfBursts-1): botBurst = frame.bursts[index+1] botLimit = azMasterOff[index+1] olap = curLimit[1] - botLimit[0] if olap < 0: raise Exception('No Burst Overlap') blim = botLimit[0] - curLimit[0] else: blim = curBurst.numValidLines lineout = blim - tlim for bb in range(bands): curData = curMap.bands[bb][curBurst.firstValidLine: curBurst.firstValidLine + curBurst.numValidLines,:] outMap.bands[bb][linecount:linecount+lineout,:] = curData[tlim:blim,:] linecount += lineout curMap = None topMap = None IML.renderISCEXML(outfile, bands, nLines, width, img.dataType, scheme) oimg = isceobj.createImage() oimg.load(outfile + '.xml') oimg.imageType = img.imageType oimg.renderHdr() try: outMap.bands[0].base.base.flush() except: pass
help = 'Replace filename with full path including dir in which file is located') fname.add_argument('-b', '--base', action='store_true', help = 'Replace filename with basename to use in current directory') inps = parser.parse_args() return inps if __name__ == '__main__': ''' Main driver. ''' inps = cmdLineParse() for fname in inps.infile: if fname.endswith('.xml'): fname = os.path.splitext(fname)[0] print('fixing xml file for file: {}'.format(fname)) if inps.full: fdir = os.path.dirname(fname) fname = os.path.abspath(os.path.join(fdir, os.path.basename(fname))) else: fname = os.path.basename(os.path.basename(fname)) img = IML.loadImage(fname)[0] img.filename = fname img.setAccessMode('READ') img.renderHdr()
def main(args, files): #######Set up logger appropriately logger = IML.createLogger(args.debug, name='imageMath') logger.debug('Known: '+ str(args)) logger.debug('Optional: '+ str(files)) #######Determine number of input and output bands bandList = [] for ii,expr in enumerate(args.equation.split(';')): #####Now parse the equation to get the file names used nsp = NumericStringParser(expr.strip()) logger.debug('Input Expression: %d : %s'%(ii, expr)) bands, known = nsp.parse() logger.debug('Unknown variables: ' + str(bands)) logger.debug('Known variables: ' + str(known)) iMath['equations'].append(expr) bandList = bandList + bands bandList = IML.uniqueList(bandList) numOutBands = len(iMath['equations']) logger.debug('Number of output bands = %d'%(numOutBands)) logger.debug('Number of input bands used = %d'%(len(bandList))) logger.debug('Input bands used = ' + str(bandList)) #####Determine unique images from the bandList fileList = IML.bandsToFiles(bandList, logger) ######Create input memmaps for ii,infile in enumerate(fileList): fstr, files = parseInputFile(infile, files) logger.debug('Input string for File %d: %s: %s'%(ii, infile, fstr)) if len(fstr.split(';')) > 1: fmap = IML.mmapFromStr(fstr, logger) bbox = None else: fmap = IML.mmapFromISCE(fstr, logger) bbox = IML.getGeoInfo(fstr) iMath['inFiles'][infile] = fmap if len(fmap.bands) == 1: iMath['inBands'][infile] = fmap.bands[0] for ii in range(len(fmap.bands)): iMath['inBands']['%s_%d'%(infile, ii)] = fmap.bands[ii] if bbox is not None: iMath['bboxes'].append(bbox) if len(files): raise IOError('Unused input variables set:\n'+ ' '.join(files)) #######Some debugging logger.debug('List of available bands: ' + str(iMath['inBands'].keys())) ####If used in calculator mode. if len(bandList) == 0: dataDict=dict(IML.fnDict.items() + IML.constDict.items()) logger.info('Calculator mode. No output files created') for ii, equation in enumerate(iMath['equations']): res=eval(expr, dataDict) logger.info('Output Band %d : %f '%(ii, res)) sys.exit(0) else: if args.out is None: raise IOError('Output file has not been defined.') #####Check if all bands in bandList have been accounted for for band in bandList: if band not in iMath['inBands'].keys(): raise ValueError('Undefined band : %s '%(band)) ######Check if all the widths match widths = [img.width for var,img in iMath['inFiles'].items() ] if len(widths) != widths.count(widths[0]): logger.debug('Widths of images: ' + str([(var, img.name, img.width) for var,img in iMath['inFiles'].items()])) raise IOError('Input images are not of same width') iMath['width'] = widths[0] logger.debug('Output Width = %d'%(iMath['width'])) #######Check if all the lengths match lengths=[img.length for var,img in iMath['inFiles'].items()] if len(lengths) != lengths.count(lengths[0]): logger.debug('Lengths of images: ' + str([(var, img.name, img.length) for var,img in iMath['inFiles'].items()])) raise IOError('Input images are not of the same length') iMath['length'] = lengths[0] logger.debug('Output Length = %d'%(iMath['length'])) #####Now create the output file outmap = IML.memmap(args.out, mode='write', nchannels=numOutBands, nxx=iMath['width'], nyy=iMath['length'], scheme=iMath['outScheme'], dataType=iMath['outType']) logger.debug('Creating output ISCE mmap with \n' + 'file = %s \n'%(args.out) + 'bands = %d \n'%(numOutBands) + 'width = %d \n'%(iMath['width']) + 'length = %d \n'%(iMath['length'])+ 'scheme = %s \n'%(iMath['outScheme']) + 'dtype = %s \n'%(iMath['outType'])) iMath['outBands'] = outmap.bands #####Start evaluating the expressions ####Set up the name space to use dataDict=dict(IML.fnDict.items() | IML.constDict.items()) bands = iMath['inBands'] outBands = iMath['outBands'] ####Array representing columns dataDict['COL'] = np.arange(iMath['width'], dtype=np.float) #####Replace ^ by ** for lineno in range(int(iMath['length'])): ####Setting row number dataDict['ROW'] = lineno*1.0 ####Load one line from each of the the bands for band in bandList: #iMath['inBands'].iteritems(): dataDict[band] = bands[band][lineno,:] ####For each output band for kk,expr in enumerate(iMath['equations']): res = eval(expr, dataDict) outBands[kk][lineno,:] = res ######Determine common bbox if any outputBbox = mergeBbox(iMath['bboxes']) ######Render ISCE XML if needed if not args.noxml: IML.renderISCEXML(args.out, numOutBands, iMath['length'], iMath['width'], iMath['outType'], iMath['outScheme'], bbox = outputBbox, descr = ' '.join(sys.argv))
def initiate_stacks(slc_stack, patch_dir, box, mini_stack_default_size, phase_linking_method, shp_size, range_window, azimuth_window): shp_file = patch_dir + '/shp' rslc_file = patch_dir + '/rslc' datum_file = patch_dir + '/datum_shift' squeezed_file = patch_dir + '/squeezed_images' rslc_ref_file = patch_dir + '/rslc_ref' quality_file = patch_dir + '/quality' # create PATCH_* folder if not exist os.makedirs(patch_dir, exist_ok=True) length = box[3] - box[1] width = box[2] - box[0] # read current slc_stack to be inverted RSLC = h5py.File(slc_stack, 'a') rslc_stack = RSLC['slc'] numSlc, rslc_length, rslc_width = rslc_stack.shape # big box is box + shp window big_box = get_big_box(box, range_window, azimuth_window, rslc_width, rslc_length) big_length = big_box[3] - big_box[1] big_width = big_box[2] - big_box[0] if 'sequential' in phase_linking_method: total_num_mini_stacks = numSlc // mini_stack_default_size # subset squeezed images stack for the patch with the big box size if not os.path.exists(squeezed_file): squeezed_image = np.memmap(squeezed_file, dtype='complex64', mode='w+', shape=(total_num_mini_stacks, length, width)) IML.renderISCEXML(squeezed_file, bands=total_num_mini_stacks, nyy=length, nxx=width, datatype='complex64', scheme='BSQ') # subset datum shift stack for the patch with the big box size if not os.path.exists(datum_file): datum_shift = np.memmap(datum_file, dtype='float32', mode='w+', shape=(total_num_mini_stacks, length, width)) IML.renderISCEXML(datum_file, bands=total_num_mini_stacks, nyy=length, nxx=width, datatype='float32', scheme='BSQ') else: total_num_mini_stacks = 1 # subset slc stack for the patch with the big box size if not os.path.exists(rslc_file): rslc = np.memmap(rslc_file, dtype='complex64', mode='w+', shape=(numSlc, big_length, big_width)) rslc[:, :, :] = rslc_stack[:, big_box[1]: big_box[3], big_box[0]:big_box[2]] RSLC.close() IML.renderISCEXML(rslc_file, bands=numSlc, nyy=length, nxx=width, datatype='complex64', scheme='BSQ') # initiate refined slc file for the patch if not os.path.exists(rslc_ref_file): rslc_ref = np.memmap(rslc_ref_file, dtype='complex64', mode='w+', shape=(numSlc, length, width)) IML.renderISCEXML(rslc_ref_file, bands=numSlc, nyy=length, nxx=width, datatype='complex64', scheme='BSQ') # initiate shp file for the patch if not os.path.isfile(shp_file): shp = np.memmap(shp_file, dtype='byte', mode='w+', shape=(shp_size, length, width)) IML.renderISCEXML(shp_file, bands=shp_size, nyy=length, nxx=width, datatype='byte', scheme='BSQ') # initiate quality file for the patch if not os.path.exists(quality_file): quality = np.memmap(quality_file, dtype='float32', mode='w+', shape=(length, width)) quality[:, :] = -1 IML.renderISCEXML(quality_file, bands=1, nyy=length, nxx=width, datatype='float32', scheme='BIL') return big_box, total_num_mini_stacks
def multilook_file(infile, lks_y, lks_x, outfile=None, method='average', margin=[0, 0, 0, 0], max_memory=4): """ Multilook input file Parameters: infile - str, path of input file to be multilooked. lks_y - int, number of looks in y / row direction. lks_x - int, number of looks in x / column direction. margin - list of 4 int, number of pixels to be skipped during multilooking. useful for offset product, where the marginal pixels are ignored during cross correlation matching. outfile - str, path of output file Returns: outfile - str, path of output file """ lks_y = int(lks_y) lks_x = int(lks_x) # input file info atr = readfile.read_attribute(infile) length, width = int(atr['LENGTH']), int(atr['WIDTH']) k = atr['FILE_TYPE'] print('multilooking {} {} file: {}'.format(atr['PROCESSOR'], k, infile)) print('number of looks in y / azimuth direction: %d' % lks_y) print('number of looks in x / range direction: %d' % lks_x) print('multilook method: {}'.format(method)) # margin --> box if margin is not [0, 0, 0, 0]: # top, bottom, left, right box = (margin[2], margin[0], width - margin[3], length - margin[1]) print( 'number of pixels to skip in top/bottom/left/right boundaries: {}'. format(margin)) else: box = (0, 0, width, length) # output file name ext = os.path.splitext(infile)[1] if not outfile: if os.getcwd() == os.path.dirname(os.path.abspath(infile)): outfile = os.path.splitext(infile)[0] + '_' + str( lks_y) + 'alks_' + str(lks_x) + 'rlks' + ext else: outfile = os.path.basename(infile) # update metadata atr = attr.update_attribute4multilook(atr, lks_y, lks_x, box=box) if ext in ['.h5', '.he5']: writefile.layout_hdf5(outfile, metadata=atr, ref_file=infile) # read source data and multilooking dsNames = readfile.get_dataset_list(infile) maxDigit = max([len(i) for i in dsNames]) dsDict = dict() for dsName in dsNames: print('multilooking {d:<{w}} from {f} ...'.format( d=dsName, w=maxDigit, f=os.path.basename(infile))) # split in Y/row direction for IO for HDF5 only if ext in ['.h5', '.he5']: # calc step size with memory usage up to 4 GB with h5py.File(infile, 'r') as f: ds = f[dsName] ds_size = np.prod(ds.shape) * 4 num_step = int(np.ceil(ds_size * 4 / (max_memory * 1024**3))) row_step = int(np.rint(length / num_step / 10) * 10) row_step = max(row_step, 10) else: row_step = box[3] - box[1] num_step = int(np.ceil((box[3] - box[1]) / (row_step * lks_y))) for i in range(num_step): r0 = box[1] + row_step * lks_y * i r1 = box[1] + row_step * lks_y * (i + 1) r1 = min(r1, box[3]) # IO box box_i = (box[0], r0, box[2], r1) box_o = (int((box[0] - box[0]) / lks_x), int( (r0 - box[1]) / lks_y), int( (box[2] - box[0]) / lks_x), int((r1 - box[1]) / lks_y)) print('box: {}'.format(box_o)) # read / multilook if method == 'nearest': data = readfile.read(infile, datasetName=dsName, box=box_i, xstep=lks_x, ystep=lks_y, print_msg=False)[0] else: data = readfile.read(infile, datasetName=dsName, box=box_i, print_msg=False)[0] data = multilook_data(data, lks_y, lks_x) # output block if data.ndim == 3: block = [ 0, data.shape[0], box_o[1], box_o[3], box_o[0], box_o[2] ] else: block = [box_o[1], box_o[3], box_o[0], box_o[2]] # write if ext in ['.h5', '.he5']: writefile.write_hdf5_block(outfile, data=data, datasetName=dsName, block=block, print_msg=False) else: dsDict[dsName] = data # for binary file with 2 bands, always use BIL scheme if (len(dsDict.keys()) == 2 and os.path.splitext(infile)[1] not in ['.h5', '.he5'] and atr.get('scheme', 'BIL').upper() != 'BIL'): print('the input binary file has 2 bands with band interleave as: {}'. format(atr['scheme'])) print( 'for the output binary file, change the band interleave to BIL as default.' ) atr['scheme'] = 'BIL' if ext not in ['.h5', '.he5']: writefile.write(dsDict, out_file=outfile, metadata=atr, ref_file=infile) # write extra metadata files for ISCE data files if os.path.isfile(infile + '.xml') or os.path.isfile(infile + '.aux.xml'): # write ISCE XML file dtype_gdal = readfile.NUMPY2GDAL_DATATYPE[atr['DATA_TYPE']] dtype_isce = readfile.GDAL2ISCE_DATATYPE[dtype_gdal] writefile.write_isce_xml(outfile, width=int(atr['WIDTH']), length=int(atr['LENGTH']), bands=len(dsDict.keys()), data_type=dtype_isce, scheme=atr['scheme'], image_type=atr['FILE_TYPE']) print(f'write file: {outfile}.xml') # write GDAL VRT file if os.path.isfile(infile + '.vrt'): from isceobj.Util.ImageUtil import ImageLib as IML img = IML.loadImage(outfile)[0] img.renderVRT() print(f'write file: {outfile}.vrt') return outfile