def calculateFrequency(inFiles, extent): masks_fused = [] for mask_OPT in inFiles: jointExt = rsu.getJointExtent(mask_OPT, AOIextent=extent) watermask_opt, geotrans = rsu.raster2array(mask_OPT, jointExt)[:2] if watermask_opt.shape[1] < extent.ncol or watermask_opt.shape[ 0] < extent.nrow: watermask_opt = rsu.padArray(watermask_opt, geotrans, extent) masks_fused.append(watermask_opt) masks = np.array(masks_fused).astype("uint8") # Number of valid observations validobs = np.nansum(masks != 255, axis=0).astype("float32") # Number of water/wetness detections Sum = np.nansum(masks == 1, axis=0).astype("float32") # Water/wet frequency #Freq = Sum / validobs # Replace NAN Sum = np.where(validobs == 0, np.nan, Sum) #Freq = np.where(validobs==0, np.nan, Freq) del masks return (Sum, validobs)
# START PROCESSING ----------------------------------------------------------------------------------------------- # Find optical water mask files watermask_files = fnmatch.filter(os.listdir(path_watermasks_opt), "*water_mask.tif") if len(watermask_files) == 0: if not DEBUG: raise GeoAlgorithmExecutionException( "Invalid input parameters: 'Start date' must be earlier than 'End date'." ) else: print("Invalid input data: No optical water masks found.") sys.exit(1) # Read optical maximum watermask as nparray geotrans_opt, proj_str_opt = rsu.raster2array(path_watermask_opt_max)[1:3] # SAR --------------------------------------------------------------------------------------- # Check projection source_sar = gdal.Open(path_watermask_sar) proj_sar = osr.SpatialReference() proj_sar.ImportFromWkt(source_sar.GetProjection()) pix_size_sar = source_sar.GetGeoTransform()[1] proj_opt = osr.SpatialReference() proj_opt.ImportFromWkt(proj_str_opt) # Reproject SAR water mask if necessary if not proj_sar.IsSame(proj_opt) or (geotrans_opt[1] != pix_size_sar): path_watermask_sar_reprojected = path_watermask_sar[:-4] + "_reprojected.tif" if not os.path.exists(path_watermask_sar_reprojected):
out_dir = os.path.dirname(path_TWI) print out_dir attrName = None attrVal = None extentBuffer = 0 # Create TWI binary mask ------------------------------------------------ outfile_binary = os.path.join(out_dir, "TWIbinary.tif") if not DEBUG: progress.setText("Creating binary mask ...") # Median filter TWI, geotrans, proj = rsu.raster2array(path_TWI) TWI = ndimage.median_filter(TWI, size=7) * 1000 path_TWI_filtered = path_TWI[:-4] + "_TWIfiltered.tif" x = rsu.array2raster(TWI, geotrans, proj, path_TWI_filtered, gdal.GDT_Float32, -9999) if x == False: raise RuntimeError("Exporting TWI failed.") # Normalize TWI TWI = (TWI - np.nanpercentile(TWI, 1)) / (np.nanpercentile(TWI, 99) - np.nanpercentile(TWI, 1)) # Create TWI mask TWI_binary = np.where(TWI > 0.4, 0, 1)
] # Check whether masks exist if len(watermask_files) == 0: if not DEBUG: raise GeoAlgorithmExecutionException("No water masks found") else: print("No water masks found.") else: print("Found " + str(len(watermask_files)) + " water mask files.\n") if not DEBUG: feedback.setProgressText("Found " + str(len(watermask_files)) + " water mask files.\n") # Get joint extent of all watermasks joint_extent = rsu.getJointExtent(watermask_files) geotrans, proj = rsu.raster2array(watermask_files[0], joint_extent)[1:3] # CALCULATE WATER FREQUENCY ---------------------------------------------------------------------------------------- if not DEBUG: feedback.setProgressText("Calculating water frequency ...") # Read in watermasks watermasks = [] for wm_file in watermask_files: # Extract date of water mask from file name dateidx = wm_file.find("_d") + 2 watermask_date = dt.datetime.strptime(wm_file[dateidx:dateidx + 8], "%Y%m%d") # Filter water mask files by dates
def calculate_indices_for_scene(scene, output_dir, bandNo, extent_AOI=None, WCRonly=False): """ Calculates spectral indices for a Sentinel or Landsat scene :param scene: Object of class 'Scene' :param output_dir: (string) Path to output directory :param bandNo: (list) List of spectral band numbers that are used for index calculations :param extent_AOI: (list) Parameters of extent of AOI :param calculate_wetness_indices: (boolean) If True water and wetness indices are calculated, if False only water indices :return: """ NODATA = -9999 # Check output directory if not os.path.exists(output_dir): os.mkdir(output_dir) output_name = scene.sensorCode + "_" + scene.tileID + "_" + dt.datetime.strftime(scene.date, "%Y%m%d") # Read in bands with clouds masked out bands = [] for b in bandNo: bands.append(scene.getBand(b, masked=True)) bands = np.array(bands) # Check bands for invalid values and set them to NAN #invalid_pixels = np.nansum(np.isnan(bands), axis=0) #bands = np.where(invalid_pixels > 0, np.nan, bands).astype("float32") print("NDVI") dest = os.path.join(output_dir, "NDVI", output_name + "_NDVI.tif") if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) NDVI = ((bands[3] - bands[2]) / (bands[3] + bands[2])) * 5000. + 5000. if (NDVI.shape[1] < extent_AOI.ncol) or (NDVI.shape[0] < extent_AOI.nrow): NDVI = rsu.padArray(NDVI, scene.geotrans, scene.proj, extent_AOI) # Save to file res = rsu.array2raster(NDVI, extent_AOI.getGeotrans(), extent_AOI.getProj(), dest, gdal.GDT_Int16, NODATA) if res != True: if not DEBUG: raise GeoAlgorithmExecutionException(res) else: print(res) sys.exit(1) del NDVI dest = os.path.join(output_dir, "NDWI", output_name + "_NDWI.tif") # if not os.path.exists(dest): print("NDWI") if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) NDWI = ((bands[1] - bands[3]) / (bands[1] + bands[3])) * 5000. + 5000. if (NDWI.shape[1] < extent_AOI.ncol) or (NDWI.shape[0] < extent_AOI.nrow): NDWI = rsu.padArray(NDWI, scene.geotrans, scene.proj, extent_AOI) # Save to file res = rsu.array2raster(NDWI, extent_AOI.getGeotrans(), extent_AOI.getProj(), dest, gdal.GDT_Int16, NODATA) if res != True: if not DEBUG: raise GeoAlgorithmExecutionException(res) else: print(res) sys.exit(1) del NDWI dest = os.path.join(output_dir, "mNDWI", output_name + "_mNDWI.tif") # if not os.path.exists(dest): print("mNDWI") if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) MNDWI = ((bands[1] - bands[4]) / (bands[1] + bands[4])) * 5000. + 5000. if (MNDWI.shape[1] < extent_AOI.ncol) or (MNDWI.shape[0] < extent_AOI.nrow): MNDWI = rsu.padArray(MNDWI, scene.geotrans, scene.proj, extent_AOI) # Save to file res = rsu.array2raster(MNDWI, extent_AOI.getGeotrans(), extent_AOI.getProj(), dest, gdal.GDT_Int16, NODATA) if res != True: if not DEBUG: raise GeoAlgorithmExecutionException(res) else: print(res) sys.exit(1) del MNDWI if not WCRonly: print("NDMI") dest = os.path.join(output_dir, "NDMI", output_name + "_NDMI.tif") if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) NDMI = ((bands[3] - bands[4]) / (bands[3] + bands[4])) * 5000. + 5000. if (NDMI.shape[1] < extent_AOI.ncol) or (NDMI.shape[0] < extent_AOI.nrow): NDMI = rsu.padArray(NDMI, scene.geotrans, scene.proj, extent_AOI) # Save to file res = rsu.array2raster(NDMI, extent_AOI.getGeotrans(), extent_AOI.getProj(), dest, gdal.GDT_Int16, NODATA) if res != True: if not DEBUG: raise GeoAlgorithmExecutionException(res) else: print(res) sys.exit(1) del NDMI print("ND0206") dest = os.path.join(output_dir, "ND0206", output_name + "_ND0206.tif") if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) ND0206 = ((bands[1] - bands[5]) / (bands[1] + bands[5])) * 5000. + 5000. if (ND0206.shape[1] < extent_AOI.ncol) or (ND0206.shape[0] < extent_AOI.nrow): ND0206 = rsu.padArray(ND0206, scene.geotrans, scene.proj, extent_AOI) # Save to file res = rsu.array2raster(ND0206, extent_AOI.getGeotrans(), extent_AOI.getProj(), dest, gdal.GDT_Int16, NODATA) if res != True: if not DEBUG: raise GeoAlgorithmExecutionException(res) else: print(res) sys.exit(1) del ND0206 print("ND0406") dest = os.path.join(output_dir, "ND0406", output_name + "_ND0406.tif") if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) ND0406 = ((bands[3] - bands[5]) / (bands[3] + bands[5])) * 5000. + 5000. if (ND0406.shape[1] < extent_AOI.ncol) or (ND0406.shape[0] < extent_AOI.nrow): ND0406 = rsu.padArray(ND0406, scene.geotrans, scene.proj, extent_AOI) # Save to file res = rsu.array2raster(ND0406, extent_AOI.getGeotrans(), extent_AOI.getProj(), dest, gdal.GDT_Int16, NODATA) if res != True: if not DEBUG: raise GeoAlgorithmExecutionException(res) else: print(res) sys.exit(1) del ND0406 print("NMDI") dest = os.path.join(output_dir, "NMDI", output_name + "_NMDI.tif") if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) NMDI = ((bands[3] - (bands[4] - bands[5])) / (bands[3] + (bands[4] - bands[5]))) * 10000. if (NMDI.shape[1] < extent_AOI.ncol) or (NMDI.shape[0] < extent_AOI.nrow): NMDI = rsu.padArray(NMDI, scene.geotrans, scene.proj, extent_AOI) # Save to file res =rsu.array2raster(NMDI, extent_AOI.getGeotrans(), extent_AOI.getProj(), dest, gdal.GDT_Int16, NODATA) if res != True: if not DEBUG: raise GeoAlgorithmExecutionException(res) else: print(res) sys.exit(1) del NMDI # Band lengths f_nir = 8300 f_swir1 = 16500 f_swir2 = 20180 dest = os.path.join(output_dir, "ABDI1", output_name + "_ABDI1.tif") print("ABDI1") if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) ABDI1 = (bands[3] * np.arctan((bands[3] - bands[4]) / (f_swir1 - f_nir))) if (ABDI1.shape[1] < extent_AOI.ncol) or (ABDI1.shape[0] < extent_AOI.nrow): ABDI1 = rsu.padArray(ABDI1, scene.geotrans, scene.proj, extent_AOI) res = rsu.array2raster(ABDI1, extent_AOI.getGeotrans(), extent_AOI.getProj(), dest, gdal.GDT_Int16, NODATA) if res != True: if not DEBUG: raise GeoAlgorithmExecutionException(res) else: print(res) sys.exit(1) del ABDI1 print("ABDI2") dest = os.path.join(output_dir, "ABDI2", output_name + "_ABDI2.tif") if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) ABDI2 = (bands[3] * np.arctan((bands[3] - bands[5]) / (f_swir2 - f_nir))) if (ABDI2.shape[1] < extent_AOI.ncol) or (ABDI2.shape[0] < extent_AOI.nrow): ABDI2 = rsu.padArray(ABDI2, scene.geotrans, scene.proj, extent_AOI) res = rsu.array2raster(ABDI2, extent_AOI.getGeotrans(), extent_AOI.getProj(), dest, gdal.GDT_Int16, NODATA) if res != True: if not DEBUG: raise GeoAlgorithmExecutionException(res) else: print(res) sys.exit(1) del ABDI2 return True
# Update progress bar if not DEBUG: progress.setText("Searching for %s scenes in imagery directory ..." % sensor) # CREATE SCENES OBJECTS FROM FOUND SCENE DIRECTORIES ------------------------------------------------------------- scenes = [] for sD in scene_dirs_IDs: # Update progress bar if not DEBUG: progress.setText("\n%s - %s" % (sD[0], sD[1])) try: # Create scene objects if sensor == "Landsat": new_scene = rsu.LandsatScene(sD[0], ID=sD[1]) elif sensor == "Sentinel": new_scene = rsu.SentinelScene(sD[0], ID=sD[1]) if tile_ID is None or (tile_ID in new_scene.tileID): scenes.append(new_scene) else: if not DEBUG: progress.setText("Scene not included: Tile ID doesn't match %s." % tile_ID) except IOError as e: if not DEBUG: progress.setText("WARNING: Scene is skipped. (%s)" % (e)) else: print("WARNING: Scene skipped. (%s)" % (e)) except Exception as e:
# Check whether masks exist if len(watermask_files) == 0: if not DEBUG: raise GeoAlgorithmExecutionException("No water masks found") else: print("No water masks found.") else: print("Found " + str(len(watermask_files)) + " water mask files.\n") if not DEBUG: feedback.setProgressText( "Found " + str(len(watermask_files)) + " water mask files.\n" ) feedback.setProgressText("\n".join(watermask_files)) # Get joint extent of all watermasks joint_extent = rsu.getJointExtent(watermask_files) geotrans, proj = rsu.raster2array(watermask_files[0], joint_extent)[1:3] # CALCULATE WATER FREQUENCY ---------------------------------------------------------------------------------------- if not DEBUG: feedback.setProgressText("Calculating water frequency ...") # Read in watermasks watermasks = [] for wm_file in watermask_files: # Extract date of water mask from file name dateidx = wm_file.find("_d") + 2 watermask_date = dt.datetime.strptime(wm_file[dateidx : dateidx + 8], "%Y%m%d") # Filter water mask files by dates
# START PROCESSING ----------------------------------------------------------------------------------------------- # Find optical water mask files watermask_files = fnmatch.filter(os.listdir(path_masks_opt), "*water_mask.tif") if len(watermask_files) == 0: if not DEBUG: raise GeoAlgorithmExecutionException( "Invalid input parameters: 'Start date' must be earlier than 'End date'." ) else: print("Invalid input data: No optical water masks found.") sys.exit(1) # Read optical maximum watermask as nparray geotrans_opt, proj_str_opt = rsu.raster2array(path_watermask_opt_max)[1:3] # SAR --------------------------------------------------------------------------------------- # Check projection source_sar = gdal.Open(path_water_freq_sar) proj_sar = osr.SpatialReference() proj_sar.ImportFromWkt(source_sar.GetProjection()) pix_size_sar = source_sar.GetGeoTransform()[1] proj_opt = osr.SpatialReference() proj_opt.ImportFromWkt(proj_str_opt) # Reproject SAR water mask if necessary if not proj_sar.IsSame(proj_opt) or (geotrans_opt[1] != pix_size_sar): # Reproject water frequency
# Median filter #TWI, geotrans, proj = rsu.raster2array(path_TWI) #TWI_smooth = ndimage.median_filter(TWI, size=7) * 1000 #dest = os.path.join(out_dir, "TWI.tif") #rsu.array2raster(TWI_smooth, geotrans, proj, dest, gdal.GDT_Int16, -9999) # Read TWI file TWI_file = gdal.Open(path_TWI) TWI = TWI_file.GetRasterBand(1).ReadAsArray() nodata_TWI = TWI_file.GetRasterBand(1).GetNoDataValue() TWI = np.where(TWI == nodata_TWI, np.nan, TWI) # Find threshold TWI = (TWI - np.nanmin(TWI)) / (np.nanmax(TWI) - np.nanmin(TWI)) TWI_binary = np.where(TWI > 0.4, 0, 1) #Sieve mask TWI_binary = rsu.removeNoise(TWI_binary, 2) TWI_binary = rsu.binaryBuffer_negative(TWI_binary, 3) #Export to file x = rsu.array2raster(TWI_binary, TWI_file.GetGeoTransform(), TWI_file.GetProjection(), outfile_binary, gdal.GDT_Byte, 255) if x == False: print("Exporting TWI mask failed.") raise RuntimeError("Exporting TWI mask failed.") del TWI_file, TWI_binary, TWI
if not debug: raise GeoAlgorithmExecutionException("No water masks found") else: print("No water masks found.") else: print("Found " + str(len(waterMaskFiles)) + " water mask files.\n") if len(wetMaskFiles) == 0: if not debug: raise GeoAlgorithmExecutionException("No wetness masks found") else: print("No wetness masks found.") else: print("Found " + str(len(wetMaskFiles)) + " wet mask files.\n") jointExtent = rsu.getJointExtent(waterMaskFiles) geotrans, proj = rsu.raster2array(waterMaskFiles[0], jointExtent)[1:3] waterFreqs = [] validPixels = [] validPixels_wet = [] wetFreqs = [] seasons = [["winter", [12, 1, 2], winter], ["spring", [3, 4, 5], spring], ["summer", [6, 7, 8], summer], ["fall", [9, 10, 11], fall]] for season in seasons: if not season[2]: continue print(season[0])
def calculate_indices_for_scene(scene, outputDir, bandNo, extentAOI=None, WCRonly=False): # Output directory if not os.path.exists(outputDir): os.mkdir(outputDir) # Make file title outputName = scene.sensorCode + "_" + scene.tileID + "_" + dt.datetime.strftime( scene.date, "%Y%m%d") # Read in bands bands = [] for b in bandNo: bands.append(scene.getBand(b, masked=True)) # Band minimum value #minimum = abs(min(0, np.nanmin(bands)))# + 10 #bands = [band + minimum for band in bands] bands = np.array(bands) invalidPixels = np.nansum(np.isnan(bands) | (bands == 0), axis=0) bands = np.where(invalidPixels > 0, np.nan, bands) # Assign arrays to spectral bands # BLUE = bands[0].astype("float32") GREEN = bands[1].astype("float32") RED = bands[2].astype("float32") NIR = bands[3].astype("float32") SWIR1 = bands[4].astype("float32") SWIR2 = bands[5].astype("float32") NAN = np.where(np.isnan(bands) | (bands == 0), 1, 0) mask = np.where(np.nansum(NAN, axis=0) > 0, 1, 0) if (mask.shape[1] < extentAOI.ncol) or (mask.shape[0] < extentAOI.nrow): mask = rsu.padArray(mask, scene.geotrans, scene.proj, extentAOI) nodata = -9999 del bands # NDVI - Normalized Difference Vegetation Index (NIR-RED/NIR+RED) dest = os.path.join(outputDir, "NDVI", outputName + "_NDVI.tif") # if not os.path.exists(dest): if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) print("NDVI") NDVI = ((NIR - RED) / (NIR + RED)) * 5000. + 5000. if (NDVI.shape[1] < extentAOI.ncol) or (NDVI.shape[0] < extentAOI.nrow): NDVI = rsu.padArray(NDVI, scene.geotrans, scene.proj, extentAOI) # Save to NDVI to file NDVI = np.where(mask == 1, nodata, NDVI) rsu.array2raster(NDVI, extentAOI.getGeotrans(), extentAOI.getProj(), dest, gdal.GDT_Int16, nodata) del NDVI # NDWI (McFeeters, 1996) and Normalized Difference Water Index dest = os.path.join(outputDir, "NDWI", outputName + "_NDWI.tif") # if not os.path.exists(dest): print("NDWI") if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) NDWI = ((GREEN - NIR) / (GREEN + NIR)) * 5000. + 5000. if (NDWI.shape[1] < extentAOI.ncol) or (NDWI.shape[0] < extentAOI.nrow): NDWI = rsu.padArray(NDWI, scene.geotrans, scene.proj, extentAOI) NDWI = np.where(mask == 1, nodata, NDWI) rsu.array2raster(NDWI, extentAOI.getGeotrans(), extentAOI.getProj(), dest, gdal.GDT_Int16, nodata) del NDWI # mNDWI (Xu ,2006) dest = os.path.join(outputDir, "mNDWI", outputName + "_mNDWI.tif") # if not os.path.exists(dest): print("mNDWI") if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) MNDWI = ((GREEN - SWIR1) / (GREEN + SWIR1)) * 5000. + 5000. if (MNDWI.shape[1] < extentAOI.ncol) or (MNDWI.shape[0] < extentAOI.nrow): MNDWI = rsu.padArray(MNDWI, scene.geotrans, scene.proj, extentAOI) MNDWI = np.where(mask == 1, nodata, MNDWI) rsu.array2raster(MNDWI, extentAOI.getGeotrans(), extentAOI.getProj(), dest, gdal.GDT_Int16, nodata) del MNDWI if not WCRonly: # NDMI (Gao, 1996) and Normalized Difference Moisture Index dest = os.path.join(outputDir, "NDMI", outputName + "_NDMI.tif") # if not os.path.exists(dest): print("NDMI") if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) NDMI = ((NIR - SWIR1) / (NIR + SWIR1)) * 5000. + 5000. if (NDMI.shape[1] < extentAOI.ncol) or (NDMI.shape[0] < extentAOI.nrow): NDMI = rsu.padArray(NDMI, scene.geotrans, scene.proj, extentAOI) NDMI = np.where(mask == 1, nodata, NDMI) rsu.array2raster(NDMI, extentAOI.getGeotrans(), extentAOI.getProj(), dest, gdal.GDT_Int16, nodata) del NDMI # Norm Diff GREEN - SWIR2 # dest = os.path.join(outputDir, "ND-GREEN-SWIR2", outputName + "_ND-GREEN-SWIR2.tif") # if not os.path.exists(dest): # print("ND-GREEN-SWIR2") # if not os.path.exists(os.path.dirname(dest)): # os.mkdir(os.path.dirname(dest)) # ND_G_SW1 = ((GREEN - SWIR2) / (GREEN + SWIR2)) * 5000. + 5000. # if (ND_G_SW1.shape[1] < extentAOI.ncol) or (ND_G_SW1.shape[0] < extentAOI.nrow): # ND_G_SW1 = rsu.padArray(ND_G_SW1, geotrans, proj, extentAOI) # rsu.array2raster(ND_G_SW1, extentAOI.getGeotrans(),extentAOI.getProj(), dest, gdal.GDT_Int16, nodata) # del ND_G_SW1 dest = os.path.join(outputDir, "ND-NIR-SWIR2", outputName + "_ND0406.tif") # if not os.path.exists(dest): print("ND0406") if not os.path.exists(os.path.dirname(dest)): os.mkdir(os.path.dirname(dest)) ND0406 = ((NIR - SWIR2) / (NIR + SWIR2)) * 5000. + 5000. if (ND0406.shape[1] < extentAOI.ncol) or (ND0406.shape[0] < extentAOI.nrow): ND0406 = rsu.padArray(ND0406, scene.geotrans, scene.proj, extentAOI) ND0406 = np.where(mask == 1, nodata, ND0406) rsu.array2raster(ND0406, extentAOI.getGeotrans(), extentAOI.getProj(), dest, gdal.GDT_Int16, nodata) del ND0406
# Subset by path/row (landsat) or tileID (Sentinel) if tileID == "": tileID = None # Create output directories path_vrt = os.path.join(path_output, "VRTfiles") if not os.path.exists(path_vrt): os.mkdir(path_vrt) path_indices = os.path.join(path_output, "indices") if not os.path.exists(path_indices): os.mkdir(path_indices) # Search for scene directories -------------------------------------------------------------- if sensor == "Sentinel": sceneDirs = rsu.search_scene_directories(path_imagery, "S2[AB]*") sceneDirs_ID = [] for i, sceD in enumerate(sceneDirs): metadatafiles = [] try: if sceD.endswith(".zip"): zpfile = zipfile.ZipFile(sceD) metadatafiles = fnmatch.filter(zpfile.namelist(), "*/GRANULE/*/MTD_TL.xml") if len(metadatafiles) == 0: metadatafiles = fnmatch.filter(zpfile.namelist(), "*/GRANULE/*/S2*.xml") if len(metadatafiles) > 0: