def mainRoutine(): cmdargs = getCmdargs() landsatTOA.makeTOAReflectance(cmdargs.infile, cmdargs.mtl, cmdargs.anglesfile, cmdargs.output)
def do_fmask(self, filters_enabled, min_cloud_size=0, cloud_prob_thresh=0.225, cloud_buffer_size=4, shadow_buffer_size=6, cirrus_prob_ratio=0.04, nir_fill_thresh=0.02, swir2_thresh=0.03, whiteness_thresh=0.7, swir2_water_test=0.03, nir_snow_thresh=0.11, green_snow_thresh=0.1): ######################################## # reflective bands stack # tmp file for reflective bands stack self.reflective_stack_file = os.path.join(self.tmp_dir, "reflective_stack.tif") if not os.path.isfile(self.reflective_stack_file): update_process_bar(self.process_bar, 10, self.process_status, self.tr("Making reflective bands stack...")) gdal_merge.main(["", "-separate", "-of", "GTiff", "-o", self.reflective_stack_file] + self.reflective_bands) ######################################## # thermal bands stack # tmp file for reflective bands stack self.thermal_stack_file = os.path.join(self.tmp_dir, "thermal_stack.tif") if not os.path.isfile(self.thermal_stack_file): update_process_bar(self.process_bar, 20, self.process_status, self.tr("Making thermal bands stack...")) gdal_merge.main(["", "-separate", "-of", "GTiff", "-o", self.thermal_stack_file] + self.thermal_bands) ######################################## # clipping the reflective bands stack (only if is activated selected area or shape area) self.reflective_stack_clip_file = os.path.join(self.tmp_dir, "reflective_stack_clip.tif") self.reflective_stack_for_process = self.clip(self.reflective_stack_file, self.reflective_stack_clip_file) ######################################## # clipping the thermal bands stack (only if is activated selected area or shape area) self.thermal_stack_clip_file = os.path.join(self.tmp_dir, "thermal_stack_clip.tif") self.thermal_stack_for_process = self.clip(self.thermal_stack_file, self.thermal_stack_clip_file) ######################################## # estimates of per-pixel angles for sun # and satellite azimuth and zenith # # fmask_usgsLandsatMakeAnglesImage.py # tmp file for angles self.angles_file = os.path.join(self.tmp_dir, "angles.tif") update_process_bar(self.process_bar, 30, self.process_status, self.tr("Making fmask angles file...")) mtlInfo = config.readMTLFile(self.mtl_path) imgInfo = fileinfo.ImageInfo(self.reflective_stack_for_process) corners = landsatangles.findImgCorners(self.reflective_stack_for_process, imgInfo) nadirLine = landsatangles.findNadirLine(corners) extentSunAngles = landsatangles.sunAnglesForExtent(imgInfo, mtlInfo) satAzimuth = landsatangles.satAzLeftRight(nadirLine) landsatangles.makeAnglesImage(self.reflective_stack_for_process, self.angles_file, nadirLine, extentSunAngles, satAzimuth, imgInfo) ######################################## # saturation mask # # fmask_usgsLandsatSaturationMask.py # tmp file for angles self.saturationmask_file = os.path.join(self.tmp_dir, "saturationmask.tif") update_process_bar(self.process_bar, 40, self.process_status, self.tr("Making saturation mask file...")) if self.landsat_version == 4: sensor = config.FMASK_LANDSAT47 elif self.landsat_version == 5: sensor = config.FMASK_LANDSAT47 elif self.landsat_version == 7: sensor = config.FMASK_LANDSAT47 elif self.landsat_version == 8: sensor = config.FMASK_LANDSAT8 # needed so the saturation function knows which # bands are visible etc. fmaskConfig = config.FmaskConfig(sensor) saturationcheck.makeSaturationMask(fmaskConfig, self.reflective_stack_for_process, self.saturationmask_file) ######################################## # top of Atmosphere reflectance # # fmask_usgsLandsatTOA.py # tmp file for toa self.toa_file = os.path.join(self.tmp_dir, "toa.tif") update_process_bar(self.process_bar, 50, self.process_status, self.tr("Making top of Atmosphere ref...")) landsatTOA.makeTOAReflectance(self.reflective_stack_for_process, self.mtl_path, self.angles_file, self.toa_file) ######################################## # cloud mask # # fmask_usgsLandsatStacked.py # tmp file for cloud self.cloud_fmask_file = os.path.join(self.tmp_dir, "cloud_fmask_{}.tif".format(datetime.now().strftime('%H%M%S'))) update_process_bar(self.process_bar, 70, self.process_status, self.tr("Making cloud mask with fmask...")) # 1040nm thermal band should always be the first (or only) band in a # stack of Landsat thermal bands thermalInfo = config.readThermalInfoFromLandsatMTL(self.mtl_path) anglesInfo = config.AnglesFileInfo(self.angles_file, 3, self.angles_file, 2, self.angles_file, 1, self.angles_file, 0) if self.landsat_version == 4: sensor = config.FMASK_LANDSAT47 elif self.landsat_version == 5: sensor = config.FMASK_LANDSAT47 elif self.landsat_version == 7: sensor = config.FMASK_LANDSAT47 elif self.landsat_version == 8: sensor = config.FMASK_LANDSAT8 fmaskFilenames = config.FmaskFilenames() fmaskFilenames.setTOAReflectanceFile(self.toa_file) fmaskFilenames.setThermalFile(self.thermal_stack_for_process) fmaskFilenames.setOutputCloudMaskFile(self.cloud_fmask_file) fmaskFilenames.setSaturationMask(self.saturationmask_file) # TODO: optional fmaskConfig = config.FmaskConfig(sensor) fmaskConfig.setThermalInfo(thermalInfo) fmaskConfig.setAnglesInfo(anglesInfo) fmaskConfig.setKeepIntermediates(False) fmaskConfig.setVerbose(True) fmaskConfig.setTempDir(self.tmp_dir) # Set the settings fmask filters from widget to FmaskConfig fmaskConfig.setMinCloudSize(min_cloud_size) fmaskConfig.setEqn17CloudProbThresh(cloud_prob_thresh) fmaskConfig.setCloudBufferSize(int(cloud_buffer_size)) fmaskConfig.setShadowBufferSize(int(shadow_buffer_size)) fmaskConfig.setCirrusProbRatio(cirrus_prob_ratio) fmaskConfig.setEqn19NIRFillThresh(nir_fill_thresh) fmaskConfig.setEqn1Swir2Thresh(swir2_thresh) fmaskConfig.setEqn2WhitenessThresh(whiteness_thresh) fmaskConfig.setEqn7Swir2Thresh(swir2_water_test) fmaskConfig.setEqn20NirSnowThresh(nir_snow_thresh) fmaskConfig.setEqn20GreenSnowThresh(green_snow_thresh) # set to 1 for all Fmask filters disabled if filters_enabled["Fmask Cloud"]: fmask.OUTCODE_CLOUD = 2 else: fmask.OUTCODE_CLOUD = 1 if filters_enabled["Fmask Shadow"]: fmask.OUTCODE_SHADOW = 3 else: fmask.OUTCODE_SHADOW = 1 if filters_enabled["Fmask Snow"]: fmask.OUTCODE_SNOW = 4 else: fmask.OUTCODE_SNOW = 1 if filters_enabled["Fmask Water"]: fmask.OUTCODE_WATER = 5 else: fmask.OUTCODE_WATER = 1 # process Fmask fmask.doFmask(fmaskFilenames, fmaskConfig) # save final result of masking self.cloud_masking_files.append(self.cloud_fmask_file) ### ending fmask process update_process_bar(self.process_bar, 100, self.process_status, self.tr("DONE"))
def do_fmask(mtl_file, filters_enabled, tmp_dir, min_cloud_size=0, cloud_prob_thresh=0.225, cloud_buffer_size=4, shadow_buffer_size=6, cirrus_prob_ratio=0.04, nir_fill_thresh=0.02, swir2_thresh=0.03, whiteness_thresh=0.7, swir2_water_test=0.03, nir_snow_thresh=0.11, green_snow_thresh=0.1): print("Fmask:") input_dir = os.path.dirname(mtl_file) # parser mtl_file_parse = mtl2dict(mtl_file) # get the landsat version landsat_version = int(mtl_file_parse['SPACECRAFT_ID'][-1]) # set bands for reflective and thermal if landsat_version in [4, 5]: # get the reflective file names bands reflective_bands = [ os.path.join(input_dir, mtl_file_parse['FILE_NAME_BAND_' + str(N)]) for N in [1, 2, 3, 4, 5, 7] ] # get the thermal file names bands thermal_bands = [ os.path.join(input_dir, mtl_file_parse['FILE_NAME_BAND_' + str(N)]) for N in [6] ] # set bands for reflective and thermal if landsat_version == 7: # get the reflective file names bands reflective_bands = [ os.path.join(input_dir, mtl_file_parse['FILE_NAME_BAND_' + str(N)]) for N in [1, 2, 3, 4, 5, 7] ] # get the thermal file names bands thermal_bands = [ os.path.join(input_dir, mtl_file_parse['FILE_NAME_BAND_6_VCID_' + str(N)]) for N in [1, 2] ] # set bands for reflective and thermal if landsat_version == 8: # get the reflective file names bands reflective_bands = [ os.path.join(input_dir, mtl_file_parse['FILE_NAME_BAND_' + str(N)]) for N in [1, 2, 3, 4, 5, 6, 7, 9] ] # get the thermal file names bands thermal_bands = [ os.path.join(input_dir, mtl_file_parse['FILE_NAME_BAND_' + str(N)]) for N in [10, 11] ] # set the prefer file name band for process reflective_bands = [ get_prefer_name(file_path) for file_path in reflective_bands ] thermal_bands = [get_prefer_name(file_path) for file_path in thermal_bands] ######################################## # reflective bands stack # tmp file for reflective bands stack reflective_stack_file = os.path.join(tmp_dir, "reflective_stack.tif") if not os.path.isfile(reflective_stack_file): gdal_merge.main( ["", "-separate", "-of", "GTiff", "-o", reflective_stack_file] + reflective_bands) ######################################## # thermal bands stack # tmp file for reflective bands stack thermal_stack_file = os.path.join(tmp_dir, "thermal_stack.tif") if not os.path.isfile(thermal_stack_file): gdal_merge.main( ["", "-separate", "-of", "GTiff", "-o", thermal_stack_file] + thermal_bands) ######################################## # estimates of per-pixel angles for sun # and satellite azimuth and zenith # # fmask_usgsLandsatMakeAnglesImage.py # tmp file for angles angles_file = os.path.join(tmp_dir, "angles.tif") mtlInfo = config.readMTLFile(mtl_file) imgInfo = fileinfo.ImageInfo(reflective_stack_file) corners = landsatangles.findImgCorners(reflective_stack_file, imgInfo) nadirLine = landsatangles.findNadirLine(corners) extentSunAngles = landsatangles.sunAnglesForExtent(imgInfo, mtlInfo) satAzimuth = landsatangles.satAzLeftRight(nadirLine) landsatangles.makeAnglesImage(reflective_stack_file, angles_file, nadirLine, extentSunAngles, satAzimuth, imgInfo) ######################################## # saturation mask # # fmask_usgsLandsatSaturationMask.py # tmp file for angles saturationmask_file = os.path.join(tmp_dir, "saturationmask.tif") if landsat_version == 4: sensor = config.FMASK_LANDSAT47 elif landsat_version == 5: sensor = config.FMASK_LANDSAT47 elif landsat_version == 7: sensor = config.FMASK_LANDSAT47 elif landsat_version == 8: sensor = config.FMASK_LANDSAT8 # needed so the saturation function knows which # bands are visible etc. fmaskConfig = config.FmaskConfig(sensor) saturationcheck.makeSaturationMask(fmaskConfig, reflective_stack_file, saturationmask_file) ######################################## # top of Atmosphere reflectance # # fmask_usgsLandsatTOA.py # tmp file for toa toa_file = os.path.join(tmp_dir, "toa.tif") landsatTOA.makeTOAReflectance(reflective_stack_file, mtl_file, angles_file, toa_file) ######################################## # cloud mask # # fmask_usgsLandsatStacked.py # tmp file for cloud cloud_fmask_file = os.path.join(tmp_dir, "fmask.tif") # 1040nm thermal band should always be the first (or only) band in a # stack of Landsat thermal bands thermalInfo = config.readThermalInfoFromLandsatMTL(mtl_file) anglesInfo = config.AnglesFileInfo(angles_file, 3, angles_file, 2, angles_file, 1, angles_file, 0) if landsat_version == 4: sensor = config.FMASK_LANDSAT47 elif landsat_version == 5: sensor = config.FMASK_LANDSAT47 elif landsat_version == 7: sensor = config.FMASK_LANDSAT47 elif landsat_version == 8: sensor = config.FMASK_LANDSAT8 fmaskFilenames = config.FmaskFilenames() fmaskFilenames.setTOAReflectanceFile(toa_file) fmaskFilenames.setThermalFile(thermal_stack_file) fmaskFilenames.setOutputCloudMaskFile(cloud_fmask_file) fmaskFilenames.setSaturationMask(saturationmask_file) # TODO: optional fmaskConfig = config.FmaskConfig(sensor) fmaskConfig.setThermalInfo(thermalInfo) fmaskConfig.setAnglesInfo(anglesInfo) fmaskConfig.setKeepIntermediates(False) fmaskConfig.setVerbose(False) fmaskConfig.setTempDir(tmp_dir) # Set the settings fmask filters from widget to FmaskConfig fmaskConfig.setMinCloudSize(min_cloud_size) fmaskConfig.setEqn17CloudProbThresh(cloud_prob_thresh) fmaskConfig.setCloudBufferSize(int(cloud_buffer_size)) fmaskConfig.setShadowBufferSize(int(shadow_buffer_size)) fmaskConfig.setCirrusProbRatio(cirrus_prob_ratio) fmaskConfig.setEqn19NIRFillThresh(nir_fill_thresh) fmaskConfig.setEqn1Swir2Thresh(swir2_thresh) fmaskConfig.setEqn2WhitenessThresh(whiteness_thresh) fmaskConfig.setEqn7Swir2Thresh(swir2_water_test) fmaskConfig.setEqn20NirSnowThresh(nir_snow_thresh) fmaskConfig.setEqn20GreenSnowThresh(green_snow_thresh) # set to 1 for all Fmask filters disabled if filters_enabled["Fmask Cloud"]: fmask.OUTCODE_CLOUD = 2 else: fmask.OUTCODE_CLOUD = 1 if filters_enabled["Fmask Shadow"]: fmask.OUTCODE_SHADOW = 3 else: fmask.OUTCODE_SHADOW = 1 if filters_enabled["Fmask Snow"]: fmask.OUTCODE_SNOW = 4 else: fmask.OUTCODE_SNOW = 1 if filters_enabled["Fmask Water"]: fmask.OUTCODE_WATER = 5 else: fmask.OUTCODE_WATER = 1 # process Fmask fmask.doFmask(fmaskFilenames, fmaskConfig) return cloud_fmask_file
def makeStacksAndAngles(cmdargs): """ Find the name of the MTL file. Make an intermediate stacks of all the TOA reflectance and thermal bands. Also make an image of the angles, saturation and TOA reflectance. Fill in the names of these in the cmdargs object. """ # find MTL file wldpath = os.path.join(cmdargs.scenedir, '*_MTL.txt') mtlList = glob.glob(wldpath) if len(mtlList) != 1: raise fmaskerrors.FmaskFileError("Cannot find a *_MTL.txt file in specified dir") cmdargs.mtl = mtlList[0] gdalmergeCmd = find_executable("gdal_merge.py") if gdalmergeCmd is None: msg = "Unable to find gdal_merge.py command. Check installation of GDAL package. " raise fmaskerrors.FmaskInstallationError(msg) # we need to find the 'SPACECRAFT_ID' to work out the wildcards to use mtlInfo = config.readMTLFile(cmdargs.mtl) landsat = mtlInfo['SPACECRAFT_ID'][-1] if landsat == '4' or landsat == '5': refWildcard = 'L*_B[1,2,3,4,5,7].TIF' thermalWildcard = 'L*_B6.TIF' elif landsat == '7': refWildcard = 'L*_B[1,2,3,4,5,7].TIF' thermalWildcard = 'L*_B6_VCID_?.TIF' elif landsat == '8': refWildcard = 'LC*_B[1-7,9].TIF' thermalWildcard = 'LC*_B1[0,1].TIF' else: raise SystemExit('Unsupported Landsat sensor') wldpath = os.path.join(cmdargs.scenedir, refWildcard) refFiles = sorted(glob.glob(wldpath)) if len(refFiles) == 0: raise fmaskerrors.FmaskFileError("Cannot find expected reflectance files for sensor") wldpath = os.path.join(cmdargs.scenedir, thermalWildcard) thermalFiles = sorted(glob.glob(wldpath)) if len(thermalFiles) == 0: raise fmaskerrors.FmaskFileError("Cannot find expected thermal files for sensor") if cmdargs.verbose: print("Making stack of all reflectance bands") (fd, tmpRefStack) = tempfile.mkstemp(dir=cmdargs.tempdir, prefix="tmp_allrefbands_", suffix=".img") os.close(fd) # use sys.executable so Windows works subprocess.check_call([sys.executable, gdalmergeCmd, '-q', '-of', DEFAULTDRIVERNAME] + CMDLINECREATIONOPTIONS + ['-separate', '-o', tmpRefStack] + refFiles) # stash so we can delete later cmdargs.refstack = tmpRefStack if cmdargs.verbose: print("Making stack of all thermal bands") (fd, tmpThermStack) = tempfile.mkstemp(dir=cmdargs.tempdir, prefix="tmp_allthermalbands_", suffix=".img") os.close(fd) subprocess.check_call([sys.executable, gdalmergeCmd, '-q', '-of', DEFAULTDRIVERNAME] + CMDLINECREATIONOPTIONS + ['-separate', '-o', tmpThermStack] + thermalFiles) cmdargs.thermal = tmpThermStack # now the angles if cmdargs.verbose: print("Creating angles file") (fd, anglesfile) = tempfile.mkstemp(dir=cmdargs.tempdir, prefix="angles_tmp_", suffix=".img") os.close(fd) usgsLandsatMakeAnglesImage.makeAngles(cmdargs.mtl, tmpRefStack, anglesfile) cmdargs.anglesfile = anglesfile # saturation if cmdargs.verbose: print("Creating saturation file") (fd, saturationfile) = tempfile.mkstemp(dir=cmdargs.tempdir, prefix="saturation_tmp_", suffix=".img") os.close(fd) usgsLandsatSaturationMask.makeSaturationMask(cmdargs.mtl, tmpRefStack, saturationfile) cmdargs.saturation = saturationfile # TOA if cmdargs.verbose: print("Creating TOA file") (fs, toafile) = tempfile.mkstemp(dir=cmdargs.tempdir, prefix="toa_tmp_", suffix=".img") os.close(fd) landsatTOA.makeTOAReflectance(tmpRefStack, cmdargs.mtl, anglesfile, toafile) cmdargs.toa = toafile