def get_detfoo_index_detector_list(maskFilename, shift): l_result = {} # Load the MSK_DETFOO gml file maskHandler = get_root_xml(maskFilename, deannotate=True) # Get the mask feature nodes # as : <eop:MaskFeature gml:id="detector_footprint-B02-10-2"> xnodes = get_all_values(maskHandler, "//*[local-name(.) = 'MaskFeature']") # Two indices : the detector index and the feature index detId = 0 # For each feature for i in range(len(xnodes)): feat = xnodes[i] # Get the attribute of the feature node # "detector_footprint-B02-10-2" attribute = list(feat.items())[0][1] element = attribute.split('-') # Get the detector index and the feature index detId = int(element[-2]) featId = int(element[-1]) l_result[featId + shift] = detId return l_result
def get_no_data(self): nodata = 0 special_values = xml_tools.get_all_values(self.root, XPATH_MAIN_S2.get("special_values")) for values in special_values: if values.findtext("SPECIAL_VALUE_TEXT") == "NODATA": nodata = int(values.findtext("SPECIAL_VALUE_INDEX")) return nodata raise MajaDriverException("NODATA not found in the L1 Header file")
def get_list_of_packaged_dbl_files(self, absolute, check): nodes = xml_tools.get_all_values( self.root, EARTH_EXPLORER_HANDLER_XPATH["DBLFilenames"]) list_of_files = [nd.text for nd in nodes] if absolute: l_rootbasepath = os.path.dirname(self.main_xml_file) list_of_files = [ os.path.join(l_rootbasepath, nd.text) for nd in nodes ] if check: for fi in list_of_files: if not os.path.exists(fi): raise MajaDataException("File " + fi + " does not exists") return list_of_files
def get_list_of_gipp_files(self): """ GetList_of_GIPP_Files :return: """ l_listofgipps = [] for gipp_node in xml_tools.get_all_values(self.root, GIPP_FILE): one_gipp = dict() one_gipp["index"] = xml_tools.get_only_value(gipp_node, GIPP_FILE_INDEX) one_gipp["file_location"] = xml_tools.get_xml_string_value(gipp_node, GIPP_FILE_LOCATION) one_gipp["nature"] = xml_tools.get_xml_string_value(gipp_node, GIPP_FILE_NATURE) one_gipp["logical_name"] = xml_tools.get_xml_string_value(gipp_node, GIPP_FILE_LOGICAL_NAME) l_listofgipps.append(one_gipp) return l_listofgipps
def get_list_of_zones(self, bandIdx): list_of_zone = [] # Convert the band index integer value in string path = "//Viewing_Incidence_Angles_Grids[@bandId='" + str( bandIdx) + "']" xnodes = xml_tools.get_all_values(self.root, path) # Two indices : the detector index and the feature index detId = 0 # For each feature for i in range(len(xnodes)): LOGGER.debug((list(xnodes[i].items()))) list_of_zone.append(xnodes[i].get("detectorId")) return list_of_zone
def get_detfoo_index_shift(maskFilename): """ Get the shift between the detector index and the feature index in the MSK_DETFOO mask :param maskFilename: string :return: """ shift = 0 # Load the MSK_DETFOO gml file maskHandler = get_root_xml(maskFilename, deannotate=True) # Get the mask feature nodes # as : <eop:MaskFeature gml:id="detector_footprint-B02-10-2"> xnodes = get_all_values(maskHandler, "//*[local-name(.) = 'MaskFeature']") # Two indices : the detector index and the feature index detId = 0 # For each feature for i in range(len(xnodes)): feat = xnodes[i] prevShift = shift prevDetId = detId # "detector_footprint-B02-10-2" attribute = list(feat.items())[0][1] element = attribute.split('-') # Get the detector index and the feature index detId = int(element[-2]) featId = int(element[-1]) # The shift between those two indices must be constant # because it should not have a gap of detector between to consecutive features shift = detId - featId # Check the index values of the next features if (i > 0) and ((shift != prevShift) or (detId != prevDetId + 1)): LOGGER.warn( "Sentinel2L1ImageFileReaderBase::get_detfoo_index_shift: The detector indices are not in ascending order " "or do not have a constant shift with the feature indices in the MSK_DETFOO " + maskFilename + " !") return False, shift return True, shift
def get_mask_feature_count(maskFilename, regex=None): """ Get the number of layers in a gml file :param maskFilename: :return: """ maskHandler = get_root_xml(maskFilename, deannotate=True) xnodes = get_all_values(maskHandler, "//*[local-name(.) = 'MaskFeature']") if xnodes is not None: if regex is None: return len(xnodes) else: nb = 0 for x in xnodes: for a in list(x.items()): if regex in a[1]: nb = nb + 1 return nb else: return 0
def get_list_of_quality_index(self): """ GetListOfQualityIndexes :return: """ l_listofqualityindexes = [] for quality_index_node in xml_tools.get_all_values(self.root, ONE_QUALITY_INDEX): one_quality_index = dict() one_quality_index["index"] = xml_tools.get_xml_int_value(quality_index_node, GIPP_FILE_INDEX) one_quality_index["code"] = xml_tools.get_xml_int_value(quality_index_node, QUALITY_INDEX_CODE) one_quality_index["value"] = xml_tools.get_xml_int_value(quality_index_node, QUALITY_INDEX_VALUE) one_quality_index["band_code"] = QUALITY_INDEX_BAND_CODE l_listofqualityindexes.append(one_quality_index) LOGGER.debug("Add the quality index [%s] Code=<%s> Value=<%s> Band_Code=<%s> ", one_quality_index["index"], one_quality_index["code"], one_quality_index["value"], one_quality_index["band_code"])
def muscate_initialize(self, product_filename, plugin_base, validate=False, schema_path=None): # Initialize the Image filename provider if not MajaMuscateL1ImageInformations.is_a_muscate_by_checking_the_filename( product_filename): LOGGER.debug("The filename <" + product_filename + "> is not an 'muscate' L1 header file.") return False if not MajaMuscateL1ImageInformations.is_a_muscate_by_checking_the_satellite( product_filename, plugin_base): LOGGER.debug( "The filename <" + product_filename + "> is not an 'muscate' L1 header file (by reading platform in the xml file)." ) return False # Init XML handler lHandler = MuscateXMLFileHandler(product_filename, validate=validate, schema_path=schema_path) # Store the satellite self.Satellite = lHandler.get_string_value_of("Platform") self.SatelliteID = self.Satellite.upper().replace("-", "") # Store the plugin name self.PluginName = plugin_base.PluginName self.ProductFileName = product_filename self.FileCategory = plugin_base.ShortFileType # LSC self.LevelType = "L1VALD" self.Prefix = self.Satellite self.FileClass = "TEST" # LANDSAT5-TM-XSTH... self.Site = lHandler.get_string_value_of("ZoneGeo") self.ProductDateStr = lHandler.get_acquisition_date_formated_yyyymmdd( ) # YYYYMMDD # LANDSAT5-TM-XSTH_20100118-103000-000_L1C_EU93066200A00B_C_V1-0 self.ProductId = lHandler.get_string_value_of("ProductId") self.ProductVersion = lHandler.get_string_value_of("ProductVersion") l_DatePDV = lHandler.get_date_pdv_formated_utc( ) # UTC=2010-01-18T12:00:00 self.ProductDate = date_utils.get_datetime_from_utc(l_DatePDV) self.GenerationDateStr = lHandler.get_string_value_of("ProductionDate") self.AcquisitionStart = lHandler.get_string_value_of("AcquisitionDate") self.OrbitNumber = lHandler.get_string_value_of("OrbitNumber") self.ReferenceSiteDefinitionId = "UNKNOWN" self.HeaderFilename = product_filename self.HeaderHandler = lHandler if xml_tools.get_only_value(lHandler.root, "//Product_Characteristics/INSTRUMENT", check=True) is not None: self.Instrument = lHandler.get_string_value_of("Instrument") if xml_tools.get_only_value( lHandler.root, "//Product_Characteristics/SPECTRAL_CONTENT", check=True) is not None: self.SpectralContent = lHandler.get_string_value_of( "SpectralContent").replace("+", "") # VENUS specification # Store the VIE and SOL filenames (DATA and Headers) to copy in the L2 product self.SOLHeaderFileName = "" self.SOLImageFileName = "" self.VIEHeaderFileName = "" self.VIEImageFileName = "" # Initialize the parameters necessary for the core of the algorithms of MACCS # Get longitude and latitude coordinates of the product ulc = lHandler.get_upper_left_corner() lrc = lHandler.get_lower_right_corner() # Estimation of the coordinate of the central point center = lHandler.get_center() #l_Corner.Longitude = ulc[0] + (lrc[0] - ulc[0]) / 2. #l_Corner.Latitude = ulc[1] + (lrc[1] - ulc[1]) / 2. self.CenterCorner.longitude = center[0] self.CenterCorner.latitude = center[1] self.CenterCorner.column = 0 self.CenterCorner.line = 0 # Initialize the Validity Start/Stop l_UTCValidity = date_utils.get_utc_from_datetime(self.ProductDate) if l_UTCValidity.endswith('.000Z'): l_UTCValidity = l_UTCValidity[:-5] self.UTCValidityStart = l_UTCValidity self.UTCValidityStop = l_UTCValidity # Get the list of bands in a L2 product l_BandsDefinitions = plugin_base.BandsDefinitions l_ListOfBandsL2Coarse = l_BandsDefinitions.get_list_of_band_id_in_l2_coarse( ) l_NbBandsL2Coarse = len(l_ListOfBandsL2Coarse) LOGGER.debug( "l_BandsDefinitions->GetListOfBandCodeInL2Coarse -> l_NbBandsL2Coarse: " + str(l_NbBandsL2Coarse)) LOGGER.debug( "MuscateXmllHandler->GetListOfBands -> l_NbBands : " + str(len(lHandler.get_list_of_bands()))) self.ListOfViewingAnglesPerBandAtL2Resolution = [] self.ListOfViewingAnglesPerBandAtL2CoarseResolution = [] self.ListOfViewingZenithAnglesPerBandAtL2CoarseResolution = [] self.ListOfViewingAzimuthAnglesPerBandAtL2CoarseResolution = [] # Initialize the Viewing angles for each detectors (Zenith and Azimuth) # Read the constants values from the Header Envi file name # The angles must be in degree if plugin_base.WideFieldSensor: # Initialize the Viewing angles for each detectors (Zenith and Azimuth) l_MeanViewingZenithalAngles = lHandler.get_mean_viewing_zenithal_angles( ) l_MeanViewingAzimuthalAngles = lHandler.get_mean_viewing_azimuthal_angles( ) self.ViewingAngle = { "incidence_zenith_angle": str(statistics.mean(l_MeanViewingZenithalAngles)), "incidence_azimuth_angle": str(statistics.mean(l_MeanViewingAzimuthalAngles)) } # For each bands for EnviProduct for bd in range(0, len(l_ListOfBandsL2Coarse)): angles = { "incidence_zenith_angle": str(l_MeanViewingZenithalAngles[bd]), "incidence_azimuth_angle": str(l_MeanViewingAzimuthalAngles[bd]) } self.ListOfViewingAnglesPerBandAtL2CoarseResolution.append( angles) self.ListOfViewingZenithAnglesPerBandAtL2CoarseResolution.append( str(angles["incidence_zenith_angle"])) self.ListOfViewingAzimuthAnglesPerBandAtL2CoarseResolution.append( str(angles["incidence_azimuth_angle"])) else: lViewingAngles = lHandler.get_mean_viewing_angles() l_ViewAngleZenith = lViewingAngles[0] l_ViewAngleAzimuth = lViewingAngles[1] self.ViewingAngle = { "incidence_zenith_angle": str(l_ViewAngleZenith), "incidence_azimuth_angle": str(l_ViewAngleAzimuth) } # For each bands for EnviProduct for bd in l_ListOfBandsL2Coarse: angles = { "incidence_zenith_angle": str(l_ViewAngleZenith), "incidence_azimuth_angle": str(l_ViewAngleAzimuth) } self.ListOfViewingAnglesPerBandAtL2CoarseResolution.append( angles) self.ListOfViewingZenithAnglesPerBandAtL2CoarseResolution.append( str(angles["incidence_zenith_angle"])) self.ListOfViewingAzimuthAnglesPerBandAtL2CoarseResolution.append( str(angles["incidence_azimuth_angle"])) # Fill the L2 resolution angles l_nbRes = len(l_BandsDefinitions.ListOfL2Resolution) for r in range(0, l_nbRes): l_res = l_BandsDefinitions.ListOfL2Resolution[r] l_l2bandcodes = l_BandsDefinitions.get_list_of_l2_band_code(l_res) l_l2bandidx = [ l_BandsDefinitions.get_band_id_in_l2_coarse(b) for b in l_l2bandcodes ] for b in l_l2bandidx: self.ListOfViewingAnglesPerBandAtL2Resolution.append( self.ListOfViewingAnglesPerBandAtL2CoarseResolution[b]) # Solar Angles lSolarAngles = lHandler.get_mean_solar_angles() self.SolarAngle = { "sun_zenith_angle": lSolarAngles[0], "sun_azimuth_angle": lSolarAngles[1] } if xml_tools.get_only_value(lHandler.root, "//Angles_Grids_List/Sun_Angles_Grids", check=True) is not None: self.SolarAngleGrid["StepUnit"] = xml_tools.get_attribute( lHandler.root, "//Angles_Grids_List/Sun_Angles_Grids/Zenith", "step_unit") self.SolarAngleGrid["ColStep"] = lHandler.get_string_value_of( "SunAngleColStep") self.SolarAngleGrid["RowStep"] = lHandler.get_string_value_of( "SunAngleRowStep") self.SolarAngleGrid["Azimuth"] = lHandler.get_sun_azimuthal_angles( ) self.SolarAngleGrid["Zenith"] = lHandler.get_sun_zenithal_angles() # Viewing angle grids self.ViewingAngleGrids = [] if len( xml_tools.get_all_values( lHandler.root, "//Angles_Grids_List/Viewing_Incidence_Angles_Grids_List/Band_Viewing_Incidence_Angles_Grids_List" )): if lHandler.has_per_band_angles(): for bn, bandid in l_BandsDefinitions.L2CoarseBandMap.items(): zonelist = lHandler.get_list_of_zones(bn) zenith_values = lHandler.get_viewing_zenithal_angles(bn) azimuth_values = lHandler.get_viewing_azimuthal_angles(bn) LOGGER.debug("Viewing Angle grid for band " + str(bn)) for d, det in enumerate(zonelist): self.ViewingAngleGrids.append({ "StepUnit": lHandler.get_viewing_grid_step_unit(bn, det), "ColStep": lHandler.get_viewing_grid_col_step(bn, det), "RowStep": lHandler.get_viewing_grid_row_step(bn, det), "Band": str(bandid), "Detector": det.lstrip('0'), "Azimuth": azimuth_values[d], "Zenith": zenith_values[d] }) else: zonelist = lHandler.get_list_of_zones("dummy") for det in zonelist: LOGGER.debug("Viewing Angle grid for det " + det) self.ViewingAngleGrids.append({ "StepUnit": lHandler.get_viewing_grid_step_unit(bandid=None, det=det), "ColStep": lHandler.get_viewing_grid_col_step(bandid=None, det=det), "RowStep": lHandler.get_viewing_grid_row_step(bandid=None, det=det), "Detector": det.lstrip('0'), "Azimuth": lHandler.get_viewing_azimuthal_angles(det)[0], "Zenith": lHandler.get_viewing_zenithal_angles(det)[0] }) # Area by resolution self.AreaByResolution = [] l_grpSuffixes = l_BandsDefinitions.ListOfL2Resolution if len(l_grpSuffixes) == 1: l_grpSuffixes = ["XS"] for res in l_grpSuffixes: l_path_group_geo = "//Group_Geopositioning_List/Group_Geopositioning[@group_id='{}']/{}" curArea = Area() curArea.origin = (xml_tools.get_xml_string_value( lHandler.root, l_path_group_geo.format(res, "ULX")), xml_tools.get_xml_string_value( lHandler.root, l_path_group_geo.format(res, "ULY"))) curArea.spacing = (xml_tools.get_xml_string_value( lHandler.root, l_path_group_geo.format(res, "XDIM")), xml_tools.get_xml_string_value( lHandler.root, l_path_group_geo.format(res, "YDIM"))) curArea.size = (xml_tools.get_xml_string_value( lHandler.root, l_path_group_geo.format(res, "NCOLS")), xml_tools.get_xml_string_value( lHandler.root, l_path_group_geo.format(res, "NROWS"))) self.AreaByResolution.append(curArea) # Spectral information self.SpectralInfo = [] l_pathBase = "//Spectral_Band_Informations_List/Spectral_Band_Informations[@band_id='{}']" l_pathNativeCoeff = "/Calibration_Coefficients_Lists/Native_Coefficients_List/COEFFICIENT[@name='{}']" l_pathRadiance = "/SOLAR_IRRADIANCE" l_pathWavelength = "/Wavelength/{}" l_pathResponse = "/Spectral_Response/{}" l_pathsSpecInfo = { 'PhysicalGain': l_pathNativeCoeff.format("PhysicalGain"), 'LuminanceMax': l_pathNativeCoeff.format("LuminanceMax"), 'LuminanceMin': l_pathNativeCoeff.format("LuminanceMin"), 'QuantizeCalMax': l_pathNativeCoeff.format("QuantizeCalMax"), 'QuantizeCalMin': l_pathNativeCoeff.format("QuantizeCalMin"), 'RadianceAdd': l_pathNativeCoeff.format("RadianceAdd"), 'RadianceMult': l_pathNativeCoeff.format("RadianceMult"), 'ReflectanceAdd': l_pathNativeCoeff.format("ReflectanceAdd"), 'ReflectanceMult': l_pathNativeCoeff.format("ReflectanceMult"), 'SolarIrradiance': l_pathRadiance, 'WavelengthMin': l_pathWavelength.format("MIN"), 'WavelengthMax': l_pathWavelength.format("MAX"), 'WavelengthCentral': l_pathWavelength.format("CENTRAL"), 'ResponseStep': l_pathResponse.format("STEP"), 'ResponseValues': l_pathResponse.format("VALUES") } for b, bidx in l_BandsDefinitions.L1BandMap.items(): specInfo = {"Band": b} realBase = l_pathBase.format(b) for measure, pathMeasure in l_pathsSpecInfo.items(): res = xml_tools.get_xml_string_value(lHandler.root, realBase + pathMeasure, check=True) if len(res): specInfo[measure] = res if measure == 'PhysicalGain': specInfo[measure] = float(res) self.SpectralInfo.append(specInfo) # ------------------------------------------------------------------------- # 4.2: New # Set the L1 no data value self.L1NoData = int(lHandler.get_string_value_of("L1NoData")) # Set the reflectance quantification value self.ReflectanceQuantification = 1. / float( lHandler.get_string_value_of("QuantificationValue")) # Computes the real value of the L1 NoData self.RealL1NoData = float( self.L1NoData) * self.ReflectanceQuantification # Save metadata related to Muscate format self.MuscateData["Node_MetadataFormat"] = xml_tools.extract_nodes( lHandler.root, "//Metadata_Identification/METADATA_FORMAT") l_NodeOriginalDataDiffuser = xml_tools.extract_nodes( lHandler.root, "//ORIGINAL_DATA_DIFFUSER") if l_NodeOriginalDataDiffuser is not None: self.MuscateData[ "Node_OriginalDataDiffuser"] = l_NodeOriginalDataDiffuser self.MuscateData[ "Node_Geoposition_Informations"] = xml_tools.extract_nodes( lHandler.root, "//Geoposition_Informations") self.MuscateData[ "Node_Geometric_Informations"] = xml_tools.extract_nodes( lHandler.root, "//Geometric_Informations") #~ self.MuscateData["Identifier"] = lIdent self.MuscateData["Authority"] = lHandler.get_string_value_of( "Authority") self.MuscateData["Producer"] = lHandler.get_string_value_of("Producer") self.MuscateData["Project"] = lHandler.get_string_value_of("Project") self.MuscateData["ZoneGeo"] = lHandler.get_string_value_of("ZoneGeo") #~ self.MuscateData["Platform"] = self.Satellite self.MuscateData["AcquisitionDate"] = lHandler.get_string_value_of( "AcquisitionDate") self.MuscateData[ "UTCAcquisitionRangeMean"] = lHandler.get_string_value_of( "UTCAcquisitionRangeMean") self.MuscateData[ "UTCAcquisitionRangeDatePrecision"] = lHandler.get_string_value_of( "UTCAcquisitionRangeDatePrecision") l_NodeSolarAnglesGrid = xml_tools.extract_nodes( lHandler.root, "//Data_List/Data[Data_Properties/NATURE='Solar_Angles_Grid']") if l_NodeSolarAnglesGrid is not None: self.MuscateData["Node_Solar_Angles_Grid"] = l_NodeSolarAnglesGrid l_NodeViewingAnglesGrid = xml_tools.extract_nodes( lHandler.root, "//Data_List/Data[Data_Properties/NATURE='Viewing_Angles_Grid']") if l_NodeViewingAnglesGrid is not None: self.MuscateData[ "Node_Viewing_Angles_Grid"] = l_NodeViewingAnglesGrid l_NodeUsefulImageInfoFile = xml_tools.extract_nodes( lHandler.root, "//Data_List/Data[Data_Properties/NATURE='Useful_Image_Informations_File']" ) if l_NodeUsefulImageInfoFile is not None: self.MuscateData[ "Node_Useful_Image_Informations_File"] = l_NodeUsefulImageInfoFile l_NodeUsefulImage = xml_tools.extract_nodes( lHandler.root, "//Mask_List/Mask[Mask_Properties/NATURE='Useful_Image']") if l_NodeUsefulImage is not None: self.MuscateData["Node_Useful_Image"] = l_NodeUsefulImage l_NodeDetFoo = xml_tools.get_only_value( lHandler.root, "//Mask_List/Mask/Mask_Properties/NATURE[.='Detector_Footprint']", check=True) if l_NodeDetFoo is not None: self.MuscateData[ "ZoneMaskFileNames"] = lHandler.get_map_list_of_detector_footprint_image_filenames( ) pix_node = xml_tools.get_only_value( lHandler.root, "//Mask_List/Mask/Mask_Properties/NATURE[.='Aberrant_Pixels']", check=True) if pix_node is not None: self.MuscateData[ "PIXImages"] = lHandler.get_list_of_pix_mask_filenames() self.MuscateData[ "PIXIndices"] = lHandler.get_list_of_pix_mask_indices() spectral_node = xml_tools.extract_nodes( lHandler.root, "//Radiometric_Informations/Spectral_Band_Informations_List") if spectral_node is not None: self.MuscateData[ "Node_Spectral_Band_Informations_List"] = spectral_node qualityGeo_node = xml_tools.extract_nodes( lHandler.root, "//Current_Product/Product_Quality_List[@level='Geo']") if qualityGeo_node is not None: self.MuscateData["Node_Product_Quality_List_Geo"] = qualityGeo_node qualityNatif_node = xml_tools.extract_nodes( lHandler.root, "//Current_Product/Product_Quality_List[@level='Natif']") if qualityNatif_node is not None: self.MuscateData[ "Node_Product_Quality_List_Natif"] = qualityNatif_node processingJob_node = xml_tools.extract_nodes( lHandler.root, "//Production_Informations/Processing_Jobs_List") if processingJob_node is not None: self.MuscateData["Node_Processing_Jobs_List"] = processingJob_node return True
def write_public_images(self, p_PublicDirectory, p_L2BaseFilename, p_ReflectanceQuantificationValue, p_AOTQuantificationValue, p_AOTNodataValue, p_VAPQuantificationValue, p_VAPNodataValue, p_CLDDataBandsSelected, p_CLDCoreAlgorithmsMapBand, p_WritePublicProduct, p_EnvCorOption, working_dir): # IF PUBLIC PART OF L2 PRODUCT IS WRITTEN if p_WritePublicProduct: l_BandsDefinitions = self._plugin.BandsDefinitions l_ListOfL2Res = l_BandsDefinitions.ListOfL2Resolution l_NumberOfResolutions = len(l_ListOfL2Res) LOGGER.debug( "L2ImageFileWriterBase::Initialize Number of resolutions: " + str(l_NumberOfResolutions) + ".") # Not use the list of XS band because for Landsat8, the band B9 is not # selected in the L2 resolution (only in L2Coarse resolution) l_BaseL2FullFilename = os.path.join(p_PublicDirectory, p_L2BaseFilename) l_MASKSDirectory = os.path.join(p_PublicDirectory, "MASKS") l_BaseL2FullMASKSFilename = os.path.join(l_MASKSDirectory, p_L2BaseFilename) file_utils.create_directory(l_MASKSDirectory) resol_QLK = 0 l_RedBandId, l_BlueBandId, l_GreenBandId = l_BandsDefinitions.get_l2_information_for_quicklook_band_code( self._quicklookredbandcode, self._quicklookgreenbandcode, self._quicklookbluebandcode) # ************************************************************************************************************* # **** LOOP on RESOLUTION ********************************************* # ************************************************************************************************************* for resol in range(0, l_NumberOfResolutions): l_StrResolution = l_BandsDefinitions.ListOfL2Resolution[resol] # -------------------------------------------------------- # L2 area AreaType l_AreaToL2Resolution l_AreaFile = self._sre_list[resol] l_ListOfBand = l_BandsDefinitions.get_list_of_l2_band_code( l_StrResolution) l_NumberOfBands = len(l_ListOfBand) LOGGER.debug( "L2ImageFileReader::Gen Public image file for the resolution " + l_StrResolution + ".") l_grpSuffix = "" if l_NumberOfResolutions == 1: l_grpSuffix = "XS" else: l_grpSuffix = l_ListOfL2Res[resol] l_StrResolution = l_BandsDefinitions.ListOfL2Resolution[resol] # Read the Coef apply for SRE and FRE images LOGGER.info( "SRE and FRE values multiply by the reflectance quantification value " + str(p_ReflectanceQuantificationValue) + ".") # ************************************************************************************************************* # **** PUBLIC DATA ************************************************ # ************************************************************************************************************* # START WRITING SRE Image file DATA # Initialize the Scalar filter sre_pipeline = OtbPipelineManager() #Extract each channel for each file tmp_l2_filename_list = [] tmp_l2_image_list = [] tmp_sre_scaled = os.path.join( working_dir, "tmp_sre_multi_round_" + l_StrResolution + ".tif") param_scaled_sre = { "im": self._sre_list[resol], "coef": p_ReflectanceQuantificationValue, "out": tmp_sre_scaled } scaled_sre_app = OtbAppHandler("RoundImage", param_scaled_sre, write_output=False) sre_pipeline.add_otb_app(scaled_sre_app) for i in range(l_NumberOfBands): if resol == resol_QLK and (l_RedBandId == i or l_GreenBandId == i or l_BlueBandId == i): tmp_sre_roi = os.path.join( working_dir, "tmp_sre_roi_" + l_ListOfBand[i] + ".tif") tmp_sre_roi_app = extract_roi(self._sre_list[resol], [i], tmp_sre_roi, write_output=False) tmp_l2_image_list.append( tmp_sre_roi_app.getoutput().get("out")) tmp_l2_filename_list.append(tmp_sre_roi) if l_RedBandId == i: self._qckl_red_image = tmp_sre_roi elif l_GreenBandId == i: self._qckl_green_image = tmp_sre_roi elif l_BlueBandId == i: self._qckl_blue_image = tmp_sre_roi sre_pipeline.add_otb_app(tmp_sre_roi_app) tmp_sre_scaled_roi = os.path.join( working_dir, "tmp_sre_scaled_roi_" + l_ListOfBand[i] + ".tif") tmp_sre_scaled_roi_app = extract_roi( scaled_sre_app.getoutput().get("out"), [i], tmp_sre_scaled_roi + ":int16", write_output=False) tmp_l2_image_list.append( tmp_sre_scaled_roi_app.getoutput().get("out")) sre_pipeline.add_otb_app(tmp_sre_scaled_roi_app) tmp_l2_filename_list.append( l_BaseL2FullFilename + "_SRE_" + l_ListOfBand[i] + ".tif" + file_utils. get_extended_filename_write_image_file_standard()) # START WRITING FRE Image file DATA tmp_tgs_filename = os.path.join( working_dir, "tmp_tgs_" + l_StrResolution + ".tif") tmp_stl_filename = os.path.join( working_dir, "tmp_stl_" + l_StrResolution + ".tif") fre_pipeline = OtbPipelineManager() if p_EnvCorOption: # Initialize the Scalar filter tmp_fre_scaled = os.path.join( working_dir, "tmp_fre_multi_round_" + l_StrResolution + ".tif") param_scaled_fre = { "im": self._fre_list[resol], "coef": p_ReflectanceQuantificationValue, "out": tmp_fre_scaled } scaled_fre_app = OtbAppHandler("RoundImage", param_scaled_fre, write_output=False) fre_pipeline.add_otb_app(scaled_fre_app) # Extract each channel for each file for i in range(l_NumberOfBands): tmp_fre_roi = os.path.join( working_dir, "tmp_fre_roi_" + l_ListOfBand[i] + ".tif") tmp_fre_roi_app = extract_roi( scaled_fre_app.getoutput().get("out"), [i], tmp_fre_roi + ":int16", write_output=False) tmp_l2_image_list.append( tmp_fre_roi_app.getoutput().get("out")) fre_pipeline.add_otb_app(tmp_fre_roi_app) tmp_l2_filename_list.append( l_BaseL2FullFilename + "_FRE_" + l_ListOfBand[i] + ".tif" + file_utils. get_extended_filename_write_image_file_standard()) #Add tgs and stl also provided by the envcorr tmp_l2_image_list.append(self._tgs_list[resol]) tmp_l2_filename_list.append(tmp_tgs_filename) tmp_l2_image_list.append(self._stl_list[resol]) tmp_l2_filename_list.append(tmp_stl_filename) # START WRITING ATB Image file DATA # Initialize the Scalar filter # FA1424: Temporary Fix to address cosmetic aspects of FA1424 # VAPThreshold.SetInput(self.GetVAPImageList()[resol)) # VAPThreshold.SetOutsideValue(255. / p_VAPQuantificationValue) # VAPThreshold.ThresholdAbove(255. / p_VAPQuantificationValue) # VAPScalar.SetInput(VAPThreshold.GetOutput()) # VAPScalar.SetCoef(p_VAPQuantificationValue) atb_pipeline = OtbPipelineManager() tmp_vap = os.path.join( working_dir, "tmp_vap_scaled_" + l_StrResolution + ".tif") param_bandmath_vap = { "il": [self._l2vapimagelist[resol], self._l2edgimagelist[resol]], "exp": "(im2b1 == 1)?" + str(p_VAPNodataValue) + ":" + "im1b1*" + str(p_VAPQuantificationValue), "out": tmp_vap } vap_scal_app = OtbAppHandler("BandMathDouble", param_bandmath_vap, write_output=False) atb_pipeline.add_otb_app(vap_scal_app) tmp_round_vap = os.path.join( working_dir, "tmp_vap_round_" + l_StrResolution + ".tif") param_round_vap = { "im": vap_scal_app.getoutput().get("out"), "out": tmp_round_vap } vap_round_app = OtbAppHandler("RoundImage", param_round_vap, write_output=False) atb_pipeline.add_otb_app(vap_round_app) tmp_aot = os.path.join( working_dir, "tmp_aot_scaled_" + l_StrResolution + ".tif") param_bandmath_aot = { "il": [self._l2aotlist[resol], self._l2edgimagelist[resol]], "exp": "(im2b1 == 1)?" + str(p_AOTNodataValue) + ":" + "im1b1*" + str(p_AOTQuantificationValue), "out": tmp_aot } aot_scal_app = OtbAppHandler("BandMathDouble", param_bandmath_aot, write_output=False) atb_pipeline.add_otb_app(aot_scal_app) tmp_round_aot = os.path.join( working_dir, "tmp_aot_round_" + l_StrResolution + ".tif") param_round_aot = { "im": aot_scal_app.getoutput().get("out"), "out": tmp_round_aot } aot_round_app = OtbAppHandler("RoundImage", param_round_aot, write_output=False) atb_pipeline.add_otb_app(aot_round_app) atb_filename = l_BaseL2FullFilename + "_ATB_" + l_grpSuffix + ".tif" param_atb_concat = { "il": [ vap_round_app.getoutput().get("out"), aot_round_app.getoutput().get("out") ], "out": atb_filename + ":uint8" + file_utils. get_extended_filename_write_image_file_standard() } atb_binconcat_app = OtbAppHandler("ConcatenateImages", param_atb_concat, write_output=False) #tmp_l2_image_list.append(atb_binconcat_app.getoutput().get("out")) #tmp_l2_filename_list.append(atb_filename) atb_pipeline.add_otb_app(atb_binconcat_app) # START WRITING IAB MASK iab_pipeline = OtbPipelineManager() # Create the image list tmp_iab = os.path.join( working_dir, "tmp_iab_concat_" + l_StrResolution + ".tif") param_iab_concat = { "il": [self._l2iwcmasklist[resol], self._l2taomasklist[resol]], "out": tmp_iab + ":uint8" } tmp_iab_concat_app = OtbAppHandler("ConcatenateImages", param_iab_concat, write_output=False) iab_pipeline.add_otb_app(tmp_iab_concat_app) iab_filename = l_BaseL2FullMASKSFilename + "_IAB_" + l_grpSuffix + ".tif" param_iab_binconcat = { "im": tmp_iab_concat_app.getoutput().get("out"), "out": iab_filename + ":uint8" + file_utils. get_extended_filename_write_image_file_standard() } iab_binconcat_app = OtbAppHandler("BinaryConcatenate", param_iab_binconcat, write_output=False) iab_pipeline.add_otb_app(iab_binconcat_app) write_images([ atb_binconcat_app.getoutput().get("out"), iab_binconcat_app.getoutput().get("out") ], [atb_filename, iab_filename]) #tmp_l2_image_list.append(iab_binconcat_app.getoutput().get("out")) #tmp_l2_filename_list.append(iab_filename) # START WRITING EDG Image file DATA tmp_l2_image_list.append(self._l2edgimagelist[resol]) tmp_l2_filename_list.append(l_BaseL2FullMASKSFilename + "_EDG_" + l_grpSuffix + ".tif") #-------------------------- # Write all the images at L2 Reso write_images(tmp_l2_image_list, tmp_l2_filename_list) atb_pipeline.free_otb_app() iab_pipeline.free_otb_app() fre_pipeline.free_otb_app() sre_pipeline.free_otb_app() # -------------------------- #Caching of cloud images needed for MG2 l_cm2_index = p_CLDCoreAlgorithmsMapBand[CLOUD_MASK_ALL_CLOUDS] l_shadows_index = p_CLDCoreAlgorithmsMapBand[ CLOUD_MASK_SHADOWS] l_shadvar_index = p_CLDCoreAlgorithmsMapBand[ CLOUD_MASK_SHADVAR] # START WRITING MG2 Image file DATA l_mg2_image_list = [] mg2_pipeline = OtbPipelineManager() # Connect the WAM image wat_resampled = os.path.join( working_dir, "wat_resampled_" + l_StrResolution + ".tif") app_resample_wat = resample(self._wasimage, self._dtm.ALTList[resol], wat_resampled, method=OtbResampleType.LINEAR, threshold=0.25, write_output=False) l_mg2_image_list.append( app_resample_wat.getoutput().get("out")) mg2_pipeline.add_otb_app(app_resample_wat) # Extract the CM2 cloud mask l_mg2_image_list.append(self._l2cldlist[resol][l_cm2_index]) #Connect the SNW image if any if self._cld_snow is not None: LOGGER.debug( "Snow mask has been successfully computed, adding it to the MG2" ) snw_resampled = os.path.join( working_dir, "snw_resampled_" + l_StrResolution + ".tif") app_resample_snw = resample(self._cld_snow, self._dtm.ALTList[resol], snw_resampled, method=OtbResampleType.LINEAR, threshold=0.25, write_output=False) l_mg2_image_list.append( app_resample_snw.getoutput().get("out")) mg2_pipeline.add_otb_app(app_resample_snw) else: # Add a constant mask tmp_constant_filename = os.path.join( working_dir, "Const_shd_masks.tif") cst_snw_app = constant_image(self._dtm.ALTList[resol], 0, tmp_constant_filename + ":uint8", write_output=False) l_mg2_image_list.append(cst_snw_app.getoutput().get("out")) mg2_pipeline.add_otb_app(cst_snw_app) # Connect the shadow or mask tmp_shador_bandmath = os.path.join( working_dir, "tmp_shador_bandmath_" + l_StrResolution + ".tif") tmp_band_math_app = band_math([ self._l2cldlist[resol][l_shadows_index], self._l2cldlist[resol][l_shadvar_index] ], "im1b1 || im2b1", tmp_shador_bandmath + ":uint8", write_output=False) l_mg2_image_list.append( tmp_band_math_app.getoutput().get("out")) mg2_pipeline.add_otb_app(tmp_band_math_app) # Connect the HID image hid_resampled = os.path.join( working_dir, "hid_resampled_" + l_StrResolution + ".tif") app_resample_hid = resample(self._dtm_hid, self._dtm.ALTList[resol], hid_resampled, method=OtbResampleType.LINEAR, threshold=0.25, write_output=False) l_mg2_image_list.append( app_resample_hid.getoutput().get("out")) mg2_pipeline.add_otb_app(app_resample_hid) # Connect the SHDimage shd_resampled = os.path.join( working_dir, "shd_resampled_" + l_StrResolution + ".tif") app_resample_shd = resample(self._dtm_shd, self._dtm.ALTList[resol], shd_resampled, method=OtbResampleType.LINEAR, threshold=0.25, write_output=False) mg2_pipeline.add_otb_app(app_resample_shd) l_mg2_image_list.append( app_resample_shd.getoutput().get("out")) if p_EnvCorOption: # Append STL l_mg2_image_list.append(tmp_stl_filename) # Append TGS l_mg2_image_list.append(tmp_tgs_filename) else: # Append STL l_mg2_image_list.append(self._stl_list[resol]) # Append TGS l_mg2_image_list.append(self._tgs_list[resol]) # Concatenate all tmp_mg2 = os.path.join( working_dir, "tmp_mg2_concat_" + l_StrResolution + ".tif") param_mg2_concat = {"il": l_mg2_image_list, "out": tmp_mg2} tmp_mg2_concat_app = OtbAppHandler("ConcatenateImages", param_mg2_concat, write_output=False) param_mg2_binconcat = { "im": tmp_mg2_concat_app.getoutput().get("out"), "out": l_BaseL2FullMASKSFilename + "_MG2_" + l_grpSuffix + ".tif" + ":uint8" + file_utils. get_extended_filename_write_image_file_standard() } mg2_binconcat_app = OtbAppHandler("BinaryConcatenate", param_mg2_binconcat, write_output=True) mg2_pipeline.add_otb_app(mg2_binconcat_app) mg2_pipeline.free_otb_app() # START WRITING SAT Image file DATA # TODO Create the writer with test on number of bands param_sat_binconcat = { "im": self._l2satimagelist[resol], "out": l_BaseL2FullMASKSFilename + "_SAT_" + l_grpSuffix + ".tif" + ":uint8" + file_utils. get_extended_filename_write_image_file_standard() } sat_binconcat_app = OtbAppHandler("BinaryConcatenate", param_sat_binconcat, write_output=True) # START WRITING PIX Image file DATA if "PIXImages" in self._l1_image_info.MuscateData: LOGGER.debug( "The L1 product have 'Aberrant_Pixels' masks. There are writed in the L2 out product..." ) otb_file_utils.otb_copy_image_to_file( self._l2piximagelist[resol], l_BaseL2FullMASKSFilename + "_PIX_" + l_grpSuffix + ".tif") else: LOGGER.debug("No PIX node detected to write") # START WRITING USI Image file DATA if "Node_Useful_Image" in self._l1_image_info.MuscateData: LOGGER.debug( "The L1 product have 'Useful_Image' files. There are copied in the L2 out product..." ) # Write the USI in the Xml file, in the Useful_Imagenode ! l_XPathRootUSI_In = "//Mask[Mask_Properties/NATURE='Useful_Image']/Mask_File_List/MASK_FILE[@group_id='{}']" xnodes_in = xml_tools.get_all_values( self._l1_image_info.MuscateData["Node_Useful_Image"], l_XPathRootUSI_In.format(l_grpSuffix)) # Get the path in the xml product filename lPath = os.path.dirname(self._l1_image_info.HeaderFilename) for node_in in xnodes_in: l_FullPathFilename = os.path.join(lPath, node_in.text) # Expand threshold the file usi_resampled = l_BaseL2FullMASKSFilename + "_USI_" + l_grpSuffix + ".tif"\ + file_utils.get_extended_filename_write_mask_file_muscate() resample(l_FullPathFilename, self._dtm.ALTList[resol], usi_resampled, threshold=0.25, method=OtbResampleType.LINEAR, write_output=True) else: LOGGER.debug( "No 'Useful_Image' mask detected in the L1 product." ) # Fin si manage USI # START WRITING DFP Image file DATA (=DFP in MUSCATE) #TODO if self._l2dfpimagelist is not None: param_dfp_binconcat = { "im": self._l2dfpimagelist[resol], "out": l_BaseL2FullMASKSFilename + "_DFP_" + l_grpSuffix + ".tif" } dfp_binconcat_app = OtbAppHandler("BinaryConcatenate", param_dfp_binconcat, write_output=True) else: LOGGER.debug("DFP Masks not available.") # START WRITING CLM (CLD) Image file DATA # Connect the CLD image # Connect the CLD image # ------------------------------------- l_cld_uses_filenames = False for f in self._l2cldlist[resol]: if not otb_is_swig_pointer(f) and os.path.exists(f): l_cld_uses_filenames = True self.write_cld_image(self._l2cldlist[resol], p_CLDDataBandsSelected, l_BaseL2FullMASKSFilename + "_CLM_" + l_grpSuffix + ".tif", use_filenames=l_cld_uses_filenames) LOGGER.debug("Writing L2 resolution image done !")