def main(): ## All Sentinel-2 data subfolders are located within a super folder (make sure data is already unzipped and each sub folder name ends with .SAFE) path = r'D:\Sentinel\test' outpath = r'D:\Sentinel\out' if not os.path.exists(outpath): os.makedirs(outpath) for folder in os.listdir(path): gc.enable() gc.collect() print ("Filname: ", path + "\\" + folder + "\\manifest.safe") ##sentinel2 = path + "\\" + folder + "\\MTD_MSIL1C.xml" sentinel2 = ProductIO.readProduct(path + "\\" + folder + "\\MTD_MSIL1C.xml") loopstarttime = str(datetime.datetime.now()) print ('Start time: ', loopstarttime) start_time = time.time() ## Extract mode, product type modestamp = folder.split("_")[1] productstamp = folder.split("_")[2] ## Start preprocessing resample = do_resampling(sentinel2) biOp = do_biophysical_parameter(resample) ##ndvi = do_vegetation_indices(sentinel2) print ("outFilename: ", outpath + "\\" + folder.split(".SAFE")[0] + '_biOp' + '.dim') ProductIO.writeProduct(biOp, outpath + "\\" + folder.split(".SAFE")[0] + '_biOp' + '.dim', "BEAM-DIMAP")
def copy_bands_to_file(src_file_path, dst_file_path, bands=None): # Get info from source product src_prod = ProductIO.readProduct(src_file_path) prod_name = src_prod.getName() prod_type = src_prod.getProductType() width = src_prod.getSceneRasterWidth() height = src_prod.getSceneRasterHeight() if bands is None: bands = src_prod.getBandNames() # Copy geocoding and selected bands from source to destination product dst_prod = Product(prod_name, prod_type, width, height) ProductUtils.copyGeoCoding(src_prod.getBandAt(0), dst_prod) for band in bands: r = ProductUtils.copyBand(band, src_prod, dst_prod, True) if r is None: src_prod.closeIO() raise RuntimeError(src_file_path + " does not contain band " + band) # Write destination product to disk ext = os.path.splitext(dst_file_path)[1] if ext == '.dim': file_type = 'BEAM_DIMAP' elif ext == '.nc': file_type = 'NetCDF-CF' elif ext == '.tif': file_type = 'GeoTIFF-BigTIFF' else: file_type = 'GeoTIFF-BigTIFF' ProductIO.writeProduct(dst_prod, dst_file_path, file_type) src_prod.closeIO() dst_prod.closeIO()
def get_prod_metadata(first_image_location, second_image_location): prod1 = ProductIO.readProduct(first_image_location) prod2 = ProductIO.readProduct(second_image_location) # Get some Metadata freqMHz = prod1.getMetadataRoot().getElement( 'Abstracted_Metadata').getAttributeDouble('radar_frequency') wavelengthM = constants.c / (freqMHz * 10**6) long1 = prod1.getMetadataRoot().getElement( 'Abstracted_Metadata').getAttributeDouble('first_near_long') long2 = prod2.getMetadataRoot().getElement( 'Abstracted_Metadata').getAttributeDouble('first_near_long') #lat = prod prod1.dispose() prod2.dispose() return wavelengthM # import jpy # Runtime = jpy.get_type('java.lang.Runtime') # max_memory = Runtime.getRuntime().maxMemory() # total_memory = Runtime.getRuntime().totalMemory() # free_memory = Runtime.getRuntime().freeMemory() # gb = 1e+9 # print('max memory:', max_memory / gb, "GB") # print('total memory:', total_memory / gb, "GB") # print('free memory:', free_memory / gb, "GB")
def guardarArchivo(): global flood_mask #Crear la imagen a partir de la mascara ProductIO.writeProduct(flood_mask, "C:/CTE_334/Actividad09/final_mask", 'GeoTIFF') os.path.exists("C:/CTE_334/Actividad09/final_mask.tif") print("IMAGEN CREADA EXITOSAMENTE A PARTIR DE MASCARA")
def match_up(filename, file, stations): print('match_up...') # file = ProductIO.readProduct(filepath+filename) geo = file.getSceneGeoCoding() size = file.getSceneRasterSize() if geo.canGetGeoPos(): for station in stations: p1 = geo.getPixelPos(geopos(station['Lat'], station['Lon']), None) if p1.getX() == 'non': continue x = p1.getX() - Height / 2 y = p1.getY() - Width / 2 if file.containsPixel(p1): flist = filename.split('_') wdir, wspeed = wind_filed_from_ndbc(station['name'], flist[-5]) if wdir == 0 and wspeed == 0: continue else: print(flist[-1].split('.')[0]) print(station) print(x, y) print(size.getHeight(), size.getWidth()) if size.getHeight() > 400 and size.getWidth > 400: subfile = subset(file, int(x), int(y)) if subfile is False: print('cut exception') continue print('write...') print(filename, station['name']) try: ProductIO.writeProduct( subfile, '/users/yangchao/GitHub/wind/snap/match_data1/' + station['name'] + '_subset_' + wdir + '_' + wspeed + '_' + station['height'] + '_' + filename.split('.')[0], 'BEAM-DIMAP') except Exception: print('exception') subfile.dispose() continue subfile.dispose() del subfile else: print('copy...') try: ProductIO.writeProduct( file, '/users/yangchao/GitHub/wind/snap/match_data1/' + station['name'] + '_subset_' + wdir + '_' + wspeed + '_' + station['height'] + '_' + filename.split('.')[0], 'BEAM-DIMAP') except Exception: print('exception') continue else: print(filename + " can't get geo pos") del size del geo file.dispose()
def read_terrain_corrected_product(path_to_dim): print(path_to_dim) dataproduct_r = ProductIO.readProduct(path_to_dim) # will the computed band show up? for band in dataproduct_r.getBandNames(): print(band) print('WRITING OUT TO GEOTIFF!!') sigma0_ortho_bands = ["Sigma0_VH_use_local_inci_angle_from_dem", "Sigma0_VV_use_local_inci_angle_from_dem"] convertComputedBandToBand(dataproduct_r.getBand(sigma0_ortho_bands[0])) convertComputedBandToBand(dataproduct_r.getBand(sigma0_ortho_bands[1])) HashMap = jpy.get_type('java.util.HashMap') sub_parameters = HashMap() sub_parameters.put('bandNames', ",".join(sigma0_ortho_bands)) # Should eventually look at using a local SRTM 1Sec DEM (instead of auto downloading) subset = GPF.createProduct("Subset", sub_parameters, dataproduct_r) final_output_name = Path(Path(path_to_dim).parent, "test") print('writing out final result') # Get a progressMonitor object # monitor = self.createProgressMonitor() # print('WRITING OUT PRODUCT') ProductIO.writeProduct(subset, str(final_output_name), 'BEAM-DIMAP')
def apply_orbit_file(self, write_intermediate=False): parameters = self.HashMap() dataproduct = GPF.createProduct("Apply-Orbit-File", parameters, self.dataproduct_r) self.operations_list.append('ApplyOrbit') SF_filepath = "" # Get a progressMonitor object monitor = self.createProgressMonitor() if write_intermediate: # Write data product with BEAM-DIM format to given file path # ProductIO.writeProduct(Product product, String filePath, String formatName) SF_filepath = Path(self.working_dir, self.name_with_safe + "_ORB") print('Writing out Orbit File corrected product') ProductIO.writeProduct(dataproduct, str(SF_filepath), 'BEAM-DIMAP', monitor) # Set start time and loop counter finish_time = datetime.datetime.now() # for calculation elapsed_time = finish_time - self.start_time print(elapsed_time.strftime("%H:%M:%S")) if os.path.exists(SF_filepath + ".dim"): print("Completed applying orbit file:", SF_filepath) else: print("Completed applying orbit file: data product saved to in-memory") self.intermediate_product = dataproduct
def topo_removal(file): image = ProductIO.readProduct(file) p = HashMap() p.put('demName', 'SRTM 1Sec HGT') result = GPF.createProduct('TopoPhaseRemoval', p, image) # Write to temporary file outfile = file.split('.dim')[0] + '_noSRTM.dim' ProductIO.writeProduct(result, outfile, 'BEAM-DIMAP')
def guardarArchivo(): global flood_mask #Crear la imagen a partir de la mascara ProductIO.writeProduct( flood_mask, "C:/Users/Usuario/Desktop/Actvidades_CTE_334/Examen_unidad_2/final_mask", 'GeoTIFF') print("IMAGEN CREADA EXITOSAMENTE A PARTIR DE MASCARA")
def bandMathSnap(input_dim, output_file, expression_list, format_file='float32'): if debug >= 2: print(cyan + "bandmathSnap() : " + bold + green + "Import Dim to SNAP : " + endC + input_dim) # Info input file product = ProductIO.readProduct(input_dim) width = product.getSceneRasterWidth() height = product.getSceneRasterHeight() name = product.getName() description = product.getDescription() band_names = product.getBandNames() if debug >= 2: print(cyan + "bandmathSnap() : " + bold + green + "Product: %s, %d x %d pixels, %s" % (name, width, height, description) + endC) print(cyan + "bandmathSnap() : " + bold + green + "Bands: %s" % (list(band_names)) + endC) # Instance de GPF GPF.getDefaultInstance().getOperatorSpiRegistry().loadOperatorSpis() # Def operateur SNAP operator = 'BandMaths' BandDescriptor = jpy.get_type( 'org.esa.snap.core.gpf.common.BandMathsOp$BandDescriptor') targetBands = jpy.array( 'org.esa.snap.core.gpf.common.BandMathsOp$BandDescriptor', len(expression_list)) # Get des expressions d'entréées i = 0 for expression in expression_list: targetBand = BandDescriptor() targetBand.name = 'band_' + str(i + 1) targetBand.type = format_file targetBand.expression = expression targetBands[i] = targetBand i += 1 # Set des parametres parameters = HashMap() parameters.put('targetBands', targetBands) # Get snappy Operators result = GPF.createProduct(operator, parameters, product) ProductIO.writeProduct(result, output_file, 'BEAM-DIMAP') if debug >= 2: print(cyan + "bandmathSnap() : " + bold + green + "Writing Done : " + endC + str(output_file)) return result
def classify(prepros_folder): for file in os.listdir(prepros_folder): ### Folder, date & timestamp classification = rootpath + "\\classification" scene_name = str(prepros_folder.split("\\")[X])[:32] # [X] element of filepath, change this to match scene name. [:32] first caracters of element print("scene_name:", scene_name) output_folder = os.path.join(classification, scene_name) print("output_folder:", output_folder) polarization = str(file)[46:48] # polarization from filename if not os.path.exists(output_folder): os.mkdir(output_folder) GPF.getDefaultInstance().getOperatorSpiRegistry().loadOperatorSpis() HashMap = snappy.jpy.get_type('java.util.HashMap') gc.enable() sentinel_1 = ProductIO.readProduct(os.path.join(prepros_folder, file)) res = [20, 50] # parameters for CFAR for r in res: resolution = r gd_window = resolution * 12.0 bg_window = resolution * 37.0 # AdaptiveThresholding (Constant False Alarm Rate CFAR) parameters = HashMap() parameters.put('targetWindowSizeInMeter', resolution) parameters.put('guardWindowSizeInMeter', gd_window) parameters.put('backgroundWindowSizeInMeter', bg_window) parameters.put('pfa', 6.0) target_1 = GPF.createProduct("AdaptiveThresholding", parameters, sentinel_1) parameters = None # Subset (extracting classification band) parameters = HashMap() parameters.put('bandNames', 'Sigma0_' + polarization + '_ship_bit_msk') outfile = output_folder + "\\" + scene_name + "_" + polarization + "_cfar_" + str(resolution) + "m" target_2 = GPF.createProduct("Subset", parameters, target_1) ProductIO.writeProduct(target_2, outfile, 'GeoTIFF-BigTIFF', pm) # Classification to vector ds = gdal.Open(str(outfile + ".tif")) rasterband = ds.GetRasterBand(1) dst_layername = outfile + "_Iceberg_outline" drv = ogr.GetDriverByName("GeoJSON") dst_ds = drv.CreateDataSource(dst_layername + ".geojson") dest_srs = ogr.osr.SpatialReference() dest_srs.ImportFromEPSG(4326) dst_layer = dst_ds.CreateLayer(dst_layername, dest_srs) gdal.Polygonize(rasterband, rasterband, dst_layer, -1, [], callback=None) # (input, mask, dest_layer,,,)
def write(self, file_path): """ Write the processed product to a file with a file type and close the product. """ print("\tWrite, file_path={}".format(file_path)) ProductIO.writeProduct(self.product, file_path, 'GeoTIFF') self.product.closeIO() self.product = None return self.product
def speckle_filter(self, filter="Gamma Map", estimateENL=True, filterSize=11, numLooksStr="1", targetWindowStr="3x3", windowSize="11x11", write_intermediate=False): print("-------------") # Apply SPECKLE FILTER print("Applying speckle-filter:", self.name) # Define object parameterisation for filtering parameters = self.HashMap() parameters.put('filter', filter) parameters.put('estimateENL', estimateENL) parameters.put('filterSizeX', filterSize) parameters.put('filterSizeY', filterSize) parameters.put('numLooksStr', numLooksStr) parameters.put('sourceBands', ",".join(self.srcbands)) parameters.put('targetWindowStr', targetWindowStr) parameters.put('windowSize', windowSize) print("Speckle filtering parameters:", parameters) # Create speckle filter data product using 'Speckle-Filter' operator/parameters and raw data product as source product # Speckle noise reduction can be applied either by spatial filtering or multilook processing # Filtered product contains 4 real bands: 2 amplitude and intensity bands for each polarizations # createProduct(String operatorName, Map<String,Object> parameters, Map<String,Product> sourceProducts) dataproduct = GPF.createProduct("Speckle-Filter", parameters, self.dataproduct_r) self.operations_list.append('SpeckleFilter') SF_filepath = "" # Get a progressMonitor object monitor = self.createProgressMonitor() if write_intermediate: # Write data product with BEAM-DIM format to given file path # ProductIO.writeProduct(Product product, String filePath, String formatName) SF_filepath = Path(self.working_dir, self.name_with_safe + "_SF") print('Writing out SpeckleFilter Product') ProductIO.writeProduct(dataproduct, str(SF_filepath), 'BEAM-DIMAP', monitor) finish_time = datetime.datetime.now() # for calculation elapsed_time = finish_time - self.start_time print(elapsed_time.strftime("%H:%M:%S")) if os.path.exists(SF_filepath + ".dim"): print("Completed speckle-filtering:", SF_filepath) else: print("Completed speckle-filtering: data product saved to in-memory") self.intermediate_product = dataproduct
def getGeoTiffImage(sarDownloadFilePath, geopandasDataFilePath, geoDataIndex, dstPath=None): ''' Get GeoTiff image from a .SAFE folder extracted after download :type sarDownloadFilePath: string or list of string :type geopandasDataFilePath: string :type geoDataIndex: int :type dstPath: string :param sarDownloadFilePath: directory (or list of directory) of .SAFE folder(s) :param geopandasDataFilePath: directory of geopandas dataframe file :param geoDataIndex: geoDataIndex of data needed to retrieve in geopandas Dataframe :param dstPath: directory of destination file, must have '.tif' extension :return: None :example: sarHelpers.getGeoTiffImage(sarDownloadFilePath='S1A_IW_GRDH_1SDV_20170221T225238_20170221T225303_015388_019405_9C41.SAFE', geopandasDataFilePath='mekongReservoirs', geoDataIndex=0, dstPath='geotiff/1.tif') ''' from snappy import jpy from snappy import ProductIO from snappy import GPF from snappy import HashMap s1meta = "manifest.safe" s1product = "%s/%s" % (sarDownloadFilePath, s1meta) reader = ProductIO.getProductReader("SENTINEL-1") product = reader.readProductNodes(s1product, None) parameters = HashMap() borderRectInGeoCoor = Utils.getGeoDataBorder(geopandasDataFilePath, geoDataIndex) subset = Utils.subset(product, borderRectInGeoCoor) calibrate = Utils.calibrate(subset) terrain = Utils.terrainCorrection(calibrate) terrainDB = GPF.createProduct("LinearToFromdB", parameters, terrain) speckle = Utils.speckleFilter(terrainDB) if dstPath is None: dstPath = sarImgPath[:-4] + '.tif' ProductIO.writeProduct(speckle, dstPath, 'GeoTiff') product.dispose() subset.dispose() calibrate.dispose() terrain.dispose() speckle.dispose() del product, subset, calibrate, terrain, terrainDB, speckle return dstPath
def snaphu_unwrapping(product, target_Product_File, outFolder, filename): parameters = HashMap() parameters.put('targetProductFile', target_Product_File) # from SNAPHU_export parameters.put('outputFolder', outFolder) parameters.put('copyOutputAndDelete', 'Snaphu-unwrapping-after.vm') parameters.put('copyFilesTemplate', 'Snaphu-unwrapping-before.vm') product = GPF.createProduct('snaphu-unwrapping', parameters, product) ProductIO.writeProduct(product, filename + '.dim', 'BEAM-DIMAP') print('Phase unwrapping performed successfully …')
def collocate_all(input_imgs, write_product): if len(input_imgs) < 2: raise ValueError('Error, len(input_imgs)={}'.format(len(input_imgs))) col = collocate(input_imgs[0],input_imgs[1]) for i in range(2,len(input_imgs)): col = collocate(col,input_imgs[i]) if write_product: collocation = "collocation_all.tif" ProductIO.writeProduct(col, collocation, 'GeoTiff') return col
def do_ifg(path): """ Takes filepath of TDX xml file Uses snappy to create interferogram Add in parameters to p if required (see gpt Interferogram -h for details) """ target = ifg_file(path) image = ProductIO.readProduct(path) p = HashMap() image = GPF.createProduct('Interferogram',p,image) ProductIO.writeProduct(image,target,'BEAM-DIMAP')
def createP(function, inputProduct, writeout=False, **kwargs): # pythonic version of GPF.createProduct() # function is string of SNAP operator # inputProduct is SNAP product object # kwargs contains any parameters to pass to the operator p = HashMap() for arg in kwargs: p.put(arg, kwargs.get(arg)) result = GPF.createProduct(function, p, inputProduct) if writeout != False: ProductIO.writeProduct(result, writeout, 'BEAM-DIMAP') else: return result
def write_out_result(self, format='BEAM-DIMAP'): if format == 'BEAM-DIMAP': # Write data product with BEAM-DIM format to given file path # ProductIO.writeProduct(Product product, String filePath, String formatName) SF_filepath = Path(self.working_dir, self.name_with_safe + "_FINAL") print('WRITING OUT PRODUCT') ProductIO.writeProduct(self.intermediate_product, str(SF_filepath), 'BEAM-DIMAP') finish_time = datetime.datetime.now()# for calculation elapsed_time = finish_time - self.start_time print(elapsed_time.strftime("%H:%M:%S")) elif format == 'GEOTIFF': print('WRITING OUT TO GEOTIFF!!') sigma0_ortho_bands = ["Sigma0_VH_use_local_inci_angle_from_dem", "Sigma0_VV_use_local_inci_angle_from_dem"] print(self.intermediate_product) print(self.intermediate_product.getBandNames()) for band in self.intermediate_product.getBandNames(): print(band) self.convertComputedBandToBand(self.intermediate_product.getBand(sigma0_ortho_bands[0])) self.convertComputedBandToBand(self.intermediate_product.getBand(sigma0_ortho_bands[1])) sub_parameters = self.HashMap() sub_parameters.put('bandNames', ",".join(sigma0_ortho_bands)) # Should eventually look at using a local SRTM 1Sec DEM (instead of auto downloading) subset = GPF.createProduct("Subset", sub_parameters, self.intermediate_product) print(self.name_with_safe) final_output_name = Path(self.working_dir, self.name_with_safe + "_".join(self.operations_list)) print('writing out final result') # Get a progressMonitor object monitor = self.createProgressMonitor() print('WRITING OUT PRODUCT') ProductIO.writeProduct(self.intermediate_product, str(final_output_name), 'GeoTIFF') finish_time = datetime.datetime.now() # for calculation elapsed_time = finish_time - self.start_time print(elapsed_time.strftime("%H:%M:%S"))
def BandMathList(stack): product = ProductIO.readProduct(stack) band_names = product.getBandNames() GPF.getDefaultInstance().getOperatorSpiRegistry().loadOperatorSpis() BandDescriptor = jpy.get_type( 'org.esa.snap.core.gpf.common.BandMathsOp$BandDescriptor') bandlist = list(band_names) #targetBands = list() x = 0 y = 1 bandlength = len(bandlist) runs = (bandlength - 1) targetBands = jpy.array( 'org.esa.snap.core.gpf.common.BandMathsOp$BandDescriptor', runs) for i in bandlist: while y <= runs: #print('{}_minus_{}'.format(bandlist[x], bandlist[y])) #targetBand1 = '{}_minus_{}'.format(bandlist[x], bandlist[y]) targetBand1 = BandDescriptor() targetBand1.name = '{}_minus_{}'.format(bandlist[x], bandlist[y]) targetBand1.type = 'float32' targetBand1.expression = '(({} - {})<(-2))? 255 : 0'.format( bandlist[x], bandlist[y]) print("Writing Band {} : {}_minus_{}".format( x, bandlist[x], bandlist[y])) #targetBands.append(targetBand1) targetBands[x] = targetBand1 x = x + 1 y = y + 1 """targetBand1 = BandDescriptor() targetBand1.name = 'first_{}_minus_last_{}'.format(bandlist[0], bandlist[bandlength]) targetBand1.type = 'float32' targetBand1.expression = '(({} - {})<(-2))? 255 : 0'.format(bandlist[x], bandlist[y]) print("Writing Band first_{}_minus_last_{}".format(bandlist[0], bandlist[bandlength]) targetBands[bandlength] = targetBand1""" parameters = HashMap() parameters.put('targetBands', targetBands) result = GPF.createProduct('BandMaths', parameters, product) print("Writing...") ProductIO.writeProduct(result, 'BandMaths.dim', 'BEAM-DIMAP') print("BandMaths.dim Done.") ProductIO.writeProduct(result, 'BandMaths.tif', "GeoTIFF-BigTIFF") print("BandMaths.tif Done.")
def range_doppler_to_sigma0(self, resolution=10.0, suffix="", window_size=11, write_intermediate=False): # APPLY Range Doppler terrain correction and ortho print('Applying applying R.Doppler terrain corr. and ortho...') rd_parameters = self.HashMap() rd_parameters.put('demName', "SRTM 1Sec HGT") # Should eventually look at using a local SRTM 1Sec DEM (instead of auto downloading) rd_parameters.put('imgResamplingMethod', "BILINEAR_INTERPOLATION") rd_parameters.put('pixelSpacingInMeter', resolution) rd_parameters.put('sourceBands', ",".join(self.srcbands)) # rd_parameters.put('mapProjection', projection) # Defined above, should be auto set to best UTM zone # APPLY RADIOMETRIC NORMALIZATION to SIGMA0 (not clear if necessary) only do if sigma0 NOT done above rd_parameters.put('applyRadiometricNormalization', True) rd_parameters.put('incidenceAngleForSigma0', "Use local incidence angle from DEM") rd_parameters.put('saveSigmaNought', True) rd_parameters.put('saveLocalIncidenceAngle', True) rd_corrected = GPF.createProduct("Terrain-Correction", rd_parameters, self.intermediate_product) self.operations_list.append("RangeDopplerOrthoConversionToSigma0") print(self.name_with_safe) final_output_name = self.name_with_safe + "_{}_{}x{}_{}m".format(suffix, window_size, window_size, resolution) print('writing out final result') # Get a progressMonitor object monitor = self.createProgressMonitor() SF_filepath = "" if write_intermediate: # Write data product with BEAM-DIM format to given file path # ProductIO.writeProduct(Product product, String filePath, String formatName) SF_filepath = Path(self.working_dir, self.name_with_safe + "_ORTHO") print('Writing out Terrain-Correction Product') ProductIO.writeProduct(rd_corrected, str(SF_filepath), 'BEAM-DIMAP', monitor) finish_time = datetime.datetime.now() # for calculation elapsed_time = finish_time - self.start_time print(elapsed_time.strftime("%H:%M:%S")) if os.path.exists(SF_filepath + ".dim"): print("Completed speckle-filtering:", SF_filepath) else: print("Completed speckle-filtering: data product saved to in-memory") self.intermediate_product = rd_corrected
def nbr(self): if hasattr(self, 'path_post'): name = 'NBR' exprss = '(B8 - B12) / (B8 + B12)' product_pre = self._band_math(self.product_pre, name, exprss) product_post = self._band_math(self.product_post, name, exprss) print(list(product_pre.getBandNames())) print(list(product_post.getBandNames())) name = 'difNBR' exprss = '$p1.NBR - $p2.NBR'.format(product_pre, product_post) products = [product_pre, product_post] product = self._band_math(products, name, exprss) out = "/".join([self.path, 'NBR.tif']) ProductIO.writeProduct(product, out, "GeoTIFF-BigTIFF")
def write_snappy_product(file_path, bands, product_name, geo_coding): try: (height, width) = bands[0]['band_data'].shape except AttributeError: raise RuntimeError(bands[0]['band_name'] + "contains no data.") product = Product(product_name, product_name, width, height) product.setSceneGeoCoding(geo_coding) # Ensure that output is saved in BEAM-DIMAP format, # otherwise writeHeader does not work. file_path = os.path.splitext(file_path)[0] + '.dim' # Bands have to be created before header is written # but header has to be written before band data is written. for b in bands: band = product.addBand(b['band_name'], ProductData.TYPE_FLOAT32) if 'description' in b.keys(): band.setDescription(b['description']) if 'unit' in b.keys(): band.setUnit(b['unit']) product.setProductWriter(ProductIO.getProductWriter('BEAM-DIMAP')) product.writeHeader(String(file_path)) for b in bands: band = product.getBand(b['band_name']) band.writePixels(0, 0, width, height, b['band_data'].astype(np.float32)) product.closeIO()
def resample(DIR, band, resolution): """ resamples a band of a SENTINEL product to a given target resolution :param DIR: base directory of Sentinel2 directory tree :param band: band name (e.g. B4) :param resolution: target resolution in meter (e.g 10) :return: resampled band """ from snappy import GPF GPF.getDefaultInstance().getOperatorSpiRegistry().loadOperatorSpis() HashMap = jpy.get_type('java.util.HashMap') BandDescriptor = jpy.get_type( 'org.esa.snap.core.gpf.common.BandMathsOp$BandDescriptor') parameters = HashMap() parameters.put('targetResolution', resolution) parameters.put('upsampling', 'Bicubic') parameters.put('downsampling', 'Mean') parameters.put('flagDownsampling', 'FlagMedianAnd') parameters.put('resampleOnPyramidLevels', True) product = ProductIO.readProduct(DIR) product = GPF.createProduct('Resample', parameters, product) rsp_band = product.getBand(band) return rsp_band
def get_bands_in_np(filepath): prod = ProductIO.readProduct(filepath) # Get some Metadata width = prod.getSceneRasterWidth() height = prod.getSceneRasterHeight() # Extract bands and tie points from the product bandnames = list(prod.getBandNames()) tpnames = list(prod.getTiePointGridNames()) bandStack = list(prod.getBands()) tiepointStack = list(prod.getTiePointGrids()) prod.dispose() img = np.zeros((len(bandnames), width, height), dtype=np.float32) try: i = 0 for currentBand in bandStack: img[i, :, :] = currentBand.readPixels(0, 0, width, height, img[i, :, :]) i += 1 except: for currentBand in bandStack: for y in range(height): # print("processing line ", y, " of ", height) currentBand.readPixels(0, y, width, 1, img) return img, bandnames
def __init__(self, pre, post=None): self.plots = "PixEx" self.path = "/".join(pre['name'].split('/')[:-2]) self.path_pre = pre['name'] self.product_pre = ProductIO.readProduct(self.path_pre) self.producttype_pre = pre['producttype'] if post: if pre['tile_id'] == post['tile_id']: self.tile_id = pre['tile_id'] else: raise self.path_post = post['name'] self.product_post = ProductIO.readProduct(self.path_post) self.producttype_post = post['producttype'] else: self.tile_id = pre['tile_id']
def readDim(input_dim): if debug >= 2: print(cyan + "readDim() : " + bold + green + "Import Dim to SNAP : " + endC + str(input_dim )) product = ProductIO.readProduct(input_dim) band_names_list = list(product.getBandNames()) return product, band_names_list
def get_ProductFile( p_path ): files = [] if(os.path.isfile(p_path)): print("Checking if the file is readable by snap:\n %s ..." % p_path ) files.append(p_path) else: print("Finding snap product file at directory:\n %s ..." % p_path ) files.extend( [os.path.join(p_path, fa) for fa in os.listdir(p_path) if os.path.isfile( os.path.join(p_path, fa) )] ) p_file_aux = None for fi in files: p = None try: # Reads data product. The method does not automatically read band data p = ProductIO.readProduct(fi) except: pass if p: p_type = p.getProductType() if p.getProductType() in AUX_DATA_FILES: p_file_aux = fi else: print(' ------------------------------------------------') print(' Type: ' + p.getProductType() ) print(' Mission/Format: ' + ', '.join( p.getProductReader().getReaderPlugIn().getFormatNames() )) #print(' Band Names: ' + ', '.join( p.getBandNames() ) ) #print(' Raster Sizes: heigth=%d, Width=%d' % (p.getSceneRasterHeight(), p.getSceneRasterWidth()) ) print(' ------------------------------------------------') return fi return p_file_aux
def process_mosaic(files, fileName): products = [ProductIO.readProduct(i) for i in files] mosaic = do_sar_mosaic(products) return save_product(mosaic, fileName, 'GeoTiff')
def extract_feature_array_from_product( file_path: str) -> (np.ndarray, int, int, int, list): """ Extract bands from an ESA data product :param file_path: path to a ESA SNAP dim file :return: (numpy array of shape (bands, pixels), image width, image height, number of pixels) """ print('Extracting feature array from product', file_path) util.start_timer() from snappy import ProductIO p = ProductIO.readProduct(file_path) bands = [p.getBand(x) for x in p.getBandNames()] if len(bands) == 0: raise Exception("No bands found in product") image_width = bands[0].getRasterWidth() image_height = bands[0].getRasterHeight() number_of_pixels = image_width * image_height feature_array = np.array([ band.readPixels(0, 0, image_width, image_height, np.zeros(number_of_pixels, np.float32)) for band in bands ]) band_names = [band.getName() for band in bands] util.end_timer_print_duration() return feature_array, image_width, image_height, number_of_pixels, band_names
def write_images(file): # Disable JAI native MediaLib extensions System = jpy.get_type('java.lang.System') System.setProperty('com.sun.media.jai.disableMediaLib', 'true') NUM_BANDS = 15 product = ProductIO.readProduct(file) band_arrays = [] w = product.getSceneRasterWidth() h = product.getSceneRasterHeight() for i in range(0, NUM_BANDS): band = product.getBand("radiance_%d" % (i + 1)) band_data = np.zeros(w * h, dtype=np.float32) band.readPixels(0, 0, w, h, band_data) band_arrays.append(band_data) result = [] value_min = -1 value_max = 1 for i in range(0, NUM_BANDS): for j in range(i + 1, NUM_BANDS): a1 = band_arrays[i] a2 = band_arrays[j] array = (a1 - a2) / (a1 + a2) array = np.ma.masked_invalid(array) array = array.clip(value_min, value_max) array -= value_min array *= 1.0 / (value_max - value_min) array.shape = (h, w) array = cm.jet(array, bytes=True) image = Image.fromarray(array, 'RGBA') name = 'radiance_%d_to_%d.png' % (i + 1, j + 1) with io.FileIO(name, 'w') as fp: print('Writing ' + name) image.save(fp, format='PNG') result.append(name) return result
import sys import numpy from snappy import String from snappy import Product from snappy import ProductData from snappy import ProductIO from snappy import ProductUtils if len(sys.argv) != 2: print("usage: %s <file>" % sys.argv[0]); sys.exit(1) print("Reading...") product = ProductIO.readProduct(sys.argv[1]) width = product.getSceneRasterWidth() height = product.getSceneRasterHeight() name = product.getName() desc = product.getDescription() band_names = product.getBandNames() print("Product: %s, %d x %d pixels, %s" % (name, width, height, desc)) print("Bands: %s" % (band_names)) b7 = product.getBand('radiance_7') b10 = product.getBand('radiance_10') ndviProduct = Product('NDVI', 'NDVI', width, height) ndviBand = ndviProduct.addBand('ndvi', ProductData.TYPE_FLOAT32) ndviBand.setNoDataValue(numpy.nan) ndviBand.setNoDataValueUsed(True)
jpy = snappy.jpy # More Java type definitions required for image generation Color = jpy.get_type('java.awt.Color') ColorPoint = jpy.get_type('org.esa.snap.core.datamodel.ColorPaletteDef$Point') ColorPaletteDef = jpy.get_type('org.esa.snap.core.datamodel.ColorPaletteDef') ImageInfo = jpy.get_type('org.esa.snap.core.datamodel.ImageInfo') ImageManager = jpy.get_type('org.esa.snap.core.image.ImageManager') JAI = jpy.get_type('javax.media.jai.JAI') # Disable JAI native MediaLib extensions System = jpy.get_type('java.lang.System') System.setProperty('com.sun.media.jai.disableMediaLib', 'true') def write_image(band, points, filename, format): cpd = ColorPaletteDef(points) ii = ImageInfo(cpd) band.setImageInfo(ii) im = ImageManager.getInstance().createColoredBandImage([band], band.getImageInfo(), 0) JAI.create("filestore", im, filename, format) product = ProductIO.readProduct(file) band = product.getBand('radiance_13') # The colour palette assigned to pixel values 0, 50, 100 in the band's geophysical units points = [ColorPoint(0.0, Color.YELLOW), ColorPoint(50.0, Color.RED), ColorPoint(100.0, Color.BLUE)] write_image(band, points, 'snappy_write_image.png', 'PNG')
import sys import numpy from snappy import String from snappy import Product from snappy import ProductData from snappy import ProductIO from snappy import ProductUtils if len(sys.argv) != 2: print("usage: %s <file>" % sys.argv[0]); sys.exit(1) print("Reading...") sourceProduct = ProductIO.readProduct(sys.argv[1]) b1 = sourceProduct.getBand('reflec_5') b2 = sourceProduct.getBand('reflec_7') b3 = sourceProduct.getBand('reflec_9') w1 = b1.getSpectralWavelength() w2 = b2.getSpectralWavelength() w3 = b3.getSpectralWavelength() a = (w2 - w1) / (w3 - w1) k = 1.03 width = sourceProduct.getSceneRasterWidth() height = sourceProduct.getSceneRasterHeight() targetProduct = Product('FLH_Product', 'FLH_Type', width, height) targetBand = targetProduct.addBand('FLH', ProductData.TYPE_FLOAT32) ProductUtils.copyGeoCoding(sourceProduct, targetProduct) targetProduct.setProductWriter(ProductIO.getProductWriter('GeoTIFF'))
import snappy from snappy import ProductIO SubsetOp = snappy.jpy.get_type('org.esa.snap.gpf.operators.standard.SubsetOp') WKTReader = snappy.jpy.get_type('com.vividsolutions.jts.io.WKTReader') if len(sys.argv) != 3: print("usage: %s <file> <geometry-wkt>" % sys.argv[0]) print(" %s ./TEST.N1 \"POLYGON((15.786082 45.30223, 11.798364 46.118263, 10.878688 43.61961, 14.722727" "42.85818, 15.786082 45.30223))\"" % sys.argv[0]) sys.exit(1) file = sys.argv[1] wkt = sys.argv[2] geom = WKTReader().read(wkt) print("Reading...") product = ProductIO.readProduct(file) op = SubsetOp() op.setSourceProduct(product) op.setGeoRegion(geom) sub_product = op.getTargetProduct() print("Writing...") ProductIO.writeProduct(sub_product, "snappy_subset_output.dim", "BEAM-DIMAP") print("Done.")
print("usage: %s <inputProduct> <wkt>" % sys.argv[0]) sys.exit(1) input = sys.argv[1] inputFileName = input[input.rfind('/')+1:] wellKnownText = sys.argv[2] try: geometry = WKTReader().read(wellKnownText) except: geometry = None print('Failed to convert WKT into geometry') sys.exit(2) product = ProductIO.readProduct(input) wktFeatureType = PlainFeatureFactory.createDefaultFeatureType(DefaultGeographicCRS.WGS84) featureBuilder = SimpleFeatureBuilder(wktFeatureType) wktFeature = featureBuilder.buildFeature('shape') wktFeature.setDefaultGeometry(geometry) newCollection = ListFeatureCollection(wktFeatureType) newCollection.add(wktFeature) productFeatures = FeatureUtils.clipFeatureCollectionToProductBounds(newCollection, product, None, ProgressMonitor.NULL) node = VectorDataNode('shape', wktFeatureType) product.getVectorDataGroup().add(node) vdGroup = product.getVectorDataGroup()
import sys import numpy from snappy import Product, ProductData, ProductIO, ProductUtils if len(sys.argv) < 2: print 'Product file requires' sys.exit(1) # input product & dimensions input_product = ProductIO.readProduct(sys.argv[1]) width = input_product.getSceneRasterWidth() height = input_product.getSceneRasterHeight() product_name = input_product.getName() # input product red & nir bands red_band = input_product.getBand('B4') nir_band = input_product.getBand('B8') # output product (ndvi) & new band output_product = Product('NDVI', 'NDVI', width, height) ProductUtils.copyGeoCoding(input_product, output_product) output_band = output_product.addBand('ndvi', ProductData.TYPE_FLOAT32) # output writer output_product_writer = ProductIO.getProductWriter('BEAM-DIMAP') output_product.setProductWriter(output_product_writer) output_product.writeHeader(product_name + '.ndvi.dim') # compute & save ndvi line by line red_row = numpy.zeros(width, dtype=numpy.float32)
def test_end_to_end(self): # PRODPATH = "C:\\Users\\carsten\\Dropbox\\Carsten\\SWProjects\\Rayleigh-Correction\\testdata\\" PRODPATH = "D:\\Dropbox\\Carsten\\SWProjects\\Rayleigh-Correction\\testdata\\" # validate here numerr=0 # read output # SENSOR = 'MERIS' SENSOR = 'OLCI' main([SENSOR]) if (SENSOR=='MERIS'): REF_FILE =OUT_FILE = PRODPATH+'Reftestprodukt1_MER_RR_20050713.dim' TEST_FILE=OUT_FILE = PRODPATH+'Testprodukt1_MER_RR_20050713.dim' NBANDS=15 if (SENSOR=='OLCI'): REF_FILE = PRODPATH+'Reftestproduct3_S3A_OL_1_EFR____20160509T103945.dim' TEST_FILE = PRODPATH+'Testproduct3_OL_1_EFR____20160509T103945.dim' NBANDS=21 print("Opening reference product ...") refproduct = ProductIO.readProduct(REF_FILE) width = refproduct.getSceneRasterWidth() height = refproduct.getSceneRasterHeight() print("Opening test product ...") testproduct = ProductIO.readProduct(TEST_FILE) widthtest = testproduct.getSceneRasterWidth() heighttest = testproduct.getSceneRasterHeight() # compare print("Start comparing ...") try: self.assertEqual(width, widthtest) print(" widths agree: ",width) except: print(" widths error: ref=",width," test=",widthtest) numerr+=1 try: self.assertEqual(height, heighttest) print(" height agree: ",height) except: print(" height error: ref=",height," test=",heighttest) numerr+=1 refvalues=np.zeros((width,height),dtype=np.float32) testvalues=np.zeros((width,height),dtype=np.float32) bandname="rBRR_" for i in range(1,NBANDS+1): refsource = refproduct.getBand(bandname+str(i)) refvalues = refsource.readPixels(0, 0, width, height, refvalues) testsource = testproduct.getBand(bandname+str(i)) testvalues = testsource.readPixels(0, 0, width, height, testvalues) try: result=np.allclose(refvalues,testvalues, rtol=0.0, atol=1e-6, equal_nan=True) self.assertEqual(result,True) print(" ",bandname+str(i)," agrees") except: print(" ",bandname+str(i)," disagrees") numerr+=1 print("toal number of tests failed =", numerr)
def main(args=sys.argv[1:]): if len(args) != 1: print("usage: raycorr-processor <SENSOR>") sys.exit(1) SENSOR = args[0] # SENSOR = 'OLCI' # SENSOR = 'MERIS' # PRODPATH = "C:\\Users\\carsten\\Dropbox\\Carsten\\SWProjects\\Rayleigh-Correction\\testdata\\" # AUXPATH = "C:\\Users\\carsten\\Dropbox\\Carsten\\Tagesordner\\20160104\\Rayleigh-Correction-Processor\\" # O3PATH="C:\\Users\\carsten\\Dropbox\\Carsten\\SWProjects\\Rayleigh-Correction\\raycorr\\" PRODPATH = "D:\\Dropbox\\Carsten\\SWProjects\\Rayleigh-Correction\\testdata\\" # AUXPATH = "D:\\Dropbox\\Carsten\\Tagesordner\\20160104\\Rayleigh-Correction-Processor\\" O3PATH="D:\\Dropbox\\Carsten\\SWProjects\\Rayleigh-Correction\\raycorr\\" DEMFactory = jpy.get_type('org.esa.snap.dem.dataio.DEMFactory') Resampling = jpy.get_type('org.esa.snap.core.dataop.resamp.Resampling') GeoPos = jpy.get_type('org.esa.snap.core.datamodel.GeoPos') if (SENSOR=='MERIS'): IN_FILE = PRODPATH+"subset_1_of_MER_RR__1PTACR20050713_094325_000002592039_00022_17611_0000.dim" OUT_FILE = PRODPATH+'Testprodukt1_MER_RR_20050713.dim' else: if (SENSOR=='OLCI'): IN_FILE = PRODPATH+'subset_3_of_S3A_OL_1_EFR____20160509T103945_20160509T104245_20160509T124907_0180_004_051_1979_SVL_O_NR_001.dim' OUT_FILE = PRODPATH+'Testproduct3_OL_1_EFR____20160509T103945.dim' else: print("Sensor ",SENSOR," not supported - exit") return file = IN_FILE # AUX_FILE = AUXPATH+'ADF\\MER_ATP_AXVACR20091026_144725_20021224_121445_20200101_000000' # adf = ADF(AUX_FILE) # ray_coeff_matrix = adf.ray_coeff_matrix # rayADF = readRayADF(AUX_FILE) # new_aux = OrderedDict() # new_aux['tau_ray'] = rayADF['tR'] # new_aux['theta'] = rayADF['theta'] # new_aux['ray_albedo_lut'] = rayADF['rayAlbLUT'] # new_aux['ray_coeff_matrix'] = ray_coeff_matrix # with open('raycorr_auxdata.json', 'w') as fp: # json.dumps(new_aux, fp, cls=JSONNumpyEncoder, indent=2) # fp.close() with open('../test/raycorr_auxdata.json', 'r') as fp: obj = json.load(fp, object_hook=json_as_numpy) # json_str = json.dumps(new_aux, cls=JSONNumpyEncoder, indent=2) # print(json_str) # obj = json.loads(json_str, object_hook=json_as_numpy) # rayADF = new_aux rayADF = obj ray_coeff_matrix=rayADF['ray_coeff_matrix'] print("Reading...") product = ProductIO.readProduct(file) width = product.getSceneRasterWidth() height = product.getSceneRasterHeight() name = product.getName() description = product.getDescription() band_names = product.getBandNames() print("Sensor: %s" % SENSOR) print("Product: %s, %s" % (name, description)) print("Raster size: %d x %d pixels" % (width, height)) print("Start time: " + str(product.getStartTime())) print("End time: " + str(product.getEndTime())) print("Bands: %s" % (list(band_names))) raycorProduct = Product('RayCorr', 'RayCorr', width, height) writer = ProductIO.getProductWriter('BEAM-DIMAP') raycorProduct.setProductWriter(writer) if (SENSOR == 'MERIS'): nbands = product.getNumBands() - 2 # the last 2 bands are l1flags and detector index; we don't need them band_name = ["radiance_1"] for i in range(1,nbands): band_name += ["radiance_" + str(i+1)] if (SENSOR == 'OLCI'): nbands = 21 band_name = ["Oa01_radiance"] sf_name = ["solar_flux_band_1"] for i in range(1,nbands): if (i < 9): band_name += ["Oa0" + str(i + 1) + "_radiance"] sf_name += ["solar_flux_band_" + str(i + 1)] else: band_name += ["Oa" + str(i + 1) + "_radiance"] sf_name += ["solar_flux_band_" + str(i + 1)] # Create TOA reflectance and Rayleig optical thickness bands for i in range(nbands): # bsource = product.getBandAt(i) bsource = product.getBand(band_name[i]) btoa_name = "rtoa_" + str(i + 1) toareflBand = raycorProduct.addBand(btoa_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, toareflBand) btaur_name = "taur_" + str(i + 1) taurBand = raycorProduct.addBand(btaur_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, taurBand) brhor_name = "rRay_" + str(i + 1) rhorBand = raycorProduct.addBand(brhor_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, rhorBand) # Fourier Terms, during debugging only brhorF1_name = "rRayF1_" + str(i + 1) rhorF1Band = raycorProduct.addBand(brhorF1_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, rhorF1Band) brhorF2_name = "rRayF2_" + str(i + 1) rhorF2Band = raycorProduct.addBand(brhorF2_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, rhorF2Band) brhorF3_name = "rRayF3_" + str(i + 1) rhorF3Band = raycorProduct.addBand(brhorF3_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, rhorF3Band) rayTransS_name = "transSRay_" + str(i + 1) rayTransSBand = raycorProduct.addBand(rayTransS_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, rayTransSBand) rayTransV_name = "transVRay_" + str(i + 1) rayTransVBand = raycorProduct.addBand(rayTransV_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, rayTransVBand) sARay_name = "sARay_" + str(i + 1) sARayBand = raycorProduct.addBand(sARay_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, sARayBand) rtoaR_name = "rtoaRay_" + str(i + 1) rtoaRBand = raycorProduct.addBand(rtoaR_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, rtoaRBand) rBRR_name = "rBRR_" + str(i + 1) rBRRBand = raycorProduct.addBand(rBRR_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, rBRRBand) spf_name = "sphericalAlbedoFactor_" + str(i + 1) spfBand = raycorProduct.addBand(spf_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, spfBand) # simple Rayleigh reflectance (Roland's formular) rRaySimple_name = "RayleighSimple_" + str(i + 1) rRaySimpleBand = raycorProduct.addBand(rRaySimple_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, rRaySimpleBand) # gaseous absorption corrected TOA reflectances rho_ng_name = "rtoa_ng_" + str(i + 1) rho_ngBand = raycorProduct.addBand(rho_ng_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, rho_ngBand) # simple Rayleigh optical thickness, for debugging taurS_name = "taurS_" + str(i + 1) taurSBand = raycorProduct.addBand(taurS_name, ProductData.TYPE_FLOAT32) ProductUtils.copySpectralBandProperties(bsource, taurSBand) raycorProduct.setAutoGrouping( 'rtoa:taur:rRay:rRayF1:rRayF2:rRayF3:transSRay:transVRay:sARay:rtoaRay:rBRR:sphericalAlbedoFactor:RayleighSimple:rtoa_ng:taurS') airmassBand = raycorProduct.addBand('airmass', ProductData.TYPE_FLOAT32) azidiffBand = raycorProduct.addBand('azidiff', ProductData.TYPE_FLOAT32) altBand = raycorProduct.addBand('altitude', ProductData.TYPE_FLOAT32) # Create flag coding raycorFlagsBand = raycorProduct.addBand('raycor_flags', ProductData.TYPE_UINT8) raycorFlagCoding = FlagCoding('raycor_flags') raycorFlagCoding.addFlag("testflag_1", 1, "Flag 1 for Rayleigh Correction") raycorFlagCoding.addFlag("testflag_2", 2, "Flag 2 for Rayleigh Correction") group = raycorProduct.getFlagCodingGroup() group.add(raycorFlagCoding) raycorFlagsBand.setSampleCoding(raycorFlagCoding) # add geocoding and create the product on disk (meta data, empty bands) ProductUtils.copyGeoCoding(product, raycorProduct) #geocoding is copied when tie point grids are copied, ProductUtils.copyTiePointGrids(product, raycorProduct) raycorProduct.writeHeader(OUT_FILE) # Calculate and write toa reflectances and Rayleigh optical thickness # =================================================================== # some stuff needed to get the altitude from an external DEM; can be omitted if altitude is used from the product # resamplingMethod = 'NEAREST_NEIGHBOUR' # Resampling.NEAREST_NEIGHBOUR.getName() resamplingMethod = Resampling.NEAREST_NEIGHBOUR.getName() demName = 'GETASSE30' # alternative 'SRTM 3Sec' dem = DEMFactory.createElevationModel(demName, resamplingMethod) # constants AVO = 6.0221367E+23 # Avogadro's number m_a_zero = 28.9595 # Mean molecular weight of dry ait (zero CO2) g0_45 = 980.616 # Acceleration of gravity (sea level and 458 latitude) Ns = 2.5469E19 # Molecular density of gas in molecules / cm3 # constants describing the state of the atmosphere and which we don't know; better values may be used if known CO2 = 3.E-4 # CO2 concentration at pixel; typical values are 300 to 360 ppm C_CO2 = CO2 * 100 # CO2 concentration in ppm m_a = 15.0556 * CO2 + m_a_zero # mean molecular weight of dry air as function of actual CO2 # other constants PA = 0.9587256 # Rayleigh Phase function, molecular asymetry factor 1 PB = 1. - PA # Rayleigh Phase function, molecular asymetry factor 2 tpoly = rayADF['tau_ray'] # Polynomial coefficients for Rayleigh transmittance h2o_cor_poly = np.array( [0.3832989, 1.6527957, -1.5635101, 0.5311913]) # Polynomial coefficients for WV transmission @ 709nm # absorb_ozon = np.array([0.0, 0.0002174, 0.0034448, 0.0205669, 0.0400134, 0.105446, 0.1081787, 0.0501634, 0.0410249, \ # 0.0349671, 0.0187495, 0.0086322, 0.0, 0.0, 0.0, 0.0084989, 0.0018944, 0.0012369, 0.0, 0.0, 0.0000488]) # OLCI # absorb_ozon = np.array([0.0002174, 0.0034448, 0.0205669, 0.0400134, 0.105446, 0.1081787, 0.0501634, \ # 0.0349671, 0.0187495, 0.0086322, 0.0, 0.0084989, 0.0018944, 0.0012369, 0.0]) # MERIS O3_FILE = O3PATH+'ozone-highres.txt' ozoneO = O3(O3_FILE) absorb_ozon = ozoneO.convolveInstrument(SENSOR) # arrays which are needed to store some stuff E0 = np.zeros(width, dtype=np.float32) radiance = np.zeros(width, dtype=np.float32) reflectance = np.zeros((nbands, width), dtype=np.float32) taur = np.zeros((nbands, width), dtype=np.float32) sigma = np.zeros(nbands, dtype=np.float32) airmass = np.zeros(width, dtype=np.float32) azidiff = np.zeros(width, dtype=np.float32) PR = np.zeros(3, dtype=np.float32) # Fourier coefficients of the Rayleigh Phase function rho_Rf = np.zeros(3, dtype=np.float32) # Fourier terms of the Rayleigh primary scattering reflectance rho_Rm = np.zeros((3, nbands, width), dtype=np.float32) # Fourier terms of the Rayleigh scattering reflectance, corrected for multiple scattering rho_R = np.zeros((nbands, width), dtype=np.float32) # first approximation of Rayleigh reflectance rho_toaR = np.zeros((nbands, width), dtype=np.float32) # toa reflectance corrected for Rayleigh scattering rho_BRR = np.zeros((nbands, width), dtype=np.float32) # top of aerosol reflectance, which is equal to bottom of Rayleigh reflectance sphericalFactor = np.zeros((nbands, width), dtype=np.float32) # spherical Albedo Correction Factor (for testing only, can be integrated into the equation later) rRaySimple = np.zeros((nbands, width), dtype=np.float32) # simple Rayleigh reflectance formular, after Roland (for testing only) rho_ng = np.zeros((nbands, width), dtype=np.float32) # toa reflectance corrected for gaseous absorption (rho_ng = "rho no gas") X2 = np.zeros(width, dtype=np.float32) # temporary variable used for WV correction algorithm for gaseous absorption trans709 = np.zeros(width, dtype=np.float32) # WV transmission at 709nm, used for WV correction algorithm for gaseous absorption taurS = np.zeros((nbands, width), dtype=np.float32) # simple Rayleigh optical thickness, for debugging only if (SENSOR == 'MERIS'): dem_alt = 'dem_alt' atm_press = 'atm_press' ozone = 'ozone' latitude = 'latitude' longitude = 'longitude' sun_zenith = 'sun_zenith' view_zenith = 'view_zenith' sun_azimuth = 'sun_azimuth' view_azimuth = 'view_azimuth' # water vapour correction: # MERIS band 9 @ 709nm to be corrected; WV absorption 900nm = band 15, WV reference 885nm= band 14 b709 = 8 # the band to be corrected bWVRef = 13 # the reference reflectance outside WV absorption band bWV = 14 # the reflectance within the WV absorption band if (SENSOR == 'OLCI'): dem_alt = 'N/A' atm_press = 'sea_level_pressure' ozone = 'total_ozone' latitude = 'TP_latitude' longitude = 'TP_longitude' sun_zenith = 'SZA' view_zenith = 'OZA' sun_azimuth = 'SAA' view_azimuth = 'OAA' # water vapour correction: # OLCI band 11 @ 709nm, WV absorption 900nm = band 19, WV reference 885nm = band 18 b709 = 11 # the band to be corrected bWVRef=17 # the reference reflectance outside WV absorption band bWV=18 # the reference reflectance outside WV absorption band if (SENSOR == 'MERIS'): # check if this is required at all! tp_alt = product.getTiePointGrid(dem_alt) alt = np.zeros(width, dtype=np.float32) tp_press = product.getTiePointGrid(atm_press) press0 = np.zeros(width, dtype=np.float32) tp_ozone = product.getTiePointGrid(ozone) ozone = np.zeros(width, dtype=np.float32) tp_latitude = product.getTiePointGrid(latitude) lat = np.zeros(width, dtype=np.float32) tp_longitude = product.getTiePointGrid(longitude) lon = np.zeros(width, dtype=np.float32) tp_theta_s = product.getTiePointGrid(sun_zenith) theta_s = np.zeros(width, dtype=np.float32) tp_theta_v = product.getTiePointGrid(view_zenith) theta_v = np.zeros(width, dtype=np.float32) tp_azi_s = product.getTiePointGrid(sun_azimuth) azi_s = np.zeros(width, dtype=np.float32) tp_azi_v = product.getTiePointGrid(view_azimuth) azi_v = np.zeros(width, dtype=np.float32) # Rayleigh multiple scattering # - Coefficients LUT dimTheta = 12 dimThetaS = dimThetaV = dimTheta gridThetaS = rayADF['theta'] gridThetaV = rayADF['theta'] gridGeometry = [gridThetaS, gridThetaV] RayScattCoeffA = ray_coeff_matrix[:, :, :, 0] RayScattCoeffB = ray_coeff_matrix[:, :, :, 1] RayScattCoeffC = ray_coeff_matrix[:, :, :, 2] RayScattCoeffD = ray_coeff_matrix[:, :, :, 3] # - Fourier terms a = np.zeros(3, dtype=np.float32) b = np.zeros(3, dtype=np.float32) c = np.zeros(3, dtype=np.float32) d = np.zeros(3, dtype=np.float32) rayMultiCorr = np.zeros(3, dtype=np.float32) # Rayleigh transmittances and spherical albedo tR_thetaS = np.zeros((nbands, width), dtype=np.float32) # Rayleigh Transmittance sun - surface tR_thetaV = np.zeros((nbands, width), dtype=np.float32) # Rayleigh Transmittance surface - sun dimTaur = 17 taurTab = np.linspace(0.0, 1.0, num=dimTaur) rayAlb_f = interp1d(taurTab, rayADF['ray_albedo_lut']) sARay = np.zeros((nbands, width), dtype=np.float32) # Rayleigh spherical albedo print("Processing ...") # Calculate the Rayleigh cross section, which depends only on wavelength but not on air pressure for i in range(nbands): print("processing Rayleigh cross section of band", i) # b_source = product.getBandAt(i) b_source = product.getBand(band_name[i]) lam = b_source.getSpectralWavelength() # wavelength of band i in nm lam = lam / 1000.0 # wavelength in micrometer lam2 = lam / 10000.0 # wavelength in cm F_N2 = 1.034 + 0.000317 / (lam ** 2) # King factor of N2 F_O2 = 1.096 + 0.001385 / (lam ** 2) + 0.0001448 / (lam ** 4) # King factor of O2 F_air = (78.084 * F_N2 + 20.946 * F_O2 + 0.934 * 1 + C_CO2 * 1.15) / ( 78.084 + 20.946 + 0.934 + C_CO2) # depolarization ratio or King Factor, (6+3rho)/(6-7rho) n_ratio = 1 + 0.54 * (CO2 - 0.0003) n_1_300 = (8060.51 + (2480990. / (132.274 - lam ** (-2))) + (17455.7 / (39.32957 - lam ** (-2)))) / 100000000.0 nCO2 = n_ratio * (1 + n_1_300) # reflective index at CO2 sigma[i] = (24 * math.pi ** 3 * (nCO2 ** 2 - 1) ** 2) / (lam2 ** 4 * Ns ** 2 * (nCO2 ** 2 + 2) ** 2) * F_air for y in range(height): print("processing line ", y, " of ", height) # start radiance to reflectance conversion theta_s = tp_theta_s.readPixels(0, y, width, 1, theta_s) # sun zenith angle in degree for i in range(nbands): b_source = product.getBand(band_name[i]) radiance = b_source.readPixels(0, y, width, 1, radiance) if (SENSOR == 'MERIS'): E0.fill(b_source.getSolarFlux()) if (SENSOR == 'OLCI'): b_source = product.getBand(sf_name[i]) E0 = b_source.readPixels(0, y, width, 1, E0) reflectance[i] = radiance * math.pi / (E0 * np.cos(np.radians(theta_s))) b_out = raycorProduct.getBand("rtoa_" + str(i + 1)) b_out.writePixels(0, y, width, 1, reflectance[i]) # radiance to reflectance conversion completed # this is dummy code to create a flag flag1 = np.zeros(width, dtype=np.bool_) flag2 = np.zeros(width, dtype=np.bool_) raycorFlags = flag1 + 2 * flag2 raycorFlagsBand.writePixels(0, y, width, 1, raycorFlags) # end flags dummy code # raycorProduct.closeIO() # if (0==1): lat = tp_latitude.readPixels(0, y, width, 1, lat) lon = tp_longitude.readPixels(0, y, width, 1, lon) # start Rayleigh optical thickness calculation # alt = tp_alt.readPixels(0, y, width, 1, alt) # using the tie-point DEM in a MERIS product # get the altitude from an external DEM for x in range(width): alt[x] = dem.getElevation(GeoPos(lat[x], lon[x])) press0 = tp_press.readPixels(0, y, width, 1, press0) ozone = tp_ozone.readPixels(0, y, width, 1, ozone) theta_s = tp_theta_s.readPixels(0, y, width, 1, theta_s) # sun zenith angle in degree theta_v = tp_theta_v.readPixels(0, y, width, 1, theta_v) # view zenith angle in degree azi_s = tp_azi_s.readPixels(0, y, width, 1, azi_s) # sun azimuth angle in degree azi_v = tp_azi_v.readPixels(0, y, width, 1, azi_v) # view azimuth angle in degree # gaseous absorption correction rho_ng = reflectance # to start: gaseous corrected reflectances equals toa reflectances # water vapour correction: # MERIS band 9 @ 709nm to be corrected; WV absorption 900nm = band 15, WV reference 885nm= band 14 # b709 = 8 # the band to be corrected # bWVRef = 13 # the reference reflectance outside WV absorption band # bWV = 14 # the reflectance within the WV absorption band # OLCI band 11 @ 709nm, WV absorption 900nm = band 19, WV reference 885nm = band 18 # b709 = 11 # the band to be corrected # bWVRef=17 # the reference reflectance outside WV absorption band # bWV=18 # the reference reflectance outside WV absorption band for i in range(width): if (reflectance[(bWV, i)] > 0): X2[i] = reflectance[(bWV, i)] / reflectance[(bWVRef, i)] else: X2[i] = 1 trans709 = h2o_cor_poly[0] + (h2o_cor_poly[1] + (h2o_cor_poly[2] + h2o_cor_poly[3] * X2) * X2) * X2 rho_ng[b709] /= trans709 # ozone correction model_ozone = 0 for x in range(width): ts = math.radians(theta_s[x]) # sun zenith angle in radian cts = math.cos(ts) # cosine of sun zenith angle sts = math.sin(ts) # sinus of sun zenith angle tv = math.radians(theta_v[x]) # view zenith angle in radian ctv = math.cos(tv) # cosine of view zenith angle stv = math.sin(tv) # sinus of view zenith angle for i in range(nbands): trans_ozoned12 = math.exp(-(absorb_ozon[i] * ozone[x] / 1000.0 - model_ozone) / cts) trans_ozoneu12 = math.exp(-(absorb_ozon[i] * ozone[x] / 1000.0 - model_ozone) / ctv) trans_ozone12 = trans_ozoned12 * trans_ozoneu12 rho_ng[(i, x)] /= trans_ozone12 # here we can decide if we continue with gaseous corrected reflectances or not reflectance = rho_ng # Now calculate the pixel dependent terms (like pressure) and finally the Rayleigh optical thickness for x in range(width): # Calculation to get the pressure z = alt[x] # altitude at pixel in meters, taken from MERIS tie-point grid z = max(z, 0) # clip to sea level Psurf0 = press0[x] # pressure at sea level in hPa, taken from MERIS tie-point grid Psurf = Psurf0 * ( 1. - 0.0065 * z / 288.15) ** 5.255 # air pressure at the pixel (i.e. at altitude) in hPa, using the international pressure equation P = Psurf * 1000. # air pressure at pixel location in dyn / cm2, which is hPa * 1000 # calculation to get the constant of gravity at the pixel altitude, taking the air mass above into account dphi = math.radians(lat[x]) # latitude in radians cos2phi = math.cos(2 * dphi) g0 = g0_45 * (1 - 0.0026373 * cos2phi + 0.0000059 * cos2phi ** 2) zs = 0.73737 * z + 5517.56 # effective mass-weighted altitude g = g0 - (0.0003085462 + 0.000000227 * cos2phi) * zs + (0.00000000007254 + 0.0000000000001 * cos2phi) * \ zs ** 2 - (1.517E-17 + 6E-20 * cos2phi) * zs ** 3 # calculations to get the Rayeigh optical thickness factor = (P * AVO) / (m_a * g) for i in range(nbands): taur[(i, x)] = sigma[i] * factor # Calculate Rayleigh Phase function ts = math.radians(theta_s[x]) # sun zenith angle in radian cts = math.cos(ts) # cosine of sun zenith angle sts = math.sin(ts) # sinus of sun zenith angle tv = math.radians(theta_v[x]) # view zenith angle in radian ctv = math.cos(tv) # cosine of view zenith angle stv = math.sin(tv) # sinus of view zenith angle airmass[x] = 1 / cts + 1 / ctv # air mass # Rayleigh Phase function, 3 Fourier terms PR[0] = 3. * PA / 4. * (1. + cts ** 2 * ctv ** 2 + (sts ** 2 * stv ** 2) / 2.) + PB PR[1] = -3. * PA / 4. * cts * ctv * sts * stv PR[2] = 3. * PA / 16. * sts ** 2 * stv ** 2 # Calculate azimuth difference azs = math.radians(azi_s[x]) azv = math.radians(azi_v[x]) cosdeltaphi = math.cos(azv - azs) azidiff[x] = math.acos(cosdeltaphi) # azimuth difference in radian # Fourier components of multiple scattering for j in [0, 1, 2]: a[j] = interpn(gridGeometry, RayScattCoeffA[j, :, :], [theta_s[x], theta_v[x]], method='linear', bounds_error=False, fill_value=None) b[j] = interpn(gridGeometry, RayScattCoeffB[j, :, :], [theta_s[x], theta_v[x]], method='linear', bounds_error=False, fill_value=None) c[j] = interpn(gridGeometry, RayScattCoeffC[j, :, :], [theta_s[x], theta_v[x]], method='linear', bounds_error=False, fill_value=None) d[j] = interpn(gridGeometry, RayScattCoeffD[j, :, :], [theta_s[x], theta_v[x]], method='linear', bounds_error=False, fill_value=None) for i in range(nbands): # Fourier series, loop for j in [0, 1, 2]: # Rayleigh primary scattering rho_Rf[j] = (PR[j] / (4.0 * (cts + ctv))) * (1. - math.exp(-airmass[x] * taur[(i, x)])) # correction for multiple scattering rayMultiCorr[j] = a[j] + b[j] * taur[(i, x)] + c[j] * taur[(i, x)] ** 2 + d[j] * taur[(i, x)] ** 3 rho_Rm[(j, i, x)] = rho_Rf[j] * rayMultiCorr[j] # rho_Rm[(0, i, x)] = rho_Rf[0] # rho_Rm[(1, i, x)] = 0. # rho_Rm[(2, i, x)] = 0. # Fourier sum to get the Rayleigh Reflectance rho_R[(i, x)] = rho_Rm[(0, i, x)] + 2.0 * rho_Rm[(1, i, x)] * math.cos(azidiff[x]) + 2. * rho_Rm[ (2, i, x)] * math.cos(2. * azidiff[x]) # complete the Rayleigh correction: see MERIS DPM PDF-p251 or DPM 9-16 # polynomial coefficients tpoly0, tpoly1 and tpoly2 from MERIS LUT tRs = ((2. / 3. + cts) + (2. / 3. - cts) * math.exp(-taur[(i, x)] / cts)) / (4. / 3. + taur[(i, x)]) tR_thetaS[(i, x)] = tpoly[0] + tpoly[1] * tRs + tpoly[ 2] * tRs ** 2 # Rayleigh Transmittance sun - surface tRv = ((2. / 3. + ctv) + (2. / 3. - ctv) * math.exp(-taur[(i, x)] / ctv)) / (4. / 3. + taur[(i, x)]) tR_thetaV[(i, x)] = tpoly[0] + tpoly[1] * tRv + tpoly[ 2] * tRv ** 2 # Rayleigh Transmittance surface - sensor sARay[(i, x)] = rayAlb_f(taur[(i, x)]) # Rayleigh spherical albedo rho_toaR[(i, x)] = (reflectance[(i, x)] - rho_R[(i, x)]) / ( tR_thetaS[(i, x)] * tR_thetaV[(i, x)]) # toa reflectance corrected for Rayleigh scattering sphericalFactor[(i, x)] = 1.0 / (1.0 + sARay[(i, x)] * rho_toaR[ (i, x)]) # factor used in the next equation to account for the spherical albedo rho_BRR[(i, x)] = rho_toaR[(i, x)] * sphericalFactor[ (i, x)] # top of aerosol reflectance, which is equal to bottom of Rayleigh reflectance # simple Rayleigh correction azi_diff_deg = math.fabs(azi_v[x] - azi_s[x]) if (azi_diff_deg > 180.0): azi_diff_deg = 360.0 - azi_diff_deg azi_diff_rad = math.radians(azi_diff_deg) cos_scat_ang = (-ctv * cts) - (stv * sts * math.cos(azi_diff_rad)) phase_rayl_min = 0.75 * (1.0 + cos_scat_ang * cos_scat_ang) for i in range(nbands): # b_source = product.getBandAt(i) b_source = product.getBand(band_name[i]) lam = b_source.getSpectralWavelength() taurS[(i, x)] = math.exp(-4.637) * math.pow((lam / 1000.0), -4.0679) pressureAtms = press0[x] * math.exp(-alt[x] / 8000.0) pressureFactor = taurS[(i, x)] / 1013.0 taurS[(i, x)] = pressureAtms * pressureFactor rRaySimple[(i, x)] = cts * taurS[(i, x)] * phase_rayl_min / (4 * 3.1415926) * (1 / ctv) * 3.1415926 # Write bands to product airmassBand.writePixels(0, y, width, 1, airmass) azidiffBand.writePixels(0, y, width, 1, azidiff) altBand.writePixels(0, y, width, 1, alt) for i in range(nbands): taurBand = raycorProduct.getBand("taur_" + str(i + 1)) taurBand.writePixels(0, y, width, 1, taur[i]) rhorBand = raycorProduct.getBand("rRay_" + str(i + 1)) rhorBand.writePixels(0, y, width, 1, rho_R[i]) rhorF1Band = raycorProduct.getBand("rRayF1_" + str(i + 1)) rhorF1Band.writePixels(0, y, width, 1, rho_Rm[0, i]) rhorF2Band = raycorProduct.getBand("rRayF2_" + str(i + 1)) rhorF2Band.writePixels(0, y, width, 1, rho_Rm[1, i]) rhorF3Band = raycorProduct.getBand("rRayF3_" + str(i + 1)) rhorF3Band.writePixels(0, y, width, 1, rho_Rm[2, i]) rayTransSBand = raycorProduct.getBand("transSRay_" + str(i + 1)) rayTransSBand.writePixels(0, y, width, 1, tR_thetaS[i]) rayTransVBand = raycorProduct.getBand("transVRay_" + str(i + 1)) rayTransVBand.writePixels(0, y, width, 1, tR_thetaV[i]) sARayBand = raycorProduct.getBand("sARay_" + str(i + 1)) sARayBand.writePixels(0, y, width, 1, sARay[i]) rtoaRBand = raycorProduct.getBand("rtoaRay_" + str(i + 1)) rtoaRBand.writePixels(0, y, width, 1, rho_toaR[i]) rBRRBand = raycorProduct.getBand("rBRR_" + str(i + 1)) rBRRBand.writePixels(0, y, width, 1, rho_BRR[i]) spfBand = raycorProduct.getBand("sphericalAlbedoFactor_" + str(i + 1)) spfBand.writePixels(0, y, width, 1, sphericalFactor[i]) rRaySimpleBand = raycorProduct.getBand("RayleighSimple_" + str(i + 1)) rRaySimpleBand.writePixels(0, y, width, 1, rRaySimple[i]) rho_ngBand = raycorProduct.getBand("rtoa_ng_" + str(i + 1)) rho_ngBand.writePixels(0, y, width, 1, rho_ng[i]) taurSBand = raycorProduct.getBand("taurS_" + str(i + 1)) taurSBand.writePixels(0, y, width, 1, taurS[i]) # Rayleigh calculation completed raycorProduct.closeIO() print("Done.")
import sys from snappy import ProductIO from snappy import GPF from snappy import jpy if len(sys.argv) != 2: print("usage: %s <file>" % sys.argv[0]) sys.exit(1) file = sys.argv[1] print("Reading...") product = ProductIO.readProduct(file) width = product.getSceneRasterWidth() height = product.getSceneRasterHeight() name = product.getName() description = product.getDescription() band_names = product.getBandNames() print("Product: %s, %d x %d pixels, %s" % (name, width, height, description)) print("Bands: %s" % (list(band_names))) GPF.getDefaultInstance().getOperatorSpiRegistry().loadOperatorSpis() HashMap = jpy.get_type('java.util.HashMap') BandDescriptor = jpy.get_type('org.esa.snap.core.gpf.common.BandMathsOp$BandDescriptor') targetBand1 = BandDescriptor() targetBand1.name = 'band_1'
import numpy from snappy import Product from snappy import ProductData from snappy import ProductIO from snappy import ProductUtils from snappy import FlagCoding if len(sys.argv) != 2: print("usage: %s <file>" % sys.argv[0]) sys.exit(1) file = sys.argv[1] print("Reading...") product = ProductIO.readProduct(file) width = product.getSceneRasterWidth() height = product.getSceneRasterHeight() name = product.getName() description = product.getDescription() band_names = product.getBandNames() print("Product: %s, %s" % (name, description)) print("Raster size: %d x %d pixels" % (width, height)) print("Start time: " + str(product.getStartTime())) print("End time: " + str(product.getEndTime())) print("Bands: %s" % (list(band_names))) b7 = product.getBand('radiance_7') b10 = product.getBand('radiance_10')
print 'Product file and band index required' sys.exit(1) # check if band index given is correct if not sys.argv[2] in ['2', '3', '4', '8']: print 'Incorrect band index' # get cli arguments product_file = sys.argv[1] band_index = sys.argv[2] band_name = 'B' + band_index product_name = { 'B2': 'blue', 'B3': 'green', 'B4': 'red', 'B8': 'nir', }[band_name] # input product: open and get dimensions & name input_product = ProductIO.readProduct(product_file) product_width = input_product.getSceneRasterWidth() product_height = input_product.getSceneRasterHeight() product_name = input_product.getName() # output product: copy selected band & save product output_product = Product(product_name, product_name, product_width, product_height) ProductUtils.copyGeoCoding(input_product, output_product) ProductUtils.copyBand(band_name, input_product, output_product, True) ProductIO.writeProduct(output_product, product_name + '.band.dim', 'BEAM-DIMAP') output_product.closeIO()